00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00020 #ifndef _SparseImage3D_hpp
00021 #define _SparseImage3D_hpp
00022
00023
00024 #include<ImLib3D/Image3D.hpp>
00025 #include<ImLib3D/BitImage3D.hpp>
00026 #include<boost/type_traits/arithmetic_traits.hpp>
00027 #include<ImLib3D/Zero.hpp>
00028
00029 #define UintToVect3Di(v) Vect3Di(v&((1<<10)-1),(v>>10)&((1<<10)-1),(v>>20)&((1<<10)-1))
00030 #define Vect3DiToUint(p) (p.x+(p.y<<10)+(p.z<<20))
00031
00032 class SparseImage3DBase;
00034
00037 class SparseStructure3D : public Streamable
00038 {
00039 friend void SparseImage3D_Test();
00041 int size;
00043 BitMask3D mask;
00044
00046 private:
00048 bool autoDestroy;
00049
00050
00052 mutable vector<SparseImage3DBase *> referencingImages;
00054 mutable bool suicideInProgress;
00055 public:
00056 void Reference(SparseImage3DBase *image) const {referencingImages.push_back(image);}
00057 bool Dereference(SparseImage3DBase *image) const ;
00059
00060 private:
00062 static vector<const SparseStructure3D *> allreadyExisting;
00063 mutable string name;
00064 public:
00065 void SetName(string _name){name=_name;}
00066 string Name() const {return name;}
00067 static const SparseStructure3D *Find(string sname);
00069 private:
00071 mutable bool valNbToPosOk;
00072 mutable vector<uint> valNbToPosIndex;
00073 void MakeValNbToPosIndex() const
00074 {
00075 valNbToPosOk=true;
00076 valNbToPosIndex.resize(size);
00077 int valNb=0;
00078 for(BitMask3D::const_iteratorXYZ p=mask.begin();p!=mask.end();++p)
00079 {
00080 if(*p)
00081 {
00082 valNbToPosIndex[valNb]=Vect3DiToUint(p);
00083 valNb++;
00084 }
00085 }
00086 }
00088
00090 mutable bool posToValNbOk;
00091 mutable Container3D<vector<uint> > xProjValNb;
00092 void MakePosToValNb() const
00093 {
00094 posToValNbOk=true;
00095 xProjValNb.Resize(Size3D(mask.Height(),mask.Depth(),1));
00096 if(!valNbToPosOk){MakeValNbToPosIndex();}
00097
00098
00099 LabelImage3D sizes(mask.Height(),mask.Depth(),1);
00100 sizes.Fill(0);
00101
00102 for(uint valNb=0;valNb<valNbToPosIndex.size();valNb++)
00103 {
00104 Vect3Di pos=UintToVect3Di(valNbToPosIndex[valNb]);
00105 sizes(pos.y,pos.z,0)++;
00106 }
00107
00108 for(LabelImage3D::iteratorXYZ p=sizes.begin();p!=sizes.end();++p)
00109 {
00110 xProjValNb(p.Pos()).resize(*p);
00111 }
00112
00113 sizes.Fill(0);
00114 for(uint valNb=0;valNb<valNbToPosIndex.size();valNb++)
00115 {
00116 Vect3Di pos=UintToVect3Di(valNbToPosIndex[valNb]);
00117 xProjValNb(pos.y,pos.z,0)[sizes(pos.y,pos.z,0)++]=valNb;
00118 }
00119 }
00121 public:
00122 void Read( ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL) ;
00123 void Write(ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL) const ;
00124 void WriteToFile (const string &fname) const {name=fname;Streamable::WriteToFile (fname);}
00125 void ReadFromFile(const string &fname) {name=fname;Streamable::ReadFromFile(fname);}
00126
00127 int ValSize() const {return size;}
00128 Size3D Size() const {return mask.Size();}
00129 const BitMask3D &Mask() const {return mask;}
00130
00131 Vect3Di valNbToPos(int valNb) const
00132 {
00133 if(!valNbToPosOk){MakeValNbToPosIndex();}
00134 return UintToVect3Di(valNbToPosIndex[valNb]);
00135 }
00136 int posToValNb(const Vect3Di &pos) const
00137 {
00138 if(!mask(pos)){return -1;}
00139 if(!posToValNbOk){MakePosToValNb();}
00140 const vector<uint> &proj=xProjValNb(pos.y,pos.z,0);
00141 vector<uint>::const_iterator p=proj.begin();
00142 for(p=proj.begin();p!=proj.end();++p){if((valNbToPosIndex[*p]&((1<<10)-1))==(uint)pos.x){return *p;}}
00143 ThrowError("SparseStructure3D::posToValNb, point in mask, but not xProjValNb");
00144 return -1;
00145 }
00146
00147 public:
00148 virtual ~SparseStructure3D();
00149
00150 public:
00151 static SparseStructure3D *Create(const string &name);
00152 static SparseStructure3D *Create(ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL);
00153 static SparseStructure3D *Create(const BitMask3D &_mask,bool _autoDestroy);
00154 private:
00155 void ComputeValSize()
00156 {
00157 size=0;
00158 for(BitMask3D::iteratorXYZ p=mask.begin();p!=mask.end();++p)
00159 {
00160 if(*p){size++;}
00161 }
00162 }
00163 SparseStructure3D();
00164 SparseStructure3D(BitMask3D _mask,bool _autoDestroy=false,int _size=-1);
00165 };
00166
00168 template<class ImageType,class _Ptr,class _Ref>
00169 class SIM3D_iteratorFast : public random_access_iterator<float,size_t>
00170 {
00171 typedef SIM3D_iteratorFast<ImageType,_Ptr,_Ref> _Self;
00172 public:
00173 ImageType *ima;
00174 _Ptr pos;
00175 public:
00176 void AssertBounds()
00177 {
00178 if(pos<ima->begin().pos || pos>=ima->end().pos)
00179 {
00180 ThrowError("iteratorFast: out of bounds:pos:%x begin:%x end:%x\n",pos,ima->begin().pos,ima->end().pos);
00181 }
00182 }
00183 inline _Ref operator*(){return *pos;}
00184 double Progress() const {if(!this){return 0;}return (_Self(ima,pos)-ima->begin())/(float)(ima->end()-ima->begin());}
00185 inline _Self operator++(int) {_Self __tmp=*this;pos++;return __tmp;}
00186 inline _Self &operator++() {pos++;return *this;}
00187 inline void operator+=(size_t m){pos+=m;}
00188 inline _Self operator+ (size_t m){_Self __tmp=*this;__tmp.pos+=m;return __tmp;}
00189 inline _Self operator- (size_t m){_Self __tmp=*this;__tmp.pos-=m;return __tmp;}
00190 inline _Self operator--(int) {_Self __tmp=*this;pos--;return __tmp;}
00191 inline _Self &operator--() {pos--;return *this;}
00192 inline void operator-=(size_t m){pos-=m;}
00193 inline int operator- (const _Self &other){return pos-other.pos;}
00194 inline bool operator< (const _Self &other){return pos< other.pos;}
00195 inline bool operator<=(const _Self &other){return pos<=other.pos;}
00196 inline bool operator> (const _Self &other){return pos> other.pos;}
00197 inline bool operator>=(const _Self &other){return pos>=other.pos;}
00198
00199 inline Vect3Di ComputePosition() const
00200 {
00201 return ima->sparseStructure->valNbToPos(pos-ima->begin().pos);
00202 }
00203 inline Vect3Di Pos() const
00204 {
00205 return ima->sparseStructure->valNbToPos(pos-ima->begin().pos);
00206 }
00207 inline bool operator!=(const _Self &other){return pos!=other.pos; }
00208 inline bool operator==(const _Self &other){return pos==other.pos; }
00209 SIM3D_iteratorFast():ima(NULL),pos(0){}
00210 SIM3D_iteratorFast(ImageType *_ima,_Ptr _pos):ima(_ima),pos(_pos){}
00211 };
00212
00213
00214
00215 class SparseImage3DBase : public Image3D
00216 {
00217 public:
00218 void Invalidate()
00219 {
00220 sparseStructure=NULL;
00221 }
00222 protected:
00223 const SparseStructure3D *sparseStructure;
00224 bool shareSparseStructureFile;
00225 void SetSparseStructure(const SparseStructure3D *_sparseStructure)
00226 {
00227 sparseStructure=_sparseStructure;sparseStructure->Reference(this);
00228 Resize(sparseStructure->Size());
00229 }
00230 SparseImage3DBase():Image3D(),sparseStructure(NULL),shareSparseStructureFile(false)
00231 {;}
00232 SparseImage3DBase(const SparseImage3DBase &other):
00233 Image3D(other),sparseStructure(NULL),shareSparseStructureFile(false)
00234 {
00235 SetSparseStructure(other.sparseStructure);
00236 }
00237 SparseImage3DBase(const SparseStructure3D *_sparseStructure):
00238 Image3D(_sparseStructure->Size()),
00239 sparseStructure(NULL),
00240 shareSparseStructureFile(false)
00241 {
00242 SetSparseStructure(_sparseStructure);
00243 }
00244 };
00245
00246
00248
00253 template<class Im3DValue>
00254 class SparseImage3D : public SparseImage3DBase
00255 {
00256 typedef SparseImage3D<Im3DValue> _Self;
00257
00258
00259 Im3DValue *imageData;
00260 Im3DValue *imageDataEnd;
00261 public:
00263 typedef Im3DValue value_type;
00264 public:
00266
00267 typedef SIM3D_iteratorFast< _Self, value_type *, value_type &> iteratorFast;
00268 typedef SIM3D_iteratorFast<const _Self,const value_type *,const value_type &> const_iteratorFast;
00269 typedef iteratorFast iterator;
00270 typedef iterator iteratorMasked;
00271 typedef iterator iteratorXYZ;
00272 typedef const_iteratorFast const_iterator;
00273 typedef const_iterator const_iteratorMasked;
00274 typedef const_iterator const_iteratorXYZ;
00275 friend class SIM3D_iteratorFast< _Self, value_type *, value_type &>;
00276 friend class SIM3D_iteratorFast<const _Self,const value_type *,const value_type &>;
00277 public:
00279
00280 iteratorFast begin() {return iteratorFast(this,imageData);}
00281 const_iteratorFast begin() const {return const_iteratorFast(this,imageData);}
00283 inline iteratorFast end() {return iteratorFast(this,imageDataEnd);}
00284 inline const_iteratorFast end() const {return const_iteratorFast(this,imageDataEnd);}
00285
00286 value_type zero;
00288 void InitZero()
00289 {
00290 ::SetZero<value_type>::Set(zero,true);
00291 }
00292
00293 value_type &Get(const Vect3Di &pos)
00294 {
00295 int valNb=sparseStructure->posToValNb(pos);
00296 return valNb<0 ? zero : imageData[valNb];
00297 }
00298 value_type Get(const Vect3Di &pos) const
00299 {
00300 int valNb=sparseStructure->posToValNb(pos);
00301 return valNb<0 ? zero : imageData[valNb];
00302 }
00303 public:
00304 inline value_type &operator()(int x,int y,int z) {return Get(Vect3Di(x,y,z));}
00305 inline value_type operator()(int x,int y,int z) const {return Get(Vect3Di(x,y,z));}
00306 inline value_type &operator()(const Vect3Di &pos) {return Get(pos);}
00307 inline value_type operator()(const Vect3Di &pos) const {return Get(pos);}
00308
00310 void Fill(const value_type &value){fill(begin(),end(),value);}
00311 template<class OtherImageType >
00312 void MaskedCopy(OtherImageType other){for(iterator p=begin();p!=end();++p){*p=other(p.Pos());}}
00313
00315 public:
00316 virtual string GetTypeName() const {return "SparseImage3D";}
00318
00323 virtual void Read( ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL) ;
00324 virtual void Write(ImLib3DFile *file,xmlpp::Element *parentNode=NULL,xmlpp::Element *node=NULL) const;
00325 public:
00327 virtual void WriteToFile (const string &fname) const {Streamable::WriteToFile(fname);}
00328 virtual void WriteToFile (const string &fname,bool _shareSparseStructureFile)
00329 {
00330 shareSparseStructureFile=_shareSparseStructureFile;
00331 Streamable::WriteToFile(fname);
00332 }
00334 public:
00335 void Resize(const Size3D &newSize);
00336 const value_type &GetZero() const {return zero;}
00337 void SetZero(const value_type& _zero) {zero=_zero;}
00338
00340 _Self& operator= (const _Self & other);
00341 bool operator==(const _Self & other) const;
00342 bool operator!=(const _Self & other) const {return !(this->operator==(other));}
00343 template<class OtherImage >
00344 bool operator== (const OtherImage & other){return Size()==other.Size() && equal(other.begin(),other.end(),begin());}
00345 template<class OtherImage >
00346 bool operator!= (const OtherImage & other){return !((*this)==other);}
00348
00349
00350 value_type SafeValue(int x,int y,int z) const
00351 {return IsInside(x,y,z) ? (*this)(x,y,z) : 0 ;}
00352 value_type SafeValue(const Vect3Di &v) const
00353 {return IsInside(v ) ? (*this)(v ) : 0 ;}
00354
00355
00356
00357
00359
00360 public:
00362 virtual ~SparseImage3D();
00363 private:
00364 void Allocate();
00365 public:
00366 SparseImage3D();
00367 explicit SparseImage3D(const string& fname):SparseImage3DBase(),imageData(NULL),imageDataEnd(NULL)
00368 {InitZero();ReadFromFile(fname);}
00369 explicit SparseImage3D(const char *fname): SparseImage3DBase(),imageData(NULL),imageDataEnd(NULL)
00370 {InitZero();ReadFromFile(fname);}
00371 explicit SparseImage3D(const SparseStructure3D *_sparseStructure);
00373 SparseImage3D(const SparseImage3D & origCont);
00375 };
00376
00377
00378 #include<ImLib3D/SparseImage3D.hxx>
00379
00380 typedef SparseImage3D<float> SparseImage3Df;
00381 #endif // _SparseImage3D_hpp