• <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

            国内精品久久久久影院优| 亚洲国产成人精品91久久久 | 香蕉久久影院| 91性高湖久久久久| 香蕉久久夜色精品升级完成| 久久频这里精品99香蕉久| 国产99久久久久久免费看| 久久青青草原精品国产| 天天躁日日躁狠狠久久 | 99热都是精品久久久久久| 久久精品国产亚洲AV无码麻豆| 欧美一区二区三区久久综| 熟妇人妻久久中文字幕| 久久精品aⅴ无码中文字字幕不卡| 亚洲AV日韩AV永久无码久久| 蜜臀av性久久久久蜜臀aⅴ麻豆| 看久久久久久a级毛片| 成人妇女免费播放久久久| 久久婷婷久久一区二区三区| 久久激情亚洲精品无码?V| 色8激情欧美成人久久综合电| 精品久久久久久久国产潘金莲| 狠狠色丁香久久婷婷综合| 久久99精品久久久久久久不卡| 欧美亚洲国产精品久久蜜芽| 久久久中文字幕日本| 久久久久青草线蕉综合超碰 | 久久久久久国产a免费观看黄色大片 | 久久成人国产精品| 国产福利电影一区二区三区久久久久成人精品综合 | 亚洲国产一成人久久精品| 国产精品九九九久久九九| 久久夜色tv网站| 婷婷久久综合九色综合九七| 无码精品久久久天天影视| 91久久精品国产91性色也| 伊人久久成人成综合网222| 久久久久人妻一区精品色| 狠狠精品久久久无码中文字幕 | 国产69精品久久久久观看软件| 91精品国产综合久久婷婷|