@ifc-lite/parser 3.3.1 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,24 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Spatial hierarchy builder - builds project/building/storey tree
|
|
2
|
+
* Spatial hierarchy builder - builds the project/site/building/storey tree.
|
|
3
|
+
*
|
|
4
|
+
* Single source for spatial-hierarchy construction. There are two entry points
|
|
5
|
+
* over one shared `buildNode`:
|
|
6
|
+
* - `build(...)` fresh parse: extracts storey elevations from the source
|
|
7
|
+
* buffer. Throws if there is no IfcProject.
|
|
8
|
+
* - `buildFromCache` cache restore: no source buffer, so storey elevations
|
|
9
|
+
* stay empty. Returns undefined if there is no IfcProject.
|
|
10
|
+
* Both paths get the same cycle guard, aggregate-descendant storey mapping, and
|
|
11
|
+
* spatial-child promotion, so they cannot drift.
|
|
3
12
|
*/
|
|
4
13
|
import type { EntityTable, StringTable, RelationshipGraph, SpatialHierarchy } from '@ifc-lite/data';
|
|
5
14
|
import type { EntityRef } from './types.js';
|
|
6
15
|
export declare class SpatialHierarchyBuilder {
|
|
7
16
|
/**
|
|
8
|
-
*
|
|
17
|
+
* Fresh-parse build. Extracts storey elevations from the source buffer.
|
|
18
|
+
* Throws if no IfcProject is present.
|
|
9
19
|
*
|
|
10
|
-
* @param lengthUnitScale - Scale
|
|
20
|
+
* @param lengthUnitScale - Scale to convert IFC length values to meters (e.g. 0.001 for millimeters).
|
|
11
21
|
*/
|
|
12
|
-
build(entities: EntityTable, relationships: RelationshipGraph,
|
|
22
|
+
build(entities: EntityTable, relationships: RelationshipGraph, _strings: StringTable, source: Uint8Array, entityIndex: {
|
|
13
23
|
byId: {
|
|
14
24
|
get(expressId: number): EntityRef | undefined;
|
|
15
25
|
};
|
|
16
26
|
}, lengthUnitScale?: number): SpatialHierarchy;
|
|
27
|
+
/**
|
|
28
|
+
* Cache-restore build. No source buffer, so storey elevations stay empty
|
|
29
|
+
* (`getStoreyByElevation` returns null). Returns undefined if no IfcProject.
|
|
30
|
+
*/
|
|
31
|
+
buildFromCache(entities: EntityTable, relationships: RelationshipGraph): SpatialHierarchy | undefined;
|
|
32
|
+
private assemble;
|
|
17
33
|
private buildNode;
|
|
18
34
|
/**
|
|
19
|
-
* Extract elevation from IfcBuildingStorey
|
|
20
|
-
*
|
|
35
|
+
* Extract elevation from an IfcBuildingStorey. Elevation is attribute index 9
|
|
36
|
+
* in both IFC2x3 and IFC4 (GlobalId, OwnerHistory, Name, Description,
|
|
37
|
+
* ObjectType, ObjectPlacement, Representation, LongName, CompositionType,
|
|
38
|
+
* Elevation).
|
|
21
39
|
*/
|
|
22
40
|
private extractElevation;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a storey's elevation from its ObjectPlacement, used as a fallback when
|
|
43
|
+
* the Elevation attribute is null. Walks
|
|
44
|
+
* IfcBuildingStorey.ObjectPlacement (IfcLocalPlacement)
|
|
45
|
+
* -> RelativePlacement (IfcAxis2Placement3D)
|
|
46
|
+
* -> Location (IfcCartesianPoint).Coordinates[2]
|
|
47
|
+
* i.e. the storey's Z relative to its parent spatial container, which matches
|
|
48
|
+
* the semantics of the Elevation attribute and avoids folding in any site-level
|
|
49
|
+
* georeferencing Z. Returns the raw (unscaled) Z, or undefined when the chain
|
|
50
|
+
* can't be resolved.
|
|
51
|
+
*/
|
|
52
|
+
private extractPlacementElevation;
|
|
23
53
|
}
|
|
24
54
|
//# sourceMappingURL=spatial-hierarchy-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spatial-hierarchy-builder.d.ts","sourceRoot":"","sources":["../src/spatial-hierarchy-builder.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"spatial-hierarchy-builder.d.ts","sourceRoot":"","sources":["../src/spatial-hierarchy-builder.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAe,MAAM,gBAAgB,CAAC;AAUjH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA0B5C,qBAAa,uBAAuB;IAClC;;;;;OAKG;IACH,KAAK,CACH,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,iBAAiB,EAChC,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE;QAAE,IAAI,EAAE;YAAE,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAA;SAAE,CAAA;KAAE,EACxE,eAAe,GAAE,MAAY,GAC5B,gBAAgB;IAMnB;;;OAGG;IACH,cAAc,CACZ,QAAQ,EAAE,WAAW,EACrB,aAAa,EAAE,iBAAiB,GAC/B,gBAAgB,GAAG,SAAS;IAI/B,OAAO,CAAC,QAAQ;IAwGhB,OAAO,CAAC,SAAS;IAqHjB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IA2CxB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,yBAAyB;CA0ClC"}
|
|
@@ -6,54 +6,74 @@ import { EntityExtractor } from './entity-extractor.js';
|
|
|
6
6
|
const log = createLogger('SpatialHierarchy');
|
|
7
7
|
export class SpatialHierarchyBuilder {
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Fresh-parse build. Extracts storey elevations from the source buffer.
|
|
10
|
+
* Throws if no IfcProject is present.
|
|
10
11
|
*
|
|
11
|
-
* @param lengthUnitScale - Scale
|
|
12
|
+
* @param lengthUnitScale - Scale to convert IFC length values to meters (e.g. 0.001 for millimeters).
|
|
12
13
|
*/
|
|
13
|
-
build(entities, relationships,
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
build(entities, relationships, _strings, source, entityIndex, lengthUnitScale = 1.0) {
|
|
15
|
+
const hierarchy = this.assemble(entities, relationships, { source, entityIndex, lengthUnitScale }, true);
|
|
16
|
+
// assemble only returns undefined when throwOnNoProject is false.
|
|
17
|
+
return hierarchy;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Cache-restore build. No source buffer, so storey elevations stay empty
|
|
21
|
+
* (`getStoreyByElevation` returns null). Returns undefined if no IfcProject.
|
|
22
|
+
*/
|
|
23
|
+
buildFromCache(entities, relationships) {
|
|
24
|
+
return this.assemble(entities, relationships, undefined, false);
|
|
25
|
+
}
|
|
26
|
+
assemble(entities, relationships, elevation, throwOnNoProject) {
|
|
27
|
+
const ctx = {
|
|
28
|
+
entities,
|
|
29
|
+
relationships,
|
|
30
|
+
byStorey: new Map(),
|
|
31
|
+
byBuilding: new Map(),
|
|
32
|
+
bySite: new Map(),
|
|
33
|
+
bySpace: new Map(),
|
|
34
|
+
storeyElevations: new Map(),
|
|
35
|
+
elementToStorey: new Map(),
|
|
36
|
+
visited: new Set(),
|
|
37
|
+
elevation,
|
|
38
|
+
};
|
|
28
39
|
const projectIds = entities.getByType(IfcTypeEnum.IfcProject);
|
|
29
40
|
if (projectIds.length === 0) {
|
|
30
41
|
console.warn('[SpatialHierarchyBuilder] No IfcProject found in IFC file');
|
|
31
|
-
|
|
42
|
+
if (throwOnNoProject) {
|
|
43
|
+
throw new Error('No IfcProject found in IFC file');
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
32
46
|
}
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
const projectNode = this.buildNode(projectId, entities, relationships, strings, source, entityIndex, byStorey, byBuilding, bySite, bySpace, storeyElevations, elementToStorey, entityTypeMap, lengthUnitScale, new Set());
|
|
36
|
-
// Note: storeyHeights remains empty for client path - uses on-demand property extraction
|
|
37
|
-
// Validation: log warnings if maps are empty
|
|
38
|
-
if (byStorey.size === 0) {
|
|
47
|
+
const projectNode = this.buildNode(projectIds[0], ctx);
|
|
48
|
+
if (ctx.byStorey.size === 0) {
|
|
39
49
|
console.warn('[SpatialHierarchyBuilder] No storeys found in spatial hierarchy');
|
|
40
50
|
}
|
|
41
|
-
if (byBuilding.size === 0) {
|
|
51
|
+
if (ctx.byBuilding.size === 0) {
|
|
42
52
|
console.warn('[SpatialHierarchyBuilder] No buildings found in spatial hierarchy');
|
|
43
53
|
}
|
|
44
|
-
const
|
|
54
|
+
const { byStorey, byBuilding, bySite, bySpace, storeyElevations, elementToStorey } = ctx;
|
|
55
|
+
// Pre-build the element -> space lookup for O(1) getContainingSpace.
|
|
56
|
+
const elementToSpace = new Map();
|
|
57
|
+
for (const [spaceId, elementIds] of bySpace) {
|
|
58
|
+
for (const elementId of elementIds) {
|
|
59
|
+
elementToSpace.set(elementId, spaceId);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
45
63
|
project: projectNode,
|
|
46
64
|
byStorey,
|
|
47
65
|
byBuilding,
|
|
48
66
|
bySite,
|
|
49
67
|
bySpace,
|
|
50
68
|
storeyElevations,
|
|
51
|
-
storeyHeights
|
|
69
|
+
// storeyHeights stays empty: both paths use on-demand property extraction.
|
|
70
|
+
storeyHeights: new Map(),
|
|
52
71
|
elementToStorey,
|
|
53
72
|
getStoreyElements(storeyId) {
|
|
54
73
|
return byStorey.get(storeyId) ?? [];
|
|
55
74
|
},
|
|
56
75
|
getStoreyByElevation(z) {
|
|
76
|
+
// With an empty storeyElevations map (cache path) this returns null.
|
|
57
77
|
let closestStorey = null;
|
|
58
78
|
let closestDistance = Infinity;
|
|
59
79
|
for (const [storeyId, elevation] of storeyElevations) {
|
|
@@ -63,34 +83,26 @@ export class SpatialHierarchyBuilder {
|
|
|
63
83
|
closestStorey = storeyId;
|
|
64
84
|
}
|
|
65
85
|
}
|
|
66
|
-
// Only return if within reasonable distance (1 meter)
|
|
86
|
+
// Only return if within a reasonable distance (1 meter).
|
|
67
87
|
return closestDistance < 1.0 ? closestStorey : null;
|
|
68
88
|
},
|
|
69
89
|
getContainingSpace(elementId) {
|
|
70
|
-
|
|
71
|
-
for (const [spaceId, elementIds] of bySpace) {
|
|
72
|
-
if (elementIds.includes(elementId)) {
|
|
73
|
-
return spaceId;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return null;
|
|
90
|
+
return elementToSpace.get(elementId) ?? null;
|
|
77
91
|
},
|
|
78
92
|
getPath(elementId) {
|
|
79
93
|
const path = [];
|
|
80
|
-
// Build path from project to element
|
|
81
94
|
const findPath = (node, targetId) => {
|
|
82
95
|
path.push(node);
|
|
83
|
-
//
|
|
84
|
-
|
|
96
|
+
// Match the node itself (so a promoted space/zone resolves) or one of
|
|
97
|
+
// its contained elements.
|
|
98
|
+
if (node.expressId === targetId || node.elements.includes(targetId)) {
|
|
85
99
|
return true;
|
|
86
100
|
}
|
|
87
|
-
// Recursively search children
|
|
88
101
|
for (const child of node.children) {
|
|
89
102
|
if (findPath(child, targetId)) {
|
|
90
103
|
return true;
|
|
91
104
|
}
|
|
92
105
|
}
|
|
93
|
-
// Backtrack
|
|
94
106
|
path.pop();
|
|
95
107
|
return false;
|
|
96
108
|
};
|
|
@@ -98,120 +110,127 @@ export class SpatialHierarchyBuilder {
|
|
|
98
110
|
return path;
|
|
99
111
|
},
|
|
100
112
|
};
|
|
101
|
-
return hierarchy;
|
|
102
113
|
}
|
|
103
|
-
buildNode(expressId,
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
name,
|
|
114
|
-
elevation: undefined,
|
|
115
|
-
children: [],
|
|
116
|
-
elements: [],
|
|
117
|
-
};
|
|
114
|
+
buildNode(expressId, ctx) {
|
|
115
|
+
const { entities, relationships } = ctx;
|
|
116
|
+
const typeEnum = entities.getTypeEnum(expressId);
|
|
117
|
+
const name = entities.getName(expressId) || `Entity #${expressId}`;
|
|
118
|
+
// Guard against cyclic IfcRelAggregates chains (A aggregates B, B aggregates
|
|
119
|
+
// A), which would otherwise recurse unbounded and overflow the stack. A
|
|
120
|
+
// revisited node is returned as a leaf so the rest of the hierarchy still
|
|
121
|
+
// builds.
|
|
122
|
+
if (ctx.visited.has(expressId)) {
|
|
123
|
+
return { expressId, type: typeEnum, name, elevation: undefined, children: [], elements: [] };
|
|
118
124
|
}
|
|
119
|
-
visited.add(expressId);
|
|
120
|
-
//
|
|
125
|
+
ctx.visited.add(expressId);
|
|
126
|
+
// Storey elevation (fresh path only): apply unit scale to convert to meters.
|
|
121
127
|
let elevation;
|
|
122
|
-
if (typeEnum === IfcTypeEnum.IfcBuildingStorey) {
|
|
123
|
-
const
|
|
128
|
+
if (typeEnum === IfcTypeEnum.IfcBuildingStorey && ctx.elevation) {
|
|
129
|
+
const { source, entityIndex, lengthUnitScale } = ctx.elevation;
|
|
130
|
+
let rawElevation = this.extractElevation(expressId, source, entityIndex);
|
|
131
|
+
if (rawElevation === undefined) {
|
|
132
|
+
// Elevation is optional and frequently null (Revit / ArchiCAD). Fall back
|
|
133
|
+
// to the storey's Z from its ObjectPlacement so it still orders + lifts in
|
|
134
|
+
// Exploded mode instead of collapsing to a single floor (#1289).
|
|
135
|
+
rawElevation = this.extractPlacementElevation(expressId, source, entityIndex);
|
|
136
|
+
}
|
|
124
137
|
if (rawElevation !== undefined) {
|
|
125
|
-
// Apply unit scale to convert to meters
|
|
126
138
|
elevation = rawElevation * lengthUnitScale;
|
|
127
|
-
storeyElevations.set(expressId, elevation);
|
|
139
|
+
ctx.storeyElevations.set(expressId, elevation);
|
|
128
140
|
}
|
|
129
141
|
}
|
|
130
|
-
//
|
|
142
|
+
// Direct contained elements via IfcRelContainedInSpatialStructure.
|
|
131
143
|
const rawContainedElements = relationships.getRelated(expressId, RelationshipType.ContainsElements, 'forward');
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
138
|
-
// A contained spatial element — an IfcSpace / IfcSpatialZone attached to a
|
|
139
|
-
// storey via IfcRelContainedInSpatialStructure, which is what Revit Family +
|
|
140
|
-
// Dynamo emit instead of IfcRelAggregates — is a tree NODE, not a contained
|
|
141
|
-
// product. Split it out here and promote it below; without this it was
|
|
142
|
-
// filtered out and vanished from the hierarchy (#1075). Unknown-typed
|
|
143
|
-
// entities (not in the EntityTable, e.g. some IFC4x3 leaves) stay elements.
|
|
144
|
+
// Split contained refs into real (non-spatial) elements vs spatial-structure
|
|
145
|
+
// children. Unknown types stay elements (getTypeEnum returns Unknown for both
|
|
146
|
+
// missing and unrecognized entities, and isSpatialStructureType(Unknown) is
|
|
147
|
+
// false). A contained IfcSpace / IfcSpatialZone (what Revit Family + Dynamo
|
|
148
|
+
// emit instead of IfcRelAggregates) is a tree NODE, not a product: promote it
|
|
149
|
+
// below so it shows in the hierarchy instead of vanishing (#1075).
|
|
144
150
|
const containedElements = [];
|
|
145
151
|
const containedSpatialChildren = [];
|
|
146
152
|
for (const id of rawContainedElements) {
|
|
147
|
-
const childType =
|
|
148
|
-
if (
|
|
153
|
+
const childType = entities.getTypeEnum(id);
|
|
154
|
+
if (isSpatialStructureType(childType) && childType !== IfcTypeEnum.IfcProject) {
|
|
149
155
|
containedSpatialChildren.push(id);
|
|
150
156
|
}
|
|
151
157
|
else {
|
|
152
158
|
containedElements.push(id);
|
|
153
159
|
}
|
|
154
160
|
}
|
|
155
|
-
//
|
|
156
|
-
// Actually, we want forward - what does this element aggregate?
|
|
161
|
+
// Forward IfcRelAggregates: what does this element aggregate?
|
|
157
162
|
const aggregatedChildren = relationships.getRelated(expressId, RelationshipType.Aggregates, 'forward');
|
|
158
163
|
// Spatial child nodes come from BOTH aggregation and containment. Dedupe so a
|
|
159
|
-
// space referenced by both relationships isn't built twice
|
|
160
|
-
// would otherwise reduce to a duplicate leaf node).
|
|
164
|
+
// space referenced by both relationships isn't built twice.
|
|
161
165
|
const childNodes = [];
|
|
162
166
|
const spatialChildIds = new Set();
|
|
163
167
|
const addSpatialChild = (childId) => {
|
|
164
168
|
if (spatialChildIds.has(childId))
|
|
165
169
|
return;
|
|
166
|
-
const childType =
|
|
170
|
+
const childType = entities.getTypeEnum(childId);
|
|
167
171
|
if (isSpatialStructureType(childType) && childType !== IfcTypeEnum.IfcProject) {
|
|
168
172
|
spatialChildIds.add(childId);
|
|
169
|
-
childNodes.push(this.buildNode(childId,
|
|
173
|
+
childNodes.push(this.buildNode(childId, ctx));
|
|
170
174
|
}
|
|
171
175
|
};
|
|
172
176
|
for (const childId of aggregatedChildren)
|
|
173
177
|
addSpatialChild(childId);
|
|
174
178
|
for (const childId of containedSpatialChildren)
|
|
175
179
|
addSpatialChild(childId);
|
|
176
|
-
//
|
|
180
|
+
// Roll contained elements up to the appropriate map.
|
|
177
181
|
if (isStoreyLikeSpatialType(typeEnum)) {
|
|
178
|
-
byStorey.set(expressId, containedElements);
|
|
182
|
+
ctx.byStorey.set(expressId, containedElements);
|
|
179
183
|
}
|
|
180
184
|
else if (isBuildingLikeSpatialType(typeEnum)) {
|
|
181
|
-
byBuilding.set(expressId, containedElements);
|
|
185
|
+
ctx.byBuilding.set(expressId, containedElements);
|
|
182
186
|
}
|
|
183
187
|
else if (typeEnum === IfcTypeEnum.IfcSite) {
|
|
184
|
-
bySite.set(expressId, containedElements);
|
|
188
|
+
ctx.bySite.set(expressId, containedElements);
|
|
185
189
|
}
|
|
186
190
|
else if (isSpaceLikeSpatialType(typeEnum)) {
|
|
187
191
|
// IfcSpace and IfcSpatialZone both roll up their contained elements here.
|
|
188
|
-
bySpace.set(expressId, containedElements);
|
|
192
|
+
ctx.bySpace.set(expressId, containedElements);
|
|
189
193
|
}
|
|
190
194
|
if (isStoreyLikeSpatialType(typeEnum)) {
|
|
191
195
|
for (const elementId of containedElements) {
|
|
192
|
-
elementToStorey.set(elementId, expressId);
|
|
196
|
+
ctx.elementToStorey.set(elementId, expressId);
|
|
197
|
+
// Propagate the storey assignment to aggregated descendants (e.g. an
|
|
198
|
+
// IfcBuildingElementPart child of an IfcWall). Without this, parts have no
|
|
199
|
+
// reverse-lookup entry even though the renderer emits them as standalone
|
|
200
|
+
// meshes. Direct storey containment wins (only set if not already mapped);
|
|
201
|
+
// `seen` guards against aggregate cycles.
|
|
202
|
+
const stack = [elementId];
|
|
203
|
+
const seen = new Set([elementId]);
|
|
204
|
+
while (stack.length > 0) {
|
|
205
|
+
const current = stack.pop();
|
|
206
|
+
const aggregatedKids = relationships.getRelated(current, RelationshipType.Aggregates, 'forward');
|
|
207
|
+
for (const kid of aggregatedKids) {
|
|
208
|
+
if (seen.has(kid))
|
|
209
|
+
continue;
|
|
210
|
+
seen.add(kid);
|
|
211
|
+
if (!ctx.elementToStorey.has(kid)) {
|
|
212
|
+
ctx.elementToStorey.set(kid, expressId);
|
|
213
|
+
}
|
|
214
|
+
stack.push(kid);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
193
217
|
}
|
|
194
|
-
// Map the storey's spatial children (IfcSpace / IfcSpatialZone) to it too,
|
|
195
|
-
//
|
|
196
|
-
//
|
|
218
|
+
// Map the storey's spatial children (IfcSpace / IfcSpatialZone) to it too, so
|
|
219
|
+
// a selected space resolves "which storey it's on" - the space is a child
|
|
220
|
+
// node, not in containedElements (#1075).
|
|
197
221
|
for (const childId of spatialChildIds) {
|
|
198
|
-
if (!elementToStorey.has(childId)) {
|
|
199
|
-
elementToStorey.set(childId, expressId);
|
|
222
|
+
if (!ctx.elementToStorey.has(childId)) {
|
|
223
|
+
ctx.elementToStorey.set(childId, expressId);
|
|
200
224
|
}
|
|
201
225
|
}
|
|
202
226
|
}
|
|
203
|
-
return {
|
|
204
|
-
expressId,
|
|
205
|
-
type: typeEnum,
|
|
206
|
-
name,
|
|
207
|
-
elevation,
|
|
208
|
-
children: childNodes,
|
|
209
|
-
elements: containedElements,
|
|
210
|
-
};
|
|
227
|
+
return { expressId, type: typeEnum, name, elevation, children: childNodes, elements: containedElements };
|
|
211
228
|
}
|
|
212
229
|
/**
|
|
213
|
-
* Extract elevation from IfcBuildingStorey
|
|
214
|
-
*
|
|
230
|
+
* Extract elevation from an IfcBuildingStorey. Elevation is attribute index 9
|
|
231
|
+
* in both IFC2x3 and IFC4 (GlobalId, OwnerHistory, Name, Description,
|
|
232
|
+
* ObjectType, ObjectPlacement, Representation, LongName, CompositionType,
|
|
233
|
+
* Elevation).
|
|
215
234
|
*/
|
|
216
235
|
extractElevation(expressId, source, entityIndex) {
|
|
217
236
|
const ref = entityIndex.byId.get(expressId);
|
|
@@ -223,37 +242,25 @@ export class SpatialHierarchyBuilder {
|
|
|
223
242
|
if (!entity)
|
|
224
243
|
return undefined;
|
|
225
244
|
const attrs = entity.attributes || [];
|
|
226
|
-
//
|
|
245
|
+
// Number from a raw value or a typed value like ['IFCLENGTHMEASURE', 3.0].
|
|
227
246
|
const extractNumber = (val) => {
|
|
228
247
|
if (typeof val === 'number')
|
|
229
248
|
return val;
|
|
230
249
|
if (Array.isArray(val) && val.length === 2 && typeof val[1] === 'number') {
|
|
231
|
-
return val[1];
|
|
250
|
+
return val[1];
|
|
232
251
|
}
|
|
233
252
|
return undefined;
|
|
234
253
|
};
|
|
235
|
-
//
|
|
254
|
+
// Read ONLY slot 9: a previous "scan every attribute for a number < 10000"
|
|
255
|
+
// fallback wrongly treated reference attributes (parsed as bare express-id
|
|
256
|
+
// numbers, e.g. OwnerHistory #3628 -> 3628) as elevations, so a storey with
|
|
257
|
+
// a null Elevation got a garbage value instead of falling through to the
|
|
258
|
+
// ObjectPlacement-Z fallback below (#1289).
|
|
236
259
|
if (attrs.length > 9) {
|
|
237
|
-
|
|
238
|
-
if (elev !== undefined)
|
|
239
|
-
return elev;
|
|
240
|
-
}
|
|
241
|
-
// Try index 8 (in case of schema variations)
|
|
242
|
-
if (attrs.length > 8) {
|
|
243
|
-
const elev = extractNumber(attrs[8]);
|
|
244
|
-
if (elev !== undefined)
|
|
245
|
-
return elev;
|
|
246
|
-
}
|
|
247
|
-
// Fallback: search for first numeric value that looks like an elevation
|
|
248
|
-
for (let i = 0; i < attrs.length; i++) {
|
|
249
|
-
const elev = extractNumber(attrs[i]);
|
|
250
|
-
if (elev !== undefined && Math.abs(elev) < 10000) {
|
|
251
|
-
return elev;
|
|
252
|
-
}
|
|
260
|
+
return extractNumber(attrs[9]);
|
|
253
261
|
}
|
|
254
262
|
}
|
|
255
263
|
catch (error) {
|
|
256
|
-
// Elevation extraction is optional - log for debugging but don't fail
|
|
257
264
|
log.caught('Failed to extract elevation', error, {
|
|
258
265
|
operation: 'extractElevation',
|
|
259
266
|
entityId: expressId,
|
|
@@ -262,5 +269,54 @@ export class SpatialHierarchyBuilder {
|
|
|
262
269
|
}
|
|
263
270
|
return undefined;
|
|
264
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Resolve a storey's elevation from its ObjectPlacement, used as a fallback when
|
|
274
|
+
* the Elevation attribute is null. Walks
|
|
275
|
+
* IfcBuildingStorey.ObjectPlacement (IfcLocalPlacement)
|
|
276
|
+
* -> RelativePlacement (IfcAxis2Placement3D)
|
|
277
|
+
* -> Location (IfcCartesianPoint).Coordinates[2]
|
|
278
|
+
* i.e. the storey's Z relative to its parent spatial container, which matches
|
|
279
|
+
* the semantics of the Elevation attribute and avoids folding in any site-level
|
|
280
|
+
* georeferencing Z. Returns the raw (unscaled) Z, or undefined when the chain
|
|
281
|
+
* can't be resolved.
|
|
282
|
+
*/
|
|
283
|
+
extractPlacementElevation(expressId, source, entityIndex) {
|
|
284
|
+
try {
|
|
285
|
+
const extractor = new EntityExtractor(source);
|
|
286
|
+
const readAttrs = (id) => {
|
|
287
|
+
const ref = entityIndex.byId.get(id);
|
|
288
|
+
if (!ref)
|
|
289
|
+
return undefined;
|
|
290
|
+
return extractor.extractEntity(ref)?.attributes ?? undefined;
|
|
291
|
+
};
|
|
292
|
+
// IfcBuildingStorey.ObjectPlacement is attribute index 5.
|
|
293
|
+
const placementId = readAttrs(expressId)?.[5];
|
|
294
|
+
if (typeof placementId !== 'number')
|
|
295
|
+
return undefined;
|
|
296
|
+
// IfcLocalPlacement(PlacementRelTo, RelativePlacement) - RelativePlacement
|
|
297
|
+
// (index 1) is the IfcAxis2Placement3D carrying this storey's own offset.
|
|
298
|
+
const axisId = readAttrs(placementId)?.[1];
|
|
299
|
+
if (typeof axisId !== 'number')
|
|
300
|
+
return undefined;
|
|
301
|
+
// IfcAxis2Placement3D(Location, Axis, RefDirection) - Location (index 0) is
|
|
302
|
+
// an IfcCartesianPoint.
|
|
303
|
+
const locationId = readAttrs(axisId)?.[0];
|
|
304
|
+
if (typeof locationId !== 'number')
|
|
305
|
+
return undefined;
|
|
306
|
+
// IfcCartesianPoint.Coordinates (index 0) is a list [x, y, z].
|
|
307
|
+
const coords = readAttrs(locationId)?.[0];
|
|
308
|
+
if (Array.isArray(coords) && coords.length >= 3 && typeof coords[2] === 'number') {
|
|
309
|
+
return coords[2];
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
log.caught('Failed to extract placement elevation', error, {
|
|
314
|
+
operation: 'extractPlacementElevation',
|
|
315
|
+
entityId: expressId,
|
|
316
|
+
entityType: 'IfcBuildingStorey',
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
265
321
|
}
|
|
266
322
|
//# sourceMappingURL=spatial-hierarchy-builder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spatial-hierarchy-builder.js","sourceRoot":"","sources":["../src/spatial-hierarchy-builder.ts"],"names":[],"mappings":"AAAA;;+DAE+D;
|
|
1
|
+
{"version":3,"file":"spatial-hierarchy-builder.js","sourceRoot":"","sources":["../src/spatial-hierarchy-builder.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ifc-lite/parser",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "IFC/STEP parser for IFC-Lite",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@ifc-lite/data": "^2.
|
|
20
|
+
"@ifc-lite/data": "^2.2.0",
|
|
21
21
|
"@ifc-lite/encoding": "^1.14.7",
|
|
22
22
|
"@ifc-lite/ifcx": "^2.1.5",
|
|
23
|
-
"@ifc-lite/wasm": "^2.
|
|
23
|
+
"@ifc-lite/wasm": "^2.13.2"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"typescript": "^6.0.3",
|
|
27
|
-
"vitest": "^4.1.
|
|
27
|
+
"vitest": "^4.1.9"
|
|
28
28
|
},
|
|
29
29
|
"license": "MPL-2.0",
|
|
30
30
|
"author": "Louis True",
|