G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsTemplate.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsCore/gsGeometry.h>
17 #include <gsCore/gsBoxTopology.h>
18 #include <gsCore/gsBoundary.h>
19 #include <gsModeling/gsCurveLoop.h>
20 #include <gsUtils/gsPointGrid.h>
21 
22 #include <gsNurbs/gsNurbsCreator.h>
23 
24 #include <eiquadprog.hpp> // external file
25 
26 
27 namespace gismo
28 {
29 
76 template<class T>
77 class gsTemplate : public gsBoxTopology
78 {
79 public:
80 
83  typedef memory::shared_ptr< gsTemplate > Ptr;
84  //typedef memory::unique_ptr< gsTemplate > LocalPtr;
85 
86 public:
87 
89  gsTemplate() : Base() { }
90 
91  gsTemplate( int const & i ) : Base()
92  {
93  GISMO_ASSERT(i<=2 , "Template with more than one hole not implemented yet.");
94  gsMatrix<T> xi(2,4);
95  xi << 1, 0, -1, 0,
96  0, 1, 0, -1;
97 
98  if ( i == 0 )
99  {
100 
101  // TO DO: add copy constructor and assignmnet operator in gsPlanarDomain
102  m_pdomain.insertHole( new gsCurveLoop<T>(gsNurbsCreator<T>::BSplineFatCircle().release()) );
103 
104  m_pdomain.outer().reverse();
105  // gsDebug<<"\n Does your template has the right orientation ? ";
106  // gsDebug<< "m_domain:\n"<< m_pdomain;
107  //m_pdomain.check() ;
108 
109  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0),0.5*xi.col(0)).release() );
110  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(1),0.5*xi.col(1)).release() );
111  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(2),0.5*xi.col(2)).release() );
112  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(3),0.5*xi.col(3)).release() );
113  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(0.5*xi.col(0), 0.5*xi.col(1)).release() );
114  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(0.5*xi.col(1), 0.5*xi.col(2)).release() );
115  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(0.5*xi.col(2), 0.5*xi.col(3)).release() );
116  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(0.5*xi.col(3), 0.5*xi.col(0)).release() );
117 
118  }
119  else if ( i == 1 )//template with one point removed
120  {
121 
122 
123  // TO DO: add copy constructor and assignmnet operator in gsPlanarDomain
124 
125  m_pdomain = gsPlanarDomain<T>( gsNurbsCreator<T>::BSplineFatCircle().release() );
126 
127  // ************** RIGHT THINGS for amoeba_lake1_pdomain.xml:
128  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0),-0.534694*xi.col(0)+0*xi.col(1)).release() );
129  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(1),-0.534694*xi.col(0)+0*xi.col(1)).release() );
130  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(2),-0.534694*xi.col(0)+0*xi.col(1)).release() );
131  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(3),-0.534694*xi.col(0)+0*xi.col(1)).release() );
132  }
133  else if(i==2)
134  {
135  m_pdomain = gsPlanarDomain<T>( gsNurbsCreator<T>::BSplineFatCircle().release() );
136 
137  //First 4 curves around upper puncture
138 
139  //1
140  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0)*(0.25) +
141  xi.col(1)*(0.732),(0.25)*xi.col(0)+xi.col(1)*(0.55)).release());
142 
143  //2
144 
145  gsMatrix<T> cc(5,2);
146  cc<<0.691, 0.717,
147  0.572, 0.672,
148  0.427, 0.55,
149  0.427, 0.55,
150  0.25, 0.55;
151  gsKnotVector<T> kk(0,1,2,3,1,2);
152  gsBSpline<T> *Trick2 = new gsBSpline<T>(kk,cc);
153  addSkeleton(Trick2);
154 
155  // 3
156  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0)*(0.25) +
157  xi.col(1)*(0.363),( 0.25)*xi.col(0)+xi.col(1)*(0.55)).release());
158  //4
159  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0)*(0.064) +
160  xi.col(1)*(0.55),( 0.25)*xi.col(0)+xi.col(1)*(0.55)).release());
161 
162  //5 Arc up left
163 
164  gsMatrix<T> coeff(3,2);
165  coeff<<-0.583, 0.876,
166  -0.468, 0.802,
167  0.064, 0.55;
168  gsKnotVector<T> kv(0,1,0,3,2);
169  gsBSpline<T> * ArcUpLeft = new gsBSpline<T>(kv,coeff);
170  addSkeleton(ArcUpLeft);
171 
172  //6 Arc center left
173  coeff<<0.064, 0.55,
174  -0.255,0.106,
175  -0.078, -0.55;
176  gsBSpline<T> * ArcCenterLeft = new gsBSpline<T>(kv, coeff);
177  addSkeleton(ArcCenterLeft);
178 
179  // 7 Arc center right
180  coeff<< 0.427, 0.55,
181  0.619, 0.007,
182  0.288, -0.55;
183  gsBSpline<T> * ArcCenterRight = new gsBSpline<T>(kv,coeff);
184  addSkeleton(ArcCenterRight);
185 
186  // 8 Central Arc
187 
188 
189  coeff<<0.25, 0.363,
190  0.170, -0.004,
191  0.10, -0.366;
192 
193  gsBSpline<T> *CentralArc = new gsBSpline<T>(kv,coeff);
194  addSkeleton(CentralArc);
195 
196  //9 Arc up
197  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0)*(0.25) +
198  xi.col(1)*(0.986),( 0.25)*xi.col(0)+xi.col(1)*(0.732)).release());
199 
200  //10 Arc up right
201 
202  coeff<<0.749, 0.750,
203  0.572, 0.672,
204  0.427, 0.55 ;
205  gsBSpline<T> * ArcUpRight = new gsBSpline<T>(kv,coeff);
206  addSkeleton(ArcUpRight);
207 
208  // 4 curves around puncture low
209 
210  //11
211  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0)*(0.10) +
212  xi.col(1)*(-0.366),(0.10)*xi.col(0)+xi.col(1)*(-0.55)).release());
213  //12
214  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0)*(0.288) +
215  xi.col(1)*(-0.55),(0.10)*xi.col(0)+xi.col(1)*(-0.55)).release());
216 
217  //13
218  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0)*(0.10) +
219  xi.col(1)*(-0.993),(0.10)*xi.col(0)+xi.col(1)*(-0.55)).release());
220  //14
221  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0)*(-0.078) +
222  xi.col(1)*(-0.55),(0.10)*xi.col(0)+xi.col(1)*(-0.55)).release());
223 
224  // 15 Arc low left
225  coeff<< -0.638,-0.837, //-0.623, -0.842
226  -0.517,-0.725,
227  -0.078, -0.55;
228  gsBSpline<T> * ArcLowLeft = new gsBSpline<T>(kv,coeff);
229  addSkeleton(ArcLowLeft);
230 
231  //16 Arc low
232  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(xi.col(0)*(0.10) +
233  xi.col(1)*(-0.990),(0.10)*xi.col(0)+xi.col(1)*(-0.718)).release());
234 
235 
236  //17 Arc low right
237 
238  coeff<<0.690, -0.824, //0.685, -0.804
239  0.556, -0.675,
240  0.288, -0.55;
241  gsBSpline<T>* ArcLowRight = new gsBSpline<T>(kv,coeff);
242  addSkeleton(ArcLowRight);
243 
244  //circular arcs around upper puncture
245 
246  // 18
247  coeff<<0.25, 0.732,
248  0.377, 0.697,
249  0.427, 0.55;
250  gsBSpline<T> * Archetto1 = new gsBSpline<T> (kv,coeff);
251  addSkeleton(Archetto1);
252 
253  //19
254  coeff<< 0.427, 0.55,
255  0.37, 0.416,
256  0.25, 0.377;
257  gsBSpline<T> * Archetto2 = new gsBSpline<T>(kv,coeff);
258  addSkeleton(Archetto2);
259 
260  //20
261  coeff<< 0.25, 0.377,
262  0.132, 0.419,
263  0.064, 0.55;
264  gsBSpline<T>* Archetto3 = new gsBSpline<T>(kv,coeff);
265  addSkeleton(Archetto3);
266 
267  //21
268  coeff<<0.064, 0.55,
269  0.117, 0.679,
270  0.25, 0.732;
271  gsBSpline<T>* Archetto4 = new gsBSpline<T>(kv,coeff);
272  addSkeleton(Archetto4);
273 
274  //circular arcs around low puncture
275 
276  //22
277  coeff<<0.10, -0.366,
278  0.224, -0.409,
279  0.288, -0.55;
280  gsBSpline<T>* Archetto5 = new gsBSpline<T>(kv,coeff);
281  addSkeleton(Archetto5);
282 
283  //23
284  coeff<< 0.288, -0.55,
285  0.220, -0.686,
286  0.10, -0.718;
287  gsBSpline<T>* Archetto6 = new gsBSpline<T>(kv,coeff);
288  addSkeleton(Archetto6);
289 
290  //24
291  coeff<<0.10, -0.718,
292  -0.025, -0.675,
293  -0.078, -0.55;
294  gsBSpline<T>* Archetto7 = new gsBSpline<T>(kv,coeff);
295  addSkeleton(Archetto7);
296 
297  //25
298 
299  coeff<< -0.078, -0.55,
300  -0.025, -0.412,
301  0.10, -0.366;
302  gsBSpline<T> *Archetto8 = new gsBSpline<T>(kv, coeff);
303  addSkeleton(Archetto8);
304 
305  //For plotting the template segmentation
306 
307  //gsWriteParaview(*m_skeleton[0],"1th",30);
308  //gsWriteParaview(*m_skeleton[1],"2th",30);
309  //gsWriteParaview(*m_skeleton[2],"3th",30);
310  //gsWriteParaview(*m_skeleton[3],"4th",30);
311 
312 
313  //gsWriteParaview(*m_skeleton[4],"5th",30);
314  //gsWriteParaview(*m_skeleton[5],"6th",30);
315  //gsWriteParaview(*m_skeleton[6],"7th",30);
316  //gsWriteParaview(*m_skeleton[7],"8th",30);
317 
318  //gsWriteParaview(*m_skeleton[8],"9th",30);
319  //gsWriteParaview(*m_skeleton[9],"10th",30);
320  //gsWriteParaview(*m_skeleton[10],"11th",30);
321 
322  //gsWriteParaview(*m_skeleton[11],"12th",30);
323  //gsWriteParaview(*m_skeleton[12],"13th",30);
324  //gsWriteParaview(*m_skeleton[13],"14th",30);
325  //gsWriteParaview(*m_skeleton[14],"15th",30);
326  //gsWriteParaview(*m_skeleton[15],"16th",30);
327  //gsWriteParaview(*m_skeleton[16],"17th",30);
328  //gsWriteParaview(*m_skeleton[17],"18th",30);
329  //gsWriteParaview(*m_skeleton[18],"19th",30);
330  //gsWriteParaview(*m_skeleton[19],"20th",30);
331  //gsWriteParaview(*m_skeleton[20],"21th",30);
332  //gsWriteParaview(*m_skeleton[21],"22th",30);
333  //gsWriteParaview(*m_skeleton[22],"23th",30);
334  //gsWriteParaview(*m_skeleton[23],"24th",30);
335  //gsWriteParaview(*m_skeleton[24],"25th",30);
336 
337 
338  }
339  else
340  {
341  gsWarn<< "Empty template.\n";
342  }
343  }
344 
345 
347  gsTemplate(int r,
348  bool ) //square)
349  : Base()
350  {
351 
352  gsMatrix<T> Bb(2,4);
353  Bb<< 0, 1, 0, 1,
354  0, 0, 1, 1;
355 
356 
357  //construct a square
358  //boundaryB= bottom side of the square
359 
360  gsBSpline<T>* boundaryB = gsNurbsCreator<T>::BSplineLineSegment(r*Bb.col(0),r*Bb.col(1)).release();
361 
362  //boundaryU = upper side of the square
363  gsBSpline<T>* boundaryU = gsNurbsCreator<T>::BSplineLineSegment(r*Bb.col(3),r*Bb.col(2)).release();
364 
365  //boundaryL = left side of the square
366  gsBSpline<T>* boundaryL = gsNurbsCreator<T>::BSplineLineSegment(r*Bb.col(2),r*Bb.col(0)).release();
367 
368  //boundaryR = right side of the square
369  gsBSpline<T>* boundaryR = gsNurbsCreator<T>::BSplineLineSegment(r*Bb.col(1),r*Bb.col(3)).release();
370 
371  //generating points on the four boundaries
372  //label 0 : boundaryB
373  //label 1 : boundaryU
374  //label 2 : boundaryR
375  //label 3 : boundaryL
376 
377  gsMatrix<T> uniformPoints = gsPointGrid<T>(0,1,102);
378  int numCols = uniformPoints.cols();
379 
380  gsMatrix<T>storage0(2, numCols),storage1(2,numCols),storage2(2,numCols),storage3(2,numCols);
381  storage0.setZero();
382  storage0.row(0)=uniformPoints.row(0);
383 
384  storage1.setOnes();
385  storage1.row(0)=uniformPoints.row(0);
386 
387  storage2.setOnes();
388  storage2.row(1)=uniformPoints.row(0);
389 
390  storage3.setZero();
391  storage3.row(1)=uniformPoints.row(0);
392 
393 
394  //creating the skeleton
395 
396  for(int i=1; i<storage0.cols()-1;++i)
397  {
398  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(storage0.col(i),storage1.col(i)).release());
399  addSkeleton( gsNurbsCreator<T>::BSplineLineSegment(storage2.col(i),storage3.col(i)).release());
400 
401  }
402  //join boundary curves in one single curve
403  std::vector< gsCurve<T> *> BoundaryCurves;
404  BoundaryCurves.push_back(boundaryB);
405  BoundaryCurves.push_back(boundaryR);
406  BoundaryCurves.push_back(boundaryU);
407  BoundaryCurves.push_back(boundaryL);
408 
409  gsCurveLoop<T>* BoundaryLoop = new gsCurveLoop<T>(BoundaryCurves);
410  // BoundaryLoop.singleCurve();
411  m_pdomain = gsPlanarDomain<T>(BoundaryLoop);
412 
413  }
414 
422  gsTemplate(const std::vector<T> & intervalWidths,
423  const gsMatrix<T> & verts,
424  size_t startIdx,
425  size_t endIdx,
426  T curveProportion
427  ) : Base()
428  {
429  index_t n = verts.rows();
430 
431  // create an outer loop of straight lines
432  gsCurveLoop<T> *loop = new gsCurveLoop<T>();
433  for(index_t i = 0; i < n; i++)
434  {
435  gsMatrix<T> tcp(2, 2);
436  tcp << verts(i, 0), verts(i, 1), verts((i + 1) % n, 0), verts((i + 1) % n, 1);
437  gsBSpline<T> * tcurve = new gsBSpline<T>( 0, intervalWidths[i], 0, 1, give(tcp) );
438  loop->insertCurve(tcurve);
439  // TODO: assert if the vertices do not define a convex polygon.
440  }
441  m_pdomain.insertHole(loop);
442 
443 
444  // compute a cubic through these points. minimize mean squared acceleration subject to
445  // fixed initial/final points and normals
446  gsMatrix<T> startPoint = verts.row(startIdx);
447  gsMatrix<T> endPoint = verts.row(endIdx);
448  // bisector must be normal to the difference between the normalized outgoing vectors
449  gsMatrix<T> Tang1i = (verts.row((startIdx + n - 1) % n) - startPoint).normalized();
450  gsMatrix<T> Tang1o = (verts.row((startIdx + 1) % n) - startPoint).normalized();
451  gsMatrix<T> Tang2i = (verts.row((endIdx + n - 1) % n) - endPoint).normalized();
452  gsMatrix<T> Tang2o = (verts.row((endIdx + 1) % n) - endPoint).normalized();
453  gsMatrix<T> startNormal = Tang1o - Tang1i;
454  gsMatrix<T> endNormal = Tang2o - Tang2i;
455  gsMatrix<T> normals(2, 2);
456  normals.col(0) = startNormal.transpose();
457  normals.col(1) = endNormal.transpose();
458 
459  // matrices representing linear equality constraints
460  gsMatrix<T> constraints(6, 8);
461  constraints.setZero();
462  constraints.block(0, 0, 2, 2).setIdentity();
463  constraints.block(2, 6, 2, 2).setIdentity();
464  constraints.block(4, 0, 1, 2) = - startNormal;
465  constraints.block(4, 2, 1, 2) = startNormal;
466  constraints.block(5, 4, 1, 2) = - endNormal;
467  constraints.block(5, 6, 1, 2) = endNormal;
468 
469  gsVector<T> constraintsRHS(6);
470  constraintsRHS.segment(0, 2) = startPoint.transpose();
471  constraintsRHS.segment(2, 2) = endPoint.transpose();
472  constraintsRHS.segment(4, 2).setZero();
473 
474  // matrices representing linear inequalities. each constraint
475  // forces the control points to be inside the convex polygon.
476  gsMatrix<T> inequalities(n * 4, 8);
477  gsVector<T> ineqRHS(n * 4);
478  inequalities.setZero();
479  ineqRHS.setZero();
480  // inequalities.block(0, 0, 1, 4) << startNormal(0, 1), -startNormal(0, 0), -startNormal(0, 1), startNormal(0, 0);
481  // inequalities.block(1, 4, 1, 4) << endNormal(0, 1), -endNormal(0, 0), -endNormal(0, 1), endNormal(0, 0);
482  for(int idxE = 0; idxE < n; idxE++)
483  {
484  gsMatrix<T> edgeDiff = verts.row((idxE + 1) % n) - verts.row(idxE);
485  for(int idxCP = 0; idxCP < 4; idxCP++)
486  {
487  inequalities.block(idxE * 4 + idxCP, 2 * idxCP, 1, 2) << -edgeDiff(0, 1), edgeDiff(0, 0);
488  ineqRHS(idxE * 4 + idxCP) = -edgeDiff(0, 1) * verts(idxE, 0) + edgeDiff(0, 0) * verts(idxE, 1);
489  }
490  }
491 
492  // matrix for computing the second differences
493  gsMatrix<T> secondDifference(4, 8);
494  secondDifference.setZero();
495  for(size_t i = 0; i < 4; i++)
496  {
497  secondDifference(i, i) = 1;
498  secondDifference(i, i + 2) = -2;
499  secondDifference(i, i + 4) = 1;
500  }
501 
502  // matrix for computing the quadratic cost in terms of the second differences
503  gsMatrix<T> costFromSec(4, 4);
504  costFromSec.setIdentity();
505  costFromSec(0, 2) = costFromSec(1, 3) = costFromSec(2, 0) = costFromSec(3, 1) = 0.5;
506 
507  // matrix for computing the total cost as a function of the original control points
508  gsMatrix<T> totalCost = secondDifference.transpose() * costFromSec * secondDifference;
509 
510  // minimise quadratic subject to linear equalities and inequalities
511  gsVector<T> imageCoefsConcat;
512  gsVector<T> zeroCost(8);
513  zeroCost.setZero();
514  constraints.transposeInPlace();
515  inequalities.transposeInPlace();
516 
517  constraintsRHS *= -1;
518  ineqRHS *= -1;
519 
520  solve_quadprog(totalCost, zeroCost,
521  constraints , constraintsRHS,
522  inequalities, ineqRHS,
523  imageCoefsConcat);
524  gsMatrix<T> imageCoefs(2, 4);
525  for(size_t i = 0; i < 4; i++)
526  {
527  imageCoefs.col(i) = imageCoefsConcat.segment(2 * i, 2);
528  }
529  GISMO_ASSERT((imageCoefs.col(0) - startPoint.transpose()).norm() < 0.0001 &&
530  (imageCoefs.col(imageCoefs.cols() - 1) - endPoint.transpose()).norm() < 0.0001,
531  "Quadratic optimization failed to satisfy constraints");
532 
533  // transform the coefficients to restrict to a subset of the original interval
534  // g: matrix to transform basis functions to monomials
535  gsMatrix<T> g(4, 4);
536  g << 1,-3,3,-1,0,3,-6,3,0,0,3,-3,0,0,0,1;
537  // k: matrix to transform monomials in t into monomials in u, where t = k0 + k1 u
538  T k0 = (T(1) - curveProportion) / 2;
539  T k1 = curveProportion;
540  gsMatrix<T> k(4, 4);
541  k.setZero();
542  k(0, 0) = 1;
543  for(index_t i = 1; i < 4; i++) // first row done already
544  {
545  for(index_t j = 0; j < 4; j++)
546  {
547  k(i, j) = k0 * k(i - 1, j);
548  if(j > 0) k(i, j) += k1 * k(i - 1, j - 1);
549  }
550  }
551  // g^(-1): transforms monomials in u into basis functions in u
552  gsMatrix<T> transformedCoefs = imageCoefs * g * k * g.inverse();
553 
554  // TODO: if any control points are outside the polygon, project them to the nearest point on the boundary. that would
555  // ensure that the spline stays inside the polygon.
556 
557  // construct the spline from the coefficients.
558  transformedCoefs.transposeInPlace();
559  addSkeleton(new gsBSpline<T>(0, 1, 0, 3, give(transformedCoefs)));
560  }
561 
562  ~gsTemplate()
563  {
564  freeAll(m_skeleton);
565  }
566 
568  gsTemplate * clone() const
569  {
570  return new gsTemplate(*this);
571  };
572 
573 public:
574 
576  std::ostream &print(std::ostream &os) const
577  {
578  if ( this->size() > 0 )
579  {
580  os << "gsTemplate (" << this->size() << ").\n";
581  //os << "First patch: " << this->patch(0) << ").\n";
582  }
583  else
584  os << "gsTemplate ( empty! ).\n";
585  return os;
586  }
587 
588  short_t parDim() const { return dim(); }
589 
591  index_t nPatches() const { return this->size(); }
592 
593  void addPatch( gsMatrix<T>* c)
594  {
595  this->m_corners.push_back( c );
596  }
597 
598  void addSkeleton( gsBSpline<T> * bs )
599  {
600  m_skeleton.push_back( bs );
601  }
602 
603  std::vector< gsBSpline<T> * > skeleton()
604  {
605  return m_skeleton;
606  }
607 
608  gsBSpline<T> * skeleton(size_t const & i)
609  {
610  return m_skeleton[i];
611  }
612 
613  // to do: add outer()
614  gsPlanarDomain<T> const & domain() const
615  {
616  return m_pdomain;
617  }
618 
619  const gsCurveLoop<T> & outer()
620  {
621  return m_pdomain.outer();
622  }
623 
624  const gsCurveLoop<T> & loop(int i) const
625  {
626  return m_pdomain.loop(i);
627  }
628 
629  int skeletonSize()
630  {
631  return m_skeleton.size();
632  }
633 // Data members
634 private:
635 
638 
639  std::vector< gsBSpline<T> * > m_skeleton; // skeleton represents "segments" inside the template
640 
641  gsPlanarDomain<T> m_pdomain;
642 
644  gsMatrix<T> ponctuals;
645 
646 public:
647  // Needed since m_pdomain is 16B aligned
648 # define Eigen gsEigen
649  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
650 # undef Eigen
651 
652 }; // class gsTemplate
653 
655 template<class T>
656 std::ostream &operator<<(std::ostream &os, const gsTemplate<T>& b)
657 {return b.print(os); }
658 
659 } // namespace gismo
Class gsNurbsCreator provides some simple examples of Nurbs Geometries.
Definition: gsNurbsCreator.h:36
std::vector< T * > release(std::vector< unique_ptr< T > > &cont)
Takes a vector of smart pointers, releases them and returns the corresponding raw pointers...
Definition: gsMemory.h:228
Class gsTemplate object.
Definition: gsTemplate.h:77
Provides declaration of the BoxTopology class.
short_t dim() const
Dimension of the boxes.
Definition: gsBoxTopology.h:98
#define short_t
Definition: gsConfig.h:35
Provides structs and classes related to interfaces and boundaries.
S give(S &x)
Definition: gsMemory.h:266
Provides declaration of Geometry abstract interface.
#define index_t
Definition: gsConfig.h:32
gsTemplate(const std::vector< T > &intervalWidths, const gsMatrix< T > &verts, size_t startIdx, size_t endIdx, T curveProportion)
Definition: gsTemplate.h:422
gsTemplate()
Default empty constructor.
Definition: gsTemplate.h:89
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
gsMatrix< T > * m_corners
List of corner points.
Definition: gsTemplate.h:637
A B-spline function of one argument, with arbitrary target dimension.
Definition: gsBSpline.h:50
static BSplinePtr BSplineFatCircle(T const &r=(T)(1), T const &x=0, T const &y=0)
Inexact circle using B-splines.
Definition: gsNurbsCreator.hpp:1034
memory::shared_ptr< gsBoxTopology > Ptr
Shared pointer for gsBoxTopology.
Definition: gsBoxTopology.h:43
#define gsWarn
Definition: gsDebug.h:50
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition: gsMemory.h:312
Class representing a Planar domain with an outer boundary and a number of holes.
Definition: gsPlanarDomain.h:43
index_t nPatches() const
Number of patches.
Definition: gsTemplate.h:591
Provides functions to generate structured point data.
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition: gsTemplate.h:576
gsTemplate * clone() const
Clone function. Used to make a copy of the object.
Definition: gsTemplate.h:568
A closed loop given by a collection of curves.
Definition: gsCurveLoop.h:36
Defines a topological arrangement of a collection of &quot;boxes&quot; (e.g., parameter domains that map to phy...
Definition: gsBoxTopology.h:38
gsTemplate(int r, bool)
square template constructed providing the 4 corners Bb matrix (2,4) (x and y coord.)
Definition: gsTemplate.h:347
Provides declaration of the NurbsCreator struct.
Interface for gsCurveLoop class, representing a loop of curves, in anticlockwise order.
gsBoxTopology Base
Shared pointer for gsTemplate.
Definition: gsTemplate.h:82