+
+/**
+* Checks if points on each side of the shapes represent a curve.
+*/
+bool CreateMeshFromPoints::CheckLinePointOrder(){
+ int sizePoints = bbGetInputLstX().size();
+ std::vector<int> lstIndexs = bbGetInputLstIndexs();
+ double point1[3], point2[3], point3[3];
+ double center[3];
+ double firstRadiusSum = 0;
+ double secondRadiusSum = 0;
+ for(int i = 0; i < lstIndexs[0] && lstIndexs[0] > 9; i+=5){
+ if(i+10 < lstIndexs[0]){
+ points->GetPoint(i, point1);
+ points->GetPoint(i+5, point2);
+ points->GetPoint(i+10, point3);
+ firstRadiusSum += vtkMath::Solve3PointCircle(point1, point2, point3, center);
+ }
+ }
+
+ for(int i = 0; i < sizePoints && lstIndexs.size() > 9; i+=(lstIndexs.size()*5)){
+ if(i+(10*lstIndexs.size()) < sizePoints){
+ points->GetPoint(i, point1);
+ points->GetPoint(i+(5*lstIndexs.size()), point2);
+ points->GetPoint(i+(10*lstIndexs.size()), point3);
+ secondRadiusSum += vtkMath::Solve3PointCircle(point1, point2, point3, center);
+ }
+ }
+
+ return firstRadiusSum > secondRadiusSum;
+}
+
+/**
+* Closes an open contour
+* lstIndexs: number of points on each spline
+*/
+void CreateMeshFromPoints::CloseOpenContourSurface(std::vector<int> lstIndexs){
+ bool linePointOrder = CheckLinePointOrder();
+ CloseContourSides(lstIndexs, !linePointOrder);
+ 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);
+ int triangleIndex = 0, currentId = 0, nextId = 0;
+ for(int splineIndex = 0; splineIndex < sizeLstIdexes;splineIndex++){
+ triangleStripBottom->GetPointIds()->SetId(triangleIndex, currentId);
+ nextId = uPointOrder?currentId + lstIndexs[splineIndex] - 1:sizeLstX - sizeLstIdexes + splineIndex;
+ triangleStripBottom->GetPointIds()->SetId(triangleIndex+1, nextId);
+ triangleIndex+=2;
+ currentId = uPointOrder?nextId + 1: splineIndex+1;
+ }
+ cells->InsertNextCell(triangleStripBottom);
+}
+