0025194: It is necessary to orthogonalize transformation matrix in gp_Trsf and gp_Trs...
[occt.git] / src / BinTools / BinTools_LocationSet.cxx
CommitLineData
b311480e 1// Created on: 2004-06-15
2// Created by: Sergey ZARITCHNY
973c2be1 3// Copyright (c) 2004-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
16#include <BinTools_LocationSet.ixx>
17#include <BinTools.hxx>
18#include <gp_Ax3.hxx>
19#include <gp_Vec.hxx>
20#include <Precision.hxx>
21#include <Standard_ErrorHandler.hxx>
22
23//=======================================================================
24//function : operator >> (gp_Trsf& T)
25//purpose :
26//=======================================================================
27static Standard_IStream& operator >>(Standard_IStream& IS, gp_Trsf& T)
28{
29 Standard_Real V1[3],V2[3],V3[3];
30 Standard_Real V[3];
31
32 BinTools::GetReal(IS, V1[0]);
33 BinTools::GetReal(IS, V1[1]);
34 BinTools::GetReal(IS, V1[2]);
35 BinTools::GetReal(IS, V[0]);
36
37 BinTools::GetReal(IS, V2[0]);
38 BinTools::GetReal(IS, V2[1]);
39 BinTools::GetReal(IS, V2[2]);
40 BinTools::GetReal(IS, V[1]);
41
42 BinTools::GetReal(IS, V3[0]);
43 BinTools::GetReal(IS, V3[1]);
44 BinTools::GetReal(IS, V3[2]);
45 BinTools::GetReal(IS, V[2]);
46
47 T.SetValues(V1[0],V1[1],V1[2],V[0],
48 V2[0],V2[1],V2[2],V[1],
7a8c6a36 49 V3[0],V3[1],V3[2],V[2]);
7fd59977 50 return IS;
51}
52
53//=======================================================================
54//function : operator << (gp_Trsf& T)
55//purpose :
56//=======================================================================
57static Standard_OStream& operator <<(Standard_OStream& OS,const gp_Trsf& T)
58{
59 gp_XYZ V = T.TranslationPart();
60 gp_Mat M = T.VectorialPart();
61
62 BinTools::PutReal(OS, M(1,1));
63 BinTools::PutReal(OS, M(1,2));
64 BinTools::PutReal(OS, M(1,3));
65 BinTools::PutReal(OS,V.Coord(1));
66
67 BinTools::PutReal(OS, M(2,1));
68 BinTools::PutReal(OS, M(2,2));
69 BinTools::PutReal(OS, M(2,3));
70 BinTools::PutReal(OS,V.Coord(2));
71
72 BinTools::PutReal(OS, M(3,1));
73 BinTools::PutReal(OS, M(3,2));
74 BinTools::PutReal(OS, M(3,3));
75 BinTools::PutReal(OS,V.Coord(3));
76
77 return OS;
78}
79
80//=======================================================================
81//function : BinTools_LocationSet
82//purpose :
83//=======================================================================
84
85BinTools_LocationSet::BinTools_LocationSet()
86{
87}
88
89
90//=======================================================================
91//function : Clear
92//purpose :
93//=======================================================================
94
95void BinTools_LocationSet::Clear()
96{
97 myMap.Clear();
98}
99
100
101//=======================================================================
102//function : Add
103//purpose :
104//=======================================================================
105
106Standard_Integer BinTools_LocationSet::Add(const TopLoc_Location& L)
107{
108 if (L.IsIdentity()) return 0;
109 Standard_Integer n = myMap.FindIndex(L);
110 if (n > 0) return n;
111 TopLoc_Location N = L;
112 do {
113 myMap.Add(N.FirstDatum());
114 N = N.NextLocation();
115 } while (!N.IsIdentity());
116 return myMap.Add(L);
117}
118
119
120//=======================================================================
121//function : Location
122//purpose :
123//=======================================================================
124
125const TopLoc_Location& BinTools_LocationSet::Location
126 (const Standard_Integer I)const
127{
128 static TopLoc_Location identity;
129 if (I == 0) return identity;
130 else return myMap(I);
131}
132
133
134//=======================================================================
135//function : Index
136//purpose :
137//=======================================================================
138
139Standard_Integer BinTools_LocationSet::Index(const TopLoc_Location& L) const
140{
141 if (L.IsIdentity()) return 0;
142 return myMap.FindIndex(L);
143}
144
145//=======================================================================
146//function : NbLocations
147//purpose :
148//=======================================================================
149
150Standard_Integer BinTools_LocationSet::NbLocations() const
151{
152 return myMap.Extent();
153}
154
155//=======================================================================
156//function : Write locations
157//purpose :
158//=======================================================================
159
160void BinTools_LocationSet::Write(Standard_OStream& OS) const
161{
162
163 Standard_Integer i, nbLoc = myMap.Extent();
164 OS << "Locations "<< nbLoc <<endl;
165 try {
166 OCC_CATCH_SIGNALS
167 for (i = 1; i <= nbLoc; i++) {
168 TopLoc_Location L = myMap(i);
169
170 TopLoc_Location L2 = L.NextLocation();
171 Standard_Boolean simple = L2.IsIdentity();
172 Standard_Integer p = L.FirstPower();
173 TopLoc_Location L1 = L.FirstDatum();
174 Standard_Boolean elementary = (simple && p == 1);
175 if (elementary) {
176
177 OS.put((Standard_Byte)1); // 1
178 OS << L.Transformation();
179 }
180 else {
181 OS.put((Standard_Byte)2); // 2
182 BinTools::PutInteger(OS, myMap.FindIndex(L1));
183 BinTools::PutInteger(OS, p);
184 while (!L2.IsIdentity()) {
185 L1 = L2.FirstDatum();
186 p = L2.FirstPower();
187 L2 = L2.NextLocation();
188 BinTools::PutInteger(OS, myMap.FindIndex(L1));
189 BinTools::PutInteger(OS, p);
190 }
191
192 BinTools::PutInteger(OS, 0);
193 }
194 }
195 }
196 catch(Standard_Failure) {
197 Standard_SStream aMsg;
198 aMsg << "EXCEPTION in BinTools_LocatioSet::Write(..)" << endl;
199 Handle(Standard_Failure) anExc = Standard_Failure::Caught();
200 aMsg << anExc << endl;
201 Standard_Failure::Raise(aMsg);
202 }
203}
204
205//=======================================================================
206//function : Read
207//purpose :
208//=======================================================================
209void BinTools_LocationSet::Read(Standard_IStream& IS)
210{
211
212 myMap.Clear();
213 char buffer[255];
214 Standard_Integer l1,p;
215
216 IS >> buffer;
217 if (IS.fail() || (strcmp(buffer,"Locations"))) {
218 Standard_SStream aMsg;
219 aMsg << "BinTools_LocationSet::Read: Not a location table"<<endl;
220 Standard_Failure::Raise(aMsg);
221 return;
222 }
223
224 Standard_Integer i, nbLoc;
225 IS >> nbLoc;
226 IS.get();// remove lf
227 TopLoc_Location L;
228 gp_Trsf T;
229
230 try {
231 OCC_CATCH_SIGNALS
232 for (i = 1; i <= nbLoc; i++) {
233
8263fcd3 234 const Standard_Byte aTypLoc = (Standard_Byte)IS.get();
7fd59977 235 if (aTypLoc == 1) {
236 IS >> T;
237 L = T;
238 }
239
240 else if (aTypLoc == 2) {
241 L = TopLoc_Location();
242 BinTools::GetInteger(IS, l1); //Index
243 while (l1 != 0) {
244 BinTools::GetInteger(IS, p);
245 TopLoc_Location L1 = myMap(l1);
246 L = L1.Powered(p) *L;
247 BinTools::GetInteger(IS, l1);
248 }
249 } else {
250 Standard_SStream aMsg;
251 aMsg << "Unexpected location's type = " << aTypLoc << endl;
252 Standard_Failure::Raise(aMsg);
253 }
254 if (!L.IsIdentity()) myMap.Add(L);
255 }
256 }
257 catch(Standard_Failure) {
258 Standard_SStream aMsg;
259 aMsg << "EXCEPTION in BinTools_LocationSet::Read(..)" << endl;
260 Handle(Standard_Failure) anExc = Standard_Failure::Caught();
261 aMsg << anExc << endl;
262 Standard_Failure::Raise(aMsg);
263 }
264}