brepjs-bim 0.23.2 → 0.24.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/README.md +19 -8
- package/dist/brepjs-bim.cjs +1042 -690
- package/dist/brepjs-bim.js +1043 -692
- package/dist/elementFns/placedGeometry.d.ts +5 -0
- package/dist/errors/bimError.d.ts +1 -1
- package/dist/ifc-writer/ifcWriter.d.ts +16 -0
- package/dist/ifc-writer/psetWriter.d.ts +6 -0
- package/dist/ifc-writer/tessellationWriter.d.ts +26 -0
- package/dist/index.d.ts +2 -0
- package/dist/model/bimModel.d.ts +9 -0
- package/dist/rigidPlacement.d.ts +4 -0
- package/dist/serialize/exactBodyPreflight.d.ts +15 -0
- package/dist/serialize/exactWallQuantities.d.ts +20 -0
- package/dist/types/bimTypes.d.ts +2 -1
- package/dist/types/productBody.d.ts +13 -0
- package/package.json +1 -1
package/dist/brepjs-bim.cjs
CHANGED
|
@@ -134,12 +134,13 @@ function specError(code, message, cause) {
|
|
|
134
134
|
cause
|
|
135
135
|
};
|
|
136
136
|
}
|
|
137
|
-
function ifcError(code, message, cause) {
|
|
137
|
+
function ifcError(code, message, cause, metadata) {
|
|
138
138
|
return {
|
|
139
139
|
kind: "BIM_IFC",
|
|
140
140
|
code,
|
|
141
141
|
message,
|
|
142
|
-
cause
|
|
142
|
+
cause,
|
|
143
|
+
...metadata !== void 0 ? { metadata } : {}
|
|
143
144
|
};
|
|
144
145
|
}
|
|
145
146
|
function geometryError(code, message, cause) {
|
|
@@ -265,7 +266,7 @@ function _usingCtx() {
|
|
|
265
266
|
//#region src/elementFns/wallFns.ts
|
|
266
267
|
function wallToSolid(spec) {
|
|
267
268
|
try {
|
|
268
|
-
var _usingCtx$
|
|
269
|
+
var _usingCtx$20 = _usingCtx();
|
|
269
270
|
if (spec.length <= 0) return (0, brepjs.err)(specError("WALL_ZERO_LENGTH", "Wall length must be positive"));
|
|
270
271
|
if (spec.height <= 0) return (0, brepjs.err)(specError("WALL_ZERO_HEIGHT", "Wall height must be positive"));
|
|
271
272
|
if (spec.thickness <= 0) return (0, brepjs.err)(specError("WALL_ZERO_THICKNESS", "Wall thickness must be positive"));
|
|
@@ -293,7 +294,7 @@ function wallToSolid(spec) {
|
|
|
293
294
|
]
|
|
294
295
|
]);
|
|
295
296
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "WALL_PROFILE_FAILED", "Failed to create wall profile"));
|
|
296
|
-
const profile = _usingCtx$
|
|
297
|
+
const profile = _usingCtx$20.u(profileResult.value);
|
|
297
298
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
298
299
|
length,
|
|
299
300
|
0,
|
|
@@ -307,16 +308,16 @@ function wallToSolid(spec) {
|
|
|
307
308
|
}
|
|
308
309
|
return (0, brepjs.ok)(solid);
|
|
309
310
|
} catch (_) {
|
|
310
|
-
_usingCtx$
|
|
311
|
+
_usingCtx$20.e = _;
|
|
311
312
|
} finally {
|
|
312
|
-
_usingCtx$
|
|
313
|
+
_usingCtx$20.d();
|
|
313
314
|
}
|
|
314
315
|
}
|
|
315
316
|
//#endregion
|
|
316
317
|
//#region src/elementFns/slabFns.ts
|
|
317
318
|
function slabToSolid(spec) {
|
|
318
319
|
try {
|
|
319
|
-
var _usingCtx$
|
|
320
|
+
var _usingCtx$19 = _usingCtx();
|
|
320
321
|
if (spec.length <= 0) return (0, brepjs.err)(specError("SLAB_ZERO_LENGTH", "Slab length must be positive"));
|
|
321
322
|
if (spec.width <= 0) return (0, brepjs.err)(specError("SLAB_ZERO_WIDTH", "Slab width must be positive"));
|
|
322
323
|
if (spec.thickness <= 0) return (0, brepjs.err)(specError("SLAB_ZERO_THICKNESS", "Slab thickness must be positive"));
|
|
@@ -344,7 +345,7 @@ function slabToSolid(spec) {
|
|
|
344
345
|
]
|
|
345
346
|
]);
|
|
346
347
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "SLAB_PROFILE_FAILED", "Failed to create slab profile"));
|
|
347
|
-
const profile = _usingCtx$
|
|
348
|
+
const profile = _usingCtx$19.u(profileResult.value);
|
|
348
349
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
349
350
|
0,
|
|
350
351
|
0,
|
|
@@ -358,9 +359,9 @@ function slabToSolid(spec) {
|
|
|
358
359
|
}
|
|
359
360
|
return (0, brepjs.ok)(solid);
|
|
360
361
|
} catch (_) {
|
|
361
|
-
_usingCtx$
|
|
362
|
+
_usingCtx$19.e = _;
|
|
362
363
|
} finally {
|
|
363
|
-
_usingCtx$
|
|
364
|
+
_usingCtx$19.d();
|
|
364
365
|
}
|
|
365
366
|
}
|
|
366
367
|
//#endregion
|
|
@@ -5048,14 +5049,14 @@ function to3D(points) {
|
|
|
5048
5049
|
}
|
|
5049
5050
|
function extendedProfileToFace(profile) {
|
|
5050
5051
|
try {
|
|
5051
|
-
var _usingCtx$
|
|
5052
|
+
var _usingCtx$18 = _usingCtx();
|
|
5052
5053
|
const invalid = validateProfile(profile);
|
|
5053
5054
|
if (invalid !== null) return (0, brepjs.err)(invalid);
|
|
5054
5055
|
const outerResult = (0, brepjs.polygon)(to3D(outerLoop(profile)));
|
|
5055
5056
|
if (!outerResult.ok) return (0, brepjs.err)(fromBrepError(outerResult.error, "PROFILE_FACE_FAILED", "Failed to build profile outer face"));
|
|
5056
5057
|
const holes = holeLoops(profile);
|
|
5057
5058
|
if (holes.length === 0) return (0, brepjs.ok)(outerResult.value);
|
|
5058
|
-
const outerFace = _usingCtx$
|
|
5059
|
+
const outerFace = _usingCtx$18.u(outerResult.value);
|
|
5059
5060
|
const holeFaces = [];
|
|
5060
5061
|
const holeWires = [];
|
|
5061
5062
|
const disposeHoleFaces = () => {
|
|
@@ -5080,9 +5081,9 @@ function extendedProfileToFace(profile) {
|
|
|
5080
5081
|
disposeHoleFaces();
|
|
5081
5082
|
return (0, brepjs.ok)(faceWithHoles);
|
|
5082
5083
|
} catch (_) {
|
|
5083
|
-
_usingCtx$
|
|
5084
|
+
_usingCtx$18.e = _;
|
|
5084
5085
|
} finally {
|
|
5085
|
-
_usingCtx$
|
|
5086
|
+
_usingCtx$18.d();
|
|
5086
5087
|
}
|
|
5087
5088
|
}
|
|
5088
5089
|
//#endregion
|
|
@@ -5404,7 +5405,7 @@ function profileToPolygon(profile, circleSegments = 32) {
|
|
|
5404
5405
|
//#region src/elementFns/beamFns.ts
|
|
5405
5406
|
function beamToSolid(spec) {
|
|
5406
5407
|
try {
|
|
5407
|
-
var _usingCtx$
|
|
5408
|
+
var _usingCtx$17 = _usingCtx();
|
|
5408
5409
|
if (spec.length <= 0) return (0, brepjs.err)(specError("BEAM_ZERO_LENGTH", "Beam length must be positive"));
|
|
5409
5410
|
if (isExtendedProfile(spec.profile)) try {
|
|
5410
5411
|
var _usingCtx3 = _usingCtx();
|
|
@@ -5442,7 +5443,7 @@ function beamToSolid(spec) {
|
|
|
5442
5443
|
]);
|
|
5443
5444
|
const profileResult = (0, brepjs.polygon)(profilePts);
|
|
5444
5445
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "BEAM_PROFILE_FAILED", "Failed to create beam profile"));
|
|
5445
|
-
const profile = _usingCtx$
|
|
5446
|
+
const profile = _usingCtx$17.u(profileResult.value);
|
|
5446
5447
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5447
5448
|
spec.length,
|
|
5448
5449
|
0,
|
|
@@ -5456,16 +5457,16 @@ function beamToSolid(spec) {
|
|
|
5456
5457
|
}
|
|
5457
5458
|
return (0, brepjs.ok)(solid);
|
|
5458
5459
|
} catch (_) {
|
|
5459
|
-
_usingCtx$
|
|
5460
|
+
_usingCtx$17.e = _;
|
|
5460
5461
|
} finally {
|
|
5461
|
-
_usingCtx$
|
|
5462
|
+
_usingCtx$17.d();
|
|
5462
5463
|
}
|
|
5463
5464
|
}
|
|
5464
5465
|
//#endregion
|
|
5465
5466
|
//#region src/elementFns/columnFns.ts
|
|
5466
5467
|
function columnToSolid(spec) {
|
|
5467
5468
|
try {
|
|
5468
|
-
var _usingCtx$
|
|
5469
|
+
var _usingCtx$16 = _usingCtx();
|
|
5469
5470
|
if (spec.height <= 0) return (0, brepjs.err)(specError("COLUMN_ZERO_HEIGHT", "Column height must be positive"));
|
|
5470
5471
|
if (isExtendedProfile(spec.profile)) try {
|
|
5471
5472
|
var _usingCtx3 = _usingCtx();
|
|
@@ -5494,7 +5495,7 @@ function columnToSolid(spec) {
|
|
|
5494
5495
|
const profilePts = profilePtsResult.value;
|
|
5495
5496
|
const profileResult = (0, brepjs.polygon)(profilePts);
|
|
5496
5497
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "COLUMN_PROFILE_FAILED", "Failed to create column profile"));
|
|
5497
|
-
const profile = _usingCtx$
|
|
5498
|
+
const profile = _usingCtx$16.u(profileResult.value);
|
|
5498
5499
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5499
5500
|
0,
|
|
5500
5501
|
0,
|
|
@@ -5508,9 +5509,9 @@ function columnToSolid(spec) {
|
|
|
5508
5509
|
}
|
|
5509
5510
|
return (0, brepjs.ok)(solid);
|
|
5510
5511
|
} catch (_) {
|
|
5511
|
-
_usingCtx$
|
|
5512
|
+
_usingCtx$16.e = _;
|
|
5512
5513
|
} finally {
|
|
5513
|
-
_usingCtx$
|
|
5514
|
+
_usingCtx$16.d();
|
|
5514
5515
|
}
|
|
5515
5516
|
}
|
|
5516
5517
|
//#endregion
|
|
@@ -5518,7 +5519,7 @@ function columnToSolid(spec) {
|
|
|
5518
5519
|
var EPSILON_MM = 1;
|
|
5519
5520
|
function openingToSolid(spec, wallThickness) {
|
|
5520
5521
|
try {
|
|
5521
|
-
var _usingCtx$
|
|
5522
|
+
var _usingCtx$15 = _usingCtx();
|
|
5522
5523
|
if (spec.width <= 0) return (0, brepjs.err)(specError("OPENING_ZERO_WIDTH", "Opening width must be positive"));
|
|
5523
5524
|
if (spec.height <= 0) return (0, brepjs.err)(specError("OPENING_ZERO_HEIGHT", "Opening height must be positive"));
|
|
5524
5525
|
if (wallThickness <= 0) return (0, brepjs.err)(specError("OPENING_ZERO_WALL_THICKNESS", "Wall thickness must be positive"));
|
|
@@ -5550,7 +5551,7 @@ function openingToSolid(spec, wallThickness) {
|
|
|
5550
5551
|
]
|
|
5551
5552
|
]);
|
|
5552
5553
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "OPENING_PROFILE_FAILED", "Failed to create opening profile"));
|
|
5553
|
-
const profile = _usingCtx$
|
|
5554
|
+
const profile = _usingCtx$15.u(profileResult.value);
|
|
5554
5555
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5555
5556
|
spec.width,
|
|
5556
5557
|
0,
|
|
@@ -5564,16 +5565,16 @@ function openingToSolid(spec, wallThickness) {
|
|
|
5564
5565
|
}
|
|
5565
5566
|
return (0, brepjs.ok)(solid);
|
|
5566
5567
|
} catch (_) {
|
|
5567
|
-
_usingCtx$
|
|
5568
|
+
_usingCtx$15.e = _;
|
|
5568
5569
|
} finally {
|
|
5569
|
-
_usingCtx$
|
|
5570
|
+
_usingCtx$15.d();
|
|
5570
5571
|
}
|
|
5571
5572
|
}
|
|
5572
5573
|
//#endregion
|
|
5573
5574
|
//#region src/elementFns/slabOpeningFns.ts
|
|
5574
5575
|
function slabOpeningToSolid(spec, slabThickness) {
|
|
5575
5576
|
try {
|
|
5576
|
-
var _usingCtx$
|
|
5577
|
+
var _usingCtx$14 = _usingCtx();
|
|
5577
5578
|
if (spec.sizeX <= 0) return (0, brepjs.err)(specError("SLAB_OPENING_ZERO_SIZE_X", "Slab opening sizeX must be positive"));
|
|
5578
5579
|
if (spec.sizeY <= 0) return (0, brepjs.err)(specError("SLAB_OPENING_ZERO_SIZE_Y", "Slab opening sizeY must be positive"));
|
|
5579
5580
|
if (slabThickness <= 0) return (0, brepjs.err)(specError("SLAB_OPENING_ZERO_SLAB_THICKNESS", "Slab thickness must be positive"));
|
|
@@ -5605,7 +5606,7 @@ function slabOpeningToSolid(spec, slabThickness) {
|
|
|
5605
5606
|
]
|
|
5606
5607
|
]);
|
|
5607
5608
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "SLAB_OPENING_PROFILE_FAILED", "Failed to create slab opening profile"));
|
|
5608
|
-
const profile = _usingCtx$
|
|
5609
|
+
const profile = _usingCtx$14.u(profileResult.value);
|
|
5609
5610
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5610
5611
|
0,
|
|
5611
5612
|
0,
|
|
@@ -5619,16 +5620,16 @@ function slabOpeningToSolid(spec, slabThickness) {
|
|
|
5619
5620
|
}
|
|
5620
5621
|
return (0, brepjs.ok)(solid);
|
|
5621
5622
|
} catch (_) {
|
|
5622
|
-
_usingCtx$
|
|
5623
|
+
_usingCtx$14.e = _;
|
|
5623
5624
|
} finally {
|
|
5624
|
-
_usingCtx$
|
|
5625
|
+
_usingCtx$14.d();
|
|
5625
5626
|
}
|
|
5626
5627
|
}
|
|
5627
5628
|
//#endregion
|
|
5628
5629
|
//#region src/elementFns/spaceFns.ts
|
|
5629
5630
|
function spaceToSolid(spec) {
|
|
5630
5631
|
try {
|
|
5631
|
-
var _usingCtx$
|
|
5632
|
+
var _usingCtx$13 = _usingCtx();
|
|
5632
5633
|
if (spec.length <= 0) return (0, brepjs.err)(specError("SPACE_ZERO_LENGTH", "Space length must be positive"));
|
|
5633
5634
|
if (spec.width <= 0) return (0, brepjs.err)(specError("SPACE_ZERO_WIDTH", "Space width must be positive"));
|
|
5634
5635
|
if (spec.height <= 0) return (0, brepjs.err)(specError("SPACE_ZERO_HEIGHT", "Space height must be positive"));
|
|
@@ -5656,7 +5657,7 @@ function spaceToSolid(spec) {
|
|
|
5656
5657
|
]
|
|
5657
5658
|
]);
|
|
5658
5659
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "SPACE_PROFILE_FAILED", "Failed to create space footprint"));
|
|
5659
|
-
const profile = _usingCtx$
|
|
5660
|
+
const profile = _usingCtx$13.u(profileResult.value);
|
|
5660
5661
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5661
5662
|
0,
|
|
5662
5663
|
0,
|
|
@@ -5670,9 +5671,9 @@ function spaceToSolid(spec) {
|
|
|
5670
5671
|
}
|
|
5671
5672
|
return (0, brepjs.ok)(solid);
|
|
5672
5673
|
} catch (_) {
|
|
5673
|
-
_usingCtx$
|
|
5674
|
+
_usingCtx$13.e = _;
|
|
5674
5675
|
} finally {
|
|
5675
|
-
_usingCtx$
|
|
5676
|
+
_usingCtx$13.d();
|
|
5676
5677
|
}
|
|
5677
5678
|
}
|
|
5678
5679
|
//#endregion
|
|
@@ -5687,7 +5688,7 @@ function gate(solid, code) {
|
|
|
5687
5688
|
}
|
|
5688
5689
|
function flatRoof(spec) {
|
|
5689
5690
|
try {
|
|
5690
|
-
var _usingCtx$
|
|
5691
|
+
var _usingCtx$12 = _usingCtx();
|
|
5691
5692
|
const { length, width, thickness } = spec;
|
|
5692
5693
|
const face = (0, brepjs.polygon)([
|
|
5693
5694
|
[
|
|
@@ -5712,7 +5713,7 @@ function flatRoof(spec) {
|
|
|
5712
5713
|
]
|
|
5713
5714
|
]);
|
|
5714
5715
|
if (!face.ok) return (0, brepjs.err)(fromBrepError(face.error, "ROOF_PROFILE_FAILED", "Failed to create roof profile"));
|
|
5715
|
-
const profile = _usingCtx$
|
|
5716
|
+
const profile = _usingCtx$12.u(face.value);
|
|
5716
5717
|
const solid = (0, brepjs.extrude)(profile, [
|
|
5717
5718
|
0,
|
|
5718
5719
|
0,
|
|
@@ -5721,9 +5722,9 @@ function flatRoof(spec) {
|
|
|
5721
5722
|
if (!solid.ok) return (0, brepjs.err)(fromBrepError(solid.error, "ROOF_EXTRUDE_FAILED", "Failed to extrude roof profile"));
|
|
5722
5723
|
return gate(solid.value, "ROOF_INVALID_SOLID");
|
|
5723
5724
|
} catch (_) {
|
|
5724
|
-
_usingCtx$
|
|
5725
|
+
_usingCtx$12.e = _;
|
|
5725
5726
|
} finally {
|
|
5726
|
-
_usingCtx$
|
|
5727
|
+
_usingCtx$12.d();
|
|
5727
5728
|
}
|
|
5728
5729
|
}
|
|
5729
5730
|
function shedRoof(spec, pitch) {
|
|
@@ -5919,7 +5920,7 @@ function roofToSolid(spec) {
|
|
|
5919
5920
|
//#region src/elementFns/curtainWallFns.ts
|
|
5920
5921
|
function boxSolid(sizeX, sizeY, sizeZ) {
|
|
5921
5922
|
try {
|
|
5922
|
-
var _usingCtx$
|
|
5923
|
+
var _usingCtx$11 = _usingCtx();
|
|
5923
5924
|
const profileResult = (0, brepjs.polygon)([
|
|
5924
5925
|
[
|
|
5925
5926
|
0,
|
|
@@ -5943,7 +5944,7 @@ function boxSolid(sizeX, sizeY, sizeZ) {
|
|
|
5943
5944
|
]
|
|
5944
5945
|
]);
|
|
5945
5946
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "CURTAIN_WALL_PROFILE_FAILED", "Failed to create component profile"));
|
|
5946
|
-
const profile = _usingCtx$
|
|
5947
|
+
const profile = _usingCtx$11.u(profileResult.value);
|
|
5947
5948
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5948
5949
|
0,
|
|
5949
5950
|
0,
|
|
@@ -5957,9 +5958,9 @@ function boxSolid(sizeX, sizeY, sizeZ) {
|
|
|
5957
5958
|
}
|
|
5958
5959
|
return (0, brepjs.ok)(solid);
|
|
5959
5960
|
} catch (_) {
|
|
5960
|
-
_usingCtx$
|
|
5961
|
+
_usingCtx$11.e = _;
|
|
5961
5962
|
} finally {
|
|
5962
|
-
_usingCtx$
|
|
5963
|
+
_usingCtx$11.d();
|
|
5963
5964
|
}
|
|
5964
5965
|
}
|
|
5965
5966
|
function disposeComponents(components) {
|
|
@@ -6058,7 +6059,7 @@ function curtainWallToGrid(spec) {
|
|
|
6058
6059
|
//#region src/elementFns/foundationFns.ts
|
|
6059
6060
|
function footingToSolid(spec) {
|
|
6060
6061
|
try {
|
|
6061
|
-
var _usingCtx$
|
|
6062
|
+
var _usingCtx$10 = _usingCtx();
|
|
6062
6063
|
if (spec.length <= 0) return (0, brepjs.err)(specError("FOOTING_ZERO_LENGTH", "Footing length must be positive"));
|
|
6063
6064
|
if (spec.width <= 0) return (0, brepjs.err)(specError("FOOTING_ZERO_WIDTH", "Footing width must be positive"));
|
|
6064
6065
|
if (spec.thickness <= 0) return (0, brepjs.err)(specError("FOOTING_ZERO_THICKNESS", "Footing thickness must be positive"));
|
|
@@ -6086,7 +6087,7 @@ function footingToSolid(spec) {
|
|
|
6086
6087
|
]
|
|
6087
6088
|
]);
|
|
6088
6089
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "FOOTING_PROFILE_FAILED", "Failed to create footing profile"));
|
|
6089
|
-
const profile = _usingCtx$
|
|
6090
|
+
const profile = _usingCtx$10.u(profileResult.value);
|
|
6090
6091
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6091
6092
|
0,
|
|
6092
6093
|
0,
|
|
@@ -6100,9 +6101,9 @@ function footingToSolid(spec) {
|
|
|
6100
6101
|
}
|
|
6101
6102
|
return (0, brepjs.ok)(solid);
|
|
6102
6103
|
} catch (_) {
|
|
6103
|
-
_usingCtx$
|
|
6104
|
+
_usingCtx$10.e = _;
|
|
6104
6105
|
} finally {
|
|
6105
|
-
_usingCtx$
|
|
6106
|
+
_usingCtx$10.d();
|
|
6106
6107
|
}
|
|
6107
6108
|
}
|
|
6108
6109
|
function pileToSolid(spec) {
|
|
@@ -6159,7 +6160,7 @@ function pileToSolid(spec) {
|
|
|
6159
6160
|
//#region src/elementFns/railingFns.ts
|
|
6160
6161
|
function panelRailing(spec) {
|
|
6161
6162
|
try {
|
|
6162
|
-
var _usingCtx$
|
|
6163
|
+
var _usingCtx$9 = _usingCtx();
|
|
6163
6164
|
const { length, height, thickness } = spec;
|
|
6164
6165
|
const profileResult = (0, brepjs.polygon)([
|
|
6165
6166
|
[
|
|
@@ -6184,7 +6185,7 @@ function panelRailing(spec) {
|
|
|
6184
6185
|
]
|
|
6185
6186
|
]);
|
|
6186
6187
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "RAILING_PROFILE_FAILED", "Failed to create railing profile"));
|
|
6187
|
-
const profile = _usingCtx$
|
|
6188
|
+
const profile = _usingCtx$9.u(profileResult.value);
|
|
6188
6189
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6189
6190
|
length,
|
|
6190
6191
|
0,
|
|
@@ -6198,9 +6199,9 @@ function panelRailing(spec) {
|
|
|
6198
6199
|
}
|
|
6199
6200
|
return (0, brepjs.ok)(solid);
|
|
6200
6201
|
} catch (_) {
|
|
6201
|
-
_usingCtx$
|
|
6202
|
+
_usingCtx$9.e = _;
|
|
6202
6203
|
} finally {
|
|
6203
|
-
_usingCtx$
|
|
6204
|
+
_usingCtx$9.d();
|
|
6204
6205
|
}
|
|
6205
6206
|
}
|
|
6206
6207
|
function postedRailing(spec) {
|
|
@@ -6263,7 +6264,7 @@ function railingToSolid(spec) {
|
|
|
6263
6264
|
//#region src/elementFns/coveringFns.ts
|
|
6264
6265
|
function coveringToSolid(spec) {
|
|
6265
6266
|
try {
|
|
6266
|
-
var _usingCtx$
|
|
6267
|
+
var _usingCtx$8 = _usingCtx();
|
|
6267
6268
|
if (spec.length <= 0) return (0, brepjs.err)(specError("COVERING_ZERO_LENGTH", "Covering length must be positive"));
|
|
6268
6269
|
if (spec.width <= 0) return (0, brepjs.err)(specError("COVERING_ZERO_WIDTH", "Covering width must be positive"));
|
|
6269
6270
|
if (spec.thickness <= 0) return (0, brepjs.err)(specError("COVERING_ZERO_THICKNESS", "Covering thickness must be positive"));
|
|
@@ -6291,7 +6292,7 @@ function coveringToSolid(spec) {
|
|
|
6291
6292
|
]
|
|
6292
6293
|
]);
|
|
6293
6294
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "COVERING_PROFILE_FAILED", "Failed to create covering profile"));
|
|
6294
|
-
const profile = _usingCtx$
|
|
6295
|
+
const profile = _usingCtx$8.u(profileResult.value);
|
|
6295
6296
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6296
6297
|
0,
|
|
6297
6298
|
0,
|
|
@@ -6305,13 +6306,29 @@ function coveringToSolid(spec) {
|
|
|
6305
6306
|
}
|
|
6306
6307
|
return (0, brepjs.ok)(solid);
|
|
6307
6308
|
} catch (_) {
|
|
6308
|
-
_usingCtx$
|
|
6309
|
+
_usingCtx$8.e = _;
|
|
6309
6310
|
} finally {
|
|
6310
|
-
_usingCtx$
|
|
6311
|
+
_usingCtx$8.d();
|
|
6312
|
+
}
|
|
6313
|
+
}
|
|
6314
|
+
//#endregion
|
|
6315
|
+
//#region src/types/productBody.ts
|
|
6316
|
+
/** Returns borrowed Product-local solids. The model retains ownership. */
|
|
6317
|
+
function bodySolids(body) {
|
|
6318
|
+
switch (body.kind) {
|
|
6319
|
+
case "PARAMETRIC": return [body.solid];
|
|
6320
|
+
case "EXACT": return body.solids;
|
|
6311
6321
|
}
|
|
6312
6322
|
}
|
|
6323
|
+
/** Model-owner cleanup. Borrowers must use {@link bodySolids} without disposing its items. */
|
|
6324
|
+
function disposeProductBody(body) {
|
|
6325
|
+
for (const solid of bodySolids(body)) solid[Symbol.dispose]();
|
|
6326
|
+
}
|
|
6313
6327
|
//#endregion
|
|
6314
6328
|
//#region src/model/bimModel.ts
|
|
6329
|
+
function exactWallBodyImmutable() {
|
|
6330
|
+
return (0, brepjs.err)(specError("EXACT_WALL_BODY_IMMUTABLE", "Cannot add an opening after a wall has taken an exact Product Body"));
|
|
6331
|
+
}
|
|
6315
6332
|
var BimModel = class {
|
|
6316
6333
|
#elements = /* @__PURE__ */ new Map();
|
|
6317
6334
|
#relationships = /* @__PURE__ */ new Map();
|
|
@@ -6330,7 +6347,8 @@ var BimModel = class {
|
|
|
6330
6347
|
return (0, brepjs.ok)(id);
|
|
6331
6348
|
}
|
|
6332
6349
|
[Symbol.dispose]() {
|
|
6333
|
-
for (const el of this.#elements.values()) if (el.category === "
|
|
6350
|
+
for (const el of this.#elements.values()) if (el.category === "SLAB" || el.category === "BEAM" || el.category === "COLUMN" || el.category === "PROXY" || el.category === "EARTHWORKS_FILL" || el.category === "SPACE" || el.category === "ROOF" || el.category === "FOOTING" || el.category === "PILE" || el.category === "COVERING") el.geometry[Symbol.dispose]();
|
|
6351
|
+
else if (el.category === "WALL" || el.category === "RAILING") disposeProductBody(el.geometry);
|
|
6334
6352
|
else if (el.category === "CURTAIN_WALL") {
|
|
6335
6353
|
for (const panel of el.geometry.panels) panel.solid[Symbol.dispose]();
|
|
6336
6354
|
for (const mullion of el.geometry.mullions) mullion.solid[Symbol.dispose]();
|
|
@@ -6391,7 +6409,10 @@ var BimModel = class {
|
|
|
6391
6409
|
if (!keyCheck.ok) return keyCheck;
|
|
6392
6410
|
const geomResult = wallToSolid(spec);
|
|
6393
6411
|
if (!geomResult.ok) return (0, brepjs.err)(geomResult.error);
|
|
6394
|
-
const id = this.#makeElement("WALL", spec,
|
|
6412
|
+
const id = this.#makeElement("WALL", spec, {
|
|
6413
|
+
kind: "PARAMETRIC",
|
|
6414
|
+
solid: geomResult.value
|
|
6415
|
+
}, options?.stableKey);
|
|
6395
6416
|
this.#associateMaterial(id, spec);
|
|
6396
6417
|
this.#associateClassification(id, spec);
|
|
6397
6418
|
return (0, brepjs.ok)(id);
|
|
@@ -6506,12 +6527,47 @@ var BimModel = class {
|
|
|
6506
6527
|
if (!keyCheck.ok) return keyCheck;
|
|
6507
6528
|
const geomResult = railingToSolid(spec);
|
|
6508
6529
|
if (!geomResult.ok) return (0, brepjs.err)(geomResult.error);
|
|
6509
|
-
const id = this.#makeElement("RAILING", spec,
|
|
6530
|
+
const id = this.#makeElement("RAILING", spec, {
|
|
6531
|
+
kind: "PARAMETRIC",
|
|
6532
|
+
solid: geomResult.value
|
|
6533
|
+
}, options?.stableKey);
|
|
6510
6534
|
this.#associateMaterial(id, spec);
|
|
6511
6535
|
this.#associateClassification(id, spec);
|
|
6512
6536
|
return (0, brepjs.ok)(id);
|
|
6513
6537
|
}
|
|
6514
6538
|
/**
|
|
6539
|
+
* Atomically replaces a parametric wall or railing Body with authoritative,
|
|
6540
|
+
* caller-owned exact solids. Success transfers every supplied handle to this
|
|
6541
|
+
* model. Failure leaves both the model and all supplied handles unchanged.
|
|
6542
|
+
*/
|
|
6543
|
+
takeExactProductBody(localId, body) {
|
|
6544
|
+
const target = this.#elements.get(localId);
|
|
6545
|
+
if (target === void 0) return (0, brepjs.err)(specError("EXACT_BODY_TARGET_NOT_FOUND", `No element found for localId ${localId}`));
|
|
6546
|
+
if (target.category !== "WALL" && target.category !== "RAILING") return (0, brepjs.err)(specError("EXACT_BODY_UNSUPPORTED_CATEGORY", `Exact Product Bodies are supported only for walls and railings, not ${target.category}`));
|
|
6547
|
+
if (target.geometry.kind === "EXACT") return (0, brepjs.err)(specError("EXACT_BODY_ALREADY_EXACT", `Element ${localId} already has an exact Product Body`));
|
|
6548
|
+
const solids = body.solids;
|
|
6549
|
+
if (solids.length === 0) return (0, brepjs.err)(specError("EXACT_BODY_EMPTY", "An exact Product Body must contain at least one solid"));
|
|
6550
|
+
if (solids.includes(target.geometry.solid)) return (0, brepjs.err)(specError("EXACT_BODY_SOLID_OWNERSHIP_CONFLICT", `Exact Product Body for ${localId} reuses the target parametric solid`));
|
|
6551
|
+
const identities = /* @__PURE__ */ new Set();
|
|
6552
|
+
for (const [itemIndex, solid] of solids.entries()) {
|
|
6553
|
+
if (identities.has(solid)) return (0, brepjs.err)(specError("EXACT_BODY_DUPLICATE_SOLID", `Exact Product Body item ${itemIndex} duplicates an earlier handle`));
|
|
6554
|
+
identities.add(solid);
|
|
6555
|
+
if (solid.disposed) return (0, brepjs.err)(specError("EXACT_BODY_SOLID_DISPOSED", `Exact Product Body item ${itemIndex} is already disposed`));
|
|
6556
|
+
try {
|
|
6557
|
+
if (!(0, brepjs.isValidSolid)(solid)) return (0, brepjs.err)(specError("EXACT_BODY_SOLID_INVALID", `Exact Product Body item ${itemIndex} is not a valid solid`));
|
|
6558
|
+
} catch (cause) {
|
|
6559
|
+
return (0, brepjs.err)(specError("EXACT_BODY_SOLID_INVALID", `Exact Product Body item ${itemIndex} could not be validated`, cause));
|
|
6560
|
+
}
|
|
6561
|
+
}
|
|
6562
|
+
const replaced = {
|
|
6563
|
+
...target,
|
|
6564
|
+
geometry: body
|
|
6565
|
+
};
|
|
6566
|
+
this.#elements.set(localId, replaced);
|
|
6567
|
+
disposeProductBody(target.geometry);
|
|
6568
|
+
return (0, brepjs.ok)(void 0);
|
|
6569
|
+
}
|
|
6570
|
+
/**
|
|
6515
6571
|
* Adds an IfcCovering. When `hostLocalId` is supplied, an
|
|
6516
6572
|
* IfcRelCoversBldgElements linking the covering to its host (e.g. a slab it
|
|
6517
6573
|
* finishes) is recorded for export.
|
|
@@ -6708,10 +6764,11 @@ var BimModel = class {
|
|
|
6708
6764
|
return (0, brepjs.ok)(id);
|
|
6709
6765
|
}
|
|
6710
6766
|
addDoor(spec, options) {
|
|
6711
|
-
const keyCheck = this.#checkOpeningKeys(options);
|
|
6712
|
-
if (!keyCheck.ok) return keyCheck;
|
|
6713
6767
|
const wall = this.#elements.get(spec.wallLocalId);
|
|
6714
6768
|
if (wall === void 0 || wall.category !== "WALL") return (0, brepjs.err)(specError("DOOR_WALL_NOT_FOUND", `No wall found for localId ${spec.wallLocalId}`));
|
|
6769
|
+
if (wall.geometry.kind === "EXACT") return exactWallBodyImmutable();
|
|
6770
|
+
const keyCheck = this.#checkOpeningKeys(options);
|
|
6771
|
+
if (!keyCheck.ok) return keyCheck;
|
|
6715
6772
|
if (spec.offsetAlongWall + spec.width > wall.spec.length) return (0, brepjs.err)(specError("DOOR_EXCEEDS_WALL_BOUNDS", "Door (offsetAlongWall + width) exceeds wall length"));
|
|
6716
6773
|
if (spec.offsetFromFloor + spec.height > wall.spec.height) return (0, brepjs.err)(specError("DOOR_EXCEEDS_WALL_BOUNDS", "Door (offsetFromFloor + height) exceeds wall height"));
|
|
6717
6774
|
const openingSpec = {
|
|
@@ -6744,10 +6801,11 @@ var BimModel = class {
|
|
|
6744
6801
|
return (0, brepjs.ok)(doorId);
|
|
6745
6802
|
}
|
|
6746
6803
|
addWindow(spec, options) {
|
|
6747
|
-
const keyCheck = this.#checkOpeningKeys(options);
|
|
6748
|
-
if (!keyCheck.ok) return keyCheck;
|
|
6749
6804
|
const wall = this.#elements.get(spec.wallLocalId);
|
|
6750
6805
|
if (wall === void 0 || wall.category !== "WALL") return (0, brepjs.err)(specError("WINDOW_WALL_NOT_FOUND", `No wall found for localId ${spec.wallLocalId}`));
|
|
6806
|
+
if (wall.geometry.kind === "EXACT") return exactWallBodyImmutable();
|
|
6807
|
+
const keyCheck = this.#checkOpeningKeys(options);
|
|
6808
|
+
if (!keyCheck.ok) return keyCheck;
|
|
6751
6809
|
if (spec.offsetAlongWall + spec.width > wall.spec.length) return (0, brepjs.err)(specError("WINDOW_EXCEEDS_WALL_BOUNDS", "Window (offsetAlongWall + width) exceeds wall length"));
|
|
6752
6810
|
if (spec.offsetFromFloor + spec.height > wall.spec.height) return (0, brepjs.err)(specError("WINDOW_EXCEEDS_WALL_BOUNDS", "Window (offsetFromFloor + height) exceeds wall height"));
|
|
6753
6811
|
const openingSpec = {
|
|
@@ -6821,27 +6879,31 @@ var BimModel = class {
|
|
|
6821
6879
|
}
|
|
6822
6880
|
#cutWallGeometry(wall, openingSpec) {
|
|
6823
6881
|
try {
|
|
6824
|
-
var _usingCtx$
|
|
6882
|
+
var _usingCtx$7 = _usingCtx();
|
|
6883
|
+
if (wall.geometry.kind === "EXACT") return exactWallBodyImmutable();
|
|
6825
6884
|
const toolResult = openingToSolid(openingSpec, wall.spec.thickness);
|
|
6826
6885
|
if (!toolResult.ok) return (0, brepjs.err)(toolResult.error);
|
|
6827
|
-
const tool = _usingCtx$
|
|
6828
|
-
const cutResult = (0, brepjs.cut)(wall.geometry, tool);
|
|
6886
|
+
const tool = _usingCtx$7.u(toolResult.value);
|
|
6887
|
+
const cutResult = (0, brepjs.cut)(wall.geometry.solid, tool);
|
|
6829
6888
|
if (!cutResult.ok) return (0, brepjs.err)(fromBrepError(cutResult.error, "WALL_CUT_FAILED", "Boolean cut of wall with opening failed"));
|
|
6830
6889
|
return (0, brepjs.ok)(cutResult.value);
|
|
6831
6890
|
} catch (_) {
|
|
6832
|
-
_usingCtx$
|
|
6891
|
+
_usingCtx$7.e = _;
|
|
6833
6892
|
} finally {
|
|
6834
|
-
_usingCtx$
|
|
6893
|
+
_usingCtx$7.d();
|
|
6835
6894
|
}
|
|
6836
6895
|
}
|
|
6837
6896
|
#replaceWallGeometry(wall, newGeometry) {
|
|
6838
6897
|
const oldGeometry = wall.geometry;
|
|
6839
6898
|
const replaced = {
|
|
6840
6899
|
...wall,
|
|
6841
|
-
geometry:
|
|
6900
|
+
geometry: {
|
|
6901
|
+
kind: "PARAMETRIC",
|
|
6902
|
+
solid: newGeometry
|
|
6903
|
+
}
|
|
6842
6904
|
};
|
|
6843
6905
|
this.#elements.set(wall.localId, replaced);
|
|
6844
|
-
oldGeometry
|
|
6906
|
+
disposeProductBody(oldGeometry);
|
|
6845
6907
|
}
|
|
6846
6908
|
#cutSlabGeometry(slab, openingSpec) {
|
|
6847
6909
|
try {
|
|
@@ -7100,6 +7162,129 @@ var BimModel = class {
|
|
|
7100
7162
|
}
|
|
7101
7163
|
};
|
|
7102
7164
|
//#endregion
|
|
7165
|
+
//#region src/elementFns/stairFns.ts
|
|
7166
|
+
function buildSilhouette$1(numberOfRisers, riserHeight, treadLength) {
|
|
7167
|
+
const pts = [];
|
|
7168
|
+
pts.push([
|
|
7169
|
+
0,
|
|
7170
|
+
0,
|
|
7171
|
+
0
|
|
7172
|
+
]);
|
|
7173
|
+
let x = 0;
|
|
7174
|
+
let z = 0;
|
|
7175
|
+
for (let i = 0; i < numberOfRisers; i++) {
|
|
7176
|
+
z += riserHeight;
|
|
7177
|
+
pts.push([
|
|
7178
|
+
x,
|
|
7179
|
+
0,
|
|
7180
|
+
z
|
|
7181
|
+
]);
|
|
7182
|
+
x += treadLength;
|
|
7183
|
+
pts.push([
|
|
7184
|
+
x,
|
|
7185
|
+
0,
|
|
7186
|
+
z
|
|
7187
|
+
]);
|
|
7188
|
+
}
|
|
7189
|
+
pts.push([
|
|
7190
|
+
x,
|
|
7191
|
+
0,
|
|
7192
|
+
0
|
|
7193
|
+
]);
|
|
7194
|
+
return pts;
|
|
7195
|
+
}
|
|
7196
|
+
function stairFlightToSolid(spec) {
|
|
7197
|
+
try {
|
|
7198
|
+
var _usingCtx$6 = _usingCtx();
|
|
7199
|
+
if (spec.width <= 0) return (0, brepjs.err)(specError("STAIR_FLIGHT_ZERO_WIDTH", "Stair flight width must be positive"));
|
|
7200
|
+
if (spec.riserHeight <= 0) return (0, brepjs.err)(specError("STAIR_FLIGHT_ZERO_RISER", "Stair flight riserHeight must be positive"));
|
|
7201
|
+
if (spec.treadLength <= 0) return (0, brepjs.err)(specError("STAIR_FLIGHT_ZERO_TREAD", "Stair flight treadLength must be positive"));
|
|
7202
|
+
if (!Number.isInteger(spec.numberOfRisers) || spec.numberOfRisers < 1) return (0, brepjs.err)(specError("STAIR_FLIGHT_BAD_RISERS", "Stair flight numberOfRisers must be a positive integer"));
|
|
7203
|
+
const silhouette = buildSilhouette$1(spec.numberOfRisers, spec.riserHeight, spec.treadLength);
|
|
7204
|
+
const profileResult = (0, brepjs.polygon)(silhouette);
|
|
7205
|
+
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "STAIR_FLIGHT_PROFILE_FAILED", "Failed to create stair flight silhouette profile"));
|
|
7206
|
+
const profile = _usingCtx$6.u(profileResult.value);
|
|
7207
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
7208
|
+
0,
|
|
7209
|
+
spec.width,
|
|
7210
|
+
0
|
|
7211
|
+
]);
|
|
7212
|
+
if (!solidResult.ok) return (0, brepjs.err)(fromBrepError(solidResult.error, "STAIR_FLIGHT_EXTRUDE_FAILED", "Failed to extrude stair flight silhouette"));
|
|
7213
|
+
const solid = solidResult.value;
|
|
7214
|
+
if (!(0, brepjs.isValidSolid)(solid)) {
|
|
7215
|
+
solid[Symbol.dispose]();
|
|
7216
|
+
return (0, brepjs.err)(geometryError("STAIR_FLIGHT_INVALID_SOLID", "Stair flight solid failed validity check"));
|
|
7217
|
+
}
|
|
7218
|
+
return (0, brepjs.ok)({
|
|
7219
|
+
solid,
|
|
7220
|
+
geometrySimplified: false
|
|
7221
|
+
});
|
|
7222
|
+
} catch (_) {
|
|
7223
|
+
_usingCtx$6.e = _;
|
|
7224
|
+
} finally {
|
|
7225
|
+
_usingCtx$6.d();
|
|
7226
|
+
}
|
|
7227
|
+
}
|
|
7228
|
+
//#endregion
|
|
7229
|
+
//#region src/elementFns/rampFns.ts
|
|
7230
|
+
function buildSilhouette(length, rise, thickness) {
|
|
7231
|
+
return [
|
|
7232
|
+
[
|
|
7233
|
+
0,
|
|
7234
|
+
0,
|
|
7235
|
+
-thickness
|
|
7236
|
+
],
|
|
7237
|
+
[
|
|
7238
|
+
length,
|
|
7239
|
+
0,
|
|
7240
|
+
rise - thickness
|
|
7241
|
+
],
|
|
7242
|
+
[
|
|
7243
|
+
length,
|
|
7244
|
+
0,
|
|
7245
|
+
rise
|
|
7246
|
+
],
|
|
7247
|
+
[
|
|
7248
|
+
0,
|
|
7249
|
+
0,
|
|
7250
|
+
0
|
|
7251
|
+
]
|
|
7252
|
+
];
|
|
7253
|
+
}
|
|
7254
|
+
function rampFlightToSolid(spec) {
|
|
7255
|
+
try {
|
|
7256
|
+
var _usingCtx$5 = _usingCtx();
|
|
7257
|
+
if (spec.width <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_WIDTH", "Ramp flight width must be positive"));
|
|
7258
|
+
if (spec.length <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_LENGTH", "Ramp flight length must be positive"));
|
|
7259
|
+
if (spec.slope <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_SLOPE", "Ramp flight slope must be positive"));
|
|
7260
|
+
if (spec.thickness <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_THICKNESS", "Ramp flight thickness must be positive"));
|
|
7261
|
+
const rise = spec.length * spec.slope;
|
|
7262
|
+
const silhouette = buildSilhouette(spec.length, rise, spec.thickness);
|
|
7263
|
+
const profileResult = (0, brepjs.polygon)(silhouette);
|
|
7264
|
+
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "RAMP_FLIGHT_PROFILE_FAILED", "Failed to create ramp flight silhouette profile"));
|
|
7265
|
+
const profile = _usingCtx$5.u(profileResult.value);
|
|
7266
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
7267
|
+
0,
|
|
7268
|
+
spec.width,
|
|
7269
|
+
0
|
|
7270
|
+
]);
|
|
7271
|
+
if (!solidResult.ok) return (0, brepjs.err)(fromBrepError(solidResult.error, "RAMP_FLIGHT_EXTRUDE_FAILED", "Failed to extrude ramp flight silhouette"));
|
|
7272
|
+
const solid = solidResult.value;
|
|
7273
|
+
if (!(0, brepjs.isValidSolid)(solid)) {
|
|
7274
|
+
solid[Symbol.dispose]();
|
|
7275
|
+
return (0, brepjs.err)(geometryError("RAMP_FLIGHT_INVALID_SOLID", "Ramp flight solid failed validity check"));
|
|
7276
|
+
}
|
|
7277
|
+
return (0, brepjs.ok)({
|
|
7278
|
+
solid,
|
|
7279
|
+
geometrySimplified: true
|
|
7280
|
+
});
|
|
7281
|
+
} catch (_) {
|
|
7282
|
+
_usingCtx$5.e = _;
|
|
7283
|
+
} finally {
|
|
7284
|
+
_usingCtx$5.d();
|
|
7285
|
+
}
|
|
7286
|
+
}
|
|
7287
|
+
//#endregion
|
|
7103
7288
|
//#region src/import/placement.ts
|
|
7104
7289
|
/**
|
|
7105
7290
|
* Metres-per-file-unit length scale read from the IfcUnitAssignment's
|
|
@@ -7307,148 +7492,100 @@ function enumValue(v) {
|
|
|
7307
7492
|
return typeof value === "string" ? value : null;
|
|
7308
7493
|
}
|
|
7309
7494
|
//#endregion
|
|
7310
|
-
//#region src/
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
const
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
_usingCtx$5.d();
|
|
7371
|
-
}
|
|
7372
|
-
}
|
|
7373
|
-
//#endregion
|
|
7374
|
-
//#region src/elementFns/rampFns.ts
|
|
7375
|
-
function buildSilhouette(length, rise, thickness) {
|
|
7376
|
-
return [
|
|
7377
|
-
[
|
|
7378
|
-
0,
|
|
7379
|
-
0,
|
|
7380
|
-
-thickness
|
|
7381
|
-
],
|
|
7382
|
-
[
|
|
7383
|
-
length,
|
|
7384
|
-
0,
|
|
7385
|
-
rise - thickness
|
|
7386
|
-
],
|
|
7387
|
-
[
|
|
7388
|
-
length,
|
|
7389
|
-
0,
|
|
7390
|
-
rise
|
|
7391
|
-
],
|
|
7392
|
-
[
|
|
7393
|
-
0,
|
|
7394
|
-
0,
|
|
7395
|
-
0
|
|
7396
|
-
]
|
|
7495
|
+
//#region src/rigidPlacement.ts
|
|
7496
|
+
var RAD_TO_DEG = 180 / Math.PI;
|
|
7497
|
+
var ROTATION_EPSILON = 1e-12;
|
|
7498
|
+
/** Applies a rigid placement as a location so the source BRep is not rebuilt. */
|
|
7499
|
+
function locateShapeInFrame(shape, frame) {
|
|
7500
|
+
return (0, brepjs.locate)(shape, placementOps(frame));
|
|
7501
|
+
}
|
|
7502
|
+
function placementOps(frame) {
|
|
7503
|
+
const matrix = placementToMatrix(frame);
|
|
7504
|
+
const rotation = rotationOp(matrix.linear);
|
|
7505
|
+
const translation = {
|
|
7506
|
+
type: "translate",
|
|
7507
|
+
v: matrix.translation
|
|
7508
|
+
};
|
|
7509
|
+
return rotation === null ? [translation] : [rotation, translation];
|
|
7510
|
+
}
|
|
7511
|
+
function rotationOp(matrix) {
|
|
7512
|
+
const [m00, m01, m02, m10, m11, m12, m20, m21, m22] = matrix;
|
|
7513
|
+
const trace = m00 + m11 + m22;
|
|
7514
|
+
let w;
|
|
7515
|
+
let x;
|
|
7516
|
+
let y;
|
|
7517
|
+
let z;
|
|
7518
|
+
if (trace > 0) {
|
|
7519
|
+
const scale = 2 * Math.sqrt(trace + 1);
|
|
7520
|
+
w = scale / 4;
|
|
7521
|
+
x = (m21 - m12) / scale;
|
|
7522
|
+
y = (m02 - m20) / scale;
|
|
7523
|
+
z = (m10 - m01) / scale;
|
|
7524
|
+
} else if (m00 > m11 && m00 > m22) {
|
|
7525
|
+
const scale = 2 * Math.sqrt(1 + m00 - m11 - m22);
|
|
7526
|
+
w = (m21 - m12) / scale;
|
|
7527
|
+
x = scale / 4;
|
|
7528
|
+
y = (m01 + m10) / scale;
|
|
7529
|
+
z = (m02 + m20) / scale;
|
|
7530
|
+
} else if (m11 > m22) {
|
|
7531
|
+
const scale = 2 * Math.sqrt(1 + m11 - m00 - m22);
|
|
7532
|
+
w = (m02 - m20) / scale;
|
|
7533
|
+
x = (m01 + m10) / scale;
|
|
7534
|
+
y = scale / 4;
|
|
7535
|
+
z = (m12 + m21) / scale;
|
|
7536
|
+
} else {
|
|
7537
|
+
const scale = 2 * Math.sqrt(1 + m22 - m00 - m11);
|
|
7538
|
+
w = (m10 - m01) / scale;
|
|
7539
|
+
x = (m02 + m20) / scale;
|
|
7540
|
+
y = (m12 + m21) / scale;
|
|
7541
|
+
z = scale / 4;
|
|
7542
|
+
}
|
|
7543
|
+
const length = Math.hypot(w, x, y, z);
|
|
7544
|
+
const sign = w < 0 ? -1 : 1;
|
|
7545
|
+
const normalizedW = sign * w / length;
|
|
7546
|
+
const normalizedX = sign * x / length;
|
|
7547
|
+
const normalizedY = sign * y / length;
|
|
7548
|
+
const normalizedZ = sign * z / length;
|
|
7549
|
+
const sinHalfAngle = Math.hypot(normalizedX, normalizedY, normalizedZ);
|
|
7550
|
+
if (sinHalfAngle < ROTATION_EPSILON) return null;
|
|
7551
|
+
const axis = [
|
|
7552
|
+
normalizedX / sinHalfAngle,
|
|
7553
|
+
normalizedY / sinHalfAngle,
|
|
7554
|
+
normalizedZ / sinHalfAngle
|
|
7397
7555
|
];
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
if (spec.length <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_LENGTH", "Ramp flight length must be positive"));
|
|
7404
|
-
if (spec.slope <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_SLOPE", "Ramp flight slope must be positive"));
|
|
7405
|
-
if (spec.thickness <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_THICKNESS", "Ramp flight thickness must be positive"));
|
|
7406
|
-
const rise = spec.length * spec.slope;
|
|
7407
|
-
const silhouette = buildSilhouette(spec.length, rise, spec.thickness);
|
|
7408
|
-
const profileResult = (0, brepjs.polygon)(silhouette);
|
|
7409
|
-
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "RAMP_FLIGHT_PROFILE_FAILED", "Failed to create ramp flight silhouette profile"));
|
|
7410
|
-
const profile = _usingCtx$4.u(profileResult.value);
|
|
7411
|
-
const solidResult = (0, brepjs.extrude)(profile, [
|
|
7412
|
-
0,
|
|
7413
|
-
spec.width,
|
|
7414
|
-
0
|
|
7415
|
-
]);
|
|
7416
|
-
if (!solidResult.ok) return (0, brepjs.err)(fromBrepError(solidResult.error, "RAMP_FLIGHT_EXTRUDE_FAILED", "Failed to extrude ramp flight silhouette"));
|
|
7417
|
-
const solid = solidResult.value;
|
|
7418
|
-
if (!(0, brepjs.isValidSolid)(solid)) {
|
|
7419
|
-
solid[Symbol.dispose]();
|
|
7420
|
-
return (0, brepjs.err)(geometryError("RAMP_FLIGHT_INVALID_SOLID", "Ramp flight solid failed validity check"));
|
|
7421
|
-
}
|
|
7422
|
-
return (0, brepjs.ok)({
|
|
7423
|
-
solid,
|
|
7424
|
-
geometrySimplified: true
|
|
7425
|
-
});
|
|
7426
|
-
} catch (_) {
|
|
7427
|
-
_usingCtx$4.e = _;
|
|
7428
|
-
} finally {
|
|
7429
|
-
_usingCtx$4.d();
|
|
7430
|
-
}
|
|
7556
|
+
return {
|
|
7557
|
+
type: "rotate",
|
|
7558
|
+
angle: 2 * Math.atan2(sinHalfAngle, normalizedW) * RAD_TO_DEG,
|
|
7559
|
+
axis
|
|
7560
|
+
};
|
|
7431
7561
|
}
|
|
7432
7562
|
//#endregion
|
|
7433
7563
|
//#region src/elementFns/placedGeometry.ts
|
|
7564
|
+
var testHooks$3 = null;
|
|
7434
7565
|
function place(solid, frame) {
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7566
|
+
let placed = null;
|
|
7567
|
+
try {
|
|
7568
|
+
placed = locateShapeInFrame(solid, frame);
|
|
7569
|
+
testHooks$3?.afterPlaced?.(placed);
|
|
7570
|
+
return (0, brepjs.ok)(placed);
|
|
7571
|
+
} catch (cause) {
|
|
7572
|
+
placed?.[Symbol.dispose]();
|
|
7573
|
+
return (0, brepjs.err)(geometryError("PLACED_GEOMETRY_FAILED", "Element placement threw while transforming geometry", cause));
|
|
7574
|
+
}
|
|
7438
7575
|
}
|
|
7439
7576
|
function disposeAll(solids) {
|
|
7440
7577
|
for (const s of solids) s[Symbol.dispose]();
|
|
7441
7578
|
}
|
|
7442
7579
|
function placeWithinParent(solid, localFrame, parentFrame) {
|
|
7443
7580
|
try {
|
|
7444
|
-
var _usingCtx$
|
|
7581
|
+
var _usingCtx$4 = _usingCtx();
|
|
7445
7582
|
const local = place(solid, localFrame);
|
|
7446
7583
|
if (!local.ok || parentFrame === void 0) return local;
|
|
7447
|
-
return place(_usingCtx$
|
|
7584
|
+
return place(_usingCtx$4.u(local.value), parentFrame);
|
|
7448
7585
|
} catch (_) {
|
|
7449
|
-
_usingCtx$
|
|
7586
|
+
_usingCtx$4.e = _;
|
|
7450
7587
|
} finally {
|
|
7451
|
-
_usingCtx$
|
|
7588
|
+
_usingCtx$4.d();
|
|
7452
7589
|
}
|
|
7453
7590
|
}
|
|
7454
7591
|
/**
|
|
@@ -7473,6 +7610,18 @@ function placedSolids(el, options = {}) {
|
|
|
7473
7610
|
const parentFrame = options.parentFrame;
|
|
7474
7611
|
switch (el.category) {
|
|
7475
7612
|
case "WALL":
|
|
7613
|
+
case "RAILING": {
|
|
7614
|
+
const out = [];
|
|
7615
|
+
for (const solid of bodySolids(el.geometry)) {
|
|
7616
|
+
const placed = placeWithinParent(solid, el.spec, parentFrame);
|
|
7617
|
+
if (!placed.ok) {
|
|
7618
|
+
disposeAll(out);
|
|
7619
|
+
return placed;
|
|
7620
|
+
}
|
|
7621
|
+
out.push(placed.value);
|
|
7622
|
+
}
|
|
7623
|
+
return (0, brepjs.ok)(out);
|
|
7624
|
+
}
|
|
7476
7625
|
case "SLAB":
|
|
7477
7626
|
case "BEAM":
|
|
7478
7627
|
case "COLUMN":
|
|
@@ -7480,8 +7629,7 @@ function placedSolids(el, options = {}) {
|
|
|
7480
7629
|
case "ROOF":
|
|
7481
7630
|
case "FOOTING":
|
|
7482
7631
|
case "PILE":
|
|
7483
|
-
case "COVERING":
|
|
7484
|
-
case "RAILING": {
|
|
7632
|
+
case "COVERING": {
|
|
7485
7633
|
const placed = placeWithinParent(el.geometry, el.spec, parentFrame);
|
|
7486
7634
|
if (!placed.ok) return placed;
|
|
7487
7635
|
return (0, brepjs.ok)([placed.value]);
|
|
@@ -7680,6 +7828,7 @@ async function initIfcApi(api) {
|
|
|
7680
7828
|
}
|
|
7681
7829
|
//#endregion
|
|
7682
7830
|
//#region src/ifc-writer/ifcWriter.ts
|
|
7831
|
+
var testHooks$2 = null;
|
|
7683
7832
|
/** Default MVD ViewDefinition declared in the STEP FILE_DESCRIPTION header. */
|
|
7684
7833
|
var DEFAULT_MVD_VIEW_DEFINITION = "ReferenceView_v1.2";
|
|
7685
7834
|
var VIEW_DEFINITION_RE = /ViewDefinition \[[^\]]*\]/;
|
|
@@ -7720,6 +7869,10 @@ var IfcWriter = class IfcWriter {
|
|
|
7720
7869
|
return (0, brepjs.err)(ifcError("IFC_INIT_FAILED", "Failed to initialize web-ifc", e));
|
|
7721
7870
|
}
|
|
7722
7871
|
}
|
|
7872
|
+
/** Package-internal lifecycle seam for deterministic writer cleanup tests. */
|
|
7873
|
+
static fromApiForTesting(api, modelId = 0) {
|
|
7874
|
+
return new IfcWriter(api, modelId, DEFAULT_MVD_VIEW_DEFINITION, {});
|
|
7875
|
+
}
|
|
7723
7876
|
nextId() {
|
|
7724
7877
|
return this.#nextExpressId++;
|
|
7725
7878
|
}
|
|
@@ -7737,6 +7890,7 @@ var IfcWriter = class IfcWriter {
|
|
|
7737
7890
|
}
|
|
7738
7891
|
writeLine(entity) {
|
|
7739
7892
|
this.#api.WriteLine(this.#modelId, entity);
|
|
7893
|
+
testHooks$2?.afterWriteLine?.();
|
|
7740
7894
|
return entity.expressID;
|
|
7741
7895
|
}
|
|
7742
7896
|
ref(id) {
|
|
@@ -7745,6 +7899,15 @@ var IfcWriter = class IfcWriter {
|
|
|
7745
7899
|
mkType(type, value) {
|
|
7746
7900
|
return this.#api.CreateIfcType(this.#modelId, type, value);
|
|
7747
7901
|
}
|
|
7902
|
+
close() {
|
|
7903
|
+
if (this.#closed) return;
|
|
7904
|
+
this.#closed = true;
|
|
7905
|
+
this.#api.CloseModel(this.#modelId);
|
|
7906
|
+
testHooks$2?.afterClose?.();
|
|
7907
|
+
}
|
|
7908
|
+
[Symbol.dispose]() {
|
|
7909
|
+
this.close();
|
|
7910
|
+
}
|
|
7748
7911
|
save() {
|
|
7749
7912
|
if (this.#closed) return (0, brepjs.err)(ifcError("IFC_ALREADY_SAVED", "Model has already been saved and closed"));
|
|
7750
7913
|
try {
|
|
@@ -7753,8 +7916,7 @@ var IfcWriter = class IfcWriter {
|
|
|
7753
7916
|
} catch (e) {
|
|
7754
7917
|
return (0, brepjs.err)(ifcError("IFC_SAVE_FAILED", "Failed to serialize IFC model", e));
|
|
7755
7918
|
} finally {
|
|
7756
|
-
this
|
|
7757
|
-
this.#closed = true;
|
|
7919
|
+
this.close();
|
|
7758
7920
|
}
|
|
7759
7921
|
}
|
|
7760
7922
|
/**
|
|
@@ -8301,6 +8463,45 @@ function writeColumnEntity(w, guid, name, _predefinedType, ownerHistoryId, local
|
|
|
8301
8463
|
//#region src/ifc-writer/tessellationWriter.ts
|
|
8302
8464
|
var IFC_MESH_TOLERANCE_MM = 5;
|
|
8303
8465
|
var IFC_MESH_ANGULAR_TOLERANCE_RAD = .3;
|
|
8466
|
+
function prepareTessellation(solid, toleranceMm = IFC_MESH_TOLERANCE_MM) {
|
|
8467
|
+
let meshData;
|
|
8468
|
+
try {
|
|
8469
|
+
meshData = (0, brepjs.mesh)(solid, {
|
|
8470
|
+
tolerance: toleranceMm,
|
|
8471
|
+
angularTolerance: IFC_MESH_ANGULAR_TOLERANCE_RAD
|
|
8472
|
+
});
|
|
8473
|
+
} catch (cause) {
|
|
8474
|
+
return {
|
|
8475
|
+
ok: false,
|
|
8476
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
8477
|
+
cause
|
|
8478
|
+
};
|
|
8479
|
+
}
|
|
8480
|
+
const { vertices, triangles } = meshData;
|
|
8481
|
+
if (vertices.length === 0 || triangles.length === 0) return {
|
|
8482
|
+
ok: false,
|
|
8483
|
+
reason: "mesh() returned an empty triangle set"
|
|
8484
|
+
};
|
|
8485
|
+
const coordList = [];
|
|
8486
|
+
for (let i = 0; i + 2 < vertices.length; i += 3) coordList.push([
|
|
8487
|
+
toIfcLengthM(vertices[i] ?? 0),
|
|
8488
|
+
toIfcLengthM(vertices[i + 1] ?? 0),
|
|
8489
|
+
toIfcLengthM(vertices[i + 2] ?? 0)
|
|
8490
|
+
]);
|
|
8491
|
+
const coordIndex = [];
|
|
8492
|
+
for (let i = 0; i + 2 < triangles.length; i += 3) coordIndex.push([
|
|
8493
|
+
(triangles[i] ?? 0) + 1,
|
|
8494
|
+
(triangles[i + 1] ?? 0) + 1,
|
|
8495
|
+
(triangles[i + 2] ?? 0) + 1
|
|
8496
|
+
]);
|
|
8497
|
+
return {
|
|
8498
|
+
ok: true,
|
|
8499
|
+
value: {
|
|
8500
|
+
coordList,
|
|
8501
|
+
coordIndex
|
|
8502
|
+
}
|
|
8503
|
+
};
|
|
8504
|
+
}
|
|
8304
8505
|
/**
|
|
8305
8506
|
* Writes an IfcTriangulatedFaceSet (preferred IFC4 tessellation) from a brepjs
|
|
8306
8507
|
* ValidSolid, wrapped in an IfcShapeRepresentation (Body/Tessellation) and an
|
|
@@ -8319,52 +8520,20 @@ var IFC_MESH_ANGULAR_TOLERANCE_RAD = .3;
|
|
|
8319
8520
|
* shape representation, so it is not referenced here.
|
|
8320
8521
|
*/
|
|
8321
8522
|
function writeTessellation(w, solid, geomSubContextId, _localPlacementId, toleranceMm = IFC_MESH_TOLERANCE_MM) {
|
|
8322
|
-
|
|
8323
|
-
|
|
8324
|
-
|
|
8325
|
-
tolerance: toleranceMm,
|
|
8326
|
-
angularTolerance: IFC_MESH_ANGULAR_TOLERANCE_RAD
|
|
8327
|
-
});
|
|
8328
|
-
} catch (e) {
|
|
8329
|
-
const reason = e instanceof Error ? e.message : String(e);
|
|
8523
|
+
const prepared = prepareTessellation(solid, toleranceMm);
|
|
8524
|
+
if (!prepared.ok) {
|
|
8525
|
+
const reason = prepared.reason;
|
|
8330
8526
|
console.warn(`writeTessellation: mesh() failed, using IfcFacetedBrep fallback: ${reason}`);
|
|
8331
8527
|
return writeFacetedBrepFallback(w, geomSubContextId, reason);
|
|
8332
8528
|
}
|
|
8333
|
-
const {
|
|
8334
|
-
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
toIfcLengthM(vertices[i] ?? 0),
|
|
8342
|
-
toIfcLengthM(vertices[i + 1] ?? 0),
|
|
8343
|
-
toIfcLengthM(vertices[i + 2] ?? 0)
|
|
8344
|
-
]);
|
|
8345
|
-
const pointListId = w.nextId();
|
|
8346
|
-
w.writeLine({
|
|
8347
|
-
expressID: pointListId,
|
|
8348
|
-
type: web_ifc.IFCCARTESIANPOINTLIST3D,
|
|
8349
|
-
CoordList: coordList.map((pt) => pt.map((v) => w.mkType(web_ifc.IFCLENGTHMEASURE, v))),
|
|
8350
|
-
TagList: null
|
|
8351
|
-
});
|
|
8352
|
-
const coordIndex = [];
|
|
8353
|
-
for (let i = 0; i + 2 < triangles.length; i += 3) coordIndex.push([
|
|
8354
|
-
(triangles[i] ?? 0) + 1,
|
|
8355
|
-
(triangles[i + 1] ?? 0) + 1,
|
|
8356
|
-
(triangles[i + 2] ?? 0) + 1
|
|
8357
|
-
]);
|
|
8358
|
-
const faceSetId = w.nextId();
|
|
8359
|
-
w.writeLine({
|
|
8360
|
-
expressID: faceSetId,
|
|
8361
|
-
type: web_ifc.IFCTRIANGULATEDFACESET,
|
|
8362
|
-
Coordinates: w.ref(pointListId),
|
|
8363
|
-
Normals: null,
|
|
8364
|
-
Closed: w.mkType(web_ifc.IFCBOOLEAN, true),
|
|
8365
|
-
CoordIndex: coordIndex.map((tri) => tri.map((idx) => w.mkType(web_ifc.IFCPOSITIVEINTEGER, idx))),
|
|
8366
|
-
PnIndex: null
|
|
8367
|
-
});
|
|
8529
|
+
const { productDefinitionShapeId } = writePreparedTessellationBody(w, [prepared.value], geomSubContextId);
|
|
8530
|
+
return {
|
|
8531
|
+
productDefinitionShapeId,
|
|
8532
|
+
usedFallback: false
|
|
8533
|
+
};
|
|
8534
|
+
}
|
|
8535
|
+
function writePreparedTessellationBody(w, items, geomSubContextId) {
|
|
8536
|
+
const bodyItemIds = items.map((item) => writePreparedTessellationItem(w, item));
|
|
8368
8537
|
const shapeRepId = w.nextId();
|
|
8369
8538
|
w.writeLine({
|
|
8370
8539
|
expressID: shapeRepId,
|
|
@@ -8372,7 +8541,7 @@ function writeTessellation(w, solid, geomSubContextId, _localPlacementId, tolera
|
|
|
8372
8541
|
ContextOfItems: w.ref(geomSubContextId),
|
|
8373
8542
|
RepresentationIdentifier: w.mkType(web_ifc.IFCLABEL, "Body"),
|
|
8374
8543
|
RepresentationType: w.mkType(web_ifc.IFCLABEL, "Tessellation"),
|
|
8375
|
-
Items:
|
|
8544
|
+
Items: bodyItemIds.map((id) => w.ref(id))
|
|
8376
8545
|
});
|
|
8377
8546
|
const productDefinitionShapeId = w.nextId();
|
|
8378
8547
|
w.writeLine({
|
|
@@ -8384,9 +8553,55 @@ function writeTessellation(w, solid, geomSubContextId, _localPlacementId, tolera
|
|
|
8384
8553
|
});
|
|
8385
8554
|
return {
|
|
8386
8555
|
productDefinitionShapeId,
|
|
8387
|
-
|
|
8556
|
+
bodyItemIds
|
|
8557
|
+
};
|
|
8558
|
+
}
|
|
8559
|
+
function writeExactBodyGeometry(w, placement, items, geomSubContextId, parentPlacementId) {
|
|
8560
|
+
const placement3DId = writeAxis2Placement3D(w, [
|
|
8561
|
+
toIfcLengthM(placement.origin[0]),
|
|
8562
|
+
toIfcLengthM(placement.origin[1]),
|
|
8563
|
+
toIfcLengthM(placement.origin[2])
|
|
8564
|
+
], [
|
|
8565
|
+
placement.axisZ[0],
|
|
8566
|
+
placement.axisZ[1],
|
|
8567
|
+
placement.axisZ[2]
|
|
8568
|
+
], [
|
|
8569
|
+
placement.axisX[0],
|
|
8570
|
+
placement.axisX[1],
|
|
8571
|
+
placement.axisX[2]
|
|
8572
|
+
]);
|
|
8573
|
+
const localPlacementId = w.nextId();
|
|
8574
|
+
w.writeLine({
|
|
8575
|
+
expressID: localPlacementId,
|
|
8576
|
+
type: web_ifc.IFCLOCALPLACEMENT,
|
|
8577
|
+
PlacementRelTo: parentPlacementId === null ? null : w.ref(parentPlacementId),
|
|
8578
|
+
RelativePlacement: w.ref(placement3DId)
|
|
8579
|
+
});
|
|
8580
|
+
return {
|
|
8581
|
+
localPlacementId,
|
|
8582
|
+
...writePreparedTessellationBody(w, items, geomSubContextId)
|
|
8388
8583
|
};
|
|
8389
8584
|
}
|
|
8585
|
+
function writePreparedTessellationItem(w, prepared) {
|
|
8586
|
+
const pointListId = w.nextId();
|
|
8587
|
+
w.writeLine({
|
|
8588
|
+
expressID: pointListId,
|
|
8589
|
+
type: web_ifc.IFCCARTESIANPOINTLIST3D,
|
|
8590
|
+
CoordList: prepared.coordList.map((point) => point.map((value) => w.mkType(web_ifc.IFCLENGTHMEASURE, value))),
|
|
8591
|
+
TagList: null
|
|
8592
|
+
});
|
|
8593
|
+
const faceSetId = w.nextId();
|
|
8594
|
+
w.writeLine({
|
|
8595
|
+
expressID: faceSetId,
|
|
8596
|
+
type: web_ifc.IFCTRIANGULATEDFACESET,
|
|
8597
|
+
Coordinates: w.ref(pointListId),
|
|
8598
|
+
Normals: null,
|
|
8599
|
+
Closed: w.mkType(web_ifc.IFCBOOLEAN, true),
|
|
8600
|
+
CoordIndex: prepared.coordIndex.map((triangle) => triangle.map((index) => w.mkType(web_ifc.IFCPOSITIVEINTEGER, index))),
|
|
8601
|
+
PnIndex: null
|
|
8602
|
+
});
|
|
8603
|
+
return faceSetId;
|
|
8604
|
+
}
|
|
8390
8605
|
/**
|
|
8391
8606
|
* Builds a wall 'Axis' IfcShapeRepresentation: an IfcPolyline from (0,0) to
|
|
8392
8607
|
* (lengthM, 0) in the wall's local XY plane, wrapped in an IfcShapeRepresentation
|
|
@@ -9883,22 +10098,22 @@ function writeStairAssembly(w, spec, stairKey, assemblyGuid, ownerHistoryId, geo
|
|
|
9883
10098
|
const flightExpressIds = [];
|
|
9884
10099
|
let geometrySimplified = false;
|
|
9885
10100
|
for (const [i, flight] of spec.flights.entries()) try {
|
|
9886
|
-
var _usingCtx$
|
|
10101
|
+
var _usingCtx$3 = _usingCtx();
|
|
9887
10102
|
const built = stairFlightToSolid(flight);
|
|
9888
10103
|
if (!built.ok) return {
|
|
9889
10104
|
ok: false,
|
|
9890
10105
|
error: built.error
|
|
9891
10106
|
};
|
|
9892
|
-
const flightSolid = _usingCtx$
|
|
10107
|
+
const flightSolid = _usingCtx$3.u(built.value.solid);
|
|
9893
10108
|
const flightPlacementId = writeLocalPlacement(w, flight.origin, flight.axisZ, flight.axisX, stairPlacementId);
|
|
9894
10109
|
const tess = writeTessellation(w, flightSolid, geomSubContextId, flightPlacementId);
|
|
9895
10110
|
if (tess.usedFallback) geometrySimplified = true;
|
|
9896
10111
|
const flightExpressId = writeStairFlightEntity(w, deriveIfcGuidSync(`elem:STAIR_FLIGHT:${stairKey}:${i}`), `${stairName} Flight ${i + 1}`, flight, ownerHistoryId, flightPlacementId, tess.productDefinitionShapeId);
|
|
9897
10112
|
flightExpressIds.push(flightExpressId);
|
|
9898
10113
|
} catch (_) {
|
|
9899
|
-
_usingCtx$
|
|
10114
|
+
_usingCtx$3.e = _;
|
|
9900
10115
|
} finally {
|
|
9901
|
-
_usingCtx$
|
|
10116
|
+
_usingCtx$3.d();
|
|
9902
10117
|
}
|
|
9903
10118
|
writeRelAggregates(w, deriveIfcGuidSync(`rel:AGGREGATES:STAIR:${stairKey}`), ownerHistoryId, assemblyExpressId, flightExpressIds);
|
|
9904
10119
|
writeAssemblyType(w, web_ifc.IFCSTAIRTYPE, "Stair Type", deriveIfcGuidSync(`type:STAIR:${stairKey}`), deriveIfcGuidSync(`rel-type:STAIR:${stairKey}`), predefinedType, ownerHistoryId, [assemblyExpressId]);
|
|
@@ -11293,6 +11508,14 @@ function writeWallBaseQuantities(w, ownerHistoryId, wallExpressId, spec, opening
|
|
|
11293
11508
|
pushWeightQuantity(w, qtyIds, netVolumeM3, densityKgM3);
|
|
11294
11509
|
writeRelDefinesByProperties(w, ownerHistoryId, wallExpressId, writeElementQuantity(w, ownerHistoryId, "Qto_WallBaseQuantities", qtyIds));
|
|
11295
11510
|
}
|
|
11511
|
+
function writeExactWallBaseQuantities(w, ownerHistoryId, wallExpressId, values) {
|
|
11512
|
+
writeRelDefinesByProperties(w, ownerHistoryId, wallExpressId, writeElementQuantity(w, ownerHistoryId, "Qto_WallBaseQuantities", [
|
|
11513
|
+
writeQtyLength(w, "Length", values.lengthM),
|
|
11514
|
+
writeQtyLength(w, "Width", values.widthM),
|
|
11515
|
+
writeQtyLength(w, "Height", values.heightM),
|
|
11516
|
+
writeQtyVolume(w, "NetVolume", values.netVolumeM3)
|
|
11517
|
+
]));
|
|
11518
|
+
}
|
|
11296
11519
|
function writeSlabCommonPset(w, ownerHistoryId, slabExpressId, spec) {
|
|
11297
11520
|
const values = {};
|
|
11298
11521
|
if (spec.isExternal !== void 0) values["IsExternal"] = spec.isExternal;
|
|
@@ -13305,457 +13528,580 @@ function checkGeoreferencing(reader) {
|
|
|
13305
13528
|
return [issue("warning", "NO_GEOREFERENCING", "Model contains a facility but no IfcProjectedCRS/IfcGeographicCRS (GRF003) — set ProjectSpec.crs")];
|
|
13306
13529
|
}
|
|
13307
13530
|
//#endregion
|
|
13308
|
-
//#region src/serialize/
|
|
13309
|
-
|
|
13310
|
-
|
|
13311
|
-
|
|
13312
|
-
|
|
13313
|
-
const
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
|
|
13317
|
-
|
|
13318
|
-
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
const
|
|
13322
|
-
const
|
|
13323
|
-
|
|
13324
|
-
const
|
|
13325
|
-
const
|
|
13326
|
-
|
|
13327
|
-
|
|
13328
|
-
|
|
13329
|
-
const columns = model.getColumns();
|
|
13330
|
-
const doors = model.getDoors();
|
|
13331
|
-
const windows = model.getWindows();
|
|
13332
|
-
const proxies = model.getProxies();
|
|
13333
|
-
const spaces = model.getSpaces();
|
|
13334
|
-
const roofs = model.getRoofs();
|
|
13335
|
-
const curtainWalls = model.getCurtainWalls();
|
|
13336
|
-
const footings = model.getFootings();
|
|
13337
|
-
const piles = model.getPiles();
|
|
13338
|
-
const stairs = model.getStairs();
|
|
13339
|
-
const ramps = model.getRamps();
|
|
13340
|
-
const railings = model.getRailings();
|
|
13341
|
-
const coverings = model.getCoverings();
|
|
13342
|
-
const assemblies = model.getElementAssemblies();
|
|
13343
|
-
const zones = model.getZones();
|
|
13344
|
-
const systems = model.getSystems();
|
|
13345
|
-
const { ownerHistoryId, geomContextId, geomSubContextId, unitAssignmentId, lengthUnitId } = writeHeader(w, meta);
|
|
13346
|
-
if (project.spec.crs !== void 0) writeMapConversion(w, project.spec.crs, geomContextId, lengthUnitId);
|
|
13347
|
-
const densityByElement = buildDensityMap(relationships);
|
|
13348
|
-
const idMap = /* @__PURE__ */ new Map();
|
|
13349
|
-
const placementMap = /* @__PURE__ */ new Map();
|
|
13350
|
-
const projectExpressId = writeProject$1(w, project.guid, project.spec.name, ownerHistoryId, unitAssignmentId, geomContextId);
|
|
13351
|
-
idMap.set(project.localId, projectExpressId);
|
|
13352
|
-
for (const el of elements) {
|
|
13353
|
-
if (el.category !== "SITE") continue;
|
|
13354
|
-
const parentId = findParentOf(el.localId, relationships);
|
|
13355
|
-
const parentPlacementId = parentId !== null ? placementMap.get(parentId) ?? null : null;
|
|
13356
|
-
const { entityId, placementId } = writeSite(w, el.guid, el.spec, ownerHistoryId, parentPlacementId);
|
|
13357
|
-
idMap.set(el.localId, entityId);
|
|
13358
|
-
placementMap.set(el.localId, placementId);
|
|
13359
|
-
}
|
|
13360
|
-
for (const bridge of bridges) {
|
|
13361
|
-
const parentId = findParentOf(bridge.localId, relationships);
|
|
13362
|
-
const parentPlacementId = parentId !== null ? placementMap.get(parentId) ?? null : null;
|
|
13363
|
-
const { entityId, placementId } = writeBridge(w, bridge.guid, bridge.spec, ownerHistoryId, parentPlacementId);
|
|
13364
|
-
idMap.set(bridge.localId, entityId);
|
|
13365
|
-
placementMap.set(bridge.localId, placementId);
|
|
13366
|
-
}
|
|
13367
|
-
const pendingParts = [...bridgeParts];
|
|
13368
|
-
while (pendingParts.length > 0) {
|
|
13369
|
-
const readyIndex = pendingParts.findIndex((candidate) => {
|
|
13370
|
-
const candidateParentId = findParentOf(candidate.localId, relationships);
|
|
13371
|
-
return candidateParentId === null || placementMap.has(candidateParentId);
|
|
13372
|
-
});
|
|
13373
|
-
const [part] = pendingParts.splice(readyIndex === -1 ? 0 : readyIndex, 1);
|
|
13374
|
-
if (part === void 0) break;
|
|
13375
|
-
const parentId = findParentOf(part.localId, relationships);
|
|
13376
|
-
const parentPlacementId = parentId !== null ? placementMap.get(parentId) ?? null : null;
|
|
13377
|
-
const { entityId, placementId } = writeBridgePart(w, part.guid, part.spec, ownerHistoryId, parentPlacementId);
|
|
13378
|
-
idMap.set(part.localId, entityId);
|
|
13379
|
-
placementMap.set(part.localId, placementId);
|
|
13380
|
-
}
|
|
13381
|
-
for (const el of elements) {
|
|
13382
|
-
if (el.category !== "BUILDING") continue;
|
|
13383
|
-
const parentSiteId = findParentOf(el.localId, relationships);
|
|
13384
|
-
const parentPlacementId = parentSiteId !== null ? placementMap.get(parentSiteId) ?? null : null;
|
|
13385
|
-
const { entityId, placementId } = writeBuilding(w, el.guid, el.spec.name, ownerHistoryId, parentPlacementId);
|
|
13386
|
-
idMap.set(el.localId, entityId);
|
|
13387
|
-
placementMap.set(el.localId, placementId);
|
|
13388
|
-
}
|
|
13389
|
-
for (const el of elements) {
|
|
13390
|
-
if (el.category !== "STOREY") continue;
|
|
13391
|
-
const parentBuildingId = findParentOf(el.localId, relationships);
|
|
13392
|
-
const parentPlacementId = parentBuildingId !== null ? placementMap.get(parentBuildingId) ?? null : null;
|
|
13393
|
-
const { entityId, placementId } = writeStorey(w, el.guid, el.spec.name, el.spec.elevation, ownerHistoryId, parentPlacementId);
|
|
13394
|
-
idMap.set(el.localId, entityId);
|
|
13395
|
-
placementMap.set(el.localId, placementId);
|
|
13396
|
-
}
|
|
13397
|
-
const openingsByWall = /* @__PURE__ */ new Map();
|
|
13398
|
-
for (const rel of relationships) {
|
|
13399
|
-
if (rel.kind !== "VOIDS_WALL") continue;
|
|
13400
|
-
const opening = elements.find((el) => el.localId === rel.openingLocalId);
|
|
13401
|
-
if (opening === void 0 || opening.category !== "OPENING") continue;
|
|
13402
|
-
if (!isWallOpening(opening.spec)) continue;
|
|
13403
|
-
const list = openingsByWall.get(rel.wallLocalId) ?? [];
|
|
13404
|
-
list.push(opening.spec);
|
|
13405
|
-
openingsByWall.set(rel.wallLocalId, list);
|
|
13406
|
-
}
|
|
13407
|
-
const openingsBySlab = /* @__PURE__ */ new Map();
|
|
13408
|
-
for (const rel of relationships) {
|
|
13409
|
-
if (rel.kind !== "VOIDS_SLAB") continue;
|
|
13410
|
-
const opening = elements.find((el) => el.localId === rel.openingLocalId);
|
|
13411
|
-
if (opening === void 0 || opening.category !== "OPENING") continue;
|
|
13412
|
-
if (!isSlabOpening(opening.spec)) continue;
|
|
13413
|
-
const list = openingsBySlab.get(rel.slabLocalId) ?? [];
|
|
13414
|
-
list.push(opening.spec);
|
|
13415
|
-
openingsBySlab.set(rel.slabLocalId, list);
|
|
13416
|
-
}
|
|
13417
|
-
for (const [i, wall] of walls.entries()) {
|
|
13418
|
-
const containingId = findContainerOf(wall.localId, relationships);
|
|
13419
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13420
|
-
const { localPlacementId, productDefinitionShapeId } = writeWallGeometry(w, wall.spec, geomSubContextId, storeyPlacementId);
|
|
13421
|
-
const wallExpressId = writeWallEntity(w, wall.guid, `Wall ${i + 1}`, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13422
|
-
idMap.set(wall.localId, wallExpressId);
|
|
13423
|
-
placementMap.set(wall.localId, localPlacementId);
|
|
13424
|
-
writeWallCommonPset(w, ownerHistoryId, wallExpressId, wall.spec);
|
|
13425
|
-
writeManufacturerPset(w, ownerHistoryId, wallExpressId, wall.spec);
|
|
13426
|
-
if (wall.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, wallExpressId, wall.spec.customProperties);
|
|
13427
|
-
writeWallBaseQuantities(w, ownerHistoryId, wallExpressId, wall.spec, openingsByWall.get(wall.localId) ?? [], densityByElement.get(wall.localId));
|
|
13428
|
-
}
|
|
13429
|
-
for (const [i, slab] of slabs.entries()) {
|
|
13430
|
-
const containingId = findContainerOf(slab.localId, relationships);
|
|
13431
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13432
|
-
const { localPlacementId, productDefinitionShapeId } = writeSlabGeometry(w, slab.spec, geomSubContextId, storeyPlacementId);
|
|
13433
|
-
const slabExpressId = writeSlabEntity(w, slab.guid, `Slab ${i + 1}`, slab.spec.predefinedType, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13434
|
-
idMap.set(slab.localId, slabExpressId);
|
|
13435
|
-
placementMap.set(slab.localId, localPlacementId);
|
|
13436
|
-
writeSlabCommonPset(w, ownerHistoryId, slabExpressId, slab.spec);
|
|
13437
|
-
writeManufacturerPset(w, ownerHistoryId, slabExpressId, slab.spec);
|
|
13438
|
-
if (slab.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, slabExpressId, slab.spec.customProperties);
|
|
13439
|
-
writeSlabBaseQuantities(w, ownerHistoryId, slabExpressId, slab.spec, openingsBySlab.get(slab.localId) ?? [], densityByElement.get(slab.localId));
|
|
13440
|
-
}
|
|
13441
|
-
for (const [i, beam] of beams.entries()) {
|
|
13442
|
-
const containingId = findContainerOf(beam.localId, relationships);
|
|
13443
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13444
|
-
const { localPlacementId, productDefinitionShapeId } = writeBeamGeometry(w, beam.spec, geomSubContextId, storeyPlacementId);
|
|
13445
|
-
const beamExpressId = writeBeamEntity(w, beam.guid, `Beam ${i + 1}`, beam.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13446
|
-
idMap.set(beam.localId, beamExpressId);
|
|
13447
|
-
placementMap.set(beam.localId, localPlacementId);
|
|
13448
|
-
writeBeamCommonPset(w, ownerHistoryId, beamExpressId, beam.spec);
|
|
13449
|
-
writeManufacturerPset(w, ownerHistoryId, beamExpressId, beam.spec);
|
|
13450
|
-
if (beam.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, beamExpressId, beam.spec.customProperties);
|
|
13451
|
-
writeBeamBaseQuantities(w, ownerHistoryId, beamExpressId, beam.spec);
|
|
13452
|
-
}
|
|
13453
|
-
for (const [i, column] of columns.entries()) {
|
|
13454
|
-
const containingId = findContainerOf(column.localId, relationships);
|
|
13455
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13456
|
-
const { localPlacementId, productDefinitionShapeId } = writeColumnGeometry(w, column.spec, geomSubContextId, storeyPlacementId);
|
|
13457
|
-
const columnExpressId = writeColumnEntity(w, column.guid, `Column ${i + 1}`, column.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13458
|
-
idMap.set(column.localId, columnExpressId);
|
|
13459
|
-
placementMap.set(column.localId, localPlacementId);
|
|
13460
|
-
writeColumnCommonPset(w, ownerHistoryId, columnExpressId, column.spec);
|
|
13461
|
-
writeManufacturerPset(w, ownerHistoryId, columnExpressId, column.spec);
|
|
13462
|
-
if (column.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, columnExpressId, column.spec.customProperties);
|
|
13463
|
-
writeColumnBaseQuantities(w, ownerHistoryId, columnExpressId, column.spec);
|
|
13464
|
-
}
|
|
13465
|
-
for (const [i, proxy] of proxies.entries()) {
|
|
13466
|
-
const containingId = findContainerOf(proxy.localId, relationships);
|
|
13467
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13468
|
-
const { localPlacementId, productDefinitionShapeId } = writeProxyGeometry(w, proxy.spec, geomSubContextId, storeyPlacementId);
|
|
13469
|
-
const proxyExpressId = writeProxyEntity(w, proxy.guid, proxy.spec.name || `Proxy ${i + 1}`, proxy.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13470
|
-
idMap.set(proxy.localId, proxyExpressId);
|
|
13471
|
-
placementMap.set(proxy.localId, localPlacementId);
|
|
13472
|
-
if (proxy.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, proxyExpressId, proxy.spec.customProperties);
|
|
13473
|
-
}
|
|
13474
|
-
for (const fill of earthworksFills) {
|
|
13475
|
-
const containingId = findContainerOf(fill.localId, relationships);
|
|
13476
|
-
const parentPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13477
|
-
const { localPlacementId, productDefinitionShapeId } = writeTessellatedProductGeometry(w, fill.geometry, geomSubContextId, parentPlacementId);
|
|
13478
|
-
const expressId = writeEarthworksFillEntity(w, fill.guid, fill.spec, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13479
|
-
idMap.set(fill.localId, expressId);
|
|
13480
|
-
placementMap.set(fill.localId, localPlacementId);
|
|
13481
|
-
if (fill.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, expressId, fill.spec.customProperties);
|
|
13482
|
-
}
|
|
13483
|
-
for (const [i, space] of spaces.entries()) {
|
|
13484
|
-
const containingId = findContainerOf(space.localId, relationships);
|
|
13485
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13486
|
-
const { localPlacementId, productDefinitionShapeId } = writeSpaceGeometry(w, space.spec, geomSubContextId, storeyPlacementId);
|
|
13487
|
-
const spaceExpressId = writeSpaceEntity(w, space.guid, space.spec.name || `Space ${i + 1}`, space.spec.longName ?? null, space.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13488
|
-
idMap.set(space.localId, spaceExpressId);
|
|
13489
|
-
placementMap.set(space.localId, localPlacementId);
|
|
13490
|
-
writeSpaceCommonPset(w, ownerHistoryId, spaceExpressId, space.spec);
|
|
13491
|
-
if (space.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, spaceExpressId, space.spec.customProperties);
|
|
13492
|
-
writeSpaceBaseQuantities(w, ownerHistoryId, spaceExpressId, space.spec);
|
|
13493
|
-
}
|
|
13494
|
-
for (const [i, roof] of roofs.entries()) {
|
|
13495
|
-
const containingId = findContainerOf(roof.localId, relationships);
|
|
13496
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13497
|
-
const { localPlacementId, productDefinitionShapeId, usedFallback } = writeRoofGeometry(w, roof.spec, roof.geometry, geomSubContextId, storeyPlacementId);
|
|
13498
|
-
if (usedFallback) console.warn(`Roof ${i + 1} tessellation failed; IFC body is a degenerate fallback.`);
|
|
13499
|
-
const roofExpressId = writeRoofEntity(w, roof.guid, `Roof ${i + 1}`, roof.spec.predefinedType, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13500
|
-
idMap.set(roof.localId, roofExpressId);
|
|
13501
|
-
placementMap.set(roof.localId, localPlacementId);
|
|
13502
|
-
writeRoofCommonPset(w, ownerHistoryId, roofExpressId, roof.spec);
|
|
13503
|
-
writeManufacturerPset(w, ownerHistoryId, roofExpressId, roof.spec);
|
|
13504
|
-
if (roof.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, roofExpressId, roof.spec.customProperties);
|
|
13505
|
-
writeRoofBaseQuantities(w, ownerHistoryId, roofExpressId, roof.spec);
|
|
13506
|
-
}
|
|
13507
|
-
for (const [i, curtainWall] of curtainWalls.entries()) {
|
|
13508
|
-
const containingId = findContainerOf(curtainWall.localId, relationships);
|
|
13509
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13510
|
-
const { curtainWallId } = writeCurtainWall(w, curtainWall.spec, curtainWall.geometry, `elem:CURTAIN_WALL:${curtainWall.localId}`, `Curtain Wall ${i + 1}`, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
13511
|
-
idMap.set(curtainWall.localId, curtainWallId);
|
|
13512
|
-
writeCurtainWallCommonPset(w, ownerHistoryId, curtainWallId, curtainWall.spec);
|
|
13513
|
-
if (curtainWall.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, curtainWallId, curtainWall.spec.customProperties);
|
|
13514
|
-
}
|
|
13515
|
-
for (const [i, footing] of footings.entries()) {
|
|
13516
|
-
const containingId = findContainerOf(footing.localId, relationships);
|
|
13517
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13518
|
-
const { localPlacementId, productDefinitionShapeId } = writeFootingGeometry(w, footing.spec, geomSubContextId, storeyPlacementId);
|
|
13519
|
-
const footingExpressId = writeFootingEntity(w, footing.guid, `Footing ${i + 1}`, footing.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13520
|
-
idMap.set(footing.localId, footingExpressId);
|
|
13521
|
-
placementMap.set(footing.localId, localPlacementId);
|
|
13522
|
-
writeFootingCommonPset(w, ownerHistoryId, footingExpressId, footing.spec);
|
|
13523
|
-
if (footing.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, footingExpressId, footing.spec.customProperties);
|
|
13524
|
-
writeFootingBaseQuantities(w, ownerHistoryId, footingExpressId, footing.spec);
|
|
13525
|
-
}
|
|
13526
|
-
for (const [i, pile] of piles.entries()) {
|
|
13527
|
-
const containingId = findContainerOf(pile.localId, relationships);
|
|
13528
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13529
|
-
const { localPlacementId, productDefinitionShapeId } = writePileGeometry(w, pile.spec, geomSubContextId, storeyPlacementId);
|
|
13530
|
-
const pileExpressId = writePileEntity(w, pile.guid, `Pile ${i + 1}`, pile.spec.predefinedType ?? "NOTDEFINED", pile.spec.constructionType ?? null, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13531
|
-
idMap.set(pile.localId, pileExpressId);
|
|
13532
|
-
placementMap.set(pile.localId, localPlacementId);
|
|
13533
|
-
writePileCommonPset(w, ownerHistoryId, pileExpressId, pile.spec);
|
|
13534
|
-
if (pile.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, pileExpressId, pile.spec.customProperties);
|
|
13535
|
-
writePileBaseQuantities(w, ownerHistoryId, pileExpressId, pile.spec);
|
|
13536
|
-
}
|
|
13537
|
-
for (const [i, assembly] of assemblies.entries()) {
|
|
13538
|
-
const containingId = findContainerOf(assembly.localId, relationships);
|
|
13539
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13540
|
-
const assemblyExpressId = writeElementAssemblyEntity(w, assembly.guid, assembly.spec.name ?? `Assembly ${i + 1}`, assembly.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, storeyPlacementId, null, assembly.spec.assemblyPlace ?? "NOTDEFINED");
|
|
13541
|
-
idMap.set(assembly.localId, assemblyExpressId);
|
|
13542
|
-
}
|
|
13543
|
-
for (const zone of zones) {
|
|
13544
|
-
const zoneExpressId = writeZoneEntity(w, zone.guid, zone.spec.name, zone.spec.longName ?? null, zone.spec.objectType ?? null, ownerHistoryId);
|
|
13545
|
-
idMap.set(zone.localId, zoneExpressId);
|
|
13546
|
-
}
|
|
13547
|
-
for (const system of systems) {
|
|
13548
|
-
const systemExpressId = writeSystemEntity(w, system.guid, system.spec.name, system.spec.longName ?? null, system.spec.objectType ?? null, ownerHistoryId);
|
|
13549
|
-
idMap.set(system.localId, systemExpressId);
|
|
13550
|
-
}
|
|
13551
|
-
for (const stair of stairs) {
|
|
13552
|
-
const containingId = findContainerOf(stair.localId, relationships);
|
|
13553
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13554
|
-
const result = writeStairAssembly(w, stair.spec, `${stair.localId}`, stair.guid, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
13555
|
-
if (!result.ok) return (0, brepjs.err)(result.error);
|
|
13556
|
-
idMap.set(stair.localId, result.value.assemblyExpressId);
|
|
13557
|
-
writeStairCommonPset(w, ownerHistoryId, result.value.assemblyExpressId, stair.spec);
|
|
13558
|
-
}
|
|
13559
|
-
for (const ramp of ramps) {
|
|
13560
|
-
const containingId = findContainerOf(ramp.localId, relationships);
|
|
13561
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13562
|
-
const result = writeRampAssembly(w, ramp.spec, `${ramp.localId}`, ramp.guid, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
13563
|
-
if (!result.ok) return (0, brepjs.err)(result.error);
|
|
13564
|
-
idMap.set(ramp.localId, result.value.assemblyExpressId);
|
|
13565
|
-
writeRampCommonPset(w, ownerHistoryId, result.value.assemblyExpressId, ramp.spec);
|
|
13566
|
-
}
|
|
13567
|
-
for (const [i, railing] of railings.entries()) {
|
|
13568
|
-
const containingId = findContainerOf(railing.localId, relationships);
|
|
13569
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13570
|
-
const { localPlacementId, productDefinitionShapeId, bodyItemId, usedFallback } = writeRailingGeometry(w, railing.spec, railing.geometry, geomSubContextId, storeyPlacementId);
|
|
13571
|
-
if (usedFallback) console.warn(`Railing ${i + 1} tessellation failed; IFC body is a degenerate fallback.`);
|
|
13572
|
-
const railingExpressId = writeRailingEntity(w, railing.guid, `Railing ${i + 1}`, railing.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13573
|
-
idMap.set(railing.localId, railingExpressId);
|
|
13574
|
-
placementMap.set(railing.localId, localPlacementId);
|
|
13575
|
-
writeRailingCommonPset(w, ownerHistoryId, railingExpressId, railing.spec);
|
|
13576
|
-
writeManufacturerPset(w, ownerHistoryId, railingExpressId, railing.spec);
|
|
13577
|
-
if (railing.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, railingExpressId, railing.spec.customProperties);
|
|
13578
|
-
if (bodyItemId !== null) applySurfaceStyle(w, model, railing.localId, bodyItemId);
|
|
13579
|
-
}
|
|
13580
|
-
for (const [i, covering] of coverings.entries()) {
|
|
13581
|
-
const containingId = findContainerOf(covering.localId, relationships);
|
|
13582
|
-
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13583
|
-
const { localPlacementId, productDefinitionShapeId, bodyItemId } = writeCoveringGeometry(w, covering.spec, geomSubContextId, storeyPlacementId);
|
|
13584
|
-
const coveringExpressId = writeCoveringEntity(w, covering.guid, `Covering ${i + 1}`, covering.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13585
|
-
idMap.set(covering.localId, coveringExpressId);
|
|
13586
|
-
placementMap.set(covering.localId, localPlacementId);
|
|
13587
|
-
writeCoveringCommonPset(w, ownerHistoryId, coveringExpressId, covering.spec);
|
|
13588
|
-
writeManufacturerPset(w, ownerHistoryId, coveringExpressId, covering.spec);
|
|
13589
|
-
if (covering.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, coveringExpressId, covering.spec.customProperties);
|
|
13590
|
-
applySurfaceStyle(w, model, covering.localId, bodyItemId);
|
|
13591
|
-
}
|
|
13592
|
-
const openingPlacementMap = /* @__PURE__ */ new Map();
|
|
13593
|
-
const openingEntityMap = /* @__PURE__ */ new Map();
|
|
13594
|
-
for (const rel of relationships) {
|
|
13595
|
-
if (rel.kind !== "VOIDS_WALL") continue;
|
|
13596
|
-
const wallElement = elements.find((el) => el.category === "WALL" && el.localId === rel.wallLocalId);
|
|
13597
|
-
if (wallElement === void 0) continue;
|
|
13598
|
-
const wallExpressId = idMap.get(rel.wallLocalId);
|
|
13599
|
-
const wallPlacementId = placementMap.get(rel.wallLocalId);
|
|
13600
|
-
if (wallExpressId === void 0 || wallPlacementId === void 0) continue;
|
|
13601
|
-
const openingElement = elements.find((el) => el.localId === rel.openingLocalId);
|
|
13602
|
-
if (openingElement === void 0 || openingElement.category !== "OPENING") continue;
|
|
13603
|
-
if (!isWallOpening(openingElement.spec)) continue;
|
|
13604
|
-
const { openingEntityId, openingPlacementId } = writeOpeningGeometry(w, openingElement.guid, openingElement.spec, wallElement.spec, wallPlacementId, geomSubContextId, ownerHistoryId);
|
|
13605
|
-
idMap.set(rel.openingLocalId, openingEntityId);
|
|
13606
|
-
openingPlacementMap.set(rel.openingLocalId, openingPlacementId);
|
|
13607
|
-
openingEntityMap.set(rel.openingLocalId, openingEntityId);
|
|
13608
|
-
writeRelVoidsElement(w, rel.guid, ownerHistoryId, wallExpressId, openingEntityId);
|
|
13609
|
-
}
|
|
13610
|
-
for (const rel of relationships) {
|
|
13611
|
-
if (rel.kind !== "VOIDS_SLAB") continue;
|
|
13612
|
-
const slabElement = elements.find((el) => el.category === "SLAB" && el.localId === rel.slabLocalId);
|
|
13613
|
-
if (slabElement === void 0) continue;
|
|
13614
|
-
const slabExpressId = idMap.get(rel.slabLocalId);
|
|
13615
|
-
const slabPlacementId = placementMap.get(rel.slabLocalId);
|
|
13616
|
-
if (slabExpressId === void 0 || slabPlacementId === void 0) continue;
|
|
13617
|
-
const openingElement = elements.find((el) => el.localId === rel.openingLocalId);
|
|
13618
|
-
if (openingElement === void 0 || openingElement.category !== "OPENING") continue;
|
|
13619
|
-
if (!isSlabOpening(openingElement.spec)) continue;
|
|
13620
|
-
const { openingEntityId } = writeSlabOpeningGeometry(w, openingElement.guid, openingElement.spec, slabElement.spec, slabPlacementId, geomSubContextId, ownerHistoryId);
|
|
13621
|
-
idMap.set(rel.openingLocalId, openingEntityId);
|
|
13622
|
-
writeRelVoidsElement(w, rel.guid, ownerHistoryId, slabExpressId, openingEntityId);
|
|
13623
|
-
}
|
|
13624
|
-
for (const [i, door] of doors.entries()) {
|
|
13625
|
-
const fillsRel = relationships.find((rel) => rel.kind === "FILLS_OPENING" && rel.fillerLocalId === door.localId);
|
|
13626
|
-
if (fillsRel === void 0 || fillsRel.kind !== "FILLS_OPENING") continue;
|
|
13627
|
-
const openingPlacementId = openingPlacementMap.get(fillsRel.openingLocalId);
|
|
13628
|
-
const openingEntityId = openingEntityMap.get(fillsRel.openingLocalId);
|
|
13629
|
-
if (openingPlacementId === void 0 || openingEntityId === void 0) continue;
|
|
13630
|
-
const doorExpressId = writeDoorEntity(w, door.guid, `Door ${i + 1}`, ownerHistoryId, openingPlacementId, geomSubContextId, toIfcLengthM(door.spec.width), toIfcLengthM(door.spec.height));
|
|
13631
|
-
idMap.set(door.localId, doorExpressId);
|
|
13632
|
-
writeRelFillsElement(w, fillsRel.guid, ownerHistoryId, openingEntityId, doorExpressId);
|
|
13633
|
-
writeDoorCommonPset(w, ownerHistoryId, doorExpressId, door.spec);
|
|
13634
|
-
}
|
|
13635
|
-
for (const [i, win] of windows.entries()) {
|
|
13636
|
-
const fillsRel = relationships.find((rel) => rel.kind === "FILLS_OPENING" && rel.fillerLocalId === win.localId);
|
|
13637
|
-
if (fillsRel === void 0 || fillsRel.kind !== "FILLS_OPENING") continue;
|
|
13638
|
-
const openingPlacementId = openingPlacementMap.get(fillsRel.openingLocalId);
|
|
13639
|
-
const openingEntityId = openingEntityMap.get(fillsRel.openingLocalId);
|
|
13640
|
-
if (openingPlacementId === void 0 || openingEntityId === void 0) continue;
|
|
13641
|
-
const windowExpressId = writeWindowEntity(w, win.guid, `Window ${i + 1}`, ownerHistoryId, openingPlacementId, geomSubContextId, toIfcLengthM(win.spec.width), toIfcLengthM(win.spec.height));
|
|
13642
|
-
idMap.set(win.localId, windowExpressId);
|
|
13643
|
-
writeRelFillsElement(w, fillsRel.guid, ownerHistoryId, openingEntityId, windowExpressId);
|
|
13644
|
-
writeWindowCommonPset(w, ownerHistoryId, windowExpressId, win.spec);
|
|
13645
|
-
}
|
|
13646
|
-
for (const rel of relationships) {
|
|
13647
|
-
if (rel.kind !== "AGGREGATES") continue;
|
|
13648
|
-
const parentExpressId = idMap.get(rel.relatingObject);
|
|
13649
|
-
const childExpressIds = rel.relatedObjects.map((id) => idMap.get(id)).filter((id) => id !== void 0);
|
|
13650
|
-
if (parentExpressId === void 0 || childExpressIds.length === 0) continue;
|
|
13651
|
-
writeRelAggregates(w, rel.guid, ownerHistoryId, parentExpressId, childExpressIds);
|
|
13652
|
-
}
|
|
13653
|
-
for (const rel of relationships) {
|
|
13654
|
-
if (rel.kind !== "CONTAINED_IN") continue;
|
|
13655
|
-
const structureExpressId = idMap.get(rel.relatingStructure);
|
|
13656
|
-
const elementExpressIds = rel.relatedElements.map((id) => idMap.get(id)).filter((id) => id !== void 0);
|
|
13657
|
-
if (structureExpressId === void 0 || elementExpressIds.length === 0) continue;
|
|
13658
|
-
writeRelContainedInSpatialStructure(w, rel.guid, ownerHistoryId, structureExpressId, elementExpressIds);
|
|
13659
|
-
}
|
|
13660
|
-
for (const rel of relationships) {
|
|
13661
|
-
if (rel.kind !== "SPACE_BOUNDARY") continue;
|
|
13662
|
-
const spaceExpressId = idMap.get(rel.spaceLocalId);
|
|
13663
|
-
const elementExpressId = idMap.get(rel.elementLocalId);
|
|
13664
|
-
if (spaceExpressId === void 0 || elementExpressId === void 0) continue;
|
|
13665
|
-
writeRelSpaceBoundary(w, rel.guid, ownerHistoryId, spaceExpressId, elementExpressId, rel.connectionType);
|
|
13666
|
-
}
|
|
13667
|
-
for (const rel of relationships) {
|
|
13668
|
-
if (rel.kind !== "NESTS") continue;
|
|
13669
|
-
const parentExpressId = idMap.get(rel.relatingObject);
|
|
13670
|
-
const childExpressIds = rel.relatedObjects.map((id) => idMap.get(id)).filter((id) => id !== void 0);
|
|
13671
|
-
if (parentExpressId === void 0 || childExpressIds.length === 0) continue;
|
|
13672
|
-
writeRelNests(w, rel.guid, ownerHistoryId, parentExpressId, childExpressIds);
|
|
13673
|
-
}
|
|
13674
|
-
for (const rel of relationships) {
|
|
13675
|
-
if (rel.kind !== "COVERS_ELEMENT") continue;
|
|
13676
|
-
const hostExpressId = idMap.get(rel.hostLocalId);
|
|
13677
|
-
const coveringExpressId = idMap.get(rel.coveringLocalId);
|
|
13678
|
-
if (hostExpressId === void 0 || coveringExpressId === void 0) continue;
|
|
13679
|
-
writeRelCoversBldgElements(w, rel.guid, ownerHistoryId, hostExpressId, [coveringExpressId]);
|
|
13531
|
+
//#region src/serialize/exactBodyPreflight.ts
|
|
13532
|
+
var testItemPreparer = null;
|
|
13533
|
+
/** Prepares every exact Body item without writing IFC lines. Source solids remain borrowed. */
|
|
13534
|
+
function preflightExactBody(input) {
|
|
13535
|
+
const prepareItem = input.prepareItem ?? testItemPreparer ?? prepareTessellation;
|
|
13536
|
+
const prepareAt = (solid, itemIndex) => {
|
|
13537
|
+
const item = prepareItem(solid);
|
|
13538
|
+
if (!item.ok) return (0, brepjs.err)(ifcError("EXACT_BODY_TESSELLATION_FAILED", `Exact Product Body item ${itemIndex} for ${input.localId} could not be tessellated: ${item.reason}`, item.cause, {
|
|
13539
|
+
localId: input.localId,
|
|
13540
|
+
itemIndex
|
|
13541
|
+
}));
|
|
13542
|
+
return (0, brepjs.ok)(item.value);
|
|
13543
|
+
};
|
|
13544
|
+
const [firstSolid, ...remainingSolids] = input.solids;
|
|
13545
|
+
const first = prepareAt(firstSolid, 0);
|
|
13546
|
+
if (!first.ok) return first;
|
|
13547
|
+
const remainingPrepared = [];
|
|
13548
|
+
for (const [remainingIndex, solid] of remainingSolids.entries()) {
|
|
13549
|
+
const item = prepareAt(solid, remainingIndex + 1);
|
|
13550
|
+
if (!item.ok) return item;
|
|
13551
|
+
remainingPrepared.push(item.value);
|
|
13680
13552
|
}
|
|
13681
|
-
|
|
13682
|
-
|
|
13683
|
-
|
|
13684
|
-
|
|
13685
|
-
|
|
13686
|
-
|
|
13553
|
+
return (0, brepjs.ok)([first.value, ...remainingPrepared]);
|
|
13554
|
+
}
|
|
13555
|
+
//#endregion
|
|
13556
|
+
//#region src/serialize/exactWallQuantities.ts
|
|
13557
|
+
function deriveExactWallQuantities(input) {
|
|
13558
|
+
const measure = input.dependencies?.measure ?? brepjs.measureVolume;
|
|
13559
|
+
let volumeMm3;
|
|
13560
|
+
if (input.solids.length === 1) try {
|
|
13561
|
+
const measured = measure(input.solids[0]);
|
|
13562
|
+
if (!measured.ok) return exactVolumeError(measured.error);
|
|
13563
|
+
volumeMm3 = measured.value;
|
|
13564
|
+
} catch (cause) {
|
|
13565
|
+
return exactVolumeError(cause);
|
|
13687
13566
|
}
|
|
13688
|
-
|
|
13689
|
-
|
|
13690
|
-
|
|
13691
|
-
|
|
13692
|
-
|
|
13693
|
-
|
|
13567
|
+
else {
|
|
13568
|
+
const fuse = input.dependencies?.fuse ?? brepjs.fuseAll;
|
|
13569
|
+
let union = null;
|
|
13570
|
+
try {
|
|
13571
|
+
const fused = fuse([...input.solids]);
|
|
13572
|
+
if (!fused.ok) return exactVolumeError(fused.error);
|
|
13573
|
+
union = fused.value;
|
|
13574
|
+
const measured = measure(union);
|
|
13575
|
+
if (!measured.ok) return exactVolumeError(measured.error);
|
|
13576
|
+
volumeMm3 = measured.value;
|
|
13577
|
+
} catch (cause) {
|
|
13578
|
+
return exactVolumeError(cause);
|
|
13579
|
+
} finally {
|
|
13580
|
+
union?.[Symbol.dispose]();
|
|
13581
|
+
}
|
|
13694
13582
|
}
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
|
|
13698
|
-
|
|
13699
|
-
|
|
13700
|
-
|
|
13701
|
-
}
|
|
13702
|
-
|
|
13703
|
-
|
|
13704
|
-
|
|
13705
|
-
|
|
13706
|
-
|
|
13707
|
-
|
|
13708
|
-
|
|
13709
|
-
|
|
13710
|
-
|
|
13711
|
-
|
|
13712
|
-
|
|
13713
|
-
|
|
13714
|
-
|
|
13715
|
-
|
|
13716
|
-
|
|
13717
|
-
ids: objectExpressIds,
|
|
13718
|
-
direction
|
|
13583
|
+
if (!Number.isFinite(volumeMm3) || volumeMm3 <= 0) return exactVolumeError(/* @__PURE__ */ new Error(`Measured exact wall volume was ${volumeMm3}`));
|
|
13584
|
+
return (0, brepjs.ok)({
|
|
13585
|
+
lengthM: toIfcLengthM(input.spec.length),
|
|
13586
|
+
widthM: toIfcLengthM(input.spec.thickness),
|
|
13587
|
+
heightM: toIfcLengthM(input.spec.height),
|
|
13588
|
+
netVolumeM3: volumeMm3 / 1e9
|
|
13589
|
+
});
|
|
13590
|
+
}
|
|
13591
|
+
function exactVolumeError(cause) {
|
|
13592
|
+
return (0, brepjs.err)(ifcError("IFC_EXACT_WALL_QUANTITY_DERIVATION_FAILED", "Failed to derive a positive finite NetVolume for an exact wall Product Body", cause));
|
|
13593
|
+
}
|
|
13594
|
+
//#endregion
|
|
13595
|
+
//#region src/serialize/toIfc.ts
|
|
13596
|
+
function preflightProductBodies(elements) {
|
|
13597
|
+
const preflighted = [];
|
|
13598
|
+
for (const element of elements) {
|
|
13599
|
+
const body = element.geometry;
|
|
13600
|
+
if (body.kind === "PARAMETRIC") {
|
|
13601
|
+
preflighted.push({
|
|
13602
|
+
kind: "PARAMETRIC",
|
|
13603
|
+
element,
|
|
13604
|
+
solid: body.solid
|
|
13719
13605
|
});
|
|
13720
13606
|
continue;
|
|
13721
13607
|
}
|
|
13722
|
-
const
|
|
13723
|
-
|
|
13724
|
-
|
|
13725
|
-
ids: [...existing.ids, ...objectExpressIds]
|
|
13608
|
+
const prepared = preflightExactBody({
|
|
13609
|
+
localId: element.localId,
|
|
13610
|
+
solids: body.solids
|
|
13726
13611
|
});
|
|
13727
|
-
|
|
13728
|
-
|
|
13729
|
-
|
|
13612
|
+
if (!prepared.ok) return (0, brepjs.err)(prepared.error);
|
|
13613
|
+
preflighted.push({
|
|
13614
|
+
kind: "EXACT",
|
|
13615
|
+
element,
|
|
13616
|
+
solids: body.solids,
|
|
13617
|
+
items: prepared.value
|
|
13730
13618
|
});
|
|
13731
13619
|
}
|
|
13732
|
-
|
|
13733
|
-
|
|
13734
|
-
|
|
13735
|
-
|
|
13736
|
-
|
|
13737
|
-
|
|
13738
|
-
|
|
13739
|
-
|
|
13740
|
-
|
|
13741
|
-
|
|
13742
|
-
|
|
13743
|
-
|
|
13744
|
-
const objectExpressIds = rel.relatedObjects.map((id) => idMap.get(id)).filter((id) => id !== void 0);
|
|
13745
|
-
if (objectExpressIds.length === 0) continue;
|
|
13746
|
-
const key = `${rel.ref.system}:${rel.ref.code}`;
|
|
13747
|
-
const entry = classByKey.get(key);
|
|
13748
|
-
if (entry === void 0) classByKey.set(key, {
|
|
13749
|
-
ref: rel.ref,
|
|
13750
|
-
ids: [...objectExpressIds]
|
|
13620
|
+
return (0, brepjs.ok)(preflighted);
|
|
13621
|
+
}
|
|
13622
|
+
async function toIfc(model, meta) {
|
|
13623
|
+
try {
|
|
13624
|
+
var _usingCtx$2 = _usingCtx();
|
|
13625
|
+
const project = model.getProject();
|
|
13626
|
+
if (!project) return (0, brepjs.err)(ifcError("NO_PROJECT", "BimModel has no project — call model.init() first"));
|
|
13627
|
+
if ((model.getBridges().length > 0 || model.getBridgeParts().length > 0 || model.getEarthworksFills().length > 0) && (meta.ifcSchema ?? "IFC4") !== "IFC4X3") return (0, brepjs.err)(ifcError("IFC4X3_REQUIRED", "Bridge, Bridge Part, and Earthworks Fill entities require IFC4X3 serialization"));
|
|
13628
|
+
const authorName = [meta.author?.givenName, meta.author?.familyName].filter((p) => Boolean(p)).join(" ");
|
|
13629
|
+
const writerResult = await IfcWriter.create(meta.mvdViewDefinition, meta.ifcSchema, {
|
|
13630
|
+
author: authorName,
|
|
13631
|
+
organization: meta.organizationName
|
|
13751
13632
|
});
|
|
13752
|
-
|
|
13633
|
+
if (!writerResult.ok) return writerResult;
|
|
13634
|
+
const w = _usingCtx$2.u(writerResult.value);
|
|
13635
|
+
w.setModelScope(project.guid);
|
|
13636
|
+
const elements = model.getAllElements();
|
|
13637
|
+
const relationships = model.getAllRelationships();
|
|
13638
|
+
const walls = model.getWalls();
|
|
13639
|
+
const slabs = model.getSlabs();
|
|
13640
|
+
const beams = model.getBeams();
|
|
13641
|
+
const bridges = model.getBridges();
|
|
13642
|
+
const bridgeParts = model.getBridgeParts();
|
|
13643
|
+
const earthworksFills = model.getEarthworksFills();
|
|
13644
|
+
const columns = model.getColumns();
|
|
13645
|
+
const doors = model.getDoors();
|
|
13646
|
+
const windows = model.getWindows();
|
|
13647
|
+
const proxies = model.getProxies();
|
|
13648
|
+
const spaces = model.getSpaces();
|
|
13649
|
+
const roofs = model.getRoofs();
|
|
13650
|
+
const curtainWalls = model.getCurtainWalls();
|
|
13651
|
+
const footings = model.getFootings();
|
|
13652
|
+
const piles = model.getPiles();
|
|
13653
|
+
const stairs = model.getStairs();
|
|
13654
|
+
const ramps = model.getRamps();
|
|
13655
|
+
const railings = model.getRailings();
|
|
13656
|
+
const coverings = model.getCoverings();
|
|
13657
|
+
const assemblies = model.getElementAssemblies();
|
|
13658
|
+
const zones = model.getZones();
|
|
13659
|
+
const systems = model.getSystems();
|
|
13660
|
+
const preflightedWallsResult = preflightProductBodies(walls);
|
|
13661
|
+
if (!preflightedWallsResult.ok) return (0, brepjs.err)(preflightedWallsResult.error);
|
|
13662
|
+
const preflightedRailingsResult = preflightProductBodies(railings);
|
|
13663
|
+
if (!preflightedRailingsResult.ok) return (0, brepjs.err)(preflightedRailingsResult.error);
|
|
13664
|
+
const preflightedWalls = preflightedWallsResult.value;
|
|
13665
|
+
const preflightedRailings = preflightedRailingsResult.value;
|
|
13666
|
+
const { ownerHistoryId, geomContextId, geomSubContextId, unitAssignmentId, lengthUnitId } = writeHeader(w, meta);
|
|
13667
|
+
if (project.spec.crs !== void 0) writeMapConversion(w, project.spec.crs, geomContextId, lengthUnitId);
|
|
13668
|
+
const densityByElement = buildDensityMap(relationships);
|
|
13669
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
13670
|
+
const placementMap = /* @__PURE__ */ new Map();
|
|
13671
|
+
const projectExpressId = writeProject$1(w, project.guid, project.spec.name, ownerHistoryId, unitAssignmentId, geomContextId);
|
|
13672
|
+
idMap.set(project.localId, projectExpressId);
|
|
13673
|
+
for (const el of elements) {
|
|
13674
|
+
if (el.category !== "SITE") continue;
|
|
13675
|
+
const parentId = findParentOf(el.localId, relationships);
|
|
13676
|
+
const parentPlacementId = parentId !== null ? placementMap.get(parentId) ?? null : null;
|
|
13677
|
+
const { entityId, placementId } = writeSite(w, el.guid, el.spec, ownerHistoryId, parentPlacementId);
|
|
13678
|
+
idMap.set(el.localId, entityId);
|
|
13679
|
+
placementMap.set(el.localId, placementId);
|
|
13680
|
+
}
|
|
13681
|
+
for (const bridge of bridges) {
|
|
13682
|
+
const parentId = findParentOf(bridge.localId, relationships);
|
|
13683
|
+
const parentPlacementId = parentId !== null ? placementMap.get(parentId) ?? null : null;
|
|
13684
|
+
const { entityId, placementId } = writeBridge(w, bridge.guid, bridge.spec, ownerHistoryId, parentPlacementId);
|
|
13685
|
+
idMap.set(bridge.localId, entityId);
|
|
13686
|
+
placementMap.set(bridge.localId, placementId);
|
|
13687
|
+
}
|
|
13688
|
+
const pendingParts = [...bridgeParts];
|
|
13689
|
+
while (pendingParts.length > 0) {
|
|
13690
|
+
const readyIndex = pendingParts.findIndex((candidate) => {
|
|
13691
|
+
const candidateParentId = findParentOf(candidate.localId, relationships);
|
|
13692
|
+
return candidateParentId === null || placementMap.has(candidateParentId);
|
|
13693
|
+
});
|
|
13694
|
+
const [part] = pendingParts.splice(readyIndex === -1 ? 0 : readyIndex, 1);
|
|
13695
|
+
if (part === void 0) break;
|
|
13696
|
+
const parentId = findParentOf(part.localId, relationships);
|
|
13697
|
+
const parentPlacementId = parentId !== null ? placementMap.get(parentId) ?? null : null;
|
|
13698
|
+
const { entityId, placementId } = writeBridgePart(w, part.guid, part.spec, ownerHistoryId, parentPlacementId);
|
|
13699
|
+
idMap.set(part.localId, entityId);
|
|
13700
|
+
placementMap.set(part.localId, placementId);
|
|
13701
|
+
}
|
|
13702
|
+
for (const el of elements) {
|
|
13703
|
+
if (el.category !== "BUILDING") continue;
|
|
13704
|
+
const parentSiteId = findParentOf(el.localId, relationships);
|
|
13705
|
+
const parentPlacementId = parentSiteId !== null ? placementMap.get(parentSiteId) ?? null : null;
|
|
13706
|
+
const { entityId, placementId } = writeBuilding(w, el.guid, el.spec.name, ownerHistoryId, parentPlacementId);
|
|
13707
|
+
idMap.set(el.localId, entityId);
|
|
13708
|
+
placementMap.set(el.localId, placementId);
|
|
13709
|
+
}
|
|
13710
|
+
for (const el of elements) {
|
|
13711
|
+
if (el.category !== "STOREY") continue;
|
|
13712
|
+
const parentBuildingId = findParentOf(el.localId, relationships);
|
|
13713
|
+
const parentPlacementId = parentBuildingId !== null ? placementMap.get(parentBuildingId) ?? null : null;
|
|
13714
|
+
const { entityId, placementId } = writeStorey(w, el.guid, el.spec.name, el.spec.elevation, ownerHistoryId, parentPlacementId);
|
|
13715
|
+
idMap.set(el.localId, entityId);
|
|
13716
|
+
placementMap.set(el.localId, placementId);
|
|
13717
|
+
}
|
|
13718
|
+
const openingsByWall = /* @__PURE__ */ new Map();
|
|
13719
|
+
for (const rel of relationships) {
|
|
13720
|
+
if (rel.kind !== "VOIDS_WALL") continue;
|
|
13721
|
+
const opening = elements.find((el) => el.localId === rel.openingLocalId);
|
|
13722
|
+
if (opening === void 0 || opening.category !== "OPENING") continue;
|
|
13723
|
+
if (!isWallOpening(opening.spec)) continue;
|
|
13724
|
+
const list = openingsByWall.get(rel.wallLocalId) ?? [];
|
|
13725
|
+
list.push(opening.spec);
|
|
13726
|
+
openingsByWall.set(rel.wallLocalId, list);
|
|
13727
|
+
}
|
|
13728
|
+
const openingsBySlab = /* @__PURE__ */ new Map();
|
|
13729
|
+
for (const rel of relationships) {
|
|
13730
|
+
if (rel.kind !== "VOIDS_SLAB") continue;
|
|
13731
|
+
const opening = elements.find((el) => el.localId === rel.openingLocalId);
|
|
13732
|
+
if (opening === void 0 || opening.category !== "OPENING") continue;
|
|
13733
|
+
if (!isSlabOpening(opening.spec)) continue;
|
|
13734
|
+
const list = openingsBySlab.get(rel.slabLocalId) ?? [];
|
|
13735
|
+
list.push(opening.spec);
|
|
13736
|
+
openingsBySlab.set(rel.slabLocalId, list);
|
|
13737
|
+
}
|
|
13738
|
+
for (const [i, preflighted] of preflightedWalls.entries()) {
|
|
13739
|
+
const wall = preflighted.element;
|
|
13740
|
+
const containingId = findContainerOf(wall.localId, relationships);
|
|
13741
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13742
|
+
const exactQuantities = preflighted.kind === "EXACT" ? deriveExactWallQuantities({
|
|
13743
|
+
spec: wall.spec,
|
|
13744
|
+
solids: preflighted.solids
|
|
13745
|
+
}) : null;
|
|
13746
|
+
const { localPlacementId, productDefinitionShapeId } = preflighted.kind === "EXACT" ? writeExactBodyGeometry(w, wall.spec, preflighted.items, geomSubContextId, storeyPlacementId) : writeWallGeometry(w, wall.spec, geomSubContextId, storeyPlacementId);
|
|
13747
|
+
const wallExpressId = writeWallEntity(w, wall.guid, `Wall ${i + 1}`, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13748
|
+
idMap.set(wall.localId, wallExpressId);
|
|
13749
|
+
placementMap.set(wall.localId, localPlacementId);
|
|
13750
|
+
writeWallCommonPset(w, ownerHistoryId, wallExpressId, wall.spec);
|
|
13751
|
+
writeManufacturerPset(w, ownerHistoryId, wallExpressId, wall.spec);
|
|
13752
|
+
if (wall.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, wallExpressId, wall.spec.customProperties);
|
|
13753
|
+
if (preflighted.kind === "EXACT") {
|
|
13754
|
+
if (exactQuantities !== null && exactQuantities.ok) writeExactWallBaseQuantities(w, ownerHistoryId, wallExpressId, exactQuantities.value);
|
|
13755
|
+
} else writeWallBaseQuantities(w, ownerHistoryId, wallExpressId, wall.spec, openingsByWall.get(wall.localId) ?? [], densityByElement.get(wall.localId));
|
|
13756
|
+
}
|
|
13757
|
+
for (const [i, slab] of slabs.entries()) {
|
|
13758
|
+
const containingId = findContainerOf(slab.localId, relationships);
|
|
13759
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13760
|
+
const { localPlacementId, productDefinitionShapeId } = writeSlabGeometry(w, slab.spec, geomSubContextId, storeyPlacementId);
|
|
13761
|
+
const slabExpressId = writeSlabEntity(w, slab.guid, `Slab ${i + 1}`, slab.spec.predefinedType, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13762
|
+
idMap.set(slab.localId, slabExpressId);
|
|
13763
|
+
placementMap.set(slab.localId, localPlacementId);
|
|
13764
|
+
writeSlabCommonPset(w, ownerHistoryId, slabExpressId, slab.spec);
|
|
13765
|
+
writeManufacturerPset(w, ownerHistoryId, slabExpressId, slab.spec);
|
|
13766
|
+
if (slab.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, slabExpressId, slab.spec.customProperties);
|
|
13767
|
+
writeSlabBaseQuantities(w, ownerHistoryId, slabExpressId, slab.spec, openingsBySlab.get(slab.localId) ?? [], densityByElement.get(slab.localId));
|
|
13768
|
+
}
|
|
13769
|
+
for (const [i, beam] of beams.entries()) {
|
|
13770
|
+
const containingId = findContainerOf(beam.localId, relationships);
|
|
13771
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13772
|
+
const { localPlacementId, productDefinitionShapeId } = writeBeamGeometry(w, beam.spec, geomSubContextId, storeyPlacementId);
|
|
13773
|
+
const beamExpressId = writeBeamEntity(w, beam.guid, `Beam ${i + 1}`, beam.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13774
|
+
idMap.set(beam.localId, beamExpressId);
|
|
13775
|
+
placementMap.set(beam.localId, localPlacementId);
|
|
13776
|
+
writeBeamCommonPset(w, ownerHistoryId, beamExpressId, beam.spec);
|
|
13777
|
+
writeManufacturerPset(w, ownerHistoryId, beamExpressId, beam.spec);
|
|
13778
|
+
if (beam.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, beamExpressId, beam.spec.customProperties);
|
|
13779
|
+
writeBeamBaseQuantities(w, ownerHistoryId, beamExpressId, beam.spec);
|
|
13780
|
+
}
|
|
13781
|
+
for (const [i, column] of columns.entries()) {
|
|
13782
|
+
const containingId = findContainerOf(column.localId, relationships);
|
|
13783
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13784
|
+
const { localPlacementId, productDefinitionShapeId } = writeColumnGeometry(w, column.spec, geomSubContextId, storeyPlacementId);
|
|
13785
|
+
const columnExpressId = writeColumnEntity(w, column.guid, `Column ${i + 1}`, column.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13786
|
+
idMap.set(column.localId, columnExpressId);
|
|
13787
|
+
placementMap.set(column.localId, localPlacementId);
|
|
13788
|
+
writeColumnCommonPset(w, ownerHistoryId, columnExpressId, column.spec);
|
|
13789
|
+
writeManufacturerPset(w, ownerHistoryId, columnExpressId, column.spec);
|
|
13790
|
+
if (column.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, columnExpressId, column.spec.customProperties);
|
|
13791
|
+
writeColumnBaseQuantities(w, ownerHistoryId, columnExpressId, column.spec);
|
|
13792
|
+
}
|
|
13793
|
+
for (const [i, proxy] of proxies.entries()) {
|
|
13794
|
+
const containingId = findContainerOf(proxy.localId, relationships);
|
|
13795
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13796
|
+
const { localPlacementId, productDefinitionShapeId } = writeProxyGeometry(w, proxy.spec, geomSubContextId, storeyPlacementId);
|
|
13797
|
+
const proxyExpressId = writeProxyEntity(w, proxy.guid, proxy.spec.name || `Proxy ${i + 1}`, proxy.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13798
|
+
idMap.set(proxy.localId, proxyExpressId);
|
|
13799
|
+
placementMap.set(proxy.localId, localPlacementId);
|
|
13800
|
+
if (proxy.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, proxyExpressId, proxy.spec.customProperties);
|
|
13801
|
+
}
|
|
13802
|
+
for (const fill of earthworksFills) {
|
|
13803
|
+
const containingId = findContainerOf(fill.localId, relationships);
|
|
13804
|
+
const parentPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13805
|
+
const { localPlacementId, productDefinitionShapeId } = writeTessellatedProductGeometry(w, fill.geometry, geomSubContextId, parentPlacementId);
|
|
13806
|
+
const expressId = writeEarthworksFillEntity(w, fill.guid, fill.spec, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13807
|
+
idMap.set(fill.localId, expressId);
|
|
13808
|
+
placementMap.set(fill.localId, localPlacementId);
|
|
13809
|
+
if (fill.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, expressId, fill.spec.customProperties);
|
|
13810
|
+
}
|
|
13811
|
+
for (const [i, space] of spaces.entries()) {
|
|
13812
|
+
const containingId = findContainerOf(space.localId, relationships);
|
|
13813
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13814
|
+
const { localPlacementId, productDefinitionShapeId } = writeSpaceGeometry(w, space.spec, geomSubContextId, storeyPlacementId);
|
|
13815
|
+
const spaceExpressId = writeSpaceEntity(w, space.guid, space.spec.name || `Space ${i + 1}`, space.spec.longName ?? null, space.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13816
|
+
idMap.set(space.localId, spaceExpressId);
|
|
13817
|
+
placementMap.set(space.localId, localPlacementId);
|
|
13818
|
+
writeSpaceCommonPset(w, ownerHistoryId, spaceExpressId, space.spec);
|
|
13819
|
+
if (space.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, spaceExpressId, space.spec.customProperties);
|
|
13820
|
+
writeSpaceBaseQuantities(w, ownerHistoryId, spaceExpressId, space.spec);
|
|
13821
|
+
}
|
|
13822
|
+
for (const [i, roof] of roofs.entries()) {
|
|
13823
|
+
const containingId = findContainerOf(roof.localId, relationships);
|
|
13824
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13825
|
+
const { localPlacementId, productDefinitionShapeId, usedFallback } = writeRoofGeometry(w, roof.spec, roof.geometry, geomSubContextId, storeyPlacementId);
|
|
13826
|
+
if (usedFallback) console.warn(`Roof ${i + 1} tessellation failed; IFC body is a degenerate fallback.`);
|
|
13827
|
+
const roofExpressId = writeRoofEntity(w, roof.guid, `Roof ${i + 1}`, roof.spec.predefinedType, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13828
|
+
idMap.set(roof.localId, roofExpressId);
|
|
13829
|
+
placementMap.set(roof.localId, localPlacementId);
|
|
13830
|
+
writeRoofCommonPset(w, ownerHistoryId, roofExpressId, roof.spec);
|
|
13831
|
+
writeManufacturerPset(w, ownerHistoryId, roofExpressId, roof.spec);
|
|
13832
|
+
if (roof.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, roofExpressId, roof.spec.customProperties);
|
|
13833
|
+
writeRoofBaseQuantities(w, ownerHistoryId, roofExpressId, roof.spec);
|
|
13834
|
+
}
|
|
13835
|
+
for (const [i, curtainWall] of curtainWalls.entries()) {
|
|
13836
|
+
const containingId = findContainerOf(curtainWall.localId, relationships);
|
|
13837
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13838
|
+
const { curtainWallId } = writeCurtainWall(w, curtainWall.spec, curtainWall.geometry, `elem:CURTAIN_WALL:${curtainWall.localId}`, `Curtain Wall ${i + 1}`, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
13839
|
+
idMap.set(curtainWall.localId, curtainWallId);
|
|
13840
|
+
writeCurtainWallCommonPset(w, ownerHistoryId, curtainWallId, curtainWall.spec);
|
|
13841
|
+
if (curtainWall.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, curtainWallId, curtainWall.spec.customProperties);
|
|
13842
|
+
}
|
|
13843
|
+
for (const [i, footing] of footings.entries()) {
|
|
13844
|
+
const containingId = findContainerOf(footing.localId, relationships);
|
|
13845
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13846
|
+
const { localPlacementId, productDefinitionShapeId } = writeFootingGeometry(w, footing.spec, geomSubContextId, storeyPlacementId);
|
|
13847
|
+
const footingExpressId = writeFootingEntity(w, footing.guid, `Footing ${i + 1}`, footing.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13848
|
+
idMap.set(footing.localId, footingExpressId);
|
|
13849
|
+
placementMap.set(footing.localId, localPlacementId);
|
|
13850
|
+
writeFootingCommonPset(w, ownerHistoryId, footingExpressId, footing.spec);
|
|
13851
|
+
if (footing.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, footingExpressId, footing.spec.customProperties);
|
|
13852
|
+
writeFootingBaseQuantities(w, ownerHistoryId, footingExpressId, footing.spec);
|
|
13853
|
+
}
|
|
13854
|
+
for (const [i, pile] of piles.entries()) {
|
|
13855
|
+
const containingId = findContainerOf(pile.localId, relationships);
|
|
13856
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13857
|
+
const { localPlacementId, productDefinitionShapeId } = writePileGeometry(w, pile.spec, geomSubContextId, storeyPlacementId);
|
|
13858
|
+
const pileExpressId = writePileEntity(w, pile.guid, `Pile ${i + 1}`, pile.spec.predefinedType ?? "NOTDEFINED", pile.spec.constructionType ?? null, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13859
|
+
idMap.set(pile.localId, pileExpressId);
|
|
13860
|
+
placementMap.set(pile.localId, localPlacementId);
|
|
13861
|
+
writePileCommonPset(w, ownerHistoryId, pileExpressId, pile.spec);
|
|
13862
|
+
if (pile.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, pileExpressId, pile.spec.customProperties);
|
|
13863
|
+
writePileBaseQuantities(w, ownerHistoryId, pileExpressId, pile.spec);
|
|
13864
|
+
}
|
|
13865
|
+
for (const [i, assembly] of assemblies.entries()) {
|
|
13866
|
+
const containingId = findContainerOf(assembly.localId, relationships);
|
|
13867
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13868
|
+
const assemblyExpressId = writeElementAssemblyEntity(w, assembly.guid, assembly.spec.name ?? `Assembly ${i + 1}`, assembly.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, storeyPlacementId, null, assembly.spec.assemblyPlace ?? "NOTDEFINED");
|
|
13869
|
+
idMap.set(assembly.localId, assemblyExpressId);
|
|
13870
|
+
}
|
|
13871
|
+
for (const zone of zones) {
|
|
13872
|
+
const zoneExpressId = writeZoneEntity(w, zone.guid, zone.spec.name, zone.spec.longName ?? null, zone.spec.objectType ?? null, ownerHistoryId);
|
|
13873
|
+
idMap.set(zone.localId, zoneExpressId);
|
|
13874
|
+
}
|
|
13875
|
+
for (const system of systems) {
|
|
13876
|
+
const systemExpressId = writeSystemEntity(w, system.guid, system.spec.name, system.spec.longName ?? null, system.spec.objectType ?? null, ownerHistoryId);
|
|
13877
|
+
idMap.set(system.localId, systemExpressId);
|
|
13878
|
+
}
|
|
13879
|
+
for (const stair of stairs) {
|
|
13880
|
+
const containingId = findContainerOf(stair.localId, relationships);
|
|
13881
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13882
|
+
const result = writeStairAssembly(w, stair.spec, `${stair.localId}`, stair.guid, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
13883
|
+
if (!result.ok) return (0, brepjs.err)(result.error);
|
|
13884
|
+
idMap.set(stair.localId, result.value.assemblyExpressId);
|
|
13885
|
+
writeStairCommonPset(w, ownerHistoryId, result.value.assemblyExpressId, stair.spec);
|
|
13886
|
+
}
|
|
13887
|
+
for (const ramp of ramps) {
|
|
13888
|
+
const containingId = findContainerOf(ramp.localId, relationships);
|
|
13889
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13890
|
+
const result = writeRampAssembly(w, ramp.spec, `${ramp.localId}`, ramp.guid, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
13891
|
+
if (!result.ok) return (0, brepjs.err)(result.error);
|
|
13892
|
+
idMap.set(ramp.localId, result.value.assemblyExpressId);
|
|
13893
|
+
writeRampCommonPset(w, ownerHistoryId, result.value.assemblyExpressId, ramp.spec);
|
|
13894
|
+
}
|
|
13895
|
+
for (const [i, preflighted] of preflightedRailings.entries()) {
|
|
13896
|
+
const railing = preflighted.element;
|
|
13897
|
+
const containingId = findContainerOf(railing.localId, relationships);
|
|
13898
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13899
|
+
let representation;
|
|
13900
|
+
let exactBodyItemIds = [];
|
|
13901
|
+
if (preflighted.kind === "EXACT") {
|
|
13902
|
+
const exact = writeExactBodyGeometry(w, railing.spec, preflighted.items, geomSubContextId, storeyPlacementId);
|
|
13903
|
+
exactBodyItemIds = exact.bodyItemIds;
|
|
13904
|
+
representation = {
|
|
13905
|
+
...exact,
|
|
13906
|
+
bodyItemId: null,
|
|
13907
|
+
usedFallback: false
|
|
13908
|
+
};
|
|
13909
|
+
} else representation = writeRailingGeometry(w, railing.spec, preflighted.solid, geomSubContextId, storeyPlacementId);
|
|
13910
|
+
const { localPlacementId, productDefinitionShapeId, bodyItemId, usedFallback } = representation;
|
|
13911
|
+
if (usedFallback) console.warn(`Railing ${i + 1} tessellation failed; IFC body is a degenerate fallback.`);
|
|
13912
|
+
const railingExpressId = writeRailingEntity(w, railing.guid, `Railing ${i + 1}`, railing.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13913
|
+
idMap.set(railing.localId, railingExpressId);
|
|
13914
|
+
placementMap.set(railing.localId, localPlacementId);
|
|
13915
|
+
writeRailingCommonPset(w, ownerHistoryId, railingExpressId, railing.spec);
|
|
13916
|
+
writeManufacturerPset(w, ownerHistoryId, railingExpressId, railing.spec);
|
|
13917
|
+
if (railing.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, railingExpressId, railing.spec.customProperties);
|
|
13918
|
+
if (preflighted.kind === "EXACT") for (const itemId of exactBodyItemIds) applySurfaceStyle(w, model, railing.localId, itemId);
|
|
13919
|
+
else if (bodyItemId !== null) applySurfaceStyle(w, model, railing.localId, bodyItemId);
|
|
13920
|
+
}
|
|
13921
|
+
for (const [i, covering] of coverings.entries()) {
|
|
13922
|
+
const containingId = findContainerOf(covering.localId, relationships);
|
|
13923
|
+
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
13924
|
+
const { localPlacementId, productDefinitionShapeId, bodyItemId } = writeCoveringGeometry(w, covering.spec, geomSubContextId, storeyPlacementId);
|
|
13925
|
+
const coveringExpressId = writeCoveringEntity(w, covering.guid, `Covering ${i + 1}`, covering.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
13926
|
+
idMap.set(covering.localId, coveringExpressId);
|
|
13927
|
+
placementMap.set(covering.localId, localPlacementId);
|
|
13928
|
+
writeCoveringCommonPset(w, ownerHistoryId, coveringExpressId, covering.spec);
|
|
13929
|
+
writeManufacturerPset(w, ownerHistoryId, coveringExpressId, covering.spec);
|
|
13930
|
+
if (covering.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, coveringExpressId, covering.spec.customProperties);
|
|
13931
|
+
applySurfaceStyle(w, model, covering.localId, bodyItemId);
|
|
13932
|
+
}
|
|
13933
|
+
const openingPlacementMap = /* @__PURE__ */ new Map();
|
|
13934
|
+
const openingEntityMap = /* @__PURE__ */ new Map();
|
|
13935
|
+
for (const rel of relationships) {
|
|
13936
|
+
if (rel.kind !== "VOIDS_WALL") continue;
|
|
13937
|
+
const wallElement = elements.find((el) => el.category === "WALL" && el.localId === rel.wallLocalId);
|
|
13938
|
+
if (wallElement === void 0) continue;
|
|
13939
|
+
const wallExpressId = idMap.get(rel.wallLocalId);
|
|
13940
|
+
const wallPlacementId = placementMap.get(rel.wallLocalId);
|
|
13941
|
+
if (wallExpressId === void 0 || wallPlacementId === void 0) continue;
|
|
13942
|
+
const openingElement = elements.find((el) => el.localId === rel.openingLocalId);
|
|
13943
|
+
if (openingElement === void 0 || openingElement.category !== "OPENING") continue;
|
|
13944
|
+
if (!isWallOpening(openingElement.spec)) continue;
|
|
13945
|
+
const { openingEntityId, openingPlacementId } = writeOpeningGeometry(w, openingElement.guid, openingElement.spec, wallElement.spec, wallPlacementId, geomSubContextId, ownerHistoryId);
|
|
13946
|
+
idMap.set(rel.openingLocalId, openingEntityId);
|
|
13947
|
+
openingPlacementMap.set(rel.openingLocalId, openingPlacementId);
|
|
13948
|
+
openingEntityMap.set(rel.openingLocalId, openingEntityId);
|
|
13949
|
+
writeRelVoidsElement(w, rel.guid, ownerHistoryId, wallExpressId, openingEntityId);
|
|
13950
|
+
}
|
|
13951
|
+
for (const rel of relationships) {
|
|
13952
|
+
if (rel.kind !== "VOIDS_SLAB") continue;
|
|
13953
|
+
const slabElement = elements.find((el) => el.category === "SLAB" && el.localId === rel.slabLocalId);
|
|
13954
|
+
if (slabElement === void 0) continue;
|
|
13955
|
+
const slabExpressId = idMap.get(rel.slabLocalId);
|
|
13956
|
+
const slabPlacementId = placementMap.get(rel.slabLocalId);
|
|
13957
|
+
if (slabExpressId === void 0 || slabPlacementId === void 0) continue;
|
|
13958
|
+
const openingElement = elements.find((el) => el.localId === rel.openingLocalId);
|
|
13959
|
+
if (openingElement === void 0 || openingElement.category !== "OPENING") continue;
|
|
13960
|
+
if (!isSlabOpening(openingElement.spec)) continue;
|
|
13961
|
+
const { openingEntityId } = writeSlabOpeningGeometry(w, openingElement.guid, openingElement.spec, slabElement.spec, slabPlacementId, geomSubContextId, ownerHistoryId);
|
|
13962
|
+
idMap.set(rel.openingLocalId, openingEntityId);
|
|
13963
|
+
writeRelVoidsElement(w, rel.guid, ownerHistoryId, slabExpressId, openingEntityId);
|
|
13964
|
+
}
|
|
13965
|
+
for (const [i, door] of doors.entries()) {
|
|
13966
|
+
const fillsRel = relationships.find((rel) => rel.kind === "FILLS_OPENING" && rel.fillerLocalId === door.localId);
|
|
13967
|
+
if (fillsRel === void 0 || fillsRel.kind !== "FILLS_OPENING") continue;
|
|
13968
|
+
const openingPlacementId = openingPlacementMap.get(fillsRel.openingLocalId);
|
|
13969
|
+
const openingEntityId = openingEntityMap.get(fillsRel.openingLocalId);
|
|
13970
|
+
if (openingPlacementId === void 0 || openingEntityId === void 0) continue;
|
|
13971
|
+
const doorExpressId = writeDoorEntity(w, door.guid, `Door ${i + 1}`, ownerHistoryId, openingPlacementId, geomSubContextId, toIfcLengthM(door.spec.width), toIfcLengthM(door.spec.height));
|
|
13972
|
+
idMap.set(door.localId, doorExpressId);
|
|
13973
|
+
writeRelFillsElement(w, fillsRel.guid, ownerHistoryId, openingEntityId, doorExpressId);
|
|
13974
|
+
writeDoorCommonPset(w, ownerHistoryId, doorExpressId, door.spec);
|
|
13975
|
+
}
|
|
13976
|
+
for (const [i, win] of windows.entries()) {
|
|
13977
|
+
const fillsRel = relationships.find((rel) => rel.kind === "FILLS_OPENING" && rel.fillerLocalId === win.localId);
|
|
13978
|
+
if (fillsRel === void 0 || fillsRel.kind !== "FILLS_OPENING") continue;
|
|
13979
|
+
const openingPlacementId = openingPlacementMap.get(fillsRel.openingLocalId);
|
|
13980
|
+
const openingEntityId = openingEntityMap.get(fillsRel.openingLocalId);
|
|
13981
|
+
if (openingPlacementId === void 0 || openingEntityId === void 0) continue;
|
|
13982
|
+
const windowExpressId = writeWindowEntity(w, win.guid, `Window ${i + 1}`, ownerHistoryId, openingPlacementId, geomSubContextId, toIfcLengthM(win.spec.width), toIfcLengthM(win.spec.height));
|
|
13983
|
+
idMap.set(win.localId, windowExpressId);
|
|
13984
|
+
writeRelFillsElement(w, fillsRel.guid, ownerHistoryId, openingEntityId, windowExpressId);
|
|
13985
|
+
writeWindowCommonPset(w, ownerHistoryId, windowExpressId, win.spec);
|
|
13986
|
+
}
|
|
13987
|
+
for (const rel of relationships) {
|
|
13988
|
+
if (rel.kind !== "AGGREGATES") continue;
|
|
13989
|
+
const parentExpressId = idMap.get(rel.relatingObject);
|
|
13990
|
+
const childExpressIds = rel.relatedObjects.map((id) => idMap.get(id)).filter((id) => id !== void 0);
|
|
13991
|
+
if (parentExpressId === void 0 || childExpressIds.length === 0) continue;
|
|
13992
|
+
writeRelAggregates(w, rel.guid, ownerHistoryId, parentExpressId, childExpressIds);
|
|
13993
|
+
}
|
|
13994
|
+
for (const rel of relationships) {
|
|
13995
|
+
if (rel.kind !== "CONTAINED_IN") continue;
|
|
13996
|
+
const structureExpressId = idMap.get(rel.relatingStructure);
|
|
13997
|
+
const elementExpressIds = rel.relatedElements.map((id) => idMap.get(id)).filter((id) => id !== void 0);
|
|
13998
|
+
if (structureExpressId === void 0 || elementExpressIds.length === 0) continue;
|
|
13999
|
+
writeRelContainedInSpatialStructure(w, rel.guid, ownerHistoryId, structureExpressId, elementExpressIds);
|
|
14000
|
+
}
|
|
14001
|
+
for (const rel of relationships) {
|
|
14002
|
+
if (rel.kind !== "SPACE_BOUNDARY") continue;
|
|
14003
|
+
const spaceExpressId = idMap.get(rel.spaceLocalId);
|
|
14004
|
+
const elementExpressId = idMap.get(rel.elementLocalId);
|
|
14005
|
+
if (spaceExpressId === void 0 || elementExpressId === void 0) continue;
|
|
14006
|
+
writeRelSpaceBoundary(w, rel.guid, ownerHistoryId, spaceExpressId, elementExpressId, rel.connectionType);
|
|
14007
|
+
}
|
|
14008
|
+
for (const rel of relationships) {
|
|
14009
|
+
if (rel.kind !== "NESTS") continue;
|
|
14010
|
+
const parentExpressId = idMap.get(rel.relatingObject);
|
|
14011
|
+
const childExpressIds = rel.relatedObjects.map((id) => idMap.get(id)).filter((id) => id !== void 0);
|
|
14012
|
+
if (parentExpressId === void 0 || childExpressIds.length === 0) continue;
|
|
14013
|
+
writeRelNests(w, rel.guid, ownerHistoryId, parentExpressId, childExpressIds);
|
|
14014
|
+
}
|
|
14015
|
+
for (const rel of relationships) {
|
|
14016
|
+
if (rel.kind !== "COVERS_ELEMENT") continue;
|
|
14017
|
+
const hostExpressId = idMap.get(rel.hostLocalId);
|
|
14018
|
+
const coveringExpressId = idMap.get(rel.coveringLocalId);
|
|
14019
|
+
if (hostExpressId === void 0 || coveringExpressId === void 0) continue;
|
|
14020
|
+
writeRelCoversBldgElements(w, rel.guid, ownerHistoryId, hostExpressId, [coveringExpressId]);
|
|
14021
|
+
}
|
|
14022
|
+
for (const rel of relationships) {
|
|
14023
|
+
if (rel.kind !== "ASSIGNS_TO_GROUP") continue;
|
|
14024
|
+
const groupExpressId = idMap.get(rel.groupLocalId);
|
|
14025
|
+
const memberExpressIds = rel.memberLocalIds.map((id) => idMap.get(id)).filter((id) => id !== void 0);
|
|
14026
|
+
if (groupExpressId === void 0 || memberExpressIds.length === 0) continue;
|
|
14027
|
+
writeRelAssignsToGroup(w, rel.guid, ownerHistoryId, groupExpressId, memberExpressIds);
|
|
14028
|
+
}
|
|
14029
|
+
for (const rel of relationships) {
|
|
14030
|
+
if (rel.kind !== "CONNECTS_ELEMENTS") continue;
|
|
14031
|
+
const relatingExpressId = idMap.get(rel.relatingElementLocalId);
|
|
14032
|
+
const relatedExpressId = idMap.get(rel.relatedElementLocalId);
|
|
14033
|
+
if (relatingExpressId === void 0 || relatedExpressId === void 0) continue;
|
|
14034
|
+
writeRelConnectsElements(w, rel.guid, ownerHistoryId, relatingExpressId, relatedExpressId, rel.description ?? null);
|
|
14035
|
+
}
|
|
14036
|
+
for (const rel of relationships) {
|
|
14037
|
+
if (rel.kind !== "CONNECTS_PATH_ELEMENTS") continue;
|
|
14038
|
+
const relatingExpressId = idMap.get(rel.relatingElementLocalId);
|
|
14039
|
+
const relatedExpressId = idMap.get(rel.relatedElementLocalId);
|
|
14040
|
+
if (relatingExpressId === void 0 || relatedExpressId === void 0) continue;
|
|
14041
|
+
writeRelConnectsPathElements(w, rel.guid, ownerHistoryId, relatingExpressId, relatedExpressId, rel.relatingConnectionType, rel.relatedConnectionType, rel.description ?? null);
|
|
14042
|
+
}
|
|
14043
|
+
const bySimpleMaterial = /* @__PURE__ */ new Map();
|
|
14044
|
+
const layeredAssociations = [];
|
|
14045
|
+
const categoryById = new Map(elements.map((e) => [e.localId, e.category]));
|
|
14046
|
+
for (const rel of relationships) {
|
|
14047
|
+
if (rel.kind !== "ASSOCIATES_MATERIAL") continue;
|
|
14048
|
+
const objectExpressIds = rel.relatedObjects.map((id) => idMap.get(id)).filter((id) => id !== void 0);
|
|
14049
|
+
if (objectExpressIds.length === 0) continue;
|
|
14050
|
+
if (rel.materialLayers !== void 0 && rel.materialLayers.length > 0) {
|
|
14051
|
+
const firstObj = rel.relatedObjects[0];
|
|
14052
|
+
const hostCat = firstObj !== void 0 ? categoryById.get(firstObj) : void 0;
|
|
14053
|
+
const direction = hostCat === "SLAB" || hostCat === "ROOF" || hostCat === "COVERING" ? "AXIS3" : "AXIS2";
|
|
14054
|
+
layeredAssociations.push({
|
|
14055
|
+
guid: rel.guid,
|
|
14056
|
+
layerSetName: rel.layerSetName ?? rel.materialName,
|
|
14057
|
+
layers: rel.materialLayers,
|
|
14058
|
+
ids: objectExpressIds,
|
|
14059
|
+
direction
|
|
14060
|
+
});
|
|
14061
|
+
continue;
|
|
14062
|
+
}
|
|
14063
|
+
const existing = bySimpleMaterial.get(rel.materialName);
|
|
14064
|
+
if (existing !== void 0) bySimpleMaterial.set(rel.materialName, {
|
|
14065
|
+
guid: existing.guid,
|
|
14066
|
+
ids: [...existing.ids, ...objectExpressIds]
|
|
14067
|
+
});
|
|
14068
|
+
else bySimpleMaterial.set(rel.materialName, {
|
|
14069
|
+
guid: rel.guid,
|
|
14070
|
+
ids: objectExpressIds
|
|
14071
|
+
});
|
|
14072
|
+
}
|
|
14073
|
+
for (const [materialName, { guid, ids }] of bySimpleMaterial) {
|
|
14074
|
+
if (ids.length === 0) continue;
|
|
14075
|
+
writeMaterialSimple(w, guid, ownerHistoryId, materialName, ids);
|
|
14076
|
+
}
|
|
14077
|
+
for (const assoc of layeredAssociations) writeMaterialLayerSet(w, assoc.guid, ownerHistoryId, {
|
|
14078
|
+
kind: "LAYER_SET",
|
|
14079
|
+
layerSetName: assoc.layerSetName,
|
|
14080
|
+
layers: assoc.layers
|
|
14081
|
+
}, assoc.ids, assoc.direction);
|
|
14082
|
+
const classByKey = /* @__PURE__ */ new Map();
|
|
14083
|
+
for (const rel of relationships) {
|
|
14084
|
+
if (rel.kind !== "ASSOCIATES_CLASSIFICATION") continue;
|
|
14085
|
+
const objectExpressIds = rel.relatedObjects.map((id) => idMap.get(id)).filter((id) => id !== void 0);
|
|
14086
|
+
if (objectExpressIds.length === 0) continue;
|
|
14087
|
+
const key = `${rel.ref.system}:${rel.ref.code}`;
|
|
14088
|
+
const entry = classByKey.get(key);
|
|
14089
|
+
if (entry === void 0) classByKey.set(key, {
|
|
14090
|
+
ref: rel.ref,
|
|
14091
|
+
ids: [...objectExpressIds]
|
|
14092
|
+
});
|
|
14093
|
+
else entry.ids.push(...objectExpressIds);
|
|
14094
|
+
}
|
|
14095
|
+
const byClassification = /* @__PURE__ */ new Map();
|
|
14096
|
+
for (const { ref, ids } of classByKey.values()) byClassification.set(ref, ids);
|
|
14097
|
+
if (byClassification.size > 0) writeClassificationRefs(w, ownerHistoryId, byClassification);
|
|
14098
|
+
writeTypeLayer(w, ownerHistoryId, model, idMap);
|
|
14099
|
+
return w.save();
|
|
14100
|
+
} catch (_) {
|
|
14101
|
+
_usingCtx$2.e = _;
|
|
14102
|
+
} finally {
|
|
14103
|
+
_usingCtx$2.d();
|
|
13753
14104
|
}
|
|
13754
|
-
const byClassification = /* @__PURE__ */ new Map();
|
|
13755
|
-
for (const { ref, ids } of classByKey.values()) byClassification.set(ref, ids);
|
|
13756
|
-
if (byClassification.size > 0) writeClassificationRefs(w, ownerHistoryId, byClassification);
|
|
13757
|
-
writeTypeLayer(w, ownerHistoryId, model, idMap);
|
|
13758
|
-
return w.save();
|
|
13759
14105
|
}
|
|
13760
14106
|
/**
|
|
13761
14107
|
* Auto-derives one IfcType per (category, predefinedType) group of occurrences
|
|
@@ -13897,7 +14243,6 @@ async function toIfcValidated(model, meta) {
|
|
|
13897
14243
|
function collectGeometryIssues(model) {
|
|
13898
14244
|
const issues = [];
|
|
13899
14245
|
const groups = [
|
|
13900
|
-
["Wall", model.getWalls()],
|
|
13901
14246
|
["Slab", model.getSlabs()],
|
|
13902
14247
|
["Beam", model.getBeams()],
|
|
13903
14248
|
["Column", model.getColumns()],
|
|
@@ -13907,13 +14252,19 @@ function collectGeometryIssues(model) {
|
|
|
13907
14252
|
["Roof", model.getRoofs()],
|
|
13908
14253
|
["Footing", model.getFootings()],
|
|
13909
14254
|
["Pile", model.getPiles()],
|
|
13910
|
-
["Railing", model.getRailings()],
|
|
13911
14255
|
["Covering", model.getCoverings()]
|
|
13912
14256
|
];
|
|
13913
14257
|
for (const [label, elements] of groups) elements.forEach((el, index) => {
|
|
13914
14258
|
const report = checkGeometryValidity(el.geometry, `${label} ${index + 1}`);
|
|
13915
14259
|
issues.push(...report.issues);
|
|
13916
14260
|
});
|
|
14261
|
+
const productGroups = [["Wall", model.getWalls()], ["Railing", model.getRailings()]];
|
|
14262
|
+
for (const [label, elements] of productGroups) elements.forEach((el, index) => {
|
|
14263
|
+
bodySolids(el.geometry).forEach((solid, itemIndex) => {
|
|
14264
|
+
const report = checkGeometryValidity(solid, `${label} ${index + 1} Body item ${itemIndex + 1}`);
|
|
14265
|
+
issues.push(...report.issues);
|
|
14266
|
+
});
|
|
14267
|
+
});
|
|
13917
14268
|
model.getRamps().forEach((ramp, index) => {
|
|
13918
14269
|
if (ramp.spec.flights.length === 0) return;
|
|
13919
14270
|
issues.push(issue("info", "SIMPLIFIED_GEOMETRY", `Ramp ${index + 1} uses simplified inclined-slab flight geometry`));
|
|
@@ -29621,6 +29972,7 @@ exports.PSET_PROPERTY_TYPE_TABLE = PSET_PROPERTY_TYPE_TABLE;
|
|
|
29621
29972
|
exports.PSET_TEMPLATES = PSET_TEMPLATES;
|
|
29622
29973
|
exports.SpfReader = SpfReader;
|
|
29623
29974
|
exports.bcfError = bcfError;
|
|
29975
|
+
exports.bodySolids = bodySolids;
|
|
29624
29976
|
exports.checkGeometryValidity = checkGeometryValidity;
|
|
29625
29977
|
exports.checkGherkinRules = checkGherkinRules;
|
|
29626
29978
|
exports.checkIds = checkIdsData;
|