Surface
detect surface points in an image stack
|
00001 /* 00002 * This work is licensed under a Creative Commons 00003 * Attribution-Noncommercial-Share Alike 3.0 United States License. 00004 * 00005 * http://creativecommons.org/licenses/by-nc-sa/3.0/us/ 00006 * 00007 * You are free: 00008 * 00009 * to Share - to copy, distribute, display, and perform the work 00010 * to Remix - to make derivative works 00011 * 00012 * Under the following conditions: 00013 * 00014 * Attribution. You must attribute the work in the manner specified by the 00015 * author or licensor (but not in any way that suggests that they endorse you 00016 * or your use of the work). 00017 * 00018 * Noncommercial. You may not use this work for commercial purposes. 00019 * 00020 * Share Alike. If you alter, transform, or build upon this work, you may 00021 * distribute the resulting work only under the same or similar license to 00022 * this one. 00023 * 00024 * For any reuse or distribution, you must make clear to others the license 00025 * terms of this work. The best way to do this is by including this header. 00026 * 00027 * Any of the above conditions can be waived if you get permission from the 00028 * copyright holder. 00029 * 00030 * Apart from the remix rights granted under this license, nothing in this 00031 * license impairs or restricts the author's moral rights. 00032 */ 00033 00034 00046 #include <config.h> 00047 00048 #include <cstdlib> 00049 #include <cstdio> 00050 #include <cassert> 00051 #include <cstring> 00052 #include <iostream> 00053 #include <sstream> 00054 #include <vector> 00055 00056 #include <inttypes.h> 00057 00058 #if defined SURFACE_HAVE_OPENGL 00059 #include <GL/gl.h> 00060 #include <GL/glu.h> 00061 #endif 00062 00063 #if defined SURFACE_HAVE_GLUT_FRAMEWORK 00064 #include <GLUT/glut.h> 00065 #elif defined SURFACE_HAVE_GLUT 00066 #include <GL/glut.h> 00067 #endif 00068 00069 #ifdef SURFACE_HAVE_DMALLOC 00070 #include <dmalloc.h> 00071 #endif 00072 00073 #include <jwsc/math/constants.h> 00074 #include <jwsc/vector/vector.h> 00075 #include <jwsc/vector/vector_math.h> 00076 #include <jwsc/matrix/matrix.h> 00077 #include <jwsc/matrix/matrix_math.h> 00078 #include <jwsc/image/image.h> 00079 #include <jwsc/image/image_io.h> 00080 #include <jwsc/imgblock/surface.h> 00081 00082 #include <jwsc++/base/option.h> 00083 #include <jwsc++/base/exception.h> 00084 #include <jwsc++/graphics/camera.h> 00085 00086 00087 /* Anaglyph glasses filter types. */ 00088 #define REDBLUE 1 00089 #define REDGREEN 2 00090 #define REDCYAN 3 00091 #define BLUERED 4 00092 #define GREENRED 5 00093 #define CYANRED 6 00094 00095 /* Program defaults. */ 00096 #define VIEW_WIDTH 800 00097 #define VIEW_HEIGHT 800 00098 #define APERTURE 60.0f 00099 #define CLIP_NEAR 10.0f 00100 #define CLIP_FAR 3000.0f 00101 #define GLASSES_TYPE REDCYAN 00102 #define CAPTURE_FNAME "capture.tiff" 00103 #define PATCH_SIZE 2.0 00104 #define SURFACE_SCALE 1.0 00105 #define X_SCALE 1.0 00106 #define Y_SCALE 1.0 00107 #define Z_SCALE 1.4 00108 #define SAMPLE_RATE 1.0 00109 00110 00111 using std::cout; 00112 using std::cerr; 00113 using std::ostringstream; 00114 using std::sscanf; 00115 using std::sprintf; 00116 using std::vector; 00117 using namespace jwsc; 00118 using jwscxx::base::Options; 00119 using jwscxx::base::Exception; 00120 using jwscxx::base::Arg_error; 00121 using jwscxx::graphics::Stereo_camera_f; 00122 00123 00125 Options* opts = 0; 00126 00128 uint32_t view_width = VIEW_WIDTH; 00129 00131 uint32_t view_height = VIEW_HEIGHT; 00132 00134 float aperture = APERTURE; 00135 00137 float clip_near = CLIP_NEAR; 00138 00140 float clip_far = CLIP_FAR; 00141 00143 int glasses_type = GLASSES_TYPE; 00144 00146 const char* capture_fname = CAPTURE_FNAME; 00147 00149 float surface_scale = SURFACE_SCALE; 00150 00152 float surface_patch_size = PATCH_SIZE; 00153 00158 float x_scale = X_SCALE; 00159 00164 float y_scale = Y_SCALE; 00165 00170 float z_scale = Z_SCALE; 00171 00177 float sample_rate = SAMPLE_RATE; 00178 00180 Stereo_camera_f* camera = 0; 00181 00183 GLUquadric* quad_fill = 0; 00184 00186 list<Surface_patch_f*>* surface = 0; 00187 00189 Vector_f* patch_offset = 0; 00190 00191 00197 struct Surface_viewer_modes 00198 { 00200 bool translate_camera; 00201 00203 bool rotate_camera; 00204 00206 bool capture_view; 00207 00212 bool anaglyph; 00213 00215 bool render_focal_plane; 00216 00218 bool render_world_axis; 00219 00221 bool focal_prp; 00222 00224 bool focal_vrp; 00225 } 00226 modes; 00227 00229 void init_modes() 00230 { 00231 modes.translate_camera = false; 00232 modes.rotate_camera = true; 00233 modes.capture_view = false; 00234 modes.anaglyph = false; 00235 modes.render_focal_plane = false; 00236 modes.render_world_axis = true; 00237 modes.focal_prp = false; 00238 modes.focal_vrp = true; 00239 } 00240 00242 void init_camera() throw (Arg_error) 00243 { 00244 delete camera; 00245 00246 camera = new Stereo_camera_f(0, 50, 300, 0, 50, 0, 0, 1, 0, 00247 aperture, clip_near, clip_far); 00248 } 00249 00251 void reset() 00252 { 00253 surface_scale = SURFACE_SCALE; 00254 aperture = APERTURE; 00255 init_camera(); 00256 init_modes(); 00257 } 00258 00260 void capture_view() 00261 { 00262 static uint32_t capture_num = 1; 00263 00264 char fname_buf [ 256 ] = { 0 }; 00265 char fname_suffix_buf[ 256 ] = { 0 }; 00266 char* fname_suffix; 00267 00268 strncpy(fname_buf, capture_fname, 250); 00269 00270 if ((fname_suffix = strstr(fname_buf, ".")) != NULL) 00271 { 00272 strncpy(fname_suffix_buf, fname_suffix, 250); 00273 } 00274 else 00275 { 00276 fname_suffix = fname_buf + strlen(fname_buf); 00277 } 00278 00279 sprintf(fname_suffix, "-%04d%s", capture_num, fname_suffix_buf); 00280 00281 camera->capture_gl_view(fname_buf, capture_num); 00282 00283 capture_num++; 00284 } 00285 00287 void render_world_axis() 00288 { 00289 static GLfloat amb_dif[4] = {0, 0, 0, 1.0f}; 00290 00291 glMatrixMode(GL_MODELVIEW); 00292 00293 glPushMatrix(); 00294 00295 float axis_length = 100.0f; 00296 float arrow_radius = axis_length / 10.0f; 00297 float arrow_height = axis_length / 5.0f; 00298 00299 /* X */ 00300 amb_dif[0] = 0.9f; amb_dif[1] = 1.0f; amb_dif[2] = 0.3f; 00301 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00302 glPushMatrix(); 00303 glRotatef(90, 0, 1.0f, 0); 00304 gluCylinder(quad_fill, 1, 1, axis_length - 0.5f*arrow_height, 8, 1); 00305 glPopMatrix(); 00306 glPushMatrix(); 00307 glTranslatef(axis_length - arrow_height, 0, 0); 00308 glRotatef(90, 0, 1.0f, 0); 00309 gluCylinder(quad_fill, arrow_radius, 0, arrow_height, 16, 8); 00310 glPopMatrix(); 00311 00312 /* Y */ 00313 amb_dif[0] = 0.9f; amb_dif[1] = 1.0f; amb_dif[2] = 0.3f; 00314 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00315 glPushMatrix(); 00316 glRotatef(-90, 1.0f, 0, 0); 00317 gluCylinder(quad_fill, 1, 1, axis_length - 0.5f*arrow_height, 8, 1); 00318 glPopMatrix(); 00319 glPushMatrix(); 00320 glTranslatef(0, axis_length - arrow_height, 0); 00321 glRotatef(-90, 1.0f, 0, 0); 00322 gluCylinder(quad_fill, arrow_radius, 0, arrow_height, 16, 8); 00323 glPopMatrix(); 00324 00325 /* Z */ 00326 amb_dif[0] = 0.9f; amb_dif[1] = 1.0f; amb_dif[2] = 0.3f; 00327 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00328 gluCylinder(quad_fill, 1, 1, axis_length - 0.5f*arrow_height, 8, 1); 00329 glPushMatrix(); 00330 glTranslatef(0, 0, axis_length - arrow_height); 00331 gluCylinder(quad_fill, arrow_radius, 0, arrow_height, 16, 8); 00332 glPopMatrix(); 00333 00334 glPopMatrix(); 00335 } 00336 00338 void render_focal_plane() 00339 { 00340 static GLfloat amb_dif[4] = {0.7f, 0.6f, 0.5f, 0.2f}; 00341 GLboolean prev_blend; 00342 GLint prev_blend_src; 00343 GLint prev_blend_dst; 00344 00345 if ((prev_blend = glIsEnabled(GL_BLEND))) 00346 { 00347 glGetIntegerv(GL_BLEND_SRC, &prev_blend_src); 00348 glGetIntegerv(GL_BLEND_DST, &prev_blend_dst); 00349 } 00350 else 00351 { 00352 glEnable(GL_BLEND); 00353 } 00354 glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA); 00355 00356 glMatrixMode(GL_MODELVIEW); 00357 00358 glPushMatrix(); 00359 glLoadIdentity(); 00360 00361 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00362 00363 float x = 200.0f; 00364 float y = 200.0f; 00365 float z = -camera->get_focal_length(); 00366 00367 glBegin(GL_POLYGON); 00368 glNormal3f( 0, 0, 1); 00369 glVertex3f( x, y, z); 00370 glVertex3f(-x, y, z); 00371 glVertex3f(-x, -y, z); 00372 glVertex3f( x, -y, z); 00373 glEnd(); 00374 00375 glPopMatrix(); 00376 00377 if (prev_blend) 00378 { 00379 glBlendFunc(prev_blend_src, prev_blend_dst); 00380 } 00381 else 00382 { 00383 glDisable(GL_BLEND); 00384 } 00385 } 00386 00388 void render_scene() 00389 { 00390 static GLfloat amb_dif[4] = {0, 0, 0, 1.0f}; 00391 00392 glMatrixMode(GL_MODELVIEW); 00393 00394 glPushMatrix(); 00395 00396 glScalef(surface_scale, surface_scale, surface_scale); 00397 00398 glTranslatef(-patch_offset->elts[0], 00399 -patch_offset->elts[1], 00400 -patch_offset->elts[2]); 00401 00402 // Render the surface patches. 00403 list<Surface_patch_f*>::iterator it; 00404 for (it = surface->begin(); it != surface->end(); it++) 00405 { 00406 const Surface_patch_f* patch = *it; 00407 00408 amb_dif[0] = 3*patch->albedo*0.78f; 00409 amb_dif[1] = 3*patch->albedo*0.6f; 00410 amb_dif[2] = 3*patch->albedo*0.2f; 00411 /* 00412 amb_dif[0] = 4*patch->albedo*0.1f; 00413 amb_dif[1] = 4*patch->albedo*1.0f; 00414 amb_dif[2] = 4*patch->albedo*0.1f; 00415 */ 00416 00417 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00418 00419 glNormal3f(patch->normal->elts[0], patch->normal->elts[1], 00420 patch->normal->elts[2]); 00421 00422 glBegin(GL_POLYGON); 00423 for (int i = 0; i < 4; i++) 00424 { 00425 const Vector_f* point = patch->pts[ i ]; 00426 glVertex3f(point->elts[0], point->elts[1], point->elts[2]); 00427 } 00428 glEnd(); 00429 } 00430 00431 glPopMatrix(); 00432 } 00433 00435 void display_glut_anaglyph() 00436 { 00437 /* Set the buffer for reading and writing. Using double buffering. */ 00438 glDrawBuffer(GL_BACK); 00439 glReadBuffer(GL_BACK); 00440 00441 /* Clear things */ 00442 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); 00443 00444 /* Left camera filter. */ 00445 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00446 switch (glasses_type) 00447 { 00448 case REDBLUE: 00449 case REDGREEN: 00450 case REDCYAN: 00451 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); 00452 break; 00453 case BLUERED: 00454 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE); 00455 break; 00456 case GREENRED: 00457 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE); 00458 break; 00459 case CYANRED: 00460 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE); 00461 break; 00462 } 00463 00464 /* Set the left camera projection. */ 00465 camera->set_left_gl_projection(); 00466 00467 /* Set the camera model view. */ 00468 camera->set_left_gl_modelview(); 00469 00470 /* Render the world axis. */ 00471 if (modes.render_world_axis) 00472 { 00473 render_world_axis(); 00474 } 00475 00476 render_scene(); 00477 00478 /* Render the focal plane if in that mode. */ 00479 if (modes.render_focal_plane) 00480 { 00481 render_focal_plane(); 00482 } 00483 00484 glFlush(); 00485 00486 glAccum(GL_LOAD, 0.5f); 00487 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 00488 00489 /* Right camera filter. */ 00490 switch (glasses_type) 00491 { 00492 case REDBLUE: 00493 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE); 00494 break; 00495 case REDGREEN: 00496 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE); 00497 break; 00498 case REDCYAN: 00499 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE); 00500 break; 00501 case BLUERED: 00502 case GREENRED: 00503 case CYANRED: 00504 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); 00505 break; 00506 } 00507 00508 /* Set the right camera projection. */ 00509 camera->set_right_gl_projection(); 00510 00511 /* Set the camera model view. */ 00512 camera->set_right_gl_modelview(); 00513 00514 /* Render the world axis. */ 00515 if (modes.render_world_axis) 00516 { 00517 render_world_axis(); 00518 } 00519 00520 render_scene(); 00521 00522 /* Render the focal plane if in that mode. */ 00523 if (modes.render_focal_plane) 00524 { 00525 render_focal_plane(); 00526 } 00527 00528 glFlush(); 00529 00531 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00532 00533 glAccum(GL_ACCUM, 0.5f); 00534 glAccum(GL_RETURN, 2.0f); 00535 } 00536 00540 void display_glut_regular() 00541 { 00542 /* Set the buffer for writing. Using double buffering. */ 00543 glDrawBuffer(GL_BACK); 00544 glReadBuffer(GL_BACK); 00545 00546 /* Clear things */ 00547 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00548 00549 /* Set the camera projection. */ 00550 camera->set_gl_projection(); 00551 00552 /* Set the camera model view. */ 00553 camera->set_gl_modelview(); 00554 00555 /* Render the world axis. */ 00556 if (modes.render_world_axis) 00557 { 00558 render_world_axis(); 00559 } 00560 00561 render_scene(); 00562 00563 /* Render the focal plane if in that mode. */ 00564 if (modes.render_focal_plane) 00565 { 00566 render_focal_plane(); 00567 } 00568 00569 glFlush(); 00570 } 00571 00573 void display_glut() 00574 { 00575 if (modes.anaglyph) 00576 { 00577 display_glut_anaglyph(); 00578 } 00579 else 00580 { 00581 display_glut_regular(); 00582 } 00583 00584 glutSwapBuffers(); 00585 00586 if (modes.capture_view) 00587 { 00588 capture_view(); 00589 modes.capture_view = 0; 00590 } 00591 } 00592 00594 void reshape_glut(int w, int h) 00595 { 00596 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00597 glViewport(0, 0, (GLsizei)w, (GLsizei)h); 00598 view_width = w; 00599 view_height = h; 00600 } 00601 00603 void keyboard_glut(unsigned char key, int a, int b) 00604 { 00605 float translate_delta = 10; 00606 float rotate_delta = 10*JWSC_DEG_TO_RAD; 00607 float focal_length; 00608 float theta; 00609 00610 Vector_f* v_tmp = 0; 00611 00612 switch (key) { 00613 case 't': 00614 modes.translate_camera = 1; 00615 modes.rotate_camera = 0; 00616 break; 00617 case 'r': 00618 modes.rotate_camera = 1; 00619 modes.translate_camera = 0; 00620 break; 00621 case 'l': 00622 if (modes.translate_camera) 00623 { 00624 const Vector_f* right = camera->get_u(); 00625 camera->translate( 00626 translate_delta * right->elts[0], 00627 translate_delta * right->elts[1], 00628 translate_delta * right->elts[2]); 00629 } 00630 else if (modes.rotate_camera) 00631 { 00632 camera->rotate(-rotate_delta, 0, 1, 0); 00633 } 00634 glutPostRedisplay(); 00635 break; 00636 case 'h': 00637 if (modes.translate_camera) 00638 { 00639 const Vector_f* right = camera->get_u(); 00640 camera->translate( 00641 -translate_delta * right->elts[0], 00642 -translate_delta * right->elts[1], 00643 -translate_delta * right->elts[2]); 00644 } 00645 else if (modes.rotate_camera) 00646 { 00647 camera->rotate(rotate_delta, 0, 1, 0); 00648 } 00649 glutPostRedisplay(); 00650 break; 00651 case 'L': 00652 if (modes.translate_camera) 00653 { 00654 const Vector_f* right = camera->get_u(); 00655 camera->translate( 00656 translate_delta * right->elts[0], 00657 translate_delta * right->elts[1], 00658 translate_delta * right->elts[2]); 00659 } 00660 else if (modes.rotate_camera) 00661 { 00662 copy_vector_f(&v_tmp, camera->get_prp()); 00663 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00664 camera->translate(v_tmp); 00665 camera->rotate(rotate_delta, camera->get_v()); 00666 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00667 camera->translate(v_tmp); 00668 } 00669 glutPostRedisplay(); 00670 break; 00671 case 'H': 00672 if (modes.translate_camera) 00673 { 00674 const Vector_f* right = camera->get_u(); 00675 camera->translate( 00676 -translate_delta * right->elts[0], 00677 -translate_delta * right->elts[1], 00678 -translate_delta * right->elts[2]); 00679 } 00680 else if (modes.rotate_camera) 00681 { 00682 copy_vector_f(&v_tmp, camera->get_prp()); 00683 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00684 camera->translate(v_tmp); 00685 camera->rotate(-rotate_delta, camera->get_v()); 00686 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00687 camera->translate(v_tmp); 00688 } 00689 glutPostRedisplay(); 00690 break; 00691 case 'k': 00692 if (modes.translate_camera) 00693 { 00694 const Vector_f* up = camera->get_v(); 00695 camera->translate( 00696 translate_delta * up->elts[0], 00697 translate_delta * up->elts[1], 00698 translate_delta * up->elts[2]); 00699 } 00700 else if (modes.rotate_camera) 00701 { 00702 camera->rotate(rotate_delta, camera->get_u()); 00703 } 00704 glutPostRedisplay(); 00705 break; 00706 case 'j': 00707 if (modes.translate_camera) 00708 { 00709 const Vector_f* up = camera->get_v(); 00710 camera->translate( 00711 -translate_delta * up->elts[0], 00712 -translate_delta * up->elts[1], 00713 -translate_delta * up->elts[2]); 00714 } 00715 else if (modes.rotate_camera) 00716 { 00717 camera->rotate(-rotate_delta, camera->get_u()); 00718 } 00719 glutPostRedisplay(); 00720 break; 00721 case 'K': 00722 if (modes.translate_camera) 00723 { 00724 const Vector_f* view = camera->get_n(); 00725 camera->translate( 00726 -translate_delta * view->elts[0], 00727 -translate_delta * view->elts[1], 00728 -translate_delta * view->elts[2]); 00729 } 00730 else if (modes.rotate_camera) 00731 { 00732 copy_vector_f(&v_tmp, camera->get_prp()); 00733 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00734 camera->translate(v_tmp); 00735 camera->rotate(-rotate_delta, camera->get_u()); 00736 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00737 camera->translate(v_tmp); 00738 } 00739 glutPostRedisplay(); 00740 break; 00741 case 'J': 00742 if (modes.translate_camera) 00743 { 00744 const Vector_f* view = camera->get_n(); 00745 camera->translate( 00746 translate_delta * view->elts[0], 00747 translate_delta * view->elts[1], 00748 translate_delta * view->elts[2]); 00749 } 00750 else if (modes.rotate_camera) 00751 { 00752 copy_vector_f(&v_tmp, camera->get_prp()); 00753 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00754 camera->translate(v_tmp); 00755 camera->rotate(rotate_delta, camera->get_u()); 00756 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00757 camera->translate(v_tmp); 00758 } 00759 glutPostRedisplay(); 00760 break; 00761 case 'F': 00762 if (modes.focal_prp) 00763 { 00764 focal_length = camera->get_focal_length() + 20; 00765 camera->set_f_with_same_aperture_using_prp(focal_length); 00766 } 00767 else if (modes.focal_vrp) 00768 { 00769 focal_length = camera->get_focal_length() + 20; 00770 camera->set_f_with_same_aperture_using_vrp(focal_length); 00771 } 00772 glutPostRedisplay(); 00773 break; 00774 case 'f': 00775 if (modes.focal_prp) 00776 { 00777 focal_length = camera->get_focal_length(); 00778 if (focal_length >= 22) 00779 { 00780 focal_length -= 20; 00781 camera->set_f_with_same_aperture_using_prp(focal_length); 00782 } 00783 } 00784 else if (modes.focal_vrp) 00785 { 00786 focal_length = camera->get_focal_length(); 00787 if (focal_length >= 22) 00788 { 00789 focal_length -= 20; 00790 camera->set_f_with_same_aperture_using_vrp(focal_length); 00791 } 00792 } 00793 glutPostRedisplay(); 00794 break; 00795 case 'S': 00796 if (surface_scale >= 2.99f) 00797 { 00798 surface_scale = 3.0f; 00799 } 00800 else 00801 { 00802 surface_scale += 0.01f; 00803 } 00804 glutPostRedisplay(); 00805 break; 00806 case 's': 00807 if (surface_scale > 0.01f) 00808 { 00809 surface_scale -= 0.01f; 00810 } 00811 glutPostRedisplay(); 00812 break; 00813 case 'A': 00814 aperture += JWSC_PI_8; 00815 camera->set_aperture(aperture); 00816 glutPostRedisplay(); 00817 break; 00818 case 'a': 00819 theta = aperture - JWSC_PI_8; 00820 if (theta >= 0) 00821 { 00822 aperture = theta; 00823 camera->set_aperture(theta); 00824 } 00825 glutPostRedisplay(); 00826 break; 00827 case 'c': 00828 modes.capture_view = 1; 00829 glutPostRedisplay(); 00830 break; 00831 case 'o': 00832 reset(); 00833 glutPostRedisplay(); 00834 break; 00835 case 'q': 00836 exit(EXIT_SUCCESS); 00837 } 00838 00839 free_vector_f(v_tmp); 00840 } 00841 00843 void main_menu_glut(int id) 00844 { 00845 switch (id) 00846 { 00847 case 0: 00848 modes.capture_view = 1; 00849 glutPostRedisplay(); 00850 break; 00851 case 1: 00852 reset(); 00853 glutPostRedisplay(); 00854 break; 00855 case 2: 00856 exit(EXIT_SUCCESS); 00857 } 00858 } 00859 00861 void option_menu_glut(int id) 00862 { 00863 switch (id) 00864 { 00865 case 0: 00866 modes.anaglyph = !modes.anaglyph; 00867 glutPostRedisplay(); 00868 break; 00869 case 1: 00870 modes.render_focal_plane = !modes.render_focal_plane; 00871 glutPostRedisplay(); 00872 break; 00873 case 2: 00874 modes.render_world_axis = !modes.render_world_axis; 00875 glutPostRedisplay(); 00876 break; 00877 } 00878 } 00879 00881 void navigation_menu_glut(int id) 00882 { 00883 switch (id) 00884 { 00885 case 0: 00886 modes.rotate_camera = true; 00887 modes.translate_camera = false; 00888 break; 00889 case 1: 00890 modes.rotate_camera = false; 00891 modes.translate_camera = true; 00892 break; 00893 case 2: 00894 modes.rotate_camera = false; 00895 modes.translate_camera = false; 00896 break; 00897 } 00898 } 00899 00901 void focal_length_menu_glut(int id) 00902 { 00903 switch (id) 00904 { 00905 case 0: 00906 modes.focal_prp = true; 00907 modes.focal_vrp = false; 00908 break; 00909 case 1: 00910 modes.focal_prp = false; 00911 modes.focal_vrp = true; 00912 break; 00913 } 00914 } 00915 00917 void init_glut(int argc, char** argv) 00918 { 00919 glutInit(&argc, (char**)argv); 00920 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_ACCUM 00921 | GLUT_ALPHA); 00922 glutInitWindowSize(view_width, view_height); 00923 glutCreateWindow("Surface Viewer"); 00924 glutDisplayFunc(display_glut); 00925 glutReshapeFunc(reshape_glut); 00926 glutKeyboardFunc(keyboard_glut); 00927 00928 int navigation = glutCreateMenu(navigation_menu_glut); 00929 glutAddMenuEntry("Rotate Camera", 0); 00930 glutAddMenuEntry("Translate Camera", 1); 00931 glutAddMenuEntry("Modify Structure", 2); 00932 00933 int focal_length = glutCreateMenu(focal_length_menu_glut); 00934 glutAddMenuEntry("PRP", 0); 00935 glutAddMenuEntry("VRP", 1); 00936 00937 int options = glutCreateMenu(option_menu_glut); 00938 glutAddMenuEntry("Anaglyph", 0); 00939 glutAddMenuEntry("Focal Plane", 1); 00940 glutAddMenuEntry("Axis", 2); 00941 00942 glutCreateMenu(main_menu_glut); 00943 glutAddSubMenu("Navigation", navigation); 00944 glutAddSubMenu("Focal Length", focal_length); 00945 glutAddSubMenu("Options", options); 00946 glutAddMenuEntry("Capture", 1); 00947 glutAddMenuEntry("Reset", 2); 00948 glutAddMenuEntry("Quit", 3); 00949 00950 glutAttachMenu(GLUT_RIGHT_BUTTON); 00951 } 00952 00954 void init_gl() 00955 { 00956 static GLfloat base_amb [] = {0.0f, 0.0f, 0.0f, 0.0f}; 00957 static GLfloat ambient0 [] = {0.2f, 0.2f, 0.2f, 1.0f}; 00958 static GLfloat diffuse0 [] = {0.9f, 0.9f, 0.9f, 1.0f}; 00959 static GLfloat direction[] = {0.0f, 0.0f, 2000.0f, 1.0f}; 00960 00961 glEnable(GL_DEPTH_TEST); 00962 glEnable(GL_LIGHTING); 00963 00964 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, base_amb); 00965 00966 glEnable(GL_LIGHT0); 00967 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0); 00968 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0); 00969 glLightfv(GL_LIGHT0, GL_POSITION, direction); 00970 00971 00972 if (!quad_fill) 00973 { 00974 quad_fill = gluNewQuadric(); 00975 gluQuadricDrawStyle(quad_fill, GLU_FILL); 00976 } 00977 00978 glLineWidth(1.0); 00979 glPointSize(1.0); 00980 glClearColor(1.0, 1.0, 1.0, 0.0); 00981 //glClearColor(0.0, 0.0, 0.0, 0.0); 00982 glClearAccum(0.0, 0.0, 0.0, 0.0); 00983 00984 glViewport(0, 0, view_width, view_height); 00985 } 00986 00988 void print_usage(void) 00989 { 00990 fprintf(stderr, "usage: surface-viewer OPTIONS surface_points\n"); 00991 fprintf(stderr, "where OPTIONS is one or more of the following:\n"); 00992 opts->print(cerr, 30); 00993 } 00994 00996 void process_help_opt(void) 00997 { 00998 print_usage(); 00999 exit(EXIT_SUCCESS); 01000 } 01001 01003 void process_version_opt(void) 01004 { 01005 cout << SURFACE_PACKAGE_STRING << "\n"; 01006 exit(EXIT_SUCCESS); 01007 } 01008 01010 void process_size_opt(const char* arg) throw (Arg_error) 01011 { 01012 int32_t w, h; 01013 01014 if (!arg) 01015 { 01016 throw Arg_error("Option 'size' requires an argument"); 01017 } 01018 if (sscanf(arg, "%d,%d", &w, &h) != 2) 01019 { 01020 throw Arg_error("Option 'size' has format width,height"); 01021 } 01022 if (w <= 0 || h <= 0) 01023 { 01024 throw Arg_error("Option 'size' must have width,height > 0"); 01025 } 01026 view_width = (uint32_t)w; 01027 view_height = (uint32_t)h; 01028 } 01029 01031 void process_glasses_opt(const char* arg) throw (Arg_error) 01032 { 01033 if (!arg) 01034 { 01035 throw Arg_error("Option 'glasses' requires an argument"); 01036 } 01037 if (strcmp("red-blue", arg) == 0) 01038 glasses_type = REDBLUE; 01039 else if (strcmp("red-green", arg) == 0) 01040 glasses_type = REDGREEN; 01041 else if (strcmp("red-cyan", arg) == 0) 01042 glasses_type = REDCYAN; 01043 else if (strcmp("blue-red", arg) == 0) 01044 glasses_type = BLUERED; 01045 else if (strcmp("green-red", arg) == 0) 01046 glasses_type = GREENRED; 01047 else if (strcmp("cyan-red", arg) == 0) 01048 glasses_type = CYANRED; 01049 else 01050 { 01051 throw Arg_error("Invalid 'glasses' type"); 01052 } 01053 } 01054 01056 void process_capture_opt(const char* arg) throw (Arg_error) 01057 { 01058 if (!arg) 01059 { 01060 throw Arg_error("Option 'capture' requires an argument"); 01061 } 01062 capture_fname = arg; 01063 } 01064 01066 void process_surf_scale_opt(const char* arg) throw (Arg_error) 01067 { 01068 if (!arg) 01069 { 01070 throw Arg_error("Option 'surf-scale' requires an argument"); 01071 } 01072 if (sscanf(arg, "%f,%f,%f", &x_scale, &y_scale, &z_scale) != 3) 01073 { 01074 throw Arg_error("Option 'surf-scale' has format x,y,z"); 01075 } 01076 if (x_scale <= 0 || y_scale <= 0 || z_scale <= 0) 01077 { 01078 throw Arg_error("Option 'surf-scale': scale must be > 0"); 01079 } 01080 } 01081 01083 void process_sample_rate_opt(const char* arg) throw (Arg_error) 01084 { 01085 if (!arg) 01086 { 01087 throw Arg_error("Option 'sample-rate' requires an argument"); 01088 } 01089 if (sscanf(arg, "%f", &sample_rate) != 1 || sample_rate <= 0 || 01090 sample_rate > 1.0) 01091 { 01092 throw Arg_error("Option 'sample-rate' must be in (0,1]"); 01093 } 01094 } 01095 01097 void process_patch_size_opt(const char* arg) throw (Arg_error) 01098 { 01099 if (!arg) 01100 { 01101 throw Arg_error("Option 'patch-size' requires an argument"); 01102 } 01103 if (sscanf(arg, "%f", &surface_patch_size) != 1 || sample_rate <= 0) 01104 { 01105 throw Arg_error("Option 'patch-size' must be > 0"); 01106 } 01107 } 01108 01110 void init_options() 01111 { 01112 using jwscxx::base::Option_no_arg; 01113 using jwscxx::base::Option_with_arg; 01114 01115 const char* l_name; 01116 const char* desc; 01117 01118 opts = new Options(); 01119 01120 l_name = "help"; 01121 desc = "Program usage"; 01122 opts->add(new Option_no_arg('h', l_name, desc, process_help_opt)); 01123 01124 l_name = "version"; 01125 desc = "Program version."; 01126 opts->add(new Option_no_arg('v', l_name, desc, process_version_opt)); 01127 01128 l_name = "size"; 01129 desc = "Window size with format width,height. Default is 600,600."; 01130 opts->add(new Option_with_arg(0, l_name, desc, process_size_opt)); 01131 01132 l_name = "glasses"; 01133 desc = "Type of colored glasses for anaglyph mode in the interactive window. Possible left-right filter types include include red-blue, red-green, red-cyan, blue-red, green-red, cyan-red. Default is cyan-red."; 01134 opts->add(new Option_with_arg(0, l_name, desc, process_glasses_opt)); 01135 01136 l_name = "capture"; 01137 desc = "View capture name in the interactive mode."; 01138 opts->add(new Option_with_arg(0, l_name, desc, process_capture_opt)); 01139 01140 l_name = "surf-scale"; 01141 desc = "Number of world units per image pixel. Has format x,y,z."; 01142 opts->add(new Option_with_arg(0, l_name, desc, process_surf_scale_opt)); 01143 01144 l_name = "sample-rate"; 01145 desc = "Surface point sampling rate."; 01146 opts->add(new Option_with_arg(0, l_name, desc, process_sample_rate_opt)); 01147 01148 l_name = "patch-size"; 01149 desc = "Surface patch size. Must be > 0."; 01150 opts->add(new Option_with_arg(0, l_name, desc, process_patch_size_opt)); 01151 } 01152 01154 void read_surface_data(const char* surface_fname) throw (Exception) 01155 { 01156 Surface_point_f* points = 0; 01157 uint32_t num_pts; 01158 Error* err; 01159 if ((err = read_surface_points_f(&points, &num_pts, surface_fname))) 01160 { 01161 ostringstream ost; 01162 ost << surface_fname << ": " << err->msg; 01163 free_error(err); 01164 throw Arg_error(ost.str()); 01165 } 01166 01167 if (num_pts == 0) 01168 { 01169 ostringstream ost; 01170 ost << surface_fname << ": doesn't contain any surface points"; 01171 throw Arg_error(ost.str()); 01172 } 01173 01174 surface = new list<Surface_patch_f*>(); 01175 create_zero_vector_f(&patch_offset, 3); 01176 01177 for (uint32_t i = 0; i < num_pts; i++) 01178 { 01179 Surface_patch_f* patch = 0; 01180 create_surface_patch_f(&patch, &(points[ i ]), surface_patch_size, 01181 x_scale, y_scale, z_scale); 01182 patch_offset->elts[0] += patch->center->elts[0]; 01183 patch_offset->elts[1] += patch->center->elts[1]; 01184 patch_offset->elts[2] += patch->center->elts[2]; 01185 surface->push_back(patch); 01186 } 01187 01188 patch_offset->elts[0] *= 1.0f/num_pts; 01189 patch_offset->elts[1] *= 1.0f/(2.0f*num_pts); 01190 patch_offset->elts[2] *= 1.0f/num_pts; 01191 01192 free(points); 01193 } 01194 01195 01196 01198 int main(int argc, char** argv) 01199 { 01200 init_options(); 01201 01202 try 01203 { 01204 int nargs = opts->process(argc, argv); 01205 01206 if (nargs < 2) 01207 { 01208 throw Arg_error("No surface to view"); 01209 } 01210 01211 read_surface_data(argv[ argc - nargs + 1]); 01212 01213 init_glut(argc, argv); 01214 init_gl(); 01215 init_camera(); 01216 init_modes(); 01217 01218 glutMainLoop(); 01219 } 01220 catch (Exception e) 01221 { 01222 cerr << "surface-viewer: "; 01223 e.print(); 01224 return EXIT_FAILURE; 01225 } 01226 01227 return EXIT_FAILURE; 01228 }