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_Mat_HeaderFile
0016 #define _gp_Mat_HeaderFile
0017 
0018 #include <gp.hxx>
0019 #include <Standard_OutOfRange.hxx>
0020 #include <Standard_OStream.hxx>
0021 #include <Standard_ConstructionError.hxx>
0022 
0023 class gp_XYZ;
0024 
0025 //! Describes a three column, three row matrix.
0026 //! This sort of object is used in various vectorial or matrix computations.
0027 class gp_Mat 
0028 {
0029 public:
0030 
0031   DEFINE_STANDARD_ALLOC
0032 
0033   //! creates  a matrix with null coefficients.
0034   gp_Mat()
0035   {
0036     myMat[0][0] = myMat[0][1] = myMat[0][2] =
0037     myMat[1][0] = myMat[1][1] = myMat[1][2] =
0038     myMat[2][0] = myMat[2][1] = myMat[2][2] = 0.0;
0039   }
0040 
0041   gp_Mat (const Standard_Real theA11, const Standard_Real theA12, const Standard_Real theA13,
0042           const Standard_Real theA21, const Standard_Real theA22, const Standard_Real theA23,
0043           const Standard_Real theA31, const Standard_Real theA32, const Standard_Real theA33);
0044 
0045   //! Creates a matrix.
0046   //! theCol1, theCol2, theCol3 are the 3 columns of the matrix.
0047   Standard_EXPORT gp_Mat (const gp_XYZ& theCol1, const gp_XYZ& theCol2, const gp_XYZ& theCol3);
0048 
0049   //! Assigns the three coordinates of theValue to the column of index
0050   //! theCol of this matrix.
0051   //! Raises OutOfRange if theCol < 1 or theCol > 3.
0052   Standard_EXPORT void SetCol (const Standard_Integer theCol, const gp_XYZ& theValue);
0053 
0054   //! Assigns the number triples theCol1, theCol2, theCol3 to the three
0055   //! columns of this matrix.
0056   Standard_EXPORT void SetCols (const gp_XYZ& theCol1, const gp_XYZ& theCol2, const gp_XYZ& theCol3);
0057 
0058   //! Modifies the matrix  M so that applying it to any number
0059   //! triple (X, Y, Z) produces the same result as the cross
0060   //! product of theRef and the number triple (X, Y, Z):
0061   //! i.e.: M * {X,Y,Z}t = theRef.Cross({X, Y ,Z})
0062   //! this matrix is anti symmetric. To apply this matrix to the
0063   //! triplet  {XYZ} is the same as to do the cross product between the
0064   //! triplet theRef and the triplet {XYZ}.
0065   //! Note: this matrix is anti-symmetric.
0066   Standard_EXPORT void SetCross (const gp_XYZ& theRef);
0067 
0068   //! Modifies the main diagonal of the matrix.
0069   //! @code
0070   //! <me>.Value (1, 1) = theX1
0071   //! <me>.Value (2, 2) = theX2
0072   //! <me>.Value (3, 3) = theX3
0073   //! @endcode
0074   //! The other coefficients of the matrix are not modified.
0075   void SetDiagonal (const Standard_Real theX1, const Standard_Real theX2, const Standard_Real theX3)
0076   {
0077     myMat[0][0] = theX1;
0078     myMat[1][1] = theX2;
0079     myMat[2][2] = theX3;
0080   }
0081 
0082   //! Modifies this matrix so that applying it to any number
0083   //! triple (X, Y, Z) produces the same result as the scalar
0084   //! product of theRef and the number triple (X, Y, Z):
0085   //! this * (X,Y,Z) = theRef.(X,Y,Z)
0086   //! Note: this matrix is symmetric.
0087   Standard_EXPORT void SetDot (const gp_XYZ& theRef);
0088 
0089   //! Modifies this matrix so that it represents the Identity matrix.
0090   void SetIdentity()
0091   {
0092     myMat[0][0] = myMat[1][1] = myMat[2][2] = 1.0;
0093     myMat[0][1] = myMat[0][2] = myMat[1][0] = myMat[1][2] = myMat[2][0] = myMat[2][1] = 0.0;
0094   }
0095 
0096   //! Modifies this matrix so that it represents a rotation. theAng is the angular value in
0097   //! radians and the XYZ axis gives the direction of the
0098   //! rotation.
0099   //! Raises ConstructionError if XYZ.Modulus() <= Resolution()
0100   Standard_EXPORT void SetRotation (const gp_XYZ& theAxis, const Standard_Real theAng);
0101 
0102   //! Assigns the three coordinates of Value to the row of index
0103   //! theRow of this matrix. Raises OutOfRange if theRow < 1 or theRow > 3.
0104   Standard_EXPORT void SetRow (const Standard_Integer theRow, const gp_XYZ& theValue);
0105 
0106   //! Assigns the number triples theRow1, theRow2, theRow3 to the three
0107   //! rows of this matrix.
0108   Standard_EXPORT void SetRows (const gp_XYZ& theRow1, const gp_XYZ& theRow2, const gp_XYZ& theRow3);
0109 
0110   //! Modifies the matrix so that it represents
0111   //! a scaling transformation, where theS is the scale factor. :
0112   //! @code
0113   //!         | theS    0.0  0.0 |
0114   //! <me> =  | 0.0   theS   0.0 |
0115   //!         | 0.0  0.0   theS  |
0116   //! @endcode
0117   void SetScale (const Standard_Real theS)
0118   {
0119     myMat[0][0] = myMat[1][1] = myMat[2][2] = theS;
0120     myMat[0][1] = myMat[0][2] = myMat[1][0] = myMat[1][2] = myMat[2][0] = myMat[2][1] = 0.0;
0121   }
0122 
0123   //! Assigns <theValue> to the coefficient of row theRow, column theCol of   this matrix.
0124   //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 3
0125   void SetValue (const Standard_Integer theRow, const Standard_Integer theCol, const Standard_Real theValue)
0126   {
0127     Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 3, " ");
0128     myMat[theRow - 1][theCol - 1] = theValue;
0129   }
0130 
0131   //! Returns the column of theCol index.
0132   //! Raises OutOfRange if theCol < 1 or theCol > 3
0133   Standard_EXPORT gp_XYZ Column (const Standard_Integer theCol) const;
0134 
0135   //! Computes the determinant of the matrix.
0136   Standard_Real Determinant() const
0137   {
0138     return myMat[0][0] * (myMat[1][1] * myMat[2][2] - myMat[2][1] * myMat[1][2]) -
0139            myMat[0][1] * (myMat[1][0] * myMat[2][2] - myMat[2][0] * myMat[1][2]) +
0140            myMat[0][2] * (myMat[1][0] * myMat[2][1] - myMat[2][0] * myMat[1][1]);
0141   }
0142 
0143   //! Returns the main diagonal of the matrix.
0144   Standard_EXPORT gp_XYZ Diagonal() const;
0145 
0146   //! returns the row of theRow index.
0147   //! Raises OutOfRange if theRow < 1 or theRow > 3
0148   Standard_EXPORT gp_XYZ Row (const Standard_Integer theRow) const;
0149 
0150   //! Returns the coefficient of range (theRow, theCol)
0151   //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 3
0152   const Standard_Real& Value (const Standard_Integer theRow, const Standard_Integer theCol) const
0153   {
0154     Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 3, " ");
0155     return myMat[theRow - 1][theCol - 1];
0156   }
0157 
0158   const Standard_Real& operator() (const Standard_Integer theRow, const Standard_Integer theCol) const { return Value (theRow, theCol); }
0159 
0160   //! Returns the coefficient of range (theRow, theCol)
0161   //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 3
0162   Standard_Real& ChangeValue (const Standard_Integer theRow, const Standard_Integer theCol)
0163   {
0164     Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 3, " ");
0165     return myMat[theRow - 1][theCol - 1];
0166   }
0167 
0168   Standard_Real& operator() (const Standard_Integer theRow, const Standard_Integer theCol) { return ChangeValue (theRow, theCol); }
0169 
0170   //! The Gauss LU decomposition is used to invert the matrix
0171   //! (see Math package) so the matrix is considered as singular if
0172   //! the largest pivot found is lower or equal to Resolution from gp.
0173   Standard_Boolean IsSingular() const
0174   {
0175     // Pour etre sur que Gauss va fonctionner, il faut faire Gauss ...
0176     Standard_Real aVal = Determinant();
0177     if (aVal < 0)
0178     {
0179       aVal = -aVal;
0180     }
0181     return aVal <= gp::Resolution();
0182   }
0183 
0184   void Add (const gp_Mat& theOther);
0185 
0186   void operator += (const gp_Mat& theOther) { Add (theOther); }
0187 
0188   //! Computes the sum of this matrix and
0189   //! the matrix theOther for each coefficient of the matrix :
0190   //! <me>.Coef(i,j) + <theOther>.Coef(i,j)
0191   Standard_NODISCARD gp_Mat Added (const gp_Mat& theOther) const;
0192 
0193   Standard_NODISCARD gp_Mat operator + (const gp_Mat& theOther) const { return Added (theOther); }
0194 
0195   void Divide (const Standard_Real theScalar);
0196 
0197   void operator /= (const Standard_Real theScalar) { Divide (theScalar); }
0198 
0199   //! Divides all the coefficients of the matrix by Scalar
0200   Standard_NODISCARD gp_Mat Divided (const Standard_Real theScalar) const;
0201 
0202   Standard_NODISCARD gp_Mat operator / (const Standard_Real theScalar) const { return Divided (theScalar); }
0203 
0204   Standard_EXPORT void Invert();
0205 
0206   //! Inverses the matrix and raises if the matrix is singular.
0207   //! -   Invert assigns the result to this matrix, while
0208   //! -   Inverted creates a new one.
0209   //! Warning
0210   //! The Gauss LU decomposition is used to invert the matrix.
0211   //! Consequently, the matrix is considered as singular if the
0212   //! largest pivot found is less than or equal to gp::Resolution().
0213   //! Exceptions
0214   //! Standard_ConstructionError if this matrix is singular,
0215   //! and therefore cannot be inverted.
0216   Standard_NODISCARD Standard_EXPORT gp_Mat Inverted() const;
0217 
0218   //! Computes  the product of two matrices <me> * <Other>
0219   Standard_NODISCARD gp_Mat Multiplied (const gp_Mat& theOther) const
0220   {
0221     gp_Mat aNewMat = *this;
0222     aNewMat.Multiply (theOther);
0223     return aNewMat;
0224   }
0225 
0226   Standard_NODISCARD gp_Mat operator * (const gp_Mat& theOther) const { return Multiplied (theOther); }
0227 
0228   //! Computes the product of two matrices <me> = <Other> * <me>.
0229   void Multiply (const gp_Mat& theOther);
0230 
0231   void operator *= (const gp_Mat& theOther) { Multiply (theOther); }
0232 
0233   void PreMultiply (const gp_Mat& theOther);
0234 
0235   Standard_NODISCARD gp_Mat Multiplied (const Standard_Real theScalar) const;
0236 
0237   Standard_NODISCARD gp_Mat operator * (const Standard_Real theScalar) const { return Multiplied (theScalar); }
0238 
0239   //! Multiplies all the coefficients of the matrix by Scalar
0240   void Multiply (const Standard_Real theScalar);
0241 
0242   void operator *= (const Standard_Real theScalar) { Multiply (theScalar); }
0243 
0244   Standard_EXPORT void Power (const Standard_Integer N);
0245 
0246   //! Computes <me> = <me> * <me> * .......* <me>,   theN time.
0247   //! if theN = 0 <me> = Identity
0248   //! if theN < 0 <me> = <me>.Invert() *...........* <me>.Invert().
0249   //! If theN < 0 an exception will be raised if the matrix is not
0250   //! inversible
0251   Standard_NODISCARD gp_Mat Powered (const Standard_Integer theN) const
0252   {
0253     gp_Mat aMatN = *this;
0254     aMatN.Power (theN);
0255     return aMatN;
0256   }
0257 
0258   void Subtract (const gp_Mat& theOther);
0259 
0260   void operator -= (const gp_Mat& theOther) { Subtract (theOther); }
0261 
0262   //! cOmputes for each coefficient of the matrix :
0263   //! <me>.Coef(i,j) - <theOther>.Coef(i,j)
0264   Standard_NODISCARD gp_Mat Subtracted (const gp_Mat& theOther) const;
0265 
0266   Standard_NODISCARD gp_Mat operator - (const gp_Mat& theOther) const { return Subtracted (theOther); }
0267 
0268   void Transpose();
0269 
0270   //! Transposes the matrix. A(j, i) -> A (i, j)
0271   Standard_NODISCARD gp_Mat Transposed() const
0272   {
0273     gp_Mat aNewMat = *this;
0274     aNewMat.Transpose();
0275     return aNewMat;
0276   }
0277 
0278   //! Dumps the content of me into the stream
0279   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
0280 
0281 friend class gp_XYZ;
0282 friend class gp_Trsf;
0283 friend class gp_GTrsf;
0284 
0285 private:
0286 
0287   Standard_Real myMat[3][3];
0288 
0289 };
0290 
0291 //=======================================================================
0292 //function : gp_Mat
0293 // purpose :
0294 //=======================================================================
0295 inline gp_Mat::gp_Mat (const Standard_Real theA11, const Standard_Real theA12, const Standard_Real theA13,
0296                        const Standard_Real theA21, const Standard_Real theA22, const Standard_Real theA23,
0297                        const Standard_Real theA31, const Standard_Real theA32, const Standard_Real theA33)
0298 {
0299   myMat[0][0] = theA11;
0300   myMat[0][1] = theA12;
0301   myMat[0][2] = theA13;
0302   myMat[1][0] = theA21;
0303   myMat[1][1] = theA22;
0304   myMat[1][2] = theA23;
0305   myMat[2][0] = theA31;
0306   myMat[2][1] = theA32;
0307   myMat[2][2] = theA33;
0308 }
0309 
0310 //=======================================================================
0311 //function : Add
0312 // purpose :
0313 //=======================================================================
0314 inline void gp_Mat::Add (const gp_Mat& theOther)
0315 {
0316   myMat[0][0] += theOther.myMat[0][0];
0317   myMat[0][1] += theOther.myMat[0][1];
0318   myMat[0][2] += theOther.myMat[0][2];
0319   myMat[1][0] += theOther.myMat[1][0];
0320   myMat[1][1] += theOther.myMat[1][1];
0321   myMat[1][2] += theOther.myMat[1][2];
0322   myMat[2][0] += theOther.myMat[2][0];
0323   myMat[2][1] += theOther.myMat[2][1];
0324   myMat[2][2] += theOther.myMat[2][2];
0325 }
0326 
0327 //=======================================================================
0328 //function : Added
0329 // purpose :
0330 //=======================================================================
0331 inline gp_Mat gp_Mat::Added (const gp_Mat& theOther) const
0332 {
0333   gp_Mat aNewMat;
0334   aNewMat.myMat[0][0] = myMat[0][0] + theOther.myMat[0][0];
0335   aNewMat.myMat[0][1] = myMat[0][1] + theOther.myMat[0][1];
0336   aNewMat.myMat[0][2] = myMat[0][2] + theOther.myMat[0][2];
0337   aNewMat.myMat[1][0] = myMat[1][0] + theOther.myMat[1][0];
0338   aNewMat.myMat[1][1] = myMat[1][1] + theOther.myMat[1][1];
0339   aNewMat.myMat[1][2] = myMat[1][2] + theOther.myMat[1][2];
0340   aNewMat.myMat[2][0] = myMat[2][0] + theOther.myMat[2][0];
0341   aNewMat.myMat[2][1] = myMat[2][1] + theOther.myMat[2][1];
0342   aNewMat.myMat[2][2] = myMat[2][2] + theOther.myMat[2][2];
0343   return aNewMat;
0344 }
0345 
0346 //=======================================================================
0347 //function : Divide
0348 // purpose :
0349 //=======================================================================
0350 inline void gp_Mat::Divide (const Standard_Real theScalar)
0351 {
0352   Standard_Real aVal = theScalar;
0353   if (aVal < 0)
0354   {
0355     aVal = -aVal;
0356   }
0357   Standard_ConstructionError_Raise_if (aVal <= gp::Resolution(),"gp_Mat : Divide by 0");
0358   const Standard_Real anUnSurScalar = 1.0 / theScalar;
0359   myMat[0][0] *= anUnSurScalar;
0360   myMat[0][1] *= anUnSurScalar;
0361   myMat[0][2] *= anUnSurScalar;
0362   myMat[1][0] *= anUnSurScalar;
0363   myMat[1][1] *= anUnSurScalar;
0364   myMat[1][2] *= anUnSurScalar;
0365   myMat[2][0] *= anUnSurScalar;
0366   myMat[2][1] *= anUnSurScalar;
0367   myMat[2][2] *= anUnSurScalar;
0368 }
0369 
0370 //=======================================================================
0371 //function : Divided
0372 // purpose :
0373 //=======================================================================
0374 inline gp_Mat gp_Mat::Divided (const Standard_Real theScalar) const
0375 {
0376   Standard_Real aVal = theScalar;
0377   if (aVal < 0)
0378   {
0379     aVal = -aVal;
0380   }
0381   Standard_ConstructionError_Raise_if (aVal <= gp::Resolution(),"gp_Mat : Divide by 0");
0382   gp_Mat aNewMat;
0383   const Standard_Real anUnSurScalar = 1.0 / theScalar;
0384   aNewMat.myMat[0][0] = myMat[0][0] * anUnSurScalar;
0385   aNewMat.myMat[0][1] = myMat[0][1] * anUnSurScalar;
0386   aNewMat.myMat[0][2] = myMat[0][2] * anUnSurScalar;
0387   aNewMat.myMat[1][0] = myMat[1][0] * anUnSurScalar;
0388   aNewMat.myMat[1][1] = myMat[1][1] * anUnSurScalar;
0389   aNewMat.myMat[1][2] = myMat[1][2] * anUnSurScalar;
0390   aNewMat.myMat[2][0] = myMat[2][0] * anUnSurScalar;
0391   aNewMat.myMat[2][1] = myMat[2][1] * anUnSurScalar;
0392   aNewMat.myMat[2][2] = myMat[2][2] * anUnSurScalar;
0393   return aNewMat;
0394 }
0395 
0396 //=======================================================================
0397 //function : Multiply
0398 // purpose :
0399 //=======================================================================
0400 inline void gp_Mat::Multiply (const gp_Mat& theOther)
0401 {
0402   const Standard_Real aT00 = myMat[0][0] * theOther.myMat[0][0] + myMat[0][1] * theOther.myMat[1][0] + myMat[0][2] * theOther.myMat[2][0];
0403   const Standard_Real aT01 = myMat[0][0] * theOther.myMat[0][1] + myMat[0][1] * theOther.myMat[1][1] + myMat[0][2] * theOther.myMat[2][1];
0404   const Standard_Real aT02 = myMat[0][0] * theOther.myMat[0][2] + myMat[0][1] * theOther.myMat[1][2] + myMat[0][2] * theOther.myMat[2][2];
0405   const Standard_Real aT10 = myMat[1][0] * theOther.myMat[0][0] + myMat[1][1] * theOther.myMat[1][0] + myMat[1][2] * theOther.myMat[2][0];
0406   const Standard_Real aT11 = myMat[1][0] * theOther.myMat[0][1] + myMat[1][1] * theOther.myMat[1][1] + myMat[1][2] * theOther.myMat[2][1];
0407   const Standard_Real aT12 = myMat[1][0] * theOther.myMat[0][2] + myMat[1][1] * theOther.myMat[1][2] + myMat[1][2] * theOther.myMat[2][2];
0408   const Standard_Real aT20 = myMat[2][0] * theOther.myMat[0][0] + myMat[2][1] * theOther.myMat[1][0] + myMat[2][2] * theOther.myMat[2][0];
0409   const Standard_Real aT21 = myMat[2][0] * theOther.myMat[0][1] + myMat[2][1] * theOther.myMat[1][1] + myMat[2][2] * theOther.myMat[2][1];
0410   const Standard_Real aT22 = myMat[2][0] * theOther.myMat[0][2] + myMat[2][1] * theOther.myMat[1][2] + myMat[2][2] * theOther.myMat[2][2];
0411   myMat[0][0] = aT00;
0412   myMat[0][1] = aT01;
0413   myMat[0][2] = aT02;
0414   myMat[1][0] = aT10;
0415   myMat[1][1] = aT11;
0416   myMat[1][2] = aT12;
0417   myMat[2][0] = aT20;
0418   myMat[2][1] = aT21;
0419   myMat[2][2] = aT22;
0420 }
0421 
0422 //=======================================================================
0423 //function : PreMultiply
0424 // purpose :
0425 //=======================================================================
0426 inline void gp_Mat::PreMultiply (const gp_Mat& theOther)
0427 {
0428   const Standard_Real aT00 = theOther.myMat[0][0] * myMat[0][0] + theOther.myMat[0][1] * myMat[1][0] + theOther.myMat[0][2] * myMat[2][0];
0429   const Standard_Real aT01 = theOther.myMat[0][0] * myMat[0][1] + theOther.myMat[0][1] * myMat[1][1] + theOther.myMat[0][2] * myMat[2][1];
0430   const Standard_Real aT02 = theOther.myMat[0][0] * myMat[0][2] + theOther.myMat[0][1] * myMat[1][2] + theOther.myMat[0][2] * myMat[2][2];
0431   const Standard_Real aT10 = theOther.myMat[1][0] * myMat[0][0] + theOther.myMat[1][1] * myMat[1][0] + theOther.myMat[1][2] * myMat[2][0];
0432   const Standard_Real aT11 = theOther.myMat[1][0] * myMat[0][1] + theOther.myMat[1][1] * myMat[1][1] + theOther.myMat[1][2] * myMat[2][1];
0433   const Standard_Real aT12 = theOther.myMat[1][0] * myMat[0][2] + theOther.myMat[1][1] * myMat[1][2] + theOther.myMat[1][2] * myMat[2][2];
0434   const Standard_Real aT20 = theOther.myMat[2][0] * myMat[0][0] + theOther.myMat[2][1] * myMat[1][0] + theOther.myMat[2][2] * myMat[2][0];
0435   const Standard_Real aT21 = theOther.myMat[2][0] * myMat[0][1] + theOther.myMat[2][1] * myMat[1][1] + theOther.myMat[2][2] * myMat[2][1];
0436   const Standard_Real aT22 = theOther.myMat[2][0] * myMat[0][2] + theOther.myMat[2][1] * myMat[1][2] + theOther.myMat[2][2] * myMat[2][2];
0437   myMat[0][0] = aT00;
0438   myMat[0][1] = aT01;
0439   myMat[0][2] = aT02;
0440   myMat[1][0] = aT10;
0441   myMat[1][1] = aT11;
0442   myMat[1][2] = aT12;
0443   myMat[2][0] = aT20;
0444   myMat[2][1] = aT21;
0445   myMat[2][2] = aT22;
0446 }
0447 
0448 //=======================================================================
0449 //function : Multiplied
0450 // purpose :
0451 //=======================================================================
0452 inline gp_Mat gp_Mat::Multiplied (const Standard_Real theScalar) const
0453 {
0454   gp_Mat aNewMat;
0455   aNewMat.myMat[0][0] = theScalar * myMat[0][0];
0456   aNewMat.myMat[0][1] = theScalar * myMat[0][1];
0457   aNewMat.myMat[0][2] = theScalar * myMat[0][2];
0458   aNewMat.myMat[1][0] = theScalar * myMat[1][0];
0459   aNewMat.myMat[1][1] = theScalar * myMat[1][1];
0460   aNewMat.myMat[1][2] = theScalar * myMat[1][2];
0461   aNewMat.myMat[2][0] = theScalar * myMat[2][0];
0462   aNewMat.myMat[2][1] = theScalar * myMat[2][1];
0463   aNewMat.myMat[2][2] = theScalar * myMat[2][2];
0464   return aNewMat;
0465 }
0466 
0467 //=======================================================================
0468 //function : Multiply
0469 // purpose :
0470 //=======================================================================
0471 inline void gp_Mat::Multiply (const Standard_Real theScalar)
0472 {
0473   myMat[0][0] *= theScalar;
0474   myMat[0][1] *= theScalar;
0475   myMat[0][2] *= theScalar;
0476   myMat[1][0] *= theScalar;
0477   myMat[1][1] *= theScalar;
0478   myMat[1][2] *= theScalar;
0479   myMat[2][0] *= theScalar;
0480   myMat[2][1] *= theScalar;
0481   myMat[2][2] *= theScalar;
0482 }
0483 
0484 //=======================================================================
0485 //function : Subtract
0486 // purpose :
0487 //=======================================================================
0488 inline void gp_Mat::Subtract (const gp_Mat& theOther)
0489 {
0490   myMat[0][0] -= theOther.myMat[0][0];
0491   myMat[0][1] -= theOther.myMat[0][1];
0492   myMat[0][2] -= theOther.myMat[0][2];
0493   myMat[1][0] -= theOther.myMat[1][0];
0494   myMat[1][1] -= theOther.myMat[1][1];
0495   myMat[1][2] -= theOther.myMat[1][2];
0496   myMat[2][0] -= theOther.myMat[2][0];
0497   myMat[2][1] -= theOther.myMat[2][1];
0498   myMat[2][2] -= theOther.myMat[2][2];
0499 }
0500 
0501 //=======================================================================
0502 //function : Subtracted
0503 // purpose :
0504 //=======================================================================
0505 inline gp_Mat gp_Mat::Subtracted (const gp_Mat& theOther) const
0506 {
0507   gp_Mat aNewMat;
0508   aNewMat.myMat[0][0] = myMat[0][0] - theOther.myMat[0][0];
0509   aNewMat.myMat[0][1] = myMat[0][1] - theOther.myMat[0][1];
0510   aNewMat.myMat[0][2] = myMat[0][2] - theOther.myMat[0][2];
0511   aNewMat.myMat[1][0] = myMat[1][0] - theOther.myMat[1][0];
0512   aNewMat.myMat[1][1] = myMat[1][1] - theOther.myMat[1][1];
0513   aNewMat.myMat[1][2] = myMat[1][2] - theOther.myMat[1][2];
0514   aNewMat.myMat[2][0] = myMat[2][0] - theOther.myMat[2][0];
0515   aNewMat.myMat[2][1] = myMat[2][1] - theOther.myMat[2][1];
0516   aNewMat.myMat[2][2] = myMat[2][2] - theOther.myMat[2][2];
0517   return aNewMat;
0518 }
0519 
0520 //=======================================================================
0521 //function : Transpose
0522 // purpose :
0523 //=======================================================================
0524 // On macOS 10.13.6 with XCode 9.4.1 the compiler has a bug leading to 
0525 // generation of invalid code when method gp_Mat::Transpose() is called 
0526 // for a matrix which is when applied to vector; it looks like vector
0527 // is transformed before the matrix is actually transposed; see #29978.
0528 // To avoid this, we disable compiler optimization here.
0529 #if defined(__APPLE__) && (__apple_build_version__ > 9020000)
0530 __attribute__((optnone))
0531 #endif
0532 inline void gp_Mat::Transpose()
0533 {
0534   Standard_Real aTemp;
0535   aTemp  = myMat[0][1];
0536   myMat[0][1] = myMat[1][0];
0537   myMat[1][0] = aTemp;
0538   aTemp  = myMat[0][2];
0539   myMat[0][2] = myMat[2][0];
0540   myMat[2][0] = aTemp;
0541   aTemp  = myMat[1][2];
0542   myMat[1][2] = myMat[2][1];
0543   myMat[2][1] = aTemp;
0544 }
0545 
0546 //=======================================================================
0547 //function : operator*
0548 // purpose :
0549 //=======================================================================
0550 inline gp_Mat operator* (const Standard_Real theScalar,
0551                          const gp_Mat& theMat3D)
0552 {
0553   return theMat3D.Multiplied (theScalar);
0554 }
0555 
0556 #endif // _gp_Mat_HeaderFile