0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / gp / gp_Trsf.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 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
973c2be1 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.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15// JCV 30/08/90 Modif passage version C++ 2.0 sur Sun
16// JCV 1/10/90 Changement de nom du package vgeom -> gp
17// JCV 4/10/90 codage sur la forme de la transformation shape,Scaling,negative
18// JCV 10/12/90 Modif introduction des classes Mat et XYZ dans gp
19
20#define No_Standard_OutOfRange
21
42cf5bc1 22
7fd59977 23#include <gp.hxx>
42cf5bc1 24#include <gp_Ax1.hxx>
25#include <gp_Ax2.hxx>
26#include <gp_Ax3.hxx>
27#include <gp_GTrsf.hxx>
28#include <gp_Mat.hxx>
29#include <gp_Pnt.hxx>
30#include <gp_Quaternion.hxx>
31#include <gp_Trsf.hxx>
32#include <gp_Trsf2d.hxx>
33#include <gp_Vec.hxx>
34#include <gp_XYZ.hxx>
7fd59977 35#include <Standard_ConstructionError.hxx>
42cf5bc1 36#include <Standard_OutOfRange.hxx>
bead40f2 37
38//=======================================================================
39//function : gp_Trsf
40//purpose : Constructor from 2d
41//=======================================================================
bead40f2 42gp_Trsf::gp_Trsf (const gp_Trsf2d& T) :
43scale(T.ScaleFactor()),
44shape(T.Form()),
45loc(T.TranslationPart().X(),T.TranslationPart().Y(), 0.0)
46{
47 const gp_Mat2d& M = T.HVectorialPart();
48 matrix(1,1) = M(1,1);
49 matrix(1,2) = M(1,2);
50 matrix(2,1) = M(2,1);
51 matrix(2,2) = M(2,2);
52 matrix(3,3) = 1.;
53 if (shape == gp_Ax1Mirror)
54 {
55 scale = 1;
56 matrix.Multiply(-1);
57 }
58}
59
7fd59977 60//=======================================================================
61//function : SetMirror
62//purpose :
63//=======================================================================
64
65void gp_Trsf::SetMirror (const gp_Ax1& A1)
66{
67 shape = gp_Ax1Mirror;
68 scale = 1;
69 loc = A1.Location().XYZ();
70 matrix.SetDot(A1.Direction().XYZ());
71 matrix.Multiply(-2);
72 matrix.SetDiagonal (matrix.Value (1,1) + 1,
73 matrix.Value (2,2) + 1,
74 matrix.Value (3,3) + 1);
75
76 loc.Multiply (matrix);
77 loc.Add (A1.Location().XYZ());
78 matrix.Multiply(-1);
79}
80
81//=======================================================================
82//function : SetMirror
83//purpose :
84//=======================================================================
85
86void gp_Trsf::SetMirror (const gp_Ax2& A2)
87{
88 shape = gp_Ax2Mirror;
89 scale = -1;
90 loc = A2.Location().XYZ();
91 matrix.SetDot(A2.Direction().XYZ());
92 matrix.Multiply(2);
93 matrix.SetDiagonal (matrix.Value (1,1) - 1,
94 matrix.Value (2,2) - 1,
95 matrix.Value (3,3) - 1);
96
97 loc.Multiply (matrix);
98 loc.Add (A2.Location().XYZ());
99}
100
101//=======================================================================
102//function : SetRotation
103//purpose :
104//=======================================================================
105
106void gp_Trsf::SetRotation (const gp_Ax1& A1,
107 const Standard_Real Ang)
108{
109 shape = gp_Rotation;
110 scale = 1.;
111 loc = A1.Location().XYZ();
112 matrix.SetRotation (A1.Direction().XYZ(), Ang);
113 loc.Reverse ();
114 loc.Multiply (matrix);
115 loc.Add (A1.Location().XYZ());
116}
117
118//=======================================================================
119//function : SetRotation
120//purpose :
121//=======================================================================
122
123void gp_Trsf::SetRotation (const gp_Quaternion& R)
124{
125 shape = gp_Rotation;
126 scale = 1.;
127 loc.SetCoord (0., 0., 0.);
128 matrix = R.GetMatrix();
129}
130
131//=======================================================================
132//function : SetScale
133//purpose :
134//=======================================================================
135
136void gp_Trsf::SetScale (const gp_Pnt& P, const Standard_Real S)
137{
138 shape = gp_Scale;
139 scale = S;
140 loc = P.XYZ();
141 Standard_Real As = scale;
142 if (As < 0) As = - As;
143 Standard_ConstructionError_Raise_if
144 (As <= gp::Resolution(),"gp_Trsf::SetScaleFactor");
145 matrix.SetIdentity ();
146 loc.Multiply (1-S);
147}
148
149//=======================================================================
150//function : SetTransformation
151//purpose :
152//=======================================================================
153
154void gp_Trsf::SetTransformation (const gp_Ax3& FromA1,
155 const gp_Ax3& ToA2)
156{
157 shape = gp_CompoundTrsf;
158 scale = 1.0;
159 // matrix from XOY ToA2 :
160 matrix.SetCol (1, ToA2.XDirection().XYZ());
161 matrix.SetCol (2, ToA2.YDirection().XYZ());
162 matrix.SetCol (3, ToA2.Direction().XYZ());
163 loc = ToA2.Location().XYZ();
164 matrix.Transpose();
165 loc.Multiply (matrix);
166 loc.Reverse ();
167
168 // matrix FromA1 to XOY :
169 const gp_XYZ& xDir = FromA1.XDirection().XYZ();
170 const gp_XYZ& yDir = FromA1.YDirection().XYZ();
171 const gp_XYZ& zDir = FromA1.Direction().XYZ();
172
173 gp_Mat MA1 (xDir, yDir, zDir);
174 gp_XYZ MA1loc = FromA1.Location().XYZ();
175
176 // matrix * MA1 => FromA1 ToA2 :
177 MA1loc.Multiply (matrix);
178 loc.Add (MA1loc);
179 matrix.Multiply (MA1);
180}
181
182void gp_Trsf::SetTransformation (const gp_Ax3& A3)
183{
184 shape = gp_CompoundTrsf;
185 scale = 1.0;
186 loc = A3.Location().XYZ();
187 matrix.SetCols (A3.XDirection().XYZ(),
188 A3.YDirection().XYZ(),
189 A3. Direction().XYZ());
190 matrix.Transpose();
191 loc.Multiply (matrix);
192 loc.Reverse ();
193}
194
195//=======================================================================
196//function : SetTransformation
197//purpose :
198//=======================================================================
199
200void gp_Trsf::SetTransformation (const gp_Quaternion& R, const gp_Vec& T)
201{
202 shape = gp_CompoundTrsf;
203 scale = 1.;
204 loc = T.XYZ();
205 matrix = R.GetMatrix();
206}
207
208//=======================================================================
209//function : SetDisplacement
210//purpose :
211//=======================================================================
212
213void gp_Trsf::SetDisplacement (const gp_Ax3& FromA1,
214 const gp_Ax3& ToA2)
215{
216 shape = gp_CompoundTrsf;
217 scale = 1.0;
218 // matrix from ToA2 to XOY :
219 matrix.SetCol (1, ToA2.XDirection().XYZ());
220 matrix.SetCol (2, ToA2.YDirection().XYZ());
221 matrix.SetCol (3, ToA2.Direction().XYZ());
222 loc = ToA2.Location().XYZ();
223 // matrix XOY to FromA1 :
224 const gp_XYZ& xDir = FromA1.XDirection().XYZ();
225 const gp_XYZ& yDir = FromA1.YDirection().XYZ();
226 const gp_XYZ& zDir = FromA1.Direction().XYZ();
227 gp_Mat MA1 (xDir, yDir, zDir);
228 MA1.Transpose();
229 gp_XYZ MA1loc = FromA1.Location().XYZ();
230 MA1loc.Multiply (MA1);
231 MA1loc.Reverse();
232 // matrix * MA1
233 MA1loc.Multiply (matrix);
234 loc.Add (MA1loc);
235 matrix.Multiply (MA1);
236}
237
238//=======================================================================
239//function : SetTranslationPart
240//purpose :
241//=======================================================================
242
243void gp_Trsf::SetTranslationPart (const gp_Vec& V) {
244
245 loc = V.XYZ();
57922171 246 const Standard_Boolean locnull = (loc.SquareModulus() < gp::Resolution());
7fd59977 247
248 switch (shape) {
249
250 case gp_Identity :
251 if (!locnull) shape = gp_Translation;
252 break;
253
254 case gp_Translation :
255 if (locnull) shape = gp_Identity;
256 break;
257
258 case gp_Rotation :
259 case gp_PntMirror :
260 case gp_Ax1Mirror :
261 case gp_Ax2Mirror :
262 case gp_Scale :
263 case gp_CompoundTrsf :
264 case gp_Other :
57922171 265 if (!locnull) {
266 shape = gp_CompoundTrsf;
267 }
7fd59977 268 break;
269 }
270}
271
272//=======================================================================
273//function : SetScaleFactor
274//purpose :
275//=======================================================================
276
277void gp_Trsf::SetScaleFactor (const Standard_Real S)
278{
279 Standard_Real As = S;
280 if (As < 0) As = - As;
281 Standard_ConstructionError_Raise_if
282 (As <= gp::Resolution(),"gp_Trsf::SetScaleFactor");
283 scale = S;
284 As = scale - 1.;
285 if (As < 0) As = - As;
9256a43d 286 Standard_Boolean unit = As <= gp::Resolution(); // = (scale == 1)
7fd59977 287 As = scale + 1.;
288 if (As < 0) As = - As;
9256a43d 289 Standard_Boolean munit = As <= gp::Resolution(); // = (scale == -1)
7fd59977 290
291 switch (shape) {
292 case gp_Identity :
293 case gp_Translation :
294 if (!unit) shape = gp_Scale;
295 if (munit) shape = gp_PntMirror;
296 break;
297 case gp_Rotation :
298 if (!unit) shape = gp_CompoundTrsf;
299 break;
300 case gp_PntMirror :
301 case gp_Ax1Mirror :
302 case gp_Ax2Mirror :
303 if (!munit) shape = gp_Scale;
304 if (unit) shape = gp_Identity;
305 break;
306 case gp_Scale :
307 if (unit) shape = gp_Identity;
308 if (munit) shape = gp_PntMirror;
309 break;
310 case gp_CompoundTrsf :
311 break;
312 case gp_Other :
313 break;
314 }
315}
316
317//=======================================================================
318//function : SetValues
319//purpose :
320// 06-01-1998 modified by PMN : On utilise TolDist pour evaluer si les coeffs
321// sont nuls : c'est toujours mieux que gp::Resolution !
322//=======================================================================
323
324void gp_Trsf::SetValues(const Standard_Real a11,
325 const Standard_Real a12,
326 const Standard_Real a13,
327 const Standard_Real a14,
328 const Standard_Real a21,
329 const Standard_Real a22,
330 const Standard_Real a23,
331 const Standard_Real a24,
332 const Standard_Real a31,
333 const Standard_Real a32,
334 const Standard_Real a33,
7a8c6a36 335 const Standard_Real a34)
7fd59977 336{
337 gp_XYZ col1(a11,a21,a31);
338 gp_XYZ col2(a12,a22,a32);
339 gp_XYZ col3(a13,a23,a33);
340 gp_XYZ col4(a14,a24,a34);
341 // compute the determinant
342 gp_Mat M(col1,col2,col3);
343 Standard_Real s = M.Determinant();
344 Standard_Real As = s;
345 if (As < 0) As = - As;
346 Standard_ConstructionError_Raise_if
7a8c6a36 347 (As < gp::Resolution(),"gp_Trsf::SetValues, null determinant");
7fd59977 348 if (s > 0)
349 s = Pow(s,1./3.);
350 else
351 s = -Pow(-s,1./3.);
352 M.Divide(s);
353
7fd59977 354 scale = s;
355 shape = gp_CompoundTrsf;
7a8c6a36 356
7fd59977 357 matrix = M;
7a8c6a36 358 Orthogonalize();
359
7fd59977 360 loc = col4;
361}
362
363//=======================================================================
364//function : GetRotation
365//purpose :
366//=======================================================================
367
368gp_Quaternion gp_Trsf::GetRotation () const
369{
370 return gp_Quaternion (matrix);
371}
372
373//=======================================================================
374//function : VectorialPart
375//purpose :
376//=======================================================================
377
378gp_Mat gp_Trsf::VectorialPart () const
379{
380 if (scale == 1.0) return matrix;
381 gp_Mat M = matrix;
382 if (shape == gp_Scale || shape == gp_PntMirror)
383 M.SetDiagonal(scale*M.Value(1,1),
384 scale*M.Value(2,2),
385 scale*M.Value(3,3));
386 else
387 M.Multiply (scale);
388 return M;
389}
390
391//=======================================================================
392//function : Invert
393//purpose :
394//=======================================================================
395
396void gp_Trsf::Invert()
397{
398 // -1
399 // X' = scale * R * X + T => X = (R / scale) * ( X' - T)
400 //
401 // Pour les gp_Trsf puisque le scale est extrait de la gp_Matrice R
402 // on a toujours determinant (R) = 1 et R-1 = R transposee.
403 if (shape == gp_Identity) { }
404 else if (shape == gp_Translation || shape == gp_PntMirror) loc.Reverse();
405 else if (shape == gp_Scale) {
406 Standard_Real As = scale;
407 if (As < 0) As = - As;
2d2b3d53 408 Standard_ConstructionError_Raise_if (As <= gp::Resolution(), "gp_Trsf::Invert() - transformation has zero scale");
7fd59977 409 scale = 1.0 / scale;
410 loc.Multiply (-scale);
411 }
412 else {
413 Standard_Real As = scale;
414 if (As < 0) As = - As;
2d2b3d53 415 Standard_ConstructionError_Raise_if (As <= gp::Resolution(), "gp_Trsf::Invert() - transformation has zero scale");
7fd59977 416 scale = 1.0 / scale;
417 matrix.Transpose ();
418 loc.Multiply (matrix);
419 loc.Multiply (-scale);
420 }
421}
422
423//=======================================================================
424//function : Multiply
425//purpose :
426//=======================================================================
427
428void gp_Trsf::Multiply(const gp_Trsf& T)
429{
430 if (T.shape == gp_Identity) { }
431 else if (shape == gp_Identity) {
432 shape = T.shape;
433 scale = T.scale;
434 loc = T.loc;
435 matrix = T.matrix;
436 }
437 else if (shape == gp_Rotation && T.shape == gp_Rotation) {
f6f03db9 438 if (T.loc.X() != 0.0 || T.loc.Y() != 0.0 || T.loc.Z() != 0.0) {
7fd59977 439 loc.Add (T.loc.Multiplied (matrix));
440 }
441 matrix.Multiply(T.matrix);
442 }
443 else if (shape == gp_Translation && T.shape == gp_Translation) {
444 loc.Add (T.loc);
445 }
446 else if (shape == gp_Scale && T.shape == gp_Scale) {
447 loc.Add (T.loc.Multiplied(scale));
448 scale = scale * T.scale;
449 }
450 else if (shape == gp_PntMirror && T.shape == gp_PntMirror) {
451 scale = 1.0;
452 shape = gp_Translation;
453 loc.Add (T.loc.Reversed());
454 }
455 else if (shape == gp_Ax1Mirror && T.shape == gp_Ax1Mirror) {
456 shape = gp_Rotation;
457 loc.Add (T.loc.Multiplied (matrix));
458 matrix.Multiply(T.matrix);
459 }
460 else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
461 shape == gp_Ax1Mirror || shape == gp_Ax2Mirror)
462 && T.shape == gp_Translation) {
463 gp_XYZ Tloc(T.loc);
464 Tloc.Multiply(matrix);
465 if (scale != 1.0) { Tloc.Multiply(scale); }
466 loc.Add (Tloc);
467 }
468 else if ((shape == gp_Scale || shape == gp_PntMirror)
469 && T.shape == gp_Translation) {
470 gp_XYZ Tloc(T.loc);
471 Tloc.Multiply (scale);
472 loc.Add (Tloc);
473 }
474 else if (shape == gp_Translation &&
475 (T.shape == gp_CompoundTrsf || T.shape == gp_Rotation ||
476 T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror)) {
477 shape = gp_CompoundTrsf;
478 scale = T.scale;
479 loc.Add (T.loc);
480 matrix = T.matrix;
481 }
482 else if (shape == gp_Translation &&
483 (T.shape == gp_Scale || T.shape == gp_PntMirror)) {
484 shape = T.shape;
485 loc.Add (T.loc);
486 scale = T.scale;
487 }
488 else if ((shape == gp_PntMirror || shape == gp_Scale) &&
489 (T.shape == gp_PntMirror || T.shape == gp_Scale)) {
490 shape = gp_CompoundTrsf;
491 gp_XYZ Tloc(T.loc);
492 Tloc.Multiply (scale);
493 loc.Add (Tloc);
494 scale = scale * T.scale;
495 }
496 else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
497 shape == gp_Ax1Mirror || shape == gp_Ax2Mirror)
498 && (T.shape == gp_Scale || T.shape == gp_PntMirror)) {
499 shape = gp_CompoundTrsf;
500 gp_XYZ Tloc(T.loc);
501 if (scale == 1.0) {
502 scale = T.scale;
503 Tloc.Multiply(matrix);
504 }
505 else {
506 Tloc.Multiply (matrix);
507 Tloc.Multiply (scale);
508 scale = scale * T.scale;
509 }
510 loc.Add (Tloc);
511 }
512 else if ((T.shape == gp_CompoundTrsf || T.shape == gp_Rotation ||
513 T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror)
514 && (shape == gp_Scale || shape == gp_PntMirror)) {
515 shape = gp_CompoundTrsf;
516 gp_XYZ Tloc(T.loc);
517 Tloc.Multiply(scale);
518 loc.Add (Tloc);
519 scale = scale * T.scale;
520 matrix = T.matrix;
521 }
522 else {
523 shape = gp_CompoundTrsf;
524 gp_XYZ Tloc(T.loc);
525 Tloc.Multiply (matrix);
526 if (scale != 1.0) {
527 Tloc.Multiply (scale);
528 scale = scale * T.scale;
529 }
530 else { scale = T.scale; }
531 loc.Add (Tloc);
532 matrix.Multiply(T.matrix);
533 }
534}
535
536//=======================================================================
537//function : Power
538//purpose :
539//=======================================================================
540
541void gp_Trsf::Power (const Standard_Integer N)
542{
543 if (shape == gp_Identity) { }
544 else {
545 if (N == 0) {
546 scale = 1.0;
547 shape = gp_Identity;
548 matrix.SetIdentity();
549 loc = gp_XYZ (0.0, 0.0, 0.0);
550 }
551 else if (N == 1) { }
552 else if (N == -1) { Invert(); }
553 else {
554 if (N < 0) { Invert(); }
555 if (shape == gp_Translation) {
556 Standard_Integer Npower = N;
557 if (Npower < 0) Npower = - Npower;
558 Npower--;
559 gp_XYZ Temploc = loc;
302f96fb 560 for(;;) {
7fd59977 561 if (IsOdd(Npower)) loc.Add (Temploc);
562 if (Npower == 1) break;
563 Temploc.Add (Temploc);
564 Npower = Npower/2;
565 }
566 }
567 else if (shape == gp_Scale) {
568 Standard_Integer Npower = N;
569 if (Npower < 0) Npower = - Npower;
570 Npower--;
571 gp_XYZ Temploc = loc;
572 Standard_Real Tempscale = scale;
302f96fb 573 for(;;) {
7fd59977 574 if (IsOdd(Npower)) {
575 loc.Add (Temploc.Multiplied(scale));
576 scale = scale * Tempscale;
577 }
578 if (Npower == 1) break;
579 Temploc.Add (Temploc.Multiplied(Tempscale));
580 Tempscale = Tempscale * Tempscale;
581 Npower = Npower/2;
582 }
583 }
584 else if (shape == gp_Rotation) {
585 Standard_Integer Npower = N;
586 if (Npower < 0) Npower = - Npower;
587 Npower--;
588 gp_Mat Tempmatrix (matrix);
589 if (loc.X() == 0.0 && loc.Y() == 0.0 && loc.Z() == 0.0) {
302f96fb 590 for(;;) {
7fd59977 591 if (IsOdd(Npower)) matrix.Multiply (Tempmatrix);
592 if (Npower == 1) break;
593 Tempmatrix.Multiply (Tempmatrix);
594 Npower = Npower/2;
595 }
596 }
597 else {
598 gp_XYZ Temploc = loc;
302f96fb 599 for(;;) {
7fd59977 600 if (IsOdd(Npower)) {
601 loc.Add (Temploc.Multiplied (matrix));
602 matrix.Multiply (Tempmatrix);
603 }
604 if (Npower == 1) break;
605 Temploc.Add (Temploc.Multiplied (Tempmatrix));
606 Tempmatrix.Multiply (Tempmatrix);
607 Npower = Npower/2;
608 }
609 }
610 }
611 else if (shape == gp_PntMirror || shape == gp_Ax1Mirror ||
612 shape == gp_Ax2Mirror) {
613 if (IsEven (N)) {
614 shape = gp_Identity;
615 scale = 1.0;
616 matrix.SetIdentity ();
617 loc.SetX(0);
618 loc.SetY(0);
619 loc.SetZ(0);
620 }
621 }
622 else {
623 shape = gp_CompoundTrsf;
624 Standard_Integer Npower = N;
625 if (Npower < 0) Npower = - Npower;
626 Npower--;
627 gp_XYZ Temploc = loc;
628 Standard_Real Tempscale = scale;
629 gp_Mat Tempmatrix (matrix);
302f96fb 630 for(;;) {
7fd59977 631 if (IsOdd(Npower)) {
632 loc.Add ((Temploc.Multiplied (matrix)).Multiplied (scale));
633 scale = scale * Tempscale;
634 matrix.Multiply (Tempmatrix);
635 }
636 if (Npower == 1) break;
637 Tempscale = Tempscale * Tempscale;
638 Temploc.Add ( (Temploc.Multiplied (Tempmatrix)).Multiplied
639 (Tempscale)
640 );
641 Tempmatrix.Multiply (Tempmatrix);
642 Npower = Npower/2;
643 }
644 }
645 }
646 }
647}
648
649//=======================================================================
650//function : PreMultiply
651//purpose :
652//=======================================================================
653
654void gp_Trsf::PreMultiply (const gp_Trsf& T)
655{
656 if (T.shape == gp_Identity) { }
657 else if (shape == gp_Identity) {
658 shape = T.shape;
659 scale = T.scale;
660 loc = T.loc;
661 matrix = T.matrix;
662 }
663 else if (shape == gp_Rotation && T.shape == gp_Rotation) {
664 loc.Multiply (T.matrix);
665 loc.Add (T.loc);
666 matrix.PreMultiply(T.matrix);
667 }
668 else if (shape == gp_Translation && T.shape == gp_Translation) {
669 loc.Add (T.loc);
670 }
671 else if (shape == gp_Scale && T.shape == gp_Scale) {
672 loc.Multiply (T.scale);
673 loc.Add (T.loc);
674 scale = scale * T.scale;
675 }
676 else if (shape == gp_PntMirror && T.shape == gp_PntMirror) {
677 scale = 1.0;
678 shape = gp_Translation;
679 loc.Reverse();
680 loc.Add (T.loc);
681 }
682 else if (shape == gp_Ax1Mirror && T.shape == gp_Ax1Mirror) {
683 shape = gp_Rotation;
684 loc.Multiply (T.matrix);
685 loc.Add (T.loc);
686 matrix.PreMultiply(T.matrix);
687 }
688 else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
689 shape == gp_Ax1Mirror || shape == gp_Ax2Mirror)
690 && T.shape == gp_Translation) {
691 loc.Add (T.loc);
692 }
693 else if ((shape == gp_Scale || shape == gp_PntMirror)
694 && T.shape == gp_Translation) {
695 loc.Add (T.loc);
696 }
697 else if (shape == gp_Translation &&
698 (T.shape == gp_CompoundTrsf || T.shape == gp_Rotation
699 || T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror)) {
700 shape = gp_CompoundTrsf;
701 matrix = T.matrix;
702 if (T.scale == 1.0) loc.Multiply (T.matrix);
703 else {
704 scale = T.scale;
705 loc.Multiply (matrix);
706 loc.Multiply (scale);
707 }
708 loc.Add (T.loc);
709 }
710 else if ((T.shape == gp_Scale || T.shape == gp_PntMirror)
711 && shape == gp_Translation) {
712 loc.Multiply (T.scale);
713 loc.Add (T.loc);
714 scale = T.scale;
715 shape = T.shape;
716 }
717 else if ((shape == gp_PntMirror || shape == gp_Scale) &&
718 (T.shape == gp_PntMirror || T.shape == gp_Scale)) {
719 shape = gp_CompoundTrsf;
720 loc.Multiply (T.scale);
721 loc.Add (T.loc);
722 scale = scale * T.scale;
723 }
724 else if ((shape == gp_CompoundTrsf || shape == gp_Rotation ||
725 shape == gp_Ax1Mirror || shape == gp_Ax2Mirror)
726 && (T.shape == gp_Scale || T.shape == gp_PntMirror)) {
727 shape = gp_CompoundTrsf;
728 loc.Multiply (T.scale);
729 loc.Add (T.loc);
730 scale = scale * T.scale;
731 }
732 else if ((T.shape == gp_CompoundTrsf || T.shape == gp_Rotation ||
733 T.shape == gp_Ax1Mirror || T.shape == gp_Ax2Mirror)
734 && (shape == gp_Scale || shape == gp_PntMirror)) {
735 shape = gp_CompoundTrsf;
736 matrix = T.matrix;
737 if (T.scale == 1.0) loc.Multiply (T.matrix);
738 else {
739 loc.Multiply (matrix);
740 loc.Multiply (T.scale);
741 scale = T.scale * scale;
742 }
743 loc.Add (T.loc);
744 }
745 else {
746 shape = gp_CompoundTrsf;
747 loc.Multiply (T.matrix);
748 if (T.scale != 1.0) {
749 loc.Multiply (T.scale); scale = scale * T.scale;
750 }
751 loc.Add (T.loc);
752 matrix.PreMultiply(T.matrix);
753 }
754}
755
756//=======================================================================
757//function : GetRotation
758//purpose : algorithm from A.Korn, M.Korn, "Mathematical Handbook for
759// scientists and Engineers" McGraw-Hill, 1961, ch.14.10-2.
760//=======================================================================
761
762Standard_Boolean gp_Trsf::GetRotation (gp_XYZ& theAxis,
763 Standard_Real& theAngle) const
764{
765 gp_Quaternion Q = GetRotation();
766 gp_Vec aVec;
767 Q.GetVectorAndAngle (aVec, theAngle);
768 theAxis = aVec.XYZ();
769 return Standard_True;
770}
7a8c6a36 771
772//=======================================================================
773//function : Orthogonalize
774//purpose :
4dba155d 775//ATTENTION!!!
776// Orthogonalization is not equivalent transformation. Therefore,
777// transformation with source matrix and with orthogonalized matrix can
778// lead to different results for one shape. Consequently, source matrix must
779// be close to orthogonalized matrix for reducing these differences.
7a8c6a36 780//=======================================================================
781void gp_Trsf::Orthogonalize()
782{
4dba155d 783 //Matrix M is called orthogonal if and only if
784 // M*Transpose(M) == E
785 //where E is identity matrix.
786
787 //Set of all rows (as of all columns) of matrix M (for gp_Trsf class) is
788 //orthonormal basis. If this condition is not satisfied then the basis can be
789 //orthonormalized in accordance with below described algorithm.
790
791 //In 3D-space, we have the linear span of three basis vectors: V1, V2 and V3.
792 //Correspond orthonormalized basis is formed by vectors Vn1, Vn2 and Vn3.
793
794 //In this case,
795 // Vn_{i}*Vn_{j} = (i == j)? 1 : 0.
796
797 //The algorithm includes following steps:
798
799 //1. Normalize V1 vector:
800 // V1n=V1/|V1|;
801 //
802 //2. Let
803 // V2n=V2-m*V1n.
804 //
805 //After multiplication two parts of this equation by V1n,
806 //we will have following equation:
807 // 0=V2*V1n-m <==> m=V2*V1n.
808 //
809 //Consequently,
810 // V2n=V2-(V2*V1n)*V1n.
811
812 //3. Let
813 // V3n=V3-m1*V1n-m2*V2n.
814 //
815 //After multiplication two parts of this equation by V1n,
816 //we will have following equation:
817 // 0=V3*V1n-m1 <==> m1=V3*V1n.
818 //
819 //After multiplication two parts of main equation by V2n,
820 //we will have following equation:
821 // 0=V3*V2n-m2 <==> m2=V3*V2n.
822 //
823 //In conclusion,
824 // V3n=V3-(V3*V1n)*V1n-(V3*V2n)*V2n.
825
7a8c6a36 826 gp_Mat aTM(matrix);
827
828 gp_XYZ aV1 = aTM.Column(1);
829 gp_XYZ aV2 = aTM.Column(2);
830 gp_XYZ aV3 = aTM.Column(3);
831
832 aV1.Normalize();
833
834 aV2 -= aV1*(aV2.Dot(aV1));
835 aV2.Normalize();
836
837 aV3 -= aV1*(aV3.Dot(aV1)) + aV2*(aV3.Dot(aV2));
838 aV3.Normalize();
839
840 aTM.SetCols(aV1, aV2, aV3);
841
842 aV1 = aTM.Row(1);
843 aV2 = aTM.Row(2);
844 aV3 = aTM.Row(3);
845
846 aV1.Normalize();
847
848 aV2 -= aV1*(aV2.Dot(aV1));
849 aV2.Normalize();
850
851 aV3 -= aV1*(aV3.Dot(aV1)) + aV2*(aV3.Dot(aV2));
852 aV3.Normalize();
853
854 aTM.SetRows(aV1, aV2, aV3);
855
856 matrix = aTM;
857}