1#![cfg(feature = "io")]
4#![allow(clippy::missing_errors_doc)]
5
6use wasm_bindgen::prelude::*;
7
8use crate::error::{WasmError, validate_positive};
9use crate::handles::solid_id_to_u32;
10use crate::helpers::TOL;
11use crate::kernel::BrepKernel;
12
13#[wasm_bindgen]
14impl BrepKernel {
15 #[wasm_bindgen(js_name = "export3mf")]
25 pub fn export_3mf(&self, solid: u32, deflection: f64) -> Result<Vec<u8>, JsError> {
26 validate_positive(deflection, "deflection")?;
27 let solid_id = self.resolve_solid(solid)?;
28 let bytes = brepkit_io::threemf::write_threemf(&self.topo, &[solid_id], deflection)?;
29 Ok(bytes)
30 }
31
32 #[wasm_bindgen(js_name = "exportStl")]
40 pub fn export_stl(&self, solid: u32, deflection: f64) -> Result<Vec<u8>, JsError> {
41 validate_positive(deflection, "deflection")?;
42 let solid_id = self.resolve_solid(solid)?;
43 let bytes = brepkit_io::stl::writer::write_stl(
44 &self.topo,
45 &[solid_id],
46 deflection,
47 brepkit_io::stl::writer::StlFormat::Binary,
48 )?;
49 Ok(bytes)
50 }
51
52 #[wasm_bindgen(js_name = "exportStlAscii")]
60 pub fn export_stl_ascii(&self, solid: u32, deflection: f64) -> Result<Vec<u8>, JsError> {
61 validate_positive(deflection, "deflection")?;
62 let solid_id = self.resolve_solid(solid)?;
63 let bytes = brepkit_io::stl::writer::write_stl(
64 &self.topo,
65 &[solid_id],
66 deflection,
67 brepkit_io::stl::writer::StlFormat::Ascii,
68 )?;
69 Ok(bytes)
70 }
71
72 #[wasm_bindgen(js_name = "exportObj")]
78 pub fn export_obj(&self, solid: u32, deflection: f64) -> Result<Vec<u8>, JsError> {
79 validate_positive(deflection, "deflection")?;
80 let solid_id = self.resolve_solid(solid)?;
81 let obj_str = brepkit_io::obj::write_obj(&self.topo, &[solid_id], deflection)?;
82 Ok(obj_str.into_bytes())
83 }
84
85 #[wasm_bindgen(js_name = "exportGlb")]
91 pub fn export_glb(&self, solid: u32, deflection: f64) -> Result<Vec<u8>, JsError> {
92 validate_positive(deflection, "deflection")?;
93 let solid_id = self.resolve_solid(solid)?;
94 let glb = brepkit_io::gltf::write_glb(&self.topo, &[solid_id], deflection)?;
95 Ok(glb)
96 }
97
98 #[wasm_bindgen(js_name = "exportPly")]
104 pub fn export_ply(&self, solid: u32, deflection: f64) -> Result<Vec<u8>, JsError> {
105 validate_positive(deflection, "deflection")?;
106 let solid_id = self.resolve_solid(solid)?;
107 let ply = brepkit_io::ply::write_ply(
108 &self.topo,
109 &[solid_id],
110 deflection,
111 brepkit_io::ply::writer::PlyFormat::BinaryLittleEndian,
112 )?;
113 Ok(ply)
114 }
115
116 #[wasm_bindgen(js_name = "importObj")]
124 pub fn import_obj(&mut self, data: &[u8]) -> Result<u32, JsError> {
125 let text = std::str::from_utf8(data).map_err(|e| WasmError::InvalidInput {
126 reason: format!("OBJ must be valid UTF-8: {e}"),
127 })?;
128 let mesh = brepkit_io::obj::read_obj(text)?;
129 let solid_id = brepkit_io::stl::import::import_mesh(self.topo_mut(), &mesh, 1e-7)?;
130 #[allow(clippy::cast_possible_truncation)]
131 Ok(solid_id.index() as u32)
132 }
133
134 #[wasm_bindgen(js_name = "importGlb")]
140 pub fn import_glb(&mut self, data: &[u8]) -> Result<u32, JsError> {
141 let mesh = brepkit_io::gltf::read_glb(data)?;
142 let solid_id = brepkit_io::stl::import::import_mesh(self.topo_mut(), &mesh, 1e-7)?;
143 #[allow(clippy::cast_possible_truncation)]
144 Ok(solid_id.index() as u32)
145 }
146
147 #[wasm_bindgen(js_name = "importStl")]
156 pub fn import_stl(&mut self, data: &[u8]) -> Result<u32, JsError> {
157 let mesh = brepkit_io::stl::reader::read_stl(data)?;
158 let solid_id = brepkit_io::stl::import::import_mesh(self.topo_mut(), &mesh, TOL)?;
159 Ok(solid_id_to_u32(solid_id))
160 }
161
162 #[wasm_bindgen(js_name = "import3mf")]
170 pub fn import_3mf(&mut self, data: &[u8]) -> Result<Vec<u32>, JsError> {
171 let meshes = brepkit_io::threemf::reader::read_threemf(data)?;
172 let mut handles = Vec::new();
173 for mesh in &meshes {
174 let solid_id = brepkit_io::stl::import::import_mesh(self.topo_mut(), mesh, TOL)?;
175 handles.push(solid_id_to_u32(solid_id));
176 }
177 Ok(handles)
178 }
179
180 #[wasm_bindgen(js_name = "importIndexedMesh")]
190 pub fn import_indexed_mesh(
191 &mut self,
192 positions: &[f64],
193 indices: &[u32],
194 ) -> Result<u32, JsError> {
195 use brepkit_math::vec::Point3;
196
197 if !positions.len().is_multiple_of(3) {
198 return Err(WasmError::InvalidInput {
199 reason: format!(
200 "positions length {} is not a multiple of 3",
201 positions.len()
202 ),
203 }
204 .into());
205 }
206 if !indices.len().is_multiple_of(3) {
207 return Err(WasmError::InvalidInput {
208 reason: format!("indices length {} is not a multiple of 3", indices.len()),
209 }
210 .into());
211 }
212
213 let verts: Vec<Point3> = positions
214 .chunks_exact(3)
215 .map(|c| Point3::new(c[0], c[1], c[2]))
216 .collect();
217 let normals = Vec::new();
218
219 let mesh = brepkit_operations::tessellate::TriangleMesh {
220 positions: verts,
221 normals,
222 indices: indices.to_vec(),
223 };
224
225 let solid_id = brepkit_io::stl::import::import_mesh(self.topo_mut(), &mesh, TOL)?;
226 Ok(solid_id_to_u32(solid_id))
227 }
228
229 #[wasm_bindgen(js_name = "exportStep")]
237 pub fn export_step(&self, solid: u32) -> Result<Vec<u8>, JsError> {
238 let solid_id = self.resolve_solid(solid)?;
239 let step_str = brepkit_io::step::writer::write_step(&self.topo, &[solid_id])?;
240 Ok(step_str.into_bytes())
241 }
242
243 #[wasm_bindgen(js_name = "importStep")]
251 pub fn import_step(&mut self, data: &[u8]) -> Result<Vec<u32>, JsError> {
252 let text = std::str::from_utf8(data)
253 .map_err(|e| JsError::new(&format!("STEP data is not valid UTF-8: {e}")))?;
254 let solid_ids = brepkit_io::step::reader::read_step(text, self.topo_mut())?;
255 Ok(solid_ids.iter().map(|id| solid_id_to_u32(*id)).collect())
256 }
257
258 #[wasm_bindgen(js_name = "exportIges")]
268 pub fn export_iges(&self, solid: u32) -> Result<Vec<u8>, JsError> {
269 let solid_id = self.resolve_solid(solid)?;
270 let iges_str = brepkit_io::iges::writer::write_iges(&self.topo, &[solid_id])?;
271 Ok(iges_str.into_bytes())
272 }
273
274 #[wasm_bindgen(js_name = "importIges")]
280 pub fn import_iges(&mut self, data: &[u8]) -> Result<Vec<u32>, JsError> {
281 let text = std::str::from_utf8(data)
282 .map_err(|e| JsError::new(&format!("IGES data is not valid UTF-8: {e}")))?;
283 let solid_ids = brepkit_io::iges::reader::read_iges(text, self.topo_mut())?;
284 Ok(solid_ids.iter().map(|id| solid_id_to_u32(*id)).collect())
285 }
286
287 #[wasm_bindgen(js_name = "serializeSolid")]
304 pub fn serialize_solid(&self, solid: u32) -> Result<Vec<u8>, JsError> {
305 let solid_id = self.resolve_solid(solid)?;
306 let bytes = brepkit_io::arena_io::serialize_solid(&self.topo, solid_id)?;
307 Ok(bytes)
308 }
309
310 #[wasm_bindgen(js_name = "deserializeSolid")]
316 pub fn deserialize_solid(&mut self, data: &[u8]) -> Result<u32, JsError> {
317 let solid_id = brepkit_io::arena_io::deserialize_solid(data, self.topo_mut())?;
318 Ok(solid_id_to_u32(solid_id))
319 }
320}