Skip to content

Commit 81d93a7

Browse files
authored
Merge branch 'develop' into feature/export-stl
2 parents 86a9681 + 4467614 commit 81d93a7

6 files changed

Lines changed: 129 additions & 78 deletions

File tree

demo/index.html

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,26 +72,35 @@ <h1 class="text-center m-3 mb-5">GCode Preview
7272
<div class="panel" v-cloak v-show="activeTab == 'layers'">
7373
<section>
7474
<div class="controls">
75-
<label :class="{'has-text-grey' : settings.singleLayerMode}" >Start layer <output id="start-layer-value" >{{settings.startLayer}}</output></label>&nbsp;
75+
<label>
76+
Start Layer
77+
<input type="checkbox" v-model="settings.enableStartLayer" />
78+
</label>
79+
<label :class="{'has-text-grey' : !settings.enableStartLayer}" ><output id="start-layer-value" >{{settings.startLayer}}</output></label>&nbsp;
7680
<input
77-
type="range"
78-
min="1"
79-
:max="settings.maxLayer"
80-
id="start-layer"
81-
v-model="settings.startLayer"
82-
:disabled="settings.singleLayerMode"
81+
type="range"
82+
min="1"
83+
:max="settings.maxLayer"
84+
id="start-layer"
85+
v-model="settings.startLayer"
86+
:disabled="!settings.enableStartLayer"
8387
/>
8488
</div>
8589
<div class="controls">
86-
<label>End layer <output id="end-layer-value" >{{settings.endLayer}}</output></label>&nbsp;
90+
<label>
91+
End Layer
92+
<input type="checkbox" v-model="settings.enableEndLayer" />
93+
</label>
94+
<label :class="{'has-text-grey' : !settings.enableEndLayer}"> <output id="end-layer-value" >{{settings.endLayer}}</output></label>&nbsp;
8795
<!-- HACK: extra :value binding to ensure the value is set after the max is updated -->
8896
<input
89-
v-model="settings.endLayer"
90-
type="range"
91-
min="1"
92-
:max="settings.maxLayer"
93-
id="end-layer"
94-
:value="settings.endLayer"
97+
v-model="settings.endLayer"
98+
type="range"
99+
min="1"
100+
:max="settings.maxLayer"
101+
id="end-layer"
102+
:value="settings.endLayer"
103+
:disabled="!settings.enableEndLayer"
95104
/>
96105
</div>
97106
<div class="controls">

