RichModel.cpp
Go to the documentation of this file.
1 #include "RichModel.h"
2 #include "EdgePoint.h"
3 #include <queue>
4 #include <cassert>
5 #include <math.h>
6 #include <iostream>
7 #define _USE_MATH_DEFINES
8 #include "Parameters.h"
9 #include "../../include/eigen/Eigen/Dense"
10 //#include <Windows.h>
11 using namespace std;
12 
13 
14 CRichModel::CRichModel(const string& filename) : CBaseModel(filename)
15 {
16 }
17 
18 CRichModel::CRichModel(const vector<CPoint3D> &verts, const vector<CBaseModel::CFace> &faces) : CBaseModel("")
19 {
20  m_Verts = verts;
21  m_Faces = faces;
23 }
24 
26 {
27  m_Edges.clear();
28  m_Edges.reserve(2 * (GetNumOfVerts() + GetNumOfFaces() - 2));
29  map<pair<int, int>, int> pondOfUndeterminedEdges;
30  int szFaces = GetNumOfFaces();
31  for (int i = 0; i < szFaces; ++i)
32  {
33  int threeIndices[3];
34  for (int j = 0; j < 3; ++j)
35  {
36  int post = (j + 1) % 3;
37  int pre = (j + 2) % 3;
38 
39  int leftVert = Face(i)[pre];
40  int rightVert = Face(i)[j];
41 
42  map<pair<int, int>, int>::const_iterator it = pondOfUndeterminedEdges.find(make_pair(leftVert, rightVert));
43  if (it != pondOfUndeterminedEdges.end())
44  {
45  int posInEdgeList = it->second;
46  if (m_Edges[posInEdgeList].indexOfOppositeVert != -1)
47  {
48  throw "Repeated edges!";
49  }
50  threeIndices[j] = posInEdgeList;
51  m_Edges[posInEdgeList].indexOfOppositeVert = Face(i)[post];
52  m_Edges[posInEdgeList].indexOfFrontFace = i;
53  }
54  else
55  {
56  CEdge edge;
57  edge.indexOfLeftVert = leftVert;
58  edge.indexOfRightVert = rightVert;
59  edge.indexOfFrontFace = i;
60  edge.indexOfOppositeVert = Face(i)[post];
61  edge.indexOfReverseEdge = (int)m_Edges.size() + 1;
62  edge.length = (Vert(leftVert) - Vert(rightVert)).Len();
63  m_Edges.push_back(edge);
64  pondOfUndeterminedEdges[make_pair(leftVert, rightVert)] = threeIndices[j] = (int)m_Edges.size() - 1;
65 
66  edge.indexOfLeftVert = rightVert;
67  edge.indexOfRightVert = leftVert;
68  edge.indexOfReverseEdge = (int)m_Edges.size() - 1;
69  edge.indexOfOppositeVert = -1;
70  edge.indexOfFrontFace = -1;
71  m_Edges.push_back(edge);
72  pondOfUndeterminedEdges[make_pair(rightVert, leftVert)] = (int)m_Edges.size() - 1;
73  }
74  }
75  for (int j = 0; j < 3; ++j)
76  {
77  m_Edges[threeIndices[j]].indexOfLeftEdge = Edge(threeIndices[(j + 2) % 3]).indexOfReverseEdge;
78  m_Edges[threeIndices[j]].indexOfRightEdge = Edge(threeIndices[(j + 1) % 3]).indexOfReverseEdge;
79  }
80  }
81  //m_Edges.swap(vector<CEdge>(m_Edges)); // dsy: comment out origin code.
82 }
83 
85 {
86  m_nIsolatedVerts = 0;
87  vector<int> sequenceOfDegrees(GetNumOfVerts(), 0);
88  m_NeighsAndAngles.clear();
90  for (int i = 0; i < (int)m_NeighsAndAngles.size(); ++i)
91  {
92  m_NeighsAndAngles[i].resize(1, make_pair(-1, 0));
93  }
94  for (int i = 0; i < (int)GetNumOfEdges(); ++i)
95  {
96  const CEdge& edge = Edge(i);
97  ++sequenceOfDegrees[edge.indexOfLeftVert];
98  int &indexOfStartEdge = m_NeighsAndAngles[edge.indexOfLeftVert][0].first;
99  if (indexOfStartEdge == -1 || !IsStartEdge(indexOfStartEdge))
100  {
101  indexOfStartEdge = i;
102  }
103  else if (IsStartEdge(i))
104  {
105  m_NeighsAndAngles[edge.indexOfLeftVert].push_back(make_pair(i, 0));
106  }
107  }
108  for (int i = 0; i < GetNumOfVerts(); ++i)
109  {
110  if (m_NeighsAndAngles[i][0].first == -1)
111  {
112  m_NeighsAndAngles[i].clear();
113  m_nIsolatedVerts++;
114  continue;
115  }
116  vector<int> startEdges;
117  for (int j = 0; j < (int)Neigh(i).size(); ++j)
118  {
119  startEdges.push_back(Neigh(i)[j].first);
120  }
121  m_NeighsAndAngles[i].resize(sequenceOfDegrees[i], make_pair(0, 0));
122  int num(0);
123  for (int j = 0; j < (int)startEdges.size(); ++j)
124  {
125  int curEdge = startEdges[j];
126  while (1)
127  {
128  m_NeighsAndAngles[i][num].first = curEdge;
129  ++num;
130  if (num >= sequenceOfDegrees[i])
131  break;
132  if (IsExtremeEdge(curEdge))
133  break;
134  curEdge = Edge(curEdge).indexOfLeftEdge;
135  if (curEdge == startEdges[j])
136  {
137  break;
138  }
139  }
140  }
141  if (num != sequenceOfDegrees[i])
142  {
143  throw "Complex vertices";
144  }
145  }
146 }
147 
149 {
152  //for (int i = 0; i < (int)m_NeighsAndAngles.size(); ++i)
153  //{
154  // m_NeighsAndAngles[i].resize(Neigh(i).size());
155  //}
156  for (int i = 0; i < (int)m_NeighsAndAngles.size(); ++i)
157  {
158  double angleSum(0);
159  for (int j = 0; j < (int)m_NeighsAndAngles[i].size(); ++j)
160  {
161  if (IsExtremeEdge(Neigh(i)[j].first))
162  m_NeighsAndAngles[i][j].second = 2 * M_PI + 0.1;
163  else
164  {
165  int next = j + 1;
166  if (next >= (int)m_NeighsAndAngles[i].size())
167  {
168  next = 0;
169  }
170  double l = Edge(Neigh(i)[j].first).length;
171  double r = Edge(Neigh(i)[next].first).length;
172  double b = Edge(Edge(Neigh(i)[j].first).indexOfRightEdge).length;
173  m_NeighsAndAngles[i][j].second = acos((l * l + r * r - b * b) / (2 * l * r));
174  m_Edges[Edge(Edge(Neigh(i)[j].first).indexOfRightEdge).indexOfReverseEdge].angleOpposite = m_NeighsAndAngles[i][j].second;
175  }
176  angleSum += m_NeighsAndAngles[i][j].second;
177  }
178  m_FlagsForCheckingConvexVerts[i].first = (angleSum < 2 * M_PI - 5 * AngleTolerance);
179  m_FlagsForCheckingConvexVerts[i].second = (angleSum < 2 * M_PI + 5 * AngleTolerance);
180  }
181 
182 }
183 
185 {
186  for (int i = 0; i < GetNumOfEdges(); ++i)
187  {
188  if (IsExtremeEdge(i))
189  continue;
190  double bottom = Edge(i).length;
191  double leftLen = Edge(Edge(i).indexOfLeftEdge).length;
192  double squareOfLeftLen = leftLen * leftLen;
193  double rightLen = Edge(Edge(i).indexOfRightEdge).length;
194  double x = (squareOfLeftLen - rightLen * rightLen) / bottom + bottom;
195  x /= 2.0;
196  m_Edges[i].coordOfOppositeVert = make_pair(x, sqrt(max(0.0, squareOfLeftLen - x * x)));
197  }
198  for (int i = 0; i < GetNumOfEdges(); ++i)
199  {
200  if (IsExtremeEdge(i))
201  continue;
202  {
203  int reverseEdge = m_Edges[m_Edges[i].indexOfLeftEdge].indexOfReverseEdge;
204  pair<double, double> coord = GetNew2DCoordinatesByReversingCurrentEdge(reverseEdge, m_Edges[reverseEdge].coordOfOppositeVert);
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);
210  }
211  {
212  int reverseEdge = m_Edges[m_Edges[i].indexOfRightEdge].indexOfReverseEdge;
213  double rightX = m_Edges[reverseEdge].length;
214  double rightY = 0;
215  double leftX = m_Edges[reverseEdge].length - m_Edges[reverseEdge].coordOfOppositeVert.first;
216  double leftY = -m_Edges[reverseEdge].coordOfOppositeVert.second;
217 
218  double detaX = rightX - leftX;
219  double detaY = rightY - leftY;
220  double scale = abs(detaX) + abs(detaY);
221  detaX /= scale;
222  detaY /= scale;
223  double len = sqrt(detaX * detaX + detaY * detaY);
224  m_Edges[i].matrixRotatedToRightEdge = make_pair(detaX / len, detaY / len);
225  }
226  }
227 }
228 
230 {
231  m_maxEdgeLength = 0;
232  for (int i = 0; i < GetNumOfEdges(); ++i)
233  {
234  if (Edge(i).length > m_maxEdgeLength)
236  }
237 
238  //Perform the following
239  //when edge lengths are changed.
240  //compute angles around a vertex
242  //planar unfolding
244 }
245 
247 {
248  //build edges and compute lengths
249  //cerr << "Line " << __LINE__ << endl;
251  m_maxEdgeLength = 0;
252  for (int i = 0; i < GetNumOfEdges(); ++i)
253  {
254  if (Edge(i).length > m_maxEdgeLength)
256  }
257  //cerr << "Line " << __LINE__ << endl;
258  //build edges incident to a vertex
260  //cerr << "Line " << __LINE__ << endl;
261  //num of open boundaries
263  //num of components
264  //cerr << "Line " << __LINE__ << endl;
266  //cerr << "Line " << __LINE__ << endl;
267  //Perform the following
268  //when edge lengths are changed.
269  //compute angles around a vertex
271  //planar unfolding
272  //cerr << "Line " << __LINE__ << endl;
274 }
275 
277 {
279  //build edges and compute lengths
281  m_maxEdgeLength = 0;
282  for (int i = 0; i < GetNumOfEdges(); ++i)
283  {
284  if (Edge(i).length > m_maxEdgeLength)
286  }
287  //build edges incident to a vertex
289  //num of open boundaries
291  //num of components
293 
294  //Perform the following
295  //when edge lengths are changed.
296  //compute angles around a vertex
298  //planar unfolding
300 }
301 
302 
304 {
305  m_nBoundries = 0;
306  if (IsClosedModel())
307  {
308  return;
309  }
310  set<int> extremeEdges;
311  for (int i = 0; i < (int)m_Edges.size(); ++i)
312  {
313  if (m_Edges[i].indexOfOppositeVert != -1)
314  continue;
315  extremeEdges.insert(i);
316  }
317 
318  while (!extremeEdges.empty())
319  {
320  ++m_nBoundries;
321  int firstEdge = *extremeEdges.begin();
322  int edge = firstEdge;
323  do
324  {
325  extremeEdges.erase(edge);
326  int root = Edge(edge).indexOfRightVert;
327  int index = GetSubindexToVert(root, Edge(edge).indexOfLeftVert);
328  edge = Neigh(root)[(index - 1 + (int)Neigh(root).size()) % (int)Neigh(root).size()].first;
329  } while (edge != firstEdge && !extremeEdges.empty());
330  }
331 }
332 
334 {
335  m_nComponents = 0;
336  vector<bool> flags(GetNumOfVerts(), false);
337  int cnt(0);
338  while (cnt < GetNumOfVerts())
339  {
340  int v;
341  for (int i = 0; i < (int)flags.size(); ++i)
342  {
343  if (!flags[i])
344  {
345  v = i;
346  break;
347  }
348  }
349  queue<int> Que;
350  Que.push(v);
351  while (!Que.empty())
352  {
353  int v = Que.front();
354  Que.pop();
355  if (flags[v])
356  continue;
357  flags[v] = true;
358  cnt++;
359  for (int i = 0; i < (int)Neigh(v).size(); ++i)
360  {
361  if (!flags[Edge(Neigh(v)[i].first).indexOfRightVert])
362  {
363  Que.push(Edge(Neigh(v)[i].first).indexOfRightVert);
364  }
365  }
366  }
367  m_nComponents++;
368  }
369 }
370 
371 void CRichModel::PrintInfo(ostream& out) const
372 {
373  out << "Model info is as follows.\n";
374  out << "Name: " << GetFileShortName() << endl;
375  out << "VertNum = " << GetNumOfVerts() << endl;
376  out << "FaceNum = " << GetNumOfFaces() << endl;
377  out << "EdgeNum = " << GetNumOfEdges() << endl;
378  out << "Scale = " << m_scale << endl;
379  if (!IsClosedModel())
380  out << "BoundaryNum = " << GetNumOfBoundries() << endl;
381  out << "Genus = " << GetNumOfGenera() << endl;
382  if (IsClosedModel())
383  out << "It is a closed model.\n";
384  else
385  out << "It is an open model.\n";
386  if (GetNumOfComponents() != 1)
387  out << "It has " << GetNumOfComponents() << " components.\n";
388 }
389 
390 void CRichModel::SetEdgeLength(int leftVert, int rightVert, double newLength)
391 {
392  int edgeID = GetEdgeIndexFromTwoVertices(leftVert, rightVert);
393  int reverseID = Edge(edgeID).indexOfReverseEdge;
394  m_Edges[edgeID].length = newLength;
395  m_Edges[reverseID].length = newLength;
396 }
397 
398 
399 double CRichModel::AngleSum(int vertIndex) const
400 {
401  double angleSum(0);
402  for (int j = 0; j < (int)m_NeighsAndAngles[vertIndex].size(); ++j)
403  {
404  angleSum += m_NeighsAndAngles[vertIndex][j].second;
405  }
406  return angleSum;
407 }
408 
409 pair<double, double> CRichModel::GetTwoSplitAngles(int root, EdgePoint pt1, EdgePoint pt2) const
410 {
411  if (!pt1.isVertex && pt2.isVertex)
412  {
413  pair<double, double> splitAngles = GetTwoSplitAngles(root, pt2, pt1);
414  return make_pair(splitAngles.second, splitAngles.first);
415  }
416  if (!pt1.isVertex)
417  {
418  if (Edge(pt1.index).indexOfOppositeVert != root)
419  {
420  pt1.proportion = 1 - pt1.proportion;
421  pt1.index = Edge(pt1.index).indexOfReverseEdge;
422  assert(Edge(pt1.index).indexOfOppositeVert == root);
423  }
424  }
425  if (!pt2.isVertex)
426  {
427  if (Edge(pt2.index).indexOfOppositeVert != root)
428  {
429  pt2.proportion = 1 - pt2.proportion;
430  pt2.index = Edge(pt2.index).indexOfReverseEdge;
431  assert(Edge(pt2.index).indexOfOppositeVert == root);
432  }
433  }
434 
435  double rightAngleSum(0);
436  double leftAngleSum(0);
437  if (pt1.isVertex && pt2.isVertex)
438  {
439  int index1 = GetSubindexToVert(root, pt1.index);
440  int index2 = GetSubindexToVert(root, pt2.index);
441  int index = index1;
442  while (index != index2)
443  {
444  rightAngleSum += Neigh(root)[index].second;
445  index = (index + 1) % Neigh(root).size();
446  }
447  index = index2;
448  leftAngleSum = Neigh(root)[index].second;
449  index = (index + 1) % Neigh(root).size();
450  while (index != index1)
451  {
452  leftAngleSum += Neigh(root)[index].second;
453  index = (index + 1) % Neigh(root).size();
454  }
455  }
456  else if (pt1.isVertex && !pt2.isVertex)
457  {
458  int index1 = GetSubindexToVert(root, pt1.index);
459  int index2 = GetSubindexToVert(root, Edge(pt2.index).indexOfLeftVert);
460  int index = index1;
461  while (index != index2)
462  {
463  rightAngleSum += Neigh(root)[index].second;
464  index = (index + 1) % Neigh(root).size();
465  }
466  int index3 = GetSubindexToVert(root, Edge(pt2.index).indexOfRightVert);
467  index = index3;
468  while (index != index1)
469  {
470  leftAngleSum += Neigh(root)[index].second;
471  index = (index + 1) % Neigh(root).size();
472  }
473 
474  if (pt2.proportion < 1e-2
475  || pt2.proportion > 1 - 1e-2
476  || Edge(pt2.index).angleOpposite < 5.0 * M_PI / 180)
477  {
478  double leftAngle2 = pt2.proportion * Edge(pt2.index).angleOpposite;
479  double rightAngle2 = (1 - pt2.proportion) * Edge(pt2.index).angleOpposite;
480  rightAngleSum += leftAngle2;
481  leftAngleSum += rightAngle2;
482  }
483  else
484  {
485  double c = Edge(pt2.index).length * pt2.proportion;
486  double a = Edge(Edge(pt2.index).indexOfLeftEdge).length;
487  double detaX = c - Edge(pt2.index).coordOfOppositeVert.first;
488  double detaY = 0 - Edge(pt2.index).coordOfOppositeVert.second;
489  double b = sqrt(detaX * detaX + detaY * detaY);
490  double leftAngle2 = acos((a * a + b * b - c * c)/(2.0 * a * b));
491  double rightAngle2 = Edge(pt2.index).angleOpposite - leftAngle2;
492  rightAngleSum += leftAngle2;
493  leftAngleSum += rightAngle2;
494  }
495  }
496  else
497  {
498  assert(!pt1.isVertex && !pt2.isVertex);
499  int index1 = GetSubindexToVert(root, Edge(pt1.index).indexOfLeftVert);
500  int index2 = GetSubindexToVert(root, Edge(pt1.index).indexOfRightVert);
501  int index3 = GetSubindexToVert(root, Edge(pt2.index).indexOfLeftVert);
502  int index4 = GetSubindexToVert(root, Edge(pt2.index).indexOfRightVert);
503  if (index1 == index3)
504  {
505  double angleSum = 0;
506  for (int i = 0; i < Neigh(root).size(); ++i)
507  angleSum += Neigh(root)[i].second;
508  if (abs(pt1.proportion - pt2.proportion) < 1e-2
509  || Edge(pt1.index).angleOpposite < 5.0 * M_PI / 180)
510  {
511  if (pt1.proportion > pt2.proportion)
512  {
513  leftAngleSum = (pt1.proportion - pt2.proportion) * Edge(pt1.index).angleOpposite;
514  rightAngleSum = angleSum - leftAngleSum;
515  }
516  else
517  {
518  rightAngleSum = (pt2.proportion - pt1.proportion) * Edge(pt1.index).angleOpposite;
519  leftAngleSum = angleSum - rightAngleSum;
520  }
521  }
522  else if (pt1.proportion > pt2.proportion)
523  {
524  double c = (pt1.proportion - pt2.proportion) * Edge(pt1.index).length;
525  double detaX1 = pt1.proportion * Edge(pt1.index).length - Edge(pt1.index).coordOfOppositeVert.first;
526  double detaY1 = 0 - Edge(pt1.index).coordOfOppositeVert.second;
527  double a = sqrt(detaX1 * detaX1 + detaY1 * detaY1);
528  double detaX2 = pt2.proportion * Edge(pt2.index).length - Edge(pt2.index).coordOfOppositeVert.first;
529  double detaY2 = 0 - Edge(pt2.index).coordOfOppositeVert.second;
530  double b = sqrt(detaX2 * detaX2 + detaY2 * detaY2);
531  leftAngleSum = acos((a * a + b * b - c * c)/(2 * a * b));
532  rightAngleSum = angleSum - leftAngleSum;
533  }
534  else
535  {
536  double c = (pt1.proportion - pt2.proportion) * Edge(pt1.index).length;
537  double detaX1 = pt1.proportion * Edge(pt1.index).length - Edge(pt1.index).coordOfOppositeVert.first;
538  double detaY1 = 0 - Edge(pt1.index).coordOfOppositeVert.second;
539  double a = sqrt(detaX1 * detaX1 + detaY1 * detaY1);
540  double detaX2 = pt2.proportion * Edge(pt2.index).length - Edge(pt2.index).coordOfOppositeVert.first;
541  double detaY2 = 0 - Edge(pt2.index).coordOfOppositeVert.second;
542  double b = sqrt(detaX2 * detaX2 + detaY2 * detaY2);
543  rightAngleSum = acos((a * a + b * b - c * c)/(2 * a * b));
544  leftAngleSum = angleSum - rightAngleSum;
545  }
546  }
547  else
548  {
549  double leftAngle1, rightAngle1, leftAngle2, rightAngle2;
550  if (pt1.proportion < 1e-2
551  || pt1.proportion > 1 - 1e-2
552  || Edge(pt1.index).angleOpposite < 5.0 * M_PI / 180)
553  {
554  leftAngle1 = pt1.proportion * Edge(pt1.index).angleOpposite;
555  rightAngle1 = (1 - pt1.proportion) * Edge(pt1.index).angleOpposite;
556  }
557  else
558  {
559  double c = Edge(pt1.index).length * pt1.proportion;
560  double a = Edge(Edge(pt1.index).indexOfLeftEdge).length;
561  double detaX = c - Edge(pt1.index).coordOfOppositeVert.first;
562  double detaY = 0 - Edge(pt1.index).coordOfOppositeVert.second;
563  double b = sqrt(detaX * detaX + detaY * detaY);
564  leftAngle1 = acos((a * a + b * b - c * c)/(2.0 * a * b));
565  rightAngle1 = Edge(pt1.index).angleOpposite - leftAngle1;
566  }
567  if (pt2.proportion < 1e-2
568  || pt2.proportion > 1 - 1e-2
569  || Edge(pt2.index).angleOpposite < 5.0 * M_PI / 180)
570  {
571  leftAngle2 = pt2.proportion * Edge(pt2.index).angleOpposite;
572  rightAngle2 = (1 - pt2.proportion) * Edge(pt2.index).angleOpposite;
573  }
574  else
575  {
576  double c = Edge(pt2.index).length * pt2.proportion;
577  double a = Edge(Edge(pt2.index).indexOfLeftEdge).length;
578  double detaX = c - Edge(pt2.index).coordOfOppositeVert.first;
579  double detaY = 0 - Edge(pt2.index).coordOfOppositeVert.second;
580  double b = sqrt(detaX * detaX + detaY * detaY);
581  leftAngle2 = acos((a * a + b * b - c * c)/(2.0 * a * b));
582  rightAngle2 = Edge(pt2.index).angleOpposite - leftAngle2;
583  }
584  leftAngleSum = leftAngle1 + rightAngle2;
585  rightAngleSum = rightAngle1 + leftAngle2;
586  int index = index2;
587  while (index != index3)
588  {
589  rightAngleSum += Neigh(root)[index].second;
590  index = (index + 1) % Neigh(root).size();
591  }
592  index = index4;
593  while (index != index1)
594  {
595  leftAngleSum += Neigh(root)[index].second;
596  index = (index + 1) % Neigh(root).size();
597  }
598  }
599  }
600  return make_pair(leftAngleSum, rightAngleSum);
601 }
602 
603 
605 {
606  return (int)m_Faces.size() * 3;
607 }
608 
610 {
611  return (int)m_Edges.size() / 2;
612 }
613 
615 {
617 }
618 
620 {
621  return m_nComponents;
622 }
623 
625 {
626  return m_nBoundries;
627 }
628 
630 {
632 }
633 
635 {
636  return m_nIsolatedVerts;
637 }
638 
640 {
641  return (int)m_Edges.size();
642 }
643 
644 bool CRichModel::isBoundaryVert(int index) const
645 {
646  return IsStartEdge(Neigh(index).front().first);
647 }
648 
649 bool CRichModel::IsStronglyConvexVert(int index) const
650 {
651  return m_FlagsForCheckingConvexVerts[index].first;
652 }
653 
654 bool CRichModel::IsWeaklyConvexVert(int index) const
655 {
656  return m_FlagsForCheckingConvexVerts[index].second;
657 }
658 
659 bool CRichModel::IsExtremeEdge(int edgeIndex) const
660 {
661  return Edge(edgeIndex).indexOfOppositeVert == -1;
662 }
663 
664 bool CRichModel::IsStartEdge(int edgeIndex) const
665 {
666  return Edge(Edge(edgeIndex).indexOfReverseEdge).indexOfOppositeVert == -1;
667 }
668 
669 const CRichModel::CEdge& CRichModel::Edge(int edgeIndex) const
670 {
671  return m_Edges[edgeIndex];
672 }
673 
674 const vector<pair<int, double> >& CRichModel::Neigh(int root) const
675 {
676  return m_NeighsAndAngles[root];
677 }
678 
679 double CRichModel::ProportionOnEdgeByImage(int edgeIndex, const pair<double, double>& coord) const
680 {
681  double res = Edge(edgeIndex).coordOfOppositeVert.first * coord.second - Edge(edgeIndex).coordOfOppositeVert.second * coord.first;
682  return res / ((coord.second - Edge(edgeIndex).coordOfOppositeVert.second) * Edge(edgeIndex).length);
683 }
684 
685 double CRichModel::ProportionOnEdgeByImage(int edgeIndex, double x1, double y1, double x2, double y2) const
686 {
687  double res = x1 * y2 - x2 * y1;
688  return res / ((y2 - y1) * Edge(edgeIndex).length);
689 }
690 
691 double CRichModel::ProportionOnLeftEdgeByImage(int edgeIndex, const pair<double, double> &coord, double proportion) const
692 {
693  double xBalance = proportion * Edge(edgeIndex).length;
694  double res = Edge(edgeIndex).coordOfOppositeVert.first * coord.second - Edge(edgeIndex).coordOfOppositeVert.second * (coord.first - xBalance);
695  return xBalance * coord.second / res;
696 }
697 
698 double CRichModel::ProportionOnRightEdgeByImage(int edgeIndex, const pair<double, double> &coord, double proportion) const
699 {
700  double part1 = Edge(edgeIndex).length * coord.second;
701  double part2 = proportion * Edge(edgeIndex).length * Edge(edgeIndex).coordOfOppositeVert.second;
702  double part3 = Edge(edgeIndex).coordOfOppositeVert.second * coord.first - Edge(edgeIndex).coordOfOppositeVert.first * coord.second;
703  return (part3 + proportion * part1 - part2) / (part3 + part1 - part2);
704 }
705 
706 pair<double, double> CRichModel::GetNew2DCoordinatesByRotatingAroundLeftChildEdge(int edgeIndex, const pair<double, double>& input2DCoordinates) const
707 {
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);
710 }
711 
712 pair<double, double> CRichModel::GetNew2DCoordinatesByRotatingAroundRightChildEdge(int edgeIndex, const pair<double, double>& input2DCoordinates) const
713 {
714  int reverseEdge = Edge(Edge(edgeIndex).indexOfRightEdge).indexOfReverseEdge;
715  pair<double, double> coordOfLeftEnd = GetNew2DCoordinatesByReversingCurrentEdge(reverseEdge, Edge(reverseEdge).coordOfOppositeVert);
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);
718 }
719 
720 pair<double, double> CRichModel::GetNew2DCoordinatesByReversingCurrentEdge(int edgeIndex, const pair<double, double>& input2DCoordinates) const
721 {
722  return make_pair(Edge(edgeIndex).length - input2DCoordinates.first, - input2DCoordinates.second);
723 }
724 
725 int CRichModel::GetSubindexToVert(int root, int neigh) const
726 {
727  for (int i = 0; i < (int)Neigh(root).size(); ++i)
728  {
729  if (Edge(Neigh(root)[i].first).indexOfRightVert == neigh)
730  return i;
731  }
732  return -1;
733 }
734 
735 double CRichModel::DistanceToOppositeAngle(int edgeIndex, const pair<double, double>& coord) const
736 {
737  double detaX = coord.first - Edge(edgeIndex).coordOfOppositeVert.first;
738  double detaY = coord.second - Edge(edgeIndex).coordOfOppositeVert.second;
739  return sqrt(detaX * detaX + detaY * detaY);
740 }
741 
742 double CRichModel::DistanceToLeftVert(int edgeIndex, const pair<double, double>& coord) const
743 {
744  double detaX = coord.first;
745  double detaY = coord.second;
746  return sqrt(detaX * detaX + detaY * detaY);
747 }
748 
749 double CRichModel::DistanceToRightVert(int edgeIndex, const pair<double, double>& coord) const
750 {
751  double detaX = coord.first - Edge(edgeIndex).length;
752  double detaY = coord.second;
753  return sqrt(detaX * detaX + detaY * detaY);
754 }
755 
756 int CRichModel::GetEdgeIndexFromTwoVertices(int leftVert, int rightVert) const
757 {
758  int subIndex = GetSubindexToVert(leftVert, rightVert);
759  assert (subIndex != -1);
760  return Neigh(leftVert)[subIndex].first;
761 }
762 
764 {
765  CPoint3D newVert = (1 - ep.proportion) * m_Verts[Edge(ep.index).indexOfLeftVert]
767  m_Verts.push_back(newVert);
768  int vertID = m_Verts.size() - 1;
769  int edgeIndex = ep.index;
770  m_UselessFaces.insert(Edge(edgeIndex).indexOfFrontFace);
771  int reverseFaceIndex = Edge(Edge(edgeIndex).indexOfReverseEdge).indexOfFrontFace;
772  if (reverseFaceIndex != -1)
773  m_UselessFaces.insert(reverseFaceIndex);
774 
775  m_UselessEdges.insert(edgeIndex);
776  if (reverseFaceIndex != -1)
777  m_UselessEdges.insert(Edge(edgeIndex).indexOfReverseEdge);
778  m_Faces.push_back(CBaseModel::CFace(Edge(edgeIndex).indexOfLeftVert, vertID, Edge(edgeIndex).indexOfOppositeVert));
779  int f1 = (int)m_Faces.size() - 1;
780  m_Faces.push_back(CBaseModel::CFace(vertID, m_Edges[edgeIndex].indexOfRightVert, m_Edges[edgeIndex].indexOfOppositeVert));
781  int f2 = (int)m_Faces.size() - 1;
782  if (reverseFaceIndex != -1)
783  m_Faces.push_back(CBaseModel::CFace(m_Edges[m_Edges[edgeIndex].indexOfReverseEdge].indexOfLeftVert, vertID, m_Edges[m_Edges[edgeIndex].indexOfReverseEdge].indexOfOppositeVert));
784  int f3 = (int)m_Faces.size() - 1;
785  if (reverseFaceIndex != -1)
786  m_Faces.push_back(CBaseModel::CFace(vertID, m_Edges[m_Edges[edgeIndex].indexOfReverseEdge].indexOfRightVert, m_Edges[m_Edges[edgeIndex].indexOfReverseEdge].indexOfOppositeVert));
787  int f4 = (int)m_Faces.size() - 1;
788  if (reverseFaceIndex == -1)
789  f3 = f4 = -1;
790  m_Edges.push_back(CRichModel::CEdge());
791  int e1 = (int)m_Edges.size() - 1;
792  m_Edges.push_back(CRichModel::CEdge());
793  int e2 = (int)m_Edges.size() - 1;
794  m_Edges.push_back(CRichModel::CEdge());
795  int e3 = (int)m_Edges.size() - 1;
796  m_Edges.push_back(CRichModel::CEdge());
797  int e4 = (int)m_Edges.size() - 1;
798  m_Edges.push_back(CRichModel::CEdge());
799  int e5 = (int)m_Edges.size() - 1;
800  if (reverseFaceIndex != -1)
801  m_Edges.push_back(CRichModel::CEdge());
802  int e6 = (int)m_Edges.size() - 1;
803  if (reverseFaceIndex != -1)
804  m_Edges.push_back(CRichModel::CEdge());
805  int e7 = (int)m_Edges.size() - 1;
806  m_Edges.push_back(CRichModel::CEdge());
807  int e8 = (int)m_Edges.size() - 1;
808  if (reverseFaceIndex == -1)
809  e6 = e7 = -1;
810 
811  m_Edges[e1].indexOfFrontFace = f1;
812  m_Edges[e1].indexOfLeftEdge = m_Edges[edgeIndex].indexOfLeftEdge;
813  m_Edges[e1].indexOfLeftVert = m_Edges[edgeIndex].indexOfLeftVert;
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;
818 
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;
826 
827  m_Edges[e5].indexOfFrontFace = f3;
828  m_Edges[e5].indexOfLeftEdge = m_Edges[m_Edges[edgeIndex].indexOfReverseEdge].indexOfLeftEdge;
829  m_Edges[e5].indexOfLeftVert = m_Edges[m_Edges[edgeIndex].indexOfReverseEdge].indexOfLeftVert;
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;
834 
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;
840  m_Edges[e8].indexOfRightEdge = m_Edges[m_Edges[edgeIndex].indexOfReverseEdge].indexOfRightEdge;
841  m_Edges[e8].indexOfRightVert = m_Edges[m_Edges[edgeIndex].indexOfReverseEdge].indexOfRightVert;
842 
843  m_Edges[e2].indexOfFrontFace = f1;
844  m_Edges[e2].indexOfLeftEdge = m_Edges[e1].indexOfReverseEdge;
845  m_Edges[e2].indexOfLeftVert = m_Edges[e1].indexOfRightVert;
846  m_Edges[e2].indexOfOppositeVert = m_Edges[e1].indexOfLeftVert;
847  m_Edges[e2].indexOfReverseEdge = e3;
848  m_Edges[e2].indexOfRightEdge = m_Edges[e1].indexOfLeftEdge;
849  m_Edges[e2].indexOfRightVert = m_Edges[e1].indexOfOppositeVert;
850 
851  m_Edges[e3].indexOfFrontFace = f2;
852  m_Edges[e3].indexOfLeftEdge = m_Edges[e4].indexOfRightEdge;
853  m_Edges[e3].indexOfLeftVert = m_Edges[e4].indexOfOppositeVert;
854  m_Edges[e3].indexOfOppositeVert = m_Edges[e4].indexOfRightVert;
855  m_Edges[e3].indexOfReverseEdge = e2;
856  m_Edges[e3].indexOfRightEdge = m_Edges[e4].indexOfReverseEdge;
857  m_Edges[e3].indexOfRightVert = m_Edges[e4].indexOfLeftVert;
858 
859  if (reverseFaceIndex != -1)
860  {
861  m_Edges[e6].indexOfFrontFace = f3;
862  m_Edges[e6].indexOfLeftEdge = m_Edges[e5].indexOfReverseEdge;
863  m_Edges[e6].indexOfLeftVert = m_Edges[e5].indexOfRightVert;
864  m_Edges[e6].indexOfOppositeVert = m_Edges[e5].indexOfLeftVert;
865  m_Edges[e6].indexOfReverseEdge = e7;
866  m_Edges[e6].indexOfRightEdge = m_Edges[e5].indexOfLeftEdge;
867  m_Edges[e6].indexOfRightVert = m_Edges[e5].indexOfOppositeVert;
868 
869  m_Edges[e7].indexOfFrontFace = f4;
870  m_Edges[e7].indexOfLeftEdge = m_Edges[e8].indexOfRightEdge;
871  m_Edges[e7].indexOfLeftVert = m_Edges[e8].indexOfOppositeVert;
872  m_Edges[e7].indexOfOppositeVert = m_Edges[e8].indexOfRightVert;
873  m_Edges[e7].indexOfReverseEdge = e6;
874  m_Edges[e7].indexOfRightEdge = m_Edges[e8].indexOfReverseEdge;
875  m_Edges[e7].indexOfRightVert = m_Edges[e8].indexOfLeftVert;
876  }
877  int newEdgeCnt = 8;
878  if (reverseFaceIndex == -1)
879  newEdgeCnt = 6;
880  //for (int i = 0; i < newEdgeCnt; ++i)
881  //{
882  // extraEdgePool[make_pair(newEdges[newEdges.size() - 1 - i].indexOfLeftVert, newEdges[newEdges.size() - 1 - i].indexOfRightVert)] = newEdges.size() - 1 - i;
883  //}
884 
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;
893 
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;
902 
903  if (reverseFaceIndex != -1)
904  {
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;
913 
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;
922  }
923  return vertID;
924 }
925 
926 void CRichModel::SavePathToObj(const vector<EdgePoint>& pl, const string& filename) const
927 {
928  ofstream out(filename.c_str());
929  //filename.substr(filename.rfind("\\") + 1, filename.rfind('.') - filename.rfind("\\") - 1);
930  //filename.substr(filename.rfind("\\") + 1, filename.rfind('.') - filename.rfind("\\") - 1)
931  out << "g " << filename.substr(filename.rfind("\\") + 1, filename.rfind('.') - filename.rfind("\\") - 1) << endl;
932  if (!pl.empty())
933  {
934  for (int i = 0; i < pl.size(); ++i)
935  {
936  CPoint3D pt = pl[i].GetShiftPoint(*this);
937  out << "v " << pt.x << " " << pt.y << " " << pt.z << endl;
938  }
939 
940  out << "l ";
941  for (int i = 0; i < pl.size(); ++i)
942  {
943  out << i + 1 << " ";
944  }
945  out << endl;
946  }
947  out.close();
948 }
949 
950 //void CRichModel::SavePathToObj(const vector<CPoint3D>& pl, const string& filename) const
951 //{
952 // ofstream out(filename.c_str());
953 // out << "g 3D_Curve" << endl;
954 // if (!pl.empty())
955 // {
956 // for (int i = 0; i < pl.size(); ++i)
957 // {
958 // CPoint3D pt = pl[i];
959 // out << "v " << pt.x << " " << pt.y << " " << pt.z << endl;
960 // }
961 //
962 // out << "l ";
963 // for (int i = 0; i < pl.size(); ++i)
964 // {
965 // out << i + 1 << " ";
966 // }
967 // out << endl;
968 // }
969 // out.close();
970 //}
971 
972 void CRichModel::SaveIsolineToObj(const vector<EdgePoint>& isoline, const string& filename) const
973 {
974  ofstream out(filename.c_str());
975  out << "g " << filename.substr(filename.rfind("\\") + 1, filename.rfind('.') - filename.rfind("\\") - 1) << endl;
976  if (!isoline.empty())
977  {
978  for (int i = 0; i < isoline.size(); ++i)
979  {
980  CPoint3D pt = isoline[i].GetShiftPoint(*this);
981  out << "v " << pt.x << " " << pt.y << " " << pt.z << endl;
982  }
983 
984  for (int i = 0; i < isoline.size() / 2; ++i)
985  {
986  out << "l " << i * 2 + 1 << " " << 2 * i + 2 << endl;
987  }
988  }
989  out.close();
990 }
991 
992 void CRichModel::SplitBasedOnScalarField(const vector<double>& scalarField,
993  double val,
994  const string& fileWithLargerScalars,
995  const string& fileWithSmallerScalars)
996 {
997  vector<EdgePoint> eps;
998  for (int i = 0; i < GetNumOfEdges(); ++i)
999  {
1000  if (Edge(i).indexOfLeftVert >
1002  continue;
1003  if (scalarField[Edge(i).indexOfLeftVert] >= val
1004  == scalarField[Edge(i).indexOfRightVert] >= val)
1005  continue;
1006  double prop = (val - scalarField[Edge(i).indexOfLeftVert])
1007  / (scalarField[Edge(i).indexOfRightVert] - scalarField[Edge(i).indexOfLeftVert]);
1008  if (prop < 1e-4 || prop > 1 - 1e-4)
1009  continue;
1010  eps.push_back(EdgePoint(i, prop));
1011  }
1012  int oldVertNum = GetNumOfVerts();
1013  for (int i = 0; i < eps.size(); ++i)
1014  SplitEdge(eps[i]);
1015 
1016  ofstream outLarge(fileWithLargerScalars.c_str());
1017  ofstream outSmall(fileWithSmallerScalars.c_str());
1018  for (int i = 0; i < GetNumOfVerts(); ++i)
1019  {
1020  outLarge << "v " << Vert(i).x
1021  << " " << Vert(i).y
1022  << " " << Vert(i).z << endl;
1023  outSmall << "v " << Vert(i).x
1024  << " " << Vert(i).y
1025  << " " << Vert(i).z << endl;
1026  }
1027 
1028  for (int i = 0; i < GetNumOfFaces(); ++i)
1029  {
1030  if (m_UselessFaces.find(i) != m_UselessFaces.end())
1031  continue;
1032  int v1 = Face(i)[0];
1033  int v2 = Face(i)[1];
1034  int v3 = Face(i)[2];
1035  int cnt(0);
1036  double average(0);
1037  if (v1 < oldVertNum)
1038  {
1039  average += scalarField[v1];
1040  cnt++;
1041  }
1042  if (v2 < oldVertNum)
1043  {
1044  average += scalarField[v2];
1045  cnt++;
1046  }
1047  if (v3 < oldVertNum)
1048  {
1049  average += scalarField[v3];
1050  cnt++;
1051  }
1052  average /= cnt;
1053  if (average < val)
1054  {
1055  outSmall << "f " << Face(i)[0] + 1 << " " << Face(i)[1] + 1 << " " << Face(i)[2] + 1 << endl;
1056  }
1057  else
1058  {
1059  outLarge << "f " << Face(i)[0] + 1 << " " << Face(i)[1] + 1 << " " << Face(i)[2] + 1 << endl;
1060  }
1061  }
1062 
1063  outLarge.close();
1064  outSmall.close();
1065 }
1066 
1067 int CRichModel::IntersectQuery(int faceID, const pair<EdgePoint, EdgePoint>& seg1, const pair<EdgePoint, EdgePoint>& seg2, EdgePoint& intersection) const
1068 {
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)
1076  {
1077  int nxt = (i + 1) % 4;
1078  if (sortingVec[i].first == sortingVec[nxt].first
1079  && sortingVec[i].second != sortingVec[nxt].second)
1080  {
1081  if (seg1.first == seg2.first || seg1.first == seg2.second)
1082  intersection = seg1.first;
1083  else
1084  intersection = seg1.second;
1085  return -1;
1086  }
1087  }
1088  for (int i = 0; i < 4; ++i)
1089  {
1090  int nxt = (i + 1) % 4;
1091  if (sortingVec[i].second == sortingVec[nxt].second)
1092  return 0;
1093  }
1094  return 1;
1095 }
1096 
1098 {
1099  return m_maxEdgeLength;
1100 }
1101 
1102 //string GetUserName()
1103 //{
1104 // const int MAX_BUFFER_LEN = 500;
1105 // char szBuffer[MAX_BUFFER_LEN] = "";
1106 // DWORD dwNameLen;
1107 //
1108 // dwNameLen = MAX_BUFFER_LEN;
1109 // ::GetUserName(szBuffer, &dwNameLen);
1110 // return szBuffer;
1111 //}
1112 
1114 {
1115  //if (MyGetUserName() == "xinshiqing")
1116  //{
1117  // cout << "-----begin---------\n";
1118  // cout << "[" << Vert(Face(faceID)[0]).x << " " << Vert(Face(faceID)[0]).y << " " << Vert(Face(faceID)[0]).z << ";" << endl;
1119  // cout << Vert(Face(faceID)[1]).x << " " << Vert(Face(faceID)[1]).y << " " << Vert(Face(faceID)[1]).z << ";" << endl;
1120  // cout << Vert(Face(faceID)[2]).x << " " << Vert(Face(faceID)[2]).y << " " << Vert(Face(faceID)[2]).z << ";" << endl;
1121  // cout << pt.x << " " << pt.y << " " << pt.z << "];" << endl;
1122  //}
1123 
1124  Eigen::MatrixXd M(4, 3);
1125  M << Vert(Face(faceID)[0]).x, Vert(Face(faceID)[1]).x, Vert(Face(faceID)[2]).x,
1126  Vert(Face(faceID)[0]).y, Vert(Face(faceID)[1]).y, Vert(Face(faceID)[2]).y,
1127  Vert(Face(faceID)[0]).z, Vert(Face(faceID)[1]).z, Vert(Face(faceID)[2]).z,
1128  1, 1, 1;
1129  Eigen::VectorXd right(4);
1130  right << pt.x, pt.y, pt.z, 1;
1131  auto M_trans = M.transpose();
1132  //if (MyGetUserName() == "xinshiqing")
1133  //{
1134  // cerr << "--------------------\n";
1135  // cerr << M_trans << endl;
1136  // cerr << "--------------------\n";
1137  // cerr << M << endl;
1138  //}
1139 
1140  right = M_trans * right;
1141  //if (MyGetUserName() == "xinshiqing")
1142  //{
1143  // cerr << "--------------------\n";
1144  // cerr << M << endl;
1145  //}
1146  M = M_trans * M;
1147  //if (MyGetUserName() == "xinshiqing")
1148  //{
1149  // cerr << "--------------------\n";
1150  // cerr << M << endl;
1151  //}
1152 
1153  Eigen::Vector3d res = M.inverse() * right;
1154 
1155 
1156  return CPoint3D(res(0), res(1), res(2));
1157 }
int GetNumOfValidDirectedEdges() const
Definition: RichModel.cpp:604
void FinishChangingEdgeLengths()
Definition: RichModel.cpp:229
vector< CEdge > m_Edges
Definition: RichModel.h:110
virtual void LoadModel()
Definition: BaseModel.cpp:162
void ComputePlanarCoordsOfIncidentVertForEdges()
Definition: RichModel.cpp:184
void PreprocessBaseModel()
Definition: RichModel.cpp:246
vector< CPoint3D > m_Verts
Definition: BaseModel.h:38
double x
Definition: Point3D.h:14
string GetFileShortName() const
Definition: BaseModel.cpp:190
bool IsStartEdge(int edgeIndex) const
Definition: RichModel.cpp:664
pair< double, double > GetTwoSplitAngles(int root, EdgePoint pt1, EdgePoint pt2) const
Definition: RichModel.cpp:409
int GetNumOfFaces() const
Definition: BaseModel.h:85
pair< double, double > GetNew2DCoordinatesByRotatingAroundLeftChildEdge(int edgeIndex, const pair< double, double > &input2DCoordinates) const
Definition: RichModel.cpp:706
void ComputeNumOfComponents()
Definition: RichModel.cpp:333
void ComputeAnglesAroundVerts()
Definition: RichModel.cpp:148
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
int SplitEdge(const EdgePoint &ep)
Definition: RichModel.cpp:763
void SaveIsolineToObj(const vector< EdgePoint > &isoline, const string &filename) const
Definition: RichModel.cpp:972
double DistanceToRightVert(int edgeIndex, const pair< double, double > &coord) const
Definition: RichModel.cpp:749
double y
Definition: Point3D.h:14
double DistanceToOppositeAngle(int edgeIndex, const pair< double, double > &coord) const
Definition: RichModel.cpp:735
int IntersectQuery(int faceID, const pair< EdgePoint, EdgePoint > &seg1, const pair< EdgePoint, EdgePoint > &seg2, EdgePoint &intersection) const
Definition: RichModel.cpp:1067
void LoadModel()
Definition: RichModel.cpp:276
double proportion
Definition: EdgePoint.h:9
double ProportionOnLeftEdgeByImage(int edgeIndex, const pair< double, double > &coord, double proportion) const
Definition: RichModel.cpp:691
double DistanceToLeftVert(int edgeIndex, const pair< double, double > &coord) const
Definition: RichModel.cpp:742
pair< double, double > coordOfOppositeVert
Definition: RichModel.h:30
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
const CEdge & Edge(int edgeIndex) const
Definition: RichModel.cpp:669
int GetEdgeIndexFromTwoVertices(int leftVert, int rightVert) const
Definition: RichModel.cpp:756
CPoint3D GetBarycentricCoord(CPoint3D pt, int faceID) const
Definition: RichModel.cpp:1113
double ProportionOnRightEdgeByImage(int edgeIndex, const pair< double, double > &coord, double proportion) const
Definition: RichModel.cpp:698
bool IsWeaklyConvexVert(int index) const
Definition: RichModel.cpp:654
int GetSubindexToVert(int root, int neigh) const
Definition: RichModel.cpp:725
vector< CFace > m_Faces
Definition: BaseModel.h:37
int index
Definition: EdgePoint.h:8
double AngleSum(int vertIndex) const
Definition: RichModel.cpp:399
pair< double, double > GetNew2DCoordinatesByRotatingAroundRightChildEdge(int edgeIndex, const pair< double, double > &input2DCoordinates) const
Definition: RichModel.cpp:712
int GetNumOfBoundries() const
Definition: RichModel.cpp:624
void SetEdgeLength(int leftVert, int rightVert, double newLength)
Definition: RichModel.cpp:390
int indexOfReverseEdge
Definition: RichModel.h:26
double ProportionOnEdgeByImage(int edgeIndex, const pair< double, double > &coord) const
Definition: RichModel.cpp:679
int GetNumOfComponents() const
Definition: RichModel.cpp:619
int GetNumOfTotalUndirectedEdges() const
Definition: RichModel.cpp:609
bool IsExtremeEdge(int edgeIndex) const
Definition: RichModel.cpp:659
int m_nIsolatedVerts
Definition: RichModel.h:107
void SplitBasedOnScalarField(const vector< double > &scalarField, double val, const string &fileWithLargerScalars, const string &fileWithSmallerScalars)
Definition: RichModel.cpp:992
const vector< pair< int, double > > & Neigh(int root) const
Definition: RichModel.cpp:674
vector< pair< bool, bool > > m_FlagsForCheckingConvexVerts
Definition: RichModel.h:114
EIGEN_DEVICE_FUNC const AcosReturnType acos() const
int GetNumOfVerts() const
Definition: BaseModel.h:80
void ComputeNumOfHoles()
Definition: RichModel.cpp:303
bool isBoundaryVert(int index) const
Definition: RichModel.cpp:644
bool IsStronglyConvexVert(int index) const
Definition: RichModel.cpp:649
int m_nBoundries
Definition: RichModel.h:106
double angleOpposite
Definition: RichModel.h:29
int GetNumOfIsolated() const
Definition: RichModel.cpp:634
bool IsClosedModel() const
Definition: RichModel.cpp:629
int64_t max(int64_t a, const int b)
Definition: Xin_Wang.cpp:10
int indexOfOppositeVert
Definition: RichModel.h:23
void CollectAndArrangeNeighs()
Definition: RichModel.cpp:84
vector< vector< pair< int, double > > > m_NeighsAndAngles
Definition: RichModel.h:112
const CPoint3D & Vert(int vertIndex) const
Definition: BaseModel.h:90
pair< double, double > GetNew2DCoordinatesByReversingCurrentEdge(int edgeIndex, const pair< double, double > &input2DCoordinates) const
Definition: RichModel.cpp:720
int GetNumOfGenera() const
Definition: RichModel.cpp:614
int m_nComponents
Definition: RichModel.h:108
void SavePathToObj(const vector< EdgePoint > &pl, const string &filename) const
Definition: RichModel.cpp:926
const CFace & Face(int faceIndex) const
Definition: BaseModel.h:100
set< int > m_UselessFaces
Definition: BaseModel.h:41
double z
Definition: Point3D.h:14
double m_maxEdgeLength
Definition: RichModel.h:109
void CreateEdgesFromVertsAndFaces()
Definition: RichModel.cpp:25
int GetNumOfEdges() const
Definition: RichModel.cpp:639
set< int > m_UselessEdges
Definition: RichModel.h:111
double m_scale
Definition: BaseModel.h:43
CRichModel(const string &filename)
Definition: RichModel.cpp:14
const double AngleTolerance
Definition: Parameters.h:2
double GetMaxEdgeLength() const
Definition: RichModel.cpp:1097
void PrintInfo(ostream &out) const
Definition: RichModel.cpp:371
bool isVertex
Definition: EdgePoint.h:7


co_scan
Author(s):
autogenerated on Mon Feb 28 2022 23:00:48