chijin 0.1.0

Minimal Rust bindings for OpenCASCADE (OCC 7.9)
use crate::ffi;
use crate::solid::Solid;
use glam::DVec3;

/// A face topology shape.
pub struct Face {
    pub(crate) inner: cxx::UniquePtr<ffi::TopoDS_Face>,
}

impl Face {
    /// Create a Face wrapping a `TopoDS_Face`.
    pub(crate) fn new(inner: cxx::UniquePtr<ffi::TopoDS_Face>) -> Self {
        Face { inner }
    }

    /// Get the normal vector at the center of mass of this face.
    ///
    /// The center of mass is computed using surface-area-weighted integration,
    /// and the normal is evaluated at that point on the surface.
    pub fn normal_at_center(&self) -> DVec3 {
        let mut nx = 0.0;
        let mut ny = 0.0;
        let mut nz = 0.0;
        ffi::face_normal_at_center(&self.inner, &mut nx, &mut ny, &mut nz);
        DVec3::new(nx, ny, nz)
    }

    /// Get the center of mass of this face.
    ///
    /// Computed using `BRepGProp::SurfaceProperties`, which gives the
    /// surface-area-weighted centroid.
    pub fn center_of_mass(&self) -> DVec3 {
        let mut cx = 0.0;
        let mut cy = 0.0;
        let mut cz = 0.0;
        ffi::face_center_of_mass(&self.inner, &mut cx, &mut cy, &mut cz);
        DVec3::new(cx, cy, cz)
    }

    /// Extrude this face along the given direction vector to create a solid.
    ///
    /// Uses `BRepPrimAPI_MakePrism`. The result can be converted to a `Shape`
    /// via `Shape::from(solid)`.
    pub fn extrude(&self, dir: DVec3) -> Solid {
        let shape = ffi::face_extrude(&self.inner, dir.x, dir.y, dir.z);
        Solid::new(shape)
    }
}