36 :
gsMesh<T>(mesh), m_precision(precision)
44 for (
size_t i = 0; i < this->m_face.size(); i++)
59 return this->m_vertex.size();
65 return this->m_face.size();
77 return m_boundary.getNumberOfVertices();
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]]));
98 return m_inverseSorting[findVertex(vertex)];
104 return m_inverseSorting[this->m_face[triangleIndex]->vertices[localVertexIndex-1]->getId()];
110 return m_boundary.getLength();
114 bool rangeCheck(
const std::vector<index_t> &corners,
const size_t minimum,
const size_t maximum)
116 for (std::vector<index_t>::const_iterator it = corners.begin(); it != corners.end(); it++)
118 if ((
size_t)*it < minimum || (size_t)*it > maximum)
127 GISMO_ASSERT(rangeCheck<T>(corners, 1, getNumberOfBoundaryVertices()),
"The corners must be <= number of boundary vertices.");
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++)
134 lengths.push_back(m_boundary.getDistanceBetween(corners[i], corners[(i + 1) % s]));
142 return m_boundary.getShortestDistanceBetween(i, j, m_precision);
148 return m_boundary.getHalfedgeLengths();
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.");
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();
166 if (vertexIndex > this->m_vertex.size())
168 gsWarn <<
"gsHalfEdgeMesh::isTriangleVertex: Vertex with vertex index " << vertexIndex
169 <<
" does not exist. There are only " << this->m_vertex.size() <<
" vertices.\n";
172 if (triangleIndex > getNumberOfTriangles())
174 gsWarn <<
"gsHalfEdgeMesh::isTriangleVertex: The " << triangleIndex
175 <<
"-th triangle does not exist. There are only " << getNumberOfTriangles() <<
" triangles.\n";
178 if (*(this->m_vertex[m_sorting[vertexIndex - 1]]) == *(this->m_face[triangleIndex]->vertices[0]))
180 if (*(this->m_vertex[m_sorting[vertexIndex - 1]]) == *(this->m_face[triangleIndex]->vertices[1]))
182 if (*(this->m_vertex[m_sorting[vertexIndex - 1]]) == *(this->m_face[triangleIndex]->vertices[2]))
188 const std::queue<typename gsHalfEdgeMesh<T>::Halfedge>
191 std::queue<Halfedge> oppositeHalfedges;
192 if (vertexIndex > this->m_vertex.size())
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;
198 else if (vertexIndex > m_n && innerVertex)
200 gsWarn <<
"gsHalfEdgeMesh::getOppositeHalfedges: Inner vertex with index 'vertexIndex' = " << vertexIndex
201 <<
"is not an inner vertex. There are only " << m_n <<
" inner vertices.\n";
205 for (
size_t i = 0; i < getNumberOfTriangles(); i++)
207 switch (isTriangleVertex(vertexIndex, i))
210 v3 = getGlobalVertexIndex(3, i);
211 v2 = getGlobalVertexIndex(2, i);
212 oppositeHalfedges.push(
Halfedge(v3, v2, getHalfedgeLength(v3, v2)));
215 v1 = getGlobalVertexIndex(1, i);
216 v3 = getGlobalVertexIndex(3, i);
217 oppositeHalfedges.push(
Halfedge(v1, v3, getHalfedgeLength(v1, v3)));
220 v2 = getGlobalVertexIndex(2, i);
221 v1 = getGlobalVertexIndex(1, i);
222 oppositeHalfedges.push(
Halfedge(v2, v1, getHalfedgeLength(v2, v1)));
229 return oppositeHalfedges;
235 size_t numVertices = getNumberOfVertices();
237 for( ; i<numVertices; i++)
244 return sorted ? i+1 : i;
246 return std::numeric_limits<size_t>::max();
252 if (internVertexIndex > this->m_vertex.size() - 1)
254 gsWarn <<
"gsHalfEdgeMesh::isBoundaryVertex: Vertex with intern vertex index = " << internVertexIndex
255 <<
" does not exist. There are only " << this->m_vertex.size() <<
" vertices.\n";
259 return m_boundary.isVertexContained(internVertexIndex);
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)
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;
275 if (numberOfHalfedge == 1)
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());
283 if (numberOfHalfedge == 2)
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());
291 if (numberOfHalfedge == 3)
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());
307 size_t numberOfInnerVerticesFound = 0;
308 m_sorting.resize(this->m_vertex.size(), 0);
309 m_inverseSorting.resize(this->m_vertex.size(), 0);
311 for (
size_t i = 0; i != this->m_vertex.size(); ++i)
313 if (!isBoundaryVertex(i))
315 numberOfInnerVerticesFound++;
316 m_sorting[numberOfInnerVerticesFound - 1] = i;
317 m_inverseSorting[i] = numberOfInnerVerticesFound;
321 std::list<size_t> boundaryVertices = m_boundary.getVertexIndices();
322 for (
size_t i = 0; i < getNumberOfBoundaryVertices(); i++)
324 m_sorting[m_n + i] = boundaryVertices.front();
325 m_inverseSorting[boundaryVertices.front()] = m_n + i + 1;
326 boundaryVertices.pop_front();
337 while(!unsortedNonTwinHalfedges.empty())
341 component.appendNextHalfedge(unsortedNonTwinHalfedges.front());
342 unsortedNonTwinHalfedges.pop_front();
343 std::queue<Halfedge> nonFittingHalfedges;
344 while (!unsortedNonTwinHalfedges.empty())
346 if (component.isAppendableAsNext(unsortedNonTwinHalfedges.front()))
348 component.appendNextHalfedge(unsortedNonTwinHalfedges.front());
349 unsortedNonTwinHalfedges.pop_front();
350 while (!nonFittingHalfedges.empty())
352 unsortedNonTwinHalfedges.push_back(nonFittingHalfedges.front());
353 nonFittingHalfedges.pop();
356 else if (component.isAppendableAsPrev(unsortedNonTwinHalfedges.front()))
358 component.appendPrevHalfedge(unsortedNonTwinHalfedges.front());
359 unsortedNonTwinHalfedges.pop_front();
360 while (!nonFittingHalfedges.empty())
362 unsortedNonTwinHalfedges.push_back(nonFittingHalfedges.front());
363 nonFittingHalfedges.pop();
368 nonFittingHalfedges.push(unsortedNonTwinHalfedges.front());
369 unsortedNonTwinHalfedges.pop_front();
376 while(!nonFittingHalfedges.empty())
378 unsortedNonTwinHalfedges.push_back( nonFittingHalfedges.front() );
379 nonFittingHalfedges.pop();
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)
395 queue0.push(allHalfedges[i]);
397 while (!(queue0.empty() && queue1.empty()))
399 if (actualQueue == 0)
401 nonTwinHalfedges.push_back(queue0.front());
403 while (!queue0.empty())
405 if (nonTwinHalfedges.back().isTwin(queue0.front()))
408 nonTwinHalfedges.pop_back();
409 while (!queue0.empty())
411 queue1.push(queue0.front());
417 queue1.push(queue0.front());
423 else if (actualQueue == 1)
425 nonTwinHalfedges.push_back(queue1.front());
427 while (!queue1.empty())
429 if (nonTwinHalfedges.back().isTwin(queue1.front()))
432 nonTwinHalfedges.pop_back();
433 while (!queue1.empty())
435 queue0.push(queue1.front());
441 queue0.push(queue1.front());
448 return nonTwinHalfedges;
456 if (m_chainedHalfedges.empty())
458 gsWarn <<
"gsHalfEdgeMesh<T>::Chain::isClosed: The chain does not store any halfedges yet.\n";
461 return (m_chainedHalfedges.front().getOrigin() == m_chainedHalfedges.back().getEnd());
467 if (this->isClosed())
468 return m_chainedHalfedges.size();
470 return m_chainedHalfedges.size() + 1;
477 for (
typename std::list<Halfedge>::const_iterator it = m_chainedHalfedges.begin();
478 it != m_chainedHalfedges.end(); ++it)
480 length += it->getLength();
490 gsWarn <<
"gsHalfEdgeMesh::Chain::getHalfedgeLengths: The chain does not store any halfedges yet.\n";
492 std::vector<T> lengths;
493 for (
typename std::list<Halfedge>::const_iterator it = m_chainedHalfedges.begin();
494 it != m_chainedHalfedges.end(); ++it)
496 lengths.push_back(it->getLength());
506 gsInfo <<
"gsHalfEdgeMesh::Chain::getFirstHalfedge: The chain does not store any halfedges yet.\n";
508 return m_chainedHalfedges.front();
516 gsInfo <<
"gsHalfEdgeMesh::Chain::getLastHalfedge: The chain does not store any halfedges yet.\n";
518 return m_chainedHalfedges.back();
526 gsWarn <<
"gsHalfEdgeMesh::Chain::getVertexIndices: The chain does not store any halfedges yet.\n";
528 std::list<size_t> vertexIndices;
529 for (
typename std::list<Halfedge>::const_iterator it = m_chainedHalfedges.begin();
530 it != m_chainedHalfedges.end(); ++it)
532 vertexIndices.push_back(it->getOrigin());
534 if (m_chainedHalfedges.size() == 1 || !(this->isClosed()))
536 vertexIndices.push_back(m_chainedHalfedges.back().getEnd());
538 return vertexIndices;
546 gsWarn <<
"gsHalfEdgeMesh::Chain::getShortestDistanceBetween: The chain does not store any halfedges yet.\n";
551 gsInfo <<
"gsHalfEdgeMesh::Chain::getShortestDistanceBetween: FirstIndex: " << i <<
" and second index: "
553 <<
" must be positiv integers smaller than the number of points of the chain, which is "
557 if (i > j) std::swap(i, j);
559 std::vector<T> l = this->getHalfedgeLengths();
560 for (
size_t z = i - 1; z < j - 1; z++)
564 if (this->isClosed() && (this->getLength() - distance < distance - precision))
566 distance = this->getLength() -
distance;
576 gsWarn <<
"gsHalfEdgeMesh::Chain::getDistanceBetween: The chain does not store any halfedges yet.\n";
581 gsInfo <<
"gsHalfEdgeMesh::Chain::getDistanceBetween: FirstIndex: " << i <<
" and second index: "
583 <<
" must be positiv integers smaller than the number of points of the chain, which is "
587 bool ordered = (i < j);
588 if (!ordered) std::swap(i, j);
590 std::vector<T> l = this->getHalfedgeLengths();
591 for (
size_t z = i - 1; z < j - 1; z++)
595 if (this->isClosed() && !ordered)
597 distance = this->getLength() -
distance;
600 gsWarn <<
"gsHalfEdgeMesh::Chain::getDistanceBetween: The chain is supposed to be closed in case the input is not ordered.\n";
609 gsWarn <<
"gsHalfEdgeMesh::Chain::isVertexContained: The chain does not store any halfedges yet.\n";
612 for (
typename std::list<Halfedge>::const_iterator it = m_chainedHalfedges.begin();
613 it != m_chainedHalfedges.end(); ++it)
615 if (it->getOrigin() == vertexIndex)
618 if (!(this->isClosed()) && this->getLastHalfedge().getEnd() == vertexIndex)
626 if (m_chainedHalfedges.empty())
629 return m_chainedHalfedges.front().isNext(previousHalfedge);
635 if (m_chainedHalfedges.empty())
638 return m_chainedHalfedges.back().isPrev(nextHalfedge);
644 if (!this->isAppendableAsPrev(prevHalfedge))
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";
652 m_chainedHalfedges.push_front(prevHalfedge);
660 if (!ignoreWarning && !isAppendableAsNext(nextHalfedge))
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";
668 m_chainedHalfedges.push_back(nextHalfedge);
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 <j> 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 'vertexIndex' 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