Skip to main content

GeometryRouter

Struct GeometryRouter 

Source
pub struct GeometryRouter { /* private fields */ }
Expand description

Geometry router - routes entities to processors

Implementations§

Source§

impl GeometryRouter

Source

pub fn process_element_with_material_layers( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, buildup: &LayerBuildup, void_index: &FxHashMap<u32, Vec<u32>>, ) -> Result<Option<SubMeshCollection>>

Process an element into per-layer sub-meshes, subtracting any openings first.

Returns Ok(None) when the buildup isn’t sliceable (single material, constituent set, profile set, degenerate) so the caller can fall back to the existing sub-mesh-voids path without duplicating work.

Each emitted SubMesh carries the layer’s IfcMaterial entity ID as its geometry_id — callers key colour lookup on that.

Source§

impl GeometryRouter

Source

pub fn detect_rtc_offset_from_first_element( &self, content: &str, decoder: &mut EntityDecoder<'_>, ) -> (f64, f64, f64)

Detect RTC offset by scanning the file for building elements. Used by synchronous parse paths.

Source

pub fn detect_rtc_offset_from_jobs( &self, jobs: &[(u32, usize, usize, IfcType)], decoder: &mut EntityDecoder<'_>, ) -> Option<(f64, f64, f64)>

Detect RTC offset using pre-collected geometry jobs (avoids re-scanning the file). Returns None when no usable translation samples were found, allowing callers to distinguish “no shift needed” from “detection had no data”.

Source

pub fn process_element( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Result<Mesh>

Process building element (IfcWall, IfcBeam, etc.) into mesh Follows the representation chain: Element → Representation → ShapeRepresentation → Items

Source

pub fn process_element_with_submeshes( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Result<SubMeshCollection>

Process element and return sub-meshes with their geometry item IDs. This preserves per-item identity for color/style lookup.

For elements with multiple styled geometry items (like windows with frames + glass), this returns separate sub-meshes that can receive different colors.

Source

pub fn process_element_with_transform( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Result<(Mesh, Matrix4<f64>)>

Process building element and return geometry + transform separately Used for instanced rendering - geometry is returned untransformed, transform is separate

Source

pub fn process_representation_item( &self, item: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Result<Mesh>

Process a single representation item (IfcExtrudedAreaSolid, etc.) Uses hash-based caching for geometry deduplication across repeated floors

Source§

impl GeometryRouter

Source

pub fn get_opening_item_meshes_world( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Result<Vec<Mesh>>

Get per-item meshes for an opening element, transformed to world coordinates. Uses the same transform_mesh path as process_element to ensure identical coordinate handling (ObjectPlacement, unit scaling, conditional RTC offset).

Source

pub fn get_opening_item_bounds_with_direction( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Result<Vec<(Point3<f64>, Point3<f64>, Option<Vector3<f64>>)>>

Extrusion direction is in world coordinates, normalized Returns None for extrusion direction if it cannot be extracted (fallback to bounds-only)

Source

pub fn process_element_with_voids( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, void_index: &FxHashMap<u32, Vec<u32>>, ) -> Result<Mesh>

Process element with void subtraction (openings) Process element with voids using optimized plane clipping

This approach is more efficient than full 3D CSG for rectangular openings:

  1. Get chamfered wall mesh (preserves chamfered corners)
  2. For each opening, use optimized box cutting with internal face generation
  3. Apply any clipping operations (roof clips) from original representation Process an element with void subtraction (openings).

This function handles three distinct cases for cutting openings:

  1. Floor/Slab openings (vertical Z-extrusion): Uses CSG with actual mesh geometry because the XY footprint may be rotated relative to the slab orientation.

  2. Wall openings (horizontal X/Y-extrusion, axis-aligned): Uses AABB clipping for fast, accurate cutting of rectangular openings.

  3. Diagonal wall openings: Uses AABB clipping without internal face generation to avoid rotation artifacts.

Reveal faces (inner surfaces of the opening holes) are generated as a post-clipping step for rectangular and diagonal openings. For diagonal walls the geometry is computed in a rotated axis-aligned frame and rotated back, giving correct results for any wall orientation.

Source

pub fn process_element_with_submeshes_and_voids( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, void_index: &FxHashMap<u32, Vec<u32>>, ) -> Result<SubMeshCollection>

Process an element into per-item sub-meshes with opening subtraction.

Mirrors [process_element_with_voids] but preserves each IfcShapeRepresentation item as its own sub-mesh so that callers can look up a direct IfcStyledItem color per geometry item (e.g. the three extrusion layers of a multi-layer wall). The opening(s) are subtracted from each sub-mesh independently so that windows and doors cut through every material layer they intersect.

Returns an empty collection when there are no openings (callers should fall back to [process_element_with_submeshes]) or when every sub-mesh is destroyed by void subtraction.

Source§

impl GeometryRouter

Source

pub fn process_element_with_voids_2d( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, void_index: &VoidIndex, ) -> Result<Mesh>

Process element with voids using 2D profile-level operations

This is a smarter and more efficient approach that:

  1. Classifies voids as coplanar (can subtract in 2D) or non-planar (need 3D CSG)
  2. Subtracts coplanar voids at the 2D profile level before extrusion
  3. Falls back to 3D CSG only for non-planar voids

Benefits:

  • 10-25x faster than full 3D CSG for most openings
  • More reliable, especially for floors/slabs with many penetrations
  • Cleaner geometry with fewer degenerate triangles
Source§

impl GeometryRouter

Source

pub fn new() -> Self

Create new router with default processors

Source

pub fn with_units(content: &str, decoder: &mut EntityDecoder<'_>) -> Self

Create router and extract unit scale from IFC file Automatically finds IFCPROJECT and extracts length unit conversion

Source

pub fn with_units_and_rtc( content: &str, decoder: &mut EntityDecoder<'_>, rtc_offset: (f64, f64, f64), ) -> Self

Create router with unit scale extracted from IFC file AND RTC offset for large coordinates This is the recommended method for georeferenced models (Swiss UTM, etc.)

§Arguments
  • content - IFC file content
  • decoder - Entity decoder
  • rtc_offset - RTC offset to subtract from world coordinates (typically model centroid)
Source

pub fn with_scale(unit_scale: f64) -> Self

Create router with pre-calculated unit scale

Source

pub fn with_rtc(rtc_offset: (f64, f64, f64)) -> Self

Create router with RTC offset for large coordinate handling Use this for georeferenced models (e.g., Swiss UTM coordinates)

Source

pub fn with_scale_and_rtc(unit_scale: f64, rtc_offset: (f64, f64, f64)) -> Self

Create router with both unit scale and RTC offset

Source

pub fn set_rtc_offset(&mut self, offset: (f64, f64, f64))

Set the RTC offset for large coordinate handling

Source

pub fn rtc_offset(&self) -> (f64, f64, f64)

Get the current RTC offset

Source

pub fn has_rtc_offset(&self) -> bool

Check if RTC offset is active (non-zero)

Source

pub fn unit_scale(&self) -> f64

Get the current unit scale factor

Source

pub fn set_material_layer_index(&mut self, index: Arc<MaterialLayerIndex>)

Attach a material-layer buildup index. After this, sub-mesh processing automatically slices single-solid elements whose buildup is sliceable (walls with IfcMaterialLayerSetUsage, etc.) into per-layer slabs.

Source

pub fn register(&mut self, processor: Box<dyn GeometryProcessor>)

Register a geometry processor

Source

pub fn preprocess_faceted_breps( &self, brep_ids: &[u32], decoder: &mut EntityDecoder<'_>, )

Batch preprocess FacetedBrep entities for maximum parallelism Call this before processing elements to enable batch triangulation across all FacetedBrep entities instead of per-entity parallelism

Source

pub fn take_cached_faceted_brep(&self, brep_id: u32) -> Option<Mesh>

Take FacetedBrep from cache (removes entry since each BREP is only used once) Returns owned Mesh directly - no cloning needed

Source

pub fn resolve_scaled_placement( &self, entity: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Result<[f64; 16]>

Resolve an element’s ObjectPlacement to a scaled world-space transform matrix. Returns the 4x4 matrix as a flat column-major array of 16 f64 values. The translation component is scaled from file units to meters.

Contributed by Mathias Søndergaard (Sonderwoods/Linkajou).

Source

pub fn schema(&self) -> &IfcSchema

Get schema reference

Trait Implementations§

Source§

impl Default for GeometryRouter

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.