G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsParametrization.hpp
Go to the documentation of this file.
1
15#include <gsIO/gsOptionList.h>
19
20namespace gismo
21{
22
23template<class T>
24bool gsParametrization<T>::rangeCheck(const std::vector<index_t> &corners, const size_t minimum, const size_t maximum)
25{
26 for (std::vector<index_t>::const_iterator it = corners.begin(); it != corners.end(); it++)
27 {
28 if ((size_t)*it < minimum || (size_t)*it > maximum)
29 { return false; }
30 }
31 return true;
32}
33
34template<class T>
36{
37 gsOptionList opt;
38 opt.addInt("boundaryMethod", "boundary methodes: {1:chords, 2:corners, 3:smallest, 4:restrict, 5:opposite, 6:distributed}", 4);
39 opt.addInt("parametrizationMethod", "parametrization methods: {1:shape, 2:uniform, 3:distance}", 1);
40 std::vector<index_t> corners;
41 opt.addMultiInt("corners", "vector for corners", corners);
42 opt.addReal("range", "in case of restrict or opposite", 0.1);
43 opt.addInt("number", "number of corners, in case of corners", 4);
44 opt.addReal("precision", "precision to calculate", 1E-8);
45 return opt;
46}
47
48template<class T>
49gsParametrization<T>::gsParametrization(const gsMesh<T> &mesh, const gsOptionList & list) : m_mesh(mesh)
50{
51 m_options.update(list, gsOptionList::addIfUnknown);
52}
53
54template<class T>
55void gsParametrization<T>::calculate(const size_t boundaryMethod,
56 const size_t paraMethod,
57 const std::vector<index_t> &cornersInput,
58 const T rangeInput,
59 const size_t numberInput)
60{
61 GISMO_ASSERT(boundaryMethod >= 1 && boundaryMethod <= 6,
62 "The boundary method " << boundaryMethod << " is not valid.");
63 GISMO_ASSERT(paraMethod >= 1 && paraMethod <= 3, "The parametrization method " << paraMethod << " is not valid.");
64 size_t n = m_mesh.getNumberOfInnerVertices();
65 size_t N = m_mesh.getNumberOfVertices();
66 size_t B = m_mesh.getNumberOfBoundaryVertices();
67 Neighbourhood neighbourhood(m_mesh, paraMethod);
68
69 T w = 0;
70 std::vector<T> halfedgeLengths = m_mesh.getBoundaryChordLengths();
71 std::vector<index_t> corners;
72 std::vector<T> lengths;
73
74 switch (boundaryMethod)
75 {
76 case 1:
77 m_parameterPoints.reserve(n + B);
78 for (size_t i = 1; i <= n + 1; i++)
79 {
80 m_parameterPoints.push_back(Point2D(0, 0, i));
81 }
82 for (size_t i = 0; i < B - 1; i++)
83 {
84 w += halfedgeLengths[i] * (T(1) / m_mesh.getBoundaryLength()) * (T)(4);
85 m_parameterPoints.push_back(Neighbourhood::findPointOnBoundary(w, n + i + 2));
86 }
87 break;
88 case 2:
89 corners = cornersInput;
90 goto case6;
91 case 3:
92 case 4:
93 case 5:
94 case 6: // N
95 { case6:
96 if (boundaryMethod != 2)
97 corners = neighbourhood.getBoundaryCorners(boundaryMethod, rangeInput, numberInput);
98
99 m_parameterPoints.reserve(N);
100 for (size_t i = 1; i <= N; i++)
101 {
102 m_parameterPoints.push_back(Point2D(0, 0, i));
103 }
104
105 lengths = m_mesh.getCornerLengths(corners);
106 m_parameterPoints[n + corners[0] - 1] = Point2D(0, 0, n + corners[0]);
107
108 for (size_t i = corners[0] + 1; i < corners[0] + B; i++)
109 {
110 w += halfedgeLengths[(i - 2) % B]
111 / findLengthOfPositionPart(i > B ? i - B : i, B, corners, lengths);
112 m_parameterPoints[(n + i - 1) > N - 1 ? n + i - 1 - B : n + i - 1] =
113 Neighbourhood::findPointOnBoundary(w, n + i > N ? n + i - B : n + i);
114 }
115 break;
116 }
117 default:
118 GISMO_ERROR("boundaryMethod not valid: " << boundaryMethod);
119 }
120
121 constructAndSolveEquationSystem(neighbourhood, n, N);
122}
123
124template<class T>
126 const size_t n,
127 const size_t N)
128{
129 gsMatrix<T> A;
130 A.resize(n, n);
131 std::vector<T> lambdas;
132 gsVector<T> b1(n), b2(n);
133 b1.setZero(); b2.setZero();
134
135 for (size_t i = 0; i < n; i++)
136 {
137 lambdas = neighbourhood.getLambdas(i);
138 for (size_t j = 0; j < n; j++)
139 {
140 A(i, j) = ( i==j ? (T)(1) : -lambdas[j] );
141 }
142
143 for (size_t j = n; j < N; j++)
144 {
145 b1(i) += (lambdas[j]) * (m_parameterPoints[j][0]);
146 b2(i) += (lambdas[j]) * (m_parameterPoints[j][1]);
147 }
148 }
149
150 gsVector<T> u(n), v(n);
151 gsEigen::PartialPivLU<typename gsMatrix<T>::Base> LU = A.partialPivLu();
152 u = LU.solve(b1);
153 v = LU.solve(b2);
154
155 for (size_t i = 0; i < n; i++)
156 m_parameterPoints[i] << u(i), v(i);
157}
158
159template<class T>
161{
162 return m_parameterPoints[vertexIndex - 1];
163}
164
165template<class T>
167{
168 gsMatrix<T> m(2, m_mesh.getNumberOfVertices());
169 for (size_t i = 1; i <= m_mesh.getNumberOfVertices(); i++)
170 {
171 m.col(i - 1) << this->getParameterPoint(i)[0], this->getParameterPoint(i)[1];
172 }
173 return m;
174}
175
176template<class T>
178{
179 gsMatrix<T> m(3, m_mesh.getNumberOfVertices());
180 for (size_t i = 1; i <= m_mesh.getNumberOfVertices(); i++)
181 {
182 m.col(i - 1) << m_mesh.getVertex(i)->x(), m_mesh.getVertex(i)->y(), m_mesh.getVertex(i)->z();
183 }
184 return m;
185}
186
187template<class T>
189{
190 gsMesh<T> mesh;
191 mesh.reserve(3 * m_mesh.getNumberOfTriangles(), m_mesh.getNumberOfTriangles(), 0);
192 for (size_t i = 0; i < m_mesh.getNumberOfTriangles(); i++)
193 {
194 typename gsMesh<T>::VertexHandle v[3];
195 for (size_t j = 1; j <= 3; ++j)
196 {
197 v[j - 1] = mesh.addVertex(getParameterPoint(m_mesh.getGlobalVertexIndex(j, i))[0],
198 getParameterPoint(m_mesh.getGlobalVertexIndex(j, i))[1]);
199 }
200 mesh.addFace(v[0], v[1], v[2]);
201 }
202 return mesh.cleanMesh();
203}
204
205
206template <class T>
207void gsParametrization<T>::writeTexturedMesh(std::string filename) const
208{
209 gsMatrix<T> params(2, m_mesh.numVertices());
210
211 for(size_t i=0; i<m_mesh.numVertices(); i++)
212 {
213 size_t index = m_mesh.unsorted(i);
214 params.col(i) = getParameterPoint(index).transpose();
215 }
216 gsWriteParaview(m_mesh, filename, params);
217}
218
219template<class T>
221{
222 m_options.update(list, gsOptionList::addIfUnknown);
223 return *this;
224}
225
226template<class T>
228{
229 calculate(m_options.getInt("boundaryMethod"),
230 m_options.getInt("parametrizationMethod"),
231 m_options.getMultiInt("corners"),
232 m_options.getReal("range"),
233 m_options.getInt("number"));
234}
235
236template<class T>
238 const size_t numberOfPositions,
239 const std::vector<index_t> &bounds,
240 const std::vector<T> &lengths)
241{
242 GISMO_UNUSED(numberOfPositions);
243 GISMO_ASSERT(1 <= position && position <= numberOfPositions, "The position " << position
244 << " is not a valid input. There are only " << numberOfPositions << " possible positions.");
245 GISMO_ASSERT(rangeCheck(bounds, 1, numberOfPositions), "The bounds are not a valid input. They have to be out of the possible positions, which only are "
246 << numberOfPositions << ". ");
247 size_t numberOfBounds = bounds.size();
248 size_t s = lengths.size();
249 if (position > (size_t)bounds[numberOfBounds - 1] || position <= (size_t)bounds[0])
250 return lengths[s - 1];
251 for (size_t i = 0; i < numberOfBounds; i++)
252 {
253 if (position - (size_t)bounds[0] + 1 > (size_t)bounds[i] - (size_t)bounds[0] + 1
254 && position - (size_t)bounds[0] + 1 <= (size_t)bounds[(i + 1) % numberOfBounds] - (size_t)bounds[0] + 1)
255 return lengths[i];
256 }
257 return 0;
258}
259
260
261//******************************************************************************************
262//******************************* nested class Neighbourhood *******************************
263//******************************************************************************************
264
265template<class T>
266gsParametrization<T>::Neighbourhood::Neighbourhood(const gsHalfEdgeMesh<T> & meshInfo, const size_t parametrizationMethod) : m_basicInfos(meshInfo)
267{
268 m_localParametrizations.reserve(meshInfo.getNumberOfInnerVertices());
269 for(size_t i=1; i <= meshInfo.getNumberOfInnerVertices(); i++)
270 {
271 m_localParametrizations.push_back(LocalParametrization(meshInfo, LocalNeighbourhood(meshInfo, i), parametrizationMethod));
272 }
273
274 m_localBoundaryNeighbourhoods.reserve(meshInfo.getNumberOfVertices() - meshInfo.getNumberOfInnerVertices());
275 for(size_t i=meshInfo.getNumberOfInnerVertices()+1; i<= meshInfo.getNumberOfVertices(); i++)
276 {
277 m_localBoundaryNeighbourhoods.push_back(LocalNeighbourhood(meshInfo, i, 0));
278 }
279}
280
281template<class T>
282const std::vector<T>& gsParametrization<T>::Neighbourhood::getLambdas(const size_t i) const
283{
284 return m_localParametrizations[i].getLambdas();
285}
286
287template<class T>
288const std::vector<index_t> gsParametrization<T>::Neighbourhood::getBoundaryCorners(const size_t method, const T range, const size_t number) const
289{
290 std::vector<std::pair<T , size_t> > angles;
291 std::vector<index_t> corners;
292 angles.reserve(m_localBoundaryNeighbourhoods.size());
293 for(typename std::vector<LocalNeighbourhood>::const_iterator it=m_localBoundaryNeighbourhoods.begin(); it!=m_localBoundaryNeighbourhoods.end(); it++)
294 {
295 angles.push_back(std::pair<T , size_t>(it->getInnerAngle(), it->getVertexIndex() - m_basicInfos.getNumberOfInnerVertices()));
296 }
297 std::sort(angles.begin(), angles.end());
298 if(method == 3)
299 {
300 this->takeCornersWithSmallestAngles(4, angles, corners);
301 std::sort(corners.begin(), corners.end());
302 gsDebug << "According to the method 'smallest inner angles' the following corners were chosen:\n";
303 for(std::vector<index_t>::iterator it=corners.begin(); it!=corners.end(); it++)
304 {
305 gsDebug << (*it) << "\n";
306 }
307 }
308 else if(method == 5)
309 {
310 searchAreas(range, angles, corners);
311 gsDebug << "According to the method 'nearly opposite corners' the following corners were chosen:\n";
312 for(size_t i=0; i<corners.size(); i++)
313 {
314 gsDebug << corners[i] << "\n";
315 }
316 }
317 else if(method == 4)
318 {
319 bool flag = true;
320 corners.reserve(4);
321 corners.push_back(angles.front().second);
322 angles.erase(angles.begin());
323 while(corners.size() < 4)
324 {
325 flag = true;
326 for(std::vector<index_t>::iterator it=corners.begin(); it!=corners.end(); it++)
327 {
328 if(m_basicInfos.getShortestBoundaryDistanceBetween(angles.front().second, *it) < range*m_basicInfos.getBoundaryLength())
329 flag = false;
330 }
331 if(flag)
332 corners.push_back(angles.front().second);
333 angles.erase(angles.begin());
334 }
335 std::sort(corners.begin(), corners.end());
336 for(size_t i=0; i<corners.size(); i++)
337 {
338 gsDebug << corners[i] << "\n";
339 }
340 }
341 else if(method == 6)
342 {
343 T oldDifference = 0;
344 T newDifference = 0;
345 std::vector<index_t> newCorners;
346 std::vector<T> lengths;
347 angles.erase(angles.begin()+number, angles.end());
348 gsDebug << "Angles:\n";
349 for(size_t i=0; i<angles.size(); i++)
350 {
351 gsDebug << angles[i].first << ", " << angles[i].second << "\n";
352 }
353 newCorners.reserve((angles.size()*(angles.size()-1)*(angles.size()-2)*(angles.size()-3))/6);
354 corners.reserve((angles.size()*(angles.size()-1)*(angles.size()-2)*(angles.size()-3))/6);
355 for(size_t i=0; i<angles.size(); i++) // n
356 {
357 for(size_t j=i+1; j<angles.size(); j++) // * (n-1)/2
358 {
359 for(size_t k=j+1; k<angles.size(); k++) // * (n-2)/3
360 {
361 for(size_t l=k+1; l<angles.size(); l++) // * (n-3)/4
362 {
363 newCorners.push_back(angles[i].second);
364 newCorners.push_back(angles[j].second);
365 newCorners.push_back(angles[k].second);
366 newCorners.push_back(angles[l].second);
367 std::sort(newCorners.begin(), newCorners.end());
368 lengths = m_basicInfos.getCornerLengths(newCorners);
369 std::sort(lengths.begin(), lengths.end());
370 newDifference = math::abs(lengths[0] - lengths[3]);
371 if(oldDifference == 0 || newDifference < oldDifference)
372 {
373 corners.erase(corners.begin(), corners.end());
374 corners.push_back(angles[i].second);
375 corners.push_back(angles[j].second);
376 corners.push_back(angles[k].second);
377 corners.push_back(angles[l].second);
378 std::sort(corners.begin(), corners.end());
379 }
380 newCorners.erase(newCorners.begin(), newCorners.end());
381 oldDifference = newDifference;
382 }
383 }
384 }
385 }
386 gsDebug << "According to the method 'evenly distributed corners' the following corners were chosen:\n";
387 for(size_t i=0; i<corners.size(); i++)
388 {
389 gsDebug << corners[i] << "\n";
390 }
391 }
392 return corners;
393}
394
395template<class T>
397{
398 GISMO_ASSERT(0 <= w && w <= 4, "Wrong value for w.");
399 if(0 <= w && w <=1)
400 return Point2D(w,0, vertexIndex);
401 else if(1<w && w<=2)
402 return Point2D(1,w-(T)(1), vertexIndex);
403 else if(2<w && w<=3)
404 return Point2D(T(1)-w+(T)(2),1, vertexIndex);
405 else if(3<w && w<=4)
406 return Point2D(0,T(1)-w+(T)(3), vertexIndex);
407 return Point2D();
408}
409
410//*****************************************************************************************************
411//*****************************************************************************************************
412//*******************THE******INTERN******FUNCTIONS******ARE******NOW******FOLLOWING*******************
413//*****************************************************************************************************
414//*****************************************************************************************************
415
416template<class T>
417void gsParametrization<T>::Neighbourhood::takeCornersWithSmallestAngles(size_t number, std::vector<std::pair<T , size_t> >& sortedAngles, std::vector<index_t>& corners) const
418{
419 sortedAngles.erase(sortedAngles.begin()+number, sortedAngles.end());
420
421 corners.clear();
422 corners.reserve(sortedAngles.size());
423 for(typename std::vector<std::pair<T, size_t> >::iterator it=sortedAngles.begin(); it!=sortedAngles.end(); it++)
424 corners.push_back(it->second);
425}
426
427template<class T>
428std::vector<T> gsParametrization<T>::Neighbourhood::midpoints(const size_t numberOfCorners, const T length) const
429{
430 std::vector<T> midpoints;
431 midpoints.reserve(numberOfCorners-1);
432 T n = 1./numberOfCorners;
433 for(size_t i=1; i<numberOfCorners; i++)
434 {
435 midpoints.push_back(T(i)*length*n);
436 }
437 return midpoints;
438}
439
440template<class T>
441void gsParametrization<T>::Neighbourhood::searchAreas(const T range, std::vector<std::pair<T, size_t> >& sortedAngles, std::vector<index_t>& corners) const
442{
443 T l = m_basicInfos.getBoundaryLength();
444 std::vector<T> h = m_basicInfos.getBoundaryChordLengths();
445 this->takeCornersWithSmallestAngles(1,sortedAngles, corners);
446 std::vector<std::vector<std::pair<T , size_t> > > areas;
447 areas.reserve(3);
448 for(size_t i=0; i<3; i++)
449 {
450 areas.push_back(std::vector<std::pair<T , size_t> >());
451 }
452 std::vector<T> midpoints = this->midpoints(4, l);
453
454 T walkAlong = 0;
455 for(size_t i=0; i<h.size(); i++)
456 {
457 walkAlong += h[(corners[0]+i-1)%h.size()];
458 for(int j = 2; j>=0; j--)
459 {
460 if(math::abs(walkAlong-midpoints[j]) <= l*range)
461 {
462 areas[j].push_back(std::pair<T , size_t>(m_localBoundaryNeighbourhoods[(corners[0]+i)%(h.size())].getInnerAngle(), (corners[0]+i)%h.size() + 1));
463 break;
464 }
465 }
466 }
467 std::sort(areas[0].begin(), areas[0].end());
468 std::sort(areas[1].begin(), areas[1].end());
469 std::sort(areas[2].begin(), areas[2].end());
470 bool smaller = false;
471 //corners.reserve(3);
472 for(size_t i=0; i<areas[0].size(); i++)
473 {
474 if(areas[0][i].second > (size_t)corners[0] || areas[0][i].second < (size_t)corners[0])
475 {
476 corners.push_back(areas[0][i].second);
477 if(areas[0][i].second < (size_t)corners[0])
478 {
479 smaller = true;
480 }
481 break;
482 }
483 }
484 for(size_t i=0; i<areas[1].size(); i++)
485 {
486 if(smaller)
487 {
488 if(areas[1][i].second > (size_t)corners[1] && areas[1][i].second < (size_t)corners[0])
489 {
490 corners.push_back(areas[1][i].second);
491 break;
492 }
493 }
494 else if(areas[1][i].second > (size_t)corners[1] || areas[1][i].second < (size_t)corners[0])
495 {
496 corners.push_back(areas[1][i].second);
497 if(areas[1][i].second < (size_t)corners[0])
498 {
499 smaller = true;
500 }
501 break;
502 }
503 }
504 for(size_t i=0; i<areas[2].size(); i++)
505 {
506 if(smaller)
507 {
508 if(areas[2][i].second > (size_t)corners[2] && areas[2][i].second < (size_t)corners[0])
509 {
510 corners.push_back(areas[2][i].second);
511 break;
512 }
513 }
514 else if(areas[2][i].second > (size_t)corners[2] || areas[2][i].second < (size_t)corners[0])
515 {
516 corners.push_back(areas[2][i].second);
517 break;
518 }
519 }
520}
521
522//*******************************************************************************************
523//**************************** nested class LocalParametrization ****************************
524//*******************************************************************************************
525
526template<class T>
527gsParametrization<T>::LocalParametrization::LocalParametrization(const gsHalfEdgeMesh<T>& meshInfo, const LocalNeighbourhood& localNeighbourhood, const size_t parametrizationMethod)
528{
529 m_vertexIndex = localNeighbourhood.getVertexIndex();
530 std::list<size_t> indices = localNeighbourhood.getVertexIndicesOfNeighbours();
531 size_t d = localNeighbourhood.getNumberOfNeighbours();
532 switch (parametrizationMethod)
533 {
534 case 1:
535 {
536 std::list<T> angles = localNeighbourhood.getAngles();
537 VectorType points;
538 T theta = 0;
539 T nextAngle = 0;
540 for(typename std::list<T>::iterator it = angles.begin(); it!=angles.end(); ++it)
541 {
542 theta += *it;
543 }
544 Point2D p(0, 0, 0);
545 T length = (*meshInfo.getVertex(indices.front()) - *meshInfo.getVertex(m_vertexIndex)).norm();
546 Point2D nextPoint(length, 0, indices.front());
547 points.reserve(indices.size());
548 points.push_back(nextPoint);
549 gsVector<T> actualVector = nextPoint - p;
550 indices.pop_front();
551 T thetaInv = 1./theta;
552 gsVector<T> nextVector;
553 while(!indices.empty())
554 {
555 length = (*meshInfo.getVertex(indices.front()) - *meshInfo.getVertex(m_vertexIndex)).norm();
556 //length = (meshInfo.getVertex(indices.front()) - meshInfo.getVertex(m_vertexIndex) ).norm();
557 nextAngle = angles.front()*thetaInv * (T)(2) * (T)(EIGEN_PI);
558 nextVector = (gsEigen::Rotation2D<T>(nextAngle).operator*(actualVector).normalized()*length) + p;
559 nextPoint = Point2D(nextVector[0], nextVector[1], indices.front());
560 points.push_back(nextPoint);
561 actualVector = nextPoint - p;
562 angles.pop_front();
563 indices.pop_front();
564 }
565 calculateLambdas(meshInfo.getNumberOfVertices(), points);
566 }
567 break;
568 case 2:
569 m_lambdas.reserve(meshInfo.getNumberOfVertices());
570 for(size_t j=1; j <= meshInfo.getNumberOfVertices(); j++)
571 {
572 m_lambdas.push_back(0); // Lambda(m_vertexIndex, j, 0)
573 }
574 while(!indices.empty())
575 {
576 m_lambdas[indices.front()-1] += (1./d);
577 indices.pop_front();
578 }
579 break;
580 case 3:
581 {
582 std::list<T> neighbourDistances = localNeighbourhood.getNeighbourDistances();
583 T sumOfDistances = 0;
584 for(typename std::list<T>::iterator it = neighbourDistances.begin(); it != neighbourDistances.end(); it++)
585 {
586 sumOfDistances += *it;
587 }
588 T sumOfDistancesInv = 1./sumOfDistances;
589 m_lambdas.reserve(meshInfo.getNumberOfVertices());
590 for(size_t j=1; j <= meshInfo.getNumberOfVertices(); j++)
591 {
592 m_lambdas.push_back(0); //Lambda(m_vertexIndex, j, 0)
593 }
594 for(typename std::list<T>::iterator it = neighbourDistances.begin(); it != neighbourDistances.end(); it++)
595 {
596 m_lambdas[indices.front()-1] += ((*it)*sumOfDistancesInv);
597 indices.pop_front();
598 }
599 }
600 break;
601 default:
602 GISMO_ERROR("parametrizationMethod not valid: " << parametrizationMethod);
603 }
604}
605
606template<class T>
608{
609 return m_lambdas;
610}
611
612//*****************************************************************************************************
613//*****************************************************************************************************
614//*******************THE******INTERN******FUNCTIONS******ARE******NOW******FOLLOWING*******************
615//*****************************************************************************************************
616//*****************************************************************************************************
617
618template<class T>
620{
621 m_lambdas.reserve(N);
622 for(size_t j=1; j <= N; j++)
623 {
624 m_lambdas.push_back(0); //Lambda(m_vertexIndex, j, 0)
625 }
626 Point2D p(0, 0, 0);
627 size_t d = points.size();
628 std::vector<T> my(d, 0);
629 size_t l=1;
630 size_t steps = 0;
631 //size_t checkOption = 0;
632 for(typename VectorType::const_iterator it=points.begin(); it != points.end(); it++)
633 {
634 gsLineSegment<2,T> actualLine(p, *it);
635 for(size_t i=1; i < d-1; i++)
636 {
637 if(l+i == d)
638 steps = d - 1;
639 else
640 steps = (l+i)%d - 1;
641 //checkoption is set to another number, in case mu is negativ
642 if(actualLine.intersectSegment(*(points.begin()+steps), *(points.begin()+(steps+1)%d)/*, checkOption*/))
643 {
644 //BarycentricCoordinates b(p, *it, *(points.begin()+steps), *(points.begin()+(steps+1)%d));
645 // calculating Barycentric Coordinates
646 gsMatrix<T, 3, 3> matrix;
647 matrix.topRows(2).col(0) = *it;
648 matrix.topRows(2).col(1) = *(points.begin()+steps);
649 matrix.topRows(2).col(2) = *(points.begin()+(steps+1)%d);
650 matrix.row(2).setOnes();
651
652 gsVector3d<T> vector3d;
653 vector3d << p, 1;
654 gsVector3d<T> delta = matrix.partialPivLu().solve(vector3d);
655 my[l-1] = delta(0);
656 my[steps] = delta(1);
657 my[(steps + 1)%d] = delta(2);
658 break;
659 }
660 }
661 for(size_t k = 1; k <= d; k++)
662 {
663 m_lambdas[points[k-1].getVertexIndex()-1] += (my[k-1]);
664 }
665 std::fill(my.begin(), my.end(), 0);
666 l++;
667 }
668 for(typename std::vector<T>::iterator it=m_lambdas.begin(); it != m_lambdas.end(); it++)
669 {
670 *it /= d;
671 }
672 for(typename std::vector<T>::iterator it=m_lambdas.begin(); it != m_lambdas.end(); it++)
673 {
674 if(*it < 0)
675 gsInfo << *it << "\n";
676 }
677}
678
679//*******************************************************************************************
680//***************************** nested class LocalNeighbourhood *****************************
681//*******************************************************************************************
682
683template<class T>
684gsParametrization<T>::LocalNeighbourhood::LocalNeighbourhood(const gsHalfEdgeMesh<T>& meshInfo, const size_t vertexIndex, const bool innerVertex)
685{
686 GISMO_ASSERT(!((innerVertex && vertexIndex > meshInfo.getNumberOfInnerVertices()) || vertexIndex < 1),
687 "Vertex with index " << vertexIndex << " does either not exist (< 1) or is not an inner vertex (> "
688 << meshInfo.getNumberOfInnerVertices() << ").");
689
690 gsVertex<T> tmp;
691 m_vertexIndex = vertexIndex;
692 std::queue<typename gsHalfEdgeMesh<T>::Halfedge>
693 allHalfedges = meshInfo.getOppositeHalfedges(m_vertexIndex, innerVertex);
694 std::queue<typename gsHalfEdgeMesh<T>::Halfedge> nonFittingHalfedges;
695 m_neighbours.appendNextHalfedge(allHalfedges.front());
696 tmp = *meshInfo.getVertex(allHalfedges.front().getOrigin()) - *meshInfo.getVertex(m_vertexIndex);
697 m_angles.push_back(tmp.angle((*meshInfo.getVertex(allHalfedges.front().getEnd())
698 - *meshInfo.getVertex(vertexIndex))));
699 m_neighbourDistances.push_back(allHalfedges.front().getLength());
700 allHalfedges.pop();
701 while (!allHalfedges.empty())
702 {
703 if (m_neighbours.isAppendableAsNext(allHalfedges.front()))
704 {
705 m_neighbours.appendNextHalfedge(allHalfedges.front());
706 tmp = *meshInfo.getVertex(allHalfedges.front().getOrigin()) - *meshInfo.getVertex(m_vertexIndex);
707 m_angles
708 .push_back(tmp.angle((*meshInfo.getVertex(allHalfedges.front().getEnd())
709 - *meshInfo.getVertex(m_vertexIndex))));
710 m_neighbourDistances.push_back(allHalfedges.front().getLength());
711 allHalfedges.pop();
712 while (!nonFittingHalfedges.empty())
713 {
714 allHalfedges.push(nonFittingHalfedges.front());
715 nonFittingHalfedges.pop();
716 }
717 }
718 else if (m_neighbours.isAppendableAsPrev(allHalfedges.front()))
719 {
720 m_neighbours.appendPrevHalfedge(allHalfedges.front());
721 tmp = *meshInfo.getVertex(allHalfedges.front().getOrigin()) - *meshInfo.getVertex(m_vertexIndex);
722 m_angles
723 .push_front(tmp.angle((*meshInfo.getVertex(allHalfedges.front().getEnd())
724 - *meshInfo.getVertex(m_vertexIndex))));
725 m_neighbourDistances.push_back(allHalfedges.front().getLength());
726 allHalfedges.pop();
727 while (!nonFittingHalfedges.empty())
728 {
729 allHalfedges.push(nonFittingHalfedges.front());
730 nonFittingHalfedges.pop();
731 }
732 }
733 else
734 {
735 nonFittingHalfedges.push(allHalfedges.front());
736 allHalfedges.pop();
737 }
738 }
739}
740
741template<class T>
743{
744 return m_vertexIndex;
745}
746
747template<class T>
749{
750 return m_neighbours.getNumberOfVertices();
751}
752
753template<class T>
755{
756 return m_neighbours.getVertexIndices();
757}
758
759template<class T>
761{
762 return m_angles;
763}
764
765template<class T>
767{
768 T angle = 0;
769 for(typename std::list<T>::const_iterator it=m_angles.begin(); it!=m_angles.end(); it++)
770 {
771 angle += (*it);
772 }
773 return angle;
774}
775
776template<class T>
778{
779 return m_neighbourDistances;
780}
781
782} // namespace gismo
gsHalfEdgeMesh is a gsMesh implementation that handles Halfedges
Definition gsHalfEdgeMesh.h:47
size_t getNumberOfVertices() const
Get number of vertices The number of vertices of the triangle mesh is returned.
Definition gsHalfEdgeMesh.hpp:58
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
size_t getNumberOfInnerVertices() const
Get number of inner vertices The number of inner vertices of the triangle mesh is returned.
Definition gsHalfEdgeMesh.hpp:70
const gsMesh< T >::gsVertexHandle & getVertex(const size_t vertexIndex) const
Get vertex The vertex with index 'vertexIndex' is returned.
Definition gsHalfEdgeMesh.hpp:82
Represents a line segment in d dimensions.
Definition gsLineSegment.h:22
bool intersectSegment(const gsPoint< d, T > &origin, const gsPoint< d, T > &end)
Tells wheter line intersects segment.
Definition gsLineSegment.h:40
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Class Representing a triangle mesh with 3D vertices.
Definition gsMesh.h:32
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
Class which holds a list of parameters/options, and provides easy access to them.
Definition gsOptionList.h:33
void addInt(const std::string &label, const std::string &desc, const index_t &value)
Adds a option named label, with description desc and value value.
Definition gsOptionList.cpp:201
void update(const gsOptionList &other, updateType type=ignoreIfUnknown)
Updates the object using the data from other.
Definition gsOptionList.cpp:253
void addMultiInt(const std::string &label, const std::string &desc, const std::vector< index_t > &values)
Adds an option-group gn containing values of a std::vector.
Definition gsOptionList.cpp:221
void addReal(const std::string &label, const std::string &desc, const Real &value)
Adds a option named label, with description desc and value value.
Definition gsOptionList.cpp:211
Class that maintains the local neighbourhood properties.
Definition gsParametrization.h:128
LocalNeighbourhood(const gsHalfEdgeMesh< T > &meshInfo, const size_t vertexIndex, const bool innerVertex=1)
Constructor.
Definition gsParametrization.hpp:684
size_t getVertexIndex() const
Get vertex index.
Definition gsParametrization.hpp:742
size_t getNumberOfNeighbours() const
Get number of neighbours.
Definition gsParametrization.hpp:748
T getInnerAngle() const
Get inner angle.
Definition gsParametrization.hpp:766
std::list< T > getNeighbourDistances() const
Get neighbour distances.
Definition gsParametrization.hpp:777
const std::list< T > & getAngles() const
Get angles.
Definition gsParametrization.hpp:760
const std::list< size_t > getVertexIndicesOfNeighbours() const
Get vertex indices of neighbours.
Definition gsParametrization.hpp:754
Class maintains local parametrization This class represents a local parametrization for a point in th...
Definition gsParametrization.h:222
const std::vector< T > & getLambdas() const
Get lambdas The lambdas are returned.
Definition gsParametrization.hpp:607
LocalParametrization(const gsHalfEdgeMesh< T > &meshInfo, const LocalNeighbourhood &localNeighbourhood, const size_t parametrizationMethod=2)
Constructor Using this constructor one needs to input mesh information, a local neighbourhood and a p...
Definition gsParametrization.hpp:527
void calculateLambdas(const size_t N, VectorType &points)
Calculate lambdas The lambdas according to Floater's algorithm are calculated.
Definition gsParametrization.hpp:619
Class that maintains neighbourhood information of triangle mesh. Represents the neighbourhood propert...
Definition gsParametrization.h:286
const std::vector< index_t > getBoundaryCorners(const size_t method, const T range=0.1, const size_t number=4) const
Get boundary corners depending on the method.
Definition gsParametrization.hpp:288
const std::vector< T > & getLambdas(const size_t i) const
Get vector of lambdas.
Definition gsParametrization.hpp:282
Neighbourhood(const gsHalfEdgeMesh< T > &meshInfo, const size_t parametrizationMethod=2)
Default constructor.
Definition gsParametrization.hpp:266
Class that maintains parametrization This class Parametrization stores the mesh information and the t...
Definition gsParametrization.h:47
virtual gsMesh< T > createFlatMesh() const
Definition gsParametrization.hpp:188
void writeTexturedMesh(std::string filename) const
Definition gsParametrization.hpp:207
void constructAndSolveEquationSystem(const Neighbourhood &neighbourhood, const size_t n, const size_t N)
Constructs linear equation system and solves it.
Definition gsParametrization.hpp:125
const Point2D & getParameterPoint(size_t vertexIndex) const
Get parameter point Returns the parameter point with given vertex index.
Definition gsParametrization.hpp:160
gsMatrix< T > createXYZmatrix()
Definition gsParametrization.hpp:177
virtual void compute()
Main function which performs the computation.
Definition gsParametrization.hpp:227
gsMatrix< T > createUVmatrix()
Definition gsParametrization.hpp:166
gsParametrization(const gsMesh< T > &mesh, const gsOptionList &list=defaultOptions())
Constructor using the input mesh and (possibly) options.
Definition gsParametrization.hpp:49
static gsOptionList defaultOptions()
Returns the list of default options for gsParametrization.
Definition gsParametrization.hpp:35
A Point in T^d, with an index number.
Definition gsPoint.h:27
A fixed-size, statically allocated 3D vector.
Definition gsVector.h:219
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
gsVertex class that represents a 3D vertex for a gsMesh.
Definition gsVertex.h:27
#define gsDebug
Definition gsDebug.h:61
#define GISMO_ERROR(message)
Definition gsDebug.h:118
#define GISMO_UNUSED(x)
Definition gsDebug.h:112
#define gsInfo
Definition gsDebug.h:43
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides declaration of Line class.
Provides a list of labeled parameters/options that can be set and accessed easily.
Class that maintains parametrization.
Provides declaration of functions writing Paraview files.
The G+Smo namespace, containing all definitions for the library.