00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "stdafx.h"
00021
00022
00023
00024
00025
00026 #include <iostream>
00027
00028 #include "gul_types.h"
00029 #include "gul_float.h"
00030 #include "gul_vector.h"
00031 #include "guge_normalize.h"
00032 #include "guge_linear.h"
00033 #include "gunu_basics.h"
00034 #include "gunu_divide.h"
00035 #include "gunu_intersect.h"
00036 #include "guar_exact.h"
00037 #include "gugr_basics.h"
00038 #include "guar_intersect.h"
00039 #include "guma_random.h"
00040 #include "guma_rkdtree.h"
00041 #include "gunu_project.h"
00042 #include "gul_io.h"
00043
00044 namespace gunu {
00045
00046 using guge::IsLinear;
00047 using guge::CalcBoundingBoxVerts;
00048 using guar::rational;
00049 using gul::rtr;
00050 using gul::rel_equal;
00051 using gugr::coord2int;
00052 using gul::point2;
00053 using gul::point;
00054 using gul::rel_equal;
00055 using gul::triangle;
00056 using gul::triangle2;
00057 using guar::IntersectTrianglesUV;
00058 using gul::Max;
00059 using gul::Min;
00060 using gul::test;
00061 using gul::List;
00062 using gul::ListNode;
00063 using gugr::cnv2coord_rnd;
00064 using gul::kdpoint;
00065 using guma::kdnnrec;
00066 using guma::kdrec;
00067 using guma::rkdtree;
00068 using guma::random_des;
00069 using gul::line;
00070 using std::cout;
00071
00072
00073
00074
00075
00076
00077 template< class T, class HP >
00078 void LinearizeOrDivide( TessInfo<T,HP> *A, const T tol,
00079 bool need_bbox )
00080 {
00081 int nu,nv,i,pu,pv,j;
00082 Ptr< T > U,V;
00083 Ptr< Ptr< HP > > Pw;
00084 point<T> P00, P01, P10, P11, SP0, SP1, SP2, SP3, CP, minP, maxP;
00085 bool subdiv;
00086 surface< T, HP > S[4], surf;
00087 Ptr< HP > buf;
00088 gul::Ptr< int > test;
00089
00090 nu = A->org->nu;
00091 pu = A->org->pu;
00092 nv = A->org->nv;
00093 pv = A->org->pv;
00094 U = A->org->U;
00095 V = A->org->V;
00096 Pw = A->org->Pw;
00097
00098 P00 = A->org->P00;
00099 P01 = A->org->P01;
00100 P10 = A->org->P10;
00101 P11 = A->org->P11;
00102
00103 buf.reserve_place( reserve_stack(hpoint<T>,nv+1), nv+1 );
00104
00105
00106 subdiv = false;
00107
00108 if( !guge::IsLinear< T,HP,point<T> >( nu, Pw[0], tol ) )
00109 {
00110 subdiv = true;
00111 CurvePoint< T, HP, point<T> >( (T)0.5, nu, pu, U, Pw[0], &SP0 );
00112 }
00113 else
00114 {
00115 SP0 = (T)0.5 * (P00 + P01);
00116 }
00117
00118 if( !guge::IsLinear<T,HP,point<T> >( nu, Pw[nv], tol ) )
00119 {
00120 subdiv = true;
00121 CurvePoint< T, HP, point<T> >( (T)0.5, nu, pu, U, Pw[nv], &SP1 );
00122 }
00123 else
00124 {
00125 SP1 = (T)0.5 * (P10 + P11);
00126 }
00127
00128 for( i = 0; i <= nv; i++ )
00129 buf[i] = Pw[i][0];
00130 if( !guge::IsLinear<T,HP,point<T> >( nv, buf, tol ) )
00131 {
00132 subdiv = true;
00133 CurvePoint< T, HP, point<T> >( (T)0.5, nv, pv, V, buf, &SP2 );
00134 }
00135 else
00136 {
00137 SP2 = (T)0.5 * (P00 + P10);
00138 }
00139
00140 for( i = 0; i <= nv; i++ )
00141 buf[i] = Pw[i][nu];
00142 if( !guge::IsLinear<T,HP,point<T> >( nv, buf, tol ) )
00143 {
00144 subdiv = true;
00145 CurvePoint< T, HP, point<T> >( (T)0.5, nv, pv, V, buf, &SP3 );
00146 }
00147 else
00148 {
00149 SP3 = (T)0.5 * (P01 + P11);
00150 }
00151
00152 #if 0
00153
00154
00155
00156
00157
00158 if( !subdiv )
00159 {
00160 for( i = 1; i < nv; i++ )
00161 {
00162 if( !guge::IsLinear< T,HP,point<T> >( nu, Pw[i], tol, t ) )
00163 {
00164 subdiv = true;
00165 break;
00166 }
00167 }
00168 }
00169 if( !subdiv )
00170 {
00171 for( j = 1; j < nu; j++ )
00172 {
00173 for( i = 0; i <= nv; i++ )
00174 buf[i] = Pw[i][j];
00175 if( !guge::IsLinear<T,HP,point<T> >( nv, buf, tol, t ) )
00176 {
00177 subdiv = true;
00178 break;
00179 }
00180 }
00181 }
00182 #endif
00183
00184 if( !subdiv )
00185 {
00186 if( !guge::IsPlanar<T,HP>( nu, nv, Pw, tol ) )
00187 subdiv = true;
00188 }
00189
00190 if( subdiv )
00191 {
00192 surf.pu = pu;
00193 surf.pv = pv;
00194 surf.net.nu = nu;
00195 surf.net.nv = nv;
00196 surf.net.Pw = Pw;
00197 surf.knu.m = nu+pu+1;
00198 surf.knu.U = U;
00199 surf.knv.m = nv+pv+1;
00200 surf.knv.U = V;
00201
00202 SplitSurface< T, HP >( &surf, 0.5, 0.5, &S[0], &S[1], &S[2], &S[3] );
00203
00204 A->divided = 1;
00205 delete A->org;
00206 A->org = 0;
00207 for( i = 0; i < 4; i++ ) A->sub[i] = new TessInfo<T,HP>();
00208
00209 for( i = 0; i < 4; i++ )
00210 {
00211 if( need_bbox )
00212 {
00213 guge::CalcBoundingBoxVerts< HP, point<T> >(
00214 S[i].net.nu+1, S[i].net.Pw[0], minP, maxP );
00215 for( j = 1; j < S[i].net.nv+1; j++ )
00216 guge::UpdateBoundingBoxVerts< HP, point<T> >(
00217 S[i].net.nu+1, S[i].net.Pw[j], minP, maxP );
00218 A->sub[i]->x1 = minP.x; A->sub[i]->x2 = maxP.x;
00219 A->sub[i]->y1 = minP.y; A->sub[i]->y2 = maxP.y;
00220 A->sub[i]->z1 = minP.z; A->sub[i]->z2 = maxP.z;
00221 }
00222 A->sub[i]->org->nu = S[i].net.nu;
00223 A->sub[i]->org->pu = S[i].pu;
00224 A->sub[i]->org->nv = S[i].net.nv;
00225 A->sub[i]->org->pv = S[i].pv;
00226 A->sub[i]->org->U = S[i].knu.U;
00227 A->sub[i]->org->V = S[i].knv.U;
00228 A->sub[i]->org->Pw = S[i].net.Pw;
00229 }
00230 CP = euclid( A->sub[0]->org->Pw[ A->sub[0]->org->nv ][ A->sub[0]->org->nu ] );
00231
00232 A->sub[0]->org->P00 = P00;
00233 A->sub[0]->org->P01 = SP0;
00234 A->sub[0]->org->P10 = SP2;
00235 A->sub[0]->org->P11 = CP;
00236 A->sub[0]->u1 = A->u1;
00237 A->sub[0]->u2 = (A->u1 + A->u2) / (T)2.0;
00238 A->sub[0]->v1 = A->v1;
00239 A->sub[0]->v2 = (A->v1 + A->v2) / (T)2.0;
00240
00241 A->sub[1]->org->P00 = SP0;
00242 A->sub[1]->org->P01 = P01;
00243 A->sub[1]->org->P10 = CP;
00244 A->sub[1]->org->P11 = SP3;
00245 A->sub[1]->u1 = (A->u1 + A->u2) / (T)2.0;;
00246 A->sub[1]->u2 = A->u2;
00247 A->sub[1]->v1 = A->v1;
00248 A->sub[1]->v2 = (A->v1 + A->v2) / (T)2.0;
00249
00250 A->sub[2]->org->P00 = SP2;
00251 A->sub[2]->org->P01 = CP;
00252 A->sub[2]->org->P10 = P10;
00253 A->sub[2]->org->P11 = SP1;
00254 A->sub[2]->u1 = A->u1;
00255 A->sub[2]->u2 = (A->u1 + A->u2) / (T)2.0;
00256 A->sub[2]->v1 = (A->v1 + A->v2) / (T)2.0;
00257 A->sub[2]->v2 = A->v2;
00258
00259 A->sub[3]->org->P00 = CP;
00260 A->sub[3]->org->P01 = SP3;
00261 A->sub[3]->org->P10 = SP1;
00262 A->sub[3]->org->P11 = P11;
00263 A->sub[3]->u1 = (A->u1 + A->u2) / (T)2.0;;
00264 A->sub[3]->u2 = A->u2;
00265 A->sub[3]->v1 = (A->v1 + A->v2) / (T)2.0;
00266 A->sub[3]->v2 = A->v2;
00267 }
00268 else
00269 {
00270 A->linearized = 1;
00271 A->divided = 0;
00272 }
00273 return;
00274 }
00275
00276
00277
00278
00279
00280 template
00281 void LinearizeOrDivide( TessInfo<float,hpoint<float> > *A, const float tol,
00282 bool need_bbox );
00283 template
00284 void LinearizeOrDivide( TessInfo<float,point<float> > *A, const float tol,
00285 bool need_bbox );
00286
00287 template
00288 void LinearizeOrDivide( TessInfo<double,hpoint<double> > *A, const double tol,
00289 bool need_bbox );
00290 template
00291 void LinearizeOrDivide( TessInfo<double,point<double> > *A, const double tol,
00292 bool need_bbox );
00293
00294
00295
00296
00297 template< class T, class HP >
00298 void DoLinearizeSurface(
00299 int current_iter, int max_iter,
00300 TessInfo<T,HP> *A,
00301 const T tol,
00302 void outfunc( TessInfo<T,HP> *, void * ),
00303 void *outfunc_data )
00304 {
00305 int nA,i;
00306 TessInfo<T,HP> **pA;
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 if( !A->linearized && !A->divided )
00320 {
00321 if( current_iter < max_iter )
00322 gunu::LinearizeOrDivide( A, tol, false );
00323 else
00324 A->linearized = 1;
00325 }
00326
00327 if( !A->linearized )
00328 {
00329 nA = 4;
00330 pA = A->sub;
00331
00332 for( i = 0; i < nA; i++ )
00333 {
00334 DoLinearizeSurface( current_iter+1, max_iter, pA[i], tol,
00335 outfunc, outfunc_data );
00336 delete pA[i];
00337 pA[i] = 0;
00338 }
00339 }
00340 else
00341 {
00342 outfunc( A, outfunc_data );
00343 }
00344 }
00345
00346
00347
00348 template void DoLinearizeSurface(
00349 int current_iter, int max_iter,
00350 TessInfo<float,hpoint<float> > *A,
00351 const float tol,
00352 void outfunc( TessInfo<float,hpoint<float> > *, void * ),
00353 void *outfunc_data );
00354 template void DoLinearizeSurface(
00355 int current_iter, int max_iter,
00356 TessInfo<double,hpoint<double> > *A,
00357 const double tol,
00358 void outfunc( TessInfo<double,hpoint<double> > *, void * ),
00359 void *outfunc_data );
00360
00361 template void DoLinearizeSurface(
00362 int current_iter, int max_iter,
00363 TessInfo<float,point<float> > *A,
00364 const float tol,
00365 void outfunc( TessInfo<float,point<float> > *, void * ),
00366 void *outfunc_data );
00367 template void DoLinearizeSurface(
00368 int current_iter, int max_iter,
00369 TessInfo<double,point<double> > *A,
00370 const double tol,
00371 void outfunc( TessInfo<double,point<double> > *, void * ),
00372 void *outfunc_data );
00373
00374
00375
00376
00377 template< class T >
00378 inline void StoreIntersectionSegmentUV(
00379 point2<rational> *Suv,
00380 int *Sflag,
00381 List<ListNode<IntersectionLineInfo<T> > >& I )
00382 {
00383 ListNode<IntersectionLineInfo<T> > *in;
00384 T u,v;
00385
00386 in = new ListNode<IntersectionLineInfo<T> >;
00387 I.Append(in);
00388 cnv2coord_rnd(Suv[0].x,&u);
00389 in->el.Suv[0].x = u - (T)1;
00390 cnv2coord_rnd(Suv[0].y,&v);
00391 in->el.Suv[0].y = v - (T)1;
00392 cnv2coord_rnd(Suv[1].x,&u);
00393 in->el.Suv[1].x = u - (T)1;
00394 cnv2coord_rnd(Suv[1].y,&v);
00395 in->el.Suv[1].y = v - (T)1;
00396 in->el.Sflag[0] = Sflag[0];
00397 in->el.Sflag[1] = Sflag[1];
00398 }
00399
00400
00401
00402 template< class T >
00403 inline void StoreIntersectionSegment(
00404 point<rational> *S,
00405 IntersectInfo<T> *II )
00406 {
00407 T scale,x,y,z;
00408 ListNode<line<T> > *in;
00409
00410 in = new ListNode<line<T> >;
00411 II->IS.Append(in);
00412
00413 scale = (T)1/II->scalei;
00414
00415 cnv2coord_rnd(S[0].x,&x);
00416 in->el.P1.x = x * scale + II->minx;
00417 cnv2coord_rnd(S[0].y,&y);
00418 in->el.P1.y = y * scale + II->miny;
00419 cnv2coord_rnd(S[0].z,&z);
00420 in->el.P1.z = z * scale + II->minz;
00421
00422 cnv2coord_rnd(S[1].x,&x);
00423 in->el.P2.x = x * scale + II->minx;
00424 cnv2coord_rnd(S[1].y,&y);
00425 in->el.P2.y = y * scale + II->miny;
00426 cnv2coord_rnd(S[1].z,&z);
00427 in->el.P2.z = z * scale + II->minz;
00428 }
00429
00430
00431
00432
00433 template< class T, class HP >
00434 void DoIntersectSurfaces(
00435 TessInfo<T,HP> *A, TessInfo<T,HP> *B,
00436 T tol,
00437 IntersectInfo<T> *II )
00438 {
00439 int nA, nB, i, j;
00440 TessInfo<T,HP> **pA, **pB;
00441
00442
00443
00444 if( (A->x1 > B->x2) || (A->x2 < B->x1) ||
00445 (A->y1 > B->y2) || (A->y2 < B->y1) ||
00446 (A->z1 > B->z2) || (A->z2 < B->z1) )
00447 {
00448 return;
00449 }
00450
00451
00452 if( !A->linearized && !A->divided )
00453 {
00454 LinearizeOrDivide<T,HP>( A, tol, true );
00455 }
00456
00457
00458 if( !B->linearized && !B->divided )
00459 {
00460 LinearizeOrDivide<T,HP>( B, tol, true );
00461 }
00462
00463
00464 if( !A->linearized || !B->linearized )
00465 {
00466 if( !A->linearized )
00467 {
00468 nA = 4;
00469 pA = A->sub;
00470 }
00471 else
00472 {
00473 nA = 1;
00474 pA = &A;
00475 }
00476
00477 if( !B->linearized )
00478 {
00479 nB = 4;
00480 pB = B->sub;
00481 }
00482 else
00483 {
00484 nB = 1;
00485 pB = &B;
00486 }
00487
00488 for( i = 0; i < nA; i++ )
00489 {
00490 for( j = 0; j < nB; j++ )
00491 {
00492 DoIntersectSurfaces( pA[i], pB[j], tol, II );
00493 }
00494 }
00495 }
00496 else
00497 {
00498 point<T> PA[2][2],PB[2][2];
00499 point<rational> PRA[2][2],PRB[2][2];
00500 point2<rational> PRA_UV[2][2],PRB_UV[2][2];
00501 T x,y,z;
00502 unsigned long *cbuf =
00503 (unsigned long *)alloca(gul::rtr<T>::mantissa_length());
00504 triangle<rational> TA[2],TB[2];
00505 triangle2<rational> TAuv[2],TBuv[2];
00506 point<rational> S[2];
00507 point2<rational> S1uv[2], S2uv[2];
00508 int S1flag[2], S2flag[2];
00509 bool result;
00510
00511
00512 PA[0][0] = A->org->P00;
00513 PA[0][1] = A->org->P01;
00514 PA[1][0] = A->org->P10;
00515 PA[1][1] = A->org->P11;
00516
00517 for( i = 0; i < 2; i++ )
00518 {
00519 for( j = 0; j < 2; j++ )
00520 {
00521 x = (PA[i][j].x - II->minx)*II->scalei;
00522 y = (PA[i][j].y - II->miny)*II->scalei;
00523 z = (PA[i][j].z - II->minz)*II->scalei;
00524
00525 PRA[i][j].x = rational(coord2int(x,cbuf),cbuf);
00526 PRA[i][j].y = rational(coord2int(y,cbuf),cbuf);
00527 PRA[i][j].z = rational(coord2int(z,cbuf),cbuf);
00528 }
00529 }
00530
00531 PRA_UV[0][0].x = rational(coord2int(A->u1+(T)1,cbuf),cbuf);
00532 PRA_UV[0][0].y = rational(coord2int(A->v1+(T)1,cbuf),cbuf);
00533
00534 PRA_UV[0][1].x = rational(coord2int(A->u2+(T)1,cbuf),cbuf);
00535 PRA_UV[0][1].y = PRA_UV[0][0].y ;
00536
00537 PRA_UV[1][0].x = PRA_UV[0][0].x;
00538 PRA_UV[1][0].y = rational(coord2int(A->v2+(T)1,cbuf),cbuf);
00539
00540 PRA_UV[1][1].x = PRA_UV[0][1].x;
00541 PRA_UV[1][1].y = PRA_UV[1][0].y;
00542
00543
00544 PB[0][0] = B->org->P00;
00545 PB[0][1] = B->org->P01;
00546 PB[1][0] = B->org->P10;
00547 PB[1][1] = B->org->P11;
00548
00549 for( i = 0; i < 2; i++ )
00550 {
00551 for( j = 0; j < 2; j++ )
00552 {
00553 x = (PB[i][j].x - II->minx)*II->scalei;
00554 y = (PB[i][j].y - II->miny)*II->scalei;
00555 z = (PB[i][j].z - II->minz)*II->scalei;
00556
00557 PRB[i][j].x = rational(coord2int(x,cbuf),cbuf);
00558 PRB[i][j].y = rational(coord2int(y,cbuf),cbuf);
00559 PRB[i][j].z = rational(coord2int(z,cbuf),cbuf);
00560 }
00561 }
00562
00563 PRB_UV[0][0].x = rational(coord2int(B->u1+(T)1,cbuf),cbuf);
00564 PRB_UV[0][0].y = rational(coord2int(B->v1+(T)1,cbuf),cbuf);
00565
00566 PRB_UV[0][1].x = rational(coord2int(B->u2+(T)1,cbuf),cbuf);
00567 PRB_UV[0][1].y = PRB_UV[0][0].y;
00568
00569 PRB_UV[1][0].x = PRB_UV[0][0].x;
00570 PRB_UV[1][0].y = rational(coord2int(B->v2+(T)1,cbuf),cbuf);
00571
00572 PRB_UV[1][1].x = PRB_UV[0][1].x;
00573 PRB_UV[1][1].y = PRB_UV[1][0].y;
00574
00575
00576 TA[0].P1 = PRA[0][0];
00577 TA[0].P2 = PRA[0][1];
00578 TA[0].P3 = PRA[1][0];
00579 TAuv[0].P1 = PRA_UV[0][0];
00580 TAuv[0].P2 = PRA_UV[0][1];
00581 TAuv[0].P3 = PRA_UV[1][0];
00582
00583 TA[1].P1 = PRA[1][1];
00584 TA[1].P2 = PRA[1][0];
00585 TA[1].P3 = PRA[0][1];
00586 TAuv[1].P1 = PRA_UV[1][1];
00587 TAuv[1].P2 = PRA_UV[1][0];
00588 TAuv[1].P3 = PRA_UV[0][1];
00589
00590
00591 TB[0].P1 = PRB[0][0];
00592 TB[0].P2 = PRB[0][1];
00593 TB[0].P3 = PRB[1][0];
00594 TBuv[0].P1 = PRB_UV[0][0];
00595 TBuv[0].P2 = PRB_UV[0][1];
00596 TBuv[0].P3 = PRB_UV[1][0];
00597
00598 TB[1].P1 = PRB[1][1];
00599 TB[1].P2 = PRB[1][0];
00600 TB[1].P3 = PRB[0][1];
00601 TBuv[1].P1 = PRB_UV[1][1];
00602 TBuv[1].P2 = PRB_UV[1][0];
00603 TBuv[1].P3 = PRB_UV[0][1];
00604
00605 result = IntersectTrianglesUV(TA[0],TAuv[0],TB[0],TBuv[0],
00606 S1uv,S1flag,S2uv,S2flag,S);
00607 if( result )
00608 {
00609
00610
00611 StoreIntersectionSegment(S,II);
00612 StoreIntersectionSegmentUV(S1uv,S1flag,II->IA);
00613 StoreIntersectionSegmentUV(S2uv,S2flag,II->IB);
00614 }
00615
00616 result = IntersectTrianglesUV(TA[1],TAuv[1],TB[0],TBuv[0],
00617 S1uv,S1flag,S2uv,S2flag,S);
00618 if( result )
00619 {
00620 StoreIntersectionSegment(S,II);
00621 StoreIntersectionSegmentUV(S1uv,S1flag,II->IA);
00622 StoreIntersectionSegmentUV(S2uv,S2flag,II->IB);
00623 }
00624
00625 result = IntersectTrianglesUV(TA[0],TAuv[0],TB[1],TBuv[1],
00626 S1uv,S1flag,S2uv,S2flag,S);
00627 if( result )
00628 {
00629 StoreIntersectionSegment(S,II);
00630 StoreIntersectionSegmentUV(S1uv,S1flag,II->IA);
00631 StoreIntersectionSegmentUV(S2uv,S2flag,II->IB);
00632 }
00633
00634 result = IntersectTrianglesUV(TA[1],TAuv[1],TB[1],TBuv[1],
00635 S1uv,S1flag,S2uv,S2flag,S);
00636 if( result )
00637 {
00638 StoreIntersectionSegment(S,II);
00639 StoreIntersectionSegmentUV(S1uv,S1flag,II->IA);
00640 StoreIntersectionSegmentUV(S2uv,S2flag,II->IB);
00641 }
00642 }
00643 }
00644
00645 template void DoIntersectSurfaces(
00646 TessInfo<float, hpoint<float> > *A, TessInfo<float,hpoint<float> > *B,
00647 float tol,
00648 IntersectInfo<float> *II );
00649
00650
00651
00652
00653
00654
00655 template< class T >
00656
00657 class is_uv_point : public gul::point2<T>
00658 {
00659 public:
00660 IntersectionLineInfo<T> *ii;
00661 point2<T> *ip;
00662
00663 is_uv_point *next;
00664 is_uv_point *prev;
00665
00666 is_uv_point( point2<T> *inP, IntersectionLineInfo<T> *inii )
00667 : point2<T>( *inP )
00668 {
00669 ip = inP;
00670 ii = inii;
00671 }
00672 };
00673
00674
00675
00676
00677 template< class T, class HP >
00678 GULAPI void IntersectSurfaces(
00679 int nu1, int pu1, const Ptr< T >& U1,
00680 int nv1, int pv1, const Ptr< T >& V1,
00681 const Ptr< Ptr < HP > >& Pw1,
00682 int nu2, int pu2, const Ptr< T >& U2,
00683 int nv2, int pv2, const Ptr< T >& V2,
00684 const Ptr< Ptr < HP > >& Pw2,
00685 T tol,
00686 List<ListNode<IntersectionLineInfo<T> > >& S1,
00687 List<ListNode<IntersectionLineInfo<T> > >& S2,
00688 List<ListNode<line<T> > >& S )
00689 {
00690 TessInfo<T,HP> A,B;
00691 point<T> maxP,minP;
00692 int j;
00693 IntersectInfo<T> II;
00694 T maxx,maxy,maxz,scale,d;
00695 rkdtree<point2<T>,T,random_des> KDT(2);
00696 is_uv_point<T> *Puv,*Peq,*Puv_next;
00697 List< is_uv_point<T> > LPuv,LPeq,LPtmp;
00698 ListNode<kdrec<point2<T>,T> > *nn;
00699 ListNode<IntersectionLineInfo<T> > *iin;
00700 Ptr<kdnnrec<point2<T>,T> > N;
00701 List< gul::ListNode<kdrec<point2<T>,T> > > outrecs;
00702 point2<T> M;
00703
00704
00705 A.org->nu = nu1;
00706 A.org->pu = pu1;
00707 A.org->U = U1;
00708 A.org->nv = nv1;
00709 A.org->pv = pv1;
00710 A.org->V = V1;
00711 A.org->Pw = Pw1;
00712
00713 guge::CalcBoundingBoxVerts<HP,point<T> >(
00714 A.org->nu+1, A.org->Pw[0], minP, maxP );
00715 for( j = 1; j < A.org->nv+1; j++ )
00716 guge::UpdateBoundingBoxVerts<HP,point<T> >(
00717 A.org->nu+1, A.org->Pw[j], minP, maxP );
00718 A.x1 = minP.x; A.x2 = maxP.x;
00719 A.y1 = minP.y; A.y2 = maxP.y;
00720 A.z1 = minP.z; A.z2 = maxP.z;
00721
00722 A.org->P00 = euclid( A.org->Pw[0][0] );
00723 A.org->P01 = euclid( A.org->Pw[0][A.org->nu] );
00724 A.org->P10 = euclid( A.org->Pw[A.org->nv][0] );
00725 A.org->P11 = euclid( A.org->Pw[A.org->nv][A.org->nu] );
00726
00727 A.u1 = 0.0;
00728 A.u2 = 1.0;
00729 A.v1 = 0.0;
00730 A.v2 = 1.0;
00731
00732
00733 B.org->nu = nu2;
00734 B.org->pu = pu2;
00735 B.org->U = U2;
00736 B.org->nv = nv2;
00737 B.org->pv = pv2;
00738 B.org->V = V2;
00739 B.org->Pw = Pw2;
00740
00741 guge::CalcBoundingBoxVerts<HP,point<T> >(
00742 B.org->nu+1, B.org->Pw[0], minP, maxP );
00743 for( j = 1; j < B.org->nv+1; j++ )
00744 guge::UpdateBoundingBoxVerts<HP,point<T> >(
00745 B.org->nu+1, B.org->Pw[j], minP, maxP );
00746 B.x1 = minP.x; B.x2 = maxP.x;
00747 B.y1 = minP.y; B.y2 = maxP.y;
00748 B.z1 = minP.z; B.z2 = maxP.z;
00749
00750 B.org->P00 = euclid( B.org->Pw[0][0] );
00751 B.org->P01 = euclid( B.org->Pw[0][B.org->nu] );
00752 B.org->P10 = euclid( B.org->Pw[B.org->nv][0] );
00753 B.org->P11 = euclid( B.org->Pw[B.org->nv][B.org->nu] );
00754
00755 B.u1 = 0.0;
00756 B.u2 = 1.0;
00757 B.v1 = 0.0;
00758 B.v2 = 1.0;
00759
00760
00761 II.minx = Min(A.x1,B.x1);
00762 maxx = Max(A.x2,B.x2);
00763 II.miny = Min(A.y1,B.y1);
00764 maxy = Max(A.y2,B.y2);
00765 II.minz = Min(A.z1,B.z1);
00766 maxz = Max(A.z2,B.z2);
00767
00768 scale = maxx - II.minx;
00769 d = maxy - II.miny;
00770 if( d > scale ) scale = d;
00771 d = maxz - II.minz;
00772 if( d > scale ) scale = d;
00773 if( !test(scale) ) return;
00774 II.minx -= scale;
00775 II.miny -= scale;
00776 II.minz -= scale;
00777 II.scalei = (T)1/scale;
00778
00779 DoIntersectSurfaces(&A,&B,tol,&II);
00780
00781
00782
00783
00784
00785 for( iin = II.IA.First(); iin; iin = iin->next )
00786 {
00787 Puv = new is_uv_point<T>(&iin->el.Suv[0],&iin->el);
00788 LPuv.Append(Puv);
00789 KDT.insert(Puv);
00790
00791 Puv = new is_uv_point<T>(&iin->el.Suv[1],&iin->el);
00792 LPuv.Append(Puv);
00793 KDT.insert(Puv);
00794 }
00795
00796
00797 for(;;)
00798 {
00799 Puv = LPuv.First();
00800 if( !Puv ) break;
00801
00802 LPuv.Remove(Puv);
00803 KDT.remove(Puv,outrecs);
00804
00805 LPtmp.Append(Puv);
00806
00807 for(;;)
00808 {
00809 Puv = LPtmp.First();
00810 if( !Puv ) break;
00811 LPtmp.Remove(Puv);
00812 LPeq.Append(Puv);
00813
00814 N.reserve_pool(1);
00815 if( KDT.nearest_neighbors( *Puv, 1, N ) )
00816 {
00817 nn = N[0].m_recs.First();
00818
00819 if( rel_equal(*Puv,*nn->el.m_base,rtr<T>::zero_tol()) )
00820 {
00821 for( ; nn; nn = nn->next )
00822 {
00823
00824 Peq = (is_uv_point<T> *)nn->el.m_base;
00825 LPuv.Remove(Peq);
00826 KDT.remove(Peq,outrecs);
00827
00828 LPtmp.Append(Peq);
00829 }
00830 }
00831 }
00832 }
00833
00834 if( LPeq.nElems > 1 )
00835 {
00836
00837 Puv = LPeq.First();
00838 M = *Puv;
00839 j = 1;
00840 Puv = Puv->next;
00841 for( ; Puv; Puv = Puv->next )
00842 {
00843 M += *Puv;
00844 j++;
00845 }
00846 M = ((T)1/(T)j)*M;
00847
00848
00849 Puv = LPeq.First();
00850 LPeq.ReleaseElems();
00851 for( ; Puv; Puv = Puv_next )
00852 {
00853 *Puv->ip = M;
00854 Puv_next = Puv->next;
00855 delete Puv;
00856 }
00857 }
00858 else
00859 LPeq.DeleteElems();
00860 }
00861
00862 S1 = II.IA;
00863 S2 = II.IB;
00864 S = II.IS;
00865 }
00866
00867 template GULAPI void IntersectSurfaces(
00868 int nu1, int pu1, const Ptr< float >& U1,
00869 int nv1, int pv1, const Ptr< float >& V1,
00870 const Ptr< Ptr < hpoint<float> > >& Pw1,
00871 int nu2, int pu2, const Ptr< float >& U2,
00872 int nv2, int pv2, const Ptr< float >& V2,
00873 const Ptr< Ptr < hpoint<float> > >& Pw2,
00874 float tol,
00875 List<ListNode<IntersectionLineInfo<float> > >& S1,
00876 List<ListNode<IntersectionLineInfo<float> > >& S2,
00877 List<ListNode<line<float> > >& S );
00878
00879
00880 #if 0
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 #endif
01142
01143 }