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            "read_stl",
118            "mesh_to_faceted_brep",
119            "import_stl_solid",
120            "write_obj",
121            "read_obj",
122            "import_obj_solid",
123            "solve_sketch",
124        ],
125    })
126    .expect("serialize capabilities")
127}
128
129#[wasm_bindgen]
130pub fn box_mesh_json(x: f64, y: f64, z: f64) -> String {
131    serde_json::to_string(&make_box(x, y, z)).expect("serialize box")
132}
133
134#[wasm_bindgen]
135pub fn cylinder_mesh_json(radius: f64, height: f64, segments: u32) -> String {
136    serde_json::to_string(&make_cylinder(radius, height, segments as usize))
137        .expect("serialize cylinder")
138}
139
140#[wasm_bindgen]
141pub fn mesh_volume_json(mesh_json: &str) -> Result<f64, JsValue> {
142    let mesh: Mesh =
143        serde_json::from_str(mesh_json).map_err(|error| JsValue::from_str(&error.to_string()))?;
144    // Volume is a signed-tetrahedron sum over positions only; do NOT require a
145    // normal buffer (mesh-only solids, e.g. sheet-metal, have none).
146    mesh.validate_geometry()
147        .map_err(|error| JsValue::from_str(&error))?;
148    Ok(mesh.signed_volume())
149}
150
151#[wasm_bindgen]
152pub fn write_stl_bytes(mesh_json: &str, name: &str) -> Result<Vec<u8>, JsValue> {
153    let mesh: Mesh = json_in(mesh_json)?;
154    write_binary_stl(&mesh, name).map_err(javascript_error)
155}
156
157/// Read binary or ASCII STL bytes ([`read_stl`]) as `{tri_count,
158/// positions, format}` JSON.
159#[wasm_bindgen]
160pub fn read_stl_json(data: &[u8]) -> Result<String, JsValue> {
161    let result = read_stl(data).map_err(javascript_error)?;
162    json_out(&result)
163}
164
165/// Import binary or ASCII STL bytes ([`read_stl`]) as a faceted
166/// (planar-triangle) BREP solid.
167/// `tolerance <= 0` derives the vertex-weld band from the model's
168/// bounding-box diagonal.
169#[wasm_bindgen]
170pub fn import_stl_solid(data: &[u8], tolerance: f64) -> Result<String, JsValue> {
171    crate::panic_hook::set_once();
172    let stl = read_stl(data).map_err(javascript_error)?;
173    let solid = mesh_to_faceted_brep(&stl.positions, None, tolerance).map_err(|refusal| javascript_error(refusal.message))?;
174    json_out(&solid)
175}
176
177/// Diagnostic carrier preview: re-express a surface over an inflated domain
178/// (open directions inflate about the centre via extended evaluation; closed
179/// directions keep their full period). `inflate <= 0` defaults to 2.
180#[wasm_bindgen]
181pub fn carrier_preview_patch_json(surface_json: &str, inflate: f64) -> Result<String, JsValue> {
182    let surface: NurbsSurface = json_in(surface_json)?;
183    let inflate = if inflate.is_finite() && inflate > 0.0 {
184        inflate
185    } else {
186        2.0
187    };
188    let preview = carrier_preview_patch(&surface, inflate).map_err(javascript_error)?;
189    json_out(&preview)
190}
191
192#[wasm_bindgen]
193pub fn write_obj_text(mesh_json: &str, name: &str) -> Result<String, JsValue> {
194    let mesh: Mesh = json_in(mesh_json)?;
195    write_obj(&mesh, name).map_err(javascript_error)
196}
197
198/// Import Wavefront OBJ text as a faceted (planar-triangle) BREP solid.
199/// `tolerance <= 0` derives the vertex-weld band from the model's
200/// bounding-box diagonal.
201#[wasm_bindgen]
202pub fn import_obj_solid(text: &str, tolerance: f64) -> Result<String, JsValue> {
203    crate::panic_hook::set_once();
204    let obj = read_obj(text).map_err(javascript_error)?;
205    let solid = mesh_to_faceted_brep(&obj.positions, Some(&obj.indices), tolerance)
206        .map_err(|refusal| javascript_error(refusal.message))?;
207    json_out(&solid)
208}