OpenCASCADE General Transformation

OpenCASCADE General Transformation

eryar@163.com

Abstract. OpenCASCADE provides a general transformation class: gp_GTrsf. It can be a transformation from gp, an affinity, or you can define your own transformation giving the matrix of transformation. The general transformation contains the vectorial part of the transformation and the translation part. A GTrsf transformation is only applicable to coordinates. Be careful if you apply such a transformation to all points of a geometric object, as this can change the nature of the object and thus render it incoherent. Typically a circle is transformed into an ellipse by an affinity transformation. To avoid modifying the nature of an object, use a gp_Trsf transformation instead, as objects of this class respect the nature of geometric objects.

Key Words. OpenCASCADE, Transformation, Affinity Transformation

1. Introduction

仿射变换(Affinity Transformation)是指线性变换后接着平移。因此,仿射变换的集合是线性变换的超集,任何线性变换都是仿射变换,但不是所有的仿射变换都是线性变换。

仿射变换的定义如下:在空间直角坐标系下,点(x,y,z)与点(x’, y’,z’)之间的变换

称为仿射变换。如果采用特殊的齐次坐标来表达,仿射变换也可用下列形式:

空间仿射变换是把平面变换到平面,直线变换到直线。两个平行平面的像也是平行的。共线三点的的简单比是不变量。平行六面体的体积是权为1的相对不变量。

OpenCASCADE的TKMath库中提供了这上仿射变换类gp_GTrsf,它能执行比gp_Trsf更通用的变换。对于TopoDS_Shape,OpenCASCADE分别提供了如下两个类进行变换:

v BRepBuilderAPI_GTransform

v BRepBuilderAPI_Transform

本文在OpenCASCADE Draw Test Harness中给出这两个类实现变换的结果。如果不想改变几何的特性,只想改变模型的位置或朝向,建议采用BRepBuilderAPI_Transform。

2.BRepBuilderAPI_Transform

OpenCASCADE中使用算法BRepBuilderAPI_Transform来实现:平移、旋转、缩放及镜像变换。在Draw Test Harness中实现的函数代码如下所示:

static Standard_Integer transform(Draw_Interpretor& di,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())
        di << a[i] << " is not a valid shape\n";
      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()) {
        di << a[i] << " is not a valid shape\n";
      }
      else {
        trf.Perform(S);
        if (!trf.IsDone())
          return 1;
        DBRep::Set(a[i],trf.Shape());
      }
    }
  }
  return 0;
}

下面给出应用Tcl脚本来实现这些变换的例子:

# make rotated copies of a sphere in between two cylinders
# create a file source toto.tcl
# toto.tcl code:
pload ALL

#create a sphere
psphere s 3
ttranslate s 25 0 12.

for {set i 0} {$i < 360} {incr i 20} {
    copy s s$i
    trotate s$i 0 0 0 0 0 1 $i
    
    vdisplay s$i
}
# create two cylinders
pcylinder c1 30 5
copy c1 c2
ttranslate c2 0 0 20
vdisplay c1 c2 s

脚本运行效果如下图所示:

Figure 2.1 Transform Tcl demo

从Draw中实现的函数来看,移动、旋转及缩放变换都是使用类

BRepBuilderAPI_Transformation来实现。Tcl脚本中先创建出一个球体,再平移后,复制13份,最后又创建出两个圆柱体。如果要对TopoDS_Shape进行变换且不改变其中的几何性质,建议都使用这个类来完成。

3.BRepBuilderAPI_GTransform

在OpenCASCADE也可使用仿射变换BRepBuilderAPI_GTransform来对形状实现上述变换操作,还可提供变形的变换,因此仿射变换是更一般的变换方法。在Draw中实现的函数代码如下所示:

///=======================================================================
// gtransform
//=======================================================================
static Standard_Integer deform(Draw_Interpretor& di,Standard_Integer n,const char** a)
{
  if (n <= 1) return 1;
  
  Standard_Integer last = n;
  
  gp_Trsf T;
  gp_GTrsf GT(T);
  
//  gp_Mat rot(Draw::Atof(a[last-3]),0,0,0,Draw::Atof(a[last-2]),0,0,0,Draw::Atof(a[last-1]));
  gp_Mat rot(Draw::Atof(a[3]),0,0,0,Draw::Atof(a[4]),0,0,0,Draw::Atof(a[5]));
  GT.SetVectorialPart(rot);
  last -= 3;
  BRepBuilderAPI_GTransform gtrf(GT);
  BRepBuilderAPI_NurbsConvert nbscv;
  //  for (Standard_Integer i = 1; i < last; i++) {
  //    TopoDS_Shape S = DBRep::Get(a[i]);
  TopoDS_Shape S = DBRep::Get(a[2]);    
  if (S.IsNull()) {
    //cout << a[2] << " is not a valid shape" << endl;
    di << a[2] << " is not a valid shape" << "\n";
  }
  else {
    gtrf.Perform(S);
    if (gtrf.IsDone()){
      DBRep::Set(a[1],gtrf.Shape());
    }
    else {
      return 1;
    }
  }
  
  return 0;
}

