Alternaria
fit cylinders and ellipsoids to fungus
|
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 <cstring> 00051 #include <cassert> 00052 #include <iostream> 00053 #include <sstream> 00054 #include <vector> 00055 00056 #include <inttypes.h> 00057 00058 #if defined ALTERNARIA_HAVE_OPENGL_FRAMEWORK 00059 #include <OpenGL/gl.h> 00060 #include <OpenGL/glu.h> 00061 #elif defined ALTERNARIA_HAVE_OPENGL 00062 #include <GL/gl.h> 00063 #include <GL/glu.h> 00064 #endif 00065 00066 #if defined ALTERNARIA_HAVE_GLUT_FRAMEWORK 00067 #include <GLUT/glut.h> 00068 #elif defined ALTERNARIA_HAVE_GLUT 00069 #include <GL/glut.h> 00070 #endif 00071 00072 #include <jwsc/math/constants.h> 00073 #include <jwsc/vector/vector.h> 00074 #include <jwsc/vector/vector_math.h> 00075 #include <jwsc/matrix/matrix.h> 00076 #include <jwsc/matrix/matrix_math.h> 00077 #include <jwsc/image/image.h> 00078 #include <jwsc/image/image_io.h> 00079 #include <jwsc/imgblock/imgblock.h> 00080 #include <jwsc/imgblock/imgblock_io.h> 00081 #include <jwsc/imgblock/surface.h> 00082 00083 #include <jwsc++/base/option.h> 00084 #include <jwsc++/base/exception.h> 00085 #include <jwsc++/graphics/camera.h> 00086 00087 #include "imaging_model.h" 00088 #include "psf_model.h" 00089 #include "structure.h" 00090 #include "spore.h" 00091 #include "hypha.h" 00092 #include "alternaria_model.h" 00093 00094 00095 /* Anaglyph glasses filter types. */ 00096 #define REDBLUE 1 00097 #define REDGREEN 2 00098 #define REDCYAN 3 00099 #define BLUERED 4 00100 #define GREENRED 5 00101 #define CYANRED 6 00102 00103 /* Program defaults. */ 00104 #define VIEW_WIDTH 800 00105 #define VIEW_HEIGHT 800 00106 #define APERTURE 60.0f 00107 #define CLIP_NEAR 10.0f 00108 #define CLIP_FAR 3000.0f 00109 #define GLASSES_TYPE REDCYAN 00110 #define CAPTURE_FMT "capture-%04u.tiff" 00111 #define MODEL_COMPARE_FNAME 0 00112 #define SURF_COMPARE_FNAME 0 00113 #define SURF_PATCH_SIZE 2.0 00114 #define OBJECT_SCALE 1.0 00115 00116 #define CENTROID_MIN -5000.0f 00117 #define CENTROID_MAX 5000.0f 00118 #define LENGTH_MU 40.0f 00119 #define LENGTH_SIGMA 4.0f 00120 #define LENGTH_MIN 1.f 00121 #define LENGTH_MAX 1000.0f 00122 #define WIDTH_MU 15.0f 00123 #define WIDTH_SIGMA 1.0f 00124 #define WIDTH_MIN 1.0f 00125 #define WIDTH_MAX 1000.0f 00126 #define DWIDTH_SIGMA 0.05f 00127 #define DWIDTH_MIN -100.0f 00128 #define DWIDTH_MAX 100.0f 00129 #define THETA_MU 0 00130 #define THETA_SIGMA 0.2f 00131 #define THETA_MIN 0 00132 #define THETA_MAX JWSC_PI 00133 #define PSI_MIN -JWSC_PI 00134 #define PSI_MAX JWSC_PI 00135 #define OPACITY_MU 0.9f 00136 #define OPACITY_SIGMA 0.2f 00137 #define OPACITY_MIN 0.0f 00138 #define OPACITY_MAX 1.0f 00139 #define DIST_MU 0.5f 00140 #define DIST_SIGMA 0.1f 00141 #define DIST_MIN 0 00142 #define DIST_MAX 1.0f 00143 00144 00145 00146 using std::cout; 00147 using std::cerr; 00148 using std::ostringstream; 00149 using std::sscanf; 00150 using std::sprintf; 00151 using std::vector; 00152 using namespace jwsc; 00153 using jwscxx::base::Options; 00154 using jwscxx::base::Exception; 00155 using jwscxx::base::Arg_error; 00156 using jwscxx::graphics::Stereo_camera_f; 00157 00158 00159 00161 Options* opts = 0; 00162 00164 uint32_t view_width = VIEW_WIDTH; 00165 00167 uint32_t view_height = VIEW_HEIGHT; 00168 00170 float aperture = APERTURE; 00171 00173 float clip_near = CLIP_NEAR; 00174 00176 float clip_far = CLIP_FAR; 00177 00179 int glasses_type = GLASSES_TYPE; 00180 00182 const char* capture_fmt = CAPTURE_FMT; 00183 00185 const char* model_compare_fname = MODEL_COMPARE_FNAME; 00186 00188 const char* surface_compare_fname = SURF_COMPARE_FNAME; 00189 00191 float object_scale = OBJECT_SCALE; 00192 00194 Stereo_camera_f* camera = 0; 00195 00197 GLUquadric* quad_fill = 0; 00198 00200 GLUquadric* quad_wire = 0; 00201 00203 PSF_model* psf = 0; 00204 00206 Alternaria* alternaria = 0; 00207 00209 Alternaria* model_compare = 0; 00210 00212 list<Surface_patch_f*>* surface_compare = 0; 00213 00215 Imaging_scale* surface_scale = 0; 00216 00218 float surface_patch_size = SURF_PATCH_SIZE; 00219 00221 Imaging_model_density* imaging_d = 0; 00222 00224 PSF_model_density* psf_d = 0; 00225 00227 Apical_hypha_density* apical_hypha_d = 0; 00228 00230 Lateral_hypha_density* lateral_hypha_d = 0; 00231 00233 Spore_density* spore_d = 0; 00234 00236 Alternaria_density* alt_d = 0; 00237 00242 Structure* highlight = 0; 00243 00249 struct Alternaria_viewer_modes 00250 { 00252 bool translate_camera; 00253 00255 bool rotate_camera; 00256 00258 bool capture_view; 00259 00264 bool anaglyph; 00265 00267 bool render_focal_plane; 00268 00270 bool render_world_axis; 00271 00273 bool focal_prp; 00274 00276 bool focal_vrp; 00277 00279 bool clip_near; 00280 } 00281 modes; 00282 00284 void init_modes() 00285 { 00286 modes.translate_camera = false; 00287 modes.rotate_camera = true; 00288 modes.capture_view = false; 00289 modes.anaglyph = false; 00290 modes.render_focal_plane = false; 00291 modes.render_world_axis = true; 00292 modes.focal_prp = false; 00293 modes.focal_vrp = true; 00294 modes.clip_near = true; 00295 } 00296 00298 void init_camera() throw (Arg_error) 00299 { 00300 delete camera; 00301 00302 // Generic 00303 camera = new Stereo_camera_f(0, 50, 300, 0, 50, 0, 0, 1, 0, 00304 aperture, clip_near, clip_far); 00305 00306 // B 00307 //camera = new Stereo_camera_f(0,340,750, 0,340,450, 0, 1, 0, 00308 // aperture, clip_near, clip_far); 00309 00310 // A 00311 //camera = new Stereo_camera_f(-20,240,-490, -20,240,-190, 0, 1, 0, 00312 } 00313 00319 void clean_up() 00320 { 00321 if (surface_compare) 00322 { 00323 list<Surface_patch_f*>::iterator it; 00324 for (it = surface_compare->begin(); it != surface_compare->end(); it++) 00325 { 00326 delete *it; 00327 } 00328 delete surface_compare; 00329 } 00330 00331 delete surface_scale; 00332 delete alternaria; 00333 delete model_compare; 00334 delete psf; 00335 delete imaging_d; 00336 delete psf_d; 00337 delete spore_d; 00338 delete apical_hypha_d; 00339 delete lateral_hypha_d; 00340 delete alt_d; 00341 delete camera; 00342 delete opts; 00343 gluDeleteQuadric(quad_fill); 00344 gluDeleteQuadric(quad_wire); 00345 } 00346 00348 void reset() 00349 { 00350 object_scale = OBJECT_SCALE; 00351 aperture = APERTURE; 00352 highlight = 0; 00353 init_camera(); 00354 init_modes(); 00355 } 00356 00358 void render_world_axis() 00359 { 00360 static GLfloat amb_dif[4] = {0, 0, 0, 1.0f}; 00361 00362 glMatrixMode(GL_MODELVIEW); 00363 00364 glPushMatrix(); 00365 00366 float axis_length = 100.0f; 00367 float arrow_radius = axis_length / 10.0f; 00368 float arrow_height = axis_length / 5.0f; 00369 00370 /* X */ 00371 amb_dif[0] = 0.9f; amb_dif[1] = 1.0f; amb_dif[2] = 0.3f; 00372 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00373 glPushMatrix(); 00374 glRotatef(90, 0, 1.0f, 0); 00375 gluCylinder(quad_fill, 1, 1, axis_length - 0.5f*arrow_height, 8, 1); 00376 glPopMatrix(); 00377 glPushMatrix(); 00378 glTranslatef(axis_length - arrow_height, 0, 0); 00379 glRotatef(90, 0, 1.0f, 0); 00380 gluCylinder(quad_fill, arrow_radius, 0, arrow_height, 16, 8); 00381 glPopMatrix(); 00382 00383 /* Y */ 00384 amb_dif[0] = 0.9f; amb_dif[1] = 1.0f; amb_dif[2] = 0.3f; 00385 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00386 glPushMatrix(); 00387 glRotatef(-90, 1.0f, 0, 0); 00388 gluCylinder(quad_fill, 1, 1, axis_length - 0.5f*arrow_height, 8, 1); 00389 glPopMatrix(); 00390 glPushMatrix(); 00391 glTranslatef(0, axis_length - arrow_height, 0); 00392 glRotatef(-90, 1.0f, 0, 0); 00393 gluCylinder(quad_fill, arrow_radius, 0, arrow_height, 16, 8); 00394 glPopMatrix(); 00395 00396 /* Z */ 00397 amb_dif[0] = 0.9f; amb_dif[1] = 1.0f; amb_dif[2] = 0.3f; 00398 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00399 gluCylinder(quad_fill, 1, 1, axis_length - 0.5f*arrow_height, 8, 1); 00400 glPushMatrix(); 00401 glTranslatef(0, 0, axis_length - arrow_height); 00402 gluCylinder(quad_fill, arrow_radius, 0, arrow_height, 16, 8); 00403 glPopMatrix(); 00404 00405 glPopMatrix(); 00406 } 00407 00409 void render_focal_plane() 00410 { 00411 static GLfloat amb_dif[4] = {0.7f, 0.6f, 0.5f, 0.2f}; 00412 GLboolean prev_blend; 00413 GLint prev_blend_src; 00414 GLint prev_blend_dst; 00415 00416 if ((prev_blend = glIsEnabled(GL_BLEND))) 00417 { 00418 glGetIntegerv(GL_BLEND_SRC, &prev_blend_src); 00419 glGetIntegerv(GL_BLEND_DST, &prev_blend_dst); 00420 } 00421 else 00422 { 00423 glEnable(GL_BLEND); 00424 } 00425 glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA); 00426 00427 glMatrixMode(GL_MODELVIEW); 00428 00429 glPushMatrix(); 00430 glLoadIdentity(); 00431 00432 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00433 00434 float x = 200.0f; 00435 float y = 200.0f; 00436 float z = -camera->get_focal_length(); 00437 00438 glBegin(GL_POLYGON); 00439 glNormal3f( 0, 0, 1); 00440 glVertex3f( x, y, z); 00441 glVertex3f(-x, y, z); 00442 glVertex3f(-x, -y, z); 00443 glVertex3f( x, -y, z); 00444 glEnd(); 00445 00446 glPopMatrix(); 00447 00448 if (prev_blend) 00449 { 00450 glBlendFunc(prev_blend_src, prev_blend_dst); 00451 } 00452 else 00453 { 00454 glDisable(GL_BLEND); 00455 } 00456 } 00457 00459 void render_model_compare() 00460 { 00461 if (!model_compare) 00462 { 00463 return; 00464 } 00465 00466 model_compare->get_root()->recursively_draw_in_opengl(quad_wire, 00467 object_scale); 00468 } 00469 00471 void render_surface_compare() 00472 { 00473 static GLfloat amb_dif[4] = {0, 0, 0, 1.0f}; 00474 00475 if (!surface_compare) 00476 { 00477 return; 00478 } 00479 00480 glMatrixMode(GL_MODELVIEW); 00481 00482 glPushMatrix(); 00483 00484 glDisable(GL_LIGHT0); 00485 glEnable(GL_LIGHT2); 00486 00487 /* Render the surface patches. */ 00488 list<Surface_patch_f*>::iterator it; 00489 for (it = surface_compare->begin(); it != surface_compare->end(); it++) 00490 { 00491 const Surface_patch_f* patch = *it; 00492 00493 amb_dif[0] = patch->albedo*0.78f; 00494 amb_dif[1] = patch->albedo*0.6f; 00495 amb_dif[2] = patch->albedo*0.2f; 00496 00497 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00498 00499 glNormal3f(patch->normal->elts[0], patch->normal->elts[1], 00500 patch->normal->elts[2]); 00501 00502 glBegin(GL_POLYGON); 00503 for (int i = 0; i < 4; i++) 00504 { 00505 const Vector_f* point = patch->pts[ i ]; 00506 glVertex3f(point->elts[0], point->elts[1], point->elts[2]); 00507 } 00508 glEnd(); 00509 } 00510 00511 glDisable(GL_LIGHT2); 00512 glEnable(GL_LIGHT0); 00513 00514 glPopMatrix(); 00515 } 00516 00518 void render_scene() 00519 { 00520 glMatrixMode(GL_MODELVIEW); 00521 00522 glPushMatrix(); 00523 00524 float x = object_scale*alternaria->get_root()->get_centroid()->elts[0]; 00525 float y = object_scale*alternaria->get_root()->get_centroid()->elts[1]; 00526 float z = object_scale*alternaria->get_root()->get_centroid()->elts[2]; 00527 glTranslatef(-x, -y, -z); 00528 00529 if (highlight) 00530 { 00531 glDisable(GL_LIGHT0); 00532 glEnable(GL_LIGHT1); 00533 highlight->draw_in_opengl(quad_fill, object_scale); 00534 glDisable(GL_LIGHT1); 00535 glEnable(GL_LIGHT0); 00536 } 00537 00538 alternaria->get_root()->recursively_draw_in_opengl(quad_fill, object_scale); 00539 00540 render_model_compare(); 00541 00542 render_surface_compare(); 00543 00544 glPopMatrix(); 00545 } 00546 00548 void display_glut_anaglyph() 00549 { 00550 /* Set the buffer for reading and writing. Using double buffering. */ 00551 glDrawBuffer(GL_BACK); 00552 glReadBuffer(GL_BACK); 00553 00554 /* Clear things */ 00555 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); 00556 00557 /* Left camera filter. */ 00558 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00559 switch (glasses_type) 00560 { 00561 case REDBLUE: 00562 case REDGREEN: 00563 case REDCYAN: 00564 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); 00565 break; 00566 case BLUERED: 00567 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE); 00568 break; 00569 case GREENRED: 00570 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE); 00571 break; 00572 case CYANRED: 00573 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE); 00574 break; 00575 } 00576 00577 /* Set the left camera projection. */ 00578 camera->set_left_gl_projection(); 00579 00580 /* Set the camera model view. */ 00581 camera->set_left_gl_modelview(); 00582 00583 /* Render the world axis. */ 00584 if (modes.render_world_axis) 00585 { 00586 render_world_axis(); 00587 } 00588 00589 render_scene(); 00590 00591 /* Render the focal plane if in that mode. */ 00592 if (modes.render_focal_plane) 00593 { 00594 render_focal_plane(); 00595 } 00596 00597 glFlush(); 00598 00599 glAccum(GL_LOAD, 0.5f); 00600 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 00601 00602 /* Right camera filter. */ 00603 switch (glasses_type) 00604 { 00605 case REDBLUE: 00606 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE); 00607 break; 00608 case REDGREEN: 00609 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE); 00610 break; 00611 case REDCYAN: 00612 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE); 00613 break; 00614 case BLUERED: 00615 case GREENRED: 00616 case CYANRED: 00617 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); 00618 break; 00619 } 00620 00621 /* Set the right camera projection. */ 00622 camera->set_right_gl_projection(); 00623 00624 /* Set the camera model view. */ 00625 camera->set_right_gl_modelview(); 00626 00627 /* Render the world axis. */ 00628 if (modes.render_world_axis) 00629 { 00630 render_world_axis(); 00631 } 00632 00633 render_scene(); 00634 00635 /* Render the focal plane if in that mode. */ 00636 if (modes.render_focal_plane) 00637 { 00638 render_focal_plane(); 00639 } 00640 00641 glFlush(); 00642 00644 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00645 00646 glAccum(GL_ACCUM, 0.5f); 00647 glAccum(GL_RETURN, 2.0f); 00648 } 00649 00653 void display_glut_regular() 00654 { 00655 /* Set the buffer for writing. Using double buffering. */ 00656 glDrawBuffer(GL_BACK); 00657 glReadBuffer(GL_BACK); 00658 00659 /* Clear things */ 00660 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00661 00662 /* Set the camera projection. */ 00663 camera->set_gl_projection(); 00664 00665 /* Set the camera model view. */ 00666 camera->set_gl_modelview(); 00667 00668 /* Render the world axis. */ 00669 if (modes.render_world_axis) 00670 { 00671 render_world_axis(); 00672 } 00673 00674 render_scene(); 00675 00676 /* Render the focal plane if in that mode. */ 00677 if (modes.render_focal_plane) 00678 { 00679 render_focal_plane(); 00680 } 00681 00682 glFlush(); 00683 } 00684 00686 void display_glut() 00687 { 00688 static uint32_t N = 1; 00689 00690 if (modes.anaglyph) 00691 { 00692 display_glut_anaglyph(); 00693 } 00694 else 00695 { 00696 display_glut_regular(); 00697 } 00698 00699 glutSwapBuffers(); 00700 00701 if (modes.capture_view) 00702 { 00703 Stereo_camera_f::capture_gl_view(capture_fmt, N++); 00704 modes.capture_view = 0; 00705 } 00706 } 00707 00709 void reshape_glut(int w, int h) 00710 { 00711 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00712 glViewport(0, 0, (GLsizei)w, (GLsizei)h); 00713 view_width = w; 00714 view_height = h; 00715 } 00716 00718 void keyboard_glut(unsigned char key, int a, int b) 00719 { 00720 float translate_delta = 10; 00721 float rotate_delta = 10*JWSC_DEG_TO_RAD; 00722 float focal_length; 00723 float theta; 00724 00725 Vector_f* v_tmp = 0; 00726 00727 switch (key) { 00728 case 't': 00729 modes.translate_camera = 1; 00730 modes.rotate_camera = 0; 00731 break; 00732 case 'r': 00733 modes.rotate_camera = 1; 00734 modes.translate_camera = 0; 00735 break; 00736 case 'l': 00737 if (modes.translate_camera) 00738 { 00739 const Vector_f* right = camera->get_u(); 00740 camera->translate( 00741 translate_delta * right->elts[0], 00742 translate_delta * right->elts[1], 00743 translate_delta * right->elts[2]); 00744 } 00745 else if (modes.rotate_camera) 00746 { 00747 camera->rotate(-rotate_delta, 0, 1, 0); 00748 } 00749 glutPostRedisplay(); 00750 break; 00751 case 'h': 00752 if (modes.translate_camera) 00753 { 00754 const Vector_f* right = camera->get_u(); 00755 camera->translate( 00756 -translate_delta * right->elts[0], 00757 -translate_delta * right->elts[1], 00758 -translate_delta * right->elts[2]); 00759 } 00760 else if (modes.rotate_camera) 00761 { 00762 camera->rotate(rotate_delta, 0, 1, 0); 00763 } 00764 glutPostRedisplay(); 00765 break; 00766 case 'L': 00767 if (modes.translate_camera) 00768 { 00769 const Vector_f* right = camera->get_u(); 00770 camera->translate( 00771 translate_delta * right->elts[0], 00772 translate_delta * right->elts[1], 00773 translate_delta * right->elts[2]); 00774 } 00775 else if (modes.rotate_camera) 00776 { 00777 copy_vector_f(&v_tmp, camera->get_prp()); 00778 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00779 camera->translate(v_tmp); 00780 camera->rotate(rotate_delta, camera->get_v()); 00781 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00782 camera->translate(v_tmp); 00783 } 00784 glutPostRedisplay(); 00785 break; 00786 case 'H': 00787 if (modes.translate_camera) 00788 { 00789 const Vector_f* right = camera->get_u(); 00790 camera->translate( 00791 -translate_delta * right->elts[0], 00792 -translate_delta * right->elts[1], 00793 -translate_delta * right->elts[2]); 00794 } 00795 else if (modes.rotate_camera) 00796 { 00797 copy_vector_f(&v_tmp, camera->get_prp()); 00798 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00799 camera->translate(v_tmp); 00800 camera->rotate(-rotate_delta, camera->get_v()); 00801 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00802 camera->translate(v_tmp); 00803 } 00804 glutPostRedisplay(); 00805 break; 00806 case 'k': 00807 if (modes.translate_camera) 00808 { 00809 const Vector_f* up = camera->get_v(); 00810 camera->translate( 00811 translate_delta * up->elts[0], 00812 translate_delta * up->elts[1], 00813 translate_delta * up->elts[2]); 00814 } 00815 else if (modes.rotate_camera) 00816 { 00817 camera->rotate(rotate_delta, camera->get_u()); 00818 } 00819 glutPostRedisplay(); 00820 break; 00821 case 'j': 00822 if (modes.translate_camera) 00823 { 00824 const Vector_f* up = camera->get_v(); 00825 camera->translate( 00826 -translate_delta * up->elts[0], 00827 -translate_delta * up->elts[1], 00828 -translate_delta * up->elts[2]); 00829 } 00830 else if (modes.rotate_camera) 00831 { 00832 camera->rotate(-rotate_delta, camera->get_u()); 00833 } 00834 glutPostRedisplay(); 00835 break; 00836 case 'K': 00837 if (modes.translate_camera) 00838 { 00839 const Vector_f* view = camera->get_n(); 00840 camera->translate( 00841 -translate_delta * view->elts[0], 00842 -translate_delta * view->elts[1], 00843 -translate_delta * view->elts[2]); 00844 } 00845 else if (modes.rotate_camera) 00846 { 00847 copy_vector_f(&v_tmp, camera->get_prp()); 00848 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00849 camera->translate(v_tmp); 00850 camera->rotate(-rotate_delta, camera->get_u()); 00851 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00852 camera->translate(v_tmp); 00853 } 00854 glutPostRedisplay(); 00855 break; 00856 case 'J': 00857 if (modes.translate_camera) 00858 { 00859 const Vector_f* view = camera->get_n(); 00860 camera->translate( 00861 translate_delta * view->elts[0], 00862 translate_delta * view->elts[1], 00863 translate_delta * view->elts[2]); 00864 } 00865 else if (modes.rotate_camera) 00866 { 00867 copy_vector_f(&v_tmp, camera->get_prp()); 00868 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00869 camera->translate(v_tmp); 00870 camera->rotate(rotate_delta, camera->get_u()); 00871 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00872 camera->translate(v_tmp); 00873 } 00874 glutPostRedisplay(); 00875 break; 00876 case 'F': 00877 if (modes.focal_prp) 00878 { 00879 focal_length = camera->get_focal_length() + 20; 00880 camera->set_f_with_same_aperture_using_prp(focal_length); 00881 } 00882 else if (modes.focal_vrp) 00883 { 00884 focal_length = camera->get_focal_length() + 20; 00885 camera->set_f_with_same_aperture_using_vrp(focal_length); 00886 } 00887 glutPostRedisplay(); 00888 break; 00889 case 'f': 00890 if (modes.focal_prp) 00891 { 00892 focal_length = camera->get_focal_length(); 00893 if (focal_length >= 22) 00894 { 00895 focal_length -= 20; 00896 camera->set_f_with_same_aperture_using_prp(focal_length); 00897 } 00898 } 00899 else if (modes.focal_vrp) 00900 { 00901 focal_length = camera->get_focal_length(); 00902 if (focal_length >= 22) 00903 { 00904 focal_length -= 20; 00905 camera->set_f_with_same_aperture_using_vrp(focal_length); 00906 } 00907 } 00908 glutPostRedisplay(); 00909 break; 00910 case 'S': 00911 if (object_scale >= 2.99f) 00912 { 00913 object_scale = 3.0f; 00914 } 00915 else 00916 { 00917 object_scale += 0.01f; 00918 } 00919 glutPostRedisplay(); 00920 break; 00921 case 's': 00922 if (object_scale > 0.01f) 00923 { 00924 object_scale -= 0.01f; 00925 } 00926 glutPostRedisplay(); 00927 break; 00928 case 'A': 00929 aperture += JWSC_PI_8; 00930 camera->set_aperture(aperture); 00931 glutPostRedisplay(); 00932 break; 00933 case 'a': 00934 theta = aperture - JWSC_PI_8; 00935 if (theta >= 0) 00936 { 00937 aperture = theta; 00938 camera->set_aperture(theta); 00939 } 00940 glutPostRedisplay(); 00941 break; 00942 case 'P': 00943 if (modes.clip_near) 00944 { 00945 clip_near += 1; 00946 } 00947 else 00948 { 00949 clip_far += 1; 00950 } 00951 camera->set_clipping(clip_near, clip_far); 00952 glutPostRedisplay(); 00953 break; 00954 case 'p': 00955 if (clip_near > 0 && clip_far > 0) 00956 { 00957 if (modes.clip_near) 00958 { 00959 clip_near -= 1; 00960 } 00961 else 00962 { 00963 clip_far -= 1; 00964 } 00965 camera->set_clipping(clip_near, clip_far); 00966 glutPostRedisplay(); 00967 } 00968 break; 00969 case 'c': 00970 modes.capture_view = 1; 00971 glutPostRedisplay(); 00972 break; 00973 case 'o': 00974 reset(); 00975 glutPostRedisplay(); 00976 break; 00977 case 'q': 00978 std::cerr << "VRP: " 00979 << camera->get_vrp()->elts[0] << ", " 00980 << camera->get_vrp()->elts[1] << ", " 00981 << camera->get_vrp()->elts[2] << '\n'; 00982 std::cerr << "PRP: " 00983 << camera->get_prp()->elts[0] << ", " 00984 << camera->get_prp()->elts[1] << ", " 00985 << camera->get_prp()->elts[2] << '\n'; 00986 //free_vector_f(v_tmp); 00987 //clean_up(); 00988 exit(EXIT_SUCCESS); 00989 } 00990 00991 free_vector_f(v_tmp); 00992 } 00993 00995 void mouse_glut(int button, int state, int x, int y) 00996 { 00997 Vector_f* near_pt = 0; 00998 Vector_f* far_pt = 0; 00999 Vector_f* isect_pt = 0; 01000 01001 if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 01002 { 01003 float u = (float)x - (float)view_width / 2.0f; 01004 float v = (float)view_height / 2.0f - (float)y; 01005 camera->get_image_pt_on_near_clipping_plane(&near_pt, u, v); 01006 camera->get_image_pt_on_far_clipping_plane(&far_pt, u, v); 01007 01008 // Undo the transformation of the view in render_scene(). 01009 multiply_vector_by_scalar_f(&near_pt, near_pt, 1.0f/object_scale); 01010 multiply_vector_by_scalar_f(&far_pt, far_pt, 1.0f/object_scale); 01011 01012 float x = alternaria->get_root()->get_centroid()->elts[0]; 01013 float y = alternaria->get_root()->get_centroid()->elts[1]; 01014 float z = alternaria->get_root()->get_centroid()->elts[2]; 01015 Vector_f* V = 0; 01016 create_vector_f(&V, 3); 01017 V->elts[0] = x; V->elts[1] = y; V->elts[2] = z; 01018 add_vectors_f(&near_pt, near_pt, V); 01019 add_vectors_f(&far_pt, far_pt, V); 01020 free_vector_f(V); 01021 01022 highlight = 0; 01023 float t_min = 1.0f; 01024 01025 vector<Structure*>* structs = alternaria->get_root()->get_descendants(); 01026 01027 for (size_t i = 0; i < structs->size(); i++) 01028 { 01029 float t = structs->at(i)->get_intersection(&isect_pt, 1, near_pt, 01030 far_pt); 01031 if (t >= 0 && t <= t_min) 01032 { 01033 t_min = t; 01034 highlight = structs->at(i); 01035 highlight->print(); 01036 } 01037 } 01038 01039 delete structs; 01040 01041 glutPostRedisplay(); 01042 } 01043 01044 free_vector_f(near_pt); 01045 free_vector_f(far_pt); 01046 free_vector_f(isect_pt); 01047 } 01048 01050 void main_menu_glut(int id) 01051 { 01052 switch (id) 01053 { 01054 case 0: 01055 modes.capture_view = 1; 01056 glutPostRedisplay(); 01057 break; 01058 case 1: 01059 reset(); 01060 glutPostRedisplay(); 01061 break; 01062 case 2: 01063 exit(EXIT_SUCCESS); 01064 } 01065 } 01066 01068 void option_menu_glut(int id) 01069 { 01070 switch (id) 01071 { 01072 case 0: 01073 modes.anaglyph = !modes.anaglyph; 01074 glutPostRedisplay(); 01075 break; 01076 case 1: 01077 modes.render_focal_plane = !modes.render_focal_plane; 01078 glutPostRedisplay(); 01079 break; 01080 case 2: 01081 modes.render_world_axis = !modes.render_world_axis; 01082 glutPostRedisplay(); 01083 break; 01084 } 01085 } 01086 01088 void navigation_menu_glut(int id) 01089 { 01090 switch (id) 01091 { 01092 case 0: 01093 modes.rotate_camera = true; 01094 modes.translate_camera = false; 01095 break; 01096 case 1: 01097 modes.rotate_camera = false; 01098 modes.translate_camera = true; 01099 break; 01100 case 2: 01101 modes.rotate_camera = false; 01102 modes.translate_camera = false; 01103 break; 01104 } 01105 } 01106 01108 void focal_length_menu_glut(int id) 01109 { 01110 switch (id) 01111 { 01112 case 0: 01113 modes.focal_prp = true; 01114 modes.focal_vrp = false; 01115 break; 01116 case 1: 01117 modes.focal_prp = false; 01118 modes.focal_vrp = true; 01119 break; 01120 } 01121 } 01122 01124 void clipping_menu_glut(int id) 01125 { 01126 switch (id) 01127 { 01128 case 0: 01129 modes.clip_near = true; 01130 break; 01131 case 1: 01132 modes.clip_near = false; 01133 break; 01134 } 01135 } 01136 01138 void init_glut(int argc, char** argv) 01139 { 01140 glutInit(&argc, argv); 01141 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_ACCUM 01142 | GLUT_ALPHA); 01143 glutInitWindowSize(view_width, view_height); 01144 glutCreateWindow("Alternaria Structure Tester"); 01145 glutDisplayFunc(display_glut); 01146 glutReshapeFunc(reshape_glut); 01147 glutKeyboardFunc(keyboard_glut); 01148 glutMouseFunc(mouse_glut); 01149 01150 int navigation = glutCreateMenu(navigation_menu_glut); 01151 glutAddMenuEntry("Rotate Camera", 0); 01152 glutAddMenuEntry("Translate Camera", 1); 01153 glutAddMenuEntry("Modify Structure", 2); 01154 01155 int focal_length = glutCreateMenu(focal_length_menu_glut); 01156 glutAddMenuEntry("PRP", 0); 01157 glutAddMenuEntry("VRP", 1); 01158 01159 int clipping = glutCreateMenu(clipping_menu_glut); 01160 glutAddMenuEntry("Near", 0); 01161 glutAddMenuEntry("Far", 1); 01162 01163 int options = glutCreateMenu(option_menu_glut); 01164 glutAddMenuEntry("Anaglyph", 0); 01165 glutAddMenuEntry("Focal Plane", 1); 01166 glutAddMenuEntry("Axis", 2); 01167 01168 glutCreateMenu(main_menu_glut); 01169 glutAddSubMenu("Navigation", navigation); 01170 glutAddSubMenu("Focal Length", focal_length); 01171 glutAddSubMenu("Clipping", clipping); 01172 glutAddSubMenu("Options", options); 01173 glutAddMenuEntry("Capture", 1); 01174 glutAddMenuEntry("Reset", 2); 01175 glutAddMenuEntry("Quit", 3); 01176 01177 glutAttachMenu(GLUT_RIGHT_BUTTON); 01178 } 01179 01181 void init_gl() 01182 { 01183 glEnable(GL_DEPTH_TEST); 01184 glEnable(GL_NORMALIZE); 01185 glEnable(GL_LIGHTING); 01186 01187 static GLfloat base_amb[] = {0.0f, 0.0f, 0.0f, 0.0f}; 01188 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, base_amb); 01189 01190 static GLfloat ambient0 [] = {0.2f, 0.2f, 0.2f, 1.0f}; 01191 static GLfloat diffuse0 [] = {0.8f, 0.8f, 0.8f, 1.0f}; 01192 static GLfloat specular0 [] = {0.9f, 0.9f, 0.9f, 1.0f}; 01193 static GLfloat direction0[] = {500.0f, 500.0f, 2000.0f, 1.0f}; 01194 01195 glEnable(GL_LIGHT0); 01196 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0); 01197 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0); 01198 glLightfv(GL_LIGHT0, GL_SPECULAR, specular0); 01199 glLightfv(GL_LIGHT0, GL_POSITION, direction0); 01200 01201 static GLfloat ambient1 [] = {0.1f, 0.1f, 0.1f, 1.0f}; 01202 static GLfloat diffuse1 [] = {0.4f, 0.4f, 0.4f, 1.0f}; 01203 static GLfloat specular1 [] = {0.5f, 0.5f, 0.5f, 1.0f}; 01204 static GLfloat direction1[] = {500.0f, 500.0f, 2000.0f, 1.0f}; 01205 01206 glDisable(GL_LIGHT1); 01207 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1); 01208 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1); 01209 glLightfv(GL_LIGHT1, GL_SPECULAR, specular1); 01210 glLightfv(GL_LIGHT1, GL_POSITION, direction1); 01211 01212 static GLfloat ambient2 [] = {0.2f, 0.2f, 0.2f, 1.0f}; 01213 static GLfloat diffuse2 [] = {0.9f, 0.9f, 0.9f, 1.0f}; 01214 static GLfloat specular2 [] = {0.0f, 0.0f, 0.0f, 1.0f}; 01215 static GLfloat direction2[] = {500.0f, 500.0f, 2000.0f, 1.0f}; 01216 01217 glDisable(GL_LIGHT2); 01218 glLightfv(GL_LIGHT2, GL_AMBIENT, ambient2); 01219 glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuse2); 01220 glLightfv(GL_LIGHT2, GL_SPECULAR, specular2); 01221 glLightfv(GL_LIGHT2, GL_POSITION, direction2); 01222 01223 01224 if (!quad_fill) 01225 { 01226 quad_fill = gluNewQuadric(); 01227 gluQuadricDrawStyle(quad_fill, GLU_FILL); 01228 } 01229 01230 if (!quad_wire) 01231 { 01232 quad_wire = gluNewQuadric(); 01233 gluQuadricDrawStyle(quad_wire, GLU_LINE); 01234 } 01235 01236 glLineWidth(1.0); 01237 glPointSize(1.0); 01238 glClearColor(0.0, 0.0, 0.0, 0.0); 01239 glClearAccum(0.0, 0.0, 0.0, 0.0); 01240 01241 glViewport(0, 0, view_width, view_height); 01242 } 01243 01245 void print_usage(void) 01246 { 01247 cerr << "usage: alternaria_viewer OPTIONS [model]\n"; 01248 cerr << "where OPTIONS is one or more of the following:\n"; 01249 opts->print(cerr, 30); 01250 } 01251 01253 void process_help_opt(void) 01254 { 01255 print_usage(); 01256 exit(EXIT_SUCCESS); 01257 } 01258 01260 void process_version_opt(void) 01261 { 01262 cout << ALTERNARIA_PACKAGE_STRING << "\n"; 01263 exit(EXIT_SUCCESS); 01264 } 01265 01267 void process_view_size_opt(const char* arg) throw (Arg_error) 01268 { 01269 int32_t w, h; 01270 01271 if (!arg) 01272 { 01273 throw Arg_error("Option 'view-size' requires an argument"); 01274 } 01275 if (sscanf(arg, "%d,%d", &w, &h) != 2) 01276 { 01277 throw Arg_error("Option 'view-size' has format width,height"); 01278 } 01279 if (w <= 0 || h <= 0) 01280 { 01281 throw Arg_error("Option 'view-size' must have width,height > 0"); 01282 } 01283 view_width = (uint32_t)w; 01284 view_height = (uint32_t)h; 01285 } 01286 01288 void process_glasses_opt(const char* arg) throw (Arg_error) 01289 { 01290 if (!arg) 01291 { 01292 throw Arg_error("Option 'glasses' requires an argument"); 01293 } 01294 if (strcmp("red-blue", arg) == 0) 01295 glasses_type = REDBLUE; 01296 else if (strcmp("red-green", arg) == 0) 01297 glasses_type = REDGREEN; 01298 else if (strcmp("red-cyan", arg) == 0) 01299 glasses_type = REDCYAN; 01300 else if (strcmp("blue-red", arg) == 0) 01301 glasses_type = BLUERED; 01302 else if (strcmp("green-red", arg) == 0) 01303 glasses_type = GREENRED; 01304 else if (strcmp("cyan-red", arg) == 0) 01305 glasses_type = CYANRED; 01306 else 01307 { 01308 throw Arg_error("Invalid 'glasses' type"); 01309 } 01310 } 01311 01313 void process_capture_opt(const char* arg) throw (Arg_error) 01314 { 01315 if (!arg) 01316 { 01317 throw Arg_error("Option 'capture' requires an argument"); 01318 } 01319 capture_fmt = arg; 01320 } 01321 01323 void process_surf_compare_opt(const char* arg) throw (Arg_error) 01324 { 01325 if (!arg) 01326 { 01327 throw Arg_error("Option 'surf-compare' requires an argument"); 01328 } 01329 surface_compare_fname = arg; 01330 } 01331 01333 void process_surf_scale_opt(const char* arg) throw (Arg_error) 01334 { 01335 float x, y, z; 01336 01337 if (!arg) 01338 { 01339 throw Arg_error("Option 'surf-scale' requires an argument"); 01340 } 01341 if (sscanf(arg, "%f,%f,%f", &x, &y, &z) != 3) 01342 { 01343 throw Arg_error("Option 'surf-scale' has format x,y,z"); 01344 } 01345 try 01346 { 01347 surface_scale->set(x, y, z); 01348 } 01349 catch (Arg_error e) 01350 { 01351 ostringstream ost; 01352 ost << "Option 'surf-scale': " << e.get_msg(); 01353 throw Arg_error(ost.str()); 01354 } 01355 } 01356 01358 void process_patch_size_opt(const char* arg) throw (Arg_error) 01359 { 01360 if (!arg) 01361 { 01362 throw Arg_error("Option 'patch-size' requires an argument"); 01363 } 01364 if (sscanf(arg, "%f", &surface_patch_size) != 1 || surface_patch_size <= 0) 01365 { 01366 throw Arg_error("Option 'patch-size' must be > 0"); 01367 } 01368 } 01369 01371 void process_model_compare_opt(const char* arg) throw (Arg_error) 01372 { 01373 if (!arg) 01374 { 01375 throw Arg_error("Option 'model-compare' requires an argument"); 01376 } 01377 model_compare_fname = arg; 01378 } 01379 01381 void init_options() 01382 { 01383 using jwscxx::base::Option_no_arg; 01384 using jwscxx::base::Option_with_arg; 01385 01386 const char* l_name; 01387 const char* desc; 01388 01389 opts = new Options(); 01390 01391 l_name = "help"; 01392 desc = "Program usage"; 01393 opts->add(new Option_no_arg('h', l_name, desc, process_help_opt)); 01394 01395 l_name = "version"; 01396 desc = "Program version."; 01397 opts->add(new Option_no_arg('v', l_name, desc, process_version_opt)); 01398 01399 l_name = "view-size"; 01400 desc = "Interactive window View size with format width,height. Default is 400,400."; 01401 opts->add(new Option_with_arg(0, l_name, desc, process_view_size_opt)); 01402 01403 l_name = "glasses"; 01404 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."; 01405 opts->add(new Option_with_arg(0, l_name, desc, process_glasses_opt)); 01406 01407 l_name = "capture"; 01408 desc = "Printf-formatted file write captured view images to."; 01409 opts->add(new Option_with_arg(0, l_name, desc, process_capture_opt)); 01410 01411 l_name = "model-compare"; 01412 desc = "Alternaria model to compare with. Rendered as a wireframe."; 01413 opts->add(new Option_with_arg(0, l_name, desc, process_model_compare_opt)); 01414 01415 l_name = "surf-compare"; 01416 desc = "Alternaria surface to compare with."; 01417 opts->add(new Option_with_arg(0, l_name, desc, process_surf_compare_opt)); 01418 01419 l_name = "surf-scale"; 01420 desc = "Number of world units per image pixel. Has format x,y,z."; 01421 opts->add(new Option_with_arg(0, l_name, desc, process_surf_scale_opt)); 01422 01423 l_name = "patch-size"; 01424 desc = "Surface patch size. Must be > 0."; 01425 opts->add(new Option_with_arg(0, l_name, desc, process_patch_size_opt)); 01426 } 01427 01428 01430 void init_densities() 01431 { 01432 spore_d->set_centroid_x(CENTROID_MIN, CENTROID_MAX); 01433 spore_d->set_centroid_y(CENTROID_MIN, CENTROID_MAX); 01434 spore_d->set_centroid_z(CENTROID_MIN, CENTROID_MAX); 01435 spore_d->set_length(LENGTH_MU, LENGTH_SIGMA, LENGTH_MIN, LENGTH_MAX); 01436 spore_d->set_width(WIDTH_MU, WIDTH_SIGMA, WIDTH_MIN, WIDTH_MAX); 01437 spore_d->set_theta(THETA_MU, THETA_SIGMA, THETA_MIN, THETA_MAX); 01438 spore_d->set_psi(PSI_MIN, PSI_MAX); 01439 spore_d->set_opacity(OPACITY_MU, OPACITY_SIGMA, OPACITY_MIN, OPACITY_MAX); 01440 01441 apical_hypha_d->set_centroid_x(CENTROID_MIN, CENTROID_MAX); 01442 apical_hypha_d->set_centroid_y(CENTROID_MIN, CENTROID_MAX); 01443 apical_hypha_d->set_centroid_z(CENTROID_MIN, CENTROID_MAX); 01444 apical_hypha_d->set_length(LENGTH_MU, LENGTH_SIGMA, LENGTH_MIN, LENGTH_MAX); 01445 apical_hypha_d->set_width(WIDTH_MU, WIDTH_SIGMA, WIDTH_MIN, WIDTH_MAX); 01446 apical_hypha_d->set_theta(THETA_MU, THETA_SIGMA, THETA_MIN, THETA_MAX); 01447 apical_hypha_d->set_psi(PSI_MIN, PSI_MAX); 01448 apical_hypha_d->set_opacity(OPACITY_MU, OPACITY_SIGMA, OPACITY_MIN, OPACITY_MAX); 01449 apical_hypha_d->set_dwidth(DWIDTH_SIGMA, DWIDTH_MIN, DWIDTH_MAX); 01450 01451 lateral_hypha_d->set_centroid_x(CENTROID_MIN, CENTROID_MAX); 01452 lateral_hypha_d->set_centroid_y(CENTROID_MIN, CENTROID_MAX); 01453 lateral_hypha_d->set_centroid_z(CENTROID_MIN, CENTROID_MAX); 01454 lateral_hypha_d->set_length(LENGTH_MU, LENGTH_SIGMA, LENGTH_MIN, LENGTH_MAX); 01455 lateral_hypha_d->set_width(WIDTH_MU, WIDTH_SIGMA, WIDTH_MIN, WIDTH_MAX); 01456 lateral_hypha_d->set_theta(THETA_MU, THETA_SIGMA, THETA_MIN, THETA_MAX); 01457 lateral_hypha_d->set_psi(PSI_MIN, PSI_MAX); 01458 lateral_hypha_d->set_opacity(OPACITY_MU, OPACITY_SIGMA, OPACITY_MIN, OPACITY_MAX); 01459 lateral_hypha_d->set_lat_dist(DIST_MU, DIST_SIGMA, DIST_MIN, DIST_MAX); 01460 } 01461 01462 01464 void read_model_compare() throw (Exception) 01465 { 01466 if (!model_compare_fname) 01467 { 01468 return; 01469 } 01470 01471 assert(model_compare == 0); 01472 01473 model_compare = new Alternaria(model_compare_fname, alt_d, spore_d, 01474 apical_hypha_d, lateral_hypha_d, lateral_hypha_d); 01475 } 01476 01477 01479 void read_surface_compare() throw (Exception) 01480 { 01481 if (!surface_compare_fname) 01482 { 01483 return; 01484 } 01485 01486 assert(surface_compare == 0); 01487 01488 Surface_point_f* points = 0; 01489 uint32_t num_pts; 01490 Error* err; 01491 if ((err = read_surface_points_f(&points, &num_pts, 01492 surface_compare_fname))) 01493 { 01494 ostringstream ost; 01495 ost << surface_compare_fname << ": " << err->msg; 01496 free(err); 01497 throw Arg_error(ost.str()); 01498 } 01499 01500 if (num_pts == 0) 01501 { 01502 ostringstream ost; 01503 ost << surface_compare_fname << ": doesn't contain any surface points"; 01504 throw Arg_error(ost.str()); 01505 } 01506 01507 01508 surface_compare = new list<Surface_patch_f*>(); 01509 01510 for (uint32_t i = 0; i < num_pts; i++) 01511 { 01512 Surface_patch_f* patch = 0; 01513 create_surface_patch_f(&patch, &(points[ i ]), 01514 surface_patch_size, surface_scale->get_x(), 01515 surface_scale->get_y(), surface_scale->get_z()); 01516 surface_compare->push_back(patch); 01517 } 01518 01519 free(points); 01520 } 01521 01522 01523 01524 01526 int main(int argc, char** argv) 01527 { 01528 init_options(); 01529 01530 try 01531 { 01532 surface_scale = new Imaging_scale(); 01533 spore_d = new Spore_density(); 01534 apical_hypha_d = new Apical_hypha_density(); 01535 lateral_hypha_d = new Lateral_hypha_density(); 01536 alt_d = new Alternaria_density(); 01537 01538 init_densities(); 01539 01540 int nargs = opts->process(argc, argv); 01541 01542 if (nargs < 2) 01543 { 01544 throw Arg_error("No input model"); 01545 } 01546 01547 alternaria = new Alternaria(argv[ argc - nargs + 1], alt_d, spore_d, 01548 apical_hypha_d, lateral_hypha_d, lateral_hypha_d); 01549 01550 read_model_compare(); 01551 read_surface_compare(); 01552 01553 init_glut(argc, argv); 01554 init_gl(); 01555 init_camera(); 01556 init_modes(); 01557 01558 glutMainLoop(); 01559 } 01560 catch (Exception e) 01561 { 01562 cerr << "alternaria_viewer: "; 01563 e.print(); 01564 } 01565 01566 return EXIT_FAILURE; 01567 }