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