class PhoneCover : Model { @Custom var size = Vector3( 78, 178, 10 ) @Custom var caseThickness = 1.2 @Custom var margin = 1.5 @Custom var cornerSize = 30 @Custom var cornerThickness = 1.2 @Custom var radius = 9f fun cornerProfile( cornerSize : double, cornerThickness : double ) : Shape2d { return Square( cornerSize ).roundCorner(2, radius ) - Square( cornerSize - cornerThickness ).roundCorner(2, radius-cornerThickness/2 ) } var cornerBackThickness = 0.8 var extraThickness = 6 @Piece fun corner() : Shape3d { val edge = ExtrusionBuilder().apply { crossSection( cornerProfile( cornerSize, cornerBackThickness ) ) forward( cornerBackThickness + size.z - 2 ) crossSection() forward( 1 ) crossSection( cornerProfile( cornerSize - 0.5, cornerThickness + 0.2 ) ) forward( 1 ) crossSection( cornerProfile( cornerSize - 1.5, cornerThickness + 0.6 ) ) }.build() val backProfile = Square( cornerSize ).roundCorner(2, radius ) - Circle( cornerSize * 0.8 ) val back = backProfile.extrude( cornerBackThickness ) return edge + back } @Piece fun case() : Shape3d { val z = size.z + cornerBackThickness * 2 + caseThickness*2 + extraThickness val x = (size.x + margin*2) * 2 + z val y = size.y + margin * 2 val flat = Square(x, y) .center() .roundAllCorners( radius + margin ) .extrude( caseThickness ) val grove = ExtrusionBuilder().apply { crossSection( Square(0.6 + caseThickness*2, size.y * 1.1).center() ) forward( caseThickness ) crossSection( Square(0.6, size.y * 1.1).center() ) }.build() val grooves = grove.translateX( z ).also() .centerXY() val hingeProfile = (Circle( caseThickness ).sides(30) intersection Square( caseThickness*2 ).centerX()) .scaleX(2) val hinge = hingeProfile.extrude( y ) .rotateX(90) .centerY() val hinges = hinge.translateX( z ).also() .centerXY() .bottomTo( flat.top ) return flat - grooves + hinges } override fun build() : Shape3d { val corner : Shape3d = corner() val corners = corner.rightTo( size.x / 2 ).mirrorX().also() .backTo( size.y / 2 ).mirrorY().also() val case : Shape3d = case() .rightTo( size.x / 2 + margin ) .centerY() .mirrorZ() return case + corners.color("Green") } }