def to_assembly(*cad_objs, render_mates=None, mate_scale=None): assembly = PartGroup([], "Group") obj_id = 0 for cad_obj in cad_objs: if isinstance(cad_obj, (PartGroup, Part, Faces, Edges, Vertices)): assembly.add(cad_obj) elif HAS_MASSEMBLY and isinstance(cad_obj, MAssembly): assembly.add( from_assembly(cad_obj, cad_obj, render_mates=render_mates, mate_scale=mate_scale)) elif isinstance(cad_obj, CqAssembly): assembly.add(from_assembly(cad_obj, cad_obj)) elif isinstance(cad_obj, Edge): assembly.add_list(_from_edgelist(Workplane(cad_obj), obj_id)) elif isinstance(cad_obj, Face): assembly.add_list(_from_facelist(Workplane(cad_obj), obj_id)) elif isinstance(cad_obj, Wire): assembly.add(_from_wirelist(Workplane(cad_obj), obj_id)) elif isinstance(cad_obj, Vertex): assembly.add_list(_from_vertexlist(Workplane(cad_obj), obj_id)) elif is_cqparts(cad_obj): assembly = convert_cqparts(cad_obj) elif _is_facelist(cad_obj): assembly.add_list(_from_facelist(cad_obj, obj_id)) elif _is_edgelist(cad_obj): assembly.add_list(_from_edgelist(cad_obj, obj_id)) elif _is_wirelist(cad_obj): assembly.add(_from_wirelist(cad_obj, obj_id)) elif _is_vertexlist(cad_obj): assembly.add_list(_from_vertexlist(cad_obj, obj_id)) elif isinstance(cad_obj, Vector): assembly.add_list(_from_vector(cad_obj, obj_id)) elif isinstance(cad_obj.val(), Vector): assembly.add_list(_from_vectorlist(cad_obj, obj_id)) elif isinstance(cad_obj, Workplane): assembly.add(_from_workplane(cad_obj, obj_id)) else: raise NotImplementedError("Type:", cad_obj) obj_id += 1 return assembly
def relocate(name, shape): a = assy.objects[name] loc = a.loc parent = a.parent while parent is not None: loc = parent.loc * loc parent = parent.parent if isinstance(shape, str): shape = assy._query(shape)[1] return Workplane(Workplane(shape).val().located(loc))
def to_edge(mate, loc=None, scale=1) -> Workplane: w = Workplane() for d in (mate.x_dir, mate.y_dir, mate.z_dir): edge = Edge.makeLine(mate.origin, mate.origin + d * scale) w.objects.append(edge if loc is None else edge.moved(loc)) return w
def _relocate(assy, origins): origin_mate = origins.get(assy.name) if origin_mate is not None: assy.obj = Workplane(assy.obj.val().moved(origin_mate.loc.inverse)) assy.loc = Location() for c in assy.children: _relocate(c, origins)
def importBox(self, importType, fileName): """ Exports a simple box to a STEP file and then imports it again :param importType: The type of file we're importing (STEP, STL, etc) :param fileName: The path and name of the file to write to """ # We're importing a STEP file if importType == importers.ImportTypes.STEP: # We first need to build a simple shape to export shape = Workplane("XY").box(1, 2, 3).val() # Export the shape to a temporary file shape.exportStep(fileName) # Reimport the shape from the new STEP file importedShape = importers.importShape(importType, fileName) # Check to make sure we got a solid back self.assertTrue(importedShape.val().ShapeType() == "Solid") # Check the number of faces and vertices per face to make sure we have a box shape self.assertTrue( importedShape.faces("+X").size() == 1 and importedShape.faces("+X").vertices().size() == 4) self.assertTrue( importedShape.faces("+Y").size() == 1 and importedShape.faces("+Y").vertices().size() == 4) self.assertTrue( importedShape.faces("+Z").size() == 1 and importedShape.faces("+Z").vertices().size() == 4)
def from_assembly(cad_obj, top, loc=None, render_mates=False, mate_scale=1): loc = Location() render_loc = cad_obj.loc color = Color(get_rgb(cad_obj.color)) parent = [ Part( Workplane(shape), "%s_%d" % (cad_obj.name, i), color=color, ) for i, shape in enumerate(cad_obj.shapes) ] if render_mates and cad_obj.mates is not None: RGB = (Color((255, 0, 0)), Color((0, 128, 0)), Color((0, 0, 255))) parent.append( PartGroup( [ Part(to_edge(mate_def.mate, scale=mate_scale), name=name, color=RGB) for name, mate_def in top.mates.items() if mate_def.assembly == cad_obj ], name="mates", loc=Location( ), # mates inherit the parent location, so actually add a no-op )) children = [ from_assembly(c, top, loc, render_mates, mate_scale) for c in cad_obj.children ] return PartGroup(parent + children, cad_obj.name, loc=render_loc)
def enclosure(height): # Bottom enclosure part part = Workplane('XY').box(WIDTH, LENGTH, height)\ .faces('+Z').shell(THICK) part = enclosure_passthrough_vertices(part.faces('>Z'))\ .rect(PASS_OUTTER, PASS_OUTTER).extrude(-height)\ .edges('|Z').fillet(2) part = enclosure_passthrough_vertices(part.faces('<Z'))\ .cboreHole(PASS_INNER, PASS_CBORE, PASS_CBORE_DEPTH) return part
def show_constraints(assy, qs): colors = [ "#e41a1c", "#377eb8", "#4daf4a", "#984ea3", "#ff7f00", "#ffff33", "#a65628", "#f781bf", "#999999", "#8dd3c7", "#ffffb3", "#bebada", "#fb8072", "#80b1d3", "#fdb462", "#b3de69", "#fccde5", "#d9d9d9", ] constraints = [] objects = [] cache = {} for i, q1q2 in enumerate(qs): parts = [] kind = q1q2[-1] if len(q1q2) == 3: q1q2 = ((q1q2[0].split("@")[0], q1q2[0]), (q1q2[1].split("@")[0], q1q2[1])) else: q1q2 = (q1q2[0:2], q1q2[2:4]) for q in q1q2: name, shape = q if name in cache: obj = cache[name]["obj"] loc = cache[name]["loc"] else: obj = assy.objects[name].obj loc = assy.objects[name].loc parent = assy.objects[name].parent while parent is not None: loc = parent.loc * loc parent = parent.parent cache[name] = {"obj": obj, "loc": loc, "shape": shape} objects.append(Part(Workplane(obj.val().located(loc)), name=name, show_faces=False)) label = str(shape) if isinstance(shape, str): shape = assy._query(shape)[1] parts.append( Faces( Workplane(Workplane(shape).val().located(loc)), name=html.escape(label), color=colors[i % len(colors)], ) ) constraints.append(PartGroup(parts, "%s_%d" % (kind, i))) show(PartGroup([PartGroup(objects, "objects")] + constraints), axes=True, axes0=True)
def _from_vector(vec, obj_id, name="Vector"): tmp = Workplane() obj = tmp.newObject([vec]) return _from_vectorlist(obj, obj_id, name)
def to_assembly(*cad_objs, name="Group", render_mates=None, mate_scale=1, default_color=None, show_parent=True): default_color = get_default( "default_color") if default_color is None else default_color assembly = PartGroup([], name) obj_id = 0 for cad_obj in cad_objs: if isinstance(cad_obj, (PartGroup, Part, Faces, Edges, Vertices)): _debug( f"CAD Obj {obj_id}: PartGroup, Part, Faces, Edges, Vertices") assembly.add(cad_obj) elif HAS_MASSEMBLY and isinstance(cad_obj, MAssembly): _debug(f"CAD Obj {obj_id}: MAssembly") assembly.add( from_assembly(cad_obj, cad_obj, render_mates=render_mates, mate_scale=mate_scale, default_color=default_color)) elif isinstance(cad_obj, CqAssembly): _debug(f"CAD Obj {obj_id}: cqAssembly") assembly.add( from_assembly(cad_obj, cad_obj, default_color=default_color)) elif isinstance(cad_obj, Edge): _debug(f"CAD Obj {obj_id}: Edge") assembly.add_list( _from_edgelist(Workplane(cad_obj), obj_id, show_parent=show_parent)) elif isinstance(cad_obj, Sketch): _debug(f"CAD Obj {obj_id}: Sketch") assembly.add_list( _from_sketch( cad_obj, obj_id, show_parent=show_parent, )) elif isinstance(cad_obj, Face): _debug(f"CAD Obj {obj_id}: Face") assembly.add_list( _from_facelist(Workplane(cad_obj), obj_id, show_parent=show_parent)) elif isinstance(cad_obj, Wire): _debug(f"CAD Obj {obj_id}: Wire") assembly.add( _from_wirelist(Workplane(cad_obj), obj_id, show_parent=show_parent)) elif isinstance(cad_obj, Vertex): _debug(f"CAD Obj {obj_id}: Vertex") assembly.add_list( _from_vertexlist(Workplane(cad_obj), obj_id, show_parent=show_parent)) elif _is_facelist(cad_obj): _debug(f"CAD Obj {obj_id}: facelist") assembly.add_list( _from_facelist(cad_obj, obj_id, show_parent=show_parent)) elif _is_edgelist(cad_obj): _debug(f"CAD Obj {obj_id}: edgelist") assembly.add_list( _from_edgelist(cad_obj, obj_id, show_parent=show_parent)) elif _is_wirelist(cad_obj): _debug(f"CAD Obj {obj_id}: wirelist") assembly.add_list( _from_wirelist(cad_obj, obj_id, show_parent=show_parent)) elif _is_vertexlist(cad_obj): _debug(f"CAD Obj {obj_id}: vertexlist") assembly.add_list( _from_vertexlist(cad_obj, obj_id, show_parent=show_parent)) elif isinstance(cad_obj, Vector): _debug(f"CAD Obj {obj_id}: Vector") assembly.add_list(_from_vector(cad_obj, obj_id)) elif isinstance(cad_obj, (Shape, Compound)): _debug(f"CAD Obj {obj_id}: Shape, Compound") assembly.add( _from_workplane(Workplane(cad_obj), obj_id, default_color=default_color, show_parent=show_parent)) elif is_compound(cad_obj): _debug(f"CAD Obj {obj_id}: TopoDS Compound") assembly.add(_Part([cad_obj], color=default_color)) elif is_shape(cad_obj): _debug(f"CAD Obj {obj_id}: TopoDS Shape") assembly.add(_Part([cad_obj], color=default_color)) elif isinstance(cad_obj.val(), Vector): _debug(f"CAD Obj {obj_id}: Vector val()") assembly.add_list( _from_vectorlist(cad_obj, obj_id, show_parent=show_parent)) elif isinstance(cad_obj, Workplane): _debug(f"CAD Obj {obj_id}: Workplane") if len(cad_obj.vals()) == 1 and not isinstance( cad_obj.val(), Sketch): assembly.add( _from_workplane(cad_obj, obj_id, default_color=default_color, show_parent=show_parent)) else: assembly2 = PartGroup([], name="Group_%s" % obj_id) for j, obj in enumerate(cad_obj.vals()): if isinstance(obj, Sketch): for sketch_obj in _from_sketch(obj, j, show_parent=False): assembly2.add(sketch_obj) else: assembly2.add( _from_workplane(Workplane(obj), j, default_color=default_color, show_parent=show_parent)) assembly.add(assembly2) else: raise NotImplementedError("Type:", cad_obj) obj_id += 1 return assembly
def from_assembly(cad_obj, top, loc=None, render_mates=False, mate_scale=1, default_color=None): loc = Location() render_loc = cad_obj.loc if cad_obj.color is None: if default_color is None: color = Color(get_default("default_color")) else: color = Color(default_color) else: color = Color(get_rgb(cad_obj.color)) # Special handling for edge lists in an MAssembly is_edges = [isinstance(obj, Edge) for obj in cad_obj.shapes] if is_edges and all(is_edges): if cad_obj.color is None: if default_color is None: color = Color(get_default("default_edgecolor")) else: color = Color(default_color) else: color = Color(get_rgb(cad_obj.color)) workplane = Workplane() workplane.objects = cad_obj.shapes parent = [Edges( workplane, name="%s_0" % cad_obj.name, color=color, )] else: if cad_obj.color is None: if default_color is None: color = Color(get_default("default_color")) else: color = Color(default_color) else: color = Color(get_rgb(cad_obj.color)) parent = [ Part( Workplane(shape), "%s_%d" % (cad_obj.name, i), color=color, ) for i, shape in enumerate(cad_obj.shapes) ] if render_mates and cad_obj.mates is not None: rgb = (Color((255, 0, 0)), Color((0, 128, 0)), Color((0, 0, 255))) pg = PartGroup( [ Edges(to_edge(mate_def.mate, scale=mate_scale), name=name, color=rgb) for name, mate_def in top.mates.items() if mate_def.assembly == cad_obj ], name="mates", loc=Location( ), # mates inherit the parent location, so actually add a no-op ) if pg.objects: parent.append(pg) children = [ from_assembly(c, top, loc, render_mates, mate_scale) for c in cad_obj.children ] return PartGroup(parent + children, cad_obj.name, loc=render_loc)
def _from_sketch(cad_obj, obj_id, show_parent=True, show_selection=True): result = [] locs = cad_obj.locs if cad_obj.locs else [Location()] workplane = Workplane() if cad_obj._faces: for loc in locs: workplane.objects += cad_obj._faces.moved(loc).Faces() result += _from_facelist(workplane, obj_id, name="Faces", show_parent=show_parent) elif cad_obj._edges: workplane.objects = [ edge.moved(loc) for edge in cad_obj._edges for loc in locs ] result += _from_edgelist(workplane, obj_id, name="Edges", show_parent=show_parent) if show_selection and cad_obj._selection: workplane = Workplane() if isinstance(cad_obj._selection[0], Location): workplane.objects = [ Vertex.makeVertex(0, 0, 0).moved(loc * obj) for obj in cad_obj._selection for loc in locs ] sel = _from_vertexlist(workplane, obj_id, name="Locations", show_parent=show_parent) elif isinstance(cad_obj._selection[0], Face): for loc in locs: workplane.objects += flatten([ obj._faces.moved(loc).Faces() for obj in cad_obj._selection ]) sel = _from_facelist(workplane, obj_id, name="Faces", show_parent=show_parent) elif isinstance(cad_obj._selection[0], (Edge, Wire)): workplane.objects = [ edge.moved(loc) for edge in cad_obj._selection for loc in locs ] sel = _from_edgelist(workplane, obj_id, name="Edges", show_parent=show_parent) elif isinstance(cad_obj._selection[0], Vertex): workplane.objects = [ vertex.moved(loc) for vertex in cad_obj._selection for loc in locs ] sel = _from_vertexlist(workplane, obj_id, name="Vertices", show_parent=show_parent) result.append(PartGroup(sel, name=f"Selection_{obj_id}")) return result
def involute_gear(m, z, alpha=20, shift=0, N=5): ''' See https://khkgears.net/new/gear_knowledge/gear_technical_reference/involute_gear_profile.html :param m: module, diameter / number of teeth :type m: float :param z: number of teeth :type z: int :param alpha: pressure angle :type alpha: float :param shift: Profile Shift Coefficient :type shift: float :param N: Resolution of curve :type N: int ''' alpha = radians(alpha) # radii r_ref = m*z/2 r_top = r_ref + m*(1+shift) r_base = r_ref*cos(alpha) r_d = r_ref - 1.25*m inv = lambda a: tan(a) - a # angles of interest alpha_inv = inv(alpha) alpha_tip = acos(r_base/r_top) alpha_tip_inv = inv(alpha_tip) a = 90/z+degrees(alpha_inv) a2 = 90/z+degrees(alpha_inv)-degrees(alpha_tip_inv) a3 = 360/z-a # involute curve (radius based parametrization) def involute_curve(r_b,sign=1): def f(r): alpha = sign*acos(r_b/r) x = r*cos(tan(alpha) - alpha) y = r*sin(tan(alpha) - alpha) return x,y return f # construct all the profiles right = ( Workplane() .transformed(rotate=(0,0,a)) .parametricCurve(involute_curve(r_base,-1), start=r_base, stop = r_top, makeWire=False, N=N) .val() ) left = ( Workplane() .transformed(rotate=(0,0,-a)) .parametricCurve(involute_curve(r_base), start=r_base, stop = r_top, makeWire=False, N=N) .val() ) top = Edge.makeCircle(r_top,angle1=-a2, angle2=a2) bottom = Edge.makeCircle(r_d, angle1=-a3, angle2=-a) side = Edge.makeLine( cq.Vector(r_d,0), cq.Vector(r_base,0)) side1 = side.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), -a) side2 = side.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), -a3) # single tooth profile profile = Wire.assembleEdges([left,top,right,side1,bottom,side2]) profile = profile.chamfer2D(m/4, profile.Vertices()[-3:-1]) # complete gear res = ( Workplane() .polarArray(0,0,360,z) .each(lambda loc: profile.located(loc)) .consolidateWires() ) return res.val()
.val() ) top = Edge.makeCircle(r_top,angle1=-a2, angle2=a2) bottom = Edge.makeCircle(r_d, angle1=-a3, angle2=-a) side = Edge.makeLine( cq.Vector(r_d,0), cq.Vector(r_base,0)) side1 = side.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), -a) side2 = side.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), -a3) # single tooth profile profile = Wire.assembleEdges([left,top,right,side1,bottom,side2]) profile = profile.chamfer2D(m/4, profile.Vertices()[-3:-1]) # complete gear res = ( Workplane() .polarArray(0,0,360,z) .each(lambda loc: profile.located(loc)) .consolidateWires() ) return res.val() show_object( Workplane(obj=involute_gear(1, 30)) .toPending().extrude(5) .faces(">Z").circle(10).extrude(5) .faces(">Z").hole(5) )
start=r_base, stop=r_top, makeWire=False, N=N).val()) left = (Workplane().transformed(rotate=(0, 0, -a)).parametricCurve( involute_curve(r_base), start=r_base, stop=r_top, makeWire=False, N=N).val()) top = Edge.makeCircle(r_top, angle1=-a2, angle2=a2) bottom = Edge.makeCircle(r_d, angle1=-a3, angle2=-a) side = Edge.makeLine(cq.Vector(r_d, 0), cq.Vector(r_base, 0)) side1 = side.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), -a) side2 = side.rotate(cq.Vector(0, 0, 0), cq.Vector(0, 0, 1), -a3) # single tooth profile profile = Wire.assembleEdges([left, top, right, side1, bottom, side2]) profile = profile.chamfer2D(m / 4, profile.Vertices()[-3:-1]) # complete gear res = (Workplane().polarArray( 0, 0, 360, z).each(lambda loc: profile.located(loc)).consolidateWires()) return res.val() show_object( Workplane(obj=involute_gear(1, 20)).toPending().twistExtrude(20, 30))