def rounded_rectangle(dims: typing.List[float], radius: float = 2, segments: int = 32, center: bool = True, shape: callable = s.circle): """ rounded rectangle (rectangular prism in the 3d case). made with the hull around circles (spheres) placed at the corners. """ if len(dims) == 2: dims = dims + [0] x, y, z = dims coordinates = [[radius, radius], [x - radius, radius], [x - radius, y - radius], [radius, y - radius]] corner = shape(r=radius, segments=segments) out = s.hull()(*[s.translate(c + [0])(corner) for c in coordinates]) if center: out = s.translate([-x / 2, -y / 2, 0])(out) if z > 0: out = s.hull()(out, s.translate([0, 0, z - 2 * radius])(out)) out = s.translate([0, 0, radius])(out) return out
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 sa_cap(Usize=1): # MODIFIED TO NOT HAVE THE ROTATION. NEEDS ROTATION DURING ASSEMBLY sa_length = 18.25 bw2 = Usize * sa_length / 2 bl2 = sa_length / 2 m = 0 pw2 = 6 * Usize + 1 pl2 = 6 if Usize == 1: m = 17 / 2 k1 = sl.polygon([[bw2, bl2], [bw2, -bl2], [-bw2, -bl2], [-bw2, bl2]]) k1 = sl.linear_extrude(height=0.1, twist=0, convexity=0, center=True)(k1) k1 = sl.translate([0, 0, 0.05])(k1) k2 = sl.polygon([[pw2, pl2], [pw2, -pl2], [-pw2, -pl2], [-pw2, pl2]]) k2 = sl.linear_extrude(height=0.1, twist=0, convexity=0, center=True)(k2) k2 = sl.translate([0, 0, 12.0])(k2) if m > 0: m1 = sl.polygon([[m, m], [m, -m], [-m, -m], [-m, m]]) m1 = sl.linear_extrude(height=0.1, twist=0, convexity=0, center=True)(m1) m1 = sl.translate([0, 0, 6.0])(m1) key_cap = sl.hull()(k1, k2, m1) else: key_cap = sl.hull()(k1, k2) # key_cap = sl.translate([0, 0, 5 + plate_thickness])(key_cap) key_cap = sl.color([220 / 255, 163 / 255, 163 / 255, 1])(key_cap) return key_cap
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 thumb_connection(): # clunky bit on the top left thumb connection (normal connectors don't work well) shape = bottom_hull([ left_key_place( sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1), left_key_place( sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1), thumb_ml_place(sl.translate(wall_locate2(-0.3, 1))(web_post_tr())), thumb_ml_place(sl.translate(wall_locate3(-0.3, 1))(web_post_tr())), ]) shape += sl.hull()([ left_key_place( sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1), left_key_place( sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1), thumb_ml_place(sl.translate(wall_locate2(-0.3, 1))(web_post_tr())), thumb_ml_place(sl.translate(wall_locate3(-0.3, 1))(web_post_tr())), thumb_tl_place(thumb_post_tl()), ]) shape += sl.hull()([ left_key_place(web_post(), cornerrow, -1), left_key_place( sl.translate(wall_locate1(-1, 0))(web_post()), cornerrow, -1), left_key_place( sl.translate(wall_locate2(-1, 0))(web_post()), cornerrow, -1), left_key_place( sl.translate(wall_locate3(-1, 0))(web_post()), cornerrow, -1), thumb_tl_place(thumb_post_tl()), ]) shape += sl.hull()([ left_key_place(web_post(), cornerrow, -1), left_key_place( sl.translate(wall_locate1(-1, 0))(web_post()), cornerrow, -1), key_place(web_post_bl(), 0, cornerrow), key_place( sl.translate(wall_locate1(-1, 0))(web_post_bl()), 0, cornerrow), thumb_tl_place(thumb_post_tl()), ]) shape += sl.hull()([ thumb_ml_place(web_post_tr()), thumb_ml_place(sl.translate(wall_locate1(-0.3, 1))(web_post_tr())), thumb_ml_place(sl.translate(wall_locate2(-0.3, 1))(web_post_tr())), thumb_ml_place(sl.translate(wall_locate3(-0.3, 1))(web_post_tr())), thumb_tl_place(thumb_post_tl()), ]) return shape
def single_plate(cylinder_segments=100): top_wall = sl.cube([keyswitch_width + 3, 1.5, plate_thickness], center=True) top_wall = sl.translate( (0, (1.5 / 2) + (keyswitch_height / 2), plate_thickness / 2))(top_wall) left_wall = sl.cube([1.5, keyswitch_height + 3, plate_thickness], center=True) left_wall = sl.translate( ((1.5 / 2) + (keyswitch_width / 2), 0, plate_thickness / 2))(left_wall) side_nub = sl.cylinder(1, 2.75, segments=cylinder_segments, center=True) side_nub = sl.rotate(rad2deg(pi / 2), [1, 0, 0])(side_nub) side_nub = sl.translate((keyswitch_width / 2, 0, 1))(side_nub) nub_cube = sl.cube([1.5, 2.75, plate_thickness], center=True) nub_cube = sl.translate( ((1.5 / 2) + (keyswitch_width / 2), 0, plate_thickness / 2))(nub_cube) side_nub = sl.hull()(side_nub, nub_cube) plate_half1 = top_wall + left_wall + side_nub plate_half2 = plate_half1 plate_half2 = sl.mirror([0, 1, 0])(plate_half2) plate_half2 = sl.mirror([1, 0, 0])(plate_half2) plate = plate_half1 + plate_half2 if plate_file is not None: socket = sl.import_(plate_file) socket = sl.translate([0, 0, plate_offset])(socket) plate = sl.union()(plate, socket) return plate
def volume(): width = light.mount_width + 20. body = sp.hull()( spu.up(1.)(sp.cube((width, thickness, 2.), center=True)), spu.up(height)( sp.rotate((0., 90., 0.))( sp.cylinder(d=thickness, h=width, center=True) ) ), ) cutout = spu.up(height)( sp.rotate((0., 90., 0.))( sp.union()( sp.cylinder( d=thickness + 1., h=light.mount_width + 1., center=True ), sp.cylinder(d=light.mount_diameter, h=width + 1., center=True), ) ) ) mounting_holes = sp.linear_extrude(15.)(holes()) return body - cutout - mounting_holes()
def nameplate(id): #create the plate bottom = cube([xlen, ylen, 0.01], center=True) top = cube([xlen-zlen-zlen, ylen-zlen, 0.1], center=True) top = translate([0, zlen/2, zlen-0.1])(top) plate = hull()([bottom, top]) # define the text id_str = name_str.replace('$ID',f'{id:03d}') msg = text(id_str, size=text_size, font=text_font, spacing = text_spacing, halign='center', valign='center') msg = linear_extrude(zlen+1)(msg) msg = resize([text_width,text_height,0])(msg) msg = translate([0, zlen/2, -0.5])(msg) #add text to the plate plate = plate - msg #generate output files scad_file = Path.cwd() / 'scad_files' / f'plate_{id:03d}.scad' if scad_file.parent.exists() is False: scad_file.parent.mkdir() scad_render_to_file(plate, str(scad_file)) stl_file = Path.cwd() / 'stl_files' / f'plate_{id:03d}.stl' if stl_file.parent.exists() is False: stl_file.parent.mkdir() subprocess.run(['openscad', '-o', str(stl_file), str(scad_file)])
def rationalize_segment(seg, joints, name, state={}): p1 = seg.p1 p2 = seg.p2 buff = 6 thickness = 3 p1x = p1.x.evalf(subs=state) p1y = p1.y.evalf(subs=state) p2x = p2.x.evalf(subs=state) p2y = p2.y.evalf(subs=state) c = solid.cylinder(r=buff, h=thickness, segments=100) c1 = solid.translate([p1x, p1y, 0])(c) c2 = solid.translate([p2x, p2y, 0])(c) link = solid.hull()(c1, c2) OT = (0, 0, 0) OQ = (0, 0, 1, 0) OP = (OT, OQ) pm = PolyMesh(generator=link) for joint in joints: pm = clevis_neg(pm, joint) if "conn" in name: #this is a connector joint pm = add_servo_mount(pm) layers = Layer(pm, name="lol", color='green') link_body = Body(pose=OP, elts=[layers], joints=joints, name=name) return link_body
def handle_bar(points): return sp.union()([ sp.hull()( sp.translate(points[i])(sp.sphere(d=hand_grip_diameter, segments=32)), sp.translate(points[i + 1])(sp.sphere(d=hand_grip_diameter, segments=32)), ) for i in range(len(points) - 1) ])
def volume(): body = spu.up(2.)(sp.cylinder(d=diameter, h=thickness)) mount = spu.up(4.)(spu.back(diameter / 2.)(sp.rotate( (-60., 0., 0.))(sp.rotate((0., 90., 0.))(sp.hull()(place_at_centres( (20., 0.), sp.cylinder(d=mount_thickness, h=mount_width, center=True) )) - spu.right(10.)(sp.cylinder( d=mount_diameter, h=mount_width + 1., center=True)))))) return body + mount
def rounded(width, height): w = width - RAD * 2 h = height - RAD * 2 return hull()( translate([RAD, RAD, 0])(cube([w, h, THICK])), translate([RAD, RAD, 0])(cylinder(r=RAD, h=THICK)), translate([RAD + w, RAD, 0])(cylinder(r=RAD, h=THICK)), translate([RAD, RAD + h, 0])(cylinder(r=RAD, h=THICK)), translate([RAD + w, RAD + h, 0])(cylinder(r=RAD, h=THICK)), )
def col_key_connector(self, row1, row2, col): verts = [] key1 = self.key_array[row1][col] key2 = self.key_array[row2][col] verts.append(key1.vertices_shape(idxs=[0, 1])) verts.append(key2.vertices_shape(idxs=[2, 3])) if col < self.ncols-1: verts.append(self.key_array[row1][col+1].vertices_shape(idxs=[1])) verts.append(self.key_array[row2][col+1].vertices_shape(idxs=[3])) return sl.hull()(*verts)
def connector(self, distance_from_surface): return optional(self.has_connector)( up(distance_from_surface - 1.25)( forward(self.plug_offset)( rotate((90, 0, 0))( hull()( left(4 - 1.25)(cylinder_outer(2.5 / 2, 6)), right(4 - 1.25)(cylinder_outer(2.5 / 2, 6)), ) ) ) + forward(self.plug_offset + self.plug_length)( rotate((90, 0, 0))( hull()( left(4 - 1.25)(cylinder_outer(8.5 / 2, self.plug_length)), right(4 - 1.25)(cylinder_outer(8.5 / 2, self.plug_length)), ) ) ) ) )
def projection(): d = motor.body_diameter + 10. outer = sp.hull()( sp.square((plate_width, d), center=True), spu.back(lower_extent - 5.)(sp.square((plate_width, 10.), center=True)), ) mounting_holes = spu.back(mount_holes_offset)(place_at_centres( (mount_holes_distance, 0.), mounting_slot())) return outer - motor.mountable_face() - mounting_holes
def bottom_hull(p, height=0.001): shape = None for item in p: proj = sl.projection()(p) t_shape = sl.linear_extrude(height=height, twist=0, convexity=0, center=True)( proj ) t_shape = sl.translate([0, 0, height / 2 - 10])(t_shape) if shape is None: shape = t_shape shape = sl.hull()(p, shape, t_shape) return shape
def __init__(self, cone, offset, radius): super(DerivativeNoseCone, self).__init__(length=cone.length, thickness=cone.thickness, outer_diameter=cone.outer_diameter, inner_diameter=cone.inner_diameter) offset = to_mm(offset) radius = to_mm(radius) self.cone = cone.cone - up(offset + radius)(sphere(r=radius)) if self.thickness: thickness = to_mm(self.thickness) self.cone = self.cone + hull()(cone.cone) * up(offset + radius)( sphere(r=radius + thickness) - sphere(r=radius))
def _inner_rq(x, y, z, r, center, edges): xr = x / 2 - r yr = y / 2 - r a = solid.hull()(( (cy(r, z) if 0 in edges else q(2 * r, 2 * r, z)).left(xr).forward(yr), (cy(r, z) if 1 in edges else q(2 * r, 2 * r, z)).left(-xr).forward(yr), (cy(r, z) if 2 in edges else q(2 * r, 2 * r, z)).left(xr).forward(-yr), (cy(r, z) if 3 in edges else q(2 * r, 2 * r, z)).left(-xr).forward(-yr), )) if not center: a = a.right(x / 2).back(y / 2).up(z / 2) return a
def projection(): """ This is an approximation of the body. It matches the maximum outer dimensions but does not accurately reflect the profile. """ body = sp.union()( sp.circle(d=45., segments=32), sp.hull()( sp.circle(d=30., segments=32), place_mounting_holes(sp.circle(d=15., segments=32)), ), ) return body - sp.circle(d=bore, segments=32) - mounting_holes()
def hull(self, thickness: float, depth: float = 1, height_slices: int = 2, mod=1): """ basic shape without dish """ slices = [ self.slice(i / height_slices, thickness, depth, mod=mod) for i in range(height_slices + 1) ] return s.hull()(*[slices])
def init_keyhole(self): top_wall = sl.cube([self.width + 3, 1.5, self.thickness], center=True) top_wall = sl.translate( (0, (1.5 / 2) + (self.height / 2), self.thickness / 2) )(top_wall) left_wall = sl.cube([1.5, self.height + 3, self.thickness], center=True) left_wall = sl.translate( ((1.5 / 2) + (self.width / 2), 0, self.thickness / 2) )(left_wall) side_nub = sl.cylinder(1, 2.75, segments=self.cylinder_segments, center=True) side_nub = sl.rotate(rad2deg(pi / 2), [1, 0, 0])(side_nub) side_nub = sl.translate((self.width / 2, 0, 1))(side_nub) nub_cube = sl.cube([1.5, 2.75, self.thickness], center=True) nub_cube = sl.translate( ((1.5 / 2) + (self.width / 2), 0, self.thickness / 2) )(nub_cube) side_nub = sl.hull()(side_nub, nub_cube) plate_half1 = top_wall + left_wall + side_nub plate_half2 = plate_half1 plate_half2 = sl.mirror([0, 1, 0])(plate_half2) plate_half2 = sl.mirror([1, 0, 0])(plate_half2) plate = plate_half1 + plate_half2 if self.hotswap_socket is not None: self.hotswap_socket = sl.translate([0, 0, self.thickness])( self.hotswap_socket) plate = sl.union()(plate, self.hotswap_socket) if self.cap_height is not None: cap = sl.cube([self.width, self.width, self.cap_height], center=True) self.cap = sl.translate([0, 0, ( self.thickness + self.switch_height + self.thickness)])( cap) if self.side == "left": plate = sl.mirror([-1, 0, 0])(plate) return plate
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 __init__(self): # stretched oval body = hull()(circle(radius) + right(phone_width)(circle(radius))) # used to hold the layers together body = body - self.screw_holes() # set self self.body = body # proper X-axis alignment self.body = right(radius)(body) # cut possible hole if self.hole: self.body -= self.hole.make_hole()
def along_ellipse(x1, x2, fn_a, d2profile): # Place an object at a certain point along an elliiptical path def place(x1, x2, aa, e, obj): return S.translate([x2 * math.sin(aa), x1 * math.cos(aa), 0])(S.rotate( util.rad2deg(-aa + math.pi / 2))(S.rotate([90, 0, 0])( S.linear_extrude(e)(obj)))) obj = S.union() # small thickness of the 2d profile e = 0.05 for a in range(0, fn_a): aa = a * 2 * math.pi / fn_a obj += S.hull()(place(x1, x2, aa, e, d2profile), place(x1, x2, aa + 2 * math.pi / fn_a, e, d2profile)) return obj
def rationalize_segment(seg,joints,name, state= {}, is_locked = False): p1 = seg p2 = seg if type(seg) != Point: p1 = seg.p1 p2 = seg.p2 buff = 6 thickness = 3 p1x = p1.x.evalf(subs=state) p1y = p1.y.evalf(subs=state) p2x = p2.x.evalf(subs=state) p2y = p2.y.evalf(subs=state) c = solid.cylinder(r= buff, h =thickness, segments =100) c1 = solid.translate([p1x, p1y, 0])(c) c2 = solid.translate([p2x, p2y, 0])(c) link = solid.hull()(c1,c2) OT = (0, 0, 0) OQ = (0, 0, 1, 0) OP = (OT, OQ) pm = PolyMesh(generator=link) for joint in joints: if is_locked: pm = square_neg(pm,joint) else: pm = clevis_neg(pm,joint) if "conn" in name: #this is a connector joint pm = add_servo_mount(pm) layers=Layer( pm, name="lol", color='green' ) link_body = Body(pose=OP, elts=[layers], joints=joints, name=name) return link_body
def wall_brace(place1, dx1, dy1, post1, place2, dx2, dy2, post2): hulls = [] hulls.append(place1(post1)) hulls.append(place1(sl.translate(wall_locate1(dx1, dy1))(post1))) hulls.append(place1(sl.translate(wall_locate2(dx1, dy1))(post1))) hulls.append(place1(sl.translate(wall_locate3(dx1, dy1))(post1))) hulls.append(place2(post2)) hulls.append(place2(sl.translate(wall_locate1(dx2, dy2))(post2))) hulls.append(place2(sl.translate(wall_locate2(dx2, dy2))(post2))) hulls.append(place2(sl.translate(wall_locate3(dx2, dy2))(post2))) shape1 = sl.hull()(*hulls) hulls = [] hulls.append(place1(sl.translate(wall_locate2(dx1, dy1))(post1))) hulls.append(place1(sl.translate(wall_locate3(dx1, dy1))(post1))) hulls.append(place2(sl.translate(wall_locate2(dx2, dy2))(post2))) hulls.append(place2(sl.translate(wall_locate3(dx2, dy2))(post2))) shape2 = bottom_hull(hulls) return shape1 + shape2
def single_plate(cylinder_segments=100): top_wall = sl.cube([keyswitch_width + 3, 1.5, plate_thickness], center=True) top_wall = sl.translate( [0, (1.5 / 2) + (keyswitch_height / 2), plate_thickness / 2])(top_wall) left_wall = sl.cube([1.5, keyswitch_height + 3, plate_thickness], center=True) left_wall = sl.translate([(1.5 / 2) + (keyswitch_width / 2), 0, plate_thickness / 2])(left_wall) side_nub = sl.cylinder(1, 2.75, segments=cylinder_segments, center=True) side_nub = sl.rotate(rad2deg(pi / 2), [1, 0, 0])(side_nub) side_nub = sl.translate([keyswitch_width / 2, 0, 1])(side_nub) nub_cube = sl.cube([1.5, 2.75, plate_thickness], center=True) nub_cube = sl.translate([(1.5 / 2) + (keyswitch_width / 2), 0, plate_thickness / 2])(nub_cube) side_nub = sl.hull()(side_nub, nub_cube) plate_half1 = top_wall + left_wall + side_nub plate_half2 = plate_half1 plate_half2 = sl.mirror([0, 1, 0])(plate_half2) plate_half2 = sl.mirror([1, 0, 0])(plate_half2) plate = plate_half1 + plate_half2 if hot_swap: hot_swap_socket = sl.import_( path.join(r"..", "geometry", r"hot_swap_plate.stl")) hot_swap_socket = sl.translate([0, 0, plate_thickness - 5.25 ])(hot_swap_socket) plate = sl.union()(plate, hot_swap_socket) return plate
def cube_chamfered(size: solid.ScadSize = None, center: bool = None, r: int = None) -> solid.OpenSCADObject: # segments = 64 - fillet # segments = 6 - chamfered segments = 32 if r == 0: return solid.cube(size, center) if len(size) > 2: h = size[2] l = size[0] else: h = size[0] l = size[0] w = size[1] c1 = right(r)(forward(r)(solid.cylinder(center=center, r=r, h=h, segments=segments))) c2 = right(l - r)(forward(r)(solid.cylinder(center=center, r=r, h=h, segments=segments))) c3 = right(r)(forward(w - r)(solid.cylinder(center=center, r=r, h=h, segments=segments))) c4 = right(l - r)(forward(w - r)(solid.cylinder(center=center, r=r, h=h, segments=segments))) cube = solid.hull().add([c1, c2, c3, c4]) if center: cube = solid.translate((-size[0] / 2, -size[1] / 2, 0))(cube) return cube
def __init__(self, **kwargs): if 'name' not in kwargs.keys(): kwargs['name'] = 'klann' if 'elts' not in kwargs.keys(): #create b1, j1, c1 = create_klann_part(1,1, "1") b2, j2, c2 = create_klann_part(-1, 1, "2") # + np.pi conn1 = b1.pop() conn2 = b2.pop() conn = combine_connectors(conn1,conn2) # print(conn.joints) A1,_,B1 = j1 A1 = voffset_joint(A1,-3, "1A") B1 = voffset_joint(B1,0,"1B") A2,_,B2 = j2 A2 = voffset_joint(A2, -9, "2A") B2 = voffset_joint(B2, -6, "2B") link_bodies = b1+b2 +[conn] link_conns = c1+c2 # #create servo mount that connects to shaft connector mt, m_attach1, m_attach2 = create_servo_mount() # #add support for A,B mount_thickness= 3 # shaft coupler layer_thickness = 3 ##create the attacher thing, with joints A1_bar, a1_attach = create_support_bar(A1,mount_thickness) B1_bar, b1_attach = create_support_bar(B1,mount_thickness) m_attach1_gen = m_attach1.get_generator() a1_gen = a1_attach.get_generator() b1_gen = b1_attach.get_generator() a1_join = solid.hull()(m_attach1_gen, a1_gen) b1_join = solid.hull()(m_attach1_gen, b1_gen) cronenberg1 = PolyMesh(generator= solid.union()(a1_join,b1_join)) # A2_bar, a2_attach = create_support_bar(A2,mount_thickness) # B2_bar, b2_attach = create_support_bar(B2,mount_thickness) # # m_attach2_gen = m_attach2.get_generator() # a2_gen = a2_attach.get_generator() # b2_gen = b2_attach.get_generator() # # a2_join = solid.hull()(m_attach2_gen, a2_gen) # b2_join = solid.hull()(m_attach2_gen, b2_gen) # cronenberg2 = PolyMesh(generator= solid.union()(a2_join,b2_join)) aparatus = cronenberg1 + A1_bar + B1_bar + mt #+ cronenberg2 + A2_bar + B2_bar shaft_conn = create_shaft_connector() OT = (0, 0, 0) OQ = (0, 0, 1, 0) OP = (OT, OQ) pos_O, neg_O = joint_from_point(Point(0,0), "1O", 1) torso = Body( pose = OP, joints = [pos_O, A2, B2, A1, B1], elts=[Layer( aparatus, name='lol', color='yellow', )], name='torso' ) coupler = Body( pose = OP, joints = [pos_O], elts = [Layer(shaft_conn, name='lol', color = 'blue')], name = 'coupler' ) kwargs['elts'] = [torso]+ link_bodies#[torso] , conn coupler, #kwargs['children'] = [torso] if 'connections' not in kwargs.keys(): kwargs['connections'] = [ #((0, 'conn', '1O'),(0,'coupler','1O')), #((0, 'torso', '1O'),(0, 'conn','1O')), #((0, 'torso', '2O'),(0, 'conn','2O')), ((0, 'torso', '1A'),(0, '1b3', '1A')), ((0, 'torso', '1B'),(0, '1b2', '1B')), ((0, 'torso', '2A'),(0, '2b3', '2A')), ((0, 'torso', '2B'),(0, '2b2', '2B')) ] + link_conns super(DoubleKlannLinkage, self).__init__(**kwargs)
def slit(): return rotate(a=back_bend_degrees)( forward(y_offset)( union()(hull()( circle(r=radius) + forward(height)(circle(r=radius))))))
def test_linearizer(): O,A,B,C,D,E,F,M,b1,b2,b3,b4,conn = create_klann_geometry(1,1) b1_dict = {b1: [M,D,C]} b2_dict = {b2: [B,E]} b3_dict = {b3: [A,C]} b4_dict = {b4:[E,D,F]} conn_dict = {conn: [M,O]} O2,A2,B2,C2,D2,E2,F2,M2,b12,b22,b32,b42,conn2 = create_klann_geometry(-1,1) b1_dict2 = {b12: [M2,D2,C2]} b2_dict2 = {b22: [B2,E2]} b3_dict2 = {b32: [A2,C2]} b4_dict2 = {b42:[E2,D2,F2]} O3,A3,B3,C3,D3,E3,F3,M3,b13,b23,b33,b43,conn3 = create_klann_geometry(1,1 + np.pi) b1_dict3 = {b13: [M3,D3,C3]} b2_dict3 = {b23: [B3,E3]} b3_dict3 = {b33: [A3,C3]} b4_dict3 = {b43:[E3,D3,F3]} O4,A4,B4,C4,D4,E4,F4,M4,b14,b24,b34,b44,conn4 = create_klann_geometry(-1,1 + np.pi) b1_dict4 = {b14: [M4,D4,C4]} b2_dict4 = {b24: [B4,E4]} b3_dict4 = {b34: [A4,C4]} b4_dict4 = {b44:[E4,D4,F4]} conn_dict4 = {conn4:[M4,O4]} # seg_paths = simulate_linkage_path(1,1) # seg_paths2 = simulate_linkage_path(-1,1) # seg_paths3 = simulate_linkage_path(1,1+np.pi) # seg_paths4 = simulate_linkage_path(-1,1+np.pi) # seg_paths.update(seg_paths2) # seg_paths.update(seg_paths3) # seg_paths.update(seg_paths4) # print("generated Geometry") # # seg_confs = seg_conflicts(seg_paths) # print("calculated conflicts") # # #add gear conflicts and joints gear = Segment(M,M3) cap = Segment(M3,M3) # seg_confs[b1]+=[gear] # seg_confs[b12]+=[gear] # seg_confs[b13]+=[gear] # seg_confs[b14]+=[gear] # seg_confs[gear] = [b1,b12,b13,b14] gear_dict = {gear:[M,M3]} cap_dict = {cap:[M3]} # seg_dicts = [b1_dict, b2_dict, b3_dict, b4_dict] seg_dicts2 = [b1_dict2, b2_dict2, b3_dict2, b4_dict2] seg_dicts3 = [b1_dict3, b2_dict3, b3_dict3, b4_dict3] seg_dicts4 = [b1_dict4, b2_dict4, b3_dict4, b4_dict4] all_dicts = [gear_dict, conn_dict, cap_dict] + seg_dicts + seg_dicts2 + seg_dicts3 + seg_dicts4 # print("added gear") # # neighbor_dicts = {list(seg.keys())[0]: [list(s.keys())[0] for s in all_dicts if shares_joint(s,seg)] # for seg in all_dicts} print("created neighbors") #optimal = create_layer_assignment(neighbor_dicts,seg_confs) optimal = {} optimal[gear] = 0 optimal[b1] = 1 optimal[b2] = 1 optimal[b3] = 2 optimal[b4] = 2 optimal[b12] = 2 optimal[b22] = 2 optimal[b32] = 1 optimal[b42] = 1 optimal[b13] = -2 optimal[b23] = -2 optimal[b33] = -1 optimal[b43] = -1 optimal[b14] = -1 optimal[b24] = -1 optimal[b34] = -2 optimal[b44] = -2 optimal[conn] = 3 optimal[cap] = -3 lock_joints = [conn,conn2,conn3,conn4,gear, cap] anchor_pts = [A,B,O,A4,B4] ratts, conns, seg_names, joint_names = rationalize_linkage(all_dicts, optimal, lock_joints, anchor_pts) pos_O, neg_O = joint_from_point(Point(0,0), "1O", 1) #Create torso mt, m_attach1, m_attach2 = create_servo_mount() # #add support for A,B mount_thickness= 3 # shaft coupler layer_thickness = 3 ##create the attacher thing, with joints A1_bar, a1_attach = create_support_bar(joint_from_point(A,"A",3)[0],mount_thickness) B1_bar, b1_attach = create_support_bar(joint_from_point(B,"B",2)[0],mount_thickness) m_attach1_gen = m_attach1.get_generator() a1_gen = a1_attach.get_generator() b1_gen = b1_attach.get_generator() a1_join = solid.hull()(m_attach1_gen, a1_gen) b1_join = solid.hull()(m_attach1_gen, b1_gen) cronenberg1 = PolyMesh(generator= solid.union()(a1_join,b1_join)) A2_bar, a2_attach = create_support_bar(joint_from_point(A2,"A2",2)[0],mount_thickness) B2_bar, b2_attach = create_support_bar(joint_from_point(B2,"B2",3)[0],mount_thickness) m_attach2_gen = m_attach2.get_generator() a2_gen = a2_attach.get_generator() b2_gen = b2_attach.get_generator() a2_join = solid.hull()(m_attach2_gen, a2_gen) b2_join = solid.hull()(m_attach2_gen, b2_gen) cronenberg2 = PolyMesh(generator= solid.union()(a2_join,b2_join)) aparatus = cronenberg1 + A1_bar + B1_bar + mt + cronenberg2 + A2_bar + B2_bar aparatus.save("torso.stl") OT = (0, 0, 0) OQ = Z_JOINT_POSE[1] OP = (OT, OQ) torso = Body( pose = OP, joints = [pos_O], elts=[Layer( aparatus, name='lol', color='yellow', )], name='torso' ) ratts += [torso] conns += [((0,'torso',"1O"),(0,seg_names[conn], joint_names[O]))] #print ratts #print conns return ratts, conns
def arm(a, b): return sp.hull()( sp.translate(a)(sp.circle(d=20., segments=32)), sp.translate(b)(sp.circle(d=25., segments=32)), )
def __init__(self, **kwargs): if 'name' not in kwargs.keys(): kwargs['name'] = 'klann' if 'elts' not in kwargs.keys(): #create O, A,B, C, D, E, F,M, b1,b2,b3,b4,conn = create_klann_geometry() pos_A, neg_A = joint_from_point(A,"A",1) pos_B, neg_B = joint_from_point(B,"B",1) pos_C, neg_C = joint_from_point(C,"C",1) pos_D, neg_D = joint_from_point(D,"D",1) pos_E, neg_E = joint_from_point(E,"E",1) pos_F, neg_F = joint_from_point(F,"F",1) pos_M, neg_M = joint_from_point(M,"M",1) pos_O, neg_O = joint_from_point(O,"O",1) b1_body = rationalize_segment(b1,[neg_M, neg_C, neg_D],"b1") b2_body = rationalize_segment(b2,[neg_B, neg_E],"b2") b3_body = rationalize_segment(b3, [neg_A,pos_C],"b3") b4_body = rationalize_segment(b4, [pos_E,pos_D], "b4") conn = rationalize_segment(conn, [neg_O, pos_M], "conn" ) # #create servo mount that connects to shaft connector b, j, c = create_klann_part(1,1, "1") A,_,B = j mt, m_attach, _ = create_servo_mount() # #add support for A,B mount_thickness= 3 # shaft coupler layer_thickness = 3 #O, A,B, C, D, E, F,M, b1,b2,b3,b4,conn = create_klann_geometry() ##create the attacher thing, with joints A_bar, a_attach = create_support_bar(A,mount_thickness) B_bar, b_attach = create_support_bar(B,mount_thickness + layer_thickness) m_attach_gen = m_attach.get_generator() a_gen = a_attach.get_generator() b_gen = b_attach.get_generator() a_join = solid.hull()(m_attach_gen, a_gen) b_join = solid.hull()(m_attach_gen, b_gen) cronenberg = PolyMesh(generator= solid.union()(a_join,b_join)) aparatus = cronenberg + A_bar + B_bar + mt shaft_conn = create_shaft_connector() OT = (0, 0, 0) OQ = (0, 0, 1, 0) OP = (OT, OQ) bt_pos, bt_neg = joint_from_point(B,"B",2) torso = Body( pose = OP, joints=[ pos_A, pos_O, bt_pos ], elts=[Layer( aparatus, name='lol', color='yellow', )], name='torso' ) coupler = Body( pose = OP, joints = [pos_O], elts = [Layer(shaft_conn, name='lol', color = 'blue')], name = 'coupler' ) kwargs['elts'] = [coupler, b1_body, b2_body, b3_body, b4_body, conn,torso]#[torso] #kwargs['children'] = [torso] if 'connections' not in kwargs.keys(): kwargs['connections'] = [ ((0, 'torso', 'A'),(0, 'b3', 'A')), ((0, 'torso', 'B'),(0, 'b2', 'B')), ((0,'torso', 'O'),(0, 'conn', 'O')), ((0, 'conn','M'),(0,'b1', 'M')), ((0,'b1','C'),(0,'b3','C')), ((0,'b1','D'), (0,'b4','D')), ((0,'b2','E'),(0,'b4','E')), ((0,'conn', 'O'), (0,'coupler', 'O')) ] super(KlannLinkage, self).__init__(**kwargs)
def __init__(self, **kwargs): if 'name' not in kwargs.keys(): kwargs['name'] = 'klann' if 'elts' not in kwargs.keys(): #create b1, j1, c1 = create_klann_part(1,1, "1",True) b2, j2, c2 = create_klann_part(1, 1+ np.pi/2, "2", True) # print(conn.joints) A1,_,B1 = j1 A2,_,B2 = j2 # A1 = voffset_joint(A1,-3, "1A") # B1 = voffset_joint(B1,0,"1B") link_bodies = b1+b2 link_conns = c1+c2 # # #create servo mount that connects to shaft connector mt, m_attach1, m_attach2 = create_servo_mount() # # #add support for A,B mount_thickness= 6 # shaft coupler layer_thickness = 15 # # ##create the attacher thing, with joints #first layer of standoffs st_body1,anch1 = standoff(mount_thickness) #contains joint "anchor" st_body2,anch2 = standoff(mount_thickness) st_body3,_ = standoff(layer_thickness) #contains joint "anchor" st_body4,_ = standoff(layer_thickness) st_conn1 = ((0,"1b3","1A"),(0,st_body1.name, "A")) st_conn2 = ((0,"1b2","1B"),(0,st_body2.name, "A")) #second layer: st_conn3 = ((0,"2b3", "2A"),(0,st_body3.name, "A")) st_conn4 = ((0,"2b2", "2B"),(0,st_body4.name, "A")) #A1_bar, a1_attach = create_support_bar(A1,mount_thickness) #B1_bar, b1_attach = create_support_bar(B1,mount_thickness + layer_thickness) # m_attach1_gen = m_attach1.get_generator() # b1_gen = b1_attach.get_generator() # ((dxa,dya,_),_) = A1.pose ((dxb,dyb,_),_) = B1.pose placed_anch1 = solid.translate([dxa,dya,0])(anch1) placed_anch2 = solid.translate([dxb,dyb,0])(anch2) a1_join = solid.hull()(m_attach1_gen, placed_anch1) b1_join = solid.hull()(m_attach1_gen, placed_anch2) # cronenberg1 = PolyMesh(generator= solid.union()(a1_join,b1_join)) aparatus = cronenberg1 +mt shaft_conn = create_shaft_connector() OT = (0, 0, 0) OQ = (0, 0, 1, 0) OP = (OT, OQ) pos_O, neg_O = joint_from_point(Point(0,0), "1O", 1) O_3, _ = joint_from_point(Point(0,0),"3O",5) torso = Body( pose = OP, joints = [pos_O, A1, B1], elts=[Layer( aparatus, name='lol', color='yellow', )], name='torso' ) coupler = Body( pose = OP, joints = [pos_O,O_3], elts = [Layer(shaft_conn, name='lol', color = 'blue')], name = 'coupler' ) kwargs['elts'] = link_bodies+ [coupler]#, st_body1, st_body2, st_body3, st_body4]#,torso]#[torso] [conn,torso]+ , [coupler]+ conn coupler, #kwargs['children'] = [torso] if 'connections' not in kwargs.keys(): kwargs['connections'] = [ ((0, '1conn', '1O'),(0,'coupler','1O')), ((0, 'coupler', '3O'),(0, '2conn','2O')) #st_conn1, #st_conn2, #st_conn3, #st_conn4 #((0, 'torso', '2O'),(0, 'conn','2O')), # ((0, 'torso', '1A'),(0, '1b3', '1A')), # ((0, 'torso', '1B'),(0, '1b2', '1B')), #((0, 'torso', '2A'),(0, '2b3', '2A')), #((0, 'torso', '2B'),(0, '2b2', '2B')) ] + link_conns super(DoubleDeckerKlannLinkage, self).__init__(**kwargs)
def test_linearizer(): O, A, B, C, D, E, F, M, b1, b2, b3, b4, conn = create_klann_geometry(1, 1) b1_dict = {b1: [M, D, C]} b2_dict = {b2: [B, E]} b3_dict = {b3: [A, C]} b4_dict = {b4: [E, D, F]} conn_dict = {conn: [M, O]} O2, A2, B2, C2, D2, E2, F2, M2, b12, b22, b32, b42, conn2 = create_klann_geometry( -1, 1) b1_dict2 = {b12: [M2, D2, C2]} b2_dict2 = {b22: [B2, E2]} b3_dict2 = {b32: [A2, C2]} b4_dict2 = {b42: [E2, D2, F2]} O3, A3, B3, C3, D3, E3, F3, M3, b13, b23, b33, b43, conn3 = create_klann_geometry( 1, 1 + np.pi) b1_dict3 = {b13: [M3, D3, C3]} b2_dict3 = {b23: [B3, E3]} b3_dict3 = {b33: [A3, C3]} b4_dict3 = {b43: [E3, D3, F3]} O4, A4, B4, C4, D4, E4, F4, M4, b14, b24, b34, b44, conn4 = create_klann_geometry( -1, 1 + np.pi) b1_dict4 = {b14: [M4, D4, C4]} b2_dict4 = {b24: [B4, E4]} b3_dict4 = {b34: [A4, C4]} b4_dict4 = {b44: [E4, D4, F4]} conn_dict4 = {conn4: [M4, O4]} # seg_paths = simulate_linkage_path(1,1) # seg_paths2 = simulate_linkage_path(-1,1) # seg_paths3 = simulate_linkage_path(1,1+np.pi) # seg_paths4 = simulate_linkage_path(-1,1+np.pi) # seg_paths.update(seg_paths2) # seg_paths.update(seg_paths3) # seg_paths.update(seg_paths4) # print("generated Geometry") # # seg_confs = seg_conflicts(seg_paths) # print("calculated conflicts") # # #add gear conflicts and joints gear = Segment(M, M3) cap = Segment(M3, M3) # seg_confs[b1]+=[gear] # seg_confs[b12]+=[gear] # seg_confs[b13]+=[gear] # seg_confs[b14]+=[gear] # seg_confs[gear] = [b1,b12,b13,b14] gear_dict = {gear: [M, M3]} cap_dict = {cap: [M3]} # seg_dicts = [b1_dict, b2_dict, b3_dict, b4_dict] seg_dicts2 = [b1_dict2, b2_dict2, b3_dict2, b4_dict2] seg_dicts3 = [b1_dict3, b2_dict3, b3_dict3, b4_dict3] seg_dicts4 = [b1_dict4, b2_dict4, b3_dict4, b4_dict4] all_dicts = [gear_dict, conn_dict, cap_dict ] + seg_dicts + seg_dicts2 + seg_dicts3 + seg_dicts4 # print("added gear") # # neighbor_dicts = {list(seg.keys())[0]: [list(s.keys())[0] for s in all_dicts if shares_joint(s,seg)] # for seg in all_dicts} print("created neighbors") #optimal = create_layer_assignment(neighbor_dicts,seg_confs) optimal = {} optimal[gear] = 0 optimal[b1] = 1 optimal[b2] = 1 optimal[b3] = 2 optimal[b4] = 2 optimal[b12] = 2 optimal[b22] = 2 optimal[b32] = 1 optimal[b42] = 1 optimal[b13] = -2 optimal[b23] = -2 optimal[b33] = -1 optimal[b43] = -1 optimal[b14] = -1 optimal[b24] = -1 optimal[b34] = -2 optimal[b44] = -2 optimal[conn] = 3 optimal[cap] = -3 lock_joints = [conn, conn2, conn3, conn4, gear, cap] anchor_pts = [A, B, O, A4, B4] ratts, conns, seg_names, joint_names = rationalize_linkage( all_dicts, optimal, lock_joints, anchor_pts) pos_O, neg_O = joint_from_point(Point(0, 0), "1O", 1) #Create torso mt, m_attach1, m_attach2 = create_servo_mount() # #add support for A,B mount_thickness = 3 # shaft coupler layer_thickness = 3 ##create the attacher thing, with joints A1_bar, a1_attach = create_support_bar( joint_from_point(A, "A", 3)[0], mount_thickness) B1_bar, b1_attach = create_support_bar( joint_from_point(B, "B", 2)[0], mount_thickness) m_attach1_gen = m_attach1.get_generator() a1_gen = a1_attach.get_generator() b1_gen = b1_attach.get_generator() a1_join = solid.hull()(m_attach1_gen, a1_gen) b1_join = solid.hull()(m_attach1_gen, b1_gen) cronenberg1 = PolyMesh(generator=solid.union()(a1_join, b1_join)) A2_bar, a2_attach = create_support_bar( joint_from_point(A2, "A2", 2)[0], mount_thickness) B2_bar, b2_attach = create_support_bar( joint_from_point(B2, "B2", 3)[0], mount_thickness) m_attach2_gen = m_attach2.get_generator() a2_gen = a2_attach.get_generator() b2_gen = b2_attach.get_generator() a2_join = solid.hull()(m_attach2_gen, a2_gen) b2_join = solid.hull()(m_attach2_gen, b2_gen) cronenberg2 = PolyMesh(generator=solid.union()(a2_join, b2_join)) aparatus = cronenberg1 + A1_bar + B1_bar + mt + cronenberg2 + A2_bar + B2_bar aparatus.save("torso.stl") OT = (0, 0, 0) OQ = Z_JOINT_POSE[1] OP = (OT, OQ) torso = Body(pose=OP, joints=[pos_O], elts=[Layer( aparatus, name='lol', color='yellow', )], name='torso') ratts += [torso] conns += [((0, 'torso', "1O"), (0, seg_names[conn], joint_names[O]))] #print ratts #print conns return ratts, conns
def __init__(self, **kwargs): if 'name' not in kwargs.keys(): kwargs['name'] = 'klann' if 'elts' not in kwargs.keys(): #create ################################################## ################################################## b1, j1, c1 = create_klann_part(1,1, "1") b2, j2, c2 = create_klann_part(-1, 1+ np.pi, "2") conn1 = b1.pop() conn2 = b2.pop() conn = combine_connectors(conn1,conn2) # print(conn.joints) A1,_,B1 = j1 A1 = voffset_joint(A1,-3, "1A") B1 = voffset_joint(B1,0,"1B") A2,_,B2 = j2 A2 = voffset_joint(A2, -9, "2A") B2 = voffset_joint(B2, -6, "2B") link_bodies = b1+b2 +[conn] link_conns = c1+c2 # #create servo mount that connects to shaft connector mt, m_attach1, m_attach2 = create_servo_mount() # #add support for A,B mount_thickness= 3 # shaft coupler layer_thickness = 3 ##create the attacher thing, with joints A1_bar, a1_attach = create_support_bar(A1,mount_thickness) B1_bar, b1_attach = create_support_bar(B1,mount_thickness) m_attach1_gen = m_attach1.get_generator() a1_gen = a1_attach.get_generator() b1_gen = b1_attach.get_generator() a1_join = solid.hull()(m_attach1_gen, a1_gen) b1_join = solid.hull()(m_attach1_gen, b1_gen) cronenberg1 = PolyMesh(generator= solid.union()(a1_join,b1_join)) A2_bar, a2_attach = create_support_bar(A2,mount_thickness) B2_bar, b2_attach = create_support_bar(B2,mount_thickness) m_attach2_gen = m_attach2.get_generator() a2_gen = a2_attach.get_generator() b2_gen = b2_attach.get_generator() a2_join = solid.hull()(m_attach2_gen, a2_gen) b2_join = solid.hull()(m_attach2_gen, b2_gen) cronenberg2 = PolyMesh(generator= solid.union()(a2_join,b2_join)) aparatus = cronenberg1 + A1_bar + B1_bar + mt + cronenberg2 + A2_bar + B2_bar OT = (0, 0, 0) OQ = (0, 0, 1, 0) OP = (OT, OQ) pos_O, neg_O = joint_from_point(Point(0,0), "1O", 1) torso = Body( pose = OP, joints = [pos_O, A2, B2, A1, B1], elts=[Layer( aparatus, name='lol', color='yellow', )], name='torso' ) # coupler = Body( # pose = OP, # joints = [pos_O], # elts = [Layer(shaft_conn, name='lol', color = 'blue')], # name = 'coupler' # ) # kwargs['elts'] = [torso]+ link_bodies#[torso] , conn coupler, #kwargs['children'] = [torso] ################################################## #b3, j3, c3 = create_klann_part(-1,1+ np.pi/2, "3") b4, j4, c4 = create_klann_part(1, 1+ np.pi/2, "4", True) # print(conn.joints) #A3,_,B3 = j3 A4,_,B4 = j4 link_bodies = b4+link_bodies link_conns = c4+link_conns # # #create servo mount that connects to shaft connector #mt, m_attach1, m_attach2 = create_servo_mount() # # #add support for A,B mount_thickness= 6 # shaft coupler layer_thickness = 15 # # ##create the attacher thing, with joints #first layer of standoffs #st_body1,anch1 = standoff(mount_thickness) #contains joint "anchor" #st_body2,anch2 = standoff(mount_thickness) st_body3,_ = standoff(layer_thickness) #contains joint "anchor" st_body4,_ = standoff(layer_thickness) #st_conn1 = ((0,"1b3","1A"),(0,st_body1.name,"A")) #st_conn2 = ((0,"1b2","1B"),(0,st_body2.name,"A")) #second layer: st_conn3 = ((0,"4b3", "4A"),(0,st_body3.name, "A")) st_conn4 = ((0,"4b2", "4B"),(0,st_body4.name, "A")) #A1_bar, a1_attach = create_support_bar(A1,mount_thickness) #B1_bar, b1_attach = create_support_bar(B1,mount_thickness + layer_thickness) # #m_attach1_gen = m_attach1.get_generator() # b1_gen = b1_attach.get_generator() #((dxa,dya,_),_) = A1.pose #((dxb,dyb,_),_) = B1.pose #placed_anch1 = solid.translate([dxa,dya,0])(anch1) #placed_anch2 = solid.translate([dxb,dyb,0])(anch2) #a1_join = solid.hull()(m_attach1_gen, placed_anch1) #b1_join = solid.hull()(m_attach1_gen, placed_anch2) #cronenberg1 = PolyMesh(generator= solid.union()(a1_join,b1_join)) #aparatus = cronenberg1 +mt shaft_conn = create_shaft_connector() OT = (0, 0, 0) OQ = (0, 0, 1, 0) OP = (OT, OQ) pos_O, neg_O = joint_from_point(Point(0,0), "1O", 1) O_3, _ = joint_from_point(Point(0,0),"3O",5) # torso = Body( # pose = OP, # joints = j1+j2, # elts=[Layer( # aparatus, # name='lol', # color='yellow', # )], # name='torso' # ) coupler = Body( pose = OP, joints = [pos_O,O_3], elts = [Layer(shaft_conn, name='lol', color = 'blue')], name = 'coupler' ) kwargs['elts'] = link_bodies+ [coupler, st_body3, st_body4,torso]#[torso] [conn,torso]+ , [coupler]+ conn coupler, #kwargs['children'] = [torso] if 'connections' not in kwargs.keys(): kwargs['connections'] = [ #((0, 'conn', '1O'),(0,'coupler','1O')), #((0, 'coupler', '3O'),(0, '4conn','4O')), # 4O? #st_conn1, #st_conn2, st_conn3, st_conn4, # ((0, 'torso', '1O'),(0, 'coupler','1O')), ((0, 'torso', '1A'),(0, '1b3', '1A')), ((0, 'torso', '1B'),(0, '1b2', '1B')), ((0, 'torso', '2A'),(0, '2b3', '2A')), ((0, 'torso', '2B'),(0, '2b2', '2B')) ] + link_conns super(DoubleDoubleDeckerKlannLinkage, self).__init__(**kwargs)
Dinsert = 133.7 Hinsert = 43.2 Dhollow = 68.2 Hhollow = 150 Dsmoke = 1.5 * 25.4 Hsmoke = 5 * 25.4 upper_plane = solid.cube(BIG, center=True) upper_plane = solid.translate([0, 0, BIG / 2])(upper_plane) ball_min = solid.sphere(d=Dmin, segments=resolution) ball_min = solid.translate([0, 0, H])(ball_min) ball_max = solid.sphere(d=Dmax, segments=resolution) nosecone = solid.hull()(ball_min, ball_max) # nosecone = solid.intersection()(upper_plane, nosecone) taper = solid.cylinder(d1=Dbase, d2=BIG + Dbase, h=BIG, segments=resolution) nosecone = solid.intersection()(taper, nosecone) minifin_top = solid.cube([17, 2.5, 10 + 3.6], center=True) minifin_bot = solid.cube([17 + 7.2, 2, 10], center=True) minifin = solid.hull()(minifin_top, minifin_bot) minifin = solid.rotate([0, 90 - theta, 0])(minifin) minifin = solid.translate([-60, 0, 24])(minifin) nosecone += minifin nose_groove = solid.translate([22, 0, 0])(solid.circle(2)) nose_groove = solid.rotate_extrude()(nose_groove) nose_groove = solid.translate([0, 0, H - 22])(nose_groove) nosecone -= nose_groove nosecone = solid.translate([-Dmax / 2, 0, 0])(nosecone) nosecone = solid.rotate([0, 90 - theta, 0])(nosecone)
def __init__(self, config, u=1): super().__init__() # determines how much flat space to reserve around the switch # prevents interference between keycap and other geometry width = config.getfloat('overall_width') + (u - 1) * 19.0 length = config.getfloat('overall_length') # changes how tight of a fit the switch is in the opening switch_length = config.getfloat( 'switch_opening_length') ## Was 14.1, then 14.25 switch_width = config.getfloat('switch_opening_width') # plate thickness for where the switch plugs in thickness = config.getfloat('plate_thickness') # if using hot swap PCB's. This is not currently implemented add_hot_swap = config.getboolean('hot_swap') add_side_nubs = config.getboolean('side_nubs') # parameters not pulled from config file # most people should not need to modify these side_nub_width = 2.75 side_nub_radius = 1.0 ### Make Geometry ### # make two of the four walls, b/c rotationally symmetric socket = sl.cube([width, length, thickness], center=True) socket -= sl.cube([switch_width, switch_length, thickness * 2], center=True) socket = sl.translate([0, 0, -thickness / 2])(socket) # tapered side nub that stabilizes the switch, goes in right wall if add_side_nubs: side_nub = sl.cylinder(side_nub_radius, side_nub_width, segments=20, center=True) side_nub = sl.rotate(90, [1, 0, 0])(side_nub) side_nub = sl.translate( [switch_width / 2, 0, side_nub_radius - thickness])(side_nub) nub_cube_len = (width - switch_width) / 2 nub_cube = sl.cube([nub_cube_len, side_nub_width, thickness], center=True) nub_cube = sl.translate([(width - nub_cube_len) / 2, 0, -thickness / 2])(nub_cube) side_nub = sl.hull()(side_nub, nub_cube) socket += side_nub + sl.rotate([0, 0, 180])(side_nub) # add hot swap socket # TODO, configure for different hot swap socket types if add_hot_swap: #TODO: fix the hot swap socket. currently not parameterized # missing the stl file in this repo raise NotImplemented('hot swap sockets are not yet implemented') hot_swap_socket = sl.import_(Path.cwd().parent / "geometry" / "hot_swap_plate.stl") hot_swap_socket = sl.translate([0, 0, thickness - 5.25])(hot_swap_socket) socket = sl.union()(socket, hot_swap_socket) self._solid = socket self._anchors = CuboidAnchorCollection.create(dims=(width, length, thickness), offset=(0, 0, -thickness / 2))