]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/interface/wxWindows/widgets/manualPaint/FillFilter.cpp
e76dc6cf0391e0fce8f387d08e96f5fa267090f0
[creaMaracasVisu.git] / lib / maracasVisuLib / src / interface / wxWindows / widgets / manualPaint / FillFilter.cpp
1 /*# ---------------------------------------------------------------------
2 #
3 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
4 #                        pour la Sant�)
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
8 #
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.
15 #
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
20 #  liability.
21 #
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 # ------------------------------------------------------------------------ */
25
26 #include "FillFilter.h"
27 #include "creaVtk_MACROS.h"
28
29 #include <vector>
30
31
32
33 FillFilter::FillFilter() 
34 {
35         _tolerancefill          = 125;
36
37 //EED 2020-04-28  BORRAME Change to local variables to use with openmp
38 //      _auxImageFill           = NULL;
39 //      _maxXback                       = 0;
40 //      _maxYback                       = 0;
41 //      _maxZback                       = 0;
42         SetDistanceFill(5);
43 }
44
45 //---------------------------------------------------------------------------
46 FillFilter::~FillFilter() 
47 {
48 /*//EED 2020-04-28  BORRAME Change to local variables to use with openmp
49         if (_auxImageFill != NULL)
50         {
51                 _auxImageFill->Delete();
52         }//_auxImageFill
53 */
54 }
55
56 //---------------------------------------------------------------------------
57 void FillFilter::SetImages(vtkImageData *image,vtkImageData *image2) // virtual
58 {       
59         baseFilterManualPaint::SetImages(image,image2); 
60
61 /* //EED 2020-04-28  BORRAME Change to local variables to use with openmp
62         if ((_maxX!=_maxXback) || (_maxY!=_maxYback) || (_maxZ!=_maxZback)) 
63         {
64                 if (_auxImageFill != NULL)
65                 {
66                         _auxImageFill->Delete();
67                 }
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();
77 #else
78                 _auxImageFill->AllocateScalars(VTK_UNSIGNED_CHAR,1);
79 #endif
80         }
81         unsigned char   * ptrAuxImageFill = (unsigned char      *)_auxImageFill->GetScalarPointer();
82         memset(ptrAuxImageFill, 0, (_maxX+1) * (_maxY+1) * (_maxZ+1) );
83         _maxXback = _maxX;
84         _maxYback = _maxY;
85         _maxZback = _maxZ;      
86 */
87
88 }
89
90
91
92
93 //---------------------------------------------------------------------------
94 void FillFilter::Run() // virtual
95 {
96         long int ivi;
97         if ((_px >= _minX) && (_px < _dimX) && (_py >= _minY) && (_py < _dimY)
98                         && (_pz >= _minZ) && (_pz < _dimZ)) 
99         {
100                 this->_IMManager->BaseInitialPoint(_px, _py ,_pz);
101                 FillToolLoop(_px, _py, _pz);
102         } //if _minX _maxX _minY _maxY _minZ _maxZ
103 }
104
105
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 )
110 {
111         // _2D3D = 1     3D
112
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; }
116
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; }
120
121
122         int auxDimX = maxXAux-minXAux+1;
123         int auxDimY = maxYAux-minYAux+1;
124         int auxDimZ = maxZAux-minZAux+1;
125
126         // new vtkImageData
127         if (_2D3D==0)  // 2D
128         {       
129                 if (_direction==0) // YZ
130                 {
131                         auxDimX = 1;
132                 }
133                 if (_direction==1) // XZ
134                 {
135                         auxDimY = 1;
136                 }
137                 if (_direction==2) // XY
138                 {
139                         auxDimZ = 1;
140                 }
141         } // if 2D
142
143         OneColumnAux    = 1;
144         OneLineAux              = auxDimX;
145         OnePlaneAux             = auxDimX*auxDimY;
146
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 );
155         return auxImageFill;
156 }
157
158
159
160 //---------------------------------------------------------------------------
161 void FillFilter::FillToolLoop(int px, int py, int pz) 
162 {
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;
168         lstX.push_back(px);
169         lstY.push_back(py);
170         lstZ.push_back(pz);
171         std::vector<long long int> lstivi;
172         lstivi.push_back( px + py*_OneLine+ pz*_OnePlane );
173
174         long int OneColumnAux, OneLineAux, OnePlaneAux;
175         int pxAux, pyAux, pzAux;
176         vtkImageData* auxImageFill = GenerateAuxImageFill(      OneColumnAux,OneLineAux,OnePlaneAux,
177                                                                                                                 px,py,pz,
178                                                                                                                 pxAux,pyAux,pzAux );
179         std::vector<long long int> lstiviAux;
180         lstiviAux.push_back( pxAux + pyAux*OneLineAux + pzAux*OnePlaneAux );
181
182
183         DEF_POINTER_IMAGE_VTK_CREA_set(v_image,ss_image,p_image,st_image,_image)                
184         if (_image2!=NULL)
185         {
186                 DEF_POINTER_IMAGE_VTK_CREA_set(v_image2,ss_image2,p_image2,st_image2,_image2)           
187         } // if _image2
188
189         GETVALUE2_VTK_CREA(_graylevelbasefill,p_image,st_image,lstivi[0])       
190
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)
194
195         while ( lstX.size()!=0 )
196         {
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)) 
199                 {   
200                         difX = px-lstX[0];
201                         difY = py-lstY[0];
202                         difZ = pz-lstZ[0];
203                         _tmpDistfill = difX*difX + difY*difY + difZ*difZ;
204                         // if distance of center point
205                         if (_tmpDistfill<=_distbasefill)
206                         {
207                                 // if point not visited
208                                 GETVALUE2_VTK_CREA(vAuxImageFill,pAuxImageFill,stAuxImageFill,lstiviAux[0] );   
209                                 if (vAuxImageFill==0)
210                                 { 
211                                         // If Gray Level valid
212
213                                         //EED01 
214                                         //              _tmpiglfill     = _image->GetScalarComponentAsDouble(px, py, pz, 0);
215                                         GETVALUE2_VTK_CREA(_tmpiglfill,p_image,st_image,lstivi[0])      
216
217                                         if (_image2!=NULL)
218                                         {
219                                                 //EED01
220                                                 //                      _tmpiglfill2    =       _image2->GetScalarComponentAsDouble(px, py, pz, 0);
221                                                 GETVALUE2_VTK_CREA(_tmpiglfill2,p_image2,st_image2,lstivi[0])   
222                                         } else {
223                                                 _tmpiglfill2    =       _tmpiglfill;
224                                         }
225
226                                         float grayLBFMTOL       = _graylevelbasefill - _tolerancefill;
227                                         float grayLBFPTOL       = _graylevelbasefill + _tolerancefill;
228                                         bool isInRange          = false;
229                                         //DFCH
230                                         if (_RangeMin <= grayLBFMTOL && _RangeMax >= grayLBFPTOL) {
231                                                 isInRange               = true;
232                                         } //fi esle
233                                         else if (_RangeMin > grayLBFMTOL && _RangeMax >= grayLBFPTOL) {
234                                                 grayLBFMTOL     = _RangeMin;
235                                                 isInRange               = true;
236                                         } //fi esle
237                                         else if (_RangeMin <= grayLBFMTOL && _RangeMax < grayLBFPTOL) {
238                                                 grayLBFPTOL     = _RangeMax;
239                                                 isInRange               = true;
240                                         } //fi esle
241                                         else if ((_RangeMin <= _graylevelbasefill) && (_graylevelbasefill <= _RangeMax)) {
242                                                 grayLBFMTOL     = _RangeMin;
243                                                 grayLBFPTOL     = _RangeMax;
244                                                 isInRange               = true;
245                                         } //fi Range
246
247                                         if (isInRange) 
248                                         {
249                                                 _auxGrayLevelValidationFill =   (_tmpiglfill  != _graylevel)    && 
250                                                                                                                 (_tmpiglfill2 != _graylevel)    && 
251                                                                                                                 (_tmpiglfill  >= grayLBFMTOL)   && 
252                                                                                                                 (_tmpiglfill  <= grayLBFPTOL)   && 
253                                                                                                                 (_tmpDistfill <= _distbasefill) ; //DFCH
254                                         } else {
255                                                 _auxGrayLevelValidationFill = false;
256                                         } // if isInRange
257
258                                         if (_auxGrayLevelValidationFill==true)  
259                                         {
260                                                 this->_IMManager->AddModifiedPixel(lstX[0], lstY[0], lstZ[0]); //DFCH
261                                                 // Modifie image
262                                                 if (_image2!=NULL)
263                                                 {
264                                                         //                              _image2->SetScalarComponentFromFloat(px, py, pz, 0,(float) _graylevel);
265                                                         SETVALUE2_VTK_CREA(_graylevel,p_image2,st_image2,lstivi[0])
266                                                 } else {
267                                                         //                              _image->SetScalarComponentFromFloat(px, py, pz, 0,(float) _graylevel);
268                                                         SETVALUE2_VTK_CREA(_graylevel,p_image,st_image,lstivi[0])
269                                                 } // if _image2
270
271                                                 // Add neighborhood points in the list 
272
273                                 // Add point to already visited
274                                 SETVALUE2_VTK_CREA(1,pAuxImageFill,stAuxImageFill,lstiviAux[0]);
275
276                                                 if (_2D3D == 0) //2D
277                                                 {
278                                                         if (_direction == 0) // YZ
279                                                         {
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);
286                                                         }
287                                                         if (_direction == 1) // XZ
288                                                         {
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);
295                                                         }
296                                                         if (_direction == 2) // XY
297                                                         {
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);
304                                                         }
305                                                 } else { // 3D
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);
312                                                 } // 2D 3D
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();
325 }
326
327 //---------------------------------------------------------------------------
328 void FillFilter::SetToleranceFill(double tolerancefill) 
329 {
330         _tolerancefill = tolerancefill;
331 }
332
333 //---------------------------------------------------------------------------
334 void FillFilter::SetDistanceFill(int distancefill) 
335 {
336         _distancefill = distancefill;
337 }
338
339 /*//EED 2020-04-28  BORRAME Change to local variables to use with openmp
340 //---------------------------------------------------------------------------
341 vtkImageData* FillFilter::GetAuxImageFill() 
342 {
343         return _auxImageFill;
344 }
345 */
346