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 "gul_vector.h"
00026 #include "gul_matrix.h"
00027 #include "guge_normalize.h"
00028 #include "guma_lineq.h"
00029 #include "guar_exact.h"
00030 #include "gugr_basics.h"
00031 #include "gugr_regularize.h"
00032 #include "gugr_triangulate.h"
00033 #include "gugr_planesweep.h"
00034 #include "gugr_contour.h"
00035 #include "gul_io.h"
00036 #include "gul_std.h"
00037 #include "gugr_io.h"
00038
00039 namespace gugr {
00040
00041 using gul::VMProduct;
00042 using guma::GaussJordan;
00043 using gul::point;
00044 using gul::point2;
00045 using gul::Ptr;
00046 using guge::CalcBoundingBoxE;
00047 using guge::UpdateBoundingBoxE;
00048 using guar::Interval;
00049 using gul::Max;
00050 using guar::GetRatio;
00051 using guar::Test;
00052 using gul::rtr;
00053 using gul::Swap;
00054 using gul::cross_product;
00055
00056 using gul::ListNode;
00057 using gul::List;
00058 using gul::ListNodeInfo;
00059 using gul::point;
00060 using gul::itriangle;
00061
00062 using gul::set;
00063 using gul::normalize;
00064 using guar::Interval;
00065 using guar::Sqrt;
00066 using guar::Test;
00067
00068 #if 0
00069
00070 template< class T >
00071 bool FaceArea(
00072 int nVerts, const Ptr< point<T> >& Verts, int faceleft, int faceright,
00073 point<T> *retNormal, int *retFaceleft, int *retFaceright, T *retArea,
00074 int *ret_nTrii, Ptr<int[3]> *retTrii )
00075 {
00076 gugr::triangle_list Tri;
00077 gugr::triangle *tri,*tri_next;
00078 T area;
00079 point<T> v,p1,p2,p3;
00080 Ptr<int[3]> Trii;
00081 int count,i0,i1,i2;
00082
00083 if( !DoTriangulateFace( nVerts, Verts, faceleft, faceright, &Tri, retNormal,
00084 retFaceleft, retFaceright ) )
00085 return false;
00086
00087
00088
00089 Trii.reserve_pool(Tri.nElems);
00090 count = 0;
00091
00092 tri = Tri.First();
00093 Tri.ReleaseElems();
00094 area = (T)0;
00095 while( tri != 0 )
00096 {
00097
00098
00099 i0 = Trii[count][0] = (int)tri->v[0].m_rep->reserved;
00100 i1 = Trii[count][1] = (int)tri->v[1].m_rep->reserved;
00101 i2 = Trii[count][2] = (int)tri->v[2].m_rep->reserved;
00102 p1 = Verts[i0];
00103 p2 = Verts[i1];
00104 p3 = Verts[i2];
00105
00106 v = gul::cross_product(p2-p1,p3-p1);
00107 area += gul::length(v)/(T)2;
00108
00109 tri_next = tri->next;
00110 delete tri;
00111 tri = tri->next;
00112
00113 count++;
00114 }
00115 *retArea = area;
00116 *ret_nTrii = count;
00117 *retTrii = Trii;
00118
00119 return true;
00120 }
00121
00122 template bool FaceArea<float>(
00123 int nVerts, const Ptr< point<float> >& Verts, int faceleft, int faceright,
00124 point<float> *retNormal, int *retFaceleft, int *retFaceright, float *retArea,
00125 int *ret_nfloatrii, Ptr<int[3]> *retfloatrii );
00126 template bool FaceArea<double>(
00127 int nVerts, const Ptr< point<double> >& Verts, int faceleft, int faceright,
00128 point<double> *retNormal, int *retFaceleft, int *retFaceright, double *retArea,
00129 int *ret_ndoublerii, Ptr<int[3]> *retdoublerii );
00130
00131 #endif
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 template< class T >
00143 GULAPI bool CalcPlane(
00144 int nVerts, const Ptr< point<T> >& Verts,
00145 point<T>& o, point<T>& b1, point<T>& b2, point<T>& b3 )
00146 {
00147 Interval ix0,iy0,iz0,ix1,iy1,iz1,ix2,iy2,iz2,ibx1,iby1,ibz1,ibx2,iby2,ibz2;
00148 Interval ilen,ilen2,inx,iny,inz;
00149 double rat,rat1;
00150 int i0,i1,i2,irat0,irat1,irat2;
00151 point<T> v1,v2;
00152
00153 irat0 = -1;
00154 rat = rtr<double>::giant();
00155
00156 for( i0 = 0; i0 < nVerts; i0++ )
00157 {
00158 ix0 = Verts[i0].x;
00159 iy0 = Verts[i0].y;
00160 iz0 = Verts[i0].z;
00161
00162 i1 = i0+1; if( i1 == nVerts ) i1 = 0;
00163 i2 = i1+1; if( i2 == nVerts ) i2 = 0;
00164
00165
00166
00167 ix1 = Verts[i1].x;
00168 iy1 = Verts[i1].y;
00169 iz1 = Verts[i1].z;
00170
00171 ibx1 = ix1 - ix0;
00172 iby1 = iy1 - iy0;
00173 ibz1 = iz1 - iz0;
00174
00175
00176
00177 ilen2 = ibx1*ibx1 + iby1*iby1 + ibz1*ibz1;
00178 ilen = Sqrt( ilen2 );
00179 if( Test(ilen)==0 ) continue;
00180
00181 ibx1 = ibx1 / ilen;
00182 iby1 = iby1 / ilen;
00183 ibz1 = ibz1 / ilen;
00184
00185
00186
00187 ix2 = Verts[i2].x;
00188 iy2 = Verts[i2].y;
00189 iz2 = Verts[i2].z;
00190
00191 ibx2 = ix2 - ix0;
00192 iby2 = iy2 - iy0;
00193 ibz2 = iz2 - iz0;
00194
00195
00196
00197 ilen = ibx2*ibx1 + iby2*iby1 + ibz2*ibz1;
00198
00199
00200
00201 ibx2 = ibx2 - ilen * ibx1;
00202 iby2 = iby2 - ilen * iby1;
00203 ibz2 = ibz2 - ilen * ibz1;
00204
00205
00206
00207 ilen2 = ibx2*ibx2 + iby2*iby2 + ibz2*ibz2;
00208 ilen = Sqrt( ilen2 );
00209 if( Test(ilen)==0 ) continue;
00210
00211 ibx2 = ibx2 / ilen;
00212 iby2 = iby2 / ilen;
00213 ibz2 = ibz2 / ilen;
00214
00215
00216
00217 inx = iby1*ibz2 - ibz1*iby2;
00218 iny = ibz1*ibx2 - ibx1*ibz2;
00219 inz = ibx1*iby2 - iby1*ibx2;
00220
00221
00222
00223 ilen2 = inx*inx + iny*iny + inz*inz;
00224 ilen = Sqrt( ilen2 );
00225 if( Test(ilen)==0 ) continue;
00226
00227 inx = inx / ilen;
00228 iny = iny / ilen;
00229 inz = inz / ilen;
00230
00231 rat1 = GetRatio(inx*inx + iny*iny + inz*inz);
00232 if( rat1 < rat )
00233 {
00234 rat = rat1;
00235 irat0 = i0;
00236 irat1 = i1;
00237 irat2 = i2;
00238 }
00239 }
00240 if( (irat0 < 0) || (rat == rtr<double>::giant()) ) return false;
00241 i0 = irat0;
00242 i1 = irat1;
00243 i2 = irat2;
00244
00245
00246
00247 o = Verts[i0];
00248 v1 = Verts[i1] - o;
00249 v2 = Verts[i2] - o;
00250 normalize(&b1,v1);
00251 b2 = v2 - (v2*b1)*b1;
00252 normalize(&b2,b2);
00253 b3 = cross_product(b1,b2);
00254 normalize(&b3,b3);
00255
00256 return true;
00257 }
00258
00259 template GULAPI bool CalcPlane(
00260 int nVerts, const Ptr< point<float> >& Verts,
00261 point<float>& o, point<float>& b1, point<float>& b2, point<float>& b3 );
00262 template GULAPI bool CalcPlane(
00263 int nVerts, const Ptr< point<double> >& Verts,
00264 point<double>& o, point<double>& b1, point<double>& b2, point<double>& b3 );
00265
00266
00267
00268
00269
00270
00271 template< class T >
00272 GULAPI bool CheckLeftHandedness(
00273 int nP, const Ptr< point<T> >& P, const Ptr< Ptr<T> >& Ti,
00274 bool& lefthanded, bool& selfintersect )
00275 {
00276 polyline pl;
00277 Ptr< point2<T> > P2;
00278 Ptr<T> v3,v2;
00279 List< ListNode<segment> > segs,outsegs;
00280 ListNode<segment> *seg;
00281 graph_edge_list E;
00282 graph_vertex_list V;
00283 rational far_minx,far_maxx,far_miny,far_maxy;
00284 T minx,maxx,miny,maxy;
00285 T dx,dy,scale,scalei;
00286 int i,left;
00287 List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *L;
00288 graph_edge *e;
00289 List< ListNode<graph_edge *> > *Le;
00290 unsigned long *cbuf =
00291 (unsigned long *)alloca(gul::rtr<T>::mantissa_length());
00292
00293 if( !nP ) return false;
00294
00295
00296
00297 P2.reserve_pool(nP);
00298 v3.reserve_pool(4);
00299 v2.reserve_pool(4);
00300
00301 for( i = 0; i < nP; i++ )
00302 {
00303 v3[0] = P[i].x;
00304 v3[1] = P[i].y;
00305 v3[2] = P[i].z;
00306 v3[3] = (T)1;
00307
00308 VMProduct(4,4,v3,Ti,v2);
00309
00310 P2[i].x = v2[0];
00311 P2[i].y = v2[1];
00312 }
00313
00314 CalcBoundingBoxE( nP, P2, minx, maxx, miny, maxy );
00315
00316 dx = maxx - minx;
00317 dy = maxy - miny;
00318 scale = dx > dy ? dx : dy;
00319 minx -= scale;
00320 miny -= scale;
00321 scalei = (T)1.0/scale;
00322
00323
00324
00325
00326
00327 pl.init( nP, P2, minx, miny, scalei );
00328
00329 AppendContour( &pl, 0, 1, segs );
00330
00331 IntersectSegments( segs, &E, &V, true );
00332
00333
00334
00335
00336
00337
00338
00339
00340 far_miny = far_minx = rational( guar::ULong(0x100000), -1 );
00341 far_maxy = far_maxx = rational( coord2int((T)2,cbuf),cbuf) +
00342 rational( guar::ULong(0x100000) );
00343
00344 RemoveUnnecessaryEdges( E, V, far_maxx, far_maxy, 1, 0, outsegs );
00345
00346 e = E.First(); if( !e ) return false;
00347
00348
00349 L = (List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *)
00350 e->reserved[1].p;
00351
00352 Le = L->First()->el.m_L;
00353
00354
00355 for( seg = segs.First(); seg != 0; seg = seg->next )
00356 if( &seg->el.e == Le ) break;
00357
00358 if( !seg ) return false;
00359
00360 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00361 left = e->f[1].i;
00362 else
00363 left = e->f[0].i;
00364
00365 lefthanded = (left != 1);
00366
00367
00368
00369 for( seg = segs.First(); seg != 0; seg = seg->next )
00370 if( seg->el.e.nElems != 1 ) break;
00371
00372 selfintersect = (seg != 0);
00373
00374
00375
00376 e = E.First();
00377 while( e )
00378 {
00379 L = (List< ListNode< ListNodeInfo< ListNode<graph_edge *> > > > *)
00380 e->reserved[1].p;
00381 L->DeleteElems();
00382 delete L;
00383 e->reserved[1].p = 0;
00384 e = e->next;
00385 }
00386
00387 return true;
00388 }
00389 template GULAPI bool CheckLeftHandedness(
00390 int nP, const Ptr< point<float> >& P, const Ptr< Ptr<float> >& Ti,
00391 bool& lefthanded, bool& selfintersect );
00392 template GULAPI bool CheckLeftHandedness(
00393 int nP, const Ptr< point<double> >& P, const Ptr< Ptr<double> >& Ti,
00394 bool& lefthanded, bool& selfintersect );
00395
00396
00397 template< class T >
00398 void Polygon3dTo2d(
00399 const List< ListNode< gul::polyline< point<T> > > >& C3,
00400 const Ptr< Ptr< T > >& Ti,
00401 List< ListNode< gul::polyline< point2<T> > > >& C2 )
00402 {
00403 ListNode< gul::polyline< point<T> > > *c3;
00404 ListNode< gul::polyline< point2<T> > > *c2;
00405 int i;
00406 Ptr<T> v3,v2;
00407
00408 v3.reserve_pool(4);
00409 v2.reserve_pool(4);
00410
00411 c3 = C3.First();
00412 while( c3 )
00413 {
00414 c2 = new ListNode< gul::polyline< point2<T> > >;
00415 C2.Append( c2 );
00416
00417 c2->el.n = c3->el.n;
00418 c2->el.P.reserve_pool( c3->el.n );
00419
00420 for( i = 0; i < c3->el.n; i++ )
00421 {
00422 v3[0] = c3->el.P[i].x;
00423 v3[1] = c3->el.P[i].y;
00424 v3[2] = c3->el.P[i].z;
00425 v3[3] = (T)1;
00426
00427 VMProduct(4,4,v3,Ti,v2);
00428
00429 c2->el.P[i].x = v2[0];
00430 c2->el.P[i].y = v2[1];
00431 }
00432
00433 c3 = c3->next;
00434 }
00435 }
00436
00437 template void Polygon3dTo2d(
00438 const List< ListNode< gul::polyline< point<float> > > >& C3,
00439 const Ptr< Ptr< float > >& Ti,
00440 List< ListNode< gul::polyline< point2<float> > > >& C2 );
00441 template void Polygon3dTo2d(
00442 const List< ListNode< gul::polyline< point<double> > > >& C3,
00443 const Ptr< Ptr< double > >& Ti,
00444 List< ListNode< gul::polyline< point2<double> > > >& C2 );
00445
00446
00447
00448
00449
00450 template< class T >
00451 GULAPI void TriangulatePolygon3d(
00452 const List< ListNode< gul::polyline< point<T> > > >& C3,
00453 const List< ListNode< gul::polyline< point<T> > > >& N3,
00454 const List< ListNode< gul::polyline< point<T> > > >& T3,
00455 const Ptr< Ptr< T > >& Ti,
00456 Ptr< point2<T> >& D,
00457 Ptr< point<T> >& F,
00458 Ptr< point<T> >& N,
00459 Ptr< point<T> >& Tx,
00460 int *nTri,
00461 Ptr<itriangle>& Tri )
00462 {
00463 T minx,maxx,miny,maxy;
00464 T dx,dy,scale,scalei;
00465 ListNode< gugr::polyline > *pn,*inc;
00466 ListNode< gul::polyline< point<T> > > *inF,*inN,*inT;
00467 List< ListNode< gul::polyline< point2<T> > > > C2;
00468 ListNode< gul::polyline< point2<T> > > *c2;
00469 List< ListNode<polyline> > Pl;
00470 List< ListNode<segment> > segs,outsegs;
00471 ListNode<segment> *seg;
00472 graph_edge_list E;
00473 graph_vertex_list V;
00474 rational far_minx,far_maxx,far_miny,far_maxy;
00475 unsigned long *cbuf =
00476 (unsigned long *)alloca(gul::rtr<T>::mantissa_length());
00477 int nv,i,nt;
00478 Ptr< point<T> > &sumF = F, &sumN = N, &sumT = Tx;
00479 Ptr<T> sumW;
00480 graph_vertex *vn;
00481 graph_edge *e;
00482 ListNode<graph_edge *> *en;
00483 Interval iu,iv;
00484 T u,v,u1,u2,v1,v2,su,sv,alpha,w,wi,giant;
00485 point<T> fB,nB,fE,nE,tB,tE,f,n,t;
00486 bool end;
00487 triangle_list tri;
00488 triangle *tr;
00489
00490 if( C3.nElems == 0 ) return;
00491
00492 giant = gul::rtr<T>::giant();
00493
00494 Polygon3dTo2d( C3, Ti, C2 );
00495
00496 c2 = C2.First();
00497 CalcBoundingBoxE( c2->el.n, c2->el.P, minx, maxx, miny, maxy );
00498 c2 = c2->next;
00499
00500 while( c2 )
00501 {
00502 UpdateBoundingBoxE( c2->el.n, c2->el.P, minx, maxx, miny, maxy );
00503 c2 = c2->next;
00504 }
00505
00506 dx = maxx - minx;
00507 dy = maxy - miny;
00508 scale = dx > dy ? dx : dy;
00509 minx -= scale;
00510 miny -= scale;
00511 scalei = (T)1.0/scale;
00512
00513 c2 = C2.First();
00514 while( c2 )
00515 {
00516 pn = new ListNode<gugr::polyline>();
00517 Pl.Append( pn );
00518 pn->el.init( c2->el.n, c2->el.P, minx, miny, scalei );
00519 c2 = c2->next;
00520 }
00521
00522 inc = Pl.First();
00523 inF = C3.First();
00524 inN = N3.First();
00525 inT = T3.First();
00526
00527 while( inc )
00528 {
00529 AppendContourFNT( &inc->el, inF->el.P, inN->el.P, inT->el.P, 0, 0, segs );
00530 inc = inc->next;
00531 inF = inF->next;
00532 inN = inN->next;
00533 inT = inT->next;
00534 }
00535
00536 IntersectSegments( segs, &E, &V, true );
00537
00538 far_miny = far_minx = rational( guar::ULong(0x100000), -1 );
00539 far_maxy = far_maxx = rational( coord2int((T)2,cbuf),cbuf) +
00540 rational( guar::ULong(0x100000) );
00541
00542 RemoveUnnecessaryEdges( E, V, far_maxx, far_maxy, 1, 0, outsegs );
00543
00544 ISDeleteBackpointers(E);
00545
00546 outsegs.DeleteElems();
00547
00548
00549
00550
00551 nv = V.nElems;
00552 D.reserve_pool(nv);
00553 sumF.reserve_pool(nv);
00554 sumN.reserve_pool(nv);
00555 sumT.reserve_pool(nv);
00556 sumW.reserve_pool(nv);
00557
00558 i = 0;
00559 vn = V.First();
00560 while( vn )
00561 {
00562 vn->v.m_rep->reserved.i = i;
00563
00564 iu = vn->v.v().x.get_bounds();
00565 iv = vn->v.v().y.get_bounds();
00566 u = (T)((iu.m_low+iu.m_high)/2.0);
00567 v = (T)((iv.m_low+iv.m_high)/2.0);
00568 u = gugr::cnv2coord(u)*scale + minx;
00569 v = gugr::cnv2coord(v)*scale + miny;
00570
00571 D[i].x = u;
00572 D[i].y = v;
00573 set( sumF[i], (T)0 );
00574 set( sumN[i], (T)0 );
00575 sumW[i] = (T)0;
00576
00577 i++;
00578 vn = vn->next;
00579 }
00580
00581 for( seg = segs.First(); seg != 0; seg = seg->next )
00582 {
00583
00584 fB = *((seg_point_info< point<T> > *)seg->el.reserved[0])->f;
00585 nB = *((seg_point_info< point<T> > *)seg->el.reserved[0])->n;
00586 tB = *((seg_point_info< point<T> > *)seg->el.reserved[0])->t;
00587 fE = *((seg_point_info< point<T> > *)seg->el.reserved[1])->f;
00588 nE = *((seg_point_info< point<T> > *)seg->el.reserved[1])->n;
00589 tE = *((seg_point_info< point<T> > *)seg->el.reserved[1])->t;
00590
00591
00592 iu = seg->el.E.x.get_bounds();
00593 iv = seg->el.E.y.get_bounds();
00594 u = (T)((iu.m_low+iu.m_high)/2.0);
00595 v = (T)((iv.m_low+iv.m_high)/2.0);
00596 u2 = cnv2coord(u)*scale + minx;
00597 v2 = cnv2coord(v)*scale + miny;
00598
00599
00600 iu = seg->el.B.x.get_bounds();
00601 iv = seg->el.B.y.get_bounds();
00602 u = (T)((iu.m_low+iu.m_high)/2.0);
00603 v = (T)((iv.m_low+iv.m_high)/2.0);
00604 u1 = cnv2coord(u)*scale + minx;
00605 v1 = cnv2coord(v)*scale + miny;
00606
00607 su = u2 - u1;
00608 sv = v2 - v1;
00609
00610
00611
00612 en = seg->el.e.First();
00613 if( !en ) continue;
00614 e = en->el;
00615 if( e->l.IsHorizontal() || (e->l.dx().test() < 0) )
00616 end = 0;
00617 else
00618 end = 1;
00619
00620 for( ; en != 0; en = en->next )
00621 {
00622 e = en->el;
00623
00624
00625
00626 vn = e->v[!end];
00627 i = vn->v.m_rep->reserved.i;
00628 u = D[i].x - u1;
00629 v = D[i].y - v1;
00630
00631 if( su > sv )
00632 alpha = u/su;
00633 else if( sv > (T)0 )
00634 alpha = v/sv;
00635 else
00636 alpha = (T)0;
00637
00638 if( (alpha == (T)0) || (alpha >= (T)1) )
00639 {
00640 wi = giant;
00641 }
00642 else
00643 {
00644 if( alpha > (T)0.5 )
00645 {
00646 u = u2 - D[i].x;
00647 v = v2 - D[i].y;
00648 }
00649 w = u*u + v*v;
00650 if( w > (T)0 ) wi = (T)1.0/w;
00651 else wi = giant;
00652 }
00653
00654 f = ((T)1.0-alpha)*fB + alpha*fE;
00655 n = ((T)1.0-alpha)*nB + alpha*nE;
00656 t = ((T)1.0-alpha)*tB + alpha*tE;
00657
00658 if( wi >= giant )
00659 {
00660 if( sumW[i] >= (T)0 )
00661 {
00662 sumW[i] = (T)-1.0;
00663 sumF[i] = -f;
00664 sumN[i] = -n;
00665 sumT[i] = -t;
00666 }
00667 else
00668 {
00669 sumW[i] -= (T)1.0;
00670 sumF[i] -= f;
00671 sumN[i] -= n;
00672 sumT[i] -= t;
00673 }
00674 }
00675 else
00676 {
00677 sumW[i] += wi;
00678 sumF[i] += wi*f;
00679 sumN[i] += wi*n;
00680 sumT[i] += wi*t;
00681 }
00682
00683
00684
00685 if( en->next && (en->next->el->v[!end] == e->v[end]) )
00686 continue;
00687
00688 vn = e->v[end];
00689 i = vn->v.m_rep->reserved.i;
00690 u = D[i].x - u1;
00691 v = D[i].y - v1;
00692
00693 if( su > sv )
00694 alpha = u/su;
00695 else if( sv > (T)0 )
00696 alpha = v/sv;
00697 else
00698 alpha = (T)0;
00699
00700 if( (alpha == (T)0) || (alpha >= (T)1) )
00701 {
00702 wi = giant;
00703 }
00704 else
00705 {
00706 if( alpha > (T)0.5 )
00707 {
00708 u = u2 - D[i].x;
00709 v = v2 - D[i].y;
00710 }
00711 w = u*u + v*v;
00712 if( w > (T)0 ) wi = (T)1.0/w;
00713 else wi = giant;
00714 }
00715
00716 f = ((T)1.0-alpha)*fB + alpha*fE;
00717 n = ((T)1.0-alpha)*nB + alpha*nE;
00718 t = ((T)1.0-alpha)*tB + alpha*tE;
00719
00720 if( wi >= giant )
00721 {
00722 if( sumW[i] >= (T)0 )
00723 {
00724 sumW[i] = (T)-1;
00725 sumF[i] = -f;
00726 sumN[i] = -n;
00727 sumT[i] = -t;
00728 }
00729 else
00730 {
00731 sumW[i] -= (T)1;
00732 sumF[i] -= f;
00733 sumN[i] -= n;
00734 sumT[i] -= t;
00735 }
00736 }
00737 else
00738 {
00739 sumW[i] += wi;
00740 sumF[i] += wi*f;
00741 sumN[i] += wi*n;
00742 sumT[i] += wi*t;
00743 }
00744 }
00745 }
00746
00747 for( i = 0; i < nv; i++ )
00748 {
00749 wi = (T)1/sumW[i];
00750 sumF[i] *= wi;
00751 sumN[i] *= wi;
00752 sumT[i] *= wi;
00753 }
00754
00755
00756 segs.DeleteElems();
00757
00758
00759
00760 Regularize( &E, &V );
00761
00762 Triangulate( &E, &V, far_minx, &tri );
00763
00764 nt = tri.nElems;
00765 Tri.reserve_pool(nt);
00766 tr = tri.First();
00767
00768 for( i = 0; i < nt; i++ )
00769 {
00770 Tri[i].v[0] = tr->v[0].m_rep->reserved.i;
00771 Tri[i].v[1] = tr->v[1].m_rep->reserved.i;
00772 Tri[i].v[2] = tr->v[2].m_rep->reserved.i;
00773 tr = tr->next;
00774 }
00775 *nTri = nt;
00776 }
00777
00778 template GULAPI void TriangulatePolygon3d<float>(
00779 const List< ListNode< gul::polyline< point<float> > > >& C3,
00780 const List< ListNode< gul::polyline< point<float> > > >& N3,
00781 const List< ListNode< gul::polyline< point<float> > > >& T3,
00782 const Ptr< Ptr< float > >& Ti,
00783 Ptr< point2<float> >& D,
00784 Ptr< point<float> >& F,
00785 Ptr< point<float> >& N,
00786 Ptr< point<float> >& Tx,
00787 int *nTri,
00788 Ptr<itriangle>& Tri );
00789
00790 template GULAPI void TriangulatePolygon3d<double>(
00791 const List< ListNode< gul::polyline< point<double> > > >& C3,
00792 const List< ListNode< gul::polyline< point<double> > > >& N3,
00793 const List< ListNode< gul::polyline< point<double> > > >& T3,
00794 const Ptr< Ptr< double > >& Ti,
00795 Ptr< point2<double> >& D,
00796 Ptr< point<double> >& F,
00797 Ptr< point<double> >& N,
00798 Ptr< point<double> >& Tx,
00799 int *nTri,
00800 Ptr<itriangle>& Tri );
00801
00802
00803 }