GeometryRouter

Struct GeometryRouter 

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

Geometry router - routes entities to processors

Implementations§

Source§

impl GeometryRouter

Source

pub fn new_brep_signature_cache() -> SharedBrepSignatureCache

Create a fresh signature cache for ONE immutable loaded model.

Source

pub fn enable_shared_brep_signature_cache( &mut self, cache: SharedBrepSignatureCache, )

Reuse completed BREP signatures across routers of the SAME source model. Attach a fresh cache when replacing the source, just like the item cache.

Source§

impl GeometryRouter

Source

pub fn drain_processor_failures(&self)

Sweep every registered processor’s own boolean-failure log into this router’s map. Called by Self::take_csg_failures, so a consumer that already drains the router — the native pipeline via produce_element_meshes, the wasm batch path via drain_and_log_csg_diagnostics — picks these up with no second opt-in.

Before #3821 BooleanClippingProcessor::take_failures was called from tests ONLY. Everything the boolean processor recorded (an unsupported operand, an EmptyOperand cutter, an unknown operator) accumulated in a RefCell no production caller ever read, so a model whose booleans all degraded still reported a clean load: absence was indistinguishable from success.

Bucketed under UNATTRIBUTED_PRODUCT_ID — the same “no attribution available” bucket take_csg_failures already uses for PENDING_MAPPED_BOOL_FAILURES. A processor is registered once per router and reused across every item it meshes, so at drain time its log is not attributable to one product from in here.

What that bucket does and does NOT preserve, precisely: the native and wasm pipelines both drain PER ELEMENT (produce_element_meshes takes the router’s failures after each job), so a record can never be mis-attributed to a DIFFERENT element — it is attributed to none. The element it came from is lost, so these records do not appear in the per-product worst_hosts detail and are excluded from products_with_failures (see super::count_attributed_products); they do count towards the failure totals and the reason breakdown. Real per-product attribution would mean threading the owning product id down to every processor.process call site; that is a follow-up, not a reason to keep dropping the records.

register stores ONE Rc per custom processor under each supported IFC type (IfcBooleanResult and IfcBooleanClippingResult share an instance), so iterating custom registrations can visit the same processor twice; the second visit drains an already-emptied log and contributes nothing. No double count.

Source§

impl GeometryRouter

Source

pub fn take_unsupported_items(&self) -> FxHashMap<String, u64>

Drain the dropped-item counts gathered since the last call.

Does NOT forget the sources already counted: the drain moves counts to the caller, it does not un-see them. That happens with the mapped-item cache this mirrors (set_tessellation_quality), since a re-tessellation re-walks every source.

Source§

impl GeometryRouter

Source

pub fn take_csg_failures(&self) -> FxHashMap<u32, Vec<BoolFailure>>

Drain every boolean / CSG failure this router knows about since it was created (or the last take_csg_failures call). The single drain point: the native pipeline and the wasm batch path both call this and nothing else.

