36 #ifndef VIGRA_MULTI_BLOCKING_HXX
37 #define VIGRA_MULTI_BLOCKING_HXX
39 #include "vigra/tinyvector.hxx"
40 #include "vigra/box.hxx"
41 #include "vigra/multi_iterator.hxx"
42 #include "vigra/multi_convolution.hxx"
43 #include "vigra/transform_iterator.hxx"
48 template<
unsigned int DIM,
class C>
52 namespace detail_multi_blocking{
54 template<
unsigned int DIM,
class C>
55 class BlockWithBorder{
69 const Block & core()
const{
73 Block localCore()
const{
74 return core_-border_.begin();
78 const Block & border()
const{
82 bool operator == (
const BlockWithBorder & rhs)
const{
83 return core_ == rhs.core_ && border_ == rhs.border_;
85 bool operator != (
const BlockWithBorder & rhs)
const{
86 return core_ != rhs.core_ || border_ != rhs.border_;
94 template<
class VALUETYPE,
unsigned int DIMENSION>
95 std::ostream& operator<< (std::ostream& stream, const BlockWithBorder<DIMENSION,VALUETYPE> & bwb) {
96 stream<<
"["<<bwb.core()<<
", "<<bwb.border()<<
" ]";
102 class MultiCoordToBlockWithBoarder{
104 typedef typename MB::Shape Shape;
105 typedef typename MB::BlockDesc BlockDesc;
106 typedef typename MB::BlockWithBorder result_type;
107 MultiCoordToBlockWithBoarder()
111 MultiCoordToBlockWithBoarder(
const MB & mb,
const Shape & width)
116 result_type operator()(
const BlockDesc & blockDesc)
const{
117 return mb_->getBlockWithBorder(blockDesc, width_);
125 class MultiCoordToBlock{
127 typedef typename MB::Shape Shape;
128 typedef typename MB::BlockDesc BlockDesc;
129 typedef typename MB::Block result_type;
133 MultiCoordToBlock(
const MB & mb)
137 result_type operator()(
const BlockDesc & blockDesc)
const{
138 return mb_->getBlock(blockDesc);
156 template<
unsigned int DIM,
class C = MultiArrayIndex>
159 typedef MultiBlocking<DIM, C> SelfType;
160 friend class detail_multi_blocking::MultiCoordToBlock<SelfType>;
161 friend class detail_multi_blocking::MultiCoordToBlockWithBoarder<SelfType>;
162 typedef C PointValue;
163 typedef TinyVector<PointValue, DIM> Point;
165 typedef Point BlockDesc;
166 typedef Box<PointValue, DIM> Block;
167 typedef MultiCoordinateIterator< DIM> MultiCoordIter;
168 typedef detail_multi_blocking::BlockWithBorder<DIM, PointValue> BlockWithBorder;
172 typedef detail_multi_blocking::MultiCoordToBlockWithBoarder<SelfType> CoordToBwb;
173 typedef detail_multi_blocking::MultiCoordToBlock<SelfType> CoordToB;
174 typedef EndAwareTransformIterator<CoordToBwb, MultiCoordIter> BlockWithBorderIter;
175 typedef EndAwareTransformIterator<CoordToB, MultiCoordIter> BlockIter;
178 MultiBlocking(
const Shape & shape,
179 const Shape & blockShape,
180 const Shape & roiBegin = Shape(0),
181 const Shape & roiEnd = Shape(0)
184 roiBlock_(roiBegin,roiEnd == Shape(0) ? shape : roiEnd),
185 blockShape_(blockShape),
186 blocksPerAxis_(vigra::SkipInitialization),
189 const Shape roiShape = roiBlock_.
size();
190 blocksPerAxis_ = roiShape / blockShape_;
194 for(
size_t d=0; d<DIM; ++d){
195 if(blocksPerAxis_[d]*blockShape_[d] < roiShape[d] ){
198 numBlocks_ *= blocksPerAxis_[d];
202 Shape beginCA(0),endCB(shape);
203 for(
size_t d=0; d<DIM; ++d){
208 volumeBorderBlocks_.push_back(Block(beginCA,endCA));
212 Shape beginCB(shape);
214 volumeBorderBlocks_.push_back(Block(beginCB,endCB));
219 Shape insideVolBlockShapeEnd(shape);
220 insideVolBlockShapeEnd -= Shape(1);
221 insideVolBlock_.
setEnd(insideVolBlockShapeEnd);
229 BlockWithBorderIter blockWithBorderBegin(
const Shape & width)
const{
230 return BlockWithBorderIter(MultiCoordIter(blocksPerAxis_),
231 CoordToBwb(*
this, width));
234 BlockWithBorderIter blockWithBorderEnd(
const Shape & width)
const{
235 const MultiCoordIter beginIter(blocksPerAxis_);
236 return BlockWithBorderIter(beginIter.getEndIterator(),
237 CoordToBwb(*
this, width));
240 Block blockDescToBlock(
const BlockDesc & desc){
241 MultiCoordIter beginIter(blocksPerAxis_);
243 return *BlockIter(beginIter,CoordToB(*
this));
245 BlockIter blockBegin()
const{
246 return BlockIter(MultiCoordIter(blocksPerAxis_),CoordToB(*
this));
250 BlockIter blockEnd()
const{
251 const MultiCoordIter beginIter(blocksPerAxis_);
252 return BlockIter(beginIter.getEndIterator(),CoordToB(*
this));
256 Block blockDescToBlock(
const BlockDesc & blockDesc)
const{
257 MultiCoordIter iter(blocksPerAxis_);
259 return *BlockIter(iter,CoordToB(*
this));
265 return !insideVolBlock_.
contains(block);
269 const Shape & roiBegin()
const{
270 return roiBlock_.
begin();
273 const Shape & roiEnd()
const{
274 return roiBlock_.
end();
277 const Shape & shape()
const{
281 const Shape & blockShape()
const{
285 const Shape & blocksPerAxis()
const{
286 return blocksPerAxis_;
289 const std::vector<Block> & volumeBorderBlocks()
const{
290 return volumeBorderBlocks_;
294 std::vector<UInt32> intersectingBlocks(
295 const Shape roiBegin,
299 std::vector<UInt32> iBlocks;
300 const Block testBlock(roiBegin, roiEnd);
301 for(BlockIter iter=blockBegin(); iter!=blockEnd(); ++iter){
302 if(testBlock.intersects(*iter)){
303 iBlocks.push_back(i);
315 BlockWithBorder getBlockWithBorder(
const BlockDesc & blockDesc,
const Shape & width )
const{
316 const Point blockStart(blockDesc * blockShape_ + roiBlock_.
begin());
317 const Point blockEnd(blockStart + blockShape_);
318 const Block core = Block(blockStart, blockEnd) & roiBlock_ ;
321 border &= Block(shape_);
322 return BlockWithBorder( core, border );
326 Block getBlock(
const BlockDesc & blockDesc)
const{
327 const Point blockStart(blockDesc * blockShape_ + roiBlock_.
begin());
328 const Point blockEnd(blockStart + blockShape_);
329 return Block(blockStart, blockEnd) & roiBlock_;
335 Shape blocksPerAxis_;
339 std::vector<Block> volumeBorderBlocks_;
340 Block insideVolBlock_;
345 #endif // VIGRA_MULTI_BLOCKING_HXX
Vector size() const
Definition: box.hxx:232
bool contains(Vector const &p) const
Definition: box.hxx:314
size_t numBlocks() const
total number of blocks
Definition: multi_blocking.hxx:225
Vector const & end() const
Definition: box.hxx:163
Definition: multi_blocking.hxx:49
Vector const & begin() const
Definition: box.hxx:143
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
void setEnd(Vector const &end)
Definition: box.hxx:190
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
bool containsVolumeBorder(const Block &block) const
does this block intersect with the volume border
Definition: multi_blocking.hxx:264
void setBegin(Vector const &begin)
Definition: box.hxx:182
void addBorder(VALUETYPE borderWidth)
Definition: box.hxx:260
Iterate over a virtual array where each element contains its coordinate.
Definition: multi_fwd.hxx:157