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

            Posted on 2016-09-07 00:06 eryar 閱讀(2746) 評論(0)  編輯 收藏 引用 所屬分類: 2.OpenCASCADE

            OpenCASCADE Shape Location

            eryar@163.com

            Abstract. The TopLoc package of OpenCASCADE gives resources to handle 3D local coordinate systems called Locations. A Location is a composition of elementary coordinate systems, each one is called a Datum. The Location keeps track of this composition. The paper will use the Draw Test Harness to illustrate the Location concept.

            Key Words. Transformation, Location, Local Coordinate Systems

            1.Introduction

            對于三維空間中的各種模型,總是想要擺放到合適的位置,最終形成一個工廠的模型,一艘船的模型,一個建筑物的模型,等等。目前來看,所有的幾何相關的庫對模型變換的實現一般都是使用了矩陣變換。有的可能只保留了最終變換的結果矩陣數據,而OpenCASCADE的TopoDS_Shape中保留了Location信息。從其文檔可以看出,Location中保留了模型變換一系列的變換組合,并可以對這個變換進行Track追蹤。如何來正確理解這個Location的意義呢?下面結合Draw Test Harness來進行說明。

            2.Draw Test

            在Draw Test Harness中對模型進行變換的命令有:ttranslate, trotate, tmove, reset, tmirror, tscale.其中ttranslate, trotate, tmove, reset命令只會對模型位置進行調整,并不能讓模型發生變形,即是剛性變換。下面就通過對一個Box進行移動和旋轉,來看看TopoDS_Shape中的Location是如何變化的。在Draw Test Harness中輸入以下命令:

            pload ALL 
            box b 10 20 30 
            vdisplay b 
            vtrihedron vt 
            dump b 

            可以看到此時box的Location是沒有的:

            wps277.tmp

            Figure 2.1 Box Location in Original

            當將box沿X方向移動一段距離后:

            # translate by x direction 
            ttranslate b 10 0 0 
            vdisplay b 
            dump b

            wps288.tmp

            Figure 2.2 Location of the translation box

            由上圖可知,當對模型進行變換后,TopoDS_Shape中即有了Location數據,變換矩陣的平移部分(第4列數據)發生了變化。下面繼續沿X軸方向移動10:

            # translate by x direction 
            ttranslate b 10 0 0 
            vdisplay b 
            dump b

            wps298.tmp

            Figure 2.3 Translate Box in X Direction

            由圖2.3可知,模型現在的位置是通過兩個Elementary變換得來的。最后一個Complex變換是上述所有變換的復合。下面再對模型進行繞Y軸旋轉45度:

            # rotate by y axis 
            trotate b 0 0 0 0 1 0 45 
            vdisplay b 
            dump b 

            wps299.tmp

            Figure 2.4 Rotate the Box

            由上圖可知,經過旋轉變換后的模型有了4個Location:三個基本變換和一個復合變換,復合變換是所有基本變換的組合。

            通過上面的示例,已經可以清晰理解OpenCASCADE中的Location的概念,雖然處理得有點復雜,通過Location可以對模型的變換軌跡有個詳細的跟蹤。這樣處理的好處就是對模型的變換過程進行了記錄,可以方便地回到歷史上的任意一個時刻;不好的地方就是程序理解起來麻煩,而且還需要有額外的內存來保存這些數據。
            以下為上述所有Tcl腳本:

            #
            # test TopoDS_Shape location.
            # Shing Liu(eryar@163.com)
            # 2016-09-06 22:50


            pload ALL

            # initialize 
            box b 10 20 30
            vdisplay b
            vtrihedron vt
            dump b

            # translate by x direction
            ttranslate b 10 0 0
            vdisplay b
            dump b

            # translate by x direction
            ttranslate b 10 0 0
            vdisplay b
            dump b

            # rotate by y axis
            trotate b 0 0 0 0 1 0 45
            vdisplay b
            dump b


            3.Draw Code

            每個Draw Test Harness命令都可以方便地找到其實現代碼,其中模型變換命令的實現代碼如下:

            //=======================================================================
            // transform
            //=======================================================================

            static Standard_Integer transform(Draw_Interpretor& ,Standard_Integer n,const char** a)
            {
              if (n <= 1) return 1;

              gp_Trsf T;
              Standard_Integer last = n;
              const char* aName = a[0];

              Standard_Boolean isBasic = Standard_False;

              if (!strcmp(aName,"reset")) {
              }
              else {
                isBasic = (aName[0] == 'b');
                aName++;

                if (!strcmp(aName,"move")) {
                  if (n < 3) return 1;
                  TopoDS_Shape SL = DBRep::Get(a[n-1]);
                  if (SL.IsNull()) return 0;
                  T = SL.Location().Transformation();
                  last = n-1;
                }
                else if (!strcmp(aName,"translate")) {
                  if (n < 5) return 1;
                  T.SetTranslation(gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1])));
                  last = n-3;
                }
                else if (!strcmp(aName,"rotate")) {
                  if (n < 9) return 1;
                  T.SetRotation(gp_Ax1(gp_Pnt(Draw::Atof(a[n-7]),Draw::Atof(a[n-6]),Draw::Atof(a[n-5])),
                                gp_Vec(Draw::Atof(a[n-4]),Draw::Atof(a[n-3]),Draw::Atof(a[n-2]))),
                                Draw::Atof(a[n-1])* (M_PI / 180.0));
                  last = n-7;
                }
                else if (!strcmp(aName,"mirror")) {
                  if (n < 8) return 1;
                  T.SetMirror(gp_Ax2(gp_Pnt(Draw::Atof(a[n-6]),Draw::Atof(a[n-5]),Draw::Atof(a[n-4])),
                              gp_Vec(Draw::Atof(a[n-3]),Draw::Atof(a[n-2]),Draw::Atof(a[n-1]))));
                  last = n-6;
                }
                else if (!strcmp(aName,"scale")) {
                  if (n < 6) return 1;
                  T.SetScale(gp_Pnt(Draw::Atof(a[n-4]),Draw::Atof(a[n-3]),Draw::Atof(a[n-2])),Draw::Atof(a[n-1]));
                  last = n-4;
                }
              }

              if (T.Form() == gp_Identity || isBasic) {
                TopLoc_Location L(T);
                for (Standard_Integer i = 1; i < last; i++) {
                  TopoDS_Shape S = DBRep::Get(a[i]);
                  if (S.IsNull())
                  {
                    std::cerr << "Error: " << a[i] << " is not a valid shape\n";
                    return 1;
                  }
                  else
                    DBRep::Set(a[i],S.Located(L));
                }
              }
              else {
                BRepBuilderAPI_Transform trf(T);
                for (Standard_Integer i = 1; i < last; i++) {
                  TopoDS_Shape S = DBRep::Get(a[i]);
                  if (S.IsNull()) {
                    std::cerr << "Error: " << a[i] << " is not a valid shape\n";
                    return 1;
                  }
                  else {
                    trf.Perform(S);
                    if (!trf.IsDone())
                      return 1;
                    DBRep::Set(a[i],trf.Shape());
                  }
                }
              }
              return 0;
            }

            對模型的變換主要使用類BRepBuilderAPI_Transform來完成。

            4.Conclusion

            通過上面的示例,已經可以清晰理解OpenCASCADE中的Location的概念,雖然處理得有點復雜,通過Location可以對模型的變換軌跡有個詳細的跟蹤。這樣處理的好處就是對模型的變換過程進行了記錄,可以方便地回到歷史上的任意一個時刻;不好的地方就是程序理解起來麻煩,而且還需要有額外的內存來保存這些數據。

            理解了Location的概念,也就理解了OpenCASCADE的Brep文件中的一項基本內容,方便開發一些轉換接口。

            關于矩陣變換在圖形學中的應用可以參考《3D數學基礎:圖形與游戲開發》。

            5.References

            1.Fletcher Dunn, Ian Parberry. 3D Math Primer for Graphics and Game Development. 清華大學出版社. 2005

            2.OpenCASCADE Draw Test Harness User Guide.

             

            一本一本久久a久久综合精品蜜桃| 91久久婷婷国产综合精品青草| 久久久久亚洲av成人无码电影| 欧美精品丝袜久久久中文字幕 | 国产一级做a爰片久久毛片| 久久噜噜电影你懂的| 久久夜色精品国产| 欧美一区二区久久精品| 国产亚洲精品自在久久| 国产午夜精品久久久久九九| 久久久久久国产精品无码下载| 嫩草影院久久99| 久久无码高潮喷水| 国产L精品国产亚洲区久久| 99久久综合国产精品免费| 亚洲国产二区三区久久| 久久精品亚洲AV久久久无码| 国产精品久久久久久久久久免费| 国产69精品久久久久久人妻精品| 国产ww久久久久久久久久| 久久亚洲精品无码AV红樱桃| 亚洲国产小视频精品久久久三级| 91久久九九无码成人网站| 久久久久亚洲AV片无码下载蜜桃| 少妇人妻综合久久中文字幕| 久久99热这里只有精品国产| 狠狠色噜噜狠狠狠狠狠色综合久久 | 青春久久| 丁香久久婷婷国产午夜视频| 久久青青草原亚洲av无码app| 久久亚洲国产最新网站| 久久精品一区二区三区中文字幕 | 色欲av伊人久久大香线蕉影院| 一本色综合久久| 色天使久久综合网天天| 久久人做人爽一区二区三区 | 91精品婷婷国产综合久久| 国产精品美女久久久m| 国产精品国色综合久久| 久久精品亚洲精品国产色婷| 97久久天天综合色天天综合色hd|