+
+/**
+* Checks if the order of the points represent a curved spline (U shape) or the points resemble a straight spline.
+* Now it checks the angle between each point and the vector that goes from the last point to the first.
+*
+* Previous version checked the curvature between 3 points in the spline, but this created problems when the straight lines
+* had curves in the middle, increasing the curvature although they are not in the U shape.
+*/
+bool CreateMeshFromPoints::CheckLinePointOrder(){
+ int sizePoints = bbGetInputLstX().size();
+ std::vector<int> lstIndexs = bbGetInputLstIndexs();
+ double point1[3], point2[3], point3[3];
+ double center[3];
+ double firstAngleSum = 0;
+ double secondAngleSum = 0;
+
+ points->GetPoint(0, point1);
+ points->GetPoint((lstIndexs[0]-1), point3);
+ double firstVect[3];
+ double secVect[3];
+ vtkMath::Subtract(point3, point1, firstVect);
+ for(int i = 0; i < lstIndexs[0]; i++){
+ points->GetPoint(i, point2);
+ vtkMath::Subtract(point2, point1, secVect);
+ firstAngleSum += vtkMath::SignedAngleBetweenVectors(firstVect, secVect, firstVect);
+ }
+ points->GetPoint((sizePoints-lstIndexs[0]), point3);
+ vtkMath::Subtract(point3, point1, firstVect);
+ for(int i = 0; i < sizePoints; i+=lstIndexs.size()){
+ points->GetPoint(i, point2);
+ vtkMath::Subtract(point2, point1, secVect);
+ secondAngleSum += vtkMath::SignedAngleBetweenVectors(firstVect, secVect, firstVect);
+ }
+
+ return firstAngleSum < secondAngleSum;
+}
+
+/**
+* Closes an open contour
+* lstIndexs: number of points on each spline
+*/
+void CreateMeshFromPoints::CloseOpenContourSurface(std::vector<int> lstIndexs){
+ bool linePointOrder = CheckLinePointOrder();
+ CloseContourSides(lstIndexs, !linePointOrder, false);
+ CloseContourBottom(!linePointOrder);
+}
+
+/**
+* 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
+* increment: increment to be used in point iteration
+* numPoints: number of points used to calculate the centroid.
+* Returns a bool indicating the validity of the centroid calculated.
+* 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] = {}, 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 && 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 && !collinear;
+}
+
+/**
+* Closes the bottom of the given countour.
+* Should only be used when its an open contour.
+* uPointOrder: points are ordered in U shape
+*/
+void CreateMeshFromPoints::CloseContourBottom(bool uPointOrder){
+ std::vector<int> lstIndexs = bbGetInputLstIndexs();
+ int sizeLstIdexes = lstIndexs.size();
+ int sizeLstX = bbGetInputLstX().size();
+
+ vtkSmartPointer<vtkTriangleStrip> triangleStripBottom = vtkSmartPointer<vtkTriangleStrip>::New();
+ triangleStripBottom->GetPointIds()->SetNumberOfIds(sizeLstIdexes*2);
+
+ double originPoint[3];
+ points->GetPoint(0, originPoint);
+ int middleMeshPoint = uPointOrder?lstIndexs[0]/2:lstIndexs[0]*sizeLstIdexes/2;
+
+ bool normalOrder = isPointingCorrectly(uPointOrder?lstIndexs[0]-1:sizeLstX-lstIndexs[0], uPointOrder?lstIndexs[0]:1, originPoint, middleMeshPoint);
+
+ int triangleIndex = 0, currentId = 0, nextId = 0;
+ for(int splineIndex = 0; splineIndex < sizeLstIdexes;splineIndex++){
+ nextId = uPointOrder?currentId + lstIndexs[splineIndex] - 1:sizeLstX - sizeLstIdexes + splineIndex;
+ if(normalOrder)
+ {
+ triangleStripBottom->GetPointIds()->SetId(triangleIndex, currentId);
+ triangleStripBottom->GetPointIds()->SetId(triangleIndex+1, nextId);
+ }
+ else{
+ triangleStripBottom->GetPointIds()->SetId(triangleIndex, nextId);
+ triangleStripBottom->GetPointIds()->SetId(triangleIndex+1, currentId);
+ }
+ currentId = uPointOrder?nextId + 1: splineIndex+1;
+ triangleIndex+=2;
+ }
+ cells->InsertNextCell(triangleStripBottom);
+}
+