根据仿射变换的定义,给定一个球面的数学表达式:

应用如下的仿射变换,将会得到一个椭球面:

由变换公式解得:

将它代入球面方程得到:

在Draw中使用BRepBuilderAPI_GTransform变换得到如下图所示:

Figure 3.1 Shape Deformation

关于仿射变换有个重要定理:一般仿射变换是正交变换、沿着三个互相正交方向的压缩或放大和平移这三者的乘积。上述命令的实现代码就是设置了仿射矩阵中的a,b和c值,从而达到对模型变形的效果。

4.Conclusion

在三维建模软件中经常需要对模型的位置和其朝向进行变换,如果不想改变模型中的几何特性,在OpenCASCADE中建议使用类BRepBuilderAPI_Transform来实现。如果需要对模型进行更通用的变换即仿射变换,可以使用类BRepBuilderAPI_GTransform来实现。使用此类后,会改变模型中的几何特性,必须谨慎使用。

5. References

1. OpenCASCADE, OpenCASCADE Draw Test Harness User Guide, 2014

2. 苏步表, 华宣积. 应用几何教程. 复旦大学出版社. 2012

3. Fletcher Dunn. 3D Math Primer for Graphics and Game Development. Wordware. 2002

 

PDF Version: OpenCASCADE General Transformation

时间: 2024-09-27 22:11:01

OpenCASCADE General Transformation的相关文章

OpenCASCADE Outline

OpenCASCADE Outline eryar@163.com      有网友反映blog中关于OpenCASCADE的文章比较杂乱,不太好找,最好能提供一个大纲,这样方便查找.于是决定将这些学习时写的文章整理下,方便对OpenCASCADE的学习理解.其实在http://www.cnblogs.com/opencascade中,已经将文章按目录重新发表了一遍.可以按OpenCASCADE的模块的顺序来学习,也可以挑选自己感兴趣的部分来学习.      由于本人水平所限,文中的错误不妥之处

(zhuan) Attention in Neural Networks and How to Use It

Adam Kosiorek About Attention in Neural Networks and How to Use It  this blog comes from: http://akosiorek.github.io/ml/2017/10/14/visual-attention.html  Oct 14, 2017 Attention mechanisms in neural networks, otherwise known as neural attention or jus

OpenCASCADE Coordinate Transforms

OpenCASCADE Coordinate Transforms eryar@163.com Abstract. The purpose of the OpenGL graphics processing pipeline is to convert 3D descriptions of objects into a 2D image that can be displayed. In many ways, this process is similar to using a camera t

OpenCascade Shape Representation in OpenSceneGraph

OpenCascade Shape Representation in OpenSceneGraph eryar@163.com 摘要Abstract:本文通过程序实例,将OpenCascade中的拓朴数据(边.面)离散化后在OpenSceneGraph中进行显示.有了这些离散数据,就可以不用OpenCascade的显示模块了,可以使用其他显示引擎对形状进行显示.即若要线框模式显示形状时,就绘制离散形状拓朴边后得到的多段线:若要实体渲染模式显示形状时,就绘制离散形状拓朴面得到的三角网格.理解这些

Topology Shapes of OpenCascade BRep

Topology Shapes of OpenCascade BRep eryar@163.com 摘要Abstract:通过对OpenCascade中的BRep数据的读写,理解边界表示法的概念及实现.理解了拓朴形状的数据结构,就对ModelingData模块有了清晰认识,方便OpenCascade其他模块如ModelingAlgorithms和Visiualization模块的理解. 关键字Key Words:OpenCascade, BRep, Topology, BRep Format 一

OpenCASCADE Quaternion

OpenCASCADE Quaternion eryar@163.com Abstract. The quaternions are members of a noncommutative division algebra first invented by William Rowan Hamilton. The idea for quaternions occurred to him while he was walking along the Royal Cannal on his way

OpenCASCADE Linear Extrusion Surface

OpenCASCADE Linear Extrusion Surface eryar@163.com Abstract. OpenCASCADE linear extrusion surface is a generalized cylinder. Such a surface is obtained by sweeping a curve (called the "extruded curve" or "basis") in a given direction (

A Simple OpenCASCADE Qt Demo-occQt

A Simple OpenCASCADE Qt Demo-occQt eryar@163.com Abstract. OpenCASCADE have provided the Qt samples in the samples directory, but they are a little complicated. So I decide write a simple OpenCASCADE Qt demo for the OpenCASCADE beginners.  Key Words.

Qt with OpenCascade

Qt with OpenCascade eryar@163.com 摘要Abstract:详细介绍了如何在Qt中使用OpenCascade. 关键字Key Words:Qt.OpenCascade 一.引言 Introduction 1.1 Overview of Qt Qt是1991年奇趣科技开发的一个跨平台的C++图形用户界面应用程序框架.它提供给应用程序开发者建立艺术级的图形用户界面所需的所有功能.Qt很容易扩展,并且允许真正地组件编程.基本上,Qt同X Window上的Motif,Ope