brepjs-bim 0.24.4 → 0.25.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 +21 -0
- package/dist/brepjs-bim.cjs +409 -415
- package/dist/brepjs-bim.js +401 -407
- package/dist/geometryCleanupDiagnostics.d.ts +6 -0
- package/dist/ifc-writer/geometryWriter.d.ts +0 -6
- package/dist/ifc-writer/headerWriter.d.ts +2 -0
- package/dist/ifc-writer/openingWriter.d.ts +1 -1
- package/dist/ifc-writer/tessellationWriter.d.ts +2 -2
- package/dist/import/cutImportedSolids.d.ts +4 -0
- package/dist/import/fromIfc.d.ts +1 -1
- package/dist/import/importedModel.d.ts +6 -3
- package/dist/serialize/productBodyPreflight.d.ts +15 -0
- package/package.json +2 -2
- package/dist/serialize/exactBodyPreflight.d.ts +0 -15
package/dist/brepjs-bim.cjs
CHANGED
|
@@ -266,7 +266,7 @@ function _usingCtx() {
|
|
|
266
266
|
//#region src/elementFns/wallFns.ts
|
|
267
267
|
function wallToSolid(spec) {
|
|
268
268
|
try {
|
|
269
|
-
var _usingCtx$
|
|
269
|
+
var _usingCtx$21 = _usingCtx();
|
|
270
270
|
if (spec.length <= 0) return (0, brepjs.err)(specError("WALL_ZERO_LENGTH", "Wall length must be positive"));
|
|
271
271
|
if (spec.height <= 0) return (0, brepjs.err)(specError("WALL_ZERO_HEIGHT", "Wall height must be positive"));
|
|
272
272
|
if (spec.thickness <= 0) return (0, brepjs.err)(specError("WALL_ZERO_THICKNESS", "Wall thickness must be positive"));
|
|
@@ -294,7 +294,7 @@ function wallToSolid(spec) {
|
|
|
294
294
|
]
|
|
295
295
|
]);
|
|
296
296
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "WALL_PROFILE_FAILED", "Failed to create wall profile"));
|
|
297
|
-
const profile = _usingCtx$
|
|
297
|
+
const profile = _usingCtx$21.u(profileResult.value);
|
|
298
298
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
299
299
|
length,
|
|
300
300
|
0,
|
|
@@ -308,16 +308,16 @@ function wallToSolid(spec) {
|
|
|
308
308
|
}
|
|
309
309
|
return (0, brepjs.ok)(solid);
|
|
310
310
|
} catch (_) {
|
|
311
|
-
_usingCtx$
|
|
311
|
+
_usingCtx$21.e = _;
|
|
312
312
|
} finally {
|
|
313
|
-
_usingCtx$
|
|
313
|
+
_usingCtx$21.d();
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
//#endregion
|
|
317
317
|
//#region src/elementFns/slabFns.ts
|
|
318
318
|
function slabToSolid(spec) {
|
|
319
319
|
try {
|
|
320
|
-
var _usingCtx$
|
|
320
|
+
var _usingCtx$20 = _usingCtx();
|
|
321
321
|
if (spec.length <= 0) return (0, brepjs.err)(specError("SLAB_ZERO_LENGTH", "Slab length must be positive"));
|
|
322
322
|
if (spec.width <= 0) return (0, brepjs.err)(specError("SLAB_ZERO_WIDTH", "Slab width must be positive"));
|
|
323
323
|
if (spec.thickness <= 0) return (0, brepjs.err)(specError("SLAB_ZERO_THICKNESS", "Slab thickness must be positive"));
|
|
@@ -345,7 +345,7 @@ function slabToSolid(spec) {
|
|
|
345
345
|
]
|
|
346
346
|
]);
|
|
347
347
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "SLAB_PROFILE_FAILED", "Failed to create slab profile"));
|
|
348
|
-
const profile = _usingCtx$
|
|
348
|
+
const profile = _usingCtx$20.u(profileResult.value);
|
|
349
349
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
350
350
|
0,
|
|
351
351
|
0,
|
|
@@ -359,9 +359,9 @@ function slabToSolid(spec) {
|
|
|
359
359
|
}
|
|
360
360
|
return (0, brepjs.ok)(solid);
|
|
361
361
|
} catch (_) {
|
|
362
|
-
_usingCtx$
|
|
362
|
+
_usingCtx$20.e = _;
|
|
363
363
|
} finally {
|
|
364
|
-
_usingCtx$
|
|
364
|
+
_usingCtx$20.d();
|
|
365
365
|
}
|
|
366
366
|
}
|
|
367
367
|
//#endregion
|
|
@@ -522,7 +522,7 @@ var propertyKeyTypes = /* @__PURE__*/ new Set([
|
|
|
522
522
|
function escapeRegex(str) {
|
|
523
523
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
524
524
|
}
|
|
525
|
-
function clone$
|
|
525
|
+
function clone$4(inst, def, params) {
|
|
526
526
|
const cl = new inst._zod.constr(def ?? inst._zod.def);
|
|
527
527
|
if (!def || params?.parent) cl._zod.parent = inst;
|
|
528
528
|
return cl;
|
|
@@ -569,7 +569,7 @@ function pick(schema, mask) {
|
|
|
569
569
|
if (checks && checks.length > 0) throw new Error(".pick() cannot be used on object schemas containing refinements");
|
|
570
570
|
const newShape = {};
|
|
571
571
|
mirrorShape(newShape, schema, maskedKeys(schema, mask));
|
|
572
|
-
return clone$
|
|
572
|
+
return clone$4(schema, mergeDefs(currDef, {
|
|
573
573
|
shape: newShape,
|
|
574
574
|
checks: []
|
|
575
575
|
}));
|
|
@@ -590,7 +590,7 @@ function omit(schema, mask) {
|
|
|
590
590
|
const omitted = new Set(maskedKeys(schema, mask));
|
|
591
591
|
const newShape = {};
|
|
592
592
|
mirrorShape(newShape, schema, Reflect.ownKeys(sourceShape(schema)).filter((key) => !omitted.has(key)));
|
|
593
|
-
return clone$
|
|
593
|
+
return clone$4(schema, mergeDefs(currDef, {
|
|
594
594
|
shape: newShape,
|
|
595
595
|
checks: []
|
|
596
596
|
}));
|
|
@@ -602,7 +602,7 @@ function extend(schema, shape) {
|
|
|
602
602
|
const existingShape = sourceShape(schema);
|
|
603
603
|
for (const key of Reflect.ownKeys(shape)) if (Object.getOwnPropertyDescriptor(existingShape, key) !== void 0) throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.");
|
|
604
604
|
}
|
|
605
|
-
return clone$
|
|
605
|
+
return clone$4(schema, mergeDefs(schema._zod.def, { shape: extended(schema, shape) }));
|
|
606
606
|
}
|
|
607
607
|
function extended(schema, shape) {
|
|
608
608
|
const newShape = {};
|
|
@@ -612,7 +612,7 @@ function extended(schema, shape) {
|
|
|
612
612
|
}
|
|
613
613
|
function safeExtend(schema, shape) {
|
|
614
614
|
if (!isPlainObject(shape)) throw new Error("Invalid input to safeExtend: expected a plain object");
|
|
615
|
-
return clone$
|
|
615
|
+
return clone$4(schema, mergeDefs(schema._zod.def, { shape: extended(schema, shape) }));
|
|
616
616
|
}
|
|
617
617
|
function merge(a, b) {
|
|
618
618
|
if (!b?._zod?.def) throw new Error("Invalid input to merge: expected an object schema. To merge a plain shape, use `.extend()`.");
|
|
@@ -620,7 +620,7 @@ function merge(a, b) {
|
|
|
620
620
|
const newShape = {};
|
|
621
621
|
mirrorShape(newShape, a, Reflect.ownKeys(sourceShape(a)));
|
|
622
622
|
mirrorShape(newShape, b, Reflect.ownKeys(sourceShape(b)));
|
|
623
|
-
return clone$
|
|
623
|
+
return clone$4(a, mergeDefs(a._zod.def, {
|
|
624
624
|
shape: newShape,
|
|
625
625
|
get catchall() {
|
|
626
626
|
return b._zod.def.catchall;
|
|
@@ -637,7 +637,7 @@ function partial(Class, schema, mask, name = "partial") {
|
|
|
637
637
|
type: "optional",
|
|
638
638
|
innerType: value
|
|
639
639
|
})));
|
|
640
|
-
return clone$
|
|
640
|
+
return clone$4(schema, mergeDefs(schema._zod.def, {
|
|
641
641
|
shape: newShape,
|
|
642
642
|
checks: []
|
|
643
643
|
}));
|
|
@@ -649,7 +649,7 @@ function required(Class, schema, mask) {
|
|
|
649
649
|
type: "nonoptional",
|
|
650
650
|
innerType: value
|
|
651
651
|
}));
|
|
652
|
-
return clone$
|
|
652
|
+
return clone$4(schema, mergeDefs(schema._zod.def, { shape: newShape }));
|
|
653
653
|
}
|
|
654
654
|
function aborted(x, startIndex = 0) {
|
|
655
655
|
if (x.aborted === true) return true;
|
|
@@ -1719,7 +1719,7 @@ var Doc = class {
|
|
|
1719
1719
|
var version = {
|
|
1720
1720
|
major: 4,
|
|
1721
1721
|
minor: 6,
|
|
1722
|
-
patch:
|
|
1722
|
+
patch: 5
|
|
1723
1723
|
};
|
|
1724
1724
|
//#endregion
|
|
1725
1725
|
//#region ../../node_modules/zod/v4/core/schemas.js
|
|
@@ -5215,7 +5215,7 @@ var ZodType = /*@__PURE__*/ $constructor("ZodType", (inst, def) => {
|
|
|
5215
5215
|
return this.check(...chks);
|
|
5216
5216
|
},
|
|
5217
5217
|
clone(def, params) {
|
|
5218
|
-
return clone$
|
|
5218
|
+
return clone$4(this, def, params);
|
|
5219
5219
|
},
|
|
5220
5220
|
brand() {
|
|
5221
5221
|
return this;
|
|
@@ -6358,14 +6358,14 @@ function to3D(points) {
|
|
|
6358
6358
|
}
|
|
6359
6359
|
function extendedProfileToFace(profile) {
|
|
6360
6360
|
try {
|
|
6361
|
-
var _usingCtx$
|
|
6361
|
+
var _usingCtx$19 = _usingCtx();
|
|
6362
6362
|
const invalid = validateProfile(profile);
|
|
6363
6363
|
if (invalid !== null) return (0, brepjs.err)(invalid);
|
|
6364
6364
|
const outerResult = (0, brepjs.polygon)(to3D(outerLoop(profile)));
|
|
6365
6365
|
if (!outerResult.ok) return (0, brepjs.err)(fromBrepError(outerResult.error, "PROFILE_FACE_FAILED", "Failed to build profile outer face"));
|
|
6366
6366
|
const holes = holeLoops(profile);
|
|
6367
6367
|
if (holes.length === 0) return (0, brepjs.ok)(outerResult.value);
|
|
6368
|
-
const outerFace = _usingCtx$
|
|
6368
|
+
const outerFace = _usingCtx$19.u(outerResult.value);
|
|
6369
6369
|
const holeFaces = [];
|
|
6370
6370
|
const holeWires = [];
|
|
6371
6371
|
const disposeHoleFaces = () => {
|
|
@@ -6390,9 +6390,9 @@ function extendedProfileToFace(profile) {
|
|
|
6390
6390
|
disposeHoleFaces();
|
|
6391
6391
|
return (0, brepjs.ok)(faceWithHoles);
|
|
6392
6392
|
} catch (_) {
|
|
6393
|
-
_usingCtx$
|
|
6393
|
+
_usingCtx$19.e = _;
|
|
6394
6394
|
} finally {
|
|
6395
|
-
_usingCtx$
|
|
6395
|
+
_usingCtx$19.d();
|
|
6396
6396
|
}
|
|
6397
6397
|
}
|
|
6398
6398
|
//#endregion
|
|
@@ -6714,7 +6714,7 @@ function profileToPolygon(profile, circleSegments = 32) {
|
|
|
6714
6714
|
//#region src/elementFns/beamFns.ts
|
|
6715
6715
|
function beamToSolid(spec) {
|
|
6716
6716
|
try {
|
|
6717
|
-
var _usingCtx$
|
|
6717
|
+
var _usingCtx$18 = _usingCtx();
|
|
6718
6718
|
if (spec.length <= 0) return (0, brepjs.err)(specError("BEAM_ZERO_LENGTH", "Beam length must be positive"));
|
|
6719
6719
|
if (isExtendedProfile(spec.profile)) try {
|
|
6720
6720
|
var _usingCtx3 = _usingCtx();
|
|
@@ -6752,7 +6752,7 @@ function beamToSolid(spec) {
|
|
|
6752
6752
|
]);
|
|
6753
6753
|
const profileResult = (0, brepjs.polygon)(profilePts);
|
|
6754
6754
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "BEAM_PROFILE_FAILED", "Failed to create beam profile"));
|
|
6755
|
-
const profile = _usingCtx$
|
|
6755
|
+
const profile = _usingCtx$18.u(profileResult.value);
|
|
6756
6756
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6757
6757
|
spec.length,
|
|
6758
6758
|
0,
|
|
@@ -6766,16 +6766,16 @@ function beamToSolid(spec) {
|
|
|
6766
6766
|
}
|
|
6767
6767
|
return (0, brepjs.ok)(solid);
|
|
6768
6768
|
} catch (_) {
|
|
6769
|
-
_usingCtx$
|
|
6769
|
+
_usingCtx$18.e = _;
|
|
6770
6770
|
} finally {
|
|
6771
|
-
_usingCtx$
|
|
6771
|
+
_usingCtx$18.d();
|
|
6772
6772
|
}
|
|
6773
6773
|
}
|
|
6774
6774
|
//#endregion
|
|
6775
6775
|
//#region src/elementFns/columnFns.ts
|
|
6776
6776
|
function columnToSolid(spec) {
|
|
6777
6777
|
try {
|
|
6778
|
-
var _usingCtx$
|
|
6778
|
+
var _usingCtx$17 = _usingCtx();
|
|
6779
6779
|
if (spec.height <= 0) return (0, brepjs.err)(specError("COLUMN_ZERO_HEIGHT", "Column height must be positive"));
|
|
6780
6780
|
if (isExtendedProfile(spec.profile)) try {
|
|
6781
6781
|
var _usingCtx3 = _usingCtx();
|
|
@@ -6804,7 +6804,7 @@ function columnToSolid(spec) {
|
|
|
6804
6804
|
const profilePts = profilePtsResult.value;
|
|
6805
6805
|
const profileResult = (0, brepjs.polygon)(profilePts);
|
|
6806
6806
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "COLUMN_PROFILE_FAILED", "Failed to create column profile"));
|
|
6807
|
-
const profile = _usingCtx$
|
|
6807
|
+
const profile = _usingCtx$17.u(profileResult.value);
|
|
6808
6808
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6809
6809
|
0,
|
|
6810
6810
|
0,
|
|
@@ -6818,9 +6818,9 @@ function columnToSolid(spec) {
|
|
|
6818
6818
|
}
|
|
6819
6819
|
return (0, brepjs.ok)(solid);
|
|
6820
6820
|
} catch (_) {
|
|
6821
|
-
_usingCtx$
|
|
6821
|
+
_usingCtx$17.e = _;
|
|
6822
6822
|
} finally {
|
|
6823
|
-
_usingCtx$
|
|
6823
|
+
_usingCtx$17.d();
|
|
6824
6824
|
}
|
|
6825
6825
|
}
|
|
6826
6826
|
//#endregion
|
|
@@ -6828,7 +6828,7 @@ function columnToSolid(spec) {
|
|
|
6828
6828
|
var EPSILON_MM = 1;
|
|
6829
6829
|
function openingToSolid(spec, wallThickness) {
|
|
6830
6830
|
try {
|
|
6831
|
-
var _usingCtx$
|
|
6831
|
+
var _usingCtx$16 = _usingCtx();
|
|
6832
6832
|
if (spec.width <= 0) return (0, brepjs.err)(specError("OPENING_ZERO_WIDTH", "Opening width must be positive"));
|
|
6833
6833
|
if (spec.height <= 0) return (0, brepjs.err)(specError("OPENING_ZERO_HEIGHT", "Opening height must be positive"));
|
|
6834
6834
|
if (wallThickness <= 0) return (0, brepjs.err)(specError("OPENING_ZERO_WALL_THICKNESS", "Wall thickness must be positive"));
|
|
@@ -6860,7 +6860,7 @@ function openingToSolid(spec, wallThickness) {
|
|
|
6860
6860
|
]
|
|
6861
6861
|
]);
|
|
6862
6862
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "OPENING_PROFILE_FAILED", "Failed to create opening profile"));
|
|
6863
|
-
const profile = _usingCtx$
|
|
6863
|
+
const profile = _usingCtx$16.u(profileResult.value);
|
|
6864
6864
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6865
6865
|
spec.width,
|
|
6866
6866
|
0,
|
|
@@ -6874,16 +6874,16 @@ function openingToSolid(spec, wallThickness) {
|
|
|
6874
6874
|
}
|
|
6875
6875
|
return (0, brepjs.ok)(solid);
|
|
6876
6876
|
} catch (_) {
|
|
6877
|
-
_usingCtx$
|
|
6877
|
+
_usingCtx$16.e = _;
|
|
6878
6878
|
} finally {
|
|
6879
|
-
_usingCtx$
|
|
6879
|
+
_usingCtx$16.d();
|
|
6880
6880
|
}
|
|
6881
6881
|
}
|
|
6882
6882
|
//#endregion
|
|
6883
6883
|
//#region src/elementFns/slabOpeningFns.ts
|
|
6884
6884
|
function slabOpeningToSolid(spec, slabThickness) {
|
|
6885
6885
|
try {
|
|
6886
|
-
var _usingCtx$
|
|
6886
|
+
var _usingCtx$15 = _usingCtx();
|
|
6887
6887
|
if (spec.sizeX <= 0) return (0, brepjs.err)(specError("SLAB_OPENING_ZERO_SIZE_X", "Slab opening sizeX must be positive"));
|
|
6888
6888
|
if (spec.sizeY <= 0) return (0, brepjs.err)(specError("SLAB_OPENING_ZERO_SIZE_Y", "Slab opening sizeY must be positive"));
|
|
6889
6889
|
if (slabThickness <= 0) return (0, brepjs.err)(specError("SLAB_OPENING_ZERO_SLAB_THICKNESS", "Slab thickness must be positive"));
|
|
@@ -6915,7 +6915,7 @@ function slabOpeningToSolid(spec, slabThickness) {
|
|
|
6915
6915
|
]
|
|
6916
6916
|
]);
|
|
6917
6917
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "SLAB_OPENING_PROFILE_FAILED", "Failed to create slab opening profile"));
|
|
6918
|
-
const profile = _usingCtx$
|
|
6918
|
+
const profile = _usingCtx$15.u(profileResult.value);
|
|
6919
6919
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6920
6920
|
0,
|
|
6921
6921
|
0,
|
|
@@ -6929,16 +6929,16 @@ function slabOpeningToSolid(spec, slabThickness) {
|
|
|
6929
6929
|
}
|
|
6930
6930
|
return (0, brepjs.ok)(solid);
|
|
6931
6931
|
} catch (_) {
|
|
6932
|
-
_usingCtx$
|
|
6932
|
+
_usingCtx$15.e = _;
|
|
6933
6933
|
} finally {
|
|
6934
|
-
_usingCtx$
|
|
6934
|
+
_usingCtx$15.d();
|
|
6935
6935
|
}
|
|
6936
6936
|
}
|
|
6937
6937
|
//#endregion
|
|
6938
6938
|
//#region src/elementFns/spaceFns.ts
|
|
6939
6939
|
function spaceToSolid(spec) {
|
|
6940
6940
|
try {
|
|
6941
|
-
var _usingCtx$
|
|
6941
|
+
var _usingCtx$14 = _usingCtx();
|
|
6942
6942
|
if (spec.length <= 0) return (0, brepjs.err)(specError("SPACE_ZERO_LENGTH", "Space length must be positive"));
|
|
6943
6943
|
if (spec.width <= 0) return (0, brepjs.err)(specError("SPACE_ZERO_WIDTH", "Space width must be positive"));
|
|
6944
6944
|
if (spec.height <= 0) return (0, brepjs.err)(specError("SPACE_ZERO_HEIGHT", "Space height must be positive"));
|
|
@@ -6966,7 +6966,7 @@ function spaceToSolid(spec) {
|
|
|
6966
6966
|
]
|
|
6967
6967
|
]);
|
|
6968
6968
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "SPACE_PROFILE_FAILED", "Failed to create space footprint"));
|
|
6969
|
-
const profile = _usingCtx$
|
|
6969
|
+
const profile = _usingCtx$14.u(profileResult.value);
|
|
6970
6970
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6971
6971
|
0,
|
|
6972
6972
|
0,
|
|
@@ -6980,9 +6980,9 @@ function spaceToSolid(spec) {
|
|
|
6980
6980
|
}
|
|
6981
6981
|
return (0, brepjs.ok)(solid);
|
|
6982
6982
|
} catch (_) {
|
|
6983
|
-
_usingCtx$
|
|
6983
|
+
_usingCtx$14.e = _;
|
|
6984
6984
|
} finally {
|
|
6985
|
-
_usingCtx$
|
|
6985
|
+
_usingCtx$14.d();
|
|
6986
6986
|
}
|
|
6987
6987
|
}
|
|
6988
6988
|
//#endregion
|
|
@@ -6997,7 +6997,7 @@ function gate(solid, code) {
|
|
|
6997
6997
|
}
|
|
6998
6998
|
function flatRoof(spec) {
|
|
6999
6999
|
try {
|
|
7000
|
-
var _usingCtx$
|
|
7000
|
+
var _usingCtx$13 = _usingCtx();
|
|
7001
7001
|
const { length, width, thickness } = spec;
|
|
7002
7002
|
const face = (0, brepjs.polygon)([
|
|
7003
7003
|
[
|
|
@@ -7022,7 +7022,7 @@ function flatRoof(spec) {
|
|
|
7022
7022
|
]
|
|
7023
7023
|
]);
|
|
7024
7024
|
if (!face.ok) return (0, brepjs.err)(fromBrepError(face.error, "ROOF_PROFILE_FAILED", "Failed to create roof profile"));
|
|
7025
|
-
const profile = _usingCtx$
|
|
7025
|
+
const profile = _usingCtx$13.u(face.value);
|
|
7026
7026
|
const solid = (0, brepjs.extrude)(profile, [
|
|
7027
7027
|
0,
|
|
7028
7028
|
0,
|
|
@@ -7031,9 +7031,9 @@ function flatRoof(spec) {
|
|
|
7031
7031
|
if (!solid.ok) return (0, brepjs.err)(fromBrepError(solid.error, "ROOF_EXTRUDE_FAILED", "Failed to extrude roof profile"));
|
|
7032
7032
|
return gate(solid.value, "ROOF_INVALID_SOLID");
|
|
7033
7033
|
} catch (_) {
|
|
7034
|
-
_usingCtx$
|
|
7034
|
+
_usingCtx$13.e = _;
|
|
7035
7035
|
} finally {
|
|
7036
|
-
_usingCtx$
|
|
7036
|
+
_usingCtx$13.d();
|
|
7037
7037
|
}
|
|
7038
7038
|
}
|
|
7039
7039
|
function shedRoof(spec, pitch) {
|
|
@@ -7229,7 +7229,7 @@ function roofToSolid(spec) {
|
|
|
7229
7229
|
//#region src/elementFns/curtainWallFns.ts
|
|
7230
7230
|
function boxSolid(sizeX, sizeY, sizeZ) {
|
|
7231
7231
|
try {
|
|
7232
|
-
var _usingCtx$
|
|
7232
|
+
var _usingCtx$12 = _usingCtx();
|
|
7233
7233
|
const profileResult = (0, brepjs.polygon)([
|
|
7234
7234
|
[
|
|
7235
7235
|
0,
|
|
@@ -7253,7 +7253,7 @@ function boxSolid(sizeX, sizeY, sizeZ) {
|
|
|
7253
7253
|
]
|
|
7254
7254
|
]);
|
|
7255
7255
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "CURTAIN_WALL_PROFILE_FAILED", "Failed to create component profile"));
|
|
7256
|
-
const profile = _usingCtx$
|
|
7256
|
+
const profile = _usingCtx$12.u(profileResult.value);
|
|
7257
7257
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
7258
7258
|
0,
|
|
7259
7259
|
0,
|
|
@@ -7267,9 +7267,9 @@ function boxSolid(sizeX, sizeY, sizeZ) {
|
|
|
7267
7267
|
}
|
|
7268
7268
|
return (0, brepjs.ok)(solid);
|
|
7269
7269
|
} catch (_) {
|
|
7270
|
-
_usingCtx$
|
|
7270
|
+
_usingCtx$12.e = _;
|
|
7271
7271
|
} finally {
|
|
7272
|
-
_usingCtx$
|
|
7272
|
+
_usingCtx$12.d();
|
|
7273
7273
|
}
|
|
7274
7274
|
}
|
|
7275
7275
|
function disposeComponents(components) {
|
|
@@ -7368,7 +7368,7 @@ function curtainWallToGrid(spec) {
|
|
|
7368
7368
|
//#region src/elementFns/foundationFns.ts
|
|
7369
7369
|
function footingToSolid(spec) {
|
|
7370
7370
|
try {
|
|
7371
|
-
var _usingCtx$
|
|
7371
|
+
var _usingCtx$11 = _usingCtx();
|
|
7372
7372
|
if (spec.length <= 0) return (0, brepjs.err)(specError("FOOTING_ZERO_LENGTH", "Footing length must be positive"));
|
|
7373
7373
|
if (spec.width <= 0) return (0, brepjs.err)(specError("FOOTING_ZERO_WIDTH", "Footing width must be positive"));
|
|
7374
7374
|
if (spec.thickness <= 0) return (0, brepjs.err)(specError("FOOTING_ZERO_THICKNESS", "Footing thickness must be positive"));
|
|
@@ -7396,7 +7396,7 @@ function footingToSolid(spec) {
|
|
|
7396
7396
|
]
|
|
7397
7397
|
]);
|
|
7398
7398
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "FOOTING_PROFILE_FAILED", "Failed to create footing profile"));
|
|
7399
|
-
const profile = _usingCtx$
|
|
7399
|
+
const profile = _usingCtx$11.u(profileResult.value);
|
|
7400
7400
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
7401
7401
|
0,
|
|
7402
7402
|
0,
|
|
@@ -7410,9 +7410,9 @@ function footingToSolid(spec) {
|
|
|
7410
7410
|
}
|
|
7411
7411
|
return (0, brepjs.ok)(solid);
|
|
7412
7412
|
} catch (_) {
|
|
7413
|
-
_usingCtx$
|
|
7413
|
+
_usingCtx$11.e = _;
|
|
7414
7414
|
} finally {
|
|
7415
|
-
_usingCtx$
|
|
7415
|
+
_usingCtx$11.d();
|
|
7416
7416
|
}
|
|
7417
7417
|
}
|
|
7418
7418
|
function pileToSolid(spec) {
|
|
@@ -7469,7 +7469,7 @@ function pileToSolid(spec) {
|
|
|
7469
7469
|
//#region src/elementFns/railingFns.ts
|
|
7470
7470
|
function panelRailing(spec) {
|
|
7471
7471
|
try {
|
|
7472
|
-
var _usingCtx$
|
|
7472
|
+
var _usingCtx$10 = _usingCtx();
|
|
7473
7473
|
const { length, height, thickness } = spec;
|
|
7474
7474
|
const profileResult = (0, brepjs.polygon)([
|
|
7475
7475
|
[
|
|
@@ -7494,7 +7494,7 @@ function panelRailing(spec) {
|
|
|
7494
7494
|
]
|
|
7495
7495
|
]);
|
|
7496
7496
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "RAILING_PROFILE_FAILED", "Failed to create railing profile"));
|
|
7497
|
-
const profile = _usingCtx$
|
|
7497
|
+
const profile = _usingCtx$10.u(profileResult.value);
|
|
7498
7498
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
7499
7499
|
length,
|
|
7500
7500
|
0,
|
|
@@ -7508,9 +7508,9 @@ function panelRailing(spec) {
|
|
|
7508
7508
|
}
|
|
7509
7509
|
return (0, brepjs.ok)(solid);
|
|
7510
7510
|
} catch (_) {
|
|
7511
|
-
_usingCtx$
|
|
7511
|
+
_usingCtx$10.e = _;
|
|
7512
7512
|
} finally {
|
|
7513
|
-
_usingCtx$
|
|
7513
|
+
_usingCtx$10.d();
|
|
7514
7514
|
}
|
|
7515
7515
|
}
|
|
7516
7516
|
function postedRailing(spec) {
|
|
@@ -7573,7 +7573,7 @@ function railingToSolid(spec) {
|
|
|
7573
7573
|
//#region src/elementFns/coveringFns.ts
|
|
7574
7574
|
function coveringToSolid(spec) {
|
|
7575
7575
|
try {
|
|
7576
|
-
var _usingCtx$
|
|
7576
|
+
var _usingCtx$9 = _usingCtx();
|
|
7577
7577
|
if (spec.length <= 0) return (0, brepjs.err)(specError("COVERING_ZERO_LENGTH", "Covering length must be positive"));
|
|
7578
7578
|
if (spec.width <= 0) return (0, brepjs.err)(specError("COVERING_ZERO_WIDTH", "Covering width must be positive"));
|
|
7579
7579
|
if (spec.thickness <= 0) return (0, brepjs.err)(specError("COVERING_ZERO_THICKNESS", "Covering thickness must be positive"));
|
|
@@ -7601,7 +7601,7 @@ function coveringToSolid(spec) {
|
|
|
7601
7601
|
]
|
|
7602
7602
|
]);
|
|
7603
7603
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "COVERING_PROFILE_FAILED", "Failed to create covering profile"));
|
|
7604
|
-
const profile = _usingCtx$
|
|
7604
|
+
const profile = _usingCtx$9.u(profileResult.value);
|
|
7605
7605
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
7606
7606
|
0,
|
|
7607
7607
|
0,
|
|
@@ -7615,9 +7615,9 @@ function coveringToSolid(spec) {
|
|
|
7615
7615
|
}
|
|
7616
7616
|
return (0, brepjs.ok)(solid);
|
|
7617
7617
|
} catch (_) {
|
|
7618
|
-
_usingCtx$
|
|
7618
|
+
_usingCtx$9.e = _;
|
|
7619
7619
|
} finally {
|
|
7620
|
-
_usingCtx$
|
|
7620
|
+
_usingCtx$9.d();
|
|
7621
7621
|
}
|
|
7622
7622
|
}
|
|
7623
7623
|
//#endregion
|
|
@@ -7805,6 +7805,31 @@ function measureProductBodyMaterial(solids) {
|
|
|
7805
7805
|
return measured;
|
|
7806
7806
|
});
|
|
7807
7807
|
}
|
|
7808
|
+
/** Borrow all items and query their tight bounds in their existing coordinates. */
|
|
7809
|
+
function productBodyBounds(solids) {
|
|
7810
|
+
const items = validateItems(solids, "productBodyBounds");
|
|
7811
|
+
if (!items.ok) return items;
|
|
7812
|
+
return ownedOperation("productBodyBounds", (scope) => {
|
|
7813
|
+
let bounds;
|
|
7814
|
+
for (const [itemIndex, solid] of items.value.entries()) {
|
|
7815
|
+
scope.itemIndex = itemIndex;
|
|
7816
|
+
const ready = before("bounds", itemIndex);
|
|
7817
|
+
if (!ready.ok) return ready;
|
|
7818
|
+
const current = (productBodyTestHooks()?.bounds ?? brepjs.getBounds)(solid);
|
|
7819
|
+
if (!Object.values(current).every(Number.isFinite) || current.xMin > current.xMax || current.yMin > current.yMax || current.zMin > current.zMax) return (0, brepjs.err)(bodyError("productBodyBounds", "BODY_INVALID_BOUNDS", "Expected finite ordered bounds", current, itemIndex));
|
|
7820
|
+
bounds = bounds === void 0 ? { ...current } : {
|
|
7821
|
+
xMin: Math.min(bounds.xMin, current.xMin),
|
|
7822
|
+
xMax: Math.max(bounds.xMax, current.xMax),
|
|
7823
|
+
yMin: Math.min(bounds.yMin, current.yMin),
|
|
7824
|
+
yMax: Math.max(bounds.yMax, current.yMax),
|
|
7825
|
+
zMin: Math.min(bounds.zMin, current.zMin),
|
|
7826
|
+
zMax: Math.max(bounds.zMax, current.zMax)
|
|
7827
|
+
};
|
|
7828
|
+
}
|
|
7829
|
+
if (bounds === void 0) throw new Error("Validated Body produced no bounds");
|
|
7830
|
+
return (0, brepjs.ok)(Object.freeze({ bounds: Object.freeze(bounds) }));
|
|
7831
|
+
});
|
|
7832
|
+
}
|
|
7808
7833
|
//#endregion
|
|
7809
7834
|
//#region src/model/bimModel.ts
|
|
7810
7835
|
function exactWallBodyImmutable() {
|
|
@@ -8360,18 +8385,18 @@ var BimModel = class {
|
|
|
8360
8385
|
}
|
|
8361
8386
|
#cutWallGeometry(wall, openingSpec) {
|
|
8362
8387
|
try {
|
|
8363
|
-
var _usingCtx$
|
|
8388
|
+
var _usingCtx$8 = _usingCtx();
|
|
8364
8389
|
if (wall.geometry.kind === "EXACT") return exactWallBodyImmutable();
|
|
8365
8390
|
const toolResult = openingToSolid(openingSpec, wall.spec.thickness);
|
|
8366
8391
|
if (!toolResult.ok) return (0, brepjs.err)(toolResult.error);
|
|
8367
|
-
const tool = _usingCtx$
|
|
8392
|
+
const tool = _usingCtx$8.u(toolResult.value);
|
|
8368
8393
|
const cutResult = (0, brepjs.cut)(wall.geometry.solid, tool);
|
|
8369
8394
|
if (!cutResult.ok) return (0, brepjs.err)(fromBrepError(cutResult.error, "WALL_CUT_FAILED", "Boolean cut of wall with opening failed"));
|
|
8370
8395
|
return (0, brepjs.ok)(cutResult.value);
|
|
8371
8396
|
} catch (_) {
|
|
8372
|
-
_usingCtx$
|
|
8397
|
+
_usingCtx$8.e = _;
|
|
8373
8398
|
} finally {
|
|
8374
|
-
_usingCtx$
|
|
8399
|
+
_usingCtx$8.d();
|
|
8375
8400
|
}
|
|
8376
8401
|
}
|
|
8377
8402
|
#replaceWallGeometry(wall, newGeometry) {
|
|
@@ -8986,7 +9011,7 @@ function buildSilhouette$1(numberOfRisers, riserHeight, treadLength) {
|
|
|
8986
9011
|
}
|
|
8987
9012
|
function stairFlightToSolid(spec) {
|
|
8988
9013
|
try {
|
|
8989
|
-
var _usingCtx$
|
|
9014
|
+
var _usingCtx$7 = _usingCtx();
|
|
8990
9015
|
if (spec.width <= 0) return (0, brepjs.err)(specError("STAIR_FLIGHT_ZERO_WIDTH", "Stair flight width must be positive"));
|
|
8991
9016
|
if (spec.riserHeight <= 0) return (0, brepjs.err)(specError("STAIR_FLIGHT_ZERO_RISER", "Stair flight riserHeight must be positive"));
|
|
8992
9017
|
if (spec.treadLength <= 0) return (0, brepjs.err)(specError("STAIR_FLIGHT_ZERO_TREAD", "Stair flight treadLength must be positive"));
|
|
@@ -8994,7 +9019,7 @@ function stairFlightToSolid(spec) {
|
|
|
8994
9019
|
const silhouette = buildSilhouette$1(spec.numberOfRisers, spec.riserHeight, spec.treadLength);
|
|
8995
9020
|
const profileResult = (0, brepjs.polygon)(silhouette);
|
|
8996
9021
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "STAIR_FLIGHT_PROFILE_FAILED", "Failed to create stair flight silhouette profile"));
|
|
8997
|
-
const profile = _usingCtx$
|
|
9022
|
+
const profile = _usingCtx$7.u(profileResult.value);
|
|
8998
9023
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
8999
9024
|
0,
|
|
9000
9025
|
spec.width,
|
|
@@ -9011,9 +9036,9 @@ function stairFlightToSolid(spec) {
|
|
|
9011
9036
|
geometrySimplified: false
|
|
9012
9037
|
});
|
|
9013
9038
|
} catch (_) {
|
|
9014
|
-
_usingCtx$
|
|
9039
|
+
_usingCtx$7.e = _;
|
|
9015
9040
|
} finally {
|
|
9016
|
-
_usingCtx$
|
|
9041
|
+
_usingCtx$7.d();
|
|
9017
9042
|
}
|
|
9018
9043
|
}
|
|
9019
9044
|
//#endregion
|
|
@@ -9044,7 +9069,7 @@ function buildSilhouette(length, rise, thickness) {
|
|
|
9044
9069
|
}
|
|
9045
9070
|
function rampFlightToSolid(spec) {
|
|
9046
9071
|
try {
|
|
9047
|
-
var _usingCtx$
|
|
9072
|
+
var _usingCtx$6 = _usingCtx();
|
|
9048
9073
|
if (spec.width <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_WIDTH", "Ramp flight width must be positive"));
|
|
9049
9074
|
if (spec.length <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_LENGTH", "Ramp flight length must be positive"));
|
|
9050
9075
|
if (spec.slope <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_SLOPE", "Ramp flight slope must be positive"));
|
|
@@ -9053,7 +9078,7 @@ function rampFlightToSolid(spec) {
|
|
|
9053
9078
|
const silhouette = buildSilhouette(spec.length, rise, spec.thickness);
|
|
9054
9079
|
const profileResult = (0, brepjs.polygon)(silhouette);
|
|
9055
9080
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "RAMP_FLIGHT_PROFILE_FAILED", "Failed to create ramp flight silhouette profile"));
|
|
9056
|
-
const profile = _usingCtx$
|
|
9081
|
+
const profile = _usingCtx$6.u(profileResult.value);
|
|
9057
9082
|
const solidResult = (0, brepjs.extrude)(profile, [
|
|
9058
9083
|
0,
|
|
9059
9084
|
spec.width,
|
|
@@ -9070,9 +9095,9 @@ function rampFlightToSolid(spec) {
|
|
|
9070
9095
|
geometrySimplified: true
|
|
9071
9096
|
});
|
|
9072
9097
|
} catch (_) {
|
|
9073
|
-
_usingCtx$
|
|
9098
|
+
_usingCtx$6.e = _;
|
|
9074
9099
|
} finally {
|
|
9075
|
-
_usingCtx$
|
|
9100
|
+
_usingCtx$6.d();
|
|
9076
9101
|
}
|
|
9077
9102
|
}
|
|
9078
9103
|
//#endregion
|
|
@@ -9215,22 +9240,22 @@ function placedSolids(el, options = {}) {
|
|
|
9215
9240
|
case "STAIR": {
|
|
9216
9241
|
const out = [];
|
|
9217
9242
|
for (const flight of el.spec.flights) try {
|
|
9218
|
-
var _usingCtx$
|
|
9243
|
+
var _usingCtx$5 = _usingCtx();
|
|
9219
9244
|
const built = stairFlightToSolid(flight);
|
|
9220
9245
|
if (!built.ok) {
|
|
9221
9246
|
disposeAll$1(out);
|
|
9222
9247
|
return (0, brepjs.err)(built.error);
|
|
9223
9248
|
}
|
|
9224
|
-
const placed = placeWithinParent(_usingCtx$
|
|
9249
|
+
const placed = placeWithinParent(_usingCtx$5.u(built.value.solid), flight, parentFrame);
|
|
9225
9250
|
if (!placed.ok) {
|
|
9226
9251
|
disposeAll$1(out);
|
|
9227
9252
|
return placed;
|
|
9228
9253
|
}
|
|
9229
9254
|
out.push(placed.value);
|
|
9230
9255
|
} catch (_) {
|
|
9231
|
-
_usingCtx$
|
|
9256
|
+
_usingCtx$5.e = _;
|
|
9232
9257
|
} finally {
|
|
9233
|
-
_usingCtx$
|
|
9258
|
+
_usingCtx$5.d();
|
|
9234
9259
|
}
|
|
9235
9260
|
return (0, brepjs.ok)(out);
|
|
9236
9261
|
}
|
|
@@ -9740,11 +9765,21 @@ function writeHeader(w, meta) {
|
|
|
9740
9765
|
WorldCoordinateSystem: w.ref(writeAxis2Placement3D(w)),
|
|
9741
9766
|
TrueNorth: null
|
|
9742
9767
|
});
|
|
9768
|
+
return {
|
|
9769
|
+
ownerHistoryId,
|
|
9770
|
+
geomContextId,
|
|
9771
|
+
geomSubContextId: writeGeometricSubContext(w, geomContextId, "Body"),
|
|
9772
|
+
unitAssignmentId,
|
|
9773
|
+
lengthUnitId
|
|
9774
|
+
};
|
|
9775
|
+
}
|
|
9776
|
+
/** Separates display Body geometry from non-subtractive Reference geometry. */
|
|
9777
|
+
function writeGeometricSubContext(w, geomContextId, identifier) {
|
|
9743
9778
|
const geomSubContextId = w.nextId();
|
|
9744
9779
|
w.writeLine({
|
|
9745
9780
|
expressID: geomSubContextId,
|
|
9746
9781
|
type: web_ifc.IFCGEOMETRICREPRESENTATIONSUBCONTEXT,
|
|
9747
|
-
ContextIdentifier: w.mkType(web_ifc.IFCLABEL,
|
|
9782
|
+
ContextIdentifier: w.mkType(web_ifc.IFCLABEL, identifier),
|
|
9748
9783
|
ContextType: w.mkType(web_ifc.IFCLABEL, "Model"),
|
|
9749
9784
|
CoordinateSpaceDimension: null,
|
|
9750
9785
|
Precision: null,
|
|
@@ -9758,13 +9793,7 @@ function writeHeader(w, meta) {
|
|
|
9758
9793
|
},
|
|
9759
9794
|
UserDefinedTargetView: null
|
|
9760
9795
|
});
|
|
9761
|
-
return
|
|
9762
|
-
ownerHistoryId,
|
|
9763
|
-
geomContextId,
|
|
9764
|
-
geomSubContextId,
|
|
9765
|
-
unitAssignmentId,
|
|
9766
|
-
lengthUnitId
|
|
9767
|
-
};
|
|
9796
|
+
return geomSubContextId;
|
|
9768
9797
|
}
|
|
9769
9798
|
/**
|
|
9770
9799
|
* Writes IfcProjectedCRS + IfcMapConversion georeferencing the model context
|
|
@@ -10172,7 +10201,7 @@ function writePreparedTessellationBody(w, items, geomSubContextId) {
|
|
|
10172
10201
|
bodyItemIds
|
|
10173
10202
|
};
|
|
10174
10203
|
}
|
|
10175
|
-
function
|
|
10204
|
+
function writeProductBodyGeometry(w, placement, items, geomSubContextId, parentPlacementId) {
|
|
10176
10205
|
const placement3DId = writeAxis2Placement3D(w, [
|
|
10177
10206
|
toIfcLengthM(placement.origin[0]),
|
|
10178
10207
|
toIfcLengthM(placement.origin[1]),
|
|
@@ -10218,47 +10247,6 @@ function writePreparedTessellationItem(w, prepared) {
|
|
|
10218
10247
|
});
|
|
10219
10248
|
return faceSetId;
|
|
10220
10249
|
}
|
|
10221
|
-
/**
|
|
10222
|
-
* Builds a wall 'Axis' IfcShapeRepresentation: an IfcPolyline from (0,0) to
|
|
10223
|
-
* (lengthM, 0) in the wall's local XY plane, wrapped in an IfcShapeRepresentation
|
|
10224
|
-
* with RepresentationIdentifier='Axis', RepresentationType='Curve2D'. Returns
|
|
10225
|
-
* the IfcShapeRepresentation express ID so callers can add it alongside the Body
|
|
10226
|
-
* representation in an IfcProductDefinitionShape.
|
|
10227
|
-
*
|
|
10228
|
-
* wallLengthMm is the wall length in mm (brepjs native units); it is converted
|
|
10229
|
-
* to metres for IFC.
|
|
10230
|
-
*/
|
|
10231
|
-
function writeWallAxisRepresentation(w, wallLengthMm, geomSubContextId) {
|
|
10232
|
-
const lengthM = toIfcLengthM(wallLengthMm);
|
|
10233
|
-
const startId = w.nextId();
|
|
10234
|
-
w.writeLine({
|
|
10235
|
-
expressID: startId,
|
|
10236
|
-
type: web_ifc.IFCCARTESIANPOINT,
|
|
10237
|
-
Coordinates: [w.mkType(web_ifc.IFCLENGTHMEASURE, 0), w.mkType(web_ifc.IFCLENGTHMEASURE, 0)]
|
|
10238
|
-
});
|
|
10239
|
-
const endId = w.nextId();
|
|
10240
|
-
w.writeLine({
|
|
10241
|
-
expressID: endId,
|
|
10242
|
-
type: web_ifc.IFCCARTESIANPOINT,
|
|
10243
|
-
Coordinates: [w.mkType(web_ifc.IFCLENGTHMEASURE, lengthM), w.mkType(web_ifc.IFCLENGTHMEASURE, 0)]
|
|
10244
|
-
});
|
|
10245
|
-
const polylineId = w.nextId();
|
|
10246
|
-
w.writeLine({
|
|
10247
|
-
expressID: polylineId,
|
|
10248
|
-
type: web_ifc.IFCPOLYLINE,
|
|
10249
|
-
Points: [w.ref(startId), w.ref(endId)]
|
|
10250
|
-
});
|
|
10251
|
-
const shapeRepId = w.nextId();
|
|
10252
|
-
w.writeLine({
|
|
10253
|
-
expressID: shapeRepId,
|
|
10254
|
-
type: web_ifc.IFCSHAPEREPRESENTATION,
|
|
10255
|
-
ContextOfItems: w.ref(geomSubContextId),
|
|
10256
|
-
RepresentationIdentifier: w.mkType(web_ifc.IFCLABEL, "Axis"),
|
|
10257
|
-
RepresentationType: w.mkType(web_ifc.IFCLABEL, "Curve2D"),
|
|
10258
|
-
Items: [w.ref(polylineId)]
|
|
10259
|
-
});
|
|
10260
|
-
return shapeRepId;
|
|
10261
|
-
}
|
|
10262
10250
|
function writeFacetedBrepFallback(w, geomSubContextId, reason) {
|
|
10263
10251
|
const originId = w.nextId();
|
|
10264
10252
|
w.writeLine({
|
|
@@ -10589,81 +10577,6 @@ function writePolyline(w, points) {
|
|
|
10589
10577
|
}
|
|
10590
10578
|
//#endregion
|
|
10591
10579
|
//#region src/ifc-writer/geometryWriter.ts
|
|
10592
|
-
function writeWallGeometry(w, spec, geomSubContextId, parentPlacementId) {
|
|
10593
|
-
const placement3DId = writeAxis2Placement3D(w, spec.origin.map(toIfcLengthM), spec.axisZ, spec.axisX);
|
|
10594
|
-
const localPlacementId = w.nextId();
|
|
10595
|
-
w.writeLine({
|
|
10596
|
-
expressID: localPlacementId,
|
|
10597
|
-
type: web_ifc.IFCLOCALPLACEMENT,
|
|
10598
|
-
PlacementRelTo: parentPlacementId !== null ? w.ref(parentPlacementId) : null,
|
|
10599
|
-
RelativePlacement: w.ref(placement3DId)
|
|
10600
|
-
});
|
|
10601
|
-
const thicknessM = toIfcLengthM(spec.thickness);
|
|
10602
|
-
const heightM = toIfcLengthM(spec.height);
|
|
10603
|
-
const lengthM = toIfcLengthM(spec.length);
|
|
10604
|
-
const profileId = w.nextId();
|
|
10605
|
-
w.writeLine({
|
|
10606
|
-
expressID: profileId,
|
|
10607
|
-
type: web_ifc.IFCRECTANGLEPROFILEDEF,
|
|
10608
|
-
ProfileType: {
|
|
10609
|
-
type: 3,
|
|
10610
|
-
value: "AREA"
|
|
10611
|
-
},
|
|
10612
|
-
ProfileName: null,
|
|
10613
|
-
Position: w.ref(writeAxis2Placement2D$1(w, [thicknessM / 2, heightM / 2])),
|
|
10614
|
-
XDim: w.mkType(web_ifc.IFCPOSITIVELENGTHMEASURE, thicknessM),
|
|
10615
|
-
YDim: w.mkType(web_ifc.IFCPOSITIVELENGTHMEASURE, heightM)
|
|
10616
|
-
});
|
|
10617
|
-
const extrusionPosId = writeAxis2Placement3D(w, [
|
|
10618
|
-
0,
|
|
10619
|
-
0,
|
|
10620
|
-
0
|
|
10621
|
-
], [
|
|
10622
|
-
1,
|
|
10623
|
-
0,
|
|
10624
|
-
0
|
|
10625
|
-
], [
|
|
10626
|
-
0,
|
|
10627
|
-
1,
|
|
10628
|
-
0
|
|
10629
|
-
]);
|
|
10630
|
-
const extrusionDirId = writeDirection(w, [
|
|
10631
|
-
0,
|
|
10632
|
-
0,
|
|
10633
|
-
1
|
|
10634
|
-
]);
|
|
10635
|
-
const extrusionId = w.nextId();
|
|
10636
|
-
w.writeLine({
|
|
10637
|
-
expressID: extrusionId,
|
|
10638
|
-
type: web_ifc.IFCEXTRUDEDAREASOLID,
|
|
10639
|
-
SweptArea: w.ref(profileId),
|
|
10640
|
-
Position: w.ref(extrusionPosId),
|
|
10641
|
-
ExtrudedDirection: w.ref(extrusionDirId),
|
|
10642
|
-
Depth: w.mkType(web_ifc.IFCPOSITIVELENGTHMEASURE, lengthM)
|
|
10643
|
-
});
|
|
10644
|
-
const shapeRepId = w.nextId();
|
|
10645
|
-
w.writeLine({
|
|
10646
|
-
expressID: shapeRepId,
|
|
10647
|
-
type: web_ifc.IFCSHAPEREPRESENTATION,
|
|
10648
|
-
ContextOfItems: w.ref(geomSubContextId),
|
|
10649
|
-
RepresentationIdentifier: w.mkType(web_ifc.IFCLABEL, "Body"),
|
|
10650
|
-
RepresentationType: w.mkType(web_ifc.IFCLABEL, "SweptSolid"),
|
|
10651
|
-
Items: [w.ref(extrusionId)]
|
|
10652
|
-
});
|
|
10653
|
-
const axisRepId = writeWallAxisRepresentation(w, spec.length, geomSubContextId);
|
|
10654
|
-
const productDefinitionShapeId = w.nextId();
|
|
10655
|
-
w.writeLine({
|
|
10656
|
-
expressID: productDefinitionShapeId,
|
|
10657
|
-
type: web_ifc.IFCPRODUCTDEFINITIONSHAPE,
|
|
10658
|
-
Name: null,
|
|
10659
|
-
Description: null,
|
|
10660
|
-
Representations: [w.ref(axisRepId), w.ref(shapeRepId)]
|
|
10661
|
-
});
|
|
10662
|
-
return {
|
|
10663
|
-
localPlacementId,
|
|
10664
|
-
productDefinitionShapeId
|
|
10665
|
-
};
|
|
10666
|
-
}
|
|
10667
10580
|
function writeSlabGeometry(w, spec, geomSubContextId, parentPlacementId) {
|
|
10668
10581
|
const placement3DId = writeAxis2Placement3D(w, spec.origin.map(toIfcLengthM), spec.axisZ, spec.axisX);
|
|
10669
10582
|
const localPlacementId = w.nextId();
|
|
@@ -11714,22 +11627,22 @@ function writeStairAssembly(w, spec, stairKey, assemblyGuid, ownerHistoryId, geo
|
|
|
11714
11627
|
const flightExpressIds = [];
|
|
11715
11628
|
let geometrySimplified = false;
|
|
11716
11629
|
for (const [i, flight] of spec.flights.entries()) try {
|
|
11717
|
-
var _usingCtx$
|
|
11630
|
+
var _usingCtx$4 = _usingCtx();
|
|
11718
11631
|
const built = stairFlightToSolid(flight);
|
|
11719
11632
|
if (!built.ok) return {
|
|
11720
11633
|
ok: false,
|
|
11721
11634
|
error: built.error
|
|
11722
11635
|
};
|
|
11723
|
-
const flightSolid = _usingCtx$
|
|
11636
|
+
const flightSolid = _usingCtx$4.u(built.value.solid);
|
|
11724
11637
|
const flightPlacementId = writeLocalPlacement(w, flight.origin, flight.axisZ, flight.axisX, stairPlacementId);
|
|
11725
11638
|
const tess = writeTessellation(w, flightSolid, geomSubContextId, flightPlacementId);
|
|
11726
11639
|
if (tess.usedFallback) geometrySimplified = true;
|
|
11727
11640
|
const flightExpressId = writeStairFlightEntity(w, deriveIfcGuidSync(`elem:STAIR_FLIGHT:${stairKey}:${i}`), `${stairName} Flight ${i + 1}`, flight, ownerHistoryId, flightPlacementId, tess.productDefinitionShapeId);
|
|
11728
11641
|
flightExpressIds.push(flightExpressId);
|
|
11729
11642
|
} catch (_) {
|
|
11730
|
-
_usingCtx$
|
|
11643
|
+
_usingCtx$4.e = _;
|
|
11731
11644
|
} finally {
|
|
11732
|
-
_usingCtx$
|
|
11645
|
+
_usingCtx$4.d();
|
|
11733
11646
|
}
|
|
11734
11647
|
writeRelAggregates(w, deriveIfcGuidSync(`rel:AGGREGATES:STAIR:${stairKey}`), ownerHistoryId, assemblyExpressId, flightExpressIds);
|
|
11735
11648
|
writeAssemblyType(w, web_ifc.IFCSTAIRTYPE, "Stair Type", deriveIfcGuidSync(`type:STAIR:${stairKey}`), deriveIfcGuidSync(`rel-type:STAIR:${stairKey}`), predefinedType, ownerHistoryId, [assemblyExpressId]);
|
|
@@ -11806,104 +11719,6 @@ function writeRampAssembly(w, spec, rampKey, assemblyGuid, ownerHistoryId, geomS
|
|
|
11806
11719
|
}
|
|
11807
11720
|
//#endregion
|
|
11808
11721
|
//#region src/ifc-writer/railingWriter.ts
|
|
11809
|
-
function writeRailingGeometry(w, spec, solid, geomSubContextId, parentPlacementId) {
|
|
11810
|
-
const placement3DId = writeAxis2Placement3D(w, spec.origin.map(toIfcLengthM), spec.axisZ, spec.axisX);
|
|
11811
|
-
const localPlacementId = w.nextId();
|
|
11812
|
-
w.writeLine({
|
|
11813
|
-
expressID: localPlacementId,
|
|
11814
|
-
type: web_ifc.IFCLOCALPLACEMENT,
|
|
11815
|
-
PlacementRelTo: parentPlacementId !== null ? w.ref(parentPlacementId) : null,
|
|
11816
|
-
RelativePlacement: w.ref(placement3DId)
|
|
11817
|
-
});
|
|
11818
|
-
if (spec.infill === "POSTED") {
|
|
11819
|
-
const tess = writeTessellation(w, solid, geomSubContextId, localPlacementId);
|
|
11820
|
-
return {
|
|
11821
|
-
localPlacementId,
|
|
11822
|
-
productDefinitionShapeId: tess.productDefinitionShapeId,
|
|
11823
|
-
bodyItemId: null,
|
|
11824
|
-
usedFallback: tess.usedFallback
|
|
11825
|
-
};
|
|
11826
|
-
}
|
|
11827
|
-
const thicknessM = toIfcLengthM(spec.thickness);
|
|
11828
|
-
const heightM = toIfcLengthM(spec.height);
|
|
11829
|
-
const lengthM = toIfcLengthM(spec.length);
|
|
11830
|
-
const profileOriginId = w.nextId();
|
|
11831
|
-
w.writeLine({
|
|
11832
|
-
expressID: profileOriginId,
|
|
11833
|
-
type: web_ifc.IFCCARTESIANPOINT,
|
|
11834
|
-
Coordinates: [w.mkType(web_ifc.IFCLENGTHMEASURE, thicknessM / 2), w.mkType(web_ifc.IFCLENGTHMEASURE, heightM / 2)]
|
|
11835
|
-
});
|
|
11836
|
-
const profilePosId = w.nextId();
|
|
11837
|
-
w.writeLine({
|
|
11838
|
-
expressID: profilePosId,
|
|
11839
|
-
type: web_ifc.IFCAXIS2PLACEMENT2D,
|
|
11840
|
-
Location: w.ref(profileOriginId),
|
|
11841
|
-
RefDirection: null
|
|
11842
|
-
});
|
|
11843
|
-
const profileId = w.nextId();
|
|
11844
|
-
w.writeLine({
|
|
11845
|
-
expressID: profileId,
|
|
11846
|
-
type: web_ifc.IFCRECTANGLEPROFILEDEF,
|
|
11847
|
-
ProfileType: {
|
|
11848
|
-
type: 3,
|
|
11849
|
-
value: "AREA"
|
|
11850
|
-
},
|
|
11851
|
-
ProfileName: null,
|
|
11852
|
-
Position: w.ref(profilePosId),
|
|
11853
|
-
XDim: w.mkType(web_ifc.IFCPOSITIVELENGTHMEASURE, thicknessM),
|
|
11854
|
-
YDim: w.mkType(web_ifc.IFCPOSITIVELENGTHMEASURE, heightM)
|
|
11855
|
-
});
|
|
11856
|
-
const extrusionPosId = writeAxis2Placement3D(w, [
|
|
11857
|
-
0,
|
|
11858
|
-
0,
|
|
11859
|
-
0
|
|
11860
|
-
], [
|
|
11861
|
-
1,
|
|
11862
|
-
0,
|
|
11863
|
-
0
|
|
11864
|
-
], [
|
|
11865
|
-
0,
|
|
11866
|
-
1,
|
|
11867
|
-
0
|
|
11868
|
-
]);
|
|
11869
|
-
const extrusionDirId = writeDirection(w, [
|
|
11870
|
-
0,
|
|
11871
|
-
0,
|
|
11872
|
-
1
|
|
11873
|
-
]);
|
|
11874
|
-
const extrusionId = w.nextId();
|
|
11875
|
-
w.writeLine({
|
|
11876
|
-
expressID: extrusionId,
|
|
11877
|
-
type: web_ifc.IFCEXTRUDEDAREASOLID,
|
|
11878
|
-
SweptArea: w.ref(profileId),
|
|
11879
|
-
Position: w.ref(extrusionPosId),
|
|
11880
|
-
ExtrudedDirection: w.ref(extrusionDirId),
|
|
11881
|
-
Depth: w.mkType(web_ifc.IFCPOSITIVELENGTHMEASURE, lengthM)
|
|
11882
|
-
});
|
|
11883
|
-
const shapeRepId = w.nextId();
|
|
11884
|
-
w.writeLine({
|
|
11885
|
-
expressID: shapeRepId,
|
|
11886
|
-
type: web_ifc.IFCSHAPEREPRESENTATION,
|
|
11887
|
-
ContextOfItems: w.ref(geomSubContextId),
|
|
11888
|
-
RepresentationIdentifier: w.mkType(web_ifc.IFCLABEL, "Body"),
|
|
11889
|
-
RepresentationType: w.mkType(web_ifc.IFCLABEL, "SweptSolid"),
|
|
11890
|
-
Items: [w.ref(extrusionId)]
|
|
11891
|
-
});
|
|
11892
|
-
const productDefinitionShapeId = w.nextId();
|
|
11893
|
-
w.writeLine({
|
|
11894
|
-
expressID: productDefinitionShapeId,
|
|
11895
|
-
type: web_ifc.IFCPRODUCTDEFINITIONSHAPE,
|
|
11896
|
-
Name: null,
|
|
11897
|
-
Description: null,
|
|
11898
|
-
Representations: [w.ref(shapeRepId)]
|
|
11899
|
-
});
|
|
11900
|
-
return {
|
|
11901
|
-
localPlacementId,
|
|
11902
|
-
productDefinitionShapeId,
|
|
11903
|
-
bodyItemId: extrusionId,
|
|
11904
|
-
usedFallback: false
|
|
11905
|
-
};
|
|
11906
|
-
}
|
|
11907
11722
|
function writeRailingEntity(w, guid, name, _predefinedType, ownerHistoryId, localPlacementId, productDefinitionShapeId) {
|
|
11908
11723
|
const id = w.nextId();
|
|
11909
11724
|
w.writeLine({
|
|
@@ -13342,7 +13157,7 @@ function writeAxis2Placement2D(w) {
|
|
|
13342
13157
|
});
|
|
13343
13158
|
return id;
|
|
13344
13159
|
}
|
|
13345
|
-
function writeOpeningGeometry(w, guid, openingSpec, wallSpec, wallPlacementId, geomSubContextId, ownerHistoryId) {
|
|
13160
|
+
function writeOpeningGeometry(w, guid, openingSpec, wallSpec, wallPlacementId, geomSubContextId, ownerHistoryId, representationIdentifier) {
|
|
13346
13161
|
const widthM = toIfcLengthM(openingSpec.width);
|
|
13347
13162
|
const heightM = toIfcLengthM(openingSpec.height);
|
|
13348
13163
|
const offsetAlongWallM = toIfcLengthM(openingSpec.offsetAlongWall);
|
|
@@ -13405,7 +13220,7 @@ function writeOpeningGeometry(w, guid, openingSpec, wallSpec, wallPlacementId, g
|
|
|
13405
13220
|
expressID: shapeRepId,
|
|
13406
13221
|
type: web_ifc.IFCSHAPEREPRESENTATION,
|
|
13407
13222
|
ContextOfItems: w.ref(geomSubContextId),
|
|
13408
|
-
RepresentationIdentifier: w.mkType(web_ifc.IFCLABEL,
|
|
13223
|
+
RepresentationIdentifier: w.mkType(web_ifc.IFCLABEL, representationIdentifier),
|
|
13409
13224
|
RepresentationType: w.mkType(web_ifc.IFCLABEL, "SweptSolid"),
|
|
13410
13225
|
Items: [w.ref(extrusionId)]
|
|
13411
13226
|
});
|
|
@@ -15162,18 +14977,22 @@ function checkGeoreferencing(reader) {
|
|
|
15162
14977
|
return [issue("warning", "NO_GEOREFERENCING", "Model contains a facility but no IfcProjectedCRS/IfcGeographicCRS (GRF003) — set ProjectSpec.crs")];
|
|
15163
14978
|
}
|
|
15164
14979
|
//#endregion
|
|
15165
|
-
//#region src/serialize/
|
|
14980
|
+
//#region src/serialize/productBodyPreflight.ts
|
|
15166
14981
|
var testItemPreparer = null;
|
|
15167
|
-
/** Prepares every
|
|
15168
|
-
function
|
|
14982
|
+
/** Prepares every retained Body item without writing IFC lines. Source solids remain borrowed. */
|
|
14983
|
+
function preflightProductBody(input) {
|
|
15169
14984
|
const prepareItem = input.prepareItem ?? testItemPreparer ?? prepareTessellation;
|
|
14985
|
+
const failed = (itemIndex, reason, cause) => (0, brepjs.err)(ifcError("BODY_TESSELLATION_FAILED", `Product Body item ${itemIndex} for ${input.localId} could not be tessellated: ${reason}`, cause, {
|
|
14986
|
+
localId: input.localId,
|
|
14987
|
+
itemIndex
|
|
14988
|
+
}));
|
|
15170
14989
|
const prepareAt = (solid, itemIndex) => {
|
|
15171
|
-
|
|
15172
|
-
|
|
15173
|
-
|
|
15174
|
-
|
|
15175
|
-
|
|
15176
|
-
|
|
14990
|
+
try {
|
|
14991
|
+
const item = prepareItem(solid);
|
|
14992
|
+
return item.ok ? (0, brepjs.ok)(item.value) : failed(itemIndex, item.reason, item.cause);
|
|
14993
|
+
} catch (cause) {
|
|
14994
|
+
return failed(itemIndex, cause instanceof Error ? cause.message : String(cause), cause);
|
|
14995
|
+
}
|
|
15177
14996
|
};
|
|
15178
14997
|
const [firstSolid, ...remainingSolids] = input.solids;
|
|
15179
14998
|
const first = prepareAt(firstSolid, 0);
|
|
@@ -15241,24 +15060,13 @@ function wallVolumeError(cause) {
|
|
|
15241
15060
|
function preflightProductBodies(elements) {
|
|
15242
15061
|
const preflighted = [];
|
|
15243
15062
|
for (const element of elements) {
|
|
15244
|
-
const
|
|
15245
|
-
if (body.kind === "PARAMETRIC") {
|
|
15246
|
-
preflighted.push({
|
|
15247
|
-
kind: "PARAMETRIC",
|
|
15248
|
-
element,
|
|
15249
|
-
solid: body.solid
|
|
15250
|
-
});
|
|
15251
|
-
continue;
|
|
15252
|
-
}
|
|
15253
|
-
const prepared = preflightExactBody({
|
|
15063
|
+
const prepared = preflightProductBody({
|
|
15254
15064
|
localId: element.localId,
|
|
15255
|
-
solids:
|
|
15065
|
+
solids: bodySolids(element.geometry)
|
|
15256
15066
|
});
|
|
15257
15067
|
if (!prepared.ok) return (0, brepjs.err)(prepared.error);
|
|
15258
15068
|
preflighted.push({
|
|
15259
|
-
kind: "EXACT",
|
|
15260
15069
|
element,
|
|
15261
|
-
solids: body.solids,
|
|
15262
15070
|
items: prepared.value
|
|
15263
15071
|
});
|
|
15264
15072
|
}
|
|
@@ -15270,7 +15078,7 @@ async function toIfc(model, meta) {
|
|
|
15270
15078
|
}
|
|
15271
15079
|
async function serializeIfc(model, meta) {
|
|
15272
15080
|
try {
|
|
15273
|
-
var _usingCtx$
|
|
15081
|
+
var _usingCtx$3 = _usingCtx();
|
|
15274
15082
|
const issues = [];
|
|
15275
15083
|
const project = model.getProject();
|
|
15276
15084
|
if (!project) return (0, brepjs.err)(ifcError("NO_PROJECT", "BimModel has no project — call model.init() first"));
|
|
@@ -15281,7 +15089,7 @@ async function serializeIfc(model, meta) {
|
|
|
15281
15089
|
organization: meta.organizationName
|
|
15282
15090
|
});
|
|
15283
15091
|
if (!writerResult.ok) return writerResult;
|
|
15284
|
-
const w = _usingCtx$
|
|
15092
|
+
const w = _usingCtx$3.u(writerResult.value);
|
|
15285
15093
|
w.setModelScope(project.guid);
|
|
15286
15094
|
const elements = model.getAllElements();
|
|
15287
15095
|
const relationships = model.getAllRelationships();
|
|
@@ -15393,13 +15201,14 @@ async function serializeIfc(model, meta) {
|
|
|
15393
15201
|
spec: wall.spec,
|
|
15394
15202
|
solids: bodySolids(wall.geometry)
|
|
15395
15203
|
});
|
|
15396
|
-
const { localPlacementId, productDefinitionShapeId } =
|
|
15204
|
+
const { localPlacementId, productDefinitionShapeId, bodyItemIds } = writeProductBodyGeometry(w, wall.spec, preflighted.items, geomSubContextId, storeyPlacementId);
|
|
15397
15205
|
const wallExpressId = writeWallEntity(w, wall.guid, `Wall ${i + 1}`, ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
15398
15206
|
idMap.set(wall.localId, wallExpressId);
|
|
15399
15207
|
placementMap.set(wall.localId, localPlacementId);
|
|
15400
15208
|
writeWallCommonPset(w, ownerHistoryId, wallExpressId, wall.spec);
|
|
15401
15209
|
writeManufacturerPset(w, ownerHistoryId, wallExpressId, wall.spec);
|
|
15402
15210
|
if (wall.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, wallExpressId, wall.spec.customProperties);
|
|
15211
|
+
for (const itemId of bodyItemIds) applySurfaceStyle(w, model, wall.localId, itemId);
|
|
15403
15212
|
if (!bodyQuantities.ok) issues.push(issue("warning", "WALL_QUANTITY_OMITTED", "Wall quantities omitted because occupied material volume could not be measured", wall.localId, {
|
|
15404
15213
|
guid: wall.guid,
|
|
15405
15214
|
cause: bodyQuantities.error
|
|
@@ -15549,27 +15358,14 @@ async function serializeIfc(model, meta) {
|
|
|
15549
15358
|
const railing = preflighted.element;
|
|
15550
15359
|
const containingId = findContainerOf(railing.localId, relationships);
|
|
15551
15360
|
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
15552
|
-
|
|
15553
|
-
let exactBodyItemIds = [];
|
|
15554
|
-
if (preflighted.kind === "EXACT") {
|
|
15555
|
-
const exact = writeExactBodyGeometry(w, railing.spec, preflighted.items, geomSubContextId, storeyPlacementId);
|
|
15556
|
-
exactBodyItemIds = exact.bodyItemIds;
|
|
15557
|
-
representation = {
|
|
15558
|
-
...exact,
|
|
15559
|
-
bodyItemId: null,
|
|
15560
|
-
usedFallback: false
|
|
15561
|
-
};
|
|
15562
|
-
} else representation = writeRailingGeometry(w, railing.spec, preflighted.solid, geomSubContextId, storeyPlacementId);
|
|
15563
|
-
const { localPlacementId, productDefinitionShapeId, bodyItemId, usedFallback } = representation;
|
|
15564
|
-
if (usedFallback) console.warn(`Railing ${i + 1} tessellation failed; IFC body is a degenerate fallback.`);
|
|
15361
|
+
const { localPlacementId, productDefinitionShapeId, bodyItemIds } = writeProductBodyGeometry(w, railing.spec, preflighted.items, geomSubContextId, storeyPlacementId);
|
|
15565
15362
|
const railingExpressId = writeRailingEntity(w, railing.guid, `Railing ${i + 1}`, railing.spec.predefinedType ?? "NOTDEFINED", ownerHistoryId, localPlacementId, productDefinitionShapeId);
|
|
15566
15363
|
idMap.set(railing.localId, railingExpressId);
|
|
15567
15364
|
placementMap.set(railing.localId, localPlacementId);
|
|
15568
15365
|
writeRailingCommonPset(w, ownerHistoryId, railingExpressId, railing.spec);
|
|
15569
15366
|
writeManufacturerPset(w, ownerHistoryId, railingExpressId, railing.spec);
|
|
15570
15367
|
if (railing.spec.customProperties !== void 0) writeCustomPsets(w, ownerHistoryId, railingExpressId, railing.spec.customProperties);
|
|
15571
|
-
|
|
15572
|
-
else if (bodyItemId !== null) applySurfaceStyle(w, model, railing.localId, bodyItemId);
|
|
15368
|
+
for (const itemId of bodyItemIds) applySurfaceStyle(w, model, railing.localId, itemId);
|
|
15573
15369
|
}
|
|
15574
15370
|
for (const [i, covering] of coverings.entries()) {
|
|
15575
15371
|
const containingId = findContainerOf(covering.localId, relationships);
|
|
@@ -15585,6 +15381,7 @@ async function serializeIfc(model, meta) {
|
|
|
15585
15381
|
}
|
|
15586
15382
|
const openingPlacementMap = /* @__PURE__ */ new Map();
|
|
15587
15383
|
const openingEntityMap = /* @__PURE__ */ new Map();
|
|
15384
|
+
let referenceContextId;
|
|
15588
15385
|
for (const rel of relationships) {
|
|
15589
15386
|
if (rel.kind !== "VOIDS_WALL") continue;
|
|
15590
15387
|
const wallElement = elements.find((el) => el.category === "WALL" && el.localId === rel.wallLocalId);
|
|
@@ -15595,7 +15392,8 @@ async function serializeIfc(model, meta) {
|
|
|
15595
15392
|
const openingElement = elements.find((el) => el.localId === rel.openingLocalId);
|
|
15596
15393
|
if (openingElement === void 0 || openingElement.category !== "OPENING") continue;
|
|
15597
15394
|
if (!isWallOpening(openingElement.spec)) continue;
|
|
15598
|
-
|
|
15395
|
+
referenceContextId ??= writeGeometricSubContext(w, geomContextId, "Reference");
|
|
15396
|
+
const { openingEntityId, openingPlacementId } = writeOpeningGeometry(w, openingElement.guid, openingElement.spec, wallElement.spec, wallPlacementId, referenceContextId, ownerHistoryId, "Reference");
|
|
15599
15397
|
idMap.set(rel.openingLocalId, openingEntityId);
|
|
15600
15398
|
openingPlacementMap.set(rel.openingLocalId, openingPlacementId);
|
|
15601
15399
|
openingEntityMap.set(rel.openingLocalId, openingEntityId);
|
|
@@ -15755,9 +15553,9 @@ async function serializeIfc(model, meta) {
|
|
|
15755
15553
|
issues
|
|
15756
15554
|
}) : saved;
|
|
15757
15555
|
} catch (_) {
|
|
15758
|
-
_usingCtx$
|
|
15556
|
+
_usingCtx$3.e = _;
|
|
15759
15557
|
} finally {
|
|
15760
|
-
_usingCtx$
|
|
15558
|
+
_usingCtx$3.d();
|
|
15761
15559
|
}
|
|
15762
15560
|
}
|
|
15763
15561
|
/**
|
|
@@ -16475,13 +16273,13 @@ function reconstructExtrusion(reader, extrusionId, scale, worldTransform, diagno
|
|
|
16475
16273
|
];
|
|
16476
16274
|
const solidResult = (() => {
|
|
16477
16275
|
try {
|
|
16478
|
-
var _usingCtx$
|
|
16479
|
-
const face = _usingCtx$
|
|
16276
|
+
var _usingCtx$2 = _usingCtx();
|
|
16277
|
+
const face = _usingCtx$2.u(faceResult.value);
|
|
16480
16278
|
return (0, brepjs.extrude)(face, extrudeVec);
|
|
16481
16279
|
} catch (_) {
|
|
16482
|
-
_usingCtx$
|
|
16280
|
+
_usingCtx$2.e = _;
|
|
16483
16281
|
} finally {
|
|
16484
|
-
_usingCtx$
|
|
16282
|
+
_usingCtx$2.d();
|
|
16485
16283
|
}
|
|
16486
16284
|
})();
|
|
16487
16285
|
if (!solidResult.ok) {
|
|
@@ -17203,6 +17001,161 @@ function errMsg$1(e) {
|
|
|
17203
17001
|
return e instanceof Error ? e.message : String(e);
|
|
17204
17002
|
}
|
|
17205
17003
|
//#endregion
|
|
17004
|
+
//#region src/geometryCleanupDiagnostics.ts
|
|
17005
|
+
var diagnosticSchema = object({
|
|
17006
|
+
operation: string(),
|
|
17007
|
+
itemIndex: number().int().nonnegative(),
|
|
17008
|
+
resourceKind: _enum(["SHAPE", "TRANSFORM"]),
|
|
17009
|
+
localId: number().optional(),
|
|
17010
|
+
cause: unknown()
|
|
17011
|
+
});
|
|
17012
|
+
var failedCleanup = object({
|
|
17013
|
+
kind: literal("FAILED"),
|
|
17014
|
+
diagnostics: array(unknown()).nonempty()
|
|
17015
|
+
});
|
|
17016
|
+
var errorMetadata = object({ cleanup: unknown().optional() });
|
|
17017
|
+
var cleanupAttempt = Symbol("geometryCleanupAttempt");
|
|
17018
|
+
var bodyOperation = _enum(["productBodyBounds", "measureProductBodyMaterial"]);
|
|
17019
|
+
function attemptIdentity(source) {
|
|
17020
|
+
const identity = cleanupAttempt in source ? source[cleanupAttempt] : source;
|
|
17021
|
+
return typeof identity === "object" && identity !== null ? identity : source;
|
|
17022
|
+
}
|
|
17023
|
+
function errorChildren(value) {
|
|
17024
|
+
const children = [];
|
|
17025
|
+
if (value instanceof AggregateError) {
|
|
17026
|
+
const errors = value.errors;
|
|
17027
|
+
children.push(...errors);
|
|
17028
|
+
}
|
|
17029
|
+
if ("cause" in value) children.push(value.cause);
|
|
17030
|
+
if ("error" in value && "suppressed" in value) children.push(value.error, value.suppressed);
|
|
17031
|
+
return children;
|
|
17032
|
+
}
|
|
17033
|
+
/** Keep the actual failed-attempt markers; their causes need not be unique. */
|
|
17034
|
+
function nativeCleanupAttempts(error) {
|
|
17035
|
+
const attempts = [];
|
|
17036
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17037
|
+
const visit = (value) => {
|
|
17038
|
+
if (typeof value !== "object" || value === null || seen.has(value)) return;
|
|
17039
|
+
seen.add(value);
|
|
17040
|
+
if (value instanceof brepjs.GeometryCleanupError) attempts.push(value);
|
|
17041
|
+
else errorChildren(value).forEach(visit);
|
|
17042
|
+
};
|
|
17043
|
+
visit(error);
|
|
17044
|
+
return attempts;
|
|
17045
|
+
}
|
|
17046
|
+
/** Read prior owner attempts without retrying releases or merging distinct failures. */
|
|
17047
|
+
function reportedGeometryCleanup(error, operation, context = {}) {
|
|
17048
|
+
const diagnostics = [];
|
|
17049
|
+
const seenErrors = /* @__PURE__ */ new Set();
|
|
17050
|
+
const seenAttempts = /* @__PURE__ */ new Set();
|
|
17051
|
+
const add = (diagnostic, identity) => {
|
|
17052
|
+
if (seenAttempts.has(identity)) return;
|
|
17053
|
+
seenAttempts.add(identity);
|
|
17054
|
+
diagnostics.push(Object.freeze({
|
|
17055
|
+
operation: diagnostic.operation,
|
|
17056
|
+
itemIndex: diagnostic.itemIndex,
|
|
17057
|
+
resourceKind: diagnostic.resourceKind,
|
|
17058
|
+
cause: diagnostic.cause,
|
|
17059
|
+
...diagnostic.localId === void 0 ? {} : { localId: diagnostic.localId },
|
|
17060
|
+
[cleanupAttempt]: identity
|
|
17061
|
+
}));
|
|
17062
|
+
};
|
|
17063
|
+
const visit = (value) => {
|
|
17064
|
+
if (typeof value !== "object" || value === null || seenErrors.has(value)) return;
|
|
17065
|
+
seenErrors.add(value);
|
|
17066
|
+
const metadata = errorMetadata.safeParse("metadata" in value ? value.metadata : void 0);
|
|
17067
|
+
const reports = [metadata.success ? metadata.data.cleanup : void 0, "cleanup" in value ? value.cleanup : void 0];
|
|
17068
|
+
const nativeAttempts = bodyOperation.safeParse("operation" in value ? value.operation : void 0).success ? nativeCleanupAttempts(value) : [];
|
|
17069
|
+
const matched = /* @__PURE__ */ new Set();
|
|
17070
|
+
const seenEntries = /* @__PURE__ */ new Set();
|
|
17071
|
+
for (const report of reports) {
|
|
17072
|
+
const parsed = failedCleanup.safeParse(report);
|
|
17073
|
+
if (!parsed.success) continue;
|
|
17074
|
+
for (const source of parsed.data.diagnostics) {
|
|
17075
|
+
if (typeof source !== "object" || source === null || seenEntries.has(source)) continue;
|
|
17076
|
+
const diagnostic = diagnosticSchema.safeParse(source);
|
|
17077
|
+
if (!diagnostic.success) continue;
|
|
17078
|
+
seenEntries.add(source);
|
|
17079
|
+
let identity = attemptIdentity(source);
|
|
17080
|
+
if (identity === source) {
|
|
17081
|
+
const native = nativeAttempts.find((attempt) => !matched.has(attempt) && attempt.resourceKind === diagnostic.data.resourceKind && attempt.cause === diagnostic.data.cause);
|
|
17082
|
+
if (native !== void 0) identity = native;
|
|
17083
|
+
}
|
|
17084
|
+
if (identity instanceof brepjs.GeometryCleanupError) matched.add(identity);
|
|
17085
|
+
add(diagnostic.data, identity);
|
|
17086
|
+
}
|
|
17087
|
+
}
|
|
17088
|
+
if (value instanceof brepjs.GeometryCleanupError) add({
|
|
17089
|
+
operation,
|
|
17090
|
+
itemIndex: context.itemIndex ?? 0,
|
|
17091
|
+
resourceKind: value.resourceKind,
|
|
17092
|
+
cause: value.cause
|
|
17093
|
+
}, value);
|
|
17094
|
+
else errorChildren(value).forEach(visit);
|
|
17095
|
+
};
|
|
17096
|
+
visit(error);
|
|
17097
|
+
return diagnostics;
|
|
17098
|
+
}
|
|
17099
|
+
//#endregion
|
|
17100
|
+
//#region src/import/cutImportedSolids.ts
|
|
17101
|
+
/** Borrow World-placed inputs; own every disconnected result independently of the cut's cache. */
|
|
17102
|
+
function cutImportedSolids(host, opening) {
|
|
17103
|
+
const context = { operation: "cutImportedSolids" };
|
|
17104
|
+
const temporaries = [];
|
|
17105
|
+
const outputs = [];
|
|
17106
|
+
const build = () => {
|
|
17107
|
+
const cutResult = (0, brepjs.cut)(host, opening);
|
|
17108
|
+
if (!cutResult.ok) return (0, brepjs.err)(fromBrepError(cutResult.error, "VOID_CUT_FAILED", "Opening cut failed"));
|
|
17109
|
+
temporaries.push({
|
|
17110
|
+
resource: cutResult.value,
|
|
17111
|
+
itemIndex: 0
|
|
17112
|
+
});
|
|
17113
|
+
const children = (0, brepjs.getKernel)().iterShapes(cutResult.value.wrapped, "solid").map(brepjs.createSolid);
|
|
17114
|
+
temporaries.push(...children.map((resource, itemIndex) => ({
|
|
17115
|
+
resource,
|
|
17116
|
+
itemIndex
|
|
17117
|
+
})));
|
|
17118
|
+
for (const solid of children) {
|
|
17119
|
+
const copied = (0, brepjs.clone)(solid);
|
|
17120
|
+
if (!copied.ok) return (0, brepjs.err)(fromBrepError(copied.error, "VOID_COPY_FAILED", "Could not retain opening result"));
|
|
17121
|
+
const candidate = copied.value;
|
|
17122
|
+
temporaries.push({
|
|
17123
|
+
resource: candidate,
|
|
17124
|
+
itemIndex: temporaries.length
|
|
17125
|
+
});
|
|
17126
|
+
const validated = (0, brepjs.validSolid)(candidate);
|
|
17127
|
+
if (!validated.ok) return (0, brepjs.err)(importError("VOID_INVALID_SOLID", "Opening result is not valid", validated.error));
|
|
17128
|
+
outputs.push(validated.value);
|
|
17129
|
+
}
|
|
17130
|
+
return (0, brepjs.ok)(outputs);
|
|
17131
|
+
};
|
|
17132
|
+
let result;
|
|
17133
|
+
try {
|
|
17134
|
+
result = build();
|
|
17135
|
+
} catch (cause) {
|
|
17136
|
+
result = (0, brepjs.err)(importError("VOID_CUT_FAILED", "Opening cut failed", cause));
|
|
17137
|
+
}
|
|
17138
|
+
const survivors = new Set(result.ok ? outputs : []);
|
|
17139
|
+
const cleanup = cleanupOwnedResources(temporaries.filter(({ resource }) => !survivors.has(resource)).reverse(), context);
|
|
17140
|
+
const diagnostics = [...result.ok ? [] : reportedGeometryCleanup(result.error, context.operation), ...cleanup.kind === "FAILED" ? cleanup.diagnostics : []];
|
|
17141
|
+
if (result.ok && diagnostics.length === 0) return result;
|
|
17142
|
+
if (result.ok) {
|
|
17143
|
+
const outputCleanup = cleanupOwnedResources(outputs.map((resource, itemIndex) => ({
|
|
17144
|
+
resource,
|
|
17145
|
+
itemIndex
|
|
17146
|
+
})), context);
|
|
17147
|
+
if (outputCleanup.kind === "FAILED") diagnostics.push(...outputCleanup.diagnostics);
|
|
17148
|
+
}
|
|
17149
|
+
const failure = result.ok ? importError("VOID_CLEANUP_FAILED", "Opening result cleanup failed") : result.error;
|
|
17150
|
+
return (0, brepjs.err)({
|
|
17151
|
+
...failure,
|
|
17152
|
+
metadata: {
|
|
17153
|
+
...failure.metadata,
|
|
17154
|
+
cleanup: cleanupReport(diagnostics)
|
|
17155
|
+
}
|
|
17156
|
+
});
|
|
17157
|
+
}
|
|
17158
|
+
//#endregion
|
|
17206
17159
|
//#region src/import/dataRead.ts
|
|
17207
17160
|
/** Narrows an unknown line attribute to the `{ type, value }` wrapper shape. */
|
|
17208
17161
|
function asTyped(v) {
|
|
@@ -17558,7 +17511,7 @@ var ELEMENT_TYPES = [
|
|
|
17558
17511
|
* fatal failures — bad bytes, unsupported schema, WASM open failure — return
|
|
17559
17512
|
* `err`. Inspect {@link ImportedModel.diagnostics} for per-element quality.
|
|
17560
17513
|
*
|
|
17561
|
-
* The web-ifc model handle is
|
|
17514
|
+
* The web-ifc model handle is closed before handing reconstructed owners to the caller.
|
|
17562
17515
|
*/
|
|
17563
17516
|
async function fromIfc(bytes, options = {}) {
|
|
17564
17517
|
const settings = { coordinateToOrigin: options.coordinateToOrigin ?? false };
|
|
@@ -17566,6 +17519,7 @@ async function fromIfc(bytes, options = {}) {
|
|
|
17566
17519
|
if (!readerResult.ok) return (0, brepjs.err)(readerResult.error);
|
|
17567
17520
|
const reader = readerResult.value;
|
|
17568
17521
|
const elements = [];
|
|
17522
|
+
let result;
|
|
17569
17523
|
try {
|
|
17570
17524
|
reader.buildGuidMap();
|
|
17571
17525
|
const diagnostics = [];
|
|
@@ -17592,13 +17546,23 @@ async function fromIfc(bytes, options = {}) {
|
|
|
17592
17546
|
diagnostics: report,
|
|
17593
17547
|
...applicationName !== void 0 ? { applicationName } : {}
|
|
17594
17548
|
};
|
|
17595
|
-
|
|
17549
|
+
result = (0, brepjs.ok)(model);
|
|
17596
17550
|
} catch (e) {
|
|
17597
|
-
|
|
17598
|
-
|
|
17599
|
-
|
|
17551
|
+
result = (0, brepjs.err)(importError("IMPORT_FAILED", "Unexpected failure during IFC import", e));
|
|
17552
|
+
}
|
|
17553
|
+
try {
|
|
17600
17554
|
reader.close();
|
|
17555
|
+
} catch (cause) {
|
|
17556
|
+
result = (0, brepjs.err)(result.ok ? importError("IMPORT_CLOSE_FAILED", "Failed to close IFC reader", cause) : {
|
|
17557
|
+
...result.error,
|
|
17558
|
+
metadata: {
|
|
17559
|
+
...result.error.metadata,
|
|
17560
|
+
readerCloseCause: cause
|
|
17561
|
+
}
|
|
17562
|
+
});
|
|
17601
17563
|
}
|
|
17564
|
+
if (!result.ok) return (0, brepjs.err)(withCleanup(result.error, disposeElements(elements), "fromIfc"));
|
|
17565
|
+
return result;
|
|
17602
17566
|
}
|
|
17603
17567
|
/**
|
|
17604
17568
|
* Reads one product into an {@link ImportedElement}. Returns null only when the
|
|
@@ -17649,8 +17613,8 @@ function readElement(reader, expressId, category, scale, containment, typeEnums,
|
|
|
17649
17613
|
...fills !== void 0 ? { fills } : {}
|
|
17650
17614
|
};
|
|
17651
17615
|
} catch (e) {
|
|
17652
|
-
|
|
17653
|
-
diagnostics.push(issue("error", "ELEMENT_READ_FAILED", `Element ${expressId} reconstruction threw: ${errMsg(e)}`, expressId));
|
|
17616
|
+
const failure = geometry === null ? e : withCleanup(importError("ELEMENT_READ_FAILED", "Element read failed", e), disposeGeometry(geometry), "readElement");
|
|
17617
|
+
diagnostics.push(issue("error", "ELEMENT_READ_FAILED", `Element ${expressId} reconstruction threw: ${errMsg(e)}`, expressId, { cause: failure }));
|
|
17654
17618
|
return null;
|
|
17655
17619
|
}
|
|
17656
17620
|
}
|
|
@@ -17666,36 +17630,79 @@ function findFills(reader, elementExpressId) {
|
|
|
17666
17630
|
}
|
|
17667
17631
|
/**
|
|
17668
17632
|
* Reconstructs a host element's body geometry and, per IFC `IfcRelVoidsElement`
|
|
17669
|
-
* semantics, subtracts
|
|
17633
|
+
* semantics, subtracts each opening's Body representation from a parametric host —
|
|
17670
17634
|
* so a wall with a door hole comes back as the cut solid, matching the source
|
|
17671
17635
|
* model. Falls back to the uncut solid (with a diagnostic) if a cut fails.
|
|
17672
17636
|
*/
|
|
17673
17637
|
function reconstructGeometry(reader, expressId, scale, voidedBy, diagnostics) {
|
|
17674
17638
|
const base = toImportedGeometry(reader, expressId, scale, diagnostics);
|
|
17675
17639
|
if (base.fidelity !== "PARAMETRIC" || base.completeness !== "COMPLETE" || voidedBy.length === 0) return base;
|
|
17676
|
-
|
|
17677
|
-
|
|
17678
|
-
|
|
17679
|
-
|
|
17680
|
-
|
|
17681
|
-
|
|
17682
|
-
|
|
17683
|
-
|
|
17640
|
+
if (base.solids[0] === void 0) return base;
|
|
17641
|
+
const hosts = [...base.solids];
|
|
17642
|
+
try {
|
|
17643
|
+
for (const openingId of voidedBy) try {
|
|
17644
|
+
var _usingCtx$1 = _usingCtx();
|
|
17645
|
+
const opening = readBodyGeometry(reader, openingId, scale, diagnostics);
|
|
17646
|
+
if (opening.kind !== "SOLID") continue;
|
|
17647
|
+
const openingOwner = _usingCtx$1.u(ownOpening(opening.solid, openingId));
|
|
17648
|
+
for (let hostIndex = 0; hostIndex < hosts.length;) {
|
|
17684
17649
|
const host = hosts[hostIndex];
|
|
17685
|
-
if (host === void 0)
|
|
17686
|
-
const cutResult = (
|
|
17650
|
+
if (host === void 0) break;
|
|
17651
|
+
const cutResult = cutImportedSolids(host, openingOwner.solid);
|
|
17687
17652
|
if (!cutResult.ok) {
|
|
17688
|
-
diagnostics.push(issue("warning", "VOID_SUBTRACTION_FAILED", `Opening ${openingId} could not be subtracted from element ${expressId}: ${cutResult.error.message}`, expressId));
|
|
17653
|
+
diagnostics.push(issue("warning", "VOID_SUBTRACTION_FAILED", `Opening ${openingId} could not be subtracted from element ${expressId}: ${cutResult.error.message}`, expressId, { cause: cutResult.error }));
|
|
17654
|
+
hostIndex++;
|
|
17689
17655
|
continue;
|
|
17690
17656
|
}
|
|
17691
|
-
|
|
17692
|
-
|
|
17657
|
+
hosts.splice(hostIndex, 1, ...cutResult.value);
|
|
17658
|
+
const cleanup = cleanupOwnedResources([{
|
|
17659
|
+
resource: host,
|
|
17660
|
+
itemIndex: hostIndex
|
|
17661
|
+
}], { operation: "importOpening" });
|
|
17662
|
+
if (cleanup.kind === "FAILED") diagnostics.push(issue("warning", "VOID_HOST_CLEANUP_FAILED", "Opening result retained, but previous host release failed", expressId, { cleanup }));
|
|
17663
|
+
hostIndex += cutResult.value.length;
|
|
17693
17664
|
}
|
|
17665
|
+
} catch (_) {
|
|
17666
|
+
_usingCtx$1.e = _;
|
|
17694
17667
|
} finally {
|
|
17695
|
-
|
|
17668
|
+
_usingCtx$1.d();
|
|
17696
17669
|
}
|
|
17670
|
+
return completeImportedGeometry("PARAMETRIC", hosts, expressId, diagnostics);
|
|
17671
|
+
} catch (cause) {
|
|
17672
|
+
const failure = importError("GEOMETRY_RECONSTRUCTION_FAILED", "Opening reconstruction failed", cause);
|
|
17673
|
+
const cleanup = cleanupOwnedResources(hosts.map((resource, itemIndex) => ({
|
|
17674
|
+
resource,
|
|
17675
|
+
itemIndex
|
|
17676
|
+
})), { operation: "reconstructGeometry" });
|
|
17677
|
+
throw Object.assign(new Error(failure.message, { cause }), {
|
|
17678
|
+
code: failure.code,
|
|
17679
|
+
metadata: withCleanup(failure, cleanup, "reconstructGeometry").metadata
|
|
17680
|
+
});
|
|
17697
17681
|
}
|
|
17698
|
-
|
|
17682
|
+
}
|
|
17683
|
+
function ownOpening(solid, openingId) {
|
|
17684
|
+
return {
|
|
17685
|
+
solid,
|
|
17686
|
+
[Symbol.dispose]() {
|
|
17687
|
+
const cleanup = cleanupOwnedResources([{
|
|
17688
|
+
resource: solid,
|
|
17689
|
+
itemIndex: 0
|
|
17690
|
+
}], { operation: "importOpeningTool" });
|
|
17691
|
+
if (cleanup.kind === "FAILED") throw new Error(`Opening ${openingId} cleanup failed`, { cause: {
|
|
17692
|
+
...importError("OPENING_CLEANUP_FAILED", "Temporary opening release failed"),
|
|
17693
|
+
metadata: { cleanup }
|
|
17694
|
+
} });
|
|
17695
|
+
}
|
|
17696
|
+
};
|
|
17697
|
+
}
|
|
17698
|
+
function withCleanup(error, cleanup, operation) {
|
|
17699
|
+
return {
|
|
17700
|
+
...error,
|
|
17701
|
+
metadata: {
|
|
17702
|
+
...error.metadata,
|
|
17703
|
+
cleanup: cleanupReport([...reportedGeometryCleanup(error, operation), ...cleanup.kind === "FAILED" ? cleanup.diagnostics : []])
|
|
17704
|
+
}
|
|
17705
|
+
};
|
|
17699
17706
|
}
|
|
17700
17707
|
function toImportedGeometry(reader, expressId, scale, diagnostics) {
|
|
17701
17708
|
const body = readBodyItems(reader, expressId, scale, diagnostics);
|
|
@@ -17743,61 +17750,48 @@ function completeImportedGeometry(fidelity, solids, expressId, diagnostics) {
|
|
|
17743
17750
|
fidelity,
|
|
17744
17751
|
completeness: "COMPLETE",
|
|
17745
17752
|
solids,
|
|
17746
|
-
solid: solids.length === 1 ? solids[0] : null,
|
|
17753
|
+
solid: solids.length === 1 ? solids[0] ?? null : null,
|
|
17747
17754
|
...measureCompleteBody(solids, expressId, diagnostics)
|
|
17748
17755
|
};
|
|
17749
17756
|
}
|
|
17750
17757
|
function measureCompleteBody(solids, expressId, diagnostics) {
|
|
17758
|
+
const unavailable = (cause, message = errMsg(cause)) => {
|
|
17759
|
+
diagnostics.push(issue("warning", "BODY_AGGREGATE_MEASUREMENT_FAILED", `Complete Body aggregate measurement failed: ${message}`, expressId, { cause }));
|
|
17760
|
+
return {
|
|
17761
|
+
bounds: null,
|
|
17762
|
+
volumeMm3: null
|
|
17763
|
+
};
|
|
17764
|
+
};
|
|
17751
17765
|
try {
|
|
17752
|
-
const first = solids
|
|
17766
|
+
const [first, ...rest] = solids;
|
|
17753
17767
|
if (first === void 0) return {
|
|
17754
17768
|
bounds: null,
|
|
17755
17769
|
volumeMm3: null
|
|
17756
17770
|
};
|
|
17757
|
-
const
|
|
17758
|
-
|
|
17759
|
-
|
|
17760
|
-
|
|
17761
|
-
|
|
17762
|
-
let zMin = initial.zMin;
|
|
17763
|
-
let zMax = initial.zMax;
|
|
17764
|
-
let volumeMm3 = 0;
|
|
17765
|
-
for (const solid of solids) {
|
|
17766
|
-
const measured = (0, brepjs.measureVolume)(solid);
|
|
17767
|
-
if (!measured.ok) throw new Error(measured.error.message);
|
|
17768
|
-
volumeMm3 += measured.value;
|
|
17769
|
-
const itemBounds = (0, brepjs.getBounds)(solid);
|
|
17770
|
-
xMin = Math.min(xMin, itemBounds.xMin);
|
|
17771
|
-
xMax = Math.max(xMax, itemBounds.xMax);
|
|
17772
|
-
yMin = Math.min(yMin, itemBounds.yMin);
|
|
17773
|
-
yMax = Math.max(yMax, itemBounds.yMax);
|
|
17774
|
-
zMin = Math.min(zMin, itemBounds.zMin);
|
|
17775
|
-
zMax = Math.max(zMax, itemBounds.zMax);
|
|
17776
|
-
}
|
|
17771
|
+
const items = [first, ...rest];
|
|
17772
|
+
const bounds = productBodyBounds(items);
|
|
17773
|
+
if (!bounds.ok) return unavailable(bounds.error, bounds.error.message);
|
|
17774
|
+
const volume = measureProductBodyMaterial(items);
|
|
17775
|
+
if (!volume.ok) return unavailable(volume.error, volume.error.message);
|
|
17777
17776
|
return {
|
|
17778
|
-
bounds:
|
|
17779
|
-
|
|
17780
|
-
xMax,
|
|
17781
|
-
yMin,
|
|
17782
|
-
yMax,
|
|
17783
|
-
zMin,
|
|
17784
|
-
zMax
|
|
17785
|
-
},
|
|
17786
|
-
volumeMm3
|
|
17777
|
+
bounds: bounds.value.bounds,
|
|
17778
|
+
volumeMm3: volume.value
|
|
17787
17779
|
};
|
|
17788
17780
|
} catch (cause) {
|
|
17789
|
-
|
|
17790
|
-
return {
|
|
17791
|
-
bounds: null,
|
|
17792
|
-
volumeMm3: null
|
|
17793
|
-
};
|
|
17781
|
+
return unavailable(cause);
|
|
17794
17782
|
}
|
|
17795
17783
|
}
|
|
17796
17784
|
function disposeGeometry(geometry) {
|
|
17797
|
-
|
|
17785
|
+
return cleanupOwnedResources(geometry.solids.map((resource, itemIndex) => ({
|
|
17786
|
+
resource,
|
|
17787
|
+
itemIndex
|
|
17788
|
+
})), { operation: "disposeImportedGeometry" });
|
|
17798
17789
|
}
|
|
17799
17790
|
function disposeElements(elements) {
|
|
17800
|
-
|
|
17791
|
+
return cleanupOwnedResources(elements.flatMap(({ geometry }) => geometry.solids).map((resource, itemIndex) => ({
|
|
17792
|
+
resource,
|
|
17793
|
+
itemIndex
|
|
17794
|
+
})), { operation: "disposeImportedElements" });
|
|
17801
17795
|
}
|
|
17802
17796
|
function toImportedPset(pset) {
|
|
17803
17797
|
return {
|