Skip to main content

brep_kernel/abi/
io_abi.rs

1use super::*;
2
3#[derive(Serialize)]
4pub(crate) struct Capabilities {
5    pub(crate) abi_version: u32,
6    pub(crate) operations: &'static [&'static str],
7}
8
9#[wasm_bindgen]
10pub fn capabilities_json() -> String {
11    serde_json::to_string(&Capabilities {
12        abi_version: 1,
13        operations: &[
14            "box_mesh",
15            "cylinder_mesh",
16            "mesh_validate",
17            "mesh_volume",
18            "nurbs_curve_evaluate",
19            "nurbs_curve_derivatives",
20            "nurbs_curve_handle_typed_arrays",
21            "make_line",
22            "make_arc",
23            "make_circle",
24            "make_parabola",
25            "make_hyperbola",
26            "uniform_clamped_knots",
27            "solve_dense",
28            "solve_banded",
29            "interpolate_curve_thinned",
30            "nurbs_surface_evaluate",
31            "nurbs_surface_derivatives",
32            "nurbs_surface_normal",
33            "nurbs_surface_handle_typed_arrays",
34            "brep_solid_resident_handle",
35            "brep_topology_validate",
36            "brep_topology_validate_detailed",
37            "make_box_brep",
38            "make_pyramid_brep",
39            "make_cylinder_brep",
40            "make_cone_brep",
41            "make_sphere_brep",
42            "make_torus_brep",
43            "extrude_profile_brep",
44            "extrude_profile_brep_draft",
45            "rib_from_profile",
46            "revolve_profile_brep",
47            "fillet_edge",
48            "chamfer_edge",
49            "fillet_edges",
50            "fillet_edges_variable",
51            "chamfer_edges_asymmetric",
52            "chamfer_edges_angle",
53            "round_convex_corner",
54            "loft_profile_brep",
55            "loft_profile_brep_guided",
56            "loft_profile_brep_guided_frame",
57            "loft_profile_brep_tangent",
58            "thicken_face_sheet",
59            "thicken_trimmed_sheet",
60            "segment_mesh_faces",
61            "mesh_regions_to_brep",
62            "solve_assembly",
63            "loft_profile_brep_closed",
64            "sweep_profile_along_path",
65            "sweep_profile_helix",
66            "sweep_profile_twisted",
67            "transform_brep",
68            "mirror_brep",
69            "split_solid_by_plane",
70            "split_solid_by_surface",
71            "split_solid_by_face_surface",
72            "parameter_space_area",
73            "trim_polygons",
74            "face_mass_properties",
75            "solid_mass_properties",
76            "solid_mass_properties_full",
77            "solid_mass_properties_density",
78            "solid_buffer_abi",
79            "tessellate_watertight",
80            "tessellate_watertight_face_stride",
81            "tessellate_watertight_face_stride_shared_samples",
82            "tessellate_face",
83            "tessellate_brep",
84            "project_point_to_curve",
85            "project_point_to_surface",
86            "intersect_curve_surface",
87            "intersect_curves",
88            "intersect_surfaces",
89            "classify_point",
90            "classify_points",
91            "parameter_point_in_face",
92            "arrange_segments",
93            "segment_intersection",
94            "point_in_polygon",
95            "build_pcurve_on_surface",
96            "carrier_preview_patch",
97            "build_imprints",
98            "apply_edge_splits",
99            "fragment_faces",
100            "boolean_operation",
101            "boolean_operation_diagnostics",
102            "offset_surface",
103            "offset_face_carrier",
104            "merge_curve_continuation_edges",
105            "merge_same_surface_faces",
106            "offset_shell",
107            "offset_shell_diagnostics",
108            "delete_face_and_heal",
109            "move_faces",
110            "sew_solid",
111            "export_step",
112            "import_step",
113            "export_iges",
114            "import_iges",
115            "write_binary_stl",
116            "read_binary_stl",
117            "mesh_to_faceted_brep",
118            "import_stl_solid",
119            "write_obj",
120            "read_obj",
121            "import_obj_solid",
122            "solve_sketch",
123        ],
124    })
125    .expect("serialize capabilities")
126}
127
128#[wasm_bindgen]
129pub fn box_mesh_json(x: f64, y: f64, z: f64) -> String {
130    serde_json::to_string(&make_box(x, y, z)).expect("serialize box")
131}
132
133#[wasm_bindgen]
134pub fn cylinder_mesh_json(radius: f64, height: f64, segments: u32) -> String {
135    serde_json::to_string(&make_cylinder(radius, height, segments as usize))
136        .expect("serialize cylinder")
137}
138
139#[wasm_bindgen]
140pub fn mesh_volume_json(mesh_json: &str) -> Result<f64, JsValue> {
141    let mesh: Mesh =
142        serde_json::from_str(mesh_json).map_err(|error| JsValue::from_str(&error.to_string()))?;
143    // Volume is a signed-tetrahedron sum over positions only; do NOT require a
144    // normal buffer (mesh-only solids, e.g. sheet-metal, have none).
145    mesh.validate_geometry()
146        .map_err(|error| JsValue::from_str(&error))?;
147    Ok(mesh.signed_volume())
148}
149
150#[wasm_bindgen]
151pub fn write_stl_bytes(mesh_json: &str, name: &str) -> Result<Vec<u8>, JsValue> {
152    let mesh: Mesh =
153        serde_json::from_str(mesh_json).map_err(|error| javascript_error(error.to_string()))?;
154    write_binary_stl(&mesh, name).map_err(javascript_error)
155}
156
157#[wasm_bindgen]
158pub fn read_stl_json(data: &[u8]) -> Result<String, JsValue> {
159    let result = read_binary_stl(data).map_err(javascript_error)?;
160    serde_json::to_string(&result).map_err(|error| javascript_error(error.to_string()))
161}
162
163/// Import binary-STL bytes as a faceted (planar-triangle) BREP solid.
164/// `tolerance <= 0` derives the vertex-weld band from the model's
165/// bounding-box diagonal.
166#[wasm_bindgen]
167pub fn import_stl_solid(data: &[u8], tolerance: f64) -> Result<String, JsValue> {
168    crate::panic_hook::set_once();
169    let stl = read_binary_stl(data).map_err(javascript_error)?;
170    let solid = mesh_to_faceted_brep(&stl.positions, None, tolerance).map_err(javascript_error)?;
171    serde_json::to_string(&solid).map_err(|error| javascript_error(error.to_string()))
172}
173
174/// Diagnostic carrier preview: re-express a surface over an inflated domain
175/// (open directions inflate about the centre via extended evaluation; closed
176/// directions keep their full period). `inflate <= 0` defaults to 2.
177#[wasm_bindgen]
178pub fn carrier_preview_patch_json(surface_json: &str, inflate: f64) -> Result<String, JsValue> {
179    let surface: NurbsSurface =
180        serde_json::from_str(surface_json).map_err(|error| javascript_error(error.to_string()))?;
181    let inflate = if inflate.is_finite() && inflate > 0.0 {
182        inflate
183    } else {
184        2.0
185    };
186    let preview = carrier_preview_patch(&surface, inflate).map_err(javascript_error)?;
187    serde_json::to_string(&preview).map_err(|error| javascript_error(error.to_string()))
188}
189
190#[wasm_bindgen]
191pub fn write_obj_text(mesh_json: &str, name: &str) -> Result<String, JsValue> {
192    let mesh: Mesh =
193        serde_json::from_str(mesh_json).map_err(|error| javascript_error(error.to_string()))?;
194    write_obj(&mesh, name).map_err(javascript_error)
195}
196
197/// Import Wavefront OBJ text as a faceted (planar-triangle) BREP solid.
198/// `tolerance <= 0` derives the vertex-weld band from the model's
199/// bounding-box diagonal.
200#[wasm_bindgen]
201pub fn import_obj_solid(text: &str, tolerance: f64) -> Result<String, JsValue> {
202    crate::panic_hook::set_once();
203    let obj = read_obj(text).map_err(javascript_error)?;
204    let solid = mesh_to_faceted_brep(&obj.positions, Some(&obj.indices), tolerance)
205        .map_err(javascript_error)?;
206    serde_json::to_string(&solid).map_err(|error| javascript_error(error.to_string()))
207}