// File: TopLoc_Location.cxx // Created: Mon Jan 21 15:58:46 1991 // Author: Christophe MARION // #define No_Standard_NoSuchObject #include #include #include #include #include #include #include const static gp_Trsf TheIdentity; static Standard_Boolean IsInternalIdentity(const TopLoc_Location& loc) { if (loc.IsIdentity()) { return Standard_True; } // if (loc.FirstDatum()->Transformation().Form() == gp_Identity) { // return Standard_True; // } return Standard_False; } //======================================================================= //function : TopLoc_Location //purpose : constructor Identity //======================================================================= TopLoc_Location::TopLoc_Location () { } //======================================================================= //function : TopLoc_Location //purpose : constructor Datum //======================================================================= TopLoc_Location::TopLoc_Location (const Handle(TopLoc_Datum3D)& D) { myItems.Construct(TopLoc_ItemLocation(D,1)); } //======================================================================= //function : TopLoc_Location //purpose : //======================================================================= TopLoc_Location::TopLoc_Location(const gp_Trsf& T) { Handle(TopLoc_Datum3D) D = new TopLoc_Datum3D(T); myItems.Construct(TopLoc_ItemLocation(D,1)); } //======================================================================= //function : Transformation //purpose : //======================================================================= const gp_Trsf& TopLoc_Location::Transformation() const { if (IsInternalIdentity(*this)) return TheIdentity; else { if (myItems.Value().myTrsf == NULL) { TopLoc_ItemLocation *I = (TopLoc_ItemLocation*) (void*) &this->myItems.Value(); // CLE if (I->myTrsf == NULL) I->myTrsf = new gp_Trsf; *(I->myTrsf) = I->myDatum->Transformation(); I->myTrsf->Power(I->myPower); I->myTrsf->PreMultiply(NextLocation().Transformation()); } return *(myItems.Value().myTrsf); } } TopLoc_Location::operator gp_Trsf() const { return Transformation(); } //======================================================================= //function : Inverted //purpose : return the inverse //======================================================================= TopLoc_Location TopLoc_Location::Inverted () const { // // the inverse of a Location is a chain in revert order // with opposite powers and same Local // TopLoc_Location result; TopLoc_SListOfItemLocation items = myItems; while (items.More()) { result.myItems.Construct(TopLoc_ItemLocation(items.Value().myDatum, -items.Value().myPower)); items.Next(); } return result; } //======================================================================= //function : Multiplied //purpose : operator * //======================================================================= TopLoc_Location TopLoc_Location::Multiplied(const TopLoc_Location& Other) const { // prepend the chain Other in front of this // cancelling null exponents if (IsIdentity()) return Other; if (Other.IsIdentity()) return *this; // prepend the queue of Other TopLoc_Location result = Multiplied(Other.NextLocation()); // does the head of Other cancel the head of result Standard_Integer p = Other.FirstPower(); if (!result.IsIdentity()) { if (Other.FirstDatum() == result.FirstDatum()) { p += result.FirstPower(); result.myItems.ToTail(); } } if (p != 0) result.myItems.Construct(TopLoc_ItemLocation(Other.FirstDatum(),p)); return result; } //======================================================================= //function : Divided //purpose : operator / this*Other.Inverted() //======================================================================= TopLoc_Location TopLoc_Location::Divided (const TopLoc_Location& Other) const { return Multiplied(Other.Inverted()); } //======================================================================= //function : Predivided //purpose : return Other.Inverted() * this //======================================================================= TopLoc_Location TopLoc_Location::Predivided (const TopLoc_Location& Other) const { return Other.Inverted().Multiplied(*this); } //======================================================================= //function : Powered //purpose : power elevation //======================================================================= TopLoc_Location TopLoc_Location::Powered (const Standard_Integer pwr) const { if (IsInternalIdentity(*this)) return *this; if (pwr == 1) return *this; if (pwr == 0) return TopLoc_Location(); // optimisation when just one element if (myItems.Tail().IsEmpty()) { TopLoc_Location result; result.myItems.Construct(TopLoc_ItemLocation(FirstDatum(), FirstPower() * pwr)); return result; } if (pwr > 0) return Multiplied(Powered(pwr - 1)); else return Inverted().Powered(-pwr); } //======================================================================= //function : HashCode //purpose : //======================================================================= Standard_Integer TopLoc_Location::HashCode(const Standard_Integer upper) const { // the HashCode computed for a Location is the bitwise exclusive or // of values computed for each element of the list // to compute this value, the depth of the element is computed // the depth is the position of the element in the list // this depth is multiplied by 3 // each element is an elementary Datum raised to a Power // the Power is bitwise left shifted by depth // this is added to the HashCode of the Datum // this value is biwise rotated by depth // the use of depth avoids getting the same result for two permutated lists. Standard_Integer depth = 0; unsigned int h = 0; TopLoc_SListOfItemLocation items = myItems; while (items.More()) { depth += 3; unsigned int i = items.Value().myDatum->HashCode(upper); unsigned int j = ( (i + items.Value().myPower) <>(32-depth) | j<ShallowDump(S); items.Next(); } S << "\n"; }