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