00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _GOSPLINESURFACE_H
00034 #define _GOSPLINESURFACE_H
00035
00036
00037 #include "ParamSurface.h"
00038 #include "BsplineBasis.h"
00039 #include "RectDomain.h"
00040 #include "ScratchVect.h"
00041
00042
00043 namespace Go
00044 {
00047
00048
00049 class Interpolator;
00050 class SplineCurve;
00051 class DirectionCone;
00052
00082 class SplineSurface : public ParamSurface
00083 {
00084 public:
00087 SplineSurface()
00088 : dim_(-1), rational_(false)
00089 {
00090 }
00091
00115 template <typename RandomIterator1,
00116 typename RandomIterator2,
00117 typename RandomIterator3>
00118 SplineSurface(int number1,
00119 int number2,
00120 int order1,
00121 int order2,
00122 RandomIterator1 knot1start,
00123 RandomIterator2 knot2start,
00124 RandomIterator3 coefsstart,
00125 int dim,
00126 bool rational = false)
00127 : dim_(dim), rational_(rational),
00128 basis_u_(number1, order1, knot1start),
00129 basis_v_(number2, order2, knot2start)
00130 {
00131 if (rational) {
00132 int n = (dim+1)*number1*number2;
00133 rcoefs_.resize(n);
00134 std::copy(coefsstart, coefsstart + n, rcoefs_.begin());
00135 coefs_.resize(dim*number1*number2);
00136 updateCoefsFromRcoefs();
00137 } else {
00138 int n = dim*number1*number2;
00139 coefs_.resize(n);
00140 std::copy(coefsstart, coefsstart + n, coefs_.begin());
00141 }
00142 }
00143
00160 template <typename RandomIterator>
00161 SplineSurface(const BsplineBasis& basis_u,
00162 const BsplineBasis& basis_v,
00163 RandomIterator coefsstart,
00164 int dim,
00165 bool rational = false)
00166 : dim_(dim), rational_(rational),
00167 basis_u_(basis_u),
00168 basis_v_(basis_v)
00169 {
00170 int number1 = basis_u.numCoefs();
00171 int number2 = basis_v.numCoefs();
00172 if (rational) {
00173 int n = (dim+1)*number1*number2;
00174 rcoefs_.resize(n);
00175 std::copy(coefsstart, coefsstart + n, rcoefs_.begin());
00176 coefs_.resize(dim*number1*number2);
00177 updateCoefsFromRcoefs();
00178 } else {
00179 int n = dim*number1*number2;
00180 coefs_.resize(n);
00181 std::copy(coefsstart, coefsstart + n, coefs_.begin());
00182 }
00183 }
00184
00186 virtual ~SplineSurface();
00187
00188
00189 virtual void read (std::istream& is);
00190
00191
00192 virtual void write (std::ostream& os) const;
00193
00194
00195 virtual BoundingBox boundingBox() const;
00196
00197
00198 virtual int dimension() const;
00199
00201 void swap(SplineSurface& other);
00202
00203
00204 virtual ClassType instanceType() const;
00205
00206
00207 static ClassType classType()
00208 { return Class_SplineSurface; }
00209
00210
00211
00212
00213 virtual SplineSurface* clone() const
00214 { return new SplineSurface(*this); }
00215
00216
00217
00218
00219
00220
00221 virtual const RectDomain& parameterDomain() const;
00222
00223
00224
00225 virtual RectDomain containingDomain() const;
00226
00227
00228 virtual CurveLoop outerBoundaryLoop(double degenerate_epsilon
00229 = DEFAULT_SPACE_EPSILON) const;
00230
00231 virtual std::vector<CurveLoop> allBoundaryLoops(double degenerate_epsilon
00232 = DEFAULT_SPACE_EPSILON) const;
00233
00234
00235 virtual void point(Point& pt, double upar, double vpar) const;
00236
00237
00238
00239
00240 virtual void point(std::vector<Point>& pts,
00241 double upar, double vpar,
00242 int derivs,
00243 bool u_from_right = true,
00244 bool v_from_right = true,
00245 double resolution = 1.0e-12) const;
00246
00249 virtual double startparam_u() const;
00250
00253 virtual double startparam_v() const;
00254
00257 virtual double endparam_u() const;
00258
00261 virtual double endparam_v() const;
00262
00263
00264 virtual void normal(Point& n, double upar, double vpar) const;
00265
00267 enum NormalConeMethod {
00268 SederbergMeyers = 0,
00269 SMCornersFirst = 1
00270 };
00274 DirectionCone normalCone(NormalConeMethod method) const;
00275
00281 virtual DirectionCone normalCone() const;
00282
00283
00284 virtual DirectionCone tangentCone(bool pardir_is_u) const;
00285
00286
00287
00288
00289
00290
00291 virtual CompositeBox compositeBox() const;
00292
00294 SplineSurface* normal() const;
00295
00303 SplineSurface* normalSurface() const;
00304
00313 SplineSurface* derivSurface(int ider1, int ider2) const;
00314
00324 SplineSurface* subSurface(double from_upar,
00325 double from_vpar,
00326 double to_upar,
00327 double to_vpar,
00328 double fuzzy =
00329 DEFAULT_PARAMETER_EPSILON) const;
00330
00331
00332 virtual std::vector<boost::shared_ptr<ParamSurface> >
00333 subSurfaces(double from_upar, double from_vpar,
00334 double to_upar, double to_vpar,
00335 double fuzzy = DEFAULT_PARAMETER_EPSILON) const;
00336
00337
00338 virtual void closestPoint(const Point& pt,
00339 double& clo_u,
00340 double& clo_v,
00341 Point& clo_pt,
00342 double& clo_dist,
00343 double epsilon,
00344 const RectDomain* domain_of_interest = NULL,
00345 double *seed = 0) const;
00346
00347
00348 virtual void closestBoundaryPoint(const Point& pt,
00349 double& clo_u,
00350 double& clo_v,
00351 Point& clo_pt,
00352 double& clo_dist,
00353 double epsilon,
00354 const RectDomain* rd = NULL,
00355 double *seed = 0) const;
00356
00380 void appendSurface(ParamSurface* sf, int join_dir,
00381 int continuity, double& dist, bool repar=true);
00382
00383 void appendSurface(SplineSurface* sf, int join_dir, int continuity, double& dist);
00384
00396 void appendSurface(ParamSurface* sf, int join_dir, bool repar=true);
00397
00398
00399 virtual void getBoundaryInfo(Point& pt1, Point& pt2,
00400 double epsilon, SplineCurve*& cv,
00401 SplineCurve*& crosscv, double knot_tol = 1e-05) const;
00402
00420 void getBoundaryInfo(double par1, double par2,
00421 int bdindex, SplineCurve*& cv,
00422 SplineCurve*& crosscv, double knot_tol = 1e-05) const;
00423
00450 void getBoundaryIdx(Point& pt1, Point& pt2,
00451 double epsilon, int& bdindex,
00452 double& par1, double& par2, double knot_tol = 1e-05) const;
00453
00455
00465 void getBoundaryIdx(Point& pt1, double epsilon, int& bdindex,
00466 double knot_tol = 1e-05) const;
00467
00468
00469 virtual void turnOrientation();
00470
00471
00472 virtual void swapParameterDirection();
00473
00474
00475 virtual void reverseParameterDirection(bool direction_is_u);
00476
00482
00483
00484
00485
00486
00487
00488 int boundaryIndex(Point& param_pt1, Point& param_pt2) const;
00489
00492 const BsplineBasis& basis_u() const
00493 { return basis_u_; }
00494
00497 const BsplineBasis& basis_v() const
00498 { return basis_v_; }
00499
00504 const BsplineBasis& basis(int i) const
00505 { return (i==0) ? basis_u_ : basis_v_; }
00506
00509 int numCoefs_u() const
00510 { return basis_u_.numCoefs(); }
00511
00514 int numCoefs_v() const
00515 { return basis_v_.numCoefs(); }
00516
00519 int order_u() const
00520 { return basis_u_.order(); }
00521
00524 int order_v() const
00525 { return basis_v_.order(); }
00526
00529 bool rational() const
00530 { return rational_; }
00531
00536 std::vector<double>::iterator coefs_begin()
00537 { return coefs_.begin(); }
00538
00543 std::vector<double>::iterator coefs_end()
00544 { return coefs_.end(); }
00545
00550 std::vector<double>::const_iterator coefs_begin() const
00551 { return coefs_.begin(); }
00552
00557 std::vector<double>::const_iterator coefs_end() const
00558 { return coefs_.end(); }
00559
00564 std::vector<double>::iterator rcoefs_begin()
00565 { return rcoefs_.begin(); }
00566
00571 std::vector<double>::iterator rcoefs_end()
00572 { return rcoefs_.end(); }
00573
00578 std::vector<double>::const_iterator rcoefs_begin() const
00579 { return rcoefs_.begin(); }
00580
00585 std::vector<double>::const_iterator rcoefs_end() const
00586 { return rcoefs_.end(); }
00587
00588
00589 virtual bool isDegenerate(bool& b, bool& r,
00590 bool& t, bool& l, double tolerance) const;
00591
00597 void setParameterDomain(double u1, double u2, double v1, double v2);
00598
00601 void insertKnot_u(double apar);
00602
00606 void insertKnot_u(const std::vector<double>& new_knots);
00607
00610 void insertKnot_v(double apar);
00611
00615 void insertKnot_v(const std::vector<double>& new_knots);
00616
00619 void removeKnot_u(double tpar);
00620
00623 void removeKnot_v(double tpar);
00624
00627 void makeBernsteinKnotsU();
00628
00631 void makeBernsteinKnotsV();
00632
00636 int numberOfPatches_u() const;
00637
00641 int numberOfPatches_v() const;
00642
00648 void raiseOrder(int raise_u, int raise_v);
00649
00658 SplineCurve* constParamCurve(double parameter,
00659 bool pardir_is_u) const;
00660
00674 void constParamCurve(double parameter,
00675 bool pardir_is_u,
00676 SplineCurve*& cv,
00677 SplineCurve*& crosscv) const;
00678
00679
00680 virtual std::vector< boost::shared_ptr<ParamCurve> >
00681 constParamCurves(double parameter, bool pardir_is_u) const;
00682
00691
00692
00704
00705 SplineCurve* edgeCurve(int ccw_edge_number) const;
00706
00721 void interpolate(Interpolator& interpolator1,
00722 Interpolator& interpolator2,
00723 int num_points1,
00724 int num_points2,
00725 int dim,
00726 const double* param1_start,
00727 const double* param2_start,
00728 const double* data_start);
00729
00740 void gridEvaluator(int num_u, int num_v,
00741 std::vector<double>& points,
00742 std::vector<double>& normals,
00743 std::vector<double>& param_u,
00744 std::vector<double>& param_v) const;
00745
00755 void gridEvaluator(int num_u, int num_v,
00756 std::vector<double>& points,
00757 std::vector<double>& param_u,
00758 std::vector<double>& param_v) const;
00759
00760
00761 virtual double nextSegmentVal(int dir, double par, bool forward, double tol) const;
00762
00763
00764 private:
00765
00766 struct degenerate_info
00767 {
00768 bool is_set_;
00769 bool b_, r_, t_, l_;
00770
00771 degenerate_info()
00772 { is_set_ = false; }
00773 };
00774
00775
00776 int dim_;
00777 bool rational_;
00778 BsplineBasis basis_u_;
00779 BsplineBasis basis_v_;
00780 std::vector<double> coefs_;
00781 std::vector<double> rcoefs_;
00782
00783
00784 mutable RectDomain domain_;
00785 mutable CurveLoop spatial_boundary_;
00786 mutable degenerate_info degen_;
00787
00788
00789
00790 void updateCoefsFromRcoefs();
00791 std::vector<double>& activeCoefs() { return rational_ ? rcoefs_ : coefs_; }
00792 bool normal_not_failsafe(Point& n, double upar, double vpar) const;
00793 bool search_for_normal(bool interval_in_u,
00794 double fixed_parameter,
00795 double interval_start,
00796 double interval_end,
00797 Point& normal) const;
00798
00799
00800 void pointsGrid(int m1, int m2, int derivs,
00801 const double* basisvals1,
00802 const double* basisvals2,
00803 const int* knotint1,
00804 const int* knotint2,
00805 double* result,
00806 double* normals = 0) const;
00807
00808
00809
00810
00811 void pointsGridNoDerivs(int m1, int m2,
00812 const double* basisvals1,
00813 const double* basisvals2,
00814 const int* knotint1,
00815 const int* knotint2,
00816 double* result,
00817 double* normals = 0) const;
00818
00819
00820
00821
00822 void closestPointImpl(const Point& pt,
00823 double& clo_u,
00824 double& clo_v,
00825 Point& clo_pt,
00826 double& clo_dist,
00827 double epsilon,
00828 const RectDomain* domain_of_interest = NULL,
00829 bool robust_seedfind = true,
00830 double *seed = 0) const;
00831
00832 void s1773(const double ppoint[],double aepsge, double estart[],double eend[],double enext[],
00833 double gpos[],int *jstat) const;
00834
00835 void s1773_s9corr(double gd[],double acoef1,double acoef2,
00836 double astart1,double aend1,double astart2,double aend2) const;
00837
00838 void s1773_s9dir(double *cdist,double *cdiff1,double *cdiff2,
00839 double PS[],const double *eval1,std::vector<Point> eval2,
00840 double aepsge, int idim,int *jstat) const;
00841
00842
00843 };
00844
00845
00847 }
00848
00849
00850
00851
00852 #endif // _GOSPLINESURFACE_H
00853
00854