G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsSolidHeVertex.h
Go to the documentation of this file.
1 
14 #pragma once
15 
17 #include <gsCore/gsLinearAlgebra.h>
18 
19 namespace gismo {
20 
21 template <class T> class gsSolidHalfEdge;
22 
23 template <class T>
24 class gsSolidHeVertex : public gsSolidElement<T>
25 {
26 public:
27  # define Eigen gsEigen
28  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
29 # undef Eigen
30  typedef T scalar_t;
31  typedef gsSolidElement<T> SolidElement;
32  typedef typename SolidElement::gsSolidHeVertexHandle gsSolidHeVertexHandle;
33  typedef typename SolidElement::gsSolidHalfEdgeHandle gsSolidHalfEdgeHandle;
34  typedef typename SolidElement::gsSolidHalfFaceHandle gsSolidHalfFaceHandle;
35 
36 // Data members
37 public:
38  gsVector3d<T> coords; // TODO: should be inherited instead, makes it more naturally
39  // halfedge out of this vertex
40  gsSolidHalfEdgeHandle hed;
41 
42 public:
43  gsSolidHeVertex(scalar_t x, scalar_t y, scalar_t z = 0) : SolidElement(), coords(x,y,z), hed(0) { }
44  gsSolidHeVertex(scalar_t x, scalar_t y, scalar_t z, int i) : SolidElement(i), coords(x,y,z), hed(0) { }
45 
46  virtual ~gsSolidHeVertex(){ }
47 
49  void move(scalar_t dx, scalar_t dy, scalar_t dz) {coords.x() += dx;coords.y() += dy;coords.z() += dz;}
50 
51 //--------------------------------------------------------------------------
52 // const members
53 public:
54  gsVector3d<T> getCoordinate() const {return coords;}
55  T x () const { return coords(0); }
56  T y () const { return coords(1); }
57  T z () const { return coords(2); }
58 
59  std::ostream &print(std::ostream &os) const;
60 
62  std::vector<gsSolidHalfFaceHandle> getHalfFaces() const;
63 
65  gsSolidHalfEdgeHandle getHalfEdge(gsSolidHeVertexHandle anotherVertex) const;
66 
68  bool hasHalfEdge(gsSolidHeVertexHandle anotherVertex) const;
69 
71  std::vector< gsSolidHalfFaceHandle > getFacesContaining2Vertices(gsSolidHeVertexHandle anotherVertex, bool const & IsBoundaryHalfEdge=false) const;
72 
74  gsSolidHalfEdgeHandle getHalfEdgeOnFace(gsSolidHalfFaceHandle f, bool dest);
75 
77  std::vector<gsSolidHalfEdgeHandle> halfEdges() const;
78 
81  bool isEquiv(gsSolidHeVertexHandle other, T tol) const
82  { using std::abs;if ( abs(x()-other->x())<=tol && abs(y()-other->y())<=tol && abs(z()-other->z())<=tol ) return true; return false; }
83 };
84 
85 //=============================================================================
86 // SOURCE
87 //=============================================================================
88 template <class T>
89 std::ostream &gsSolidHeVertex<T>::print(std::ostream &os) const
90 {
91  os<<"Vertex " << this->getId() << "( "<<coords.x() << " " << coords.y() << " " << coords.z() << " )\n";
92  return os;
93 }
94 
95 template <class T>
96 std::vector<typename gsSolidHeVertex<T>::gsSolidHalfFaceHandle> gsSolidHeVertex<T>::getHalfFaces() const
97 {
98  // See gsSolid<T>::getHEwrtTwoVertexIDs for algorithm explaination
99  std::vector< gsSolidHalfFaceHandle > faceList;
100  gsSolidHalfEdgeHandle he1 = hed;
101  gsSolidHalfEdgeHandle instant_he = he1;
102  do
103  {
104  faceList.push_back(instant_he->face);
105  instant_he = instant_he->prev->mate;
106  } while (instant_he!= he1);
107  return faceList;
108 }
109 
110 template <class T>
111 typename gsSolidHeVertex<T>::gsSolidHalfEdgeHandle gsSolidHeVertex<T>::getHalfEdge(gsSolidHeVertexHandle anotherVertex) const
112 {
113  // Theoretical background: ID1: the current vertex, ID2: = anotherVertex. Let he1 is the HE emanating from ID1, then he1->prev and he1 are the two HEs of 1 face containing ID1.
114  // Furthermore: he1->prev->mate and he1->prev->mate->pre are the two HEs of the adjacent face containing ID1 in a CCW fashion.
115  // Continue to do that way, we can access all HEs emanating or shooting at ID1
116  const gsSolidHalfEdgeHandle he1 = hed;
117  gsSolidHalfEdgeHandle instant_he = he1;
118  do
119  {
120  // check if target of instant_he is ID2
121  if (instant_he->target()==anotherVertex)
122  return instant_he;
123  instant_he = instant_he->prev->mate;
124  } while (instant_he!=he1);
125 
126  GISMO_ERROR("ERROR:gsSolidHeVertex.h: No HE is found while it is supposed to be existent");
127 }
128 
129 template <class T>
130 bool gsSolidHeVertex<T>::hasHalfEdge(gsSolidHeVertexHandle anotherVertex) const
131 {
132  gsSolidHalfEdgeHandle he1 = hed;
133  gsSolidHalfEdgeHandle instant_he = he1;
134  do
135  {
136  if (instant_he->target()==anotherVertex) {return true;};
137  instant_he = instant_he->prev->mate;
138  } while (instant_he!=he1);
139  return false;
140 }
141 
142 template <class T>
143 std::vector< typename gsSolidHeVertex<T>::gsSolidHalfFaceHandle >
144 // *isBoundaryHalfEdge* = is an existing half-edge
145 gsSolidHeVertex<T>::getFacesContaining2Vertices(gsSolidHeVertexHandle anotherVertex, bool const & IsBoundaryHalfEdge) const
146 {
147  std::vector<gsSolidHalfFaceHandle> faceList;
148  if (IsBoundaryHalfEdge)
149  {
150  gsSolidHalfEdgeHandle he = getHalfEdge(anotherVertex);
151  // as this is a boundary edge, there are exactly two faces incident to the edge
152  faceList.push_back(he->face);
153  faceList.push_back(he->mate->face);
154  }
155  else
156  {
157  // as this is NOT a boundary edge, there are only ONE face containing the edge
158  std::vector<gsSolidHalfFaceHandle> faceList1;
159  std::vector<gsSolidHalfFaceHandle> faceList2;
160  faceList1 = getHalfFaces();
161  faceList2 = anotherVertex->getHalfFaces();
162  // find intersection of faceList and faceList2
163  for (unsigned i=0;i!=faceList1.size();i++)
164  {
165  for (unsigned j=0;j!=faceList2.size();j++)
166  {
167  if (faceList1[i]==faceList2[j]) {faceList.push_back(faceList1[i]); break;};
168  };
169  };
170 
171  };
172  return faceList;
173 }
174 
175 template<class T>
176 typename gsSolidHeVertex<T>::gsSolidHalfEdgeHandle gsSolidHeVertex<T>::getHalfEdgeOnFace(typename gsSolidHeVertex<T>::gsSolidHalfFaceHandle f, bool dest)
177 {
178  gsSolidHalfEdgeHandle currentEdge = hed;
179  while(1)
180  {
181  if(!dest && currentEdge->face == f) return currentEdge;
182  currentEdge = currentEdge->mate;
183  if(dest && currentEdge->face == f) return currentEdge;
184  currentEdge = currentEdge->next;
185  assert(currentEdge != hed); // didn't find the face
186  }
187 }
188 
189 template<class T>
190 std::vector<typename gsSolidHeVertex<T>::gsSolidHalfEdgeHandle> gsSolidHeVertex<T>::halfEdges() const
191 {
192  gsSolidHalfEdgeHandle he1 = hed;
193  gsSolidHalfEdgeHandle instant_he = he1;
194  std::vector<gsSolidHalfEdgeHandle> heSet;
195  do
196  {
197  heSet.push_back(instant_he);
198  instant_he = instant_he->prev->mate;
199  } while (instant_he!=he1);
200  return heSet;
201 }
202 
203 } // namespace gismo
204 
205 
Provides gsSolidElement class - interface for an element (vertex, edge or face) of a solid...
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
This is the main header file that collects wrappers of Eigen for linear algebra.
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4488