標籤:平面 set text pods isp char location 需要 lin
OpenCASCADE Make Face With Holes
[email protected]
OpenCASCADE提供了構造Face的類BRepBuilderAPI_MakeFace,使用這個類可以構造出帶孔的面。如所示:
當然,要得到所示的結果,還可以使用Boolean操作,用一個面去Cut幾個圓柱。當使用布爾操作就會涉及到一些複雜演算法,如求交,重構Topo體等,比較耗時。既然可以直接在產生面的時候挖孔,這個不涉及複雜演算法,速度、穩定性都比使用布爾操作要好。本文主要來介紹如何使用BRepBuilderAPI_MakeFace來產生帶孔的面,及其注意事項。直接上代碼:
#include <gp_Circ.hxx>#include <gp_Pln.hxx>#include <BRepBuilderAPI_MakeEdge.hxx>#include <BRepBuilderAPI_MakeWire.hxx>#include <BRepBuilderAPI_MakeFace.hxx>#include <BRepTools.hxx>#pragma comment(lib, "TKernel.lib")#pragma comment(lib, "TKMath.lib")#pragma comment(lib, "TKG2d.lib")#pragma comment(lib, "TKG3d.lib")#pragma comment(lib, "TKGeomBase.lib")#pragma comment(lib, "TKGeomAlgo.lib")#pragma comment(lib, "TKBRep.lib")#pragma comment(lib, "TKTopAlgo.lib")void makeFaceTest(){ 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"); }}int main(int argc, char* argv[]){ makeFaceTest(); return 0;}
上面代碼就是在一個平面上開三個孔,最後在D盤產生face.brep檔案。在Draw Test Harness中載入並顯示這個檔案得到:
當切換到線框顯示模式時,和預期效果一致。但是當切換到著色顯示模式時,發現產生的面和預期的效果剛好相反。這是什麼原因呢?
在Draw Test Harness中輸入命令pcruve來檢查,如所示:
根據pcurve命令的提示得知,藍色的方嚮應該反向,紅色的為外環。所以得知,內環孔的方向反了。修改代碼,直接將Wire的方向Reverse。修改後的代碼如下:
#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>#pragma comment(lib, "TKernel.lib")#pragma comment(lib, "TKMath.lib")#pragma comment(lib, "TKG2d.lib")#pragma comment(lib, "TKG3d.lib")#pragma comment(lib, "TKGeomBase.lib")#pragma comment(lib, "TKGeomAlgo.lib")#pragma comment(lib, "TKBRep.lib")#pragma comment(lib, "TKTopAlgo.lib")void makeFaceTest(){ 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"); }}int main(int argc, char* argv[]){ makeFaceTest(); return 0;}
重新載入新產生的face.brep並使用pcurve查看,得到如所示的效果:
從可知,這時得到的為預期的效果。綜上所述,如果要直接使用BRepBuilderAPI_MakeFace來產生帶有孔的面,需要自己為外環和內環的方向負責,opencascade對此不作檢查。當面顯示不正確時,可以使用Draw Test Harness的pcurve命令來檢查。一個帶孔的面的pcurve的規則為:外環為逆時針方向;內環孔的方向為順時針方向。
基於直接產生的帶孔的面,還可以進一步使用放樣演算法來造型,如展開,旋轉等,如所示。這樣就可以避免使用布爾操作,提高造型演算法的效能和穩定性。
OpenCASCADE Make Face With Holes