class GearWheel(cqparts.Part): """ This is a model gear wheel from Spintronics """ # Parameters gear_od = PositiveFloat(22, doc="O-ring tyre internal diameter") gear_thickness = PositiveFloat(1.5, doc="O-ring tyre thickness") spacer_od = PositiveFloat(6, doc="Spacer diameter") # give a bit of clearance spacer_thickness = PositiveFloat(10, doc="Space thickness/length") # default appearance _render = render_props(template='wood_dark') def make(self): # Outside face r = cadquery.Workplane("front").circle(self.spacer_od / 2).extrude( self.spacer_thickness) r = r.faces("<Z") \ .transformed(offset=(0, 0, (-self.gear_thickness + self.spacer_thickness)/2)) \ .circle((self.gear_od)/2).extrude(self.gear_thickness) return r def get_cutout(self, clearance=1): # A cylinder with a equal clearance on every face return cadquery.Workplane('XY', origin=(0, 0, -clearance)) \ .circle((self.diameter / 2) + clearance) \ .extrude(self.gear_thickness + (2 * clearance)) @property def width(self): """How much axle is required to extend out from the inside of the wheel to the outside in order for the wheel to fit nicely.""" return self.spacer_thickness @property def diameter(self): """Diameter of gear""" return self.gear_od @property def mate_centre(self): """Assumes rotating around Z axis""" return Mate( self, CoordSystem(origin=(0, 0, +self.width / 2), # xDir=(1, 0, 0), normal=(0, -1, 0), )) # default appearance _render = render_props(color=(240, 240, 240)) # Light grey
class YellowPipe(Printable): radius = PositiveFloat(1.5) leg1 = PositiveFloat(20) leg2 = PositiveFloat(20) turn = PositiveFloat(6) _render = render_props(color=(255, 255, 0)) _material = "yellow_abs" def make(self): leg1 = cq.Workplane("XY").circle(self.radius).extrude(self.leg1 - self.turn) corner = (cq.Workplane("XY").workplane( offset=self.leg1 - self.turn).circle(self.radius).revolve( angleDegrees=90, axisStart=(-self.turn, 1), axisEnd=(-self.turn, 2))) leg1 = leg1.union(corner) leg2 = (cq.Workplane("ZY").circle( self.radius).extrude(self.leg2 - self.turn - self.radius * 2).translate( (-self.turn, 0, self.leg1))) leg1 = leg1.union(leg2) return leg1 def cutout(self): return self.local_obj
class NutInsertTool(cqparts.Part): """This is a tool in push nuts into holes""" _render = render_props(template="yellow") def __init__(self, size="M3", clearance=-0.2, length=10): """Thanks https://www.fairburyfastener.com/xdims_metric_nuts.htm""" super(NutInsertTool, self).__init__() self.length = length self.size = size self.clearance = clearance def make(self): nut = Nut(size=self.size, clearance=self.clearance) # Calculate where to start in Y y = (self.length / 2.0) + (nut.od / 4) y2 = y - ((nut.od / 2.0) - (nut.od / 4)) x = nut.face_width / 2.0 points = [(x, 0), (x, y), (0, y2), (-x, y), (-x, -y), (x, -y), (x, 0)] r = (cadquery.Workplane("front").transformed( offset=(0, -self.length / 2.0, 0), rotate=(0, 0, 0)).polyline(points).close().extrude(nut.thickness)) r = r.union( cadquery.Workplane("front").transformed( offset=(0, -self.length, 0), rotate=(0, 0, 0)).circle(4).extrude(nut.thickness)) r = (r.faces("front").workplane().transformed( offset=(0, 5 - self.length / 2.0 - (nut.od / 3), 0)).hole(3) ) # Formula not quite right (centre of gravity?) return r
class _Stator(cqparts.Part): # Parameters width = PositiveFloat(40.0, doc="Motor Size") length = PositiveFloat(20, doc="stator length") cham = PositiveFloat(3, doc="chamfer") _render = render_props(color=(50, 50, 50)) def make(self): base = (cq.Workplane("XY").box( self.width, self.width, self.length, centered=(True, True, True)).edges("|Z").chamfer(self.cham)) return base @property def mate_top(self): " top of the stator" return Mate( self, CoordSystem(origin=(0, 0, self.length / 2), xDir=(0, 1, 0), normal=(0, 0, 1)), ) @property def mate_bottom(self): " bottom of the stator" return Mate( self, CoordSystem(origin=(0, 0, -self.length / 2), xDir=(1, 0, 0), normal=(0, 0, -1)), )
class Stepper_Holder(cqparts.Part): """ This is a holder for astandard 28BYJ-48 stepper motor """ # default appearance _render = render_props(color=(20, 20, 150)) # Parameters body_length = PositiveFloat(61, doc="Body length") motor_od = 28.5 def rod_block(self, workplane, offset): r = workplane.transformed(offset=(offset, 0, 0)).box(15, 15, self.body_length) return r def base_plate(self, workplane): r = workplane.transformed(offset=(-BAR_SEPERATION / 2, -6.5, 0)).box(BAR_SEPERATION, 2, self.body_length) return r def mounting_block(self, workplane, offset): r = workplane.transformed(offset=(offset, 13.5, 10)).box(15, 12, 30) return r def make(self): # Outside face r = self.rod_block(cadquery.Workplane("YZ"), 0) r = r.union(self.rod_block(r.faces(">X"), -BAR_SEPERATION)) r = r.union( self.mounting_block(r.faces(">X"), -20 + BAR_SEPERATION / 2)) r = r.union(self.mounting_block(r.faces(">X"), -BAR_SEPERATION)) r = r.union(self.base_plate(r.faces(">X"))) # add holes for bars r = r.faces(">X").workplane().transformed(offset=(0, 0.625, 0)).\ rect(BAR_SEPERATION, 0, forConstruction=True).vertices().hole(8.5) # cut out to fit motor r = r.faces(">Z").workplane().transformed(offset=(-2, 0, 0)).\ hole(self.motor_od) # add some holes for mounting nut inserts to hold motor in r = r.faces("<Z").workplane().transformed(offset=(9.5, 0, 0)).\ rect(0, 36, forConstruction=True).vertices().hole(3) # add some holes for mounting or zip ties r = r.faces("<Z").workplane().transformed(offset=(-10, 0, 0)).\ rect(10, 20, forConstruction=True).vertices().hole(3) #r = r.faces(">X").workplane().lineTo(0, BAR_SEPERATION, forConstruction=True).vertices().hole(11) return r # Construct mating points for two axes @property def mate_centre(self): return Mate( self, CoordSystem( origin=(-self.body_length / 2, -BAR_SEPERATION / 2, 0), xDir=(1, 0, 0), normal=(0, 0, 1), ))
class Belt(cqparts.Part): # Parameters rad = PositiveFloat(10) spacing = PositiveFloat(100) belt_width = PositiveFloat(5) belt_thickness = PositiveFloat(1) # default appearance _render = render_props(template="red") def profile(self): p = cq.Workplane("XZ").rect(self.belt_width, self.belt_thickness) return p def make(self): outer = self.profile().extrude(self.spacing).translate( (0, 0, -self.rad)) p2 = (self.profile().revolve(180, (2, self.rad), (1, self.rad)).translate( (0, 0, -self.rad))) outer = outer.union(p2) p3 = self.profile().extrude(self.spacing).translate((0, 0, self.rad)) outer = outer.union(p3) p4 = (self.profile().revolve(180, (-2, self.rad), (1, self.rad)).translate( (0, -self.spacing, -self.rad))) outer = outer.union(p4) return outer
class StepperGear(TrapezoidalGear): """ This is a length of threaded rod (without thread) """ # Parameters gear_od = PositiveFloat(8, doc="Gear diameter") gear_length = PositiveFloat(2, doc="Gear length") # default appearance _render = render_props(color=(200, 200, 200)) # dark grey def make(self): r = super(StepperGear, self).make() r = r.faces(">Z").circle((self.gear_od) / 2).extrude(self.gear_length) # cut out shaft e = 0.03 # Margin of error w = e + 3.0 / 2 # distance of flat tab l = 4.0 / 2 # distance along flat tab (no error term as that is in the c term c = e + 0.5 # Curved end r = r.cut( cadquery.Workplane("XY").transformed(offset=(0, 0, -5)).lineTo( w, 0).lineTo(w, l).threePointArc( (0, l + c), (-w, l)).lineTo(-w, -l).threePointArc( (0, -l - c), (w, -l)).lineTo(w, 0).close().extrude(20)) return r # Construct mating points for two axes @property def mate_shaft(self): """This is the top of the box""" return Mate( self, CoordSystem(origin=(0, 0, 0), xDir=(1, 0, 0), normal=(0, 0, 1)))
class Standoff(cqparts.Part): size = PositiveFloat(3) length = PositiveFloat(15) _render = render_props(template="steel") def make(self): so = cq.Workplane("XY").circle(self.size / 2).extrude(-self.size) if self.length > 0: hx = cq.Workplane("XY").polygon(6, self.size * 2).extrude(self.length) so = so.union(hx) return so def make_cutout(self, part, clearance=0): part = part.local_obj.cut((self.world_coords - part.world_coords) + self.cutout(clearance=clearance)) def cutout(self, clearance=0): so = cq.Workplane("XY").circle(self.size / 2).extrude(-self.length) return so def mate_top(self): return Mate( self, CoordSystem(origin=(0, 0, self.length), xDir=(1, 0, 0), normal=(0, 0, 1)), )
class Shaft(cqparts.Part): " base shaft , override ME" length = PositiveFloat(24, doc="shaft length") diam = PositiveFloat(5, doc="shaft diameter") _render = render_props(color=(50, 255, 255)) def make(self): shft = cq.Workplane("XY")\ .circle(self.diam/2)\ .extrude(self.length)\ .faces(">Z")\ .chamfer(0.4) return shft def cut_out(self): cutout = cq.Workplane("XY")\ .circle(self.diam/2)\ .extrude(self.length) return cutout # TODO , mate for shafts def get_cutout(self, clearance=0): " clearance cut out for shaft " return cq.Workplane('XY', origin=(0, 0, 0)) \ .circle((self.diam / 2) + clearance) \ .extrude(self.length*2)
class Base(Printable): diameter = PositiveFloat(10) width = PositiveFloat(40) height = PositiveFloat(20) lower_height = PositiveFloat(10) thickness = PositiveFloat(2) _render = render_props(color=(100, 150, 100)) def make(self): # base = cq.Workplane("XY").rect(self.length,self.width).extrude(self.height) base = cq.Workplane("XY").circle(self.diameter / 2).extrude( self.height) inc = 360 / float(4) mt = MountTab() t1 = mt.local_obj.translate( (-self.diameter / 2, self.width / 2 - mt.diameter / 2, 0)) t2 = t1.mirror("YZ") t_r = t1.union(t2) t_l = t_r.mirror("XZ") base = base.union(t_r) base = base.union(t_l) # base = base.edges("|Z").fillet(2) return base def mate_lower(self): return Mate(self, CoordSystem(origin=(0, 0, self.lower_height)))
class Yaw(Printable): width = PositiveFloat(40) diameter = PositiveFloat(20) height = PositiveFloat(5) _render = render_props(color=(130, 150, 100)) def make(self): # yaw = cq.Workplane("XY").rect(self.length,self.width).extrude(self.height) yaw = cq.Workplane("XY").circle(self.diameter / 2).extrude(self.height) # yaw = yaw.edges("|Z").fillet(2) return yaw def mate_middle(self, offset=0): return Mate( self, CoordSystem(origin=(0, 0, self.height), xDir=(1, 0, 0), normal=(0, 0, 1)), ) def mate_side(self, offset=0): return Mate( self, CoordSystem(origin=(offset, 0, self.height / 2), xDir=(1, 0, 0), normal=(0, 1, 0)), )
class Pitch(Printable): diameter = PositiveFloat(41) width = PositiveFloat(40) length = PositiveFloat(10) height = PositiveFloat(10) thickness = PositiveFloat(5) _render = render_props(color=(160, 150, 100)) def make(self): pitch = (cq.Workplane("XY").circle(self.diameter / 2 + self.thickness).circle( self.diameter / 2).extrude( self.height)) pitch = pitch.transformed(rotate=(0, 90, 90)).split(keepTop=True) rot = cq.Workplane("YZ").circle(self.height / 2).extrude(-self.thickness) rot = rot.translate( (self.diameter / 2 + self.thickness, 0, self.height / 2)) other_side = rot.mirror("YZ") rot = rot.union(other_side) pitch = pitch.union(rot) return pitch def mate_side(self, offset=0): return Mate( self, CoordSystem(origin=(offset, 0, self.height / 2), xDir=(0, 1, 0), normal=(1, 0, 0)), )
class seal(cover): shrink = PositiveFloat(0.5) overlap = PositiveFloat(0.75) _render = render_props(color=(20, 20, 20), alpha=0.7) def make(self): outer = rounded( height=self.thickness, width=self.width, depth=self.depth, shrinkX=self.overlap, shrinkY=self.overlap, ).local_obj # inner = rounded(shrinkX=self.shrink,shrinkY=self.shrink).local_obj # outer = outer.cut(inner) # outer = outer.faces("<Z").fillet(self.thickness*0.5) return outer def mate_back(self): return Mate( self, CoordSystem(origin=(0, 0, self.thickness), xDir=(1, 0, 0), normal=(0, 0, 1)), )
class cabinet(Printable): depth = PositiveFloat(80) width = PositiveFloat(60) height = PositiveFloat(35) thickness = PositiveFloat(1.5) _render = render_props(color=(255, 255, 205)) _material = "grey_abs" def make(self): cab = cq.Workplane("XY").box(self.depth, self.width, self.height, centered=(True, True, False)) cab = cab.faces(">Z").shell(-self.thickness) cab = cab.edges("|Z").fillet(self.thickness + 0.1) # cab = cab.faces().fillet(2) return cab def mate_front(self): return Mate( self, CoordSystem(origin=(0, 0, self.height), xDir=(-1, 0, 0), normal=(0, 0, 1)), ) def mate_back(self): return Mate( self, CoordSystem(origin=(0, 0, self.height), xDir=(1, 0, 0), normal=(0, 0, -1)), )
class Coupling(cqparts.Part): length = PositiveFloat(24) outer_diam = PositiveFloat(9) inner_diam_A = PositiveFloat(5) inner_diam_B = PositiveFloat(5) gap = PositiveFloat(3) _render = render_props(color=(75, 75, 50)) def make(self): lm = (cq.Workplane("XY").workplane(offset=-self.length / 2).circle( self.outer_diam / 2).circle(self.inner_diam_A / 2).extrude( self.length)) return lm def mate_input(self, offset=0): return Mate( self, CoordSystem(origin=(0, 0, -self.gap / 2), xDir=(1, 0, 0), normal=(0, 0, 1)), ) def mate_output(self, offset=0): return Mate( self, CoordSystem(origin=(0, 0, self.gap / 2), xDir=(1, 0, 0), normal=(0, 0, 1)), )
class Cylinder(cqparts.Part): diam = PositiveFloat(10, doc="cylinder's diameter") length = PositiveFloat(10, doc="cylinder's length") embed = PositiveFloat(2, doc="embedding distance") hole_diam = PositiveFloat(2.72, doc="pilot hole diam") _render = render_props(alpha=0.8) def make_base_cylinder(self): # This is used as a basis for make() and cutaway() return cadquery.Workplane('XY') \ .circle(self.diam/2).extrude(self.embed + self.length) def make(self): # Use the base cylindrical shape, and cut a hole through it return self.make_base_cylinder() \ .faces(">Z").hole(self.hole_diam / 2) @property def cutaway(self): # Use the base cylindrical shape, no alterations return self.make_base_cylinder() @property def mate_embedded(self): return Mate(self, CoordSystem((0, 0, self.embed)))
class _CaseLid(_Case): _render = render_props(color=(50, 50, 50)) def make(self): wp = cq.Workplane("XY") c = super(_CaseLid, self).make() # add the slab on top b = (wp.transformed(offset=(0, 0, self.height)).box( self.length, self.width, self.thickness, centered=(True, True, False)).edges("|Z").fillet(1)) b.faces(">Z").chamfer(0.2) b = b.union(c) return b def mate_bottom(self, explode=0): return Mate( self, CoordSystem(origin=(0, 0, -2 * explode), xDir=(1, 0, 0), normal=(0, 0, -1)), ) def mate_top(self, explode=0): return Mate( self, CoordSystem( origin=(0, 0, self.height + 2 * explode), xDir=(1, 0, 0), normal=(0, 0, 1), ), )
class Template(cqparts.Part): length = PositiveFloat(24) diam = PositiveFloat(5) _render = render_props(color=(50, 255, 255)) def make(self): shft = cq.Workplane("XY").circle(self.diam / 2).extrude(self.length) return shft def cut_out(self): cutout = cq.Workplane("XY").circle(self.diam / 2).extrude(self.length) return cutout def get_cutout(self, clearance=0): " clearance cut out for shaft " return (cq.Workplane( "XY", origin=(0, 0, 0)).circle((self.diam / 2) + clearance).extrude(self.length * 2)) def mate_tip(self, offset=0): return Mate( self, CoordSystem(origin=(0, 0, self.length), xDir=(1, 0, 0), normal=(0, 0, 1)), )
class Stepper_Holder(cqparts.Part): """ This is a simple holder for a standard 28BYJ-48 stepper motor. It needs to be assembled. """ # default appearance _render = render_props(color=(20, 20, 150)) height = 30 def make(self): # Outside face r = cadquery.Workplane("XY").rect(30, 55).extrude(self.height) return r # Construct mating points for two axes @property def mate_centre(self): """This is the top of the box""" embed_depth = ( 10 ) # Make non zero to actually embed stepper into solid block and checkout cutouts return Mate( self, CoordSystem( origin=(10, 0, self.height - embed_depth), xDir=(1, 0, 0), normal=(0, 0, 1), ), )
class TrainPan(cqparts.Part): length = PositiveFloat(35) width = PositiveFloat(12) height = PositiveFloat(0) wagon = PartRef() magnet = PartRef() _render = render_props(template="steel") def make(self): wp = cq.Workplane("XY") pan = wp.box(self.width, self.length, self.height, centered=(True, True, False)).chamfer(0.2) if self.wagon is not None: w = self.wagon(width=self.width, length=self.length).make() w = w.translate((0, 0, self.height)) pan = pan.union(w) return pan def mate_lift(self, lift=0): return Mate( self, CoordSystem(origin=(0, 0, -lift), xDir=(1, 0, 0), normal=(0, 0, 1))) @property def mate_top(self): return Mate( self, CoordSystem(origin=(0, 0, self.height), xDir=(1, 0, 0), normal=(0, 0, 1)), ) def mate_end(self, direction): return Mate( self, CoordSystem( origin=(0, direction * self.length / 2, self.height / 2), xDir=(1, 0, 1), normal=(0, direction, 0), ), ) # returns the mates for the wheels def wheel_points(self, inset=0, axle=0): mps = [] pos = [1, -1] for i in pos: m = Mate( self, CoordSystem( origin=(0, i * (self.length / 2 - inset), axle), xDir=(0, 0, 1), normal=(0, i, 0), ), ) mps.append(m) return mps
class Motor(cqparts.Part): """ This is a standard DC motor with a worm gear """ # Parameters motor_od = PositiveFloat(24.1, doc="Motor diameter") motor_length = PositiveFloat(30.5, doc="Motor length") shaft_od = PositiveFloat(2, doc="Shaft diameter") shaft_length = PositiveFloat(6.5, doc="Shaft length") # Modelling worm drive as a cylinder gear_od = PositiveFloat(6, doc="Gear diameter") gear_length = PositiveFloat(10, doc="Gear length") # default appearance _render = render_props(color=(200, 200, 0)) # dark yellow def make(self): # Outside face r = cadquery.Workplane("YZ").circle( (self.motor_od) / 2).extrude(self.motor_length) r = r.faces(">X").circle( (self.shaft_od) / 2).extrude(self.shaft_length) r = r.faces(">X").circle((self.gear_od) / 2).extrude(self.gear_length) return r def get_cutout(self, clearance=1): # Outside face r = cadquery.Workplane("YZ").circle(clearance + (self.motor_od / 2)).extrude( self.motor_length) return r
class Loco(Wagon): _render = render_props(template="steel") def make(self): drop = 6 cab_scale = self.width * 0.8 wp = cq.Workplane("ZX") tank = (wp.workplane(offset=-self.length / 2).circle( self.width / 3).extrude(self.length * 0.6).translate( (0, 0, self.width / 3)).faces(">X").chamfer(0.5)) block = cq.Workplane("XY").box(self.width, self.length, self.width / drop, centered=(True, True, False)) tank = tank.cut(block) tank = tank.translate((0, 0, -self.width / drop)) cab = cq.Workplane("XY").rect(cab_scale, cab_scale).extrude(cab_scale) cab = cab.faces(">Z").edges("|Y").fillet(1) cab = cab.translate((0, self.length / 4, 0)) cab = cab.faces(">Y").shell(-0.4) cab = cab.union(tank) chimney = (cq.Workplane("XY").circle(self.width / 9.2).extrude( self.width * 0.7).faces(">Z").chamfer(0.2)) chimney = chimney.translate((0, -self.length * 0.35, 0)) cab = cab.union(chimney) return cab
class WoodPanel(cqparts.Part): thickness = PositiveFloat(15, doc="thickness of panel") width = PositiveFloat(100, doc="panel width") length = PositiveFloat(100, doc="panel length") _render = render_props(template='wood') # wooden def make(self): return cadquery.Workplane('XY') \ .box(self.length, self.width, self.thickness) @property def mate_end(self): # center of +x face return Mate( self, CoordSystem( origin=(self.length / 2, 0, 0), xDir=(0, 0, -1), normal=(-1, 0, 0), )) def get_mate_edge(self, thickness): return Mate( self, CoordSystem(origin=((self.length / 2) - (thickness / 2), 0, self.thickness / 2)))
class SideConstruct(cqparts.Part): # Parameters seperation = PositiveFloat(40, doc="bar seperation") # default appearance _render = render_props(color=(250, 50, 90)) def make(self): plate = cadquery.Workplane("XY").box(self.seperation+2, 2, 0.5)\ .faces(">Y").workplane() \ .pushPoints([(0, self.seperation/2), (0, -self.seperation/2)]) \ .hole(0.125) return plate # Construct mating points for two axes @property def mate_left(self): return Mate( self, CoordSystem( origin=(0, self.seperation / 2, 0), xDir=(1, 0, 0), normal=(0, -1, 0), )) @property def mate_right(self): print('Mating right') return Mate( self, CoordSystem( origin=(0, -self.seperation / 2, 0), xDir=(1, 0, 0), normal=(0, 1, 0), ))
class ThreadedRod(cqparts.Part): """ This is a length of threaded rod (without thread) """ # Parameters rod_od = PositiveFloat(8, doc="Rod diameter") rod_length = PositiveFloat(200, doc="Rod length") # default appearance _render = render_props(color=(200, 200, 200)) # dark grey def make(self): # Outside face r = cadquery.Workplane("YZ").circle( (self.rod_od) / 2).extrude(self.rod_length) # r = r.faces(">X").circle((self.gear_od)/2).extrude(self.gear_length) return r # Construct mating points @property def mate_start(self): return Mate( self, CoordSystem(origin=(0, 0, 0), # xDir=(1, 0, 0), normal=(0, -1, 0), ))
class BarHolder(cqparts.Part): """ This is a mount to hold a threaded screw. With a spacer to make sure the selected screw goes the requested depth into the wood below. """ length = 15 wall = 4.0 shaft_diameter = 8.3 # default appearance _render = render_props(color=(200, 200, 200)) # dark grey def make(self): l = self.length radius = (self.shaft_diameter / 2.0) + self.wall r = cadquery.Workplane("XY").circle(radius).extrude(l) # add holes for rod r = r.faces(">Z").workplane().hole(self.shaft_diameter) return r def get_cutout(self, clearance=0.5): # A cylinder with a equal clearance on every face return (cadquery.Workplane( "XY", origin=(0, 0, clearance + 10)).circle((self.shaft_diameter / 2.0) + clearance).extrude(-self.length - (2 * clearance))) def apply_cutout(self, part): # Cut space for screw hole from part this is fitted into part.local_obj = part.local_obj.cut((self.world_coords - part.world_coords) + self.get_cutout())
class ThreadedRod(H3Part): """ This is a length of threaded rod (without thread) """ # Parameters rod_od = PositiveFloat(8, doc="Rod diameter") rod_length = PositiveFloat(200, doc="Rod length") # default appearance _render = render_props(color=(200, 200, 200)) # dark grey def make(self): # Outside face r = cadquery.Workplane("YZ").circle( (self.rod_od) / 2).extrude(self.rod_length) # r = r.faces(">X").circle((self.gear_od)/2).extrude(self.gear_length) return r # Construct mating points def mate_along(self, distance=0, xDir=(1, 0, 0), normal=(0, -1, 0), rotation=(0, 0, 0)): """Mating along rod""" return Mate( self, CoordSystem(origin=(distance, 0, 0), xDir=xDir, normal=normal).rotated(rotation), )
class Base(cqparts.Part): diameter = PositiveFloat(40) height = PositiveFloat(10) mounts = Int(4) _render = render_props(color=(100, 150, 100)) def make(self): base = cq.Workplane("XY").circle(self.diameter / 2).extrude( self.height) inc = 360 / float(self.mounts) for i in range(self.mounts): t = MountTab().local_obj t = t.translate((-self.diameter / 2, 0, 0)) t = t.rotate((0, 0, 0), (0, 0, 1), i * inc) base = base.union(t) base = base.edges("|Z").fillet(1) return base def mate_top(self): return Mate( self, CoordSystem(origin=(0, 0, self.height), xDir=(1, 0, 0), normal=(0, 0, 1)), )
class BoltHolder(cqparts.Part): """This is the holder for the testing Bolts""" _render = render_props(template="red", alpha=0.2) width = 28 height = 20 def make(self): r = (cadquery.Workplane("XY").transformed(offset=(-10, 0, 0)).rect( 6 * 20 + 10, self.width, centered=False).extrude(self.height)) return r def mate_nut_top(self, nth=0): """Mating along top face""" return Mate( self, CoordSystem(origin=(nth * 20, self.width / 2, self.height), # xDir=(1, 0, 0), normal=(0, -1, 0), ), ) def mate_nut_bottom(self, nth=0): """Mating along top face""" return Mate( self, CoordSystem(origin=(nth * 20, self.width / 2, 0), # xDir=(1, 0, 0), normal=(0, -1, 0), ), )
class YellowDisc(Printable): radius = PositiveFloat(10) height = PositiveFloat(15) inner = PositiveFloat(1.5) _render = render_props(color=(255, 255, 0)) _material = "yellow_abs" def make(self): disc = (cq.Workplane("XY").circle(self.radius).circle( self.inner).extrude(self.height)) disc = disc.faces(">Z").chamfer(0.3) return disc def mate_top(self, rot=0): return Mate( self, CoordSystem(origin=(0, 0, self.height), xDir=(1, 0, 0), normal=(0, 0, 1)).rotated((0, 0, rot)), ) def mate_side(self, rot=0): return Mate( self, CoordSystem( origin=(-self.inner / 2, 0, self.height * 0.8), xDir=(0, 0, 1), normal=(-1, 0, 0), ).rotated((0, 0, rot)), )