brepjs-bim 0.11.0 → 0.13.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 +63 -17
- package/dist/brepjs-bim.js +63 -17
- package/dist/ifc-writer/stairWriter.d.ts +5 -3
- package/dist/model/bimModel.d.ts +3 -3
- package/package.json +2 -1
package/dist/brepjs-bim.cjs
CHANGED
|
@@ -6406,10 +6406,12 @@ var BimModel = class {
|
|
|
6406
6406
|
this.#associateClassification(id, spec);
|
|
6407
6407
|
return (0, brepjs.ok)(id);
|
|
6408
6408
|
}
|
|
6409
|
-
addRoof(spec) {
|
|
6409
|
+
addRoof(spec, options) {
|
|
6410
|
+
const keyCheck = this.#checkStableKey(options);
|
|
6411
|
+
if (!keyCheck.ok) return keyCheck;
|
|
6410
6412
|
const geomResult = roofToSolid(spec);
|
|
6411
6413
|
if (!geomResult.ok) return (0, brepjs.err)(geomResult.error);
|
|
6412
|
-
const id = this.#makeElement("ROOF", spec, geomResult.value);
|
|
6414
|
+
const id = this.#makeElement("ROOF", spec, geomResult.value, options?.stableKey);
|
|
6413
6415
|
this.#associateMaterial(id, spec);
|
|
6414
6416
|
this.#associateClassification(id, spec);
|
|
6415
6417
|
return (0, brepjs.ok)(id);
|
|
@@ -6443,8 +6445,10 @@ var BimModel = class {
|
|
|
6443
6445
|
* the IFC layer from `spec.flights`; the STAIR element itself carries no solid
|
|
6444
6446
|
* (the assembly container's Representation is null, valid per IFC4).
|
|
6445
6447
|
*/
|
|
6446
|
-
addStair(spec) {
|
|
6447
|
-
const
|
|
6448
|
+
addStair(spec, options) {
|
|
6449
|
+
const keyCheck = this.#checkStableKey(options);
|
|
6450
|
+
if (!keyCheck.ok) return keyCheck;
|
|
6451
|
+
const id = this.#makeElement("STAIR", spec, null, options?.stableKey);
|
|
6448
6452
|
this.#associateMaterial(id, spec);
|
|
6449
6453
|
this.#associateClassification(id, spec);
|
|
6450
6454
|
return (0, brepjs.ok)(id);
|
|
@@ -6453,8 +6457,10 @@ var BimModel = class {
|
|
|
6453
6457
|
* Adds an IfcRamp assembly. Geometry for each flight is built and written by the
|
|
6454
6458
|
* IFC layer from `spec.flights`; the RAMP element carries no solid of its own.
|
|
6455
6459
|
*/
|
|
6456
|
-
addRamp(spec) {
|
|
6457
|
-
const
|
|
6460
|
+
addRamp(spec, options) {
|
|
6461
|
+
const keyCheck = this.#checkStableKey(options);
|
|
6462
|
+
if (!keyCheck.ok) return keyCheck;
|
|
6463
|
+
const id = this.#makeElement("RAMP", spec, null, options?.stableKey);
|
|
6458
6464
|
this.#associateMaterial(id, spec);
|
|
6459
6465
|
this.#associateClassification(id, spec);
|
|
6460
6466
|
return (0, brepjs.ok)(id);
|
|
@@ -8101,7 +8107,7 @@ function writeTessellation(w, solid, geomSubContextId, _localPlacementId, tolera
|
|
|
8101
8107
|
type: web_ifc.IFCTRIANGULATEDFACESET,
|
|
8102
8108
|
Coordinates: w.ref(pointListId),
|
|
8103
8109
|
Normals: null,
|
|
8104
|
-
Closed: true,
|
|
8110
|
+
Closed: w.mkType(web_ifc.IFCBOOLEAN, true),
|
|
8105
8111
|
CoordIndex: coordIndex.map((tri) => tri.map((idx) => w.mkType(web_ifc.IFCPOSITIVEINTEGER, idx))),
|
|
8106
8112
|
PnIndex: null
|
|
8107
8113
|
});
|
|
@@ -8205,7 +8211,7 @@ function writeFacetedBrepFallback(w, geomSubContextId, reason) {
|
|
|
8205
8211
|
expressID: faceOuterBoundId,
|
|
8206
8212
|
type: web_ifc.IFCFACEOUTERBOUND,
|
|
8207
8213
|
Bound: w.ref(loopId),
|
|
8208
|
-
Orientation: true
|
|
8214
|
+
Orientation: w.mkType(web_ifc.IFCBOOLEAN, true)
|
|
8209
8215
|
});
|
|
8210
8216
|
const faceId = w.nextId();
|
|
8211
8217
|
w.writeLine({
|
|
@@ -9630,13 +9636,15 @@ function writeRampEntity(w, guid, name, predefinedType, ownerHistoryId, localPla
|
|
|
9630
9636
|
* per `spec.flights[i]` (each with a tessellated stepped-solid body), and a single
|
|
9631
9637
|
* IfcRelAggregates linking the flights to the stair. Flight placements are
|
|
9632
9638
|
* relative to the stair placement, which is relative to `parentPlacementId`
|
|
9633
|
-
* (typically the storey).
|
|
9639
|
+
* (typically the storey). The assembly's GlobalId is the element's stored guid
|
|
9640
|
+
* (stableKey-derived when the caller provided one); flight, type, and
|
|
9641
|
+
* relationship GUIDs are deterministic, keyed on `stairKey`/index so
|
|
9634
9642
|
* re-serializing an identical model is byte-stable.
|
|
9635
9643
|
*
|
|
9636
9644
|
* Returns a BimError if any flight solid cannot be built. Stair flights are real
|
|
9637
9645
|
* stepped solids; tessellation failure is flagged via `geometrySimplified`.
|
|
9638
9646
|
*/
|
|
9639
|
-
function writeStairAssembly(w, spec, stairKey, ownerHistoryId, geomSubContextId, parentPlacementId) {
|
|
9647
|
+
function writeStairAssembly(w, spec, stairKey, assemblyGuid, ownerHistoryId, geomSubContextId, parentPlacementId) {
|
|
9640
9648
|
const predefinedType = spec.predefinedType ?? "NOTDEFINED";
|
|
9641
9649
|
const stairName = spec.name ?? "Stair";
|
|
9642
9650
|
if (spec.flights[0] === void 0) return {
|
|
@@ -9656,7 +9664,7 @@ function writeStairAssembly(w, spec, stairKey, ownerHistoryId, geomSubContextId,
|
|
|
9656
9664
|
0,
|
|
9657
9665
|
0
|
|
9658
9666
|
], parentPlacementId);
|
|
9659
|
-
const assemblyExpressId = writeStairEntity(w,
|
|
9667
|
+
const assemblyExpressId = writeStairEntity(w, assemblyGuid, stairName, predefinedType, ownerHistoryId, stairPlacementId);
|
|
9660
9668
|
const flightExpressIds = [];
|
|
9661
9669
|
let geometrySimplified = false;
|
|
9662
9670
|
for (const [i, flight] of spec.flights.entries()) try {
|
|
@@ -9696,7 +9704,7 @@ function writeStairAssembly(w, spec, stairKey, ownerHistoryId, geomSubContextId,
|
|
|
9696
9704
|
* inclined-slab solids, so `geometrySimplified` is always true. GUIDs are
|
|
9697
9705
|
* deterministic keyed on `rampKey`.
|
|
9698
9706
|
*/
|
|
9699
|
-
function writeRampAssembly(w, spec, rampKey, ownerHistoryId, geomSubContextId, parentPlacementId) {
|
|
9707
|
+
function writeRampAssembly(w, spec, rampKey, assemblyGuid, ownerHistoryId, geomSubContextId, parentPlacementId) {
|
|
9700
9708
|
const predefinedType = spec.predefinedType ?? "NOTDEFINED";
|
|
9701
9709
|
const rampName = spec.name ?? "Ramp";
|
|
9702
9710
|
if (spec.flights[0] === void 0) return {
|
|
@@ -9716,7 +9724,7 @@ function writeRampAssembly(w, spec, rampKey, ownerHistoryId, geomSubContextId, p
|
|
|
9716
9724
|
0,
|
|
9717
9725
|
0
|
|
9718
9726
|
], parentPlacementId);
|
|
9719
|
-
const assemblyExpressId = writeRampEntity(w,
|
|
9727
|
+
const assemblyExpressId = writeRampEntity(w, assemblyGuid, rampName, predefinedType, ownerHistoryId, rampPlacementId);
|
|
9720
9728
|
const flightExpressIds = [];
|
|
9721
9729
|
const geometrySimplified = true;
|
|
9722
9730
|
for (const [i, flight] of spec.flights.entries()) try {
|
|
@@ -12275,7 +12283,7 @@ async function toIfc(model, meta) {
|
|
|
12275
12283
|
for (const stair of stairs) {
|
|
12276
12284
|
const containingId = findContainerOf(stair.localId, relationships);
|
|
12277
12285
|
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
12278
|
-
const result = writeStairAssembly(w, stair.spec, `${stair.localId}`, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
12286
|
+
const result = writeStairAssembly(w, stair.spec, `${stair.localId}`, stair.guid, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
12279
12287
|
if (!result.ok) return (0, brepjs.err)(result.error);
|
|
12280
12288
|
idMap.set(stair.localId, result.value.assemblyExpressId);
|
|
12281
12289
|
writeStairCommonPset(w, ownerHistoryId, result.value.assemblyExpressId, stair.spec);
|
|
@@ -12283,7 +12291,7 @@ async function toIfc(model, meta) {
|
|
|
12283
12291
|
for (const ramp of ramps) {
|
|
12284
12292
|
const containingId = findContainerOf(ramp.localId, relationships);
|
|
12285
12293
|
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
12286
|
-
const result = writeRampAssembly(w, ramp.spec, `${ramp.localId}`, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
12294
|
+
const result = writeRampAssembly(w, ramp.spec, `${ramp.localId}`, ramp.guid, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
12287
12295
|
if (!result.ok) return (0, brepjs.err)(result.error);
|
|
12288
12296
|
idMap.set(ramp.localId, result.value.assemblyExpressId);
|
|
12289
12297
|
writeRampCommonPset(w, ownerHistoryId, result.value.assemblyExpressId, ramp.spec);
|
|
@@ -16497,7 +16505,7 @@ function assignNum(target, key, value) {
|
|
|
16497
16505
|
* while the IR path serves the viewport and dedup. GlobalIds derive from
|
|
16498
16506
|
* families key paths (stable under reordering), not insertion order.
|
|
16499
16507
|
*
|
|
16500
|
-
* Scope: Storey containers, Wall/Slab/Column/Beam elements, and wall openings — a
|
|
16508
|
+
* Scope: Storey containers, Wall/Slab/Column/Beam/Roof/Stair elements, and wall openings — a
|
|
16501
16509
|
* fill-role void (Door/Window family) maps onto addDoor/addWindow, which cut
|
|
16502
16510
|
* the wall and wire IfcRelVoidsElement + IfcRelFillsElement; the opening and
|
|
16503
16511
|
* filler GlobalIds derive from the synthesized key paths. Anonymous (non-fill)
|
|
@@ -16543,8 +16551,46 @@ var SPEC_ROUTES = {
|
|
|
16543
16551
|
Beam: {
|
|
16544
16552
|
parse: parseBeamSpec,
|
|
16545
16553
|
add: (m, spec, key) => m.addBeam(spec, { stableKey: key })
|
|
16554
|
+
},
|
|
16555
|
+
Roof: {
|
|
16556
|
+
parse: parseRoofSpec,
|
|
16557
|
+
add: (m, spec, key) => m.addRoof(spec, { stableKey: key })
|
|
16558
|
+
},
|
|
16559
|
+
Stair: {
|
|
16560
|
+
parse: parseStairSpec,
|
|
16561
|
+
add: (m, spec, key) => m.addStair(spec, { stableKey: key }),
|
|
16562
|
+
input: stairSpecInput
|
|
16546
16563
|
}
|
|
16547
16564
|
};
|
|
16565
|
+
/** StairSpec has no top-level origin — placement lives per flight — so the
|
|
16566
|
+
* element's folded translate lands on every flight's origin instead. */
|
|
16567
|
+
function stairSpecInput(el) {
|
|
16568
|
+
const base = specInput(el);
|
|
16569
|
+
const fold = base["origin"] ?? [
|
|
16570
|
+
0,
|
|
16571
|
+
0,
|
|
16572
|
+
0
|
|
16573
|
+
];
|
|
16574
|
+
const flights = Array.isArray(base["flights"]) ? base["flights"] : [];
|
|
16575
|
+
return {
|
|
16576
|
+
...base,
|
|
16577
|
+
flights: flights.map((f) => {
|
|
16578
|
+
const fo = f["origin"] ?? [
|
|
16579
|
+
0,
|
|
16580
|
+
0,
|
|
16581
|
+
0
|
|
16582
|
+
];
|
|
16583
|
+
return {
|
|
16584
|
+
...f,
|
|
16585
|
+
origin: [
|
|
16586
|
+
fo[0] + fold[0],
|
|
16587
|
+
fo[1] + fold[1],
|
|
16588
|
+
fo[2] + fold[2]
|
|
16589
|
+
]
|
|
16590
|
+
};
|
|
16591
|
+
})
|
|
16592
|
+
};
|
|
16593
|
+
}
|
|
16548
16594
|
function specRoute(type) {
|
|
16549
16595
|
return Object.hasOwn(SPEC_ROUTES, type) ? SPEC_ROUTES[type] : void 0;
|
|
16550
16596
|
}
|
|
@@ -16707,7 +16753,7 @@ function familiesToBim(root, options) {
|
|
|
16707
16753
|
} else if (route !== void 0) {
|
|
16708
16754
|
const keyed = requireKeyed(el);
|
|
16709
16755
|
if (!keyed.ok) return keyed;
|
|
16710
|
-
const parsed = route.parse(specInput(el));
|
|
16756
|
+
const parsed = route.parse(("input" in route ? route.input : specInput)(el));
|
|
16711
16757
|
if (!parsed.ok) return parsed;
|
|
16712
16758
|
const added = route.add(model, parsed.value, el.keyPath);
|
|
16713
16759
|
if (!added.ok) return added;
|
package/dist/brepjs-bim.js
CHANGED
|
@@ -6383,10 +6383,12 @@ var BimModel = class {
|
|
|
6383
6383
|
this.#associateClassification(id, spec);
|
|
6384
6384
|
return ok(id);
|
|
6385
6385
|
}
|
|
6386
|
-
addRoof(spec) {
|
|
6386
|
+
addRoof(spec, options) {
|
|
6387
|
+
const keyCheck = this.#checkStableKey(options);
|
|
6388
|
+
if (!keyCheck.ok) return keyCheck;
|
|
6387
6389
|
const geomResult = roofToSolid(spec);
|
|
6388
6390
|
if (!geomResult.ok) return err(geomResult.error);
|
|
6389
|
-
const id = this.#makeElement("ROOF", spec, geomResult.value);
|
|
6391
|
+
const id = this.#makeElement("ROOF", spec, geomResult.value, options?.stableKey);
|
|
6390
6392
|
this.#associateMaterial(id, spec);
|
|
6391
6393
|
this.#associateClassification(id, spec);
|
|
6392
6394
|
return ok(id);
|
|
@@ -6420,8 +6422,10 @@ var BimModel = class {
|
|
|
6420
6422
|
* the IFC layer from `spec.flights`; the STAIR element itself carries no solid
|
|
6421
6423
|
* (the assembly container's Representation is null, valid per IFC4).
|
|
6422
6424
|
*/
|
|
6423
|
-
addStair(spec) {
|
|
6424
|
-
const
|
|
6425
|
+
addStair(spec, options) {
|
|
6426
|
+
const keyCheck = this.#checkStableKey(options);
|
|
6427
|
+
if (!keyCheck.ok) return keyCheck;
|
|
6428
|
+
const id = this.#makeElement("STAIR", spec, null, options?.stableKey);
|
|
6425
6429
|
this.#associateMaterial(id, spec);
|
|
6426
6430
|
this.#associateClassification(id, spec);
|
|
6427
6431
|
return ok(id);
|
|
@@ -6430,8 +6434,10 @@ var BimModel = class {
|
|
|
6430
6434
|
* Adds an IfcRamp assembly. Geometry for each flight is built and written by the
|
|
6431
6435
|
* IFC layer from `spec.flights`; the RAMP element carries no solid of its own.
|
|
6432
6436
|
*/
|
|
6433
|
-
addRamp(spec) {
|
|
6434
|
-
const
|
|
6437
|
+
addRamp(spec, options) {
|
|
6438
|
+
const keyCheck = this.#checkStableKey(options);
|
|
6439
|
+
if (!keyCheck.ok) return keyCheck;
|
|
6440
|
+
const id = this.#makeElement("RAMP", spec, null, options?.stableKey);
|
|
6435
6441
|
this.#associateMaterial(id, spec);
|
|
6436
6442
|
this.#associateClassification(id, spec);
|
|
6437
6443
|
return ok(id);
|
|
@@ -8078,7 +8084,7 @@ function writeTessellation(w, solid, geomSubContextId, _localPlacementId, tolera
|
|
|
8078
8084
|
type: WebIFC.IFCTRIANGULATEDFACESET,
|
|
8079
8085
|
Coordinates: w.ref(pointListId),
|
|
8080
8086
|
Normals: null,
|
|
8081
|
-
Closed: true,
|
|
8087
|
+
Closed: w.mkType(WebIFC.IFCBOOLEAN, true),
|
|
8082
8088
|
CoordIndex: coordIndex.map((tri) => tri.map((idx) => w.mkType(WebIFC.IFCPOSITIVEINTEGER, idx))),
|
|
8083
8089
|
PnIndex: null
|
|
8084
8090
|
});
|
|
@@ -8182,7 +8188,7 @@ function writeFacetedBrepFallback(w, geomSubContextId, reason) {
|
|
|
8182
8188
|
expressID: faceOuterBoundId,
|
|
8183
8189
|
type: WebIFC.IFCFACEOUTERBOUND,
|
|
8184
8190
|
Bound: w.ref(loopId),
|
|
8185
|
-
Orientation: true
|
|
8191
|
+
Orientation: w.mkType(WebIFC.IFCBOOLEAN, true)
|
|
8186
8192
|
});
|
|
8187
8193
|
const faceId = w.nextId();
|
|
8188
8194
|
w.writeLine({
|
|
@@ -9607,13 +9613,15 @@ function writeRampEntity(w, guid, name, predefinedType, ownerHistoryId, localPla
|
|
|
9607
9613
|
* per `spec.flights[i]` (each with a tessellated stepped-solid body), and a single
|
|
9608
9614
|
* IfcRelAggregates linking the flights to the stair. Flight placements are
|
|
9609
9615
|
* relative to the stair placement, which is relative to `parentPlacementId`
|
|
9610
|
-
* (typically the storey).
|
|
9616
|
+
* (typically the storey). The assembly's GlobalId is the element's stored guid
|
|
9617
|
+
* (stableKey-derived when the caller provided one); flight, type, and
|
|
9618
|
+
* relationship GUIDs are deterministic, keyed on `stairKey`/index so
|
|
9611
9619
|
* re-serializing an identical model is byte-stable.
|
|
9612
9620
|
*
|
|
9613
9621
|
* Returns a BimError if any flight solid cannot be built. Stair flights are real
|
|
9614
9622
|
* stepped solids; tessellation failure is flagged via `geometrySimplified`.
|
|
9615
9623
|
*/
|
|
9616
|
-
function writeStairAssembly(w, spec, stairKey, ownerHistoryId, geomSubContextId, parentPlacementId) {
|
|
9624
|
+
function writeStairAssembly(w, spec, stairKey, assemblyGuid, ownerHistoryId, geomSubContextId, parentPlacementId) {
|
|
9617
9625
|
const predefinedType = spec.predefinedType ?? "NOTDEFINED";
|
|
9618
9626
|
const stairName = spec.name ?? "Stair";
|
|
9619
9627
|
if (spec.flights[0] === void 0) return {
|
|
@@ -9633,7 +9641,7 @@ function writeStairAssembly(w, spec, stairKey, ownerHistoryId, geomSubContextId,
|
|
|
9633
9641
|
0,
|
|
9634
9642
|
0
|
|
9635
9643
|
], parentPlacementId);
|
|
9636
|
-
const assemblyExpressId = writeStairEntity(w,
|
|
9644
|
+
const assemblyExpressId = writeStairEntity(w, assemblyGuid, stairName, predefinedType, ownerHistoryId, stairPlacementId);
|
|
9637
9645
|
const flightExpressIds = [];
|
|
9638
9646
|
let geometrySimplified = false;
|
|
9639
9647
|
for (const [i, flight] of spec.flights.entries()) try {
|
|
@@ -9673,7 +9681,7 @@ function writeStairAssembly(w, spec, stairKey, ownerHistoryId, geomSubContextId,
|
|
|
9673
9681
|
* inclined-slab solids, so `geometrySimplified` is always true. GUIDs are
|
|
9674
9682
|
* deterministic keyed on `rampKey`.
|
|
9675
9683
|
*/
|
|
9676
|
-
function writeRampAssembly(w, spec, rampKey, ownerHistoryId, geomSubContextId, parentPlacementId) {
|
|
9684
|
+
function writeRampAssembly(w, spec, rampKey, assemblyGuid, ownerHistoryId, geomSubContextId, parentPlacementId) {
|
|
9677
9685
|
const predefinedType = spec.predefinedType ?? "NOTDEFINED";
|
|
9678
9686
|
const rampName = spec.name ?? "Ramp";
|
|
9679
9687
|
if (spec.flights[0] === void 0) return {
|
|
@@ -9693,7 +9701,7 @@ function writeRampAssembly(w, spec, rampKey, ownerHistoryId, geomSubContextId, p
|
|
|
9693
9701
|
0,
|
|
9694
9702
|
0
|
|
9695
9703
|
], parentPlacementId);
|
|
9696
|
-
const assemblyExpressId = writeRampEntity(w,
|
|
9704
|
+
const assemblyExpressId = writeRampEntity(w, assemblyGuid, rampName, predefinedType, ownerHistoryId, rampPlacementId);
|
|
9697
9705
|
const flightExpressIds = [];
|
|
9698
9706
|
const geometrySimplified = true;
|
|
9699
9707
|
for (const [i, flight] of spec.flights.entries()) try {
|
|
@@ -12252,7 +12260,7 @@ async function toIfc(model, meta) {
|
|
|
12252
12260
|
for (const stair of stairs) {
|
|
12253
12261
|
const containingId = findContainerOf(stair.localId, relationships);
|
|
12254
12262
|
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
12255
|
-
const result = writeStairAssembly(w, stair.spec, `${stair.localId}`, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
12263
|
+
const result = writeStairAssembly(w, stair.spec, `${stair.localId}`, stair.guid, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
12256
12264
|
if (!result.ok) return err(result.error);
|
|
12257
12265
|
idMap.set(stair.localId, result.value.assemblyExpressId);
|
|
12258
12266
|
writeStairCommonPset(w, ownerHistoryId, result.value.assemblyExpressId, stair.spec);
|
|
@@ -12260,7 +12268,7 @@ async function toIfc(model, meta) {
|
|
|
12260
12268
|
for (const ramp of ramps) {
|
|
12261
12269
|
const containingId = findContainerOf(ramp.localId, relationships);
|
|
12262
12270
|
const storeyPlacementId = containingId !== null ? placementMap.get(containingId) ?? null : null;
|
|
12263
|
-
const result = writeRampAssembly(w, ramp.spec, `${ramp.localId}`, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
12271
|
+
const result = writeRampAssembly(w, ramp.spec, `${ramp.localId}`, ramp.guid, ownerHistoryId, geomSubContextId, storeyPlacementId);
|
|
12264
12272
|
if (!result.ok) return err(result.error);
|
|
12265
12273
|
idMap.set(ramp.localId, result.value.assemblyExpressId);
|
|
12266
12274
|
writeRampCommonPset(w, ownerHistoryId, result.value.assemblyExpressId, ramp.spec);
|
|
@@ -16474,7 +16482,7 @@ function assignNum(target, key, value) {
|
|
|
16474
16482
|
* while the IR path serves the viewport and dedup. GlobalIds derive from
|
|
16475
16483
|
* families key paths (stable under reordering), not insertion order.
|
|
16476
16484
|
*
|
|
16477
|
-
* Scope: Storey containers, Wall/Slab/Column/Beam elements, and wall openings — a
|
|
16485
|
+
* Scope: Storey containers, Wall/Slab/Column/Beam/Roof/Stair elements, and wall openings — a
|
|
16478
16486
|
* fill-role void (Door/Window family) maps onto addDoor/addWindow, which cut
|
|
16479
16487
|
* the wall and wire IfcRelVoidsElement + IfcRelFillsElement; the opening and
|
|
16480
16488
|
* filler GlobalIds derive from the synthesized key paths. Anonymous (non-fill)
|
|
@@ -16520,8 +16528,46 @@ var SPEC_ROUTES = {
|
|
|
16520
16528
|
Beam: {
|
|
16521
16529
|
parse: parseBeamSpec,
|
|
16522
16530
|
add: (m, spec, key) => m.addBeam(spec, { stableKey: key })
|
|
16531
|
+
},
|
|
16532
|
+
Roof: {
|
|
16533
|
+
parse: parseRoofSpec,
|
|
16534
|
+
add: (m, spec, key) => m.addRoof(spec, { stableKey: key })
|
|
16535
|
+
},
|
|
16536
|
+
Stair: {
|
|
16537
|
+
parse: parseStairSpec,
|
|
16538
|
+
add: (m, spec, key) => m.addStair(spec, { stableKey: key }),
|
|
16539
|
+
input: stairSpecInput
|
|
16523
16540
|
}
|
|
16524
16541
|
};
|
|
16542
|
+
/** StairSpec has no top-level origin — placement lives per flight — so the
|
|
16543
|
+
* element's folded translate lands on every flight's origin instead. */
|
|
16544
|
+
function stairSpecInput(el) {
|
|
16545
|
+
const base = specInput(el);
|
|
16546
|
+
const fold = base["origin"] ?? [
|
|
16547
|
+
0,
|
|
16548
|
+
0,
|
|
16549
|
+
0
|
|
16550
|
+
];
|
|
16551
|
+
const flights = Array.isArray(base["flights"]) ? base["flights"] : [];
|
|
16552
|
+
return {
|
|
16553
|
+
...base,
|
|
16554
|
+
flights: flights.map((f) => {
|
|
16555
|
+
const fo = f["origin"] ?? [
|
|
16556
|
+
0,
|
|
16557
|
+
0,
|
|
16558
|
+
0
|
|
16559
|
+
];
|
|
16560
|
+
return {
|
|
16561
|
+
...f,
|
|
16562
|
+
origin: [
|
|
16563
|
+
fo[0] + fold[0],
|
|
16564
|
+
fo[1] + fold[1],
|
|
16565
|
+
fo[2] + fold[2]
|
|
16566
|
+
]
|
|
16567
|
+
};
|
|
16568
|
+
})
|
|
16569
|
+
};
|
|
16570
|
+
}
|
|
16525
16571
|
function specRoute(type) {
|
|
16526
16572
|
return Object.hasOwn(SPEC_ROUTES, type) ? SPEC_ROUTES[type] : void 0;
|
|
16527
16573
|
}
|
|
@@ -16684,7 +16730,7 @@ function familiesToBim(root, options) {
|
|
|
16684
16730
|
} else if (route !== void 0) {
|
|
16685
16731
|
const keyed = requireKeyed(el);
|
|
16686
16732
|
if (!keyed.ok) return keyed;
|
|
16687
|
-
const parsed = route.parse(specInput(el));
|
|
16733
|
+
const parsed = route.parse(("input" in route ? route.input : specInput)(el));
|
|
16688
16734
|
if (!parsed.ok) return parsed;
|
|
16689
16735
|
const added = route.add(model, parsed.value, el.keyPath);
|
|
16690
16736
|
if (!added.ok) return added;
|
|
@@ -20,13 +20,15 @@ export interface AssemblyWriteResult {
|
|
|
20
20
|
* per `spec.flights[i]` (each with a tessellated stepped-solid body), and a single
|
|
21
21
|
* IfcRelAggregates linking the flights to the stair. Flight placements are
|
|
22
22
|
* relative to the stair placement, which is relative to `parentPlacementId`
|
|
23
|
-
* (typically the storey).
|
|
23
|
+
* (typically the storey). The assembly's GlobalId is the element's stored guid
|
|
24
|
+
* (stableKey-derived when the caller provided one); flight, type, and
|
|
25
|
+
* relationship GUIDs are deterministic, keyed on `stairKey`/index so
|
|
24
26
|
* re-serializing an identical model is byte-stable.
|
|
25
27
|
*
|
|
26
28
|
* Returns a BimError if any flight solid cannot be built. Stair flights are real
|
|
27
29
|
* stepped solids; tessellation failure is flagged via `geometrySimplified`.
|
|
28
30
|
*/
|
|
29
|
-
export declare function writeStairAssembly(w: IfcWriter, spec: StairSpec, stairKey: string, ownerHistoryId: number, geomSubContextId: number, parentPlacementId: number | null): {
|
|
31
|
+
export declare function writeStairAssembly(w: IfcWriter, spec: StairSpec, stairKey: string, assemblyGuid: string, ownerHistoryId: number, geomSubContextId: number, parentPlacementId: number | null): {
|
|
30
32
|
ok: true;
|
|
31
33
|
value: AssemblyWriteResult;
|
|
32
34
|
} | {
|
|
@@ -40,7 +42,7 @@ export declare function writeStairAssembly(w: IfcWriter, spec: StairSpec, stairK
|
|
|
40
42
|
* inclined-slab solids, so `geometrySimplified` is always true. GUIDs are
|
|
41
43
|
* deterministic keyed on `rampKey`.
|
|
42
44
|
*/
|
|
43
|
-
export declare function writeRampAssembly(w: IfcWriter, spec: RampSpec, rampKey: string, ownerHistoryId: number, geomSubContextId: number, parentPlacementId: number | null): {
|
|
45
|
+
export declare function writeRampAssembly(w: IfcWriter, spec: RampSpec, rampKey: string, assemblyGuid: string, ownerHistoryId: number, geomSubContextId: number, parentPlacementId: number | null): {
|
|
44
46
|
ok: true;
|
|
45
47
|
value: AssemblyWriteResult;
|
|
46
48
|
} | {
|
package/dist/model/bimModel.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export declare class BimModel {
|
|
|
45
45
|
addBeam(spec: BeamSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
|
|
46
46
|
addColumn(spec: ColumnSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
|
|
47
47
|
addSpace(spec: SpaceSpec): Result<LocalId, BimError>;
|
|
48
|
-
addRoof(spec: RoofSpec): Result<LocalId, BimError>;
|
|
48
|
+
addRoof(spec: RoofSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
|
|
49
49
|
addCurtainWall(spec: CurtainWallSpec): Result<LocalId, BimError>;
|
|
50
50
|
addFooting(spec: FootingSpec): Result<LocalId, BimError>;
|
|
51
51
|
addPile(spec: PileSpec): Result<LocalId, BimError>;
|
|
@@ -54,12 +54,12 @@ export declare class BimModel {
|
|
|
54
54
|
* the IFC layer from `spec.flights`; the STAIR element itself carries no solid
|
|
55
55
|
* (the assembly container's Representation is null, valid per IFC4).
|
|
56
56
|
*/
|
|
57
|
-
addStair(spec: StairSpec): Result<LocalId, BimError>;
|
|
57
|
+
addStair(spec: StairSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
|
|
58
58
|
/**
|
|
59
59
|
* Adds an IfcRamp assembly. Geometry for each flight is built and written by the
|
|
60
60
|
* IFC layer from `spec.flights`; the RAMP element carries no solid of its own.
|
|
61
61
|
*/
|
|
62
|
-
addRamp(spec: RampSpec): Result<LocalId, BimError>;
|
|
62
|
+
addRamp(spec: RampSpec, options?: ElementIdentityOptions): Result<LocalId, BimError>;
|
|
63
63
|
addRailing(spec: RailingSpec): Result<LocalId, BimError>;
|
|
64
64
|
/**
|
|
65
65
|
* Adds an IfcCovering. When `hostLocalId` is supplied, an
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brepjs-bim",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "BIM layer for brepjs — IFC4-aligned parametric building elements",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bim",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"build": "vite build",
|
|
44
44
|
"typecheck": "tsgo --noEmit",
|
|
45
45
|
"test": "vitest run",
|
|
46
|
+
"test:coverage": "vitest run --coverage",
|
|
46
47
|
"lint": "eslint src tests"
|
|
47
48
|
},
|
|
48
49
|
"peerDependencies": {
|