fluidcad 0.0.26 → 0.0.28

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.
Files changed (93) hide show
  1. package/lib/dist/common/scene-object.d.ts +45 -0
  2. package/lib/dist/common/scene-object.js +121 -0
  3. package/lib/dist/common/shape-factory.d.ts +1 -1
  4. package/lib/dist/common/shape-history-tracker.d.ts +35 -0
  5. package/lib/dist/common/shape-history-tracker.js +114 -0
  6. package/lib/dist/common/shape.js +7 -1
  7. package/lib/dist/common/shapes.d.ts +0 -1
  8. package/lib/dist/common/shapes.js +0 -1
  9. package/lib/dist/common/solid.js +5 -1
  10. package/lib/dist/core/extrude.d.ts +12 -13
  11. package/lib/dist/core/extrude.js +19 -1
  12. package/lib/dist/core/part.d.ts +2 -1
  13. package/lib/dist/core/part.js +4 -1
  14. package/lib/dist/core/sketch.d.ts +4 -3
  15. package/lib/dist/core/sketch.js +4 -1
  16. package/lib/dist/features/chamfer.js +12 -6
  17. package/lib/dist/features/extrude-base.d.ts +43 -1
  18. package/lib/dist/features/extrude-base.js +141 -36
  19. package/lib/dist/features/extrude-to-face.d.ts +1 -1
  20. package/lib/dist/features/extrude-to-face.js +42 -19
  21. package/lib/dist/features/extrude-two-distances.d.ts +1 -1
  22. package/lib/dist/features/extrude-two-distances.js +41 -15
  23. package/lib/dist/features/extrude.d.ts +1 -1
  24. package/lib/dist/features/extrude.js +75 -20
  25. package/lib/dist/features/fillet.js +3 -4
  26. package/lib/dist/features/fuse.js +14 -0
  27. package/lib/dist/features/infinite-extrude.d.ts +1 -0
  28. package/lib/dist/features/infinite-extrude.js +33 -4
  29. package/lib/dist/features/loft.js +18 -5
  30. package/lib/dist/features/mirror-shape.d.ts +1 -3
  31. package/lib/dist/features/mirror-shape.js +2 -1
  32. package/lib/dist/features/revolve.js +17 -4
  33. package/lib/dist/features/rotate.js +1 -0
  34. package/lib/dist/features/simple-extruder.js +5 -0
  35. package/lib/dist/features/sweep.js +13 -2
  36. package/lib/dist/features/translate.js +3 -1
  37. package/lib/dist/filters/face/face-filter.d.ts +12 -0
  38. package/lib/dist/filters/face/face-filter.js +21 -0
  39. package/lib/dist/filters/face/torus-filter.d.ts +19 -0
  40. package/lib/dist/filters/face/torus-filter.js +38 -0
  41. package/lib/dist/helpers/scene-helpers.d.ts +10 -2
  42. package/lib/dist/helpers/scene-helpers.js +278 -10
  43. package/lib/dist/index.d.ts +1 -0
  44. package/lib/dist/oc/boolean-ops.d.ts +32 -4
  45. package/lib/dist/oc/boolean-ops.js +122 -11
  46. package/lib/dist/oc/color-transfer.d.ts +37 -0
  47. package/lib/dist/oc/color-transfer.js +135 -0
  48. package/lib/dist/oc/extrude-ops.js +25 -3
  49. package/lib/dist/oc/face-ops.d.ts +0 -1
  50. package/lib/dist/oc/face-ops.js +0 -13
  51. package/lib/dist/oc/face-query.d.ts +2 -0
  52. package/lib/dist/oc/face-query.js +30 -0
  53. package/lib/dist/oc/fillet-ops.d.ts +5 -3
  54. package/lib/dist/oc/fillet-ops.js +107 -70
  55. package/lib/dist/oc/intersection.js +6 -3
  56. package/lib/dist/oc/mesh.d.ts +25 -2
  57. package/lib/dist/oc/mesh.js +112 -35
  58. package/lib/dist/oc/shape-ops.d.ts +25 -20
  59. package/lib/dist/oc/shape-ops.js +129 -113
  60. package/lib/dist/rendering/mesh-transform.js +17 -1
  61. package/lib/dist/rendering/render-solid.js +19 -6
  62. package/lib/dist/rendering/render-wire.js +2 -0
  63. package/lib/dist/rendering/render.d.ts +12 -2
  64. package/lib/dist/rendering/render.js +195 -220
  65. package/lib/dist/scene-manager.d.ts +2 -0
  66. package/lib/dist/scene-manager.js +4 -3
  67. package/lib/dist/tests/common/scene-object-history.test.d.ts +1 -0
  68. package/lib/dist/tests/common/scene-object-history.test.js +274 -0
  69. package/lib/dist/tests/common/shape-history-tracker.test.d.ts +1 -0
  70. package/lib/dist/tests/common/shape-history-tracker.test.js +110 -0
  71. package/lib/dist/tests/features/2d/project-regression.test.d.ts +1 -0
  72. package/lib/dist/tests/features/2d/project-regression.test.js +69 -0
  73. package/lib/dist/tests/features/2d/project-user-regression.test.d.ts +1 -0
  74. package/lib/dist/tests/features/2d/project-user-regression.test.js +37 -0
  75. package/lib/dist/tests/features/color-lineage.test.d.ts +1 -0
  76. package/lib/dist/tests/features/color-lineage.test.js +213 -0
  77. package/lib/dist/tests/features/cut-symmetric-through-all.test.d.ts +1 -0
  78. package/lib/dist/tests/features/cut-symmetric-through-all.test.js +32 -0
  79. package/lib/dist/tests/features/extrude-history.test.d.ts +1 -0
  80. package/lib/dist/tests/features/extrude-history.test.js +248 -0
  81. package/lib/dist/tests/features/extrude.test.js +71 -0
  82. package/lib/dist/tests/features/fillet2d.test.js +16 -1
  83. package/lib/dist/tests/features/peer-ops-history.test.d.ts +1 -0
  84. package/lib/dist/tests/features/peer-ops-history.test.js +119 -0
  85. package/lib/dist/tests/features/select.test.js +50 -0
  86. package/lib/dist/tests/features/subtract.test.js +21 -1
  87. package/lib/dist/tests/setup.js +3 -2
  88. package/lib/dist/tsconfig.tsbuildinfo +1 -1
  89. package/package.json +3 -3
  90. package/ui/dist/assets/{index-BeLxRMCv.js → index-BrW_x4uc.js} +37 -37
  91. package/ui/dist/index.html +1 -1
  92. package/lib/dist/common/solid-face.d.ts +0 -9
  93. package/lib/dist/common/solid-face.js +0 -22
