1#[cfg(feature = "output")]
7pub mod output;
8
9#[cxx::bridge(namespace = "manifold_rs")]
10mod ffi {
11 unsafe extern "C++" {
13 include!("manifold_rs.h");
14
15 type Polygons;
16
17 fn size(self: &Polygons) -> usize;
19
20 fn get_as_slice(self: &Polygons, i: usize) -> &[f64];
22
23 type Manifold;
25
26 fn slice(self: &Manifold, height: f64) -> UniquePtr<Polygons>;
28
29 fn project(self: &Manifold) -> UniquePtr<Polygons>;
31
32 fn sphere(radius: f64, segments: u32) -> UniquePtr<Manifold>;
34
35 fn cube(x_size: f64, y_size: f64, z_size: f64) -> UniquePtr<Manifold>;
37
38 fn cylinder(
40 radius_low: f64,
41 radius_high: f64,
42 height: f64,
43 segments: u32,
44 ) -> UniquePtr<Manifold>;
45
46 fn union_(a: &Manifold, b: &Manifold) -> UniquePtr<Manifold>;
48
49 fn intersection(a: &Manifold, b: &Manifold) -> UniquePtr<Manifold>;
51
52 fn difference(a: &Manifold, b: &Manifold) -> UniquePtr<Manifold>;
54
55 fn trim_by_plane(
57 self: &Manifold,
58 x: f64,
59 y: f64,
60 z: f64,
61 offset: f64,
62 ) -> UniquePtr<Manifold>;
63
64 fn hull(self: &Manifold) -> UniquePtr<Manifold>;
66
67 fn translate(self: &Manifold, x: f64, y: f64, z: f64) -> UniquePtr<Manifold>;
69
70 fn scale(self: &Manifold, x: f64, y: f64, z: f64) -> UniquePtr<Manifold>;
72
73 fn rotate(self: &Manifold, x: f64, y: f64, z: f64) -> UniquePtr<Manifold>;
75
76 fn extrude(
78 multi_polygon_data: &[&[f64]],
79 height: f64,
80 n_divisions: u32,
81 twist_degrees: f64,
82 scale_top_x: f64,
83 scale_top_y: f64,
84 ) -> UniquePtr<Manifold>;
85
86 fn revolve(
88 multi_polygon_data: &[&[f64]],
89 circular_segments: u32,
90 revolve_degrees: f64,
91 ) -> UniquePtr<Manifold>;
92
93 fn refine(self: &Manifold, n: i32) -> UniquePtr<Manifold>;
95
96 fn refine_to_length(self: &Manifold, t: f64) -> UniquePtr<Manifold>;
98
99 fn refine_to_tolerance(self: &Manifold, t: f64) -> UniquePtr<Manifold>;
101
102 fn smooth_by_normals(self: &Manifold, normal_idx: i32) -> UniquePtr<Manifold>;
104
105 fn smooth_out(
107 self: &Manifold,
108 min_sharp_angle: f64,
109 min_smoothness: f64,
110 ) -> UniquePtr<Manifold>;
111
112 fn calculate_normals(
114 self: &Manifold,
115 normal_idx: i32,
116 min_sharp_angle: f64,
117 ) -> UniquePtr<Manifold>;
118
119 type Mesh;
121
122 fn num_props(self: &Mesh) -> u32;
124
125 fn vertices(self: &Mesh) -> UniquePtr<CxxVector<f32>>;
127
128 fn indices(self: &Mesh) -> UniquePtr<CxxVector<u32>>;
130
131 fn mesh_from_manifold(manifold: &Manifold) -> UniquePtr<Mesh>;
133
134 fn manifold_from_mesh(mesh: &Mesh) -> UniquePtr<Manifold>;
136
137 fn mesh_from_vertices(vertices: &[f32], indices: &[u32]) -> UniquePtr<Mesh>;
142 }
143}
144
145pub enum BooleanOp {
147 Union,
149 Intersection,
151 Difference,
153}
154
155pub struct Polygons(cxx::UniquePtr<ffi::Polygons>);
157
158impl Polygons {
159 pub fn size(&self) -> usize {
161 self.0.size()
162 }
163
164 pub fn get_as_slice(&self, i: usize) -> &[f64] {
166 self.0.get_as_slice(i)
167 }
168}
169
170pub struct Manifold(cxx::UniquePtr<ffi::Manifold>);
172
173impl Manifold {
174 pub fn slice(&self, height: f64) -> Polygons {
176 Polygons(self.0.slice(height))
177 }
178
179 pub fn project(&self) -> Polygons {
181 Polygons(self.0.project())
182 }
183
184 pub fn trim_by_plane(&self, x: f64, y: f64, z: f64, offset: f64) -> Self {
186 Self(self.0.trim_by_plane(x, y, z, offset))
187 }
188
189 pub fn hull(&self) -> Self {
191 Self(self.0.hull())
192 }
193
194 pub fn translate(&self, x: f64, y: f64, z: f64) -> Self {
196 Self(self.0.translate(x, y, z))
197 }
198
199 pub fn scale(&self, x: f64, y: f64, z: f64) -> Self {
201 Self(self.0.scale(x, y, z))
202 }
203
204 pub fn rotate(&self, x: f64, y: f64, z: f64) -> Self {
206 Self(self.0.rotate(x, y, z))
207 }
208
209 pub fn sphere(radius: f64, segments: u32) -> Self {
211 Self(ffi::sphere(radius, segments))
212 }
213
214 pub fn cube(x_size: f64, y_size: f64, z_size: f64) -> Self {
216 Self(ffi::cube(x_size, y_size, z_size))
217 }
218
219 pub fn cylinder(radius_low: f64, radius_high: f64, height: f64, segments: u32) -> Self {
221 Self(ffi::cylinder(radius_low, radius_high, height, segments))
222 }
223
224 pub fn union(&self, b: &Self) -> Self {
226 Self(ffi::union_(self.inner(), b.inner()))
227 }
228
229 pub fn intersection(&self, b: &Self) -> Self {
231 Self(ffi::intersection(self.inner(), b.inner()))
232 }
233
234 pub fn difference(&self, b: &Self) -> Self {
236 Self(ffi::difference(self.inner(), b.inner()))
237 }
238
239 pub fn boolean_op(&self, b: &Self, op: crate::BooleanOp) -> Self {
241 match op {
242 crate::BooleanOp::Union => self.union(b),
243 crate::BooleanOp::Intersection => self.intersection(b),
244 crate::BooleanOp::Difference => self.difference(b),
245 }
246 }
247
248 pub fn extrude(
250 multi_polygon_data: &[&[f64]],
251 height: f64,
252 n_divisions: u32,
253 twist_degrees: f64,
254 scale_top_x: f64,
255 scale_top_y: f64,
256 ) -> Self {
257 Self(ffi::extrude(
258 multi_polygon_data,
259 height,
260 n_divisions,
261 twist_degrees,
262 scale_top_x,
263 scale_top_y,
264 ))
265 }
266
267 pub fn revolve(
269 multi_polygon_data: &[&[f64]],
270 circular_segments: u32,
271 revolve_degrees: f64,
272 ) -> Self {
273 Self(ffi::revolve(
274 multi_polygon_data,
275 circular_segments,
276 revolve_degrees,
277 ))
278 }
279
280 pub fn refine(self: &Manifold, n: i32) -> Self {
282 Self(self.0.refine(n))
283 }
284
285 pub fn refine_to_length(self: &Manifold, t: f64) -> Self {
287 Self(self.0.refine_to_length(t))
288 }
289
290 pub fn refine_to_tolerance(self: &Manifold, t: f64) -> Self {
292 Self(self.0.refine_to_tolerance(t))
293 }
294
295 pub fn smooth_by_normals(self: &Manifold, normal_idx: i32) -> Self {
297 Self(self.0.smooth_by_normals(normal_idx))
298 }
299
300 pub fn smooth_out(self: &Manifold, min_sharp_angle: f64, min_smoothness: f64) -> Self {
302 Self(self.0.smooth_out(min_sharp_angle, min_smoothness))
303 }
304
305 pub fn calculate_normals(self: &Manifold, normal_idx: i32, min_sharp_angle: f64) -> Self {
307 Self(self.0.calculate_normals(normal_idx, min_sharp_angle))
308 }
309
310 pub fn to_mesh(&self) -> Mesh {
312 Mesh(ffi::mesh_from_manifold(&self.0))
313 }
314
315 pub fn from_mesh(mesh: Mesh) -> Self {
317 mesh.into()
318 }
319
320 fn inner(&self) -> &ffi::Manifold {
322 self.0.as_ref().unwrap()
323 }
324}
325
326pub struct Mesh(cxx::UniquePtr<ffi::Mesh>);
328
329impl Mesh {
331 pub fn new(vertices: &[f32], indices: &[u32]) -> Self {
333 let mesh = ffi::mesh_from_vertices(vertices, indices);
334 Self(mesh)
335 }
336
337 pub fn num_props(&self) -> u32 {
339 self.0.num_props()
340 }
341
342 pub fn vertices(&self) -> Vec<f32> {
344 let vertices_binding = self.0.vertices();
345 let vertices = vertices_binding.as_ref().unwrap().as_slice();
346 vertices.to_vec()
347 }
348
349 pub fn indices(&self) -> Vec<u32> {
351 let indices_binding = self.0.indices();
352 let indices = indices_binding.as_ref().unwrap().as_slice();
353 indices.to_vec()
354 }
355
356 pub fn to_manifold(&self) -> Manifold {
358 let manifold = ffi::manifold_from_mesh(&self.0);
359 Manifold(manifold)
360 }
361}
362
363impl From<Mesh> for Manifold {
365 fn from(mesh: Mesh) -> Self {
366 mesh.to_manifold()
367 }
368}
369
370impl From<Manifold> for Mesh {
372 fn from(manifold: Manifold) -> Self {
373 manifold.to_mesh()
374 }
375}
376
377#[test]
378fn test_manifold_ffi() {
379 let sphere = ffi::sphere(1.0, 32);
380
381 let mesh = ffi::mesh_from_manifold(&sphere);
382
383 let vertices_binding = mesh.vertices();
384 let vertices = vertices_binding.as_ref().unwrap().as_slice();
385 assert!(!vertices.is_empty());
386
387 let indices_binding = mesh.indices();
388 let indices = indices_binding.as_ref().unwrap().as_slice();
389 assert!(!indices.is_empty());
390}