Surface
detect surface points in an image stack
surface_viewer.cpp
Go to the documentation of this file.
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 }