brepjs-bim 0.16.1 → 0.17.1
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 +22 -17
- package/dist/brepjs-bim.cjs +117 -71
- package/dist/brepjs-bim.js +117 -71
- package/dist/elementFns/placedGeometry.d.ts +6 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,7 +23,8 @@ curtain walls, a panel/mullion grid). Element geometry is **unplaced template ge
|
|
|
23
23
|
coordinates — placement (`origin` / `axisX` / `axisZ`) is applied by the IFC layer via
|
|
24
24
|
`IfcLocalPlacement`, not baked into the brepjs solid. Use `placedSolids(element)` to read an
|
|
25
25
|
element's geometry already transformed to its world placement as fresh, caller-owned solids
|
|
26
|
-
(stairs return one solid per flight
|
|
26
|
+
(stairs and ramps return one solid per flight, curtain walls their panels and mullions) — handy
|
|
27
|
+
for display so the on-screen scene matches the IFC
|
|
27
28
|
export.
|
|
28
29
|
|
|
29
30
|
- Units default to mm; IFC export emits SI metres.
|
|
@@ -35,18 +36,18 @@ export.
|
|
|
35
36
|
|
|
36
37
|
## Status
|
|
37
38
|
|
|
38
|
-
| Area | State
|
|
39
|
-
| ----------------- |
|
|
40
|
-
| Elements | wall, slab, beam, column, roof, curtain wall, space, footing/pile, stair, ramp, railing, covering, proxy
|
|
41
|
-
| Profiles | rectangular / circular / I-shape cores + extended L/T/U/Z/C, hollow, ellipse, arbitrary-with-voids
|
|
42
|
-
| Openings | door / window / slab openings cut as boolean voids; `FillsOpening` / `Voids*` relationships
|
|
43
|
-
| Spatial structure | project → site → building → storey aggregation; `placeIn` to assign elements to a storey
|
|
44
|
-
| Property sets | IFC pset templates + measure types; quantity sets for takeoff
|
|
45
|
-
| Data layers | materials (layer/profile/simple sets), classification refs, surface styles, zones/systems
|
|
46
|
-
| IFC export | `toIfc` → IFC-SPF (`Uint8Array`); IFC4 / IFC4X3 schema selection; owner history
|
|
47
|
-
| IFC import | `fromIfc` / `SpfReader` → `ImportedModel` (elements, geometry, psets, materials, spatial tree)
|
|
48
|
-
| Validation | referential integrity, schema check, geometry validity, IFC round-trip report
|
|
49
|
-
| Interop | COBie 2.4 export (CSV/JSON), IDS 1.0 checking, BCF 3.0 read/write
|
|
39
|
+
| Area | State |
|
|
40
|
+
| ----------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
41
|
+
| Elements | wall, slab, beam, column, roof, curtain wall, space, footing/pile, stair, ramp, railing, covering, proxy |
|
|
42
|
+
| Profiles | rectangular / circular / I-shape cores + extended L/T/U/Z/C, hollow, ellipse, arbitrary-with-voids |
|
|
43
|
+
| Openings | door / window / slab openings cut as boolean voids; `FillsOpening` / `Voids*` relationships |
|
|
44
|
+
| Spatial structure | project → site → building → storey aggregation; `placeIn` to assign elements to a storey |
|
|
45
|
+
| Property sets | IFC pset templates + measure types; quantity sets for takeoff |
|
|
46
|
+
| Data layers | materials (layer/profile/simple sets), classification refs, surface styles, zones/systems |
|
|
47
|
+
| IFC export | `toIfc` → IFC-SPF (`Uint8Array`); IFC4 / IFC4X3 schema selection; owner history |
|
|
48
|
+
| IFC import | `fromIfc` / `SpfReader` → `ImportedModel` (elements, geometry, psets, materials, spatial tree) |
|
|
49
|
+
| Validation | referential integrity, schema check, geometry validity, IFC round-trip report, buildingSMART gherkin rules |
|
|
50
|
+
| Interop | COBie 2.4 export (CSV/JSON), IDS 1.0 checking, BCF 3.0 read/write |
|
|
50
51
|
|
|
51
52
|
### Independent validation
|
|
52
53
|
|
|
@@ -56,9 +57,13 @@ web-ifc parser used internally), not just self-checked. The committed sample
|
|
|
56
57
|
validator and generates geometry for every product. See [VALIDATION.md](./VALIDATION.md)
|
|
57
58
|
to reproduce, and `examples/sampleBuilding.mjs` for the model it validates.
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
The buildingSMART Validation Service's complete normative rule catalog also runs
|
|
61
|
+
locally (`scripts/setupGherkinRunner.sh` builds the service's own engine; all three
|
|
62
|
+
committed fixtures pass 950 scenarios with zero failures), so service findings are
|
|
63
|
+
reproducible before upload.
|
|
64
|
+
|
|
65
|
+
> **Not yet:** desktop-tool interop (Revit / Solibri) is unverified. The fixtures
|
|
66
|
+
> and per-tool checklists are ready in [VALIDATION.md](./VALIDATION.md). This is an
|
|
62
67
|
> experimental pre-1.0 package and the API may change.
|
|
63
68
|
|
|
64
69
|
## Usage
|
|
@@ -98,7 +103,7 @@ if (wall.ok) model.placeIn(wall.value, storeyId);
|
|
|
98
103
|
const solid = model.getWalls()[0]?.geometry;
|
|
99
104
|
|
|
100
105
|
// Serialize to an IFC-SPF byte buffer.
|
|
101
|
-
const ifc = await toIfc(model, {
|
|
106
|
+
const ifc = await toIfc(model, { applicationName: 'brepjs-bim', applicationVersion: '1.0' });
|
|
102
107
|
// ifc.ok && ifc.value instanceof Uint8Array
|
|
103
108
|
```
|
|
104
109
|
|
package/dist/brepjs-bim.cjs
CHANGED
|
@@ -7314,6 +7314,65 @@ function stairFlightToSolid(spec) {
|
|
|
7314
7314
|
}
|
|
7315
7315
|
}
|
|
7316
7316
|
//#endregion
|
|
7317
|
+
//#region src/elementFns/rampFns.ts
|
|
7318
|
+
function buildSilhouette(length, rise, thickness) {
|
|
7319
|
+
return [
|
|
7320
|
+
[
|
|
7321
|
+
0,
|
|
7322
|
+
0,
|
|
7323
|
+
-thickness
|
|
7324
|
+
],
|
|
7325
|
+
[
|
|
7326
|
+
length,
|
|
7327
|
+
0,
|
|
7328
|
+
rise - thickness
|
|
7329
|
+
],
|
|
7330
|
+
[
|
|
7331
|
+
length,
|
|
7332
|
+
0,
|
|
7333
|
+
rise
|
|
7334
|
+
],
|
|
7335
|
+
[
|
|
7336
|
+
0,
|
|
7337
|
+
0,
|
|
7338
|
+
0
|
|
7339
|
+
]
|
|
7340
|
+
];
|
|
7341
|
+
}
|
|
7342
|
+
function rampFlightToSolid(spec) {
|
|
7343
|
+
try {
|
|
7344
|
+
var _usingCtx$4 = _usingCtx();
|
|
7345
|
+
if (spec.width <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_WIDTH", "Ramp flight width must be positive"));
|
|
7346
|
+
if (spec.length <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_LENGTH", "Ramp flight length must be positive"));
|
|
7347
|
+
if (spec.slope <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_SLOPE", "Ramp flight slope must be positive"));
|
|
7348
|
+
if (spec.thickness <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_THICKNESS", "Ramp flight thickness must be positive"));
|
|
7349
|
+
const rise = spec.length * spec.slope;
|
|
7350
|
+
const silhouette = buildSilhouette(spec.length, rise, spec.thickness);
|
|
7351
|
+
const profileResult = (0, brepjs.polygon)(silhouette);
|
|
7352
|
+
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "RAMP_FLIGHT_PROFILE_FAILED", "Failed to create ramp flight silhouette profile"));
|
|
7353
|
+
const profile = _usingCtx$4.u(profileResult.value);
|
|
7354
|
+
const solidResult = (0, brepjs.extrude)(profile, [
|
|
7355
|
+
0,
|
|
7356
|
+
spec.width,
|
|
7357
|
+
0
|
|
7358
|
+
]);
|
|
7359
|
+
if (!solidResult.ok) return (0, brepjs.err)(fromBrepError(solidResult.error, "RAMP_FLIGHT_EXTRUDE_FAILED", "Failed to extrude ramp flight silhouette"));
|
|
7360
|
+
const solid = solidResult.value;
|
|
7361
|
+
if (!(0, brepjs.isValidSolid)(solid)) {
|
|
7362
|
+
solid[Symbol.dispose]();
|
|
7363
|
+
return (0, brepjs.err)(geometryError("RAMP_FLIGHT_INVALID_SOLID", "Ramp flight solid failed validity check"));
|
|
7364
|
+
}
|
|
7365
|
+
return (0, brepjs.ok)({
|
|
7366
|
+
solid,
|
|
7367
|
+
geometrySimplified: true
|
|
7368
|
+
});
|
|
7369
|
+
} catch (_) {
|
|
7370
|
+
_usingCtx$4.e = _;
|
|
7371
|
+
} finally {
|
|
7372
|
+
_usingCtx$4.d();
|
|
7373
|
+
}
|
|
7374
|
+
}
|
|
7375
|
+
//#endregion
|
|
7317
7376
|
//#region src/elementFns/placedGeometry.ts
|
|
7318
7377
|
function place(solid, frame) {
|
|
7319
7378
|
const result = (0, brepjs.applyMatrix)(solid, placementToMatrix(frame));
|
|
@@ -7332,10 +7391,12 @@ function disposeAll(solids) {
|
|
|
7332
7391
|
* failure the solids already built for this call are disposed before the error is
|
|
7333
7392
|
* returned, so no partial array is leaked.
|
|
7334
7393
|
*
|
|
7335
|
-
* Stairs carry no element solid (`.geometry` is null), so flight
|
|
7336
|
-
* from `spec.flights` and placed per flight. Curtain walls
|
|
7337
|
-
* mullions.
|
|
7338
|
-
*
|
|
7394
|
+
* Stairs and ramps carry no element solid (`.geometry` is null), so flight
|
|
7395
|
+
* solids are built from `spec.flights` and placed per flight. Curtain walls
|
|
7396
|
+
* return placed panels + mullions. Proxies are authored in world coordinates
|
|
7397
|
+
* (no placement frame), so their solid is returned as a fresh identity-placed
|
|
7398
|
+
* copy. Elements with no solid geometry (doors/windows/groups/spatial) return
|
|
7399
|
+
* an empty array.
|
|
7339
7400
|
*/
|
|
7340
7401
|
function placedSolids(el) {
|
|
7341
7402
|
switch (el.category) {
|
|
@@ -7347,6 +7408,7 @@ function placedSolids(el) {
|
|
|
7347
7408
|
case "ROOF":
|
|
7348
7409
|
case "FOOTING":
|
|
7349
7410
|
case "PILE":
|
|
7411
|
+
case "COVERING":
|
|
7350
7412
|
case "RAILING": {
|
|
7351
7413
|
const placed = place(el.geometry, el.spec);
|
|
7352
7414
|
if (!placed.ok) return placed;
|
|
@@ -7355,29 +7417,72 @@ function placedSolids(el) {
|
|
|
7355
7417
|
case "STAIR": {
|
|
7356
7418
|
const out = [];
|
|
7357
7419
|
for (const flight of el.spec.flights) try {
|
|
7358
|
-
var _usingCtx$
|
|
7420
|
+
var _usingCtx$3 = _usingCtx();
|
|
7359
7421
|
const built = stairFlightToSolid(flight);
|
|
7360
7422
|
if (!built.ok) {
|
|
7361
7423
|
disposeAll(out);
|
|
7362
7424
|
return (0, brepjs.err)(built.error);
|
|
7363
7425
|
}
|
|
7364
|
-
const placed = place(_usingCtx$
|
|
7426
|
+
const placed = place(_usingCtx$3.u(built.value.solid), flight);
|
|
7427
|
+
if (!placed.ok) {
|
|
7428
|
+
disposeAll(out);
|
|
7429
|
+
return placed;
|
|
7430
|
+
}
|
|
7431
|
+
out.push(placed.value);
|
|
7432
|
+
} catch (_) {
|
|
7433
|
+
_usingCtx$3.e = _;
|
|
7434
|
+
} finally {
|
|
7435
|
+
_usingCtx$3.d();
|
|
7436
|
+
}
|
|
7437
|
+
return (0, brepjs.ok)(out);
|
|
7438
|
+
}
|
|
7439
|
+
case "RAMP": {
|
|
7440
|
+
const out = [];
|
|
7441
|
+
for (const flight of el.spec.flights) try {
|
|
7442
|
+
var _usingCtx3 = _usingCtx();
|
|
7443
|
+
const built = rampFlightToSolid(flight);
|
|
7444
|
+
if (!built.ok) {
|
|
7445
|
+
disposeAll(out);
|
|
7446
|
+
return (0, brepjs.err)(built.error);
|
|
7447
|
+
}
|
|
7448
|
+
const placed = place(_usingCtx3.u(built.value.solid), flight);
|
|
7365
7449
|
if (!placed.ok) {
|
|
7366
7450
|
disposeAll(out);
|
|
7367
7451
|
return placed;
|
|
7368
7452
|
}
|
|
7369
7453
|
out.push(placed.value);
|
|
7370
7454
|
} catch (_) {
|
|
7371
|
-
|
|
7455
|
+
_usingCtx3.e = _;
|
|
7372
7456
|
} finally {
|
|
7373
|
-
|
|
7457
|
+
_usingCtx3.d();
|
|
7374
7458
|
}
|
|
7375
7459
|
return (0, brepjs.ok)(out);
|
|
7376
7460
|
}
|
|
7461
|
+
case "PROXY": {
|
|
7462
|
+
const placed = place(el.geometry, {
|
|
7463
|
+
origin: [
|
|
7464
|
+
0,
|
|
7465
|
+
0,
|
|
7466
|
+
0
|
|
7467
|
+
],
|
|
7468
|
+
axisX: [
|
|
7469
|
+
1,
|
|
7470
|
+
0,
|
|
7471
|
+
0
|
|
7472
|
+
],
|
|
7473
|
+
axisZ: [
|
|
7474
|
+
0,
|
|
7475
|
+
0,
|
|
7476
|
+
1
|
|
7477
|
+
]
|
|
7478
|
+
});
|
|
7479
|
+
if (!placed.ok) return placed;
|
|
7480
|
+
return (0, brepjs.ok)([placed.value]);
|
|
7481
|
+
}
|
|
7377
7482
|
case "CURTAIN_WALL": {
|
|
7378
7483
|
const out = [];
|
|
7379
7484
|
for (const c of [...el.geometry.panels, ...el.geometry.mullions]) try {
|
|
7380
|
-
var
|
|
7485
|
+
var _usingCtx4 = _usingCtx();
|
|
7381
7486
|
const componentLocal = place(c.solid, {
|
|
7382
7487
|
origin: c.origin,
|
|
7383
7488
|
axisX: [
|
|
@@ -7395,16 +7500,16 @@ function placedSolids(el) {
|
|
|
7395
7500
|
disposeAll(out);
|
|
7396
7501
|
return componentLocal;
|
|
7397
7502
|
}
|
|
7398
|
-
const placed = place(
|
|
7503
|
+
const placed = place(_usingCtx4.u(componentLocal.value), el.spec);
|
|
7399
7504
|
if (!placed.ok) {
|
|
7400
7505
|
disposeAll(out);
|
|
7401
7506
|
return placed;
|
|
7402
7507
|
}
|
|
7403
7508
|
out.push(placed.value);
|
|
7404
7509
|
} catch (_) {
|
|
7405
|
-
|
|
7510
|
+
_usingCtx4.e = _;
|
|
7406
7511
|
} finally {
|
|
7407
|
-
|
|
7512
|
+
_usingCtx4.d();
|
|
7408
7513
|
}
|
|
7409
7514
|
return (0, brepjs.ok)(out);
|
|
7410
7515
|
}
|
|
@@ -9491,65 +9596,6 @@ function writeRelContainedInSpatialStructure(w, guid, ownerHistoryId, relatingSt
|
|
|
9491
9596
|
});
|
|
9492
9597
|
}
|
|
9493
9598
|
//#endregion
|
|
9494
|
-
//#region src/elementFns/rampFns.ts
|
|
9495
|
-
function buildSilhouette(length, rise, thickness) {
|
|
9496
|
-
return [
|
|
9497
|
-
[
|
|
9498
|
-
0,
|
|
9499
|
-
0,
|
|
9500
|
-
-thickness
|
|
9501
|
-
],
|
|
9502
|
-
[
|
|
9503
|
-
length,
|
|
9504
|
-
0,
|
|
9505
|
-
rise - thickness
|
|
9506
|
-
],
|
|
9507
|
-
[
|
|
9508
|
-
length,
|
|
9509
|
-
0,
|
|
9510
|
-
rise
|
|
9511
|
-
],
|
|
9512
|
-
[
|
|
9513
|
-
0,
|
|
9514
|
-
0,
|
|
9515
|
-
0
|
|
9516
|
-
]
|
|
9517
|
-
];
|
|
9518
|
-
}
|
|
9519
|
-
function rampFlightToSolid(spec) {
|
|
9520
|
-
try {
|
|
9521
|
-
var _usingCtx$3 = _usingCtx();
|
|
9522
|
-
if (spec.width <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_WIDTH", "Ramp flight width must be positive"));
|
|
9523
|
-
if (spec.length <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_LENGTH", "Ramp flight length must be positive"));
|
|
9524
|
-
if (spec.slope <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_SLOPE", "Ramp flight slope must be positive"));
|
|
9525
|
-
if (spec.thickness <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_THICKNESS", "Ramp flight thickness must be positive"));
|
|
9526
|
-
const rise = spec.length * spec.slope;
|
|
9527
|
-
const silhouette = buildSilhouette(spec.length, rise, spec.thickness);
|
|
9528
|
-
const profileResult = (0, brepjs.polygon)(silhouette);
|
|
9529
|
-
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "RAMP_FLIGHT_PROFILE_FAILED", "Failed to create ramp flight silhouette profile"));
|
|
9530
|
-
const profile = _usingCtx$3.u(profileResult.value);
|
|
9531
|
-
const solidResult = (0, brepjs.extrude)(profile, [
|
|
9532
|
-
0,
|
|
9533
|
-
spec.width,
|
|
9534
|
-
0
|
|
9535
|
-
]);
|
|
9536
|
-
if (!solidResult.ok) return (0, brepjs.err)(fromBrepError(solidResult.error, "RAMP_FLIGHT_EXTRUDE_FAILED", "Failed to extrude ramp flight silhouette"));
|
|
9537
|
-
const solid = solidResult.value;
|
|
9538
|
-
if (!(0, brepjs.isValidSolid)(solid)) {
|
|
9539
|
-
solid[Symbol.dispose]();
|
|
9540
|
-
return (0, brepjs.err)(geometryError("RAMP_FLIGHT_INVALID_SOLID", "Ramp flight solid failed validity check"));
|
|
9541
|
-
}
|
|
9542
|
-
return (0, brepjs.ok)({
|
|
9543
|
-
solid,
|
|
9544
|
-
geometrySimplified: true
|
|
9545
|
-
});
|
|
9546
|
-
} catch (_) {
|
|
9547
|
-
_usingCtx$3.e = _;
|
|
9548
|
-
} finally {
|
|
9549
|
-
_usingCtx$3.d();
|
|
9550
|
-
}
|
|
9551
|
-
}
|
|
9552
|
-
//#endregion
|
|
9553
9599
|
//#region src/ifc-writer/stairWriter.ts
|
|
9554
9600
|
function writeLocalPlacement(w, origin, axisZ, axisX, parentPlacementId) {
|
|
9555
9601
|
const placement3DId = writeAxis2Placement3D(w, origin.map(toIfcLengthM), axisZ, axisX);
|
package/dist/brepjs-bim.js
CHANGED
|
@@ -7291,6 +7291,65 @@ function stairFlightToSolid(spec) {
|
|
|
7291
7291
|
}
|
|
7292
7292
|
}
|
|
7293
7293
|
//#endregion
|
|
7294
|
+
//#region src/elementFns/rampFns.ts
|
|
7295
|
+
function buildSilhouette(length, rise, thickness) {
|
|
7296
|
+
return [
|
|
7297
|
+
[
|
|
7298
|
+
0,
|
|
7299
|
+
0,
|
|
7300
|
+
-thickness
|
|
7301
|
+
],
|
|
7302
|
+
[
|
|
7303
|
+
length,
|
|
7304
|
+
0,
|
|
7305
|
+
rise - thickness
|
|
7306
|
+
],
|
|
7307
|
+
[
|
|
7308
|
+
length,
|
|
7309
|
+
0,
|
|
7310
|
+
rise
|
|
7311
|
+
],
|
|
7312
|
+
[
|
|
7313
|
+
0,
|
|
7314
|
+
0,
|
|
7315
|
+
0
|
|
7316
|
+
]
|
|
7317
|
+
];
|
|
7318
|
+
}
|
|
7319
|
+
function rampFlightToSolid(spec) {
|
|
7320
|
+
try {
|
|
7321
|
+
var _usingCtx$4 = _usingCtx();
|
|
7322
|
+
if (spec.width <= 0) return err(specError("RAMP_FLIGHT_ZERO_WIDTH", "Ramp flight width must be positive"));
|
|
7323
|
+
if (spec.length <= 0) return err(specError("RAMP_FLIGHT_ZERO_LENGTH", "Ramp flight length must be positive"));
|
|
7324
|
+
if (spec.slope <= 0) return err(specError("RAMP_FLIGHT_ZERO_SLOPE", "Ramp flight slope must be positive"));
|
|
7325
|
+
if (spec.thickness <= 0) return err(specError("RAMP_FLIGHT_ZERO_THICKNESS", "Ramp flight thickness must be positive"));
|
|
7326
|
+
const rise = spec.length * spec.slope;
|
|
7327
|
+
const silhouette = buildSilhouette(spec.length, rise, spec.thickness);
|
|
7328
|
+
const profileResult = polygon(silhouette);
|
|
7329
|
+
if (!profileResult.ok) return err(fromBrepError(profileResult.error, "RAMP_FLIGHT_PROFILE_FAILED", "Failed to create ramp flight silhouette profile"));
|
|
7330
|
+
const profile = _usingCtx$4.u(profileResult.value);
|
|
7331
|
+
const solidResult = extrude(profile, [
|
|
7332
|
+
0,
|
|
7333
|
+
spec.width,
|
|
7334
|
+
0
|
|
7335
|
+
]);
|
|
7336
|
+
if (!solidResult.ok) return err(fromBrepError(solidResult.error, "RAMP_FLIGHT_EXTRUDE_FAILED", "Failed to extrude ramp flight silhouette"));
|
|
7337
|
+
const solid = solidResult.value;
|
|
7338
|
+
if (!isValidSolid(solid)) {
|
|
7339
|
+
solid[Symbol.dispose]();
|
|
7340
|
+
return err(geometryError("RAMP_FLIGHT_INVALID_SOLID", "Ramp flight solid failed validity check"));
|
|
7341
|
+
}
|
|
7342
|
+
return ok({
|
|
7343
|
+
solid,
|
|
7344
|
+
geometrySimplified: true
|
|
7345
|
+
});
|
|
7346
|
+
} catch (_) {
|
|
7347
|
+
_usingCtx$4.e = _;
|
|
7348
|
+
} finally {
|
|
7349
|
+
_usingCtx$4.d();
|
|
7350
|
+
}
|
|
7351
|
+
}
|
|
7352
|
+
//#endregion
|
|
7294
7353
|
//#region src/elementFns/placedGeometry.ts
|
|
7295
7354
|
function place(solid, frame) {
|
|
7296
7355
|
const result = applyMatrix(solid, placementToMatrix(frame));
|
|
@@ -7309,10 +7368,12 @@ function disposeAll(solids) {
|
|
|
7309
7368
|
* failure the solids already built for this call are disposed before the error is
|
|
7310
7369
|
* returned, so no partial array is leaked.
|
|
7311
7370
|
*
|
|
7312
|
-
* Stairs carry no element solid (`.geometry` is null), so flight
|
|
7313
|
-
* from `spec.flights` and placed per flight. Curtain walls
|
|
7314
|
-
* mullions.
|
|
7315
|
-
*
|
|
7371
|
+
* Stairs and ramps carry no element solid (`.geometry` is null), so flight
|
|
7372
|
+
* solids are built from `spec.flights` and placed per flight. Curtain walls
|
|
7373
|
+
* return placed panels + mullions. Proxies are authored in world coordinates
|
|
7374
|
+
* (no placement frame), so their solid is returned as a fresh identity-placed
|
|
7375
|
+
* copy. Elements with no solid geometry (doors/windows/groups/spatial) return
|
|
7376
|
+
* an empty array.
|
|
7316
7377
|
*/
|
|
7317
7378
|
function placedSolids(el) {
|
|
7318
7379
|
switch (el.category) {
|
|
@@ -7324,6 +7385,7 @@ function placedSolids(el) {
|
|
|
7324
7385
|
case "ROOF":
|
|
7325
7386
|
case "FOOTING":
|
|
7326
7387
|
case "PILE":
|
|
7388
|
+
case "COVERING":
|
|
7327
7389
|
case "RAILING": {
|
|
7328
7390
|
const placed = place(el.geometry, el.spec);
|
|
7329
7391
|
if (!placed.ok) return placed;
|
|
@@ -7332,29 +7394,72 @@ function placedSolids(el) {
|
|
|
7332
7394
|
case "STAIR": {
|
|
7333
7395
|
const out = [];
|
|
7334
7396
|
for (const flight of el.spec.flights) try {
|
|
7335
|
-
var _usingCtx$
|
|
7397
|
+
var _usingCtx$3 = _usingCtx();
|
|
7336
7398
|
const built = stairFlightToSolid(flight);
|
|
7337
7399
|
if (!built.ok) {
|
|
7338
7400
|
disposeAll(out);
|
|
7339
7401
|
return err(built.error);
|
|
7340
7402
|
}
|
|
7341
|
-
const placed = place(_usingCtx$
|
|
7403
|
+
const placed = place(_usingCtx$3.u(built.value.solid), flight);
|
|
7404
|
+
if (!placed.ok) {
|
|
7405
|
+
disposeAll(out);
|
|
7406
|
+
return placed;
|
|
7407
|
+
}
|
|
7408
|
+
out.push(placed.value);
|
|
7409
|
+
} catch (_) {
|
|
7410
|
+
_usingCtx$3.e = _;
|
|
7411
|
+
} finally {
|
|
7412
|
+
_usingCtx$3.d();
|
|
7413
|
+
}
|
|
7414
|
+
return ok(out);
|
|
7415
|
+
}
|
|
7416
|
+
case "RAMP": {
|
|
7417
|
+
const out = [];
|
|
7418
|
+
for (const flight of el.spec.flights) try {
|
|
7419
|
+
var _usingCtx3 = _usingCtx();
|
|
7420
|
+
const built = rampFlightToSolid(flight);
|
|
7421
|
+
if (!built.ok) {
|
|
7422
|
+
disposeAll(out);
|
|
7423
|
+
return err(built.error);
|
|
7424
|
+
}
|
|
7425
|
+
const placed = place(_usingCtx3.u(built.value.solid), flight);
|
|
7342
7426
|
if (!placed.ok) {
|
|
7343
7427
|
disposeAll(out);
|
|
7344
7428
|
return placed;
|
|
7345
7429
|
}
|
|
7346
7430
|
out.push(placed.value);
|
|
7347
7431
|
} catch (_) {
|
|
7348
|
-
|
|
7432
|
+
_usingCtx3.e = _;
|
|
7349
7433
|
} finally {
|
|
7350
|
-
|
|
7434
|
+
_usingCtx3.d();
|
|
7351
7435
|
}
|
|
7352
7436
|
return ok(out);
|
|
7353
7437
|
}
|
|
7438
|
+
case "PROXY": {
|
|
7439
|
+
const placed = place(el.geometry, {
|
|
7440
|
+
origin: [
|
|
7441
|
+
0,
|
|
7442
|
+
0,
|
|
7443
|
+
0
|
|
7444
|
+
],
|
|
7445
|
+
axisX: [
|
|
7446
|
+
1,
|
|
7447
|
+
0,
|
|
7448
|
+
0
|
|
7449
|
+
],
|
|
7450
|
+
axisZ: [
|
|
7451
|
+
0,
|
|
7452
|
+
0,
|
|
7453
|
+
1
|
|
7454
|
+
]
|
|
7455
|
+
});
|
|
7456
|
+
if (!placed.ok) return placed;
|
|
7457
|
+
return ok([placed.value]);
|
|
7458
|
+
}
|
|
7354
7459
|
case "CURTAIN_WALL": {
|
|
7355
7460
|
const out = [];
|
|
7356
7461
|
for (const c of [...el.geometry.panels, ...el.geometry.mullions]) try {
|
|
7357
|
-
var
|
|
7462
|
+
var _usingCtx4 = _usingCtx();
|
|
7358
7463
|
const componentLocal = place(c.solid, {
|
|
7359
7464
|
origin: c.origin,
|
|
7360
7465
|
axisX: [
|
|
@@ -7372,16 +7477,16 @@ function placedSolids(el) {
|
|
|
7372
7477
|
disposeAll(out);
|
|
7373
7478
|
return componentLocal;
|
|
7374
7479
|
}
|
|
7375
|
-
const placed = place(
|
|
7480
|
+
const placed = place(_usingCtx4.u(componentLocal.value), el.spec);
|
|
7376
7481
|
if (!placed.ok) {
|
|
7377
7482
|
disposeAll(out);
|
|
7378
7483
|
return placed;
|
|
7379
7484
|
}
|
|
7380
7485
|
out.push(placed.value);
|
|
7381
7486
|
} catch (_) {
|
|
7382
|
-
|
|
7487
|
+
_usingCtx4.e = _;
|
|
7383
7488
|
} finally {
|
|
7384
|
-
|
|
7489
|
+
_usingCtx4.d();
|
|
7385
7490
|
}
|
|
7386
7491
|
return ok(out);
|
|
7387
7492
|
}
|
|
@@ -9468,65 +9573,6 @@ function writeRelContainedInSpatialStructure(w, guid, ownerHistoryId, relatingSt
|
|
|
9468
9573
|
});
|
|
9469
9574
|
}
|
|
9470
9575
|
//#endregion
|
|
9471
|
-
//#region src/elementFns/rampFns.ts
|
|
9472
|
-
function buildSilhouette(length, rise, thickness) {
|
|
9473
|
-
return [
|
|
9474
|
-
[
|
|
9475
|
-
0,
|
|
9476
|
-
0,
|
|
9477
|
-
-thickness
|
|
9478
|
-
],
|
|
9479
|
-
[
|
|
9480
|
-
length,
|
|
9481
|
-
0,
|
|
9482
|
-
rise - thickness
|
|
9483
|
-
],
|
|
9484
|
-
[
|
|
9485
|
-
length,
|
|
9486
|
-
0,
|
|
9487
|
-
rise
|
|
9488
|
-
],
|
|
9489
|
-
[
|
|
9490
|
-
0,
|
|
9491
|
-
0,
|
|
9492
|
-
0
|
|
9493
|
-
]
|
|
9494
|
-
];
|
|
9495
|
-
}
|
|
9496
|
-
function rampFlightToSolid(spec) {
|
|
9497
|
-
try {
|
|
9498
|
-
var _usingCtx$3 = _usingCtx();
|
|
9499
|
-
if (spec.width <= 0) return err(specError("RAMP_FLIGHT_ZERO_WIDTH", "Ramp flight width must be positive"));
|
|
9500
|
-
if (spec.length <= 0) return err(specError("RAMP_FLIGHT_ZERO_LENGTH", "Ramp flight length must be positive"));
|
|
9501
|
-
if (spec.slope <= 0) return err(specError("RAMP_FLIGHT_ZERO_SLOPE", "Ramp flight slope must be positive"));
|
|
9502
|
-
if (spec.thickness <= 0) return err(specError("RAMP_FLIGHT_ZERO_THICKNESS", "Ramp flight thickness must be positive"));
|
|
9503
|
-
const rise = spec.length * spec.slope;
|
|
9504
|
-
const silhouette = buildSilhouette(spec.length, rise, spec.thickness);
|
|
9505
|
-
const profileResult = polygon(silhouette);
|
|
9506
|
-
if (!profileResult.ok) return err(fromBrepError(profileResult.error, "RAMP_FLIGHT_PROFILE_FAILED", "Failed to create ramp flight silhouette profile"));
|
|
9507
|
-
const profile = _usingCtx$3.u(profileResult.value);
|
|
9508
|
-
const solidResult = extrude(profile, [
|
|
9509
|
-
0,
|
|
9510
|
-
spec.width,
|
|
9511
|
-
0
|
|
9512
|
-
]);
|
|
9513
|
-
if (!solidResult.ok) return err(fromBrepError(solidResult.error, "RAMP_FLIGHT_EXTRUDE_FAILED", "Failed to extrude ramp flight silhouette"));
|
|
9514
|
-
const solid = solidResult.value;
|
|
9515
|
-
if (!isValidSolid(solid)) {
|
|
9516
|
-
solid[Symbol.dispose]();
|
|
9517
|
-
return err(geometryError("RAMP_FLIGHT_INVALID_SOLID", "Ramp flight solid failed validity check"));
|
|
9518
|
-
}
|
|
9519
|
-
return ok({
|
|
9520
|
-
solid,
|
|
9521
|
-
geometrySimplified: true
|
|
9522
|
-
});
|
|
9523
|
-
} catch (_) {
|
|
9524
|
-
_usingCtx$3.e = _;
|
|
9525
|
-
} finally {
|
|
9526
|
-
_usingCtx$3.d();
|
|
9527
|
-
}
|
|
9528
|
-
}
|
|
9529
|
-
//#endregion
|
|
9530
9576
|
//#region src/ifc-writer/stairWriter.ts
|
|
9531
9577
|
function writeLocalPlacement(w, origin, axisZ, axisX, parentPlacementId) {
|
|
9532
9578
|
const placement3DId = writeAxis2Placement3D(w, origin.map(toIfcLengthM), axisZ, axisX);
|
|
@@ -10,9 +10,11 @@ import { BimError } from '../errors/bimError.js';
|
|
|
10
10
|
* failure the solids already built for this call are disposed before the error is
|
|
11
11
|
* returned, so no partial array is leaked.
|
|
12
12
|
*
|
|
13
|
-
* Stairs carry no element solid (`.geometry` is null), so flight
|
|
14
|
-
* from `spec.flights` and placed per flight. Curtain walls
|
|
15
|
-
* mullions.
|
|
16
|
-
*
|
|
13
|
+
* Stairs and ramps carry no element solid (`.geometry` is null), so flight
|
|
14
|
+
* solids are built from `spec.flights` and placed per flight. Curtain walls
|
|
15
|
+
* return placed panels + mullions. Proxies are authored in world coordinates
|
|
16
|
+
* (no placement frame), so their solid is returned as a fresh identity-placed
|
|
17
|
+
* copy. Elements with no solid geometry (doors/windows/groups/spatial) return
|
|
18
|
+
* an empty array.
|
|
17
19
|
*/
|
|
18
20
|
export declare function placedSolids(el: AnyBimElement): Result<readonly ValidSolid[], BimError>;
|