vcglib/wrap/gl/tetramesh.h

435 lines
8.6 KiB
C
Raw Normal View History

#ifndef __GLWRAPTETRA__
#define __GLWRAPTETRA__
2004-10-04 19:05:13 +02:00
#include <GL/glew.h>
#include <GL/GL.h>
#include <vcg/space/color4.h>
#include <vcg/space/Tetra3.h>
2004-10-04 19:05:13 +02:00
#include <wrap/gui/view.h>
#include <wrap/gl/space.h>
2004-10-04 19:05:13 +02:00
#include <wrap/gl/math.h>
namespace vcg {
2004-10-04 19:05:13 +02:00
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};
};
2004-05-17 17:27:16 +02:00
template <typename CONT_TETRA>
2005-06-30 12:16:11 +02:00
class GlTetramesh:public GLW{
2004-10-04 19:05:13 +02:00
public:
typedef typename CONT_TETRA::value_type TetraType;
typedef typename TetraType::VertexType VertexType;
typedef typename VertexType::ScalarType ScalarType;
typedef typename VertexType::CoordType Point3x;
2004-10-04 19:05:13 +02:00
//subclass for clipping planes
class ClipPlane
{
private:
Point3x D;
Point3x D0;
GLdouble eqn[4];
vcg::Matrix44<float> TR;
Point3x pp0;
Point3x pp1;
Point3x pp2;
Point3x pp3;
public:
2004-10-07 15:14:37 +02:00
bool active;
2004-10-04 19:05:13 +02:00
Point3x P;
2004-10-07 15:14:37 +02:00
ClipPlane (){active=false;}
2004-10-04 19:05:13 +02:00
~ClipPlane (){}
ClipPlane(Point3x p0, Point3x p1,Point3x p2)
{
Point3x N=((p1-p0)^(p2-p0)).Normalize();
N.Normalize();
D=N;
D0=D;
P=(p0+p1+p2)/3.f;
Point3x v0=N;
Point3x v1=(P-p0);
v1.Normalize();
Point3x v2=(v0^v1);
v2.Normalize();
v0=v0*2;
v1=v1*2;
v2=v2*2;
pp0=-v1-v2;
pp1=-v1+v2;
pp2=v1+v2;
pp3=v1-v2;
}
//set normal of the clipping plane
void SetD(Point3x d)
{
D=d;
}
//set the point of the clipping plane
void SetP(Point3x p)
{
P=p;
}
void GlClip()
{
2004-10-07 15:14:37 +02:00
if (active){
GLdouble d=-(D.V(0)*P.V(0)+D.V(1)*P.V(1)+D.V(2)*P.V(2));
eqn[0]=-D.V(0);
eqn[1]=-D.V(1);
eqn[2]=-D.V(2);
eqn[3]=-d;
glClipPlane(GL_CLIP_PLANE0, eqn);
glEnable(GL_CLIP_PLANE0);
}
2004-10-04 19:05:13 +02:00
}
void GlDraw()
{
glPushMatrix();
glPushAttrib(0xffffffff);
glDisable(GL_CLIP_PLANE0);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glTranslate(P);
glMultMatrix(TR);
glLineWidth(0.5);
glColor3d(0.7,0,0.7);
glBegin(GL_LINE_LOOP);
glVertex(pp0);
glVertex(pp1);
glVertex(pp2);
glVertex(pp3);
glEnd();
glPopAttrib();
glPopMatrix();
}
void Transform(vcg::Matrix44<float> Tr)
{
//thath's for casting in case of trackball using
//float to double and vice-versa
Point3f p=Point3f((float)D0.V(0),(float)D0.V(1),(float)D0.V(2));
TR=Tr;
p=TR*p;
D=Point3x((ScalarType) p.V(0),(ScalarType) p.V(1),(ScalarType) p.V(2));
}
void Translate(float L)
{
Point3x D1=D*L;
P+=D1;
}
};
2005-06-30 12:16:11 +02:00
GlTetramesh(CONT_TETRA & _t):tetra(_t){}
CONT_TETRA & tetra;
2004-10-04 19:05:13 +02:00
ClipPlane section;
private:
double shrink_factor;
2004-10-07 15:14:37 +02:00
public:
2004-10-04 19:05:13 +02:00
void SetHint(Hint h, double value){
switch(h){
case HShrinkFactor: shrink_factor = value; break;
}
}
2004-10-04 19:05:13 +02:00
void AddClipSection(Point3x p0,Point3x p1,Point3x p2)
{
section=ClipPlane(p0,p1,p2);
2004-10-07 15:14:37 +02:00
section.active=true;
}
void ClearClipSection()
{
section.active=false;
2004-10-04 19:05:13 +02:00
}
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 <DrawMode dm,NormalMode nm,ColorMode cm >
2004-08-26 15:18:32 +02:00
2004-05-17 17:27:16 +02:00
void Draw(){
2004-08-26 15:18:32 +02:00
switch (dm){
case DMNone: break;
case DMSmallTetra:_DrawSmallTetra<cm>();break;
case DMFlat:_DrawSurface<dm,nm,cm>();break;
case DMWire:_DrawSurface<dm,nm,cm>();break;
2004-08-26 15:18:32 +02:00
case DMHidden:_DrawSurface<dm,nm,cm>();break;
case DMFlatWire:_DrawFlatWire<nm,cm>(); break;
case DMTransparent:break;
}
}
2004-05-17 17:27:16 +02:00
private:
template <ColorMode cm >
void _DrawSmallTetra(){
Point3x p[4],br;
CONT_TETRA::iterator it;
2004-08-26 15:18:32 +02:00
glPushAttrib(0xffffffff);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glPolygonMode(GL_FRONT,GL_FILL);
2004-10-07 15:14:37 +02:00
if (section.active)
2004-10-04 19:05:13 +02:00
{
section.GlClip();
section.GlDraw();
}
2004-10-07 15:14:37 +02:00
/*glBegin(GL_TRIANGLES);*/
for( it = tetra.begin(); it != tetra.end(); ++it)
if((!it->IsD())&&(!(it->IsS()))) //draw as normal
{
_DrawSmallTetra<cm>(*it);
}
else
2004-10-07 15:14:37 +02:00
if((!it->IsD())&&((it->IsS())))//draw in selection mode
{
_DrawSelectedTetra(*it);
}
2004-10-07 15:14:37 +02:00
//glEnd();
2004-08-26 15:18:32 +02:00
glPopAttrib();
}
template <NormalMode nm,ColorMode cm >
void _DrawFlatWire(){
glPushAttrib(0xffff);
2004-08-26 15:18:32 +02:00
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH);
glDepthRange(0.001,1.0);
Draw<DMFlat,nm,cm>();
glDisable(GL_LIGHTING);
glColor3f(0.0,0.0,0.0);
glDepthRange(0.0,0.999);
2004-07-08 10:41:31 +02:00
Draw<DMHidden,nm,cm>();
glPopAttrib();
}
template <DrawMode dm,NormalMode nm,ColorMode cm >
void _DrawSurface(){
CONT_TETRA::iterator it;
2004-08-26 15:18:32 +02:00
glPushAttrib(0xffff);
glEnable(GL_COLOR_MATERIAL);
if((dm == DMWire)||(dm ==DMHidden))
2004-08-26 15:18:32 +02:00
{
glDisable(GL_LIGHTING);
glDisable(GL_NORMALIZE);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
2004-08-26 15:18:32 +02:00
}
else
2004-08-26 15:18:32 +02:00
{
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glPolygonMode(GL_FRONT,GL_FILL);
2004-08-26 15:18:32 +02:00
}
2004-10-07 15:14:37 +02:00
//glBegin(GL_TRIANGLES);
for( it = tetra.begin(); it != tetra.end(); ++it)
2004-08-26 15:18:32 +02:00
_DrawTetra<dm,nm,cm>((*it));
2004-10-07 15:14:37 +02:00
//glEnd();
glPopAttrib();
}
void _DrawSelectedTetra(TetraType &t)
{
glPushMatrix();
glPushAttrib(0xffff);
2004-10-07 15:14:37 +02:00
glDisable(GL_CLIP_PLANE0);
glDisable(GL_BLEND);
glDisable(GL_LIGHTING);
glDisable(GL_NORMALIZE);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glColor3d(1,0,0);
glBegin(GL_TRIANGLES);
for (int face=0;face<4;face++)
{
glVertex(t.V(Tetra::VofF(face,0))->P());
glVertex(t.V(Tetra::VofF(face,1))->P());
glVertex(t.V(Tetra::VofF(face,2))->P());
}
glEnd();
2004-10-07 15:14:37 +02:00
//end drawing
glPopAttrib();
glPopMatrix();
}
template <DrawMode dm,NormalMode nm,ColorMode cm >
void _DrawTetra(TetraType &t)
{
if((!t.IsD())&&(!t.IsS()))
2004-08-26 15:18:32 +02:00
{
2004-07-08 10:41:31 +02:00
if ((dm!=DMWire)&&(dm!=DMHidden))
_ChooseColorTetra<cm>(t);
for(int i = 0; i < 4; ++i){
if (dm == DMWire)
_DrawFace<cm>(t,i);
else
{
if (t.IsBorderF(i))
{
if(nm==NMSmooth)
2004-08-26 15:18:32 +02:00
_DrawFaceSmooth<cm>(t,i);
else
2004-08-26 15:18:32 +02:00
if(nm==NMFlat)
_DrawFace<cm>(t,i);
}
}
}
}
else
if((!t.IsD())&&(t.IsS()))
_DrawSelectedTetra(t);
}
template <ColorMode cm >
void _ChooseColorTetra(TetraType &t)
{
if (cm==CMNone)
2004-08-26 15:18:32 +02:00
{
if (t.IsS())
glColor3d(1,0,0);
else
glColor3d(0.8f,0.8f,0.8f);
}
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);
2004-08-26 15:18:32 +02:00
}
}
template <ColorMode cm >
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);
2004-08-26 15:18:32 +02:00
}
else
if(cm == CMPerVertex)
glColor3f(v.C()[0],v.C()[1],v.C()[2]);
}
}
template <ColorMode cm >
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));
2004-10-07 15:14:37 +02:00
glBegin(GL_TRIANGLES);
_ChooseColorVertex<cm>(*v0);
glNormal(v0->N());
glVertex(v0->P());
_ChooseColorVertex<cm>(*v1);
glNormal(v1->N());
glVertex(v1->P());
_ChooseColorVertex<cm>(*v2);
glNormal(v2->N());
glVertex(v2->P());
glEnd();
}
template <ColorMode cm >
void _DrawFace(TetraType &t,int face)
{
2004-10-07 15:14:37 +02:00
glBegin(GL_TRIANGLES);
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<cm>(*v0);
glVertex(v0->P());
_ChooseColorVertex<cm>(*v1);
glVertex(v1->P());
_ChooseColorVertex<cm>(*v2);
glVertex(v2->P());
2004-10-07 15:14:37 +02:00
glEnd();
}
template <ColorMode cm >
void _DrawSmallTetra(TetraType &t)
{
Tetra3<ScalarType> T=Tetra3<ScalarType>();
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();
2004-08-26 15:18:32 +02:00
for(int i = 0; i < 4; ++i)
p[i] = t.V(i)->P()* shrink_factor + br *(1- shrink_factor);
_ChooseColorTetra<cm>(t);
2004-10-07 15:14:37 +02:00
glBegin(GL_TRIANGLES);
for(int i = 0; i < 4; ++i)
{
2004-08-26 15:18:32 +02:00
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<cm>(*v0);
glVertex(p[Tetra::VofF(i,0)]);
_ChooseColorVertex<cm>(*v1);
2004-08-26 15:18:32 +02:00
glVertex(p[Tetra::VofF(i,1)]);
_ChooseColorVertex<cm>(*v2);
2004-08-26 15:18:32 +02:00
glVertex(p[Tetra::VofF(i,2)]);
}
2004-10-07 15:14:37 +02:00
glEnd();
}
};
}
#endif