def vertex_fillet(cube_shp, vert): # apply a fillet on incident edges on a vertex afillet = BRepFilletAPI_MakeFillet(cube_shp) cnt = 0 # find edges from vertex _map = TopTools_IndexedDataMapOfShapeListOfShape() topexp_MapShapesAndAncestors(cube_shp, TopAbs_VERTEX, TopAbs_EDGE, _map) results = _map.FindFromKey(vert) topology_iterator = TopTools_ListIteratorOfListOfShape(results) while topology_iterator.More(): edge = topods_Edge(topology_iterator.Value()) topology_iterator.Next() first, last = topexp_FirstVertex(edge), topexp_LastVertex(edge) vertex, first_vert, last_vert = BRep_Tool().Pnt(vert), BRep_Tool().Pnt( first), BRep_Tool().Pnt(last) if edge.Orientation(): if not vertex.IsEqual(first_vert, 0.001): afillet.Add(0, 20., edge) else: afillet.Add(20, 0, edge) cnt += 1 afillet.Build() if afillet.IsDone(): return afillet.Shape() else: raise AssertionError('you failed on me you fool!')
def pcurve(self, face): """ computes the 2d parametric spline that lies on the surface of the face :return: Geom2d_Curve, u, v """ crv, u, v = BRep_Tool().CurveOnSurface(self, face) return crv.GetObject(), u, v
def curve(self): if self._curve is not None and not self.is_dirty: pass else: self._curve_handle = BRep_Tool().Curve(self)[0] self._curve = self._curve_handle.GetObject() return self._curve
def project_curve(self, other): # this way Geom_Circle and alike are valid too if (isinstance(other, TopoDS_Edge) or isinstance(other, Geom_Curve) or issubclass(other, Geom_Curve)): # convert edge to curve first, last = topexp.FirstVertex(other), topexp.LastVertex(other) lbound, ubound = BRep_Tool().Parameter( first, other), BRep_Tool().Parameter(last, other) other = BRep_Tool.Curve(other, lbound, ubound).GetObject() return geomprojlib.Project(other, self.surface_handle)
class LoopWirePairs(object): ''' for looping through consequtive wires assures that the returned edge pairs are ordered ''' def __init__(self, wireA, wireB): self.wireA = wireA self.wireB = wireB self.we_A = WireExplorer(self.wireA) self.we_B = WireExplorer(self.wireB) self.tp_A = Topo(self.wireA) self.tp_B = Topo(self.wireB) self.bt = BRep_Tool() self.vertsA = [v for v in self.we_A.ordered_vertices()] self.vertsB = [v for v in self.we_B.ordered_vertices()] self.edgesA = [v for v in WireExplorer(wireA).ordered_edges()] self.edgesB = [v for v in WireExplorer(wireB).ordered_edges()] self.pntsB = [self.bt.Pnt(v) for v in self.vertsB] self.number_of_vertices = len(self.vertsA) self.index = 0 def closest_point(self, vertexFromWireA): pt = self.bt.Pnt(vertexFromWireA) distances = [pt.Distance(i) for i in self.pntsB] indx_max_dist = distances.index(min(distances)) return self.vertsB[indx_max_dist] def next(self): if self.index == self.number_of_vertices: raise StopIteration vert = self.vertsA[self.index] closest = self.closest_point(vert) edges_a = self.tp_A.edges_from_vertex(vert) edges_b = self.tp_B.edges_from_vertex(closest) a1, a2 = Edge(next(edges_a)), Edge(next(edges_a)) b1, b2 = Edge(next(edges_b)), Edge(next(edges_b)) mpA = a1.mid_point() self.index += 1 if mpA.Distance(b1.mid_point()) < mpA.Distance(b2.mid_point()): return iter([a1, a2]), iter([b1, b2]) else: return iter([a1, a2]), iter([b2, b1]) def __iter__(self): return self
def parameter(vertex, edge, face=None): """ Return the parameter of the vertex on the edge. :param OCCT.TopoDS.TopoDS_Vertex vertex: The vertex. :param OCCT.TopoDS.TopoDS_Edge edge: The edge. :param OCCT.TopoDS.TopoDS_Face face: The face. :return: The parameter. :rtype: float """ if not face: BRep_Tool.Parameter_(vertex, edge) else: return BRep_Tool.Parameter_(vertex, edge, face)
def continuity_edge_face(self, edge, face): """ compute the continuity between two faces at :edge: :param edge: an Edge or TopoDS_Edge from :face: :param face: a Face or TopoDS_Face :return: bool, GeomAbs_Shape if it has continuity, otherwise False, None """ bt = BRep_Tool() if bt.HasContinuity(edge, self, face): continuity = bt.Continuity(edge, self, face) return True, continuity else: return False, None
def point(self): """ :return: A point at vertex location. :rtype: afem.geometry.entities.Point """ gp_pnt = BRep_Tool.Pnt_(self.object) return Point(gp_pnt.X(), gp_pnt.Y(), gp_pnt.Z())
def curve(self): """ :return: The underlying curve of the edge. :rtype: afem.geometry.entities.Curve """ geom_curve, _, _ = BRep_Tool.Curve_(self.object, 0., 0.) return Curve.wrap(geom_curve)
def surface(self): """ :return: The underlying surface of the face. :rtype: afem.geometry.entities.Surface """ geom_surface = BRep_Tool.Surface_(self.object) return Surface.wrap(geom_surface)
def __init__(self, x=0, y=0, z=0, **kwargs): if isinstance(x, TopoDS_Shape): pnt = BRep_Tool.Pnt_(x) x, y, z = pnt.X(), pnt.Y(), pnt.Z() elif isinstance(x, gp_Pnt): x, y, z = pnt.X(), pnt.Y(), pnt.Z() super().__init__(x=x, y=y, z=z, **kwargs)
def __init__(self, shape1, shape2, pnt=None, tol=-1.): shape = IntersectShapes(shape1, shape2).shape pnt = CheckGeom.to_point(pnt) self._found = False self._pln = None if pnt is None: tool = PlaneByEdges(shape, tol) self._found = tool.found self._pln = tool.plane elif CheckGeom.is_point(pnt): edges = shape.edges pnts = [pnt] for edge in edges: BRepMesh_IncrementalMesh(edge.object, 0.001) loc = TopLoc_Location() poly3d = BRep_Tool.Polygon3D_(edge.object, loc) if poly3d.NbNodes == 0: continue tcol_pnts = poly3d.Nodes() for i in range(1, tcol_pnts.Length() + 1): gp_pnt = tcol_pnts.Value(i) pnt = CheckGeom.to_point(gp_pnt) pnts.append(pnt) if len(pnts) < 3: raise ValueError('Less than three points to fit a plane.') if tol < 0.: tol = 1.0e-7 tool = PlaneByApprox(pnts, tol) self._found = True self._pln = tool.plane else: raise TypeError('Invalid input.')
def __init__(self, wireA, wireB): self.wireA = wireA self.wireB = wireB self.we_A = WireExplorer(self.wireA) self.we_B = WireExplorer(self.wireB) self.tp_A = Topo(self.wireA) self.tp_B = Topo(self.wireB) self.bt = BRep_Tool() self.vertsA = [v for v in self.we_A.ordered_vertices()] self.vertsB = [v for v in self.we_B.ordered_vertices()] self.edgesA = [v for v in WireExplorer(wireA).ordered_edges()] self.edgesB = [v for v in WireExplorer(wireB).ordered_edges()] self.pntsB = [self.bt.Pnt(v) for v in self.vertsB] self.number_of_vertices = len(self.vertsA) self.index = 0
def face_normal(face): from OCCT.BRepTools import breptools_UVBounds umin, umax, vmin, vmax = breptools_UVBounds(face) surf = BRep_Tool().Surface(face) props = GeomLProp_SLProps(surf, (umin+umax)/2., (vmin+vmax)/2., 1, TOLERANCE) norm = props.Normal() if face.Orientation() == TopAbs_REVERSED: norm.Reverse() return norm
def dumpTopology(shape, level=0): """ Print the details of an object from the top down """ brt = BRep_Tool() s = shape.ShapeType() if s == TopAbs_VERTEX: pnt = brt.Pnt(topods_Vertex(shape)) print(".." * level + "<Vertex %i: %s %s %s>" % (hash(shape), pnt.X(), pnt.Y(), pnt.Z())) else: print(".." * level, end="") print(shapeTypeString(shape)) it = TopoDS_Iterator(shape) while it.More(): shp = it.Value() it.Next() dumpTopology(shp, level + 1)
def uv_from_projected_point_on_face(face, pt): ''' returns the uv coordinate from a projected point on a face ''' srf = BRep_Tool().Surface(face) sas = ShapeAnalysis_Surface(srf) uv = sas.ValueOfUV(pt, 1e-2) print('distance ', sas.Value(uv).Distance(pt)) return uv.Coord()
def make_edge(self, *args): d = self.declaration if d.surface: # Convert the curve to 2d args = list(args) pln = gp_Pln(d.position.proxy, d.direction.proxy) args[0] = GeomAPI.To2d_(args[0], pln) args.insert(1, BRep_Tool.Surface_(d.surface)) return BRepBuilderAPI_MakeEdge(*args).Edge()
def update_shape(self, change=None): d = self.declaration child = self.get_first_child() if hasattr(child, 'curve'): curve = child.curve else: curve = BRep_Tool.Curve_(child.shape, 0, 1)[0] trimmed_curve = self.curve = Geom_TrimmedCurve(curve, d.u, d.v) self.shape = self.make_edge(trimmed_curve)
def coerce_point(arg): if isinstance(arg, TopoDS_Shape): arg = BRep_Tool.Pnt_(arg) if hasattr(arg, 'XYZ'): # copy from gp_Pnt, gp_Vec, gp_Dir, etc.. return Point(arg.X(), arg.Y(), arg.Z()) if isinstance(arg, Point): return arg if isinstance(arg, dict): return Point(**arg) return Point(*arg)
def same_parameter(edge): """ Returns the SameParameter flag for the edge. :param OCCT.TopoDS.TopoDS_Edge edge: The edge. :return: The same parameter flag. :rtype: bool """ return BRep_Tool.SameParameter_(edge)
def coerce_direction(arg): if isinstance(arg, TopoDS_Shape): arg = BRep_Tool.Pnt_(arg) if hasattr(arg, 'XYZ'): # copy from gp_Pnt2d, gp_Vec2d, gp_Dir2d, etc.. return Direction(arg.X(), arg.Y(), arg.Z()) if isinstance(arg, Direction): return arg if isinstance(arg, dict): return Direction(**arg) return Direction(*arg)
def same_range(edge): """ Returns the SameRange flag for the edge. :param OCCT.TopoDS.TopoDS_Edge edge: The edge. :return: The same range flag. :rtype: bool """ return BRep_Tool.SameRange_(edge)
def pnt_of_vertex(vertex): """ Get the underlying point of the vertex. :param OCCT.TopoDS.TopoDS_Vertex vertex: The vertex. :return: The point. :rtype: OCCT.gp.gp_Pnt """ return BRep_Tool.Pnt_(vertex)
def curve_of_edge(edge): """ Get the curve of the edge. :param OCCT.TopoDS.TopoDS_Edge edge: The edge. :return: Underlying curve of edge. :rtype: OCCT.Geom.Geom_Curve """ return BRep_Tool.Curve_(edge, 0., 0.)
def surface_of_face(face): """ Get the surface of the face. :param OCCT.TopoDS.TopoDS_Face face: The face. :return: Underlying surface of face. :rtype: OCCT.Geom.Geom_Surface """ return BRep_Tool.Surface_(face)
def simple_mesh(): # # Create the shape # theBox = BRepPrimAPI_MakeBox(200, 60, 60).Shape() theSphere = BRepPrimAPI_MakeSphere(gp_Pnt(100, 20, 20), 80).Shape() shape = BRepAlgoAPI_Fuse(theSphere, theBox).Shape() # # Mesh the shape # BRepMesh_IncrementalMesh(shape, 0.8) builder = BRep_Builder() comp = TopoDS_Compound() builder.MakeCompound(comp) bt = BRep_Tool() ex = TopExp_Explorer(shape, TopAbs_FACE) while ex.More(): face = topods_Face(ex.Current()) location = TopLoc_Location() facing = (bt.Triangulation(face, location)) tab = facing.Nodes() tri = facing.Triangles() for i in range(1, facing.NbTriangles() + 1): trian = tri.Value(i) index1, index2, index3 = trian.Get() for j in range(1, 4): if j == 1: m = index1 n = index2 elif j == 2: n = index3 elif j == 3: m = index2 me = BRepBuilderAPI_MakeEdge(tab.Value(m), tab.Value(n)) if me.IsDone(): builder.Add(comp, me.Edge()) ex.Next() display.EraseAll() display.DisplayShape(shape) display.DisplayShape(comp, update=True)
def vertex_clicked(shp, *kwargs): """ This function is called whenever a vertex is selected """ for shape in shp: # this should be a TopoDS_Vertex print("Face selected: ", shape) v = topods_Vertex(shape) pnt = BRep_Tool.Pnt(v) print("3d gp_Pnt selected coordinates : X=", pnt.X(), "Y=", pnt.Y(), "Z=", pnt.Z()) # then convert to screen coordinates screen_coord = display.View.Convert(pnt.X(), pnt.Y(), pnt.Z()) print("2d screen coordinates : ", screen_coord)
def project_vertex(self, pnt, tol=TOLERANCE): '''projects self with a point, curve, edge, face, solid method wraps dealing with the various topologies if other is a point: returns uv, point ''' if isinstance(pnt, TopoDS_Vertex): pnt = BRep_Tool.Pnt(pnt) proj = GeomAPI_ProjectPointOnSurf(pnt, self.surface_handle, tol) uv = proj.LowerDistanceParameters() proj_pnt = proj.NearestPoint() return uv, proj_pnt
def radius_at_uv(face, u, v): ''' returns the mean radius at a u,v coordinate @param face: surface input @param u,v: u,v coordinate ''' h_srf = BRep_Tool().Surface(face) #uv_domain = GeomLProp_SurfaceTool().Bounds(h_srf) curvature = GeomLProp_SLProps(h_srf, u, v, 1, 1e-6) try: _crv_min = 1. / curvature.MinCurvature() except ZeroDivisionError: _crv_min = 0. try: _crv_max = 1. / curvature.MaxCurvature() except ZeroDivisionError: _crv_max = 0. return abs((_crv_min + _crv_max) / 2.)
def _build_solid(compound, divide_closed): """ Method to try and build a valid solid from an OpenVSP component. """ # Get all the faces in the compound. The surfaces must be split. Discard # any with zero area. top_exp = TopExp_Explorer(compound, TopAbs_FACE) faces = [] while top_exp.More(): shape = top_exp.Current() face = CheckShape.to_face(shape) fprop = GProp_GProps() BRepGProp.SurfaceProperties_(face, fprop, 1.0e-7) a = fprop.Mass() if a <= 1.0e-7: top_exp.Next() continue faces.append(face) top_exp.Next() # Replace any planar B-Spline surfaces with planes non_planar_faces = [] planar_faces = [] for f in faces: hsrf = BRep_Tool.Surface_(f) try: is_pln = GeomLib_IsPlanarSurface(hsrf, 1.0e-7) if is_pln.IsPlanar(): w = ShapeAnalysis.OuterWire_(f) # Fix the wire because they are usually degenerate edges in # the planar end caps. builder = BRepBuilderAPI_MakeWire() for e in ExploreShape.get_edges(w): if LinearProps(e).length > 1.0e-7: builder.Add(e) w = builder.Wire() fix = ShapeFix_Wire() fix.Load(w) geom_pln = Geom_Plane(is_pln.Plan()) fix.SetSurface(geom_pln) fix.FixReorder() fix.FixConnected() fix.FixEdgeCurves() fix.FixDegenerated() w = fix.WireAPIMake() # Build the planar face fnew = BRepBuilderAPI_MakeFace(w, True).Face() planar_faces.append(fnew) else: non_planar_faces.append(f) except RuntimeError: non_planar_faces.append(f) # Make a compound of the faces shape = CreateShape.compound(non_planar_faces + planar_faces) # Split closed faces if divide_closed: divide = ShapeUpgrade_ShapeDivideClosed(shape) divide.Perform() shape = divide.Result() # Sew shape sew = BRepBuilderAPI_Sewing(1.0e-7) sew.Load(shape) sew.Perform() sewn_shape = sew.SewedShape() if sewn_shape.ShapeType() == TopAbs_FACE: face = sewn_shape sewn_shape = TopoDS_Shell() builder = BRep_Builder() builder.MakeShell(sewn_shape) builder.Add(sewn_shape, face) # Attempt to unify planar domains unify_shp = ShapeUpgrade_UnifySameDomain(sewn_shape, False, True, False) unify_shp.Build() shape = unify_shp.Shape() # Make solid shell = ExploreShape.get_shells(shape)[0] solid = ShapeFix_Solid().SolidFromShell(shell) # Limit tolerance FixShape.limit_tolerance(solid) # Check shape validity check_shp = BRepCheck_Analyzer(solid, True) if check_shp.IsValid(): return solid, True, [] else: invalid_shapes = _topods_iterator_check(solid, check_shp) return solid, False, invalid_shapes