1 /*# ---------------------------------------------------------------------
3 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
6 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
7 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 # This software is governed by the CeCILL-B license under French law and
10 # abiding by the rules of distribution of free software. You can use,
11 # modify and/ or redistribute the software under the terms of the CeCILL-B
12 # license as circulated by CEA, CNRS and INRIA at the following URL
13 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
14 # or in the file LICENSE.txt.
16 # As a counterpart to the access to the source code and rights to copy,
17 # modify and redistribute granted by the license, users are provided only
18 # with a limited warranty and the software's author, the holder of the
19 # economic rights, and the successive licensors have only limited
22 # The fact that you are presently reading this means that you have had
23 # knowledge of the CeCILL-B license and that you accept its terms.
24 # ------------------------------------------------------------------------ */
26 #include "FillFilter.h"
27 #include "creaVtk_MACROS.h"
33 FillFilter::FillFilter()
38 _limitRecursionFill = 50000;
46 //---------------------------------------------------------------------------
47 FillFilter::~FillFilter()
49 if (_auxImageFill != NULL)
51 _auxImageFill->Delete();
55 //---------------------------------------------------------------------------
56 void FillFilter::SetImages(vtkImageData *image,vtkImageData *image2) // virtual
58 baseFilterManualPaint::SetImages(image,image2);
59 if ((_maxX!=_maxXback) || (_maxY!=_maxYback) || (_maxZ!=_maxZback))
61 if (_auxImageFill != NULL)
63 _auxImageFill->Delete();
65 _auxImageFill = vtkImageData::New();
66 _auxImageFill->SetDimensions(_maxX + 1, _maxY + 1, _maxZ + 1);
67 _auxImageFill->SetOrigin(0, 0, 0);
68 _auxImageFill->SetExtent(0, _maxX, 0, _maxY, 0, _maxZ);
69 //EED 2017-01-01 Migration VTK7
70 #if VTK_MAJOR_VERSION <= 5
71 _auxImageFill->SetWholeExtent(0, _maxX, 0, _maxY, 0, _maxZ);
72 _auxImageFill->SetScalarTypeToUnsignedChar();
73 _auxImageFill->AllocateScalars();
75 _auxImageFill->AllocateScalars(VTK_UNSIGNED_CHAR,1);
78 unsigned char * ptrAuxImageFill = (unsigned char *)_auxImageFill->GetScalarPointer();
79 memset(ptrAuxImageFill, 0, (_maxX+1) * (_maxY+1) * (_maxZ+1) );
88 //---------------------------------------------------------------------------
89 void FillFilter::Run() // virtual
92 if ((_px >= _minX) && (_px <= _maxX) && (_py >= _minY) && (_py <= _maxY)
93 && (_pz >= _minZ) && (_pz <= _maxZ))
95 _graylevelbasefill = _image->GetScalarComponentAsDouble(_px, _py, _pz,0);
96 _distbasefill = _distancefill * _distancefill;
101 _countRecursiveFill = 0;
102 _countRecursiveFillProblem = 0;
103 _countProgressingFill = 0;
104 DEF_POINTER_IMAGE_VTK_CREA_set(v_image,ss_image,p_image,st_image,_image)
107 DEF_POINTER_IMAGE_VTK_CREA_set(v_image2,ss_image2,p_image2,st_image2,_image2)
110 // _usingAuxImageFill = false;
111 ivi = _px + _py*(_maxX+1) + _pz*(_maxX+1)*(_maxY+1); // index vector image
112 FillToolLoop(_px, _py, _pz, ivi);
113 } //if _minX _maxX _minY _maxY _minZ _maxZ
116 //---------------------------------------------------------------------------
117 void FillFilter::FillToolLoop(int px, int py, int pz,long int iviA)
119 double difX,difY,difZ,_tmpDistfill;
120 std::vector<int> lstX;
121 std::vector<int> lstY;
122 std::vector<int> lstZ;
123 std::vector<long long int> lstivi;
127 lstivi.push_back( iviA );
129 DEF_POINTER_IMAGE_VTK_CREA_set(v_image,ss_image,p_image,st_image,_image)
132 DEF_POINTER_IMAGE_VTK_CREA_set(v_image2,ss_image2,p_image2,st_image2,_image2)
135 DEF_POINTER_IMAGE_VTK_CREA(v_auxImageFill,ss_auxImageFill,p_auxImageFill,st_auxImageFill,_auxImageFill)
136 while ( lstX.size()!=0 )
138 // if point inside image
139 if ((lstX[0] >= _minX) && (lstX[0] <= _maxX) && (lstY[0] >= _minY) && (lstY[0] <= _maxY) && (lstZ[0] >= _minZ) && (lstZ[0] <= _maxZ))
144 _tmpDistfill = difX*difX + difY*difY + difZ*difZ;
145 // if distance of center point
146 if (_tmpDistfill<=_distbasefill)
148 // if point not visited
149 GETVALUE2_VTK_CREA(v_auxImageFill,p_auxImageFill,st_auxImageFill,lstivi[0] );
150 if (v_auxImageFill==0)
152 // If Gray Level valid
155 // _tmpiglfill = _image->GetScalarComponentAsDouble(px, py, pz, 0);
156 GETVALUE2_VTK_CREA(_tmpiglfill,p_image,st_image,lstivi[0])
161 // _tmpiglfill2 = _image2->GetScalarComponentAsDouble(px, py, pz, 0);
162 GETVALUE2_VTK_CREA(_tmpiglfill2,p_image2,st_image2,lstivi[0])
164 _tmpiglfill2 = _tmpiglfill;
167 float grayLBFMTOL = _graylevelbasefill - _tolerancefill;
168 float grayLBFPTOL = _graylevelbasefill + _tolerancefill;
169 bool isInRange = false;
171 if (_RangeMin <= grayLBFMTOL && _RangeMax >= grayLBFPTOL) {
174 else if (_RangeMin > grayLBFMTOL && _RangeMax >= grayLBFPTOL) {
175 grayLBFMTOL = _RangeMin;
178 else if (_RangeMin <= grayLBFMTOL && _RangeMax < grayLBFPTOL) {
179 grayLBFPTOL = _RangeMax;
182 else if ((_RangeMin <= _graylevelbasefill) && (_graylevelbasefill <= _RangeMax)) {
183 grayLBFMTOL = _RangeMin;
184 grayLBFPTOL = _RangeMax;
190 _auxGrayLevelValidationFill = (_tmpiglfill != _graylevel)
191 && (_tmpiglfill2 != _graylevel)
192 && (_tmpiglfill >= grayLBFMTOL)
193 && (_tmpiglfill <= grayLBFPTOL)
194 && (_tmpDistfill <= _distbasefill); //DFCH
196 _auxGrayLevelValidationFill = false;
199 if (_auxGrayLevelValidationFill)
202 this->_IMManager->AddModifiedPixel(lstX[0], lstY[0], lstZ[0]); //DFCH
207 // _image2->SetScalarComponentFromFloat(px, py, pz, 0,(float) _graylevel);
208 SETVALUE2_VTK_CREA(_graylevel,p_image2,st_image2,lstivi[0])
210 // _image->SetScalarComponentFromFloat(px, py, pz, 0,(float) _graylevel);
211 SETVALUE2_VTK_CREA(_graylevel,p_image,st_image,lstivi[0])
214 // Add neighborhood points in the list
217 if (_direction == 0) // YZ
219 //lstX.push_back(lstX[0]+1); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]+_OneColumn);
220 //lstX.push_back(lstX[0]-1); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]-_OneColumn);
221 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]+1); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]+_OneLine);
222 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]-1); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]-_OneLine);
223 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]+1); lstivi.push_back( lstivi[0]+_OnePlane);
224 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]-1); lstivi.push_back( lstivi[0]-_OnePlane);
226 if (_direction == 1) // XZ
228 lstX.push_back(lstX[0]+1); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]+_OneColumn);
229 lstX.push_back(lstX[0]-1); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]-_OneColumn);
230 // lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]+1); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]+_OneLine);
231 // lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]-1); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]-_OneLine);
232 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]+1); lstivi.push_back( lstivi[0]+_OnePlane);
233 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]-1); lstivi.push_back( lstivi[0]-_OnePlane);
235 if (_direction == 2) // XY
237 lstX.push_back(lstX[0]+1); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]+_OneColumn);
238 lstX.push_back(lstX[0]-1); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]-_OneColumn);
239 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]+1); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]+_OneLine);
240 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]-1); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]-_OneLine);
241 //lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]+1); lstivi.push_back( lstivi[0]+_OnePlane);
242 //lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]-1); lstivi.push_back( lstivi[0]-_OnePlane);
245 lstX.push_back(lstX[0]+1); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]+_OneColumn);
246 lstX.push_back(lstX[0]-1); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]-_OneColumn);
247 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]+1); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]+_OneLine);
248 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]-1); lstZ.push_back(lstZ[0] ); lstivi.push_back( lstivi[0]-_OneLine);
249 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]+1); lstivi.push_back( lstivi[0]+_OnePlane);
250 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]-1); lstivi.push_back( lstivi[0]-_OnePlane);
252 } // if gray level valid _auxGrayLevelValidationFill
253 } // if point not visited
254 // Add point to already visited
255 SETVALUE2_VTK_CREA(1,p_auxImageFill,st_auxImageFill,lstivi[0]);
256 } // if distance of center point
257 } // if point inside image
258 // Remove point from the list
259 lstX.erase( lstX.begin() );
260 lstY.erase( lstY.begin() );
261 lstZ.erase( lstZ.begin() );
262 lstivi.erase( lstivi.begin() );
263 } // while _lstX.size
270 //---------------------------------------------------------------------------
271 void FillFilter::Run2() // virtual
275 if ((_px >= _minX) && (_px <= _maxX) && (_py >= _minY) && (_py <= _maxY)
276 && (_pz >= _minZ) && (_pz <= _maxZ))
278 _graylevelbasefill = _image->GetScalarComponentAsDouble(_px, _py, _pz,0);
282 _distbasefill = _distancefill * _distancefill;
283 _countRecursiveFill = 0;
284 _countRecursiveFillProblem = 0;
285 _countProgressingFill = 0;
286 _usingAuxImageFill = false;
288 ivi = _px + _py*(_maxX+1) + _pz*(_maxX+1)*(_maxY+1); // index vector image
290 DEF_POINTER_IMAGE_VTK_CREA_set(v_image,ss_image,p_image,st_image,_image)
293 DEF_POINTER_IMAGE_VTK_CREA_set(v_image2,ss_image2,p_image2,st_image2,_image2)
297 // FillToolRecursive(_px, _py, _pz);
298 FillToolRecursive(_px, _py, _pz, ivi);
299 unsigned char *pImage;
300 pImage = (unsigned char *) _auxImageFill->GetScalarPointer();
304 while (_countRecursiveFillProblem != 0)
306 _countRecursiveFillProblem = 0;
307 _usingAuxImageFill = true;
308 for (kk = 0; kk <= _maxZ; kk++)
310 for (jj = 0; jj <= _maxY; jj++)
312 for (ii = 0; ii <= _maxX; ii++)
314 if (pImage[ivi] == 1)
317 // FillToolRecursive(ii, jj, kk);
318 FillToolRecursive(ii, jj, kk, ivi);
326 } //if _minX _maxX _minY _maxY _minZ _maxZ
331 //---------------------------------------------------------------------------
332 void FillFilter::FillToolRecursive(int px, int py, int pz,long int ivi)
334 //ups ??EED DEF_POINTER_IMAGE_VTK_CREA(v_image,ss_image,p_image,st_image,_image)
335 //ups ??EED DEF_POINTER_IMAGE_VTK_CREA(v_image2,ss_image2,p_image2,st_image2,_image2)
337 _countRecursiveFill++;
338 _countProgressingFill++;
339 if (_countProgressingFill > 200000)
341 printf("R %ld \n", _countRecursiveFill);
342 _countProgressingFill = 0;
345 if ((px >= _minX) && (px <= _maxX) && (py >= _minY) && (py <= _maxY)
346 && (pz >= _minZ) && (pz <= _maxZ))
348 if (_usingAuxImageFill == true)
350 //UPS ??EED this->_IMManager->AddModifiedPixel(px, py, pz); //DFCH
352 // _auxImageFill->SetScalarComponentFromFloat(px, py, pz, 0, 0);
353 _ptrAuxImageFill[ ivi ]=0;
358 _tmpDistfill = difX*difX + difY*difY + difZ*difZ;
359 // _tmpDistfill = (px-_pxfill)*(px-_pxfill)
360 // + (py-_pyfill)*(py-_pyfill)
361 // + (pz-_pzfill)*(pz-_pzfill);
363 //if (_countRecursiveFill >1 )
365 // printf(" -> %d %d %d cr=%ld r=%f\n", px,py,pz,_countRecursiveFill , _tmpDistfill);
370 // _tmpiglfill = _image->GetScalarComponentAsDouble(px, py, pz, 0);
371 GETVALUE2_VTK_CREA(_tmpiglfill,p_image,st_image,ivi)
376 // _tmpiglfill2 = _image2->GetScalarComponentAsDouble(px, py, pz, 0);
377 GETVALUE2_VTK_CREA(_tmpiglfill2,p_image2,st_image2,ivi)
379 _tmpiglfill2 = _tmpiglfill;
382 float grayLBFMTOL = _graylevelbasefill - _tolerancefill;
383 float grayLBFPTOL = _graylevelbasefill + _tolerancefill;
384 bool isInRange = false;
386 if (_RangeMin <= grayLBFMTOL && _RangeMax >= grayLBFPTOL) {
389 else if (_RangeMin > grayLBFMTOL && _RangeMax >= grayLBFPTOL) {
390 grayLBFMTOL = _RangeMin;
393 else if (_RangeMin <= grayLBFMTOL && _RangeMax < grayLBFPTOL) {
394 grayLBFPTOL = _RangeMax;
397 else if ((_RangeMin <= _graylevelbasefill) && (_graylevelbasefill <= _RangeMax)) {
398 grayLBFMTOL = _RangeMin;
399 grayLBFPTOL = _RangeMax;
405 _auxGrayLevelValidationFill = (_tmpiglfill != _graylevel)
406 && (_tmpiglfill2 != _graylevel)
407 && (_tmpiglfill >= grayLBFMTOL)
408 && (_tmpiglfill <= grayLBFPTOL)
409 && (_tmpDistfill <= _distbasefill); //DFCH
411 _auxGrayLevelValidationFill = false;
415 if (_auxGrayLevelValidationFill == true)
417 //UPS ??EED this->_IMManager->AddModifiedPixel(px, py, pz); //DFCH
421 // _image2->SetScalarComponentFromFloat(px, py, pz, 0,(float) _graylevel);
422 SETVALUE2_VTK_CREA(_graylevel,p_image2,st_image2,ivi)
425 // _image->SetScalarComponentFromFloat(px, py, pz, 0,(float) _graylevel);
426 SETVALUE2_VTK_CREA(_graylevel,p_image,st_image,ivi)
429 if (_countRecursiveFill < _limitRecursionFill)
434 if (_direction == 0) // YZ
436 //FillToolRecursive(px+1,py,pz);
437 //FillToolRecursive(px-1,py,pz);
438 FillToolRecursive(px, py + 1, pz, ivi+_OneLine );
439 FillToolRecursive(px, py - 1, pz, ivi-_OneLine );
440 FillToolRecursive(px, py, pz - 1, ivi-_OnePlane );
441 FillToolRecursive(px, py, pz + 1, ivi+_OnePlane );
443 if (_direction == 1) // XZ
445 FillToolRecursive(px + 1, py, pz, ivi+_OneColumn);
446 FillToolRecursive(px - 1, py, pz, ivi-_OneColumn);
447 //FillToolRecursive(px,py+1,pz);
448 //FillToolRecursive(px,py-1,pz);
449 FillToolRecursive(px, py, pz - 1, ivi-_OnePlane );
450 FillToolRecursive(px, py, pz + 1, ivi+_OnePlane );
452 if (_direction == 2) // XY
454 FillToolRecursive(px + 1, py, pz, ivi+_OneColumn);
455 FillToolRecursive(px, py + 1, pz, ivi+_OneLine);
456 FillToolRecursive(px - 1, py, pz, ivi-_OneColumn);
457 FillToolRecursive(px, py - 1, pz, ivi-_OneLine);
458 //FillToolRecursive(px,py,pz-1);
459 //FillToolRecursive(px,py,pz+1);
462 FillToolRecursive(px + 1, py, pz, ivi+_OneColumn );
463 FillToolRecursive(px - 1, py, pz, ivi-_OneColumn );
464 FillToolRecursive(px, py + 1, pz, ivi+_OneLine );
465 FillToolRecursive(px, py - 1, pz, ivi-_OneLine );
466 FillToolRecursive(px, py, pz - 1, ivi-_OnePlane );
467 FillToolRecursive(px, py, pz + 1, ivi+_OnePlane );
470 } //_countRecursiveFill
473 if ((_auxGrayLevelValidationFill == true) && (_countRecursiveFill >= _limitRecursionFill))
475 _countRecursiveFillProblem++;
478 if (_direction == 0) // YZ
480 //SetAuxImageFill(px+1,py,pz);
481 //SetAuxImageFill(px-1,py,pz);
482 SetAuxImageFill(px, py + 1, pz,ivi+_OneLine);
483 SetAuxImageFill(px, py - 1, pz,ivi-_OneLine);
484 SetAuxImageFill(px, py, pz - 1,ivi-_OnePlane);
485 SetAuxImageFill(px, py, pz + 1,ivi+_OnePlane);
487 if (_direction == 1) // XZ
489 SetAuxImageFill(px + 1, py, pz,ivi+_OneColumn);
490 SetAuxImageFill(px - 1, py, pz,ivi-_OneColumn);
491 //SetAuxImageFill(px,py+1,pz);
492 //SetAuxImageFill(px,py-1,pz);
493 SetAuxImageFill(px, py, pz - 1,ivi-_OnePlane);
494 SetAuxImageFill(px, py, pz + 1,ivi+_OnePlane);
496 if (_direction == 2) // XY
498 SetAuxImageFill(px + 1, py, pz,ivi+_OneColumn);
499 SetAuxImageFill(px - 1, py, pz,ivi-_OneColumn);
500 SetAuxImageFill(px, py + 1, pz,ivi+_OneLine);
501 SetAuxImageFill(px, py - 1, pz,ivi-_OneLine);
502 //SetAuxImageFill(px,py,pz-1);
503 //SetAuxImageFill(px,py,pz+1);
506 SetAuxImageFill(px + 1, py, pz,ivi+_OneColumn);
507 SetAuxImageFill(px - 1, py, pz,ivi-_OneColumn);
508 SetAuxImageFill(px, py + 1, pz,ivi+_OneLine);
509 SetAuxImageFill(px, py - 1, pz,ivi-_OneLine);
510 SetAuxImageFill(px, py, pz - 1,ivi-_OnePlane);
511 SetAuxImageFill(px, py, pz + 1,ivi+_OnePlane);
514 } // _graylevel //_limitRecursionFill
516 } //if _minX _maxX _minY _maxY _minZ _maxZ
517 _countRecursiveFill--;
521 //---------------------------------------------------------------------------
522 void FillFilter::SetAuxImageFill(int px, int py, int pz, long int ivi)
524 if ((px >= _minX) && (px <= _maxX) && (py >= _minY) && (py <= _maxY)
525 && (pz >= _minZ) && (pz <= _maxZ))
527 this->_IMManager->AddModifiedPixel(px, py, pz); //DFCH
529 // _auxImageFill->SetScalarComponentFromFloat(px, py, pz, 0, 1);
530 _ptrAuxImageFill[ ivi ]=1;
536 //---------------------------------------------------------------------------
537 void FillFilter::SetToleranceFill(double tolerancefill)
539 _tolerancefill = tolerancefill;
542 //---------------------------------------------------------------------------
543 void FillFilter::SetDistanceFill(int distancefill)
545 _distancefill = distancefill;