pub struct IfcAPI { /* private fields */ }Expand description
Main IFC-Lite API
Implementations§
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn parse_alignment_lines(&self, content: String) -> Float32Array
pub fn parse_alignment_lines(&self, content: String) -> Float32Array
Parse the file and return every IfcAlignment directrix as a flat
Float32Array of 3D line-list vertices [x0,y0,z0, x1,y1,z1, …] in
the renderer’s Y-up world space (RTC-subtracted, metres). Consecutive
samples form line segments. Feed straight to
renderer.setLineOverlay('alignment', ...).
Returns an empty array when the file has no alignments (or none with a resolvable Axis curve), so the caller can clear the overlay cheaply.
Sourcepub fn parse_alignment_lines_in_frame(
&self,
content: String,
frame: JsValue,
) -> Result<Float32Array, JsValue>
pub fn parse_alignment_lines_in_frame( &self, content: String, frame: JsValue, ) -> Result<Float32Array, JsValue>
Parse alignments in the exact RTC frame selected by the mesh pre-pass.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn plan_appearance(
&self,
content: &[u8],
request_json: &str,
) -> Result<Vec<u8>, JsError>
pub fn plan_appearance( &self, content: &[u8], request_json: &str, ) -> Result<Vec<u8>, JsError>
Plan image/UV edits against an effective IFC snapshot without mutating it. JSON input uses AppearanceRequest; output is UTF-8 AppearancePlan JSON. Call from a worker, then validate sourceRevision and allocator before an atomic host commit. Preview UVs describe an unsplit canonical mesh item.
Sourcepub fn catalog_appearance(
&self,
content: &[u8],
request_json: &str,
) -> Result<Vec<u8>, JsError>
pub fn catalog_appearance( &self, content: &[u8], request_json: &str, ) -> Result<Vec<u8>, JsError>
Catalog effective IfcProduct classes and IfcRelDefinesByType membership. JSON input is AppearanceCatalogRequest; output is AppearanceCatalog JSON. Run in a worker and validate sourceRevision before using the selectors.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn plan_page_appearance(
&self,
content: &[u8],
request_json: &str,
rgba: &[u8],
) -> Result<Vec<u8>, JsError>
pub fn plan_page_appearance( &self, content: &[u8], request_json: &str, rgba: &[u8], ) -> Result<Vec<u8>, JsError>
Finite-page composition over original canonical albedo. RGBA is supplied separately from the bounded JSON request. Result: IFPA magic, little-endian u32 JSON byte length, metadata JSON, then PNG bytes addressed by metadata. Run in a cancellable worker; atomically adopt every item asset and IFC edit.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn plan_mesh_transfer(
&self,
content: &[u8],
request_json: &str,
rgba: &[u8],
) -> Result<Vec<u8>, JsError>
pub fn plan_mesh_transfer( &self, content: &[u8], request_json: &str, rgba: &[u8], ) -> Result<Vec<u8>, JsError>
Registered mesh observations over canonical target albedo. Host verifies
original GLB identity against decoded source mesh/image and freezes frames.
Run in an owned cancellable worker. IFPA output adds transfer coverage;
plan is null when no sample is observed. Never infer accuracy approval.
Sourcepub fn plan_point_transfer(
&self,
content: &[u8],
request_json: &str,
rgba: &[u8],
positions: &[f64],
colors: &[u8],
normals: &[f32],
stations: &[u32],
) -> Result<Vec<u8>, JsError>
pub fn plan_point_transfer( &self, content: &[u8], request_json: &str, rgba: &[u8], positions: &[f64], colors: &[u8], normals: &[f32], stations: &[u32], ) -> Result<Vec<u8>, JsError>
Registered RGB point-cloud observations (#4381). request_json.source
is {kind:'points', …}; positions (3n f64, source-frame metres) and
colors (3n RGB8) are the payload, normals (3n f32, oriented) and
stations (n indices into source.viewpoints) are empty when absent.
rgba carries only the target’s existing rasters. Same output as
planMeshTransfer; transfer.source records the orientation used.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn plan_annotation_plane(
&self,
content: &[u8],
request_json: &str,
) -> Result<Vec<u8>, JsError>
pub fn plan_annotation_plane( &self, content: &[u8], request_json: &str, ) -> Result<Vec<u8>, JsError>
Create a calibrated image annotation through canonical native geometry. Input is AnnotationPlaneRequest; output UTF-8 AnnotationPlanePlan JSON. Does not mutate the IFC snapshot or decode the host-owned image.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn plan_captured_mesh(
&self,
content: &[u8],
request_json: &str,
) -> Result<Vec<u8>, JsError>
pub fn plan_captured_mesh( &self, content: &[u8], request_json: &str, ) -> Result<Vec<u8>, JsError>
Create a captured textured surface through canonical native geometry. Input is CapturedMeshRequest; output UTF-8 CapturedMeshPlan JSON. Does not mutate the IFC snapshot or decode the host-owned image.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn propose_scan_elements(
&self,
report_json: &str,
options_json: &str,
) -> Result<Vec<u8>, JsError>
pub fn propose_scan_elements( &self, report_json: &str, options_json: &str, ) -> Result<Vec<u8>, JsError>
Propose IFC walls, slabs, columns and pipes from a scan segmentation
report (#6894). report_json is the JSON segmentScanPoints
returned; options_json is a camelCase ScanProposalOptions object
({} for the defaults; scanToModel maps the report’s frame into the
IFC model frame). Returns the UTF-8 JSON ScanProposalReport in the
model frame (Z up, metres). Pure: loads and changes nothing.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn segment_scan_points(
&self,
positions: &[f32],
options_json: &str,
) -> Result<Vec<u8>, JsError>
pub fn segment_scan_points( &self, positions: &[f32], options_json: &str, ) -> Result<Vec<u8>, JsError>
Detect planes and cylinders (columns, pipes) in a point cloud (#6870). positions are xyz f32 metres
(at most 100,000,000 points); options_json is a camelCase
ScanSegmentationOptions object ({} for the defaults). Returns the
UTF-8 JSON ScanSegmentationReport. Pure: loads and changes nothing.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn plan_pdf_fill_annotation(
&self,
source: &[u8],
request_json: &str,
) -> Result<Vec<u8>, JsError>
pub fn plan_pdf_fill_annotation( &self, source: &[u8], request_json: &str, ) -> Result<Vec<u8>, JsError>
Plan an opaque polygonal PDF fill page as canonical IfcAnnotation geometry with a provenance property set. An exact page plans directly; a page with visible omissions needs the accepted fidelity report digest.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn diagnose_geometry(&self, content: &[u8]) -> JsValue
pub fn diagnose_geometry(&self, content: &[u8]) -> JsValue
Run geometry extraction on content and return its typed CSG / opening
diagnostics (the GeometryDiagnostics contract) as a JS object, or
undefined when nothing diagnostic-worthy happened (no openings, no
failures). Takes the raw IFC bytes (Uint8Array) so there is no input-size
cap. The produced meshes are dropped; only the diagnostics are returned.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn set_entity_index_owned_binding(
&self,
ids: Vec<u32>,
starts: Vec<u32>,
lengths: Vec<u32>,
) -> Result<(), JsValue>
pub fn set_entity_index_owned_binding( &self, ids: Vec<u32>, starts: Vec<u32>, lengths: Vec<u32>, ) -> Result<(), JsValue>
Populate cached_entity_index from pre-extracted column arrays.
Used by the streaming pre-pass to share its already-built entity
index across worker realms via SAB-backed Uint32Arrays — every
process worker would otherwise re-scan the entire file in
processGeometryBatch’s lazy build path (~5 s on a 1 GB IFC),
even though the pre-pass worker built the same index minutes
earlier.
Adopts the three binding-owned columns into a compact ColumnarEntityIndex
(sorted u32 columns + binary search) instead of a per-worker
FxHashMap — ~229 MB vs ~436 MB on a 19.1 M-entity model (#1682).
ColumnarEntityIndex::from_owned_columns verifies the id ordering once
(O(n)) and only argsorts if the producer did not emit sorted columns.
lengths[i] is the byte length of entity ids[i], so lookup returns
(start, start + length) to match the existing (start, end) layout.
Idempotent in the sense that repeated calls REPLACE the cache — supports the parser-worker pattern of reusing one IfcAPI across multiple loads with different files.
Throws when the three columns disagree in length. Every call is a content swap, a rejected one included: the previous file’s index, content-scoped caches and pipeline diagnostics are dropped before the error is raised, and a rejected or empty index leaves no index, so the next batch scans the bytes it is given.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn set_entity_index(
&self,
ids: &[u32],
starts: &[u32],
lengths: &[u32],
) -> Result<(), ColumnLengthMismatch>
pub fn set_entity_index( &self, ids: &[u32], starts: &[u32], lengths: &[u32], ) -> Result<(), ColumnLengthMismatch>
Install an entity index from borrowed columns, preserving the public Rust
API. The JavaScript binding consumes its owned ABI buffers separately
so it does not copy them again (#3989). Same contract as setEntityIndex.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn extrusion_definitions(
&self,
content: &[u8],
ids: Option<Vec<u32>>,
) -> Result<ExtrusionDefinitionsJs, JsValue>
pub fn extrusion_definitions( &self, content: &[u8], ids: Option<Vec<u32>>, ) -> Result<ExtrusionDefinitionsJs, JsValue>
ids is an optional product STEP-ID filter; None selects all and
Some([]) selects no products, matching the Rust and Python APIs.
Matrices are column-major f64; profile_position and position_matrix are
applied before world_from_source. No mesh is decoded on this path.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn export_csv(
&self,
content: &[u8],
mode: String,
delimiter: String,
include_properties: bool,
) -> Vec<u8> ⓘ
pub fn export_csv( &self, content: &[u8], mode: String, delimiter: String, include_properties: bool, ) -> Vec<u8> ⓘ
Export tabular CSV. mode ∈ {"entities", "properties", "quantities",
"spatial"}. delimiter defaults to , when empty; include_properties adds
flattened Pset_Prop columns to the entities view.
Sourcepub fn export_json(
&self,
content: &[u8],
pretty: bool,
include_properties: bool,
include_quantities: bool,
) -> Vec<u8> ⓘ
pub fn export_json( &self, content: &[u8], pretty: bool, include_properties: bool, include_quantities: bool, ) -> Vec<u8> ⓘ
Export structured JSON (array of entity objects with typed property values).
Sourcepub fn export_jsonld(
&self,
content: &[u8],
context: String,
include_properties: bool,
include_quantities: bool,
pretty: bool,
included: Option<Vec<u32>>,
) -> Vec<u8> ⓘ
pub fn export_jsonld( &self, content: &[u8], context: String, include_properties: bool, include_quantities: bool, pretty: bool, included: Option<Vec<u32>>, ) -> Vec<u8> ⓘ
Export JSON-LD (@graph of ifc: nodes). Empty context ⇒ buildingSMART
IFC4 OWL default.
included is an express-id isolation filter mirroring exportObj /
exportGlb, and carries the same null-vs-empty distinction across the wasm
boundary: omit it (undefined) for “no isolation filter” (every entity is
emitted); pass an empty Uint32Array for “isolation is ACTIVE and currently
matches nothing”, which emits an empty @graph. Collapsing the two — as a
bare Uint32Array parameter would force a caller to do — silently exported
the whole model when a filter matched nothing (#4659, the JSON-LD twin of
#4483/#4484). A non-empty Uint32Array is the ordinary allowlist.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn export_dfjson(&self, content: &[u8], name: String) -> String
pub fn export_dfjson(&self, content: &[u8], name: String) -> String
Export the IfcSpace volumes in content as a Dragonfly DFJSON string.
Each space becomes an extruded Room2D (floor polygon + floor-to-ceiling height)
grouped into stories — the simpler Ladybug Tools target for mostly-vertical-wall
models. Loads via dragonfly.model.Model.from_dfjson.
const api = new IfcAPI();
const dfjson = api.exportDfjson(ifcContent, "my_model");Source§impl IfcAPI
impl IfcAPI
Sourcepub fn export_glb(
&self,
content: &[u8],
include_metadata: bool,
hidden: &[u32],
isolated: Option<Vec<u32>>,
hidden_types_csv: String,
lit: Option<bool>,
emissive: Option<bool>,
) -> Result<Vec<u8>, JsValue>
pub fn export_glb( &self, content: &[u8], include_metadata: bool, hidden: &[u32], isolated: Option<Vec<u32>>, hidden_types_csv: String, lit: Option<bool>, emissive: Option<bool>, ) -> Result<Vec<u8>, JsValue>
Export the render geometry in content as a binary GLB (Uint8Array).
hidden / isolated are express-id visibility filters; hidden_types_csv is a
comma-separated list of IFC type names whose class toggle is off (e.g.
"IfcOpeningElement,IfcSpace"). isolated carries the isolation allowlist’s
null-vs-empty distinction across the wasm boundary: omit it (undefined) for
“no isolation filter” (every mesh is a candidate); pass an empty Uint32Array
for “isolation is ACTIVE and currently matches nothing” (every mesh is
excluded). Collapsing the two — as a bare Uint32Array parameter would force a
caller to do — silently exports the whole model when a filter matches nothing
(#4328 follow-up: reachable by filtering the Class tab to a type present only
in a federated model’s secondary member, then exporting “Visible Only”). A
non-empty Uint32Array is the ordinary allowlist. include_metadata attaches
counts + per-node expressId. Per-mesh RTC origin rides the node translation
(precision-safe).
lit emits standard PBR materials that shade from normals; omitted or
true ⇒ lit (the default), false ⇒ flat KHR_materials_unlit (the
historical look — #1321). Optional at the boundary so older 5-arg callers
keep lit-by-default behaviour.
emissive self-illuminates each material at its base colour (core glTF
emissiveFactor) so renderers without ambient/IBL — Google Earth — don’t
render the model near-black (#1427); omitted or false ⇒ off.
Fails CLOSED: when the visible mesh set is empty this throws an Error
whose message starts with NO_RENDER_GEOMETRY, instead of returning a
structurally valid but empty GLB. #1438 put that guard only in the TS
CLI/MCP wrappers; making the boundary itself refuse means SDK/viewer/
direct callers inherit it too (the TS guards stay as defense-in-depth).
Sourcepub fn export_glb_from_meshes(
&self,
positions: &[f32],
normals: &[f32],
indices: &[u32],
vertex_counts: &[u32],
index_counts: &[u32],
colors: &[f32],
origins: &[f64],
express_ids: &[u32],
include_metadata: bool,
lit: Option<bool>,
emissive: Option<bool>,
) -> Result<Vec<u8>, JsValue>
pub fn export_glb_from_meshes( &self, positions: &[f32], normals: &[f32], indices: &[u32], vertex_counts: &[u32], index_counts: &[u32], colors: &[f32], origins: &[f64], express_ids: &[u32], include_metadata: bool, lit: Option<bool>, emissive: Option<bool>, ) -> Result<Vec<u8>, JsValue>
Assemble a GLB from already-produced meshes (the viewer’s MeshData, flattened)
— no re-meshing. Per mesh i: vertex_counts[i] verts + index_counts[i] indices
taken in order from the concatenated positions/normals/indices; colors is
RGBA per mesh, origins xyz per mesh, express_ids labels each mesh (indices are
per-mesh local). The caller passes exactly the meshes it wants emitted.
Fails CLOSED: if the declared vertex/index counts run past the flattened
positions / indices, there are fewer index_counts than meshes, normals
is empty or too short to cover every vertex, a mesh’s index block is not a
whole number of triangles, or an index names a vertex its own mesh does not
have (glTF 2.0 3.7.2.1), this throws an Error whose message starts with
MALFORMED_MESH_INPUT — instead of silently emitting a GLB with those meshes
dropped, a TRIANGLES primitive whose count is not a multiple of 3, or the
out-of-range index copied into the BIN chunk. (The viewer always passes
fully-backed, normal-covered, whole-triangle, in-range arrays, so this only
fires on a caller bug.)
Sourcepub fn export_kmz_from_meshes(
&self,
positions: &[f32],
normals: &[f32],
indices: &[u32],
vertex_counts: &[u32],
index_counts: &[u32],
colors: &[f32],
origins: &[f64],
latitude: f64,
longitude: f64,
altitude: f64,
x_axis_abscissa: Option<f64>,
x_axis_ordinate: Option<f64>,
name: String,
altitude_mode: Option<String>,
) -> Result<Vec<u8>, JsValue>
pub fn export_kmz_from_meshes( &self, positions: &[f32], normals: &[f32], indices: &[u32], vertex_counts: &[u32], index_counts: &[u32], colors: &[f32], origins: &[f64], latitude: f64, longitude: f64, altitude: f64, x_axis_abscissa: Option<f64>, x_axis_ordinate: Option<f64>, name: String, altitude_mode: Option<String>, ) -> Result<Vec<u8>, JsValue>
Build a Google-Earth-ready KMZ (Uint8Array) straight from the viewer’s
already-produced meshes — the working path (#1427). The model is embedded as
COLLADA (model.dae), the only <Model> format Google Earth loads (a GLB
raises “Unsupported element: Model”), with emission-lit double-sided materials
placement. Mesh arrays match exportGlbFromMeshes;
latitude/longitude/altitude + x_axis_abscissa/x_axis_ordinate
(grid-north, undefined ⇒ heading 0) place + orient the model.
altitude_mode ("clampToGround" default ⇒ rest on terrain, ignoring
altitude; "absolute" ⇒ place at altitude metres MSL) selects the
KML vertical placement (#1427).
Fails CLOSED: when no triangle survives (an empty visible set, or meshes
whose only triangles are degenerate and collapse in the vertex dedup)
this throws an Error whose message starts with NO_RENDER_GEOMETRY;
a declared vertex/index count running past its buffer, an index block
that is not whole triangles, or an index outside its mesh throws
MALFORMED_MESH_INPUT, exactly as exportGlbFromMeshes does. These used
to ship as a “successful” archive: an empty one around a COLLADA
document the 1.4.1 schema rejects, or one with meshes or faces missing.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn export_hbjson(&self, content: &[u8], name: String) -> Vec<u8> ⓘ
pub fn export_hbjson(&self, content: &[u8], name: String) -> Vec<u8> ⓘ
Export the IfcSpace volumes in content as Honeybee HBJSON UTF-8 bytes.
Returned as UTF-8 bytes (Uint8Array) so output is not capped by the
V8 max-string ceiling (~512 MB); decode with TextDecoder when a string
is genuinely needed.
Rooms are built analytically from extruded-area profiles (watertight by construction);
faces are typed Floor / RoofCeiling / Wall with outward normals. The result loads via
honeybee.model.Model.from_hbjson and is ready for Ladybug Tools / Pollination.
const api = new IfcAPI();
const hbjson = api.exportHbjson(ifcContent, "my_model");Sourcepub fn export_hbjson_with_stats(&self, content: &[u8], name: String) -> JsValue
pub fn export_hbjson_with_stats(&self, content: &[u8], name: String) -> JsValue
Like Self::export_hbjson, but also returns the export’s coverage stats
(HbjsonStats: spaces seen, rooms emitted, spaces skipped as degenerate, plus
apertures / doors / shades / constructions / interior adjacencies) so a caller
can tell whether the “success” result silently dropped input.
Returns a plain JS object { content: Uint8Array, stats: HbjsonStats }; content
is UTF-8 HBJSON bytes (same encoding rationale as Self::export_hbjson — not
capped by the V8 max-string ceiling). Runs the export once — content and stats
come from the same pass, not two separate exports.
const api = new IfcAPI();
const { content, stats } = api.exportHbjsonWithStats(ifcContent, "my_model");
if (stats.skipped > 0) console.warn(`${stats.skipped} spaces skipped as degenerate`);Source§impl IfcAPI
impl IfcAPI
Sourcepub fn export_landxml_terrain(
&self,
content: &[u8],
product_ids: Vec<u32>,
options: LandXmlTerrainOptionsJs,
) -> Result<String, JsError>
pub fn export_landxml_terrain( &self, content: &[u8], product_ids: Vec<u32>, options: LandXmlTerrainOptionsJs, ) -> Result<String, JsError>
Export the terrain products product_ids (express ids) of content as
one LandXML 1.2 document, one <Surface> each.
Returns JSON { xml, crsName, surfaces: [{ productId, globalId, name, points, faces }] }. A selection that is not an authored triangulated
terrain, or whose georeferencing is missing or ambiguous, throws an
Error whose message starts with TERRAIN_REFUSED: and names the
reason.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn export_obj(
&self,
content: &[u8],
include_normals: bool,
hidden: &[u32],
isolated: Option<Vec<u32>>,
) -> Vec<u8> ⓘ
pub fn export_obj( &self, content: &[u8], include_normals: bool, hidden: &[u32], isolated: Option<Vec<u32>>, ) -> Vec<u8> ⓘ
Export the render geometry in content as Wavefront OBJ UTF-8 bytes.
Returned as UTF-8 bytes (Uint8Array) so output is not capped by the
V8 max-string ceiling (~512 MB); decode with TextDecoder when a string
is genuinely needed.
hidden is an express-id filter mirroring the viewer’s visibility state.
isolated carries the isolation allowlist’s null-vs-empty distinction across
the wasm boundary: omit it (undefined) for “no isolation filter” (every mesh
is a candidate); pass an empty Uint32Array for “isolation is ACTIVE and
currently matches nothing” (every mesh is excluded). Collapsing the two — as a
bare Uint32Array parameter would force a caller to do — silently exports the
whole model when a filter matches nothing (the OBJ twin of #4328/#4364, fixed
for GLB in export_glb). A non-empty Uint32Array is the ordinary allowlist.
Instanced type-library shapes are skipped regardless of the filter.
const obj = api.exportObj(ifcContent, true, new Uint32Array(), undefined);Source§impl IfcAPI
impl IfcAPI
Sourcepub fn plan_map_conversion_normalization(
&self,
content: &[u8],
) -> Result<String, JsError>
pub fn plan_map_conversion_normalization( &self, content: &[u8], ) -> Result<String, JsError>
Plan opt-in map similarity normalization on a completed STEP export. Returns entity patches, allocated IDs and atomic refusal warnings as JSON.
Sourcepub fn export_step(
&self,
content: &[u8],
schema: String,
included: Option<Vec<u32>>,
mutations_json: String,
) -> Result<Vec<u8>, JsError>
pub fn export_step( &self, content: &[u8], schema: String, included: Option<Vec<u32>>, mutations_json: String, ) -> Result<Vec<u8>, JsError>
Re-serialize the model in content to STEP/IFC UTF-8 bytes.
Returned as UTF-8 bytes (Uint8Array) so output is not capped by the
V8 max-string ceiling (~512 MB); decode with TextDecoder when a string
is genuinely needed.
schema is the FILE_SCHEMA label to write (empty ⇒ preserve the source schema).
included is an express-id allowlist carrying the same null-vs-empty
distinction as exportObj / exportGlb: omit it (undefined) for “no
isolation filter” (whole model); pass an empty Uint32Array for “isolation
is ACTIVE and currently matches nothing”, which writes a header-only file
with an empty DATA; section. Collapsing the two — as a bare Uint32Array
parameter would force a caller to do — silently exported the whole model
when a filter matched nothing (#4659, the STEP twin of #4483/#4484). When
set, the forward #-reference closure is added so the subset never dangles
a reference.
mutations_json carries MutablePropertyView edits; empty ⇒ none. It is
either the mutation log MutablePropertyView.exportMutations() returns
(an object with a mutations array, optionally newEntities and
georefMutations), written with byte parity to the TypeScript
StepExporter (#5941), or the older pre-serialized
{ attributeUpdates, propertyMutations } shape. A log does not combine
with included. See export_step_json for both shapes.
A non-empty but malformed mutations_json throws rather than silently
exporting the model with none of the caller’s edits applied — mirrors
exportGlb’s and exportMerged’s fail-closed contract on this same API.
Sourcepub fn export_merged(
&self,
concatenated: &[u8],
lengths: &[u32],
schema: String,
) -> Vec<u8> ⓘ
pub fn export_merged( &self, concatenated: &[u8], lengths: &[u32], schema: String, ) -> Vec<u8> ⓘ
Merge several IFC models into one STEP/IFC UTF-8 byte buffer (Uint8Array).
concatenated is every model’s
bytes laid end-to-end; lengths[i] is the byte length of model i. The first model
keeps its ids; later models are id-offset and their project unified to the first.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn extract_profiles(
&self,
content: String,
model_index: u32,
) -> ProfileCollection
pub fn extract_profiles( &self, content: String, model_index: u32, ) -> ProfileCollection
Extract raw profile polygons from all building elements with IfcExtrudedAreaSolid
representations.
Returns a [ProfileCollection] whose entries each carry:
- A 2D polygon (outer + holes) in local profile space (metres)
- A 4 × 4 column-major transform in WebGL Y-up world space
- Extrusion direction (world space) and depth (metres)
Use [ProfileProjector] (TypeScript) to convert these into DrawingLine[]
for clean projection without tessellation artifacts.
const api = new IfcAPI();
const profiles = api.extractProfiles(ifcContent, 0);
console.log('Profiles:', profiles.length);
for (let i = 0; i < profiles.length; i++) {
const p = profiles.get(i);
console.log(p.ifcType, 'depth:', p.extrusionDepth);
}Source§impl IfcAPI
impl IfcAPI
Sourcepub fn process_geometry_batch(
&self,
data: &[u8],
jobs_flat: &[u32],
unit_scale: f64,
rtc_x: f64,
rtc_y: f64,
rtc_z: f64,
needs_shift: bool,
void_keys: &[u32],
void_counts: &[u32],
void_values: &[u32],
style_ids: &[u32],
style_colors: &[u8],
plane_angle_to_radians: Option<f64>,
material_element_ids: Option<Vec<u32>>,
material_color_counts: Option<Vec<u32>>,
material_colors_rgba: Option<Vec<u8>>,
) -> MeshCollection
pub fn process_geometry_batch( &self, data: &[u8], jobs_flat: &[u32], unit_scale: f64, rtc_x: f64, rtc_y: f64, rtc_z: f64, needs_shift: bool, void_keys: &[u32], void_counts: &[u32], void_values: &[u32], style_ids: &[u32], style_colors: &[u8], plane_angle_to_radians: Option<f64>, material_element_ids: Option<Vec<u32>>, material_color_counts: Option<Vec<u32>>, material_colors_rgba: Option<Vec<u8>>, ) -> MeshCollection
Process geometry for a subset of pre-scanned entities → flat
MeshCollection. Takes raw bytes + pre-pass data from buildPrePassOnce.
Thin wrapper over IfcAPI::produce_batch; converts each produced mesh
to MeshDataJs (the IFC Z-up→WebGL Y-up rotation with preserved winding happens
there). Flat indices preserve source order through this proper rotation.
Sourcepub fn process_geometry_batch_instanced(
&self,
data: &[u8],
jobs_flat: &[u32],
unit_scale: f64,
rtc_x: f64,
rtc_y: f64,
rtc_z: f64,
needs_shift: bool,
void_keys: &[u32],
void_counts: &[u32],
void_values: &[u32],
style_ids: &[u32],
style_colors: &[u8],
plane_angle_to_radians: Option<f64>,
material_element_ids: Option<Vec<u32>>,
material_color_counts: Option<Vec<u32>>,
material_colors_rgba: Option<Vec<u8>>,
) -> Vec<u8> ⓘ
pub fn process_geometry_batch_instanced( &self, data: &[u8], jobs_flat: &[u32], unit_scale: f64, rtc_x: f64, rtc_y: f64, rtc_z: f64, needs_shift: bool, void_keys: &[u32], void_counts: &[u32], void_values: &[u32], style_ids: &[u32], style_colors: &[u8], plane_angle_to_radians: Option<f64>, material_element_ids: Option<Vec<u32>>, material_color_counts: Option<Vec<u32>>, material_colors_rgba: Option<Vec<u8>>, ) -> Vec<u8> ⓘ
Like IfcAPI::process_geometry_batch but collates the batch’s meshes
into a GPU-instancing shard (IFNS wire format) instead of a flat
MeshCollection. Repeated geometry collapses to one template + per-
occurrence transforms; non-instanceable meshes ride as flat singleton
templates so nothing is dropped. The shard stays in the producer-native
(IFC Z-up) frame — the renderer composes the constant Z-up→Y-up swap at
upload. Each batch shard renders independently: affinity routing already
co-locates identical geometry on one worker, so per-batch collation
captures ~all the dedup and no cross-batch merge is needed. Returns empty
bytes only when the batch produced zero non-empty meshes.
Sourcepub fn process_geometry_batch_partitioned(
&self,
data: &[u8],
jobs_flat: &[u32],
unit_scale: f64,
rtc_x: f64,
rtc_y: f64,
rtc_z: f64,
needs_shift: bool,
void_keys: &[u32],
void_counts: &[u32],
void_values: &[u32],
style_ids: &[u32],
style_colors: &[u8],
plane_angle_to_radians: Option<f64>,
material_element_ids: Option<Vec<u32>>,
material_color_counts: Option<Vec<u32>>,
material_colors_rgba: Option<Vec<u8>>,
) -> PartitionedBatch
pub fn process_geometry_batch_partitioned( &self, data: &[u8], jobs_flat: &[u32], unit_scale: f64, rtc_x: f64, rtc_y: f64, rtc_z: f64, needs_shift: bool, void_keys: &[u32], void_counts: &[u32], void_values: &[u32], style_ids: &[u32], style_colors: &[u8], plane_angle_to_radians: Option<f64>, material_element_ids: Option<Vec<u32>>, material_color_counts: Option<Vec<u32>>, material_colors_rgba: Option<Vec<u8>>, ) -> PartitionedBatch
Produce a batch ONCE and PARTITION it (the instanced-ONLY path): opaque ordinary occurrences (colour alpha >= 0.99 AND geometry_class == 0) are collated into the instanced shard; everything else (transparent glass, type-product geometry) goes to the flat MeshCollection. Each mesh takes exactly ONE route, so produce_batch runs once (no emit-both 2× meshing) and the renderer draws opaque occurrences via instancing instead of flat. Partition mirrors the renderer gates: INSTANCED_ALPHA_CUTOFF (0.99 = OPAQUE_ALPHA_CUTOFF) for transparency, geometry_class for the Model/Types split.
NOTE: the renderer must be instanced-feature-complete (picking / selection / lens overlays on instanced geometry) before the worker calls this in place of processGeometryBatch — otherwise those features break for the opaque bulk. See the instanced-only follow-ups.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn set_source_bytes(&self, data: Vec<u8>)
pub fn set_source_bytes(&self, data: Vec<u8>)
Store the whole IFC source file ONCE per load so the *FromSource batch
variants can read it from the wasm heap instead of re-copying it per call.
Mirrors the setEntityIndex lifecycle: called once per worker per load,
and REPLACES the previous file wholesale (repeated calls swap the bytes),
so a parser/geometry worker reusing one IfcAPI across loads is safe.
The bytes must be the exact source the batch jobs’ byte spans index into
(the same buffer passed as data to the legacy processGeometryBatch*),
or the decoded entities won’t match — the JS worker installs its own
session buffer, so this holds by construction.
Taking Vec<u8> (by value) means wasm-bindgen hands us ownership of the
single JS→wasm copy directly; we wrap it in Arc with no second copy.
Sourcepub fn process_geometry_batch_from_source(
&self,
jobs_flat: &[u32],
unit_scale: f64,
rtc_x: f64,
rtc_y: f64,
rtc_z: f64,
needs_shift: bool,
void_keys: &[u32],
void_counts: &[u32],
void_values: &[u32],
style_ids: &[u32],
style_colors: &[u8],
plane_angle_to_radians: Option<f64>,
material_element_ids: Option<Vec<u32>>,
material_color_counts: Option<Vec<u32>>,
material_colors_rgba: Option<Vec<u8>>,
) -> MeshCollection
pub fn process_geometry_batch_from_source( &self, jobs_flat: &[u32], unit_scale: f64, rtc_x: f64, rtc_y: f64, rtc_z: f64, needs_shift: bool, void_keys: &[u32], void_counts: &[u32], void_values: &[u32], style_ids: &[u32], style_colors: &[u8], plane_angle_to_radians: Option<f64>, material_element_ids: Option<Vec<u32>>, material_color_counts: Option<Vec<u32>>, material_colors_rgba: Option<Vec<u8>>, ) -> MeshCollection
Like IfcAPI::process_geometry_batch but reads the source bytes held by
IfcAPI::set_source_bytes instead of taking data. Byte-for-byte
identical output — it delegates to the legacy twin with the held slice.
Sourcepub fn process_geometry_batch_partitioned_from_source(
&self,
jobs_flat: &[u32],
unit_scale: f64,
rtc_x: f64,
rtc_y: f64,
rtc_z: f64,
needs_shift: bool,
void_keys: &[u32],
void_counts: &[u32],
void_values: &[u32],
style_ids: &[u32],
style_colors: &[u8],
plane_angle_to_radians: Option<f64>,
material_element_ids: Option<Vec<u32>>,
material_color_counts: Option<Vec<u32>>,
material_colors_rgba: Option<Vec<u8>>,
) -> PartitionedBatch
pub fn process_geometry_batch_partitioned_from_source( &self, jobs_flat: &[u32], unit_scale: f64, rtc_x: f64, rtc_y: f64, rtc_z: f64, needs_shift: bool, void_keys: &[u32], void_counts: &[u32], void_values: &[u32], style_ids: &[u32], style_colors: &[u8], plane_angle_to_radians: Option<f64>, material_element_ids: Option<Vec<u32>>, material_color_counts: Option<Vec<u32>>, material_colors_rgba: Option<Vec<u8>>, ) -> PartitionedBatch
Like IfcAPI::process_geometry_batch_partitioned but reads the source
bytes held by IfcAPI::set_source_bytes instead of taking data.
Byte-for-byte identical output — it delegates to the legacy twin.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn build_pre_pass_once(&self, data: &[u8]) -> JsValue
pub fn build_pre_pass_once(&self, data: &[u8]) -> JsValue
Run the pre-pass ONCE and return serialized results for worker distribution. Takes raw bytes (&u8) to avoid TextDecoder overhead.
Sourcepub fn build_pre_pass_streaming(
&self,
data: &[u8],
on_event: &Function,
chunk_size: u32,
disabled_type_names: Option<Vec<String>>,
skip_type_geometry: bool,
) -> Result<JsValue, JsValue>
pub fn build_pre_pass_streaming( &self, data: &[u8], on_event: &Function, chunk_size: u32, disabled_type_names: Option<Vec<String>>, skip_type_geometry: bool, ) -> Result<JsValue, JsValue>
Streaming pre-pass: emits geometry jobs in chunks via a JS callback instead of waiting for the full file scan to complete.
Single linear walk over the file:
- Builds the entity index incrementally from the same scan that collects geometry jobs (a separate index scan would double wall-clock).
- As soon as
IFCPROJECThas been seen, the unit scale and the first ~50 geometry jobs have been collected, resolvesunitScale+rtcOffsetand emits ametacallback so the JS host can spin up geometry process workers. - Emits
jobscallbacks everychunk_sizejobs (or fewer if the meta phase already buffered some). - Emits
completewith the total job count at end of scan.
On a 986 MB / 14 M-entity file this drops time-to-first-geometry from ~17 s (full pre-pass + worker spawn + first batch) to ~3 s (first 100 K bytes scanned + meta + first chunk).
The callback receives a single JsValue argument shaped as one of:
{ type: "meta", unitScale, rtcOffset: [x,y,z], needsShift, buildingRotation? }
{ type: "jobs", jobs: Uint32Array } // [id, start, end] triples
{ type: "complete", totalJobs }
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn build_pre_pass_streaming_sharded_owned_binding(
&self,
data: &[u8],
on_event: &Function,
chunk_size: u32,
disabled_type_names: Option<Vec<String>>,
skip_type_geometry: bool,
index_ids: Vec<u32>,
index_starts: Vec<u32>,
index_lengths: Vec<u32>,
index_classes: &[u8],
) -> Result<JsValue, JsValue>
pub fn build_pre_pass_streaming_sharded_owned_binding( &self, data: &[u8], on_event: &Function, chunk_size: u32, disabled_type_names: Option<Vec<String>>, skip_type_geometry: bool, index_ids: Vec<u32>, index_starts: Vec<u32>, index_lengths: Vec<u32>, index_classes: &[u8], ) -> Result<JsValue, JsValue>
Sharded pre-pass variant: same scan/discovery/jobs/columns pipeline as
buildPrePassStreaming, but
- the entity index is PREBUILT from the host’s stitched shard columns
(file order; see
scanEntityIndexShard) — the scan skips its inline index build, the meta RTC ladder resolves against the FULL index (no partial-ladder full-rescan detour), and the post-scanentity-indexevent is skipped (the host already delivered it), and - styles resolution is EXTERNAL: the styled-item spans are resolved as
shard slices on the geometry workers (
resolveStyledItemsShard); this call stashes the SUPPORT spans + plane-angle scale, and the follow-upfinalizePrepassStylesmerges + flattens into the exact styles payload the serial path emits. NOstylesevent is emitted here.
Sourcepub fn build_pre_pass_streaming_sharded_with_source_fingerprint_owned_binding(
&self,
data: &[u8],
on_event: &Function,
chunk_size: u32,
disabled_type_names: Option<Vec<String>>,
skip_type_geometry: bool,
index_ids: Vec<u32>,
index_starts: Vec<u32>,
index_lengths: Vec<u32>,
index_classes: &[u8],
) -> Result<JsValue, JsValue>
pub fn build_pre_pass_streaming_sharded_with_source_fingerprint_owned_binding( &self, data: &[u8], on_event: &Function, chunk_size: u32, disabled_type_names: Option<Vec<String>>, skip_type_geometry: bool, index_ids: Vec<u32>, index_starts: Vec<u32>, index_lengths: Vec<u32>, index_classes: &[u8], ) -> Result<JsValue, JsValue>
Existing sharded prepass plus an exact full-source key in complete.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn build_pre_pass_streaming_sharded(
&self,
data: &[u8],
on_event: &Function,
chunk_size: u32,
disabled_type_names: Option<Vec<String>>,
skip_type_geometry: bool,
index_ids: &[u32],
index_starts: &[u32],
index_lengths: &[u32],
index_classes: &[u8],
) -> Result<JsValue, JsValue>
pub fn build_pre_pass_streaming_sharded( &self, data: &[u8], on_event: &Function, chunk_size: u32, disabled_type_names: Option<Vec<String>>, skip_type_geometry: bool, index_ids: &[u32], index_starts: &[u32], index_lengths: &[u32], index_classes: &[u8], ) -> Result<JsValue, JsValue>
Borrowed public Rust contract. JS uses the owned binding above.
Sourcepub fn build_pre_pass_streaming_sharded_with_source_fingerprint(
&self,
data: &[u8],
on_event: &Function,
chunk_size: u32,
disabled_type_names: Option<Vec<String>>,
skip_type_geometry: bool,
index_ids: &[u32],
index_starts: &[u32],
index_lengths: &[u32],
index_classes: &[u8],
) -> Result<JsValue, JsValue>
pub fn build_pre_pass_streaming_sharded_with_source_fingerprint( &self, data: &[u8], on_event: &Function, chunk_size: u32, disabled_type_names: Option<Vec<String>>, skip_type_geometry: bool, index_ids: &[u32], index_starts: &[u32], index_lengths: &[u32], index_classes: &[u8], ) -> Result<JsValue, JsValue>
Borrowed public Rust contract, including full-source fingerprinting.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn scan_entity_index_shard(
&self,
data: &[u8],
range_start: u32,
range_end: u32,
) -> JsValue
pub fn scan_entity_index_shard( &self, data: &[u8], range_start: u32, range_end: u32, ) -> JsValue
SPIKE (sharded pre-pass): scan the entity index over a single byte range.
Each idle browser geometry worker calls this on its [range_start, range_end) shard; the main thread stitches the returned columns into the
full entity index (byte-identical to the single-threaded
build_entity_index) by binary-searching each shard for the previous
shard’s handoff. Delegates to
ifc_lite_processing::scan_shard_classified_with_refusals — a
separately-maintained loop over the same EntityScanner primitive as
scan_shard (the one the native build_entity_index_parallel fans across
cores), plus a per-record class column this sharded path also needs. The
two loops’ records/handoff are kept in parity by a dedicated test
(rust/processing/tests/issue_2053_shard_scan_parity.rs), not by
delegation — edit one without the other and that test catches the drift.
Byte offsets returned are GLOBAL (relative to file start), so shards
concatenate without rewriting. Returns a plain object:
{ ids: Uint32Array, starts: Uint32Array, lengths: Uint32Array, classes: Uint8Array, handoff: number, oversizedIdStarts: Uint32Array }
where classes is the parallel per-record prepass class byte
(PREPASS_CLASS_*: named code in the low bits plus the geometry-job /
type-candidate flags) the host filters on to rebuild pre-pass span
lists, and handoff is the global start of the first entity at/after
range_end (the next shard’s first real entity), or -1 at EOF.
oversizedIdStarts carries the global start byte of every record this
shard refused for an express id above u32::MAX (#3395). Offsets, not
a count, and deliberately NOT reported from here: a shard begins at an
arbitrary byte, so it can start inside a quoted value and refuse a
string literal shaped like #4294967297=IFCWALL( — text no file
declared. Reporting per shard would warn “skipped N records” on a file
that is fine. The host’s stitch keeps only the offsets at/after the
retained boundary it computed for this shard and reports once, which is
what makes the number attributable to a record the stitch retained
(#3430).
Sourcepub fn resolve_styled_items_shard(
&self,
data: &[u8],
spans: &[u32],
) -> Result<JsValue, JsValue>
pub fn resolve_styled_items_shard( &self, data: &[u8], spans: &[u32], ) -> Result<JsValue, JsValue>
Sharded pre-pass: resolve ONE contiguous (file-ordered) slice of the
styled-item span list on this worker, against the entity index installed
by setEntityIndex. Returns raw resolved maps as flat columns:
{ orphanIds, orphanColors (f32 rgba per id), geomIds, geomColors, geomFinishes }, where geomFinishes is the #5582 [metallic, roughness] pair per geomIds entry (NaN when unauthored), from
resolve_geometry_finishes over this slice.
The host merges shard results IN SHARD ORDER with first-wins per
geometry id, reproducing the serial resolver’s file-order precedence,
then hands the merged columns to finalizePrepassStyles.
spans is [id, start, len] triples.
Sourcepub fn finalize_prepass_styles(
&self,
data: &[u8],
orphan_ids: &[u32],
orphan_colors: &[f32],
geom_ids: &[u32],
geom_colors: &[f32],
colour_map_spans: &[u32],
material_def_spans: &[u32],
rel_material_spans: &[u32],
void_spans: &[u32],
fills_spans: &[u32],
aggregate_spans: &[u32],
plane_angle_to_radians: f64,
) -> Result<JsValue, JsValue>
pub fn finalize_prepass_styles( &self, data: &[u8], orphan_ids: &[u32], orphan_colors: &[f32], geom_ids: &[u32], geom_colors: &[f32], colour_map_spans: &[u32], material_def_spans: &[u32], rel_material_spans: &[u32], void_spans: &[u32], fills_spans: &[u32], aggregate_spans: &[u32], plane_angle_to_radians: f64, ) -> Result<JsValue, JsValue>
Sharded pre-pass: merge the shard-resolved styled-item columns with the
SUPPORT spans (extracted host-side from the shard classes) and run the
CANONICAL styles flatten. Returns the exact styles event payload the
serial path emits. Runs on any worker with setEntityIndex installed.
Span arguments are [id, start, len] triples; plane_angle_to_radians
comes from the meta event. orphanColors / geomColors carry exactly
four floats per id in orphanIds / geomIds; any other length throws
before either column is read. The payload’s styleFinishes come from
the geometry finishes a preceding setPrepassGeometryFinishes stashed
(consumed here); without that call they are all NaN.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn set_style_finishes(&self, style_ids: &[u32], style_finishes: &[f32])
pub fn set_style_finishes(&self, style_ids: &[u32], style_finishes: &[f32])
Install the prepass’s authored metallic/roughness per style (#5582):
styleFinishes carries two floats per styleIds entry,
[metallic, roughness], NaN for an unauthored field — the
styleFinishes array every prepass result carries beside styleColors.
Call it with the same styleIds later passed to processGeometryBatch*;
finishes set for a different style wire are ignored. Empty arrays clear
them. Malformed lengths never throw: a style without a complete pair
simply gets no finish.
The batch stamps each returned MeshDataJs (metallic / roughness)
from these, taking each mesh’s finish from the style its colour came
from (#5984). Occurrences that ride the instanced (IFNS) shard carry
theirs in the shard’s per-instance finish field (v3).
Sourcepub fn set_prepass_geometry_finishes(
&self,
geom_ids: &[u32],
geom_finishes: &[f32],
)
pub fn set_prepass_geometry_finishes( &self, geom_ids: &[u32], geom_finishes: &[f32], )
Sharded pre-pass (#5582): stash the shard-merged geometry finishes —
the geomFinishes columns resolveStyledItemsShard returns, merged
first-wins like geomColors — for the next finalizePrepassStyles /
finalizePrepassStylesFromSource call on this instance, which consumes
them and emits the aligned styleFinishes. Without this call that
finalize emits NaN finishes, as it always emitted colours only.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn scan_entity_index_shard_from_source(
&self,
start: u32,
end: u32,
) -> JsValue
pub fn scan_entity_index_shard_from_source( &self, start: u32, end: u32, ) -> JsValue
Scan a shard of the source installed by setSourceBytes.
Sourcepub fn resolve_styled_items_shard_from_source(
&self,
spans: &[u32],
) -> Result<JsValue, JsValue>
pub fn resolve_styled_items_shard_from_source( &self, spans: &[u32], ) -> Result<JsValue, JsValue>
Resolve styled-item spans against the installed source and entity index.
Sourcepub fn finalize_prepass_styles_from_source(
&self,
orphan_ids: &[u32],
orphan_colors: &[f32],
geom_ids: &[u32],
geom_colors: &[f32],
colour_map_spans: &[u32],
material_def_spans: &[u32],
rel_material_spans: &[u32],
void_spans: &[u32],
fills_spans: &[u32],
aggregate_spans: &[u32],
plane_angle_to_radians: f64,
) -> Result<JsValue, JsValue>
pub fn finalize_prepass_styles_from_source( &self, orphan_ids: &[u32], orphan_colors: &[f32], geom_ids: &[u32], geom_colors: &[f32], colour_map_spans: &[u32], material_def_spans: &[u32], rel_material_spans: &[u32], void_spans: &[u32], fills_spans: &[u32], aggregate_spans: &[u32], plane_angle_to_radians: f64, ) -> Result<JsValue, JsValue>
Finalize prepass styles against the installed source and entity index.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn parse_grid_lines(&self, content: String) -> Float32Array
pub fn parse_grid_lines(&self, content: String) -> Float32Array
Parse the file and return every IfcGridAxis as a flat Float32Array
of 3D line-list vertices [x0,y0,z0, x1,y1,z1, …] (one segment per
axis) in the renderer’s Y-up world space (RTC-subtracted, metres). Feed
straight to a line pipeline (e.g. renderer.setLineOverlay('grid', …)).
Returns an empty array when the file has no grids, so the caller can clear the overlay cheaply.
Sourcepub fn parse_grid_lines_in_frame(
&self,
content: String,
frame: JsValue,
) -> Result<Float32Array, JsValue>
pub fn parse_grid_lines_in_frame( &self, content: String, frame: JsValue, ) -> Result<Float32Array, JsValue>
Parse grid line vertices in the exact frame selected by the mesh pre-pass.
Sourcepub fn parse_grid_axes(&self, content: String) -> GridAxisCollection
pub fn parse_grid_axes(&self, content: String) -> GridAxisCollection
Parse the file and return structured per-axis data (tag + endpoints) in the renderer’s Y-up world space (RTC-subtracted, metres). Use this when you also need the axis tags (to render grid bubbles / labels).
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn parse_landxml_tin_bytes(
&self,
data: &[u8],
) -> Result<LandXmlTinDocumentJs, JsValue>
pub fn parse_landxml_tin_bytes( &self, data: &[u8], ) -> Result<LandXmlTinDocumentJs, JsValue>
Parse a supported LandXML TIN document from its original bytes.
The object is an owned serialization of the semantic document. Errors
deliberately use LandXmlError::Display, including its stable LXML code.
Sourcepub fn parse_landxml_source_bytes(
&self,
data: &[u8],
) -> Result<LandXmlSourceDocumentJs, JsValue>
pub fn parse_landxml_source_bytes( &self, data: &[u8], ) -> Result<LandXmlSourceDocumentJs, JsValue>
Parse all currently supported LandXML source families from the original bytes. Terrain-only and alignment-only sources both return an honest empty sibling collection, allowing the viewer’s single load path to handle either form and mixed documents uniformly.
Sourcepub fn parse_landxml_source_bytes_with_options(
&self,
data: &[u8],
options: JsValue,
) -> Result<LandXmlSourceDocumentJs, JsValue>
pub fn parse_landxml_source_bytes_with_options( &self, data: &[u8], options: JsValue, ) -> Result<LandXmlSourceDocumentJs, JsValue>
Parse a source with explicit hostile-input bounds. Passing
cancelled: true refuses before entering WASM; in-flight browser
cancellation is performed by terminating the worker that owns this
synchronous operation.
Sourcepub fn probe_landxml_alignment_at_distance(
&self,
data: &[u8],
alignment_source_id: &str,
distance: f64,
offset_right: f64,
) -> Result<LandXmlAlignmentProbeJs, JsValue>
pub fn probe_landxml_alignment_at_distance( &self, data: &[u8], alignment_source_id: &str, distance: f64, offset_right: f64, ) -> Result<LandXmlAlignmentProbeJs, JsValue>
Evaluate one supported horizontal-alignment source span at an exact f64 distance. The binding reuses the native validator, so malformed deserialized records, discontinuities, unresolved references, and unsupported transition domains are rejected rather than approximated.
Sourcepub fn probe_landxml_alignment_at_station(
&self,
data: &[u8],
alignment_source_id: &str,
station: f64,
offset_right: f64,
) -> Result<LandXmlAlignmentProbesJs, JsValue>
pub fn probe_landxml_alignment_at_station( &self, data: &[u8], alignment_source_id: &str, station: f64, offset_right: f64, ) -> Result<LandXmlAlignmentProbesJs, JsValue>
Evaluate a bounded set of physical locations carrying a displayed station label. A duplicate label is real, never collapsed; an excessive number is refused rather than allocated synchronously.
Sourcepub fn inspect_landxml_alignment_at_distance(
&self,
data: &[u8],
alignment_source_id: &str,
distance: f64,
) -> Result<LandXmlAlignmentInspectionJs, JsValue>
pub fn inspect_landxml_alignment_at_distance( &self, data: &[u8], alignment_source_id: &str, distance: f64, ) -> Result<LandXmlAlignmentInspectionJs, JsValue>
Inspect authored cant and superelevation records at a physical distance. Cant exposes bracketing source records only; no transition value is fabricated. Superelevation blocks preserve their authored bounds.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn create_landxml_tin_stream_session(
&self,
max_bytes: u32,
options: Option<LandXmlParseOptionsJs>,
) -> Result<LandXmlTinStreamSession, JsValue>
pub fn create_landxml_tin_stream_session( &self, max_bytes: u32, options: Option<LandXmlParseOptionsJs>, ) -> Result<LandXmlTinStreamSession, JsValue>
Starts one owned raw-byte LandXML session. The caller must free or abort the session on every cancellation path.
options is the same shape parseLandXmlSourceBytesWithOptions
accepts (see LandXmlParseOptionsJs) and is optional so every
existing single-argument call site keeps working unchanged. A bad
assumedLinearUnit token (or any other invalid option) refuses here,
at session construction, never partway through a stream (#5175).
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn scan_entities_fast(&self, content: &str) -> JsValue
pub fn scan_entities_fast(&self, content: &str) -> JsValue
Fast entity scanning using SIMD-accelerated Rust scanner Returns array of entity references for data model parsing Much faster than TypeScript byte-by-byte scanning (5-10x speedup)
The returned array also carries two own properties describing what the
scan refused (#7393): oversizedIdCount (records skipped because their
express id does not fit u32, #3395) and malformedRecordCount (0 or 1:
whether a record was dropped for having no terminating ;, #3695).
Sourcepub fn scan_entities_fast_bytes(&self, data: &[u8]) -> JsValue
pub fn scan_entities_fast_bytes(&self, data: &[u8]) -> JsValue
Fast entity scanning from raw bytes (avoids TextDecoder.decode on JS side). Accepts Uint8Array directly — saves ~2-5s for 487MB files by skipping JS string creation and UTF-16→UTF-8 conversion.
Carries the same oversizedIdCount / malformedRecordCount array
properties as scanEntitiesFast (#7393).
Sourcepub fn scan_geometry_entities_fast(&self, content: &str) -> JsValue
pub fn scan_geometry_entities_fast(&self, content: &str) -> JsValue
Fast geometry-only entity scanning Scans only entities that have geometry, skipping 99% of non-geometry entities Returns array of geometry entity references for parallel processing Much faster than scanning all entities (3x speedup for large files)
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn get_pipeline_diagnostics(&self) -> JsValue
pub fn get_pipeline_diagnostics(&self) -> JsValue
Structured pipeline diagnostics accumulated across every
processGeometryBatch* call since the last load reset
(clearPrePassCache / setEntityIndex), as a JS object with a
schemaVersion field — or undefined when no batch has run yet.
Includes per-batch summed geometry wall time, mesh/triangle counts,
the degenerate-backstop drop count, and the CSG failure aggregates.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn simplify_meshes(
&self,
express_ids: &[u32],
levels: &[u8],
positions: &[f32],
normals: &[f32],
indices: &[u32],
vertex_counts: &[u32],
index_counts: &[u32],
origins: &[f64],
local_to_world: &[f64],
local_to_world_present: &[u8],
rtc_x: f64,
rtc_y: f64,
rtc_z: f64,
unit_scale: f64,
y_up: bool,
) -> Result<SimplifiedMeshes, JsValue>
pub fn simplify_meshes( &self, express_ids: &[u32], levels: &[u8], positions: &[f32], normals: &[f32], indices: &[u32], vertex_counts: &[u32], index_counts: &[u32], origins: &[f64], local_to_world: &[f64], local_to_world_present: &[u8], rtc_x: f64, rtc_y: f64, rtc_z: f64, unit_scale: f64, y_up: bool, ) -> Result<SimplifiedMeshes, JsValue>
Simplify already-produced element meshes at per-element demesher levels (1-4 = cavity removal + clustering at 0.5/0.25/0.10/0.03 triangle ratio, 5 = bounding box).
One RECORD per input MeshData entry (an element may span several
records — per-material submeshes; pass all of them, grouped or not).
Per record i: vertexCounts[i] vertices from positions (and
normals when non-empty), indexCounts[i] indices from indices
(per-record local), origins[i*3..], localToWorld[i*16..] valid
only when localToWorldPresent[i] != 0, level levels[i] (records
of one element must agree). Arrays are the boundary Y-up convention
when yUp is true (the browser/SDK case).
rtcX/Y/Z = coordinateInfo.originShift (IFC Z-up metres);
unitScale = metres per project length unit.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn extract_swept_disk_descriptions(
&self,
content: &[u8],
ids: Option<Vec<u32>>,
) -> Result<JsValue, JsValue>
pub fn extract_swept_disk_descriptions( &self, content: &[u8], ids: Option<Vec<u32>>, ) -> Result<JsValue, JsValue>
Return authored swept-disk occurrences, including exact line/arc
directrices and derived measurements, in absolute IFC Z-up metres.
ids contains product STEP IDs; omit it for all products or pass an
empty Uint32Array for none. Unsupported records keep their status and
a null directrix_metrics; malformed representation walks report a
diagnostic and omit that product atomically.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn parse_symbolic_representations(
&self,
content: String,
) -> SymbolicRepresentationCollection
pub fn parse_symbolic_representations( &self, content: String, ) -> SymbolicRepresentationCollection
Parse IFC file and extract symbolic representations (Plan, Annotation, FootPrint, Axis). These are 2D curves used for architectural drawings instead of sectioning 3D geometry.
This standalone entry point detects an RTC frame from the whole source.
Use parseSymbolicRepresentationsInFrame when the symbols accompany
meshes produced by a streaming pre-pass or federation override.
Example:
const api = new IfcAPI();
const symbols = api.parseSymbolicRepresentations(ifcData);
console.log('Found', symbols.totalCount, 'symbolic items');
for (let i = 0; i < symbols.polylineCount; i++) {
const polyline = symbols.getPolyline(i);
console.log('Polyline for', polyline.ifcType, ':', polyline.points);
}Sourcepub fn parse_symbolic_representations_in_frame(
&self,
content: String,
frame: JsValue,
) -> Result<SymbolicRepresentationCollection, JsValue>
pub fn parse_symbolic_representations_in_frame( &self, content: String, frame: JsValue, ) -> Result<SymbolicRepresentationCollection, JsValue>
Parse symbolic representations in the exact RTC frame selected by the browser mesh pre-pass rather than detecting a second frame from the whole source.
Source§impl IfcAPI
impl IfcAPI
Sourcepub fn clear_pre_pass_cache(&self)
pub fn clear_pre_pass_cache(&self)
Clear the cached entity index (call between loads when reusing
the same IfcAPI instance — e.g. the parser worker keeps one
IfcAPI alive across multiple parse requests).
Recovers a poisoned cache Mutex instead of panicking; see mod_tests.rs.
Sourcepub fn set_referenced_repmaps(&self, ids: &[u32])
pub fn set_referenced_repmaps(&self, ids: &[u32])
Install the pre-computed set of IfcRepresentationMap ids referenced by
an IfcMappedItem (issue #957), so the worker’s first type-product batch
SKIPS the per-worker Self::get_or_build_referenced_repmaps full-file
walk. The streaming pre-pass built the same set once from the
IfcMappedItem spans it already scanned (see
styling::build_referenced_representation_maps_from_spans) and ships the
id list here — bit-identical to what each worker would compute, since a
set’s membership is order-invariant and consumers only call .contains.
Installed AFTER setEntityIndex (which clears this cache on content
swap), so the injected value survives. When this setter is never called
(native path, non-streaming callers), the lazy build path is unchanged.
Sourcepub fn set_instantiated_type_ids(&self, ids: &[u32])
pub fn set_instantiated_type_ids(&self, ids: &[u32])
Install the pre-computed set of type ids that an IfcRelDefinesByType
instantiates (#957 follow-up), so the worker’s first type-product batch
skips the per-worker Self::get_or_build_instantiated_type_ids
full-file walk. Same injection contract as Self::set_referenced_repmaps.
Sourcepub fn set_mapped_instance_plan(&self, source_ids: &[u32])
pub fn set_mapped_instance_plan(&self, source_ids: &[u32])
Install the pre-computed #1623 Phase 3 don’t-bake plan: the flat list of
IfcRepresentationMap ids that an IfcMappedItem instantiates >= 2 times.
The streaming pre-pass tallies it in the SAME scan that builds the referenced-
repmap set (styling::build_mapped_instance_plan_from_spans) and ships the id
list here. The batch path arms its router with it (batch-local template mode),
so a repeated single-solid mapped source materializes ONCE per batch and the
rest ride as instances in the IFNS shard.
Same injection contract as Self::set_referenced_repmaps: installed after
setEntityIndex (which clears it on content swap), and a no-op absence leaves
the batch path materializing every occurrence (byte-identical). Each id is
stored as (2, id) — the batch-local router only needs the eligibility set
(count >= 2); the min-id template slot is unused in batch-local mode.
Sourcepub fn set_material_layer_index(
&self,
element_ids: &[u32],
axis: &[u32],
layer_counts: &[u32],
direction_sense: &[f64],
offset: &[f64],
layer_material_ids: &[u32],
layer_thicknesses: &[f64],
)
pub fn set_material_layer_index( &self, element_ids: &[u32], axis: &[u32], layer_counts: &[u32], direction_sense: &[f64], offset: &[f64], layer_material_ids: &[u32], layer_thicknesses: &[f64], )
Install the pre-computed ifc_lite_geometry::MaterialLayerIndex (#563)
from its flat SoA encoding, so the worker’s first batch skips the
per-worker Self::get_or_build_material_layer_index full-file decode
scan (the dominant first-batch cost on layered architectural models,
which run this on the DEFAULT view). The streaming pre-pass built the
index once from the IfcRelAssociatesMaterial spans it already scanned
(MaterialLayerIndex::from_spans) and flat-encoded it here; the flat
encoding round-trips bit-for-bit (proven in material_layer_index tests),
so the injected index equals each worker’s from_content result.
Same injection contract as Self::set_referenced_repmaps: installed
after setEntityIndex, and a no-op absence leaves the lazy build intact.
Sourcepub fn get_memory(&self) -> JsValue
pub fn get_memory(&self) -> JsValue
Get WASM memory for zero-copy access
Sourcepub fn set_merge_layers(&self, enabled: bool)
pub fn set_merge_layers(&self, enabled: bool)
Toggle the “render multilayer walls as a single solid” mode (issue #540).
When enabled is true, every subsequent processGeometryBatch call
will suppress geometry emission for IfcBuildingElementPart entities
whose IfcRelAggregates parent wall is sliceable (has an
IfcMaterialLayerSetUsage) AND has its own Representation. The
parent wall keeps its per-layer sub-mesh colouring, so the visual
result is the same as the layered render but with one mesh per wall
instead of one per layer part — much cheaper for both CPU and GPU.
Default is false. Pass true before calling processGeometryBatch.
Sourcepub fn set_rect_param_fast_path(&self, enabled: bool)
pub fn set_rect_param_fast_path(&self, enabled: bool)
Enable or disable the PARAMETRIC rectangular-opening fast path (the
placement-frame, ground-truth-exact analytic cut) for processGeometryBatch.
DEFAULT ON (corpus-validated; native defaults ON too, and wasm has no env to
read IFC_LITE_RECT_PARAM, so both targets default in LOCKSTEP – the
byte-identical native==wasm contract requires both take the same path). This
toggle is the wasm-side escape hatch mirroring IFC_LITE_RECT_PARAM=0.
The path subtracts rectangular openings as exact parametric boxes in the host’s
own placement frame (rotated walls included), deferring any non-clean case to
the exact kernel. Pass false before processGeometryBatch to opt out.
Sourcepub fn set_compute_geometry_hashes(&self, tolerance: Option<f64>)
pub fn set_compute_geometry_hashes(&self, tolerance: Option<f64>)
Enable or disable per-entity geometry fingerprinting in
processGeometryBatch, used by the viewer’s revision-diff feature.
Pass a positive tolerance (metres) to enable — the quantization grid
positions snap to (larger tolerates more float noise, smaller catches
finer edits; below the f32 precision floor of model-local coordinates,
~1 mm, mostly hashes noise). Finer than
ifc_lite_geometry::MIN_GEOM_HASH_TOLERANCE (1e-6 m) is clamped up to it
— see that constant’s doc for why (an i128 overflow surface, not a
precision win). null/undefined/non-positive disables. Default: off.
Sourcepub fn set_tessellation_quality(
&self,
level: Option<String>,
) -> Result<(), JsValue>
pub fn set_tessellation_quality( &self, level: Option<String>, ) -> Result<(), JsValue>
Select the tessellation detail level applied by every subsequent
processGeometryBatch call (issue #976, step 4).
level is one of "lowest" | "low" | "medium" | "high" | "highest"
(case-insensitive). "medium" is the default and reproduces the
engine’s historical hardcoded densities byte-for-byte; lower levels
trade curved-surface smoothness for throughput, higher levels reduce
faceting on pipes / cylinders / NURBS at a triangle-count cost.
Pass null/undefined to reset to the default.
Set BEFORE processing — meshes already emitted are not regenerated. Throws on an unrecognized level so typos fail loudly instead of silently rendering at the wrong density.
Sourcepub fn set_skip_small_cuts(&self, on: bool)
pub fn set_skip_small_cuts(&self, on: bool)
Toggle the tier-independent small-cut skip (#1286). When true,
processGeometryBatch drops IfcBooleanResult differences whose cutter is
tiny relative to its host (steel copes/notches) while keeping the
tessellation tier — so curves stay full-density. The viewer enables this for
the on-screen load; exports/drawings leave it off so their geometry keeps
every cut. Default off ⇒ byte-identical to before.
Set BEFORE processing — meshes already emitted are not regenerated.
Trait Implementations§
Source§impl FromWasmAbi for IfcAPI
impl FromWasmAbi for IfcAPI
Source§impl IntoWasmAbi for IfcAPI
impl IntoWasmAbi for IfcAPI
Source§impl LongRefFromWasmAbi for IfcAPI
impl LongRefFromWasmAbi for IfcAPI
Source§impl OptionFromWasmAbi for IfcAPI
impl OptionFromWasmAbi for IfcAPI
Source§impl OptionIntoWasmAbi for IfcAPI
impl OptionIntoWasmAbi for IfcAPI
Source§impl RefFromWasmAbi for IfcAPI
impl RefFromWasmAbi for IfcAPI
Source§type Abi = WasmPtr<WasmRefCell<IfcAPI>>
type Abi = WasmPtr<WasmRefCell<IfcAPI>>
Self are recovered from.Source§impl RefMutFromWasmAbi for IfcAPI
impl RefMutFromWasmAbi for IfcAPI
Source§impl TryFromJsValue for IfcAPI
impl TryFromJsValue for IfcAPI
Source§impl VectorFromWasmAbi for IfcAPI
impl VectorFromWasmAbi for IfcAPI
Source§impl VectorIntoWasmAbi for IfcAPI
impl VectorIntoWasmAbi for IfcAPI
impl SupportsConstructor for IfcAPI
impl SupportsInstanceProperty for IfcAPI
impl SupportsStaticProperty for IfcAPI
Auto Trait Implementations§
impl !Freeze for IfcAPI
impl RefUnwindSafe for IfcAPI
impl Send for IfcAPI
impl Sync for IfcAPI
impl Unpin for IfcAPI
impl UnwindSafe for IfcAPI
Blanket Implementations§
§impl<U> As for U
impl<U> As for U
§fn as_<T>(self) -> Twhere
T: CastFrom<U>,
fn as_<T>(self) -> Twhere
T: CastFrom<U>,
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 moreSource§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
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
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 more§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> ReturnWasmAbi for Twhere
T: IntoWasmAbi,
impl<T> ReturnWasmAbi for Twhere
T: IntoWasmAbi,
Source§type Abi = <T as IntoWasmAbi>::Abi
type Abi = <T as IntoWasmAbi>::Abi
IntoWasmAbi::AbiSource§fn return_abi(self) -> <T as ReturnWasmAbi>::Abi
fn return_abi(self) -> <T as ReturnWasmAbi>::Abi
IntoWasmAbi::into_abi, except that it may throw and never
return in the case of Err.§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read more§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).§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.