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