def make(self): cone_radius = self.diameter / 2 cone_height = cone_radius # to achieve a 45deg angle cylinder_radius = cone_radius - self.chamfer cylinder_height = self.height shaft_radius = (self.diameter / 2.) - self.height cone = cadquery.Workplane("XY").union( cadquery.CQ(cadquery.Solid.makeCone(0, cone_radius, cone_height)) \ .translate((0, 0, -cone_height)) ) cylinder = cadquery.Workplane("XY") \ .circle(cylinder_radius).extrude(-cylinder_height) head = cone.intersect(cylinder) # Raised bubble (if given) if self.raised: sphere_radius = ((self.raised**2) + (cylinder_radius**2)) / (2 * self.raised) sphere = cadquery.Workplane("XY").workplane(offset=-(sphere_radius - self.raised)) \ .sphere(sphere_radius) raised_cylinder = cadquery.Workplane("XY").circle( cylinder_radius).extrude(self.raised) from Helpers import show raised_bubble = sphere.intersect(raised_cylinder) head = head.union(raised_bubble) # Bugle Head if self.bugle and (0 <= self.bugle_ratio < 1.0): # bugle_angle = angle head material makes with chamfer cylinder on top bugle_angle = (pi / 4) * self.bugle_ratio # face_span = longest straight distance along flat conical face (excluding chamfer) face_span = sqrt(2) * (( (self.diameter / 2.) - self.chamfer) - shaft_radius) r2 = (face_span / 2.) / sin((pi / 4) - bugle_angle) d_height = r2 * sin(bugle_angle) r1 = (r2 * cos(bugle_angle)) + shaft_radius torus = cadquery.Workplane("XY").union( cadquery.CQ( cadquery.Solid.makeTorus( r1, r2, # radii pnt=FreeCAD.Base.Vector(0, 0, 0), dir=FreeCAD.Base.Vector(0, 0, 1), angleDegrees1=0., angleDegrees2=360.)).translate( (0, 0, -(self.height + d_height)))) head = head.cut(torus) return head
def make_top(self, x, y): s = self co = "CenterOfBoundBox" # calcs top_z = s.total_z - s.bottom_z glass_pocket_xy = s.glass_dim + s.glass_pocket_xy_fudge pedistal_pocket_xy = s.pedestal_xy + s.pedistal_pocket_xy_fudge center_lane_width_o = s.scratch_tool_width_o + s.scratch_tool_width_fudge center_lane_width_c = s.scratch_tool_width_c + s.scratch_tool_width_fudge dowel_clearance_d = s.dowel_nominal_d + s.dowel_clearance_fudge thickness_remaining_under_slot = s.worst_case_glass_thickness + s.pedestal_z outer_guide_array_spacing_o = s.outer_guide_spacing_o + center_lane_width_o outer_guide_array_spacing_c = s.outer_guide_spacing_c + center_lane_width_c t = cq.CQ().box(x, y, top_z, centered=(True, True, False)).val().Solids()[0] t = cq.CQ().add(t).faces("<Z[-1]").workplane(centerOption=co).rect( pedistal_pocket_xy, pedistal_pocket_xy).cutBlind( -s.pedestal_z).val().Solids()[0] # cut indent for pedistal t = cq.CQ().add(t).faces("<Z[-2]").workplane(centerOption=co).rect( glass_pocket_xy, glass_pocket_xy).cutBlind( -(s.worst_case_glass_thickness + s.glass_thickness_margin) ).val().Solids()[0] # cut pocket glass lives in t = cq.CQ().add(t).faces("<Z[-3]").workplane(centerOption=co).rect( s.safe_step_xy, s.safe_step_xy).cutBlind(-s.safe_step_z).val().Solids()[ 0] # cut tiny step to protect device surface t = cq.CQ().add(t).faces(">Z[-1]").workplane(centerOption=co).rarray( s.glass_dim + s.dowel_nominal_d + s.nominal_glass_pin_play, 2 * s.dowel_offset_from_center1, 2, 2).hole(dowel_clearance_d).val().Solids()[ 0] # cut clearance fit dowel pin holes t = cq.CQ().add(t).faces(">Z[-1]").workplane( centerOption=co).transformed(rotate=(0, 0, 90)).rarray( s.glass_dim + s.dowel_nominal_d + s.nominal_glass_pin_play, 2 * s.dowel_offset_from_center2, 2, 2).hole(dowel_clearance_d).val().Solids()[ 0] # cut clearance fit dowel pin holes t = cq.CQ().add(t).faces(">Z[-1]").workplane(centerOption=co).rarray( outer_guide_array_spacing_o, 1, 2, 1).rect(center_lane_width_o, y).cutBlind(-(top_z - thickness_remaining_under_slot)).val( ).Solids()[0] # cut the outer slots t = cq.CQ().add(t).faces(">Z[-1]").workplane(centerOption=co).rarray( outer_guide_array_spacing_c, 1, 1, 1).rect(center_lane_width_c, y).cutBlind(-(top_z - thickness_remaining_under_slot)).val( ).Solids()[0] # cut the central slot twp = cq.CQ().add(t) twp.faces("<Z[-1]").tag("top_mate") return twp
def make(self, offset=(0, 0, 0)): r1 = self.diameter / 2. r2 = self.diameter_top / 2. head = cadquery.Workplane("XY").union( cadquery.CQ(cadquery.Solid.makeCone(r1, r2, self.height))) return head.translate(offset)
def make(self): # cone radii cone_radius_at = lambda z: self.roller_surface_radius + ( self.roller_surface_gradient * z) cone_radius_base = cone_radius_at(self.base_height) cone_radius_top = cone_radius_at(self.base_height + self.height) # ring base shape outer_ring = cadquery.Workplane('XY', origin=(0, 0, self.base_height)) \ .circle(self.outer_diam / 2).extrude(self.height) # cut cone from base shape (provides conical rolling surface) if abs(self.roller_surface_gradient) > 1e-6: cone = cadquery.CQ( cadquery.Solid.makeCone( radius1=cone_radius_base, radius2=cone_radius_top, height=self.height, dir=cadquery.Vector(0, 0, 1), )).translate((0, 0, self.base_height)) outer_ring = outer_ring.cut(cone) else: outer_ring = outer_ring.faces('>Z') \ .circle(self.roller_surface_radius).cutThruAll() return outer_ring
def make(self): cone_radius_at = lambda z: self.roller_surface_radius + ( self.roller_surface_gradient * z) cone_radius_base = cone_radius_at(self.base_height) cone_radius_top = cone_radius_at(self.base_height + self.height) # ring base shape inner_ring = cadquery.Workplane('XY', origin=(0, 0, self.base_height)) \ .circle(max(cone_radius_base, cone_radius_top)) \ .circle(self.inner_diam / 2) \ .extrude(self.height) # intersect cone with base shape (provides conical rolling surface) if abs(self.roller_surface_gradient) > 1e-6: cone = cadquery.CQ( cadquery.Solid.makeCone( radius1=cone_radius_base, radius2=cone_radius_top, height=self.height, dir=cadquery.Vector(0, 0, 1), )).translate((0, 0, self.base_height)) inner_ring = inner_ring.intersect(cone) return inner_ring
def make_bottom(self, x, y): s = self co = "CenterOfBoundBox" # calcs dowel_press_d = s.dowel_nominal_d + s.dowel_press_fudge b = cq.CQ().box(x, y, s.bottom_z, centered=(True, True, False)).val().Solids()[0] b = cq.CQ().add(b).faces(">Z[-1]").workplane(centerOption=co).rect( s.pedestal_xy, s.pedestal_xy).extrude( s.pedestal_z).val().Solids()[0] # extrude substrate pedistal b = cq.CQ().add(b).faces(">Z[-1]").workplane(centerOption=co).rect( s.safe_step_xy, s.safe_step_xy).cutBlind(-s.bottom_safe_step_z).val().Solids()[ 0] # cut tiny step under substrate b = cq.CQ().add(b).faces("<Z[-1]").workplane(centerOption=co).rarray( s.glass_dim + s.dowel_nominal_d + s.nominal_glass_pin_play, 2 * s.dowel_offset_from_center1, 2, 2).hole(dowel_press_d).val().Solids()[ 0] # cut press fit dowel pin holes b = cq.CQ().add(b).faces("<Z[-1]").workplane( centerOption=co).transformed(rotate=(0, 0, 90)).rarray( s.glass_dim + s.dowel_nominal_d + s.nominal_glass_pin_play, 2 * s.dowel_offset_from_center2, 2, 2).hole(dowel_press_d).val().Solids()[ 0] # cut press fit dowel pin holes b = cq.CQ().add(b).faces("<Z[-1]").workplane(centerOption=co).rect( s.centerpunch_xy, s.centerpunch_xy).cutThruAll().val().Solids()[0] # cut window bwp = cq.CQ().add(b) bwp.faces("<Z[-2]").tag("bottom_mate") return bwp
def _singlePad(pnt): pnt += Vec(-D * 0.5, -E * 0.5, 0) pad = cq.CQ(cq.Solid.makeBox(D, E, c, pnt)) if tc > 0: if tr > 0: pad.edges(_s("|Z") - s_topleft).fillet(tr) pad.edges(s_topleft).chamfer(tc) elif tr > 0: pad.edges("|Z").fillet(tr) return pad.objects[0]
def get_ball_torus(cls, rolling_radius, ball_radius): return cadquery.Workplane("XY").union( cadquery.CQ(cadquery.Solid.makeTorus( rolling_radius, ball_radius, # radii pnt=cadquery.Vector(0,0,0).wrapped, dir=cadquery.Vector(0,0,1).wrapped, angleDegrees1=0., angleDegrees2=360., )) )
def make(self): points = self.get_cross_section_points() head = cadquery.Workplane("XY") \ .polyline(points).close() \ .extrude(self.height) if self.chamfer: cone_height = ((self.diameter / 2.) - self.chamfer) + self.height cone_radius = (self.diameter / 2.) + (self.height - self.chamfer) if self.chamfer_top: cone = cadquery.Workplane('XY').union( cadquery.CQ( cadquery.Solid.makeCone( cone_radius, 0, cone_height, pnt=cadquery.Vector(0, 0, 0), dir=cadquery.Vector(0, 0, 1), ))) head = head.intersect(cone) if self.chamfer_base: cone = cadquery.Workplane('XY').union( cadquery.CQ( cadquery.Solid.makeCone( cone_radius, 0, cone_height, pnt=cadquery.Vector(0, 0, self.height), dir=cadquery.Vector(0, 0, -1), ))) head = head.intersect(cone) # Washer if self.washer: washer = cadquery.Workplane("XY") \ .circle(self.washer_diameter / 2) \ .extrude(self.washer_height) head = head.union(washer) return head
def make_cutter(self): """ Add countersunk cone to cutter """ obj = super(CounterSunkFastenerHead, self).make_cutter() cone = cadquery.CQ(cadquery.Solid.makeCone( radius1=self.diameter / 2, radius2=0, height=self.height, dir=cadquery.Vector(0,0,-1), )) return obj.union(cone)
def display(*cadObjs, height=400, ortho=True, fov=0.2, debug=False, default_color=None): """ Jupyter 3D representation support """ if default_color is None: default_color = (0.9, 0.9, 0.9) def _display(cadObj): html = x3d_display(cadObj, export_edges=True, height=height, ortho=ortho, fov=fov, debug=debug) IPython.display.display(IPython.display.HTML(html)) if len(cadObjs) == 1: cadObj = cadObjs[0] else: cadObj = cq_jupyter.Assembly( [cq_jupyter.convert(cadObj) for cadObj in cadObjs]) if isinstance(cadObj, cadquery.Shape): part = cq_jupyter.Part(cadquery.CQ(cadObj), color=default_color) _display(cq_jupyter.Assembly([part])) elif isinstance(cadObj, cadquery.Workplane): part = cq_jupyter.Part(cadObj, color=default_color) _display(cq_jupyter.Assembly([part])) elif isinstance(cadObj, cq_jupyter.Assembly): _display(cadObj) elif isinstance(cadObj, (cq_jupyter.Part, cq_jupyter.Edges, cq_jupyter.Faces)): _display(cq_jupyter.Assembly([cadObj])) elif has_cqparts and isinstance(cadObj, cqparts.Assembly): cadObj.world_coords = CoordSystem() assembly = convertCqparts(cadObj) display(assembly) elif has_cqparts and isinstance(cadObj, cqparts.Part): part = cq_jupyter.Part(cadObj.local_obj, color=default_color) display(part) else: return cadObj
def export_function(button): 'executes export of user selected filetype, only on button press' filename = mkui.export_filename.value filetype = mkui.export_filetype.value fullname = filename + '.' + filetype if filetype == 'STEP': mkui.new_model.shape.findSolid().scale(final_scale).exportStep(fullname) if filetype == 'STL': mkui.new_model.shape.findSolid().scale(final_scale).wrapped.exportStl(fullname) elif filetype == 'JSON': cqgen(mkui.new_model.shape.findSolid().scale(final_scale), name=filename) elif filetype == 'SVG': cq.CQ(mkui.new_model.shape.findSolid().scale(final_scale)).exportSvg(fullname) else: print 'nothing exported, sorry' print 'exported model as: ' + fullname
def make(self): head = super(RoundFastenerHead, self).make() # Add chamfered square block beneath fastener head if self.coach_head: cone_radius = ((self.coach_width / 2.) + self.coach_height) - self.coach_chamfer cone_height = cone_radius box = cadquery.Workplane("XY").rect( self.coach_width, self.coach_width).extrude(-self.coach_height) cone = cadquery.Workplane("XY").union( cadquery.CQ(cadquery.Solid.makeCone(0, cone_radius, cone_height)) \ .translate((0, 0, -cone_height)) ) head = head.union(box.intersect(cone)) return head
def make(self): cone_radius_at = lambda z: self.radius + (self.gradient * z) cone_radius_base = cone_radius_at(self.base_height) cone_radius_top = cone_radius_at(self.base_height + self.height) # intersect cone with base shape (provides conical rolling surface) if abs(self.gradient) > 1e-6: roller = cadquery.CQ( cadquery.Solid.makeCone( radius1=cone_radius_base, radius2=cone_radius_top, height=self.height, dir=cadquery.Vector(0, 0, 1), )).translate((0, 0, self.base_height)) else: roller = cadquery.Workplane('XY', origin=(0, 0, self.base_height)) \ .circle(self.radius).extrude(self.height) return roller
import cadquery as cq # need for reload import importlib #import cqgdml import cqgdml importlib.reload(cqgdml) from cqgdml import * from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox ret = cq.CQ(BRepPrimAPI_MakeBox(100., 100., 100.).Shape()) show_object(ret) #show_object(v.shape2show()) #v.exportVol("/tmp/file.gdml")
def ring(inner_radius, outer_radius, width): ring = (cq.Workplane( origin=(0, 0, -width / 2)).circle(outer_radius).circle(inner_radius).extrude(width)) return ring tol = 0.05 ball_diam = 5 r1, r2, r3, r4 = 4, 6, 8, 10 r5 = (r3 + r2) / 2 inner_ring = ring(r1, r2, ball_diam) outer_ring = ring(r3, r4, ball_diam) torus = cq.CQ(cq.Solid.makeTorus(r5, ball_diam / 2 + tol)) ball = cq.Workplane().sphere(ball_diam / 2) inner = inner_ring.cut(torus) outer = outer_ring.cut(torus) # Assembly number_balls = 6 balls = ["ball_%d" % i for i in range(number_balls)] def create_bearing(): L = lambda *args: cq.Location(cq.Vector(*args)) C = lambda *args: cq.Color(*args)
#reload(Ex024_Using_FreeCAD_Solids_as_CQ_Objects) #You'll need to delete the original shape that was created, and the new shape should be named sequentially (Shape001, etc). #You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access. #You can get a more information on this example at http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid import cadquery, FreeCAD, Part #Create a new document that we can draw our modle on newDoc = FreeCAD.newDocument() #shows a 1x1x1 FreeCAD cube in the display initialBox = newDoc.addObject("Part::Box", "initialBox") newDoc.recompute() #Make a CQ object cqBox = cadquery.CQ(cadquery.Solid(initialBox.Shape)) #Extrude a peg newThing = cqBox.faces(">Z").workplane().circle(0.5).extrude(0.25) #Add a FreeCAD object to the tree and then store a CQ object in it nextShape = newDoc.addObject("Part::Feature", "nextShape") nextShape.Shape = newThing.val().wrapped #Rerender the doc to see what the new solid looks like newDoc.recompute() #Would like to zoom to fit the part here, but FreeCAD doesn't seem to have that scripting functionality
def make(self): # build Head obj = self.head.make() # (screw drive indentation is made last) # build neck (inner_radius, outer_radius) = self.thread.get_radii() if self.neck_length: # neck neck = cadquery.Workplane( 'XY', origin=(0, 0, -self.neck_length)).circle( self.neck_diam / 2).extrude(self.neck_length) obj = obj.union(neck) # neck -> taper to thread's inner radius taper_length = 0 if 0 < self.neck_taper < 90: taper_length = ((self.neck_diam / 2) - inner_radius) / tan( radians(self.neck_taper)) if taper_length > 0: neck_taper = cadquery.Workplane("XY").union( cadquery.CQ( cadquery.Solid.makeCone( radius1=(self.neck_diam / 2), radius2=inner_radius, height=taper_length, dir=cadquery.Vector(0, 0, -1), )).translate((0, 0, -self.neck_length))) obj = obj.union(neck_taper) # build thread thread = self.thread.local_obj.translate((0, 0, -self.length)) obj = obj.union(thread) # Sharpen to a point if self.tip_length: # create "cutter" tool shape tip_cutter = cadquery.Workplane('XY').box( (outer_radius * 2) + 10, (outer_radius * 2) + 10, self.tip_length, centered=(True, True, False), ) tip_template = cadquery.Workplane("XY").union( cadquery.CQ( cadquery.Solid.makeCone( radius1=(self.tip_diameter / 2), radius2=outer_radius, height=self.tip_length, dir=cadquery.Vector(0, 0, 1), ))) tip_cutter = tip_cutter.cut(tip_template) # move & cut obj.cut(tip_cutter.translate((0, 0, -self.length))) # apply screw drive (if there is one) if self.drive: obj = self.drive.apply( obj, world_coords=CoordSystem(origin=self.head.get_face_offset())) return obj
def lid(assembly, include_hardware=False): """Create lid of sample chamber.""" hardware = cq.Assembly(None) bolts_sink_depth = chamber_nut.nut_thickness - support_h # create lid plate lid = cq.Workplane("XY").box(chamber_l, chamber_w, lid_h) # make the socket clearance ears on the corners lid = lid.faces(">Z").rect(chamber_l, chamber_w, forConstruction=True).vertices().rect(m5_socket_clearance + chamber_bolt_offset * 2, chamber_bolt_offset * 2, centered=True).cutBlind(-bolts_sink_depth) lid = lid.faces(">Z").rect(chamber_l, chamber_w, forConstruction=True).vertices().rect(chamber_bolt_offset * 2, m5_socket_clearance + chamber_bolt_offset * 2, centered=True).cutBlind(-bolts_sink_depth) lid = lid.faces(">Z").workplane().pushPoints(chamber_bolt_xys).circle(m5_socket_clearance / 2).cutBlind(-bolts_sink_depth) # make the bolt holes and put on the nuts lid = lid.faces(">Z").workplane(offset=-bolts_sink_depth).pushPoints(chamber_bolt_xys).clearanceHole(chamber_nut, counterSunk=False, baseAssembly=hardware) # cut m4 blind threaded holes for window support lid = ( lid.faces(">Z") .workplane(centerOption="CenterOfBoundBox") .pushPoints(support_bolt_xys) .hole( diameter=support_bolt.tap_hole_diameters["Soft"], depth=lid_h - lid_h_under_support_screw, ) ) # fillet corner side edges lid = lid.edges("|Z").fillet(chamber_fillet) # create and cut window o-ring groove groove = oring_groove( lid_oring_i_l, lid_oring_i_w, lid_oring_groove_h, lid_oring_groove_w, lid_oring_groove_r, ) groove = groove.translate((window_ap_x_offset, 0, (lid_h / 2 - lid_oring_groove_h / 2 - window_h))) # lid = lid.cut(groove) # we'll cut it below instead with the toolbox version of the groove cutter # cut aperture for light transmission window_ap = cq.Workplane("XY").box(window_ap_l, window_ap_w, lid_h).edges("|Z").fillet(window_ap_r).translate((window_ap_x_offset, 0, 0)) lid = lid.cut(window_ap) # cut window recess window_recess = drilled_corner_cube(window_recess_l, window_recess_w, window_h, window_recess_r) window_recess = window_recess.translate((window_ap_x_offset, 0, lid_h / 2 - window_h / 2)) lid = lid.cut(window_recess) # window if include_hardware is True: window = cq.Workplane().box(159, 170, window_h).translate((window_ap_x_offset, 0, lid_h / 2 - window_h / 2)) assembly.add(window, name="window") # cut o-ring groove cq.Workplane.mk_groove = tb.groovy.mk_groove # add in our groovemaker lid = cq.CQ(lid.findSolid()).faces(">Z[-3]").workplane(centerOption="CenterOfBoundBox") lid = lid.mk_groove(ring_cs=2.62, follow_pending_wires=False, ring_id=190.17, gland_x=151, gland_y=162, hardware=assembly) # BS169N70 standard # lid = lid.mk_groove(ring_cs=2, follow_pending_wires=False, ring_id=190, gland_x=151, gland_y=162) # polymax metric option: 190X2N70 assembly.add(lid, name="lid") if include_hardware is True: assembly.add(hardware.toCompound(), name="chamber_nuts") # missing nuts?