00001 #include <config.h>
00002 #include <fstream>
00003
00004 #ifdef _WINDOWS
00005 # include <windows.h>
00006 # include <GL/gl.h>
00007 #else
00008 # include <qgl.h>
00009 #endif
00010
00011 #include <cmath>
00012
00013
00014 #ifdef _WINDOWS
00015 # include <float.h>
00016 # define isinf(x) (_finite(x) == 0)
00017 # define isnan(x) _isnan(x)
00018 #endif
00019
00020 #include "bsurface.h"
00021
00022 using util::Vector;
00023 using util::Matrix;
00024
00025 using std::ifstream;
00026 using std::ofstream;
00027 #define C_SEG 20
00028 #define C_SCALE 0.01
00029 #define d_step 0.01
00030 #define l_step 0.1
00031 #define MRES_OFF 0.01
00032 #define MIN_HEIGHT 10
00033 #define MIN_WIDTH 10
00034
00035 #define err_tol 0.000001
00036 #define max_it 20
00037 #define inner_loop_max_it 100
00038
00039 using std::cout;
00040 using std::endl;
00041
00042 namespace util
00043 {
00044
00045 namespace Shapes
00046 {
00047
00048 void BSplineSurface::Load(const char* fnm, double scale, int TextureId, int divU, int divV)
00049 {
00050 _TextureId=TextureId;
00051 _scale=scale;
00052 _divU=divU;
00053 _divV=divV;
00054 LoadPatch(fnm);
00055 precomputed=false;
00056 }
00057
00058 void BSplineSurface::Reread()
00059 {
00060 _divU = _divV = -1;
00061 LoadPatch(_fname.c_str());
00062 precomputed=false;
00063 }
00064
00065 void BSplineSurface::BoundingBox(double &x1,double &y1, double &z1, double &x2, double &y2, double &z2)
00066 {
00067 x1=x2=Control_points[0][0][0][0];
00068 y1=y2=Control_points[0][0][0][1];
00069 z1=z2=Control_points[0][0][0][2];
00070
00071 for (unsigned int i=0; i<Control_points[0].size(); i++)
00072 for (unsigned int j=0; j<Control_points[0][0].size(); j++) {
00073
00074 if(Control_points[0][i][j][0]<x1)
00075 x1=Control_points[0][i][j][0];
00076
00077 if(Control_points[0][i][j][1]<y1)
00078 y1=Control_points[0][i][j][1];
00079
00080 if(Control_points[0][i][j][2]<z1)
00081 z1=Control_points[0][i][j][2];
00082
00083 if(Control_points[0][i][j][0]>x2)
00084 x2=Control_points[0][i][j][0];
00085
00086 if(Control_points[0][i][j][1]>y2)
00087 y2=Control_points[0][i][j][1];
00088
00089 if(Control_points[0][i][j][2]>z2)
00090 z2=Control_points[0][i][j][2];
00091 }
00092 }
00093
00094 void BSplineSurface::Transform(Matrix3d M,double x, double y, double z)
00095 {
00096 Point3d D;
00097 D[0]=x;
00098 D[1]=y;
00099 D[2]=z;
00100
00101 for (unsigned int i=0; i<Control_points[0].size(); i++)
00102 for (unsigned int j=0; j<Control_points[0][0].size(); j++) {
00103
00104
00105 Control_points[0][i][j]=M*(Control_points[0][i][j]);
00106 Control_points[0][i][j]=Control_points[0][i][j]+D;
00107 }
00108
00109 precomputed=false;
00110 }
00111
00112 void BSplineSurface::Draw(int uDiv, int vDiv)
00113 {
00114 if(!precomputed)
00115 Precompute(uDiv,vDiv);
00116
00117
00118
00119
00120 for (int i=0; i<_divU; ++i) {
00121 const double u1 = 1.0*i/uDiv;
00122 const double u2 = 1.0*(i+1)/uDiv;
00123
00124 if(!s_mesh)
00125 glBegin(GL_TRIANGLES);
00126
00127 for (int j=0; j<_divV; ++j) {
00128 bool flip=false;
00129 int id1 = PtId(i, j);
00130 int id2 = PtId(i+1,j);
00131 int id3 = PtId(i+1,j+1);
00132 int id4 = PtId(i,j+1);
00133 const double v1 = 1.0*j/vDiv;
00134 const double v2 = 1.0*(j+1)/vDiv;
00135
00136
00137
00138
00139 if(s_mesh)
00140 glBegin(GL_LINES);
00141
00142 if(contraction){
00143 if( psurf && _ctract[id4]<0)
00144 glColor3f(0.8*(-_ctract[id4]/(-c_min))+0.2,0.2,0.2);
00145 else
00146 glColor3f(0.2,0.8*(_ctract[id4]/(c_max))+0.2,0.2);
00147 }
00148
00149 glTexCoord2d(u1, v2);
00150 glNormal3d(_nrml[id4][0],_nrml[id4][1],_nrml[id4][2]);
00151 glVertex3d(_vrtx[id4][0],_vrtx[id4][1],_vrtx[id4][2]);
00152
00153
00154 if(contraction){
00155 if( psurf && _ctract[id1]<0)
00156 glColor3f(0.8*(-_ctract[id1]/(-c_min))+0.2,0.2,0.2);
00157 else
00158 glColor3f(0.2,0.8*(_ctract[id1]/(c_max))+0.2,0.2);
00159 }
00160
00161
00162 glTexCoord2d(u1, v1);
00163 glNormal3d(_nrml[id1][0],_nrml[id1][1],_nrml[id1][2]);
00164 glVertex3d(_vrtx[id1][0],_vrtx[id1][1],_vrtx[id1][2]);
00165
00166
00167 if(_nrml[id4]*_nrml[id2]>_nrml[id3]*_nrml[id1]) {
00168
00169 if(contraction){
00170 if( psurf && _ctract[id2]<0)
00171 glColor3f(0.8*(-_ctract[id2]/(-c_min))+0.2,0.2,0.2);
00172 else
00173 glColor3f(0.2,0.8*(_ctract[id2]/(c_max))+0.2,0.2);
00174 }
00175
00176
00177 flip=true;
00178 glTexCoord2d(u2, v1);
00179 glNormal3d(_nrml[id2][0],_nrml[id2][1],_nrml[id2][2]);
00180 glVertex3d(_vrtx[id2][0],_vrtx[id2][1],_vrtx[id2][2]);
00181
00182 if(s_mesh) {
00183
00184
00185 if(contraction){
00186 if( psurf && _ctract[id4]<0)
00187 glColor3f(0.8*(-_ctract[id4]/(-c_min))+0.2,0.2,0.2);
00188 else
00189 glColor3f(0.2,0.8*(_ctract[id4]/(c_max))+0.2,0.2);
00190 }
00191
00192
00193 glTexCoord2d(u1, v2);
00194 glNormal3d(_nrml[id4][0],_nrml[id4][1],_nrml[id4][2]);
00195 glVertex3d(_vrtx[id4][0],_vrtx[id4][1],_vrtx[id4][2]);
00196 }
00197
00198
00199
00200 if(contraction){
00201 if( psurf && _ctract[id4]<0)
00202 glColor3f(0.8*(-_ctract[id4]/(-c_min))+0.2,0.2,0.2);
00203 else
00204 glColor3f(0.2,0.8*(_ctract[id4]/(c_max))+0.2,0.2);
00205 }
00206
00207
00208 glTexCoord2d(u1, v2);
00209 glNormal3d(_nrml[id4][0],_nrml[id4][1],_nrml[id4][2]);
00210 glVertex3d(_vrtx[id4][0],_vrtx[id4][1],_vrtx[id4][2]);
00211
00212 } else {
00213
00214
00215 if(contraction){
00216 if( psurf && _ctract[id3]<0)
00217 glColor3f(0.8*(-_ctract[id3]/(-c_min))+0.2,0.2,0.2);
00218 else
00219 glColor3f(0.2,0.8*(_ctract[id3]/(c_max))+0.2,0.2);
00220 }
00221
00222
00223 glTexCoord2d(u2, v2);
00224 glNormal3d(_nrml[id3][0],_nrml[id3][1],_nrml[id3][2]);
00225 glVertex3d(_vrtx[id3][0],_vrtx[id3][1],_vrtx[id3][2]);
00226
00227 if(s_mesh) {
00228
00229 if(contraction){
00230 if( psurf && _ctract[id4]<0)
00231 glColor3f(0.8*(-_ctract[id4]/(-c_min))+0.2,0.2,0.2);
00232 else
00233 glColor3f(0.2,0.8*(_ctract[id4]/(c_max))+0.2,0.2);
00234 }
00235
00236
00237 glTexCoord2d(u1, v2);
00238 glNormal3d(_nrml[id4][0],_nrml[id4][1],_nrml[id4][2]);
00239 glVertex3d(_vrtx[id4][0],_vrtx[id4][1],_vrtx[id4][2]);
00240 }
00241
00242
00243 if(contraction){
00244 if( psurf && _ctract[id1]<0)
00245 glColor3f(0.8*(-_ctract[id1]/(-c_min))+0.2,0.2,0.2);
00246 else
00247 glColor3f(0.2,0.8*(_ctract[id1]/(c_max))+0.2,0.2);
00248 }
00249
00250
00251 glTexCoord2d(u1, v1);
00252 glNormal3d(_nrml[id1][0],_nrml[id1][1],_nrml[id1][2]);
00253 glVertex3d(_vrtx[id1][0],_vrtx[id1][1],_vrtx[id1][2]);
00254 }
00255
00256
00257 if(contraction){
00258 if( psurf && _ctract[id2]<0)
00259 glColor3f(0.8*(-_ctract[id2]/(-c_min))+0.2,0.2,0.2);
00260 else
00261 glColor3f(0.2,0.8*(_ctract[id2]/(c_max))+0.2,0.2);
00262 }
00263
00264
00265 glTexCoord2d(u2, v1);
00266 glNormal3d(_nrml[id2][0],_nrml[id2][1],_nrml[id2][2]);
00267 glVertex3d(_vrtx[id2][0],_vrtx[id2][1],_vrtx[id2][2]);
00268
00269
00270 if(contraction){
00271 if( psurf && _ctract[id3]<0)
00272 glColor3f(0.8*(-_ctract[id3]/(-c_min))+0.2,0.2,0.2);
00273 else
00274 glColor3f(0.2,0.8*(_ctract[id3]/(c_max))+0.2,0.2);
00275 }
00276
00277
00278
00279 glTexCoord2d(u2, v2);
00280 glNormal3d(_nrml[id3][0],_nrml[id3][1],_nrml[id3][2]);
00281 glVertex3d(_vrtx[id3][0],_vrtx[id3][1],_vrtx[id3][2]);
00282
00283 if(s_mesh) {
00284
00285 if(flip) {
00286
00287 if(contraction){
00288 if( psurf && _ctract[id4]<0)
00289 glColor3f(0.8*(-_ctract[id4]/(-c_min))+0.2,0.2,0.2);
00290 else
00291 glColor3f(0.2,0.8*(_ctract[id4]/(c_max))+0.2,0.2);
00292 }
00293
00294
00295 glTexCoord2d(u1, v2);
00296 glNormal3d(_nrml[id4][0],_nrml[id4][1],_nrml[id4][2]);
00297 glVertex3d(_vrtx[id4][0],_vrtx[id4][1],_vrtx[id4][2]);
00298 } else {
00299
00300
00301 if(contraction){
00302 if( psurf && _ctract[id1]<0)
00303 glColor3f(0.8*(-_ctract[id1]/(-c_min))+0.2,0.2,0.2);
00304 else
00305 glColor3f(0.2,0.8*(_ctract[id1]/(c_max))+0.2,0.2);
00306 }
00307
00308
00309 glTexCoord2d(u1, v1);
00310 glNormal3d(_nrml[id1][0],_nrml[id1][1],_nrml[id1][2]);
00311 glVertex3d(_vrtx[id1][0],_vrtx[id1][1],_vrtx[id1][2]);
00312 }
00313 glEnd();
00314 }
00315 }
00316 glEnd();
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 }
00337
00338 void BSplineSurface::Precompute(int uDiv, int vDiv)
00339 {
00340 unsigned int newsize = (uDiv+1)*(vDiv+1);
00341 if (_vrtx.size() != newsize) {
00342 _vrtx.resize(newsize);
00343 _nrml.resize(newsize);
00344
00345 _ctract.resize(newsize);
00346 }
00347 _divU = uDiv;
00348 _divV = vDiv;
00349
00350 const double du = 1.0/uDiv*(n_u-degree);
00351 const double dv = 1.0/vDiv*(n_v-degree);
00352 c_min=c_max=0;
00353 for (int i=0; i<=_divU; ++i) {
00354 const double u = 3.0+i*du;
00355 for (int j=0; j<=_divV; ++j) {
00356 const int id = PtId(i, j);
00357 const double v = 3.0+j*dv;
00358 _vrtx[id] = Eval(u, v);
00359 _nrml[id] = NormalEval(u, v);
00360 if( psurf ){
00361 _ctract[id]=HasContracted(psurf, u, v);
00362 if(_ctract[id]<c_min)
00363 c_min=_ctract[id];
00364 if(_ctract[id]>c_max)
00365 c_max=_ctract[id];
00366
00367
00368 }
00369 else
00370 _ctract[id]=0;
00371 }
00372 }
00373 if(c_max>fabs(c_min))
00374 c_min=-c_max;
00375 else
00376 c_max=-c_min;
00377 precomputed=true;
00378 }
00379
00380 BSplineSurface::BSplineSurface() : _TextureId(-1)
00381 {
00382 degree=3;
00383 wireframe=true;
00384 n_u=MIN_HEIGHT;
00385 n_v=MIN_WIDTH;
00386 selected[0]=selected[1]=selected_level=0;
00387 periodic=false;
00388 Reset(n_u,n_v);
00389 lines=true;
00390 u_prec=l_step;
00391 v_prec=l_step;
00392
00393 poly_line[0]=1.0;
00394 poly_line[1]=1.0;
00395
00396 s_mesh=false;
00397 disp_normal=false;
00398 disp_c_mesh=true;
00399 contraction=false;
00400 precomputed=false;
00401 c_min=0;
00402 c_max=0;
00403 psurf=NULL;
00404 }
00405
00406 BSplineSurface::~BSplineSurface()
00407 {
00408 }
00409
00410 BSplineSurface::BSplineSurface(const BSplineSurface &B)
00411 {
00412 _TextureId=B._TextureId;
00413 _scale=B._scale;
00414 _divU=B._divU;
00415 _divV=B._divV;
00416 if(B.precomputed) {
00417 _vrtx=B._vrtx;
00418 _nrml=B._nrml;
00419 precomputed=B.precomputed;
00420 }
00421 else
00422 precomputed=false;
00423
00424 wireframe=true;
00425
00426 degree=3;
00427 wireframe=true;
00428 n_u=B.n_u;
00429 n_v=B.n_v;
00430 selected[0]=selected[1]=selected_level=0;
00431 periodic=false;
00432 Reset(n_u,n_v);
00433 lines=true;
00434 contraction = B.contraction;
00435 psurf = B.psurf;
00436
00437 for(unsigned int i=0;i<Control_points[0].size();i++)
00438 for(unsigned int j=0;j<Control_points[0][0].size();j++)
00439 Control_points[0][i][j]=B.Control_points[0][i][j];
00440 }
00441
00442 bool BSplineSurface::SavePatch(const char *fname)
00443 {
00444 bool saved=false;
00445
00446 ofstream File;
00447
00448 File.open(fname);
00449
00450 File<<n_u<<" ";
00451
00452 File<<n_v<<std::endl;
00453
00454 File<<3<<std::endl;
00455
00456 for(int i=0;i<n_u;i++) {
00457 for(int j=0;j<n_v;j++) {
00458
00459 File<<Control_points[0][i][j][0]<<" "<<Control_points[0][i][j][1]<<" "<<Control_points[0][i][j][2]<<std::endl;
00460
00461 }
00462 }
00463 return saved;
00464 }
00465
00466 bool BSplineSurface::LoadPatch(const char *fname)
00467 {
00468 bool loaded=false;
00469 int degree;
00470 ifstream File;
00471
00472 File.open(fname);
00473 _f_name=fname;
00474
00475 File>>n_u;
00476 File>>n_v;
00477 File>>degree;
00478
00479 if(degree!=3)
00480 std::cout<<"Warning: "<<fname<<" is not a cubic patch"<<std::endl;
00481
00482 Reset(n_u,n_v);
00483
00484 for(int i=0;i<n_u;i++) {
00485 for(int j=0;j<n_v;j++) {
00486
00487 File>>Control_points[0][i][j][0]>>Control_points[0][i][j][1]>>Control_points[0][i][j][2];
00488
00489 }
00490 }
00491 return loaded;
00492 }
00493
00494 void BSplineSurface::Reset(int u, int v)
00495 {
00496 vector<Point3d >*c_points;
00497 vector< vector<Point3d > > *cc_points;
00498
00499 n_u=u;
00500 n_v=v;
00501 footprint.clear();
00502 int *cv=new int[4];
00503 footprint.push_back(cv);
00504
00505 selected[0]=selected[1]=0;
00506 selected_level=0;
00507 selected_region.clear();
00508
00509 Control_points.clear();
00510
00511 Details.clear();
00512
00513 cc_points= new vector< vector<Point3d > >;
00514
00515 Point3d p;
00516
00517 for(int i=0;i<u;i++) {
00518 c_points = new vector< Point3d >;
00519 for(int j=0;j<v;j++) {
00520
00521 p[0]=(float)i/u-0.5+err_tol;
00522 p[1]=(float)j/v-0.5+err_tol;
00523 p[2]=0;
00524
00525 c_points->push_back(p);
00526
00527 }
00528 cc_points->push_back(*c_points);
00529 delete c_points;
00530 }
00531 Control_points.push_back(*cc_points);
00532
00533 delete cc_points;
00534
00535
00536 }
00537
00538
00539 float BSplineSurface::HasContracted(BSplineSurface * b, float u, float v){
00540
00541 Point3d pu= PartialU(u,v);
00542 Point3d bpu= b->PartialU(u,v);
00543 Point3d pv= PartialV(u,v);
00544 Point3d bpv= b->PartialV(u,v);
00545
00546 pu=pu ^ pv;
00547 bpu=bpu ^ bpv;
00548 float ret=(pu.norm()/bpu.norm());
00549 ret-=1;
00550
00551
00552 return ret;
00553 }
00554
00555 void BSplineSurface::HalveU()
00556 {
00557 vector< Point3d > temp;
00558
00559 Point3d val;
00560
00561 vector< vector< Point3d > > c_points;
00562 vector< vector< Point3d > > d_points;
00563 int *cr=new int[4];
00564
00565 if( (Control_points[Control_points.size()-1].size()+3 )/2 >=MIN_HEIGHT) {
00566
00567 footprint.push_back(cr);
00568 val=val*0;
00569
00570 for(unsigned int j=0;j<Control_points[Control_points.size()-1][0].size();j++)
00571 temp.push_back(val);
00572
00573 for(unsigned int i=0;i<( Control_points[Control_points.size()-1].size()+3)/2;i++) {
00574 c_points.push_back(temp);
00575 d_points.push_back(temp);
00576 }
00577
00578 Control_points.push_back(c_points);
00579 Details.push_back(d_points);
00580
00581 for(unsigned int i=0;i<footprint.size();i++) {
00582
00583 footprint[i][1]=footprint[i][3]=10000000;
00584 footprint[i][0]=footprint[i][2]=-1;
00585
00586 }
00587 footprint[footprint.size()-2][1]=0;
00588 footprint[footprint.size()-2][0]=
00589 (int)Control_points[Control_points.size()-2].size()-1;
00590 footprint[footprint.size()-2][3]=0;
00591 footprint[footprint.size()-2][2]=
00592 (int)Control_points[Control_points.size()-2][0].size()-1;
00593
00594 footprint[footprint.size()-1][1]=0;
00595 footprint[footprint.size()-1][0]=
00596 (int)Control_points[Control_points.size()-1].size()-1;
00597 footprint[footprint.size()-1][3]=0;
00598 footprint[footprint.size()-1][2]=
00599 (int)Control_points[Control_points.size()-1][0].size()-1;
00600
00601
00602 UpdateFootprint();
00603 }
00604 }
00605
00606 void BSplineSurface::DoubleV()
00607 {
00608 vector< Point3d > temp;
00609
00610 Point3d val;
00611 int line_size;
00612 vector< vector< Point3d > > c_points;
00613 vector< vector< Point3d > > d_points;
00614 int *cr=new int[4];
00615
00616 footprint.push_back(cr);
00617
00618 for(unsigned int k=0;k<Control_points[0].size();k++) {
00619
00620 temp.clear();
00621
00622 temp.push_back(Control_points[0][k][0]);
00623
00624 val=Control_points[0][k][0]*(1.0/2.0)
00625 +Control_points[0][k][1]*(1.0/2.0);
00626
00627 temp.push_back(val);
00628
00629 val=Control_points[0][k][1]*(3.0/4.0)
00630 +Control_points[0][k][2]*(1.0/4.0);
00631
00632 temp.push_back(val);
00633
00634 val=Control_points[0][k][1]*(3.0/16.0)
00635 +Control_points[0][k][2]*(11.0/16.0)
00636 +Control_points[0][k][3]*(1.0/8.0);
00637
00638 temp.push_back(val);
00639
00640 val=Control_points[0][k][2]*(1.0/2.0)
00641 +Control_points[0][k][3]*(1.0/2.0);
00642
00643 temp.push_back(val);
00644
00645 line_size= (int)Control_points[0][k].size()-1;
00646
00647 for(int i=3;i<line_size-2;i++) {
00648 val=Control_points[0][k][i-1]*(1.0/8.0)
00649 +Control_points[0][k][i]*(3.0/4.0)
00650 +Control_points[0][k][i+1]*(1.0/8.0);
00651
00652 temp.push_back(val);
00653
00654
00655
00656 val= Control_points[0][k][i]*(1.0/2.0)
00657 +Control_points[0][k][i+1]*(1.0/2.0);
00658 temp.push_back(val);
00659
00660
00661 }
00662
00663
00664
00665
00666
00667 val=Control_points[0][k][line_size-1]*(3.0/16.0)
00668 +Control_points[0][k][line_size-2]*(11.0/16.0)
00669 +Control_points[0][k][line_size-3]*(1.0/8.0);
00670
00671 temp.push_back(val);
00672
00673 val=Control_points[0][k][line_size-2]*(1.0/4.0)
00674 +Control_points[0][k][line_size-1]*(3.0/4.0);
00675
00676 temp.push_back(val);
00677
00678 val=Control_points[0][k][line_size]*(1.0/2.0)
00679 +Control_points[0][k][line_size-1]*(1.0/2.0);
00680
00681 temp.push_back(val);
00682
00683 temp.push_back(Control_points[0][k][line_size]);
00684
00685 c_points.push_back(temp);
00686
00687
00688 }
00689 Control_points.insert(Control_points.begin(),c_points);
00690 n_v=(int)Control_points[0][0].size();
00691 n_u=(int)Control_points[0].size();
00692 temp.clear();
00693 val=val*0;
00694
00695 for(int i=0;i<n_v;i++)
00696 temp.push_back(val);
00697
00698 for(int i=0;i<n_u;i++)
00699 d_points.push_back(temp);
00700
00701 Details.insert(Details.begin(),d_points);
00702
00703 for(unsigned int i=0;i<footprint.size();i++) {
00704
00705 footprint[i][1]=footprint[i][3]=10000000;
00706 footprint[i][0]=footprint[i][2]=-1;
00707
00708 }
00709 CalcPreImage(selected[0],selected[1],selected_level);
00710
00711 }
00712
00713 void BSplineSurface::HalveV()
00714 {
00715 vector< Point3d > temp;
00716
00717 Point3d val;
00718
00719 vector< vector< Point3d > > c_points;
00720 vector< vector< Point3d > > d_points;
00721 int *cr=new int[4];
00722
00723 if( (Control_points[Control_points.size()-1][0].size()+3) /2 >=MIN_WIDTH) {
00724 footprint.push_back(cr);
00725 val=val*0;
00726
00727 for(unsigned int i=0;i<( Control_points[Control_points.size()-1][0].size()+3)/2;i++)
00728 temp.push_back(val);
00729
00730 for(unsigned int j=0;j<Control_points[Control_points.size()-1].size();j++) {
00731 c_points.push_back(temp);
00732 d_points.push_back(temp);
00733 }
00734
00735 Control_points.push_back(c_points);
00736 Details.push_back(d_points);
00737
00738 for(unsigned int i=0;i<footprint.size();i++) {
00739 footprint[i][1]=footprint[i][3]=10000000;
00740 footprint[i][0]=footprint[i][2]=-1;
00741 }
00742
00743 footprint[footprint.size()-2][1]=0;
00744 footprint[footprint.size()-2][0]=
00745 (int)Control_points[Control_points.size()-2].size()-1;
00746 footprint[footprint.size()-2][3]=0;
00747 footprint[footprint.size()-2][2]=
00748 (int)Control_points[Control_points.size()-2][0].size()-1;
00749
00750 footprint[footprint.size()-1][1]=0;
00751 footprint[footprint.size()-1][0]=
00752 (int)Control_points[Control_points.size()-1].size()-1;
00753 footprint[footprint.size()-1][3]=0;
00754 footprint[footprint.size()-1][2]=
00755 (int)Control_points[Control_points.size()-1][0].size()-1;
00756
00757
00758 UpdateFootprint();
00759 }
00760 }
00761
00762
00763 void BSplineSurface::DoubleU() {
00764 vector< Point3d > temp;
00765 vector< vector< Point3d > >temp_grid;
00766 vector< vector< Point3d > > c_points;
00767 vector< vector< Point3d > > d_points;
00768 int *cr=new int[4];
00769
00770 footprint.push_back(cr);
00771
00772 Point3d val;
00773 int line_size;
00774
00775 for(unsigned int k=0;k<Control_points[0][0].size();k++) {
00776
00777 temp.clear();
00778
00779 temp.push_back(Control_points[0][0][k]);
00780
00781 val=Control_points[0][0][k]*(1.0/2.0)
00782 +Control_points[0][1][k]*(1.0/2.0);
00783
00784 temp.push_back(val);
00785
00786 val=Control_points[0][1][k]*(3.0/4.0)
00787 +Control_points[0][2][k]*(1.0/4.0);
00788
00789 temp.push_back(val);
00790
00791 val=Control_points[0][1][k]*(3.0/16.0)
00792 +Control_points[0][2][k]*(11.0/16.0)
00793 +Control_points[0][3][k]*(1.0/8.0);
00794
00795 temp.push_back(val);
00796
00797
00798
00799
00800
00801
00802 line_size=(int)Control_points[0].size()-1;
00803
00804 for(int i=2;i<line_size-3;i++) {
00805 val= Control_points[0][i][k]*(1.0/2.0)
00806 +Control_points[0][i+1][k]*(1.0/2.0);
00807 temp.push_back(val);
00808
00809 val=Control_points[0][i][k]*(1.0/8.0)
00810 +Control_points[0][i+1][k]*(3.0/4.0)
00811 +Control_points[0][i+2][k]*(1.0/8.0);
00812
00813 temp.push_back(val);
00814
00815
00816
00817 }
00818 val=Control_points[0][line_size-2][k]*(1.0/2.0)
00819 +Control_points[0][line_size-3][k]*(1.0/2.0);
00820
00821 temp.push_back(val);
00822
00823 val=Control_points[0][line_size-1][k]*(3.0/16.0)
00824 +Control_points[0][line_size-2][k]*(11.0/16.0)
00825 +Control_points[0][line_size-3][k]*(1.0/8.0);
00826
00827 temp.push_back(val);
00828
00829 val=Control_points[0][line_size-2][k]*(1.0/4.0)
00830 +Control_points[0][line_size-1][k]*(3.0/4.0);
00831
00832 temp.push_back(val);
00833
00834 val=Control_points[0][line_size][k]*(1.0/2.0)
00835 +Control_points[0][line_size-1][k]*(1.0/2.0);
00836
00837 temp.push_back(val);
00838
00839 temp.push_back(Control_points[0][line_size][k]);
00840
00841
00842 temp_grid.push_back(temp);
00843
00844 }
00845
00846
00847
00848 for(unsigned int i=0;i<temp_grid[0].size();i++) {
00849 temp.clear();
00850 for(unsigned int j=0;j<temp_grid.size();j++) {
00851 temp.push_back(temp_grid[j][i]);
00852 }
00853 c_points.push_back(temp);
00854 }
00855
00856 Control_points.insert(Control_points.begin(),c_points);
00857
00858 temp.clear();
00859 val=val*0;
00860
00861 n_v=(int)Control_points[0][0].size();
00862 n_u=(int)Control_points[0].size();
00863
00864 for(int i=0;i<n_v;i++)
00865 temp.push_back(val);
00866
00867 for(int i=0;i<n_u;i++)
00868 d_points.push_back(temp);
00869
00870 Details.insert(Details.begin(),d_points);
00871
00872 for(unsigned int i=0;i<footprint.size();i++) {
00873 footprint[i][1]=footprint[i][3]=10000000;
00874 footprint[i][0]=footprint[i][2]=-1;
00875 }
00876 CalcPreImage(selected[0],selected[1],selected_level);
00877 }
00878
00879 void BSplineSurface::DisplayControlPoints(Matrix3d A,Point3d trans)
00880 {
00881 Point3d t;
00882 glColor3dv(unsel_point);
00883 int k=selected_level;
00884
00885
00886 for(unsigned int i=0;i<Control_points[k].size();i++) {
00887 for(unsigned int j=0;j<Control_points[k][0].size();j++) {
00888 if(k==selected_level) {
00889 t=Control_points[selected_level][i][j];
00890 t[2]=-t[2]+k*(MRES_OFF);
00891 t=A*t;
00892 t[2]=0;
00893 t=t+trans;
00894 if(i!=selected[0] || j!=selected[1])
00895 DrawCircle(t[0],t[1],t[2],0.7);
00896
00897 else {
00898 glColor3dv(sel_point);;
00899 DrawCircle(t[0],t[1],t[2],1.0);
00900
00901 glColor3dv(unsel_point);
00902 }
00903 } else {
00904 t=Control_points[k][i][j];
00905 t[2]=-t[2]+k*(MRES_OFF);
00906 t=A*t;
00907 t[2]=0;
00908 t=t+trans;
00909 glColor3d(0.8*(k/Control_points.size()),0.8*(k/Control_points.size()),0.8*(k/Control_points.size()));
00910 DrawCircle(t[0],t[1],t[2],0.3);
00911
00912 glColor3dv(unsel_point);
00913 }
00914 }
00915 }
00916
00917
00918 for(unsigned int i=0;i<selected_region.size();i++) {
00919 t=Control_points[selected_level][selected_region[i][0]][selected_region[i][1]];
00920 t[2]=-t[2]+k*(MRES_OFF);
00921 t=A*t;
00922 t[2]=0.01;
00923 t=t+trans;
00924 glColor3dv(sel_point);;
00925 DrawCircle(t[0],t[1],t[2],1.0);
00926
00927 glColor3dv(unsel_point);
00928 }
00929
00930 if(disp_c_mesh){
00931
00932 glBegin(GL_LINES);
00933 for(unsigned int i=0;i<Control_points[k].size();i++) {
00934 for(unsigned int j=0;j<Control_points[k][0].size();j++) {
00935 if(i!=Control_points[k].size()-1){
00936 t=Control_points[k][i][j];
00937 t[2]=-t[2]+k*(MRES_OFF);
00938 t=A*t;
00939 t[2]=0;
00940 t=t+trans;
00941 glVertex3d(t[0],t[1],t[2]);
00942
00943 t=Control_points[k][i+1][j];
00944 t[2]=-t[2]+k*(MRES_OFF);
00945 t=A*t;
00946 t[2]=0;
00947 t=t+trans;
00948 glVertex3d(t[0],t[1],t[2]);
00949
00950
00951 }
00952 if(j!=Control_points[k][0].size()-1){
00953 t=Control_points[k][i][j];
00954 t[2]=-t[2]+k*(MRES_OFF);
00955 t=A*t;
00956 t[2]=0;
00957 t=t+trans;
00958 glVertex3d(t[0],t[1],t[2]);
00959
00960 t=Control_points[k][i][j+1];
00961 t[2]=-t[2]+k*(MRES_OFF);
00962 t=A*t;
00963 t[2]=0;
00964 t=t+trans;
00965 glVertex3d(t[0],t[1],t[2]);
00966
00967 }
00968
00969 }
00970
00971 }
00972 glEnd();
00973 }
00974
00975 }
00976
00977 void BSplineSurface::DrawCircle(double x, double y, double z, double weight) {
00978 glBegin(GL_TRIANGLES);
00979 for(double i=0;i<C_SEG;i++) {
00980 glVertex3d( x+ sqrt(weight)*C_SCALE*cos(2*3.14159*(i/C_SEG)),y
00981 + sqrt(weight)*C_SCALE*sin(2*3.14159*(i/C_SEG)),z);
00982 glVertex3d( x+ sqrt(weight)*C_SCALE*cos(2*3.14159*((i+1)/C_SEG)),y
00983 + sqrt(weight)*C_SCALE*sin(2*3.14159*((i+1)/C_SEG)),z);
00984 glVertex3d(x,y,z);
00985 }
00986 glEnd();
00987 }
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004 void BSplineSurface::DisplaySurface()
01005 {
01006 Point3d u_val,u_val2,u_val3,u_val4;
01007 Point3d n_val,n_val2,n_val3,n_val4;
01008 glLineWidth(1.0);
01009
01010
01011
01012
01013
01014 n_u=(int)Control_points[0].size();
01015 n_v=(int)Control_points[0][0].size();
01016
01017
01018 if(wireframe) {
01019 if(n_u>1) {
01020
01021
01022 glColor3dv(poly_line);
01023
01024
01025 for(double i=3;i<= (n_u+d_step) && n_u>1 ; i+=u_prec*((double)n_u-(double)degree)) {
01026 glBegin(GL_LINE_STRIP);
01027 for(double j=3;j<= (n_v+d_step) && n_v>1 ; j+=d_step*((double)n_v-(double)degree)) {
01028 if(contraction){
01029 if( psurf && HasContracted(psurf,i,j))
01030 glColor3f(0.5,0.0,0.0);
01031 else
01032 glColor3f(0.0,0.5,0.0);
01033 }
01034
01035 u_val= Eval(i,j);
01036 glVertex3d(u_val[0],u_val[1],u_val[2]);
01037 }
01038 glEnd();
01039 }
01040
01041 for(double i=3;i<= (n_v+d_step) && n_v>1 ; i+=v_prec*((double)n_v-(double)degree)) {
01042 glBegin(GL_LINE_STRIP);
01043 for(double j=3;j<= (n_u+d_step) && n_u>1 ; j+=d_step*((double)n_u-(double)degree)) {
01044 if(contraction){
01045 if( psurf && HasContracted(psurf,i,j))
01046 glColor3f(0.5,0.0,0.0);
01047 else
01048 glColor3f(0.0,0.5,0.0);
01049 }
01050
01051
01052 u_val= Eval(j,i);
01053 glVertex3d(u_val[0],u_val[1],u_val[2]);
01054 }
01055 glEnd();
01056 }
01057 }
01058 } else {
01059 if(n_u>1) {
01060
01061 if(s_mesh)
01062 glBegin(GL_TRIANGLES);
01063
01064 for(double i=3;i<= (n_u) && n_u>1 ; i+=u_prec/5.0*((double)n_u-(double)degree)) {
01065 for(double j=3; j<=(n_v) && n_v>1 ; j+=v_prec/5.0*((double)n_v-(double)degree)) {
01066 u_val= Eval(i,j);
01067 n_val=NormalEval(i,j);
01068
01069 u_val2= Eval(i+u_prec/5.0*(n_u-degree),j);
01070 n_val2=NormalEval(i+u_prec/5.0*(n_u-degree),j);
01071
01072 n_val3=NormalEval(i,j+v_prec/5.0*(n_v-degree));
01073 u_val3= Eval(i,j+v_prec/5.0*(n_v-degree));
01074
01075 u_val4= Eval(i+u_prec/5.0*(n_u-degree),j+v_prec/5.0
01076 * (n_v-degree));
01077 n_val4=NormalEval(i+u_prec/5.0*(n_u-degree),j+v_prec/5.0
01078 * (n_v-degree));
01079
01080 if(contraction){
01081 if( psurf && HasContracted(psurf,i,j))
01082 glColor3f(0.5,0.0,0.0);
01083 else
01084 glColor3f(0.0,0.5,0.0);
01085 }
01086
01087
01088 if(n_val2*n_val3 > n_val*n_val4 ) {
01089 if(!s_mesh)
01090 glBegin(GL_LINE_STRIP);
01091
01092 glNormal3d(n_val[0],n_val[1],n_val[2]);
01093 glVertex3d(u_val[0],u_val[1],u_val[2]);
01094
01095 glNormal3d(n_val2[0],n_val2[1],n_val2[2]);
01096 glVertex3d(u_val2[0],u_val2[1],u_val2[2]);
01097
01098 glNormal3d(n_val3[0],n_val3[1],n_val3[2]);
01099 glVertex3d(u_val3[0],u_val3[1],u_val3[2]);
01100
01101 if(!s_mesh) {
01102 glNormal3d(n_val[0],n_val[1],n_val[2]);
01103 glVertex3d(u_val[0],u_val[1],u_val[2]);
01104 }
01105
01106 if(!s_mesh) {
01107 glEnd();
01108 glBegin(GL_LINE_STRIP);
01109
01110 }
01111 glNormal3d(n_val4[0],n_val4[1],n_val4[2]);
01112 glVertex3d(u_val4[0],u_val4[1],u_val4[2]);
01113
01114
01115
01116 glNormal3d(n_val3[0],n_val3[1],n_val3[2]);
01117 glVertex3d(u_val3[0],u_val3[1],u_val3[2]);
01118
01119
01120
01121 glNormal3d(n_val2[0],n_val2[1],n_val2[2]);
01122 glVertex3d(u_val2[0],u_val2[1],u_val2[2]);
01123
01124 if(!s_mesh) {
01125 glNormal3d(n_val4[0],n_val4[1],n_val4[2]);
01126 glVertex3d(u_val4[0],u_val4[1],u_val4[2]);
01127 glEnd();
01128 }
01129 } else {
01130 if(!s_mesh) {
01131 glBegin(GL_LINE_STRIP);
01132 }
01133
01134 glNormal3d(n_val[0],n_val[1],n_val[2]);
01135 glVertex3d(u_val[0],u_val[1],u_val[2]);
01136
01137 glNormal3d(n_val2[0],n_val2[1],n_val2[2]);
01138 glVertex3d(u_val2[0],u_val2[1],u_val2[2]);
01139
01140 glNormal3d(n_val4[0],n_val4[1],n_val4[2]);
01141 glVertex3d(u_val4[0],u_val4[1],u_val4[2]);
01142
01143 if(!s_mesh) {
01144 glNormal3d(n_val[0],n_val[1],n_val[2]);
01145 glVertex3d(u_val[0],u_val[1],u_val[2]);
01146 glEnd();
01147 glBegin(GL_LINE_STRIP);
01148 }
01149
01150 glNormal3d(n_val4[0],n_val4[1],n_val4[2]);
01151 glVertex3d(u_val4[0],u_val4[1],u_val4[2]);
01152
01153 glNormal3d(n_val3[0],n_val3[1],n_val3[2]);
01154 glVertex3d(u_val3[0],u_val3[1],u_val3[2]);
01155
01156 glNormal3d(n_val[0],n_val[1],n_val[2]);
01157 glVertex3d(u_val[0],u_val[1],u_val[2]);
01158
01159 if(!s_mesh) {
01160 glNormal3d(n_val4[0],n_val4[1],n_val4[2]);
01161 glVertex3d(u_val4[0],u_val4[1],u_val4[2]);
01162 glEnd();
01163 }
01164 }
01165 }
01166 }
01167 glEnd();
01168 }
01169 }
01170
01171
01172 glDisable(GL_LIGHTING);
01173 if(disp_normal) {
01174 glBegin(GL_LINES);
01175
01176 for(double i=1;i< (n_u+degree-1-u_prec/2.0*(n_u+degree)) && n_u>1 ; i+=u_prec/2.0*((double)n_u-(double)degree)) {
01177 for(double j=1;j< (n_v+degree-1-v_prec/2.0*(n_v+degree)) && n_v>1 ; j+=v_prec/2.0*((double)n_v+(double)degree)) {
01178
01179 Point3d pos;
01180 Point3d nrml;
01181
01182 pos=Eval(i,j);
01183 glColor3f(1.0,0.0,0.0);
01184 nrml=NormalEval(i,j);
01185
01186 if(i==n_u && j==n_v)
01187 glColor3f(0.0,1.0,0.0);
01188 glVertex3d(pos[0],pos[1],pos[2]);
01189 pos=pos+nrml*0.05;
01190
01191 glVertex3d(pos[0],pos[1],pos[2]);
01192 }
01193 }
01194 glEnd();
01195 }
01196 glEnable(GL_LIGHTING);
01197
01198 glColor3dv(sel_point);
01199 glLineWidth(3.0);
01200
01201
01202
01203 glLineWidth(1.0);
01204
01205 n_u=(int)Control_points[0].size();
01206 n_v=(int)Control_points[0][0].size();
01207 }
01208
01209
01210 void BSplineSurface::UpdateFootprint()
01211 {
01212 unsigned int line_size;
01213
01214
01215 for(int i=selected_level-1;i>=0;i--) {
01216 if(Control_points[i].size()>Control_points[i+1].size()) {
01217
01218
01219
01220 for(unsigned int j=0;j<Control_points[i][0].size();j++) {
01221 for(unsigned int k=0;k<=Control_points[i].size();k++) {
01222 if(k<5) {
01223 if(k==0)
01224 Control_points[i][0][j]=Control_points[i+1][0][j];
01225
01226 if(k==1) {
01227 Control_points[i][1][j]=Control_points[i+1][0][j]*(1.0/2.0)
01228 +Control_points[i+1][1][j]*(1.0/2.0)
01229 +Details[i][0][j];
01230 }
01231 if(k==2)
01232 Control_points[i][2][j]=Control_points[i+1][1][j]*(3.0/4.0)
01233 +Control_points[i+1][2][j]*(1.0/4.0)
01234 +Details[i][0][j]*(-2033.0/3000.0)
01235 +Details[i][1][j]*(-49.0/152.0);
01236
01237 if(k==3)
01238 Control_points[i][3][j]=Control_points[i+1][1][j]*(3.0/16.0)
01239 +Control_points[i+1][2][j]*(11.0/16.0)
01240 +Control_points[i+1][3][j]*(1.0/8.0)
01241 +Details[i][0][j]*(2137.0/12000.0)
01242 +Details[i][1][j]*(-289.0/608.0)
01243 +Details[i][2][j]*(-23.0/208.0);
01244
01245 if(k==4) {
01246 Control_points[i][4][j]=Control_points[i+1][2][j]*(1.0/2.0)
01247 +Control_points[i+1][3][j]*(1.0/2.0)
01248 +Details[i][0][j]*(139.0/500.0)
01249 +Details[i][1][j]*1.0
01250 +Details[i][2][j]*(-23.0/52.0);
01251 }
01252 } else {
01253 line_size=(int)Control_points[i].size()-1;
01254 unsigned int lsize2=(int)Control_points[i+1].size()-1;
01255 if( k<line_size-4) {
01256
01257 for(;k<line_size-4;k++) {
01258 if(k%2==1) {
01259 Control_points[i][k][j]= Control_points[i+1][(k)/2][j]*(1.0/8.0)
01260 +Control_points[i+1][(k)/2+1][j]*(3.0/4.0)
01261 +Control_points[i+1][(k)/2+2][j]*(1.0/8.0);
01262 } else {
01263 Control_points[i][k][j]= Control_points[i+1][(k)/2][j]*(1.0/2.0)
01264 +Control_points[i+1][(k)/2+1][j]*(1.0/2.0);
01265 }
01266 if(k<=7 || line_size-k<=7 ) {
01267 if(k==5) {
01268 Control_points[i][k][j]=Control_points[i][k][j]
01269 +Details[i][0][j]*(139.0/2000.0)
01270 +Details[i][1][j]*(-347.0/912.0)
01271 +Details[i][2][j]*(-63.0/208.0)
01272 +Details[i][3][j]*(-23.0/208.0);
01273
01274 } else if(k==6) {
01275 Control_points[i][k][j]=Control_points[i][k][j]
01276 +Details[i][1][j]*(-115.0/228.0)
01277 +Details[i][2][j]*1.0
01278 +Details[i][3][j]*(-23.0/52.0);
01279
01280 } else if(k==7) {
01281 Control_points[i][k][j]=Control_points[i][k][j]
01282 +Details[i][1][j]*(-115.0/912.0)
01283 +Details[i][2][j]*(-63.0/208.0)
01284 +Details[i][3][j]*(-63.0/208.0)
01285 +Details[i][4][j]*(-23.0/208.0);
01286
01287 } else if(k==line_size-7)
01288 Control_points[i][k][j]=Control_points[i][k][j]
01289 +Details[i][lsize2-4][j]*(-115.0/912.0)
01290 +Details[i][lsize2-5][j]*(-63.0/208.0)
01291 +Details[i][lsize2-6][j]*(-63.0/208.0)
01292 +Details[i][lsize2-7][j]*(-23.0/208.0);
01293
01294 else if(k==line_size-6)
01295 Control_points[i][k][j]=Control_points[i][k][j]
01296 +Details[i][lsize2-4][j]*(-115.0/228.0)
01297 +Details[i][lsize2-5][j]*1.0
01298 +Details[i][lsize2-6][j]*(-23.0/52.0);
01299
01300 else if(k==line_size-5)
01301 Control_points[i][k][j]=Control_points[i][k][j]
01302 +Details[i][lsize2-3][j]*(139.0/2000.0)
01303 +Details[i][lsize2-4][j]*(-347.0/912.0)
01304 +Details[i][lsize2-5][j]*(-63.0/208.0)
01305 +Details[i][lsize2-6][j]*(-23.0/208.0);
01306
01307 } else if(k%2==0)
01308 Control_points[i][k][j]=Control_points[i][k][j]
01309 +Details[i][(k-4)/2][j]*(-23.0/52.0)
01310 +Details[i][(k-4)/2+1][j]*1.0
01311 +Details[i][(k-4)/2+2][j]*(-23.0/52.0);
01312
01313 else
01314 Control_points[i][k][j]=Control_points[i][k][j]
01315 +Details[i][(k-4)/2][j]*(-23.0/208.0)
01316 +Details[i][(k-4)/2+1][j]*(-63.0/208.0)
01317 +Details[i][(k-4)/2+2][j]*(-63.0/208.0)
01318 +Details[i][(k-4)/2+3][j]*(-23.0/208.0);
01319 }
01320 }
01321 if(k>=line_size-4) {
01322 if(k==line_size-4)
01323 Control_points[i][line_size-4][j]=Control_points[i+1][lsize2-2][j]*(1.0/2.0)
01324 +Control_points[i+1][lsize2-3][j]*(1.0/2.0)
01325 +Details[i][lsize2-3][j]*(139.0/500.0)
01326 +Details[i][lsize2-4][j]*1.0
01327 +Details[i][lsize2-5][j]*(-23.0/52.0);
01328
01329 if(k==line_size-3)
01330 Control_points[i][line_size-3][j]=Control_points[i+1][lsize2-1][j]*(3.0/16.0)
01331 +Control_points[i+1][lsize2-2][j]*(11.0/16.0)
01332 +Control_points[i+1][lsize2-3][j]*(1.0/8.0)
01333 +Details[i][lsize2-3][j]*(2137.0/12000.0)
01334 +Details[i][lsize2-4][j]*(-289.0/608.0)
01335 +Details[i][lsize2-5][j]*(-23.0/208.0);
01336
01337 if(k==line_size-2)
01338 Control_points[i][line_size-2][j]=Control_points[i+1][lsize2-1][j]*(3.0/4.0)
01339 +Control_points[i+1][lsize2-2][j]*(1.0/4.0)
01340 +Details[i][lsize2-3][j]*(-2033.0/3000.0)
01341 +Details[i][lsize2-4][j]*(-49.0/152.0);
01342
01343 if(k==line_size-1)
01344 Control_points[i][line_size-1][j]=Control_points[i+1][lsize2][j]*(1.0/2.0)
01345 +Control_points[i+1][lsize2-1][j]*(1.0/2.0)
01346 +Details[i][lsize2-3][j];
01347
01348 if(k==line_size)
01349 Control_points[i][line_size][j]=Control_points[i+1][lsize2][j];
01350 }
01351 }
01352 }
01353 }
01354 } else {
01355 for(unsigned int j=0;j<Control_points[i].size();j++) {
01356 for(unsigned int k=0;k<=Control_points[i][0].size();k++) {
01357
01358
01359
01360 unsigned int lsize2=(int)Control_points[i+1][0].size()-1;
01361 if(k<5) {
01362 if(k==0)
01363 Control_points[i][j][0]=Control_points[i+1][j][0]*1.0;
01364
01365 if(k==1)
01366 Control_points[i][j][1]=Control_points[i+1][j][0]*(1.0/2.0)
01367 +Control_points[i+1][j][1]*(1.0/2.0)
01368 +Details[i][j][0];
01369
01370 if(k==2)
01371 Control_points[i][j][2]=Control_points[i+1][j][1]*(3.0/4.0)
01372 +Control_points[i+1][j][2]*(1.0/4.0)
01373 +Details[i][j][0]*(-2033.0/3000.0)
01374 +Details[i][j][1]*(-49.0/152.0);
01375
01376 if(k==3)
01377 Control_points[i][j][3]=Control_points[i+1][j][1]*(3.0/16.0)
01378 +Control_points[i+1][j][2]*(11.0/16.0)
01379 +Control_points[i+1][j][3]*(1.0/8.0)
01380 +Details[i][j][0]*(2137.0/12000.0)
01381 +Details[i][j][1]*(-289.0/608.0)
01382 +Details[i][j][2]*(-23.0/208.0);
01383
01384 if(k==4)
01385 Control_points[i][j][4]=Control_points[i+1][j][2]*(1.0/2.0)
01386 +Control_points[i+1][j][3]*(1.0/2.0)
01387 +Details[i][j][0]*(139.0/500.0)
01388 +Details[i][j][1]*1.0
01389 +Details[i][j][2]*(-23.0/52.0);
01390
01391 } else {
01392
01393 line_size=(int)Control_points[i][0].size()-1;
01394
01395 if( k<line_size-4) {
01396 for(;k<line_size-4;k++) {
01397
01398 if(k%2) {
01399 Control_points[i][j][k]= Control_points[i+1][j][(k)/2]*(1.0/8.0)
01400 +Control_points[i+1][j][(k)/2+1]*(3.0/4.0)
01401 +Control_points[i+1][j][(k)/2+2]*(1.0/8.0);
01402 }
01403 else{
01404 Control_points[i][j][k]= Control_points[i+1][j][(k)/2]*(1.0/2.0)
01405 +Control_points[i+1][j][(k)/2+1]*(1.0/2.0);
01406 }
01407 if(k<=7 || k>=line_size-7 ) {
01408 if(k==5) {
01409 Control_points[i][j][k]=Control_points[i][j][k]
01410 +Details[i][j][0]*(139.0/2000.0)
01411 +Details[i][j][1]*(-347.0/912.0)
01412 +Details[i][j][2]*(-63.0/208.0)
01413 +Details[i][j][3]*(-23.0/208.0);
01414
01415 } else if(k==6) {
01416 Control_points[i][j][k]=Control_points[i][j][k]
01417 +Details[i][j][1]*(-115.0/228.0)
01418 +Details[i][j][2]*1.0
01419 +Details[i][j][3]*(-23.0/52.0);
01420 }
01421
01422 else if(k==7) {
01423 Control_points[i][j][k]=Control_points[i][j][k]
01424 +Details[i][j][1]*(-115.0/912.0)
01425 +Details[i][j][2]*(-63.0/208.0)
01426 +Details[i][j][3]*(-63.0/208.0)
01427 +Details[i][j][4]*(-23.0/208.0);
01428
01429 } else if(k==line_size-7)
01430 Control_points[i][j][k]=Control_points[i][j][k]
01431 +Details[i][j][lsize2-4]*(-115.0/912.0)
01432 +Details[i][j][lsize2-5]*(-63.0/208.0)
01433 +Details[i][j][lsize2-6]*(-63.0/208.0)
01434 +Details[i][j][lsize2-7]*(-23.0/208.0);
01435
01436 else if(k==line_size-6)
01437 Control_points[i][j][k]=Control_points[i][j][k]
01438 +Details[i][j][lsize2-4]*(-115.0/228.0)
01439 +Details[i][j][lsize2-5]*1.0
01440 +Details[i][j][lsize2-6]*(-23.0/52.0);
01441
01442 else if(k==line_size-5)
01443 Control_points[i][j][k]=Control_points[i][j][k]
01444 +Details[i][j][lsize2-3]*(139.0/2000.0)
01445 +Details[i][j][lsize2-4]*(-347.0/912.0)
01446 +Details[i][j][lsize2-5]*(-63.0/208.0)
01447 +Details[i][j][lsize2-6]*(-23.0/208.0);
01448 } else if(k%2==0)
01449 Control_points[i][j][k]=Control_points[i][j][k]
01450 +Details[i][j][(k-4)/2]*(-23.0/52.0)
01451 +Details[i][j][(k-4)/2+1]*1.0
01452 +Details[i][j][(k-4)/2+2]*(-23.0/52.0);
01453 else
01454 Control_points[i][j][k]=Control_points[i][j][k]
01455 +Details[i][j][(k-4)/2]*(-23.0/208.0)
01456 +Details[i][j][(k-4)/2+1]*(-63.0/208.0)
01457 +Details[i][j][(k-4)/2+2]*(-63.0/208.0)
01458 +Details[i][j][(k-4)/2+3]*(-23.0/208.0);
01459 }
01460 }
01461 if(k>=line_size-4) {
01462 if(k==line_size-4)
01463 Control_points[i][j][line_size-4]=Control_points[i+1][j][lsize2-2]*(1.0/2.0)
01464 +Control_points[i+1][j][lsize2-3]*(1.0/2.0)
01465 +Details[i][j][lsize2-3]*(139.0/500.0)
01466 +Details[i][j][lsize2-4]*1.0
01467 +Details[i][j][lsize2-5]*(-23.0/52.0);
01468
01469 if(k==line_size-3)
01470 Control_points[i][j][line_size-3]=Control_points[i+1][j][lsize2-1]*(3.0/16.0)
01471 +Control_points[i+1][j][lsize2-2]*(11.0/16.0)
01472 +Control_points[i+1][j][lsize2-3]*(1.0/8.0)
01473 +Details[i][j][lsize2-3]*(2137.0/12000.0)
01474 +Details[i][j][lsize2-4]*(-289.0/608.0)
01475 +Details[i][j][lsize2-5]*(-23.0/208.0);
01476
01477 if(k==line_size-2)
01478 Control_points[i][j][line_size-2]=Control_points[i+1][j][lsize2-1]*(3.0/4.0)
01479 +Control_points[i+1][j][lsize2-2]*(1.0/4.0)
01480 +Details[i][j][lsize2-3]*(-2033.0/3000.0)
01481 +Details[i][j][lsize2-4]*(-49.0/152.0);
01482
01483 if(k==line_size-1)
01484 Control_points[i][j][line_size-1]=Control_points[i+1][j][lsize2]*(1.0/2.0)
01485 +Control_points[i+1][j][lsize2-1]*(1.0/2.0)
01486 +Details[i][j][lsize2-3];
01487
01488 if(k==line_size)
01489 Control_points[i][j][line_size]=Control_points[i+1][j][lsize2];
01490 }
01491 }
01492 }
01493 }
01494 }
01495 }
01496 for(unsigned int i=selected_level+1;i<Control_points.size();i++) {
01497 if(Control_points[i].size()<Control_points[i-1].size()) {
01498 unsigned int line_size=(int)Control_points[i].size()-1;
01499 for(unsigned int j=0;j<Control_points[i][0].size();j++) {
01500 for(unsigned int k=0;k<=Control_points[i].size();k++) {
01501
01502
01503 unsigned int l2=(int)Control_points[i-1].size()-1;
01504
01505
01506 if(k==0) {
01507 Control_points[i][0][j]=Control_points[i-1][0][j];
01508
01509 Details[i-1][0][j]=Control_points[i-1][0][j]*(-45.0/139.0)
01510 +Control_points[i-1][1][j]*(90.0/139.0)
01511 +Control_points[i-1][2][j]*(-135.0/278.0)
01512 +Control_points[i-1][3][j]*(30.0/139.0)
01513 +Control_points[i-1][4][j]*(-15.0/278.0);
01514 }
01515 if(k==1) {
01516 Control_points[i][1][j]=Control_points[i-1][0][j]*(-49.0/139.0)
01517 +Control_points[i-1][1][j]*(98.0/139.0)
01518 +Control_points[i-1][2][j]*(135.0/139.0)
01519 +Control_points[i-1][3][j]*(-60.0/139.0)
01520 +Control_points[i-1][4][j]*(15.0/139.0);
01521
01522 Details[i-1][1][j]=Control_points[i-1][2][j]*(57.0/490.0)
01523 +Control_points[i-1][3][j]*(-114.0/245.0)
01524 +Control_points[i-1][4][j]*(171.0/245.0)
01525 +Control_points[i-1][5][j]*(-114.0/245.0)
01526 +Control_points[i-1][6][j]*(57.0/490.0);
01527
01528 }
01529 if(k==2) {
01530 Control_points[i][2][j]=Control_points[i-1][0][j]*(9.0/50.0)
01531 +Control_points[i-1][1][j]*(-9.0/25.0)
01532 +Control_points[i-1][2][j]*(-2.0/25.0)
01533 +Control_points[i-1][3][j]*(32.0/25.0)
01534 +Control_points[i-1][4][j]*(43.0/100.0)
01535 +Control_points[i-1][5][j]*(-3.0/5.0)
01536 +Control_points[i-1][6][j]*(3.0/20.0);
01537
01538
01539 Details[i-1][2][j]=Control_points[i-1][4][j]*(13.0/98.0)
01540 +Control_points[i-1][5][j]*(-26.0/49.0)
01541 +Control_points[i-1][6][j]*(39.0/49.0)
01542 +Control_points[i-1][7][j]*(-26.0/49.0)
01543 +Control_points[i-1][8][j]*(13.0/98.0);
01544 }
01545
01546 if(k>=3 && k<=line_size-3) {
01547 unsigned int band_start=(k-3)*2+2;
01548
01549 Control_points[i][k][j]=Control_points[i-1][band_start][j]*(23.0/196.0)
01550 +Control_points[i-1][band_start+1][j]*(-23.0/49.0)
01551 +Control_points[i-1][band_start+2][j]*(9.0/28.0)
01552 +Control_points[i-1][band_start+3][j]*(52.0/49.0)
01553 +Control_points[i-1][band_start+4][j]*(9.0/28.0)
01554 +Control_points[i-1][band_start+5][j]*(-23.0/49.0)
01555 +Control_points[i-1][band_start+6][j]*(23.0/196.0);
01556
01557
01558 if(2*k<l2-8) {
01559
01560 Details[i-1][k][j]=Control_points[i-1][2*k][j]*(13.0/98.0)
01561 +Control_points[i-1][2*k+1][j]*(-26.0/49.0)
01562 +Control_points[i-1][2*k+2][j]*(39.0/49.0)
01563 +Control_points[i-1][2*k+3][j]*(-26.0/49.0)
01564 +Control_points[i-1][2*k+4][j]*(13.0/98.0);
01565
01566
01567 }
01568
01569
01570
01571
01572
01573
01574
01575
01576 }
01577
01578 if(k==line_size-2) {
01579
01580 Control_points[i][line_size-2][j]=Control_points[i-1][l2][j]*(9.0/50.0)
01581 +Control_points[i-1][l2-1][j]*(-9.0/25.0)
01582 +Control_points[i-1][l2-2][j]*(-2.0/25.0)
01583 +Control_points[i-1][l2-3][j]*(32.0/25.0)
01584 +Control_points[i-1][l2-4][j]*(43.0/100.0)
01585 +Control_points[i-1][l2-5][j]*(-3.0/5.0)
01586 +Control_points[i-1][l2-6][j]*(3.0/20.0);
01587
01588
01589 Details[i-1][line_size-5][j]=Control_points[i-1][l2-4][j]*(13.0/98.0)
01590 +Control_points[i-1][l2-5][j]*(-26.0/49.0)
01591 +Control_points[i-1][l2-6][j]*(39.0/49.0)
01592 +Control_points[i-1][l2-7][j]*(-26.0/49.0)
01593 +Control_points[i-1][l2-8][j]*(13.0/98.0);
01594 }
01595 if(k==line_size-1) {
01596 Control_points[i][line_size-1][j]=Control_points[i-1][l2][j]*(-49.0/139.0)
01597 +Control_points[i-1][l2-1][j]*(98.0/139.0)
01598 +Control_points[i-1][l2-2][j]*(135.0/139.0)
01599 +Control_points[i-1][l2-3][j]*(-60.0/139.0)
01600 +Control_points[i-1][l2-4][j]*(15.0/139.0);
01601
01602 Details[i-1][line_size-4][j]=Control_points[i-1][l2-2][j]*(57.0/490.0)
01603 +Control_points[i-1][l2-3][j]*(-114.0/245.0)
01604 +Control_points[i-1][l2-4][j]*(171.0/245.0)
01605 +Control_points[i-1][l2-5][j]*(-114.0/245.0)
01606 +Control_points[i-1][l2-6][j]*(57.0/490.0);
01607 }
01608
01609 if(k==line_size) {
01610 Control_points[i][line_size][j]=Control_points[i-1][l2][j];
01611 Details[i-1][line_size-3][j]=Control_points[i-1][l2][j]*(-45.0/139.0)
01612 +Control_points[i-1][l2-1][j]*(90.0/139.0)
01613 +Control_points[i-1][l2-2][j]*(-135.0/278.0)
01614 +Control_points[i-1][l2-3][j]*(30.0/139.0)
01615 +Control_points[i-1][l2-4][j]*(-15.0/278.0);
01616 }
01617 }
01618 }
01619 } else {
01620 unsigned int line_size=(int)Control_points[i][0].size()-1;
01621
01622 for(unsigned int j=0;j<Control_points[i].size();j++) {
01623 for(unsigned int k=0;k<=Control_points[i][0].size();k++) {
01624
01625
01626 unsigned int l2=(int)Control_points[i-1][0].size()-1;
01627
01628 if(k==0) {
01629
01630
01631
01632 Control_points[i][j][0]=Control_points[i-1][j][0];
01633
01634 Details[i-1][j][0]=Control_points[i-1][j][0]*(-45.0/139.0)
01635 +Control_points[i-1][j][1]*(90.0/139.0)
01636 +Control_points[i-1][j][2]*(-135.0/278.0)
01637 +Control_points[i-1][j][3]*(30.0/139.0)
01638 +Control_points[i-1][j][4]*(-15.0/278.0);
01639 }
01640 if(k==1) {
01641 Control_points[i][j][1]=Control_points[i-1][j][0]*(-49.0/139.0)
01642 +Control_points[i-1][j][1]*(98.0/139.0)
01643 +Control_points[i-1][j][2]*(135.0/139.0)
01644 +Control_points[i-1][j][3]*(-60.0/139.0)
01645 +Control_points[i-1][j][4]*(15.0/139.0);
01646
01647 Details[i-1][j][1]=Control_points[i-1][j][2]*(57.0/490.0)
01648 +Control_points[i-1][j][3]*(-114.0/245.0)
01649 +Control_points[i-1][j][4]*(171.0/245.0)
01650 +Control_points[i-1][j][5]*(-114.0/245.0)
01651 +Control_points[i-1][j][6]*(57.0/490.0);
01652 }
01653 if(k==2) {
01654 Control_points[i][j][2]=Control_points[i-1][j][0]*(9.0/50.0)
01655 +Control_points[i-1][j][1]*(-9.0/25.0)
01656 +Control_points[i-1][j][2]*(-2.0/25.0)
01657 +Control_points[i-1][j][3]*(32.0/25.0)
01658 +Control_points[i-1][j][4]*(43.0/100.0)
01659 +Control_points[i-1][j][5]*(-3.0/5.0)
01660 +Control_points[i-1][j][6]*(3.0/20.0);
01661
01662 Details[i-1][j][2]=Control_points[i-1][j][4]*(13.0/98.0)
01663 +Control_points[i-1][j][5]*(-26.0/49.0)
01664 +Control_points[i-1][j][6]*(39.0/49.0)
01665 +Control_points[i-1][j][7]*(-26.0/49.0)
01666 +Control_points[i-1][j][8]*(13.0/98.0);
01667 }
01668
01669 if(k>=3 && k<=line_size-3) {
01670 unsigned int band_start=(k-3)*2+2;
01671
01672 Control_points[i][j][k]=Control_points[i-1][j][band_start]*(23.0/196.0)
01673 +Control_points[i-1][j][band_start+1]*(-23.0/49.0)
01674 +Control_points[i-1][j][band_start+2]*(9.0/28.0)
01675 +Control_points[i-1][j][band_start+3]*(52.0/49.0)
01676 +Control_points[i-1][j][band_start+4]*(9.0/28.0)
01677 +Control_points[i-1][j][band_start+5]*(-23.0/49.0)
01678 +Control_points[i-1][j][band_start+6]*(23.0/196.0);
01679
01680
01681
01682 if(2*k<l2-8) {
01683 Details[i-1][j][k]=Control_points[i-1][j][2*k]*(13.0/98.0)
01684 +Control_points[i-1][j][2*k+1]*(-26.0/49.0)
01685 +Control_points[i-1][j][2*k+2]*(39.0/49.0)
01686 +Control_points[i-1][j][2*k+3]*(-26.0/49.0)
01687 +Control_points[i-1][j][2*k+4]*(13.0/98.0);
01688 }
01689 }
01690
01691 if(k==line_size-2) {
01692 Control_points[i][j][line_size-2]=Control_points[i-1][j][l2]*(9.0/50.0)
01693 +Control_points[i-1][j][l2-1]*(-9.0/25.0)
01694 +Control_points[i-1][j][l2-2]*(-2.0/25.0)
01695 +Control_points[i-1][j][l2-3]*(32.0/25.0)
01696 +Control_points[i-1][j][l2-4]*(43.0/100.0)
01697 +Control_points[i-1][j][l2-5]*(-3.0/5.0)
01698 +Control_points[i-1][j][l2-6]*(3.0/20.0);
01699
01700 Details[i-1][j][line_size-5]=Control_points[i-1][j][l2-4]*(13.0/98.0)
01701 +Control_points[i-1][j][l2-5]*(-26.0/49.0)
01702 +Control_points[i-1][j][l2-6]*(39.0/49.0)
01703 +Control_points[i-1][j][l2-7]*(-26.0/49.0)
01704 +Control_points[i-1][j][l2-8]*(13.0/98.0);
01705 }
01706 if(k==line_size-1) {
01707 Control_points[i][j][line_size-1]=Control_points[i-1][j][l2]*(-49.0/139.0)
01708 +Control_points[i-1][j][l2-1]*(98.0/139.0)
01709 +Control_points[i-1][j][l2-2]*(135.0/139.0)
01710 +Control_points[i-1][j][l2-3]*(-60.0/139.0)
01711 +Control_points[i-1][j][l2-4]*(15.0/139.0);
01712
01713 Details[i-1][j][line_size-4]=Control_points[i-1][j][l2-2]*(57.0/490.0)
01714 +Control_points[i-1][j][l2-3]*(-114.0/245.0)
01715 +Control_points[i-1][j][l2-4]*(171.0/245.0)
01716 +Control_points[i-1][j][l2-5]*(-114.0/245.0)
01717 +Control_points[i-1][j][l2-6]*(57.0/490.0);
01718 }
01719
01720 if(k==line_size) {
01721 Control_points[i][j][line_size]=Control_points[i-1][j][l2];
01722
01723 Details[i-1][j][line_size-3]=Control_points[i-1][j][l2]*(-45.0/139.0)
01724 +Control_points[i-1][j][l2-1]*(90.0/139.0)
01725 +Control_points[i-1][j][l2-2]*(-135.0/278.0)
01726 +Control_points[i-1][j][l2-3]*(30.0/139.0)
01727 +Control_points[i-1][j][l2-4]*(-15.0/278.0);
01728
01729 }
01730 }
01731 }
01732 }
01733 }
01734 }
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796 void BSplineSurface::CalcPreImage(int i, int j, unsigned int level)
01797 {
01798 if(i>footprint[level][0])
01799 footprint[level][0]=i;
01800 if(i<footprint[level][1])
01801 footprint[level][1]=i;
01802 if(j>footprint[level][2])
01803 footprint[level][2]=j;
01804 if(j<footprint[level][3])
01805 footprint[level][3]=j;
01806
01807 if(level<Control_points.size()-1) {
01808 if(Control_points[level].size()>Control_points[level+1].size()) {
01809 int line_size=(int)Control_points[level].size()-1;
01810 if(i==0) {
01811 CalcPreImage(0,j,level+1);
01812 CalcPreImage(2,j,level+1);
01813 }
01814
01815 if(i==1) {
01816 CalcPreImage(0,j,level+1);
01817 CalcPreImage(2,j,level+1);
01818 }
01819
01820 if(i==2) {
01821 CalcPreImage(0,j,level+1);
01822 CalcPreImage(3,j, level+1);
01823 }
01824
01825 if(i>2 && i<line_size-2) {
01826 if(i>6)
01827 CalcPreImage(i/2-(i+1)%2,j,level+1);
01828 else
01829 CalcPreImage(0,j,level+1);
01830 CalcPreImage(i/2+3,j,level+1);
01831 }
01832
01833 int l2=(int)Control_points[level+1].size()-1;
01834
01835 if(i==line_size) {
01836 CalcPreImage(l2,j,level+1);
01837 CalcPreImage(l2-2,j,level+1);
01838 }
01839
01840 if(i==line_size-1) {
01841 CalcPreImage(l2-2,j,level+1);
01842 CalcPreImage(l2-1,j,level+1);
01843 }
01844
01845 if(i==line_size-2) {
01846 CalcPreImage(l2-3,j, level+1);
01847 CalcPreImage(l2-1,j,level+1);
01848 }
01849 } else {
01850 int line_size=(int)Control_points[level][0].size()-1;
01851
01852 if(j==0) {
01853 CalcPreImage(i,0,level+1);
01854 CalcPreImage(i,2,level+1);
01855 }
01856
01857 if(j==1) {
01858 CalcPreImage(i,1,level+1);
01859 CalcPreImage(i,2,level+1);
01860 }
01861
01862 if(j==2) {
01863 CalcPreImage(i,1,level+1);
01864 CalcPreImage(i,3, level+1);
01865 }
01866
01867 if(j>2 && j<line_size-2) {
01868 CalcPreImage(i,j/2-(j+1)%2,level+1);
01869 CalcPreImage(i,j/2+2,level+1);
01870 }
01871
01872 int l2=(int)Control_points[level+1][0].size()-1;
01873
01874 if(j==line_size) {
01875 CalcPreImage(i,l2-2,level+1);
01876 CalcPreImage(i,l2,level+1);
01877 }
01878
01879 if(j==line_size-1) {
01880 CalcPreImage(i,l2-2,level+1);
01881 CalcPreImage(i,l2-1,level+1);
01882 }
01883
01884 if(j==line_size-2) {
01885 CalcPreImage(i,l2-3, level+1);
01886 CalcPreImage(i,l2-1,level+1);
01887 }
01888 }
01889 }
01890 }
01891
01892 void BSplineSurface::CalcFootprint(unsigned int i,unsigned int j,unsigned int level) {
01893
01894 if((int)i>footprint[level][0])
01895 footprint[level][0]=(int)i;
01896 if((int)i<footprint[level][1])
01897 footprint[level][1]=(int)i;
01898 if((int)j>footprint[level][2])
01899 footprint[level][2]=(int)j;
01900 if((int)j<footprint[level][3])
01901 footprint[level][3]=(int)j;
01902
01903 if(level) {
01904 if(Control_points[level].size()<Control_points[level-1].size()) {
01905 if(i==0) {
01906 CalcFootprint(0 ,j , level-1);
01907 CalcFootprint(1 ,j , level-1);
01908
01909 } else if(i==1) {
01910 CalcFootprint(1,j,level-1);
01911 CalcFootprint(3,j, level-1);
01912
01913 } else if(i==2) {
01914 CalcFootprint(2,j,level-1);
01915 CalcFootprint(5,j,level-1);
01916
01917 } else if(i>=3 && i<(Control_points[level].size()-3)) {
01918 CalcFootprint(2*(i-3)+3,j,level-1);
01919 CalcFootprint(2*(i-3)+7,j,level-1);
01920
01921 } else {
01922 unsigned int l=(int)Control_points[level].size()-1;
01923 unsigned int l2=(int)Control_points[level-1].size()-1;
01924
01925 if(i==l) {
01926 CalcFootprint(l2 ,j , level-1);
01927 CalcFootprint(l2-1 ,j , level-1);
01928
01929 } else if(i==l-1) {
01930 CalcFootprint(l2-1,j, level-1);
01931 CalcFootprint(l2-3,j, level-1);
01932
01933 } else if(i==l-2) {
01934 CalcFootprint(l2-2,j,level-1);
01935 CalcFootprint(l2-5,j,level-1);
01936 }
01937 }
01938 } else {
01939 if(j==0) {
01940 CalcFootprint(i ,0 , level-1);
01941 CalcFootprint(i ,1 , level-1);
01942
01943 } else if(j==1) {
01944 CalcFootprint(i,1, level-1);
01945 CalcFootprint(i,3, level-1);
01946
01947 } else if(j==2) {
01948 CalcFootprint(i,2,level-1);
01949 CalcFootprint(i,5,level-1);
01950
01951 } else if(j>=3 && j<(Control_points[level][0].size()-3)) {
01952 CalcFootprint(i,2*(j-3)+3,level-1);
01953 CalcFootprint(i,2*(j-3)+7,level-1);
01954
01955 } else {
01956 unsigned int l=(int)Control_points[level][0].size()-1;
01957 unsigned int l2=(int)Control_points[level-1][0].size()-1;
01958
01959 if(j==l) {
01960 CalcFootprint(i ,l2 , level-1);
01961 CalcFootprint(i,l2-1 , level-1);
01962
01963 } else if(j==l-1) {
01964 CalcFootprint(i,l2-1, level-1);
01965 CalcFootprint(i,l2-3, level-1);
01966
01967 } else if(j==l-2) {
01968 CalcFootprint(i,l2-2,level-1);
01969 CalcFootprint(i,l2-5,level-1);
01970 }
01971 }
01972 }
01973 }
01974 }
01975
01976 void BSplineSurface::RenderFootprint() {
01977
01978 for(unsigned int i=0;i<footprint.size();i++) {
01979 RenderLine( footprint[i][0],footprint[i][2] ,i,footprint[i][0] ,footprint[i][3] ,i);
01980 RenderLine( footprint[i][0],footprint[i][2] ,i,footprint[i][1] ,footprint[i][2] ,i);
01981 RenderLine( footprint[i][1],footprint[i][2] ,i,footprint[i][1] ,footprint[i][3] ,i);
01982 RenderLine( footprint[i][0],footprint[i][3] ,i,footprint[i][1] ,footprint[i][3] ,i);
01983 }
01984 }
01985
01986 void BSplineSurface::RenderSupport(unsigned int i,unsigned int j,unsigned int level)
01987 {
01988 if(level) {
01989 if(Control_points[level].size()<Control_points[level-1].size()) {
01990 if(i==0) {
01991 RenderLine(i,j,level,0,j,level-1);
01992 RenderSupport(0 ,j , level-1);
01993 RenderLine(i,j,level,1,j,level-1);
01994 RenderSupport(1 ,j , level-1);
01995
01996 } else if(i==1) {
01997 RenderLine(i,j,level,1,j,level-1);
01998 RenderSupport(1,j, level-1);
01999 RenderLine(i,j,level,2,j,level-1);
02000 RenderSupport(2,j, level-1);
02001 RenderLine(i,j,level,3,j,level-1);
02002 RenderSupport(3,j, level-1);
02003
02004 } else if(i==2) {
02005 RenderLine(i,j,level,2,j,level-1);
02006 RenderSupport(2,j,level-1);
02007 RenderLine(i,j,level,3,j,level-1);
02008 RenderSupport(3,j,level-1);
02009 RenderLine(i,j,level,4,j,level-1);
02010 RenderSupport(4,j,level-1);
02011 RenderLine(i,j,level,5,j,level-1);
02012 RenderSupport(5,j,level-1);
02013
02014 } else if(i>=3 && i<(Control_points[level].size()-3)) {
02015 RenderLine(i,j,level,2*(i-3)+3,j,level-1);
02016 RenderSupport(2*(i-3)+3,j,level-1);
02017 RenderLine(i,j,level,2*(i-3)+4,j,level-1);
02018 RenderSupport(2*(i-3)+4,j,level-1);
02019 RenderLine(i,j,level,2*(i-3)+5,j,level-1);
02020 RenderSupport(2*(i-3)+5,j,level-1);
02021 RenderLine(i,j,level,2*(i-3)+6,j,level-1);
02022 RenderSupport(2*(i-3)+6,j,level-1);
02023 RenderLine(i,j,level,2*(i-3)+7,j,level-1);
02024 RenderSupport(2*(i-3)+7,j,level-1);
02025
02026 } else {
02027 unsigned int l=(int)Control_points[level].size()-1;
02028 unsigned int l2=(int)Control_points[level-1].size()-1;
02029 if(i==l) {
02030 RenderLine(i,j,level,l2,j,level-1);
02031 RenderSupport(l2 ,j , level-1);
02032 RenderLine(i,j,level,l2-1,j,level-1);
02033 RenderSupport(l2-1 ,j , level-1);
02034
02035 } else if(i==l-1) {
02036 RenderLine(i,j,level,l2-1,j,level-1);
02037 RenderSupport(l2-1,j, level-1);
02038 RenderLine(i,j,level,l2-2,j,level-1);
02039 RenderSupport(l2-2,j, level-1);
02040 RenderLine(i,j,level,l2-3,j,level-1);
02041 RenderSupport(l2-3,j, level-1);
02042
02043 } else if(i==l-2) {
02044 RenderLine(i,j,level,l2-2,j,level-1);
02045 RenderSupport(l2-2,j,level-1);
02046 RenderLine(i,j,level,l2-3,j,level-1);
02047 RenderSupport(l2-3,j,level-1);
02048 RenderLine(i,j,level,l2-4,j,level-1);
02049 RenderSupport(l2-4,j,level-1);
02050 RenderLine(i,j,level,l2-5,j,level-1);
02051 RenderSupport(l2-5,j,level-1);
02052 }
02053 }
02054 } else {
02055 if(j==0) {
02056 RenderLine(i,j,level,i,0,level-1);
02057 RenderSupport(i ,0 , level-1);
02058 RenderLine(i,j,level,i,1,level-1);
02059 RenderSupport(i ,1 , level-1);
02060
02061 } else if(j==1) {
02062 RenderLine(i,j,level,i,1,level-1);
02063 RenderSupport(i,1, level-1);
02064 RenderLine(i,j,level,i,2,level-1);
02065 RenderSupport(i,2, level-1);
02066 RenderLine(i,j,level,i,3,level-1);
02067 RenderSupport(i,3, level-1);
02068
02069 } else if(j==2) {
02070 RenderLine(i,j,level,i,2,level-1);
02071 RenderSupport(i,2,level-1);
02072 RenderLine(i,j,level,i,3,level-1);
02073 RenderSupport(i,3,level-1);
02074 RenderLine(i,j,level,i,4,level-1);
02075 RenderSupport(i,4,level-1);
02076 RenderLine(i,j,level,i,5,level-1);
02077 RenderSupport(i,5,level-1);
02078
02079 } else if(j>=3 && j<(Control_points[level][0].size()-3)) {
02080 RenderLine(i,j,level,i,2*(j-3)+3,level-1);
02081 RenderSupport(i,2*(j-3)+3,level-1);
02082 RenderLine(i,j,level,i,2*(j-3)+4,level-1);
02083 RenderSupport(i,2*(j-3)+4,level-1);
02084 RenderLine(i,j,level,i,2*(j-3)+5,level-1);
02085 RenderSupport(i,2*(j-3)+5,level-1);
02086 RenderLine(i,j,level,i,2*(j-3)+6,level-1);
02087 RenderSupport(i,2*(j-3)+6,level-1);
02088 RenderLine(i,j,level,i,2*(j-3)+7,level-1);
02089 RenderSupport(i,2*(j-3)+7,level-1);
02090
02091 } else {
02092 unsigned int l=(int)Control_points[level][0].size()-1;
02093 unsigned int l2=(int)Control_points[level-1][0].size()-1;
02094
02095 if(j==l) {
02096 RenderLine(i,j,level,i,l2,level-1);
02097 RenderSupport(i ,l2 , level-1);
02098 RenderLine(i,j,level,i,l2-1,level-1);
02099 RenderSupport(i,l2-1 , level-1);
02100
02101 } else if(j==l-1) {
02102 RenderLine(i,j,level,i,l2-1,level-1);
02103 RenderSupport(i,l2-1, level-1);
02104 RenderLine(i,j,level,i,l2-2,level-1);
02105 RenderSupport(i,l2-2, level-1);
02106 RenderLine(i,j,level,i,l2-3,level-1);
02107 RenderSupport(i,l2-3, level-1);
02108 } else if(j==l-2) {
02109 RenderLine(i,j,level,i,l2-2,level-1);
02110 RenderSupport(i,l2-2,level-1);
02111 RenderLine(i,j,level,i,l2-3,level-1);
02112 RenderSupport(i,l2-3,level-1);
02113 RenderLine(i,j,level,i,l2-4,level-1);
02114 RenderSupport(i,l2-4,level-1);
02115 RenderLine(i,j,level,i,l2-5,level-1);
02116 RenderSupport(i,l2-5,level-1);
02117 }
02118 }
02119 }
02120 }
02121 }
02122
02123 void BSplineSurface::RenderLine(int i1, int j1, int level1, int i2, int j2, int level2)
02124 {
02125 glBegin(GL_LINES);
02126
02127 glVertex3d(Control_points[level1][i1][j1][0],Control_points[level1][i1][j1][1],
02128 Control_points[level1][i1][j1][2]-(level1)*(MRES_OFF));
02129 glVertex3d(Control_points[level2][i2][j2][0],Control_points[level2][i2][j2][1],
02130 Control_points[level2][i2][j2][2]-(level2)*(MRES_OFF));
02131
02132 glEnd();
02133 }
02134
02135
02136 void BSplineSurface::SelectPoint(Point3d n, Matrix3d A,Point3d trans)
02137 {
02138 Point3d t;
02139
02140 double dis=1000;
02141
02142 for(unsigned int i=0;i<Control_points[selected_level].size();i++) {
02143 for(unsigned int j=0;j<Control_points[selected_level][0].size();j++) {
02144 t=Control_points[selected_level][i][j];
02145 t[2]=-t[2]+(selected_level)*(MRES_OFF);
02146 t=A*t;
02147 t[2]=0;
02148 t=t+trans;
02149 if( (n-t).norm()<dis) {
02150 dis=(n-t).norm();
02151 selected[0]=i;
02152 selected[1]=j;
02153 }
02154 }
02155 }
02156
02157 for(unsigned int i=0;i<footprint.size();i++) {
02158 footprint[i][1]=footprint[i][3]=10000000;
02159 footprint[i][0]=footprint[i][2]=-1;
02160 footprint[i][1]=footprint[i][3]=0;
02161 footprint[i][0]=(int)Control_points[i].size()-1;
02162 footprint[i][2]=(int)Control_points[i][0].size()-1;
02163 }
02164 CalcFootprint(selected[0],selected[1],selected_level);
02165 CalcPreImage(selected[0],selected[1],selected_level);
02166
02167 UpdateFootprint();
02168 }
02169
02170
02171 void BSplineSurface::MovePoint(Point3d n, Matrix3d A,Point3d trans)
02172 {
02173 Point3d t;
02174
02175 t=Control_points[selected_level][selected[0]][selected[1]];
02176 t[2]=-t[2]+(selected_level)*(MRES_OFF);
02177 t=A*t;
02178 t[0]=n[0]-trans[0];
02179 t[1]=n[1]-trans[1];
02180 t=(~A)*t;
02181
02182 t[2]=-t[2]+(selected_level)*(MRES_OFF);;
02183 Control_points[selected_level][selected[0]][selected[1]]=t;
02184
02185 UpdateFootprint();
02186 }
02187
02188
02189
02190
02191
02192
02193
02194
02195 bool BSplineSurface::EditLevel(unsigned int i)
02196 {
02197 bool valid=true;
02198
02199 if(i<Control_points.size())
02200 selected_level=i;
02201 else
02202 valid=false;
02203
02204 selected[0]=0;
02205 selected[1]=0;
02206
02207 for(unsigned int i=0;i<footprint.size();i++) {
02208
02209 footprint[i][1]=footprint[i][3]=100000000;
02210 footprint[i][0]=footprint[i][2]=-1;
02211
02212 }
02213
02214 CalcFootprint(selected[0],selected[1],selected_level);
02215 CalcPreImage(selected[0],selected[1],selected_level);
02216
02217 selected_region.clear();
02218 return valid;
02219 }
02220
02221 Point3d BSplineSurface::Eval(double u, double v) const
02222 {
02223 std::vector<Point3d> p_v(4);
02224
02225
02226 if(u>(n_u))
02227 u=n_u;
02228
02229 if(u<degree)
02230 u=degree;
02231
02232 if(v>(n_v))
02233 v=n_v;
02234
02235 if(v<degree)
02236 v=degree;
02237
02238 int delta=(int)v;
02239
02240 if(!periodic) {
02241 int i=0;
02242 for(;i<=degree && (delta-i)<=0;i++)
02243 p_v[i]=EvalU(u,0);
02244
02245 for(;i<=degree && (delta-i)<n_v;i++)
02246 p_v[i]=EvalU(u,delta-i);
02247
02248 int t=n_v-1;
02249 for(;i<=degree;i++)
02250 p_v[i]=EvalU(u,t);
02251
02252 } else {
02253 for(int i=0;i<=degree;i++)
02254 {
02255 p_v[i]=EvalU(u,(delta-i+n_v)%(n_v));
02256 }
02257 }
02258
02259 for(int i=degree+1; i>=2;i--) {
02260 double omega;
02261 double ind=delta;
02262 int j=0;
02263
02264 for(;j<=i-1 && (i-1+ind>=n_v);j++,ind--) {
02265 if(n_v-ind>0 && v-ind>0)
02266 omega= (v-ind)/(n_v-ind);
02267 else
02268 omega=0;
02269
02270 p_v[j]=p_v[j]*omega + p_v[j+1]*(1-omega);
02271
02272 }
02273
02274 for(;j<=i-1 ; j++, ind--){
02275 if((i-1+ind-(degree))<=0 || v-degree<=0){
02276 omega=0;
02277 }
02278 else if(ind<(degree)){
02279 omega= (v-(degree))/(i-1+ind-(degree));
02280 }
02281 else
02282 omega = (v-ind)/(i-1);
02283
02284 p_v[j]=p_v[j]*omega + p_v[j+1]*(1-omega);
02285
02286 }
02287 }
02288 return p_v[0];
02289 }
02290
02291 Point3d BSplineSurface::EvalU(double u, int m) const
02292 {
02293 std::vector<Point3d> p_u(4);
02294
02295 int delta=(int)u;
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343 if(!periodic) {
02344 int i=0;
02345 for(;i<=degree && (delta-i)<=0;i++)
02346 p_u[i]=Control_points[0][0][m];
02347
02348 for(;i<=degree && (delta-i)<n_u;i++)
02349 p_u[i]=Control_points[0][delta-i][m];
02350
02351 int t=n_u-1;
02352 for(;i<=degree;i++)
02353 p_u[i]=Control_points[0][t][m];
02354
02355 } else {
02356 for(int i=0;i<=degree;i++)
02357 p_u[i]=Control_points[0][(delta-i+n_u)%(n_u)][m];
02358 }
02359
02360
02361 for(int i=degree+1; i>=2;i--) {
02362 double omega;
02363 double ind=delta;
02364 int j=0;
02365
02366 for(;j<=i-1 && (i-1+ind>=n_u);j++,ind--) {
02367 if(n_u-ind>0 && u-ind>0)
02368 omega= (u-ind)/(n_u-ind);
02369 else
02370 omega=0;
02371
02372 p_u[j]=p_u[j]*omega + p_u[j+1]*(1-omega);
02373
02374 }
02375
02376
02377 for(;j<=i-1 ; j++, ind--){
02378 if((i-1+ind-(degree))<=0 || u-degree<=0){
02379 omega=0;
02380 }
02381 else if(ind<(degree)){
02382 omega= (u-(degree))/(i-1+ind-(degree));
02383 }
02384 else
02385 omega = (u-ind)/(i-1);
02386
02387 p_u[j]=p_u[j]*omega + p_u[j+1]*(1-omega);
02388
02389 }
02390
02391
02392 }
02393
02394
02395
02396
02397
02398 return p_u[0];
02399 }
02400
02401 void BSplineSurface::SelectRegion(vector<Point3d > s_reg, Matrix3d A,Point3d trans)
02402 {
02403 selected_region.clear();
02404
02405
02406
02407 selected_bb[0]=selected_bb[2]=0;
02408 selected_bb[1]=selected_bb[3]=0;
02409
02410 if(s_reg.size()>1) {
02411 for(unsigned int i=0; i<Control_points[selected_level].size();i++) {
02412 for(unsigned int j=0; j<Control_points[selected_level][0].size();j++) {
02413
02414 int *index=new int[2];
02415 index[0]=i;
02416 index[1]=j;
02417
02418 Point3d p=Control_points[selected_level][i][j];
02419
02420 p[2]=-p[2];
02421 p=A*p;
02422 p[2]=0;
02423 p=p+trans;
02424 if(InsideContour(s_reg,p))
02425 selected_region.push_back(index);
02426 }
02427 }
02428 }
02429 }
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502 bool BSplineSurface::InsideContour(vector< Point3d > shape, Point3d p) {
02503
02504 bool inside=false;
02505 for(unsigned int i=0;i<shape.size()-2;i++) {
02506 if( (shape[i][1]-p[1])*(shape[i+1][1]-p[1])<=0 || shape[i+1][1]==p[1]) {
02507 if(shape[i][0]<=p[0] && shape[i+1][0]<=p[0]) {
02508 inside=!inside;
02509
02510 } else if( (shape[i][0]-p[0])*(shape[i+1][0]-p[0])<=0 || shape[i+1][0]==p[0]) {
02511 double t=(p[1]-shape[i][1])/(shape[i+1][1]-shape[i][1]);
02512 if( (t*(shape[i+1][0] - shape[i][0])+shape[i][0])<=p[0]) {
02513 inside=!inside;
02514 }
02515 }
02516 }
02517 }
02518 if( (shape[shape.size()-1][1]-p[1])*(shape[0][1]-p[1])<0 || shape[0][1]==p[1]) {
02519 if(shape[shape.size()-1][0]<=p[0] && shape[0][0]<=p[0]) {
02520 inside=!inside;
02521
02522 } else if( (shape[shape.size()-1][0]-p[0])*(shape[0][0]-p[0])<0 || shape[0][0]==p[0]) {
02523 double t=(p[1]-shape[shape.size()-1][1])/(shape[0][1]-shape[shape.size()-1][1]);
02524
02525 if((t*(shape[0][0] - shape[shape.size()-1][0])+shape[shape.size()-1][0])<=p[0]) {
02526 inside=!inside;
02527
02528 }
02529 }
02530 }
02531 return inside;
02532 }
02533
02534 void BSplineSurface::MoveRegion(Point3d dis)
02535 {
02536 for(unsigned int i=0;i<selected_region.size();i++)
02537 Control_points[selected_level][selected_region[i][0]][selected_region[i][1]] =
02538 Control_points[selected_level][selected_region[i][0]][selected_region[i][1]]+dis;
02539
02540 for(unsigned int i=0;i<footprint.size();i++) {
02541 footprint[i][1]=footprint[i][3]=10000000;
02542 footprint[i][0]=footprint[i][2]=-1;
02543 footprint[i][1]=footprint[i][3]=0;
02544 footprint[i][0]=(int)Control_points[i].size()-1;
02545 footprint[i][2]=(int)Control_points[i][0].size()-1;
02546 }
02547 CalcFootprint(selected_bb[0],selected_bb[1],selected_level);
02548 CalcPreImage(selected_bb[0],selected_bb[1],selected_level);
02549
02550 CalcFootprint(selected_bb[0],selected_bb[3],selected_level);
02551 CalcPreImage(selected_bb[0],selected_bb[3],selected_level);
02552
02553 CalcFootprint(selected_bb[2],selected_bb[1],selected_level);
02554 CalcPreImage(selected_bb[2],selected_bb[1],selected_level);
02555
02556 CalcFootprint(selected_bb[2],selected_bb[3],selected_level);
02557 CalcPreImage(selected_bb[2],selected_bb[3],selected_level);
02558
02559 UpdateFootprint();
02560 }
02561
02562 Point3d BSplineSurface::NormalEval(double u, double v) const
02563 {
02564 Point3d p_u;
02565 Point3d p_v;
02566
02567 if(u>(n_u))
02568 u=n_u;
02569
02570 if(u<3)
02571 u=3;
02572
02573 if(v>(n_v))
02574 v=n_v;
02575
02576 if(v<3)
02577 v=3;
02578
02579 if(u>5.0)
02580 p_u=(Eval(u,v)-Eval(u-0.05,v))*(1.0/0.05);
02581 else
02582 p_u=(Eval(u+0.05,v)-Eval(u,v))*(1.0/0.05);
02583
02584 if(v>5.0)
02585 p_v=(Eval(u,v)-Eval(u,v-0.05))*(1.0/0.05);
02586 else
02587 p_v=(Eval(u,v+0.05)-Eval(u,v))*(1.0/0.05);
02588
02589 p_u=p_u*(1/p_u.norm());
02590 p_v=p_v*(1/p_v.norm());
02591
02592 p_u=p_u.cross(p_v);
02593
02594 float l=p_u.norm();
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616 p_u=p_u*(1/l);
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630 return p_u;
02631 }
02632
02633 BSplineSurface& BSplineSurface::operator=(const BSplineSurface& B)
02634 {
02635 _TextureId = B._TextureId;
02636 _scale = B._scale;
02637 _divU=B._divU;
02638 _divV=B._divV;
02639 _vrtx=B._vrtx;
02640 _nrml=B._nrml;
02641 _f_name=B._f_name;
02642
02643 if(B.precomputed) {
02644 _vrtx=B._vrtx;
02645 _nrml=B._nrml;
02646 precomputed=B.precomputed;
02647 }
02648 else
02649 precomputed=false;
02650
02651 Reset(B.n_u,B.n_v);
02652
02653 for(int i=0;i<n_u;i++)
02654 for(int j=0;j<n_v;j++)
02655 Control_points[0][i][j]=B.Control_points[0][i][j];
02656
02657 return *this;
02658 }
02659
02660 BSplineSurface BSplineSurface::operator+(const BSplineSurface& B)
02661 {
02662 BSplineSurface A1=(*this);
02663 BSplineSurface A2=B;
02664 BSplineSurface P;
02665
02666 while(A1.n_u<A2.n_u)
02667 A1.DoubleU();
02668
02669 while(A2.n_u<A1.n_u)
02670 A2.DoubleU();
02671
02672 while(A1.n_v<A2.n_v)
02673 A1.DoubleV();
02674
02675 while(A2.n_v<A1.n_v)
02676 A2.DoubleV();
02677
02678 P.Reset(A1.n_u,A1.n_v);
02679
02680 for(int i=0;i<P.n_u;i++)
02681 for(int j=0;j<P.n_v;j++)
02682 P.Control_points[0][i][j]=A1.Control_points[0][i][j]+A2.Control_points[0][i][j];
02683
02684 return P;
02685 }
02686
02687 BSplineSurface BSplineSurface::operator-(const BSplineSurface& B)
02688 {
02689 BSplineSurface A1=(*this);
02690 BSplineSurface A2=B;
02691 BSplineSurface P;
02692
02693 while(A1.n_u<A2.n_u)
02694 A1.DoubleU();
02695
02696 while(A2.n_u<A1.n_u)
02697 A2.DoubleU();
02698
02699 while(A1.n_v<A2.n_v)
02700 A1.DoubleV();
02701
02702 while(A2.n_v<A1.n_v)
02703 A2.DoubleV();
02704
02705 P.Reset(A1.n_u,A1.n_v);
02706
02707 for(int i=0;i<P.n_u;i++)
02708 for(int j=0;j<P.n_v;j++)
02709 P.Control_points[0][i][j]=A1.Control_points[0][i][j]-A2.Control_points[0][i][j];
02710
02711 return P;
02712 }
02713
02714 BSplineSurface BSplineSurface::operator*(const double c)
02715 {
02716 BSplineSurface P=(*this);
02717
02718 P.Reset(n_u,n_v);
02719
02720 for(int i=0;i<n_u;i++)
02721 for(int j=0;j<n_v;j++)
02722 P.Control_points[0][i][j]=Control_points[0][i][j]*c;
02723
02724 return P;
02725 }
02726
02727
02728 void BSplineSurface::SetColors(double c1[3],double c2[3],double c3[3])
02729 {
02730 for(int i=0;i<3;i++) {
02731 sel_point[i]=c1[i];
02732 unsel_point[i]=c2[i];
02733 poly_line[i]=c3[i];
02734 }
02735 }
02736
02737 Point3d BSplineSurface::PartialU(double u, double v) const
02738 {
02739 Point3d p_u,Eu1,Eu2;
02740 Point2d u1,u2;
02741
02742 u1[0]=u2[0]=u;
02743 u1[1]=u2[1]=v;
02744
02745 u1[0]-=5*err_tol;
02746 u2[0]+=5*err_tol;
02747 Eu1=Eval(u1[0],u1[1]);
02748 Eu2=Eval(u2[0],u2[1]);
02749
02750 if(u1[0]<3.0)
02751 u1[0]=3.0;
02752
02753 if(u2[0]>(n_u))
02754 u2[0]=(n_u);
02755
02756 p_u=(Eu2-Eu1)*(1.0/(fabs(u1[0]-u2[0])));
02757
02758 return p_u;
02759 }
02760
02761 Point3d BSplineSurface::PartialV(double u, double v) const
02762 {
02763
02764 Point3d p_v,Ev1,Ev2;
02765 Point2d v1,v2;
02766
02767 v1[0]=v2[0]=u;
02768 v1[1]=v2[1]=v;
02769
02770 v1[1]-=5*err_tol;
02771 v2[1]+=5*err_tol;
02772 Ev1=Eval(v1[0],v1[1]);
02773 Ev2=Eval(v2[0],v2[1]);
02774
02775 if(v1[1]<3.0)
02776 v1[1]=3.0;
02777
02778 if(v2[1]>(n_u))
02779 v2[1]=(n_u);
02780
02781 p_v=(Ev2-Ev1)*(1.0/(fabs(v1[1]-v2[1])));
02782
02783 return p_v;
02784
02785 }
02786
02787 bool BSplineSurface::PointInversion(Point2d &surf_p, Point2d p0, Point3d cp) const
02788 {
02789
02790
02791 Point2d u1,u2;
02792 Point3d Eu1,Eu2;
02793 Point2d v1,v2;
02794 Point3d Ev1,Ev2;
02795 Point2d p=p0;
02796 Point2d prev_step;
02797 Point3d Esurf_p;
02798
02799 double dis=1000;
02800 double count=0;
02801 double du,dv;
02802
02803
02804
02805 surf_p=p0;
02806 Esurf_p=Eval(surf_p[0],surf_p[1]);
02807
02808 while(fabs(dis-(cp-Esurf_p).norm())>err_tol && count<max_it) {
02809 count++;
02810 dis=(cp-Esurf_p).norm();
02811
02812 if(surf_p[0]<3)
02813 surf_p[0]=3;
02814
02815 if(surf_p[0]>(n_u))
02816 surf_p[0]=(n_u);
02817
02818
02819 if(surf_p[1]<3)
02820 surf_p[1]=3;
02821
02822 if(surf_p[1]>(n_v))
02823 surf_p[1]=(n_v);
02824
02825
02826
02827
02828 u1=surf_p;
02829 u2=surf_p;
02830 u1[0]-=5*err_tol;
02831 u2[0]+=5*err_tol;
02832 Eu1=Eval(u1[0],u1[1]);
02833 Eu2=Eval(u2[0],u2[1]);
02834
02835 Point3d Fu= Eu2-Eu1;
02836 Fu= Fu*(1/Fu.norm());
02837
02838 if(u1[0]<3.0)
02839 u1[0]=3.0;
02840
02841 if(u2[0]>(n_u))
02842 u2[0]=(n_u);
02843
02844
02845
02846
02847 v1=surf_p;
02848 v2=surf_p;
02849 v1[1]-=5*err_tol;
02850 v2[1]+=5*err_tol;
02851 Ev1=Eval(v1[0],v1[1]);
02852 Ev2=Eval(v2[0],v2[1]);
02853
02854 if(v1[1]<3.0)
02855 v1[1]=3.0;
02856
02857 if(v2[1]>(n_v))
02858 v2[1]=(n_v);
02859
02860
02861
02862 Point3d Fv= Ev2-Ev1;
02863 Fv= Fv*(1/Fv.norm());
02864
02865 float c=1;
02866
02867
02868 du=-( (cp-Esurf_p-Fu*(fabs(u2[0]-u1[0]))*c).norm() - (cp-Esurf_p).norm() )/(fabs(u2[0]-u1[0]));
02869 dv=-( (cp-Esurf_p-Fv*(fabs(v2[1]-v1[1]))*c).norm() - (cp-Esurf_p).norm() )/(fabs(v2[1]-v1[1]));
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879 double step=0.01;
02880 int search_steps=0;
02881 while( step > err_tol && search_steps<inner_loop_max_it) {
02882 search_steps++;
02883
02884 Point2d temp=surf_p;
02885
02886 temp[0]+=step*du;
02887 temp[1]+=step*dv;
02888
02889 if(temp[0]<3)
02890 temp[0]=3;
02891
02892 if(temp[0]>(n_u))
02893 temp[0]=(n_u);
02894
02895
02896 if(temp[1]<3)
02897 temp[1]=3;
02898
02899 if(temp[1]>(n_v))
02900 temp[1]=(n_v);
02901
02902
02903
02904 Point3d Etemp=Eval(temp[0],temp[1]);
02905
02906 if( (Etemp-cp).norm()<(Esurf_p-cp).norm()) {
02907 step*=7.1;
02908 surf_p=temp;
02909
02910 Esurf_p=Etemp;
02911
02912 } else
02913 step/=6.7;
02914 }
02915
02916
02917
02918 }
02919 if(surf_p[0]<3)
02920 surf_p[0]=3;
02921
02922 if(surf_p[0]>(n_u))
02923 surf_p[0]=(n_u);
02924
02925
02926 if(surf_p[1]<3)
02927 surf_p[1]=3;
02928
02929 if(surf_p[1]>(n_v))
02930 surf_p[1]=(n_v);
02931
02932
02933
02934 if(count>=max_it)
02935 return false;
02936 else
02937 return true;
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042 }
03043
03044 Point3d BSplineSurface::EvalN(double u, double v) const
03045 {
03046 return Eval(ConvertU(u),ConvertV(v));
03047 }
03048
03049 Point3d BSplineSurface::NormalEvalN(double u, double v) const
03050 {
03051 return NormalEval(ConvertU(u),ConvertV(v));
03052 }
03053
03054 Point3d BSplineSurface::PartialUN(double u, double v) const
03055 {
03056 return PartialU(ConvertU(u),ConvertV(v));
03057 }
03058
03059 Point3d BSplineSurface::PartialVN(double u, double v) const
03060 {
03061 return PartialU(ConvertU(u),ConvertV(v));
03062 }
03063
03064 Point3d BSplineSurface::ContourEval(double u) const
03065 {
03066 Point3d p;
03067 Point2d k;
03068
03069 k=ContourInverse(u);
03070 p=EvalN(k[0],k[1]);
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082 return p;
03083 }
03084
03085 Point2d BSplineSurface::ContourInverse(double u) const
03086 {
03087 Point2d k;
03088 u = fmod(u,1.0);
03089
03090 if(u<=0.25) {
03091 k[0]=0.00;
03092 k[1]=u/0.25;
03093 }
03094 else if(u<=0.5) {
03095 k[0]=(u-0.25)/0.25;
03096 k[1]=1.0;
03097 }
03098 else if(u<=0.75) {
03099 k[0]=1.0;
03100 k[1]=1.0-(u-0.5)/0.25;;
03101 }
03102 else{
03103 k[0]=1.0-(u-0.75)/0.25;
03104 k[1]=0.0;
03105 }
03106
03107
03108
03109
03110
03111
03112 return k;
03113 }
03114
03115 bool BSplineSurface::PointInversionN(Point2d &surf_p, Point2d p0, Point3d q) const
03116 {
03117 bool error;
03118 surf_p[0]=ConvertU(surf_p[0]);
03119 surf_p[1]=ConvertV(surf_p[1]);
03120
03121 p0[0]=ConvertU(p0[0]);
03122 p0[1]=ConvertV(p0[1]);
03123
03124 error = PointInversion(surf_p,p0,q);
03125
03126 surf_p[0]= (surf_p[0]-3.0)/(n_u-degree);
03127 surf_p[1]= (surf_p[1]-3.0)/(n_v-degree);
03128
03129 return error;
03130 };
03131
03132 double BSplineSurface::ConvertU(double u) const{
03133 return (u*(n_u-degree) )+3.0;
03134 }
03135
03136 double BSplineSurface::ConvertV(double v) const{
03137 return (v*(n_v-degree) )+3.0;
03138 }
03139
03140 BSplineSurface BSplineSurface::Interpolate(const BSplineSurface &BS1, const BSplineSurface &BS2,
03141 double alpha, int num_rows, int num_cols) const {
03142 BSplineSurface interpolated=BS1;
03143 BSplineSurface s1=BS1;
03144 BSplineSurface s2=BS2;
03145
03146 s1.Resize(num_rows,num_cols);
03147 s2.Resize(num_rows,num_cols);
03148
03149 interpolated=s1*(1-alpha) + s2*(alpha);
03150 return interpolated;
03151 }
03152
03153 unsigned int BSplineSurface::LowestResDim(int i) {
03154
03155 if(i==0)
03156 return (int)Control_points[(int)Control_points.size()-1].size();
03157
03158 if(i==1)
03159 return (int)Control_points[(int)Control_points.size()-1][0].size();
03160
03161 return 0;
03162 }
03163
03164 BSplineSurface BSplineSurface::LowestRes()
03165 {
03166 BSplineSurface l_res=(*this);
03167 int k=(int)Control_points.size()-1;
03168 l_res.Reset(LowestResDim(0),LowestResDim(1));
03169
03170 for(int i=0;i<l_res.n_u;i++)
03171 for(int j=0;j<l_res.n_v;j++)
03172 l_res.Control_points[0][i][j]=Control_points[k][i][j];
03173
03174 return l_res;
03175 }
03176
03177 void BSplineSurface::Resize(unsigned int num_rows,unsigned int num_cols)
03178 {
03179 if(num_rows<LowestResDim(0) || num_cols<LowestResDim(1) ) {
03180
03181 while(num_rows<LowestResDim(0) && num_rows>=MIN_HEIGHT)
03182 HalveU();
03183 while(num_cols<LowestResDim(1) && num_cols>=MIN_WIDTH)
03184 HalveV();
03185
03186 (*this)=LowestRes();
03187
03188 }
03189
03190 if(num_rows>Control_points[0].size() || num_cols>Control_points[0][0].size() ) {
03191 while(num_rows>=2*Control_points[0].size()-3 )
03192 DoubleU();
03193 while(num_cols>=2*Control_points[0][0].size()-3 )
03194 DoubleV();
03195 }
03196
03197
03198 }
03199
03200 }
03201
03202 }