00001 #include "std/support.H"
00002 #include "glew/glew.H"
00003
00004 #include "uv_data.H"
00005 #include "uv_mapping.H"
00006 #include "bmesh.H"
00007 #include "std/config.H"
00008
00009 using namespace mlib;
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #define DEBUG_DOT_HEIGHT 200
00020 #define MAPPING_SIZE 100
00021 #define MAPPING_BINS MAPPING_SIZE*MAPPING_SIZE
00022
00023 #define DEBUG_SIZE (MAPPING_SIZE + DEBUG_DOT_HEIGHT)*MAPPING_SIZE
00024
00025
00026
00027
00028 UVMapping::UVMapping(Bface *f) :
00029 _seed_face(f),
00030 _face_cnt(0),
00031 _bin_cnt(0),
00032 _entry_cnt(0),
00033 _use_cnt(0),
00034 _du(-1.0),
00035 _dv(-1.0),
00036 _wrap_u(false),
00037 _wrap_v(false),
00038 _wrap_bad(false),
00039 _virgin_debug_image(0),
00040 _marked_debug_image(0)
00041 {
00042
00043 int k;
00044
00045 assert(_seed_face);
00046
00047 _mapping.clear();
00048 for (k=0 ; k < MAPPING_BINS ; k++) _mapping.add(new ARRAY<Bface*>);
00049
00050 compute_limits(f);
00051 compute_mapping(f);
00052 compute_wrapping(f);
00053
00054
00055 if (Config::get_var_bool("HATCHING_DEBUG_MAPPING",false))
00056 compute_debug_image();
00057
00058
00059 }
00060
00061
00062
00063
00064 UVMapping::~UVMapping()
00065 {
00066
00067
00068 UVdata* uvd;
00069 int k, i, cnt=0;
00070
00071
00072 assert(!_use_cnt);
00073
00074
00075 for (k=0;k<_mapping.num();k++)
00076 {
00077 for (i=0;i<_mapping[k]->num();i++)
00078 {
00079 uvd = UVdata::lookup((*_mapping[k])[i]);
00080 assert(uvd);
00081 if (uvd->mapping())
00082 {
00083 assert(uvd->mapping()==this);
00084 uvd->set_mapping(0);
00085 cnt++;
00086 }
00087 }
00088 }
00089
00090 err_mesg(ERR_LEV_WARN,
00091 "UVMapping::~UVMapping() - Removed from %d faces (should have been %d).",
00092 cnt, _face_cnt);
00093
00094 for (k=0;k<_mapping.num();k++) delete _mapping[k];
00095 _mapping.clear();
00096
00097 if (_virgin_debug_image) delete[] _virgin_debug_image;
00098 if (_marked_debug_image) delete[] _marked_debug_image;
00099
00100 }
00101
00102
00103
00104
00105 void
00106 UVMapping::draw_debug()
00107 {
00108
00109 int w,h;
00110
00111 VIEW_SIZE(w,h);
00112
00113
00114
00115
00116 glMatrixMode(GL_MODELVIEW);
00117 glPushMatrix();
00118 glLoadIdentity();
00119 glMatrixMode(GL_PROJECTION);
00120 glPushMatrix();
00121 glLoadMatrixd(VIEW::peek()->pix_proj().transpose().matrix());
00122
00123 glRasterPos2i(w-MAPPING_SIZE,0);
00124
00125 glPushAttrib(GL_ENABLE_BIT);
00126 glDisable(GL_BLEND);
00127
00128 glDrawPixels(MAPPING_SIZE,MAPPING_SIZE + DEBUG_DOT_HEIGHT,GL_RGB,GL_UNSIGNED_BYTE,_marked_debug_image);
00129
00130 glPopAttrib();
00131
00132 glPopMatrix();
00133 glMatrixMode(GL_MODELVIEW);
00134 glPopMatrix();
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 void
00150 UVMapping::compute_debug_image()
00151 {
00152
00153 err_mesg(ERR_LEV_SPAM, "UVMapping::compute_debug_map()");
00154
00155 int k, max=0;
00156
00157 assert(!_virgin_debug_image);
00158 assert(!_marked_debug_image);
00159
00160 _virgin_debug_image = new unsigned char[3*DEBUG_SIZE];
00161 assert(_virgin_debug_image);
00162 _marked_debug_image = new unsigned char[3*DEBUG_SIZE];
00163 assert(_marked_debug_image);
00164
00165 assert(_mapping.num() == MAPPING_BINS);
00166
00167 for (k=0;k<_mapping.num();k++)
00168 if (_mapping[k]->num() > max)
00169 max = _mapping[k]->num();
00170
00171
00172
00173 GLubyte b;
00174 for (k=0;k<MAPPING_BINS;k++)
00175 {
00176 b = (unsigned char)( (double)(0x88)*
00177 ( (double)(_mapping[k]->num()) / (double)(max) ) );
00178
00179 if (b)
00180 {
00181 _virgin_debug_image[3*k ] = b;
00182 _virgin_debug_image[3*k+1] = b;
00183 _virgin_debug_image[3*k+2] = b;
00184 }
00185 else
00186 {
00187 _virgin_debug_image[3*k ] = 0;
00188 _virgin_debug_image[3*k+1] = 0x99;
00189 _virgin_debug_image[3*k+2] = 0xFF;
00190 }
00191 }
00192
00193
00194
00195 for (k=MAPPING_BINS;k<DEBUG_SIZE;k++)
00196 {
00197 b = (unsigned char)0;
00198
00199 _virgin_debug_image[3*k ] = b;
00200 _virgin_debug_image[3*k+1] = b;
00201 _virgin_debug_image[3*k+2] = b;
00202
00203 }
00204
00205 int h = int(floor( ( 0.0 + 1.0 ) * (double) DEBUG_DOT_HEIGHT / 2.0 ));
00206 if (h==DEBUG_DOT_HEIGHT) h--;
00207
00208 for (int u=0; u<MAPPING_SIZE; u++)
00209 {
00210 k = (MAPPING_SIZE + h) * MAPPING_SIZE + u;
00211
00212 _virgin_debug_image[3*k ] = 0x90;
00213 _virgin_debug_image[3*k+1] = 0x90;
00214 _virgin_debug_image[3*k+2] = 0x90;
00215 }
00216
00217 clear_debug_image();
00218 }
00219
00220
00221
00222 void
00223 UVMapping::clear_debug_image()
00224 {
00225 static bool cool = Config::get_var_bool("HATCHING_DEBUG_MAPPING",false);
00226 assert(cool);
00227
00228 for (int i=0; i<3*DEBUG_SIZE; i++)
00229 _marked_debug_image[i] = _virgin_debug_image[i];
00230 }
00231
00232
00233
00234
00235 void
00236 UVMapping::debug_dot(
00237 double ewe,
00238 double val,
00239 unsigned char r,
00240 unsigned char g,
00241 unsigned char b)
00242 {
00243 static bool cool = Config::get_var_bool("HATCHING_DEBUG_MAPPING",false);
00244 assert(cool);
00245
00246 assert(val >= -1.0);
00247 assert(val <= 1.0);
00248
00249 int u = int(floor( ( ewe - _min_u ) / _du ));
00250 if (u==MAPPING_SIZE) u--;
00251
00252 int h = int(floor( ( val + 1.0 ) * (double) DEBUG_DOT_HEIGHT / 2.0 ));
00253 if (h==DEBUG_DOT_HEIGHT) h--;
00254
00255 int k = (MAPPING_SIZE + h) * MAPPING_SIZE + u;
00256
00257 _marked_debug_image[3*k ] = r;
00258 _marked_debug_image[3*k+1] = g;
00259 _marked_debug_image[3*k+2] = b;
00260
00261 }
00262
00263
00264
00265
00266 void
00267 UVMapping::compute_limits(Bface *f)
00268 {
00269 int k;
00270
00271 assert(f);
00272
00273
00274 UVdata* uvdata = UVdata::lookup(f);
00275 assert(uvdata);
00276
00277
00278 assert(uvdata->mapping()==0);
00279
00280
00281 _min_u = uvdata->uv(1)[0];
00282 _max_u = uvdata->uv(1)[0];
00283 _min_v = uvdata->uv(1)[1];
00284 _max_v = uvdata->uv(1)[1];
00285
00286
00287 CBface_list& faces = f->mesh()->faces();
00288 for (k=0; k< faces.num(); k++) faces[k]->clear_bit(1);
00289
00290
00291 recurse(f,&UVMapping::add_limit);
00292
00293
00294 assert( _min_u < _max_u );
00295 assert( _min_v < _max_v );
00296
00297 _span_u = _max_u - _min_u;
00298 _span_v = _max_v - _min_v;
00299
00300 _du = _span_u/(double)MAPPING_SIZE;
00301 _dv = _span_v/(double)MAPPING_SIZE;
00302
00303 err_mesg(ERR_LEV_INFO,
00304 "UVMapping::compute_limits() - u_min=%f u_max=%f v_min=%f v_max=%f u_span=%f v_span=%f",
00305 _min_u, _max_u, _min_v, _max_v, _span_u, _span_v);
00306 }
00307
00308
00309
00310
00311 void
00312 UVMapping::compute_mapping(Bface *f)
00313 {
00314 int k;
00315
00316 assert(f);
00317
00318
00319 UVdata* uvdata = UVdata::lookup(f);
00320 assert(uvdata);
00321
00322
00323 assert(uvdata->mapping()==0);
00324
00325
00326 CBface_list& faces = f->mesh()->faces();
00327 for (k=0; k< faces.num(); k++) faces[k]->clear_bit(1);
00328
00329
00330 recurse(f,&UVMapping::add_face);
00331
00332 err_mesg(ERR_LEV_INFO,
00333 "UVMapping::generate_mapping() - %d faces added to mapping (from %d in mesh) using %d entries.",
00334 _face_cnt, faces.num(), _entry_cnt);
00335
00336 err_mesg(ERR_LEV_INFO,
00337 "UVMapping::generate_mapping() - %d populated bins of possible %d (%d holes).",
00338 _bin_cnt, MAPPING_BINS, MAPPING_BINS-_bin_cnt);
00339 }
00340
00341
00342
00343
00344 void
00345 UVMapping::compute_wrapping(Bface *f)
00346 {
00347 int k;
00348
00349 assert(f);
00350
00351
00352 UVdata* uvdata = UVdata::lookup(f);
00353 assert(uvdata);
00354
00355
00356 assert(uvdata->mapping()==this);
00357
00358
00359 CBface_list& faces = f->mesh()->faces();
00360 for (k=0; k< faces.num(); k++) faces[k]->clear_bit(1);
00361
00362
00363 recurse_wrapping(f);
00364
00365 if (_wrap_bad)
00366 err_mesg(ERR_LEV_WARN, "UVMapping::compute_mapping() - No wrapping set due to anomolous seam.");
00367 if (_wrap_u)
00368 err_mesg(ERR_LEV_INFO, "UVMapping::compute_mapping() - Wrapping in u at (%f,%f) discontinuity.", _min_u, _max_u);
00369 if (_wrap_v)
00370 err_mesg(ERR_LEV_INFO, "UVMapping::compute_mapping() - Wrapping in v at (%f,%f) discontinuity.", _min_v, _max_v);
00371 if ( (!_wrap_bad) && (!_wrap_u) && (!_wrap_v) )
00372 err_mesg(ERR_LEV_INFO, "UVMapping::compute_mapping() - No wrapping detected.");
00373
00374 }
00375
00376
00377
00378
00379 void
00380 UVMapping::recurse_wrapping(Bface *seed_f)
00381 {
00382 int k;
00383
00384 Bface *f;
00385 ARRAY<Bface*> faces;
00386
00387 assert(seed_f);
00388
00389 faces.push(seed_f);
00390
00391 while (faces.num()>0)
00392 {
00393
00394 f = faces.pop();
00395
00396
00397 if (!f->is_set(1))
00398 {
00399 f->set_bit(1);
00400
00401
00402
00403 UVdata* uvdata = UVdata::lookup(f);
00404 assert(uvdata);
00405 assert(uvdata->mapping()==this);
00406
00407 for (k=1; k<=3; k++)
00408 {
00409 Bedge *nxt_e = f->e(k);
00410 assert(nxt_e);
00411 Bface *nxt_f = nxt_e->other_face(f);
00412 if (nxt_f)
00413 {
00414 UVdata *nxt_uvdata = UVdata::lookup(nxt_f);
00415 if (nxt_uvdata)
00416 {
00417 UVpt uva = uvdata->uv(k);
00418 UVpt uvb = uvdata->uv((k==3)?(1):(k+1));
00419 int nxt_k = ( (nxt_f->e1()==nxt_e)?(1):
00420 ((nxt_f->e2()==nxt_e)?(2):
00421 ((nxt_f->e3()==nxt_e)?(3):(0))));
00422 assert(nxt_k);
00423 UVpt nxt_uva = nxt_uvdata->uv(nxt_k);
00424 UVpt nxt_uvb = nxt_uvdata->uv((nxt_k==3)?(1):(nxt_k+1));
00425
00426
00427
00428 if ((uva==nxt_uvb)&&(uvb==nxt_uva))
00429 {
00430
00431 faces.push(nxt_f);
00432 }
00433
00434
00435
00436
00437
00438
00439 else
00440 {
00441
00442 if (nxt_uvdata->mapping() == this)
00443 {
00444
00445
00446
00447
00448
00449
00450
00451 if ((uva[0]==uvb[0])&&(nxt_uva[0]==nxt_uvb[0]))
00452 {
00453
00454
00455
00456 if ( (uva[0]==_min_u && nxt_uva[0]==_max_u) ||
00457 (uva[0]==_max_u && nxt_uva[0]==_min_u))
00458 {
00459
00460 if (!_wrap_u)
00461 {
00462 err_mesg(ERR_LEV_SPAM, "UVMapping::recurse_wrapping() - Found a valid wrapping seam in u.");
00463 _wrap_u = true;
00464 }
00465 }
00466 else
00467 {
00468
00469
00470
00471 _wrap_bad = true;
00472 _wrap_u = false;
00473 _wrap_v = false;
00474
00475 err_mesg(ERR_LEV_WARN,
00476 "UVMapping::recurse_wrapping() - Found an INVALID wrapping seam in u: (%f,%f) since u extrema are: (%f,%f)",
00477 uva[0], nxt_uva[0], _min_u, _max_u);
00478 err_mesg(ERR_LEV_WARN, "UVMapping::recurse_wrapping() - Aborting all wrapping.");
00479 }
00480 }
00481 else if ((uva[1]==uvb[1])&&(nxt_uva[1]==nxt_uvb[1]))
00482 {
00483
00484
00485
00486 if ( (uva[1]==_min_v && nxt_uva[1]==_max_v) ||
00487 (uva[1]==_max_v && nxt_uva[1]==_min_v))
00488 {
00489
00490 if (!_wrap_v)
00491 {
00492 err_mesg(ERR_LEV_INFO, "UVMapping::recurse_wrapping() - Found a valid wrapping seam in v.");
00493 _wrap_v = true;
00494 }
00495 }
00496 else
00497 {
00498
00499
00500
00501 _wrap_bad = true;
00502 _wrap_u = false;
00503 _wrap_v = false;
00504
00505 err_mesg(ERR_LEV_WARN,
00506 "UVMapping::recurse_wrapping() - Found an INVALID wrapping seam in v: (%f,%f) since v extrema are: (%f,%f)",
00507 uva[1], nxt_uva[1], _min_v, _max_v);
00508 err_mesg(ERR_LEV_WARN, "UVMapping::recurse_wrapping() - Aborting all wrapping.");
00509 }
00510 }
00511 else
00512 {
00513
00514
00515
00516 _wrap_bad = true;
00517 _wrap_u = false;
00518 _wrap_v = false;
00519
00520 err_mesg(ERR_LEV_WARN,
00521 "UVMapping::recurse_wrapping() - Found an INVALID wrapping. The seam wasn't constant in u or v.");
00522 err_mesg(ERR_LEV_WARN,
00523 "UVMapping::recurse_wrapping() - Edge #1 (%f,%f)-(%f,%f) Edge #2 (%f,%f)-(%f,%f)",
00524 uva[0], uva[1], uvb[0], uvb[1], nxt_uvb[0], nxt_uvb[1], nxt_uva[0], nxt_uva[1]);
00525 err_mesg(ERR_LEV_WARN,
00526 "UVMapping::recurse_wrapping() - Aborting all wrapping.");
00527 }
00528 }
00529 }
00530 }
00531 }
00532 }
00533 }
00534 }
00535 }
00536
00537
00538
00539
00540 void
00541 UVMapping::recurse(Bface *seed_f, rec_fun_t fun )
00542 {
00543 int k;
00544
00545
00546 Bface* f;
00547 ARRAY<Bface*> faces;
00548
00549 assert(seed_f);
00550
00551 faces.push(seed_f);
00552
00553 while (faces.num()>0)
00554 {
00555
00556 f = faces.pop();
00557
00558
00559 if (!f->is_set(1))
00560 {
00561 f->set_bit(1);
00562
00563
00564
00565 UVdata* uvdata = UVdata::lookup(f);
00566 assert(uvdata);
00567 assert(uvdata->mapping()==0);
00568
00569
00570 (this->*fun)(f);
00571
00572 for (k=1; k<=3; k++)
00573 {
00574 Bedge *nxt_e = f->e(k);
00575 assert(nxt_e);
00576 Bface *nxt_f = nxt_e->other_face(f);
00577 if (nxt_f)
00578 {
00579 UVdata *nxt_uvdata = UVdata::lookup(nxt_f);
00580 if (nxt_uvdata)
00581 {
00582 UVpt uva = uvdata->uv(k);
00583 UVpt uvb = uvdata->uv((k==3)?(1):(k+1));
00584 int nxt_k = ( (nxt_f->e1()==nxt_e)?(1):
00585 ((nxt_f->e2()==nxt_e)?(2):
00586 ((nxt_f->e3()==nxt_e)?(3):(0))));
00587 assert(nxt_k);
00588 UVpt nxt_uva = nxt_uvdata->uv(nxt_k);
00589 UVpt nxt_uvb = nxt_uvdata->uv((nxt_k==3)?(1):(nxt_k+1));
00590
00591
00592
00593 if ((uva==nxt_uvb)&&(uvb==nxt_uva))
00594 {
00595
00596 faces.push(nxt_f);
00597 }
00598 else {
00599
00600 }
00601 }
00602 }
00603 }
00604 }
00605 }
00606 }
00607
00608
00609
00610
00611 void
00612 UVMapping::add_limit(Bface *f)
00613 {
00614 int k;
00615
00616 assert(f);
00617
00618 UVdata* uvdata = UVdata::lookup(f);
00619 assert(uvdata);
00620 assert(uvdata->mapping()==0);
00621
00622
00623 for (k=1; k<=3; k++)
00624 {
00625 if ( uvdata->uv(k)[0] < _min_u )
00626 _min_u = uvdata->uv(k)[0];
00627 if ( uvdata->uv(k)[0] > _max_u )
00628 _max_u = uvdata->uv(k)[0];
00629 if ( uvdata->uv(k)[1] < _min_v )
00630 _min_v = uvdata->uv(k)[1];
00631 if ( uvdata->uv(k)[1] > _max_v )
00632 _max_v = uvdata->uv(k)[1];
00633 }
00634
00635 }
00636
00637
00638
00639
00640
00641 void
00642 UVMapping::add_face(Bface *f)
00643 {
00644 int k, u, v;
00645 int umax=0, vmax=0;
00646 int umin=MAPPING_SIZE-1, vmin=MAPPING_SIZE-1;
00647 int entry_count = 0;
00648 int bin_count = 0;
00649
00650 assert(f);
00651
00652 UVdata* uvdata = UVdata::lookup(f);
00653 assert(uvdata);
00654 assert(uvdata->mapping()==0);
00655
00656
00657 for (k=1; k<=3; k++)
00658 {
00659 assert( uvdata->uv(k)[0] <= _max_u );
00660 assert( uvdata->uv(k)[1] <= _max_v );
00661 assert( uvdata->uv(k)[0] >= _min_u );
00662 assert( uvdata->uv(k)[1] >= _min_v );
00663 }
00664
00665
00666 for (k=1; k<=3; k++)
00667 {
00668 u = int(floor( (uvdata->uv(k)[0] - _min_u) / _du ));
00669 if (u==MAPPING_SIZE) u--;
00670 v = int(floor( (uvdata->uv(k)[1] - _min_v ) /_dv ));
00671 if (v==MAPPING_SIZE) v--;
00672
00673 if (u<umin) umin=u;
00674 if (u>umax) umax=u;
00675
00676 if (v<vmin) vmin=v;
00677 if (v>vmax) vmax=v;
00678 }
00679
00680
00681
00682
00683
00684 if (umin>0) umin--;
00685 if (vmin>0) vmin--;
00686 if (umax<MAPPING_SIZE-1) umax++;
00687 if (vmax<MAPPING_SIZE-1) vmax++;
00688
00689
00690 assert(umin>=0);
00691 assert(vmin>=0);
00692
00693 assert(umax<MAPPING_SIZE);
00694 assert(vmax<MAPPING_SIZE);
00695
00696 assert(umax>=umin);
00697 assert(vmax>=vmin);
00698
00699 UVpt_list box;
00700 UVpt_list tri;
00701
00702 bool isect;
00703
00704 for (v=vmin; v<=vmax; v++)
00705 {
00706 for (u=umin; u<=umax; u++)
00707 {
00708 isect = false;
00709
00710 box.clear();
00711 tri.clear();
00712
00713 box += UVpt( _min_u + u *_du , _min_v + v * _dv );
00714 box += UVpt( _min_u + (u+1) *_du , _min_v + v * _dv );
00715 box += UVpt( _min_u + (u+1) *_du , _min_v + (v+1) * _dv );
00716 box += UVpt( _min_u + u *_du , _min_v + (v+1) * _dv );
00717
00718 tri += uvdata->uv1();
00719 tri += uvdata->uv2();
00720 tri += uvdata->uv3();
00721
00722
00723 if (box.contains(tri)) isect = true;
00724 else if (tri.contains(box)) isect = true;
00725
00726 else
00727 {
00728 for (k=0; k<3; k++)
00729 {
00730 if (!isect)
00731 {
00732 if (intersect(box[0],box[1],tri[k],tri[(k+1)%3])) isect=true;
00733 else if (intersect(box[1],box[2],tri[k],tri[(k+1)%3])) isect=true;
00734 else if (intersect(box[2],box[3],tri[k],tri[(k+1)%3])) isect=true;
00735 else if (intersect(box[3],box[0],tri[k],tri[(k+1)%3])) isect=true;
00736
00737 }
00738 }
00739 }
00740
00741 if (isect)
00742 {
00743 entry_count++;
00744 _mapping[u+MAPPING_SIZE*v]->add(f);
00745 if ( _mapping[u+MAPPING_SIZE*v]->num() == 1 ) bin_count++;
00746 }
00747
00748 }
00749 }
00750
00751
00752
00753 assert(entry_count>0);
00754
00755 uvdata->set_mapping(this);
00756
00757
00758 _face_cnt++;
00759
00760
00761 _entry_cnt += entry_count;
00762
00763
00764 _bin_cnt += bin_count;
00765
00766
00767 }
00768
00769
00770
00771
00772 Bface*
00773 UVMapping::find_face(CUVpt &uv, Wvec &bc)
00774 {
00775 static bool debug = Config::get_var_bool("HATCHING_DEBUG_MAPPING",false);
00776
00777 int k,i;
00778
00779 UVdata* uvdata;
00780 Bface *f;
00781
00782 int u = int(floor( ( uv[0] - _min_u ) / _du ));
00783 if (u==MAPPING_SIZE) u--;
00784 int v = int(floor( ( uv[1] - _min_v ) / _dv ));
00785 if (v==MAPPING_SIZE) v--;
00786
00787 i = u+MAPPING_SIZE*v;
00788
00789 for (k=0; k<_mapping[i]->num(); k++)
00790 {
00791 f = (*_mapping[i])[k];
00792 uvdata = UVdata::lookup(f);
00793 assert(uvdata);
00794
00795 CUVpt& uv1 = uvdata->uv1();
00796 CUVpt& uv2 = uvdata->uv2();
00797 CUVpt& uv3 = uvdata->uv3();
00798 UVvec uv3_1 = uv3 - uv1;
00799
00800 double A = det(uv2 - uv1, uv3_1 );
00801 double bc1 = det(uv2 - uv , uv3 - uv ) / A;
00802
00803 if ((bc1<0)||(bc1>1)) continue;
00804
00805 double bc2 = det(uv - uv1, uv3_1 ) / A;
00806
00807 if ((bc2<0)||(bc2>1)) continue;
00808
00809 double bc3 = 1.0 - bc1 - bc2;
00810
00811 if (bc3>=0)
00812 {
00813 bc = Wvec(bc1,bc2,bc3);
00814
00815 if (debug)
00816 {
00817 _marked_debug_image[3*i ] = 0xFF;
00818 _marked_debug_image[3*i+1] = 0x77;
00819 _marked_debug_image[3*i+2] = 0x77;
00820 }
00821
00822 return f;
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846 }
00847 return 0;
00848 }
00849
00850
00851
00852
00853
00854 bool
00855 UVMapping::intersect(CUVpt &pt1a, CUVpt &pt1b, CUVpt &pt2a, CUVpt &pt2b)
00856 {
00857
00858 if ((pt1a==pt2a)||(pt1a==pt2b)||(pt1b==pt2a)||(pt1b==pt2b)) return true;
00859
00860 double c1a = det(pt1b - pt1a, pt2a - pt1a);
00861 double c1b = det(pt1b - pt1a, pt2b - pt1a);
00862 double c2a = det(pt2b - pt2a, pt1a - pt2a);
00863 double c2b = det(pt2b - pt2a, pt1b - pt2a);
00864
00865
00866
00867 if ( ( ((c1a>=-gEpsZeroMath)&&(c1b<=gEpsZeroMath)) || ((c1a<=gEpsZeroMath)&&(c1b>=-gEpsZeroMath)) ) &&
00868 ( ((c2a>=-gEpsZeroMath)&&(c2b<=gEpsZeroMath)) || ((c2a<=gEpsZeroMath)&&(c2b>=-gEpsZeroMath)) ) )
00869 return true;
00870
00871 return false;
00872 }
00873
00874
00875
00876
00877 void
00878 UVMapping::interpolate(
00879 CUVpt &uv1, double frac1,
00880 CUVpt &uv2, double frac2,
00881 UVpt &uv )
00882 {
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895 double lo;
00896 double hi;
00897
00898 if (!_wrap_u)
00899 {
00900 uv[0] = uv1[0]*frac1 + uv2[0]*frac2;
00901 }
00902 else
00903 {
00904 lo = _min_u + 0.25*_span_u;
00905 hi = _max_u - 0.25*_span_u;
00906
00907 if ((uv1[0]>hi) && (uv2[0]<lo))
00908 {
00909 uv[0] = uv1[0]*frac1 + (uv2[0]+_span_u)*frac2;
00910 }
00911 else if ((uv1[0]<lo) && (uv2[0]>hi))
00912 {
00913 uv[0] = (uv1[0]+_span_u)*frac1 + uv2[0]*frac2;
00914 }
00915 else
00916 {
00917 uv[0] = uv1[0]*frac1 + uv2[0]*frac2;
00918 }
00919
00920 if (uv[0]>_max_u) uv[0] = uv[0] - _span_u;
00921 }
00922
00923
00924 if (!_wrap_v)
00925 {
00926 uv[1] = uv1[1]*frac1 + uv2[1]*frac2;
00927 }
00928 else
00929 {
00930 lo = _min_v + 0.25*_span_v;
00931 hi = _max_v - 0.25*_span_v;
00932
00933 if ((uv1[1]>hi) && (uv2[1]<lo))
00934 {
00935 uv[1] = uv1[1]*frac1 + (uv2[1]+_span_v)*frac2;
00936 }
00937 else if ((uv1[1]<lo) && (uv2[1]>hi))
00938 {
00939 uv[1] = (uv1[1]+_span_v)*frac1 + uv2[1]*frac2;
00940 }
00941 else
00942 {
00943 uv[1] = uv1[1]*frac1 + uv2[1]*frac2;
00944 }
00945
00946 if (uv[1]>_max_v) uv[1] = uv[1] - _span_v;
00947 }
00948
00949
00950 }
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964 void
00965 UVMapping::apply_wrap(
00966 UVpt &uv)
00967 {
00968
00969 if (_wrap_u)
00970 {
00971 if (uv[0]<_min_u)
00972 do
00973 uv[0] += _span_u;
00974 while (uv[0]<_min_u);
00975
00976 else if (uv[0]>_max_u)
00977 do
00978 uv[0] -= _span_u;
00979 while (uv[0]>_max_u);
00980 }
00981
00982 if (_wrap_v)
00983 {
00984 if (uv[1]<_min_v)
00985 do
00986 uv[1] += _span_v;
00987 while (uv[1]<_min_v);
00988
00989 else if (uv[1]>_max_v)
00990 do
00991 uv[1] -= _span_v;
00992 while (uv[1]>_max_v);
00993 }
00994
00995 }
00996