00001 #ifndef _HOBJ_H_
00002 #define _HOBJ_H_
00003
00004 #include <iostream>
00005
00006 #include "EntityAttributes.hpp"
00007
00014 class hHybridMesh;
00016
00017
00018
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00050 class hObj
00051 {
00052 public:
00054 static const int nTypes = 8;
00055 static const EntityAttributes eTable[nTypes];
00056
00057
00058
00059 inline static ID makeId(const uTind posId,const uTind typeId) { return ID(posId + (typeId<<29)); }
00060 inline static uTind posFromId(const ID id) {return ((id<<3)>>3); }
00061 inline static uTind typeFromId(const ID id) { return (id>>29); }
00062 inline static ID maxId() { return std::numeric_limits<ID>::max(); }
00063 inline static ID maxPos() { return posFromId(maxId()); }
00064 inline static ID maxType(){ return typeFromId(maxId()); }
00065
00066 static const int8_t delMark=-4,
00067 derefMark = -3,
00068 nothingMark=0,
00069 partialRefMark = -1,
00070 fullRefMark = -2;
00071
00073 protected: hObj(const uTind posID,const EntityAttributes & typeSpecyfic);
00074 public: ~hObj();
00075
00076 bool operator==(const hObj & other) const { return id_ == other.id_; }
00077 operator const EntityAttributes() const;
00078
00079 hObj* next() { return reinterpret_cast<hObj*>((reinterpret_cast<BYTE*>(this)+this->mySize_)); }
00080 const hObj* next() const { return reinterpret_cast<const hObj*>((reinterpret_cast<const BYTE*>(this)+this->mySize_)); }
00081 inline int nCurrentSons() const { return nMyClassSons_ + nOtherSons_; }
00082
00083 bool isBroken() const { return nMyClassSons_ > 0;}
00084 bool isMarkedBreak() const { return nMyClassSons_ == fullRefMark;}
00085 bool isMarkedDref() const { return nMyClassSons_ == derefMark;}
00086 bool isSliceBroken() const { return (isBroken() && nMyClassSons_ < 8); }
00087 bool isNull() const { return (mySize_==0); }
00088
00089 void mark2Ref(hHybridMesh* myMesh,const int refType=8);
00090 void mark2Dref(hHybridMesh* myMesh);
00091 void mark2Del(hHybridMesh* myMesh);
00092 int hBreak(hHybridMesh* myMesh,const Tind sonsCount=8);
00093 void derefine(hHybridMesh* myMesh);
00094 bool test(const hHybridMesh* myMesh) const;
00095 double* geoCenter(const hHybridMesh *myMesh, double center[3]) const;
00096 bool equals(const hObj& other,bool compareBreak=false) const ;
00097
00098
00099
00100 template < class T >
00101 T* getMyClassChild(const int number)
00102 {
00103 assert( static_cast<int>(nMyClassSons_) > number);
00104 T* child(reinterpret_cast<T*>(next()));
00105 assert(child->type_ == T::myType);
00106 for(int i(number-1);i>=0;--i) {
00107 do {
00108 child = reinterpret_cast<T*>(child->next());
00109 assert(child->type_ == T::myType);
00110 } while (child->level_!= this->level_+1);
00111 }
00112 assert(child->parent_ == this->id_);
00113 assert(child->level_ == this->level_+1);
00114 return child;
00115 }
00116
00117 template < class T >
00118 const T* getMyClassChild(const int number) const
00119 {
00120 assert( static_cast<int>(nMyClassSons_) > number);
00121 const T* child(reinterpret_cast<const T*>(next()));
00122 assert(child->type_ == T::myType);
00123
00124 for(int i(number-1);i>=0;--i) {
00125 do {
00126 child = reinterpret_cast<const T*>(child->next());
00127 assert(child->type_ == T::myType);
00128 } while (child->level_!= this->level_+1);
00129 }
00130 assert(child->parent_ == this->id_);
00131 assert(child->level_ == this->level_+1);
00132 return child;
00133 }
00134
00135 bool isAtBoundary() const
00136 {
00137 if(type_ == 0)
00138 {
00139 return (nOtherSons_==1);
00140 }
00141 else throw "setAtBoundary: This function works only for vertex!";
00142 }
00143 void setAtBoundary(const bool atBoundary)
00144 {
00145 if(type_== 0)
00146 {
00147 nOtherSons_ = ( atBoundary ? 1 : 0 );
00148 }
00149 else throw "setAtBoundary: This function works only for vertex!";
00150 }
00151 bool operator< (const hObj & other) const
00152 {
00153 register uTind i(0);
00154 while((components(i) == other.components(i)) && (i<typeSpecyfic_.nComponents_))
00155 ++i;
00156
00157 return (components(i) < other.components(i));
00158 }
00159
00160 friend std::ostream& operator<<(std::ostream& os,const hObj & obj);
00161
00162 void print() const;
00163
00164 static bool comparePtrs(const hObj * me, const hObj * other)
00165 {
00166 return me->operator<(*other);
00167 }
00168
00169 void updatePointers()
00170 {
00171 nodes_ = reinterpret_cast<ID*>( this+1 );
00172 }
00173
00174
00175
00176 inline const ID& verts(const uTind i) const { assert(i < typeSpecyfic_.nVerts_); return nodes_[i];}
00177
00178
00179 inline const ID* verts() const { assert( typeSpecyfic_.nVerts_ > 0); return nodes_;}
00180 void swapVerts(const int v1,const int v2) ;
00181
00182 inline ID& components(const uTind i) { assert(i < typeSpecyfic_.nComponents_); return nodes_[typeSpecyfic_.compOffset_+i];}
00183 inline const ID& components(const uTind i)const { assert(i < typeSpecyfic_.nComponents_); return nodes_[typeSpecyfic_.compOffset_+i];}
00184 inline ID* components() { assert( typeSpecyfic_.nComponents_ > 0); return nodes_+typeSpecyfic_.compOffset_;}
00185 inline const ID* components() const { assert( typeSpecyfic_.nComponents_ > 0); return nodes_+typeSpecyfic_.compOffset_;}
00186 inline int& flags(const uTind i) { assert(i < typeSpecyfic_.nFlags_); return reinterpret_cast<int*>(nodes_+typeSpecyfic_.flagOffset_)[i];}
00187 inline const int& flags(const uTind i) const { assert(i < typeSpecyfic_.nFlags_); return reinterpret_cast<const int*>(nodes_+typeSpecyfic_.flagOffset_)[i];}
00188 inline int* flags() { assert( typeSpecyfic_.nFlags_ > 0); return reinterpret_cast<int*>(nodes_+typeSpecyfic_.flagOffset_);}
00189 inline const int* flags() const { assert( typeSpecyfic_.nFlags_ > 0); return reinterpret_cast<const int*>(nodes_+typeSpecyfic_.flagOffset_);}
00190 inline ID& neighs(const uTind i) { assert(i < typeSpecyfic_.nNeighs_); return nodes_[typeSpecyfic_.neighOffset_+i]; }
00191 inline const ID& neighs(const uTind i) const { assert(i < typeSpecyfic_.nNeighs_); return nodes_[typeSpecyfic_.neighOffset_+i]; }
00192 inline ID* neighs() { assert( typeSpecyfic_.nNeighs_ > 0); return nodes_+typeSpecyfic_.neighOffset_;}
00193 inline const ID* neighs() const { assert( typeSpecyfic_.nNeighs_ > 0); return nodes_+typeSpecyfic_.neighOffset_;}
00194 inline ID& sons(const uTind i) { assert(i < typeSpecyfic_.nSons_); return nodes_[typeSpecyfic_.sonsOffset_+i]; }
00195 inline const ID& sons(const uTind i) const { assert(i < typeSpecyfic_.nSons_); return nodes_[typeSpecyfic_.sonsOffset_+i]; }
00196 inline ID* sons() { assert( typeSpecyfic_.nSons_ > 0); return nodes_+typeSpecyfic_.sonsOffset_;}
00197 inline const ID* sons() const { assert( typeSpecyfic_.nSons_ > 0); return nodes_+typeSpecyfic_.sonsOffset_;}
00198
00199
00200
00201 inline void incRef() { ++nRefs; }
00202 inline void decRef(hHybridMesh* myMesh) {
00203 --nRefs;
00204
00205 if(nRefs < 1) {
00206 mark2Del(myMesh);
00207 }
00208 }
00209
00211 union {
00212 ID id_;
00213 struct{ ID pos_:29,type_:3;};
00214 };
00215 ID parent_;
00216 uint8_t mySize_;
00217 int8_t level_,
00218 nMyClassSons_,
00219 nOtherSons_,
00220 nRefs;
00221
00222 #ifdef TURBULENTFLOW
00223 double dist2bound_;
00224 ID nearstFace_;
00225 double planeCoords_[4];
00226 #endif
00227
00228 EntityAttributes const & typeSpecyfic_;
00229 protected:
00230 void updateHash(hHybridMesh * myMesh) const;
00231
00232 ID * nodes_;
00233
00234 private:
00235 hObj(const hObj & other);
00236 hObj & operator=(const hObj & other);
00237 };
00238
00239 std::ostream& operator<<(std::ostream & os, const hObj & obj);
00240
00241 typedef hObj Face;
00242 typedef hObj Elem;
00243
00245 #endif // _HOBJ_H_