0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / gp / gp_GTrsf.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19
20 #define No_Standard_OutOfRange
21
22 #include <gp_GTrsf.ixx>
23 #include <gp_Mat.hxx>
24
25 void gp_GTrsf::SetTranslationPart (const gp_XYZ& Coord)
26 {
27   loc = Coord;
28   if (Form() == gp_CompoundTrsf || Form() == gp_Other || 
29       Form() == gp_Translation)   { }
30   else if (Form() == gp_Identity) { shape = gp_Translation; }
31   else                            { shape = gp_CompoundTrsf; }
32 }
33
34 void gp_GTrsf::Invert ()
35 {
36   if (shape == gp_Other) {
37     matrix.Invert() ;
38     loc.Multiply (matrix);
39     loc.Reverse();
40   }
41   else {
42     gp_Trsf T = Trsf();
43     T.Invert ();
44     SetTrsf (T);       
45   }
46 }
47
48 void gp_GTrsf::Multiply (const gp_GTrsf& T)
49 {
50   if (Form() == gp_Other || T.Form() == gp_Other) {
51     shape = gp_Other;
52     loc.Add (T.loc.Multiplied (matrix));
53     matrix.Multiply(T.matrix);
54   }
55   else {
56     gp_Trsf T1 = Trsf();
57     gp_Trsf T2 = T.Trsf();
58     T1.Multiply(T2);
59     matrix = T1.matrix;
60     loc = T1.loc;
61     scale = T1.scale;
62     shape = T1.shape;
63   }
64 }
65
66 void gp_GTrsf::Power (const Standard_Integer N)
67 {
68   if (N == 0)  {
69     scale = 1.;
70     shape = gp_Identity;
71     matrix.SetIdentity();
72     loc = gp_XYZ (0.,0.,0.);
73   }
74   else if (N == 1) { }
75   else if (N == -1) { Invert(); }
76   else {
77     if (shape == gp_Other) {
78       Standard_Integer Npower = N;
79       if (Npower < 0) Npower = - Npower;
80       Npower--;
81       gp_XYZ Temploc = loc;
82 //      Standard_Real Tempscale = scale;
83       gp_Mat Tempmatrix (matrix);
84       for(;;) {
85         if (IsOdd(Npower)) {
86           loc.Add (Temploc.Multiplied (matrix));
87           matrix.Multiply (Tempmatrix);
88         }
89         if (Npower == 1) { break; }
90         Temploc.Add (Temploc.Multiplied (Tempmatrix));
91         Tempmatrix.Multiply (Tempmatrix);
92         Npower = Npower/2;
93       }
94     }
95     else {
96       gp_Trsf T = Trsf ();
97       T.Power (N);
98       SetTrsf (T);
99     }
100   }
101 }
102
103 void gp_GTrsf::PreMultiply (const gp_GTrsf& T)
104 {
105   if (Form() == gp_Other || T.Form() == gp_Other) {
106     shape = gp_Other;
107     loc.Multiply (T.matrix);
108     loc.Add (T.loc);
109     matrix.PreMultiply(T.matrix);
110   }
111   else {
112     gp_Trsf T1 = Trsf();
113     gp_Trsf T2 = T.Trsf();
114     T1.PreMultiply(T2);
115     matrix = T1.matrix;
116     loc = T1.loc;
117     scale = T1.scale;
118     shape = T1.shape;
119   }
120 }
121
122 void gp_GTrsf::SetForm()
123 {
124   Standard_Real tol = 1.e-12; // Precision::Angular();
125   //
126   // don t trust the initial values !
127   //
128   gp_Mat M(matrix);
129   Standard_Real s = M.Determinant();
130   Standard_Real As = s;
131   if (As < 0) As = - As;
132   Standard_ConstructionError_Raise_if
133     (As < gp::Resolution(),"gp_GTrsf::SetForm, null determinant");
134   if (s > 0)
135     s = Pow(s,1./3.);
136   else
137     s = -Pow(-s,1./3.);
138   M.Divide(s);
139   
140   // check if the matrix is an uniform matrix
141   // the transposition should be the invert.
142   gp_Mat TM(M);
143   TM.Transpose();
144   TM.Multiply(M);
145   gp_Mat anIdentity ;
146   anIdentity.SetIdentity() ;
147   TM.Subtract(anIdentity);
148   if (shape==gp_Other) shape = gp_CompoundTrsf;
149
150   Standard_Integer i, j;
151   for (i=1; i<=3; i++) {
152     for (j=1; j<=3; j++) {
153       As = TM.Value(i,j);
154       if (As < 0) As = - As;
155       if (As > tol) {
156         shape = gp_Other;
157         return;
158       }
159     }
160   }
161 }