天天看點

OpenCASCADE General Transformation

<a href="mailto:[email protected]">[email protected]</a>

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’)之間的變換

OpenCASCADE General Transformation

稱為仿射變換。如果采用特殊的齊次坐标來表達,仿射變換也可用下列形式:

OpenCASCADE General Transformation

空間仿射變換是把平面變換到平面,直線變換到直線。兩個平行平面的像也是平行的。共線三點的的簡單比是不變量。平行六面體的體積是權為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&amp; di,Standard_Integer n,const char** a)

{

  if (n &lt;= 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; 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 &lt; last; i++) {

      TopoDS_Shape S = DBRep::Get(a[i]);

      if (S.IsNull())

        di &lt;&lt; a[i] &lt;&lt; " is not a valid shape\n";

      else

        DBRep::Set(a[i],S.Located(L));

    BRepBuilderAPI_Transform trf(T);

      if (S.IsNull()) {

      }

      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 &lt; 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

腳本運作效果如下圖所示:

OpenCASCADE General Transformation

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&amp; di,Standard_Integer n,const char** a)

  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 &lt; last; i++) {

  //    TopoDS_Shape S = DBRep::Get(a[i]);

  TopoDS_Shape S = DBRep::Get(a[2]);    

  if (S.IsNull()) {

    //cout &lt;&lt; a[2] &lt;&lt; " is not a valid shape" &lt;&lt; endl;

    di &lt;&lt; a[2] &lt;&lt; " is not a valid shape" &lt;&lt; "\n";

    gtrf.Perform(S);

    if (gtrf.IsDone()){

      DBRep::Set(a[1],gtrf.Shape());

    else {

      return 1;

根據仿射變換的定義,給定一個球面的數學表達式:

OpenCASCADE General Transformation

應用如下的仿射變換,将會得到一個橢球面:

OpenCASCADE General Transformation

由變換公式解得:

OpenCASCADE General Transformation

将它代入球面方程得到:

OpenCASCADE General Transformation

在Draw中使用BRepBuilderAPI_GTransform變換得到如下圖所示:

OpenCASCADE General Transformation

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

繼續閱讀