00001 #include "std/fstream.H"
00002 #include "disp/animator.H"
00003 #include "disp/recorder.H"
00004 #include "geom/gl_util.H"
00005 #include "geom/distrib.H"
00006 #include "geom/recorder_ui.H"
00007 #include "geom/texture.H"
00008 #include "geom/world.H"
00009 #include "gtex/ref_image.H"
00010 #include "gtex/buffer_ref_image.H"
00011 #include "gtex/curvature_ui.H"
00012 #include "gtex/fader_texture.H"
00013 #include "gtex/flat_shade.H"
00014 #include "gtex/key_line.H"
00015 #include "gtex/sil_frame.H"
00016 #include "manip/cam_pz.H"
00017 #include "manip/cam_fp.H"
00018 #include "mesh/hybrid.H"
00019 #include "mesh/lmesh.H"
00020 #include "mesh/objreader.H"
00021 #include "mesh/patch.H"
00022 #include "mlib/points.H"
00023
00024 using namespace mlib;
00025
00026 #include "std/run_avg.H"
00027 #include "std/stop_watch.H"
00028 #include "std/support.H"
00029 #include "std/time.H"
00030 #include "widgets/alert_box.H"
00031 #include "widgets/file_select.H"
00032 #include "widgets/fps.H"
00033 #include "widgets/menu.H"
00034
00035 #include "base_jotapp/base_jotapp.H"
00036
00037
00038
00039 int bk_camera(const Event& ev, State *& s);
00040 int fwd_camera(const Event& ev, State *& s);
00041
00042 int next_texture(const Event&, State *&);
00043
00044 int rotate_camera(const Event& ev, State *&);
00045
00046 int toggle_buffer(const Event&, State *&);
00047
00048 int toggle_antialias(const Event&, State *&);
00049 int next_antialias(const Event&, State *&);
00050
00051 int freeze_sils(const Event&, State *&);
00052
00053 int toggle_random_sils(const Event&, State *&);
00054
00055 int toggle_hidden_lines(const Event&, State *&);
00056
00057 int debug_cb(const Event& ev, State *&);
00058
00059 int clear_cb(const Event&, State *&);
00060
00061 void alert_cbs(void *ptr, void *dptr, int idx, int but_idx);
00062
00063 void do_clear();
00064
00065 int save_cb(const Event&, State *&);
00066 int load_cb(const Event&, State *&);
00067
00068 void file_cbs(void *ptr, int idx, int action, str_ptr path, str_ptr file);
00069
00070 void do_save(str_ptr fullpath);
00071 void do_load(str_ptr fullpath);
00072
00073 int animation_keys(const Event &e, State *&s);
00074
00075 int render_mode(const Event &e, State *&s);
00076
00077 int toggle_recorder(const Event &, State *&);
00078 int rec_play(const Event &, State *&);
00079 int rec_rec(const Event &, State *&);
00080 int rec_stop(const Event &, State *&);
00081 int rec_pause(const Event &, State *&);
00082
00083 int toggle_repair(const Event &, State *&);
00084
00085 int undo_redo(const Event &e, State *&);
00086
00087 int quit(const Event&, State *&);
00088
00089 int refine(const Event&, State *&);
00090
00091 int cycle_subdiv_loc_calc(const Event&, State *&);
00092
00093 int clear_selections(const Event&, State *&);
00094
00095 int unrefine(const Event&, State *&);
00096
00097 int toggle_transp(const Event&e, State *&);
00098
00099 int write(const Event&, State *&);
00100
00101 int print_mesh(const Event&, State *&);
00102
00103 int write_xformed(const Event&, State *&);
00104
00105 int write_merged_meshes(const Event&, State *&);
00106
00107 int save_config(const Event &e, State *&);
00108
00109 int clear_creases(const Event&, State*&);
00110
00111 int toggle_no_text(const Event&, State*&);
00112
00113 int toggle_show_secondary_faces(const Event&, State *&);
00114
00115 int recreate_creases(const Event&, State *&);
00116 int toggle_crease(const Event &, State *&);
00117
00118 int split_mesh(const Event &e, State *&);
00119
00120 int kill_component(const Event &, State *&);
00121
00122 int print_key_menu(const Event&, State *&);
00123
00124 int toggle_curvature_ui(const Event&, State *&);
00125
00126
00127
00128
00129
00130 class SMVIEWapp : public BaseJOTapp {
00131
00132 public:
00133
00134
00135 class WINDOWjot : public BaseJOTapp::WINDOW
00136 {
00137 public:
00138 State _otherstart;
00139
00140 WINDOWjot(WINSYS *win) : WINDOW(win) {}
00141 };
00142
00143 protected:
00144
00145
00146
00147
00148
00149
00150 static void splash_cb(void *j, void *jd, int, int) {
00151 ((SMVIEWapp *)j)->_windows[0]->_view->set_focus();
00152 }
00153
00154 public:
00155
00156
00157 SMVIEWapp(int argc, char **argv) : BaseJOTapp(argc, argv) {}
00158
00159
00160 protected:
00161
00162 virtual WINDOW* new_window(WINSYS *win) { return new WINDOWjot(win);}
00163
00164 virtual void init_scene();
00165
00166 virtual void init_interact_cb(WINDOW &base_window);
00167
00168 virtual void init_kbd(WINDOW &base_window);
00169
00170 virtual void init_fsa();
00171
00172 public:
00173 virtual void init()
00174 {
00175 srand48((long)the_time());
00176
00177 BaseJOTapp::init();
00178
00179
00180
00181
00182
00183 splash_cb(this,NULL,0,0);
00184 }
00185 };
00186
00187
00188
00189
00190
00191
00192
00193
00194 void
00195 SMVIEWapp::init_scene()
00196 {
00197 int i;
00198
00199
00200 BaseJOTapp::init_scene();
00201
00202
00203
00204 for (i=0; i<_windows.num(); i++) {
00205 _windows[i]->_view->set_rendering(
00206 Config::get_var_str("JOT_RENDER_STYLE", **RSMOOTH_SHADE));
00207 }
00208
00209 }
00210
00211
00212
00213
00214 void
00215 SMVIEWapp::init_interact_cb(WINDOW &base_window)
00216 {
00217 BaseJOTapp::init_interact_cb(base_window);
00218
00219
00220
00221
00222 }
00223
00224
00225
00226
00227
00228 void
00229 SMVIEWapp::init_kbd(WINDOW &base_window)
00230 {
00231
00232 BaseJOTapp::init_kbd(base_window);
00233
00234
00235
00236 _key_menu->add_menu_item('a', "Toggle antialias", &toggle_antialias);
00237 _key_menu->add_menu_item('A', "Toggle next antialias", &next_antialias);
00238 _key_menu->add_menu_item('b', "Toggle buffer", &toggle_buffer);
00239 _key_menu->add_menu_item('c', "Clear (delete) all objects", &clear_cb);
00240
00241 _key_menu->add_menu_item('D', "Toggle no_text", &toggle_no_text);
00242 _key_menu->add_menu_item('d', "Debug callback", &debug_cb);
00243 _key_menu->add_menu_item('F', "Freeze sils", &freeze_sils);
00244 _key_menu->add_menu_item('i', "Recreate Creases", &recreate_creases);
00245 _key_menu->add_menu_item('k', "Clear creases", &clear_creases);
00246 _key_menu->add_menu_item('l', "Load File", &load_cb);
00247 _key_menu->add_menu_item('N', "Next texture", &next_texture);
00248 _key_menu->add_menu_item('p', "Print mesh statistics", &print_mesh);
00249 _key_menu->add_menu_item('r', "Rotate", &rotate_camera);
00250 _key_menu->add_menu_item('s', "Save", &save_cb);
00251 _key_menu->add_menu_item('S', "Cycle subdivision loc calc", &cycle_subdiv_loc_calc);
00252 _key_menu->add_menu_item("t", "Refine mesh", &refine);
00253 _key_menu->add_menu_item('U', "Unrefine mesh", &unrefine);
00254 _key_menu->add_menu_item('w', "Write mesh", &write);
00255 _key_menu->add_menu_item('W', "Write_xformed mesh", &write_xformed);
00256
00257 _key_menu->add_menu_item('Z', "Toggle hidden lines in Key Line rendering style",
00258 &toggle_hidden_lines);
00259 _key_menu->add_menu_item('=', "Toggle random sils", &toggle_random_sils);
00260
00261
00262
00263 _key_menu->add_menu_item("CX/*-+24568", "Animation keys", &animation_keys);
00264
00265 _key_menu->add_menu_item("\r\n\x8\x7f", "Undo Redo", &undo_redo);
00266
00267 _key_menu->add_menu_item("!@#", "Render mode", &render_mode);
00268
00269 _key_menu->add_menu_item("%", "Toggle Curvature gTexture UI", &toggle_curvature_ui);
00270 }
00271
00272
00273
00274
00275 void
00276 SMVIEWapp::init_fsa()
00277 {
00278 BaseJOTapp::init_fsa();
00279
00280 for (int i = 0; i < _windows.num(); i++)
00281 {
00282 WINDOWjot *winjot = (WINDOWjot *) _windows[i];
00283 VIEWint_list::add(_windows[i]->_view, &winjot->_otherstart);
00284 }
00285
00286 }
00287
00288
00289
00290
00291 int
00292 main(int argc, char **argv)
00293 {
00294 SMVIEWapp app(argc, argv);
00295
00296 app.init();
00297 app.Run();
00298
00299 return 0;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308 enum alert_cb_t {
00309 ALERT_CLEAR_CB = 0,
00310 ALERT_SAVE_JOT_OVERWRITE_CB,
00311 ALERT_SAVE_JOT_FAILED_CB,
00312 ALERT_LOAD_JOT_FAILED_CB
00313 };
00314
00315 enum file_cb_t {
00316 FILE_SAVE_JOT_CB = 0,
00317 FILE_LOAD_JOT_CB
00318
00319 };
00320
00321
00322
00323
00324
00325
00326 inline BMESH*
00327 find_mesh()
00328 {
00329 BMESH* ret = BMESH::center_of_interest();
00330 return ret ? ret : VisRefImage::get_mesh();
00331 }
00332
00333 inline BMESH*
00334 find_ctrl_mesh()
00335 {
00336 return get_ctrl_mesh(find_mesh());
00337 }
00338
00339 int
00340 bk_camera(const Event& ev, State *& s)
00341 {
00342 ((VIEWptr) (ev.view()))->bk_cam_hist();
00343 return 0;
00344 }
00345
00346 int
00347 fwd_camera(const Event& ev, State *& s)
00348 {
00349 ((VIEWptr) (ev.view()))->fwd_cam_hist();
00350 return 0;
00351 }
00352
00353 int
00354 next_texture(const Event&, State *&)
00355 {
00356 Patch* patch = VisRefImage::get_ctrl_patch();
00357
00358 if (patch) {
00359 patch->next_texture();
00360 WORLD::message(patch->cur_tex()->class_name());
00361 }
00362
00363 return 0;
00364 }
00365
00366
00367 int
00368 rotate_camera(const Event& ev, State *&)
00369 {
00370 CAMptr cam (ev.view()->cam());
00371 CAMdataptr data(cam->data());
00372
00373 cam->set_zoom(1);
00374 cam->set_min(NDCpt(XYpt(-1,-1)));
00375 cam->data()->changed();
00376
00377 XYpt cpt = data->center();
00378 double radsq = sqr(1+fabs(cpt[0]));
00379
00380
00381
00382
00383
00384
00385 XYpt tp = XYpt(0.485, 0.5);
00386 XYpt te = XYpt(0.5,0.5);
00387
00388
00389 Wvec op (tp[0], 0, 0);
00390 Wvec oe (te[0], 0, 0);
00391 double opsq = op * op, oesq = oe * oe;
00392 double lop = opsq > radsq ? 0 : sqrt(radsq - opsq);
00393 double loe = oesq > radsq ? 0 : sqrt(radsq - oesq);
00394 Wvec nop = Wvec(op[0], 0, lop).normalized();
00395 Wvec noe = Wvec(oe[0], 0, loe).normalized();
00396 double dot = nop * noe;
00397
00398 if (fabs(dot) > 0.0001) {
00399 data->rotate(Wline(data->center(), Wvec::Y()),
00400 -2*Acos(dot) * Sign(te[0]-tp[0]));
00401
00402 double rdist = te[1]-tp[1];
00403
00404 CAMdata dd = CAMdata(*data);
00405
00406 Wline raxe(data->center(),data->right_v());
00407 data->rotate(raxe, rdist);
00408 data->set_up(data->from() + Wvec::Y());
00409 if (data->right_v() * dd.right_v() < 0)
00410 *data = dd;
00411 }
00412
00413 return 0;
00414 }
00415
00416
00417 int
00418 toggle_buffer(const Event& ev, State *&)
00419 {
00420 BufferRefImage *buf = BufferRefImage::lookup(ev.view());
00421 if (buf)
00422 {
00423 if (buf->is_observing())
00424 {
00425 cerr << "DrawInt: BufferRefImage was observing -- Toggling OFF..\n";
00426 buf->unobserve();
00427 }
00428 else
00429 {
00430 cerr << "DrawInt: BufferRefImage was NOT observing -- Toggling ON...\n";
00431 buf->observe();
00432 }
00433 }
00434
00435 return 0;
00436 }
00437
00438 int
00439 toggle_antialias(const Event&, State *&)
00440 {
00441
00442 int a = VIEW::peek()->get_antialias_enable();
00443
00444 VIEW::peek()->set_antialias_enable(!a);
00445
00446 if (VIEW::peek()->get_antialias_enable())
00447 {
00448 WORLD::message(str_ptr("Antialiasing: ENALBED Jitters: ") +
00449 str_ptr(VIEW::get_jitter_num(VIEW::peek()->get_antialias_mode())));
00450 }
00451 else
00452 {
00453 WORLD::message(str_ptr("Antialiasing: DISABLED Jitters: ") +
00454 str_ptr(VIEW::get_jitter_num(VIEW::peek()->get_antialias_mode())));
00455 }
00456
00457 return 0;
00458 }
00459
00460 int
00461 next_antialias(const Event&, State *&)
00462 {
00463
00464 int m = VIEW::peek()->get_antialias_mode();
00465
00466 VIEW::peek()->set_antialias_mode((m+1)%VIEW::get_jitter_mode_num());
00467
00468 if (VIEW::peek()->get_antialias_enable())
00469 {
00470 WORLD::message(str_ptr("Antialiasing: ENALBED Jitters: ") +
00471 str_ptr(VIEW::get_jitter_num(VIEW::peek()->get_antialias_mode())));
00472 }
00473 else
00474 {
00475 WORLD::message(str_ptr("Antialiasing: DISABLED Jitters: ") +
00476 str_ptr(VIEW::get_jitter_num(VIEW::peek()->get_antialias_mode())));
00477 }
00478
00479 return 0;
00480 }
00481
00482 int
00483 freeze_sils(const Event&, State *&)
00484 {
00485 BMESH::_freeze_sils = !BMESH::_freeze_sils;
00486
00487 return 0;
00488 }
00489
00490 int
00491 toggle_random_sils(const Event&, State *&)
00492 {
00493 BMESH::toggle_random_sils();
00494 char msg[256];
00495 sprintf(msg, "Randomized silhouettes: %s",
00496 BMESH::_random_sils ? "ON" : "OFF");
00497 WORLD::message(msg);
00498 return 0;
00499 }
00500
00501 int
00502 toggle_hidden_lines(const Event&, State *&)
00503 {
00504 KeyLineTexture::toggle_show_hidden_lines();
00505
00506 return 0;
00507 }
00508
00509
00510 inline bool
00511 is_sec(Bface* f)
00512 {
00513 return f && f->is_secondary();
00514 }
00515
00516
00517 class BadEdgeFilter : public SimplexFilter {
00518 public:
00519 virtual bool accept(CBsimplex* s) const {
00520 if (!is_edge(s))
00521 return false;
00522 Bedge* e = (Bedge*)s;
00523 return (e->is_multi() && (is_sec(e->f1()) || is_sec(e->f2())));
00524 }
00525 };
00526
00527
00528
00529
00530
00531
00532
00533 inline Wpt
00534 map_centroid(CBface* f, CWpt& eye, CWvec& t)
00535 {
00536
00537
00538
00539
00540 assert(f);
00541 Wpt c = (f->is_quad() ? f->quad_centroid() : f->centroid());
00542 return eye + t*c.dist(eye);
00543 }
00544
00545 inline double
00546 get_area(CBface* f)
00547 {
00548 return (f->is_quad() ? (f->quad_area()/2) : f->area());
00549 }
00550
00551 inline double
00552 normalized_pix_area(CBface* f, CWpt& eye, CWvec& t, CWvec& x, CWvec& y)
00553 {
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 if (!(f && f->mesh())) return 0;
00571 Wpt o = map_centroid(f, eye, t);
00572 double s = sqrt(get_area(f))/2;
00573 PIXEL a = (o - (x + y)*s);
00574 PIXEL b = (o + (x - y)*s);
00575 PIXEL c = (o - (x - y)*s);
00576 return fabs(det(b-a, c-a));
00577 }
00578
00579 inline double
00580 avg_bface_pix_area(BMESH* mesh)
00581 {
00582 if (!mesh) return 0;
00583
00584 CAMdataptr cam = VIEW::peek_cam()->data();
00585 Wpt eye = cam->from();
00586 Wvec t = cam-> at_v().normalized();
00587 Wvec x = cam->right_v().normalized();
00588 Wvec y = cam-> pup_v().normalized();
00589
00590 RunningAvg<double> ret(0);
00591 for (int i=0; i<mesh->nfaces(); i++)
00592 ret.add(normalized_pix_area(mesh->bf(i), eye, t, x, y));
00593 return ret.val();
00594 }
00595
00596 extern bool draw_skin_only;
00597
00598 inline bool
00599 print_edge_info(CBedge_list& edges)
00600 {
00601 bool ret = false;
00602 err_msg("********");
00603 for (int i=0; i<edges.num(); i++) {
00604 int n = edges[i]->nfaces();
00605 int a = edges[i]->num_all_faces();
00606 err_msg(" %2d: %d top, %d lower", i, n, a - n);
00607
00608 if (a > n) {
00609 WORLD::show(edges[i]->v1()->loc(), edges[i]->v2()->loc(), 4);
00610 ret = true;
00611 }
00612 }
00613 return ret;
00614 }
00615
00616 inline void
00617 debug_vis_ref_img(CNDCpt& p)
00618 {
00619 VisRefImage* vis = VisRefImage::lookup();
00620 if (!vis) {
00621 cerr << "debug_vis_ref_img: no vis ref image" << endl;
00622 return;
00623 }
00624 if (vis->need_update()) {
00625 cerr << "debug_vis_ref_img: vis ref image is out of date!" << endl;
00626 return;
00627 }
00628 cerr << "debug_vis_ref_img: NDCpt " << p << endl
00629 << " val: " << vis->val (p) << endl
00630 << " red: " << vis->red (p) << ", "
00631 << " green: " << vis->green(p) << ", "
00632 << " blue: " << vis->blue (p) << ", "
00633 << " alpha: " << vis->alpha(p) << endl;
00634 }
00635
00636 int
00637 debug_cb(const Event& ev, State *&)
00638 {
00639 switch (ev._c) {
00640 case 'd': {
00641 FlatShadeTexture::toggle_debug_uv();
00642 WORLD::message(
00643 str_ptr("Debug UV: ") + (FlatShadeTexture::debug_uv() ? "ON" : "OFF")
00644 );
00645 break;
00646 }
00647 default:
00648 ;
00649 }
00650
00651 return 0;
00652 }
00653
00654 int
00655 clear_cb(const Event&, State *&)
00656 {
00657
00658 AlertBox *box = VIEW::peek()->win()->alert_box();
00659
00660 box->set_title("Warning");
00661 box->set_icon(AlertBox::EXCLAMATION_ICON);
00662 box->add_text("You are about to delete everything!");
00663 box->add_text("Sure?");
00664 box->add_button("Yes");
00665 box->add_button("No");
00666 box->set_default(0);
00667
00668 if (box->display(true, alert_cbs, NULL, NULL, ALERT_CLEAR_CB))
00669 cerr << "clear_cb() - AlertBox displayed.\n";
00670 else
00671 cerr << "clear_cb() - AlertBox **FAILED** to display!!\n";
00672
00673 return 0;
00674 }
00675
00676 void
00677 alert_cbs(void *ptr, void *dptr, int idx, int but_idx)
00678 {
00679
00680 switch(idx)
00681 {
00682 case ALERT_CLEAR_CB:
00683 if (but_idx == 0)
00684 {
00685 do_clear();
00686 }
00687 else
00688 {
00689 assert(but_idx == 1);
00690
00691 }
00692 break;
00693 case ALERT_SAVE_JOT_OVERWRITE_CB:
00694 if (but_idx == 0)
00695 {
00696 do_save((char *)dptr);
00697 }
00698 else if (but_idx == 1)
00699 {
00700
00701 Event e; State *s=NULL;
00702 save_cb(e, s);
00703 }
00704 else
00705 {
00706 assert(but_idx == 2);
00707
00708 }
00709
00710 delete[] (char *)dptr;
00711 break;
00712 case ALERT_SAVE_JOT_FAILED_CB:
00713 assert(but_idx == 0);
00714 break;
00715 case ALERT_LOAD_JOT_FAILED_CB:
00716 assert(but_idx == 0);
00717 break;
00718 default:
00719 assert(0);
00720 }
00721 }
00722
00723 void
00724 do_clear()
00725 {
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 GELlist drawn = DRAWN;
00736
00737
00738 for (int i=0; i<drawn.num(); i++) {
00739 if (gel_to_bmesh(drawn[i]))
00740
00741 WORLD::undisplay(drawn[i]);
00742 }
00743 }
00744
00745 int
00746 save_cb(const Event&, State *&)
00747 {
00748
00749 FileSelect *sel = VIEW::peek()->win()->file_select();
00750
00751 sel->set_title("Save Scene");
00752 sel->set_action("Save");
00753 sel->set_icon(FileSelect::SAVE_ICON);
00754 sel->set_path(".");
00755 sel->set_filter("*.jot");
00756
00757 str_ptr fname = ((IOManager::basename() != NULL_STR) ? (IOManager::basename()) : (str_ptr("out"))) + ".jot";
00758
00759 sel->set_file(fname);
00760
00761
00762 if (sel->display(true, file_cbs, NULL, FILE_SAVE_JOT_CB))
00763 cerr << "save_cb() - FileSelect displayed.\n";
00764 else
00765 cerr << "save_cb() - FileSelect **FAILED** to display!!\n";
00766
00767 return 0;
00768 }
00769
00770
00771 int
00772 load_cb(const Event&, State *&)
00773 {
00774
00775 FileSelect *sel = VIEW::peek()->win()->file_select();
00776
00777 sel->set_title("Load Scene");
00778 sel->set_action("Load");
00779 sel->set_icon(FileSelect::LOAD_ICON);
00780 sel->set_path(".");
00781 sel->set_file("");
00782 sel->set_filter("*.jot");
00783
00784
00785 if (sel->display(true, file_cbs, NULL, FILE_LOAD_JOT_CB))
00786 cerr << "load_cb() - FileSelect displayed.\n";
00787 else
00788 cerr << "load_cb() - FileSelect **FAILED** to display!!\n";
00789
00790 return 0;
00791 }
00792
00793 void
00794 file_cbs(void *ptr, int idx, int action, str_ptr path, str_ptr file)
00795 {
00796 str_ptr fullpath = path + file;
00797
00798 switch(idx)
00799 {
00800 case FILE_SAVE_JOT_CB:
00801 if (action == FileSelect::OK_ACTION)
00802 {
00803 bool exists; FILE *foo; exists=!!(foo=fopen(**(fullpath),"r"));if(exists)fclose(foo);
00804
00805 if (!exists)
00806 {
00807 do_save(fullpath);
00808 }
00809 else
00810 {
00811 AlertBox *box = VIEW::peek()->win()->alert_box();
00812
00813 box->set_title("Warning");
00814 box->set_icon(AlertBox::EXCLAMATION_ICON);
00815 box->add_text("Destination exists:");
00816 box->add_text(fullpath);
00817 box->add_text("Overwrite?");
00818 box->add_button("Yes");
00819 box->add_button("No");
00820 box->add_button("Cancel");
00821 box->set_default(0);
00822
00823
00824
00825
00826
00827
00828
00829 char *fp = new char[(int)fullpath.len()+1]; assert(fp); strcpy(fp,**fullpath);
00830
00831 if (box->display(true, alert_cbs, ptr, fp, ALERT_SAVE_JOT_OVERWRITE_CB))
00832 cerr << "clear_cb() - AlertBox displayed.\n";
00833 else
00834 cerr << "clear_cb() - AlertBox **FAILED** to display!!\n";
00835 }
00836 }
00837 break;
00838 case FILE_LOAD_JOT_CB:
00839 if (action == FileSelect::OK_ACTION)
00840 {
00841 do_load(fullpath);
00842 }
00843 break;
00844 default:
00845 assert(0);
00846 }
00847 }
00848
00849 void
00850 do_save(str_ptr fullpath)
00851 {
00852 SAVEobs::save_status_t status;
00853
00854 cerr << "\ndo_save() - Saving...\n";
00855
00856 NetStream s(fullpath, NetStream::ascii_w);
00857
00858 int old_cursor = VIEW::peek()->get_cursor();
00859 VIEW::peek()->set_cursor(WINSYS::CURSOR_WAIT);
00860 SAVEobs::notify_save_obs(s, status, true, true);
00861 VIEW::peek()->set_cursor(old_cursor);
00862
00863 if (status == SAVEobs::SAVE_ERROR_NONE)
00864 {
00865 cerr << "do_save() - ...done.\n";
00866
00867 WORLD::message(str_ptr("Saved '") + fullpath + "'");
00868 }
00869 else
00870 {
00871 cerr << "do_save() - ...aborted!!!" << endl;
00872
00873 WORLD::message(str_ptr("Problem saving '") + fullpath + "'");
00874
00875 AlertBox *box = VIEW::peek()->win()->alert_box();
00876
00877 box->set_title("Warning");
00878 box->set_icon(AlertBox::WARNING_ICON);
00879 box->add_text("Problem saving scene to file:");
00880 box->add_text(fullpath);
00881 box->add_button("OK");
00882 box->set_default(0);
00883
00884 switch(status)
00885 {
00886 case SAVEobs::SAVE_ERROR_STREAM:
00887 box->add_text("Couldn't create output stream.");
00888 break;
00889 case SAVEobs::SAVE_ERROR_WRITE:
00890 box->add_text("Error occurred during write.");
00891 break;
00892 case SAVEobs::SAVE_ERROR_CWD:
00893 box->add_text("Error changing current working directory.");
00894 break;
00895 default:
00896 assert(0);
00897 }
00898
00899 if (box->display(true, alert_cbs, NULL, NULL, ALERT_SAVE_JOT_FAILED_CB))
00900 cerr << "do_save() - AlertBox displayed.\n";
00901 else
00902 cerr << "do_save() - AlertBox **FAILED** to display!!\n";
00903 }
00904
00905 }
00906
00907 void
00908 do_load(str_ptr fullpath)
00909 {
00910 LOADobs::load_status_t status;
00911
00912 cerr << "\ndo_load() - Loading...\n";
00913
00914 NetStream s(fullpath, NetStream::ascii_r);
00915
00916
00917
00918
00919 do_clear();
00920
00921 int old_cursor = VIEW::peek()->get_cursor();
00922 VIEW::peek()->set_cursor(WINSYS::CURSOR_WAIT);
00923 LOADobs::notify_load_obs(s, status, true, true);
00924 VIEW::peek()->set_cursor(old_cursor);
00925
00926 if (status == LOADobs::LOAD_ERROR_NONE) {
00927 cerr << "do_load() - ...done.\n";
00928
00929 WORLD::message(str_ptr("Loaded '") + fullpath + "'");
00930
00931 } else {
00932
00933
00934
00935 cerr << "do_load() - ...aborted!!!" << endl;
00936
00937 WORLD::message(str_ptr("Problem loading '") + fullpath + "'");
00938
00939 AlertBox *box = VIEW::peek()->win()->alert_box();
00940
00941 box->set_title("Warning");
00942 box->set_icon(AlertBox::WARNING_ICON);
00943 box->add_text("Problem loading scene from file:");
00944 box->add_text(fullpath);
00945 box->add_button("OK");
00946 box->set_default(0);
00947
00948 switch(status) {
00949 case LOADobs::LOAD_ERROR_STREAM:
00950 box->add_text("Couldn't create input stream.");
00951 break;
00952 case LOADobs::LOAD_ERROR_JOT:
00953 box->add_text("The anticipated #jot header was found.");
00954 box->add_text("Error occurred while reading remaining file.");
00955 break;
00956 case LOADobs::LOAD_ERROR_CWD:
00957 box->add_text("Error changing current working directory.");
00958 break;
00959 case LOADobs::LOAD_ERROR_AUX:
00960 box->set_icon(AlertBox::INFO_ICON);
00961 box->add_text("Failed to load as jot format file.");
00962 box->add_text("Succeeded with an auxillary file parser!");
00963 break;
00964 case LOADobs::LOAD_ERROR_READ:
00965 box->add_text("Error occurred during read.");
00966 break;
00967 default:
00968 assert(0);
00969 }
00970
00971 if (box->display(true, alert_cbs, NULL, NULL, ALERT_LOAD_JOT_FAILED_CB))
00972 cerr << "do_save() - AlertBox displayed.\n";
00973 else
00974 cerr << "do_save() - AlertBox **FAILED** to display!!\n";
00975 }
00976 }
00977
00978 int
00979 animation_keys(const Event &e, State *&s)
00980 {
00981
00982
00983
00984
00985 assert(!(VIEW::peek()->recorder()->on() && VIEW::peek()->animator()->on()));
00986
00987
00988 if(!VIEW::peek()->recorder()->on() && !VIEW::peek()->animator()->on())
00989 {
00990 switch (e._c)
00991 {
00992 case 'C':
00993 return toggle_recorder(e,s);
00994 break;
00995 case 'X':
00996 VIEW::peek()->animator()->toggle_activation();
00997 break;
00998 };
00999 }
01000
01001 else if(VIEW::peek()->recorder()->on())
01002 {
01003 switch (e._c)
01004 {
01005 case 'X':
01006 WORLD::message("Deactivate recorder first!");
01007 break;
01008 case 'C':
01009 return toggle_recorder(e,s);
01010 break;
01011 case '/':
01012 return rec_play(e,s);
01013 break;
01014 case '*':
01015 return rec_rec(e,s);
01016 break;
01017 case '-':
01018 return rec_stop(e,s);
01019 break;
01020 case '+':
01021 return rec_pause(e,s);
01022 break;
01023 };
01024 }
01025
01026 else if(VIEW::peek()->animator()->on())
01027 {
01028 switch (e._c)
01029 {
01030 case 'C':
01031 WORLD::message("Deactivate recorder first!");
01032 break;
01033 case 'X':
01034 VIEW::peek()->animator()->toggle_activation();
01035 break;
01036 case '/':
01037 VIEW::peek()->animator()->press_play();
01038 break;
01039 case '*':
01040 VIEW::peek()->animator()->press_render();
01041 break;
01042 case '-':
01043 VIEW::peek()->animator()->press_sync();
01044 break;
01045 case '+':
01046 VIEW::peek()->animator()->press_stop();
01047 break;
01048 case '5':
01049 VIEW::peek()->animator()->press_beginning();
01050 break;
01051 case '4':
01052 VIEW::peek()->animator()->press_step_rev();
01053 break;
01054 case '6':
01055 VIEW::peek()->animator()->press_step_fwd();
01056 break;
01057 case '2':
01058 VIEW::peek()->animator()->press_jog_rev();
01059 break;
01060 case '8':
01061 VIEW::peek()->animator()->press_jog_fwd();
01062 break;
01063 };
01064 }
01065 else
01066 {
01067
01068 assert(0);
01069 return 0;
01070 }
01071
01072 return 0;
01073 }
01074
01075 int
01076 render_mode(const Event &e, State *&s)
01077 {
01078 switch (e._c)
01079 {
01080 case '!':
01081 WORLD::message("Rendering ALL Objects.");
01082 VIEW::peek()->set_render_mode(VIEW::NORMAL_MODE);
01083 break;
01084 case '@':
01085 WORLD::message("Rendering OPAQUE Objects.");
01086 VIEW::peek()->set_render_mode(VIEW::OPAQUE_MODE);
01087 break;
01088 case '#':
01089 WORLD::message("Rendering TRANSPARENT Objects.");
01090 VIEW::peek()->set_render_mode(VIEW::TRANSPARENT_MODE);
01091 break;
01092 default:
01093
01094 break;
01095 };
01096
01097 return 0;
01098 }
01099
01100 int
01101 toggle_recorder (const Event &, State *&)
01102 {
01103 Recorder* _rec =VIEW::peek()->recorder();
01104 if ( _rec == NULL)
01105 return 0;
01106 if (_rec->on())
01107 _rec->deactivate();
01108 else {
01109 if (_rec->get_ui() == NULL) {
01110 _rec->set_ui(new RecorderUI(_rec));
01111 _rec->_name_buf = str_ptr ("default");
01112 _rec->new_path();
01113 }
01114 _rec->activate();
01115 }
01116 return 1;
01117 }
01118
01119 int
01120 rec_play (const Event &, State *&)
01121 {
01122
01123 Recorder* _rec = NULL;
01124 if ( ( _rec =VIEW::peek()->recorder()) == NULL ) return 0;
01125 _rec->rec_play();
01126 return 1;
01127 }
01128
01129 int
01130 rec_rec (const Event &, State *&)
01131 {
01132
01133 Recorder* _rec = NULL;
01134 if ( ( _rec =VIEW::peek()->recorder()) == NULL ) return 0;
01135 _rec->rec_record();
01136 return 1;
01137 }
01138
01139 int
01140 rec_stop (const Event &, State *&)
01141 {
01142
01143 Recorder* _rec = NULL;
01144 if ( ( _rec =VIEW::peek()->recorder()) == NULL ) return 0;
01145 _rec->rec_stop();
01146 return 1;
01147 }
01148
01149 int
01150 rec_pause (const Event &, State *&)
01151 {
01152
01153 Recorder* _rec = NULL;
01154 if ( ( _rec =VIEW::peek()->recorder()) == NULL ) return 0;
01155 _rec->rec_pause();
01156 return 1;
01157 }
01158
01159 int
01160 set_pen(const Event & ev, State *&)
01161 {
01162
01163 if (ev._c == '.')
01164 {
01165 BaseJOTapp::instance()->next_pen();
01166 }
01167 else if (ev._c == ',')
01168 {
01169 BaseJOTapp::instance()->prev_pen();
01170 }
01171
01172 VIEW::peek()->set_focus();
01173
01174 return 0;
01175 }
01176
01177 int
01178 undo_redo(const Event &e, State *&)
01179 {
01180 switch (e._c) {
01181 case '\n':
01182 case '\r':
01183 WORLD::redo();
01184 break;
01185 case '\x8' :
01186 case '\x7f':
01187 WORLD::undo();
01188 break;
01189 default:
01190 err_msg("undo_redo: unknown key: %d (ASCII decimal code)",
01191 int(e._c));
01192 }
01193
01194 return 0;
01195 }
01196
01197
01198 int
01199 quit(const Event&, State *&)
01200 {
01201 if (Config::get_var_bool("DEBUG_STRPOOL",false))
01202 err_msg("strpool load factor: %f", STR::load_factor());
01203
01204 WORLD::Quit();
01205
01206 return 0;
01207 }
01208
01209 int
01210 refine(const Event&, State *&)
01211 {
01212 BMESH* m = find_ctrl_mesh();
01213 if (!m || !LMESH::isa(m))
01214 return 0;
01215
01216 LMESH* ctrl_mesh = (LMESH*)m;
01217
01218 if (Config::get_var_bool("DEBUG_VOLUME_PRESERVATION",false))
01219 cerr << "Current mesh volume=" << ctrl_mesh->volume() <<endl;
01220
01221 if (ctrl_mesh && ctrl_mesh->loc_calc() && **ctrl_mesh->loc_calc()->name())
01222 WORLD::message(**ctrl_mesh->loc_calc()->name());
01223
01224 ctrl_mesh->refine();
01225 if (Config::get_var_bool("DEBUG_VOLUME_PRESERVATION",false))
01226 cerr << "Refined mesh volume=" << ctrl_mesh->volume() <<endl;
01227
01228 return 0;
01229 }
01230
01231 int
01232 cycle_subdiv_loc_calc(const Event&, State *&)
01233 {
01234 BMESH* m = find_ctrl_mesh();
01235 if (!m || !LMESH::isa(m))
01236 return 0;
01237
01238 static int k=0;
01239 LMESH* ctrl_mesh = (LMESH*)m;
01240 SubdivLocCalc* calc = 0;
01241 switch (++k % 3) {
01242 case 0: calc = new LoopLoc; break;
01243 case 1: calc = new Hybrid2Loc; break;
01244 case 2: calc = new HybridVolPreserve; break;
01245 }
01246 assert(calc != 0);
01247 ctrl_mesh->set_subdiv_loc_calc(calc);
01248 ctrl_mesh->update();
01249 WORLD::message(calc->name() + " scheme in use");
01250
01251 return 0;
01252 }
01253
01254 int
01255 clear_selections(const Event&, State *&)
01256 {
01257 MeshGlobal::deselect_all_edges();
01258 MeshGlobal::deselect_all_faces();
01259 return 0;
01260 }
01261
01262
01263 int
01264 unrefine(const Event&, State *&)
01265 {
01266 BMESH* m = find_ctrl_mesh();
01267 if (!m || !LMESH::isa(m))
01268 return 0;
01269
01270 ((LMESH*)m)->unrefine();
01271
01272 return 0;
01273 }
01274
01275 inline BMESHptr
01276 control_mesh(CBMESHptr& m)
01277 {
01278
01279
01280 return (m && LMESH::isa(&*m)) ? BMESHptr(((LMESH*)&*m)->control_mesh()) : m;
01281 }
01282
01283 int
01284 toggle_sil_frame(const Event&, State *&)
01285 {
01286 BMESH* mesh = find_ctrl_mesh();
01287 if (!mesh)
01288 return 0;
01289
01290 mesh->toggle_render_style(SilFrameTexture::static_name());
01291
01292 return 0;
01293 }
01294
01295
01296 int
01297 toggle_transp(const Event&e, State *&)
01298 {
01299 RAYhit ray(VisRefImage::get_cursor());
01300 e.view()->intersect(ray);
01301
01302 if (ray.success() && ray.appear() ) {
01303 if (ray.appear()->has_transp() ) {
01304 ray.appear()->unset_transp();
01305 }
01306 else {
01307 ray.appear()->set_transp(.5);
01308 }
01309 }
01310
01311 return 0;
01312 }
01313
01314 int
01315 write(const Event&, State *&)
01316 {
01317 BMESH* mesh = find_mesh();
01318
01319 if (!mesh) {
01320 cerr << "write - No mesh... aborting.\n";
01321 return 0;
01322 }
01323
01324 mesh->print();
01325
01326 str_ptr fname = "out.sm";
01327
01328 if (mesh->write_file(**fname)) {
01329 WORLD::message(str_ptr("Wrote mesh: ") + fname);
01330 } else {
01331 WORLD::message(str_ptr("Failed to write mesh: ") + fname);
01332 }
01333
01334 return 1;
01335 }
01336
01337 int
01338 print_mesh(const Event&, State *&)
01339 {
01340 BMESH* mesh = find_mesh();
01341 if (mesh)
01342 mesh->print();
01343 return 0;
01344 }
01345
01346 int
01347 write_xformed(const Event&, State *&)
01348 {
01349 BMESH* mesh = find_mesh();
01350 if (!mesh) {
01351 return 0;
01352 }
01353
01354
01355
01356
01357 MOD::tick();
01358 mesh->transform(mesh->xform(), MOD());
01359
01360
01361 if (mesh->write_file("out.sm")) {
01362 WORLD::message("Wrote ***TRANSFORMED*** mesh to out.sm");
01363 } else {
01364 WORLD::message("Couldn't write mesh file: out.sm");
01365 }
01366
01367 MOD::tick();
01368 mesh->transform(mesh->inv_xform(), MOD());
01369
01370 return 1;
01371 }
01372
01373 int
01374 save_config(const Event &e, State *&)
01375 {
01376 bool ret;
01377
01378 ret = Config::save_config(Config::JOT_ROOT() + "jot.cfg");
01379
01380 if (ret)
01381 WORLD::message(str_ptr("Wrote config to ") + Config::JOT_ROOT() + "jot.cfg");
01382 else
01383 WORLD::message(str_ptr("FAILED!! Writing config to ") + Config::JOT_ROOT() + "jot.cfg");
01384
01385 return 1;
01386 }
01387
01388
01389
01390
01391
01392
01393
01394
01395 int
01396 clear_creases(const Event&, State*&)
01397 {
01398 BMESH* mesh = find_ctrl_mesh();
01399 if (!mesh)
01400 return 0;
01401
01402 WORLD::message("Clearing creases");
01403 mesh->clear_creases();
01404
01405 return 0;
01406 }
01407
01408
01409 int
01410 toggle_no_text(const Event&, State*&)
01411 {
01412 if (!TEXT2D::toggle_suppress_draw())
01413 WORLD::message("Text on");
01414
01415 return 0;
01416 }
01417
01418
01419
01420
01421
01422
01423
01424 int
01425 recreate_creases(const Event&, State *&)
01426 {
01427 BMESH* mesh = find_ctrl_mesh();
01428 if (!mesh)
01429 return 0;
01430
01431 WORLD::message("Recreating creases");
01432 for (int k = mesh->nedges()-1; k>=0; k--)
01433 mesh->be(k)->compute_crease(0.5);
01434 mesh->changed();
01435
01436 return 0;
01437 }
01438
01439 int
01440 toggle_crease(const Event &, State *&)
01441 {
01442 VisRefImage *vis_ref = VisRefImage::lookup(VIEW::peek());
01443 vis_ref->update();
01444 Wpt obj_pt;
01445 Bface* face = vis_ref->intersect(VisRefImage::get_cursor(), obj_pt);
01446
01447 if (face) {
01448 Wvec bc;
01449 face->project_barycentric(obj_pt, bc);
01450 int i=0;
01451 if (bc[0] < bc[1])
01452 i = (bc[0] < bc[2]) ? 0 : 2;
01453 else
01454 i = (bc[1] < bc[2]) ? 1 : 2;
01455 Bvert *vert = face->v(i+1);
01456 Bedge *edge = face->opposite_edge(vert);
01457
01458 edge->set_crease(!edge->is_crease());
01459 face->mesh()->changed();
01460 }
01461 return 0;
01462 }
01463
01464 int
01465 toggle_curvature_ui(const Event&, State *&)
01466 {
01467
01468 if(CurvatureUISingleton::Instance().is_vis(VIEW::peek())){
01469
01470 CurvatureUISingleton::Instance().hide(VIEW::peek());
01471
01472 } else {
01473
01474 CurvatureUISingleton::Instance().show(VIEW::peek());
01475 VIEW::peek()->set_focus();
01476
01477 }
01478
01479 return 0;
01480
01481 }
01482
01483