7 #define _USE_MATH_DEFINES 9 #include "../../include/eigen/Eigen/Dense" 29 map<pair<int, int>,
int> pondOfUndeterminedEdges;
31 for (
int i = 0; i < szFaces; ++i)
34 for (
int j = 0; j < 3; ++j)
36 int post = (j + 1) % 3;
37 int pre = (j + 2) % 3;
39 int leftVert =
Face(i)[pre];
40 int rightVert =
Face(i)[j];
42 map<pair<int, int>,
int>::const_iterator it = pondOfUndeterminedEdges.find(make_pair(leftVert, rightVert));
43 if (it != pondOfUndeterminedEdges.end())
45 int posInEdgeList = it->second;
46 if (
m_Edges[posInEdgeList].indexOfOppositeVert != -1)
48 throw "Repeated edges!";
50 threeIndices[j] = posInEdgeList;
51 m_Edges[posInEdgeList].indexOfOppositeVert =
Face(i)[post];
52 m_Edges[posInEdgeList].indexOfFrontFace = i;
64 pondOfUndeterminedEdges[make_pair(leftVert, rightVert)] = threeIndices[j] = (int)
m_Edges.size() - 1;
72 pondOfUndeterminedEdges[make_pair(rightVert, leftVert)] = (int)
m_Edges.size() - 1;
75 for (
int j = 0; j < 3; ++j)
99 if (indexOfStartEdge == -1 || !
IsStartEdge(indexOfStartEdge))
101 indexOfStartEdge = i;
116 vector<int> startEdges;
117 for (
int j = 0; j < (int)
Neigh(i).size(); ++j)
119 startEdges.push_back(
Neigh(i)[j].first);
123 for (
int j = 0; j < (int)startEdges.size(); ++j)
125 int curEdge = startEdges[j];
130 if (num >= sequenceOfDegrees[i])
135 if (curEdge == startEdges[j])
141 if (num != sequenceOfDegrees[i])
143 throw "Complex vertices";
192 double squareOfLeftLen = leftLen * leftLen;
194 double x = (squareOfLeftLen - rightLen * rightLen) / bottom + bottom;
196 m_Edges[i].coordOfOppositeVert = make_pair(x,
sqrt(
max(0.0, squareOfLeftLen - x * x)));
203 int reverseEdge =
m_Edges[
m_Edges[i].indexOfLeftEdge].indexOfReverseEdge;
205 double scale =
abs(coord.first) +
abs(coord.second);
206 coord.first /= scale;
207 coord.second /= scale;
208 double len =
sqrt(coord.first * coord.first + coord.second * coord.second);
209 m_Edges[i].matrixRotatedToLeftEdge = make_pair(coord.first / len, coord.second / len);
212 int reverseEdge =
m_Edges[
m_Edges[i].indexOfRightEdge].indexOfReverseEdge;
213 double rightX =
m_Edges[reverseEdge].length;
215 double leftX =
m_Edges[reverseEdge].length -
m_Edges[reverseEdge].coordOfOppositeVert.first;
216 double leftY = -
m_Edges[reverseEdge].coordOfOppositeVert.second;
218 double detaX = rightX - leftX;
219 double detaY = rightY - leftY;
220 double scale =
abs(detaX) +
abs(detaY);
223 double len =
sqrt(detaX * detaX + detaY * detaY);
224 m_Edges[i].matrixRotatedToRightEdge = make_pair(detaX / len, detaY / len);
310 set<int> extremeEdges;
311 for (
int i = 0; i < (int)
m_Edges.size(); ++i)
313 if (
m_Edges[i].indexOfOppositeVert != -1)
315 extremeEdges.insert(i);
318 while (!extremeEdges.empty())
321 int firstEdge = *extremeEdges.begin();
322 int edge = firstEdge;
325 extremeEdges.erase(edge);
328 edge =
Neigh(root)[(index - 1 + (int)
Neigh(root).size()) % (
int)
Neigh(root).size()].first;
329 }
while (edge != firstEdge && !extremeEdges.empty());
341 for (
int i = 0; i < (int)flags.size(); ++i)
359 for (
int i = 0; i < (int)
Neigh(v).size(); ++i)
363 Que.push(
Edge(
Neigh(v)[i].first).indexOfRightVert);
373 out <<
"Model info is as follows.\n";
378 out <<
"Scale = " <<
m_scale << endl;
383 out <<
"It is a closed model.\n";
385 out <<
"It is an open model.\n";
394 m_Edges[edgeID].length = newLength;
395 m_Edges[reverseID].length = newLength;
414 return make_pair(splitAngles.second, splitAngles.first);
435 double rightAngleSum(0);
436 double leftAngleSum(0);
442 while (index != index2)
444 rightAngleSum +=
Neigh(root)[index].second;
445 index = (index + 1) %
Neigh(root).size();
448 leftAngleSum =
Neigh(root)[index].second;
449 index = (index + 1) %
Neigh(root).size();
450 while (index != index1)
452 leftAngleSum +=
Neigh(root)[index].second;
453 index = (index + 1) %
Neigh(root).size();
461 while (index != index2)
463 rightAngleSum +=
Neigh(root)[index].second;
464 index = (index + 1) %
Neigh(root).size();
468 while (index != index1)
470 leftAngleSum +=
Neigh(root)[index].second;
471 index = (index + 1) %
Neigh(root).size();
480 rightAngleSum += leftAngle2;
481 leftAngleSum += rightAngle2;
489 double b =
sqrt(detaX * detaX + detaY * detaY);
490 double leftAngle2 =
acos((a * a + b * b - c * c)/(2.0 * a * b));
492 rightAngleSum += leftAngle2;
493 leftAngleSum += rightAngle2;
503 if (index1 == index3)
506 for (
int i = 0; i <
Neigh(root).size(); ++i)
507 angleSum +=
Neigh(root)[i].second;
514 rightAngleSum = angleSum - leftAngleSum;
519 leftAngleSum = angleSum - rightAngleSum;
527 double a =
sqrt(detaX1 * detaX1 + detaY1 * detaY1);
530 double b =
sqrt(detaX2 * detaX2 + detaY2 * detaY2);
531 leftAngleSum =
acos((a * a + b * b - c * c)/(2 * a * b));
532 rightAngleSum = angleSum - leftAngleSum;
539 double a =
sqrt(detaX1 * detaX1 + detaY1 * detaY1);
542 double b =
sqrt(detaX2 * detaX2 + detaY2 * detaY2);
543 rightAngleSum =
acos((a * a + b * b - c * c)/(2 * a * b));
544 leftAngleSum = angleSum - rightAngleSum;
549 double leftAngle1, rightAngle1, leftAngle2, rightAngle2;
563 double b =
sqrt(detaX * detaX + detaY * detaY);
564 leftAngle1 =
acos((a * a + b * b - c * c)/(2.0 * a * b));
580 double b =
sqrt(detaX * detaX + detaY * detaY);
581 leftAngle2 =
acos((a * a + b * b - c * c)/(2.0 * a * b));
584 leftAngleSum = leftAngle1 + rightAngle2;
585 rightAngleSum = rightAngle1 + leftAngle2;
587 while (index != index3)
589 rightAngleSum +=
Neigh(root)[index].second;
590 index = (index + 1) %
Neigh(root).size();
593 while (index != index1)
595 leftAngleSum +=
Neigh(root)[index].second;
596 index = (index + 1) %
Neigh(root).size();
600 return make_pair(leftAngleSum, rightAngleSum);
606 return (
int)
m_Faces.size() * 3;
611 return (
int)
m_Edges.size() / 2;
687 double res = x1 * y2 - x2 * y1;
688 return res / ((y2 - y1) *
Edge(edgeIndex).
length);
693 double xBalance = proportion *
Edge(edgeIndex).
length;
695 return xBalance * coord.second / res;
700 double part1 =
Edge(edgeIndex).
length * coord.second;
703 return (part3 + proportion * part1 - part2) / (part3 + part1 - part2);
708 return make_pair(
Edge(edgeIndex).matrixRotatedToLeftEdge.first * input2DCoordinates.first -
Edge(edgeIndex).matrixRotatedToLeftEdge.second * input2DCoordinates.second,
709 Edge(edgeIndex).matrixRotatedToLeftEdge.second * input2DCoordinates.first +
Edge(edgeIndex).matrixRotatedToLeftEdge.first * input2DCoordinates.second);
716 return make_pair(
Edge(edgeIndex).matrixRotatedToRightEdge.first * input2DCoordinates.first -
Edge(edgeIndex).matrixRotatedToRightEdge.second * input2DCoordinates.second + coordOfLeftEnd.first,
717 Edge(edgeIndex).matrixRotatedToRightEdge.second * input2DCoordinates.first +
Edge(edgeIndex).matrixRotatedToRightEdge.first * input2DCoordinates.second + coordOfLeftEnd.second);
722 return make_pair(
Edge(edgeIndex).length - input2DCoordinates.first, - input2DCoordinates.second);
727 for (
int i = 0; i < (int)
Neigh(root).size(); ++i)
739 return sqrt(detaX * detaX + detaY * detaY);
744 double detaX = coord.first;
745 double detaY = coord.second;
746 return sqrt(detaX * detaX + detaY * detaY);
751 double detaX = coord.first -
Edge(edgeIndex).
length;
752 double detaY = coord.second;
753 return sqrt(detaX * detaX + detaY * detaY);
759 assert (subIndex != -1);
760 return Neigh(leftVert)[subIndex].first;
768 int vertID =
m_Verts.size() - 1;
769 int edgeIndex = ep.
index;
772 if (reverseFaceIndex != -1)
776 if (reverseFaceIndex != -1)
779 int f1 = (int)
m_Faces.size() - 1;
781 int f2 = (int)
m_Faces.size() - 1;
782 if (reverseFaceIndex != -1)
784 int f3 = (int)
m_Faces.size() - 1;
785 if (reverseFaceIndex != -1)
787 int f4 = (int)
m_Faces.size() - 1;
788 if (reverseFaceIndex == -1)
791 int e1 = (int)
m_Edges.size() - 1;
793 int e2 = (int)
m_Edges.size() - 1;
795 int e3 = (int)
m_Edges.size() - 1;
797 int e4 = (int)
m_Edges.size() - 1;
799 int e5 = (int)
m_Edges.size() - 1;
800 if (reverseFaceIndex != -1)
802 int e6 = (int)
m_Edges.size() - 1;
803 if (reverseFaceIndex != -1)
805 int e7 = (int)
m_Edges.size() - 1;
807 int e8 = (int)
m_Edges.size() - 1;
808 if (reverseFaceIndex == -1)
811 m_Edges[e1].indexOfFrontFace = f1;
814 m_Edges[e1].indexOfOppositeVert =
m_Edges[edgeIndex].indexOfOppositeVert;
815 m_Edges[e1].indexOfReverseEdge = e8;
816 m_Edges[e1].indexOfRightEdge = e3;
817 m_Edges[e1].indexOfRightVert = vertID;
819 m_Edges[e4].indexOfFrontFace = f2;
820 m_Edges[e4].indexOfLeftEdge = e2;
821 m_Edges[e4].indexOfLeftVert = vertID;
822 m_Edges[e4].indexOfOppositeVert =
m_Edges[edgeIndex].indexOfOppositeVert;
823 m_Edges[e4].indexOfReverseEdge = e5;
824 m_Edges[e4].indexOfRightEdge =
m_Edges[edgeIndex].indexOfRightEdge;
825 m_Edges[e4].indexOfRightVert =
m_Edges[edgeIndex].indexOfRightVert;
827 m_Edges[e5].indexOfFrontFace = f3;
830 m_Edges[e5].indexOfOppositeVert =
m_Edges[
m_Edges[edgeIndex].indexOfReverseEdge].indexOfOppositeVert;
831 m_Edges[e5].indexOfReverseEdge = e4;
832 m_Edges[e5].indexOfRightEdge = e7;
833 m_Edges[e5].indexOfRightVert = vertID;
835 m_Edges[e8].indexOfFrontFace = f4;
836 m_Edges[e8].indexOfLeftEdge = e6;
837 m_Edges[e8].indexOfLeftVert = vertID;
838 m_Edges[e8].indexOfOppositeVert =
m_Edges[
m_Edges[edgeIndex].indexOfReverseEdge].indexOfOppositeVert;
839 m_Edges[e8].indexOfReverseEdge = e1;
843 m_Edges[e2].indexOfFrontFace = f1;
847 m_Edges[e2].indexOfReverseEdge = e3;
851 m_Edges[e3].indexOfFrontFace = f2;
855 m_Edges[e3].indexOfReverseEdge = e2;
859 if (reverseFaceIndex != -1)
861 m_Edges[e6].indexOfFrontFace = f3;
865 m_Edges[e6].indexOfReverseEdge = e7;
869 m_Edges[e7].indexOfFrontFace = f4;
873 m_Edges[e7].indexOfReverseEdge = e6;
878 if (reverseFaceIndex == -1)
885 int leftEdge =
m_Edges[
m_Edges[e1].indexOfLeftEdge].indexOfReverseEdge;
886 m_Edges[leftEdge].indexOfFrontFace = f1;
887 m_Edges[leftEdge].indexOfLeftEdge = e3;
888 m_Edges[leftEdge].indexOfLeftVert;
889 m_Edges[leftEdge].indexOfOppositeVert =
m_Edges[e1].indexOfRightVert;
890 m_Edges[leftEdge].indexOfReverseEdge;
891 m_Edges[leftEdge].indexOfRightEdge =
m_Edges[e1].indexOfReverseEdge;
892 m_Edges[leftEdge].indexOfRightVert;
894 int rightEdge =
m_Edges[
m_Edges[e4].indexOfRightEdge].indexOfReverseEdge;
895 m_Edges[rightEdge].indexOfFrontFace = f2;
896 m_Edges[rightEdge].indexOfLeftEdge =
m_Edges[e4].indexOfReverseEdge;
897 m_Edges[rightEdge].indexOfLeftVert;
898 m_Edges[rightEdge].indexOfOppositeVert =
m_Edges[e4].indexOfLeftVert;
899 m_Edges[rightEdge].indexOfReverseEdge;
900 m_Edges[rightEdge].indexOfRightEdge = e2;
901 m_Edges[rightEdge].indexOfRightVert;
903 if (reverseFaceIndex != -1)
905 leftEdge =
m_Edges[
m_Edges[e5].indexOfLeftEdge].indexOfReverseEdge;
906 m_Edges[leftEdge].indexOfFrontFace = f3;
907 m_Edges[leftEdge].indexOfLeftEdge = e7;
908 m_Edges[leftEdge].indexOfLeftVert;
909 m_Edges[leftEdge].indexOfOppositeVert =
m_Edges[e5].indexOfRightVert;
910 m_Edges[leftEdge].indexOfReverseEdge;
911 m_Edges[leftEdge].indexOfRightEdge =
m_Edges[e5].indexOfReverseEdge;
912 m_Edges[leftEdge].indexOfRightVert;
914 rightEdge =
m_Edges[
m_Edges[e8].indexOfRightEdge].indexOfReverseEdge;
915 m_Edges[rightEdge].indexOfFrontFace = f4;
916 m_Edges[rightEdge].indexOfLeftEdge =
m_Edges[e8].indexOfReverseEdge;
917 m_Edges[rightEdge].indexOfLeftVert;
918 m_Edges[rightEdge].indexOfOppositeVert =
m_Edges[e8].indexOfLeftVert;
919 m_Edges[rightEdge].indexOfReverseEdge;
920 m_Edges[rightEdge].indexOfRightEdge = e6;
921 m_Edges[rightEdge].indexOfRightVert;
928 ofstream out(filename.c_str());
931 out <<
"g " << filename.substr(filename.rfind(
"\\") + 1, filename.rfind(
'.') - filename.rfind(
"\\") - 1) << endl;
934 for (
int i = 0; i < pl.size(); ++i)
936 CPoint3D pt = pl[i].GetShiftPoint(*
this);
937 out <<
"v " << pt.
x <<
" " << pt.
y <<
" " << pt.
z << endl;
941 for (
int i = 0; i < pl.size(); ++i)
974 ofstream out(filename.c_str());
975 out <<
"g " << filename.substr(filename.rfind(
"\\") + 1, filename.rfind(
'.') - filename.rfind(
"\\") - 1) << endl;
976 if (!isoline.empty())
978 for (
int i = 0; i < isoline.size(); ++i)
980 CPoint3D pt = isoline[i].GetShiftPoint(*
this);
981 out <<
"v " << pt.
x <<
" " << pt.
y <<
" " << pt.
z << endl;
984 for (
int i = 0; i < isoline.size() / 2; ++i)
986 out <<
"l " << i * 2 + 1 <<
" " << 2 * i + 2 << endl;
994 const string& fileWithLargerScalars,
995 const string& fileWithSmallerScalars)
997 vector<EdgePoint> eps;
1008 if (prop < 1e-4 || prop > 1 - 1e-4)
1013 for (
int i = 0; i < eps.size(); ++i)
1016 ofstream outLarge(fileWithLargerScalars.c_str());
1017 ofstream outSmall(fileWithSmallerScalars.c_str());
1020 outLarge <<
"v " <<
Vert(i).
x 1022 <<
" " <<
Vert(i).
z << endl;
1023 outSmall <<
"v " <<
Vert(i).
x 1025 <<
" " <<
Vert(i).
z << endl;
1032 int v1 =
Face(i)[0];
1033 int v2 =
Face(i)[1];
1034 int v3 =
Face(i)[2];
1037 if (v1 < oldVertNum)
1039 average += scalarField[v1];
1042 if (v2 < oldVertNum)
1044 average += scalarField[v2];
1047 if (v3 < oldVertNum)
1049 average += scalarField[v3];
1055 outSmall <<
"f " <<
Face(i)[0] + 1 <<
" " <<
Face(i)[1] + 1 <<
" " <<
Face(i)[2] + 1 << endl;
1059 outLarge <<
"f " <<
Face(i)[0] + 1 <<
" " <<
Face(i)[1] + 1 <<
" " <<
Face(i)[2] + 1 << endl;
1069 set<pair<double, string>> sortingSet;
1070 sortingSet.insert(make_pair(seg1.first.GetNumbering(*
this, faceID),
"seg1"));
1071 sortingSet.insert(make_pair(seg1.second.GetNumbering(*
this, faceID),
"seg1"));
1072 sortingSet.insert(make_pair(seg2.first.GetNumbering(*
this, faceID),
"seg2"));
1073 sortingSet.insert(make_pair(seg2.second.GetNumbering(*
this, faceID),
"seg2"));
1074 vector<pair<double, string>> sortingVec(sortingSet.begin(), sortingSet.end());
1075 for (
int i = 0; i < 4; ++i)
1077 int nxt = (i + 1) % 4;
1078 if (sortingVec[i].first == sortingVec[nxt].first
1079 && sortingVec[i].second != sortingVec[nxt].second)
1081 if (seg1.first == seg2.first || seg1.first == seg2.second)
1082 intersection = seg1.first;
1084 intersection = seg1.second;
1088 for (
int i = 0; i < 4; ++i)
1090 int nxt = (i + 1) % 4;
1091 if (sortingVec[i].second == sortingVec[nxt].second)
1124 Eigen::MatrixXd M(4, 3);
1129 Eigen::VectorXd right(4);
1130 right << pt.
x, pt.
y, pt.
z, 1;
1131 auto M_trans = M.transpose();
1140 right = M_trans * right;
1153 Eigen::Vector3d res = M.inverse() * right;
1156 return CPoint3D(res(0), res(1), res(2));
int GetNumOfValidDirectedEdges() const
void FinishChangingEdgeLengths()
void ComputePlanarCoordsOfIncidentVertForEdges()
void PreprocessBaseModel()
vector< CPoint3D > m_Verts
string GetFileShortName() const
bool IsStartEdge(int edgeIndex) const
pair< double, double > GetTwoSplitAngles(int root, EdgePoint pt1, EdgePoint pt2) const
int GetNumOfFaces() const
pair< double, double > GetNew2DCoordinatesByRotatingAroundLeftChildEdge(int edgeIndex, const pair< double, double > &input2DCoordinates) const
void ComputeNumOfComponents()
void ComputeAnglesAroundVerts()
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
int SplitEdge(const EdgePoint &ep)
void SaveIsolineToObj(const vector< EdgePoint > &isoline, const string &filename) const
double DistanceToRightVert(int edgeIndex, const pair< double, double > &coord) const
double DistanceToOppositeAngle(int edgeIndex, const pair< double, double > &coord) const
int IntersectQuery(int faceID, const pair< EdgePoint, EdgePoint > &seg1, const pair< EdgePoint, EdgePoint > &seg2, EdgePoint &intersection) const
double ProportionOnLeftEdgeByImage(int edgeIndex, const pair< double, double > &coord, double proportion) const
double DistanceToLeftVert(int edgeIndex, const pair< double, double > &coord) const
pair< double, double > coordOfOppositeVert
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
const CEdge & Edge(int edgeIndex) const
int GetEdgeIndexFromTwoVertices(int leftVert, int rightVert) const
CPoint3D GetBarycentricCoord(CPoint3D pt, int faceID) const
double ProportionOnRightEdgeByImage(int edgeIndex, const pair< double, double > &coord, double proportion) const
bool IsWeaklyConvexVert(int index) const
int GetSubindexToVert(int root, int neigh) const
double AngleSum(int vertIndex) const
pair< double, double > GetNew2DCoordinatesByRotatingAroundRightChildEdge(int edgeIndex, const pair< double, double > &input2DCoordinates) const
int GetNumOfBoundries() const
void SetEdgeLength(int leftVert, int rightVert, double newLength)
double ProportionOnEdgeByImage(int edgeIndex, const pair< double, double > &coord) const
int GetNumOfComponents() const
int GetNumOfTotalUndirectedEdges() const
bool IsExtremeEdge(int edgeIndex) const
void SplitBasedOnScalarField(const vector< double > &scalarField, double val, const string &fileWithLargerScalars, const string &fileWithSmallerScalars)
const vector< pair< int, double > > & Neigh(int root) const
vector< pair< bool, bool > > m_FlagsForCheckingConvexVerts
EIGEN_DEVICE_FUNC const AcosReturnType acos() const
int GetNumOfVerts() const
bool isBoundaryVert(int index) const
bool IsStronglyConvexVert(int index) const
int GetNumOfIsolated() const
bool IsClosedModel() const
int64_t max(int64_t a, const int b)
void CollectAndArrangeNeighs()
vector< vector< pair< int, double > > > m_NeighsAndAngles
const CPoint3D & Vert(int vertIndex) const
pair< double, double > GetNew2DCoordinatesByReversingCurrentEdge(int edgeIndex, const pair< double, double > &input2DCoordinates) const
int GetNumOfGenera() const
void SavePathToObj(const vector< EdgePoint > &pl, const string &filename) const
const CFace & Face(int faceIndex) const
set< int > m_UselessFaces
void CreateEdgesFromVertsAndFaces()
int GetNumOfEdges() const
set< int > m_UselessEdges
CRichModel(const string &filename)
const double AngleTolerance
double GetMaxEdgeLength() const
void PrintInfo(ostream &out) const