0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / gp / gp_GTrsf.hxx
CommitLineData
42cf5bc1 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_GTrsf_HeaderFile
16#define _gp_GTrsf_HeaderFile
17
d5477f8c 18#include <gp_Ax1.hxx>
19#include <gp_Ax2.hxx>
42cf5bc1 20#include <gp_Mat.hxx>
42cf5bc1 21#include <gp_Trsf.hxx>
d5477f8c 22#include <gp_TrsfForm.hxx>
23#include <gp_XYZ.hxx>
24#include <Standard_ConstructionError.hxx>
25#include <Standard_OutOfRange.hxx>
26
42cf5bc1 27
896faa72 28// Avoid possible conflict with SetForm macro defined by windows.h
29#ifdef SetForm
30#undef SetForm
31#endif
42cf5bc1 32
33//! Defines a non-persistent transformation in 3D space.
34//! This transformation is a general transformation.
08eda8e3 35//! It can be a gp_Trsf, an affinity, or you can define
42cf5bc1 36//! your own transformation giving the matrix of transformation.
37//!
08eda8e3 38//! With a gp_GTrsf you can transform only a triplet of coordinates gp_XYZ.
39//! It is not possible to transform other geometric objects
40//! because these transformations can change the nature of non-elementary geometric objects.
41//! The transformation gp_GTrsf can be represented as follow:
42//! @code
43//! V1 V2 V3 T XYZ XYZ
42cf5bc1 44//! | a11 a12 a13 a14 | | x | | x'|
45//! | a21 a22 a23 a24 | | y | | y'|
46//! | a31 a32 a33 a34 | | z | = | z'|
47//! | 0 0 0 1 | | 1 | | 1 |
08eda8e3 48//! @endcode
42cf5bc1 49//! where {V1, V2, V3} define the vectorial part of the
08eda8e3 50//! transformation and T defines the translation part of the transformation.
42cf5bc1 51//! Warning
08eda8e3 52//! A gp_GTrsf transformation is only applicable to coordinates.
53//! Be careful if you apply such a transformation to all points of a geometric object,
54//! as this can change the nature of the object and thus render it incoherent!
55//! Typically, a circle is transformed into an ellipse by an affinity transformation.
56//! To avoid modifying the nature of an object, use a gp_Trsf transformation instead,
57//! as objects of this class respect the nature of geometric objects.
42cf5bc1 58class gp_GTrsf
59{
60public:
61
62 DEFINE_STANDARD_ALLOC
63
42cf5bc1 64 //! Returns the Identity transformation.
d5477f8c 65 gp_GTrsf()
66 {
67 shape = gp_Identity;
68 matrix.SetScale (1.0);
69 loc.SetCoord (0.0, 0.0, 0.0);
70 scale = 1.0;
71 }
42cf5bc1 72
d5477f8c 73 //! Converts the gp_Trsf transformation theT into a
42cf5bc1 74 //! general transformation, i.e. Returns a GTrsf with
d5477f8c 75 //! the same matrix of coefficients as the Trsf theT.
76 gp_GTrsf (const gp_Trsf& theT)
77 {
78 shape = theT.Form();
79 matrix = theT.matrix;
80 loc = theT.TranslationPart();
81 scale = theT.ScaleFactor();
82 }
42cf5bc1 83
d5477f8c 84 //! Creates a transformation based on the matrix theM and the
85 //! vector theV where theM defines the vectorial part of
42cf5bc1 86 //! the transformation, and V the translation part, or
d5477f8c 87 gp_GTrsf (const gp_Mat& theM, const gp_XYZ& theV)
88 : matrix (theM),
89 loc (theV)
90 {
91 shape = gp_Other;
92 scale = 0.0;
93 }
94
95 //! Changes this transformation into an affinity of ratio theRatio
96 //! with respect to the axis theA1.
42cf5bc1 97 //! Note: an affinity is a point-by-point transformation that
98 //! transforms any point P into a point P' such that if H is
d5477f8c 99 //! the orthogonal projection of P on the axis theA1 or the
42cf5bc1 100 //! plane A2, the vectors HP and HP' satisfy:
d5477f8c 101 //! HP' = theRatio * HP.
102 void SetAffinity (const gp_Ax1& theA1, const Standard_Real theRatio);
103
104 //! Changes this transformation into an affinity of ratio theRatio
42cf5bc1 105 //! with respect to the plane defined by the origin, the "X Direction" and
d5477f8c 106 //! the "Y Direction" of coordinate system theA2.
42cf5bc1 107 //! Note: an affinity is a point-by-point transformation that
108 //! transforms any point P into a point P' such that if H is
109 //! the orthogonal projection of P on the axis A1 or the
d5477f8c 110 //! plane theA2, the vectors HP and HP' satisfy:
111 //! HP' = theRatio * HP.
112 void SetAffinity (const gp_Ax2& theA2, const Standard_Real theRatio);
113
114 //! Replaces the coefficient (theRow, theCol) of the matrix representing
115 //! this transformation by theValue. Raises OutOfRange
116 //! if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 4
117 void SetValue (const Standard_Integer theRow, const Standard_Integer theCol, const Standard_Real theValue);
118
119 //! Replaces the vectorial part of this transformation by theMatrix.
120 void SetVectorialPart (const gp_Mat& theMatrix)
121 {
122 matrix = theMatrix;
123 shape = gp_Other;
124 scale = 0.0;
125 }
126
42cf5bc1 127 //! Replaces the translation part of
d5477f8c 128 //! this transformation by the coordinates of the number triple theCoord.
129 Standard_EXPORT void SetTranslationPart (const gp_XYZ& theCoord);
130
131 //! Assigns the vectorial and translation parts of theT to this transformation.
132 void SetTrsf (const gp_Trsf& theT)
133 {
134 shape = theT.shape;
135 matrix = theT.matrix;
136 loc = theT.loc;
137 scale = theT.scale;
138 }
42cf5bc1 139
140 //! Returns true if the determinant of the vectorial part of
141 //! this transformation is negative.
d5477f8c 142 Standard_Boolean IsNegative() const { return matrix.Determinant() < 0.0; }
42cf5bc1 143
144 //! Returns true if this transformation is singular (and
145 //! therefore, cannot be inverted).
146 //! Note: The Gauss LU decomposition is used to invert the
147 //! transformation matrix. Consequently, the transformation
148 //! is considered as singular if the largest pivot found is less
149 //! than or equal to gp::Resolution().
150 //! Warning
151 //! If this transformation is singular, it cannot be inverted.
d5477f8c 152 Standard_Boolean IsSingular() const { return matrix.IsSingular(); }
42cf5bc1 153
154 //! Returns the nature of the transformation. It can be an
155 //! identity transformation, a rotation, a translation, a mirror
156 //! transformation (relative to a point, an axis or a plane), a
157 //! scaling transformation, a compound transformation or
158 //! some other type of transformation.
d5477f8c 159 gp_TrsfForm Form() const { return shape; }
42cf5bc1 160
161 //! verify and set the shape of the GTrsf Other or CompoundTrsf
162 //! Ex :
08eda8e3 163 //! @code
42cf5bc1 164 //! myGTrsf.SetValue(row1,col1,val1);
165 //! myGTrsf.SetValue(row2,col2,val2);
166 //! ...
167 //! myGTrsf.SetForm();
08eda8e3 168 //! @endcode
42cf5bc1 169 Standard_EXPORT void SetForm();
d5477f8c 170
42cf5bc1 171 //! Returns the translation part of the GTrsf.
d5477f8c 172 const gp_XYZ& TranslationPart() const { return loc; }
42cf5bc1 173
174 //! Computes the vectorial part of the GTrsf. The returned Matrix
175 //! is a 3*3 matrix.
d5477f8c 176 const gp_Mat& VectorialPart() const { return matrix; }
42cf5bc1 177
178 //! Returns the coefficients of the global matrix of transformation.
d5477f8c 179 //! Raises OutOfRange if theRow < 1 or theRow > 3 or theCol < 1 or theCol > 4
180 Standard_Real Value (const Standard_Integer theRow, const Standard_Integer theCol) const;
181
182 Standard_Real operator() (const Standard_Integer theRow, const Standard_Integer theCol) const { return Value (theRow, theCol); }
183
42cf5bc1 184 Standard_EXPORT void Invert();
42cf5bc1 185
186 //! Computes the reverse transformation.
187 //! Raises an exception if the matrix of the transformation
188 //! is not inversible.
d5477f8c 189 Standard_NODISCARD gp_GTrsf Inverted() const
190 {
191 gp_GTrsf aT = *this;
192 aT.Invert();
193 return aT;
194 }
42cf5bc1 195
d5477f8c 196 //! Computes the transformation composed from theT and <me>.
197 //! In a C++ implementation you can also write Tcomposed = <me> * theT.
42cf5bc1 198 //! Example :
08eda8e3 199 //! @code
200 //! gp_GTrsf T1, T2, Tcomp; ...............
42cf5bc1 201 //! //composition :
202 //! Tcomp = T2.Multiplied(T1); // or (Tcomp = T2 * T1)
203 //! // transformation of a point
08eda8e3 204 //! gp_XYZ P(10.,3.,4.);
205 //! gp_XYZ P1(P);
42cf5bc1 206 //! Tcomp.Transforms(P1); //using Tcomp
08eda8e3 207 //! gp_XYZ P2(P);
42cf5bc1 208 //! T1.Transforms(P2); //using T1 then T2
209 //! T2.Transforms(P2); // P1 = P2 !!!
08eda8e3 210 //! @endcode
d5477f8c 211 Standard_NODISCARD gp_GTrsf Multiplied (const gp_GTrsf& theT) const
212 {
213 gp_GTrsf aTres = *this;
214 aTres.Multiply (theT);
215 return aTres;
1fa8e37b 216 }
42cf5bc1 217
d5477f8c 218 Standard_NODISCARD gp_GTrsf operator * (const gp_GTrsf& theT) const { return Multiplied (theT); }
219
220 //! Computes the transformation composed with <me> and theT.
221 //! <me> = <me> * theT
222 Standard_EXPORT void Multiply (const gp_GTrsf& theT);
42cf5bc1 223
d5477f8c 224 void operator *= (const gp_GTrsf& theT) { Multiply (theT); }
225
226 //! Computes the product of the transformation theT and this
42cf5bc1 227 //! transformation and assigns the result to this transformation.
d5477f8c 228 //! this = theT * this
229 Standard_EXPORT void PreMultiply (const gp_GTrsf& theT);
230
231 Standard_EXPORT void Power (const Standard_Integer theN);
42cf5bc1 232
233 //! Computes:
234 //! - the product of this transformation multiplied by itself
d5477f8c 235 //! theN times, if theN is positive, or
42cf5bc1 236 //! - the product of the inverse of this transformation
d5477f8c 237 //! multiplied by itself |theN| times, if theN is negative.
238 //! If theN equals zero, the result is equal to the Identity
42cf5bc1 239 //! transformation.
d5477f8c 240 //! I.e.: <me> * <me> * .......* <me>, theN time.
241 //! if theN =0 <me> = Identity
242 //! if theN < 0 <me> = <me>.Inverse() *...........* <me>.Inverse().
42cf5bc1 243 //!
244 //! Raises an exception if N < 0 and if the matrix of the
245 //! transformation not inversible.
d5477f8c 246 Standard_NODISCARD gp_GTrsf Powered (const Standard_Integer theN) const
247 {
248 gp_GTrsf aT = *this;
249 aT.Power (theN);
250 return aT;
251 }
252
253 void Transforms (gp_XYZ& theCoord) const;
254
42cf5bc1 255 //! Transforms a triplet XYZ with a GTrsf.
d5477f8c 256 void Transforms (Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const;
257
258 gp_Trsf Trsf() const;
42cf5bc1 259
2615c2d7 260 //! Convert transformation to 4x4 matrix.
261 template<class T>
262 void GetMat4 (NCollection_Mat4<T>& theMat) const
263 {
264 if (shape == gp_Identity)
265 {
266 theMat.InitIdentity();
267 return;
268 }
269
270 theMat.SetValue (0, 0, static_cast<T> (Value (1, 1)));
271 theMat.SetValue (0, 1, static_cast<T> (Value (1, 2)));
272 theMat.SetValue (0, 2, static_cast<T> (Value (1, 3)));
273 theMat.SetValue (0, 3, static_cast<T> (Value (1, 4)));
274 theMat.SetValue (1, 0, static_cast<T> (Value (2, 1)));
275 theMat.SetValue (1, 1, static_cast<T> (Value (2, 2)));
276 theMat.SetValue (1, 2, static_cast<T> (Value (2, 3)));
277 theMat.SetValue (1, 3, static_cast<T> (Value (2, 4)));
278 theMat.SetValue (2, 0, static_cast<T> (Value (3, 1)));
279 theMat.SetValue (2, 1, static_cast<T> (Value (3, 2)));
280 theMat.SetValue (2, 2, static_cast<T> (Value (3, 3)));
281 theMat.SetValue (2, 3, static_cast<T> (Value (3, 4)));
282 theMat.SetValue (3, 0, static_cast<T> (0));
283 theMat.SetValue (3, 1, static_cast<T> (0));
284 theMat.SetValue (3, 2, static_cast<T> (0));
285 theMat.SetValue (3, 3, static_cast<T> (1));
286 }
287
4e993e4d 288 //! Convert transformation from 4x4 matrix.
289 template<class T>
290 void SetMat4 (const NCollection_Mat4<T>& theMat)
291 {
292 shape = gp_Other;
293 scale = 0.0;
294 matrix.SetValue (1, 1, theMat.GetValue (0, 0));
295 matrix.SetValue (1, 2, theMat.GetValue (0, 1));
296 matrix.SetValue (1, 3, theMat.GetValue (0, 2));
297 matrix.SetValue (2, 1, theMat.GetValue (1, 0));
298 matrix.SetValue (2, 2, theMat.GetValue (1, 1));
299 matrix.SetValue (2, 3, theMat.GetValue (1, 2));
300 matrix.SetValue (3, 1, theMat.GetValue (2, 0));
301 matrix.SetValue (3, 2, theMat.GetValue (2, 1));
302 matrix.SetValue (3, 3, theMat.GetValue (2, 2));
303 loc.SetCoord (theMat.GetValue (0, 3), theMat.GetValue (1, 3), theMat.GetValue (2, 3));
304 }
305
bc73b006 306 //! Dumps the content of me into the stream
307 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
308
42cf5bc1 309private:
310
42cf5bc1 311 gp_Mat matrix;
312 gp_XYZ loc;
313 gp_TrsfForm shape;
314 Standard_Real scale;
315
42cf5bc1 316};
317
318
d5477f8c 319//=======================================================================
320//function : SetAffinity
321// purpose :
322//=======================================================================
323inline void gp_GTrsf::SetAffinity (const gp_Ax1& theA1, const Standard_Real theRatio)
324{
325 shape = gp_Other;
326 scale = 0.0;
327 matrix.SetDot (theA1.Direction().XYZ());
328 matrix.Multiply (1.0 - theRatio);
329 matrix.SetDiagonal (matrix.Value (1,1) + theRatio,
330 matrix.Value (2,2) + theRatio,
331 matrix.Value (3,3) + theRatio);
332 loc = theA1.Location().XYZ();
333 loc.Reverse ();
334 loc.Multiply (matrix);
335 loc.Add (theA1.Location().XYZ());
336}
337
338//=======================================================================
339//function : SetAffinity
340// purpose :
341//=======================================================================
342inline void gp_GTrsf::SetAffinity (const gp_Ax2& theA2, const Standard_Real theRatio)
343{
344 shape = gp_Other;
345 scale = 0.0;
346 matrix.SetDot (theA2.Direction().XYZ());
347 matrix.Multiply (theRatio - 1.);
348 loc = theA2.Location().XYZ();
349 loc.Reverse ();
350 loc.Multiply (matrix);
351 matrix.SetDiagonal (matrix.Value (1,1) + 1.,
352 matrix.Value (2,2) + 1.,
353 matrix.Value (3,3) + 1.);
354}
355
356//=======================================================================
357//function : SetValue
358// purpose :
359//=======================================================================
360inline void gp_GTrsf::SetValue (const Standard_Integer theRow,
361 const Standard_Integer theCol,
362 const Standard_Real theValue)
363{
364 Standard_OutOfRange_Raise_if
365 (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 4, " ");
366 if (theCol == 4)
367 {
368 loc.SetCoord (theRow, theValue);
369 if (shape == gp_Identity)
370 {
371 shape = gp_Translation;
372 }
373 return;
374 }
375 else
376 {
377 if (!(shape == gp_Other) && !(scale == 1.0))
378 {
379 matrix.Multiply (scale);
380 }
381 matrix.SetValue (theRow, theCol, theValue);
382 shape = gp_Other;
383 scale = 0.0;
384 return;
385 }
386}
42cf5bc1 387
d5477f8c 388//=======================================================================
389//function : Value
390// purpose :
391//=======================================================================
392inline Standard_Real gp_GTrsf::Value (const Standard_Integer theRow,
393 const Standard_Integer theCol) const
394{
395 Standard_OutOfRange_Raise_if
396 (theRow < 1 || theRow > 3 || theCol < 1 || theCol > 4, " ");
397 if (theCol == 4)
398 {
399 return loc.Coord (theRow);
400 }
401 if (shape == gp_Other)
402 {
403 return matrix.Value (theRow, theCol);
404 }
405 return scale * matrix.Value (theRow, theCol);
406}
42cf5bc1 407
d5477f8c 408//=======================================================================
409//function : Transforms
410// purpose :
411//=======================================================================
412inline void gp_GTrsf::Transforms (gp_XYZ& theCoord) const
413{
414 theCoord.Multiply (matrix);
415 if (!(shape == gp_Other) && !(scale == 1.0))
416 {
417 theCoord.Multiply (scale);
418 }
419 theCoord.Add (loc);
420}
42cf5bc1 421
d5477f8c 422//=======================================================================
423//function : Transforms
424// purpose :
425//=======================================================================
426inline void gp_GTrsf::Transforms (Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) const
427{
428 gp_XYZ aTriplet (theX, theY, theZ);
429 aTriplet.Multiply (matrix);
430 if (!(shape == gp_Other) && !(scale == 1.0))
431 {
432 aTriplet.Multiply (scale);
433 }
434 aTriplet.Add (loc);
435 aTriplet.Coord (theX, theY, theZ);
436}
42cf5bc1 437
d5477f8c 438//=======================================================================
439//function : Trsf
440// purpose :
441//=======================================================================
442inline gp_Trsf gp_GTrsf::Trsf() const
443{
444 if (Form() == gp_Other)
445 {
446 throw Standard_ConstructionError("gp_GTrsf::Trsf() - non-orthogonal GTrsf");
447 }
448 gp_Trsf aT;
449 aT.shape = shape;
450 aT.scale = scale;
451 aT.matrix = matrix;
452 aT.loc = loc;
453 return aT;
454}
42cf5bc1 455
456#endif // _gp_GTrsf_HeaderFile