@ifc-lite/create 1.14.5 → 1.15.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.
- package/dist/ifc-creator-math.d.ts +23 -0
- package/dist/ifc-creator-math.d.ts.map +1 -0
- package/dist/ifc-creator-math.js +50 -0
- package/dist/ifc-creator-math.js.map +1 -0
- package/dist/ifc-creator.d.ts +63 -1
- package/dist/ifc-creator.d.ts.map +1 -1
- package/dist/ifc-creator.js +221 -40
- package/dist/ifc-creator.js.map +1 -1
- package/dist/in-store/_emit-helpers.d.ts +52 -0
- package/dist/in-store/_emit-helpers.d.ts.map +1 -0
- package/dist/in-store/_emit-helpers.js +147 -0
- package/dist/in-store/_emit-helpers.js.map +1 -0
- package/dist/in-store/anchor.d.ts +27 -0
- package/dist/in-store/anchor.d.ts.map +1 -0
- package/dist/in-store/anchor.js +5 -0
- package/dist/in-store/anchor.js.map +1 -0
- package/dist/in-store/auto-space-detect.d.ts +68 -0
- package/dist/in-store/auto-space-detect.d.ts.map +1 -0
- package/dist/in-store/auto-space-detect.js +353 -0
- package/dist/in-store/auto-space-detect.js.map +1 -0
- package/dist/in-store/beam.d.ts +25 -0
- package/dist/in-store/beam.d.ts.map +1 -0
- package/dist/in-store/beam.js +119 -0
- package/dist/in-store/beam.js.map +1 -0
- package/dist/in-store/column.d.ts +42 -0
- package/dist/in-store/column.d.ts.map +1 -0
- package/dist/in-store/column.js +108 -0
- package/dist/in-store/column.js.map +1 -0
- package/dist/in-store/door.d.ts +44 -0
- package/dist/in-store/door.d.ts.map +1 -0
- package/dist/in-store/door.js +68 -0
- package/dist/in-store/door.js.map +1 -0
- package/dist/in-store/duplicate.d.ts +100 -0
- package/dist/in-store/duplicate.d.ts.map +1 -0
- package/dist/in-store/duplicate.js +122 -0
- package/dist/in-store/duplicate.js.map +1 -0
- package/dist/in-store/extract-walls.d.ts +80 -0
- package/dist/in-store/extract-walls.d.ts.map +1 -0
- package/dist/in-store/extract-walls.js +529 -0
- package/dist/in-store/extract-walls.js.map +1 -0
- package/dist/in-store/generate-spaces.d.ts +71 -0
- package/dist/in-store/generate-spaces.d.ts.map +1 -0
- package/dist/in-store/generate-spaces.js +76 -0
- package/dist/in-store/generate-spaces.js.map +1 -0
- package/dist/in-store/member.d.ts +32 -0
- package/dist/in-store/member.d.ts.map +1 -0
- package/dist/in-store/member.js +35 -0
- package/dist/in-store/member.js.map +1 -0
- package/dist/in-store/plate.d.ts +43 -0
- package/dist/in-store/plate.d.ts.map +1 -0
- package/dist/in-store/plate.js +33 -0
- package/dist/in-store/plate.js.map +1 -0
- package/dist/in-store/resolve-anchor.d.ts +12 -0
- package/dist/in-store/resolve-anchor.d.ts.map +1 -0
- package/dist/in-store/resolve-anchor.js +89 -0
- package/dist/in-store/resolve-anchor.js.map +1 -0
- package/dist/in-store/resolve-source.d.ts +19 -0
- package/dist/in-store/resolve-source.d.ts.map +1 -0
- package/dist/in-store/resolve-source.js +203 -0
- package/dist/in-store/resolve-source.js.map +1 -0
- package/dist/in-store/roof.d.ts +43 -0
- package/dist/in-store/roof.d.ts.map +1 -0
- package/dist/in-store/roof.js +33 -0
- package/dist/in-store/roof.js.map +1 -0
- package/dist/in-store/slab.d.ts +44 -0
- package/dist/in-store/slab.d.ts.map +1 -0
- package/dist/in-store/slab.js +142 -0
- package/dist/in-store/slab.js.map +1 -0
- package/dist/in-store/space.d.ts +43 -0
- package/dist/in-store/space.d.ts.map +1 -0
- package/dist/in-store/space.js +71 -0
- package/dist/in-store/space.js.map +1 -0
- package/dist/in-store/wall.d.ts +27 -0
- package/dist/in-store/wall.d.ts.map +1 -0
- package/dist/in-store/wall.js +119 -0
- package/dist/in-store/wall.js.map +1 -0
- package/dist/in-store/window.d.ts +36 -0
- package/dist/in-store/window.d.ts.map +1 -0
- package/dist/in-store/window.js +57 -0
- package/dist/in-store/window.js.map +1 -0
- package/dist/index.d.ts +18 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +96 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* Pull every wall axis on a given storey from a parsed `IfcDataStore`
|
|
6
|
+
* plus an optional overlay (`MutablePropertyView`-style new-entities
|
|
7
|
+
* map). The resulting 2D segments feed `detectEnclosedAreas`.
|
|
8
|
+
*
|
|
9
|
+
* Two extraction strategies, tried in order:
|
|
10
|
+
*
|
|
11
|
+
* 1. **Axis representation** (preferred).
|
|
12
|
+
* `IfcShapeRepresentation` with `RepresentationIdentifier = 'Axis'`
|
|
13
|
+
* is the standard way authoring tools (Revit, ArchiCAD, etc.) ship
|
|
14
|
+
* a wall's centreline. Items are usually `IfcPolyline` (2 points →
|
|
15
|
+
* start, end) or `IfcTrimmedCurve` (treated as polyline endpoints).
|
|
16
|
+
* The endpoints are read in storey-local space, walked through the
|
|
17
|
+
* placement chain, and projected to the storey-floor plane.
|
|
18
|
+
*
|
|
19
|
+
* 2. **Body fallback — placement + IfcRectangleProfileDef.XDim**.
|
|
20
|
+
* Matches the convention emitted by `addWallToStore` /
|
|
21
|
+
* `IfcCreator.addIfcWall`: placement origin = wall Start,
|
|
22
|
+
* RefDirection = wall axis, profile XDim = wall length. Used for
|
|
23
|
+
* walls authored by the Add Element tool or anything else that
|
|
24
|
+
* mirrors that shape.
|
|
25
|
+
*
|
|
26
|
+
* Walls that match neither shape are skipped with a recorded reason —
|
|
27
|
+
* `WallExtractionResult.skipped[]` carries `{ wallId, reason }` so
|
|
28
|
+
* callers (and the viewer's Auto Spaces UI) can surface why a wall
|
|
29
|
+
* didn't contribute to the planar graph.
|
|
30
|
+
*/
|
|
31
|
+
import { EntityExtractor, extractLengthUnitScale, } from '@ifc-lite/parser';
|
|
32
|
+
/**
|
|
33
|
+
* Element types treated as "wall-like" dividers by default. Extends
|
|
34
|
+
* the obvious walls with curtain walls (often the only divider on a
|
|
35
|
+
* storey full of glazing), virtual walls (used by IFC exports for
|
|
36
|
+
* hypothetical room boundaries), and plates / members (used as
|
|
37
|
+
* partition panels in some pre-fab workflows). Callers can extend
|
|
38
|
+
* via `options.extraDividerTypes` for vendor-specific cases.
|
|
39
|
+
*/
|
|
40
|
+
const DEFAULT_DIVIDER_TYPES = new Set([
|
|
41
|
+
'ifcwall',
|
|
42
|
+
'ifcwallstandardcase',
|
|
43
|
+
'ifcwallelementedcase',
|
|
44
|
+
'ifccurtainwall',
|
|
45
|
+
'ifcvirtualelement',
|
|
46
|
+
'ifcplate',
|
|
47
|
+
'ifcmember',
|
|
48
|
+
'ifcrailing',
|
|
49
|
+
]);
|
|
50
|
+
const AXIS_EPS = 1e-6;
|
|
51
|
+
export function extractWallSegmentsForStorey(store, storeyExpressId, overlay, options = {}) {
|
|
52
|
+
const segments = [];
|
|
53
|
+
const contributing = [];
|
|
54
|
+
const skipped = [];
|
|
55
|
+
const debug = !!options.debug;
|
|
56
|
+
const log = debug ? (...args) => console.debug('[extract-walls]', ...args) : () => { };
|
|
57
|
+
// Resolve the model's length unit so the segments we hand to the
|
|
58
|
+
// detector are always in METRES — without this a millimetre model
|
|
59
|
+
// would produce coords like (31614, 23345) and the panel's
|
|
60
|
+
// metre-based snap tolerance would be effectively zero.
|
|
61
|
+
let lengthUnitScale = 1.0;
|
|
62
|
+
if (store.source) {
|
|
63
|
+
try {
|
|
64
|
+
lengthUnitScale = extractLengthUnitScale(store.source, store.entityIndex);
|
|
65
|
+
if (!Number.isFinite(lengthUnitScale) || lengthUnitScale <= 0)
|
|
66
|
+
lengthUnitScale = 1.0;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
lengthUnitScale = 1.0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
log(`length unit scale = ${lengthUnitScale} (raw → metres)`);
|
|
73
|
+
if (!store.source) {
|
|
74
|
+
log('no source bytes on data store — extraction cannot run');
|
|
75
|
+
return { segments, contributingWallIds: contributing, skipped, considered: 0, lengthUnitScale };
|
|
76
|
+
}
|
|
77
|
+
const dividerTypes = new Set(DEFAULT_DIVIDER_TYPES);
|
|
78
|
+
if (options.extraDividerTypes) {
|
|
79
|
+
for (const t of options.extraDividerTypes)
|
|
80
|
+
dividerTypes.add(t.toLowerCase());
|
|
81
|
+
}
|
|
82
|
+
const extractor = new EntityExtractor(store.source);
|
|
83
|
+
const dividerIds = collectDividerIdsOnStorey(store, storeyExpressId, dividerTypes, log);
|
|
84
|
+
log(`storey #${storeyExpressId}: ${dividerIds.length} contained divider element(s)`);
|
|
85
|
+
for (const id of dividerIds) {
|
|
86
|
+
const result = extractWallAxisFromSource(store, extractor, id, log);
|
|
87
|
+
if (result.segment) {
|
|
88
|
+
segments.push(scaleSegment(result.segment, lengthUnitScale));
|
|
89
|
+
contributing.push(id);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
skipped.push({ wallId: id, reason: result.reason ?? 'no-axis-or-rect-profile' });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
let overlayCount = 0;
|
|
96
|
+
if (overlay) {
|
|
97
|
+
for (const ent of overlay.getNewEntities()) {
|
|
98
|
+
if (!dividerTypes.has(ent.type.toLowerCase()))
|
|
99
|
+
continue;
|
|
100
|
+
overlayCount++;
|
|
101
|
+
const result = extractWallAxisFromOverlay(store, extractor, overlay, ent, log);
|
|
102
|
+
if (result.segment) {
|
|
103
|
+
// Overlay walls are authored via addWallToStore which emits
|
|
104
|
+
// metre coords — don't double-scale.
|
|
105
|
+
segments.push(result.segment);
|
|
106
|
+
contributing.push(ent.expressId);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
skipped.push({ wallId: ent.expressId, reason: result.reason ?? 'no-axis-or-rect-profile' });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (overlayCount > 0)
|
|
113
|
+
log(`overlay walls considered: ${overlayCount}`);
|
|
114
|
+
}
|
|
115
|
+
if (debug) {
|
|
116
|
+
log(`segments=${segments.length} contributing=${contributing.length} skipped=${skipped.length}`);
|
|
117
|
+
if (skipped.length > 0) {
|
|
118
|
+
const reasonCounts = skipped.reduce((acc, s) => {
|
|
119
|
+
acc[s.reason] = (acc[s.reason] ?? 0) + 1;
|
|
120
|
+
return acc;
|
|
121
|
+
}, {});
|
|
122
|
+
log('skip reasons:', reasonCounts);
|
|
123
|
+
log('first few skipped:', skipped.slice(0, 8));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
segments,
|
|
128
|
+
contributingWallIds: contributing,
|
|
129
|
+
skipped,
|
|
130
|
+
considered: dividerIds.length + overlayCount,
|
|
131
|
+
lengthUnitScale,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function scaleSegment(seg, scale) {
|
|
135
|
+
if (scale === 1)
|
|
136
|
+
return seg;
|
|
137
|
+
return {
|
|
138
|
+
a: [seg.a[0] * scale, seg.a[1] * scale],
|
|
139
|
+
b: [seg.b[0] * scale, seg.b[1] * scale],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function isDividerType(type, dividerTypes) {
|
|
143
|
+
return dividerTypes.has(type.toLowerCase());
|
|
144
|
+
}
|
|
145
|
+
function collectDividerIdsOnStorey(store, storeyId, dividerTypes, log) {
|
|
146
|
+
const ids = [];
|
|
147
|
+
const seen = new Set();
|
|
148
|
+
if (!store.source)
|
|
149
|
+
return ids;
|
|
150
|
+
const extractor = new EntityExtractor(store.source);
|
|
151
|
+
const visitMember = (memberId) => {
|
|
152
|
+
if (seen.has(memberId))
|
|
153
|
+
return;
|
|
154
|
+
const memberType = store.entities.getTypeName(memberId);
|
|
155
|
+
if (memberType && isDividerType(memberType, dividerTypes)) {
|
|
156
|
+
seen.add(memberId);
|
|
157
|
+
ids.push(memberId);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// Member is a sub-structure (IfcSpace, IfcBuildingPart, …);
|
|
161
|
+
// descend through its IfcRelAggregates / contained children too.
|
|
162
|
+
descendAggregate(memberId);
|
|
163
|
+
};
|
|
164
|
+
const descendAggregate = (parentId) => {
|
|
165
|
+
// Avoid revisiting parents we've already walked (cycles are
|
|
166
|
+
// theoretically possible in malformed IFC).
|
|
167
|
+
if (seen.has(parentId))
|
|
168
|
+
return;
|
|
169
|
+
seen.add(parentId);
|
|
170
|
+
// Anything `IfcRelContainedInSpatialStructure`-anchored to this
|
|
171
|
+
// sub-structure should still be reachable.
|
|
172
|
+
walkContainmentInto(parentId);
|
|
173
|
+
// And recurse through aggregation.
|
|
174
|
+
const aggRels = store.entityIndex.byType.get('IFCRELAGGREGATES') ?? [];
|
|
175
|
+
for (const relId of aggRels) {
|
|
176
|
+
const ref = store.entityIndex.byId.get(relId);
|
|
177
|
+
if (!ref)
|
|
178
|
+
continue;
|
|
179
|
+
const rel = extractor.extractEntity(ref);
|
|
180
|
+
if (!rel)
|
|
181
|
+
continue;
|
|
182
|
+
const relating = rel.attributes[4];
|
|
183
|
+
if (typeof relating !== 'number' || relating !== parentId)
|
|
184
|
+
continue;
|
|
185
|
+
const related = rel.attributes[5];
|
|
186
|
+
if (!Array.isArray(related))
|
|
187
|
+
continue;
|
|
188
|
+
for (const child of related) {
|
|
189
|
+
if (typeof child !== 'number')
|
|
190
|
+
continue;
|
|
191
|
+
visitMember(child);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
const walkContainmentInto = (parentId) => {
|
|
196
|
+
const containedRels = store.entityIndex.byType.get('IFCRELCONTAINEDINSPATIALSTRUCTURE') ?? [];
|
|
197
|
+
for (const relId of containedRels) {
|
|
198
|
+
const ref = store.entityIndex.byId.get(relId);
|
|
199
|
+
if (!ref)
|
|
200
|
+
continue;
|
|
201
|
+
const rel = extractor.extractEntity(ref);
|
|
202
|
+
if (!rel)
|
|
203
|
+
continue;
|
|
204
|
+
const relating = rel.attributes[5];
|
|
205
|
+
if (typeof relating !== 'number' || relating !== parentId)
|
|
206
|
+
continue;
|
|
207
|
+
const related = rel.attributes[4];
|
|
208
|
+
if (!Array.isArray(related))
|
|
209
|
+
continue;
|
|
210
|
+
for (const member of related) {
|
|
211
|
+
if (typeof member !== 'number')
|
|
212
|
+
continue;
|
|
213
|
+
visitMember(member);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
// Mark the storey itself as seen but DON'T push it (we want its
|
|
218
|
+
// children, not the storey id).
|
|
219
|
+
seen.add(storeyId);
|
|
220
|
+
walkContainmentInto(storeyId);
|
|
221
|
+
// Some authoring tools attach elements via IfcRelAggregates to the
|
|
222
|
+
// storey instead of containment (or in addition). Walk both
|
|
223
|
+
// unconditionally to keep coverage broad.
|
|
224
|
+
const aggRels = store.entityIndex.byType.get('IFCRELAGGREGATES') ?? [];
|
|
225
|
+
for (const relId of aggRels) {
|
|
226
|
+
const ref = store.entityIndex.byId.get(relId);
|
|
227
|
+
if (!ref)
|
|
228
|
+
continue;
|
|
229
|
+
const rel = extractor.extractEntity(ref);
|
|
230
|
+
if (!rel)
|
|
231
|
+
continue;
|
|
232
|
+
const relating = rel.attributes[4];
|
|
233
|
+
if (typeof relating !== 'number' || relating !== storeyId)
|
|
234
|
+
continue;
|
|
235
|
+
const related = rel.attributes[5];
|
|
236
|
+
if (!Array.isArray(related))
|
|
237
|
+
continue;
|
|
238
|
+
for (const child of related) {
|
|
239
|
+
if (typeof child !== 'number')
|
|
240
|
+
continue;
|
|
241
|
+
visitMember(child);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
log(`collected ${ids.length} divider candidate(s) — types: ${[...dividerTypes].join(', ')}`);
|
|
245
|
+
return ids;
|
|
246
|
+
}
|
|
247
|
+
function extractWallAxisFromSource(store, extractor, wallId, log) {
|
|
248
|
+
const ref = store.entityIndex.byId.get(wallId);
|
|
249
|
+
if (!ref) {
|
|
250
|
+
log(`wall #${wallId}: missing entity ref`);
|
|
251
|
+
return { segment: null, reason: 'no-source-bytes' };
|
|
252
|
+
}
|
|
253
|
+
const wall = extractor.extractEntity(ref);
|
|
254
|
+
if (!wall) {
|
|
255
|
+
log(`wall #${wallId}: extractor returned null`);
|
|
256
|
+
return { segment: null, reason: 'wall-not-parsed' };
|
|
257
|
+
}
|
|
258
|
+
const placementId = numericAttr(wall.attributes[5]);
|
|
259
|
+
const representationId = numericAttr(wall.attributes[6]);
|
|
260
|
+
if (placementId === null)
|
|
261
|
+
return { segment: null, reason: 'no-placement' };
|
|
262
|
+
if (representationId === null)
|
|
263
|
+
return { segment: null, reason: 'no-representation' };
|
|
264
|
+
return computeWallSegment(store, extractor, placementId, representationId, undefined, wallId, log);
|
|
265
|
+
}
|
|
266
|
+
function extractWallAxisFromOverlay(store, extractor, overlay, wall, log) {
|
|
267
|
+
const placementId = numericAttr(wall.attributes[5]);
|
|
268
|
+
const representationId = numericAttr(wall.attributes[6]);
|
|
269
|
+
if (placementId === null)
|
|
270
|
+
return { segment: null, reason: 'no-placement' };
|
|
271
|
+
if (representationId === null)
|
|
272
|
+
return { segment: null, reason: 'no-representation' };
|
|
273
|
+
return computeWallSegment(store, extractor, placementId, representationId, overlay, wall.expressId, log);
|
|
274
|
+
}
|
|
275
|
+
function computeWallSegment(store, extractor, placementId, representationId, overlay, wallId, log) {
|
|
276
|
+
const frame = readPlacementFrame(store, extractor, overlay, placementId);
|
|
277
|
+
if (!frame) {
|
|
278
|
+
log(`wall #${wallId}: placement chain not resolvable (placement=#${placementId})`);
|
|
279
|
+
return { segment: null, reason: 'placement-not-resolvable' };
|
|
280
|
+
}
|
|
281
|
+
// Strategy 1 — Axis representation (start, end of polyline). Walks
|
|
282
|
+
// the wall's `Axis` representation and reads its first item if it's
|
|
283
|
+
// a 2-vertex IfcPolyline. This matches the standard authoring-tool
|
|
284
|
+
// convention so most imported IFC files succeed here.
|
|
285
|
+
const axisEndpoints = readAxisRepresentationEndpoints(store, extractor, overlay, representationId);
|
|
286
|
+
if (axisEndpoints) {
|
|
287
|
+
const start = applyFrame(frame, axisEndpoints[0]);
|
|
288
|
+
const end = applyFrame(frame, axisEndpoints[1]);
|
|
289
|
+
return finaliseSegment(start, end, wallId, log, 'axis-rep');
|
|
290
|
+
}
|
|
291
|
+
// Strategy 2 — addWallToStore convention. Origin = Start, length =
|
|
292
|
+
// IfcRectangleProfileDef.XDim, end = origin + axisX * length.
|
|
293
|
+
const length = readWallLength(store, extractor, overlay, representationId);
|
|
294
|
+
if (length !== null && length > AXIS_EPS) {
|
|
295
|
+
const start = frame.origin;
|
|
296
|
+
const end = [
|
|
297
|
+
frame.origin[0] + frame.axisX[0] * length,
|
|
298
|
+
frame.origin[1] + frame.axisX[1] * length,
|
|
299
|
+
];
|
|
300
|
+
return finaliseSegment(start, end, wallId, log, 'rect-profile');
|
|
301
|
+
}
|
|
302
|
+
log(`wall #${wallId}: no Axis representation and no IfcRectangleProfileDef body — skipping`);
|
|
303
|
+
return { segment: null, reason: 'no-axis-or-rect-profile' };
|
|
304
|
+
}
|
|
305
|
+
function finaliseSegment(start, end, wallId, log, source) {
|
|
306
|
+
const dx = end[0] - start[0];
|
|
307
|
+
const dy = end[1] - start[1];
|
|
308
|
+
const len = Math.hypot(dx, dy);
|
|
309
|
+
if (len < AXIS_EPS) {
|
|
310
|
+
log(`wall #${wallId}: degenerate axis length=${len.toExponential(2)} (source=${source})`);
|
|
311
|
+
return { segment: null, reason: 'zero-length-axis' };
|
|
312
|
+
}
|
|
313
|
+
log(`wall #${wallId}: axis (${start[0].toFixed(3)},${start[1].toFixed(3)})→(${end[0].toFixed(3)},${end[1].toFixed(3)}) len=${len.toFixed(3)} source=${source}`);
|
|
314
|
+
return { segment: { a: start, b: end } };
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Walk IfcLocalPlacement → IfcAxis2Placement3D → CartesianPoint and
|
|
318
|
+
* read the ground-plane origin + RefDirection. Returns null when any
|
|
319
|
+
* link is missing.
|
|
320
|
+
*/
|
|
321
|
+
function readPlacementFrame(store, extractor, overlay, placementId) {
|
|
322
|
+
const placement = readEntity(store, extractor, overlay, placementId);
|
|
323
|
+
if (!placement)
|
|
324
|
+
return null;
|
|
325
|
+
const axisPlacementId = numericAttr(placement.attributes[1]);
|
|
326
|
+
if (axisPlacementId === null)
|
|
327
|
+
return null;
|
|
328
|
+
const axisPlacement = readEntity(store, extractor, overlay, axisPlacementId);
|
|
329
|
+
if (!axisPlacement)
|
|
330
|
+
return null;
|
|
331
|
+
const locationId = numericAttr(axisPlacement.attributes[0]);
|
|
332
|
+
const refDirId = numericAttr(axisPlacement.attributes[2]);
|
|
333
|
+
if (locationId === null)
|
|
334
|
+
return null;
|
|
335
|
+
const locationEnt = readEntity(store, extractor, overlay, locationId);
|
|
336
|
+
if (!locationEnt)
|
|
337
|
+
return null;
|
|
338
|
+
const origin = readVec3(locationEnt.attributes[0]);
|
|
339
|
+
if (!origin)
|
|
340
|
+
return null;
|
|
341
|
+
let axisX = [1, 0];
|
|
342
|
+
if (refDirId !== null) {
|
|
343
|
+
const refDir = readEntity(store, extractor, overlay, refDirId);
|
|
344
|
+
if (refDir) {
|
|
345
|
+
const dir = readVec3(refDir.attributes[0]);
|
|
346
|
+
if (dir) {
|
|
347
|
+
const len = Math.hypot(dir[0], dir[1]);
|
|
348
|
+
if (len > AXIS_EPS)
|
|
349
|
+
axisX = [dir[0] / len, dir[1] / len];
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return { origin: [origin[0], origin[1]], axisX };
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Apply a placement frame to a storey-local 2D point. The point's X is
|
|
357
|
+
* along the wall's local axis; Y is perpendicular (perpendicular to
|
|
358
|
+
* the wall direction in the ground plane).
|
|
359
|
+
*/
|
|
360
|
+
function applyFrame(frame, local) {
|
|
361
|
+
const ax = frame.axisX[0];
|
|
362
|
+
const ay = frame.axisX[1];
|
|
363
|
+
// Perpendicular = rotate axisX 90° CCW around +Z.
|
|
364
|
+
const px = -ay;
|
|
365
|
+
const py = ax;
|
|
366
|
+
return [
|
|
367
|
+
frame.origin[0] + ax * local[0] + px * local[1],
|
|
368
|
+
frame.origin[1] + ay * local[0] + py * local[1],
|
|
369
|
+
];
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Walk the wall's representations, looking for the standard `Axis`
|
|
373
|
+
* representation. Returns the first two vertices of the first
|
|
374
|
+
* `IfcPolyline` item found, in storey-local 2D. Most authoring tools
|
|
375
|
+
* emit this as a 2-point polyline along the wall centreline.
|
|
376
|
+
*/
|
|
377
|
+
function readAxisRepresentationEndpoints(store, extractor, overlay, representationId) {
|
|
378
|
+
const productShape = readEntity(store, extractor, overlay, representationId);
|
|
379
|
+
if (!productShape)
|
|
380
|
+
return null;
|
|
381
|
+
const reps = productShape.attributes[2];
|
|
382
|
+
if (!Array.isArray(reps))
|
|
383
|
+
return null;
|
|
384
|
+
for (const repRef of reps) {
|
|
385
|
+
const repId = numericAttr(repRef);
|
|
386
|
+
if (repId === null)
|
|
387
|
+
continue;
|
|
388
|
+
const rep = readEntity(store, extractor, overlay, repId);
|
|
389
|
+
if (!rep)
|
|
390
|
+
continue;
|
|
391
|
+
// IfcShapeRepresentation: [ContextOfItems, RepresentationIdentifier, RepresentationType, Items]
|
|
392
|
+
const identifier = stringAttr(rep.attributes[1]);
|
|
393
|
+
if (!identifier || identifier.toLowerCase() !== 'axis')
|
|
394
|
+
continue;
|
|
395
|
+
const items = rep.attributes[3];
|
|
396
|
+
if (!Array.isArray(items))
|
|
397
|
+
continue;
|
|
398
|
+
for (const itemRef of items) {
|
|
399
|
+
const itemId = numericAttr(itemRef);
|
|
400
|
+
if (itemId === null)
|
|
401
|
+
continue;
|
|
402
|
+
const item = readEntity(store, extractor, overlay, itemId);
|
|
403
|
+
if (!item)
|
|
404
|
+
continue;
|
|
405
|
+
const itemType = (store.entities.getTypeName(itemId) || item.type || '').toLowerCase();
|
|
406
|
+
if (itemType !== 'ifcpolyline')
|
|
407
|
+
continue;
|
|
408
|
+
// IfcPolyline.Points = list of IfcCartesianPoint refs (attribute 0).
|
|
409
|
+
const pointsRefs = item.attributes[0];
|
|
410
|
+
if (!Array.isArray(pointsRefs) || pointsRefs.length < 2)
|
|
411
|
+
continue;
|
|
412
|
+
const a = readCartesianPoint2D(store, extractor, overlay, pointsRefs[0]);
|
|
413
|
+
const b = readCartesianPoint2D(store, extractor, overlay, pointsRefs[pointsRefs.length - 1]);
|
|
414
|
+
if (a && b)
|
|
415
|
+
return [a, b];
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
420
|
+
function readCartesianPoint2D(store, extractor, overlay, ref) {
|
|
421
|
+
const id = numericAttr(ref);
|
|
422
|
+
if (id === null)
|
|
423
|
+
return null;
|
|
424
|
+
const ent = readEntity(store, extractor, overlay, id);
|
|
425
|
+
if (!ent)
|
|
426
|
+
return null;
|
|
427
|
+
const coords = readVec3(ent.attributes[0]);
|
|
428
|
+
if (!coords)
|
|
429
|
+
return null;
|
|
430
|
+
return [coords[0], coords[1]];
|
|
431
|
+
}
|
|
432
|
+
function readWallLength(store, extractor, overlay, representationId) {
|
|
433
|
+
// IfcWall.Representation → IfcProductDefinitionShape.Representations[]
|
|
434
|
+
// → IfcShapeRepresentation.Items[] → IfcExtrudedAreaSolid → SweptArea
|
|
435
|
+
// → IfcRectangleProfileDef.XDim
|
|
436
|
+
const productShape = readEntity(store, extractor, overlay, representationId);
|
|
437
|
+
if (!productShape)
|
|
438
|
+
return null;
|
|
439
|
+
const reps = productShape.attributes[2];
|
|
440
|
+
if (!Array.isArray(reps))
|
|
441
|
+
return null;
|
|
442
|
+
for (const repRef of reps) {
|
|
443
|
+
const repId = numericAttr(repRef);
|
|
444
|
+
if (repId === null)
|
|
445
|
+
continue;
|
|
446
|
+
const rep = readEntity(store, extractor, overlay, repId);
|
|
447
|
+
if (!rep)
|
|
448
|
+
continue;
|
|
449
|
+
const items = rep.attributes[3];
|
|
450
|
+
if (!Array.isArray(items))
|
|
451
|
+
continue;
|
|
452
|
+
for (const itemRef of items) {
|
|
453
|
+
const itemId = numericAttr(itemRef);
|
|
454
|
+
if (itemId === null)
|
|
455
|
+
continue;
|
|
456
|
+
const item = readEntity(store, extractor, overlay, itemId);
|
|
457
|
+
if (!item)
|
|
458
|
+
continue;
|
|
459
|
+
// IfcExtrudedAreaSolid: attribute 0 = SweptArea (profile)
|
|
460
|
+
const profileId = numericAttr(item.attributes[0]);
|
|
461
|
+
if (profileId === null)
|
|
462
|
+
continue;
|
|
463
|
+
const profile = readEntity(store, extractor, overlay, profileId);
|
|
464
|
+
if (!profile)
|
|
465
|
+
continue;
|
|
466
|
+
const profileType = profileTypeName(store, profile, profileId);
|
|
467
|
+
if (profileType !== 'ifcrectangleprofiledef')
|
|
468
|
+
continue;
|
|
469
|
+
// IfcRectangleProfileDef.XDim = attribute index 3.
|
|
470
|
+
const xdim = numericAttr(profile.attributes[3]);
|
|
471
|
+
if (xdim !== null && xdim > 0)
|
|
472
|
+
return xdim;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return null;
|
|
476
|
+
}
|
|
477
|
+
function profileTypeName(store, profile, profileId) {
|
|
478
|
+
const fromTable = store.entities.getTypeName(profileId);
|
|
479
|
+
const name = (fromTable && fromTable !== 'Unknown' ? fromTable : profile.type) ?? '';
|
|
480
|
+
return name.toLowerCase();
|
|
481
|
+
}
|
|
482
|
+
function readEntity(store, extractor, overlay, expressId) {
|
|
483
|
+
const ref = store.entityIndex.byId.get(expressId);
|
|
484
|
+
if (ref && ref.byteLength > 0 && ref.byteOffset >= 0) {
|
|
485
|
+
return extractor.extractEntity(ref);
|
|
486
|
+
}
|
|
487
|
+
// Overlay-only entity: fall back to the overlay reader.
|
|
488
|
+
if (overlay) {
|
|
489
|
+
for (const ent of overlay.getNewEntities()) {
|
|
490
|
+
if (ent.expressId === expressId) {
|
|
491
|
+
return { type: ent.type, attributes: ent.attributes };
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return null;
|
|
496
|
+
}
|
|
497
|
+
function numericAttr(v) {
|
|
498
|
+
if (typeof v === 'number')
|
|
499
|
+
return v;
|
|
500
|
+
if (typeof v === 'string') {
|
|
501
|
+
if (v.startsWith('#')) {
|
|
502
|
+
const n = Number(v.slice(1));
|
|
503
|
+
return Number.isFinite(n) ? n : null;
|
|
504
|
+
}
|
|
505
|
+
const n = Number(v);
|
|
506
|
+
return Number.isFinite(n) ? n : null;
|
|
507
|
+
}
|
|
508
|
+
return null;
|
|
509
|
+
}
|
|
510
|
+
function stringAttr(v) {
|
|
511
|
+
if (typeof v === 'string') {
|
|
512
|
+
// Strip STEP single quotes if present (parser sometimes returns them, sometimes not).
|
|
513
|
+
if (v.startsWith("'") && v.endsWith("'"))
|
|
514
|
+
return v.slice(1, -1);
|
|
515
|
+
return v;
|
|
516
|
+
}
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
function readVec3(v) {
|
|
520
|
+
if (!Array.isArray(v) || v.length < 2)
|
|
521
|
+
return null;
|
|
522
|
+
const x = numericAttr(v[0]);
|
|
523
|
+
const y = numericAttr(v[1]);
|
|
524
|
+
const z = v.length >= 3 ? numericAttr(v[2]) : 0;
|
|
525
|
+
if (x === null || y === null || z === null)
|
|
526
|
+
return null;
|
|
527
|
+
return [x, y, z];
|
|
528
|
+
}
|
|
529
|
+
//# sourceMappingURL=extract-walls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-walls.js","sourceRoot":"","sources":["../../src/in-store/extract-walls.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stitch together the auto-space pipeline for a single storey:
|
|
3
|
+
*
|
|
4
|
+
* walls (existing + overlay)
|
|
5
|
+
* → 2D axis segments (`extractWallSegmentsForStorey`)
|
|
6
|
+
* → enclosed regions (`detectEnclosedAreas`)
|
|
7
|
+
* → IfcSpace per region (`addSpaceToStore` polygon mode)
|
|
8
|
+
*
|
|
9
|
+
* Pure orchestration — the geometry/IFC heavy lifting lives in the
|
|
10
|
+
* dedicated modules. The result lists every IfcSpace expressId emitted
|
|
11
|
+
* plus a richer per-region summary (area, outline) for UI feedback.
|
|
12
|
+
*/
|
|
13
|
+
import type { IfcDataStore } from '@ifc-lite/parser';
|
|
14
|
+
import type { StoreEditor } from '@ifc-lite/mutations';
|
|
15
|
+
import { type OverlayWallReader, type WallSkip } from './extract-walls.js';
|
|
16
|
+
import { type DetectedSpace, type DetectStats } from './auto-space-detect.js';
|
|
17
|
+
import { type SpaceBuildResult } from './space.js';
|
|
18
|
+
export interface GenerateSpacesOptions {
|
|
19
|
+
/** Snap tolerance for wall-end vertex merge in METRES. Default 0.1 m. */
|
|
20
|
+
snapTolerance?: number;
|
|
21
|
+
/** Drop detected regions below this area in m². Default 0.5 m². */
|
|
22
|
+
minArea?: number;
|
|
23
|
+
/** IfcSpace extrusion height (m). Default 3. */
|
|
24
|
+
height?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Naming pattern for emitted spaces. `{n}` is replaced with a 1-based
|
|
27
|
+
* index. Default `'Space {n}'`.
|
|
28
|
+
*/
|
|
29
|
+
namePattern?: string;
|
|
30
|
+
/** Optional IfcSpacePredefinedType (defaults to INTERNAL). */
|
|
31
|
+
predefinedType?: string;
|
|
32
|
+
/** Optional override for IfcSpace.LongName (single value, all spaces). */
|
|
33
|
+
longName?: string;
|
|
34
|
+
/** When true, runs detection but doesn't emit any IfcSpace. */
|
|
35
|
+
dryRun?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* When true, every stage of the pipeline (wall extraction →
|
|
38
|
+
* detection) emits `console.debug` messages so the viewer's
|
|
39
|
+
* Auto Spaces "no regions detected" failure mode can be diagnosed
|
|
40
|
+
* from devtools without touching the algorithm. The result also
|
|
41
|
+
* carries detection stats unconditionally.
|
|
42
|
+
*/
|
|
43
|
+
debug?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Additional element types to treat as space dividers (passed to
|
|
46
|
+
* the wall extractor verbatim — case-insensitive). The defaults
|
|
47
|
+
* already cover walls, curtain walls, virtual elements, plates,
|
|
48
|
+
* members, and railings.
|
|
49
|
+
*/
|
|
50
|
+
extraDividerTypes?: string[];
|
|
51
|
+
}
|
|
52
|
+
export interface GenerateSpacesResult {
|
|
53
|
+
/** Total walls considered (existing + overlay) on the storey. */
|
|
54
|
+
wallsConsidered: number;
|
|
55
|
+
/** Walls that contributed an axis segment to the planar graph. */
|
|
56
|
+
wallsContributing: number;
|
|
57
|
+
/** Walls dropped by the extractor, with the reason (best-effort). */
|
|
58
|
+
wallsSkipped: WallSkip[];
|
|
59
|
+
/** Enclosed regions detected (after min-area + outer-face filter). */
|
|
60
|
+
detected: DetectedSpace[];
|
|
61
|
+
/** Per-stage planar-graph statistics — surfaced for diagnostics. */
|
|
62
|
+
detectionStats: DetectStats;
|
|
63
|
+
/** Per-region builder result. Empty when `dryRun: true`. */
|
|
64
|
+
emitted: Array<{
|
|
65
|
+
region: DetectedSpace;
|
|
66
|
+
result: SpaceBuildResult;
|
|
67
|
+
name: string;
|
|
68
|
+
}>;
|
|
69
|
+
}
|
|
70
|
+
export declare function generateSpacesFromWalls(editor: StoreEditor, store: IfcDataStore, storeyExpressId: number, options?: GenerateSpacesOptions, overlay?: OverlayWallReader): GenerateSpacesResult;
|
|
71
|
+
//# sourceMappingURL=generate-spaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-spaces.d.ts","sourceRoot":"","sources":["../../src/in-store/generate-spaces.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,qBAAqB;IACpC,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,iEAAiE;IACjE,eAAe,EAAE,MAAM,CAAC;IACxB,kEAAkE;IAClE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,YAAY,EAAE,QAAQ,EAAE,CAAC;IACzB,sEAAsE;IACtE,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,oEAAoE;IACpE,cAAc,EAAE,WAAW,CAAC;IAC5B,4DAA4D;IAC5D,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,aAAa,CAAC;QAAC,MAAM,EAAE,gBAAgB,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnF;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,YAAY,EACnB,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE,qBAA0B,EACnC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,oBAAoB,CA6EtB"}
|