include ; // Constants // Cooordinates X=0; Y=1; Z=2; // Offset OFFSET=0.01; /** * Handle for bézier point * * @param point - Point to manage * @param angle - Angle starting as 3h00 * @param strength - Handle distance from manage point */ function handle(point,angle,strength) = [ point[0] + polar_to_xy(strength,angle)[0] , point[1] + polar_to_xy(strength,angle)[1] ]; /** * Show Debug point */ module debugPoint(point, id, color,textSize=20,r=1.5,t = [0,0,0]) { translation = is_undef(t) ? [0,0,0] : t; translate(point) { color(is_undef(color) ? "white" : color) sphere(r = r); //translate([3, 3, 0.6]) { translate([textSize/7+translation[0], textSize/7+translation[1], textSize/10+translation[2]]) { color("white") scale([0.2, 0.2, 1]) linear_extrude(height = 0.1) text(str(id), size = textSize, halign = "center", valign = "center"); } } } /** * Show vnf points */ module vnfPoints(points,textSize=1,r=0.1) { for(i = [0:1:len(points)-1]) for(j = [0:1:len(points[i])-1]) { pos = points[i][j]; label = str(i,",",j); debugPoint(pos, label, "Red", textSize=textSize, r=r); } } /** * Displays debug information for a path by visualizing its self-crossings. * * @param path - The input path to analyze for self-crossings. * * This module: * - Splits the path at points where it intersects itself. * - Renders each segment of the split path with different colors for easy identification. */ module showDebugPath( path ) { assert(is_path(path),"Path to show is not a path"); assert(is_path_simple(path),"Path is not simple"); rainbow(split_path_at_self_crossings(path)) stroke($item, closed=false, width=0.2); } /** * Rounded Triangle */ 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); } /** * Function to translate a path manually along X and Y * * @param path - Original path * @param dx - x translation * @param dy - y translation */ function translate_path(path, dx=0, dy=0) = [for (p = path) [p[0] + dx, p[1] + dy]]; /** * Convert points to bezier curve * * @param points - Points * * @return a path */ function asCurve( points,steps=128 ) = bezpath_curve(points,N=3,splinesteps=steps); /** * Print path points */ module print_path_points(path) { for (i = [0:len(path)-1]) { echo(str("\t Point ", i, ": [", path[i][0], ", ", path[i][1], "]")); } } /** * Expand path * * @param path - Original path * @param delta - distance to expand * * Keep the same number of points */ function expandPath( path, delta ) = offset( deduplicate(path), delta=delta, chamfer=false, same_length=true ) ; /** * Inches to centimeter conversion */ function inches_to_cm(inches) = inches * 2.54; /** * Calculates heights for n layers where the first layer starts at 0 and the last at fin_thickness. * * @param n - Number of layers. * @param fin_thickness - The total height to be divided. * @return An array where each element represents the height of the top of each layer. */ function layerHeights(n, fin_thickness) = let( layer_height = fin_thickness / (n - 1) ) [ for (i = [0 : n-1]) i * layer_height ]; /** * Make a skirt around a profile * * @param profile - Path ot the mold * @param moldThickness - Thickness of the mold * @param angle - Angle of the skirt starting from flat angle * @param moldDeep - Mold deep. Normally height of the skirt should be 3 times the thickness of the model * @param side - Bottom or top part of the mold * */ module skirt( profile, moldThickness = 4 , angle = 45 , moldDeep, side = "bottom", heightFactor = 3, clearance = 0.2 ) { height = heightFactor * moldDeep; echo ("height",height); deviation = opp_ang_to_adj (height,angle); // deviation = 3; if ( side == "bottom" ) { lowInt = profile; lowExt = expandPath( lowInt , moldThickness ); highInt = expandPath( lowInt , deviation ); highExt = expandPath( lowInt , deviation + moldThickness ); difference(){ skin([lowExt , highExt ], z=[0 , height ] , slices=0); skin([lowInt , highInt ], z=[-OFFSET , height+OFFSET ] , slices=0); } } else if ( side == "top" ) { lowInt = expandPath( profile , -moldThickness ); lowExt = expandPath( profile , -clearance ); highInt = expandPath( profile , +deviation-moldThickness ); highExt = expandPath( profile , +deviation -clearance ); difference(){ skin([lowExt , highExt ], z=[0 , height ] , slices=0); skin([lowInt , highInt ], z=[-OFFSET , height+OFFSET ] , slices=0); } } } if ( false ) { skirt( rect([30,30]), moldDeep=5, moldThickness = 3, side="bottom" ); up(1) skirt( rect([30,30]), moldDeep=5, moldThickness = 3, side="top", clearance=1 ); }