include "cleaver-outline.scl"; set demand_eval true; commentOutCode << show( profile1, curve3, curve4, circle1, circle2, circle3, circle4 ); show( curve5, point18, point25 ); >> # Dimensions. << CleaverLength: 12; CleaverPoint: pt( point1.X, point23.Y ); OutlineLength: CleaverPoint.X - point9.X; ModelScale: CleaverLength / OutlineLength; BladeThickness: .1 / ModelScale; BladeMaxWidth: 3.5 / ModelScale; HandleThickness: .7 / ModelScale; HandleEdgeWidth: .1 / ModelScale; # Width of the round edge. HandleEdgeOffset: .03 / ModelScale; # Amount the metal sticks out. HandleEdgeRound: .04 / ModelScale; # Tiny round up to the flat faces. >> << # Separate the handle and blade portions of the top edge of the cleaver. RefCrv: kRefineCrv( curve1 )$; size( curve1.ctlpoly ); size( RefCrv.ctlpoly ); TopEdge: extrude( RefCrv, pt( 0, 0, -BladeThickness ), pt( 0, 0, BladeThickness ) )$; TopPt1UV: nodalMap( TopEdge, point25 ); TopPt1UV.x; TopPt1 : srfeval(TopEdge, TopPt1UV.x, 0 ); TopPt2UV: nodalMap( TopEdge, point31 ); TopPt2 : srfeval(TopEdge, TopPt2UV.x, 0 ); # Extrude normalized the 0...8 parametrization to 0...1 . TopEdge.ukv[ size( TopEdge.ukv )-1 ]; ParamFactor: curve1.kv[ size( curve1.kv )-1 ]; BladeOutline: profile( regionFromCrv( curve1, 0, ParamFactor*TopPt2UV.x ), point32, point33, curve3 )$; BladeEdgeSrf: extrude( reverseCrv( BladeOutline ), pt( 0, 0, -BladeThickness ), pt( 0, 0, BladeThickness ) )$; BladeHoleSrf: extrude( objTransform( UnitCircle, sg( circle4.radius), tXYZ( circle4.center.X, circle4.center.Y, 0) ), pt( 0, 0, -BladeThickness ), pt( 0, 0, BladeThickness ) )$; BladeEdge: shell( BladeEdgeSrf, BladeHoleSrf )$; BladeArc: arcEndDirTanLine( Origin, vecAtAngle( 83 ), lineVertical( BladeThickness/2 ) ); BladeRightProfile: profile( BladeArc, pt( BladeThickness/2, BladeMaxWidth ) ); BladeLeftProfile: reverseCrv( reflect( BladeRightProfile, YAxis) ); BladeProfile: profile( BladeLeftProfile, BladeRightProfile ); BladeAxis: profile( reverseCrv( curve4 ), ptOffset( point21, vec( -4 / ModelScale, 0 ) ) ); BladePlate: sweepConstantWidth( BladeAxis, BladeProfile, 1, vec( 0, 0, 1 ), false ); Blade: combineShells( BladePlate, BladeEdge, "*" ); >> # Handle outline is closed. Start in middle of a straight segment for sweep. << HandleTopEdge: regionFromCrv( curve1, ParamFactor*TopPt1UV.x, ParamFactor ); HandleTopEdgeEnd: HandleTopEdge.ctlpoly[0]; HandleOutlineEnd: ptInterp( HandleTopEdgeEnd, point18, .5 ); HandleOutline: profile( HandleOutlineEnd, HandleTopEdge, curve2, point18, HandleOutlineEnd )$; # Construct a rounded edge curve for the handle. HandleEdgeLine1: lineHorizontal( HandleThickness/2 ); HandleEdgeLine2: lineVertical( -HandleEdgeOffset ); HandleEdgeLine3: lineHorizontal( -HandleThickness/2 ); HandleEdgePt1: pt( -( HandleEdgeOffset+HandleEdgeWidth ), HandleThickness/2 ); HandleEdgePt2: pt( -HandleEdgeOffset, 0 ); HandleEdgeCirc1: circleThru3Pts( HandleEdgePt1, HandleEdgePt2, reflect( HandleEdgePt1, XAxis ) ); HandleEdgeCrv: outlineCrv( array( HandleEdgeLine1, fillet( HandleEdgeRound ), HandleEdgeCirc1, fillet( HandleEdgeRound ), reverseObj( HandleEdgeLine3 ) ), true ); Handle: sweepConstantWidth( HandleOutline, reverseObj( HandleEdgeCrv ), 1, vec( 1, 0, 0 ) , true )$; # Three rivets to hold the handle to the blade. RivetLength: HandleThickness + 2 * HandleEdgeOffset; RivetTopVec: vec( 0, 0, RivetLength / 2 ); RivetBotVec: vec( 0, 0, -RivetLength ); # Rivets should be done with rightCirCylinder, but the radii don't transform! procedure my_rtCirCylinder( EndPt, CtrVec, Rad ) extrude( objTransform( unitCircle, sG( Rad ) ), EndPt, ptOffset( EndPt, CtrVec ), true )$; Rivet1: my_rtCirCylinder( ptOffset( circle1.center, RivetTopVec ), RivetBotVec, circle1.radius ); Rivet2: my_rtCirCylinder( ptOffset( ptInterp( circle1.center, circle3.center, .5 ), RivetTopVec ), RivetBotVec, circle2.radius ); Rivet3: my_rtCirCylinder( ptOffset( circle3.center, RivetTopVec ), RivetBotVec, circle3.radius ); >> commentOutCode show( Blade, Handle, Rivet1, Rivet2, Rivet3 ); << setColor( Handle, color( 20, 20, 20 ) ); setSq( Handle, "Plastic" ); setColor( Blade, "Silver" ); setSq( Blade, "SilverSurface" ); setColor( Rivet1, "Bronze" ); setSq( Rivet1, "BrassSurface" ); setColor( Rivet2, "Bronze" ); setSq( Rivet2, "BrassSurface" ); setColor( Rivet3, "Bronze" ); setSq( Rivet3, "BrassSurface" ); >> pwd(); commentOutCode dumpA1File( array( Blade, Handle, Rivet1, Rivet2, Rivet3 ), "cleaver.a1" ); Cleaver: Group( Blade, Handle, Rivet1, Rivet2, Rivet3 )$;