Visual Computing Library
Loading...
Searching...
No Matches
mesh_pos.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_SPACE_COMPLEX_MESH_POS_H
24#define VCL_SPACE_COMPLEX_MESH_POS_H
25
26#include <vclib/mesh/components/adjacent_faces.h>
27#include <vclib/mesh/elements/face.h>
28
29namespace vcl {
30
47template<face::HasAdjacentFaces FaceType>
49{
50 const FaceType* mFace = nullptr;
51
52 const typename FaceType::VertexType* mVertex = nullptr;
53
54 short mEdge = -1;
55
56public:
57 using VertexType = FaceType::VertexType;
58
62 MeshPos() = default;
63
64 MeshPos(const FaceType* f, short e) : mFace(f), mEdge(e)
65 {
66 if (f != nullptr)
67 mVertex = f->vertex(e);
68 assert(isValid(mFace, mVertex, mEdge));
69 }
70
71 MeshPos(const FaceType* f, const VertexType* v) : mFace(f), mVertex(v)
72 {
73 for (uint i = 0; i < f->vertexNumber(); i++)
74 if (f->vertex(i) == v)
75 mEdge = i;
76 assert(isValid(mFace, mVertex, mEdge));
77 }
78
89 MeshPos(const FaceType* f, const VertexType* v, short e) :
90 mFace(f), mVertex(v), mEdge(e)
91 {
92 assert(isValid(mFace, mVertex, mEdge));
93 }
94
108 static bool isValid(const FaceType* f, const VertexType* v, short e)
109 {
110 if (f == nullptr || v == nullptr || e < 0)
111 return false;
112 if (!comp::isAdjacentFacesAvailableOn(*f))
113 return false;
114 return (ushort) e < f->vertexNumber() &&
115 (v == f->vertex(e) || v == f->vertexMod(e + 1));
116 }
117
118 const FaceType* face() const { return mFace; }
119
120 const VertexType* vertex() const { return mVertex; }
121
122 short edge() const { return mEdge; }
123
124 const FaceType* adjFace() const { return mFace->adjFace(mEdge); }
125
126 const VertexType* adjVertex() const
127 {
128 MeshPos<FaceType> tmpPos = *this;
129 tmpPos.flipVertex();
130 return tmpPos.vertex();
131 }
132
133 short adjEdge() const
134 {
135 MeshPos<FaceType> tmpPos = *this;
136 tmpPos.flipEdge();
137 return tmpPos.edge();
138 }
139
144 bool isValid() const { return isValid(mFace, mVertex, mEdge); }
145
151 bool isNull() const
152 {
153 return mFace == nullptr || mVertex == nullptr || mEdge < 0;
154 }
155
163 bool isEdgeOnBorder() const { return mFace->adjFace(mEdge) == nullptr; }
164
173 bool isCCWOriented() const { return mFace->vertex(mEdge) == mVertex; }
174
186 bool flipFace()
187 {
188 const FaceType* nf = mFace->adjFace(mEdge);
189 if (nf != nullptr) {
190 mEdge = nf->indexOfAdjFace(mFace);
191 mFace = nf;
192 return true;
193 }
194 else {
195 return false;
196 }
197 }
198
204 {
205 if (mFace->vertexMod(mEdge) == mVertex) {
206 mVertex = mFace->vertexMod(mEdge + 1);
207 }
208 else {
209 mVertex = mFace->vertexMod(mEdge);
210 }
211 }
212
217 void flipEdge()
218 {
219 if (mFace->vertexMod(mEdge + 1) == mVertex) {
220 mEdge = (mEdge + 1) % (short) mFace->vertexNumber();
221 }
222 else {
223 short n = mFace->vertexNumber();
224 mEdge = ((mEdge - 1) % n + n) %
225 n; // be sure to get the right index of the previous edge
226 }
227 }
228
241 {
242 flipEdge();
243 flipFace();
244 }
245
255 {
257 do {
259 } while (*this != startPos && !isEdgeOnBorder());
260 return (*this != startPos);
261 }
262
272 {
273 bool onBorder = false;
274 uint count = countAdjacentFacesToV(onBorder);
275 // if we visited a border, it means that we visited the all faces
276 // adjacent to v twice to reach the same starting MeshPos.
277 if (onBorder)
278 count /= 2;
279 return count;
280 }
281
282 bool operator==(const MeshPos& op) const
283 {
284 return mFace == op.mFace && mVertex == op.mVertex && mEdge == op.mEdge;
285 }
286
287 bool operator!=(const MeshPos& op) const { return !(*this == op); }
288
289 bool operator<(const MeshPos& op) const
290 {
291 if (mFace == op.mFace) {
292 if (mEdge == op.mEdge)
293 return mVertex < op.mVertex;
294 else
295 return mEdge < op.mEdge;
296 }
297 else {
298 return mFace < op.mFace;
299 }
300 }
301
302private:
303 uint countAdjacentFacesToV(bool& onBorder) const
304 {
305 uint count = 0;
306 onBorder = false;
307 // start from this MeshPos
308 MeshPos<FaceType> mp = *this;
309 do {
310 // go to the next edge in the star of v (if face is on border, will
311 // change just edge)
312 mp.nextEdgeAdjacentToV();
313 ++count;
314 // if we are visiting a border, it means that we will start to
315 // navigate in the opposite sense as we were before.
316 if (mp.isEdgeOnBorder()) // flag that we visited a border
317 onBorder = true;
318 }
319 // we end when we will reach the same pos (same triplet f-v-e) of start
320 while (mp != *this);
321 return count;
322 }
323};
324
325} // namespace vcl
326
327#endif // VCL_SPACE_COMPLEX_MESH_POS_H
The MeshPos class describes a "Position in a Mesh" that can be identified with a triplet of Face-Vert...
Definition mesh_pos.h:49
uint numberOfAdjacentFacesToV() const
Returns the number of adjacent faces to the current vertex of this MeshPos. This works also for verti...
Definition mesh_pos.h:271
MeshPos()=default
Empty constructor that creates a null (invalid) MeshPos.
bool isEdgeOnBorder() const
Returns true if the current edge of this MeshPos is on a border. To check if is on border,...
Definition mesh_pos.h:163
void flipVertex()
Moves this MeshPos to the vertex adjacent to the current vertex that shares the same face and the sam...
Definition mesh_pos.h:203
bool isCCWOriented() const
Returns true if the current vertex of the MeshPos corresponts to the first vertex of the current edge...
Definition mesh_pos.h:173
MeshPos(const FaceType *f, const VertexType *v, short e)
Constructor that creates a MeshPos with the given facem vertex and edge. The given triplet must descr...
Definition mesh_pos.h:89
static bool isValid(const FaceType *f, const VertexType *v, short e)
Helper function to check if a MeshPos is valid, that is if:
Definition mesh_pos.h:108
bool nextEdgeOnBorderAdjacentToV()
Moves the MeshPos to the next edge on border that is adjacent to the current vertex of the MeshPos....
Definition mesh_pos.h:254
bool flipFace()
Moves this MeshPos to the face adjacent to the current face that shares the same vertex and the same ...
Definition mesh_pos.h:186
bool isNull() const
Returns true if this is null, non initialized, MeshPos. The result of this function is different from...
Definition mesh_pos.h:151
void nextEdgeAdjacentToV()
Moves this MeshPos to the next edge that is adjacent to the current vertex of the MeshPos....
Definition mesh_pos.h:240
void flipEdge()
Moves this MeshPos to the edge adjacent to the current edge that shares the same face and the same ve...
Definition mesh_pos.h:217
bool isValid() const
Returns true if this MeshPos is valid.
Definition mesh_pos.h:144
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43