minimal ply tetra importer and tetragl (immediate mode)

This commit is contained in:
T.Alderighi 2018-05-14 20:01:43 +02:00
parent fb0684974a
commit 85f3a5fad5
3 changed files with 984 additions and 1125 deletions

View File

@ -37,10 +37,10 @@ namespace tetra {
class GLW { class GLW {
public: public:
enum DrawMode {DMNone, DMSmallTetra,DMFlat,DMWire, DMHidden,DMTransparent,DMFlatWire} ; enum DrawMode {DMNone, DMSmallTetra,DMFlat,DMWire, DMHidden,DMTransparent,DMFlatWire} ;
enum NormalMode{NMFlat,NMSmooth, NMUser, NMPerMesh}; enum NormalMode{NMFlat,NMSmooth, NMUser, NMPerMesh};
enum ColorMode {CMNone, CMPerMesh,CMUser,CMPerTetraF,CMPerVertexF,CMPerVertex}; enum ColorMode {CMNone, CMPerMesh,CMUser,CMPerTetra,CMPerVertexF,CMPerVertex};
enum Hint {HShrinkFactor}; enum Hint {HShrinkFactor};
}; };
template <typename CONT_TETRA> template <typename CONT_TETRA>
@ -49,411 +49,423 @@ class GlTetramesh:public GLW{
public: public:
typedef typename CONT_TETRA::value_type TetraType; typedef typename CONT_TETRA::value_type TetraType;
typedef typename TetraType::VertexType VertexType; typedef typename TetraType::VertexType VertexType;
typedef typename VertexType::ScalarType ScalarType; typedef typename VertexType::ScalarType ScalarType;
typedef typename VertexType::CoordType Point3x; typedef typename VertexType::CoordType Point3x;
//subclass for clipping planes //subclass for clipping planes
class ClipPlane class ClipPlane
{ {
private: private:
Point3x D; Point3x D;
Point3x D0; Point3x D0;
GLdouble eqn[4]; GLdouble eqn[4];
vcg::Matrix44<float> TR; vcg::Matrix44<float> TR;
Point3x pp0; Point3x pp0;
Point3x pp1; Point3x pp1;
Point3x pp2; Point3x pp2;
Point3x pp3; Point3x pp3;
public: public:
bool active; bool active;
Point3x P; Point3x P;
ClipPlane (){active=false;} ClipPlane (){active=false;}
~ClipPlane (){} ~ClipPlane (){}
ClipPlane(Point3x p0, Point3x p1,Point3x p2) ClipPlane(Point3x p0, Point3x p1,Point3x p2)
{ {
Point3x N=((p1-p0)^(p2-p0)).Normalize(); Point3x N=((p1-p0)^(p2-p0)).Normalize();
N.Normalize(); N.Normalize();
D=N; D=N;
D0=D; D0=D;
P=(p0+p1+p2)/3.f; P=(p0+p1+p2)/3.f;
Point3x v0=N; Point3x v0=N;
Point3x v1=(P-p0); Point3x v1=(P-p0);
v1.Normalize(); v1.Normalize();
Point3x v2=(v0^v1); Point3x v2=(v0^v1);
v2.Normalize(); v2.Normalize();
v0=v0*2; v0=v0*2;
v1=v1*2; v1=v1*2;
v2=v2*2; v2=v2*2;
pp0=-v1-v2; pp0=-v1-v2;
pp1=-v1+v2; pp1=-v1+v2;
pp2=v1+v2; pp2=v1+v2;
pp3=v1-v2; pp3=v1-v2;
} }
//set normal of the clipping plane //set normal of the clipping plane
void SetD(Point3x d) void SetD(Point3x d)
{ {
D=d; D=d;
} }
//set the point of the clipping plane //set the point of the clipping plane
void SetP(Point3x p) void SetP(Point3x p)
{ {
P=p; P=p;
} }
bool IsClipped(Point3x p)
{
return D.V(0) * p.X() + D.V(1) * p.Y() + D.V(2) * p.Z() - vcg::Norm(P) < 0;
}
void GlClip() void GlClip()
{ {
if (active){ if (active){
GLdouble d=-(D.V(0)*P.V(0)+D.V(1)*P.V(1)+D.V(2)*P.V(2)); 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[0]=-D.V(0);
eqn[1]=-D.V(1); eqn[1]=-D.V(1);
eqn[2]=-D.V(2); eqn[2]=-D.V(2);
eqn[3]=-d; eqn[3]=-d;
glClipPlane(GL_CLIP_PLANE0, eqn); glClipPlane(GL_CLIP_PLANE0, eqn);
glEnable(GL_CLIP_PLANE0); glEnable(GL_CLIP_PLANE0);
} }
} }
void GlDraw() void GlDraw()
{ {
glPushMatrix(); glPushMatrix();
glPushAttrib(0xffffffff); glPushAttrib(0xffffffff);
glDisable(GL_CLIP_PLANE0); glDisable(GL_CLIP_PLANE0);
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE); glEnable(GL_NORMALIZE);
glTranslate(P); glTranslate(P);
glMultMatrix(TR); glMultMatrix(TR);
glLineWidth(0.5); glLineWidth(0.5);
glColor3d(0.7,0,0.7); glColor3d(0.7,0,0.7);
glBegin(GL_LINE_LOOP); glBegin(GL_LINE_LOOP);
glVertex(pp0); glVertex(pp0);
glVertex(pp1); glVertex(pp1);
glVertex(pp2); glVertex(pp2);
glVertex(pp3); glVertex(pp3);
glEnd(); glEnd();
glPopAttrib(); glPopAttrib();
glPopMatrix(); 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 Transform(vcg::Matrix44<float> Tr) void Translate(float L)
{ {
//thath's for casting in case of trackball using Point3x D1=D*L;
//float to double and vice-versa P+=D1;
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;
}
}; };
GlTetramesh(CONT_TETRA * _t):tetra(_t){} GlTetramesh(CONT_TETRA * _t):tetra(_t){}
GlTetramesh( ) {} GlTetramesh( ) {}
CONT_TETRA * tetra; CONT_TETRA * tetra;
ClipPlane section; ClipPlane section;
private: private:
ScalarType shrink_factor; ScalarType shrink_factor = 0.95f;
public: public:
void SetHint(Hint h, double value){ void SetHint(Hint h, double value){
switch(h){ switch(h){
case HShrinkFactor: shrink_factor = value; break; case HShrinkFactor: shrink_factor = value; break;
} }
} }
void AddClipSection(Point3x p0,Point3x p1,Point3x p2) void AddClipSection(Point3x p0,Point3x p1,Point3x p2)
{ {
section=ClipPlane(p0,p1,p2); section=ClipPlane(p0,p1,p2);
section.active=true; section.active=true;
} }
void ClearClipSection() void ClearClipSection()
{ {
section.active=false; section.active=false;
} }
typedef Color4b (*color_func_vertex)(VertexType&v); template <DrawMode dm,NormalMode nm,ColorMode cm >
color_func_vertex color_vertex; void Draw(){
switch (dm){
typedef Color4b (*color_func_tetra)(TetraType&v); case DMNone: break;
color_func_tetra color_tetra;
template <DrawMode dm,NormalMode nm,ColorMode cm >
void Draw(){
switch (dm){
case DMNone: break;
case DMSmallTetra:_DrawSmallTetra<cm>();break; case DMSmallTetra:_DrawSmallTetra<cm>();break;
case DMFlat:_DrawSurface<dm,nm,cm>();break; case DMFlat:_DrawSurface<dm,nm,cm>();break;
case DMWire:_DrawSurface<dm,nm,cm>();break; case DMWire:_DrawSurface<dm,nm,cm>();break;
case DMHidden:_DrawSurface<dm,nm,cm>();break; case DMHidden:_DrawSurface<dm,nm,cm>();break;
case DMFlatWire:_DrawFlatWire<nm,cm>(); break; case DMFlatWire:_DrawFlatWire<nm,cm>(); break;
case DMTransparent:break; case DMTransparent:break;
} }
} }
private: private:
template <ColorMode cm > template <ColorMode cm >
void _DrawSmallTetra(){ void _DrawSmallTetra(){
Point3x p[4],br; typename CONT_TETRA::iterator it;
typename CONT_TETRA::iterator it;
glPushAttrib(0xffffffff);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glPolygonMode(GL_FRONT,GL_FILL);
if (section.active)
{
section.GlClip();
section.GlDraw();
}
/*glBegin(GL_TRIANGLES);*/
for( it = tetra->begin(); it != tetra->end(); ++it)
if((!it->IsD())&&(!(it->IsS()))) //draw as normal
{
_DrawSmallTetra<cm>(*it);
}
else
if((!it->IsD())&&((it->IsS())))//draw in selection mode
{
_DrawSelectedTetra(*it);
}
//glEnd();
glPopAttrib();
}
template <NormalMode nm,ColorMode cm > // glPushAttrib(0xffff);
void _DrawFlatWire(){ // glEnable(GL_COLOR_MATERIAL);
glPushAttrib(0xffff); // glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL); // glPolygonMode(GL_FRONT, GL_FILL);
glEnable(GL_DEPTH); // glLight(GL_LIGHT0, GL_DIFFUSE, vcg::Color4b::White);
glDepthRange(0.001,1.0); // glEnable(GL_LIGHT0);
Draw<DMFlat,nm,cm>(); // glEnable(GL_LIGHTING);
glDisable(GL_LIGHTING); /*glBegin(GL_TRIANGLES);*/
glColor3f(0.0,0.0,0.0); for( it = tetra->begin(); it != tetra->end(); ++it)
glDepthRange(0.0,0.999); if((!it->IsD())&&(!(it->IsS()))) //draw as normal
Draw<DMHidden,nm,cm>(); {
glPopAttrib(); _DrawSmallTetra<cm>(*it);
} }
else
if((!it->IsD())&&((it->IsS())))//draw in selection mode
{
_DrawSelectedTetra(*it);
}
//glEnd();
// glPopAttrib();
if (section.active)
{
// section.GlClip();
section.GlDraw();
}
}
template <NormalMode nm,ColorMode cm >
void _DrawFlatWire(){
glPushAttrib(0xffff);
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);
Draw<DMHidden,nm,cm>();
glPopAttrib();
}
template <DrawMode dm,NormalMode nm,ColorMode cm > template <DrawMode dm,NormalMode nm,ColorMode cm >
void _DrawSurface(){ void _DrawSurface(){
typename CONT_TETRA::iterator it; typename CONT_TETRA::iterator it;
glPushAttrib(0xffff); glPushAttrib(0xffff);
glEnable(GL_COLOR_MATERIAL); glEnable(GL_COLOR_MATERIAL);
if((dm == DMWire)||(dm ==DMHidden)) if((dm == DMWire)||(dm ==DMHidden))
{ {
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glDisable(GL_NORMALIZE); glDisable(GL_NORMALIZE);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
} }
else else
{ {
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE); glEnable(GL_LIGHTING);
glPolygonMode(GL_FRONT,GL_FILL); glEnable(GL_NORMALIZE);
} glPolygonMode(GL_FRONT,GL_FILL);
//glBegin(GL_TRIANGLES); }
for( it = tetra->begin(); it != tetra->end(); ++it) //glBegin(GL_TRIANGLES);
_DrawTetra<dm,nm,cm>((*it)); for( it = tetra->begin(); it != tetra->end(); ++it)
//glEnd(); _DrawTetra<dm,nm,cm>((*it));
glPopAttrib(); //glEnd();
} glPopAttrib();
}
void _DrawSelectedTetra(TetraType &t) void _DrawSelectedTetra(TetraType &t)
{
glPushMatrix();
glPushAttrib(0xffff);
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();
//end drawing
glPopAttrib();
glPopMatrix();
}
template <DrawMode dm,NormalMode nm,ColorMode cm >
void _DrawTetra(TetraType &t)
{
if((!t.IsD())&&(!t.IsS()))
{
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)
_DrawFaceSmooth<cm>(t,i);
else
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)
{
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);
}
}
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);
}
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));
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)
{
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());
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();
for(int i = 0; i < 4; ++i)
p[i] = t.V(i)->P()* shrink_factor + br *(1- shrink_factor);
_ChooseColorTetra<cm>(t);
glBegin(GL_TRIANGLES);
for(int i = 0; i < 4; ++i)
{ {
glNormal(t.N(i)); glPushMatrix();
VertexType *v0=t.V(Tetra::VofF(i,0)); glPushAttrib(0xffff);
VertexType *v1=t.V(Tetra::VofF(i,1)); glDisable(GL_CLIP_PLANE0);
VertexType *v2=t.V(Tetra::VofF(i,2)); 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();
//end drawing
glPopAttrib();
glPopMatrix();
}
template <DrawMode dm,NormalMode nm,ColorMode cm >
void _DrawTetra(TetraType &t)
{
if((!t.IsD())&&(!t.IsS()))
{
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)
_DrawFaceSmooth<cm>(t,i);
else
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)
{
if (t.IsS())
glColor3d(1,0,0);
else
glColor3d(0.8f,0.8f,0.8f);
}
if (cm == CMPerTetra)
vcg::glColor(t.C());
// 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 <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);
// }
// else
if(cm == CMPerVertex)
vcg::glColor(v.C());
}
}
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));
glBegin(GL_TRIANGLES);
_ChooseColorVertex<cm>(*v0); _ChooseColorVertex<cm>(*v0);
glVertex(p[Tetra::VofF(i,0)]); glNormal(v0->N());
glVertex(v0->P());
_ChooseColorVertex<cm>(*v1); _ChooseColorVertex<cm>(*v1);
glVertex(p[Tetra::VofF(i,1)]); glNormal(v1->N());
glVertex(v1->P());
_ChooseColorVertex<cm>(*v2); _ChooseColorVertex<cm>(*v2);
glVertex(p[Tetra::VofF(i,2)]); glNormal(v2->N());
} glVertex(v2->P());
glEnd(); glEnd();
} }
template < ColorMode cm >
void _DrawFace(TetraType &t,int face)
{
glBegin(GL_TRIANGLES);
VertexType *v0=t.V(Tetra::VofF(face,0));
VertexType *v1=t.V(Tetra::VofF(face,1));
VertexType *v2=t.V(Tetra::VofF(face,2));
glNormal(vcg::Normal(v0->P(), v1->P(), v2->P()).normalized());
_ChooseColorVertex<cm>(*v0);
glVertex(v0->P());
_ChooseColorVertex<cm>(*v1);
glVertex(v1->P());
_ChooseColorVertex<cm>(*v2);
glVertex(v2->P());
glEnd();
}
template < ColorMode cm >
void _DrawSmallTetra(TetraType &t)
{
Point3x p[4], br;
br = Tetra::Barycenter(t);
if (section.IsClipped(br))
return;
bool border = false;
bool clipBorder = false;
for (int i = 0; i < 4; ++i)
{
border = border || t.IsB(i);
Point3x br1 = Tetra::Barycenter(*t.TTp(i));
clipBorder = clipBorder || section.IsClipped(br1);
}
if (!border && !clipBorder)
return;
for(int i = 0; i < 4; ++i)
p[i] = t.V(i)->P() * shrink_factor + br * (1 - shrink_factor);
_ChooseColorTetra<cm>(t);
glBegin(GL_TRIANGLES);
for(int i = 0; i < 4; ++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));
glNormal(vcg::Normal(v0->P(), v1->P(), v2->P()).normalized());
_ChooseColorVertex<cm>(*v0);
glVertex(p[Tetra::VofF(i,0)]);
_ChooseColorVertex<cm>(*v1);
glVertex(p[Tetra::VofF(i,1)]);
_ChooseColorVertex<cm>(*v2);
glVertex(p[Tetra::VofF(i,2)]);
}
glEnd();
}
}; };
} // end namespace tetra } // end namespace tetra

View File

@ -354,7 +354,7 @@ public:
fprintf(fpout,"%d ",vp->Flags()); fprintf(fpout,"%d ",vp->Flags());
if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) ) if( HasPerVertexColor(m) && (pi.mask & Mask::IOM_VERTCOLOR) )
fprintf(fpout,"%d %d %d %d ",vp->C()[0],vp->C()[1],vp->C()[2],vp->C()[3] ); fprintf(fpout,"%d %d %d %d ",vp->C()[0], vp->C()[1], vp->C()[2], vp->C()[3] );
if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) ) if( HasPerVertexQuality(m) && (pi.mask & Mask::IOM_VERTQUALITY) )
fprintf(fpout,"%g ",vp->Q()); fprintf(fpout,"%g ",vp->Q());

File diff suppressed because it is too large Load Diff