]> Creatis software - creaMaracasVisu.git/blob - bbtk/src/bbcreaMaracasVisuManualContourModel_Box.cxx
a6b2a7e3695b215215dd8c41e228e484af82b737
[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                 lstRstX.clear();
67                 lstRstY.clear();
68                 lstRstZ.clear();
69                 size=(*lstIndexsOut)[iLstIndexOut];
70                 if (size>2)
71                 {
72                         double dist=0,dist2,distSeg,delta;
73                         double dd,dx,dy,dz;
74                         int i,k;
75                         for ( i=iGeneral+1 ; i<iGeneral+size ; i++ )
76                         {
77                                 dx      = (*lstOutX)[i]-(*lstOutX)[i-1];
78                                 dy      = (*lstOutY)[i]-(*lstOutY)[i-1];
79                                 dz      = (*lstOutZ)[i]-(*lstOutZ)[i-1];
80                                 dist= dist+sqrt( dx*dx + dy*dy + dz*dz );
81                         } //for
82                         delta = dist/(size-1);
83                         lstRstX.push_back( (*lstOutX)[iGeneral] );
84                         lstRstY.push_back( (*lstOutY)[iGeneral] );
85                         lstRstZ.push_back( (*lstOutZ)[iGeneral] );
86                         for (i=iGeneral+1; i<iGeneral+size;i++)
87                         {
88                                 dist2 = 0;
89                                 for (k=iGeneral+1; k<iGeneral+size;k++)
90                                 {
91                                         dx = (*lstOutX)[k]-(*lstOutX)[k-1];
92                                         dy = (*lstOutY)[k]-(*lstOutY)[k-1];
93                                         dz = (*lstOutZ)[k]-(*lstOutZ)[k-1];
94                                         distSeg = sqrt( dx*dx + dy*dy + dz*dz );
95                                         ii = i-iGeneral;
96                                         if ( dist2+distSeg >= ii*delta )
97                                         {
98                                                 dd=(ii*delta-dist2)/distSeg;
99                                                 if (distSeg==0)
100                                                 {
101                                                         dd = 0;
102                                                 } // if distSeg == 0
103                                                 lstRstX.push_back( (*lstOutX)[k-1] + dd*dx );
104                                                 lstRstY.push_back( (*lstOutY)[k-1] + dd*dy );
105                                                 lstRstZ.push_back( (*lstOutZ)[k-1] + dd*dz );
106                                                 k=iGeneral+size;
107                                         } else {
108                                                 if ( k==iGeneral+size-1 )
109                                                 {
110                                                         dd = 1;
111                                                         lstRstX.push_back( (*lstOutX)[k-1] + dd*dx );
112                                                         lstRstY.push_back( (*lstOutY)[k-1] + dd*dy );
113                                                         lstRstZ.push_back( (*lstOutZ)[k-1] + dd*dz );
114                                                 }
115                                         }// if dist2 
116                                         dist2 = dist2+distSeg;
117                                 } // for k
118                         } //for i   
119                         if (lstRstX.size()!=size) 
120                         {
121                                 printf("EED Warnning!   ManualContourModel_Box::RedistributionPoints  >> This list is not coherent  iLstIndexOut=%d  lstRstX.size()=%d  size=%d\n",iLstIndexOut, lstRstX.size(), size);
122                         }
123                         for (i=iGeneral; i<iGeneral+size;i++)
124                         {
125                                 ii=i-iGeneral;
126                                 (*lstOutX)[i] = lstRstX[ii];
127                                 (*lstOutY)[i] = lstRstY[ii];
128                                 (*lstOutZ)[i] = lstRstZ[ii];
129                         } // for i
130                 } // if size>2
131                 iGeneral=iGeneral+size;
132         }// for iLstIndexOut
133 }
134
135
136 //-------------------------------------------------------------------------------------------------------------
137
138
139 void ManualContourModel_Box::ExtractContour(    std::vector<double> *lstX,
140                                                                                                 std::vector<double> *lstY, 
141                                                                                                 std::vector<double> *lstZ,
142                                                                                                 std::vector<int>        *lstIndexs,
143                                                                                                 int contour,
144                                                                                                 std::vector<double> *lstOutX,
145                                                                                                 std::vector<double> *lstOutY, 
146                                                                                                 std::vector<double> *lstOutZ )
147 {
148         int     i;
149         int     iLstIndex;
150         int     iContour;
151         int     sizeLstIndexslstIndexs;
152         int     iGeneral;
153         int     iGeneralPlusSize;
154         if ( (lstX!=NULL) &&  (lstY!=NULL) && (lstZ!=NULL) && (lstIndexs!=NULL) && (lstOutX!=NULL) && (lstOutY!=NULL) && (lstOutZ!=NULL) )
155         {
156                 sizeLstIndexslstIndexs  = (*lstIndexs).size();
157                 if  ( sizeLstIndexslstIndexs!=0 ) 
158                 {
159                         (*lstOutX).clear();
160                         (*lstOutY).clear();
161                         (*lstOutZ).clear();
162                         iGeneral                                = 0;
163                         iGeneralPlusSize                = (*lstIndexs)[0];
164                         for ( iContour=1 ; iContour<=contour ; iContour++ )
165                         {
166                                 iGeneral                        = iGeneral+(*lstIndexs)[iContour-1];
167                                 iGeneralPlusSize        = iGeneral+(*lstIndexs)[iContour];
168                         } // for iContour
169                         for ( i=iGeneral ; i<iGeneralPlusSize ; i++ )
170                         {
171                                 (*lstOutX).push_back( (*lstX)[i] );
172                                 (*lstOutY).push_back( (*lstY)[i] );
173                                 (*lstOutZ).push_back( (*lstZ)[i] );                             
174                         } //for
175                 } // size
176         } // NULL
177 }
178
179 void ManualContourModel_Box::PutPointsInContour(std::vector<double> *lstTmpX,
180                                                                                                 std::vector<double> *lstTmpY, 
181                                                                                                 std::vector<double> *lstTmpZ,
182                                                                                                 int contour,
183                                                                                                 std::vector<double> *lstOutX,
184                                                                                                 std::vector<double> *lstOutY, 
185                                                                                                 std::vector<double> *lstOutZ,
186                                                                                                 std::vector<int>        *lstOutIndexs )
187 {
188         int     i;
189         int     iLstIndex;
190         int     iContour;
191         int     sizeLstIndexslstIndexs;
192         int     iGeneral;
193         int     iGeneralPlusSize;
194         int     iSize;
195         int     SizeContour;
196         if ( (lstTmpX!=NULL) &&  (lstTmpY!=NULL) && (lstTmpZ!=NULL)  && (lstOutX!=NULL) && (lstOutY!=NULL) && (lstOutZ!=NULL) && (lstOutIndexs!=NULL) )
197         {
198                 sizeLstIndexslstIndexs  = (*lstOutIndexs).size();
199                 if  ( sizeLstIndexslstIndexs!=0 ) 
200                 {
201                         iGeneral                                = 0;
202                         iGeneralPlusSize                = (*lstOutIndexs)[0];
203                         for ( iContour=1 ; iContour<=contour ; iContour++ )
204                         {
205                                 iGeneral                        = iGeneral + (*lstOutIndexs)[iContour-1];
206                                 SizeContour             = (*lstOutIndexs)[iContour];
207                         } // for iContour
208                         iGeneralPlusSize        = iGeneral + SizeContour;
209                         
210                         if(SizeContour==(*lstTmpX).size() )
211                         {
212                                 int iSize=0;
213                                 for ( i=iGeneral ; i<iGeneralPlusSize ; i++ )
214                                 {
215                                         (*lstOutX)[i] = (*lstTmpX)[iSize] ;
216                                         (*lstOutY)[i] = (*lstTmpY)[iSize] ;
217                                         (*lstOutZ)[i] = (*lstTmpZ)[iSize] ;
218                                         iSize++;                                        
219                                 } //for                 
220                         } else {
221                                 printf("EED Warnning!! ManualContourModel_Box::PutPointsInContour  the lstTmp vector is not of the correct size. \n");
222                                 for ( i=iGeneral ; i<iGeneralPlusSize ; i++ )
223                                 {
224                                         (*lstOutX)[i] = -9999 ;
225                                         (*lstOutY)[i] = -9999 ;
226                                         (*lstOutZ)[i] = -9999 ;
227                                 } //for                 
228                         }
229                 } // size
230         } // NULL
231 }
232
233 double ManualContourModel_Box::SizeContour(     std::vector<double> *lstX,
234                                                                                         std::vector<double> *lstY, 
235                                                                                         std::vector<double> *lstZ)
236 {
237         int     i;
238         double  dx;
239         double  dy;
240         double  dz;
241         double  dist            = 0;
242         int     iSize           = (*lstX).size()  - 1;
243         for ( i=0 ; i<iSize ; i++ )
244         {
245                 dx      = (*lstX)[i+1]-(*lstX)[i];
246                 dy      = (*lstY)[i+1]-(*lstY)[i];
247                 dz      = (*lstZ)[i+1]-(*lstZ)[i];
248                 dist= dist+sqrt( dx*dx + dy*dy + dz*dz );
249         } //for i
250         return dist;
251 }
252
253 void ManualContourModel_Box::Redistribution_SIN(        double alpha,
254                                                                                                         double beta,
255                                                                                                         std::vector<double> *lstInX,
256                                                                                                         std::vector<double> *lstInY, 
257                                                                                                         std::vector<double> *lstInZ,
258                                                                                                         std::vector<double> *lstOutX,
259                                                                                                         std::vector<double> *lstOutY, 
260                                                                                                         std::vector<double> *lstOutZ )
261 {
262         int i,sizeLstInX=(*lstInX).size();
263         (*lstOutX).clear();     
264         (*lstOutY).clear();     
265         (*lstOutZ).clear();     
266         for ( i=0 ; i<sizeLstInX ; i++ )
267         {
268                 (*lstOutX).push_back( (*lstInX)[i] );
269                 (*lstOutY).push_back( (*lstInY)[i] );
270                 (*lstOutZ).push_back( (*lstInZ)[i] );
271         } // for i
272 }
273
274 void ManualContourModel_Box::CopyContour2InContour1(
275                                                                                                         std::vector<double> *lstInX,
276                                                                                                         std::vector<double> *lstInY, 
277                                                                                                         std::vector<double> *lstInZ,
278                                                                                                         std::vector<double> *lstOutX,
279                                                                                                         std::vector<double> *lstOutY, 
280                                                                                                         std::vector<double> *lstOutZ )
281 {
282         int i,sizeLstInX=(*lstInX).size();
283         (*lstOutX).clear();     
284         (*lstOutY).clear();     
285         (*lstOutZ).clear();     
286         for ( i=0 ; i<sizeLstInX ; i++ )
287         {
288                 (*lstOutX).push_back( (*lstInX)[i] );
289                 (*lstOutY).push_back( (*lstInY)[i] );
290                 (*lstOutZ).push_back( (*lstInZ)[i] );
291         } // for i
292 }
293
294 double ManualContourModel_Box::IntegralDistanceTwoContours(std::vector<double> *lstTmpAX,
295                                                                                                                         std::vector<double> *lstTmpAY, 
296                                                                                                                         std::vector<double> *lstTmpAZ,
297                                                                                                                         std::vector<double> *lstTmpBX,
298                                                                                                                         std::vector<double> *lstTmpBY, 
299                                                                                                                         std::vector<double> *lstTmpBZ )
300 {
301         int     i;
302         double  dx;
303         double  dy;
304         double  dz;
305         double  dist            = 0;
306         int     iSize           = (*lstTmpAX).size();
307         for ( i=0 ; i<iSize ; i++ )
308         {
309                 dx      = (*lstTmpAX)[i]-(*lstTmpBX)[i];
310                 dy      = (*lstTmpAY)[i]-(*lstTmpBY)[i];
311                 dz      = (*lstTmpAZ)[i]-(*lstTmpBZ)[i];
312                 dist= dist+ sqrt( dx*dx + dy*dy + dz*dz );
313         } //for i
314         return dist;
315 }
316
317
318 void ManualContourModel_Box::RedistributionPointsAllContours_SIN(       std::vector<double> *lstOutX,
319                                                                                                                                         std::vector<double> *lstOutY, 
320                                                                                                                                         std::vector<double> *lstOutZ,
321                                                                                                                                         std::vector<int>        *lstIndexsOut )
322 {
323         std::vector<double> lstTmp1X;
324         std::vector<double> lstTmp1Y;
325         std::vector<double> lstTmp1Z;
326         std::vector<double> lstTmp2X;
327         std::vector<double> lstTmp2Y;
328         std::vector<double> lstTmp2Z;
329         std::vector<double> lstTmp1aX;
330         std::vector<double> lstTmp1aY;
331         std::vector<double> lstTmp1aZ;
332         int     iContour;
333         double  nbContours              = (*lstIndexsOut).size()-1;
334         double  alpha,iAlpha;
335         double  beta,iBeta;
336         double  sizeContour1;
337         double  sizeContour2;
338         double  distAcum;
339         double minDistAcum;
340         
341         ExtractContour(lstOutX,lstOutY,lstOutZ,lstIndexsOut,0,&lstTmp1X,&lstTmp1Y,&lstTmp1Z);
342         sizeContour1    = SizeContour( &lstTmp1X, &lstTmp1Y, &lstTmp1Z );
343         
344 // Increment    
345         for ( iContour=0; iContour<nbContours ; iContour++ )
346         {
347                 beta    = 0.10;
348 // find Alpha
349                 ExtractContour( lstOutX,lstOutY,lstOutZ,lstIndexsOut, iContour+1 ,&lstTmp2X,&lstTmp2Y,&lstTmp2Z );              
350                 sizeContour2    = SizeContour( &lstTmp2X, &lstTmp2Y, &lstTmp2Z );
351                 if (sizeContour1<sizeContour2){
352                         alpha   = 0;
353                         minDistAcum=-999999999;
354                         for (iAlpha=0.1 ; iAlpha<1; iAlpha=iAlpha+0.1) 
355                         {
356                                 Redistribution_SIN( alpha,beta, &lstTmp1X,&lstTmp1Y,&lstTmp1Z , &lstTmp1aX,&lstTmp1aY,&lstTmp1aZ );
357                                 distAcum = IntegralDistanceTwoContours( &lstTmp1aX,&lstTmp1aY,&lstTmp1aZ , &lstTmp2X,&lstTmp2Y,&lstTmp2Z );
358                                 if (distAcum<minDistAcum) 
359                                 {
360                                         alpha           = iAlpha;
361                                         minDistAcum     = distAcum;
362                                 } // if integerDist
363                         } // for alpha
364 // find Beta
365                         for (iBeta=0.0 ; iBeta<0.2; iBeta=iBeta+0.01) 
366                         {
367                                 minDistAcum=-999999999;
368                                 Redistribution_SIN( alpha,beta, &lstTmp1X,&lstTmp1Y,&lstTmp1Z , &lstTmp1aX,&lstTmp1aY,&lstTmp1aZ );
369                                 distAcum = IntegralDistanceTwoContours( &lstTmp1aX,&lstTmp1aY,&lstTmp1aZ , &lstTmp2X,&lstTmp2Y,&lstTmp2Z );
370                                 if (distAcum<minDistAcum) 
371                                 {
372                                         beta            = iBeta;
373                                         minDistAcum     = distAcum;
374                                 } // if integerDist
375
376                         } // for beta
377                 } //if sizeContour2<sizeContour1
378 // Set Alpha y Beta
379                 Redistribution_SIN( alpha,beta, &lstTmp1X,&lstTmp1Y,&lstTmp1Z , &lstTmp1aX,&lstTmp1aY,&lstTmp1aZ );
380                 double nn       = SizeContour( &lstTmp1aX, &lstTmp1aY, &lstTmp1aZ );
381                 PutPointsInContour(&lstTmp1aX,&lstTmp1aY,&lstTmp1aZ, iContour ,lstOutX,lstOutY,lstOutZ,lstIndexsOut);                           
382                 sizeContour1 = sizeContour2;
383                 CopyContour2InContour1( &lstTmp2X,&lstTmp2Y,&lstTmp2Z , &lstTmp1X,&lstTmp1Y,&lstTmp1Z );
384         } // for iContour 
385 }
386  
387
388
389 void ManualContourModel_Box::RedistributionPoints_SIN_iContour(int iContour,    std::vector<double> *lstOutX,
390                                                                                                         std::vector<double> *lstOutY, 
391                                                                                                         std::vector<double> *lstOutZ,
392                                                                                                         std::vector<int> *lstIndexsOut,double alpha, double beta )
393 {
394 printf("EED ManualContourModel_Box::RedistributionPoints_SIN_iContour  Start \n");
395         std::vector<double> lstRstX;
396         std::vector<double> lstRstY;
397         std::vector<double> lstRstZ;
398         int iLstIndexOut,sizeLstIndexOut = lstIndexsOut->size();
399         int ii,iGeneral;
400         double iiByDelta;
401         int size,iGeneralPlusSize;
402         double Alpha,Beta,t,tt, PI=3.14159265;
403         double TwoPI=2*PI;
404         double dist=0,dist2,distSeg,delta;
405         double dd,dx,dy,dz;
406         int i,k;
407         int firstK;
408         double tmpX,tmpY,tmpZ;
409         iGeneral=0;
410         for (iLstIndexOut=0;  iLstIndexOut<sizeLstIndexOut; iLstIndexOut++)  // For each contour
411         {
412                 lstRstX.clear();
413                 lstRstY.clear();
414                 lstRstZ.clear();
415                 size                            = (*lstIndexsOut)[iLstIndexOut];
416                 iGeneralPlusSize        = iGeneral+size;
417                 if (size>2)
418                 {
419                         dist=0;
420                         for ( i=iGeneral ; i<iGeneralPlusSize-1 ; i++ )
421                         {
422                                 dx      = (*lstOutX)[i]-(*lstOutX)[i+1];
423                                 dy      = (*lstOutY)[i]-(*lstOutY)[i+1];
424                                 dz      = (*lstOutZ)[i]-(*lstOutZ)[i+1];
425                                 dist= dist+sqrt( dx*dx + dy*dy + dz*dz );
426                         } //for
427                         delta = dist/(size-1);
428
429                         firstK  = 0;                    
430                         for (i=iGeneral; i<iGeneralPlusSize;i++)                                //  For each point of one contour
431                         {
432                                 ii = i-iGeneral;
433                                 dist2   = 0;
434                                 for (k=iGeneral; k<iGeneralPlusSize-1;k++)                      // Search inside
435                                 {
436 if ( 385==(*lstOutY)[k]  )
437
438         t               =       ((double)ii) / ((double)(size-1));
439         Beta    = 0.20; //  [0..1]
440         Alpha   = 0.0;  // [0..1]
441         Beta    = bbGetInputParam()[0];
442         Alpha   = bbGetInputParam()[1];
443         tt              = t + 0.70710678182*sin(t*TwoPI)*Beta + Alpha;
444         if (tt>1) { tt=tt-1; }
445         if (tt<0) { tt=tt+1; }
446         iiByDelta = tt * dist;
447 } else {
448   iiByDelta = ii*delta;
449 }
450                                         dx = (*lstOutX)[k+1]-(*lstOutX)[k];
451                                         dy = (*lstOutY)[k+1]-(*lstOutY)[k];
452                                         dz = (*lstOutZ)[k+1]-(*lstOutZ)[k];
453                                         distSeg = sqrt( dx*dx + dy*dy + dz*dz );
454                                         if ( dist2+distSeg >= iiByDelta )
455                                         {
456                                                 if (distSeg==0)
457                                                 {
458                                                         dd = 0;
459                                                 } else {
460                                                         dd=(iiByDelta-dist2)/distSeg;
461                                                 }// if distSeg == 0
462                                                 lstRstX.push_back( (*lstOutX)[k] + dd*dx );
463                                                 lstRstY.push_back( (*lstOutY)[k] + dd*dy );
464                                                 lstRstZ.push_back( (*lstOutZ)[k] + dd*dz );
465                                                 if (ii==0) { firstK=k; }
466                                                 k = iGeneralPlusSize-1;
467                                         } else {
468                                                 if ( k==iGeneral+size-2 )
469                                                 {
470                                                         dd = 1;
471                                                         lstRstX.push_back( (*lstOutX)[k] + dd*dx );
472                                                         lstRstY.push_back( (*lstOutY)[k] + dd*dy );
473                                                         lstRstZ.push_back( (*lstOutZ)[k] + dd*dz );
474                                                 }
475                                         }// if dist2 
476                                         dist2 = dist2+distSeg;
477                                 } // for k
478                         } //for i   
479                         
480                         
481                         if (lstRstX.size()!=size) 
482                         {
483                                 printf("EED Warnning!   ManualContourModel_Box::RedistributionPoints  >> This list is not coherent  iLstIndexOut=%d  lstRstX.size()=%d  size=%d\n",iLstIndexOut, lstRstX.size(), size);
484                                 tmpX    = lstRstX[iGeneral];
485                                 tmpY    = lstRstY[iGeneral];
486                                 tmpZ    = lstRstZ[iGeneral];
487                                 lstRstX.push_back( tmpX );
488                                 lstRstY.push_back( tmpY );
489                                 lstRstZ.push_back( tmpZ );
490                         }
491                         int iii;
492                         for (i=iGeneral; i<iGeneralPlusSize;i++)
493                         {
494 //                              ii=( (i-iGeneral) + firstK) % size ;
495                                 ii= i-iGeneral ;
496                                 iii=iGeneral+ ( (i-iGeneral) + firstK) % size ;
497                                 (*lstOutX)[iii] = lstRstX[ii];
498                                 (*lstOutY)[iii] = lstRstY[ii];
499                                 (*lstOutZ)[iii] = lstRstZ[ii];
500                         } // for i
501                 } // if size>2
502                 iGeneral=iGeneral+size;
503         }// for iLstIndexOut
504         
505 printf("EED ManualContourModel_Box::RedistributionPoints_SIN_iContour  End \n");
506         
507 }
508
509
510
511
512 void ManualContourModel_Box::ClockwisePoints(   std::vector<double> *lstInX,
513                                                                                         std::vector<double> *lstInY, 
514                                                                                         std::vector<double> *lstInZ,
515                                                                                         std::vector<int> *lstIndexsIn )
516 {
517         int     iLstIndexIn,sizeLstIndexIn=lstIndexsIn->size();
518         int     i,iGeneral=0;
519         int     size,size2;
520         double  cx,cy,cz;
521         double  px,py,pz;
522         double  backpx,backpy,backpz;
523         double  ang;
524         char    dir=-1;
525         bool    dirx,diry,dirz;
526         int     flagAng=0;
527         float   backang;
528         double  tmp;
529
530         // For each contour
531         for (iLstIndexIn=0;  iLstIndexIn<sizeLstIndexIn; iLstIndexIn++)
532         {
533                 // Step 1. Find gravity center and direction
534                 size    = (*lstIndexsIn)[iLstIndexIn];
535                 if (size>2)  // for contour with more than 2 points
536                 {
537                         cx              = 0;
538                         cy              = 0;
539                         cz              = 0;
540                         dirx    = true;
541                         diry    = true;
542                         dirz    = true;
543                         for ( i=0 ; i<size ; i++ )
544                         {
545                                 px=(*lstInX)[iGeneral+i];
546                                 py=(*lstInY)[iGeneral+i];
547                                 pz=(*lstInZ)[iGeneral+i];
548                                 cx      = px + cx;
549                                 cy      = py + cy;
550                                 cz      = pz + cz;
551                                 if (i!=0) 
552                                 { 
553                                         if (backpx!=px) { dirx=false; } 
554                                         if (backpy!=py) { diry=false; } 
555                                         if (backpz!=pz) { dirz=false; } 
556                                         backpx=px;
557                                         backpy=py;
558                                         backpz=pz;
559                                 } // if i!=0
560                                 backpx=px; 
561                                 backpy=py; 
562                                 backpz=pz; 
563                         } // for i 
564                         cx=cx/size;
565                         cy=cy/size;
566                         cz=cz/size;
567                         if (dirx==true) { dir=1; }  // YZ 
568                         if (diry==true) { dir=2; }  // XZ 
569                         if (dirz==true) { dir=0; }  // XZ 
570                         // Step 2. Find angle diference find 
571                         flagAng=0;
572                         for ( i=0 ; i<size ; i++ )
573                         {
574                                 px = (*lstInX)[iGeneral+i]-cx;
575                                 py = (*lstInY)[iGeneral+i]-cy;
576                                 pz = (*lstInZ)[iGeneral+i]-cz;
577                                 if (dir==0) { ang=atan2( py , px ); } // XY
578                                 if (dir==1) { ang=atan2( pz , py ); } // YZ
579                                 if (dir==2) { ang=atan2( pz , px ); } // XZ
580                                 if (i>0) 
581                                 { 
582                                         if (backang<ang) 
583                                         {
584                                                 flagAng++;
585                                         } else {
586                                                 flagAng--;
587                                         }// if backang<ang
588                                 } // if i
589                                 backang=ang; 
590                         } // for i 
591
592
593                         // Step 3. Invert order of points
594                         if (flagAng<0)
595                         {
596                                 size2 = size/2;
597                                 for ( i=0 ; i<size2 ; i++ )
598                                 {
599                                         tmp                                                     = (*lstInX)[iGeneral+i];
600                                         (*lstInX)[iGeneral+i]                   = (*lstInX)[iGeneral+size-1-i];
601                                         (*lstInX)[iGeneral+size-1-i]    = tmp;
602                                         tmp                                                     = (*lstInY)[iGeneral+i];
603                                         (*lstInY)[iGeneral+i]                   = (*lstInY)[iGeneral+size-1-i];
604                                         (*lstInY)[iGeneral+size-1-i]    = tmp;
605                                         tmp                                                     = (*lstInZ)[iGeneral+i];
606                                         (*lstInZ)[iGeneral+i]                   = (*lstInZ)[iGeneral+size-1-i];
607                                         (*lstInZ)[iGeneral+size-1-i]    = tmp;
608                                 } // for i
609                         } // flagAng
610                 } // size>2
611                 iGeneral = iGeneral+size;
612         } // for iLstIndexIn
613 }
614
615
616 /*
617 void ManualContourModel_Box::ShiftValues(       std::vector<double> *lstInX,
618                                                                                         std::vector<double> *lstInY, 
619                                                                                         std::vector<double> *lstInZ,
620                                                                                         std::vector<int> *lstIndexsIn )
621 {
622         int iLstIndexIn,sizeLstIndexIn=lstIndexsIn->size();
623         int ii, iGeneral=0;
624         int size,size2;
625         double dist,distMin;
626         int i,iBack;
627         int ig;
628         double dx,dy,dz;
629         std::vector<double> LstTmpX;
630         std::vector<double> LstTmpY;
631         std::vector<double> LstTmpZ;
632         if (sizeLstIndexIn>=2)
633         {
634         
635                 for (iLstIndexIn=0;  iLstIndexIn<sizeLstIndexIn-1; iLstIndexIn++)
636                 {
637                         size  = (*lstIndexsIn)[iLstIndexIn];
638                         size2 = (*lstIndexsIn)[iLstIndexIn+1];
639                         //find min distance and  iBack
640                         distMin = 10000000;
641                         iBack   = 0;
642                         
643                         
644                         for (ig=0; ig<size; ig++)
645                         {
646                                 for ( i=0 ; i<size2 ; i++ )
647                                 {
648                                         dx      = (*lstInX)[iGeneral+ig]-(*lstInX)[iGeneral+size+i];
649                                         dy      = (*lstInY)[iGeneral+ig]-(*lstInY)[iGeneral+size+i];
650                                         dz      = (*lstInZ)[iGeneral+ig]-(*lstInZ)[iGeneral+size+i];
651                                         dist= sqrt( dx*dx + dy*dy + dz*dz );
652                                         if ( dist<distMin ) 
653                                         {
654                                                 iBack   = i-ig;
655                                                 distMin = dist;
656                                         }
657                                 } // for i size2
658                         } // for ig size
659
660 if (iBack<0) 
661 {
662         printf("- "); 
663         iBack = iBack + size2; 
664 }
665                         
666 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);
667                         
668                         if (iBack!=0)
669                         {
670                                 LstTmpX.clear();
671                                 LstTmpY.clear();
672                                 LstTmpZ.clear();
673                                 for (i=0 ; i<size2 ; i++) 
674                                 {
675                                         ii= (i+iBack)%size2;
676                                         LstTmpX.push_back( (*lstInX)[iGeneral+size+ii] );
677                                         LstTmpY.push_back( (*lstInY)[iGeneral+size+ii] );
678                                         LstTmpZ.push_back( (*lstInZ)[iGeneral+size+ii] );
679                                 } // for i                              
680                                 for (i=0 ; i<size2 ; i++) 
681                                 {
682                                         (*lstInX)[iGeneral+size+i] = LstTmpX[i];
683                                         (*lstInY)[iGeneral+size+i] = LstTmpY[i];
684                                         (*lstInZ)[iGeneral+size+i] = LstTmpZ[i];
685                                 } // for i                              
686                         }
687                         iGeneral=iGeneral+size;
688                 } // for iLstIndexIn
689                 
690 //------------          
691                 
692                 iGeneral=0;
693
694                 for (iLstIndexIn=0;  iLstIndexIn<sizeLstIndexIn-1; iLstIndexIn++)
695                 {
696                         size  = (*lstIndexsIn)[iLstIndexIn];
697                         size2 = (*lstIndexsIn)[iLstIndexIn+1];
698                         //find min distance and  iBack
699                         distMin = 10000000;
700                         iBack   = 0;
701                         
702                         
703 //                      for (ig=0; ig<size; ig++)
704 //                      {
705                                 for ( i=0 ; i<size2 ; i++ )
706                                 {
707                                         dx      = (*lstInX)[iGeneral]-(*lstInX)[iGeneral+size+i];
708                                         dy      = (*lstInY)[iGeneral]-(*lstInY)[iGeneral+size+i];
709                                         dz      = (*lstInZ)[iGeneral]-(*lstInZ)[iGeneral+size+i];
710                                         dist= sqrt( dx*dx + dy*dy + dz*dz );
711                                         if ( dist<distMin ) 
712                                         {
713                                                 iBack   = i;
714                                                 distMin = dist;
715                                         }
716                                 } // for i size2
717 //                      } // for ig size
718
719                         
720 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);
721                         
722                         if (iBack!=0)
723                         {
724                                 LstTmpX.clear();
725                                 LstTmpY.clear();
726                                 LstTmpZ.clear();
727                                 for (i=0 ; i<size2 ; i++) 
728                                 {
729                                         ii= (i+iBack)%size2;
730                                         LstTmpX.push_back( (*lstInX)[iGeneral+size+ii] );
731                                         LstTmpY.push_back( (*lstInY)[iGeneral+size+ii] );
732                                         LstTmpZ.push_back( (*lstInZ)[iGeneral+size+ii] );
733                                 } // for i                              
734                                 for (i=0 ; i<size2 ; i++) 
735                                 {
736                                         (*lstInX)[iGeneral+size+i] = LstTmpX[i];
737                                         (*lstInY)[iGeneral+size+i] = LstTmpY[i];
738                                         (*lstInZ)[iGeneral+size+i] = LstTmpZ[i];
739                                 } // for i                              
740                         }
741                         iGeneral=iGeneral+size;
742                 } // for iLstIndexIn
743                 
744         } // if sizeLstIndexIn
745         
746 }
747 */
748
749
750
751 void ManualContourModel_Box::ShiftValues(       std::vector<double> *lstInX,
752                                                                                         std::vector<double> *lstInY, 
753                                                                                         std::vector<double> *lstInZ,
754                                                                                         std::vector<int> *lstIndexsIn )
755 {
756         int iLstIndexIn,sizeLstIndexIn=lstIndexsIn->size();
757         int ii, iGeneral=0;
758         int size,size2;
759         double dist,distMin;
760         int i,iBack;
761         int ig;
762         double dx,dy,dz;
763         std::vector<double> LstTmpX;
764         std::vector<double> LstTmpY;
765         std::vector<double> LstTmpZ;
766         if (sizeLstIndexIn>=2)
767         {
768         
769           
770          
771                 for (iLstIndexIn=0;  iLstIndexIn<sizeLstIndexIn-1; iLstIndexIn++)
772                 {
773                         size  = (*lstIndexsIn)[iLstIndexIn];
774                         size2 = (*lstIndexsIn)[iLstIndexIn+1];
775                         //find min distance and  iBack
776                         distMin = 10000000;
777                         iBack   = 0;
778                         
779                     // Comparing distance between two contours  
780                     // Both contours need the same size 
781                         for (ig=0; ig<size; ig++)
782                         {
783                                 dist=0;
784                                 for ( i=0 ; i<size2 ; i++ )
785                                 {
786                                         dx      = (*lstInX)[iGeneral+i]-(*lstInX)[iGeneral+size+(i+ig)%size];
787                                         dy      = (*lstInY)[iGeneral+i]-(*lstInY)[iGeneral+size+(i+ig)%size];
788                                         dz      = (*lstInZ)[iGeneral+i]-(*lstInZ)[iGeneral+size+(i+ig)%size];
789                                         dist= dist + sqrt( dx*dx + dy*dy + dz*dz );
790                                 } // for i size2
791
792                                 if ( dist<distMin ) 
793                                 {
794                                         iBack   = ig+size;
795                                         distMin = dist;
796                                 }
797                                 
798                         } // for ig size
799
800                         
801 //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);
802                         
803                         if (iBack!=0)
804                         {
805                                 LstTmpX.clear();
806                                 LstTmpY.clear();
807                                 LstTmpZ.clear();
808                                 for (i=0 ; i<size2 ; i++) 
809                                 {
810                                         ii = (i+iBack)%size2;
811                                         if (ii<(size2-1)) // Skip the last item
812                                         {
813                                                 LstTmpX.push_back( (*lstInX)[iGeneral+size+ii] );
814                                                 LstTmpY.push_back( (*lstInY)[iGeneral+size+ii] );
815                                                 LstTmpZ.push_back( (*lstInZ)[iGeneral+size+ii] );
816                                         }
817                                 } // for i
818                                 
819                                 //Repeat the first item at the end to close the contour
820                                 LstTmpX.push_back( LstTmpX[0] );
821                                 LstTmpY.push_back( LstTmpY[0] );
822                                 LstTmpZ.push_back( LstTmpZ[0] );
823
824                                 for (i=0 ; i<size2 ; i++) 
825                                 {
826                                         (*lstInX)[iGeneral+size+i] = LstTmpX[i];
827                                         (*lstInY)[iGeneral+size+i] = LstTmpY[i];
828                                         (*lstInZ)[iGeneral+size+i] = LstTmpZ[i];
829                                 } // for i                              
830                         }
831                         iGeneral=iGeneral+size;
832                 } // for iLstIndexIn
833                 
834                 
835         } // if sizeLstIndexIn
836         
837 }
838
839
840
841
842
843
844 void ManualContourModel_Box::Process()
845 {
846 // THE MAIN PROCESSING METHOD BODY
847 //   Here we simply set the input 'In' value to the output 'Out'
848 //   And print out the output value
849 // INPUT/OUTPUT ACCESSORS ARE OF THE FORM :
850 //    void bbSet{Input|Output}NAME(const TYPE&)
851 //    const TYPE& bbGet{Input|Output}NAME() const 
852 //    Where :
853 //    * NAME is the name of the input/output
854 //      (the one provided in the attribute 'name' of the tag 'input')
855 //    * TYPE is the C++ type of the input/output
856 //      (the one provided in the attribute 'type' of the tag 'input')
857
858 //    bbSetOutputOut( bbGetInputIn() );
859 //    std::cout << "Output value = " <<bbGetOutputOut() << std::endl;
860
861         // First Step  Spline Interpolation
862         std::vector<double> lstInX=bbGetInputLstControlPointsX();
863         std::vector<double> lstInY=bbGetInputLstControlPointsY();
864         std::vector<double> lstInZ=bbGetInputLstControlPointsZ();
865         if ( (lstInX.size()!=lstInY.size()) || (lstInY.size()!=lstInZ.size()) ) 
866         { 
867                 printf("Warnning !!  .. ManualContourModel_Box: The list X Y Z, no have the same number of elements \n");
868                 return;
869         }
870         std::vector<int>        lstIndexsIn=bbGetInputLstIndexsIn();
871         std::vector<int>        lstIndexsOut;
872         std::vector<double> lstOutX;
873         std::vector<double> lstOutY;
874         std::vector<double> lstOutZ;
875         if (bbGetInputLstIndexsIn().size()==0)
876         {
877                 lstIndexsIn.push_back( lstInX.size() );
878         }
879         
880 // Step 1.  All contours the same clockwise direction (Control Points)
881         if (bbGetInputDoubleContour()==1)
882         {
883                 ClockwisePoints( &lstInX , &lstInY , &lstInZ , &lstIndexsIn );
884 //              ShiftValues( &lstInX , &lstInY , &lstInZ , &lstIndexsIn );
885         } // DoubleContour
886         int i,size=lstIndexsIn.size();
887         int iGeneral=0;
888         
889 // Step 2.  Spline interpolation of control points      
890         for (i=0;i<size;i++)
891         {
892                 ProcessBySegment(       bbGetInputType() , 
893                                                         iGeneral,  lstIndexsIn[i] ,
894                                                         &lstInX ,  &lstInY  , &lstInZ,
895                                                         &lstOutX , &lstOutY , &lstOutZ,
896                                                         &lstIndexsOut,bbGetInputOpenClose() );
897         } // for
898
899         if (bbGetInputDoubleContour()==0)
900         {
901 // Finish if Simple contours
902                 //////////////////// Set Out   DoubleContour = 0
903                 bbSetOutputLstContourPointsX(lstOutX);  
904                 bbSetOutputLstContourPointsY(lstOutY);  
905                 bbSetOutputLstContourPointsZ(lstOutZ);
906                 bbSetOutputLstIndexsOut(lstIndexsOut);  
907         } else {
908 // Step 3. Interpolation in the other direction
909 // Step 3.1 Linear Normalice points around contours     
910                 RedistributionPoints(&lstOutX,&lstOutY,&lstOutZ,&lstIndexsOut);
911 //EED 01/2021           
912 // Step 3.2 Shift points to find minimun acumulate distance     
913                 ShiftValues( &lstOutX, &lstOutY, &lstOutZ, &lstIndexsOut );
914 // Step 3.3. SIN Normalice points around contours       
915 //              RedistributionPoints_SIN_iContour(-1, &lstOutX,&lstOutY,&lstOutZ,&lstIndexsOut,-1,-1);
916                 RedistributionPointsAllContours_SIN( &lstOutX,&lstOutY,&lstOutZ,&lstIndexsOut);
917 //              ShiftValues( &lstOutX, &lstOutY, &lstOutZ, &lstIndexsOut );
918 // Step 3.4 Transpose the vectors   
919                 lstInX.clear();
920                 lstInY.clear();
921                 lstInZ.clear();
922                 lstIndexsIn.clear();
923                 size  = bbGetInputNbPoints();
924                 int j,size2 = lstIndexsOut.size();
925                 for (i=0;i<size;i++)
926                 {
927                         for (j=0;j<size2;j++)
928                         {
929                                 lstInX.push_back( lstOutX[ j*lstIndexsOut[j] + i ] );
930                                 lstInY.push_back( lstOutY[ j*lstIndexsOut[j] + i ] );
931                                 lstInZ.push_back( lstOutZ[ j*lstIndexsOut[j] + i ] );
932                         } // for j
933                         lstIndexsIn.push_back( size2 );
934                 } // for i
935                 lstOutX.clear();
936                 lstOutY.clear();
937                 lstOutZ.clear();
938                 lstIndexsOut.clear();
939 // Step 3.5 Interponation 2
940                 size=lstIndexsIn.size();
941                 iGeneral=0;
942                 for (i=0;i<size;i++)
943                 {
944                         ProcessBySegment(       bbGetInputType() , 
945                                                                 iGeneral, lstIndexsIn[i] ,
946                                                                 &lstInX,&lstInY,&lstInZ,
947                                                                 &lstOutX,&lstOutY,&lstOutZ,
948                                                                 &lstIndexsOut,bbGetInputOpenClose2());
949                 } // for
950                 RedistributionPoints(&lstOutX,&lstOutY,&lstOutZ,&lstIndexsOut);
951 // Step 3.6 Transpose the vectors   
952                 lstInX.clear();
953                 lstInY.clear();
954                 lstInZ.clear();
955                 lstIndexsIn.clear();
956                 size  = bbGetInputNbPoints();
957                 size2 = lstIndexsOut.size();
958                 for (i=0;i<size;i++)
959                 {
960                         for (j=0;j<size2;j++)
961                         {
962                                 lstInX.push_back( lstOutX[ j*lstIndexsOut[j] + i ] );
963                                 lstInY.push_back( lstOutY[ j*lstIndexsOut[j] + i ] );
964                                 lstInZ.push_back( lstOutZ[ j*lstIndexsOut[j] + i ] );
965                         } // for j
966                         lstIndexsIn.push_back( size2 );
967                 } // for i
968                 lstOutX.clear();
969                 lstOutY.clear();
970                 lstOutZ.clear();
971                 lstIndexsOut.clear();
972                 //////////////////// Set Out   DoubleContour = 1
973                 bbSetOutputLstContourPointsX(lstInX);   
974                 bbSetOutputLstContourPointsY(lstInY);   
975                 bbSetOutputLstContourPointsZ(lstInZ);
976                 bbSetOutputLstIndexsOut(lstIndexsIn);   
977
978         } // if DoubleContour 
979
980 }
981 //===== 
982 // 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)
983 //===== 
984 void ManualContourModel_Box::bbUserSetDefaultValues()
985 {
986
987 //  SET HERE THE DEFAULT INPUT/OUTPUT VALUES OF YOUR BOX 
988 //    Here we initialize the input 'In' to 0
989    bbSetInputType(1);
990    bbSetInputDoubleContour(0);
991    bbSetInputOpenClose(false);
992    bbSetInputOpenClose2(false);
993    bbSetInputNbPoints(100);
994   
995 }
996 //===== 
997 // 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)
998 //===== 
999 void ManualContourModel_Box::bbUserInitializeProcessing()
1000 {
1001
1002 //  THE INITIALIZATION METHOD BODY :
1003 //    Here does nothing 
1004 //    but this is where you should allocate the internal/output pointers 
1005 //    if any 
1006
1007   
1008 }
1009 //===== 
1010 // 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)
1011 //===== 
1012 void ManualContourModel_Box::bbUserFinalizeProcessing()
1013 {
1014
1015 //  THE FINALIZATION METHOD BODY :
1016 //    Here does nothing 
1017 //    but this is where you should desallocate the internal/output pointers 
1018 //    if any
1019   
1020 }
1021 }
1022 // EO namespace bbcreaMaracasVisu
1023
1024