Opencascade make face with Holes
[Email protected]
Opencascade provides a class brepbuilderapi_makeface for constructing the face, which can be used to construct a polygon with holes. As shown in the following:
Of course, to get the results shown, you can also use a Boolean operation to cut several cylinders with a face. When using Boolean operation, it involves some complicated algorithms, such as intersection, reconstructing topo body, etc., which is time consuming. Since it is possible to dig holes directly in the generated polygons, this does not involve complex algorithms, and speed and stability are better than using Boolean operations. This article mainly describes how to use Brepbuilderapi_makeface to generate a polygon with holes, and its considerations. Directly on the code:
#include <gp_Circ.hxx>#include<gp_Pln.hxx>#include<BRepBuilderAPI_MakeEdge.hxx>#include<BRepBuilderAPI_MakeWire.hxx>#include<BRepBuilderAPI_MakeFace.hxx>#include<BRepTools.hxx>#pragmaComment (lib, "TKernel.lib")#pragmaComment (lib, "TKMath.lib")#pragmaComment (lib, "TKG2d.lib")#pragmaComment (lib, "TKG3d.lib")#pragmaComment (lib, "TKGeomBase.lib")#pragmaComment (lib, "TKGeomAlgo.lib")#pragmaComment (lib, "TKBRep.lib")#pragmaComment (lib, "TKTopAlgo.lib")voidmakefacetest () {GP_PLN aplane; Gp_circ ACircle1 (Gp::xoy (),1.0); Gp_circ ACircle2 (Gp::xoy (),1.0); Gp_circ ACircle3 (Gp::xoy (),1.0); Acircle1.setlocation (GP_PNT (3.0,3.0,0.0)); Acircle2.setlocation (GP_PNT (7.0,3.0,0.0)); Acircle3.setlocation (GP_PNT (3.0,7.0,0.0)); Brepbuilderapi_makeedge AnEdgeMaker1 (ACIRCLE1); Brepbuilderapi_makeedge AnEdgeMaker2 (ACircle2); Brepbuilderapi_makeedge AnEdgeMaker3 (ACIRCLE3); Brepbuilderapi_makewire AWireMaker1 (Anedgemaker1.edge ()); Brepbuilderapi_makewire AWireMaker2 (Anedgemaker2.edge ()); Brepbuilderapi_makewire AWireMaker3 (Anedgemaker3.edge ()); Brepbuilderapi_makeface Afacemaker (Aplane,0.0,10.0,0.0,10.0); if(Awiremaker1.isdone ()) {Afacemaker.add (Awiremaker1.wire ()); } if(Awiremaker2.isdone ()) {Afacemaker.add (Awiremaker2.wire ()); } if(Awiremaker3.isdone ()) {Afacemaker.add (Awiremaker3.wire ()); } if(Afacemaker.isdone ()) {Breptools::write (), Afacemaker.shape (),"D:/face.brep"); }}intMainintargcChar*argv[]) {makefacetest (); return 0;}
The code above is to open three holes on a flat surface, and finally generate the Face.brep file in the D drive. Loading and displaying this file in the draw Test harness gets:
When you switch to wireframe display mode, the effect is the same as expected. However, when you switch to shaded display mode, you find that the resulting polygon and the expected effect are exactly the opposite. What is the reason for this?
In the draw Test harness, enter the command Pcruve to check, as shown in:
According to the tip of the Pcurve command, the blue direction should be reversed, the red is the outer ring. So I learned that the direction of the inner ring hole is reversed. Modify the code to reverse the direction of the wire directly. The modified code is as follows:
#include <gp_Circ.hxx>#include<gp_Pln.hxx>#include<TopoDS_Wire.hxx>#include<BRepBuilderAPI_MakeEdge.hxx>#include<BRepBuilderAPI_MakeWire.hxx>#include<BRepBuilderAPI_MakeFace.hxx>#include<BRepTools.hxx>#pragmaComment (lib, "TKernel.lib")#pragmaComment (lib, "TKMath.lib")#pragmaComment (lib, "TKG2d.lib")#pragmaComment (lib, "TKG3d.lib")#pragmaComment (lib, "TKGeomBase.lib")#pragmaComment (lib, "TKGeomAlgo.lib")#pragmaComment (lib, "TKBRep.lib")#pragmaComment (lib, "TKTopAlgo.lib")voidmakefacetest () {GP_PLN aplane; Gp_circ ACircle1 (Gp::xoy (),1.0); Gp_circ ACircle2 (Gp::xoy (),1.0); Gp_circ ACircle3 (Gp::xoy (),1.0); Acircle1.setlocation (GP_PNT (3.0,3.0,0.0)); Acircle2.setlocation (GP_PNT (7.0,3.0,0.0)); Acircle3.setlocation (GP_PNT (3.0,7.0,0.0)); Brepbuilderapi_makeedge AnEdgeMaker1 (ACIRCLE1); Brepbuilderapi_makeedge AnEdgeMaker2 (ACircle2); Brepbuilderapi_makeedge AnEdgeMaker3 (ACIRCLE3); Brepbuilderapi_makewire AWireMaker1 (Anedgemaker1.edge ()); Brepbuilderapi_makewire AWireMaker2 (Anedgemaker2.edge ()); Brepbuilderapi_makewire AWireMaker3 (Anedgemaker3.edge ()); Brepbuilderapi_makeface Afacemaker (Aplane,0.0,10.0,0.0,10.0); if(Awiremaker1.isdone ()) {Topods_wire AWire1=Awiremaker1.wire (); Awire1.reverse (); Afacemaker.add (AWire1); } if(Awiremaker2.isdone ()) {Topods_wire AWire2=Awiremaker2.wire (); Awire2.reverse (); Afacemaker.add (AWire2); } if(Awiremaker3.isdone ()) {Topods_wire aWire3=Awiremaker3.wire (); Awire3.reverse (); Afacemaker.add (AWire3); } if(Afacemaker.isdone ()) {Breptools::write (), Afacemaker.shape (),"D:/face.brep"); }}intMainintargcChar*argv[]) {makefacetest (); return 0;}
Reload the newly generated face.brep and use the Pcurve view to get the effect as shown:
From the known, then get the desired effect. In summary, if you want to use Brepbuilderapi_makeface directly to create a face with holes, you need to be responsible for the direction of the outer ring and inner ring, opencascade do not check this. When displayed incorrectly, you can use the Pcurve command of the draw Test harness to check. The rule for a pcurve with a perforated face is: the outer ring is counterclockwise, and the inner ring hole is clockwise in direction.
Based on the directly generated perforated faces, you can further use the loft algorithm for styling, such as stretching, rotating, and so on, as shown in. This avoids using Boolean operations to improve the performance and stability of the modeling algorithm.
Opencascade make face with Holes