]> Creatis software - creaMaracasVisu.git/blob - bbtk/src/bbcreaMaracasVisuShowNPoints_Tools.cxx
#3502 Modify middle point in patch
[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         wsp->StopAutoAddPoints();
36     wsp->StopTrackPoint();
37         if ( (wsp->GetLstModelShowNPointsSize()==1) &&
38          (wsp->GetModelShowNPoints()->GetLstPointsSize()==3) &&
39          (bbGetInputMesh()!=NULL ) )
40     {
41                 std::vector<int> lstX = wsp->GetModelShowNPoints()->GetLstPointsX();
42                 std::vector<int> lstY = wsp->GetModelShowNPoints()->GetLstPointsY();
43                 std::vector<int> lstZ = wsp->GetModelShowNPoints()->GetLstPointsZ();
44                 
45                 double pA[3];
46         pA[0] = lstX[0];
47         pA[1] = lstY[0];
48         pA[2] = lstZ[0];
49         double pB[3];
50         pB[0] = lstX[1];
51         pB[1] = lstY[1];
52         pB[2] = lstZ[1];
53         double pC[3];
54         pC[0] = lstX[2];
55         pC[1] = lstY[2];
56         pC[2] = lstZ[2];
57
58                 double v[3];
59                 double u[3];
60                 vtkMath::Subtract(pC,pA,v);
61                 vtkMath::Subtract(pB,pA,u);
62                 
63                 /**point in AC closest to B.
64                 *formula t=(V)dot(U)/(V)dot(V)
65                 */
66                 double t = vtkMath::Dot(v,u)/vtkMath::Dot(v,v);
67                 /**nP found point
68                 *formula A+t(C-A) -> A+tV
69                 */
70                 vtkMath::MultiplyScalar(v, t);
71                 double nP[3];
72                 vtkMath::Add(pA, v, nP);
73                 
74                 //calculate direction vector from found point to B
75                 double dirVector[3];
76                 vtkMath::Subtract(pB, nP, dirVector);
77                 
78                 double pointAdd[3];
79                 double pointSub[3];
80                 
81                 //Add and subtract direction vector to A and C to find the 4 points to create the patch,
82                 
83                 std::vector<int> resListX;
84                 std::vector<int> resListY;
85                 std::vector<int> resListZ;
86                 
87                 vtkMath::Add(pA, dirVector, pointAdd);
88                 vtkMath::Subtract(pA, dirVector, pointSub);
89                 
90                 resListX.push_back(pointSub[0]);
91                 resListY.push_back(pointSub[1]);
92                 resListZ.push_back(pointSub[2]);
93
94                 resListX.push_back(pointAdd[0]);
95                 resListY.push_back(pointAdd[1]);
96                 resListZ.push_back(pointAdd[2]);
97                 
98                 
99                 vtkMath::Add(pC, dirVector, pointAdd);
100                 vtkMath::Subtract(pC, dirVector, pointSub);
101                 
102                 resListX.push_back(pointAdd[0]);
103                 resListY.push_back(pointAdd[1]);
104                 resListZ.push_back(pointAdd[2]);
105                 
106                 resListX.push_back(pointSub[0]);
107                 resListY.push_back(pointSub[1]);
108                 resListZ.push_back(pointSub[2]);
109                 //printf("PG ShowNPoints_Tools::CreatePatch_3points  Calls CreatePatch_Points !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
110                 //Create patch given the previously calculated points (4 points)
111                 CreatePatch_Points(resListX, resListY, resListZ);
112         }else{
113                 //printf("PG ShowNPoints_Tools::CreatePatch_3points  Warning patch not apply. Need only one group of 3 points\n");
114         }
115 }
116
117 void ShowNPoints_Tools::CreatePatch_4points()
118 {
119         WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
120         wsp->StopAutoAddPoints();
121     wsp->StopTrackPoint();
122         if ( (wsp->GetLstModelShowNPointsSize()==1) &&
123          (wsp->GetModelShowNPoints()->GetLstPointsSize()==4) &&
124          (bbGetInputMesh()!=NULL ) )
125     {                
126                 std::vector<int> lstX = wsp->GetModelShowNPoints()->GetLstPointsX();
127                 std::vector<int> lstY = wsp->GetModelShowNPoints()->GetLstPointsY();
128                 std::vector<int> lstZ = wsp->GetModelShowNPoints()->GetLstPointsZ();
129                 CreatePatch_Points(lstX, lstY, lstZ);
130     }else{
131                 printf("PG ShowNPoints_Tools::CreatePatch_4points  Warning patch not apply. Need only one group of 4 points\n");
132         }
133 }
134
135 void ShowNPoints_Tools::CreatePatch_Points(std::vector<int> lstX, std::vector<int> lstY, std::vector<int> lstZ)
136 {
137     WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
138     std::vector<long int>   lstIdNormalSurface;
139     double                  spc[3];
140                             spc[0]          = bbGetInputSpacing()[0];
141                             spc[1]          = bbGetInputSpacing()[1];
142                             spc[2]          = bbGetInputSpacing()[2];
143     vtkPoints               *points         = bbGetInputMesh()->GetPoints();
144     vtkStaticPointLocator   *pointLocator   = vtkStaticPointLocator::New();
145     pointLocator->SetDataSet( bbGetInputMesh() );
146     pointLocator->BuildLocator();
147     wsp->StopTrackPoint();
148     double p[3],pM[3];
149     double dx,dy,dz;
150     
151     wsp->DeleteAllPoints_();
152     //wsp->ErasePoint( 0 );
153     //wsp->ErasePoint( 0 );
154     //wsp->ErasePoint( 0 );
155     //wsp->ErasePoint( 0 );
156     // --- Group 0 ---
157     dx = lstX[1]-lstX[0];
158     dy = lstY[1]-lstY[0];
159     dz = lstZ[1]-lstZ[0];
160     //
161     //
162     double part = 0.25;
163     for(int sect = 0; sect < 5; sect++)
164     {
165         p[0] = lstX[0] + dx*(sect*part);
166                 p[1] = lstY[0] + dy*(sect*part);
167                 p[2] = lstZ[0] + dz*(sect*part);
168                 if(sect == 4){
169                         p[0] = p[0] + 0.5*(((lstX[1]+lstX[2])/2)-p[0]);
170                         p[1] = p[1] + 0.5*(((lstY[1]+lstY[2])/2)-p[1]);
171                         p[2] = p[2] + 0.5*(((lstZ[1]+lstZ[2])/2)-p[2]);
172                 }
173                 if(sect == 0){
174                         p[0] = p[0] + 0.5*(((lstX[0]+lstX[3])/2)-p[0]);
175                         p[1] = p[1] + 0.5*(((lstY[0]+lstY[3])/2)-p[1]);
176                         p[2] = p[2] + 0.5*(((lstZ[0]+lstZ[3])/2)-p[2]);
177                 }
178                 NearestPointToMesh(points, pointLocator, spc, p,pM);
179                 wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
180                 
181                 if(sect == 0 || sect == 4) lstIdNormalSurface.push_back( pointLocator->FindClosestPoint(pM) );
182     }
183         
184     // --- Group 1 ---
185     wsp->InsertCollectionAfter_();
186       p[0] = (lstX[0]+lstX[3])/2;
187       p[1] = (lstY[0]+lstY[3])/2;
188       p[2] = (lstZ[0]+lstZ[3])/2;
189       NearestPointToMesh(points, pointLocator, spc, p,pM);
190       wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
191       p[0] = (lstX[1]+lstX[2])/2;
192       p[1] = (lstY[1]+lstY[2])/2;
193       p[2] = (lstZ[1]+lstZ[2])/2;
194       NearestPointToMesh(points, pointLocator, spc, p,pM);
195       wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
196       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;
197       wsp->InsertPoint(p[0] ,p[1], p[2],"");
198         
199     // --- Group 2 ---
200     
201     wsp->InsertCollectionAfter_();
202
203     dx = lstX[2]-lstX[3];
204     dy = lstY[2]-lstY[3];
205     dz = lstZ[2]-lstZ[3];  
206     for(int sect = 0; sect < 5; sect++)
207     {
208         p[0] = lstX[3] + dx*(sect*part);
209                 p[1] = lstY[3] + dy*(sect*part);
210                 p[2] = lstZ[3] + dz*(sect*part);
211                 if(sect == 4){
212                         p[0] = p[0] + 0.5*(((lstX[1]+lstX[2])/2)-p[0]);
213                         p[1] = p[1] + 0.5*(((lstY[1]+lstY[2])/2)-p[1]);
214                         p[2] = p[2] + 0.5*(((lstZ[1]+lstZ[2])/2)-p[2]);
215                 }
216                 if(sect == 0){
217                         p[0] = p[0] + 0.5*(((lstX[0]+lstX[3])/2)-p[0]);
218                         p[1] = p[1] + 0.5*(((lstY[0]+lstY[3])/2)-p[1]);
219                         p[2] = p[2] + 0.5*(((lstZ[0]+lstZ[3])/2)-p[2]);
220                 }
221                 NearestPointToMesh(points, pointLocator, spc, p,pM);
222                 wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
223                 
224                 if(sect == 0 || sect == 4) lstIdNormalSurface.push_back( pointLocator->FindClosestPoint(pM) );
225     }
226
227      pointLocator->Delete();
228     
229     // Check normals
230 //        1. Recorrer las normales de lstIdNormals y calcular el promedio  -> V1
231     double          *nValue;
232         double                  n1[3];
233     vtkPointData    *pointdata  =  bbGetInputMesh()->GetPointData();
234     vtkDataArray    *dataarray  = pointdata->GetNormals();
235         int i,size = lstIdNormalSurface.size();
236         n1[0]=0;
237         n1[1]=0;
238         n1[2]=0;
239         for (i=0; i<size; i++)
240         {
241             nValue        = dataarray->GetTuple3( lstIdNormalSurface[i] );
242                 n1[0] = n1[0] + nValue[0];
243                 n1[1] = n1[1] + nValue[1];
244                 n1[2] = n1[2] + nValue[2];
245         } // for i
246         n1[0] = n1[0]/size;
247         n1[1] = n1[1]/size;
248         n1[2] = n1[2]/size;
249
250 //        2. Calcular el promedio de 4 normales de la nueva superficie     -> V2
251     double pC[3];
252     double pM1[3];
253     double pM2[3];
254     double n2[3];
255     n2[0] = 0;
256     n2[1] = 0;
257     n2[2] = 0;
258     // Collection 0 with 4 points
259     // Collection 1 with 3 points
260     // Collection 2 with 4 points
261     wsp->GetCollectionPoint(1,1, pC);
262     
263     wsp->GetCollectionPoint(0,0, pM);
264     vtkMath::Subtract(pM,pC,pM1);
265     wsp->GetCollectionPoint(0,3, pM);
266     vtkMath::Subtract(pM,pC,pM2);
267     vtkMath::Cross(pM1,pM2,pM);
268     n2[0] = pM[0];
269     n2[1] = pM[1];
270     n2[2] = pM[2];
271
272     wsp->GetCollectionPoint(0,3, pM);
273     vtkMath::Subtract(pM,pC,pM1);
274     wsp->GetCollectionPoint(2,3, pM);
275     vtkMath::Subtract(pM,pC,pM2);
276     vtkMath::Cross(pM1,pM2,pM);
277     n2[0] = n2[0] + pM[0];
278     n2[1] = n2[1] + pM[1];
279     n2[2] = n2[2] + pM[2];
280
281     wsp->GetCollectionPoint(2,3, pM);
282     vtkMath::Subtract(pM,pC,pM1);
283     wsp->GetCollectionPoint(2,0, pM);
284     vtkMath::Subtract(pM,pC,pM2);
285     vtkMath::Cross(pM1,pM2,pM);
286     n2[0] = n2[0] + pM[0];
287     n2[1] = n2[1] + pM[1];
288     n2[2] = n2[2] + pM[2];
289     
290     wsp->GetCollectionPoint(2,0, pM);
291     vtkMath::Subtract(pM,pC,pM1);
292     wsp->GetCollectionPoint(0,0, pM);
293     vtkMath::Subtract(pM,pC,pM2);
294     vtkMath::Cross(pM1,pM2,pM);
295     n2[0] = n2[0] + pM[0];
296     n2[1] = n2[1] + pM[1];
297     n2[2] = n2[2] + pM[2];
298     
299     n2[0] = n2[0] / 4;
300     n2[1] = n2[1] / 4;
301     n2[2] = n2[2] / 4;
302     
303 //        3. Calcular el angulo entre V1 y V2
304     double angle = vtkMath::AngleBetweenVectors(n1,n2) * 180 / vtkMath::Pi();
305 //        4. Si el angulo es major de 90 Invertir las normales de la superficie actual
306     if (angle<90)
307     {
308         vtkMath::MultiplyScalar(n2, -1);
309         wsp->InvertLstPoints_();
310     } // if angle
311     std::vector<double> normalOut(n2, n2 + 3);
312     double norm = vtkMath::Norm(n2);
313     normalOut[0] = normalOut[0]/norm;
314         normalOut[1] = normalOut[1]/norm;
315         normalOut[2] = normalOut[2]/norm;
316     bbSetOutputOut(normalOut);
317     
318     // --- Finish ---
319     wsp->SetOutputBox();
320     wsp->UndoRedo_SaveCollection();
321 }
322
323 void ShowNPoints_Tools::MovePatchCenter()
324 {       
325         std::vector<double> params = bbGetInputParams();
326         if(params.size() == 4)
327         {
328                 if(params[3] != 1 && params[3] != -1)
329                 {
330                         printf("PG ShowNPoints_Tools::MovePatchCenter()  Warning params are wrong. direction of movement should be 1 or -1\n");
331                         return;
332                 }
333                 
334                 double centerPoint[3];
335                 std::vector<double> normal, modPoint;
336                 
337                 normal.push_back(params[0]);
338                 normal.push_back(params[1]);
339                 normal.push_back(params[2]);
340
341                 int direction = -params[3];
342                 
343                 WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
344                 wsp->GetCollectionPoint(1,1, centerPoint);
345                 modPoint.push_back(centerPoint[0] + direction*normal[0]);
346                 modPoint.push_back(centerPoint[1] + direction*normal[1]);
347                 modPoint.push_back(centerPoint[2] + direction*normal[2]);
348
349                 wsp->SetCollectionPoint(1, 1, modPoint);
350                 wsp->GetViewShowNPoints()->RefreshPoints();
351         }else{
352                 printf("PG ShowNPoints_Tools::MovePatchCenter()  Warning params are wrong. Need 4: normal x y z and direction of movement (1 or -1)\n");
353         }
354 }
355
356 //=====
357 // 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)
358 //===== 
359 void ShowNPoints_Tools::Process()
360 {
361
362 // THE MAIN PROCESSING METHOD BODY
363 //   Here we simply set the input 'In' value to the output 'Out'
364 //   And print out the output value
365 // INPUT/OUTPUT ACCESSORS ARE OF THE FORM :
366 //    void bbSet{Input|Output}NAME(const TYPE&)
367 //    const TYPE& bbGet{Input|Output}NAME() const 
368 //    Where :
369 //    * NAME is the name of the input/output
370 //      (the one provided in the attribute 'name' of the tag 'input')
371 //    * TYPE is the C++ type of the input/output
372 //      (the one provided in the attribute 'type' of the tag 'input')
373
374 //    bbSetOutputOut( bbGetInputIn() );
375 //    std::cout << "Output value = " <<bbGetOutputOut() << std::endl;
376
377     if (bbGetInputWidgetShowNPoints()!=NULL)
378     {
379         if (bbGetInputType()==1)
380         {
381             bbGetInputWidgetShowNPoints()->OnAutoAddPoints_tool();
382         } // if Type
383
384         if (bbGetInputType()==5)
385         {
386             bbGetInputWidgetShowNPoints()->OnAddPoint_();
387         } // if Type
388         if (bbGetInputType()==10)
389         {
390             bbGetInputWidgetShowNPoints()->OnInsertPoint_();
391         } // if Type
392         if (bbGetInputType()==20)
393         {
394             bbGetInputWidgetShowNPoints()->OnTrackPoint_tool();
395         } // if Type
396         if (bbGetInputType()==30)
397         {
398             bbGetInputWidgetShowNPoints()->OnSetPoint_();
399         } // if Type
400         if (bbGetInputType()==40)
401         {
402             bbGetInputWidgetShowNPoints()->OnErasePoint_();
403         } // if Type
404         if (bbGetInputType()==50)
405         {
406             bbGetInputWidgetShowNPoints()->OnDeleteAllPoints_();
407         } // if Type
408         if (bbGetInputType()==100)
409         {
410             bbGetInputWidgetShowNPoints()->OnInsertCollectionAfter_();
411         } // if Type
412         if (bbGetInputType()==110)
413         {
414             bbGetInputWidgetShowNPoints()->OnDeleteCollection_();
415         } // if Type
416         if (bbGetInputType()==120)
417         {
418             bbGetInputWidgetShowNPoints()->OnResetCollections_();
419         } // if Type
420         if (bbGetInputType()==190)
421         {
422             CreatePatch_3points();
423         } // if Type
424         if (bbGetInputType()==200)
425         {
426             CreatePatch_4points();
427         } // if Type
428         if (bbGetInputType()==210)
429         {
430             bbGetInputWidgetShowNPoints()->OnInvertLstPoints_();
431         } // if Type
432         if(bbGetInputType()==220)
433         {
434                 MovePatchCenter();
435         } // if Type
436     } // if bbGetInputWidgetShowNPoints
437 }
438 //===== 
439 // 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)
440 //===== 
441 void ShowNPoints_Tools::bbUserSetDefaultValues()
442 {
443 //  SET HERE THE DEFAULT INPUT/OUTPUT VALUES OF YOUR BOX 
444 //    Here we initialize the input 'In' to 0
445    bbSetInputType(0);
446    bbSetInputMesh(NULL);
447    bbSetInputWidgetShowNPoints(NULL);
448     
449     std::vector<double> spc;
450     spc.push_back(1);
451     spc.push_back(1);
452     spc.push_back(1);
453     bbSetInputSpacing(spc);
454 }
455 //===== 
456 // 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)
457 //===== 
458 void ShowNPoints_Tools::bbUserInitializeProcessing()
459 {
460 //  THE INITIALIZATION METHOD BODY :
461 //    Here does nothing 
462 //    but this is where you should allocate the internal/output pointers 
463 //    if any
464 }
465 //===== 
466 // 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)
467 //===== 
468 void ShowNPoints_Tools::bbUserFinalizeProcessing()
469 {
470 //  THE FINALIZATION METHOD BODY :
471 //    Here does nothing 
472 //    but this is where you should desallocate the internal/output pointers 
473 //    if any
474 }
475
476 } // EO namespace bbcreaMaracasVisu
477
478