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