def vertex_fillet(cube, vert): # apply a fillet on incident edges on a vertex afillet = BRepFilletAPI_MakeFillet(cube) cnt = 0 # find edges from vertex _map = TopTools_IndexedDataMapOfShapeListOfShape() topexp_MapShapesAndAncestors(cube, 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 simple_mesh(occshape, mesh_incremental_float=0.8): #TODO: figure out why is it that some surfaces do not work occshape = TopoDS_Shape(occshape) bt = BRep_Tool() BRepMesh_IncrementalMesh(occshape, mesh_incremental_float) occshape_face_list = fetch.geom_explorer(occshape, "face") occface_list = [] for occshape_face in occshape_face_list: location = TopLoc_Location() #occshape_face = modify.fix_face(occshape_face) facing = bt.Triangulation(occshape_face, location).GetObject() if facing: tab = facing.Nodes() tri = facing.Triangles() for i in range(1, facing.NbTriangles() + 1): trian = tri.Value(i) index1, index2, index3 = trian.Get() #print index1, index2, index3 pypt1 = fetch.occpt2pypt(tab.Value(index1)) pypt2 = fetch.occpt2pypt(tab.Value(index2)) pypt3 = fetch.occpt2pypt(tab.Value(index3)) #print pypt1, pypt2, pypt3 occface = make_polygon([pypt1, pypt2, pypt3]) occface_list.append(occface) return occface_list
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 __init__(self, pnt): if isinstance(pnt, (list, tuple)): self._coord = list(pnt) elif isinstance(pnt, gp_Pnt): self._coord = [pnt.X(), pnt.Y(), pnt.Z()] elif isinstance(pnt, TopoDS_Vertex): pnt = BRep_Tool.Pnt(pnt) self._coord = [pnt.X(), pnt.Y(), pnt.Z()] elif isinstance(pnt, TopoDS_Shape): pnt = BRep_Tool.Pnt(TopoDS_Vertex(pnt)) self._coord = [pnt.X(), pnt.Y(), pnt.Z()] else: raise TypeError
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): if isinstance(other, TopoDS_Edge): # convert edge to curve first, last = TopExp.FirstVertex(other), TopExp.LastVertex(other) lbound, ubound = BRep_Tool().Parameter(first, other), BRep_Tool().Parameter(first, other) other = BRep_Tool.Curve(other, lbound, ubound).GetObject() from OCC.GeomProjLib import GeomProjLib 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(edges_a.next()), Edge(edges_a.next()) b1, b2 = Edge(edges_b.next()), Edge(edges_b.next()) 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 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 points_frm_wire(occ_wire): ''' vertex_list = geom_explorer(occ_wire, TopAbs_VERTEX) point_list = vertex_list_2_point_list(vertex_list) n_pt_list = [] for pt in point_list: if n_pt_list: p_vert = (n_pt_list[-1].X(), n_pt_list[-1].Y(), n_pt_list[-1].Z()) c_vert = (pt.X(), pt.Y(), pt.Z()) if c_vert != p_vert: n_pt_list.append(pt) else: n_pt_list.append(pt) return n_pt_list ''' #TODO: WHEN DEALING WITH OPEN WIRE IT WILL NOT RETURN THE LAST VERTEX verts = Topology.WireExplorer(occ_wire).ordered_vertices() point_list = [] for vert in verts: pt = BRep_Tool.Pnt(vert) point_list.append(pt) #this always returns points in order that is opposite of the input #e.g. if the inputs are clockwise it will ouput anticlockwise #e.g. if the inputs are anticlockwise it will ouput clockwise #thus the point list needs to be reversed to reflect the true order #point_list = list(reversed(point_list)) return point_list
def __init__(self, pnt): if isinstance(pnt, (list, tuple)): gp_Pnt.__init__(self, *pnt) elif isinstance(pnt, vec): gp_Pnt.__init__(self, *pnt) elif isinstance(pnt, gp_Pnt): gp_Pnt.__init__(self, pnt) elif isinstance(pnt, TopoDS_Vertex): # convert to type "gp_Pnt" gp_Pnt.__init__(self, BRep_Tool.Pnt(pnt)) elif isinstance(pnt, TopoDS_Shape): self.brt = BRep_Tool() self.pnt1 = self.brt.Pnt(topods_Vertex(pnt)) gp_Pnt.__init__(self, self.pnt1.XYZ()) else: raise TypeError
def write_edge(points_edge, topo_edge): """ Method to recreate an Edge associated to a geometric curve after the modification of its points. :param points_edge: the deformed points array. :param topo_edge: the Edge to be modified :return: Edge (Shape) :rtype: TopoDS_Edge """ # convert Edge to Geom B-spline Curve nurbs_converter = BRepBuilderAPI_NurbsConvert(topo_edge) nurbs_converter.Perform(topo_edge) nurbs_curve = nurbs_converter.Shape() topo_curve = topods_Edge(nurbs_curve) h_geomcurve = BRep_Tool.Curve(topo_curve)[0] h_bcurve = geomconvert_CurveToBSplineCurve(h_geomcurve) bspline_edge_curve = h_bcurve.GetObject() # Edge geometric properties nb_cpt = bspline_edge_curve.NbPoles() # check consistency if points_edge.shape[0] != nb_cpt: raise ValueError("Input control points do not have not have the " "same number as the geometric edge!") else: for i in range(1, nb_cpt + 1): cpt = points_edge[i - 1] bspline_edge_curve.SetPole(i, gp_Pnt(cpt[0], cpt[1], cpt[2])) new_edge = BRepBuilderAPI_MakeEdge(bspline_edge_curve.GetHandle()) return new_edge.Edge()
def parse(self, filename): """ Method to parse the file `filename`. It returns a matrix with all the coordinates. :param string filename: name of the input file. :return: mesh_points: it is a `n_points`-by-3 matrix containing the coordinates of the points of the mesh :rtype: numpy.ndarray """ self.infile = filename self.shape = self.load_shape_from_file(filename) # cycle on the faces to get the control points # init some quantities n_faces = 0 control_point_position = [0] faces_explorer = TopExp_Explorer(self.shape, TopAbs_FACE) mesh_points = np.zeros(shape=(0, 3)) while faces_explorer.More(): # performing some conversions to get the right format (BSplineSurface) face = OCC.TopoDS.topods_Face(faces_explorer.Current()) nurbs_converter = BRepBuilderAPI_NurbsConvert(face) nurbs_converter.Perform(face) nurbs_face = nurbs_converter.Shape() brep_face = BRep_Tool.Surface(OCC.TopoDS.topods_Face(nurbs_face)) bspline_face = geomconvert_SurfaceToBSplineSurface(brep_face) # openCascade object occ_face = bspline_face.GetObject() # extract the Control Points of each face n_poles_u = occ_face.NbUPoles() n_poles_v = occ_face.NbVPoles() control_polygon_coordinates = np.zeros(\ shape=(n_poles_u * n_poles_v, 3)) # cycle over the poles to get their coordinates i = 0 for pole_u_direction in range(n_poles_u): for pole_v_direction in range(n_poles_v): control_point_coordinates = occ_face.Pole(\ pole_u_direction + 1, pole_v_direction + 1) control_polygon_coordinates[i, :] = [control_point_coordinates.X(),\ control_point_coordinates.Y(),\ control_point_coordinates.Z()] i += 1 # pushing the control points coordinates to the mesh_points array (used for FFD) mesh_points = np.append( mesh_points, control_polygon_coordinates, axis=0) control_point_position.append( control_point_position[-1] + n_poles_u * n_poles_v) n_faces += 1 faces_explorer.Next() self._control_point_position = control_point_position return mesh_points
def occ_triangle_mesh(event=None): # # Mesh the shape # BRepMesh_IncrementalMesh(aShape, 0.1) builder = BRep_Builder() Comp = TopoDS_Compound() builder.MakeCompound(Comp) ex = TopExp_Explorer(aShape, TopAbs_FACE) while ex.More(): F = topods_Face(ex.Current()) L = TopLoc_Location() facing = (BRep_Tool().Triangulation(F, L)).GetObject() tab = facing.Nodes() tri = facing.Triangles() for i in range(1, facing.NbTriangles() + 1): trian = tri.Value(i) #print trian 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.DisplayShape(Comp, update=True)
def project_face_on_faceplane(occface2projon, occface2proj): """ This function projects the OCCface onto another OCCface plane. The plane stretches through infinity. Parameters ---------- occface2projon : OCCface The OCCface to be projected on. occface2proj : OCCface The OCCface to be projected. Returns ------- list of points : pyptlist The list of projected points. """ wire_list = list(Topology.Topo(occface2proj).wires()) occpt_list = [] for wire in wire_list: occpts = Topology.WireExplorer(wire).ordered_vertices() occpt_list.extend(occpts) proj_ptlist = [] for occpt in occpt_list: occ_pnt = BRep_Tool.Pnt(occpt) pypt = (occ_pnt.X(), occ_pnt.Y(), occ_pnt.Z()) projected_pt = project_point_on_faceplane(pypt, occface2projon) proj_ptlist.append(projected_pt) return proj_ptlist
def srf_nrml_facing_solid_inward(occ_face, occ_solid): #move the face in the direction of the normal #first offset the face so that vert will be within the solid o_wire = Construct.make_offset(occ_face, 0.0001) o_face = BRepBuilderAPI_MakeFace(o_wire).Face() wire_list = list(Topology.Topo(o_face).wires()) occpt_list = [] for wire in wire_list: occpts = Topology.WireExplorer(wire).ordered_vertices() occpt_list.extend(occpts) pt = BRep_Tool.Pnt(occpt_list[0]) #a point that is on the edge of the face normal = face_normal(occ_face) gp_direction2move = gp_Vec(normal[0], normal[1], normal[2]) gp_moved_pt = pt.Translated(gp_direction2move.Multiplied(0.001)) mv_pt = (gp_moved_pt.X(), gp_moved_pt.Y(), gp_moved_pt.Z()) in_solid = point_in_solid(occ_solid, mv_pt) if in_solid: return True else: return False
def format_wire_for_roboDK(wire, is_reverse=False): vertices = sweeper.get_ordered_vertices_from_wire(wire) brt = BRep_Tool() wire = [] last_path_direction = None for i in range(len(vertices)): index = i next_index = index + 1 if is_reverse: index = len(vertices) - 1 - i next_index = index - 1 v = vertices[index] pnt = brt.Pnt(topods_Vertex(v)) normal = get_vertex_normal(v, front_face) if not ((index == 0 and is_reverse) or (index == len(vertices) - 1 and not is_reverse)): pnt_next = brt.Pnt(topods_Vertex(vertices[next_index])) mat_pnt = numpy.mat([pnt.X(), pnt.Y(), pnt.Z()]) mat_pnt_next = numpy.mat( [pnt_next.X(), pnt_next.Y(), pnt_next.Z()]) path_direction = mat_pnt_next - mat_pnt path_direction = path_direction / scipy.linalg.norm(path_direction) last_path_direction = path_direction else: path_direction = last_path_direction #direction should be away from base_position p1 = [pnt.X() + normal.X(), pnt.Y() + normal.Y(), pnt.Z() + normal.Z()] p2 = [pnt.X() - normal.X(), pnt.Y() - normal.Y(), pnt.Z() - normal.Z()] #normal vector should point towards base_position if sweeper.get_distance_points( p1, sweeper.base_position) < sweeper.get_distance_points( p2, sweeper.base_position): direction = [normal.X(), normal.Y(), normal.Z()] else: direction = [-normal.X(), -normal.Y(), -normal.Z()] wire.append({ "location": [pnt.X(), pnt.Y(), pnt.Z()], "direction": direction, "path_direction": [ path_direction.item(0), path_direction.item(1), path_direction.item(2) ] }) return wire
def points_frm_solid(occ_solid): verts = Topology.Topo(occ_solid).vertices() point_list = [] for vert in verts: pt = BRep_Tool.Pnt(vert) point_list.append(pt) return point_list
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 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 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 """ edge = edge if not isinstance(edge,KbeObject) else edge.topo face = face if not isinstance(face, KbeObject) else face.topo bt = BRep_Tool() if bt.HasContinuity(edge, self.topo, face): continuity = bt.Continuity(edge, self.topo, face) return True, continuity else: return False, None
def face_normal(face): umin, umax, vmin, vmax = BRepTools.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 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 dump_topology_to_string(shape, level=0, buffer=""): """ Reutnrs 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>\n" % (hash(shape), pnt.X(), pnt.Y(), pnt.Z())) else: print(".." * level, end="") print(shape_type_string(shape)) it = TopoDS_Iterator(shape) while it.More() and level < 5: # LEVEL MAX shp = it.Value() it.Next() print(dump_topology_to_string(shp, level + 1, buffer))
def simple_mesh(): # # Create the shape # shape = BRepPrimAPI_MakeBox(200, 200, 200).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)).GetObject() 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 process_wire(wire): '''takes a wire and extracts points returns a list of points''' vertices = [] explorer = BRepTools_WireExplorer(wire) while explorer.More(): vertex = TopoDS().Vertex(explorer.CurrentVertex()) xyz = Point(BRep_Tool().Pnt(vertex)) vertices.append(xyz) explorer.Next() return vertices
def intersection(a, b): if set([a.ShapeType(), b.ShapeType()]) <= set([TopAbs.TopAbs_WIRE, TopAbs.TopAbs_EDGE]): # TODO: check if the computed point is within the bounded part of # the curves l = [] for c0 in subshapes(a, TopAbs.TopAbs_EDGE): c0_ = BRep_Tool.Curve(c0)[0] for c1 in subshapes(b, TopAbs.TopAbs_EDGE): c1_ = BRep_Tool.Curve(c1)[0] # TODO: use IntTools_EdgeEdge # or IntTools_BeanBeanIntersector u = GeomAPI_ExtremaCurveCurve(c0_, c1_) par = u.LowerDistanceParameters()[0] pnt = c0_.GetObject().Value(par) l.append(BRepBuilderAPI_MakeVertex(pnt).Vertex()) return l c = BRepAlgoAPI.BRepAlgoAPI_Common(a, b).Shape() comp = TopoDS.topods_Compound(c) # get the subshape of the compound: types = set([a.ShapeType(), b.ShapeType()]) # compound = 0 # compsolid = 1 # solid = 2 # shell = 3 # face = 4 # wire = 5 # edge = 6 # vertex = 7 # shape = 8 if types == set([TopAbs.TopAbs_FACE]): return [subshapes(comp, TopAbs.TopAbs_FACE)[0]] elif types == set([TopAbs.TopAbs_FACE, TopAbs.TopAbs_SOLID]): return [subshapes(comp, TopAbs.TopAbs_SHELL)[0]] elif types == set([TopAbs.TopAbs_SOLID]): return [subshapes(comp, TopAbs.TopAbs_SOLID)[0]] elif types == set([TopAbs.TopAbs_SHELL]): return [subshapes(comp, TopAbs.TopAbs_EDGE)[0]] else: raise ConstructionError()
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 DumpTop(self, 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)) dmp = " " * level dmp += "%s - " % shapeTypeString(shape) dmp += "%.5e %.5e %.5e" % (pnt.X(), pnt.Y(), pnt.Z()) print(dmp) else: dmp = " " * level dmp += shapeTypeString(shape) print(dmp) it = TopoDS_Iterator(shape) while it.More(): shp = it.Value() it.Next() self.DumpTop(shp, level + 1)
def discretize(shape, tol): """This method discretizes the OpenCascade shape. :param shape: Shape to discretize :type shape: :return: discretized face; profile coordinates; id of the surface the\ coordinates belong to :rtype: OCC.TopoDS.TopoDS_Compound; numpy.ndarray; numpy.ndarray """ BRepMesh_IncrementalMesh(shape, tol, False, 5) builder = BRep_Builder() comp = TopoDS_Compound() builder.MakeCompound(comp) bt = BRep_Tool() ex = TopExp_Explorer(shape, TopAbs_EDGE) edge_coords = np.zeros([0, 3]) edge_ids = np.zeros([0], dtype=int) edge_id = 0 while ex.More(): edge = topods_Edge(ex.Current()) location = TopLoc_Location() edging = (bt.Polygon3D(edge, location)).GetObject() tab = edging.Nodes() for i in range(1, edging.NbNodes() + 1): p = tab.Value(i) edge_coords = np.append(edge_coords, [[p.X(), p.Y(), p.Z()]], axis=0) edge_ids = np.append(edge_ids, edge_id) mv = BRepBuilderAPI_MakeVertex(p) if mv.IsDone(): builder.Add(comp, mv.Vertex()) edge_id += 1 ex.Next() edge_coords = np.round(edge_coords, 8) return edge_coords, edge_ids