00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __GLWRAPTETRA__
00025 #define __GLWRAPTETRA__
00026 #include <GL/glew.h>
00027 #include <GL/GL.h>
00028 #include <vcg/space/color4.h>
00029 #include <vcg/space/tetra3.h>
00030 #include <wrap/gui/view.h>
00031 #include <wrap/gl/space.h>
00032 #include <wrap/gl/math.h>
00033
00034 namespace vcg {
00035
00036 namespace tetra {
00037
00038 class GLW {
00039 public:
00040 enum DrawMode {DMNone, DMSmallTetra,DMFlat,DMWire, DMHidden,DMTransparent,DMFlatWire} ;
00041 enum NormalMode{NMFlat,NMSmooth, NMUser, NMPerMesh};
00042 enum ColorMode {CMNone, CMPerMesh,CMUser,CMPerTetraF,CMPerVertexF,CMPerVertex};
00043 enum Hint {HShrinkFactor};
00044 };
00045
00046 template <typename CONT_TETRA>
00047 class GlTetramesh:public GLW{
00048
00049
00050 public:
00051
00052 typedef typename CONT_TETRA::value_type TetraType;
00053 typedef typename TetraType::VertexType VertexType;
00054 typedef typename VertexType::ScalarType ScalarType;
00055 typedef typename VertexType::CoordType Point3x;
00056
00057
00058 class ClipPlane
00059 {
00060 private:
00061 Point3x D;
00062 Point3x D0;
00063 GLdouble eqn[4];
00064 vcg::Matrix44<float> TR;
00065
00066 Point3x pp0;
00067 Point3x pp1;
00068 Point3x pp2;
00069 Point3x pp3;
00070
00071 public:
00072
00073 bool active;
00074
00075 Point3x P;
00076
00077 ClipPlane (){active=false;}
00078
00079 ~ClipPlane (){}
00080
00081 ClipPlane(Point3x p0, Point3x p1,Point3x p2)
00082 {
00083 Point3x N=((p1-p0)^(p2-p0)).Normalize();
00084 N.Normalize();
00085 D=N;
00086 D0=D;
00087 P=(p0+p1+p2)/3.f;
00088
00089 Point3x v0=N;
00090 Point3x v1=(P-p0);
00091 v1.Normalize();
00092 Point3x v2=(v0^v1);
00093 v2.Normalize();
00094
00095 v0=v0*2;
00096 v1=v1*2;
00097 v2=v2*2;
00098
00099 pp0=-v1-v2;
00100 pp1=-v1+v2;
00101 pp2=v1+v2;
00102 pp3=v1-v2;
00103
00104 }
00105
00106 void SetD(Point3x d)
00107 {
00108 D=d;
00109 }
00110
00111 void SetP(Point3x p)
00112 {
00113 P=p;
00114 }
00115
00116 void GlClip()
00117 {
00118 if (active){
00119 GLdouble d=-(D.V(0)*P.V(0)+D.V(1)*P.V(1)+D.V(2)*P.V(2));
00120 eqn[0]=-D.V(0);
00121 eqn[1]=-D.V(1);
00122 eqn[2]=-D.V(2);
00123 eqn[3]=-d;
00124 glClipPlane(GL_CLIP_PLANE0, eqn);
00125 glEnable(GL_CLIP_PLANE0);
00126 }
00127 }
00128
00129 void GlDraw()
00130 {
00131 glPushMatrix();
00132 glPushAttrib(0xffffffff);
00133 glDisable(GL_CLIP_PLANE0);
00134
00135 glEnable(GL_LIGHTING);
00136 glEnable(GL_NORMALIZE);
00137
00138 glTranslate(P);
00139 glMultMatrix(TR);
00140 glLineWidth(0.5);
00141 glColor3d(0.7,0,0.7);
00142 glBegin(GL_LINE_LOOP);
00143 glVertex(pp0);
00144 glVertex(pp1);
00145 glVertex(pp2);
00146 glVertex(pp3);
00147 glEnd();
00148
00149 glPopAttrib();
00150 glPopMatrix();
00151
00152 }
00153
00154 void Transform(vcg::Matrix44<float> Tr)
00155 {
00156
00157
00158 Point3f p=Point3f((float)D0.V(0),(float)D0.V(1),(float)D0.V(2));
00159 TR=Tr;
00160 p=TR*p;
00161 D=Point3x((ScalarType) p.V(0),(ScalarType) p.V(1),(ScalarType) p.V(2));
00162 }
00163
00164 void Translate(float L)
00165 {
00166 Point3x D1=D*L;
00167 P+=D1;
00168 }
00169
00170
00171 };
00172
00173 GlTetramesh(CONT_TETRA * _t):tetra(_t){}
00174 GlTetramesh( ) {}
00175
00176 CONT_TETRA * tetra;
00177 ClipPlane section;
00178
00179 private:
00180 ScalarType shrink_factor;
00181
00182
00183 public:
00184
00185 void SetHint(Hint h, double value){
00186 switch(h){
00187 case HShrinkFactor: shrink_factor = value; break;
00188 }
00189 }
00190
00191 void AddClipSection(Point3x p0,Point3x p1,Point3x p2)
00192 {
00193 section=ClipPlane(p0,p1,p2);
00194 section.active=true;
00195 }
00196
00197 void ClearClipSection()
00198 {
00199 section.active=false;
00200 }
00201
00202 typedef Color4b (*color_func_vertex)(VertexType&v);
00203 color_func_vertex color_vertex;
00204
00205 typedef Color4b (*color_func_tetra)(TetraType&v);
00206 color_func_tetra color_tetra;
00207
00208
00209 template <DrawMode dm,NormalMode nm,ColorMode cm >
00210
00211 void Draw(){
00212 switch (dm){
00213 case DMNone: break;
00214 case DMSmallTetra:_DrawSmallTetra<cm>();break;
00215 case DMFlat:_DrawSurface<dm,nm,cm>();break;
00216 case DMWire:_DrawSurface<dm,nm,cm>();break;
00217 case DMHidden:_DrawSurface<dm,nm,cm>();break;
00218 case DMFlatWire:_DrawFlatWire<nm,cm>(); break;
00219 case DMTransparent:break;
00220 }
00221 }
00222
00223 private:
00224 template <ColorMode cm >
00225 void _DrawSmallTetra(){
00226 Point3x p[4],br;
00227 typename CONT_TETRA::iterator it;
00228 glPushAttrib(0xffffffff);
00229 glEnable(GL_COLOR_MATERIAL);
00230 glEnable(GL_LIGHT0);
00231 glEnable(GL_LIGHTING);
00232 glEnable(GL_NORMALIZE);
00233 glPolygonMode(GL_FRONT,GL_FILL);
00234 if (section.active)
00235 {
00236 section.GlClip();
00237 section.GlDraw();
00238 }
00239
00240 for( it = tetra->begin(); it != tetra->end(); ++it)
00241 if((!it->IsD())&&(!(it->IsS())))
00242 {
00243 _DrawSmallTetra<cm>(*it);
00244 }
00245 else
00246 if((!it->IsD())&&((it->IsS())))
00247 {
00248 _DrawSelectedTetra(*it);
00249 }
00250
00251 glPopAttrib();
00252 }
00253
00254 template <NormalMode nm,ColorMode cm >
00255 void _DrawFlatWire(){
00256 glPushAttrib(0xffff);
00257 glEnable(GL_COLOR_MATERIAL);
00258 glEnable(GL_DEPTH);
00259 glDepthRange(0.001,1.0);
00260 Draw<DMFlat,nm,cm>();
00261 glDisable(GL_LIGHTING);
00262 glColor3f(0.0,0.0,0.0);
00263 glDepthRange(0.0,0.999);
00264 Draw<DMHidden,nm,cm>();
00265 glPopAttrib();
00266 }
00267
00268
00269 template <DrawMode dm,NormalMode nm,ColorMode cm >
00270 void _DrawSurface(){
00271 typename CONT_TETRA::iterator it;
00272
00273 glPushAttrib(0xffff);
00274 glEnable(GL_COLOR_MATERIAL);
00275 if((dm == DMWire)||(dm ==DMHidden))
00276 {
00277 glDisable(GL_LIGHTING);
00278 glDisable(GL_NORMALIZE);
00279 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
00280 }
00281 else
00282 {
00283 glEnable(GL_LIGHTING);
00284 glEnable(GL_NORMALIZE);
00285 glPolygonMode(GL_FRONT,GL_FILL);
00286 }
00287
00288 for( it = tetra->begin(); it != tetra->end(); ++it)
00289 _DrawTetra<dm,nm,cm>((*it));
00290
00291 glPopAttrib();
00292 }
00293
00294
00295 void _DrawSelectedTetra(TetraType &t)
00296 {
00297 glPushMatrix();
00298 glPushAttrib(0xffff);
00299 glDisable(GL_CLIP_PLANE0);
00300 glDisable(GL_BLEND);
00301 glDisable(GL_LIGHTING);
00302 glDisable(GL_NORMALIZE);
00303 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
00304
00305 glColor3d(1,0,0);
00306
00307 glBegin(GL_TRIANGLES);
00308 for (int face=0;face<4;face++)
00309 {
00310 glVertex(t.V(Tetra::VofF(face,0))->P());
00311 glVertex(t.V(Tetra::VofF(face,1))->P());
00312 glVertex(t.V(Tetra::VofF(face,2))->P());
00313 }
00314 glEnd();
00315
00316
00317 glPopAttrib();
00318 glPopMatrix();
00319 }
00320
00321 template <DrawMode dm,NormalMode nm,ColorMode cm >
00322 void _DrawTetra(TetraType &t)
00323 {
00324 if((!t.IsD())&&(!t.IsS()))
00325 {
00326 if ((dm!=DMWire)&&(dm!=DMHidden))
00327 _ChooseColorTetra<cm>(t);
00328 for(int i = 0; i < 4; ++i){
00329 if (dm == DMWire)
00330 _DrawFace<cm>(t,i);
00331 else
00332 {
00333 if (t.IsBorderF(i))
00334 {
00335 if(nm==NMSmooth)
00336 _DrawFaceSmooth<cm>(t,i);
00337 else
00338 if(nm==NMFlat)
00339 _DrawFace<cm>(t,i);
00340 }
00341 }
00342 }
00343 }
00344 else
00345 if((!t.IsD())&&(t.IsS()))
00346 _DrawSelectedTetra(t);
00347 }
00348
00349 template <ColorMode cm >
00350 void _ChooseColorTetra(TetraType &t)
00351 {
00352 if (cm==CMNone)
00353 {
00354 if (t.IsS())
00355 glColor3d(1,0,0);
00356 else
00357 glColor3d(0.8f,0.8f,0.8f);
00358 }
00359 else
00360 if(cm == CMPerTetraF)
00361 {
00362 Color4b c;
00363 c = color_tetra(t);
00364 GLint ic[4]; ic[0] = c[0];ic[1] = c[1];ic[2] = c[2];ic[3] = c[3];
00365 glMaterialiv(GL_FRONT,GL_DIFFUSE ,ic);
00366 }
00367 }
00368
00369 template <ColorMode cm >
00370 void _ChooseColorVertex(VertexType &v)
00371 {
00372 if (cm!=CMNone)
00373 {
00374 if(cm == CMPerVertexF)
00375 {
00376 Color4b c;
00377 c = color_vertex(v);
00378 GLint ic[4]; ic[0] = c[0];ic[1] = c[1];ic[2] = c[2];ic[3] = c[3];
00379 glMaterialiv(GL_FRONT,GL_DIFFUSE ,ic);
00380 }
00381 else
00382 if(cm == CMPerVertex)
00383 glColor3f(v.C()[0],v.C()[1],v.C()[2]);
00384 }
00385 }
00386
00387 template <ColorMode cm >
00388 void _DrawFaceSmooth(TetraType &t,int face)
00389 {
00390
00391 VertexType *v0=t.V(Tetra::VofF(face,0));
00392 VertexType *v1=t.V(Tetra::VofF(face,1));
00393 VertexType *v2=t.V(Tetra::VofF(face,2));
00394
00395 glBegin(GL_TRIANGLES);
00396 _ChooseColorVertex<cm>(*v0);
00397 glNormal(v0->N());
00398 glVertex(v0->P());
00399 _ChooseColorVertex<cm>(*v1);
00400 glNormal(v1->N());
00401 glVertex(v1->P());
00402 _ChooseColorVertex<cm>(*v2);
00403 glNormal(v2->N());
00404 glVertex(v2->P());
00405 glEnd();
00406 }
00407
00408 template <ColorMode cm >
00409 void _DrawFace(TetraType &t,int face)
00410 {
00411 glBegin(GL_TRIANGLES);
00412 glNormal(t.N(face));
00413 VertexType *v0=t.V(Tetra::VofF(face,0));
00414 VertexType *v1=t.V(Tetra::VofF(face,1));
00415 VertexType *v2=t.V(Tetra::VofF(face,2));
00416 _ChooseColorVertex<cm>(*v0);
00417 glVertex(v0->P());
00418 _ChooseColorVertex<cm>(*v1);
00419 glVertex(v1->P());
00420 _ChooseColorVertex<cm>(*v2);
00421 glVertex(v2->P());
00422 glEnd();
00423 }
00424
00425 template <ColorMode cm >
00426 void _DrawSmallTetra(TetraType &t)
00427 {
00428 Tetra3<ScalarType> T=Tetra3<ScalarType>();
00429 T.P0(0)=t.V(0)->cP();
00430 T.P1(0)=t.V(1)->cP();
00431 T.P2(0)=t.V(2)->cP();
00432 T.P3(0)=t.V(3)->cP();
00433 Point3x p[4], br;
00434 br=T.ComputeBarycenter();
00435 for(int i = 0; i < 4; ++i)
00436 p[i] = t.V(i)->P()* shrink_factor + br *(1- shrink_factor);
00437 _ChooseColorTetra<cm>(t);
00438
00439 glBegin(GL_TRIANGLES);
00440 for(int i = 0; i < 4; ++i)
00441 {
00442 glNormal(t.N(i));
00443 VertexType *v0=t.V(Tetra::VofF(i,0));
00444 VertexType *v1=t.V(Tetra::VofF(i,1));
00445 VertexType *v2=t.V(Tetra::VofF(i,2));
00446 _ChooseColorVertex<cm>(*v0);
00447 glVertex(p[Tetra::VofF(i,0)]);
00448 _ChooseColorVertex<cm>(*v1);
00449 glVertex(p[Tetra::VofF(i,1)]);
00450 _ChooseColorVertex<cm>(*v2);
00451 glVertex(p[Tetra::VofF(i,2)]);
00452 }
00453 glEnd();
00454 }
00455
00456
00457 };
00458
00459 }
00460 }
00461 #endif