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中输入以下命令:

  1. pload ALL
  2. box b
  3. vdisplay b
  4. vtrihedron vt
  5. dump b

可以看到此时box的Location是没有的:

Figure 2.1 Box Location in Original

当将box沿X方向移动一段距离后:

  1. # translate by x direction
  2. ttranslate b
  3. vdisplay b
  4. dump b

Figure 2.2 Location of the translation box

由上图可知,当对模型进行变换后,TopoDS_Shape中即有了Location数据,变换矩阵的平移部分(第4列数据)发生了变化。下面继续沿X轴方向移动10:

  1. # translate by x direction
  2. ttranslate b
  3. vdisplay b
  4. dump b

Figure 2.3 Translate Box in X Direction

由图2.3可知,模型现在的位置是通过两个Elementary变换得来的。最后一个Complex变换是上述所有变换的复合。下面再对模型进行绕Y轴旋转45度:

  1. # rotate by y axis
  2. trotate b
  3. vdisplay b
  4. dump b

Figure 2.4 Rotate the Box

由上图可知,经过旋转变换后的模型有了4个Location:三个基本变换和一个复合变换,复合变换是所有基本变换的组合。

通过上面的示例,已经可以清晰理解OpenCASCADE中的Location的概念,虽然处理得有点复杂,通过Location可以对模型的变换轨迹有个详细的跟踪。这样处理的好处就是对模型的变换过程进行了记录,可以方便地回到历史上的任意一个时刻;不好的地方就是程序理解起来麻烦,而且还需要有额外的内存来保存这些数据。
以下为上述所有Tcl脚本:

  1. #
  2. # test TopoDS_Shape location.
  3. # Shing Liu(eryar@163.com)
  4. # 2016-09-06 22:50
  5. #
  6.  
  7. pload ALL
  8.  
  9. # initialize
  10. box b
  11. vdisplay b
  12. vtrihedron vt
  13. dump b
  14.  
  15. # translate by x direction
  16. ttranslate b
  17. vdisplay b
  18. dump b
  19.  
  20. # translate by x direction
  21. ttranslate b
  22. vdisplay b
  23. dump b
  24.  
  25. # rotate by y axis
  26. trotate b
  27. vdisplay b
  28. dump b

3.Draw Code

每个Draw Test Harness命令都可以方便地找到其实现代码,其中模型变换命令的实现代码如下:

  1. //=======================================================================
  2. // transform
  3. //=======================================================================
  4.  
  5. static Standard_Integer transform(Draw_Interpretor& ,Standard_Integer n,const char** a)
  6. {
  7. if (n <= ) return ;
  8.  
  9. gp_Trsf T;
  10. Standard_Integer last = n;
  11. const char* aName = a[];
  12.  
  13. Standard_Boolean isBasic = Standard_False;
  14.  
  15. if (!strcmp(aName,"reset")) {
  16. }
  17. else {
  18. isBasic = (aName[] == 'b');
  19. aName++;
  20.  
  21. if (!strcmp(aName,"move")) {
  22. if (n < ) return ;
  23. TopoDS_Shape SL = DBRep::Get(a[n-]);
  24. if (SL.IsNull()) return ;
  25. T = SL.Location().Transformation();
  26. last = n-;
  27. }
  28. else if (!strcmp(aName,"translate")) {
  29. if (n < ) return ;
  30. T.SetTranslation(gp_Vec(Draw::Atof(a[n-]),Draw::Atof(a[n-]),Draw::Atof(a[n-])));
  31. last = n-;
  32. }
  33. else if (!strcmp(aName,"rotate")) {
  34. if (n < ) return ;
  35. T.SetRotation(gp_Ax1(gp_Pnt(Draw::Atof(a[n-]),Draw::Atof(a[n-]),Draw::Atof(a[n-])),
  36. gp_Vec(Draw::Atof(a[n-]),Draw::Atof(a[n-]),Draw::Atof(a[n-]))),
  37. Draw::Atof(a[n-])* (M_PI / 180.0));
  38. last = n-;
  39. }
  40. else if (!strcmp(aName,"mirror")) {
  41. if (n < ) return ;
  42. T.SetMirror(gp_Ax2(gp_Pnt(Draw::Atof(a[n-]),Draw::Atof(a[n-]),Draw::Atof(a[n-])),
  43. gp_Vec(Draw::Atof(a[n-]),Draw::Atof(a[n-]),Draw::Atof(a[n-]))));
  44. last = n-;
  45. }
  46. else if (!strcmp(aName,"scale")) {
  47. if (n < ) return ;
  48. T.SetScale(gp_Pnt(Draw::Atof(a[n-]),Draw::Atof(a[n-]),Draw::Atof(a[n-])),Draw::Atof(a[n-]));
  49. last = n-;
  50. }
  51. }
  52.  
  53. if (T.Form() == gp_Identity || isBasic) {
  54. TopLoc_Location L(T);
  55. for (Standard_Integer i = ; i < last; i++) {
  56. TopoDS_Shape S = DBRep::Get(a[i]);
  57. if (S.IsNull())
  58. {
  59. std::cerr << "Error: " << a[i] << " is not a valid shape\n";
  60. return ;
  61. }
  62. else
  63. DBRep::Set(a[i],S.Located(L));
  64. }
  65. }
  66. else {
  67. BRepBuilderAPI_Transform trf(T);
  68. for (Standard_Integer i = ; i < last; i++) {
  69. TopoDS_Shape S = DBRep::Get(a[i]);
  70. if (S.IsNull()) {
  71. std::cerr << "Error: " << a[i] << " is not a valid shape\n";
  72. return ;
  73. }
  74. else {
  75. trf.Perform(S);
  76. if (!trf.IsDone())
  77. return ;
  78. DBRep::Set(a[i],trf.Shape());
  79. }
  80. }
  81. }
  82. return ;
  83. }

