0031313: Foundation Classes - Dump improvement for classes
[occt.git] / src / gp / gp_GTrsf.cxx
1 // Copyright (c) 1995-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 #define No_Standard_OutOfRange
16
17
18 #include <gp_Ax1.hxx>
19 #include <gp_Ax2.hxx>
20 #include <gp_GTrsf.hxx>
21 #include <gp_Mat.hxx>
22 #include <gp_Trsf.hxx>
23 #include <gp_XYZ.hxx>
24 #include <Standard_ConstructionError.hxx>
25 #include <Standard_Dump.hxx>
26 #include <Standard_OutOfRange.hxx>
27
28 void gp_GTrsf::SetTranslationPart (const gp_XYZ& Coord)
29 {
30   loc = Coord;
31   if (Form() == gp_CompoundTrsf || Form() == gp_Other || 
32       Form() == gp_Translation)   { }
33   else if (Form() == gp_Identity) { shape = gp_Translation; }
34   else                            { shape = gp_CompoundTrsf; }
35 }
36
37 void gp_GTrsf::Invert ()
38 {
39   if (shape == gp_Other) {
40     matrix.Invert() ;
41     loc.Multiply (matrix);
42     loc.Reverse();
43   }
44   else {
45     gp_Trsf T = Trsf();
46     T.Invert ();
47     SetTrsf (T);       
48   }
49 }
50
51 void gp_GTrsf::Multiply (const gp_GTrsf& T)
52 {
53   if (Form() == gp_Other || T.Form() == gp_Other) {
54     shape = gp_Other;
55     loc.Add (T.loc.Multiplied (matrix));
56     matrix.Multiply(T.matrix);
57   }
58   else {
59     gp_Trsf T1 = Trsf();
60     gp_Trsf T2 = T.Trsf();
61     T1.Multiply(T2);
62     matrix = T1.matrix;
63     loc = T1.loc;
64     scale = T1.scale;
65     shape = T1.shape;
66   }
67 }
68
69 void gp_GTrsf::Power (const Standard_Integer N)
70 {
71   if (N == 0)  {
72     scale = 1.;
73     shape = gp_Identity;
74     matrix.SetIdentity();
75     loc = gp_XYZ (0.,0.,0.);
76   }
77   else if (N == 1) { }
78   else if (N == -1) { Invert(); }
79   else {
80     if (shape == gp_Other) {
81       Standard_Integer Npower = N;
82       if (Npower < 0) Npower = - Npower;
83       Npower--;
84       gp_XYZ Temploc = loc;
85 //      Standard_Real Tempscale = scale;
86       gp_Mat Tempmatrix (matrix);
87       for(;;) {
88         if (IsOdd(Npower)) {
89           loc.Add (Temploc.Multiplied (matrix));
90           matrix.Multiply (Tempmatrix);
91         }
92         if (Npower == 1) { break; }
93         Temploc.Add (Temploc.Multiplied (Tempmatrix));
94         Tempmatrix.Multiply (Tempmatrix);
95         Npower = Npower/2;
96       }
97     }
98     else {
99       gp_Trsf T = Trsf ();
100       T.Power (N);
101       SetTrsf (T);
102     }
103   }
104 }
105
106 void gp_GTrsf::PreMultiply (const gp_GTrsf& T)
107 {
108   if (Form() == gp_Other || T.Form() == gp_Other) {
109     shape = gp_Other;
110     loc.Multiply (T.matrix);
111     loc.Add (T.loc);
112     matrix.PreMultiply(T.matrix);
113   }
114   else {
115     gp_Trsf T1 = Trsf();
116     gp_Trsf T2 = T.Trsf();
117     T1.PreMultiply(T2);
118     matrix = T1.matrix;
119     loc = T1.loc;
120     scale = T1.scale;
121     shape = T1.shape;
122   }
123 }
124
125 void gp_GTrsf::SetForm()
126 {
127   Standard_Real tol = 1.e-12; // Precision::Angular();
128   //
129   // don t trust the initial values !
130   //
131   gp_Mat M(matrix);
132   Standard_Real s = M.Determinant();
133
134   if ( Abs(s) < gp::Resolution() )
135     throw Standard_ConstructionError("gp_GTrsf::SetForm, null determinant");
136
137   if (s > 0)
138     s = Pow(s,1./3.);
139   else
140     s = -Pow(-s,1./3.);
141   M.Divide(s);
142   
143   // check if the matrix is an uniform matrix
144   // the transposition should be the invert.
145   gp_Mat TM(M);
146   TM.Transpose();
147   TM.Multiply(M);
148   gp_Mat anIdentity ;
149   anIdentity.SetIdentity() ;
150   TM.Subtract(anIdentity);
151   if (shape==gp_Other) shape = gp_CompoundTrsf;
152
153   for (Standard_Integer i = 1; i <= 3; i++)
154     for (Standard_Integer j = 1; j <= 3; j++)
155       if ( Abs( TM.Value(i, j) ) > tol )
156       {
157         shape = gp_Other;
158         return;
159       }
160 }
161
162 //=======================================================================
163 //function : DumpJson
164 //purpose  : 
165 //=======================================================================
166 void gp_GTrsf::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
167 {
168   OCCT_DUMP_CLASS_BEGIN (theOStream, gp_GTrsf)
169
170   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &matrix)
171   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &loc)
172
173   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, shape)
174   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, scale)
175 }