00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00021 #ifndef _BitImage3D_internal
00022 #error BitImage3DIterators should only be included by BitImage3D.hpp
00023 #endif
00024
00025
00026
00027
00028
00029
00030
00032 template<class BitImage3D,class _Ref>
00033 class BIM3D_iteratorFast
00034 {
00035 typedef BIM3D_iteratorFast<BitImage3D,_Ref> _Self;
00036 public:
00037 BitImage3D *ima;
00038 size_t pos;
00039 public:
00040 void AssertBounds()
00041 {
00042 if(pos<ima->begin().pos || pos>=ima->end().pos)
00043 {
00044 ThrowError("iteratorFast: out of bounds:pos:%x begin:%x end:%x\n",pos,ima->begin().pos,ima->end().pos);
00045 }
00046 }
00047 inline _Ref operator*(){return (*ima)(pos);}
00048 double Progress() const {if(!this){return 0;}return pos/(float)ima->GetNVoxels();}
00049 inline _Self operator++(int) {_Self __tmp=*this;pos++;return __tmp;}
00050 inline _Self &operator++() {pos++;return *this;}
00051 inline void operator+=(size_t m){pos+=m;}
00052 inline _Self operator+ (size_t m){_Self __tmp=*this;__tmp.pos+=m;return __tmp;}
00053 inline _Self operator- (size_t m){_Self __tmp=*this;__tmp.pos-=m;return __tmp;}
00054 inline _Self operator--(int) {_Self __tmp=*this;pos--;return __tmp;}
00055 inline _Self &operator--() {pos--;return *this;}
00056 inline void operator-=(size_t m){pos-=m;}
00057 inline int operator- (const _Self &other){return pos-other.pos;}
00058 inline bool operator< (const _Self &other){return pos< other.pos;}
00059 inline bool operator<=(const _Self &other){return pos<=other.pos;}
00060 inline bool operator> (const _Self &other){return pos> other.pos;}
00061 inline bool operator>=(const _Self &other){return pos>=other.pos;}
00062
00063 inline Vect3Di ComputePosition() const
00064 {
00065 size_t offset=pos;
00066 Vect3Di res;
00067 res.z=offset/(ima->Height()*ima->Width());
00068 offset=offset%(ima->Height()*ima->Width());
00069 res.y=offset/ima->Width();
00070 res.x=offset%ima->Width();
00071 return res;
00072 }
00073 void operator+=(const Vect3Di &dV)
00074 {
00075 pos+=dV.x+ima->Width()*dV.y+ima->Width()*ima->Height()*dV.z;
00076 }
00077 inline void operator=(const Vect3Di &P)
00078 {
00079 pos=P.x+ima->Width()*P.y+ima->Width()*ima->Height()*P.z;
00080 }
00081 inline bool operator!=(const _Self &other){return pos!=other.pos; }
00082 inline bool operator==(const _Self &other){return pos==other.pos; }
00083 BIM3D_iteratorFast():ima(NULL),pos(0){}
00084 BIM3D_iteratorFast(BitImage3D *_ima,size_t _pos):ima(_ima),pos(_pos){}
00085 };
00086
00088
00089 template<class BitImage3D,class _Ref>
00090 class BIM3D_iteratorXYZ : public BIM3D_iteratorFast<BitImage3D,_Ref>
00091 {
00092 typedef BIM3D_iteratorFast<BitImage3D,_Ref> _Base;
00093 typedef BIM3D_iteratorXYZ <BitImage3D,_Ref> _Self;
00094 void Reposition(){Vect3Di v=this->ComputePosition();x=v.x;y=v.y;z=v.z;}
00095 public:
00096 int x,y,z;
00097
00098 void AssertBounds()
00099 {
00100 if(!this->ima->IsInside(x,y,z) || this->pos>=this->ima->GetNVoxels())
00101 {
00102 ThrowError("iteratorXYZ: out of bounds %d %d %d: image %d %d %d :pos:%u end:%u\n",
00103 x,y,z,
00104 this->ima->Width(),this->ima->Height(),this->ima->Depth(),
00105 this->pos,this->ima->GetNVoxels());
00106 }
00107 }
00108
00109 inline _Self operator++(int){_Self __tmp=*this;++(*this);return __tmp;}
00110 inline _Self &operator++()
00111 {
00112 this->pos++;
00113 x++;
00114 if(x>=this->ima->Width())
00115 {
00116 x=0;
00117 y++;
00118 if(y>=this->ima->Height())
00119 {
00120 y=0;
00121 z++;
00122 }
00123 }
00124 return *this;
00125 }
00126 inline _Self operator--(int){_Self __tmp=*this;--(*this);return __tmp;}
00127 inline _Self &operator--()
00128 {
00129 this->pos--;
00130 x--;
00131 if(x<0)
00132 {
00133 x=this->ima->Width()-1;
00134 y--;
00135 if(y<0)
00136 {
00137 y=this->ima->Height()-1;
00138 z--;
00139 }
00140 }
00141 return *this;
00142 }
00144 inline Vect3Di V() const {return Vect3Di(x,y,z);}
00146 inline Vect3Di Pos() const {return Vect3Di(x,y,z);}
00147
00148 inline void operator=(const Vect3Di &P)
00149 {
00150 x=P.x;
00151 y=P.y;
00152 z=P.z;
00153 this->pos=x+y*this->ima->Width()+z*this->ima->Width()*this->ima->Height();
00154 }
00155
00156 inline void operator+=(size_t m){this->pos+=m;this->Rethis->position();}
00157 inline void operator-=(size_t m){this->pos-=m;this->Rethis->position();}
00158 inline _Self operator+ (size_t m){_Self __tmp=*this;__tmp.pos+=m;__tmp.Reposition();return __tmp;}
00159 inline _Self operator- (size_t m){_Self __tmp=*this;__tmp.pos-=m;__tmp.Reposition();return __tmp;}
00160
00161 void operator= (const BIM3D_iteratorFast<BitImage3D,_Ref> &other)
00162 {
00163 this->ima=other.ima;
00164 this->pos=other.pos;
00165 if(this->pos==0){x=0;y=0;z=0;}
00166 else{Reposition();}
00167 }
00168 BIM3D_iteratorXYZ():_Base(){;}
00169 BIM3D_iteratorXYZ(const BIM3D_iteratorFast<BitImage3D,_Ref> &other) : _Base(other)
00170 {
00171 operator=(other);
00172 }
00173 BIM3D_iteratorXYZ(BitImage3D *_ima,size_t _pos) : _Base(_ima,_pos)
00174 {
00175
00176 if(this->pos!=this->ima->GetData())
00177 {_Base::operator=(BIM3D_iteratorFast<BitImage3D,_Ref>(this->pos).ComputePosition(this->ima));}
00178 }
00179
00180 };
00181
00183
00184 template<class BitImage3D,class _Ref>
00185 class BIM3D_iteratorZone : public BIM3D_iteratorXYZ<BitImage3D,_Ref>
00186 {
00187 typedef BIM3D_iteratorFast <BitImage3D,_Ref> _BaseBase;
00188 typedef BIM3D_iteratorXYZ <BitImage3D,_Ref> _Base;
00189 typedef BIM3D_iteratorZone<BitImage3D,_Ref> _Self;
00190 public:
00191 RectZone3Di zone;
00192 double Progress(){return (this->pos-this->ima->GetData())/(float)zone.Volume();}
00193 void AssertBounds()
00194 {
00195 if(!this->ima->IsInside(this->x,this->y,this->z) || !this->zone.IsInside(this->x,this->y,this->z) ||
00196 this->pos<this->ima->GetData() || this->pos>=this->ima->GetData()+this->ima->GetNVoxels())
00197 {
00198 ThrowError("iteratorZone: out of bounds %d %d %d:zone:%d %d %d - %d %d %d: image %d %d %d : pos:%x begin:%x end:%x\n",
00199 this->x,this->y,this->z,
00200 zone.x0,zone.y0,zone.z0,
00201 zone.x1,zone.y1,zone.z1,
00202 this->ima->Width(),this->ima->Height(),this->ima->Depth(),
00203 this->pos,this->ima->GetData(),this->ima->GetData()+this->ima->GetNVoxels());
00204 }
00205 }
00206 inline _Self operator++(int){_Self __tmp=*this;++(*this);return __tmp;}
00207 inline _Self &operator++()
00208 {
00209 this->pos++;
00210 if(this->zone.ToNext(this->x,this->y,this->z))
00211 {
00212 if(this->zone.IsInside(this->x,this->y,this->z))
00213 {
00214 _BaseBase::operator=(Vect3Di(this->x,this->y,this->z));
00215 }
00216 else{this->pos=this->ima->GetNVoxels();}
00217 }
00218 return *this;
00219 }
00220 inline void operator--(int)
00221 {
00222 this->pos--;
00223 if(this->zone.ToPrev(this->x,this->y,this->z))
00224 {
00225 if(this->zone.IsInside(this->x,this->y,this->z))
00226 {
00227 _BaseBase::operator=(Vect3Di(this->x,this->y,this->z));
00228 }
00229 else{this->pos=NULL;}
00230 }
00231 }
00232
00233 inline void operator+=(size_t m){while (m--) operator++(0);}
00234 inline void operator-=(size_t m){while (m--) operator--(0);}
00235 inline _Self operator+ (size_t m){_Self __tmp=*this;__tmp+=m;return __tmp;}
00236 inline _Self operator- (size_t m){_Self __tmp=*this;__tmp-=m;return __tmp;}
00237
00238 void operator= (const BIM3D_iteratorFast<BitImage3D,_Ref> &other)
00239 {
00240 this->ima=other.ima;
00241 this->pos=other.pos;
00242 if(!this->ima->IsInside(zone.GetP0()) || !this->ima->IsInside(zone.GetP1()))
00243 {
00244 ThrowError("iteratorZone zone does not fit in image");
00245 }
00246
00247 if(this->pos==0){this->zone.ToStart(this->x,this->y,this->z);}
00248 else{_Base::operator=(other.ComputePosition());}
00249 _BaseBase::operator=(Vect3Di(this->x,this->y,this->z));
00250 }
00251 BIM3D_iteratorZone():_Base(){}
00252
00253
00254
00255
00256 BIM3D_iteratorZone(const RectZone3Di &_zone):
00257 _Base(),zone(_zone)
00258 {
00259 }
00260 };
00261
00262
00263
00264
00265