brepjs-bim 0.16.0 → 0.16.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/dist/brepjs-bim.cjs +1003 -154
- package/dist/brepjs-bim.js +1003 -155
- 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
|
@@ -7804,9 +7804,42 @@ function writeHeader(w, meta) {
|
|
|
7804
7804
|
ownerHistoryId,
|
|
7805
7805
|
geomContextId,
|
|
7806
7806
|
geomSubContextId,
|
|
7807
|
-
unitAssignmentId
|
|
7807
|
+
unitAssignmentId,
|
|
7808
|
+
lengthUnitId
|
|
7808
7809
|
};
|
|
7809
7810
|
}
|
|
7811
|
+
/**
|
|
7812
|
+
* Writes IfcProjectedCRS + IfcMapConversion georeferencing the model context
|
|
7813
|
+
* (GRF003). Coordinates are metres; rotation defaults to identity.
|
|
7814
|
+
*/
|
|
7815
|
+
function writeMapConversion(w, crs, geomContextId, lengthUnitId) {
|
|
7816
|
+
const crsId = w.nextId();
|
|
7817
|
+
w.writeLine({
|
|
7818
|
+
expressID: crsId,
|
|
7819
|
+
type: web_ifc.IFCPROJECTEDCRS,
|
|
7820
|
+
Name: w.mkType(web_ifc.IFCLABEL, crs.name),
|
|
7821
|
+
Description: crs.description !== void 0 ? w.mkType(web_ifc.IFCTEXT, crs.description) : null,
|
|
7822
|
+
GeodeticDatum: crs.geodeticDatum !== void 0 ? w.mkType(web_ifc.IFCIDENTIFIER, crs.geodeticDatum) : null,
|
|
7823
|
+
VerticalDatum: crs.verticalDatum !== void 0 ? w.mkType(web_ifc.IFCIDENTIFIER, crs.verticalDatum) : null,
|
|
7824
|
+
MapProjection: crs.mapProjection !== void 0 ? w.mkType(web_ifc.IFCIDENTIFIER, crs.mapProjection) : null,
|
|
7825
|
+
MapZone: crs.mapZone !== void 0 ? w.mkType(web_ifc.IFCIDENTIFIER, crs.mapZone) : null,
|
|
7826
|
+
MapUnit: w.ref(lengthUnitId)
|
|
7827
|
+
});
|
|
7828
|
+
const conversionId = w.nextId();
|
|
7829
|
+
w.writeLine({
|
|
7830
|
+
expressID: conversionId,
|
|
7831
|
+
type: web_ifc.IFCMAPCONVERSION,
|
|
7832
|
+
SourceCRS: w.ref(geomContextId),
|
|
7833
|
+
TargetCRS: w.ref(crsId),
|
|
7834
|
+
Eastings: w.mkType(web_ifc.IFCLENGTHMEASURE, crs.eastings ?? 0),
|
|
7835
|
+
Northings: w.mkType(web_ifc.IFCLENGTHMEASURE, crs.northings ?? 0),
|
|
7836
|
+
OrthogonalHeight: w.mkType(web_ifc.IFCLENGTHMEASURE, crs.orthogonalHeight ?? 0),
|
|
7837
|
+
XAxisAbscissa: crs.xAxisAbscissa !== void 0 ? w.mkType(web_ifc.IFCREAL, crs.xAxisAbscissa) : null,
|
|
7838
|
+
XAxisOrdinate: crs.xAxisOrdinate !== void 0 ? w.mkType(web_ifc.IFCREAL, crs.xAxisOrdinate) : null,
|
|
7839
|
+
Scale: crs.scale !== void 0 ? w.mkType(web_ifc.IFCREAL, crs.scale) : null
|
|
7840
|
+
});
|
|
7841
|
+
return crsId;
|
|
7842
|
+
}
|
|
7810
7843
|
function writeAxis2Placement3D(w, origin = [
|
|
7811
7844
|
0,
|
|
7812
7845
|
0,
|
|
@@ -9572,12 +9605,56 @@ function writeStairFlightEntity(w, guid, name, flight, ownerHistoryId, localPlac
|
|
|
9572
9605
|
ObjectPlacement: w.ref(localPlacementId),
|
|
9573
9606
|
Representation: w.ref(productDefinitionShapeId),
|
|
9574
9607
|
Tag: null,
|
|
9575
|
-
NumberOfRisers:
|
|
9576
|
-
NumberOfTreads:
|
|
9577
|
-
RiserHeight:
|
|
9578
|
-
TreadLength:
|
|
9608
|
+
NumberOfRisers: null,
|
|
9609
|
+
NumberOfTreads: null,
|
|
9610
|
+
RiserHeight: null,
|
|
9611
|
+
TreadLength: null,
|
|
9579
9612
|
PredefinedType: null
|
|
9580
9613
|
});
|
|
9614
|
+
writeStairFlightCommonPset(w, ownerHistoryId, id, flight);
|
|
9615
|
+
return id;
|
|
9616
|
+
}
|
|
9617
|
+
/** Pset_StairFlightCommon: the standard home for the flight geometry data the
|
|
9618
|
+
* deprecated IfcStairFlight attributes used to carry. Note the standard's
|
|
9619
|
+
* singular `NumberOfRiser`. */
|
|
9620
|
+
function writeStairFlightCommonPset(w, ownerHistoryId, flightExpressId, flight) {
|
|
9621
|
+
const props = [
|
|
9622
|
+
writeSingleValue(w, "NumberOfRiser", w.mkType(web_ifc.IFCCOUNTMEASURE, flight.numberOfRisers)),
|
|
9623
|
+
writeSingleValue(w, "NumberOfTreads", w.mkType(web_ifc.IFCCOUNTMEASURE, flight.numberOfRisers - 1)),
|
|
9624
|
+
writeSingleValue(w, "RiserHeight", w.mkType(web_ifc.IFCPOSITIVELENGTHMEASURE, toIfcLengthM(flight.riserHeight))),
|
|
9625
|
+
writeSingleValue(w, "TreadLength", w.mkType(web_ifc.IFCPOSITIVELENGTHMEASURE, toIfcLengthM(flight.treadLength)))
|
|
9626
|
+
];
|
|
9627
|
+
const psetId = w.nextId();
|
|
9628
|
+
w.writeLine({
|
|
9629
|
+
expressID: psetId,
|
|
9630
|
+
type: web_ifc.IFCPROPERTYSET,
|
|
9631
|
+
GlobalId: w.mkType(web_ifc.IFCGLOBALLYUNIQUEID, w.guidFor(psetId)),
|
|
9632
|
+
OwnerHistory: w.ref(ownerHistoryId),
|
|
9633
|
+
Name: w.mkType(web_ifc.IFCLABEL, "Pset_StairFlightCommon"),
|
|
9634
|
+
Description: null,
|
|
9635
|
+
HasProperties: props.map((id) => w.ref(id))
|
|
9636
|
+
});
|
|
9637
|
+
w.writeLine({
|
|
9638
|
+
expressID: w.nextId(),
|
|
9639
|
+
type: web_ifc.IFCRELDEFINESBYPROPERTIES,
|
|
9640
|
+
GlobalId: w.mkType(web_ifc.IFCGLOBALLYUNIQUEID, w.guidFor(psetId + 1e5)),
|
|
9641
|
+
OwnerHistory: w.ref(ownerHistoryId),
|
|
9642
|
+
Name: null,
|
|
9643
|
+
Description: null,
|
|
9644
|
+
RelatedObjects: [w.ref(flightExpressId)],
|
|
9645
|
+
RelatingPropertyDefinition: w.ref(psetId)
|
|
9646
|
+
});
|
|
9647
|
+
}
|
|
9648
|
+
function writeSingleValue(w, name, value) {
|
|
9649
|
+
const id = w.nextId();
|
|
9650
|
+
w.writeLine({
|
|
9651
|
+
expressID: id,
|
|
9652
|
+
type: web_ifc.IFCPROPERTYSINGLEVALUE,
|
|
9653
|
+
Name: w.mkType(web_ifc.IFCIDENTIFIER, name),
|
|
9654
|
+
Description: null,
|
|
9655
|
+
NominalValue: value,
|
|
9656
|
+
Unit: null
|
|
9657
|
+
});
|
|
9581
9658
|
return id;
|
|
9582
9659
|
}
|
|
9583
9660
|
function writeStairEntity(w, guid, name, _predefinedType, ownerHistoryId, localPlacementId) {
|
|
@@ -11088,12 +11165,11 @@ function writeRoofBaseQuantities(w, ownerHistoryId, roofExpressId, spec) {
|
|
|
11088
11165
|
const widthM = toIfcLengthM(spec.width);
|
|
11089
11166
|
const thicknessM = toIfcLengthM(spec.thickness);
|
|
11090
11167
|
const grossAreaM2 = lengthM * widthM;
|
|
11091
|
-
|
|
11168
|
+
grossAreaM2 * thicknessM;
|
|
11092
11169
|
writeRelDefinesByProperties(w, ownerHistoryId, roofExpressId, writeElementQuantity(w, ownerHistoryId, "Qto_RoofBaseQuantities", [
|
|
11093
11170
|
writeQtyArea(w, "GrossArea", grossAreaM2),
|
|
11094
11171
|
writeQtyArea(w, "NetArea", grossAreaM2),
|
|
11095
|
-
|
|
11096
|
-
writeQtyVolume(w, "NetVolume", grossVolumeM3)
|
|
11172
|
+
writeQtyArea(w, "ProjectedArea", grossAreaM2)
|
|
11097
11173
|
]));
|
|
11098
11174
|
}
|
|
11099
11175
|
function writeCurtainWallCommonPset(w, ownerHistoryId, curtainWallExpressId, spec) {
|
|
@@ -11120,7 +11196,7 @@ function writeFootingBaseQuantities(w, ownerHistoryId, footingExpressId, spec) {
|
|
|
11120
11196
|
writeRelDefinesByProperties(w, ownerHistoryId, footingExpressId, writeElementQuantity(w, ownerHistoryId, "Qto_FootingBaseQuantities", [
|
|
11121
11197
|
writeQtyLength(w, "Length", lengthM),
|
|
11122
11198
|
writeQtyLength(w, "Width", widthM),
|
|
11123
|
-
writeQtyLength(w, "
|
|
11199
|
+
writeQtyLength(w, "Height", depthM),
|
|
11124
11200
|
writeQtyVolume(w, "GrossVolume", grossVolumeM3),
|
|
11125
11201
|
writeQtyVolume(w, "NetVolume", grossVolumeM3)
|
|
11126
11202
|
]));
|
|
@@ -12068,6 +12144,918 @@ async function checkRoundTrip(bytes) {
|
|
|
12068
12144
|
};
|
|
12069
12145
|
}
|
|
12070
12146
|
//#endregion
|
|
12147
|
+
//#region src/import/spfReader.ts
|
|
12148
|
+
var SUPPORTED_SCHEMAS = [
|
|
12149
|
+
"IFC2X3",
|
|
12150
|
+
"IFC4",
|
|
12151
|
+
"IFC4X3"
|
|
12152
|
+
];
|
|
12153
|
+
/**
|
|
12154
|
+
* Foundation layer of the IFC reader: owns the web-ifc WASM model handle and
|
|
12155
|
+
* exposes typed line access, GUID↔expressId lookup, world-transform composition,
|
|
12156
|
+
* geometry-engine access and STEP string decoding.
|
|
12157
|
+
*
|
|
12158
|
+
* Lifecycle: created via the static async {@link SpfReader.create}; the caller
|
|
12159
|
+
* MUST call {@link SpfReader.close} (it always issues `CloseModel`, preventing
|
|
12160
|
+
* WASM handle leaks). The handle is `using`-friendly via `Symbol.dispose`.
|
|
12161
|
+
*/
|
|
12162
|
+
function deleteVector(vec) {
|
|
12163
|
+
vec.delete?.();
|
|
12164
|
+
}
|
|
12165
|
+
var SpfReader = class SpfReader {
|
|
12166
|
+
schema;
|
|
12167
|
+
modelId;
|
|
12168
|
+
#api;
|
|
12169
|
+
#closed = false;
|
|
12170
|
+
#linesByType = /* @__PURE__ */ new Map();
|
|
12171
|
+
constructor(api, modelId, schema) {
|
|
12172
|
+
this.#api = api;
|
|
12173
|
+
this.modelId = modelId;
|
|
12174
|
+
this.schema = schema;
|
|
12175
|
+
}
|
|
12176
|
+
static async create(bytes, settings = {}) {
|
|
12177
|
+
let api;
|
|
12178
|
+
try {
|
|
12179
|
+
api = new web_ifc.IfcAPI();
|
|
12180
|
+
await initIfcApi(api);
|
|
12181
|
+
} catch (e) {
|
|
12182
|
+
return (0, brepjs.err)(importError("OPEN_MODEL_FAILED", "Failed to initialize web-ifc", e));
|
|
12183
|
+
}
|
|
12184
|
+
let modelId;
|
|
12185
|
+
try {
|
|
12186
|
+
modelId = api.OpenModel(bytes, { COORDINATE_TO_ORIGIN: settings.coordinateToOrigin ?? false });
|
|
12187
|
+
} catch (e) {
|
|
12188
|
+
return (0, brepjs.err)(importError("OPEN_MODEL_FAILED", "web-ifc OpenModel threw", e));
|
|
12189
|
+
}
|
|
12190
|
+
if (modelId < 0 || !api.IsModelOpen(modelId)) {
|
|
12191
|
+
if (modelId >= 0) api.CloseModel(modelId);
|
|
12192
|
+
return (0, brepjs.err)(importError("OPEN_MODEL_FAILED", "web-ifc OpenModel returned an invalid model id"));
|
|
12193
|
+
}
|
|
12194
|
+
const schemaRaw = api.GetModelSchema(modelId);
|
|
12195
|
+
if (!SUPPORTED_SCHEMAS.includes(schemaRaw)) {
|
|
12196
|
+
api.CloseModel(modelId);
|
|
12197
|
+
return (0, brepjs.err)(importError("SCHEMA_UNSUPPORTED", `Unsupported IFC schema "${schemaRaw}"`));
|
|
12198
|
+
}
|
|
12199
|
+
return (0, brepjs.ok)(new SpfReader(api, modelId, schemaRaw));
|
|
12200
|
+
}
|
|
12201
|
+
/** Always issues CloseModel; safe to call more than once. */
|
|
12202
|
+
close() {
|
|
12203
|
+
if (this.#closed) return;
|
|
12204
|
+
this.#closed = true;
|
|
12205
|
+
this.#api.CloseModel(this.modelId);
|
|
12206
|
+
}
|
|
12207
|
+
[Symbol.dispose]() {
|
|
12208
|
+
this.close();
|
|
12209
|
+
}
|
|
12210
|
+
/**
|
|
12211
|
+
* Raw line object for an express id. With `flatten=false` (default) references
|
|
12212
|
+
* appear as `{ type, value }` wrappers and nested entities are not resolved;
|
|
12213
|
+
* pass `flatten=true` to recursively inline referenced lines.
|
|
12214
|
+
*/
|
|
12215
|
+
getLine(expressId, flatten = false) {
|
|
12216
|
+
return this.#api.GetLine(this.modelId, expressId, flatten) ?? null;
|
|
12217
|
+
}
|
|
12218
|
+
/** Express ids of every line whose type equals `type` (no inherited types). */
|
|
12219
|
+
getLinesOfType(type) {
|
|
12220
|
+
const cached = this.#linesByType.get(type);
|
|
12221
|
+
if (cached !== void 0) return cached;
|
|
12222
|
+
const vec = this.#api.GetLineIDsWithType(this.modelId, type);
|
|
12223
|
+
const out = [];
|
|
12224
|
+
for (let i = 0; i < vec.size(); i++) out.push(vec.get(i));
|
|
12225
|
+
deleteVector(vec);
|
|
12226
|
+
this.#linesByType.set(type, out);
|
|
12227
|
+
return out;
|
|
12228
|
+
}
|
|
12229
|
+
/** Express ids of every line in the model. */
|
|
12230
|
+
getAllLines() {
|
|
12231
|
+
const vec = this.#api.GetAllLines(this.modelId);
|
|
12232
|
+
const out = [];
|
|
12233
|
+
for (let i = 0; i < vec.size(); i++) out.push(vec.get(i));
|
|
12234
|
+
deleteVector(vec);
|
|
12235
|
+
return out;
|
|
12236
|
+
}
|
|
12237
|
+
/** IFC type code for an express id. */
|
|
12238
|
+
/** Uppercased IFC entity name of the instance (e.g. `IFCWALL`). */
|
|
12239
|
+
typeNameOf(expressId) {
|
|
12240
|
+
return this.#api.GetNameFromTypeCode(this.getLineType(expressId)).toUpperCase();
|
|
12241
|
+
}
|
|
12242
|
+
getLineType(expressId) {
|
|
12243
|
+
const t = this.#api.GetLineType(this.modelId, expressId);
|
|
12244
|
+
return typeof t === "number" ? t : Number(t?.value ?? t);
|
|
12245
|
+
}
|
|
12246
|
+
/** Builds web-ifc's internal GUID→expressId index; call before guid lookups. */
|
|
12247
|
+
buildGuidMap() {
|
|
12248
|
+
this.#api.CreateIfcGuidToExpressIdMapping(this.modelId);
|
|
12249
|
+
}
|
|
12250
|
+
/** expressId for a GlobalId, or undefined. Requires {@link buildGuidMap} first. */
|
|
12251
|
+
expressIdFromGuid(guid) {
|
|
12252
|
+
const id = this.#api.GetExpressIdFromGuid(this.modelId, guid);
|
|
12253
|
+
return typeof id === "number" ? id : void 0;
|
|
12254
|
+
}
|
|
12255
|
+
/** GlobalId for an express id, or undefined. Requires {@link buildGuidMap} first. */
|
|
12256
|
+
guidFromExpressId(expressId) {
|
|
12257
|
+
const guid = this.#api.GetGuidFromExpressId(this.modelId, expressId);
|
|
12258
|
+
return typeof guid === "string" ? guid : void 0;
|
|
12259
|
+
}
|
|
12260
|
+
/**
|
|
12261
|
+
* Composed world transform (column-major 16-float matrix) for a placement
|
|
12262
|
+
* express id, resolving the full IfcLocalPlacement chain.
|
|
12263
|
+
*/
|
|
12264
|
+
getWorldTransform(placementExpressId) {
|
|
12265
|
+
return this.#api.GetWorldTransformMatrix(this.modelId, placementExpressId);
|
|
12266
|
+
}
|
|
12267
|
+
/** Streams placed meshes for the given product express ids. */
|
|
12268
|
+
streamMeshes(expressIds, cb) {
|
|
12269
|
+
this.#api.StreamMeshes(this.modelId, expressIds, cb);
|
|
12270
|
+
}
|
|
12271
|
+
/** Geometry buffers for a geometry express id; caller MUST call `.delete()`. */
|
|
12272
|
+
getGeometry(geometryExpressId) {
|
|
12273
|
+
return this.#api.GetGeometry(this.modelId, geometryExpressId);
|
|
12274
|
+
}
|
|
12275
|
+
/** Reads a Float32Array view of vertex data from a WASM pointer. */
|
|
12276
|
+
getVertexArray(ptr, size) {
|
|
12277
|
+
return this.#api.GetVertexArray(ptr, size);
|
|
12278
|
+
}
|
|
12279
|
+
/** Reads a Uint32Array view of index data from a WASM pointer. */
|
|
12280
|
+
getIndexArray(ptr, size) {
|
|
12281
|
+
return this.#api.GetIndexArray(ptr, size);
|
|
12282
|
+
}
|
|
12283
|
+
/** Decodes IFC STEP string escapes (`\X2\`, `\S\`, `\X\`) in a raw value. */
|
|
12284
|
+
decodeText(s) {
|
|
12285
|
+
const decoded = this.#api.DecodeText(s);
|
|
12286
|
+
return typeof decoded === "string" ? decoded : s;
|
|
12287
|
+
}
|
|
12288
|
+
};
|
|
12289
|
+
//#endregion
|
|
12290
|
+
//#region src/validation/qtoDefinitions.generated.ts
|
|
12291
|
+
var QTO_DEFINITIONS = {
|
|
12292
|
+
"Qto_ActuatorBaseQuantities": {
|
|
12293
|
+
"entities": ["IFCACTUATOR"],
|
|
12294
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12295
|
+
},
|
|
12296
|
+
"Qto_AirTerminalBaseQuantities": {
|
|
12297
|
+
"entities": ["IFCAIRTERMINAL"],
|
|
12298
|
+
"quantities": {
|
|
12299
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12300
|
+
"Perimeter": "IFCQUANTITYLENGTH",
|
|
12301
|
+
"TotalSurfaceArea": "IFCQUANTITYAREA"
|
|
12302
|
+
}
|
|
12303
|
+
},
|
|
12304
|
+
"Qto_AirTerminalBoxTypeBaseQuantities": {
|
|
12305
|
+
"entities": ["IFCAIRTERMINALBOX"],
|
|
12306
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12307
|
+
},
|
|
12308
|
+
"Qto_AirToAirHeatRecoveryBaseQuantities": {
|
|
12309
|
+
"entities": ["IFCAIRTOAIRHEATRECOVERY"],
|
|
12310
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12311
|
+
},
|
|
12312
|
+
"Qto_AlarmBaseQuantities": {
|
|
12313
|
+
"entities": ["IFCALARM"],
|
|
12314
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12315
|
+
},
|
|
12316
|
+
"Qto_AudioVisualApplianceBaseQuantities": {
|
|
12317
|
+
"entities": ["IFCAUDIOVISUALAPPLIANCE"],
|
|
12318
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12319
|
+
},
|
|
12320
|
+
"Qto_BeamBaseQuantities": {
|
|
12321
|
+
"entities": ["IFCBEAM"],
|
|
12322
|
+
"quantities": {
|
|
12323
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12324
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12325
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12326
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12327
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12328
|
+
"NetSurfaceArea": "IFCQUANTITYAREA",
|
|
12329
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12330
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12331
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12332
|
+
}
|
|
12333
|
+
},
|
|
12334
|
+
"Qto_BoilerBaseQuantities": {
|
|
12335
|
+
"entities": ["IFCBOILER"],
|
|
12336
|
+
"quantities": {
|
|
12337
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12338
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12339
|
+
"TotalSurfaceArea": "IFCQUANTITYAREA"
|
|
12340
|
+
}
|
|
12341
|
+
},
|
|
12342
|
+
"Qto_BuildingBaseQuantities": {
|
|
12343
|
+
"entities": ["IFCBUILDING"],
|
|
12344
|
+
"quantities": {
|
|
12345
|
+
"EavesHeight": "IFCQUANTITYLENGTH",
|
|
12346
|
+
"FootprintArea": "IFCQUANTITYAREA",
|
|
12347
|
+
"GrossFloorArea": "IFCQUANTITYAREA",
|
|
12348
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12349
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12350
|
+
"NetFloorArea": "IFCQUANTITYAREA",
|
|
12351
|
+
"NetVolume": "IFCQUANTITYVOLUME"
|
|
12352
|
+
}
|
|
12353
|
+
},
|
|
12354
|
+
"Qto_BuildingElementProxyQuantities": {
|
|
12355
|
+
"entities": ["IFCBUILDINGELEMENTPROXY"],
|
|
12356
|
+
"quantities": {
|
|
12357
|
+
"NetSurfaceArea": "IFCQUANTITYCOUNT",
|
|
12358
|
+
"NetVolume": "IFCQUANTITYCOUNT"
|
|
12359
|
+
}
|
|
12360
|
+
},
|
|
12361
|
+
"Qto_BuildingStoreyBaseQuantities": {
|
|
12362
|
+
"entities": ["IFCBUILDINGSTOREY"],
|
|
12363
|
+
"quantities": {
|
|
12364
|
+
"GrossFloorArea": "IFCQUANTITYAREA",
|
|
12365
|
+
"GrossHeight": "IFCQUANTITYLENGTH",
|
|
12366
|
+
"GrossPerimeter": "IFCQUANTITYLENGTH",
|
|
12367
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12368
|
+
"NetFloorArea": "IFCQUANTITYAREA",
|
|
12369
|
+
"NetHeigtht": "IFCQUANTITYLENGTH",
|
|
12370
|
+
"NetVolume": "IFCQUANTITYVOLUME"
|
|
12371
|
+
}
|
|
12372
|
+
},
|
|
12373
|
+
"Qto_BurnerBaseQuantities": {
|
|
12374
|
+
"entities": ["IFCBURNER"],
|
|
12375
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12376
|
+
},
|
|
12377
|
+
"Qto_CableCarrierFittingBaseQuantities": {
|
|
12378
|
+
"entities": ["IFCCABLECARRIERFITTING"],
|
|
12379
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12380
|
+
},
|
|
12381
|
+
"Qto_CableCarrierSegmentBaseQuantities": {
|
|
12382
|
+
"entities": ["IFCCABLECARRIERSEGMENT"],
|
|
12383
|
+
"quantities": {
|
|
12384
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12385
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12386
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12387
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12388
|
+
}
|
|
12389
|
+
},
|
|
12390
|
+
"Qto_CableFittingBaseQuantities": {
|
|
12391
|
+
"entities": ["IFCCABLEFITTING"],
|
|
12392
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12393
|
+
},
|
|
12394
|
+
"Qto_CableSegmentBaseQuantities": {
|
|
12395
|
+
"entities": ["IFCCABLESEGMENT"],
|
|
12396
|
+
"quantities": {
|
|
12397
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12398
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12399
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12400
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12401
|
+
}
|
|
12402
|
+
},
|
|
12403
|
+
"Qto_ChillerBaseQuantities": {
|
|
12404
|
+
"entities": ["IFCCHILLER"],
|
|
12405
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12406
|
+
},
|
|
12407
|
+
"Qto_ChimneyBaseQuantities": {
|
|
12408
|
+
"entities": ["IFCCHIMNEY"],
|
|
12409
|
+
"quantities": { "Length": "IFCQUANTITYLENGTH" }
|
|
12410
|
+
},
|
|
12411
|
+
"Qto_CoilBaseQuantities": {
|
|
12412
|
+
"entities": ["IFCCOIL"],
|
|
12413
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12414
|
+
},
|
|
12415
|
+
"Qto_ColumnBaseQuantities": {
|
|
12416
|
+
"entities": ["IFCCOLUMN"],
|
|
12417
|
+
"quantities": {
|
|
12418
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12419
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12420
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12421
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12422
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12423
|
+
"NetSurfaceArea": "IFCQUANTITYAREA",
|
|
12424
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12425
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12426
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12427
|
+
}
|
|
12428
|
+
},
|
|
12429
|
+
"Qto_CommunicationsApplianceBaseQuantities": {
|
|
12430
|
+
"entities": ["IFCCOMMUNICATIONSAPPLIANCE"],
|
|
12431
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12432
|
+
},
|
|
12433
|
+
"Qto_CompressorBaseQuantities": {
|
|
12434
|
+
"entities": ["IFCCOMPRESSOR"],
|
|
12435
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12436
|
+
},
|
|
12437
|
+
"Qto_CondenserBaseQuantities": {
|
|
12438
|
+
"entities": ["IFCCONDENSER"],
|
|
12439
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12440
|
+
},
|
|
12441
|
+
"Qto_ConstructionEquipmentResourceBaseQuantities": {
|
|
12442
|
+
"entities": ["IFCCONSTRUCTIONEQUIPMENTRESOURCE"],
|
|
12443
|
+
"quantities": {
|
|
12444
|
+
"OperatingTime": "IFCQUANTITYTIME",
|
|
12445
|
+
"UsageTime": "IFCQUANTITYTIME"
|
|
12446
|
+
}
|
|
12447
|
+
},
|
|
12448
|
+
"Qto_ConstructionMaterialResourceBaseQuantities": {
|
|
12449
|
+
"entities": ["IFCCONSTRUCTIONMATERIALRESOURCE"],
|
|
12450
|
+
"quantities": {
|
|
12451
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12452
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12453
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12454
|
+
"NetWeight": "IFCQUANTITYWEIGHT"
|
|
12455
|
+
}
|
|
12456
|
+
},
|
|
12457
|
+
"Qto_ControllerBaseQuantities": {
|
|
12458
|
+
"entities": ["IFCCONTROLLER"],
|
|
12459
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12460
|
+
},
|
|
12461
|
+
"Qto_CooledBeamBaseQuantities": {
|
|
12462
|
+
"entities": ["IFCCOOLEDBEAM"],
|
|
12463
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12464
|
+
},
|
|
12465
|
+
"Qto_CoolingTowerBaseQuantities": {
|
|
12466
|
+
"entities": ["IFCCOOLINGTOWER"],
|
|
12467
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12468
|
+
},
|
|
12469
|
+
"Qto_CoveringBaseQuantities": {
|
|
12470
|
+
"entities": ["IFCCOVERING"],
|
|
12471
|
+
"quantities": {
|
|
12472
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12473
|
+
"NetArea": "IFCQUANTITYAREA",
|
|
12474
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12475
|
+
}
|
|
12476
|
+
},
|
|
12477
|
+
"Qto_CurtainWallQuantities": {
|
|
12478
|
+
"entities": ["IFCCURTAINWALL"],
|
|
12479
|
+
"quantities": {
|
|
12480
|
+
"GrossSideArea": "IFCQUANTITYAREA",
|
|
12481
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12482
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12483
|
+
"NetSideArea": "IFCQUANTITYAREA",
|
|
12484
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12485
|
+
}
|
|
12486
|
+
},
|
|
12487
|
+
"Qto_DamperBaseQuantities": {
|
|
12488
|
+
"entities": ["IFCDAMPER"],
|
|
12489
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12490
|
+
},
|
|
12491
|
+
"Qto_DistributionChamberElementBaseQuantities": {
|
|
12492
|
+
"entities": ["IFCDISTRIBUTIONCHAMBERELEMENT"],
|
|
12493
|
+
"quantities": {
|
|
12494
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12495
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12496
|
+
"NetSurfaceArea": "IFCQUANTITYAREA",
|
|
12497
|
+
"NetVolume": "IFCQUANTITYVOLUME"
|
|
12498
|
+
}
|
|
12499
|
+
},
|
|
12500
|
+
"Qto_DoorBaseQuantities": {
|
|
12501
|
+
"entities": ["IFCDOOR"],
|
|
12502
|
+
"quantities": {
|
|
12503
|
+
"Area": "IFCQUANTITYAREA",
|
|
12504
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12505
|
+
"Perimeter": "IFCQUANTITYLENGTH",
|
|
12506
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12507
|
+
}
|
|
12508
|
+
},
|
|
12509
|
+
"Qto_DuctFittingBaseQuantities": {
|
|
12510
|
+
"entities": ["IFCDUCTFITTING"],
|
|
12511
|
+
"quantities": {
|
|
12512
|
+
"GrossCrossSectionArea": "IFCQUANTITYAREA",
|
|
12513
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12514
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12515
|
+
"NetCrossSectionArea": "IFCQUANTITYAREA",
|
|
12516
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12517
|
+
}
|
|
12518
|
+
},
|
|
12519
|
+
"Qto_DuctSegmentBaseQuantities": {
|
|
12520
|
+
"entities": ["IFCDUCTSEGMENT"],
|
|
12521
|
+
"quantities": {
|
|
12522
|
+
"GrossCrossSectionArea": "IFCQUANTITYAREA",
|
|
12523
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12524
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12525
|
+
"NetCrossSectionArea": "IFCQUANTITYAREA",
|
|
12526
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12527
|
+
}
|
|
12528
|
+
},
|
|
12529
|
+
"Qto_DuctSilencerBaseQuantities": {
|
|
12530
|
+
"entities": ["IFCDUCTSILENCER"],
|
|
12531
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12532
|
+
},
|
|
12533
|
+
"Qto_ElectricApplianceBaseQuantities": {
|
|
12534
|
+
"entities": ["IFCELECTRICAPPLIANCE"],
|
|
12535
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12536
|
+
},
|
|
12537
|
+
"Qto_ElectricDistributionBoardBaseQuantities": {
|
|
12538
|
+
"entities": ["IFCELECTRICDISTRIBUTIONBOARD"],
|
|
12539
|
+
"quantities": {
|
|
12540
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12541
|
+
"NumberOfCircuits": "IFCQUANTITYCOUNT"
|
|
12542
|
+
}
|
|
12543
|
+
},
|
|
12544
|
+
"Qto_ElectricFlowStorageDeviceBaseQuantities": {
|
|
12545
|
+
"entities": ["IFCELECTRICFLOWSTORAGEDEVICE"],
|
|
12546
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12547
|
+
},
|
|
12548
|
+
"Qto_ElectricGeneratorBaseQuantities": {
|
|
12549
|
+
"entities": ["IFCELECTRICGENERATOR"],
|
|
12550
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12551
|
+
},
|
|
12552
|
+
"Qto_ElectricMotorBaseQuantities": {
|
|
12553
|
+
"entities": ["IFCELECTRICMOTOR"],
|
|
12554
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12555
|
+
},
|
|
12556
|
+
"Qto_ElectricTimeControlBaseQuantities": {
|
|
12557
|
+
"entities": ["IFCELECTRICTIMECONTROL"],
|
|
12558
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12559
|
+
},
|
|
12560
|
+
"Qto_EvaporativeCoolerBaseQuantities": {
|
|
12561
|
+
"entities": ["IFCEVAPORATIVECOOLER"],
|
|
12562
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12563
|
+
},
|
|
12564
|
+
"Qto_EvaporatorBaseQuantities": {
|
|
12565
|
+
"entities": ["IFCEVAPORATOR"],
|
|
12566
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12567
|
+
},
|
|
12568
|
+
"Qto_FanBaseQuantities": {
|
|
12569
|
+
"entities": ["IFCFAN"],
|
|
12570
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12571
|
+
},
|
|
12572
|
+
"Qto_FilterBaseQuantities": {
|
|
12573
|
+
"entities": ["IFCFILTER"],
|
|
12574
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12575
|
+
},
|
|
12576
|
+
"Qto_FireSuppressionTerminalBaseQuantities": {
|
|
12577
|
+
"entities": ["IFCFIRESUPPRESSIONTERMINAL"],
|
|
12578
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12579
|
+
},
|
|
12580
|
+
"Qto_FlowInstrumentBaseQuantities": {
|
|
12581
|
+
"entities": ["IFCFLOWINSTRUMENT"],
|
|
12582
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12583
|
+
},
|
|
12584
|
+
"Qto_FlowMeterBaseQuantities": {
|
|
12585
|
+
"entities": ["IFCFLOWMETER"],
|
|
12586
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12587
|
+
},
|
|
12588
|
+
"Qto_FootingBaseQuantities": {
|
|
12589
|
+
"entities": ["IFCFOOTING"],
|
|
12590
|
+
"quantities": {
|
|
12591
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12592
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12593
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12594
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12595
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12596
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12597
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12598
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12599
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA",
|
|
12600
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12601
|
+
}
|
|
12602
|
+
},
|
|
12603
|
+
"Qto_HeatExchangerBaseQuantities": {
|
|
12604
|
+
"entities": ["IFCHEATEXCHANGER"],
|
|
12605
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12606
|
+
},
|
|
12607
|
+
"Qto_HumidifierBaseQuantities": {
|
|
12608
|
+
"entities": ["IFCHUMIDIFIER"],
|
|
12609
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12610
|
+
},
|
|
12611
|
+
"Qto_InterceptorBaseQuantities": {
|
|
12612
|
+
"entities": ["IFCINTERCEPTOR"],
|
|
12613
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12614
|
+
},
|
|
12615
|
+
"Qto_JunctionBoxBaseQuantities": {
|
|
12616
|
+
"entities": ["IFCJUNCTIONBOX"],
|
|
12617
|
+
"quantities": {
|
|
12618
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12619
|
+
"NumberOfGangs": "IFCQUANTITYCOUNT"
|
|
12620
|
+
}
|
|
12621
|
+
},
|
|
12622
|
+
"Qto_LaborResourceBaseQuantities": {
|
|
12623
|
+
"entities": ["IFCLABORRESOURCE"],
|
|
12624
|
+
"quantities": {
|
|
12625
|
+
"OvertimeWork": "IFCQUANTITYTIME",
|
|
12626
|
+
"StandardWork": "IFCQUANTITYTIME"
|
|
12627
|
+
}
|
|
12628
|
+
},
|
|
12629
|
+
"Qto_LampBaseQuantities": {
|
|
12630
|
+
"entities": ["IFCLAMP"],
|
|
12631
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12632
|
+
},
|
|
12633
|
+
"Qto_LightFixtureBaseQuantities": {
|
|
12634
|
+
"entities": ["IFCLIGHTFIXTURE"],
|
|
12635
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12636
|
+
},
|
|
12637
|
+
"Qto_MemberBaseQuantities": {
|
|
12638
|
+
"entities": ["IFCMEMBER"],
|
|
12639
|
+
"quantities": {
|
|
12640
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12641
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12642
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12643
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12644
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12645
|
+
"NetSurfaceArea": "IFCQUANTITYAREA",
|
|
12646
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12647
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12648
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12649
|
+
}
|
|
12650
|
+
},
|
|
12651
|
+
"Qto_MotorConnectionBaseQuantities": {
|
|
12652
|
+
"entities": ["IFCMOTORCONNECTION"],
|
|
12653
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12654
|
+
},
|
|
12655
|
+
"Qto_OpeningElementBaseQuantities": {
|
|
12656
|
+
"entities": ["IFCOPENINGELEMENT"],
|
|
12657
|
+
"quantities": {
|
|
12658
|
+
"Area": "IFCQUANTITYAREA",
|
|
12659
|
+
"Depth": "IFCQUANTITYLENGTH",
|
|
12660
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12661
|
+
"Volume": "IFCQUANTITYVOLUME",
|
|
12662
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12663
|
+
}
|
|
12664
|
+
},
|
|
12665
|
+
"Qto_OutletBaseQuantities": {
|
|
12666
|
+
"entities": ["IFCOUTLET"],
|
|
12667
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12668
|
+
},
|
|
12669
|
+
"Qto_PileBaseQuantities": {
|
|
12670
|
+
"entities": ["IFCPILE"],
|
|
12671
|
+
"quantities": {
|
|
12672
|
+
"CrossSectionArea": "IFCQUANTITYAREA",
|
|
12673
|
+
"GrossSurfaceArea": "IFCQUANTITYAREA",
|
|
12674
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12675
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12676
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12677
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12678
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12679
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12680
|
+
}
|
|
12681
|
+
},
|
|
12682
|
+
"Qto_PipeFittingBaseQuantities": {
|
|
12683
|
+
"entities": ["IFCPIPEFITTING"],
|
|
12684
|
+
"quantities": {
|
|
12685
|
+
"GrossCrossSectionArea": "IFCQUANTITYAREA",
|
|
12686
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12687
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12688
|
+
"NetCrossSectionArea": "IFCQUANTITYAREA",
|
|
12689
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12690
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12691
|
+
}
|
|
12692
|
+
},
|
|
12693
|
+
"Qto_PipeSegmentBaseQuantities": {
|
|
12694
|
+
"entities": ["IFCPIPESEGMENT"],
|
|
12695
|
+
"quantities": {
|
|
12696
|
+
"GrossCrossSectionArea": "IFCQUANTITYAREA",
|
|
12697
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12698
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12699
|
+
"NetCrossSectionArea": "IFCQUANTITYAREA",
|
|
12700
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12701
|
+
"OuterSurfaceArea": "IFCQUANTITYAREA"
|
|
12702
|
+
}
|
|
12703
|
+
},
|
|
12704
|
+
"Qto_PlateBaseQuantities": {
|
|
12705
|
+
"entities": ["IFCPLATE"],
|
|
12706
|
+
"quantities": {
|
|
12707
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12708
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12709
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12710
|
+
"NetArea": "IFCQUANTITYAREA",
|
|
12711
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12712
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12713
|
+
"Perimeter": "IFCQUANTITYLENGTH",
|
|
12714
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12715
|
+
}
|
|
12716
|
+
},
|
|
12717
|
+
"Qto_ProjectionElementBaseQuantities": {
|
|
12718
|
+
"entities": ["IFCPROJECTIONELEMENT"],
|
|
12719
|
+
"quantities": {
|
|
12720
|
+
"Area": "IFCQUANTITYAREA",
|
|
12721
|
+
"Volume": "IFCQUANTITYVOLUME"
|
|
12722
|
+
}
|
|
12723
|
+
},
|
|
12724
|
+
"Qto_ProtectiveDeviceBaseQuantities": {
|
|
12725
|
+
"entities": ["IFCPROTECTIVEDEVICE"],
|
|
12726
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12727
|
+
},
|
|
12728
|
+
"Qto_ProtectiveDeviceTrippingUnitBaseQuantities": {
|
|
12729
|
+
"entities": ["IFCPROTECTIVEDEVICETRIPPINGUNIT"],
|
|
12730
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12731
|
+
},
|
|
12732
|
+
"Qto_PumpBaseQuantities": {
|
|
12733
|
+
"entities": ["IFCPUMP"],
|
|
12734
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12735
|
+
},
|
|
12736
|
+
"Qto_RailingBaseQuantities": {
|
|
12737
|
+
"entities": ["IFCRAILING"],
|
|
12738
|
+
"quantities": { "Length": "IFCQUANTITYLENGTH" }
|
|
12739
|
+
},
|
|
12740
|
+
"Qto_RampFlightBaseQuantities": {
|
|
12741
|
+
"entities": ["IFCRAMPFLIGHT"],
|
|
12742
|
+
"quantities": {
|
|
12743
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12744
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12745
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12746
|
+
"NetArea": "IFCQUANTITYAREA",
|
|
12747
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12748
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12749
|
+
}
|
|
12750
|
+
},
|
|
12751
|
+
"Qto_ReinforcingElementBaseQuantities": {
|
|
12752
|
+
"entities": ["IFCREINFORCINGELEMENT"],
|
|
12753
|
+
"quantities": {
|
|
12754
|
+
"Count": "IFCQUANTITYCOUNT",
|
|
12755
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12756
|
+
"Weight": "IFCQUANTITYWEIGHT"
|
|
12757
|
+
}
|
|
12758
|
+
},
|
|
12759
|
+
"Qto_RoofBaseQuantities": {
|
|
12760
|
+
"entities": ["IFCROOF"],
|
|
12761
|
+
"quantities": {
|
|
12762
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12763
|
+
"NetArea": "IFCQUANTITYAREA",
|
|
12764
|
+
"ProjectedArea": "IFCQUANTITYAREA"
|
|
12765
|
+
}
|
|
12766
|
+
},
|
|
12767
|
+
"Qto_SanitaryTerminalBaseQuantities": {
|
|
12768
|
+
"entities": ["IFCSANITARYTERMINAL"],
|
|
12769
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12770
|
+
},
|
|
12771
|
+
"Qto_SensorBaseQuantities": {
|
|
12772
|
+
"entities": ["IFCSENSOR"],
|
|
12773
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12774
|
+
},
|
|
12775
|
+
"Qto_SiteBaseQuantities": {
|
|
12776
|
+
"entities": ["IFCSITE"],
|
|
12777
|
+
"quantities": {
|
|
12778
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12779
|
+
"GrossPerimeter": "IFCQUANTITYLENGTH"
|
|
12780
|
+
}
|
|
12781
|
+
},
|
|
12782
|
+
"Qto_SlabBaseQuantities": {
|
|
12783
|
+
"entities": ["IFCSLAB"],
|
|
12784
|
+
"quantities": {
|
|
12785
|
+
"Depth": "IFCQUANTITYLENGTH",
|
|
12786
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12787
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12788
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12789
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12790
|
+
"NetArea": "IFCQUANTITYAREA",
|
|
12791
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12792
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12793
|
+
"Perimeter": "IFCQUANTITYLENGTH",
|
|
12794
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12795
|
+
}
|
|
12796
|
+
},
|
|
12797
|
+
"Qto_SolarDeviceBaseQuantities": {
|
|
12798
|
+
"entities": ["IFCSOLARDEVICE"],
|
|
12799
|
+
"quantities": {
|
|
12800
|
+
"GrossArea": "IFCQUANTITYAREA",
|
|
12801
|
+
"GrossWeight": "IFCQUANTITYWEIGHT"
|
|
12802
|
+
}
|
|
12803
|
+
},
|
|
12804
|
+
"Qto_SpaceBaseQuantities": {
|
|
12805
|
+
"entities": ["IFCSPACE"],
|
|
12806
|
+
"quantities": {
|
|
12807
|
+
"FinishCeilingHeight": "IFCQUANTITYLENGTH",
|
|
12808
|
+
"FinishFloorHeight": "IFCQUANTITYLENGTH",
|
|
12809
|
+
"GrossCeilingArea": "IFCQUANTITYAREA",
|
|
12810
|
+
"GrossFloorArea": "IFCQUANTITYAREA",
|
|
12811
|
+
"GrossPerimeter": "IFCQUANTITYLENGTH",
|
|
12812
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12813
|
+
"GrossWallArea": "IFCQUANTITYAREA",
|
|
12814
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12815
|
+
"NetCeilingArea": "IFCQUANTITYAREA",
|
|
12816
|
+
"NetFloorArea": "IFCQUANTITYAREA",
|
|
12817
|
+
"NetPerimeter": "IFCQUANTITYLENGTH",
|
|
12818
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12819
|
+
"NetWallArea": "IFCQUANTITYAREA"
|
|
12820
|
+
}
|
|
12821
|
+
},
|
|
12822
|
+
"Qto_SpaceHeaterBaseQuantities": {
|
|
12823
|
+
"entities": ["IFCSPACEHEATER"],
|
|
12824
|
+
"quantities": {
|
|
12825
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12826
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12827
|
+
"NetWeight": "IFCQUANTITYWEIGHT"
|
|
12828
|
+
}
|
|
12829
|
+
},
|
|
12830
|
+
"Qto_StackTerminalBaseQuantities": {
|
|
12831
|
+
"entities": ["IFCSTACKTERMINAL"],
|
|
12832
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12833
|
+
},
|
|
12834
|
+
"Qto_StairFlightBaseQuantities": {
|
|
12835
|
+
"entities": ["IFCSTAIRFLIGHT"],
|
|
12836
|
+
"quantities": {
|
|
12837
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12838
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12839
|
+
"NetVolume": "IFCQUANTITYVOLUME"
|
|
12840
|
+
}
|
|
12841
|
+
},
|
|
12842
|
+
"Qto_SwitchingDeviceBaseQuantities": {
|
|
12843
|
+
"entities": ["IFCSWITCHINGDEVICE"],
|
|
12844
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12845
|
+
},
|
|
12846
|
+
"Qto_TankBaseQuantities": {
|
|
12847
|
+
"entities": ["IFCTANK"],
|
|
12848
|
+
"quantities": {
|
|
12849
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12850
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12851
|
+
"TotalSurfaceArea": "IFCQUANTITYAREA"
|
|
12852
|
+
}
|
|
12853
|
+
},
|
|
12854
|
+
"Qto_TransformerBaseQuantities": {
|
|
12855
|
+
"entities": ["IFCTRANSFORMER"],
|
|
12856
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12857
|
+
},
|
|
12858
|
+
"Qto_TubeBundleBaseQuantities": {
|
|
12859
|
+
"entities": ["IFCTUBEBUNDLE"],
|
|
12860
|
+
"quantities": {
|
|
12861
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12862
|
+
"NetWeight": "IFCQUANTITYWEIGHT"
|
|
12863
|
+
}
|
|
12864
|
+
},
|
|
12865
|
+
"Qto_UnitaryControlElementBaseQuantities": {
|
|
12866
|
+
"entities": ["IFCUNITARYCONTROLELEMENT"],
|
|
12867
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12868
|
+
},
|
|
12869
|
+
"Qto_UnitaryEquipmentBaseQuantities": {
|
|
12870
|
+
"entities": ["IFCUNITARYEQUIPMENT"],
|
|
12871
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12872
|
+
},
|
|
12873
|
+
"Qto_ValveBaseQuantities": {
|
|
12874
|
+
"entities": ["IFCVALVE"],
|
|
12875
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12876
|
+
},
|
|
12877
|
+
"Qto_VibrationIsolatorBaseQuantities": {
|
|
12878
|
+
"entities": ["IFCVIBRATIONISOLATOR"],
|
|
12879
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12880
|
+
},
|
|
12881
|
+
"Qto_WallBaseQuantities": {
|
|
12882
|
+
"entities": ["IFCWALL"],
|
|
12883
|
+
"quantities": {
|
|
12884
|
+
"GrossFootprintArea": "IFCQUANTITYAREA",
|
|
12885
|
+
"GrossSideArea": "IFCQUANTITYAREA",
|
|
12886
|
+
"GrossVolume": "IFCQUANTITYVOLUME",
|
|
12887
|
+
"GrossWeight": "IFCQUANTITYWEIGHT",
|
|
12888
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12889
|
+
"Length": "IFCQUANTITYLENGTH",
|
|
12890
|
+
"NetFootprintArea": "IFCQUANTITYAREA",
|
|
12891
|
+
"NetSideArea": "IFCQUANTITYAREA",
|
|
12892
|
+
"NetVolume": "IFCQUANTITYVOLUME",
|
|
12893
|
+
"NetWeight": "IFCQUANTITYWEIGHT",
|
|
12894
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12895
|
+
}
|
|
12896
|
+
},
|
|
12897
|
+
"Qto_WasteTerminalBaseQuantities": {
|
|
12898
|
+
"entities": ["IFCWASTETERMINAL"],
|
|
12899
|
+
"quantities": { "GrossWeight": "IFCQUANTITYWEIGHT" }
|
|
12900
|
+
},
|
|
12901
|
+
"Qto_WindowBaseQuantities": {
|
|
12902
|
+
"entities": ["IFCWINDOW"],
|
|
12903
|
+
"quantities": {
|
|
12904
|
+
"Area": "IFCQUANTITYAREA",
|
|
12905
|
+
"Height": "IFCQUANTITYLENGTH",
|
|
12906
|
+
"Perimeter": "IFCQUANTITYLENGTH",
|
|
12907
|
+
"Width": "IFCQUANTITYLENGTH"
|
|
12908
|
+
}
|
|
12909
|
+
}
|
|
12910
|
+
};
|
|
12911
|
+
//#endregion
|
|
12912
|
+
//#region src/validation/gherkinChecks.ts
|
|
12913
|
+
/**
|
|
12914
|
+
* Local implementations of the buildingSMART Validation Service's gherkin
|
|
12915
|
+
* normative rules that apply to the entity vocabulary this writer emits:
|
|
12916
|
+
*
|
|
12917
|
+
* - IFC102 — absence of deprecated entities and attributes (IFC4 lists from
|
|
12918
|
+
* the official rule definition).
|
|
12919
|
+
* - QTY001 — every `Qto_*` element quantity uses the standard set name,
|
|
12920
|
+
* quantity names, quantity entity types, applicable element, and
|
|
12921
|
+
* `MethodOfMeasurement='BaseQuantities'` (table generated from the official
|
|
12922
|
+
* qto_definitions.csv).
|
|
12923
|
+
* - GRF003 — a model containing facilities (IfcBuilding) declares a
|
|
12924
|
+
* coordinate reference system (warning severity, like the service).
|
|
12925
|
+
*
|
|
12926
|
+
* These run inside `toIfcValidated`, so the local gate covers the gherkin
|
|
12927
|
+
* layer before anything is uploaded.
|
|
12928
|
+
*/
|
|
12929
|
+
async function checkGherkinRules(bytes) {
|
|
12930
|
+
const readerResult = await SpfReader.create(bytes);
|
|
12931
|
+
if (!readerResult.ok) return [issue("error", "PARSE_FAILED", `Could not open the model: ${readerResult.error.message}`)];
|
|
12932
|
+
const reader = readerResult.value;
|
|
12933
|
+
try {
|
|
12934
|
+
return [
|
|
12935
|
+
...checkDeprecated(reader),
|
|
12936
|
+
...checkQuantitySets(reader),
|
|
12937
|
+
...checkGeoreferencing(reader)
|
|
12938
|
+
];
|
|
12939
|
+
} finally {
|
|
12940
|
+
reader.close();
|
|
12941
|
+
}
|
|
12942
|
+
}
|
|
12943
|
+
/** IFC4 deprecated entities (IFC102, official rule table). */
|
|
12944
|
+
var DEPRECATED_IFC4_ENTITIES = [
|
|
12945
|
+
"IFC2DCOMPOSITECURVE",
|
|
12946
|
+
"IFCBEAMSTANDARDCASE",
|
|
12947
|
+
"IFCCONNECTIONPORTGEOMETRY",
|
|
12948
|
+
"IFCCOLUMNSTANDARDCASE",
|
|
12949
|
+
"IFCDOORSTANDARDCASE",
|
|
12950
|
+
"IFCDOORSTYLE",
|
|
12951
|
+
"IFCELECTRICALELEMENT",
|
|
12952
|
+
"IFCEQUIPMENTELEMENT",
|
|
12953
|
+
"IFCFACEBASEDSURFACEMODEL",
|
|
12954
|
+
"IFCMATERIALCLASSIFICATIONRELATIONSHIP",
|
|
12955
|
+
"IFCMATERIALLIST",
|
|
12956
|
+
"IFCMEMBERSTANDARDCASE",
|
|
12957
|
+
"IFCOPENINGSTANDARDCASE",
|
|
12958
|
+
"IFCPLATESTANDARDCASE",
|
|
12959
|
+
"IFCPRESENTATIONSTYLEASSIGNMENT",
|
|
12960
|
+
"IFCPROXY",
|
|
12961
|
+
"IFCRELCOVERSBLDGELEMENTS",
|
|
12962
|
+
"IFCRELCOVERSSPACES",
|
|
12963
|
+
"IFCSLABELEMENTEDCASE",
|
|
12964
|
+
"IFCSLABSTANDARDCASE",
|
|
12965
|
+
"IFCTEXTLITERAL",
|
|
12966
|
+
"IFCWALLELEMENTEDCASE",
|
|
12967
|
+
"IFCWALLSTANDARDCASE",
|
|
12968
|
+
"IFCWINDOWSTANDARDCASE",
|
|
12969
|
+
"IFCWINDOWSTYLE"
|
|
12970
|
+
];
|
|
12971
|
+
/** IFC4 deprecated attributes (IFC102): entity -> attributes that must be empty. */
|
|
12972
|
+
var DEPRECATED_IFC4_ATTRIBUTES = {
|
|
12973
|
+
IFCDOORLININGPROPERTIES: ["ShapeAspectStyle"],
|
|
12974
|
+
IFCDOORPANELPROPERTIES: ["ShapeAspectStyle"],
|
|
12975
|
+
IFCFILLAREASTYLEHATCHING: ["PointOfReferenceHatchLine"],
|
|
12976
|
+
IFCREINFORCINGELEMENT: ["SteelGrade"],
|
|
12977
|
+
IFCRELASSIGNSTOACTOR: ["RelatedObjectsType"],
|
|
12978
|
+
IFCRELASSIGNSTOCONTROL: ["RelatedObjectsType"],
|
|
12979
|
+
IFCRELASSIGNSTOGROUP: ["RelatedObjectsType"],
|
|
12980
|
+
IFCRELASSIGNSTOGROUPBYFACTOR: ["RelatedObjectsType"],
|
|
12981
|
+
IFCRELASSIGNSTOPROCESS: ["RelatedObjectsType"],
|
|
12982
|
+
IFCRELASSIGNSTOPRODUCT: ["RelatedObjectsType"],
|
|
12983
|
+
IFCRELASSIGNSTORESOURCE: ["RelatedObjectsType"],
|
|
12984
|
+
IFCSTAIRFLIGHT: [
|
|
12985
|
+
"NumberOfRisers",
|
|
12986
|
+
"NumberOfTreads",
|
|
12987
|
+
"RiserHeight",
|
|
12988
|
+
"TreadLength"
|
|
12989
|
+
],
|
|
12990
|
+
IFCWINDOWPANELPROPERTIES: ["ShapeAspectStyle"],
|
|
12991
|
+
IFCWINDOWLININGPROPERTIES: ["ShapeAspectStyle"]
|
|
12992
|
+
};
|
|
12993
|
+
function checkDeprecated(reader) {
|
|
12994
|
+
const issues = [];
|
|
12995
|
+
if (reader.schema !== "IFC4") return issues;
|
|
12996
|
+
for (const id of reader.getAllLines()) {
|
|
12997
|
+
const typeName = reader.typeNameOf(id);
|
|
12998
|
+
if (DEPRECATED_IFC4_ENTITIES.includes(typeName)) {
|
|
12999
|
+
issues.push(issue("error", "DEPRECATED_ENTITY", `#${id} ${typeName} is deprecated in IFC4 (IFC102)`, id));
|
|
13000
|
+
continue;
|
|
13001
|
+
}
|
|
13002
|
+
const attrs = DEPRECATED_IFC4_ATTRIBUTES[typeName];
|
|
13003
|
+
if (attrs === void 0) continue;
|
|
13004
|
+
const line = reader.getLine(id);
|
|
13005
|
+
if (line === null) continue;
|
|
13006
|
+
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));
|
|
13007
|
+
}
|
|
13008
|
+
return issues;
|
|
13009
|
+
}
|
|
13010
|
+
function textOf(v) {
|
|
13011
|
+
const value = v?.value;
|
|
13012
|
+
return typeof value === "string" ? value : void 0;
|
|
13013
|
+
}
|
|
13014
|
+
function checkQuantitySets(reader) {
|
|
13015
|
+
const issues = [];
|
|
13016
|
+
const related = /* @__PURE__ */ new Map();
|
|
13017
|
+
for (const relId of reader.getLinesOfType(web_ifc.IFCRELDEFINESBYPROPERTIES)) {
|
|
13018
|
+
const rel = reader.getLine(relId);
|
|
13019
|
+
if (rel === null) continue;
|
|
13020
|
+
const target = rel["RelatingPropertyDefinition"]?.value;
|
|
13021
|
+
if (typeof target !== "number") continue;
|
|
13022
|
+
const objects = rel["RelatedObjects"];
|
|
13023
|
+
if (!Array.isArray(objects)) continue;
|
|
13024
|
+
const names = objects.map((o) => o.value).filter((v) => typeof v === "number").map((id) => reader.typeNameOf(id));
|
|
13025
|
+
related.set(target, [...related.get(target) ?? [], ...names]);
|
|
13026
|
+
}
|
|
13027
|
+
for (const id of reader.getLinesOfType(web_ifc.IFCELEMENTQUANTITY)) {
|
|
13028
|
+
const line = reader.getLine(id);
|
|
13029
|
+
if (line === null) continue;
|
|
13030
|
+
const name = textOf(line["Name"]);
|
|
13031
|
+
if (name === void 0 || !name.startsWith("Qto_")) continue;
|
|
13032
|
+
const definition = QTO_DEFINITIONS[name];
|
|
13033
|
+
if (definition === void 0) {
|
|
13034
|
+
issues.push(issue("error", "QTO_UNKNOWN_SET", `#${id} '${name}' is not a standard quantity set (QTY001)`, id));
|
|
13035
|
+
continue;
|
|
13036
|
+
}
|
|
13037
|
+
if (textOf(line["MethodOfMeasurement"]) !== "BaseQuantities") issues.push(issue("error", "QTO_METHOD", `#${id} '${name}' must declare MethodOfMeasurement='BaseQuantities' (QTY001)`, id));
|
|
13038
|
+
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));
|
|
13039
|
+
const quantities = line["Quantities"];
|
|
13040
|
+
if (!Array.isArray(quantities)) continue;
|
|
13041
|
+
for (const q of quantities) {
|
|
13042
|
+
const qid = q.value;
|
|
13043
|
+
if (typeof qid !== "number") continue;
|
|
13044
|
+
const qName = textOf(reader.getLine(qid)?.["Name"]);
|
|
13045
|
+
if (qName === void 0) continue;
|
|
13046
|
+
const expectedType = definition.quantities[qName];
|
|
13047
|
+
if (expectedType === void 0) issues.push(issue("error", "QTO_UNKNOWN_QUANTITY", `#${qid} '${qName}' is not defined in ${name} (QTY001)`, qid));
|
|
13048
|
+
else if (reader.typeNameOf(qid) !== expectedType) issues.push(issue("error", "QTO_WRONG_TYPE", `#${qid} '${qName}' must be a ${expectedType} (QTY001)`, qid));
|
|
13049
|
+
}
|
|
13050
|
+
}
|
|
13051
|
+
return issues;
|
|
13052
|
+
}
|
|
13053
|
+
function checkGeoreferencing(reader) {
|
|
13054
|
+
if (!(reader.getLinesOfType(web_ifc.IFCBUILDING).length > 0)) return [];
|
|
13055
|
+
if (reader.getLinesOfType(web_ifc.IFCPROJECTEDCRS).length > 0 || reader.getLinesOfType(web_ifc.IFCGEOGRAPHICCRS).length > 0) return [];
|
|
13056
|
+
return [issue("warning", "NO_GEOREFERENCING", "Model contains a facility but no IfcProjectedCRS/IfcGeographicCRS (GRF003) — set ProjectSpec.crs")];
|
|
13057
|
+
}
|
|
13058
|
+
//#endregion
|
|
12071
13059
|
//#region src/serialize/toIfc.ts
|
|
12072
13060
|
async function toIfc(model, meta) {
|
|
12073
13061
|
const project = model.getProject();
|
|
@@ -12101,7 +13089,8 @@ async function toIfc(model, meta) {
|
|
|
12101
13089
|
const assemblies = model.getElementAssemblies();
|
|
12102
13090
|
const zones = model.getZones();
|
|
12103
13091
|
const systems = model.getSystems();
|
|
12104
|
-
const { ownerHistoryId, geomContextId, geomSubContextId, unitAssignmentId } = writeHeader(w, meta);
|
|
13092
|
+
const { ownerHistoryId, geomContextId, geomSubContextId, unitAssignmentId, lengthUnitId } = writeHeader(w, meta);
|
|
13093
|
+
if (project.spec.crs !== void 0) writeMapConversion(w, project.spec.crs, geomContextId, lengthUnitId);
|
|
12105
13094
|
const densityByElement = buildDensityMap(relationships);
|
|
12106
13095
|
const idMap = /* @__PURE__ */ new Map();
|
|
12107
13096
|
const placementMap = /* @__PURE__ */ new Map();
|
|
@@ -12602,11 +13591,13 @@ async function toIfcValidated(model, meta) {
|
|
|
12602
13591
|
const geometry = collectGeometryIssues(model);
|
|
12603
13592
|
const schema = await checkSchema(bytes);
|
|
12604
13593
|
const roundTrip = await checkRoundTrip(bytes);
|
|
13594
|
+
const gherkin = await checkGherkinRules(bytes);
|
|
12605
13595
|
const report = { issues: [
|
|
12606
13596
|
...integrity.issues,
|
|
12607
13597
|
...geometry.issues,
|
|
12608
13598
|
...schema.issues,
|
|
12609
|
-
...roundTrip.issues
|
|
13599
|
+
...roundTrip.issues,
|
|
13600
|
+
...gherkin
|
|
12610
13601
|
] };
|
|
12611
13602
|
return (0, brepjs.ok)({
|
|
12612
13603
|
bytes,
|
|
@@ -12691,149 +13682,6 @@ function findContainerOf(elementId, relationships) {
|
|
|
12691
13682
|
return null;
|
|
12692
13683
|
}
|
|
12693
13684
|
//#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
13685
|
//#region src/import/spatialTree.ts
|
|
12838
13686
|
var CATEGORY_BY_TYPE = /* @__PURE__ */ new Map([
|
|
12839
13687
|
[web_ifc.IFCPROJECT, "PROJECT"],
|
|
@@ -27026,6 +27874,7 @@ exports.PSET_TEMPLATES = PSET_TEMPLATES;
|
|
|
27026
27874
|
exports.SpfReader = SpfReader;
|
|
27027
27875
|
exports.bcfError = bcfError;
|
|
27028
27876
|
exports.checkGeometryValidity = checkGeometryValidity;
|
|
27877
|
+
exports.checkGherkinRules = checkGherkinRules;
|
|
27029
27878
|
exports.checkIds = checkIdsData;
|
|
27030
27879
|
exports.checkIdsData = checkIdsData;
|
|
27031
27880
|
exports.checkReferentialIntegrity = checkReferentialIntegrity;
|