def fix_collinear(cls, wire, tol): """ :return: """ if wire.Reversed() is 1: wire.Reverse() explorer = BRepTools_WireExplorer(wire) prev = None while explorer.More(): curr = explorer.Current() if prev is None: prev = curr explorer.Next() continue v1 = gp.gp_Vec(topexp.FirstVertex(curr), topexp.LastVertex(curr)) v2 = gp.gp_Vec(topexp.FirstVertex(prev), topexp.LastVertex(prev)) if v1.Angle(v2) < tol: # remove common vertex comm = topexp.CommonVertex(curr, prev) # if angle between these is close to 0 or pi, remove the vertex ... return
def make_faces_from_edges(edges): """ assumes """ import networkx as nx G = nx.Graph() m = {} # N = len(edges) # seen = [None]*N for edge in edges: v1 = topexp.FirstVertex(edge) v2 = topexp.LastVertex(edge) m[hash(edge)] = edge node = hash(edge) G.add_node(node, isedge=1) G.add_edge(node, hash(v1)) G.add_edge(node, hash(v2)) faces = [] for i, c in enumerate(nx.connected_components(G)): group = [] for n in c: if G.node[n].get('isedge', None) == 1: group.append(m[n]) w = make_wirex(*group) f = make_face(w) faces.append(f) print('groups', len(faces)) return faces
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)
def sort_edges_into_order(occedgelist, isclosed=False): from OCC.TopoDS import topods from OCC.TopExp import topexp from OCC.BRep import BRep_Tool from OCC.ShapeAnalysis import ShapeAnalysis_WireOrder from OCC.Precision import precision sawo_statusdict = { 0: "all edges are direct and in sequence", 1: "all edges are direct but some are not in sequence", 2: "unresolved gaps remain", -1: "some edges are reversed, but no gaps remain", -2: "some edges are reversed and some gaps remain", -10: "failure on reorder" } mode3d = True SAWO = ShapeAnalysis_WireOrder(mode3d, precision.PConfusion()) for occedge in occedgelist: V1 = topexp.FirstVertex(topods.Edge(occedge)) V2 = topexp.LastVertex(topods.Edge(occedge)) pnt1 = BRep_Tool().Pnt(V1) pnt2 = BRep_Tool().Pnt(V2) SAWO.Add(pnt1.XYZ(), pnt2.XYZ()) SAWO.SetKeepLoopsMode(True) SAWO.Perform(isclosed) #print "SAWO.Status()", SAWO.Status() if not SAWO.IsDone(): raise RuntimeError, "build wire: Unable to reorder edges: \n" + sawo_statusdict[ SAWO.Status()] else: if SAWO.Status() not in [0, -1]: pass # not critical, wirebuilder will handle this SAWO.SetChains(precision.PConfusion()) sorted_edge2dlist = [] #print "Number of chains: ", SAWO.NbChains() for i in range(SAWO.NbChains()): sorted_edges = [] estart, eend = SAWO.Chain(i + 1) #print "Number of edges in chain", i, ": ", eend - estart + 1 if (eend - estart + 1) == 0: continue for j in range(estart, eend + 1): idx = abs(SAWO.Ordered(j)) edge2w = occedgelist[idx - 1] if SAWO.Ordered(j) < 0: edge2w.Reverse() sorted_edges.append(edge2w) sorted_edge2dlist.append(sorted_edges) return sorted_edge2dlist
def last_vertex(self): return topexp.LastVertex(self)
def arrange_edges_2_wires(occedgelist, isclosed=False): from OCC.TopoDS import topods from OCC.TopExp import topexp from OCC.BRep import BRep_Tool from OCC.ShapeAnalysis import ShapeAnalysis_WireOrder from OCC.Precision import precision from OCC.BRepBuilderAPI import BRepBuilderAPI_WireDone, BRepBuilderAPI_EmptyWire, BRepBuilderAPI_DisconnectedWire, BRepBuilderAPI_NonManifoldWire wb_errdict = { BRepBuilderAPI_WireDone: "No error", BRepBuilderAPI_EmptyWire: "Empty wire", BRepBuilderAPI_DisconnectedWire: "disconnected wire", BRepBuilderAPI_NonManifoldWire: "non-manifold wire" } sawo_statusdict = { 0: "all edges are direct and in sequence", 1: "all edges are direct but some are not in sequence", 2: "unresolved gaps remain", -1: "some edges are reversed, but no gaps remain", -2: "some edges are reversed and some gaps remain", -10: "failure on reorder" } mode3d = True SAWO = ShapeAnalysis_WireOrder(mode3d, precision.PConfusion()) for edge in occedgelist: V1 = topexp.FirstVertex(topods.Edge(edge)) V2 = topexp.LastVertex(topods.Edge(edge)) pnt1 = BRep_Tool().Pnt(V1) pnt2 = BRep_Tool().Pnt(V2) SAWO.Add(pnt1.XYZ(), pnt2.XYZ()) SAWO.SetKeepLoopsMode(True) SAWO.Perform(isclosed) #print "SAWO.Status()", SAWO.Status() if not SAWO.IsDone(): raise RuntimeError, "build wire: Unable to reorder edges: \n" + sawo_statusdict[ SAWO.Status()] else: if SAWO.Status() not in [0, -1]: pass # not critical, wirebuilder will handle this SAWO.SetChains(precision.PConfusion()) wirelist = [] #print "Number of chains: ", SAWO.NbChains() for i in range(SAWO.NbChains()): wirebuilder = BRepBuilderAPI_MakeWire() estart, eend = SAWO.Chain(i + 1) #print "Number of edges in chain", i, ": ", eend - estart + 1 if (eend - estart + 1) == 0: continue for j in range(estart, eend + 1): idx = abs( SAWO.Ordered(j) ) # wirebuilder = s_addToWireBuilder(wirebuilder, edgelist[idx-1]) edge2w = occedgelist[idx - 1] wirebuilder.Add(edge2w) if wirebuilder is None: raise RuntimeError, " build wire: Error adding edge number " + str( j + 1) + " to Wire number " + str(i) err = wirebuilder.Error() if err != BRepBuilderAPI_WireDone: raise RuntimeError, "Overlay2D: build wire: Error adding edge number " + str( j + 1) + " to Wire number " + str( i) + ": \n" + wb_errdict[err] try: wirebuilder.Build() aWire = wirebuilder.Wire() wirelist.append(aWire) except Exception, err: raise RuntimeError, "Overlay2D: build wire: Creation of Wire number " + str( i) + " from edge(s) failed. \n" + str(err) wirebuilder.Build() aWire = wirebuilder.Wire() wirelist.append(aWire)
def other_vertex(edge: TopoDS_Edge, vert: TopoDS_Vertex): if hash(vert) == hash(topexp.FirstVertex(edge)): return topexp.LastVertex(edge) elif hash(vert) == hash(topexp.LastVertex(edge)): return topexp.FirstVertex(edge) return None
def __call__(self, plane: gp.gp_Pln, vertex=None, edge_dict=None, **kwargs): if isinstance(self._base, TopoDS_Shape): base_shape = self._base else: base_shape = self._base.Shape() new_shape = Splitter.__call__(self, plane) # ------------------------------------- # dict updates if edge_dict: # includes 3 new edges, # 2 edges - 'replacement' for cut edge # 1 edge - 'cutter' the edge # and 1 edge that is 'removed' new_hash = ShapeDict.of_edges(new_shape) for new in self.added: # remove the 'cutter' edge from new_hash hnew = hash(new) new_hash.remove(hnew) # add 'cutter' to state dict edge_dict[hnew] = -1 # find the 'removed' edge prev_hash = ShapeDict.of_edges(base_shape) removed_edges = prev_hash.difference(new_hash) assert len(removed_edges) == 1 removed_id = list(removed_edges.keys())[0] for eid in new_hash: if eid not in edge_dict: # updated the 'replacement' edges with edge_dict[eid] = removed_edges[removed_id] # remove the 'removed' edge from state dict edge_dict.remove(removed_id) # ------------------------------------- # find the edge that is out of order on one of the faces # technically, this should be self.new_edge FACES = list(Topo(new_shape).faces()) to_swap = [] for i, face in enumerate(FACES): wire = brep.breptools.OuterWire(face) edge_iter = brep.BRepTools_WireExplorer(wire, face) orient1 = defaultdict(int) cnt = 0 while edge_iter.More(): edge_in_new = edge_iter.Current() cnt += 1 orient1[edge_in_new.Orientation()] += 1 edge_iter.Next() bestk, bestv = None, float('inf') for k, v in orient1.items(): if v < bestv: bestk, bestv = k, v # only one edge should be disoriented.... if bestv != cnt: edge_iter.Clear() edge_iter = brep.BRepTools_WireExplorer(wire, face) while edge_iter.More(): edge_in_new = edge_iter.Current() if edge_in_new.Orientation() == bestk: to_swap.append([i, edge_in_new]) edge_iter.Next() print(len(to_swap)) # once again this should only ever be length one ... for i, edge in to_swap: va = topexp.FirstVertex(edge) vb = topexp.LastVertex(edge) new_edge = Construct.make_edge(va, vb) if edge_dict: edge_dict[hash(new_edge)] = -1 # for edge in # not quite working .... reshaper = brep.BRepTools_ReShape() reshaper.Replace(edge, new_edge) fi = FACES[i] FACES[i] = reshaper.Apply(fi) print('swap', fi, FACES[i]) return FACES
def last_vertex(self) -> TopoDS_Vertex: return topexp.LastVertex(self)