]> Creatis software - creaVtk.git/commitdiff
#3502 Bug close surface in CreateMeshFromPoints
authorPablo Garzon <garzon@ei-pfe-706.creatis.insa-lyon.fr>
Fri, 24 Mar 2023 10:41:45 +0000 (11:41 +0100)
committerPablo Garzon <garzon@ei-pfe-706.creatis.insa-lyon.fr>
Fri, 24 Mar 2023 10:41:45 +0000 (11:41 +0100)
bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.cxx
bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.h

index 69aab0853b9182bfbc92af097f6a8ca2fe5caf96..463e632ca411f127a9a7f0f9e0cd8473252007c8 100644 (file)
@@ -39,7 +39,7 @@ void CreateMeshFromPoints::Process()
                std::vector<int> lstIndexs              = bbGetInputLstIndexs();
                if ( (lstIndexs.size()<=1) || (lstX.size()==0) || (lstX.size()!=lstY.size()) || (lstY.size()!=lstZ.size()) )
                {
-                       printf("PG CreateMeshFromPoints::Process: List of points X Y Z  and LstIndexes is not correct\n");
+                       printf("Warning! CreateMeshFromPoints::Process: List of points X Y Z  and LstIndexes is not correct\n");
                        bbSetOutputOut(NULL);
                } else  {
                        int ii,sizeSegment1,sizeSegment2;
@@ -85,14 +85,20 @@ void CreateMeshFromPoints::Process()
                                cells->InsertNextCell(triangleStrip);
                        } //for  LstIndexs
 
+                       int lastId1 = lstIndexs[0]-1;
+                       int lastId2 = sizeLstX - 1;
+                       int firstId2 = sizeLstX - lstIndexs[sizeLstIdexes - 1];
+                       bool face1open = lstX[0] != lstX[lastId1] && lstY[0] != lstY[lastId1] && lstZ[0] != lstZ[lastId1];
+                       bool face2open = lstX[firstId2] != lstX[lastId2] && lstY[firstId2] != lstY[lastId2] && lstZ[firstId2] != lstZ[lastId2];
                        
