@@ -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