00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 #ifndef __VCG_GLTRIMESH
00113 #define __VCG_GLTRIMESH
00114
00115 #include <queue>
00116 #include <vector>
00117
00118
00119 #include <wrap/gl/space.h>
00120 #include <wrap/gl/math.h>
00121 #include <vcg/space/color4.h>
00122
00123 namespace vcg {
00124
00125
00126
00127
00128
00129 class GLW
00130 {
00131 public:
00132 enum DrawMode {DMNone, DMBox, DMPoints, DMWire, DMHidden, DMFlat, DMSmooth, DMFlatWire, DMRadar, DMLast} ;
00133 enum NormalMode {NMNone, NMPerVert, NMPerFace, NMPerWedge, NMLast};
00134 enum ColorMode {CMNone, CMPerMesh, CMPerFace, CMPerVert, CMLast};
00135 enum TextureMode{TMNone, TMPerVert, TMPerWedge, TMPerWedgeMulti};
00136 enum Hint {
00137 HNUseTriStrip = 0x0001,
00138
00139 HNUseDisplayList = 0x0004,
00140 HNCacheDisplayList = 0x0008,
00141 HNLazyDisplayList = 0x0010,
00142 HNIsTwoManifold = 0x0020,
00143 HNUsePerWedgeNormal = 0x0040,
00144 HNHasFFTopology = 0x0080,
00145 HNHasVFTopology = 0x0100,
00146 HNHasVertNormal = 0x0200,
00147 HNHasFaceNormal = 0x0400,
00148 HNUseVArray = 0x0800,
00149 HNUseLazyEdgeStrip = 0x1000,
00150 HNUseVBO = 0x2000,
00151 HNIsPolygonal = 0x4000
00152 };
00153
00154 enum Change {
00155 CHVertex = 0x01,
00156 CHNormal = 0x02,
00157 CHColor = 0x04,
00158 CHFace = 0x08,
00159 CHFaceNormal = 0x10,
00160 CHRender = 0x20,
00161 CHAll = 0xff
00162 };
00163 enum HintParami {
00164 HNPDisplayListSize =0
00165 };
00166 enum HintParamf {
00167 HNPCreaseAngle =0,
00168 HNPZTwist = 1,
00169 HNPPointSize = 2
00170 };
00171
00172 template<class MESH_TYPE>
00173 class VertToSplit
00174 {
00175 public:
00176 typename MESH_TYPE::face_base_pointer f;
00177 char z;
00178 char edge;
00179 bool newp;
00180 typename MESH_TYPE::vertex_pointer v;
00181 };
00182
00183
00184 class GLAElem {
00185 public :
00186 int glmode;
00187 int len;
00188 int start;
00189 };
00190
00191
00192 };
00193
00194 template <class MESH_TYPE, bool partial = false , class FACE_POINTER_CONTAINER = std::vector<typename MESH_TYPE::FacePointer> >
00195 class GlTrimesh : public GLW
00196 {
00197 public:
00198
00199 typedef MESH_TYPE mesh_type;
00200 FACE_POINTER_CONTAINER face_pointers;
00201
00202
00203 std::vector<unsigned int> TMId;
00204 unsigned int array_buffers[3];
00205
00206 int curr_hints;
00207
00208
00209 int HNParami[8];
00210 float HNParamf[8];
00211
00212 MESH_TYPE *m;
00213 GlTrimesh()
00214 {
00215 m=0;
00216 dl=0xffffffff;
00217 curr_hints=HNUseLazyEdgeStrip;
00218 cdm=DMNone;
00219 ccm=CMNone;
00220 cnm=NMNone;
00221
00222 SetHintParamf(HNPCreaseAngle,float(M_PI/5));
00223 SetHintParamf(HNPZTwist,0.00005f);
00224 SetHintParamf(HNPPointSize,1.0f);
00225 }
00226
00227 ~GlTrimesh()
00228 {
00229
00230 if(curr_hints&HNUseVBO)
00231 {
00232 for(int i=0;i<3;++i)
00233 if(glIsBuffer(array_buffers[i]))
00234 glDeleteBuffersARB(1, (GLuint *)(array_buffers+i));
00235 }
00236 }
00237
00238 void SetHintParami(const HintParami hip, const int value)
00239 {
00240 HNParami[hip]=value;
00241 }
00242 int GetHintParami(const HintParami hip) const
00243 {
00244 return HNParami[hip];
00245 }
00246 void SetHintParamf(const HintParamf hip, const float value)
00247 {
00248 HNParamf[hip]=value;
00249 }
00250 float GetHintParamf(const HintParamf hip) const
00251 {
00252 return HNParamf[hip];
00253 }
00254 void SetHint(Hint hn)
00255 {
00256 curr_hints |= hn;
00257 }
00258 void ClearHint(Hint hn)
00259 {
00260 curr_hints&=(~hn);
00261 }
00262
00263 unsigned int dl;
00264 std::vector<unsigned int> indices;
00265
00266 DrawMode cdm;
00267 NormalMode cnm;
00268 ColorMode ccm;
00269
00270 void Update()
00271 {
00272 if(m==0) return;
00273
00274 if(curr_hints&HNUseVArray || curr_hints&HNUseVBO)
00275 {
00276 typename MESH_TYPE::FaceIterator fi;
00277 indices.clear();
00278 for(fi = m->face.begin(); fi != m->face.end(); ++fi)
00279 {
00280 indices.push_back((unsigned int)((*fi).V(0) - &(*m->vert.begin())));
00281 indices.push_back((unsigned int)((*fi).V(1) - &(*m->vert.begin())));
00282 indices.push_back((unsigned int)((*fi).V(2) - &(*m->vert.begin())));
00283 }
00284
00285 if(curr_hints&HNUseVBO)
00286 {
00287 if(!glIsBuffer(array_buffers[1]))
00288 glGenBuffers(2,(GLuint*)array_buffers);
00289 glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]);
00290 glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType),
00291 (char *)&(m->vert[0].P()), GL_STATIC_DRAW_ARB);
00292
00293 glBindBuffer(GL_ARRAY_BUFFER,array_buffers[1]);
00294 glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType),
00295 (char *)&(m->vert[0].N()), GL_STATIC_DRAW_ARB);
00296 }
00297
00298 glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
00299 glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 }
00330
00331 void Draw(DrawMode dm ,ColorMode cm, TextureMode tm)
00332 {
00333 switch(dm)
00334 {
00335 case DMNone : Draw<DMNone >(cm,tm); break;
00336 case DMBox : Draw<DMBox >(cm,tm); break;
00337 case DMPoints : Draw<DMPoints >(cm,tm); break;
00338 case DMWire : Draw<DMWire >(cm,tm); break;
00339 case DMHidden : Draw<DMHidden >(cm,tm); break;
00340 case DMFlat : Draw<DMFlat >(cm,tm); break;
00341 case DMSmooth : Draw<DMSmooth >(cm,tm); break;
00342 case DMFlatWire: Draw<DMFlatWire>(cm,tm); break;
00343 default : break;
00344 }
00345 }
00346
00347 template< DrawMode dm >
00348 void Draw(ColorMode cm, TextureMode tm)
00349 {
00350 switch(cm)
00351 {
00352 case CMNone : Draw<dm,CMNone >(tm); break;
00353 case CMPerMesh : Draw<dm,CMPerMesh>(tm); break;
00354 case CMPerFace : Draw<dm,CMPerFace>(tm); break;
00355 case CMPerVert : Draw<dm,CMPerVert>(tm); break;
00356 default : break;
00357 }
00358 }
00359
00360 template< DrawMode dm, ColorMode cm >
00361 void Draw(TextureMode tm)
00362 {
00363 switch(tm)
00364 {
00365 case TMNone : Draw<dm,cm,TMNone >(); break;
00366 case TMPerVert : Draw<dm,cm,TMPerVert >(); break;
00367 case TMPerWedge : Draw<dm,cm,TMPerWedge >(); break;
00368 case TMPerWedgeMulti : Draw<dm,cm,TMPerWedgeMulti >(); break;
00369 default : break;
00370 }
00371 }
00372
00373
00374
00375 template< DrawMode dm, ColorMode cm, TextureMode tm>
00376 void Draw()
00377 {
00378 if(!m) return;
00379 if((curr_hints & HNUseDisplayList)){
00380 if (cdm==dm && ccm==cm){
00381 glCallList(dl);
00382 return;
00383 }
00384 else {
00385 if(dl==0xffffffff) dl=glGenLists(1);
00386 glNewList(dl,GL_COMPILE);
00387 }
00388 }
00389
00390 glPushMatrix();
00391 switch(dm)
00392 {
00393 case DMNone : break;
00394 case DMBox : DrawBBox(cm);break;
00395 case DMPoints : DrawPoints<NMPerVert,cm>();break;
00396 case DMHidden : DrawHidden();break;
00397 case DMFlat : DrawFill<NMPerFace,cm,tm>();break;
00398 case DMFlatWire : DrawFlatWire<NMPerFace,cm,tm>();break;
00399 case DMRadar : DrawRadar<NMPerFace,cm>();break;
00400 case DMWire : DrawWire<NMPerVert,cm>();break;
00401 case DMSmooth : DrawFill<NMPerVert,cm,tm>();break;
00402 default : break;
00403 }
00404 glPopMatrix();
00405
00406 if((curr_hints & HNUseDisplayList)){
00407 cdm=dm;
00408 ccm=cm;
00409 glEndList();
00410 glCallList(dl);
00411 }
00412 }
00413
00414
00415
00416
00417
00418
00419 template <NormalMode nm, ColorMode cm, TextureMode tm>
00420 void DrawFill()
00421 {
00422 if(m->fn==0) return;
00423 typename FACE_POINTER_CONTAINER::iterator fp;
00424
00425 typename MESH_TYPE::FaceIterator fi;
00426
00427 typename std::vector<typename MESH_TYPE::FaceType*>::iterator fip;
00428 short curtexname=-1;
00429
00430 if(cm == CMPerMesh)
00431 glColor(m->C());
00432
00433 if(tm == TMPerWedge || tm == TMPerWedgeMulti )
00434 glDisable(GL_TEXTURE_2D);
00435
00436 if(curr_hints&HNUseVBO)
00437 {
00438 if( (cm==CMNone) || (cm==CMPerMesh) )
00439 {
00440 if (nm==NMPerVert)
00441 glEnableClientState (GL_NORMAL_ARRAY);
00442 glEnableClientState (GL_VERTEX_ARRAY);
00443
00444 if (nm==NMPerVert)
00445 {
00446 glBindBuffer(GL_ARRAY_BUFFER,array_buffers[1]);
00447 glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
00448 }
00449 glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]);
00450 glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0);
00451
00452 glDrawElements(GL_TRIANGLES ,m->fn*3,GL_UNSIGNED_INT, &(*indices.begin()) );
00453 glDisableClientState (GL_VERTEX_ARRAY);
00454 if (nm==NMPerVert)
00455 glDisableClientState (GL_NORMAL_ARRAY);
00456
00457 glBindBuffer(GL_ARRAY_BUFFER, 0);
00458
00459 return;
00460
00461 }
00462 }
00463
00464 if(curr_hints&HNUseVArray)
00465 {
00466 if( (cm==CMNone) || (cm==CMPerMesh) )
00467 {
00468 if (nm==NMPerVert)
00469 glEnableClientState (GL_NORMAL_ARRAY);
00470 glEnableClientState (GL_VERTEX_ARRAY);
00471
00472 if (nm==NMPerVert)
00473 glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->N()[0]));
00474 glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->P()[0]));
00475
00476 glDrawElements(GL_TRIANGLES ,m->fn*3,GL_UNSIGNED_INT, &(*indices.begin()) );
00477 glDisableClientState (GL_VERTEX_ARRAY);
00478 if (nm==NMPerVert)
00479 glDisableClientState (GL_NORMAL_ARRAY);
00480
00481 return;
00482 }
00483 }
00484 else
00485
00486 if(curr_hints&HNUseTriStrip)
00487 {
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 }
00522 else
00523 {
00524 if(partial)
00525 fp = face_pointers.begin();
00526 else
00527 fi = m->face.begin();
00528
00529 if(tm==TMPerWedgeMulti)
00530 {
00531 curtexname=(*fi).WT(0).n();
00532 if (curtexname >= 0)
00533 {
00534 glEnable(GL_TEXTURE_2D);
00535 glBindTexture(GL_TEXTURE_2D,TMId[curtexname]);
00536 }
00537 else
00538 {
00539 glDisable(GL_TEXTURE_2D);
00540 }
00541 }
00542
00543 if(tm==TMPerWedge)
00544 glEnable(GL_TEXTURE_2D);
00545
00546 if(tm==TMPerVert && !TMId.empty())
00547 {
00548 curtexname = 0;
00549 glEnable(GL_TEXTURE_2D);
00550 glBindTexture(GL_TEXTURE_2D,TMId[curtexname]);
00551 }
00552 glBegin(GL_TRIANGLES);
00553
00554 while( (partial)?(fp!=face_pointers.end()):(fi!=m->face.end()))
00555 {
00556 typename MESH_TYPE::FaceType & f = (partial)?(*(*fp)): *fi;
00557
00558 if(!f.IsD())
00559 {
00560 if(tm==TMPerWedgeMulti)
00561 if(f.WT(0).n() != curtexname)
00562 {
00563 curtexname=(*fi).WT(0).n();
00564 glEnd();
00565
00566 if (curtexname >= 0)
00567 {
00568 glEnable(GL_TEXTURE_2D);
00569 glBindTexture(GL_TEXTURE_2D,TMId[curtexname]);
00570 }
00571 else
00572 {
00573 glDisable(GL_TEXTURE_2D);
00574 }
00575
00576 glBegin(GL_TRIANGLES);
00577 }
00578
00579 if(nm == NMPerFace) glNormal(f.cN());
00580 if(nm == NMPerVert) glNormal(f.V(0)->cN());
00581 if(nm == NMPerWedge)glNormal(f.WN(0));
00582
00583 if(cm == CMPerFace) glColor(f.C());
00584 if(cm == CMPerVert) glColor(f.V(0)->C());
00585 if(tm==TMPerVert) glTexCoord(f.V(0)->T().P());
00586 if( (tm==TMPerWedge)||(tm==TMPerWedgeMulti) )glTexCoord(f.WT(0).t(0));
00587 glVertex(f.V(0)->P());
00588
00589 if(nm == NMPerVert) glNormal(f.V(1)->cN());
00590 if(nm == NMPerWedge)glNormal(f.WN(1));
00591 if(cm == CMPerVert) glColor(f.V(1)->C());
00592 if(tm==TMPerVert) glTexCoord(f.V(1)->T().P());
00593 if( (tm==TMPerWedge)|| (tm==TMPerWedgeMulti)) glTexCoord(f.WT(1).t(0));
00594 glVertex(f.V(1)->P());
00595
00596 if(nm == NMPerVert) glNormal(f.V(2)->cN());
00597 if(nm == NMPerWedge)glNormal(f.WN(2));
00598 if(cm == CMPerVert) glColor(f.V(2)->C());
00599 if(tm==TMPerVert) glTexCoord(f.V(2)->T().P());
00600 if( (tm==TMPerWedge)|| (tm==TMPerWedgeMulti)) glTexCoord(f.WT(2).t(0));
00601 glVertex(f.V(2)->P());
00602 }
00603
00604 if(partial)
00605 ++fp;
00606 else
00607 ++fi;
00608 }
00609
00610 glEnd();
00611
00612 }
00613 }
00614
00615
00616 template <NormalMode nm, ColorMode cm>
00617 void DrawWirePolygonal()
00618 {
00619
00620 typename MESH_TYPE::FaceIterator fi;
00621
00622
00623 typename FACE_POINTER_CONTAINER::iterator fp;
00624
00625 typename std::vector<typename MESH_TYPE::FaceType*>::iterator fip;
00626
00627 if(cm == CMPerMesh)
00628 glColor(m->C());
00629
00630 {
00631 if(partial)
00632 fp = face_pointers.begin();
00633 else
00634 fi = m->face.begin();
00635
00636 glBegin(GL_LINES);
00637
00638 while( (partial)?(fp!=face_pointers.end()):(fi!=m->face.end()))
00639 {
00640 typename MESH_TYPE::FaceType & f = (partial)?(*(*fp)): *fi;
00641
00642 if(!f.IsD())
00643 {
00644
00645 if(nm == NMPerFace) glNormal(f.cN());
00646 if(cm == CMPerFace) glColor(f.C());
00647
00648 if (!f.IsF(0)) {
00649 if(nm == NMPerVert) glNormal(f.V(0)->cN());
00650 if(nm == NMPerWedge)glNormal(f.WN(0));
00651 if(cm == CMPerVert) glColor(f.V(0)->C());
00652 glVertex(f.V(0)->P());
00653
00654 if(nm == NMPerVert) glNormal(f.V(1)->cN());
00655 if(nm == NMPerWedge)glNormal(f.WN(1));
00656 if(cm == CMPerVert) glColor(f.V(1)->C());
00657 glVertex(f.V(1)->P());
00658 }
00659
00660 if (!f.IsF(1)) {
00661 if(nm == NMPerVert) glNormal(f.V(1)->cN());
00662 if(nm == NMPerWedge)glNormal(f.WN(1));
00663 if(cm == CMPerVert) glColor(f.V(1)->C());
00664 glVertex(f.V(1)->P());
00665
00666 if(nm == NMPerVert) glNormal(f.V(2)->cN());
00667 if(nm == NMPerWedge)glNormal(f.WN(2));
00668 if(cm == CMPerVert) glColor(f.V(2)->C());
00669 glVertex(f.V(2)->P());
00670 }
00671
00672 if (!f.IsF(2)) {
00673 if(nm == NMPerVert) glNormal(f.V(2)->cN());
00674 if(nm == NMPerWedge)glNormal(f.WN(2));
00675 if(cm == CMPerVert) glColor(f.V(2)->C());
00676 glVertex(f.V(2)->P());
00677
00678 if(nm == NMPerVert) glNormal(f.V(0)->cN());
00679 if(nm == NMPerWedge)glNormal(f.WN(0));
00680 if(cm == CMPerVert) glColor(f.V(0)->C());
00681 glVertex(f.V(0)->P());
00682 }
00683
00684 }
00685
00686 if(partial)
00687 ++fp;
00688 else
00689 ++fi;
00690 }
00691
00692 glEnd();
00693
00694 }
00695 }
00696
00698
00699 template<NormalMode nm, ColorMode cm>
00700 void DrawPointsBase()
00701 {
00702 typename MESH_TYPE::VertexIterator vi;
00703 glBegin(GL_POINTS);
00704 if(cm==CMPerMesh) glColor(m->C());
00705
00706 for(vi=m->vert.begin();vi!=m->vert.end();++vi)if(!(*vi).IsD())
00707 {
00708 if(nm==NMPerVert) glNormal((*vi).cN());
00709 if(cm==CMPerVert) glColor((*vi).C());
00710 glVertex((*vi).P());
00711 }
00712 glEnd();
00713 }
00714
00716 double CameraDistance(){
00717 Point3<typename MESH_TYPE::ScalarType> res;
00718 Matrix44<typename MESH_TYPE::ScalarType> mm;
00719 glGetv(GL_MODELVIEW_MATRIX,mm);
00720 Point3<typename MESH_TYPE::ScalarType> c=m->bbox.Center();
00721 res=mm*c;
00722 return Norm(res);
00723 }
00724 template<NormalMode nm, ColorMode cm>
00725 void DrawPoints()
00726 {
00727 glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT);
00728 glPointSize(GetHintParamf(HNPPointSize));
00729
00730 if (glPointParameterfv) {
00731 float camDist = (float)CameraDistance();
00732 float quadratic[] = { 0.0f, 0.0f, 1.0f/(camDist*camDist) , 0.0f };
00733 glPointParameterfv( GL_POINT_DISTANCE_ATTENUATION, quadratic );
00734 glPointParameterf( GL_POINT_SIZE_MAX, 16.0f );
00735 glPointParameterf( GL_POINT_SIZE_MIN, 1.0f );
00736 }
00737
00738 if(m->vn!=(int)m->vert.size())
00739 {
00740 DrawPointsBase<nm,cm>();
00741 }
00742 else
00743 {
00744 if(cm==CMPerMesh)
00745 glColor(m->C());
00746
00747
00748
00749 if (nm==NMPerVert)
00750 {
00751 glEnableClientState (GL_NORMAL_ARRAY);
00752 if (m->vert.size() != 0)
00753 glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->N()[0]));
00754 }
00755 if (cm==CMPerVert)
00756 {
00757 glEnableClientState (GL_COLOR_ARRAY);
00758 if (m->vert.size() != 0)
00759 glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->C()[0]));
00760 }
00761
00762 glEnableClientState (GL_VERTEX_ARRAY);
00763 if (m->vert.size() != 0)
00764 glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->P()[0]));
00765
00766 glDrawArrays(GL_POINTS,0,m->vn);
00767
00768 glDisableClientState (GL_VERTEX_ARRAY);
00769 if (nm==NMPerVert) glDisableClientState (GL_NORMAL_ARRAY);
00770 if (cm==CMPerVert) glDisableClientState (GL_COLOR_ARRAY);
00771 }
00772 glPopAttrib();
00773 return;
00774 }
00775
00776 void DrawHidden()
00777 {
00778
00779 glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT );
00780 glEnable(GL_POLYGON_OFFSET_FILL);
00781 glPolygonOffset(1.0, 1);
00782
00783 glDisable(GL_LIGHTING);
00784 glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
00785 DrawFill<NMNone,CMNone,TMNone>();
00786 glDisable(GL_POLYGON_OFFSET_FILL);
00787 glEnable(GL_LIGHTING);
00788 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
00789
00790 DrawWire<NMPerVert,CMNone>();
00791 glPopAttrib();
00792
00793 }
00794
00795 template <NormalMode nm, ColorMode cm, TextureMode tm>
00796 void DrawFlatWire()
00797 {
00798
00799
00800 glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT );
00801 glEnable(GL_POLYGON_OFFSET_FILL);
00802 glPolygonOffset(1.0, 1);
00803 DrawFill<nm,cm,tm>();
00804 glDisable(GL_POLYGON_OFFSET_FILL);
00805
00806 glEnable(GL_COLOR_MATERIAL);
00807 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
00808
00809 glColor3f(.3f,.3f,.3f);
00810 DrawWire<nm,CMNone>();
00811 glPopAttrib();
00812
00813 }
00814
00815 template <NormalMode nm, ColorMode cm>
00816 void DrawRadar()
00817 {
00818 const float ZTWIST=HNParamf[HNPZTwist];
00819 glEnable(GL_BLEND);
00820 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00821 glDepthMask(0);
00822 glDepthRange(ZTWIST,1.0f);
00823
00824 if (cm == CMNone)
00825 glColor4f(0.2f, 1.0f, 0.4f, 0.2f);
00826
00827 Draw<DMFlat,CMNone,TMNone>();
00828
00829 glDepthMask(1);
00830 glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
00831
00832 Draw<DMFlat,CMNone,TMNone>();
00833
00834 glDepthRange(0.0f,1.0f-ZTWIST);
00835 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
00836 glColor4f(0.1f, 1.0f, 0.2f, 0.6f);
00837 Draw<DMWire,CMNone,TMNone>();
00838 glDisable(GL_BLEND);
00839 glDepthRange(0,1.0f);
00840
00841 }
00842
00843
00844
00845 #ifdef GL_TEXTURE0_ARB
00846
00847 void DrawTexture_NPV_TPW2()
00848 {
00849 unsigned int texname=(*(m->face.begin())).WT(0).n(0);
00850 glBindTexture(GL_TEXTURE_2D,TMId[texname]);
00851 typename MESH_TYPE::FaceIterator fi;
00852 glBegin(GL_TRIANGLES);
00853 for(fi=m->face.begin();fi!=m->face.end();++fi)if(!(*fi).IsD()){
00854 if(texname!=(*fi).WT(0).n(0)) {
00855 texname=(*fi).WT(0).n(0);
00856 glEnd();
00857 glBindTexture(GL_TEXTURE_2D,TMId[texname]);
00858 glBegin(GL_TRIANGLES);
00859 }
00860 glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(0).t(0));
00861 glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(0).t(0));
00862 glNormal((*fi).V(0)->N());
00863 glVertex((*fi).V(0)->P());
00864
00865 glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(1).t(0));
00866 glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(1).t(0));
00867 glNormal((*fi).V(1)->N());
00868 glVertex((*fi).V(1)->P());
00869
00870 glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(2).t(0));
00871 glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(2).t(0));
00872 glNormal((*fi).V(2)->N());
00873 glVertex((*fi).V(2)->P());
00874 }
00875 glEnd();
00876 }
00877
00878 #endif
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 private:
00892
00893 template <NormalMode nm, ColorMode cm>
00894 void DrawWire()
00895 {
00896
00897 if ( (curr_hints & HNIsPolygonal) )
00898 {
00899 DrawWirePolygonal<nm,cm>();
00900 }
00901 else
00902 {
00903 glPushAttrib(GL_POLYGON_BIT);
00904 glPolygonMode(GL_FRONT_AND_BACK ,GL_LINE);
00905 DrawFill<nm,cm,TMNone>();
00906 glPopAttrib();
00907 }
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927 }
00928
00929 void DrawBBox(ColorMode cm)
00930 {
00931 if(cm==CMPerMesh) glColor(m->C());
00932 glBoxWire(m->bbox);
00933 }
00934
00935
00936 };
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955 #define VCTRACE (void)0
00956
00957
00958 template<class MESH_TYPE>
00959 void Crease(MESH_TYPE &m, typename MESH_TYPE::scalar_type angleRad)
00960 {
00961 assert(m.HasFFTopology());
00962 typename MESH_TYPE::scalar_type cosangle=Cos(angleRad);
00963
00964 std::vector<GLW::VertToSplit<MESH_TYPE> > SPL;
00965 std::vector<typename MESH_TYPE::VertexType> newvert;
00966 newvert.reserve(m.fn*3);
00967
00968 enum {VISITED_0= MESH_TYPE::FaceType::USER0,
00969 VISITED_1= MESH_TYPE::FaceType::USER0<<1,
00970 VISITED_2= MESH_TYPE::FaceType::USER0<<2} ;
00971 int vis[3]={VISITED_0,VISITED_1,VISITED_2};
00972
00973
00974 typename MESH_TYPE::FaceIterator fi;
00975 for(fi=m.face.begin();fi!=m.face.end();++fi)
00976 if(!(*fi).IsD()) (*fi).Supervisor_Flags()&= (~(VISITED_0 | VISITED_1 | VISITED_2));
00977
00978 for(fi=m.face.begin();fi!=m.face.end();++fi)
00979 if(!(*fi).IsD())
00980 for(int j=0;j<3;++j)
00981 if(!((*fi).Supervisor_Flags() & (vis[j])))
00982 {
00983
00984
00985 typename MESH_TYPE::hedgepos_type he(&*fi,j,(*fi).V(j));
00986 typename MESH_TYPE::hedgepos_type she=he;
00987 typename MESH_TYPE::face_base_pointer nextf;
00988 GLW::VertToSplit<MESH_TYPE> spl;
00989 spl.newp=false;
00990 spl.edge=-1;
00991
00992
00993 do {
00994 he.FlipF();
00995 he.FlipE();
00996 if(he.IsBorder()) break;
00997 } while(he!=she);
00998 if(he==she)
00999 {
01000 do {
01001 he.FlipF();
01002 he.FlipE();
01003 nextf=he.f->F(he.z);
01004 typename MESH_TYPE::scalar_type ps=nextf->N()*he.f->N();
01005 if(ps<cosangle) break;
01006 int vz=0;
01007 if(he.v == he.f->V(he.z)) vz=he.z;
01008 if(he.v == he.f->V((he.z+1)%3)) vz=(he.z+1)%3;
01009 assert((he.f->Supervisor_Flags() & vis[vz] )==0);
01010 } while(he!=she);
01011 }
01012 he.FlipE();
01013
01014 she=he;
01015 newvert.push_back(*(*fi).V(j));
01016 typename MESH_TYPE::vertex_pointer curvert=&newvert.back();
01017
01018
01019
01020 do{
01021
01022 spl.v=curvert;
01023 spl.f=he.f;
01024 spl.z=-1;
01025 if(he.v == he.f->V(he.z)) spl.z=he.z;
01026 if(he.v == he.f->V((he.z+1)%3)) spl.z=(he.z+1)%3;
01027 assert(spl.z>=0);
01028
01029
01030 assert((spl.f->Supervisor_Flags() & vis[spl.z] )==0);
01031 spl.f->Supervisor_Flags() |= vis[spl.z];
01032 SPL.push_back(spl);
01033 spl.newp=false;
01034 spl.edge=-1;
01035 if(he.IsBorder()) break;
01036 nextf=he.f->F(he.z);
01037 if(nextf==she.f) break;
01038 typename MESH_TYPE::scalar_type ps=nextf->N()*he.f->N();
01039 if(ps<cosangle){
01040
01041 newvert.push_back(*(he.v));
01042 curvert=&newvert.back();
01043 spl.newp=true;
01044
01045 }
01046 he.FlipF();
01047 if(spl.newp) spl.edge=he.z;
01048 he.FlipE();
01049
01050 }while(he!=she);
01051 }
01052 assert(SPL.size()==m.fn*3);
01053
01054 typename std::vector<GLW::VertToSplit<MESH_TYPE> >::iterator vsi;
01055 for(vsi=SPL.begin();vsi!=SPL.end();++vsi)
01056 {
01057 (*vsi).f->V((*vsi).z)=(*vsi).v;
01058 if((*vsi).newp){
01059 assert((*vsi).edge>=0 && (*vsi).edge<3);
01060 if(!(*vsi).f->IsBorder( (*vsi).edge) )
01061 (*vsi).f->Detach((*vsi).edge);
01062
01063 }
01064 }
01065
01066 m.vert.math::Swap(newvert);
01067 m.vn=m.vert.size();
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 #endif