G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
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
22namespace gismo
23{
24
32template<class T>
34{
35
36public:
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
413private:
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
478private:
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 B-spline function of one argument, with arbitrary target dimension.
Definition gsBSpline.h:51
A closed loop given by a collection of curves.
Definition gsCurveLoop.h:37
Abstract base class representing a curve.
Definition gsCurve.h:31
virtual void jacobian_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Computes for each point u a block of result containing the Jacobian matrix.
Definition gsFunction.hpp:53
virtual void deriv2_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate second derivatives of the function at points u into result.
Definition gsGeometry.hpp:174
gsMatrix< T > & coefs()
Definition gsGeometry.h:340
void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate the function at points u into result.
Definition gsGeometry.hpp:166
gsMatrix< T > support() const
Returns the range of parameters (same as parameterRange())
Definition gsGeometry.hpp:193
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Class representing a Planar domain with an outer boundary and a number of holes.
Definition gsPlanarDomain.h:44
Abstract base class representing a surface.
Definition gsSurface.h:31
memory::shared_ptr< gsSurface > Ptr
Shared pointer for gsSurface.
Definition gsSurface.h:35
Class for a trim surface.
Definition gsTrimSurface.h:34
void fromArcsToParams(const int loopNumber, const int curveNumber, const gsVector< T > &arcs, gsVector< T > &parameters, const T eps)
Definition gsTrimSurface.hpp:441
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
gsCurveLoop< T > & boundaryLoop()
Get a boundary curve loop.
Definition gsTrimSurface.h:97
T findParameter(const gsCurve< T > &curve, const T arc, T curArc, T lowParam, T uppParam, const T eps)
Definition gsTrimSurface.hpp:515
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
void evalSurface_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Definition gsTrimSurface.h:168
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 > 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
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
gsMatrix< T > evalCurve(int loopNumber, int curveNumber, const gsMatrix< T > &u) const
Look at evalCurve_into.
Definition gsTrimSurface.h:149
gsMatrix< T > splitCurve(size_t loopId, size_t curveId, T lengthRatio=.5)
Definition gsTrimSurface.h:194
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 > 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
gsBSpline< T > cuttingCurve(int const &sourceID, int const &targetID) const
Define a spline curve connecting source-target
Definition gsTrimSurface.hpp:184
T arcLength(const gsCurve< T > &curve, const T a, const T b, const int quadPoints=4) const
Definition gsTrimSurface.hpp:343
void getPhysicalyUniformCurveParameters(const int loopNumber, const int curveNumber, const int nmbParams, gsVector< T > &parameters, const T eps=1e-6)
Definition gsTrimSurface.h:392
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
gsTrimSurface< T > * clone() const
Clone function. Used to make a copy of the (derived) geometry.
Definition gsTrimSurface.h:78
gsMatrix< T > sampleNormal(int loopNumber, int curveNumber, size_t npoints) const
sample standard unit normals along a trimming curve
Definition gsTrimSurface.h:251
gsTrimSurface()
Default empty constructor.
Definition gsTrimSurface.h:42
gsTrimSurface(typename gsSurface< T >::Ptr g, gsPlanarDomain< T > *d)
Constructor by a shared pointer.
Definition gsTrimSurface.h:45
gsCurve< T > & getCurve(int loopNumber, int curveNumber) const
Returns curveNumber-th curve in loopNumber-th loop.
Definition gsTrimSurface.h:103
void evalCurve_into(int loopNumber, int curveNumber, const gsMatrix< T > &u, gsMatrix< T > &result) const
Definition gsTrimSurface.h:133
gsMatrix< T > derivatives(int sourceID) const
Definition gsTrimSurface.hpp:77
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
gsVector3d< T > cornerNormal(int const &sourceID) const
Compute the surface normal at a corner.
Definition gsTrimSurface.hpp:89
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition gsTrimSurface.hpp:29
memory::unique_ptr< gsMesh< T > > toMesh(int npoints=50) const
Return a triangulation of the trimmed surface.
Definition gsTrimSurface.hpp:236
const gsCurveLoop< T > & boundaryLoop() const
Look at (non-const) boundaryLoop.
Definition gsTrimSurface.h:100
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 > evalSurface(const gsMatrix< T > &u) const
Definition gsTrimSurface.h:179
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
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
#define short_t
Definition gsConfig.h:35
#define GISMO_UNUSED(x)
Definition gsDebug.h:112
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides declaration of gsPlanarDomain class. The outer boundary (m_loops[0]) is a loop of curves,...
Provides functions to generate structured point data.
Provides declaration of Surface abstract interface.
The G+Smo namespace, containing all definitions for the library.
gsMatrix< T > uniformPointGrid(const gsVector< T > &lower, const gsVector< T > &upper, int numPoints=1000)
Definition gsPointGrid.hpp:94