@ifc-lite/export 2.5.3 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attribute-real-slots.d.ts +53 -0
- package/dist/attribute-real-slots.d.ts.map +1 -0
- package/dist/attribute-real-slots.js +99 -0
- package/dist/attribute-real-slots.js.map +1 -0
- package/dist/demesh-prune.d.ts +24 -0
- package/dist/demesh-prune.d.ts.map +1 -0
- package/dist/demesh-prune.js +185 -0
- package/dist/demesh-prune.js.map +1 -0
- package/dist/demesh-session.d.ts +136 -0
- package/dist/demesh-session.d.ts.map +1 -0
- package/dist/demesh-session.js +273 -0
- package/dist/demesh-session.js.map +1 -0
- package/dist/demesh-writer.d.ts +84 -0
- package/dist/demesh-writer.d.ts.map +1 -0
- package/dist/demesh-writer.js +240 -0
- package/dist/demesh-writer.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/reference-collector.d.ts +6 -0
- package/dist/reference-collector.d.ts.map +1 -1
- package/dist/reference-collector.js +36 -1
- package/dist/reference-collector.js.map +1 -1
- package/dist/schema-converter.d.ts +22 -1
- package/dist/schema-converter.d.ts.map +1 -1
- package/dist/schema-converter.js +5 -2
- package/dist/schema-converter.js.map +1 -1
- package/dist/select-qualification.d.ts +9 -0
- package/dist/select-qualification.d.ts.map +1 -0
- package/dist/select-qualification.js +156 -0
- package/dist/select-qualification.js.map +1 -0
- package/dist/step-exporter.d.ts +34 -1
- package/dist/step-exporter.d.ts.map +1 -1
- package/dist/step-exporter.js +44 -19
- package/dist/step-exporter.js.map +1 -1
- package/dist/step-serialization.d.ts +39 -6
- package/dist/step-serialization.d.ts.map +1 -1
- package/dist/step-serialization.js +129 -10
- package/dist/step-serialization.js.map +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1,273 @@
|
|
|
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
|
+
* DemeshSession — interactive selective mesh simplification with deferred
|
|
6
|
+
* IFC export (the "demesher").
|
|
7
|
+
*
|
|
8
|
+
* Workflow (one session per loaded model):
|
|
9
|
+
* 1. `simplify(expressIds)` — each call escalates the selection one level
|
|
10
|
+
* (1-4 = cavity removal + vertex-clustering decimation at
|
|
11
|
+
* 0.5/0.25/0.10/0.03 triangle ratio, 5 = bounding box). Simplification
|
|
12
|
+
* ALWAYS re-runs from the ORIGINAL meshes at the new level — quality
|
|
13
|
+
* never degrades cumulatively, and `reset()` is trivial. The returned
|
|
14
|
+
* render meshes go straight into the scene:
|
|
15
|
+
* `scene.removeMeshesForEntities(ids)` + `scene.addMeshes(renderMeshes)`.
|
|
16
|
+
* 2. `exportIfc()` — separately, when the user is done: loads the original
|
|
17
|
+
* bytes into a store, swaps each simplified element's representation
|
|
18
|
+
* for an `IfcTriangulatedFaceSet` (via `applySimplifiedGeometry`),
|
|
19
|
+
* prunes the orphaned geometry, and writes the lighter IFC. IFC2X3
|
|
20
|
+
* sources are upconverted to IFC4 first (`IfcTriangulatedFaceSet` is
|
|
21
|
+
* IFC4+).
|
|
22
|
+
*
|
|
23
|
+
* The model file is parsed at most twice per session (once for meshes unless
|
|
24
|
+
* the caller supplies the ones it already holds, once at export); button
|
|
25
|
+
* presses between those touch only mesh data in wasm.
|
|
26
|
+
*/
|
|
27
|
+
import { GeometryProcessor, } from '@ifc-lite/geometry';
|
|
28
|
+
import { IfcParser } from '@ifc-lite/parser';
|
|
29
|
+
import { MutablePropertyView, StoreEditor } from '@ifc-lite/mutations';
|
|
30
|
+
import { StepExporter } from './step-exporter.js';
|
|
31
|
+
import { applySimplifiedGeometry, } from './demesh-writer.js';
|
|
32
|
+
export class DemeshSession {
|
|
33
|
+
source;
|
|
34
|
+
options;
|
|
35
|
+
gp = null;
|
|
36
|
+
ownsGp = false;
|
|
37
|
+
meshes = null;
|
|
38
|
+
originShift;
|
|
39
|
+
unitScale;
|
|
40
|
+
// Single-flight guards: concurrent calls (rapid button presses) must share
|
|
41
|
+
// ONE processor init / meshing pass / unit-scale scan. The promises are
|
|
42
|
+
// sticky on rejection too — a fatal wasm init failure stays terminal for
|
|
43
|
+
// the session instead of spawning a second doomed processor.
|
|
44
|
+
gpPromise = null;
|
|
45
|
+
meshesPromise = null;
|
|
46
|
+
unitScalePromise = null;
|
|
47
|
+
/** expressId -> state of the CURRENT simplification (from-original). */
|
|
48
|
+
applied = new Map();
|
|
49
|
+
constructor(source, options = {}) {
|
|
50
|
+
this.source = source instanceof Uint8Array ? source : new Uint8Array(source);
|
|
51
|
+
this.options = options;
|
|
52
|
+
this.meshes = options.meshes ?? null;
|
|
53
|
+
this.originShift = options.originShift ?? { x: 0, y: 0, z: 0 };
|
|
54
|
+
this.unitScale = options.unitScale ?? null;
|
|
55
|
+
}
|
|
56
|
+
/** The level currently applied to an element (0 = untouched). */
|
|
57
|
+
levelOf(expressId) {
|
|
58
|
+
return this.applied.get(expressId)?.level ?? 0;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The coordinate-frame shift of the meshes this session works with (the
|
|
62
|
+
* supplied `originShift`, or the session's own load's after self-meshing).
|
|
63
|
+
* A viewer whose scene uses a different anchor (multi-model federation
|
|
64
|
+
* with a shared RTC) translates render-mesh origins by the difference.
|
|
65
|
+
*/
|
|
66
|
+
getOriginShift() {
|
|
67
|
+
return { ...this.originShift };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The ORIGINAL mesh records of `expressIds` (session frame, untouched by
|
|
71
|
+
* any simplification) — lets a viewer restore an element's real geometry
|
|
72
|
+
* in the scene after `reset()`. Meshes the source on first use.
|
|
73
|
+
*/
|
|
74
|
+
async originalMeshesFor(expressIds) {
|
|
75
|
+
const meshes = await this.ensureMeshes();
|
|
76
|
+
const wanted = new Set(expressIds);
|
|
77
|
+
return meshes.filter((m) => wanted.has(m.expressId));
|
|
78
|
+
}
|
|
79
|
+
/** Express ids currently carrying simplified geometry. */
|
|
80
|
+
simplifiedIds() {
|
|
81
|
+
return [...this.applied.keys()];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Simplify `expressIds` at `level`, or — when `level` is omitted — one
|
|
85
|
+
* level past each element's current one (the button behavior: press,
|
|
86
|
+
* press again, ...; capped at 5).
|
|
87
|
+
*/
|
|
88
|
+
async simplify(expressIds, level) {
|
|
89
|
+
const meshes = await this.ensureMeshes();
|
|
90
|
+
const unitScale = await this.ensureUnitScale();
|
|
91
|
+
const gp = await this.ensureProcessor();
|
|
92
|
+
const levels = new Map();
|
|
93
|
+
for (const id of expressIds) {
|
|
94
|
+
levels.set(id, Math.min(5, level ?? this.levelOf(id) + 1));
|
|
95
|
+
}
|
|
96
|
+
const targetIds = new Set(levels.keys());
|
|
97
|
+
// Always simplify from the ORIGINAL records of the selection.
|
|
98
|
+
const records = meshes.filter((m) => targetIds.has(m.expressId));
|
|
99
|
+
const out = gp.simplifyMeshes(records, levels, {
|
|
100
|
+
originShift: this.originShift,
|
|
101
|
+
unitScale,
|
|
102
|
+
});
|
|
103
|
+
if (!out) {
|
|
104
|
+
throw new Error('DemeshSession.simplify: geometry processor is not initialized');
|
|
105
|
+
}
|
|
106
|
+
const result = { renderMeshes: [], elements: [], skipped: out.skipped };
|
|
107
|
+
for (const el of out.elements) {
|
|
108
|
+
this.applied.set(el.expressId, el);
|
|
109
|
+
result.renderMeshes.push(el.render);
|
|
110
|
+
result.elements.push({
|
|
111
|
+
expressId: el.expressId,
|
|
112
|
+
level: el.level,
|
|
113
|
+
trisBefore: el.trisBefore,
|
|
114
|
+
trisAfter: el.trisAfter,
|
|
115
|
+
cavitiesDropped: el.cavitiesDropped,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Forget the simplification state for `expressIds` (all when omitted).
|
|
122
|
+
* The caller restores the elements' original meshes in the scene.
|
|
123
|
+
*/
|
|
124
|
+
reset(expressIds) {
|
|
125
|
+
if (!expressIds) {
|
|
126
|
+
this.applied.clear();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
for (const id of expressIds)
|
|
130
|
+
this.applied.delete(id);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* The `n` heaviest elements by triangle count — demesh candidates for the
|
|
134
|
+
* UI. Requires meshes (supplied or produced on first `simplify`).
|
|
135
|
+
*/
|
|
136
|
+
async heaviest(n) {
|
|
137
|
+
const meshes = await this.ensureMeshes();
|
|
138
|
+
const byElement = new Map();
|
|
139
|
+
for (const m of meshes) {
|
|
140
|
+
if ((m.geometryClass ?? 0) !== 0)
|
|
141
|
+
continue;
|
|
142
|
+
byElement.set(m.expressId, (byElement.get(m.expressId) ?? 0) + m.indices.length / 3);
|
|
143
|
+
}
|
|
144
|
+
return [...byElement.entries()]
|
|
145
|
+
.map(([expressId, triangles]) => ({ expressId, triangles }))
|
|
146
|
+
.sort((a, b) => b.triangles - a.triangles)
|
|
147
|
+
.slice(0, Math.max(0, n));
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Write the lighter IFC: original bytes + tessellated replacements for
|
|
151
|
+
* every currently simplified element. Does not mutate session state — the
|
|
152
|
+
* user can keep simplifying and export again.
|
|
153
|
+
*/
|
|
154
|
+
async exportIfc() {
|
|
155
|
+
if (this.applied.size === 0) {
|
|
156
|
+
throw new Error('DemeshSession.exportIfc: nothing simplified yet');
|
|
157
|
+
}
|
|
158
|
+
// Load (and upconvert when needed) the store the mutations apply to.
|
|
159
|
+
let sourceBytes = this.source;
|
|
160
|
+
let upconverted = false;
|
|
161
|
+
let store = await new IfcParser().parseColumnar(toArrayBuffer(sourceBytes), {
|
|
162
|
+
disableWorkerScan: true,
|
|
163
|
+
});
|
|
164
|
+
if ((store.schemaVersion ?? 'IFC4').toUpperCase() === 'IFC2X3') {
|
|
165
|
+
// IfcTriangulatedFaceSet is IFC4+. The schema conversion is a
|
|
166
|
+
// line-faithful rewrite (express ids preserved), so the session's
|
|
167
|
+
// element ids stay valid against the converted buffer.
|
|
168
|
+
const converted = new StepExporter(store).export({ schema: 'IFC4' });
|
|
169
|
+
sourceBytes = converted.content;
|
|
170
|
+
store = await new IfcParser().parseColumnar(toArrayBuffer(sourceBytes), {
|
|
171
|
+
disableWorkerScan: true,
|
|
172
|
+
});
|
|
173
|
+
upconverted = true;
|
|
174
|
+
}
|
|
175
|
+
const view = new MutablePropertyView(null, 'default');
|
|
176
|
+
const editor = new StoreEditor(store, view);
|
|
177
|
+
const elements = [...this.applied.values()].map((el) => ({
|
|
178
|
+
expressId: el.expressId,
|
|
179
|
+
positions: el.localPositions,
|
|
180
|
+
indices: el.localIndices,
|
|
181
|
+
color: el.render.color,
|
|
182
|
+
}));
|
|
183
|
+
const report = applySimplifiedGeometry(store, editor, elements);
|
|
184
|
+
const schema = ((store.schemaVersion ?? 'IFC4').toUpperCase() === 'IFC2X3' ? 'IFC4' : (store.schemaVersion ?? 'IFC4'));
|
|
185
|
+
const result = new StepExporter(store, view).export({ schema, applyMutations: true });
|
|
186
|
+
return {
|
|
187
|
+
bytes: result.content,
|
|
188
|
+
report,
|
|
189
|
+
upconverted,
|
|
190
|
+
bytesBefore: this.source.byteLength,
|
|
191
|
+
bytesAfter: result.content.byteLength,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
/** Release the session's own GeometryProcessor (a shared one is untouched). */
|
|
195
|
+
destroy() {
|
|
196
|
+
if (this.ownsGp && this.gp) {
|
|
197
|
+
this.gp.dispose();
|
|
198
|
+
}
|
|
199
|
+
this.gp = null;
|
|
200
|
+
this.gpPromise = null;
|
|
201
|
+
this.meshes = null;
|
|
202
|
+
this.meshesPromise = null;
|
|
203
|
+
this.unitScalePromise = null;
|
|
204
|
+
this.applied.clear();
|
|
205
|
+
}
|
|
206
|
+
ensureProcessor() {
|
|
207
|
+
this.gpPromise ??= (async () => {
|
|
208
|
+
if (this.options.geometryProcessor) {
|
|
209
|
+
this.gp = this.options.geometryProcessor;
|
|
210
|
+
return this.gp;
|
|
211
|
+
}
|
|
212
|
+
const gp = new GeometryProcessor();
|
|
213
|
+
// Track before init so destroy() during a pending init still disposes.
|
|
214
|
+
this.gp = gp;
|
|
215
|
+
this.ownsGp = true;
|
|
216
|
+
await gp.init();
|
|
217
|
+
return gp;
|
|
218
|
+
})();
|
|
219
|
+
return this.gpPromise;
|
|
220
|
+
}
|
|
221
|
+
ensureMeshes() {
|
|
222
|
+
this.meshesPromise ??= (async () => {
|
|
223
|
+
if (this.meshes)
|
|
224
|
+
return this.meshes;
|
|
225
|
+
const gp = await this.ensureProcessor();
|
|
226
|
+
const meshes = [];
|
|
227
|
+
for await (const event of gp.processAdaptive(this.source, { sizeThreshold: 0 })) {
|
|
228
|
+
if (event.type === 'batch') {
|
|
229
|
+
meshes.push(...event.meshes);
|
|
230
|
+
if (event.coordinateInfo)
|
|
231
|
+
this.originShift = event.coordinateInfo.originShift;
|
|
232
|
+
}
|
|
233
|
+
else if (event.type === 'complete' && event.coordinateInfo) {
|
|
234
|
+
this.originShift = event.coordinateInfo.originShift;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
this.meshes = meshes;
|
|
238
|
+
return meshes;
|
|
239
|
+
})();
|
|
240
|
+
return this.meshesPromise;
|
|
241
|
+
}
|
|
242
|
+
ensureUnitScale() {
|
|
243
|
+
this.unitScalePromise ??= (async () => {
|
|
244
|
+
if (this.unitScale !== null)
|
|
245
|
+
return this.unitScale;
|
|
246
|
+
const { scanIfcEntities, extractLengthUnitScale } = await import('@ifc-lite/parser');
|
|
247
|
+
const { entityRefs } = await scanIfcEntities(toArrayBuffer(this.source));
|
|
248
|
+
const byId = new Map();
|
|
249
|
+
const byType = new Map();
|
|
250
|
+
for (const ref of entityRefs) {
|
|
251
|
+
byId.set(ref.expressId, ref);
|
|
252
|
+
const type = String(ref.type || '').toUpperCase();
|
|
253
|
+
const list = byType.get(type);
|
|
254
|
+
if (list)
|
|
255
|
+
list.push(ref.expressId);
|
|
256
|
+
else
|
|
257
|
+
byType.set(type, [ref.expressId]);
|
|
258
|
+
}
|
|
259
|
+
this.unitScale = extractLengthUnitScale(this.source, { byId, byType });
|
|
260
|
+
return this.unitScale;
|
|
261
|
+
})();
|
|
262
|
+
return this.unitScalePromise;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
function toArrayBuffer(bytes) {
|
|
266
|
+
if (bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength && bytes.buffer instanceof ArrayBuffer) {
|
|
267
|
+
return bytes.buffer;
|
|
268
|
+
}
|
|
269
|
+
const copy = new ArrayBuffer(bytes.byteLength);
|
|
270
|
+
new Uint8Array(copy).set(bytes);
|
|
271
|
+
return copy;
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=demesh-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demesh-session.js","sourceRoot":"","sources":["../src/demesh-session.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EACL,iBAAiB,GAGlB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,uBAAuB,GAGxB,MAAM,oBAAoB,CAAC;AA0C5B,MAAM,OAAO,aAAa;IACP,MAAM,CAAa;IACnB,OAAO,CAAuB;IACvC,EAAE,GAA6B,IAAI,CAAC;IACpC,MAAM,GAAG,KAAK,CAAC;IACf,MAAM,GAAsB,IAAI,CAAC;IACjC,WAAW,CAAsC;IACjD,SAAS,CAAgB;IACjC,2EAA2E;IAC3E,wEAAwE;IACxE,yEAAyE;IACzE,6DAA6D;IACrD,SAAS,GAAsC,IAAI,CAAC;IACpD,aAAa,GAA+B,IAAI,CAAC;IACjD,gBAAgB,GAA2B,IAAI,CAAC;IACxD,wEAAwE;IACvD,OAAO,GAAG,IAAI,GAAG,EAAiC,CAAC;IAEpE,YAAY,MAAgC,EAAE,UAAgC,EAAE;QAC9E,IAAI,CAAC,MAAM,GAAG,MAAM,YAAY,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QAC7E,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QAC/D,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;IAC7C,CAAC;IAED,iEAAiE;IACjE,OAAO,CAAC,SAAiB;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IACjD,CAAC;IAED;;;;;OAKG;IACH,cAAc;QACZ,OAAO,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,iBAAiB,CAAC,UAAoB;QAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,0DAA0D;IAC1D,aAAa;QACX,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CAAC,UAAoB,EAAE,KAAc;QACjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC/C,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAExC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,8DAA8D;QAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QAEjE,MAAM,GAAG,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE;YAC7C,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS;SACV,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QAED,MAAM,MAAM,GAAyB,EAAE,YAAY,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QAC9F,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YACnC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YACpC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACnB,SAAS,EAAE,EAAE,CAAC,SAAS;gBACvB,KAAK,EAAE,EAAE,CAAC,KAAK;gBACf,UAAU,EAAE,EAAE,CAAC,UAAU;gBACzB,SAAS,EAAE,EAAE,CAAC,SAAS;gBACvB,eAAe,EAAE,EAAE,CAAC,eAAe;aACpC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,UAAqB;QACzB,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,UAAU;YAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ,CAAC,CAAS;QACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC3C,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;aAC5B,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;aAC3D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;aACzC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,SAAS;QACb,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QAED,qEAAqE;QACrE,IAAI,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC;QAC9B,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,KAAK,GAAG,MAAM,IAAI,SAAS,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE;YAC1E,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC/D,8DAA8D;YAC9D,kEAAkE;YAClE,uDAAuD;YACvD,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YACrE,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC;YAChC,KAAK,GAAG,MAAM,IAAI,SAAS,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE;gBACtE,iBAAiB,EAAE,IAAI;aACxB,CAAC,CAAC;YACH,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,mBAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAgC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACpF,SAAS,EAAE,EAAE,CAAC,SAAS;YACvB,SAAS,EAAE,EAAE,CAAC,cAAc;YAC5B,OAAO,EAAE,EAAE,CAAC,YAAY;YACxB,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK;SACvB,CAAC,CAAC,CAAC;QACJ,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEhE,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,MAAM,CAAC,CAG3G,CAAC;QACX,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC;QACtF,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,OAAO;YACrB,MAAM;YACN,WAAW;YACX,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU;YACnC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU;SACtC,CAAC;IACJ,CAAC;IAED,+EAA+E;IAC/E,OAAO;QACL,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YAC3B,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACf,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,SAAS,KAAK,CAAC,KAAK,IAAI,EAAE;YAC7B,IAAI,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC;gBACnC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC;gBACzC,OAAO,IAAI,CAAC,EAAE,CAAC;YACjB,CAAC;YACD,MAAM,EAAE,GAAG,IAAI,iBAAiB,EAAE,CAAC;YACnC,uEAAuE;YACvE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;YAChB,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAEO,YAAY;QAClB,IAAI,CAAC,aAAa,KAAK,CAAC,KAAK,IAAI,EAAE;YACjC,IAAI,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC,MAAM,CAAC;YACpC,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YACxC,MAAM,MAAM,GAAe,EAAE,CAAC;YAC9B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;gBAChF,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC3B,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;oBAC7B,IAAI,KAAK,CAAC,cAAc;wBAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;gBAChF,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;oBAC7D,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;gBACtD,CAAC;YACH,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,gBAAgB,KAAK,CAAC,KAAK,IAAI,EAAE;YACpC,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC,SAAS,CAAC;YACnD,MAAM,EAAE,eAAe,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACrF,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,eAAe,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACzE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuC,CAAC;YAC5D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;YAC3C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAC7B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;gBAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;gBAClD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC9B,IAAI,IAAI;oBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;;oBAC9B,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;YACzC,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,sBAAsB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC,SAAS,CAAC;QACxB,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,SAAS,aAAa,CAAC,KAAiB;IACtC,IAAI,KAAK,CAAC,UAAU,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,MAAM,CAAC,UAAU,IAAI,KAAK,CAAC,MAAM,YAAY,WAAW,EAAE,CAAC;QAClH,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/C,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Demesher IFC writer: replace product representations with simplified
|
|
3
|
+
* tessellated geometry and prune the orphaned original geometry subgraphs.
|
|
4
|
+
*
|
|
5
|
+
* Per element this authors `IfcCartesianPointList3D` →
|
|
6
|
+
* `IfcTriangulatedFaceSet` → `IfcShapeRepresentation('Body','Tessellation')`
|
|
7
|
+
* → `IfcProductDefinitionShape` in the editor overlay, swaps the product's
|
|
8
|
+
* `Representation` attribute, then runs ONE global reverse-reference
|
|
9
|
+
* mark-and-sweep over the replaced subgraphs: an old geometry entity is
|
|
10
|
+
* tombstoned only when every entity that references it is itself being
|
|
11
|
+
* tombstoned. Shared representations (`IfcMappedItem` sources, a
|
|
12
|
+
* `IfcProductDefinitionShape` shared by several products) survive partial
|
|
13
|
+
* selections by construction. Type-library geometry
|
|
14
|
+
* (`IfcTypeProduct.RepresentationMaps`) is likewise kept — the type object
|
|
15
|
+
* itself still references it.
|
|
16
|
+
*
|
|
17
|
+
* Geometry arrives from the wasm demesher (`simplifyMeshes`) already in the
|
|
18
|
+
* element's object-placement frame in FILE units, so this module does no
|
|
19
|
+
* coordinate math beyond rounding. `IfcTriangulatedFaceSet` requires IFC4+ —
|
|
20
|
+
* callers upconvert IFC2X3 stores before applying (`convert --schema IFC4`
|
|
21
|
+
* path).
|
|
22
|
+
*/
|
|
23
|
+
import { type IfcDataStore } from '@ifc-lite/parser';
|
|
24
|
+
/** Attribute value union accepted by the editor (structural, see below). */
|
|
25
|
+
type EditorValue = unknown;
|
|
26
|
+
/**
|
|
27
|
+
* The three editor primitives this writer needs — structurally satisfied by
|
|
28
|
+
* `@ifc-lite/mutations` `StoreEditor` (kept duck-typed so `@ifc-lite/export`
|
|
29
|
+
* does not grow a package dependency on `@ifc-lite/mutations`).
|
|
30
|
+
*/
|
|
31
|
+
export interface DemeshEditorLike {
|
|
32
|
+
addEntity(type: string, attributes: EditorValue[]): {
|
|
33
|
+
expressId: number;
|
|
34
|
+
};
|
|
35
|
+
setPositionalAttribute(expressId: number, index: number, value: EditorValue): void;
|
|
36
|
+
removeEntity(expressId: number): boolean;
|
|
37
|
+
}
|
|
38
|
+
/** One element's simplified geometry, in its object-placement frame, file units. */
|
|
39
|
+
export interface SimplifiedElementGeometry {
|
|
40
|
+
expressId: number;
|
|
41
|
+
/** xyz triplets (f64), element object frame, FILE units, IFC Z-up. */
|
|
42
|
+
positions: ArrayLike<number>;
|
|
43
|
+
/** 0-based triangle indices (converted to 1-based `CoordIndex` here). */
|
|
44
|
+
indices: ArrayLike<number>;
|
|
45
|
+
/** RGBA 0..1 for the replacement's surface style; omit for no style. */
|
|
46
|
+
color?: ArrayLike<number>;
|
|
47
|
+
}
|
|
48
|
+
export interface ApplySimplifiedGeometryOptions {
|
|
49
|
+
/**
|
|
50
|
+
* Tombstone `IfcRelVoidsElement` / `IfcOpeningElement` attached to replaced
|
|
51
|
+
* products (default true): opening cuts are already baked into the
|
|
52
|
+
* simplified mesh, and a stale void relationship would re-cut it.
|
|
53
|
+
*/
|
|
54
|
+
stripOpenings?: boolean;
|
|
55
|
+
/** Coordinate rounding, decimal places in file units (default 6). */
|
|
56
|
+
coordinateDecimals?: number;
|
|
57
|
+
}
|
|
58
|
+
export interface DemeshApplyReport {
|
|
59
|
+
/** Products whose Representation was swapped. */
|
|
60
|
+
replaced: number[];
|
|
61
|
+
/** Elements left untouched, with a reason slug. */
|
|
62
|
+
skipped: Array<{
|
|
63
|
+
expressId: number;
|
|
64
|
+
reason: string;
|
|
65
|
+
}>;
|
|
66
|
+
/** Original-geometry entities tombstoned by the prune. */
|
|
67
|
+
prunedEntityCount: number;
|
|
68
|
+
/** IfcRelVoidsElement + IfcOpeningElement entities stripped. */
|
|
69
|
+
strippedOpeningCount: number;
|
|
70
|
+
warnings: string[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Apply simplified geometry to the store's editor overlay. The store buffer
|
|
74
|
+
* itself is never mutated; changes materialize on the next
|
|
75
|
+
* `StepExporter.export({ applyMutations: true })`.
|
|
76
|
+
*
|
|
77
|
+
* The store must have a COMPLETE `entityIndex.byId` — the prune's reverse
|
|
78
|
+
* index walks it as the referrer universe. A store parsed with
|
|
79
|
+
* `deferPropertyAtomIndex` keeps property atoms out of `byId`, so feed a
|
|
80
|
+
* full reparse instead (`DemeshSession` always does).
|
|
81
|
+
*/
|
|
82
|
+
export declare function applySimplifiedGeometry(store: IfcDataStore, editor: DemeshEditorLike, elements: SimplifiedElementGeometry[], options?: ApplySimplifiedGeometryOptions): DemeshApplyReport;
|
|
83
|
+
export {};
|
|
84
|
+
//# sourceMappingURL=demesh-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demesh-writer.d.ts","sourceRoot":"","sources":["../src/demesh-writer.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAA8C,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAIjG,4EAA4E;AAC5E,KAAK,WAAW,GAAG,OAAO,CAAC;AAE3B;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACnF,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1C;AAED,oFAAoF;AACpF,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7B,yEAAyE;IACzE,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC3B,wEAAwE;IACxE,KAAK,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,8BAA8B;IAC7C;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mDAAmD;IACnD,OAAO,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,0DAA0D;IAC1D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,gBAAgB,EACxB,QAAQ,EAAE,yBAAyB,EAAE,EACrC,OAAO,GAAE,8BAAmC,GAC3C,iBAAiB,CA4JnB"}
|
|
@@ -0,0 +1,240 @@
|
|
|
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
|
+
* Demesher IFC writer: replace product representations with simplified
|
|
6
|
+
* tessellated geometry and prune the orphaned original geometry subgraphs.
|
|
7
|
+
*
|
|
8
|
+
* Per element this authors `IfcCartesianPointList3D` →
|
|
9
|
+
* `IfcTriangulatedFaceSet` → `IfcShapeRepresentation('Body','Tessellation')`
|
|
10
|
+
* → `IfcProductDefinitionShape` in the editor overlay, swaps the product's
|
|
11
|
+
* `Representation` attribute, then runs ONE global reverse-reference
|
|
12
|
+
* mark-and-sweep over the replaced subgraphs: an old geometry entity is
|
|
13
|
+
* tombstoned only when every entity that references it is itself being
|
|
14
|
+
* tombstoned. Shared representations (`IfcMappedItem` sources, a
|
|
15
|
+
* `IfcProductDefinitionShape` shared by several products) survive partial
|
|
16
|
+
* selections by construction. Type-library geometry
|
|
17
|
+
* (`IfcTypeProduct.RepresentationMaps`) is likewise kept — the type object
|
|
18
|
+
* itself still references it.
|
|
19
|
+
*
|
|
20
|
+
* Geometry arrives from the wasm demesher (`simplifyMeshes`) already in the
|
|
21
|
+
* element's object-placement frame in FILE units, so this module does no
|
|
22
|
+
* coordinate math beyond rounding. `IfcTriangulatedFaceSet` requires IFC4+ —
|
|
23
|
+
* callers upconvert IFC2X3 stores before applying (`convert --schema IFC4`
|
|
24
|
+
* path).
|
|
25
|
+
*/
|
|
26
|
+
import { EntityExtractor, getAllAttributesForEntity } from '@ifc-lite/parser';
|
|
27
|
+
import { pruneReplacedSubgraphs } from './demesh-prune.js';
|
|
28
|
+
import { stepReal } from './step-serialization.js';
|
|
29
|
+
/**
|
|
30
|
+
* Apply simplified geometry to the store's editor overlay. The store buffer
|
|
31
|
+
* itself is never mutated; changes materialize on the next
|
|
32
|
+
* `StepExporter.export({ applyMutations: true })`.
|
|
33
|
+
*
|
|
34
|
+
* The store must have a COMPLETE `entityIndex.byId` — the prune's reverse
|
|
35
|
+
* index walks it as the referrer universe. A store parsed with
|
|
36
|
+
* `deferPropertyAtomIndex` keeps property atoms out of `byId`, so feed a
|
|
37
|
+
* full reparse instead (`DemeshSession` always does).
|
|
38
|
+
*/
|
|
39
|
+
export function applySimplifiedGeometry(store, editor, elements, options = {}) {
|
|
40
|
+
const report = {
|
|
41
|
+
replaced: [],
|
|
42
|
+
skipped: [],
|
|
43
|
+
prunedEntityCount: 0,
|
|
44
|
+
strippedOpeningCount: 0,
|
|
45
|
+
warnings: [],
|
|
46
|
+
};
|
|
47
|
+
if (!store.source) {
|
|
48
|
+
throw new Error('applySimplifiedGeometry: store has no source buffer');
|
|
49
|
+
}
|
|
50
|
+
const source = store.source;
|
|
51
|
+
const byId = store.entityIndex.byId;
|
|
52
|
+
const extractor = new EntityExtractor(source);
|
|
53
|
+
const decimals = options.coordinateDecimals ?? 6;
|
|
54
|
+
const roundFactor = 10 ** decimals;
|
|
55
|
+
const round = (v) => (Number.isFinite(v) ? Math.round(v * roundFactor) / roundFactor : 0);
|
|
56
|
+
const getEntity = (id) => {
|
|
57
|
+
const ref = byId.get(id);
|
|
58
|
+
return ref ? extractor.extractEntity(ref) : null;
|
|
59
|
+
};
|
|
60
|
+
const contextId = findBodyContextId(byId, getEntity);
|
|
61
|
+
if (contextId === null) {
|
|
62
|
+
report.warnings.push('no IfcGeometricRepresentationContext found; nothing applied');
|
|
63
|
+
for (const el of elements) {
|
|
64
|
+
report.skipped.push({ expressId: el.expressId, reason: 'no-context' });
|
|
65
|
+
}
|
|
66
|
+
return report;
|
|
67
|
+
}
|
|
68
|
+
// One IfcSurfaceStyle chain per distinct RGBA across all elements.
|
|
69
|
+
const styleCache = new Map();
|
|
70
|
+
const surfaceStyleFor = (color) => {
|
|
71
|
+
const r = clamp01(color[0]);
|
|
72
|
+
const g = clamp01(color[1]);
|
|
73
|
+
const b = clamp01(color[2]);
|
|
74
|
+
const a = color.length > 3 ? clamp01(color[3]) : 1;
|
|
75
|
+
const key = `${r},${g},${b},${a}`;
|
|
76
|
+
const cached = styleCache.get(key);
|
|
77
|
+
if (cached !== undefined)
|
|
78
|
+
return cached;
|
|
79
|
+
const rgb = editor.addEntity('IfcColourRgb', [null, stepReal(r), stepReal(g), stepReal(b)]);
|
|
80
|
+
const shading = editor.addEntity('IfcSurfaceStyleShading', [
|
|
81
|
+
`#${rgb.expressId}`,
|
|
82
|
+
stepReal(roundTo(1 - a, 4)),
|
|
83
|
+
]);
|
|
84
|
+
const style = editor.addEntity('IfcSurfaceStyle', [
|
|
85
|
+
null,
|
|
86
|
+
'.BOTH.',
|
|
87
|
+
[`#${shading.expressId}`],
|
|
88
|
+
]);
|
|
89
|
+
styleCache.set(key, style.expressId);
|
|
90
|
+
return style.expressId;
|
|
91
|
+
};
|
|
92
|
+
/** productId -> the old Representation ref it was detached from (if any). */
|
|
93
|
+
const replacedOldRep = new Map();
|
|
94
|
+
for (const el of elements) {
|
|
95
|
+
// A repeated id would author a second overlay chain and orphan the first
|
|
96
|
+
// (bloat, not corruption) — replace once, skip the rest.
|
|
97
|
+
if (replacedOldRep.has(el.expressId)) {
|
|
98
|
+
report.skipped.push({ expressId: el.expressId, reason: 'duplicate-id' });
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const ref = byId.get(el.expressId);
|
|
102
|
+
if (!ref) {
|
|
103
|
+
report.skipped.push({ expressId: el.expressId, reason: 'not-found' });
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const repAttrIndex = findAttrIndex(ref.type, 'Representation');
|
|
107
|
+
if (repAttrIndex === null) {
|
|
108
|
+
report.skipped.push({ expressId: el.expressId, reason: 'no-representation-attribute' });
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
// Malformed geometry is rejected, never repaired: a trailing coordinate
|
|
112
|
+
// silently dropped by flooring, or a NaN/Infinity coerced to 0 by
|
|
113
|
+
// `round()`, would author a subtly wrong tessellation into the file.
|
|
114
|
+
const vertexCount = Math.floor(el.positions.length / 3);
|
|
115
|
+
const triCount = Math.floor(el.indices.length / 3);
|
|
116
|
+
if (el.positions.length % 3 !== 0 ||
|
|
117
|
+
el.indices.length % 3 !== 0 ||
|
|
118
|
+
vertexCount < 3 ||
|
|
119
|
+
triCount < 1 ||
|
|
120
|
+
!valuesAreFinite(el.positions) ||
|
|
121
|
+
!indicesInRange(el.indices, vertexCount)) {
|
|
122
|
+
report.skipped.push({ expressId: el.expressId, reason: 'invalid-geometry' });
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const entity = getEntity(el.expressId);
|
|
126
|
+
const oldRep = entity && typeof entity.attributes?.[repAttrIndex] === 'number'
|
|
127
|
+
? entity.attributes[repAttrIndex]
|
|
128
|
+
: null;
|
|
129
|
+
// CoordList: LIST OF LIST [3:3] OF IfcLengthMeasure — REAL literals.
|
|
130
|
+
const coordList = new Array(vertexCount);
|
|
131
|
+
for (let v = 0; v < vertexCount; v++) {
|
|
132
|
+
coordList[v] = [
|
|
133
|
+
stepReal(round(el.positions[v * 3])),
|
|
134
|
+
stepReal(round(el.positions[v * 3 + 1])),
|
|
135
|
+
stepReal(round(el.positions[v * 3 + 2])),
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
// CoordIndex: LIST OF LIST [3:3] OF IfcPositiveInteger — 1-BASED.
|
|
139
|
+
const coordIndex = new Array(triCount);
|
|
140
|
+
for (let t = 0; t < triCount; t++) {
|
|
141
|
+
coordIndex[t] = [
|
|
142
|
+
Number(el.indices[t * 3]) + 1,
|
|
143
|
+
Number(el.indices[t * 3 + 1]) + 1,
|
|
144
|
+
Number(el.indices[t * 3 + 2]) + 1,
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
const pointList = editor.addEntity('IfcCartesianPointList3D', [coordList]);
|
|
148
|
+
// (Coordinates, Normals, Closed, CoordIndex, PnIndex) — normals omitted
|
|
149
|
+
// (consumers compute flat normals), Closed unknown (decimation may open
|
|
150
|
+
// the shell).
|
|
151
|
+
const faceSet = editor.addEntity('IfcTriangulatedFaceSet', [
|
|
152
|
+
`#${pointList.expressId}`,
|
|
153
|
+
null,
|
|
154
|
+
null,
|
|
155
|
+
coordIndex,
|
|
156
|
+
null,
|
|
157
|
+
]);
|
|
158
|
+
const shapeRep = editor.addEntity('IfcShapeRepresentation', [
|
|
159
|
+
`#${contextId}`,
|
|
160
|
+
'Body',
|
|
161
|
+
'Tessellation',
|
|
162
|
+
[`#${faceSet.expressId}`],
|
|
163
|
+
]);
|
|
164
|
+
const pds = editor.addEntity('IfcProductDefinitionShape', [
|
|
165
|
+
null,
|
|
166
|
+
null,
|
|
167
|
+
[`#${shapeRep.expressId}`],
|
|
168
|
+
]);
|
|
169
|
+
editor.setPositionalAttribute(el.expressId, repAttrIndex, `#${pds.expressId}`);
|
|
170
|
+
if (el.color && el.color.length >= 3) {
|
|
171
|
+
const styleId = surfaceStyleFor(el.color);
|
|
172
|
+
editor.addEntity('IfcStyledItem', [`#${faceSet.expressId}`, [`#${styleId}`], null]);
|
|
173
|
+
}
|
|
174
|
+
replacedOldRep.set(el.expressId, oldRep);
|
|
175
|
+
report.replaced.push(el.expressId);
|
|
176
|
+
}
|
|
177
|
+
if (report.replaced.length === 0) {
|
|
178
|
+
return report;
|
|
179
|
+
}
|
|
180
|
+
pruneReplacedSubgraphs(store, editor, replacedOldRep, options.stripOpenings !== false, report);
|
|
181
|
+
return report;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* The file's 'Body' `IfcGeometricRepresentationSubContext` (the context
|
|
185
|
+
* every authored Body representation should share), falling back to a
|
|
186
|
+
* 'Model' `IfcGeometricRepresentationContext`, then to any geometric
|
|
187
|
+
* context. `null` when the file has none (pathological).
|
|
188
|
+
*/
|
|
189
|
+
function findBodyContextId(byId, getEntity) {
|
|
190
|
+
let modelContext = null;
|
|
191
|
+
let anyContext = null;
|
|
192
|
+
for (const [id, ref] of byId) {
|
|
193
|
+
const type = ref.type.toUpperCase();
|
|
194
|
+
if (type === 'IFCGEOMETRICREPRESENTATIONSUBCONTEXT') {
|
|
195
|
+
const attrs = getEntity(id)?.attributes;
|
|
196
|
+
if (typeof attrs?.[0] === 'string' && attrs[0].toUpperCase() === 'BODY') {
|
|
197
|
+
return id;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else if (type === 'IFCGEOMETRICREPRESENTATIONCONTEXT') {
|
|
201
|
+
const attrs = getEntity(id)?.attributes;
|
|
202
|
+
if (modelContext === null && typeof attrs?.[1] === 'string' && attrs[1].toUpperCase() === 'MODEL') {
|
|
203
|
+
modelContext = id;
|
|
204
|
+
}
|
|
205
|
+
if (anyContext === null)
|
|
206
|
+
anyContext = id;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return modelContext ?? anyContext;
|
|
210
|
+
}
|
|
211
|
+
function findAttrIndex(typeName, attrName) {
|
|
212
|
+
const attrs = getAllAttributesForEntity(typeName);
|
|
213
|
+
if (!attrs || attrs.length === 0)
|
|
214
|
+
return null;
|
|
215
|
+
const idx = attrs.findIndex((a) => a?.name === attrName);
|
|
216
|
+
return idx >= 0 ? idx : null;
|
|
217
|
+
}
|
|
218
|
+
function valuesAreFinite(values) {
|
|
219
|
+
for (let i = 0; i < values.length; i++) {
|
|
220
|
+
if (!Number.isFinite(values[i]))
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
function indicesInRange(indices, vertexCount) {
|
|
226
|
+
for (let i = 0; i < indices.length; i++) {
|
|
227
|
+
const v = indices[i];
|
|
228
|
+
if (!Number.isInteger(v) || v < 0 || v >= vertexCount)
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
function clamp01(v) {
|
|
234
|
+
return Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : 1;
|
|
235
|
+
}
|
|
236
|
+
function roundTo(v, decimals) {
|
|
237
|
+
const f = 10 ** decimals;
|
|
238
|
+
return Math.round(v * f) / f;
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=demesh-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demesh-writer.js","sourceRoot":"","sources":["../src/demesh-writer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export { collectReferencedEntityIds, getVisibleEntityIds, collectStyleEntities }
|
|
|
8
8
|
export { convertEntityType, convertStepLine, needsConversion, describeConversion, type IfcSchemaVersion } from './schema-converter.js';
|
|
9
9
|
export { Ifc5Exporter, IFC5_KNOWN_PROP_NAMES, type Ifc5ExportOptions, type Ifc5ExportResult } from './ifc5-exporter.js';
|
|
10
10
|
export type { Vec3, LodInput, Lod0Element, Lod0Json, Lod1MetaJson, GenerateLod1Result } from './lod-geometry-types.js';
|
|
11
|
+
export { DemeshSession, type DemeshSessionOptions, type DemeshSimplifyResult, type DemeshExportResult, } from './demesh-session.js';
|
|
12
|
+
export { applySimplifiedGeometry, type ApplySimplifiedGeometryOptions, type DemeshApplyReport, type DemeshEditorLike, type SimplifiedElementGeometry, } from './demesh-writer.js';
|
|
11
13
|
export { generateLod0 } from './lod0-generator.js';
|
|
12
14
|
export { generateLod1, type GenerateLod1Options } from './lod1-generator.js';
|
|
13
15
|
export { parseGLB, extractGlbMapping, parseGLBToMeshData, countGlbMeshes } from './glb.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;GAEG;AAIH,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAKnF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxI,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC9K,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACjH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACvI,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGxH,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACvH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;GAEG;AAIH,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAKnF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxI,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC9K,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACjH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACvI,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGxH,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACvH,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,uBAAuB,EACvB,KAAK,8BAA8B,EACnC,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,GAC/B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC"}
|