]> Creatis software - creaMaracasVisu.git/blob - bbtk/src/bbcreaMaracasVisuShowNPoints_Tools.cxx
#3506 New Tool Cut Surface
[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                 if(wsp->GetModelShowNPoints()->GetLstPointsSize()==4){
126                         CreatePatch_4points();
127                 }
128                 else if(wsp->GetModelShowNPoints()->GetLstPointsSize()==3){
129                         CreatePatch_3points();
130                 }
131                 else{
132                         printf("PG ShowNPoints_Tools::CreatePatch_Npoints  Warning patch not apply. Number of points is invalid. Group should have 3 or 4 points\n");
133                 }
134         }
135         else{
136                 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");
137         }
138 }
139
140 void ShowNPoints_Tools::CreatePatch_Points(std::vector<double> lstX, std::vector<double> lstY, std::vector<double> lstZ)
141 {
142     WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
143     std::vector<long int>   lstIdNormalSurface;
144     double                  spc[3];
145                             spc[0]          = bbGetInputSpacing()[0];
146                             spc[1]          = bbGetInputSpacing()[1];
147                             spc[2]          = bbGetInputSpacing()[2];
148     vtkPoints               *points         = bbGetInputMesh()->GetPoints();
149     vtkStaticPointLocator   *pointLocator   = vtkStaticPointLocator::New();
150     pointLocator->SetDataSet( bbGetInputMesh() );
151     pointLocator->BuildLocator();
152     wsp->StopTrackPoint();
153     double p[3],pM[3];
154     double dx,dy,dz;
155     
156     wsp->DeleteAllPoints_();
157     //wsp->ErasePoint( 0 );
158     //wsp->ErasePoint( 0 );
159     //wsp->ErasePoint( 0 );
160     //wsp->ErasePoint( 0 );
161     // --- Group 0 ---
162     dx = lstX[1]-lstX[0];
163     dy = lstY[1]-lstY[0];
164     dz = lstZ[1]-lstZ[0];
165     //
166     //
167     double part = 0.25;
168     for(int sect = 0; sect < 5; sect++)
169     {
170         p[0] = lstX[0] + dx*(sect*part);
171                 p[1] = lstY[0] + dy*(sect*part);
172                 p[2] = lstZ[0] + dz*(sect*part);
173                 if(sect == 4){
174                         p[0] = p[0] + 0.5*(((lstX[1]+lstX[2])/2)-p[0]);
175                         p[1] = p[1] + 0.5*(((lstY[1]+lstY[2])/2)-p[1]);
176                         p[2] = p[2] + 0.5*(((lstZ[1]+lstZ[2])/2)-p[2]);
177                 }
178                 if(sect == 0){
179                         p[0] = p[0] + 0.5*(((lstX[0]+lstX[3])/2)-p[0]);
180                         p[1] = p[1] + 0.5*(((lstY[0]+lstY[3])/2)-p[1]);
181                         p[2] = p[2] + 0.5*(((lstZ[0]+lstZ[3])/2)-p[2]);
182                 }
183                 NearestPointToMesh(points, pointLocator, spc, p,pM);
184                 wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
185                 
186                 if(sect == 0 || sect == 4) lstIdNormalSurface.push_back( pointLocator->FindClosestPoint(pM) );
187     }
188         
189     // --- Group 1 ---
190     wsp->InsertCollectionAfter_();
191       p[0] = (lstX[0]+lstX[3])/2;
192       p[1] = (lstY[0]+lstY[3])/2;
193       p[2] = (lstZ[0]+lstZ[3])/2;
194       NearestPointToMesh(points, pointLocator, spc, p,pM);
195       wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
196       p[0] = (lstX[1]+lstX[2])/2;
197       p[1] = (lstY[1]+lstY[2])/2;
198       p[2] = (lstZ[1]+lstZ[2])/2;
199       NearestPointToMesh(points, pointLocator, spc, p,pM);
200       wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
201       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;
202       wsp->InsertPoint(p[0] ,p[1], p[2],"");
203         
204     // --- Group 2 ---
205     
206     wsp->InsertCollectionAfter_();
207
208     dx = lstX[2]-lstX[3];
209     dy = lstY[2]-lstY[3];
210     dz = lstZ[2]-lstZ[3];  
211     for(int sect = 0; sect < 5; sect++)
212     {
213         p[0] = lstX[3] + dx*(sect*part);
214                 p[1] = lstY[3] + dy*(sect*part);
215                 p[2] = lstZ[3] + dz*(sect*part);
216                 if(sect == 4){
217                         p[0] = p[0] + 0.5*(((lstX[1]+lstX[2])/2)-p[0]);
218                         p[1] = p[1] + 0.5*(((lstY[1]+lstY[2])/2)-p[1]);
219                         p[2] = p[2] + 0.5*(((lstZ[1]+lstZ[2])/2)-p[2]);
220                 }
221                 if(sect == 0){
222                         p[0] = p[0] + 0.5*(((lstX[0]+lstX[3])/2)-p[0]);
223                         p[1] = p[1] + 0.5*(((lstY[0]+lstY[3])/2)-p[1]);
224                         p[2] = p[2] + 0.5*(((lstZ[0]+lstZ[3])/2)-p[2]);
225                 }
226                 NearestPointToMesh(points, pointLocator, spc, p,pM);
227                 wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
228                 
229                 if(sect == 0 || sect == 4) lstIdNormalSurface.push_back( pointLocator->FindClosestPoint(pM) );
230     }
231
232      pointLocator->Delete();
233     
234     // Check normals
235 //        1. Recorrer las normales de lstIdNormals y calcular el promedio  -> V1
236     double          *nValue;
237         double                  n1[3];
238     vtkPointData    *pointdata  =  bbGetInputMesh()->GetPointData();
239     vtkDataArray    *dataarray  = pointdata->GetNormals();
240         int i,size = lstIdNormalSurface.size();
241         n1[0]=0;
242         n1[1]=0;
243         n1[2]=0;
244         for (i=0; i<size; i++)
245         {
246             nValue        = dataarray->GetTuple3( lstIdNormalSurface[i] );
247                 n1[0] = n1[0] + nValue[0];
248                 n1[1] = n1[1] + nValue[1];
249                 n1[2] = n1[2] + nValue[2];
250         } // for i
251         n1[0] = n1[0]/size;
252         n1[1] = n1[1]/size;
253         n1[2] = n1[2]/size;
254
255 //        2. Calcular el promedio de 4 normales de la nueva superficie     -> V2
256     double pC[3];
257     double pM1[3];
258     double pM2[3];
259     double n2[3];
260     n2[0] = 0;
261     n2[1] = 0;
262     n2[2] = 0;
263     // Collection 0 with 4 points
264     // Collection 1 with 3 points
265     // Collection 2 with 4 points
266     wsp->GetCollectionPoint(1,1, pC);
267     
268     wsp->GetCollectionPoint(0,0, pM);
269     vtkMath::Subtract(pM,pC,pM1);
270     wsp->GetCollectionPoint(0,3, pM);
271     vtkMath::Subtract(pM,pC,pM2);
272     vtkMath::Cross(pM1,pM2,pM);
273     n2[0] = pM[0];
274     n2[1] = pM[1];
275     n2[2] = pM[2];
276
277     wsp->GetCollectionPoint(0,3, pM);
278     vtkMath::Subtract(pM,pC,pM1);
279     wsp->GetCollectionPoint(2,3, pM);
280     vtkMath::Subtract(pM,pC,pM2);
281     vtkMath::Cross(pM1,pM2,pM);
282     n2[0] = n2[0] + pM[0];
283     n2[1] = n2[1] + pM[1];
284     n2[2] = n2[2] + pM[2];
285
286     wsp->GetCollectionPoint(2,3, pM);
287     vtkMath::Subtract(pM,pC,pM1);
288     wsp->GetCollectionPoint(2,0, pM);
289     vtkMath::Subtract(pM,pC,pM2);
290     vtkMath::Cross(pM1,pM2,pM);
291     n2[0] = n2[0] + pM[0];
292     n2[1] = n2[1] + pM[1];
293     n2[2] = n2[2] + pM[2];
294     
295     wsp->GetCollectionPoint(2,0, pM);
296     vtkMath::Subtract(pM,pC,pM1);
297     wsp->GetCollectionPoint(0,0, pM);
298     vtkMath::Subtract(pM,pC,pM2);
299     vtkMath::Cross(pM1,pM2,pM);
300     n2[0] = n2[0] + pM[0];
301     n2[1] = n2[1] + pM[1];
302     n2[2] = n2[2] + pM[2];
303     
304     n2[0] = n2[0] / 4;
305     n2[1] = n2[1] / 4;
306     n2[2] = n2[2] / 4;
307     
308 //        3. Calcular el angulo entre V1 y V2
309     double angle = vtkMath::AngleBetweenVectors(n1,n2) * 180 / vtkMath::Pi();
310 //        4. Si el angulo es major de 90 Invertir las normales de la superficie actual
311     if (angle<90)
312     {
313         vtkMath::MultiplyScalar(n2, -1);
314         wsp->InvertLstPoints_();
315     } // if angle
316     std::vector<double> normalOut(n2, n2 + 3);
317     double norm = vtkMath::Norm(n2);
318     normalOut[0] = normalOut[0]/norm;
319         normalOut[1] = normalOut[1]/norm;
320         normalOut[2] = normalOut[2]/norm;
321     bbSetOutputOut(normalOut);
322     
323     // --- Finish ---
324     wsp->SetOutputBox();
325     wsp->UndoRedo_SaveCollection();
326 }
327
328 void ShowNPoints_Tools::MovePatchCenter()
329 {       
330         std::vector<double> params = bbGetInputParams();
331         if(params.size() == 4)
332         {
333                 if(params[3] != 1 && params[3] != -1)
334                 {
335                         printf("PG ShowNPoints_Tools::MovePatchCenter()  Warning params are wrong. direction of movement should be 1 or -1\n");
336                         return;
337                 }
338                 
339                 double centerPoint[3];
340                 std::vector<double> normal, modPoint;
341                 
342                 normal.push_back(params[0]);
343                 normal.push_back(params[1]);
344                 normal.push_back(params[2]);
345
346                 int direction = -1 * params[3];
347                 
348                 WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
349                 wsp->GetCollectionPoint(1,1, centerPoint);
350                 modPoint.push_back(centerPoint[0] + direction * normal[0]);
351                 modPoint.push_back(centerPoint[1] + direction * normal[1]);
352                 modPoint.push_back(centerPoint[2] + direction * normal[2]);
353
354                 wsp->SetCollectionPoint(1, 1, modPoint);
355         
356         // --- Finish ---
357         wsp->SetOutputBox();
358         wsp->UndoRedo_SaveCollection();
359         }else{
360                 printf("PG ShowNPoints_Tools::MovePatchCenter()  Warning params are wrong. Need 4: normal x y z and direction of movement (1 or -1)\n");
361         }
362 }
363
364 /**
365 *       Creates a cutting surface with 1 group of points. This surface can have its area adjusted 
366 *       (increase or decrease the distance from the points to the center)
367 *       The centroid is set as the output, to be used by the expanding tool.
368 */
369 void ShowNPoints_Tools::CreateExpandedSurface()
370 {
371         //
372         //Set Input to 0 as this function is only used by the popup menu
373         bbSetInputType(0);
374         //
375         //
376         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
377         wsp->StopAutoAddPoints();
378     wsp->StopTrackPoint();
379         if((wsp->GetLstModelShowNPointsSize()==1) && (bbGetInputMesh()!=NULL ) && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0))
380         {       
381                 std::vector<double> lstX = wsp->GetModelShowNPoints()->GetLstPointsX();
382                 std::vector<double> lstY = wsp->GetModelShowNPoints()->GetLstPointsY();
383                 std::vector<double> lstZ = wsp->GetModelShowNPoints()->GetLstPointsZ();
384                 
385                 wsp->DeleteAllPoints_();
386                 double centroid[3];
387                 
388                 for(int i = 0; i < (int)lstX.size(); i++){
389                         centroid[0] += lstX[i];
390                         centroid[1] += lstY[i];
391                         centroid[2] += lstZ[i];
392                 }
393                 centroid[0] /= lstX.size();
394                 centroid[1] /= lstX.size();
395                 centroid[2] /= lstX.size();
396                 
397                 double p[3];
398                 double dV[3];
399                 
400                 for(int i = 0; i < (int)lstX.size(); i++){
401                         dV[0] = lstX[i] - centroid[0];
402                         dV[1] = lstY[i] - centroid[1];
403                         dV[2] = lstZ[i] - centroid[2];
404                         vtkMath::Normalize(dV);
405                         
406                         p[0] = lstX[i] + 4*dV[0];
407                         p[1] = lstY[i] + 4*dV[1];
408                         p[2] = lstZ[i] + 4*dV[2];
409                         wsp->AddPoint(p[0] ,p[1], p[2],"");
410                 }
411                 
412                 std::vector<double> outData = {centroid[0], centroid[1], centroid[2]};
413                 bbSetOutputOut(outData);
414         }
415         else{
416                 printf("PG ShowNPoints_Tools::CreateExpandedSurface  Warning surface not apply. groups, mesh or points invalid. need 1 group of points\n");
417         }
418         // --- Finish ---
419         wsp->SetOutputBox();
420         wsp->UndoRedo_SaveCollection();
421 }
422
423 /**
424 *       Creates a cutting surface with 3 groups of points. This surface can have its area adjusted
425 *       (Increase or decrease distance from points to centroid of spline or distance between splines)
426 *       The centroid and normal is set as the Output, to be used by the expanding tools.
427 */
428 void ShowNPoints_Tools::CreateWideExpandedSurface()
429 {
430         //
431         //Set Input to 0 as this function is only used by the popup menu
432         bbSetInputType(0);
433         //
434         //
435         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
436         wsp->StopAutoAddPoints();
437     wsp->StopTrackPoint();
438     
439         if((wsp->GetLstModelShowNPointsSize()==1) && (bbGetInputMesh()!=NULL ) && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0))
440         {       
441                 std::vector<double> lstX = wsp->GetModelShowNPoints()->GetLstPointsX();
442                 std::vector<double> lstY = wsp->GetModelShowNPoints()->GetLstPointsY();
443                 std::vector<double> lstZ = wsp->GetModelShowNPoints()->GetLstPointsZ();
444                 
445                 wsp->DeleteAllPoints_();
446                 
447                 double normal[3];
448                 double centroid[3];
449                         
450                 for(int i = 0; i < (int)lstX.size(); i++){
451                         centroid[0] += lstX[i];
452                         centroid[1] += lstY[i];
453                         centroid[2] += lstZ[i];
454                 }
455                 centroid[0] /= lstX.size();
456                 centroid[1] /= lstX.size();
457                 centroid[2] /= lstX.size();
458                 
459                 double v1[3], v2[3];
460                 double currNormal[3];
461                 
462                 for(int i = 0; i < ((int)lstX.size())-1; i++){
463                         v1[0] = lstX[i] - centroid[0];
464                         v1[1] = lstY[i] - centroid[1];
465                         v1[2] = lstZ[i] - centroid[2];          
466                         v2[0] = lstX[i+1] - centroid[0];
467                         v2[1] = lstY[i+1] - centroid[1];
468                         v2[2] = lstZ[i+1] - centroid[2];
469                         vtkMath::Cross(v1, v2, currNormal);
470                         normal[0] += currNormal[0];
471                         normal[1] += currNormal[1];
472                         normal[2] += currNormal[2];
473                 }
474                 
475                 normal[0] /= (lstX.size()-1);
476                 normal[1] /= (lstX.size()-1);
477                 normal[2] /= (lstX.size()-1);
478                 
479                 vtkMath::Normalize(normal);
480                 
481                 double np[3], dV[3];
482                 int     addNormal = 1;
483                 //Add new groups on both sides from the main group
484                 for(int group = 0; group < 3; group++){
485                         for(int i = 0; i < (int) lstX.size(); i++){
486                                 dV[0] = lstX[i] - centroid[0];
487                                 dV[1] = lstY[i] - centroid[1];
488                                 dV[2] = lstZ[i] - centroid[2];
489                                 vtkMath::Normalize(dV);
490                                 
491                                 np[0] = lstX[i] + dV[0]*4 + ((normal[0]*2)*addNormal);
492                                 np[1] = lstY[i] + dV[1]*4 + ((normal[1]*2)*addNormal);
493                                 np[2] = lstZ[i] + dV[2]*4 + ((normal[2]*2)*addNormal);
494                                 wsp->AddPoint(np[0] ,np[1], np[2],"");
495                         }
496                         addNormal--;
497                         if(group < 2)wsp->InsertCollectionAfter_();
498                 }
499                 
500                 std::vector<double> outData = {centroid[0], centroid[1], centroid[2], normal[0], normal[1], normal[2]};
501                 bbSetOutputOut(outData);
502                 
503                 // --- Finish ---
504         wsp->SetOutputBox();
505         wsp->UndoRedo_SaveCollection();
506         }
507         else{
508                 printf("PG ShowNPoints_Tools::CreateWideExpandedSurface  Warning surface not apply. groups, mesh or points invalid. need 1 group of points\n");
509         }
510 }
511
512 /**
513 *       Given a cutting surface, expand its area by moving the points outwards of the main centroid.
514 */
515 void ShowNPoints_Tools::ExpandSurfaceArea()
516 {
517         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
518         wsp->StopAutoAddPoints();
519     wsp->StopTrackPoint();
520
521         if((wsp->GetLstModelShowNPointsSize()==1 || wsp->GetLstModelShowNPointsSize() == 3)  
522                 && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0)
523                 && (bbGetInputParams().size() == 4))
524         {
525                 std::vector<double> params = bbGetInputParams();
526                 double direction = params[3];
527                 double centroid[3] = {params[0], params[1], params[2]};
528                 int numCollection = wsp->GetLstModelShowNPointsSize()==1?0:1;
529                 
530                 double dV[3], currPoint[3], mdfdPoint[3];
531                 
532                 std::vector<double> modPoint;
533                 int pointsPerSpline = wsp->GetModelShowNPoints()->GetLstPointsSize();
534                 for(int i = 0; i < pointsPerSpline; i++){
535                         wsp->GetCollectionPoint(numCollection, i, currPoint);
536                         dV[0] = currPoint[0] - centroid[0];
537                         dV[1] = currPoint[1] - centroid[1];
538                         dV[2] = currPoint[2] - centroid[2];
539                         vtkMath::Normalize(dV);
540                         
541                         vtkMath::MultiplyScalar(dV, direction);
542                         vtkMath::Add(currPoint, dV, mdfdPoint);
543                         modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
544                         wsp->SetCollectionPoint(numCollection, i, modPoint);
545                         
546                         if(wsp->GetLstModelShowNPointsSize() == 3){
547                                 wsp->GetCollectionPoint(0, i, currPoint);
548                                 vtkMath::Add(currPoint, dV, mdfdPoint);
549                                 modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
550                                 wsp->SetCollectionPoint(0, i, modPoint);
551                                 
552                                 wsp->GetCollectionPoint(2, i, currPoint);
553                                 vtkMath::Add(currPoint, dV, mdfdPoint);
554                                 modPoint.insert(modPoint.begin(), std::begin(mdfdPoint), std::end(mdfdPoint));
555                                 wsp->SetCollectionPoint(2, i, modPoint);
556                         }
557                 }
558         }
559         else{
560                 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");
561         }
562         // --- Finish ---
563         wsp->SetOutputBox();
564         wsp->UndoRedo_SaveCollection();
565 }
566 /**
567 *       Given a cutting surface, expand the distance between the edge splines and the middle spline. making it "wider".
568 */
569 void ShowNPoints_Tools::WidenSurface()
570 {
571         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
572         wsp->StopAutoAddPoints();
573     wsp->StopTrackPoint();
574
575         if((wsp->GetLstModelShowNPointsSize()==3)  
576                 && (wsp->GetModelShowNPoints()->GetLstPointsSize()>0)
577                 && (bbGetInputParams().size() == 4))
578         {
579                 double direction = bbGetInputParams()[3];
580                 double normal[3] = {bbGetInputParams()[0], bbGetInputParams()[1], bbGetInputParams()[2]};
581                 vtkMath::MultiplyScalar(normal, direction);
582                 
583                 int pointsPerSpline = wsp->GetModelShowNPoints()->GetLstPointsSize();
584                 double pointSp1[3], pointSp2[3];
585                 std::vector<double> modifiedPoint;
586                 for(int i = 0; i < pointsPerSpline; i++){
587                         wsp->GetCollectionPoint(0, i, pointSp1);
588                         wsp->GetCollectionPoint(2, i, pointSp2);
589                         vtkMath::Add(pointSp1, normal, pointSp1);
590                         vtkMath::Subtract(pointSp2, normal, pointSp2);
591                         modifiedPoint.insert(modifiedPoint.begin(), std::begin(pointSp1), std::end(pointSp1));
592                         wsp->SetCollectionPoint(0, i, modifiedPoint);
593                         modifiedPoint.insert(modifiedPoint.begin(), std::begin(pointSp2), std::end(pointSp2));
594                         wsp->SetCollectionPoint(2, i, modifiedPoint);
595                 }
596         
597         }else{
598                 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");
599         }
600         // --- Finish ---
601         wsp->SetOutputBox();
602         wsp->UndoRedo_SaveCollection();
603 }
604 //=====
605 // 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)
606 //===== 
607 void ShowNPoints_Tools::Process()
608 {
609
610 // THE MAIN PROCESSING METHOD BODY
611 //   Here we simply set the input 'In' value to the output 'Out'
612 //   And print out the output value
613 // INPUT/OUTPUT ACCESSORS ARE OF THE FORM :
614 //    void bbSet{Input|Output}NAME(const TYPE&)
615 //    const TYPE& bbGet{Input|Output}NAME() const 
616 //    Where :
617 //    * NAME is the name of the input/output
618 //      (the one provided in the attribute 'name' of the tag 'input')
619 //    * TYPE is the C++ type of the input/output
620 //      (the one provided in the attribute 'type' of the tag 'input')
621
622 //    bbSetOutputOut( bbGetInputIn() );
623 //    std::cout << "Output value = " <<bbGetOutputOut() << std::endl;
624
625     if (bbGetInputWidgetShowNPoints()!=NULL)
626     {
627         if (bbGetInputType()==1)
628         {
629             bbGetInputWidgetShowNPoints()->OnAutoAddPoints_tool();
630         } // if Type
631
632         if (bbGetInputType()==5)
633         {
634             bbGetInputWidgetShowNPoints()->OnAddPoint_();
635         } // if Type
636         if (bbGetInputType()==10)
637         {
638             bbGetInputWidgetShowNPoints()->OnInsertPoint_();
639         } // if Type
640         if (bbGetInputType()==20)
641         {
642             bbGetInputWidgetShowNPoints()->OnTrackPoint_tool();
643         } // if Type
644         if (bbGetInputType()==30)
645         {
646             bbGetInputWidgetShowNPoints()->OnSetPoint_();
647         } // if Type
648         if (bbGetInputType()==40)
649         {
650             bbGetInputWidgetShowNPoints()->OnErasePoint_();
651         } // if Type
652         if (bbGetInputType()==50)
653         {
654             bbGetInputWidgetShowNPoints()->OnDeleteAllPoints_();
655         } // if Type
656         if (bbGetInputType()==100)
657         {
658             bbGetInputWidgetShowNPoints()->OnInsertCollectionAfter_();
659         } // if Type
660         if (bbGetInputType()==110)
661         {
662             bbGetInputWidgetShowNPoints()->OnDeleteCollection_();
663         } // if Type
664         if (bbGetInputType()==120)
665         {
666             bbGetInputWidgetShowNPoints()->OnResetCollections_();
667         } // if Type
668         if (bbGetInputType()==200)
669         {
670             InitCreatePatch_Points();
671         } // if Type
672         if (bbGetInputType()==210)
673         {
674             bbGetInputWidgetShowNPoints()->OnInvertLstPoints_();
675         } // if Type
676         if(bbGetInputType()==220)
677         {
678                 MovePatchCenter();
679         } // if Type
680         if(bbGetInputType()==300)
681         {
682                 CreateExpandedSurface();
683         } // if Type
684         if(bbGetInputType()==310)
685         {
686                 CreateWideExpandedSurface();
687         } // if Type
688         if(bbGetInputType()==320)
689         {
690                 ExpandSurfaceArea();
691         } // if Type
692         if(bbGetInputType()==330)
693         {
694                 WidenSurface();
695         } // if Type
696     } // if bbGetInputWidgetShowNPoints
697 }
698 //===== 
699 // 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)
700 //===== 
701 void ShowNPoints_Tools::bbUserSetDefaultValues()
702 {
703 //  SET HERE THE DEFAULT INPUT/OUTPUT VALUES OF YOUR BOX 
704 //    Here we initialize the input 'In' to 0
705    bbSetInputType(0);
706    bbSetInputMesh(NULL);
707    bbSetInputWidgetShowNPoints(NULL);
708     
709     std::vector<double> spc;
710     spc.push_back(1);
711     spc.push_back(1);
712     spc.push_back(1);
713     bbSetInputSpacing(spc);
714 }
715 //===== 
716 // 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)
717 //===== 
718 void ShowNPoints_Tools::bbUserInitializeProcessing()
719 {
720 //  THE INITIALIZATION METHOD BODY :
721 //    Here does nothing 
722 //    but this is where you should allocate the internal/output pointers 
723 //    if any
724 }
725 //===== 
726 // 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)
727 //===== 
728 void ShowNPoints_Tools::bbUserFinalizeProcessing()
729 {
730 //  THE FINALIZATION METHOD BODY :
731 //    Here does nothing 
732 //    but this is where you should desallocate the internal/output pointers 
733 //    if any
734 }
735
736 } // EO namespace bbcreaMaracasVisu
737
738