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 #include <iostream>
00023
00024 #include "gul_types.h"
00025 #include "gust_new.h"
00026 #include "gul_vector.h"
00027 #include "guge_linear.h"
00028 #include "guge_normalize.h"
00029 #include "gunu_basics.h"
00030 #include "gunu_derivatives.h"
00031 #include "gunu_divide.h"
00032 #include "gunu_intersect.h"
00033 #include "gunu_linearize.h"
00034 #include "guar_exact.h"
00035 #include "gugr_basics.h"
00036 #include "gugr_split.h"
00037 #include "gul_std.h"
00038 #include "gugr_regularize.h"
00039 #include "gugr_triangulate.h"
00040 #include "gugr_planesweep.h"
00041 #include "gul_io.h"
00042 #include "gul_std.h"
00043 #include "gugr_io.h"
00044
00045 #include "gunu_tesselate.h"
00046
00047 using gul::List;
00048 using gul::List2;
00049 using gul::ListNode;
00050 using gul::point;
00051 using gul::hpoint;
00052 using gul::point2;
00053 using gul::hpoint2;
00054 using gul::curve;
00055 using gul::Min;
00056 using gul::set;
00057
00058 using gul::normalize;
00059 using gul::euclid;
00060 using guar::rational;
00061 using gugr::graph_vertex;
00062 using gugr::graph_edge;
00063 using gugr::cut_info;
00064 using gugr::IntersectWithVerticals;
00065 using gugr::DivideVerticalStrips;
00066 using gugr::IntersectWithHorizontals;
00067 using gugr::DivideHorizontalStrips;
00068 using gugr::EdgeCycle;
00069 using gugr::graph_vertex_list;
00070 using gugr::graph_edge_list;
00071 using gugr::vertex_rep;
00072 using gugr::coord2int;
00073
00074
00075
00076
00077 namespace gunu {
00078
00079 template< class T, class HP >
00080 void _DoLinearizeTrimmedSurface(
00081 int current_iter, int max_iter,
00082 TessInfo<T,HP> *A,
00083 gugr::GraphInfo *G, gugr::GraphConvInfo<T> *Gconv,
00084 const T tol,
00085 void outfunc1( gunu::TessInfo<T,HP> *, void * ),
00086 void outfunc2( gunu::TessInfo<T,HP> *, gugr::GraphInfo *,
00087 gugr::GraphConvInfo<T> *, void * ),
00088 void *usrdata )
00089 {
00090 int nA,i;
00091 TessInfo<T,HP> **pA;
00092 gugr::GraphInfo *Gsub[4];
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 if( !A->linearized && !A->divided )
00104 {
00105 if( current_iter < max_iter )
00106 LinearizeOrDivide<T,HP>( A, tol );
00107 else
00108 A->linearized = 1;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118 if( !A->linearized )
00119 {
00120
00121 for( i = 0; i < 4; i++ ) Gsub[i] = new gugr::GraphInfo();
00122 gugr::SplitGraph( G, (A->u1+A->u2)/(T)2.0, (A->v1+A->v2)/(T)2.0, Gconv,
00123 Gsub );
00124
00125 nA = 4;
00126 pA = A->sub;
00127
00128 for( i = 0; i < nA; i++ )
00129 {
00130 if( (Gsub[i]->V.nElems==4) && (Gsub[i]->E.nElems==4) )
00131 {
00132 if( Gsub[i]->face > 0 )
00133 DoLinearizeSurface( current_iter+1, max_iter, pA[i], tol,
00134 outfunc1, usrdata );
00135 }
00136 else
00137 {
00138 _DoLinearizeTrimmedSurface( current_iter+1, max_iter,
00139 pA[i], Gsub[i], Gconv, tol, outfunc1, outfunc2, usrdata );
00140 }
00141
00142 delete pA[i];
00143 pA[i] = 0;
00144 delete Gsub[i];
00145 Gsub[i] = 0;
00146 }
00147 }
00148 else
00149 {
00150 if( (G->V.nElems==4) && (G->E.nElems==4) )
00151 {
00152 if( G->face > 0 ) outfunc1( A, usrdata );
00153 }
00154 else
00155 {
00156 outfunc2( A, G, Gconv, usrdata );
00157 }
00158 }
00159 }
00160
00161
00162
00163
00164
00165 template void _DoLinearizeTrimmedSurface(
00166 int current_iter, int max_iter,
00167 TessInfo<float,hpoint<float> > *A,
00168 gugr::GraphInfo *G, gugr::GraphConvInfo<float> *Gconv,
00169 const float tol,
00170 void outfunc1( TessInfo<float,hpoint<float> > *, void * ),
00171 void outfunc2( TessInfo<float,hpoint<float> > *, gugr::GraphInfo *,
00172 gugr::GraphConvInfo<float> *, void * ),
00173 void *usrdata );
00174 template void _DoLinearizeTrimmedSurface(
00175 int current_iter, int max_iter,
00176 TessInfo<double,hpoint<double> > *A,
00177 gugr::GraphInfo *G, gugr::GraphConvInfo<double> *Gconv,
00178 const double tol,
00179 void outfunc1( TessInfo<double,hpoint<double> > *, void * ),
00180 void outfunc2( TessInfo<double,hpoint<double> > *, gugr::GraphInfo *,
00181 gugr::GraphConvInfo<double> *, void * ),
00182 void *usrdata );
00183
00184 template void _DoLinearizeTrimmedSurface(
00185 int current_iter, int max_iter,
00186 TessInfo<float,point<float> > *A,
00187 gugr::GraphInfo *G, gugr::GraphConvInfo<float> *Gconv,
00188 const float tol,
00189 void outfunc1( TessInfo<float,point<float> > *, void * ),
00190 void outfunc2( TessInfo<float,point<float> > *, gugr::GraphInfo *,
00191 gugr::GraphConvInfo<float> *, void * ),
00192 void *usrdata );
00193 template void _DoLinearizeTrimmedSurface(
00194 int current_iter, int max_iter,
00195 TessInfo<double,point<double> > *A,
00196 gugr::GraphInfo *G, gugr::GraphConvInfo<double> *Gconv,
00197 const double tol,
00198 void outfunc1( TessInfo<double,point<double> > *, void * ),
00199 void outfunc2( TessInfo<double,point<double> > *, gugr::GraphInfo *,
00200 gugr::GraphConvInfo<double> *, void * ),
00201 void *usrdata );
00202
00203
00204
00205
00206
00207
00208
00209 template< class T, class HP >
00210 GULAPI void TessQuadCb( TessInfo<T,HP> *A, void *usrdata )
00211 {
00212 gul::point<T> P00,P01,P10,P11,T00,T01,T10,T11;
00213 int nu,nv,pu,pv;
00214 TessCbData<T> *cb = (TessCbData<T> *)usrdata;
00215
00216 P00 = A->org->P00;
00217 P01 = A->org->P01;
00218 P10 = A->org->P10;
00219 P11 = A->org->P11;
00220
00221 if( cb->need_normals == 0 )
00222 {
00223 cb->quadfunc( cb->usrdata,
00224 &P00, &P01, &P10, &P11, NULL, NULL, NULL, NULL,
00225 NULL, NULL, NULL, NULL );
00226 }
00227 else
00228 {
00229 nu = A->org->nu;
00230 pu = A->org->pu;
00231 nv = A->org->nv;
00232 pv = A->org->pv;
00233 Ptr< Ptr < HP > >& Pw = A->org->Pw;
00234
00235 CalcNormal_U0V0<T>( nu, pu, nv, pv, Pw, &T00 );
00236 CalcNormal_U1V0<T>( nu, pu, nv, pv, Pw, &T01 );
00237 CalcNormal_U0V1<T>( nu, pu, nv, pv, Pw, &T10 );
00238 CalcNormal_U1V1<T>( nu, pu, nv, pv, Pw, &T11 );
00239
00240 cb->quadfunc( cb->usrdata, &P00, &P01, &P10, &P11,
00241 &T00, &T01, &T10, &T11, &A->u1, &A->u2, &A->v1, &A->v2 );
00242 }
00243 }
00244
00245
00246 template GULAPI void TessQuadCb( TessInfo<float,hpoint<float> > *A, void *usrdata );
00247 template GULAPI void TessQuadCb( TessInfo<float,point<float> > *A, void *usrdata );
00248 template GULAPI void TessQuadCb( TessInfo<double,hpoint<double> > *A, void *usrdata );
00249 template GULAPI void TessQuadCb( TessInfo<double,point<double> > *A, void *usrdata );
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 template< class T >
00266 struct vertex_convert_cache
00267 {
00268 point<T> p;
00269 point<T> n;
00270 point2<T> d;
00271
00272 void *operator new( size_t s )
00273 {
00274 size_t dummy;
00275 void *p = gust::PoolAlloc( s, &dummy );
00276 if( p == NULL ) throw gul::PoolAllocError();
00277 return(p);
00278 }
00279 void operator delete( void *p, size_t s )
00280 {
00281 if( p != 0 ) gust::PoolFree( p, s );
00282 }
00283 };
00284
00285 template< class T >
00286 vertex_convert_cache<T> *FillVertexCache(
00287 vertex_rep *vert, const int code, bool normals,
00288 const T& orgx, const T& orgy, const T& scale,
00289 const T& u0, const T& v0, const T& w, const T& h, const T& a,
00290 const point<T>& W1, const point<T>& V2,
00291 const point<T>& V1, const point<T>& U1,
00292 const point<T>& W1n, const point<T>& V2n,
00293 const point<T>& V1n, const point<T>& U1n )
00294 {
00295 guar::Interval iu,iv;
00296 T u,v,ru,rv,tu,tv,tw;
00297 vertex_convert_cache<T> *buf;
00298
00299 vert->reserved.p = buf = new vertex_convert_cache<T>();
00300
00301 iu = vert->v.x.get_bounds();
00302 iv = vert->v.y.get_bounds();
00303 u = (T)((iu.m_low+iu.m_high)/2.0);
00304 v = (T)((iv.m_low+iv.m_high)/2.0);
00305 u = buf->d.x = gugr::cnv2coord(u)*scale + orgx;
00306 v = buf->d.y = gugr::cnv2coord(v)*scale + orgy;
00307 ru = u-u0;
00308 rv = v-v0;
00309 if( code > 0 )
00310 {
00311 tu = h*ru/a;
00312 tw = w*(h-rv)/a;
00313 tv = (T)1.0 - tu - tw;
00314 buf->p = tu*U1 + tv*V1 + tw*W1;
00315 if( normals ) buf->n = tu*U1n + tv*V1n + tw*W1n;
00316 }
00317 else if( code < 0 )
00318 {
00319 tu = w*rv/a;
00320 tw = h*(w-ru)/a;
00321 tv = (T)1.0 - tu - tw;
00322 buf->p = tu*U1 + tv*V2 + tw*W1;
00323 if( normals ) buf->n = tu*U1n + tv*V2n + tw*W1n;
00324 }
00325 else
00326 {
00327 tw = (w-ru)/w;
00328 tu = (T)1.0 - tw;
00329 buf->p = tw*W1 + tu*U1;
00330 if( normals ) buf->n = tw*W1n + tu*U1n;
00331 }
00332 return buf;
00333 }
00334
00335 template< class T, class HP >
00336 GULAPI void TessTriCb( TessInfo<T,HP> *A, gugr::GraphInfo *G,
00337 gugr::GraphConvInfo<T> *Gconv, void *data )
00338 {
00339 gugr::triangle_list Tri;
00340 gugr::triangle *tri,*tri_next;
00341 TessCbData<T> *cb = (TessCbData<T> *)data;
00342 point<T> T00,T01,T10,T11;
00343 vertex_convert_cache<T> *c1,*c2,*c3;
00344
00345 const point<T>& P00 = A->org->P00;
00346 const point<T>& P01 = A->org->P01;
00347 const point<T>& P10 = A->org->P10;
00348 const point<T>& P11 = A->org->P11;
00349 const int& nu = A->org->nu;
00350 const int& pu = A->org->pu;
00351 const int& nv = A->org->nv;
00352 const int& pv = A->org->pv;
00353 Ptr< Ptr< HP > >& Pw = A->org->Pw;
00354
00355 const T& orgx = Gconv->minx;
00356 const T& orgy = Gconv->miny;
00357 const T& scale = Gconv->scale;
00358
00359 const T& u0 = A->u1;
00360 const T& u1 = A->u2;
00361 const T& v0 = A->v1;
00362 const T& v1 = A->v2;
00363
00364 bool normals = cb->need_normals;
00365 void *usrdata = cb->usrdata;
00366
00367 T w = u1-u0;
00368 T h = v1-v0;
00369 T a = w*h;
00370
00371
00372
00373
00374
00375
00376
00377
00378 gugr::InsertDiagonal( &(G->E), &(G->V), G->P[0][0], G->P[1][1] );
00379
00380
00381
00382
00383
00384
00385
00386
00387 gugr::Regularize( &(G->E), &(G->V) );
00388
00389
00390
00391
00392
00393
00394
00395
00396 gugr::Triangulate( &(G->E), &(G->V), Gconv->FarMinX, &Tri );
00397
00398
00399 if( normals )
00400 {
00401 CalcNormal_U0V0<T>( nu, pu, nv, pv, Pw, &T00 );
00402 CalcNormal_U1V0<T>( nu, pu, nv, pv, Pw, &T01 );
00403 CalcNormal_U0V1<T>( nu, pu, nv, pv, Pw, &T10 );
00404 CalcNormal_U1V1<T>( nu, pu, nv, pv, Pw, &T11 );
00405 }
00406
00407 tri = Tri.head;
00408 while( tri != 0 )
00409 {
00410 if( tri->v[0].m_rep->reserved.p == 0 )
00411 c1 = FillVertexCache(
00412 tri->v[0].m_rep, tri->code0, normals, orgx, orgy, scale,
00413 u0, v0, w, h, a, P00, P01, P10, P11, T00, T01, T10, T11 );
00414 else
00415 c1 = (vertex_convert_cache<T> *)tri->v[0].m_rep->reserved.p;
00416
00417 if( tri->v[1].m_rep->reserved.p == 0 )
00418 c2 = FillVertexCache(
00419 tri->v[1].m_rep, tri->code1, normals, orgx, orgy, scale,
00420 u0, v0, w, h, a, P00, P01, P10, P11, T00, T01, T10, T11 );
00421 else
00422 c2 = (vertex_convert_cache<T> *)tri->v[1].m_rep->reserved.p;
00423
00424 if( tri->v[2].m_rep->reserved.p == 0 )
00425 c3 = FillVertexCache(
00426 tri->v[2].m_rep, tri->code2, normals, orgx, orgy, scale,
00427 u0, v0, w, h, a, P00, P01, P10, P11, T00, T01, T10, T11 );
00428 else
00429 c3 = (vertex_convert_cache<T> *)tri->v[2].m_rep->reserved.p;
00430
00431
00432
00433
00434
00435
00436
00437 cb->trifunc( usrdata, &c1->p, &c2->p, &c3->p, &c1->n, &c2->n, &c3->n,
00438 &c1->d, &c2->d, &c3->d );
00439 tri = tri->next;
00440 }
00441 tri = Tri.First();
00442 Tri.ReleaseElems();
00443 while( tri != 0 )
00444 {
00445 delete ((vertex_convert_cache<T> *)tri->v[0].m_rep->reserved.p);
00446 tri->v[0].m_rep->reserved.p = 0;
00447 delete ((vertex_convert_cache<T> *)tri->v[1].m_rep->reserved.p);
00448 tri->v[1].m_rep->reserved.p = 0;
00449 delete ((vertex_convert_cache<T> *)tri->v[2].m_rep->reserved.p);
00450 tri->v[2].m_rep->reserved.p = 0;
00451
00452 tri_next = tri->next;
00453 delete tri;
00454 tri = tri_next;
00455 }
00456 }
00457
00458
00459 template GULAPI void TessTriCb(
00460 TessInfo<float,hpoint<float> > *A, gugr::GraphInfo *G,
00461 gugr::GraphConvInfo<float> *Gconv, void *data );
00462 template GULAPI void TessTriCb(
00463 TessInfo<float,point<float> > *A, gugr::GraphInfo *G,
00464 gugr::GraphConvInfo<float> *Gconv, void *data );
00465 template GULAPI void TessTriCb(
00466 TessInfo<double,hpoint<double> > *A, gugr::GraphInfo *G,
00467 gugr::GraphConvInfo<double> *Gconv, void *data );
00468 template GULAPI void TessTriCb(
00469 TessInfo<double,point<double> > *A, gugr::GraphInfo *G,
00470 gugr::GraphConvInfo<double> *Gconv, void *data );
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 }
00510