Skip to main content

manifold_csg_sys/
lib.rs

1//! Raw FFI bindings to the [manifold3d](https://github.com/elalish/manifold) C API.
2//!
3//! These are low-level, unsafe bindings. Users should prefer the safe wrappers
4//! in the [`manifold-csg`](https://crates.io/crates/manifold-csg) crate.
5//!
6//! # Overview
7//!
8//! manifold3d is a geometry kernel for constructive solid geometry (CSG)
9//! operations. It provides:
10//!
11//! - **3D Boolean operations**: union, difference, intersection of solid meshes
12//! - **2D cross-section operations**: offset, boolean, hull for 2D regions
13//! - **Mesh construction**: from vertices/indices, primitives (cube, sphere, cylinder)
14//! - **Extrusion**: 2D cross-sections to 3D solids
15//! - **Queries**: volume, surface area, bounding box, vertex/face counts
16
17#![allow(non_camel_case_types)]
18
19use std::os::raw::c_int;
20
21// ── Opaque handle types ─────────────────────────────────────────────────
22
23/// Opaque handle to a manifold3d Manifold object (3D solid).
24#[repr(C)]
25#[derive(Debug)]
26pub struct ManifoldManifold {
27    _private: [u8; 0],
28}
29
30/// Opaque handle to a manifold3d `ManifoldVec` (vector of Manifold objects).
31#[repr(C)]
32#[derive(Debug)]
33pub struct ManifoldManifoldVec {
34    _private: [u8; 0],
35}
36
37/// Opaque handle to a manifold3d `Polygons` object (2D polygon set).
38#[repr(C)]
39#[derive(Debug)]
40pub struct ManifoldPolygons {
41    _private: [u8; 0],
42}
43
44/// Opaque handle to a manifold3d `SimplePolygon` object (single polygon ring).
45#[repr(C)]
46#[derive(Debug)]
47pub struct ManifoldSimplePolygon {
48    _private: [u8; 0],
49}
50
51/// Opaque handle to a manifold3d `RayHitVec` (vector of ray hit results).
52#[repr(C)]
53#[derive(Debug)]
54pub struct ManifoldRayHitVec {
55    _private: [u8; 0],
56}
57
58/// Opaque handle to a manifold3d `ExecutionContext` — observes progress
59/// and allows cooperative cancellation of long-running boolean evaluations.
60/// The C API documents it as safe to read/write from any thread.
61#[repr(C)]
62#[derive(Debug)]
63pub struct ManifoldExecutionContext {
64    _private: [u8; 0],
65}
66
67/// Opaque handle to a manifold3d `Triangulation` result.
68#[repr(C)]
69#[derive(Debug)]
70pub struct ManifoldTriangulation {
71    _private: [u8; 0],
72}
73
74/// Opaque handle to a manifold3d `MeshGL` object (f32 vertices, u32 indices).
75#[repr(C)]
76#[derive(Debug)]
77pub struct ManifoldMeshGL {
78    _private: [u8; 0],
79}
80
81/// Opaque handle to a manifold3d `MeshGL64` object (f64 vertices, u64 indices).
82#[repr(C)]
83#[derive(Debug)]
84pub struct ManifoldMeshGL64 {
85    _private: [u8; 0],
86}
87
88/// Opaque handle to a manifold3d `Box` (3D axis-aligned bounding box).
89#[repr(C)]
90#[derive(Debug)]
91pub struct ManifoldBox {
92    _private: [u8; 0],
93}
94
95/// Opaque handle to a manifold3d `CrossSection` object (2D region).
96#[repr(C)]
97#[derive(Debug)]
98pub struct ManifoldCrossSection {
99    _private: [u8; 0],
100}
101
102/// Opaque handle to a manifold3d `CrossSectionVec` (vector of CrossSection objects).
103#[repr(C)]
104#[derive(Debug)]
105pub struct ManifoldCrossSectionVec {
106    _private: [u8; 0],
107}
108
109/// Opaque handle to a manifold3d `Rect` (2D axis-aligned bounding box).
110#[repr(C)]
111#[derive(Debug)]
112pub struct ManifoldRect {
113    _private: [u8; 0],
114}
115
116// ── Value types ─────────────────────────────────────────────────────────
117
118/// Pair of manifolds returned by `manifold_split` / `manifold_split_by_plane`.
119#[repr(C)]
120#[derive(Debug)]
121pub struct ManifoldManifoldPair {
122    pub first: *mut ManifoldManifold,
123    pub second: *mut ManifoldManifold,
124}
125
126/// 2D vector used by manifold3d polygon API.
127#[repr(C)]
128#[derive(Debug, Clone, Copy)]
129pub struct ManifoldVec2 {
130    pub x: f64,
131    pub y: f64,
132}
133
134/// 3D vector returned by manifold3d C API.
135#[repr(C)]
136#[derive(Debug, Clone, Copy)]
137pub struct ManifoldVec3 {
138    pub x: f64,
139    pub y: f64,
140    pub z: f64,
141}
142
143/// 3D integer vector.
144#[repr(C)]
145#[derive(Debug, Clone, Copy)]
146pub struct ManifoldIVec3 {
147    pub x: c_int,
148    pub y: c_int,
149    pub z: c_int,
150}
151
152/// 4D vector (e.g. for tangents with weight).
153#[repr(C)]
154#[derive(Debug, Clone, Copy)]
155pub struct ManifoldVec4 {
156    pub x: f64,
157    pub y: f64,
158    pub z: f64,
159    pub w: f64,
160}
161
162/// Surface area and volume properties returned by manifold queries.
163#[repr(C)]
164#[derive(Debug, Clone, Copy)]
165pub struct ManifoldProperties {
166    pub surface_area: f64,
167    pub volume: f64,
168}
169
170/// Result of a ray-manifold intersection test.
171#[repr(C)]
172#[derive(Debug, Clone, Copy)]
173pub struct ManifoldRayHit {
174    pub face_id: u64,
175    pub distance: f64,
176    pub position: ManifoldVec3,
177    pub normal: ManifoldVec3,
178}
179
180/// Options for constructing a `MeshGL` with additional metadata.
181#[repr(C)]
182#[derive(Debug)]
183pub struct ManifoldMeshGLOptions {
184    pub run_indices: *mut u32,
185    pub run_indices_length: usize,
186    pub run_original_ids: *mut u32,
187    pub run_original_ids_length: usize,
188    pub merge_from_vert: *mut u32,
189    pub merge_to_vert: *mut u32,
190    pub merge_verts_length: usize,
191    pub halfedge_tangents: *mut f32,
192}
193
194/// Options for constructing a `MeshGL64` with additional metadata.
195#[repr(C)]
196#[derive(Debug)]
197pub struct ManifoldMeshGL64Options {
198    pub run_indices: *mut u64,
199    pub run_indices_length: usize,
200    pub run_original_ids: *mut u32,
201    pub run_original_ids_length: usize,
202    pub merge_from_vert: *mut u64,
203    pub merge_to_vert: *mut u64,
204    pub merge_verts_length: usize,
205    pub halfedge_tangents: *mut f64,
206}
207
208// ── Enums ───────────────────────────────────────────────────────────────
209
210/// Boolean operation type for `manifold_batch_boolean`.
211#[repr(C)]
212#[derive(Debug, Clone, Copy, PartialEq, Eq)]
213pub enum ManifoldOpType {
214    Add = 0,
215    Subtract = 1,
216    Intersect = 2,
217}
218
219/// Fill rule for constructing CrossSections from polygons.
220#[repr(C)]
221#[derive(Debug, Clone, Copy, PartialEq, Eq)]
222pub enum ManifoldFillRule {
223    EvenOdd = 0,
224    NonZero = 1,
225    Positive = 2,
226    Negative = 3,
227}
228
229/// Join type for CrossSection offset operations (Clipper2).
230#[repr(C)]
231#[derive(Debug, Clone, Copy, PartialEq, Eq)]
232pub enum ManifoldJoinType {
233    Square = 0,
234    Round = 1,
235    Miter = 2,
236    Bevel = 3,
237}
238
239/// Error codes from manifold3d status check.
240#[repr(C)]
241#[derive(Debug, Clone, Copy, PartialEq, Eq)]
242pub enum ManifoldError {
243    NoError = 0,
244    NonFiniteVertex = 1,
245    NotManifold = 2,
246    VertexOutOfBounds = 3,
247    PropertiesWrongLength = 4,
248    MissingPositionProperties = 5,
249    MergeVectorsDifferentLengths = 6,
250    MergeIndexOutOfBounds = 7,
251    TransformWrongLength = 8,
252    RunIndexWrongLength = 9,
253    FaceIdWrongLength = 10,
254    InvalidConstruction = 11,
255    ResultTooLarge = 12,
256}
257
258// ── Function pointer types ─────────────────────────────────────────────
259
260/// SDF callback: `fn(x, y, z, ctx) -> distance`
261pub type ManifoldSdf = Option<unsafe extern "C" fn(f64, f64, f64, *mut std::ffi::c_void) -> f64>;
262
263// ── C API declarations ──────────────────────────────────────────────────
264
265unsafe extern "C" {
266    // ── Memory sizes ───────────────────────────────────────────────────
267
268    pub fn manifold_manifold_size() -> usize;
269    pub fn manifold_manifold_vec_size() -> usize;
270    pub fn manifold_cross_section_size() -> usize;
271    pub fn manifold_cross_section_vec_size() -> usize;
272    pub fn manifold_simple_polygon_size() -> usize;
273    pub fn manifold_polygons_size() -> usize;
274    pub fn manifold_manifold_pair_size() -> usize;
275    pub fn manifold_meshgl_size() -> usize;
276    pub fn manifold_meshgl64_size() -> usize;
277    pub fn manifold_box_size() -> usize;
278    pub fn manifold_rect_size() -> usize;
279    pub fn manifold_triangulation_size() -> usize;
280    pub fn manifold_ray_hit_vec_size() -> usize;
281    pub fn manifold_execution_context_size() -> usize;
282
283    // ── Allocation ─────────────────────────────────────────────────────
284
285    pub fn manifold_alloc_manifold() -> *mut ManifoldManifold;
286    pub fn manifold_alloc_manifold_vec() -> *mut ManifoldManifoldVec;
287    pub fn manifold_alloc_cross_section() -> *mut ManifoldCrossSection;
288    pub fn manifold_alloc_cross_section_vec() -> *mut ManifoldCrossSectionVec;
289    pub fn manifold_alloc_simple_polygon() -> *mut ManifoldSimplePolygon;
290    pub fn manifold_alloc_polygons() -> *mut ManifoldPolygons;
291    pub fn manifold_alloc_meshgl() -> *mut ManifoldMeshGL;
292    pub fn manifold_alloc_meshgl64() -> *mut ManifoldMeshGL64;
293    pub fn manifold_alloc_box() -> *mut ManifoldBox;
294    pub fn manifold_alloc_rect() -> *mut ManifoldRect;
295    pub fn manifold_alloc_triangulation() -> *mut ManifoldTriangulation;
296    pub fn manifold_alloc_ray_hit_vec() -> *mut ManifoldRayHitVec;
297    pub fn manifold_alloc_execution_context() -> *mut ManifoldExecutionContext;
298
299    // ── Destruction (destruct only, does not free) ─────────────────────
300
301    pub fn manifold_destruct_manifold(m: *mut ManifoldManifold);
302    pub fn manifold_destruct_manifold_vec(ms: *mut ManifoldManifoldVec);
303    pub fn manifold_destruct_cross_section(m: *mut ManifoldCrossSection);
304    pub fn manifold_destruct_cross_section_vec(csv: *mut ManifoldCrossSectionVec);
305    pub fn manifold_destruct_simple_polygon(p: *mut ManifoldSimplePolygon);
306    pub fn manifold_destruct_polygons(p: *mut ManifoldPolygons);
307    pub fn manifold_destruct_meshgl(m: *mut ManifoldMeshGL);
308    pub fn manifold_destruct_meshgl64(m: *mut ManifoldMeshGL64);
309    pub fn manifold_destruct_box(b: *mut ManifoldBox);
310    pub fn manifold_destruct_rect(b: *mut ManifoldRect);
311    pub fn manifold_destruct_triangulation(m: *mut ManifoldTriangulation);
312    pub fn manifold_destruct_ray_hit_vec(v: *mut ManifoldRayHitVec);
313    pub fn manifold_destruct_execution_context(ctx: *mut ManifoldExecutionContext);
314
315    // ── Deletion (destruct + free) ─────────────────────────────────────
316
317    pub fn manifold_delete_manifold(m: *mut ManifoldManifold);
318    pub fn manifold_delete_manifold_vec(ms: *mut ManifoldManifoldVec);
319    pub fn manifold_delete_cross_section(cs: *mut ManifoldCrossSection);
320    pub fn manifold_delete_cross_section_vec(csv: *mut ManifoldCrossSectionVec);
321    pub fn manifold_delete_simple_polygon(p: *mut ManifoldSimplePolygon);
322    pub fn manifold_delete_polygons(p: *mut ManifoldPolygons);
323    pub fn manifold_delete_meshgl(m: *mut ManifoldMeshGL);
324    pub fn manifold_delete_meshgl64(m: *mut ManifoldMeshGL64);
325    pub fn manifold_delete_box(b: *mut ManifoldBox);
326    pub fn manifold_delete_rect(b: *mut ManifoldRect);
327    pub fn manifold_delete_triangulation(m: *mut ManifoldTriangulation);
328    pub fn manifold_delete_ray_hit_vec(v: *mut ManifoldRayHitVec);
329    pub fn manifold_delete_execution_context(ctx: *mut ManifoldExecutionContext);
330
331    // ── Polygons ───────────────────────────────────────────────────────
332
333    /// Create a simple polygon from an array of 2D points.
334    pub fn manifold_simple_polygon(
335        mem: *mut ManifoldSimplePolygon,
336        ps: *const ManifoldVec2,
337        length: usize,
338    ) -> *mut ManifoldSimplePolygon;
339
340    /// Create a polygon set from an array of simple polygon pointers.
341    pub fn manifold_polygons(
342        mem: *mut ManifoldPolygons,
343        ps: *const *mut ManifoldSimplePolygon,
344        length: usize,
345    ) -> *mut ManifoldPolygons;
346
347    /// Get the number of points in a simple polygon.
348    pub fn manifold_simple_polygon_length(p: *const ManifoldSimplePolygon) -> usize;
349
350    /// Get the number of simple polygons in a polygon set.
351    pub fn manifold_polygons_length(ps: *const ManifoldPolygons) -> usize;
352
353    /// Get the number of points in a specific simple polygon within a polygon set.
354    pub fn manifold_polygons_simple_length(ps: *const ManifoldPolygons, idx: usize) -> usize;
355
356    /// Get a point from a simple polygon by index.
357    pub fn manifold_simple_polygon_get_point(
358        p: *const ManifoldSimplePolygon,
359        idx: usize,
360    ) -> ManifoldVec2;
361
362    /// Extract a simple polygon from a polygon set by index.
363    pub fn manifold_polygons_get_simple(
364        mem: *mut ManifoldSimplePolygon,
365        ps: *const ManifoldPolygons,
366        idx: usize,
367    ) -> *mut ManifoldSimplePolygon;
368
369    /// Get a point from a polygon set by simple polygon index and point index.
370    pub fn manifold_polygons_get_point(
371        ps: *const ManifoldPolygons,
372        simple_idx: usize,
373        pt_idx: usize,
374    ) -> ManifoldVec2;
375
376    // ── MeshGL construction (f32) ───────────────────────────────────────
377
378    /// Create a `MeshGL` from vertex properties and triangle indices.
379    /// `vert_props`: flat f32 array [x,y,z,...] with `n_props` values per vertex.
380    /// `tri_verts`: flat u32 array, 3 indices per triangle.
381    pub fn manifold_meshgl(
382        mem: *mut ManifoldMeshGL,
383        vert_props: *const f32,
384        n_verts: usize,
385        n_props: usize,
386        tri_verts: *const u32,
387        n_tris: usize,
388    ) -> *mut ManifoldMeshGL;
389
390    /// Create a `MeshGL` with halfedge tangents.
391    pub fn manifold_meshgl_w_tangents(
392        mem: *mut ManifoldMeshGL,
393        vert_props: *const f32,
394        n_verts: usize,
395        n_props: usize,
396        tri_verts: *const u32,
397        n_tris: usize,
398        halfedge_tangent: *const f32,
399    ) -> *mut ManifoldMeshGL;
400
401    /// Create a `MeshGL` with full options (run indices, merge, tangents).
402    pub fn manifold_meshgl_w_options(
403        mem: *mut ManifoldMeshGL,
404        vert_props: *const f32,
405        n_verts: usize,
406        n_props: usize,
407        tri_verts: *const u32,
408        n_tris: usize,
409        options: *const ManifoldMeshGLOptions,
410    ) -> *mut ManifoldMeshGL;
411
412    /// Create a Manifold from a `MeshGL`.
413    pub fn manifold_of_meshgl(
414        mem: *mut ManifoldManifold,
415        mesh: *const ManifoldMeshGL,
416    ) -> *mut ManifoldManifold;
417
418    /// Extract `MeshGL` from a Manifold.
419    pub fn manifold_get_meshgl(
420        mem: *mut ManifoldMeshGL,
421        m: *const ManifoldManifold,
422    ) -> *mut ManifoldMeshGL;
423
424    /// Extract `MeshGL` from a Manifold with normals at the given property index.
425    pub fn manifold_get_meshgl_w_normals(
426        mem: *mut ManifoldMeshGL,
427        m: *const ManifoldManifold,
428        normal_idx: i32,
429    ) -> *mut ManifoldMeshGL;
430
431    /// Copy a `MeshGL`.
432    pub fn manifold_meshgl_copy(
433        mem: *mut ManifoldMeshGL,
434        m: *const ManifoldMeshGL,
435    ) -> *mut ManifoldMeshGL;
436
437    /// Merge coincident vertices in a `MeshGL`, returning a new merged mesh.
438    pub fn manifold_meshgl_merge(
439        mem: *mut ManifoldMeshGL,
440        m: *const ManifoldMeshGL,
441    ) -> *mut ManifoldMeshGL;
442
443    // ── MeshGL data access ──────────────────────────────────────────────
444
445    pub fn manifold_meshgl_num_prop(m: *const ManifoldMeshGL) -> usize;
446    pub fn manifold_meshgl_num_vert(m: *const ManifoldMeshGL) -> usize;
447    pub fn manifold_meshgl_num_tri(m: *const ManifoldMeshGL) -> usize;
448    pub fn manifold_meshgl_vert_properties_length(m: *const ManifoldMeshGL) -> usize;
449    pub fn manifold_meshgl_tri_length(m: *const ManifoldMeshGL) -> usize;
450    pub fn manifold_meshgl_merge_length(m: *const ManifoldMeshGL) -> usize;
451    pub fn manifold_meshgl_run_index_length(m: *const ManifoldMeshGL) -> usize;
452    pub fn manifold_meshgl_run_original_id_length(m: *const ManifoldMeshGL) -> usize;
453    pub fn manifold_meshgl_run_transform_length(m: *const ManifoldMeshGL) -> usize;
454    pub fn manifold_meshgl_face_id_length(m: *const ManifoldMeshGL) -> usize;
455    pub fn manifold_meshgl_tangent_length(m: *const ManifoldMeshGL) -> usize;
456
457    /// Copy vertex properties into caller-provided buffer.
458    pub fn manifold_meshgl_vert_properties(mem: *mut f32, m: *const ManifoldMeshGL) -> *mut f32;
459
460    /// Copy triangle indices into caller-provided buffer.
461    pub fn manifold_meshgl_tri_verts(mem: *mut u32, m: *const ManifoldMeshGL) -> *mut u32;
462
463    /// Copy merge-from vertex indices into caller-provided buffer.
464    pub fn manifold_meshgl_merge_from_vert(mem: *mut u32, m: *const ManifoldMeshGL) -> *mut u32;
465
466    /// Copy merge-to vertex indices into caller-provided buffer.
467    pub fn manifold_meshgl_merge_to_vert(mem: *mut u32, m: *const ManifoldMeshGL) -> *mut u32;
468
469    /// Copy run indices into caller-provided buffer.
470    pub fn manifold_meshgl_run_index(mem: *mut u32, m: *const ManifoldMeshGL) -> *mut u32;
471
472    /// Copy run original IDs into caller-provided buffer.
473    pub fn manifold_meshgl_run_original_id(mem: *mut u32, m: *const ManifoldMeshGL) -> *mut u32;
474
475    /// Copy run transforms into caller-provided buffer.
476    pub fn manifold_meshgl_run_transform(mem: *mut f32, m: *const ManifoldMeshGL) -> *mut f32;
477
478    /// Copy face IDs into caller-provided buffer.
479    pub fn manifold_meshgl_face_id(mem: *mut u32, m: *const ManifoldMeshGL) -> *mut u32;
480
481    /// Copy halfedge tangents into caller-provided buffer.
482    pub fn manifold_meshgl_halfedge_tangent(mem: *mut f32, m: *const ManifoldMeshGL) -> *mut f32;
483
484    /// Get the tolerance of a MeshGL.
485    pub fn manifold_meshgl_tolerance(m: *const ManifoldMeshGL) -> f32;
486
487    /// Get the number of run flags.
488    pub fn manifold_meshgl_run_flags_length(m: *const ManifoldMeshGL) -> usize;
489
490    /// Copy run flags into caller-provided buffer.
491    pub fn manifold_meshgl_run_flags(mem: *mut u8, m: *const ManifoldMeshGL) -> *mut u8;
492
493    /// Get the number of triangle runs.
494    pub fn manifold_meshgl_num_run(m: *const ManifoldMeshGL) -> usize;
495
496    // ── MeshGL64 construction (f64 vertices, u64 indices) ───────────────
497
498    /// Create a `MeshGL64` from f64 vertex properties and u64 triangle indices.
499    pub fn manifold_meshgl64(
500        mem: *mut ManifoldMeshGL64,
501        vert_props: *const f64,
502        n_verts: usize,
503        n_props: usize,
504        tri_verts: *const u64,
505        n_tris: usize,
506    ) -> *mut ManifoldMeshGL64;
507
508    /// Create a `MeshGL64` with halfedge tangents.
509    pub fn manifold_meshgl64_w_tangents(
510        mem: *mut ManifoldMeshGL64,
511        vert_props: *const f64,
512        n_verts: usize,
513        n_props: usize,
514        tri_verts: *const u64,
515        n_tris: usize,
516        halfedge_tangent: *const f64,
517    ) -> *mut ManifoldMeshGL64;
518
519    /// Create a `MeshGL64` with full options (run indices, merge, tangents).
520    pub fn manifold_meshgl64_w_options(
521        mem: *mut ManifoldMeshGL64,
522        vert_props: *const f64,
523        n_verts: usize,
524        n_props: usize,
525        tri_verts: *const u64,
526        n_tris: usize,
527        options: *const ManifoldMeshGL64Options,
528    ) -> *mut ManifoldMeshGL64;
529
530    /// Create a Manifold from a `MeshGL64`.
531    pub fn manifold_of_meshgl64(
532        mem: *mut ManifoldManifold,
533        mesh: *const ManifoldMeshGL64,
534    ) -> *mut ManifoldManifold;
535
536    /// Extract `MeshGL64` from a Manifold.
537    pub fn manifold_get_meshgl64(
538        mem: *mut ManifoldMeshGL64,
539        m: *const ManifoldManifold,
540    ) -> *mut ManifoldMeshGL64;
541
542    /// Extract `MeshGL64` from a Manifold with normals at the given property index.
543    pub fn manifold_get_meshgl64_w_normals(
544        mem: *mut ManifoldMeshGL64,
545        m: *const ManifoldManifold,
546        normal_idx: i32,
547    ) -> *mut ManifoldMeshGL64;
548
549    /// Copy a `MeshGL64`.
550    pub fn manifold_meshgl64_copy(
551        mem: *mut ManifoldMeshGL64,
552        m: *const ManifoldMeshGL64,
553    ) -> *mut ManifoldMeshGL64;
554
555    /// Merge coincident vertices in a `MeshGL64`, returning a new merged mesh.
556    pub fn manifold_meshgl64_merge(
557        mem: *mut ManifoldMeshGL64,
558        m: *const ManifoldMeshGL64,
559    ) -> *mut ManifoldMeshGL64;
560
561    // ── MeshGL64 data access ────────────────────────────────────────────
562
563    pub fn manifold_meshgl64_num_prop(m: *const ManifoldMeshGL64) -> usize;
564    pub fn manifold_meshgl64_num_vert(m: *const ManifoldMeshGL64) -> usize;
565    pub fn manifold_meshgl64_num_tri(m: *const ManifoldMeshGL64) -> usize;
566    pub fn manifold_meshgl64_vert_properties_length(m: *const ManifoldMeshGL64) -> usize;
567    pub fn manifold_meshgl64_tri_length(m: *const ManifoldMeshGL64) -> usize;
568    pub fn manifold_meshgl64_merge_length(m: *const ManifoldMeshGL64) -> usize;
569    pub fn manifold_meshgl64_run_index_length(m: *const ManifoldMeshGL64) -> usize;
570    pub fn manifold_meshgl64_run_original_id_length(m: *const ManifoldMeshGL64) -> usize;
571    pub fn manifold_meshgl64_run_transform_length(m: *const ManifoldMeshGL64) -> usize;
572    pub fn manifold_meshgl64_face_id_length(m: *const ManifoldMeshGL64) -> usize;
573    pub fn manifold_meshgl64_tangent_length(m: *const ManifoldMeshGL64) -> usize;
574
575    /// Copy f64 vertex properties into caller-provided buffer.
576    pub fn manifold_meshgl64_vert_properties(mem: *mut f64, m: *const ManifoldMeshGL64)
577    -> *mut f64;
578
579    /// Copy u64 triangle indices into caller-provided buffer.
580    pub fn manifold_meshgl64_tri_verts(mem: *mut u64, m: *const ManifoldMeshGL64) -> *mut u64;
581
582    /// Copy merge-from vertex indices into caller-provided buffer.
583    pub fn manifold_meshgl64_merge_from_vert(mem: *mut u64, m: *const ManifoldMeshGL64)
584    -> *mut u64;
585
586    /// Copy merge-to vertex indices into caller-provided buffer.
587    pub fn manifold_meshgl64_merge_to_vert(mem: *mut u64, m: *const ManifoldMeshGL64) -> *mut u64;
588
589    /// Copy run indices into caller-provided buffer.
590    pub fn manifold_meshgl64_run_index(mem: *mut u64, m: *const ManifoldMeshGL64) -> *mut u64;
591
592    /// Copy run original IDs into caller-provided buffer.
593    pub fn manifold_meshgl64_run_original_id(mem: *mut u32, m: *const ManifoldMeshGL64)
594    -> *mut u32;
595
596    /// Copy run transforms into caller-provided buffer.
597    pub fn manifold_meshgl64_run_transform(mem: *mut f64, m: *const ManifoldMeshGL64) -> *mut f64;
598
599    /// Copy face IDs into caller-provided buffer.
600    pub fn manifold_meshgl64_face_id(mem: *mut u64, m: *const ManifoldMeshGL64) -> *mut u64;
601
602    /// Copy halfedge tangents into caller-provided buffer.
603    pub fn manifold_meshgl64_halfedge_tangent(
604        mem: *mut f64,
605        m: *const ManifoldMeshGL64,
606    ) -> *mut f64;
607
608    /// Get the tolerance of a MeshGL64.
609    pub fn manifold_meshgl64_tolerance(m: *const ManifoldMeshGL64) -> f64;
610
611    /// Get the number of run flags.
612    pub fn manifold_meshgl64_run_flags_length(m: *const ManifoldMeshGL64) -> usize;
613
614    /// Copy run flags into caller-provided buffer.
615    pub fn manifold_meshgl64_run_flags(mem: *mut u8, m: *const ManifoldMeshGL64) -> *mut u8;
616
617    /// Get the number of triangle runs.
618    pub fn manifold_meshgl64_num_run(m: *const ManifoldMeshGL64) -> usize;
619
620    // ── SDF (level set) ────────────────────────────────────────────────
621
622    /// Create a manifold from a signed distance function.
623    ///
624    /// By default, the execution policy (sequential or parallel) will be chosen
625    /// automatically depending on the size of the job and whether Manifold has
626    /// been compiled with a PAR backend.
627    pub fn manifold_level_set(
628        mem: *mut ManifoldManifold,
629        sdf: ManifoldSdf,
630        bounds: *mut ManifoldBox,
631        edge_length: f64,
632        level: f64,
633        tolerance: f64,
634        ctx: *mut std::ffi::c_void,
635    ) -> *mut ManifoldManifold;
636
637    /// Create a manifold from a signed distance function (sequential execution).
638    ///
639    /// Use this if you are calling from a language runtime that has a lock
640    /// preventing parallel execution of closures.
641    pub fn manifold_level_set_seq(
642        mem: *mut ManifoldManifold,
643        sdf: ManifoldSdf,
644        bounds: *mut ManifoldBox,
645        edge_length: f64,
646        level: f64,
647        tolerance: f64,
648        ctx: *mut std::ffi::c_void,
649    ) -> *mut ManifoldManifold;
650
651    // ── Manifold vectors ───────────────────────────────────────────────
652
653    pub fn manifold_manifold_empty_vec(mem: *mut ManifoldManifoldVec) -> *mut ManifoldManifoldVec;
654
655    pub fn manifold_manifold_vec(
656        mem: *mut ManifoldManifoldVec,
657        sz: usize,
658    ) -> *mut ManifoldManifoldVec;
659
660    pub fn manifold_manifold_vec_reserve(ms: *mut ManifoldManifoldVec, sz: usize);
661
662    pub fn manifold_manifold_vec_length(ms: *const ManifoldManifoldVec) -> usize;
663
664    pub fn manifold_manifold_vec_get(
665        mem: *mut ManifoldManifold,
666        ms: *const ManifoldManifoldVec,
667        idx: usize,
668    ) -> *mut ManifoldManifold;
669
670    pub fn manifold_manifold_vec_set(
671        ms: *mut ManifoldManifoldVec,
672        idx: usize,
673        m: *mut ManifoldManifold,
674    );
675
676    pub fn manifold_manifold_vec_push_back(ms: *mut ManifoldManifoldVec, m: *mut ManifoldManifold);
677
678    // ── Manifold boolean operations ────────────────────────────────────
679
680    /// Generic boolean operation between two manifolds.
681    pub fn manifold_boolean(
682        mem: *mut ManifoldManifold,
683        a: *const ManifoldManifold,
684        b: *const ManifoldManifold,
685        op: ManifoldOpType,
686    ) -> *mut ManifoldManifold;
687
688    /// Batch boolean: apply `op` across all manifolds in the vector.
689    pub fn manifold_batch_boolean(
690        mem: *mut ManifoldManifold,
691        ms: *mut ManifoldManifoldVec,
692        op: ManifoldOpType,
693    ) -> *mut ManifoldManifold;
694
695    pub fn manifold_union(
696        mem: *mut ManifoldManifold,
697        a: *const ManifoldManifold,
698        b: *const ManifoldManifold,
699    ) -> *mut ManifoldManifold;
700
701    pub fn manifold_difference(
702        mem: *mut ManifoldManifold,
703        a: *const ManifoldManifold,
704        b: *const ManifoldManifold,
705    ) -> *mut ManifoldManifold;
706
707    pub fn manifold_intersection(
708        mem: *mut ManifoldManifold,
709        a: *const ManifoldManifold,
710        b: *const ManifoldManifold,
711    ) -> *mut ManifoldManifold;
712
713    /// Split manifold `a` by manifold `b` into two parts.
714    pub fn manifold_split(
715        mem_first: *mut ManifoldManifold,
716        mem_second: *mut ManifoldManifold,
717        a: *const ManifoldManifold,
718        b: *const ManifoldManifold,
719    ) -> ManifoldManifoldPair;
720
721    /// Minkowski sum of two manifolds.
722    pub fn manifold_minkowski_sum(
723        mem: *mut ManifoldManifold,
724        a: *const ManifoldManifold,
725        b: *const ManifoldManifold,
726    ) -> *mut ManifoldManifold;
727
728    /// Minkowski difference of two manifolds.
729    pub fn manifold_minkowski_difference(
730        mem: *mut ManifoldManifold,
731        a: *const ManifoldManifold,
732        b: *const ManifoldManifold,
733    ) -> *mut ManifoldManifold;
734
735    // ── Plane operations ────────────────────────────────────────────────
736
737    /// Split a manifold into two halves along a plane.
738    ///
739    /// The plane is `nx*x + ny*y + nz*z = offset`.
740    /// Returns a pair: `first` is on the positive side, `second` on negative.
741    pub fn manifold_split_by_plane(
742        mem_first: *mut ManifoldManifold,
743        mem_second: *mut ManifoldManifold,
744        m: *const ManifoldManifold,
745        normal_x: f64,
746        normal_y: f64,
747        normal_z: f64,
748        offset: f64,
749    ) -> ManifoldManifoldPair;
750
751    /// Trim to the positive side of a plane.
752    pub fn manifold_trim_by_plane(
753        mem: *mut ManifoldManifold,
754        m: *const ManifoldManifold,
755        normal_x: f64,
756        normal_y: f64,
757        normal_z: f64,
758        offset: f64,
759    ) -> *mut ManifoldManifold;
760
761    // ── 3D to 2D ────────────────────────────────────────────────────────
762
763    /// Slice a manifold at a given Z height, returning 2D polygons.
764    pub fn manifold_slice(
765        mem: *mut ManifoldPolygons,
766        m: *const ManifoldManifold,
767        height: f64,
768    ) -> *mut ManifoldPolygons;
769
770    /// Project a manifold onto the XY plane, returning 2D polygons.
771    pub fn manifold_project(
772        mem: *mut ManifoldPolygons,
773        m: *const ManifoldManifold,
774    ) -> *mut ManifoldPolygons;
775
776    // ── Convex hulls ────────────────────────────────────────────────────
777
778    /// Compute the convex hull of a manifold.
779    pub fn manifold_hull(
780        mem: *mut ManifoldManifold,
781        m: *const ManifoldManifold,
782    ) -> *mut ManifoldManifold;
783
784    /// Compute the convex hull of a set of manifolds.
785    pub fn manifold_batch_hull(
786        mem: *mut ManifoldManifold,
787        ms: *mut ManifoldManifoldVec,
788    ) -> *mut ManifoldManifold;
789
790    /// Compute the convex hull of a set of 3D points.
791    pub fn manifold_hull_pts(
792        mem: *mut ManifoldManifold,
793        ps: *const ManifoldVec3,
794        length: usize,
795    ) -> *mut ManifoldManifold;
796
797    // ── Transforms ──────────────────────────────────────────────────────
798
799    pub fn manifold_translate(
800        mem: *mut ManifoldManifold,
801        m: *const ManifoldManifold,
802        x: f64,
803        y: f64,
804        z: f64,
805    ) -> *mut ManifoldManifold;
806
807    /// Rotate by Euler angles (degrees), applied in z-y'-x" order.
808    pub fn manifold_rotate(
809        mem: *mut ManifoldManifold,
810        m: *const ManifoldManifold,
811        x: f64,
812        y: f64,
813        z: f64,
814    ) -> *mut ManifoldManifold;
815
816    pub fn manifold_scale(
817        mem: *mut ManifoldManifold,
818        m: *const ManifoldManifold,
819        x: f64,
820        y: f64,
821        z: f64,
822    ) -> *mut ManifoldManifold;
823
824    /// Apply a 4x3 affine transformation matrix (column-major).
825    ///
826    /// ```text
827    /// | x1 x2 x3 x4 |     col1 = (x1, y1, z1) -- X basis
828    /// | y1 y2 y3 y4 |     col2 = (x2, y2, z2) -- Y basis
829    /// | z1 z2 z3 z4 |     col3 = (x3, y3, z3) -- Z basis
830    ///                      col4 = (x4, y4, z4) -- translation
831    /// ```
832    pub fn manifold_transform(
833        mem: *mut ManifoldManifold,
834        m: *const ManifoldManifold,
835        x1: f64,
836        y1: f64,
837        z1: f64,
838        x2: f64,
839        y2: f64,
840        z2: f64,
841        x3: f64,
842        y3: f64,
843        z3: f64,
844        x4: f64,
845        y4: f64,
846        z4: f64,
847    ) -> *mut ManifoldManifold;
848
849    /// Mirror a manifold across the plane defined by normal (nx, ny, nz).
850    pub fn manifold_mirror(
851        mem: *mut ManifoldManifold,
852        m: *const ManifoldManifold,
853        nx: f64,
854        ny: f64,
855        nz: f64,
856    ) -> *mut ManifoldManifold;
857
858    /// Warp a manifold by applying a function to each vertex.
859    pub fn manifold_warp(
860        mem: *mut ManifoldManifold,
861        m: *const ManifoldManifold,
862        fun: Option<unsafe extern "C" fn(f64, f64, f64, *mut std::ffi::c_void) -> ManifoldVec3>,
863        ctx: *mut std::ffi::c_void,
864    ) -> *mut ManifoldManifold;
865
866    /// Smooth a manifold by converting sharp edges to smooth curves using
867    /// vertex normals at the given property index.
868    pub fn manifold_smooth_by_normals(
869        mem: *mut ManifoldManifold,
870        m: *const ManifoldManifold,
871        normal_idx: c_int,
872    ) -> *mut ManifoldManifold;
873
874    /// Smooth out sharp edges of a manifold.
875    pub fn manifold_smooth_out(
876        mem: *mut ManifoldManifold,
877        m: *const ManifoldManifold,
878        min_sharp_angle: f64,
879        min_smoothness: f64,
880    ) -> *mut ManifoldManifold;
881
882    /// Increase the density of the mesh by splitting every edge into
883    /// `refine` pieces.
884    pub fn manifold_refine(
885        mem: *mut ManifoldManifold,
886        m: *const ManifoldManifold,
887        refine: c_int,
888    ) -> *mut ManifoldManifold;
889
890    /// Refine the mesh so that no edge is longer than `length`.
891    pub fn manifold_refine_to_length(
892        mem: *mut ManifoldManifold,
893        m: *const ManifoldManifold,
894        length: f64,
895    ) -> *mut ManifoldManifold;
896
897    /// Refine the mesh to a given tolerance.
898    pub fn manifold_refine_to_tolerance(
899        mem: *mut ManifoldManifold,
900        m: *const ManifoldManifold,
901        tolerance: f64,
902    ) -> *mut ManifoldManifold;
903
904    /// Set the tolerance of the manifold, returning a new manifold.
905    pub fn manifold_set_tolerance(
906        mem: *mut ManifoldManifold,
907        m: *const ManifoldManifold,
908        tolerance: f64,
909    ) -> *mut ManifoldManifold;
910
911    /// Simplify the mesh, removing vertices until the error exceeds `tolerance`.
912    pub fn manifold_simplify(
913        mem: *mut ManifoldManifold,
914        m: *const ManifoldManifold,
915        tolerance: f64,
916    ) -> *mut ManifoldManifold;
917
918    // ── Shapes / Constructors ───────────────────────────────────────────
919
920    pub fn manifold_empty(mem: *mut ManifoldManifold) -> *mut ManifoldManifold;
921
922    pub fn manifold_copy(
923        mem: *mut ManifoldManifold,
924        m: *const ManifoldManifold,
925    ) -> *mut ManifoldManifold;
926
927    /// Construct a regular tetrahedron.
928    pub fn manifold_tetrahedron(mem: *mut ManifoldManifold) -> *mut ManifoldManifold;
929
930    pub fn manifold_cube(
931        mem: *mut ManifoldManifold,
932        x: f64,
933        y: f64,
934        z: f64,
935        center: c_int,
936    ) -> *mut ManifoldManifold;
937
938    pub fn manifold_cylinder(
939        mem: *mut ManifoldManifold,
940        height: f64,
941        radius_low: f64,
942        radius_high: f64,
943        circular_segments: c_int,
944        center: c_int,
945    ) -> *mut ManifoldManifold;
946
947    pub fn manifold_sphere(
948        mem: *mut ManifoldManifold,
949        radius: f64,
950        circular_segments: c_int,
951    ) -> *mut ManifoldManifold;
952
953    /// Create a smooth manifold from a `MeshGL` with per-halfedge smoothness.
954    pub fn manifold_smooth(
955        mem: *mut ManifoldManifold,
956        mesh: *const ManifoldMeshGL,
957        half_edges: *const usize,
958        smoothness: *const f64,
959        n_idxs: usize,
960    ) -> *mut ManifoldManifold;
961
962    /// Create a smooth manifold from a `MeshGL64` with per-halfedge smoothness.
963    pub fn manifold_smooth64(
964        mem: *mut ManifoldManifold,
965        mesh: *const ManifoldMeshGL64,
966        half_edges: *const usize,
967        smoothness: *const f64,
968        n_idxs: usize,
969    ) -> *mut ManifoldManifold;
970
971    /// Extrude a 2D polygon set into a 3D manifold along the Z axis.
972    ///
973    /// The resulting solid spans `z in [0, height]`.
974    pub fn manifold_extrude(
975        mem: *mut ManifoldManifold,
976        cs: *const ManifoldPolygons,
977        height: f64,
978        slices: c_int,
979        twist_degrees: f64,
980        scale_x: f64,
981        scale_y: f64,
982    ) -> *mut ManifoldManifold;
983
984    /// Revolve a 2D polygon set around the Y axis to create a 3D manifold.
985    pub fn manifold_revolve(
986        mem: *mut ManifoldManifold,
987        cs: *const ManifoldPolygons,
988        circular_segments: c_int,
989        revolve_degrees: f64,
990    ) -> *mut ManifoldManifold;
991
992    /// Compose multiple manifolds into a single compound manifold.
993    pub fn manifold_compose(
994        mem: *mut ManifoldManifold,
995        ms: *mut ManifoldManifoldVec,
996    ) -> *mut ManifoldManifold;
997
998    /// Decompose a manifold into its connected components.
999    pub fn manifold_decompose(
1000        mem: *mut ManifoldManifoldVec,
1001        m: *const ManifoldManifold,
1002    ) -> *mut ManifoldManifoldVec;
1003
1004    /// Mark this manifold as the original, assigning it a unique ID for
1005    /// tracking through boolean operations.
1006    pub fn manifold_as_original(
1007        mem: *mut ManifoldManifold,
1008        m: *const ManifoldManifold,
1009    ) -> *mut ManifoldManifold;
1010
1011    // ── Manifold info / queries ─────────────────────────────────────────
1012
1013    pub fn manifold_is_empty(m: *const ManifoldManifold) -> c_int;
1014    pub fn manifold_status(m: *const ManifoldManifold) -> ManifoldError;
1015    /// Returns a copy of `m` with `ctx` attached. The attachment is
1016    /// consumed by the next eager op (`manifold_status`, `manifold_refine*`).
1017    /// Deferred ops (booleans, transforms, batch) ignore any attached
1018    /// context and produce results with no attached context.
1019    pub fn manifold_with_context(
1020        mem: *mut ManifoldManifold,
1021        m: *const ManifoldManifold,
1022        ctx: *mut ManifoldExecutionContext,
1023    ) -> *mut ManifoldManifold;
1024    pub fn manifold_num_vert(m: *const ManifoldManifold) -> usize;
1025    pub fn manifold_num_edge(m: *const ManifoldManifold) -> usize;
1026    pub fn manifold_num_tri(m: *const ManifoldManifold) -> usize;
1027    pub fn manifold_num_prop(m: *const ManifoldManifold) -> usize;
1028    pub fn manifold_volume(m: *const ManifoldManifold) -> f64;
1029    pub fn manifold_surface_area(m: *const ManifoldManifold) -> f64;
1030    pub fn manifold_epsilon(m: *const ManifoldManifold) -> f64;
1031    pub fn manifold_get_tolerance(m: *const ManifoldManifold) -> f64;
1032    pub fn manifold_num_prop_vert(m: *const ManifoldManifold) -> usize;
1033    pub fn manifold_genus(m: *const ManifoldManifold) -> c_int;
1034    pub fn manifold_original_id(m: *const ManifoldManifold) -> c_int;
1035
1036    /// Get the number of circular segments for a given radius.
1037    pub fn manifold_get_circular_segments(radius: f64) -> c_int;
1038
1039    /// Reserve a block of unique IDs for use with `manifold_as_original`.
1040    pub fn manifold_reserve_ids(n: u32) -> u32;
1041
1042    /// Set custom properties on each vertex of a manifold.
1043    ///
1044    /// The callback receives: `(new_prop, position, old_prop, ctx)`.
1045    pub fn manifold_set_properties(
1046        mem: *mut ManifoldManifold,
1047        m: *const ManifoldManifold,
1048        num_prop: c_int,
1049        fun: Option<
1050            unsafe extern "C" fn(*mut f64, ManifoldVec3, *const f64, *mut std::ffi::c_void),
1051        >,
1052        ctx: *mut std::ffi::c_void,
1053    ) -> *mut ManifoldManifold;
1054
1055    /// Calculate Gaussian and mean curvature and store at the given property indices.
1056    pub fn manifold_calculate_curvature(
1057        mem: *mut ManifoldManifold,
1058        m: *const ManifoldManifold,
1059        gaussian_idx: c_int,
1060        mean_idx: c_int,
1061    ) -> *mut ManifoldManifold;
1062
1063    /// Compute the minimum gap between two manifolds within `search_length`.
1064    pub fn manifold_min_gap(
1065        m: *const ManifoldManifold,
1066        other: *const ManifoldManifold,
1067        search_length: f64,
1068    ) -> f64;
1069
1070    /// Calculate vertex normals and store at the given property index.
1071    pub fn manifold_calculate_normals(
1072        mem: *mut ManifoldManifold,
1073        m: *const ManifoldManifold,
1074        normal_idx: c_int,
1075        min_sharp_angle: f64,
1076    ) -> *mut ManifoldManifold;
1077
1078    // ── Ray casting ─────────────────────────────────────────────────────
1079
1080    /// Cast a ray from `origin` to `end` against a manifold, returning all hits.
1081    pub fn manifold_ray_cast(
1082        mem: *mut ManifoldRayHitVec,
1083        m: *const ManifoldManifold,
1084        origin_x: f64,
1085        origin_y: f64,
1086        origin_z: f64,
1087        end_x: f64,
1088        end_y: f64,
1089        end_z: f64,
1090    ) -> *mut ManifoldRayHitVec;
1091
1092    /// Number of hits in a ray hit vector.
1093    pub fn manifold_ray_hit_vec_length(v: *const ManifoldRayHitVec) -> usize;
1094
1095    /// Get a hit by index from a ray hit vector.
1096    pub fn manifold_ray_hit_vec_get(v: *const ManifoldRayHitVec, idx: usize) -> ManifoldRayHit;
1097
1098    // ── Execution context (cancel + progress) ───────────────────────────
1099
1100    /// Construct an `ExecutionContext` in pre-allocated memory. Attach
1101    /// to a manifold via [`manifold_with_context`]; subsequent eager
1102    /// operations on the result observe the context.
1103    pub fn manifold_execution_context(
1104        mem: *mut ManifoldExecutionContext,
1105    ) -> *mut ManifoldExecutionContext;
1106
1107    /// Request cancellation of any boolean evaluation observing this context.
1108    /// Sticky: once cancelled, the context stays cancelled.
1109    pub fn manifold_execution_context_cancel(ctx: *mut ManifoldExecutionContext);
1110
1111    /// Returns nonzero if the context has been cancelled.
1112    pub fn manifold_execution_context_cancelled(ctx: *mut ManifoldExecutionContext) -> c_int;
1113
1114    /// Progress in [0.0, 1.0] for an in-flight evaluation observing this context.
1115    pub fn manifold_execution_context_progress(ctx: *mut ManifoldExecutionContext) -> f64;
1116
1117    // ── Bounding box ────────────────────────────────────────────────────
1118
1119    pub fn manifold_bounding_box(
1120        mem: *mut ManifoldBox,
1121        m: *const ManifoldManifold,
1122    ) -> *mut ManifoldBox;
1123
1124    pub fn manifold_box(
1125        mem: *mut ManifoldBox,
1126        x1: f64,
1127        y1: f64,
1128        z1: f64,
1129        x2: f64,
1130        y2: f64,
1131        z2: f64,
1132    ) -> *mut ManifoldBox;
1133
1134    pub fn manifold_box_min(b: *const ManifoldBox) -> ManifoldVec3;
1135    pub fn manifold_box_max(b: *const ManifoldBox) -> ManifoldVec3;
1136    pub fn manifold_box_dimensions(b: *const ManifoldBox) -> ManifoldVec3;
1137    pub fn manifold_box_center(b: *const ManifoldBox) -> ManifoldVec3;
1138    pub fn manifold_box_scale(b: *const ManifoldBox) -> f64;
1139
1140    pub fn manifold_box_contains_pt(b: *const ManifoldBox, x: f64, y: f64, z: f64) -> c_int;
1141
1142    pub fn manifold_box_contains_box(a: *const ManifoldBox, b: *const ManifoldBox) -> c_int;
1143
1144    pub fn manifold_box_include_pt(b: *mut ManifoldBox, x: f64, y: f64, z: f64);
1145
1146    pub fn manifold_box_union(
1147        mem: *mut ManifoldBox,
1148        a: *const ManifoldBox,
1149        b: *const ManifoldBox,
1150    ) -> *mut ManifoldBox;
1151
1152    pub fn manifold_box_transform(
1153        mem: *mut ManifoldBox,
1154        b: *const ManifoldBox,
1155        x1: f64,
1156        y1: f64,
1157        z1: f64,
1158        x2: f64,
1159        y2: f64,
1160        z2: f64,
1161        x3: f64,
1162        y3: f64,
1163        z3: f64,
1164        x4: f64,
1165        y4: f64,
1166        z4: f64,
1167    ) -> *mut ManifoldBox;
1168
1169    pub fn manifold_box_translate(
1170        mem: *mut ManifoldBox,
1171        b: *const ManifoldBox,
1172        x: f64,
1173        y: f64,
1174        z: f64,
1175    ) -> *mut ManifoldBox;
1176
1177    pub fn manifold_box_mul(
1178        mem: *mut ManifoldBox,
1179        b: *const ManifoldBox,
1180        x: f64,
1181        y: f64,
1182        z: f64,
1183    ) -> *mut ManifoldBox;
1184
1185    pub fn manifold_box_does_overlap_pt(b: *const ManifoldBox, x: f64, y: f64, z: f64) -> c_int;
1186
1187    pub fn manifold_box_does_overlap_box(a: *const ManifoldBox, b: *const ManifoldBox) -> c_int;
1188
1189    pub fn manifold_box_is_finite(b: *const ManifoldBox) -> c_int;
1190
1191    // ── CrossSection constructors ───────────────────────────────────────
1192
1193    pub fn manifold_cross_section_empty(
1194        mem: *mut ManifoldCrossSection,
1195    ) -> *mut ManifoldCrossSection;
1196
1197    pub fn manifold_cross_section_copy(
1198        mem: *mut ManifoldCrossSection,
1199        cs: *const ManifoldCrossSection,
1200    ) -> *mut ManifoldCrossSection;
1201
1202    pub fn manifold_cross_section_of_simple_polygon(
1203        mem: *mut ManifoldCrossSection,
1204        p: *const ManifoldSimplePolygon,
1205        fr: ManifoldFillRule,
1206    ) -> *mut ManifoldCrossSection;
1207
1208    pub fn manifold_cross_section_of_polygons(
1209        mem: *mut ManifoldCrossSection,
1210        p: *const ManifoldPolygons,
1211        fr: ManifoldFillRule,
1212    ) -> *mut ManifoldCrossSection;
1213
1214    pub fn manifold_cross_section_square(
1215        mem: *mut ManifoldCrossSection,
1216        x: f64,
1217        y: f64,
1218        center: c_int,
1219    ) -> *mut ManifoldCrossSection;
1220
1221    pub fn manifold_cross_section_circle(
1222        mem: *mut ManifoldCrossSection,
1223        radius: f64,
1224        circular_segments: c_int,
1225    ) -> *mut ManifoldCrossSection;
1226
1227    /// Compose multiple cross-sections into a single compound cross-section.
1228    pub fn manifold_cross_section_compose(
1229        mem: *mut ManifoldCrossSection,
1230        csv: *mut ManifoldCrossSectionVec,
1231    ) -> *mut ManifoldCrossSection;
1232
1233    // ── CrossSection decompose ──────────────────────────────────────────
1234
1235    pub fn manifold_cross_section_decompose(
1236        mem: *mut ManifoldCrossSectionVec,
1237        cs: *const ManifoldCrossSection,
1238    ) -> *mut ManifoldCrossSectionVec;
1239
1240    // ── CrossSection vectors ────────────────────────────────────────────
1241
1242    pub fn manifold_cross_section_empty_vec(
1243        mem: *mut ManifoldCrossSectionVec,
1244    ) -> *mut ManifoldCrossSectionVec;
1245
1246    pub fn manifold_cross_section_vec(
1247        mem: *mut ManifoldCrossSectionVec,
1248        sz: usize,
1249    ) -> *mut ManifoldCrossSectionVec;
1250
1251    pub fn manifold_cross_section_vec_reserve(csv: *mut ManifoldCrossSectionVec, sz: usize);
1252
1253    pub fn manifold_cross_section_vec_length(csv: *const ManifoldCrossSectionVec) -> usize;
1254
1255    pub fn manifold_cross_section_vec_get(
1256        mem: *mut ManifoldCrossSection,
1257        csv: *const ManifoldCrossSectionVec,
1258        idx: usize,
1259    ) -> *mut ManifoldCrossSection;
1260
1261    pub fn manifold_cross_section_vec_set(
1262        csv: *mut ManifoldCrossSectionVec,
1263        idx: usize,
1264        cs: *mut ManifoldCrossSection,
1265    );
1266
1267    pub fn manifold_cross_section_vec_push_back(
1268        csv: *mut ManifoldCrossSectionVec,
1269        cs: *mut ManifoldCrossSection,
1270    );
1271
1272    // ── CrossSection booleans ───────────────────────────────────────────
1273
1274    /// Generic boolean operation between two cross-sections.
1275    pub fn manifold_cross_section_boolean(
1276        mem: *mut ManifoldCrossSection,
1277        a: *const ManifoldCrossSection,
1278        b: *const ManifoldCrossSection,
1279        op: ManifoldOpType,
1280    ) -> *mut ManifoldCrossSection;
1281
1282    /// Batch boolean: apply `op` across all cross-sections in the vector.
1283    pub fn manifold_cross_section_batch_boolean(
1284        mem: *mut ManifoldCrossSection,
1285        csv: *mut ManifoldCrossSectionVec,
1286        op: ManifoldOpType,
1287    ) -> *mut ManifoldCrossSection;
1288
1289    pub fn manifold_cross_section_union(
1290        mem: *mut ManifoldCrossSection,
1291        a: *const ManifoldCrossSection,
1292        b: *const ManifoldCrossSection,
1293    ) -> *mut ManifoldCrossSection;
1294
1295    pub fn manifold_cross_section_difference(
1296        mem: *mut ManifoldCrossSection,
1297        a: *const ManifoldCrossSection,
1298        b: *const ManifoldCrossSection,
1299    ) -> *mut ManifoldCrossSection;
1300
1301    pub fn manifold_cross_section_intersection(
1302        mem: *mut ManifoldCrossSection,
1303        a: *const ManifoldCrossSection,
1304        b: *const ManifoldCrossSection,
1305    ) -> *mut ManifoldCrossSection;
1306
1307    // ── CrossSection convex hulls ───────────────────────────────────────
1308
1309    pub fn manifold_cross_section_hull(
1310        mem: *mut ManifoldCrossSection,
1311        cs: *const ManifoldCrossSection,
1312    ) -> *mut ManifoldCrossSection;
1313
1314    /// Compute the convex hull of a set of cross-sections.
1315    pub fn manifold_cross_section_batch_hull(
1316        mem: *mut ManifoldCrossSection,
1317        css: *mut ManifoldCrossSectionVec,
1318    ) -> *mut ManifoldCrossSection;
1319
1320    /// Compute the convex hull of a simple polygon.
1321    pub fn manifold_cross_section_hull_simple_polygon(
1322        mem: *mut ManifoldCrossSection,
1323        ps: *const ManifoldSimplePolygon,
1324    ) -> *mut ManifoldCrossSection;
1325
1326    /// Compute the convex hull of a polygon set.
1327    pub fn manifold_cross_section_hull_polygons(
1328        mem: *mut ManifoldCrossSection,
1329        ps: *const ManifoldPolygons,
1330    ) -> *mut ManifoldCrossSection;
1331
1332    // ── CrossSection transforms ─────────────────────────────────────────
1333
1334    pub fn manifold_cross_section_translate(
1335        mem: *mut ManifoldCrossSection,
1336        cs: *const ManifoldCrossSection,
1337        x: f64,
1338        y: f64,
1339    ) -> *mut ManifoldCrossSection;
1340
1341    pub fn manifold_cross_section_rotate(
1342        mem: *mut ManifoldCrossSection,
1343        cs: *const ManifoldCrossSection,
1344        deg: f64,
1345    ) -> *mut ManifoldCrossSection;
1346
1347    pub fn manifold_cross_section_scale(
1348        mem: *mut ManifoldCrossSection,
1349        cs: *const ManifoldCrossSection,
1350        x: f64,
1351        y: f64,
1352    ) -> *mut ManifoldCrossSection;
1353
1354    pub fn manifold_cross_section_mirror(
1355        mem: *mut ManifoldCrossSection,
1356        cs: *const ManifoldCrossSection,
1357        ax_x: f64,
1358        ax_y: f64,
1359    ) -> *mut ManifoldCrossSection;
1360
1361    pub fn manifold_cross_section_transform(
1362        mem: *mut ManifoldCrossSection,
1363        cs: *const ManifoldCrossSection,
1364        x1: f64,
1365        y1: f64,
1366        x2: f64,
1367        y2: f64,
1368        x3: f64,
1369        y3: f64,
1370    ) -> *mut ManifoldCrossSection;
1371
1372    /// Warp a cross-section by applying a function to each vertex.
1373    pub fn manifold_cross_section_warp_context(
1374        mem: *mut ManifoldCrossSection,
1375        cs: *const ManifoldCrossSection,
1376        fun: Option<unsafe extern "C" fn(f64, f64, *mut std::ffi::c_void) -> ManifoldVec2>,
1377        ctx: *mut std::ffi::c_void,
1378    ) -> *mut ManifoldCrossSection;
1379
1380    /// Simplify the contours of a cross-section to within `epsilon` tolerance.
1381    pub fn manifold_cross_section_simplify(
1382        mem: *mut ManifoldCrossSection,
1383        cs: *const ManifoldCrossSection,
1384        epsilon: f64,
1385    ) -> *mut ManifoldCrossSection;
1386
1387    // ── CrossSection offset ─────────────────────────────────────────────
1388
1389    /// Offset (inflate/deflate) a cross-section by `delta`.
1390    ///
1391    /// Uses Clipper2 under the hood. `jt` selects the join type.
1392    /// `miter_limit` is used when `jt` is Miter.
1393    /// `circular_segments` controls round join resolution.
1394    pub fn manifold_cross_section_offset(
1395        mem: *mut ManifoldCrossSection,
1396        cs: *const ManifoldCrossSection,
1397        delta: f64,
1398        jt: ManifoldJoinType,
1399        miter_limit: f64,
1400        circular_segments: c_int,
1401    ) -> *mut ManifoldCrossSection;
1402
1403    // ── CrossSection queries ────────────────────────────────────────────
1404
1405    pub fn manifold_cross_section_area(cs: *const ManifoldCrossSection) -> f64;
1406    pub fn manifold_cross_section_num_vert(cs: *const ManifoldCrossSection) -> usize;
1407    pub fn manifold_cross_section_num_contour(cs: *const ManifoldCrossSection) -> usize;
1408    pub fn manifold_cross_section_is_empty(cs: *const ManifoldCrossSection) -> c_int;
1409
1410    pub fn manifold_cross_section_bounds(
1411        mem: *mut ManifoldRect,
1412        cs: *const ManifoldCrossSection,
1413    ) -> *mut ManifoldRect;
1414
1415    // ── CrossSection extraction ─────────────────────────────────────────
1416
1417    pub fn manifold_cross_section_to_polygons(
1418        mem: *mut ManifoldPolygons,
1419        cs: *const ManifoldCrossSection,
1420    ) -> *mut ManifoldPolygons;
1421
1422    // ── Rectangle ───────────────────────────────────────────────────────
1423
1424    pub fn manifold_rect(
1425        mem: *mut ManifoldRect,
1426        x1: f64,
1427        y1: f64,
1428        x2: f64,
1429        y2: f64,
1430    ) -> *mut ManifoldRect;
1431
1432    pub fn manifold_rect_min(r: *const ManifoldRect) -> ManifoldVec2;
1433    pub fn manifold_rect_max(r: *const ManifoldRect) -> ManifoldVec2;
1434    pub fn manifold_rect_dimensions(r: *const ManifoldRect) -> ManifoldVec2;
1435    pub fn manifold_rect_center(r: *const ManifoldRect) -> ManifoldVec2;
1436    pub fn manifold_rect_scale(r: *const ManifoldRect) -> f64;
1437
1438    pub fn manifold_rect_contains_pt(r: *const ManifoldRect, x: f64, y: f64) -> c_int;
1439
1440    pub fn manifold_rect_contains_rect(a: *const ManifoldRect, b: *const ManifoldRect) -> c_int;
1441
1442    pub fn manifold_rect_include_pt(r: *mut ManifoldRect, x: f64, y: f64);
1443
1444    pub fn manifold_rect_union(
1445        mem: *mut ManifoldRect,
1446        a: *const ManifoldRect,
1447        b: *const ManifoldRect,
1448    ) -> *mut ManifoldRect;
1449
1450    pub fn manifold_rect_transform(
1451        mem: *mut ManifoldRect,
1452        r: *const ManifoldRect,
1453        x1: f64,
1454        y1: f64,
1455        x2: f64,
1456        y2: f64,
1457        x3: f64,
1458        y3: f64,
1459    ) -> *mut ManifoldRect;
1460
1461    pub fn manifold_rect_translate(
1462        mem: *mut ManifoldRect,
1463        r: *const ManifoldRect,
1464        x: f64,
1465        y: f64,
1466    ) -> *mut ManifoldRect;
1467
1468    pub fn manifold_rect_mul(
1469        mem: *mut ManifoldRect,
1470        r: *const ManifoldRect,
1471        x: f64,
1472        y: f64,
1473    ) -> *mut ManifoldRect;
1474
1475    pub fn manifold_rect_does_overlap_rect(a: *const ManifoldRect, r: *const ManifoldRect)
1476    -> c_int;
1477
1478    pub fn manifold_rect_is_empty(r: *const ManifoldRect) -> c_int;
1479    pub fn manifold_rect_is_finite(r: *const ManifoldRect) -> c_int;
1480
1481    // ── Triangulation ───────────────────────────────────────────────────
1482
1483    /// Triangulate a polygon set, returning triangle indices.
1484    pub fn manifold_triangulate(
1485        mem: *mut ManifoldTriangulation,
1486        ps: *const ManifoldPolygons,
1487        epsilon: f64,
1488    ) -> *mut ManifoldTriangulation;
1489
1490    pub fn manifold_triangulation_num_tri(m: *const ManifoldTriangulation) -> usize;
1491
1492    /// Copy triangle vertex indices into caller-provided buffer.
1493    /// Each triangle is 3 consecutive i32 values.
1494    pub fn manifold_triangulation_tri_verts(
1495        mem: *mut i32,
1496        m: *const ManifoldTriangulation,
1497    ) -> *mut i32;
1498
1499    // ── Static quality globals ──────────────────────────────────────────
1500
1501    pub fn manifold_set_min_circular_angle(degrees: f64);
1502    pub fn manifold_set_min_circular_edge_length(length: f64);
1503    pub fn manifold_set_circular_segments(number: c_int);
1504    pub fn manifold_reset_to_circular_defaults();
1505
1506    // ── OBJ I/O ─────────────────────────────────────────────────────────
1507    //
1508    // These four functions live in manifold's iostream-using path, gated by
1509    // `MANIFOLD_NO_IOSTREAM` upstream-side. On wasm32-unknown-unknown we
1510    // build with that macro defined (the C++ symbols don't exist), so the
1511    // FFI declarations are also elided. Consumers reaching for OBJ I/O on
1512    // that target should use the binary `MeshGL64` API instead.
1513
1514    /// Import a manifold from a Wavefront obj file.
1515    ///
1516    /// The `obj_file` parameter is the content of the obj file (not the filename),
1517    /// and should be null-terminated.
1518    #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
1519    pub fn manifold_read_obj(
1520        mem: *mut ManifoldManifold,
1521        obj_file: *const std::ffi::c_char,
1522    ) -> *mut ManifoldManifold;
1523
1524    /// Import a MeshGL64 from a Wavefront obj file.
1525    ///
1526    /// The `obj_file` parameter is the content of the obj file (not the filename),
1527    /// and should be null-terminated.
1528    #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
1529    pub fn manifold_meshgl64_read_obj(
1530        mem: *mut ManifoldMeshGL64,
1531        obj_file: *const std::ffi::c_char,
1532    ) -> *mut ManifoldMeshGL64;
1533
1534    /// Export a manifold to a Wavefront obj string via callback.
1535    ///
1536    /// The callback receives a temporary null-terminated string buffer containing
1537    /// the obj content, plus a user-provided context pointer. The buffer is freed
1538    /// automatically after the callback returns.
1539    #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
1540    pub fn manifold_write_obj(
1541        manifold: *const ManifoldManifold,
1542        callback: Option<unsafe extern "C" fn(*mut std::ffi::c_char, *mut std::ffi::c_void)>,
1543        args: *mut std::ffi::c_void,
1544    );
1545
1546    /// Export a MeshGL64 to a Wavefront obj string via callback.
1547    ///
1548    /// The callback receives a temporary null-terminated string buffer containing
1549    /// the obj content, plus a user-provided context pointer. The buffer is freed
1550    /// automatically after the callback returns.
1551    #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
1552    pub fn manifold_meshgl64_write_obj(
1553        mesh: *const ManifoldMeshGL64,
1554        callback: Option<unsafe extern "C" fn(*mut std::ffi::c_char, *mut std::ffi::c_void)>,
1555        args: *mut std::ffi::c_void,
1556    );
1557}