diff --git a/wrap/gl/glwraptetra.h b/wrap/gl/glwraptetra.h new file mode 100644 index 00000000..b919bc28 --- /dev/null +++ b/wrap/gl/glwraptetra.h @@ -0,0 +1,228 @@ +#ifndef __GLWRAPTETRA__ +#define __GLWRAPTETRA__ + +#include +#include +#include +#include + +namespace vcg { +class GLW { +public: + enum DrawMode {DMNone, DMSmallTetra,DMFlat,DMWire, DMHidden,DMTransparent,DMFlatWire} ; + enum NormalMode{NMFlat,NMSmooth, NMUser, NMPerMesh}; + enum ColorMode {CMNone, CMPerMesh,CMUser,CMPerTetraF,CMPerVertexF,CMPerVertex}; + enum Hint {HShrinkFactor}; +}; +template +class GLWrapTetra:public GLW{ +public: + + typedef typename CONT_TETRA::value_type TetraType; + typedef typename TetraType::VertexType VertexType; + typedef typename VertexType::ScalarType ScalarType; + typedef typename VertexType::CoordType Point3x; + + GLWrapTetra(CONT_TETRA & _t):tetra(_t){} + + CONT_TETRA & tetra; + + private: + double shrink_factor; + + public: + + void SetHint(Hint h, double value){ + switch(h){ + case HShrinkFactor: shrink_factor = value; break; + } + } + + typedef Color4b (*color_func_vertex)(VertexType&v); + color_func_vertex color_vertex; + + typedef Color4b (*color_func_tetra)(TetraType&v); + color_func_tetra color_tetra; + + + template + void Draw(){ + switch (dm){ + case DMNone: break; + case DMSmallTetra: _DrawSmallTetra();break; + case DMFlat:_DrawSurface();break; + case DMWire:_DrawSurface();break; + case DMHidden:break;//DrawSurface();break; + case DMFlatWire:_DrawFlatWire(); break; + case DMTransparent:break; + } + } +private: +template + void _DrawSmallTetra(){ + Point3x p[4],br; + CONT_TETRA::iterator it; + glPushAttrib(0xffffffff); + glEnable(GL_LIGHTING); + glEnable(GL_NORMALIZE); + glPolygonMode(GL_FRONT,GL_FILL); + glBegin(GL_TRIANGLES); + for( it = tetra.begin(); it != tetra.end(); ++it) + if(!(*it).IsD()){ + _DrawSmallTetra(*it); + } + glEnd(); + glPopAttrib(); + } + +template +void _DrawFlatWire(){ + glPushAttrib(0xffff); + glEnable(GL_DEPTH); + glDepthRange(0.001,1.0); + Draw(); + glDisable(GL_LIGHTING); + glColor3f(0.0,0.0,0.0); + glDepthRange(0.0,0.999); + Draw(); + glPopAttrib(); +} + + +template +void _DrawSurface(){ + CONT_TETRA::iterator it; + + glPushAttrib(0xffffffff); + glEnable(GL_LIGHTING); + glEnable(GL_NORMALIZE); + if(dm == DMWire) + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + else + glPolygonMode(GL_FRONT,GL_FILL); + + glBegin(GL_TRIANGLES); + for( it = tetra.begin(); it != tetra.end(); ++it) + _DrawTetra((*it)); + glEnd(); + glPopAttrib(); +} + +template +void _DrawTetra(TetraType &t) +{ + if(!(t.IsD())) + { + _ChooseColorTetra(t); + for(int i = 0; i < 4; ++i){ + if(t.IsBorderF(i)) + { + if(nm==NMSmooth) + _DrawFaceSmooth(t,i); + else + if(nm==NMFlat) + _DrawFace(t,i); + } + } + } +} + +template +void _ChooseColorTetra(TetraType &t) +{ + if (cm==CMNone) + glColor3d(0.8,0.8,0.8); + else + if(cm == CMPerTetraF) + { + Color4b c; + c = color_tetra(t); + GLint ic[4]; ic[0] = c[0];ic[1] = c[1];ic[2] = c[2];ic[3] = c[3]; + glMaterialiv(GL_FRONT,GL_DIFFUSE ,ic); + } +} + +template +void _ChooseColorVertex(VertexType &v) +{ + if (cm!=CMNone) + { + if(cm == CMPerVertexF) + { + Color4b c; + c = color_vertex(v); + GLint ic[4]; ic[0] = c[0];ic[1] = c[1];ic[2] = c[2];ic[3] = c[3]; + glMaterialiv(GL_FRONT,GL_DIFFUSE ,ic); + } + else + if(cm == CMPerVertex) + glColor3f(v.C()[0],v.C()[1],v.C()[2]); + } +} + +template +void _DrawFaceSmooth(TetraType &t,int face) +{ + + VertexType *v0=t.V(Tetra::VofF(face,0)); + VertexType *v1=t.V(Tetra::VofF(face,1)); + VertexType *v2=t.V(Tetra::VofF(face,2)); + _ChooseColorVertex(*v0); + glNormal(v0->N()); + glVertex(v0->P()); + _ChooseColorVertex(*v1); + glNormal(v1->N()); + glVertex(v1->P()); + _ChooseColorVertex(*v2); + glNormal(v2->N()); + glVertex(v2->P()); +} + +template +void _DrawFace(TetraType &t,int face) +{ + glNormal(t.N(face)); + VertexType *v0=t.V(Tetra::VofF(face,0)); + VertexType *v1=t.V(Tetra::VofF(face,1)); + VertexType *v2=t.V(Tetra::VofF(face,2)); + _ChooseColorVertex(*v0); + glVertex(v0->P()); + _ChooseColorVertex(*v1); + glVertex(v1->P()); + _ChooseColorVertex(*v2); + glVertex(v2->P()); +} + +template +void _DrawSmallTetra(TetraType &t) +{ + Tetra3 T=Tetra3(); + T.P0(0)=t.V(0)->cP(); + T.P1(0)=t.V(1)->cP(); + T.P2(0)=t.V(2)->cP(); + T.P3(0)=t.V(3)->cP(); + Point3x p[4], br; + br=T.ComputeBarycenter(); + for(int i = 0; i < 4; ++i) + p[i] = t.V(i)->P()* shrink_factor + br *(1- shrink_factor); + _ChooseColorTetra(t); + for(int i = 0; i < 4; ++i) + { + glNormal(t.N(i)); + VertexType *v0=t.V(Tetra::VofF(i,0)); + VertexType *v1=t.V(Tetra::VofF(i,1)); + VertexType *v2=t.V(Tetra::VofF(i,2)); + _ChooseColorVertex(*v0); + glVertex(p[Tetra::VofF(i,0)]); + _ChooseColorVertex(*v1); + glVertex(p[Tetra::VofF(i,1)]); + _ChooseColorVertex(*v2); + glVertex(p[Tetra::VofF(i,2)]); + } +} + + +}; + +} +#endif \ No newline at end of file