class ChopTest : Model { override fun build() : Shape3d { val sq = Square( 300, 400 ).rotate(45 ) return Chop.chopZ( sq.extrude( 500 ), sq ) } } @Data class Chop( val shape : Shape3d, val orientation : int, val position : float, val crossSection : Shape2d, val bumpSpacing : float, val bumpSize : Vector2, val clearance : float ) : Lazy3d() { func chopZ( shape : Shape3d, crossSection : Shape2d ) : Chop { return Chop( shape, 2, shape.middle.z, crossSection, 100, Vector2( 16, 10 ), 0.5 ) } func chopZ( shape : Shape3d ) : Chop { val crossSection = Square( shape.size.x, shape.size.y ) .frontTo( shape.front ) .leftTo( shape.left ) return chopZ( shape, crossSection ) } meth bump() = Cylinder( bumpSize.x / 2, bumpSize.y, bumpSize.y*0.5 ) meth hole() = Cylinder( bumpSize.x / 2 + clearance, bumpSize.y + clearance, bumpSize.y*0.5 + clearance ) meth bumpsOrHoles( bumpOrHole : Shape3d ) : Shape3d { val within = crossSection.offset( - bumpSize.x ) var result : Shape3d = Union3d() val bumpsX = crossSection.size.x ~/ bumpSpacing val bumpsY = crossSection.size.y ~/ bumpSpacing val left = crossSection.middle.x - (bumpsX-1) * bumpSpacing/2 val front = crossSection.middle.y - (bumpsY-1) * bumpSpacing/2 println( "Bumps : $bumpsX" ) for (ix in 0 until bumpsX ) { val x = left + ix * bumpSpacing for (iy in 0 until bumpsY ) { val y = front + iy * bumpSpacing val pos = Vector2( x, y ) if (within.contains(pos)) { println( "Yes $pos" ) result = result + bumpOrHole.translate( x, y, 0 ) } else { println( "No $pos" ) } } } return result.translateZ( position ) } meth bumps() : Shape3d { return bumpsOrHoles( bump() ) } meth holes() : Shape3d { return bumpsOrHoles( hole() ) } meth partA() : Shape3d { val bumps = bumps() val bounding = shape.boundingCube().topTo( position-clearance/2 ) val part = shape.intersection( bounding ) + bumps return part } meth partB() : Shape3d { val holes = holes() val bounding = shape.boundingCube().bottomTo( position+clearance/2 ) val part = shape.intersection( bounding ) - holes return part.translateZ( -position ) } override fun build() : Shape3d { val a = partA() val b = partB() return a + b.leftTo( a.right + 10 ) } }