@ifc-lite/export 4.0.1 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/anonymize-export.d.ts.map +1 -1
- package/dist/anonymize-export.js +10 -4
- package/dist/anonymize-export.js.map +1 -1
- package/dist/anonymize-placement.d.ts.map +1 -1
- package/dist/anonymize-placement.js +5 -6
- package/dist/anonymize-placement.js.map +1 -1
- package/dist/appearance-dependencies.d.ts +12 -0
- package/dist/appearance-dependencies.d.ts.map +1 -0
- package/dist/appearance-dependencies.js +195 -0
- package/dist/appearance-dependencies.js.map +1 -0
- package/dist/authored-resource-cleanup.d.ts +14 -0
- package/dist/authored-resource-cleanup.d.ts.map +1 -0
- package/dist/authored-resource-cleanup.js +156 -0
- package/dist/authored-resource-cleanup.js.map +1 -0
- package/dist/csv-table.d.ts +10 -0
- package/dist/csv-table.d.ts.map +1 -0
- package/dist/csv-table.js +39 -0
- package/dist/csv-table.js.map +1 -0
- package/dist/effective-appearance-record.d.ts +8 -0
- package/dist/effective-appearance-record.d.ts.map +1 -0
- package/dist/effective-appearance-record.js +49 -0
- package/dist/effective-appearance-record.js.map +1 -0
- package/dist/ifc5-appearance.d.ts +20 -0
- package/dist/ifc5-appearance.d.ts.map +1 -0
- package/dist/ifc5-appearance.js +106 -0
- package/dist/ifc5-appearance.js.map +1 -0
- package/dist/ifc5-export-helpers.d.ts +19 -0
- package/dist/ifc5-export-helpers.d.ts.map +1 -1
- package/dist/ifc5-export-helpers.js +41 -0
- package/dist/ifc5-export-helpers.js.map +1 -1
- package/dist/ifc5-exporter.d.ts +12 -10
- package/dist/ifc5-exporter.d.ts.map +1 -1
- package/dist/ifc5-exporter.js +24 -41
- package/dist/ifc5-exporter.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/lod0-generator.js +1 -1
- package/dist/lod0-generator.js.map +1 -1
- package/dist/merged-context.d.ts.map +1 -1
- package/dist/merged-context.js +15 -1
- package/dist/merged-context.js.map +1 -1
- package/dist/merged-empty-containers.d.ts.map +1 -1
- package/dist/merged-empty-containers.js +9 -11
- package/dist/merged-empty-containers.js.map +1 -1
- package/dist/merged-subcontext.d.ts.map +1 -1
- package/dist/merged-subcontext.js +19 -1
- package/dist/merged-subcontext.js.map +1 -1
- package/dist/obj.d.ts +20 -0
- package/dist/obj.d.ts.map +1 -0
- package/dist/obj.js +40 -0
- package/dist/obj.js.map +1 -0
- package/dist/parquet-exporter.d.ts.map +1 -1
- package/dist/parquet-exporter.js +5 -5
- package/dist/parquet-exporter.js.map +1 -1
- package/dist/reference-collector.d.ts +21 -8
- package/dist/reference-collector.d.ts.map +1 -1
- package/dist/reference-collector.js +38 -45
- package/dist/reference-collector.js.map +1 -1
- package/dist/retype.d.ts +1 -1
- package/dist/retype.d.ts.map +1 -1
- package/dist/retype.js +13 -3
- package/dist/retype.js.map +1 -1
- package/dist/schema-converter-attr-remap.d.ts +18 -7
- package/dist/schema-converter-attr-remap.d.ts.map +1 -1
- package/dist/schema-converter-attr-remap.js +42 -48
- package/dist/schema-converter-attr-remap.js.map +1 -1
- package/dist/schema-converter.d.ts.map +1 -1
- package/dist/schema-converter.js +16 -78
- package/dist/schema-converter.js.map +1 -1
- package/dist/step-argument-parser.d.ts +20 -3
- package/dist/step-argument-parser.d.ts.map +1 -1
- package/dist/step-argument-parser.js +60 -11
- package/dist/step-argument-parser.js.map +1 -1
- package/dist/step-attribute-mutations.d.ts +32 -2
- package/dist/step-attribute-mutations.d.ts.map +1 -1
- package/dist/step-attribute-mutations.js +87 -6
- package/dist/step-attribute-mutations.js.map +1 -1
- package/dist/step-comment-skip.d.ts +13 -0
- package/dist/step-comment-skip.d.ts.map +1 -0
- package/dist/step-comment-skip.js +19 -0
- package/dist/step-comment-skip.js.map +1 -0
- package/dist/step-export-types.d.ts +51 -0
- package/dist/step-export-types.d.ts.map +1 -1
- package/dist/step-export-types.js +38 -0
- package/dist/step-export-types.js.map +1 -1
- package/dist/step-outer-args.d.ts +27 -0
- package/dist/step-outer-args.d.ts.map +1 -0
- package/dist/step-outer-args.js +64 -0
- package/dist/step-outer-args.js.map +1 -0
- package/dist/step-overlay-attribute-overrides.d.ts.map +1 -1
- package/dist/step-overlay-attribute-overrides.js +6 -2
- package/dist/step-overlay-attribute-overrides.js.map +1 -1
- package/dist/step-property-sets.d.ts.map +1 -1
- package/dist/step-property-sets.js +8 -2
- package/dist/step-property-sets.js.map +1 -1
- package/dist/step-serialization.d.ts +1 -1
- package/dist/step-serialization.js +1 -1
- package/dist/step-slot-grammar.d.ts +24 -0
- package/dist/step-slot-grammar.d.ts.map +1 -0
- package/dist/step-slot-grammar.js +201 -0
- package/dist/step-slot-grammar.js.map +1 -0
- package/dist/step-source-iteration.d.ts.map +1 -1
- package/dist/step-source-iteration.js +26 -2
- package/dist/step-source-iteration.js.map +1 -1
- package/dist/style-closure.d.ts +3 -1
- package/dist/style-closure.d.ts.map +1 -1
- package/dist/style-closure.js +16 -1
- package/dist/style-closure.js.map +1 -1
- package/dist/subset-entity-reader.d.ts +12 -4
- package/dist/subset-entity-reader.d.ts.map +1 -1
- package/dist/subset-entity-reader.js +4 -16
- package/dist/subset-entity-reader.js.map +1 -1
- package/dist/texture-map-closure.d.ts +10 -0
- package/dist/texture-map-closure.d.ts.map +1 -0
- package/dist/texture-map-closure.js +22 -0
- package/dist/texture-map-closure.js.map +1 -0
- package/dist/unit-normalize.d.ts.map +1 -1
- package/dist/unit-normalize.js +12 -49
- package/dist/unit-normalize.js.map +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
/**
|
|
5
|
+
* RFC 4180 CSV for a table of row OBJECTS — one header row from `columns`, then
|
|
6
|
+
* one line per row reading exactly those keys, in that order.
|
|
7
|
+
*
|
|
8
|
+
* Every table export in this repo (zones, clashes, …) had grown its own copy of
|
|
9
|
+
* the same 15-line loop around `escapeCsvCell`. The loop is not where the
|
|
10
|
+
* security lives — that is the escaper — but three copies of "null → empty,
|
|
11
|
+
* boolean → `true`/`false`, trailing newline" still drift (one forgot the
|
|
12
|
+
* trailing newline, so `cat a.csv b.csv` joined two rows). One writer, one set
|
|
13
|
+
* of rules:
|
|
14
|
+
*
|
|
15
|
+
* - `null` / `undefined` → empty cell (a spreadsheet reads `null` as text).
|
|
16
|
+
* - booleans → `true` / `false` (not `1`/`0`, which sum).
|
|
17
|
+
* - every other value → `String(value)` through {@link escapeCsvCell}, which
|
|
18
|
+
* applies RFC 4180 quoting and the CWE-1236 formula-injection guard. A cell
|
|
19
|
+
* whose first or last character is whitespace is quoted so an importer cannot
|
|
20
|
+
* trim the padding away (`quoteWhitespacePadded`).
|
|
21
|
+
* - lines end with `\n` and the file ends with one.
|
|
22
|
+
*/
|
|
23
|
+
import { escapeCsvCell } from './csv-cell.js';
|
|
24
|
+
/** Serialise one cell value under the rules documented on {@link tableToCsv}. */
|
|
25
|
+
export function csvCellOf(value, delimiter = ',') {
|
|
26
|
+
if (value === null || value === undefined)
|
|
27
|
+
return '';
|
|
28
|
+
const raw = typeof value === 'boolean' ? (value ? 'true' : 'false') : String(value);
|
|
29
|
+
return escapeCsvCell(raw, { delimiter, quoteWhitespacePadded: true });
|
|
30
|
+
}
|
|
31
|
+
export function tableToCsv(columns, rows, options = {}) {
|
|
32
|
+
const delimiter = options.delimiter ?? ',';
|
|
33
|
+
const lines = [columns.map((column) => csvCellOf(column, delimiter)).join(delimiter)];
|
|
34
|
+
for (const row of rows) {
|
|
35
|
+
lines.push(columns.map((column) => csvCellOf(row[column], delimiter)).join(delimiter));
|
|
36
|
+
}
|
|
37
|
+
return `${lines.join('\n')}\n`;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=csv-table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv-table.js","sourceRoot":"","sources":["../src/csv-table.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAU9C,iFAAiF;AACjF,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,SAAS,GAAG,GAAG;IACvD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACrD,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpF,OAAO,aAAa,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,OAAoC,EACpC,IAAoB,EACpB,UAA6B,EAAE;IAE/B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,GAAG,CAAC;IAC3C,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACtF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type IfcDataStore } from '@ifc-lite/parser';
|
|
2
|
+
import type { MutablePropertyView } from '@ifc-lite/mutations';
|
|
3
|
+
import type { EffectiveEntityIndex } from './effective-index.js';
|
|
4
|
+
/** Compose the existing STEP writers; never invent a second override policy. */
|
|
5
|
+
export declare function effectiveAppearanceRecord(store: IfcDataStore, view: MutablePropertyView, index: EffectiveEntityIndex, id: number): string;
|
|
6
|
+
/** URLReference occupies slot 5 after the inherited IfcSurfaceTexture fields. */
|
|
7
|
+
export declare function effectiveImageUri(line: string): string | undefined;
|
|
8
|
+
//# sourceMappingURL=effective-appearance-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effective-appearance-record.d.ts","sourceRoot":"","sources":["../src/effective-appearance-record.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAQjE,gFAAgF;AAChF,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM,GACtF,MAAM,CAuBR;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOlE"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { asSourceBytes, parseStepValue } from '@ifc-lite/parser';
|
|
5
|
+
import { serializeEntityArgs } from './attribute-real-slots.js';
|
|
6
|
+
import { applyOverlayEntityOverrides } from './step-overlay-attribute-overrides.js';
|
|
7
|
+
import { applySourceLineMutations } from './step-attribute-mutations.js';
|
|
8
|
+
import { readStepSlots, splitTopLevelStepArguments } from './step-argument-parser.js';
|
|
9
|
+
import { retypeArgTokens } from './retype.js';
|
|
10
|
+
/** Compose the existing STEP writers; never invent a second override policy. */
|
|
11
|
+
export function effectiveAppearanceRecord(store, view, index, id) {
|
|
12
|
+
const record = index.get(id);
|
|
13
|
+
if (!record)
|
|
14
|
+
throw new Error('Missing IFC entity during appearance cleanup; resources were retained.');
|
|
15
|
+
const schema = store.schemaVersion || 'IFC4';
|
|
16
|
+
const named = new Map(view.getAttributeMutationsForEntity(id).map(({ name, value }) => [name, value]));
|
|
17
|
+
const created = view.getNewEntity(id);
|
|
18
|
+
if (created) {
|
|
19
|
+
const retype = view.getEntityTypeMutation(id);
|
|
20
|
+
const type = retype?.newType ?? created.type;
|
|
21
|
+
let args = serializeEntityArgs(created.type, created.attributes, schema);
|
|
22
|
+
if (retype) {
|
|
23
|
+
const slots = splitTopLevelStepArguments(args);
|
|
24
|
+
if (slots === null)
|
|
25
|
+
throw new Error('Invalid authored IFC entity during appearance cleanup; resources were retained.');
|
|
26
|
+
args = retypeArgTokens(slots, created.type, type, retype.predefinedType, schema).tokens.join(',');
|
|
27
|
+
}
|
|
28
|
+
args = applyOverlayEntityOverrides(args, type, named, view.getPositionalMutationsForEntity(id), schema);
|
|
29
|
+
return `#${id}=${type.toUpperCase()}(${args});`;
|
|
30
|
+
}
|
|
31
|
+
const source = asSourceBytes(store.source);
|
|
32
|
+
const original = source.decodeUtf8(record.byteOffset, record.byteOffset + record.byteLength);
|
|
33
|
+
const result = applySourceLineMutations(view, id, original, record.type, named, schema, true);
|
|
34
|
+
if (result.unreadable)
|
|
35
|
+
throw new Error('Unreadable edited IFC entity during appearance cleanup; resources were retained.');
|
|
36
|
+
return result.text;
|
|
37
|
+
}
|
|
38
|
+
/** URLReference occupies slot 5 after the inherited IfcSurfaceTexture fields. */
|
|
39
|
+
export function effectiveImageUri(line) {
|
|
40
|
+
const record = readStepSlots(line);
|
|
41
|
+
if (record === null)
|
|
42
|
+
throw new Error('Unreadable IFC image during appearance cleanup; resources were retained.');
|
|
43
|
+
const argument = record.slots[5];
|
|
44
|
+
if (argument === undefined)
|
|
45
|
+
return undefined;
|
|
46
|
+
const value = parseStepValue(argument.trim());
|
|
47
|
+
return typeof value === 'string' ? value : undefined;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=effective-appearance-record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effective-appearance-record.js","sourceRoot":"","sources":["../src/effective-appearance-record.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { MeshData } from '@ifc-lite/geometry';
|
|
2
|
+
import { type IfcxNode, type IfcxEncodedImage } from '@ifc-lite/ifcx';
|
|
3
|
+
/** Packs canonical mesh fragments without evaluating styles or changing UV mappings. */
|
|
4
|
+
export declare class Ifc5AppearanceWriter {
|
|
5
|
+
private readonly occupiedPaths;
|
|
6
|
+
private readonly originals?;
|
|
7
|
+
readonly images: IfcxNode[];
|
|
8
|
+
private readonly imagePaths;
|
|
9
|
+
private readonly sourcePaths;
|
|
10
|
+
private imageBytes;
|
|
11
|
+
private nextFragment;
|
|
12
|
+
constructor(occupiedPaths: Set<string>, originals?: ReadonlyMap<string, IfcxEncodedImage> | undefined);
|
|
13
|
+
private uniquePath;
|
|
14
|
+
private image;
|
|
15
|
+
fragments(owner: IfcxNode, meshes: MeshData[], convert: (mesh: MeshData) => {
|
|
16
|
+
points: number[][];
|
|
17
|
+
faceVertexIndices: number[];
|
|
18
|
+
}): IfcxNode[];
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=ifc5-appearance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ifc5-appearance.d.ts","sourceRoot":"","sources":["../src/ifc5-appearance.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAgD,KAAK,QAAQ,EAAmB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAErI,wFAAwF;AACxF,qBAAa,oBAAoB;IAOnB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAAe,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IANpF,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAM;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8C;IAC1E,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAK;gBAEI,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,EAAmB,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,YAAA;IAE3H,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,KAAK;IA2Cb,SAAS,CACP,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,QAAQ,EAAE,EAClB,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK;QAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;QAAC,iBAAiB,EAAE,MAAM,EAAE,CAAA;KAAE,GAC/E,QAAQ,EAAE;CA0Bd"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { encodeIfcxImage, IFCX_APPEARANCE, IFCX_IMAGE } from '@ifc-lite/ifcx';
|
|
5
|
+
/** Packs canonical mesh fragments without evaluating styles or changing UV mappings. */
|
|
6
|
+
export class Ifc5AppearanceWriter {
|
|
7
|
+
occupiedPaths;
|
|
8
|
+
originals;
|
|
9
|
+
images = [];
|
|
10
|
+
imagePaths = new Map();
|
|
11
|
+
sourcePaths = new WeakMap();
|
|
12
|
+
imageBytes = 0;
|
|
13
|
+
nextFragment = 0;
|
|
14
|
+
constructor(occupiedPaths, originals) {
|
|
15
|
+
this.occupiedPaths = occupiedPaths;
|
|
16
|
+
this.originals = originals;
|
|
17
|
+
}
|
|
18
|
+
uniquePath(proposed) {
|
|
19
|
+
let path = proposed;
|
|
20
|
+
for (let suffix = 1; this.occupiedPaths.has(path); suffix++)
|
|
21
|
+
path = `${proposed}-${suffix}`;
|
|
22
|
+
this.occupiedPaths.add(path);
|
|
23
|
+
return path;
|
|
24
|
+
}
|
|
25
|
+
image(mesh) {
|
|
26
|
+
const source = mesh.texture?.rgba ?? mesh.textureBitmap;
|
|
27
|
+
if (!source)
|
|
28
|
+
throw new Error('Cannot export an unresolved IFCX texture. Load its image before exporting.');
|
|
29
|
+
const dimensions = mesh.texture ?? mesh.textureBitmap;
|
|
30
|
+
const dimensionKey = `${dimensions.width}x${dimensions.height}`;
|
|
31
|
+
const original = (mesh.textureRef ? this.originals?.get(mesh.textureRef.url) : undefined)
|
|
32
|
+
?? mesh.texture?.original;
|
|
33
|
+
const cached = !original && this.sourcePaths.get(source)?.get(dimensionKey);
|
|
34
|
+
if (cached)
|
|
35
|
+
return cached;
|
|
36
|
+
let pixels;
|
|
37
|
+
if (mesh.texture) {
|
|
38
|
+
pixels = mesh.texture;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const bitmap = mesh.textureBitmap;
|
|
42
|
+
if (typeof OffscreenCanvas === 'undefined') {
|
|
43
|
+
throw new Error('IFCX bitmap export requires OffscreenCanvas; headless callers can supply decoded MeshData.texture pixels.');
|
|
44
|
+
}
|
|
45
|
+
if (bitmap.width < 1 || bitmap.height < 1 || bitmap.width > 16_384 || bitmap.height > 16_384
|
|
46
|
+
|| bitmap.width * bitmap.height * 4 > 512 * 1024 * 1024)
|
|
47
|
+
throw new Error('IFCX texture exceeds the image budget.');
|
|
48
|
+
const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
|
|
49
|
+
const context = canvas.getContext('2d');
|
|
50
|
+
if (!context)
|
|
51
|
+
throw new Error('Unable to read the IFCX texture bitmap.');
|
|
52
|
+
context.drawImage(bitmap, 0, 0);
|
|
53
|
+
const data = context.getImageData(0, 0, bitmap.width, bitmap.height).data;
|
|
54
|
+
pixels = { width: bitmap.width, height: bitmap.height,
|
|
55
|
+
rgba: new Uint8Array(data.buffer, data.byteOffset, data.byteLength), repeatS: false, repeatT: false };
|
|
56
|
+
}
|
|
57
|
+
if (original)
|
|
58
|
+
pixels = { ...pixels, original };
|
|
59
|
+
const encoded = encodeIfcxImage(pixels);
|
|
60
|
+
let path = this.imagePaths.get(encoded.key);
|
|
61
|
+
if (!path) {
|
|
62
|
+
if (this.imageBytes + (pixels.rgba.length + (pixels.original?.bytes.length ?? 0)) > 512 * 1024 * 1024)
|
|
63
|
+
throw new Error('IFCX images exceed the 512 MiB file pixel budget.');
|
|
64
|
+
this.imageBytes += pixels.rgba.length + (pixels.original?.bytes.length ?? 0);
|
|
65
|
+
path = this.uniquePath(`ifclite-image-${encoded.key}`);
|
|
66
|
+
this.imagePaths.set(encoded.key, path);
|
|
67
|
+
this.images.push({ path, attributes: { [IFCX_IMAGE]: encoded.value } });
|
|
68
|
+
}
|
|
69
|
+
let sourcePaths = this.sourcePaths.get(source);
|
|
70
|
+
if (!sourcePaths)
|
|
71
|
+
this.sourcePaths.set(source, sourcePaths = new Map());
|
|
72
|
+
if (!original)
|
|
73
|
+
sourcePaths.set(dimensionKey, path);
|
|
74
|
+
return path;
|
|
75
|
+
}
|
|
76
|
+
fragments(owner, meshes, convert) {
|
|
77
|
+
const children = owner.children ??= {};
|
|
78
|
+
return meshes.map((mesh, index) => {
|
|
79
|
+
const path = this.uniquePath(`ifclite-mesh-${this.nextFragment++}`);
|
|
80
|
+
let name = `Appearance ${index + 1}`;
|
|
81
|
+
while (Object.hasOwn(children, name))
|
|
82
|
+
name += '_';
|
|
83
|
+
children[name] = path;
|
|
84
|
+
const [r, g, b, a] = mesh.color;
|
|
85
|
+
const attributes = {
|
|
86
|
+
'usd::usdgeom::mesh': convert(mesh),
|
|
87
|
+
'bsi::ifc::presentation::diffuseColor': [r, g, b],
|
|
88
|
+
'bsi::ifc::presentation::opacity': a,
|
|
89
|
+
};
|
|
90
|
+
const sampler = mesh.texture ?? mesh.textureRef;
|
|
91
|
+
if (sampler) {
|
|
92
|
+
if (typeof sampler.repeatS !== 'boolean' || typeof sampler.repeatT !== 'boolean')
|
|
93
|
+
throw new Error('IFCX texture sampler wraps must be boolean.');
|
|
94
|
+
if (!mesh.uvs || mesh.uvs.length !== mesh.positions.length / 3 * 2
|
|
95
|
+
|| !mesh.uvs.every(Number.isFinite))
|
|
96
|
+
throw new Error('Cannot export IFCX texture without a finite UV pair per vertex.');
|
|
97
|
+
attributes[IFCX_APPEARANCE] = {
|
|
98
|
+
image: { ref: this.image(mesh) }, uvs: Array.from(mesh.uvs),
|
|
99
|
+
repeatS: sampler.repeatS, repeatT: sampler.repeatT,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return { path, attributes };
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=ifc5-appearance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ifc5-appearance.js","sourceRoot":"","sources":["../src/ifc5-appearance.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Property names that have official IFC5 schema definitions in prop@v5a.ifcx.
|
|
3
|
+
* Source: https://github.com/buildingSMART/ifcx.dev/blob/main/@standards.buildingsmart.org/ifc/core/prop@v5a.ifcx
|
|
4
|
+
*
|
|
5
|
+
* IFC4 properties NOT in this set (e.g. Reference, LoadBearing, ExtendToStructure)
|
|
6
|
+
* must be omitted from IFC5 export — the viewer reports "Missing schema" errors for them.
|
|
7
|
+
*
|
|
8
|
+
* Name and Description are handled separately (always exported), so they're excluded here.
|
|
9
|
+
*/
|
|
10
|
+
export declare const IFC5_KNOWN_PROP_NAMES: Set<string>;
|
|
1
11
|
/** IFCX node in output, matching the shape `collectRequiredImports` scans. */
|
|
2
12
|
interface IfcxNodeOutputLike {
|
|
3
13
|
attributes?: Record<string, unknown>;
|
|
@@ -28,5 +38,14 @@ export declare function generateUuid(id: number): string;
|
|
|
28
38
|
* Uses the IFC type enum lookup for canonical casing (e.g. "IfcRelAggregates", not "Ifcrelaggregates").
|
|
29
39
|
*/
|
|
30
40
|
export declare function stepTypeToClassName(stepType: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* The exported node path of an entity whose GlobalId is a namespaced path
|
|
43
|
+
* (#4444): a store reconstructed from a shared room keys its entities by room
|
|
44
|
+
* path, `/<slotId>/<GlobalId>`, and an exported file must not carry the
|
|
45
|
+
* room-internal slot. Removes `prefix` when the GlobalId is under it
|
|
46
|
+
* (`/m1/<GlobalId>` → `/<GlobalId>`); any other GlobalId is returned verbatim,
|
|
47
|
+
* so an owner's own STEP-parsed store (bare GlobalIds) is unaffected.
|
|
48
|
+
*/
|
|
49
|
+
export declare function stripNodePathPrefix(globalId: string, prefix: string | undefined): string;
|
|
31
50
|
export {};
|
|
32
51
|
//# sourceMappingURL=ifc5-export-helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ifc5-export-helpers.d.ts","sourceRoot":"","sources":["../src/ifc5-export-helpers.ts"],"names":[],"mappings":"AAWA,8EAA8E;AAC9E,UAAU,kBAAkB;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,qFAAqF;AACrF,eAAO,MAAM,mBAAmB;IAC9B,wGAAwG;;IAExG,wCAAwC;;IAExC,mFAAmF;;CAE3E,CAAC;AAEX;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAmCrF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU5D"}
|
|
1
|
+
{"version":3,"file":"ifc5-export-helpers.d.ts","sourceRoot":"","sources":["../src/ifc5-export-helpers.ts"],"names":[],"mappings":"AAWA;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,aAkBhC,CAAC;AAEH,8EAA8E;AAC9E,UAAU,kBAAkB;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,qFAAqF;AACrF,eAAO,MAAM,mBAAmB;IAC9B,wGAAwG;;IAExG,wCAAwC;;IAExC,mFAAmF;;CAE3E,CAAC;AAEX;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAmCrF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU5D;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGxF"}
|
|
@@ -6,6 +6,34 @@
|
|
|
6
6
|
* keep ifc5-exporter.ts under its module-size budget; no behavior change.
|
|
7
7
|
*/
|
|
8
8
|
import { IfcTypeEnumToString, IfcTypeEnumFromString } from '@ifc-lite/data';
|
|
9
|
+
/**
|
|
10
|
+
* Property names that have official IFC5 schema definitions in prop@v5a.ifcx.
|
|
11
|
+
* Source: https://github.com/buildingSMART/ifcx.dev/blob/main/@standards.buildingsmart.org/ifc/core/prop@v5a.ifcx
|
|
12
|
+
*
|
|
13
|
+
* IFC4 properties NOT in this set (e.g. Reference, LoadBearing, ExtendToStructure)
|
|
14
|
+
* must be omitted from IFC5 export — the viewer reports "Missing schema" errors for them.
|
|
15
|
+
*
|
|
16
|
+
* Name and Description are handled separately (always exported), so they're excluded here.
|
|
17
|
+
*/
|
|
18
|
+
export const IFC5_KNOWN_PROP_NAMES = new Set([
|
|
19
|
+
'UsageType',
|
|
20
|
+
'TypeName',
|
|
21
|
+
'IsExternal',
|
|
22
|
+
'RefElevation',
|
|
23
|
+
'ElevationOfRefHeight',
|
|
24
|
+
'ElevationOfTerrain',
|
|
25
|
+
'NumberOfStoreys',
|
|
26
|
+
'Height',
|
|
27
|
+
'Width',
|
|
28
|
+
'Length',
|
|
29
|
+
'Depth',
|
|
30
|
+
'Volume',
|
|
31
|
+
'NetVolume',
|
|
32
|
+
'NetArea',
|
|
33
|
+
'NetSideArea',
|
|
34
|
+
'CrossSectionArea',
|
|
35
|
+
'Station',
|
|
36
|
+
]);
|
|
9
37
|
/** Standard IFC5 schema package URIs, keyed by the attribute prefix they provide. */
|
|
10
38
|
export const IFCX_SCHEMA_IMPORTS = {
|
|
11
39
|
/** Core IFC: bsi::ifc::class, bsi::ifc::presentation::*, bsi::ifc::material, bsi::ifc::spaceBoundary */
|
|
@@ -81,4 +109,17 @@ export function stepTypeToClassName(stepType) {
|
|
|
81
109
|
}
|
|
82
110
|
return stepType;
|
|
83
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* The exported node path of an entity whose GlobalId is a namespaced path
|
|
114
|
+
* (#4444): a store reconstructed from a shared room keys its entities by room
|
|
115
|
+
* path, `/<slotId>/<GlobalId>`, and an exported file must not carry the
|
|
116
|
+
* room-internal slot. Removes `prefix` when the GlobalId is under it
|
|
117
|
+
* (`/m1/<GlobalId>` → `/<GlobalId>`); any other GlobalId is returned verbatim,
|
|
118
|
+
* so an owner's own STEP-parsed store (bare GlobalIds) is unaffected.
|
|
119
|
+
*/
|
|
120
|
+
export function stripNodePathPrefix(globalId, prefix) {
|
|
121
|
+
if (!prefix || !globalId.startsWith(`${prefix}/`))
|
|
122
|
+
return globalId;
|
|
123
|
+
return globalId.slice(prefix.length);
|
|
124
|
+
}
|
|
84
125
|
//# sourceMappingURL=ifc5-export-helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ifc5-export-helpers.js","sourceRoot":"","sources":["../src/ifc5-export-helpers.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ifc5-export-helpers.js","sourceRoot":"","sources":["../src/ifc5-export-helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/ifc5-exporter.d.ts
CHANGED
|
@@ -13,18 +13,11 @@
|
|
|
13
13
|
import type { IfcDataStore } from '@ifc-lite/parser';
|
|
14
14
|
import type { MutablePropertyView } from '@ifc-lite/mutations';
|
|
15
15
|
import type { GeometryResult } from '@ifc-lite/geometry';
|
|
16
|
-
|
|
17
|
-
* Property names that have official IFC5 schema definitions in prop@v5a.ifcx.
|
|
18
|
-
* Source: https://github.com/buildingSMART/ifcx.dev/blob/main/@standards.buildingsmart.org/ifc/core/prop@v5a.ifcx
|
|
19
|
-
*
|
|
20
|
-
* IFC4 properties NOT in this set (e.g. Reference, LoadBearing, ExtendToStructure)
|
|
21
|
-
* must be omitted from IFC5 export — the viewer reports "Missing schema" errors for them.
|
|
22
|
-
*
|
|
23
|
-
* Name and Description are handled separately (always exported), so they're excluded here.
|
|
24
|
-
*/
|
|
25
|
-
export declare const IFC5_KNOWN_PROP_NAMES: Set<string>;
|
|
16
|
+
import { type IfcxEncodedImage } from '@ifc-lite/ifcx';
|
|
26
17
|
/** Options for IFC5 export */
|
|
27
18
|
export interface Ifc5ExportOptions {
|
|
19
|
+
/** Original image bytes keyed by exact MeshTextureRef.url; retained in IFCX without recompression. */
|
|
20
|
+
textureSources?: ReadonlyMap<string, IfcxEncodedImage>;
|
|
28
21
|
/** Author name */
|
|
29
22
|
author?: string;
|
|
30
23
|
/** Data version identifier */
|
|
@@ -51,6 +44,14 @@ export interface Ifc5ExportOptions {
|
|
|
51
44
|
* When true, relationship entities (IfcRel*), type objects, materials,
|
|
52
45
|
* and other non-spatial entities are excluded from the output. */
|
|
53
46
|
onlyTreeEntities?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* A namespace prefix to remove from GlobalId-derived node paths (#4444). A
|
|
49
|
+
* store reconstructed from a shared room keys its entities by room path,
|
|
50
|
+
* `/<slotId>/<GlobalId>`; the slot is the room's namespace, not the
|
|
51
|
+
* model's, so the exported file carries `/<GlobalId>` — the same paths a
|
|
52
|
+
* single-model room exports. GlobalIds outside the prefix are untouched.
|
|
53
|
+
*/
|
|
54
|
+
stripPathPrefix?: string;
|
|
54
55
|
}
|
|
55
56
|
/** Result of IFC5 export */
|
|
56
57
|
export interface Ifc5ExportResult {
|
|
@@ -121,6 +122,7 @@ export declare class Ifc5Exporter {
|
|
|
121
122
|
* will NOT be emitted as a node (deleted, hidden, or outside the exported
|
|
122
123
|
* tree). Every step below is driven by it rather than by the deletion
|
|
123
124
|
* check alone, so the maps can never describe a node `export` never wrote.
|
|
125
|
+
* @param stripPathPrefix see {@link Ifc5ExportOptions.stripPathPrefix}.
|
|
124
126
|
*/
|
|
125
127
|
private buildEntityMaps;
|
|
126
128
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ifc5-exporter.d.ts","sourceRoot":"","sources":["../src/ifc5-exporter.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"ifc5-exporter.d.ts","sourceRoot":"","sources":["../src/ifc5-exporter.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAY,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAUnE,OAAO,EAA2B,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAsBhF,8BAA8B;AAC9B,MAAM,WAAW,iBAAiB;IAChC,sGAAsG;IACtG,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACvD,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gEAAgE;IAChE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wCAAwC;IACxC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mCAAmC;IACnC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2CAA2C;IAC3C,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACvC;;yEAEqE;IACrE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;uEAEmE;IACnE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,4BAA4B;AAC5B,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,KAAK,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AA4BD;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,QAAQ,CAAS;IACzB,6EAA6E;IAC7E,OAAO,CAAC,UAAU,CAA6B;IAC/C,yEAAyE;IACzE,OAAO,CAAC,gBAAgB,CAA6B;IACrD,0CAA0C;IAC1C,OAAO,CAAC,WAAW,CAA6B;IAChD;;;;;;OAMG;IACH,OAAO,CAAC,UAAU,CAA2C;IAC7D;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,iBAAiB,CAAqB;gBAG5C,SAAS,EAAE,YAAY,EACvB,cAAc,CAAC,EAAE,cAAc,GAAG,IAAI,EACtC,YAAY,CAAC,EAAE,mBAAmB,EAClC,QAAQ,CAAC,EAAE,MAAM;IAQnB;;OAEG;IACH,MAAM,CAAC,OAAO,GAAE,iBAAsB,GAAG,gBAAgB;IAmOzD,yDAAyD;IACzD,OAAO,CAAC,eAAe;IAYvB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,eAAe;IAqJvB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA8B9B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAoB5B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAiC5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAkBvB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA+CxB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA2B1B;;OAEG;IACH,OAAO,CAAC,eAAe;CAsBxB"}
|
package/dist/ifc5-exporter.js
CHANGED
|
@@ -4,37 +4,11 @@
|
|
|
4
4
|
import { IfcTypeEnumToString, PropertyValueType, IFCX_VERSION, } from '@ifc-lite/data';
|
|
5
5
|
import { convertEntityType } from './schema-converter.js';
|
|
6
6
|
import { getEffectiveEntityIndex } from './effective-index.js';
|
|
7
|
+
import { Ifc5AppearanceWriter } from './ifc5-appearance.js';
|
|
8
|
+
import { IFCX_APPEARANCE_SCHEMAS } from '@ifc-lite/ifcx';
|
|
7
9
|
import { buildMaterialAttribute } from './ifc5-material.js';
|
|
8
|
-
import { collectRequiredImports, generateUuid, stepTypeToClassName } from './ifc5-export-helpers.js';
|
|
10
|
+
import { collectRequiredImports, generateUuid, IFC5_KNOWN_PROP_NAMES, stepTypeToClassName, stripNodePathPrefix, } from './ifc5-export-helpers.js';
|
|
9
11
|
import { addClassificationAttribute } from './ifc5-classification.js';
|
|
10
|
-
/**
|
|
11
|
-
* Property names that have official IFC5 schema definitions in prop@v5a.ifcx.
|
|
12
|
-
* Source: https://github.com/buildingSMART/ifcx.dev/blob/main/@standards.buildingsmart.org/ifc/core/prop@v5a.ifcx
|
|
13
|
-
*
|
|
14
|
-
* IFC4 properties NOT in this set (e.g. Reference, LoadBearing, ExtendToStructure)
|
|
15
|
-
* must be omitted from IFC5 export — the viewer reports "Missing schema" errors for them.
|
|
16
|
-
*
|
|
17
|
-
* Name and Description are handled separately (always exported), so they're excluded here.
|
|
18
|
-
*/
|
|
19
|
-
export const IFC5_KNOWN_PROP_NAMES = new Set([
|
|
20
|
-
'UsageType',
|
|
21
|
-
'TypeName',
|
|
22
|
-
'IsExternal',
|
|
23
|
-
'RefElevation',
|
|
24
|
-
'ElevationOfRefHeight',
|
|
25
|
-
'ElevationOfTerrain',
|
|
26
|
-
'NumberOfStoreys',
|
|
27
|
-
'Height',
|
|
28
|
-
'Width',
|
|
29
|
-
'Length',
|
|
30
|
-
'Depth',
|
|
31
|
-
'Volume',
|
|
32
|
-
'NetVolume',
|
|
33
|
-
'NetArea',
|
|
34
|
-
'NetSideArea',
|
|
35
|
-
'CrossSectionArea',
|
|
36
|
-
'Station',
|
|
37
|
-
]);
|
|
38
12
|
// ============================================================================
|
|
39
13
|
// Exporter
|
|
40
14
|
// ============================================================================
|
|
@@ -111,9 +85,10 @@ export class Ifc5Exporter {
|
|
|
111
85
|
|| (visibleIds !== null && !visibleIds.has(id))
|
|
112
86
|
|| (treeIds !== null && !treeIds.has(id));
|
|
113
87
|
// Build UUID paths and child-name maps from spatial hierarchy
|
|
114
|
-
this.buildEntityMaps(isOmitted);
|
|
88
|
+
this.buildEntityMaps(isOmitted, options.stripPathPrefix);
|
|
115
89
|
// Build mesh lookup by expressId
|
|
116
90
|
const meshByEntity = this.buildMeshLookup(options);
|
|
91
|
+
const appearance = new Ifc5AppearanceWriter(new Set(this.entityUuids.values()), options.textureSources);
|
|
117
92
|
// Collect nodes
|
|
118
93
|
const nodes = [];
|
|
119
94
|
/** expressIds that actually became nodes — the root node may only point at these. */
|
|
@@ -184,15 +159,21 @@ export class Ifc5Exporter {
|
|
|
184
159
|
if (options.includeGeometry !== false) {
|
|
185
160
|
const meshes = meshByEntity.get(expressId);
|
|
186
161
|
if (meshes && meshes.length > 0) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
attributes['
|
|
162
|
+
if (meshes.some((mesh) => mesh.texture || mesh.textureRef)) {
|
|
163
|
+
nodes.push(...appearance.fragments(node, meshes, (mesh) => this.convertToUsdMesh([mesh])));
|
|
164
|
+
meshCount += meshes.length;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
const usdMesh = this.convertToUsdMesh(meshes);
|
|
168
|
+
attributes['usd::usdgeom::mesh'] = usdMesh;
|
|
169
|
+
// Color/presentation
|
|
170
|
+
const [r, g, b, a] = meshes[0].color;
|
|
171
|
+
attributes['bsi::ifc::presentation::diffuseColor'] = [r, g, b];
|
|
172
|
+
if (a < 1.0) {
|
|
173
|
+
attributes['bsi::ifc::presentation::opacity'] = a;
|
|
174
|
+
}
|
|
175
|
+
meshCount++;
|
|
194
176
|
}
|
|
195
|
-
meshCount++;
|
|
196
177
|
}
|
|
197
178
|
}
|
|
198
179
|
if (Object.keys(attributes).length > 0)
|
|
@@ -238,6 +219,7 @@ export class Ifc5Exporter {
|
|
|
238
219
|
attributes: {},
|
|
239
220
|
});
|
|
240
221
|
}
|
|
222
|
+
nodes.push(...appearance.images);
|
|
241
223
|
// Determine required imports by scanning which attribute namespaces are used
|
|
242
224
|
const imports = collectRequiredImports(nodes);
|
|
243
225
|
// Assemble IFCX file
|
|
@@ -250,7 +232,7 @@ export class Ifc5Exporter {
|
|
|
250
232
|
timestamp: new Date().toISOString(),
|
|
251
233
|
},
|
|
252
234
|
imports,
|
|
253
|
-
schemas: {},
|
|
235
|
+
schemas: appearance.images.length ? IFCX_APPEARANCE_SCHEMAS : {},
|
|
254
236
|
data: nodes,
|
|
255
237
|
};
|
|
256
238
|
const content = options.prettyPrint !== false
|
|
@@ -291,8 +273,9 @@ export class Ifc5Exporter {
|
|
|
291
273
|
* will NOT be emitted as a node (deleted, hidden, or outside the exported
|
|
292
274
|
* tree). Every step below is driven by it rather than by the deletion
|
|
293
275
|
* check alone, so the maps can never describe a node `export` never wrote.
|
|
276
|
+
* @param stripPathPrefix see {@link Ifc5ExportOptions.stripPathPrefix}.
|
|
294
277
|
*/
|
|
295
|
-
buildEntityMaps(isOmitted) {
|
|
278
|
+
buildEntityMaps(isOmitted, stripPathPrefix) {
|
|
296
279
|
const { spatialHierarchy, entities, strings } = this.dataStore;
|
|
297
280
|
// --- 1. Assign UUID paths ---
|
|
298
281
|
// An omitted entity gets no UUID entry. `getChildrenForEntity`'s `addChild`
|
|
@@ -308,7 +291,7 @@ export class Ifc5Exporter {
|
|
|
308
291
|
continue;
|
|
309
292
|
// Use IFC GlobalId if available, otherwise generate a deterministic UUID
|
|
310
293
|
const globalId = strings.get(entities.globalId[i]);
|
|
311
|
-
this.entityUuids.set(id, globalId
|
|
294
|
+
this.entityUuids.set(id, globalId ? stripNodePathPrefix(globalId, stripPathPrefix) : generateUuid(id));
|
|
312
295
|
}
|
|
313
296
|
// --- 2. Build parent→children and spatial maps ---
|
|
314
297
|
const parentOf = new Map();
|