def produceOutput(mains): eps = 0.02 # eps is mostly for clearing display sheen rail = RailData(mains, eps) tapes = getTapeDataList(mains) # Find max leg height, and span across all units maxHi = 0 unwide = tapes[0].wide + tapes[-1].wide + 2*rail.Slack span = -rail.CapWide - unwide - tapes[0].oho - tapes[-1].oh1 for tt in tapes: maxHi = max(maxHi, tt.high) span += rail.CapWide + tt.wide + rail.Slack - tt.oh1 - tt.oho print ('Span across {} units is {:<0.2f}'.format(len(tapes)-1, span)) # Make bridges bridgeAsm = makeBridges(rail, span) asm = None sideA = tapes[0] for sideB in tapes[1:]: c = makeUnit(rail, sideA, sideB, maxHi) openChan = sideA.wide + rail.Slack - sideA.oh1 - sideA.oho asm = (c + back(rail.CapWide+openChan)(asm)) if asm else c sideA = sideB if bridgeAsm: asm += bridgeAsm cylSegments = 44 cylSet_fn = '$fn = {};'.format(cylSegments) asmFile = 'channel-asm{}.scad'.format(version) scad_render_to_file(asm, asmFile, file_header=cylSet_fn, include_orig_code=False) print ('Wrote scad code to {}'.format(asmFile))
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 createPrinted(inputboard, outputdir, pcbthickness, thickness, framewidth, ignore, frameclearance, enlargeholes): """ Create a 3D printed self-registering stencil. """ board = pcbnew.LoadBoard(inputboard) refs = parseReferences(ignore) removeComponents(board, refs) Path(outputdir).mkdir(parents=True, exist_ok=True) # We create the stencil based on DXF export. Using it avoids the necessity # to interpret KiCAD PAD shapes which constantly change with newer and newer # versions. height = min(pcbthickness, max(0.5, pcbthickness - 0.3)) bottomPaste, topPaste, outline = pasteDxfExport(board, outputdir) topStencil = printedStencil(outline, topPaste, thickness, height, framewidth, frameclearance, enlargeholes, True) bottomStencil = printedStencil(outline, bottomPaste, thickness, height, framewidth, frameclearance, enlargeholes, False) bottomStencilFile = os.path.join(outputdir, "bottomStencil.scad") solid.scad_render_to_file(bottomStencil, bottomStencilFile, file_header=f'$fa = 0.4; $fs = 0.4;', include_orig_code=True) renderScad(bottomStencilFile, os.path.join(outputdir, "bottomStencil.stl")) topStencilFile = os.path.join(outputdir, "topStencil.scad") solid.scad_render_to_file(topStencil, topStencilFile, file_header=f'$fa = 0.4; $fs = 0.4;', include_orig_code=True) renderScad(topStencilFile, os.path.join(outputdir, "topStencil.stl"))
def main(): fn = 200 scad_render_to_file(token_tray_1(), "condition_tokens_tray_1.scad", file_header=f"$fn = {fn};\n") scad_render_to_file(token_tray_2(), "condition_tokens_tray_2.scad", file_header=f"$fn = {fn};\n")
def main(): fn = 200 scad_render_to_file(hitpoint_tray_1(), "hit_points_tokens_tray_1.scad", file_header=f"$fn = {fn};\n") scad_render_to_file(hitpoint_tray_2(), "hit_points_tokens_tray_2.scad", file_header=f"$fn = {fn};\n")
def show(self, thing): if (self.running_instance is None or self.running_instance.poll() is not None): self.running_instance = self._popen([ self.running_file.name, ]) solid.scad_render_to_file(thing, self.running_file.name, file_header=self.header)
def plane_render_part3D(self, thepart, pconfig, filename=False): self.make_part3D(thepart, pconfig) if filename==False: if thepart.name is None: return filename = thepart.name+'.scad' else: filename = filename +',scad' if hasattr(thepart, 'border3D'): solid.scad_render_to_file(thepart.border3D, filename, include_orig_code=False)
def produceOutput(ap): if not ap.ready: return asm = ap.getOblongArm() cylSegments, version, title = 90, 1, 'legs' cylSet_fn = '$fn = {};'.format(cylSegments) asmFile = '{}{}.scad'.format(title, version) scad_render_to_file(asm, asmFile, file_header=cylSet_fn, include_orig_code=False) print('Wrote scad code to {}'.format(asmFile))
def cli(filename): """ Generate a scad file of a plate with optional holes in it. First define the overall geometry: "circle" or "square", then declare the holes. The json file must have a certain structure, i.e.: { "width": 400, "height": 300, "thickness": 15, "holes": [ { "diameter": 5.5, "x_pos": 20, "y_pos": 20, "z_pos": 0, "depth": 15 }, ... ] } """ p = Path(filename) click.echo(f'Generating {p.stem}.scad') with open(filename) as f: data = json.load(f) if "holes" in data: if "thickness" in data: scad_render_to_file( Model.plate_with_holes( data["form"] if "form" in data else "square", { "width": data["width"] if "width" in data else 0, "height": data["height"] if "height" in data else 0, "diameter": data["diameter"] if "diameter" in data else 0, "thickness": data["thickness"], "fillet": data["fillet"] if "fillet" in data else 0 }, data["holes"], data["bosses"] if "bosses" in data else None ), file_header=f'$fn = {SEGMENTS};', filepath=f'{p.stem}.scad' ) click.echo('Processing complete.') else: click.echo('Declare the thickness of your plate.') click.echo('Process aborted.') else: click.echo('You must include some holes in your plate!') click.echo('Process aborted.')
def render_to(self, thing, stl_name, header=None): if header is None: header = self.header f = tempfile.NamedTemporaryFile(suffix=".scad", delete=True) solid.scad_render_to_file(thing, f.name, file_header=header) try: I = subprocess.run(["openscad", "-o", stl_name, f.name], capture_output=True, check=True) except subprocess.CalledProcessError as e: sys.stdout.write(e.stdout) sys.stderr.write(e.stderr) raise
def create(inputboard, outputdir, jigsize, jigthickness, pcbthickness, registerborder, tolerance, ignore, cutout): """ Create stencil and register elements for manual paste dispensing jig. See more details at: https://github.com/yaqwsx/KiKit/blob/master/doc/stencil.md """ board = pcbnew.LoadBoard(inputboard) refs = parseReferences(ignore) removeComponents(board, refs) Path(outputdir).mkdir(parents=True, exist_ok=True) jigsize = (fromMm(jigsize[0]), fromMm(jigsize[1])) addJigFrame(board, jigsize) cutoutComponents(board, getComponents(board, parseReferences(cutout))) stencilFile = os.path.join(outputdir, "stencil.kicad_pcb") board.Save(stencilFile) plotPlan = [ # name, id, comment ("PasteBottom", pcbnew.B_Paste, "Paste Bottom"), ("PasteTop", pcbnew.F_Paste, "Paste top"), ] gerberDir = os.path.join(outputdir, "gerber") gerberImpl(stencilFile, gerberDir, plotPlan, False) gerbers = [os.path.join(gerberDir, x) for x in os.listdir(gerberDir)] subprocess.check_call( ["zip", "-j", os.path.join(outputdir, "gerbers.zip")] + gerbers) jigthickness = fromMm(jigthickness) pcbthickness = fromMm(pcbthickness) outerBorder, innerBorder = fromMm(registerborder[0]), fromMm( registerborder[1]) tolerance = fromMm(tolerance) topRegister = makeTopRegister(board, jigsize, jigthickness, pcbthickness, outerBorder, innerBorder, tolerance) bottomRegister = makeBottomRegister(board, jigsize, jigthickness, pcbthickness, outerBorder, innerBorder, tolerance) topRegisterFile = os.path.join(outputdir, "topRegister.scad") solid.scad_render_to_file(topRegister, topRegisterFile) renderScad(topRegisterFile, os.path.join(outputdir, "topRegister.stl")) bottomRegisterFile = os.path.join(outputdir, "bottomRegister.scad") solid.scad_render_to_file(bottomRegister, bottomRegisterFile) renderScad(bottomRegisterFile, os.path.join(outputdir, "bottomRegister.stl"))
def create(inputboard, outputdir, jigsize, jigthickness, pcbthickness, registerborder, tolerance, ignore, cutout): board = pcbnew.LoadBoard(inputboard) refs = parseReferences(ignore) removeComponents(board, refs) Path(outputdir).mkdir(parents=True, exist_ok=True) jigsize = (fromMm(jigsize[0]), fromMm(jigsize[1])) addJigFrame(board, jigsize) cutoutComponents(board, getComponents(board, parseReferences(cutout))) stencilFile = os.path.join(outputdir, "stencil.kicad_pcb") board.Save(stencilFile) plotPlan = [ # name, id, comment ("PasteBottom", pcbnew.B_Paste, "Paste Bottom"), ("PasteTop", pcbnew.F_Paste, "Paste top"), ] # get a copy of exportSettingsJlcpcb dictionary and # exclude the Edge.Cuts layer for creation of stencil gerber files exportSettings = exportSettingsJlcpcb.copy() exportSettings["ExcludeEdgeLayer"] = True gerberDir = os.path.join(outputdir, "gerber") gerberImpl(stencilFile, gerberDir, plotPlan, False, exportSettings) gerbers = [os.path.join(gerberDir, x) for x in os.listdir(gerberDir)] subprocess.check_call( ["zip", "-j", os.path.join(outputdir, "gerbers.zip")] + gerbers) jigthickness = fromMm(jigthickness) pcbthickness = fromMm(pcbthickness) outerBorder, innerBorder = fromMm(registerborder[0]), fromMm( registerborder[1]) tolerance = fromMm(tolerance) topRegister = makeTopRegister(board, jigsize, jigthickness, pcbthickness, outerBorder, innerBorder, tolerance) bottomRegister = makeBottomRegister(board, jigsize, jigthickness, pcbthickness, outerBorder, innerBorder, tolerance) topRegisterFile = os.path.join(outputdir, "topRegister.scad") solid.scad_render_to_file(topRegister, topRegisterFile) renderScad(topRegisterFile, os.path.join(outputdir, "topRegister.stl")) bottomRegisterFile = os.path.join(outputdir, "bottomRegister.scad") solid.scad_render_to_file(bottomRegister, bottomRegisterFile) renderScad(bottomRegisterFile, os.path.join(outputdir, "bottomRegister.stl"))
def render2Openscad(self,fn=None,segments=48): """Generates .scad file for the geometry. .. note:: If ``fn=None``, then will use the same filename and path as .geo file. Keyword Args: fn (str): Output filename. segments (int): Number of segments used for convex hull of surface. """ if fn==None: fn=self.fnGeo.replace(".geo",".scad") solid.scad_render_to_file(self.genAsOpenscad(), filepath=fn,file_header='$fn = %s;' % segments, include_orig_code=False)
def build_your_own(): # TODO: flush out this interface from keebgen import DactylManuform, Key, KeyColumn, ThumbCluster num_rows = 4 num_cols = 6 lightcycle = DactylManuform.unpopulated(rows=num_rows, cols=num_cols) key_params = {'switch': 'cherry_mx', 'cap': 'oem'} small_key = Key(**key_params) big_key = Key(units=1.5, **key_params) # Define the right half # Columns from left to right """ [x][x][x][x][x][x] [x][x][x][x][x][x] [x][x][x][x][x][x] [x][x][x][x][x] """ cols = [KeyColumn(keys=[small_key] * (num_rows-1))] # short first column cols += [KeyColumn(keys=[small_key] * num_rows) for _ in range(num_cols-1)] lightcycle.right_half.add_columns(cols) thumb_cluster = ThumbCluster(style='dactyl') thumb_cols = [ KeyColumn(keys=[small_key]*3), KeyColumn(keys=[small_key, big_key]), KeyColumn(keys=[big_key]), ] # TODO: Do we need a way to communicate how the thumb columns are aligned? """ [x][x] [x]| || | [x]|_||_| """ thumb_cluster.add_columns(thumb_cols) lightcycle.right_half.set_thumb_cluster(thumb_cluster) lightcycle.left_half = lightcycle.right_half.copy(mirror=True) sl.scad_render_to_file(lightcycle.solid(), "lightcycle.scad")
def main(filename): """ Main function to - load and calibrate the event from simtel file - pass the selected event to create array: - camera + event - telescope structure - tel id (w/o data_after_cleaning: Red (Y) or Green (N)) - add MC cross on ground - add ground ref frame :return: the full array plus the MC cross on ground and reference frame + grid for xy-plane """ array = union() event = load_calibrate(filename) # array.add(telescope_camera_event(event=event)) array.add(tilted_grid(event=event, tel_pos=False, zen_az_arrows=True)) array.add(ground_grid(event=event, tel_pos=False)) array = array + mc_details(event=event) file_out = 'ground.scad' scad_render_to_file(array, file_out)
def plane_render_all3D(self,callmode,config): """Render all parts in the Plane""" self.modeconfig=milling.mode_config[callmode] self.make_copies() config=copy.copy(self.modeconfig) if(self.modeconfig['overview']==False): for thepart in self.getParts(False): if not (hasattr(thepart, 'subpart') and thepart.subpart): self.render_part3D(thepart,config) else: scene = False for thepart in self.getParts(True): if not (hasattr(thepart, 'subpart') and thepart.subpart): self.make_part3D(thepart, config) if scene==False: scene = solid.part()(thepart.border3D) else: scene += solid.part()(thepart.border3D) solid.scad_render_to_file(scene, 'Overview.scad', include_orig_code=False)
def plane_render_all3D(self,callmode,config): """Render all parts in the Plane""" self.modeconfig=milling.mode_config[callmode] self.make_copies() config=copy.copy(self.modeconfig) if(self.modeconfig['overview']==False): for thepart in self.getParts(False): if not (hasattr(thepart, 'subpart') and thepart.subpart): self.render_part3D(thepart,config) else: scene = False for thepart in self.getParts(True): if not (hasattr(thepart, 'subpart') and thepart.subpart): self.make_part3D(thepart, config) if hasattr(thepart,"border3D"): if scene==False: scene = solid.part()(thepart.border3D) else: scene += solid.part()(thepart.border3D) solid.scad_render_to_file(scene, 'Overview.scad', include_orig_code=False)
def main(filename): """ Main function to - load and calibrate the event from simtel file - pass the selected event to create array: - camera + event - telescope structure - tel id (w/o data_after_cleaning: Red (Y) or Green (N)) - add MC cross on ground - add ground ref frame :return: the full array plus the MC cross on ground and reference frame + grid for xy-plane """ array = union() event = load_calibrate(filename) array.add(telescope_camera_event(event=event)) array = array + mc_details(event=event) # dimension, origin and label of reference arrow ref_arr = ref_arrow_3d(2000, origin=(1000, 1000, 0), label={ 'x': "x_gnd = NORTH", 'y': "y_gnd = WEST", 'z': "z_gnd" }) array = array + ref_arr if "Paranal" in filename: site = "Paranal" elif "palma" in filename: site = "LaPalma" else: site = "nosite" file_out = 'basic_geometry_4LST_' + site + '.scad' scad_render_to_file(array, file_out)
def main(): config = configparser.ConfigParser() config.read('default_config.ini') # intermediates_dir = Path(__file__).resolve().parent.parent / 'intermediates' intermediates_dir = Path(__file__).resolve().parent / 'intermediates' intermediates_dir.mkdir(exist_ok=True) # key switch socket socket = CherryMXSocket(config['socket']) socket.to_file(intermediates_dir / 'socket.scad') # keycap keycaps = [] for r in range(1, 5): keycap = OEM(r, 1) keycap.translate(0, 19 * (4 - r), 0) keycaps.append(keycap) keycapsolid = sl.part() for key in keycaps: keycapsolid += key.solid() keycap_output = intermediates_dir / 'keycaps.scad' sl.scad_render_to_file(keycapsolid, keycap_output) # key_assy socket_aligned_keys = [] face_aligned_keys = [] for r in range(1, 5): socket_key = SocketAlignedKey(config['key_assy'], config['socket'], r) socket_key.translate(0, 19 * (4 - r), 0) socket_aligned_keys.append(socket_key) face_key = FaceAlignedKey(config['key_assy'], config['socket'], r) face_key.translate(0, 19 * (4 - r), 0) face_aligned_keys.append(face_key) key_solid = sl.part() for key in socket_aligned_keys: key_solid += key.solid() socket_aligned_keys_output = intermediates_dir / 'socket_aligned_keys.scad' sl.scad_render_to_file(key_solid, socket_aligned_keys_output) key_solid = sl.part() for key in face_aligned_keys: key_solid += key.solid() face_aligned_keys_output = intermediates_dir / 'face_aligned_keys.scad' sl.scad_render_to_file(key_solid, face_aligned_keys_output) curved_column = ConcaveOrtholinearColumn(config['column'], config['key_assy'], config['socket']) curved_column.to_file(intermediates_dir / 'curved_column.scad') keyboard = DactylManuform(config['keyboard'], config['column'], config['key_assy'], config['socket']) keyboard.to_file(intermediates_dir / 'keyboard.scad')
def main(out_dir): # Parameters height_ratio = 0.25 left_loc = ONE_THIRD midpoint_loc = 0.5 right_loc = 2 * ONE_THIRD gens = 5 # Results all_polys = union() # setup ax, ay = 0, 0 bx, by = 100, 0 cx, cy = 50, 86.6 base_seg1 = LineSegment2(Point2(ax, ay), Point2(cx, cy)) base_seg2 = LineSegment2(Point2(cx, cy), Point2(bx, by)) base_seg3 = LineSegment2(Point2(bx, by), Point2(ax, ay)) generations = [[base_seg1, base_seg2, base_seg3]] # Recursively generate snowflake segments for g in range(1, gens): generations.append([]) for seg in generations[g - 1]: generations[g].extend( kochify(seg, height_ratio, left_loc, midpoint_loc, right_loc)) # # Put all generations into SCAD orig_length = abs(generations[0][0]) for g, a_gen in enumerate(generations): points = [s.p1 for s in a_gen] # Just use arrays for points so SCAD understands points = [[p.x, p.y] for p in points] # Move each generation up in y so it doesn't overlap the others h = orig_length * 1.5 * g # Do the SCAD edges = [list(range(len(points)))] all_polys.add(forward(h)(polygon(points=points, paths=edges))) file_out = scad_render_to_file(all_polys, out_dir=out_dir, include_orig_code=True) print(f"{__file__}: SCAD file written to: {file_out}")
def matrix2render(threeDimensionalMatrix): distance = 15 cube_size = 1 figure = cube([0.1, 0.1, 0.1], center=True) for matrix_i in range(len(threeDimensionalMatrix)): for row_i in range(len(threeDimensionalMatrix[matrix_i])): for cube_i in range(len(threeDimensionalMatrix[matrix_i][row_i])): if threeDimensionalMatrix[matrix_i][row_i][cube_i] == 1: new_cube = right(matrix_i * cube_size)(cube( [cube_size, cube_size, cube_size], center=True)) new_cube = up(row_i * cube_size)(new_cube) new_cube = forward(cube_i * cube_size)(new_cube) figure += new_cube SEGMENTS = 48 file_out = scad_render_to_file(figure) print(f"{__file__}: SCAD file written to: \n{file_out}")
def main(): fn = 200 os.makedirs("generated", exist_ok=True) scad_render_to_file( ipadminiholderfront().set_modifier("") + ipadminiholderback(), filepath="generated/iPadMiniHolder-preview.scad", file_header=f"$fn = {fn};\n", ) scad_render_to_file( ipadminiholderfront(), filepath="generated/iPad-Mini-Holder-Front.scad", file_header=f"$fn = {fn};\n", ) scad_render_to_file( ipadminiholderback(), filepath="generated/iPad-Mini-Holder-Back.scad", file_header=f"$fn = {fn};\n", )
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)
#button def button(): square = up(10.5)(cube([6, 6, 3], True)) cylinderbutton = up(2.5)(cylinder(r=2, h=5, center=True)) return down(5)(square) + cylinderbutton # d = cube(1) + right(5)(sphere(5)) - cylinder(r=2, h=6) def final(): return down(1)(block()) \ - left(y / 2)( \ right(21)(down(5.5)(usbconn())) \ + right(4)(down(2)(button())) \ + right(14)(arduino()) \ ) #render scad_render_to_file(final(), 'out_file.scad') # scad_render_to_file(pinhole, 'out_file.scad') # scad_render_to_file(usbconn, 'out_file.scad') # scad_render_to_file(arduino(), 'out_file.scad') # scad_render_to_file(dupont, 'out_file.scad') # scad_render_to_file(smds, 'out_file.scad') # scad_render_to_file(button, 'out_file.scad') # scad_render_to_file(block, 'out_file.scad')
from . import big_box from . import drawers from . import dimensions import solid from solid import utils def assembly(): box = big_box.assembly() box = utils.color('blue')(box) bottom_drawer = utils.up(1)(utils.right(1)(drawers.assembly())) bottom_drawer = utils.color('red')(bottom_drawer) top_drawer = utils.right(1)(utils.up((dimensions.box_x / 4) - 1)( drawers.assembly())) top_drawer = utils.color('green')(top_drawer) middle_spacer = solid.cube([dimensions.box_x, 1, 1.5]) middle_spacer = utils.up((dimensions.box_z / 2) - 0.5)(middle_spacer) middle_spacer = utils.right(0.5)(middle_spacer) middle_spacer = utils.color('blue')(middle_spacer) monitor_stand = box + bottom_drawer + top_drawer + middle_spacer return monitor_stand if __name__ == "__main__": monitor_stand = assembly() solid.scad_render_to_file(monitor_stand, 'assembly.scad')
def render(suffix, final): suffix += '.scad' s.scad_render_to_file(final, __file__.replace('.py', suffix))
parser.add_argument( "-o", "--output", metavar="FILE", type=str, default=None, help="the name of the file to write to", ) args = parser.parse_args() filepath = join( dirname(dirname(abspath(__file__))), "files", args.output or f"key_grid_tester_{args.length}x{args.width}.scad", ) print(f"Writing {args.length}x{args.width} key tester frame to {filepath} . . .") scad_render_to_file( key_grid_tester( args.length, args.width, wall_height=args.height, margin_length=args.margin_length, margin_width=args.margin_width, ), filepath=filepath, include_orig_code=True, )
screw_head_radius = 4 screw_rad = 2 screw_length = 10 head_hole_height = spacer_height - screw_length body = s.cube(size=[spacer_depth, spacer_width, spacer_height]) slot = u.up(3)(s.cube(size=[spacer_depth, 10, 2])) slot_round = u.back(1)(u.up(2)( s.rotate(a=spacer_height, v=[1, 0, 0])( s.cube(size=[spacer_depth, 4, 4]) ) )) screw_hole = u.forward(5)( s.cylinder(r=screw_head_radius, h=head_hole_height, segments=32) + u.up(head_hole_height)( s.cylinder(r=screw_rad, h=screw_length, segments=32) ) ) screw_hole_1 = u.right(screw_offset)(screw_hole) screw_hole_2 = u.right(spacer_depth - screw_offset)(screw_hole) wire_run = u.up(20)(s.cube(size=[spacer_depth, 4, 9])) final = body - slot - slot_round - screw_hole_1 - screw_hole_2 - wire_run s.scad_render_to_file(final, __file__.replace('.py', '.scad'))
def main(): # scad_render_to_file(battery_cup(), 'battery_cup.scad') # scad_render_to_file(coffee_cover(85 * mm), 'coffee_cover.scad') scad_render_to_file(coffee_cover(95 * mm), 'coffee_cover.scad')
def render_shim(label, thickness): scad_render_to_file(unistrut_shim(thickness), f'unistrut_shim_{label}.scad')
h=15, center=True), cylinder(r=4, h=16, center=True)))) # Right piece uses a more Pythonic grammar. + (plus) is equivalent to union(), # - (minus) is equivalent to difference() and * (star) is equivalent to intersection # solid.utils also defines up(), down(), left(), right(), forward(), and back() # for common transforms. right_piece = right(15)(cube([10, 5, 3], center=True)) cyl = cylinder(r=5, h=15, center=True) - cylinder(r=4, h=16, center=True) right_piece += right(10)(cyl) return union()(left_piece, right_piece) if __name__ == '__main__': out_dir = sys.argv[1] if len(sys.argv) > 1 else None a = basic_geometry() # Adding the file_header argument as shown allows you to change # the detail of arcs by changing the SEGMENTS variable. This can # be expensive when making lots of small curves, but is otherwise # useful. file_out = scad_render_to_file(a, out_dir=out_dir, file_header=f'$fn = {SEGMENTS};') print(f"{__file__}: SCAD file written to: \n{file_out}")
v.screw_length = s.var(10, comment='Length of thread to be inside spacer.', end_comment='[3:45]') v.head_hole_height = s.var('spacer_height - screw_length') body = s.cube(size=[spacer_depth, spacer_width, v.spacer_height]) slot = u.up(3)(s.cube(size=[spacer_depth, 10, 2])) slot_round = u.back(1)(u.up(2)( s.rotate(a=v.spacer_height, v=[1, 0, 0])( s.cube(size=[spacer_depth, 4, 4]) ) )) screw_hole = u.forward(5)( s.cylinder(r=v.screw_head_radius, h=v.head_hole_height, segments=32) + u.up(v.head_hole_height)( s.cylinder(r=v.screw_radius, h=v.screw_length, segments=32) ) ) screw_hole_1 = u.right(screw_offset)(screw_hole) screw_hole_2 = u.right(screw_offset_2)(screw_hole) wire_run = u.up(20)(s.cube(size=[spacer_depth, 4, 9])) final = body - slot - slot_round - screw_hole_1 - screw_hole_2 - wire_run s.scad_render_to_file(final, __file__.replace('.py', '.scad'), variables=v)
def main(): base = make_base() pole = make_pole() top = make_top() final_obj = base + pole + top solid.scad_render_to_file(final_obj, "model.scad")
sta = spu.forward(depth - thickness)(sta) obj += (spu.up(height / 2)(sta) - ha) if (half and topbox): window = sp.cube( [width - 2 * thickness, thickness, height / 2 - 1.5 * thickness]) window = sp.translate([thickness, 0, thickness])(window) obj += spu.up(height / 2 - thickness / 2)(window) return obj def main(): obj = sp.part() obj += box(600, 600, 200, True, False) return obj if __name__ == "__main__": import os import sys out_dir = sys.argv[1] if len(sys.argv) > 1 else os.curdir file_out = os.path.join(out_dir, 'box.scad') obj = main() print("%(__file__)s: SCAD file written to: \n%(file_out)s" % vars()) sp.scad_render_to_file(obj, file_out, file_header='$fn = %s;' % SEGMENTS, include_orig_code=True)
def save(self, file): # Add screws screw_head_radius = 3.0 screw_head_length = 2.5 screw_shaft_radius = 1.40 # 2.8mm diameter = 0.3mm extra screw_shaft_length = 15.0 head = sc.translate([0,0,screw_shaft_length])( sc.cylinder(h=screw_head_length + 100, r=screw_head_radius, segments=self._round_segments) ) shaft = sc.cylinder(h=screw_shaft_length + 0.1, r=screw_shaft_radius, segments=self._round_segments) screw_down = sc.translate([0,0,-screw_shaft_length - screw_head_length])( sc.union()(head,shaft) ) # Origin is top of screw screw_side = sc.rotate([0,90,0])(screw_down) sc.scad_render_to_file(screw_side, "screw.scad", include_orig_code=False) # Place 4 screws in the right side screw_recess_side = 1.0 assert screw_recess_side < self._thickness_xy side_thick = self._thickness_xy - self._board_slot ymin = self._board_bbox.bot() - self._board_slot - side_thick/2.0 ymax = self._board_bbox.top() + self._board_slot + side_thick/2.0 zmin = -self.cavity_bot - self._thickness_z + screw_head_radius + self._min_screw_material zmax = self.cavity_top - self._thickness_z - screw_head_radius x = self._board_bbox.right() + self._thickness_xy + 1.0 # Add screws to the side for y in [ymin, ymax]: for z in [zmin, zmax]: self._case -= sc.translate([x,y,z])(screw_side) print "Free material around side screws: {0}mm".\ format(self._thickness_xy - self._board_slot - 2*screw_shaft_radius) # Add screws to the top screw_recess_top = 0 assert screw_recess_top < self._thickness_z min_screw_depth = 3.0 #Lowest depth screw can possibly go zmin = self.cavity_top + screw_head_length + min_screw_depth z_want = self.cavity_top + self._thickness_z - screw_recess_top z = max(zmin, z_want) ys = [self._board_bbox.top() + self._board_slot + (self._thickness_xy - self._board_slot)/2.0, self._board_bbox.bot() - self._board_slot - (self._thickness_xy - self._board_slot)/2.0] xs = [self._board_bbox.left() + screw_head_radius, self._board_bbox.right() - screw_shaft_length - 1.0] for y in ys: for x in xs: self._case -= sc.translate([x,y,z])(screw_down) #Top area: top of the case top_area_select = self._board_bbox.copy().pad(self._thickness_xy*2) top_area_select = rect2scad(top_area_select, self._thickness_z + 0.1, self.cavity_top - 0.05) # main_area is the case without the top or side main_area = self._board_bbox.copy() main_area.bounds[0][0] -= self._thickness_xy*2 main_area.bounds[0][1] -= self._thickness_xy*2 main_area.bounds[1][0] -= 0.05 #So we don't have a degenerate face main_area.bounds[1][1] += self._thickness_xy*2 main_area = rect2scad(main_area, self.height * 2, z_start = -self.height - 10) #Add screws to hold down the board remove_top = self._board_bbox.copy().pad(self._thickness_xy*2) remove_top = rect2scad(remove_top, self.height, self.cavity_top + 0.05) x = self._board_bbox.left() + (self._board_bbox.width + self._board_slot*2)/2.0 ys = [self._board_bbox.bot() - screw_shaft_radius - 0.5, self._board_bbox.top() + screw_shaft_radius + 0.5] z = screw_head_length for y in ys: self._case -= (sc.translate([x,y,z])(screw_down) - remove_top) print "Board screw location: ({0}, {1})".format(x,y) # Separate out the sides of the case main_part = self._case * main_area side = self._case - (main_area + top_area_select) # Side of the case, first part to screw on #The top of the case (screwed on after the side) top = self._case * top_area_select main_part -= top_area_select sc.scad_render_to_file(top, "top." + file, include_orig_code=False) sc.scad_render_to_file(main_part, "main." + file, include_orig_code=False) sc.scad_render_to_file(side, "side." + file, include_orig_code=False) exploded = sc.union()( main_part, sc.translate([40,0,0])(side), sc.translate([0,0,40])(top) ) sc.scad_render_to_file(exploded, "exploded." + file, include_orig_code=False) sc.scad_render_to_file(self._case, file, include_orig_code=False)