• <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 閱讀(5257) 評論(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函數(shù),主要用來對BRep表示的拓樸形狀的數(shù)據(jù)進(jìn)行讀寫,也提供了查找一個面中外環(huán)(Outer Wire)的函數(shù)。因為OpenCASCADE中的邊界表示法BRep的數(shù)據(jù)結(jié)構(gòu)如下圖1.1所示:

            wps_clip_image-4070

            Figure 1.1 BRep Data Structure of OpenCASCADE

            因為OpenCASCADE中拓樸結(jié)構(gòu)采用了包含關(guān)系,當(dāng)需要將TopoDS_Shape數(shù)據(jù)保存到文件時,如何保持TopoDS_Shape中的關(guān)系,以便于從文件讀取這些數(shù)據(jù)時,可以重構(gòu)出TopoDS_Shape中的各種關(guān)系?

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

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

            2.Topology Shape Serialization

            OpenCASCADE的類BRepTools中提供了如下函數(shù),可以TopoDS_Shape中的數(shù)據(jù)進(jìn)行導(dǎo)入導(dǎo)出:

            v BRepTools::Dump();

            v BRepTools::Read();

            v BRepTools::Write();

            這幾個函數(shù)比較常用,因為可以方便地將TopoDS_Shape導(dǎo)出,或?qū)氲絆penCASCADE的Draw Test Harness中,來對程序一些算法進(jìn)行驗證。對于使用了組合關(guān)系的TopoDS_Shape如何確保數(shù)據(jù)的保存及讀取后,能夠維持這些關(guān)系?帶著這個問題去看BRep文件讀寫的功能,應(yīng)該更為清晰。

            還是看看代碼,如下所示為輸出TopoDS_Shape的函數(shù),在程序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函數(shù)如下:


            //=======================================================================
            //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;
            }

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


            //=======================================================================
            //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中的幾何信息較多,F(xiàn)ace中的幾何信息最少,只是幾何曲面或其用于顯示的網(wǎng)格數(shù)據(jù)。在將拓樸數(shù)據(jù)輸出時,拓樸面、邊及頂點中包含的幾何信息都是前面幾何數(shù)據(jù)的編號,即相當(dāng)于索引號的形式輸出,代碼如下所示:


            //=======================================================================
            //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());
                  }
                }
              }
              
            }

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

            在實現(xiàn)從文件讀取BRep表示的數(shù)據(jù)時,先將幾何信息讀取到對應(yīng)的集合中,再讀取拓樸結(jié)構(gòu)數(shù)據(jù)時,若拓樸結(jié)構(gòu)中包含幾何信息,則以索引的方式,找到對應(yīng)的幾何數(shù)據(jù)即可。詳細(xì)實現(xiàn)可參考源程序。

            3. For Debugging

            由于BRepTools為Toolkit TKBRep中的類,所以依賴的動態(tài)庫較少,所以在編程時,若要驗證一些算法的正確性時,經(jīng)常需要將TopoDS_Shape的數(shù)據(jù)導(dǎo)出,甚至可以直接先在Draw Test Harness中使用相關(guān)命令來將導(dǎo)出的數(shù)據(jù)導(dǎo)入來查看結(jié)果。

            4. Conclusion

            通過BRepTools中對TopoDS_Shape數(shù)據(jù)的輸出及導(dǎo)入的代碼分析可知,對于只有組合關(guān)系的數(shù)據(jù),若想維持這種關(guān)系,就需要引入集合映射的類來產(chǎn)生索引,進(jìn)而在讀取數(shù)據(jù)時,可以根據(jù)索引來重構(gòu)拓樸關(guān)系。由于opennurbs中的BRep在內(nèi)存中本來就是索引的方式,所以在數(shù)據(jù)存取時,實現(xiàn)要簡單很多。

            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

            2021久久精品免费观看| 人妻系列无码专区久久五月天| 亚洲精品美女久久久久99小说| 无码人妻少妇久久中文字幕 | 色综合久久中文字幕无码| 久久国产免费直播| 久久午夜电影网| 一本色道久久88综合日韩精品| 亚洲综合熟女久久久30p| 国产99久久精品一区二区| 少妇被又大又粗又爽毛片久久黑人| 人妻精品久久无码专区精东影业| 色综合久久天天综合| 伊人精品久久久久7777| 夜夜亚洲天天久久| 无码精品久久久久久人妻中字| 久久精品女人天堂AV麻| 国产精品美女久久久久网| 波多野结衣久久| 欧美久久久久久午夜精品| 色综合久久中文色婷婷| 久久99精品国产麻豆| 囯产精品久久久久久久久蜜桃| 精品国产91久久久久久久a| 国产精品视频久久| 亚洲中文久久精品无码ww16| 青青草国产97免久久费观看| 狠狠人妻久久久久久综合| 精品午夜久久福利大片| 久久精品中文无码资源站| 亚洲色欲久久久综合网| 久久无码国产专区精品| 中文字幕精品无码久久久久久3D日动漫| 日韩精品久久久久久| 久久精品国内一区二区三区| 精品久久久久久综合日本| 国产情侣久久久久aⅴ免费| 久久国产精品国产自线拍免费| 久久se精品一区二区| 亚洲国产成人久久综合一| 精品久久久久久无码国产|