/** * Merged IFC STEP exporter * * Combines multiple IFC models into a single STEP file, similar to * IfcOpenShell's MergeProjects recipe. Handles ID remapping, spatial * structure unification, and infrastructure deduplication. */ import type { IfcDataStore } from '@ifc-lite/parser'; /** * A model to be included in the merge, with its data store and metadata. */ export interface MergeModelInput { /** Unique model identifier */ id: string; /** Display name */ name: string; /** Parsed IFC data store (must have source buffer) */ dataStore: IfcDataStore; } /** * Options for merged STEP export */ export interface MergeExportOptions { /** IFC schema version for the output file (any version, will convert if needed) */ schema: 'IFC2X3' | 'IFC4' | 'IFC4X3' | 'IFC5'; /** File description */ description?: string; /** Author name */ author?: string; /** Organization name */ organization?: string; /** Application name (defaults to 'ifc-lite') */ application?: string; /** Output filename */ filename?: string; /** * Strategy for merging the project hierarchy. * - 'keep-first': Keep the first model's IfcProject as the root */ projectStrategy?: 'keep-first'; /** Apply visibility filtering to each model before merging */ visibleOnly?: boolean; /** Hidden entity IDs per model (local expressIds) */ hiddenEntityIdsByModel?: Map>; /** Isolated entity IDs per model (null = no isolation) */ isolatedEntityIdsByModel?: Map | null>; /** Progress callback for async export */ onProgress?: (progress: ExportProgress) => void; } /** * Progress information during export */ export interface ExportProgress { /** Current phase of export */ phase: 'preparing' | 'entities' | 'assembling'; /** Progress 0-1 */ percent: number; /** Number of entities processed so far */ entitiesProcessed: number; /** Total entities to process */ entitiesTotal: number; /** Current model being processed (for merged export) */ currentModel?: string; } /** * Result of merged STEP export */ export interface MergeExportResult { /** STEP file content as bytes (avoids V8 string length limit for large files) */ content: Uint8Array; /** Statistics */ stats: { /** Number of models merged */ modelCount: number; /** Total entities in the output */ totalEntityCount: number; /** File size in bytes */ fileSize: number; }; } /** * Merges multiple IFC models into a single STEP file. * * Uses the same approach as IfcOpenShell's MergeProjects recipe, extended * with spatial hierarchy unification: * 1. First model's entities use their original IDs * 2. Subsequent models' IDs are offset to avoid collisions * 3. IfcProject is unified — all references remapped to the first model's project * 4. Spatial structure (Site, Building, Storey) is unified by name/elevation: * matching entities are remapped to the first model's equivalents so that * products from all models end up in the same unified tree * 5. Duplicate entities and shared infrastructure (units, contexts) are skipped */ export declare class MergedExporter { private models; constructor(models: MergeModelInput[]); export(options: MergeExportOptions): MergeExportResult; /** * Async export that yields to the event loop between entity chunks, * reporting progress via the onProgress callback. This keeps the UI * responsive during large merged exports. */ exportAsync(options: MergeExportOptions): Promise; /** * Remap all #ID references in a STEP entity line. * Applies offset to all IDs, then overrides with specific remappings. * * Only `#` tokens in code positions are rewritten; tokens inside * single-quoted STEP strings (e.g. a 'Room #205' Name or a 'http://x#42' * URL) are left untouched so string attribute values are not corrupted. */ private remapEntityText; /** * Find entity IDs of shared infrastructure types in a data store. * Returns a map of uppercase type name → array of expressIds. */ private findInfrastructureEntities; /** * Find entity IDs of a specific type in a data store. */ private findEntitiesByType; /** * Build lookup tables from the first model's spatial entities for * matching against subsequent models during merge. */ private buildSpatialLookup; /** * Match a subsequent model's spatial entities (Site, Building, Storey) * to the first model's equivalents. Matched entities are remapped and * their duplicate entity is skipped from output. * * Matching strategy: * - Sites/Buildings: by name (case-insensitive), or if only one in each model * - Storeys: by name first, then by elevation (tolerance ±0.5 model units) */ private unifySpatialEntities; /** * Skip IfcRelAggregates that become fully redundant after spatial unification. * * When Model2's `IfcRelAggregates(Project, (Site))` gets remapped to * `IfcRelAggregates(FirstProject, (FirstSite))`, it duplicates Model1's * existing relationship, causing viewers to show Site multiple times. * * An IfcRelAggregates is redundant if both its RelatingObject (attr 4) * and ALL its RelatedObjects (attr 5) were remapped via sharedRemap. */ private skipRedundantRelAggregates; /** * Extract the Name attribute (index 2) from a STEP entity. */ private extractEntityName; /** * Extract the Elevation attribute (index 9) from an IfcBuildingStorey. */ private extractStoreyElevation; /** * Extract a specific attribute (by 0-based index) from a STEP entity's * raw text. Returns the raw string value (e.g., "'Name'", "$", "#123"). */ private extractStepAttribute; } //# sourceMappingURL=merged-exporter.d.ts.map