microcad_core/geo3d/
mod.rs

1// Copyright © 2024-2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! 3D Geometry
5
6mod bounds;
7mod collection;
8mod geometry;
9mod primitives;
10mod triangle_mesh;
11
12pub use bounds::*;
13pub use collection::*;
14pub use geometry::*;
15pub use manifold_rs::Manifold;
16pub use primitives::*;
17pub use triangle_mesh::{Triangle, TriangleMesh, Vertex};
18
19use crate::{BooleanOp, RenderResolution};
20
21impl From<&BooleanOp> for manifold_rs::BooleanOp {
22    fn from(op: &BooleanOp) -> Self {
23        match op {
24            BooleanOp::Union => manifold_rs::BooleanOp::Union,
25            BooleanOp::Intersect => manifold_rs::BooleanOp::Intersection,
26            BooleanOp::Subtract => manifold_rs::BooleanOp::Difference,
27            _ => unimplemented!(),
28        }
29    }
30}
31
32/// Trait to render a 3D geometry into a mesh.
33pub trait RenderToMesh: Sized {
34    /// Render to manifold.
35    ///
36    /// Implement this method preferably.
37    fn render_to_manifold(&self, resolution: &RenderResolution) -> std::rc::Rc<Manifold>;
38
39    /// Render to mesh.
40    ///
41    /// Implement only if [`RenderToMesh::render_to_manifold`] is not possible.
42    fn render_to_mesh(&self, resolution: &RenderResolution) -> TriangleMesh {
43        self.render_to_manifold(resolution).to_mesh().into()
44    }
45}
46
47#[test]
48fn test_mesh_volume() {
49    let manifold = Manifold::sphere(1.0, 512);
50    let mesh = TriangleMesh::from(manifold.to_mesh());
51
52    let volume = mesh.volume();
53    assert!((volume - 4.0 / 3.0 * std::f64::consts::PI).abs() < 1e-3);
54}