]> Creatis software - creaMaracasVisu.git/blob - bbtk/src/bbcreaMaracasVisuShowNPoints_Tools.cxx
3517 ShowNPoints actual Point
[creaMaracasVisu.git] / bbtk / src / bbcreaMaracasVisuShowNPoints_Tools.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 "bbcreaMaracasVisuShowNPoints_Tools.h"
5 #include "bbcreaMaracasVisuPackage.h"
6
7 #include <vtkPointData.h>
8 #include <vtkDataArray.h>
9 #include <vtkMath.h>
10
11
12 namespace bbcreaMaracasVisu
13 {
14
15 BBTK_ADD_BLACK_BOX_TO_PACKAGE(creaMaracasVisu,ShowNPoints_Tools)
16 BBTK_BLACK_BOX_IMPLEMENTATION(ShowNPoints_Tools,bbtk::AtomicBlackBox);
17
18
19
20 void ShowNPoints_Tools::NearestPointToMesh( vtkPoints *points,vtkStaticPointLocator *pointLocator,double *spc,double *p,double *pM)
21 {
22     p[0]  = p[0] * spc[0];
23     p[1]  = p[1] * spc[1];
24     p[2]  = p[2] * spc[2];
25     points->GetPoint( pointLocator->FindClosestPoint(p) , pM );
26     pM[0] = pM[0] / spc[0];
27     pM[1] = pM[1] / spc[1];
28     pM[2] = pM[2] / spc[2];
29 }
30
31 void ShowNPoints_Tools::CreatePatch_3points()
32 {
33         //printf("PG ShowNPoints_Tools::CreatePatch_3points  Entered patch 3 points !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
34         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
35         
36         std::vector<double> lstX = wsp->GetModelShowNPoints()->GetLstPointsX();
37         std::vector<double> lstY = wsp->GetModelShowNPoints()->GetLstPointsY();
38         std::vector<double> lstZ = wsp->GetModelShowNPoints()->GetLstPointsZ();
39         
40         double pA[3];
41     pA[0] = lstX[0];
42     pA[1] = lstY[0];
43     pA[2] = lstZ[0];
44     double pB[3];
45     pB[0] = lstX[1];
46     pB[1] = lstY[1];
47     pB[2] = lstZ[1];
48     double pC[3];
49     pC[0] = lstX[2];
50     pC[1] = lstY[2];
51     pC[2] = lstZ[2];
52
53         double v[3];
54         double u[3];
55         vtkMath::Subtract(pC,pA,v);
56         vtkMath::Subtract(pB,pA,u);
57         
58         /**point in AC closest to B.
59         *formula t=(V)dot(U)/(V)dot(V)
60         */
61         double t = vtkMath::Dot(v,u)/vtkMath::Dot(v,v);
62         /**nP found point
63         *formula A+t(C-A) -> A+tV
64         */
65         vtkMath::MultiplyScalar(v, t);
66         double nP[3];
67         vtkMath::Add(pA, v, nP);
68         
69         //calculate direction vector from found point to B
70         double dirVector[3];
71         vtkMath::Subtract(pB, nP, dirVector);
72         
73         double pointAdd[3];
74         double pointSub[3];
75         
76         //Add and subtract direction vector to A and C to find the 4 points to create the patch,
77         
78         std::vector<double> resListX;
79         std::vector<double> resListY;
80         std::vector<double> resListZ;
81         
82         vtkMath::Add(pA, dirVector, pointAdd);
83         vtkMath::Subtract(pA, dirVector, pointSub);
84         
85         resListX.push_back(pointSub[0]);
86         resListY.push_back(pointSub[1]);
87         resListZ.push_back(pointSub[2]);
88
89         resListX.push_back(pointAdd[0]);
90         resListY.push_back(pointAdd[1]);
91         resListZ.push_back(pointAdd[2]);
92         
93         
94         vtkMath::Add(pC, dirVector, pointAdd);
95         vtkMath::Subtract(pC, dirVector, pointSub);
96         
97         resListX.push_back(pointAdd[0]);
98         resListY.push_back(pointAdd[1]);
99         resListZ.push_back(pointAdd[2]);
100         
101         resListX.push_back(pointSub[0]);
102         resListY.push_back(pointSub[1]);
103         resListZ.push_back(pointSub[2]);
104
105         //Create patch given the previously calculated points (4 points)
106         CreatePatch_Points(resListX, resListY, resListZ);
107 }
108
109 void ShowNPoints_Tools::CreatePatch_4points()
110 {
111         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
112              
113         std::vector<double> lstX = wsp->GetModelShowNPoints()->GetLstPointsX();
114         std::vector<double> lstY = wsp->GetModelShowNPoints()->GetLstPointsY();
115         std::vector<double> lstZ = wsp->GetModelShowNPoints()->GetLstPointsZ();
116         CreatePatch_Points(lstX, lstY, lstZ);
117 }
118
119 void ShowNPoints_Tools::InitCreatePatch_Points()
120 {
121         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
122         wsp->StopAutoAddPoints();
123     wsp->StopTrackPoint();
124         if((wsp->GetLstModelShowNPointsSize()==1) && (bbGetInputMesh()!=NULL ))
125     {
126                 if(wsp->GetModelShowNPoints()->GetLstPointsSize()==4){
127                         CreatePatch_4points();
128                 }
129                 else if(wsp->GetModelShowNPoints()->GetLstPointsSize()==3){
130                         CreatePatch_3points();
131                 }
132                 else{
133                         printf("PG ShowNPoints_Tools::CreatePatch_Npoints  Warning patch not apply. Number of points is invalid. Group should have 3 or 4 points\n");
134                 }
135         }
136         else{
137                 printf("PG ShowNPoints_Tools::CreatePatch_Npoints  Warning patch not apply. groups or mesh invalid. Need 1 group of 3 or 4 points, and a mesh\n");
138     } // if wsp && mesh
139 }
140
141 void ShowNPoints_Tools::InitCreateVolumeSurface_Points()
142 {
143     InitCreatePatch_Points();   //  1 group -> 3 groups
144     
145     // 3 groups to 4 groups
146     WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
147     wsp->StopAutoAddPoints();
148     wsp->StopTrackPoint();
149     if( wsp->GetLstModelShowNPointsSize()==3 )
150     {
151         double spc[3];
152         double pC1[3];    // fist point
153         double dx,dy,dz;
154         double pC2A[3];  // first middle point
155         double pC2B[3];  // second midle point
156         double pC3[3];   // last point
157         double pN[3];    // new over the surface
158
159         vtkPoints               *points         = bbGetInputMesh()->GetPoints();
160         vtkStaticPointLocator   *pointLocator   = vtkStaticPointLocator::New();
161         pointLocator->SetDataSet( bbGetInputMesh() );
162         pointLocator->BuildLocator();
163         spc[0]          = bbGetInputSpacing()[0];
164         spc[1]          = bbGetInputSpacing()[1];
165         spc[2]          = bbGetInputSpacing()[2];
166         wsp->InsertCollectionAfter_();
167         wsp->GetCollectionPoint(1,0, pC1);
168         wsp->GetCollectionPoint(1,2, pC3);
169         dx=pC3[0]-pC1[0];
170         dy=pC3[1]-pC1[1];
171         dz=pC3[2]-pC1[2];
172         pC2A[0]=pC1[0]+dx*0.33333;   pC2A[1]=pC1[1]+dy*0.3333;   pC2A[2]=pC1[2]+dz*0.33333;
173         pC2B[0]=pC1[0]+dx*0.66666;   pC2B[1]=pC1[1]+dy*0.6666;   pC2B[2]=pC1[2]+dz*0.66666;
174         
175         wsp->InsertPoint(pC1[0] ,pC1[1], pC1[2],"");
176         
177         NearestPointToMesh(points, pointLocator, spc, pC2A,pN);
178         wsp->InsertPoint(pN[0] ,pN[1], pN[2],"");
179         
180         NearestPointToMesh(points, pointLocator, spc, pC2B,pN);
181         wsp->InsertPoint(pN[0] ,pN[1], pN[2],"");
182         
183         wsp->InsertPoint(pC3[0] ,pC3[1], pC3[2],"");
184         
185         
186         // Add points to the other Groups
187         std::vector<double> pointStart;
188         pointStart.push_back( pC1[0] );
189         pointStart.push_back( pC1[1] );
190         pointStart.push_back( pC1[2] );
191         std::vector<double> pointEnd;
192         pointEnd.push_back( pC3[0] );
193         pointEnd.push_back( pC3[1] );
194         pointEnd.push_back( pC3[2] );
195
196         printf("EED ShowNPoints_Tools::InitCreateVolumeSurface_Points 1\n");
197         wsp->SetActualCollection(0);
198         printf("EED ShowNPoints_Tools::InitCreateVolumeSurface_Points 2\n");
199         wsp->SetReferencePoint(pointStart);
200         printf("EED ShowNPoints_Tools::InitCreateVolumeSurface_Points 3\n");
201         wsp->OnInsertPoint_();
202         printf("EED ShowNPoints_Tools::InitCreateVolumeSurface_Points 4\n");
203         wsp->SetReferencePoint(pointEnd);
204         printf("EED ShowNPoints_Tools::InitCreateVolumeSurface_Points 5\n");
205         wsp->OnInsertPoint_();
206         printf("EED ShowNPoints_Tools::InitCreateVolumeSurface_Points 6\n");
207
208         wsp->SetActualCollection(2);
209         wsp->SetReferencePoint(pointStart);
210         wsp->OnInsertPoint_();
211         wsp->SetReferencePoint(pointEnd);
212         wsp->OnInsertPoint_();
213
214         // --- Finish ---
215         wsp->SetOutputBox();
216         wsp->UndoRedo_SaveCollection();
217
218     } // if wsp && mesh
219 }
220
221
222 void ShowNPoints_Tools::CreatePatch_Points(std::vector<double> lstX, std::vector<double> lstY, std::vector<double> lstZ)
223 {
224     WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
225     std::vector<long int>   lstIdNormalSurface;
226     double                  spc[3];
227                             spc[0]          = bbGetInputSpacing()[0];
228                             spc[1]          = bbGetInputSpacing()[1];
229                             spc[2]          = bbGetInputSpacing()[2];
230     vtkPoints               *points         = bbGetInputMesh()->GetPoints();
231     vtkStaticPointLocator   *pointLocator   = vtkStaticPointLocator::New();
232     pointLocator->SetDataSet( bbGetInputMesh() );
233     pointLocator->BuildLocator();
234     wsp->StopTrackPoint();
235     double p[3],pM[3];
236     double dx,dy,dz;
237     
238     wsp->DeleteAllPoints_();
239     //wsp->ErasePoint( 0 );
240     //wsp->ErasePoint( 0 );
241     //wsp->ErasePoint( 0 );
242     //wsp->ErasePoint( 0 );
243     // --- Group 0 ---
244     dx = lstX[1]-lstX[0];
245     dy = lstY[1]-lstY[0];
246     dz = lstZ[1]-lstZ[0];
247     //
248     //
249     double part = 0.25;
250     for(int sect = 0; sect < 5; sect++)
251     {
252         p[0] = lstX[0] + dx*(sect*part);
253                 p[1] = lstY[0] + dy*(sect*part);
254                 p[2] = lstZ[0] + dz*(sect*part);
255                 if(sect == 4){
256                         p[0] = p[0] + 0.5*(((lstX[1]+lstX[2])/2)-p[0]);
257                         p[1] = p[1] + 0.5*(((lstY[1]+lstY[2])/2)-p[1]);
258                         p[2] = p[2] + 0.5*(((lstZ[1]+lstZ[2])/2)-p[2]);
259                 }
260                 if(sect == 0){
261                         p[0] = p[0] + 0.5*(((lstX[0]+lstX[3])/2)-p[0]);
262                         p[1] = p[1] + 0.5*(((lstY[0]+lstY[3])/2)-p[1]);
263                         p[2] = p[2] + 0.5*(((lstZ[0]+lstZ[3])/2)-p[2]);
264                 }
265                 NearestPointToMesh(points, pointLocator, spc, p,pM);
266                 wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
267                 if(sect == 0 || sect == 4) lstIdNormalSurface.push_back( pointLocator->FindClosestPoint(pM) );
268     }
269         
270     // --- Group 1 ---
271     double centroid[3];
272     
273     wsp->InsertCollectionAfter_();
274       p[0] = (lstX[0]+lstX[3])/2;
275       p[1] = (lstY[0]+lstY[3])/2;
276       p[2] = (lstZ[0]+lstZ[3])/2;
277       NearestPointToMesh(points, pointLocator, spc, p,pM);
278       wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
279       p[0] = (lstX[1]+lstX[2])/2;
280       p[1] = (lstY[1]+lstY[2])/2;
281       p[2] = (lstZ[1]+lstZ[2])/2;
282       NearestPointToMesh(points, pointLocator, spc, p,pM);
283       wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
284       p[0] = (lstX[0]+lstX[1]+lstX[2]+lstX[3])/4;          p[1] = (lstY[0]+lstY[1]+lstY[2]+lstY[3])/4;          p[2] = (lstZ[0]+lstZ[1]+lstZ[2]+lstZ[3])/4;
285       wsp->InsertPoint(p[0] ,p[1], p[2],"");
286           std::copy(std::begin(p), std::end(p), std::begin(centroid));
287     // --- Group 2 ---
288     wsp->InsertCollectionAfter_();
289     dx = lstX[2]-lstX[3];
290     dy = lstY[2]-lstY[3];
291     dz = lstZ[2]-lstZ[3];  
292     for(int sect = 0; sect < 5; sect++)
293     {
294         p[0] = lstX[3] + dx*(sect*part);
295                 p[1] = lstY[3] + dy*(sect*part);
296                 p[2] = lstZ[3] + dz*(sect*part);
297                 if(sect == 4){
298                         p[0] = p[0] + 0.5*(((lstX[1]+lstX[2])/2)-p[0]);
299                         p[1] = p[1] + 0.5*(((lstY[1]+lstY[2])/2)-p[1]);
300                         p[2] = p[2] + 0.5*(((lstZ[1]+lstZ[2])/2)-p[2]);
301                 }
302                 if(sect == 0){
303                         p[0] = p[0] + 0.5*(((lstX[0]+lstX[3])/2)-p[0]);
304                         p[1] = p[1] + 0.5*(((lstY[0]+lstY[3])/2)-p[1]);
305                         p[2] = p[2] + 0.5*(((lstZ[0]+lstZ[3])/2)-p[2]);
306                 }
307                 NearestPointToMesh(points, pointLocator, spc, p,pM);
308                 wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
309                 if(sect == 0 || sect == 4) lstIdNormalSurface.push_back( pointLocator->FindClosestPoint(pM) );
310     }
311      pointLocator->Delete();
312     // Check normals
313 //        1. Recorrer las normales de lstIdNormals y calcular el promedio  -> V1
314     double          *nValue;
315         double                  n1[3];
316     vtkPointData    *pointdata  =  bbGetInputMesh()->GetPointData();
317     vtkDataArray    *dataarray  = pointdata->GetNormals();
318         int i,size = lstIdNormalSurface.size();
319         n1[0]=0;
320         n1[1]=0;
321         n1[2]=0;
322         for (i=0; i<size; i++)
323         {
324             nValue        = dataarray->GetTuple3( lstIdNormalSurface[i] );
325                 n1[0] = n1[0] + nValue[0];
326                 n1[1] = n1[1] + nValue[1];
327                 n1[2] = n1[2] + nValue[2];
328         } // for i
329         n1[0] = n1[0]/size;
330         n1[1] = n1[1]/size;
331         n1[2] = n1[2]/size;
332
333 //        2. Calcular el promedio de 4 normales de la nueva superficie     -> V2
334     double pC[3];
335     double pM1[3];
336     double pM2[3];
337     double n2[3];
338     n2[0] = 0;
339     n2[1] = 0;
340     n2[2] = 0;
341     // Collection 0 with 4 points
342     // Collection 1 with 3 points
343     // Collection 2 with 4 points
344     wsp->GetCollectionPoint(1,1, pC);
345     
346     wsp->GetCollectionPoint(0,0, pM);
347     vtkMath::Subtract(pM,pC,pM1);
348     wsp->GetCollectionPoint(0,3, pM);
349     vtkMath::Subtract(pM,pC,pM2);
350     vtkMath::Cross(pM1,pM2,pM);
351     n2[0] = pM[0];
352     n2[1] = pM[1];
353     n2[2] = pM[2];
354
355     wsp->GetCollectionPoint(0,3, pM);
356     vtkMath::Subtract(pM,pC,pM1);
357     wsp->GetCollectionPoint(2,3, pM);
358     vtkMath::Subtract(pM,pC,pM2);
359     vtkMath::Cross(pM1,pM2,pM);
360     n2[0] = n2[0] + pM[0];
361     n2[1] = n2[1] + pM[1];
362     n2[2] = n2[2] + pM[2];
363
364     wsp->GetCollectionPoint(2,3, pM);
365     vtkMath::Subtract(pM,pC,pM1);
366     wsp->GetCollectionPoint(2,0, pM);
367     vtkMath::Subtract(pM,pC,pM2);
368     vtkMath::Cross(pM1,pM2,pM);
369     n2[0] = n2[0] + pM[0];
370     n2[1] = n2[1] + pM[1];
371     n2[2] = n2[2] + pM[2];
372     
373     wsp->GetCollectionPoint(2,0, pM);
374     vtkMath::Subtract(pM,pC,pM1);
375     wsp->GetCollectionPoint(0,0, pM);
376     vtkMath::Subtract(pM,pC,pM2);
377     vtkMath::Cross(pM1,pM2,pM);
378     n2[0] = n2[0] + pM[0];
379     n2[1] = n2[1] + pM[1];
380     n2[2] = n2[2] + pM[2];
381     
382     n2[0] = n2[0] / 4;
383     n2[1] = n2[1] / 4;
384     n2[2] = n2[2] / 4;
385     
386 //        3. Calcular el angulo entre V1 y V2
387     double angle = vtkMath::AngleBetweenVectors(n1,n2) * 180 / vtkMath::Pi();
388 //        4. Si el angulo es major de 90 Invertir las normales de la superficie actual
389     if (angle<90)
390     {
391         vtkMath::MultiplyScalar(n2, -1);
392         wsp->InvertLstPoints_();
393     } // if angle
394     std::vector<double> normalOut(n2, n2 + 3);
395     double norm = vtkMath::Norm(n2);
396     normalOut[0] = normalOut[0]/norm;
397         normalOut[1] = normalOut[1]/norm;
398         normalOut[2] = normalOut[2]/norm;
399         
400         std::vector<double> outputData;
401         outputData.insert(outputData.end(), &centroid[0], &centroid[3]);
402         outputData.insert(outputData.end(), &normalOut[0], &normalOut[3]);
403         
404         bbSetOutputOut(outputData);
405     //bbSetOutputOut(normalOut);
406     
407     // --- Finish ---
408     wsp->SetOutputBox();
409     wsp->UndoRedo_SaveCollection();
410 }
411
412 void ShowNPoints_Tools::MovePatchCenter()
413 {       
414         std::vector<double> params = bbGetInputParams();
415         if(params.size() == 4)
416         {
417                 if(params[3] != 1 && params[3] != -1)
418                 {
419                         printf("PG ShowNPoints_Tools::MovePatchCenter()  Warning params are wrong. direction of movement should be 1 or -1\n");
420                         return;
421                 }
422                 
423                 double centerPoint[3];
424                 std::vector<double> normal, modPoint;
425                 
426                 normal.push_back(params[0]);
427                 normal.push_back(params[1]);
428                 normal.push_back(params[2]);
429
430                 int direction = -1 * params[3];
431                 
432                 WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
433                 wsp->GetCollectionPoint(1,1, centerPoint);
434                 modPoint.push_back(centerPoint[0] + direction * normal[0]);
435                 modPoint.push_back(centerPoint[1] + direction * normal[1]);
436                 modPoint.push_back(centerPoint[2] + direction * normal[2]);
437
438                 wsp->SetCollectionPoint(1, 1, modPoint);
439         
440         // --- Finish ---
441         wsp->SetOutputBox();
442         wsp->UndoRedo_SaveCollection();
443         }else{
444                 printf("PG ShowNPoints_Tools::MovePatchCenter()  Warning params are wrong. Need 4: normal x y z and direction of movement (1 or -1)\n");
445         }
446 }
447
448 /**
449 *       Creates a cutting surface with 1 group of points. This surface can have its area adjusted 
450 *       (increase or decrease the distance from the points to the center)
451 *       The centroid is set as the output, to be used by the expanding tool.
452 */
453 void ShowNPoints_Tools::CreateExpandedSurface()
454 {
455         //
456         //Set Input to 0 as this function should only be executed manually but still update its children.
457         bbSetInputType(0);
458         //
459         //
460         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
461         wsp->StopAutoAddPoints();
462     wsp->StopTrackPoint();
463         if((wsp->GetLstModelShowNPointsSize()==1) && (bbGetInputMesh()!=NULL ) && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0))
464         {       
465                 //Set Input to 0 as this function should only be executed manually but still update its children.
466                 //bbSetInputType(0);
467                 //
468                 std::vector<double> lstX = wsp->GetModelShowNPoints()->GetLstPointsX();
469                 std::vector<double> lstY = wsp->GetModelShowNPoints()->GetLstPointsY();
470                 std::vector<double> lstZ = wsp->GetModelShowNPoints()->GetLstPointsZ();
471                 
472                 wsp->DeleteAllPoints_();
473                 double centroid[3];
474                 
475                 for(int i = 0; i < (int)lstX.size(); i++){
476                         centroid[0] += lstX[i];
477                         centroid[1] += lstY[i];
478                         centroid[2] += lstZ[i];
479                 }
480                 centroid[0] /= lstX.size();
481                 centroid[1] /= lstX.size();
482                 centroid[2] /= lstX.size();
483                 
484                 double p[3];
485                 double dV[3];
486                 
487                 for(int i = 0; i < (int)lstX.size(); i++){
488                         dV[0] = lstX[i] - centroid[0];
489                         dV[1] = lstY[i] - centroid[1];
490                         dV[2] = lstZ[i] - centroid[2];
491                         vtkMath::Normalize(dV);
492                         
493                         p[0] = lstX[i] + 4*dV[0];
494                         p[1] = lstY[i] + 4*dV[1];
495                         p[2] = lstZ[i] + 4*dV[2];
496                         wsp->AddPoint(p[0] ,p[1], p[2],"");
497                 }
498                 std::vector<double> outData = {centroid[0], centroid[1], centroid[2]};
499                 bbSetOutputOut(outData);
500         }
501         else{
502                 printf("PG ShowNPoints_Tools::CreateExpandedSurface  Warning surface not apply. groups, mesh or points invalid. need 1 group of points\n");
503         }
504         // --- Finish ---
505         wsp->SetOutputBox();
506         wsp->UndoRedo_SaveCollection();
507 }
508
509 /**
510 *       Creates a cutting surface with 3 groups of points. This surface can have its area adjusted
511 *       (Increase or decrease distance from points to centroid of spline or distance between splines)
512 *       The centroid and normal is set as the Output, to be used by the expanding tools.
513 */
514 void ShowNPoints_Tools::CreateWideExpandedSurface()
515 {
516         //
517         //Set Input to 0 as this function is only used by the popup menu
518         //bbSetInputType(0);
519         //
520         //
521         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
522         wsp->StopAutoAddPoints();
523     wsp->StopTrackPoint();
524     
525         if((wsp->GetLstModelShowNPointsSize()==1) && (bbGetInputMesh()!=NULL ) && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0))
526         {       
527                 std::vector<double> lstX = wsp->GetModelShowNPoints()->GetLstPointsX();
528                 std::vector<double> lstY = wsp->GetModelShowNPoints()->GetLstPointsY();
529                 std::vector<double> lstZ = wsp->GetModelShowNPoints()->GetLstPointsZ();
530                 
531                 wsp->DeleteAllPoints_();
532                 
533                 double normal[3];
534                 double centroid[3];
535                         
536                 for(int i = 0; i < (int)lstX.size(); i++){
537                         centroid[0] += lstX[i];
538                         centroid[1] += lstY[i];
539                         centroid[2] += lstZ[i];
540                 }
541                 centroid[0] /= lstX.size();
542                 centroid[1] /= lstX.size();
543                 centroid[2] /= lstX.size();
544                 
545                 double v1[3], v2[3];
546                 double currNormal[3];
547                 
548                 for(int i = 0; i < ((int)lstX.size())-1; i++){
549                         v1[0] = lstX[i] - centroid[0];
550                         v1[1] = lstY[i] - centroid[1];
551                         v1[2] = lstZ[i] - centroid[2];          
552                         v2[0] = lstX[i+1] - centroid[0];
553                         v2[1] = lstY[i+1] - centroid[1];
554                         v2[2] = lstZ[i+1] - centroid[2];
555                         vtkMath::Cross(v1, v2, currNormal);
556                         normal[0] += currNormal[0];
557                         normal[1] += currNormal[1];
558                         normal[2] += currNormal[2];
559                 }
560                 
561                 normal[0] /= (lstX.size()-1);
562                 normal[1] /= (lstX.size()-1);
563                 normal[2] /= (lstX.size()-1);
564                 
565                 vtkMath::Normalize(normal);
566                 
567                 double np[3], dV[3];
568                 int     addNormal = 1;
569                 //Add new groups on both sides from the original spline
570                 for(int group = 0; group < 2; group++){
571                         for(int i = 0; i < (int) lstX.size(); i++){
572                                 dV[0] = lstX[i] - centroid[0];
573                                 dV[1] = lstY[i] - centroid[1];
574                                 dV[2] = lstZ[i] - centroid[2];
575                                 vtkMath::Normalize(dV);
576                                 
577                                 np[0] = lstX[i] + dV[0]*4 + ((normal[0]*2)*addNormal);
578                                 np[1] = lstY[i] + dV[1]*4 + ((normal[1]*2)*addNormal);
579                                 np[2] = lstZ[i] + dV[2]*4 + ((normal[2]*2)*addNormal);
580                                 wsp->AddPoint(np[0] ,np[1], np[2],"");
581                         }
582                         addNormal = -1;
583                         if(group < 1)wsp->InsertCollectionAfter_();
584                 }
585                 
586                 std::vector<double> outData = {centroid[0], centroid[1], centroid[2], normal[0], normal[1], normal[2]};
587                 bbSetOutputOut(outData);
588                 
589                 // --- Finish ---
590         wsp->SetOutputBox();
591         wsp->UndoRedo_SaveCollection();
592         }
593         else{
594                 printf("PG ShowNPoints_Tools::CreateWideExpandedSurface  Warning surface not apply. groups, mesh or points invalid. need 1 group of points\n");
595         }
596 }
597
598 /**
599 *       Given a cutting surface, expand its area by moving the points outwards of the main centroid.
600 */
601 void ShowNPoints_Tools::ExpandSurfaceArea()
602 {
603         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
604         wsp->StopAutoAddPoints();
605     wsp->StopTrackPoint();
606     
607         if((wsp->GetLstModelShowNPointsSize()==1 || wsp->GetLstModelShowNPointsSize() == 2)  
608                 && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0)
609                 && (bbGetInputParams().size() == 4))
610         {
611                 std::vector<double> params = bbGetInputParams();
612                 double direction = params[3];
613                 double centroid[3] = {params[0], params[1], params[2]};
614                 
615                 double dV[3], currPoint[3], mdfdPoint[3];
616                 
617                 std::vector<double> modPoint;
618                 int pointsPerSpline = wsp->GetModelShowNPoints()->GetLstPointsSize();
619                 for(int i = 0; i < pointsPerSpline; i++){
620                         wsp->GetCollectionPoint(0, i, currPoint);
621                         dV[0] = currPoint[0] - centroid[0];
622                         dV[1] = currPoint[1] - centroid[1];
623                         dV[2] = currPoint[2] - centroid[2];
624                         vtkMath::Normalize(dV);
625                         
626                         vtkMath::MultiplyScalar(dV, direction);
627                         vtkMath::Add(currPoint, dV, mdfdPoint);
628                         modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
629                         wsp->SetCollectionPoint(0, i, modPoint);
630                         
631                         if(wsp->GetLstModelShowNPointsSize() == 2){
632                                 wsp->GetCollectionPoint(1, i, currPoint);
633                                 vtkMath::Add(currPoint, dV, mdfdPoint);
634                                 modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
635                                 wsp->SetCollectionPoint(1, i, modPoint);
636                         }
637                 }
638         }
639         else{
640                 printf("PG ShowNPoints_Tools::ExpandSurface  Warning surface not apply. groups, points or params invalid. need 1 group of points, need 4 params(centroid and direction)\n");
641         }
642         // --- Finish ---
643         wsp->SetOutputBox();
644         wsp->UndoRedo_SaveCollection();
645 }
646
647 void ShowNPoints_Tools::ExpandPatch()
648 {
649         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
650         wsp->StopAutoAddPoints();
651     wsp->StopTrackPoint();
652         if((wsp->GetLstModelShowNPointsSize() == 3)  
653                 && (wsp->GetLstPointsX().size() == 13)
654                 && (bbGetInputParams().size() == 4))
655         {
656                 std::vector<double> params = bbGetInputParams();
657                 double direction = params[3];
658                 double centroid[3] = {params[0], params[1], params[2]};
659
660                 std::vector<double> modPoint(3);
661                 double currentPoint[3], dV[3], mdfdPoint[3];
662                 for(int group = 0; group < 3; group++){
663                         if(group == 1){
664                                 wsp->GetCollectionPoint(group, 0, currentPoint);
665                                 dV[0] = currentPoint[0] - centroid[0];
666                                 dV[1] = currentPoint[1] - centroid[1];
667                                 dV[2] = currentPoint[2] - centroid[2];
668                                 vtkMath::Normalize(dV);
669                                 vtkMath::MultiplyScalar(dV, direction);
670                                 vtkMath::Add(currentPoint, dV, mdfdPoint);
671                                 modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
672                                 wsp->SetCollectionPoint(group, 0, modPoint);
673                                 wsp->GetCollectionPoint(group, 2, currentPoint);
674                                 dV[0] = currentPoint[0] - centroid[0];
675                                 dV[1] = currentPoint[1] - centroid[1];
676                                 dV[2] = currentPoint[2] - centroid[2];
677                                 vtkMath::Normalize(dV);
678                                 vtkMath::MultiplyScalar(dV, direction);
679                                 vtkMath::Add(currentPoint, dV, mdfdPoint);
680                                 modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
681                                 wsp->SetCollectionPoint(group, 2, modPoint);
682                         }else{
683                                 for(int i = 0; i < 5; i++){
684                                         wsp->GetCollectionPoint(group,i, currentPoint);
685                                         dV[0] = currentPoint[0] - centroid[0];
686                                         dV[1] = currentPoint[1] - centroid[1];
687                                         dV[2] = currentPoint[2] - centroid[2];
688                                         vtkMath::Normalize(dV);
689                                         vtkMath::MultiplyScalar(dV, direction);
690                                         vtkMath::Add(currentPoint, dV, mdfdPoint);
691                                         modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
692                                         wsp->SetCollectionPoint(group, i, modPoint);
693                                 }
694                         }
695                 }
696         }else{
697                 printf("PG ShowNPoints_Tools::ExpandPatch  Warning groups, points or params invalid. need 3 groups of points, need 4 params(centroid, and direction 1 or -1)\n");
698         }
699         // --- Finish ---
700         wsp->SetOutputBox();
701         wsp->UndoRedo_SaveCollection();
702 }
703
704 /**
705 *       Given a cutting surface, expand the distance between the edge splines and the middle spline. making it "wider" or "thicker".
706 */
707 void ShowNPoints_Tools::WidenSurface()
708 {
709         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
710         wsp->StopAutoAddPoints();
711     wsp->StopTrackPoint();
712
713         if((wsp->GetLstModelShowNPointsSize()==2)  
714                 && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0)
715                 && (bbGetInputParams().size() == 4))
716         {
717                 double direction = bbGetInputParams()[3];
718                 double normal[3] = {bbGetInputParams()[0], bbGetInputParams()[1], bbGetInputParams()[2]};
719                 vtkMath::MultiplyScalar(normal, direction);
720                 
721                 int pointsPerSpline = wsp->GetModelShowNPoints()->GetLstPointsSize();
722                 double pointSp1[3], pointSp2[3];
723                 std::vector<double> modifiedPoint;
724                 for(int i = 0; i < pointsPerSpline; i++){
725                         wsp->GetCollectionPoint(0, i, pointSp1);
726                         wsp->GetCollectionPoint(1, i, pointSp2);
727                         vtkMath::Add(pointSp1, normal, pointSp1);
728                         vtkMath::Subtract(pointSp2, normal, pointSp2);
729                         modifiedPoint.insert(modifiedPoint.begin(), std::begin(pointSp1), std::end(pointSp1));
730                         wsp->SetCollectionPoint(0, i, modifiedPoint);
731                         modifiedPoint.insert(modifiedPoint.begin(), std::begin(pointSp2), std::end(pointSp2));
732                         wsp->SetCollectionPoint(1, i, modifiedPoint);
733                 }
734         
735         }else{
736                 printf("PG ShowNPoints_Tools::WidenSurface  Warning surface not apply. groups, points or params invalid. need 3 group of points, need 4 params(normal and direction)\n");
737         }
738         // --- Finish ---
739         wsp->SetOutputBox();
740         wsp->UndoRedo_SaveCollection();
741 }
742
743 void ShowNPoints_Tools::MovePointInNormal()
744 {
745         //move the currently selected control point in the direction or opposite of the normal vector of the closest point in the input mesh
746
747         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
748         wsp->StopAutoAddPoints();
749     wsp->StopTrackPoint();
750     if((wsp->GetLstModelShowNPointsSize()>=2)  //Check condition
751                 && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0)
752                 && (bbGetInputParams().size() == 1)
753                 && (bbGetInputMesh() != NULL)
754                 && (bbGetInputSpacing().size() == 3))
755         {
756                 if(bbGetInputParams()[0] != -1 && bbGetInputParams()[0] != 1){
757                         printf("PG ShowNPoints_Tools::MovePointInNormal No direction provided, must be 1 or -1");
758                         return;
759                 }
760                 double spc[3];
761         double x,y,z;
762         double p[3], normal[3];;         // point to modify and normal
763         std::vector<double> pN(3);    // new point
764
765         spc[0]                                                          = bbGetInputSpacing()[0];
766         spc[1]                                                          = bbGetInputSpacing()[1];
767         spc[2]                                                          = bbGetInputSpacing()[2];
768         
769         vtkStaticPointLocator   *pointLocator   = vtkStaticPointLocator::New();
770         pointLocator->SetDataSet( bbGetInputMesh() );
771         pointLocator->BuildLocator();
772         
773 //        int idControlPoint = wsp->GetModelShowNPoints()->GetNearestPoint();
774         int idControlPoint = wsp->GetModelShowNPoints()->GetIdCurrentPoint();
775         
776         if(idControlPoint >= 0){
777                     wsp->GetModelShowNPoints()->GetIdPoint(idControlPoint, &x, &y, &z);
778                     p[0] = x * spc[0];
779                     p[1] = y * spc[1];
780                     p[2] = z * spc[2];
781                     int idMeshPoint = pointLocator->FindClosestPoint(p);
782                     bbGetInputMesh()->GetPointData()->GetNormals()->GetTuple(idMeshPoint, normal);
783                         int direction = bbGetInputParams()[0];
784                     pN[0] = p[0] / spc[0] + direction*normal[0];
785                     pN[1] = p[1] / spc[1] + direction*normal[1];
786                     pN[2] = p[2] / spc[2] + direction*normal[2];
787                     
788                     wsp->GetModelShowNPoints()->SetPointById(idControlPoint, pN);
789                     wsp->GetViewShowNPoints()->RefreshPoint(idControlPoint);
790                     wsp->SetOutputBox();
791                 wsp->UndoRedo_SaveCollection();
792         } // if idControlPoint
793         } //wsp
794 }
795
796 void ShowNPoints_Tools::ChangeCurrentPoint()
797 {
798     if(bbGetInputParams()[0] != -1 && bbGetInputParams()[0] != 1){
799         printf("PG ShowNPoints_Tools::MovePointInNormal No direction provided, must be 1 or -1");
800         return;
801     } // if Params
802     int step=bbGetInputParams()[0];
803     WidgetShowNPoints   *wsp            = bbGetInputWidgetShowNPoints();
804     int                 idControlPoint  = wsp->GetModelShowNPoints()->GetIdCurrentPoint() + step;
805     int size=wsp->GetModelShowNPoints()->GetLstPointsSize();
806     if (idControlPoint<0)       { idControlPoint = size-1;  }
807     if (idControlPoint>=size )  { idControlPoint = 0;       }
808     wsp->GetModelShowNPoints()->SetIdCurrentPoint( idControlPoint );
809     wsp->RefreshCollectionText();
810     wsp->RefreshColourCollection();
811 }
812
813 void ShowNPoints_Tools::JoinPoints()
814 {
815         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
816         wsp->StopAutoAddPoints();
817     wsp->StopTrackPoint();
818     if((wsp->GetLstModelShowNPointsSize()>=2)
819                 && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0))
820         {
821                 int numberOfSplines = wsp->GetLstModelShowNPointsSize();
822                 double x, y, z;
823                 int sizeCurrentSpline, i;
824                 wsp->GetModelShowNPoints()->GetIdPoint(0, &x, &y, &z);
825                 std::vector<double> pointStart = {x, y, z};
826                 sizeCurrentSpline = wsp->GetModelShowNPoints()->GetLstPointsX().size();
827                 wsp->GetModelShowNPoints()->GetIdPoint(sizeCurrentSpline-1, &x, &y, &z);
828                 std::vector<double> pointEnd = {x, y, z};
829                 for(i = 0; i < numberOfSplines; i++){
830                         sizeCurrentSpline = wsp->GetModelShowNPoints(i)->GetLstPointsX().size();
831                         wsp->SetCollectionPoint(i, 0, pointStart);
832                         wsp->SetCollectionPoint(i, sizeCurrentSpline-1, pointEnd);
833                 }
834                 wsp->SetOutputBox();
835         wsp->UndoRedo_SaveCollection();
836         } // if Size
837 }
838
839 //=====
840 // 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)
841 //===== 
842 void ShowNPoints_Tools::Process()
843 {
844
845 // THE MAIN PROCESSING METHOD BODY
846 //   Here we simply set the input 'In' value to the output 'Out'
847 //   And print out the output value
848 // INPUT/OUTPUT ACCESSORS ARE OF THE FORM :
849 //    void bbSet{Input|Output}NAME(const TYPE&)
850 //    const TYPE& bbGet{Input|Output}NAME() const 
851 //    Where :
852 //    * NAME is the name of the input/output
853 //      (the one provided in the attribute 'name' of the tag 'input')
854 //    * TYPE is the C++ type of the input/output
855 //      (the one provided in the attribute 'type' of the tag 'input')
856
857 //    bbSetOutputOut( bbGetInputIn() );
858 //    std::cout << "Output value = " <<bbGetOutputOut() << std::endl;
859
860     if (bbGetInputWidgetShowNPoints()!=NULL)
861     {
862         if (bbGetInputType()==1)
863         {
864             bbGetInputWidgetShowNPoints()->OnAutoAddPoints_tool();
865         } // if Type
866
867         if (bbGetInputType()==5)
868         {
869             bbGetInputWidgetShowNPoints()->OnAddPoint_();
870         } // if Type
871         if (bbGetInputType()==10)
872         {
873             bbGetInputWidgetShowNPoints()->OnInsertPoint_();
874         } // if Type
875         if (bbGetInputType()==20)
876         {
877             bbGetInputWidgetShowNPoints()->OnTrackPoint_tool();
878         } // if Type
879         if (bbGetInputType()==30)
880         {
881             bbGetInputWidgetShowNPoints()->OnSetPoint_();
882         } // if Type
883         if (bbGetInputType()==40)
884         {
885             bbGetInputWidgetShowNPoints()->OnErasePoint_();
886         } // if Type
887         if (bbGetInputType()==50)
888         {
889             bbGetInputWidgetShowNPoints()->OnDeleteAllPoints_();
890         } // if Type
891         if (bbGetInputType()==100)
892         {
893             bbGetInputWidgetShowNPoints()->OnInsertCollectionAfter_();
894         } // if Type
895         if (bbGetInputType()==110)
896         {
897             bbGetInputWidgetShowNPoints()->OnDeleteCollection_();
898         } // if Type
899         if (bbGetInputType()==120)
900         {
901             bbGetInputWidgetShowNPoints()->OnResetCollections_();
902         } // if Type
903         if (bbGetInputType()==200)   // Create patch surface
904         {
905             InitCreatePatch_Points();
906         } // if Type
907         if (bbGetInputType()==205)  // Create volume surface from points
908         {
909             InitCreateVolumeSurface_Points();
910         } // if Type
911         if (bbGetInputType()==210)
912         {
913             bbGetInputWidgetShowNPoints()->OnInvertLstPoints_();
914         } // if Type
915         if(bbGetInputType()==220)
916         {
917                 MovePatchCenter();
918         } // if Type
919         if(bbGetInputType()==230)
920         {
921                 MovePointInNormal();
922         } // if Type
923         if(bbGetInputType()==235)
924         {
925             ChangeCurrentPoint();
926         } // if Type
927
928         if(bbGetInputType()==240)
929         {
930                 JoinPoints();
931         } // if Type
932         if(bbGetInputType()==300)
933         {
934                 CreateExpandedSurface();
935         } // if Type
936         if(bbGetInputType()==310)
937         {
938                 CreateWideExpandedSurface();
939         } // if Type
940         if(bbGetInputType()==320)
941         {
942                 ExpandSurfaceArea();
943         } // if Type
944         if(bbGetInputType()==330)
945         {
946                 WidenSurface();
947         } // if Type
948         if(bbGetInputType()==340)
949         {
950                 ExpandPatch();
951         } // if Type
952     } // if bbGetInputWidgetShowNPoints
953 }
954 //===== 
955 // 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)
956 //===== 
957 void ShowNPoints_Tools::bbUserSetDefaultValues()
958 {
959 //  SET HERE THE DEFAULT INPUT/OUTPUT VALUES OF YOUR BOX 
960 //    Here we initialize the input 'In' to 0
961    bbSetInputType(0);
962    bbSetInputMesh(NULL);
963    bbSetInputWidgetShowNPoints(NULL);
964     
965     std::vector<double> spc;
966     spc.push_back(1);
967     spc.push_back(1);
968     spc.push_back(1);
969     bbSetInputSpacing(spc);
970 }
971 //===== 
972 // 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)
973 //===== 
974 void ShowNPoints_Tools::bbUserInitializeProcessing()
975 {
976 //  THE INITIALIZATION METHOD BODY :
977 //    Here does nothing 
978 //    but this is where you should allocate the internal/output pointers 
979 //    if any
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 ShowNPoints_Tools::bbUserFinalizeProcessing()
985 {
986 //  THE FINALIZATION METHOD BODY :
987 //    Here does nothing 
988 //    but this is where you should desallocate the internal/output pointers 
989 //    if any
990 }
991
992 } // EO namespace bbcreaMaracasVisu
993
994