Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

SparseImage3D.hpp

Go to the documentation of this file.
00001 /* ImLib3D
00002  * Copyright (c) 2001, ULP-IPB Strasbourg.
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or (at
00007  * your option) any later version.
00008  * 
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  * 
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 //      //! number of times this object is used. when it goes down to zero, it should delete itself
00050 //      mutable int refCount;
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         // we want each vector in xProjValNb to be of exact good size
00098         // so first find exact sizes
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         // now correctly resize each one
00108         for(LabelImage3D::iteratorXYZ p=sizes.begin();p!=sizes.end();++p)
00109         {
00110             xProjValNb(p.Pos()).resize(*p);
00111         }
00112         // finally fill in xProjValNb, using sizes as a counter
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//, public ArithmeticOperators<SparseStructure3D,float>
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 //  value_type      SafeValue(int pos)     const {return IsInside(pos) ?           Get(pos) : 0;}
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     // ****************** constructors/destructors*******
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

Generated on Fri Jun 17 13:36:07 2005 for ImLib3D by  doxygen 1.4.2