import uk.co.nickthecoder.foocad.smartextrusion.v1.* import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.* import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* class AntiBirdSpikes : Model { @Custom var roofRidgeSize = Vector3( 161, 20, 3.0 ) //Vector3(50,20,3.0) @Custom var chairBackSize = Vector3( 210, 10, 20 ) @Custom var chairBackGap = 4 @Custom var nailRidgeSize = Vector2( 5, 2 ) @Custom var holeEvery = 7 @Custom var angle = 90 @Custom var headDiameter = 5.0 @Custom var nailDiameter = 2.0 @Slice( brimWidth=5 ) @Piece meth withNail() : Shape3d { var halfAngleRadians = Math.PI/180 * angle/2 val triangle = PolygonBuilder().apply { val x = roofRidgeSize.y * Math.sin( halfAngleRadians ) val y = roofRidgeSize.y * Math.cos( halfAngleRadians ) moveTo( -x, 0 ) lineTo( x, 0 ) lineTo( 0, y ) }.build() val ridge = Square( nailRidgeSize.x, triangle.back + nailRidgeSize.y ).centerX() .roundAllCorners(1,1) val solid = (triangle + ridge) .extrude(roofRidgeSize.x).rotateX(90) .centerY() val remove = triangle.translateY(-roofRidgeSize.z / Math.sin( halfAngleRadians )) .extrude(roofRidgeSize.x+0.02).rotateX(90) .centerY() val hole = ( Cylinder( 10, headDiameter/2 ).topTo(remove.top) + Cylinder( 20, nailDiameter/2 ).bottomTo(remove.top+0.2) ).color("Red") val holes = hole.repeatY( roofRidgeSize.x / holeEvery, holeEvery).centerY() val attachmentHoles = Cylinder( 50, nailDiameter/2 ) .rotateY( angle/2 ) .translateX( remove.right - roofRidgeSize.z *2 -2 ) .frontTo( solid.front + 10 ) .mirrorX().also().mirrorY().also() return solid - remove - holes - attachmentHoles } var plasticRidgeSize = Vector2( 14, 5 ) var plasticRidgeSpacing = 6 meth plasticRidge( length : double, height : double ) : Shape3d { val ridgePiece = Square( plasticRidgeSize.x, height ) .roundCorners( listOf(3,2), plasticRidgeSize.x/2, 1 ) .scaleX(0.5) .extrude(1.2) .rotateX(90).centerXY() .rotateZ(90).rotateZ(90).translateZ(-2).also(2) return ridgePiece .translate( 0, plasticRidgeSpacing, plasticRidgeSize.y/2 ).also() .repeatY( length / plasticRidgeSpacing/2, plasticRidgeSpacing*2 ) .centerXY() } @Slice( brimWidth=5 ) @Piece meth plastic() : Shape3d { var halfAngleRadians = Math.PI/180 * angle/2 val triangle = PolygonBuilder().apply { val x = roofRidgeSize.y * Math.sin( halfAngleRadians ) val y = roofRidgeSize.y * Math.cos( halfAngleRadians ) moveTo( -x, 0 ) lineTo( x, 0 ) lineTo( 0, y ) }.build() val solid = triangle .extrude(roofRidgeSize.x).rotateX(90) .centerY() val remove = triangle.translateY(-roofRidgeSize.z / Math.sin( halfAngleRadians )) .extrude(roofRidgeSize.x+0.02).rotateX(90) .centerY() val ridge = plasticRidge( roofRidgeSize.x, solid.top + plasticRidgeSize.y ) val attachmentHoles = Cylinder( 50, nailDiameter/2 ) .rotateY( angle/2 ) .translateX( remove.right - roofRidgeSize.z *2 -2 ) .frontTo( solid.front + 10 ) .mirrorX().also().mirrorY().also() return solid + ridge - remove - attachmentHoles } @Piece meth chairBack() : Shape3d { val solid = Square( chairBackSize.y, chairBackSize.z ).centerX() .roundCorners(listOf(3,2),chairBackSize.y/2 ) .extrude(chairBackSize.x).rotateX(90) .centerY() val remove = Square( chairBackGap, chairBackSize.z ).centerX() .roundCorners(listOf(3,2),1,1 ) .backTo( solid.top - 4 ) .extrude( chairBackSize.x + 0.02 ).rotateX(90) .centerY() val ridge = plasticRidge( chairBackSize.x-1, solid.top+2.5 ) return solid + ridge - remove } @Piece( print="withNail" ) override fun build() : Shape3d { return withNail() } }