def __post_init__(self): if self.base is None: self.base = [18.16, 18.16] if self.top_delta is None: self.top_delta = [6, 4] if self.size is None: self.size = [1, 1] if self.skew is None: self.skew = [0, 0] if self.tilt is None: self.tilt = [0, 0] self.dims = [self.base[i] * self.size[i] for i in [0, 1]] self.top_dims = [self.dims[i] - self.top_delta[i] for i in [0, 1]] dish_kwargs = { 'dish_type': self.dish_type, 'top_dims': self.top_dims, 'key_z': self.z } if self.dish_kwargs is not None: dish_kwargs.update(self.dish_kwargs) self.dish = Dish(**dish_kwargs) # masks used to exclude anything not inside/outside the key self.inside = s.difference()(s.translate([0, 0, 50])(s.cube([100, 100, 100], center=True)), self._shape(self.thickness, self.depth)) self.outside = s.difference()(s.cube([1000, 1000, 1000], center=True), self.hull(self.thickness, self.depth, mod=2))
def create_servo_mount(): """ right now designed to fit Jacobs institute model """ width = 6.5 length = 20.0 depth = 2.3 voffset = -18.5 - 9 left_bar = solid.cube([width,length,depth], center = True) hole = solid.cylinder(r=2,h=10, center =True,segments = 100) hole1 = solid.translate([0,4,0])(hole) hole2 = solid.translate([0,-4,0])(hole) left_bar = solid.difference()(left_bar, hole1) left_bar = solid.difference()(left_bar, hole2) right_bar = solid.cube([width,length,depth],center = True) right_bar = solid.difference()(right_bar, hole1) right_bar = solid.difference()(right_bar, hole2) left_spread = -30.0 right_spread = 17.0 left_bar = solid.translate([left_spread, 0,-(depth/2 + voffset)])(left_bar) right_bar = solid.translate([right_spread, 0 , -(depth/2+voffset)])(right_bar) connector = solid.cube([(right_spread - left_spread) + width,width,depth],center=True) placed_connector = solid.translate([(left_spread+right_spread)/2,-(length/2 +width/2), -(depth/2+voffset)])(connector) total_mount = left_bar + placed_connector + right_bar pl = PolyMesh(generator= total_mount) attach_point1 = PolyMesh(generator =solid.translate([width, 0,0])(right_bar)) attach_point2 = PolyMesh(generator =solid.translate([-width, 0,0])(left_bar)) return pl, attach_point1, attach_point2
def hJoint (right, out, name): female = out # Create the outer cylinder j = solid.rotate(a = [-90, 0, 0])\ (solid.cylinder(r=outerD/2, h=width, segments = 20)) j = solid.translate(v = [0, 0, outerD/2])(j) # Create the clamp j = j + solid.cube([outerD,width,border]) j = j + solid.translate([0, 0, border+thick])\ (solid.cube([outerD,width,border])) j = j - solid.translate(v = [0, 0, border])(solid.cube([outerD,width,thick+2*t])) # Create the center hole c = solid.rotate(a = [90, 0, 0])\ (solid.cylinder(r=innerD/2,center=True, h=2*width, segments=20)) if female: if (right and out) or (not right and not out): off = -(width-6) else: off = width-6 c = solid.translate(v = [0, width/2+off, outerD/2])(c) else: c = solid.translate(v = [0, width/2, outerD/2])(c) j = solid.difference()(j, c) if not female: if (right and out) or (not right and not out): off = -border else: off = border c = solid.rotate(a = [90, 0, 0])\ (solid.cylinder(r=(outerD)/2-border,center=True, h=width, segments = 20)) c = solid.translate(v = [0, width/2+off, outerD/2])(c) cube = solid.cube([outerD, width, 2*border+thick]) c = solid.difference()(c, \ solid.translate(v = [-outerD/2.0, 0, 0])(cube)) j = solid.difference()(j, c) # Create bolt holes j = solid.difference()(j, solid.translate(v=[.65*outerD, width/2, 0]) (solid.cylinder(r=bolt/2, h = outerD, segments = 20))) j = solid.difference()(j, solid.translate(v=[.85*outerD, width/2, 0]) (solid.cylinder(r=bolt/2, h = outerD, segments = 20))) # Support bar # j = j + solid.translate(v = [-thick,0,border])(solid.cube([thick, width, thick+2*t])) # Move and rotate j = solid.translate(v=[0, 0, -border])(j) if right: j = solid.translate(v=[width, 0, 0])(solid.rotate(a=[0, 0, 90])(j)) j = PolyMesh(generator=j) j.save("heliodon/joint" + name + ".stl") return j
def __init__(self, cone, shoulder=None, thickness=None, upper_tpi=6, lower_tpi=4, offset=None, thread_height=None, thread_diameter=None): super(ThreadedBaseOutsetScrewInBase, self).__init__(cone, shoulder, thickness) shoulder = to_mm(self.shoulder) thickness = to_mm(thickness, self.thickness) radius = to_mm(cone.inner_diameter / 2.) offset = to_mm(offset, to_inch(thickness)) upper_tooth = to_mm(1. / upper_tpi * sqrt(3) / 2.) lower_tooth = to_mm(1. / lower_tpi * sqrt(3) / 2.) thread_height = to_mm(thread_height, self.length / 3) thread_diameter = to_mm(thread_diameter, cone.inner_diameter / 2.) self.cone = difference()( union()((cone.cone - cylinder(h=offset, r=3 * radius)), color("red")(self.slice(cone.cone, thread_height, offset))), up(offset - self.epsilon)(self.threaded_female_column( length=thread_height + 2 * self.epsilon, diameter=thread_diameter, threads_per_inch=upper_tpi)), cylinder(h=to_mm(0.25), r=radius - thickness)) core_radius = min(thread_diameter / 2 - thickness - upper_tooth, radius - thickness - lower_tooth) lower_thread = down(shoulder)(self.threaded_male_column( length=shoulder + offset, diameter=radius * 2 - thickness * 2., threads_per_inch=lower_tpi)) upper_thread = up(offset)(self.threaded_male_column( length=thread_height, diameter=thread_diameter, threads_per_inch=upper_tpi)) self.center_mate = upper_thread + lower_thread + cylinder( h=thickness, r=radius - thickness) - down(shoulder - thickness)( cylinder(h=shoulder + offset + thread_height, r=core_radius)) self.mate = difference()( down(shoulder)(cylinder(h=shoulder, r=radius)) + self.slice(cone.cone, offset), down(shoulder)(self.threaded_female_column( length=shoulder + offset, diameter=radius * 2 - thickness * 2, threads_per_inch=lower_tpi)), cylinder(h=thickness, r=radius - thickness))
def __init__(self, retainer_diameter, height, depth, threads_per_inch, cap_diameter, hole_diameter, cap_thickness,**kwargs): r_r = to_mm(retainer_diameter/2.) height = to_mm(height) h_r = to_mm(hole_diameter/2.) c_r = to_mm(cap_diameter/2.) c_t = to_mm(cap_thickness) threads_per_inch = threads_per_inch o_d = kwargs.get('outer_diameter') i_d = kwargs.get('inner_diameter') if 'bodytube' in kwargs: o_d = kwargs['bodytube'].outer_diameter i_d = kwargs['bodytube'].inner_diameter print i_d i_r = to_mm(i_d/2.) o_r = to_mm(o_d/2.) print retainer_diameter flange_d = to_mm(kwargs.get('flange_diameter'), safe=True) flange_t = to_mm(kwargs.get('flange_thickness'), safe=True) spine_diameter = to_mm(kwargs.get('spine_diameter'), safe=True) round_radius = to_mm(kwargs.get('round_radius',0)) if flange_d and flange_t: flange = cylinder(h=flange_t, r=flange_d/2.) else: flange = cylinder(h=height, r=o_r/2.) # HACK because this will be removed self.retainer = difference() (self.threaded_male_column(height, to_mm(retainer_diameter), threads_per_inch) + flange, cylinder(h=height, r=o_r), up(height-depth), cylinder(h=depth, r=i_r)) self.cap = difference()(cylinder(h=height,r=c_r), self.threaded_female_column(height-c_t, to_mm(retainer_diameter), threads_per_inch), cylinder(h=height, r=h_r)) if spine_diameter: no_spines = kwargs.get('spines',0) spines = [] for idx in xrange(0, no_spines): spines.append(rotate([0,0,360/no_spines*idx])(right(c_r)(cylinder(h=height-c_t-spine_diameter/2, r=spine_diameter/2)+ up(height-c_t-spine_diameter/2)(sphere(r=spine_diameter/2.))))) self.cap+=union()(*spines) self.round = rotate_extrude()(right(c_r-round_radius)(square([round_radius,round_radius])*circle(round_radius))) self.cap -= up(height-round_radius)(rotate_extrude()(right(c_r-round_radius)(square([round_radius,round_radius])))) self.cap += up(height-round_radius)(self.round)
def generalized_pot(extrude_func, prof_n1, prof_p1, pot_l, pot_w, holes=True, base_th=3, emboss_text=""): base_prof = S.difference()( # main profile S.difference()( prof_p1(), prof_n1(), ), # cut off everything above the base height S.translate([-pot_l * 5, base_th])(S.square(pot_l * 10), ), ) base = S.hull()(extrude_func(base_prof)) # bottom holes if holes: base = S.difference()( base, S.translate([0, 0, -INC])(S.linear_extrude(base_th * 2)(hole_pattern( pot_l, pot_w)), ), ) # embossed text emboss_depth = 0.4 font_size = 6 if len(emboss_text): base = S.difference()( base, # text S.translate([0, 10, base_th - emboss_depth])(S.linear_extrude( emboss_depth * 2)(S.text( EMBOSS_TEXT, halign="center", valign="center", size=font_size)), )) return S.difference()( S.union()(extrude_func(prof_p1), base), extrude_func(prof_n1), )
def test(d1, d2, c, h): disc = solid.cylinder(h=h, d=d2 + 3) cuts = fret1(d1, d2, c, h + FIDDLE * 2) t = solid.difference()(disc, solid.translate((0, 0, -FIDDLE))(cuts)) pf = pathlib.Path('scadout/test.scad') with pf.open('w') as pfo: pfo.write(solid.scad_render(t))
def model_right(): shape = sl.union()( key_holes(), connectors(), thumb(), thumb_connectors(), ) s2 = sl.union()( case_walls(), screw_insert_outers(), teensy_holder(), usb_holder(), ) s2 = sl.difference()(s2, rj9_space(), usb_holder_hole(), screw_insert_holes()) shape = sl.union()( shape, s2, rj9_holder(), wire_posts(), ) shape -= sl.translate([0, 0, -20])(sl.cube([350, 350, 40], center=True)) return shape
def __init__(self, cone, shoulder=None, thickness=None, threads_per_inch=6, thread_height=None, thread_diameter=None, screw_length=None, screw_diameter=None, screw_size=None): super(ScrewInBaseWithScrewHole, self).__init__(cone, shoulder, thickness, threads_per_inch, thread_height, thread_diameter) radius = to_mm(cone.inner_diameter / 2) shoulder = to_mm(self.shoulder) thickness = to_mm(self.thickness) screw_length = to_mm(screw_length) screw_radius = to_mm(screw_diameter / 2) if not screw_radius: "get_screw_size" self.mate = difference()( union()(self.mate, down(shoulder)(cylinder(h=screw_length, r=screw_radius + thickness / 2.)), up(min(screw_length - shoulder - thickness, -thickness))(cylinder(h=thickness, r=radius))), down(shoulder)(cylinder(h=screw_length, r=screw_radius)))
def tie_rod_plate(): def pt(x, y, r=1.): return sp.translate((x, y))(sp.circle(r=r, segments=16)) magic_1 = (40., 72.) magic_2 = (5., 60.) tie_rod_hole_1 = (-5., 102.) tie_rod_hole_2 = (-20., 102.) return sp.linear_extrude(6.)(sp.difference()( sp.union()( sp.hull()( pt(5., 0.), pt(45., 0.), pt(*magic_1), pt(*magic_2), ), sp.hull()( pt(*magic_1), pt(*magic_2), pt(*tie_rod_hole_1, r=7.), pt(*tie_rod_hole_2, r=7.), pt(-5., 85.), ), ), pt(*tie_rod_hole_1, r=tie_rod_hole_diameter / 2.), pt(*tie_rod_hole_2, r=tie_rod_hole_diameter / 2.), ))
def spacerMaker(radius, right, out, spacer, name): s = solid.rotate(a = [-90, 0, 0])\ (solid.cylinder(r=outerD/2, h=spacer, segments = 20)) s1 = solid.rotate(a = [90, 0, 0])\ (solid.cylinder(r=innerD/2, h=3*spacer, segments = 20, center=True)) s = solid.difference()(s, s1) """s1 = solid.rotate(a = [90, 0, 0])\ (solid.cylinder(r=innerD/2, h=2*border, segments = 20)) s1 = solid.translate(v = [0, spacer+2*border, 0])(s1) s = s + s1""" if not out: s = solid.translate(v = [0, -spacer, 0])(s) off = radius - width else: off = radius s = solid.translate(v = [0, off, 0])(s) if right: s = solid.rotate(a = [0, 0, -90])(s) s = PolyMesh(generator=s) s.save("heliodon/spacer" + name +".stl") return s
def pi_bplus_a_backplate(height=2.5): support_height = 3 full_length = B_LENGTH width = B_WIDTH support_z = -support_height - height / 2 plate = utils.cube_chamfered([full_length, width, height], center=True, r=3) screw_top = MachineScrew(type=ScrewType.M2_HEX, length=support_height * 2, overhang=True)() support = solid.cylinder(d=6, h=support_height, center=False, segments=32) screw_x = full_length / 2 - B_SCREW_OFF plate = solid.union()( plate, translate((screw_x, width / 2 - B_SCREW_OFF, support_z))(support), translate((screw_x, -width / 2 + B_SCREW_OFF, support_z))(support), translate((screw_x - B_SCREW_DISTANCE_X, width / 2 - B_SCREW_OFF, support_z))(support), translate((screw_x - B_SCREW_DISTANCE_X, -width / 2 + B_SCREW_OFF, support_z))(support), ) plate = solid.difference()( plate, translate((screw_x, width / 2 - B_SCREW_OFF, 0))(screw_top), translate((screw_x, -width / 2 + B_SCREW_OFF, 0))(screw_top), translate((screw_x - B_SCREW_DISTANCE_X, -width / 2 + B_SCREW_OFF, 0))(screw_top), translate((screw_x - B_SCREW_DISTANCE_X, width / 2 - B_SCREW_OFF, 0))(screw_top), ) return plate
def arc(rad:float, start_degrees:float, end_degrees:float, segments:int=None) -> OpenSCADObject: # Note: the circle that this arc is drawn from gets segments, # not the arc itself. That means a quarter-circle arc will # have segments/4 segments. bottom_half_square = back(rad)(square([3 * rad, 2 * rad], center=True)) top_half_square = forward(rad)(square([3 * rad, 2 * rad], center=True)) start_shape = circle(rad, segments=segments) if abs((end_degrees - start_degrees) % 360) <= 180: end_angle = end_degrees - 180 ret = difference()( start_shape, rotate(a=start_degrees)(bottom_half_square.copy()), rotate(a=end_angle)(bottom_half_square.copy()) ) else: ret = intersection()( start_shape, union()( rotate(a=start_degrees)(top_half_square.copy()), rotate(a=end_degrees)(bottom_half_square.copy()) ) ) return ret
def cherry_stem(rotate: float = 0, inset: float = 0, length: float = 4.4, depth: float = 4, height: float = 25, horiz_thickness: float = 1.3, vert_thickness: float = 1.3, border_width: float = 2.1, border_height: float = 1.0, border_length: float = 1.1, shape: callable = rounded_rectangle, chamfer_connector: bool = True) -> s.OpenSCADObject: """ a stem to connect keycap to a cherry mx switch refactored from key.scad in https://www.thingiverse.com/thing:2289371 """ base = shape([length + border_width, length + border_height, height], radius=.5, shape=s.sphere, center=True) cross = s.translate([0, 0, depth / 2 + inset])(s.union()( leg([length + border_width, horiz_thickness, depth]), s.rotate([0, 0, 90])(leg([length, vert_thickness, depth])))) out = s.difference()(base, cross) out = s.rotate([0, 0, rotate])(out) return out
def pi_zero_frontplate(gpio_opening=True, flex_cover=True, support_height=3.7): height = ZERO_PLATE_HEIGHT plate = _zero_plate_base(support_height=support_height, screw_offset=0, height=height) screw_obj = MachineScrew(type=ScrewType.M2_HEX, length=height + support_height - 1, clearance=-0.2) screw = rotate([180, 0, 0])(screw_obj()) plate = solid.difference()( plate, translate( (ZERO_LENGTH / 2 - ZERO_SCREW_OFF, ZERO_WIDTH / 2 - ZERO_SCREW_OFF, -height / 2 - support_height))(screw), translate((ZERO_LENGTH / 2 - ZERO_SCREW_OFF, -ZERO_WIDTH / 2 + ZERO_SCREW_OFF, -height / 2 - support_height))(screw), translate((-ZERO_LENGTH / 2 + ZERO_SCREW_OFF, -ZERO_WIDTH / 2 + ZERO_SCREW_OFF, -height / 2 - support_height))(screw), translate((-ZERO_LENGTH / 2 + ZERO_SCREW_OFF, ZERO_WIDTH / 2 - ZERO_SCREW_OFF, -height / 2 - support_height))(screw), ) if flex_cover: flex_cover = utils.cube_chamfered([ZERO_LENGTH, 13, ZERO_PLATE_HEIGHT], center=True, r=3) plate += translate((10, 0, 0))(flex_cover) if gpio_opening: gpio_opening = translate( (0, ZERO_WIDTH / 2 - GPIO_WIDTH / 2 - GPIO_OFFSET, 0))(solid.cube([GPIO_LENGTH, GPIO_WIDTH, height], center=True)) plate -= gpio_opening return plate
def make_key(self): """ assemble the key """ key = s.difference()(self._shape(0, 0), s.translate([0, 0, -.5])(self._shape( self.thickness, self.depth))) #key = s.union()(key, ) if self.connector is not None: key = s.union()(key, self.stem()) if self.text is not None: key = s.difference()(key, self.inset_text()) return key
def create_ommatidum(outer_sphere_radius, inner_sphere_radius, ommatidum_radius): """Create an hexagonal based pyramid.""" # Outer shell outer_shell = [tuple(np.round(sph2cart(ommatidum_radius, az, 0), 2)) for az in np.arange(0, 359, 60)] outer_points = [[0, 0, 0]] + [[outer_sphere_radius, x, y] for x, y, _ in outer_shell] # Inner shell inner_shell = [tuple(np.round( sph2cart(ommatidum_radius - thickness, az, 0), 2)) for az in np.arange(0, 359, 60)] inner_points = [[0, 0, 0]] + [[outer_sphere_radius, x, y] for x, y, _ in inner_shell] # Define Faces faces = [ [0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 5], [0, 5, 6], [0, 6, 1], [1, 2, 3, 4, 5, 6]] # Create ommatidum ommatidum = solid.difference()( solid.hull()(solid.polyhedron(outer_points, faces)), solid.hull()(solid.polyhedron(inner_points, faces)), solid.sphere(inner_sphere_radius) ) return ommatidum
def pi_zero_backplate(): zero_plate = _zero_plate_base(support_height=ZERO_SUPPORT_HEIGHT_TOP, screw_offset=-.5) camera_plate = utils.cube_chamfered([ADAPTER_SIDE,ADAPTER_SIDE,ZERO_PLATE_HEIGHT],center=True,r=3) camera_plate = camera_plate + zero_plate screw_obj = MachineScrew(type=ScrewType.M2_HEX,length=ZERO_PLATE_HEIGHT*2,clearance=0) screw_bottom = rotate([180,0,0])(screw_obj()) screw_top = MachineScrew(type=ScrewType.M2_HEX,length=ZERO_PLATE_HEIGHT*2,overhang=True)() camera_plate = solid.difference()( camera_plate, # Upper plate mount screws translate((ADAPTER_SIDE/2-ADAPTER_HOLE_TO_SIDE,ADAPTER_SIDE/2-ADAPTER_HOLE_TO_SIDE,-ZERO_PLATE_HEIGHT/2))(screw_bottom), translate((-ADAPTER_SIDE/2+ADAPTER_HOLE_TO_SIDE,ADAPTER_SIDE/2-ADAPTER_HOLE_TO_SIDE,-ZERO_PLATE_HEIGHT/2))(screw_bottom), translate((ADAPTER_SIDE/2-ADAPTER_HOLE_TO_SIDE,-ADAPTER_SIDE/2+ADAPTER_HOLE_TO_SIDE,-ZERO_PLATE_HEIGHT/2))(screw_bottom), translate((-ADAPTER_SIDE/2+ADAPTER_HOLE_TO_SIDE,-ADAPTER_SIDE/2+ADAPTER_HOLE_TO_SIDE,-ZERO_PLATE_HEIGHT/2))(screw_bottom), # Lens ring mount screws translate((0,CS_LENS_RING_NUT_OFFSET,-ZERO_PLATE_HEIGHT/2))(screw_bottom), translate((0,-CS_LENS_RING_NUT_OFFSET,-ZERO_PLATE_HEIGHT/2))(screw_bottom), # Pi mount screws translate((ZERO_LENGTH/2-ZERO_SCREW_OFF,ZERO_WIDTH/2-ZERO_SCREW_OFF,-.5))(screw_top), translate((ZERO_LENGTH/2-ZERO_SCREW_OFF,-ZERO_WIDTH/2+ZERO_SCREW_OFF,-.5))(screw_top), translate((-ZERO_LENGTH/2+ZERO_SCREW_OFF,-ZERO_WIDTH/2+ZERO_SCREW_OFF,-.5))(screw_top), translate((-ZERO_LENGTH/2+ZERO_SCREW_OFF,ZERO_WIDTH/2-ZERO_SCREW_OFF,-.5))(screw_top), # flex cable opening translate((ZERO_LENGTH/2-ZERO_PLATE_TO_EDGE/2,0,0))(cube([ZERO_PLATE_TO_EDGE,13,ZERO_PLATE_HEIGHT],center=True)) ) # flex cable cover flex_cover = utils.cube_chamfered([ZERO_LENGTH,13,ZERO_PLATE_HEIGHT-1.5],center=True,r=3) camera_plate += translate((10,0,0.75))(flex_cover) camera_plate -= translate((ADAPTER_SIDE/2-1.5,0,0))(cube([3,13,ZERO_PLATE_HEIGHT],center=True)) camera_plate = rotate((180,0,0))(camera_plate) return camera_plate
def nut(screw_type: str = 'm3') -> OpenSCADObject: dims = screw_dimensions[screw_type.lower()] outer_rad = dims['nut_outer_diam'] inner_rad = dims['screw_outer_diam'] ret = difference()(circle(outer_rad, segments=6), circle(inner_rad)) return ret
def flat_cap(x, y, z, r, recess=0): """flat_cap x, y, z cap dimensions r (int): radius for rounded edges recess: decimal, percent of cap to remove """ cap = rounded_cube(x, y, z, r) if recess > 0: if recess < 1: insert = rounded_cube(x * recess, y * recess, (z * recess) - 0.5, r, center=True) cap = s.difference()(cap, s.translate([0, 0, z - (z * recess) + 0.5])(insert)) else: raise ValueError(f"recess should be a decimal between 0 and 1") out = s.union()(cap, mx_post(6, z / 2)) return out
def pi_bplus_a_frontplate(height=2.5, gpio_opening=True): support_height = 12 # This is basically only the aray from screw to screw, we only care about that area length = B_SCREW_DISTANCE_X + 2 * B_SCREW_OFF width = B_WIDTH support_z = -support_height - height / 2 plate = utils.cube_chamfered([length, width, height], center=True, r=3) screw_obj = MachineScrew(type=ScrewType.M2_HEX, length=support_height, clearance=-0.2) screw_bottom = rotate([180, 0, 0])(screw_obj()) support = solid.cylinder(d=6, h=support_height, center=False, segments=32) plate = solid.union()( plate, translate((length / 2 - B_SCREW_OFF, width / 2 - B_SCREW_OFF, support_z))(support), translate((length / 2 - B_SCREW_OFF, -width / 2 + B_SCREW_OFF, support_z))(support), translate((-length / 2 + B_SCREW_OFF, -width / 2 + B_SCREW_OFF, support_z))(support), translate((-length / 2 + B_SCREW_OFF, width / 2 - B_SCREW_OFF, support_z))(support), ) plate = solid.difference()( plate, # Upper plate mount screws translate((ADAPTER_SIDE / 2 - ADAPTER_HOLE_TO_SIDE, ADAPTER_SIDE / 2 - ADAPTER_HOLE_TO_SIDE, -height / 2)) (screw_bottom), translate((-ADAPTER_SIDE / 2 + ADAPTER_HOLE_TO_SIDE, ADAPTER_SIDE / 2 - ADAPTER_HOLE_TO_SIDE, -height / 2))(screw_bottom), translate((ADAPTER_SIDE / 2 - ADAPTER_HOLE_TO_SIDE, -ADAPTER_SIDE / 2 + ADAPTER_HOLE_TO_SIDE, -height / 2))(screw_bottom), translate((-ADAPTER_SIDE / 2 + ADAPTER_HOLE_TO_SIDE, -ADAPTER_SIDE / 2 + ADAPTER_HOLE_TO_SIDE, -height / 2))(screw_bottom), # Lens ring mount screws translate((CS_LENS_RING_NUT_OFFSET, 0, -height / 2))(screw_bottom), translate((-CS_LENS_RING_NUT_OFFSET, 0, -height / 2))(screw_bottom), # Pi mount screws translate((length / 2 - B_SCREW_OFF, width / 2 - B_SCREW_OFF, -support_height - screw_obj.head_h))(screw_bottom), translate((length / 2 - B_SCREW_OFF, -width / 2 + B_SCREW_OFF, -support_height - screw_obj.head_h))(screw_bottom), translate((-length / 2 + B_SCREW_OFF, -width / 2 + B_SCREW_OFF, -support_height - screw_obj.head_h))(screw_bottom), translate((-length / 2 + B_SCREW_OFF, width / 2 - B_SCREW_OFF, -support_height - screw_obj.head_h))(screw_bottom), # flex cable opening translate((0, ADAPTER_SIDE / 2 - 2.5, 0))(cube([16.5, 2, height], center=True))) if gpio_opening: gpio_opening = translate( (0.3, -(width / 2 - GPIO_WIDTH / 2 - 0.8), 0))(solid.cube([GPIO_LENGTH, GPIO_WIDTH, height], center=True)) plate -= gpio_opening return plate
def rj9_holder(): shape = sl.union()( sl.translate([0, 2, 0])(sl.cube([10.78, 9, 18.38], center=True)), sl.translate([0, 0, 5])(sl.cube([10.78, 13, 5], center=True)), ) shape = sl.difference()(rj9_cube(), shape) shape = sl.translate(rj9_position)(shape) return shape
def test_body_pure_container(self) -> None: parent = component.Component() composer_1 = MockEmbodiedComponent(2.0) composer_2 = MockEmbodiedComponent(3.0) parent.compose(solid.union(), composer_1, make_children=False) parent.compose(solid.difference(), composer_2, make_children=False) self.assertTrue( utils.compare_flattened_openscad_children( parent.body, solid.difference()(solid.union()(solid.cube(size=2.0)), solid.cube(size=3.0)), ), msg= "The innermost composition on pure containers must first be evaluted on its own", )
def volume(angle_multiplier): return sp.difference()( sp.union()( sp.rotate((0., angle_multiplier * 90., 180.))(axle()), sp.rotate((0., angle_multiplier * camber, 0.))(bearing_housing()), ), sp.rotate((0., angle_multiplier * camber, 0.))(kingpin_hole()), )
def _shape(self, thickness: float = 1, depth: float = 1): """ for want of a better name. the shape with bowl, paramaterized to thickness """ d = self.dish.dish d = s.translate([*self.skew, 0])(s.rotate([*self.tilt, 0])(d)) if self.dish.inverted: key = s.difference()(s.union()(self.hull(thickness, depth), d), outside) else: key = s.difference()(self.hull(thickness, depth), d) return key
def ell_main(): return S.translate([0, 0, pot_w])( S.difference()( S.scale([1, pot_lw_ratio, 1])(S.sphere(pot_w)), # cut out inside S.scale([s2, pot_lw_ratio * s2, s2])(S.sphere(pot_w)), S.translate([-rectl / 2, -rectl / 2, -pot_w + 50])(S.cube([rectl, rectl, rectl])), ))
def make_lamp_scad(filename, bright_stars, stick_figures, radius, thickness): """Use bright stars and input arguements to create the scad lamp.""" # Create a main shell to be inscribed on shell = solid.difference()(solid.sphere(r=radius), solid.sphere(r=radius - thickness / 2), sutil.down(radius)(solid.cube(2 * radius, center=True))) # Add stick figures i_shell = make_stick_figures(shell, stick_figures, radius, 0.5) # i_shell = shell # Add another layer of shell (without inscription) c_shell = solid.difference()(solid.sphere(r=radius - thickness / 2), solid.sphere(r=radius - thickness), sutil.down(radius)(solid.cube(2 * radius, center=True))) # Add stars to both the i_shell and c_shell i_stars = solid.difference() i_stars.add(i_shell) for _, az, alt, _, rad in bright_stars: i_stars.add( solid.rotate(a=[0, -1 * (90 - alt), az])(solid.cylinder(rad, h=radius))) c_stars = solid.difference() c_stars.add(c_shell) for _, az, alt, _, rad in bright_stars: c_stars.add( solid.rotate(a=[0, -1 * (90 - alt), az])(solid.cylinder(rad, h=radius))) complete = solid.union()(i_stars, c_stars) # Render to file solid.scad_render_to_file(i_stars, filename + '-inscription' + '.scad', file_header='$fn = %s;' % SEGMENTS) solid.scad_render_to_file(c_stars, filename + '-stars' + '.scad', file_header='$fn = %s;' % SEGMENTS) solid.scad_render_to_file(complete, filename + '-complete' + '.scad', file_header='$fn = %s;' % SEGMENTS)
def arc(radius): a = solid.difference()( solid.cylinder(r=radius, h=thick, segments=48), solid.cylinder(r=radius-width, h=thick, segments=48)) a = solid.intersection()(a, solid.cube([radius, radius, thick])) a = solid.difference()(a, solid.translate(v=[.75*outerD, radius-width/2, 0]) (solid.cylinder(r=bolt/2, h=2*thick, segments=20, center=True))) a = solid.difference()(a, solid.translate(v=[radius-width/2, .75*outerD, width/2.0]) (solid.cylinder(r=bolt/2, h=2*thick, segments=20, center=True))) c = solid.translate(v=[radius-width/2, 0, 0])\ (solid.cylinder(r=bolt/2, h=2*thick, segments=20, center=True)) # Add bolt holes for fastening the two sheets of acryllic together for step in range(1,3): a = solid.difference()(a, solid.rotate(a = [0,0, step * 30])(c)) PolyLine(generator = solid.projection()(a)).save("heliodon/a" + str(radius) + ".dxf") return PolyMesh(generator=a)
def mx_post(h, z_offset): """post to connect to mx switch """ out = s.difference()( s.translate([0, 0, (7 / 2) - z_offset])(rounded_cube(7.25, 5.25, h, 1.5)), s.translate([0, 0, 5])(cross(h=h)), ) out = s.union()(out, s.cube([7.5, 5.5, 2], center=True)) return out
def bearing(bearing_type: str = '624') -> OpenSCADObject: dims = bearing_dimensions[bearing_type.lower()] outerR = dims['outer_d'] / 2 innerR = dims['inner_d'] / 2 thickness = dims['thickness'] bearing = cylinder(outerR, thickness) bearing.add_param('$fs', 1) hole = cylinder(innerR, thickness + 2) hole.add_param('$fs', 1) bearing = difference()(bearing, translate([0, 0, -1])(hole)) return bearing
def make_stick_figures(shell, stick_figures, radius, breadth): """Adds stick figure inscription onto the shell.""" # Create inscribed shell i_shell = solid.difference() i_shell.add(shell) # Add individual polygons to the inscribed shell for cname in sorted(stick_figures.keys()): for a1, e1, a2, e2 in stick_figures[cname]: i_shell.add( solid.linear_extrude(height=radius)(solid.polygon( make_sticks(a1, e1, a2, e2, radius, breadth)))) return i_shell
def stem(self, rotate: float = 0): """ create stem """ if self.connector == "mx": connector = cherry_stem(rotate=rotate) else: raise NotImplementedError() return s.difference()(connector, self.inside)
def create_servo_mount(): """ right now designed to fit Jacobs institute model """ width = 6.5 length = 20.0 depth = 2.3 voffset = -18.5 - 9 left_bar = solid.cube([width, length, depth], center=True) hole = solid.cylinder(r=2, h=10, center=True, segments=100) hole1 = solid.translate([0, 4, 0])(hole) hole2 = solid.translate([0, -4, 0])(hole) left_bar = solid.difference()(left_bar, hole1) left_bar = solid.difference()(left_bar, hole2) right_bar = solid.cube([width, length, depth], center=True) right_bar = solid.difference()(right_bar, hole1) right_bar = solid.difference()(right_bar, hole2) left_spread = -30.0 right_spread = 17.0 left_bar = solid.translate([left_spread, 0, -(depth / 2 + voffset)])(left_bar) right_bar = solid.translate([right_spread, 0, -(depth / 2 + voffset)])(right_bar) connector = solid.cube( [(right_spread - left_spread) + width, width, depth], center=True) placed_connector = solid.translate([(left_spread + right_spread) / 2, -(length / 2 + width / 2), -(depth / 2 + voffset)])(connector) total_mount = left_bar + placed_connector + right_bar pl = PolyMesh(generator=total_mount) attach_point1 = PolyMesh( generator=solid.translate([width, 0, 0])(right_bar)) attach_point2 = PolyMesh( generator=solid.translate([-width, 0, 0])(left_bar)) return pl, attach_point1, attach_point2
def hollow_out(obj: OpenSCADObject, shell_thickness: int) -> OpenSCADObject: """Hollow SCAD object. Python implementation of dotSCAD's hollow_out module. Implemented due to solidpython having issues pickling imported scad modules. Args: obj: scad object to hollow. shell_thickness: shell thickness. """ return solid.difference()(obj, solid.offset(delta=-shell_thickness)(obj))
def plane_make_part3D(self, thepart, pconfig): self.generate_part3D(thepart, pconfig) # for cutout in thepart.cutouts3D: # for c in cutout: # thepart.border3D = thepart.border3D - c subparts = [] for sp in thepart.parts: if hasattr(sp, 'subpart') and sp.subpart: self.make_part3D(sp, pconfig) if hasattr(sp, 'border3D'): subparts.append(sp.border3D) if len(subparts): if hasattr(thepart, 'border3D'): thepart.border3D=solid.union()(thepart.border3D,*subparts) else: thepart.border3D=solid.union()(*subparts) if not hasattr(thepart, 'border3D'): return False cutouts = [thepart.border3D] for cutout in thepart.cutouts3D: for c in cutout: cutouts.append(c) thepart.border3D = solid.difference()(*cutouts) # 3D transformations can only be applied to parts, so we can just go up the tree p = thepart c=0 print p while(p and type(p) is not Plane):# and (c==0 or not p.renderable() )): p.rotations_to_3D() if hasattr(p, 'transform') and p.transform is not None and p.transform is not False: print p.transform if 'matrix3D' in p.transform: if type(p.transform['matrix3D'][0]) is list or type(p.transform['matrix3D'][0]) is Vec: thepart.border3D=solid.translate([-p.transform['matrix3D'][0][0], -p.transform['matrix3D'][0][1],-p.transform['matrix3D'][0][2]])(thepart.border3D) thepart.border3D=solid.multmatrix(m=p.transform['matrix3D'][1])(thepart.border3D) thepart.border3D=solid.translate([p.transform['matrix3D'][0][0], p.transform['matrix3D'][0][1],p.transform['matrix3D'][0][2]])(thepart.border3D) else: thepart.border3D=solid.multmatrix(m=p.transform['matrix3D'])(thepart.border3D) if 'rotate3D' in p.transform: if type(p.transform['rotate3D'][0]) is list or type(p.transform['rotate3D'][0]) is Vec: thepart.border3D=solid.translate([-p.transform['rotate3D'][0][0], -p.transform['rotate3D'][0][1],-p.transform['rotate3D'][0][2]])(thepart.border3D) thepart.border3D=solid.rotate([p.transform['rotate3D'][1][0], p.transform['rotate3D'][1][1],p.transform['rotate3D'][1][2] ])(thepart.border3D) thepart.border3D=solid.translate([p.transform['rotate3D'][0][0], p.transform['rotate3D'][0][1],p.transform['rotate3D'][0][2]])(thepart.border3D) else: thepart.border3D=solid.rotate([p.transform['rotate3D'][0], p.transform['rotate3D'][1],p.transform['rotate3D'][2] ])(thepart.border3D) if 'translate3D' in p.transform: thepart.border3D=solid.translate([p.transform['translate3D'][0], p.transform['translate3D'][1],p.transform['translate3D'][2] ])(thepart.border3D) c+=1 p=p.parent