Initial Release
This commit is contained in:
parent
782b814293
commit
24d13d59e6
|
@ -0,0 +1,363 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <GL/glew.h>
|
||||
#include <GL/glut.h>
|
||||
#include <wrap/gl/space.h>
|
||||
|
||||
|
||||
#include <wrap/callback.h>
|
||||
#include <wrap/gui/trackball.h>
|
||||
#include <vcg/simplex/vertex/with/vcvn.h>
|
||||
#include <vcg/simplex/vertex/with/vcvn.h>
|
||||
#include <vcg/simplex/face/with/fcfn.h>
|
||||
#include <vcg/space/index/grid_static_ptr.h>
|
||||
#include <vcg/complex/trimesh/base.h>
|
||||
#include<wrap/io_trimesh/export_ply.h>
|
||||
#include<wrap/io_trimesh/import_ply.h>
|
||||
#include<vcg/complex/trimesh/update/normal.h>
|
||||
#include<vcg/complex/trimesh/update/bounding.h>
|
||||
|
||||
#include "visshader.h"
|
||||
using namespace vcg;
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
|
||||
// Vertex, Face, Mesh and Grid definitions.
|
||||
class MyEdge;
|
||||
class AFace;
|
||||
class AVertex : public VertexVCVN< float ,MyEdge,AFace > {};
|
||||
class AFace : public FaceFCFN< AVertex,MyEdge,AFace > {};
|
||||
class AMesh : public tri::TriMesh< vector<AVertex>, vector<AFace> > {};
|
||||
|
||||
///////// Global ////////
|
||||
|
||||
int SampleNum=32;
|
||||
int WindowRes=800;
|
||||
|
||||
bool SwapFlag=false;
|
||||
|
||||
float lopass=0,hipass=1,gamma=1;
|
||||
bool LightFlag=true;
|
||||
bool ColorFlag=true;
|
||||
|
||||
Trackball Q;
|
||||
|
||||
int ScreenH,ScreenW;
|
||||
float ViewAngle=45;
|
||||
|
||||
class TimeOracle
|
||||
{
|
||||
public:
|
||||
time_t start;
|
||||
time_t cur;
|
||||
|
||||
char buf[128];
|
||||
|
||||
char const *TimeToEndStr(double perc)
|
||||
{
|
||||
time(&cur);
|
||||
double diff=difftime(cur,start);
|
||||
diff= diff/perc - diff;
|
||||
|
||||
int hh=diff/3600;
|
||||
int mm=(diff-hh*3600)/60;
|
||||
int ss=diff-hh*3600-mm*60;
|
||||
sprintf(buf,"%02i:%02i:%02i",hh,mm,ss);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void Start(){time(&start);};
|
||||
};
|
||||
|
||||
bool cb(const char *buf)
|
||||
{
|
||||
printf(buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
// prototypes
|
||||
void SaveTexturedGround();
|
||||
|
||||
void Draw(AMesh &mm)
|
||||
{
|
||||
AMesh::FaceIterator fi;
|
||||
glBegin(GL_TRIANGLES);
|
||||
for(fi=mm.face.begin();fi!=mm.face.end();++fi)
|
||||
{
|
||||
|
||||
glNormal((*fi).V(0)->N()); glColor((*fi).V(0)->C()); glVertex((*fi).V(0)->P());
|
||||
glNormal((*fi).V(1)->N()); glColor((*fi).V(1)->C()); glVertex((*fi).V(1)->P());
|
||||
glNormal((*fi).V(2)->N()); glColor((*fi).V(2)->C()); glVertex((*fi).V(2)->P());
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
AMesh m;
|
||||
VertexVisShader<AMesh> Vis(m);
|
||||
|
||||
string OutNameMsh;
|
||||
|
||||
|
||||
/* Called when the window is first opened and whenever
|
||||
* the window is reconfigured (moved or resized).
|
||||
*/
|
||||
void ViewReshape(GLsizei w, GLsizei h)
|
||||
{
|
||||
ScreenW=w; ScreenH=h;
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
gluPerspective(ViewAngle,(float)w/(float)h,.1,10000);
|
||||
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
|
||||
}
|
||||
|
||||
void ViewDisplay (void)
|
||||
{
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
gluPerspective(ViewAngle,1,.1,10);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glLoadIdentity ();
|
||||
glTranslatef(0,0,-4);
|
||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
Q.GetView();
|
||||
Q.Apply();
|
||||
Q.Draw();
|
||||
float d = 2.0/m.bbox.Diag();
|
||||
glScalef(d, d, d);
|
||||
glTranslate(-m.bbox.Center());
|
||||
if(LightFlag) glEnable(GL_LIGHTING);
|
||||
else glDisable(GL_LIGHTING);
|
||||
if(ColorFlag) glEnable(GL_COLOR_MATERIAL);
|
||||
else glDisable(GL_COLOR_MATERIAL);
|
||||
Draw(m);
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
void ViewSpecialKey(int , int , int )
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
void Toggle(bool &flag) {flag = !flag;}
|
||||
/*********************************************************************/
|
||||
/*********************************************************************/
|
||||
/*********************************************************************/
|
||||
void ViewKey(unsigned char key, int , int )
|
||||
{
|
||||
Point3f dir;
|
||||
switch (key) {
|
||||
case 27: exit(0); break;
|
||||
case 'l' :
|
||||
lopass=lopass+.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma);
|
||||
Vis.MapVisibility(gamma,lopass,hipass);
|
||||
break;
|
||||
case 'L' :
|
||||
lopass=lopass-.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma);
|
||||
Vis.MapVisibility(gamma,lopass,hipass);
|
||||
break;
|
||||
case 'h' :
|
||||
hipass=hipass-.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma);
|
||||
Vis.MapVisibility(gamma,lopass,hipass);
|
||||
break;
|
||||
case 'H' :
|
||||
hipass=hipass+.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma);
|
||||
Vis.MapVisibility(gamma,lopass,hipass);
|
||||
break;
|
||||
case 'g' :
|
||||
gamma=gamma-.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma);
|
||||
Vis.MapVisibility(gamma,lopass,hipass);
|
||||
break;
|
||||
case 'G' :
|
||||
gamma=gamma+.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma);
|
||||
Vis.MapVisibility(gamma,lopass,hipass);
|
||||
break;
|
||||
case 'c' :
|
||||
Vis.ComputeUniform(SampleNum,cb);
|
||||
Vis.MapVisibility(gamma,lopass,hipass);
|
||||
break;
|
||||
case ' ' : {
|
||||
Point3f dir = Q.camera.ViewPoint();
|
||||
printf("ViewPoint %f %f %f\n",dir[0],dir[1],dir[2]);
|
||||
dir.Normalize();
|
||||
dir=Inverse(Q.track.Matrix())*dir;
|
||||
printf("ViewPoint %f %f %f\n",dir[0],dir[1],dir[2]);
|
||||
dir.Normalize();
|
||||
Vis.ComputeSingle(dir,cb);
|
||||
Vis.MapVisibility(gamma,lopass,hipass); }
|
||||
break;
|
||||
case 's' :
|
||||
Vis.SmoothVisibility();
|
||||
Vis.MapVisibility(gamma,lopass,hipass);
|
||||
break;
|
||||
case 'S' :
|
||||
{
|
||||
vcg::tri::io::PlyInfo p;
|
||||
p.mask|=vcg::ply::PLYMask::PM_VERTCOLOR /* | vcg::ply::PLYMask::PM_VERTQUALITY*/ ;
|
||||
tri::io::ExporterPLY<AMesh>::Save(m,OutNameMsh.c_str(),false,p);
|
||||
}
|
||||
break;
|
||||
case 'a' : LightFlag = !LightFlag; printf("Toggled Light\n"); break;
|
||||
case 'A' : ColorFlag = !ColorFlag; printf("Toggled Color\n"); break;
|
||||
}
|
||||
glutPostRedisplay(); ;
|
||||
}
|
||||
void ViewMenu(int val)
|
||||
{
|
||||
ViewKey(val, 0, 0);
|
||||
}
|
||||
/*********************************************************************/
|
||||
// TrackBall Functions
|
||||
/*********************************************************************/
|
||||
|
||||
int PressedButton; // What is the button actually pressed?
|
||||
int KeyMod;
|
||||
int GW,GH; // Grandezza della finestra
|
||||
int B[3]={0,0,0}; // Variabile globale che tiene lo stato dei tre bottoni;
|
||||
|
||||
|
||||
void ViewMouse(int button, int state, int x, int y)
|
||||
{
|
||||
static int glut_buttons=0;
|
||||
|
||||
int m_mask = 0;
|
||||
KeyMod=glutGetModifiers();
|
||||
if(GLUT_ACTIVE_SHIFT & KeyMod) m_mask |= Trackball::KEY_SHIFT;
|
||||
if(GLUT_ACTIVE_ALT & KeyMod) m_mask |= Trackball::KEY_ALT;
|
||||
if(GLUT_ACTIVE_CTRL & KeyMod) m_mask |= Trackball::KEY_CTRL;
|
||||
|
||||
if(state == GLUT_DOWN) {
|
||||
glut_buttons |= (1<<button);
|
||||
Q.MouseDown(x, ScreenH-y, glut_buttons | m_mask);
|
||||
} else {
|
||||
//glut_buttons &= ~(1<<button);
|
||||
glut_buttons = 0;
|
||||
m_mask = 0;
|
||||
Q.MouseUp(x, ScreenH-y, glut_buttons);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewMouseMotion(int x, int y)
|
||||
{
|
||||
Q.MouseMove(x,ScreenH-y);
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void SetLight()
|
||||
{
|
||||
GLfloat light_ambient0[] = {0.0, 0.0, 0.0, 1.0};
|
||||
GLfloat light_diffuse0[] = {1.0, 1.0, 1.0, 1.0};
|
||||
GLfloat light_position0[] = {0.0, 10.0, 300.0, 0.0};
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient0);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0);
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
|
||||
glEnable(GL_LIGHT0);
|
||||
}
|
||||
|
||||
void ViewInit (void) {
|
||||
SetLight();
|
||||
Q.Reset();
|
||||
Q.radius= 1;
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glClearColor (0.8, 0.8, 0.8, 0.0);
|
||||
glEnable(GL_NORMALIZE);
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
// glEnable(GL_BLEND);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
// glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glColorMaterial(GL_FRONT,GL_DIFFUSE);
|
||||
//glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
|
||||
//glColorMaterial(GL_FRONT,GL_AMBIENT);
|
||||
glMateriali(GL_FRONT,GL_SHININESS,0);
|
||||
float spec[4]={0,0,0,1};
|
||||
glMaterialfv(GL_FRONT,GL_SPECULAR,spec);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if(argc<2) {
|
||||
printf(
|
||||
"shadevis 1.0 \n"__DATE__"\n"
|
||||
"Copyright 2003-2004 Visual Computing Lab I.S.T.I. C.N.R.\n"
|
||||
"Paolo Cignoni (cignoni@isti.cnr.it)\n\n"
|
||||
"Usage: shadevis file.ply [options]\n"
|
||||
"Options:\n"
|
||||
" -w# WindowResolution (default 600)\n"
|
||||
" -n# Sample Directions (default 32)\n"
|
||||
" -z# z offset (default 1e-4)\n"
|
||||
" -da # Cone Direction Angle in degree (default 45)\n"
|
||||
" -dv # # # Cone Direction vector (default 0 0 1)\n"
|
||||
" -c Set IsClosed Flag\n"
|
||||
" -f Flip normal of the model\n"
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int i=1;
|
||||
while(i<argc && (argv[i][0]=='-'))
|
||||
{
|
||||
switch(argv[i][1])
|
||||
{
|
||||
case 'n' : SampleNum = atoi(argv[i]+2); break;
|
||||
case 'f' : SwapFlag=false; break;
|
||||
case 'w' : WindowRes= atoi(argv[i]+2); printf("Set WindowRes to %i\n",WindowRes ); break;
|
||||
case 's' : Vis.SplitNum= atoi(argv[i]+2); printf("Set SplitNum to %i\n",Vis.SplitNum ); break;
|
||||
case 'z' : Vis.ZTWIST = atof(argv[i]+2); printf("Set ZTWIST to %f\n",Vis.ZTWIST ); break;
|
||||
default: {printf("Error unable to parse option '%s'\n",argv[i]); exit(0);}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
string basename = argv[i];
|
||||
if(!(basename.substr(basename.length()-4)==".ply")) {
|
||||
printf("Error: Unknown file extension %s\n",basename.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// loading original mesh
|
||||
int ret=tri::io::ImporterPLY<AMesh>::Open(m,argv[i]);
|
||||
if(ret) {printf("Error unable to open mesh %s\n",argv[i]);exit(-1);}
|
||||
tri::UpdateNormals<AMesh>::PerVertexNormalized(m);
|
||||
tri::UpdateBounding<AMesh>::Box(m);
|
||||
|
||||
printf("Mesh bbox (%f %f %f)-(%f %f %f)\n\n",m.bbox.min[0],m.bbox.min[1],m.bbox.min[2],m.bbox.max[0],m.bbox.max[1],m.bbox.max[2]);
|
||||
OutNameMsh=(string(argv[i]).substr(0,strlen(argv[i])-4));
|
||||
OutNameMsh+="_vis.ply";
|
||||
|
||||
printf("Mesh Output filename %s\n",OutNameMsh.c_str());
|
||||
|
||||
printf("Mesh %iv %if bbox Diag %g\n",m.vn,m.fn,m.bbox.Diag());
|
||||
|
||||
glutInit(&argc, argv);
|
||||
|
||||
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
|
||||
glutInitWindowSize(WindowRes, WindowRes);
|
||||
glutInitWindowPosition (10,10);
|
||||
glutCreateWindow ("shadevis - Visual Computing Lab - vcg.isti.cnr.it ");
|
||||
glutDisplayFunc(ViewDisplay);
|
||||
glutReshapeFunc(ViewReshape);
|
||||
glutKeyboardFunc(ViewKey);
|
||||
glutSpecialFunc(ViewSpecialKey);
|
||||
glutMouseFunc(ViewMouse);
|
||||
glutMotionFunc(ViewMouseMotion);
|
||||
|
||||
ViewInit();
|
||||
glewInit();
|
||||
glutMainLoop();
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*#***************************************************************************
|
||||
* Visibility.h o o *
|
||||
* o o *
|
||||
* Visual Computing Group _ O _ *
|
||||
* IEI Institute, CNUCE Institute, CNR Pisa \/)\/ *
|
||||
* /\/| *
|
||||
* Copyright(C) 1999 by Paolo Cignoni, Paolo Pingi, Claudio Rocchini | *
|
||||
* All rights reserved. \ *
|
||||
* *
|
||||
* Permission to use, copy, modify, distribute and sell this software and *
|
||||
* its documentation for any purpose is hereby granted without fee, provided *
|
||||
* that the above copyright notice appear in all copies and that both that *
|
||||
* copyright notice and this permission notice appear in supporting *
|
||||
* documentation. the author makes no representations about the suitability *
|
||||
* of this software for any purpose. It is provided "as is" without express *
|
||||
* or implied warranty. *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
/*#**************************************************************************
|
||||
History
|
||||
|
||||
2003 Aug 26 First Working version
|
||||
|
||||
****************************************************************************/
|
||||
#ifndef __VCG_SIMPLE_PIC
|
||||
#define __VCG_SIMPLE_PIC
|
||||
#include <vcg/math/matrix44.h>
|
||||
|
||||
namespace vcg {
|
||||
template <class PixType>
|
||||
class SimplePic
|
||||
{public:
|
||||
std::vector<PixType> img;
|
||||
int sx,sy;
|
||||
void Create(int tx,int ty)
|
||||
{
|
||||
sx=tx;sy=ty;
|
||||
img.resize(sx*sy);
|
||||
}
|
||||
PixType &Pix(int x, int y) {return img[sx*y+x];}
|
||||
|
||||
void OpenGLSnap(GLenum format=0)
|
||||
{
|
||||
int vp[4];
|
||||
glGetIntegerv( GL_VIEWPORT,vp ); // Lettura viewport
|
||||
glPixelStorei( GL_PACK_ROW_LENGTH, 0);
|
||||
glPixelStorei( GL_PACK_ALIGNMENT, 1);
|
||||
int tx = vp[2];
|
||||
int ty = vp[3];
|
||||
|
||||
Create(tx,ty);
|
||||
|
||||
GLenum mtype = 0;
|
||||
|
||||
if(format==0) {
|
||||
format = GL_RGBA;
|
||||
mtype = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
if(format==GL_DEPTH_COMPONENT) {
|
||||
format = GL_DEPTH_COMPONENT;
|
||||
mtype = GL_FLOAT;
|
||||
}
|
||||
glReadPixels(vp[0],vp[1],vp[2],vp[3],format,mtype,(GLvoid *)&img[0]);
|
||||
}
|
||||
bool SavePPM( const char * filename )
|
||||
{
|
||||
FILE * fp = fopen(filename,"wb");
|
||||
if(fp==0) return false;
|
||||
|
||||
|
||||
fprintf(fp,"P6\n%d %d\n255\n",sx,sy);
|
||||
|
||||
for(int i=0;i<sx*sy;++i)
|
||||
{
|
||||
fwrite(&(img[i]),3,1,fp);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif // __VCG_MESH_VISIBILITY
|
|
@ -0,0 +1,516 @@
|
|||
/*#***************************************************************************
|
||||
* Visibility.h o o *
|
||||
* o o *
|
||||
* Visual Computing Group _ O _ *
|
||||
* IEI Institute, CNUCE Institute, CNR Pisa \/)\/ *
|
||||
* /\/| *
|
||||
* Copyright(C) 1999 by Paolo Cignoni, Paolo Pingi, Claudio Rocchini | *
|
||||
* All rights reserved. \ *
|
||||
* *
|
||||
* Permission to use, copy, modify, distribute and sell this software and *
|
||||
* its documentation for any purpose is hereby granted without fee, provided *
|
||||
* that the above copyright notice appear in all copies and that both that *
|
||||
* copyright notice and this permission notice appear in supporting *
|
||||
* documentation. the author makes no representations about the suitability *
|
||||
* of this software for any purpose. It is provided "as is" without express *
|
||||
* or implied warranty. *
|
||||
* *
|
||||
*****************************************************************************/
|
||||
/*#**************************************************************************
|
||||
History
|
||||
|
||||
2003 Aug 26 First Working version
|
||||
|
||||
****************************************************************************/
|
||||
#ifndef __VCG_MESH_VISIBILITY
|
||||
#define __VCG_MESH_VISIBILITY
|
||||
#include <bitset>
|
||||
#include <vcg/math/matrix44.h>
|
||||
#include "simplepic.h"
|
||||
namespace vcg {
|
||||
|
||||
template <class ScalarType>
|
||||
void GenNormal(int vn, std::vector<Point3<ScalarType > > &NN)
|
||||
{
|
||||
typedef Point3<ScalarType> Point3x;
|
||||
NN.clear();
|
||||
while(NN.size()<vn)
|
||||
{
|
||||
Point3x pp(float(rand())/RAND_MAX,float(rand())/RAND_MAX,float(rand())/RAND_MAX);
|
||||
pp=pp*2.0-Point3x(1,1,1);
|
||||
if(pp.SquaredNorm()<1)
|
||||
{
|
||||
Normalize(pp);
|
||||
NN.push_back(pp);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Base Class che definisce le varie interfaccie;
|
||||
template <class MESH_TYPE, int MAXVIS=2048> class VisShader
|
||||
{
|
||||
public :
|
||||
enum {VisMax=MAXVIS};
|
||||
VisShader(MESH_TYPE &me):m(me)
|
||||
{
|
||||
CullFlag= false;
|
||||
IsClosed = false;
|
||||
ZTWIST=1e-3;
|
||||
SplitNum=1;
|
||||
|
||||
CameraViewing=false;
|
||||
}
|
||||
|
||||
typedef Point3<typename MESH_TYPE::ScalarType> Point3x;
|
||||
|
||||
typedef typename MESH_TYPE::CoordType CoordType;
|
||||
typedef typename MESH_TYPE::ScalarType ScalarType;
|
||||
typedef typename MESH_TYPE::VertexType VertexType;
|
||||
typedef typename MESH_TYPE::VertexPointer VertexPointer;
|
||||
typedef typename MESH_TYPE::VertexIterator VertexIterator;
|
||||
typedef typename MESH_TYPE::FaceIterator FaceIterator;
|
||||
typedef typename MESH_TYPE::FaceType FaceType;
|
||||
typedef Matrix44<ScalarType> Matrix44x;
|
||||
typedef Box3<ScalarType> Box3x;
|
||||
|
||||
// The Basic Data the mesh and its wrapper;
|
||||
MESH_TYPE &m;
|
||||
|
||||
std::vector<MESH_TYPE *> OMV; // Occluder Mesh Vector;
|
||||
|
||||
// la visibilita' e' in float, per ogni entita'
|
||||
// 1 significa che e' totalmente visibile per una data direzione.
|
||||
|
||||
std::vector<float> VV;
|
||||
std::vector< Point3x > VN; // Vettore delle normali che ho usato per calcolare la mask e i float in W;
|
||||
|
||||
// User defined parameters and flags
|
||||
bool IsClosed;
|
||||
float ZTWIST;
|
||||
bool CullFlag; // Enable the frustum culling. Useful when the splitting value is larger than 2
|
||||
int SplitNum;
|
||||
protected:
|
||||
bool CameraViewing;
|
||||
//Camera<ScalarType> Cam;
|
||||
public:
|
||||
|
||||
/********************************************************/
|
||||
// Generic functions with Specialized code for every subclass
|
||||
virtual void MapVisibility(float Gamma=1, float LowPass=0, float HighPass=1,bool FalseColor=false)=0;
|
||||
//virtual void ApplyLightingEnvironment(std::vector<float> &W, float Gamma);
|
||||
|
||||
virtual int GLAccumPixel( std::vector<int> &PixSeen)=0;
|
||||
|
||||
virtual bool ReadVisibility(const char * /*filename*/){assert( 0); return false;}
|
||||
virtual bool WriteVisibility(const char * /*filename*/){assert( 0); return false;}
|
||||
|
||||
/********************************************************/
|
||||
// Generic functions with same code for every subclass
|
||||
|
||||
void Clear() { fill(VV.begin(),VV.end(),0); }
|
||||
|
||||
void InitGL()
|
||||
{
|
||||
glPushAttrib(GL_COLOR_BUFFER_BIT );
|
||||
::glClearColor (1.0, 1.0, 1.0, 0.0);
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
}
|
||||
|
||||
void RestoreGL()
|
||||
{
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Funzione principale di conversione in visibilita'
|
||||
Dati i due vettori PixSeen e PixNotSeen che indicano per ogni entita' (vertice o faccia)
|
||||
quanti sono, rispettivamente, i pixel visibili e occlusi,
|
||||
questa funzione calcola un valore float per ogni entita' che indica quanto e' visibile lungo una data direzione camera
|
||||
== 1 significa completamente visibile
|
||||
== 0 significa completamente occluso.
|
||||
|
||||
*/
|
||||
void AddPixelCount(std::vector<float> &_VV, const std::vector<int> &PixSeen)
|
||||
{
|
||||
assert(_VV.size()==PixSeen.size());
|
||||
for(int i=0;i<PixSeen.size();++i)
|
||||
if(PixSeen[i]>0) _VV[i]+= 1;
|
||||
}
|
||||
|
||||
|
||||
//void SetVisibilityMask(std::vector< std::bitset<MAXVIS> > &_VM, const std::vector<int> &PixSeen, const int dir)
|
||||
// {
|
||||
// assert(_VM.size()==PixSeen.size());
|
||||
// for(int i=0;i<PixSeen.size();++i)
|
||||
// if(PixSeen[i]>0) _VM[i][dir]=true;
|
||||
// }
|
||||
|
||||
/*******************************
|
||||
Funzioni ad alto livello che computano le Visibility Mask per varie distribuzioni di direzioni
|
||||
|
||||
|
||||
*******************************/
|
||||
|
||||
// Funzione Generica chiamata da tutte le seguenti
|
||||
void Compute( CallBack *cb)
|
||||
{
|
||||
//cb(buf.format("Start to compute %i dir\n",VN.size()));
|
||||
InitGL();
|
||||
VV.resize(m.vert.size());
|
||||
vector<int> PixSeen(VV.size(),0);
|
||||
|
||||
for(int i=0;i<VN.size();++i)
|
||||
{
|
||||
int t0=clock();
|
||||
fill(PixSeen.begin(),PixSeen.end(),0);
|
||||
int added=SplittedRendering(VN[i], PixSeen,cb);
|
||||
AddPixelCount(VV,PixSeen);
|
||||
int t1=clock();
|
||||
printf("ComputeSingleDir %i on %i : %i msec\n",i,VN.size(),t1-t0);
|
||||
}
|
||||
|
||||
RestoreGL();
|
||||
}
|
||||
|
||||
void ComputeCone(int nn, Point3x &dir, ScalarType ConeAngleDeg, CallBack *cb)
|
||||
{
|
||||
string buf;
|
||||
ScalarType ConeAngleRad=ToRad(ConeAngleDeg);
|
||||
ScalarType SolidAngleSter = (1.0 - Cos(ConeAngleRad))*2*M_PI;
|
||||
int Frac=(4.0*M_PI)/SolidAngleSter;
|
||||
printf("ComputeCone for an angle of %f , solidAngle =%f pi asked %i normals, forecasted we need to ask %i normals\n",
|
||||
ConeAngleDeg,SolidAngleSter/M_PI,nn,nn*Frac);
|
||||
|
||||
VN.clear();
|
||||
vector<Point3x> nvt;
|
||||
GenNormal(nn*Frac,nvt);
|
||||
ScalarType CosConeAngle=Cos(ConeAngleRad);
|
||||
for(int i=0;i<nvt.size();++i)
|
||||
if(dir*nvt[i]>=CosConeAngle) VN.push_back(nvt[i]);
|
||||
|
||||
printf("Asked %i normal, got %i normals\n",nn,VN.size());
|
||||
Compute(cb);
|
||||
}
|
||||
|
||||
void ComputeHalf(int nn, Point3x &dir, CallBack *cb)
|
||||
{
|
||||
string buf;
|
||||
|
||||
VN.clear();
|
||||
vector<Point3x> nvt;
|
||||
GenNormal(nn*2,nvt);
|
||||
for(int i=0;i<nvt.size();++i)
|
||||
if(dir*nvt[i]>0) VN.push_back(nvt[i]);
|
||||
|
||||
printf("Asked %i normal, got %i normals\n",nn,VN.size());
|
||||
Compute(cb);
|
||||
}
|
||||
|
||||
void ComputeUniform(int nn, CallBack *cb)
|
||||
{
|
||||
VN.clear();
|
||||
GenNormal(nn,VN);
|
||||
char buf[256];
|
||||
sprintf(buf,"Asked %i normal, got %i normals\n",nn,VN.size());
|
||||
cb(buf);
|
||||
Compute(cb);
|
||||
}
|
||||
|
||||
void ComputeSingle(Point3x &dir, CallBack *cb)
|
||||
{
|
||||
VN.clear();
|
||||
VN.push_back(dir);
|
||||
printf("Computing one direction (%f %f %f)\n",dir[0],dir[1],dir[2]);
|
||||
Compute(cb);
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
|
||||
int SplittedRendering(Point3x &ViewDir, std::vector<int> &PixSeen, CallBack *cb=DummyCallBack)
|
||||
{
|
||||
int tt=0;
|
||||
int i,j;
|
||||
for(i=0;i<SplitNum;++i)
|
||||
for(j=0;j<SplitNum;++j){
|
||||
SetupOrthoViewMatrix(ViewDir, i,j,SplitNum);
|
||||
tt+=GLAccumPixel(PixSeen);
|
||||
}
|
||||
return tt;
|
||||
}
|
||||
|
||||
// Compute a rotation matrix that bring Axis parallel to Z.
|
||||
void GenMatrix(Matrix44d &a, Point3d Axis, double angle)
|
||||
{
|
||||
const double eps=1e-5;
|
||||
Point3d RotAx = Axis ^ Point3d(0,0,1);
|
||||
double RotAngle = Angle(Axis,Point3d(0,0,1));
|
||||
|
||||
if(math::Abs(RotAx.Norm())<eps) { // in questo caso Axis e' collineare con l'asse z
|
||||
RotAx=Point3d(0,1,0);
|
||||
double RotAngle = Angle(Axis,Point3d(0,1,0));
|
||||
}
|
||||
//printf("Rotating around (%5.3f %5.3f %5.3f) %5.3f\n",RotAx[0],RotAx[1],RotAx[2],RotAngle);
|
||||
a.SetRotate(-RotAngle,RotAx);
|
||||
//Matrix44d rr;
|
||||
//rr.SetRotate(-angle, Point3d(0,0,1));
|
||||
//a=rr*a;
|
||||
}
|
||||
|
||||
|
||||
// Genera la matrice di proj e model nel caso di un rendering ortogonale.
|
||||
// subx e suby indicano la sottoparte che si vuole
|
||||
void SetupOrthoViewMatrix(Point3x &ViewDir, int subx, int suby,int LocSplit)
|
||||
{
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
float dlt=2.0f/LocSplit;
|
||||
|
||||
glOrtho(-1+subx*dlt, -1+(subx+1)*dlt, -1+suby*dlt, -1+(suby+1)*dlt,-2,2);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glLoadIdentity ();
|
||||
Matrix44d rot;
|
||||
Point3d qq; qq.Import(ViewDir);
|
||||
GenMatrix(rot,qq,0);
|
||||
glMultMatrixd((const double *)&rot);
|
||||
double d=2.0/m.bbox.Diag();
|
||||
glScalef(d,d,d);
|
||||
glTranslate(-m.bbox.Center());
|
||||
}
|
||||
|
||||
void ComputeSingleDirection(Point3x BaseDir, std::vector<int> &PixSeen, CallBack *cb=DummyCallBack)
|
||||
{
|
||||
int t0=clock();
|
||||
string buf;
|
||||
|
||||
int added=SplittedRendering(BaseDir, PixSeen,cb);
|
||||
int t1=clock();
|
||||
printf("ComputeSingleDir %i msec\n",t1-t0);
|
||||
}
|
||||
|
||||
void ComputeAverageVisibilityDirection()
|
||||
{
|
||||
int i,j;
|
||||
VD.resize(VM.size());
|
||||
for(j=0;j<VM.size();++j)
|
||||
{
|
||||
Point3x &nn=VD[j];
|
||||
nn=Point3x(0,0,0);
|
||||
bitset<VisMax> &msk=VM[j];
|
||||
for(i=0;i<VN.size();++i)
|
||||
if(msk[i]) nn+=VN[i];
|
||||
}
|
||||
for(j=0;j<VM.size();++j)
|
||||
VD[j].Normalize();
|
||||
|
||||
}
|
||||
|
||||
// calcola un LightingEnvironment direzionale, cioe'un vettore di pesi per l'insieme di normali
|
||||
// corrente tale che
|
||||
// mette a 1 tutti i vettori che sono entro un angolo DegAngle1
|
||||
// a 0 tutti quelli oltre DegAngle2 e
|
||||
// sfuma linearmente nel mezzo.
|
||||
void DirectionalLightingEnvironment(std::vector<float> &LE, Point3x dir, ScalarType DegAngle1, ScalarType DegAngle2)
|
||||
{
|
||||
LE.clear();
|
||||
LE.resize(VN.size(),0);
|
||||
int i;
|
||||
for(i=0;i<VN.size();++i)
|
||||
{
|
||||
ScalarType a=ToDeg(Angle(dir,VN[i]));
|
||||
if(a<DegAngle1) { LE[i]=1; continue; }
|
||||
if(a>DegAngle2) { LE[i]=0; continue; }
|
||||
LE[i] = 1.0-(a-DegAngle1)/(DegAngle2-DegAngle1);
|
||||
|
||||
}
|
||||
// last step normalize the weights;
|
||||
ScalarType sum=0;
|
||||
for(i=0;i<VN.size();++i)
|
||||
sum+=LE[i];
|
||||
for(i=0;i<VN.size();++i)
|
||||
LE[i]/=sum;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
|
||||
template <class MESH_TYPE> class VertexVisShader : public VisShader<MESH_TYPE>
|
||||
{
|
||||
public :
|
||||
|
||||
// Function Members
|
||||
VertexVisShader(MESH_TYPE &me):VisShader<MESH_TYPE>(me)
|
||||
{
|
||||
// la mesh DEVE avere colore per vertice
|
||||
if(! m.HasPerVertexColor()) assert(0);
|
||||
}
|
||||
|
||||
void Init() { VV.resize(m.vert.size()); AssignColorId(); }
|
||||
// Vis::VisMode Id() {return Vis::VMPerVert;};
|
||||
void Compute(int nn);
|
||||
|
||||
void AddPixelCount(std::vector<float> &_VV, std::vector<int> &PixSeen, std::vector<int> &PixNotSeen )
|
||||
{
|
||||
for(int i=0;i<m.vert.size();++i)
|
||||
_VV[i]+= float(PixSeen[i])/float(PixSeen[i]-PixNotSeen[i]);
|
||||
}
|
||||
|
||||
void DrawFill(MESH_TYPE &mm)
|
||||
{
|
||||
glBegin(GL_TRIANGLES);
|
||||
MESH_TYPE::FaceIterator fi;
|
||||
for(fi=mm.face.begin();fi!=mm.face.end();++fi)
|
||||
{
|
||||
glVertex((*fi).V(0)->P());
|
||||
glVertex((*fi).V(1)->P());
|
||||
glVertex((*fi).V(2)->P());
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
//VertexVisibility
|
||||
// Funzione Principale restituisce per ogni entita' quanti px si vedono o no.
|
||||
int GLAccumPixel( std::vector<int> &PixSeen)
|
||||
{
|
||||
SimplePic<float> snapZ;
|
||||
SimplePic<Color4b> snapC;
|
||||
|
||||
glClearColor(Color4b::White);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT );
|
||||
glDisable(GL_LIGHTING);
|
||||
glDepthRange(0.0f,1.0f);
|
||||
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
||||
glDepthMask(GL_TRUE);
|
||||
glDrawBuffer(GL_BACK);
|
||||
glReadBuffer(GL_BACK);
|
||||
|
||||
/////** Si disegnano le front face **/////
|
||||
glDepthRange(2.0*ZTWIST,1.0f);
|
||||
// glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK);
|
||||
glColor(Color4b::Red);
|
||||
DrawFill(m);
|
||||
snapC.OpenGLSnap();
|
||||
|
||||
// if(!IsClosed) // sono necessarie due passate in piu!
|
||||
//{
|
||||
// /////** Si disegnano le back face shiftate in avanti di 2 epsilon **/////
|
||||
// glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
||||
// glColor(Color4b::Black);
|
||||
// glCullFace(GL_FRONT);
|
||||
// glDepthRange(0.0f,1.0f-2.0*ZTWIST);
|
||||
// DrawFill(m);
|
||||
// //glw.DrawFill<GLW::NMNone, GLW::CMNone,GLW::TMNone>();
|
||||
//}
|
||||
//if(OMV.size()>0)
|
||||
//{
|
||||
// /////** Si disegnano le back face shiftate in avanti di 2 epsilon **/////
|
||||
// glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
|
||||
// glColor(Color4b::Black);
|
||||
// glDisable(GL_CULL_FACE);
|
||||
// glDepthRange(0.0f,1.0f-2.0*ZTWIST);
|
||||
// for(unsigned int i=0;i<OMV.size();++i)
|
||||
// DrawFill(*(OMV[i]));
|
||||
// //OGV[i]->DrawFill<GLW::NMNone, GLW::CMNone,GLW::TMNone>();
|
||||
//}
|
||||
int cnt=0;
|
||||
snapZ.OpenGLSnap(GL_DEPTH_COMPONENT);
|
||||
snapC.OpenGLSnap();
|
||||
double MM[16];
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX,MM);
|
||||
double MP[16];
|
||||
glGetDoublev(GL_PROJECTION_MATRIX,MP);
|
||||
int VP[4];
|
||||
glGetIntegerv(GL_VIEWPORT,VP);
|
||||
double tx,ty,tz;
|
||||
for(int i=0;i<m.vert.size();++i)
|
||||
{
|
||||
gluProject(m.vert[i].P()[0],m.vert[i].P()[1],m.vert[i].P()[2],
|
||||
MM,MP,VP,
|
||||
&tx,&ty,&tz);
|
||||
if(tx>=0 && tx<snapZ.sx && ty>=0 && ty<snapZ.sy)
|
||||
{
|
||||
int txi=floor(tx),tyi=floor(ty);
|
||||
float sd=snapZ.Pix(tx,ty);
|
||||
|
||||
int col = min( min(snapC.Pix(txi+0,tyi+0)[0],snapC.Pix(txi+1,tyi+0)[0]),
|
||||
min(snapC.Pix(txi+0,tyi+1)[0],snapC.Pix(txi+1,tyi+1)[0]));
|
||||
if(col!=0)
|
||||
if(tz<sd+ZTWIST) {
|
||||
PixSeen[i]++;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
glPopAttrib();
|
||||
printf("Seen %i vertexes on %i\n",cnt,m.vert.size());
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void SmoothVisibility()
|
||||
{
|
||||
MESH_TYPE::FaceIterator fi;
|
||||
vector<float> VV2;
|
||||
vector<int> VC(VV.size(),1);
|
||||
VV2=VV;
|
||||
for(fi=m.face.begin();fi!=m.face.end();++fi)
|
||||
for(int i=0;i<3;++i)
|
||||
{
|
||||
VV2[(*fi).V(i)-&*m.vert.begin()] += VV[(*fi).V1(i)-&*m.vert.begin()];
|
||||
++VC[(*fi).V(i)-&*m.vert.begin()];
|
||||
}
|
||||
|
||||
for(unsigned int i=0;i<VV2.size();++i)
|
||||
VV[i]=VV2[i]/VC[i];
|
||||
}
|
||||
|
||||
void MapVisibility(float Gamma=1, float LowPass=0, float HighPass=1, bool FalseColor = false)
|
||||
{
|
||||
float minv=*min_element(VV.begin(),VV.end());
|
||||
float maxv=*max_element(VV.begin(),VV.end());
|
||||
printf("Visibility Range %f %f\n", minv,maxv);
|
||||
|
||||
MESH_TYPE::VertexIterator vi;
|
||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi){
|
||||
float gval=(VV[vi-m.vert.begin()]-minv)/(maxv-minv);
|
||||
if(gval<LowPass) gval=LowPass;
|
||||
if(gval>HighPass) gval=HighPass;
|
||||
(*vi).C().SetGrayShade(pow((gval-LowPass)/(HighPass-LowPass),Gamma));
|
||||
}
|
||||
}
|
||||
|
||||
//void ApplyLightingEnvironment(std::vector<float> &W, float Gamma=1)
|
||||
// {
|
||||
// assert(W.size()==VN.size());
|
||||
// MESH_TYPE::VertexIterator vi;
|
||||
//
|
||||
// for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||
// {
|
||||
// float gray=0;
|
||||
// bitset<VisMax> &msk=VM[vi-m.vert.begin()];
|
||||
// for(int i=0;i<VN.size();++i)
|
||||
// if(msk[i]) gray+=W[i];
|
||||
//
|
||||
// (*vi).C().SetGrayShade(gray);
|
||||
// }
|
||||
// }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
#endif // __VCG_MESH_VISIBILITY
|
Loading…
Reference in New Issue