#line 1 "/user/cvsspst/ees1cg/RAVL/RAVL-0.7/Core/Container/Array/Array3d.hh" // This file is part of RAVL, Recognition And Vision Library // Copyright (C) 2001, University of Surrey // This code may be redistributed under the terms of the GNU Lesser // General Public License (LGPL). See the lgpl.licence file for details or // see http://www.gnu.org/copyleft/lesser.html // file-header-ends-here #ifndef RAVL_ARRAY3D_HEADER #define RAVL_ARRAY3D_HEADER 1 /////////////////////////////////////////////////////////////////////// //! file="Ravl/Core/Container/Array/Array3d.hh" //! lib=RavlCore //! author="Radek Marik" //! date="2/5/1993" //! docentry="Ravl.Core.Arrays.3D" //! rcsid="$Id: Array3d.hh,v 1.6 2002/06/10 16:52:27 craftit Exp $" //! example=exArray3d.cc //! userlevel=Normal #include "Ravl/RBfAcc3d.hh" #include "Ravl/Buffer3d.hh" #include "Ravl/Index3d.hh" #include "Ravl/IndexRange3d.hh" #include "Ravl/BfAcc3Iter.hh" #include "Ravl/BfAcc3Iter2.hh" #include "Ravl/BfAcc3Iter3.hh" #include "Ravl/Types.hh" namespace RavlN { template class Array1dC; template class Slice1dC; template class Slice1dIterC; //! userlevel=Basic //: 3 Dimensional array // The class Array3dC is a container of items which can be indexed // by 3-dimensional index. template class Array3dC : public RangeBufferAccess3dC { public: Array3dC() {} //: Creates an empty 3D array. Array3dC(SizeT dim1, SizeT dim2, SizeT dim3); //: Creates 3D array with the range < <0,dim1-1>, <0,dim2-1>, <0,dim3-1> > Array3dC(IntT minI,IntT maxI,IntT minJ,IntT maxJ,IntT minK,IntT maxK); //: Creates 3D array with the range minRow to maxRow by minCol to maxCol. Array3dC(IndexC minI,IndexC maxI,IndexC minJ,IndexC maxJ,IndexC minK,IndexC maxK); //: Creates 3D array with the range minRow to maxRow by minCol to maxCol. Array3dC(const Index3dC & min, const Index3dC & max); //: Creates 3D array with the range < , , >. Array3dC(const IndexRangeC & rng1, const IndexRangeC & rng2, const IndexRangeC & rng3); //: Creates 3D array with the range Array3dC(const IndexRange3dC & rect); //: Create 3D array with the range covering indexes in 'rect' Array3dC(const IndexRange3dC & rect,const BufferC &data); //: Create 3D array with the range covering indexes in 'rect' from data. // NB. It is the users responsability to ensure that 'data' is // large enought to contain 'rect'. Array3dC(const Array3dC &arr,const IndexRange3dC & rect); //: Create a sub array of 'arr' covering indexes 'rect'. Array3dC Copy() const; //: Make a copy of the array. #if 0 Array1dC SliceRow(IndexC i) { return Array1dC(data.Data(),(*this)[i]); } //: Access row as 1d array. // NB. Changes made to the slice will also affect this array! Slice1dC SliceColumn(IndexC i) { return Slice1dC(data.Data(), &((*this)[Range1().Min()][i]), Min(Range1.Size(),Range2.Size()), Stride()); } //: Access columb as 1d slice. // NB. Changes made to the slice will also affect this array! Slice1dC Diagonal() { return Slice1dC(data.Data(), &((*this)[Range1().Min()][Range2().Min()]), Min(Range1.Size(),Range2.Size()), Stride()+1); } //: Take a slice along the diagonal of the array. // NB. Changes made to the slice will also affect this array! #endif inline const Array3dC & Array3d() const { return(*this); } //: access to the constant object inline Array3dC & Array3d() { return(*this); } //: access to the object #if 0 inline void ShiftIndexes1(IndexC offset); //: All indexes of Range1() will be changed by 'offset'. // The range will be shifted by -offset. void ShiftIndexes2(IndexC offset); //: All indexes of Range2() will be changed by 'offset'. // The range will be shifted by -offset. #endif Array3dC operator+(const Array3dC & arr) const; //: Sums 2 numerical arrays. // The operator returns the result as a new array. Array3dC operator-(const Array3dC & arr) const; //: Subtracts 2 numerical arrays. // The operator returns the result as a new array. Array3dC operator*(const Array3dC & arr) const; //: Mutliplies 2 numerical arrays. // The operator returns the result as a new array. Array3dC operator/(const Array3dC & arr) const; //: Divides 2 numerical arrays. // The operator returns the result as a new array. Array3dC operator*(const DataT &number) const; //: Multiplys the array by the 'number'. // The operator returns the result as a new array. Array3dC operator/(const DataT &number) const; //: Divides all array items by the 'number'. // The operator returns the result as a new array. Array3dC operator+(const DataT &number) const; //: Adds 'number' to the array. // The operator returns the result as a new array. Array3dC operator-(const DataT &number) const; //: Subtracts 'number' from all array items. // The operator returns the result as a new array. const Array3dC & operator+=(const Array3dC & arr); //: Adds the 2nd array to this array. const Array3dC & operator-=(const Array3dC & arr); //: Subtracts the 2nd array from this array. const Array3dC & operator*=(const Array3dC & arr); //: Multiplies the 2nd array to this array. const Array3dC & operator/=(const Array3dC & arr); //: Divides the 2nd array from this array. const Array3dC & operator+=(const DataT &number); //: Adds 'number' to all array items. const Array3dC & operator-=(const DataT &number); //: Subtracts 'number' from all array items. const Array3dC & operator*=(const DataT &number); //: Multiplies the array by the 'number'. const Array3dC & operator/=(const DataT &number); //: Divides the array elements by the 'number'. protected: void ConstructAccess(const IndexRangeC &rng1); //: Construct access for buffer. // This assumes a suitable amount of space has been allocated // in 'data' Buffer3dC data; // Raw data stored in array. }; template ostream & operator<<(ostream & s, const Array3dC & arr); // Prints into the stream 's' template istream & operator>>(istream & s, Array3dC & arr); // Reads the array from the stream 's' //////////////////////////////////////////////////////////////////////////////// #if 0 template inline void Array3dC::ShiftIndexes1(IndexC offset) { ShiftIndexes(offset); } template void Array3dC::ShiftIndexes2(IndexC offset) { for(BufferAccessIterC > it(*this);it.IsElm();it.Next()) it.Data().ShiftIndexes(offset); size2 -= offset.V(); // Keep dim2 uptodate. } #endif template void Array3dC::ConstructAccess(const IndexRangeC &rng1) { Attach(data,rng1); const SizeT d3Size = Range3().Size(); const SizeT d2Size = Range2().Size(); BufferAccessC *acc2 = data.DataIndex().ReferenceElm() - Range2().Min().V(); DataT *atData = data.Data().ReferenceElm() - Range3().Min().V(); for(BufferAccessIterC > > it(*this,rng1);it;it++,acc2 += d2Size) { *it = acc2; for(BufferAccessIterC > it2(*it,Range2());it2;it2++,atData += d3Size) *it2 = atData; } } template Array3dC::Array3dC(SizeT nsize1, SizeT nsize2, SizeT nsize3) : RangeBufferAccess3dC(IndexRangeC(0,nsize2-1),IndexRangeC(0,nsize3-1)), data(nsize1,nsize2,nsize3) { ConstructAccess(IndexRangeC(0,nsize1-1)); } template Array3dC::Array3dC(IndexC minI,IndexC maxI, IndexC minJ,IndexC maxJ, IndexC minK,IndexC maxK) : RangeBufferAccess3dC(IndexRangeC(minJ,maxI),IndexRangeC(minK,maxK)), data(IndexRangeC(minI,maxI).Size(),IndexRangeC(minJ,maxJ).Size(),IndexRangeC(minK,maxK).Size()) { RavlAssert(minI <= maxI); RavlAssert(minJ <= maxJ); RavlAssert(minK <= maxK); ConstructAccess(IndexRangeC(minI,maxI)); } template Array3dC::Array3dC(IntT minI,IntT maxI,IntT minJ,IntT maxJ,IntT minK,IntT maxK) : RangeBufferAccess3dC(IndexRangeC(minJ,maxJ),IndexRangeC(minK,maxK)), data(IndexRangeC(minI,maxI).Size(),IndexRangeC(minJ,maxJ).Size(),IndexRangeC(minK,maxK).Size()) { RavlAssert(minI <= maxI); RavlAssert(minJ <= maxJ); RavlAssert(minK <= maxK); ConstructAccess(IndexRangeC(minI,maxI)); } template Array3dC::Array3dC(const IndexRangeC & rng1, const IndexRangeC & rng2, const IndexRangeC & rng3) : RangeBufferAccess3dC(rng2,rng3), data(rng1.Size(),rng2.Size(),rng3.Size()) { ConstructAccess(rng1); } template Array3dC::Array3dC(const Index3dC & min, const Index3dC & max) : RangeBufferAccess3dC(IndexRangeC(min[1],max[1]),IndexRangeC(min[2],max[2])), data(IndexRangeC(min[0],max[0]).Size(), IndexRangeC(min[1],max[1]).Size(), IndexRangeC(min[2],max[2]).Size()) { ConstructAccess(IndexRangeC(min[0],max[0])); } template Array3dC::Array3dC(const IndexRange3dC & frame) : RangeBufferAccess3dC(frame.Range2(),frame.Range3()), data(frame.Range1().Size(),frame.Range2().Size(),frame.Range3().Size()) { ConstructAccess(frame.Range1()); } template Array3dC::Array3dC(const IndexRange3dC & frame,const BufferC &ndata) : RangeBufferAccess3dC(frame.Range2(),frame.Range3()), data(ndata, frame.Range1().Size(), frame.Range2().Size(), frame.Range3().Size() ) { ConstructAccess(frame.Range1()); } template Array3dC::Array3dC(const Array3dC &arr,const IndexRange3dC & frame) : RangeBufferAccess3dC (arr,frame), data(arr.data) {} template Array3dC Array3dC::Copy() const { Array3dC ret(Frame()); for(BufferAccess3dIter2C it(ret,ret.Range2(),ret.Range3(), (*this),Range2(),Range3());it;it++) it.Data1() = it.Data2(); return ret; } template ostream & operator<<(ostream & s, const Array3dC & arr) { s << arr.Frame() << "\n"; return s << ((const RangeBufferAccess3dC &)arr); } template istream &operator>>(istream & s, Array3dC & arr) { IndexRange3dC frame; s >> frame; arr = Array3dC(frame); return s >> ((RangeBufferAccess3dC &)arr); } template BinOStreamC &operator<<(BinOStreamC & s, const Array3dC & arr) { s << arr.Range1().Min() << arr.Range1().Max() << arr.Range2().Min() << arr.Range2().Max() << arr.Range3().Min() << arr.Range3().Max(); return s << ((const RangeBufferAccess3dC &)arr); } template BinIStreamC &operator>>(BinIStreamC & s, Array3dC & arr) { IndexRangeC rng1,rng2,rng3; s >> rng1.Min() >> rng1.Max() >> rng2.Min() >> rng2.Max() >> rng3.Min() >> rng3.Max(); arr = Array3dC(rng1,rng2,rng3); return s >> ((RangeBufferAccess3dC &)arr); } template Array3dC Array3dC::operator+(const Array3dC & arr) const { Array3dC ret(Frame()); for(BufferAccess3dIter3C it(ret,Range2(),Range3(), *this,Range2(),Range3(), arr,arr.Range2(),arr.Range3()); it;it++) it.Data1() = it.Data2() + it.Data3(); return ret; } template Array3dC Array3dC::operator-(const Array3dC & arr) const { Array3dC ret(Frame()); for(BufferAccess3dIter3C it(ret,Range2(),Range3(), *this,Range2(),Range3(), arr,arr.Range2(),arr.Range3());it;it++) it.Data1() = it.Data2() - it.Data3(); return ret; } template Array3dC Array3dC::operator*(const Array3dC & arr) const { Array3dC ret(Frame()); for(BufferAccess3dIter3C it(ret,Range2(),Range3(), *this,Range2(),Range3(), arr,arr.Range2(),arr.Range3());it;it++) it.Data1() = it.Data2() * it.Data3(); return ret; } template Array3dC Array3dC::operator/(const Array3dC & arr) const { Array3dC ret(Frame()); for(BufferAccess3dIter3C it(ret,Range2(),Range3(), *this,Range2(),Range3(), arr,arr.Range2(),arr.Range3());it;it++) it.Data1() = it.Data2() / it.Data3(); return ret; } template Array3dC Array3dC::operator+(const DataT &number) const { Array3dC ret(Frame()); for(BufferAccess3dIter2C it(ret,Range2(),Range3(), (*this),Range2(),Range3());it;it++) it.Data1() = it.Data2() + number; return ret; } template Array3dC Array3dC::operator-(const DataT &number) const { Array3dC ret(Frame()); for(BufferAccess3dIter2C it(ret,Range2(),Range3(), (*this),Range2(),Range3());it;it++) it.Data1() = it.Data2() - number; return ret; } template Array3dC Array3dC::operator*(const DataT &number) const { Array3dC ret(Frame()); for(BufferAccess3dIter2C it(ret,Range2(),Range3(), (*this),Range2(),Range3());it;it++) it.Data1() = it.Data2() * number; return ret; } template Array3dC Array3dC::operator/(const DataT &number) const { Array3dC ret(Frame()); for(BufferAccess3dIter2C it(ret,Range2(),Range3(), (*this),Range2(),Range3());it;it++) it.Data1() = it.Data2() / number; return ret; } template const Array3dC & Array3dC::operator+=(const Array3dC & arr) { for(BufferAccess3dIter2C it(*this,Range2(),Range3(), arr,arr.Range2(),arr.Range3());it;it++) it.Data1() += it.Data2(); return *this; } template const Array3dC & Array3dC::operator-=(const Array3dC & arr) { for(BufferAccess3dIter2C it(*this,Range2(),Range3(), arr,arr.Range2(),arr.Range3());it;it++) it.Data1() -= it.Data2(); return *this; } template const Array3dC & Array3dC::operator*=(const Array3dC & arr) { for(BufferAccess3dIter2C it(*this,Range2(),Range3(), arr,arr.Range2(),arr.Range3());it;it++) it.Data1() *= it.Data2(); return *this; } template const Array3dC & Array3dC::operator/=(const Array3dC & arr) { for(BufferAccess3dIter2C it(*this,Range2(),Range3(), arr,arr.Range2(),arr.Range3());it;it++) it.Data1() /= it.Data2(); return *this; } template const Array3dC & Array3dC::operator+=(const DataT &number) { for(BufferAccess3dIterC it(*this,Range2(),Range3());it;it++) it.Data1() += number; return *this; } template const Array3dC & Array3dC::operator-=(const DataT &number) { for(BufferAccess3dIterC it(*this,Range2(),Range3());it;it++) it.Data1() -= number; return *this; } template const Array3dC & Array3dC::operator*=(const DataT &number) { for(BufferAccess3dIterC it(*this,Range2(),Range3());it;it++) it.Data1() *= number; return *this; } template const Array3dC & Array3dC::operator/=(const DataT &number) { for(BufferAccess3dIterC it(*this,Range2(),Range3());it;it++) it.Data() /= number; return *this; } } #endif