brepjs-bim 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -17
- package/dist/brepjs-bim.cjs +1160 -288
- package/dist/brepjs-bim.js +1160 -289
- package/dist/elementFns/placedGeometry.d.ts +4 -4
- package/dist/ifc-writer/headerWriter.d.ts +7 -0
- package/dist/index.d.ts +2 -1
- package/dist/specs/spatialSpec.d.ts +24 -0
- package/dist/validation/gherkinChecks.d.ts +18 -0
- package/dist/validation/qtoDefinitions.generated.d.ts +5 -0
- package/package.json +1 -1
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,10 @@ 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. Elements with no solid geometry
|
|
7338
|
-
* return an empty array.
|
|
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. Elements with no solid geometry
|
|
7397
|
+
* (doors/windows/groups/spatial) return an empty array.
|
|
7339
7398
|
*/
|
|
7340
7399
|
function placedSolids(el) {
|
|
7341
7400
|
switch (el.category) {
|
|
@@ -7347,6 +7406,7 @@ function placedSolids(el) {
|
|
|
7347
7406
|
case "ROOF":
|
|
7348
7407
|
case "FOOTING":
|
|
7349
7408
|
case "PILE":
|
|
7409
|
+
case "COVERING":
|
|
7350
7410
|
case "RAILING": {
|
|
7351
7411
|
const placed = place(el.geometry, el.spec);
|
|
7352
7412
|
if (!placed.ok) return placed;
|
|
@@ -7355,29 +7415,51 @@ function placedSolids(el) {
|
|
|
7355
7415
|
case "STAIR": {
|
|
7356
7416
|
const out = [];
|
|
7357
7417
|
for (const flight of el.spec.flights) try {
|
|
7358
|
-
var _usingCtx$
|
|
7418
|
+
var _usingCtx$3 = _usingCtx();
|
|
7359
7419
|
const built = stairFlightToSolid(flight);
|
|
7360
7420
|
if (!built.ok) {
|
|
7361
7421
|
disposeAll(out);
|
|
7362
7422
|
return (0, brepjs.err)(built.error);
|
|
7363
7423
|
}
|
|
7364
|
-
const placed = place(_usingCtx$
|
|
7424
|
+
const placed = place(_usingCtx$3.u(built.value.solid), flight);
|
|
7425
|
+
if (!placed.ok) {
|
|
7426
|
+
disposeAll(out);
|
|
7427
|
+
return placed;
|
|
7428
|
+
}
|
|
7429
|
+
out.push(placed.value);
|
|
7430
|
+
} catch (_) {
|
|
7431
|
+
_usingCtx$3.e = _;
|
|
7432
|
+
} finally {
|
|
7433
|
+
_usingCtx$3.d();
|
|
7434
|
+
}
|
|
7435
|
+
return (0, brepjs.ok)(out);
|
|
7436
|
+
}
|
|
7437
|
+
case "RAMP": {
|
|
7438
|
+
const out = [];
|
|
7439
|
+
for (const flight of el.spec.flights) try {
|
|
7440
|
+
var _usingCtx3 = _usingCtx();
|
|
7441
|
+
const built = rampFlightToSolid(flight);
|
|
7442
|
+
if (!built.ok) {
|
|
7443
|
+
disposeAll(out);
|
|
7444
|
+
return (0, brepjs.err)(built.error);
|
|
7445
|
+
}
|
|
7446
|
+
const placed = place(_usingCtx3.u(built.value.solid), flight);
|
|
7365
7447
|
if (!placed.ok) {
|
|
7366
7448
|
disposeAll(out);
|
|
7367
7449
|
return placed;
|
|
7368
7450
|
}
|
|
7369
7451
|
out.push(placed.value);
|
|
7370
7452
|
} catch (_) {
|
|
7371
|
-
|
|
7453
|
+
_usingCtx3.e = _;
|
|
7372
7454
|
} finally {
|
|
7373
|
-
|
|
7455
|
+
_usingCtx3.d();
|
|
7374
7456
|
}
|
|
7375
7457
|
return (0, brepjs.ok)(out);
|
|
7376
7458
|
}
|
|
7377
7459
|
case "CURTAIN_WALL": {
|
|
7378
7460
|
const out = [];
|
|
7379
7461
|
for (const c of [...el.geometry.panels, ...el.geometry.mullions]) try {
|
|
7380
|
-
var
|
|
7462
|
+
var _usingCtx4 = _usingCtx();
|
|
7381
7463
|
const componentLocal = place(c.solid, {
|
|
7382
7464
|
origin: c.origin,
|
|
7383
7465
|
axisX: [
|
|
@@ -7395,16 +7477,16 @@ function placedSolids(el) {
|
|
|
7395
7477
|
disposeAll(out);
|
|
7396
7478
|
return componentLocal;
|
|
7397
7479
|
}
|
|
7398
|
-
const placed = place(
|
|
7480
|
+
const placed = place(_usingCtx4.u(componentLocal.value), el.spec);
|
|
7399
7481
|
if (!placed.ok) {
|
|
7400
7482
|
disposeAll(out);
|
|
7401
7483
|
return placed;
|
|
7402
7484
|
}
|
|
7403
7485
|
out.push(placed.value);
|
|
7404
7486
|
} catch (_) {
|
|
7405
|
-
|
|
7487
|
+
_usingCtx4.e = _;
|
|
7406
7488
|
} finally {
|
|
7407
|
-
|
|
7489
|
+
_usingCtx4.d();
|
|
7408
7490
|
}
|
|
7409
7491
|
return (0, brepjs.ok)(out);
|
|
7410
7492
|
}
|
|
@@ -7804,9 +7886,42 @@ function writeHeader(w, meta) {
|
|
|
7804
7886
|
ownerHistoryId,
|
|
7805
7887
|
geomContextId,
|
|
7806
7888
|
geomSubContextId,
|
|
7807
|
-
unitAssignmentId
|
|
7889
|
+
unitAssignmentId,
|
|
7890
|
+
lengthUnitId
|
|
7808
7891
|
};
|
|
7809
7892
|
}
|
|
7893
|
+
/**
|
|
7894
|
+
* Writes IfcProjectedCRS + IfcMapConversion georeferencing the model context
|
|
7895
|
+
* (GRF003). Coordinates are metres; rotation defaults to identity.
|
|
7896
|
+
*/
|
|
7897
|
+
function writeMapConversion(w, crs, geomContextId, lengthUnitId) {
|
|
7898
|
+
const crsId = w.nextId();
|
|
7899
|
+
w.writeLine({
|
|
7900
|
+
expressID: crsId,
|
|
7901
|
+
type: web_ifc.IFCPROJECTEDCRS,
|
|
7902
|
+
Name: w.mkType(web_ifc.IFCLABEL, crs.name),
|
|
7903
|
+
Description: crs.description !== void 0 ? w.mkType(web_ifc.IFCTEXT, crs.description) : null,
|
|
7904
|
+
GeodeticDatum: crs.geodeticDatum !== void 0 ? w.mkType(web_ifc.IFCIDENTIFIER, crs.geodeticDatum) : null,
|
|
7905
|
+
VerticalDatum: crs.verticalDatum !== void 0 ? w.mkType(web_ifc.IFCIDENTIFIER, crs.verticalDatum) : null,
|
|
7906
|
+
MapProjection: crs.mapProjection !== void 0 ? w.mkType(web_ifc.IFCIDENTIFIER, crs.mapProjection) : null,
|
|
7907
|
+
MapZone: crs.mapZone !== void 0 ? w.mkType(web_ifc.IFCIDENTIFIER, crs.mapZone) : null,
|
|
7908
|
+
MapUnit: w.ref(lengthUnitId)
|
|
7909
|
+
});
|
|
7910
|
+
const conversionId = w.nextId();
|
|
7911
|
+
w.writeLine({
|
|
7912
|
+
expressID: conversionId,
|
|
7913
|
+
type: web_ifc.IFCMAPCONVERSION,
|
|
7914
|
+
SourceCRS: w.ref(geomContextId),
|
|
7915
|
+
TargetCRS: w.ref(crsId),
|
|
7916
|
+
Eastings: w.mkType(web_ifc.IFCLENGTHMEASURE, crs.eastings ?? 0),
|
|
7917
|
+
Northings: w.mkType(web_ifc.IFCLENGTHMEASURE, crs.northings ?? 0),
|
|
7918
|
+
OrthogonalHeight: w.mkType(web_ifc.IFCLENGTHMEASURE, crs.orthogonalHeight ?? 0),
|
|
7919
|
+
XAxisAbscissa: crs.xAxisAbscissa !== void 0 ? w.mkType(web_ifc.IFCREAL, crs.xAxisAbscissa) : null,
|
|
7920
|
+
XAxisOrdinate: crs.xAxisOrdinate !== void 0 ? w.mkType(web_ifc.IFCREAL, crs.xAxisOrdinate) : null,
|
|
7921
|
+
Scale: crs.scale !== void 0 ? w.mkType(web_ifc.IFCREAL, crs.scale) : null
|
|
7922
|
+
});
|
|
7923
|
+
return crsId;
|
|
7924
|
+
}
|
|
7810
7925
|
function writeAxis2Placement3D(w, origin = [
|
|
7811
7926
|
0,
|
|
7812
7927
|
0,
|
|
@@ -9458,65 +9573,6 @@ function writeRelContainedInSpatialStructure(w, guid, ownerHistoryId, relatingSt
|
|
|
9458
9573
|
});
|
|
9459
9574
|
}
|
|
9460
9575
|
//#endregion
|
|
9461
|
-
//#region src/elementFns/rampFns.ts
|
|
9462
|
-
function buildSilhouette(length, rise, thickness) {
|
|
9463
|
-
return [
|
|
9464
|
-
[
|
|
9465
|
-
0,
|
|
9466
|
-
0,
|
|
9467
|
-
-thickness
|
|
9468
|
-
],
|
|
9469
|
-
[
|
|
9470
|
-
length,
|
|
9471
|
-
0,
|
|
9472
|
-
rise - thickness
|
|
9473
|
-
],
|
|
9474
|
-
[
|
|
9475
|
-
length,
|
|
9476
|
-
0,
|
|
9477
|
-
rise
|
|
9478
|
-
],
|
|
9479
|
-
[
|
|
9480
|
-
0,
|
|
9481
|
-
0,
|
|
9482
|
-
0
|
|
9483
|
-
]
|
|
9484
|
-
];
|
|
9485
|
-
}
|
|
9486
|
-
function rampFlightToSolid(spec) {
|
|
9487
|
-
try {
|
|
9488
|
-
var _usingCtx$3 = _usingCtx();
|
|
9489
|
-
if (spec.width <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_WIDTH", "Ramp flight width must be positive"));
|
|
9490
|
-
if (spec.length <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_LENGTH", "Ramp flight length must be positive"));
|
|
9491
|
-
if (spec.slope <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_SLOPE", "Ramp flight slope must be positive"));
|
|
9492
|
-
if (spec.thickness <= 0) return (0, brepjs.err)(specError("RAMP_FLIGHT_ZERO_THICKNESS", "Ramp flight thickness must be positive"));
|
|
9493
|
-
const rise = spec.length * spec.slope;
|
|
9494
|
-
const silhouette = buildSilhouette(spec.length, rise, spec.thickness);
|
|
9495
|
-
const profileResult = (0, brepjs.polygon)(silhouette);
|
|
9496
|
-
if (!profileResult.ok) return (0, brepjs.err)(fromBrepError(profileResult.error, "RAMP_FLIGHT_PROFILE_FAILED", "Failed to create ramp flight silhouette profile"));
|
|
9497
|
-
const profile = _usingCtx$3.u(profileResult.value);
|
|
9498
|
-
const solidResult = (0, brepjs.extrude)(profile, [
|
|
9499
|
-
0,
|
|
9500
|
-
spec.width,
|
|
9501
|
-
0
|
|
9502
|
-
]);
|
|
9503
|
-
if (!solidResult.ok) return (0, brepjs.err)(fromBrepError(solidResult.error, "RAMP_FLIGHT_EXTRUDE_FAILED", "Failed to extrude ramp flight silhouette"));
|
|
9504
|
-
const solid = solidResult.value;
|
|
9505
|
-
if (!(0, brepjs.isValidSolid)(solid)) {
|
|
9506
|
-
solid[Symbol.dispose]();
|
|
9507
|
-
return (0, brepjs.err)(geometryError("RAMP_FLIGHT_INVALID_SOLID", "Ramp flight solid failed validity check"));
|
|
9508
|
-
}
|
|
9509
|
-
return (0, brepjs.ok)({
|
|
9510
|
-
solid,
|
|
9511
|
-
geometrySimplified: true
|
|
9512
|
-
});
|
|
9513
|
-
} catch (_) {
|
|
9514
|
-
_usingCtx$3.e = _;
|
|
9515
|
-
} finally {
|
|
9516
|
-
_usingCtx$3.d();
|
|
9517
|
-
}
|
|
9518
|
-
}
|
|
9519
|
-
//#endregion
|
|
9520
9576
|
//#region src/ifc-writer/stairWriter.ts
|
|
9521
9577
|
function writeLocalPlacement(w, origin, axisZ, axisX, parentPlacementId) {
|
|
9522
9578
|
const placement3DId = writeAxis2Placement3D(w, origin.map(toIfcLengthM), axisZ, axisX);
|
|
@@ -9572,12 +9628,56 @@ function writeStairFlightEntity(w, guid, name, flight, ownerHistoryId, localPlac
|
|
|
9572
9628
|
ObjectPlacement: w.ref(localPlacementId),
|
|
9573
9629
|
Representation: w.ref(productDefinitionShapeId),
|
|
9574
9630
|
Tag: null,
|
|
9575
|
-
NumberOfRisers:
|
|
9576
|
-
NumberOfTreads:
|
|
9577
|
-
RiserHeight:
|
|
9578
|
-
TreadLength:
|
|
9631
|
+
NumberOfRisers: null,
|
|
9632
|
+
NumberOfTreads: null,
|
|
9633
|
+
RiserHeight: null,
|
|
9634
|
+
TreadLength: null,
|
|
9579
9635
|
PredefinedType: null
|
|
9580
9636
|
});
|
|
9637
|
+
writeStairFlightCommonPset(w, ownerHistoryId, id, flight);
|
|
9638
|
+
return id;
|
|
9639
|
+
}
|
|
9640
|
+
/** Pset_StairFlightCommon: the standard home for the flight geometry data the
|
|
9641
|
+
* deprecated IfcStairFlight attributes used to carry. Note the standard's
|
|
9642
|
+
* singular `NumberOfRiser`. */
|
|
9643
|
+
function writeStairFlightCommonPset(w, ownerHistoryId, flightExpressId, flight) {
|
|
9644
|
+
const props = [
|
|
9645
|
+
writeSingleValue(w, "NumberOfRiser", w.mkType(web_ifc.IFCCOUNTMEASURE, flight.numberOfRisers)),
|
|
9646
|
+
writeSingleValue(w, "NumberOfTreads", w.mkType(web_ifc.IFCCOUNTMEASURE, flight.numberOfRisers - 1)),
|
|
9647
|
+
writeSingleValue(w, "RiserHeight", w.mkType(web_ifc.IFCPOSITIVELENGTHMEASURE, toIfcLengthM(flight.riserHeight))),
|
|
9648
|
+
writeSingleValue(w, "TreadLength", w.mkType(web_ifc.IFCPOSITIVELENGTHMEASURE, toIfcLengthM(flight.treadLength)))
|
|
9649
|
+
];
|
|
9650
|
+
const psetId = w.nextId();
|
|
9651
|
+
w.writeLine({
|
|
9652
|
+
expressID: psetId,
|
|
9653
|
+
type: web_ifc.IFCPROPERTYSET,
|
|
9654
|
+
GlobalId: w.mkType(web_ifc.IFCGLOBALLYUNIQUEID, w.guidFor(psetId)),
|
|
9655
|
+
OwnerHistory: w.ref(ownerHistoryId),
|
|
9656
|
+
Name: w.mkType(web_ifc.IFCLABEL, "Pset_StairFlightCommon"),
|
|
9657
|
+
Description: null,
|
|
9658
|
+
HasProperties: props.map((id) => w.ref(id))
|
|
9659
|
+
});
|
|
9660
|
+
w.writeLine({
|
|
9661
|
+
expressID: w.nextId(),
|
|
9662
|
+
type: web_ifc.IFCRELDEFINESBYPROPERTIES,
|
|
9663
|
+
GlobalId: w.mkType(web_ifc.IFCGLOBALLYUNIQUEID, w.guidFor(psetId + 1e5)),
|
|
9664
|
+
OwnerHistory: w.ref(ownerHistoryId),
|
|
9665
|
+
Name: null,
|
|
9666
|
+
Description: null,
|
|
9667
|
+
RelatedObjects: [w.ref(flightExpressId)],
|
|
9668
|
+
RelatingPropertyDefinition: w.ref(psetId)
|
|
9669
|
+
});
|
|
9670
|
+
}
|
|
9671
|
+
function writeSingleValue(w, name, value) {
|
|
9672
|
+
const id = w.nextId();
|
|
9673
|
+
w.writeLine({
|
|
9674
|
+
expressID: id,
|
|
9675
|
+
type: web_ifc.IFCPROPERTYSINGLEVALUE,
|
|
9676
|
+
Name: w.mkType(web_ifc.IFCIDENTIFIER, name),
|
|
9677
|
+
Description: null,
|
|
9678
|
+
NominalValue: value,
|
|
9679
|
+
Unit: null
|
|
9680
|
+
});
|
|
9581
9681
|
return id;
|
|
9582
9682
|
}
|
|
9583
9683
|
function writeStairEntity(w, guid, name, _predefinedType, ownerHistoryId, localPlacementId) {
|
|
@@ -11088,12 +11188,11 @@ function writeRoofBaseQuantities(w, ownerHistoryId, roofExpressId, spec) {
|
|
|
11088
11188
|
const widthM = toIfcLengthM(spec.width);
|
|
11089
11189
|
const thicknessM = toIfcLengthM(spec.thickness);
|
|
11090
11190
|
const grossAreaM2 = lengthM * widthM;
|
|
11091
|
-
|
|
11191
|
+
grossAreaM2 * thicknessM;
|
|
11092
11192
|
writeRelDefinesByProperties(w, ownerHistoryId, roofExpressId, writeElementQuantity(w, ownerHistoryId, "Qto_RoofBaseQuantities", [
|
|
11093
11193
|
writeQtyArea(w, "GrossArea", grossAreaM2),
|
|
11094
11194
|
writeQtyArea(w, "NetArea", grossAreaM2),
|
|
11095
|
-
|
|
11096
|
-
writeQtyVolume(w, "NetVolume", grossVolumeM3)
|
|
11195
|
+
writeQtyArea(w, "ProjectedArea", grossAreaM2)
|
|
11097
11196
|
]));
|
|
11098
11197
|
}
|
|
11099
11198
|
function writeCurtainWallCommonPset(w, ownerHistoryId, curtainWallExpressId, spec) {
|
|
@@ -11120,7 +11219,7 @@ function writeFootingBaseQuantities(w, ownerHistoryId, footingExpressId, spec) {
|
|
|
11120
11219
|
writeRelDefinesByProperties(w, ownerHistoryId, footingExpressId, writeElementQuantity(w, ownerHistoryId, "Qto_FootingBaseQuantities", [
|
|
11121
11220
|
writeQtyLength(w, "Length", lengthM),
|
|
11122
11221
|
writeQtyLength(w, "Width", widthM),
|
|
11123
|
-
writeQtyLength(w, "
|
|
11222
|
+
writeQtyLength(w, "Height", depthM),
|
|
11124
11223
|
writeQtyVolume(w, "GrossVolume", grossVolumeM3),
|
|
11125
11224
|
writeQtyVolume(w, "NetVolume", grossVolumeM3)
|
|
11126
11225
|
]));
|
|
@@ -12068,71 +12167,984 @@ async function checkRoundTrip(bytes) {
|
|
|
12068
12167
|
};
|
|
12069
12168
|
}
|
|
12070
12169
|
//#endregion
|
|
12071
|
-
//#region src/
|
|
12072
|
-
|
|
12073
|
-
|
|
12074
|
-
|
|
12075
|
-
|
|
12076
|
-
|
|
12077
|
-
|
|
12078
|
-
|
|
12079
|
-
|
|
12080
|
-
|
|
12081
|
-
|
|
12082
|
-
|
|
12083
|
-
|
|
12084
|
-
|
|
12085
|
-
|
|
12086
|
-
|
|
12087
|
-
|
|
12088
|
-
|
|
12089
|
-
|
|
12090
|
-
|
|
12091
|
-
|
|
12092
|
-
|
|
12093
|
-
|
|
12094
|
-
|
|
12095
|
-
|
|
12096
|
-
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
const railings = model.getRailings();
|
|
12100
|
-
const coverings = model.getCoverings();
|
|
12101
|
-
const assemblies = model.getElementAssemblies();
|
|
12102
|
-
const zones = model.getZones();
|
|
12103
|
-
const systems = model.getSystems();
|
|
12104
|
-
const { ownerHistoryId, geomContextId, geomSubContextId, unitAssignmentId } = writeHeader(w, meta);
|
|
12105
|
-
const densityByElement = buildDensityMap(relationships);
|
|
12106
|
-
const idMap = /* @__PURE__ */ new Map();
|
|
12107
|
-
const placementMap = /* @__PURE__ */ new Map();
|
|
12108
|
-
const projectExpressId = writeProject$1(w, project.guid, project.spec.name, ownerHistoryId, unitAssignmentId, geomContextId);
|
|
12109
|
-
idMap.set(project.localId, projectExpressId);
|
|
12110
|
-
for (const el of elements) {
|
|
12111
|
-
if (el.category !== "SITE") continue;
|
|
12112
|
-
const { entityId, placementId } = writeSite(w, el.guid, el.spec.name, ownerHistoryId);
|
|
12113
|
-
idMap.set(el.localId, entityId);
|
|
12114
|
-
placementMap.set(el.localId, placementId);
|
|
12115
|
-
}
|
|
12116
|
-
for (const el of elements) {
|
|
12117
|
-
if (el.category !== "BUILDING") continue;
|
|
12118
|
-
const parentSiteId = findParentOf(el.localId, relationships);
|
|
12119
|
-
const parentPlacementId = parentSiteId !== null ? placementMap.get(parentSiteId) ?? null : null;
|
|
12120
|
-
const { entityId, placementId } = writeBuilding(w, el.guid, el.spec.name, ownerHistoryId, parentPlacementId);
|
|
12121
|
-
idMap.set(el.localId, entityId);
|
|
12122
|
-
placementMap.set(el.localId, placementId);
|
|
12123
|
-
}
|
|
12124
|
-
for (const el of elements) {
|
|
12125
|
-
if (el.category !== "STOREY") continue;
|
|
12126
|
-
const parentBuildingId = findParentOf(el.localId, relationships);
|
|
12127
|
-
const parentPlacementId = parentBuildingId !== null ? placementMap.get(parentBuildingId) ?? null : null;
|
|
12128
|
-
const { entityId, placementId } = writeStorey(w, el.guid, el.spec.name, el.spec.elevation, ownerHistoryId, parentPlacementId);
|
|
12129
|
-
idMap.set(el.localId, entityId);
|
|
12130
|
-
placementMap.set(el.localId, placementId);
|
|
12170
|
+
//#region src/import/spfReader.ts
|
|
12171
|
+
var SUPPORTED_SCHEMAS = [
|
|
12172
|
+
"IFC2X3",
|
|
12173
|
+
"IFC4",
|
|
12174
|
+
"IFC4X3"
|
|
12175
|
+
];
|
|
12176
|
+
/**
|
|
12177
|
+
* Foundation layer of the IFC reader: owns the web-ifc WASM model handle and
|
|
12178
|
+
* exposes typed line access, GUID↔expressId lookup, world-transform composition,
|
|
12179
|
+
* geometry-engine access and STEP string decoding.
|
|
12180
|
+
*
|
|
12181
|
+
* Lifecycle: created via the static async {@link SpfReader.create}; the caller
|
|
12182
|
+
* MUST call {@link SpfReader.close} (it always issues `CloseModel`, preventing
|
|
12183
|
+
* WASM handle leaks). The handle is `using`-friendly via `Symbol.dispose`.
|
|
12184
|
+
*/
|
|
12185
|
+
function deleteVector(vec) {
|
|
12186
|
+
vec.delete?.();
|
|
12187
|
+
}
|
|
12188
|
+
var SpfReader = class SpfReader {
|
|
12189
|
+
schema;
|
|
12190
|
+
modelId;
|
|
12191
|
+
#api;
|
|
12192
|
+
#closed = false;
|
|
12193
|
+
#linesByType = /* @__PURE__ */ new Map();
|
|
12194
|
+
constructor(api, modelId, schema) {
|
|
12195
|
+
this.#api = api;
|
|
12196
|
+
this.modelId = modelId;
|
|
12197
|
+
this.schema = schema;
|
|
12131
12198
|
}
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
|
|
12135
|
-
|
|
12199
|
+
static async create(bytes, settings = {}) {
|
|
12200
|
+
let api;
|
|
12201
|
+
try {
|
|
12202
|
+
api = new web_ifc.IfcAPI();
|
|
12203
|
+
await initIfcApi(api);
|
|
12204
|
+
} catch (e) {
|
|
12205
|
+
return (0, brepjs.err)(importError("OPEN_MODEL_FAILED", "Failed to initialize web-ifc", e));
|
|
12206
|
+
}
|
|
12207
|
+
let modelId;
|
|
12208
|
+
try {
|
|
12209
|
+
modelId = api.OpenModel(bytes, { COORDINATE_TO_ORIGIN: settings.coordinateToOrigin ?? false });
|
|
12210
|
+
} catch (e) {
|
|
12211
|
+
return (0, brepjs.err)(importError("OPEN_MODEL_FAILED", "web-ifc OpenModel threw", e));
|
|
12212
|
+
}
|
|
12213
|
+
if (modelId < 0 || !api.IsModelOpen(modelId)) {
|
|
12214
|
+
if (modelId >= 0) api.CloseModel(modelId);
|
|
12215
|
+
return (0, brepjs.err)(importError("OPEN_MODEL_FAILED", "web-ifc OpenModel returned an invalid model id"));
|
|
12216
|
+
}
|
|
12217
|
+
const schemaRaw = api.GetModelSchema(modelId);
|
|
12218
|
+
if (!SUPPORTED_SCHEMAS.includes(schemaRaw)) {
|
|
12219
|
+
api.CloseModel(modelId);
|
|
12220
|
+
return (0, brepjs.err)(importError("SCHEMA_UNSUPPORTED", `Unsupported IFC schema "${schemaRaw}"`));
|
|
12221
|
+
}
|
|
12222
|
+
return (0, brepjs.ok)(new SpfReader(api, modelId, schemaRaw));
|
|
12223
|
+
}
|
|
12224
|
+
/** Always issues CloseModel; safe to call more than once. */
|
|
12225
|
+
close() {
|
|
12226
|
+
if (this.#closed) return;
|
|
12227
|
+
this.#closed = true;
|
|
12228
|
+
this.#api.CloseModel(this.modelId);
|
|
12229
|
+
}
|
|
12230
|
+
[Symbol.dispose]() {
|
|
12231
|
+
this.close();
|
|
12232
|
+
}
|
|
12233
|
+
/**
|
|
12234
|
+
* Raw line object for an express id. With `flatten=false` (default) references
|
|
12235
|
+
* appear as `{ type, value }` wrappers and nested entities are not resolved;
|
|
12236
|
+
* pass `flatten=true` to recursively inline referenced lines.
|
|
12237
|
+
*/
|
|
12238
|
+
getLine(expressId, flatten = false) {
|
|
12239
|
+
return this.#api.GetLine(this.modelId, expressId, flatten) ?? null;
|
|
12240
|
+
}
|
|
12241
|
+
/** Express ids of every line whose type equals `type` (no inherited types). */
|
|
12242
|
+
getLinesOfType(type) {
|
|
12243
|
+
const cached = this.#linesByType.get(type);
|
|
12244
|
+
if (cached !== void 0) return cached;
|
|
12245
|
+
const vec = this.#api.GetLineIDsWithType(this.modelId, type);
|
|
12246
|
+
const out = [];
|
|
12247
|
+
for (let i = 0; i < vec.size(); i++) out.push(vec.get(i));
|
|
12248
|
+
deleteVector(vec);
|
|
12249
|
+
this.#linesByType.set(type, out);
|
|
12250
|
+
return out;
|
|
12251
|
+
}
|
|
12252
|
+
/** Express ids of every line in the model. */
|
|
12253
|
+
getAllLines() {
|
|
12254
|
+
const vec = this.#api.GetAllLines(this.modelId);
|
|
12255
|
+
const out = [];
|
|
12256
|
+
for (let i = 0; i < vec.size(); i++) out.push(vec.get(i));
|
|
12257
|
+
deleteVector(vec);
|
|
12258
|
+
return out;
|
|
12259
|
+
}
|
|
12260
|
+
/** IFC type code for an express id. */
|
|
12261
|
+
/** Uppercased IFC entity name of the instance (e.g. `IFCWALL`). */
|
|
12262
|
+
typeNameOf(expressId) {
|
|
12263
|
+
return this.#api.GetNameFromTypeCode(this.getLineType(expressId)).toUpperCase();
|
|
12264
|
+
}
|
|
12265
|
+
getLineType(expressId) {
|
|
12266
|
+
const t = this.#api.GetLineType(this.modelId, expressId);
|
|
12267
|
+
return typeof t === "number" ? t : Number(t?.value ?? t);
|
|
12268
|
+
}
|
|
12269
|
+
/** Builds web-ifc's internal GUID→expressId index; call before guid lookups. */
|
|
12270
|
+
buildGuidMap() {
|
|
12271
|
+
this.#api.CreateIfcGuidToExpressIdMapping(this.modelId);
|
|
12272
|
+
}
|
|
12273
|
+
/** expressId for a GlobalId, or undefined. Requires {@link buildGuidMap} first. */
|
|
12274
|
+
expressIdFromGuid(guid) {
|
|
12275
|
+
const id = this.#api.GetExpressIdFromGuid(this.modelId, guid);
|
|
12276
|
+
return typeof id === "number" ? id : void 0;
|
|
12277
|
+
}
|
|
12278
|
+
/** GlobalId for an express id, or undefined. Requires {@link buildGuidMap} first. */
|
|
12279
|
+
guidFromExpressId(expressId) {
|
|
12280
|
+
const guid = this.#api.GetGuidFromExpressId(this.modelId, expressId);
|
|
12281
|
+
return typeof guid === "string" ? guid : void 0;
|
|
12282
|
+
}
|
|
12283
|
+
/**
|
|
12284
|
+
* Composed world transform (column-major 16-float matrix) for a placement
|
|
12285
|
+
* express id, resolving the full IfcLocalPlacement chain.
|
|
12286
|
+
*/
|
|
12287
|
+
getWorldTransform(placementExpressId) {
|
|
12288
|
+
return this.#api.GetWorldTransformMatrix(this.modelId, placementExpressId);
|
|
12289
|
+
}
|
|
12290
|
+
/** Streams placed meshes for the given product express ids. */
|
|
12291
|
+
streamMeshes(expressIds, cb) {
|
|
12292
|
+
this.#api.StreamMeshes(this.modelId, expressIds, cb);
|
|
12293
|
+
}
|
|
12294
|
+
/** Geometry buffers for a geometry express id; caller MUST call `.delete()`. */
|
|
12295
|
+
getGeometry(geometryExpressId) {
|
|
12296
|
+
return this.#api.GetGeometry(this.modelId, geometryExpressId);
|
|
12297
|
+
}
|
|
12298
|
+
/** Reads a Float32Array view of vertex data from a WASM pointer. */
|
|
12299
|
+
getVertexArray(ptr, size) {
|
|
12300
|
+
return this.#api.GetVertexArray(ptr, size);
|
|
12301
|
+
}
|
|
12302
|
+
/** Reads a Uint32Array view of index data from a WASM pointer. */
|
|
12303
|
+
getIndexArray(ptr, size) {
|
|
12304
|
+
return this.#api.GetIndexArray(ptr, size);
|
|
12305
|
+
}
|
|
12306
|
+
/** Decodes IFC STEP string escapes (`\X2\`, `\S\`, `\X\`) in a raw value. */
|
|
12307
|
+
decodeText(s) {
|
|
12308
|
+
const decoded = this.#api.DecodeText(s);
|
|
12309
|
+
return typeof decoded === "string" ? decoded : s;
|
|
12310
|
+
}
|
|
12311
|
+
};
|
|
12312
|
+
//#endregion
|
|
12313
|
+
//#region src/validation/qtoDefinitions.generated.ts
|
|
12314
|
+
var QTO_DEFINITIONS = {
|
|
12315
|
+
"Qto_ActuatorBaseQuantities": {
|
|
12316
|
+
"entities": ["IFCACTUATOR"],
|
|
12317
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12318
|
+
},
|
|
12319
|
+
"Qto_AirTerminalBaseQuantities": {
|
|
12320
|
+
"entities": ["IFCAIRTERMINAL"],
|
|
12321
|
+
"quantities": {
|
|
12322
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12323
|
+
"Perimeter": "IFCQUANTITYLENGTH",
|
|
12324
|
+
"TotalSurfaceArea": "IFCQUANTITYAREA"
|
|
12325
|
+
}
|
|
12326
|
+
},
|
|
12327
|
+
"Qto_AirTerminalBoxTypeBaseQuantities": {
|
|
12328
|
+
"entities": ["IFCAIRTERMINALBOX"],
|
|
12329
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12330
|
+
},
|
|
12331
|
+
"Qto_AirToAirHeatRecoveryBaseQuantities": {
|
|
12332
|
+
"entities": ["IFCAIRTOAIRHEATRECOVERY"],
|
|
12333
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12334
|
+
},
|
|
12335
|
+
"Qto_AlarmBaseQuantities": {
|
|
12336
|
+
"entities": ["IFCALARM"],
|
|
12337
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12338
|
+
},
|
|
12339
|
+
"Qto_AudioVisualApplianceBaseQuantities": {
|
|
12340
|
+
"entities": ["IFCAUDIOVISUALAPPLIANCE"],
|
|
12341
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12342
|
+
},
|
|
12343
|
+
"Qto_BeamBaseQuantities": {
|
|
12344
|
+
"entities": ["IFCBEAM"],
|
|
12345
|
+
"quantities": {
|
|
12346
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12347
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12348
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12349
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12350
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12351
|
+
"NetSurfaceArea": "IFCQUANTITYAREA",
|
|
12352
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12353
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12354
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12355
|
+
}
|
|
12356
|
+
},
|
|
12357
|
+
"Qto_BoilerBaseQuantities": {
|
|
12358
|
+
"entities": ["IFCBOILER"],
|
|
12359
|
+
"quantities": {
|
|
12360
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12361
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12362
|
+
"TotalSurfaceArea": "IFCQUANTITYAREA"
|
|
12363
|
+
}
|
|
12364
|
+
},
|
|
12365
|
+
"Qto_BuildingBaseQuantities": {
|
|
12366
|
+
"entities": ["IFCBUILDING"],
|
|
12367
|
+
"quantities": {
|
|
12368
|
+
"EavesHeight": "IFCQUANTITYLENGTH",
|
|
12369
|
+
"FootprintArea": "IFCQUANTITYAREA",
|
|
12370
|
+
"GrossFloorArea": "IFCQUANTITYAREA",
|
|
12371
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12372
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12373
|
+
"NetFloorArea": "IFCQUANTITYAREA",
|
|
12374
|
+
"NetVolume": "IFCQUANTITYVOLUME"
|
|
12375
|
+
}
|
|
12376
|
+
},
|
|
12377
|
+
"Qto_BuildingElementProxyQuantities": {
|
|
12378
|
+
"entities": ["IFCBUILDINGELEMENTPROXY"],
|
|
12379
|
+
"quantities": {
|
|
12380
|
+
"NetSurfaceArea": "IFCQUANTITYCOUNT",
|
|
12381
|
+
"NetVolume": "IFCQUANTITYCOUNT"
|
|
12382
|
+
}
|
|
12383
|
+
},
|
|
12384
|
+
"Qto_BuildingStoreyBaseQuantities": {
|
|
12385
|
+
"entities": ["IFCBUILDINGSTOREY"],
|
|
12386
|
+
"quantities": {
|
|
12387
|
+
"GrossFloorArea": "IFCQUANTITYAREA",
|
|
12388
|
+
"GrossHeight": "IFCQUANTITYLENGTH",
|
|
12389
|
+
"GrossPerimeter": "IFCQUANTITYLENGTH",
|
|
12390
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12391
|
+
"NetFloorArea": "IFCQUANTITYAREA",
|
|
12392
|
+
"NetHeigtht": "IFCQUANTITYLENGTH",
|
|
12393
|
+
"NetVolume": "IFCQUANTITYVOLUME"
|
|
12394
|
+
}
|
|
12395
|
+
},
|
|
12396
|
+
"Qto_BurnerBaseQuantities": {
|
|
12397
|
+
"entities": ["IFCBURNER"],
|
|
12398
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12399
|
+
},
|
|
12400
|
+
"Qto_CableCarrierFittingBaseQuantities": {
|
|
12401
|
+
"entities": ["IFCCABLECARRIERFITTING"],
|
|
12402
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12403
|
+
},
|
|
12404
|
+
"Qto_CableCarrierSegmentBaseQuantities": {
|
|
12405
|
+
"entities": ["IFCCABLECARRIERSEGMENT"],
|
|
12406
|
+
"quantities": {
|
|
12407
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12408
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12409
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12410
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12411
|
+
}
|
|
12412
|
+
},
|
|
12413
|
+
"Qto_CableFittingBaseQuantities": {
|
|
12414
|
+
"entities": ["IFCCABLEFITTING"],
|
|
12415
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12416
|
+
},
|
|
12417
|
+
"Qto_CableSegmentBaseQuantities": {
|
|
12418
|
+
"entities": ["IFCCABLESEGMENT"],
|
|
12419
|
+
"quantities": {
|
|
12420
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12421
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12422
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12423
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12424
|
+
}
|
|
12425
|
+
},
|
|
12426
|
+
"Qto_ChillerBaseQuantities": {
|
|
12427
|
+
"entities": ["IFCCHILLER"],
|
|
12428
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12429
|
+
},
|
|
12430
|
+
"Qto_ChimneyBaseQuantities": {
|
|
12431
|
+
"entities": ["IFCCHIMNEY"],
|
|
12432
|
+
"quantities": { "Length": "IFCQUANTITYLENGTH" }
|
|
12433
|
+
},
|
|
12434
|
+
"Qto_CoilBaseQuantities": {
|
|
12435
|
+
"entities": ["IFCCOIL"],
|
|
12436
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12437
|
+
},
|
|
12438
|
+
"Qto_ColumnBaseQuantities": {
|
|
12439
|
+
"entities": ["IFCCOLUMN"],
|
|
12440
|
+
"quantities": {
|
|
12441
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12442
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12443
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12444
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12445
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12446
|
+
"NetSurfaceArea": "IFCQUANTITYAREA",
|
|
12447
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12448
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12449
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12450
|
+
}
|
|
12451
|
+
},
|
|
12452
|
+
"Qto_CommunicationsApplianceBaseQuantities": {
|
|
12453
|
+
"entities": ["IFCCOMMUNICATIONSAPPLIANCE"],
|
|
12454
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12455
|
+
},
|
|
12456
|
+
"Qto_CompressorBaseQuantities": {
|
|
12457
|
+
"entities": ["IFCCOMPRESSOR"],
|
|
12458
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12459
|
+
},
|
|
12460
|
+
"Qto_CondenserBaseQuantities": {
|
|
12461
|
+
"entities": ["IFCCONDENSER"],
|
|
12462
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12463
|
+
},
|
|
12464
|
+
"Qto_ConstructionEquipmentResourceBaseQuantities": {
|
|
12465
|
+
"entities": ["IFCCONSTRUCTIONEQUIPMENTRESOURCE"],
|
|
12466
|
+
"quantities": {
|
|
12467
|
+
"OperatingTime": "IFCQUANTITYTIME",
|
|
12468
|
+
"UsageTime": "IFCQUANTITYTIME"
|
|
12469
|
+
}
|
|
12470
|
+
},
|
|
12471
|
+
"Qto_ConstructionMaterialResourceBaseQuantities": {
|
|
12472
|
+
"entities": ["IFCCONSTRUCTIONMATERIALRESOURCE"],
|
|
12473
|
+
"quantities": {
|
|
12474
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12475
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12476
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12477
|
+
"NetWeight": "IFCQUANTITYWEIGHT"
|
|
12478
|
+
}
|
|
12479
|
+
},
|
|
12480
|
+
"Qto_ControllerBaseQuantities": {
|
|
12481
|
+
"entities": ["IFCCONTROLLER"],
|
|
12482
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12483
|
+
},
|
|
12484
|
+
"Qto_CooledBeamBaseQuantities": {
|
|
12485
|
+
"entities": ["IFCCOOLEDBEAM"],
|
|
12486
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12487
|
+
},
|
|
12488
|
+
"Qto_CoolingTowerBaseQuantities": {
|
|
12489
|
+
"entities": ["IFCCOOLINGTOWER"],
|
|
12490
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12491
|
+
},
|
|
12492
|
+
"Qto_CoveringBaseQuantities": {
|
|
12493
|
+
"entities": ["IFCCOVERING"],
|
|
12494
|
+
"quantities": {
|
|
12495
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12496
|
+
"NetArea": "IFCQUANTITYAREA",
|
|
12497
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12498
|
+
}
|
|
12499
|
+
},
|
|
12500
|
+
"Qto_CurtainWallQuantities": {
|
|
12501
|
+
"entities": ["IFCCURTAINWALL"],
|
|
12502
|
+
"quantities": {
|
|
12503
|
+
"GrossSideArea": "IFCQUANTITYAREA",
|
|
12504
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12505
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12506
|
+
"NetSideArea": "IFCQUANTITYAREA",
|
|
12507
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12508
|
+
}
|
|
12509
|
+
},
|
|
12510
|
+
"Qto_DamperBaseQuantities": {
|
|
12511
|
+
"entities": ["IFCDAMPER"],
|
|
12512
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12513
|
+
},
|
|
12514
|
+
"Qto_DistributionChamberElementBaseQuantities": {
|
|
12515
|
+
"entities": ["IFCDISTRIBUTIONCHAMBERELEMENT"],
|
|
12516
|
+
"quantities": {
|
|
12517
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12518
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12519
|
+
"NetSurfaceArea": "IFCQUANTITYAREA",
|
|
12520
|
+
"NetVolume": "IFCQUANTITYVOLUME"
|
|
12521
|
+
}
|
|
12522
|
+
},
|
|
12523
|
+
"Qto_DoorBaseQuantities": {
|
|
12524
|
+
"entities": ["IFCDOOR"],
|
|
12525
|
+
"quantities": {
|
|
12526
|
+
"Area": "IFCQUANTITYAREA",
|
|
12527
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12528
|
+
"Perimeter": "IFCQUANTITYLENGTH",
|
|
12529
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12530
|
+
}
|
|
12531
|
+
},
|
|
12532
|
+
"Qto_DuctFittingBaseQuantities": {
|
|
12533
|
+
"entities": ["IFCDUCTFITTING"],
|
|
12534
|
+
"quantities": {
|
|
12535
|
+
"GrossCrossSectionArea": "IFCQUANTITYAREA",
|
|
12536
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12537
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12538
|
+
"NetCrossSectionArea": "IFCQUANTITYAREA",
|
|
12539
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12540
|
+
}
|
|
12541
|
+
},
|
|
12542
|
+
"Qto_DuctSegmentBaseQuantities": {
|
|
12543
|
+
"entities": ["IFCDUCTSEGMENT"],
|
|
12544
|
+
"quantities": {
|
|
12545
|
+
"GrossCrossSectionArea": "IFCQUANTITYAREA",
|
|
12546
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12547
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12548
|
+
"NetCrossSectionArea": "IFCQUANTITYAREA",
|
|
12549
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12550
|
+
}
|
|
12551
|
+
},
|
|
12552
|
+
"Qto_DuctSilencerBaseQuantities": {
|
|
12553
|
+
"entities": ["IFCDUCTSILENCER"],
|
|
12554
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12555
|
+
},
|
|
12556
|
+
"Qto_ElectricApplianceBaseQuantities": {
|
|
12557
|
+
"entities": ["IFCELECTRICAPPLIANCE"],
|
|
12558
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12559
|
+
},
|
|
12560
|
+
"Qto_ElectricDistributionBoardBaseQuantities": {
|
|
12561
|
+
"entities": ["IFCELECTRICDISTRIBUTIONBOARD"],
|
|
12562
|
+
"quantities": {
|
|
12563
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12564
|
+
"NumberOfCircuits": "IFCQUANTITYCOUNT"
|
|
12565
|
+
}
|
|
12566
|
+
},
|
|
12567
|
+
"Qto_ElectricFlowStorageDeviceBaseQuantities": {
|
|
12568
|
+
"entities": ["IFCELECTRICFLOWSTORAGEDEVICE"],
|
|
12569
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12570
|
+
},
|
|
12571
|
+
"Qto_ElectricGeneratorBaseQuantities": {
|
|
12572
|
+
"entities": ["IFCELECTRICGENERATOR"],
|
|
12573
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12574
|
+
},
|
|
12575
|
+
"Qto_ElectricMotorBaseQuantities": {
|
|
12576
|
+
"entities": ["IFCELECTRICMOTOR"],
|
|
12577
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12578
|
+
},
|
|
12579
|
+
"Qto_ElectricTimeControlBaseQuantities": {
|
|
12580
|
+
"entities": ["IFCELECTRICTIMECONTROL"],
|
|
12581
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12582
|
+
},
|
|
12583
|
+
"Qto_EvaporativeCoolerBaseQuantities": {
|
|
12584
|
+
"entities": ["IFCEVAPORATIVECOOLER"],
|
|
12585
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12586
|
+
},
|
|
12587
|
+
"Qto_EvaporatorBaseQuantities": {
|
|
12588
|
+
"entities": ["IFCEVAPORATOR"],
|
|
12589
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12590
|
+
},
|
|
12591
|
+
"Qto_FanBaseQuantities": {
|
|
12592
|
+
"entities": ["IFCFAN"],
|
|
12593
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12594
|
+
},
|
|
12595
|
+
"Qto_FilterBaseQuantities": {
|
|
12596
|
+
"entities": ["IFCFILTER"],
|
|
12597
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12598
|
+
},
|
|
12599
|
+
"Qto_FireSuppressionTerminalBaseQuantities": {
|
|
12600
|
+
"entities": ["IFCFIRESUPPRESSIONTERMINAL"],
|
|
12601
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12602
|
+
},
|
|
12603
|
+
"Qto_FlowInstrumentBaseQuantities": {
|
|
12604
|
+
"entities": ["IFCFLOWINSTRUMENT"],
|
|
12605
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12606
|
+
},
|
|
12607
|
+
"Qto_FlowMeterBaseQuantities": {
|
|
12608
|
+
"entities": ["IFCFLOWMETER"],
|
|
12609
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12610
|
+
},
|
|
12611
|
+
"Qto_FootingBaseQuantities": {
|
|
12612
|
+
"entities": ["IFCFOOTING"],
|
|
12613
|
+
"quantities": {
|
|
12614
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12615
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12616
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12617
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12618
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12619
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12620
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12621
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12622
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA",
|
|
12623
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12624
|
+
}
|
|
12625
|
+
},
|
|
12626
|
+
"Qto_HeatExchangerBaseQuantities": {
|
|
12627
|
+
"entities": ["IFCHEATEXCHANGER"],
|
|
12628
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12629
|
+
},
|
|
12630
|
+
"Qto_HumidifierBaseQuantities": {
|
|
12631
|
+
"entities": ["IFCHUMIDIFIER"],
|
|
12632
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12633
|
+
},
|
|
12634
|
+
"Qto_InterceptorBaseQuantities": {
|
|
12635
|
+
"entities": ["IFCINTERCEPTOR"],
|
|
12636
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12637
|
+
},
|
|
12638
|
+
"Qto_JunctionBoxBaseQuantities": {
|
|
12639
|
+
"entities": ["IFCJUNCTIONBOX"],
|
|
12640
|
+
"quantities": {
|
|
12641
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12642
|
+
"NumberOfGangs": "IFCQUANTITYCOUNT"
|
|
12643
|
+
}
|
|
12644
|
+
},
|
|
12645
|
+
"Qto_LaborResourceBaseQuantities": {
|
|
12646
|
+
"entities": ["IFCLABORRESOURCE"],
|
|
12647
|
+
"quantities": {
|
|
12648
|
+
"OvertimeWork": "IFCQUANTITYTIME",
|
|
12649
|
+
"StandardWork": "IFCQUANTITYTIME"
|
|
12650
|
+
}
|
|
12651
|
+
},
|
|
12652
|
+
"Qto_LampBaseQuantities": {
|
|
12653
|
+
"entities": ["IFCLAMP"],
|
|
12654
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12655
|
+
},
|
|
12656
|
+
"Qto_LightFixtureBaseQuantities": {
|
|
12657
|
+
"entities": ["IFCLIGHTFIXTURE"],
|
|
12658
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12659
|
+
},
|
|
12660
|
+
"Qto_MemberBaseQuantities": {
|
|
12661
|
+
"entities": ["IFCMEMBER"],
|
|
12662
|
+
"quantities": {
|
|
12663
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12664
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12665
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12666
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12667
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12668
|
+
"NetSurfaceArea": "IFCQUANTITYAREA",
|
|
12669
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12670
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12671
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12672
|
+
}
|
|
12673
|
+
},
|
|
12674
|
+
"Qto_MotorConnectionBaseQuantities": {
|
|
12675
|
+
"entities": ["IFCMOTORCONNECTION"],
|
|
12676
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12677
|
+
},
|
|
12678
|
+
"Qto_OpeningElementBaseQuantities": {
|
|
12679
|
+
"entities": ["IFCOPENINGELEMENT"],
|
|
12680
|
+
"quantities": {
|
|
12681
|
+
"Area": "IFCQUANTITYAREA",
|
|
12682
|
+
"Depth": "IFCQUANTITYLENGTH",
|
|
12683
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12684
|
+
"Volume": "IFCQUANTITYVOLUME",
|
|
12685
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12686
|
+
}
|
|
12687
|
+
},
|
|
12688
|
+
"Qto_OutletBaseQuantities": {
|
|
12689
|
+
"entities": ["IFCOUTLET"],
|
|
12690
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12691
|
+
},
|
|
12692
|
+
"Qto_PileBaseQuantities": {
|
|
12693
|
+
"entities": ["IFCPILE"],
|
|
12694
|
+
"quantities": {
|
|
12695
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12696
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12697
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12698
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12699
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12700
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12701
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12702
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12703
|
+
}
|
|
12704
|
+
},
|
|
12705
|
+
"Qto_PipeFittingBaseQuantities": {
|
|
12706
|
+
"entities": ["IFCPIPEFITTING"],
|
|
12707
|
+
"quantities": {
|
|
12708
|
+
"GrossCrossSectionArea": "IFCQUANTITYAREA",
|
|
12709
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12710
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12711
|
+
"NetCrossSectionArea": "IFCQUANTITYAREA",
|
|
12712
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12713
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12714
|
+
}
|
|
12715
|
+
},
|
|
12716
|
+
"Qto_PipeSegmentBaseQuantities": {
|
|
12717
|
+
"entities": ["IFCPIPESEGMENT"],
|
|
12718
|
+
"quantities": {
|
|
12719
|
+
"GrossCrossSectionArea": "IFCQUANTITYAREA",
|
|
12720
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12721
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12722
|
+
"NetCrossSectionArea": "IFCQUANTITYAREA",
|
|
12723
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12724
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12725
|
+
}
|
|
12726
|
+
},
|
|
12727
|
+
"Qto_PlateBaseQuantities": {
|
|
12728
|
+
"entities": ["IFCPLATE"],
|
|
12729
|
+
"quantities": {
|
|
12730
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12731
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12732
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12733
|
+
"NetArea": "IFCQUANTITYAREA",
|
|
12734
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12735
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12736
|
+
"Perimeter": "IFCQUANTITYLENGTH",
|
|
12737
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12738
|
+
}
|
|
12739
|
+
},
|
|
12740
|
+
"Qto_ProjectionElementBaseQuantities": {
|
|
12741
|
+
"entities": ["IFCPROJECTIONELEMENT"],
|
|
12742
|
+
"quantities": {
|
|
12743
|
+
"Area": "IFCQUANTITYAREA",
|
|
12744
|
+
"Volume": "IFCQUANTITYVOLUME"
|
|
12745
|
+
}
|
|
12746
|
+
},
|
|
12747
|
+
"Qto_ProtectiveDeviceBaseQuantities": {
|
|
12748
|
+
"entities": ["IFCPROTECTIVEDEVICE"],
|
|
12749
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12750
|
+
},
|
|
12751
|
+
"Qto_ProtectiveDeviceTrippingUnitBaseQuantities": {
|
|
12752
|
+
"entities": ["IFCPROTECTIVEDEVICETRIPPINGUNIT"],
|
|
12753
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12754
|
+
},
|
|
12755
|
+
"Qto_PumpBaseQuantities": {
|
|
12756
|
+
"entities": ["IFCPUMP"],
|
|
12757
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12758
|
+
},
|
|
12759
|
+
"Qto_RailingBaseQuantities": {
|
|
12760
|
+
"entities": ["IFCRAILING"],
|
|
12761
|
+
"quantities": { "Length": "IFCQUANTITYLENGTH" }
|
|
12762
|
+
},
|
|
12763
|
+
"Qto_RampFlightBaseQuantities": {
|
|
12764
|
+
"entities": ["IFCRAMPFLIGHT"],
|
|
12765
|
+
"quantities": {
|
|
12766
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12767
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12768
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12769
|
+
"NetArea": "IFCQUANTITYAREA",
|
|
12770
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12771
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12772
|
+
}
|
|
12773
|
+
},
|
|
12774
|
+
"Qto_ReinforcingElementBaseQuantities": {
|
|
12775
|
+
"entities": ["IFCREINFORCINGELEMENT"],
|
|
12776
|
+
"quantities": {
|
|
12777
|
+
"Count": "IFCQUANTITYCOUNT",
|
|
12778
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12779
|
+
"Weight": "IFCQUANTITYWEIGHT"
|
|
12780
|
+
}
|
|
12781
|
+
},
|
|
12782
|
+
"Qto_RoofBaseQuantities": {
|
|
12783
|
+
"entities": ["IFCROOF"],
|
|
12784
|
+
"quantities": {
|
|
12785
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12786
|
+
"NetArea": "IFCQUANTITYAREA",
|
|
12787
|
+
"ProjectedArea": "IFCQUANTITYAREA"
|
|
12788
|
+
}
|
|
12789
|
+
},
|
|
12790
|
+
"Qto_SanitaryTerminalBaseQuantities": {
|
|
12791
|
+
"entities": ["IFCSANITARYTERMINAL"],
|
|
12792
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12793
|
+
},
|
|
12794
|
+
"Qto_SensorBaseQuantities": {
|
|
12795
|
+
"entities": ["IFCSENSOR"],
|
|
12796
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12797
|
+
},
|
|
12798
|
+
"Qto_SiteBaseQuantities": {
|
|
12799
|
+
"entities": ["IFCSITE"],
|
|
12800
|
+
"quantities": {
|
|
12801
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12802
|
+
"GrossPerimeter": "IFCQUANTITYLENGTH"
|
|
12803
|
+
}
|
|
12804
|
+
},
|
|
12805
|
+
"Qto_SlabBaseQuantities": {
|
|
12806
|
+
"entities": ["IFCSLAB"],
|
|
12807
|
+
"quantities": {
|
|
12808
|
+
"Depth": "IFCQUANTITYLENGTH",
|
|
12809
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12810
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12811
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12812
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12813
|
+
"NetArea": "IFCQUANTITYAREA",
|
|
12814
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12815
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12816
|
+
"Perimeter": "IFCQUANTITYLENGTH",
|
|
12817
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12818
|
+
}
|
|
12819
|
+
},
|
|
12820
|
+
"Qto_SolarDeviceBaseQuantities": {
|
|
12821
|
+
"entities": ["IFCSOLARDEVICE"],
|
|
12822
|
+
"quantities": {
|
|
12823
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12824
|
+
"GrossWeight": "IFCQUANTITYWEIGHT"
|
|
12825
|
+
}
|
|
12826
|
+
},
|
|
12827
|
+
"Qto_SpaceBaseQuantities": {
|
|
12828
|
+
"entities": ["IFCSPACE"],
|
|
12829
|
+
"quantities": {
|
|
12830
|
+
"FinishCeilingHeight": "IFCQUANTITYLENGTH",
|
|
12831
|
+
"FinishFloorHeight": "IFCQUANTITYLENGTH",
|
|
12832
|
+
"GrossCeilingArea": "IFCQUANTITYAREA",
|
|
12833
|
+
"GrossFloorArea": "IFCQUANTITYAREA",
|
|
12834
|
+
"GrossPerimeter": "IFCQUANTITYLENGTH",
|
|
12835
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12836
|
+
"GrossWallArea": "IFCQUANTITYAREA",
|
|
12837
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12838
|
+
"NetCeilingArea": "IFCQUANTITYAREA",
|
|
12839
|
+
"NetFloorArea": "IFCQUANTITYAREA",
|
|
12840
|
+
"NetPerimeter": "IFCQUANTITYLENGTH",
|
|
12841
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12842
|
+
"NetWallArea": "IFCQUANTITYAREA"
|
|
12843
|
+
}
|
|
12844
|
+
},
|
|
12845
|
+
"Qto_SpaceHeaterBaseQuantities": {
|
|
12846
|
+
"entities": ["IFCSPACEHEATER"],
|
|
12847
|
+
"quantities": {
|
|
12848
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12849
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12850
|
+
"NetWeight": "IFCQUANTITYWEIGHT"
|
|
12851
|
+
}
|
|
12852
|
+
},
|
|
12853
|
+
"Qto_StackTerminalBaseQuantities": {
|
|
12854
|
+
"entities": ["IFCSTACKTERMINAL"],
|
|
12855
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12856
|
+
},
|
|
12857
|
+
"Qto_StairFlightBaseQuantities": {
|
|
12858
|
+
"entities": ["IFCSTAIRFLIGHT"],
|
|
12859
|
+
"quantities": {
|
|
12860
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12861
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12862
|
+
"NetVolume": "IFCQUANTITYVOLUME"
|
|
12863
|
+
}
|
|
12864
|
+
},
|
|
12865
|
+
"Qto_SwitchingDeviceBaseQuantities": {
|
|
12866
|
+
"entities": ["IFCSWITCHINGDEVICE"],
|
|
12867
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12868
|
+
},
|
|
12869
|
+
"Qto_TankBaseQuantities": {
|
|
12870
|
+
"entities": ["IFCTANK"],
|
|
12871
|
+
"quantities": {
|
|
12872
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12873
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12874
|
+
"TotalSurfaceArea": "IFCQUANTITYAREA"
|
|
12875
|
+
}
|
|
12876
|
+
},
|
|
12877
|
+
"Qto_TransformerBaseQuantities": {
|
|
12878
|
+
"entities": ["IFCTRANSFORMER"],
|
|
12879
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12880
|
+
},
|
|
12881
|
+
"Qto_TubeBundleBaseQuantities": {
|
|
12882
|
+
"entities": ["IFCTUBEBUNDLE"],
|
|
12883
|
+
"quantities": {
|
|
12884
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12885
|
+
"NetWeight": "IFCQUANTITYWEIGHT"
|
|
12886
|
+
}
|
|
12887
|
+
},
|
|
12888
|
+
"Qto_UnitaryControlElementBaseQuantities": {
|
|
12889
|
+
"entities": ["IFCUNITARYCONTROLELEMENT"],
|
|
12890
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12891
|
+
},
|
|
12892
|
+
"Qto_UnitaryEquipmentBaseQuantities": {
|
|
12893
|
+
"entities": ["IFCUNITARYEQUIPMENT"],
|
|
12894
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12895
|
+
},
|
|
12896
|
+
"Qto_ValveBaseQuantities": {
|
|
12897
|
+
"entities": ["IFCVALVE"],
|
|
12898
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12899
|
+
},
|
|
12900
|
+
"Qto_VibrationIsolatorBaseQuantities": {
|
|
12901
|
+
"entities": ["IFCVIBRATIONISOLATOR"],
|
|
12902
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12903
|
+
},
|
|
12904
|
+
"Qto_WallBaseQuantities": {
|
|
12905
|
+
"entities": ["IFCWALL"],
|
|
12906
|
+
"quantities": {
|
|
12907
|
+
"GrossFootprintArea": "IFCQUANTITYAREA",
|
|
12908
|
+
"GrossSideArea": "IFCQUANTITYAREA",
|
|
12909
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12910
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12911
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12912
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12913
|
+
"NetFootprintArea": "IFCQUANTITYAREA",
|
|
12914
|
+
"NetSideArea": "IFCQUANTITYAREA",
|
|
12915
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12916
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12917
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12918
|
+
}
|
|
12919
|
+
},
|
|
12920
|
+
"Qto_WasteTerminalBaseQuantities": {
|
|
12921
|
+
"entities": ["IFCWASTETERMINAL"],
|
|
12922
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12923
|
+
},
|
|
12924
|
+
"Qto_WindowBaseQuantities": {
|
|
12925
|
+
"entities": ["IFCWINDOW"],
|
|
12926
|
+
"quantities": {
|
|
12927
|
+
"Area": "IFCQUANTITYAREA",
|
|
12928
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12929
|
+
"Perimeter": "IFCQUANTITYLENGTH",
|
|
12930
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12931
|
+
}
|
|
12932
|
+
}
|
|
12933
|
+
};
|
|
12934
|
+
//#endregion
|
|
12935
|
+
//#region src/validation/gherkinChecks.ts
|
|
12936
|
+
/**
|
|
12937
|
+
* Local implementations of the buildingSMART Validation Service's gherkin
|
|
12938
|
+
* normative rules that apply to the entity vocabulary this writer emits:
|
|
12939
|
+
*
|
|
12940
|
+
* - IFC102 — absence of deprecated entities and attributes (IFC4 lists from
|
|
12941
|
+
* the official rule definition).
|
|
12942
|
+
* - QTY001 — every `Qto_*` element quantity uses the standard set name,
|
|
12943
|
+
* quantity names, quantity entity types, applicable element, and
|
|
12944
|
+
* `MethodOfMeasurement='BaseQuantities'` (table generated from the official
|
|
12945
|
+
* qto_definitions.csv).
|
|
12946
|
+
* - GRF003 — a model containing facilities (IfcBuilding) declares a
|
|
12947
|
+
* coordinate reference system (warning severity, like the service).
|
|
12948
|
+
*
|
|
12949
|
+
* These run inside `toIfcValidated`, so the local gate covers the gherkin
|
|
12950
|
+
* layer before anything is uploaded.
|
|
12951
|
+
*/
|
|
12952
|
+
async function checkGherkinRules(bytes) {
|
|
12953
|
+
const readerResult = await SpfReader.create(bytes);
|
|
12954
|
+
if (!readerResult.ok) return [issue("error", "PARSE_FAILED", `Could not open the model: ${readerResult.error.message}`)];
|
|
12955
|
+
const reader = readerResult.value;
|
|
12956
|
+
try {
|
|
12957
|
+
return [
|
|
12958
|
+
...checkDeprecated(reader),
|
|
12959
|
+
...checkQuantitySets(reader),
|
|
12960
|
+
...checkGeoreferencing(reader)
|
|
12961
|
+
];
|
|
12962
|
+
} finally {
|
|
12963
|
+
reader.close();
|
|
12964
|
+
}
|
|
12965
|
+
}
|
|
12966
|
+
/** IFC4 deprecated entities (IFC102, official rule table). */
|
|
12967
|
+
var DEPRECATED_IFC4_ENTITIES = [
|
|
12968
|
+
"IFC2DCOMPOSITECURVE",
|
|
12969
|
+
"IFCBEAMSTANDARDCASE",
|
|
12970
|
+
"IFCCONNECTIONPORTGEOMETRY",
|
|
12971
|
+
"IFCCOLUMNSTANDARDCASE",
|
|
12972
|
+
"IFCDOORSTANDARDCASE",
|
|
12973
|
+
"IFCDOORSTYLE",
|
|
12974
|
+
"IFCELECTRICALELEMENT",
|
|
12975
|
+
"IFCEQUIPMENTELEMENT",
|
|
12976
|
+
"IFCFACEBASEDSURFACEMODEL",
|
|
12977
|
+
"IFCMATERIALCLASSIFICATIONRELATIONSHIP",
|
|
12978
|
+
"IFCMATERIALLIST",
|
|
12979
|
+
"IFCMEMBERSTANDARDCASE",
|
|
12980
|
+
"IFCOPENINGSTANDARDCASE",
|
|
12981
|
+
"IFCPLATESTANDARDCASE",
|
|
12982
|
+
"IFCPRESENTATIONSTYLEASSIGNMENT",
|
|
12983
|
+
"IFCPROXY",
|
|
12984
|
+
"IFCRELCOVERSBLDGELEMENTS",
|
|
12985
|
+
"IFCRELCOVERSSPACES",
|
|
12986
|
+
"IFCSLABELEMENTEDCASE",
|
|
12987
|
+
"IFCSLABSTANDARDCASE",
|
|
12988
|
+
"IFCTEXTLITERAL",
|
|
12989
|
+
"IFCWALLELEMENTEDCASE",
|
|
12990
|
+
"IFCWALLSTANDARDCASE",
|
|
12991
|
+
"IFCWINDOWSTANDARDCASE",
|
|
12992
|
+
"IFCWINDOWSTYLE"
|
|
12993
|
+
];
|
|
12994
|
+
/** IFC4 deprecated attributes (IFC102): entity -> attributes that must be empty. */
|
|
12995
|
+
var DEPRECATED_IFC4_ATTRIBUTES = {
|
|
12996
|
+
IFCDOORLININGPROPERTIES: ["ShapeAspectStyle"],
|
|
12997
|
+
IFCDOORPANELPROPERTIES: ["ShapeAspectStyle"],
|
|
12998
|
+
IFCFILLAREASTYLEHATCHING: ["PointOfReferenceHatchLine"],
|
|
12999
|
+
IFCREINFORCINGELEMENT: ["SteelGrade"],
|
|
13000
|
+
IFCRELASSIGNSTOACTOR: ["RelatedObjectsType"],
|
|
13001
|
+
IFCRELASSIGNSTOCONTROL: ["RelatedObjectsType"],
|
|
13002
|
+
IFCRELASSIGNSTOGROUP: ["RelatedObjectsType"],
|
|
13003
|
+
IFCRELASSIGNSTOGROUPBYFACTOR: ["RelatedObjectsType"],
|
|
13004
|
+
IFCRELASSIGNSTOPROCESS: ["RelatedObjectsType"],
|
|
13005
|
+
IFCRELASSIGNSTOPRODUCT: ["RelatedObjectsType"],
|
|
13006
|
+
IFCRELASSIGNSTORESOURCE: ["RelatedObjectsType"],
|
|
13007
|
+
IFCSTAIRFLIGHT: [
|
|
13008
|
+
"NumberOfRisers",
|
|
13009
|
+
"NumberOfTreads",
|
|
13010
|
+
"RiserHeight",
|
|
13011
|
+
"TreadLength"
|
|
13012
|
+
],
|
|
13013
|
+
IFCWINDOWPANELPROPERTIES: ["ShapeAspectStyle"],
|
|
13014
|
+
IFCWINDOWLININGPROPERTIES: ["ShapeAspectStyle"]
|
|
13015
|
+
};
|
|
13016
|
+
function checkDeprecated(reader) {
|
|
13017
|
+
const issues = [];
|
|
13018
|
+
if (reader.schema !== "IFC4") return issues;
|
|
13019
|
+
for (const id of reader.getAllLines()) {
|
|
13020
|
+
const typeName = reader.typeNameOf(id);
|
|
13021
|
+
if (DEPRECATED_IFC4_ENTITIES.includes(typeName)) {
|
|
13022
|
+
issues.push(issue("error", "DEPRECATED_ENTITY", `#${id} ${typeName} is deprecated in IFC4 (IFC102)`, id));
|
|
13023
|
+
continue;
|
|
13024
|
+
}
|
|
13025
|
+
const attrs = DEPRECATED_IFC4_ATTRIBUTES[typeName];
|
|
13026
|
+
if (attrs === void 0) continue;
|
|
13027
|
+
const line = reader.getLine(id);
|
|
13028
|
+
if (line === null) continue;
|
|
13029
|
+
for (const attr of attrs) if (line[attr] !== null && line[attr] !== void 0) issues.push(issue("error", "DEPRECATED_ATTRIBUTE", `#${id} ${typeName}.${attr} is deprecated in IFC4 and must be empty (IFC102)`, id));
|
|
13030
|
+
}
|
|
13031
|
+
return issues;
|
|
13032
|
+
}
|
|
13033
|
+
function textOf(v) {
|
|
13034
|
+
const value = v?.value;
|
|
13035
|
+
return typeof value === "string" ? value : void 0;
|
|
13036
|
+
}
|
|
13037
|
+
function checkQuantitySets(reader) {
|
|
13038
|
+
const issues = [];
|
|
13039
|
+
const related = /* @__PURE__ */ new Map();
|
|
13040
|
+
for (const relId of reader.getLinesOfType(web_ifc.IFCRELDEFINESBYPROPERTIES)) {
|
|
13041
|
+
const rel = reader.getLine(relId);
|
|
13042
|
+
if (rel === null) continue;
|
|
13043
|
+
const target = rel["RelatingPropertyDefinition"]?.value;
|
|
13044
|
+
if (typeof target !== "number") continue;
|
|
13045
|
+
const objects = rel["RelatedObjects"];
|
|
13046
|
+
if (!Array.isArray(objects)) continue;
|
|
13047
|
+
const names = objects.map((o) => o.value).filter((v) => typeof v === "number").map((id) => reader.typeNameOf(id));
|
|
13048
|
+
related.set(target, [...related.get(target) ?? [], ...names]);
|
|
13049
|
+
}
|
|
13050
|
+
for (const id of reader.getLinesOfType(web_ifc.IFCELEMENTQUANTITY)) {
|
|
13051
|
+
const line = reader.getLine(id);
|
|
13052
|
+
if (line === null) continue;
|
|
13053
|
+
const name = textOf(line["Name"]);
|
|
13054
|
+
if (name === void 0 || !name.startsWith("Qto_")) continue;
|
|
13055
|
+
const definition = QTO_DEFINITIONS[name];
|
|
13056
|
+
if (definition === void 0) {
|
|
13057
|
+
issues.push(issue("error", "QTO_UNKNOWN_SET", `#${id} '${name}' is not a standard quantity set (QTY001)`, id));
|
|
13058
|
+
continue;
|
|
13059
|
+
}
|
|
13060
|
+
if (textOf(line["MethodOfMeasurement"]) !== "BaseQuantities") issues.push(issue("error", "QTO_METHOD", `#${id} '${name}' must declare MethodOfMeasurement='BaseQuantities' (QTY001)`, id));
|
|
13061
|
+
for (const entity of related.get(id) ?? []) if (!definition.entities.includes(entity)) issues.push(issue("error", "QTO_WRONG_ENTITY", `#${id} '${name}' is not applicable to ${entity} (QTY001)`, id));
|
|
13062
|
+
const quantities = line["Quantities"];
|
|
13063
|
+
if (!Array.isArray(quantities)) continue;
|
|
13064
|
+
for (const q of quantities) {
|
|
13065
|
+
const qid = q.value;
|
|
13066
|
+
if (typeof qid !== "number") continue;
|
|
13067
|
+
const qName = textOf(reader.getLine(qid)?.["Name"]);
|
|
13068
|
+
if (qName === void 0) continue;
|
|
13069
|
+
const expectedType = definition.quantities[qName];
|
|
13070
|
+
if (expectedType === void 0) issues.push(issue("error", "QTO_UNKNOWN_QUANTITY", `#${qid} '${qName}' is not defined in ${name} (QTY001)`, qid));
|
|
13071
|
+
else if (reader.typeNameOf(qid) !== expectedType) issues.push(issue("error", "QTO_WRONG_TYPE", `#${qid} '${qName}' must be a ${expectedType} (QTY001)`, qid));
|
|
13072
|
+
}
|
|
13073
|
+
}
|
|
13074
|
+
return issues;
|
|
13075
|
+
}
|
|
13076
|
+
function checkGeoreferencing(reader) {
|
|
13077
|
+
if (!(reader.getLinesOfType(web_ifc.IFCBUILDING).length > 0)) return [];
|
|
13078
|
+
if (reader.getLinesOfType(web_ifc.IFCPROJECTEDCRS).length > 0 || reader.getLinesOfType(web_ifc.IFCGEOGRAPHICCRS).length > 0) return [];
|
|
13079
|
+
return [issue("warning", "NO_GEOREFERENCING", "Model contains a facility but no IfcProjectedCRS/IfcGeographicCRS (GRF003) — set ProjectSpec.crs")];
|
|
13080
|
+
}
|
|
13081
|
+
//#endregion
|
|
13082
|
+
//#region src/serialize/toIfc.ts
|
|
13083
|
+
async function toIfc(model, meta) {
|
|
13084
|
+
const project = model.getProject();
|
|
13085
|
+
if (!project) return (0, brepjs.err)(ifcError("NO_PROJECT", "BimModel has no project — call model.init() first"));
|
|
13086
|
+
const authorName = [meta.author?.givenName, meta.author?.familyName].filter((p) => Boolean(p)).join(" ");
|
|
13087
|
+
const writerResult = await IfcWriter.create(meta.mvdViewDefinition, meta.ifcSchema, {
|
|
13088
|
+
author: authorName,
|
|
13089
|
+
organization: meta.organizationName
|
|
13090
|
+
});
|
|
13091
|
+
if (!writerResult.ok) return writerResult;
|
|
13092
|
+
const w = writerResult.value;
|
|
13093
|
+
w.setModelScope(project.guid);
|
|
13094
|
+
const elements = model.getAllElements();
|
|
13095
|
+
const relationships = model.getAllRelationships();
|
|
13096
|
+
const walls = model.getWalls();
|
|
13097
|
+
const slabs = model.getSlabs();
|
|
13098
|
+
const beams = model.getBeams();
|
|
13099
|
+
const columns = model.getColumns();
|
|
13100
|
+
const doors = model.getDoors();
|
|
13101
|
+
const windows = model.getWindows();
|
|
13102
|
+
const proxies = model.getProxies();
|
|
13103
|
+
const spaces = model.getSpaces();
|
|
13104
|
+
const roofs = model.getRoofs();
|
|
13105
|
+
const curtainWalls = model.getCurtainWalls();
|
|
13106
|
+
const footings = model.getFootings();
|
|
13107
|
+
const piles = model.getPiles();
|
|
13108
|
+
const stairs = model.getStairs();
|
|
13109
|
+
const ramps = model.getRamps();
|
|
13110
|
+
const railings = model.getRailings();
|
|
13111
|
+
const coverings = model.getCoverings();
|
|
13112
|
+
const assemblies = model.getElementAssemblies();
|
|
13113
|
+
const zones = model.getZones();
|
|
13114
|
+
const systems = model.getSystems();
|
|
13115
|
+
const { ownerHistoryId, geomContextId, geomSubContextId, unitAssignmentId, lengthUnitId } = writeHeader(w, meta);
|
|
13116
|
+
if (project.spec.crs !== void 0) writeMapConversion(w, project.spec.crs, geomContextId, lengthUnitId);
|
|
13117
|
+
const densityByElement = buildDensityMap(relationships);
|
|
13118
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
13119
|
+
const placementMap = /* @__PURE__ */ new Map();
|
|
13120
|
+
const projectExpressId = writeProject$1(w, project.guid, project.spec.name, ownerHistoryId, unitAssignmentId, geomContextId);
|
|
13121
|
+
idMap.set(project.localId, projectExpressId);
|
|
13122
|
+
for (const el of elements) {
|
|
13123
|
+
if (el.category !== "SITE") continue;
|
|
13124
|
+
const { entityId, placementId } = writeSite(w, el.guid, el.spec.name, ownerHistoryId);
|
|
13125
|
+
idMap.set(el.localId, entityId);
|
|
13126
|
+
placementMap.set(el.localId, placementId);
|
|
13127
|
+
}
|
|
13128
|
+
for (const el of elements) {
|
|
13129
|
+
if (el.category !== "BUILDING") continue;
|
|
13130
|
+
const parentSiteId = findParentOf(el.localId, relationships);
|
|
13131
|
+
const parentPlacementId = parentSiteId !== null ? placementMap.get(parentSiteId) ?? null : null;
|
|
13132
|
+
const { entityId, placementId } = writeBuilding(w, el.guid, el.spec.name, ownerHistoryId, parentPlacementId);
|
|
13133
|
+
idMap.set(el.localId, entityId);
|
|
13134
|
+
placementMap.set(el.localId, placementId);
|
|
13135
|
+
}
|
|
13136
|
+
for (const el of elements) {
|
|
13137
|
+
if (el.category !== "STOREY") continue;
|
|
13138
|
+
const parentBuildingId = findParentOf(el.localId, relationships);
|
|
13139
|
+
const parentPlacementId = parentBuildingId !== null ? placementMap.get(parentBuildingId) ?? null : null;
|
|
13140
|
+
const { entityId, placementId } = writeStorey(w, el.guid, el.spec.name, el.spec.elevation, ownerHistoryId, parentPlacementId);
|
|
13141
|
+
idMap.set(el.localId, entityId);
|
|
13142
|
+
placementMap.set(el.localId, placementId);
|
|
13143
|
+
}
|
|
13144
|
+
const openingsByWall = /* @__PURE__ */ new Map();
|
|
13145
|
+
for (const rel of relationships) {
|
|
13146
|
+
if (rel.kind !== "VOIDS_WALL") continue;
|
|
13147
|
+
const opening = elements.find((el) => el.localId === rel.openingLocalId);
|
|
12136
13148
|
if (opening === void 0 || opening.category !== "OPENING") continue;
|
|
12137
13149
|
if (!isWallOpening(opening.spec)) continue;
|
|
12138
13150
|
const list = openingsByWall.get(rel.wallLocalId) ?? [];
|
|
@@ -12602,11 +13614,13 @@ async function toIfcValidated(model, meta) {
|
|
|
12602
13614
|
const geometry = collectGeometryIssues(model);
|
|
12603
13615
|
const schema = await checkSchema(bytes);
|
|
12604
13616
|
const roundTrip = await checkRoundTrip(bytes);
|
|
13617
|
+
const gherkin = await checkGherkinRules(bytes);
|
|
12605
13618
|
const report = { issues: [
|
|
12606
13619
|
...integrity.issues,
|
|
12607
13620
|
...geometry.issues,
|
|
12608
13621
|
...schema.issues,
|
|
12609
|
-
...roundTrip.issues
|
|
13622
|
+
...roundTrip.issues,
|
|
13623
|
+
...gherkin
|
|
12610
13624
|
] };
|
|
12611
13625
|
return (0, brepjs.ok)({
|
|
12612
13626
|
bytes,
|
|
@@ -12691,149 +13705,6 @@ function findContainerOf(elementId, relationships) {
|
|
|
12691
13705
|
return null;
|
|
12692
13706
|
}
|
|
12693
13707
|
//#endregion
|
|
12694
|
-
//#region src/import/spfReader.ts
|
|
12695
|
-
var SUPPORTED_SCHEMAS = [
|
|
12696
|
-
"IFC2X3",
|
|
12697
|
-
"IFC4",
|
|
12698
|
-
"IFC4X3"
|
|
12699
|
-
];
|
|
12700
|
-
/**
|
|
12701
|
-
* Foundation layer of the IFC reader: owns the web-ifc WASM model handle and
|
|
12702
|
-
* exposes typed line access, GUID↔expressId lookup, world-transform composition,
|
|
12703
|
-
* geometry-engine access and STEP string decoding.
|
|
12704
|
-
*
|
|
12705
|
-
* Lifecycle: created via the static async {@link SpfReader.create}; the caller
|
|
12706
|
-
* MUST call {@link SpfReader.close} (it always issues `CloseModel`, preventing
|
|
12707
|
-
* WASM handle leaks). The handle is `using`-friendly via `Symbol.dispose`.
|
|
12708
|
-
*/
|
|
12709
|
-
function deleteVector(vec) {
|
|
12710
|
-
vec.delete?.();
|
|
12711
|
-
}
|
|
12712
|
-
var SpfReader = class SpfReader {
|
|
12713
|
-
schema;
|
|
12714
|
-
modelId;
|
|
12715
|
-
#api;
|
|
12716
|
-
#closed = false;
|
|
12717
|
-
#linesByType = /* @__PURE__ */ new Map();
|
|
12718
|
-
constructor(api, modelId, schema) {
|
|
12719
|
-
this.#api = api;
|
|
12720
|
-
this.modelId = modelId;
|
|
12721
|
-
this.schema = schema;
|
|
12722
|
-
}
|
|
12723
|
-
static async create(bytes, settings = {}) {
|
|
12724
|
-
let api;
|
|
12725
|
-
try {
|
|
12726
|
-
api = new web_ifc.IfcAPI();
|
|
12727
|
-
await initIfcApi(api);
|
|
12728
|
-
} catch (e) {
|
|
12729
|
-
return (0, brepjs.err)(importError("OPEN_MODEL_FAILED", "Failed to initialize web-ifc", e));
|
|
12730
|
-
}
|
|
12731
|
-
let modelId;
|
|
12732
|
-
try {
|
|
12733
|
-
modelId = api.OpenModel(bytes, { COORDINATE_TO_ORIGIN: settings.coordinateToOrigin ?? false });
|
|
12734
|
-
} catch (e) {
|
|
12735
|
-
return (0, brepjs.err)(importError("OPEN_MODEL_FAILED", "web-ifc OpenModel threw", e));
|
|
12736
|
-
}
|
|
12737
|
-
if (modelId < 0 || !api.IsModelOpen(modelId)) {
|
|
12738
|
-
if (modelId >= 0) api.CloseModel(modelId);
|
|
12739
|
-
return (0, brepjs.err)(importError("OPEN_MODEL_FAILED", "web-ifc OpenModel returned an invalid model id"));
|
|
12740
|
-
}
|
|
12741
|
-
const schemaRaw = api.GetModelSchema(modelId);
|
|
12742
|
-
if (!SUPPORTED_SCHEMAS.includes(schemaRaw)) {
|
|
12743
|
-
api.CloseModel(modelId);
|
|
12744
|
-
return (0, brepjs.err)(importError("SCHEMA_UNSUPPORTED", `Unsupported IFC schema "${schemaRaw}"`));
|
|
12745
|
-
}
|
|
12746
|
-
return (0, brepjs.ok)(new SpfReader(api, modelId, schemaRaw));
|
|
12747
|
-
}
|
|
12748
|
-
/** Always issues CloseModel; safe to call more than once. */
|
|
12749
|
-
close() {
|
|
12750
|
-
if (this.#closed) return;
|
|
12751
|
-
this.#closed = true;
|
|
12752
|
-
this.#api.CloseModel(this.modelId);
|
|
12753
|
-
}
|
|
12754
|
-
[Symbol.dispose]() {
|
|
12755
|
-
this.close();
|
|
12756
|
-
}
|
|
12757
|
-
/**
|
|
12758
|
-
* Raw line object for an express id. With `flatten=false` (default) references
|
|
12759
|
-
* appear as `{ type, value }` wrappers and nested entities are not resolved;
|
|
12760
|
-
* pass `flatten=true` to recursively inline referenced lines.
|
|
12761
|
-
*/
|
|
12762
|
-
getLine(expressId, flatten = false) {
|
|
12763
|
-
return this.#api.GetLine(this.modelId, expressId, flatten) ?? null;
|
|
12764
|
-
}
|
|
12765
|
-
/** Express ids of every line whose type equals `type` (no inherited types). */
|
|
12766
|
-
getLinesOfType(type) {
|
|
12767
|
-
const cached = this.#linesByType.get(type);
|
|
12768
|
-
if (cached !== void 0) return cached;
|
|
12769
|
-
const vec = this.#api.GetLineIDsWithType(this.modelId, type);
|
|
12770
|
-
const out = [];
|
|
12771
|
-
for (let i = 0; i < vec.size(); i++) out.push(vec.get(i));
|
|
12772
|
-
deleteVector(vec);
|
|
12773
|
-
this.#linesByType.set(type, out);
|
|
12774
|
-
return out;
|
|
12775
|
-
}
|
|
12776
|
-
/** Express ids of every line in the model. */
|
|
12777
|
-
getAllLines() {
|
|
12778
|
-
const vec = this.#api.GetAllLines(this.modelId);
|
|
12779
|
-
const out = [];
|
|
12780
|
-
for (let i = 0; i < vec.size(); i++) out.push(vec.get(i));
|
|
12781
|
-
deleteVector(vec);
|
|
12782
|
-
return out;
|
|
12783
|
-
}
|
|
12784
|
-
/** IFC type code for an express id. */
|
|
12785
|
-
/** Uppercased IFC entity name of the instance (e.g. `IFCWALL`). */
|
|
12786
|
-
typeNameOf(expressId) {
|
|
12787
|
-
return this.#api.GetNameFromTypeCode(this.getLineType(expressId)).toUpperCase();
|
|
12788
|
-
}
|
|
12789
|
-
getLineType(expressId) {
|
|
12790
|
-
const t = this.#api.GetLineType(this.modelId, expressId);
|
|
12791
|
-
return typeof t === "number" ? t : Number(t?.value ?? t);
|
|
12792
|
-
}
|
|
12793
|
-
/** Builds web-ifc's internal GUID→expressId index; call before guid lookups. */
|
|
12794
|
-
buildGuidMap() {
|
|
12795
|
-
this.#api.CreateIfcGuidToExpressIdMapping(this.modelId);
|
|
12796
|
-
}
|
|
12797
|
-
/** expressId for a GlobalId, or undefined. Requires {@link buildGuidMap} first. */
|
|
12798
|
-
expressIdFromGuid(guid) {
|
|
12799
|
-
const id = this.#api.GetExpressIdFromGuid(this.modelId, guid);
|
|
12800
|
-
return typeof id === "number" ? id : void 0;
|
|
12801
|
-
}
|
|
12802
|
-
/** GlobalId for an express id, or undefined. Requires {@link buildGuidMap} first. */
|
|
12803
|
-
guidFromExpressId(expressId) {
|
|
12804
|
-
const guid = this.#api.GetGuidFromExpressId(this.modelId, expressId);
|
|
12805
|
-
return typeof guid === "string" ? guid : void 0;
|
|
12806
|
-
}
|
|
12807
|
-
/**
|
|
12808
|
-
* Composed world transform (column-major 16-float matrix) for a placement
|
|
12809
|
-
* express id, resolving the full IfcLocalPlacement chain.
|
|
12810
|
-
*/
|
|
12811
|
-
getWorldTransform(placementExpressId) {
|
|
12812
|
-
return this.#api.GetWorldTransformMatrix(this.modelId, placementExpressId);
|
|
12813
|
-
}
|
|
12814
|
-
/** Streams placed meshes for the given product express ids. */
|
|
12815
|
-
streamMeshes(expressIds, cb) {
|
|
12816
|
-
this.#api.StreamMeshes(this.modelId, expressIds, cb);
|
|
12817
|
-
}
|
|
12818
|
-
/** Geometry buffers for a geometry express id; caller MUST call `.delete()`. */
|
|
12819
|
-
getGeometry(geometryExpressId) {
|
|
12820
|
-
return this.#api.GetGeometry(this.modelId, geometryExpressId);
|
|
12821
|
-
}
|
|
12822
|
-
/** Reads a Float32Array view of vertex data from a WASM pointer. */
|
|
12823
|
-
getVertexArray(ptr, size) {
|
|
12824
|
-
return this.#api.GetVertexArray(ptr, size);
|
|
12825
|
-
}
|
|
12826
|
-
/** Reads a Uint32Array view of index data from a WASM pointer. */
|
|
12827
|
-
getIndexArray(ptr, size) {
|
|
12828
|
-
return this.#api.GetIndexArray(ptr, size);
|
|
12829
|
-
}
|
|
12830
|
-
/** Decodes IFC STEP string escapes (`\X2\`, `\S\`, `\X\`) in a raw value. */
|
|
12831
|
-
decodeText(s) {
|
|
12832
|
-
const decoded = this.#api.DecodeText(s);
|
|
12833
|
-
return typeof decoded === "string" ? decoded : s;
|
|
12834
|
-
}
|
|
12835
|
-
};
|
|
12836
|
-
//#endregion
|
|
12837
13708
|
//#region src/import/spatialTree.ts
|
|
12838
13709
|
var CATEGORY_BY_TYPE = /* @__PURE__ */ new Map([
|
|
12839
13710
|
[web_ifc.IFCPROJECT, "PROJECT"],
|
|
@@ -27026,6 +27897,7 @@ exports.PSET_TEMPLATES = PSET_TEMPLATES;
|
|
|
27026
27897
|
exports.SpfReader = SpfReader;
|
|
27027
27898
|
exports.bcfError = bcfError;
|
|
27028
27899
|
exports.checkGeometryValidity = checkGeometryValidity;
|
|
27900
|
+
exports.checkGherkinRules = checkGherkinRules;
|
|
27029
27901
|
exports.checkIds = checkIdsData;
|
|
27030
27902
|
exports.checkIdsData = checkIdsData;
|
|
27031
27903
|
exports.checkReferentialIntegrity = checkReferentialIntegrity;
|