@bldrs-ai/conway 1.425.1281 → 1.426.1283

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.425.1281";
33
+ var versionString = "Conway v1.426.1283";
34
34
 
35
35
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
36
36
  var wasmType = "";
@@ -584,6 +584,20 @@ var environment_default = Environment;
584
584
 
585
585
  // compiled/src/core/progress.js
586
586
  function yieldToEventLoop() {
587
+ const scheduler = globalThis.scheduler;
588
+ if (typeof scheduler?.yield === "function") {
589
+ return scheduler.yield();
590
+ }
591
+ if (typeof MessageChannel === "function") {
592
+ return new Promise((resolve) => {
593
+ const channel = new MessageChannel();
594
+ channel.port1.onmessage = () => {
595
+ channel.port1.close();
596
+ resolve();
597
+ };
598
+ channel.port2.postMessage(null);
599
+ });
600
+ }
587
601
  return new Promise((resolve) => {
588
602
  setTimeout(resolve, 0);
589
603
  });
@@ -70412,9 +70426,24 @@ var IfcModelGeometry = class {
70412
70426
  /**
70413
70427
  * Add a mesh to the geometry cache.
70414
70428
  *
70429
+ * Freezes the native float vertex mirror at add time (one
70430
+ * GetVertexData call): consumers (the compat GetGeometry surface)
70431
+ * read float vertices whose frame must match the scene transforms,
70432
+ * which are authored against the geometry AS CREATED. Later native
70433
+ * mutations that keep the vertex count (normalize's centering)
70434
+ * deliberately do NOT refresh the mirror, so every extraction path —
70435
+ * whole-model walk, per-product demand pump, parse-time preview —
70436
+ * serves the same creation-frame floats. Without this, paths that
70437
+ * first read vertices only after a centering mutation serve
70438
+ * per-geometry-shifted vertices against unshifted transforms
70439
+ * (Share's demand-path "scatter").
70440
+ *
70415
70441
  * @param mesh
70416
70442
  */
70417
70443
  add(mesh) {
70444
+ if (mesh.type === CanonicalMeshType.BUFFER_GEOMETRY) {
70445
+ mesh.geometry.GetVertexData();
70446
+ }
70418
70447
  this.meshes_.set(mesh.localID, mesh);
70419
70448
  }
70420
70449
  /**
@@ -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.425.1281";
14968
+ var versionString = "Conway v1.426.1283";
14969
14969
 
14970
14970
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
14971
14971
  function pThreadsAllowed() {
@@ -16310,6 +16310,20 @@ var Memory = class {
16310
16310
  // compiled/src/core/progress.js
16311
16311
  var DEFAULT_PROGRESS_INTERVAL_MS = 100;
16312
16312
  function yieldToEventLoop() {
16313
+ const scheduler = globalThis.scheduler;
16314
+ if (typeof scheduler?.yield === "function") {
16315
+ return scheduler.yield();
16316
+ }
16317
+ if (typeof MessageChannel === "function") {
16318
+ return new Promise((resolve) => {
16319
+ const channel = new MessageChannel();
16320
+ channel.port1.onmessage = () => {
16321
+ channel.port1.close();
16322
+ resolve();
16323
+ };
16324
+ channel.port2.postMessage(null);
16325
+ });
16326
+ }
16313
16327
  return new Promise((resolve) => {
16314
16328
  setTimeout(resolve, 0);
16315
16329
  });
@@ -86257,9 +86271,24 @@ var IfcModelGeometry = class {
86257
86271
  /**
86258
86272
  * Add a mesh to the geometry cache.
86259
86273
  *
86274
+ * Freezes the native float vertex mirror at add time (one
86275
+ * GetVertexData call): consumers (the compat GetGeometry surface)
86276
+ * read float vertices whose frame must match the scene transforms,
86277
+ * which are authored against the geometry AS CREATED. Later native
86278
+ * mutations that keep the vertex count (normalize's centering)
86279
+ * deliberately do NOT refresh the mirror, so every extraction path —
86280
+ * whole-model walk, per-product demand pump, parse-time preview —
86281
+ * serves the same creation-frame floats. Without this, paths that
86282
+ * first read vertices only after a centering mutation serve
86283
+ * per-geometry-shifted vertices against unshifted transforms
86284
+ * (Share's demand-path "scatter").
86285
+ *
86260
86286
  * @param mesh
86261
86287
  */
86262
86288
  add(mesh) {
86289
+ if (mesh.type === CanonicalMeshType.BUFFER_GEOMETRY) {
86290
+ mesh.geometry.GetVertexData();
86291
+ }
86263
86292
  this.meshes_.set(mesh.localID, mesh);
86264
86293
  }
86265
86294
  /**
@@ -15943,7 +15943,7 @@ var ParsingBuffer = class {
15943
15943
  };
15944
15944
 
15945
15945
  // compiled/src/version/version.js
15946
- var versionString = "Conway v1.425.1281";
15946
+ var versionString = "Conway v1.426.1283";
15947
15947
 
15948
15948
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
15949
15949
  function pThreadsAllowed() {
@@ -17287,6 +17287,20 @@ var Memory = class {
17287
17287
 
17288
17288
  // compiled/src/core/progress.js
17289
17289
  function yieldToEventLoop() {
17290
+ const scheduler = globalThis.scheduler;
17291
+ if (typeof scheduler?.yield === "function") {
17292
+ return scheduler.yield();
17293
+ }
17294
+ if (typeof MessageChannel === "function") {
17295
+ return new Promise((resolve) => {
17296
+ const channel = new MessageChannel();
17297
+ channel.port1.onmessage = () => {
17298
+ channel.port1.close();
17299
+ resolve();
17300
+ };
17301
+ channel.port2.postMessage(null);
17302
+ });
17303
+ }
17290
17304
  return new Promise((resolve) => {
17291
17305
  setTimeout(resolve, 0);
17292
17306
  });
@@ -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.425.1281";
947
+ var versionString = "Conway v1.426.1283";
948
948
 
949
949
  // compiled/dependencies/conway-geom/interface/conway_geometry.js
950
950
  var wasmType = "";
@@ -1498,6 +1498,20 @@ var environment_default = Environment;
1498
1498
 
1499
1499
  // compiled/src/core/progress.js
1500
1500
  function yieldToEventLoop() {
1501
+ const scheduler = globalThis.scheduler;
1502
+ if (typeof scheduler?.yield === "function") {
1503
+ return scheduler.yield();
1504
+ }
1505
+ if (typeof MessageChannel === "function") {
1506
+ return new Promise((resolve) => {
1507
+ const channel = new MessageChannel();
1508
+ channel.port1.onmessage = () => {
1509
+ channel.port1.close();
1510
+ resolve();
1511
+ };
1512
+ channel.port2.postMessage(null);
1513
+ });
1514
+ }
1501
1515
  return new Promise((resolve) => {
1502
1516
  setTimeout(resolve, 0);
1503
1517
  });
@@ -70410,9 +70424,24 @@ var IfcModelGeometry = class {
70410
70424
  /**
70411
70425
  * Add a mesh to the geometry cache.
70412
70426
  *
70427
+ * Freezes the native float vertex mirror at add time (one
70428
+ * GetVertexData call): consumers (the compat GetGeometry surface)
70429
+ * read float vertices whose frame must match the scene transforms,
70430
+ * which are authored against the geometry AS CREATED. Later native
70431
+ * mutations that keep the vertex count (normalize's centering)
70432
+ * deliberately do NOT refresh the mirror, so every extraction path —
70433
+ * whole-model walk, per-product demand pump, parse-time preview —
70434
+ * serves the same creation-frame floats. Without this, paths that
70435
+ * first read vertices only after a centering mutation serve
70436
+ * per-geometry-shifted vertices against unshifted transforms
70437
+ * (Share's demand-path "scatter").
70438
+ *
70413
70439
  * @param mesh
70414
70440
  */
70415
70441
  add(mesh) {
70442
+ if (mesh.type === CanonicalMeshType.BUFFER_GEOMETRY) {
70443
+ mesh.geometry.GetVertexData();
70444
+ }
70416
70445
  this.meshes_.set(mesh.localID, mesh);
70417
70446
  }
70418
70447
  /**
@@ -93,6 +93,47 @@ describe("OpenModelStreamed + DEFER_GEOMETRY", () => {
93
93
  api.CloseModel(classicID);
94
94
  api.CloseModel(deferredID);
95
95
  }, 240000);
96
+ test("deferred GetGeometry serves byte-identical vertex content to classic", async () => {
97
+ // The build multiplies GetGeometry FLOAT vertices by captured
98
+ // transforms, and the float mirror's frame must match the scene
99
+ // transforms (frozen at mesh add — see IfcModelGeometry.add). A
100
+ // per-geometry frame shift here renders as scattered pieces even
101
+ // with perfect transform parity, which transform-only assertions
102
+ // cannot catch.
103
+ //
104
+ // Fresh IfcAPI: CloseModel destroys the shared wasm processor, and
105
+ // models opened after ANY close serve empty geometry payloads (a
106
+ // long-standing multi-open shim quirk — browsers open one model per
107
+ // page). The shared `api` has closed models by the time this runs.
108
+ const api2 = new IfcAPI();
109
+ await api2.Init();
110
+ const classicID = api2.OpenModel(buffer, SETTINGS);
111
+ const geometryIDs = new Set();
112
+ api2.StreamAllMeshes(classicID, (mesh) => {
113
+ for (let where = 0; where < mesh.geometries.size(); ++where) {
114
+ geometryIDs.add(mesh.geometries.get(where).geometryExpressID);
115
+ }
116
+ });
117
+ const deferredID = await api2.OpenModelStreamed(buffer, { ...SETTINGS, DEFER_GEOMETRY: true });
118
+ api2.StreamAllMeshes(deferredID, () => { });
119
+ let compared = 0;
120
+ for (const geometryID of geometryIDs) {
121
+ const classicGeometry = api2.GetGeometry(classicID, geometryID);
122
+ const deferredGeometry = api2.GetGeometry(deferredID, geometryID);
123
+ const classicSize = classicGeometry.GetVertexDataSize();
124
+ if (classicSize === 0) {
125
+ continue;
126
+ }
127
+ expect(deferredGeometry.GetVertexDataSize()).toBe(classicSize);
128
+ const classicVertices = api2.GetVertexArray(classicGeometry.GetVertexData(), classicSize);
129
+ const deferredVertices = api2.GetVertexArray(deferredGeometry.GetVertexData(), classicSize);
130
+ expect(deferredVertices).toEqual(classicVertices);
131
+ ++compared;
132
+ }
133
+ expect(compared).toBeGreaterThan(0);
134
+ api2.CloseModel(classicID);
135
+ api2.CloseModel(deferredID);
136
+ }, 240000);
96
137
  test("ExtractGeometryBatch is a safe no-op on non-deferred models", async () => {
97
138
  const modelID = await api.OpenModelStreamed(buffer, SETTINGS);
98
139
  expect(api.ExtractGeometryBatch(modelID, 8))
@@ -42,7 +42,14 @@ export declare const DEFAULT_PROGRESS_INTERVAL_MS = 100;
42
42
  * repaint progress UI and timers (e.g. stall watchdogs) can fire. Used by the
43
43
  * *Async load variants between progress ticks.
44
44
  *
45
- * @return {Promise<void>} A promise resolved on the next timer turn.
45
+ * Not timer-based where avoidable: background tabs clamp setTimeout to >=1s,
46
+ * which would collapse a cooperative parse to a ~5% duty cycle the moment
47
+ * the tab loses focus. scheduler.yield() (and the MessageChannel fallback)
48
+ * post ordinary tasks, which are not clamped — loads keep their CPU in
49
+ * backgrounded tabs. setTimeout remains as the last-resort fallback for
50
+ * environments without either (where throttling doesn't apply anyway).
51
+ *
52
+ * @return {Promise<void>} A promise resolved on the next event-loop task.
46
53
  */
47
54
  export declare function yieldToEventLoop(): Promise<void>;
48
55
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/core/progress.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,GACvB,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,GAAG,WAAW,CAAA;AAEvE,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAElF;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAE,KAAK,EAAE,aAAa,KAAM,IAAI,CAAA;AAE/D;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAM,IAAI,CAAA;AAEhF,oEAAoE;AACpE,eAAO,MAAM,4BAA4B,MAAM,CAAA;AAE/C;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAIhD;AAED;;;;;;;GAOG;AACH,qBAAa,eAAe;IAexB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAdhC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,YAAY,CAAY;IAChC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,MAAM,CAAoB;IAElC;;;;;OAKG;gBAEgB,UAAU,EAAE,gBAAgB,EAC5B,aAAa,GAAE,MAAqC;IAEvE;;;;OAIG;IACH,IAAW,KAAK,IAAI,aAAa,GAAG,SAAS,CAE5C;IAED;;;;;;OAMG;IACI,UAAU,CAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,MAAM,GAAI,IAAI;IAQnF;;;;;OAKG;IACI,aAAa,CAAE,KAAK,EAAE,MAAM,GAAI,IAAI;IAI3C;;;;OAIG;IACI,MAAM,CAAE,SAAS,EAAE,MAAM,GAAI,IAAI;IAUxC;;;;;OAKG;IACI,QAAQ,CAAE,SAAS,CAAC,EAAE,MAAM,GAAI,IAAI;IAK3C;;;;;OAKG;IACH,OAAO,CAAC,IAAI;CAkBb"}
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/core/progress.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,GACvB,aAAa,GAAG,WAAW,GAAG,UAAU,GAAG,YAAY,GAAG,WAAW,CAAA;AAEvE,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAElF;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAE,KAAK,EAAE,aAAa,KAAM,IAAI,CAAA;AAE/D;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAM,IAAI,CAAA;AAEhF,oEAAoE;AACpE,eAAO,MAAM,4BAA4B,MAAM,CAAA;AAE/C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAuBhD;AAED;;;;;;;GAOG;AACH,qBAAa,eAAe;IAexB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAdhC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;IAC/C,OAAO,CAAC,YAAY,CAAY;IAChC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,MAAM,CAAoB;IAElC;;;;;OAKG;gBAEgB,UAAU,EAAE,gBAAgB,EAC5B,aAAa,GAAE,MAAqC;IAEvE;;;;OAIG;IACH,IAAW,KAAK,IAAI,aAAa,GAAG,SAAS,CAE5C;IAED;;;;;;OAMG;IACI,UAAU,CAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE,MAAM,GAAI,IAAI;IAQnF;;;;;OAKG;IACI,aAAa,CAAE,KAAK,EAAE,MAAM,GAAI,IAAI;IAI3C;;;;OAIG;IACI,MAAM,CAAE,SAAS,EAAE,MAAM,GAAI,IAAI;IAUxC;;;;;OAKG;IACI,QAAQ,CAAE,SAAS,CAAC,EAAE,MAAM,GAAI,IAAI;IAK3C;;;;;OAKG;IACH,OAAO,CAAC,IAAI;CAkBb"}
@@ -6,9 +6,30 @@ export const DEFAULT_PROGRESS_INTERVAL_MS = 100;
6
6
  * repaint progress UI and timers (e.g. stall watchdogs) can fire. Used by the
7
7
  * *Async load variants between progress ticks.
8
8
  *
9
- * @return {Promise<void>} A promise resolved on the next timer turn.
9
+ * Not timer-based where avoidable: background tabs clamp setTimeout to >=1s,
10
+ * which would collapse a cooperative parse to a ~5% duty cycle the moment
11
+ * the tab loses focus. scheduler.yield() (and the MessageChannel fallback)
12
+ * post ordinary tasks, which are not clamped — loads keep their CPU in
13
+ * backgrounded tabs. setTimeout remains as the last-resort fallback for
14
+ * environments without either (where throttling doesn't apply anyway).
15
+ *
16
+ * @return {Promise<void>} A promise resolved on the next event-loop task.
10
17
  */
11
18
  export function yieldToEventLoop() {
19
+ const scheduler = globalThis.scheduler;
20
+ if (typeof scheduler?.yield === "function") {
21
+ return scheduler.yield();
22
+ }
23
+ if (typeof MessageChannel === "function") {
24
+ return new Promise((resolve) => {
25
+ const channel = new MessageChannel();
26
+ channel.port1.onmessage = () => {
27
+ channel.port1.close();
28
+ resolve();
29
+ };
30
+ channel.port2.postMessage(null);
31
+ });
32
+ }
12
33
  return new Promise((resolve) => {
13
34
  setTimeout(resolve, 0);
14
35
  });
@@ -54,12 +54,21 @@ describe("ProgressTracker", () => {
54
54
  });
55
55
  });
56
56
  describe("yieldToEventLoop", () => {
57
- test("lets queued macrotasks run", async () => {
57
+ test("does not starve queued timers", async () => {
58
+ // The yield posts an ordinary task (scheduler.yield / MessageChannel —
59
+ // deliberately NOT a timer, so background tabs' >=1s setTimeout clamp
60
+ // cannot collapse a cooperative parse). Message tasks can be serviced
61
+ // ahead of the timer queue, so a due timer is not guaranteed to run
62
+ // within ONE yield — the contract is that repeated yielding lets due
63
+ // timers fire promptly (stall watchdogs stay live during a parse).
58
64
  let timerRan = false;
59
65
  setTimeout(() => {
60
66
  timerRan = true;
61
67
  }, 0);
62
- await yieldToEventLoop();
68
+ const MAX_YIELDS = 50;
69
+ for (let where = 0; where < MAX_YIELDS && !timerRan; ++where) {
70
+ await yieldToEventLoop();
71
+ }
63
72
  expect(timerRan).toBe(true);
64
73
  });
65
74
  });
@@ -30,6 +30,18 @@ export declare class IfcModelGeometry implements ModelGeometry {
30
30
  /**
31
31
  * Add a mesh to the geometry cache.
32
32
  *
33
+ * Freezes the native float vertex mirror at add time (one
34
+ * GetVertexData call): consumers (the compat GetGeometry surface)
35
+ * read float vertices whose frame must match the scene transforms,
36
+ * which are authored against the geometry AS CREATED. Later native
37
+ * mutations that keep the vertex count (normalize's centering)
38
+ * deliberately do NOT refresh the mirror, so every extraction path —
39
+ * whole-model walk, per-product demand pump, parse-time preview —
40
+ * serves the same creation-frame floats. Without this, paths that
41
+ * first read vertices only after a centering mutation serve
42
+ * per-geometry-shifted vertices against unshifted transforms
43
+ * (Share's demand-path "scatter").
44
+ *
33
45
  * @param mesh
34
46
  */
35
47
  add(mesh: CanonicalMesh): void;
@@ -1 +1 @@
1
- {"version":3,"file":"ifc_model_geometry.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_model_geometry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAqB,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,YAAY,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAoB,8BAA8B,EAAE,MAAM,YAAY,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAmB,MAAM,4BAA4B,CAAA;AAG/E;;GAEG;AACH,qBAAa,gBAAiB,YAAW,aAAa;aAUvB,KAAK,EAAE,YAAY;aAAkB,MAAM,EAAE,OAAO;IARjF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAE3D;;;;;OAKG;gBAC0B,KAAK,EAAE,YAAY,EAAkB,MAAM,GAAE,OAAe;IAEzF;;;;OAIG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAgBhC;;;;OAIG;IACI,GAAG,CAAC,IAAI,EAAE,aAAa;IAK9B;;;;OAIG;IACI,MAAM,CAAC,OAAO,EAAE,MAAM;IAe7B;;;;;OAKG;IACI,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI/D;;;;OAIG;IACI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,aAAa,CAAC;IAI3D;;;;OAIG;IACI,qBAAqB,IAAI,MAAM;IAqBtC;;;;OAIG;IACK,IAAI,IAAK,gBAAgB,CAAE;QACjC,8BAA8B;QAC9B,MAAM;QACN,iBAAiB;QACjB,MAAM;KAAC,GAAG;QACV,8BAA8B;QAC9B,MAAM;QACN,SAAS;QACT,SAAS;KAAC,CAAC;CAqDd"}
1
+ {"version":3,"file":"ifc_model_geometry.d.ts","sourceRoot":"","sources":["../../../src/ifc/ifc_model_geometry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAqB,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,YAAY,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAoB,8BAA8B,EAAE,MAAM,YAAY,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAmB,MAAM,4BAA4B,CAAA;AAG/E;;GAEG;AACH,qBAAa,gBAAiB,YAAW,aAAa;aAUvB,KAAK,EAAE,YAAY;aAAkB,MAAM,EAAE,OAAO;IARjF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAE3D;;;;;OAKG;gBAC0B,KAAK,EAAE,YAAY,EAAkB,MAAM,GAAE,OAAe;IAEzF;;;;OAIG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACI,iBAAiB,IAAI,IAAI;IAgBhC;;;;;;;;;;;;;;;;OAgBG;IACI,GAAG,CAAC,IAAI,EAAE,aAAa;IAS9B;;;;OAIG;IACI,MAAM,CAAC,OAAO,EAAE,MAAM;IAe7B;;;;;OAKG;IACI,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI/D;;;;OAIG;IACI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,aAAa,CAAC;IAI3D;;;;OAIG;IACI,qBAAqB,IAAI,MAAM;IAqBtC;;;;OAIG;IACK,IAAI,IAAK,gBAAgB,CAAE;QACjC,8BAA8B;QAC9B,MAAM;QACN,iBAAiB;QACjB,MAAM;KAAC,GAAG;QACV,8BAA8B;QAC9B,MAAM;QACN,SAAS;QACT,SAAS;KAAC,CAAC;CAqDd"}
@@ -40,9 +40,24 @@ export class IfcModelGeometry {
40
40
  /**
41
41
  * Add a mesh to the geometry cache.
42
42
  *
43
+ * Freezes the native float vertex mirror at add time (one
44
+ * GetVertexData call): consumers (the compat GetGeometry surface)
45
+ * read float vertices whose frame must match the scene transforms,
46
+ * which are authored against the geometry AS CREATED. Later native
47
+ * mutations that keep the vertex count (normalize's centering)
48
+ * deliberately do NOT refresh the mirror, so every extraction path —
49
+ * whole-model walk, per-product demand pump, parse-time preview —
50
+ * serves the same creation-frame floats. Without this, paths that
51
+ * first read vertices only after a centering mutation serve
52
+ * per-geometry-shifted vertices against unshifted transforms
53
+ * (Share's demand-path "scatter").
54
+ *
43
55
  * @param mesh
44
56
  */
45
57
  add(mesh) {
58
+ if (mesh.type === CanonicalMeshType.BUFFER_GEOMETRY) {
59
+ mesh.geometry.GetVertexData();
60
+ }
46
61
  this.meshes_.set(mesh.localID, mesh);
47
62
  }
48
63
  /**
@@ -5,5 +5,5 @@
5
5
  // only the first segment (major) is meaningful and is the one CI carries forward.
6
6
  // Must stay in `vN.N.N` shape: the CI stamp regex, scripts/updateVersion.mjs, and
7
7
  // statistics.ts all match `v\d+\.\d+\.\d+`.
8
- const versionString = 'Conway v1.425.1281';
8
+ const versionString = 'Conway v1.426.1283';
9
9
  export { versionString };