BernsteinUtils.h

00001 //===========================================================================
00002 // GoTools - SINTEF Geometry Tools
00003 //
00004 // GoTools module: Implicitization, version 1.0
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 _BERNSTEINUTILS_H
00034 #define _BERNSTEINUTILS_H
00035 
00036 
00037 #include "BernsteinPoly.h"
00038 #include "BernsteinMulti.h"
00039 #include "Array.h"
00040 #include "SplineCurve.h"
00041 #include "SplineSurface.h"
00042 #include <vector>
00043 
00044 
00045 namespace Go {
00048 
00049 
00050 
00051 class SplineCurve;
00052 class SplineSurface;
00053 
00054 
00063 void spline_to_bernstein(const SplineCurve& seg, int dd,
00064                          BernsteinPoly& bp);
00065 
00068 void spline_to_bernstein(const SplineSurface& pat, int dd,
00069                          BernsteinMulti& bm);
00070 
00073 void spline_to_bernstein(const SplineCurve& seg,
00074                          std::vector<BernsteinPoly>& seg_bp);
00075 
00076 
00079 void spline_to_bernstein(const SplineSurface& pat,
00080                          std::vector<BernsteinMulti>& pat_bm);
00081 
00082 
00091 template <int Ndim>
00092 void splineToBernstein(const SplineCurve& segment,
00093                        Array<BernsteinPoly, Ndim>& curve_bp)
00094 {
00095     int order = segment.order();
00096     ALWAYS_ERROR_IF(order != segment.numCoefs(),
00097                     "The curve is not Bezier");
00098     int dim = segment.dimension();
00099     bool rational = segment.rational();
00100     int ndim = rational ? dim+1 : dim;
00101     ALWAYS_ERROR_IF(ndim != Ndim,
00102                     "The dimension of curve_bp does not match the "
00103                     "dimension of seg");
00104     std::vector<double> coefs(order);
00105     for (int i = 0; i < Ndim; ++i) {
00106         curve_bp[i] = BernsteinPoly(coefs);
00107     }
00108     std::vector<double>::const_iterator segment_coefs;
00109     if (rational) {
00110         segment_coefs = segment.rcoefs_begin();
00111     } else {
00112         segment_coefs = segment.coefs_begin();
00113     }
00114     for (int i = 0; i < order; ++i) {
00115         for (int dd = 0; dd < Ndim; ++dd) {
00116             curve_bp[dd][i] = segment_coefs[Ndim*i + dd];
00117         }
00118     }
00119 
00120     return;
00121 }
00122 
00123 
00132 template <int Ndim>
00133 void splineToBernstein(const SplineSurface& patch,
00134                        Array<BernsteinMulti, Ndim>& surface_bm)
00135 {
00136     int orderu = patch.order_u();
00137     int orderv = patch.order_v();
00138     ALWAYS_ERROR_IF((orderu != patch.numCoefs_u())
00139                     || (orderv != patch.numCoefs_v()),
00140                     "The surface is not Bezier");
00141     int dim = patch.dimension();
00142     bool rational = patch.rational();
00143     int ndim = rational ? dim+1 : dim;
00144     ALWAYS_ERROR_IF(ndim != Ndim,
00145                     "The dimension of surface_bm does not match the "
00146                     "dimension of pat");
00147     std::vector<double> coefs(orderu * orderv);
00148     for (int i = 0; i < Ndim; ++i) {
00149         surface_bm[i] = BernsteinMulti(orderu-1, orderv-1, coefs);
00150     }
00151     std::vector<double>::const_iterator patch_coefs;
00152     if (rational) {
00153         patch_coefs = patch.rcoefs_begin();
00154     } else {
00155         patch_coefs = patch.coefs_begin();
00156     }
00157     for (int j = 0; j < orderv; ++j) {
00158         for (int i = 0; i < orderu; ++i) {
00159             for (int dd = 0; dd < Ndim; ++dd) {
00160                 surface_bm[dd][orderu*j + i]
00161                     = patch_coefs[Ndim*(orderu*j + i) + dd];
00162             }
00163         }
00164     }
00165 
00166     return;
00167 }
00168 
00169 
00179 template <int Ndim>
00180 void bernsteinToSpline(const Array<BernsteinPoly, Ndim>& curve_bp,
00181                        bool rational,
00182                        SplineCurve& segment)
00183 {
00184     int npoints = curve_bp[0].degree() + 1;
00185     int order = npoints;
00186     int dim = (rational ? Ndim - 1 : Ndim);
00187     std::vector<double> knots(2 * order, 0.0);
00188     for (int i = order; i < 2 * order; ++i)
00189         knots[i] = 1.0;
00190     std::vector<double> coefs(Ndim * npoints);
00191     for (int j = 0; j < npoints; ++j) {
00192         for (int dd = 0; dd < dim; ++dd) {
00193             coefs[j*Ndim + dd] = curve_bp[dd][j];
00194         }
00195         if (rational) {
00196             coefs[j*Ndim + dim] = curve_bp[Ndim-1][j];
00197         }
00198     }
00199 
00200     segment = SplineCurve(npoints, order,
00201                           knots.begin(), coefs.begin(), dim, rational);
00202     return;
00203 }
00204 
00205 
00215 template <int Ndim>
00216 void bernsteinToSpline(const Array<BernsteinMulti, Ndim>& surface_bm,
00217                        bool rational,
00218                        SplineSurface& patch)
00219 {
00220     int npointsu = surface_bm[0].degreeU() + 1;
00221     int npointsv = surface_bm[0].degreeV() + 1;
00222     int orderu = npointsu;
00223     int orderv = npointsv;
00224     int dim = (rational ? Ndim - 1 : Ndim);
00225     std::vector<double> knotsu(2 * orderu, 0.0);
00226     for (int i = orderu; i < 2 * orderu; ++i)
00227         knotsu[i] = 1.0;
00228     std::vector<double> knotsv(2 * orderv, 0.0);
00229     for (int i = orderv; i < 2 * orderv; ++i)
00230         knotsv[i] = 1.0;
00231     std::vector<double> coefs(Ndim * npointsu * npointsv);
00232     for (int j = 0; j < npointsv; ++j) {
00233         for (int i = 0; i < npointsu; ++i) {
00234             for (int dd = 0; dd < dim; ++dd) {
00235                 coefs[(npointsu*j + i) * Ndim + dd]
00236                     = surface_bm[dd][npointsu*j + i];
00237             }
00238             if (rational) {
00239                 coefs[(npointsu*j + i) * Ndim + dim]
00240                     = surface_bm[Ndim-1][npointsu*j + i];
00241             }
00242         }
00243     }
00244 
00245     patch = SplineSurface(npointsu, npointsv, orderu, orderv,
00246                           knotsu.begin(), knotsv.begin(),
00247                           coefs.begin(), dim, rational);
00248     return;
00249 }
00250 
00251 
00253 } // namespace Go
00254 
00255 
00256 #endif // _BERNSTEINUTILS_H
00257 
00258 

Generated on Mon Jun 11 15:13:16 2007 for GoTools Implicitization Library by  doxygen 1.5.1