OSGBSplineTensorSurface.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                           OpenSG NURBS Library                            *
00003  *                                                                           *
00004  *                                                                           *
00005  * Copyright (C) 2001-2006 by the University of Bonn, Computer Graphics Group*
00006  *                                                                           *
00007  *                         http://cg.cs.uni-bonn.de/                         *
00008  *                                                                           *
00009  * contact: edhellon@cs.uni-bonn.de, guthe@cs.uni-bonn.de, rk@cs.uni-bonn.de *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 #ifdef WIN32
00039 #   pragma warning (disable : 985)
00040 #endif
00041 #include "OSGBSplineTensorSurface.h"
00042
00043 OSG_USING_NAMESPACE
00044
00045
00046
00047 // FIXME: clean up all of the copy'n'paste mess...
00048 // FIXME: double-check that we actually got it correct...
00049
00050 #ifdef _DEBUG
00051  #ifdef WIN32
00052   #undef THIS_FILE
00053 static char THIS_FILE[] = __FILE__;
00054  #endif
00055 #endif
00056 
00057 const char BSplineTensorSurface::ff_const_1[] = "BEGINBSPLINETENSORSURFACE";
00058 const char BSplineTensorSurface::ff_const_2[] = "DIMENSIONU";
00059 const char BSplineTensorSurface::ff_const_3[] = "DIMENSIONV";
00060 const char BSplineTensorSurface::ff_const_4[] = "NUMBEROFCONTROLPOINTS";
00061 const char BSplineTensorSurface::ff_const_5[] = "BEGINRATIONALBSPLINETENSORSURFACE";
00062
00063
00064 int BSplineTensorSurface::CheckKnotPoints(const DCTPdvector& knots, int dim)
00065 {
00066     //now check knotvector whether it has
00067     //(a,a,....a, ......., b,b,....b)
00068     // |-dim+1-|           |-dim+1-|
00069     //structure
00070
00071     DCTPdvector::size_type max_index  = knots.size() - 1;
00072     double                 test_begin = knots[0], test_end = knots[max_index];
00073
00074     for(DCTPdvector::size_type i = 1; i < static_cast<unsigned int>(dim) + 1; ++i)
00075         if(knots[i] != test_begin || knots[max_index - i] != test_end)
00076             return -1;                                                                //FIXME: double comparison ?!
00077
00078     return 0;
00079 }
00080
00081 int BSplineTensorSurface::deleteBezierKnot_U(double k)
00082 {
00083     DCTPdvector knots = basis_function_u.getKnotVector();
00084
00085     if(k >= knots[knots.size() - 1])
00086         return -1;                                 // knot is too high
00087     if(k <= knots[0])
00088         return -2;                  // knot is too low
00089
00090     DCTPdvector::size_type i    = 0;
00091     int                    mult = 0;
00092     while(knots[i] <= k)
00093     {
00094         if(knots[i] == k)
00095             mult++;
00096         i++;
00097     }
00098     if(mult < dimension_u + 1)
00099         return -3;                         // knot doesn't have enough multiplicity
00100     i--;
00101
00102     // delete from knotvector
00103     knots.erase(knots.begin() + i);
00104     // set new knot vector
00105     basis_function_u.setKnotVector(knots);
00106     // delete control points from the control point mesh corresponding to just deleted knot
00107     control_points.erase(control_points.begin() + i - dimension_u);
00108     return 0;
00109
00110 }
00111
00112 int BSplineTensorSurface::deleteBezierKnot_V(double k)
00113 {
00114     DCTPdvector knots = basis_function_v.getKnotVector();
00115
00116     if(k >= knots[knots.size() - 1])
00117         return -1;                                 // knot is too high
00118     if(k <= knots[0])
00119         return -2;                  // knot is too low
00120
00121     DCTPdvector::size_type i    = 0;
00122     int                    mult = 0;
00123     while(knots[i] <= k)
00124     {
00125         if(knots[i] == k)
00126             mult++;
00127         i++;
00128     }
00129     if(mult < dimension_v + 1)
00130         return -3;                         // knot doesn't have enough multiplicity
00131     i--;
00132
00133     // delete from knotvector
00134     knots.erase(knots.begin() + i);
00135     // set new knot vector
00136     basis_function_v.setKnotVector(knots);
00137
00138     // delete control points from the control point mesh corresponding to just deleted knot
00139     for(DCTPVec4dvector::size_type j = 0; j < control_points.size(); j++)
00140     {
00141         control_points[j].erase(control_points[j].begin() + i - dimension_v);
00142     }
00143
00144     return 0;
00145 }
00146
00147
00148 //setup functions
00149 int BSplineTensorSurface::setKnotsAndDimension(const DCTPdvector& knots_u, int dim_u, const DCTPdvector& knots_v, int dim_v)
00150 {
00151     if(dim_u < 1 || dim_v < 1)
00152         return -1;                         //invalid dimension
00153
00154     DCTPdvector::size_type max_index = knots_u.size() - 1;
00155     if(max_index < 3)
00156         return -2;                //here's an implicit check fer structure, see below
00157     if(CheckKnotPoints(knots_u, dim_u) )
00158         return -3;
00159
00160     max_index = knots_v.size() - 1;
00161     if(max_index < 3)
00162         return -2;                //here's an implicit check fer structure, see below
00163     if(CheckKnotPoints(knots_v, dim_v) )
00164         return -3;
00165
00166     dimension_u = dim_u; dimension_v = dim_v;
00167     if(basis_function_u.setKnotVector(knots_u) )
00168         return -4;                                            //error in BSplineBasisFunction.setKno...
00169     if(basis_function_v.setKnotVector(knots_v) )
00170         return -4;                                            //error in BSplineBasisFunction.setKno...
00171
00172     return 0;
00173 }
00174
00175 void BSplineTensorSurface::setControlPointMatrix(const DCTPVec4dmatrix &cps)
00176 {
00177     // FIXME: check that this is really a matrix
00178     control_points = cps;
00179 }
00180
00181 void BSplineTensorSurface::getParameterInterval_U(double &minpar, double &maxpar)
00182 {
00183     basis_function_u.getParameterInterval(minpar, maxpar);
00184 }
00185
00186 void BSplineTensorSurface::getParameterInterval_V(double &minpar, double &maxpar)
00187 {
00188     basis_function_v.getParameterInterval(minpar, maxpar);
00189 }
00190
00191 //I/O facilities - FIXME: read( char *fname ), etc. missing
00193 
00199 int BSplineTensorSurface::read(std::istream &infile)
00200 {
00201     //FIXME: maybe we need more checks!!!
00202     char txtbuffer[256];
00203     bool israt = false;
00204
00205
00206     infile.getline(txtbuffer, 255);   //read line
00207     if(strcmp(txtbuffer, ff_const_1) &&
00208        strcmp(txtbuffer, ff_const_5))
00209     {
00210         return -1; //bad file format
00211     }
00212     if(!strcmp(txtbuffer, ff_const_5))
00213     {
00214         israt = true;
00215     }
00216
00217
00218     infile >> txtbuffer; //FIXME: error prone: too long string causes problem!!!
00219     if(strcmp(txtbuffer, ff_const_2) )
00220         return -1;                                     //yeah, bad file format again
00221     infile >> dimension_u >> std::ws;
00222     if(dimension_u < 1)
00223         return -2;                    //ah, bad dimension
00224
00225     infile >> txtbuffer; //FIXME: error prone: too long string causes problem!!!
00226     if(strcmp(txtbuffer, ff_const_3) )
00227         return -1;                                     //yeah, bad file format again
00228     infile >> dimension_v >> std::ws;
00229     if(dimension_v < 1)
00230         return -2;                    //ah, bad dimension
00231
00232
00233     if(basis_function_u.read(infile) )
00234         return -3;                                    //error reading basis function
00235     if(CheckKnotPoints(basis_function_u.getKnotVector(), dimension_u) )
00236         return -4;
00237     infile >> std::ws;
00238     if(basis_function_v.read(infile) )
00239         return -3;                                    //error reading basis function
00240     if(CheckKnotPoints(basis_function_v.getKnotVector(), dimension_v) )
00241         return -4;
00242     infile >> std::ws;
00243
00244     infile >> txtbuffer; //FIXME: error prone: too long string causes problem!!!
00245     if(strcmp(txtbuffer, ff_const_4) )
00246         return -1;                                    //bad file format once again
00247
00248     DCTPVec4dmatrix::size_type num_of_cps_u;
00249     DCTPVec4dvector::size_type num_of_cps_v;
00250     infile >> num_of_cps_u >> num_of_cps_v >> std::ws;
00251     if(num_of_cps_u < 1 || num_of_cps_v < 1)
00252         return -5;                                         //too few control points
00253     control_points.resize(num_of_cps_u);   //FIXME: whatif not enoght memory?
00254
00255     for(DCTPdvector::size_type u = 0; u < num_of_cps_u; ++u)
00256     {
00257         control_points[u].resize(num_of_cps_v);      //FIXME: not enough mem, exception thrown by STL
00258
00259         for(DCTPdvector::size_type v = 0; v < num_of_cps_v; ++v)
00260         {
00261             Vec4d cp;
00262             if(israt)
00263             {
00264                 infile >> cp[0] >> cp[1] >> cp[2] >> cp[3] >> std::ws;
00265             }
00266             else
00267             {
00268                 infile >> cp[0] >> cp[1] >> cp[2] >> std::ws;
00269                 cp[3] = 1.0;
00270             }
00271             control_points[u][v] = cp;     //FIXME: ya see, we need ERROR CHECKS!!!
00272         }
00273     }
00274
00275     return 0;
00276 }
00277
00279
00285 int BSplineTensorSurface::write(std::ostream &outfile)
00286 {
00287     bool                       israt = false;
00288     DCTPdvector::size_type     u, v;
00289     DCTPVec4dmatrix::size_type num_of_cps_u = control_points.size();
00290     DCTPVec4dvector::size_type num_of_cps_v = control_points[0].size(); //FIXME:what if it's not initialized yet
00291
00292     for(u = 0; u < num_of_cps_u; ++u)
00293     {
00294         for(v = 0; v < num_of_cps_v; ++v)
00295         {
00296             if(osgAbs(control_points[u][v][3] - 1.0) > DCTP_EPS)
00297             {
00298                 israt = true;
00299                 break;
00300             }
00301         }
00302     }
00303
00304     //FIXME: maybe we need more checks!!!
00305     outfile.precision(DCTP_PRECISION);
00306     if(!israt)
00307     {
00308         outfile << ff_const_1 << std::endl;
00309     }
00310     else
00311     {
00312         outfile << ff_const_5 << std::endl;
00313     }
00314     outfile << ff_const_2 << " " << dimension_u << std::endl;
00315     outfile << ff_const_3 << " " << dimension_v << std::endl;
00316     basis_function_u.write(outfile);
00317     basis_function_v.write(outfile);
00318     outfile << ff_const_4 << " " << num_of_cps_u << " " << num_of_cps_v << std::endl;
00319
00320     for(u = 0; u < num_of_cps_u; ++u)
00321     {
00322         for(v = 0; v < num_of_cps_v; ++v)
00323         {
00324             Vec4d cp = control_points[u][v];
00325             if(!israt)
00326             {
00327                 outfile << cp[0] << " " << cp[1] << " " << cp[2] << std::endl;
00328             }
00329             else
00330             {
00331                 outfile << cp[0] << " " << cp[1] << " " << cp[2] << " " << cp[3] << std::endl;
00332             }
00333         }
00334     }
00335
00336     return 0;
00337 }
00338
00339
00341
00350 Vec4d BSplineTensorSurface::compute4D(Vec2d uv, int &error)
00351 {
00352     //FIXME: verification before goin' into computation!!
00353     double *nu;
00354     int     span_u = basis_function_u.computeAllNonzero(uv[0], dimension_u, nu);
00355     double *nv;
00356     int     span_v = basis_function_v.computeAllNonzero(uv[1], dimension_v, nv);
00357
00358     Vec4d result(0.0, 0.0, 0.0, 0.0);
00359     if(span_u < 0 || span_v < 0)
00360     {
00361         std::cerr << "spanu: " << span_u << " spanv: " << span_v << std::endl;
00362         error = (span_u < 0) ? span_u : span_v;
00363         if(span_u >= 0)
00364             delete[]  nu;
00365         if(span_v >= 0)
00366             delete[]  nv;
00367         result[3] = 1.0;
00368         return result; //error occured in BSplineBasisFunction.computeAll...
00369     }
00370
00371     unsigned int index_v = span_v - dimension_v;
00372     Vec4d        temp;
00373     unsigned int index_u;
00374
00375     for(int l = 0; l <= dimension_v; ++l)
00376     {
00377         temp[0] = temp[1] = temp[2] = temp[3] = 0.0;
00378         index_u = span_u - dimension_u;
00379
00380         for(DCTPVec4dmatrix::size_type k = 0; k <= static_cast<unsigned int>(dimension_u); ++k)
00381         {
00382             temp += control_points[index_u][index_v] * nu[k];
00383             ++index_u;
00384         }
00385
00386         ++index_v;
00387         result += temp * nv[l];
00388     }
00389
00390     delete[]  nu;
00391     delete[]  nv;
00392
00393     return (result);
00394 }
00395
00396 Vec3d BSplineTensorSurface::compute(Vec2d uv, int &error)
00397 {
00398     Vec4d rat_res;
00399     Vec3d res;
00400
00401     rat_res = compute4D(uv, error);
00402     res[0]  = rat_res[0] / rat_res[3];
00403     res[1]  = rat_res[1] / rat_res[3];
00404     res[2]  = rat_res[2] / rat_res[3];
00405     return res;
00406 }
00407
00408 void BSplineTensorSurface::RatSurfaceDerivs(DCTPVec4dmatrix &rclHomDerivs, DCTPVec3dmatrix &rclEuclidDerivs)
00409 {
00410     unsigned int ui_k, ui_l, ui_j, ui_i;
00411     Vec3d        cl_v, cl_v2;
00412
00413     // FIXME: optimize for special case clHomDervis.size()==2!
00414     // FIXME: binomial coefficients are all 1 in this case, so alredy removed
00415
00416     for(ui_k = 0; ui_k < rclHomDerivs.size(); ++ui_k)
00417     {
00418         for(ui_l = 0; ui_l < rclHomDerivs.size() - ui_k; ++ui_l)
00419         {
00420             cl_v[0] = rclHomDerivs[ui_k][ui_l][0];
00421             cl_v[1] = rclHomDerivs[ui_k][ui_l][1];
00422             cl_v[2] = rclHomDerivs[ui_k][ui_l][2];
00423
00424             for(ui_j = 1; ui_j <= ui_l; ++ui_j)
00425             {
00426                 //cl_v -= Binomial(ui_l, ui_j) * rclHomDerivs[0][ui_j][3] * rclEuclidDerivs[ui_k][ui_l-ui_j];
00427                 cl_v -= rclHomDerivs[0][ui_j][3] * rclEuclidDerivs[ui_k][ui_l - ui_j];
00428             }
00429
00430             for(ui_i = 1; ui_i <= ui_k; ++ui_i)
00431             {
00432                 //cl_v -= Binomial(ui_k, ui_i) * rclHomDerivs[ui_i][0][3] * rclEuclidDerivs[ui_k-ui_i][ui_l];
00433                 cl_v -= rclHomDerivs[ui_i][0][3] * rclEuclidDerivs[ui_k - ui_i][ui_l];
00434                 cl_v2 = Vec3d(0.0, 0.0, 0.0);
00435
00436                 for(ui_j = 1; ui_j <= ui_l; ++ui_j)
00437                 {
00438                     //cl_v2 += Binomial(ui_l, ui_j) * rclHomDerivs[ui_i][ui_j][3] * rclEuclidDerivs[ui_k-ui_i][ui_l-ui_j];
00439                     cl_v2 += rclHomDerivs[ui_i][ui_j][3] * rclEuclidDerivs[ui_k - ui_i][ui_l - ui_j];
00440                 }
00441
00442 //                cl_v -= Binomial(ui_k, ui_i) * cl_v2;
00443                 cl_v -= cl_v2;
00444             }
00445
00446             rclEuclidDerivs[ui_k][ui_l] = cl_v * (1.0 / rclHomDerivs[0][0][3]);
00447         }
00448     }
00449 }
00450
00451
00453
00462 Vec3f BSplineTensorSurface::computeNormal(Vec2d clUV, int &riError, Pnt3f &rclPos)
00463 {
00464     Vec3d cl_norm;
00465     Vec3d cl_pos;
00466     Vec3f cl_normal;
00467
00468     cl_norm      = computeNormal(clUV, riError, cl_pos);
00469     cl_normal[0] = static_cast<Real32>(cl_norm[0]);
00470     cl_normal[1] = static_cast<Real32>(cl_norm[1]);
00471     cl_normal[2] = static_cast<Real32>(cl_norm[2]);
00472     rclPos[0]    = static_cast<Real32>(cl_pos[0]);
00473     rclPos[1]    = static_cast<Real32>(cl_pos[1]);
00474     rclPos[2]    = static_cast<Real32>(cl_pos[2]);
00475
00476     return cl_normal;
00477 }
00478
00479
00480 Vec3d BSplineTensorSurface::computeNormal(Vec2d clUV, int &riError, Vec3d &rclPos)
00481 {
00482     int             i_uspan;
00483     int             i_vspan;
00484     double        **ppd_nu;
00485     double        **ppd_nv;
00486     Vec3d           cl_temp;
00487     Vec3d           cl_normal;
00488     int             i_k;
00489     int             i_s;
00490     int             i_l;
00491     DCTPVec4dmatrix vvcl_skl;
00492     DCTPVec3dmatrix vvcl_skl_eucl;
00493     Vec4d          *pcl_temp;
00494     int             i_r;
00495     double          d_len;
00496     int             i_u;
00497     int             i_v;
00498
00499     vvcl_skl.resize(2);
00500     vvcl_skl[0].resize(2);
00501     vvcl_skl[1].resize(2);
00502     vvcl_skl_eucl.resize(2);
00503     vvcl_skl_eucl[0].resize(2);
00504     vvcl_skl_eucl[1].resize(2);
00505
00506     i_uspan = basis_function_u.computeDersBasisFuns(clUV[0], dimension_u, ppd_nu, 1);
00507     i_vspan = basis_function_v.computeDersBasisFuns(clUV[1], dimension_v, ppd_nv, 1);
00508     if( (i_uspan < 0) || (i_vspan < 0) )
00509     {
00510         riError = -1;
00511         return cl_normal;
00512     }
00513
00514 //  vvcl_skl.resize( 2 );
00515 //  vvcl_skl[ 0 ].resize( 2 );
00516 //  vvcl_skl[ 1 ].resize( 2 );
00517     pcl_temp = new Vec4d[dimension_v + 1];
00518 //  vcl_temp.resize( dimension_v + 1 );
00519
00520     for(i_k = 0; i_k <= 1; ++i_k)
00521     {
00522         i_v = i_vspan - dimension_v;
00523
00524         for(i_s = 0; i_s <= dimension_v; ++i_s)
00525         {
00526             pcl_temp[i_s] = Vec4d(0.0, 0.0, 0.0, 0.0);
00527             i_u           = i_uspan - dimension_u;
00528
00529             for(i_r = 0; i_r <= dimension_u; ++i_r)
00530             {
00531                 pcl_temp[i_s] += control_points[i_u][i_v] * ppd_nu[i_k][i_r];
00532                 ++i_u;
00533             }
00534
00535             ++i_v;
00536         }
00537
00538         for(i_l = 0; i_l <= 1 - i_k; ++i_l)
00539         {
00540             vvcl_skl[i_k][i_l] = Vec4d(0.0, 0.0, 0.0, 0.0);
00541
00542             for(i_s = 0; i_s <= dimension_v; ++i_s)
00543             {
00544                 vvcl_skl[i_k][i_l] += pcl_temp[i_s] * ppd_nv[i_l][i_s];
00545             }
00546         }
00547     }
00548
00549     RatSurfaceDerivs(vvcl_skl, vvcl_skl_eucl);
00550     correctDers(clUV, vvcl_skl_eucl[0][0], vvcl_skl_eucl[1][0], vvcl_skl_eucl[0][1]);
00551     cl_temp = vvcl_skl_eucl[1][0].cross(vvcl_skl_eucl[0][1]);
00552     d_len   = cl_temp.squareLength();
00553     if(d_len < DCTP_EPS * DCTP_EPS)
00554     {
00555 //        std::cerr<<"d_len too small: " << d_len << std::endl;
00556         cl_normal[0] = cl_normal[1] = cl_normal[2] = 0.0;
00557         riError      = -2;
00558     }
00559     else
00560     {
00561         cl_temp     *= 1.0 / sqrt(d_len);
00562         riError      = 0;
00563         cl_normal[0] = cl_temp[0];
00564         cl_normal[1] = cl_temp[1];
00565         cl_normal[2] = cl_temp[2];
00566     }
00567
00568     rclPos[0] = vvcl_skl_eucl[0][0][0];
00569     rclPos[1] = vvcl_skl_eucl[0][0][1];
00570     rclPos[2] = vvcl_skl_eucl[0][0][2];
00571
00572     // clean up allocated memory
00573     delete[]  ppd_nu[0];
00574     delete[]  ppd_nu[1];
00575     delete[]  ppd_nv[0];
00576     delete[]  ppd_nv[1];
00577     delete[]  ppd_nu;
00578     delete[]  ppd_nv;
00579     delete[]  pcl_temp;
00580
00581     return cl_normal;
00582 }
00583
00584
00586
00595 Vec3d BSplineTensorSurface::computeNormalTex(Vec2d &                                 rclUV,
00596                                              int &                                   riError,
00597                                              Vec3d &                                 rclPos,
00598                                              Vec2d &                                 rclTexCoord,
00599                                              const std::vector<std::vector<Pnt2f> > *cpvvclTexCP)
00600 {
00601     int             i_uspan;
00602     int             i_vspan;
00603     double        **ppd_nu;
00604     double        **ppd_nv;
00605     Vec3d           cl_normal;
00606     int             i_k;
00607     int             i_s;
00608     int             i_l;
00609     DCTPVec4dmatrix vvcl_skl;
00610     DCTPVec3dmatrix vvcl_skl_eucl;
00611     Vec4d          *pcl_temp;
00612     int             i_r;
00613     double          d_len;
00614     int             i_u;
00615     int             i_v;
00616     double         *pd_nvl;
00617     double         *pd_nuk;
00618     Vec2d           cl_temp;
00619
00620     vvcl_skl.resize(2);
00621     vvcl_skl[0].resize(2);
00622     vvcl_skl[1].resize(2);
00623     vvcl_skl_eucl.resize(2);
00624     vvcl_skl_eucl[0].resize(2);
00625     vvcl_skl_eucl[1].resize(2);
00626
00627     i_uspan = basis_function_u.computeDersBasisFuns(rclUV[0], dimension_u, ppd_nu, 1);
00628     i_vspan = basis_function_v.computeDersBasisFuns(rclUV[1], dimension_v, ppd_nv, 1);
00629     if( (i_uspan < 0) || (i_vspan < 0) )
00630     {
00631         riError = -1;
00632         return cl_normal;
00633     }
00634
00635 //  vvcl_skl.resize( 2 );
00636 //  vvcl_skl[ 0 ].resize( 2 );
00637 //  vvcl_skl[ 1 ].resize( 2 );
00638     pcl_temp = new Vec4d[dimension_v + 1];
00639 //  vcl_temp.resize( dimension_v + 1 );
00640
00641     for(i_k = 0; i_k <= 1; ++i_k)
00642     {
00643         i_v = i_vspan - dimension_v;
00644
00645         for(i_s = 0; i_s <= dimension_v; ++i_s)
00646         {
00647             pcl_temp[i_s] = Vec4d(0.0, 0.0, 0.0, 0.0);
00648             i_u           = i_uspan - dimension_u;
00649
00650             for(i_r = 0; i_r <= dimension_u; ++i_r)
00651             {
00652                 pcl_temp[i_s] += control_points[i_u][i_v] * ppd_nu[i_k][i_r];
00653                 ++i_u;
00654             }
00655
00656             ++i_v;
00657         }
00658
00659         for(i_l = 0; i_l <= 1 - i_k; ++i_l)
00660         {
00661             vvcl_skl[i_k][i_l] = Vec4d(0.0, 0.0, 0.0, 0.0);
00662
00663             for(i_s = 0; i_s <= dimension_v; ++i_s)
00664             {
00665                 vvcl_skl[i_k][i_l] += pcl_temp[i_s] * ppd_nv[i_l][i_s];
00666             }
00667         }
00668     }
00669
00670     RatSurfaceDerivs(vvcl_skl, vvcl_skl_eucl);
00671     rclPos = vvcl_skl_eucl[0][0];
00672
00673     correctDers(rclUV, vvcl_skl_eucl[0][0], vvcl_skl_eucl[1][0], vvcl_skl_eucl[0][1]);
00674     cl_normal = vvcl_skl_eucl[1][0].cross(vvcl_skl_eucl[0][1]);
00675     d_len     = cl_normal.squareLength();
00676
00677     if(d_len < DCTP_EPS * DCTP_EPS)
00678     {
00679         cl_normal[0] = cl_normal[1] = cl_normal[2] = 0.0;
00680         riError      = -2;
00681     }
00682     else
00683     {
00684         cl_normal *= 1.0 / sqrt(d_len);
00685         riError    = 0;
00686     }
00687
00688     // calculate texture coord
00689     rclTexCoord[0] = rclTexCoord[1] = 0.0;
00690     i_v            = i_vspan - dimension_v;
00691     pd_nvl         = ppd_nv[0];
00692
00693     for(i_l = 0; i_l <= dimension_v; ++i_l)
00694     {
00695         cl_temp[0] = cl_temp[1] = 0.0;
00696         i_u        = i_uspan - dimension_u;
00697         pd_nuk     = ppd_nu[0];
00698
00699         for(i_k = 0; i_k <= dimension_u; ++i_k)
00700         {
00701             cl_temp[0] += (*cpvvclTexCP)[i_u][i_v].x() * *pd_nuk;
00702             cl_temp[1] += (*cpvvclTexCP)[i_u][i_v].y() * *pd_nuk;
00703             ++i_u;
00704             ++pd_nuk;
00705         }
00706
00707         ++i_v;
00708         rclTexCoord += cl_temp * *pd_nvl;
00709         ++pd_nvl;
00710     }
00711
00712     // clean up allocated memory
00713     delete[]  ppd_nu[0];
00714     delete[]  ppd_nu[1];
00715     delete[]  ppd_nv[0];
00716     delete[]  ppd_nv[1];
00717     delete[]  ppd_nu;
00718     delete[]  ppd_nv;
00719     delete[]  pcl_temp;
00720
00721     return cl_normal;
00722 }
00723
00724
00726
00732 int BSplineTensorSurface::insertKnot_U(double k)
00733 {
00734     DCTPdvector knots = basis_function_u.getKnotVector();
00735     int         span  = basis_function_u.insertKnot(k);
00736     if(span < 0)
00737         return span;             // some error happened
00738
00739     DCTPVec4dmatrix            newcps(control_points.size() + 1);
00740     DCTPVec4dvector::size_type i;
00741
00742     for(i = 0; i < newcps.size(); i++)
00743     {
00744         newcps[i].resize(control_points[0].size() );      // this must be 0 (or at least < newcps.size() - 1
00745     }
00746
00747     for(i = 0; int(i) <= span - dimension_u; i++)
00748         newcps[i] = control_points[i];
00749
00750     for(i = span - dimension_u + 1; i <= static_cast<unsigned int>(span); i++)
00751     {
00752         double alpha;
00753         if(knots[i + dimension_u] != knots[i])
00754             alpha = (k - knots[i]) / (knots[i + dimension_u] - knots[i]);
00755         else
00756             alpha = 0;
00757
00758         for(DCTPVec4dvector::size_type j = 0; j < newcps[i].size(); j++)
00759         {
00760             newcps[i][j] = control_points[i][j] * alpha +
00761                            control_points[i - 1][j] * (1 - alpha);
00762         } // j
00763
00764     } // i
00765
00766     for(i = span + 1; i < newcps.size(); i++)
00767     {
00768         newcps[i] = control_points[i - 1];
00769     }
00770
00771     control_points = newcps;
00772     return span;
00773 }
00774
00775
00777
00783 int BSplineTensorSurface::insertKnot_V(double k)
00784 {
00785     DCTPdvector knots = basis_function_v.getKnotVector();
00786     int         span  = basis_function_v.insertKnot(k);
00787     if(span < 0)
00788         return span;             // some error happened
00789     DCTPVec4dmatrix            newcps(control_points.size() );
00790     DCTPVec4dvector::size_type i, j;
00791
00792     for(i = 0; i < newcps.size(); i++)
00793         newcps[i].resize(control_points[i].size() + 1);
00794
00795     for(i = 0; i < control_points.size(); i++)
00796         for(j = 0; int(j) <= span - dimension_v; j++)
00797             newcps[i][j] = control_points[i][j];
00798
00799     // precalculate alpha values
00800     DCTPdvector alphavec(dimension_v);
00801
00802     for(j = span - dimension_v + 1; int(j) <= span; j++)
00803     {
00804         if(knots[j + dimension_v] != knots[j])
00805             alphavec[j - span + dimension_v - 1] = (k - knots[j]) / (knots[j + dimension_v] - knots[j]);
00806         else
00807             alphavec[j - span + dimension_v - 1] = 0;
00808     }
00809
00810     for(i = 0; i < control_points.size(); i++)
00811         for(j = span - dimension_v + 1; int(j) <= span; j++)
00812         {
00813             double alpha = alphavec[j - span + dimension_v - 1];
00814             newcps[i][j] = control_points[i][j] * alpha + control_points[i][j - 1] * (1 - alpha);
00815         }
00816
00817     // j
00818
00819     for(i = 0; i < control_points.size(); i++)
00820         for(j = span + 1; j < newcps[i].size(); j++)
00821             newcps[i][j] = control_points[i][j - 1];
00822
00823     control_points = newcps;
00824     return span;
00825 }
00826
00828
00843 int BSplineTensorSurface::makeBezier(beziersurfacematrix &beziers, DCTPdvector &upars, DCTPdvector &vpars)
00844 {
00845     double firstknotu, lastknotu;
00846     double firstknotv, lastknotv;
00847     basis_function_u.getParameterInterval(firstknotu, lastknotu);
00848     basis_function_v.getParameterInterval(firstknotv, lastknotv);
00849     DCTPdvector     uknots     = basis_function_u.getKnotVector();
00850     DCTPdvector     vknots     = basis_function_v.getKnotVector();
00851     DCTPdvector     origuknots = uknots; // backup original curve characteristics
00852     DCTPdvector     origvknots = vknots; // same here
00853     DCTPVec4dmatrix origcps    = control_points; // same here
00854     double          prevknot   = firstknotu;
00855     int             mult       = 0;
00856     int             err;
00857     int             i;
00858
00859     // first convert along u knots
00860     for(i = 1; i < int(uknots.size()); i++)
00861     {
00862         double actk = uknots[i];
00863         if(actk == prevknot)
00864             mult++;
00865         else
00866         {
00867             for(int j = mult + 1; j < dimension_u; j++) //each interior knot must have the multiplicity of dimension -1
00868             { //std::cerr << "about to insert uknot: " << prevknot << std::endl;
00869                 err = insertKnot_U(prevknot);
00870                 //std::cerr << "inserted uknot..." << std::endl;
00871                 if(err < 0)
00872                     return err;         // some error happened during insertKnot
00873                 err = 0;
00874             }
00875
00876             if(prevknot != firstknotu && prevknot != lastknotu)
00877             {
00878                 for(int j = mult; j > dimension_u - 1; j--)
00879                 {
00880                     //std::cerr << "about to delete knot: " << prevknot << std::endl;
00881                     err = deleteBezierKnot_U(prevknot);
00882                     //std::cerr << "deleted knot..." << std::endl;
00883                     if(err)
00884                         return err;     // some error happened during deleteBezierKnot
00885                 }
00886             }
00887             mult = 0;
00888         }
00889         prevknot = actk;
00890     }
00891
00892     // now convert along v knots
00893     mult     = 0;
00894     prevknot = firstknotv;
00895
00896     for(i = 1; i < int(vknots.size()); i++)
00897     {
00898         double actk = vknots[i];
00899         if(actk == prevknot)
00900             mult++;
00901         else
00902         {
00903             for(int j = mult + 1; j < dimension_v; j++) //each interior knot must have the multiplicity of dimension -1
00904             { //        std::cerr << "about to insert vknot: " << prevknot << std::endl;
00905                 err = insertKnot_V(prevknot);
00906 //        std::cerr << "inserted vknot..." << std::endl;
00907                 if(err < 0)
00908                     return err;         // some error happened during insertKnot
00909                 err = 0;
00910             }
00911
00912             if(prevknot != firstknotv && prevknot != lastknotv)
00913             {
00914                 for(int j = mult; j > dimension_v - 1; j--)
00915                 {
00916 //          std::cerr << "about to delete knot: " << prevknot << std::endl;
00917                     err = deleteBezierKnot_V(prevknot);
00918 //          std::cerr << "deleted knot..." << std::endl;
00919                     if(err)
00920                         return err;     // some error happened during deleteBezierKnot
00921                 }
00922             }
00923             mult = 0;
00924         }
00925         prevknot = actk;
00926     }
00927
00928     // now do the actual conversation into nxm bezier segments
00929     uknots = basis_function_u.getKnotVector(); // FIXME: it could be more efficient.
00930     int unum_of_beziers = (uknots.size() - 2) / dimension_u - 1;
00931     if( (unum_of_beziers * dimension_u + 2) != int(uknots.size()) - dimension_u)
00932     {
00933         basis_function_u.setKnotVector(origuknots);
00934         basis_function_v.setKnotVector(origuknots);
00935         control_points = origcps;
00936         return -5;
00937     }
00938     vknots = basis_function_v.getKnotVector(); // FIXME: it could be more efficient.
00939     int vnum_of_beziers = (vknots.size() - 2) / dimension_v - 1;
00940     if( (vnum_of_beziers * dimension_v + 2) != int(vknots.size()) - dimension_v)
00941     {
00942         basis_function_u.setKnotVector(origuknots);
00943         basis_function_v.setKnotVector(origuknots);
00944         control_points = origcps;
00945         return -5;
00946     }
00947
00948     beziers.resize(unum_of_beziers);
00949     upars.resize(unum_of_beziers + 1);
00950     vpars.resize(vnum_of_beziers + 1);
00951
00952     for(i = 0; i < unum_of_beziers + 1; i++)
00953         upars[i] = uknots[1 + dimension_u * i];
00954
00955     for(i = 0; i < vnum_of_beziers + 1; i++)
00956         vpars[i] = vknots[1 + dimension_v * i];
00957
00958     for(i = 0; i < unum_of_beziers; i++)
00959         beziers[i].resize(vnum_of_beziers);
00960
00961     DCTPVec4dmatrix beziercps(dimension_u + 1);
00962
00963     for(i = 0; i < dimension_u + 1; i++)
00964         beziercps[i].resize(dimension_v + 1);
00965
00966     for(i = 0; i < unum_of_beziers; i++)
00967     {
00968         for(int j = 0; j < vnum_of_beziers; j++)
00969         {
00970             for(int u = 0; u < dimension_u + 1; u++)
00971             {
00972                 for(int v = 0; v < dimension_v + 1; v++)
00973                 {
00974                     beziercps[u][v] = control_points[i * dimension_u + u][j * dimension_v + v];
00975                 } // v
00976
00977             } // u
00978
00979             beziers[i][j].setControlPointMatrix(beziercps);
00980         } // j
00981
00982     } // i
00983
00984     // restore original curve
00985     basis_function_u.setKnotVector(origuknots);
00986     basis_function_v.setKnotVector(origvknots);
00987     control_points = origcps;
00988     return 0;
00989
00990 }
00991
00992
00993 int BSplineTensorSurface::getSplitParams(DCTPdvector &upars, DCTPdvector &vpars)
00994 {
00995     DCTPdvector &uknots          = basis_function_u.getKnotVector();
00996     DCTPdvector &vknots          = basis_function_v.getKnotVector();
00997     int          unum_of_beziers = (uknots.size() - 2) / dimension_u - 1;
00998     int          vnum_of_beziers = (vknots.size() - 2) / dimension_v - 1;
00999     int          i;
01000
01001     upars.resize(unum_of_beziers + 1);
01002     vpars.resize(vnum_of_beziers + 1);
01003
01004     for(i = 0; i < unum_of_beziers + 1; i++)
01005         upars[i] = uknots[1 + dimension_u * i];
01006
01007     for(i = 0; i < vnum_of_beziers + 1; i++)
01008         vpars[i] = vknots[1 + dimension_v * i];
01009
01010     return 0;
01011 }
01012
01013
01014
01015 // subdivide surface at midpoint into 4 bezier surfaces
01016 int BSplineTensorSurface::midPointSubDivision(std::vector<std::vector<BSplineTensorSurface> > &rvvcl_newbspline)
01017 {
01018     double                           d_min;
01019     double                           d_max;
01020     int                              ui_cnt;
01021     int                              ui_idx;
01022     int                              i_span = 0;
01023     std::vector<std::vector<Vec4d> > vvcl_cp;
01024     unsigned int                     ui_cpy;
01025     unsigned int                     ui_cpy_cnt;
01026
01027     rvvcl_newbspline.resize(2);
01028     rvvcl_newbspline[0].resize(2);
01029     rvvcl_newbspline[1].resize(2);
01030
01031     // insert knots in u direction
01032     rvvcl_newbspline[0][0] = *this;
01033     rvvcl_newbspline[0][0].getParameterInterval_U(d_min, d_max);
01034     ui_cnt = rvvcl_newbspline[0][0].getDimension_U();
01035
01036     for(ui_idx = 0; ui_idx < ui_cnt; ++ui_idx)
01037     {
01038         i_span = rvvcl_newbspline[0][0].insertKnot_U( (d_min + d_max) * 0.5);
01039     }
01040
01041     i_span                            -= dimension_u - 2;
01042     rvvcl_newbspline[0][1].dimension_u = dimension_u;
01043     rvvcl_newbspline[1][0].dimension_u = dimension_u;
01044     rvvcl_newbspline[1][1].dimension_u = dimension_u;
01045     rvvcl_newbspline[0][1].dimension_v = dimension_v;
01046     rvvcl_newbspline[1][0].dimension_v = dimension_v;
01047     rvvcl_newbspline[1][1].dimension_v = dimension_v;
01048
01049     // split in u direction
01050     ui_cnt = rvvcl_newbspline[0][0].getControlPointMatrix().size();
01051
01052     for(ui_idx = 0; ui_idx <= dimension_u; ++ui_idx)
01053     {
01054         rvvcl_newbspline[1][0].getKnotVector_U().push_back(
01055             rvvcl_newbspline[0][0].getKnotVector_U()[i_span]);
01056     }
01057
01058     for(ui_idx = i_span - 1; ui_idx < ui_cnt; ++ui_idx)
01059     {
01060         rvvcl_newbspline[1][0].getControlPointMatrix().push_back(
01061             rvvcl_newbspline[0][0].getControlPointMatrix()[ui_idx]);
01062         rvvcl_newbspline[1][0].getKnotVector_U().push_back(
01063             rvvcl_newbspline[0][0].getKnotVector_U()[ui_idx + dimension_u + 1]);
01064     }
01065
01066     rvvcl_newbspline[0][0].getControlPointMatrix().resize(i_span);
01067     rvvcl_newbspline[0][0].getKnotVector_U().resize(i_span + dimension_u);
01068     rvvcl_newbspline[0][0].getKnotVector_U().push_back(
01069         rvvcl_newbspline[0][0].getKnotVector_U()[i_span + dimension_u - 1]);
01070     rvvcl_newbspline[1][0].getKnotVector_V() = rvvcl_newbspline[0][0].getKnotVector_V();
01071
01072     ui_cnt = rvvcl_newbspline[0][0].getKnotVector_U().size() - 1;
01073     ui_idx = ui_cnt - dimension_u - 1;
01074     while(rvvcl_newbspline[0][0].getKnotVector_U()[ui_cnt] == rvvcl_newbspline[0][0].getKnotVector_U()[ui_idx])
01075     {
01076         rvvcl_newbspline[0][0].getKnotVector_U().pop_back();
01077         rvvcl_newbspline[0][0].getControlPointMatrix().pop_back();
01078         --ui_cnt;
01079         --ui_idx;
01080     }
01081
01082     // insert knots in v direction
01083     rvvcl_newbspline[0][0].getParameterInterval_V(d_min, d_max);
01084     ui_cnt = rvvcl_newbspline[0][0].getDimension_V();
01085
01086     for(ui_idx = 0; ui_idx < ui_cnt; ++ui_idx)
01087     {
01088         i_span = rvvcl_newbspline[0][0].insertKnot_V( (d_min + d_max) * 0.5);
01089         i_span = rvvcl_newbspline[1][0].insertKnot_V( (d_min + d_max) * 0.5);
01090     }
01091
01092     i_span -= dimension_v - 2;
01093
01094     // split in v direction
01095     ui_cnt = rvvcl_newbspline[0][0].getControlPointMatrix()[0].size();
01096
01097     for(ui_idx = 0; ui_idx <= dimension_v; ++ui_idx)
01098     {
01099         rvvcl_newbspline[0][1].getKnotVector_V().push_back(
01100             rvvcl_newbspline[0][0].getKnotVector_V()[i_span]);
01101         rvvcl_newbspline[1][1].getKnotVector_V().push_back(
01102             rvvcl_newbspline[1][0].getKnotVector_V()[i_span]);
01103     }
01104
01105     for(ui_idx = i_span - 1; ui_idx < ui_cnt; ++ui_idx)
01106     {
01107         ui_cpy_cnt = rvvcl_newbspline[0][0].getControlPointMatrix().size();
01108         rvvcl_newbspline[0][1].getControlPointMatrix().resize(ui_cpy_cnt);
01109
01110         for(ui_cpy = 0; ui_cpy < ui_cpy_cnt; ++ui_cpy)
01111         {
01112             rvvcl_newbspline[0][1].getControlPointMatrix()[ui_cpy].push_back(
01113                 rvvcl_newbspline[0][0].getControlPointMatrix()[ui_cpy][ui_idx]);
01114         }
01115
01116         ui_cpy_cnt = rvvcl_newbspline[1][0].getControlPointMatrix().size();
01117         rvvcl_newbspline[1][1].getControlPointMatrix().resize(ui_cpy_cnt);
01118
01119         for(ui_cpy = 0; ui_cpy < ui_cpy_cnt; ++ui_cpy)
01120         {
01121             rvvcl_newbspline[1][1].getControlPointMatrix()[ui_cpy].push_back(
01122                 rvvcl_newbspline[1][0].getControlPointMatrix()[ui_cpy][ui_idx]);
01123         }
01124
01125         rvvcl_newbspline[0][1].getKnotVector_V().push_back(
01126             rvvcl_newbspline[0][0].getKnotVector_V()[ui_idx + dimension_v + 1]);
01127         rvvcl_newbspline[1][1].getKnotVector_V().push_back(
01128             rvvcl_newbspline[1][0].getKnotVector_V()[ui_idx + dimension_v + 1]);
01129     }
01130
01131     ui_cnt = rvvcl_newbspline[0][0].getControlPointMatrix().size();
01132
01133     for(ui_idx = 0; ui_idx < ui_cnt; ++ui_idx)
01134     {
01135         rvvcl_newbspline[0][0].getControlPointMatrix()[ui_idx].resize(i_span);
01136     }
01137
01138     ui_cnt = rvvcl_newbspline[1][0].getControlPointMatrix().size();
01139
01140     for(ui_idx = 0; ui_idx < ui_cnt; ++ui_idx)
01141     {
01142         rvvcl_newbspline[1][0].getControlPointMatrix()[ui_idx].resize(i_span);
01143     }
01144
01145     rvvcl_newbspline[0][0].getKnotVector_V().resize(i_span + dimension_v);
01146     rvvcl_newbspline[0][0].getKnotVector_V().push_back(
01147         rvvcl_newbspline[0][0].getKnotVector_V()[i_span + dimension_v - 1]);
01148     rvvcl_newbspline[1][0].getKnotVector_V().resize(i_span + dimension_v);
01149     rvvcl_newbspline[1][0].getKnotVector_V().push_back(
01150         rvvcl_newbspline[1][0].getKnotVector_V()[i_span + dimension_v - 1]);
01151     rvvcl_newbspline[0][1].getKnotVector_U() = rvvcl_newbspline[0][0].getKnotVector_U();
01152     rvvcl_newbspline[1][1].getKnotVector_U() = rvvcl_newbspline[1][0].getKnotVector_U();
01153
01154     ui_cnt = rvvcl_newbspline[0][0].getKnotVector_V().size() - 1;
01155     ui_idx = ui_cnt - dimension_v - 1;
01156     while(rvvcl_newbspline[0][0].getKnotVector_V()[ui_cnt] == rvvcl_newbspline[0][0].getKnotVector_V()[ui_idx])
01157     {
01158         rvvcl_newbspline[0][0].getKnotVector_V().pop_back();
01159         ui_cpy_cnt = rvvcl_newbspline[0][0].getControlPointMatrix().size();
01160
01161         for(ui_cpy = 0; ui_cpy < ui_cpy_cnt; ++ui_cpy)
01162         {
01163             rvvcl_newbspline[0][0].getControlPointMatrix()[ui_cpy].pop_back();
01164         }
01165
01166         rvvcl_newbspline[1][0].getKnotVector_V().pop_back();
01167         ui_cpy_cnt = rvvcl_newbspline[1][0].getControlPointMatrix().size();
01168
01169         for(ui_cpy = 0; ui_cpy < ui_cpy_cnt; ++ui_cpy)
01170         {
01171             rvvcl_newbspline[1][0].getControlPointMatrix()[ui_cpy].pop_back();
01172         }
01173
01174         --ui_cnt;
01175         --ui_idx;
01176     }
01177
01178     return 0;
01179 }
01180
01181
01182 // subdivide surface at midpoint into 2 bezier surfaces
01183 int BSplineTensorSurface::midPointSubDivisionU(std::vector<BSplineTensorSurface> &rvcl_newbspline)
01184 {
01185     double                           d_min;
01186     double                           d_max;
01187     int                              ui_cnt;
01188     int                              ui_idx;
01189     int                              i_span = 0;
01190     std::vector<std::vector<Vec4d> > vvcl_cp;
01191 //    unsigned int                     ui_cpy;
01192 //    unsigned int                     ui_cpy_cnt;
01193
01194     rvcl_newbspline.resize(2);
01195
01196     // insert knots in u direction
01197     rvcl_newbspline[0] = *this;
01198     getParameterInterval_U(d_min, d_max);
01199     ui_cnt = rvcl_newbspline[0].getDimension_U();
01200
01201     for(ui_idx = 0; ui_idx <= ui_cnt; ++ui_idx)
01202     {
01203         i_span = rvcl_newbspline[0].insertKnot_U( (d_min + d_max) * 0.5);
01204     }
01205
01206     i_span                        -= dimension_u - 2;
01207     rvcl_newbspline[1].dimension_u = dimension_u;
01208     rvcl_newbspline[1].dimension_v = dimension_v;
01209
01210     // split in u direction
01211     ui_cnt = rvcl_newbspline[0].getControlPointMatrix().size();
01212
01213     for(ui_idx = 0; ui_idx <= dimension_u; ++ui_idx)
01214     {
01215         rvcl_newbspline[1].getKnotVector_U().push_back(
01216             rvcl_newbspline[0].getKnotVector_U()[i_span]);
01217     }
01218
01219     for(ui_idx = i_span - 1; ui_idx < ui_cnt; ++ui_idx)
01220     {
01221         rvcl_newbspline[1].getControlPointMatrix().push_back(
01222             rvcl_newbspline[0].getControlPointMatrix()[ui_idx]);
01223         rvcl_newbspline[1].getKnotVector_U().push_back(
01224             rvcl_newbspline[0].getKnotVector_U()[ui_idx + dimension_u + 1]);
01225     }
01226
01227     rvcl_newbspline[0].getControlPointMatrix().resize(i_span);
01228     rvcl_newbspline[0].getKnotVector_U().resize(i_span + dimension_u);
01229     rvcl_newbspline[0].getKnotVector_U().push_back(
01230         rvcl_newbspline[0].getKnotVector_U()[i_span + dimension_u - 1]);
01231     rvcl_newbspline[1].getKnotVector_V() = rvcl_newbspline[0].getKnotVector_V();
01232
01233     ui_cnt = rvcl_newbspline[0].getKnotVector_U().size() - 1;
01234     ui_idx = ui_cnt - dimension_u - 1;
01235     while(rvcl_newbspline[0].getKnotVector_U()[ui_cnt] == rvcl_newbspline[0].getKnotVector_U()[ui_idx])
01236     {
01237         rvcl_newbspline[0].getKnotVector_U().pop_back();
01238         rvcl_newbspline[0].getControlPointMatrix().pop_back();
01239         --ui_cnt;
01240         --ui_idx;
01241     }
01242
01243     return 0;
01244 }
01245
01246
01247 // subdivide surface at midpoint into 2 bezier surfaces
01248 int BSplineTensorSurface::midPointSubDivisionV(std::vector<BSplineTensorSurface> &rvcl_newbspline)
01249 {
01250     double                           d_min;
01251     double                           d_max;
01252     int                              ui_cnt;
01253     int                              ui_idx;
01254     int                              i_span = 0;
01255     std::vector<std::vector<Vec4d> > vvcl_cp;
01256     unsigned int                     ui_cpy;
01257     unsigned int                     ui_cpy_cnt;
01258
01259     rvcl_newbspline.resize(2);
01260
01261     // insert knots in u direction
01262     rvcl_newbspline[0] = *this;
01263     getParameterInterval_V(d_min, d_max);
01264     ui_cnt = rvcl_newbspline[0].getDimension_V();
01265
01266     for(ui_idx = 0; ui_idx < ui_cnt; ++ui_idx)
01267     {
01268         i_span = rvcl_newbspline[0].insertKnot_V( (d_min + d_max) * 0.5);
01269     }
01270
01271     i_span                        -= dimension_v - 2;
01272     rvcl_newbspline[1].dimension_u = dimension_u;
01273     rvcl_newbspline[1].dimension_v = dimension_v;
01274
01275     // split in v direction
01276     ui_cnt = rvcl_newbspline[0].getControlPointMatrix()[0].size();
01277
01278     for(ui_idx = 0; ui_idx <= dimension_v; ++ui_idx)
01279     {
01280         rvcl_newbspline[1].getKnotVector_V().push_back(
01281             rvcl_newbspline[0].getKnotVector_V()[i_span]);
01282     }
01283
01284     ui_cpy_cnt = rvcl_newbspline[0].getControlPointMatrix().size();
01285     rvcl_newbspline[1].getControlPointMatrix().resize(ui_cpy_cnt);
01286
01287     for(ui_idx = i_span - 1; ui_idx < ui_cnt; ++ui_idx)
01288     {
01289         for(ui_cpy = 0; ui_cpy < ui_cpy_cnt; ++ui_cpy)
01290         {
01291             rvcl_newbspline[1].getControlPointMatrix()[ui_cpy].push_back(
01292                 rvcl_newbspline[0].getControlPointMatrix()[ui_cpy][ui_idx]);
01293         }
01294
01295         rvcl_newbspline[1].getKnotVector_V().push_back(
01296             rvcl_newbspline[0].getKnotVector_V()[ui_idx + dimension_v + 1]);
01297     }
01298
01299     ui_cnt = rvcl_newbspline[0].getControlPointMatrix().size();
01300
01301     for(ui_idx = 0; ui_idx < ui_cnt; ++ui_idx)
01302     {
01303         rvcl_newbspline[0].getControlPointMatrix()[ui_idx].resize(i_span);
01304     }
01305
01306     rvcl_newbspline[0].getKnotVector_V().resize(i_span + dimension_v);
01307     rvcl_newbspline[0].getKnotVector_V().push_back(
01308         rvcl_newbspline[0].getKnotVector_V()[i_span + dimension_v - 1]);
01309     rvcl_newbspline[1].getKnotVector_U() = rvcl_newbspline[0].getKnotVector_U();
01310
01311     ui_cnt = rvcl_newbspline[0].getKnotVector_V().size() - 1;
01312     ui_idx = ui_cnt - dimension_v - 1;
01313     while(rvcl_newbspline[0].getKnotVector_V()[ui_cnt] == rvcl_newbspline[0].getKnotVector_V()[ui_idx])
01314     {
01315         rvcl_newbspline[0].getKnotVector_V().pop_back();
01316         ui_cpy_cnt = rvcl_newbspline[0].getControlPointMatrix().size();
01317
01318         for(ui_cpy = 0; ui_cpy < ui_cpy_cnt; ++ui_cpy)
01319         {
01320             rvcl_newbspline[0].getControlPointMatrix()[ui_cpy].pop_back();
01321         }
01322
01323         --ui_cnt;
01324         --ui_idx;
01325     }
01326
01327     return 0;
01328 }
01329
01330
01331 // subdivide surface at param into 2 bezier surfaces
01332 int BSplineTensorSurface::subDivisionU(std::vector<BSplineTensorSurface> &rvcl_newbspline, double dSplit)
01333 {
01334     double                           d_min;
01335     double                           d_max;
01336     int                              ui_cnt;
01337     int                              ui_idx;
01338     int                              i_span = 0;
01339     std::vector<std::vector<Vec4d> > vvcl_cp;
01340 //    unsigned int                     ui_cpy;
01341 //    unsigned int                     ui_cpy_cnt;
01342
01343     rvcl_newbspline.clear();
01344     rvcl_newbspline.resize(2);
01345
01346     // insert knots in u direction
01347     rvcl_newbspline[0] = *this;
01348     getParameterInterval_U(d_min, d_max);
01349     ui_cnt = rvcl_newbspline[0].getDimension_U();
01350
01351     for(ui_idx = 0; ui_idx <= ui_cnt; ++ui_idx)
01352     {
01353         i_span = rvcl_newbspline[0].insertKnot_U(d_min + (d_max - d_min) * dSplit);
01354     }
01355
01356     i_span                        -= dimension_u - 2;
01357     rvcl_newbspline[1].dimension_u = dimension_u;
01358     rvcl_newbspline[1].dimension_v = dimension_v;
01359
01360     // split in u direction
01361     ui_cnt = rvcl_newbspline[0].getControlPointMatrix().size();
01362
01363     for(ui_idx = 0; ui_idx <= dimension_u; ++ui_idx)
01364     {
01365         rvcl_newbspline[1].getKnotVector_U().push_back(
01366             rvcl_newbspline[0].getKnotVector_U()[i_span]);
01367     }
01368
01369     for(ui_idx = i_span - 1; ui_idx < ui_cnt; ++ui_idx)
01370     {
01371         rvcl_newbspline[1].getControlPointMatrix().push_back(
01372             rvcl_newbspline[0].getControlPointMatrix()[ui_idx]);
01373         rvcl_newbspline[1].getKnotVector_U().push_back(
01374             rvcl_newbspline[0].getKnotVector_U()[ui_idx + dimension_u + 1]);
01375     }
01376
01377     rvcl_newbspline[0].getControlPointMatrix().resize(i_span);
01378     rvcl_newbspline[0].getKnotVector_U().resize(i_span + dimension_u);
01379     rvcl_newbspline[0].getKnotVector_U().push_back(
01380         rvcl_newbspline[0].getKnotVector_U()[i_span + dimension_u - 1]);
01381     rvcl_newbspline[1].getKnotVector_V() = rvcl_newbspline[0].getKnotVector_V();
01382
01383     ui_cnt = rvcl_newbspline[0].getKnotVector_U().size() - 1;
01384     ui_idx = ui_cnt - dimension_u - 1;
01385     while(rvcl_newbspline[0].getKnotVector_U()[ui_cnt] == rvcl_newbspline[0].getKnotVector_U()[ui_idx])
01386     {
01387         rvcl_newbspline[0].getKnotVector_U().pop_back();
01388         rvcl_newbspline[0].getControlPointMatrix().pop_back();
01389         --ui_cnt;
01390         --ui_idx;
01391     }
01392
01393     return 0;
01394 }
01395
01396
01397 // subdivide surface at param into 2 bezier surfaces
01398 int BSplineTensorSurface::subDivisionV(std::vector<BSplineTensorSurface> &rvcl_newbspline, double dSplit)
01399 {
01400     double                           d_min;
01401     double                           d_max;
01402     int                              ui_cnt;
01403     int                              ui_idx;
01404     int                              i_span = 0;
01405     std::vector<std::vector<Vec4d> > vvcl_cp;
01406     unsigned int                     ui_cpy;
01407     unsigned int                     ui_cpy_cnt;
01408
01409     rvcl_newbspline.clear();
01410     rvcl_newbspline.resize(2);
01411
01412     // insert knots in u direction
01413     rvcl_newbspline[0] = *this;
01414     getParameterInterval_V(d_min, d_max);
01415     ui_cnt = rvcl_newbspline[0].getDimension_V();
01416
01417     for(ui_idx = 0; ui_idx < ui_cnt; ++ui_idx)
01418     {
01419         i_span = rvcl_newbspline[0].insertKnot_V(d_min + (d_max - d_min) * dSplit);
01420     }
01421
01422     i_span                        -= dimension_v - 2;
01423     rvcl_newbspline[1].dimension_u = dimension_u;
01424     rvcl_newbspline[1].dimension_v = dimension_v;
01425
01426     // split in v direction
01427     ui_cnt = rvcl_newbspline[0].getControlPointMatrix()[0].size();
01428
01429     for(ui_idx = 0; ui_idx <= dimension_v; ++ui_idx)
01430     {
01431         rvcl_newbspline[1].getKnotVector_V().push_back(
01432             rvcl_newbspline[0].getKnotVector_V()[i_span]);
01433     }
01434
01435     ui_cpy_cnt = rvcl_newbspline[0].getControlPointMatrix().size();
01436     rvcl_newbspline[1].getControlPointMatrix().resize(ui_cpy_cnt);
01437
01438     for(ui_idx = i_span - 1; ui_idx < ui_cnt; ++ui_idx)
01439     {
01440         for(ui_cpy = 0; ui_cpy < ui_cpy_cnt; ++ui_cpy)
01441         {
01442             rvcl_newbspline[1].getControlPointMatrix()[ui_cpy].push_back(
01443                 rvcl_newbspline[0].getControlPointMatrix()[ui_cpy][ui_idx]);
01444         }
01445
01446         rvcl_newbspline[1].getKnotVector_V().push_back(
01447             rvcl_newbspline[0].getKnotVector_V()[ui_idx + dimension_v + 1]);
01448     }
01449
01450     ui_cnt = rvcl_newbspline[0].getControlPointMatrix().size();
01451
01452     for(ui_idx = 0; ui_idx < ui_cnt; ++ui_idx)
01453     {
01454         rvcl_newbspline[0].getControlPointMatrix()[ui_idx].resize(i_span);
01455     }
01456
01457     rvcl_newbspline[0].getKnotVector_V().resize(i_span + dimension_v);
01458     rvcl_newbspline[0].getKnotVector_V().push_back(
01459         rvcl_newbspline[0].getKnotVector_V()[i_span + dimension_v - 1]);
01460     rvcl_newbspline[1].getKnotVector_U() = rvcl_newbspline[0].getKnotVector_U();
01461
01462     ui_cnt = rvcl_newbspline[0].getKnotVector_V().size() - 1;
01463     ui_idx = ui_cnt - dimension_v - 1;
01464     while(rvcl_newbspline[0].getKnotVector_V()[ui_cnt] == rvcl_newbspline[0].getKnotVector_V()[ui_idx])
01465     {
01466         rvcl_newbspline[0].getKnotVector_V().pop_back();
01467         ui_cpy_cnt = rvcl_newbspline[0].getControlPointMatrix().size();
01468
01469         for(ui_cpy = 0; ui_cpy < ui_cpy_cnt; ++ui_cpy)
01470         {
01471             rvcl_newbspline[0].getControlPointMatrix()[ui_cpy].pop_back();
01472         }
01473
01474         --ui_cnt;
01475         --ui_idx;
01476     }
01477
01478     return 0;
01479 }
01480
01481
01482 //new vector-enabled computational functions from Michael
01483 void BSplineTensorSurface::compute(std::vector<Vec2d> &rvclUV,
01484                                    std::vector<Pnt3f> &rvclPos)
01485
01486 {
01487     const unsigned int cui_cnt = rvclUV.size();
01488     unsigned int       ui_idx;
01489     double            *pd_nu;
01490     double            *pd_nv;
01491     int                i_span_u = -1;
01492     int                i_span_v = -1;
01493     unsigned int       ui_index_v;
01494     Vec4d             *pcl_temp = new Vec4d[dimension_u + 1];
01495     unsigned int       ui_index_u;
01496     int                i_l;
01497     int                i_k;
01498     double            *pd_nul;
01499     double            *pd_nvk;
01500     bool               b_u_new;
01501     bool               b_v_new;
01502     Vec4d             *pcl_templ;
01503     int                i_old_u;
01504
01505     rvclPos.resize(cui_cnt);
01506
01507     for(ui_idx = 0; ui_idx < cui_cnt; ++ui_idx)
01508     {
01509         if(ui_idx == 0)
01510         {
01511             i_span_u = basis_function_u.computeAllNonzero(rvclUV[ui_idx][0], dimension_u, pd_nu);
01512             i_span_v = basis_function_v.computeAllNonzero(rvclUV[ui_idx][1], dimension_v, pd_nv);
01513             b_u_new  = b_v_new = true;
01514         }
01515         else
01516         {
01517             if(osgAbs(rvclUV[ui_idx][0] - rvclUV[ui_idx - 1][0]) > DCTP_EPS)
01518             {
01519                 i_old_u = i_span_u;
01520                 if(i_span_u >= 0)
01521                     delete[]  pd_nu;
01522                 i_span_u = basis_function_u.computeAllNonzero(rvclUV[ui_idx][0], dimension_u, pd_nu);
01523                 b_u_new  = true;
01524                 b_v_new  = (i_old_u != i_span_u) ? true : false;
01525             }
01526             else
01527             {
01528                 b_u_new = false;
01529                 b_v_new = false;
01530             }
01531             if(osgAbs(rvclUV[ui_idx][1] - rvclUV[ui_idx - 1][1]) > DCTP_EPS)
01532             {
01533                 if(i_span_v >= 0)
01534                     delete[]  pd_nv;
01535                 i_span_v = basis_function_v.computeAllNonzero(rvclUV[ui_idx][1], dimension_v, pd_nv);
01536                 b_v_new  = true;
01537             }
01538         }
01539
01540         if( (i_span_u < 0) || (i_span_v < 0) )
01541         {
01542             rvclPos[ui_idx] = Pnt3f(0.0, 0.0, 0.0);
01543         }
01544         else if(b_v_new)
01545         {
01546             ui_index_u = i_span_u - dimension_u;
01547             pd_nul     = pd_nu;
01548             pcl_templ  = pcl_temp;
01549             Vec4d tempposition(0.0, 0.0, 0.0, 0.0);
01550
01551             for(i_l = 0; i_l <= dimension_u; ++i_l)
01552             {
01553                 (*pcl_templ) = Vec4d(0.0, 0.0, 0.0, 0.0);
01554                 ui_index_v   = i_span_v - dimension_v;
01555                 pd_nvk       = pd_nv;
01556
01557                 for(i_k = 0; i_k <= dimension_v; ++i_k)
01558                 {
01559                     *pcl_templ += control_points[ui_index_u][ui_index_v] * *pd_nvk;
01560                     ++ui_index_v;
01561                     ++pd_nvk;
01562                 }
01563
01564                 ++ui_index_u;
01565                 tempposition += *pcl_templ * *pd_nul;
01566                 ++pd_nul;
01567                 ++pcl_templ;
01568             }
01569
01570             rvclPos[ui_idx][0] = tempposition[0] / tempposition[3];
01571             rvclPos[ui_idx][1] = tempposition[1] / tempposition[3];
01572             rvclPos[ui_idx][2] = tempposition[2] / tempposition[3];
01573         }
01574         else if(b_u_new)
01575         {
01576             ui_index_u = i_span_u - dimension_u;
01577             pd_nul     = pd_nu;
01578             pcl_templ  = pcl_temp;
01579             Vec4d tempposition(0.0, 0.0, 0.0, 0.0);
01580
01581             for(i_l = 0; i_l <= dimension_u; ++i_l)
01582             {
01583                 ++ui_index_u;
01584                 tempposition += *pcl_templ * *pd_nul;
01585                 ++pd_nul;
01586                 ++pcl_templ;
01587             }
01588
01589             rvclPos[ui_idx][0] = tempposition[0] / tempposition[3];
01590             rvclPos[ui_idx][1] = tempposition[1] / tempposition[3];
01591             rvclPos[ui_idx][2] = tempposition[2] / tempposition[3];
01592 #ifdef OSG_COUNT_COMP
01593             ++g_uiVSameComp;
01594 #endif
01595         }
01596         else
01597         {
01598             rvclPos[ui_idx] = rvclPos[ui_idx - 1];
01599 #ifdef OSG_COUNT_COMP
01600             ++g_uiSameComp;
01601 #endif
01602         }
01603 #ifdef OSG_COUNT_COMP
01604         ++g_uiTotalComp;
01605 #endif
01606     }
01607
01608     if(i_span_u >= 0)
01609         delete[]  pd_nu;
01610     if(i_span_v >= 0)
01611         delete[]  pd_nv;
01612     delete[]  pcl_temp;
01613
01614 #ifdef OSG_COUNT_COMP
01615     cerr << g_uiTotalComp << " " << g_uiVSameComp << " " << g_uiSameComp << endl;
01616 #endif
01617 }
01618
01619
01620 void BSplineTensorSurface::computeNormal(std::vector<Vec2d> &rvclUV,
01621                                          std::vector<Pnt3f> &rvclPos,
01622                                          std::vector<Vec3f> &rvclNorm)
01623 {
01624     const unsigned int cui_cnt = rvclUV.size();
01625     unsigned int       ui_idx;
01626     int                i_uspan = -1;
01627     int                i_vspan = -1;
01628     double           **ppd_nu;
01629     double           **ppd_nv;
01630     int                i_k;
01631     int                i_s;
01632     int                i_l;
01633     DCTPVec4dmatrix    vvcl_skl;
01634     DCTPVec3dmatrix    vvcl_skl_eucl;
01635     Vec4d             *apcl_temp[2];
01636     int                i_r;
01637     double             d_len = 0.0;
01638     int                i_u;
01639     int                i_v;
01640     bool               b_u_new;
01641     bool               b_v_new;
01642     Vec4d             *pcl_temps;
01643     double            *pd_nuls;
01644     double            *pd_nvkr;
01645     Vec4d             *pcl_sklkl;
01646     int                i_old_u;
01647
01648 //  std::cerr << dimension_u << " " << dimension_v << std::endl;
01649
01650     vvcl_skl.resize(2);
01651     vvcl_skl[0].resize(2);
01652     vvcl_skl[1].resize(2);
01653     vvcl_skl_eucl.resize(2);
01654     vvcl_skl_eucl[0].resize(2);
01655     vvcl_skl_eucl[1].resize(2);
01656
01657     apcl_temp[0] = new Vec4d[dimension_u + 1];
01658     apcl_temp[1] = new Vec4d[dimension_u + 1];
01659
01660     rvclPos.resize(cui_cnt);
01661     rvclNorm.resize(cui_cnt);
01662
01663     for(ui_idx = 0; ui_idx < cui_cnt; ++ui_idx)
01664     {
01665         if(ui_idx == 0)
01666         {
01667             i_uspan = basis_function_u.computeDersBasisFuns(rvclUV[ui_idx][0], dimension_u, ppd_nu, 1);
01668             i_vspan = basis_function_v.computeDersBasisFuns(rvclUV[ui_idx][1], dimension_v, ppd_nv, 1);
01669             b_u_new = b_v_new = true;
01670         }
01671         else
01672         {
01673             if(osgAbs(rvclUV[ui_idx][0] - rvclUV[ui_idx - 1][0]) > DCTP_EPS)
01674             {
01675                 i_old_u = i_uspan;
01676                 if(i_uspan >= 0)
01677                 {
01678                     delete[]  ppd_nu[0];
01679                     delete[]  ppd_nu[1];
01680                     delete[]  ppd_nu;
01681                 }
01682                 i_uspan = basis_function_u.computeDersBasisFuns(rvclUV[ui_idx][0], dimension_u, ppd_nu, 1);
01683                 b_u_new = true;
01684                 b_v_new = (i_old_u != i_uspan) ? true : false;
01685             }
01686             else
01687             {
01688                 b_u_new = false;
01689                 b_v_new = false;
01690             }
01691             if(osgAbs(rvclUV[ui_idx][1] - rvclUV[ui_idx - 1][1]) > DCTP_EPS)
01692             {
01693                 if(i_vspan >= 0)
01694                 {
01695                     delete[]  ppd_nv[0];
01696                     delete[]  ppd_nv[1];
01697                     delete[]  ppd_nv;
01698                 }
01699                 i_vspan = basis_function_v.computeDersBasisFuns(rvclUV[ui_idx][1], dimension_v, ppd_nv, 1);
01700                 b_v_new = true;
01701             }
01702         }
01703         if( (i_uspan < 0) || (i_vspan < 0) )
01704         {
01705             rvclPos[ui_idx]  = Pnt3f(0.0, 0.0, 0.0);
01706             rvclNorm[ui_idx] = Vec3f(0.0, 0.0, 0.0);
01707         }
01708         else if(b_v_new)
01709         {
01710             for(i_k = 0; i_k <= 1; ++i_k)
01711             {
01712                 i_u       = i_uspan - dimension_u;
01713                 pcl_temps = apcl_temp[i_k];
01714
01715                 for(i_s = 0; i_s <= dimension_u; ++i_s)
01716                 {
01717                     (*pcl_temps) = Vec4d(0.0, 0.0, 0.0, 0.0);
01718                     i_v          = i_vspan - dimension_v;
01719                     pd_nvkr      = ppd_nv[i_k];
01720
01721                     for(i_r = 0; i_r <= dimension_v; ++i_r)
01722                     {
01723                         *pcl_temps += control_points[i_u][i_v] * *pd_nvkr;
01724                         ++i_v;
01725                         ++pd_nvkr;
01726                     }
01727
01728                     ++i_u;
01729                     ++pcl_temps;
01730                 }
01731
01732                 pcl_sklkl = &(vvcl_skl[i_k][0]);
01733
01734                 for(i_l = 0; i_l <= 1 - i_k; ++i_l)
01735                 {
01736                     (*pcl_sklkl) = Vec4d(0.0, 0.0, 0.0, 0.0);
01737                     pcl_temps    = apcl_temp[i_k];
01738                     pd_nuls      = ppd_nu[i_l];
01739
01740                     for(i_s = 0; i_s <= dimension_u; ++i_s)
01741                     {
01742                         *pcl_sklkl += *pcl_temps * *pd_nuls;
01743                         ++pcl_temps;
01744                         ++pd_nuls;
01745                     }
01746
01747                     ++pcl_sklkl;
01748                 }
01749             }
01750
01751             RatSurfaceDerivs(vvcl_skl, vvcl_skl_eucl);
01752             rvclPos[ui_idx][0] = vvcl_skl_eucl[0][0][0];
01753             rvclPos[ui_idx][1] = vvcl_skl_eucl[0][0][1];
01754             rvclPos[ui_idx][2] = vvcl_skl_eucl[0][0][2];
01755
01756             correctDers(rvclUV[ui_idx], vvcl_skl_eucl[0][0], vvcl_skl_eucl[1][0], vvcl_skl_eucl[0][1]);
01757 //          rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] );    // switched because of optimization!
01758 //          d_len = rvclNorm[ ui_idx ].squareLength( );
01759             Vec3d tempnorm = vvcl_skl_eucl[0][1].cross(vvcl_skl_eucl[1][0]);
01760             rvclNorm[ui_idx][0] = tempnorm[0];
01761             rvclNorm[ui_idx][1] = tempnorm[1];
01762             rvclNorm[ui_idx][2] = tempnorm[2];
01763             d_len               = tempnorm.squareLength();
01764
01765             if(d_len > DCTP_EPS * DCTP_EPS)
01766             {
01767                 rvclNorm[ui_idx] *= 1.0 / sqrt(d_len);
01768             }
01769             else
01770             {
01771                 rvclNorm[ui_idx][0] = rvclNorm[ui_idx][1] = rvclNorm[ui_idx][2] = 0.0;
01772             }
01773         }
01774         else if(b_u_new)
01775         {
01776             for(i_k = 0; i_k <= 1; ++i_k)
01777             {
01778                 pcl_sklkl = &(vvcl_skl[i_k][0]);
01779
01780                 for(i_l = 0; i_l <= 1 - i_k; ++i_l)
01781                 {
01782                     (*pcl_sklkl) = Vec4d(0.0, 0.0, 0.0, 0.0);
01783                     pcl_temps    = apcl_temp[i_k];
01784                     pd_nuls      = ppd_nu[i_l];
01785
01786                     for(i_s = 0; i_s <= dimension_u; ++i_s)
01787                     {
01788                         *pcl_sklkl += *pcl_temps * *pd_nuls;
01789                         ++pcl_temps;
01790                         ++pd_nuls;
01791                     }
01792
01793                     ++pcl_sklkl;
01794                 }
01795             }
01796
01797             RatSurfaceDerivs(vvcl_skl, vvcl_skl_eucl);
01798             rvclPos[ui_idx][0] = vvcl_skl_eucl[0][0][0];
01799             rvclPos[ui_idx][1] = vvcl_skl_eucl[0][0][1];
01800             rvclPos[ui_idx][2] = vvcl_skl_eucl[0][0][2];
01801
01802             correctDers(rvclUV[ui_idx], vvcl_skl_eucl[0][0], vvcl_skl_eucl[1][0], vvcl_skl_eucl[0][1]);
01803 //          rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] );    // switched because of optimization!
01804 //          d_len = rvclNorm[ ui_idx ].squareLength( );
01805             Vec3d tempnorm = vvcl_skl_eucl[0][1].cross(vvcl_skl_eucl[1][0]);
01806             rvclNorm[ui_idx][0] = tempnorm[0];
01807             rvclNorm[ui_idx][1] = tempnorm[1];
01808             rvclNorm[ui_idx][2] = tempnorm[2];
01809             if(d_len > DCTP_EPS * DCTP_EPS)
01810             {
01811                 rvclNorm[ui_idx] *= 1.0 / sqrt(d_len);
01812             }
01813             else
01814             {
01815                 rvclNorm[ui_idx][0] = rvclNorm[ui_idx][1] = rvclNorm[ui_idx][2] = 0.0;
01816             }
01817 #ifdef OSG_COUNT_COMP
01818             ++g_uiVSameComp;
01819 #endif
01820         }
01821         else
01822         {
01823             rvclPos[ui_idx]  = rvclPos[ui_idx - 1];
01824             rvclNorm[ui_idx] = rvclNorm[ui_idx - 1];
01825 #ifdef OSG_COUNT_COMP
01826             ++g_uiSameComp;
01827 #endif
01828         }
01829 #ifdef OSG_COUNT_COMP
01830         ++g_uiTotalComp;
01831 #endif
01832     }
01833
01834     // clean up allocated memory
01835     if(i_uspan >= 0)
01836     {
01837         delete[]  ppd_nu[0];
01838         delete[]  ppd_nu[1];
01839         delete[]  ppd_nu;
01840     }
01841     if(i_vspan >= 0)
01842     {
01843         delete[]  ppd_nv[0];
01844         delete[]  ppd_nv[1];
01845         delete[]  ppd_nv;
01846     }
01847     delete[]  apcl_temp[0];
01848     delete[]  apcl_temp[1];
01849
01850 #ifdef OSG_COUNT_COMP
01851     cerr << g_uiTotalComp << " " << g_uiVSameComp << " " << g_uiSameComp << endl;
01852 #endif
01853 }
01854
01855
01856 void BSplineTensorSurface::computeNormalforTrimming(std::vector<Vec2d> &rvclUV,
01857                                                     std::vector<Vec3d> &rvclNorm,
01858                                                     std::vector<Vec3d> *pvclPos)
01859 {
01860     const unsigned int cui_cnt = rvclUV.size();
01861     unsigned int       ui_idx;
01862     int                i_uspan = -1;
01863     int                i_vspan = -1;
01864     double           **ppd_nu;
01865     double           **ppd_nv;
01866     int                i_k;
01867     int                i_s;
01868     int                i_l;
01869     DCTPVec4dmatrix    vvcl_skl;
01870     DCTPVec3dmatrix    vvcl_skl_eucl;
01871     Vec4d             *apcl_temp[2];
01872     int                i_r;
01873     double             d_len = 0.0;
01874     int                i_u;
01875     int                i_v;
01876     bool               b_u_new;
01877     bool               b_v_new;
01878     Vec4d             *pcl_temps;
01879     double            *pd_nuls;
01880     double            *pd_nvkr;
01881     Vec4d             *pcl_sklkl;
01882     int                i_old_u;
01883
01884 //  std::cerr << dimension_u << " " << dimension_v << std::endl;
01885
01886     vvcl_skl.resize(2);
01887     vvcl_skl[0].resize(2);
01888     vvcl_skl[1].resize(2);
01889     vvcl_skl_eucl.resize(2);
01890     vvcl_skl_eucl[0].resize(2);
01891     vvcl_skl_eucl[1].resize(2);
01892
01893     apcl_temp[0] = new Vec4d[dimension_u + 1];
01894     apcl_temp[1] = new Vec4d[dimension_u + 1];
01895
01896     if(pvclPos != NULL)
01897     {
01898         pvclPos->resize(cui_cnt);
01899     }
01900     rvclNorm.resize(cui_cnt);
01901
01902     for(ui_idx = 0; ui_idx < cui_cnt; ++ui_idx)
01903     {
01904         if(ui_idx == 0)
01905         {
01906             i_uspan = basis_function_u.computeDersBasisFuns(rvclUV[ui_idx][0], dimension_u, ppd_nu, 1);
01907             i_vspan = basis_function_v.computeDersBasisFuns(rvclUV[ui_idx][1], dimension_v, ppd_nv, 1);
01908             b_u_new = b_v_new = true;
01909         }
01910         else
01911         {
01912             if(osgAbs(rvclUV[ui_idx][0] - rvclUV[ui_idx - 1][0]) > DCTP_EPS)
01913             {
01914                 i_old_u = i_uspan;
01915                 if(i_uspan >= 0)
01916                 {
01917                     delete[]  ppd_nu[0];
01918                     delete[]  ppd_nu[1];
01919                     delete[]  ppd_nu;
01920                 }
01921                 i_uspan = basis_function_u.computeDersBasisFuns(rvclUV[ui_idx][0], dimension_u, ppd_nu, 1);
01922                 b_u_new = true;
01923                 b_v_new = (i_old_u != i_uspan) ? true : false;
01924             }
01925             else
01926             {
01927                 b_u_new = false;
01928                 b_v_new = false;
01929             }
01930             if(osgAbs(rvclUV[ui_idx][1] - rvclUV[ui_idx - 1][1]) > DCTP_EPS)
01931             {
01932                 if(i_vspan >= 0)
01933                 {
01934                     delete[]  ppd_nv[0];
01935                     delete[]  ppd_nv[1];
01936                     delete[]  ppd_nv;
01937                 }
01938                 i_vspan = basis_function_v.computeDersBasisFuns(rvclUV[ui_idx][1], dimension_v, ppd_nv, 1);
01939                 b_v_new = true;
01940             }
01941         }
01942         if( (i_uspan < 0) || (i_vspan < 0) )
01943         {
01944             if(pvclPos != NULL)
01945             {
01946                 (*pvclPos)[ui_idx] = Vec3d(0.0, 0.0, 0.0);
01947             }
01948             rvclNorm[ui_idx] = Vec3d(0.0, 0.0, 0.0);
01949         }
01950         else if(b_v_new)
01951         {
01952             for(i_k = 0; i_k <= 1; ++i_k)
01953             {
01954                 i_u       = i_uspan - dimension_u;
01955                 pcl_temps = apcl_temp[i_k];
01956
01957                 for(i_s = 0; i_s <= dimension_u; ++i_s)
01958                 {
01959                     (*pcl_temps) = Vec4d(0.0, 0.0, 0.0, 0.0);
01960                     i_v          = i_vspan - dimension_v;
01961                     pd_nvkr      = ppd_nv[i_k];
01962
01963                     for(i_r = 0; i_r <= dimension_v; ++i_r)
01964                     {
01965                         *pcl_temps += control_points[i_u][i_v] * *pd_nvkr;
01966                         ++i_v;
01967                         ++pd_nvkr;
01968                     }
01969
01970                     ++i_u;
01971                     ++pcl_temps;
01972                 }
01973
01974                 pcl_sklkl = &(vvcl_skl[i_k][0]);
01975
01976                 for(i_l = 0; i_l <= 1 - i_k; ++i_l)
01977                 {
01978                     (*pcl_sklkl) = Vec4d(0.0, 0.0, 0.0, 0.0);
01979                     pcl_temps    = apcl_temp[i_k];
01980                     pd_nuls      = ppd_nu[i_l];
01981
01982                     for(i_s = 0; i_s <= dimension_u; ++i_s)
01983                     {
01984                         *pcl_sklkl += *pcl_temps * *pd_nuls;
01985                         ++pcl_temps;
01986                         ++pd_nuls;
01987                     }
01988
01989                     ++pcl_sklkl;
01990                 }
01991             }
01992
01993             RatSurfaceDerivs(vvcl_skl, vvcl_skl_eucl);
01994             if(pvclPos != NULL)
01995             {
01996                 (*pvclPos)[ui_idx] = vvcl_skl_eucl[0][0];
01997             }
01998
01999             correctDers(rvclUV[ui_idx], vvcl_skl_eucl[0][0], vvcl_skl_eucl[1][0], vvcl_skl_eucl[0][1]);
02000 //          rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] );    // switched because of optimization!
02001 //          d_len = rvclNorm[ ui_idx ].squareLength( );
02002             Vec3d tempnorm = vvcl_skl_eucl[0][1].cross(vvcl_skl_eucl[1][0]);
02003             rvclNorm[ui_idx][0] = tempnorm[0];
02004             rvclNorm[ui_idx][1] = tempnorm[1];
02005             rvclNorm[ui_idx][2] = tempnorm[2];
02006             d_len               = tempnorm.squareLength();
02007
02008             if(d_len > DCTP_EPS * DCTP_EPS)
02009             {
02010                 rvclNorm[ui_idx] *= 1.0 / sqrt(d_len);
02011             }
02012             else
02013             {
02014                 rvclNorm[ui_idx][0] = rvclNorm[ui_idx][1] = rvclNorm[ui_idx][2] = 0.0;
02015             }
02016         }
02017         else if(b_u_new)
02018         {
02019             for(i_k = 0; i_k <= 1; ++i_k)
02020             {
02021                 pcl_sklkl = &(vvcl_skl[i_k][0]);
02022
02023                 for(i_l = 0; i_l <= 1 - i_k; ++i_l)
02024                 {
02025                     (*pcl_sklkl) = Vec4d(0.0, 0.0, 0.0, 0.0);
02026                     pcl_temps    = apcl_temp[i_k];
02027                     pd_nuls      = ppd_nu[i_l];
02028
02029                     for(i_s = 0; i_s <= dimension_u; ++i_s)
02030                     {
02031                         *pcl_sklkl += *pcl_temps * *pd_nuls;
02032                         ++pcl_temps;
02033                         ++pd_nuls;
02034                     }
02035
02036                     ++pcl_sklkl;
02037                 }
02038             }
02039
02040             RatSurfaceDerivs(vvcl_skl, vvcl_skl_eucl);
02041             if(pvclPos != NULL)
02042             {
02043                 (*pvclPos)[ui_idx] = vvcl_skl_eucl[0][0];
02044             }
02045
02046             correctDers(rvclUV[ui_idx], vvcl_skl_eucl[0][0], vvcl_skl_eucl[1][0], vvcl_skl_eucl[0][1]);
02047 //          rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] );    // switched because of optimization!
02048 //          d_len = rvclNorm[ ui_idx ].squareLength( );
02049             Vec3d tempnorm = vvcl_skl_eucl[0][1].cross(vvcl_skl_eucl[1][0]);
02050             rvclNorm[ui_idx][0] = tempnorm[0];
02051             rvclNorm[ui_idx][1] = tempnorm[1];
02052             rvclNorm[ui_idx][2] = tempnorm[2];
02053             if(d_len > DCTP_EPS * DCTP_EPS)
02054             {
02055                 rvclNorm[ui_idx] *= 1.0 / sqrt(d_len);
02056             }
02057             else
02058             {
02059                 rvclNorm[ui_idx][0] = rvclNorm[ui_idx][1] = rvclNorm[ui_idx][2] = 0.0;
02060             }
02061 #ifdef OSG_COUNT_COMP
02062             ++g_uiVSameComp;
02063 #endif
02064         }
02065         else
02066         {
02067             if(pvclPos != NULL)
02068             {
02069                 (*pvclPos)[ui_idx] = (*pvclPos)[ui_idx - 1];
02070             }
02071             rvclNorm[ui_idx] = rvclNorm[ui_idx - 1];
02072 #ifdef OSG_COUNT_COMP
02073             ++g_uiSameComp;
02074 #endif
02075         }
02076 #ifdef OSG_COUNT_COMP
02077         ++g_uiTotalComp;
02078 #endif
02079     }
02080
02081     // clean up allocated memory
02082     if(i_uspan >= 0)
02083     {
02084         delete[]  ppd_nu[0];
02085         delete[]  ppd_nu[1];
02086         delete[]  ppd_nu;
02087     }
02088     if(i_vspan >= 0)
02089     {
02090         delete[]  ppd_nv[0];
02091         delete[]  ppd_nv[1];
02092         delete[]  ppd_nv;
02093     }
02094     delete[]  apcl_temp[0];
02095     delete[]  apcl_temp[1];
02096
02097 #ifdef OSG_COUNT_COMP
02098     cerr << g_uiTotalComp << " " << g_uiVSameComp << " " << g_uiSameComp << endl;
02099 #endif
02100 
02101 }
02102
02103
02104 void BSplineTensorSurface::computeNormalTex(std::vector<Vec2d> &                    rvclUV,
02105                                             std::vector<Pnt3f> &                    rvclPos,
02106                                             std::vector<Vec3f> &                    rvclNorm,
02107                                             std::vector<Pnt2f> &                    rvclTexCoord,
02108                                             const std::vector<std::vector<Pnt2f> > *cpvvclTexCP)
02109 {
02110     const unsigned int cui_cnt = rvclUV.size();
02111     unsigned int       ui_idx;
02112     int                i_uspan = -1;
02113     int                i_vspan = -1;
02114     double           **ppd_nu;
02115     double           **ppd_nv;
02116     int                i_k;
02117     int                i_s;
02118     int                i_l;
02119     DCTPVec4dmatrix    vvcl_skl;
02120     DCTPVec3dmatrix    vvcl_skl_eucl;
02121     Vec4d             *apcl_temp[2];
02122     int                i_r;
02123     double             d_len;
02124     int                i_u;
02125     int                i_v;
02126     bool               b_u_new;
02127     bool               b_v_new;
02128     Vec4d             *pcl_temps;
02129     double            *pd_nuls;
02130     double            *pd_nvkr;
02131     Vec4d             *pcl_sklkl;
02132     Vec2d             *pcl_temp_2d = new Vec2d[dimension_u + 1];
02133     Vec2d             *pcl_temp_2dl;
02134     int                i_old_u;
02135
02136     vvcl_skl.resize(2);
02137     vvcl_skl[0].resize(2);
02138     vvcl_skl[1].resize(2);
02139     vvcl_skl_eucl.resize(2);
02140     vvcl_skl_eucl[0].resize(2);
02141     vvcl_skl_eucl[1].resize(2);
02142
02143     apcl_temp[0] = new Vec4d[dimension_u + 1];
02144     apcl_temp[1] = new Vec4d[dimension_u + 1];
02145
02146     rvclPos.resize(cui_cnt);
02147     rvclNorm.resize(cui_cnt);
02148     rvclTexCoord.resize(cui_cnt);
02149
02150     for(ui_idx = 0; ui_idx < cui_cnt; ++ui_idx)
02151     {
02152         if(ui_idx == 0)
02153         {
02154             i_uspan = basis_function_u.computeDersBasisFuns(rvclUV[ui_idx][0], dimension_u, ppd_nu, 1);
02155             i_vspan = basis_function_v.computeDersBasisFuns(rvclUV[ui_idx][1], dimension_v, ppd_nv, 1);
02156             b_u_new = b_v_new = true;
02157         }
02158         else
02159         {
02160             if(osgAbs(rvclUV[ui_idx][0] - rvclUV[ui_idx - 1][0]) > DCTP_EPS)
02161             {
02162                 i_old_u = i_uspan;
02163                 if(i_uspan >= 0)
02164                 {
02165                     delete[]  ppd_nu[0];
02166                     delete[]  ppd_nu[1];
02167                     delete[]  ppd_nu;
02168                 }
02169                 i_uspan = basis_function_u.computeDersBasisFuns(rvclUV[ui_idx][0], dimension_u, ppd_nu, 1);
02170                 b_u_new = true;
02171                 b_v_new = (i_old_u != i_uspan) ? true : false;
02172             }
02173             else
02174             {
02175                 b_u_new = false;
02176                 b_v_new = false;
02177             }
02178             if(osgAbs(rvclUV[ui_idx][1] - rvclUV[ui_idx - 1][1]) > DCTP_EPS)
02179             {
02180                 if(i_vspan >= 0)
02181                 {
02182                     delete[]  ppd_nv[0];
02183                     delete[]  ppd_nv[1];
02184                     delete[]  ppd_nv;
02185                 }
02186                 i_vspan = basis_function_v.computeDersBasisFuns(rvclUV[ui_idx][1], dimension_v, ppd_nv, 1);
02187                 b_v_new = true;
02188             }
02189         }
02190         if( (i_uspan < 0) || (i_vspan < 0) )
02191         {
02192             rvclPos[ui_idx]  = Pnt3f(0.0, 0.0, 0.0);
02193             rvclNorm[ui_idx] = Vec3f(0.0, 0.0, 0.0);
02194         }
02195         else if(b_v_new)
02196         {
02197             for(i_k = 0; i_k <= 1; ++i_k)
02198             {
02199                 i_u       = i_uspan - dimension_u;
02200                 pcl_temps = apcl_temp[i_k];
02201
02202                 for(i_s = 0; i_s <= dimension_u; ++i_s)
02203                 {
02204                     (*pcl_temps) = Vec4d(0.0, 0.0, 0.0, 0.0);
02205                     i_v          = i_vspan - dimension_v;
02206                     pd_nvkr      = ppd_nv[i_k];
02207
02208                     for(i_r = 0; i_r <= dimension_v; ++i_r)
02209                     {
02210                         *pcl_temps += control_points[i_u][i_v] * *pd_nvkr;
02211                         ++i_v;
02212                         ++pd_nvkr;
02213                     }
02214
02215                     ++i_u;
02216                     ++pcl_temps;
02217                 }
02218
02219                 pcl_sklkl = &(vvcl_skl[i_k][0]);
02220
02221                 for(i_l = 0; i_l <= 1 - i_k; ++i_l)
02222                 {
02223                     (*pcl_sklkl) = Vec4d(0.0, 0.0, 0.0, 0.0);
02224                     pcl_temps    = apcl_temp[i_k];
02225                     pd_nuls      = ppd_nu[i_l];
02226
02227                     for(i_s = 0; i_s <= dimension_u; ++i_s)
02228                     {
02229                         *pcl_sklkl += *pcl_temps * *pd_nuls;
02230                         ++pcl_temps;
02231                         ++pd_nuls;
02232                     }
02233
02234                     ++pcl_sklkl;
02235                 }
02236             }
02237
02238             RatSurfaceDerivs(vvcl_skl, vvcl_skl_eucl);
02239
02240 //          rvclPos[ ui_idx ] = aacl_skl[ 0 ][ 0 ];
02241             rvclPos[ui_idx][0] = vvcl_skl_eucl[0][0][0];
02242             rvclPos[ui_idx][1] = vvcl_skl_eucl[0][0][1];
02243             rvclPos[ui_idx][2] = vvcl_skl_eucl[0][0][2];
02244
02245             correctDers(rvclUV[ui_idx], vvcl_skl_eucl[0][0], vvcl_skl_eucl[1][0], vvcl_skl_eucl[0][1]);
02246 //          rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] );
02247 //          d_len = rvclNorm[ ui_idx ].squareLength( );
02248             Vec3d tempnorm = vvcl_skl_eucl[0][1].cross(vvcl_skl_eucl[1][0]);
02249             rvclNorm[ui_idx][0] = tempnorm[0];
02250             rvclNorm[ui_idx][1] = tempnorm[1];
02251             rvclNorm[ui_idx][2] = tempnorm[2];
02252             d_len               = tempnorm.squareLength();
02253
02254             if(d_len > DCTP_EPS * DCTP_EPS)
02255             {
02256                 rvclNorm[ui_idx] *= 1.0 / sqrt(d_len);
02257             }
02258             else
02259             {
02260                 rvclNorm[ui_idx][0] = rvclNorm[ui_idx][1] = rvclNorm[ui_idx][2] = 0.0;
02261             }
02262
02263             // calculate texture coord
02264 //          rvclTexCoord[ ui_idx ].x() = rvclTexCoord[ ui_idx ].y() = 0.0;
02265             Vec2d temptexcoord(0, 0);
02266             i_u          = i_uspan - dimension_u;
02267             pd_nuls      = ppd_nu[0];
02268             pcl_temp_2dl = pcl_temp_2d;
02269
02270             for(i_l = 0; i_l <= dimension_u; ++i_l)
02271             {
02272                 (*pcl_temp_2dl)[0] = (*pcl_temp_2dl)[1] = 0.0;
02273                 i_v                = i_vspan - dimension_v;
02274                 pd_nvkr            = ppd_nv[0];
02275
02276                 for(i_k = 0; i_k <= dimension_v; ++i_k)
02277                 {
02278                     (*pcl_temp_2dl)[0] += (*cpvvclTexCP)[i_u][i_v].x() * *pd_nvkr;
02279                     (*pcl_temp_2dl)[1] += (*cpvvclTexCP)[i_u][i_v].y() * *pd_nvkr;
02280                     ++i_v;
02281                     ++pd_nvkr;
02282                 }
02283
02284                 ++i_u;
02285                 temptexcoord += *pcl_temp_2dl * *pd_nuls;
02286                 ++pd_nuls;
02287                 ++pcl_temp_2dl;
02288                 rvclTexCoord[ui_idx][0] = temptexcoord[0];
02289                 rvclTexCoord[ui_idx][1] = temptexcoord[1];
02290             }
02291         }
02292         else if(b_u_new)
02293         {
02294             for(i_k = 0; i_k <= 1; ++i_k)
02295             {
02296                 pcl_sklkl = &(vvcl_skl[i_k][0]);
02297
02298                 for(i_l = 0; i_l <= 1 - i_k; ++i_l)
02299                 {
02300                     (*pcl_sklkl)[0] = (*pcl_sklkl)[1] = (*pcl_sklkl)[2] = 0.0;
02301                     pcl_temps       = apcl_temp[i_k];
02302                     pd_nuls         = ppd_nu[i_l];
02303
02304                     for(i_s = 0; i_s <= dimension_u; ++i_s)
02305                     {
02306                         *pcl_sklkl += *pcl_temps * *pd_nuls;
02307                         ++pcl_temps;
02308                         ++pd_nuls;
02309                     }
02310
02311                     ++pcl_sklkl;
02312                 }
02313             }
02314
02315             RatSurfaceDerivs(vvcl_skl, vvcl_skl_eucl);
02316             //rvclPos[ ui_idx ] = aacl_skl[ 0 ][ 0 ];
02317             rvclPos[ui_idx][0] = vvcl_skl_eucl[0][0][0];
02318             rvclPos[ui_idx][1] = vvcl_skl_eucl[0][0][1];
02319             rvclPos[ui_idx][2] = vvcl_skl_eucl[0][0][2];
02320
02321             correctDers(rvclUV[ui_idx], vvcl_skl_eucl[0][0], vvcl_skl_eucl[1][0], vvcl_skl_eucl[0][1]);
02322 //          rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] );
02323 //          d_len = rvclNorm[ ui_idx ].squareLength( );
02324             Vec3d tempnorm = vvcl_skl_eucl[0][1].cross(vvcl_skl_eucl[1][0]);
02325             rvclNorm[ui_idx][0] = tempnorm[0];
02326             rvclNorm[ui_idx][1] = tempnorm[1];
02327             rvclNorm[ui_idx][2] = tempnorm[2];
02328             d_len               = tempnorm.squareLength();
02329             if(d_len > DCTP_EPS * DCTP_EPS)
02330             {
02331                 rvclNorm[ui_idx] *= 1.0 / sqrt(d_len);
02332             }
02333             else
02334             {
02335                 rvclNorm[ui_idx][0] = rvclNorm[ui_idx][1] = rvclNorm[ui_idx][2] = 0.0;
02336             }
02337
02338             // calculate texture coord
02339 //          rvclTexCoord[ ui_idx ][0] = rvclTexCoord[ ui_idx ][1] = 0.0;
02340             pd_nuls      = ppd_nu[0];
02341             pcl_temp_2dl = pcl_temp_2d;
02342             Vec2d temptexcoord(0, 0);
02343
02344             for(i_l = 0; i_l <= dimension_u; ++i_l)
02345             {
02346                 temptexcoord += *pcl_temp_2dl * *pd_nuls;
02347                 ++pd_nuls;
02348                 ++pcl_temp_2dl;
02349             }
02350
02351             rvclTexCoord[ui_idx][0] = temptexcoord[0];
02352             rvclTexCoord[ui_idx][1] = temptexcoord[1];
02353 #ifdef OSG_COUNT_COMP
02354             ++g_uiVSameComp;
02355 #endif
02356         }
02357         else
02358         {
02359             rvclPos[ui_idx]      = rvclPos[ui_idx - 1];
02360             rvclNorm[ui_idx]     = rvclNorm[ui_idx - 1];
02361             rvclTexCoord[ui_idx] = rvclTexCoord[ui_idx - 1];
02362 #ifdef OSG_COUNT_COMP
02363             ++g_uiSameComp;
02364 #endif
02365         }
02366 #ifdef OSG_COUNT_COMP
02367         ++g_uiTotalComp;
02368 #endif
02369     }
02370
02371     // clean up allocated memory
02372     if(i_uspan >= 0)
02373     {
02374         delete[]  ppd_nu[0];
02375         delete[]  ppd_nu[1];
02376         delete[]  ppd_nu;
02377     }
02378     if(i_vspan >= 0)
02379     {
02380         delete[]  ppd_nv[0];
02381         delete[]  ppd_nv[1];
02382         delete[]  ppd_nv;
02383     }
02384     delete[]  apcl_temp[0];
02385     delete[]  apcl_temp[1];
02386     delete[]  pcl_temp_2d;
02387
02388 #ifdef OSG_COUNT_COMP
02389     cerr << g_uiTotalComp << " " << g_uiVSameComp << " " << g_uiSameComp << endl;
02390 #endif
02391 }
02392
02393
02394 void BSplineTensorSurface::computeTex(std::vector<Vec2d> &                    rvclUV,
02395                                       std::vector<Pnt3f> &                    rvclPos,
02396                                       std::vector<Pnt2f> &                    rvclTexCoord,
02397                                       const std::vector<std::vector<Vec2d> > *cpvvclTexCP)
02398 {
02399     const unsigned int cui_cnt = rvclUV.size();
02400     unsigned int       ui_idx;
02401     double            *pd_nu;
02402     double            *pd_nv;
02403     int                i_span_u = -1;
02404     int                i_span_v = -1;
02405     unsigned int       ui_index_v;
02406     Vec4d             *pcl_temp  = new Vec4d[dimension_u + 1];
02407     Vec2d             *pcl_ttemp = new Vec2d[dimension_u + 1];
02408     unsigned int       ui_index_u;
02409     int                i_l;
02410     int                i_k;
02411     double            *pd_nul;
02412     double            *pd_nvk;
02413     bool               b_u_new;
02414     bool               b_v_new;
02415     Vec4d             *pcl_templ;
02416     Vec2d             *pcl_ttempl;
02417     int                i_old_u;
02418
02419     rvclPos.resize(cui_cnt);
02420     rvclTexCoord.resize(cui_cnt);
02421
02422     for(ui_idx = 0; ui_idx < cui_cnt; ++ui_idx)
02423     {
02424         if(ui_idx == 0)
02425         {
02426             i_span_u = basis_function_u.computeAllNonzero(rvclUV[ui_idx][0], dimension_u, pd_nu);
02427             i_span_v = basis_function_v.computeAllNonzero(rvclUV[ui_idx][1], dimension_v, pd_nv);
02428             b_u_new  = b_v_new = true;
02429         }
02430         else
02431         {
02432             if(osgAbs(rvclUV[ui_idx][0] - rvclUV[ui_idx - 1][0]) > DCTP_EPS)
02433             {
02434                 i_old_u = i_span_u;
02435                 if(i_span_u >= 0)
02436                     delete[]  pd_nu;
02437                 i_span_u = basis_function_u.computeAllNonzero(rvclUV[ui_idx][0], dimension_u, pd_nu);
02438                 b_u_new  = true;
02439                 b_v_new  = (i_old_u != i_span_u) ? true : false;
02440             }
02441             else
02442             {
02443                 b_u_new = false;
02444                 b_v_new = false;
02445             }
02446             if(osgAbs(rvclUV[ui_idx][1] - rvclUV[ui_idx - 1][1]) > DCTP_EPS)
02447             {
02448                 if(i_span_v >= 0)
02449                     delete[]  pd_nv;
02450                 i_span_v = basis_function_v.computeAllNonzero(rvclUV[ui_idx][1], dimension_v, pd_nv);
02451                 b_v_new  = true;
02452             }
02453         }
02454
02455         if( (i_span_u < 0) || (i_span_v < 0) )
02456         {
02457             rvclPos[ui_idx]      = Pnt3f(0.0, 0.0, 0.0);
02458             rvclTexCoord[ui_idx] = Pnt2f(0.0, 0.0);
02459         }
02460         else if(b_v_new)
02461         {
02462             ui_index_u = i_span_u - dimension_u;
02463             pd_nul     = pd_nu;
02464             pcl_templ  = pcl_temp;
02465             pcl_ttempl = pcl_ttemp;
02466             Vec4d tempposition(0.0, 0.0, 0.0, 0.0);
02467             Vec2d temptex(0, 0);
02468
02469             for(i_l = 0; i_l <= dimension_u; ++i_l)
02470             {
02471                 (*pcl_templ)  = Vec4d(0.0, 0.0, 0.0, 0.0);
02472                 (*pcl_ttempl) = Vec2d(0.0, 0.0);
02473                 ui_index_v    = i_span_v - dimension_v;
02474                 pd_nvk        = pd_nv;
02475
02476                 for(i_k = 0; i_k <= dimension_v; ++i_k)
02477                 {
02478                     *pcl_templ  += control_points[ui_index_u][ui_index_v] * *pd_nvk;
02479                     *pcl_ttempl += (*cpvvclTexCP)[ui_index_u][ui_index_v] * *pd_nvk;
02480                     ++ui_index_v;
02481                     ++pd_nvk;
02482                 }
02483
02484                 ++ui_index_u;
02485                 tempposition += *pcl_templ * *pd_nul;
02486                 temptex      += *pcl_ttempl * *pd_nul;
02487                 ++pd_nul;
02488                 ++pcl_templ;
02489                 ++pcl_ttempl;
02490             }
02491
02492             rvclPos[ui_idx][0]      = tempposition[0] / tempposition[3];
02493             rvclPos[ui_idx][1]      = tempposition[1] / tempposition[3];
02494             rvclPos[ui_idx][2]      = tempposition[2] / tempposition[3];
02495             rvclTexCoord[ui_idx][0] = temptex[0];
02496             rvclTexCoord[ui_idx][1] = temptex[1];
02497         }
02498         else if(b_u_new)
02499         {
02500             ui_index_u = i_span_u - dimension_u;
02501             pd_nul     = pd_nu;
02502             pcl_templ  = pcl_temp;
02503             pcl_ttempl = pcl_ttemp;
02504             Vec4d tempposition(0.0, 0.0, 0.0, 0.0);
02505             Vec2d temptex(0, 0);
02506
02507             for(i_l = 0; i_l <= dimension_u; ++i_l)
02508             {
02509                 ++ui_index_u;
02510                 tempposition += *pcl_templ * *pd_nul;
02511                 temptex      += *pcl_ttempl * *pd_nul;
02512                 ++pd_nul;
02513                 ++pcl_templ;
02514                 ++pcl_ttempl;
02515             }
02516
02517             rvclPos[ui_idx][0]      = tempposition[0] / tempposition[3];
02518             rvclPos[ui_idx][1]      = tempposition[1] / tempposition[3];
02519             rvclPos[ui_idx][2]      = tempposition[2] / tempposition[3];
02520             rvclTexCoord[ui_idx][0] = temptex[0];
02521             rvclTexCoord[ui_idx][1] = temptex[1];
02522 #ifdef OSG_COUNT_COMP
02523             ++g_uiVSameComp;
02524 #endif
02525         }
02526         else
02527         {
02528             rvclPos[ui_idx]      = rvclPos[ui_idx - 1];
02529             rvclTexCoord[ui_idx] = rvclTexCoord[ui_idx - 1];
02530 #ifdef OSG_COUNT_COMP
02531             ++g_uiSameComp;
02532 #endif
02533         }
02534 #ifdef OSG_COUNT_COMP
02535         ++g_uiTotalComp;
02536 #endif
02537     }
02538
02539     if(i_span_u >= 0)
02540         delete[]  pd_nu;
02541     if(i_span_v >= 0)
02542         delete[]  pd_nv;
02543     delete[]  pcl_temp;
02544     delete[]  pcl_ttemp;
02545
02546 #ifdef OSG_COUNT_COMP
02547     cerr << g_uiTotalComp << " " << g_uiVSameComp << " " << g_uiSameComp << endl;
02548 #endif
02549 }
02550
02551
02552 void BSplineTensorSurface::computeTexforTrimming(std::vector<Vec2d> &                    rvclUV,
02553                                                  std::vector<Vec2d> &                    rvclTexCoord,
02554                                                  const std::vector<std::vector<Vec2d> > *cpvvclTexCP)
02555 {
02556     const unsigned int cui_cnt = rvclUV.size();
02557     unsigned int       ui_idx;
02558     double            *pd_nu;
02559     double            *pd_nv;
02560     int                i_span_u = -1;
02561     int                i_span_v = -1;
02562     unsigned int       ui_index_v;
02563     Vec2d             *pcl_ttemp = new Vec2d[dimension_u + 1];
02564     unsigned int       ui_index_u;
02565     int                i_l;
02566     int                i_k;
02567     double            *pd_nul;
02568     double            *pd_nvk;
02569     bool               b_u_new;
02570     bool               b_v_new;
02571     Vec2d             *pcl_ttempl;
02572     int                i_old_u;
02573
02574     rvclTexCoord.resize(cui_cnt);
02575
02576     for(ui_idx = 0; ui_idx < cui_cnt; ++ui_idx)
02577     {
02578         if(ui_idx == 0)
02579         {
02580             i_span_u = basis_function_u.computeAllNonzero(rvclUV[ui_idx][0], dimension_u, pd_nu);
02581             i_span_v = basis_function_v.computeAllNonzero(rvclUV[ui_idx][1], dimension_v, pd_nv);
02582             b_u_new  = b_v_new = true;
02583         }
02584         else
02585         {
02586             if(osgAbs(rvclUV[ui_idx][0] - rvclUV[ui_idx - 1][0]) > DCTP_EPS)
02587             {
02588                 i_old_u = i_span_u;
02589                 if(i_span_u >= 0)
02590                     delete[]  pd_nu;
02591                 i_span_u = basis_function_u.computeAllNonzero(rvclUV[ui_idx][0], dimension_u, pd_nu);
02592                 b_u_new  = true;
02593                 b_v_new  = (i_old_u != i_span_u) ? true : false;
02594             }
02595             else
02596             {
02597                 b_u_new = false;
02598                 b_v_new = false;
02599             }
02600             if(osgAbs(rvclUV[ui_idx][1] - rvclUV[ui_idx - 1][1]) > DCTP_EPS)
02601             {
02602                 if(i_span_v >= 0)
02603                     delete[]  pd_nv;
02604                 i_span_v = basis_function_v.computeAllNonzero(rvclUV[ui_idx][1], dimension_v, pd_nv);
02605                 b_v_new  = true;
02606             }
02607         }
02608
02609         if( (i_span_u < 0) || (i_span_v < 0) )
02610         {
02611             rvclTexCoord[ui_idx][0] = rvclTexCoord[ui_idx][1] = 0.0;
02612         }
02613         else if(b_v_new)
02614         {
02615             ui_index_u              = i_span_u - dimension_u;
02616             pd_nul                  = pd_nu;
02617             pcl_ttempl              = pcl_ttemp;
02618             rvclTexCoord[ui_idx][0] = rvclTexCoord[ui_idx][1] = 0.0;
02619
02620             for(i_l = 0; i_l <= dimension_u; ++i_l)
02621             {
02622                 (*pcl_ttempl)[0] = (*pcl_ttempl)[1] = 0.0;
02623                 ui_index_v       = i_span_v - dimension_v;
02624                 pd_nvk           = pd_nv;
02625
02626                 for(i_k = 0; i_k <= dimension_v; ++i_k)
02627                 {
02628                     *pcl_ttempl += (*cpvvclTexCP)[ui_index_u][ui_index_v] * *pd_nvk;
02629                     ++ui_index_v;
02630                     ++pd_nvk;
02631                 }
02632
02633                 ++ui_index_u;
02634                 rvclTexCoord[ui_idx] += *pcl_ttempl * *pd_nul;
02635                 ++pd_nul;
02636                 ++pcl_ttempl;
02637             }
02638         }
02639         else if(b_u_new)
02640         {
02641             ui_index_u              = i_span_u - dimension_u;
02642             pd_nul                  = pd_nu;
02643             pcl_ttempl              = pcl_ttemp;
02644             rvclTexCoord[ui_idx][0] = rvclTexCoord[ui_idx][1] = 0.0;
02645
02646             for(i_l = 0; i_l <= dimension_u; ++i_l)
02647             {
02648                 ++ui_index_u;
02649                 rvclTexCoord[ui_idx] += *pcl_ttempl * *pd_nul;
02650                 ++pd_nul;
02651                 ++pcl_ttempl;
02652             }
02653
02654 #ifdef OSG_COUNT_COMP
02655             ++g_uiVSameComp;
02656 #endif
02657         }
02658         else
02659         {
02660             rvclTexCoord[ui_idx] = rvclTexCoord[ui_idx - 1];
02661 #ifdef OSG_COUNT_COMP
02662             ++g_uiSameComp;
02663 #endif
02664         }
02665 #ifdef OSG_COUNT_COMP
02666         ++g_uiTotalComp;
02667 #endif
02668     }
02669
02670     if(i_span_u >= 0)
02671         delete[]  pd_nu;
02672     if(i_span_v >= 0)
02673         delete[]  pd_nv;
02674     delete[]  pcl_ttemp;
02675
02676 #ifdef OSG_COUNT_COMP
02677     cerr << g_uiTotalComp << " " << g_uiVSameComp << " " << g_uiSameComp << endl;
02678 #endif
02679 }
02680
02681
02682 void BSplineTensorSurface::correctDers(const Vec2d cclUV, const Vec3d cclPos, Vec3d &rclDU, Vec3d &rclDV)
02683 {
02684     return;
02685     // TODO: this tried to correct 0 derivs, but it was
02686     // TODO: only half-implemented plus the approach didn't really work.
02687     // TODO: implement something like this someday...
02688 #if 0
02689     if(rclDU.squareLength() < DCTP_EPS)
02690     {
02691         // du is zero
02692         Vec3d  cl_temp;
02693         Vec3d  cl_low;
02694         Vec3d  cl_high;
02695         Vec2d  cl_param;
02696         double d_step;
02697         double d_minpar;
02698         double d_maxpar;
02699         int    i_err;
02700
02701         getParameterInterval_U(d_minpar, d_maxpar);
02702
02703         // step in -u direction
02704         cl_param = cclUV;
02705         cl_low   = cclPos;
02706         d_step   = cl_param[0] - d_minpar;
02707         while(d_step > DCTP_EPS)
02708         {
02709             d_step      *= 0.5;
02710             cl_param[0] -= d_step;
02711             cl_temp      = compute(cl_param, i_err);
02712             if( (cl_temp - cclPos).squareLength() > DCTP_EPS)
02713             {
02714                 cl_low       = cl_temp;
02715                 cl_param[0] += d_step;
02716             }
02717 /*          else if( ( cl_temp - cclPos ).squareLength( ) > ( cl_low - cclPos ).squareLength( ) )
02718             {
02719                 cl_low = cl_temp;
02720             }*/
02721         }
02722
02723         // step in +u direction
02724         cl_param = cclUV;
02725         cl_high  = cclPos;
02726         d_step   = d_maxpar - cl_param[0];
02727         while(d_step > DCTP_EPS)
02728         {
02729             d_step      *= 0.5;
02730             cl_param[0] += d_step;
02731             cl_temp      = compute(cl_param, i_err);
02732             if( (cl_temp - cclPos).squareLength() > DCTP_EPS)
02733             {
02734                 cl_high      = cl_temp;
02735                 cl_param[0] -= d_step;
02736             }
02737 /*          else if( ( cl_temp - cclPos ).squareLength( ) > ( cl_high - cclPos ).squareLength( ) )
02738             {
02739                 cl_high = cl_temp;
02740             }*/
02741         }
02742
02743         // calculate dirivative
02744 //      std::cerr << "du: " << rclDU;
02745         if( (cl_high - cl_low).squareLength() > DCTP_EPS)
02746         {
02747             rclDU = cl_high - cl_low;
02748         }
02749         else
02750         {
02751             rclDU[0] = rclDU[1] = rclDU[2] = 0.0;
02752         }
02753 //      std::cerr << " -> " << rclDU << std::endl;
02754     }
02755
02756     if(rclDV.squareLength() < DCTP_EPS)
02757     {
02758         // dv is zero
02759         Vec3d  cl_temp;
02760         Vec3d  cl_low;
02761         Vec3d  cl_high;
02762         Vec2d  cl_param;
02763         double d_step;
02764         double d_minpar;
02765         double d_maxpar;
02766         int    i_err;
02767
02768         getParameterInterval_V(d_minpar, d_maxpar);
02769
02770         // step in -v direction
02771         cl_param = cclUV;
02772         cl_low   = cclPos;
02773         d_step   = cl_param[1] - d_minpar;
02774         while(d_step > DCTP_EPS)
02775         {
02776             d_step      *= 0.5;
02777             cl_param[1] -= d_step;
02778             cl_temp      = compute(cl_param, i_err);
02779             if( (cl_temp - cclPos).squareLength() > DCTP_EPS)
02780             {
02781                 cl_low       = cl_temp;
02782                 cl_param[1] += d_step;
02783             }
02784 /*          else if( ( cl_temp - cclPos ).squareLength( ) > ( cl_low - cclPos ).squareLength( ) )
02785             {
02786                 cl_low = cl_temp;
02787             }*/
02788         }
02789
02790         // step in +v direction
02791         cl_param = cclUV;
02792         cl_high  = cclPos;
02793         d_step   = d_maxpar - cl_param[1];
02794         while(d_step > DCTP_EPS)
02795         {
02796             d_step      *= 0.5;
02797             cl_param[1] += d_step;
02798             cl_temp      = compute(cl_param, i_err);
02799             if( (cl_temp - cclPos).squareLength() > DCTP_EPS)
02800             {
02801                 cl_high      = cl_temp;
02802                 cl_param[1] -= d_step;
02803             }
02804 /*          else if( ( cl_temp - cclPos ).squareLength( ) > ( cl_high - cclPos ).squareLength( ) )
02805             {
02806                 cl_high = cl_temp;
02807             }*/
02808         }
02809
02810         // calculate dirivative
02811 //      std::cerr << "dv: " << rclDV;
02812         if( (cl_high - cl_low).squareLength() > DCTP_EPS)
02813         {
02814             rclDV = cl_high - cl_low;
02815         }
02816         else
02817         {
02818             rclDV[0] = rclDV[1] = rclDV[2] = 0.0;
02819         }
02820 //      std::cerr << " -> " << rclDV << std::endl;
02821     }
02822 #endif
02823 }