OpendTect  6.6
array3dfloodfill.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*+
4 ________________________________________________________________________
5 
6  (C) dGB Beheer B.V.; (LICENSE) http://opendtect.org/OpendTect_license.txt
7  Author: K.Tingdahl/Y.C.Liu
8  Date: Nov 2008
9  RCS: $Id$
10  ________________________________________________________________________
11 
12 -*/
13 
14 #include "arraynd.h"
15 #include "arrayndinfo.h"
16 #include "arrayndimpl.h"
17 #include "multidimstorage.h"
18 #include "paralleltask.h"
19 #include "thread.h"
20 #include "varlenarray.h"
21 
22 
23 #define mMaxNrComp 10
24 
25 
44 template <class T>
46 {
47 public:
48  Array3DFloodfill(const Array3D<T>& input,T threshold,
49  bool aboveisovalue,Array3D<T>& output);
51 
52  void setOutsideValue(T val);
55  void setInsideValue( T val ) { insideval_ = val; }
57  void useInputValue( bool yn ) { useinputval_ = yn; }
58  void use6Neighbors( bool yn ) { use6neighbors_ = yn; }
59  /*<The true, we use 6 neighbors, otherwise, use 26. */
60 
61  void addSeed(int,int,int);
62  bool isAboveIsovalue() const { return aboveisovalue_; }
63  /*<Only when use input value. */
64 
65  int maxNrThreads() const { return compartments_.size(); }
66  od_int64 nrIterations() const{return input_.info().getTotalSz();}
67 
68 protected:
69 
70  void setOutput(int,int,int,bool addseed);
71  bool doWork(od_int64 start,od_int64 stop,int);
72  int getNextWorkCompartment();
73  void returnCompartment(int);
74 
75  int getWorkCompartment(int,int,int) const;
76 
83 
84  int nrcomp0_;
85  int compsz0_;
86  int nrcomp1_;
87  int compsz1_;
88  int nrcomp2_;
89  int compsz2_;
90 
91  int sz0_;
92  int sz1_;
93  int sz2_;
94 
95  struct Compartment
96  {
97  Compartment() : isused_( false )
98  , seeds_( 3, 0 ) {}
99  bool isused_;
102  };
103 
109 
119 };
120 
121 
122 template <class T> inline
124  bool max, Array3D<T>& output )
125  : input_(input)
126  , output_(output)
127  , threshold_(threshold)
128  , aboveisovalue_(max)
129  , insideval_(mUdf(T))
130  , use6neighbors_(true)
131  , useinputval_(true)
132  , sz0_(input.info().getSize(0))
133  , sz1_(input.info().getSize(1))
134  , sz2_(input.info().getSize(2))
135  , isdefined_(0)
136  , nrcomp0_(0)
137  , nrcomp1_(0)
138  , nrcomp2_(0)
139  , compsz0_(0)
140  , compsz1_(0)
141  , compsz2_(0)
142 {
144  OD::memZero( isdefined_->getData(), sizeof(bool)*sz0_*sz1_*sz2_ );
145 
146  setOutsideValue( mUdf(T) );
147 
148  compsz0_ = sz0_/mMaxNrComp; if ( compsz0_<3 ) compsz0_ = 3;
149  compsz1_ = sz1_/mMaxNrComp; if ( compsz1_<3 ) compsz1_ = 3;
150  compsz2_ = sz2_/mMaxNrComp; if ( compsz2_<3 ) compsz2_ = 3;
151 
155 
156  const int nrcompartments = nrcomp0_*nrcomp1_*nrcomp2_;
157  mAllocVarLenArr( int, arr, nrcompartments);
158  for ( int idx=0; idx<nrcompartments; idx++ )
159  {
160  compartments_ += new Compartment();
161  arr[idx] = idx;
162  }
163 
164  std::random_shuffle( mVarLenArr(arr), arr+nrcompartments );
165  for ( int idx=0; idx<nrcompartments; idx++ )
166  permutation_ += arr[idx];
167 }
168 
169 
170 template <class T> inline
172 {
173  delete isdefined_;
174  deepErase( compartments_ );
175 }
176 
177 
178 template <class T> inline
179 int Array3DFloodfill<T>::getWorkCompartment( int x0, int x1, int x2 ) const
180 {
181  return (x0/compsz0_)*(x1/compsz1_)*(x2/compsz2_);
182 }
183 
184 
185 template <class T> inline
187 {
188  outsideval_ = val;
189  output_.setAll( outsideval_ );
190 }
191 
192 
193 template <class T> inline
194 void Array3DFloodfill<T>::addSeed( int x0, int x1, int x2 )
195 {
196  setOutput( x0, x1, x2, true );
197 }
198 
199 
200 template <class T> inline
201 void Array3DFloodfill<T>::setOutput( int x0, int x1, int x2, bool addseed )
202 {
203  if ( x0<0 || x0>=sz0_ || x1<0 || x1>=sz1_ || x2<0 || x2>=sz2_ )
204  return;
205 
206  addToNrDone( 1 );
207 
208  const int cellidx = getWorkCompartment( x0, x1, x2 );
209 
210  compartments_[cellidx]->lock_.readLock();
211  if ( isdefined_->get(x0,x1,x2) )
212  {
213  compartments_[cellidx]->lock_.readUnLock();
214  return;
215  }
216 
217  if ( !compartments_[cellidx]->lock_.convReadToWriteLock() )
218  {
219  if ( isdefined_->get(x0,x1,x2) )
220  {
221  compartments_[cellidx]->lock_.writeUnLock();
222  return;
223  }
224  }
225 
226  if ( addseed )
227  isdefined_->set( x0, x1, x2, true );
228 
229  const T inputval = input_.get( x0, x1, x2 );
230 
231  T val = inputval;
232  if ( !useinputval_ && ((aboveisovalue_ && inputval<threshold_) ||
233  (!aboveisovalue_ && inputval>threshold_)) )
234  val = outsideval_;
235 
236  output_.set( x0, x1, x2, val );
237 
238  if ( addseed && ((aboveisovalue_ && inputval>=threshold_) ||
239  (!aboveisovalue_ && inputval<=threshold_) ) )
240  {
241  int dummy;
242  int seed[] = { x0, x1, x2 };
243  compartments_[cellidx]->seeds_.add( &dummy, seed );
244  compartmentlock_.signal( false );
245  }
246 
247  compartments_[cellidx]->lock_.writeUnLock();
248 }
249 
250 
251 template <class T> inline
253 {
254  compartmentlock_.lock();
255  while ( true )
256  {
257  bool nothingleft = true;
258  for ( int idx=permutation_.size()-1; idx>=0; idx-- )
259  {
260  const int compidx = permutation_[idx];
261  if ( compartments_[compidx]->isused_ )
262  nothingleft = false;
263  else
264  {
265  compartments_[compidx]->lock_.readLock();
266  if ( !compartments_[compidx]->seeds_.isEmpty() )
267  {
268  compartments_[compidx]->lock_.readUnLock();
269  compartments_[compidx]->isused_ = true;
270  compartmentlock_.unLock();
271  return compidx;
272  }
273 
274  compartments_[compidx]->lock_.readUnLock();
275  }
276  }
277 
278  if ( nothingleft )
279  break;
280 
281  compartmentlock_.wait();
282  }
283 
284  compartmentlock_.unLock();
285  return -1;
286 }
287 
288 
289 template <class T> inline
291 {
292  compartmentlock_.lock();
293  compartments_[comp]->isused_ = false;
294  compartmentlock_.unLock();
295  compartmentlock_.signal( true );
296 }
297 
298 
299 template <class T> inline
301 {
302  while ( shouldContinue() )
303  {
304  const int compidx = getNextWorkCompartment();
305  if ( compidx==-1 )
306  return true;
307 
308  Compartment& comp = *compartments_[compidx];
309  comp.lock_.readLock();
310  while ( !comp.seeds_.isEmpty() )
311  {
312  int idxs[3];
313  int arrpos[3];
314  comp.lock_.convReadToWriteLock();
315 
316  if ( !comp.seeds_.getIndex( 0, idxs ) ||
317  !comp.seeds_.getPos( idxs, arrpos ) )
318  {
319  comp.lock_.writeUnLock();
320  returnCompartment( compidx );
321  pErrMsg("Error!");
322  return false;
323  }
324 
325  comp.seeds_.remove( idxs );
326  comp.lock_.writeUnLock();
327 
328  for ( int i=-1; i<=1; i++ )
329  {
330  for ( int j=-1; j<=1; j++ )
331  {
332  for ( int k=-1; k<=1; k++ )
333  {
334  const char nrzeros = !i + !j + !k;
335  if ( nrzeros==3 )
336  continue;
337 
338  const bool addseed = !use6neighbors_ || nrzeros==2;
339  setOutput( arrpos[0]+i, arrpos[1]+j, arrpos[2]+k,
340  addseed );
341  }
342  }
343  }
344 
345  comp.lock_.readLock();
346  }
347 
348  comp.lock_.readUnLock();
349  returnCompartment( compidx );
350  }
351 
352  return true;
353 }
354 
Array3DFloodfill::useinputval_
bool useinputval_
Definition: array3dfloodfill.h:80
Array3DFloodfill::nrcomp2_
int nrcomp2_
Definition: array3dfloodfill.h:88
Array3DFloodfill::Array3DFloodfill
Array3DFloodfill(const Array3D< T > &input, T threshold, bool aboveisovalue, Array3D< T > &output)
Definition: array3dfloodfill.h:123
Array3DFloodfill::~Array3DFloodfill
~Array3DFloodfill()
Definition: array3dfloodfill.h:171
Array3DFloodfill::nrcomp1_
int nrcomp1_
Definition: array3dfloodfill.h:86
Array3DFloodfill::insideval_
T insideval_
Definition: array3dfloodfill.h:81
Array3DFloodfill::permutation_
TypeSet< int > permutation_
Definition: array3dfloodfill.h:108
Threads::ReadWriteLock::readUnLock
void readUnLock()
Array3DFloodfill::addSeed
void addSeed(int, int, int)
Definition: array3dfloodfill.h:194
Array3DFloodfill::compartments_
ObjectSet< Compartment > compartments_
Definition: array3dfloodfill.h:104
ObjectSet
Set of pointers to objects.
Definition: commontypes.h:31
Array3DFloodfill::isdefined_
Array3DImpl< bool > * isdefined_
Definition: array3dfloodfill.h:115
Array3DFloodfill::threshold_
T threshold_
Definition: array3dfloodfill.h:77
Threads::ReadWriteLock::convReadToWriteLock
bool convReadToWriteLock()
mVarLenArr
#define mVarLenArr(varnm)
Definition: varlenarray.h:55
Threads::ReadWriteLock
Lock that permits multiple readers to lock the object at the same time, but it will not allow any rea...
Definition: thread.h:143
od_int64
#define od_int64
Definition: plftypes.h:35
Array3DFloodfill::setInsideValue
void setInsideValue(T val)
Definition: array3dfloodfill.h:55
Array3DFloodfill::Compartment::Compartment
Compartment()
Definition: array3dfloodfill.h:97
varlenarray.h
Array3DImpl< bool >
Array3DFloodfill::Compartment::isused_
bool isused_
Protected by compartmentlock_.
Definition: array3dfloodfill.h:99
MPE::addSeed
void addSeed(EM::SectionID, EM::SubID)
Array3DFloodfill::outsideval_
T outsideval_
Definition: array3dfloodfill.h:82
Array3DFloodfill::Compartment
Definition: array3dfloodfill.h:96
MultiDimStorage< int >
arrayndimpl.h
Array3DFloodfill::input_
const Array3D< T > & input_
Not protected.
Definition: array3dfloodfill.h:110
Threads::ReadWriteLock::readLock
void readLock()
No writers will be active.
Array3DFloodfill::compsz2_
int compsz2_
Definition: array3dfloodfill.h:89
arraynd.h
arrayndinfo.h
Array3D
Array3D ( Subclass of ArrayND ) is a three dimensional array.
Definition: arraynd.h:162
Array3DFloodfill::returnCompartment
void returnCompartment(int)
Definition: array3dfloodfill.h:290
Array3DFloodfill::doWork
bool doWork(od_int64 start, od_int64 stop, int)
Definition: array3dfloodfill.h:300
Array3DFloodfill::compartmentlock_
Threads::ConditionVar compartmentlock_
Definition: array3dfloodfill.h:105
MultiDimStorage::getIndex
bool getIndex(int global_pos, IDX &) const
Definition: multidimstorage.h:535
mMaxNrComp
#define mMaxNrComp
Definition: array3dfloodfill.h:23
mClass
#define mClass(module)
Definition: commondefs.h:181
Array3DFloodfill::sz0_
int sz0_
Definition: array3dfloodfill.h:91
Array3DFloodfill::setOutsideValue
void setOutsideValue(T val)
Definition: array3dfloodfill.h:186
Threads::ConditionVar
Is an object that faciliates many threads to wait for something to happen.
Definition: thread.h:110
MultiDimStorage::getPos
int getPos(int idx) const
Definition: multidimstorage.h:309
Array3DFloodfill::Compartment::lock_
Threads::ReadWriteLock lock_
Definition: array3dfloodfill.h:100
pErrMsg
#define pErrMsg(msg)
Usual access point for programmer error messages.
Definition: errmsg.h:37
Array3DFloodfill::Compartment::seeds_
MultiDimStorage< int > seeds_
Protected by lock_.
Definition: array3dfloodfill.h:101
ParallelTask
Generalization of a task that can be run in parallel.
Definition: paralleltask.h:66
Array3DFloodfill::compsz1_
int compsz1_
Definition: array3dfloodfill.h:87
Array3DFloodfill::maxNrThreads
int maxNrThreads() const
Definition: array3dfloodfill.h:65
Array3DFloodfill::use6neighbors_
int use6neighbors_
Definition: array3dfloodfill.h:79
Threads::ReadWriteLock::writeUnLock
void writeUnLock()
deepErase
void deepErase(BufferStringSet &)
Array3DFloodfill::output_
Array3D< T > & output_
Definition: array3dfloodfill.h:112
MultiDimStorage::remove
void remove(const IDX &index)
Definition: multidimstorage.h:483
Array3DFloodfill::getNextWorkCompartment
int getNextWorkCompartment()
Definition: array3dfloodfill.h:252
Array3DFloodfill::aboveisovalue_
bool aboveisovalue_
Definition: array3dfloodfill.h:78
Array3DFloodfill::sz2_
int sz2_
Definition: array3dfloodfill.h:93
Array3DFloodfill::getWorkCompartment
int getWorkCompartment(int, int, int) const
Definition: array3dfloodfill.h:179
mAllocVarLenArr
#define mAllocVarLenArr(type, varnm, __size)
Definition: varlenarray.h:53
MultiDimStorage::isEmpty
bool isEmpty() const
Definition: multidimstorage.h:253
Array3DFloodfill
Given an input array and a threshold, we use flood fill to find all the locations with values less (o...
Definition: array3dfloodfill.h:46
mUdf
#define mUdf(type)
Use this macro to get the undefined for simple types.
Definition: undefval.h:274
Array3DFloodfill::nrIterations
od_int64 nrIterations() const
Definition: array3dfloodfill.h:66
Array3DFloodfill::compsz0_
int compsz0_
Definition: array3dfloodfill.h:85
Array3DFloodfill::isAboveIsovalue
bool isAboveIsovalue() const
Definition: array3dfloodfill.h:62
Array3DFloodfill::useInputValue
void useInputValue(bool yn)
Definition: array3dfloodfill.h:57
Array3DFloodfill::sz1_
int sz1_
Definition: array3dfloodfill.h:92
thread.h
paralleltask.h
Array3DFloodfill::use6Neighbors
void use6Neighbors(bool yn)
Definition: array3dfloodfill.h:58
Array3DFloodfill::setOutput
void setOutput(int, int, int, bool addseed)
Definition: array3dfloodfill.h:201
ArrayND::getData
const T * getData() const
Definition: arraynd.h:54
Array3DFloodfill::nrcomp0_
int nrcomp0_
Definition: array3dfloodfill.h:84
multidimstorage.h
TypeSet< int >

Generated at for the OpendTect seismic interpretation project. Copyright (C): dGB Beheer B.V. 1995-2021