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

            Representation Data in OpenCascade BRep

            Posted on 2013-12-14 18:40 eryar 閱讀(3123) 評論(2)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

            Representation Data in OpenCascade BRep

            eryar@163.com

            摘要Abstract:現在的顯示器大多數是光柵顯示器,即可以看做一個像素的矩陣。在光柵顯示器上顯示的任何圖形,實際上都是一些具有一種或多種顏色的集合。數學上精確表示的圖形在顯示器中只能用逼近的方式顯示出來。本文主要對OpenCascade的BRep文件中用來顯示曲線和曲面的離散數據結構進行說明。

            關鍵字:OpenCascade, BRep, Polygon, Triangulation, Subdivision Curves,

            一、引言 Introduction

            光柵圖形顯示器可以看做一個像素矩陣。在光柵顯示器上顯示的任何一種圖形,實際上都是一些具有一種或多種顏色的像素的集合。在數學上,理想的曲線是沒有寬度的,它是由無數個點構成的集合,而當要顯示曲線時,就不能用無數個點在顯示器中顯示,必須對其進行離散化,即細分處理。考慮性能要求,需要用盡可能少的點來顯示曲線。對于曲面也是一樣,雖然已經有曲面的數學解析表示,但是需要在顯示器中顯示時,必須對其離散化,即三角剖分得到的逼近曲面的三角網格。

            在OpenCascade中已經有曲線和曲面的精確的數學解析表達形式的類,如下圖所示:

            wps_clip_image-26135

            Figure 1.1 Parametric geometry curves

            wps_clip_image-30917

            Figure 1.2 Parametric geometry surfaces

            在OpenGL中顯示這些曲線和曲面時,不能直接顯示出由參數方程精確表示的曲線和曲面,必須對曲線和曲面進行細分,即離散化,得到OpenGL顯示用的點和三角網格。

            在OpenCascade中使用類Poly_Polygon3D/Poly_Polygon2D來保存多段線的數據,即可以用來保存逼近顯示由參數方程精確表示的曲線的離散點數據。

            在OpenCascade中使用類Poly_Triangulation來保存網格數據,即用三角網格來逼近表示的曲面,或更通用的一個形狀。

            形狀的離散化由函數BRepMesh::Mesh()來統(tǒng)一處理,處理后就可以得到形狀用來顯示的多段線和三角網格數據。有了這些離散數據,不管是將形狀交給顯示模塊進行顯示,還是將形狀在其他顯示引擎中顯示,就很方便了。

            在OpenCascade的BRep中也保存了形狀的用來顯示用的離散數據,即多段線和三角網格。只有經過BRepMesh::Mesh()離散化之后,形狀才具有這些數據。

            二、細分曲線 Subdivision of Curves

            在前面的一篇文章《在OpenSceneGraph中繪制OpenCascade的曲線 》中對曲線的顯示使用了統(tǒng)一細分處理(uniform subdivision),即將曲線在整個參數區(qū)域內均分后得到一些線段來顯示。沒有考慮這樣的問題:在曲線很平的區(qū)域內,就會存在冗余的點;在曲線曲度很大的區(qū)域內,可能點的數量還不足以顯示出光滑的曲線。自適應細分(Adaptive Subdivision)的方法就是將點放在最需要的地方,其主要目的是可視化曲線時更高效的渲染。通常這種方法主要用于游戲,因為其顯示更高效,性能更好。

            wps_clip_image-27356

            Figure 2.1 Uniform sampling on a curve

            如上圖所示,統(tǒng)一采樣來繪制曲線時,通常會在直線段區(qū)域生成很多多余的點,而在曲線區(qū)域的點太少,不能表示出光滑的曲線。自適應細分曲線有很多種方法,每種方法都會考慮速度、效率和精度,即如何用最少的點精確地表示出曲線。當你理解這個基本概念后,也可以對其他方法進行研究。

            在OpenCascade中對曲線的細分使用的類是GCPnts_TangentialDeflection,其算法描述如下,感興趣的讀者可以結合源程序對其算法實現進行研究:

            wps_clip_image-9058

            其中各個點的橫坐標對應的參數分別為:

            wps_clip_image-26078

            從上述公式結合向量的數量積公式可以看出,約束條件是兩個向量夾角的余弦值分別小于角度偏差和曲率偏差。算法將產生滿足約束條件的曲線上的最少數量的點。

            wps_clip_image-20720

            細分曲線后的點保存在類Poly_Polygon3D中。在BRep中也保存有多段線數據,如下所示:

            示例:

            wps_clip_image-21527

            BNF定義:

            wps_clip_image-10682

            詳細說明:

            <3D polygon record>定義了空間多段線(3D polyline)L,用來逼近空間參數曲線C。多段線的數據包含節(jié)點數m>=2,參數顯示標志位p,逼近偏差(deflection)d>=0,節(jié)點Ni(1=<i<=m),參數ui(1=<i<=m)。當參數顯示標志位p=1時,參數u才會顯示。多段線L通過這些節(jié)點,多段線L逼近曲線C的逼近偏差定義如下所示:

            wps_clip_image-18171

            參數ui(1=<i<=m)是曲線C上通過節(jié)點Ni的參數值:

            wps_clip_image-8816

            示例數據表示的多段線為:m=2,參數顯示標志位p=1,逼近偏差d=0.1,節(jié)點N1=(1,0,0),N2=(2,0,0),參數u1=0,u2=1。

            三、細分曲面 Subdivision of surfaces

            我們知道使用參數方程可以精確表示出三維曲線和曲面,但是參數方程表示的曲線曲面并不能直接交給OpenGL直接顯示出來。為此,圖形學中廣泛使用三角網格來表達三維模型,即用三角形組成的面片列表來近似逼近表示三維模型。

            wps_clip_image-3413

            Figure 3.1 Triangulation of Chinese Dragon

            用三角網格表示的曲面需要解決幾個問題:三角網格的產生、描述、遍歷、簡化和壓縮等。在OpenCascade中三角網格的產生使用算法Delaunay三角剖分算法生成網格數據,網格的描述使用類Poly_Triangulation。BRep文件中也保存三角網格的數據,如下所示:

            示例:

            wps_clip_image-20489

            BNF定義:

            wps_clip_image-19514

            詳細說明:

            <triangulation record>定義了逼近曲面S的三角剖分T(triangulation)。三角剖分的數據包含節(jié)點數m>=3,三角形數k>=1,參數顯示標志位p,逼近偏差d>=0,節(jié)點Ni(1<=i<=m),參數對ui,vi(1<=i<=m),三角形nj,1,nj,2,nj,3。參數只有當參數顯示標志位p=1時才顯示。三角剖分逼近曲面的偏差d定義如下所示:

            wps_clip_image-24429

            參數對ui,vi描述了曲面S上過節(jié)點Ni的參數:

            wps_clip_image-20588

            三角形nj,1, nj,2, nj,3用來取得三角形的三個頂點值Nnj,1,Nnj,2,Nnj,3,節(jié)點遍歷的順序就是Nnj,1,Nnj,2,Nnj,3。從三角剖分T的任意一側遍歷,所有三角形都有相同的方向:順時針或逆時針。

            三角剖分中的三角形數據:

            wps_clip_image-30677

            表示的三角剖分為:m=4個節(jié)點,k=2個三角形,參數顯示標志位p=1,逼近偏差d=0,節(jié)點N1(0,0,0),N2(0,0,3),N3(0,2,3),N4(0,2,0),參數值(u1,v1)=(0,0),(u2,v2)=(3,0),(u3,v3)=(3,-2),(u4,v4)=(0,-2)。從點(1,0,0)((-1,0,0)),三角形是順時針(逆時針)的。

            四、程序示例 Code Example

            通過創(chuàng)建多段線和三角網格數據并將其輸出,可以理解BRep文件中用來顯示的離散的數據結構。程序示例如下所示:

            /*
            *    Copyright (c) 2013 eryar All Rights Reserved.
            *
            *        File    : Main.cpp
            *        Author  : eryar@163.com
            *        Date    : 2013-12-12 21:46
            *        Version : 1.0v
            *
            *    Description : There are two kind of data for shape representation 
            *                  of the BRep file of OpenCascade. One is Polyline to
            *                  approximates a 3D curve; the other is triangulations
            *                  to approximates a surface.
            *
            *       KeyWords : OpenCascade, BRep File, Polygon, Triangulation
            *                  
            */

            #define WNT
            #include 
            <TColStd_Array1OfReal.hxx>
            #include 
            <TColgp_Array1OfPnt.hxx>
            #include 
            <TColgp_Array1OfPnt2d.hxx>

            #include 
            <Poly.hxx>
            #include 
            <Poly_Polygon3D.hxx>
            #include 
            <Poly_Array1OfTriangle.hxx>
            #include 
            <Poly_Triangulation.hxx>

            #pragma comment(lib, 
            "TKernel.lib")
            #pragma comment(lib, 
            "TKMath.lib")

            int main(void)
            {
                
            // 3D Polygons:
                
            // Polygon3D 1
                
            // 2 1
                
            // 0.1
                
            // 1 0 0 2 0 0
                
            // 0 1
                TColStd_Array1OfReal parameters(12);
                TColgp_Array1OfPnt nodes(
            12);
                Handle_Poly_Polygon3D polyline;

                nodes.SetValue(
            1, gp_Pnt(100));
                nodes.SetValue(
            2, gp_Pnt(200));

                parameters.SetValue(
            10.0);
                parameters.SetValue(
            21.0);

                polyline 
            = new Poly_Polygon3D(nodes, parameters);
                polyline
            ->Deflection(0.1);

                Poly::Write(polyline, std::cout);
                Poly::Write(polyline, std::cout, 
            false);

                
            // Triangulations.
                
            // 4 2 1 0
                
            // 0 0 0 0 0 3 0 2 3 0 2 0 0 0 3 0 3 -2 0 -2 2 4 3 2 1 4 
                Standard_Integer nodeCount = 4;
                Standard_Integer triangleCount 
            = 2;
                Standard_Real deflection 
            = 0.0;
                Standard_Boolean hasUV 
            = Standard_True;

                TColgp_Array1OfPnt triNodes(
            1, nodeCount);
                TColgp_Array1OfPnt2d UVNodes(
            1, nodeCount);
                Poly_Array1OfTriangle triangles(
            1, triangleCount);
                Handle_Poly_Triangulation triangulation;

                triNodes(
            1).SetCoord(000);
                triNodes(
            2).SetCoord(003);
                triNodes(
            3).SetCoord(023);
                triNodes(
            4).SetCoord(020);

                UVNodes(
            1).SetCoord(0.00.0);
                UVNodes(
            2).SetCoord(3.00.0);
                UVNodes(
            3).SetCoord(3.0-2.0);
                UVNodes(
            4).SetCoord(0.0-2.0);

                triangles(
            1).Set(243);
                triangles(
            2).Set(214);

                triangulation 
            = new Poly_Triangulation(triNodes, UVNodes, triangles);
                triangulation
            ->Deflection(deflection);

                Poly::Write(triangulation, std::cout);
                Poly::Write(triangulation, std::cout, 
            false);

                
            return 0;
            }

            輸出結果如下所示:

             

            Poly_Polygon3D
            2 1
            0.1
            1 0 0
            2 0 0
            0 1
            Poly_Polygon3D
                   
            2 Nodes
            with parameters
            Deflection : 
            0.1

            Nodes :
                     
            1 :                 1                 0                 0
                     
            2 :                 2                 0                 0

            Parameters :
            0 1
            Poly_Triangulation
            4 2 1
            0
            0 0 0
            0 0 3
            0 2 3
            0 2 0
            0 0
            3 0
            3 -2
            0 -2
            2 4 3
            2 1 4
            Poly_Triangulation
                   
            4 Nodes
                   
            2 Triangles
            with UV nodes
            Deflection : 
            0

            3D Nodes :
                     
            1 :                 0                 0                 0
                     
            2 :                 0                 0                 3
                     
            3 :                 0                 2                 3
                     
            4 :                 0                 2                 0

            UV Nodes :
                     
            1 :                 0                 0
                     
            2 :                 3                 0
                     
            3 :                 3                -2
                     
            4 :                 0                -2

            Triangles :
                     
            1 :          2          4          3
                     
            2 :          2          1          4
            Press any key to 
            continue . . .


            五、結論

            通過對OpenCascade中BRep文件中的離散數據的學習,理解顯示用數據結構及其實現。另外發(fā)現在類Poly和類BRepTools_ShapeSet中都有對多段線和三角網格進行讀寫的函數,有重復代碼,可以合并簡化。

             

            Feedback

            # re: Representation Data in OpenCascade BRep  回復  更多評論   

            2017-04-18 15:03 by Sirius
            老師您好,我有一個小問題,希望您有空的時候能解答一下。
            GCPnts_TangentialDeflection::Initialize()函數中的兩個參數AngularDeflection和CurvatureDeflection應該如何設置?有沒有具體實例可以參照一下呀?

            # re: Representation Data in OpenCascade BRep  回復  更多評論   

            2017-04-18 15:20 by eryar
            @Sirius
            這兩個參數越小,離散曲線得到的點越多,即越逼近真實曲線。

            具體說明看這個類的頭文件。
            国产精品久久午夜夜伦鲁鲁| 亚洲va久久久噜噜噜久久天堂| 久久精品国产亚洲AV无码偷窥| 久久精品国产久精国产思思| 久久国产精品99久久久久久老狼| 97精品伊人久久大香线蕉app| 久久中文字幕一区二区| 日韩久久无码免费毛片软件| 波多野结衣久久| 99久久精品费精品国产一区二区| 国产精品免费久久久久久久久| 热RE99久久精品国产66热| 久久婷婷五月综合色高清| 久久黄色视频| 久久国产精品久久国产精品| 亚洲精品NV久久久久久久久久| 亚洲精品国产字幕久久不卡| 精品久久久久久99人妻| 久久综合亚洲欧美成人| 综合久久精品色| 久久久这里有精品中文字幕| 久久国产亚洲精品无码| 久久精品国产色蜜蜜麻豆| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 久久精品国产亚洲精品| 麻豆亚洲AV永久无码精品久久| 久久久久18| 色综合久久天天综合| 18禁黄久久久AAA片| 香港aa三级久久三级老师2021国产三级精品三级在 | 97精品伊人久久久大香线蕉| 91精品久久久久久无码| 久久精品9988| 久久精品一区二区国产| 国产情侣久久久久aⅴ免费| 性欧美丰满熟妇XXXX性久久久| 久久久这里有精品| 午夜精品久久久久久久无码| 久久国产成人午夜AV影院| 久久精品国产一区二区| 亚洲国产天堂久久综合|