00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #include <stdlib.h>
00058 #include <stdio.h>
00059 #include <stdarg.h>
00060 #include <time.h>
00061
00062
00063 #define NOMINMAX
00064
00065 #include <GL/glew.h>
00066 #include <GL/glut.h>
00067 #include <wrap/gl/space.h>
00068
00069
00070 #include <wrap/callback.h>
00071 #include <vcg/math/base.h>
00072 #include <wrap/gui/trackball.h>
00073 #include <vcg/simplex/vertex/with/vcvn.h>
00074 #include <vcg/simplex/vertex/with/vcvn.h>
00075 #include <vcg/simplex/face/with/fn.h>
00076 #include <vcg/space/index/grid_static_ptr.h>
00077 #include <vcg/complex/trimesh/base.h>
00078 #include<wrap/io_trimesh/export_ply.h>
00079 #include<wrap/io_trimesh/import_ply.h>
00080 #include<vcg/complex/trimesh/update/normal.h>
00081 #include<vcg/complex/trimesh/update/bounding.h>
00082 #include<vcg/complex/trimesh/update/color.h>
00083
00084 #include "visshader.h"
00085 using namespace vcg;
00086 using namespace std;
00087
00088
00089
00090
00091
00092 class MyEdge;
00093 class AFace;
00094 class AVertex : public VertexVCVN< float ,MyEdge,AFace > {};
00095 class AFace : public FaceFN< AVertex,MyEdge,AFace > {};
00096 class AMesh : public tri::TriMesh< vector<AVertex>, vector<AFace> > {};
00097
00099
00100 int SampleNum=64;
00101 int WindowRes=800;
00102 unsigned int TexInd=0;
00103 bool SwapFlag=false;
00104 bool CullFlag=false;
00105 bool ClosedFlag=false;
00106 Point3f ConeDir(0,1,0);
00107 float ConeAngleRad = math::ToRad(180.0f);
00108
00109 float lopass=0,hipass=1,gamma_correction=1;
00110 float diff=.8;
00111 float ambi=.2;
00112
00113 bool LightFlag=true;
00114 bool ColorFlag=true;
00115 bool FalseColorFlag=false;
00116 bool ShowDirFlag=false;
00117 int imgcnt=0;
00118
00119 Color4b BaseColor=Color4b::White;
00120 Trackball QV;
00121 Trackball QL;
00122 Trackball *Q=&QV;
00123
00124 int ScreenH,ScreenW;
00125 float ViewAngle=33;
00126 vector<Point3f> ViewVector;
00127
00128 bool cb(const char *buf)
00129 {
00130 printf(buf);
00131 return true;
00132 }
00133
00134 void BuildOnePixelTexture(Color4b c, unsigned int &TexInd)
00135 {
00136 if(TexInd==0) glGenTextures(1,&TexInd);
00137
00138 glBindTexture(GL_TEXTURE_1D,TexInd);
00139 glTexImage1D(GL_TEXTURE_1D,0,GL_RGBA,1,0,GL_RGBA,GL_UNSIGNED_BYTE,&c);
00140 glEnable(GL_TEXTURE_1D);
00141 glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
00142 }
00143 void glutPrintf(int x, int y, const char * f, ... )
00144 {
00145 glMatrixMode (GL_PROJECTION);
00146 glPushMatrix();
00147 glLoadIdentity ();
00148 glOrtho(0,ScreenW,0,ScreenH,-1,1);
00149 glMatrixMode (GL_MODELVIEW);
00150 glPushMatrix();
00151 glLoadIdentity ();
00152
00153 int len, i;
00154 char buf[4096];
00155 va_list marker;
00156 va_start( marker, f );
00157
00158 int n = vsprintf(buf,f,marker);
00159 va_end( marker );
00160 glPushAttrib(GL_ENABLE_BIT);
00161 glDisable(GL_LIGHTING);
00162 glColor3f(0,0,0);
00163 glRasterPos2f(x, y);
00164 len = (int) strlen(buf);
00165 for (i = 0; i < len; i++) {
00166 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, buf[i]);
00167 }
00168 glMatrixMode (GL_PROJECTION);
00169 glPopMatrix();
00170 glMatrixMode (GL_MODELVIEW);
00171 glPopMatrix();
00172 glPopAttrib();
00173 }
00174
00175
00176 void SaveTexturedGround();
00177
00178 void DrawViewVector()
00179 {
00180 glDisable(GL_LIGHTING);
00181 glColor3f(0,0,1);
00182 glBegin(GL_LINES);
00183 for(unsigned int i=0;i<ViewVector.size();++i)
00184 {
00185 glVertex3f(0,0,0);glVertex(ViewVector[i]);
00186 }
00187 glEnd();
00188 }
00189 void DrawLightVector()
00190 {
00191 const int sz=5;
00192 glPushMatrix();
00193 QL.Apply();
00194 glDisable(GL_LIGHTING);
00195 glBegin(GL_LINES);
00196 glColor3f(1,1,0);
00197 for(unsigned int i=0;i<=sz;++i)
00198 for(unsigned int j=0;j<=sz;++j)
00199 {
00200 glColor3f(1,1,0);
00201 glVertex3f(-1.0f+i*2.0/sz,-1.0f+j*2.0/sz,-1);
00202 glVertex3f(-1.0f+i*2.0/sz,-1.0f+j*2.0/sz, 1);
00203 }
00204 glEnd();
00205 glPopMatrix();
00206 }
00207
00208 void Draw(AMesh &mm)
00209 {
00210 if(mm.face.empty())
00211 {
00212 glPushAttrib(GL_ENABLE_BIT);
00213 glDisable(GL_LIGHTING);
00214 AMesh::VertexIterator vi;
00215 glBegin(GL_POINTS);
00216 for(vi=mm.vert.begin();vi!=mm.vert.end();++vi)
00217 {
00218 if(ColorFlag) glColor((*vi).C());
00219 glVertex((*vi).P());
00220 }
00221 glEnd();
00222 glPopAttrib();
00223 }
00224 else
00225 {
00226 AMesh::FaceIterator fi;
00227 glBegin(GL_TRIANGLES);
00228 for(fi=mm.face.begin();fi!=mm.face.end();++fi)
00229 {
00230 glNormal((*fi).V(0)->N()); if(ColorFlag) glColor((*fi).V(0)->C()); glVertex((*fi).V(0)->P());
00231 glNormal((*fi).V(1)->N()); if(ColorFlag) glColor((*fi).V(1)->C()); glVertex((*fi).V(1)->P());
00232 glNormal((*fi).V(2)->N()); if(ColorFlag) glColor((*fi).V(2)->C()); glVertex((*fi).V(2)->P());
00233 }
00234 glEnd();
00235 }
00236 }
00237
00238 AMesh m;
00239 VertexVisShader<AMesh> Vis(m);
00240
00241 string OutNameMsh;
00242
00243
00244
00245
00246
00247 void ViewReshape(GLsizei w, GLsizei h)
00248 {
00249 ScreenW=w; ScreenH=h;
00250 glViewport(0,0,w,h);
00251 }
00252
00253 void ViewDisplay (void)
00254 {
00255 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00256 glMatrixMode (GL_PROJECTION);
00257 glLoadIdentity ();
00258 gluPerspective(ViewAngle,(float)ScreenW/ScreenH,1,7);
00259 glMatrixMode (GL_MODELVIEW);
00260 glLoadIdentity ();
00261 glPushMatrix();
00262 QL.Apply();
00263 glutPrintf(5,5,"Diffuse %04.2f Ambient %04.2f "
00264 " LowPass %04.2f HiPass %04.2f Gamma %04.2f rgb = %03i:%03i:%03i",
00265 diff,ambi,lopass,hipass,gamma_correction,BaseColor[0],BaseColor[1],BaseColor[2]);
00266
00267 GLfloat light_position0[] = {0.0, 10.0, 300.0, 0.0};
00268 glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
00269 glPopMatrix();
00270 glTranslatef(0,0,-4);
00271 if(Q==&QL) DrawLightVector();
00272 QL.GetView();
00273 QV.GetView();
00274 QV.Apply(false);
00275 if(ShowDirFlag) DrawViewVector();
00276
00277 float d = 2.0/m.bbox.Diag();
00278 glScalef(d, d, d);
00279 glColor3f(diff,diff,diff);
00280 glTranslate(-m.bbox.Center());
00281 if(LightFlag) glEnable(GL_LIGHTING);
00282 else glDisable(GL_LIGHTING);
00283 if(ColorFlag) glEnable(GL_COLOR_MATERIAL);
00284 else glDisable(GL_COLOR_MATERIAL);
00285 if(FalseColorFlag) glColorMaterial(GL_FRONT,GL_DIFFUSE);
00286 else glColorMaterial(GL_FRONT,GL_AMBIENT);
00287
00288 glMateriali(GL_FRONT,GL_SHININESS,0);
00289 float spec[4]={0,0,0,1};
00290 float ambientV[4]={ambi,ambi,ambi,1};
00291 float diffuseV[4]={diff,diff,diff,1};
00292 glMaterialfv(GL_FRONT,GL_SPECULAR,spec);
00293 glMaterialfv(GL_FRONT,GL_AMBIENT, ambientV);
00294 glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuseV);
00295 glCullFace(GL_BACK);
00296
00297 if(CullFlag) glEnable(GL_CULL_FACE);
00298 else glDisable(GL_CULL_FACE);
00299
00300 BuildOnePixelTexture(BaseColor,TexInd);
00301 Draw(m);
00302 glutSwapBuffers();
00303 }
00304
00305 void ViewSpecialKey(int , int , int )
00306 {
00307 glutPostRedisplay();
00308 }
00309 void Toggle(bool &flag) {flag = !flag;}
00310 void UpdateVis()
00311 {
00312 if( LightFlag && !FalseColorFlag)
00313 Vis.MapVisibility(gamma_correction,lopass,hipass,ambi);
00314 if(!LightFlag && !FalseColorFlag)
00315 Vis.MapVisibility(gamma_correction,lopass,hipass,1.0);
00316 if(FalseColorFlag)
00317 Vis.MapFalseColor();
00318 }
00319
00320
00321
00322
00323 void ViewKey(unsigned char key, int , int )
00324 {
00325 Point3f dir;
00326 switch (key) {
00327 case 27: exit(0); break;
00328 case 9: if(Q==&QV) Q=&QL;else Q=&QV; break;
00329 case 'l' :
00330 lopass=lopass+.05;
00331 printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction);
00332 UpdateVis(); break;
00333 case 'L' :
00334 lopass=lopass-.05;
00335 printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction);
00336 UpdateVis(); break;
00337 case 'h' :
00338 hipass=hipass-.05;
00339 printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction);
00340 UpdateVis(); break;
00341 case 'H' :
00342 hipass=hipass+.05;
00343 printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction);
00344 UpdateVis(); break;
00345 case 'd' : diff+=.05; printf("Ambient %f Diffuse %f, \n",ambi,diff); UpdateVis(); break;
00346 case 'D' : diff-=.05; printf("Ambient %f Diffuse %f, \n",ambi,diff); UpdateVis(); break;
00347 case 'a' : ambi+=.05; printf("Ambient %f Diffuse %f, \n",ambi,diff); UpdateVis(); break;
00348 case 'A' : ambi-=.05; printf("Ambient %f Diffuse %f, \n",ambi,diff); UpdateVis(); break;
00349
00350 case 'e' : ambi+=.05; diff-=.05;
00351 printf("Ambient %f Diffuse %f, \n",ambi,diff);
00352 UpdateVis(); break;
00353 case 'E' : ambi-=.05; diff+=.05;
00354 printf("Ambient %f Diffuse %f, \n",ambi,diff);
00355 UpdateVis(); break;
00356 case 'p' :
00357 gamma_correction=gamma_correction-.05;
00358 printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction);
00359 UpdateVis(); break;
00360 case 'P' :
00361 gamma_correction=gamma_correction+.05;
00362 printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction);
00363 UpdateVis(); break;
00364 case 13 :
00365
00366 Vis.ComputeUniformCone(SampleNum,ViewVector, ConeAngleRad,ConeDir,cb);
00367 UpdateVis(); break;
00368 case ' ' : {
00369 Point3f dir = Q->camera.ViewPoint();
00370 printf("ViewPoint %f %f %f\n",dir[0],dir[1],dir[2]);
00371 dir.Normalize();
00372 dir=Inverse(Q->track.Matrix())*dir;
00373 printf("ViewPoint %f %f %f\n",dir[0],dir[1],dir[2]);
00374 dir.Normalize();
00375 Vis.ComputeSingle(dir,ViewVector,cb);
00376 UpdateVis();
00377 } break;
00378 case 'r' : BaseColor[0]=min(255,BaseColor[0]+2); break;
00379 case 'R' : BaseColor[0]=max( 0,BaseColor[0]-2); break;
00380 case 'g' : BaseColor[1]=min(255,BaseColor[1]+2); break;
00381 case 'G' : BaseColor[1]=max( 0,BaseColor[1]-2); break;
00382 case 'b' : BaseColor[2]=min(255,BaseColor[2]+2); break;
00383 case 'B' : BaseColor[2]=max( 0,BaseColor[2]-2); break;
00384
00385 case 'v' : Toggle(ShowDirFlag); break;
00386 case 'V' :
00387 {
00388 SimplePic<Color4b> snapC;
00389 snapC.OpenGLSnap();
00390 char buf[128];
00391 sprintf(buf,"Snap%03i.ppm",imgcnt++);
00392 snapC.SavePPM(buf);
00393 }
00394 case 's' :
00395 Vis.SmoothVisibility();
00396 UpdateVis(); break;
00397 case 't' :
00398 Vis.SmoothVisibility(true);
00399 UpdateVis(); break;
00400 case 'S' :
00401 {
00402 vcg::tri::io::PlyInfo p;
00403 p.mask|=vcg::tri::io::Mask::IOM_VERTCOLOR ;
00404 tri::io::ExporterPLY<AMesh>::Save(m,OutNameMsh.c_str(),false,p);
00405 }
00406 break;
00407 case 'C' : LightFlag = !LightFlag;
00408 printf("Toggled Light %s\n",LightFlag?"on":"off");
00409 UpdateVis(); break;
00410 case 'c' : ColorFlag = !ColorFlag;
00411 printf("Toggled Color %s\n",ColorFlag?"on":"off"); break;
00412 case 'f' : FalseColorFlag = !FalseColorFlag;
00413 printf("Toggled FalseColor %s\n",ColorFlag?"on":"off");
00414 UpdateVis(); break;
00415
00416 case '1' : diff=0.80f; ambi=0.10f; gamma_correction=1.0; lopass=0.00f; hipass=1.00f; ColorFlag=false; UpdateVis(); break;
00417 case '2' : diff=0.65f; ambi=0.30f; gamma_correction=1.0; lopass=0.15f; hipass=0.80f; ColorFlag=true; UpdateVis(); break;
00418 case '3' : diff=0.45f; ambi=0.50f; gamma_correction=1.0; lopass=0.20f; hipass=0.75f; ColorFlag=true; UpdateVis(); break;
00419 case '4' : diff=0.35f; ambi=0.60f; gamma_correction=1.0; lopass=0.25f; hipass=0.70f; ColorFlag=true; UpdateVis(); break;
00420 }
00421 glutPostRedisplay(); ;
00422 }
00423 void ViewMenu(int val)
00424 {
00425 ViewKey(val, 0, 0);
00426 }
00427
00428
00429
00430
00431 int GW,GH;
00432
00433 void ViewMouse(int button, int state, int x, int y)
00434 {
00435 static int KeyMod=0;
00436 static int glut_buttons=0;
00437
00438 int m_mask = 0;
00439 if(state == GLUT_DOWN) {
00440 KeyMod=glutGetModifiers();
00441 if(GLUT_ACTIVE_SHIFT & KeyMod) m_mask |= Trackball::KEY_SHIFT;
00442 if(GLUT_ACTIVE_ALT & KeyMod) m_mask |= Trackball::KEY_ALT;
00443 if(GLUT_ACTIVE_CTRL & KeyMod) m_mask |= Trackball::KEY_CTRL;
00444
00445 glut_buttons |= (1<<button);
00446 Q->MouseDown(x, ScreenH-y, glut_buttons | m_mask);
00447 } else {
00448 if(GLUT_ACTIVE_SHIFT & KeyMod) m_mask |= Trackball::KEY_SHIFT;
00449 if(GLUT_ACTIVE_ALT & KeyMod) m_mask |= Trackball::KEY_ALT;
00450 if(GLUT_ACTIVE_CTRL & KeyMod) m_mask |= Trackball::KEY_CTRL;
00451 glut_buttons |= (1<<button);
00452 Q->MouseUp(x, ScreenH-y, glut_buttons | m_mask);
00453 }
00454 }
00455
00456 void ViewMouseMotion(int x, int y)
00457 {
00458 Q->MouseMove(x,ScreenH-y);
00459 glutPostRedisplay();
00460 }
00461
00462 void SetLight()
00463 {
00464 GLfloat light_ambient0[] = {0.0, 0.0, 0.0, 1.0};
00465 GLfloat light_diffuse0[] = {1.0, 1.0, 1.0, 1.0};
00466 GLfloat light_position0[] = {0.0, 10.0, 300.0, 0.0};
00467 glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
00468 glLightfv(GL_LIGHT0, GL_AMBIENT, light_diffuse0);
00469 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0);
00470 glEnable(GL_LIGHT0);
00471 glLightModelfv(GL_LIGHT_MODEL_AMBIENT,light_ambient0);
00472
00473 }
00474
00475 void ViewInit (void) {
00476 SetLight();
00477 Q->Reset();
00478 Q->radius= 1;
00479 glEnable(GL_DEPTH_TEST);
00480 glDepthFunc(GL_LEQUAL);
00481 glClearColor (0.8, 0.8, 0.8, 0.0);
00482 glEnable(GL_NORMALIZE);
00483 glEnable(GL_LIGHTING);
00484
00485
00486 glShadeModel(GL_SMOOTH);
00487
00488 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00489 glEnable(GL_CULL_FACE);
00490 glCullFace(GL_BACK);
00491 }
00492
00493
00494
00495 int main(int argc, char** argv)
00496 {
00497 if(argc<2) {
00498 printf(
00499 "shadevis 1.0 \n"__DATE__"\n"
00500 "Copyright 2003-2004 Visual Computing Lab I.S.T.I. C.N.R.\n"
00501 "Paolo Cignoni (cignoni@isti.cnr.it)\n\n"
00502 "Usage: shadevis file.ply [options]\n"
00503 "Options:\n"
00504 " -w# WindowResolution (default 600)\n"
00505 " -n# Sample Directions (default 64)\n"
00506 " -z# z offset (default 1e-3)\n"
00507 " -c assume that the mesh is closed (slightly faster, default false)\n"
00508 " -f Flip normal of the model\n"
00509 " -da # Cone Direction Angle in degree (default 180)\n"
00510 " -dv # # # Cone Direction vector (default 0 0 1)\n"
00511 );
00512
00513 return 1;
00514 }
00515
00516 srand(time(0));
00517 int i=1;
00518 while(i<argc && (argv[i][0]=='-'))
00519 {
00520 switch(argv[i][1])
00521 {
00522 case 'd' :
00523 if(argv[i][2] == 'a') {
00524 ConeAngleRad = math::ToRad(atof(argv[i+1])); ++i; break;
00525 }
00526 if(argv[i][2] == 'v') {
00527 Point3f p(atof(argv[i+1]),atof(argv[i+2]),atof(argv[i+3]));
00528 ConeDir = Normalize(p);
00529 i+=3; break;
00530 }
00531 printf("Error unable to parse option '%s'\n",argv[i]);
00532 exit(0);
00533 break;
00534 case 'n' : SampleNum = atoi(argv[i]+2); break;
00535 case 'f' : SwapFlag=false; break;
00536 case 'c' : ClosedFlag=true; break;
00537 case 'w' : WindowRes= atoi(argv[i]+2);
00538 printf("Set WindowRes to %i\n",WindowRes ); break;
00539 case 's' : Vis.SplitNum= atoi(argv[i]+2);
00540 printf("Set SplitNum to %i\n",Vis.SplitNum ); break;
00541 case 'z' : Vis.ZTWIST = atof(argv[i]+2);
00542 printf("Set ZTWIST to %f\n",Vis.ZTWIST ); break;
00543 default: {
00544 printf("Error unable to parse option '%s'\n",argv[i]);
00545 exit(0);
00546 }
00547 }
00548
00549 ++i;
00550 }
00551
00552
00553 string basename = argv[i];
00554 if(!(basename.substr(basename.length()-4)==".ply")) {
00555 printf("Error: Unknown file extension %s\n",basename.c_str());
00556 return 1;
00557 }
00558
00559
00560 int ret=tri::io::ImporterPLY<AMesh>::Open(m,argv[i]);
00561 if(ret) {printf("Error unable to open mesh %s : '%s' \n",argv[i],tri::io::ImporterPLY<AMesh>::ErrorMsg(ret));exit(-1);}
00562 tri::UpdateNormals<AMesh>::PerVertexNormalized(m);
00563 tri::UpdateBounding<AMesh>::Box(m);
00564 tri::UpdateColor<AMesh>::VertexConstant(m,Color4b::White);
00565 Vis.IsClosedFlag=ClosedFlag;
00566 Vis.Init();
00567 UpdateVis();
00568
00569 printf("Mesh bbox (%f %f %f)-(%f %f %f)\n\n",
00570 m.bbox.min[0],m.bbox.min[1],m.bbox.min[2],
00571 m.bbox.max[0],m.bbox.max[1],m.bbox.max[2]);
00572
00573 OutNameMsh=(string(argv[i]).substr(0,strlen(argv[i])-4));
00574 OutNameMsh+="_vis.ply";
00575
00576 printf("Mesh Output filename %s\n",OutNameMsh.c_str());
00577
00578 printf("Mesh %iv %if bbox Diag %g\n",m.vn,m.fn,m.bbox.Diag());
00579
00580 glutInit(&argc, argv);
00581
00582 glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
00583 glutInitWindowSize(WindowRes, WindowRes);
00584 glutInitWindowPosition (10,10);
00585 glutCreateWindow ("shadevis - Visual Computing Lab - vcg.isti.cnr.it ");
00586 glutDisplayFunc(ViewDisplay);
00587 glutReshapeFunc(ViewReshape);
00588 glutKeyboardFunc(ViewKey);
00589 glutSpecialFunc(ViewSpecialKey);
00590 glutMouseFunc(ViewMouse);
00591 glutMotionFunc(ViewMouseMotion);
00592
00593 ViewInit();
00594 glewInit();
00595 glutMainLoop();
00596
00597 return(0);
00598 }