G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsPeriodicStitch.hpp
Go to the documentation of this file.
1 
16 
17 namespace gismo
18 {
19 
20 /* Nested class Neighbourhood */
21 
22 template<class T>
23 std::vector<size_t> gsPeriodicStitch<T>::Neighbourhood::computeCorrections(const std::vector<size_t>& stitchIndices,
24  const LocalNeighbourhood& localNeighbourhood) const
25 {
26  auto indexIt = std::find(stitchIndices.begin(), stitchIndices.end(), localNeighbourhood.getVertexIndex());
27 
28  if(indexIt == stitchIndices.end()) // Not on the stitch, nothing to do.
29  {
30  return std::vector<size_t>();
31  }
32 
33  std::list<size_t> result;
34  std::list<size_t> neighbours = localNeighbourhood.getVertexIndicesOfNeighbours();
35 
36  if(indexIt == stitchIndices.begin()) // In the beginning of the stitch.
37  {
38  auto nextOnStitch = std::find(neighbours.begin(), neighbours.end(), *std::next(indexIt));
39  // (Assuming that the stitch has at least two vertices.)
40  for(auto it=nextOnStitch; it!=neighbours.end(); ++it)
41  result.push_back(*it);
42  }
43  else if(std::next(indexIt) == stitchIndices.end()) // In the end of the stitch.
44  {
45  auto prevOnStitch = std::find(neighbours.begin(), neighbours.end(), *std::prev(indexIt));
46  // (Again assuming the stitch to have at least two vertices.)
47  for(auto it=neighbours.begin(); it!=prevOnStitch; ++it)
48  result.push_back(*it);
49  }
50  else // In the middle of the stitch.
51  {
52  while(neighbours.front() != *std::next(indexIt))
53  {
54  neighbours.push_back(neighbours.front());
55  neighbours.pop_front();
56  }
57 
58  auto prevOnStitch = std::find(neighbours.begin(), neighbours.end(), *std::prev(indexIt));
59  for(auto it=neighbours.begin(); it!=prevOnStitch; ++it)
60  result.push_back(*it);
61  }
62 
63  // Other stitch vertices can still be present in the neighbourhood.
64  for(auto it=stitchIndices.begin(); it!=stitchIndices.end(); ++it)
65  result.remove(*it);
66 
67  std::vector<size_t> finalResult;
68  finalResult.reserve(result.size());
69  for(auto it=result.begin(); it!=result.end(); ++it)
70  finalResult.push_back(*it);
71 
72  return finalResult;
73 }
74 
75 template<class T>
77  const std::vector<size_t>& stitchIndices,
78  gsSparseMatrix<int>& corrections,
79  const size_t parametrizationMethod)
80  : gsParametrization<T>::Neighbourhood(meshInfo, parametrizationMethod)
81 {
82  // We re-do a little of the work done already in the constructor of the parent class.
83  // Alternatively, we could provide a constructor of the parent class setting m_basicInfos
84  // and do everything else here, much as we did when this was a part of the parent class.
85  // Cf., e.g., fcacc860ee28edd608e841af5aeb74dacc90e006 for a reference.
86 
87  index_t N = meshInfo.getNumberOfVertices();
88  corrections.resize(N, N);
89  corrections.setZero(); // important, otherwise you might end up with artifacts
90 
91  for(size_t i=1; i <= meshInfo.getNumberOfVertices(); i++)
92  {
93  LocalNeighbourhood localNeighbourhood = (i <= meshInfo.getNumberOfInnerVertices()) ?
94  LocalNeighbourhood(meshInfo, i) :
95  LocalNeighbourhood(meshInfo, i, 0);
96 
97  std::vector<size_t> corr = computeCorrections(stitchIndices, localNeighbourhood);
98 
99  for(auto it=corr.begin(); it!=corr.end(); ++it)
100  {
101  corrections(i-1, *it-1) = 1;
102  corrections(*it-1, i-1) = -1;
103  }
104  }
105 }
106 
107 template <class T>
109 {
110  calculate(this->m_options.getInt("parametrizationMethod"));
111 }
112 
113 template<class T>
114 void gsPeriodicStitch<T>::calculate(const size_t paraMethod)
115 {
116  size_t n = this->m_mesh.getNumberOfInnerVertices();
117  size_t N = this->m_mesh.getNumberOfVertices();
118 
119  Neighbourhood neighbourhood(this->m_mesh, m_stitchIndices, m_corrections, paraMethod);
120 
121  this->initParameterPoints();
122 
124  constructAndSolveEquationSystem(neighbourhood, n, N);
125 }
126 
127 template <class T>
129  const size_t n,
130  const size_t N)
131 {
132  std::vector<T> lambdas;
133  gsMatrix<T> LHS(N, N);
134  gsMatrix<T> RHS(N, 2);
135 
136  // prevent Valgrind warnings
137  LHS.setZero();
138  RHS.setZero();
139 
140  // interior points
141  for (size_t i = 0; i < n; i++)
142  {
143  lambdas = neighbourhood.getLambdas(i);
144  for (size_t j = 0; j < N; j++)
145  {
146  LHS(i, j) = ( i==j ? (T)(1) : -lambdas[j] );
147 
148  // If your neighbour is across the stitch, its contributions appear
149  // on the right hand-side multiplied by +1 or -1. Write the equations
150  // down if it is unclear. (-;
151  if(m_corrections(i, j) == 1)
152  RHS(i, 0) -= lambdas[j];
153  else if(m_corrections(i, j) == -1)
154  RHS(i, 0) += lambdas[j];
155  }
156  }
157 
158  // points on the lower and upper boundary
159  for (size_t i=n; i<N; i++)
160  {
161  LHS(i, i) = (T)(1);
162  RHS.row(i) = this->m_parameterPoints[i];
163  }
164 
165  // Solve the system and save the results.
166  gsEigen::PartialPivLU<typename gsMatrix<T>::Base> LU = LHS.partialPivLu();
167  gsMatrix<T> sol = LU.solve(RHS);
168  for (size_t i = 0; i < n; i++)
169  {
170  this->m_parameterPoints[i] << sol(i, 0), sol(i, 1);
171  }
172 }
173 
174 template<class T>
176 {
177  typedef typename gsMesh<T>::VertexHandle VertexHandle;
178  typedef typename gsParametrization<T>::Point2D Point2D;
179 
180  gsMesh<T> result;
181  for(size_t i=0; i<this->m_mesh.getNumberOfTriangles(); i++)
182  {
183  std::vector<size_t> vertices;
184  for(size_t j=1; j<=3; ++j)
185  {
186  vertices.push_back(this->m_mesh.getGlobalVertexIndex(j, i));
187  }
188  bool nearStitchTriangle = (edgeIsInCorrections(vertices[0]-1, vertices[1]-1) ||
189  edgeIsInCorrections(vertices[1]-1, vertices[2]-1) ||
190  edgeIsInCorrections(vertices[2]-1, vertices[0]-1));
191 
192  VertexHandle v[3];
193  for (size_t j = 1; j <= 3; ++j)
194  {
195  const Point2D& point = gsParametrization<T>::getParameterPoint(vertices[j-1]);
196  // The near-stitch triangles get their stitch vertices shifted by 1 to the left.
197  if( nearStitchTriangle && isOnStitch(vertices[j-1]) )
198  v[j - 1] = result.addVertex(point[0] + (T)(1), point[1]);
199  else
200  v[j - 1] = result.addVertex(point[0], point[1]);
201  }
202  result.addFace( v[0], v[1], v[2]);
203  }
204 
205  return result.cleanMesh();
206 }
207 
208 } // namespace gismo
Class that maintains parametrization This class Parametrization stores the mesh information and the t...
Definition: gsParametrization.h:46
Implementation of periodic Floater parametrization using a stitch. This class is an alternative to gs...
void calculate(const size_t paraMethod)
Definition: gsPeriodicStitch.hpp:114
Definition: gsPeriodicStitch.h:76
size_t getVertexIndex() const
Get vertex index.
Definition: gsParametrization.hpp:739
gsMesh< T > createUnfoldedFlatMesh() const
Definition: gsPeriodicStitch.hpp:175
gsSparseMatrix< int > m_corrections
Definition: gsPeriodicStitch.h:198
const Point2D & getParameterPoint(size_t vertexIndex) const
Get parameter point Returns the parameter point with given vertex index.
Definition: gsParametrization.hpp:157
Class that maintains the local neighbourhood properties.
Definition: gsParametrization.h:127
#define index_t
Definition: gsConfig.h:32
const index_t & getInt(const std::string &label) const
Reads value for option label from options.
Definition: gsOptionList.cpp:37
void compute()
Computes the periodic parametrization.
Definition: gsPeriodicStitch.hpp:108
size_t getNumberOfInnerVertices() const
Get number of inner vertices The number of inner vertices of the triangle mesh is returned...
Definition: gsHalfEdgeMesh.hpp:69
const std::list< size_t > getVertexIndicesOfNeighbours() const
Get vertex indices of neighbours.
Definition: gsParametrization.hpp:751
Class Representing a triangle mesh with 3D vertices.
Definition: gsMesh.h:31
const std::vector< size_t > m_stitchIndices
indices of the vertices on the stitch
Definition: gsPeriodicStitch.h:200
size_t getNumberOfVertices() const
Get number of vertices The number of vertices of the triangle mesh is returned.
Definition: gsHalfEdgeMesh.hpp:57
gsMesh & cleanMesh()
reorders the vertices of all faces of an .stl mesh, such that only 1 vertex is used instead of #(adja...
Definition: gsMesh.hpp:250
const std::vector< T > & getLambdas(const size_t i) const
Get vector of lambdas.
Definition: gsParametrization.hpp:279
void constructAndSolveEquationSystem(const Neighbourhood &neighbourhood, const size_t n, const size_t N)
Definition: gsPeriodicStitch.hpp:128
std::vector< size_t > computeCorrections(const std::vector< size_t > &stitchIndices, const LocalNeighbourhood &localNeighbourhood) const
Definition: gsPeriodicStitch.hpp:23
Neighbourhood(const gsHalfEdgeMesh< T > &meshInfo, const std::vector< size_t > &stitchIndices, gsSparseMatrix< int > &corrections, const size_t parametrizationMethod=2)
Definition: gsPeriodicStitch.hpp:76
A Point in T^d, with an index number.
Definition: gsPoint.h:26
bool edgeIsInCorrections(index_t beg, index_t end) const
Definition: gsPeriodicStitch.h:182
bool isOnStitch(size_t vertexIndex) const
Definition: gsPeriodicStitch.h:170
const gsHalfEdgeMesh< T > m_mesh
mesh information
Definition: gsParametrization.h:57
gsHalfEdgeMesh is a gsMesh implementation that handles Halfedges
Definition: gsHalfEdgeMesh.h:46
VectorType m_parameterPoints
parameter points
Definition: gsParametrization.h:58
gsVertex class that represents a 3D vertex for a gsMesh.
Definition: gsVertex.h:26