diff --git a/demo/js/app.js b/demo/js/app.js index 85cde8aa..18fbcabe 100644 --- a/demo/js/app.js +++ b/demo/js/app.js @@ -200,12 +200,12 @@ export const app = (window.app = createApp({ preview.sceneManager.boundingBoxColor = drawBoundingBox.value ? (settings.value.boundingBoxColor ?? 'magenta') : undefined; + preview.sceneManager.travelColor = settings.value.travelColor; }); watchEffect(() => { if (!preview) return; preview.sceneManager.renderTravel = settings.value.renderTravel; - preview.sceneManager.travelColor = settings.value.travelColor; preview.sceneManager.lineWidth = +settings.value.lineWidth; preview.sceneManager.renderExtrusion = settings.value.renderExtrusion; diff --git a/src/extensions/object3d.ts b/src/extensions/object3d.ts new file mode 100644 index 00000000..bd2293e9 --- /dev/null +++ b/src/extensions/object3d.ts @@ -0,0 +1,21 @@ +import { Object3D } from 'three'; + +declare module 'three' { + interface Object3D { + // eslint-disable-next-line no-unused-vars + getByUserData(name: string, value: unknown): Array; + } +} + +// from https://discourse.threejs.org/t/getobject-by-any-custom-property-present-in-userdata-of-object/3378/3 +Object3D.prototype.getByUserData = function (this: Object3D, name: string, value: unknown) { + const meshes: Array = []; + + this.traverse((node) => { + if (node.userData[name] === value) { + meshes.push(node); + } + }); + + return meshes; +}; diff --git a/src/gcode-preview.ts b/src/gcode-preview.ts index 0a410539..c07e9018 100644 --- a/src/gcode-preview.ts +++ b/src/gcode-preview.ts @@ -5,6 +5,7 @@ import { Job } from './job'; import { DevGUI, type DevModeOptions } from './dev-gui'; import Stats from 'three/examples/jsm/libs/stats.module.js'; import { makeDroppable } from './extra/dom-utils'; +import './extensions/object3d'; // import extensions /** * Options for configuring the G-code preview diff --git a/src/scene-manager.ts b/src/scene-manager.ts index dcdef194..34a7468f 100644 --- a/src/scene-manager.ts +++ b/src/scene-manager.ts @@ -27,7 +27,8 @@ import { Vector3, WebGLRenderer, MathUtils, - LineBasicMaterial + LineBasicMaterial, + Object3D } from 'three'; export type BuildVolumeDef = Pick; @@ -331,6 +332,12 @@ export class SceneManager { } this.materials[0].uniforms.uColor.value = this._extrusionColor; + + if (!this.renderTubes) { + for (const line of this.extrusionLines) { + line.material.color.set(this._extrusionColor); + } + } } /** @@ -364,6 +371,10 @@ export class SceneManager { */ set travelColor(value: number | string | Color) { this._travelColor = new Color(value); + + for (const line of this.travelLines) { + line.material.color.set(this._travelColor); + } } /** @@ -604,6 +615,16 @@ export class SceneManager { }); } + private get travelLines() { + const lines = this.scene.getByUserData('lineType', 'travel'); + return lines as unknown as [LineSegments2]; + } + + private get extrusionLines() { + const lines = this.scene.getByUserData('lineType', 'extrusion'); + return lines as unknown as [LineSegments2]; + } + /** @internal */ /** * Animation loop that continuously renders the scene @@ -828,7 +849,13 @@ export class SceneManager { */ private renderPaths(endPathNumber: number = Infinity): void { if (this.renderTravel) { - this.renderPathsAsLines(this.job.travels.slice(this.renderPathIndex, endPathNumber), this._travelColor); + const travelLine = this.renderPathsAsLines( + this.job.travels.slice(this.renderPathIndex, endPathNumber), + this._travelColor + ); + travelLine.userData = { + lineType: 'travel' + }; } if (this.renderExtrusion) { @@ -837,7 +864,10 @@ export class SceneManager { if (this.renderTubes) { this.renderPathsAsTubes(toolPaths.slice(this.renderPathIndex, endPathNumber), color); } else { - this.renderPathsAsLines(toolPaths.slice(this.renderPathIndex, endPathNumber), color); + const extrusionLine = this.renderPathsAsLines(toolPaths.slice(this.renderPathIndex, endPathNumber), color); + extrusionLine.userData = { + lineType: 'extrusion' + }; } }); } @@ -848,7 +878,7 @@ export class SceneManager { * @param paths - Array of paths to render * @param color - Color to use for the lines */ - private renderPathsAsLines(paths: Path[], color: Color): void { + private renderPathsAsLines(paths: Path[], color: Color): Object3D { const minZ = this.job.layers[this._startLayer - 1]?.z; const maxZ = this.job.layers[this._endLayer - 1]?.z; @@ -882,6 +912,7 @@ export class SceneManager { this.disposables.push(material); this.disposables.push(geometry); this.currentChunk?.add(line); + return line; } /**