Crate ifc_lite_geometry

Crate ifc_lite_geometry 

Source
Expand description

§IFC-Lite Geometry Processing

Efficient geometry processing for IFC models using earcutr triangulation and nalgebra for transformations.

§Overview

This crate transforms IFC geometry representations into GPU-ready triangle meshes:

  • Profile Handling: Extract and process 2D profiles (rectangle, circle, arbitrary)
  • Extrusion: Generate 3D meshes from extruded profiles
  • Triangulation: Polygon triangulation with hole support via earcutr
  • CSG Operations: Full boolean operations (difference, union, intersection)
  • Mesh Processing: Normal calculation and coordinate transformations

§Supported Geometry Types

TypeStatusDescription
IfcExtrudedAreaSolidFullMost common - extruded profiles
IfcExtrudedAreaSolidTaperedFullLofted extrusion between two profiles
IfcFacetedBrepFullBoundary representation meshes
IfcTriangulatedFaceSetFullPre-triangulated (IFC4)
IfcBooleanClippingResultFullCSG operations (difference, union, intersection)
IfcMappedItemFullInstanced geometry
IfcSweptDiskSolidFullPipe/tube geometry

§Quick Start

ⓘ
use ifc_lite_geometry::{
    Profile2D, extrude_profile, triangulate_polygon,
    Point2, Point3, Vector3
};

// Create a rectangular profile
let profile = Profile2D::rectangle(2.0, 1.0);

// Extrude to 3D
let direction = Vector3::new(0.0, 0.0, 1.0);
let mesh = extrude_profile(&profile, direction, 3.0)?;

println!("Generated {} triangles", mesh.triangle_count());

§Geometry Router

Use the GeometryRouter to automatically dispatch entities to appropriate processors:

ⓘ
use ifc_lite_geometry::{GeometryRouter, GeometryProcessor};

let router = GeometryRouter::new();

// Process entity
if let Some(mesh) = router.process(&decoder, &entity)? {
    renderer.add_mesh(mesh);
}

§Performance

  • Simple extrusions: ~2000 entities/sec
  • Complex Breps: ~200 entities/sec
  • Boolean operations: ~20 entities/sec

Re-exports§

pub use rect_fast::RectFastStats;
pub use clash_solid::intersection_solid;
pub use clash_solid::DegenerateReason;
pub use clash_solid::IntersectionSolid;
pub use csg::calculate_normals;
pub use csg::ClippingProcessor;
pub use csg::GroupCut;
pub use csg::GroupReject;
pub use csg::Plane;
pub use csg::Triangle;
pub use material_layer_index::LayerAxis;
pub use material_layer_index::LayerBuildup;
pub use material_layer_index::LayerInfo;
pub use material_layer_index::MaterialLayerFlat;
pub use material_layer_index::MaterialLayerIndex;
pub use mesh::InstanceMeta;
pub use mesh::Mesh;
pub use mesh::SubMesh;
pub use mesh::SubMeshCollection;
pub use analytic::extract_analytic_extrusion;
pub use analytic::extract_analytic_profile;
pub use analytic::extract_swept_disk;
pub use analytic::AnalyticCurveSegment;
pub use analytic::AnalyticExtrusion;
pub use analytic::AnalyticProfile;
pub use analytic::AnalyticProfileLoop;
pub use analytic::AnalyticStatus;
pub use analytic::AnalyticSweptDisk;
pub use analytic::ProfileLoopKind;
pub use simplify::simplify_mesh;
pub use simplify::SimplifyOptions;
pub use simplify::SimplifyStats;

Modules§