Two kinds of record come out, distinguished by their key:

  • Keyed by IFC product express id — the void-subtraction path (multi-layer wall sub-meshes, single-mesh process_element_with_voids_parts), which knows the host element whose opening / clip tripped a fallback.
  • Keyed by UNATTRIBUTED_PRODUCT_ID — the registered processors’ own logs (swept by Self::drain_processor_failures, #3821, including what the transient boolean under an IfcCsgSolid hands back to CsgSolidProcessor) and the producer-less hatch. Standalone IfcBooleanResult chains DO flow here now; what they still lack is the owning product id. See drain_processor_failures for the cost.
Source

pub fn take_layer_slice_diag(&self) -> Vec<(u32, &'static str)>

Drain the per-element layered-slice diagnostics gathered since the last call (wasm logs them to the browser console after each batch).

Source

pub fn csg_failure_product_count(&self) -> usize

Products with at least one recorded CSG failure, under the same count_attributed_products rule the pipelines’ scalar uses (a bare .len() would make this the one surface counting the synthetic bucket). PEEKS: no processor sweep, unlike take_csg_failures.

Source

pub fn csg_failure_total(&self) -> usize

Total CSG failures, INCLUDING the unattributed bucket (real failures, unknown owner). Peeks, like Self::csg_failure_product_count.

Source

pub fn host_consumed_by_void(&self, product_id: u32) -> bool

Whether a host product was fully consumed by a containing void (its opening’s real solid engulfs the host). An empty void-cut result for such a host is CORRECT — the element should render nothing — and must not trigger the un-cut fallback.

Source

pub fn take_classification_stats(&self) -> ClassificationStats

Drain and return the cumulative opening-classification counters since the router was created (or the last take_classification_stats call). The internal counters are reset to zero.

Source

pub fn take_host_opening_diagnostics( &self, ) -> FxHashMap<u32, HostOpeningDiagnostic>

Drain and return the per-host opening diagnostic map.

Source

pub fn take_rect_fast_stats(&self) -> RectFastStats

Drain and return this router’s rect_fast counters (resets them to zero).

Source

pub fn host_opening_diagnostic_count(&self) -> usize

Total number of hosts with diagnostic records (mostly for tests).

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

Errors when the items cannot share one f64 frame (#6349); use Self::process_element_parts to keep such products at full precision.

Source

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

Self::process_element as frame parts: one mesh, unless body items lie in frames at least 1 km apart, which stay separate meshes (#6349).

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_representation_item( &self, item: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Result<Mesh>

Process a single representation item (IfcExtrudedAreaSolid, etc.), with content-dedup: a 128-bit structural hash of the item subtree skips the meshing + CSG for geometry byte-identical to an item meshed earlier (e.g. the thousands of Tekla connection plates/bolts an exporter failed to share via IfcMappedItem). The cached mesh is colour-free and pre-placement; the caller keeps this item’s own geometry_id (so colour/palette/texture stay per-instance) and applies voids + placement afterwards, so a cache hit is indistinguishable from a fresh build.

Source

pub fn take_content_hash_oversized_ref_drops(&self) -> usize

Drain refs the content-hash walk refused above u32::MAX (#3421/#3752).

Source§

impl GeometryRouter

Source

pub fn detect_rtc_anchor_for_file( &self, content: &[u8], decoder: &mut EntityDecoder<'_>, ) -> Option<(f64, f64, f64)>

Self::detect_rtc_offset_for_file’s window with no placement-bounds fallback. None when no usable translation sample was found, so a caller can tell “no shift needed” from “detection had no data” — the distinction the streaming ladder in ifc_lite_processing::stream_meta climbs.

Source

pub fn detect_rtc_offset_for_file( &self, content: &[u8], decoder: &mut EntityDecoder<'_>, ) -> Option<RtcVerdict>

The RTC verdict for content: the median over the canonical sample window, or the full-file placement-bounds scan when that window yielded no usable translation.

Single shared entry point for the server processing path, the wasm prepasses and the overlays, so every one of them makes the identical needs-shift decision: a model whose sampled placements fail to decode while raw geometry carries coordinates past crate::LARGE_COORD_THRESHOLD_METERS (1 km, was 10 km before #4934) must be re-based identically everywhere (previously the wasm prepasses silently fell back to (0,0,0) and the browser rendered f32 vertex jitter that the server never saw).

The spans are [file_geometry_spans] — every geometry-bearing entity of content, in file order, sampled lazily to the sampler’s usable-sample cap. They are deliberately NOT a job list the caller passes in: a job list is a SCHEDULE, and every pipeline schedules differently, so a caller-supplied window made the median anchor a function of the scheduler rather than of the model and one file resolved to several anchors (#4611, pinned by wasm-bindings/src/api/gpu_meshes/prepass_tests.rs).

None means neither ladder found a coordinate to judge; MeshFrame::select in ifc_lite_processing decides what that means.

Source§

impl GeometryRouter

Source

pub fn process_element_with_submeshes_textured( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, texture_index: &FxHashMap<u32, ResolvedTextureMap>, ) -> Result<SubMeshCollection>

Texture-aware Self::process_element_with_submeshes (#1781): a face set listed in texture_index becomes its own textured sub-mesh carrying per-vertex UVs + the texture attachment. The void path never passes an index — a CSG cut rebuilds vertices, which would orphan the UVs, so a voided textured element renders with its style colour instead.

Source

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

Tessellate an IfcRepresentationMap’s MappedRepresentation and bake its MappingOrigin placement (issue #957).

Used to render geometry that hangs off an IfcTypeProduct (e.g. IfcBoilerType) through its RepresentationMaps when no occurrence instantiates it — the buildingSMART annex-E “tessellated shape with style” samples ship exactly this shape (geometry on the type, declared via IfcRelDeclares, with no product instance).

Unlike Self::process_mapped_item_cached, this applies MappingOrigin (IfcRepresentationMap attr 0) rather than a MappingTarget: there is no occurrence placement and no IfcMappedItem to carry one, so the MappingOrigin axis placement is the only transform. It is the caller’s responsibility to only invoke this for orphan representation maps so normally-instanced typed products aren’t double-rendered.

Errors when the map’s items cannot share one f64 frame (#6446); use Self::process_representation_map_with_texture to keep such a map at full precision.

Source

pub fn process_representation_map_with_texture( &self, rep_map: &DecodedEntity, decoder: &mut EntityDecoder<'_>, texture_index: &FxHashMap<u32, ResolvedTextureMap>, ) -> Result<Vec<(Mesh, Vec<f32>, Option<TextureAttachment>)>>

Texture-aware variant of Self::process_representation_map (issue #961). Returns one render part per output mesh: each textured IfcTriangulatedFaceSet item becomes its OWN part carrying its UVs + decoded image (so a representation with several differently-textured items renders each with the correct image), and all untextured items are merged into a single part with empty UVs / no texture, except that untextured items in frames at least 1 km apart stay separate untextured parts (#6446). The MappingOrigin placement is baked into every part.

Source§

impl GeometryRouter

Source

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

Strict column-major local frame of an IfcLinearPlacement relative to its PlacementRelTo, exactly as rendering composes it, in file units. Unlike rendering there is no identity fallback: a writer baking this frame must refuse a placement it cannot resolve (#7335).

Source§

impl GeometryRouter

Source

pub fn resolve_scaled_mapped_item_transform( &self, item: &DecodedEntity, source: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Result<Option<[f64; 16]>>

Resolve an IfcMappedItem placement in metre coordinates. The returned column-major matrix retains the authored linear part; only translation receives the IFC length-unit scale.

Source

pub fn resolve_scaled_mapped_item_transform_with_origin_loader<F>( &self, item: &DecodedEntity, decoder: &mut EntityDecoder<'_>, origin: F, ) -> Result<Option<[f64; 16]>>
where F: FnOnce(&mut EntityDecoder<'_>) -> Result<Option<Matrix4<f64>>>,

Resolve a mapped target with a caller-supplied source-origin loader. The loader runs after target parsing, preserving the standard error precedence, and may reuse a parsed origin for repeated source maps.

Source

pub fn mapping_origin_transform( &self, source: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Result<Option<Matrix4<f64>>>

IfcRepresentationMap.MappingOrigin (attr 0) as a 4x4, or None when it is absent or null (nothing to compose), or the identity.

A PRESENT origin that cannot be turned into a placement — a dangling reference, or an entity that is not an IfcAxis2Placement — is an ERROR, not a silent identity. Every other consumer of a broken mapped-item transform now behaves that way: the MappingTarget operator parse has always propagated (a non-IfcDirection axis errors), the void fast-path probes defer the opening to the exact kernel, and the 2D drawing extractor abandons the profile. Substituting the identity here would render the item at a position nothing else agrees with. #1985

Source§

impl GeometryRouter

Source

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

Exact counterpart to resolve_scaled_placement: refuses a world placement when the shared reference-walk guard truncated its chain.

Source§

impl GeometryRouter

Source

pub fn parametric_rect_probe_all( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Option<Vec<RectParam>>

EXACT boxes for a body that is a UNION OF RECTANGULAR PRISMS (the common Tekla multi-solid opening): one box per representation item, or None if any item is not a rectangular extrusion. The cellular rect_fast cut subtracts the N boxes natively.

Source

pub fn parametric_rect_probe( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Option<RectParam>

PHASE-0 CENSUS (read-only): the EXACT oriented rectangular box of an extruded element, read from the IFC parametrics (IfcRectangleProfileDef XDim/YDim/Depth + composed placement axes), NOT inferred from the f32 mesh. Returns None unless the element’s body is a single clean IfcRectangleProfileDef extrusion (after unwrapping IfcBooleanClippingResult / IfcMappedItem). This is the parametric frame + extents the failed oriented attempt should have used instead of infer_opening_frame + mesh-AABB.

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§

impl GeometryRouter

Source

pub fn opening_requires_subtraction( &self, id: u32, decoder: &mut EntityDecoder<'_>, ) -> bool

Whether an opening must retain the canonical cutter path. Only a proven Reference-only opening (optionally with BoundingBox) returns false. Unknown, malformed, empty and over-budget representation data returns true so ordinary cutter/error handling remains authoritative (#4440).

Source§

impl GeometryRouter

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.

Errors when the element’s body items cannot share one f64 frame (#6349); Self::process_element_with_voids_parts keeps them.

Source

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

Self::process_element_with_voids over the element’s frame parts (Self::process_element_parts): each part is cut by the same openings, classified once. An ordinary element has exactly one part (#6349).

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 new() -> Self

Create new router with default processors

Source

pub fn with_units<T>(content: &T, decoder: &mut EntityDecoder<'_>) -> Self
where T: AsRef<[u8]> + ?Sized,

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

Source

pub fn with_units_and_rtc<T>( content: &T, decoder: &mut EntityDecoder<'_>, rtc_offset: (f64, f64, f64), ) -> Self
where T: AsRef<[u8]> + ?Sized,

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_scale_and_local_frame(unit_scale: f64, enabled: bool) -> Self

Create a router with an explicit per-mesh local-frame policy.

This is intentionally a constructor rather than a mutable switch: mesh caches are frame-dependent, so the policy must be fixed before any geometry is produced.

Source

pub fn new_dedup_cache() -> ItemDedupCache

A fresh empty shared item-dedup cache, to be cloned into every per-element / per-batch router of ONE loaded model so they all dedup against it. Keep one per model: the key is a per-model entity-structure hash, and the cached meshes bake in this model’s unit scale / tessellation quality.

Source

pub fn build_dedup_extra_enabled() -> bool

Whether content-dedup covers EXTRA item types beyond the proven default set (faceset / surface-model families). item_signature’s generic byte walk is already complete for them, so this is pure additive build savings on models that repeat tessellated geometry — but it pays a hash on every such item, so it stays OFF by default until corpus-validated (low-reuse models would pay the hash for no payback, the #1177 trap). Opt in with IFC_LITE_DEDUP_EXTRA=1 or Self::set_build_dedup_extra_override. Default OFF keeps native==wasm identical.

Source

pub fn set_build_dedup_extra_override(v: Option<bool>)

Test-only: force Self::build_dedup_extra_enabled on/off (None = env).

Source

pub fn enable_content_dedup_shared(&mut self, cache: ItemDedupCache)

Inject a shared item-dedup cache (see Self::new_dedup_cache) into this router. All routers given the SAME Arc dedup against one cache, so byte-identical geometry is meshed once across the whole model regardless of how elements are partitioned across threads or batches.

Source

pub fn new_mapped_item_cache() -> SharedMappedItemCache

A fresh empty shared IfcMappedItem source cache, to be cloned into every per-element / per-batch router of ONE loaded model so a mapped source shared across owning elements is meshed once model-wide (#1623). Mirrors Self::new_dedup_cache. Keep one per model/pass: the cached meshes bake in this pass’s unit scale / tessellation quality.

Source

pub fn enable_shared_mapped_item_cache(&mut self, cache: SharedMappedItemCache)

Inject a shared IfcMappedItem source cache (see Self::new_mapped_item_cache) into this router. All routers given the SAME Arc mesh each unique IfcRepresentationMap source once across the whole model, instead of once per owning element (a fresh router is built per element). Takes precedence over the per-router RefCell mapped_item_cache; leaving it unset keeps the per-router fallback for single-shot callers.

Source

pub fn enable_output_instancing(&mut self, plan: MappedInstancePlan)

Arm the #1623 Phase 2 don’t-bake instancing plan (see MappedInstancePlan) on this router. Requires a shared mapped-item cache to be enabled too — the don’t-bake instance placeholders rely on the source being meshed once into it (the orphan-recovery template at finalize reads it). Leaving it unset keeps every occurrence materializing (byte-identical flat output).

Source

pub fn enable_indexed_colour_split_guard(&mut self, ids: Arc<FxHashSet<u32>>)

Arm the #858 don’t-bake exclusion set: geometry-item ids of mapped sources whose single solid carries an IfcIndexedColourMap. Such a source is routed to the flat materialize (per-palette split) instead of don’t-bake, so its occurrences keep the per-triangle palette (an instance placeholder would collapse it to one colour). Armed alongside Self::enable_output_instancing when the model has any indexed-colour maps; unset ⇒ no exclusion.

Source

pub fn set_preserve_triangle_order(&self, on: bool) -> bool

Keep source hygiene index-only for the elements meshed until this is called again with false, because a caller will map their triangles back to source faces by index (#858’s per-triangle colour split). Returns the previous setting so a caller can restore it.

Source

pub fn set_instancing_batch_local(&mut self, on: bool)

Select the #1623 Phase 3 batch-local template mode (see Self::instancing_batch_local). The WASM per-batch path sets this so each batch materializes its OWN first-seen template per source and stays a self-contained shard; the native path leaves it off (global min-id template).

Source

pub fn disable_content_dedup(&mut self)

Disable content-dedup (drops the cache reference so item_dedup_key returns None and meshing is never skipped). Test/bench helper for an A/B against the deduped path.

Source

pub fn dedup_unique_count(&self) -> usize

Number of unique item meshes cached by content-dedup so far — the reuse the pipeline recovered (vs. the meshed-item count). Diagnostics.

Source

pub fn mapped_shared_unique_count(&self) -> usize

Number of unique IfcRepresentationMap sources meshed into the SHARED mapped-item cache so far (0 when no shared cache is injected — the RefCell fallback isn’t counted). Diagnostics, mirroring Self::dedup_unique_count; used by the #1623 A/B test to confirm the shared cache actually captured sources (so a cross-router hit is genuinely exercised, not a no-op).

Source

pub fn geometry_routing_key( &self, element: &DecodedEntity, decoder: &mut EntityDecoder<'_>, ) -> Option<u128>

Content-routing key for an element: a 128-bit structural hash of its WHOLE representation subtree (the Representation attribute, e.g. an IfcProductDefinitionShape), or None if it has no geometry. Two elements with byte-identical geometry — even renumbered — share a key, so a host can route them to the same worker; combined with the per-worker dedup cache the geometry is then meshed once per worker. Meshing-free (decode + fold) and reuses the per-router signature memo so shared sub-entities are hashed once.

(A per-instance shape-representation wrapper can make this finer than the per-ITEM dedup unit, but a true 4-router simulation showed that costs essentially no extra meshing — 1.01× — because the shared items still land on one worker, so the simpler whole-representation hash is used.)

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 with_quality(quality: TessellationQuality) -> Self

Create router with a specific tessellation quality level

Source

pub fn with_scale_and_quality( unit_scale: f64, quality: TessellationQuality, ) -> Self

Create router with both unit scale and tessellation quality

Source

pub fn set_tessellation_quality(&mut self, quality: TessellationQuality)

Set the tessellation quality level.

A quality change invalidates mapped_item_cache (keyed by RepresentationMap id, not by quality) and the record of which sources’ drops are already counted, since every source is re-walked; both are cleared here. The content-hash-keyed caches stay correct.

Source

pub fn tessellation_quality(&self) -> TessellationQuality

Get the current tessellation quality level

Source

pub fn set_skip_small_cuts(&mut self, on: bool)

Set the per-build small-cut skip (#1286) and re-register the boolean / CSG / mapped processors so they carry it. Tier-independent: the viewer turns this on to skip tiny steel copes/notches for fast first paint while the tessellation tier stays at Medium (curves keep full density).

Scoped to this router instance, so a concurrent native build with the skip off is unaffected (this replaced a process-wide static that bled across builds). false (default) keeps every cut, byte-identical to before the optimization.

Source

pub fn skip_small_cuts(&self) -> bool

Get the current per-build small-cut skip flag.

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 is_material_layer_sliceable(&self, element_id: u32) -> bool

True when element_id carries a sliceable IfcMaterialLayerSetUsage, i.e. process_element_with_submeshes would split it into per-layer sub-meshes. Lets the mesh producer render the wall as ONE solid in 3D while still emitting the per-layer slices (tagged section-only) for the 2D cut.

Source

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

Register a geometry processor

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
§

impl<U> As for U

§

fn as_<T>(self) -> T
where T: CastFrom<U>,

Casts self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. 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.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

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

Initializes a with the given initializer. Read more
§

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

Dereferences the given pointer. Read more
§

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

Mutably dereferences the given pointer. Read more
§

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
§

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

§

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

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

fn is_in_subset(&self) -> bool

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

fn to_subset_unchecked(&self) -> SS

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

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

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more