G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsNurbs.h
Go to the documentation of this file.
1
14#pragma once
15
17#include <gsCore/gsGeometry.h>
18
21#include <gsNurbs/gsBoehm.h>
22
23
24namespace gismo
25{
26
38template<class T>
39class gsNurbs : public gsGeoTraits<1,T>::GeometryBase
40{
41
42public:
43 typedef gsKnotVector<T> KnotVectorType;
44
45 typedef typename gsGeoTraits<1,T>::GeometryBase Base;
46
48 typedef T Scalar_t;
49
51 typedef gsNurbsBasis<T> Basis;
52
54 typedef memory::shared_ptr< gsNurbs > Ptr;
55
57 typedef memory::unique_ptr< gsNurbs > uPtr;
58
59public:
60
62 gsNurbs() : Base() { }
63
65 gsNurbs( const Basis & basis, const gsMatrix<T> & coefs ) :
66 Base(basis, coefs) { }
67
70 {
71 this->m_coefs.swap(coefs);
72 this->m_basis = new Basis(KV, give(w));
73 }
74
76 gsNurbs( const gsKnotVector<T>& KV, const gsMatrix<T> * pcoefs ) :
77 Base( new Basis(KV, & pcoefs->rightCols(1) ), pcoefs)
78 {
79 // TO DO: divide pcoefs by the weights
80 }
81
82 GISMO_CLONE_FUNCTION(gsNurbs)
83
84 GISMO_BASIS_ACCESSORS
85
86public:
87
88// ***********************************************
89// Virtual member functions required by the base class
90// ***********************************************
91
93 std::ostream &print(std::ostream &os) const
94 { os << "NURBS curve "<< "of degree "<< this->basis().degree()
95 << " over knots "<< this->basis().knots() <<",\n";
96 os << "weights: ["<< this->weights().transpose()<< " ]\n ";
97 os << "with control points "<< this->m_coefs << ".\n";
98 return os;
99 };
100
101
102// ***********************************************
103// Additional members for univariate B-Splines
104// ***********************************************
105
107 T domainStart() const { return this->basis().knots().first(); };
108
110 T domainEnd() const { return this->basis().knots().last(); };
111
113 KnotVectorType & knots() { return this->basis().knots(); }
114
116 const KnotVectorType & knots() const { return this->basis().knots(); }
117
119 T & weight(int i) { return this->basis().weight(i); }
120
122 const T weight(int i) const { return this->basis().weight(i); }
123
125 const gsMatrix<T> & weights() const { return this->basis().weights(); }
126 gsMatrix<T> & weights() { return this->basis().weights(); }
127
128 void isCompatible( gsGeometry<T> * other )
129 {
130 // compatible curves: same degree, same first/last p+1 knots
131 };
132 void makeCompatible( gsGeometry<T> * other )
133 {
134 // compatible curves: same degree, same first/last p+1 knots
135 };
136
137 void merge( gsGeometry<T> * otherG )
138 {
139 // See also gsBSpline::merge().
140 // check geometric dimension
141 GISMO_ASSERT(this->geoDim()==otherG->geoDim(),
142 "gsNurbs: cannot merge curves in different spaces ( R^"
143 << this->geoDim() << ", R^" << otherG->geoDim() << " ).");
144
145 // check if the type of other is BSpline
146 gsNurbs * other = dynamic_cast<gsNurbs *>( otherG ); // TODO: to uPtr
147 GISMO_ASSERT( other!=NULL, "Can only merge with B-spline curves.");
148 other= other->clone().release();
149
150 // TODO: check for periodic
151
152 // check degree
153 const int mDeg = this ->basis().degree();
154 const int oDeg = other->basis().degree();
155 const int deg = math::max(mDeg,oDeg);
156
157 other->gsNurbs::degreeElevate( deg - oDeg ); // degreeElevate(0) does nothing (and very quickly)
158 this ->gsNurbs::degreeElevate( deg - mDeg );
159
160 // check whether the resulting curve will be continuous
161 // TODO: ideally, the tolerance should be a parameter of the function
162 T tol = 1e-8;
163 gsMatrix<T> mValue = this ->eval(this ->support().col(1));
164 gsMatrix<T> oValue = other->eval(other->support().col(0));
165 bool continuous = gsAllCloseAbsolute(mValue,oValue,tol);
166
167 // merge knot vectors.
168 KnotVectorType& mKnots = this ->basis().knots();
169 KnotVectorType& oKnots = other->basis().knots();
170 T lastKnot = mKnots.last();
171 if (continuous) // reduce knot multiplicity
172 {
173 // TODO check for clamped knot vectors otherwise
174 // we should do knot insertion beforehands
175 mKnots.remove(lastKnot);
176 }// else there is a knot of multiplicity deg + 1 at the discontinuity
177
178 oKnots.addConstant(lastKnot-oKnots.first());
179 mKnots.append( oKnots.begin()+deg+1, oKnots.end());
180
181 // merge coefficients
182 int n= this->coefsSize();
183 int skip = continuous ? 1 : 0;
184 this->m_coefs.conservativeResize( n + other->coefsSize() -skip, gsEigen::NoChange ) ;
185
186 this->m_coefs.block( n,0,other->coefsSize()-skip,other->geoDim() ) =
187 other->m_coefs.block( 1,0,other->coefsSize()-skip,other->geoDim() ) ;
188
189 // merge Weights
190 this->weights().conservativeResize( n + other->coefsSize() -skip, gsEigen::NoChange ) ;
191
192 this->weights().block( n,0,other->coefsSize()-skip,1 ) =
193 other->weights().block( 1,0,other->coefsSize()-skip, 1 ) ;
194
195 delete other;
196 }
197
199 void insertKnot( T knot, int i = 1 )
200 {
201 if (i==0) return;
202
203 gsMatrix<T> tmp = basis().projectiveCoefs(m_coefs);
204 gsBoehm(basis().knots(), tmp, knot, i);
205 basis().setFromProjectiveCoefs(tmp, m_coefs, basis().weights());
206 }
207
209 template <class It>
210 void insertKnots(It inBegin, It inEnd)
211 {
212 gsMatrix<T> tmp = basis().projectiveCoefs(m_coefs);
213 gsBoehmRefine(basis().knots(), tmp, this->degree(), inBegin, inEnd);
214 basis().setFromProjectiveCoefs(tmp, m_coefs, basis().weights());
215 }
216
217 /*
218 void degreeElevate(int const i, int const dir = -1)
219 {
220 GISMO_ASSERT( (dir == -1) || (dir == 0),
221 "Invalid basis component "<< dir <<" requested for degree elevation" );
222
223 bspline::degreeElevateBSpline(this->basis(), this->m_coefs, i);
224 }
225 */
226
227 //void toProjective() { m_weights=w; } ;
228
229
230protected:
231 // TODO Check function
232 // check function: check the coefficient number, degree, knot vector ...
233
234private:
235
236 // Avoid hidden overloads w.r.t. gsGeometry
237 using Base::insertKnot;
238
239// Data members
240private:
241
242 using Base::m_coefs;
243
244 bool projective;
245
246}; // class gsNurbs
247
248
249} // namespace gismo
Abstract base class representing a geometry map.
Definition gsGeometry.h:93
gsMatrix< T > & coefs()
Definition gsGeometry.h:340
short_t degree(const short_t &i) const
Returns the degree wrt direction i.
Definition gsGeometry.hpp:333
short_t geoDim() const
Dimension n of the absent physical space.
Definition gsGeometry.h:292
virtual const gsBasis< T > & basis() const =0
Returns a const reference to the basis of the geometry.
gsBasis< T > * m_basis
Pointer to the basis of this geometry.
Definition gsGeometry.h:632
gsMatrix< T > support() const
Returns the range of parameters (same as parameterRange())
Definition gsGeometry.hpp:193
gsMatrix< T > m_coefs
Coefficient matrix of size coefsSize() x geoDim()
Definition gsGeometry.h:629
index_t coefsSize() const
Return the number of coefficients (control points)
Definition gsGeometry.h:371
virtual void insertKnot(T knot, index_t dir, index_t i=1)
Inserts knot knot at direction dir, i times.
Definition gsGeometry.hpp:444
Class for representing a knot vector.
Definition gsKnotVector.h:80
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
A univariate NURBS basis.
Definition gsNurbsBasis.h:40
A NURBS function of one argument, with arbitrary target dimension.
Definition gsNurbs.h:40
KnotVectorType & knots()
Returns a reference to the knot vector.
Definition gsNurbs.h:113
T & weight(int i)
Access to i-th weight.
Definition gsNurbs.h:119
memory::unique_ptr< gsNurbs > uPtr
Unique pointer for gsNurbs.
Definition gsNurbs.h:57
void insertKnot(T knot, int i=1)
Insert the given new knot (multiplicity i) without changing the curve.
Definition gsNurbs.h:199
const KnotVectorType & knots() const
Returns a (const )reference to the knot vector.
Definition gsNurbs.h:116
T Scalar_t
Coefficient type.
Definition gsNurbs.h:48
const gsMatrix< T > & weights() const
Returns the weights of the rational basis.
Definition gsNurbs.h:125
gsNurbs()
Default empty constructor.
Definition gsNurbs.h:62
void insertKnots(It inBegin, It inEnd)
Insert the knots in the range [inBegin,inEnd) without changing the curve.
Definition gsNurbs.h:210
gsNurbs(const gsKnotVector< T > &KV, const gsMatrix< T > *pcoefs)
Construct B-Spline by a knot vector, degree and projective coefficient matrix.
Definition gsNurbs.h:76
T domainEnd() const
Returns the starting value of the domain of the basis.
Definition gsNurbs.h:110
gsNurbs(const Basis &basis, const gsMatrix< T > &coefs)
Construct NURBS by NURBS basis functions and coefficient matrix.
Definition gsNurbs.h:65
gsMatrix< T > m_coefs
Coefficient matrix of size coefsSize() x geoDim()
Definition gsGeometry.h:629
gsNurbs(const gsKnotVector< T > &KV, gsMatrix< T > w, gsMatrix< T > coefs)
Construct B-Spline by a knot vector, degree, weights and coefficient matrix.
Definition gsNurbs.h:69
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition gsNurbs.h:93
memory::shared_ptr< gsNurbs > Ptr
Shared pointer for gsNurbs.
Definition gsNurbs.h:54
T domainStart() const
Returns the starting value of the domain of the basis.
Definition gsNurbs.h:107
const T weight(int i) const
Const access to i-th weight.
Definition gsNurbs.h:122
Class that creates a rational counterpart for a given basis.
Definition gsRationalBasis.h:48
Boehm's algorithm for knot insertion.
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides declaration of Geometry abstract interface.
Knot vector for B-splines.
This is the main header file that collects wrappers of Eigen for linear algebra.
Represents a NURBS basis with one parameter.
The G+Smo namespace, containing all definitions for the library.
void gsBoehm(KnotVectorType &knots, Mat &coefs, T val, int r=1, bool update_knots=true)
Performs insertion of multiple knot on "knots" and coefficients "coefs".
Definition gsBoehm.hpp:29
bool gsAllCloseAbsolute(const matrix_t1 &a, const matrix_t2 &b, const typename matrix_t1::Scalar &tol)
tests if the difference between two matrices is bounded by tol in norm
Definition gsMath.h:465
S give(S &x)
Definition gsMemory.h:266
void gsBoehmRefine(KnotVectorType &knots, Mat &coefs, int p, ValIt valBegin, ValIt valEnd, bool update_knots=true)
Definition gsBoehm.hpp:163