@ifc-lite/parser 3.3.2 → 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,23 +1,41 @@
|
|
|
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;
|
|
23
41
|
/**
|
|
@@ -26,11 +44,10 @@ export declare class SpatialHierarchyBuilder {
|
|
|
26
44
|
* IfcBuildingStorey.ObjectPlacement (IfcLocalPlacement)
|
|
27
45
|
* -> RelativePlacement (IfcAxis2Placement3D)
|
|
28
46
|
* -> Location (IfcCartesianPoint).Coordinates[2]
|
|
29
|
-
* i.e. the storey's Z relative to its parent spatial container
|
|
30
|
-
* semantics of the Elevation attribute
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* undefined when the placement chain can't be resolved.
|
|
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.
|
|
34
51
|
*/
|
|
35
52
|
private extractPlacementElevation;
|
|
36
53
|
}
|
|
@@ -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,128 +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) {
|
|
128
|
+
if (typeEnum === IfcTypeEnum.IfcBuildingStorey && ctx.elevation) {
|
|
129
|
+
const { source, entityIndex, lengthUnitScale } = ctx.elevation;
|
|
123
130
|
let rawElevation = this.extractElevation(expressId, source, entityIndex);
|
|
124
131
|
if (rawElevation === undefined) {
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
// lifts correctly in Exploded mode instead of being dropped from the sort,
|
|
129
|
-
// which made the model look like it had a single floor (#1289).
|
|
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).
|
|
130
135
|
rawElevation = this.extractPlacementElevation(expressId, source, entityIndex);
|
|
131
136
|
}
|
|
132
137
|
if (rawElevation !== undefined) {
|
|
133
|
-
// Apply unit scale to convert to meters
|
|
134
138
|
elevation = rawElevation * lengthUnitScale;
|
|
135
|
-
storeyElevations.set(expressId, elevation);
|
|
139
|
+
ctx.storeyElevations.set(expressId, elevation);
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
|
-
//
|
|
142
|
+
// Direct contained elements via IfcRelContainedInSpatialStructure.
|
|
139
143
|
const rawContainedElements = relationships.getRelated(expressId, RelationshipType.ContainsElements, 'forward');
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
// A contained spatial element — an IfcSpace / IfcSpatialZone attached to a
|
|
147
|
-
// storey via IfcRelContainedInSpatialStructure, which is what Revit Family +
|
|
148
|
-
// Dynamo emit instead of IfcRelAggregates — is a tree NODE, not a contained
|
|
149
|
-
// product. Split it out here and promote it below; without this it was
|
|
150
|
-
// filtered out and vanished from the hierarchy (#1075). Unknown-typed
|
|
151
|
-
// 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).
|
|
152
150
|
const containedElements = [];
|
|
153
151
|
const containedSpatialChildren = [];
|
|
154
152
|
for (const id of rawContainedElements) {
|
|
155
|
-
const childType =
|
|
156
|
-
if (
|
|
153
|
+
const childType = entities.getTypeEnum(id);
|
|
154
|
+
if (isSpatialStructureType(childType) && childType !== IfcTypeEnum.IfcProject) {
|
|
157
155
|
containedSpatialChildren.push(id);
|
|
158
156
|
}
|
|
159
157
|
else {
|
|
160
158
|
containedElements.push(id);
|
|
161
159
|
}
|
|
162
160
|
}
|
|
163
|
-
//
|
|
164
|
-
// Actually, we want forward - what does this element aggregate?
|
|
161
|
+
// Forward IfcRelAggregates: what does this element aggregate?
|
|
165
162
|
const aggregatedChildren = relationships.getRelated(expressId, RelationshipType.Aggregates, 'forward');
|
|
166
163
|
// Spatial child nodes come from BOTH aggregation and containment. Dedupe so a
|
|
167
|
-
// space referenced by both relationships isn't built twice
|
|
168
|
-
// would otherwise reduce to a duplicate leaf node).
|
|
164
|
+
// space referenced by both relationships isn't built twice.
|
|
169
165
|
const childNodes = [];
|
|
170
166
|
const spatialChildIds = new Set();
|
|
171
167
|
const addSpatialChild = (childId) => {
|
|
172
168
|
if (spatialChildIds.has(childId))
|
|
173
169
|
return;
|
|
174
|
-
const childType =
|
|
170
|
+
const childType = entities.getTypeEnum(childId);
|
|
175
171
|
if (isSpatialStructureType(childType) && childType !== IfcTypeEnum.IfcProject) {
|
|
176
172
|
spatialChildIds.add(childId);
|
|
177
|
-
childNodes.push(this.buildNode(childId,
|
|
173
|
+
childNodes.push(this.buildNode(childId, ctx));
|
|
178
174
|
}
|
|
179
175
|
};
|
|
180
176
|
for (const childId of aggregatedChildren)
|
|
181
177
|
addSpatialChild(childId);
|
|
182
178
|
for (const childId of containedSpatialChildren)
|
|
183
179
|
addSpatialChild(childId);
|
|
184
|
-
//
|
|
180
|
+
// Roll contained elements up to the appropriate map.
|
|
185
181
|
if (isStoreyLikeSpatialType(typeEnum)) {
|
|
186
|
-
byStorey.set(expressId, containedElements);
|
|
182
|
+
ctx.byStorey.set(expressId, containedElements);
|
|
187
183
|
}
|
|
188
184
|
else if (isBuildingLikeSpatialType(typeEnum)) {
|
|
189
|
-
byBuilding.set(expressId, containedElements);
|
|
185
|
+
ctx.byBuilding.set(expressId, containedElements);
|
|
190
186
|
}
|
|
191
187
|
else if (typeEnum === IfcTypeEnum.IfcSite) {
|
|
192
|
-
bySite.set(expressId, containedElements);
|
|
188
|
+
ctx.bySite.set(expressId, containedElements);
|
|
193
189
|
}
|
|
194
190
|
else if (isSpaceLikeSpatialType(typeEnum)) {
|
|
195
191
|
// IfcSpace and IfcSpatialZone both roll up their contained elements here.
|
|
196
|
-
bySpace.set(expressId, containedElements);
|
|
192
|
+
ctx.bySpace.set(expressId, containedElements);
|
|
197
193
|
}
|
|
198
194
|
if (isStoreyLikeSpatialType(typeEnum)) {
|
|
199
195
|
for (const elementId of containedElements) {
|
|
200
|
-
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
|
+
}
|
|
201
217
|
}
|
|
202
|
-
// Map the storey's spatial children (IfcSpace / IfcSpatialZone) to it too,
|
|
203
|
-
//
|
|
204
|
-
//
|
|
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).
|
|
205
221
|
for (const childId of spatialChildIds) {
|
|
206
|
-
if (!elementToStorey.has(childId)) {
|
|
207
|
-
elementToStorey.set(childId, expressId);
|
|
222
|
+
if (!ctx.elementToStorey.has(childId)) {
|
|
223
|
+
ctx.elementToStorey.set(childId, expressId);
|
|
208
224
|
}
|
|
209
225
|
}
|
|
210
226
|
}
|
|
211
|
-
return {
|
|
212
|
-
expressId,
|
|
213
|
-
type: typeEnum,
|
|
214
|
-
name,
|
|
215
|
-
elevation,
|
|
216
|
-
children: childNodes,
|
|
217
|
-
elements: containedElements,
|
|
218
|
-
};
|
|
227
|
+
return { expressId, type: typeEnum, name, elevation, children: childNodes, elements: containedElements };
|
|
219
228
|
}
|
|
220
229
|
/**
|
|
221
|
-
* Extract elevation from IfcBuildingStorey
|
|
222
|
-
*
|
|
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).
|
|
223
234
|
*/
|
|
224
235
|
extractElevation(expressId, source, entityIndex) {
|
|
225
236
|
const ref = entityIndex.byId.get(expressId);
|
|
@@ -231,29 +242,25 @@ export class SpatialHierarchyBuilder {
|
|
|
231
242
|
if (!entity)
|
|
232
243
|
return undefined;
|
|
233
244
|
const attrs = entity.attributes || [];
|
|
234
|
-
//
|
|
245
|
+
// Number from a raw value or a typed value like ['IFCLENGTHMEASURE', 3.0].
|
|
235
246
|
const extractNumber = (val) => {
|
|
236
247
|
if (typeof val === 'number')
|
|
237
248
|
return val;
|
|
238
249
|
if (Array.isArray(val) && val.length === 2 && typeof val[1] === 'number') {
|
|
239
|
-
return val[1];
|
|
250
|
+
return val[1];
|
|
240
251
|
}
|
|
241
252
|
return undefined;
|
|
242
253
|
};
|
|
243
|
-
//
|
|
244
|
-
//
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
// fallback
|
|
248
|
-
// numbers (e.g. OwnerHistory #3628 -> 3628, or ObjectPlacement #7150) — as
|
|
249
|
-
// elevations, so a storey with a null Elevation got a garbage value instead
|
|
250
|
-
// of falling through to the ObjectPlacement-Z fallback below (#1289).
|
|
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).
|
|
251
259
|
if (attrs.length > 9) {
|
|
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,
|
|
@@ -268,11 +275,10 @@ export class SpatialHierarchyBuilder {
|
|
|
268
275
|
* IfcBuildingStorey.ObjectPlacement (IfcLocalPlacement)
|
|
269
276
|
* -> RelativePlacement (IfcAxis2Placement3D)
|
|
270
277
|
* -> Location (IfcCartesianPoint).Coordinates[2]
|
|
271
|
-
* i.e. the storey's Z relative to its parent spatial container
|
|
272
|
-
* semantics of the Elevation attribute
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
* undefined when the placement chain can't be resolved.
|
|
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.
|
|
276
282
|
*/
|
|
277
283
|
extractPlacementElevation(expressId, source, entityIndex) {
|
|
278
284
|
try {
|
|
@@ -287,12 +293,12 @@ export class SpatialHierarchyBuilder {
|
|
|
287
293
|
const placementId = readAttrs(expressId)?.[5];
|
|
288
294
|
if (typeof placementId !== 'number')
|
|
289
295
|
return undefined;
|
|
290
|
-
// IfcLocalPlacement(PlacementRelTo, RelativePlacement)
|
|
296
|
+
// IfcLocalPlacement(PlacementRelTo, RelativePlacement) - RelativePlacement
|
|
291
297
|
// (index 1) is the IfcAxis2Placement3D carrying this storey's own offset.
|
|
292
298
|
const axisId = readAttrs(placementId)?.[1];
|
|
293
299
|
if (typeof axisId !== 'number')
|
|
294
300
|
return undefined;
|
|
295
|
-
// IfcAxis2Placement3D(Location, Axis, RefDirection)
|
|
301
|
+
// IfcAxis2Placement3D(Location, Axis, RefDirection) - Location (index 0) is
|
|
296
302
|
// an IfcCartesianPoint.
|
|
297
303
|
const locationId = readAttrs(axisId)?.[0];
|
|
298
304
|
if (typeof locationId !== 'number')
|
|
@@ -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",
|
|
@@ -20,11 +20,11 @@
|
|
|
20
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",
|