demo/js/app.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,11 @@ export const app = (window.app = createApp({
8282
layerCount.value = countLayers;
8383
const colors = extrusionColor instanceof Array ? extrusionColor : [extrusionColor];
8484
const currentSettings = {
85+
startLayer: 1,
86+
enableStartLayer: false,
8587
maxLayer: countLayers,
8688
endLayer: countLayers,
89+
enableEndLayer: false,
8790
singleLayerMode,
8891
renderTravel,
8992
travelColor: '#' + travelColor.getHexString(),
@@ -223,8 +226,8 @@ export const app = (window.app = createApp({
223226
});
224227

225228
watchEffect(() => {
226-
preview.startLayer = +settings.value.startLayer;
227-
preview.endLayer = +settings.value.endLayer;
229+
preview.startLayer = settings.value.enableStartLayer ? +settings.value.startLayer : undefined;
230+
preview.endLayer = settings.value.enableEndLayer ? +settings.value.endLayer : undefined;
228231
});
229232

230233
watchEffect(() => {

demo/js/presets.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export const presets = {
2323
original: 'https://www.thingiverse.com/thing:387266'
2424
},
2525
extrusionWidth: 0.5,
26+
lineHeight: 0.3,
2627
extrusionColor: ['#95dfa1'],
2728
travelColor: 'red',
2829
topLayerColor: undefined,
@@ -69,6 +70,7 @@ export const presets = {
6970
original: 'https://www.thingiverse.com/thing:1013494'
7071
},
7172
lineWidth: 1,
73+
lineHeight: 0.3,
7274
renderExtrusion: true,
7375
renderTubes: true,
7476
extrusionColor: ['#919191'],

demo/style.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,7 @@ footer {
309309
.is-size-8 {
310310
font-size: 0.6rem !important;
311311
}
312+
313+
.widget.right.bottom {
314+
max-width: 25vw;
315+
}

package-lock.json

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/webgl-preview.ts

Lines changed: 91 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ import {
2828
Scene,
2929
ShaderMaterial,
3030
Vector3,
31-
WebGLRenderer
31+
WebGLRenderer,
32+
MathUtils
3233
} from 'three';
3334

3435
/**
@@ -402,77 +403,114 @@ export class WebGLPreview {
402403
* Gets the current start layer (1-based index)
403404
* @returns Start layer number
404405
*/
405-
get startLayer(): number {
406+
get startLayer(): number | undefined {
406407
return this._startLayer;
407408
}
408409

409410
/**
410411
* Sets the start layer (1-based index)
411412
* @param value - Layer number to start rendering from
412413
*/
413-
set startLayer(value: number) {
414-
if (this.countLayers > 1 && value > 0) {
415-
this._startLayer = value;
416-
if (value <= this.countLayers) {
417-
const layer = this.job.layers[value - 1];
418-
this.materials.forEach((material) => {
419-
material.uniforms.clipMinY.value = layer.z;
420-
});
421-
this.updateLineClipping();
422-
} else {
423-
this.materials.forEach((material) => {
424-
material.uniforms.clipMinY.value = -Infinity;
425-
});
426-
this.updateLineClipping();
427-
}
414+
set startLayer(value: number | undefined) {
415+
if (typeof value === 'number') {
416+
this._startLayer = MathUtils.clamp(value, 1, this.countLayers);
417+
} else {
418+
this._startLayer = undefined;
428419
}
420+
421+
this.updateClippingPlanes();
429422
}
430423

431-
private updateLineClipping() {
432-
if (this._startLayer && this._endLayer) {
433-
const minZ = this.job.layers[this._startLayer - 1]?.z || 0;
434-
const maxZ = this.job.layers[this._endLayer - 1]?.z || 0;
424+
/**
425+
* Updates the clipping planes for the 3D preview based on the start and end layers.
426+
*
427+
* This method calculates the minimum and maximum Z values from the specified start and end layers.
428+
* If the start layer is not defined, the minimum Z value defaults to 0.
429+
* If the end layer is not defined, the maximum Z value defaults to Infinity.
430+
*
431+
* It then updates the clipping planes for shader materials and line clipping using these Z values.
432+
*
433+
* @private
434+
*/
435+
private updateClippingPlanes() {
436+
const minZ = !this._startLayer ? 0 : this.job.layers[this._startLayer - 1]?.z ?? 0;
435437

436-
this.scene.traverse((obj) => {
437-
if (obj instanceof LineSegments2) {
438-
const material = obj.material as LineMaterial;
439-
material.clippingPlanes = [new Plane(new Vector3(0, 1, 0), -minZ), new Plane(new Vector3(0, -1, 0), maxZ)];
440-
}
441-
});
442-
}
438+
const maxZ = !this._endLayer ? Infinity : this.job.layers[this._endLayer - 1]?.z ?? Infinity;
439+
440+
this.updateClippingPlanesForShaderMaterials(minZ, maxZ);
441+
this.updateLineClipping(minZ, maxZ);
442+
}
443+
444+
/**
445+
* Updates the clipping planes for all shader materials in the scene.
446+
* This method sets the min and max Z values for the clipping planes in the shader materials.
447+
*
448+
* @param minZ - The minimum Z value for the clipping plane.
449+
* @param maxZ - The maximum Z value for the clipping plane
450+
*/
451+
452+
private updateClippingPlanesForShaderMaterials(minZ: number, maxZ: number) {
453+
this.materials.forEach((material) => {
454+
material.uniforms.clipMinY.value = minZ;
455+
material.uniforms.clipMaxY.value = maxZ;
456+
});
457+
}
458+
459+
/**
460+
* Applies clipping planes to the specified material based on the minimum and maximum Z values.
461+
*
462+
* This method creates clipping planes for the top and bottom of the specified Z range,
463+
* then applies them to the material's clippingPlanes property.
464+
*
465+
* @param material - Shader material to apply clipping planes to
466+
* @param minZ - The minimum Z value for the clipping plane.
467+
* @param maxZ - The maximum Z value for the clipping plane.
468+
*/
469+
private applyMinMaxClippingPlanes(material: Material, minZ: number, maxZ: number) {
470+
material.clippingPlanes = [new Plane(new Vector3(0, 1, 0), -minZ), new Plane(new Vector3(0, -1, 0), maxZ)];
471+
}
472+
473+
/**
474+
* Updates the clipping planes for all `LineSegments2` objects in the scene.
475+
* This method filters the scene's children to find instances of `LineSegments2`,
476+
* then applies the clipping planes to their materials.
477+
*
478+
* @param minZ - The minimum Z value for the clipping plane.
479+
* @param maxZ - The maximum Z value for the clipping plane.
480+
*/
481+
private updateLineClipping(minZ: number, maxZ: number) {
482+
this.scene.traverse((obj) => {
483+
if (obj instanceof LineSegments2) {
484+
const material = obj.material as LineMaterial;
485+
this.applyMinMaxClippingPlanes(material, minZ, maxZ);
486+
}
487+
});
443488
}
444489

445490
/**
446491
* Gets the current end layer (1-based index)
447492
* @returns End layer number
448493
*/
449-
get endLayer(): number {
494+
get endLayer(): number | undefined {
450495
return this._endLayer;
451496
}
452497

453498
/**
454499
* Sets the end layer (1-based index)
455500
* @param value - Layer number to end rendering at
456501
*/
457-
set endLayer(value: number) {
458-
if (this.countLayers > 1 && value > 0) {
459-
this._endLayer = value;
460-
if (this._singleLayerMode === true) {
461-
this.startLayer = this._endLayer - 1;
462-
}
463-
if (value <= this.countLayers) {
464-
const layer = this.job.layers[value - 1];
465-
this.materials.forEach((material) => {
466-
material.uniforms.clipMaxY.value = layer.z;
467-
});
468-
this.updateLineClipping();
469-
} else {
470-
this.materials.forEach((material) => {
471-
material.uniforms.clipMaxY.value = Infinity;
472-
});
473-
this.updateLineClipping();
474-
}
502+
set endLayer(value: number | undefined) {
503+
if (typeof value === 'number') {
504+
this._endLayer = MathUtils.clamp(value, 1, this.countLayers);
505+
} else {
506+
this._endLayer = undefined;
507+
}
508+
509+
if (this._singleLayerMode === true) {
510+
this.startLayer = this._endLayer - 1;
475511
}
512+
513+
this.updateClippingPlanes();
476514
}
477515

478516
/**
@@ -778,15 +816,16 @@ export class WebGLPreview {
778816
* @param color - Color to use for the lines
779817
*/
780818
private renderPathsAsLines(paths: Path[], color: Color): void {
819+
const minZ = this.job.layers[this._startLayer - 1]?.z ?? 0;
820+
const maxZ = this.job.layers[this._endLayer - 1]?.z ?? Infinity;
821+
781822
const material = new LineMaterial({
782823
color: Number(color.getHex()),
783-
linewidth: this.lineWidth,
784-
clippingPlanes: [
785-
new Plane(new Vector3(0, 1, 0), this._startLayer ? -this.job.layers[this._startLayer - 1].z : 0),
786-
new Plane(new Vector3(0, -1, 0), this._endLayer ? this.job.layers[this._endLayer - 1].z : 0)
787-
]
824+
linewidth: this.lineWidth
788825
});
789826

827+
this.applyMinMaxClippingPlanes(material, minZ, maxZ);
828+
790829
const lineVertices: number[] = [];
791830

792831
// lines need to be offset.
@@ -819,12 +858,6 @@ export class WebGLPreview {
819858
const colorNumber = Number(color.getHex());
820859
const geometries: BufferGeometry[] = [];
821860

822-
// const material = new MeshLambertMaterial({
823-
// color: colorNumber,
824-
// wireframe: this._wireframe,
825-
// clippingPlanes: this.clippingPlanes
826-
// });
827-
828861
const material = createColorMaterial(colorNumber, this.ambientLight, this.directionalLight, this.brightness);
829862

830863
this.materials.push(material);
@@ -840,7 +873,6 @@ export class WebGLPreview {
840873

841874
const batchedMesh = this.createBatchMesh(geometries, material);
842875
this.disposables.push(material);
843-
// this.disposables.push(batchedMesh);
844876

845877
this.group?.add(batchedMesh);
846878
}

0 commit comments

Comments
 (0)