Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:03:44

0001 // Copyright (c) 1991-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #ifndef _gp_GTrsf_HeaderFile
0016 #define _gp_GTrsf_HeaderFile
0017 
0018 #include <gp_Ax1.hxx>
0019 #include <gp_Ax2.hxx>
0020 #include <gp_Mat.hxx>
0021 #include <gp_Trsf.hxx>
0022 #include <gp_TrsfForm.hxx>
0023 #include <gp_XYZ.hxx>
0024 #include <Standard_ConstructionError.hxx>
0025 #include <Standard_OutOfRange.hxx>
0026 
0027 
0028 // Avoid possible conflict with SetForm macro defined by windows.h
0029 #ifdef SetForm
0030 #undef SetForm
0031 #endif
0032 
0033 //! Defines a non-persistent transformation in 3D space.
0034 //! This transformation is a general transformation.
0035 //! It can be a gp_Trsf, an affinity, or you can define
0036 //! your own transformation giving the matrix of transformation.
0037 //!
0038 //! With a gp_GTrsf you can transform only a triplet of coordinates gp_XYZ.
0039 //! It is not possible to transform other geometric objects
0040 //! because these transformations can change the nature of non-elementary geometric objects.
0041 //! The transformation gp_GTrsf can be represented as follow:
0042 //! @code
0043 //!    V1   V2   V3    T       XYZ        XYZ
0044 //! | a11  a12  a13   a14 |   | x |      | x'|
0045 //! | a21  a22  a23   a24 |   | y |      | y'|
0046 //! | a31  a32  a33   a34 |   | z |   =  | z'|
0047 //! |  0    0    0     1  |   | 1 |      | 1 |
0048 //! @endcode
0049 //! where {V1, V2, V3} define the vectorial part of the
0050 //! transformation and T defines the translation part of the transformation.
0051 //! Warning
0052 //! A gp_GTrsf transformation is only applicable to coordinates.
0053 //! Be careful if you apply such a transformation to all points of a geometric object,
0054 //! as this can change the nature of the object and thus render it incoherent!
0055 //! Typically, a circle is transformed into an ellipse by an affinity transformation.
0056 //! To avoid modifying the nature of an object, use a gp_Trsf transformation instead,
0057 //! as objects of this class respect the nature of geometric objects.
0058 class gp_GTrsf 
0059 {
0060 public:
0061 
0062   DEFINE_STANDARD_ALLOC
0063 
0064   //! Returns the Identity transformation.
0065   gp_GTrsf()
0066   {
0067     shape = gp_Identity;
0068     matrix.SetScale (1.0);
0069     loc.SetCoord (0.0, 0.0, 0.0);
0070     scale = 1.0;
0071   }
0072 
0073   //! Converts the gp_Trsf transformation theT into a
0074   //! general transformation, i.e. Returns a GTrsf with
0075   //! the same matrix of coefficients as the Trsf theT.
0076   gp_GTrsf (const gp_Trsf& theT)
0077   {
0078     shape = theT.Form();
0079     matrix = theT.matrix;
0080     loc = theT.TranslationPart();
0081     scale = theT.ScaleFactor();
0082   }
0083 
0084   //! Creates a transformation based on the matrix theM and the
0085   //! vector theV where theM defines the vectorial part of
0086   //! the transformation, and V the translation part, or
0087   gp_GTrsf (const gp_Mat& theM, const gp_XYZ& theV)
0088   : matrix (theM),
0089     loc (theV)
0090   {
0091     shape = gp_Other;
0092     scale = 0.0;
0093   }
0094 
0095   //! Changes this transformation into an affinity of ratio theRatio
0096   //! with respect to the axis theA1.
0097   //! Note: an affinity is a point-by-point transformation that
0098   //! transforms any point P into a point P' such that if H is
0099   //! the orthogonal projection of P on the axis theA1 or the
0100   //! plane A2, the vectors HP and HP' satisfy:
0101   //! HP' = theRatio * HP.
0102   void SetAffinity (const gp_Ax1& theA1, const Standard_Real theRatio);
0103 
0104   //! Changes this transformation into an affinity of ratio theRatio
0105   //! with respect to  the plane defined by the origin, the "X Direction" and
0106   //! the "Y Direction" of coordinate system theA2.
0107   //! Note: an affinity is a point-by-point transformation that
0108   //! transforms any point P into a point P' such that if H is
0109   //! the orthogonal projection of P on the axis A1 or the
0110   //! plane theA2, the vectors HP and HP' satisfy:
0111   //! HP' = theRatio * HP.
0112   void SetAffinity (const gp_Ax2& theA2, const Standard_Real theRatio);
0113 
0114   //! Replaces  the coefficient (theRow, theCol) of the matrix representing
0115   //! this transformation by theValue.  Raises OutOfRange
0116   //! if  theRow < 1 or theRow > 3 or theCol < 1 or theCol > 4
0117   void SetValue (const Standard_Integer theRow, const Standard_Integer theCol, const Standard_Real theValue);
0118 
0119   //! Replaces the vectorial part of this transformation by theMatrix.
0120   void SetVectorialPart (const gp_Mat& theMatrix)
0121   {
0122     matrix = theMatrix;
0123     shape = gp_Other;
0124     scale = 0.0;
0125   }
0126 
0127   //! Replaces the translation part of
0128   //! this transformation by the coordinates of the number triple theCoord.
0129   Standard_EXPORT void SetTranslationPart (const gp_XYZ& theCoord);
0130 
0131   //! Assigns the vectorial and translation parts of theT to this transformation.
0132   void SetTrsf (const gp_Trsf& theT)
0133   {
0134     shape = theT.shape;
0135     matrix = theT.matrix;
0136     loc = theT.loc;
0137     scale = theT.scale;
0138   }
0139 
0140   //! Returns true if the determinant of the vectorial part of
0141   //! this transformation is negative.
0142   Standard_Boolean IsNegative() const { return matrix.Determinant() < 0.0; }
0143 
0144   //! Returns true if this transformation is singular (and
0145   //! therefore, cannot be inverted).
0146   //! Note: The Gauss LU decomposition is used to invert the
0147   //! transformation matrix. Consequently, the transformation
0148   //! is considered as singular if the largest pivot found is less
0149   //! than or equal to gp::Resolution().
0150   //! Warning
0151   //! If this transformation is singular, it cannot be inverted.
0152   Standard_Boolean IsSingular() const { return matrix.IsSingular(); }
0153 
0154   //! Returns the nature of the transformation.  It can be an
0155   //! identity transformation, a rotation, a translation, a mirror
0156   //! transformation (relative to a point, an axis or a plane), a
0157   //! scaling transformation, a compound transformation or
0158   //! some other type of transformation.
0159   gp_TrsfForm Form() const { return shape; }
0160 
0161   //! verify and set the shape of the GTrsf Other or CompoundTrsf
0162   //! Ex :
0163   //! @code
0164   //! myGTrsf.SetValue(row1,col1,val1);
0165   //! myGTrsf.SetValue(row2,col2,val2);
0166   //! ...
0167   //! myGTrsf.SetForm();
0168   //! @endcode
0169   Standard_EXPORT void SetForm();
0170 
0171   //! Returns the translation part of the GTrsf.
0172   const gp_XYZ& TranslationPart() const { return loc; }
0173 
0174   //! Computes the vectorial part of the GTrsf. The returned Matrix
0175   //! is a  3*3 matrix.
0176   const gp_Mat& VectorialPart() const { return matrix; }
0177 
0178   //! Returns the coefficients of the global matrix of transformation.
0179   //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 4
0180   Standard_Real Value (const Standard_Integer theRow, const Standard_Integer theCol) const;
0181 
0182   Standard_Real operator() (const Standard_Integer theRow, const Standard_Integer theCol) const { return Value (theRow, theCol); }
0183 
0184   Standard_EXPORT void Invert();
0185 
0186   //! Computes the reverse transformation.
0187   //! Raises an exception if the matrix of the transformation
0188   //! is not inversible.
0189   Standard_NODISCARD gp_GTrsf Inverted() const
0190   {
0191     gp_GTrsf aT = *this;
0192     aT.Invert();
0193     return aT;
0194   }
0195 
0196   //! Computes the transformation composed from theT and <me>.
0197   //! In a C++ implementation you can also write Tcomposed = <me> * theT.
0198   //! Example :
0199   //! @code
0200   //! gp_GTrsf T1, T2, Tcomp; ...............
0201   //! //composition :
0202   //! Tcomp = T2.Multiplied(T1);         // or   (Tcomp = T2 * T1)
0203   //! // transformation of a point
0204   //! gp_XYZ P(10.,3.,4.);
0205   //! gp_XYZ P1(P);
0206   //! Tcomp.Transforms(P1);               //using Tcomp
0207   //! gp_XYZ P2(P);
0208   //! T1.Transforms(P2);                  //using T1 then T2
0209   //! T2.Transforms(P2);                  // P1 = P2 !!!
0210   //! @endcode
0211   Standard_NODISCARD gp_GTrsf Multiplied (const gp_GTrsf& theT) const
0212    {
0213     gp_GTrsf aTres = *this;
0214     aTres.Multiply (theT);
0215     return aTres;
0216   }
0217 
0218   Standard_NODISCARD gp_GTrsf operator * (const gp_GTrsf& theT)  const { return Multiplied (theT); }
0219 
0220   //! Computes the transformation composed with <me> and theT.
0221   //! <me> = <me> * theT
0222   Standard_EXPORT void Multiply (const gp_GTrsf& theT);
0223 
0224   void operator *= (const gp_GTrsf& theT) { Multiply (theT); }
0225 
0226   //! Computes the product of the transformation theT and this
0227   //! transformation and assigns the result to this transformation.
0228   //! this = theT * this
0229   Standard_EXPORT void PreMultiply (const gp_GTrsf& theT);
0230 
0231   Standard_EXPORT void Power (const Standard_Integer theN);
0232 
0233   //! Computes:
0234   //! -   the product of this transformation multiplied by itself
0235   //! theN times, if theN is positive, or
0236   //! -   the product of the inverse of this transformation
0237   //! multiplied by itself |theN| times, if theN is negative.
0238   //! If theN equals zero, the result is equal to the Identity
0239   //! transformation.
0240   //! I.e.:  <me> * <me> * .......* <me>, theN time.
0241   //! if theN =0 <me> = Identity
0242   //! if theN < 0 <me> = <me>.Inverse() *...........* <me>.Inverse().
0243   //!
0244   //! Raises an exception if N < 0 and if the matrix of the
0245   //! transformation not inversible.
0246   Standard_NODISCARD gp_GTrsf Powered (const Standard_Integer theN) const
0247   {
0248     gp_GTrsf aT = *this;
0249     aT.Power (theN);
0250     return aT;
0251   }
0252 
0253   void Transforms (gp_XYZ& theCoord) const;
0254 
0255   //! Transforms a triplet XYZ with a GTrsf.
0256   void Transforms (Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const;
0257 
0258   gp_Trsf Trsf() const;
0259 
0260   //! Convert transformation to 4x4 matrix.
0261   template<class T>
0262   void GetMat4 (NCollection_Mat4<T>& theMat) const
0263   {
0264     if (shape == gp_Identity)
0265     {
0266       theMat.InitIdentity();
0267       return;
0268     }
0269 
0270     theMat.SetValue (0, 0, static_cast<T> (Value (1, 1)));
0271     theMat.SetValue (0, 1, static_cast<T> (Value (1, 2)));
0272     theMat.SetValue (0, 2, static_cast<T> (Value (1, 3)));
0273     theMat.SetValue (0, 3, static_cast<T> (Value (1, 4)));
0274     theMat.SetValue (1, 0, static_cast<T> (Value (2, 1)));
0275     theMat.SetValue (1, 1, static_cast<T> (Value (2, 2)));
0276     theMat.SetValue (1, 2, static_cast<T> (Value (2, 3)));
0277     theMat.SetValue (1, 3, static_cast<T> (Value (2, 4)));
0278     theMat.SetValue (2, 0, static_cast<T> (Value (3, 1)));
0279     theMat.SetValue (2, 1, static_cast<T> (Value (3, 2)));
0280     theMat.SetValue (2, 2, static_cast<T> (Value (3, 3)));
0281     theMat.SetValue (2, 3, static_cast<T> (Value (3, 4)));
0282     theMat.SetValue (3, 0, static_cast<T> (0));
0283     theMat.SetValue (3, 1, static_cast<T> (0));
0284     theMat.SetValue (3, 2, static_cast<T> (0));
0285     theMat.SetValue (3, 3, static_cast<T> (1));
0286   }
0287 
0288   //! Convert transformation from 4x4 matrix.
0289   template<class T>
0290   void SetMat4 (const NCollection_Mat4<T>& theMat)
0291   {
0292     shape = gp_Other;
0293     scale = 0.0;
0294     matrix.SetValue (1, 1, theMat.GetValue (0, 0));
0295     matrix.SetValue (1, 2, theMat.GetValue (0, 1));
0296     matrix.SetValue (1, 3, theMat.GetValue (0, 2));
0297     matrix.SetValue (2, 1, theMat.GetValue (1, 0));
0298     matrix.SetValue (2, 2, theMat.GetValue (1, 1));
0299     matrix.SetValue (2, 3, theMat.GetValue (1, 2));
0300     matrix.SetValue (3, 1, theMat.GetValue (2, 0));
0301     matrix.SetValue (3, 2, theMat.GetValue (2, 1));
0302     matrix.SetValue (3, 3, theMat.GetValue (2, 2));
0303     loc.SetCoord (theMat.GetValue (0, 3), theMat.GetValue (1, 3), theMat.GetValue (2, 3));
0304   }
0305 
0306   //! Dumps the content of me into the stream
0307   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0308 
0309 private:
0310 
0311   gp_Mat matrix;
0312   gp_XYZ loc;
0313   gp_TrsfForm shape;
0314   Standard_Real scale;
0315 
0316 };
0317 
0318 
0319 //=======================================================================
0320 //function : SetAffinity
0321 // purpose :
0322 //=======================================================================
0323 inline void gp_GTrsf::SetAffinity (const gp_Ax1& theA1, const Standard_Real theRatio)
0324 {
0325   shape = gp_Other;
0326   scale = 0.0;
0327   matrix.SetDot (theA1.Direction().XYZ());
0328   matrix.Multiply (1.0 - theRatio);
0329   matrix.SetDiagonal (matrix.Value (1,1) + theRatio,
0330                       matrix.Value (2,2) + theRatio,
0331                       matrix.Value (3,3) + theRatio);
0332   loc = theA1.Location().XYZ();
0333   loc.Reverse ();
0334   loc.Multiply (matrix);
0335   loc.Add (theA1.Location().XYZ());
0336 }
0337 
0338 //=======================================================================
0339 //function : SetAffinity
0340 // purpose :
0341 //=======================================================================
0342 inline void gp_GTrsf::SetAffinity (const gp_Ax2& theA2, const Standard_Real theRatio)
0343 {
0344   shape = gp_Other;
0345   scale = 0.0;
0346   matrix.SetDot (theA2.Direction().XYZ());
0347   matrix.Multiply (theRatio - 1.);
0348   loc = theA2.Location().XYZ();
0349   loc.Reverse ();
0350   loc.Multiply (matrix);
0351   matrix.SetDiagonal (matrix.Value (1,1) + 1.,
0352                       matrix.Value (2,2) + 1.,
0353                       matrix.Value (3,3) + 1.);
0354 }
0355 
0356 //=======================================================================
0357 //function : SetValue
0358 // purpose :
0359 //=======================================================================
0360 inline void gp_GTrsf::SetValue (const Standard_Integer theRow,
0361                                 const Standard_Integer theCol,
0362                                 const Standard_Real theValue)
0363 {
0364   Standard_OutOfRange_Raise_if
0365     (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 4, " ");
0366   if (theCol == 4)
0367   {
0368     loc.SetCoord (theRow, theValue);
0369     if (shape == gp_Identity)
0370     {
0371       shape = gp_Translation;
0372     }
0373     return;
0374   }
0375   else
0376   {
0377     if (!(shape == gp_Other) && !(scale == 1.0))
0378     {
0379       matrix.Multiply (scale);
0380     }
0381     matrix.SetValue (theRow, theCol, theValue);
0382     shape = gp_Other;
0383     scale = 0.0;
0384     return;
0385   }
0386 }
0387 
0388 //=======================================================================
0389 //function : Value
0390 // purpose :
0391 //=======================================================================
0392 inline Standard_Real gp_GTrsf::Value (const Standard_Integer theRow,
0393                                       const Standard_Integer theCol) const
0394 {
0395   Standard_OutOfRange_Raise_if
0396     (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 4, " ");
0397   if (theCol == 4)
0398   {
0399     return loc.Coord (theRow);
0400   }
0401   if (shape == gp_Other)
0402   {
0403     return matrix.Value (theRow, theCol);
0404   }
0405   return scale * matrix.Value (theRow, theCol);
0406 }
0407 
0408 //=======================================================================
0409 //function : Transforms
0410 // purpose :
0411 //=======================================================================
0412 inline void gp_GTrsf::Transforms (gp_XYZ& theCoord) const
0413 {
0414   theCoord.Multiply (matrix);
0415   if (!(shape == gp_Other) && !(scale == 1.0))
0416   {
0417     theCoord.Multiply (scale);
0418   }
0419   theCoord.Add (loc);
0420 }
0421 
0422 //=======================================================================
0423 //function : Transforms
0424 // purpose :
0425 //=======================================================================
0426 inline void gp_GTrsf::Transforms (Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const
0427 {
0428   gp_XYZ aTriplet (theX, theY, theZ);
0429   aTriplet.Multiply (matrix);
0430   if (!(shape == gp_Other) && !(scale == 1.0))
0431   {
0432     aTriplet.Multiply (scale);
0433   }
0434   aTriplet.Add (loc);
0435   aTriplet.Coord (theX, theY, theZ);
0436 }
0437 
0438 //=======================================================================
0439 //function : Trsf
0440 // purpose :
0441 //=======================================================================
0442 inline gp_Trsf gp_GTrsf::Trsf() const
0443 {
0444   if (Form() == gp_Other)
0445   {
0446     throw Standard_ConstructionError("gp_GTrsf::Trsf() - non-orthogonal GTrsf");
0447   }
0448   gp_Trsf aT;
0449   aT.shape = shape;
0450   aT.scale = scale;
0451   aT.matrix = matrix;
0452   aT.loc = loc;
0453   return aT;
0454 }
0455 
0456 #endif // _gp_GTrsf_HeaderFile