G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsHalfEdgeMesh.hpp
Go to the documentation of this file.
1 
14 #pragma once
15 
16 namespace gismo
17 {
18 //struct less_than_ptr
19 //{
20 // bool operator()(gsMesh<>::gsVertexHandle lhs, gsMesh<>::gsVertexHandle rhs)
21 // {
22 // return ((*lhs) < (*rhs));
23 // }
24 //};
25 //
26 //struct equal_ptr
27 //{
28 // bool operator()(gsMesh<>::gsVertexHandle lhs, gsMesh<>::gsVertexHandle rhs)
29 // {
30 // return ((*lhs) == (*rhs));
31 // }
32 //};
33 
34 template<class T>
35 gsHalfEdgeMesh<T>::gsHalfEdgeMesh(const gsMesh<T> &mesh, T precision, bool periodic)
36  : gsMesh<T>(mesh), m_precision(precision)
37 {
38  //this->cleanMesh();
39  //std::sort(this->m_vertex.begin(), this->m_vertex.end(), less_than_ptr());
40  //typename std::vector<gsVertex<T> *, std::allocator<gsVertex<T> *> >::iterator
41  //last = std::unique(this->m_vertex.begin(), this->m_vertex.end(), equal_ptr());
42 
43  m_halfedges.reserve(3*this->m_face.size());
44  for (size_t i = 0; i < this->m_face.size(); i++)
45  {
46  m_halfedges.push_back(getInternHalfedge(this->m_face[i], 1));
47  m_halfedges.push_back(getInternHalfedge(this->m_face[i], 2));
48  m_halfedges.push_back(getInternHalfedge(this->m_face[i], 3));
49  }
50 
52  m_n = this->m_vertex.size() - m_boundary.getNumberOfVertices();
53  sortVertices();
54 }
55 
56 template<class T>
58 {
59  return this->m_vertex.size();
60 }
61 
62 template<class T>
64 {
65  return this->m_face.size();
66 }
67 
68 template<class T>
70 {
71  return m_n;
72 }
73 
74 template<class T>
76 {
77  return m_boundary.getNumberOfVertices();
78 }
79 
80 template<class T>
81 const typename gsMesh<T>::gsVertexHandle &gsHalfEdgeMesh<T>::getVertex(const size_t vertexIndex) const
82 {
83  GISMO_ASSERT(vertexIndex <= this->m_vertex.size(), "Vertex with index 'vertexIndex'=" << vertexIndex
84  << " does not exist. There are only " << this->m_vertex.size() << " vertices.");
85  return ((this->m_vertex[m_sorting[vertexIndex - 1]]));
86 }
87 
88 /*template<class T>
89 size_t gsHalfEdgeMesh<T>::getVertexIndex(const gsMesh<T>::gsVertexHandle &vertex) const
90 {
91  return m_inverseSorting[getInternVertexIndex(vertex)];
92 }*/
93 
94  // Dominik's version
95 template<class T>
96 size_t gsHalfEdgeMesh<T>::getVertexIndex(const typename gsMesh<T>::gsVertexHandle &vertex) const
97 {
98  return m_inverseSorting[findVertex(vertex)];
99 }
100 
101 template<class T>
102 size_t gsHalfEdgeMesh<T>::getGlobalVertexIndex(size_t localVertexIndex, size_t triangleIndex) const
103 {
104  return m_inverseSorting[this->m_face[triangleIndex]->vertices[localVertexIndex-1]->getId()];
105 }
106 
107 template<class T>
109 {
110  return m_boundary.getLength();
111 }
112 
113 template<class T>
114 bool rangeCheck(const std::vector<index_t> &corners, const size_t minimum, const size_t maximum)
115 {
116  for (std::vector<index_t>::const_iterator it = corners.begin(); it != corners.end(); it++)
117  {
118  if ((size_t)*it < minimum || (size_t)*it > maximum)
119  { return false; }
120  }
121  return true;
122 }
123 
124 template<class T>
125 std::vector<T> gsHalfEdgeMesh<T>::getCornerLengths(std::vector<index_t> &corners) const
126 {
127  GISMO_ASSERT(rangeCheck<T>(corners, 1, getNumberOfBoundaryVertices()), "The corners must be <= number of boundary vertices.");
128 
129  std::sort(corners.begin(), corners.end());
130  size_t s = corners.size();
131  std::vector<T> lengths;
132  for (size_t i = 0; i < s; i++)
133  {
134  lengths.push_back(m_boundary.getDistanceBetween(corners[i], corners[(i + 1) % s]));
135  }
136  return lengths;
137 }
138 
139 template<class T>
141 {
142  return m_boundary.getShortestDistanceBetween(i, j, m_precision);
143 }
144 
145 template<class T>
146 const std::vector<T> gsHalfEdgeMesh<T>::getBoundaryChordLengths() const
147 {
148  return m_boundary.getHalfedgeLengths();
149 }
150 
151 template<class T>
152 T gsHalfEdgeMesh<T>::getHalfedgeLength(size_t originVertexIndex, size_t endVertexIndex) const
153 {
154  GISMO_ASSERT(originVertexIndex <= this->m_vertex.size() && endVertexIndex <= this->m_vertex.size(),
155  "One of the input vertex indices " << originVertexIndex << " or " << endVertexIndex
156  << " does not exist. There are only " << this->m_vertex.size() << " vertices.");
157 
158  return gsVector3d<T>(getVertex(originVertexIndex)->x() - getVertex(endVertexIndex)->x(),
159  getVertex(originVertexIndex)->y() - getVertex(endVertexIndex)->y(),
160  getVertex(originVertexIndex)->z() - getVertex(endVertexIndex)->z()).norm();
161 }
162 
163 template<class T>
164 short_t gsHalfEdgeMesh<T>::isTriangleVertex(size_t vertexIndex, size_t triangleIndex) const
165 {
166  if (vertexIndex > this->m_vertex.size())
167  {
168  gsWarn << "gsHalfEdgeMesh::isTriangleVertex: Vertex with vertex index " << vertexIndex
169  << " does not exist. There are only " << this->m_vertex.size() << " vertices.\n";
170  return 0;
171  }
172  if (triangleIndex > getNumberOfTriangles())
173  {
174  gsWarn << "gsHalfEdgeMesh::isTriangleVertex: The " << triangleIndex
175  << "-th triangle does not exist. There are only " << getNumberOfTriangles() << " triangles.\n";
176  return 0;
177  }
178  if (*(this->m_vertex[m_sorting[vertexIndex - 1]]) == *(this->m_face[triangleIndex]->vertices[0]))
179  { return 1; }
180  if (*(this->m_vertex[m_sorting[vertexIndex - 1]]) == *(this->m_face[triangleIndex]->vertices[1]))
181  { return 2; }
182  if (*(this->m_vertex[m_sorting[vertexIndex - 1]]) == *(this->m_face[triangleIndex]->vertices[2]))
183  { return 3; }
184  return 0; // not contained
185 }
186 
187 template<class T>
188 const std::queue<typename gsHalfEdgeMesh<T>::Halfedge>
189 gsHalfEdgeMesh<T>::getOppositeHalfedges(const size_t vertexIndex, const bool innerVertex) const
190 {
191  std::queue<Halfedge> oppositeHalfedges;
192  if (vertexIndex > this->m_vertex.size())
193  {
194  gsInfo << "gsHalfEdgeMesh::getOppositeHalfedges: The vertex with index " << vertexIndex
195  << " does not exist. There are only " << this->m_vertex.size() << " vertices.\n";
196  return oppositeHalfedges;
197  }
198  else if (vertexIndex > m_n && innerVertex)
199  {
200  gsWarn << "gsHalfEdgeMesh::getOppositeHalfedges: Inner vertex with index 'vertexIndex' = " << vertexIndex
201  << "is not an inner vertex. There are only " << m_n << " inner vertices.\n";
202  }
203 
204  size_t v1, v2, v3;
205  for (size_t i = 0; i < getNumberOfTriangles(); i++)
206  {
207  switch (isTriangleVertex(vertexIndex, i))
208  {
209  case 1:
210  v3 = getGlobalVertexIndex(3, i);
211  v2 = getGlobalVertexIndex(2, i);
212  oppositeHalfedges.push(Halfedge(v3, v2, getHalfedgeLength(v3, v2)));
213  break;
214  case 2:
215  v1 = getGlobalVertexIndex(1, i);
216  v3 = getGlobalVertexIndex(3, i);
217  oppositeHalfedges.push(Halfedge(v1, v3, getHalfedgeLength(v1, v3)));
218  break;
219  case 3:
220  v2 = getGlobalVertexIndex(2, i);
221  v1 = getGlobalVertexIndex(1, i);
222  oppositeHalfedges.push(Halfedge(v2, v1, getHalfedgeLength(v2, v1)));
223  break;
224  default:
225  // vertex is not supposed to show up
226  break;
227  }
228  }
229  return oppositeHalfedges;
230 }
231 
232 template <class T>
233 size_t gsHalfEdgeMesh<T>::findVertex(T x, T y, T z, bool sorted, real_t tol) const
234 {
235  size_t numVertices = getNumberOfVertices();
236  size_t i=0;
237  for( ; i<numVertices; i++)
238  {
239  typename gsMesh<T>::gsVertexHandle handle = sorted ? getVertex(i+1) : getVertexUnsorted(i);
240 
241  if((math::abs(x - handle->x()) < tol) &&
242  (math::abs(y - handle->y()) < tol) &&
243  (math::abs(z - handle->z()) < tol))
244  return sorted ? i+1 : i;
245  }
246  return std::numeric_limits<size_t>::max();
247 }
248 
249 template<class T>
250 bool gsHalfEdgeMesh<T>::isBoundaryVertex(const size_t internVertexIndex) const
251 {
252  if (internVertexIndex > this->m_vertex.size() - 1)
253  {
254  gsWarn << "gsHalfEdgeMesh::isBoundaryVertex: Vertex with intern vertex index = " << internVertexIndex
255  << " does not exist. There are only " << this->m_vertex.size() << " vertices.\n";
256  return false;
257  }
258  else
259  return m_boundary.isVertexContained(internVertexIndex);
260 }
261 
262 template<class T>
263 const typename gsHalfEdgeMesh<T>::Halfedge
264 gsHalfEdgeMesh<T>::getInternHalfedge(const typename gsMesh<T>::gsFaceHandle &triangle, size_t numberOfHalfedge) const
265 {
266  size_t index1 = triangle->vertices[0]->getId();
267  size_t index2 = triangle->vertices[1]->getId();
268  size_t index3 = triangle->vertices[2]->getId();
269  if (numberOfHalfedge < 1 || numberOfHalfedge > 3)
270  {
271  gsWarn << "gsHalfEdgeMesh::getInternHalfedge: The inputted number of the halfedge " << numberOfHalfedge
272  << " is supposed to be 1,2 or 3. Because input was not expected, first halfedge is returned.\n";
273  numberOfHalfedge = 1;
274  }
275  if (numberOfHalfedge == 1)
276  {
277  return Halfedge(index2, index1,
279  triangle->vertices[1]->x() - triangle->vertices[0]->x(),
280  triangle->vertices[1]->y() - triangle->vertices[0]->y(),
281  triangle->vertices[1]->z() - triangle->vertices[0]->z()).norm());
282  }
283  if (numberOfHalfedge == 2)
284  {
285  return Halfedge(index3, index2,
287  triangle->vertices[2]->x() - triangle->vertices[1]->x(),
288  triangle->vertices[2]->y() - triangle->vertices[1]->y(),
289  triangle->vertices[2]->z() - triangle->vertices[1]->z()).norm());
290  }
291  if (numberOfHalfedge == 3)
292  {
293  return Halfedge(index1, index3,
295  triangle->vertices[0]->x() - triangle->vertices[2]->x(),
296  triangle->vertices[0]->y() - triangle->vertices[2]->y(),
297  triangle->vertices[0]->z() - triangle->vertices[2]->z()).norm());
298  }
299  return Halfedge();
300 }
301 
302 template<class T>
304 {
305  // first all interior, then all boundary
306 
307  size_t numberOfInnerVerticesFound = 0;
308  m_sorting.resize(this->m_vertex.size(), 0);
309  m_inverseSorting.resize(this->m_vertex.size(), 0);
310 
311  for (size_t i = 0; i != this->m_vertex.size(); ++i)
312  {
313  if (!isBoundaryVertex(i))
314  {
315  numberOfInnerVerticesFound++;
316  m_sorting[numberOfInnerVerticesFound - 1] = i;
317  m_inverseSorting[i] = numberOfInnerVerticesFound;
318  }
319  }
320 
321  std::list<size_t> boundaryVertices = m_boundary.getVertexIndices();
322  for (size_t i = 0; i < getNumberOfBoundaryVertices(); i++)
323  {
324  m_sorting[m_n + i] = boundaryVertices.front();
325  m_inverseSorting[boundaryVertices.front()] = m_n + i + 1;
326  boundaryVertices.pop_front();
327  }
328 }
329 
330 // nested class Boundary
332 template<class T>
333 gsHalfEdgeMesh<T>::Boundary::Boundary(const std::vector<typename gsHalfEdgeMesh<T>::Halfedge> &halfedges)
334 {
335  std::list<Halfedge> unsortedNonTwinHalfedges = findNonTwinHalfedges(halfedges);
336 
337  while(!unsortedNonTwinHalfedges.empty())
338  {
339  // Start a new connected component.
340  Chain component;
341  component.appendNextHalfedge(unsortedNonTwinHalfedges.front());
342  unsortedNonTwinHalfedges.pop_front();
343  std::queue<Halfedge> nonFittingHalfedges;
344  while (!unsortedNonTwinHalfedges.empty())
345  {
346  if (component.isAppendableAsNext(unsortedNonTwinHalfedges.front()))
347  {
348  component.appendNextHalfedge(unsortedNonTwinHalfedges.front());
349  unsortedNonTwinHalfedges.pop_front();
350  while (!nonFittingHalfedges.empty())
351  {
352  unsortedNonTwinHalfedges.push_back(nonFittingHalfedges.front());
353  nonFittingHalfedges.pop();
354  }
355  }
356  else if (component.isAppendableAsPrev(unsortedNonTwinHalfedges.front()))
357  {
358  component.appendPrevHalfedge(unsortedNonTwinHalfedges.front());
359  unsortedNonTwinHalfedges.pop_front();
360  while (!nonFittingHalfedges.empty())
361  {
362  unsortedNonTwinHalfedges.push_back(nonFittingHalfedges.front());
363  nonFittingHalfedges.pop();
364  }
365  }
366  else
367  {
368  nonFittingHalfedges.push(unsortedNonTwinHalfedges.front());
369  unsortedNonTwinHalfedges.pop_front();
370  }
371  }
372 
373  m_boundary.push_back(component);
374 
375  // // Collect the remaining half edges for the next connected component.
376  while(!nonFittingHalfedges.empty())
377  {
378  unsortedNonTwinHalfedges.push_back( nonFittingHalfedges.front() );
379  nonFittingHalfedges.pop(); // Start a new connected component.
380  }
381  }
382 }
384 // private
385 
386 template<class T>
387 const std::list<typename gsHalfEdgeMesh<T>::Halfedge> gsHalfEdgeMesh<T>::Boundary::findNonTwinHalfedges(const std::vector<typename gsHalfEdgeMesh<T>::Halfedge> &allHalfedges)
388 {
389  std::queue<Halfedge> queue0;
390  std::queue<Halfedge> queue1;
391  bool actualQueue = 0;
392  std::list<Halfedge> nonTwinHalfedges;
393  for (size_t i = 0; i < allHalfedges.size(); ++i)
394  {
395  queue0.push(allHalfedges[i]);
396  }
397  while (!(queue0.empty() && queue1.empty()))
398  {
399  if (actualQueue == 0)
400  {
401  nonTwinHalfedges.push_back(queue0.front());
402  queue0.pop();
403  while (!queue0.empty())
404  {
405  if (nonTwinHalfedges.back().isTwin(queue0.front()))
406  {
407  queue0.pop();
408  nonTwinHalfedges.pop_back();
409  while (!queue0.empty())
410  {
411  queue1.push(queue0.front());
412  queue0.pop();
413  }
414  }
415  else
416  {
417  queue1.push(queue0.front());
418  queue0.pop();
419  }
420  }
421  actualQueue = 1;
422  }
423  else if (actualQueue == 1)
424  {
425  nonTwinHalfedges.push_back(queue1.front());
426  queue1.pop();
427  while (!queue1.empty())
428  {
429  if (nonTwinHalfedges.back().isTwin(queue1.front()))
430  {
431  queue1.pop();
432  nonTwinHalfedges.pop_back();
433  while (!queue1.empty())
434  {
435  queue0.push(queue1.front());
436  queue1.pop();
437  }
438  }
439  else
440  {
441  queue0.push(queue1.front());
442  queue1.pop();
443  }
444  }
445  actualQueue = 0;
446  }
447  }
448  return nonTwinHalfedges;
449 }
450 
451 // nested class Chain
452 
453 template<class T>
455 {
456  if (m_chainedHalfedges.empty())
457  {
458  gsWarn << "gsHalfEdgeMesh<T>::Chain::isClosed: The chain does not store any halfedges yet.\n";
459  return true;
460  }
461  return (m_chainedHalfedges.front().getOrigin() == m_chainedHalfedges.back().getEnd());
462 }
463 
464 template<class T>
466 {
467  if (this->isClosed())
468  return m_chainedHalfedges.size();
469  else
470  return m_chainedHalfedges.size() + 1;
471 }
472 
473 template<class T>
475 {
476  T length = 0;
477  for (typename std::list<Halfedge>::const_iterator it = m_chainedHalfedges.begin();
478  it != m_chainedHalfedges.end(); ++it)
479  {
480  length += it->getLength();
481  }
482  return length;
483 }
484 
485 template<class T>
487 {
488  if (this->isEmpty())
489  {
490  gsWarn << "gsHalfEdgeMesh::Chain::getHalfedgeLengths: The chain does not store any halfedges yet.\n";
491  }
492  std::vector<T> lengths;
493  for (typename std::list<Halfedge>::const_iterator it = m_chainedHalfedges.begin();
494  it != m_chainedHalfedges.end(); ++it)
495  {
496  lengths.push_back(it->getLength());
497  }
498  return lengths;
499 }
500 
501 template<class T>
503 {
504  if (this->isEmpty())
505  {
506  gsInfo << "gsHalfEdgeMesh::Chain::getFirstHalfedge: The chain does not store any halfedges yet.\n";
507  }
508  return m_chainedHalfedges.front();
509 }
510 
511 template<class T>
513 {
514  if (this->isEmpty())
515  {
516  gsInfo << "gsHalfEdgeMesh::Chain::getLastHalfedge: The chain does not store any halfedges yet.\n";
517  }
518  return m_chainedHalfedges.back();
519 }
520 
521 template<class T>
522 const std::list<size_t> gsHalfEdgeMesh<T>::Chain::getVertexIndices() const
523 {
524  if (this->isEmpty())
525  {
526  gsWarn << "gsHalfEdgeMesh::Chain::getVertexIndices: The chain does not store any halfedges yet.\n";
527  }
528  std::list<size_t> vertexIndices;
529  for (typename std::list<Halfedge>::const_iterator it = m_chainedHalfedges.begin();
530  it != m_chainedHalfedges.end(); ++it)
531  {
532  vertexIndices.push_back(it->getOrigin());
533  }
534  if (m_chainedHalfedges.size() == 1 || !(this->isClosed()))
535  {
536  vertexIndices.push_back(m_chainedHalfedges.back().getEnd());
537  }
538  return vertexIndices;
539 }
540 
541 template<class T>
542 T gsHalfEdgeMesh<T>::Chain::getShortestDistanceBetween(size_t i, size_t j, T precision) const
543 {
544  if (this->isEmpty())
545  {
546  gsWarn << "gsHalfEdgeMesh::Chain::getShortestDistanceBetween: The chain does not store any halfedges yet.\n";
547  return 0;
548  }
549  if (i > this->getNumberOfVertices() || j > this->getNumberOfVertices() || i < 1 || j < 1)
550  {
551  gsInfo << "gsHalfEdgeMesh::Chain::getShortestDistanceBetween: FirstIndex: " << i << " and second index: "
552  << j
553  << " must be positiv integers smaller than the number of points of the chain, which is "
554  << this->getNumberOfVertices() << ".\n";
555  return 0;
556  }
557  if (i > j) std::swap(i, j);
558  T distance = 0;
559  std::vector<T> l = this->getHalfedgeLengths();
560  for (size_t z = i - 1; z < j - 1; z++)
561  {
562  distance += l[z];
563  }
564  if (this->isClosed() && (this->getLength() - distance < distance - precision))
565  {
566  distance = this->getLength() - distance;
567  }
568  return distance;
569 }
570 
571 template<class T>
573 {
574  if (this->isEmpty())
575  {
576  gsWarn << "gsHalfEdgeMesh::Chain::getDistanceBetween: The chain does not store any halfedges yet.\n";
577  return 0;
578  }
579  if (i > this->getNumberOfVertices() || j > this->getNumberOfVertices() || i < 1 || j < 1)
580  {
581  gsInfo << "gsHalfEdgeMesh::Chain::getDistanceBetween: FirstIndex: " << i << " and second index: "
582  << j
583  << " must be positiv integers smaller than the number of points of the chain, which is "
584  << this->getNumberOfVertices() << ".\n";
585  return 0;
586  }
587  bool ordered = (i < j);
588  if (!ordered) std::swap(i, j);
589  T distance = 0;
590  std::vector<T> l = this->getHalfedgeLengths();
591  for (size_t z = i - 1; z < j - 1; z++)
592  {
593  distance += l[z];
594  }
595  if (this->isClosed() && !ordered)
596  {
597  distance = this->getLength() - distance;
598  }
599  else if (!ordered)
600  gsWarn << "gsHalfEdgeMesh::Chain::getDistanceBetween: The chain is supposed to be closed in case the input is not ordered.\n";
601  return distance;
602 }
603 
604 template<class T>
605 bool gsHalfEdgeMesh<T>::Chain::isVertexContained(const size_t &vertexIndex) const
606 {
607  if (this->isEmpty())
608  {
609  gsWarn << "gsHalfEdgeMesh::Chain::isVertexContained: The chain does not store any halfedges yet.\n";
610  return false;
611  }
612  for (typename std::list<Halfedge>::const_iterator it = m_chainedHalfedges.begin();
613  it != m_chainedHalfedges.end(); ++it)
614  {
615  if (it->getOrigin() == vertexIndex)
616  return true;
617  }
618  if (!(this->isClosed()) && this->getLastHalfedge().getEnd() == vertexIndex) //here ! was added
619  return true;
620  return false;
621 }
622 
623 template<class T>
625 {
626  if (m_chainedHalfedges.empty())
627  return true;
628  else
629  return m_chainedHalfedges.front().isNext(previousHalfedge);
630 }
631 
632 template<class T>
634 {
635  if (m_chainedHalfedges.empty())
636  return true;
637  else
638  return m_chainedHalfedges.back().isPrev(nextHalfedge);
639 }
640 
641 template<class T>
643 {
644  if (!this->isAppendableAsPrev(prevHalfedge))
645  {
646  gsWarn << "gsHalfEdgeMesh::Chain::appendPrevHalfedge: This halfedge is not appendable at the beginning.\n";
647  gsInfo << "The first halfedge of the chain has origin " << this->getFirstHalfedge().getOrigin()
648  << " and prevHalfedge has the end " << prevHalfedge.getEnd() << ".\n";
649  }
650  else
651  {
652  m_chainedHalfedges.push_front(prevHalfedge);
653  }
654 }
655 
656 template<class T>
658  bool ignoreWarning)
659 {
660  if (!ignoreWarning && !isAppendableAsNext(nextHalfedge))
661  {
662  gsWarn << "gsHalfEdgeMesh::Chain::appendNextHalfedge: This halfedge is not appendable at the end.\n";
663  gsInfo << "The last halfedge of the chain has end " << this->getLastHalfedge().getEnd()
664  << " and nextHalfedge has the origin " << nextHalfedge.getOrigin() << ".\n";
665  }
666  else
667  {
668  m_chainedHalfedges.push_back(nextHalfedge);
669  }
670 }
671 
672 } // namespace gismo
const Halfedge & getLastHalfedge() const
Get last halfedge.
Definition: gsHalfEdgeMesh.hpp:512
Boundary()
Empty Constructor.
Definition: gsHalfEdgeMesh.h:383
A fixed-size, statically allocated 3D vector.
Definition: gsVector.h:218
const std::queue< Halfedge > getOppositeHalfedges(const size_t vertexIndex, const bool innerVertex=1) const
Returns queue of all opposite halfedges of vertex The opposite halfedge of a point in a triangle is m...
Definition: gsHalfEdgeMesh.hpp:189
const std::vector< T > getBoundaryChordLengths() const
Get chord lengths of boundary A vector storing the lengths of the halfedges of the boundary is return...
Definition: gsHalfEdgeMesh.hpp:146
T getBoundaryLength() const
Get length of the boundary of the triangle mesh. The length of the boundary of the triangle mesh is r...
Definition: gsHalfEdgeMesh.hpp:108
T distance(gsMatrix< T > const &A, gsMatrix< T > const &B, index_t i=0, index_t j=0, bool cols=false)
compute a distance between the point number in the set and the point number &lt;j&gt; in the set ; by def...
const Halfedge getInternHalfedge(const typename gsMesh< T >::gsFaceHandle &triangle, size_t numberOfHalfedge) const
Returns halfedge of triangle For a given triangle the first, second or third halfedge are constructed...
Definition: gsHalfEdgeMesh.hpp:264
#define short_t
Definition: gsConfig.h:35
T getDistanceBetween(size_t i, size_t j) const
Get distance between vertices.
Definition: gsHalfEdgeMesh.hpp:572
size_t getEnd() const
Get end vertex index.
Definition: gsHalfEdgeMesh.h:97
const Halfedge & getFirstHalfedge() const
Get first halfedge.
Definition: gsHalfEdgeMesh.hpp:502
std::vector< Chain > m_boundary
boundary chains
Definition: gsHalfEdgeMesh.h:538
size_t findVertex(const typename gsMesh< T >::gsVertexHandle &vertex) const
Finds the vertex that has the same coordinates (up to a tolerance) as vertex.
Definition: gsHalfEdgeMesh.h:707
T getShortestBoundaryDistanceBetween(size_t i, size_t j) const
Get distance between vertices The distance between i-th and j-th boundary vertex is returned...
Definition: gsHalfEdgeMesh.hpp:140
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
size_t getNumberOfInnerVertices() const
Get number of inner vertices The number of inner vertices of the triangle mesh is returned...
Definition: gsHalfEdgeMesh.hpp:69
size_t m_n
number of inner vertices in the mesh
Definition: gsHalfEdgeMesh.h:781
Class Representing a triangle mesh with 3D vertices.
Definition: gsMesh.h:31
std::vector< T > getCornerLengths(std::vector< index_t > &corners) const
Get boundary part lengths between corners A vector containing the numbers of the boundary corners ser...
Definition: gsHalfEdgeMesh.hpp:125
void appendPrevHalfedge(const Halfedge &prevHalfedge)
Appends halfedge at beginning of chain if possible.
Definition: gsHalfEdgeMesh.hpp:642
size_t getNumberOfVertices() const
Get number of vertices The number of vertices of the triangle mesh is returned.
Definition: gsHalfEdgeMesh.hpp:57
#define gsWarn
Definition: gsDebug.h:50
void sortVertices()
Creates ordering for vertices The vertices in m_vertices are not ordered. Therefore two index vectors...
Definition: gsHalfEdgeMesh.hpp:303
T getHalfedgeLength(const size_t originVertexIndex, const size_t endVertexIndex) const
Get halfedge length The length of the halfedge with origin and end vertex is returned. In case one of the input vertex indices is greater than the number of vertices, a error message is printed. Nothing is returned then.
Definition: gsHalfEdgeMesh.hpp:152
size_t getNumberOfVertices() const
Get number of vertices.
Definition: gsHalfEdgeMesh.h:407
#define gsInfo
Definition: gsDebug.h:43
short_t isTriangleVertex(size_t vertexIndex, size_t triangleIndex) const
Returns the index of a vertex contained in triangle The integers 0 for not contained 1 for being vert...
Definition: gsHalfEdgeMesh.hpp:164
T x() const
Definition: gsVertex.h:108
void appendNextHalfedge(const Halfedge &nextHalfedge, bool ignoreWarning=false)
Appends halfedge at end of chain if possible.
Definition: gsHalfEdgeMesh.hpp:657
T getLength() const
Get length of the chain.
Definition: gsHalfEdgeMesh.hpp:474
Boundary m_boundary
boundary of the mesh
Definition: gsHalfEdgeMesh.h:780
const gsMesh< T >::gsVertexHandle & getVertex(const size_t vertexIndex) const
Get vertex The vertex with index &#39;vertexIndex&#39; is returned.
Definition: gsHalfEdgeMesh.hpp:81
size_t getNumberOfTriangles() const
Get number of triangles The number of triangles of the triangle mesh is returned. ...
Definition: gsHalfEdgeMesh.hpp:63
bool isAppendableAsPrev(const Halfedge &previousHalfedge) const
Tells if halfedge is appendable at beginning.
Definition: gsHalfEdgeMesh.hpp:624
size_t getOrigin() const
Get origin vertex index.
Definition: gsHalfEdgeMesh.h:91
T y() const
Definition: gsVertex.h:110
bool isAppendableAsNext(const Halfedge &nextHalfedge) const
Tells if halfedge is appendable at end.
Definition: gsHalfEdgeMesh.hpp:633
bool isVertexContained(const size_t &vertexIndex) const
Tells if vertex is contained in chain.
Definition: gsHalfEdgeMesh.hpp:605
Class that maintains directed halfedges in any dimension.
Definition: gsHalfEdgeMesh.h:64
const std::list< size_t > getVertexIndices() const
Get list of vertex indices.
Definition: gsHalfEdgeMesh.hpp:522
bool isClosed() const
Tells whether chain is closed or not.
Definition: gsHalfEdgeMesh.hpp:454
size_t getNumberOfBoundaryVertices() const
Get number of boundary vertices The number of boundary vertices of the triangle mesh is returned...
Definition: gsHalfEdgeMesh.hpp:75
std::vector< T > getHalfedgeLengths() const
Get vector of halfedge lengths.
Definition: gsHalfEdgeMesh.hpp:486
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4488
bool isBoundaryVertex(const size_t internVertexIndex) const
Tells whether a vertex is a boundary vertex or not. The boundary is constructed and it is tested whet...
Definition: gsHalfEdgeMesh.hpp:250
gsHalfEdgeMesh(size_t nv=0)
Default constructor.
Definition: gsHalfEdgeMesh.h:544
size_t getGlobalVertexIndex(const size_t localVertexIndex, const size_t triangleIndex) const
Get vertex index for firts, second or third vertex of triangle Returns the vertex index of a vertex w...
Definition: gsHalfEdgeMesh.hpp:102
const std::list< Halfedge > findNonTwinHalfedges(const std::vector< Halfedge > &allHalfedges)
Finds halfedges without twin halfedge.
Definition: gsHalfEdgeMesh.hpp:387
gsHalfEdgeMesh is a gsMesh implementation that handles Halfedges
Definition: gsHalfEdgeMesh.h:46
std::vector< Halfedge > m_halfedges
vector of halfedges
Definition: gsHalfEdgeMesh.h:779
size_t getNumberOfVertices() const
Get number of vertices.
Definition: gsHalfEdgeMesh.hpp:465
T z() const
Definition: gsVertex.h:112
gsVertex class that represents a 3D vertex for a gsMesh.
Definition: gsVertex.h:26
T getShortestDistanceBetween(size_t i, size_t j, T precision) const
Get shortest distance between vertices.
Definition: gsHalfEdgeMesh.hpp:542
Class that maintains boundary of triangle mesh.
Definition: gsHalfEdgeMesh.h:378