0032137: Coding Rules - merge redundant .lxx files into header files within Package gp
[occt.git] / src / gp / gp_Trsf.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_Trsf_HeaderFile
16 #define _gp_Trsf_HeaderFile
17
18 #include <gp_TrsfForm.hxx>
19 #include <gp_Mat.hxx>
20 #include <gp_XYZ.hxx>
21 #include <NCollection_Mat4.hxx>
22 #include <Standard_ConstructionError.hxx>
23 #include <Standard_OStream.hxx>
24 #include <Standard_OutOfRange.hxx>
25 #include <Standard_SStream.hxx>
26
27 class gp_Pnt;
28 class gp_Trsf2d;
29 class gp_Ax1;
30 class gp_Ax2;
31 class gp_Quaternion;
32 class gp_Ax3;
33 class gp_Vec;
34
35 // Avoid possible conflict with SetForm macro defined by windows.h
36 #ifdef SetForm
37 #undef SetForm
38 #endif
39
40 //! Defines a non-persistent transformation in 3D space.
41 //! The following transformations are implemented :
42 //! . Translation, Rotation, Scale
43 //! . Symmetry with respect to a point, a line, a plane.
44 //! Complex transformations can be obtained by combining the
45 //! previous elementary transformations using the method
46 //! Multiply.
47 //! The transformations can be represented as follow :
48 //! @code
49 //!    V1   V2   V3    T       XYZ        XYZ
50 //! | a11  a12  a13   a14 |   | x |      | x'|
51 //! | a21  a22  a23   a24 |   | y |      | y'|
52 //! | a31  a32  a33   a34 |   | z |   =  | z'|
53 //! |  0    0    0     1  |   | 1 |      | 1 |
54 //! @endcode
55 //! where {V1, V2, V3} defines the vectorial part of the
56 //! transformation and T defines the translation part of the
57 //! transformation.
58 //! This transformation never change the nature of the objects.
59 class gp_Trsf 
60 {
61 public:
62
63   DEFINE_STANDARD_ALLOC
64
65   //! Returns the identity transformation.
66   gp_Trsf();
67
68   //! Creates  a 3D transformation from the 2D transformation theT.
69   //! The resulting transformation has a homogeneous
70   //! vectorial part, V3, and a translation part, T3, built from theT:
71   //! a11    a12
72   //! 0             a13
73   //! V3 =    a21    a22    0       T3
74   //! =   a23
75   //! 0    0    1.
76   //! 0
77   //! It also has the same scale factor as theT. This
78   //! guarantees (by projection) that the transformation
79   //! which would be performed by theT in a plane (2D space)
80   //! is performed by the resulting transformation in the xOy
81   //! plane of the 3D space, (i.e. in the plane defined by the
82   //! origin (0., 0., 0.) and the vectors DX (1., 0., 0.), and DY
83   //! (0., 1., 0.)). The scale factor is applied to the entire space.
84   Standard_EXPORT gp_Trsf (const gp_Trsf2d& theT);
85
86   //! Makes the transformation into a symmetrical transformation.
87   //! theP is the center of the symmetry.
88   void SetMirror (const gp_Pnt& theP);
89
90   //! Makes the transformation into a symmetrical transformation.
91   //! theA1 is the center of the axial symmetry.
92   Standard_EXPORT void SetMirror (const gp_Ax1& theA1);
93
94   //! Makes the transformation into a symmetrical transformation.
95   //! theA2 is the center of the planar symmetry
96   //! and defines the plane of symmetry by its origin, "X
97   //! Direction" and "Y Direction".
98   Standard_EXPORT void SetMirror (const gp_Ax2& theA2);
99
100   //! Changes the transformation into a rotation.
101   //! theA1 is the rotation axis and theAng is the angular value of the
102   //! rotation in radians.
103   Standard_EXPORT void SetRotation (const gp_Ax1& theA1, const Standard_Real theAng);
104
105   //! Changes the transformation into a rotation defined by quaternion.
106   //! Note that rotation is performed around origin, i.e.
107   //! no translation is involved.
108   Standard_EXPORT void SetRotation (const gp_Quaternion& theR);
109
110   //! Replaces the rotation part with specified quaternion.
111   Standard_EXPORT void SetRotationPart (const gp_Quaternion& theR);
112
113   //! Changes the transformation into a scale.
114   //! theP is the center of the scale and theS is the scaling value.
115   //! Raises ConstructionError  If <theS> is null.
116   Standard_EXPORT void SetScale (const gp_Pnt& theP, const Standard_Real theS);
117
118   //! Modifies this transformation so that it transforms the
119   //! coordinate system defined by theFromSystem1 into the
120   //! one defined by theToSystem2. After this modification, this
121   //! transformation transforms:
122   //! -   the origin of theFromSystem1 into the origin of theToSystem2,
123   //! -   the "X Direction" of theFromSystem1 into the "X
124   //! Direction" of theToSystem2,
125   //! -   the "Y Direction" of theFromSystem1 into the "Y
126   //! Direction" of theToSystem2, and
127   //! -   the "main Direction" of theFromSystem1 into the "main
128   //! Direction" of theToSystem2.
129   //! Warning
130   //! When you know the coordinates of a point in one
131   //! coordinate system and you want to express these
132   //! coordinates in another one, do not use the
133   //! transformation resulting from this function. Use the
134   //! transformation that results from SetTransformation instead.
135   //! SetDisplacement and SetTransformation create
136   //! related transformations: the vectorial part of one is the
137   //! inverse of the vectorial part of the other.
138   Standard_EXPORT void SetDisplacement (const gp_Ax3& theFromSystem1, const gp_Ax3& theToSystem2);
139
140   //! Modifies this transformation so that it transforms the
141   //! coordinates of any point, (x, y, z), relative to a source
142   //! coordinate system into the coordinates (x', y', z') which
143   //! are relative to a target coordinate system, but which
144   //! represent the same point
145   //! The transformation is from the coordinate
146   //! system "theFromSystem1" to the coordinate system "theToSystem2".
147   //! Example :
148   //! @code
149   //! gp_Ax3 theFromSystem1, theToSystem2;
150   //! double x1, y1, z1;  // are the coordinates of a point in the local system theFromSystem1
151   //! double x2, y2, z2;  // are the coordinates of a point in the local system theToSystem2
152   //! gp_Pnt P1 (x1, y1, z1)
153   //! gp_Trsf T;
154   //! T.SetTransformation (theFromSystem1, theToSystem2);
155   //! gp_Pnt P2 = P1.Transformed (T);
156   //! P2.Coord (x2, y2, z2);
157   //! @endcode
158   Standard_EXPORT void SetTransformation (const gp_Ax3& theFromSystem1, const gp_Ax3& theToSystem2);
159
160   //! Modifies this transformation so that it transforms the
161   //! coordinates of any point, (x, y, z), relative to a source
162   //! coordinate system into the coordinates (x', y', z') which
163   //! are relative to a target coordinate system, but which
164   //! represent the same point
165   //! The transformation is from the default coordinate system
166   //! @code
167   //! {P(0.,0.,0.), VX (1.,0.,0.), VY (0.,1.,0.), VZ (0., 0. ,1.) }
168   //! @endcode
169   //! to the local coordinate system defined with the Ax3 theToSystem.
170   //! Use in the same way  as the previous method. FromSystem1 is
171   //! defaulted to the absolute coordinate system.
172   Standard_EXPORT void SetTransformation (const gp_Ax3& theToSystem);
173
174   //! Sets transformation by directly specified rotation and translation.
175   Standard_EXPORT void SetTransformation (const gp_Quaternion& R, const gp_Vec& theT);
176
177   //! Changes the transformation into a translation.
178   //! theV is the vector of the translation.
179   void SetTranslation (const gp_Vec& theV);
180
181   //! Makes the transformation into a translation where the translation vector
182   //! is the vector (theP1, theP2) defined from point theP1 to point theP2.
183   void SetTranslation (const gp_Pnt& theP1, const gp_Pnt& theP2);
184
185   //! Replaces the translation vector with the vector theV.
186   Standard_EXPORT void SetTranslationPart (const gp_Vec& theV);
187
188   //! Modifies the scale factor.
189   //! Raises ConstructionError  If theS is null.
190   Standard_EXPORT void SetScaleFactor (const Standard_Real theS);
191
192   void SetForm (const gp_TrsfForm theP) { shape = theP; }
193
194   //! Sets the coefficients  of the transformation.  The
195   //! transformation  of the  point  x,y,z is  the point
196   //! x',y',z' with :
197   //! @code
198   //! x' = a11 x + a12 y + a13 z + a14
199   //! y' = a21 x + a22 y + a23 z + a24
200   //! z' = a31 x + a32 y + a33 z + a34
201   //! @endcode
202   //! The method Value(i,j) will return aij.
203   //! Raises ConstructionError if the determinant of  the aij is null.
204   //! The matrix is orthogonalized before future using.
205   Standard_EXPORT void SetValues (const Standard_Real a11, const Standard_Real a12, const Standard_Real a13, const Standard_Real a14, const Standard_Real a21, const Standard_Real a22, const Standard_Real a23, const Standard_Real a24, const Standard_Real a31, const Standard_Real a32, const Standard_Real a33, const Standard_Real a34);
206
207   //! Returns true if the determinant of the vectorial part of
208   //! this transformation is negative.
209   Standard_Boolean IsNegative() const { return (scale < 0.0); }
210
211   //! Returns the nature of the transformation. It can be: an
212   //! identity transformation, a rotation, a translation, a mirror
213   //! transformation (relative to a point, an axis or a plane), a
214   //! scaling transformation, or a compound transformation.
215   gp_TrsfForm Form() const { return shape; }
216
217   //! Returns the scale factor.
218   Standard_Real ScaleFactor() const { return scale; }
219
220   //! Returns the translation part of the transformation's matrix
221   const gp_XYZ& TranslationPart() const { return loc; }
222
223   //! Returns the boolean True if there is non-zero rotation.
224   //! In the presence of rotation, the output parameters store the axis
225   //! and the angle of rotation. The method always returns positive
226   //! value "theAngle", i.e., 0. < theAngle <= PI.
227   //! Note that this rotation is defined only by the vectorial part of
228   //! the transformation; generally you would need to check also the
229   //! translational part to obtain the axis (gp_Ax1) of rotation.
230   Standard_EXPORT Standard_Boolean GetRotation (gp_XYZ& theAxis, Standard_Real& theAngle) const;
231
232   //! Returns quaternion representing rotational part of the transformation.
233   Standard_EXPORT gp_Quaternion GetRotation() const;
234
235   //! Returns the vectorial part of the transformation. It is
236   //! a 3*3 matrix which includes the scale factor.
237   Standard_EXPORT gp_Mat VectorialPart() const;
238
239   //! Computes the homogeneous vectorial part of the transformation.
240   //! It is a 3*3 matrix which doesn't include the scale factor.
241   //! In other words, the vectorial part of this transformation is equal
242   //! to its homogeneous vectorial part, multiplied by the scale factor.
243   //! The coefficients of this matrix must be multiplied by the
244   //! scale factor to obtain the coefficients of the transformation.
245   const gp_Mat& HVectorialPart() const { return matrix; }
246
247   //! Returns the coefficients of the transformation's matrix.
248   //! It is a 3 rows * 4 columns matrix.
249   //! This coefficient includes the scale factor.
250   //! Raises OutOfRanged if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 4
251   Standard_Real Value (const Standard_Integer theRow, const Standard_Integer theCol) const;
252
253   Standard_EXPORT void Invert();
254
255   //! Computes the reverse transformation
256   //! Raises an exception if the matrix of the transformation
257   //! is not inversible, it means that the scale factor is lower
258   //! or equal to Resolution from package gp.
259   //! Computes the transformation composed with T and  <me>.
260   //! In a C++ implementation you can also write Tcomposed = <me> * T.
261   //! Example :
262   //! @code
263   //! gp_Trsf T1, T2, Tcomp; ...............
264   //! Tcomp = T2.Multiplied(T1);         // or   (Tcomp = T2 * T1)
265   //! gp_Pnt P1(10.,3.,4.);
266   //! gp_Pnt P2 = P1.Transformed(Tcomp); // using Tcomp
267   //! gp_Pnt P3 = P1.Transformed(T1);    // using T1 then T2
268   //! P3.Transform(T2);                  // P3 = P2 !!!
269   //! @endcode
270   Standard_NODISCARD gp_Trsf Inverted() const
271   {
272     gp_Trsf aT = *this;
273     aT.Invert();
274     return aT;
275   }
276   
277   Standard_NODISCARD gp_Trsf Multiplied (const gp_Trsf& theT) const
278   {
279     gp_Trsf aTresult (*this);
280     aTresult.Multiply (theT);
281     return aTresult;
282   }
283
284   Standard_NODISCARD gp_Trsf operator * (const gp_Trsf& theT) const { return Multiplied (theT); }
285
286   //! Computes the transformation composed with <me> and theT.
287   //! <me> = <me> * theT
288   Standard_EXPORT void Multiply (const gp_Trsf& theT);
289
290   void operator *= (const gp_Trsf& theT) { Multiply (theT); }
291
292   //! Computes the transformation composed with <me> and T.
293   //! <me> = theT * <me>
294   Standard_EXPORT void PreMultiply (const gp_Trsf& theT);
295
296   Standard_EXPORT void Power (const Standard_Integer theN);
297
298   //! Computes the following composition of transformations
299   //! <me> * <me> * .......* <me>, theN time.
300   //! if theN = 0 <me> = Identity
301   //! if theN < 0 <me> = <me>.Inverse() *...........* <me>.Inverse().
302   //!
303   //! Raises if theN < 0 and if the matrix of the transformation not
304   //! inversible.
305   Standard_NODISCARD gp_Trsf Powered (const Standard_Integer theN) const
306   {
307     gp_Trsf aT = *this;
308     aT.Power (theN);
309     return aT;
310   }
311
312   void Transforms (Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const;
313
314   //! Transformation of a triplet XYZ with a Trsf
315   void Transforms (gp_XYZ& theCoord) const;
316
317   //! Convert transformation to 4x4 matrix.
318   template<class T>
319   void GetMat4 (NCollection_Mat4<T>& theMat) const
320   {
321     if (shape == gp_Identity)
322     {
323       theMat.InitIdentity();
324       return;
325     }
326
327     theMat.SetValue (0, 0, static_cast<T> (Value (1, 1)));
328     theMat.SetValue (0, 1, static_cast<T> (Value (1, 2)));
329     theMat.SetValue (0, 2, static_cast<T> (Value (1, 3)));
330     theMat.SetValue (0, 3, static_cast<T> (Value (1, 4)));
331     theMat.SetValue (1, 0, static_cast<T> (Value (2, 1)));
332     theMat.SetValue (1, 1, static_cast<T> (Value (2, 2)));
333     theMat.SetValue (1, 2, static_cast<T> (Value (2, 3)));
334     theMat.SetValue (1, 3, static_cast<T> (Value (2, 4)));
335     theMat.SetValue (2, 0, static_cast<T> (Value (3, 1)));
336     theMat.SetValue (2, 1, static_cast<T> (Value (3, 2)));
337     theMat.SetValue (2, 2, static_cast<T> (Value (3, 3)));
338     theMat.SetValue (2, 3, static_cast<T> (Value (3, 4)));
339     theMat.SetValue (3, 0, static_cast<T> (0));
340     theMat.SetValue (3, 1, static_cast<T> (0));
341     theMat.SetValue (3, 2, static_cast<T> (0));
342     theMat.SetValue (3, 3, static_cast<T> (1));
343   }
344
345   //! Dumps the content of me into the stream
346   Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
347
348   //! Inits the content of me from the stream
349   Standard_EXPORT Standard_Boolean InitFromJson (const Standard_SStream& theSStream, Standard_Integer& theStreamPos);
350
351 friend class gp_GTrsf;
352
353 protected:
354
355   //! Makes orthogonalization of "matrix"
356   Standard_EXPORT void Orthogonalize();
357
358 private:
359
360   Standard_Real scale;
361   gp_TrsfForm shape;
362   gp_Mat matrix;
363   gp_XYZ loc;
364
365 };
366
367 #include <gp_Trsf2d.hxx>
368 #include <gp_Vec.hxx>
369 #include <gp_Pnt.hxx>
370
371 //=======================================================================
372 //function : gp_Trsf
373 // purpose :
374 //=======================================================================
375 inline gp_Trsf::gp_Trsf ()
376 : scale (1.0),
377   shape (gp_Identity),
378   matrix (1, 0, 0, 0, 1, 0, 0, 0, 1),
379   loc (0.0, 0.0, 0.0)
380 {}
381
382 //=======================================================================
383 //function : SetMirror
384 // purpose :
385 //=======================================================================
386 inline void gp_Trsf::SetMirror (const gp_Pnt& theP)
387 {
388   shape = gp_PntMirror;
389   scale = -1.0;
390   loc = theP.XYZ();
391   matrix.SetIdentity();
392   loc.Multiply (2.0);
393 }
394
395 //=======================================================================
396 //function : SetTranslation
397 // purpose :
398 //=======================================================================
399 inline void gp_Trsf::SetTranslation (const gp_Vec& theV) 
400 {
401   shape = gp_Translation;
402   scale = 1.;
403   matrix.SetIdentity();
404   loc = theV.XYZ();
405 }
406
407 //=======================================================================
408 //function : SetTranslation
409 // purpose :
410 //=======================================================================
411 inline void gp_Trsf::SetTranslation (const gp_Pnt& theP1,
412                                      const gp_Pnt& theP2) 
413 {
414   shape = gp_Translation;
415   scale = 1.0;
416   matrix.SetIdentity();
417   loc = (theP2.XYZ()).Subtracted (theP1.XYZ());
418 }
419
420 //=======================================================================
421 //function : Value
422 // purpose :
423 //=======================================================================
424 inline Standard_Real gp_Trsf::Value (const Standard_Integer theRow, const Standard_Integer theCol) const
425 {
426   Standard_OutOfRange_Raise_if (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 4, " ");
427   if (theCol < 4)
428   {
429     return scale * matrix.Value (theRow, theCol);
430   }
431   else
432   {
433     return loc.Coord (theRow);
434   }
435 }
436
437 //=======================================================================
438 //function : Transforms
439 // purpose :
440 //=======================================================================
441 inline void gp_Trsf::Transforms (Standard_Real& theX,
442                                  Standard_Real& theY,
443                                  Standard_Real& theZ) const 
444 {
445   gp_XYZ aTriplet (theX, theY, theZ);
446   aTriplet.Multiply (matrix);
447   if (scale != 1.0)
448   {
449     aTriplet.Multiply (scale);
450   }
451   aTriplet.Add (loc);
452   theX = aTriplet.X();
453   theY = aTriplet.Y();
454   theZ = aTriplet.Z();
455 }
456
457 //=======================================================================
458 //function : Transforms
459 // purpose :
460 //=======================================================================
461 inline void gp_Trsf::Transforms (gp_XYZ& theCoord) const
462 {
463   theCoord.Multiply (matrix);
464   if (scale != 1.0)
465   {
466     theCoord.Multiply (scale);
467   }
468   theCoord.Add (loc);
469 }
470
471 #endif // _gp_Trsf_HeaderFile