G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsNurbs.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsCore/gsLinearAlgebra.h>
17 #include <gsCore/gsGeometry.h>
18 
19 #include <gsNurbs/gsNurbsBasis.h>
20 #include <gsNurbs/gsKnotVector.h>
21 #include <gsNurbs/gsBoehm.h>
22 
23 
24 namespace gismo
25 {
26 
38 template<class T>
39 class gsNurbs : public gsGeoTraits<1,T>::GeometryBase
40 {
41 
42 public:
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 
59 public:
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 
86 public:
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 
230 protected:
231  // TODO Check function
232  // check function: check the coefficient number, degree, knot vector ...
233 
234 private:
235 
236  // Avoid hidden overloads w.r.t. gsGeometry
237  using Base::insertKnot;
238 
239 // Data members
240 private:
241 
242  using Base::m_coefs;
243 
244  bool projective;
245 
246 }; // class gsNurbs
247 
248 
249 } // namespace gismo
void gsBoehm(KnotVectorType &knots, Mat &coefs, T val, int r=1, bool update_knots=true)
Performs insertion of multiple knot on &quot;knots&quot; and coefficients &quot;coefs&quot;.
Definition: gsBoehm.hpp:29
Knot vector for B-splines.
Abstract base class representing a geometry map.
Definition: gsGeometry.h:92
gsMatrix< T > m_coefs
Coefficient matrix of size coefsSize() x geoDim()
Definition: gsGeometry.h:624
Represents a NURBS basis with one parameter.
A NURBS function of one argument, with arbitrary target dimension.
Definition: gsNurbs.h:39
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
const KnotVectorType & knots() const
Returns a (const )reference to the knot vector.
Definition: gsNurbs.h:116
gsBasis< T > * m_basis
Pointer to the basis of this geometry.
Definition: gsGeometry.h:627
Class that creates a rational counterpart for a given basis.
Definition: gsRationalBasis.h:47
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition: gsNurbs.h:93
const gsMatrix< T > & weights() const
Returns the weights of the rational basis.
Definition: gsNurbs.h:125
short_t degree(const short_t &i) const
Returns the degree wrt direction i.
Definition: gsGeometry.hpp:333
Boehm&#39;s algorithm for knot insertion.
void gsBoehmRefine(KnotVectorType &knots, Mat &coefs, int p, ValIt valBegin, ValIt valEnd, bool update_knots=true)
Definition: gsBoehm.hpp:163
memory::shared_ptr< gsNurbs > Ptr
Shared pointer for gsNurbs.
Definition: gsNurbs.h:54
S give(S &x)
Definition: gsMemory.h:266
Provides declaration of Geometry abstract interface.
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
index_t coefsSize() const
Return the number of coefficients (control points)
Definition: gsGeometry.h:371
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
virtual void insertKnot(T knot, index_t dir, index_t i=1)
Inserts knot knot at direction dir, i times.
Definition: gsGeometry.hpp:430
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
void insertKnots(It inBegin, It inEnd)
Insert the knots in the range [inBegin,inEnd) without changing the curve.
Definition: gsNurbs.h:210
T & weight(int i)
Access to i-th weight.
Definition: gsNurbs.h:119
Interface for the set of functions defined on a domain (the total number of functions in the set equa...
Definition: gsFuncData.h:23
gsNurbs()
Default empty constructor.
Definition: gsNurbs.h:62
T domainEnd() const
Returns the starting value of the domain of the basis.
Definition: gsNurbs.h:110
void insertKnot(T knot, int i=1)
Insert the given new knot (multiplicity i) without changing the curve.
Definition: gsNurbs.h:199
A univariate NURBS basis.
Definition: gsNurbsBasis.h:39
gsMatrix< T > support() const
Returns the range of parameters (same as parameterRange())
Definition: gsGeometry.hpp:193
T Scalar_t
Coefficient type.
Definition: gsNurbs.h:48
Class for representing a knot vector.
Definition: gsKnotVector.h:79
This is the main header file that collects wrappers of Eigen for linear algebra.
const T weight(int i) const
Const access to i-th weight.
Definition: gsNurbs.h:122
T domainStart() const
Returns the starting value of the domain of the basis.
Definition: gsNurbs.h:107
gsNurbs(const Basis &basis, const gsMatrix< T > &coefs)
Construct NURBS by NURBS basis functions and coefficient matrix.
Definition: gsNurbs.h:65
KnotVectorType & knots()
Returns a reference to the knot vector.
Definition: gsNurbs.h:113
virtual const gsBasis< T > & basis() const =0
Returns a const reference to the basis of the geometry.
short_t geoDim() const
Dimension n of the absent physical space.
Definition: gsGeometry.h:292
memory::unique_ptr< gsNurbs > uPtr
Unique pointer for gsNurbs.
Definition: gsNurbs.h:57
gsMatrix< T > & coefs()
Definition: gsGeometry.h:340