]> Creatis software - creaMaracasVisu.git/blob - bbtk/src/bbcreaMaracasVisuShowNPoints_Tools.cxx
#3516 Join points tool
[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         // --- Finish ---
186         wsp->SetOutputBox();
187         wsp->UndoRedo_SaveCollection();
188
189     } // if wsp && mesh
190 }
191
192
193 void ShowNPoints_Tools::CreatePatch_Points(std::vector<double> lstX, std::vector<double> lstY, std::vector<double> lstZ)
194 {
195     WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
196     std::vector<long int>   lstIdNormalSurface;
197     double                  spc[3];
198                             spc[0]          = bbGetInputSpacing()[0];
199                             spc[1]          = bbGetInputSpacing()[1];
200                             spc[2]          = bbGetInputSpacing()[2];
201     vtkPoints               *points         = bbGetInputMesh()->GetPoints();
202     vtkStaticPointLocator   *pointLocator   = vtkStaticPointLocator::New();
203     pointLocator->SetDataSet( bbGetInputMesh() );
204     pointLocator->BuildLocator();
205     wsp->StopTrackPoint();
206     double p[3],pM[3];
207     double dx,dy,dz;
208     
209     wsp->DeleteAllPoints_();
210     //wsp->ErasePoint( 0 );
211     //wsp->ErasePoint( 0 );
212     //wsp->ErasePoint( 0 );
213     //wsp->ErasePoint( 0 );
214     // --- Group 0 ---
215     dx = lstX[1]-lstX[0];
216     dy = lstY[1]-lstY[0];
217     dz = lstZ[1]-lstZ[0];
218     //
219     //
220     double part = 0.25;
221     for(int sect = 0; sect < 5; sect++)
222     {
223         p[0] = lstX[0] + dx*(sect*part);
224                 p[1] = lstY[0] + dy*(sect*part);
225                 p[2] = lstZ[0] + dz*(sect*part);
226                 if(sect == 4){
227                         p[0] = p[0] + 0.5*(((lstX[1]+lstX[2])/2)-p[0]);
228                         p[1] = p[1] + 0.5*(((lstY[1]+lstY[2])/2)-p[1]);
229                         p[2] = p[2] + 0.5*(((lstZ[1]+lstZ[2])/2)-p[2]);
230                 }
231                 if(sect == 0){
232                         p[0] = p[0] + 0.5*(((lstX[0]+lstX[3])/2)-p[0]);
233                         p[1] = p[1] + 0.5*(((lstY[0]+lstY[3])/2)-p[1]);
234                         p[2] = p[2] + 0.5*(((lstZ[0]+lstZ[3])/2)-p[2]);
235                 }
236                 NearestPointToMesh(points, pointLocator, spc, p,pM);
237                 wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
238                 if(sect == 0 || sect == 4) lstIdNormalSurface.push_back( pointLocator->FindClosestPoint(pM) );
239     }
240         
241     // --- Group 1 ---
242     double centroid[3];
243     
244     wsp->InsertCollectionAfter_();
245       p[0] = (lstX[0]+lstX[3])/2;
246       p[1] = (lstY[0]+lstY[3])/2;
247       p[2] = (lstZ[0]+lstZ[3])/2;
248       NearestPointToMesh(points, pointLocator, spc, p,pM);
249       wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
250       p[0] = (lstX[1]+lstX[2])/2;
251       p[1] = (lstY[1]+lstY[2])/2;
252       p[2] = (lstZ[1]+lstZ[2])/2;
253       NearestPointToMesh(points, pointLocator, spc, p,pM);
254       wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
255       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;
256       wsp->InsertPoint(p[0] ,p[1], p[2],"");
257           std::copy(std::begin(p), std::end(p), std::begin(centroid));
258     // --- Group 2 ---
259     wsp->InsertCollectionAfter_();
260     dx = lstX[2]-lstX[3];
261     dy = lstY[2]-lstY[3];
262     dz = lstZ[2]-lstZ[3];  
263     for(int sect = 0; sect < 5; sect++)
264     {
265         p[0] = lstX[3] + dx*(sect*part);
266                 p[1] = lstY[3] + dy*(sect*part);
267                 p[2] = lstZ[3] + dz*(sect*part);
268                 if(sect == 4){
269                         p[0] = p[0] + 0.5*(((lstX[1]+lstX[2])/2)-p[0]);
270                         p[1] = p[1] + 0.5*(((lstY[1]+lstY[2])/2)-p[1]);
271                         p[2] = p[2] + 0.5*(((lstZ[1]+lstZ[2])/2)-p[2]);
272                 }
273                 if(sect == 0){
274                         p[0] = p[0] + 0.5*(((lstX[0]+lstX[3])/2)-p[0]);
275                         p[1] = p[1] + 0.5*(((lstY[0]+lstY[3])/2)-p[1]);
276                         p[2] = p[2] + 0.5*(((lstZ[0]+lstZ[3])/2)-p[2]);
277                 }
278                 NearestPointToMesh(points, pointLocator, spc, p,pM);
279                 wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
280                 if(sect == 0 || sect == 4) lstIdNormalSurface.push_back( pointLocator->FindClosestPoint(pM) );
281     }
282      pointLocator->Delete();
283     // Check normals
284 //        1. Recorrer las normales de lstIdNormals y calcular el promedio  -> V1
285     double          *nValue;
286         double                  n1[3];
287     vtkPointData    *pointdata  =  bbGetInputMesh()->GetPointData();
288     vtkDataArray    *dataarray  = pointdata->GetNormals();
289         int i,size = lstIdNormalSurface.size();
290         n1[0]=0;
291         n1[1]=0;
292         n1[2]=0;
293         for (i=0; i<size; i++)
294         {
295             nValue        = dataarray->GetTuple3( lstIdNormalSurface[i] );
296                 n1[0] = n1[0] + nValue[0];
297                 n1[1] = n1[1] + nValue[1];
298                 n1[2] = n1[2] + nValue[2];
299         } // for i
300         n1[0] = n1[0]/size;
301         n1[1] = n1[1]/size;
302         n1[2] = n1[2]/size;
303
304 //        2. Calcular el promedio de 4 normales de la nueva superficie     -> V2
305     double pC[3];
306     double pM1[3];
307     double pM2[3];
308     double n2[3];
309     n2[0] = 0;
310     n2[1] = 0;
311     n2[2] = 0;
312     // Collection 0 with 4 points
313     // Collection 1 with 3 points
314     // Collection 2 with 4 points
315     wsp->GetCollectionPoint(1,1, pC);
316     
317     wsp->GetCollectionPoint(0,0, pM);
318     vtkMath::Subtract(pM,pC,pM1);
319     wsp->GetCollectionPoint(0,3, pM);
320     vtkMath::Subtract(pM,pC,pM2);
321     vtkMath::Cross(pM1,pM2,pM);
322     n2[0] = pM[0];
323     n2[1] = pM[1];
324     n2[2] = pM[2];
325
326     wsp->GetCollectionPoint(0,3, pM);
327     vtkMath::Subtract(pM,pC,pM1);
328     wsp->GetCollectionPoint(2,3, pM);
329     vtkMath::Subtract(pM,pC,pM2);
330     vtkMath::Cross(pM1,pM2,pM);
331     n2[0] = n2[0] + pM[0];
332     n2[1] = n2[1] + pM[1];
333     n2[2] = n2[2] + pM[2];
334
335     wsp->GetCollectionPoint(2,3, pM);
336     vtkMath::Subtract(pM,pC,pM1);
337     wsp->GetCollectionPoint(2,0, pM);
338     vtkMath::Subtract(pM,pC,pM2);
339     vtkMath::Cross(pM1,pM2,pM);
340     n2[0] = n2[0] + pM[0];
341     n2[1] = n2[1] + pM[1];
342     n2[2] = n2[2] + pM[2];
343     
344     wsp->GetCollectionPoint(2,0, pM);
345     vtkMath::Subtract(pM,pC,pM1);
346     wsp->GetCollectionPoint(0,0, pM);
347     vtkMath::Subtract(pM,pC,pM2);
348     vtkMath::Cross(pM1,pM2,pM);
349     n2[0] = n2[0] + pM[0];
350     n2[1] = n2[1] + pM[1];
351     n2[2] = n2[2] + pM[2];
352     
353     n2[0] = n2[0] / 4;
354     n2[1] = n2[1] / 4;
355     n2[2] = n2[2] / 4;
356     
357 //        3. Calcular el angulo entre V1 y V2
358     double angle = vtkMath::AngleBetweenVectors(n1,n2) * 180 / vtkMath::Pi();
359 //        4. Si el angulo es major de 90 Invertir las normales de la superficie actual
360     if (angle<90)
361     {
362         vtkMath::MultiplyScalar(n2, -1);
363         wsp->InvertLstPoints_();
364     } // if angle
365     std::vector<double> normalOut(n2, n2 + 3);
366     double norm = vtkMath::Norm(n2);
367     normalOut[0] = normalOut[0]/norm;
368         normalOut[1] = normalOut[1]/norm;
369         normalOut[2] = normalOut[2]/norm;
370         
371         std::vector<double> outputData;
372         outputData.insert(outputData.end(), &centroid[0], &centroid[3]);
373         outputData.insert(outputData.end(), &normalOut[0], &normalOut[3]);
374         
375         bbSetOutputOut(outputData);
376     //bbSetOutputOut(normalOut);
377     
378     // --- Finish ---
379     wsp->SetOutputBox();
380     wsp->UndoRedo_SaveCollection();
381 }
382
383 void ShowNPoints_Tools::MovePatchCenter()
384 {       
385         std::vector<double> params = bbGetInputParams();
386         if(params.size() == 4)
387         {
388                 if(params[3] != 1 && params[3] != -1)
389                 {
390                         printf("PG ShowNPoints_Tools::MovePatchCenter()  Warning params are wrong. direction of movement should be 1 or -1\n");
391                         return;
392                 }
393                 
394                 double centerPoint[3];
395                 std::vector<double> normal, modPoint;
396                 
397                 normal.push_back(params[0]);
398                 normal.push_back(params[1]);
399                 normal.push_back(params[2]);
400
401                 int direction = -1 * params[3];
402                 
403                 WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
404                 wsp->GetCollectionPoint(1,1, centerPoint);
405                 modPoint.push_back(centerPoint[0] + direction * normal[0]);
406                 modPoint.push_back(centerPoint[1] + direction * normal[1]);
407                 modPoint.push_back(centerPoint[2] + direction * normal[2]);
408
409                 wsp->SetCollectionPoint(1, 1, modPoint);
410         
411         // --- Finish ---
412         wsp->SetOutputBox();
413         wsp->UndoRedo_SaveCollection();
414         }else{
415                 printf("PG ShowNPoints_Tools::MovePatchCenter()  Warning params are wrong. Need 4: normal x y z and direction of movement (1 or -1)\n");
416         }
417 }
418
419 /**
420 *       Creates a cutting surface with 1 group of points. This surface can have its area adjusted 
421 *       (increase or decrease the distance from the points to the center)
422 *       The centroid is set as the output, to be used by the expanding tool.
423 */
424 void ShowNPoints_Tools::CreateExpandedSurface()
425 {
426         //
427         //Set Input to 0 as this function should only be executed manually but still update its children.
428         bbSetInputType(0);
429         //
430         //
431         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
432         wsp->StopAutoAddPoints();
433     wsp->StopTrackPoint();
434         if((wsp->GetLstModelShowNPointsSize()==1) && (bbGetInputMesh()!=NULL ) && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0))
435         {       
436                 //Set Input to 0 as this function should only be executed manually but still update its children.
437                 //bbSetInputType(0);
438                 //
439                 std::vector<double> lstX = wsp->GetModelShowNPoints()->GetLstPointsX();
440                 std::vector<double> lstY = wsp->GetModelShowNPoints()->GetLstPointsY();
441                 std::vector<double> lstZ = wsp->GetModelShowNPoints()->GetLstPointsZ();
442                 
443                 wsp->DeleteAllPoints_();
444                 double centroid[3];
445                 
446                 for(int i = 0; i < (int)lstX.size(); i++){
447                         centroid[0] += lstX[i];
448                         centroid[1] += lstY[i];
449                         centroid[2] += lstZ[i];
450                 }
451                 centroid[0] /= lstX.size();
452                 centroid[1] /= lstX.size();
453                 centroid[2] /= lstX.size();
454                 
455                 double p[3];
456                 double dV[3];
457                 
458                 for(int i = 0; i < (int)lstX.size(); i++){
459                         dV[0] = lstX[i] - centroid[0];
460                         dV[1] = lstY[i] - centroid[1];
461                         dV[2] = lstZ[i] - centroid[2];
462                         vtkMath::Normalize(dV);
463                         
464                         p[0] = lstX[i] + 4*dV[0];
465                         p[1] = lstY[i] + 4*dV[1];
466                         p[2] = lstZ[i] + 4*dV[2];
467                         wsp->AddPoint(p[0] ,p[1], p[2],"");
468                 }
469                 std::vector<double> outData = {centroid[0], centroid[1], centroid[2]};
470                 bbSetOutputOut(outData);
471         }
472         else{
473                 printf("PG ShowNPoints_Tools::CreateExpandedSurface  Warning surface not apply. groups, mesh or points invalid. need 1 group of points\n");
474         }
475         // --- Finish ---
476         wsp->SetOutputBox();
477         wsp->UndoRedo_SaveCollection();
478 }
479
480 /**
481 *       Creates a cutting surface with 3 groups of points. This surface can have its area adjusted
482 *       (Increase or decrease distance from points to centroid of spline or distance between splines)
483 *       The centroid and normal is set as the Output, to be used by the expanding tools.
484 */
485 void ShowNPoints_Tools::CreateWideExpandedSurface()
486 {
487         //
488         //Set Input to 0 as this function is only used by the popup menu
489         //bbSetInputType(0);
490         //
491         //
492         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
493         wsp->StopAutoAddPoints();
494     wsp->StopTrackPoint();
495     
496         if((wsp->GetLstModelShowNPointsSize()==1) && (bbGetInputMesh()!=NULL ) && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0))
497         {       
498                 std::vector<double> lstX = wsp->GetModelShowNPoints()->GetLstPointsX();
499                 std::vector<double> lstY = wsp->GetModelShowNPoints()->GetLstPointsY();
500                 std::vector<double> lstZ = wsp->GetModelShowNPoints()->GetLstPointsZ();
501                 
502                 wsp->DeleteAllPoints_();
503                 
504                 double normal[3];
505                 double centroid[3];
506                         
507                 for(int i = 0; i < (int)lstX.size(); i++){
508                         centroid[0] += lstX[i];
509                         centroid[1] += lstY[i];
510                         centroid[2] += lstZ[i];
511                 }
512                 centroid[0] /= lstX.size();
513                 centroid[1] /= lstX.size();
514                 centroid[2] /= lstX.size();
515                 
516                 double v1[3], v2[3];
517                 double currNormal[3];
518                 
519                 for(int i = 0; i < ((int)lstX.size())-1; i++){
520                         v1[0] = lstX[i] - centroid[0];
521                         v1[1] = lstY[i] - centroid[1];
522                         v1[2] = lstZ[i] - centroid[2];          
523                         v2[0] = lstX[i+1] - centroid[0];
524                         v2[1] = lstY[i+1] - centroid[1];
525                         v2[2] = lstZ[i+1] - centroid[2];
526                         vtkMath::Cross(v1, v2, currNormal);
527                         normal[0] += currNormal[0];
528                         normal[1] += currNormal[1];
529                         normal[2] += currNormal[2];
530                 }
531                 
532                 normal[0] /= (lstX.size()-1);
533                 normal[1] /= (lstX.size()-1);
534                 normal[2] /= (lstX.size()-1);
535                 
536                 vtkMath::Normalize(normal);
537                 
538                 double np[3], dV[3];
539                 int     addNormal = 1;
540                 //Add new groups on both sides from the original spline
541                 for(int group = 0; group < 2; group++){
542                         for(int i = 0; i < (int) lstX.size(); i++){
543                                 dV[0] = lstX[i] - centroid[0];
544                                 dV[1] = lstY[i] - centroid[1];
545                                 dV[2] = lstZ[i] - centroid[2];
546                                 vtkMath::Normalize(dV);
547                                 
548                                 np[0] = lstX[i] + dV[0]*4 + ((normal[0]*2)*addNormal);
549                                 np[1] = lstY[i] + dV[1]*4 + ((normal[1]*2)*addNormal);
550                                 np[2] = lstZ[i] + dV[2]*4 + ((normal[2]*2)*addNormal);
551                                 wsp->AddPoint(np[0] ,np[1], np[2],"");
552                         }
553                         addNormal = -1;
554                         if(group < 1)wsp->InsertCollectionAfter_();
555                 }
556                 
557                 std::vector<double> outData = {centroid[0], centroid[1], centroid[2], normal[0], normal[1], normal[2]};
558                 bbSetOutputOut(outData);
559                 
560                 // --- Finish ---
561         wsp->SetOutputBox();
562         wsp->UndoRedo_SaveCollection();
563         }
564         else{
565                 printf("PG ShowNPoints_Tools::CreateWideExpandedSurface  Warning surface not apply. groups, mesh or points invalid. need 1 group of points\n");
566         }
567 }
568
569 /**
570 *       Given a cutting surface, expand its area by moving the points outwards of the main centroid.
571 */
572 void ShowNPoints_Tools::ExpandSurfaceArea()
573 {
574         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
575         wsp->StopAutoAddPoints();
576     wsp->StopTrackPoint();
577     
578         if((wsp->GetLstModelShowNPointsSize()==1 || wsp->GetLstModelShowNPointsSize() == 2)  
579                 && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0)
580                 && (bbGetInputParams().size() == 4))
581         {
582                 std::vector<double> params = bbGetInputParams();
583                 double direction = params[3];
584                 double centroid[3] = {params[0], params[1], params[2]};
585                 
586                 double dV[3], currPoint[3], mdfdPoint[3];
587                 
588                 std::vector<double> modPoint;
589                 int pointsPerSpline = wsp->GetModelShowNPoints()->GetLstPointsSize();
590                 for(int i = 0; i < pointsPerSpline; i++){
591                         wsp->GetCollectionPoint(0, i, currPoint);
592                         dV[0] = currPoint[0] - centroid[0];
593                         dV[1] = currPoint[1] - centroid[1];
594                         dV[2] = currPoint[2] - centroid[2];
595                         vtkMath::Normalize(dV);
596                         
597                         vtkMath::MultiplyScalar(dV, direction);
598                         vtkMath::Add(currPoint, dV, mdfdPoint);
599                         modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
600                         wsp->SetCollectionPoint(0, i, modPoint);
601                         
602                         if(wsp->GetLstModelShowNPointsSize() == 2){
603                                 wsp->GetCollectionPoint(1, i, currPoint);
604                                 vtkMath::Add(currPoint, dV, mdfdPoint);
605                                 modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
606                                 wsp->SetCollectionPoint(1, i, modPoint);
607                         }
608                 }
609         }
610         else{
611                 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");
612         }
613         // --- Finish ---
614         wsp->SetOutputBox();
615         wsp->UndoRedo_SaveCollection();
616 }
617
618 void ShowNPoints_Tools::ExpandPatch()
619 {
620         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
621         wsp->StopAutoAddPoints();
622     wsp->StopTrackPoint();
623         if((wsp->GetLstModelShowNPointsSize() == 3)  
624                 && (wsp->GetLstPointsX().size() == 13)
625                 && (bbGetInputParams().size() == 4))
626         {
627                 std::vector<double> params = bbGetInputParams();
628                 double direction = params[3];
629                 double centroid[3] = {params[0], params[1], params[2]};
630
631                 std::vector<double> modPoint(3);
632                 double currentPoint[3], dV[3], mdfdPoint[3];
633                 for(int group = 0; group < 3; group++){
634                         if(group == 1){
635                                 wsp->GetCollectionPoint(group, 0, currentPoint);
636                                 dV[0] = currentPoint[0] - centroid[0];
637                                 dV[1] = currentPoint[1] - centroid[1];
638                                 dV[2] = currentPoint[2] - centroid[2];
639                                 vtkMath::Normalize(dV);
640                                 vtkMath::MultiplyScalar(dV, direction);
641                                 vtkMath::Add(currentPoint, dV, mdfdPoint);
642                                 modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
643                                 wsp->SetCollectionPoint(group, 0, modPoint);
644                                 wsp->GetCollectionPoint(group, 2, currentPoint);
645                                 dV[0] = currentPoint[0] - centroid[0];
646                                 dV[1] = currentPoint[1] - centroid[1];
647                                 dV[2] = currentPoint[2] - centroid[2];
648                                 vtkMath::Normalize(dV);
649                                 vtkMath::MultiplyScalar(dV, direction);
650                                 vtkMath::Add(currentPoint, dV, mdfdPoint);
651                                 modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
652                                 wsp->SetCollectionPoint(group, 2, modPoint);
653                         }else{
654                                 for(int i = 0; i < 5; i++){
655                                         wsp->GetCollectionPoint(group,i, currentPoint);
656                                         dV[0] = currentPoint[0] - centroid[0];
657                                         dV[1] = currentPoint[1] - centroid[1];
658                                         dV[2] = currentPoint[2] - centroid[2];
659                                         vtkMath::Normalize(dV);
660                                         vtkMath::MultiplyScalar(dV, direction);
661                                         vtkMath::Add(currentPoint, dV, mdfdPoint);
662                                         modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
663                                         wsp->SetCollectionPoint(group, i, modPoint);
664                                 }
665                         }
666                 }
667         }else{
668                 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");
669         }
670         // --- Finish ---
671         wsp->SetOutputBox();
672         wsp->UndoRedo_SaveCollection();
673 }
674
675 /**
676 *       Given a cutting surface, expand the distance between the edge splines and the middle spline. making it "wider" or "thicker".
677 */
678 void ShowNPoints_Tools::WidenSurface()
679 {
680         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
681         wsp->StopAutoAddPoints();
682     wsp->StopTrackPoint();
683
684         if((wsp->GetLstModelShowNPointsSize()==2)  
685                 && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0)
686                 && (bbGetInputParams().size() == 4))
687         {
688                 double direction = bbGetInputParams()[3];
689                 double normal[3] = {bbGetInputParams()[0], bbGetInputParams()[1], bbGetInputParams()[2]};
690                 vtkMath::MultiplyScalar(normal, direction);
691                 
692                 int pointsPerSpline = wsp->GetModelShowNPoints()->GetLstPointsSize();
693                 double pointSp1[3], pointSp2[3];
694                 std::vector<double> modifiedPoint;
695                 for(int i = 0; i < pointsPerSpline; i++){
696                         wsp->GetCollectionPoint(0, i, pointSp1);
697                         wsp->GetCollectionPoint(1, i, pointSp2);
698                         vtkMath::Add(pointSp1, normal, pointSp1);
699                         vtkMath::Subtract(pointSp2, normal, pointSp2);
700                         modifiedPoint.insert(modifiedPoint.begin(), std::begin(pointSp1), std::end(pointSp1));
701                         wsp->SetCollectionPoint(0, i, modifiedPoint);
702                         modifiedPoint.insert(modifiedPoint.begin(), std::begin(pointSp2), std::end(pointSp2));
703                         wsp->SetCollectionPoint(1, i, modifiedPoint);
704                 }
705         
706         }else{
707                 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");
708         }
709         // --- Finish ---
710         wsp->SetOutputBox();
711         wsp->UndoRedo_SaveCollection();
712 }
713
714 void ShowNPoints_Tools::MovePointInNormal()
715 {
716         //move the currently selected control point in the direction or opposite of the normal vector of the closest point in the input mesh
717
718         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
719         wsp->StopAutoAddPoints();
720     wsp->StopTrackPoint();
721     if((wsp->GetLstModelShowNPointsSize()>=2)  //Check condition
722                 && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0)
723                 && (bbGetInputParams().size() == 1)
724                 && (bbGetInputMesh() != NULL)
725                 && (bbGetInputSpacing().size() == 3))
726         {
727                 if(bbGetInputParams()[0] != -1 && bbGetInputParams()[0] != 1){
728                         printf("PG ShowNPoints_Tools::MovePointInNormal No direction provided, must be 1 or -1");
729                         return;
730                 }
731                 double spc[3];
732         double x,y,z;
733         double p[3], normal[3];;         // point to modify and normal
734         std::vector<double> pN(3);    // new point
735
736         spc[0]                                                          = bbGetInputSpacing()[0];
737         spc[1]                                                          = bbGetInputSpacing()[1];
738         spc[2]                                                          = bbGetInputSpacing()[2];
739         
740         vtkStaticPointLocator   *pointLocator   = vtkStaticPointLocator::New();
741         pointLocator->SetDataSet( bbGetInputMesh() );
742         pointLocator->BuildLocator();
743         
744         int idControlPoint = wsp->GetModelShowNPoints()->GetNearestPoint();
745         if(idControlPoint >= 0){
746                     wsp->GetModelShowNPoints()->GetIdPoint(idControlPoint, &x, &y, &z);
747                     p[0] = x * spc[0];
748                     p[1] = y * spc[1];
749                     p[2] = z * spc[2];
750                     int idMeshPoint = pointLocator->FindClosestPoint(p);
751                     bbGetInputMesh()->GetPointData()->GetNormals()->GetTuple(idMeshPoint, normal);
752                         int direction = bbGetInputParams()[0];
753                     pN[0] = p[0] / spc[0] + direction*normal[0];
754                     pN[1] = p[1] / spc[1] + direction*normal[1];
755                     pN[2] = p[2] / spc[2] + direction*normal[2];
756                     
757                     wsp->GetModelShowNPoints()->SetPointById(idControlPoint, pN);
758                     wsp->GetViewShowNPoints()->RefreshPoint(idControlPoint);
759                     wsp->SetOutputBox();
760                 wsp->UndoRedo_SaveCollection();
761         }
762         
763         }
764 }
765
766 void ShowNPoints_Tools::JoinPoints()
767 {
768         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
769         wsp->StopAutoAddPoints();
770     wsp->StopTrackPoint();
771     if((wsp->GetLstModelShowNPointsSize()>=2)
772                 && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0))
773         {
774                 int numberOfSplines = wsp->GetLstModelShowNPointsSize();
775                 double x, y, z;
776                 int sizeCurrentSpline, i;
777                 wsp->GetModelShowNPoints()->GetIdPoint(0, &x, &y, &z);
778                 std::vector<double> pointStart = {x, y, z};
779                 sizeCurrentSpline = wsp->GetModelShowNPoints()->GetLstPointsX().size();
780                 wsp->GetModelShowNPoints()->GetIdPoint(sizeCurrentSpline-1, &x, &y, &z);
781                 std::vector<double> pointEnd = {x, y, z};
782                 for(i = 0; i < numberOfSplines; i++){
783                         sizeCurrentSpline = wsp->GetModelShowNPoints(i)->GetLstPointsX().size();
784                         wsp->SetCollectionPoint(i, 0, pointStart);
785                         wsp->SetCollectionPoint(i, sizeCurrentSpline-1, pointEnd);
786                 }
787                 wsp->SetOutputBox();
788         wsp->UndoRedo_SaveCollection();
789         }
790 }
791 //=====
792 // 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)
793 //===== 
794 void ShowNPoints_Tools::Process()
795 {
796
797 // THE MAIN PROCESSING METHOD BODY
798 //   Here we simply set the input 'In' value to the output 'Out'
799 //   And print out the output value
800 // INPUT/OUTPUT ACCESSORS ARE OF THE FORM :
801 //    void bbSet{Input|Output}NAME(const TYPE&)
802 //    const TYPE& bbGet{Input|Output}NAME() const 
803 //    Where :
804 //    * NAME is the name of the input/output
805 //      (the one provided in the attribute 'name' of the tag 'input')
806 //    * TYPE is the C++ type of the input/output
807 //      (the one provided in the attribute 'type' of the tag 'input')
808
809 //    bbSetOutputOut( bbGetInputIn() );
810 //    std::cout << "Output value = " <<bbGetOutputOut() << std::endl;
811
812     if (bbGetInputWidgetShowNPoints()!=NULL)
813     {
814         if (bbGetInputType()==1)
815         {
816             bbGetInputWidgetShowNPoints()->OnAutoAddPoints_tool();
817         } // if Type
818
819         if (bbGetInputType()==5)
820         {
821             bbGetInputWidgetShowNPoints()->OnAddPoint_();
822         } // if Type
823         if (bbGetInputType()==10)
824         {
825             bbGetInputWidgetShowNPoints()->OnInsertPoint_();
826         } // if Type
827         if (bbGetInputType()==20)
828         {
829             bbGetInputWidgetShowNPoints()->OnTrackPoint_tool();
830         } // if Type
831         if (bbGetInputType()==30)
832         {
833             bbGetInputWidgetShowNPoints()->OnSetPoint_();
834         } // if Type
835         if (bbGetInputType()==40)
836         {
837             bbGetInputWidgetShowNPoints()->OnErasePoint_();
838         } // if Type
839         if (bbGetInputType()==50)
840         {
841             bbGetInputWidgetShowNPoints()->OnDeleteAllPoints_();
842         } // if Type
843         if (bbGetInputType()==100)
844         {
845             bbGetInputWidgetShowNPoints()->OnInsertCollectionAfter_();
846         } // if Type
847         if (bbGetInputType()==110)
848         {
849             bbGetInputWidgetShowNPoints()->OnDeleteCollection_();
850         } // if Type
851         if (bbGetInputType()==120)
852         {
853             bbGetInputWidgetShowNPoints()->OnResetCollections_();
854         } // if Type
855         if (bbGetInputType()==200)   // Create patch surface
856         {
857             InitCreatePatch_Points();
858         } // if Type
859         if (bbGetInputType()==205)  // Create volume surface from points
860         {
861             InitCreateVolumeSurface_Points();
862         } // if Type
863         if (bbGetInputType()==210)
864         {
865             bbGetInputWidgetShowNPoints()->OnInvertLstPoints_();
866         } // if Type
867         if(bbGetInputType()==220)
868         {
869                 MovePatchCenter();
870         } // if Type
871         if(bbGetInputType()==230)
872         {
873                 MovePointInNormal();
874         } // if Type
875         if(bbGetInputType()==240)
876         {
877                 JoinPoints();
878         } // if Type
879         if(bbGetInputType()==300)
880         {
881                 CreateExpandedSurface();
882         } // if Type
883         if(bbGetInputType()==310)
884         {
885                 CreateWideExpandedSurface();
886         } // if Type
887         if(bbGetInputType()==320)
888         {
889                 ExpandSurfaceArea();
890         } // if Type
891         if(bbGetInputType()==330)
892         {
893                 WidenSurface();
894         } // if Type
895         if(bbGetInputType()==340)
896         {
897                 ExpandPatch();
898         } // if Type
899     } // if bbGetInputWidgetShowNPoints
900 }
901 //===== 
902 // 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)
903 //===== 
904 void ShowNPoints_Tools::bbUserSetDefaultValues()
905 {
906 //  SET HERE THE DEFAULT INPUT/OUTPUT VALUES OF YOUR BOX 
907 //    Here we initialize the input 'In' to 0
908    bbSetInputType(0);
909    bbSetInputMesh(NULL);
910    bbSetInputWidgetShowNPoints(NULL);
911     
912     std::vector<double> spc;
913     spc.push_back(1);
914     spc.push_back(1);
915     spc.push_back(1);
916     bbSetInputSpacing(spc);
917 }
918 //===== 
919 // 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)
920 //===== 
921 void ShowNPoints_Tools::bbUserInitializeProcessing()
922 {
923 //  THE INITIALIZATION METHOD BODY :
924 //    Here does nothing 
925 //    but this is where you should allocate the internal/output pointers 
926 //    if any
927 }
928 //===== 
929 // 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)
930 //===== 
931 void ShowNPoints_Tools::bbUserFinalizeProcessing()
932 {
933 //  THE FINALIZATION METHOD BODY :
934 //    Here does nothing 
935 //    but this is where you should desallocate the internal/output pointers 
936 //    if any
937 }
938
939 } // EO namespace bbcreaMaracasVisu
940
941