@ifc-lite/create 1.14.4 → 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.
Files changed (87) hide show
  1. package/dist/ifc-creator-math.d.ts +23 -0
  2. package/dist/ifc-creator-math.d.ts.map +1 -0
  3. package/dist/ifc-creator-math.js +50 -0
  4. package/dist/ifc-creator-math.js.map +1 -0
  5. package/dist/ifc-creator.d.ts +63 -1
  6. package/dist/ifc-creator.d.ts.map +1 -1
  7. package/dist/ifc-creator.js +221 -40
  8. package/dist/ifc-creator.js.map +1 -1
  9. package/dist/in-store/_emit-helpers.d.ts +52 -0
  10. package/dist/in-store/_emit-helpers.d.ts.map +1 -0
  11. package/dist/in-store/_emit-helpers.js +147 -0
  12. package/dist/in-store/_emit-helpers.js.map +1 -0
  13. package/dist/in-store/anchor.d.ts +27 -0
  14. package/dist/in-store/anchor.d.ts.map +1 -0
  15. package/dist/in-store/anchor.js +5 -0
  16. package/dist/in-store/anchor.js.map +1 -0
  17. package/dist/in-store/auto-space-detect.d.ts +68 -0
  18. package/dist/in-store/auto-space-detect.d.ts.map +1 -0
  19. package/dist/in-store/auto-space-detect.js +353 -0
  20. package/dist/in-store/auto-space-detect.js.map +1 -0
  21. package/dist/in-store/beam.d.ts +25 -0
  22. package/dist/in-store/beam.d.ts.map +1 -0
  23. package/dist/in-store/beam.js +119 -0
  24. package/dist/in-store/beam.js.map +1 -0
  25. package/dist/in-store/column.d.ts +42 -0
  26. package/dist/in-store/column.d.ts.map +1 -0
  27. package/dist/in-store/column.js +108 -0
  28. package/dist/in-store/column.js.map +1 -0
  29. package/dist/in-store/door.d.ts +44 -0
  30. package/dist/in-store/door.d.ts.map +1 -0
  31. package/dist/in-store/door.js +68 -0
  32. package/dist/in-store/door.js.map +1 -0
  33. package/dist/in-store/duplicate.d.ts +100 -0
  34. package/dist/in-store/duplicate.d.ts.map +1 -0
  35. package/dist/in-store/duplicate.js +122 -0
  36. package/dist/in-store/duplicate.js.map +1 -0
  37. package/dist/in-store/extract-walls.d.ts +80 -0
  38. package/dist/in-store/extract-walls.d.ts.map +1 -0
  39. package/dist/in-store/extract-walls.js +529 -0
  40. package/dist/in-store/extract-walls.js.map +1 -0
  41. package/dist/in-store/generate-spaces.d.ts +71 -0
  42. package/dist/in-store/generate-spaces.d.ts.map +1 -0
  43. package/dist/in-store/generate-spaces.js +76 -0
  44. package/dist/in-store/generate-spaces.js.map +1 -0
  45. package/dist/in-store/member.d.ts +32 -0
  46. package/dist/in-store/member.d.ts.map +1 -0
  47. package/dist/in-store/member.js +35 -0
  48. package/dist/in-store/member.js.map +1 -0
  49. package/dist/in-store/plate.d.ts +43 -0
  50. package/dist/in-store/plate.d.ts.map +1 -0
  51. package/dist/in-store/plate.js +33 -0
  52. package/dist/in-store/plate.js.map +1 -0
  53. package/dist/in-store/resolve-anchor.d.ts +12 -0
  54. package/dist/in-store/resolve-anchor.d.ts.map +1 -0
  55. package/dist/in-store/resolve-anchor.js +89 -0
  56. package/dist/in-store/resolve-anchor.js.map +1 -0
  57. package/dist/in-store/resolve-source.d.ts +19 -0
  58. package/dist/in-store/resolve-source.d.ts.map +1 -0
  59. package/dist/in-store/resolve-source.js +203 -0
  60. package/dist/in-store/resolve-source.js.map +1 -0
  61. package/dist/in-store/roof.d.ts +43 -0
  62. package/dist/in-store/roof.d.ts.map +1 -0
  63. package/dist/in-store/roof.js +33 -0
  64. package/dist/in-store/roof.js.map +1 -0
  65. package/dist/in-store/slab.d.ts +44 -0
  66. package/dist/in-store/slab.d.ts.map +1 -0
  67. package/dist/in-store/slab.js +142 -0
  68. package/dist/in-store/slab.js.map +1 -0
  69. package/dist/in-store/space.d.ts +43 -0
  70. package/dist/in-store/space.d.ts.map +1 -0
  71. package/dist/in-store/space.js +71 -0
  72. package/dist/in-store/space.js.map +1 -0
  73. package/dist/in-store/wall.d.ts +27 -0
  74. package/dist/in-store/wall.d.ts.map +1 -0
  75. package/dist/in-store/wall.js +119 -0
  76. package/dist/in-store/wall.js.map +1 -0
  77. package/dist/in-store/window.d.ts +36 -0
  78. package/dist/in-store/window.d.ts.map +1 -0
  79. package/dist/in-store/window.js +57 -0
  80. package/dist/in-store/window.js.map +1 -0
  81. package/dist/index.d.ts +18 -1
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +18 -0
  84. package/dist/index.js.map +1 -1
  85. package/dist/types.d.ts +96 -0
  86. package/dist/types.d.ts.map +1 -1
  87. package/package.json +8 -4
@@ -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"}