From: Pablo Garzon Date: Fri, 24 Mar 2023 10:41:45 +0000 (+0100) Subject: #3502 Bug close surface in CreateMeshFromPoints X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=480c35b0a2e635921565e4c08fb9f187188f78ff;p=creaVtk.git #3502 Bug close surface in CreateMeshFromPoints --- diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.cxx b/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.cxx index 69aab08..463e632 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.cxx +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.cxx @@ -39,7 +39,7 @@ void CreateMeshFromPoints::Process() std::vector 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 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 triangleStrip1 = vtkSmartPointer::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 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 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 lstIndexs){ * False = invalid centroid = all points are the same. */ bool CreateMeshFromPoints::CalcValidCentroid(double(¢roid)[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; diff --git a/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.h b/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.h index f67c312..5d5ed25 100644 --- a/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.h +++ b/bbtk_creaVtk_PKG/src/bbcreaVtkCreateMeshFromPoints.h @@ -30,7 +30,6 @@ class bbcreaVtk_EXPORT CreateMeshFromPoints BBTK_DECLARE_INPUT(LstY,std::vector); BBTK_DECLARE_INPUT(LstZ,std::vector); BBTK_DECLARE_INPUT(LstIndexs,std::vector); - 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,""); BBTK_INPUT(CreateMeshFromPoints,LstZ,"List Z point",std::vector,""); BBTK_INPUT(CreateMeshFromPoints,LstIndexs,"Number of points by segment",std::vector,""); - 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*,"");