@bldrs-ai/conway 1.530.1503 → 1.534.1505

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.
@@ -30,7 +30,7 @@ var import_node_process = require("node:process");
30
30
  var readline = __toESM(require("node:readline"), 1);
31
31
 
32
32
  // compiled/src/version/version.js
33
- var versionString = "Conway v1.530.1503";
33
+ var versionString = "Conway v1.534.1505";
34
34
 
35
35
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
36
36
  var wasmType = "";
@@ -14965,7 +14965,7 @@ ${t5.join("\n")}` : "";
14965
14965
  var import_process = require("process");
14966
14966
 
14967
14967
  // compiled/src/version/version.js
14968
- var versionString = "Conway v1.530.1503";
14968
+ var versionString = "Conway v1.534.1505";
14969
14969
 
14970
14970
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
14971
14971
  function pThreadsAllowed() {
@@ -88456,6 +88456,7 @@ var IfcSceneBuilder = class {
88456
88456
  this.sceneLocalIdMap_ = /* @__PURE__ */ new Map();
88457
88457
  this.geometrySet_ = /* @__PURE__ */ new Set();
88458
88458
  this.sceneStack_ = [];
88459
+ this.geometryNodeVisits_ = 0;
88459
88460
  }
88460
88461
  /**
88461
88462
  *
@@ -88646,37 +88647,118 @@ var IfcSceneBuilder = class {
88646
88647
  isAllSpaces() {
88647
88648
  return this.scene_.every((node) => !(node instanceof IfcSceneGeometry) || node.isSpace);
88648
88649
  }
88650
+ *walk(includeSpaces = false) {
88651
+ for (let index = 0; index < this.scene_.length; ++index) {
88652
+ const resolved = this.resolveGeometryNode_(index, includeSpaces);
88653
+ if (resolved === void 0 || resolved[2] === void 0) {
88654
+ continue;
88655
+ }
88656
+ yield [resolved[0], resolved[1], resolved[2], resolved[3], resolved[4]];
88657
+ }
88658
+ }
88649
88659
  /**
88650
- * Walk the current scene.
88660
+ * The number of nodes in the scene array. Append-only, so a caller that
88661
+ * remembers this value has a stable cursor into the scene: everything
88662
+ * added after it sits at a higher index.
88651
88663
  *
88652
- * @yields Raw absolute matrix transform, the native absolute transform, the canonical mesh,
88653
- * @param includeSpaces
88654
- * the canonical material and the associated step element as it walks the hierarchy.
88655
- * @param walkTemporary Include temporary items.
88664
+ * @return {number} The node count.
88656
88665
  */
88657
- *walk(includeSpaces = false) {
88658
- for (const node of this.scene_) {
88659
- if (node instanceof IfcSceneGeometry && (includeSpaces || !node.isSpace)) {
88660
- const parentIndex = node.parentIndex;
88661
- const geometry = node.model.geometry?.getByLocalID(node.localID);
88662
- if (geometry === void 0) {
88663
- continue;
88664
- }
88665
- let parentNode;
88666
- if (parentIndex !== void 0) {
88667
- parentNode = this.scene_[parentIndex];
88668
- }
88669
- const material = this.materials.getMaterialByGeometryID(node.materialOverideLocalID ?? geometry.localID);
88670
- yield [
88671
- parentNode?.absoluteTransform,
88672
- parentNode?.absoluteNativeTransform,
88673
- geometry,
88674
- material !== void 0 ? material[0] : void 0,
88675
- node.relatedElementLocalId !== void 0 ? this.model.getElementByLocalID(node.relatedElementLocalId) : void 0
88676
- ];
88666
+ get nodeCount() {
88667
+ return this.scene_.length;
88668
+ }
88669
+ /**
88670
+ * How many times a node has been considered by any walk form since this
88671
+ * scene was built.
88672
+ *
88673
+ * Exists so the *complexity* of an incremental consumer can be asserted
88674
+ * rather than timed: a capture that walks only what the scene gained
88675
+ * visits each node about once for the whole load, where one that
88676
+ * re-walks from zero visits every node once per call. Output parity
88677
+ * cannot distinguish those — both deliver the same meshes — so without
88678
+ * this a regression from O(new nodes) back to O(batches x scene) passes
88679
+ * every correctness test while restoring the cost. See the batch-size
88680
+ * invariance test in ifc_api_deferred_open.test.ts.
88681
+ *
88682
+ * @return {number} The visit count.
88683
+ */
88684
+ get geometryNodeVisits() {
88685
+ return this.geometryNodeVisits_;
88686
+ }
88687
+ /**
88688
+ * Walk only the nodes added at or after `startIndex` — the incremental
88689
+ * form of {@link walk}, for a consumer draining the scene in batches.
88690
+ *
88691
+ * Unlike `walk`, this yields nodes whose geometry does NOT resolve, with
88692
+ * `undefined` in the geometry slot and the node's index last. That is
88693
+ * deliberate: a cursor-based caller passes each index exactly once, so a
88694
+ * node skipped for missing geometry would be lost forever, where the
88695
+ * whole-scene walk would have picked it up on its next pass. Geometry can
88696
+ * appear late — a product that maps geometry a release freed re-extracts
88697
+ * it — so the caller must park those indices and retry them with
88698
+ * {@link walkNode}. Yielding them is what makes that possible.
88699
+ *
88700
+ * @param startIndex First node index to consider.
88701
+ * @param includeSpaces Include space geometry.
88702
+ * @yields The walk tuple plus the node's index.
88703
+ */
88704
+ *walkFrom(startIndex, includeSpaces = false) {
88705
+ for (let index = startIndex; index < this.scene_.length; ++index) {
88706
+ const resolved = this.resolveGeometryNode_(index, includeSpaces);
88707
+ if (resolved === void 0) {
88708
+ continue;
88677
88709
  }
88710
+ yield resolved;
88678
88711
  }
88679
88712
  }
88713
+ /**
88714
+ * Resolve one node by index, for retrying a node {@link walkFrom} yielded
88715
+ * without geometry.
88716
+ *
88717
+ * @param index The node's index in the scene array.
88718
+ * @param includeSpaces Include space geometry.
88719
+ * @return {[...]|undefined} The walk tuple plus the index, or undefined
88720
+ * when the node isn't geometry this walk covers.
88721
+ */
88722
+ walkNode(index, includeSpaces = false) {
88723
+ return this.resolveGeometryNode_(index, includeSpaces);
88724
+ }
88725
+ /**
88726
+ * The shared body of walk/walkFrom/walkNode: one node in, one walk tuple
88727
+ * out. Single-sourced so the incremental walk cannot drift from the whole
88728
+ * -scene one — a drift here would show up as geometry placed differently
88729
+ * depending on batch size.
88730
+ *
88731
+ * @param index The node's index in the scene array.
88732
+ * @param includeSpaces Include space geometry.
88733
+ * @return {[...]|undefined} Undefined when the node isn't a geometry node
88734
+ * this walk covers; otherwise the tuple, whose geometry slot is undefined
88735
+ * if the geometry doesn't currently resolve.
88736
+ */
88737
+ resolveGeometryNode_(index, includeSpaces) {
88738
+ ++this.geometryNodeVisits_;
88739
+ const node = this.scene_[index];
88740
+ if (!(node instanceof IfcSceneGeometry) || !includeSpaces && node.isSpace) {
88741
+ return void 0;
88742
+ }
88743
+ const geometry = node.model.geometry?.getByLocalID(node.localID);
88744
+ if (geometry === void 0) {
88745
+ return [void 0, void 0, void 0, void 0, void 0, index];
88746
+ }
88747
+ const parentIndex = node.parentIndex;
88748
+ let parentNode;
88749
+ if (parentIndex !== void 0) {
88750
+ parentNode = this.scene_[parentIndex];
88751
+ }
88752
+ const material = this.materials.getMaterialByGeometryID(node.materialOverideLocalID ?? geometry.localID);
88753
+ return [
88754
+ parentNode?.absoluteTransform,
88755
+ parentNode?.absoluteNativeTransform,
88756
+ geometry,
88757
+ material !== void 0 ? material[0] : void 0,
88758
+ node.relatedElementLocalId !== void 0 ? this.model.getElementByLocalID(node.relatedElementLocalId) : void 0,
88759
+ index
88760
+ ];
88761
+ }
88680
88762
  /**
88681
88763
  *
88682
88764
  */
@@ -15943,7 +15943,7 @@ var ParsingBuffer = class {
15943
15943
  };
15944
15944
 
15945
15945
  // compiled/src/version/version.js
15946
- var versionString = "Conway v1.530.1503";
15946
+ var versionString = "Conway v1.534.1505";
15947
15947
 
15948
15948
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
15949
15949
  function pThreadsAllowed() {
@@ -944,7 +944,7 @@ var EntityTypesIfcCount = 909;
944
944
  var entity_types_ifc_gen_default = EntityTypesIfc;
945
945
 
946
946
  // compiled/src/version/version.js
947
- var versionString = "Conway v1.530.1503";
947
+ var versionString = "Conway v1.534.1505";
948
948
 
949
949
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
950
950
  var wasmType = "";
@@ -277,6 +277,126 @@ describe("OpenModelStreamed + DEFER_GEOMETRY", () => {
277
277
  api4.CloseModel(classicID);
278
278
  api4.CloseModel(deferredID);
279
279
  }, 240000);
280
+ test("shared representation survives a batch boundary, emitted once", async () => {
281
+ // data/mapped_shared_representation.ifc: one IfcRepresentationMap
282
+ // mapped by two products 15 products apart, so a batch size of 4
283
+ // guarantees they land in DIFFERENT batches. The smoke corpus cannot
284
+ // produce this shape — there every sharer of a definition falls
285
+ // inside one batch — so this is the only fixture that exercises the
286
+ // delta capture across a boundary where geometry is shared.
287
+ //
288
+ // It pins the cursor capture from both directions. Lose a parked or
289
+ // suffix node and the second mapped product goes missing; re-emit a
290
+ // node the cursor should have passed (the failure a reverted cursor
291
+ // or a broken watermark produces) and instances duplicate. Both show
292
+ // up as an instance-count mismatch against classic, which is why the
293
+ // comparison is against classic rather than a hard-coded number.
294
+ const api5 = new IfcAPI();
295
+ await api5.Init();
296
+ const fixture = new Uint8Array(fs.readFileSync("data/mapped_shared_representation.ifc"));
297
+ const classicID = api5.OpenModel(fixture, SETTINGS);
298
+ const classicPlacements = [];
299
+ api5.StreamAllMeshes(classicID, (mesh) => {
300
+ for (let where = 0; where < mesh.geometries.size(); ++where) {
301
+ const placed = mesh.geometries.get(where);
302
+ classicPlacements.push(`${placed.geometryExpressID}@${[...placed.flatTransformation]
303
+ .map((value) => value.toFixed(3)).join(",")}`);
304
+ }
305
+ });
306
+ const deferredID = await api5.OpenModelStreamed(fixture, { ...SETTINGS, DEFER_GEOMETRY: true });
307
+ const pumpedPlacements = [];
308
+ let batches = 0;
309
+ for (;;) {
310
+ const { extracted, remaining } = api5.ExtractGeometryBatch(deferredID, 4, (mesh) => {
311
+ for (let where = 0; where < mesh.geometries.size(); ++where) {
312
+ const placed = mesh.geometries.get(where);
313
+ pumpedPlacements.push(`${placed.geometryExpressID}@${[...placed.flatTransformation]
314
+ .map((value) => value.toFixed(3)).join(",")}`);
315
+ }
316
+ });
317
+ ++batches;
318
+ if (remaining === 0 && extracted === 0) {
319
+ break;
320
+ }
321
+ }
322
+ // The boundary the fixture exists to create: with 16 products at
323
+ // batch 4, the two sharers cannot be in the same batch.
324
+ expect(batches).toBeGreaterThan(2);
325
+ // Exact multiset equality — placement included, so an instance
326
+ // delivered at the wrong location fails as loudly as a missing one.
327
+ expect(pumpedPlacements.slice().sort())
328
+ .toEqual(classicPlacements.slice().sort());
329
+ // Emitted once each: a duplicate would survive the multiset check
330
+ // only if classic duplicated too, but state it directly since
331
+ // re-emission is the specific failure a broken cursor produces.
332
+ expect(new Set(pumpedPlacements).size).toBe(pumpedPlacements.length);
333
+ // Both users of the shared map are present, at their own placements
334
+ // — the shared SOURCE geometry appears under two distinct transforms.
335
+ const mappedTransforms = new Set(pumpedPlacements.map((entry) => entry.split("@")[1]));
336
+ expect(mappedTransforms.size).toBe(pumpedPlacements.length);
337
+ api5.CloseModel(classicID);
338
+ api5.CloseModel(deferredID);
339
+ }, 240000);
340
+ test("delta capture visits each scene node once, whatever the batch size", async () => {
341
+ // Output parity cannot see this. The whole-scene walk this replaced
342
+ // delivered exactly the same meshes; what changed is the COST of
343
+ // delivering them — it re-resolved every node on every call, so the
344
+ // capture was O(batches x scene). A revert would pass every
345
+ // correctness assertion in this file while restoring the 1.47-2.97x
346
+ // regression the PR description measures, so the complexity gets an
347
+ // assertion of its own.
348
+ //
349
+ // Counting node visits rather than timing: deterministic, and it
350
+ // fails the same way on a fast machine as a slow one.
351
+ const api6 = new IfcAPI();
352
+ await api6.Init();
353
+ const fixture = new Uint8Array(fs.readFileSync("data/mapped_shared_representation.ifc"));
354
+ /**
355
+ * Pump a fresh deferred model to completion and report how much
356
+ * scene walking it took.
357
+ *
358
+ * @param batchSize Products per ExtractGeometryBatch call.
359
+ * @return {Promise<{visits: number, nodes: number, batches: number}>}
360
+ * Node visits, final scene size, and calls taken.
361
+ */
362
+ async function pump(batchSize) {
363
+ const modelID = await api6.OpenModelStreamed(fixture, { ...SETTINGS, DEFER_GEOMETRY: true });
364
+ let batches = 0;
365
+ for (;;) {
366
+ const { extracted, remaining } = api6.ExtractGeometryBatch(modelID, batchSize, () => { });
367
+ ++batches;
368
+ if (remaining === 0 && extracted === 0) {
369
+ break;
370
+ }
371
+ }
372
+ const scene = api6.getPassthrough(modelID)
373
+ .model[1];
374
+ // A revert that drops the counter along with the cursor would
375
+ // otherwise fail as `expected undefined to be less than 68`, which
376
+ // reads like a broken test rather than the regression it is.
377
+ expect(typeof scene?.geometryNodeVisits)
378
+ .toBe("number");
379
+ const measured = { visits: scene.geometryNodeVisits, nodes: scene.nodeCount, batches };
380
+ api6.CloseModel(modelID);
381
+ return measured;
382
+ }
383
+ const oneAtATime = await pump(1);
384
+ const allAtOnce = await pump(64);
385
+ // The fixture is 16 products, so batch 1 really does take many calls
386
+ // — otherwise this asserts nothing.
387
+ expect(oneAtATime.batches).toBeGreaterThan(8);
388
+ expect(allAtOnce.batches).toBeLessThan(oneAtATime.batches);
389
+ // The invariant: total walking is a property of the SCENE, not of how
390
+ // many calls drained it. Allowing 2x the node count leaves room for
391
+ // the whole-model drain's own pass and for parked-node retries
392
+ // (DEMAND_PARKED_NODE_RETRIES each, and nothing in this corpus parks
393
+ // a node at all), while a per-call re-walk would land near
394
+ // batches x nodes — an order of magnitude clear of the bound.
395
+ expect(oneAtATime.visits).toBeLessThan(oneAtATime.nodes * 2);
396
+ // And it must not grow when the batch shrinks, which is the specific
397
+ // shape of the regression: same scene, ~16x the calls, same work.
398
+ expect(oneAtATime.visits).toBeLessThan(allAtOnce.visits * 2);
399
+ }, 240000);
280
400
  test("ExtractGeometryBatch is a safe no-op on non-deferred models", async () => {
281
401
  const modelID = await api.OpenModelStreamed(buffer, SETTINGS);
282
402
  expect(api.ExtractGeometryBatch(modelID, 8))
@@ -75,7 +75,38 @@ export declare class IfcApiProxyIfc implements IfcApiModelPassthrough {
75
75
  * batches - the watermark makes each instance captured exactly once,
76
76
  * in the same order the classic single walk would process it.
77
77
  */
78
- private readonly demandCapturedCounts_;
78
+ /**
79
+ * How much of the scene array the delta capture has consumed. The scene
80
+ * is append-only, so this is a stable cursor: everything a batch adds
81
+ * sits above it. Replaces the per-entity walk watermark this used to
82
+ * keep, which existed only because the capture restarted its walk from
83
+ * zero every batch — an O(batches x scene) cost that dominated on
84
+ * instance-dense models (D3D: 562k instances, 1182 batches at size 64).
85
+ */
86
+ private demandSceneCursor_;
87
+ /**
88
+ * Node indices walkFrom yielded without resolvable geometry, against the
89
+ * number of times a later capture has re-checked them. Parked because a
90
+ * cursor passes each index once, where the whole-scene walk this replaced
91
+ * re-checked every node on every call. See IfcSceneBuilder.walkFrom.
92
+ *
93
+ * Bounded by DEMAND_PARKED_NODE_RETRIES because not every unresolved node
94
+ * is waiting on something: extraction can append a scene node and then
95
+ * fail to cache geometry for it (extractSweptDiskSolid returns early on a
96
+ * failed directrix; extractRepresentationItem still calls addGeometry),
97
+ * and no amount of re-checking makes a deterministic failure resolve.
98
+ * Retrying those forever would be O(batches x unresolvable) — still under
99
+ * the O(batches x scene) this replaced, but unbounded in batch count for
100
+ * no benefit. Expiring after a fixed number of attempts makes the total
101
+ * retry work O(retries x unresolvable) regardless of batch size.
102
+ *
103
+ * Measured at zero on every model available here — the 12-model smoke
104
+ * corpus, PSB, and D3D (which logs exactly the malformed-geometry errors
105
+ * that produce this case) all park nothing — so this path is a
106
+ * correctness guard rather than a hot path, and its constant is chosen to
107
+ * be generous rather than tuned.
108
+ */
109
+ private readonly demandPendingNodes_;
79
110
  /** Cursor into demandProducts_ — products before it are extracted. */
80
111
  private demandCursor_;
81
112
  /** Wall-clock split of the store-backed batch pump (profile script). */
@@ -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":"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"}
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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"}
@@ -30,6 +30,14 @@ import { CanonicalMeshType } from "../../index.js";
30
30
  // Batch size used when a whole-model consumer (streamAllMeshes) drains
31
31
  // a deferred model's remaining products synchronously.
32
32
  const DEFERRED_DRAIN_BATCH = 256;
33
+ /* How many later captures re-check a scene node whose geometry did not
34
+ * resolve when its index passed the cursor, before giving up on it. See
35
+ * demandPendingNodes_ for why the bound exists and why the value is
36
+ * generous rather than tuned: nothing in the corpus, PSB or D3D parks a
37
+ * node at all, and a node that is waiting on anything real is waiting on
38
+ * the very next extraction, not the eighth. */
39
+ // eslint-disable-next-line no-magic-numbers
40
+ const DEMAND_PARKED_NODE_RETRIES = 8;
33
41
  /* Moving-window size for the streamed columnar parse (matches the
34
42
  * ifc_stream_open default; the window bounds parse-time scratch, not
35
43
  * the source buffer, which the model keeps resident here). */
@@ -87,7 +95,38 @@ export class IfcApiProxyIfc {
87
95
  * batches - the watermark makes each instance captured exactly once,
88
96
  * in the same order the classic single walk would process it.
89
97
  */
90
- this.demandCapturedCounts_ = new Map();
98
+ /**
99
+ * How much of the scene array the delta capture has consumed. The scene
100
+ * is append-only, so this is a stable cursor: everything a batch adds
101
+ * sits above it. Replaces the per-entity walk watermark this used to
102
+ * keep, which existed only because the capture restarted its walk from
103
+ * zero every batch — an O(batches x scene) cost that dominated on
104
+ * instance-dense models (D3D: 562k instances, 1182 batches at size 64).
105
+ */
106
+ this.demandSceneCursor_ = 0;
107
+ /**
108
+ * Node indices walkFrom yielded without resolvable geometry, against the
109
+ * number of times a later capture has re-checked them. Parked because a
110
+ * cursor passes each index once, where the whole-scene walk this replaced
111
+ * re-checked every node on every call. See IfcSceneBuilder.walkFrom.
112
+ *
113
+ * Bounded by DEMAND_PARKED_NODE_RETRIES because not every unresolved node
114
+ * is waiting on something: extraction can append a scene node and then
115
+ * fail to cache geometry for it (extractSweptDiskSolid returns early on a
116
+ * failed directrix; extractRepresentationItem still calls addGeometry),
117
+ * and no amount of re-checking makes a deterministic failure resolve.
118
+ * Retrying those forever would be O(batches x unresolvable) — still under
119
+ * the O(batches x scene) this replaced, but unbounded in batch count for
120
+ * no benefit. Expiring after a fixed number of attempts makes the total
121
+ * retry work O(retries x unresolvable) regardless of batch size.
122
+ *
123
+ * Measured at zero on every model available here — the 12-model smoke
124
+ * corpus, PSB, and D3D (which logs exactly the malformed-geometry errors
125
+ * that produce this case) all park nothing — so this path is a
126
+ * correctness guard rather than a hot path, and its constant is chosen to
127
+ * be generous rather than tuned.
128
+ */
129
+ this.demandPendingNodes_ = new Map();
91
130
  /** Cursor into demandProducts_ — products before it are extracted. */
92
131
  this.demandCursor_ = 0;
93
132
  /** Wall-clock split of the store-backed batch pump (profile script). */
@@ -1617,19 +1656,45 @@ export class IfcApiProxyIfc {
1617
1656
  }
1618
1657
  const [model, scene, meshMap, geometryMaterialTransformMap] = this.model;
1619
1658
  let coordinationMatrix = this.demandCoordination_ ?? glmatrix.mat4.create();
1620
- const seenThisPass = new Map();
1621
1659
  const deltas = new Map();
1622
- // eslint-disable-next-line no-unused-vars
1623
- for (const [_, nativeTransform, geometry, material, entity] of scene.walk()) {
1624
- if (entity?.localID === void 0 || entity.expressID === void 0) {
1625
- continue;
1660
+ // Everything the scene has gained since the last capture, plus any
1661
+ // node parked earlier for unresolvable geometry. Each node passes
1662
+ // through exactly once, so no watermark is needed to suppress
1663
+ // re-emission - the cursor IS the watermark, one for the whole scene
1664
+ // rather than one per entity.
1665
+ const capturedCursor = this.demandSceneCursor_;
1666
+ const pending = this.demandPendingNodes_;
1667
+ this.demandSceneCursor_ = scene.nodeCount;
1668
+ const candidates = function* () {
1669
+ for (const [index, attempts] of [...pending]) {
1670
+ const retried = scene.walkNode(index);
1671
+ if (retried === void 0 || retried[2] === void 0) {
1672
+ if (attempts + 1 >= DEMAND_PARKED_NODE_RETRIES) {
1673
+ pending.delete(index);
1674
+ }
1675
+ else {
1676
+ pending.set(index, attempts + 1);
1677
+ }
1678
+ continue;
1679
+ }
1680
+ pending.delete(index);
1681
+ yield retried;
1626
1682
  }
1627
- // Per-entity walk position vs watermark: instances before the
1628
- // watermark were captured in an earlier call (append-only walk
1629
- // order makes the count a stable cursor).
1630
- const walkIndex = seenThisPass.get(entity.localID) ?? 0;
1631
- seenThisPass.set(entity.localID, walkIndex + 1);
1632
- if (walkIndex < (this.demandCapturedCounts_.get(entity.localID) ?? 0)) {
1683
+ for (const candidate of scene.walkFrom(capturedCursor)) {
1684
+ if (candidate[2] === void 0) {
1685
+ pending.set(candidate[5], 0);
1686
+ continue;
1687
+ }
1688
+ yield candidate;
1689
+ }
1690
+ };
1691
+ // eslint-disable-next-line no-unused-vars
1692
+ for (const [_, nativeTransform, geometry, material, entity] of candidates()) {
1693
+ // `candidates` never yields an unresolved geometry — the undefined
1694
+ // arm is the parked-node signal, handled there — but the tuple type
1695
+ // allows it, so narrow here rather than asserting at each use.
1696
+ if (geometry === void 0 ||
1697
+ entity?.localID === void 0 || entity.expressID === void 0) {
1633
1698
  continue;
1634
1699
  }
1635
1700
  if (geometry.type !== CanonicalMeshType.BUFFER_GEOMETRY || geometry.temporary) {
@@ -1718,7 +1783,6 @@ export class IfcApiProxyIfc {
1718
1783
  }
1719
1784
  mesh[0].push(placed);
1720
1785
  mesh[1].geometries = mesh[0];
1721
- this.demandCapturedCounts_.set(entity.localID, (this.demandCapturedCounts_.get(entity.localID) ?? 0) + 1);
1722
1786
  let delta = deltas.get(entity.expressID);
1723
1787
  if (delta === void 0) {
1724
1788
  delta = [];
@@ -151,6 +151,7 @@ export declare class IfcSceneBuilder implements WalkableScene<StepEntityBase<Ent
151
151
  * the canonical material and the associated step element as it walks the hierarchy.
152
152
  * @param walkTemporary Include temporary items.
153
153
  */
154
+ private geometryNodeVisits_;
154
155
  walk(includeSpaces?: boolean): IterableIterator<[
155
156
  readonly number[] | undefined,
156
157
  NativeTransform4x4 | undefined,
@@ -158,6 +159,85 @@ export declare class IfcSceneBuilder implements WalkableScene<StepEntityBase<Ent
158
159
  CanonicalMaterial | undefined,
159
160
  StepEntityBase<EntityTypesIfc> | undefined
160
161
  ]>;
162
+ /**
163
+ * The number of nodes in the scene array. Append-only, so a caller that
164
+ * remembers this value has a stable cursor into the scene: everything
165
+ * added after it sits at a higher index.
166
+ *
167
+ * @return {number} The node count.
168
+ */
169
+ get nodeCount(): number;
170
+ /**
171
+ * How many times a node has been considered by any walk form since this
172
+ * scene was built.
173
+ *
174
+ * Exists so the *complexity* of an incremental consumer can be asserted
175
+ * rather than timed: a capture that walks only what the scene gained
176
+ * visits each node about once for the whole load, where one that
177
+ * re-walks from zero visits every node once per call. Output parity
178
+ * cannot distinguish those — both deliver the same meshes — so without
179
+ * this a regression from O(new nodes) back to O(batches x scene) passes
180
+ * every correctness test while restoring the cost. See the batch-size
181
+ * invariance test in ifc_api_deferred_open.test.ts.
182
+ *
183
+ * @return {number} The visit count.
184
+ */
185
+ get geometryNodeVisits(): number;
186
+ /**
187
+ * Walk only the nodes added at or after `startIndex` — the incremental
188
+ * form of {@link walk}, for a consumer draining the scene in batches.
189
+ *
190
+ * Unlike `walk`, this yields nodes whose geometry does NOT resolve, with
191
+ * `undefined` in the geometry slot and the node's index last. That is
192
+ * deliberate: a cursor-based caller passes each index exactly once, so a
193
+ * node skipped for missing geometry would be lost forever, where the
194
+ * whole-scene walk would have picked it up on its next pass. Geometry can
195
+ * appear late — a product that maps geometry a release freed re-extracts
196
+ * it — so the caller must park those indices and retry them with
197
+ * {@link walkNode}. Yielding them is what makes that possible.
198
+ *
199
+ * @param startIndex First node index to consider.
200
+ * @param includeSpaces Include space geometry.
201
+ * @yields The walk tuple plus the node's index.
202
+ */
203
+ walkFrom(startIndex: number, includeSpaces?: boolean): IterableIterator<[
204
+ readonly number[] | undefined,
205
+ NativeTransform4x4 | undefined,
206
+ CanonicalMesh | undefined,
207
+ CanonicalMaterial | undefined,
208
+ StepEntityBase<EntityTypesIfc> | undefined,
209
+ number
210
+ ]>;
211
+ /**
212
+ * Resolve one node by index, for retrying a node {@link walkFrom} yielded
213
+ * without geometry.
214
+ *
215
+ * @param index The node's index in the scene array.
216
+ * @param includeSpaces Include space geometry.
217
+ * @return {[...]|undefined} The walk tuple plus the index, or undefined
218
+ * when the node isn't geometry this walk covers.
219
+ */
220
+ walkNode(index: number, includeSpaces?: boolean): [
221
+ readonly number[] | undefined,
222
+ NativeTransform4x4 | undefined,
223
+ CanonicalMesh | undefined,
224
+ CanonicalMaterial | undefined,
225
+ StepEntityBase<EntityTypesIfc> | undefined,
226
+ number
227
+ ] | undefined;
228
+ /**
229
+ * The shared body of walk/walkFrom/walkNode: one node in, one walk tuple
230
+ * out. Single-sourced so the incremental walk cannot drift from the whole
231
+ * -scene one — a drift here would show up as geometry placed differently
232
+ * depending on batch size.
233
+ *
234
+ * @param index The node's index in the scene array.
235
+ * @param includeSpaces Include space geometry.
236
+ * @return {[...]|undefined} Undefined when the node isn't a geometry node
237
+ * this walk covers; otherwise the tuple, whose geometry slot is undefined
238
+ * if the geometry doesn't currently resolve.
239
+ */
240
+ private resolveGeometryNode_;
161
241
  /**
162
242
  *
163
243
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ifc_scene_builder.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_scene_builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ifc_scene_builder.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_scene_builder.ts"],"names":[],"mappings":"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"}