G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsTrimSurface.h
Go to the documentation of this file.
1 
15 #pragma once
16 
17 #include <iostream>
18 #include <gsCore/gsSurface.h>
20 #include <gsUtils/gsPointGrid.h>
21 
22 namespace gismo
23 {
24 
32 template<class T>
34 {
35 
36 public:
37 
38  typedef memory::shared_ptr<gsTrimSurface> Ptr;
39  typedef memory::unique_ptr<gsTrimSurface> uPtr;
40 
42  gsTrimSurface() : m_domain(NULL) { }
43 
46  : m_surface(g), m_domain(d)
47  { }
48 
49  gsTrimSurface( gsSurface<T>* g, gsPlanarDomain<T> * d) : m_surface(g), m_domain(d)
50  { }
51 
54  gsTrimSurface(gsMatrix<T> const & corner, int patchDeg1, int patchDeg2, int curveDeg);
55 
56  gsTrimSurface(const gsTrimSurface& other)
57  {
58  m_surface = other.m_surface;
59  m_domain = other.m_domain->clone().release();
60  }
61 
62  gsTrimSurface& operator=(const gsTrimSurface& other)
63  {
64  m_surface = other.m_surface;
65  delete m_domain;
66  m_domain = other.m_domain->clone().release();
67  return *this;
68  }
69 
70  ~gsTrimSurface() //destructor
71  {
72  // don't delete m_surface since it is now a shared_ptr - it will take care of itself
73  // delete m_surface;
74  delete m_domain;
75  }
76 
78  gsTrimSurface<T> * clone() const { return new gsTrimSurface(*this); }
79 
81  std::ostream &print(std::ostream &os) const;
82 
83  friend std::ostream& operator<< (std::ostream& os, const gsTrimSurface& ts)
84  { return ts.print(os); }
85 
86  gsBasis<T> & basis() const { return m_surface->basis(); }
87 
88  short_t geoDim() const { return m_surface->geoDim(); }
89 
90  //bool isProjective() const { return m_surface->isProjective(); }
91 
92  typename gsSurface<T>::Ptr getTP() const { return m_surface; }
93 
94  int nTrims() const { return m_domain->numLoops(); }
95 
97  gsCurveLoop<T>& boundaryLoop() { return m_domain->loop(0); }
98 
100  const gsCurveLoop<T>& boundaryLoop() const { return m_domain->loop(0); }
101 
103  gsCurve<T>& getCurve(int loopNumber, int curveNumber) const
104  {
105  return m_domain->curve(loopNumber, curveNumber);
106  }
107 
108  void sampleLoop_into(int loopNumber, int npoints, gsMatrix<T> & u) const;
109 
110  gsMatrix<T> sampleLoop(int loopNumber, int npoints = 100) const
111  {
112  gsMatrix<T> u;
113  sampleLoop_into(loopNumber, npoints, u);
114  return u;
115  }
116 
117  gsMatrix<T> sampleBoundary( int npoints = 100) const
118  { return sampleLoop(0, npoints); }
119 
120  void sampleCurve_into( int loopNumber, int curveNumber, int npoints, gsMatrix<T> & u) const;
121 
122  gsMatrix<T> sampleCurve( int loopNumber, int curveNumber, int npoints = 100) const
123  {
124  gsMatrix<T> u;
125  sampleCurve_into(loopNumber, curveNumber, npoints, u);
126  return u;
127  }
128 
133  void evalCurve_into(int loopNumber,
134  int curveNumber,
135  const gsMatrix<T>& u,
136  gsMatrix<T>& result) const
137  {
138  GISMO_ASSERT(0 <= loopNumber && loopNumber < m_domain->numLoops(),
139  "Loop number is out of range!");
140  GISMO_ASSERT(0 <= curveNumber &&
141  curveNumber < m_domain->loop(loopNumber).size(),
142  "Curve number is out of range!");
143 
144  const gsCurve<T> & curve = getCurve(loopNumber, curveNumber);
145  evalCurve_into(curve, u, result);
146  }
147 
149  gsMatrix<T> evalCurve(int loopNumber,
150  int curveNumber,
151  const gsMatrix<T>& u) const
152  {
153  gsMatrix<T> result;
154  evalCurve_into(loopNumber, curveNumber, u, result);
155  return result;
156  }
157 
158  gsMatrix<T> sampleBoundaryCurve( unsigned curveNumber, int npoints = 100) const
159  { return sampleCurve(0, curveNumber, npoints); }
160 
169  gsMatrix<T>& result) const
170  {
171  m_surface->eval_into(u, result);
172  }
173 
180  {
181  gsMatrix<T> result;
182  evalSurface_into(u, result);
183  return result;
184  }
185 
186 
187  gsPlanarDomain<T> & domain() { return *m_domain; }
188  const gsPlanarDomain<T> & domain() const { return *m_domain; }
189 
194  gsMatrix<T> splitCurve(size_t loopId, size_t curveId, T lengthRatio=.5)
195  {return m_domain->splitCurve(loopId,curveId,lengthRatio);}
196 
199  gsMatrix<T> derivatives(int sourceID) const;
200 
202  gsVector3d<T> cornerNormal(int const & sourceID) const;
203 
205  void cuttingAngles(int const & sourceID,int const & targetID,T* angle, T* angle1, T* angle2,bool const & isCCWviewFromNormal=true) const;
206 
208  gsVector<T> TangentCoefs_bisect(int const & sourceID) const;
209 
212  gsVector<T> TangentCoefs_bisect(int const & sourceID,gsVector3d<T> normal) const;
213 
215  gsBSpline<T> cuttingCurve(int const & sourceID,int const & targetID) const;
216 
218  memory::unique_ptr<gsMesh<T> > toMesh(int npoints = 50) const;
219 
221  gsMatrix<T> UnitTangentCoefs_next(int const & sourceID,gsMatrix<T> const & corJacobian) const;
222 
224  gsMatrix<T> UnitTangentCoefs_prev(int const & sourceID,gsMatrix<T> const & corJacobian) const;
225 
227  gsMatrix<T> TangentCoefs_next(int const & sourceID) const;
228 
230  gsMatrix<T> TangentCoefs_prev(int const & sourceID) const;
231 
232  gsMatrix<T> vertexCoord(int const & loopID, int const & curveID) const
233  {
234  gsMatrix<T> cp = m_domain->curve(loopID,curveID).coefs();
235  gsMatrix<T> vert(2,1);
236  gsMatrix<T> vert3D;
237  vert << cp(0,0), cp(0,1);
238  (*m_surface).eval_into(vert,vert3D);
239  return vert3D;
240  }
241 
244  {
245  gsMatrix<T,3> Jacobian = m_surface->jacobian(point);
246  gsMatrix<T,3> res = Jacobian.col(0).cross(Jacobian.col(1)).normalized();
247  return res;
248  }
249 
251  gsMatrix<T> sampleNormal(int loopNumber, int curveNumber, size_t npoints) const
252  {
253  assert( (loopNumber>=0) && (loopNumber < m_domain->numLoops()) );
254  assert( (curveNumber>=0) && (curveNumber < m_domain->loop(loopNumber).size() ) );
255  //gsMatrix<T> u( this->geoDim(), npoints );
256 
257  gsMatrix<T> u(3, npoints);
258 
259  gsMatrix<T> pts = m_domain->sampleCurve(loopNumber, curveNumber, npoints);
260  gsMatrix<T> nm(3,1);
261 
262  for (size_t i=0; i < npoints; i++)
263  {
264  u.col(i) = unitNormal(pts.col(i));
265  }
266 
267  return u;
268  }
269 
271  gsMatrix<T> trimCurTangents(int loopN, int curveN, size_t npoints) const
272  {
273  gsMatrix<T> interval = m_domain->curve(loopN,curveN).parameterRange();
274  // sample parameter points
275  gsMatrix<T> tval = gsPointGrid(interval(0,0), interval(0,1), npoints);
276  gsMatrix<T> trimCur = m_domain->curve(loopN,curveN).eval(tval);
277  gsMatrix<T> trimCurDev = m_domain->curve(loopN,curveN).jacobian(tval);
278  gsMatrix<T> trimCurJac = m_surface->jacobian( trimCur );
279  //gsMatrix<T> tangents(this->geoDim(),npoints);
280  gsMatrix<T> tangents(3,npoints);
281 
282  for (size_t i=0; i<=npoints-1; i++)
283  {
284  tangents.col(i) = trimCurJac.middleCols( 2*i,2 )*trimCurDev.col(i);
285  }
286  return tangents;
287  }
288 
289 
290  void cleanEndpoints(T eps)
291  {
292  GISMO_UNUSED(eps);
293  gsMatrix<T> supp = this->m_surface->support();
294  size_t n = domain().loop(0).curves().size();
295  for(size_t i = 0; i < n; i++)
296  {
297  gsCurve<T> &thisCurve = domain().loop(0).curve(i);
298  for(size_t dim = 0; dim < 2; dim++)
299  {
300  gsMatrix<T> &coefs = thisCurve.coefs();
301  GISMO_ASSERT(coefs(0, dim) >= supp(dim, 0) - eps, "invalid curve endpoint");
302  coefs(0, dim) = std::max(coefs(0, dim), supp(dim, 0));
303  GISMO_ASSERT(coefs(coefs.rows() - 1, dim) <= supp(dim, 1) + eps, "invalid curve endpoint");
304  coefs(coefs.rows() - 1, dim) = std::min(coefs(coefs.rows() - 1, dim), supp(dim, 1));
305  }
306  }
307  }
308 
310  T nearestPoint(int loopNumber, int curveNumber, int nTrialPoints, int nIterations, const gsMatrix<T> &spacePoint)
311  {
312  GISMO_ASSERT(spacePoint.rows() == 3 && spacePoint.cols() == 1, "Invalid dimensions");
313  const gsCurve<T> & c = m_domain->curve(loopNumber, curveNumber);
314  gsMatrix<T> supp = c.support();
315  gsVector<T> start = supp.col(0), end = supp.col(1);
316  gsMatrix<T> trialPoints = uniformPointGrid(start, end, nTrialPoints);
317  gsMatrix<T> curveVal, curveDeriv, curveDeriv2, surfVal, surfDeriv, surfDeriv2;
318  T closestParam(10e100), closestSqDist(10e100);
319 
320  for(int idxTrial = 0; idxTrial < nTrialPoints; idxTrial++)
321  {
322  gsMatrix<T> u = trialPoints.col(idxTrial);
323  // apply Newton's method to the function
324  // f(u) = ||p - x(u)||^2
325  // where x(u) is the parametrisation of the curve in space.
326  // (todo - also check the distances at the endpoints of the curve?
327  // although this is for splitting the curve and we would never want
328  // to split at the endpoint.)
329  for(int iteration = 0; iteration < nIterations; iteration++)
330  {
331  c.eval_into(u, curveVal);
332  c.jacobian_into(u, curveDeriv);
333  c.deriv2_into(u, curveDeriv2);
334 
335  m_surface->eval_into(curveVal, surfVal);
336  m_surface->jacobian_into(curveVal, surfDeriv);
337  m_surface->deriv2_into(curveVal, surfDeriv2);
338 
339  // evaluate derivative of f
340  gsMatrix<T> sqDistDeriv = -2 * (spacePoint - surfVal).transpose() *
341  surfDeriv * curveDeriv;
342  GISMO_ASSERT(sqDistDeriv.rows() == 1 && sqDistDeriv.cols() == 1, "Derivative should be 1x1");
343 
344  // evaluate second derivative of f
345  // from comment for gsBasis::deriv2_into, the second deriv of a surface takes the form:
346  // ( dxxf_1 dyyf_1 dxyf_1 dxxf_2 dyyf_2 dxy2f_2 dxxf_3 dyyf_3 dxyf_3 )^T
347 
348  gsMatrix<T> termFromSurfaceCurvature(3, 1);
349  for(int idxJ = 0; idxJ < 3; idxJ++)
350  {
351  termFromSurfaceCurvature(idxJ, 0) = surfDeriv2(idxJ * 3) * curveDeriv(0, 0) * curveDeriv(0, 0) +
352  surfDeriv2(idxJ * 3 + 1) * curveDeriv(1, 0) * curveDeriv(1, 0) +
353  (T)(2) * surfDeriv2(idxJ * 3 + 2) * curveDeriv(0, 0) * curveDeriv(1, 0);
354  }
355  gsMatrix<T> sqDistDeriv2Term1 = (surfDeriv * curveDeriv).transpose();
356  sqDistDeriv2Term1 *= (surfDeriv * curveDeriv);
357  gsMatrix<T> sqDistDeriv2Term2 = (spacePoint - surfVal).transpose() * (termFromSurfaceCurvature + surfDeriv * curveDeriv2);
358  gsMatrix<T> sqDistDeriv2 = 2 * (sqDistDeriv2Term1 - sqDistDeriv2Term2);
359  GISMO_ASSERT(sqDistDeriv2.rows() == 1 && sqDistDeriv2.cols() == 1, "Second derivative should be 1x1");
360 
361  u -= sqDistDeriv / sqDistDeriv2(0, 0);
362  u(0, 0) = (u(0, 0) < supp(0, 0))? supp(0, 0): ((u(0, 0) > supp(0, 1)? supp(0, 1): u(0, 0)));
363  }
364  // compute sqDist for the point found by the last iteration, and compare against the best seen so far
365  c.eval_into(u, curveVal);
366  m_surface->eval_into(curveVal, surfVal);
367  T sqDist = (spacePoint - surfVal).squaredNorm();
368  if(idxTrial == 0 || sqDist < closestSqDist)
369  {
370  closestParam = u(0, 0);
371  closestSqDist = sqDist;
372  }
373  }
374  return closestParam;
375  }
376 
378  T getLengthOfCurve(const int loopNumber,
379  const int curveNumber,
380  const T eps = 1e-6,
381  const int nmbSegments = 50) const;
382 
383 
392  void getPhysicalyUniformCurveParameters(const int loopNumber,
393  const int curveNumber,
394  const int nmbParams,
395  gsVector<T>& parameters,
396  const T eps = 1e-6)
397  {
398  T length = getLengthOfCurve(loopNumber, curveNumber, eps);
399 
400  // divide the length in nmbParams equally spaced arcs
401  gsVector<T> arcs(nmbParams);
402  for (int pt = 0; pt != nmbParams; pt++)
403  {
404  arcs(pt) = length * (pt * 1.0 / (nmbParams - 1));
405  }
406 
407  // compute parameters from arcs
408  fromArcsToParams(loopNumber, curveNumber, arcs, parameters, eps);
409 
410  }
411 
412 // private member functions
413 private:
417  void evalCurve_into(const gsCurve<T>& curve,
418  const gsMatrix<T>& u,
419  gsMatrix<T> &result) const;
420 
421 
426  T arcLength(const gsCurve<T>& curve,
427  const T a,
428  const T b,
429  const int quadPoints = 4) const;
430 
439  T getLengthOfCurve(const gsCurve<T>& curve,
440  gsMatrix<T>& params,
441  bool linear = false) const;
442 
443 
444 
455  void fromArcsToParams(const int loopNumber,
456  const int curveNumber,
457  const gsVector<T>& arcs,
458  gsVector<T>& parameters,
459  const T eps);
460 
461 
471  T findParameter(const gsCurve<T>& curve,
472  const T arc,
473  T curArc,
474  T lowParam,
475  T uppParam,
476  const T eps);
477 // Data members
478 private:
479 
480  typename gsSurface<T>::Ptr m_surface;
481 
482  gsPlanarDomain<T> * m_domain;
483 
484 }; // class gsTrimSurface
485 
486 
487 }// namespace gismo
488 
489 #ifndef GISMO_BUILD_LIB
490 #include GISMO_HPP_HEADER(gsTrimSurface.hpp)
491 #endif
492 
493 
A fixed-size, statically allocated 3D vector.
Definition: gsVector.h:218
gsCurve< T > & getCurve(int loopNumber, int curveNumber) const
Returns curveNumber-th curve in loopNumber-th loop.
Definition: gsTrimSurface.h:103
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
gsMatrix< T > evalSurface(const gsMatrix< T > &u) const
Definition: gsTrimSurface.h:179
T arcLength(const gsCurve< T > &curve, const T a, const T b, const int quadPoints=4) const
Definition: gsTrimSurface.hpp:343
Provides declaration of Surface abstract interface.
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
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
gsTrimSurface(typename gsSurface< T >::Ptr g, gsPlanarDomain< T > *d)
Constructor by a shared pointer.
Definition: gsTrimSurface.h:45
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
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
gsMatrix< T > trimCurTangents(int loopN, int curveN, size_t npoints) const
Return the tangent vectors of the trimming curve curveNumber in trimming loop loopNumber.
Definition: gsTrimSurface.h:271
gsMatrix< T > derivatives(int sourceID) const
Definition: gsTrimSurface.hpp:77
gsMatrix< T > sampleNormal(int loopNumber, int curveNumber, size_t npoints) const
sample standard unit normals along a trimming curve
Definition: gsTrimSurface.h:251
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
gsMatrix< T > gsPointGrid(gsVector< T > const &a, gsVector< T > const &b, gsVector< unsigned > const &np)
Construct a Cartesian grid of uniform points in a hypercube, using np[i] points in direction i...
Definition: gsPointGrid.hpp:82
gsTrimSurface< T > * clone() const
Clone function. Used to make a copy of the (derived) geometry.
Definition: gsTrimSurface.h:78
gsCurveLoop< T > & boundaryLoop()
Get a boundary curve loop.
Definition: gsTrimSurface.h:97
void fromArcsToParams(const int loopNumber, const int curveNumber, const gsVector< T > &arcs, gsVector< T > &parameters, const T eps)
Definition: gsTrimSurface.hpp:441
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
const gsCurveLoop< T > & boundaryLoop() const
Look at (non-const) boundaryLoop.
Definition: gsTrimSurface.h:100
Abstract base class representing a surface.
Definition: gsSurface.h:30
Class representing a Planar domain with an outer boundary and a number of holes.
Definition: gsPlanarDomain.h:43
gsMatrix< T > unitNormal(gsMatrix< T > point) const
Compute the unit normal vector of the trimmed surface at a point in the parameter domain...
Definition: gsTrimSurface.h:243
memory::shared_ptr< gsSurface > Ptr
Shared pointer for gsSurface.
Definition: gsSurface.h:35
gsMatrix< T > splitCurve(size_t loopId, size_t curveId, T lengthRatio=.5)
Definition: gsTrimSurface.h:194
T nearestPoint(int loopNumber, int curveNumber, int nTrialPoints, int nIterations, const gsMatrix< T > &spacePoint)
find the parameter of the nearest point on a curve to a given point in space
Definition: gsTrimSurface.h:310
#define GISMO_UNUSED(x)
Definition: gsDebug.h:112
Provides functions to generate structured point data.
void evalSurface_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Definition: gsTrimSurface.h:168
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
void getPhysicalyUniformCurveParameters(const int loopNumber, const int curveNumber, const int nmbParams, gsVector< T > &parameters, const T eps=1e-6)
Definition: gsTrimSurface.h:392
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
gsMatrix< T > evalCurve(int loopNumber, int curveNumber, const gsMatrix< T > &u) const
Look at evalCurve_into.
Definition: gsTrimSurface.h:149
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...
gsMatrix< T > & coefs()
Definition: gsGeometry.h:340
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition: gsTrimSurface.hpp:29