对模型的变换主要使用类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.

OpenCASCADE Shape Location的更多相关文章

  1. OpenCascade Shape Representation in OpenSceneGraph

    OpenCascade Shape Representation in OpenSceneGraph eryar@163.com 摘要Abstract:本文通过程序实例,将OpenCascade中的拓 ...

  2. Locations Section of OpenCascade BRep

    Locations Section of OpenCascade BRep eryar@163.com 摘要Abstract:本文结合OpenCascade的BRep格式描述文档和源程序,对BRep格 ...

  3. Open Cascade DataExchange IGES

    Open Cascade DataExchange IGES eryar@163.com 摘要Abstract:本文结合OpenCascade和Initial Graphics Exchange Sp ...

  4. Scipy教程 - 统计函数库scipy.stats

    http://blog.csdn.net/pipisorry/article/details/49515215 统计函数Statistical functions(scipy.stats) Pytho ...

  5. scipy.stats

    scipy.stats Scipy的stats模块包含了多种概率分布的随机变量,随机变量分为连续的和离散的两种.所有的连续随机变量都是rv_continuous的派生类的对象,而所有的离散随机变量都是 ...

  6. elasticsearch 口水篇(6) Mapping 定义索引

    前面我们感觉ES就想是一个nosql数据库,支持Free Schema. 接触过Lucene.solr的同学这时可能会思考一个问题——怎么定义document中的field?store.index.a ...

  7. cvpr2015papers

    @http://www-cs-faculty.stanford.edu/people/karpathy/cvpr2015papers/ CVPR 2015 papers (in nicer forma ...

  8. elasticsearch Mapping 定义索引

    Mapping is the process of defining how a document should be mapped to the Search Engine, including i ...

  9. Split Shape by Plane in OpenCASCADE

    Split Shape by Plane in OpenCASCADE eryar@163.com Abstract. Sometimes you want to split a shape by p ...

随机推荐

  1. 对Castle Windsor的Resolve方法的解析时new对象的探讨

    依赖注入框架Castle Windsor从容器里解析一个实例时(也就是调用Resolve方法),是通过调用待解析对象的构造函数new一个对象并返回,那么问题是:它是调用哪个构造函数呢? 无参的构造函数 ...

  2. jsp前端实现分页代码

    前端需要订一page类包装,其参数为 private Integer pageSize=10; //每页记录条数=10 private Integer totalCount; //总记录条数 priv ...

  3. jQuery学习之路(7)- 用原生JavaScript实现jQuery的某些简单功能

    ▓▓▓▓▓▓ 大致介绍 学习了妙味,用原生的JavaScript实现jQuery中的某些部分功能 定义自己的函数库lQuery ▓▓▓▓▓▓ $()选择器的实现 jQuery是面向对象的,所以自己编写 ...

  4. jQuery之Deferred源码剖析

    一.前言 大约在夏季,我们谈过ES6的Promise(详见here),其实在ES6前jQuery早就有了Promise,也就是我们所知道的Deferred对象,宗旨当然也和ES6的Promise一样, ...

  5. JavaScript之链式结构序列化

    一.概述 在JavaScript中,链式模式代码,太多太多,如下: if_else: if(...){ //TODO }else if(...){ //TODO }else{ //TODO } swi ...

  6. Consul 服务注册与服务发现

    上一篇:Mac OS.Ubuntu 安装及使用 Consul 1. 服务注册 对 Consul 进行服务注册之前,需要先部署一个服务站点,我们可以使用 ASP.NET Core 创建 Web 应用程序 ...

  7. 【NLP】揭秘马尔可夫模型神秘面纱系列文章(一)

    初识马尔可夫和马尔可夫链 作者:白宁超 2016年7月10日20:34:20 摘要:最早接触马尔可夫模型的定义源于吴军先生<数学之美>一书,起初觉得深奥难懂且无什么用场.直到学习自然语言处 ...

  8. 玩转spring boot——结合JPA入门

    参考官方例子:https://spring.io/guides/gs/accessing-data-jpa/ 接着上篇内容 一.小试牛刀 创建maven项目后,修改pom.xml文件 <proj ...

  9. linux centos中添加删除修改环境变量,设置java环境变量

    前言 安装完软件必要添加环境变量.指令很少,然而长时间不写就会不自信:我写的对吗?于是百度开始,于是发现又是各有千秋.好吧,好记星不如烂笔头.当然,最重要的是,百度出来的都他妈的是如何添加环境变量,只 ...

  10. 面向对象相关知识点xmind