轉載請注明出處 ltr199010@163.com
本人在處理計算幾何一些算法時,由於模型有時是由其他軟件建模,再讀入的,所以經常會遇到獲取曲面上的曲線(如邊界)以及參數域2D曲線和空間3D曲線之間的轉化等問題。今天有人來問我相關的問題,想着還是總結分享一下吧。
1. 根據 TopoDS_Face 類型的面,獲取 TopoDS_Edge 類型的邊界。
利用 TopExp_Explorer 類,可以探索一個拓撲對象中包含的下級拓撲對象,找到Face中的Wire,再找Wire中的Edge。具體代碼實現如下。
1 TopoDS_Face aFace, 2 for (TopExp_Explorer wireExp(aFace, TopAbs_WIRE); wireExp.More(); wireExp.Next()){ 3 for (TopExp_Explorer edgeExp(wireExp.Current(), TopAbs_EDGE); edgeExp.More(); edgeExp.Next()){ 4 TopoDS_Edge anEdge = TopoDS::Edge(edgeExp.Current()); 5 // Next step 6 } 7 }
如果你需要的只是 TopoDS_Edge 類型的邊界,那么到此為止。如果同時你還需要這條曲線的參數域2D曲線的信息,那么繼續往下做。
2. 根據 TopoDS_Face 類型的面和 TopoDS_Edge 類型的邊界,生成 Handle(Geom2d_BSplineCurve) 類型的曲面參數域上的2D曲線。
利用 BRep_Tool::CurveOnSurface 函數獲取 Handle(Geom2d_Curve) 類型的曲面參數域曲線,再利用 Geom2dConvert::CurveToBSplineCurve 函數將其轉換為我們更常用的 Handle(Geom2d_BSplineCurve) 類型。具體代碼實現如下。
該步的注意點:如果原來的曲線是某曲線裁剪得到的,那么轉出來的 Handle(Geom2d_Curve) 類型的曲線是完整的曲線,需要利用首尾參數再人為裁剪一次。這可能是OCC的一個bug,后期版本也許會修正。
1 double aFirst; 2 double aLast; 3 // get the 2d curve of the edge on the face 4 Handle(Geom2d_Curve) aCurve2d = BRep_Tool::CurveOnSurface(anEdge, aFace, aFirst, aLast); 5 6 Handle(Geom2d_BSplineCurve) aPCurve; 7 // if the curve does not exist 8 if (aCurve2d == NULL){ 9 fprintf(stderr, "The curve does not exist.\n"); 10 } 11 // 12 else{ 13 fprintf(stderr, "The curve is an infinite line.\n"); 14 // trim the curve by the first and last parameter 15 Handle(Geom2d_TrimmedCurve) aTrimmedCurve = new Geom2d_TrimmedCurve(aCurve2d, aFirst, aLast); 16 17 aPCurve = Geom2dConvert::CurveToBSplineCurve(aTrimmedCurve); 18 }
3. 重新生成3D曲線
這里我們利用B樣條曲面和獲取到的參數域上的2DB樣條曲線來生成3D曲線。這么做有什么好處呢?在第一步中獲得的Edge只包含了空間曲線的信息,如果你的程序需要對參數域上的曲線進行操作,那么這一步就能把參數域2D曲線和Edge聯系起來了。具體代碼實現如下。
該步的注意點:BRepLib::BuildCurve3d這個函數一定要執行,這樣你的Edge里面才會有3d的曲線。這樣這條曲線才可以被顯示。
1 Handle(Geom_BSplineSurface) aSurface; 2 Handle(Geom2d_BSplineCurve) aPCurve; 3 // use the surface and the 2d parameter curve to create a TopoDS_Edge 4 TopoDS_Edge anEdge = BRepBuilderAPI_MakeEdge(aPCurve, aSurface).Edge(); 5 // create 3d edge 6 // this line is significance, otherwise the edge can not be displayed 7 BRepLib::BuildCurve3d(anEdge);
