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 00047 #include <config.h> 00048 00049 #include <cstdlib> 00050 #include <cstdio> 00051 #include <cstring> 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/prob/pdf.h> 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 00081 #include <jwsc++/base/option.h> 00082 #include <jwsc++/base/exception.h> 00083 #include <jwsc++/graphics/camera.h> 00084 00085 #include "imaging_model.h" 00086 #include "psf_model.h" 00087 #include "structure.h" 00088 #include "spore.h" 00089 #include "hypha.h" 00090 #include "alternaria_model.h" 00091 00092 00093 /* Anaglyph glasses filter types. */ 00094 #define REDBLUE 1 00095 #define REDGREEN 2 00096 #define REDCYAN 3 00097 #define BLUERED 4 00098 #define GREENRED 5 00099 #define CYANRED 6 00100 00101 /* Program defaults. */ 00102 #define VIEW_WIDTH 800 00103 #define VIEW_HEIGHT 800 00104 #define APERTURE 60.0f 00105 #define CLIP_NEAR 10.0f 00106 #define CLIP_FAR 3000.0f 00107 #define GLASSES_TYPE REDCYAN 00108 #define CAPTURE_FMT "capture-%04u.tiff" 00109 #define OBJECT_SCALE 1.0 00110 #define SEED 2537984 00111 #define IMG_IN_FNAME 0 00112 #define IMG_OUT_FNAME "imaging.model" 00113 #define PSF_IN_FNAME 0 00114 #define PSF_OUT_FNAME "psf.model" 00115 #define ALT_IN_FNAME 0 00116 #define ALT_OUT_FNAME "alternaria.model" 00117 #define ALT_SCENE_FMT 0 00118 #define PSF_H_FMT 0 00119 #define NUM_SCENE_COLS 128 00120 #define NUM_SCENE_ROWS 128 00121 #define NUM_SCENE_IMGS 128 00122 #define CENTROID_MIN -5000.0f 00123 #define CENTROID_MAX 5000.0f 00124 #define NUM_STRUCTS 300 00125 #define BASE_LEVEL 0 00126 00127 00128 using std::cout; 00129 using std::cerr; 00130 using std::ostringstream; 00131 using std::sscanf; 00132 using std::vector; 00133 using namespace jwsc; 00134 using jwscxx::base::Options; 00135 using jwscxx::base::Exception; 00136 using jwscxx::base::Arg_error; 00137 using jwscxx::base::IO_error; 00138 using jwscxx::graphics::Stereo_camera_f; 00139 00140 00142 Options* opts = 0; 00143 00145 uint32_t view_width = VIEW_WIDTH; 00146 00148 uint32_t view_height = VIEW_HEIGHT; 00149 00151 float aperture = APERTURE; 00152 00154 float clip_near = CLIP_NEAR; 00155 00157 float clip_far = CLIP_FAR; 00158 00160 int glasses_type = GLASSES_TYPE; 00161 00163 const char* capture_fmt = CAPTURE_FMT; 00164 00166 float object_scale = OBJECT_SCALE; 00167 00169 uint32_t seed = SEED; 00170 00172 const char* img_in_fname = IMG_IN_FNAME; 00173 00175 const char* img_out_fname = IMG_OUT_FNAME; 00176 00178 const char* psf_in_fname = PSF_IN_FNAME; 00179 00181 const char* psf_out_fname = PSF_OUT_FNAME; 00182 00184 const char* alt_in_fname = ALT_IN_FNAME; 00185 00187 const char* alt_out_fname = ALT_OUT_FNAME; 00188 00193 const char* alt_scene_fmt = ALT_SCENE_FMT; 00194 00196 const char* psf_h_fmt = PSF_H_FMT; 00197 00199 uint32_t num_structs = NUM_STRUCTS; 00200 00202 uint32_t base_level = BASE_LEVEL; 00203 00205 Imaging_window* img_window = 0; 00206 00208 Imaging_scale* img_scale = 0; 00209 00211 Imaging_model* imaging = 0; 00212 00214 PSF_padding* padding = 0; 00215 00217 PSF_model* psf = 0; 00218 00220 Alternaria* alternaria = 0; 00221 00223 Imaging_model_density* imaging_d = 0; 00224 00226 PSF_model_density* psf_d = 0; 00227 00229 Apical_hypha_density* apical_hypha_d = 0; 00230 00232 Lateral_hypha_density* lateral_hypha_1_d = 0; 00233 00235 Lateral_hypha_density* lateral_hypha_n_d = 0; 00236 00238 Spore_density* spore_d = 0; 00239 00241 Alternaria_density* alt_d = 0; 00242 00244 bool interactive = 0; 00245 00247 Stereo_camera_f* camera = 0; 00248 00250 GLUquadric* quad_fill = 0; 00251 00253 GLUquadric* quad_wire = 0; 00254 00259 Structure* highlight = 0; 00260 00266 struct Alternaria_gen_modes 00267 { 00269 bool translate_camera; 00270 00272 bool rotate_camera; 00273 00275 bool modify_structure; 00276 00278 bool capture_view; 00279 00284 bool anaglyph; 00285 00287 bool render_focal_plane; 00288 00290 bool render_world_axis; 00291 00293 bool focal_prp; 00294 00296 bool focal_vrp; 00297 } 00298 modes; 00299 00301 void init_modes() 00302 { 00303 modes.translate_camera = false; 00304 modes.rotate_camera = true; 00305 modes.modify_structure = false; 00306 modes.capture_view = false; 00307 modes.anaglyph = false; 00308 modes.render_focal_plane = false; 00309 modes.render_world_axis = true; 00310 modes.focal_prp = false; 00311 modes.focal_vrp = true; 00312 } 00313 00315 void init_camera() throw (Arg_error) 00316 { 00317 delete camera; 00318 00319 camera = new Stereo_camera_f(0, 50, 300, 0, 50, 0, 0, 1, 0, 00320 aperture, clip_near, clip_far); 00321 } 00322 00328 void clean_up() 00329 { 00330 delete img_window; 00331 delete img_scale; 00332 delete padding; 00333 delete alternaria; 00334 delete psf; 00335 delete imaging; 00336 delete imaging_d; 00337 delete psf_d; 00338 delete spore_d; 00339 delete apical_hypha_d; 00340 delete lateral_hypha_1_d; 00341 delete lateral_hypha_n_d; 00342 delete alt_d; 00343 delete camera; 00344 delete opts; 00345 gluDeleteQuadric(quad_fill); 00346 gluDeleteQuadric(quad_wire); 00347 } 00348 00350 void reset() 00351 { 00352 object_scale = OBJECT_SCALE; 00353 aperture = APERTURE; 00354 highlight = 0; 00355 init_camera(); 00356 init_modes(); 00357 } 00358 00360 void render_world_axis() 00361 { 00362 static GLfloat amb_dif[4] = {0, 0, 0, 1.0f}; 00363 00364 glMatrixMode(GL_MODELVIEW); 00365 00366 glPushMatrix(); 00367 00368 float axis_length = 100.0f; 00369 float arrow_radius = axis_length / 10.0f; 00370 float arrow_height = axis_length / 5.0f; 00371 00372 /* X */ 00373 amb_dif[0] = 0.9f; amb_dif[1] = 1.0f; amb_dif[2] = 0.3f; 00374 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00375 glPushMatrix(); 00376 glRotatef(90, 0, 1.0f, 0); 00377 gluCylinder(quad_fill, 1, 1, axis_length - 0.5f*arrow_height, 8, 1); 00378 glPopMatrix(); 00379 glPushMatrix(); 00380 glTranslatef(axis_length - arrow_height, 0, 0); 00381 glRotatef(90, 0, 1.0f, 0); 00382 gluCylinder(quad_fill, arrow_radius, 0, arrow_height, 16, 8); 00383 glPopMatrix(); 00384 00385 /* Y */ 00386 amb_dif[0] = 0.9f; amb_dif[1] = 1.0f; amb_dif[2] = 0.3f; 00387 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00388 glPushMatrix(); 00389 glRotatef(-90, 1.0f, 0, 0); 00390 gluCylinder(quad_fill, 1, 1, axis_length - 0.5f*arrow_height, 8, 1); 00391 glPopMatrix(); 00392 glPushMatrix(); 00393 glTranslatef(0, axis_length - arrow_height, 0); 00394 glRotatef(-90, 1.0f, 0, 0); 00395 gluCylinder(quad_fill, arrow_radius, 0, arrow_height, 16, 8); 00396 glPopMatrix(); 00397 00398 /* Z */ 00399 amb_dif[0] = 0.9f; amb_dif[1] = 1.0f; amb_dif[2] = 0.3f; 00400 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00401 gluCylinder(quad_fill, 1, 1, axis_length - 0.5f*arrow_height, 8, 1); 00402 glPushMatrix(); 00403 glTranslatef(0, 0, axis_length - arrow_height); 00404 gluCylinder(quad_fill, arrow_radius, 0, arrow_height, 16, 8); 00405 glPopMatrix(); 00406 00407 glPopMatrix(); 00408 } 00409 00411 void render_focal_plane() 00412 { 00413 static GLfloat amb_dif[4] = {0.7f, 0.6f, 0.5f, 0.2f}; 00414 GLboolean prev_blend; 00415 GLint prev_blend_src; 00416 GLint prev_blend_dst; 00417 00418 if ((prev_blend = glIsEnabled(GL_BLEND))) 00419 { 00420 glGetIntegerv(GL_BLEND_SRC, &prev_blend_src); 00421 glGetIntegerv(GL_BLEND_DST, &prev_blend_dst); 00422 } 00423 else 00424 { 00425 glEnable(GL_BLEND); 00426 } 00427 glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA); 00428 00429 glMatrixMode(GL_MODELVIEW); 00430 00431 glPushMatrix(); 00432 glLoadIdentity(); 00433 00434 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, amb_dif); 00435 00436 float x = 200.0f; 00437 float y = 200.0f; 00438 float z = -camera->get_focal_length(); 00439 00440 glBegin(GL_POLYGON); 00441 glNormal3f( 0, 0, 1); 00442 glVertex3f( x, y, z); 00443 glVertex3f(-x, y, z); 00444 glVertex3f(-x, -y, z); 00445 glVertex3f( x, -y, z); 00446 glEnd(); 00447 00448 glPopMatrix(); 00449 00450 if (prev_blend) 00451 { 00452 glBlendFunc(prev_blend_src, prev_blend_dst); 00453 } 00454 else 00455 { 00456 glDisable(GL_BLEND); 00457 } 00458 } 00459 00461 void render_scene() 00462 { 00463 glMatrixMode(GL_MODELVIEW); 00464 00465 glPushMatrix(); 00466 00467 float x = object_scale*alternaria->get_root()->get_centroid()->elts[0]; 00468 float y = object_scale*alternaria->get_root()->get_centroid()->elts[1]; 00469 float z = object_scale*alternaria->get_root()->get_centroid()->elts[2]; 00470 glTranslatef(-x, -y, -z); 00471 00472 if (highlight) 00473 { 00474 glEnable(GL_LIGHT1); 00475 highlight->draw_in_opengl(quad_fill, object_scale); 00476 glDisable(GL_LIGHT1); 00477 } 00478 00479 alternaria->get_root()->recursively_draw_in_opengl(quad_fill, object_scale); 00480 00481 glPopMatrix(); 00482 } 00483 00485 void display_glut_anaglyph() 00486 { 00487 /* Set the buffer for reading and writing. Using double buffering. */ 00488 glDrawBuffer(GL_BACK); 00489 glReadBuffer(GL_BACK); 00490 00491 /* Clear things */ 00492 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); 00493 00494 /* Left camera filter. */ 00495 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00496 switch (glasses_type) 00497 { 00498 case REDBLUE: 00499 case REDGREEN: 00500 case REDCYAN: 00501 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); 00502 break; 00503 case BLUERED: 00504 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE); 00505 break; 00506 case GREENRED: 00507 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE); 00508 break; 00509 case CYANRED: 00510 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE); 00511 break; 00512 } 00513 00514 /* Set the left camera projection. */ 00515 camera->set_left_gl_projection(); 00516 00517 /* Set the camera model view. */ 00518 camera->set_left_gl_modelview(); 00519 00520 /* Render the world axis. */ 00521 if (modes.render_world_axis) 00522 { 00523 render_world_axis(); 00524 } 00525 00526 render_scene(); 00527 00528 /* Render the focal plane if in that mode. */ 00529 if (modes.render_focal_plane) 00530 { 00531 render_focal_plane(); 00532 } 00533 00534 glFlush(); 00535 00536 glAccum(GL_LOAD, 0.5f); 00537 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 00538 00539 /* Right camera filter. */ 00540 switch (glasses_type) 00541 { 00542 case REDBLUE: 00543 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE); 00544 break; 00545 case REDGREEN: 00546 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE); 00547 break; 00548 case REDCYAN: 00549 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE); 00550 break; 00551 case BLUERED: 00552 case GREENRED: 00553 case CYANRED: 00554 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE); 00555 break; 00556 } 00557 00558 /* Set the right camera projection. */ 00559 camera->set_right_gl_projection(); 00560 00561 /* Set the camera model view. */ 00562 camera->set_right_gl_modelview(); 00563 00564 /* Render the world axis. */ 00565 if (modes.render_world_axis) 00566 { 00567 render_world_axis(); 00568 } 00569 00570 render_scene(); 00571 00572 /* Render the focal plane if in that mode. */ 00573 if (modes.render_focal_plane) 00574 { 00575 render_focal_plane(); 00576 } 00577 00578 glFlush(); 00579 00581 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 00582 00583 glAccum(GL_ACCUM, 0.5f); 00584 glAccum(GL_RETURN, 2.0f); 00585 } 00586 00590 void display_glut_regular() 00591 { 00592 /* Set the buffer for writing. Using double buffering. */ 00593 glDrawBuffer(GL_BACK); 00594 glReadBuffer(GL_BACK); 00595 00596 /* Clear things */ 00597 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00598 00599 /* Set the camera projection. */ 00600 camera->set_gl_projection(); 00601 00602 /* Set the camera model view. */ 00603 camera->set_gl_modelview(); 00604 00605 /* Render the world axis. */ 00606 if (modes.render_world_axis) 00607 { 00608 render_world_axis(); 00609 } 00610 00611 render_scene(); 00612 00613 /* Render the focal plane if in that mode. */ 00614 if (modes.render_focal_plane) 00615 { 00616 render_focal_plane(); 00617 } 00618 00619 glFlush(); 00620 } 00621 00623 void display_glut() 00624 { 00625 static uint32_t N = 1; 00626 00627 if (modes.anaglyph) 00628 { 00629 display_glut_anaglyph(); 00630 } 00631 else 00632 { 00633 display_glut_regular(); 00634 } 00635 00636 glutSwapBuffers(); 00637 00638 if (modes.capture_view) 00639 { 00640 Stereo_camera_f::capture_gl_view(capture_fmt, N++); 00641 modes.capture_view = 0; 00642 } 00643 } 00644 00645 00647 void reshape_glut(int w, int h) 00648 { 00649 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00650 glViewport(0, 0, (GLsizei)w, (GLsizei)h); 00651 view_width = w; 00652 view_height = h; 00653 } 00654 00656 void keyboard_glut(unsigned char key, int a, int b) 00657 { 00658 float translate_delta = 10; 00659 float rotate_delta = 10*JWSC_DEG_TO_RAD; 00660 float focal_length; 00661 float theta; 00662 00663 Vector_f* v_tmp = 0; 00664 Alternaria* alt; 00665 00666 switch (key) { 00667 case 't': 00668 modes.translate_camera = true; 00669 modes.rotate_camera = false; 00670 modes.modify_structure = false; 00671 break; 00672 case 'r': 00673 modes.rotate_camera = true; 00674 modes.translate_camera = false; 00675 modes.modify_structure = false; 00676 break; 00677 case 'l': 00678 if (modes.translate_camera) 00679 { 00680 const Vector_f* right = camera->get_u(); 00681 camera->translate( 00682 translate_delta * right->elts[0], 00683 translate_delta * right->elts[1], 00684 translate_delta * right->elts[2]); 00685 } 00686 else if (modes.rotate_camera) 00687 { 00688 camera->rotate(-rotate_delta, 0, 1, 0); 00689 } 00690 else if (modes.modify_structure && highlight) 00691 { 00692 float width = highlight->get_width(); 00693 try 00694 { 00695 highlight->set_width(width + 0.5); 00696 } 00697 catch (Arg_error e) 00698 { 00699 e.print_details(); 00700 } 00701 } 00702 glutPostRedisplay(); 00703 break; 00704 case 'h': 00705 if (modes.translate_camera) 00706 { 00707 const Vector_f* right = camera->get_u(); 00708 camera->translate( 00709 -translate_delta * right->elts[0], 00710 -translate_delta * right->elts[1], 00711 -translate_delta * right->elts[2]); 00712 } 00713 else if (modes.rotate_camera) 00714 { 00715 camera->rotate(rotate_delta, 0, 1, 0); 00716 } 00717 else if (modes.modify_structure && highlight) 00718 { 00719 float width = highlight->get_width(); 00720 try 00721 { 00722 highlight->set_width(width - 0.5); 00723 } 00724 catch (Arg_error e) 00725 { 00726 e.print_details(); 00727 } 00728 } 00729 glutPostRedisplay(); 00730 break; 00731 case 'L': 00732 if (modes.translate_camera) 00733 { 00734 const Vector_f* right = camera->get_u(); 00735 camera->translate( 00736 translate_delta * right->elts[0], 00737 translate_delta * right->elts[1], 00738 translate_delta * right->elts[2]); 00739 } 00740 else if (modes.rotate_camera) 00741 { 00742 copy_vector_f(&v_tmp, camera->get_prp()); 00743 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00744 camera->translate(v_tmp); 00745 camera->rotate(rotate_delta, camera->get_v()); 00746 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00747 camera->translate(v_tmp); 00748 } 00749 else if (modes.modify_structure && highlight) 00750 { 00751 float psi = highlight->get_psi() + 0.1f*JWSC_PI_2; 00752 if (psi > spore_d->get_psi().get_max() 00753 && (psi - JWSC_2_PI) >= spore_d->get_psi().get_min()) 00754 { 00755 psi -= JWSC_2_PI; 00756 } 00757 try 00758 { 00759 highlight->set_psi(psi); 00760 } 00761 catch (Arg_error e) 00762 { 00763 e.print_details(); 00764 } 00765 } 00766 glutPostRedisplay(); 00767 break; 00768 case 'H': 00769 if (modes.translate_camera) 00770 { 00771 const Vector_f* right = camera->get_u(); 00772 camera->translate( 00773 -translate_delta * right->elts[0], 00774 -translate_delta * right->elts[1], 00775 -translate_delta * right->elts[2]); 00776 } 00777 else if (modes.rotate_camera) 00778 { 00779 copy_vector_f(&v_tmp, camera->get_prp()); 00780 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00781 camera->translate(v_tmp); 00782 camera->rotate(-rotate_delta, camera->get_v()); 00783 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00784 camera->translate(v_tmp); 00785 } 00786 else if (modes.modify_structure && highlight) 00787 { 00788 float psi = highlight->get_psi() - 0.1f*JWSC_PI_2; 00789 if (psi < spore_d->get_psi().get_min() 00790 && (psi + JWSC_2_PI) <= spore_d->get_psi().get_max()) 00791 { 00792 psi += JWSC_2_PI; 00793 } 00794 try 00795 { 00796 highlight->set_psi(psi); 00797 } 00798 catch (Arg_error e) 00799 { 00800 e.print_details(); 00801 } 00802 } 00803 glutPostRedisplay(); 00804 break; 00805 case 'k': 00806 if (modes.translate_camera) 00807 { 00808 const Vector_f* up = camera->get_v(); 00809 camera->translate( 00810 translate_delta * up->elts[0], 00811 translate_delta * up->elts[1], 00812 translate_delta * up->elts[2]); 00813 } 00814 else if (modes.rotate_camera) 00815 { 00816 camera->rotate(rotate_delta, camera->get_u()); 00817 } 00818 else if (modes.modify_structure && highlight) 00819 { 00820 float length = highlight->get_length(); 00821 try 00822 { 00823 highlight->set_length(length + 1); 00824 } 00825 catch (Arg_error e) 00826 { 00827 e.print_details(); 00828 } 00829 } 00830 glutPostRedisplay(); 00831 break; 00832 case 'j': 00833 if (modes.translate_camera) 00834 { 00835 const Vector_f* up = camera->get_v(); 00836 camera->translate( 00837 -translate_delta * up->elts[0], 00838 -translate_delta * up->elts[1], 00839 -translate_delta * up->elts[2]); 00840 } 00841 else if (modes.rotate_camera) 00842 { 00843 camera->rotate(-rotate_delta, camera->get_u()); 00844 } 00845 else if (modes.modify_structure && highlight) 00846 { 00847 float length = highlight->get_length(); 00848 try 00849 { 00850 highlight->set_length(length - 1); 00851 } 00852 catch (Arg_error e) 00853 { 00854 e.print_details(); 00855 } 00856 } 00857 glutPostRedisplay(); 00858 break; 00859 case 'K': 00860 if (modes.translate_camera) 00861 { 00862 const Vector_f* view = camera->get_n(); 00863 camera->translate( 00864 -translate_delta * view->elts[0], 00865 -translate_delta * view->elts[1], 00866 -translate_delta * view->elts[2]); 00867 } 00868 else if (modes.rotate_camera) 00869 { 00870 copy_vector_f(&v_tmp, camera->get_prp()); 00871 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00872 camera->translate(v_tmp); 00873 camera->rotate(-rotate_delta, camera->get_u()); 00874 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00875 camera->translate(v_tmp); 00876 } 00877 else if (modes.modify_structure && highlight) 00878 { 00879 float theta = highlight->get_theta(); 00880 try 00881 { 00882 highlight->set_theta(theta + 0.1f*JWSC_PI_2); 00883 } 00884 catch (Arg_error e) 00885 { 00886 e.print_details(); 00887 } 00888 } 00889 glutPostRedisplay(); 00890 break; 00891 case 'J': 00892 if (modes.translate_camera) 00893 { 00894 const Vector_f* view = camera->get_n(); 00895 camera->translate( 00896 translate_delta * view->elts[0], 00897 translate_delta * view->elts[1], 00898 translate_delta * view->elts[2]); 00899 } 00900 else if (modes.rotate_camera) 00901 { 00902 copy_vector_f(&v_tmp, camera->get_prp()); 00903 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00904 camera->translate(v_tmp); 00905 camera->rotate(rotate_delta, camera->get_u()); 00906 multiply_vector_by_scalar_f(&v_tmp, v_tmp, -1); 00907 camera->translate(v_tmp); 00908 } 00909 else if (modes.modify_structure && highlight) 00910 { 00911 float theta = highlight->get_theta(); 00912 try 00913 { 00914 highlight->set_theta(theta - 0.1f*JWSC_PI_2); 00915 } 00916 catch (Arg_error e) 00917 { 00918 e.print_details(); 00919 } 00920 } 00921 glutPostRedisplay(); 00922 break; 00923 case 'v': 00924 if (modes.modify_structure && highlight 00925 && dynamic_cast<Apical_structure*>(highlight)) 00926 { 00927 Apical_structure* apical = (Apical_structure*)highlight; 00928 const Vector_f* centroid = apical->get_centroid(); 00929 float x = centroid->elts[0] + 00930 sample_gaussian_pdf_d(0, 1, -10, 10); 00931 float y = centroid->elts[1] + 00932 sample_gaussian_pdf_d(0, 1, -10, 10); 00933 float z = centroid->elts[2] + 00934 sample_gaussian_pdf_d(0, 1, -10, 10); 00935 try 00936 { 00937 apical->set_position(x, y, z); 00938 } 00939 catch (Arg_error e) 00940 { 00941 e.print_details(); 00942 } 00943 glutPostRedisplay(); 00944 } 00945 break; 00946 case 'V': 00947 break; 00948 case 'b': 00949 if (modes.modify_structure && highlight 00950 && dynamic_cast<Lateral_structure*>(highlight)) 00951 { 00952 Lateral_structure* lat = (Lateral_structure*)highlight; 00953 float lat_dist = lat->get_lat_dist(); 00954 try 00955 { 00956 lat->set_lat_dist(lat_dist - 0.1); 00957 } 00958 catch (Arg_error e) 00959 { 00960 Structure* parent = 0; 00961 float max = lat->get_density()->get_lat_dist().get_max(); 00962 00963 if (dynamic_cast<Apical_structure*>(lat->get_parent()) && 00964 (parent = lat->get_parent()->get_parent())) 00965 { 00966 try 00967 { 00968 lat->set_parent(parent, max - 0.1); 00969 } 00970 catch (Arg_error e) 00971 { 00972 e.print_details(); 00973 } 00974 } 00975 else 00976 { 00977 e.print_details(); 00978 } 00979 } 00980 glutPostRedisplay(); 00981 } 00982 break; 00983 case 'B': 00984 if (modes.modify_structure && highlight 00985 && dynamic_cast<Lateral_structure*>(highlight)) 00986 { 00987 Lateral_structure* lat = (Lateral_structure*)highlight; 00988 float lat_dist = lat->get_lat_dist(); 00989 try 00990 { 00991 lat->set_lat_dist(lat_dist + 0.1); 00992 } 00993 catch (Arg_error e) 00994 { 00995 Apical_structure* apical = 0; 00996 float min = lat->get_density()->get_lat_dist().get_min(); 00997 00998 if (lat->get_parent() && 00999 (apical = lat->get_parent()->get_apical())) 01000 { 01001 try 01002 { 01003 lat->set_parent(apical, min + 0.1); 01004 } 01005 catch (Arg_error e) 01006 { 01007 e.print_details(); 01008 } 01009 } 01010 else 01011 { 01012 e.print_details(); 01013 } 01014 } 01015 glutPostRedisplay(); 01016 } 01017 break; 01018 case 'm': 01019 if (modes.modify_structure && highlight 01020 && dynamic_cast<Apical_hypha*>(highlight)) 01021 { 01022 Apical_hypha* rvals_1 = 0; 01023 Apical_hypha* rvals_2 = 0; 01024 01025 try 01026 { 01027 float width_1 = highlight->get_width() + 01028 apical_hypha_d->sample_dwidth(); 01029 float width_2 = highlight->get_width() + 01030 apical_hypha_d->sample_dwidth(); 01031 rvals_1 = apical_hypha_d->sample(); 01032 rvals_1->set_width(width_1); 01033 rvals_2 = apical_hypha_d->sample(); 01034 rvals_2->set_width(width_2); 01035 alternaria->split_apical_hypha_into_apical( 01036 (Apical_hypha*)highlight, rvals_1, rvals_2); 01037 highlight = 0; 01038 delete rvals_1; 01039 delete rvals_2; 01040 } 01041 catch (Arg_error e) 01042 { 01043 delete rvals_1; 01044 delete rvals_2; 01045 e.print_details(); 01046 } 01047 } 01048 else if (modes.modify_structure && highlight 01049 && dynamic_cast<Spore*>(highlight)) 01050 { 01051 Spore* rvals_1 = spore_d->sample(); 01052 Spore* rvals_2 = spore_d->sample(); 01053 01054 float width = 0.65f*highlight->get_width(); 01055 float sigma = spore_d->get_width().get_sigma(); 01056 float min = -6.0f*sigma; 01057 float max = 6.0f*sigma; 01058 01059 try 01060 { 01061 width += sample_gaussian_pdf_d(0, sigma, min, max); 01062 rvals_1->set_width(width); 01063 width += sample_gaussian_pdf_d(0, sigma, min, max); 01064 rvals_1->set_width(width); 01065 alternaria->split_spore_into_spore( 01066 (Spore*)highlight, rvals_1, rvals_2); 01067 highlight = 0; 01068 delete rvals_1; 01069 delete rvals_2; 01070 } 01071 catch (Arg_error e) 01072 { 01073 delete rvals_1; 01074 delete rvals_2; 01075 e.print_details(); 01076 } 01077 } 01078 glutPostRedisplay(); 01079 break; 01080 case 'M': 01081 if (modes.modify_structure && highlight 01082 && dynamic_cast<Apical_hypha*>(highlight)) 01083 { 01084 Apical_hypha* rvals = 0; 01085 01086 try 01087 { 01088 float width = highlight->get_width() + 01089 apical_hypha_d->sample_dwidth(); 01090 rvals = apical_hypha_d->sample(); 01091 rvals->set_width(width); 01092 alternaria->merge_apical_hypha_with_apical( 01093 (Apical_hypha*)highlight, rvals); 01094 highlight = 0; 01095 delete rvals; 01096 } 01097 catch (Arg_error e) 01098 { 01099 delete rvals; 01100 e.print_details(); 01101 } 01102 } 01103 else if (modes.modify_structure && highlight 01104 && highlight->get_apical() 01105 && dynamic_cast<Spore*>(highlight)) 01106 { 01107 Spore* rvals = spore_d->sample(); 01108 01109 float width = 0.65f*highlight->get_width() + 01110 0.65f*highlight->get_apical()->get_width(); 01111 float sigma = spore_d->get_width().get_sigma(); 01112 float min = -6.0f*sigma; 01113 float max = 6.0f*sigma; 01114 01115 try 01116 { 01117 width += sample_gaussian_pdf_d(0, sigma, min, max); 01118 rvals->set_width(width); 01119 alternaria->merge_spore_with_spore((Spore*)highlight,rvals); 01120 highlight = 0; 01121 delete rvals; 01122 } 01123 catch (Arg_error e) 01124 { 01125 delete rvals; 01126 e.print_details(); 01127 } 01128 } 01129 glutPostRedisplay(); 01130 break; 01131 case 'n': 01132 if (modes.modify_structure && highlight 01133 && dynamic_cast<Apical_hypha*>(highlight)) 01134 { 01135 Apical_hypha* rvals_1 = 0; 01136 Lateral_hypha* rvals_2 = 0; 01137 01138 try 01139 { 01140 float width = highlight->get_width() + 01141 apical_hypha_d->sample_dwidth(); 01142 rvals_1 = apical_hypha_d->sample(); 01143 rvals_1->set_width(width); 01144 if (highlight->get_level() == 0) 01145 { 01146 rvals_2 = lateral_hypha_1_d->sample(); 01147 } 01148 else 01149 { 01150 rvals_2 = lateral_hypha_n_d->sample(); 01151 } 01152 alternaria->split_apical_hypha_into_lateral( 01153 (Apical_hypha*)highlight, rvals_1, rvals_2); 01154 delete rvals_1; 01155 delete rvals_2; 01156 } 01157 catch (Arg_error e) 01158 { 01159 delete rvals_1; 01160 delete rvals_2; 01161 e.print_details(); 01162 } 01163 glutPostRedisplay(); 01164 } 01165 break; 01166 case 'N': 01167 if (modes.modify_structure && highlight && highlight->get_parent() 01168 && dynamic_cast<Apical_hypha*>(highlight->get_parent()) 01169 && dynamic_cast<Lateral_hypha*>(highlight)) 01170 { 01171 Apical_hypha* rvals = 0; 01172 01173 try 01174 { 01175 float width = highlight->get_width() + 01176 apical_hypha_d->sample_dwidth(); 01177 rvals = apical_hypha_d->sample(); 01178 rvals->set_width(width); 01179 alternaria->merge_apical_hypha_with_lateral( 01180 (Apical_hypha*)highlight->get_parent(), 01181 (Lateral_hypha*)highlight, rvals); 01182 highlight = 0; 01183 delete rvals; 01184 } 01185 catch (Arg_error e) 01186 { 01187 delete rvals; 01188 e.print_details(); 01189 } 01190 glutPostRedisplay(); 01191 } 01192 break; 01193 case 'F': 01194 if (modes.focal_prp) 01195 { 01196 focal_length = camera->get_focal_length() + 20; 01197 camera->set_f_with_same_aperture_using_prp(focal_length); 01198 } 01199 else if (modes.focal_vrp) 01200 { 01201 focal_length = camera->get_focal_length() + 20; 01202 camera->set_f_with_same_aperture_using_vrp(focal_length); 01203 } 01204 glutPostRedisplay(); 01205 break; 01206 case 'f': 01207 if (modes.focal_prp) 01208 { 01209 focal_length = camera->get_focal_length(); 01210 if (focal_length >= 22) 01211 { 01212 focal_length -= 20; 01213 camera->set_f_with_same_aperture_using_prp(focal_length); 01214 } 01215 } 01216 else if (modes.focal_vrp) 01217 { 01218 focal_length = camera->get_focal_length(); 01219 if (focal_length >= 22) 01220 { 01221 focal_length -= 20; 01222 camera->set_f_with_same_aperture_using_vrp(focal_length); 01223 } 01224 } 01225 glutPostRedisplay(); 01226 break; 01227 case 'S': 01228 if (object_scale >= 2.99f) 01229 { 01230 object_scale = 3.0f; 01231 } 01232 else 01233 { 01234 object_scale += 0.01f; 01235 } 01236 glutPostRedisplay(); 01237 break; 01238 case 's': 01239 if (object_scale > 0.01f) 01240 { 01241 object_scale -= 0.01f; 01242 } 01243 glutPostRedisplay(); 01244 break; 01245 case 'A': 01246 aperture += JWSC_PI_8; 01247 camera->set_aperture(aperture); 01248 glutPostRedisplay(); 01249 break; 01250 case 'a': 01251 theta = aperture - JWSC_PI_8; 01252 if (theta >= 0) 01253 { 01254 aperture = theta; 01255 camera->set_aperture(theta); 01256 } 01257 glutPostRedisplay(); 01258 break; 01259 case 'c': 01260 modes.capture_view = 1; 01261 glutPostRedisplay(); 01262 break; 01263 case 'C': 01264 alt = alternaria->clone(); 01265 delete alternaria; 01266 alternaria = alt; 01267 highlight = 0; 01268 glutPostRedisplay(); 01269 break; 01270 case 'o': 01271 reset(); 01272 glutPostRedisplay(); 01273 break; 01274 case 'w': 01275 imaging->print(img_out_fname); 01276 psf->print(psf_out_fname); 01277 alternaria->print(alt_out_fname); 01278 break; 01279 case 'W': 01280 if (psf_h_fmt) 01281 { 01282 psf->write_h(psf_h_fmt); 01283 } 01284 if (alt_scene_fmt) 01285 { 01286 Alternaria_model* model = new Alternaria_model(*alternaria, 01287 psf, imaging); 01288 model->write_scene(alt_scene_fmt, psf); 01289 delete model; 01290 } 01291 break; 01292 case 'q': 01293 free_vector_f(v_tmp); 01294 clean_up(); 01295 exit(EXIT_SUCCESS); 01296 } 01297 01298 free_vector_f(v_tmp); 01299 } 01300 01302 void mouse_glut(int button, int state, int x, int y) 01303 { 01304 Vector_f* near_pt = 0; 01305 Vector_f* far_pt = 0; 01306 Vector_f* isect_pt = 0; 01307 01308 if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 01309 { 01310 float u = (float)x - (float)view_width / 2.0f; 01311 float v = (float)view_height / 2.0f - (float)y; 01312 camera->get_image_pt_on_near_clipping_plane(&near_pt, u, v); 01313 camera->get_image_pt_on_far_clipping_plane(&far_pt, u, v); 01314 01315 // Undo the transformation of the view in render_scene(). 01316 multiply_vector_by_scalar_f(&near_pt, near_pt, 1.0f/object_scale); 01317 multiply_vector_by_scalar_f(&far_pt, far_pt, 1.0f/object_scale); 01318 01319 float x = alternaria->get_root()->get_centroid()->elts[0]; 01320 float y = alternaria->get_root()->get_centroid()->elts[1]; 01321 float z = alternaria->get_root()->get_centroid()->elts[2]; 01322 Vector_f* V = 0; 01323 create_vector_f(&V, 3); 01324 V->elts[0] = x; V->elts[1] = y; V->elts[2] = z; 01325 add_vectors_f(&near_pt, near_pt, V); 01326 add_vectors_f(&far_pt, far_pt, V); 01327 free_vector_f(V); 01328 01329 highlight = 0; 01330 float t_min = 1.0f; 01331 01332 vector<Structure*>* structs = alternaria->get_root()->get_descendants(); 01333 01334 for (size_t i = 0; i < structs->size(); i++) 01335 { 01336 float t = structs->at(i)->get_intersection(&isect_pt, 1, near_pt, 01337 far_pt); 01338 if (t >= 0 && t <= t_min) 01339 { 01340 t_min = t; 01341 highlight = structs->at(i); 01342 } 01343 } 01344 01345 delete structs; 01346 01347 if (highlight) 01348 { 01349 highlight->print(); 01350 } 01351 01352 glutPostRedisplay(); 01353 } 01354 01355 free_vector_f(near_pt); 01356 free_vector_f(far_pt); 01357 free_vector_f(isect_pt); 01358 } 01359 01361 void main_menu_glut(int id) 01362 { 01363 switch (id) 01364 { 01365 case 0: 01366 modes.capture_view = 1; 01367 glutPostRedisplay(); 01368 break; 01369 case 1: 01370 reset(); 01371 glutPostRedisplay(); 01372 break; 01373 case 2: 01374 clean_up(); 01375 exit(EXIT_SUCCESS); 01376 } 01377 } 01378 01380 void option_menu_glut(int id) 01381 { 01382 switch (id) 01383 { 01384 case 0: 01385 modes.anaglyph = !modes.anaglyph; 01386 glutPostRedisplay(); 01387 break; 01388 case 1: 01389 modes.render_focal_plane = !modes.render_focal_plane; 01390 glutPostRedisplay(); 01391 break; 01392 case 2: 01393 modes.render_world_axis = !modes.render_world_axis; 01394 glutPostRedisplay(); 01395 break; 01396 } 01397 } 01398 01400 void navigation_menu_glut(int id) 01401 { 01402 switch (id) 01403 { 01404 case 0: 01405 modes.rotate_camera = true; 01406 modes.translate_camera = false; 01407 modes.modify_structure = false; 01408 break; 01409 case 1: 01410 modes.rotate_camera = false; 01411 modes.translate_camera = true; 01412 modes.modify_structure = false; 01413 break; 01414 case 2: 01415 modes.rotate_camera = false; 01416 modes.translate_camera = false; 01417 modes.modify_structure = true; 01418 break; 01419 } 01420 } 01421 01423 void focal_length_menu_glut(int id) 01424 { 01425 switch (id) 01426 { 01427 case 0: 01428 modes.focal_prp = true; 01429 modes.focal_vrp = false; 01430 break; 01431 case 1: 01432 modes.focal_prp = false; 01433 modes.focal_vrp = true; 01434 break; 01435 } 01436 } 01437 01439 void init_glut(int argc, char** argv) 01440 { 01441 glutInit(&argc, argv); 01442 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_ACCUM 01443 | GLUT_ALPHA); 01444 glutInitWindowSize(view_width, view_height); 01445 glutCreateWindow("Alternaria Structure Tester"); 01446 glutDisplayFunc(display_glut); 01447 glutReshapeFunc(reshape_glut); 01448 glutKeyboardFunc(keyboard_glut); 01449 glutMouseFunc(mouse_glut); 01450 01451 int navigation = glutCreateMenu(navigation_menu_glut); 01452 glutAddMenuEntry("Rotate Camera", 0); 01453 glutAddMenuEntry("Translate Camera", 1); 01454 glutAddMenuEntry("Modify Structure", 2); 01455 01456 int focal_length = glutCreateMenu(focal_length_menu_glut); 01457 glutAddMenuEntry("PRP", 0); 01458 glutAddMenuEntry("VRP", 1); 01459 01460 int options = glutCreateMenu(option_menu_glut); 01461 glutAddMenuEntry("Anaglyph", 0); 01462 glutAddMenuEntry("Focal Plane", 1); 01463 glutAddMenuEntry("Axis", 2); 01464 01465 glutCreateMenu(main_menu_glut); 01466 glutAddSubMenu("Navigation", navigation); 01467 glutAddSubMenu("Focal Length", focal_length); 01468 glutAddSubMenu("Options", options); 01469 glutAddMenuEntry("Capture", 1); 01470 glutAddMenuEntry("Reset", 2); 01471 glutAddMenuEntry("Quit", 3); 01472 01473 glutAttachMenu(GLUT_RIGHT_BUTTON); 01474 } 01475 01477 void init_gl() 01478 { 01479 glEnable(GL_DEPTH_TEST); 01480 glEnable(GL_NORMALIZE); 01481 glEnable(GL_LIGHTING); 01482 01483 static GLfloat base_amb[] = {0.0f, 0.0f, 0.0f, 0.0f}; 01484 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, base_amb); 01485 01486 static GLfloat ambient0 [] = {0.2f, 0.2f, 0.2f, 1.0f}; 01487 static GLfloat diffuse0 [] = {0.8f, 0.8f, 0.8f, 1.0f}; 01488 static GLfloat specular0 [] = {0.9f, 0.9f, 0.9f, 1.0f}; 01489 static GLfloat direction0[] = {500.0f, 500.0f, 2000.0f, 1.0f}; 01490 01491 glEnable(GL_LIGHT0); 01492 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0); 01493 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0); 01494 glLightfv(GL_LIGHT0, GL_SPECULAR, specular0); 01495 glLightfv(GL_LIGHT0, GL_POSITION, direction0); 01496 01497 static GLfloat ambient1 [] = {0.1f, 0.1f, 0.1f, 1.0f}; 01498 static GLfloat diffuse1 [] = {0.4f, 0.4f, 0.4f, 1.0f}; 01499 static GLfloat specular1 [] = {0.5f, 0.5f, 0.5f, 1.0f}; 01500 static GLfloat direction1[] = {500.0f, 500.0f, 2000.0f, 1.0f}; 01501 01502 glDisable(GL_LIGHT1); 01503 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1); 01504 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1); 01505 glLightfv(GL_LIGHT1, GL_SPECULAR, specular1); 01506 glLightfv(GL_LIGHT1, GL_POSITION, direction1); 01507 01508 if (!quad_fill) 01509 { 01510 quad_fill = gluNewQuadric(); 01511 gluQuadricDrawStyle(quad_fill, GLU_FILL); 01512 } 01513 01514 if (!quad_wire) 01515 { 01516 quad_wire = gluNewQuadric(); 01517 gluQuadricDrawStyle(quad_wire, GLU_LINE); 01518 } 01519 01520 glLineWidth(1.0); 01521 glPointSize(1.0); 01522 glClearColor(0.0, 0.0, 0.0, 0.0); 01523 glClearAccum(0.0, 0.0, 0.0, 0.0); 01524 01525 glViewport(0, 0, view_width, view_height); 01526 } 01527 01529 void print_usage(void) 01530 { 01531 cerr << "usage: alternaria-gen OPTIONS\n"; 01532 cerr << "where OPTIONS is one or more of the following:\n"; 01533 opts->print(cerr, 33); 01534 } 01535 01537 void process_help_opt(void) 01538 { 01539 print_usage(); 01540 clean_up(); 01541 exit(EXIT_SUCCESS); 01542 } 01543 01545 void process_version_opt(void) 01546 { 01547 cout << ALTERNARIA_PACKAGE_STRING << "\n"; 01548 clean_up(); 01549 exit(EXIT_SUCCESS); 01550 } 01551 01553 void process_options_opt(const char* arg) throw (Arg_error) 01554 { 01555 if (!arg) 01556 { 01557 throw Arg_error("Option 'options' requires an argument"); 01558 } 01559 try 01560 { 01561 opts->process(arg); 01562 } 01563 catch (IO_error e) 01564 { 01565 throw Arg_error(e.get_msg()); 01566 } 01567 } 01568 01570 void process_seed_opt(const char* arg) throw (Arg_error) 01571 { 01572 if (!arg) 01573 { 01574 throw Arg_error("Option 'seed' requires an argument"); 01575 } 01576 if (sscanf(arg, "%u", &seed) != 1) 01577 { 01578 throw Arg_error("Option 'seed' must be a non-negative integer"); 01579 } 01580 } 01581 01583 void process_apical_hypha_length_opt(const char* arg) throw (Arg_error) 01584 { 01585 float mu, sigma, min, max; 01586 01587 if (!arg) 01588 { 01589 throw Arg_error("Option 'apical-hypha-length' requires an argument"); 01590 } 01591 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01592 { 01593 throw Arg_error("Option 'apical-hypha-length' has format mu,sigma,min,max"); 01594 } 01595 try 01596 { 01597 apical_hypha_d->set_length(mu, sigma, min, max); 01598 } 01599 catch (Arg_error e) 01600 { 01601 ostringstream ost; 01602 ost << "Option 'apical-hypha-length': " << e.get_msg(); 01603 throw Arg_error(ost.str()); 01604 } 01605 } 01606 01608 void process_lateral_hypha_length_opt(const char* arg) throw (Arg_error) 01609 { 01610 float mu, sigma, min, max; 01611 01612 if (!arg) 01613 { 01614 throw Arg_error("Option 'lateral-hypha-length' requires an argument"); 01615 } 01616 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01617 { 01618 throw Arg_error("Option 'lateral-hypha-length' has format mu,sigma,min,max"); 01619 } 01620 try 01621 { 01622 lateral_hypha_1_d->set_length(mu, sigma, min, max); 01623 lateral_hypha_n_d->set_length(mu, sigma, min, max); 01624 } 01625 catch (Arg_error e) 01626 { 01627 ostringstream ost; 01628 ost << "Option 'lateral-hypha-length': " << e.get_msg(); 01629 throw Arg_error(ost.str()); 01630 } 01631 } 01632 01634 void process_apical_hypha_width_opt(const char* arg) throw (Arg_error) 01635 { 01636 float mu, sigma, min, max; 01637 01638 if (!arg) 01639 { 01640 throw Arg_error("Option 'apical-hypha-width' requires an argument"); 01641 } 01642 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01643 { 01644 throw Arg_error("Option 'apical-hypha-width' has format mu,sigma,min,max"); 01645 } 01646 try 01647 { 01648 apical_hypha_d->set_width(mu, sigma, min, max); 01649 } 01650 catch (Arg_error e) 01651 { 01652 ostringstream ost; 01653 ost << "Option 'apical-hypha-width': " << e.get_msg(); 01654 throw Arg_error(ost.str()); 01655 } 01656 } 01657 01659 void process_lateral_hypha_width_opt(const char* arg) throw (Arg_error) 01660 { 01661 float mu, sigma, min, max; 01662 01663 if (!arg) 01664 { 01665 throw Arg_error("Option 'lateral-hypha-width' requires an argument"); 01666 } 01667 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01668 { 01669 throw Arg_error("Option 'lateral-hypha-width' has format mu,sigma,min,max"); 01670 } 01671 try 01672 { 01673 lateral_hypha_1_d->set_width(mu, sigma, min, max); 01674 lateral_hypha_n_d->set_width(mu, sigma, min, max); 01675 } 01676 catch (Arg_error e) 01677 { 01678 ostringstream ost; 01679 ost << "Option 'lateral-hypha-width': " << e.get_msg(); 01680 throw Arg_error(ost.str()); 01681 } 01682 } 01683 01685 void process_apical_hypha_theta_opt(const char* arg) throw (Arg_error) 01686 { 01687 float mu, sigma, min, max; 01688 01689 if (!arg) 01690 { 01691 throw Arg_error("Option 'apical-hypha-theta' requires an argument"); 01692 } 01693 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01694 { 01695 throw Arg_error("Option 'apical-hypha-theta' has format mu,sigma,min,max"); 01696 } 01697 try 01698 { 01699 apical_hypha_d->set_theta(mu, sigma, min, max); 01700 } 01701 catch (Arg_error e) 01702 { 01703 ostringstream ost; 01704 ost << "Option 'apical-hypha-theta': " << e.get_msg(); 01705 throw Arg_error(ost.str()); 01706 } 01707 } 01708 01710 void process_lateral_hypha_1_theta_opt(const char* arg) throw (Arg_error) 01711 { 01712 float mu, sigma, min, max; 01713 01714 if (!arg) 01715 { 01716 throw Arg_error("Option 'lateral-hypha-1-theta' requires an argument"); 01717 } 01718 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01719 { 01720 throw Arg_error("Option 'lateral-hypha-1-theta' has format mu,sigma,min,max"); 01721 } 01722 try 01723 { 01724 lateral_hypha_1_d->set_theta(mu, sigma, min, max); 01725 } 01726 catch (Arg_error e) 01727 { 01728 ostringstream ost; 01729 ost << "Option 'lateral-hypha-1-theta': " << e.get_msg(); 01730 throw Arg_error(ost.str()); 01731 } 01732 } 01733 01735 void process_lateral_hypha_n_theta_opt(const char* arg) throw (Arg_error) 01736 { 01737 float mu, sigma, min, max; 01738 01739 if (!arg) 01740 { 01741 throw Arg_error("Option 'lateral-hypha-n-theta' requires an argument"); 01742 } 01743 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01744 { 01745 throw Arg_error("Option 'lateral-hypha-n-theta' has format mu,sigma,min,max"); 01746 } 01747 try 01748 { 01749 lateral_hypha_n_d->set_theta(mu, sigma, min, max); 01750 } 01751 catch (Arg_error e) 01752 { 01753 ostringstream ost; 01754 ost << "Option 'lateral-hypha-n-theta': " << e.get_msg(); 01755 throw Arg_error(ost.str()); 01756 } 01757 } 01758 01760 void process_hypha_psi_opt(const char* arg) throw (Arg_error) 01761 { 01762 float min, max; 01763 01764 if (!arg) 01765 { 01766 throw Arg_error("Option 'hypha-psi' requires an argument"); 01767 } 01768 if (sscanf(arg, "%f,%f", &min, &max) != 2) 01769 { 01770 throw Arg_error("Option 'hypha-psi' has format min,max"); 01771 } 01772 try 01773 { 01774 apical_hypha_d->set_psi(min, max); 01775 lateral_hypha_1_d->set_psi(min, max); 01776 lateral_hypha_n_d->set_psi(min, max); 01777 } 01778 catch (Arg_error e) 01779 { 01780 ostringstream ost; 01781 ost << "Option 'hypha-psi': " << e.get_msg(); 01782 throw Arg_error(ost.str()); 01783 } 01784 } 01785 01787 void process_hypha_opacity_opt(const char* arg) throw (Arg_error) 01788 { 01789 float mu, sigma, min, max; 01790 01791 if (!arg) 01792 { 01793 throw Arg_error("Option 'hypha-opacity' requires an argument"); 01794 } 01795 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01796 { 01797 throw Arg_error("Option 'hypha-opacity' has format mu,sigma,min,max"); 01798 } 01799 try 01800 { 01801 apical_hypha_d->set_opacity(mu, sigma, min, max); 01802 lateral_hypha_1_d->set_opacity(mu, sigma, min, max); 01803 lateral_hypha_n_d->set_opacity(mu, sigma, min, max); 01804 } 01805 catch (Arg_error e) 01806 { 01807 ostringstream ost; 01808 ost << "Option 'hypha-opacity': " << e.get_msg(); 01809 throw Arg_error(ost.str()); 01810 } 01811 } 01812 01814 void process_lateral_hypha_dist_opt(const char* arg) throw (Arg_error) 01815 { 01816 float mu, sigma, min, max; 01817 01818 if (!arg) 01819 { 01820 throw Arg_error("Option 'lateral-hypha-dist' requires an argument"); 01821 } 01822 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01823 { 01824 throw Arg_error("Option 'lateral-hypha-dist' has format mu,sigma,min,max"); 01825 } 01826 try 01827 { 01828 lateral_hypha_1_d->set_lat_dist(mu, sigma, min, max); 01829 lateral_hypha_n_d->set_lat_dist(mu, sigma, min, max); 01830 } 01831 catch (Arg_error e) 01832 { 01833 ostringstream ost; 01834 ost << "Option 'lateral-hypha-dist': " << e.get_msg(); 01835 throw Arg_error(ost.str()); 01836 } 01837 } 01838 01840 void process_spore_length_opt(const char* arg) throw (Arg_error) 01841 { 01842 float mu, sigma, min, max; 01843 01844 if (!arg) 01845 { 01846 throw Arg_error("Option 'spore-length' requires an argument"); 01847 } 01848 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01849 { 01850 throw Arg_error("Option 'spore-length' has format mu,sigma,min,max"); 01851 } 01852 try 01853 { 01854 spore_d->set_length(mu, sigma, min, max); 01855 } 01856 catch (Arg_error e) 01857 { 01858 ostringstream ost; 01859 ost << "Option 'spore-length': " << e.get_msg(); 01860 throw Arg_error(ost.str()); 01861 } 01862 } 01863 01865 void process_spore_width_opt(const char* arg) throw (Arg_error) 01866 { 01867 float mu, sigma, min, max; 01868 01869 if (!arg) 01870 { 01871 throw Arg_error("Option 'spore-width' requires an argument"); 01872 } 01873 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01874 { 01875 throw Arg_error("Option 'spore-width' has format mu,sigma,min,max"); 01876 } 01877 try 01878 { 01879 spore_d->set_width(mu, sigma, min, max); 01880 } 01881 catch (Arg_error e) 01882 { 01883 ostringstream ost; 01884 ost << "Option 'spore-width': " << e.get_msg(); 01885 throw Arg_error(ost.str()); 01886 } 01887 } 01888 01890 void process_spore_theta_opt(const char* arg) throw (Arg_error) 01891 { 01892 float mu, sigma, min, max; 01893 01894 if (!arg) 01895 { 01896 throw Arg_error("Option 'spore-theta' requires an argument"); 01897 } 01898 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01899 { 01900 throw Arg_error("Option 'spore-theta' has format mu,sigma,min,max"); 01901 } 01902 try 01903 { 01904 spore_d->set_theta(mu, sigma, min, max); 01905 } 01906 catch (Arg_error e) 01907 { 01908 ostringstream ost; 01909 ost << "Option 'spore-theta': " << e.get_msg(); 01910 throw Arg_error(ost.str()); 01911 } 01912 } 01913 01915 void process_spore_psi_opt(const char* arg) throw (Arg_error) 01916 { 01917 float min, max; 01918 01919 if (!arg) 01920 { 01921 throw Arg_error("Option 'spore-psi' requires an argument"); 01922 } 01923 if (sscanf(arg, "%f,%f", &min, &max) != 2) 01924 { 01925 throw Arg_error("Option 'spore-psi' has format min,max"); 01926 } 01927 try 01928 { 01929 spore_d->set_psi(min, max); 01930 } 01931 catch (Arg_error e) 01932 { 01933 ostringstream ost; 01934 ost << "Option 'spore-psi': " << e.get_msg(); 01935 throw Arg_error(ost.str()); 01936 } 01937 } 01938 01940 void process_spore_opacity_opt(const char* arg) throw (Arg_error) 01941 { 01942 float mu, sigma, min, max; 01943 01944 if (!arg) 01945 { 01946 throw Arg_error("Option 'spore-opacity' requires an argument"); 01947 } 01948 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01949 { 01950 throw Arg_error("Option 'spore-opacity' has format mu,sigma,min,max"); 01951 } 01952 try 01953 { 01954 spore_d->set_opacity(mu, sigma, min, max); 01955 } 01956 catch (Arg_error e) 01957 { 01958 ostringstream ost; 01959 ost << "Option 'spore-opacity': " << e.get_msg(); 01960 throw Arg_error(ost.str()); 01961 } 01962 } 01963 01965 void process_psf_alpha_opt(const char* arg) throw (Arg_error) 01966 { 01967 float mu, sigma, min, max; 01968 01969 if (!arg) 01970 { 01971 throw Arg_error("Option 'psf-alpha' requires an argument"); 01972 } 01973 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01974 { 01975 throw Arg_error("Option 'psf-alpha' has format mu,sigma,min,max"); 01976 } 01977 try 01978 { 01979 psf_d->set_alpha(mu, sigma, min, max); 01980 } 01981 catch (Arg_error e) 01982 { 01983 ostringstream ost; 01984 ost << "Option 'psf-alpha': " << e.get_msg(); 01985 throw Arg_error(ost.str()); 01986 } 01987 } 01988 01990 void process_psf_beta_opt(const char* arg) throw (Arg_error) 01991 { 01992 float mu, sigma, min, max; 01993 01994 if (!arg) 01995 { 01996 throw Arg_error("Option 'psf-beta' requires an argument"); 01997 } 01998 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 01999 { 02000 throw Arg_error("Option 'psf-beta' has format mu,sigma,min,max"); 02001 } 02002 try 02003 { 02004 psf_d->set_beta(mu, sigma, min, max); 02005 } 02006 catch (Arg_error e) 02007 { 02008 ostringstream ost; 02009 ost << "Option 'psf-beta': " << e.get_msg(); 02010 throw Arg_error(ost.str()); 02011 } 02012 } 02013 02015 void process_psf_gamma_opt(const char* arg) throw (Arg_error) 02016 { 02017 float mu, sigma, min, max; 02018 02019 if (!arg) 02020 { 02021 throw Arg_error("Option 'psf-gamma' requires an argument"); 02022 } 02023 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 02024 { 02025 throw Arg_error("Option 'psf-gamma' has format mu,sigma,min,max"); 02026 } 02027 try 02028 { 02029 psf_d->set_gamma(mu, sigma, min, max); 02030 } 02031 catch (Arg_error e) 02032 { 02033 ostringstream ost; 02034 ost << "Option 'psf-gamma': " << e.get_msg(); 02035 throw Arg_error(ost.str()); 02036 } 02037 } 02038 02040 void process_img_bg_opt(const char* arg) throw (Arg_error) 02041 { 02042 float mu, sigma, min, max; 02043 02044 if (!arg) 02045 { 02046 throw Arg_error("Option 'img-bg' requires an argument"); 02047 } 02048 if (sscanf(arg, "%f,%f,%f,%f", &mu, &sigma, &min, &max) != 4) 02049 { 02050 throw Arg_error("Option 'img-bg' has format mu,sigma,min,max"); 02051 } 02052 try 02053 { 02054 imaging_d->set_bg(mu, sigma, min, max); 02055 } 02056 catch (Arg_error e) 02057 { 02058 ostringstream ost; 02059 ost << "Option 'img-bg': " << e.get_msg(); 02060 throw Arg_error(ost.str()); 02061 } 02062 } 02063 02065 void process_levels_p_opt(const char* arg) throw (Arg_error) 02066 { 02067 float p; 02068 02069 if (!arg) 02070 { 02071 throw Arg_error("Option 'levels-p' requires an argument"); 02072 } 02073 if (sscanf(arg, "%f", &p) != 1) 02074 { 02075 throw Arg_error("Option 'levels-p' must be in a number in (0,1)"); 02076 } 02077 try 02078 { 02079 alt_d->set_num_levels_p(p); 02080 } 02081 catch (Arg_error e) 02082 { 02083 ostringstream ost; 02084 ost << "Option 'levels-p': " << e.get_msg(); 02085 throw Arg_error(ost.str()); 02086 } 02087 } 02088 02090 void process_structs_p_opt(const char* arg) throw (Arg_error) 02091 { 02092 float spore_p, apical_hypha_p, lateral_hypha_1_p, lateral_hypha_n_p; 02093 02094 if (!arg) 02095 { 02096 throw Arg_error("Option 'structs-p' requires an argument"); 02097 } 02098 if (sscanf(arg, "%f,%f,%f,%f", &spore_p, &apical_hypha_p, &lateral_hypha_1_p, &lateral_hypha_n_p) != 4) 02099 { 02100 throw Arg_error("Option 'structs-p' has format spore,apical-hypha,lateral-hypha-1,lateral-hypha-n"); 02101 } 02102 try 02103 { 02104 alt_d->set_structure_p(spore_p, apical_hypha_p, lateral_hypha_1_p, 02105 lateral_hypha_n_p); 02106 } 02107 catch (Arg_error e) 02108 { 02109 ostringstream ost; 02110 ost << "Option 'structs-p': " << e.get_msg(); 02111 throw Arg_error(ost.str()); 02112 } 02113 } 02114 02116 void process_img_in_opt(const char* arg) throw (Arg_error) 02117 { 02118 if (!arg) 02119 { 02120 throw Arg_error("Option 'img-in' requires an argument"); 02121 } 02122 img_in_fname = arg; 02123 } 02124 02126 void process_img_out_opt(const char* arg) throw (Arg_error) 02127 { 02128 if (!arg) 02129 { 02130 throw Arg_error("Option 'img-out' requires an argument"); 02131 } 02132 img_out_fname = arg; 02133 } 02134 02136 void process_psf_in_opt(const char* arg) throw (Arg_error) 02137 { 02138 if (!arg) 02139 { 02140 throw Arg_error("Option 'psf-in' requires an argument"); 02141 } 02142 psf_in_fname = arg; 02143 } 02144 02146 void process_psf_out_opt(const char* arg) throw (Arg_error) 02147 { 02148 if (!arg) 02149 { 02150 throw Arg_error("Option 'psf-out' requires an argument"); 02151 } 02152 psf_out_fname = arg; 02153 } 02154 02156 void process_alt_in_opt(const char* arg) throw (Arg_error) 02157 { 02158 if (!arg) 02159 { 02160 throw Arg_error("Option 'alt-in' requires an argument"); 02161 } 02162 alt_in_fname = arg; 02163 } 02164 02166 void process_alt_out_opt(const char* arg) throw (Arg_error) 02167 { 02168 if (!arg) 02169 { 02170 throw Arg_error("Option 'alt-out' requires an argument"); 02171 } 02172 alt_out_fname = arg; 02173 } 02174 02176 void process_scene_fmt_opt(const char* arg) throw (Arg_error) 02177 { 02178 if (!arg) 02179 { 02180 throw Arg_error("Option 'scene-fmt' requires an argument"); 02181 } 02182 alt_scene_fmt = arg; 02183 } 02184 02186 void process_scene_size_opt(const char* arg) throw (Arg_error) 02187 { 02188 uint32_t ncols, nrows, nimgs; 02189 02190 if (!arg) 02191 { 02192 throw Arg_error("Option 'scene-size' requires an argument"); 02193 } 02194 if (sscanf(arg, "%u,%u,%u", &ncols, &nrows, &nimgs) != 3) 02195 { 02196 throw Arg_error("Option 'scene-size' has format ncols,nrows,nimgs"); 02197 } 02198 try 02199 { 02200 img_window->set(0, 0, 0, ncols, nrows, nimgs); 02201 } 02202 catch (Arg_error e) 02203 { 02204 ostringstream ost; 02205 ost << "Option 'scene-size': " << e.get_msg(); 02206 throw Arg_error(ost.str()); 02207 } 02208 } 02209 02211 void process_scene_scale_opt(const char* arg) throw (Arg_error) 02212 { 02213 float x, y, z; 02214 02215 if (!arg) 02216 { 02217 throw Arg_error("Option 'scene-scale' requires an argument"); 02218 } 02219 if (sscanf(arg, "%f,%f,%f", &x, &y, &z) != 3) 02220 { 02221 throw Arg_error("Option 'scene-scale' has format x,y,z"); 02222 } 02223 try 02224 { 02225 img_scale->set(x, y, z); 02226 } 02227 catch (Arg_error e) 02228 { 02229 ostringstream ost; 02230 ost << "Option 'scene-scale': " << e.get_msg(); 02231 throw Arg_error(ost.str()); 02232 } 02233 } 02234 02236 void process_psf_fmt_opt(const char* arg) throw (Arg_error) 02237 { 02238 if (!arg) 02239 { 02240 throw Arg_error("Option 'psf-fmt' requires an argument"); 02241 } 02242 psf_h_fmt = arg; 02243 } 02244 02246 void process_num_structs_opt(const char* arg) throw (Arg_error) 02247 { 02248 if (!arg) 02249 { 02250 throw Arg_error("Option 'num-structs' requires an argument"); 02251 } 02252 if (sscanf(arg, "%u", &num_structs) != 1) 02253 { 02254 throw Arg_error("Option 'num-structs' must be an integer"); 02255 } 02256 } 02257 02259 void process_interactive_opt() throw (Arg_error) 02260 { 02261 interactive = true; 02262 } 02263 02265 void process_view_size_opt(const char* arg) throw (Arg_error) 02266 { 02267 int32_t w, h; 02268 02269 if (!arg) 02270 { 02271 throw Arg_error("Option 'view-size' requires an argument"); 02272 } 02273 if (sscanf(arg, "%d,%d", &w, &h) != 2) 02274 { 02275 throw Arg_error("Option 'view-size' has format width,height"); 02276 } 02277 if (w <= 0 || h <= 0) 02278 { 02279 throw Arg_error("Option 'view-size' must have width,height > 0"); 02280 } 02281 view_width = (uint32_t)w; 02282 view_height = (uint32_t)h; 02283 } 02284 02286 void process_glasses_opt(const char* arg) throw (Arg_error) 02287 { 02288 if (!arg) 02289 { 02290 throw Arg_error("Option 'glasses' requires an argument"); 02291 } 02292 if (strcmp("red-blue", arg) == 0) 02293 glasses_type = REDBLUE; 02294 else if (strcmp("red-green", arg) == 0) 02295 glasses_type = REDGREEN; 02296 else if (strcmp("red-cyan", arg) == 0) 02297 glasses_type = REDCYAN; 02298 else if (strcmp("blue-red", arg) == 0) 02299 glasses_type = BLUERED; 02300 else if (strcmp("green-red", arg) == 0) 02301 glasses_type = GREENRED; 02302 else if (strcmp("cyan-red", arg) == 0) 02303 glasses_type = CYANRED; 02304 else 02305 { 02306 throw Arg_error("Invalid 'glasses' type"); 02307 } 02308 } 02309 02311 void process_capture_opt(const char* arg) throw (Arg_error) 02312 { 02313 if (!arg) 02314 { 02315 throw Arg_error("Option 'capture' requires an argument"); 02316 } 02317 capture_fmt = arg; 02318 } 02319 02321 void process_base_level_opt(const char* arg) throw (Arg_error) 02322 { 02323 if (!arg) 02324 { 02325 throw Arg_error("Option 'base-level' requires an argument"); 02326 } 02327 if (sscanf(arg, "%u", &base_level) != 1) 02328 { 02329 throw Arg_error("Option 'base-level' must be >= 0"); 02330 } 02331 } 02332 02334 void init_options() 02335 { 02336 using jwscxx::base::Option_no_arg; 02337 using jwscxx::base::Option_with_arg; 02338 02339 const char* l_name; 02340 const char* desc; 02341 02342 opts = new Options(); 02343 02344 l_name = "help"; 02345 desc = "Program usage"; 02346 opts->add(new Option_no_arg('h', l_name, desc, process_help_opt)); 02347 02348 l_name = "version"; 02349 desc = "Program version."; 02350 opts->add(new Option_no_arg('v', l_name, desc, process_version_opt)); 02351 02352 l_name = "options"; 02353 desc = "Process a file of program options."; 02354 opts->add(new Option_with_arg(0, l_name, desc, process_options_opt)); 02355 02356 l_name = "interactive"; 02357 desc = "Show the generated Alternaria in an interactive GLUT/GL window."; 02358 opts->add(new Option_no_arg('i', l_name, desc, process_interactive_opt)); 02359 02360 l_name = "view-size"; 02361 desc = "Interactive window View size with format width,height. Default is 400,400."; 02362 opts->add(new Option_with_arg(0, l_name, desc, process_view_size_opt)); 02363 02364 l_name = "glasses"; 02365 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."; 02366 opts->add(new Option_with_arg(0, l_name, desc, process_glasses_opt)); 02367 02368 l_name = "capture"; 02369 desc = "Printf-formatted file write captured view images to."; 02370 opts->add(new Option_with_arg(0, l_name, desc, process_capture_opt)); 02371 02372 l_name = "seed"; 02373 desc = "Random seed to use in srand(). Must be a non-negative integer."; 02374 opts->add(new Option_with_arg(0, l_name, desc, process_seed_opt)); 02375 02376 l_name = "img-in"; 02377 desc = "Imaging input file to read from."; 02378 opts->add(new Option_with_arg(0, l_name, desc, process_img_in_opt)); 02379 02380 l_name = "img-out"; 02381 desc = "Imaging output file to write to."; 02382 opts->add(new Option_with_arg(0, l_name, desc, process_img_out_opt)); 02383 02384 l_name = "psf-in"; 02385 desc = "PSF input file to read from."; 02386 opts->add(new Option_with_arg(0, l_name, desc, process_psf_in_opt)); 02387 02388 l_name = "psf-out"; 02389 desc = "PSF output file to write to."; 02390 opts->add(new Option_with_arg(0, l_name, desc, process_psf_out_opt)); 02391 02392 l_name = "alt-in"; 02393 desc = "Alternaria input file to read from."; 02394 opts->add(new Option_with_arg(0, l_name, desc, process_alt_in_opt)); 02395 02396 l_name = "alt-out"; 02397 desc = "Alternaria output file to write to."; 02398 opts->add(new Option_with_arg(0, l_name, desc, process_alt_out_opt)); 02399 02400 l_name = "scene-fmt"; 02401 desc = "Printf-formatted file name for the optically sectioned scene. Must contain one integer conversion"; 02402 opts->add(new Option_with_arg(0, l_name, desc, process_scene_fmt_opt)); 02403 02404 l_name = "scene-scale"; 02405 desc = "Number of alternaria world units per image pixel. Has format x,y,z."; 02406 opts->add(new Option_with_arg(0, l_name, desc, process_scene_scale_opt)); 02407 02408 l_name = "scene-size"; 02409 desc = "Width, height, and number of images to write the optically sectioned scene to. Has format ncols,nrows,nimgs."; 02410 opts->add(new Option_with_arg(0, l_name, desc, process_scene_size_opt)); 02411 02412 l_name = "psf-fmt"; 02413 desc = "Printf-formatted file name for the optically sectioned PSF. Must contain one integer conversion."; 02414 opts->add(new Option_with_arg(0, l_name, desc, process_psf_fmt_opt)); 02415 02416 l_name = "num-structs"; 02417 desc = "Number of structure elements to generate in the Alternaria. Must be an integer."; 02418 opts->add(new Option_with_arg(0, l_name, desc, process_num_structs_opt)); 02419 02420 l_name = "apical-hypha-length"; 02421 desc = "Length of an apical hypha. Has argument format mu,sigma,min,max."; 02422 opts->add(new Option_with_arg(0, l_name, desc, 02423 process_apical_hypha_length_opt)); 02424 02425 l_name = "lateral-hypha-length"; 02426 desc = "Length of a lateral hypha. Has argument format mu,sigma,min,max."; 02427 opts->add(new Option_with_arg(0, l_name, desc, 02428 process_lateral_hypha_length_opt)); 02429 02430 l_name = "apical-hypha-width"; 02431 desc = "Width of an apical hypha. Has argument format mu,sigma,min,max."; 02432 opts->add(new Option_with_arg(0, l_name, desc, 02433 process_apical_hypha_width_opt)); 02434 02435 l_name = "lateral-hypha-width"; 02436 desc = "Width of a lateral hypha. Has argument format mu,sigma,min,max."; 02437 opts->add(new Option_with_arg(0, l_name, desc, 02438 process_lateral_hypha_width_opt)); 02439 02440 l_name = "apical-hypha-theta"; 02441 desc = "Theta Euler angle of an apical hypha. Has argument format mu,sigma,min,max."; 02442 opts->add(new Option_with_arg(0, l_name, desc, 02443 process_apical_hypha_theta_opt)); 02444 02445 l_name = "lateral-hypha-1-theta"; 02446 desc = "Theta Euler angle of a lateral hypha at level 1. Has argument format mu,sigma,min,max."; 02447 opts->add(new Option_with_arg(0, l_name, desc, 02448 process_lateral_hypha_1_theta_opt)); 02449 02450 l_name = "lateral-hypha-n-theta"; 02451 desc = "Theta Euler angle of a lateral hypha at level > 1. Has argument format mu,sigma,min,max."; 02452 opts->add(new Option_with_arg(0, l_name, desc, 02453 process_lateral_hypha_n_theta_opt)); 02454 02455 l_name = "hypha-psi"; 02456 desc = "Psi Euler angle of a hypha. Has argument format mu,sigma,min,max."; 02457 opts->add(new Option_with_arg(0, l_name, desc, process_hypha_psi_opt)); 02458 02459 l_name = "hypha-opacity"; 02460 desc = "Opacity of a hypha. Has argument format mu,sigma,min,max."; 02461 opts->add(new Option_with_arg(0, l_name, desc, process_hypha_opacity_opt)); 02462 02463 l_name = "lateral-hypha-dist"; 02464 desc = "Distance of a lateral hypha from its parent. Has argument format mu,sigma,min,max."; 02465 opts->add(new Option_with_arg(0, l_name, desc, 02466 process_lateral_hypha_dist_opt)); 02467 02468 l_name = "spore-width"; 02469 desc = "Width of a spore. Has argument format mu,sigma,min,max."; 02470 opts->add(new Option_with_arg(0, l_name, desc, process_spore_width_opt)); 02471 02472 l_name = "spore-length"; 02473 desc = "Length of a spore. Has argument format mu,sigma,min,max."; 02474 opts->add(new Option_with_arg(0, l_name, desc, process_spore_length_opt)); 02475 02476 l_name = "spore-theta"; 02477 desc = "Theta Euler angle of a spore. Has argument format mu,sigma,min,max."; 02478 opts->add(new Option_with_arg(0, l_name, desc, process_spore_theta_opt)); 02479 02480 l_name = "spore-psi"; 02481 desc = "Psi Euler angle of a spore. Has argument format min,max."; 02482 opts->add(new Option_with_arg(0, l_name, desc, process_spore_psi_opt)); 02483 02484 l_name = "spore-opacity"; 02485 desc = "Opacity of a spore. Has argument format mu,sigma,min,max."; 02486 opts->add(new Option_with_arg(0, l_name, desc, process_spore_opacity_opt)); 02487 02488 l_name = "psf-alpha"; 02489 desc = "PSF alpha parameter. Has argument format mu,sigma,min,max."; 02490 opts->add(new Option_with_arg(0, l_name, desc, process_psf_alpha_opt)); 02491 02492 l_name = "psf-beta"; 02493 desc = "PSF beta parameter. Has argument format mu,sigma,min,max."; 02494 opts->add(new Option_with_arg(0, l_name, desc, process_psf_beta_opt)); 02495 02496 l_name = "psf-gamma"; 02497 desc = "PSF gamma parameter. Has argument format mu,sigma,min,max."; 02498 opts->add(new Option_with_arg(0, l_name, desc, process_psf_gamma_opt)); 02499 02500 l_name = "img-bg"; 02501 desc = "Image background parameter. Has argument format mu,sigma,min,max."; 02502 opts->add(new Option_with_arg(0, l_name, desc, process_img_bg_opt)); 02503 02504 l_name = "levels-p"; 02505 desc = "Geometric distribution parameter over growth levels. Must be in (0,1)"; 02506 opts->add(new Option_with_arg(0, l_name, desc, process_levels_p_opt)); 02507 02508 l_name = "structs-p"; 02509 desc = "Distribution over structure type. Has argument format spore,apical-hypha,lateral-hypha. All must sum to 1."; 02510 opts->add(new Option_with_arg(0, l_name, desc, process_structs_p_opt)); 02511 02512 l_name = "base-level"; 02513 desc = "Base level for the root Structure. Must be >= 0."; 02514 opts->add(new Option_with_arg(0, l_name, desc, process_base_level_opt)); 02515 } 02516 02517 02518 void* operator new (size_t s) throw (std::bad_alloc) 02519 { 02520 return malloc(s); 02521 } 02522 02523 02524 void operator delete (void* ptr) throw () 02525 { 02526 if (ptr) 02527 free(ptr); 02528 } 02529 02530 02531 02532 02534 int main(int argc, char** argv) 02535 { 02536 init_options(); 02537 02538 try 02539 { 02540 img_window = new Imaging_window(); 02541 img_scale = new Imaging_scale(); 02542 padding = new PSF_padding(); 02543 imaging_d = new Imaging_model_density(); 02544 psf_d = new PSF_model_density(); 02545 spore_d = new Spore_density(); 02546 apical_hypha_d = new Apical_hypha_density(); 02547 lateral_hypha_1_d = new Lateral_hypha_density(); 02548 lateral_hypha_n_d = new Lateral_hypha_density(); 02549 alt_d = new Alternaria_density(); 02550 02551 img_window->set(0, 0, 0, NUM_SCENE_COLS, NUM_SCENE_ROWS, 02552 NUM_SCENE_IMGS); 02553 02554 spore_d->set_centroid_x(CENTROID_MIN, CENTROID_MAX); 02555 spore_d->set_centroid_y(CENTROID_MIN, CENTROID_MAX); 02556 spore_d->set_centroid_z(CENTROID_MIN, CENTROID_MAX); 02557 02558 apical_hypha_d->set_centroid_x(CENTROID_MIN, CENTROID_MAX); 02559 apical_hypha_d->set_centroid_y(CENTROID_MIN, CENTROID_MAX); 02560 apical_hypha_d->set_centroid_z(CENTROID_MIN, CENTROID_MAX); 02561 02562 lateral_hypha_1_d->set_centroid_x(CENTROID_MIN, CENTROID_MAX); 02563 lateral_hypha_1_d->set_centroid_y(CENTROID_MIN, CENTROID_MAX); 02564 lateral_hypha_1_d->set_centroid_z(CENTROID_MIN, CENTROID_MAX); 02565 02566 lateral_hypha_n_d->set_centroid_x(CENTROID_MIN, CENTROID_MAX); 02567 lateral_hypha_n_d->set_centroid_y(CENTROID_MIN, CENTROID_MAX); 02568 lateral_hypha_n_d->set_centroid_z(CENTROID_MIN, CENTROID_MAX); 02569 02570 opts->process(argc, argv); 02571 02572 std::srand(seed); 02573 02574 // Sometimes the first few draws off the generator are always ~0. 02575 std::rand(); 02576 std::rand(); 02577 std::rand(); 02578 02579 if (img_in_fname) 02580 { 02581 imaging = new Imaging_model(img_in_fname, img_window, img_scale, 02582 imaging_d); 02583 } 02584 else 02585 { 02586 imaging = imaging_d->sample(img_window, img_scale); 02587 } 02588 02589 if (psf_in_fname) 02590 { 02591 psf = new PSF_model(psf_in_fname, padding, psf_d, imaging); 02592 } 02593 else 02594 { 02595 psf = psf_d->sample(padding, imaging); 02596 } 02597 02598 if (alt_in_fname) 02599 { 02600 alternaria = new Alternaria(alt_in_fname, alt_d, spore_d, 02601 apical_hypha_d, lateral_hypha_1_d, lateral_hypha_n_d); 02602 } 02603 else 02604 { 02605 float x = 0.5f*img_scale->get_x()*img_window->get_num_cols(); 02606 float y = 0.5f*apical_hypha_d->sample_length(); 02607 float z = 0.5f*img_scale->get_z()*img_window->get_num_imgs(); 02608 alternaria = alt_d->sample(num_structs, x, y, z, JWSC_PI_2, 0, 02609 base_level, spore_d, apical_hypha_d, lateral_hypha_1_d, 02610 lateral_hypha_n_d); 02611 } 02612 02613 if (interactive) 02614 { 02615 init_glut(argc, argv); 02616 init_gl(); 02617 init_camera(); 02618 init_modes(); 02619 glutMainLoop(); 02620 } 02621 else 02622 { 02623 if (img_out_fname) 02624 { 02625 imaging->print(img_out_fname); 02626 } 02627 if (psf_out_fname) 02628 { 02629 psf->print(psf_out_fname); 02630 } 02631 if (alt_out_fname) 02632 { 02633 alternaria->print(alt_out_fname); 02634 } 02635 if (psf_h_fmt) 02636 { 02637 psf->write_h(psf_h_fmt); 02638 } 02639 if (alt_scene_fmt) 02640 { 02641 Alternaria_model* model = new Alternaria_model(*alternaria, 02642 psf, imaging); 02643 model->write_scene(alt_scene_fmt, psf); 02644 delete model; 02645 } 02646 } 02647 } 02648 catch (Exception e) 02649 { 02650 cerr << "alternaria_gen: "; 02651 e.print(); 02652 } 02653 02654 clean_up(); 02655 02656 return EXIT_SUCCESS; 02657 }