@bldrs-ai/conway 1.437.1313 → 1.440.1336
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/compiled/Dist/ConwayGeomWasmNode.js +0 -0
- package/compiled/Dist/ConwayGeomWasmNodeMT.js +0 -0
- package/compiled/Dist/ConwayGeomWasmWeb.js +0 -0
- package/compiled/Dist/ConwayGeomWasmWebMT.wasm +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNode.js +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmNodeMT.js +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWeb.js +0 -0
- package/compiled/dependencies/conway-geom/Dist/ConwayGeomWasmWebMT.wasm +0 -0
- package/compiled/examples/browser-bundled.cjs +21 -8
- package/compiled/examples/cli-bundled.cjs +70 -13
- package/compiled/examples/cli-step-bundled.cjs +115 -28
- package/compiled/examples/validator-bundled.cjs +21 -8
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.d.ts.map +1 -1
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.js +153 -23
- package/compiled/src/AP214E3_2010/ap214_geometry_extraction.test.js +6 -1
- package/compiled/src/compat/web-ifc/coordination_f64.d.ts +12 -0
- package/compiled/src/compat/web-ifc/coordination_f64.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/coordination_f64.js +13 -0
- package/compiled/src/compat/web-ifc/ifc_api.d.ts +13 -0
- package/compiled/src/compat/web-ifc/ifc_api.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api.js +19 -0
- package/compiled/src/compat/web-ifc/ifc_api_deferred_open.test.js +26 -5
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough.d.ts +9 -0
- package/compiled/src/compat/web-ifc/ifc_api_model_passthrough.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_preview_coordination.test.d.ts +2 -0
- package/compiled/src/compat/web-ifc/ifc_api_preview_coordination.test.d.ts.map +1 -0
- package/compiled/src/compat/web-ifc/ifc_api_preview_coordination.test.js +124 -0
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts +10 -0
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ap214.js +35 -2
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.d.ts +34 -10
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.d.ts.map +1 -1
- package/compiled/src/compat/web-ifc/ifc_api_proxy_ifc.js +94 -24
- package/compiled/src/ifc/ifc_geometry_extraction.d.ts +27 -3
- package/compiled/src/ifc/ifc_geometry_extraction.d.ts.map +1 -1
- package/compiled/src/ifc/ifc_geometry_extraction.js +56 -4
- package/compiled/src/step/parsing/decode_utf8.d.ts +15 -0
- package/compiled/src/step/parsing/decode_utf8.d.ts.map +1 -1
- package/compiled/src/step/parsing/decode_utf8.js +28 -0
- package/compiled/src/step/parsing/step_string_parser.js +8 -8
- package/compiled/src/version/version.js +1 -1
- package/compiled/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/* eslint-disable no-magic-numbers, dot-notation */
|
|
2
|
+
// Adopted preview-channel coordination frames must be validated against
|
|
3
|
+
// the durable walk's first geometry (Share#1634): a model can carry
|
|
4
|
+
// geometry in more than one frame, so a preview anchored on a
|
|
5
|
+
// local-scale unit hands the deferred pump a ~identity frame and the
|
|
6
|
+
// georeferenced body streams out raw. The deferred pump now re-derives
|
|
7
|
+
// from its own first geometry when the adopted frame leaves it beyond
|
|
8
|
+
// the large-coordinate budget.
|
|
9
|
+
//
|
|
10
|
+
// The adoption is injected directly (tiny fixtures parse in one tick,
|
|
11
|
+
// so the parse-time preview channel never fires on them); the injected
|
|
12
|
+
// identity frame is exactly what a wrong-frame preview anchor produces.
|
|
13
|
+
import * as fs from "fs";
|
|
14
|
+
import { beforeAll, describe, expect, test } from "@jest/globals";
|
|
15
|
+
import { LARGE_COORDINATE_BUDGET_M } from "./coordination_f64.js";
|
|
16
|
+
import { IfcAPI } from "./ifc_api.js";
|
|
17
|
+
const SETTINGS = {
|
|
18
|
+
COORDINATE_TO_ORIGIN: true,
|
|
19
|
+
USE_FAST_BOOLS: true,
|
|
20
|
+
DEFER_GEOMETRY: true,
|
|
21
|
+
};
|
|
22
|
+
const IDENTITY = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
23
|
+
let api;
|
|
24
|
+
let georeferenced;
|
|
25
|
+
let local;
|
|
26
|
+
/**
|
|
27
|
+
* Pump a deferred model to completion and collect every placement
|
|
28
|
+
* translation.
|
|
29
|
+
*
|
|
30
|
+
* @param modelID The deferred model.
|
|
31
|
+
* @return {number[][]} One [x, y, z] per placed geometry.
|
|
32
|
+
*/
|
|
33
|
+
function pumpTranslations(modelID) {
|
|
34
|
+
const translations = [];
|
|
35
|
+
for (;;) {
|
|
36
|
+
const batch = [];
|
|
37
|
+
const { extracted, remaining } = api.ExtractGeometryBatch(modelID, 4, (mesh) => batch.push(mesh));
|
|
38
|
+
for (const mesh of batch) {
|
|
39
|
+
for (let where = 0; where < mesh.geometries.size(); ++where) {
|
|
40
|
+
const placed = mesh.geometries.get(where);
|
|
41
|
+
translations.push([
|
|
42
|
+
placed.flatTransformation[12],
|
|
43
|
+
placed.flatTransformation[13],
|
|
44
|
+
placed.flatTransformation[14],
|
|
45
|
+
]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (remaining === 0 || extracted === 0) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return translations;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* @param translations Placement translations.
|
|
56
|
+
* @return {number} Largest absolute component.
|
|
57
|
+
*/
|
|
58
|
+
function maxComponent(translations) {
|
|
59
|
+
return translations.reduce((max, t) => Math.max(max, ...t.map(Math.abs)), 0);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Simulate a preview channel that anchored in the wrong frame: adopt an
|
|
63
|
+
* identity coordination exactly the way createDeferred does.
|
|
64
|
+
*
|
|
65
|
+
* @param modelID The deferred model.
|
|
66
|
+
*/
|
|
67
|
+
function injectIdentityPreviewFrame(modelID) {
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
|
+
const proxy = api.models.get(modelID);
|
|
70
|
+
expect(proxy).toBeDefined();
|
|
71
|
+
proxy["demandCoordination_"] = [...IDENTITY];
|
|
72
|
+
proxy["_isCoordinated"] = true;
|
|
73
|
+
proxy["demandCoordinationFromPreview_"] = true;
|
|
74
|
+
}
|
|
75
|
+
beforeAll(async () => {
|
|
76
|
+
api = new IfcAPI();
|
|
77
|
+
await api.Init();
|
|
78
|
+
georeferenced = new Uint8Array(fs.readFileSync("data/index_georeferenced.ifc"));
|
|
79
|
+
local = new Uint8Array(fs.readFileSync("data/index.ifc"));
|
|
80
|
+
}, 120000);
|
|
81
|
+
describe("deferred pump preview-frame validation (Share#1634)", () => {
|
|
82
|
+
test("wrong-frame adopted coordination is re-derived on a georeferenced model", async () => {
|
|
83
|
+
// Control: no preview involvement — the pump derives its own frame.
|
|
84
|
+
const controlID = await api.OpenModelStreamed(georeferenced, { ...SETTINGS });
|
|
85
|
+
const control = pumpTranslations(controlID);
|
|
86
|
+
expect(control.length).toBeGreaterThan(0);
|
|
87
|
+
expect(maxComponent(control)).toBeLessThan(LARGE_COORDINATE_BUDGET_M);
|
|
88
|
+
// Explicit applied-frame report (Share#1634 acceptance): the real
|
|
89
|
+
// recenter offset — while GetCoordinationMatrix keeps its classic
|
|
90
|
+
// identity contract for assembled-model stamping.
|
|
91
|
+
const applied = api.GetAppliedCoordinationMatrix(controlID);
|
|
92
|
+
expect(Math.max(...applied.map(Math.abs)))
|
|
93
|
+
.toBeGreaterThan(LARGE_COORDINATE_BUDGET_M);
|
|
94
|
+
expect(api.GetCoordinationMatrix(controlID)).toEqual(IDENTITY);
|
|
95
|
+
// Adopting an identity frame (wrong-frame preview anchor) must not
|
|
96
|
+
// leave the body raw: the first durable geometry fails the budget
|
|
97
|
+
// check and the frame re-derives.
|
|
98
|
+
const adoptedID = await api.OpenModelStreamed(georeferenced, { ...SETTINGS });
|
|
99
|
+
injectIdentityPreviewFrame(adoptedID);
|
|
100
|
+
const adopted = pumpTranslations(adoptedID);
|
|
101
|
+
expect(adopted.length).toEqual(control.length);
|
|
102
|
+
expect(maxComponent(adopted)).toBeLessThan(LARGE_COORDINATE_BUDGET_M);
|
|
103
|
+
for (let where = 0; where < control.length; ++where) {
|
|
104
|
+
expect(adopted[where][0]).toBeCloseTo(control[where][0], 6);
|
|
105
|
+
expect(adopted[where][1]).toBeCloseTo(control[where][1], 6);
|
|
106
|
+
expect(adopted[where][2]).toBeCloseTo(control[where][2], 6);
|
|
107
|
+
}
|
|
108
|
+
}, 120000);
|
|
109
|
+
test("a within-budget adopted frame is kept (no false-positive re-derive)", async () => {
|
|
110
|
+
// On a local-scale model an identity frame is a VALID preview
|
|
111
|
+
// frame — validation must keep it, preserving preview/durable
|
|
112
|
+
// agreement, rather than re-deriving to the first-geometry anchor.
|
|
113
|
+
const adoptedID = await api.OpenModelStreamed(local, { ...SETTINGS });
|
|
114
|
+
injectIdentityPreviewFrame(adoptedID);
|
|
115
|
+
const adopted = pumpTranslations(adoptedID);
|
|
116
|
+
expect(adopted.length).toBeGreaterThan(0);
|
|
117
|
+
expect(maxComponent(adopted)).toBeLessThan(LARGE_COORDINATE_BUDGET_M);
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
119
|
+
const proxy = api.models.get(adoptedID);
|
|
120
|
+
// Frame survived untouched: still exactly the injected identity.
|
|
121
|
+
expect([...proxy["demandCoordination_"]]).toEqual(IDENTITY);
|
|
122
|
+
expect(proxy["demandCoordinationFromPreview_"]).toBe(false);
|
|
123
|
+
}, 120000);
|
|
124
|
+
});
|
|
@@ -70,6 +70,8 @@ export declare class IfcApiProxyAP214 implements IfcApiModelPassthrough {
|
|
|
70
70
|
* identity contract (see the IFC proxy's demandCoordination_ note).
|
|
71
71
|
*/
|
|
72
72
|
private demandCoordination_?;
|
|
73
|
+
/** Unvalidated adopted preview frame — see the IFC proxy twin. */
|
|
74
|
+
private demandCoordinationFromPreview_;
|
|
73
75
|
_isCoordinated: boolean;
|
|
74
76
|
linearScalingFactor: number;
|
|
75
77
|
identity: number[];
|
|
@@ -316,6 +318,14 @@ export declare class IfcApiProxyAP214 implements IfcApiModelPassthrough {
|
|
|
316
318
|
* @return {Array<number>}
|
|
317
319
|
*/
|
|
318
320
|
getCoordinationMatrix(): Array<number>;
|
|
321
|
+
/**
|
|
322
|
+
* The coordination frame actually applied to emitted placements —
|
|
323
|
+
* the derived (or validated adopted) recenter, identity when no
|
|
324
|
+
* recenter ran. See ifc_api_model_passthrough.getAppliedCoordination.
|
|
325
|
+
*
|
|
326
|
+
* @return {Array<number>} column-major mat4
|
|
327
|
+
*/
|
|
328
|
+
getAppliedCoordination(): Array<number>;
|
|
319
329
|
/**
|
|
320
330
|
*
|
|
321
331
|
* @param ptr
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ifc_api_proxy_ap214.d.ts","sourceRoot":"","sources":["../../../../src/compat/web-ifc/ifc_api_proxy_ap214.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,cAAc,EACf,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EACL,QAAQ,EACR,WAAW,EACX,WAAW,EACX,cAAc,EACd,cAAc,EACd,WAAW,EACX,MAAM,EACP,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"ifc_api_proxy_ap214.d.ts","sourceRoot":"","sources":["../../../../src/compat/web-ifc/ifc_api_proxy_ap214.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConwayGeometry, } from "../../index.js";
|
|
2
2
|
import * as glmatrix from "gl-matrix";
|
|
3
|
-
import { composeTransformF64, deriveCoordinationF64 } from "./coordination_f64.js";
|
|
3
|
+
import { LARGE_COORDINATE_BUDGET_M, TRANSLATION_X, TRANSLATION_Y, TRANSLATION_Z, composeTransformF64, deriveCoordinationF64 } from "./coordination_f64.js";
|
|
4
4
|
import Logger from "../../logging/logger.js";
|
|
5
5
|
import ParsingBuffer from "../../parsing/parsing_buffer.js";
|
|
6
6
|
import { ExtractResult } from "../../index.js";
|
|
@@ -109,6 +109,8 @@ export class IfcApiProxyAP214 {
|
|
|
109
109
|
* the IFC proxy's delta capture; see its demandCapturedCounts_ note.
|
|
110
110
|
*/
|
|
111
111
|
this.demandCapturedCounts_ = new Map();
|
|
112
|
+
/** Unvalidated adopted preview frame — see the IFC proxy twin. */
|
|
113
|
+
this.demandCoordinationFromPreview_ = false;
|
|
112
114
|
this._isCoordinated = false;
|
|
113
115
|
this.linearScalingFactor = 1;
|
|
114
116
|
this.identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
@@ -214,6 +216,9 @@ export class IfcApiProxyAP214 {
|
|
|
214
216
|
if (this.deferredMode_ && loadState.previewCoordinationMatrix !== void 0) {
|
|
215
217
|
this.demandCoordination_ = loadState.previewCoordinationMatrix;
|
|
216
218
|
this._isCoordinated = true;
|
|
219
|
+
// Adopted, not derived — validated against the durable walk's
|
|
220
|
+
// first geometry (see the IFC proxy's demandCoordinationFromPreview_).
|
|
221
|
+
this.demandCoordinationFromPreview_ = true;
|
|
217
222
|
}
|
|
218
223
|
let FILE_NAME = stepHeader.headers.get("FILE_NAME");
|
|
219
224
|
if (FILE_NAME !== void 0) {
|
|
@@ -848,6 +853,16 @@ export class IfcApiProxyAP214 {
|
|
|
848
853
|
const coordinationMatrix = this.model[5];
|
|
849
854
|
return Array.from(coordinationMatrix);
|
|
850
855
|
}
|
|
856
|
+
/**
|
|
857
|
+
* The coordination frame actually applied to emitted placements —
|
|
858
|
+
* the derived (or validated adopted) recenter, identity when no
|
|
859
|
+
* recenter ran. See ifc_api_model_passthrough.getAppliedCoordination.
|
|
860
|
+
*
|
|
861
|
+
* @return {Array<number>} column-major mat4
|
|
862
|
+
*/
|
|
863
|
+
getAppliedCoordination() {
|
|
864
|
+
return [...(this.demandCoordination_ ?? this.identity)];
|
|
865
|
+
}
|
|
851
866
|
/**
|
|
852
867
|
*
|
|
853
868
|
* @param ptr
|
|
@@ -1002,8 +1017,11 @@ export class IfcApiProxyAP214 {
|
|
|
1002
1017
|
doubleSided: true,
|
|
1003
1018
|
blend: 0,
|
|
1004
1019
|
};
|
|
1020
|
+
const validatePreviewFrame = this.demandCoordinationFromPreview_ &&
|
|
1021
|
+
this.settings?.COORDINATE_TO_ORIGIN === true;
|
|
1005
1022
|
let nativePt;
|
|
1006
|
-
if (!this._isCoordinated
|
|
1023
|
+
if ((!this._isCoordinated || validatePreviewFrame) &&
|
|
1024
|
+
this.settings?.COORDINATE_TO_ORIGIN) {
|
|
1007
1025
|
nativePt = geometry.geometry.getPoint(0);
|
|
1008
1026
|
}
|
|
1009
1027
|
const expressID = model.getElementByLocalID(geometry.localID)?.expressID;
|
|
@@ -1017,6 +1035,21 @@ export class IfcApiProxyAP214 {
|
|
|
1017
1035
|
this.demandCoordination_ = derived;
|
|
1018
1036
|
this._isCoordinated = true;
|
|
1019
1037
|
}
|
|
1038
|
+
else if (validatePreviewFrame) {
|
|
1039
|
+
// One-shot adopted-frame validation — see the IFC proxy twin
|
|
1040
|
+
// (Share#1634). Bare composition here: AP214 has no per-leaf
|
|
1041
|
+
// recenter (issue #308).
|
|
1042
|
+
this.demandCoordinationFromPreview_ = false;
|
|
1043
|
+
const probe = composeTransformF64(coordinationMatrix, geometryTransform);
|
|
1044
|
+
const magnitude = Math.max(Math.abs(probe[TRANSLATION_X]), Math.abs(probe[TRANSLATION_Y]), Math.abs(probe[TRANSLATION_Z]));
|
|
1045
|
+
if (magnitude > LARGE_COORDINATE_BUDGET_M) {
|
|
1046
|
+
const derived = deriveCoordinationF64(geometryTransform, nativePt, this.NormalizeMat, this.linearScalingFactor);
|
|
1047
|
+
coordinationMatrix = derived;
|
|
1048
|
+
this.demandCoordination_ = derived;
|
|
1049
|
+
Logger.info(`[deferred] preview coordination frame rejected (first durable ` +
|
|
1050
|
+
`placement at ${Math.round(magnitude)}m); re-derived from the durable anchor`);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1020
1053
|
// Bare composition — no per-leaf recenter (issue #308: AP214
|
|
1021
1054
|
// instances share one geometry buffer), matching streamAllMeshes.
|
|
1022
1055
|
const newTransformArr = composeTransformF64(coordinationMatrix, geometryTransform);
|
|
@@ -72,16 +72,20 @@ export declare class IfcApiProxyIfc implements IfcApiModelPassthrough {
|
|
|
72
72
|
/** Cursor into demandProducts_ — products before it are extracted. */
|
|
73
73
|
private demandCursor_;
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* relating object's
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
|
|
84
|
-
|
|
75
|
+
* Deferred-mode rel-aggregates worklist, pumped batch-by-batch AFTER
|
|
76
|
+
* the product cursor completes. Classic's whole-model walk follows
|
|
77
|
+
* its product loop with a second pass extracting every
|
|
78
|
+
* IfcRelAggregates related product using the relating object's
|
|
79
|
+
* rel-voids. Aggregate-target products are EXCLUDED from
|
|
80
|
+
* demandProducts_ (see aggregateTargetLocalIDs) so this pass is their
|
|
81
|
+
* first and only extraction — content is final when their instances
|
|
82
|
+
* are captured, and no placement is ever appended over an
|
|
83
|
+
* already-delivered one (the ILNA missing-facades / 388_4
|
|
84
|
+
* duplicate-placement class).
|
|
85
|
+
*/
|
|
86
|
+
private demandAggregates_?;
|
|
87
|
+
/** Cursor into demandAggregates_ — items before it are extracted. */
|
|
88
|
+
private demandAggregatesCursor_;
|
|
85
89
|
/**
|
|
86
90
|
* Coordination matrix the deferred capture derived (or adopted from
|
|
87
91
|
* the parse-time preview channel). Kept OFF the model tuple's slot 5
|
|
@@ -93,6 +97,18 @@ export declare class IfcApiProxyIfc implements IfcApiModelPassthrough {
|
|
|
93
97
|
* memory.
|
|
94
98
|
*/
|
|
95
99
|
private demandCoordination_?;
|
|
100
|
+
/**
|
|
101
|
+
* True while an adopted preview-channel coordination frame is still
|
|
102
|
+
* unvalidated against the durable walk's first geometry. A model can
|
|
103
|
+
* carry geometry in more than one frame (ISSUE_129: a local-scale
|
|
104
|
+
* annotation previews first while the body is georeferenced at
|
|
105
|
+
* ~8.3e6 m), so a frame anchored on the wrong unit leaves the body
|
|
106
|
+
* raw — the Share#1634 browser-vs-node divergence, which was really
|
|
107
|
+
* preview-vs-no-preview. streamNewMeshes_ clears this on its first
|
|
108
|
+
* geometry, re-deriving from it when the adopted frame fails the
|
|
109
|
+
* large-coordinate budget.
|
|
110
|
+
*/
|
|
111
|
+
private demandCoordinationFromPreview_;
|
|
96
112
|
_isCoordinated: boolean;
|
|
97
113
|
linearScalingFactor: number;
|
|
98
114
|
identity: number[];
|
|
@@ -376,6 +392,14 @@ export declare class IfcApiProxyIfc implements IfcApiModelPassthrough {
|
|
|
376
392
|
* @return {Array<number>}
|
|
377
393
|
*/
|
|
378
394
|
getCoordinationMatrix(): Array<number>;
|
|
395
|
+
/**
|
|
396
|
+
* The coordination frame actually applied to emitted placements —
|
|
397
|
+
* the derived (or validated adopted) recenter, identity when no
|
|
398
|
+
* recenter ran. See ifc_api_model_passthrough.getAppliedCoordination.
|
|
399
|
+
*
|
|
400
|
+
* @return {Array<number>} column-major mat4
|
|
401
|
+
*/
|
|
402
|
+
getAppliedCoordination(): Array<number>;
|
|
379
403
|
/**
|
|
380
404
|
*
|
|
381
405
|
* @param ptr
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ifc_api_proxy_ifc.d.ts","sourceRoot":"","sources":["../../../../src/compat/web-ifc/ifc_api_proxy_ifc.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,cAAc,EACf,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,YAAY,MAAM,0BAA0B,CAAA;AACnD,OAAO,EACL,QAAQ,EACR,WAAW,EACX,WAAW,EACX,cAAc,EACd,cAAc,EACd,WAAW,EACX,MAAM,EACP,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"ifc_api_proxy_ifc.d.ts","sourceRoot":"","sources":["../../../../src/compat/web-ifc/ifc_api_proxy_ifc.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConwayGeometry, } from "../../index.js";
|
|
2
2
|
import IfcStepModel from "../../ifc/ifc_step_model.js";
|
|
3
3
|
import * as glmatrix from "gl-matrix";
|
|
4
|
-
import { composeTransformF64, deriveCoordinationF64 } from "./coordination_f64.js";
|
|
4
|
+
import { LARGE_COORDINATE_BUDGET_M, TRANSLATION_X, TRANSLATION_Y, TRANSLATION_Z, composeTransformF64, deriveCoordinationF64 } from "./coordination_f64.js";
|
|
5
5
|
import { IfcProperties } from "./ifc_properties.js";
|
|
6
6
|
import Logger from "../../logging/logger.js";
|
|
7
7
|
import { ProgressTracker } from "../../core/progress.js";
|
|
@@ -20,7 +20,7 @@ import Memory from "../../memory/memory.js";
|
|
|
20
20
|
import { FromRawLineData } from "./ifc2x4_helper.js";
|
|
21
21
|
import { shimIfcEntityMap, shimIfcEntityReverseMap } from "./shim_schema_mapping.js";
|
|
22
22
|
import { EntityTypesIfcCount } from "../../ifc/ifc4_gen/entity_types_ifc.gen.js";
|
|
23
|
-
import { IfcProduct, IfcRoot } from "../../ifc/ifc4_gen/index.js";
|
|
23
|
+
import { IfcProduct, IfcRelAggregates, IfcRoot } from "../../ifc/ifc4_gen/index.js";
|
|
24
24
|
import { CanonicalMeshType } from "../../index.js";
|
|
25
25
|
// Batch size used when a whole-model consumer (streamAllMeshes) drains
|
|
26
26
|
// a deferred model's remaining products synchronously.
|
|
@@ -58,17 +58,20 @@ export class IfcApiProxyIfc {
|
|
|
58
58
|
this.demandCapturedCounts_ = new Map();
|
|
59
59
|
/** Cursor into demandProducts_ — products before it are extracted. */
|
|
60
60
|
this.demandCursor_ = 0;
|
|
61
|
+
/** Cursor into demandAggregates_ — items before it are extracted. */
|
|
62
|
+
this.demandAggregatesCursor_ = 0;
|
|
61
63
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
64
|
+
* True while an adopted preview-channel coordination frame is still
|
|
65
|
+
* unvalidated against the durable walk's first geometry. A model can
|
|
66
|
+
* carry geometry in more than one frame (ISSUE_129: a local-scale
|
|
67
|
+
* annotation previews first while the body is georeferenced at
|
|
68
|
+
* ~8.3e6 m), so a frame anchored on the wrong unit leaves the body
|
|
69
|
+
* raw — the Share#1634 browser-vs-node divergence, which was really
|
|
70
|
+
* preview-vs-no-preview. streamNewMeshes_ clears this on its first
|
|
71
|
+
* geometry, re-deriving from it when the adopted frame fails the
|
|
72
|
+
* large-coordinate budget.
|
|
70
73
|
*/
|
|
71
|
-
this.
|
|
74
|
+
this.demandCoordinationFromPreview_ = false;
|
|
72
75
|
this._isCoordinated = false;
|
|
73
76
|
this.linearScalingFactor = 1;
|
|
74
77
|
this.identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
|
@@ -175,6 +178,9 @@ export class IfcApiProxyIfc {
|
|
|
175
178
|
if (this.deferredMode_ && loadState.previewCoordinationMatrix !== void 0) {
|
|
176
179
|
this.demandCoordination_ = loadState.previewCoordinationMatrix;
|
|
177
180
|
this._isCoordinated = true;
|
|
181
|
+
// Adopted, not derived: validate against the durable walk's first
|
|
182
|
+
// geometry before trusting it (see demandCoordinationFromPreview_).
|
|
183
|
+
this.demandCoordinationFromPreview_ = true;
|
|
178
184
|
}
|
|
179
185
|
let FILE_NAME = stepHeader.headers.get("FILE_NAME");
|
|
180
186
|
if (FILE_NAME !== void 0) {
|
|
@@ -984,6 +990,16 @@ export class IfcApiProxyIfc {
|
|
|
984
990
|
/* eslint-enable no-unused-vars */
|
|
985
991
|
return Array.from(coordinationMatrix);
|
|
986
992
|
}
|
|
993
|
+
/**
|
|
994
|
+
* The coordination frame actually applied to emitted placements —
|
|
995
|
+
* the derived (or validated adopted) recenter, identity when no
|
|
996
|
+
* recenter ran. See ifc_api_model_passthrough.getAppliedCoordination.
|
|
997
|
+
*
|
|
998
|
+
* @return {Array<number>} column-major mat4
|
|
999
|
+
*/
|
|
1000
|
+
getAppliedCoordination() {
|
|
1001
|
+
return [...(this.demandCoordination_ ?? this.identity)];
|
|
1002
|
+
}
|
|
987
1003
|
/**
|
|
988
1004
|
*
|
|
989
1005
|
* @param ptr
|
|
@@ -1038,7 +1054,9 @@ export class IfcApiProxyIfc {
|
|
|
1038
1054
|
releaseGeometry() {
|
|
1039
1055
|
if (this.deferredMode_ &&
|
|
1040
1056
|
this.demandProducts_ !== void 0 &&
|
|
1041
|
-
this.demandCursor_ < this.demandProducts_.length
|
|
1057
|
+
(this.demandCursor_ < this.demandProducts_.length ||
|
|
1058
|
+
this.demandAggregatesCursor_ <
|
|
1059
|
+
(this.demandAggregates_?.length ?? 0))) {
|
|
1042
1060
|
Logger.warning("[ReleaseModelGeometry]: deferred pump not drained \u2014 not releasing");
|
|
1043
1061
|
return false;
|
|
1044
1062
|
}
|
|
@@ -1086,14 +1104,33 @@ export class IfcApiProxyIfc {
|
|
|
1086
1104
|
return { extracted: 0, remaining: 0 };
|
|
1087
1105
|
}
|
|
1088
1106
|
if (this.demandProducts_ === void 0) {
|
|
1107
|
+
// Aggregate-target products are extracted ONLY by the
|
|
1108
|
+
// rel-aggregates pass below (with the relating object's master
|
|
1109
|
+
// rel-voids), never by the per-product pass: extracting them here
|
|
1110
|
+
// first would emit their instances with the uncut/placeholder
|
|
1111
|
+
// content and the pass's later replacement would never reach an
|
|
1112
|
+
// incremental consumer (it copies at delivery), while the pass's
|
|
1113
|
+
// second scene instance would draw over the first (see
|
|
1114
|
+
// aggregateTargetLocalIDs).
|
|
1115
|
+
const aggregateTargets = this.conwayGeometry_.aggregateTargetLocalIDs();
|
|
1089
1116
|
const products = [];
|
|
1090
1117
|
for (const product of this.model[0].types(IfcProduct)) {
|
|
1118
|
+
if (aggregateTargets.has(product.localID)) {
|
|
1119
|
+
continue;
|
|
1120
|
+
}
|
|
1091
1121
|
products.push(product.localID);
|
|
1092
1122
|
}
|
|
1123
|
+
const aggregates = [];
|
|
1124
|
+
for (const relAggregate of this.model[0].types(IfcRelAggregates)) {
|
|
1125
|
+
aggregates.push(relAggregate);
|
|
1126
|
+
}
|
|
1093
1127
|
this.demandProducts_ = products;
|
|
1128
|
+
this.demandAggregates_ = aggregates;
|
|
1094
1129
|
this.demandCursor_ = 0;
|
|
1130
|
+
this.demandAggregatesCursor_ = 0;
|
|
1095
1131
|
}
|
|
1096
|
-
const
|
|
1132
|
+
const budget = Math.max(batchSize, 1);
|
|
1133
|
+
const end = Math.min(this.demandCursor_ + budget, this.demandProducts_.length);
|
|
1097
1134
|
let extracted = 0;
|
|
1098
1135
|
for (; this.demandCursor_ < end; ++this.demandCursor_) {
|
|
1099
1136
|
const localID = this.demandProducts_[this.demandCursor_];
|
|
@@ -1101,23 +1138,27 @@ export class IfcApiProxyIfc {
|
|
|
1101
1138
|
++extracted;
|
|
1102
1139
|
}
|
|
1103
1140
|
}
|
|
1104
|
-
// Classic parity: once the product walk completes,
|
|
1105
|
-
// whole-model walk's second (rel-aggregates master-voids) pass
|
|
1106
|
-
// the
|
|
1107
|
-
//
|
|
1108
|
-
//
|
|
1109
|
-
|
|
1141
|
+
// Classic parity: once the product walk completes, pump the
|
|
1142
|
+
// whole-model walk's second (rel-aggregates master-voids) pass with
|
|
1143
|
+
// the same per-call budget — batch-by-batch, not as one end-of-load
|
|
1144
|
+
// stall — so aggregate parts stream in cut, exactly once, with
|
|
1145
|
+
// final content (see demandAggregates_).
|
|
1146
|
+
const aggregates = this.demandAggregates_ ?? [];
|
|
1110
1147
|
if (this.demandCursor_ >= this.demandProducts_.length &&
|
|
1111
|
-
|
|
1112
|
-
this.
|
|
1113
|
-
this.
|
|
1148
|
+
this.demandAggregatesCursor_ < aggregates.length) {
|
|
1149
|
+
const aggregatesEnd = Math.min(this.demandAggregatesCursor_ + (budget - extracted), aggregates.length);
|
|
1150
|
+
for (; this.demandAggregatesCursor_ < aggregatesEnd; ++this.demandAggregatesCursor_) {
|
|
1151
|
+
this.conwayGeometry_.extractRelAggregateGeometry(aggregates[this.demandAggregatesCursor_]);
|
|
1152
|
+
++extracted;
|
|
1153
|
+
}
|
|
1114
1154
|
}
|
|
1115
1155
|
if (meshCallback !== void 0) {
|
|
1116
1156
|
this.streamNewMeshes_(meshCallback);
|
|
1117
1157
|
}
|
|
1118
1158
|
return {
|
|
1119
1159
|
extracted,
|
|
1120
|
-
remaining: this.demandProducts_.length - this.demandCursor_
|
|
1160
|
+
remaining: (this.demandProducts_.length - this.demandCursor_) +
|
|
1161
|
+
(aggregates.length - this.demandAggregatesCursor_),
|
|
1121
1162
|
};
|
|
1122
1163
|
}
|
|
1123
1164
|
/**
|
|
@@ -1175,8 +1216,11 @@ export class IfcApiProxyIfc {
|
|
|
1175
1216
|
doubleSided: true,
|
|
1176
1217
|
blend: 0,
|
|
1177
1218
|
};
|
|
1219
|
+
const validatePreviewFrame = this.demandCoordinationFromPreview_ &&
|
|
1220
|
+
this.settings?.COORDINATE_TO_ORIGIN === true;
|
|
1178
1221
|
let nativePt;
|
|
1179
|
-
if (!this._isCoordinated
|
|
1222
|
+
if ((!this._isCoordinated || validatePreviewFrame) &&
|
|
1223
|
+
this.settings?.COORDINATE_TO_ORIGIN) {
|
|
1180
1224
|
nativePt = geometry.geometry.getPoint(0);
|
|
1181
1225
|
}
|
|
1182
1226
|
// normalize() recenters the shared geometry buffer (side effect)
|
|
@@ -1195,6 +1239,25 @@ export class IfcApiProxyIfc {
|
|
|
1195
1239
|
this.demandCoordination_ = derived;
|
|
1196
1240
|
this._isCoordinated = true;
|
|
1197
1241
|
}
|
|
1242
|
+
else if (validatePreviewFrame) {
|
|
1243
|
+
// One-shot check of an adopted preview frame against the durable
|
|
1244
|
+
// walk's first geometry: when the composed placement still lands
|
|
1245
|
+
// beyond the large-coordinate budget, the preview anchored in a
|
|
1246
|
+
// different frame than the model body (Share#1634) — re-derive
|
|
1247
|
+
// from this geometry, the classic path's anchor. The throwaway
|
|
1248
|
+
// preview scene may briefly disagree; the durable model must
|
|
1249
|
+
// place like the classic open.
|
|
1250
|
+
this.demandCoordinationFromPreview_ = false;
|
|
1251
|
+
const probe = composeTransformF64(coordinationMatrix, geometryTransform, center);
|
|
1252
|
+
const magnitude = Math.max(Math.abs(probe[TRANSLATION_X]), Math.abs(probe[TRANSLATION_Y]), Math.abs(probe[TRANSLATION_Z]));
|
|
1253
|
+
if (magnitude > LARGE_COORDINATE_BUDGET_M) {
|
|
1254
|
+
const derived = deriveCoordinationF64(geometryTransform, nativePt, this.NormalizeMat, this.linearScalingFactor);
|
|
1255
|
+
coordinationMatrix = derived;
|
|
1256
|
+
this.demandCoordination_ = derived;
|
|
1257
|
+
Logger.info(`[deferred] preview coordination frame rejected (first durable ` +
|
|
1258
|
+
`placement at ${Math.round(magnitude)}m); re-derived from the durable anchor`);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1198
1261
|
const newTransformArr = composeTransformF64(coordinationMatrix, geometryTransform, center);
|
|
1199
1262
|
geometryMaterialTransformMap.set(expressID, [geometry.geometry, material_, newTransformArr]);
|
|
1200
1263
|
const color = {
|
|
@@ -1317,6 +1380,9 @@ export class IfcApiProxyIfc {
|
|
|
1317
1380
|
const geometryTransform = nativeTransform?.getValues();
|
|
1318
1381
|
if (!this._isCoordinated && this.settings?.COORDINATE_TO_ORIGIN) {
|
|
1319
1382
|
coordinationMatrix = deriveCoordinationF64(geometryTransform, nativePt, this.NormalizeMat, this.linearScalingFactor);
|
|
1383
|
+
// Persisted for getAppliedCoordination (Share#1634): report
|
|
1384
|
+
// the real applied frame, not the classic silent identity.
|
|
1385
|
+
this.demandCoordination_ = Array.from(coordinationMatrix);
|
|
1320
1386
|
this._isCoordinated = true;
|
|
1321
1387
|
}
|
|
1322
1388
|
const newTransformArr = composeTransformF64(coordinationMatrix, geometryTransform, center);
|
|
@@ -1445,6 +1511,8 @@ export class IfcApiProxyIfc {
|
|
|
1445
1511
|
if (!this._isCoordinated && this.settings?.COORDINATE_TO_ORIGIN) {
|
|
1446
1512
|
Logger.info("Setting up coordinationMatrix");
|
|
1447
1513
|
coordinationMatrix = deriveCoordinationF64(geometryTransform, nativePt, this.NormalizeMat, this.linearScalingFactor);
|
|
1514
|
+
// Persisted for getAppliedCoordination (Share#1634).
|
|
1515
|
+
this.demandCoordination_ = Array.from(coordinationMatrix);
|
|
1448
1516
|
this._isCoordinated = true;
|
|
1449
1517
|
}
|
|
1450
1518
|
const newTransformArr = composeTransformF64(coordinationMatrix, geometryTransform, center);
|
|
@@ -1559,6 +1627,8 @@ export class IfcApiProxyIfc {
|
|
|
1559
1627
|
if (!this._isCoordinated && this.settings?.COORDINATE_TO_ORIGIN) {
|
|
1560
1628
|
Logger.info("Setting up coordinationMatrix");
|
|
1561
1629
|
coordinationMatrix = deriveCoordinationF64(geometryTransform, nativePt, this.NormalizeMat, this.linearScalingFactor);
|
|
1630
|
+
// Persisted for getAppliedCoordination (Share#1634).
|
|
1631
|
+
this.demandCoordination_ = Array.from(coordinationMatrix);
|
|
1562
1632
|
this._isCoordinated = true;
|
|
1563
1633
|
}
|
|
1564
1634
|
const newTransformArr = composeTransformF64(coordinationMatrix, geometryTransform, center);
|
|
@@ -5,7 +5,7 @@ import { CanonicalProfile } from "../core/canonical_profile.js";
|
|
|
5
5
|
import { CountProgressCallback } from "../core/progress.js";
|
|
6
6
|
import { NativeULongVector, NativeUintVector, NativeVectorBound3D, NativeVectorGeometry, NativeVectorGeometryCollection, NativeVectorGlmVec2, NativeVectorGlmVec3, NativeVectorIndexedPolygonalFace, NativeVectorProfile, NativeVectorSegment, WasmModule } from "../core/native_types.js";
|
|
7
7
|
import { ExtractResult } from "../core/shared_constants.js";
|
|
8
|
-
import { IfcAxis2Placement2D, IfcAxis2Placement3D, IfcBooleanResult, IfcCartesianTransformationOperator3D, IfcCircleProfileDef, IfcColourRgb, IfcDirection, IfcExtrudedAreaSolid, IfcIndexedPolyCurve, IfcMappedItem, IfcNormalisedRatioMeasure, IfcObjectPlacement, IfcPolygonalFaceSet, IfcProduct, IfcProfileDef, IfcRepresentationItem, IfcSpecularExponent, IfcSpecularRoughness, IfcStyledItem, IfcSurfaceStyle, IfcBooleanClippingResult, IfcCompositeCurve, IfcPolyline, IfcTrimmedCurve, IfcCartesianPoint, IfcCurve, IfcCircle, IfcHalfSpaceSolid, IfcPlane, IfcShellBasedSurfaceModel, IfcFace, IfcFacetedBrep, IfcMaterialList, IfcMaterialLayerSetUsage, IfcMaterial, IfcRectangleProfileDef, IfcMaterialProfileSet, IfcMaterialConstituentSet, IfcMaterialConstituent, IfcMaterialProfile, IfcSIPrefix, IfcFaceBasedSurfaceModel, IfcConnectedFaceSet, IfcAdvancedBrep, IfcAdvancedFace, IfcBSplineCurve, IfcBSplineSurface, IfcBSplineSurfaceWithKnots, IfcRationalBSplineSurfaceWithKnots, IfcCylindricalSurface, IfcSurfaceOfRevolution, IfcSurfaceOfLinearExtrusion, IfcAxis1Placement, IfcRectangleHollowProfileDef, IfcEllipseProfileDef, IfcCircleHollowProfileDef, IfcIShapeProfileDef, IfcUShapeProfileDef, IfcCartesianTransformationOperator2D, IfcCartesianTransformationOperator2DnonUniform, IfcLShapeProfileDef, IfcCShapeProfileDef, IfcTShapeProfileDef, IfcZShapeProfileDef, IfcPolygonalBoundedHalfSpace, IfcSurface, IfcLine, IfcEllipse, IfcMaterialLayerSet, IfcSweptDiskSolid, IfcBlock, IfcCsgPrimitive3D, IfcSolidModel, IfcTessellatedFaceSet, IfcMaterialProfileSetUsage, IfcRevolvedAreaSolid, IfcFaceSurface } from "./ifc4_gen/index.js";
|
|
8
|
+
import { IfcAxis2Placement2D, IfcAxis2Placement3D, IfcBooleanResult, IfcCartesianTransformationOperator3D, IfcCircleProfileDef, IfcColourRgb, IfcDirection, IfcExtrudedAreaSolid, IfcIndexedPolyCurve, IfcMappedItem, IfcNormalisedRatioMeasure, IfcObjectPlacement, IfcPolygonalFaceSet, IfcProduct, IfcProfileDef, IfcRepresentationItem, IfcSpecularExponent, IfcSpecularRoughness, IfcStyledItem, IfcSurfaceStyle, IfcBooleanClippingResult, IfcCompositeCurve, IfcPolyline, IfcTrimmedCurve, IfcCartesianPoint, IfcCurve, IfcCircle, IfcHalfSpaceSolid, IfcPlane, IfcShellBasedSurfaceModel, IfcFace, IfcFacetedBrep, IfcMaterialList, IfcMaterialLayerSetUsage, IfcMaterial, IfcRectangleProfileDef, IfcMaterialProfileSet, IfcMaterialConstituentSet, IfcMaterialConstituent, IfcMaterialProfile, IfcSIPrefix, IfcFaceBasedSurfaceModel, IfcConnectedFaceSet, IfcAdvancedBrep, IfcAdvancedFace, IfcBSplineCurve, IfcBSplineSurface, IfcBSplineSurfaceWithKnots, IfcRationalBSplineSurfaceWithKnots, IfcCylindricalSurface, IfcSurfaceOfRevolution, IfcSurfaceOfLinearExtrusion, IfcAxis1Placement, IfcRectangleHollowProfileDef, IfcEllipseProfileDef, IfcCircleHollowProfileDef, IfcIShapeProfileDef, IfcUShapeProfileDef, IfcCartesianTransformationOperator2D, IfcCartesianTransformationOperator2DnonUniform, IfcLShapeProfileDef, IfcCShapeProfileDef, IfcTShapeProfileDef, IfcZShapeProfileDef, IfcRelAggregates, IfcPolygonalBoundedHalfSpace, IfcSurface, IfcLine, IfcEllipse, IfcMaterialLayerSet, IfcSweptDiskSolid, IfcBlock, IfcCsgPrimitive3D, IfcSolidModel, IfcTessellatedFaceSet, IfcMaterialProfileSetUsage, IfcRevolvedAreaSolid, IfcFaceSurface } from "./ifc4_gen/index.js";
|
|
9
9
|
import { IfcMaterialCache } from "./ifc_material_cache.js";
|
|
10
10
|
import { IfcSceneBuilder } from "./ifc_scene_builder.js";
|
|
11
11
|
import IfcStepModel from "./ifc_step_model.js";
|
|
@@ -929,6 +929,28 @@ export declare class IfcGeometryExtraction {
|
|
|
929
929
|
*/
|
|
930
930
|
dumpGeometry(outputFilePath: string, geometry: GeometryObject): void;
|
|
931
931
|
private extractionMapsPrepared_;
|
|
932
|
+
private aggregateTargetLocalIDs_?;
|
|
933
|
+
/**
|
|
934
|
+
* Local IDs of every IfcProduct that is a RelatedObject of any
|
|
935
|
+
* IfcRelAggregates — the exact set the rel-aggregates pass
|
|
936
|
+
* ({@link extractRelAggregateGeometry}) re-extracts with the relating
|
|
937
|
+
* object's master rel-voids.
|
|
938
|
+
*
|
|
939
|
+
* Both product walks SKIP these in their first pass and extract them
|
|
940
|
+
* only in the aggregates pass, for two invariants consumers rely on:
|
|
941
|
+
* 1. one scene instance per placement (the first-pass node plus the
|
|
942
|
+
* re-extraction node used to coincide exactly — a duplicate draw
|
|
943
|
+
* that z-fights), and
|
|
944
|
+
* 2. a part's canonical mesh content is never REPLACED after its
|
|
945
|
+
* instances were already emitted — incremental consumers copy
|
|
946
|
+
* content at delivery time, so a first-pass emission served the
|
|
947
|
+
* uncut (or empty) content and the later replacement never
|
|
948
|
+
* reached the screen (the ILNA missing-facades class).
|
|
949
|
+
*
|
|
950
|
+
* @return {Set<number>} product localIDs deferred to the aggregates
|
|
951
|
+
* pass; empty for models without IfcRelAggregates.
|
|
952
|
+
*/
|
|
953
|
+
aggregateTargetLocalIDs(): Set<number>;
|
|
932
954
|
/**
|
|
933
955
|
* One-time extraction setup shared by the whole-model walk and the
|
|
934
956
|
* per-product demand path (Phase B2): linear scaling factor and the
|
|
@@ -985,11 +1007,13 @@ export declare class IfcGeometryExtraction {
|
|
|
985
1007
|
* Extract one IfcRelAggregates' related products with the relating
|
|
986
1008
|
* object's ("master") rel-voids — the shared per-item body of the
|
|
987
1009
|
* whole-model walk's rel-aggregates loop and
|
|
988
|
-
* {@link extractRelAggregatesGeometry}.
|
|
1010
|
+
* {@link extractRelAggregatesGeometry}. Public so the deferred pump
|
|
1011
|
+
* can run the pass incrementally (batch-budgeted) instead of as one
|
|
1012
|
+
* end-of-load stall.
|
|
989
1013
|
*
|
|
990
1014
|
* @param relAggregate The rel-aggregates relationship to process.
|
|
991
1015
|
*/
|
|
992
|
-
|
|
1016
|
+
extractRelAggregateGeometry(relAggregate: IfcRelAggregates): void;
|
|
993
1017
|
/**
|
|
994
1018
|
* Extract one product's geometry into the scene: placement, material /
|
|
995
1019
|
* style extraction, representation items (including mapped items) and
|