Skip to main content

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 csg::calculate_normals;
pub use csg::ClippingProcessor;
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 simplify::simplify_mesh;
pub use simplify::SimplifyOptions;
pub use simplify::SimplifyStats;

Modules§

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.
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)

Structs§

AdvancedBrepProcessor
AdvancedBrep processor Handles IfcAdvancedBrep and IfcAdvancedBrepWithVoids - NURBS/B-spline surfaces Supports planar faces and B-spline surface tessellation
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.
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.
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
FaceBasedSurfaceModel processor Handles IfcFaceBasedSurfaceModel - surface model made of connected face sets
FacetedBrepProcessor
FacetedBrep processor Handles IfcFacetedBrep - explicit mesh with faces Supports faces with inner bounds (holes) Uses parallel triangulation for large BREPs
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.
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
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
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
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§

BoolFailureReason
Why a boolean operation failed or was skipped.
BoolOp
Which boolean operation produced the failure.
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
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; tune empirically with the tolerance_sweep test against real revision pairs.
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. Bump in lockstep with the TS decoder.
LARGE_COORD_THRESHOLD_METERS
The streaming / needs-shift 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. Shared by the router’s own coordinate sampling (router::rtc_offset) and the streaming pre-pass meta resolver (ifc_lite_processing::stream_meta) so those two make the same decision. (Other 10 km checks carry their own local constant of the same value.)

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.
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.
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
decode_instanced
Decode an instanced shard. Returns None on a bad magic/version or truncation.
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.
ensure_ccw
Ensure contour has counter-clockwise winding (positive area)
ensure_cw
Ensure contour has clockwise winding (for holes)
extract_profiles
Extract profiles for every building element in content.
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
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 [local_frame_enabled] on/off, or None for the target default. 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.
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).
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 IfcWallIfcBuildingElementPart pair.
propagate_voids_via_aggregates
Propagate openings from hosts that aggregate parts to every aggregated descendant — recursive and type-agnostic (IfcWallElementedCase panels, IfcRoof → IfcSlab skylights, nested assemblies, …).
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]).
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_prism_defers
Telemetry disabled in the default build; the perf harness must enable an observability feature to read real counts.
take_prism_stats
triangulate_polygon
Triangulate a simple polygon (no holes) Returns triangle indices into the input points
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.

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 GeometryRouter::new_dedup_cache and inject it into every per-element / per-batch router via 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.
Point2
A statically sized 2-dimensional column point.
Point3
A statically sized 3-dimensional column point.
Result
Result type for geometry operations
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.