@@ -4,252 +4,227 @@ import { AxisObjectBase } from "../features/axis-renderable-base.js";
4
4
  import { Sketch } from "../features/2d/sketch.js";
5
5
  import { transformMeshes } from "./mesh-transform.js";
6
6
  import { ShapeOps } from "../oc/shape-ops.js";
7
- const meshBuilder = new MeshBuilder();
8
- function renderSceneObject(obj, scene, buildDurationMs) {
9
- const hasError = !!obj.getError();
10
- const sceneShapes = obj.getOwnShapes({ excludeMeta: false, excludeGuide: false });
11
- const renderedSceneShapes = [];
12
- if (sceneShapes.length) {
13
- console.log(` - Scene shapes: ${sceneShapes.length}`);
14
- for (const shape of sceneShapes) {
15
- let meshes = shape.getMeshes();
16
- if (!meshes) {
17
- const meshSource = shape.getMeshSource();
18
- if (meshSource) {
19
- let sourceMeshes = meshSource.shape.getMeshes();
20
- if (!sourceMeshes) {
21
- sourceMeshes = meshBuilder.build(meshSource.shape);
22
- meshSource.shape.setMeshes(sourceMeshes);
23
- }
24
- meshes = sourceMeshes ? transformMeshes(sourceMeshes, meshSource.matrix) : meshBuilder.build(shape);
25
- }
26
- else {
27
- meshes = meshBuilder.build(shape);
28
- }
29
- shape.setMeshes(meshes);
7
+ export class SceneRenderer {
8
+ meshBuilder = new MeshBuilder();
9
+ render(scene) {
10
+ const sceneObjects = scene.getAllSceneObjects();
11
+ console.log("============ Rendering ==============", sceneObjects.length);
12
+ const skippedContainers = new Set();
13
+ const buildDurations = new Map();
14
+ for (const object of sceneObjects) {
15
+ // Skip descendants of cloned sketches — their edges are already
16
+ // computed by the parent sketch's clone-mode build.
17
+ const parent = object.getParent();
18
+ if (parent && skippedContainers.has(parent)) {
19
+ skippedContainers.add(object);
20
+ continue;
30
21
  }
31
- const shapeType = shape.getType();
32
- renderedSceneShapes.push({
33
- shapeId: shape.id,
34
- meshes,
35
- shapeType,
36
- isMetaShape: shape.isMetaShape() || undefined,
37
- isGuide: shape.isGuideShape() || undefined,
38
- metaType: shape.metaType || undefined,
39
- metaData: shape.metaData || undefined,
40
- });
41
- }
42
- }
43
- let isVisible = !!sceneShapes.length;
44
- if (obj.isAlwaysVisible()) {
45
- isVisible = true;
46
- }
47
- else if (obj.isContainer()) {
48
- const children = scene.getChildren(obj);
49
- isVisible = children.some(child => {
50
- const shapes = child.getOwnShapes();
51
- return shapes.length > 0;
52
- });
53
- }
54
- scene.addRenderedObject(obj, {
55
- id: obj.id,
56
- name: obj.getName(),
57
- parentId: obj.parentId,
58
- object: obj.serialize(),
59
- sceneShapes: renderedSceneShapes,
60
- type: obj.getType(),
61
- uniqueType: obj.getUniqueType(),
62
- fromCache: scene.isCached(obj),
63
- visible: isVisible,
64
- isContainer: obj.isContainer(),
65
- hasError,
66
- errorMessage: obj.getError() || undefined,
67
- sourceLocation: obj.getSourceLocation() || undefined,
68
- buildDurationMs,
69
- });
70
- }
71
- export function renderSceneRollback(scene, rollbackIndex) {
72
- console.log("============ Rollback Rendering ==============", rollbackIndex);
73
- const scope = new Set();
74
- const allObjects = scene.getAllSceneObjects();
75
- for (let i = 0; i <= rollbackIndex && i < allObjects.length; i++) {
76
- scope.add(allObjects[i]);
77
- }
78
- scene.clearRenderedObjects();
79
- for (const obj of allObjects) {
80
- const inScope = scope.has(obj);
81
- if (inScope) {
82
- const sceneShapes = obj.getOwnShapes({ excludeMeta: false }, scope);
83
- const renderedSceneShapes = [];
84
- for (const shape of sceneShapes) {
85
- let meshes = shape.getMeshes();
86
- if (!meshes) {
87
- const meshSource = shape.getMeshSource();
88
- if (meshSource) {
89
- let sourceMeshes = meshSource.shape.getMeshes();
90
- if (!sourceMeshes) {
91
- sourceMeshes = meshBuilder.build(meshSource.shape);
92
- meshSource.shape.setMeshes(sourceMeshes);
93
- }
94
- meshes = sourceMeshes ? transformMeshes(sourceMeshes, meshSource.matrix) : meshBuilder.build(shape);
95
- }
96
- else {
97
- meshes = meshBuilder.build(shape);
98
- }
99
- shape.setMeshes(meshes);
100
- }
101
- renderedSceneShapes.push({
102
- shapeId: shape.id,
103
- meshes,
104
- shapeType: shape.getType(),
105
- isMetaShape: shape.isMetaShape() || undefined,
106
- isGuide: shape.isGuideShape() || undefined,
107
- metaType: shape.metaType || undefined,
108
- metaData: shape.metaData || undefined,
109
- });
22
+ console.log("Rendering object:", object.getUniqueType());
23
+ if (!scene.isCached(object)) {
24
+ buildDurations.set(object, this.buildObject(object, scene));
25
+ }
26
+ // After building, mark cloned sketches so their children are skipped —
27
+ // the sketch's build() already populated them with transformed shapes.
28
+ if (object instanceof Sketch && object.getCloneSource()) {
29
+ skippedContainers.add(object);
110
30
  }
111
- let isVisible = !!sceneShapes.length;
112
- if (obj.isAlwaysVisible()) {
113
- isVisible = true;
31
+ }
32
+ for (const object of sceneObjects) {
33
+ if (skippedContainers.has(object)) {
34
+ continue;
114
35
  }
115
- else if (obj.isContainer()) {
116
- const children = scene.getChildren(obj);
117
- isVisible = children.some(child => {
118
- if (!scope.has(child))
119
- return false;
120
- const shapes = child.getOwnShapes({ excludeMeta: true }, scope);
121
- return shapes.length > 0;
36
+ object.clean(scene.getPartScopedAllObjects(object));
37
+ }
38
+ this.aggregateContainerDurations(sceneObjects, scene, buildDurations);
39
+ for (const object of sceneObjects) {
40
+ this.renderObject(object, scene, buildDurations.get(object));
41
+ }
42
+ return scene;
43
+ }
44
+ renderRollback(scene, rollbackIndex) {
45
+ console.log("============ Rollback Rendering ==============", rollbackIndex);
46
+ const allObjects = scene.getAllSceneObjects();
47
+ const scope = new Set();
48
+ for (let i = 0; i <= rollbackIndex && i < allObjects.length; i++) {
49
+ scope.add(allObjects[i]);
50
+ }
51
+ scene.clearRenderedObjects();
52
+ for (const obj of allObjects) {
53
+ if (!scope.has(obj)) {
54
+ this.emitRendered(obj, scene, {
55
+ sceneShapes: [],
56
+ visible: false,
57
+ hasError: false,
58
+ scope,
122
59
  });
60
+ continue;
123
61
  }
124
- scene.addRenderedObject(obj, {
125
- id: obj.id,
126
- name: obj.getName(),
127
- parentId: obj.parentId,
128
- object: obj.serialize(scope),
62
+ const sceneShapes = obj.getOwnShapes({ excludeMeta: false }, scope);
63
+ const renderedSceneShapes = sceneShapes.map(s => this.toRenderedShape(s));
64
+ this.emitRendered(obj, scene, {
129
65
  sceneShapes: renderedSceneShapes,
130
- type: obj.getType(),
131
- uniqueType: obj.getUniqueType(),
132
- fromCache: scene.isCached(obj),
133
- visible: isVisible,
134
- isContainer: obj.isContainer(),
66
+ visible: this.computeVisibility(obj, scene, sceneShapes.length, scope),
135
67
  hasError: false,
136
- sourceLocation: obj.getSourceLocation() || undefined,
68
+ scope,
137
69
  });
138
70
  }
139
- else {
140
- scene.addRenderedObject(obj, {
141
- id: obj.id,
142
- name: obj.getName(),
143
- parentId: obj.parentId,
144
- object: obj.serialize(scope),
145
- sceneShapes: [],
146
- type: obj.getType(),
147
- uniqueType: obj.getUniqueType(),
148
- fromCache: scene.isCached(obj),
71
+ const result = scene.getRenderedObjects();
72
+ console.table(result);
73
+ return scene;
74
+ }
75
+ renderObject(obj, scene, buildDurationMs) {
76
+ const sceneShapes = obj.getOwnShapes({ excludeMeta: false, excludeGuide: false });
77
+ const renderedSceneShapes = [];
78
+ try {
79
+ if (sceneShapes.length) {
80
+ console.log(` - Scene shapes: ${sceneShapes.length}`);
81
+ for (const shape of sceneShapes) {
82
+ renderedSceneShapes.push(this.toRenderedShape(shape));
83
+ }
84
+ }
85
+ const errorMessage = obj.getError();
86
+ this.emitRendered(obj, scene, {
87
+ sceneShapes: renderedSceneShapes,
88
+ visible: this.computeVisibility(obj, scene, sceneShapes.length),
89
+ hasError: !!errorMessage,
90
+ errorMessage: errorMessage || undefined,
91
+ buildDurationMs,
92
+ });
93
+ }
94
+ catch (error) {
95
+ const message = error instanceof Error ? error.message : String(error);
96
+ console.error(`Error rendering object ${obj.getUniqueType()}:`, error);
97
+ this.emitRendered(obj, scene, {
98
+ sceneShapes: renderedSceneShapes,
149
99
  visible: false,
150
- isContainer: obj.isContainer(),
151
- hasError: false,
152
- sourceLocation: obj.getSourceLocation() || undefined,
100
+ hasError: true,
101
+ errorMessage: message,
102
+ buildDurationMs,
153
103
  });
154
104
  }
155
105
  }
156
- const result = scene.getRenderedObjects();
157
- console.table(result);
158
- return scene;
159
- }
160
- export function renderScene(scene) {
161
- const sceneObjects = scene.getAllSceneObjects();
162
- console.log("============ Rendering ==============", sceneObjects.length);
163
- const skippedContainers = new Set();
164
- const buildDurations = new Map();
165
- for (const object of sceneObjects) {
166
- // Skip descendants of cloned sketches — their edges are already
167
- // computed by the parent sketch's clone-mode build.
168
- const parent = object.getParent();
169
- if (parent && skippedContainers.has(parent)) {
170
- skippedContainers.add(object);
171
- continue;
172
- }
173
- console.log("Rendering object:", object.getUniqueType());
174
- const isCached = scene.isCached(object);
175
- if (!isCached) {
176
- object.clearError();
177
- const buildStart = performance.now();
178
- try {
179
- object.build({
180
- getSceneObjects() {
181
- return scene.getPartScopedObjectsUpTo(object);
182
- },
183
- getActiveSceneObjects() {
184
- return scene.getPartScopedActiveObjectsUpTo(object);
185
- },
186
- getSceneObjectsFromTo(from, to) {
187
- return scene.getSceneObjectsFromTo(from, to);
188
- },
189
- getTransform() {
190
- return object.getTransform();
191
- },
192
- getLastObject() {
193
- const objects = scene.getSceneObjectsUpTo(object);
194
- for (let i = objects.length - 1; i >= 0; i--) {
195
- const obj = objects[i];
196
- if (!(obj instanceof PlaneObjectBase) && !(obj instanceof AxisObjectBase)) {
197
- return obj;
198
- }
106
+ buildObject(object, scene) {
107
+ object.clearError();
108
+ const start = performance.now();
109
+ try {
110
+ object.build({
111
+ getSceneObjects: () => scene.getPartScopedObjectsUpTo(object),
112
+ getActiveSceneObjects: () => scene.getPartScopedActiveObjectsUpTo(object),
113
+ getSceneObjectsFromTo: (from, to) => scene.getSceneObjectsFromTo(from, to),
114
+ getTransform: () => object.getTransform(),
115
+ getLastObject: () => {
116
+ const objects = scene.getSceneObjectsUpTo(object);
117
+ for (let i = objects.length - 1; i >= 0; i--) {
118
+ const obj = objects[i];
119
+ if (!(obj instanceof PlaneObjectBase) && !(obj instanceof AxisObjectBase)) {
120
+ return obj;
199
121
  }
200
- return null;
201
- },
202
- });
203
- const appliedTransform = object.getAppliedTransform();
204
- if (appliedTransform && !object.isContainer()) {
205
- const shapes = object.getAddedShapes();
206
- for (let i = 0; i < shapes.length; i++) {
207
- shapes[i] = ShapeOps.transform(shapes[i], appliedTransform);
208
122
  }
123
+ return null;
124
+ },
125
+ });
126
+ const appliedTransform = object.getAppliedTransform();
127
+ if (appliedTransform && !object.isContainer()) {
128
+ const shapes = object.getAddedShapes();
129
+ for (let i = 0; i < shapes.length; i++) {
130
+ shapes[i] = ShapeOps.transform(shapes[i], appliedTransform);
209
131
  }
210
132
  }
211
- catch (error) {
212
- const message = error instanceof Error ? error.message : String(error);
213
- console.error(`Error building object ${object.getUniqueType()}:`, error);
214
- object.setError(message);
215
- }
216
- buildDurations.set(object, performance.now() - buildStart);
217
133
  }
218
- // After building, mark cloned sketches so their children are skipped —
219
- // the sketch's build() already populated them with transformed shapes.
220
- if (object instanceof Sketch && object.getCloneSource()) {
221
- skippedContainers.add(object);
134
+ catch (error) {
135
+ const message = error instanceof Error ? error.message : String(error);
136
+ console.error(`Error building object ${object.getUniqueType()}:`, error);
137
+ object.setError(message);
222
138
  }
139
+ return performance.now() - start;
223
140
  }
224
- // Cleanup pass — let objects adjust based on final scene state
225
- for (const object of sceneObjects) {
226
- if (skippedContainers.has(object)) {
227
- continue;
141
+ getOrBuildMeshes(shape) {
142
+ const existing = shape.getMeshes();
143
+ if (existing) {
144
+ return existing;
145
+ }
146
+ let meshes;
147
+ const meshSource = shape.getMeshSource();
148
+ if (meshSource) {
149
+ let sourceMeshes = meshSource.shape.getMeshes();
150
+ if (!sourceMeshes) {
151
+ sourceMeshes = this.meshBuilder.build(meshSource.shape);
152
+ meshSource.shape.setMeshes(sourceMeshes);
153
+ }
154
+ meshes = sourceMeshes ? transformMeshes(sourceMeshes, meshSource.matrix) : this.meshBuilder.build(shape);
228
155
  }
229
- object.clean(scene.getPartScopedAllObjects(object));
156
+ else {
157
+ meshes = this.meshBuilder.build(shape);
158
+ }
159
+ shape.setMeshes(meshes);
160
+ return meshes;
161
+ }
162
+ toRenderedShape(shape) {
163
+ return {
164
+ shapeId: shape.id,
165
+ meshes: this.getOrBuildMeshes(shape),
166
+ shapeType: shape.getType(),
167
+ isMetaShape: shape.isMetaShape() || undefined,
168
+ isGuide: shape.isGuideShape() || undefined,
169
+ metaType: shape.metaType || undefined,
170
+ metaData: shape.metaData || undefined,
171
+ };
230
172
  }
231
- // Roll up container durations: include own build time plus all descendants.
232
- // Iterate in reverse so nested containers are aggregated before their parents.
233
- for (let i = sceneObjects.length - 1; i >= 0; i--) {
234
- const object = sceneObjects[i];
235
- if (!object.isContainer()) {
236
- continue;
173
+ computeVisibility(obj, scene, ownShapeCount, scope) {
174
+ if (obj.isAlwaysVisible()) {
175
+ return true;
237
176
  }
238
- const own = buildDurations.get(object);
239
- if (own === undefined) {
240
- continue;
177
+ if (obj.isContainer()) {
178
+ const children = scene.getChildren(obj);
179
+ return children.some(child => {
180
+ if (scope && !scope.has(child)) {
181
+ return false;
182
+ }
183
+ const shapes = scope
184
+ ? child.getOwnShapes({ excludeMeta: true }, scope)
185
+ : child.getOwnShapes();
186
+ return shapes.length > 0;
187
+ });
241
188
  }
242
- let total = own;
243
- for (const child of scene.getChildren(object)) {
244
- const childDuration = buildDurations.get(child);
245
- if (childDuration !== undefined) {
246
- total += childDuration;
189
+ return ownShapeCount > 0;
190
+ }
191
+ aggregateContainerDurations(sceneObjects, scene, durations) {
192
+ for (let i = sceneObjects.length - 1; i >= 0; i--) {
193
+ const object = sceneObjects[i];
194
+ if (!object.isContainer()) {
195
+ continue;
196
+ }
197
+ const own = durations.get(object);
198
+ if (own === undefined) {
199
+ continue;
200
+ }
201
+ let total = own;
202
+ for (const child of scene.getChildren(object)) {
203
+ const childDuration = durations.get(child);
204
+ if (childDuration !== undefined) {
205
+ total += childDuration;
206
+ }
247
207
  }
208
+ durations.set(object, total);
248
209
  }
249
- buildDurations.set(object, total);
250
210
  }
251
- for (const object of sceneObjects) {
252
- renderSceneObject(object, scene, buildDurations.get(object));
211
+ emitRendered(obj, scene, opts) {
212
+ const rendered = {
213
+ id: obj.id,
214
+ name: obj.getName(),
215
+ parentId: obj.parentId,
216
+ object: obj.serialize(opts.scope),
217
+ sceneShapes: opts.sceneShapes,
218
+ type: obj.getType(),
219
+ uniqueType: obj.getUniqueType(),
220
+ fromCache: scene.isCached(obj),
221
+ visible: opts.visible,
222
+ isContainer: obj.isContainer(),
223
+ hasError: opts.hasError,
224
+ errorMessage: opts.errorMessage,
225
+ sourceLocation: obj.getSourceLocation() || undefined,
226
+ buildDurationMs: opts.buildDurationMs,
227
+ };
228
+ scene.addRenderedObject(obj, rendered);
253
229
  }
254
- return scene;
255
230
  }
@@ -1,4 +1,5 @@
1
1
  import { Scene } from "./rendering/scene.js";
2
+ import { SceneRenderer } from "./rendering/render.js";
2
3
  import type { ExportOptions } from "./io/file-export.js";
3
4
  import type { ShapeProperties } from "./oc/props.js";
4
5
  import type { FaceProperties } from "./oc/face-props.js";
@@ -8,6 +9,7 @@ declare class SceneManager {
8
9
  rootPath: string;
9
10
  currentScene: Scene;
10
11
  currentFile: string;
12
+ renderer: SceneRenderer;
11
13
  constructor(rootPath: string);
12
14
  setCurrentFile(filePath: string): void;
13
15
  startScene(): Scene;
@@ -1,5 +1,5 @@
1
1
  import { Scene } from "./rendering/scene.js";
2
- import { renderScene, renderSceneRollback } from "./rendering/render.js";
2
+ import { SceneRenderer } from "./rendering/render.js";
3
3
  import { SceneCompare } from "./rendering/scene-compare.js";
4
4
  import { FileImport } from "./io/file-import.js";
5
5
  import { FileExport } from "./io/file-export.js";
@@ -12,6 +12,7 @@ class SceneManager {
12
12
  rootPath;
13
13
  currentScene = new Scene();
14
14
  currentFile = '';
15
+ renderer = new SceneRenderer();
15
16
  constructor(rootPath) {
16
17
  this.rootPath = rootPath;
17
18
  }
@@ -24,10 +25,10 @@ class SceneManager {
24
25
  return this.currentScene;
25
26
  }
26
27
  renderScene(scene) {
27
- return renderScene(scene);
28
+ return this.renderer.render(scene);
28
29
  }
29
30
  rollbackScene(scene, rollbackIndex) {
30
- return renderSceneRollback(scene, rollbackIndex);
31
+ return this.renderer.renderRollback(scene, rollbackIndex);
31
32
  }
32
33
  compare(previous, current) {
33
34
  return SceneCompare.compare(previous, current);