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

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