0030997: Foundation Classes - name correction of dump macros
[occt.git] / src / TopLoc / TopLoc_Location.cxx
CommitLineData
b311480e 1// Created on: 1991-01-21
2// Created by: Christophe MARION
3// Copyright (c) 1991-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#define No_Standard_NoSuchObject
18
42cf5bc1 19
20#include <gp_Trsf.hxx>
21#include <Standard_ConstructionError.hxx>
7fd59977 22#include <Standard_NoSuchObject.hxx>
0904aa63 23#include <Standard_Dump.hxx>
7fd59977 24#include <TopLoc_Datum3D.hxx>
7fd59977 25#include <TopLoc_ItemLocation.hxx>
42cf5bc1 26#include <TopLoc_Location.hxx>
27#include <TopLoc_SListOfItemLocation.hxx>
7fd59977 28
f24125b9 29static const gp_Trsf TheIdentity;
7fd59977 30
7fd59977 31//=======================================================================
32//function : TopLoc_Location
33//purpose : constructor Identity
34//=======================================================================
35
36TopLoc_Location::TopLoc_Location ()
37{
38}
39//=======================================================================
40//function : TopLoc_Location
41//purpose : constructor Datum
42//=======================================================================
43
44TopLoc_Location::TopLoc_Location (const Handle(TopLoc_Datum3D)& D)
45{
46 myItems.Construct(TopLoc_ItemLocation(D,1));
47}
48
49//=======================================================================
50//function : TopLoc_Location
51//purpose :
52//=======================================================================
53
54TopLoc_Location::TopLoc_Location(const gp_Trsf& T)
55{
56 Handle(TopLoc_Datum3D) D = new TopLoc_Datum3D(T);
57 myItems.Construct(TopLoc_ItemLocation(D,1));
58}
59
60//=======================================================================
61//function : Transformation
62//purpose :
63//=======================================================================
64
65const gp_Trsf& TopLoc_Location::Transformation() const
66{
ee6bb37b 67 if (IsIdentity())
7fd59977 68 return TheIdentity;
ee6bb37b 69 else
70 return myItems.Value().myTrsf;
7fd59977 71}
72
73TopLoc_Location::operator gp_Trsf() const
74{
75 return Transformation();
76}
77
78//=======================================================================
79//function : Inverted
80//purpose : return the inverse
81//=======================================================================
82
83TopLoc_Location TopLoc_Location::Inverted () const
84{
85 //
86 // the inverse of a Location is a chain in revert order
87 // with opposite powers and same Local
88 //
89 TopLoc_Location result;
90 TopLoc_SListOfItemLocation items = myItems;
91 while (items.More()) {
92 result.myItems.Construct(TopLoc_ItemLocation(items.Value().myDatum,
93 -items.Value().myPower));
94 items.Next();
95 }
96 return result;
97}
98
99//=======================================================================
100//function : Multiplied
101//purpose : operator *
102//=======================================================================
103
104TopLoc_Location TopLoc_Location::Multiplied(const TopLoc_Location& Other) const
105{
106 // prepend the chain Other in front of this
107 // cancelling null exponents
108
109 if (IsIdentity()) return Other;
110 if (Other.IsIdentity()) return *this;
111
112 // prepend the queue of Other
113 TopLoc_Location result = Multiplied(Other.NextLocation());
114 // does the head of Other cancel the head of result
115
116 Standard_Integer p = Other.FirstPower();
117 if (!result.IsIdentity()) {
118 if (Other.FirstDatum() == result.FirstDatum()) {
119 p += result.FirstPower();
120 result.myItems.ToTail();
121 }
122 }
123 if (p != 0)
124 result.myItems.Construct(TopLoc_ItemLocation(Other.FirstDatum(),p));
125 return result;
126}
127
128//=======================================================================
129//function : Divided
130//purpose : operator / this*Other.Inverted()
131//=======================================================================
132
133TopLoc_Location TopLoc_Location::Divided (const TopLoc_Location& Other) const
134{
135 return Multiplied(Other.Inverted());
136}
137
138//=======================================================================
139//function : Predivided
140//purpose : return Other.Inverted() * this
141//=======================================================================
142
143TopLoc_Location TopLoc_Location::Predivided (const TopLoc_Location& Other)
144 const
145{
146 return Other.Inverted().Multiplied(*this);
147}
148
149//=======================================================================
150//function : Powered
151//purpose : power elevation
152//=======================================================================
153
154TopLoc_Location TopLoc_Location::Powered (const Standard_Integer pwr) const
155{
ee6bb37b 156 if (IsIdentity()) return *this;
7fd59977 157 if (pwr == 1) return *this;
158 if (pwr == 0) return TopLoc_Location();
159
160 // optimisation when just one element
161 if (myItems.Tail().IsEmpty()) {
162 TopLoc_Location result;
163 result.myItems.Construct(TopLoc_ItemLocation(FirstDatum(),
164 FirstPower() * pwr));
165 return result;
166 }
167
168 if (pwr > 0) return Multiplied(Powered(pwr - 1));
169 else return Inverted().Powered(-pwr);
170}
171
172//=======================================================================
2b2be3fb 173// function : HashCode
174// purpose :
7fd59977 175//=======================================================================
2b2be3fb 176Standard_Integer TopLoc_Location::HashCode (const Standard_Integer theUpperBound) const
7fd59977 177{
178 // the HashCode computed for a Location is the bitwise exclusive or
179 // of values computed for each element of the list
180 // to compute this value, the depth of the element is computed
181 // the depth is the position of the element in the list
182 // this depth is multiplied by 3
183 // each element is an elementary Datum raised to a Power
184 // the Power is bitwise left shifted by depth
185 // this is added to the HashCode of the Datum
186 // this value is biwise rotated by depth
187 // the use of depth avoids getting the same result for two permutated lists.
188
2b2be3fb 189 Standard_Integer depth = 0;
190 unsigned int h = 0;
7fd59977 191 TopLoc_SListOfItemLocation items = myItems;
2b2be3fb 192 while (items.More())
193 {
7fd59977 194 depth += 3;
467e864a 195 unsigned int i = ::HashCode (items.Value().myDatum, theUpperBound);
196 const Standard_Integer aClampedDepth = depth % 32;
197 unsigned int j = ((i + items.Value().myPower) << aClampedDepth);
198 j = j >> (32 - aClampedDepth) | j << aClampedDepth;
7fd59977 199 h ^= j;
2b2be3fb 200 items.Next ();
7fd59977 201 }
2b2be3fb 202 return ::HashCode (h, theUpperBound);
7fd59977 203}
204
205//=======================================================================
206//function : IsEqual
207//purpose : operator ==
208//=======================================================================
209
210// two locations are Equal if the Items have the same LocalValues and Powers
211// this is a recursive function to test it
212
213Standard_Boolean TopLoc_Location::IsEqual (const TopLoc_Location& Other) const
214{
215 const void** p = (const void**) &myItems;
216 const void** q = (const void**) &Other.myItems;
217 if (*p == *q ) {return Standard_True ; }
218 if (IsIdentity() || Other.IsIdentity() ) {return Standard_False; }
219 if (FirstDatum() != Other.FirstDatum() ) {return Standard_False; }
220 if (FirstPower() != Other.FirstPower() ) {return Standard_False; }
221 else { return NextLocation() == Other.NextLocation();}
222}
223
224//=======================================================================
225//function : IsDifferent
226//purpose :
227//=======================================================================
228
229Standard_Boolean TopLoc_Location::IsDifferent
230 (const TopLoc_Location& Other) const
231{
232 return !IsEqual(Other);
233}
234
0904aa63 235//=======================================================================
236//function : DumpJson
237//purpose :
238//=======================================================================
239void TopLoc_Location::DumpJson (Standard_OStream& theOStream, const Standard_Integer theDepth) const
240{
3de0f784 241 OCCT_DUMP_CLASS_BEGIN (theOStream, TopLoc_Location);
0904aa63 242
3de0f784 243 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &Transformation());
244 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, IsIdentity());
0904aa63 245}
246
7fd59977 247//=======================================================================
248//function : ShallowDump
249//purpose :
250//=======================================================================
251
252void TopLoc_Location::ShallowDump(Standard_OStream& S) const
253{
254 S << "TopLoc_Location : ";
255 TopLoc_SListOfItemLocation items = myItems;
04232180 256 if (items.IsEmpty()) S << "Identity"<<std::endl;
7fd59977 257 while (items.More()) {
258 S<<"\n";
04232180 259 S << " Exponent : " << items.Value().myPower <<std::endl;
7fd59977 260 items.Value().myDatum->ShallowDump(S);
261 items.Next();
262 }
263 S << "\n";
264}
265
266