pub struct GeometryRouter { /* private fields */ }Expand description
Geometry router - routes entities to processors
Implementations§
Source§impl GeometryRouter
impl GeometryRouter
Sourcepub fn process_element_with_material_layers(
&self,
element: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
buildup: &LayerBuildup,
void_index: &FxHashMap<u32, Vec<u32>>,
) -> Result<Option<SubMeshCollection>>
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
impl GeometryRouter
Sourcepub fn detect_rtc_offset_from_first_element(
&self,
content: &str,
decoder: &mut EntityDecoder<'_>,
) -> (f64, f64, f64)
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.
Sourcepub fn detect_rtc_offset_from_jobs(
&self,
jobs: &[(u32, usize, usize, IfcType)],
decoder: &mut EntityDecoder<'_>,
) -> Option<(f64, f64, f64)>
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”.
Sourcepub fn process_element(
&self,
element: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
) -> Result<Mesh>
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
Sourcepub fn process_element_with_submeshes(
&self,
element: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
) -> Result<SubMeshCollection>
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.
Sourcepub fn process_element_with_transform(
&self,
element: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
) -> Result<(Mesh, Matrix4<f64>)>
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
Sourcepub fn process_representation_item(
&self,
item: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
) -> Result<Mesh>
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
impl GeometryRouter
Sourcepub fn get_opening_item_meshes_world(
&self,
element: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
) -> Result<Vec<Mesh>>
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).
Sourcepub fn get_opening_item_bounds_with_direction(
&self,
element: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
) -> Result<Vec<(Point3<f64>, Point3<f64>, Option<Vector3<f64>>)>>
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)
Sourcepub fn process_element_with_voids(
&self,
element: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
void_index: &FxHashMap<u32, Vec<u32>>,
) -> Result<Mesh>
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:
- Get chamfered wall mesh (preserves chamfered corners)
- For each opening, use optimized box cutting with internal face generation
- 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:
-
Floor/Slab openings (vertical Z-extrusion): Uses CSG with actual mesh geometry because the XY footprint may be rotated relative to the slab orientation.
-
Wall openings (horizontal X/Y-extrusion, axis-aligned): Uses AABB clipping for fast, accurate cutting of rectangular openings.
-
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.
Sourcepub fn process_element_with_submeshes_and_voids(
&self,
element: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
void_index: &FxHashMap<u32, Vec<u32>>,
) -> Result<SubMeshCollection>
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
impl GeometryRouter
Sourcepub fn process_element_with_voids_2d(
&self,
element: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
void_index: &VoidIndex,
) -> Result<Mesh>
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:
- Classifies voids as coplanar (can subtract in 2D) or non-planar (need 3D CSG)
- Subtracts coplanar voids at the 2D profile level before extrusion
- 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
impl GeometryRouter
Sourcepub fn with_units(content: &str, decoder: &mut EntityDecoder<'_>) -> Self
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
Sourcepub fn with_units_and_rtc(
content: &str,
decoder: &mut EntityDecoder<'_>,
rtc_offset: (f64, f64, f64),
) -> Self
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 contentdecoder- Entity decoderrtc_offset- RTC offset to subtract from world coordinates (typically model centroid)
Sourcepub fn with_scale(unit_scale: f64) -> Self
pub fn with_scale(unit_scale: f64) -> Self
Create router with pre-calculated unit scale
Sourcepub fn with_rtc(rtc_offset: (f64, f64, f64)) -> Self
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)
Sourcepub fn with_scale_and_rtc(unit_scale: f64, rtc_offset: (f64, f64, f64)) -> Self
pub fn with_scale_and_rtc(unit_scale: f64, rtc_offset: (f64, f64, f64)) -> Self
Create router with both unit scale and RTC offset
Sourcepub fn set_rtc_offset(&mut self, offset: (f64, f64, f64))
pub fn set_rtc_offset(&mut self, offset: (f64, f64, f64))
Set the RTC offset for large coordinate handling
Sourcepub fn rtc_offset(&self) -> (f64, f64, f64)
pub fn rtc_offset(&self) -> (f64, f64, f64)
Get the current RTC offset
Sourcepub fn has_rtc_offset(&self) -> bool
pub fn has_rtc_offset(&self) -> bool
Check if RTC offset is active (non-zero)
Sourcepub fn unit_scale(&self) -> f64
pub fn unit_scale(&self) -> f64
Get the current unit scale factor
Sourcepub fn set_material_layer_index(&mut self, index: Arc<MaterialLayerIndex>)
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.
Sourcepub fn register(&mut self, processor: Box<dyn GeometryProcessor>)
pub fn register(&mut self, processor: Box<dyn GeometryProcessor>)
Register a geometry processor
Sourcepub fn preprocess_faceted_breps(
&self,
brep_ids: &[u32],
decoder: &mut EntityDecoder<'_>,
)
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
Sourcepub fn take_cached_faceted_brep(&self, brep_id: u32) -> Option<Mesh>
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
Sourcepub fn resolve_scaled_placement(
&self,
entity: &DecodedEntity,
decoder: &mut EntityDecoder<'_>,
) -> Result<[f64; 16]>
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).
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for GeometryRouter
impl !RefUnwindSafe for GeometryRouter
impl !Send for GeometryRouter
impl !Sync for GeometryRouter
impl Unpin for GeometryRouter
impl UnsafeUnpin for GeometryRouter
impl !UnwindSafe for GeometryRouter
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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 moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.