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 _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 }
00254
00255
00256 #endif // _BERNSTEINUTILS_H
00257
00258