SplineSurface.h

00001 //===========================================================================
00002 // GoTools - SINTEF Geometry Tools version 1.1
00003 //
00004 // GoTools module: CORE
00005 //
00006 // Copyright (C) 2000-2007 SINTEF ICT, Applied Mathematics, Norway.
00007 //
00008 // This program is free software; you can redistribute it and/or          
00009 // modify it under the terms of the GNU General Public License            
00010 // as published by the Free Software Foundation version 2 of the License. 
00011 //
00012 // This program is distributed in the hope that it will be useful,        
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00015 // GNU General Public License for more details.                           
00016 //
00017 // You should have received a copy of the GNU General Public License      
00018 // along with this program; if not, write to the Free Software            
00019 // Foundation, Inc.,                                                      
00020 // 59 Temple Place - Suite 330,                                           
00021 // Boston, MA  02111-1307, USA.                                           
00022 //
00023 // Contact information: E-mail: tor.dokken@sintef.no                      
00024 // SINTEF ICT, Department of Applied Mathematics,                         
00025 // P.O. Box 124 Blindern,                                                 
00026 // 0314 Oslo, Norway.                                                     
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
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     // inherited from Streamable
00189     virtual void read (std::istream& is);
00190 
00191     // inherited from Streamable
00192     virtual void write (std::ostream& os) const;
00193 
00194     // inherited from GeomObject
00195     virtual BoundingBox boundingBox() const;
00196 
00197     // inherited from GeomObject
00198     virtual int dimension() const;
00199     
00201     void swap(SplineSurface& other);
00202 
00203     // inherited from GeomObject
00204     virtual ClassType instanceType() const;
00205 
00206     // inherited from GeomObject
00207     static ClassType classType()
00208     { return Class_SplineSurface; }
00209 // #if ((_MSC_VER > 0) && (_MSC_VER < 1300))
00210 //     virtual GeomObject* clone() const
00211 //     { return new SplineSurface(*this); }
00212 // #else
00213     virtual SplineSurface* clone() const
00214     { return new SplineSurface(*this); }
00215 // #endif
00216 
00217     // inherited from ParamSurface
00218 // #if ((_MSC_VER > 0) && (_MSC_VER < 1300))
00219 //     virtual const Domain& parameterDomain() const;
00220 // #else
00221     virtual const RectDomain& parameterDomain() const;
00222 // #endif
00223 
00224     // inherited from ParamSurface
00225     virtual RectDomain containingDomain() const;
00226 
00227     // inherited from ParamSurface
00228     virtual CurveLoop outerBoundaryLoop(double degenerate_epsilon
00229                                           = DEFAULT_SPACE_EPSILON) const;
00230     // inherited from ParamSurface
00231     virtual std::vector<CurveLoop> allBoundaryLoops(double degenerate_epsilon
00232                                                       = DEFAULT_SPACE_EPSILON) const;
00233 
00234     // inherited from ParamSurface
00235     virtual void point(Point& pt, double upar, double vpar) const;
00236 
00237     // Output: Partial derivatives up to order derivs (pts[0]=S(u,v),
00238     // pts[1]=dS/du=S_u, pts[2]=S_v, pts[3]=S_uu, pts[4]=S_uv, pts[5]=S_vv, ...)
00239     // inherited from ParamSurface
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     // inherited from ParamSurface
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     // inherited from ParamSurface
00284     virtual DirectionCone tangentCone(bool pardir_is_u) const;
00285 
00286     // Creates a composite box enclosing the surface. The composite box
00287     // consists of an inner and an edge box. The inner box is
00288     // made from the interior control points of the surface, while the
00289     // edge box is made from the boundary control points.
00290     // Inherited from ParamSurface
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     // inherited from ParamSurface
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     // inherited from ParamSurface
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     // inherited from ParamSurface
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     // inherited from ParamSurface
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     // corresponding boundary.  The Boundaries are indexed as in \getBoundaryIdx().
00465     void getBoundaryIdx(Point& pt1, double epsilon, int& bdindex,
00466                         double knot_tol = 1e-05) const;
00467 
00468     // inherited from ParamSurface
00469     virtual void turnOrientation();
00470 
00471     // inherited from ParamSurface
00472     virtual void swapParameterDirection();
00473 
00474     // inherited from ParamSurface
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     // inherited from ParamSurface
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     // inherited from ParamSurface
00680     virtual std::vector< boost::shared_ptr<ParamCurve> >
00681     constParamCurves(double parameter, bool pardir_is_u) const;
00682 
00691 
00692 
00704   // @@sbr What about the orientation? Seems it follows that of the sf.
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     // inherited from ParamSurface
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     // Canonical data
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     // Generated data
00784     mutable RectDomain domain_;
00785     mutable CurveLoop spatial_boundary_;
00786     mutable degenerate_info degen_;
00787 
00788 
00789     // Helper functions
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, // normal is not defined here
00796                            double interval_end,
00797                            Point& normal) const;
00798 
00799     // Members new to this class
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     // Rewritten pointsGrid, to avoid reformatting results.
00809     // Does not return the derivatives, works only for a 3D non-rational
00810     // spline.
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     // Actually computes the closest point. Only difference is the explicit
00820     // robust_seedfind-parameter, which is always true in the virtual
00821     // closestPoint() function, when that function calls closestPointImpl().
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 } // namespace Go
00848 
00849 
00850 
00851 
00852 #endif // _GOSPLINESURFACE_H
00853 
00854 

Generated on Mon Jun 11 14:48:18 2007 for GoTools Core Library by  doxygen 1.5.1