$search
00001 /* 00002 James R. Diebel 00003 Stanford University 00004 00005 Started: 30 November 2004 00006 Last revised: 00007 00008 compmesh.cc - Utility to compare two MSH files in an OpenGL window 00009 00010 Depends on: 00011 - Mesh class (mesh.hh) 00012 -- Vec3d class (vec3d.hh) 00013 -- Vert class (vert.hh) 00014 -- Edge class (edge.hh) 00015 -- Face class (face.hh) 00016 - Timer class (timer.hh) 00017 - TriMesh class (trimesh.h) 00018 - GUI headers (gui.hh) 00019 -- OpenGL 00020 -- GLUT 00021 -- GLUI 00022 */ 00023 00024 #include <iostream> 00025 #include <fstream> 00026 #include <string.h> 00027 #include "bmtk/mesh.hh" 00028 #include "bmtk/gui.hh" 00029 #include "bmtk/timer.hh" 00030 00031 #define D2R 0.017453293 00032 #define R2D 57.29578 00033 00034 using namespace std; 00035 00036 // Data contained within namespace to avoid collisions 00037 namespace compmesh { 00038 // Mesh data to be displayed 00039 Mesh* m; 00040 Mesh* dm; 00041 00042 // Windowing details (default values if no options file) 00043 int wx0 = 200; // upper left of main window 00044 int wy0 = 0; 00045 int wdx = 1000; // size of main window 00046 int wdy = 800; 00047 int cx0 = 0; // upper left of control window 00048 int cy0 = 0; 00049 int bdx, bdy; // size of window manager border 00050 00051 // Viewpoint variables (default values if no options file) 00052 float xyAspect; 00053 int lastX, lastY; 00054 float rotationX = 0.0, rotationY = 0.0; 00055 int motionMode; 00056 Vec3d center; 00057 00058 // These are the live variables passed into GLUI 00059 // (default values if no options file) 00060 int currMesh = 1; 00061 int origMesh = 0; 00062 int wireframe = 0; 00063 int face2face = 0; 00064 int face2vert = 0; 00065 int edgeAngles = 0; 00066 int vertPotentials = 0; 00067 int vertGradients = 0; 00068 int faceColors = 1; 00069 int centerSphere = 1; 00070 int meshBoundary = 0; 00071 int vertGradVecs = 0; 00072 int segment = 0; 00073 00074 int keypoints = 0; 00075 int vertNormals = 0; 00076 int faceAreas = 0; 00077 int vertSteps = 0; 00078 int edge2face = 0; 00079 int face2edge = 0; 00080 int polyMesh = 0; 00081 00082 float gs2 = 1.0; 00083 float gsn2 = 1.0; 00084 00085 char text[sizeof(GLUI_String)] = {""}; 00086 int diffuseIntensity = 100; 00087 int ambientIntensity = 50; 00088 int main_window; 00089 float scale = 1.0; 00090 int counter = 0; 00091 00092 float delta=1.0; 00093 00094 // Pointers to the windows and some of the controls we'll create 00095 GLUI *glui; 00096 GLUI_Spinner *diffuseSpinner, *ambientSpinner, *deltaSpinner, 00097 *gs2Spinner, *gsn2Spinner; 00098 GLUI_Rollout *visualsRollout; 00099 00100 // Miscellaneous global variables 00101 GLfloat light_ambient[4]; 00102 GLfloat light_diffuse[4]; 00103 GLfloat light_position[] = {.5f, .5f, 1.0f, 0.0f}; 00104 } 00105 using namespace compmesh; 00106 00107 int main (int argc, char *argv[]) { 00108 // if bad command line args, give usage instructions and exit 00109 if (argc < 3) { 00110 cout << endl 00111 << "Usage: compmesh file_1.msh file_2.msh" << endl; 00112 exit(1); 00113 } 00114 00115 // read mesh from file 00116 Mesh m1,m2; 00117 m1.readMesh(argv[1]); m2.readMesh(argv[2]); 00118 00119 // find mesh properties that are independent of options 00120 m1.findMeshProps(); m2.findMeshProps(); 00121 00122 // initialize OpenGL window class 00123 startGUI(&m1, &m2); 00124 00125 return 0; 00126 } 00127 00128 // GLUI control callback 00129 void controlCB(int control) { 00130 if (control == -1) { 00131 cout << "Exiting..." << endl << flush; 00132 exit(0); 00133 } 00134 if (control == 100) { 00135 saveOptions(); 00136 m->writeOptions("mrf_options.dat"); 00137 } 00138 if (control == 150) { 00139 center = (m->boxMin + m->boxMax)/2; 00140 } 00141 if (control == 151) { 00142 m->runCG(); 00143 } 00144 if (control == 152) { 00145 m->reset(); 00146 sprintf(text,"Potential: %.2f",m->psi); 00147 myGlutDisplay(); 00148 } 00149 if (control == 154) { 00150 m->anneal(); 00151 } 00152 if (control == 155) { 00153 m->runSegmentation(); 00154 update(); 00155 } 00156 00157 if (control == 156) { 00158 cout << "Saving Mesh..." << endl; 00159 m->writeMesh("blah"); 00160 } 00161 00162 if (control == 157) { 00163 if (dm) delete dm; 00164 dm = m->genDecimatedMesh(); 00165 update(); 00166 } 00167 00168 if (control == 250) { 00169 for (int i=0;i<3;i++) { 00170 light_diffuse[i] = float(diffuseIntensity)/100.0f; 00171 light_ambient[i] = float(ambientIntensity)/100.0f; 00172 } 00173 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); 00174 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); 00175 } 00176 if (control == 251) { 00177 m->setVertVar(gs2); 00178 m->setNormalVar(gsn2); 00179 m->findMeshPotential(); 00180 m->findLocalEdgePotentials(); 00181 m->findVertGradients(); 00182 m->findSearchDirs(true); 00183 update(); 00184 } 00185 } 00186 00187 // Parses keyboard commands 00188 void myGlutKeyboard(unsigned char Key, int x, int y) { 00189 switch(Key) 00190 { 00191 case 27: 00192 case 'q': 00193 exit(0); 00194 break; 00195 case 'x': case ' ': 00196 center[0] += 0.01*m->box*cos(rotationX*D2R)*sin(rotationY*D2R); 00197 center[1] -= 0.01*m->box*sin(rotationX*D2R); 00198 center[2] -= 0.01*m->box*cos(rotationX*D2R)*cos(rotationY*D2R); 00199 break; 00200 case 'z': 00201 center[0] -= 0.01*m->box*cos(rotationX*D2R)*sin(rotationY*D2R); 00202 center[1] += 0.01*m->box*sin(rotationX*D2R); 00203 center[2] += 0.01*m->box*cos(rotationX*D2R)*cos(rotationY*D2R); 00204 break; 00205 case 'a': 00206 center[0] -= 0.01*m->box*cos(rotationY*D2R); 00207 center[2] -= 0.01*m->box*sin(rotationY*D2R); 00208 break; 00209 case 'd': 00210 center[0] += 0.01*m->box*cos(rotationY*D2R); 00211 center[2] += 0.01*m->box*sin(rotationY*D2R); 00212 break; 00213 case 'w': 00214 center[0] += 0.01*m->box*sin(rotationX*D2R)*sin(rotationY*D2R); 00215 center[1] += 0.01*m->box*cos(rotationX*D2R); 00216 center[2] -= 0.01*m->box*sin(rotationX*D2R)*cos(rotationY*D2R); 00217 break; 00218 case 's': 00219 center[0] -= 0.01*m->box*sin(rotationX*D2R)*sin(rotationY*D2R); 00220 center[1] -= 0.01*m->box*cos(rotationX*D2R); 00221 center[2] += 0.01*m->box*sin(rotationX*D2R)*cos(rotationY*D2R); 00222 break; 00223 }; 00224 00225 glutPostRedisplay(); 00226 } 00227 00228 // Passes keyboard commands to the appropriate interpreter 00229 void myGlutMenu(int value) { 00230 myGlutKeyboard(value, 0, 0); 00231 } 00232 00233 // Run each time OpenGL renders a frame 00234 void myGlutIdle(void) { 00235 // According to the GLUT specification, the current window is 00236 // undefined during an idle callback. So we need to explicitly change 00237 // it if necessary 00238 if (glutGetWindow() != main_window) 00239 glutSetWindow(main_window); 00240 00241 glutPostRedisplay(); 00242 00243 // if it is our first iterations, 00244 // infer the size of the window manager border 00245 if (!counter) { 00246 bdx = glutGet(GLUT_WINDOW_X) - wx0; 00247 bdy = glutGet(GLUT_WINDOW_Y) - wy0; 00248 } 00249 00250 // Updates frame counter 00251 counter++; 00252 } 00253 00254 // Parses mouse button presses 00255 void myGlutMouse(int button, int button_state, int x, int y) { 00256 lastX = x; 00257 lastY = y; 00258 if (button == GLUT_LEFT_BUTTON && button_state == GLUT_DOWN) { 00259 if (glutGetModifiers() == GLUT_ACTIVE_CTRL) 00260 motionMode = 3; // translate on surface of screen 00261 else 00262 motionMode = 1; // rotate 00263 } 00264 if (button == GLUT_RIGHT_BUTTON && button_state == GLUT_DOWN) { 00265 if (glutGetModifiers() == GLUT_ACTIVE_CTRL) 00266 motionMode = 4; // translate into/out of screen 00267 else 00268 motionMode = 2; // zoom 00269 } 00270 00271 if (button_state == GLUT_UP) { 00272 motionMode = 0; // no motion 00273 myGlutDisplay(); 00274 } 00275 } 00276 00277 // Parses mouse motion 00278 void myGlutMotion(int x, int y) { 00279 if (motionMode == 1) { // rotate 00280 rotationX += float(y - lastY)/4.0f; 00281 rotationY += float(x - lastX)/4.0f; 00282 //cout << rotationX << " " << rotationY << endl << flush; 00283 } else if (motionMode == 2) { // zoom 00284 int diff = y - lastY; 00285 int mag = abs(y - lastY); 00286 for (int i=0;i<mag;i++) { 00287 if (diff < 0) scale *= 1.01; 00288 else scale /= 1.01; 00289 } 00290 } else if (motionMode == 3) { // translate left/right, up/down 00291 float distX = 0.1*m->box*float(x - lastX)/float(wdx); 00292 float distY = 0.1*m->box*float(y - lastY)/float(wdy); 00293 center[0] -= distX*cos(rotationY*D2R); 00294 center[2] -= distX*sin(rotationY*D2R); 00295 center[0] += distY*sin(rotationX*D2R)*sin(rotationY*D2R); 00296 center[1] += distY*cos(rotationX*D2R); 00297 center[2] -= distY*sin(rotationX*D2R)*cos(rotationY*D2R); 00298 } else if (motionMode == 4) { // translate into/out of screen 00299 float distZ = 0.1*m->box*float(y - lastY)/float(wdy); 00300 center[0] -= distZ*cos(rotationX*D2R)*sin(rotationY*D2R); 00301 center[1] += distZ*sin(rotationX*D2R); 00302 center[2] += distZ*cos(rotationX*D2R)*cos(rotationY*D2R); 00303 } 00304 if (motionMode) { 00305 lastX = x; 00306 lastY = y; 00307 } 00308 00309 glutPostRedisplay(); 00310 } 00311 00312 // tells GLUT when the window has been reshaped 00313 void myGlutReshape(int x, int y) { 00314 wdx = x; wdy = y; 00315 xyAspect = (float)x / (float)y; 00316 glViewport(0, 0, x, y); 00317 00318 glutPostRedisplay(); 00319 } 00320 00321 00322 float neg(float arg) { 00323 return (fabs(arg) - arg)/2; 00324 } 00325 00326 // Draws the actual mesh with calls directly to OpenGL 00327 void drawMesh(void) { 00328 // Draw the triangles 00329 if (currMesh || origMesh) { 00330 float color; 00331 glBegin(GL_TRIANGLES); 00332 for (int i=0;i<m->nf;i++) { 00333 float* n; 00334 if (currMesh) n = &(m->f[i].n.x[0]); 00335 if (origMesh) n = &(m->f[i].n0.x[0]); 00336 if (segment) n = &(m->f[i].r->n.x[0]); 00337 glNormal3d(n[0],n[1],n[2]); 00338 00339 if (faceColors) { 00340 glColor4f(fabs(n[0]),fabs(n[1]),fabs(n[2]),0.5); 00341 } else if (faceAreas) { 00342 color = m->f[i].s/delta; 00343 glColor4f(color,color,color,0); 00344 } else glColor4f(0.5,0.5,0.5,0.5); 00345 for (int j=0;j<3;j++) { 00346 if (vertPotentials) { 00347 color = (m->f[i].v[j]->psiEdge + m->f[i].v[j]->psi)/delta; 00348 glColor4f(color,color,color,0); 00349 } 00350 if (vertGradients) { 00351 glColor4f(fabs(m->f[i].v[j]->gradPsi[0])/delta, 00352 fabs(m->f[i].v[j]->gradPsi[1])/delta, 00353 fabs(m->f[i].v[j]->gradPsi[2])/delta,0); 00354 } 00355 if (vertSteps) { 00356 color = m->f[i].v[j]->step*delta; 00357 glColor4f(color,color,color,0); 00358 } 00359 if (segment && 0) { 00360 if (m->f[i].flag < -1) { 00361 color = 1; 00362 glColor4f(color,color,color,0); 00363 } 00364 } 00365 if (!origMesh) 00366 glVertex3d(m->f[i].v[j]->x[0], m->f[i].v[j]->x[1], m->f[i].v[j]->x[2]); 00367 else 00368 glVertex3d(m->f[i].v[j]->x0[0], 00369 m->f[i].v[j]->x0[1], 00370 m->f[i].v[j]->x0[2]); 00371 } 00372 } 00373 glEnd(); 00374 } 00375 00376 // Draw the triangles 00377 if (segment && dm) { 00378 float color; 00379 glBegin(GL_TRIANGLES); 00380 for (int i=0;i<dm->nf;i++) { 00381 float* n; 00382 n = &(dm->f[i].n.x[0]); 00383 glNormal3d(n[0],n[1],n[2]); 00384 00385 if (faceColors) { 00386 glColor4f(n[0],n[1],n[2],0.5); 00387 } else glColor4f(0.5,0.5,0.5,0.5); 00388 for (int j=0;j<3;j++) { 00389 glVertex3d(dm->f[i].v[j]->x[0], 00390 dm->f[i].v[j]->x[1], 00391 dm->f[i].v[j]->x[2]); 00392 } 00393 } 00394 glEnd(); 00395 } 00396 // Draw the triangles 00397 if (keypoints && dm) { 00398 float color; 00399 glBegin(GL_POINTS); 00400 for (int i=0;i<dm->nf;i++) { 00401 glColor4f(1,1,1,0.5); 00402 for (int j=0;j<4;j++) { 00403 if (dm->f[i].v[j%3]->i == 141) 00404 glVertex3d(dm->f[i].v[j%3]->x[0], 00405 dm->f[i].v[j%3]->x[1], 00406 dm->f[i].v[j%3]->x[2]); 00407 } 00408 } 00409 glEnd(); 00410 } 00411 00412 // Draw the wireframe 00413 if (wireframe) { 00414 glBegin(GL_LINES); 00415 if (!edgeAngles) glColor4f(0,0,0,0.5); 00416 glNormal3d(0,0,0); 00417 for (int i=0;i<m->ne;i++) { 00418 if (segment) { 00419 if (m->e[i].flag == -1) 00420 continue; 00421 } 00422 if (edgeAngles) { 00423 float color = m->e[i].psi/delta; 00424 glColor4f(color,color,color,0); 00425 } 00426 if (!origMesh) { 00427 glVertex3d(m->e[i].v[0]->x[0], 00428 m->e[i].v[0]->x[1], 00429 m->e[i].v[0]->x[2]); 00430 glVertex3d(m->e[i].v[1]->x[0], 00431 m->e[i].v[1]->x[1], 00432 m->e[i].v[1]->x[2]); 00433 } else { 00434 glVertex3d(m->e[i].v[0]->x0[0], 00435 m->e[i].v[0]->x0[1], 00436 m->e[i].v[0]->x0[2]); 00437 glVertex3d(m->e[i].v[1]->x0[0], 00438 m->e[i].v[1]->x0[1], 00439 m->e[i].v[1]->x0[2]); 00440 } 00441 } 00442 glEnd(); 00443 } 00444 00445 // draw points flagged as boundary points between regions 00446 if (keypoints) { 00447 glBegin(GL_POINTS); 00448 glColor4f(1,1,1,0.5); 00449 for (int i=0;i<m->nv;i++) { 00450 if (m->v[i].flag < -3) { 00451 glVertex3d(m->v[i].x[0], 00452 m->v[i].x[1], 00453 m->v[i].x[2]); 00454 } 00455 } 00456 glEnd(); 00457 } 00458 00459 if (segment && 0) { 00460 glBegin(GL_POINTS); 00461 glColor4f(1,1,1,0.5); 00462 for (int i=0;i<m->nr;i++) { 00463 if (m->r[i].vi.size() > 0) { 00464 glVertex3d(m->v[m->r[i].vi[0]].x[0], 00465 m->v[m->r[i].vi[0]].x[1], 00466 m->v[m->r[i].vi[0]].x[2]); 00467 glVertex3d(m->v[m->r[i].vi.back()].x[0], 00468 m->v[m->r[i].vi.back()].x[1], 00469 m->v[m->r[i].vi.back()].x[2]); 00470 } 00471 } 00472 glEnd(); 00473 } 00474 00475 if (segment) { 00476 for (int i=0;i<m->nr;i++) { 00477 if (i>=m->nr) break; 00478 glBegin(GL_LINE_STRIP); 00479 float color = 0; 00480 glColor4f(color,color,color,0.5f); 00481 for(int j=0;j<m->r[i].vi.size();j++) { 00482 if (m->r[i].vi[j] == -1) { 00483 glEnd(); 00484 glBegin(GL_LINE_STRIP); 00485 continue; 00486 } else { 00487 glVertex3d(m->v[m->r[i].vi[j]].x[0], 00488 m->v[m->r[i].vi[j]].x[1], 00489 m->v[m->r[i].vi[j]].x[2]); 00490 } 00491 } 00492 glEnd(); 00493 } 00494 } 00495 00496 if (polyMesh) { 00497 for (int i=0;i<m->nr;i++) { 00498 glBegin(GL_POLYGON); 00499 if (faceColors) 00500 glColor4f(m->r[i].n.x[0],m->r[i].n.x[1],m->r[i].n.x[2],0.5); 00501 else 00502 glColor4f(0.50,0.50,0.50,0.5); 00503 glNormal3d(m->r[i].n.x[0],m->r[i].n.x[1],m->r[i].n.x[2]); 00504 for(int j=0;j<m->r[i].vi.size();j++) { 00505 if (m->r[i].vi[j] == -1) 00506 break; 00507 else 00508 glVertex3d(m->v[m->r[i].vi[j]].x[0], 00509 m->v[m->r[i].vi[j]].x[1], 00510 m->v[m->r[i].vi[j]].x[2]); 00511 } 00512 glEnd(); 00513 } 00514 } 00515 00516 // Draw the mesh boundary 00517 if (meshBoundary) { 00518 glBegin(GL_LINES); 00519 glColor4f(0,0,0,0.5); 00520 glNormal3d(0,0,0); 00521 for (int i=0;i<m->ne;i++) { 00522 if (m->e[i].nf == 1) { 00523 glVertex3d(m->e[i].v[0]->x[0], 00524 m->e[i].v[0]->x[1], 00525 m->e[i].v[0]->x[2]); 00526 glVertex3d(m->e[i].v[1]->x[0], 00527 m->e[i].v[1]->x[1], 00528 m->e[i].v[1]->x[2]); 00529 } 00530 } 00531 glEnd(); 00532 00533 glBegin(GL_POINTS); 00534 for (int i=0;i<m->nv;i++) { 00535 if (m->v[i].bound) { 00536 glVertex3d(m->v[i].x[0], 00537 m->v[i].x[1], 00538 m->v[i].x[2]); 00539 } 00540 } 00541 glEnd(); 00542 00543 glBegin(GL_TRIANGLES); 00544 glColor4f(1,1,1,0.5); 00545 for (int i=0;i<m->nf;i++) { 00546 if (m->f[i].bound) { 00547 glVertex3d(m->f[i].v[0]->x[0], 00548 m->f[i].v[0]->x[1], 00549 m->f[i].v[0]->x[2]); 00550 glVertex3d(m->f[i].v[1]->x[0], 00551 m->f[i].v[1]->x[1], 00552 m->f[i].v[1]->x[2]); 00553 glVertex3d(m->f[i].v[2]->x[0], 00554 m->f[i].v[2]->x[1], 00555 m->f[i].v[2]->x[2]); 00556 } 00557 } 00558 glEnd(); 00559 } 00560 00561 // Draw the gradient vector field 00562 if (vertGradVecs) { 00563 glBegin(GL_LINES); 00564 glColor4f(0,0,0,0.5); 00565 glNormal3d(0,0,0); 00566 for (int i=0;i<m->nv;i++) { 00567 glVertex3d(m->v[i].x[0],m->v[i].x[1],m->v[i].x[2]); 00568 glVertex3d(m->v[i].x[0]+m->v[i].gradPsi[0]/(2*delta), 00569 m->v[i].x[1]+m->v[i].gradPsi[1]/(2*delta), 00570 m->v[i].x[2]+m->v[i].gradPsi[2]/(2*delta)); 00571 } 00572 glEnd(); 00573 } 00574 00575 // Draw the vertex normal vector field 00576 if (vertNormals) { 00577 glBegin(GL_LINES); 00578 glColor4f(0,0,0,0.5); 00579 glNormal3d(0,0,0); 00580 for (int i=0;i<m->nv;i++) { 00581 glVertex3d(m->v[i].x[0],m->v[i].x[1],m->v[i].x[2]); 00582 glVertex3d(m->v[i].x[0]+m->v[i].n[0]/delta, 00583 m->v[i].x[1]+m->v[i].n[1]/delta, 00584 m->v[i].x[2]+m->v[i].n[2]/delta); 00585 } 00586 glEnd(); 00587 } 00588 00589 // Draw the face-to-face links 00590 if (face2face) { 00591 glBegin(GL_LINES); 00592 glColor4f(1.0,0,0,0); 00593 glNormal3d(0,0,0); 00594 for (int i=0;i<m->nf;i++) { 00595 for (int j=0;j<m->f[i].nf;j++) { 00596 glVertex3d(m->f[i].x[0],m->f[i].x[1],m->f[i].x[2]); 00597 glVertex3d(m->f[i].f[j]->x[0],m->f[i].f[j]->x[1],m->f[i].f[j]->x[2]); 00598 } 00599 } 00600 glEnd(); 00601 } 00602 00603 // Draw the face-to-vertex links 00604 if (face2vert) { 00605 glBegin(GL_LINES); 00606 glColor4f(0,1.0,0,0); 00607 glNormal3d(0,0,0); 00608 for (int i=0;i<m->nf;i++) { 00609 for (int j=0;j<3;j++) { 00610 glVertex3d(m->f[i].x[0],m->f[i].x[1],m->f[i].x[2]); 00611 glVertex3d(m->f[i].v[j]->x[0],m->f[i].v[j]->x[1],m->f[i].v[j]->x[2]); 00612 } 00613 } 00614 glEnd(); 00615 } 00616 00617 // Draw edge-to-face links 00618 if (edge2face) { 00619 glBegin(GL_LINES); 00620 glColor4f(1.0,0,0,0); 00621 glNormal3d(0,0,0); 00622 for (int i=0;i<m->ne;i++) { 00623 for (int j=0;j<m->e[i].nf;j++) { 00624 glVertex3d(0.5*(m->e[i].v[0]->x[0] + m->e[i].v[1]->x[0]), 00625 0.5*(m->e[i].v[0]->x[1] + m->e[i].v[1]->x[1]), 00626 0.5*(m->e[i].v[0]->x[2] + m->e[i].v[1]->x[2])); 00627 glVertex3d(m->e[i].f[j]->x[0],m->e[i].f[j]->x[1],m->e[i].f[j]->x[2]); 00628 } 00629 } 00630 glEnd(); 00631 } 00632 00633 // Draw face-to-edge links 00634 if (face2edge) { 00635 glBegin(GL_LINES); 00636 glColor4f(1.0,0,0,0); 00637 glNormal3d(0,0,0); 00638 for (int i=0;i<m->nf;i++) { 00639 for (int j=0;j<3;j++) { 00640 glVertex3d(m->f[i].x[0],m->f[i].x[1],m->f[i].x[2]); 00641 glVertex3d(0.5*(m->f[i].e[j]->v[0]->x[0] + m->f[i].e[j]->v[1]->x[0]), 00642 0.5*(m->f[i].e[j]->v[0]->x[1] + m->f[i].e[j]->v[1]->x[1]), 00643 0.5*(m->f[i].e[j]->v[0]->x[2] + m->f[i].e[j]->v[1]->x[2])); 00644 } 00645 } 00646 glEnd(); 00647 } 00648 00649 } 00650 00651 00652 // Displays everything to the screen 00653 void myGlutDisplay(void) { 00654 //glClearColor(.9f, .9f, .9f, 1.0f); 00655 glClearColor(0.3, 0.3, 0.3, 1.0f); 00656 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00657 00658 glMatrixMode(GL_PROJECTION); 00659 glLoadIdentity(); 00660 glFrustum(-xyAspect*.0008, xyAspect*.0008, -.0008, .0008, .01, 15.0); 00661 glMatrixMode(GL_MODELVIEW); 00662 00663 glLoadIdentity(); 00664 glTranslatef(0.0, 0.0, -1.2f); 00665 glRotatef(rotationX, 1.0, 0.0, 0.0); 00666 glRotatef(rotationY, 0.0, 1.0, 0.0); 00667 00668 // Render the center of rotation 00669 if (centerSphere || motionMode > 2) { 00670 glColor4f(1,0,0,0); 00671 glutSolidSphere(0.005,10,10); 00672 } 00673 00674 // Scale things according to zoom factor 00675 glScalef(scale, scale, scale); 00676 00677 // Render the mesh 00678 glTranslatef(-center[0], -center[1], -center[2]); 00679 drawMesh(); 00680 glTranslatef(center[0], center[1], center[2]); 00681 00682 // Disable lighting and set up ortho projection to render text 00683 glDisable(GL_LIGHTING); 00684 glMatrixMode(GL_PROJECTION); 00685 glLoadIdentity(); 00686 gluOrtho2D(0.0, 100.0, 0.0, 100.0); 00687 glMatrixMode(GL_MODELVIEW); 00688 glLoadIdentity(); 00689 glColor3ub(255,255,255); 00690 glRasterPos2i(10, 10); 00691 00692 // Render the live character array 'text' 00693 for(int i=0;i<(int)strlen(text);i++) 00694 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, text[i]); 00695 00696 glEnable(GL_LIGHTING); 00697 00698 glutSwapBuffers(); 00699 } 00700 00701 void saveOptions() { 00702 cout << "- Saving GUI options..." << flush; 00703 ofstream fout("gui_options.dat"); 00704 if (fout) { 00705 // Window details 00706 fout << glutGet(GLUT_WINDOW_X) - bdx << " "; 00707 fout << glutGet(GLUT_WINDOW_Y) - bdy << endl; 00708 fout << glutGet(GLUT_WINDOW_WIDTH) << " "; 00709 fout << glutGet(GLUT_WINDOW_HEIGHT) << endl; 00710 fout << cx0 << endl; 00711 fout << cy0 << endl; 00712 00713 // Viewpoint variables 00714 fout << center[0] << " "; 00715 fout << center[1] << " "; 00716 fout << center[2] << endl; 00717 fout << rotationX << " "; 00718 fout << rotationY << endl; 00719 fout << scale << endl; 00720 fout << delta << endl; 00721 00722 // Visuals 00723 fout << currMesh << endl; 00724 fout << origMesh << endl; 00725 fout << wireframe << endl; 00726 fout << face2face << endl; 00727 fout << face2vert << endl; 00728 fout << edgeAngles << endl; 00729 fout << vertPotentials << endl; 00730 fout << vertGradients << endl; 00731 fout << faceColors << endl; 00732 fout << centerSphere << endl; 00733 fout << meshBoundary << endl; 00734 fout << vertGradVecs << endl; 00735 fout << segment << endl; 00736 fout << diffuseIntensity << endl; 00737 fout << ambientIntensity << endl; 00738 } 00739 00740 fout.close(); 00741 cout << "Done." << endl << flush; 00742 } 00743 00744 void loadOptions() { 00745 cout << "- Loading GUI options..." << flush; 00746 ifstream fin("gui_options.dat"); 00747 if (fin) { 00748 // Window details 00749 fin >> wx0; 00750 fin >> wy0; 00751 fin >> wdx; 00752 fin >> wdy; 00753 fin >> cx0; 00754 fin >> cy0; 00755 00756 // Viewpoint variables 00757 fin >> center[0]; 00758 fin >> center[1]; 00759 fin >> center[2]; 00760 fin >> rotationX; 00761 fin >> rotationY; 00762 fin >> scale; 00763 fin >> delta; 00764 00765 // Visuals 00766 fin >> currMesh; 00767 fin >> origMesh; 00768 fin >> wireframe; 00769 fin >> face2face; 00770 fin >> face2vert; 00771 fin >> edgeAngles; 00772 fin >> vertPotentials; 00773 fin >> vertGradients; 00774 fin >> faceColors; 00775 fin >> centerSphere; 00776 fin >> meshBoundary; 00777 fin >> vertGradVecs; 00778 fin >> segment; 00779 fin >> diffuseIntensity; 00780 fin >> ambientIntensity; 00781 } 00782 00783 for (int i=0;i<3;i++) { 00784 light_diffuse[i] = float(diffuseIntensity)/100.0f; 00785 light_ambient[i] = float(ambientIntensity)/100.0f; 00786 } 00787 gs2 = m->gs2; 00788 gsn2 = m->gsn2; 00789 fin.close(); 00790 cout << "Done." << endl << flush; 00791 } 00792 00793 void update(void) { 00794 sprintf(text,"Potential: %.2f",m->psi); 00795 myGlutDisplay(); 00796 } 00797 00798 // Starts the graphical user interface 00799 int startGUI(Mesh *m_) { 00800 // Set local variables to passed values 00801 m = m_; 00802 sprintf(text,"Potential: %.2f",m->psi); 00803 m->registerCB(update); 00804 00805 // Load options file 00806 loadOptions(); 00807 00809 // Initialize GLUT and create window // 00811 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 00812 glutInitWindowPosition(wx0, wy0); 00813 glutInitWindowSize(wdx, wdy); 00814 00815 main_window = glutCreateWindow("ViewMesh 1.0"); 00816 glutDisplayFunc(myGlutDisplay); 00817 glutReshapeFunc(myGlutReshape); 00818 glutKeyboardFunc(myGlutKeyboard); 00819 glutMotionFunc(myGlutMotion); 00820 glutMouseFunc(myGlutMouse); 00821 00822 // Set up OpenGL lights 00823 glEnable(GL_LIGHTING); 00824 glEnable(GL_NORMALIZE); 00825 00826 glEnable(GL_LIGHT0); 00827 glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); 00828 glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); 00829 glLightfv(GL_LIGHT0, GL_POSITION, light_position); 00830 00831 // Set up OpenGL materials 00832 glEnable(GL_COLOR_MATERIAL); 00833 00834 // Make sure lines appear above polygons 00835 //glPolygonOffset(10.0,10.0); 00836 //glEnable(GL_POLYGON_OFFSET_FILL); 00837 glDisable(GL_POLYGON_OFFSET_FILL); 00838 00839 // Enable z-buferring and others 00840 glEnable(GL_DEPTH_TEST); 00841 glClearDepth(1.0f); 00842 glDepthFunc(GL_LEQUAL); 00843 glPointSize(4); 00844 //glEnable(GL_CULL_FACE); 00845 00846 00848 // Here's the GLUI code // 00850 cout << "- Starting GLUI version " << GLUI_Master.get_version() << endl; 00851 00852 // name, flags, x, and y 00853 glui = GLUI_Master.create_glui("Control Panel", cx0, cy0, 0); 00854 00855 glui->add_statictext("ViewMesh 1.0"); 00856 visualsRollout = glui->add_rollout("Visuals", true); 00857 00858 // Control for the visual display 00859 glui->add_checkbox_to_panel 00860 (visualsRollout,"Current Mesh",&currMesh,0, NULL); 00861 glui->add_checkbox_to_panel 00862 (visualsRollout,"Original Mesh",&origMesh,0, NULL); 00863 glui->add_checkbox_to_panel 00864 (visualsRollout,"Wireframe",&wireframe,0, NULL); 00865 glui->add_checkbox_to_panel 00866 (visualsRollout,"Face-to-Face",&face2face,0, NULL); 00867 glui->add_checkbox_to_panel 00868 (visualsRollout,"Face-to-Vertex",&face2vert,0, NULL); 00869 glui->add_checkbox_to_panel 00870 (visualsRollout,"Edge Angles",&edgeAngles,0, NULL); 00871 glui->add_checkbox_to_panel 00872 (visualsRollout,"Vert Potentials",&vertPotentials,0, NULL); 00873 glui->add_checkbox_to_panel 00874 (visualsRollout,"Vert Gradients",&vertGradients,0, NULL); 00875 glui->add_checkbox_to_panel 00876 (visualsRollout,"Face Colors",&faceColors,0, NULL); 00877 glui->add_checkbox_to_panel 00878 (visualsRollout,"Center Sphere",¢erSphere,0, NULL); 00879 glui->add_checkbox_to_panel 00880 (visualsRollout,"Mesh Boundary",&meshBoundary,0, NULL); 00881 glui->add_checkbox_to_panel 00882 (visualsRollout,"Vert Normals",&vertNormals,0, NULL); 00883 glui->add_checkbox_to_panel 00884 (visualsRollout,"Vert Grad Vecs",&vertGradVecs,0, NULL); 00885 glui->add_checkbox_to_panel 00886 (visualsRollout,"Face Areas",&faceAreas,0, NULL); 00887 glui->add_checkbox_to_panel 00888 (visualsRollout,"Vert Steps",&vertSteps,0, NULL); 00889 glui->add_checkbox_to_panel 00890 (visualsRollout,"Segmentation",&segment,0, NULL); 00891 glui->add_checkbox_to_panel 00892 (visualsRollout,"Key Points",&keypoints,0, NULL); 00893 glui->add_checkbox_to_panel 00894 (visualsRollout,"PolyMesh",&polyMesh,0, NULL); 00895 00896 // Add some controls for lights 00897 diffuseSpinner = glui->add_spinner_to_panel 00898 (visualsRollout, "Diffuse:", GLUI_SPINNER_INT, 00899 &diffuseIntensity,250,controlCB); 00900 diffuseSpinner->set_int_limits(0, 100); 00901 ambientSpinner = glui->add_spinner_to_panel 00902 (visualsRollout, "Ambient:", GLUI_SPINNER_INT, 00903 &ambientIntensity,250,controlCB); 00904 ambientSpinner->set_int_limits(0, 100); 00905 00906 deltaSpinner = glui->add_spinner_to_panel 00907 (visualsRollout, "Delta:", GLUI_SPINNER_FLOAT, 00908 &delta,0,controlCB); 00909 deltaSpinner->set_float_limits(0,100); 00910 00911 gs2Spinner = glui->add_spinner_to_panel 00912 (visualsRollout, "Vert Var:", GLUI_SPINNER_FLOAT, 00913 &gs2,251,controlCB); 00914 gs2Spinner->set_float_limits(0,1000); 00915 00916 gsn2Spinner = glui->add_spinner_to_panel 00917 (visualsRollout, "Normal Var:", GLUI_SPINNER_FLOAT, 00918 &gsn2,251,controlCB); 00919 gsn2Spinner->set_float_limits(0,2); 00920 00921 // Recenter button 00922 glui->add_button("Recenter",150,controlCB); 00923 // A 'run' button 00924 glui->add_button("Run",151,controlCB); 00925 glui->add_button("Run Anneal",154,controlCB); 00926 glui->add_button("Reset",152,controlCB); 00927 glui->add_button("Segment",155,controlCB); 00928 glui->add_button("Tessellate",157,controlCB); 00929 00930 // Save mesh button 00931 glui->add_button("Save Mesh", 156,controlCB); 00932 00933 // Save options button 00934 glui->add_button("Save Options",100,controlCB); 00935 // A 'quit' button 00936 glui->add_button("Quit", -1,controlCB); 00937 00938 // Link windows to GLUI, and register idle callback 00939 glui->set_main_gfx_window(main_window); 00940 00941 // We register the idle callback with GLUI, not with GLUT 00942 GLUI_Master.set_glutIdleFunc(myGlutIdle); 00943 00944 // Regular GLUT main loop 00945 glutMainLoop(); 00946 00947 return 0; 00948 }