2bf880d8b0319281100dd68cbbb2fc177f4383fe
[occt.git] / src / gp / gp_Mat.hxx
1 // Copyright (c) 1991-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _gp_Mat_HeaderFile
16 #define _gp_Mat_HeaderFile
17
18 #include <gp.hxx>
19 #include <Standard_OutOfRange.hxx>
20 #include <Standard_OStream.hxx>
21 #include <Standard_ConstructionError.hxx>
22
23 class gp_XYZ;
24 class gp_Trsf;
25 class gp_GTrsf;
26
27 #define Mat00 matrix[0][0]
28 #define Mat01 matrix[0][1]
29 #define Mat02 matrix[0][2]
30 #define Mat10 matrix[1][0]
31 #define Mat11 matrix[1][1]
32 #define Mat12 matrix[1][2]
33 #define Mat20 matrix[2][0]
34 #define Mat21 matrix[2][1]
35 #define Mat22 matrix[2][2]
36
37 #define Nat00 aNewMat.matrix[0][0]
38 #define Nat01 aNewMat.matrix[0][1]
39 #define Nat02 aNewMat.matrix[0][2]
40 #define Nat10 aNewMat.matrix[1][0]
41 #define Nat11 aNewMat.matrix[1][1]
42 #define Nat12 aNewMat.matrix[1][2]
43 #define Nat20 aNewMat.matrix[2][0]
44 #define Nat21 aNewMat.matrix[2][1]
45 #define Nat22 aNewMat.matrix[2][2]
46
47 #define Oat00 theOther.matrix[0][0]
48 #define Oat01 theOther.matrix[0][1]
49 #define Oat02 theOther.matrix[0][2]
50 #define Oat10 theOther.matrix[1][0]
51 #define Oat11 theOther.matrix[1][1]
52 #define Oat12 theOther.matrix[1][2]
53 #define Oat20 theOther.matrix[2][0]
54 #define Oat21 theOther.matrix[2][1]
55 #define Oat22 theOther.matrix[2][2]
56
57 //! Describes a three column, three row matrix. This sort of
58 //! object is used in various vectorial or matrix computations.
59 class gp_Mat 
60 {
61 public:
62
63   DEFINE_STANDARD_ALLOC
64
65   //! creates  a matrix with null coefficients.
66   gp_Mat()
67   {
68     Mat00 = Mat01 = Mat02 =
69     Mat10 = Mat11 = Mat12 =
70     Mat20 = Mat21 = Mat22 = 0.0;
71   }
72
73   gp_Mat (const Standard_Real theA11, const Standard_Real theA12, const Standard_Real theA13,
74           const Standard_Real theA21, const Standard_Real theA22, const Standard_Real theA23,
75           const Standard_Real theA31, const Standard_Real theA32, const Standard_Real theA33);
76
77   //! Creates a matrix.
78   //! theCol1, theCol2, theCol3 are the 3 columns of the matrix.
79   Standard_EXPORT gp_Mat (const gp_XYZ& theCol1, const gp_XYZ& theCol2, const gp_XYZ& theCol3);
80
81   //! Assigns the three coordinates of theValue to the column of index
82   //! theCol of this matrix.
83   //! Raises OutOfRange if theCol < 1 or theCol > 3.
84   Standard_EXPORT void SetCol (const Standard_Integer theCol, const gp_XYZ& theValue);
85
86   //! Assigns the number triples theCol1, theCol2, theCol3 to the three
87   //! columns of this matrix.
88   Standard_EXPORT void SetCols (const gp_XYZ& theCol1, const gp_XYZ& theCol2, const gp_XYZ& theCol3);
89
90   //! Modifies the matrix  M so that applying it to any number
91   //! triple (X, Y, Z) produces the same result as the cross
92   //! product of theRef and the number triple (X, Y, Z):
93   //! i.e.: M * {X,Y,Z}t = theRef.Cross({X, Y ,Z})
94   //! this matrix is anti symmetric. To apply this matrix to the
95   //! triplet  {XYZ} is the same as to do the cross product between the
96   //! triplet theRef and the triplet {XYZ}.
97   //! Note: this matrix is anti-symmetric.
98   Standard_EXPORT void SetCross (const gp_XYZ& theRef);
99
100   //! Modifies the main diagonal of the matrix.
101   //! @code
102   //! <me>.Value (1, 1) = theX1
103   //! <me>.Value (2, 2) = theX2
104   //! <me>.Value (3, 3) = theX3
105   //! @endcode
106   //! The other coefficients of the matrix are not modified.
107   void SetDiagonal (const Standard_Real theX1, const Standard_Real theX2, const Standard_Real theX3)
108   {
109     Mat00 = theX1;
110     Mat11 = theX2;
111     Mat22 = theX3;
112   }
113
114   //! Modifies this matrix so that applying it to any number
115   //! triple (X, Y, Z) produces the same result as the scalar
116   //! product of theRef and the number triple (X, Y, Z):
117   //! this * (X,Y,Z) = theRef.(X,Y,Z)
118   //! Note: this matrix is symmetric.
119   Standard_EXPORT void SetDot (const gp_XYZ& theRef);
120
121   //! Modifies this matrix so that it represents the Identity matrix.
122   void SetIdentity()
123   {
124     Mat00 = Mat11 = Mat22 = 1.0;
125     Mat01 = Mat02 = Mat10 = Mat12 = Mat20 = Mat21 = 0.0;
126   }
127
128   //! Modifies this matrix so that it represents a rotation. theAng is the angular value in
129   //! radians and the XYZ axis gives the direction of the
130   //! rotation.
131   //! Raises ConstructionError if XYZ.Modulus() <= Resolution()
132   Standard_EXPORT void SetRotation (const gp_XYZ& theAxis, const Standard_Real theAng);
133
134   //! Assigns the three coordinates of Value to the row of index
135   //! theRow of this matrix. Raises OutOfRange if theRow < 1 or theRow > 3.
136   Standard_EXPORT void SetRow (const Standard_Integer theRow, const gp_XYZ& theValue);
137
138   //! Assigns the number triples theRow1, theRow2, theRow3 to the three
139   //! rows of this matrix.
140   Standard_EXPORT void SetRows (const gp_XYZ& theRow1, const gp_XYZ& theRow2, const gp_XYZ& theRow3);
141
142   //! Modifies the matrix so that it represents
143   //! a scaling transformation, where theS is the scale factor. :
144   //! @code
145   //!         | theS    0.0  0.0 |
146   //! <me> =  | 0.0   theS   0.0 |
147   //!         | 0.0  0.0   theS  |
148   //! @endcode
149   void SetScale (const Standard_Real theS)
150   {
151     Mat00 = Mat11 = Mat22 = theS;
152     Mat01 = Mat02 = Mat10 = Mat12 = Mat20 = Mat21 = 0.0;
153   }
154
155   //! Assigns <theValue> to the coefficient of row theRow, column theCol of   this matrix.
156   //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 3
157   void SetValue (const Standard_Integer theRow, const Standard_Integer theCol, const Standard_Real theValue)
158   {
159     Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 3, " ");
160     matrix[theRow - 1][theCol - 1] = theValue;
161   }
162
163   //! Returns the column of theCol index.
164   //! Raises OutOfRange if theCol < 1 or theCol > 3
165   Standard_EXPORT gp_XYZ Column (const Standard_Integer theCol) const;
166
167   //! Computes the determinant of the matrix.
168   Standard_Real Determinant() const
169   {
170     return Mat00 * (Mat11 * Mat22 - Mat21 * Mat12) -
171            Mat01 * (Mat10 * Mat22 - Mat20 * Mat12) +
172            Mat02 * (Mat10 * Mat21 - Mat20 * Mat11);
173   }
174
175   //! Returns the main diagonal of the matrix.
176   Standard_EXPORT gp_XYZ Diagonal() const;
177
178   //! returns the row of theRow index.
179   //! Raises OutOfRange if theRow < 1 or theRow > 3
180   Standard_EXPORT gp_XYZ Row (const Standard_Integer theRow) const;
181
182   //! Returns the coefficient of range (theRow, theCol)
183   //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 3
184   const Standard_Real& Value (const Standard_Integer theRow, const Standard_Integer theCol) const
185   {
186     Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 3, " ");
187     return matrix[theRow - 1][theCol - 1];
188   }
189
190   const Standard_Real& operator() (const Standard_Integer theRow, const Standard_Integer theCol) const { return Value (theRow, theCol); }
191
192   //! Returns the coefficient of range (theRow, theCol)
193   //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 3
194   Standard_Real& ChangeValue (const Standard_Integer theRow, const Standard_Integer theCol)
195   {
196     Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 3, " ");
197     return matrix[theRow - 1][theCol - 1];
198   }
199
200   Standard_Real& operator() (const Standard_Integer theRow, const Standard_Integer theCol) { return ChangeValue (theRow, theCol); }
201
202   //! The Gauss LU decomposition is used to invert the matrix
203   //! (see Math package) so the matrix is considered as singular if
204   //! the largest pivot found is lower or equal to Resolution from gp.
205   Standard_Boolean IsSingular() const
206   {
207     // Pour etre sur que Gauss va fonctionner, il faut faire Gauss ...
208     Standard_Real aVal = Determinant();
209     if (aVal < 0)
210     {
211       aVal = -aVal;
212     }
213     return aVal <= gp::Resolution();
214   }
215
216   void Add (const gp_Mat& theOther);
217
218   void operator += (const gp_Mat& theOther) { Add (theOther); }
219
220   //! Computes the sum of this matrix and
221   //! the matrix theOther for each coefficient of the matrix :
222   //! <me>.Coef(i,j) + <theOther>.Coef(i,j)
223   Standard_NODISCARD gp_Mat Added (const gp_Mat& theOther) const;
224
225   Standard_NODISCARD gp_Mat operator + (const gp_Mat& theOther) const { return Added (theOther); }
226
227   void Divide (const Standard_Real theScalar);
228
229   void operator /= (const Standard_Real theScalar) { Divide (theScalar); }
230
231   //! Divides all the coefficients of the matrix by Scalar
232   Standard_NODISCARD gp_Mat Divided (const Standard_Real theScalar) const;
233
234   Standard_NODISCARD gp_Mat operator / (const Standard_Real theScalar) const { return Divided (theScalar); }
235
236   Standard_EXPORT void Invert();
237
238   //! Inverses the matrix and raises if the matrix is singular.
239   //! -   Invert assigns the result to this matrix, while
240   //! -   Inverted creates a new one.
241   //! Warning
242   //! The Gauss LU decomposition is used to invert the matrix.
243   //! Consequently, the matrix is considered as singular if the
244   //! largest pivot found is less than or equal to gp::Resolution().
245   //! Exceptions
246   //! Standard_ConstructionError if this matrix is singular,
247   //! and therefore cannot be inverted.
248   Standard_NODISCARD Standard_EXPORT gp_Mat Inverted() const;
249
250   //! Computes  the product of two matrices <me> * <Other>
251   Standard_NODISCARD gp_Mat Multiplied (const gp_Mat& theOther) const
252   {
253     gp_Mat aNewMat = *this;
254     aNewMat.Multiply (theOther);
255     return aNewMat;
256   }
257
258   Standard_NODISCARD gp_Mat operator * (const gp_Mat& theOther) const { return Multiplied (theOther); }
259
260   //! Computes the product of two matrices <me> = <Other> * <me>.
261   void Multiply (const gp_Mat& theOther);
262
263   void operator *= (const gp_Mat& theOther) { Multiply (theOther); }
264
265   void PreMultiply (const gp_Mat& theOther);
266
267   Standard_NODISCARD gp_Mat Multiplied (const Standard_Real theScalar) const;
268
269   Standard_NODISCARD gp_Mat operator * (const Standard_Real theScalar) const { return Multiplied (theScalar); }
270
271   //! Multiplies all the coefficients of the matrix by Scalar
272   void Multiply (const Standard_Real theScalar);
273
274   void operator *= (const Standard_Real theScalar) { Multiply (theScalar); }
275
276   Standard_EXPORT void Power (const Standard_Integer N);
277
278   //! Computes <me> = <me> * <me> * .......* <me>,   theN time.
279   //! if theN = 0 <me> = Identity
280   //! if theN < 0 <me> = <me>.Invert() *...........* <me>.Invert().
281   //! If theN < 0 an exception will be raised if the matrix is not
282   //! inversible
283   Standard_NODISCARD gp_Mat Powered (const Standard_Integer theN) const
284   {
285     gp_Mat aMatN = *this;
286     aMatN.Power (theN);
287     return aMatN;
288   }
289
290   void Subtract (const gp_Mat& theOther);
291
292   void operator -= (const gp_Mat& theOther) { Subtract (theOther); }
293
294   //! cOmputes for each coefficient of the matrix :
295   //! <me>.Coef(i,j) - <theOther>.Coef(i,j)
296   Standard_NODISCARD gp_Mat Subtracted (const gp_Mat& theOther) const;
297
298   Standard_NODISCARD gp_Mat operator - (const gp_Mat& theOther) const { return Subtracted (theOther); }
299
300   void Transpose();
301
302   //! Transposes the matrix. A(j, i) -> A (i, j)
303   Standard_NODISCARD gp_Mat Transposed() const
304   {
305     gp_Mat aNewMat = *this;
306     aNewMat.Transpose();
307     return aNewMat;
308   }
309
310   //! Dumps the content of me into the stream
311   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
312
313 friend class gp_XYZ;
314 friend class gp_Trsf;
315 friend class gp_GTrsf;
316
317 private:
318
319   Standard_Real matrix[3][3];
320
321 };
322
323 //=======================================================================
324 //function : gp_Mat
325 // purpose :
326 //=======================================================================
327 inline gp_Mat::gp_Mat (const Standard_Real theA11, const Standard_Real theA12, const Standard_Real theA13,
328                        const Standard_Real theA21, const Standard_Real theA22, const Standard_Real theA23,
329                        const Standard_Real theA31, const Standard_Real theA32, const Standard_Real theA33)
330   {
331     Mat00 = theA11;
332     Mat01 = theA12;
333     Mat02 = theA13;
334     Mat10 = theA21;
335     Mat11 = theA22;
336     Mat12 = theA23;
337     Mat20 = theA31;
338     Mat21 = theA32;
339     Mat22 = theA33;
340   }
341
342 //=======================================================================
343 //function : Add
344 // purpose :
345 //=======================================================================
346 inline void gp_Mat::Add (const gp_Mat& theOther)
347 {
348   Mat00 = Mat00 + Oat00;
349   Mat01 = Mat01 + Oat01;
350   Mat02 = Mat02 + Oat02;
351   Mat10 = Mat10 + Oat10;
352   Mat11 = Mat11 + Oat11;
353   Mat12 = Mat12 + Oat12;
354   Mat20 = Mat20 + Oat20;
355   Mat21 = Mat21 + Oat21;
356   Mat22 = Mat22 + Oat22;
357 }
358
359 //=======================================================================
360 //function : Added
361 // purpose :
362 //=======================================================================
363 inline gp_Mat gp_Mat::Added (const gp_Mat& theOther) const
364 {
365   gp_Mat aNewMat;
366   Nat00 = Mat00 + Oat00;
367   Nat01 = Mat01 + Oat01;
368   Nat02 = Mat02 + Oat02;
369   Nat10 = Mat10 + Oat10;
370   Nat11 = Mat11 + Oat11;
371   Nat12 = Mat12 + Oat12;
372   Nat20 = Mat20 + Oat20;
373   Nat21 = Mat21 + Oat21;
374   Nat22 = Mat22 + Oat22;
375   return aNewMat;
376 }
377
378 //=======================================================================
379 //function : Divide
380 // purpose :
381 //=======================================================================
382 inline void gp_Mat::Divide (const Standard_Real theScalar)
383 {
384   Standard_Real aVal = theScalar;
385   if (aVal < 0)
386   {
387     aVal = -aVal;
388   }
389   Standard_ConstructionError_Raise_if (aVal <= gp::Resolution(),"gp_Mat : Divide by 0");
390   Standard_Real anUnSurScalar = 1.0 / theScalar;
391   Mat00 *= anUnSurScalar;
392   Mat01 *= anUnSurScalar;
393   Mat02 *= anUnSurScalar;
394   Mat10 *= anUnSurScalar;
395   Mat11 *= anUnSurScalar;
396   Mat12 *= anUnSurScalar;
397   Mat20 *= anUnSurScalar;
398   Mat21 *= anUnSurScalar;
399   Mat22 *= anUnSurScalar;
400 }
401
402 //=======================================================================
403 //function : Divided
404 // purpose :
405 //=======================================================================
406 inline gp_Mat gp_Mat::Divided (const Standard_Real theScalar) const
407 {
408   Standard_Real aVal = theScalar;
409   if (aVal < 0)
410   {
411     aVal = -aVal;
412   }
413   Standard_ConstructionError_Raise_if (aVal <= gp::Resolution(),"gp_Mat : Divide by 0");
414   gp_Mat aNewMat;
415   Standard_Real anUnSurScalar = 1.0 / theScalar;
416   Nat00 = Mat00 * anUnSurScalar;
417   Nat01 = Mat01 * anUnSurScalar;
418   Nat02 = Mat02 * anUnSurScalar;
419   Nat10 = Mat10 * anUnSurScalar;
420   Nat11 = Mat11 * anUnSurScalar;
421   Nat12 = Mat12 * anUnSurScalar;
422   Nat20 = Mat20 * anUnSurScalar;
423   Nat21 = Mat21 * anUnSurScalar;
424   Nat22 = Mat22 * anUnSurScalar;
425   return aNewMat;
426 }
427
428 //=======================================================================
429 //function : Multiply
430 // purpose :
431 //=======================================================================
432 inline void gp_Mat::Multiply (const gp_Mat& theOther)
433 {
434   Standard_Real aT00, aT01, aT02, aT10, aT11, aT12, aT20, aT21, aT22;
435   aT00 = Mat00 * Oat00 + Mat01 * Oat10 + Mat02 * Oat20;
436   aT01 = Mat00 * Oat01 + Mat01 * Oat11 + Mat02 * Oat21;
437   aT02 = Mat00 * Oat02 + Mat01 * Oat12 + Mat02 * Oat22;
438   aT10 = Mat10 * Oat00 + Mat11 * Oat10 + Mat12 * Oat20;
439   aT11 = Mat10 * Oat01 + Mat11 * Oat11 + Mat12 * Oat21;
440   aT12 = Mat10 * Oat02 + Mat11 * Oat12 + Mat12 * Oat22;
441   aT20 = Mat20 * Oat00 + Mat21 * Oat10 + Mat22 * Oat20;
442   aT21 = Mat20 * Oat01 + Mat21 * Oat11 + Mat22 * Oat21;
443   aT22 = Mat20 * Oat02 + Mat21 * Oat12 + Mat22 * Oat22;
444   Mat00 = aT00;
445   Mat01 = aT01;
446   Mat02 = aT02;
447   Mat10 = aT10;
448   Mat11 = aT11;
449   Mat12 = aT12;
450   Mat20 = aT20;
451   Mat21 = aT21;
452   Mat22 = aT22;
453 }
454
455 //=======================================================================
456 //function : PreMultiply
457 // purpose :
458 //=======================================================================
459 inline void gp_Mat::PreMultiply (const gp_Mat& theOther)
460 {
461   Standard_Real aT00, aT01, aT02, aT10, aT11, aT12, aT20, aT21, aT22;
462   aT00 = Oat00 * Mat00 + Oat01 * Mat10 + Oat02 * Mat20;
463   aT01 = Oat00 * Mat01 + Oat01 * Mat11 + Oat02 * Mat21;
464   aT02 = Oat00 * Mat02 + Oat01 * Mat12 + Oat02 * Mat22;
465   aT10 = Oat10 * Mat00 + Oat11 * Mat10 + Oat12 * Mat20;
466   aT11 = Oat10 * Mat01 + Oat11 * Mat11 + Oat12 * Mat21;
467   aT12 = Oat10 * Mat02 + Oat11 * Mat12 + Oat12 * Mat22;
468   aT20 = Oat20 * Mat00 + Oat21 * Mat10 + Oat22 * Mat20;
469   aT21 = Oat20 * Mat01 + Oat21 * Mat11 + Oat22 * Mat21;
470   aT22 = Oat20 * Mat02 + Oat21 * Mat12 + Oat22 * Mat22;
471   Mat00 = aT00;
472   Mat01 = aT01;
473   Mat02 = aT02;
474   Mat10 = aT10;
475   Mat11 = aT11;
476   Mat12 = aT12;
477   Mat20 = aT20;
478   Mat21 = aT21;
479   Mat22 = aT22;
480 }
481
482 //=======================================================================
483 //function : Multiplied
484 // purpose :
485 //=======================================================================
486 inline gp_Mat gp_Mat::Multiplied (const Standard_Real theScalar) const
487 {
488   gp_Mat aNewMat;
489   Nat00 = theScalar * Mat00;
490   Nat01 = theScalar * Mat01;
491   Nat02 = theScalar * Mat02;
492   Nat10 = theScalar * Mat10;
493   Nat11 = theScalar * Mat11;
494   Nat12 = theScalar * Mat12;
495   Nat20 = theScalar * Mat20;
496   Nat21 = theScalar * Mat21;
497   Nat22 = theScalar * Mat22;
498   return aNewMat;
499 }
500
501 //=======================================================================
502 //function : Multiply
503 // purpose :
504 //=======================================================================
505 inline void gp_Mat::Multiply (const Standard_Real theScalar)
506 {
507   Mat00 *= theScalar;
508   Mat01 *= theScalar;
509   Mat02 *= theScalar;
510   Mat10 *= theScalar;
511   Mat11 *= theScalar;
512   Mat12 *= theScalar;
513   Mat20 *= theScalar;
514   Mat21 *= theScalar;
515   Mat22 *= theScalar;
516 }
517
518 //=======================================================================
519 //function : Subtract
520 // purpose :
521 //=======================================================================
522 inline void gp_Mat::Subtract (const gp_Mat& theOther)
523 {
524   Mat00 -= Oat00;
525   Mat01 -= Oat01;
526   Mat02 -= Oat02;
527   Mat10 -= Oat10;
528   Mat11 -= Oat11;
529   Mat12 -= Oat12;
530   Mat20 -= Oat20;
531   Mat21 -= Oat21;
532   Mat22 -= Oat22;
533 }
534
535 //=======================================================================
536 //function : Subtracted
537 // purpose :
538 //=======================================================================
539 inline gp_Mat gp_Mat::Subtracted (const gp_Mat& theOther) const
540 {
541   gp_Mat aNewMat;
542   Nat00 = Mat00 - Oat00;
543   Nat01 = Mat01 - Oat01;
544   Nat02 = Mat02 - Oat02;
545   Nat10 = Mat10 - Oat10;
546   Nat11 = Mat11 - Oat11;
547   Nat12 = Mat12 - Oat12;
548   Nat20 = Mat20 - Oat20;
549   Nat21 = Mat21 - Oat21;
550   Nat22 = Mat22 - Oat22;
551   return aNewMat;
552 }
553
554 //=======================================================================
555 //function : Transpose
556 // purpose :
557 //=======================================================================
558 // On macOS 10.13.6 with XCode 9.4.1 the compiler has a bug leading to 
559 // generation of invalid code when method gp_Mat::Transpose() is called 
560 // for a matrix which is when applied to vector; it looks like vector
561 // is transformed before the matrix is actually transposed; see #29978.
562 // To avoid this, we disable compiler optimization here.
563 #if defined(__APPLE__) && (__apple_build_version__ > 9020000)
564 __attribute__((optnone))
565 #endif
566 inline void gp_Mat::Transpose()
567 {
568   Standard_Real aTemp;
569   aTemp  = Mat01;
570   Mat01  = Mat10;
571   Mat10  = aTemp;
572   aTemp  = Mat02;
573   Mat02  = Mat20;
574   Mat20  = aTemp;
575   aTemp  = Mat12;
576   Mat12  = Mat21;
577   Mat21  = aTemp;
578 }
579
580 //=======================================================================
581 //function : operator*
582 // purpose :
583 //=======================================================================
584 inline gp_Mat operator* (const Standard_Real theScalar,
585                          const gp_Mat& theMat3D)
586 {
587   return theMat3D.Multiplied (theScalar);
588 }
589
590 #endif // _gp_Mat_HeaderFile