34 "gsNurbs: cannot merge curves in different spaces ( R^"
35 << this->geoDim() <<
", R^" << otherG->
geoDim() <<
" ).");
39 GISMO_ASSERT( other!=NULL,
"Can only merge with B-spline curves.");
40 other= other->clone().release();
43 other->basis().isPeriodic() ==
false,
44 "Cannot merge a closed curve with anything." );
47 const short_t mDeg =
this ->basis().degree();
48 const short_t oDeg = other->basis().degree();
49 const short_t deg = math::max(mDeg,oDeg);
51 other->gsBSpline::degreeElevate( deg - oDeg );
52 this ->gsBSpline::degreeElevate( deg - mDeg );
57 gsMatrix<T> mValue =
this ->eval(
this ->support().col(1));
58 gsMatrix<T> oValue = other->eval(other->support().col(0));
62 KnotVectorType& mKnots =
this ->basis().knots();
63 KnotVectorType& oKnots = other->basis().knots();
64 T lastKnot = mKnots.last();
69 mKnots.remove(lastKnot);
72 oKnots.addConstant(lastKnot-oKnots.first());
73 mKnots.append( oKnots.begin()+deg+1, oKnots.end());
76 unsigned n= this->coefsSize();
77 index_t skip = continuous ? 1 : 0;
78 this->m_coefs.conservativeResize( n + other->coefsSize() -skip, gsEigen::NoChange ) ;
80 this->m_coefs.block( n,0,other->coefsSize()-skip,other->geoDim() ) =
81 other->m_coefs.block( 1,0,other->coefsSize()-skip,other->geoDim() ) ;
90 GISMO_ASSERT(domainStart()-tolerance < u0 && u0 < domainEnd()+tolerance,
91 "starting point "<< u0 <<
" not in the knot vector");
92 GISMO_ASSERT(domainStart()-tolerance < u1 && u1 < domainEnd()+tolerance,
93 "end point "<< u1 <<
" not in the knot vector");
99 KnotVectorType & knots = copy.
basis().knots();
102 const short_t p = basis().degree();
103 const index_t multStart = p + 1 - knots.multiplicity(u0);
104 const index_t multEnd = p + 1 - knots.multiplicity(u1);
113 const index_t tDim = coefs.cols();
117 const index_t nL = knots.uFind(u0).firstAppearance();
119 index_t nL2 = knots.uFind(u1).firstAppearance();
120 bool isEnd =
math::abs(u1 - this->domainEnd()) < tolerance;
123 nL2 = copy.numCoefs();
126 gsMatrix<T> coefRes = coefs.block(nL, 0, nL2-nL, tDim);
129 typename KnotVectorType::iterator itStart = knots.iFind(u0);
130 typename KnotVectorType::iterator itEnd = knots.iFind(u1) + (isEnd ? p + 1 : 0);
131 typename KnotVectorType::knotContainer matRes(itStart-p, itEnd+1);
132 KnotVectorType knotsRes(
give(matRes), p);
145 for (
auto iter = this->knots().ubegin() + 1; iter != this->knots().uend() - 1; ++iter)
147 currentSegment.
splitAt(*iter, leftPart, currentSegment, tolerance);
151 bezierSegments.
addPatch(currentSegment);
152 return bezierSegments;
158 T curvatureTolerance)
const
160 std::vector<internal::gsBoundingBoxPair<T>> hulls = internal::getPotentialIntersectionRanges<T>(*
this, other, curvatureTolerance);
162 std::vector<internal::gsCurveIntersectionResult<T>> results;
163 for (
typename std::vector<internal::gsBoundingBoxPair<T>>::const_iterator hull = hulls.begin(); hull!=hulls.end(); hull++)
165 gsBSpline<T> crv1 = this->segmentFromTo(hull->b1.getRange().getMin(), hull->b1.getRange().getMax());
168 internal::gsCurveCurveDistanceSystem<T> obj(crv1, crv2);
171 uv(1) = 0.5 * (crv2.domainStart() + crv2.domainEnd());
172 T
distance = obj.compute(uv, tolerance);
174 if (distance < math::max( (T)1e-10, tolerance))
180 internal::gsCurveIntersectionResult<T> result(uv(0), uv(1), pt);
181 results.push_back(result);
191 index_t coefsSize = m_coefs.rows();
193 T len = (m_coefs.row(0)-m_coefs.row(coefsSize-1)).norm();
195 for (
index_t ipt = 0; ipt != coefsSize - 1; ++ipt)
197 T dist = (m_coefs.row(ipt) - m_coefs.row(ipt + 1)).norm();
212 if( this->basis().isPeriodic() )
214 int borderKnotMult = this->basis().borderKnotMult();
215 KnotVectorType & knots = this->knots();
216 unsigned deg = this->basis().degree();
218 GISMO_ASSERT( knot != knots[deg] && knot != knots[knots.size() - deg - 1],
219 "You are trying to increase the multiplicity of the p+1st knot but the code is not ready for that.\n");
224 if( knot < knots[deg - borderKnotMult + 1] )
226 knot += this->basis()._activeLength();
228 else if( knot > knots[knots.size() - deg + borderKnotMult - 2] )
230 knot -= this->basis()._activeLength();
233 if((knot < knots[2*deg + 1 - borderKnotMult]) || (knot >= knots[knots.size() - 2*deg - 2 + borderKnotMult]))
234 this->basis().enforceOuterKnotsPeriodic();
240 gsBoehm( this->basis().knots(), this->coefs(), knot, i );
245 gsBoehm( this->basis().knots(), this->coefs() , knot, i);
251 insertKnot(knot,0,i);
257 GISMO_ASSERT(domainStart()-tolerance < u0 && u0 < domainEnd()+tolerance,
258 "splitting point "<< u0 <<
" not in the knot vector");
260 left = segmentFromTo(this->domainStart(), u0, tolerance);
261 right = segmentFromTo(u0, this->domainEnd(), tolerance);
267 GISMO_ASSERT( u.cols() == 1,
"Expecting single point.");
271 for (
index_t k = 0; k != u.rows(); ++k)
273 std::vector<T> roots;
274 slv.allRoots(*
this, roots, k, u(k,0) ) ;
276 if( roots.size()!=0 )
279 this->eval_into( xx, e );
282 for(
index_t j=0; j!=e.cols(); j++)
283 if( ( e.col(j)-u ).norm() < tol )
293 return (( v - m_coefs.row(0) ).squaredNorm() < tol ||
294 ( v - m_coefs.bottomRows(1)).squaredNorm() < tol );
302 if ((v - m_coefs.row(0)).squaredNorm() < tol)
304 else if ((v - m_coefs.bottomRows(1)).squaredNorm() < tol)
305 curr[0] = m_coefs.rows()-1;
308 curr[0] = m_coefs.rows();
309 gsWarn<<
"Point "<< v <<
" is not an corner of the patch. (Call isPatchCorner() first!).\n";
317 if ((v - m_coefs.row(0)).squaredNorm() < (T)(1e-3))
319 else if ((v - m_coefs.bottomRows(1)).squaredNorm() < (T)(1e-3))
322 gsWarn<<
"Point "<< v <<
" is not an endpoint of the curve.\n";
328 if ((v - m_coefs.bottomRows(1)).squaredNorm() < (T)(1e-3))
330 else if ((v - m_coefs.row(0)).squaredNorm() < (T)(1e-3))
333 gsWarn<<
"Point "<< v <<
" is not an endpoint of the curve.\n";
341 GISMO_ASSERT( static_cast<int>(i) == 0 && static_cast<int>(j) == 0,
342 "Invalid basis components "<<i<<
" and "<<j<<
" requested" );
351 "Invalid basis component "<< dir <<
" requested for degree elevation" );
366 GSXML_COMMON_FUNCTIONS(gsBSpline<T>);
367 static std::string tag () {
return "Geometry"; }
368 static std::string type () {
return "BSpline"; }
370 static gsBSpline<T> *
get (gsXmlNode * node)
372 return getGeometryFromXml< gsBSpline<T> >(node);
375 static gsXmlNode * put (
const gsBSpline<T> & obj,
378 return putGeometryToXml< gsBSpline<T> >(obj,data);
bool isPatchCorner(gsMatrix< T > const &v, T tol=1e-3) const
Return true if point u is an endpoint (corner) of the curve with tolerance tol.
Definition: gsBSpline.hpp:291
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry<T>::uPtr.
Definition: gsMultiPatch.hpp:210
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
Abstract base class representing a geometry map.
Definition: gsGeometry.h:92
void merge(gsGeometry< T > *otherG)
Merge other B-spline into this one.
Definition: gsBSpline.hpp:29
T pseudoCurvature() const
Definition: gsBSpline.hpp:189
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
T distance(gsMatrix< T > const &A, gsMatrix< T > const &B, index_t i=0, index_t j=0, bool cols=false)
compute a distance between the point number in the set and the point number <j> in the set ; by def...
Creates a mapped object or data pointer to a matrix without copying data.
Definition: gsLinearAlgebra.h:126
Implementation of B Spline Curve/Curve intersection.
#define short_t
Definition: gsConfig.h:35
bool isOn(gsMatrix< T > const &u, T tol=1e-3) const
Return true if point u is on the curve with tolerance tol.
Definition: gsBSpline.hpp:265
void setFurthestCorner(gsMatrix< T > const &v)
Modifies the parameterization such that the point v is the ending point of the curve. Assumes that v is either the starting or the ending point of the curve.
Definition: gsBSpline.hpp:326
S give(S &x)
Definition: gsMemory.h:266
gsMatrix< T > eval(const gsMatrix< T > &u) const
Evaluate the function,.
Definition: gsFunctionSet.hpp:120
#define index_t
Definition: gsConfig.h:32
T domainEnd() const
Returns the end value of the domain of the basis.
Definition: gsBSpline.h:167
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Provides implementation of generic XML functions.
A B-spline function of one argument, with arbitrary target dimension.
Definition: gsBSpline.h:50
void setOriginCorner(gsMatrix< T > const &v)
Modifies the parameterization such that the point v is the starting point of the curve. Assumes that v is either the starting or the ending point of the curve.
Definition: gsBSpline.hpp:315
void degreeElevateBSpline(Basis_t &basis, gsMatrix< typename Basis_t::Scalar_t > &coefs, short_t m)
Increase the degree of a 1D B-spline from degree p to degree p + m.
Definition: gsBSplineAlgorithms.h:224
void insertKnot(T knot, index_t i=1)
Definition: gsBSpline.hpp:249
Implementation of common algorithms for B-splines.
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition: gsVector.h:35
#define gsWarn
Definition: gsDebug.h:50
Provides declaration of the MultiPatch class.
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
std::vector< internal::gsCurveIntersectionResult< T > > intersect(const gsBSpline< T > &other, T tolerance=1e-5, T curvatureTolerance=1+1e-6) const
Definition: gsBSpline.hpp:156
void degreeElevate(short_t const i=1, short_t const dir=-1)
Elevate the degree by the given amount i for the direction dir. If dir is -1 then degree elevation is...
Definition: gsBSpline.hpp:347
gsMultiPatch< T > toBezier(T tolerance=1e-15) const
Definition: gsBSpline.hpp:138
#define GISMO_UNUSED(x)
Definition: gsDebug.h:112
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4486
Definition: gsBSplineSolver.h:113
void findCorner(const gsMatrix< T > &v, gsVector< index_t, 1 > &curr, T tol=1e-3)
returns the tensor-index curr of the corner control point v, or an invalid index if the corner is not...
Definition: gsBSpline.hpp:298
gsBSpline< T > segmentFromTo(T u0, T u1, T tolerance=1e-15) const
Definition: gsBSpline.hpp:87
virtual const gsBasis< T > & basis() const =0
Returns a const reference to the basis of the geometry.
T domainStart() const
Returns the starting value of the domain of the basis.
Definition: gsBSpline.h:164
Provides declaration of input/output XML utilities struct.
short_t geoDim() const
Dimension n of the absent physical space.
Definition: gsGeometry.h:292
void splitAt(T u0, gsBSpline< T > &left, gsBSpline< T > &right, T tolerance=1e-15) const
Definition: gsBSpline.hpp:255
gsMatrix< T > & coefs()
Definition: gsGeometry.h:340
void copy(T begin, T end, U *result)
Small wrapper for std::copy mimicking std::copy for a raw pointer destination, copies n positions sta...
Definition: gsMemory.h:391