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()
37 //EED 2020-04-28 BORRAME Change to local variables to use with openmp
38 // _auxImageFill = NULL;
45 //---------------------------------------------------------------------------
46 FillFilter::~FillFilter()
48 /*//EED 2020-04-28 BORRAME Change to local variables to use with openmp
49 if (_auxImageFill != NULL)
51 _auxImageFill->Delete();
56 //---------------------------------------------------------------------------
57 void FillFilter::SetImages(vtkImageData *image,vtkImageData *image2) // virtual
59 baseFilterManualPaint::SetImages(image,image2);
61 /* //EED 2020-04-28 BORRAME Change to local variables to use with openmp
62 if ((_maxX!=_maxXback) || (_maxY!=_maxYback) || (_maxZ!=_maxZback))
64 if (_auxImageFill != NULL)
66 _auxImageFill->Delete();
68 _auxImageFill = vtkImageData::New();
69 _auxImageFill->SetDimensions(_maxX + 1, _maxY + 1, _maxZ + 1);
70 _auxImageFill->SetOrigin(0, 0, 0);
71 _auxImageFill->SetExtent(0, _maxX, 0, _maxY, 0, _maxZ);
72 //EED 2017-01-01 Migration VTK7
73 #if VTK_MAJOR_VERSION <= 5
74 _auxImageFill->SetWholeExtent(0, _maxX, 0, _maxY, 0, _maxZ);
75 _auxImageFill->SetScalarTypeToUnsignedChar();
76 _auxImageFill->AllocateScalars();
78 _auxImageFill->AllocateScalars(VTK_UNSIGNED_CHAR,1);
81 unsigned char * ptrAuxImageFill = (unsigned char *)_auxImageFill->GetScalarPointer();
82 memset(ptrAuxImageFill, 0, (_maxX+1) * (_maxY+1) * (_maxZ+1) );
93 //---------------------------------------------------------------------------
94 void FillFilter::Run() // virtual
97 if ((_px >= _minX) && (_px < _dimX) && (_py >= _minY) && (_py < _dimY)
98 && (_pz >= _minZ) && (_pz < _dimZ))
100 this->_IMManager->BaseInitialPoint(_px, _py ,_pz);
101 FillToolLoop(_px, _py, _pz);
102 } //if _minX _maxX _minY _maxY _minZ _maxZ
106 //---------------------------------------------------------------------------
107 vtkImageData* FillFilter::GenerateAuxImageFill( long int &OneColumnAux, long int &OneLineAux , long int &OnePlaneAux,
108 int px,int py,int pz,
109 int &pxAux, int &pyAux, int &pzAux )
113 int minXAux = px-_distancefill; if (minXAux>=0) { pxAux=px-minXAux; } else { pxAux=px; minXAux=0; }
114 int minYAux = py-_distancefill; if (minYAux>=0) { pyAux=py-minYAux; } else { pyAux=py; minYAux=0; }
115 int minZAux = pz-_distancefill; if (minZAux>=0) { pzAux=pz-minZAux; } else { pzAux=pz; minZAux=0; }
117 int maxXAux = px+_distancefill; if (maxXAux>_dimX) { maxXAux=_dimX; }
118 int maxYAux = py+_distancefill; if (maxYAux>_dimY) { maxYAux=_dimY; }
119 int maxZAux = pz+_distancefill; if (maxZAux>_dimZ) { maxZAux=_dimZ; }
122 int auxDimX = maxXAux-minXAux+1;
123 int auxDimY = maxYAux-minYAux+1;
124 int auxDimZ = maxZAux-minZAux+1;
129 if (_direction==0) // YZ
133 if (_direction==1) // XZ
137 if (_direction==2) // XY
144 OneLineAux = auxDimX;
145 OnePlaneAux = auxDimX*auxDimY;
147 vtkImageData *auxImageFill;
148 auxImageFill = vtkImageData::New();
149 auxImageFill->SetDimensions(auxDimX, auxDimY, auxDimZ);
150 auxImageFill->SetOrigin(0, 0, 0);
151 auxImageFill->SetExtent(0, auxDimX, 0, auxDimY, 0, auxDimZ);
152 auxImageFill->AllocateScalars(VTK_UNSIGNED_CHAR,1);
153 unsigned char * ptrAuxImageFill = (unsigned char *)auxImageFill->GetScalarPointer();
154 memset( ptrAuxImageFill, 0, auxDimX*auxDimY*auxDimZ );
160 //---------------------------------------------------------------------------
161 void FillFilter::FillToolLoop(int px, int py, int pz)
163 _distbasefill = _distancefill * _distancefill;
164 double difX,difY,difZ,_tmpDistfill;
165 std::vector<int> lstX;
166 std::vector<int> lstY;
167 std::vector<int> lstZ;
171 std::vector<long long int> lstivi;
172 lstivi.push_back( px + py*_OneLine+ pz*_OnePlane );
174 long int OneColumnAux, OneLineAux, OnePlaneAux;
175 int pxAux, pyAux, pzAux;
176 vtkImageData* auxImageFill = GenerateAuxImageFill( OneColumnAux,OneLineAux,OnePlaneAux,
179 std::vector<long long int> lstiviAux;
180 lstiviAux.push_back( pxAux + pyAux*OneLineAux + pzAux*OnePlaneAux );
183 DEF_POINTER_IMAGE_VTK_CREA_set(v_image,ss_image,p_image,st_image,_image)
186 DEF_POINTER_IMAGE_VTK_CREA_set(v_image2,ss_image2,p_image2,st_image2,_image2)
189 GETVALUE2_VTK_CREA(_graylevelbasefill,p_image,st_image,lstivi[0])
191 //EED 2020-04-28 BORRAME Change to local variables to use with openmp
192 // DEF_POINTER_IMAGE_VTK_CREA(v_auxImageFill,ss_auxImageFill,p_auxImageFill,st_auxImageFill,_auxImageFill)
193 DEF_POINTER_IMAGE_VTK_CREA(vAuxImageFill,ssAuxImageFill,pAuxImageFill,stAuxImageFill,auxImageFill)
195 while ( lstX.size()!=0 )
197 // if point inside image
198 if ((lstX[0] >= _minX) && (lstX[0] < _dimX) && (lstY[0] >= _minY) && (lstY[0] < _dimY) && (lstZ[0] >= _minZ) && (lstZ[0] < _dimZ))
203 _tmpDistfill = difX*difX + difY*difY + difZ*difZ;
204 // if distance of center point
205 if (_tmpDistfill<=_distbasefill)
207 // if point not visited
208 GETVALUE2_VTK_CREA(vAuxImageFill,pAuxImageFill,stAuxImageFill,lstiviAux[0] );
209 if (vAuxImageFill==0)
211 // If Gray Level valid
214 // _tmpiglfill = _image->GetScalarComponentAsDouble(px, py, pz, 0);
215 GETVALUE2_VTK_CREA(_tmpiglfill,p_image,st_image,lstivi[0])
220 // _tmpiglfill2 = _image2->GetScalarComponentAsDouble(px, py, pz, 0);
221 GETVALUE2_VTK_CREA(_tmpiglfill2,p_image2,st_image2,lstivi[0])
223 _tmpiglfill2 = _tmpiglfill;
226 float grayLBFMTOL = _graylevelbasefill - _tolerancefill;
227 float grayLBFPTOL = _graylevelbasefill + _tolerancefill;
228 bool isInRange = false;
230 if (_RangeMin <= grayLBFMTOL && _RangeMax >= grayLBFPTOL) {
233 else if (_RangeMin > grayLBFMTOL && _RangeMax >= grayLBFPTOL) {
234 grayLBFMTOL = _RangeMin;
237 else if (_RangeMin <= grayLBFMTOL && _RangeMax < grayLBFPTOL) {
238 grayLBFPTOL = _RangeMax;
241 else if ((_RangeMin <= _graylevelbasefill) && (_graylevelbasefill <= _RangeMax)) {
242 grayLBFMTOL = _RangeMin;
243 grayLBFPTOL = _RangeMax;
249 _auxGrayLevelValidationFill = (_tmpiglfill != _graylevel) &&
250 (_tmpiglfill2 != _graylevel) &&
251 (_tmpiglfill >= grayLBFMTOL) &&
252 (_tmpiglfill <= grayLBFPTOL) &&
253 (_tmpDistfill <= _distbasefill) ; //DFCH
255 _auxGrayLevelValidationFill = false;
258 if (_auxGrayLevelValidationFill==true)
260 this->_IMManager->AddModifiedPixel(lstX[0], lstY[0], lstZ[0]); //DFCH
264 // _image2->SetScalarComponentFromFloat(px, py, pz, 0,(float) _graylevel);
265 SETVALUE2_VTK_CREA(_graylevel,p_image2,st_image2,lstivi[0])
267 // _image->SetScalarComponentFromFloat(px, py, pz, 0,(float) _graylevel);
268 SETVALUE2_VTK_CREA(_graylevel,p_image,st_image,lstivi[0])
271 // Add neighborhood points in the list
273 // Add point to already visited
274 SETVALUE2_VTK_CREA(1,pAuxImageFill,stAuxImageFill,lstiviAux[0]);
278 if (_direction == 0) // YZ
280 //lstX.push_back(lstX[0]+1); lstY.push_back(lstY[0]); lstZ.push_back(lstZ[0]); lstivi.push_back(lstivi[0]+_OneColumn); lstiviAux.push_back(lstiviAux[0]+OneColumnAux);
281 //lstX.push_back(lstX[0]-1); lstY.push_back(lstY[0]); lstZ.push_back(lstZ[0]); lstivi.push_back(lstivi[0]-_OneColumn); lstiviAux.push_back(lstiviAux[0]-OneColumnAux);
282 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]+1); lstZ.push_back(lstZ[0] ); lstivi.push_back(lstivi[0]+_OneLine); lstiviAux.push_back(lstiviAux[0]+OneLineAux);
283 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]-1); lstZ.push_back(lstZ[0] ); lstivi.push_back(lstivi[0]-_OneLine); lstiviAux.push_back(lstiviAux[0]-OneLineAux);
284 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]+1); lstivi.push_back(lstivi[0]+_OnePlane); lstiviAux.push_back(lstiviAux[0]+OnePlaneAux);
285 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]-1); lstivi.push_back(lstivi[0]-_OnePlane); lstiviAux.push_back(lstiviAux[0]-OnePlaneAux);
287 if (_direction == 1) // XZ
289 lstX.push_back(lstX[0]+1); lstY.push_back(lstY[0]); lstZ.push_back(lstZ[0]); lstivi.push_back(lstivi[0]+_OneColumn); lstiviAux.push_back(lstiviAux[0]+OneColumnAux);
290 lstX.push_back(lstX[0]-1); lstY.push_back(lstY[0]); lstZ.push_back(lstZ[0]); lstivi.push_back(lstivi[0]-_OneColumn); lstiviAux.push_back(lstiviAux[0]-OneColumnAux);
291 // lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]+1); lstZ.push_back(lstZ[0] ); lstivi.push_back(lstivi[0]+_OneLine); lstiviAux.push_back(lstiviAux[0]+OneLineAux);
292 // lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]-1); lstZ.push_back(lstZ[0] ); lstivi.push_back(lstivi[0]-_OneLine); lstiviAux.push_back(lstiviAux[0]-OneLineAux);
293 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]+1); lstivi.push_back(lstivi[0]+_OnePlane); lstiviAux.push_back(lstiviAux[0]+OnePlaneAux);
294 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]-1); lstivi.push_back(lstivi[0]-_OnePlane); lstiviAux.push_back(lstiviAux[0]-OnePlaneAux);
296 if (_direction == 2) // XY
298 lstX.push_back(lstX[0]+1); lstY.push_back(lstY[0]); lstZ.push_back(lstZ[0]); lstivi.push_back(lstivi[0]+_OneColumn); lstiviAux.push_back(lstiviAux[0]+OneColumnAux);
299 lstX.push_back(lstX[0]-1); lstY.push_back(lstY[0]); lstZ.push_back(lstZ[0]); lstivi.push_back(lstivi[0]-_OneColumn); lstiviAux.push_back(lstiviAux[0]-OneColumnAux);
300 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]+1); lstZ.push_back(lstZ[0] ); lstivi.push_back(lstivi[0]+_OneLine); lstiviAux.push_back(lstiviAux[0]+OneLineAux);
301 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]-1); lstZ.push_back(lstZ[0] ); lstivi.push_back(lstivi[0]-_OneLine); lstiviAux.push_back(lstiviAux[0]-OneLineAux);
302 //lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]+1); lstivi.push_back(lstivi[0]+_OnePlane); lstiviAux.push_back(lstiviAux[0]+OnePlaneAux);
303 //lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]-1); lstivi.push_back(lstivi[0]-_OnePlane); lstiviAux.push_back(lstiviAux[0]-OnePlaneAux);
306 lstX.push_back(lstX[0]+1); lstY.push_back(lstY[0]); lstZ.push_back(lstZ[0]); lstivi.push_back(lstivi[0]+_OneColumn); lstiviAux.push_back(lstiviAux[0]+OneColumnAux);
307 lstX.push_back(lstX[0]-1); lstY.push_back(lstY[0]); lstZ.push_back(lstZ[0]); lstivi.push_back(lstivi[0]-_OneColumn); lstiviAux.push_back(lstiviAux[0]-OneColumnAux);
308 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]+1); lstZ.push_back(lstZ[0] ); lstivi.push_back(lstivi[0]+_OneLine); lstiviAux.push_back(lstiviAux[0]+OneLineAux);
309 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0]-1); lstZ.push_back(lstZ[0] ); lstivi.push_back(lstivi[0]-_OneLine); lstiviAux.push_back(lstiviAux[0]-OneLineAux);
310 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]+1); lstivi.push_back(lstivi[0]+_OnePlane); lstiviAux.push_back(lstiviAux[0]+OnePlaneAux);
311 lstX.push_back(lstX[0] ); lstY.push_back(lstY[0] ); lstZ.push_back(lstZ[0]-1); lstivi.push_back(lstivi[0]-_OnePlane); lstiviAux.push_back(lstiviAux[0]-OnePlaneAux);
313 } // if gray level valid _auxGrayLevelValidationFill
314 } // if point not visited
315 } // if distance of center point
316 } // if point inside image
317 // Remove point from the list
318 lstX.erase( lstX.begin() );
319 lstY.erase( lstY.begin() );
320 lstZ.erase( lstZ.begin() );
321 lstivi.erase( lstivi.begin() );
322 lstiviAux.erase( lstiviAux.begin() );
323 } // while _lstX.size
324 auxImageFill->Delete();
327 //---------------------------------------------------------------------------
328 void FillFilter::SetToleranceFill(double tolerancefill)
330 _tolerancefill = tolerancefill;
333 //---------------------------------------------------------------------------
334 void FillFilter::SetDistanceFill(int distancefill)
336 _distancefill = distancefill;
339 /*//EED 2020-04-28 BORRAME Change to local variables to use with openmp
340 //---------------------------------------------------------------------------
341 vtkImageData* FillFilter::GetAuxImageFill()
343 return _auxImageFill;