Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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