Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-14 09:14:37

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_Trsf_HeaderFile
0016 #define _gp_Trsf_HeaderFile
0017 
0018 #include <gp_TrsfForm.hxx>
0019 #include <gp_Mat.hxx>
0020 #include <gp_XYZ.hxx>
0021 #include <NCollection_Mat4.hxx>
0022 #include <Standard_OStream.hxx>
0023 #include <Standard_OutOfRange.hxx>
0024 #include <Standard_SStream.hxx>
0025 
0026 class gp_Pnt;
0027 class gp_Trsf2d;
0028 class gp_Ax1;
0029 class gp_Ax2;
0030 class gp_Quaternion;
0031 class gp_Ax3;
0032 class gp_Vec;
0033 
0034 // Avoid possible conflict with SetForm macro defined by windows.h
0035 #ifdef SetForm
0036   #undef SetForm
0037 #endif
0038 
0039 //! Defines a non-persistent transformation in 3D space.
0040 //! The following transformations are implemented :
0041 //! . Translation, Rotation, Scale
0042 //! . Symmetry with respect to a point, a line, a plane.
0043 //! Complex transformations can be obtained by combining the
0044 //! previous elementary transformations using the method
0045 //! Multiply.
0046 //! The transformations can be represented as follow :
0047 //! @code
0048 //!    V1   V2   V3    T       XYZ        XYZ
0049 //! | a11  a12  a13   a14 |   | x |      | x'|
0050 //! | a21  a22  a23   a24 |   | y |      | y'|
0051 //! | a31  a32  a33   a34 |   | z |   =  | z'|
0052 //! |  0    0    0     1  |   | 1 |      | 1 |
0053 //! @endcode
0054 //! where {V1, V2, V3} defines the vectorial part of the
0055 //! transformation and T defines the translation part of the
0056 //! transformation.
0057 //! This transformation never change the nature of the objects.
0058 class gp_Trsf
0059 {
0060 public:
0061   DEFINE_STANDARD_ALLOC
0062 
0063   //! Returns the identity transformation.
0064   constexpr gp_Trsf() noexcept;
0065 
0066   //! Creates a 3D transformation from the 2D transformation theT.
0067   //! The resulting transformation has a homogeneous
0068   //! vectorial part, V3, and a translation part, T3, built from theT:
0069   //! a11    a12
0070   //! 0             a13
0071   //! V3 =    a21    a22    0       T3
0072   //! =   a23
0073   //! 0    0    1.
0074   //! 0
0075   //! It also has the same scale factor as theT. This
0076   //! guarantees (by projection) that the transformation
0077   //! which would be performed by theT in a plane (2D space)
0078   //! is performed by the resulting transformation in the xOy
0079   //! plane of the 3D space, (i.e. in the plane defined by the
0080   //! origin (0., 0., 0.) and the vectors DX (1., 0., 0.), and DY
0081   //! (0., 1., 0.)). The scale factor is applied to the entire space.
0082   Standard_EXPORT gp_Trsf(const gp_Trsf2d& theT);
0083 
0084   //! Makes the transformation into a symmetrical transformation.
0085   //! theP is the center of the symmetry.
0086   constexpr void SetMirror(const gp_Pnt& theP) noexcept;
0087 
0088   //! Makes the transformation into a symmetrical transformation.
0089   //! theA1 is the center of the axial symmetry.
0090   Standard_EXPORT void SetMirror(const gp_Ax1& theA1) noexcept;
0091 
0092   //! Makes the transformation into a symmetrical transformation.
0093   //! theA2 is the center of the planar symmetry
0094   //! and defines the plane of symmetry by its origin, "X
0095   //! Direction" and "Y Direction".
0096   Standard_EXPORT void SetMirror(const gp_Ax2& theA2) noexcept;
0097 
0098   //! Changes the transformation into a rotation.
0099   //! theA1 is the rotation axis and theAng is the angular value of the
0100   //! rotation in radians.
0101   Standard_EXPORT void SetRotation(const gp_Ax1& theA1, const double theAng);
0102 
0103   //! Changes the transformation into a rotation defined by quaternion.
0104   //! Note that rotation is performed around origin, i.e.
0105   //! no translation is involved.
0106   Standard_EXPORT void SetRotation(const gp_Quaternion& theR);
0107 
0108   //! Replaces the rotation part with specified quaternion.
0109   Standard_EXPORT void SetRotationPart(const gp_Quaternion& theR);
0110 
0111   //! Changes the transformation into a scale.
0112   //! theP is the center of the scale and theS is the scaling value.
0113   //! Raises ConstructionError If <theS> is null.
0114   Standard_EXPORT void SetScale(const gp_Pnt& theP, const double theS);
0115 
0116   //! Modifies this transformation so that it transforms the
0117   //! coordinate system defined by theFromSystem1 into the
0118   //! one defined by theToSystem2. After this modification, this
0119   //! transformation transforms:
0120   //! -   the origin of theFromSystem1 into the origin of theToSystem2,
0121   //! -   the "X Direction" of theFromSystem1 into the "X
0122   //! Direction" of theToSystem2,
0123   //! -   the "Y Direction" of theFromSystem1 into the "Y
0124   //! Direction" of theToSystem2, and
0125   //! -   the "main Direction" of theFromSystem1 into the "main
0126   //! Direction" of theToSystem2.
0127   //! Warning
0128   //! When you know the coordinates of a point in one
0129   //! coordinate system and you want to express these
0130   //! coordinates in another one, do not use the
0131   //! transformation resulting from this function. Use the
0132   //! transformation that results from SetTransformation instead.
0133   //! SetDisplacement and SetTransformation create
0134   //! related transformations: the vectorial part of one is the
0135   //! inverse of the vectorial part of the other.
0136   Standard_EXPORT void SetDisplacement(const gp_Ax3& theFromSystem1, const gp_Ax3& theToSystem2);
0137 
0138   //! Modifies this transformation so that it transforms the
0139   //! coordinates of any point, (x, y, z), relative to a source
0140   //! coordinate system into the coordinates (x', y', z') which
0141   //! are relative to a target coordinate system, but which
0142   //! represent the same point
0143   //! The transformation is from the coordinate
0144   //! system "theFromSystem1" to the coordinate system "theToSystem2".
0145   //! Example :
0146   //! @code
0147   //! gp_Ax3 theFromSystem1, theToSystem2;
0148   //! double x1, y1, z1;  // are the coordinates of a point in the local system theFromSystem1
0149   //! double x2, y2, z2;  // are the coordinates of a point in the local system theToSystem2
0150   //! gp_Pnt P1 (x1, y1, z1)
0151   //! gp_Trsf T;
0152   //! T.SetTransformation (theFromSystem1, theToSystem2);
0153   //! gp_Pnt P2 = P1.Transformed (T);
0154   //! P2.Coord (x2, y2, z2);
0155   //! @endcode
0156   Standard_EXPORT void SetTransformation(const gp_Ax3& theFromSystem1, const gp_Ax3& theToSystem2);
0157 
0158   //! Modifies this transformation so that it transforms the
0159   //! coordinates of any point, (x, y, z), relative to a source
0160   //! coordinate system into the coordinates (x', y', z') which
0161   //! are relative to a target coordinate system, but which
0162   //! represent the same point
0163   //! The transformation is from the default coordinate system
0164   //! @code
0165   //! {P(0.,0.,0.), VX (1.,0.,0.), VY (0.,1.,0.), VZ (0., 0. ,1.) }
0166   //! @endcode
0167   //! to the local coordinate system defined with the Ax3 theToSystem.
0168   //! Use in the same way as the previous method. FromSystem1 is
0169   //! defaulted to the absolute coordinate system.
0170   Standard_EXPORT void SetTransformation(const gp_Ax3& theToSystem);
0171 
0172   //! Sets transformation by directly specified rotation and translation.
0173   Standard_EXPORT void SetTransformation(const gp_Quaternion& R, const gp_Vec& theT);
0174 
0175   //! Changes the transformation into a translation.
0176   //! theV is the vector of the translation.
0177   constexpr void SetTranslation(const gp_Vec& theV) noexcept;
0178 
0179   //! Makes the transformation into a translation where the translation vector
0180   //! is the vector (theP1, theP2) defined from point theP1 to point theP2.
0181   constexpr void SetTranslation(const gp_Pnt& theP1, const gp_Pnt& theP2) noexcept;
0182 
0183   //! Replaces the translation vector with the vector theV.
0184   Standard_EXPORT void SetTranslationPart(const gp_Vec& theV) noexcept;
0185 
0186   //! Modifies the scale factor.
0187   //! Raises ConstructionError If theS is null.
0188   Standard_EXPORT void SetScaleFactor(const double theS);
0189 
0190   constexpr void SetForm(const gp_TrsfForm theP) noexcept { shape = theP; }
0191 
0192   //! Sets the coefficients of the transformation. The
0193   //! transformation of the point x,y,z is the point
0194   //! x',y',z' with :
0195   //! @code
0196   //! x' = a11 x + a12 y + a13 z + a14
0197   //! y' = a21 x + a22 y + a23 z + a24
0198   //! z' = a31 x + a32 y + a33 z + a34
0199   //! @endcode
0200   //! The method Value(i,j) will return aij.
0201   //! Raises ConstructionError if the determinant of the aij is null.
0202   //! The matrix is orthogonalized before future using.
0203   Standard_EXPORT void SetValues(const double a11,
0204                                  const double a12,
0205                                  const double a13,
0206                                  const double a14,
0207                                  const double a21,
0208                                  const double a22,
0209                                  const double a23,
0210                                  const double a24,
0211                                  const double a31,
0212                                  const double a32,
0213                                  const double a33,
0214                                  const double a34);
0215 
0216   //! Returns true if the determinant of the vectorial part of
0217   //! this transformation is negative.
0218   constexpr bool IsNegative() const noexcept { return (scale < 0.0); }
0219 
0220   //! Returns the nature of the transformation. It can be: an
0221   //! identity transformation, a rotation, a translation, a mirror
0222   //! transformation (relative to a point, an axis or a plane), a
0223   //! scaling transformation, or a compound transformation.
0224   constexpr gp_TrsfForm Form() const noexcept { return shape; }
0225 
0226   //! Returns the scale factor.
0227   constexpr double ScaleFactor() const noexcept { return scale; }
0228 
0229   //! Returns the translation part of the transformation's matrix
0230   constexpr const gp_XYZ& TranslationPart() const noexcept { return loc; }
0231 
0232   //! Returns the boolean True if there is non-zero rotation.
0233   //! In the presence of rotation, the output parameters store the axis
0234   //! and the angle of rotation. The method always returns positive
0235   //! value "theAngle", i.e., 0. < theAngle <= PI.
0236   //! Note that this rotation is defined only by the vectorial part of
0237   //! the transformation; generally you would need to check also the
0238   //! translational part to obtain the axis (gp_Ax1) of rotation.
0239   Standard_EXPORT bool GetRotation(gp_XYZ& theAxis, double& theAngle) const;
0240 
0241   //! Returns quaternion representing rotational part of the transformation.
0242   Standard_EXPORT gp_Quaternion GetRotation() const;
0243 
0244   //! Returns the vectorial part of the transformation. It is
0245   //! a 3*3 matrix which includes the scale factor.
0246   constexpr gp_Mat VectorialPart() const noexcept;
0247 
0248   //! Computes the homogeneous vectorial part of the transformation.
0249   //! It is a 3*3 matrix which doesn't include the scale factor.
0250   //! In other words, the vectorial part of this transformation is equal
0251   //! to its homogeneous vectorial part, multiplied by the scale factor.
0252   //! The coefficients of this matrix must be multiplied by the
0253   //! scale factor to obtain the coefficients of the transformation.
0254   constexpr const gp_Mat& HVectorialPart() const noexcept { return matrix; }
0255 
0256   //! Returns the coefficients of the transformation's matrix.
0257   //! It is a 3 rows * 4 columns matrix.
0258   //! This coefficient includes the scale factor.
0259   //! Raises OutOfRanged if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 4
0260   constexpr double Value(const int theRow, const int theCol) const;
0261 
0262   Standard_EXPORT void Invert();
0263 
0264   //! Computes the reverse transformation
0265   //! Raises an exception if the matrix of the transformation
0266   //! is not inversible, it means that the scale factor is lower
0267   //! or equal to Resolution from package gp.
0268   //! Computes the transformation composed with T and <me>.
0269   //! In a C++ implementation you can also write Tcomposed = <me> * T.
0270   //! Example :
0271   //! @code
0272   //! gp_Trsf T1, T2, Tcomp; ...............
0273   //! Tcomp = T2.Multiplied(T1);         // or   (Tcomp = T2 * T1)
0274   //! gp_Pnt P1(10.,3.,4.);
0275   //! gp_Pnt P2 = P1.Transformed(Tcomp); // using Tcomp
0276   //! gp_Pnt P3 = P1.Transformed(T1);    // using T1 then T2
0277   //! P3.Transform(T2);                  // P3 = P2 !!!
0278   //! @endcode
0279   [[nodiscard]] gp_Trsf Inverted() const
0280   {
0281     gp_Trsf aT = *this;
0282     aT.Invert();
0283     return aT;
0284   }
0285 
0286   [[nodiscard]] gp_Trsf Multiplied(const gp_Trsf& theT) const
0287   {
0288     gp_Trsf aTresult(*this);
0289     aTresult.Multiply(theT);
0290     return aTresult;
0291   }
0292 
0293   [[nodiscard]] gp_Trsf operator*(const gp_Trsf& theT) const { return Multiplied(theT); }
0294 
0295   //! Computes the transformation composed with <me> and theT.
0296   //! <me> = <me> * theT
0297   Standard_EXPORT void Multiply(const gp_Trsf& theT);
0298 
0299   void operator*=(const gp_Trsf& theT) { Multiply(theT); }
0300 
0301   //! Computes the transformation composed with <me> and T.
0302   //! <me> = theT * <me>
0303   Standard_EXPORT void PreMultiply(const gp_Trsf& theT);
0304 
0305   Standard_EXPORT void Power(const int theN);
0306 
0307   //! Computes the following composition of transformations
0308   //! <me> * <me> * .......* <me>, theN time.
0309   //! if theN = 0 <me> = Identity
0310   //! if theN < 0 <me> = <me>.Inverse() *...........* <me>.Inverse().
0311   //!
0312   //! Raises if theN < 0 and if the matrix of the transformation not
0313   //! inversible.
0314   [[nodiscard]] gp_Trsf Powered(const int theN) const
0315   {
0316     gp_Trsf aT = *this;
0317     aT.Power(theN);
0318     return aT;
0319   }
0320 
0321   constexpr void Transforms(double& theX, double& theY, double& theZ) const noexcept;
0322 
0323   //! Transformation of a triplet XYZ with a Trsf
0324   constexpr void Transforms(gp_XYZ& theCoord) const noexcept;
0325 
0326   //! Convert transformation to 4x4 matrix.
0327   template <class T>
0328   void GetMat4(NCollection_Mat4<T>& theMat) const
0329   {
0330     if (shape == gp_Identity)
0331     {
0332       theMat.InitIdentity();
0333       return;
0334     }
0335 
0336     theMat.SetValue(0, 0, static_cast<T>(Value(1, 1)));
0337     theMat.SetValue(0, 1, static_cast<T>(Value(1, 2)));
0338     theMat.SetValue(0, 2, static_cast<T>(Value(1, 3)));
0339     theMat.SetValue(0, 3, static_cast<T>(Value(1, 4)));
0340     theMat.SetValue(1, 0, static_cast<T>(Value(2, 1)));
0341     theMat.SetValue(1, 1, static_cast<T>(Value(2, 2)));
0342     theMat.SetValue(1, 2, static_cast<T>(Value(2, 3)));
0343     theMat.SetValue(1, 3, static_cast<T>(Value(2, 4)));
0344     theMat.SetValue(2, 0, static_cast<T>(Value(3, 1)));
0345     theMat.SetValue(2, 1, static_cast<T>(Value(3, 2)));
0346     theMat.SetValue(2, 2, static_cast<T>(Value(3, 3)));
0347     theMat.SetValue(2, 3, static_cast<T>(Value(3, 4)));
0348     theMat.SetValue(3, 0, static_cast<T>(0));
0349     theMat.SetValue(3, 1, static_cast<T>(0));
0350     theMat.SetValue(3, 2, static_cast<T>(0));
0351     theMat.SetValue(3, 3, static_cast<T>(1));
0352   }
0353 
0354   //! Dumps the content of me into the stream
0355   Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const;
0356 
0357   //! Inits the content of me from the stream
0358   Standard_EXPORT bool InitFromJson(const Standard_SStream& theSStream, int& theStreamPos);
0359 
0360   friend class gp_GTrsf;
0361 
0362 protected:
0363   //! Makes orthogonalization of "matrix"
0364   Standard_EXPORT void Orthogonalize();
0365 
0366 private:
0367   double      scale;
0368   gp_TrsfForm shape;
0369   gp_Mat      matrix;
0370   gp_XYZ      loc;
0371 };
0372 
0373 #include <gp_Trsf2d.hxx>
0374 #include <gp_Vec.hxx>
0375 #include <gp_Pnt.hxx>
0376 
0377 //=================================================================================================
0378 
0379 inline constexpr gp_Trsf::gp_Trsf() noexcept
0380     : scale(1.0),
0381       shape(gp_Identity),
0382       matrix(1, 0, 0, 0, 1, 0, 0, 0, 1),
0383       loc(0.0, 0.0, 0.0)
0384 {
0385 }
0386 
0387 //=================================================================================================
0388 
0389 inline constexpr void gp_Trsf::SetMirror(const gp_Pnt& theP) noexcept
0390 {
0391   shape = gp_PntMirror;
0392   scale = -1.0;
0393   loc   = theP.XYZ();
0394   matrix.SetIdentity();
0395   loc.Multiply(2.0);
0396 }
0397 
0398 //=================================================================================================
0399 
0400 inline constexpr void gp_Trsf::SetTranslation(const gp_Vec& theV) noexcept
0401 {
0402   shape = gp_Translation;
0403   scale = 1.;
0404   matrix.SetIdentity();
0405   loc = theV.XYZ();
0406 }
0407 
0408 //=================================================================================================
0409 
0410 inline constexpr void gp_Trsf::SetTranslation(const gp_Pnt& theP1, const gp_Pnt& theP2) noexcept
0411 {
0412   shape = gp_Translation;
0413   scale = 1.0;
0414   matrix.SetIdentity();
0415   loc = (theP2.XYZ()).Subtracted(theP1.XYZ());
0416 }
0417 
0418 //=================================================================================================
0419 
0420 inline constexpr double gp_Trsf::Value(const int theRow, const int theCol) const
0421 {
0422   Standard_OutOfRange_Raise_if(theRow < 1 || theRow > 3 || theCol < 1 || theCol > 4, " ");
0423   if (theCol < 4)
0424   {
0425     // Access matrix data directly to avoid non-constexpr Value() call
0426     return scale * matrix.myMat[theRow - 1][theCol - 1];
0427   }
0428   else
0429   {
0430     return loc.Coord(theRow);
0431   }
0432 }
0433 
0434 //=================================================================================================
0435 
0436 inline constexpr void gp_Trsf::Transforms(double& theX, double& theY, double& theZ) const noexcept
0437 {
0438   gp_XYZ aTriplet(theX, theY, theZ);
0439   aTriplet.Multiply(matrix);
0440   if (scale != 1.0)
0441   {
0442     aTriplet.Multiply(scale);
0443   }
0444   aTriplet.Add(loc);
0445   theX = aTriplet.X();
0446   theY = aTriplet.Y();
0447   theZ = aTriplet.Z();
0448 }
0449 
0450 //=================================================================================================
0451 
0452 inline constexpr void gp_Trsf::Transforms(gp_XYZ& theCoord) const noexcept
0453 {
0454   theCoord.Multiply(matrix);
0455   if (scale != 1.0)
0456   {
0457     theCoord.Multiply(scale);
0458   }
0459   theCoord.Add(loc);
0460 }
0461 
0462 //=================================================================================================
0463 
0464 inline constexpr gp_Mat gp_Trsf::VectorialPart() const noexcept
0465 {
0466   if (scale == 1.0)
0467   {
0468     return matrix;
0469   }
0470   gp_Mat M = matrix;
0471   if (shape == gp_Scale || shape == gp_PntMirror)
0472   {
0473     // Access matrix data directly for constexpr (gp_Trsf is friend of gp_Mat)
0474     M.SetDiagonal(scale * M.myMat[0][0], scale * M.myMat[1][1], scale * M.myMat[2][2]);
0475   }
0476   else
0477   {
0478     M.Multiply(scale);
0479   }
0480   return M;
0481 }
0482 
0483 #endif // _gp_Trsf_HeaderFile