analytic
Exact source descriptions for IFC geometry, in representation-local IFC units. A description does not claim to include later boolean operations.
clash_solid
The intersection SOLID of a clashing pair — the overlap volume itself, as a mesh the viewer can draw opaque while ghosting both parents (the BIMcollab Zoom / Solibri presentation). A contact point tells you two elements touch; this tells you how deep, in what shape, and in which direction.
csg
CSG (Constructive Solid Geometry) Operations
kernel
Pure-Rust exact mesh-arrangement CSG kernel — the only CSG kernel, on every target (see docs/architecture/geometry-pipeline.md). Pure-Rust exact mesh-arrangement CSG kernel — predicate foundation.
material_layer_index
Material Layer Index
mesh
Mesh data structures
mesh_weld
Intra-mesh vertex weld + index dedup applied at the per-element mesh source (build_mesh_data), collapsing the faceted-brep per-face vertex duplication while keeping creases (distinct normals) split. Intra-mesh vertex weld + index dedup, applied at the mesh SOURCE.
progress
Cooperative heartbeat from long geometry work to a host that must tell a slow call from a hung one (see the module docs). Cooperative progress heartbeat from inside long geometry work.
projection_outline
Winding-independent 2D footprint outline of a mesh, for construction projection on 2D floor plans (issue #979).
rect_fast
Analytic fast path for axis-aligned rectangular openings cut through an axis-aligned box host (the dominant case: rectangular windows/doors in a straight wall). This sidesteps the exact mesh-arrangement CSG kernel — which is at its single-threaded, memory-bandwidth-bound floor — for openings that need no exact arithmetic at all.
simplify
Per-element mesh simplification for the demesher (cavity removal, grid vertex-clustering decimation, bounding-box collapse). Per-element mesh simplification (“demesher”).
space_dcel
Persistent, editable space topology (DCEL)
zone_split
Cut one element into one closed solid per location zone (#2508 item 2), on top of the exact kernel rather than beside it. Cut one element into one solid per location zone (issue #2508 item 2).

Structs§

AdvancedBrepProcessor
AdvancedBrep processor Handles IfcAdvancedBrep and IfcAdvancedBrepWithVoids - NURBS/B-spline surfaces Supports planar faces and B-spline surface tessellation
AlignmentAxis
Shared evaluated axis. Retains the canonical evaluator before renderer conversion, so a future WASM consumer can request an f64 frame at any distance.
AlignmentCurve
Parsed alignment curve. Holds horizontal and vertical segments in authored order with cumulative-start stations precomputed.
AlignmentFrame
Cross-section placement frame at a station.
AlignmentSample
AlignmentSamplingDiagnostic
AlignmentSamplingOptions
Output bounds include both endpoints. Distance starts at the physical start, irrespective of authored chainage; spacing is horizontal distance in metres.
AlignmentSamplingReport
BoolFailure
Single boolean / CSG failure record.
BooleanClippingProcessor
BooleanResult processor Handles IfcBooleanResult and IfcBooleanClippingResult - CSG operations
ClassificationStats
Counts of opening classification outcomes during the most recent geometry pass. Useful for confirming whether the host-aware floor-opening classifier guard (commit 1e033f8) is taking effect on a given model.
ClassificationSummary
Opening-classifier outcome counts (rectangular / diagonal / non-rectangular).
Collated
Result of collation: instanced templates + the meshes left to render flat.
ContourSet
The result of a contour-set boolean: rings grouped into disjoint shapes.
DecodedInstance
One occurrence of a decoded template.
DecodedInstanced
A decoded instanced shard.
DecodedTemplate
A unique geometry decoded from an instanced shard.
ExtractedProfile
A profile extracted from a single IFC building element.
ExtrudedAreaSolidProcessor
ExtrudedAreaSolid processor (P0) Handles IfcExtrudedAreaSolid - extrusion of 2D profiles
ExtrudedAreaSolidTaperedProcessor
FaceBasedSurfaceModelProcessor
Handles IfcFaceBasedSurfaceModel: FbsmFaces (SET of IfcConnectedFaceSet) -> Face[] -> FaceBound -> PolyLoop, or AdvancedFace[] -> FaceSurface.
FacetedBrepProcessor
FacetedBrep processor Handles IfcFacetedBrep - explicit mesh with faces Supports faces with inner bounds (holes) Uses parallel triangulation for large BREPs
FixedGridComposition
Bounded sequential fixed-grid authoring. The caller charges worst-case work before construction and each overlay; this context independently caps sizes.
GeometryClosure
What an ENTITY’s produced geometry looked like topologically, folded over every segment the hasher was fed (#1891).
GeometryDiagnostics
Aggregate CSG / opening diagnostics for one geometry pass — the public diagnostics contract. Built by aggregate_diagnostics from drained router data and serialized to the @ifc-lite/geometry complete event, and reused verbatim by the native ProcessingStats path (rust/processing/src/processor/mod.rs populates geometry_diagnostics). wasm-free (serde only).
GeometryHasher
Accumulates a single entity’s geometry signature across one or more mesh segments. Segments are combined commutatively, so the order in which the kernel emits an entity’s pieces does not affect the result.
GeometryRouter
Geometry router - routes entities to processors
HostOpeningDiagnostic
Per-host opening diagnostic captured during void processing.
ImageTextureRef
An unresolved IfcImageTexture reference (#1781).
InstanceMeshRef
A borrowed view of a mesh for collation/encoding — lets callers feed geometry from any owner (geometry’s Mesh, processing’s MeshData) WITHOUT cloning the vertex data (cloning 219k meshes’ geometry risks the build-container OOM).
InstanceOccurrence
One occurrence of a template geometry.
InstanceTemplate
A unique geometry shared by two or more occurrences.
MeshTexture
A decoded RGBA8 image ready for GPU upload.
OpeningDiagnostic
One opening’s worth of diagnostic data — what classify_openings observed about it.
OrientVerdict
What orient_mesh_outward_verdict concluded about a mesh’s SURFACE TOPOLOGY, on top of whether it re-wound anything.
PlaneFrame
A plane in 3D: world = origin + u * u_axis + v * v_axis.
PolygonalFaceSetProcessor
Handles IfcPolygonalFaceSet - explicit polygon meshes that need triangulation Unlike IfcTriangulatedFaceSet, faces can be arbitrary polygons (not just triangles)
Profile2D
2D Profile with optional holes
Profile2DWithVoids
Profile with void tracking for depth-aware extrusion
ProfileProcessor
Profile processor - processes IFC profiles into 2D contours
ReasonCount
One CSG failure reason and its occurrence count this pass. reason is one of the stable crate::diagnostics::BoolFailureReason::label strings.
RectFastSummary
rect_fast fast-path engagement counters (perf observability).
RectParam
EXACT parametric oriented box of a rectangular extrusion, in WORLD space. r columns are the orthonormal world axes (profile-X’, profile-Y’, extrude); half are the half-extents along those axes (XDim/2, YDim/2, Depth/2). Produced by GeometryRouter::parametric_rect_probe.
ResolvedTextureMap
A fully resolved IfcIndexedTriangleTextureMap for one face set.
RevolvedAreaSolidProcessor
RevolvedAreaSolid processor Handles IfcRevolvedAreaSolid - rotates a 2D profile around an axis
SampledAlignmentAxis
ScanOutline
Traced outline in plane coordinates.
ScanOutlineDiagnostics
What the run did, for the UI and for judging a result. Serialises to camelCase for the wasm binding. #[non_exhaustive]: diagnostics grow as the tracer does, and only this crate builds them.
ScanOutlineOptions
Every tunable of the tracer, with defaults sized for building scans in metres. Deserialises from camelCase with every field optional (absent means the default) and unknown fields refused, which is the shape the wasm binding accepts.
SharedBrepSignatureCache
Model-scoped memo of completed fast BREP signatures, keyed by express id. Create a fresh cache for every source/model; identical ids in different models must never share this cache. Quality, scale and RTC are folded later.
SkippedProfile
A building element whose construction-projection profile was dropped — its IfcExtrudedAreaSolid (direct or via IfcMappedItem) is present but could not be turned into 2D drawing geometry, or the mapped-item chain was too deep. Never an element the extractor deliberately excludes (a non-IfcExtrudedAreaSolid representation, an IfcFeatureElement).
SurfaceOfLinearExtrusionProcessor
SurfaceOfLinearExtrusion processor Handles IfcSurfaceOfLinearExtrusion - surface created by sweeping a curve along a direction
SweptDiskSolidProcessor
SweptDiskSolid processor Handles IfcSweptDiskSolid - sweeps a circular profile along a curve
TerrainCdtMesh
A deterministic, f64 constrained triangulation. Indices address points.
TextureAttachment
A surface texture attached to an output mesh: the stable dedup key plus the pixel source. texture_id is the IfcSurfaceTexture express id — every mesh sampling the same image carries the same id, so consumers create one GPU texture per id instead of one per mesh.
TriangulatedFaceSetProcessor
TriangulatedFaceSet processor (P0) Handles IfcTriangulatedFaceSet - explicit triangle meshes
UnionFind
Disjoint sets over 0..n.
VoidIndex
Index mapping host elements to their voids
VoidInfo
Void metadata for depth-aware extrusion
WorstHost
One of the worst-failing host elements (bounded top-N, opt-in detail).

Enums§

AlignmentSamplingDiagnosticCode
BoolFailureReason
Why a boolean operation failed or was skipped.
BoolOp
Which boolean operation produced the failure.
BooleanOp2D
Which boolean to apply in boolean_2d.
ContourFillRule
Explicit winding rule for quantized planar authoring.
Error
Errors that can occur during geometry processing
OpeningKindDiag
Discriminator for OpeningDiagnostic::kind. Mirrors OpeningType without dragging the geometry data along.
ProfileType
Common profile types
TerrainCdtError
Failure to build a constrained terrain mesh.
TessellationQuality
Detail level for geometry tessellation, selectable by consumers.
TextureSource
Where a resolved surface texture’s pixels come from.

Constants§

DEFAULT_GEOM_HASH_TOLERANCE
Default quantization grid in metres (1 mm). Chosen as a starting point near the f32 precision floor of RTC-local coordinates; tolerance_sweep only exercises a synthetic cube today; real-revision-pair calibration is still open (see that test’s doc comment).
FACETED_BREP_DEDUP_FACE_LIMIT
Face-count threshold above which [faceted_brep_face_count] tells the caller to skip the structural signature walk entirely (#1909). The walk in [try_faceted_brep_signature] mirrors the mesher’s own traversal face-by-face, bound-by-bound, point-by-point — for dedup to pay off there must be at least one OTHER item sharing this exact signature. Tekla-style duplication (thousands of connection plates/bolts, the case this cache exists for) tops out at low hundreds of faces per part; a SINGLE huge faceted import — a terrain, a scanned mesh, one big BREP with no sibling — has none, so hashing every point is pure loss that DOUBLES the traversal cost of an already-expensive mesh with no possible payback. Set well above any plausible detail-part face count and well below the scale where a single giant mesh becomes measurably worse — a 2.5 M-triangle model reported ~30 s where web-ifc took ~2.85 s, traced to this hash.
GEOMETRY_DIAGNOSTICS_SCHEMA_VERSION
Compatibility handshake for the GeometryDiagnostics contract, serialized as schemaVersion. DISTINCT from the viewer cache FORMAT_VERSION (an invalidation token): this is a promise consumers can gate on.
INSTANCED_MAGIC
"IFNS" little-endian — the instanced-shard magic the TS decoder validates.
INSTANCED_VERSION
Instanced format version this encoder writes for a record that CARRIES trailing field 1 (item_id). Decoders accept v1 and any version at or above 2 that declares a valid stride, so this bumps only when a trailing field is APPENDED — never to gate a read. Keep in lockstep with the TS decoder.
LARGE_COORD_THRESHOLD_METERS
The large-coordinate threshold and its predicate, defined in ifc_lite_core::limits so core’s own bounds scan can use them too. The large-coordinate threshold (metres): a world coordinate whose magnitude exceeds this needs RTC re-basing before it is cast to f32, or the model renders with vertex jitter.
MAX_CELLS_LIMIT
Largest cell budget accepted: about 64 M cells, a few hundred MB of working grids, which is what a 32-bit wasm heap can still afford.
MAX_GAP_LIMIT
Hard upper bound on ScanOutlineOptions::max_gap: a closing radius that bridges more than half a metre starts to fuse rooms and erase corridors.
MAX_SNAP_DISTANCE_CELLS
The snap band gathers (2r + 3)² cells per step along an edge.
MAX_TEXTURE_DIMENSION
Upper bound on a decoded texture’s width/height. 16384² RGBA ≈ 1 GiB — a hostile/garbage image header claiming larger dimensions is rejected BEFORE any pixel buffer is allocated, so a crafted file can’t drive an OOM. Matches the IfcPixelTexture bound.
MAX_VERTEX_MOVE_CELLS
The support check searches a disk of about this radius per edge sample.
MIN_CELL_SIZE_LIMIT
Finest cell accepted (metres). Finer cells only grow the radii (in cells) that the closing and the support check work in.
MIN_GEOM_HASH_TOLERANCE
Floor on the quantization tolerance (GeometryHasher::new clamps any smaller request up to this).
UNATTRIBUTED_PRODUCT_ID
The csg_failures key used for records that belong to no single product: the boolean processors’ own logs (swept once per element by crate::GeometryRouter::drain_processor_failures) and PENDING_MAPPED_BOOL_FAILURES. Zero is not a valid IFC express id, so it cannot collide with a real product.

Traits§

GeometryProcessor
Geometry processor trait Each processor handles one type of IFC representation

Functions§

aggregate_diagnostics
Build a GeometryDiagnostics from drained router data. wasm-free so both the wasm/viewer path and a future native path can produce the same contract. The caller owns draining: the router accessors are destructive (mem::take), so drain once and pass the results here — do not double-take.
bake_source_at_world
Bake a SOURCE-coords Mesh at a PRE-RTC row-major world transform into absolute POST-RTC world geometry (positions, normals, indices) — the #1623 Phase 2 finalize fallback for a don’t-bake instance whose template occurrence never materialized (an orphan; effectively unreachable for the eligible single-solid type-instanced set, but kept so geometry is NEVER silently lost). The affine part transforms positions; the inverse-transpose of the linear part transforms normals (renormalized). Geometrically equal to the baked flat occurrence (same triangles); the registry source is pre-weld, so vertices are unwelded — that changes only the vertex count, not the rendered surface.
boolean_2d
Apply a boolean operation to two contour sets.
boolean_2d_fixed_grid
Fixed-grid contour overlay using the same canonical engine and complete island/hole collector as boolean_2d. Coordinates are quantized; callers must include grid_size in their declared approximation and charge repeated operations against a shared budget. The per-call edge cap also bounds the uninterruptible overlay’s worst-case intersection expansion.
build_aggregate_children_index
Scan content for IfcRelAggregates and build the full (unfiltered) parent → children map used by propagate_voids_via_aggregates.
build_texture_index
Scan the model for IfcIndexedTriangleTextureMap entities and build an index keyed by the face set id each one maps to (issue #961). Cheap substring bail-out keeps untextured files (the overwhelming majority) off the scan.
collate_and_encode
One-shot producer: collate the mesh views into templates + instances and encode them as an instanced shard. The caller (e.g. the native helper) builds InstanceMeshRefs borrowing its own mesh storage — no geometry is cloned.
collate_instances
collate_refs over geometry Mesh values (thin wrapper, no geometry clone).
collate_refs
Group instanceable meshes by representation identity into templates + per-instance transforms. min_group is the smallest occurrence count worth instancing (groups below it are emitted flat); use 2 to instance any repeat.
collate_refs_in_basis
collate_refs against baked positions that are NOT in the native frame: baked_basis is what the baker did to the vertices after InstanceMeta was captured, so that p_baked = B · p_native.
collate_refs_verified_in
Compatibility entry point preserving the original verify-only emission contract. Use collate_refs_in_basis for baked-frame output.
compose_instance_world_row_major
Compose an occurrence’s full PRE-RTC world transform transform·local·canonical as a row-major [f64; 16]. Public so the processing crate’s don’t-bake finalize (#1623 Phase 2) can record the SAME world placement collate_refs computes for a baked occurrence — without materializing the occurrence’s vertices.
compute_parts_to_skip
Compute the set of aggregated IfcBuildingElementPart ids to skip when the “merge multilayer wall as a single solid” toggle is on (issue #540): a part is skipped when its parent’s layered build-up is sliceable, so the parent’s merged-layer geometry is drawn instead of the individual parts.
compute_signed_area
Compute the signed area of a 2D contour Positive = counter-clockwise, Negative = clockwise
coord_is_large
The large-coordinate threshold and its predicate, defined in ifc_lite_core::limits so core’s own bounds scan can use them too. True when any component of point (metres) lies strictly beyond LARGE_COORD_THRESHOLD_METERS from the origin.
count_attributed_products
How many REAL products have at least one failure. The synthetic UNATTRIBUTED_PRODUCT_ID bucket is excluded: it is not a product, and counting it would report “1 product failed” for a model where the only records came from an unattributed sweep. Its records still count towards the failure TOTALS — they are real failures, only their owner is unknown.
decode_instance_finishes
Trailing field 2 of every instance record, in instance order (#5984): [metallic, roughness], NaN where unauthored. A shard whose stride does not reach the field (v1, v2, or a v3 written by a model without finishes) reads as all-NaN rather than failing, the same forward/backward rule the item id follows. None exactly when decode_instanced would refuse the header or the instance table does not fit the buffer.
decode_instanced
Decode an instanced shard. Returns None on a bad magic/version or truncation.
embedded_raster_dimensions
Inspect supported raster headers without decoding pixel buffers. Hosts that aggregate many embedded images can budget their allocations before decoding. A successful header read does not certify the compressed pixel stream.
encode_instanced
encode_refs over geometry Mesh values, with id/colour accessor closures (thin wrapper, no geometry clone).
encode_refs
Encode a Collated result + its source mesh views into an instanced shard. Per-occurrence entity id + colour come from each InstanceMeshRef.
encode_refs_with_finishes
encode_refs plus each occurrence’s IFC-authored finish (#5984): finishes[i] is meshes[i]’s [metallic, roughness], NaN where unauthored, and a missing entry is unauthored. InstanceMeshRef is published with public fields, so the finish travels beside it rather than in it. Only a shard where some written occurrence authors a finish widens its records to trailing field 2 (stride 100, version 3); every other shard is byte-identical to encode_refs’s, so a model without finishes pays nothing. Read back with super::decode_instance_finishes.
ensure_ccw
Ensure contour has counter-clockwise winding (positive area)
ensure_cw
Ensure contour has clockwise winding (for holes)
extract_profiles
Extract IfcExtrudedAreaSolid profiles (incl. nested IfcMappedItem) for every element in content. Drops are silent — see extract_profiles_with_diagnostics.
extract_profiles_with_diagnostics
Same as extract_profiles, plus every SkippedProfile (default features — unlike diag_debug!).
extrude_profile
Extrude a 2D profile along the Z axis
extrude_profile_lofted
Extrude with a different cross section at the top (lofted/tapered extrusion).
extrude_profile_with_voids
Extrude a 2D profile with void awareness
format_unsupported_breakdown
The human-facing type=count breakdown, count-desc then name, as one line.
hash_mesh_world
Convenience: hash a single-segment entity in one call.
instance_rel_row_major_f32
Template-relative instance transform rel = post_rtc(M_k) · post_rtc(M_ref)⁻¹ as a row-major [f32; 16], or None when M_ref is singular. m_k / m_ref are PRE-RTC row-major world transforms (see compose_instance_world_row_major); rtc is the model offset. This is EXACTLY collate_refs’ per-occurrence rel, exposed for the don’t-bake finalize where the occurrence carries no geometry to group — the template’s baked world geometry placed by rel reproduces the occurrence’s world geometry (bounded by verify_recomposition). #1623 Phase 2.
is_valid_contour
Check if a contour is valid (has area, not degenerate)
local_frame_set_enabled_override
Test/harness-only: force the target/env fallback on/off, or None for the target default. A router constructed with an explicit frame policy does not consult this process-global hook. Mirrors rect_fast::param_set_enabled_override. The mesh-output determinism manifest uses it to run native and wasm with the SAME flag state (wasm defaults ON, native defaults OFF below), so the two targets’ outputs are comparable byte-for-byte.
locate_axis_curve
Resolve an IfcAlignment’s directrix curve.
meshed_representations
The representations of element (its IfcProductDefinitionShape Representations, decoded) that the element meshing paths mesh, in order: each IfcShapeRepresentation whose effective type is body geometry, or an annotation’s 2D fill, or that names no type at all, minus a MappedRepresentation when the element also carries direct body geometry. Anything that must agree with what renders (the IgnoreOpaque opening filter in ifc-lite-processing, #4699) selects through this.
orient_mesh_outward
Orient every connected component of mesh consistently and outward, in place. Returns true iff any triangle’s winding was flipped (the caller must then recompute normals — the existing ones were baked with the old winding).
orient_mesh_outward_verdict
orient_mesh_outward, also reporting the per-component topology it had to work out along the way. See OrientVerdict.
parse_axis2_placement_3d
Parse IfcAxis2Placement3D into transformation matrix
parse_axis2_placement_3d_from_id
Parse IfcAxis2Placement3D from entity ID (fast-path variant)
parse_cartesian_point
Parse IfcCartesianPoint from an entity attribute
parse_cartesian_point_from_id
Parse IfcCartesianPoint from entity ID (fast-path variant)
parse_direction
Parse IfcDirection entity
parse_direction_from_id
Parse IfcDirection from entity ID.
point_in_contour
Check if a point is inside a contour using ray casting
propagate_voids_to_parts
Propagate void (opening) relationships from aggregate parents to their children and return a child-part → parent-element map covering every emitted aggregate IfcWall → IfcBuildingElementPart pair.
propagate_voids_via_aggregates
Propagate openings from hosts that aggregate parts to every aggregated descendant — any depth, any type (IfcWallElementedCase panels, IfcRoof → IfcSlab skylights, nested assemblies, …).
resolve_2d
Resolve a ring set into disjoint shapes without changing the area it covers (a self-union). Canonicalises a hand-built contour set — or the flattened rings of a MeshOutline — into grouped outer/hole shapes.
rotation_angle_about_z
The building/site rotation about the world vertical (Z) axis, derived from a resolved column-major 4×4 placement matrix (as returned by crate::GeometryRouter::resolve_scaled_placement). The local X-axis (the placement’s RefDirection, composed through the full parent chain and normalized) is column 0 — elements [0], [1], [2] — so its angle in the world XY plane is atan2(m[1], m[0]).
sample_alignment_axes
Sample every resolvable alignment in source order. Failed axes are reported; no identity-placement or implicit-metre fallback is permitted. When bounds coarsen spacing both endpoints remain; exhausted total budgets omit later axes with explicit diagnostics. The cap applies to emitted samples, not IFC parsing memory (which is bounded by input size and canonical refwalk guards).
sanitize_contours
Drop rings that cannot contribute, so no input can panic or hang the overlay: fewer than 3 vertices, ANY non-finite coordinate (a NaN makes i_overlay’s segment ordering meaningless, so the whole ring goes rather than the offending point — dropping single points would silently deform the boundary instead), or all vertices collinear (a ring with no interior). A trailing vertex equal to the first is stripped, so a caller that closes its rings explicitly does not feed in a zero-length edge. Note this drops only provably-collinear rings, NOT by area: a zero-signed-area bow-tie still carries coverage under NonZero and is left for i_overlay.
scale_segments
Scale a tessellator’s segment count by the selected quality level.
subtract_2d
Perform 2D boolean difference: profile - void_contour
subtract_multiple_2d
Perform 2D boolean difference with multiple voids at once
subtract_multiple_2d_counted
Like subtract_multiple_2d, but also reports how many DISCONNECTED output shapes the difference produced (each with non-degenerate area). The returned Profile2D is the largest shape (as subtract_multiple_2d); a caller that must not silently drop geometry — the 2D opening-subtraction re-extrude — checks shapes == 1 and otherwise defers to the exact kernel (a void that splits the profile into pieces can’t be re-extruded from a single profile).
take_bool2d_stats
Read + reset the 2D-path telemetry: (hosts cut via the 2D path, opening footprints subtracted in those hosts). Process-global; used by the perf harness to report the fast-path hit-rate. Relaxed atomics — a stale read under concurrency only mis-reports a diagnostic count, never geometry.
take_cdt_recovery_fallbacks
Read + reset (stuck, exhausted): constraint segments [Cdt::recover_segment] gave up on since the last call, each of which made build_from return None so the caller ear-clipped. stuck is the “no flippable crossing edge” exit (crossing constraints, a duplicate vertex the segment names); exhausted is the 100 000-flip guard. Process-global relaxed atomics, like crate::take_bool2d_stats: a stale read under concurrency mis-reports a diagnostic count, never geometry.
take_plane_weld_stats
Read + reset [(calls, calls that moved something, vertices moved); 2] as [every caller, union only]. Process-global relaxed atomics: a stale read under concurrency mis-reports a diagnostic count, never geometry.
take_prism_defers
Read + reset the per-reason defer counters as (name, count) pairs.
take_prism_stats
Read + reset the prism-path telemetry: (hosts cut via the prism path, openings subtracted analytically, openings routed to the exact residual on prism-cut hosts). Process-global; the perf harness reports the fast-path hit-rate from it. Relaxed atomics — a stale read under concurrency only mis-reports a diagnostic count, never geometry.
trace_scan_outline
Trace outlines from plane points given as flat [u0, v0, u1, v1, …].
triangulate_polygon
Triangulate a simple polygon (no holes) Returns triangle indices into the input points
triangulate_terrain_pslg
Triangulate a non-crossing PSLG through the repository’s exact-predicate CDT. The output covers the convex hull; callers own closed-region/hole selection because an open breakline has no fill-side meaning.
triangulate_terrain_pslg_with_progress
Triangulate while checking a caller-supplied cancellation/work callback in source validation, exact CDT construction/recovery, and output emission.
verify_recomposition
Maximum per-vertex world-space error (in mesh units) when each occurrence is reconstructed by applying its instance transform to the template’s baked world geometry, versus the occurrence’s own baked world geometry. The template-relative transform operates on world coords, so each mesh’s origin is folded in. Used by tests + as a runtime diagnostic — [verify_pairing] above runs the same [reconstructed_vertex_error] kernel inline, per candidate group, so a production caller never has to run this after the fact to find out its Collated shipped a mis-grouped occurrence.

Type Aliases§

ItemDedupCache
Shared content-dedup cache: maps a 128-bit structural item hash to the LOCAL (pre-placement, void-free, colour-free) item mesh PLUS its precomputed instancing rep_identity (Some when instancing tagged it, else None). Storing the rep beside the mesh lets a cache hit stamp it without re-running the O(verts) compute_mesh_hash_full per occurrence. Build ONE per loaded model with crate::GeometryRouter::new_dedup_cache and inject it into every per-element / per-batch router via crate::GeometryRouter::enable_content_dedup_shared so byte-identical geometry is meshed once regardless of how the work is partitioned across threads/batches.
MappedInstancePlan
#1623 Phase 2 “don’t-bake” instancing plan: IfcRepresentationMap express id ⇒ (occurrence_count, template_item_id), where template_item_id is the SMALLEST IfcMappedItem express id referencing that source (a deterministic, race-free choice of which occurrence materializes its geometry as the shared template). Only sources with occurrence_count >= 2 appear. Built ONCE from the file scan and injected into every per-element / per-batch router via GeometryRouter::enable_output_instancing. When a mapped item’s source is in this plan AND the occurrence is a single-solid ordinary product, the NON-template occurrences skip the per-occurrence vertex bake and emit an instance-only placeholder (empty geometry carrying crate::mesh::InstanceMeta) instead of a full materialized mesh — the ~29s / 43M-vertex materialize this phase kills. None ⇒ every occurrence materializes (historical flat output, byte-identical); exporters and the determinism harness never arm it.
Matrix4
A stack-allocated, column-major, 4x4 square matrix.
Point2
A statically sized 2-dimensional column point.
Point3
A statically sized 3-dimensional column point.
Result
Result type for geometry operations
Ring2D
A closed ring: 2D points in order, WITHOUT a duplicated closing vertex.
SharedMappedItemCache
Shared IfcMappedItem source cache: maps an IfcRepresentationMap express id to its SOURCE-coordinate (pre-MappingTarget, pre-placement, colour-free) item mesh. Build ONE per loaded model with GeometryRouter::new_mapped_item_cache and inject it into every per-element / per-batch router via GeometryRouter::enable_shared_mapped_item_cache, so a source shared by many owning elements is meshed ONCE model-wide instead of once per element (a fresh router is built per element, so the per-router RefCell mapped_item_cache only dedups WITHIN one element — #1623). The value is the same source-coords mesh the RefCell would store; the per-occurrence MappingTarget transform + instance_meta are applied by the caller AFTER the lookup, so a cross-router cache hit is byte-identical to a fresh build.
Vector2
A stack-allocated, 2-dimensional column vector.
Vector3
A stack-allocated, 3-dimensional column vector.