]> Creatis software - creaMaracasVisu.git/blob - bbtk/src/bbcreaMaracasVisuManualContourModel_Box.cxx
2b2404271ff40b64634a7f62bccd6fbbaeb4e93f
[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 printf("EED ManualContourModel_Box::ClockwisePoints cx=%f cy=%f cz=%f    flagAng=%d   size=%d \n",cx,cy,cz,flagAng, size);
221 //if (cy<=490) { flagAng = flagAng*(-1); }
222
223                         // Step 3. Invert order of points
224                         if (flagAng<0)
225                         {
226                                 size2 = size/2;
227                                 for ( i=0 ; i<size2 ; i++ )
228                                 {
229                                         tmp                                                     = (*lstInX)[iGeneral+i];
230                                         (*lstInX)[iGeneral+i]                   = (*lstInX)[iGeneral+size-1-i];
231                                         (*lstInX)[iGeneral+size-1-i]    = tmp;
232                                         tmp                                                     = (*lstInY)[iGeneral+i];
233                                         (*lstInY)[iGeneral+i]                   = (*lstInY)[iGeneral+size-1-i];
234                                         (*lstInY)[iGeneral+size-1-i]    = tmp;
235                                         tmp                                                     = (*lstInZ)[iGeneral+i];
236                                         (*lstInZ)[iGeneral+i]                   = (*lstInZ)[iGeneral+size-1-i];
237                                         (*lstInZ)[iGeneral+size-1-i]    = tmp;
238                                 } // for i
239                         } // flagAng
240                 } // size>2
241                 iGeneral = iGeneral+size;
242         } // for iLstIndexIn
243 }
244
245 void ManualContourModel_Box::ShiftValues(       std::vector<double> *lstInX,
246                                                                                         std::vector<double> *lstInY, 
247                                                                                         std::vector<double> *lstInZ,
248                                                                                         std::vector<int> *lstIndexsIn )
249 {
250         int iLstIndexIn,sizeLstIndexIn=lstIndexsIn->size();
251         int ii, iGeneral=0;
252         int size,size2;
253         double dist,distMin;
254         int i,iBack;
255         int ig;
256         double dx,dy,dz;
257         std::vector<double> LstTmpX;
258         std::vector<double> LstTmpY;
259         std::vector<double> LstTmpZ;
260         if (sizeLstIndexIn>=2)
261         {
262         
263                 for (iLstIndexIn=0;  iLstIndexIn<sizeLstIndexIn-1; iLstIndexIn++)
264                 {
265                         size  = (*lstIndexsIn)[iLstIndexIn];
266                         size2 = (*lstIndexsIn)[iLstIndexIn+1];
267                         //find min distance and  iBack
268                         distMin = 10000000;
269                         iBack   = 0;
270                         
271                         
272                         for (ig=0; ig<size; ig++)
273                         {
274                                 for ( i=0 ; i<size2 ; i++ )
275                                 {
276                                         dx      = (*lstInX)[iGeneral+ig]-(*lstInX)[iGeneral+size+i];
277                                         dy      = (*lstInY)[iGeneral+ig]-(*lstInY)[iGeneral+size+i];
278                                         dz      = (*lstInZ)[iGeneral+ig]-(*lstInZ)[iGeneral+size+i];
279                                         dist= sqrt( dx*dx + dy*dy + dz*dz );
280                                         if ( dist<distMin ) 
281                                         {
282                                                 iBack   = i-ig;
283                                                 distMin = dist;
284                                         }
285                                 } // for i size2
286                         } // for ig size
287
288 if (iBack<0) 
289 {
290         printf("- "); 
291         iBack = iBack + size2; 
292 }
293                         
294 printf("EED ManualContourModel_Box::ShiftValues px=%f py=%f pz=%f  iBack=%d/%d  size=%d  distMin=%f \n", (*lstInX)[iGeneral]  , (*lstInY)[iGeneral] , (*lstInZ)[iGeneral], iBack, size2,size, distMin);
295                         
296                         if (iBack!=0)
297                         {
298                                 LstTmpX.clear();
299                                 LstTmpY.clear();
300                                 LstTmpZ.clear();
301                                 for (i=0 ; i<size2 ; i++) 
302                                 {
303                                         ii= (i+iBack)%size2;
304                                         LstTmpX.push_back( (*lstInX)[iGeneral+size+ii] );
305                                         LstTmpY.push_back( (*lstInY)[iGeneral+size+ii] );
306                                         LstTmpZ.push_back( (*lstInZ)[iGeneral+size+ii] );
307                                 } // for i                              
308                                 for (i=0 ; i<size2 ; i++) 
309                                 {
310                                         (*lstInX)[iGeneral+size+i] = LstTmpX[i];
311                                         (*lstInY)[iGeneral+size+i] = LstTmpY[i];
312                                         (*lstInZ)[iGeneral+size+i] = LstTmpZ[i];
313                                 } // for i                              
314                         }
315                         iGeneral=iGeneral+size;
316                 } // for iLstIndexIn
317                 
318 //------------          
319                 
320                 iGeneral=0;
321
322                 for (iLstIndexIn=0;  iLstIndexIn<sizeLstIndexIn-1; iLstIndexIn++)
323                 {
324                         size  = (*lstIndexsIn)[iLstIndexIn];
325                         size2 = (*lstIndexsIn)[iLstIndexIn+1];
326                         //find min distance and  iBack
327                         distMin = 10000000;
328                         iBack   = 0;
329                         
330                         
331 //                      for (ig=0; ig<size; ig++)
332 //                      {
333                                 for ( i=0 ; i<size2 ; i++ )
334                                 {
335                                         dx      = (*lstInX)[iGeneral]-(*lstInX)[iGeneral+size+i];
336                                         dy      = (*lstInY)[iGeneral]-(*lstInY)[iGeneral+size+i];
337                                         dz      = (*lstInZ)[iGeneral]-(*lstInZ)[iGeneral+size+i];
338                                         dist= sqrt( dx*dx + dy*dy + dz*dz );
339                                         if ( dist<distMin ) 
340                                         {
341                                                 iBack   = i;
342                                                 distMin = dist;
343                                         }
344                                 } // for i size2
345 //                      } // for ig size
346
347                         
348 printf("EED ManualContourModel_Box::ShiftValues px=%f py=%f pz=%f  iBack=%d/%d  size=%d  distMin=%f \n", (*lstInX)[iGeneral]  , (*lstInY)[iGeneral] , (*lstInZ)[iGeneral], iBack, size2,size, distMin);
349                         
350                         if (iBack!=0)
351                         {
352                                 LstTmpX.clear();
353                                 LstTmpY.clear();
354                                 LstTmpZ.clear();
355                                 for (i=0 ; i<size2 ; i++) 
356                                 {
357                                         ii= (i+iBack)%size2;
358                                         LstTmpX.push_back( (*lstInX)[iGeneral+size+ii] );
359                                         LstTmpY.push_back( (*lstInY)[iGeneral+size+ii] );
360                                         LstTmpZ.push_back( (*lstInZ)[iGeneral+size+ii] );
361                                 } // for i                              
362                                 for (i=0 ; i<size2 ; i++) 
363                                 {
364                                         (*lstInX)[iGeneral+size+i] = LstTmpX[i];
365                                         (*lstInY)[iGeneral+size+i] = LstTmpY[i];
366                                         (*lstInZ)[iGeneral+size+i] = LstTmpZ[i];
367                                 } // for i                              
368                         }
369                         iGeneral=iGeneral+size;
370                 } // for iLstIndexIn
371                 
372         } // if sizeLstIndexIn
373         
374 }
375
376
377
378 void ManualContourModel_Box::Process()
379 {
380 // THE MAIN PROCESSING METHOD BODY
381 //   Here we simply set the input 'In' value to the output 'Out'
382 //   And print out the output value
383 // INPUT/OUTPUT ACCESSORS ARE OF THE FORM :
384 //    void bbSet{Input|Output}NAME(const TYPE&)
385 //    const TYPE& bbGet{Input|Output}NAME() const 
386 //    Where :
387 //    * NAME is the name of the input/output
388 //      (the one provided in the attribute 'name' of the tag 'input')
389 //    * TYPE is the C++ type of the input/output
390 //      (the one provided in the attribute 'type' of the tag 'input')
391
392 //    bbSetOutputOut( bbGetInputIn() );
393 //    std::cout << "Output value = " <<bbGetOutputOut() << std::endl;
394
395         // First Step  Spline Interpolation
396         std::vector<double> lstInX=bbGetInputLstControlPointsX();
397         std::vector<double> lstInY=bbGetInputLstControlPointsY();
398         std::vector<double> lstInZ=bbGetInputLstControlPointsZ();
399         if ( (lstInX.size()!=lstInY.size()) || (lstInY.size()!=lstInZ.size()) ) 
400         { 
401                 printf("Warnning !!  .. ManualContourModel_Box: The list X Y Z, no have the same number of elements \n");
402                 return;
403         }
404         std::vector<int>        lstIndexsIn=bbGetInputLstIndexsIn();
405         std::vector<int>        lstIndexsOut;
406         std::vector<double> lstOutX;
407         std::vector<double> lstOutY;
408         std::vector<double> lstOutZ;
409         if (bbGetInputLstIndexsIn().size()==0)
410         {
411                 lstIndexsIn.push_back( lstInX.size() );
412         }
413         if (bbGetInputDoubleContour()==1)
414         {
415                 ClockwisePoints( &lstInX , &lstInY , &lstInZ , &lstIndexsIn );
416                 ShiftValues( &lstInX , &lstInY , &lstInZ , &lstIndexsIn );
417         } // DoubleContour
418         int i,size=lstIndexsIn.size();
419         int iGeneral=0;
420         for (i=0;i<size;i++)
421         {
422                 ProcessBySegment(       bbGetInputType() , 
423                                                         iGeneral,  lstIndexsIn[i] ,
424                                                         &lstInX ,  &lstInY  , &lstInZ,
425                                                         &lstOutX , &lstOutY , &lstOutZ,
426                                                         &lstIndexsOut,bbGetInputOpenClose() );
427         } // for
428
429         if (bbGetInputDoubleContour()==0)
430         {
431                 //////////////////// Set Out   DoubleContour = 0
432                 bbSetOutputLstContourPointsX(lstOutX);  
433                 bbSetOutputLstContourPointsY(lstOutY);  
434                 bbSetOutputLstContourPointsZ(lstOutZ);
435                 bbSetOutputLstIndexsOut(lstIndexsOut);  
436         } else {
437                 RedistributionPoints(&lstOutX,&lstOutY,&lstOutZ,&lstIndexsOut);
438                 ///////////// Second Step Transpose the vectors   
439                 lstInX.clear();
440                 lstInY.clear();
441                 lstInZ.clear();
442                 lstIndexsIn.clear();
443                 size  = bbGetInputNbPoints();
444                 int j,size2 = lstIndexsOut.size();
445                 for (i=0;i<size;i++)
446                 {
447                         for (j=0;j<size2;j++)
448                         {
449                                 lstInX.push_back( lstOutX[ j*lstIndexsOut[j] + i ] );
450                                 lstInY.push_back( lstOutY[ j*lstIndexsOut[j] + i ] );
451                                 lstInZ.push_back( lstOutZ[ j*lstIndexsOut[j] + i ] );
452                         } // for j
453                         lstIndexsIn.push_back( size2 );
454                 } // for i
455                 lstOutX.clear();
456                 lstOutY.clear();
457                 lstOutZ.clear();
458                 lstIndexsOut.clear();
459                 ///////////////////// Third step Interponation 2
460                 size=lstIndexsIn.size();
461                 iGeneral=0;
462                 for (i=0;i<size;i++)
463                 {
464                         ProcessBySegment(       bbGetInputType() , 
465                                                                 iGeneral, lstIndexsIn[i] ,
466                                                                 &lstInX,&lstInY,&lstInZ,
467                                                                 &lstOutX,&lstOutY,&lstOutZ,
468                                                                 &lstIndexsOut,bbGetInputOpenClose2());
469                 } // for
470                 RedistributionPoints(&lstOutX,&lstOutY,&lstOutZ,&lstIndexsOut);
471                 //////////////////// Forth step Transpose the vectors   
472                 lstInX.clear();
473                 lstInY.clear();
474                 lstInZ.clear();
475                 lstIndexsIn.clear();
476                 size  = bbGetInputNbPoints();
477                 size2 = lstIndexsOut.size();
478                 for (i=0;i<size;i++)
479                 {
480                         for (j=0;j<size2;j++)
481                         {
482                                 lstInX.push_back( lstOutX[ j*lstIndexsOut[j] + i ] );
483                                 lstInY.push_back( lstOutY[ j*lstIndexsOut[j] + i ] );
484                                 lstInZ.push_back( lstOutZ[ j*lstIndexsOut[j] + i ] );
485                         } // for j
486                         lstIndexsIn.push_back( size2 );
487                 } // for i
488                 lstOutX.clear();
489                 lstOutY.clear();
490                 lstOutZ.clear();
491                 lstIndexsOut.clear();
492                 //////////////////// Set Out   DoubleContour = 1
493                 bbSetOutputLstContourPointsX(lstInX);   
494                 bbSetOutputLstContourPointsY(lstInY);   
495                 bbSetOutputLstContourPointsZ(lstInZ);
496                 bbSetOutputLstIndexsOut(lstIndexsIn);   
497
498         } // if DoubleContour 
499
500 }
501 //===== 
502 // 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)
503 //===== 
504 void ManualContourModel_Box::bbUserSetDefaultValues()
505 {
506
507 //  SET HERE THE DEFAULT INPUT/OUTPUT VALUES OF YOUR BOX 
508 //    Here we initialize the input 'In' to 0
509    bbSetInputType(1);
510    bbSetInputDoubleContour(0);
511    bbSetInputOpenClose(false);
512    bbSetInputOpenClose2(false);
513    bbSetInputNbPoints(100);
514   
515 }
516 //===== 
517 // 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)
518 //===== 
519 void ManualContourModel_Box::bbUserInitializeProcessing()
520 {
521
522 //  THE INITIALIZATION METHOD BODY :
523 //    Here does nothing 
524 //    but this is where you should allocate the internal/output pointers 
525 //    if any 
526
527   
528 }
529 //===== 
530 // 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)
531 //===== 
532 void ManualContourModel_Box::bbUserFinalizeProcessing()
533 {
534
535 //  THE FINALIZATION METHOD BODY :
536 //    Here does nothing 
537 //    but this is where you should desallocate the internal/output pointers 
538 //    if any
539   
540 }
541 }
542 // EO namespace bbcreaMaracasVisu
543
544