G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsTrimSurface.hpp
Go to the documentation of this file.
1 
15 #pragma once
16 
17 #include <gsUtils/gsMesh/gsMesh.h>
19 
21 
22 #include <gsNurbs/gsBSpline.h>
23 #include <gsNurbs/gsKnotVector.h>
24 
25 namespace gismo
26 {
27 
28 template <class T>
29 std::ostream &gsTrimSurface<T>::print(std::ostream &os) const
30 {
31  os << "Trimmed surface with "<< nTrims()<<" trim loop(s).\n";
32  os << "Master surface: "<< *m_surface <<"\n";
33  os << "Domain: "<< *m_domain <<"\n";
34  return os;
35 }
36 
37 template <class T>
38 gsTrimSurface<T>::gsTrimSurface(gsMatrix<T> const & corner, int patchDeg1, int patchDeg2, int curveDeg)
39 {
40  // Construct the Bezier knot vector for all trimming curves
41  gsKnotVector<T> kv(0, 1, 0, curveDeg+1);
42  unsigned int ntcp = kv.size() - kv.degree() - 1;
43 
44  // Initialize a trimming curve loop
45  gsCurveLoop<T> * tloop = new gsCurveLoop<T>();
46 
47  // run over the 4 corner vertices of the unit square (the fifth one is the first one)
48  gsMatrix<T> DomCor = gsMatrix<T>(5,2);
49  DomCor << 0, 0, 1, 0, 1, 1, 0, 1, 0, 0;
50  for (int ic=0; ic < 4; ic++)
51  {
52  // Define a spline curve from the current vertex to the next one
53  gsMatrix<T> tcp (ntcp, 2);
54  for (unsigned int i=0; i < ntcp; i++)
55  {
56  for (unsigned int xi=0; xi < 2; xi++)
57  {
58  tcp(i,xi) = DomCor(ic,xi) + (T)(i) / ((T)(ntcp)-(T)(1)) * (DomCor(ic+1,xi)-DomCor(ic,xi));
59  }
60  }
61  tloop->insertCurve( new gsBSpline<T>(0,1,0,curveDeg, give(tcp)) );
62  }
63 
64  // Then construct a planar domain with only an outer loop *tloop*
65  gsPlanarDomain<T> * domain1= new gsPlanarDomain<T>(tloop);
66 
67  // Define the master NURBS surface: degree 2, Bezier patch: todo: derive cps from corners
68  gsKnotVector<T> KV1 = gsKnotVector<T>(0, 1, 0, patchDeg1+1);
69  gsKnotVector<T> KV2 = gsKnotVector<T>(0, 1, 0, patchDeg2+1);
70  typename gsTensorBSpline<2,T>::Ptr tp1(new gsTensorBSpline<2,T>(corner, KV1, KV2));
71 
72  this->m_domain = domain1;
73  this->m_surface = tp1;
74 }
75 
76 template <class T>
78 {
79  std::vector< gsCurve<T>* > trimLoop = m_domain->outer().curves();
80  //edges of the angle in the parameter domain
81  gsMatrix<T> CPside2 = (trimLoop[sourceID]->coefs());
82  gsMatrix<T> AngleVertex(2,1); // vertex of the trimmed surface angle
83  AngleVertex << CPside2(0,0), CPside2(0,1);
84  return m_surface->jacobian(AngleVertex);
85 }
86 
87 
88 template <class T>
89 gsVector3d<T> gsTrimSurface<T>::cornerNormal(int const & sourceID) const
90 {
91  gsMatrix<T> cj = this->derivatives(sourceID);
92  gsVector3d<T> dx = cj.col(0);
93  gsVector3d<T> dy = cj.col(1);
94  gsVector3d<T> n = dx.cross(dy);
95  n.normalize();
96  return n;
97 }
98 
99 
100 template <class T>
101 void gsTrimSurface<T>::cuttingAngles(int const & sourceID,int const & targetID,T* angle, T* angle1, T* angle2, bool const & isCCWviewFromNormal) const
102 {
103  std::vector< gsCurve<T>* > trimLoop = m_domain->outer().curves();
104  // source
105  gsMatrix<T> CPside2 = (trimLoop[sourceID]->coefs());
106  gsMatrix<T> AngleVertex(2,1); // vertex of the trimmed surface angle
107  AngleVertex << CPside2(0,0), CPside2(0,1);
108  // target
109  gsMatrix<T> targetCP = (trimLoop[targetID]->coefs());
110  gsMatrix<T> TargetVertex(2,1);
111  TargetVertex << targetCP(0,0), targetCP(0,1);
112  // cutting edge
113  gsMatrix<T> cuttingEdge = TargetVertex-AngleVertex;
114 
115  //edges of the angle in space
116  gsMatrix<T> tangent_side1 = TangentCoefs_prev(sourceID);
117  gsMatrix<T> tangent_side2 = TangentCoefs_next(sourceID);
118  gsVector3d<T> tangent_side1_space;
119  gsVector3d<T> tangent_side2_space;
120 
121  gsMatrix<T> corJacobian = derivatives(sourceID);
122  tangent_side1_space = corJacobian*tangent_side1;
123  tangent_side2_space = corJacobian*tangent_side2;
124 
125  gsVector3d<T> cuttingEdge_space = corJacobian*cuttingEdge;
126  //
127  gsVector3d<T> normal = unitNormal(AngleVertex);
128  if (isCCWviewFromNormal==false)
129  {
130  normal = - normal;
131  };
132 
133  *angle1 = conditionedAngle<T>(cuttingEdge_space, tangent_side1_space, normal);
134  *angle2 = conditionedAngle<T>(tangent_side2_space, cuttingEdge_space, normal);
135  *angle = conditionedAngle<T>(tangent_side2_space, tangent_side1_space, normal);
136 }
137 
138 template <class T>
139 void gsTrimSurface<T>::sampleLoop_into( int loopNumber, int npoints, gsMatrix<T> & u) const
140 {
141  assert( (loopNumber>=0) && (loopNumber < m_domain->numLoops()) );
142 
143  gsMatrix<T> pts = m_domain->sampleLoop(loopNumber, npoints);
144  return m_surface->eval_into(pts, u); // Compute points on curve of the surface
145 }
146 
147 template <class T>
148 void gsTrimSurface<T>::sampleCurve_into( int loopNumber, int curveNumber, int npoints, gsMatrix<T> & u ) const
149 {
150  assert( (loopNumber>=0) && (loopNumber < m_domain->numLoops()) );
151  assert( (curveNumber>=0) && (curveNumber < m_domain->loop(loopNumber).size() ) );
152 
153  gsMatrix<T> pts = m_domain->sampleCurve(loopNumber, curveNumber, npoints);
154  //m_domain->sample(pts,loopNumber,npoints);
155  return m_surface->eval_into(pts, u); // Compute points on curve of the surface
156 }
157 
158 
159 template <class T>
161 {
162  gsMatrix<T> corJacobian = derivatives(sourceID);
163  gsMatrix<T> tangent_side1 = UnitTangentCoefs_prev(sourceID, corJacobian);
164  gsMatrix<T> tangent_side2 = UnitTangentCoefs_next(sourceID, corJacobian);
165  gsVector<T> coefs(2);
166  coefs(0) = tangent_side1(0) + tangent_side2(0);
167  coefs(1) = tangent_side1(1) + tangent_side2(1);
168 
169  return coefs;
170 }
171 
172 template <class T>
174 {
175  gsMatrix<T> corJacobian = derivatives(sourceID);
176  gsVector3d<T> tangent_side1 = UnitTangentCoefs_prev(sourceID, corJacobian);
177  gsVector3d<T> tangent_side2 = UnitTangentCoefs_next(sourceID, corJacobian);
178  gsVector<T> coefs(2);
179  coefs = TangentCoefs_bisect(sourceID);
180  return ( normal.dot( tangent_side1.cross( tangent_side2 ) ) >= 0 ) ? coefs: (-coefs).eval();
181 }
182 
183 template <class T>
184 gsBSpline<T> gsTrimSurface<T>::cuttingCurve(int const & sourceID,int const & targetID) const
185 {
186  std::vector< gsCurve<T>* > trimLoop = m_domain->outer().curves();
187  int curveDeg = trimLoop[sourceID]->degree();
188  if (curveDeg<=1)
189  {
190  gsWarn<<"gsTrimSurface: degree of trimming curve is less than 2, this will fail to work in most cases. The degree is set to 3 instead.\n";
191  curveDeg=3;
192  }
193  gsKnotVector<T> kv(0, 1, 0, curveDeg+1); // todo: get kv from curve00.basis().knots(),curve00.basis().degree()
194 
195  gsMatrix<T> CPside2 = (trimLoop[sourceID]->coefs());
196  gsMatrix<T> targetCP = (trimLoop[targetID]->coefs());
197 
198  gsMatrix<T> tg1 = TangentCoefs_bisect(sourceID); //tangent 1
199  gsMatrix<T> tg2 = TangentCoefs_bisect(targetID); // tangent 2
200 
201  // weights
202  T w_reg = 1;
203  T w_app = 0;
204 
205  // Exact constraints: point interpolation
206  short_t dimPI = 1; // dimension of space of preImage
207  short_t dimI = 2; // dimension of space of image
208  int nip=2; // number of interpolating points
209  int nn=2; // number of prescribed normals
210  gsMatrix<T> image(dimI,nip);
211  gsMatrix<T> preImage(dimPI,nip);
212  gsMatrix<T> normal(dimI,nn);
213  gsMatrix<T> preNormal(dimPI,nn);
214  preImage << kv[0],kv[kv.size()-1];
215  preNormal << kv[0],kv[kv.size()-1];
216  image.col(0) = CPside2.row(0);
217  image.col(1) = targetCP.row(0);
218  normal(0,0) = -tg1(1);
219  normal(1,0) = tg1(0);
220  normal(0,1) = -tg2(1);
221  normal(1,1) = tg2(0);
222 
223  // Approximate constraints
224  int nipApp = 1;
225  gsMatrix<T> preImageApp(dimPI,nipApp);
226  gsMatrix<T> imageApp(dimI,nipApp);
227  preImageApp << .5*kv[0]+.5*kv[kv.size()-1];
228  imageApp = .5*CPside2.row(0).transpose() + .5*targetCP.row(0).transpose();
229 
230  gsMatrix<T> pointResiduals, normalResiduals;
231  return gsInterpolate(kv,preImage,image,preNormal,normal,preImageApp,imageApp,w_reg,w_app, pointResiduals, normalResiduals);
232 }
233 
234 
235 template <class T>
236 memory::unique_ptr<gsMesh<T> > gsTrimSurface<T>::toMesh(int npoints) const
237 {
238  typename gsMesh<T>::uPtr msh = m_domain->toMesh(npoints);
239  gsMatrix<T> tmp;
240 
241  // For all vertices of the msh, push forward the value by m_surface
242  for (size_t i = 0; i!= msh->numVertices(); ++i)
243  {
244  m_surface->eval_into( msh->vertex(i).topRows(2), tmp );
245  msh->vertex(i).topRows(m_surface->geoDim() ) = tmp;
246  }
247 
248  return msh;
249 }
250 
251 template <class T>
252 gsMatrix<T> gsTrimSurface<T>::UnitTangentCoefs_next(int const & sourceID,gsMatrix<T> const & corJacobian) const
253 {
254  gsMatrix<T> tangent_side2 = TangentCoefs_next(sourceID);
255  gsMatrix<T> spatialTangent = tangent_side2(0)*corJacobian.col(0)+tangent_side2(1)*corJacobian.col(1);
256  tangent_side2 = tangent_side2*((T)(1)/spatialTangent.norm());
257 
258  return tangent_side2;
259 }
260 
261 template <class T>
262 gsMatrix<T> gsTrimSurface<T>::UnitTangentCoefs_prev(int const & sourceID,gsMatrix<T> const & corJacobian) const
263 {
264  gsMatrix<T> tangent_side1 = TangentCoefs_prev(sourceID);
265  gsMatrix<T> spatialTangent = tangent_side1(0)*corJacobian.col(0)+tangent_side1(1)*corJacobian.col(1);
266  tangent_side1 = tangent_side1*((T)(1)/spatialTangent.norm());
267 
268  return tangent_side1;
269 }
270 
271 template <class T>
273 {
274  std::vector< gsCurve<T>* > trimLoop = m_domain->outer().curves();
275  gsMatrix<T> CPside2 = (trimLoop[sourceID]->coefs());
276  gsMatrix<T> tangent_side2(2,1); // side 2 of the trimmed surface angle
277  tangent_side2 << CPside2(1,0)-CPside2(0,0),CPside2(1,1)-CPside2(0,1);
278 
279  return tangent_side2;
280 }
281 
282 template <class T>
284 {
285  std::vector< gsCurve<T>* > trimLoop = m_domain->outer().curves();
286  int priorToSource(0);
287  if ( sourceID>0 ) priorToSource = sourceID-1; else priorToSource = trimLoop.size()-1;
288  gsMatrix<T> CPside1 = (trimLoop[priorToSource]->coefs());
289  int const nrow = CPside1.rows();
290  gsMatrix<T> tangent_side1(2,1); // side 1 of the trimmed surface angle
291  tangent_side1 << CPside1(nrow-2,0)-CPside1(nrow-1,0),CPside1(nrow-2,1)-CPside1(nrow-1,1);
292  return tangent_side1;
293 }
294 
295 
296 template <typename T>
297 T gsTrimSurface<T>::getLengthOfCurve(const int loopNumber,
298  const int curveNumber,
299  const T eps,
300  const int nmbSegments) const
301 {
302  const gsCurve<T>& curve = getCurve(loopNumber, curveNumber);
303  gsMatrix<T> support = curve.support();
304 
305  gsVector<T> supStart = support.col(0);
306  gsVector<T> supEnd = support.col(1);
307 
308  gsMatrix<T> params;
309 
310  int n = nmbSegments;
311  T length = 1;
312  T newLength = 0;
313 
314  while (eps < math::abs(length - newLength))
315  {
316  params = uniformPointGrid(supStart, supEnd, n);
317  length = newLength;
318 
319  newLength = getLengthOfCurve(curve, params, false);
320  n += 10;
321  }
322 
323  return newLength;
324 }
325 
326 
327 // =============================================================================
328 // private member functions
329 // =============================================================================
330 
331 template <class T>
333  const gsMatrix<T>& u,
334  gsMatrix<T>& result) const
335 {
336  gsMatrix<T> curveResult;
337  curve.eval_into(u, curveResult);
338  m_surface->eval_into(curveResult, result);
339 }
340 
341 
342 template <typename T>
344  const T a,
345  const T b,
346  const int quadPoints) const
347 {
348  gsVector<index_t> tmp(1);
349  tmp(0) = quadPoints;
350 
351  gsGaussRule<T> gaussRule;
352  gaussRule.setNodes(tmp);
353 
354  gsMatrix<T> nodes;
355  gsVector<T> weights;
356 
357  gsVector<T> lower(1);
358  gsVector<T> upper(1);
359  lower(0) = a;
360  upper(0) = b;
361 
362  gaussRule.mapTo(lower, upper, nodes, weights);
363 
364  T length = 0;
365  for (int col = 0; col != nodes.cols(); col++)
366  {
367  gsMatrix<T> param(1, 1);
368  param(0, 0) = nodes(0, col);
369 
371  gsMatrix<T> jacobian;
372  gsMatrix<T> pointOnCurve;
373 
374  curve.eval_into(param, pointOnCurve);
375  curve.deriv_into(param, grad);
376  m_surface->jacobian_into(pointOnCurve, jacobian);
377 
378  gsMatrix<T> derivative = jacobian * grad;
379 
380  T value = 0;
381  for (int row = 0; row != derivative.rows(); row++)
382  {
383  value += derivative(row, 0) * derivative(row, 0);
384  }
385 
386  value = math::sqrt(value);
387  length += weights(col) * value;
388  }
389 
390  return length;
391 }
392 
393 
394 template <typename T>
396  gsMatrix<T>& params,
397  bool linear) const
398 {
399  T length = 0;
400 
401  if (linear)
402  {
403  gsMatrix<T> points;
404  evalCurve_into(curve, params, points);
405 
406  for (int col = 0; col < points.cols() - 1; col++)
407  {
408  gsVector<T> p1 = points.col(col);
409  gsVector<T> p2 = points.col(col + 1);
410 
411  // compute distance between this two points
412  T dst = 0;
413  for (int row = 0; row < p1.rows(); row++)
414  {
415  T tmp = (p1(row) - p2(row));
416  tmp *= tmp;
417  dst += tmp;
418  }
419 
420  length += math::sqrt(dst);
421  }
422  }
423  else
424  {
425  for (int col = 0; col != params.cols() - 1; col++)
426  {
427  const T a = params(0, col);
428  const T b = params(0, col + 1);
429 
430  T arc = arcLength(curve, a, b);
431 
432  length += arc;
433  }
434  }
435 
436  return length;
437 }
438 
439 
440 template <typename T>
441 void gsTrimSurface<T>::fromArcsToParams(const int loopNumber,
442  const int curveNumber,
443  const gsVector<T>& arcs,
444  gsVector<T>& parameters,
445  const T eps)
446 {
447  const gsCurve<T>& curve = getCurve(loopNumber, curveNumber);
448 
449  gsMatrix<T> support = curve.support();
450 
451  gsVector<T> supStart = support.col(0);
452  gsVector<T> supEnd = support.col(1);
453 
454  gsMatrix<T> par = uniformPointGrid(supStart, supEnd, arcs.size() * 10);
455 
456  parameters.resize(arcs.size());
457 
458 
459  T curArc = 0; // current arc
460  T oldParam = supStart(0); // variable to remember old parameter
461  T newParam = oldParam;
462  int parCounter = 1; // how many parameters (par!) we already used
463 
464  for (int p = 0; p != arcs.size(); p++)
465  {
466  const T arc = arcs(p);
467 
468  // we build curent arc untill we reach arc
469  while (curArc < arc)
470  {
471  oldParam = newParam;
472  newParam = par(0, parCounter);
473  parCounter++;
474 
475  T dst = arcLength(curve, oldParam, newParam);
476  curArc += dst;
477 
478  if (parCounter == par.cols())
479  break;
480  }
481 
482  // in case we just missed last point -------------------------------
483  if (parCounter == par.cols() && p == arcs.size() - 1)
484  {
485  parameters(p) = supEnd(0);
486  break;
487  }
488 
489  if (parCounter == par.cols() && p != arcs.size() - 1)
490  {
491  GISMO_ERROR("This should not happen. Last arc is too long...\n");
492  } // ---------------------------------------------------------------
493 
494 
495  // here we know that arc <= curArc,
496  // we want to find parameter t, that arc == curArc
497  // we do this with binary search (bisection) technique
498  if (arc == curArc)
499  {
500  parameters(p) = newParam;
501  }
502  else
503  {
504  // find parameter via binary search
505  T t = findParameter(curve,
506  arc, curArc, oldParam, newParam,
507  eps);
508  parameters(p) = t;
509  }
510  }
511 }
512 
513 
514 template <typename T>
516  const T arc,
517  T curArc,
518  T lowParam,
519  T uppParam,
520  const T eps)
521 {
522  // setting upper arc and lower arc
523  T arcUpp = curArc;
524  T arcLow = curArc - arcLength(curve, lowParam, uppParam);
525 
526  T midParam;
527 
528  // do the binary search
529  while (eps < math::abs(arcUpp - arcLow))
530  {
531  midParam = lowParam + (uppParam - lowParam) / (T)(2);
532 
533  // "arc" distance
534  T dst = arcLength(curve, midParam, uppParam);
535 
536  if (arc == arcUpp - dst)
537  {
538  return midParam;
539  }
540  else if (arc < arcUpp - dst)
541  {
542  arcUpp -= dst;
543  uppParam = midParam;
544  }
545  else
546  {
547  arcLow = arcUpp - dst;
548  lowParam = midParam;
549  }
550  }
551 
552  midParam = lowParam + (uppParam - lowParam) / (T)(2);
553 
554  return midParam;
555 }
556 
557 
558 } // namespace gismo
Knot vector for B-splines.
A fixed-size, statically allocated 3D vector.
Definition: gsVector.h:218
Class for a trim surface.
Definition: gsTrimSurface.h:33
Abstract base class representing a curve.
Definition: gsCurve.h:30
#define short_t
Definition: gsConfig.h:35
A tensor product of d B-spline functions, with arbitrary target dimension.
Definition: gsTensorBSpline.h:44
T arcLength(const gsCurve< T > &curve, const T a, const T b, const int quadPoints=4) const
Definition: gsTrimSurface.hpp:343
S give(S &x)
Definition: gsMemory.h:266
gsMatrix< T > TangentCoefs_prev(int const &sourceID) const
Return the coefficients of the representation of the unit tangent of the edge COMING to vertex source...
Definition: gsTrimSurface.hpp:283
size_t size() const
Number of knots (including repetitions).
Definition: gsKnotVector.h:242
gsMatrix< T > TangentCoefs_next(int const &sourceID) const
Return the coefficients of the representation of the unit tangent of the edge ENAMATING from vertex s...
Definition: gsTrimSurface.hpp:272
void setNodes(gsVector< index_t > const &numNodes, unsigned digits=0)
Initialize quadrature rule with numNodes number of quadrature points per integration variable...
Definition: gsGaussRule.hpp:95
memory::unique_ptr< gsMesh< T > > toMesh(int npoints=50) const
Return a triangulation of the trimmed surface.
Definition: gsTrimSurface.hpp:236
gsMatrix< T > uniformPointGrid(const gsVector< T > &lower, const gsVector< T > &upper, int numPoints=1000)
Definition: gsPointGrid.hpp:94
gsVector3d< T > cornerNormal(int const &sourceID) const
Compute the surface normal at a corner.
Definition: gsTrimSurface.hpp:89
A B-spline function of one argument, with arbitrary target dimension.
Definition: gsBSpline.h:50
gsBSpline< T > gsInterpolate(gsKnotVector< T > &kv, const gsMatrix< T > &preImage, const gsMatrix< T > &image, const gsMatrix< T > &preNormal, const gsMatrix< T > &normal, const gsMatrix< T > &preImageApp, const gsMatrix< T > &imageApp, T const &w_reg, T const &w_app, gsMatrix< T > &outPointResiduals, gsMatrix< T > &outNormalResiduals)
Definition: gsModelingUtils.hpp:392
gsMatrix< T > derivatives(int sourceID) const
Definition: gsTrimSurface.hpp:77
#define gsWarn
Definition: gsDebug.h:50
virtual void deriv_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate derivatives of the function at points u into result.
Definition: gsGeometry.hpp:170
gsBSpline< T > cuttingCurve(int const &sourceID, int const &targetID) const
Define a spline curve connecting source-target
Definition: gsTrimSurface.hpp:184
gsMatrix< T > UnitTangentCoefs_prev(int const &sourceID, gsMatrix< T > const &corJacobian) const
Return the coefficients of the representation of the unit tangent of the edge COMING to vertex source...
Definition: gsTrimSurface.hpp:262
T getLengthOfCurve(const int loopNumber, const int curveNumber, const T eps=1e-6, const int nmbSegments=50) const
Computes length of curveNumber-th curve in loopNumber-th loop.
Definition: gsTrimSurface.hpp:297
void fromArcsToParams(const int loopNumber, const int curveNumber, const gsVector< T > &arcs, gsVector< T > &parameters, const T eps)
Definition: gsTrimSurface.hpp:441
Provides declaration of the Mesh class.
virtual void mapTo(const gsVector< T > &lower, const gsVector< T > &upper, gsMatrix< T > &nodes, gsVector< T > &weights) const
Maps quadrature rule (i.e., points and weights) from the reference domain to an element.
Definition: gsQuadRule.h:177
void evalCurve_into(int loopNumber, int curveNumber, const gsMatrix< T > &u, gsMatrix< T > &result) const
Definition: gsTrimSurface.h:133
void cuttingAngles(int const &sourceID, int const &targetID, T *angle, T *angle1, T *angle2, bool const &isCCWviewFromNormal=true) const
Compute angle discrepancy between the angles defined by the edge source-target with the sides of the ...
Definition: gsTrimSurface.hpp:101
Represents a B-spline curve/function with one parameter.
Class representing a Planar domain with an outer boundary and a number of holes.
Definition: gsPlanarDomain.h:43
Utility functions required by gsModeling classes.
gsMatrix< T > support() const
Returns the range of parameters (same as parameterRange())
Definition: gsGeometry.hpp:193
void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate the function at points u into result.
Definition: gsGeometry.hpp:166
EIGEN_STRONG_INLINE grad_expr< E > grad(const E &u)
The gradient of a variable.
Definition: gsExpressions.h:4490
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
Class for representing a knot vector.
Definition: gsKnotVector.h:79
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4486
gsTrimSurface()
Default empty constructor.
Definition: gsTrimSurface.h:42
gsVector< T > TangentCoefs_bisect(int const &sourceID) const
Compute the (scale of) tangent of the curve emanateing from a vertex in the parameter whose image bis...
Definition: gsTrimSurface.hpp:160
A closed loop given by a collection of curves.
Definition: gsCurveLoop.h:36
Class that represents the (tensor) Gauss-Legendre quadrature rule.
Definition: gsGaussRule.h:27
gsMatrix< T > UnitTangentCoefs_next(int const &sourceID, gsMatrix< T > const &corJacobian) const
Return the coefficients of the representation of the unit tangent of the edge ENAMATING from vertex s...
Definition: gsTrimSurface.hpp:252
int degree() const
Returns the degree of the knot vector.
Definition: gsKnotVector.hpp:700
memory::shared_ptr< gsTensorBSpline > Ptr
Shared pointer for gsTensorBSpline.
Definition: gsTensorBSpline.h:59
T findParameter(const gsCurve< T > &curve, const T arc, T curArc, T lowParam, T uppParam, const T eps)
Definition: gsTrimSurface.hpp:515
Provides declaration of gsPlanarDomain class. The outer boundary (m_loops[0]) is a loop of curves...
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition: gsTrimSurface.hpp:29