include ; include ; include ; include ; include ; include ; include ; include ; include ; include ; include ; /** * Kitesurf Fins mold * * * * Requirements : * - The plunger normaly should be twice the height of the part * */ /************************************************/ /* Parameters */ /************************************************/ /* [Fin Specs] */ // Height fin_height = 51; // 10 inches in mm // Width fin_width = 120; // Width at the base in mm // Length at the base in mm fin_base = 114; fin_top_withdraw = 10; fin_edge_withdraw = 20; fin_back_withraw = 20; fin_start_angle = 60; // Angle [Point 0 ] fin_sweep = 25; // Sweep Angle [Point 1] fin_edge_angle = 30; fin_edge_strength = 30; fin_counter_angle = 30; // counter angle [Point 2] fin_counter_strength = 10; // Length [Point 2] fin_width_tip = 5; // Width at the tip in mm fin_thickness = 8; // Thickness of the fin in mm fin_end_angle = 110; fin_end_strength = 30; // Back fin_back_height = 30; // Percent height fin_back_widthdraw = 20; // Percent height fin_back_angle = 20; // back angle fin_back_strength = 30; /* [Debugging] */ // Showing all layers show_debug_layers = false; // Draw master profile draw_profile = false; // Draw Fin build_fin = false; /* [Mold] */ // Mold base height mold_extra_height = 3; mold_extra_width = 3; mold_skirt_factor = 3; mold_piston_height = 10; resin_escape_diameter = 4; // Diameter for screw holes in mm merge_holes_diameter = 6; piston_depth = 5; /* [Rendering] */ // Rendering parts render_fin = false; render_mold = true; render_drill_template = false; parts = "all"; // [all, top, bottom] mold_part = "all"; // [all, top, bottom] name = "Kiteboard"; name_suffix = "fin"; version = "0.9b"; // Scaling scale_factor = 1.0; // [0.1:0.1:2] // Printable rendering printable = true; /* [Hidden] */ $fn=64; /*************/ /* Constants */ /*************/ // Define the offset value as a constant OFFSET = 0.01; CLEARING = 0.1; /************************************************/ /* Derived variable */ mold_width = fin_height +2 * mold_extra_width; mold_length = fin_width +2 * mold_extra_width; /******************/ /* Profile points */ /******************/ start = [ 0 , 0 ]; top_point = [ fin_base -5 , fin_height ]; edge_point = [ fin_base +3 , fin_height-9 ]; counter_edge_point = [ fin_base , 28 ]; tail_point = [ fin_base +5 , 10 ]; end_point = [ fin_base , 0 ]; points = flatten([ // ***************** // INITIAL POINT // ***************** bez_begin(start,60,30), // ***************** // TOP POINT // ***************** bez_tang(top_point,0,30,8), // ***************** // EDGE POINT // ***************** bez_tang(edge_point,-90,5), // ********************** // COUNTER EDGE POINT // ********************** bez_tang(counter_edge_point,-90,10), // ***************** // TAIL Point // ***************** bez_tang(tail_point,-90,3,3), // ***************** // END POINT // ***************** bez_end(end_point,65,3), ]); profile = translate_path( asCurve(points,32),-fin_base/2,0 ); /** * Build mold * */ module buildMold() { // Bottom mold if ( mold_part == "bottom" || mold_part == "all") { union() { difference() { support( profile, extraWidth = mold_extra_width, height = fin_thickness/2 + mold_extra_height, part="bottom" ); buildFin( fin_thickness ); translate([-25,fin_height/4,-9]) mirror([-1,0,0]) color("Orange") moldMark( name, name_suffix, version, font="Saira Stencil One", size=8 ); }; moldSkirt ( profile, deepness = fin_thickness, heightFactor = mold_skirt_factor, thickness = 3, part = "bottom" ); } /* difference() { case(mold_base_height,true); // Piston down(piston_depth-OFFSET) fwd(20) bottomInsert(); } */ } // Top Mold if ( mold_part == "top" || mold_part == "all") { union() { difference() { union(){ down(0) support( profile, extraWidth = mold_extra_width, height = fin_thickness/2 + mold_extra_height, part="top" ); translate([50,fin_height/4,5]) color("Orange") moldMark( name, name_suffix, version, font="Saira Stencil One", size=8 ); moldSkirt ( profile, deepness = fin_thickness, heightFactor = mold_skirt_factor, thickness = 3, part = "top" ); } buildFin( fin_thickness ); }; } } /* up(printable ? 0 : 60) fwd(printable ? fin_height+50 : 0) down(mold_base_height) mirror([0,0,printable ? 1 : 0 ]) { difference() { union() { // case case(mold_top_height,false); // Piston mirror([1,0,0]) down(mold_top_height+piston_depth-OFFSET) fwd(20) topPiston(); }; resin_escape(40); } } */ } /** * Drill template * */ module buildDrillTemplate() { spacing = 38.5; drill_depth = 15; drill_diameter = 6; template_height = 5; p1 = 20; p2 = p1-spacing; mirror([0,0,printable ? 1 : 0]) difference() { left(1) color ("Orange") cuboid([fin_width+7,15,10],rounding=3); down(OFFSET) { hull(){ left(28) cylinder(h=template_height+2*OFFSET,r=drill_diameter/2); left(55) cylinder(h=template_height+2*OFFSET,r=drill_diameter/2); } hull(){ left(12) cylinder(h=template_height+2*OFFSET,r=drill_diameter/2); left(-10) cylinder(h=template_height+2*OFFSET,r=drill_diameter/2); } hull(){ left(-27) cylinder(h=template_height+2*OFFSET,r=drill_diameter/2); left(-53) cylinder(h=template_height+2*OFFSET,r=drill_diameter/2); } } xrot(-90) buildFin(fin_thickness + 2*CLEARING ); //left(60) cylinder(h=20,r=6/2); up(template_height+OFFSET) { left(p1) cylinder(h=drill_depth+template_height,r=drill_diameter/2,orient=DOWN); left(p2) cylinder(h=drill_depth,r=drill_diameter/2,orient=DOWN); } } } module rounded_triangle(radius, height) { triangle_points = [[0, 0], [75, 0], [0, -35]]; // Equilateral triangle with side length 100 rounded_shape = round_corners( triangle_points, r=radius ); mirror([0,0,1]) linear_extrude(height = height) polygon(rounded_shape); } // ***************** // * Bottom insert * // ***************** module bottomInsert() { debug=true; layer_profile = profile; skin( [ layer_profile,expandPath(layer_profile,3) ], z=[0,piston_depth], slices=0 ) //up(debug ? 2 : 0) up(OFFSET) buildFinSide(true) ; } // ***************** // * Top piston * // ***************** module topPiston() { debug=true; layer_profile = profile; difference() { skin( [ layer_profile,expandPath(layer_profile,3) ], z=[0,piston_depth], slices=0 ); down(OFFSET) buildFinSide(false); } } /** * Build fin * */ module buildFin( thickness ) { union() { if (parts != "bottom") buildFinSide( thickness ); if (parts != "top") buildFinSide( thickness , true ); } } /** * Build fin side * * @param flip - Define it it is top or bottom fin side */ module buildFinSide(thickness,flip=false) { mirror([0,0,flip ? 1 : 0]) color(flip ? "Gray" : "LightGray") /*up(fin_thickness/4)*/ /*down(fin_thickness) */ ellipse_extrude( thickness / 2 ) polygon(profile); } module resin_escape(length) { color ("Blue") cylinder(h=length, r=resin_escape_diameter/2); } // ***************** // * Drilling * // ***************** module drilling(){ /*fwd(20)*/ color("Red") /*up(mold_piston_height+5)*/ up(-OFFSET) orient(DOWN) threaded_rod( d=merge_holes_diameter, l=drilling_length, pitch=1.5, anchor=BOTTOM, //orient=BOTTOM ); } /** * Draws a profile based on Bezier path points with optional debug visualization. * * @param points - Array of points defining the Bezier path. * @param debug - Boolean flag to enable/disable debug visualization. Defaults to true. * * This module: * - Calculates the closest point on the Bezier path to a fixed point. * - Draws the Bezier path with debug information if debug is true. * - Optionally shows spheres at specific points for debugging (currently commented out). */ module drawProfile( points,debug = true ){ pt = [100,0]; pos = bezpath_closest_point(points, pt); xy = bezpath_points(points,pos[0],pos[1]); debug_bezier(points, N=3,width=0.2); //color("red") translate(pt) sphere(r=6); //color("blue") translate(xy) sphere(r=6); } echo ("**********************"); echo ("* Configuration *"); echo ("**********************"); //echo ("Base thickness" ,str(base_tickness," mm")); module drawProfile( points,layouts,debug = true, r = 1.5, text_size = 40 ){ for (i = [ 0 : len( layouts ) - 1 ]) { debugPoint ( points[i == 0 ? 0 : i * 3], id = layouts[i][0], color = layouts[i][1], t = layouts[i][2], textSize = text_size, r = r ); } debug_bezier(points, N=3,width=1.2); } if ( draw_profile ) drawProfile( points, [ //["Start" /*, "Red", [-20,4,0]*/], ["Start", "Red", [-20,-14,0]], ["Top" , "Blue", [-5,5,0]], ["Edge" , "Brown", [10,-5,0]], ["Counter Edge","Orange", [35,-5,0]], ["Tail" , "Yellow", [8,-5,0]], ["End" , "Red", [8,-10,0]], ], text_size = 40 ); echo ("****************************"); echo ("** Build **"); echo ("****************************"); echo (str("filename :",name,"-",mold_part,"-"/*,partition,*/,version,".stl"," ")); // ***************** // * Fin Drawing * // ***************** if ( render_fin ) scale([scale_factor, scale_factor, scale_factor]) buildFin( fin_thickness ); /** * Render Mold */ if ( render_mold ) buildMold(); if ( render_drill_template ) buildDrillTemplate();