Developer Documentation

BSplineSurfaceT_impl.hh
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42
43
44
45 //=============================================================================
46 //
47 // CLASS BSplineSurfaceT - IMPLEMENTATION
48 // Author: Ellen Dekkers <dekkers@cs.rwth-aachen.de>
49 //
50 //=============================================================================
51
52 #define BSPLINESURFACE_BSPLINESURFACET_C
53
54 //== INCLUDES =================================================================
55
56 #include <OpenMesh/Core/Geometry/VectorT.hh>
57
58 #include <iostream>
59 #include <fstream>
60
61 #include "BSplineSurfaceT.hh"
62
63 #include <cfloat>
64 #include <ACG/Geometry/Algorithms.hh>
65 #include <ACG/Math/BSplineBasis.hh>
66
67 //== NAMESPACES ===============================================================
68
69 namespace ACG {
70
71 //== IMPLEMENTATION ==========================================================
72
73 template <class PointT>
74 BSplineSurfaceT<PointT>::
75 BSplineSurfaceT( unsigned int _degm, unsigned int _degn )
76 : dimm_(0),
77 dimn_(0),
78 ref_count_cpselections_(0),
79 ref_count_eselections_(0)
80 {
81 set_degree(_degm, _degn);
82 }
83
84 //-----------------------------------------------------------------------------
85
86 template <class PointT>
87 template <class PropT>
88 void
89 BSplineSurfaceT<PointT>::
90 request_prop( unsigned int& _ref_count, PropT& _prop)
91 {
92 if(_ref_count == 0)
93 {
94 _ref_count = 1;
95
96 // always use vertex size!!!
97 _prop.resize(n_control_points_m());
98 for (unsigned int i = 0; i < _prop.size(); ++i)
99 _prop[i].resize(n_control_points_n());
100 }
101 else ++_ref_count;
102 }
103
104 //-----------------------------------------------------------------------------
105
106 template <class PointT>
107 template <class PropT>
108 void
109 BSplineSurfaceT<PointT>::
110 release_prop( unsigned int& _ref_count, PropT& _prop)
111 {
112 if( _ref_count <= 1)
113 {
114 _ref_count = 0;
115 _prop.clear();
116 }
117 else --_ref_count;
118 }
119
120 //-----------------------------------------------------------------------------
121
122 template <class PointT>
123 void
124 BSplineSurfaceT<PointT>::
125 resize(unsigned int _m, unsigned int _n)
126 {
127 control_net_.resize(_m);
128
129 for (unsigned int i = 0; i < control_net_.size(); ++i)
130 control_net_[i].resize(_n);
131
132 dimm_ = _m;
133 dimn_ = _n;
134
135 // resize cpselections
136 cpselections_.resize(_m);
137 for (unsigned int i = 0; i < cpselections_.size(); ++i)
138 cpselections_[i].resize(_n);
139
140 // resize eselections
141 eselections_.resize(_m);
142 for (unsigned int i = 0; i < eselections_.size(); ++i)
143 eselections_[i].resize(_n);
144 }
145
146 //-----------------------------------------------------------------------------
147
148 template <class PointT>
149 void
150 BSplineSurfaceT<PointT>::
151 reset_control_net()
152 {
153 control_net_.clear();
154
155 // reset properties
156 cpselections_.clear();
157 eselections_.clear();
158 }
159
160 //-----------------------------------------------------------------------------
161
162 template <class PointT>
163 void
164 BSplineSurfaceT<PointT>::
165 createKnots()
166 {
167 knotvector_m_.createKnots(degree_m_, dimm_);
168 knotvector_n_.createKnots(degree_n_, dimn_);
169 }
170
171 //-----------------------------------------------------------------------------
172
173 template <class PointT>
174 void
175 BSplineSurfaceT<PointT>::
176 set_degree(unsigned int _degm, unsigned int _degn)
177 {
178 degree_m_ = _degm;
179 degree_n_ = _degn;
180 }
181
182 //-----------------------------------------------------------------------------
183
184 template <class PointT>
185 void
186 BSplineSurfaceT<PointT>::
187 add_vector_m(const std::vector< Point> & _control_polygon)
188 {
189 insert_vector_m(_control_polygon, dimm_);
190 }
191
192 //-----------------------------------------------------------------------------
193
194 template <class PointT>
195 void
196 BSplineSurfaceT<PointT>::
197 add_vector_n(const std::vector< Point> & _control_polygon)
198 {
199 insert_vector_n(_control_polygon, dimn_);
200 }
201
202 //-----------------------------------------------------------------------------
203
204 template <class PointT>
205 void
206 BSplineSurfaceT<PointT>::
207 insert_vector_m(const std::vector< Point> & _control_polygon, unsigned int _m)
208 {
209 std::cout << "insert_vector_m of size " << _control_polygon.size() << " at m = " << _m << std::endl;
210
211 assert(_m <= dimm_);
212 if (dimn_ == 0)
213 dimn_ =_control_polygon.size();
214
215 assert(_control_polygon.size() == dimn_);
216
217 resize(dimm_ + 1, dimn_);
218
219 control_net_.insert(control_net_.begin() + _m, _control_polygon);
220 control_net_.pop_back(); // TODO check
221 std::cout << "control_net_: " << control_net_.size() << " x " << control_net_[control_net_.size()-1].size() << std::endl;
222
223 // resize property net cpselection
224 std::vector<unsigned char> dummy(_control_polygon.size(), 0);
225 cpselections_.insert(cpselections_.begin() + _m, dummy);
226 cpselections_.pop_back();
227 std::cout << "cpselections_: " << cpselections_.size() << " x " << cpselections_[cpselections_.size()-1].size() << std::endl;
228
229 // resize property net eselection
230 eselections_.insert(eselections_.begin() + _m, dummy);
231 eselections_.pop_back();
232 std::cout << "eselections_: " << eselections_.size() << " x " << eselections_[eselections_.size()-1].size() << std::endl;
233 }
234
235 //-----------------------------------------------------------------------------
236
237 template <class PointT>
238 void
239 BSplineSurfaceT<PointT>::
240 insert_vector_n(const std::vector< Point> & _control_polygon, unsigned int _n)
241 {
242 assert(_n <= dimn_);
243 if (dimm_ == 0)
244 dimm_ = _control_polygon.size();
245
246 assert(_control_polygon.size() == dimm_);
247
248 resize(dimm_, dimn_+1);
249
250 for (unsigned int i = 0; i < dimm_; ++i)
251 {
252 control_net_[i].insert(control_net_[i].begin() + _n, _control_polygon[i]);
253 control_net_[i].pop_back();
254 }
255
256 // resize property net cpselection
257 for (unsigned int i = 0; i < dimm_; ++i)
258 {
259 cpselections_[i].insert(cpselections_[i].begin() + _n, 0);
260 cpselections_[i].pop_back();
261 }
262 // resize property net eselection
263 for (unsigned int i = 0; i < dimm_; ++i)
264 {
265 eselections_[i].insert(eselections_[i].begin() + _n, 0);
266 eselections_[i].pop_back();
267 }
268 }
269
270 //-----------------------------------------------------------------------------
271
272 template <class PointT>
273 void
274 BSplineSurfaceT<PointT>::
275 delete_vector_m(unsigned int _m)
276 {
277 assert(_m < dimm_);
278
280
281 if(control_net_.begin() + _m < control_net_.end())
282 control_net_.erase(control_net_.begin() + _m);
283
284 resize(dimm_-1, dimn_);
285
286 // erase from properties
287 if(cpselections_.begin() + _m < cpselections_.end())
288 cpselections_.erase(cpselections_.begin() + _m);
289
290 if(eselections_.begin() + _m < eselections_.end())
291 eselections_.erase(eselections_.begin() + _m);
292
293 // Now rebuild knot vectors
294 createKnots();
295 }
296
297 //-----------------------------------------------------------------------------
298
299 template <class PointT>
300 void
301 BSplineSurfaceT<PointT>::
302 delete_vector_n(unsigned int _n)
303 {
304 assert(_n < dimn_);
305
307
308 for (unsigned int i = 0; i < control_net_.size(); ++i) {
309 if(control_net_[i].begin() + _n < control_net_[i].end())
310 control_net_[i].erase(control_net_[i].begin() + _n);
311 }
312
313 resize(dimm_, dimn_-1);
314
315 // erase from properties
316 for (unsigned int i = 0; i < cpselections_.size(); ++i)
317 if(cpselections_[i].begin() + _n < cpselections_[i].end())
318 cpselections_[i].erase(cpselections_[i].begin() + _n);
319
320 for (unsigned int i = 0; i < eselections_.size(); ++i)
321 if(eselections_[i].begin() + _n < eselections_[i].end())
322 eselections_[i].erase(eselections_[i].begin() + _n);
323
324 // Now rebuild knot vectors
325 createKnots();
326 }
327
328 //-----------------------------------------------------------------------------
329
330 template <class PointT>
331 void
332 BSplineSurfaceT<PointT>::
333 get_vector_m(std::vector< Point> & _control_polygon, unsigned int _m)
334 {
335 assert(_m < dimm_);
336 _control_polygon = control_net_[_m];
337 }
338
339 //-----------------------------------------------------------------------------
340
341 template <class PointT>
342 void
343 BSplineSurfaceT<PointT>::
344 get_vector_n(std::vector< Point> & _control_polygon, unsigned int _n)
345 {
346 assert(_n < dimn_);
347 _control_polygon.resize(dimm_);
348
349 for (unsigned int i = 0; i < dimm_; ++i)
350 _control_polygon[i] = control_net_[i][_n];
351 }
352
353 //-----------------------------------------------------------------------------
354
355 template <class PointT>
356 void
357 BSplineSurfaceT<PointT>::
358 set_knots_m(std::vector< Scalar > _knots)
359 {
360 // set the knotvector
361 knotvector_m_.setKnotvector(_knots);
362 }
363
364 //-----------------------------------------------------------------------------
365
366 template <class PointT>
367 void
368 BSplineSurfaceT<PointT>::
369 set_knots_n(std::vector< Scalar > _knots)
370 {
371 // set the knotvector
372 knotvector_n_.setKnotvector(_knots);
373 }
374
375 //-----------------------------------------------------------------------------
376
377 template <class PointT>
378 void
379 BSplineSurfaceT<PointT>::
380 insert_knot_m(double _u)
381 {
382 // span and interval i,i+1
383 Vec2i span = spanm(_u);
384 Vec2i interval = interval_m(_u);
385
386 // create new knot vector
387 Knotvector newknotvecu( get_knotvector_m() );
388 newknotvecu.insertKnot(interval[1], _u);
389
390 // alphas
391 std::vector<double> alpha;
392 for( int i = span[0]; i < span[1]; ++i)
393 {
394 double a(knotvector_m_.getKnot(i+1));
395 double b(knotvector_m_.getKnot(i+degree_m_+1));
396 alpha.push_back((_u-a)/(b-a));
397 }
398 knotvector_m_ = newknotvecu;
399
400 // new control net
401 ControlNet oldcpts(control_net_);
402
403 resize(n_control_points_m()+1, n_control_points_n());
404
405 for( int i = 0; i < n_control_points_m(); ++i) // for all v rows
406 {
407 if( i <= span[0])
408 control_net_[i] = oldcpts[i];
409 else if( i <= span[1])
410 for( unsigned int j = 0; j < n_control_points_n(); ++j)
411 {
412 control_net_[i][j] = oldcpts[i-1][j]*(1.0-alpha[i-span[0]-1])+oldcpts[i][j]*alpha[i-span[0]-1];
413 }
414 else
415 control_net_[i] = oldcpts[i-1];
416 }
417 }
418
419 //-----------------------------------------------------------------------------
420
421 template <class PointT>
422 void
423 BSplineSurfaceT<PointT>::
424 insert_knot_n(double _v)
425 {
426 // span and interval i,i+1
427 Vec2i span = spann(_v);
428 Vec2i interval = interval_n(_v);
429
430 // create new knot vector
431 Knotvector newknotvecv( get_knotvector_n() );
432 newknotvecv.insertKnot(interval[1], _v);
433
434 // alphas
435 std::vector<double> alpha;
436 for( int i = span[0]; i < span[1]; ++i)
437 {
438 double a(knotvector_n_.getKnot(i+1));
439 double b(knotvector_n_.getKnot(i+degree_n_+1));
440 alpha.push_back((_v-a)/(b-a));
441 }
442 knotvector_n_ = newknotvecv;
443
444 // new control net
445 ControlNet oldcpts(control_net_);
446
447 resize(n_control_points_m(), n_control_points_n()+1);
448
449 for( int i = 0; i < n_control_points_n(); ++i) // for all v rows
450 {
451 if( i <= span[0])
452 for( unsigned int j = 0; j < n_control_points_m(); ++j)
453 control_net_[j][i] = oldcpts[j][i];
454 else if( i <= span[1])
455 for( unsigned int j = 0; j < n_control_points_m(); ++j)
456 {
457 control_net_[j][i] = oldcpts[j][i-1]*(1.0-alpha[i-span[0]-1])+oldcpts[j][i]*alpha[i-span[0]-1];
458 }
459 else
460 for( unsigned int j = 0; j < n_control_points_m(); ++j)
461 control_net_[j][i] = oldcpts[j][i-1];
462 }
463 }
464
465 //-----------------------------------------------------------------------------
466
467 template <class PointT>
468 PointT
469 BSplineSurfaceT<PointT>::
470 surfacePoint(double _u, double _v)
471 {
472 double epsilon = 0.0000001;
473
474 if (_u > upperu() && _u < upperu()+epsilon)
475 _u = upperu();
476
477 if (_v > upperv() && _v < upperv()+epsilon)
478 _v = upperv();
479
480 assert(_u >= loweru() && _u <= upperu());
481 assert(_v >= lowerv() && _v <= upperv());
482
483 int pm = degree_m();
484 int pn = degree_n();
485
486 Point point = Point(0.0, 0.0, 0.0);
487
488 Vec2i span_m(spanm(_u));
489 Vec2i span_n(spann(_v));
490
491
492 std::vector<Scalar> basisFuns_m(pm+1);
493 std::vector<Scalar> basisFuns_n(pn+1);
494
495 // evaluate basis functions
496 ACG::bsplineBasisFunctions(basisFuns_m, span_m, _u, knotvector_m_.getKnotvector());
497 ACG::bsplineBasisFunctions(basisFuns_n, span_n, _v, knotvector_n_.getKnotvector());
498
499 // compute surface point
500
501 for (int i = span_m[0]; i <= span_m[1]; ++i)
502 for (int j = span_n[0]; j <= span_n[1]; ++j)
503 point += control_net_[i][j] * basisFuns_m[i-span_m[0]] * basisFuns_n[j - span_n[0]];
504
505 return point;
506 }
507
508 //-----------------------------------------------------------------------------
509
510 template <class PointT>
511 void
512 BSplineSurfaceT<PointT>::
513 surfacePointNormal( Point& _pt, Point& _normal, double _u, double _v )
514 {
515 double epsilon = 0.0000001;
516
517 if (_u > upperu() && _u < upperu()+epsilon)
518 _u = upperu();
519
520 if (_v > upperv() && _v < upperv()+epsilon)
521 _v = upperv();
522
523 assert(_u >= loweru() && _u <= upperu());
524 assert(_v >= lowerv() && _v <= upperv());
525
526 int pm = degree_m();
527 int pn = degree_n();
528
529 _pt = Point(0.0, 0.0, 0.0);
530
531 Vec2i span_m(spanm(_u));
532 Vec2i span_n(spann(_v));
533
534
535 std::vector<Scalar> basisFuns_m(pm+1);
536 std::vector<Scalar> ders_m(pm+1);
537 std::vector<Scalar> basisFuns_n(pn+1);
538 std::vector<Scalar> ders_n(pn+1);
539
540 // evaluate basis functions
541 ACG::bsplineBasisDerivatives(ders_m, span_m, _u, 1, knotvector_m_.getKnotvector(), &basisFuns_m);
542 ACG::bsplineBasisDerivatives(ders_n, span_n, _v, 1, knotvector_n_.getKnotvector(), &basisFuns_n);
543
544
545 // compute surface point and tangents
546
547 Point dpdu = Point(0,0,0);
548 Point dpdv = Point(0,0,0);
549
550 for (int i = 0; i <= pm; ++i)
551 {
552 for (int j = 0; j <= pn; ++j)
553 {
554 Point cp = control_net_[i + span_m[0]][j + span_n[0]];
555
556 _pt += cp * (basisFuns_m[i] * basisFuns_n[j]);
557
558 dpdu += cp * (ders_m[i] * basisFuns_n[j]);
559 dpdv += cp * (basisFuns_m[i] * ders_n[j]);
560 }
561 }
562
563 _normal = (dpdu % dpdv).normalize();
564 }
565
566 //-----------------------------------------------------------------------------
567
568 template <class PointT>
569 PointT
570 BSplineSurfaceT<PointT>::
571 surfacePoint_rec(double _u, double _v)
572 {
573 double epsilon = 0.0000001;
574
575 if (_u > upperu() && _u < upperu()+epsilon)
576 _u = upperu();
577
578 if (_v > upperv() && _v < upperv()+epsilon)
579 _v = upperv();
580
581 assert(_u >= loweru() && _u <= upperu());
582 assert(_v >= lowerv() && _v <= upperv());
583
584 int pm = degree_m();
585 int pn = degree_n();
586
587 Point point = Point(0.0, 0.0, 0.0);
588
589 Vec2i span_m(spanm(_u));
590 Vec2i span_n(spann(_v));
591
592 for (int i = span_m[0]; i <= span_m[1]; ++i)
593 for (int j = span_n[0]; j <= span_n[1]; ++j)
594 point += control_net_[i][j] * basisFunction(knotvector_m_, i, pm, _u) * basisFunction(knotvector_n_, j, pn, _v);
595
596 return point;
597 }
598
599 //-----------------------------------------------------------------------------
600
601 template <class PointT>
602 typename BSplineSurfaceT<PointT>::Scalar
603 BSplineSurfaceT<PointT>::
604 basisFunction(Knotvector & _knotvector, int _i, int _n, double _t)
605 {
606 int m = _knotvector.size() - 1;
607
608 // Mansfield Cox deBoor recursion
609 if ((_i==0 && _t== _knotvector(0)) || (_i==m-_n-1 && _t==_knotvector(m)))
610 return 1.0;
611
612 if (_n == 0) {
613 if (_t >= _knotvector(_i) && _t < _knotvector(_i+1))
614 return 1.0;
615 else
616 return 0.0;
617 }
618
619 double Nin1 = basisFunction(_knotvector, _i, _n-1, _t);
620 double Nin2 = basisFunction(_knotvector, _i+1, _n-1, _t);
621
622 double fac1 = 0;
623 // if ((_knotvector(_i+_n) - _knotvector(_i)) > 0.000001 )
624 if ((_knotvector(_i+_n) - _knotvector(_i)) != 0)
625 fac1 = (_t - _knotvector(_i)) / (_knotvector(_i+_n) - _knotvector(_i)) ;
626
627 double fac2 = 0;
628 // if ( (_knotvector(_i+1+_n) - _knotvector(_i+1)) > 0.000001 )
629 if ( (_knotvector(_i+1+_n) - _knotvector(_i+1)) != 0 )
630 fac2 = (_knotvector(_i+1+_n) - _t) / (_knotvector(_i+1+_n) - _knotvector(_i+1));
631
632 // std::cout << "Nin1 = " << Nin1 << ", Nin2 = " << Nin2 << ", fac1 = " << fac1 << ", fac2 = " << fac2 << std::endl;
633
634 return (fac1*Nin1 + fac2*Nin2);
635 }
636
637 //-----------------------------------------------------------------------------
638
639 template <class PointT>
640 PointT
641 BSplineSurfaceT<PointT>::
642 derivativeSurfacePoint(double _u, double _v, int _derm, int _dern)
643 {
644 assert(_u >= loweru() && _u <= upperu());
645 assert(_v >= lowerv() && _v <= upperv());
646
647 int pn = degree_n();
648 int pm = degree_m();
649
650 Point point(0,0,0);
651
652 Vec2i span_m(spanm(_u));
653 Vec2i span_n(spann(_v));
654
655 std::vector<Scalar> ders_m(pm+1);
656 std::vector<Scalar> ders_n(pn+1);
657
658 ACG::bsplineBasisDerivatives<Scalar>(ders_m, span_m, _u, _derm, knotvector_m_.getKnotvector(), 0);
659 ACG::bsplineBasisDerivatives<Scalar>(ders_n, span_n, _v, _dern, knotvector_n_.getKnotvector(), 0);
660
661 for (int i = span_m[0]; i <= span_m[1]; i++)
662 for (int j = span_n[0]; j <= span_n[1]; j++)
663 point += control_net_[i][j] * ders_m[i - span_m[0]] * ders_n[j - span_n[0]];
664
665
666 return point;
667 }
668
669 //-----------------------------------------------------------------------------
670
671 template <class PointT>
672 PointT
673 BSplineSurfaceT<PointT>::
674 normalSurfacePoint(double _u, double _v)
675 {
676 assert(_u >= loweru() && _u <= upperu());
677 assert(_v >= lowerv() && _v <= upperv());
678
679 Point derivu = derivativeSurfacePoint(_u,_v,1,0);
680 Point derivv = derivativeSurfacePoint(_u,_v,0,1);
681
682 Point normal( (derivu%derivv).normalize());
683
684 return normal;
685 }
686
687 //-----------------------------------------------------------------------------
688
689 template <class PointT>
690 typename BSplineSurfaceT<PointT>::Scalar
691 BSplineSurfaceT<PointT>::
692 derivativeBasisFunction(Knotvector & _knotvector, int _i, int _n, double _t, int _der)
693 {
694 assert(_n >= 0);
695 assert(_i >= 0);
696
697 if (_der == 0)
698 return basisFunction(_knotvector, _i, _n, _t);
699
700 Scalar Nin1 = derivativeBasisFunction(_knotvector, _i, _n-1, _t, _der-1);
701 Scalar Nin2 = derivativeBasisFunction(_knotvector, _i+1, _n-1, _t, _der-1);
702
703 Scalar fac1 = 0;
704 if ( fabs(_knotvector(_i+_n)-_knotvector(_i)) > 1e-6 )
705 fac1 = Scalar(_n) / (_knotvector(_i+_n)-_knotvector(_i));
706
707 Scalar fac2 = 0;
708 if ( fabs(_knotvector(_i+_n+1)-_knotvector(_i+1)) > 1e-6 )
709 fac2 = Scalar(_n) / (_knotvector(_i+_n+1)-_knotvector(_i+1));
710
711 return (fac1*Nin1 - fac2*Nin2);
712 }
713
714 //-----------------------------------------------------------------------------
715
716 template <class PointT>
717 typename BSplineSurfaceT<PointT>::Scalar
718 BSplineSurfaceT<PointT>::
719 loweru()
720 {
721 return knotvector_m_(degree_m());
722 }
723
724 //-----------------------------------------------------------------------------
725
726 template <class PointT>
727 typename BSplineSurfaceT<PointT>::Scalar
728 BSplineSurfaceT<PointT>::
729 upperu() {
730 return knotvector_m_(knotvector_m_.size() - 1 - degree_m());
731 }
732
733 //-----------------------------------------------------------------------------
734
735 template <class PointT>
736 typename BSplineSurfaceT<PointT>::Scalar
737 BSplineSurfaceT<PointT>::
738 lowerv()
739 {
740 return knotvector_n_(degree_n());
741 }
742
743 //-----------------------------------------------------------------------------
744
745 template <class PointT>
746 typename BSplineSurfaceT<PointT>::Scalar
747 BSplineSurfaceT<PointT>::
748 upperv() {
749 return knotvector_n_(knotvector_n_.size() - 1 - degree_n());
750 }
751
752 //-----------------------------------------------------------------------------
753
754 template <class PointT>
755 ACG::Vec2i
756 BSplineSurfaceT<PointT>::
757 spanm(double _t)
758 {
759 return ACG::bsplineSpan(_t, degree_m(), knotvector_m_.getKnotvector());
760 }
761
762 //-----------------------------------------------------------------------------
763
764 template <class PointT>
765 ACG::Vec2i
766 BSplineSurfaceT<PointT>::
767 spann(double _t)
768 {
769 return ACG::bsplineSpan(_t, degree_n(), knotvector_n_.getKnotvector());
770 }
771
772 //-----------------------------------------------------------------------------
773
774 template <class PointT>
775 ACG::Vec2i
776 BSplineSurfaceT<PointT>::
777 interval_m(double _t)
778 {
779 unsigned int i(0);
780
781 if (_t >= upperu())
782 i = dimm_-1;
783 else
784 {
785 while (_t >= knotvector_m_(i)) i++;
786 while (_t < knotvector_m_(i)) i--;
787 }
788
789 return Vec2i(i, i+1);
790 }
791
792 //-----------------------------------------------------------------------------
793
794 template <class PointT>
795 ACG::Vec2i
796 BSplineSurfaceT<PointT>::
797 interval_n(double _t)
798 {
799 unsigned int i(0);
800
801 if (_t >= upperv())
802 i = dimn_-1;
803 else
804 {
805 while (_t >= knotvector_n_(i)) i++;
806 while (_t < knotvector_n_(i)) i--;
807 }
808
809 return Vec2i(i, i+1);
810 }
811
812 //-----------------------------------------------------------------------------
813
814 //=============================================================================
815 } // namespace ACG
816 //=============================================================================
ACG::BSplineSurfaceT::delete_vector_n
void delete_vector_n(unsigned int _n)
Deletes an m control point vector.
Definition: BSplineSurfaceT_impl.hh:302
ACG::BSplineSurfaceT::resize
void resize(unsigned int _m, unsigned int _n)
Resizes the spline struct.
Definition: BSplineSurfaceT_impl.hh:125
ACG::BSplineSurfaceT::normalSurfacePoint
Point normalSurfacePoint(double _u, double _v)
Returns the normal of a spline surface.
Definition: BSplineSurfaceT_impl.hh:674
ACG::Vec2i
VectorT< signed int, 2 > Vec2i
Definition: VectorT.hh:98
ACG::BSplineSurfaceT::surfacePoint_rec
Point surfacePoint_rec(double _u, double _v)
Evaluates a spline surface at parameters _u and _v.
Definition: BSplineSurfaceT_impl.hh:571
ACG::BSplineSurfaceT::degree_m
int degree_m() const
Returns the spline degree in m direction.
Definition: BSplineSurfaceT.hh:172
ACG::BSplineSurfaceT::dimm_
unsigned int dimm_
number of control points in m direction
Definition: BSplineSurfaceT.hh:457
ACG::bsplineBasisDerivatives
void bsplineBasisDerivatives(std::vector< Scalar > &_ders, const Vec2i &_span, Scalar _t, int _der, const std::vector< Scalar > &_knots, std::vector< Scalar > *_functionVals)
Compute derivatives of basis functions in a span.
Definition: BSplineBasis.cc:167
ACG::BSplineSurfaceT::spanm
ACG::Vec2i spanm(double _t)
Returns the basis functions which are unequal to zero at parameter u.
Definition: BSplineSurfaceT_impl.hh:757
ACG::BSplineSurfaceT::loweru
Scalar loweru()
Returns the lower u parameter.
Definition: BSplineSurfaceT_impl.hh:719
ACG
Namespace providing different geometric functions concerning angles.
Definition: BaseObjectData.hh:68
ACG::BSplineSurfaceT::upperv
Scalar upperv()
Returns the upper v parameter.
Definition: BSplineSurfaceT_impl.hh:748
ACG::BSplineSurfaceT::n_control_points_n
unsigned int n_control_points_n() const
Returns the number of controlpoints in n direction.
Definition: BSplineSurfaceT.hh:179
ACG::BSplineSurfaceT::add_vector_n
void add_vector_n(const std::vector< Point > &_control_polygon)
Adds a control point m-vector.
Definition: BSplineSurfaceT_impl.hh:197
ACG::BSplineSurfaceT::knotvector_m_
Knotvector knotvector_m_
Knotvector in m direction.
Definition: BSplineSurfaceT.hh:462
ACG::BSplineSurfaceT::set_degree
void set_degree(unsigned int _degm, unsigned int _degn)
Sets the degree of the spline surface.
Definition: BSplineSurfaceT_impl.hh:176
ACG::BSplineSurfaceT::spann
ACG::Vec2i spann(double _t)
Returns the basis functions which are unequal to zero at parameter v.
Definition: BSplineSurfaceT_impl.hh:767
OpenMesh::VectorT
Definition: Vector11T.hh:83
ACG::BSplineSurfaceT::interval_n
ACG::Vec2i interval_n(double _t)
Returns the index of the knots v and v+1 such that t in [v, v+1)
Definition: BSplineSurfaceT_impl.hh:797
ACG::BSplineSurfaceT::n_control_points_m
unsigned int n_control_points_m() const
Returns the number of controlpoints in m direction.
Definition: BSplineSurfaceT.hh:177
ACG::BSplineSurfaceT::createKnots
void createKnots()
Creates interpolating knotvectors 0...0, 1, 2, ..., n...n.
Definition: BSplineSurfaceT_impl.hh:165
ACG::BSplineSurfaceT::interval_m
ACG::Vec2i interval_m(double _t)
Returns the index of the knots u and u+1 such that t in [u, u+1)
Definition: BSplineSurfaceT_impl.hh:777
ACG::BSplineSurfaceT::surfacePoint
Point surfacePoint(double _u, double _v)
Evaluates a spline surface at parameters _u and _v.
Definition: BSplineSurfaceT_impl.hh:470
ACG::BSplineSurfaceT::BSplineSurfaceT
BSplineSurfaceT(unsigned int _degm=3, unsigned int _degn=3)
Constructor.
Definition: BSplineSurfaceT_impl.hh:75
ACG::bsplineSpan
Vec2i bsplineSpan(Scalar _t, int _degree, const std::vector< Scalar > &_knots)
Find the span of a parameter value.
Definition: BSplineBasis.cc:71
ACG::BSplineSurfaceT::add_vector_m
void add_vector_m(const std::vector< Point > &_control_polygon)
Adds a control point n-vector.
Definition: BSplineSurfaceT_impl.hh:187
ACG::BSplineSurfaceT::set_knots_m
void set_knots_m(std::vector< Scalar > _knots)
Set the knotvector of the bspline surface in m direction.
Definition: BSplineSurfaceT_impl.hh:358
ACG::BSplineSurfaceT::insert_vector_n
void insert_vector_n(const std::vector< Point > &_control_polygon, unsigned int _n)
Inserts an m control point vector.
Definition: BSplineSurfaceT_impl.hh:240
ACG::BSplineSurfaceT::set_knots_n
void set_knots_n(std::vector< Scalar > _knots)
Set the knotvector of the bspline surface in n direction.
Definition: BSplineSurfaceT_impl.hh:369
ACG::BSplineSurfaceT::get_knotvector_m
Knotvector get_knotvector_m()
Get the knotvector in m direction.
Definition: BSplineSurfaceT.hh:113
ACG::BSplineSurfaceT::cpselections_
PropertyNet cpselections_
list of control point properties
Definition: BSplineSurfaceT.hh:478
ACG::BSplineSurfaceT::degree_n_
unsigned int degree_n_
Spline degree in n direction.
Definition: BSplineSurfaceT.hh:460
ACG::BSplineSurfaceT::get_vector_m
void get_vector_m(std::vector< Point > &_control_polygon, unsigned int _m)
Returns an n control point vector.
Definition: BSplineSurfaceT_impl.hh:333
ACG::bsplineBasisFunctions
void bsplineBasisFunctions(std::vector< Scalar > &_N, const Vec2i &_span, Scalar _t, const std::vector< Scalar > &_knots)
Evaluate basis functions in a span.
Definition: BSplineBasis.cc:119
ACG::BSplineSurfaceT::reset_control_net
void reset_control_net()
Clears the control net.
Definition: BSplineSurfaceT_impl.hh:151
ACG::BSplineSurfaceT::lowerv
Scalar lowerv()
Returns the lower v parameter.
Definition: BSplineSurfaceT_impl.hh:738
ACG::BSplineSurfaceT
Definition: BSplineSurfaceT.hh:82
ACG::BSplineSurfaceT::delete_vector_m
void delete_vector_m(unsigned int _m)
Deletes an n control point vector.
Definition: BSplineSurfaceT_impl.hh:275
ACG::BSplineSurfaceT::dimn_
unsigned int dimn_
number of control points in n direction
Definition: BSplineSurfaceT.hh:458
ACG::BSplineSurfaceT::upperu
Scalar upperu()
Returns the upper u parameter.
Definition: BSplineSurfaceT_impl.hh:729
ACG::BSplineSurfaceT::insert_knot_m
void insert_knot_m(double _t)
Insert a knot i in m direction without changing the surface.
Definition: BSplineSurfaceT_impl.hh:380
ACG::BSplineSurfaceT::knotvector_n_
Knotvector knotvector_n_
Knotvector in n direction.
Definition: BSplineSurfaceT.hh:463
ACG::BSplineSurfaceT::eselections_
PropertyNet eselections_
list of edge properties
Definition: BSplineSurfaceT.hh:482
ACG::BSplineSurfaceT::insert_vector_m
void insert_vector_m(const std::vector< Point > &_control_polygon, unsigned int _m)
Inserts an n control point vector.
Definition: BSplineSurfaceT_impl.hh:207
ACG::BSplineSurfaceT::surfacePointNormal
void surfacePointNormal(Point &_pt, Point &_normal, double _u, double _v)
Evaluates a spline surface at parameters _u and _v.
Definition: BSplineSurfaceT_impl.hh:513
ACG::BSplineSurfaceT::get_vector_n
void get_vector_n(std::vector< Point > &_control_polygon, unsigned int _n)
Returns an m ctrPointVector.
Definition: BSplineSurfaceT_impl.hh:344
ACG::BSplineSurfaceT::degree_n
int degree_n() const
Returns the spline degree in n direction.
Definition: BSplineSurfaceT.hh:174
ACG::BSplineSurfaceT::basisFunction
Scalar basisFunction(Knotvector &_knotvector, int _i, int _n, double _t)
A Spline Basis Function.
Definition: BSplineSurfaceT_impl.hh:604
ACG::BSplineSurfaceT::insert_knot_n
void insert_knot_n(double _t)
Insert a knot i in n direction without changing the surface.
Definition: BSplineSurfaceT_impl.hh:424
ACG::BSplineSurfaceT::get_knotvector_n
Knotvector get_knotvector_n()
Get the knotvector in n direction.
Definition: BSplineSurfaceT.hh:115
ACG::KnotvectorT< double >
ACG::BSplineSurfaceT::derivativeSurfacePoint
Point derivativeSurfacePoint(double _u, double _v, int _derm, int _dern)
Returns the _derm&#39;th derivative of a spline surface.
Definition: BSplineSurfaceT_impl.hh:642
ACG::BSplineSurfaceT::degree_m_
unsigned int degree_m_
Spline degree in m direction.
Definition: BSplineSurfaceT.hh:459
ACG::BSplineSurfaceT::derivativeBasisFunction
Scalar derivativeBasisFunction(Knotvector &_knotvector, int _i, int _n, double _t, int _der)
Derivative of a Spline Basis Function.
Definition: BSplineSurfaceT_impl.hh:692