• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            eryar

            PipeCAD - Plant Piping Design Software.
            RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
            posts - 603, comments - 590, trackbacks - 0, articles - 0

            OpenCASCADE BRepTools

            Posted on 2015-03-14 20:18 eryar 閱讀(5211) 評論(0)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

            OpenCASCADE BRepTools

            eryar@163.com

            Abstract. OpenCASCADE BRepTools provides utilities for BRep data structure. OuterWire method to find the outer wire of a face. Dump method to dump a BRep object. It also can be used as the data exchange for OpenCASCADE native shapes. 

            Key Words. OpenCASCADE, BRepTools, BRep, Topology

            1. Introduction

            OpenCASCADE提供了一個類BRepTools,其中有許多static函數,主要用來對BRep表示的拓樸形狀的數據進行讀寫,也提供了查找一個面中外環(Outer Wire)的函數。因為OpenCASCADE中的邊界表示法BRep的數據結構如下圖1.1所示:

            wps_clip_image-4070

            Figure 1.1 BRep Data Structure of OpenCASCADE

            因為OpenCASCADE中拓樸結構采用了包含關系,當需要將TopoDS_Shape數據保存到文件時,如何保持TopoDS_Shape中的關系,以便于從文件讀取這些數據時,可以重構出TopoDS_Shape中的各種關系?

            參考opennurbs中的BRep表示時數據的存儲方式,可知直接在BRep中保存拓樸及幾何數據的索引,這樣對數據的存儲及讀取時重構拓樸結構還是很方便的。而在OpenCASCADE中拓樸數據是以Handle來保存的,且為組合關系,即一個父結構中有一個列表(TopoDS_ListOfShape)給包含了子結構數據。對于沒有索引的OpenCASCADE的拓樸結構,如何進行讀寫操作呢?

            本文結合類BRepTools中的函數,對OpenCASCADE中TopoDS_Shape數據的保存和讀取功能的代碼進行分析,從而對ModelingData中的BRep數據做進一步的理解。

            2.Topology Shape Serialization

            OpenCASCADE的類BRepTools中提供了如下函數,可以TopoDS_Shape中的數據進行導入導出:

            v BRepTools::Dump();

            v BRepTools::Read();

            v BRepTools::Write();

            這幾個函數比較常用,因為可以方便地將TopoDS_Shape導出,或導入到OpenCASCADE的Draw Test Harness中,來對程序一些算法進行驗證。對于使用了組合關系的TopoDS_Shape如何確保數據的保存及讀取后,能夠維持這些關系?帶著這個問題去看BRep文件讀寫的功能,應該更為清晰。

            還是看看代碼,如下所示為輸出TopoDS_Shape的函數,在程序Debug時比較常用:

            //=======================================================================
            //function : Dump
            //purpose  : 
            //=======================================================================
            void  BRepTools::Dump(const TopoDS_Shape& Sh, Standard_OStream& S)
            {
              BRepTools_ShapeSet SS;
              SS.Add(Sh);
              SS.Dump(Sh,S);
              SS.Dump(S);
            }

            其中使用了類BRepTools_ShapeSet,這里的Set的意思我理解為集合的意思,其Add函數如下:


            //=======================================================================
            //function : Add
            //purpose  : 
            //=======================================================================
            Standard_Integer  TopTools_ShapeSet::Add(const TopoDS_Shape& S)
            {
              
            if (S.IsNull()) return 0;
              myLocations.Add(S.Location());
              TopoDS_Shape S2 
            = S;
              S2.Location(TopLoc_Location());
              Standard_Integer index 
            = myShapes.FindIndex(S2);
              
            if (index == 0) {
                AddGeometry(S2);

                
            for (TopoDS_Iterator its(S2,Standard_False,Standard_False);
                     its.More(); its.Next())
                  Add(its.Value());
                index 
            = myShapes.Add(S2);
              }
              
            return index;
            }

            這是一個遞歸函數,通過AddGeometry函數,將TopoDS_Shape中的幾何信息都保存到相應的集合Set中,Set中使用了Map,即給每個幾何信息一個唯一的編號與之對應。


            //=======================================================================
            //function : AddGeometry
            //purpose  : 
            //=======================================================================

            void BRepTools_ShapeSet::AddGeometry(const TopoDS_Shape& S)
            {
              
            // Add the geometry
              
              
            if (S.ShapeType() == TopAbs_VERTEX) {
                
                Handle(BRep_TVertex) TV 
            = Handle(BRep_TVertex)::DownCast(S.TShape());
                BRep_ListIteratorOfListOfPointRepresentation itrp(TV
            ->Points());
                
                
            while (itrp.More()) {
                  
            const Handle(BRep_PointRepresentation)& PR = itrp.Value();

                  
            if (PR->IsPointOnCurve()) {
                    myCurves.Add(PR
            ->Curve());
                  }

                  
            else if (PR->IsPointOnCurveOnSurface()) {
                    myCurves2d.Add(PR
            ->PCurve());
                    mySurfaces.Add(PR
            ->Surface());
                  }

                  
            else if (PR->IsPointOnSurface()) {
                    mySurfaces.Add(PR
            ->Surface());
                  }

                  ChangeLocations().Add(PR
            ->Location());
                  itrp.Next();
                }

              }
              
            else if (S.ShapeType() == TopAbs_EDGE) {

                
            // Add the curve geometry
                Handle(BRep_TEdge) TE = Handle(BRep_TEdge)::DownCast(S.TShape());
                BRep_ListIteratorOfListOfCurveRepresentation itrc(TE
            ->Curves());

                
            while (itrc.More()) {
                  
            const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
                  
            if (CR->IsCurve3D()) {
                    
            if (!CR->Curve3D().IsNull()) {
                      myCurves.Add(CR
            ->Curve3D());
                      ChangeLocations().Add(CR
            ->Location());
                    }
                  }
                  
            else if (CR->IsCurveOnSurface()) {
                    mySurfaces.Add(CR
            ->Surface());
                    myCurves2d.Add(CR
            ->PCurve());
                    ChangeLocations().Add(CR
            ->Location());
                    
            if (CR->IsCurveOnClosedSurface())
                      myCurves2d.Add(CR
            ->PCurve2());
                  }
                  
            else if (CR->IsRegularity()) {
                    mySurfaces.Add(CR
            ->Surface());
                    ChangeLocations().Add(CR
            ->Location());
                    mySurfaces.Add(CR
            ->Surface2());
                    ChangeLocations().Add(CR
            ->Location2());
                  }
                  
            else if (myWithTriangles) { // for XML Persistence
                    if (CR->IsPolygon3D()) {
                      
            if (!CR->Polygon3D().IsNull()) {
                        myPolygons3D.Add(CR
            ->Polygon3D());
                        ChangeLocations().Add(CR
            ->Location());
                      }
                    }
                    
            else if (CR->IsPolygonOnTriangulation()) {
                      myTriangulations.Add(CR
            ->Triangulation());
                      myNodes.Add(CR
            ->PolygonOnTriangulation());
                      ChangeLocations().Add(CR
            ->Location());
                      
            if (CR->IsPolygonOnClosedTriangulation())
                        myNodes.Add(CR
            ->PolygonOnTriangulation2());
                    }
                    
            else if (CR->IsPolygonOnSurface()) {
                      mySurfaces.Add(CR
            ->Surface());
                      myPolygons2D.Add(CR
            ->Polygon());
                      ChangeLocations().Add(CR
            ->Location());
                      
            if (CR->IsPolygonOnClosedSurface())
                      myPolygons2D.Add(CR
            ->Polygon2());
                    }
                  }
                  itrc.Next();
                }
              }

              
            else if (S.ShapeType() == TopAbs_FACE) {

                
            // Add the surface geometry
                Handle(BRep_TFace) TF = Handle(BRep_TFace)::DownCast(S.TShape());
                
            if (!TF->Surface().IsNull())  mySurfaces.Add(TF->Surface());

                
            if (myWithTriangles) { // for XML Persistence
                  Handle(Poly_Triangulation) Tr = TF->Triangulation();
                  
            if (!Tr.IsNull()) myTriangulations.Add(Tr);
                }

                ChangeLocations().Add(TF
            ->Location());
              }
            }

            由上述代碼可知,Edge中的幾何信息較多,Face中的幾何信息最少,只是幾何曲面或其用于顯示的網格數據。在將拓樸數據輸出時,拓樸面、邊及頂點中包含的幾何信息都是前面幾何數據的編號,即相當于索引號的形式輸出,代碼如下所示:


            //=======================================================================
            //function : WriteGeometry
            //purpose  : 
            //=======================================================================

            void  BRepTools_ShapeSet::WriteGeometry(const TopoDS_Shape& S, 
                                                    Standard_OStream
            &   OS)const 
            {
              
            // Write the geometry
              
              
            if (S.ShapeType() == TopAbs_VERTEX) {

                
            // Write the point geometry
                TopoDS_Vertex V = TopoDS::Vertex(S);
                OS 
            << BRep_Tool::Tolerance(V) << "\n";
                gp_Pnt p 
            = BRep_Tool::Pnt(V);
                OS
            <<p.X()<<" "<<p.Y()<<" "<<p.Z()<<"\n";

                Handle(BRep_TVertex) TV 
            = Handle(BRep_TVertex)::DownCast(S.TShape());
                BRep_ListIteratorOfListOfPointRepresentation itrp(TV
            ->Points());
                
                
            while (itrp.More()) {
                  
            const Handle(BRep_PointRepresentation)& PR = itrp.Value();

                  OS 
            << PR->Parameter();
                  
            if (PR->IsPointOnCurve()) {
                    OS 
            << " 1 " << myCurves.Index(PR->Curve());
                  }

                  
            else if (PR->IsPointOnCurveOnSurface()) {
                    OS 
            << " 2 " <<  myCurves2d.Index(PR->PCurve());
                    OS 
            << " " << mySurfaces.Index(PR->Surface());
                  }

                  
            else if (PR->IsPointOnSurface()) {
                    OS 
            << " 3 " << PR->Parameter2() << " ";
                    OS 
            << mySurfaces.Index(PR->Surface());
                  }

                  OS 
            << " " << Locations().Index(PR->Location());
                  OS 
            << "\n";
                  
                  itrp.Next();
                }
                
                OS 
            << "0 0\n"// end representations

              }

              
            else if (S.ShapeType() == TopAbs_EDGE) {

                
            // Write the curve geometry 

                Handle(BRep_TEdge) TE 
            = Handle(BRep_TEdge)::DownCast(S.TShape());

                OS 
            << " " << TE->Tolerance() << " ";
                OS 
            << ((TE->SameParameter()) ? 1 : 0<< " ";
                OS 
            << ((TE->SameRange())     ? 1 : 0<< " ";
                OS 
            << ((TE->Degenerated())   ? 1 : 0<< "\n";
                
                Standard_Real first, last;
                BRep_ListIteratorOfListOfCurveRepresentation itrc 
            = TE->Curves();
                
            while (itrc.More()) {
                  
            const Handle(BRep_CurveRepresentation)& CR = itrc.Value();
                  
            if (CR->IsCurve3D()) {
                    
            if (!CR->Curve3D().IsNull()) {
                      Handle(BRep_GCurve) GC 
            = Handle(BRep_GCurve)::DownCast(itrc.Value());
                      GC
            ->Range(first, last);
                      OS 
            << "";                               // -1- Curve 3D
                      OS << " "<<myCurves.Index(CR->Curve3D());
                      OS 
            << " "<<Locations().Index(CR->Location());
                      OS 
            << " "<<first<<" "<<last;
                      OS 
            << "\n";
                    }
                  }
                  
            else if (CR->IsCurveOnSurface()) {
                    Handle(BRep_GCurve) GC 
            = Handle(BRep_GCurve)::DownCast(itrc.Value());
                    GC
            ->Range(first, last);
                    
            if (!CR->IsCurveOnClosedSurface())
                      OS 
            << "";                             // -2- Curve on surf
                    else
                      OS 
            << "";                             // -3- Curve on closed surf
                    OS <<" "<<myCurves2d.Index(CR->PCurve());
                    
            if (CR->IsCurveOnClosedSurface()) {
                      OS 
            <<" " << myCurves2d.Index(CR->PCurve2());
                      PrintRegularity(CR
            ->Continuity(),OS);
                    }
                    OS 
            << " " << mySurfaces.Index(CR->Surface());
                    OS 
            << " " << Locations().Index(CR->Location());
                    OS 
            << " "<<first<<" "<<last;
                    OS 
            << "\n";

                    
            // Write UV Points // for XML Persistence higher performance
                    if (FormatNb() == 2)
                    {
                      gp_Pnt2d Pf,Pl;
                      
            if (CR->IsCurveOnClosedSurface()) {
                        Handle(BRep_CurveOnClosedSurface) COCS 
            = 
                          Handle(BRep_CurveOnClosedSurface)::DownCast(CR);
                        COCS
            ->UVPoints2(Pf,Pl);
                      }
                      
            else {
                        Handle(BRep_CurveOnSurface) COS 
            = 
                          Handle(BRep_CurveOnSurface)::DownCast(CR);
                        COS
            ->UVPoints(Pf,Pl);
                      }
                      OS 
            << Pf.X() << " " << Pf.Y() << " " << Pl.X() << " " << Pl.Y() << "\n";
                    }
                  }
                  
            else if (CR->IsRegularity()) {
                    OS 
            << "";                              // -4- Regularity
                    PrintRegularity(CR->Continuity(),OS);
                    OS 
            << " "<<mySurfaces.Index(CR->Surface());
                    OS 
            << " "<<Locations().Index(CR->Location());
                    OS 
            << " "<<mySurfaces.Index(CR->Surface2());
                    OS 
            << " "<<Locations().Index(CR->Location2());
                    OS 
            << "\n";
                  }

                  
            else if (myWithTriangles) { // for XML Persistence
                    if (CR->IsPolygon3D()) {
                      Handle(BRep_Polygon3D) GC 
            = Handle(BRep_Polygon3D)::DownCast(itrc.Value());
                      
            if (!GC->Polygon3D().IsNull()) {
                        OS 
            << "";                            // -5- Polygon3D
                        OS << " "<<myPolygons3D.FindIndex(CR->Polygon3D());
                        OS 
            << " "<<Locations().Index(CR->Location());
                        OS 
            << "\n";
                      }
                    }
                    
            else if (CR->IsPolygonOnTriangulation()) {
                      Handle(BRep_PolygonOnTriangulation) PT 
            = 
                        Handle(BRep_PolygonOnTriangulation)::DownCast(itrc.Value());
                      
            if (!CR->IsPolygonOnClosedTriangulation())
                        OS 
            << "";                            // -6- Polygon on triangulation
                      else
                        OS 
            << "";                            // -7- Polygon on closed triangulation
                      OS << " " <<  myNodes.FindIndex(PT->PolygonOnTriangulation());
                      
            if (CR->IsPolygonOnClosedTriangulation()) {
                        OS 
            << " " << myNodes.FindIndex(PT->PolygonOnTriangulation2());
                      }
                      OS 
            << " " << myTriangulations.FindIndex(PT->Triangulation());
                      OS 
            << " "<<Locations().Index(CR->Location());
                      OS 
            << "\n";
                    }
                  }
                  
                  itrc.Next();
                }
                OS 
            << "0\n"// end of the list of representations
              }
              
              
            else if (S.ShapeType() == TopAbs_FACE) {

                Handle(BRep_TFace) TF 
            = Handle(BRep_TFace)::DownCast(S.TShape());
                
            const TopoDS_Face& F = TopoDS::Face(S);

                
            if (!(TF->Surface()).IsNull()) {
                  OS 
            << ((BRep_Tool::NaturalRestriction(F)) ? 1 : 0);
                  OS 
            << " ";
                  
            // Write the surface geometry
                  OS << " " <<TF->Tolerance();
                  OS 
            << " " <<mySurfaces.Index(TF->Surface());
                  OS 
            << " " <<Locations().Index(TF->Location());
                  OS 
            << "\n";
                }
                
            else //For correct reading of null face
                  {
                OS 
            << 0;
                OS 
            << " ";
                OS 
            << " " <<TF->Tolerance();
                OS 
            << " " << 0;
                OS 
            << " " << 0;
                OS 
            << "\n";
                  }
                
            if (myWithTriangles) { // for XML Persistence
                  if (!(TF->Triangulation()).IsNull()) {
                    OS 
            << 2;
                    OS 
            << " ";
                    
            // Write the triangulation
                    OS << " " <<myTriangulations.FindIndex(TF->Triangulation());
                  }
                }
              }
              
            }

            通過先將幾何數據收集到相應的集合(映射)中,再在拓樸結構對應的地方以索引號的方式輸出,這樣就便于從文件讀取數據時,以類似的方式來重構BRep邊界表示的拓樸Shape的結構。即讀取文件重構拓樸結構數據是輸出的逆過程。

            在實現從文件讀取BRep表示的數據時,先將幾何信息讀取到對應的集合中,再讀取拓樸結構數據時,若拓樸結構中包含幾何信息,則以索引的方式,找到對應的幾何數據即可。詳細實現可參考源程序。

            3. For Debugging

            由于BRepTools為Toolkit TKBRep中的類,所以依賴的動態庫較少,所以在編程時,若要驗證一些算法的正確性時,經常需要將TopoDS_Shape的數據導出,甚至可以直接先在Draw Test Harness中使用相關命令來將導出的數據導入來查看結果。

            4. Conclusion

            通過BRepTools中對TopoDS_Shape數據的輸出及導入的代碼分析可知,對于只有組合關系的數據,若想維持這種關系,就需要引入集合映射的類來產生索引,進而在讀取數據時,可以根據索引來重構拓樸關系。由于opennurbs中的BRep在內存中本來就是索引的方式,所以在數據存取時,實現要簡單很多。

            5. References

            1. OpenCASCADE Team. BRep Format. 2014.12

            2. Shing Liu. Topology and Geometry in OpenCascade-Topology. 

            http://www.shnenglu.com/eryar/archive/2013/09/21/203338.html

            3. Shing Liu. Topology and Geometry in OpenCascade-Vertex

            http://www.shnenglu.com/eryar/archive/2013/08/20/202678.html

            4. Shing Liu. Topology and Geometry in OpenCascade-Edge

            http://www.shnenglu.com/eryar/archive/2013/08/24/202739.html

            5. Shing Liu. Topology and Geometry in OpenCascade-Face

            http://www.shnenglu.com/eryar/archive/2013/09/12/203199.html

            久久久久一级精品亚洲国产成人综合AV区| 伊人久久精品无码av一区 | 久久AAAA片一区二区| 亚洲色欲久久久综合网| 91精品国产色综久久 | 久久婷婷五月综合成人D啪| 久久婷婷色综合一区二区| 国产亚洲精品自在久久| 精品永久久福利一区二区| 亚洲一区精品伊人久久伊人| 久久精品亚洲福利| 无码人妻久久一区二区三区免费| 久久亚洲AV成人无码| 99精品久久精品一区二区| 久久免费视频1| 国产福利电影一区二区三区久久老子无码午夜伦不 | 天堂无码久久综合东京热| 久久久噜噜噜久久| 日韩十八禁一区二区久久| 97超级碰碰碰碰久久久久 | 国产叼嘿久久精品久久| 国产精品久久午夜夜伦鲁鲁| 久久久久久久97| 精品久久久无码人妻中文字幕豆芽 | 国产69精品久久久久久人妻精品| 久久久噜噜噜久久中文字幕色伊伊 | 99精品国产综合久久久久五月天 | 日本欧美国产精品第一页久久| 精品久久久久久久中文字幕| 国产一级持黄大片99久久| 久久影院久久香蕉国产线看观看| 久久播电影网| 少妇人妻88久久中文字幕| 潮喷大喷水系列无码久久精品| 97精品伊人久久大香线蕉app| 亚洲欧洲久久av| 久久大香香蕉国产| 久久久久亚洲AV片无码下载蜜桃| 久久国产精品99国产精| 久久国产精品免费| 99re久久精品国产首页2020|