def region_as_splinegon(boundary_splines): """Represents a region as a splinegon. Based on the combined topological-geometrical (intermediate) representation of the regions, (done by :func:`skeleton2regions`), this function provides a fully geometrical description of a region. Parameters ---------- boundary_splines : list Each element of the list is a `Handle_Geom_BSplineCurve` object, giving a reference to the B-splines bounding the region. The splines must either be ordered (see :func:`branches2boundary`) or they must appear in an order such that the n-th spline in the list can be connected to one of the first n-1 splines in the list. Returns ------- splinegon : TopoDS_Face The resulting splinegon (surface). For details on the object, see the OpenCASCADE API: https://www.opencascade.com/doc/occt-7.4.0/refman/html/class_topo_d_s___face.html boundary : TopoDS_Wire The boundary of the splinegon. For details on the resulting object, see the OpenCASCADE API: https://www.opencascade.com/doc/occt-7.4.0/refman/html/class_topo_d_s___wire.html See Also -------- skeleton2regions fit_spline Notes ----- The syntax `Handle_classname` in PythonOCC corresponds to wrapping the object of class `classname` with a smart pointer. In the C++ interface, it is done by a template: `Handle<classname>`. """ # Combine the splines so that they form the boundary (a collection of joining splines) boundary = BRepBuilderAPI_MakeWire() for spline in boundary_splines: edge = BRepBuilderAPI_MakeEdge(spline).Edge() boundary.Add(edge) _wire_error(boundary.Error()) # The planar surface (face) is stretched by the wire splinegon = BRepBuilderAPI_MakeFace(boundary.Wire()) _face_error(splinegon.Error()) return splinegon.Face(), boundary.Wire()
def write_face(self, points_face, list_points_edge, topo_face, toledge): """ Method to recreate a Face associated to a geometric surface after the modification of Face points. It returns a TopoDS_Face. :param points_face: the new face points array. :param list_points_edge: new edge points :param topo_face: the face to be modified :param toledge: tolerance on the surface creation after modification :return: TopoDS_Face (Shape) :rtype: TopoDS_Shape """ # convert Face to Geom B-spline Surface nurbs_converter = BRepBuilderAPI_NurbsConvert(topo_face) nurbs_converter.Perform(topo_face) nurbs_face = nurbs_converter.Shape() topo_nurbsface = topods.Face(nurbs_face) h_geomsurface = BRep_Tool.Surface(topo_nurbsface) h_bsurface = geomconvert_SurfaceToBSplineSurface(h_geomsurface) bsurface = h_bsurface.GetObject() nb_u = bsurface.NbUPoles() nb_v = bsurface.NbVPoles() # check consistency if points_face.shape[0] != nb_u * nb_v: raise ValueError("Input control points do not have not have the " "same number as the geometric face!") # cycle on the face points indice_cpt = 0 for iu in range(1, nb_u + 1): for iv in range(1, nb_v + 1): cpt = points_face[indice_cpt] bsurface.SetPole(iu, iv, gp_Pnt(cpt[0], cpt[1], cpt[2])) indice_cpt += 1 # create modified new face new_bspline_tface = BRepBuilderAPI_MakeFace() toler = precision_Confusion() new_bspline_tface.Init(bsurface.GetHandle(), False, toler) # cycle on the wires face_wires_explorer = TopExp_Explorer( topo_nurbsface.Oriented(TopAbs_FORWARD), TopAbs_WIRE) ind_edge_total = 0 while face_wires_explorer.More(): # get old wire twire = topods_Wire(face_wires_explorer.Current()) # cycle on the edges ind_edge = 0 wire_explorer_edge = TopExp_Explorer( twire.Oriented(TopAbs_FORWARD), TopAbs_EDGE) # check edges order on the wire mode3d = True tolerance_edges = toledge wire_order = ShapeAnalysis_WireOrder(mode3d, tolerance_edges) # an edge list deformed_edges = [] # cycle on the edges while wire_explorer_edge.More(): tedge = topods_Edge(wire_explorer_edge.Current()) new_bspline_tedge = self.write_edge( list_points_edge[ind_edge_total], tedge) deformed_edges.append(new_bspline_tedge) analyzer = topexp() vfirst = analyzer.FirstVertex(new_bspline_tedge) vlast = analyzer.LastVertex(new_bspline_tedge) pt1 = BRep_Tool.Pnt(vfirst) pt2 = BRep_Tool.Pnt(vlast) wire_order.Add(pt1.XYZ(), pt2.XYZ()) ind_edge += 1 ind_edge_total += 1 wire_explorer_edge.Next() # grouping the edges in a wire, then in the face # check edges order and connectivity within the wire wire_order.Perform() # new wire to be created stol = ShapeFix_ShapeTolerance() new_bspline_twire = BRepBuilderAPI_MakeWire() for order_i in range(1, wire_order.NbEdges() + 1): deformed_edge_i = wire_order.Ordered(order_i) if deformed_edge_i > 0: # insert the deformed edge to the new wire new_edge_toadd = deformed_edges[deformed_edge_i - 1] stol.SetTolerance(new_edge_toadd, toledge) new_bspline_twire.Add(new_edge_toadd) if new_bspline_twire.Error() != 0: stol.SetTolerance(new_edge_toadd, toledge * 10.0) new_bspline_twire.Add(new_edge_toadd) else: deformed_edge_revers = deformed_edges[ np.abs(deformed_edge_i) - 1] stol.SetTolerance(deformed_edge_revers, toledge) new_bspline_twire.Add(deformed_edge_revers) if new_bspline_twire.Error() != 0: stol.SetTolerance(deformed_edge_revers, toledge * 10.0) new_bspline_twire.Add(deformed_edge_revers) # add new wire to the Face new_bspline_tface.Add(new_bspline_twire.Wire()) face_wires_explorer.Next() return topods.Face(new_bspline_tface.Face())
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)