Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-23 09:17:38

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