brepjs-bim 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brepjs-bim.cjs +288 -97
- package/dist/brepjs-bim.js +287 -97
- package/dist/familiesAdapter.d.ts +22 -0
- package/dist/index.d.ts +1 -0
- package/dist/model/bimModel.d.ts +9 -4
- package/package.json +5 -2
package/dist/brepjs-bim.cjs
CHANGED
|
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
16
|
}
|
|
17
17
|
return to;
|
|
18
18
|
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
20
20
|
value: mod,
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
@@ -27,7 +27,7 @@ web_ifc = __toESM(web_ifc, 1);
|
|
|
27
27
|
//#region src/identity/ifcGuid.ts
|
|
28
28
|
var IFC_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$";
|
|
29
29
|
function newIfcGuid() {
|
|
30
|
-
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
30
|
+
const bytes = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16));
|
|
31
31
|
bytes[6] = (bytes[6] ?? 0) & 15 | 64;
|
|
32
32
|
bytes[8] = (bytes[8] ?? 0) & 63 | 128;
|
|
33
33
|
return encodeIfcGuid(bytes);
|
|
@@ -69,7 +69,7 @@ function fnv1a(text) {
|
|
|
69
69
|
}
|
|
70
70
|
function digest16(stableKey) {
|
|
71
71
|
const seed = `${NAMESPACE}::${stableKey}`;
|
|
72
|
-
const bytes = new Uint8Array(16);
|
|
72
|
+
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
73
73
|
for (let block = 0; block < 4; block++) {
|
|
74
74
|
const h = fnv1a(`b${block}:${seed}`);
|
|
75
75
|
bytes[block * 4 + 0] = h >>> 24 & 255;
|
|
@@ -206,7 +206,7 @@ function fromBrepError(inner, code, message) {
|
|
|
206
206
|
};
|
|
207
207
|
}
|
|
208
208
|
//#endregion
|
|
209
|
-
//#region \0@oxc-project+runtime@0.
|
|
209
|
+
//#region \0@oxc-project+runtime@0.143.0/helpers/esm/usingCtx.js
|
|
210
210
|
function _usingCtx() {
|
|
211
211
|
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
212
212
|
var n = Error();
|
|
@@ -293,7 +293,8 @@ function wallToSolid(spec) {
|
|
|
293
293
|
]
|
|
294
294
|
]);
|
|
295
295
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "WALL_PROFILE_FAILED", "Failed to create wall profile"));
|
|
296
|
-
const
|
|
296
|
+
const profile = _usingCtx$19.u(profileResult.value);
|
|
297
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
297
298
|
length,
|
|
298
299
|
0,
|
|
299
300
|
0
|
|
@@ -343,7 +344,8 @@ function slabToSolid(spec) {
|
|
|
343
344
|
]
|
|
344
345
|
]);
|
|
345
346
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "SLAB_PROFILE_FAILED", "Failed to create slab profile"));
|
|
346
|
-
const
|
|
347
|
+
const profile = _usingCtx$18.u(profileResult.value);
|
|
348
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
347
349
|
0,
|
|
348
350
|
0,
|
|
349
351
|
thickness
|
|
@@ -437,7 +439,6 @@ function cached(getter) {
|
|
|
437
439
|
Object.defineProperty(this, "value", { value });
|
|
438
440
|
return value;
|
|
439
441
|
}
|
|
440
|
-
throw new Error("cached value already set");
|
|
441
442
|
} };
|
|
442
443
|
}
|
|
443
444
|
function nullish(input) {
|
|
@@ -483,7 +484,10 @@ function assignProp(target, prop, value) {
|
|
|
483
484
|
}
|
|
484
485
|
function mergeDefs(...defs) {
|
|
485
486
|
const mergedDescriptors = {};
|
|
486
|
-
for (const def of defs)
|
|
487
|
+
for (const def of defs) {
|
|
488
|
+
const descriptors = Object.getOwnPropertyDescriptors(def);
|
|
489
|
+
Object.assign(mergedDescriptors, descriptors);
|
|
490
|
+
}
|
|
487
491
|
return Object.defineProperties({}, mergedDescriptors);
|
|
488
492
|
}
|
|
489
493
|
function esc(str) {
|
|
@@ -805,7 +809,7 @@ var _parse = (_Err) => (schema, value, _ctx, _params) => {
|
|
|
805
809
|
}, ctx);
|
|
806
810
|
if (result instanceof Promise) throw new $ZodAsyncError();
|
|
807
811
|
if (result.issues.length) {
|
|
808
|
-
const e = new (_params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
|
|
812
|
+
const e = new ((_params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
|
|
809
813
|
captureStackTrace(e, _params?.callee);
|
|
810
814
|
throw e;
|
|
811
815
|
}
|
|
@@ -822,7 +826,7 @@ var _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
|
|
|
822
826
|
}, ctx);
|
|
823
827
|
if (result instanceof Promise) result = await result;
|
|
824
828
|
if (result.issues.length) {
|
|
825
|
-
const e = new (params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
|
|
829
|
+
const e = new ((params?.Err) ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
|
|
826
830
|
captureStackTrace(e, params?.callee);
|
|
827
831
|
throw e;
|
|
828
832
|
}
|
|
@@ -989,8 +993,10 @@ var $ZodCheckLessThan = /*@__PURE__*/ $constructor("$ZodCheckLessThan", (inst, d
|
|
|
989
993
|
inst._zod.onattach.push((inst) => {
|
|
990
994
|
const bag = inst._zod.bag;
|
|
991
995
|
const curr = (def.inclusive ? bag.maximum : bag.exclusiveMaximum) ?? Number.POSITIVE_INFINITY;
|
|
992
|
-
if (def.value < curr)
|
|
993
|
-
|
|
996
|
+
if (def.value < curr) {
|
|
997
|
+
if (def.inclusive) bag.maximum = def.value;
|
|
998
|
+
else bag.exclusiveMaximum = def.value;
|
|
999
|
+
}
|
|
994
1000
|
});
|
|
995
1001
|
inst._zod.check = (payload) => {
|
|
996
1002
|
if (def.inclusive ? payload.value <= def.value : payload.value < def.value) return;
|
|
@@ -1011,8 +1017,10 @@ var $ZodCheckGreaterThan = /*@__PURE__*/ $constructor("$ZodCheckGreaterThan", (i
|
|
|
1011
1017
|
inst._zod.onattach.push((inst) => {
|
|
1012
1018
|
const bag = inst._zod.bag;
|
|
1013
1019
|
const curr = (def.inclusive ? bag.minimum : bag.exclusiveMinimum) ?? Number.NEGATIVE_INFINITY;
|
|
1014
|
-
if (def.value > curr)
|
|
1015
|
-
|
|
1020
|
+
if (def.value > curr) {
|
|
1021
|
+
if (def.inclusive) bag.minimum = def.value;
|
|
1022
|
+
else bag.exclusiveMinimum = def.value;
|
|
1023
|
+
}
|
|
1016
1024
|
});
|
|
1017
1025
|
inst._zod.check = (payload) => {
|
|
1018
1026
|
if (def.inclusive ? payload.value >= def.value : payload.value > def.value) return;
|
|
@@ -2545,7 +2553,7 @@ var $ZodOptional = /*@__PURE__*/ $constructor("$ZodOptional", (inst, def) => {
|
|
|
2545
2553
|
inst._zod.optin = "optional";
|
|
2546
2554
|
inst._zod.optout = "optional";
|
|
2547
2555
|
defineLazy(inst._zod, "values", () => {
|
|
2548
|
-
return def.innerType._zod.values ? new Set([...def.innerType._zod.values, void 0]) : void 0;
|
|
2556
|
+
return def.innerType._zod.values ? /* @__PURE__ */ new Set([...def.innerType._zod.values, void 0]) : void 0;
|
|
2549
2557
|
});
|
|
2550
2558
|
defineLazy(inst._zod, "pattern", () => {
|
|
2551
2559
|
const pattern = def.innerType._zod.pattern;
|
|
@@ -2579,7 +2587,7 @@ var $ZodNullable = /*@__PURE__*/ $constructor("$ZodNullable", (inst, def) => {
|
|
|
2579
2587
|
return pattern ? new RegExp(`^(${cleanRegex(pattern.source)}|null)$`) : void 0;
|
|
2580
2588
|
});
|
|
2581
2589
|
defineLazy(inst._zod, "values", () => {
|
|
2582
|
-
return def.innerType._zod.values ? new Set([...def.innerType._zod.values, null]) : void 0;
|
|
2590
|
+
return def.innerType._zod.values ? /* @__PURE__ */ new Set([...def.innerType._zod.values, null]) : void 0;
|
|
2583
2591
|
});
|
|
2584
2592
|
inst._zod.parse = (payload, ctx) => {
|
|
2585
2593
|
if (payload.value === null) return payload;
|
|
@@ -3513,8 +3521,10 @@ function finalize$1(ctx, schema) {
|
|
|
3513
3521
|
defs[seen.defId] = seen.def;
|
|
3514
3522
|
}
|
|
3515
3523
|
}
|
|
3516
|
-
if (ctx.external) {} else if (Object.keys(defs).length > 0)
|
|
3517
|
-
|
|
3524
|
+
if (ctx.external) {} else if (Object.keys(defs).length > 0) {
|
|
3525
|
+
if (ctx.target === "draft-2020-12") result.$defs = defs;
|
|
3526
|
+
else result.definitions = defs;
|
|
3527
|
+
}
|
|
3518
3528
|
try {
|
|
3519
3529
|
const finalized = JSON.parse(JSON.stringify(result));
|
|
3520
3530
|
Object.defineProperty(finalized, "~standard", {
|
|
@@ -3627,16 +3637,18 @@ var numberProcessor = (schema, ctx, _json, _params) => {
|
|
|
3627
3637
|
const exMin = typeof exclusiveMinimum === "number" && exclusiveMinimum >= (minimum ?? Number.NEGATIVE_INFINITY);
|
|
3628
3638
|
const exMax = typeof exclusiveMaximum === "number" && exclusiveMaximum <= (maximum ?? Number.POSITIVE_INFINITY);
|
|
3629
3639
|
const legacy = ctx.target === "draft-04" || ctx.target === "openapi-3.0";
|
|
3630
|
-
if (exMin)
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
if (
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
+
if (exMin) {
|
|
3641
|
+
if (legacy) {
|
|
3642
|
+
json.minimum = exclusiveMinimum;
|
|
3643
|
+
json.exclusiveMinimum = true;
|
|
3644
|
+
} else json.exclusiveMinimum = exclusiveMinimum;
|
|
3645
|
+
} else if (typeof minimum === "number") json.minimum = minimum;
|
|
3646
|
+
if (exMax) {
|
|
3647
|
+
if (legacy) {
|
|
3648
|
+
json.maximum = exclusiveMaximum;
|
|
3649
|
+
json.exclusiveMaximum = true;
|
|
3650
|
+
} else json.exclusiveMaximum = exclusiveMaximum;
|
|
3651
|
+
} else if (typeof maximum === "number") json.maximum = maximum;
|
|
3640
3652
|
if (typeof multipleOf === "number") json.multipleOf = multipleOf;
|
|
3641
3653
|
};
|
|
3642
3654
|
var booleanProcessor = (_schema, _ctx, json, _params) => {
|
|
@@ -3657,9 +3669,10 @@ var literalProcessor = (schema, ctx, json, _params) => {
|
|
|
3657
3669
|
const vals = [];
|
|
3658
3670
|
for (const val of def.values) if (val === void 0) {
|
|
3659
3671
|
if (ctx.unrepresentable === "throw") throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
3660
|
-
} else if (typeof val === "bigint")
|
|
3661
|
-
|
|
3662
|
-
|
|
3672
|
+
} else if (typeof val === "bigint") {
|
|
3673
|
+
if (ctx.unrepresentable === "throw") throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
3674
|
+
else vals.push(Number(val));
|
|
3675
|
+
} else vals.push(val);
|
|
3663
3676
|
if (vals.length === 0) {} else if (vals.length === 1) {
|
|
3664
3677
|
const val = vals[0];
|
|
3665
3678
|
json.type = val === null ? "null" : typeof val;
|
|
@@ -5074,7 +5087,7 @@ function extendedProfileToFace(profile) {
|
|
|
5074
5087
|
}
|
|
5075
5088
|
//#endregion
|
|
5076
5089
|
//#region src/specs/profile.ts
|
|
5077
|
-
var EXTENDED_PROFILE_KIND_SET = new Set([
|
|
5090
|
+
var EXTENDED_PROFILE_KIND_SET = /* @__PURE__ */ new Set([
|
|
5078
5091
|
"L_SHAPE",
|
|
5079
5092
|
"T_SHAPE",
|
|
5080
5093
|
"U_SHAPE",
|
|
@@ -5298,7 +5311,7 @@ function profileToPolygon(profile, circleSegments = 32) {
|
|
|
5298
5311
|
case "RECTANGULAR": {
|
|
5299
5312
|
const halfW = profile.width / 2;
|
|
5300
5313
|
const halfH = profile.height / 2;
|
|
5301
|
-
|
|
5314
|
+
const pts = [
|
|
5302
5315
|
[
|
|
5303
5316
|
-halfW,
|
|
5304
5317
|
-halfH,
|
|
@@ -5319,7 +5332,8 @@ function profileToPolygon(profile, circleSegments = 32) {
|
|
|
5319
5332
|
halfH,
|
|
5320
5333
|
0
|
|
5321
5334
|
]
|
|
5322
|
-
]
|
|
5335
|
+
];
|
|
5336
|
+
return (0, brepjs.ok)(pts);
|
|
5323
5337
|
}
|
|
5324
5338
|
case "CIRCULAR": {
|
|
5325
5339
|
if (circleSegments < 3) return (0, brepjs.err)(specError("PROFILE_CIRCLE_SEGMENTS", `profileToPolygon: circleSegments must be >= 3, got ${circleSegments}`));
|
|
@@ -5354,7 +5368,7 @@ function profileToPolygon(profile, circleSegments = 32) {
|
|
|
5354
5368
|
[-halfW, -flangeInnerY]
|
|
5355
5369
|
];
|
|
5356
5370
|
const r = profile.filletRadius ?? 0;
|
|
5357
|
-
const rootCorners = new Set([
|
|
5371
|
+
const rootCorners = /* @__PURE__ */ new Set([
|
|
5358
5372
|
3,
|
|
5359
5373
|
4,
|
|
5360
5374
|
9,
|
|
@@ -5396,13 +5410,15 @@ function beamToSolid(spec) {
|
|
|
5396
5410
|
var _usingCtx3 = _usingCtx();
|
|
5397
5411
|
const faceResult = extendedProfileToFace(spec.profile);
|
|
5398
5412
|
if (!faceResult.ok) return (0, brepjs.err)(faceResult.error);
|
|
5399
|
-
const
|
|
5413
|
+
const face = _usingCtx3.u(faceResult.value);
|
|
5414
|
+
const prismResult = (0, brepjs.extrude)(face, [
|
|
5400
5415
|
0,
|
|
5401
5416
|
0,
|
|
5402
5417
|
spec.length
|
|
5403
5418
|
]);
|
|
5404
5419
|
if (!prismResult.ok) return (0, brepjs.err)(fromBrepError(prismResult.error, "BEAM_EXTRUDE_FAILED", "Failed to extrude beam profile"));
|
|
5405
|
-
const
|
|
5420
|
+
const prism = _usingCtx3.u(prismResult.value);
|
|
5421
|
+
const solid = (0, brepjs.rotate)(prism, 90, { axis: [
|
|
5406
5422
|
0,
|
|
5407
5423
|
1,
|
|
5408
5424
|
0
|
|
@@ -5419,13 +5435,15 @@ function beamToSolid(spec) {
|
|
|
5419
5435
|
}
|
|
5420
5436
|
const profilePtsResult = profileToPolygon(spec.profile);
|
|
5421
5437
|
if (!profilePtsResult.ok) return (0, brepjs.err)(profilePtsResult.error);
|
|
5422
|
-
const
|
|
5438
|
+
const profilePts = profilePtsResult.value.map(([px, py]) => [
|
|
5423
5439
|
0,
|
|
5424
5440
|
px,
|
|
5425
5441
|
py
|
|
5426
|
-
])
|
|
5442
|
+
]);
|
|
5443
|
+
const profileResult = (0, brepjs.polygon)(profilePts);
|
|
5427
5444
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "BEAM_PROFILE_FAILED", "Failed to create beam profile"));
|
|
5428
|
-
const
|
|
5445
|
+
const profile = _usingCtx$16.u(profileResult.value);
|
|
5446
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5429
5447
|
spec.length,
|
|
5430
5448
|
0,
|
|
5431
5449
|
0
|
|
@@ -5453,7 +5471,8 @@ function columnToSolid(spec) {
|
|
|
5453
5471
|
var _usingCtx3 = _usingCtx();
|
|
5454
5472
|
const faceResult = extendedProfileToFace(spec.profile);
|
|
5455
5473
|
if (!faceResult.ok) return (0, brepjs.err)(faceResult.error);
|
|
5456
|
-
const
|
|
5474
|
+
const face = _usingCtx3.u(faceResult.value);
|
|
5475
|
+
const extResult = (0, brepjs.extrude)(face, [
|
|
5457
5476
|
0,
|
|
5458
5477
|
0,
|
|
5459
5478
|
spec.height
|
|
@@ -5475,7 +5494,8 @@ function columnToSolid(spec) {
|
|
|
5475
5494
|
const profilePts = profilePtsResult.value;
|
|
5476
5495
|
const profileResult = (0, brepjs.polygon)(profilePts);
|
|
5477
5496
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "COLUMN_PROFILE_FAILED", "Failed to create column profile"));
|
|
5478
|
-
const
|
|
5497
|
+
const profile = _usingCtx$15.u(profileResult.value);
|
|
5498
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5479
5499
|
0,
|
|
5480
5500
|
0,
|
|
5481
5501
|
spec.height
|
|
@@ -5495,7 +5515,7 @@ function columnToSolid(spec) {
|
|
|
5495
5515
|
}
|
|
5496
5516
|
//#endregion
|
|
5497
5517
|
//#region src/elementFns/openingFns.ts
|
|
5498
|
-
var EPSILON_MM
|
|
5518
|
+
var EPSILON_MM = 1;
|
|
5499
5519
|
function openingToSolid(spec, wallThickness) {
|
|
5500
5520
|
try {
|
|
5501
5521
|
var _usingCtx$14 = _usingCtx();
|
|
@@ -5504,7 +5524,7 @@ function openingToSolid(spec, wallThickness) {
|
|
|
5504
5524
|
if (wallThickness <= 0) return (0, brepjs.err)(specError("OPENING_ZERO_WALL_THICKNESS", "Wall thickness must be positive"));
|
|
5505
5525
|
const x0 = spec.offsetAlongWall;
|
|
5506
5526
|
const yLow = -1;
|
|
5507
|
-
const yHigh = wallThickness + EPSILON_MM
|
|
5527
|
+
const yHigh = wallThickness + EPSILON_MM;
|
|
5508
5528
|
const zLow = spec.offsetFromFloor;
|
|
5509
5529
|
const zHigh = spec.offsetFromFloor + spec.height;
|
|
5510
5530
|
const profileResult = (0, brepjs.polygon)([
|
|
@@ -5530,7 +5550,8 @@ function openingToSolid(spec, wallThickness) {
|
|
|
5530
5550
|
]
|
|
5531
5551
|
]);
|
|
5532
5552
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "OPENING_PROFILE_FAILED", "Failed to create opening profile"));
|
|
5533
|
-
const
|
|
5553
|
+
const profile = _usingCtx$14.u(profileResult.value);
|
|
5554
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5534
5555
|
spec.width,
|
|
5535
5556
|
0,
|
|
5536
5557
|
0
|
|
@@ -5550,7 +5571,6 @@ function openingToSolid(spec, wallThickness) {
|
|
|
5550
5571
|
}
|
|
5551
5572
|
//#endregion
|
|
5552
5573
|
//#region src/elementFns/slabOpeningFns.ts
|
|
5553
|
-
var EPSILON_MM = 1;
|
|
5554
5574
|
function slabOpeningToSolid(spec, slabThickness) {
|
|
5555
5575
|
try {
|
|
5556
5576
|
var _usingCtx$13 = _usingCtx();
|
|
@@ -5585,10 +5605,11 @@ function slabOpeningToSolid(spec, slabThickness) {
|
|
|
5585
5605
|
]
|
|
5586
5606
|
]);
|
|
5587
5607
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "SLAB_OPENING_PROFILE_FAILED", "Failed to create slab opening profile"));
|
|
5588
|
-
const
|
|
5608
|
+
const profile = _usingCtx$13.u(profileResult.value);
|
|
5609
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5589
5610
|
0,
|
|
5590
5611
|
0,
|
|
5591
|
-
slabThickness + 2
|
|
5612
|
+
slabThickness + 2
|
|
5592
5613
|
]);
|
|
5593
5614
|
if (!solidResult.ok) return (0, brepjs.err)(fromBrepError(solidResult.error, "SLAB_OPENING_EXTRUDE_FAILED", "Failed to extrude slab opening profile"));
|
|
5594
5615
|
const solid = solidResult.value;
|
|
@@ -5635,7 +5656,8 @@ function spaceToSolid(spec) {
|
|
|
5635
5656
|
]
|
|
5636
5657
|
]);
|
|
5637
5658
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "SPACE_PROFILE_FAILED", "Failed to create space footprint"));
|
|
5638
|
-
const
|
|
5659
|
+
const profile = _usingCtx$12.u(profileResult.value);
|
|
5660
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5639
5661
|
0,
|
|
5640
5662
|
0,
|
|
5641
5663
|
height
|
|
@@ -5690,7 +5712,8 @@ function flatRoof(spec) {
|
|
|
5690
5712
|
]
|
|
5691
5713
|
]);
|
|
5692
5714
|
if (!face.ok) return (0, brepjs.err)(fromBrepError(face.error, "ROOF_PROFILE_FAILED", "Failed to create roof profile"));
|
|
5693
|
-
const
|
|
5715
|
+
const profile = _usingCtx$11.u(face.value);
|
|
5716
|
+
const solid = (0, brepjs.extrude)(profile, [
|
|
5694
5717
|
0,
|
|
5695
5718
|
0,
|
|
5696
5719
|
thickness
|
|
@@ -5731,7 +5754,8 @@ function shedRoof(spec, pitch) {
|
|
|
5731
5754
|
]
|
|
5732
5755
|
]);
|
|
5733
5756
|
if (!face.ok) return (0, brepjs.err)(fromBrepError(face.error, "ROOF_PROFILE_FAILED", "Failed to create shed profile"));
|
|
5734
|
-
const
|
|
5757
|
+
const profile = _usingCtx3.u(face.value);
|
|
5758
|
+
const solid = (0, brepjs.extrude)(profile, [
|
|
5735
5759
|
length,
|
|
5736
5760
|
0,
|
|
5737
5761
|
0
|
|
@@ -5777,7 +5801,8 @@ function gableRoof(spec, pitch) {
|
|
|
5777
5801
|
]
|
|
5778
5802
|
]);
|
|
5779
5803
|
if (!face.ok) return (0, brepjs.err)(fromBrepError(face.error, "ROOF_PROFILE_FAILED", "Failed to create gable profile"));
|
|
5780
|
-
const
|
|
5804
|
+
const profile = _usingCtx4.u(face.value);
|
|
5805
|
+
const solid = (0, brepjs.extrude)(profile, [
|
|
5781
5806
|
length,
|
|
5782
5807
|
0,
|
|
5783
5808
|
0
|
|
@@ -5918,7 +5943,8 @@ function boxSolid(sizeX, sizeY, sizeZ) {
|
|
|
5918
5943
|
]
|
|
5919
5944
|
]);
|
|
5920
5945
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "CURTAIN_WALL_PROFILE_FAILED", "Failed to create component profile"));
|
|
5921
|
-
const
|
|
5946
|
+
const profile = _usingCtx$10.u(profileResult.value);
|
|
5947
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
5922
5948
|
0,
|
|
5923
5949
|
0,
|
|
5924
5950
|
sizeZ
|
|
@@ -6060,7 +6086,8 @@ function footingToSolid(spec) {
|
|
|
6060
6086
|
]
|
|
6061
6087
|
]);
|
|
6062
6088
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "FOOTING_PROFILE_FAILED", "Failed to create footing profile"));
|
|
6063
|
-
const
|
|
6089
|
+
const profile = _usingCtx$9.u(profileResult.value);
|
|
6090
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6064
6091
|
0,
|
|
6065
6092
|
0,
|
|
6066
6093
|
thickness
|
|
@@ -6086,7 +6113,8 @@ function pileToSolid(spec) {
|
|
|
6086
6113
|
var _usingCtx4 = _usingCtx();
|
|
6087
6114
|
const faceResult = extendedProfileToFace(spec.profile);
|
|
6088
6115
|
if (!faceResult.ok) return (0, brepjs.err)(faceResult.error);
|
|
6089
|
-
const
|
|
6116
|
+
const face = _usingCtx4.u(faceResult.value);
|
|
6117
|
+
const extResult = (0, brepjs.extrude)(face, [
|
|
6090
6118
|
0,
|
|
6091
6119
|
0,
|
|
6092
6120
|
spec.length
|
|
@@ -6108,7 +6136,8 @@ function pileToSolid(spec) {
|
|
|
6108
6136
|
const profilePts = profilePtsResult.value;
|
|
6109
6137
|
const profileResult = (0, brepjs.polygon)(profilePts);
|
|
6110
6138
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "PILE_PROFILE_FAILED", "Failed to create pile profile"));
|
|
6111
|
-
const
|
|
6139
|
+
const profile = _usingCtx3.u(profileResult.value);
|
|
6140
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6112
6141
|
0,
|
|
6113
6142
|
0,
|
|
6114
6143
|
spec.length
|
|
@@ -6155,7 +6184,8 @@ function panelRailing(spec) {
|
|
|
6155
6184
|
]
|
|
6156
6185
|
]);
|
|
6157
6186
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "RAILING_PROFILE_FAILED", "Failed to create railing profile"));
|
|
6158
|
-
const
|
|
6187
|
+
const profile = _usingCtx$8.u(profileResult.value);
|
|
6188
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6159
6189
|
length,
|
|
6160
6190
|
0,
|
|
6161
6191
|
0
|
|
@@ -6261,7 +6291,8 @@ function coveringToSolid(spec) {
|
|
|
6261
6291
|
]
|
|
6262
6292
|
]);
|
|
6263
6293
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "COVERING_PROFILE_FAILED", "Failed to create covering profile"));
|
|
6264
|
-
const
|
|
6294
|
+
const profile = _usingCtx$7.u(profileResult.value);
|
|
6295
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
6265
6296
|
0,
|
|
6266
6297
|
0,
|
|
6267
6298
|
thickness
|
|
@@ -6288,6 +6319,7 @@ var BimModel = class {
|
|
|
6288
6319
|
#counter = makeLocalIdCounter();
|
|
6289
6320
|
#projectId = null;
|
|
6290
6321
|
#modelScope = "";
|
|
6322
|
+
#usedStableKeys = /* @__PURE__ */ new Set();
|
|
6291
6323
|
init(spec) {
|
|
6292
6324
|
if (this.#projectId !== null) return (0, brepjs.err)(specError("DUPLICATE_PROJECT", "BimModel.init() called twice — only one project per model"));
|
|
6293
6325
|
this.#modelScope = spec.projectId ?? `${spec.name}::${spec.description ?? ""}`;
|
|
@@ -6305,24 +6337,35 @@ var BimModel = class {
|
|
|
6305
6337
|
addSite(spec) {
|
|
6306
6338
|
return this.#makeElement("SITE", spec, null);
|
|
6307
6339
|
}
|
|
6308
|
-
addBuilding(spec) {
|
|
6309
|
-
return this.#makeElement("BUILDING", spec, null);
|
|
6340
|
+
addBuilding(spec, options) {
|
|
6341
|
+
return this.#makeElement("BUILDING", spec, null, options?.stableKey);
|
|
6310
6342
|
}
|
|
6311
|
-
addStorey(spec) {
|
|
6312
|
-
return this.#makeElement("STOREY", spec, null);
|
|
6343
|
+
addStorey(spec, options) {
|
|
6344
|
+
return this.#makeElement("STOREY", spec, null, options?.stableKey);
|
|
6313
6345
|
}
|
|
6314
|
-
|
|
6346
|
+
/** Reject a duplicate stableKey BEFORE any geometry is built, so the
|
|
6347
|
+
* Result-returning adders never allocate a solid they cannot store. */
|
|
6348
|
+
#checkStableKey(options) {
|
|
6349
|
+
const key = options?.stableKey;
|
|
6350
|
+
if (key !== void 0 && this.#usedStableKeys.has(key)) return (0, brepjs.err)(specError("DUPLICATE_STABLE_KEY", `BimModel: duplicate stableKey '${key}'`));
|
|
6351
|
+
return (0, brepjs.ok)(void 0);
|
|
6352
|
+
}
|
|
6353
|
+
addWall(spec, options) {
|
|
6354
|
+
const keyCheck = this.#checkStableKey(options);
|
|
6355
|
+
if (!keyCheck.ok) return keyCheck;
|
|
6315
6356
|
const geomResult = wallToSolid(spec);
|
|
6316
6357
|
if (!geomResult.ok) return (0, brepjs.err)(geomResult.error);
|
|
6317
|
-
const id = this.#makeElement("WALL", spec, geomResult.value);
|
|
6358
|
+
const id = this.#makeElement("WALL", spec, geomResult.value, options?.stableKey);
|
|
6318
6359
|
this.#associateMaterial(id, spec);
|
|
6319
6360
|
this.#associateClassification(id, spec);
|
|
6320
6361
|
return (0, brepjs.ok)(id);
|
|
6321
6362
|
}
|
|
6322
|
-
addSlab(spec) {
|
|
6363
|
+
addSlab(spec, options) {
|
|
6364
|
+
const keyCheck = this.#checkStableKey(options);
|
|
6365
|
+
if (!keyCheck.ok) return keyCheck;
|
|
6323
6366
|
const geomResult = slabToSolid(spec);
|
|
6324
6367
|
if (!geomResult.ok) return (0, brepjs.err)(geomResult.error);
|
|
6325
|
-
const id = this.#makeElement("SLAB", spec, geomResult.value);
|
|
6368
|
+
const id = this.#makeElement("SLAB", spec, geomResult.value, options?.stableKey);
|
|
6326
6369
|
this.#associateMaterial(id, spec);
|
|
6327
6370
|
this.#associateClassification(id, spec);
|
|
6328
6371
|
return (0, brepjs.ok)(id);
|
|
@@ -6941,10 +6984,14 @@ var BimModel = class {
|
|
|
6941
6984
|
getAllRelationships() {
|
|
6942
6985
|
return [...this.#relationships.values()];
|
|
6943
6986
|
}
|
|
6944
|
-
#makeElement(category, spec, geometry) {
|
|
6987
|
+
#makeElement(category, spec, geometry, stableKey) {
|
|
6945
6988
|
const localId = this.#counter.next();
|
|
6989
|
+
if (stableKey !== void 0) {
|
|
6990
|
+
if (this.#usedStableKeys.has(stableKey)) throw new Error(`BimModel: duplicate stableKey '${stableKey}'`);
|
|
6991
|
+
this.#usedStableKeys.add(stableKey);
|
|
6992
|
+
}
|
|
6946
6993
|
const el = {
|
|
6947
|
-
guid: deriveIfcGuidSync(makeElementKey(this.#modelScope, category, localId)),
|
|
6994
|
+
guid: deriveIfcGuidSync(stableKey !== void 0 ? `elem:${this.#modelScope}:${stableKey}` : makeElementKey(this.#modelScope, category, localId)),
|
|
6948
6995
|
localId,
|
|
6949
6996
|
category,
|
|
6950
6997
|
spec,
|
|
@@ -7191,9 +7238,11 @@ function stairFlightToSolid(spec) {
|
|
|
7191
7238
|
if (spec.riserHeight <= 0) return (0, brepjs.err)(specError("STAIR_FLIGHT_ZERO_RISER", "Stair flight riserHeight must be positive"));
|
|
7192
7239
|
if (spec.treadLength <= 0) return (0, brepjs.err)(specError("STAIR_FLIGHT_ZERO_TREAD", "Stair flight treadLength must be positive"));
|
|
7193
7240
|
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"));
|
|
7194
|
-
const
|
|
7241
|
+
const silhouette = buildSilhouette$1(spec.numberOfRisers, spec.riserHeight, spec.treadLength);
|
|
7242
|
+
const profileResult = (0, brepjs.polygon)(silhouette);
|
|
7195
7243
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "STAIR_FLIGHT_PROFILE_FAILED", "Failed to create stair flight silhouette profile"));
|
|
7196
|
-
const
|
|
7244
|
+
const profile = _usingCtx$5.u(profileResult.value);
|
|
7245
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
7197
7246
|
0,
|
|
7198
7247
|
spec.width,
|
|
7199
7248
|
0
|
|
@@ -7349,7 +7398,7 @@ function isIfcSchema(value) {
|
|
|
7349
7398
|
* linear-infrastructure entities). Entities absent from every per-schema set are
|
|
7350
7399
|
* treated as schema-agnostic and supported everywhere (open-world default).
|
|
7351
7400
|
*/
|
|
7352
|
-
var IFC4X3_ONLY_ENTITIES = new Set([
|
|
7401
|
+
var IFC4X3_ONLY_ENTITIES = /* @__PURE__ */ new Set([
|
|
7353
7402
|
"IfcAlignment",
|
|
7354
7403
|
"IfcAlignmentHorizontal",
|
|
7355
7404
|
"IfcAlignmentVertical",
|
|
@@ -7429,7 +7478,8 @@ var IfcWriter = class IfcWriter {
|
|
|
7429
7478
|
try {
|
|
7430
7479
|
const api = new web_ifc.IfcAPI();
|
|
7431
7480
|
await initIfcApi(api);
|
|
7432
|
-
|
|
7481
|
+
const modelId = api.CreateModel({ schema: fileSchemaString(ifcSchema) });
|
|
7482
|
+
return (0, brepjs.ok)(new IfcWriter(api, modelId, mvdViewDefinition, header));
|
|
7433
7483
|
} catch (e) {
|
|
7434
7484
|
return (0, brepjs.err)(ifcError("IFC_INIT_FAILED", "Failed to initialize web-ifc", e));
|
|
7435
7485
|
}
|
|
@@ -7483,8 +7533,10 @@ var IfcWriter = class IfcWriter {
|
|
|
7483
7533
|
let head = new TextDecoder().decode(bytes.subarray(0, HEADER_SCAN));
|
|
7484
7534
|
if (FILE_NAME_RE.test(head)) head = head.replace(FILE_NAME_RE, (_m, prefix, systems) => `${prefix}(${stepString(this.#author)}),(${stepString(this.#organization)}),${systems},${stepString("")})`);
|
|
7485
7535
|
else console.warn("IfcWriter: FILE_NAME null-field pattern not found; author/organization/authorization left unpatched");
|
|
7486
|
-
if (this.#mvdViewDefinition.length > 0)
|
|
7487
|
-
|
|
7536
|
+
if (this.#mvdViewDefinition.length > 0) {
|
|
7537
|
+
if (VIEW_DEFINITION_RE.test(head)) head = head.replace(VIEW_DEFINITION_RE, `ViewDefinition [${this.#mvdViewDefinition}]`);
|
|
7538
|
+
else console.warn(`IfcWriter: FILE_DESCRIPTION ViewDefinition not found; MVD "${this.#mvdViewDefinition}" not declared`);
|
|
7539
|
+
}
|
|
7488
7540
|
const patchedHeadBytes = new TextEncoder().encode(head);
|
|
7489
7541
|
const tail = bytes.subarray(HEADER_SCAN);
|
|
7490
7542
|
const out = new Uint8Array(patchedHeadBytes.byteLength + tail.byteLength);
|
|
@@ -9403,9 +9455,11 @@ function rampFlightToSolid(spec) {
|
|
|
9403
9455
|
if (spec.slope <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_SLOPE", "Ramp flight slope must be positive"));
|
|
9404
9456
|
if (spec.thickness <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_THICKNESS", "Ramp flight thickness must be positive"));
|
|
9405
9457
|
const rise = spec.length * spec.slope;
|
|
9406
|
-
const
|
|
9458
|
+
const silhouette = buildSilhouette(spec.length, rise, spec.thickness);
|
|
9459
|
+
const profileResult = (0, brepjs.polygon)(silhouette);
|
|
9407
9460
|
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "RAMP_FLIGHT_PROFILE_FAILED", "Failed to create ramp flight silhouette profile"));
|
|
9408
|
-
const
|
|
9461
|
+
const profile = _usingCtx$3.u(profileResult.value);
|
|
9462
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
9409
9463
|
0,
|
|
9410
9464
|
spec.width,
|
|
9411
9465
|
0
|
|
@@ -11731,7 +11785,7 @@ function isSlabOpening(spec) {
|
|
|
11731
11785
|
* instead, and OPENINGs are tied to their host through VOIDS rels — neither
|
|
11732
11786
|
* participates in containment, so excluding them here avoids false orphans.
|
|
11733
11787
|
*/
|
|
11734
|
-
var CONTAINABLE_CATEGORIES = new Set([
|
|
11788
|
+
var CONTAINABLE_CATEGORIES = /* @__PURE__ */ new Set([
|
|
11735
11789
|
"WALL",
|
|
11736
11790
|
"SLAB",
|
|
11737
11791
|
"BEAM",
|
|
@@ -12528,14 +12582,15 @@ async function toIfcValidated(model, meta) {
|
|
|
12528
12582
|
const geometry = collectGeometryIssues(model);
|
|
12529
12583
|
const schema = await checkSchema(bytes);
|
|
12530
12584
|
const roundTrip = await checkRoundTrip(bytes);
|
|
12585
|
+
const report = { issues: [
|
|
12586
|
+
...integrity.issues,
|
|
12587
|
+
...geometry.issues,
|
|
12588
|
+
...schema.issues,
|
|
12589
|
+
...roundTrip.issues
|
|
12590
|
+
] };
|
|
12531
12591
|
return (0, brepjs.ok)({
|
|
12532
12592
|
bytes,
|
|
12533
|
-
report
|
|
12534
|
-
...integrity.issues,
|
|
12535
|
-
...geometry.issues,
|
|
12536
|
-
...schema.issues,
|
|
12537
|
-
...roundTrip.issues
|
|
12538
|
-
] }
|
|
12593
|
+
report
|
|
12539
12594
|
});
|
|
12540
12595
|
}
|
|
12541
12596
|
/**
|
|
@@ -12756,7 +12811,7 @@ var SpfReader = class SpfReader {
|
|
|
12756
12811
|
};
|
|
12757
12812
|
//#endregion
|
|
12758
12813
|
//#region src/import/spatialTree.ts
|
|
12759
|
-
var CATEGORY_BY_TYPE = new Map([
|
|
12814
|
+
var CATEGORY_BY_TYPE = /* @__PURE__ */ new Map([
|
|
12760
12815
|
[web_ifc.IFCPROJECT, "PROJECT"],
|
|
12761
12816
|
[web_ifc.IFCSITE, "SITE"],
|
|
12762
12817
|
[web_ifc.IFCBUILDING, "BUILDING"],
|
|
@@ -12938,7 +12993,8 @@ function reconstructExtrusion(reader, extrusionId, scale, worldTransform, diagno
|
|
|
12938
12993
|
const solidResult = (() => {
|
|
12939
12994
|
try {
|
|
12940
12995
|
var _usingCtx$1 = _usingCtx();
|
|
12941
|
-
|
|
12996
|
+
const face = _usingCtx$1.u(faceResult.value);
|
|
12997
|
+
return (0, brepjs.extrude)(face, extrudeVec);
|
|
12942
12998
|
} catch (_) {
|
|
12943
12999
|
_usingCtx$1.e = _;
|
|
12944
13000
|
} finally {
|
|
@@ -12991,10 +13047,12 @@ function reconstructRevolution(reader, revolutionId, scale, worldTransform, diag
|
|
|
12991
13047
|
const revolved = (() => {
|
|
12992
13048
|
try {
|
|
12993
13049
|
var _usingCtx3 = _usingCtx();
|
|
12994
|
-
|
|
13050
|
+
const face = _usingCtx3.u(faceResult.value);
|
|
13051
|
+
const angleDeg = angleRaw * readPlaneAngleScale(reader) * (180 / Math.PI);
|
|
13052
|
+
return (0, brepjs.revolve)(face, {
|
|
12995
13053
|
at: center,
|
|
12996
13054
|
axis: direction,
|
|
12997
|
-
angle:
|
|
13055
|
+
angle: angleDeg
|
|
12998
13056
|
});
|
|
12999
13057
|
} catch (_) {
|
|
13000
13058
|
_usingCtx3.e = _;
|
|
@@ -13109,7 +13167,7 @@ function packBinaryStl(vertices, indices, scaleToMm) {
|
|
|
13109
13167
|
}
|
|
13110
13168
|
return new Uint8Array(buffer);
|
|
13111
13169
|
}
|
|
13112
|
-
var PARAMETRIC_PROFILE_BUILDERS = new Map([
|
|
13170
|
+
var PARAMETRIC_PROFILE_BUILDERS = /* @__PURE__ */ new Map([
|
|
13113
13171
|
[web_ifc.IFCRECTANGLEPROFILEDEF, (f) => ({
|
|
13114
13172
|
kind: "RECTANGULAR",
|
|
13115
13173
|
width: f("XDim"),
|
|
@@ -13877,14 +13935,15 @@ async function fromIfc(bytes, options = {}) {
|
|
|
13877
13935
|
}
|
|
13878
13936
|
const report = appendIssues(emptyReport(), diagnostics);
|
|
13879
13937
|
const applicationName = readApplicationName(reader);
|
|
13880
|
-
|
|
13938
|
+
const model = {
|
|
13881
13939
|
schema: reader.schema,
|
|
13882
13940
|
spatialTree: spatialRoot === null ? null : mapSpatialNode(spatialRoot),
|
|
13883
13941
|
elements,
|
|
13884
13942
|
byExpressId,
|
|
13885
13943
|
diagnostics: report,
|
|
13886
13944
|
...applicationName !== void 0 ? { applicationName } : {}
|
|
13887
|
-
}
|
|
13945
|
+
};
|
|
13946
|
+
return (0, brepjs.ok)(model);
|
|
13888
13947
|
} catch (e) {
|
|
13889
13948
|
return (0, brepjs.err)(importError("IMPORT_FAILED", "Unexpected failure during IFC import", e));
|
|
13890
13949
|
} finally {
|
|
@@ -14911,7 +14970,7 @@ function parseSlabOpeningInput(input) {
|
|
|
14911
14970
|
* containers (PROJECT/SITE/BUILDING/STOREY), abstract groupings, and the SPACE
|
|
14912
14971
|
* category (which maps to the Space sheet, not Component) are excluded.
|
|
14913
14972
|
*/
|
|
14914
|
-
var COMPONENT_CATEGORIES = new Set([
|
|
14973
|
+
var COMPONENT_CATEGORIES = /* @__PURE__ */ new Set([
|
|
14915
14974
|
"WALL",
|
|
14916
14975
|
"SLAB",
|
|
14917
14976
|
"BEAM",
|
|
@@ -15536,9 +15595,10 @@ function parseIdsXml(xml) {
|
|
|
15536
15595
|
const title = info ? firstChild(info, "title")?.text ?? "" : "";
|
|
15537
15596
|
const specsContainer = firstChild(root, "specifications");
|
|
15538
15597
|
if (specsContainer === void 0) return (0, brepjs.err)(idsError("IDS_INVALID_SCHEMA", "IDS document has no <specifications> element"));
|
|
15598
|
+
const specifications = childrenNamed(specsContainer, "specification").map(parseSpecification);
|
|
15539
15599
|
return (0, brepjs.ok)({
|
|
15540
15600
|
title,
|
|
15541
|
-
specifications
|
|
15601
|
+
specifications
|
|
15542
15602
|
});
|
|
15543
15603
|
}
|
|
15544
15604
|
function parseSpecification(el) {
|
|
@@ -15895,10 +15955,7 @@ function restrictionsOf(facet) {
|
|
|
15895
15955
|
push(facet.system);
|
|
15896
15956
|
push(facet.value);
|
|
15897
15957
|
break;
|
|
15898
|
-
case "Material":
|
|
15899
|
-
push(facet.value);
|
|
15900
|
-
break;
|
|
15901
|
-
case "PartOf": break;
|
|
15958
|
+
case "Material": push(facet.value);
|
|
15902
15959
|
}
|
|
15903
15960
|
return out;
|
|
15904
15961
|
}
|
|
@@ -16298,7 +16355,8 @@ function parseBcfFiles(files) {
|
|
|
16298
16355
|
topics
|
|
16299
16356
|
});
|
|
16300
16357
|
} catch (cause) {
|
|
16301
|
-
|
|
16358
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
16359
|
+
return (0, brepjs.err)(bcfError("BCF_PARSE_FAILED", `Failed to parse BCF container: ${message}`, cause));
|
|
16302
16360
|
}
|
|
16303
16361
|
}
|
|
16304
16362
|
function parseVersion(xml) {
|
|
@@ -16413,6 +16471,138 @@ function assignNum(target, key, value) {
|
|
|
16413
16471
|
if (value !== void 0) target[key] = Number(value);
|
|
16414
16472
|
}
|
|
16415
16473
|
//#endregion
|
|
16474
|
+
//#region src/familiesAdapter.ts
|
|
16475
|
+
/**
|
|
16476
|
+
* brepjs-families -> BimModel adapter. Consumes a resolved element tree and
|
|
16477
|
+
* feeds each element's PRE-DESUGARED props into the parametric specs — the
|
|
16478
|
+
* spec path stays authoritative for IFC (IfcExtrudedAreaSolid + placement),
|
|
16479
|
+
* while the IR path serves the viewport and dedup. GlobalIds derive from
|
|
16480
|
+
* families key paths (stable under reordering), not insertion order.
|
|
16481
|
+
*
|
|
16482
|
+
* v1 scope: Storey containers and Wall/Slab elements. Openings, fills, and
|
|
16483
|
+
* relationship wiring (IfcRelVoidsElement) follow with the opening writer.
|
|
16484
|
+
*/
|
|
16485
|
+
var SPEC_DEFAULTS = {
|
|
16486
|
+
origin: [
|
|
16487
|
+
0,
|
|
16488
|
+
0,
|
|
16489
|
+
0
|
|
16490
|
+
],
|
|
16491
|
+
axisX: [
|
|
16492
|
+
1,
|
|
16493
|
+
0,
|
|
16494
|
+
0
|
|
16495
|
+
],
|
|
16496
|
+
axisZ: [
|
|
16497
|
+
0,
|
|
16498
|
+
0,
|
|
16499
|
+
1
|
|
16500
|
+
],
|
|
16501
|
+
materialName: "Default"
|
|
16502
|
+
};
|
|
16503
|
+
var GEOMETRY_PROPS = /* @__PURE__ */ new Set([
|
|
16504
|
+
"voids",
|
|
16505
|
+
"fuse",
|
|
16506
|
+
"transform",
|
|
16507
|
+
"psets"
|
|
16508
|
+
]);
|
|
16509
|
+
/** Fold the resolved geometry's OUTER literal translate chain into the spec
|
|
16510
|
+
* placement origin, so IfcLocalPlacement matches the IR world frame no
|
|
16511
|
+
* matter where the transform came from (family-internal or prop-level).
|
|
16512
|
+
* Parameter-driven translations cannot fold and keep the default origin. */
|
|
16513
|
+
function composedOrigin(el) {
|
|
16514
|
+
const out = [...el.props["origin"] ?? [
|
|
16515
|
+
0,
|
|
16516
|
+
0,
|
|
16517
|
+
0
|
|
16518
|
+
]];
|
|
16519
|
+
let moved = false;
|
|
16520
|
+
let node = el.geometry;
|
|
16521
|
+
while (node.kind === "Translate") {
|
|
16522
|
+
const v = node.vector;
|
|
16523
|
+
if (v.kind !== "Vec3Lit") break;
|
|
16524
|
+
out[0] += v.value[0];
|
|
16525
|
+
out[1] += v.value[1];
|
|
16526
|
+
out[2] += v.value[2];
|
|
16527
|
+
moved = true;
|
|
16528
|
+
node = node.target;
|
|
16529
|
+
}
|
|
16530
|
+
return moved || el.props["origin"] !== void 0 ? out : void 0;
|
|
16531
|
+
}
|
|
16532
|
+
function specInput(el) {
|
|
16533
|
+
const fromProps = {};
|
|
16534
|
+
for (const [k, v] of Object.entries(el.props)) if (!GEOMETRY_PROPS.has(k)) fromProps[k] = v;
|
|
16535
|
+
const origin = composedOrigin(el);
|
|
16536
|
+
return {
|
|
16537
|
+
...SPEC_DEFAULTS,
|
|
16538
|
+
...fromProps,
|
|
16539
|
+
...origin ? { origin } : {},
|
|
16540
|
+
...collectSpecProps(el)
|
|
16541
|
+
};
|
|
16542
|
+
}
|
|
16543
|
+
function collectSpecProps(el) {
|
|
16544
|
+
const psets = el.attributes["psets"];
|
|
16545
|
+
const out = {};
|
|
16546
|
+
if (psets && typeof psets === "object") {
|
|
16547
|
+
const common = psets["Pset_WallCommon"];
|
|
16548
|
+
if (common && typeof common === "object") {
|
|
16549
|
+
const c = common;
|
|
16550
|
+
if (typeof c["IsExternal"] === "boolean") out["isExternal"] = c["IsExternal"];
|
|
16551
|
+
if (typeof c["FireRating"] === "string") out["fireRating"] = c["FireRating"];
|
|
16552
|
+
}
|
|
16553
|
+
}
|
|
16554
|
+
delete out["psets"];
|
|
16555
|
+
return out;
|
|
16556
|
+
}
|
|
16557
|
+
/**
|
|
16558
|
+
* Project a resolved families tree into an eager BimModel. The caller owns
|
|
16559
|
+
* the returned model (`using`); families stays domain-neutral — this adapter
|
|
16560
|
+
* is where families types meet the IFC vocabulary.
|
|
16561
|
+
*/
|
|
16562
|
+
function familiesToBim(root, options) {
|
|
16563
|
+
const model = new BimModel();
|
|
16564
|
+
const initResult = model.init(options.project);
|
|
16565
|
+
if (!initResult.ok) return initResult;
|
|
16566
|
+
const siteId = model.addSite({ name: options.siteName ?? "Site" });
|
|
16567
|
+
const buildingId = model.addBuilding({ name: options.buildingName ?? "Building" });
|
|
16568
|
+
model.aggregate(siteId, buildingId);
|
|
16569
|
+
const idByKeyPath = /* @__PURE__ */ new Map();
|
|
16570
|
+
const walk = (el, storeyId) => {
|
|
16571
|
+
let containerId = storeyId;
|
|
16572
|
+
if (el.type === "Storey") {
|
|
16573
|
+
const id = model.addStorey({
|
|
16574
|
+
name: el.attributes["name"] ?? el.keyPath,
|
|
16575
|
+
elevation: el.props["elevation"] ?? 0
|
|
16576
|
+
}, { stableKey: el.keyPath });
|
|
16577
|
+
model.aggregate(buildingId, id);
|
|
16578
|
+
idByKeyPath.set(el.keyPath, id);
|
|
16579
|
+
containerId = id;
|
|
16580
|
+
} else if (el.type === "Wall" || el.type === "Slab") {
|
|
16581
|
+
const parsed = el.type === "Wall" ? parseWallSpec(specInput(el)) : parseSlabSpec(specInput(el));
|
|
16582
|
+
if (!parsed.ok) return parsed;
|
|
16583
|
+
const added = el.type === "Wall" ? model.addWall(parsed.value, { stableKey: el.keyPath }) : model.addSlab(parsed.value, { stableKey: el.keyPath });
|
|
16584
|
+
if (!added.ok) return added;
|
|
16585
|
+
idByKeyPath.set(el.keyPath, added.value);
|
|
16586
|
+
if (containerId === null) return (0, brepjs.err)(specError("FAMILIES_NO_STOREY", `familiesToBim: '${el.keyPath}' has no Storey ancestor — IFC elements need spatial containment`));
|
|
16587
|
+
model.placeIn(added.value, containerId);
|
|
16588
|
+
} else if (el.type !== "Opening" && el.type !== "Group" && el.geometry.kind !== "Empty") return (0, brepjs.err)(specError("FAMILIES_UNSUPPORTED_TYPE", `familiesToBim: no spec mapping for element type '${el.type}' at '${el.keyPath}'`));
|
|
16589
|
+
for (const child of el.children) {
|
|
16590
|
+
const r = walk(child, containerId);
|
|
16591
|
+
if (!r.ok) return r;
|
|
16592
|
+
}
|
|
16593
|
+
return (0, brepjs.ok)(void 0);
|
|
16594
|
+
};
|
|
16595
|
+
const walked = walk(root, null);
|
|
16596
|
+
if (!walked.ok) {
|
|
16597
|
+
model[Symbol.dispose]();
|
|
16598
|
+
return walked;
|
|
16599
|
+
}
|
|
16600
|
+
return (0, brepjs.ok)({
|
|
16601
|
+
model,
|
|
16602
|
+
idByKeyPath
|
|
16603
|
+
});
|
|
16604
|
+
}
|
|
16605
|
+
//#endregion
|
|
16416
16606
|
exports.BimModel = BimModel;
|
|
16417
16607
|
exports.DEFAULT_IFC_SCHEMA = DEFAULT_IFC_SCHEMA;
|
|
16418
16608
|
exports.DEFAULT_UNITS = DEFAULT_UNITS;
|
|
@@ -16436,6 +16626,7 @@ exports.emptyReport = emptyReport;
|
|
|
16436
16626
|
exports.exportCobie = deriveCobieModel;
|
|
16437
16627
|
exports.extendedProfileArea = extendedProfileArea;
|
|
16438
16628
|
exports.extendedProfileToFace = extendedProfileToFace;
|
|
16629
|
+
exports.familiesToBim = familiesToBim;
|
|
16439
16630
|
exports.fileSchemaString = fileSchemaString;
|
|
16440
16631
|
exports.fromBrepError = fromBrepError;
|
|
16441
16632
|
exports.fromIfc = fromIfc;
|