def _unify_compound(proto): builder = BRep_Builder() comp = TopoDS_Compound() builder.MakeCompound(comp) explorer = TopExp_Explorer() explorer.Init(proto.Shape(), TopAbs_SOLID) while explorer.More(): builder.Add(comp, _unify_solid(Shape(explorer.Current())).Solid()) explorer.Next() explorer.Init(proto.Shape(), TopAbs_SHELL, TopAbs_SOLID) while explorer.More(): builder.Add(comp, _unify_shell(Shape(explorer.Current())).Shell()) explorer.Next() faces = [] explorer.Init(proto.Shape(), TopAbs_FACE, TopAbs_SHELL) while explorer.More(): faces.append(Shape(explorer.Current())) explorer.Next() faces_new = _unify_faces_array(faces) for f in faces_new: builder.Add(comp, f.Shape()) return Shape(comp)
def _make_edge(crv, interval=None) -> Shape: aCurve = crv.Curve() if interval is None: return Shape(BRepBuilderAPI_MakeEdge(aCurve).Edge()) else: return Shape( BRepBuilderAPI_MakeEdge(aCurve, interval[0], interval[1]).Edge())
def _box(x, y=None, z=None, center=False, size=None): if size is None: size = x if isinstance(size, (float, int)): x = size if y is None and z is None: size = (x, x, x) else: if z is None: size = (x, y, 0) else: size = (x, y, z) x, y, z = size[0], size[1], size[2] if center: pnt = point3() if center is True: pnt = point3(-x / 2, -y / 2, -z / 2) if isinstance(center, str): if ("x" in center): pnt += point3(-x/2, 0, 0) if ("y" in center): pnt += point3(0, -y/2, 0) if ("z" in center): pnt += point3(0, 0, -z/2) ax2 = gp_Ax2(pnt.Pnt(), gp_Dir(0, 0, 1)) return Shape(OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeBox(ax2, *size).Shape()) else: return Shape(OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeBox(*size).Shape())
def _revol(shp, r=None, yaw=0.0): if r is not None: shp = shp.rotX(deg(90)).movX(r) ax = gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)) if yaw == 0: return Shape(BRepPrimAPI_MakeRevol(shp.Shape(), ax).Shape()) else: return Shape(BRepPrimAPI_MakeRevol(shp.Shape(), ax, yaw).Shape())
def _unify_solid(proto): mkSolid = BRepBuilderAPI_MakeSolid() explorer = TopExp_Explorer() explorer.Init(proto.Shape(), TopAbs_SHELL) while explorer.More(): mkSolid.Add(_unify_shell(Shape(explorer.Current())).Shell()) explorer.Next() mkSolid.Build() return Shape(mkSolid.Shape())
def _make_shell(vec): algo = BRepOffsetAPI_Sewing() for a in vec: algo.Add(a.Shape()) algo.Perform() if len(vec) > 1: fixer = ShapeFix_Shell(algo.SewedShape()) fixer.Perform() return Shape(fixer.Shell()) else: return Shape(algo.SewedShape())
def _fill(wires): if not isinstance(wires, (list, tuple)): return Shape(BRepBuilderAPI_MakeFace(wires.Wire_orEdgeToWire()).Face()) algo = BRepBuilderAPI_MakeFace(wires[0].Wire_orEdgeToWire()) for i in range(1, len(wires)): algo.Add(wires[i].Wire_orEdgeToWire()) algo.Build() fixer = ShapeFix_Face(algo.Face()) fixer.Perform() fixer.FixOrientation() return Shape(fixer.Face())
def _make_face(surf, u1=None, u2=None, v1=None, v2=None): if u1 is None: u1, u2, v1, v2 = surf.Surface().Bounds() algo = BRepBuilderAPI_MakeFace(surf.Surface(), u1, u2, v1, v2, 1e-6) algo.Build() return Shape(algo.Face())
def _union(lst): if len(lst) == 1: return lst[0] nrsize = 0 rsize = len(lst) // 2 + len(lst) % 2 narr = [TopoDS_Shape() for i in range(rsize)] for i in range(len(lst) // 2): narr[i] = occ_pair_union(lst[i].Shape(), lst[len(lst) - i - 1].Shape()) if len(lst) % 2: narr[rsize - 1] = lst[len(lst) // 2].Shape() while rsize != 1: nrsize = rsize // 2 + rsize % 2 for i in range(rsize // 2): narr[i] = occ_pair_union(narr[i], narr[rsize - i - 1]) if rsize % 2: narr[nrsize - 1] = narr[rsize // 2] rsize = nrsize return Shape(narr[0])
def _intersect(lst): ret = lst[0].Shape() for i in range(1, len(lst)): ret = occ_pair_intersect(ret, lst[i].Shape()) return Shape(ret)
def _difference(lst): ret = lst[0].Shape() for i in range(1, len(lst)): ret = occ_pair_difference(ret, lst[i].Shape()) return Shape(ret)
def create_interactive_object(obj, color=None): if isinstance(obj, InteractiveObject): return obj if isinstance(color, (tuple, list)): color = Color(*color) if isinstance( obj, (OCC.Core.TopoDS.TopoDS_Edge, OCC.Core.TopoDS.TopoDS_Wire, OCC.Core.TopoDS.TopoDS_Vertex, OCC.Core.TopoDS.TopoDS_Face, OCC.Core.TopoDS.TopoDS_Compound, OCC.Core.TopoDS.TopoDS_CompSolid, OCC.Core.TopoDS.TopoDS_Shell, OCC.Core.TopoDS.TopoDS_Solid, OCC.Core.TopoDS.TopoDS_Shape)): obj = Shape(obj) if isinstance(obj, Shape): return ShapeInteractiveObject(obj, color) elif isinstance(obj, Axis): return AxisInteractiveObject(obj, color) elif isinstance(obj, (Geom_CartesianPoint, point3)): return PointInteractiveObject(obj, color) else: raise Exception("unresolved type", obj.__class__)
def _chamfer(shp, r, refs=None): if refs: refs = points(refs) if shp.is_solid() or shp.is_compound() or shp.is_compsolid(): mk = BRepFilletAPI_MakeChamfer(shp.Shape()) if refs: for p in refs: minimum = float("inf") vtx = p.Vtx() for edg in shp.edges(): extrema = BRepExtrema_DistShapeShape(edg.Edge(), vtx) if minimum > extrema.Value(): ret = edg minimum = extrema.Value() mk.Add(r, ret.Edge()) else: for edg in shp.edges(): mk.Add(r, edg.Edge()) return Shape(mk.Shape()) else: raise Exception("Fillet argument has unsuported type.")
def _from_brep(path): from zencad.geom.shape import Shape path = os.path.expanduser(path) shp = TopoDS_Shape() builder = BRep_Builder() breptools.Read(shp, path, builder) return Shape(shp)
def _unify_shell(proto): faces = [] mkShell = BRepOffsetAPI_Sewing() newfaces = _unify_faces_array(proto.faces()) for n in newfaces: mkShell.Add(n.Shape()) mkShell.Perform() return Shape(mkShell.SewedShape())
def _fillet2d(shp, r, refs=None): mk = BRepFilletAPI_MakeFillet2d(shp.Face()) if refs is None: refs = shp.vertices() for p in refs: mk.AddFillet(_near_vertex(shp, p).Vertex(), r) return Shape(mk.Shape())
def _make_wire(arr): mk = BRepBuilderAPI_MakeWire() for ptr in arr: if (ptr.Shape().ShapeType() == TopAbs_WIRE): mk.Add(ptr.Wire()) elif (ptr.Shape().ShapeType() == TopAbs_EDGE): mk.Add(ptr.Edge()) return Shape(mk.Wire())
def _thicksolid(proto, t, refs): facesToRemove = TopTools_ListOfShape() for p in refs: facesToRemove.Append(_near_face(proto, p).Face()) algo = BRepOffsetAPI_MakeThickSolid() algo.MakeThickSolidByJoin(proto.Shape(), facesToRemove, t, 1.e-3) return Shape(algo.Shape())
def _cylinder(r, h, yaw=None, center=False): if yaw: if center: ax2 = gp_Ax2(gp_Pnt(0, 0, -h/2), gp_Dir(0, 0, 1)) raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeCylinder( ax2, r, h, yaw).Shape() return Shape(raw) else: raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeCylinder( r, h, yaw).Shape() return Shape(raw) else: if center: ax2 = gp_Ax2(gp_Pnt(0, 0, -h/2), gp_Dir(0, 0, 1)) raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeCylinder( ax2, r, h).Shape() return Shape(raw) else: raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeCylinder(r, h).Shape() return Shape(raw)
def _section(a, b, pretty): algo = BRepAlgoAPI_Section(a.Shape(), b.Shape()) if pretty: algo.ComputePCurveOn1(True) algo.Approximation(True) algo.Build() if not algo.IsDone(): printf("warn: section algotithm failed\n") return Shape(algo.Shape())
def _loft(arr, smooth=False, shell=False, maxdegree=4): builder = BRepOffsetAPI_ThruSections(not shell, not smooth) builder.SetMaxDegree(maxdegree) for v in arr: if v.Shape().ShapeType() == TopAbs_FACE: raise Exception("Loft argument must be array of Wires or Edges") for r in arr: builder.AddWire(r.Wire_orEdgeToWire()) return Shape(builder.Shape())
def _make_solid(shells): if not isinstance(shells, (list, tuple)): shells = [shells] algo = BRepBuilderAPI_MakeSolid() for s in shells: algo.Add(s.Shell()) fixer = ShapeFix_Solid(algo.Solid()) fixer.Perform() return Shape(fixer.Solid())
def _polygon(pnts, wire=False): pnts = points(pnts) if wire: return wire_module._polysegment(pnts, closed=True) mk = BRepBuilderAPI_MakePolygon() for i in range(len(pnts)): mk.Add(pnts[i].Pnt()) mk.Close() return Shape(BRepBuilderAPI_MakeFace(mk.Shape()).Face())
def _torus(r1, r2, yaw=None, pitch=None): if yaw is None and pitch is None: raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeTorus(r1, r2).Shape() elif yaw is None and pitch is not None: pitch = angle_pair(pitch) raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeTorus( r1, r2, pitch[0], pitch[1]).Shape() elif yaw is not None and pitch is None: raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeTorus(r1, r2, yaw).Shape() else: pitch = angle_pair(pitch) raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeTorus( r1, r2, pitch[0], pitch[1], yaw).Shape() return Shape(raw)
def _sphere(r, yaw=None, pitch=None): if yaw is None and pitch is None: raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeSphere(r).Shape() elif yaw is None and pitch is not None: pitch = angle_pair(pitch) raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeSphere( r, pitch[0], pitch[1]).Shape() elif yaw is not None and pitch is None: raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeSphere(r, yaw).Shape() else: pitch = angle_pair(pitch) raw = OCC.Core.BRepPrimAPI.BRepPrimAPI_MakeSphere( r, pitch[0], pitch[1], yaw).Shape() return Shape(raw)
def _extrude(shp, vec, center=False): if type(vec) in (float, int): vec = vector3(0, 0, vec) else: vec = vector3(vec) if center: trs = translate(-vec / 2) return _extrude(trs(shp), vec) # Если в объекте есть только один face, но сам объект не face, # извлекаем face и применяем влгоритм на нём. shp = _restore_shapetype(shp) obj = shp.Shape() return Shape(BRepPrimAPI_MakePrism(obj, vec.Vec()).Shape())
def _near_part(shp, pnt, topabs): min = float("inf") ret = shape_types[topabs].construct() vtx = point3(pnt).Vtx() ex = TopExp_Explorer(shp.Shape(), topabs) while ex.More(): obj = shape_types[topabs].convert(ex.Current()) extrema = BRepExtrema_DistShapeShape(obj, vtx) if min > extrema.Value(): ret = obj min = extrema.Value() ex.Next() return Shape(ret)
def _pipe(shp, spine, mode="corrected_frenet", force_approx_c1=False): if (spine.Shape().IsNull()): raise Exception("Cannot sweep along empty spine") if (shp.Shape().IsNull()): raise Exception("Cannot sweep empty profile") try: if isinstance(mode, str): tri = geomfill_triedron_map[mode] else: tri = mode except Exception: raise Exception("pipe: undefined mode") return Shape(BRepOffsetAPI_MakePipe(spine.Wire_orEdgeToWire(), shp.Shape(), tri, force_approx_c1).Shape())
def _pipe_shell( arr, spine, frenet=False, approx_c1=False, binormal=None, parallel=None, discrete=False, solid=True, transition=0 ): mkPipeShell = BRepOffsetAPI_MakePipeShell(spine.Wire_orEdgeToWire()) if transition == 1: transMode = BRepBuilderAPI_RightCorner elif transition == 2: transMode = BRepBuilderAPI_RoundCorner else: transMode = BRepBuilderAPI_Transformed mkPipeShell.SetMode(frenet) mkPipeShell.SetTransitionMode(transMode) mkPipeShell.SetForceApproxC1(approx_c1) if binormal is not None: mkPipeShell.SetMode(binormal.Dir()) if parallel is not None: mkPipeShell.SetMode(gp_Ax2(gp_Pnt(0, 0, 0), parallel.Dir())) if discrete: mkPipeShell.SetDiscreteMode() for a in arr: mkPipeShell.Add(a.Wire_orEdgeToWire()) if not mkPipeShell.IsReady(): raise Exception("shape is not ready to build") mkPipeShell.Build() if solid: mkPipeShell.MakeSolid() return Shape(mkPipeShell.Shape())
def _polysegment(pnts, closed=False) -> Shape: if len(pnts) <= 1: raise Exception("Need at least two points for polysegment") mkWire = BRepBuilderAPI_MakeWire() def __make_edge(a, b): try: return BRepBuilderAPI_MakeEdge(to_Pnt(a), to_Pnt(b)).Edge() except: raise Exception(f"Cannot make edge segment from points {a}, {b}") for i in range(len(pnts) - 1): mkWire.Add(__make_edge(pnts[i], pnts[i + 1])) if (closed): mkWire.Add(__make_edge(pnts[len(pnts) - 1], pnts[0])) return Shape(mkWire.Wire())