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

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