-                       if(bbGetInputCloseSurface()){                   
+                       if(bbGetInputCloseSurface())
+                       {                       
                                //false = Open Contour
                                //true = Closed Contour
-                               if(bbGetInputOpenClose()){                      
+                               if(!face1open && !face2open)
+                               {               
                                        CloseContourSides(lstIndexs, true);
-                               }
-                               else{
+                               }else{
                                        CloseOpenContourSurface(lstIndexs);
                                }
                        }
@@ -134,38 +140,37 @@ void CreateMeshFromPoints::CloseContourSides(std::vector<int> lstIndexs, bool uP
        
        for(int facesIdx = 0; facesIdx < 2; facesIdx++){
                std::fill(std::begin(centroid), std::end(centroid), 0);
-               if(facesIdx == 0){
+               if(facesIdx == 0)
+               {
                        firstIndex = 0;
                        numPointsFace = uPointOrder?lstIndexs[0]: sizeLstIdexes;
                        end = uPointOrder?firstIndex + numPointsFace:sizePoints - lstIndexs[sizeLstIdexes - 1] + 1;
                        contraryId = sizePoints-1;
-               }
-               else{
+               }else{
                        firstIndex = uPointOrder?sizePoints - lstIndexs[sizeLstIdexes-1]:lstIndexs[0]-1;
                        numPointsFace = uPointOrder?lstIndexs[sizeLstIdexes-1]:sizeLstIdexes;
                        end = uPointOrder?firstIndex + numPointsFace:sizePoints;
                        contraryId = 0;
                }
-               if(numPointsFace > 1){
-                       double lastPoint[3] = {};
+               if(numPointsFace > 1)
+               {
                        bool validCentroid = CalcValidCentroid(centroid, firstIndex, end, increment, numPointsFace);
-                       if(validCentroid){
+                       if(validCentroid)
+                       {
                                bool normalOrder    = isPointingCorrectly(firstIndex, firstIndex+increment, centroid, contraryId);
                                centroidId          = points->InsertNextPoint(centroid[0], centroid[1], centroid[2]);
                                vtkSmartPointer<vtkTriangleStrip> triangleStrip1 = vtkSmartPointer<vtkTriangleStrip>::New();
-                               triangleStrip1->GetPointIds()->SetNumberOfIds(numPointsFace*2+1);
-                               if( !normalOrder )
-                {      //(facesIdx == 0 && uPointOrder) || (facesIdx == 1 && !uPointOrder)){
+                               triangleStrip1->GetPointIds()->SetNumberOfIds(numPointsFace*2+2);
+                               if( normalOrder )
+                {
                                        int initial = firstIndex;
                                        int triangleIndex = 0;
                                        for(int index = initial; index < end; index+=increment){
                                                triangleStrip1->GetPointIds()->SetId(triangleIndex,index);
+                                               triangleStrip1->GetPointIds()->SetId(triangleIndex+1,centroidId);
                                                if(index+increment >= end){
-                                                       triangleStrip1->GetPointIds()->SetId(triangleIndex+1,initial);
-                                                       triangleStrip1->GetPointIds()->SetId(triangleIndex+2,centroidId);
-                                               }
-                                               else{
-                                                       triangleStrip1->GetPointIds()->SetId(triangleIndex+1,centroidId);
+                                                       triangleStrip1->GetPointIds()->SetId(triangleIndex+2,initial);
+                                                       triangleStrip1->GetPointIds()->SetId(triangleIndex+3,centroidId);
                                                }
                                                triangleIndex+=2;
                                        }
@@ -176,12 +181,10 @@ void CreateMeshFromPoints::CloseContourSides(std::vector<int> lstIndexs, bool uP
                                        int triangleStripStart = end-1;
                                        for(int index = triangleStripStart; index > initial; index-=increment){
                                                triangleStrip1->GetPointIds()->SetId(triangleIndex,index);
+                                               triangleStrip1->GetPointIds()->SetId(triangleIndex+1,centroidId);
                                                if(index-increment <= initial){
-                                                       triangleStrip1->GetPointIds()->SetId(triangleIndex+1,triangleStripStart);
-                                                       triangleStrip1->GetPointIds()->SetId(triangleIndex+2,centroidId);
-                                               }
-                                               else{
-                                                       triangleStrip1->GetPointIds()->SetId(triangleIndex+1,centroidId);
+                                                       triangleStrip1->GetPointIds()->SetId(triangleIndex+2,triangleStripStart);
+                                                       triangleStrip1->GetPointIds()->SetId(triangleIndex+3,centroidId);
                                                }
                                                triangleIndex+=2;
                                        }
@@ -216,7 +219,7 @@ bool CreateMeshFromPoints::isPointingCorrectly( int firstPointId, int secPointId
        double dotCalc;
        dotCalc = vtkMath::Dot(normal, contrVect);
        
-       return dotCalc<0;
+       return dotCalc>0;
 }
 
 /**
@@ -255,15 +258,13 @@ bool CreateMeshFromPoints::CheckLinePointOrder(){
 * lstIndexs: number of points on each spline
 */
 void CreateMeshFromPoints::CloseOpenContourSurface(std::vector<int> lstIndexs){
-       int     sizeLstIdexes = lstIndexs.size();
-       int sizeLstX = bbGetInputLstX().size();
        bool linePointOrder = CheckLinePointOrder();
        CloseContourSides(lstIndexs, !linePointOrder);
        CloseContourBottom(!linePointOrder);
 }
 
 /**
-* Calculates centroid.
+* Calculates centroid and checks if points are collinear.
 * centroid: array to store calculation
 * start: start index of points to use
 * end: end index of points to use
@@ -273,23 +274,39 @@ void CreateMeshFromPoints::CloseOpenContourSurface(std::vector<int> lstIndexs){
 * False = invalid centroid = all points are the same.
 */
 bool CreateMeshFromPoints::CalcValidCentroid(double(&centroid)[3], int start, int end, int increment, int numPoints){
-       double currPoint[3] = {}, prevPoint[3] = {};
+       double currPoint[3] = {}, prevPoint[3] = {}, middlePoint[3] = {}, firstPoint[3] = {};
+       double vector1[3], vector2[3];
        bool samePoint = true;
+       int splineMidPoint = numPoints/2;
+       bool collinear = true;
+       
+       points->GetPoint(start, firstPoint);
+       points->GetPoint(splineMidPoint, middlePoint);
+       vtkMath::Subtract(middlePoint, firstPoint, vector1);
+       
        for(int i = start; i < end; i+=increment){
                points->GetPoint(i, currPoint);
-               if(samePoint && (currPoint[0] != prevPoint[0] || currPoint[1] != prevPoint[1] || currPoint[2] != prevPoint[2])){
+               if(samePoint && i > start && (currPoint[0] != prevPoint[0] || currPoint[1] != prevPoint[1] || currPoint[2] != prevPoint[2])){
                        samePoint = false;
                }
+
+               vtkMath::Subtract(currPoint, firstPoint, vector2);
+               double angle = vtkMath::AngleBetweenVectors(vector1, vector2);
+               if(angle > 0.0001 && collinear){
+                       collinear = false;
+               }
+               
                centroid[0] += currPoint[0];
                centroid[1] += currPoint[1];
                centroid[2] += currPoint[2];
                std::copy(std::begin(currPoint), std::end(currPoint), prevPoint);
        }
+       
        centroid[0] /= numPoints;
        centroid[1] /= numPoints;
        centroid[2] /= numPoints;
        
-       return !samePoint;
+       return !samePoint && !collinear;
 }
 
 /**
@@ -325,7 +342,6 @@ void CreateMeshFromPoints::bbUserSetDefaultValues()
 //    Here we initialize the input 'In' to 0
 //   bbSetInputIn(0);
        bbSetInputCloseSurface(false);
-       bbSetInputOpenClose(false);
        points          = NULL;
        cells           = NULL;
        polydata        = NULL;
index f67c312e61cd365e1610672f5e63d8055604a1d9..5d5ed25508c813bfbd71533b219cfec2237b781c 100644 (file)
@@ -30,7 +30,6 @@ class bbcreaVtk_EXPORT CreateMeshFromPoints
   BBTK_DECLARE_INPUT(LstY,std::vector<double>);
   BBTK_DECLARE_INPUT(LstZ,std::vector<double>);
   BBTK_DECLARE_INPUT(LstIndexs,std::vector<int>);
-  BBTK_DECLARE_INPUT(OpenClose, bool);
   BBTK_DECLARE_INPUT(CloseSurface, bool);
   BBTK_DECLARE_OUTPUT(Out,vtkPolyData*);
   BBTK_PROCESS(Process);
@@ -64,7 +63,6 @@ BBTK_BEGIN_DESCRIBE_BLACK_BOX(CreateMeshFromPoints,bbtk::AtomicBlackBox);
   BBTK_INPUT(CreateMeshFromPoints,LstY,"List Y point",std::vector<double>,"");
   BBTK_INPUT(CreateMeshFromPoints,LstZ,"List Z point",std::vector<double>,"");
   BBTK_INPUT(CreateMeshFromPoints,LstIndexs,"Number of points by segment",std::vector<int>,"");
-  BBTK_INPUT(CreateMeshFromPoints,OpenClose,"(default false) Type of Contour: false=Open, true=Close",bool,"");
   BBTK_INPUT(CreateMeshFromPoints,CloseSurface,"(default false) Add the caps to close the surface",bool,"");
 
   BBTK_OUTPUT(CreateMeshFromPoints,Out,"vtkPolyData",vtkPolyData*,"");