]> Creatis software - creaMaracasVisu.git/blob - bbtk/src/bbcreaMaracasVisuManualContourModel_Box.cxx
#3331 creaMaracasVisu Bug New Normal - Select contour with 2 points, HelpViewerNV
[creaMaracasVisu.git] / bbtk / src / bbcreaMaracasVisuManualContourModel_Box.cxx
1 //===== 
2 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
3 //===== 
4 #include "bbcreaMaracasVisuManualContourModel_Box.h"
5 #include "bbcreaMaracasVisuPackage.h"
6
7 #include <creaContoursFactory.h>
8
9
10 namespace bbcreaMaracasVisu
11 {
12
13 BBTK_ADD_BLACK_BOX_TO_PACKAGE(creaMaracasVisu,ManualContourModel_Box)
14 BBTK_BLACK_BOX_IMPLEMENTATION(ManualContourModel_Box,bbtk::AtomicBlackBox);
15 //===== 
16 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
17 //===== 
18
19
20 void ManualContourModel_Box::ProcessBySegment(  
21                         int Type, 
22                         int &iGeneral, int sizeSegment,
23                         std::vector<double> *lstInX,std::vector<double> *lstInY, std::vector<double> *lstInZ,
24                         std::vector<double> *lstOutX,std::vector<double> *lstOutY, std::vector<double> *lstOutZ,
25                         std::vector<int>        *lstIndexsOut, bool open )
26 {
27         creaContoursFactory f;
28         manualContourModel      *m;
29         int i,size=iGeneral+sizeSegment;
30         double x,y,z;
31         m = (manualContourModel*)f.getContourModel( bbGetInputType() );
32         m->SetNumberOfPointsSpline( bbGetInputNbPoints() );
33         m->SetCloseContour( open );
34         for (i=iGeneral;i<size;i++)
35         {
36                 m->AddPoint( (*lstInX)[i] , (*lstInY)[i] , (*lstInZ)[i] );
37         } // for
38         m->UpdateSpline();
39         int sizeContour = bbGetInputNbPoints();
40         for (i=0;i<sizeContour;i++)
41         {
42                 m->GetSpline_i_Point(i,&x,&y,&z);
43                 lstOutX->push_back(x);
44                 lstOutY->push_back(y);
45                 lstOutZ->push_back(z);
46         } // for
47         iGeneral=iGeneral+sizeSegment;
48         lstIndexsOut->push_back( sizeContour );
49         delete m;
50 }
51
52
53 void ManualContourModel_Box::RedistributionPoints(      std::vector<double> *lstOutX,
54                                                                                                         std::vector<double> *lstOutY, 
55                                                                                                         std::vector<double> *lstOutZ,
56                                                                                                         std::vector<int> *lstIndexsOut )
57 {
58         std::vector<double> lstRstX;
59         std::vector<double> lstRstY;
60         std::vector<double> lstRstZ;
61         int iLstIndexOut,sizeLstIndexOut=lstIndexsOut->size();
62         int ii, iGeneral=0;
63         int size;
64         for (iLstIndexOut=0;  iLstIndexOut<sizeLstIndexOut; iLstIndexOut++)
65         {
66 //printf("EED ManualContourModel_Box::RedistributionPoints iLstIndexOut=%d   \n", iLstIndexOut);
67                 lstRstX.clear();
68                 lstRstY.clear();
69                 lstRstZ.clear();
70                 size=(*lstIndexsOut)[iLstIndexOut];
71                 if (size>2)
72                 {
73                         double dist=0,dist2,distSeg,delta;
74                         double dd,dx,dy,dz;
75                         int i,k;
76                         for (i=iGeneral+1; i<iGeneral+size;i++)
77                         {
78                                 dx=(*lstOutX)[i]-(*lstOutX)[i-1];
79                                 dy=(*lstOutY)[i]-(*lstOutY)[i-1];
80                                 dz=(*lstOutZ)[i]-(*lstOutZ)[i-1];
81                                 dist = dist+sqrt( dx*dx + dy*dy + dz*dz );
82                         } //for
83                         delta=dist/(size-1);
84                         lstRstX.push_back( (*lstOutX)[iGeneral] );
85                         lstRstY.push_back( (*lstOutY)[iGeneral] );
86                         lstRstZ.push_back( (*lstOutZ)[iGeneral] );
87                         for (i=iGeneral+1; i<iGeneral+size;i++)
88                         {
89 //printf("EED ManualContourModel_Box::RedistributionPointsi=%d \n", i-iGeneral );
90
91                                 dist2 = 0;
92                                 for (k=iGeneral+1; k<iGeneral+size;k++)
93                                 {
94                                         dx=(*lstOutX)[k]-(*lstOutX)[k-1];
95                                         dy=(*lstOutY)[k]-(*lstOutY)[k-1];
96                                         dz=(*lstOutZ)[k]-(*lstOutZ)[k-1];
97                                         distSeg = sqrt( dx*dx + dy*dy + dz*dz );
98                                         ii=i-iGeneral;
99                                         if ( dist2+distSeg>=ii*delta) 
100                                         {
101                                                 dd=(ii*delta-dist2)/distSeg;
102                                                 if (distSeg==0)
103                                                 {
104                                                         dd=0;
105                                                 } // if distSeg == 0
106                                                 lstRstX.push_back( (*lstOutX)[k-1] + dd*dx );
107                                                 lstRstY.push_back( (*lstOutY)[k-1] + dd*dy );
108                                                 lstRstZ.push_back( (*lstOutZ)[k-1] + dd*dz );
109                                                 k=iGeneral+size;
110                                         } else {
111                                                 if (k==iGeneral+size-1) 
112                                                 {
113                                                         dd=1;
114                                                         lstRstX.push_back( (*lstOutX)[k-1] + dd*dx );
115                                                         lstRstY.push_back( (*lstOutY)[k-1] + dd*dy );
116                                                         lstRstZ.push_back( (*lstOutZ)[k-1] + dd*dz );
117 //                                                      printf("EED ManualContourModel_Box::RedistributionPoints iLstIndexOut=%d    i=%d k=%d  dist2+distSeg=%f    ii*delta=%f   dif=%f \n", iLstIndexOut,i-iGeneral, k-iGeneral, dist2+distSeg , ii*delta ,  (dist2+distSeg) - ii*delta);
118                                                 }
119                                         }// if dist2 
120                                         dist2=dist2+distSeg;
121                                 } // for k
122                         } //for i   
123                         if (lstRstX.size()!=size) 
124                         {
125                                 printf("EED Warnning!   ManualContourModel_Box::RedistributionPoints  >> This list is not coherent  iLstIndexOut=%d  lstRstX.size()=%d  size=%d\n",iLstIndexOut, lstRstX.size(), size);
126                         }
127                         for (i=iGeneral; i<iGeneral+size;i++)
128                         {
129                                 ii=i-iGeneral;
130                                 (*lstOutX)[i] = lstRstX[ii];
131                                 (*lstOutY)[i] = lstRstY[ii];
132                                 (*lstOutZ)[i] = lstRstZ[ii];
133                         } // for i
134                 } // if size>2
135                 iGeneral=iGeneral+size;
136         }// for iLstIndexOut
137 }
138
139
140 void ManualContourModel_Box::ClockwisePoints(   std::vector<double> *lstInX,
141                                                                                         std::vector<double> *lstInY, 
142                                                                                         std::vector<double> *lstInZ,
143                                                                                         std::vector<int> *lstIndexsIn )
144 {
145         int     iLstIndexIn,sizeLstIndexIn=lstIndexsIn->size();
146         int     i,iGeneral=0;
147         int     size,size2;
148         double  cx,cy,cz;
149         double  px,py,pz;
150         double  backpx,backpy,backpz;
151         double  ang;
152         char    dir=-1;
153         bool    dirx,diry,dirz;
154         int     flagAng=0;
155         float   backang;
156         double  tmp;
157
158         // For each contour
159         for (iLstIndexIn=0;  iLstIndexIn<sizeLstIndexIn; iLstIndexIn++)
160         {
161                 // Step 1. Find gravity center and direction
162                 size    = (*lstIndexsIn)[iLstIndexIn];
163                 if (size>2)  // for contour with more than 2 points
164                 {
165                         cx              = 0;
166                         cy              = 0;
167                         cz              = 0;
168                         dirx    = true;
169                         diry    = true;
170                         dirz    = true;
171                         for ( i=0 ; i<size ; i++ )
172                         {
173                                 px=(*lstInX)[iGeneral+i];
174                                 py=(*lstInY)[iGeneral+i];
175                                 pz=(*lstInZ)[iGeneral+i];
176                                 cx      = px + cx;
177                                 cy      = py + cy;
178                                 cz      = pz + cz;
179                                 if (i!=0) 
180                                 { 
181                                         if (backpx!=px) { dirx=false; } 
182                                         if (backpy!=py) { diry=false; } 
183                                         if (backpz!=pz) { dirz=false; } 
184                                         backpx=px;
185                                         backpy=py;
186                                         backpz=pz;
187                                 } // if i!=0
188                                 backpx=px; 
189                                 backpy=py; 
190                                 backpz=pz; 
191                         } // for i 
192                         cx=cx/size;
193                         cy=cy/size;
194                         cz=cz/size;
195                         if (dirx==true) { dir=1; }  // YZ 
196                         if (diry==true) { dir=2; }  // XZ 
197                         if (dirz==true) { dir=0; }  // XZ 
198                         // Step 2. Find angle diference find 
199                         flagAng=0;
200                         for ( i=0 ; i<size ; i++ )
201                         {
202                                 px = (*lstInX)[iGeneral+i]-cx;
203                                 py = (*lstInY)[iGeneral+i]-cy;
204                                 pz = (*lstInZ)[iGeneral+i]-cz;
205                                 if (dir==0) { ang=atan2( py , px ); } // XY
206                                 if (dir==1) { ang=atan2( pz , py ); } // YZ
207                                 if (dir==2) { ang=atan2( pz , px ); } // XZ
208                                 if (i>0) 
209                                 { 
210                                         if (backang<ang) 
211                                         {
212                                                 flagAng++;
213                                         } else {
214                                                 flagAng--;
215                                         }// if backang<ang
216                                 } // if i
217                                 backang=ang; 
218                         } // for i 
219
220                         // Step 3. Invert order of points
221                         if (flagAng<0)
222                         {
223                                 size2 = size/2;
224                                 for ( i=0 ; i<size2 ; i++ )
225                                 {
226                                         tmp                                                     = (*lstInX)[iGeneral+i];
227                                         (*lstInX)[iGeneral+i]                   = (*lstInX)[iGeneral+size-1-i];
228                                         (*lstInX)[iGeneral+size-1-i]    = tmp;
229                                         tmp                                                     = (*lstInY)[iGeneral+i];
230                                         (*lstInY)[iGeneral+i]                   = (*lstInY)[iGeneral+size-1-i];
231                                         (*lstInY)[iGeneral+size-1-i]    = tmp;
232                                         tmp                                                     = (*lstInZ)[iGeneral+i];
233                                         (*lstInZ)[iGeneral+i]                   = (*lstInZ)[iGeneral+size-1-i];
234                                         (*lstInZ)[iGeneral+size-1-i]    = tmp;
235                                 } // for i
236                         } // flagAng
237                 } // size>2
238                 iGeneral = iGeneral+size;
239         } // for iLstIndexIn
240 }
241
242 void ManualContourModel_Box::ShiftValues(       std::vector<double> *lstInX,
243                                                                                         std::vector<double> *lstInY, 
244                                                                                         std::vector<double> *lstInZ,
245                                                                                         std::vector<int> *lstIndexsIn )
246 {
247         int iLstIndexIn,sizeLstIndexIn=lstIndexsIn->size();
248         int ii, iGeneral=0;
249         int size,size2;
250         double dist,distMin;
251         int i,iBack;
252         double dx,dy,dz;
253         std::vector<double> LstTmpX;
254         std::vector<double> LstTmpY;
255         std::vector<double> LstTmpZ;
256         if (sizeLstIndexIn>=2)
257         {
258                 for (iLstIndexIn=0;  iLstIndexIn<sizeLstIndexIn-1; iLstIndexIn++)
259                 {
260                         size  = (*lstIndexsIn)[iLstIndexIn];
261                         size2 = (*lstIndexsIn)[iLstIndexIn+1];
262                         //find min distance and  iBack
263                         distMin = 10000000;
264                         iBack   = 0;
265                         for ( i=0 ; i<size2 ; i++ )
266                         {
267                                 dx      = (*lstInX)[iGeneral]-(*lstInX)[iGeneral+size+i];
268                                 dy      = (*lstInY)[iGeneral]-(*lstInY)[iGeneral+size+i];
269                                 dz      = (*lstInZ)[iGeneral]-(*lstInZ)[iGeneral+size+i];
270                                 dist= sqrt( dx*dx + dy*dy + dz*dz );
271                                 if ( dist<distMin ) 
272                                 {
273                                         iBack   = i;
274                                         distMin = dist;
275                                 }
276                         } // for dist
277                         if (iBack!=0)
278                         {
279                                 LstTmpX.clear();
280                                 LstTmpY.clear();
281                                 LstTmpZ.clear();
282                                 for (i=0 ; i<size2 ; i++) 
283                                 {
284                                         ii= (i+iBack)%size2;
285                                         LstTmpX.push_back( (*lstInX)[iGeneral+size+ii] );
286                                         LstTmpY.push_back( (*lstInY)[iGeneral+size+ii] );
287                                         LstTmpZ.push_back( (*lstInZ)[iGeneral+size+ii] );
288                                 } // for i                              
289                                 for (i=0 ; i<size2 ; i++) 
290                                 {
291                                         (*lstInX)[iGeneral+size+i] = LstTmpX[i];
292                                         (*lstInY)[iGeneral+size+i] = LstTmpY[i];
293                                         (*lstInZ)[iGeneral+size+i] = LstTmpZ[i];
294                                 } // for i                              
295                         }
296                         iGeneral=iGeneral+size;
297                 } // for iLstIndexIn
298         } // sizeLstIndexIn
299 }
300
301
302
303 void ManualContourModel_Box::Process()
304 {
305 // THE MAIN PROCESSING METHOD BODY
306 //   Here we simply set the input 'In' value to the output 'Out'
307 //   And print out the output value
308 // INPUT/OUTPUT ACCESSORS ARE OF THE FORM :
309 //    void bbSet{Input|Output}NAME(const TYPE&)
310 //    const TYPE& bbGet{Input|Output}NAME() const 
311 //    Where :
312 //    * NAME is the name of the input/output
313 //      (the one provided in the attribute 'name' of the tag 'input')
314 //    * TYPE is the C++ type of the input/output
315 //      (the one provided in the attribute 'type' of the tag 'input')
316
317 //    bbSetOutputOut( bbGetInputIn() );
318 //    std::cout << "Output value = " <<bbGetOutputOut() << std::endl;
319
320         // First Step  Spline Interpolation
321         std::vector<double> lstInX=bbGetInputLstControlPointsX();
322         std::vector<double> lstInY=bbGetInputLstControlPointsY();
323         std::vector<double> lstInZ=bbGetInputLstControlPointsZ();
324         if ( (lstInX.size()!=lstInY.size()) || (lstInY.size()!=lstInZ.size()) ) 
325         { 
326                 printf("Warnning !!  .. ManualContourModel_Box: The list X Y Z, no have the same number of elements \n");
327                 return;
328         }
329         std::vector<int>        lstIndexsIn=bbGetInputLstIndexsIn();
330         std::vector<int>        lstIndexsOut;
331         std::vector<double> lstOutX;
332         std::vector<double> lstOutY;
333         std::vector<double> lstOutZ;
334         if (bbGetInputLstIndexsIn().size()==0)
335         {
336                 lstIndexsIn.push_back( lstInX.size() );
337         }
338         if (bbGetInputDoubleContour()==1)
339         {
340                 ClockwisePoints( &lstInX , &lstInY , &lstInZ , &lstIndexsIn );
341                 ShiftValues( &lstInX , &lstInY , &lstInZ , &lstIndexsIn );
342         } // DoubleContour
343         int i,size=lstIndexsIn.size();
344         int iGeneral=0;
345         for (i=0;i<size;i++)
346         {
347                 ProcessBySegment(       bbGetInputType() , 
348                                                         iGeneral,  lstIndexsIn[i] ,
349                                                         &lstInX ,  &lstInY  , &lstInZ,
350                                                         &lstOutX , &lstOutY , &lstOutZ,
351                                                         &lstIndexsOut,bbGetInputOpenClose() );
352         } // for
353
354         if (bbGetInputDoubleContour()==0)
355         {
356                 //////////////////// Set Out   DoubleContour = 0
357                 bbSetOutputLstContourPointsX(lstOutX);  
358                 bbSetOutputLstContourPointsY(lstOutY);  
359                 bbSetOutputLstContourPointsZ(lstOutZ);
360                 bbSetOutputLstIndexsOut(lstIndexsOut);  
361         } else {
362                 RedistributionPoints(&lstOutX,&lstOutY,&lstOutZ,&lstIndexsOut);
363                 ///////////// Second Step Transpose the vectors   
364                 lstInX.clear();
365                 lstInY.clear();
366                 lstInZ.clear();
367                 lstIndexsIn.clear();
368                 size  = bbGetInputNbPoints();
369                 int j,size2 = lstIndexsOut.size();
370                 for (i=0;i<size;i++)
371                 {
372                         for (j=0;j<size2;j++)
373                         {
374                                 lstInX.push_back( lstOutX[ j*lstIndexsOut[j] + i ] );
375                                 lstInY.push_back( lstOutY[ j*lstIndexsOut[j] + i ] );
376                                 lstInZ.push_back( lstOutZ[ j*lstIndexsOut[j] + i ] );
377                         } // for j
378                         lstIndexsIn.push_back( size2 );
379                 } // for i
380                 lstOutX.clear();
381                 lstOutY.clear();
382                 lstOutZ.clear();
383                 lstIndexsOut.clear();
384                 ///////////////////// Third step Interponation 2
385                 size=lstIndexsIn.size();
386                 iGeneral=0;
387                 for (i=0;i<size;i++)
388                 {
389                         ProcessBySegment(       bbGetInputType() , 
390                                                                 iGeneral, lstIndexsIn[i] ,
391                                                                 &lstInX,&lstInY,&lstInZ,
392                                                                 &lstOutX,&lstOutY,&lstOutZ,
393                                                                 &lstIndexsOut,bbGetInputOpenClose2());
394                 } // for
395                 RedistributionPoints(&lstOutX,&lstOutY,&lstOutZ,&lstIndexsOut);
396                 //////////////////// Forth step Transpose the vectors   
397                 lstInX.clear();
398                 lstInY.clear();
399                 lstInZ.clear();
400                 lstIndexsIn.clear();
401                 size  = bbGetInputNbPoints();
402                 size2 = lstIndexsOut.size();
403                 for (i=0;i<size;i++)
404                 {
405                         for (j=0;j<size2;j++)
406                         {
407                                 lstInX.push_back( lstOutX[ j*lstIndexsOut[j] + i ] );
408                                 lstInY.push_back( lstOutY[ j*lstIndexsOut[j] + i ] );
409                                 lstInZ.push_back( lstOutZ[ j*lstIndexsOut[j] + i ] );
410                         } // for j
411                         lstIndexsIn.push_back( size2 );
412                 } // for i
413                 lstOutX.clear();
414                 lstOutY.clear();
415                 lstOutZ.clear();
416                 lstIndexsOut.clear();
417                 //////////////////// Set Out   DoubleContour = 1
418                 bbSetOutputLstContourPointsX(lstInX);   
419                 bbSetOutputLstContourPointsY(lstInY);   
420                 bbSetOutputLstContourPointsZ(lstInZ);
421                 bbSetOutputLstIndexsOut(lstIndexsIn);   
422
423         } // if DoubleContour 
424
425 }
426 //===== 
427 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
428 //===== 
429 void ManualContourModel_Box::bbUserSetDefaultValues()
430 {
431
432 //  SET HERE THE DEFAULT INPUT/OUTPUT VALUES OF YOUR BOX 
433 //    Here we initialize the input 'In' to 0
434    bbSetInputType(1);
435    bbSetInputDoubleContour(0);
436    bbSetInputOpenClose(false);
437    bbSetInputOpenClose2(false);
438    bbSetInputNbPoints(100);
439   
440 }
441 //===== 
442 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
443 //===== 
444 void ManualContourModel_Box::bbUserInitializeProcessing()
445 {
446
447 //  THE INITIALIZATION METHOD BODY :
448 //    Here does nothing 
449 //    but this is where you should allocate the internal/output pointers 
450 //    if any 
451
452   
453 }
454 //===== 
455 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
456 //===== 
457 void ManualContourModel_Box::bbUserFinalizeProcessing()
458 {
459
460 //  THE FINALIZATION METHOD BODY :
461 //    Here does nothing 
462 //    but this is where you should desallocate the internal/output pointers 
463 //    if any
464   
465 }
466 }
467 // EO namespace bbcreaMaracasVisu
468
469