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 rounded_cube(size, corner_radius, segments=None, center=False): if isinstance(corner_radius, (int, float)): corner_radius = XYZ( (corner_radius, corner_radius, corner_radius, corner_radius), (corner_radius, corner_radius, corner_radius, corner_radius), (corner_radius, corner_radius, corner_radius, corner_radius), ) else: corner_radius = XYZ(*corner_radius) if isinstance(size, (int, float)): size = XYZ(size, size, size) else: size = XYZ(*size) shapex = linear_extrude(size.x)(rounded_rectangle(XY(size.z, size.y), corner_radius.z, segments)) shapex = rotate((0, 90, 0))(shapex) shapex = translate(XYZ(0, 0, size.z))(shapex) shapey = linear_extrude(size.y)(rounded_rectangle(XY(size.x, size.z), corner_radius.y, segments)) shapey = rotate((90, 0, 0))(shapey) shapey = translate(XYZ(0, size.y, 0))(shapey) shapez = linear_extrude(size.z)(rounded_rectangle(XY(size.x, size.y), corner_radius.x, segments)) rc = intersection()(shapex, shapey, shapez) return rc
def makeRegister(board, jigFrameSize, jigThickness, pcbThickness, outerBorder, innerBorder, tolerance, topSide): bBox = findBoardBoundingBox(board) centerpoint = rectCenter(bBox) top = jigThickness - fromMm(0.15) pcbBottom = jigThickness - pcbThickness outerPolygon, holes = createOuterPolygon(board, jigFrameSize, outerBorder) outerRing = outerPolygon.exterior.coords if topSide: outerRing = mirrorX(outerRing, centerpoint[0]) body = solid.linear_extrude(height=top, convexity=10)(solid.polygon(outerRing)) innerRing = createOffsetPolygon(board, -innerBorder).exterior.coords if topSide: innerRing = mirrorX(innerRing, centerpoint[0]) innerCutout = solid.utils.down(jigThickness)(solid.linear_extrude( height=3 * jigThickness, convexity=10)(solid.polygon(innerRing))) registerRing = createOffsetPolygon(board, tolerance).exterior.coords if topSide: registerRing = mirrorX(registerRing, centerpoint[0]) registerCutout = solid.utils.up(jigThickness - pcbThickness)( solid.linear_extrude(height=jigThickness, convexity=10)(solid.polygon(registerRing))) register = body - innerCutout - registerCutout for hole in holes: register = register - solid.translate([hole[0], hole[1], top])( m2countersink()) return solid.scale(toMm(1))(solid.translate( [-centerpoint[0], -centerpoint[1], 0])(register))
def printedStencilSubstrate(outlineDxf, thickness, frameHeight, frameWidth, frameClearance): bodyOffset = solid.utils.up(0) if frameWidth + frameClearance == 0 else solid.offset(r=frameWidth + frameClearance) body = solid.linear_extrude(height=thickness + frameHeight)( bodyOffset(solid.import_dxf(outlineDxf))) boardOffset = solid.utils.up(0) if frameClearance == 0 else solid.offset(r=frameClearance) board = solid.utils.up(thickness)( solid.linear_extrude(height=thickness + frameHeight)( boardOffset(solid.import_dxf(outlineDxf)))) return body - board
def printedStencil(outlineDxf, holesDxf, extraHoles, thickness, frameHeight, frameWidth, frameClearance, enlargeHoles, front): zScale = -1 if front else 1 xRotate = 180 if front else 0 substrate = solid.scale([1, 1, zScale])(printedStencilSubstrate(outlineDxf, thickness, frameHeight, frameWidth, frameClearance)) holesOffset = solid.utils.up(0) if enlargeHoles == 0 else solid.offset(delta=enlargeHoles) holes = solid.linear_extrude(height=4*thickness, center=True)( holesOffset(solid.import_dxf(holesDxf))) substrate -= holes for h in extraHoles: substrate -= solid.scale([toMm(1), -toMm(1), 1])( solid.linear_extrude(height=4*thickness, center=True)( solid.polygon(h.exterior.coords))) return solid.rotate(a=xRotate, v=[1, 0, 0])(substrate)
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 process(outline_file, solderpaste_file, stencil_thickness=0.2, include_ledge=True, ledge_height=1.2, ledge_gap=0.0, increase_hole_size_by=0.0): outline_shape = create_outline_shape(outline_file) cutout_polygon = create_cutouts( solderpaste_file, increase_hole_size_by=increase_hole_size_by) if ledge_gap: # Add a gap between the ledge and the stencil outline_shape = offset_shape(outline_shape, ledge_gap) outline_polygon = polygon(outline_shape) stencil = linear_extrude(height=stencil_thickness)(outline_polygon - cutout_polygon) if include_ledge: ledge_shape = offset_shape(outline_shape, 1.2) ledge_polygon = polygon(ledge_shape) - outline_polygon # Cut the ledge in half by taking the bounding box of the outline, cutting it in half # and removing the resulting shape from the ledge shape # We always leave the longer side of the ledge intact so we don't end up with a tiny ledge. cutter = bounding_box(ledge_shape) height = abs(cutter[1][1] - cutter[0][1]) width = abs(cutter[0][0] - cutter[3][0]) if width > height: cutter[1][1] -= height / 2 cutter[2][1] -= height / 2 else: cutter[2][0] -= width / 2 cutter[3][0] -= width / 2 ledge_polygon = ledge_polygon - polygon(cutter) ledge = utils.down(ledge_height - stencil_thickness)( linear_extrude(height=ledge_height)(ledge_polygon)) stencil = ledge + stencil # Rotate the stencil to make it printable stencil = rotate(a=180, v=[1, 0, 0])(stencil) return scad_render(stencil)
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 write_to_scad(self, filename = 'test.scad'): """Uses solidpython to export the animation (shapes and their associated transformations) to an OpenSCAD file, ready to be rendered as an STL. Inputs: filename: The filename to export to. """ if type(self.final_shapes) == NoneType: self.render_shapes() shapes_to_export = [] for shape in self.final_shapes: solid_shapes = [] for i in range(len(shape)): #For each shape (which is stored as a list of points)... solid_shape = shape[i].T.tolist() #Represent it as a polygon... solid_shapes.append(sp.polygon(solid_shape)) #Extrude that polygon up .21mm... solid_shapes[i] = sp.linear_extrude(.21)(solid_shapes[i]) #Then translate that extrusion up .2mm... solid_shapes[i] = up(i*.2)(solid_shapes[i]) shapes_to_export.append(solid_shapes) #Then union ALL of the extrudes of EVERY shape final_export = union()(shapes_to_export) scad_render_to_file(final_export,filename)
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 assemble_chair(polygons, tf_xyz_rpy, t=3.0): """ Create a 3D rendering of a chair from part outlines. Args: polygons ([PolyLine]): list of PolyLines representing the outlines of the chair parts tf_xyz_rpy ([[x,y,z][r,p,y]]): List of transformations as x,y,z offsets and roll, pitch, yaw rotations in degrees t (int): material thickness Returns: A list of PolyMeshes, with one PolyMesh per input polygon, transformed by corresponding tf input """ polys = [] for (p, r) in zip(polygons, tf_xyz_rpy): translation, rotation = r solid_p = p.get_generator() thick_p = sl.linear_extrude(t)(solid_p) rotated_p = sl.rotate(rotation)(thick_p) translated_p = sl.translate(translation)(rotated_p) poly = PolyMesh(generator=translated_p) polys.append(poly) return polys
def planar_slice_3d(mesh, slice_args, slice_width=1): (plane, offset) = slice_args slice_gen = sl.linear_extrude(slice_width)(plane.get_generator()) slice_gen = sl.translate(offset)(slice_gen) slice = PolyMesh(generator=slice_gen) intersection = (slice.intersected(mesh)) return intersection
def planar_slice_3d(mesh, slice_args, slice_width=1): (plane, offset) = slice_args slice_gen = sl.linear_extrude(slice_width)(plane.get_generator()) slice_gen = sl.translate(offset)(slice_gen) slice = PolyMesh(generator=slice_gen) intersection = slice.intersected(mesh) return intersection
def dovetail(width, length, depth, ratio): return linear_extrude(depth)(polygon(( (0, 0), (width, 0), (width - length * ratio, length), (length * ratio, length), )))
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 label(a_str:str, width:float=15, halign:str="left", valign:str="baseline", size:int=10, depth:float=0.5, lineSpacing:float=1.15, font:str="MgOpen Modata:style=Bold", segments:int=40, spacing:int=1) -> OpenSCADObject: """Renders a multi-line string into a single 3D object. __author__ = 'NerdFever.com' __copyright__ = 'Copyright 2018-2019 NerdFever.com' __version__ = '' __email__ = '*****@*****.**' __status__ = 'Development' __license__ = Copyright 2018-2019 NerdFever.com """ lines = a_str.splitlines() texts = [] for idx, l in enumerate(lines): t = text(text=l, halign=halign, valign=valign, font=font, spacing=spacing).add_param('$fn', segments) t = linear_extrude(height=1)(t) t = translate([0, -size * idx * lineSpacing, 0])(t) texts.append(t) result = union()(texts) result = resize([width, 0, depth])(result) result = translate([0, (len(lines)-1)*size / 2, 0])(result) return result
def part(variant='', configuration='', debug=False): out_cyl = sp.cylinder(h=dim15 + 0.001, d=dim10) cone = sp.cylinder(h=dim16, d1=dim10, d2=dim11) cone = sp.translate([0, 0, dim15])(cone) tmp = out_cyl + cone bseat = sp.translate([0, 0, -0.1])(sp.cylinder(d=dim11, h=dim16 + 0.1)) tmp -= bseat flange = sp.cylinder(d=dim14, h=dim15 + 0.2) flange = sp.translate([0, 0, dim16 - 0.1])(flange) tmp -= flange chamfer = chamfers.mcad_chamfer_cylinder(diameter=dim11, length=1.5, angle=30, depth=None, internal=True) tmp -= chamfer pn = curved_text.mcad_circle_text(diameter=(dim10 + dim11) / 2 - PN_s, t=_code_name + _version + variant, size=PN_s, font="Open Sans:style=Bold", halign="center", valign="baseline", spacing=1, direction="cw") pn = sp.linear_extrude(PN_d + 0.001)(pn) tmp -= sp.translate([0, 0, PN_d])(sp.rotate([0, 180, 0])(pn)) if debug: tmp += assembly.connector(SPOOL_CONN) if debug: tmp += assembly.connector(BEARING_CONN) return tmp
def slice(self, progress, delta_t, delta_d, mod=1): skew_i = [s * progress for s in self.skew] # calculate tilt for slices after the first if progress > 0: tilt_i = [-t / (self.z * progress) for t in self.tilt] if not self.double_sculpted: tilt_i[1] = 0 else: tilt_i = [0, 0] depth_i = (self.z * mod - delta_d) * progress key_shape_kwargs = { 'size': [self.base[i] * self.size[i] - delta_t for i in [0, 1]], 'top_delta': [d * mod for d in self.top_delta], 'progress': progress, } if self.key_shape_kwargs is not None: key_shape_kwargs.update(self.key_shape_kwargs) out = self.key_shape(**key_shape_kwargs) out = s.translate([*skew_i, depth_i])(s.rotate([*tilt_i, 0])( s.linear_extrude(height=_SMALL)(out))) return out
def profile(width: float, length: float, thickness: float): shape = union()( square(size=[width, length]), translate([0, width, 0])(rotate([0, 0, -90])(square(size=[width, length]))), ) return linear_extrude(height=thickness)(shape)
def volume(): width = 6. height = 6. cable_exit = sp.translate((0., magic_1, 0.))(sp.cube( (width, 20., height * 2), center=True)) return sp.linear_extrude(box_depth)(projection()) - cable_exit
def locate_part_number(text): pn = sp.text(text=text, size=PN_s, font="Open Sans:style=Bold", halign="center") pn = sp.linear_extrude(PN_d + 0.001)(pn) pn = sp.rotate([90, 0, 0])(pn) pn = sp.translate([0, -N_af / 2 + PN_d - 0.001, (N_h - PN_s) / 2])(pn) return pn
def screw_hole( radius: float, length: float, head_radius: t.Optional[float] = None, cap_depth: t.Optional[float] = None, angle=None, ): solids = [s.linear_extrude(length)(s.circle(r=radius))] if angle is not None: counter = s.translate([0, 0, length])(cone(head_radius, angle, False)) solids.append(counter) if cap_depth is not None: cut = s.translate([0, 0, length - cap_depth])( s.linear_extrude(cap_depth)(s.circle(r=head_radius)) ) solids.append(cut) return s.union()(*solids)
def process(outline_file, solderpaste_file, stencil_thickness=0.2, include_ledge=True, ledge_height=1.2, ledge_gap=0.0, increase_hole_size_by=0.0): outline_shape = create_outline_shape(outline_file) cutout_polygon = create_cutouts(solderpaste_file, increase_hole_size_by=increase_hole_size_by) if ledge_gap: # Add a gap between the ledge and the stencil outline_shape = offset_shape(outline_shape, ledge_gap) outline_polygon = polygon(outline_shape) stencil = linear_extrude(height=stencil_thickness)(outline_polygon - cutout_polygon) if include_ledge: ledge_shape = offset_shape(outline_shape, 1.2) ledge_polygon = polygon(ledge_shape) - outline_polygon # Cut the ledge in half by taking the bounding box of the outline, cutting it in half # and removing the resulting shape from the ledge shape # We always leave the longer side of the ledge intact so we don't end up with a tiny ledge. cutter = bounding_box(ledge_shape) height = abs(cutter[1][1] - cutter[0][1]) width = abs(cutter[0][0] - cutter[3][0]) if width > height: cutter[1][1] -= height/2 cutter[2][1] -= height/2 else: cutter[2][0] -= width/2 cutter[3][0] -= width/2 ledge_polygon = ledge_polygon - polygon(cutter) ledge = utils.down( ledge_height - stencil_thickness )( linear_extrude(height=ledge_height)(ledge_polygon) ) stencil = ledge + stencil # Rotate the stencil to make it printable stencil = rotate(a=180, v=[1, 0, 0])(stencil) return scad_render(stencil)
def draw_profile(): obj = prof_p1 + S.color("black")(prof_n1) # draw intersection points if True: obj += S.color("red")(S.linear_extrude(10)(S.union()( S.translate(bottom_meet_pt)(S.circle(0.2)), S.translate(upper_meet_pt)(S.circle(0.2)), ))) return obj
def panel_shape(panel_tri): edge_midpoint = 0.5 * (panel_tri[0] + panel_tri[1]) rotation_vector = panel_tri[1] - panel_tri[0] transform = lambda x: solid.translate( edge_midpoint)(solid.rotate(a=panel_angle, v=rotation_vector) (solid.translate(-edge_midpoint)(x))) return transform( solid.linear_extrude(0.01)(solid.polygon(panel_tri * 0.9)))
def get_case_wall(height): d = case - (sc.offset(-2 * mm)(case)) d = ( d + screws.create_screws(diameter=5.2 * mm) - screws.create_screws(diameter=3.2 * mm) ) d = sc.linear_extrude(height)(d) # d = (d - switches.create_all_switches(size=0.8)) return d
def ff_linear_extrude(obj, height, axis="z", center=True, **kwargs): """Note that center only centers the 'axis', not your 2d object""" _check_axis(axis) o = solid.linear_extrude(height, **kwargs)(obj) if center: o = o.down(height / 2) if axis == "y": o = o.rotate(90, 0, 0) elif axis == "x": o = o.rotate(0, 90, 0) return o
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 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 key_lettering(): messages = ["LeRoy", "Dental"] layout = union()([ forward((index - 0.5) * -LETTER_HEIGHT)(text(message, halign='center', valign='center')) for index, message in enumerate(messages) ]) lettering = up(THICKNESS / 2 - LETTERING_RISE)( linear_extrude(height=2 * LETTERING_RISE)(scale([0.8, 0.8, 1])(layout))) return back(HANDLE_DIAMETER / 2)(lettering)
def volume(): extrusion = sp.rotate((0, 0, 0))(sp.union()( spu.down(length)(sp.linear_extrude(length)(projection_main())), spu.down(10.)(sp.linear_extrude(10.)(projection_fan())), )) rotated_extrusion = sp.rotate( (90, 0, 0))(spu.forward(fan.size[1] / 2.)(extrusion)) tray_mounting_holes = sp.linear_extrude(10.)(mounting_holes(6)) def cable_cutout(position, diameter): return sp.translate(position)(sp.rotate( (0, 90, 0))(sp.cylinder(d=diameter, h=outer_wall_thickness + 1., center=True))) cable_cutouts = sp.union()( cable_cutout((-33, 20, 15), 15.), cable_cutout((-33, 60, 10), 12.), ) return rotated_extrusion - tray_mounting_holes - cable_cutouts
def assembly(): print "adapter needs height 32mm and we have %smm" % (8 * material_height) print "phone needs height 32mm and we have %smm" % (6 * material_height) print "total height %smm" % (len(ls) * material_height) layers = [] for i, l in enumerate(ls): l_inst = l() layer = linear_extrude(height=material_height)(l_inst.body) layer = up(i * (material_height + layer_z_gap))(layer) layer = color(l_inst.color)(layer) layers.append(layer) return union()(layers)
def planar_slice(mesh, slice_args, slice_width=5): """ Returns a 2D projection of where the mesh intersects the plane. Args: mesh (PolyMesh): 3D PolyMesh object to be sliced plane (PolyLine): a 3D PolyLine of coplanar points """ (plane, offset) = slice_args slice_gen = sl.linear_extrude(slice_width)(plane.get_generator()) slice_gen = sl.translate(offset)(slice_gen) slice = PolyMesh(generator=slice_gen) intersection = (slice.intersected(mesh)).get_generator() return PolyLine(generator=sl.projection()(intersection))
def leg(dims: typing.List[float], flare: bool = True) -> s.OpenSCADObject: """ """ x, y, z = dims leg = s.cube(dims, center=True) if flare: flare = s.linear_extrude(x)(s.circle(r=y, segments=3)) flare = s.rotate([0, -90, 0])(flare) flare = s.translate([x / 2, 0, -y * 1.1])(flare) leg = s.union()(leg, flare) return leg
def slice_sim(slices, t_m=3.0): """ Returns simulation of assembled slice-formed solid. Args: slices ([PolyLine]): list of PolyLines to simulate. t_m (float): material thickness Returns: A PolyMesh representing the assembled slices. """ # assume stacked in the z dimension axis = np.array([0, 0, 1]) slice_solids = [] for (i, slice) in enumerate(slices): translation = list(t_m * axis * i) slice_solid = sl.linear_extrude(t_m)(slice.get_generator()) positioned_solid = sl.translate(translation)(slice_solid) slice_solids.append(positioned_solid) return PolyMesh(generator=sl.union()(slice_solids))
def path_render3D(self, pconfig, border=False): global _delta, PRECISION, SCALEUP self.rotations_to_3D() config={} config=self.overwrite(config,pconfig) inherited = self.get_config() # if('transformations' in config): config=self.overwrite(config, inherited) if border==False and 'zoffset' in pconfig: zoffset= pconfig['zoffset'] elif 'zoffset' in config and config['zoffset']: zoffset= config['zoffset'] else: zoffset = 0 if 'thickness' not in config: config['thickness']=pconfig['thickness'] if config['z0'] is None or config['z0'] is False: z0=0 else: z0=config['z0'] if border==False: z0 += 1 if (config['z1'] is False or config['z1'] is None) and config['z0'] is not None and config['thickness'] is not None: if border==False: z1 = - config['thickness']- 20 else: z1 = - config['thickness'] else: z1= config['z1'] z0 *=config['zdir'] z1*=config['zdir'] # z0 = - config['thickness'] - z0 # z1 = - config['thickness'] - z1 # try to avoid faces and points touching by offsetting them slightly z0+=_delta z1-=_delta _delta+=0.00001 outline = [] points = self.polygonise(RESOLUTION) # extrude_path = [ Point3(0,0,zoffset + float(z0)), Point3(0,0, zoffset + float(z1)) ] for p in points: outline.append( [round(p[0],PRECISION)*SCALEUP, round(p[1],PRECISION)*SCALEUP ]) outline.append([round(points[0][0],PRECISION)*SCALEUP, round(points[0][1],PRECISION)*SCALEUP]) # outline.append( Point3(p[0], p[1], p[2] )) # outline.append( Point3(points[0][0], points[0][1], points[0][2] )) h = round(abs(z1-z0),PRECISION)*SCALEUP bottom = round((min(z1,z0)+zoffset),PRECISION) *SCALEUP # extruded = extrude_along_path(shape_pts=outline, path_pts=extrude_path) if self.extrude_scale is not None: scale = self.extrude_scale if self.extrude_centre is None: self.extrude_centre = V(0,0) centre = (PSharp(V(0,0)).point_transform(config['transformations']).pos+self.extrude_centre) centre = [centre[0], centre[1]] uncentre = [-centre[0], -centre[1]] extruded = solid.translate([0,0,bottom])( solid.translate(centre)( solid.linear_extrude(height=h, center=False, scale = scale)( solid.translate(uncentre)(solid.polygon(points=outline))))) else: scale = 1 extruded = solid.translate([0,0,bottom])(solid.linear_extrude(height=h, center=False)(solid.polygon(points=outline))) #extruded = translate([0,0,bottom])(linear_extrude(height=h, center=False)(solid.polygon(points=outline))) # if 'isback' in config and config['isback'] and border==False: # extruded = mirror([1,0,0])(extruded ) if 'colour' in config and config['colour']: extruded = solid.color(self.scad_colour(config['colour']))(extruded) if hasattr(self, 'transform') and self.transform is not None and self.transform is not False and 'matrix3D' in self.transform: if type(self.transform['matrix3D'][0]) is list: extruded=solid.translate([-self.transform['rotate3D'][1][0], - self.transform['rotate3D'][1][1]])(extruded) extruded=solid.multmatrix(m=self.transform['matrix3D'][0])(extruded) extruded=solid.translate([self.transform['rotate3D'][1][0], self.transform['rotate3D'][1][1]])(extruded) else: extruded=solid.multmatrix(m=self.transform['matrix3D'])(extruded) if hasattr(self, 'transform') and self.transform is not None and self.transform is not False and 'rotate3D' in self.transform: if type(self.transform['rotate3D'][0]) is list: print [-self.transform['rotate3D'][1][0], - self.transform['rotate3D'][1][1], - self.transform['rotate3D'][1][2]- zoffset] extruded=solid.translate([-self.transform['rotate3D'][1][0], - self.transform['rotate3D'][1][1], - self.transform['rotate3D'][1][2]- zoffset])(extruded) extruded=solid.rotate([self.transform['rotate3D'][0][0], self.transform['rotate3D'][0][1],self.transform['rotate3D'][0][2] ])(extruded) extruded=solid.translate([self.transform['rotate3D'][1][0], self.transform['rotate3D'][1][1], self.transform['rotate3D'][1][1] + zoffset])(extruded) else: extruded=solid.rotate([self.transform['rotate3D'][0], self.transform['rotate3D'][1],self.transform['rotate3D'][2] ])(extruded) if hasattr(self, 'transform') and self.transform is not None and self.transform is not False and 'translate3D' in self.transform: extruded=solid.translate([self.transform['translate3D'][0], self.transform['translate3D'][1],self.transform['translate3D'][2] ])(extruded) return [extruded]
s.cube(size=[lid_guide_padding, lid_guide_width, wall_width]) ) )) # lid guide padding bottom on power side lid += u.up(lid_guide_bot_z)( u.forward(lid_guide_y + board_width - lid_guide_width)( u.right(depth - half_wall_width - lid_guide_padding + hnt)( s.cube(size=[lid_guide_padding, lid_guide_width, wall_width]) ) ) ) logo = u.right(40)(u.up(height - emboss_depth)( s.linear_extrude(height=emboss_depth)( s.rotate(a=[0, 0, 90])( s.import_(file=logo_file) ) ) )) body -= logo def render(suffix, final): suffix += '.scad' s.scad_render_to_file(final, __file__.replace('.py', suffix)) # rotate and split into 2 files for printing render( '-print-body', s.rotate(a=[0, -90, 0])(body))