# -*- coding: utf-8 -*- """ Created on Thu Apr 27 12:03:30 2023 @author: Edward Middleton-Smith Procedural OpenSCAD Generation https://github.com/taxpon/openpyscad/blob/develop/openpyscad/base.py """ # CLASSES # ATTRIBUTE DECLARATION # METHODS # FUNCTION # ARGUMENTS # ARGUMENT VALIDATION # ATTRIBUTE + VARIABLE INSTANTIATION # METHODS # RETURNS # NORMAL METHODS # FUNCTION # ARGUMENTS # ARGUMENT VALIDATION # VARIABLE INSTANTIATION # METHODS # RETURNS import openpyscad as ops import argument_validation as av def bool_2_str(mybool): # FUNCTION # Convert boolean to lowercase string for openscad # ARGUMENTS # bool mybool # ARGUMENT VALIDATION if not av.val_bool(mybool): return f'Error converting boolean to string.\nInput: {mybool}' # RETURNS return str(mybool).lower() def neg_fillet(L, r, centre = True, q = 25): # FUNCTION # return negative-space fillet object for use with boolean operation # ARGUMENTS # int L - cylinder height # double r - fillet radius # bool centre - is fillet centred vertically? # int q - quality / discretisation - number of points per edge # ARGUMENT VALIDATION if not (av.val_double(L, 0) and av.val_double(r, 0) and av.val_bool(centre) and av.val_int(q, 0)): return None # VARIABLE INSTANTIATION fillet = ops.Difference() # METHODS fillet.append(ops.Cube([r, r, L], center = "false", _fn = q)) fillet.append(ops.Cylinder(L, r, center = "false")) fillet.mirror([1, 1, 0]) fillet.translate([r, r, -L/2 if centre else 0]) # RETURNS return fillet def base_fillet_cube(a, b, c, f, q, centre = True): # FUNCTION # return openpyscad object of cube with base edges and corners filleted with radius f # ARGUMENTS # double a, b, c - cube dimensions x, y, z # double f - fillet radius # int q - quality / discretisation - number of points per edge # bool centre - is base-filleted cube centred? # ARGUMENT VALIDATION if not (av.val_double(a, 0) and av.val_double(a, 0) and av.val_double(a, 0)): return None if not (av.val_double(f, 0, min(a, b, c)) and av.val_int(q, 1) and av.val_bool(centre)): return None # VARIABLE INSTANTIATION my_dif = ops.Difference() # METHODS my_dif.append(ops.Cube([a, b, c], center = "true", _fn = q).translate([0, 0, c/2])) my_dif.append(neg_fillet(a, f, True, q).rotate([90, 0, 0])) my_dif.append(neg_fillet(a, f, True, q).rotate([90, 0, 0]).mirror([0, 1, 0]).translate([f + a, 0, 0])) my_dif.append(neg_fillet(a, f, True, q).rotate([0, 90, 0])) my_dif.append(neg_fillet(a, f, True, q).rotate([0, 90, 0]).mirror([1, 0, 0]).translate([0, f + b, 0])) # RETURNS return my_dif.translate([0 if centre else a/2, 0 if centre else b/2, -c/2 if centre else 0]) def triprism(a, L, centre = True): # FUNCTION # Triangular-based prism # ARGUMENTS # double a - triangle side-length # double L - depth in Z-direction # bool centre - is triprism centred by volume? # ARGUMENT VALIDATION if not (av.val_double(a, 0) and av.val_double(L, 0) and av.val_bool(centre)): return None # RETURNS return ops.Polygon([[0,0], [0, a], [a, 0]]).linear_extrude(L, center = bool_2_str(centre)).translate([-a/2 if centre else 0, -a/3 if centre else 0, 0]) def gen_openscad_colours(): return [ # openscad_colours = [ "Lavender", "Thistle", "Plum", "Violet", "Orchid", "Fuchsia", "Magenta", "MediumOrchid", "MediumPurple", "BlueViolet", "DarkViolet", "DarkOrchid", "DarkMagenta", "Purple", "Indigo", "DarkSlateBlue", "SlateBlue", "MediumSlateBlue", "Pink", "LightPink", "HotPink", "DeepPink", "MediumVioletRed", "PaleVioletRed", "Aqua", "Cyan", "LightCyan", "PaleTurquoise", "Aquamarine", "Turquoise", "MediumTurquoise", "DarkTurquoise", "CadetBlue", "SteelBlue", "LightSteelBlue", "PowderBlue", "LightBlue", "SkyBlue", "LightSkyBlue", "DeepSkyBlue", "DodgerBlue", "CornflowerBlue", "RoyalBlue", "Blue", "MediumBlue", "DarkBlue", "Navy", "MidnightBlue", "IndianRed", "LightCoral", "Salmon", "DarkSalmon", "LightSalmon", "Red", "Crimson", "FireBrick", "DarkRed", "GreenYellow", "Chartreuse", "LawnGreen", "Lime", "LimeGreen", "PaleGreen", "LightGreen", "MediumSpringGreen", "SpringGreen", "MediumSeaGreen", "SeaGreen", "ForestGreen", "Green", "DarkGreen", "YellowGreen", "OliveDrab", "Olive", "DarkOliveGreen", "MediumAquamarine", "DarkSeaGreen", "LightSeaGreen", "DarkCyan", "Teal", "LightSalmon", "Coral", "Tomato", "OrangeRed", "DarkOrange", "Orange", "Gold", "Yellow", "LightYellow", "LemonChiffon", "LightGoldenrodYellow", "PapayaWhip", "Moccasin", "PeachPuff", "PaleGoldenrod", "Khaki", "DarkKhaki", "Cornsilk", "BlanchedAlmond", "Bisque", "NavajoWhite", "Wheat", "BurlyWood", "Tan", "RosyBrown", "SandyBrown", "Goldenrod", "DarkGoldenrod", "Peru", "Chocolate", "SaddleBrown", "Sienna", "Brown", "Maroon", "White", "Snow", "Honeydew", "MintCream", "Azure", "AliceBlue", "GhostWhite", "WhiteSmoke", "Seashell", "Beige", "OldLace", "FloralWhite", "Ivory", "AntiqueWhite", "Linen", "LavenderBlush", "MistyRose", "Gainsboro", "LightGrey", "Silver", "DarkGray", "Gray", "DimGray", "LightSlateGray", "SlateGray", "DarkSlateGray", "Black" ]