- Timestamp:
- May 29, 2006 7:55:49 PM (18 years ago)
- Location:
- trunk/gui/vizservers/nanovis
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gui/vizservers/nanovis/nanovis.cpp
r434 r445 22 22 #include <string> 23 23 #include <sys/time.h> 24 #include <sys/types.h> 25 #include <unistd.h> 26 #include <fcntl.h> 24 27 25 28 #include "nanovis.h" 29 #include "RpField1D.h" 26 30 #include "RpFieldRect3D.h" 27 31 #include "RpFieldPrism3D.h" … … 48 52 49 53 // default transfer function 50 float def_tf[24] = { 51 1, 1, 1, 0.5, // red 52 1, 1, 0, 0.5, // yellow 53 0, 1, 0, 0.5, // green 54 0, 1, 1, 0.5, // cyan 55 0, 0, 1, 0.5, // blue 56 1, 0, 1, 0.5, // magenta 57 }; 58 int def_tf_size = 6; 54 char *def_transfunc = "transfunc define default {\n\ 55 0.0 1 1 1 0.5\n\ 56 0.2 1 1 0 0.5\n\ 57 0.4 0 1 0 0.5\n\ 58 0.6 0 1 1 0.5\n\ 59 0.8 0 0 1 0.5\n\ 60 1.0 1 0 1 0.5\n\ 61 }"; 59 62 60 63 #ifdef XINETD … … 73 76 void init_particles(); 74 77 void get_slice_vectors(); 78 Rappture::Outcome load_volume_file(int index, char *fname); 79 void load_volume(int index, int width, int height, int depth, int n_component, float* data); 80 TransferFunction* get_transfunc(char *name); 75 81 76 82 ParticleSystem* psys; … … 79 85 Lic* lic; 80 86 87 //frame buffer for final rendering 81 88 unsigned char* screen_buffer = NULL; 82 NVISid final_fbo, final_color_tex, final_depth_rb; //frame buffer for final rendering89 NVISid final_fbo, final_color_tex, final_depth_rb; 83 90 84 91 bool advect=false; … … 87 94 88 95 int n_volumes = 0; 89 Volume* volume[MAX_N_VOLUMES]; //pointers to volumes, currently handle up to 10 volumes 90 TransferFunction* tf[MAX_N_VOLUMES]; //transfer functions, currently handle up to 10 colormaps 91 Texture2D* plane[10]; //pointers to 2D planes, currently handle up 10 96 // pointers to volumes, currently handle up to 10 volumes 97 Volume* volume[MAX_N_VOLUMES]; 98 // maps transfunc name to TransferFunction object 99 Tcl_HashTable tftable; 100 101 // pointers to 2D planes, currently handle up 10 102 Texture2D* plane[10]; 92 103 93 104 PerfQuery* perf; //perfromance counter … … 117 128 // Tcl interpreter for incoming messages 118 129 static Tcl_Interp *interp; 130 static Tcl_DString cmdbuffer; 119 131 120 132 static int CameraCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); … … 122 134 static int ClearCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 123 135 static int ScreenCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 124 static int TransferFunctionNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 125 static int TransferFunctionUpdateCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 136 static int TransfuncCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 126 137 static int VolumeCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 127 static int VolumeNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));128 138 static int VolumeLinkCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 129 139 static int VolumeMoveCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 130 static int VolumeEnableCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));131 140 static int RefreshCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 132 141 static int PlaneNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); … … 281 290 return TCL_ERROR; 282 291 } 283 if (ivol < 0 || ivol > n_volumes) {292 if (ivol < 0 || ivol >= n_volumes) { 284 293 Tcl_AppendResult(interp, "bad volume index \"", argv[n], 285 294 "\": out of range", (char*)NULL); … … 325 334 return TCL_ERROR; 326 335 } 327 if (ivol < 0 || ivol > n_volumes) {336 if (ivol < 0 || ivol >= n_volumes) { 328 337 Tcl_AppendResult(interp, "bad volume index \"", argv[n], 329 338 "\": out of range", (char*)NULL); … … 376 385 } 377 386 378 void update_transfer_function(int index, float* data);379 380 //The client sends the first sends the index of the transfer function381 //to modify. Then the client sends a chunck of binary floats.382 static int383 TransferFunctionUpdateCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])384 {385 fprintf(stderr, "update transfer function cmd\n");386 387 double index;388 389 if (argc != 2) {390 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],391 " tf_index\"", (char*)NULL);392 return TCL_ERROR;393 }394 if (Tcl_GetDouble(interp, argv[1], &index) != TCL_OK) {395 return TCL_ERROR;396 }397 398 //Now read 256*4*4 bytes. The server expects the transfer function to be 256 units of (RGBA) floats399 char tmp[256*4*4];400 bzero(tmp, 256*4*4);401 int status = read(0, tmp, 256*4*4);402 if (status <= 0) {403 exit(0);404 }405 406 update_transfer_function((int)index, (float*)tmp);407 return TCL_OK;408 }409 410 411 //The client sends the index of the index of the transfer function412 //to create. Then the client sends a chunck of binary floats.413 static int414 TransferFunctionNewCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])415 {416 fprintf(stderr, "update transfer function cmd\n");417 418 double index;419 420 if (argc != 2) {421 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],422 " tf_index\"", (char*)NULL);423 return TCL_ERROR;424 }425 if (Tcl_GetDouble(interp, argv[1], &index) != TCL_OK) {426 return TCL_ERROR;427 }428 429 //Now read 256*4*4 bytes. The server expects the transfer function to be 256 units of (RGBA) floats430 char tmp[256*4*4];431 bzero(tmp, 256*4*4);432 int status = read(0, tmp, 256*4*4);433 if (status <= 0) {434 exit(0);435 }436 437 tf[(int)index] = new TransferFunction(256, (float*)tmp);438 return TCL_OK;439 }440 441 442 387 void set_object(float x, float y, float z){ 443 388 live_obj_x = x; … … 449 394 * ---------------------------------------------------------------------- 450 395 * CLIENT COMMAND: 396 * transfunc define <name> { <v> <r> <g> <b> <w> ... } 397 * 398 * Clients send these commands to manipulate the transfer functions. 399 * ---------------------------------------------------------------------- 400 */ 401 static int 402 TransfuncCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) 403 { 404 if (argc < 2) { 405 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 406 " option arg arg...\"", (char*)NULL); 407 return TCL_ERROR; 408 } 409 410 char c = *argv[1]; 411 if (c == 'd' && strcmp(argv[1],"define") == 0) { 412 if (argc < 4) { 413 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 414 argv[1], " option ?arg arg...?\"", (char*)NULL); 415 return TCL_ERROR; 416 } 417 418 // decode the data and store in a series of fields 419 Rappture::Field1D rFunc, gFunc, bFunc, wFunc; 420 int xferc, i, j; 421 char **xferv; 422 423 if (Tcl_SplitList(interp, argv[3], &xferc, &xferv) != TCL_OK) { 424 return TCL_ERROR; 425 } 426 if (xferc % 5 != 0) { 427 Tcl_Free((char*)xferv); 428 Tcl_AppendResult(interp, "missing data in transfunc: should be ", 429 "{ v r g b w ... }", (char*)NULL); 430 return TCL_ERROR; 431 } 432 433 for (i=0; i < xferc; i += 5) { 434 double vals[5]; 435 for (j=0; j < 5; j++) { 436 if (Tcl_GetDouble(interp, xferv[i+j], &vals[j]) != TCL_OK) { 437 Tcl_Free((char*)xferv); 438 return TCL_ERROR; 439 } 440 if (vals[j] < 0 || vals[j] > 1) { 441 Tcl_Free((char*)xferv); 442 Tcl_AppendResult(interp, "bad value \"", xferv[i+j], 443 "\": should be in the range 0-1", (char*)NULL); 444 return TCL_ERROR; 445 } 446 } 447 rFunc.define(vals[0], vals[1]); 448 gFunc.define(vals[0], vals[2]); 449 bFunc.define(vals[0], vals[3]); 450 wFunc.define(vals[0], vals[4]); 451 } 452 Tcl_Free((char*)xferv); 453 454 // sample the given function into discrete slots 455 const int nslots = 256; 456 float data[4*nslots]; 457 for (i=0; i < nslots; i++) { 458 double xval = double(i)/(nslots-1); 459 data[4*i] = rFunc.value(xval); 460 data[4*i+1] = gFunc.value(xval); 461 data[4*i+2] = bFunc.value(xval); 462 data[4*i+3] = wFunc.value(xval); 463 } 464 465 // find or create this transfer function 466 int newEntry; 467 Tcl_HashEntry *entryPtr; 468 TransferFunction *tf; 469 470 entryPtr = Tcl_CreateHashEntry(&tftable, argv[2], &newEntry); 471 if (newEntry) { 472 tf = new TransferFunction(nslots, data); 473 Tcl_SetHashValue(entryPtr, (ClientData)tf); 474 } else { 475 tf = (TransferFunction*)Tcl_GetHashValue(entryPtr); 476 tf->update(data); 477 } 478 479 return TCL_OK; 480 } 481 Tcl_AppendResult(interp, "bad option \"", argv[1], 482 "\": should be define", (char*)NULL); 483 return TCL_ERROR; 484 } 485 486 /* 487 * ---------------------------------------------------------------------- 488 * CLIENT COMMAND: 489 * volume data state on|off ?<volumeId> ...? 451 490 * volume outline state on|off ?<volumeId> ...? 452 491 * volume outline color on|off ?<volumeId> ...? 453 * volume data state on|off ?<volumeId> ...? 492 * volume shading color <value> ?<volumeId> ...? 493 * volume shading diffuse <value> ?<volumeId> ...? 494 * volume shading specular <value> ?<volumeId> ...? 495 * volume shading opacity <value> ?<volumeId> ...? 496 * volume state on|off ?<volumeId> ...? 454 497 * 455 498 * Clients send these commands to manipulate the volumes. … … 466 509 467 510 char c = *argv[1]; 468 if (c == 'o' && strcmp(argv[1],"outline") == 0) { 511 if (c == 'd' && strcmp(argv[1],"data") == 0) { 512 if (argc < 3) { 513 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 514 argv[1], " option ?arg arg...?\"", (char*)NULL); 515 return TCL_ERROR; 516 } 517 c = *argv[2]; 518 if (c == 's' && strcmp(argv[2],"state") == 0) { 519 if (argc < 4) { 520 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 521 argv[1], " state on|off ?volume ...?\"", (char*)NULL); 522 return TCL_ERROR; 523 } 524 525 int state; 526 if (Tcl_GetBoolean(interp, argv[3], &state) != TCL_OK) { 527 return TCL_ERROR; 528 } 529 530 int ivol; 531 if (argc < 5) { 532 for (ivol=0; ivol < n_volumes; ivol++) { 533 if (state) { 534 volume[ivol]->enable_data(); 535 } else { 536 volume[ivol]->disable_data(); 537 } 538 } 539 } else { 540 for (int n=4; n < argc; n++) { 541 if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) { 542 return TCL_ERROR; 543 } 544 if (state) { 545 volume[ivol]->enable_data(); 546 } else { 547 volume[ivol]->disable_data(); 548 } 549 } 550 } 551 return TCL_OK; 552 } 553 else if (c == 'f' && strcmp(argv[2],"follows") == 0) { 554 int nbytes; 555 if (Tcl_GetInt(interp, argv[3], &nbytes) != TCL_OK) { 556 return TCL_ERROR; 557 } 558 559 char fname[64]; 560 sprintf(fname,"/tmp/nv%d.dat",getpid()); 561 std::ofstream dfile(fname); 562 563 char buffer[8096]; 564 while (nbytes > 0) { 565 int chunk = (sizeof(buffer) < nbytes) ? sizeof(buffer) : nbytes; 566 int status = fread(buffer, 1, chunk, stdin); 567 if (status > 0) { 568 dfile.write(buffer,status); 569 nbytes -= status; 570 } else { 571 Tcl_AppendResult(interp, "data unpacking failed in file ", 572 fname, (char*)NULL); 573 return TCL_ERROR; 574 } 575 } 576 dfile.close(); 577 578 char cmdstr[512]; 579 sprintf(cmdstr, "mimedecode %s | gunzip -c > /tmp/nv%d.dx", fname, getpid()); 580 if (system(cmdstr) != 0) { 581 Tcl_AppendResult(interp, "data unpacking failed in file ", 582 fname, (char*)NULL); 583 return TCL_ERROR; 584 } 585 586 sprintf(fname,"/tmp/nv%d.dx",getpid()); 587 588 int n = n_volumes; 589 Rappture::Outcome err = load_volume_file(n, fname); 590 591 sprintf(cmdstr, "rm -f /tmp/nv%d.dat /tmp/nv%d.dx", getpid(), getpid()); 592 system(cmdstr); 593 594 if (err) { 595 Tcl_AppendResult(interp, err.remark().c_str(), (char*)NULL); 596 return TCL_ERROR; 597 } 598 599 volume[n]->set_n_slice(512); 600 volume[n]->disable_cutplane(0); 601 volume[n]->disable_cutplane(1); 602 volume[n]->disable_cutplane(2); 603 vol_render->add_volume(volume[n], get_transfunc("default")); 604 605 return TCL_OK; 606 } 607 Tcl_AppendResult(interp, "bad option \"", argv[2], 608 "\": should be follows or state", (char*)NULL); 609 return TCL_ERROR; 610 } 611 else if (c == 'o' && strcmp(argv[1],"outline") == 0) { 469 612 if (argc < 3) { 470 613 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], … … 499 642 return TCL_ERROR; 500 643 } 501 if (ivol < 0 || ivol > n_volumes) {644 if (ivol < 0 || ivol >= n_volumes) { 502 645 Tcl_AppendResult(interp, "bad volume index \"", argv[n], 503 646 "\": out of range", (char*)NULL); … … 535 678 return TCL_ERROR; 536 679 } 537 if (ivol < 0 || ivol > n_volumes) {680 if (ivol < 0 || ivol >= n_volumes) { 538 681 Tcl_AppendResult(interp, "bad volume index \"", argv[n], 539 682 "\": out of range", (char*)NULL); … … 550 693 return TCL_ERROR; 551 694 } 552 else if (c == 's' && strcmp(argv[1],"s tate") == 0) {695 else if (c == 's' && strcmp(argv[1],"shading") == 0) { 553 696 if (argc < 3) { 554 697 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 555 " state on|off ?volume...?\"", (char*)NULL);698 argv[1], " option ?arg arg...?\"", (char*)NULL); 556 699 return TCL_ERROR; 557 700 } 558 559 int state; 560 if (Tcl_GetBoolean(interp, argv[2], &state) != TCL_OK) { 561 return TCL_ERROR; 562 } 563 564 int ivol; 565 for (int n=3; n < argc; n++) { 566 if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) { 701 c = *argv[2]; 702 if (c == 'c' && strcmp(argv[2],"color") == 0) { 703 if (argc < 4) { 704 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 705 argv[1], " color value ?volume ...?\"", (char*)NULL); 706 return TCL_ERROR; 707 } 708 709 float cval[3]; 710 if (GetColor(interp, argv[3], cval) != TCL_OK) { 567 711 return TCL_ERROR; 568 712 } 569 if (state) { 570 volume[ivol]->enable_data(); 713 714 int ivol; 715 if (argc < 5) { 716 for (ivol=0; ivol < n_volumes; ivol++) { 717 //volume[ivol]->set_diffuse((float)dval); 718 } 571 719 } else { 572 volume[ivol]->disable_data(); 720 for (int n=4; n < argc; n++) { 721 if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) { 722 return TCL_ERROR; 723 } 724 //volume[ivol]->set_diffuse((float)dval); 725 } 726 } 727 return TCL_OK; 728 } 729 else if (c == 'd' && strcmp(argv[2],"diffuse") == 0) { 730 if (argc < 4) { 731 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 732 argv[1], " diffuse value ?volume ...?\"", (char*)NULL); 733 return TCL_ERROR; 734 } 735 736 double dval; 737 if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) { 738 return TCL_ERROR; 739 } 740 741 int ivol; 742 if (argc < 5) { 743 for (ivol=0; ivol < n_volumes; ivol++) { 744 volume[ivol]->set_diffuse((float)dval); 745 } 746 } else { 747 for (int n=4; n < argc; n++) { 748 if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) { 749 return TCL_ERROR; 750 } 751 volume[ivol]->set_diffuse((float)dval); 752 } 753 } 754 return TCL_OK; 755 } 756 else if (c == 'o' && strcmp(argv[2],"opacity") == 0) { 757 if (argc < 4) { 758 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 759 argv[1], " opacity value ?volume ...?\"", (char*)NULL); 760 return TCL_ERROR; 761 } 762 763 double dval; 764 if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) { 765 return TCL_ERROR; 766 } 767 768 int ivol; 769 if (argc < 5) { 770 for (ivol=0; ivol < n_volumes; ivol++) { 771 volume[ivol]->set_opacity_scale((float)dval); 772 } 773 } else { 774 for (int n=4; n < argc; n++) { 775 if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) { 776 return TCL_ERROR; 777 } 778 volume[ivol]->set_opacity_scale((float)dval); 779 } 780 } 781 return TCL_OK; 782 } 783 else if (c == 's' && strcmp(argv[2],"specular") == 0) { 784 if (argc < 4) { 785 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 786 argv[1], " specular value ?volume ...?\"", (char*)NULL); 787 return TCL_ERROR; 788 } 789 790 double dval; 791 if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) { 792 return TCL_ERROR; 793 } 794 795 int ivol; 796 if (argc < 5) { 797 for (ivol=0; ivol < n_volumes; ivol++) { 798 volume[ivol]->set_specular((float)dval); 799 } 800 } else { 801 for (int n=4; n < argc; n++) { 802 if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) { 803 return TCL_ERROR; 804 } 805 volume[ivol]->set_specular((float)dval); 806 } 807 } 808 return TCL_OK; 809 } 810 Tcl_AppendResult(interp, "bad option \"", argv[2], 811 "\": should be color, diffuse, opacity, or specular", (char*)NULL); 812 return TCL_ERROR; 813 } 814 else if (c == 's' && strcmp(argv[1],"state") == 0) { 815 if (argc < 3) { 816 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 817 argv[1], " on|off ?volume...?\"", (char*)NULL); 818 return TCL_ERROR; 819 } 820 821 int state; 822 if (Tcl_GetBoolean(interp, argv[2], &state) != TCL_OK) { 823 return TCL_ERROR; 824 } 825 826 int ivol; 827 if (argc < 4) { 828 for (ivol=0; ivol < n_volumes; ivol++) { 829 if (state) { 830 volume[ivol]->enable(); 831 } else { 832 volume[ivol]->disable(); 833 } 834 } 835 } else { 836 for (int n=3; n < argc; n++) { 837 if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) { 838 return TCL_ERROR; 839 } 840 if (state) { 841 volume[ivol]->enable(); 842 } else { 843 volume[ivol]->disable(); 844 } 573 845 } 574 846 } … … 577 849 578 850 Tcl_AppendResult(interp, "bad option \"", argv[1], 579 "\": should be state", (char*)NULL);851 "\": should be data, outline, shading, or state", (char*)NULL); 580 852 return TCL_ERROR; 581 853 } … … 590 862 if (argc != 3) { 591 863 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 592 864 " volume_index tf_index \"", (char*)NULL); 593 865 return TCL_ERROR; 594 866 } … … 600 872 } 601 873 602 vol_render->add_volume(volume[(int)volume_index], tf[(int)tf_index]);874 //vol_render->add_volume(volume[(int)volume_index], tf[(int)tf_index]); 603 875 604 876 return TCL_OK; … … 628 900 return TCL_OK; 629 901 } 630 631 //Enable a volume.632 //Can enable a volume that is not yet added to the volume renderer.633 //But it won't be rendered until it's added to the volume renderer using VolumeLinkCmd634 //volume_index: the index maintained in the volume renderer.635 static int636 VolumeEnableCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])637 {638 fprintf(stderr, "enabled a volume to render command\n");639 640 double volume_index, mode;641 642 if (argc != 3) {643 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],644 " volume_index mode \"", (char*)NULL);645 return TCL_ERROR;646 }647 if (Tcl_GetDouble(interp, argv[1], &volume_index) != TCL_OK) {648 return TCL_ERROR;649 }650 if (Tcl_GetDouble(interp, argv[2], &mode) != TCL_OK) {651 return TCL_ERROR;652 }653 654 if(mode==0)655 vol_render->disable_volume((int)volume_index);656 else657 vol_render->enable_volume((int)volume_index);658 659 return TCL_OK;660 }661 662 663 void load_volume(int index, int width, int height, int depth, int n_component, float* data);664 665 //The client sends the load data command to tell the index of the volume, and the dimensions of the data666 //Then the client sends a chunck of binary floats. This call creates a NEW volume667 static int668 VolumeNewCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])669 {670 fprintf(stderr, "load data command\n");671 672 double index, w, h, d;673 674 if (argc != 5) {675 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],676 " volume_index w h d \"", (char*)NULL);677 return TCL_ERROR;678 }679 if (Tcl_GetDouble(interp, argv[1], &index) != TCL_OK) {680 return TCL_ERROR;681 }682 if (Tcl_GetDouble(interp, argv[2], &w) != TCL_OK) {683 return TCL_ERROR;684 }685 if (Tcl_GetDouble(interp, argv[3], &h) != TCL_OK) {686 return TCL_ERROR;687 }688 if (Tcl_GetDouble(interp, argv[4], &d) != TCL_OK) {689 return TCL_ERROR;690 }691 692 //Now read w*h*d*4*4 bytes. The server expects the volume to be units of 4-float tuples693 char* tmp = new char[int(w*h*d*4*4)];694 bzero(tmp, w*h*d*4*4);695 int status = read(0, tmp, w*h*d*4*4);696 if (status <= 0){697 exit(0);698 }699 700 load_volume(int(index), int(w), int(h), int(d), 4, (float*) tmp);701 702 delete[] tmp;703 return TCL_OK;704 }705 706 902 707 903 static int … … 906 1102 } 907 1103 908 plane_render->add_plane(plane[(int)plane_index], tf[(int)tf_index]);1104 //plane_render->add_plane(plane[(int)plane_index], tf[(int)tf_index]); 909 1105 910 1106 return TCL_OK; … … 1057 1253 1058 1254 #ifndef NV40 1059 nx = pow(2.0, ceil(log10((double)nx)/log10(2.0))); // must be an even power of 2 1060 ny = pow(2.0, ceil(log10((double)ny)/log10(2.0))); 1061 nz = pow(2.0, ceil(log10((double)nz)/log10(2.0))); 1255 // must be an even power of 2 for older cards 1256 nx = (int)pow(2.0, ceil(log10((double)nx)/log10(2.0))); 1257 ny = (int)pow(2.0, ceil(log10((double)ny)/log10(2.0))); 1258 nz = (int)pow(2.0, ceil(log10((double)nz)/log10(2.0))); 1062 1259 #endif 1063 1260 … … 1110 1307 /* Load a 3D volume from a dx-format file 1111 1308 */ 1112 void 1309 Rappture::Outcome 1113 1310 load_volume_file(int index, char *fname) { 1311 Rappture::Outcome result; 1312 1114 1313 Rappture::MeshTri2D xymesh; 1115 1314 int dummy, nx, ny, nz, nxy, npts; … … 1140 1339 } 1141 1340 1142 std::ofstream ftmp("tmppts"); 1341 char fpts[128]; 1342 sprintf(fpts, "/tmp/tmppts%d", getpid()); 1343 char fcells[128]; 1344 sprintf(fcells, "/tmp/tmpcells%d", getpid()); 1345 1346 std::ofstream ftmp(fpts); 1143 1347 // save corners of bounding box first, to work around meshing 1144 1348 // problems in voronoi utility … … 1156 1360 ftmp.close(); 1157 1361 1158 if (system("voronoi -t < tmppts > tmpcells") == 0) { 1362 char cmdstr[512]; 1363 sprintf(cmdstr, "voronoi -t < %s > %s", fpts, fcells); 1364 if (system(cmdstr) == 0) { 1159 1365 int cx, cy, cz; 1160 std::ifstream ftri( "tmpcells");1366 std::ifstream ftri(fcells); 1161 1367 while (!ftri.eof()) { 1162 1368 ftri.getline(line,sizeof(line)-1); … … 1170 1376 ftri.close(); 1171 1377 } else { 1172 std::cerr << "WARNING: triangularization failed" << std::endl; 1173 } 1378 return result.error("triangularization failed"); 1379 } 1380 1381 sprintf(cmdstr, "rm -f %s %s", fpts, fcells); 1382 system(cmdstr); 1174 1383 } 1175 1384 else if (sscanf(start, "object %d class regulararray count %d", &dummy, &nz) == 2) { … … 1187 1396 else if (sscanf(start, "object %d class array type %s rank 0 items %d data follows", &dummy, type, &npts) == 3) { 1188 1397 if (isrect && (npts != nx*ny*nz)) { 1189 std::cerr << "inconsistent data: expected " << nx*ny*nz << " points but found " << npts << " points" << std::endl; 1190 return; 1398 char mesg[256]; 1399 sprintf(mesg,"inconsistent data: expected %d points but found %d points", nx*ny*nz, npts); 1400 return result.error(mesg); 1191 1401 } 1192 1402 else if (!isrect && (npts != nxy*nz)) { 1193 std::cerr << "inconsistent data: expected " << nxy*nz << " points but found " << npts << " points" << std::endl; 1194 return; 1403 char mesg[256]; 1404 sprintf(mesg,"inconsistent data: expected %d points but found %d points", nxy*nz, npts); 1405 return result.error(mesg); 1195 1406 } 1196 1407 break; … … 1227 1438 // make sure that we read all of the expected points 1228 1439 if (nread != nx*ny*nz) { 1229 std::cerr << "inconsistent data: expected " << nx*ny*nz << " points but found " << nread << " points" << std::endl; 1230 return; 1440 char mesg[256]; 1441 sprintf(mesg,"inconsistent data: expected %d points but found %d points", nx*ny*nz, nread); 1442 result.error(mesg); 1443 return result; 1231 1444 } 1232 1445 … … 1243 1456 1244 1457 #ifndef NV40 1245 nx = pow(2.0, ceil(log10((double)nx)/log10(2.0))); // must be an even power of 2 1246 ny = pow(2.0, ceil(log10((double)ny)/log10(2.0))); 1247 nz = pow(2.0, ceil(log10((double)nz)/log10(2.0))); 1458 // must be an even power of 2 for older cards 1459 nx = (int)pow(2.0, ceil(log10((double)nx)/log10(2.0))); 1460 ny = (int)pow(2.0, ceil(log10((double)ny)/log10(2.0))); 1461 nz = (int)pow(2.0, ceil(log10((double)nz)/log10(2.0))); 1248 1462 #endif 1249 1463 … … 1253 1467 double dv = field.valueMax() - field.valueMin(); 1254 1468 if (dv == 0.0) { dv = 1.0; } 1255 1256 std::cout << "generating " << nx << "x" << ny << "x" << nz << " = " << nx*ny*nz << " points" << std::endl;1257 1469 1258 1470 // generate the uniformly sampled data that we need for a volume … … 1274 1486 double oldval = ((ngen/4) % nx == 0) ? 0.0 : data[ngen-4]; 1275 1487 oldval = (oldval < 0) ? 0.0 : oldval; 1276 data[ngen+1] = (curval-oldval)/dmin;1488 data[ngen+1] = curval-oldval; // assume dx=1 1277 1489 1278 1490 // gradient in y-direction 1279 1491 oldval = (ngen-4*nx >= 0) ? data[ngen-4*nx] : 0.0; 1280 1492 oldval = (oldval < 0) ? 0.0 : oldval; 1281 data[ngen+2] = (curval-oldval)/dmin;1493 data[ngen+2] = curval-oldval; // assume dy=1 1282 1494 1283 1495 // gradient in z-direction 1284 1496 oldval = (ngen-4*nx*ny >= 0) ? data[ngen-4*nx*ny] : 0.0; 1285 1497 oldval = (oldval < 0) ? 0.0 : oldval; 1286 data[ngen+3] = (curval-oldval)/dmin;1287 1498 data[ngen+3] = curval-oldval; // assume dz=1 1499 ngen += 4; 1288 1500 } 1289 1501 } 1290 1502 } 1291 1292 /*1293 //hack very first and last yz slice have 0 grad1294 for(int iz=0; iz<nz; iz++){1295 for(int iy=0; iy<ny; iy++){1296 int index1, index2;1297 int ix1 = 0;1298 int ix2 = 3;1299 index1 = ix1 + iy*nx + iz*nx*ny;1300 index2 = ix2 + iy*nx + iz*nx*ny;1301 data[4*index1 + 1] = data[4*index2 + 1];1302 data[4*index1 + 2] = data[4*index2 + 2];1303 data[4*index1 + 3] = data[4*index2 + 3];1304 1305 ix1 = nx-1;1306 ix2 = nx-2;1307 index1 = ix1 + iy*nx + iz*nx*ny;1308 index2 = ix2 + iy*nx + iz*nx*ny;1309 data[4*index1 + 1] = data[4*index2 + 1];1310 data[4*index1 + 2] = data[4*index2 + 2];1311 data[4*index1 + 3] = data[4*index2 + 3];1312 }1313 }1314 */1315 1503 1316 1504 load_volume(index, nx, ny, nz, 4, data); … … 1331 1519 // make sure that we read all of the expected points 1332 1520 if (nread != nxy*nz) { 1333 std::cerr << "inconsistent data: expected " << nxy*nz << " points but found " << nread << " points" << std::endl; 1334 return; 1521 char mesg[256]; 1522 sprintf(mesg,"inconsistent data: expected %d points but found %d points", nxy*nz, nread); 1523 return result.error(mesg); 1335 1524 } 1336 1525 … … 1346 1535 1347 1536 nx = (int)ceil(dx/dmin); 1348 nx = pow(2.0, ceil(log10((double)nx)/log10(2.0))); // must be an even power of 21349 1537 ny = (int)ceil(dy/dmin); 1350 ny = pow(2.0, ceil(log10((double)ny)/log10(2.0)));1351 1538 nz = (int)ceil(dz/dmin); 1352 nz = pow(2.0, ceil(log10((double)nz)/log10(2.0))); 1539 #ifndef NV40 1540 // must be an even power of 2 for older cards 1541 nx = (int)pow(2.0, ceil(log10((double)nx)/log10(2.0))); 1542 ny = (int)pow(2.0, ceil(log10((double)ny)/log10(2.0))); 1543 nz = (int)pow(2.0, ceil(log10((double)nz)/log10(2.0))); 1544 #endif 1353 1545 float *data = new float[4*nx*ny*nz]; 1354 1546 … … 1356 1548 double dv = field.valueMax() - field.valueMin(); 1357 1549 if (dv == 0.0) { dv = 1.0; } 1358 std::cout << "generating " << nx << "x" << ny << "x" << nz << " = " << nx*ny*nz << " points" << std::endl;1359 1550 1360 1551 // generate the uniformly sampled data that we need for a volume … … 1367 1558 double xval = x0 + ix*dmin; 1368 1559 double v = field.value(xval,yval,zval); 1369 data[ngen++] = (isnan(v)) ? -1.0 : (v - vmin)/dv; 1370 data[ngen++] = 0.0; 1371 data[ngen++] = 0.0; 1372 data[ngen++] = 0.0; 1560 1561 // scale all values [0-1], -1 => out of bounds 1562 v = (isnan(v)) ? -1.0 : (v - vmin)/dv; 1563 data[ngen] = v; 1564 1565 // gradient in x-direction 1566 double curval = (v < 0) ? 0.0 : v; 1567 double oldval = ((ngen/4) % nx == 0) ? 0.0 : data[ngen-4]; 1568 oldval = (oldval < 0) ? 0.0 : oldval; 1569 data[ngen+1] = curval-oldval; // assume dx=1 1570 1571 // gradient in y-direction 1572 oldval = (ngen-4*nx >= 0) ? data[ngen-4*nx] : 0.0; 1573 oldval = (oldval < 0) ? 0.0 : oldval; 1574 data[ngen+2] = curval-oldval; // assume dy=1 1575 1576 // gradient in z-direction 1577 oldval = (ngen-4*nx*ny >= 0) ? data[ngen-4*nx*ny] : 0.0; 1578 oldval = (oldval < 0) ? 0.0 : oldval; 1579 data[ngen+3] = curval-oldval; // assume dz=1 1580 ngen += 4; 1373 1581 } 1374 1582 } … … 1378 1586 } 1379 1587 } else { 1380 std::cerr << "WARNING: data not found in file " << fname << std::endl; 1381 } 1588 char mesg[256]; 1589 sprintf(mesg,"data not found in file %s", fname); 1590 return result.error(mesg); 1591 } 1592 1593 // 1594 // Center this new volume on the origin. 1595 // 1596 float dx0 = -0.5; 1597 float dy0 = -0.5*dy/dx; 1598 float dz0 = -0.5*dz/dx; 1599 volume[index]->move(Vector3(dx0, dy0, dz0)); 1600 1601 return result; 1382 1602 } 1383 1603 … … 1404 1624 1405 1625 1406 // load a colormap 1D texture1407 void load_transfer_function(int index, int size, float* data){ 1408 1409 if(tf[index]!=0){1410 delete tf[index];1411 tf[index]=0;1412 }1413 1414 tf[index] = new TransferFunction(size, data);1626 // get a colormap 1D texture by name 1627 TransferFunction* 1628 get_transfunc(char *name) { 1629 Tcl_HashEntry *entryPtr; 1630 entryPtr = Tcl_FindHashEntry(&tftable, name); 1631 if (entryPtr) { 1632 return (TransferFunction*)Tcl_GetHashValue(entryPtr); 1633 } 1634 return NULL; 1415 1635 } 1416 1636 … … 1421 1641 1422 1642 //fprintf(stderr, "tf update\n"); 1423 if(tf[0]==0) return; 1643 TransferFunction *tf = get_transfunc("default"); 1644 if (tf == NULL) return; 1424 1645 1425 1646 float data[256*4]; … … 1432 1653 } 1433 1654 1434 tf [0]->update(data);1655 tf->update(data); 1435 1656 1436 1657 #ifdef EVENTLOG … … 1441 1662 #endif 1442 1663 } 1443 1444 1445 //------------------------------------------1446 //update the transfer function in server mode1447 //------------------------------------------1448 void update_transfer_function(int index, float* data){1449 tf[index]->update(data);1450 }1451 1452 1664 1453 1665 … … 1623 1835 1624 1836 1625 void init_transfer_function(){1626 tf[0] = new TransferFunction(def_tf_size, def_tf);1627 }1628 1629 1630 1837 //init line integral convolution 1631 1838 void init_lic(){ … … 1705 1912 glLightfv(GL_LIGHT1, GL_SPECULAR, white_light); 1706 1913 1707 //init volume a nd colormap arrays1914 //init volume array 1708 1915 for(int i=0; i<MAX_N_VOLUMES; i++){ 1709 1916 volume[i] = 0; 1710 tf[i] = 0;1711 1917 } 1918 1919 // init table of transfer functions 1920 Tcl_InitHashTable(&tftable, TCL_STRING_KEYS); 1712 1921 1713 1922 //check if performance query is supported … … 1720 1929 //load_volume_file(0, "./data/nw-AB-Vg=0.000-Vd=1.000-potential.dx"); 1721 1930 //load_volume_file(0, "./data/test2.dx"); 1722 1723 load_volume_file(0, "./data/mu-wire-3d.dx"); 1931 //load_volume_file(0, "./data/mu-wire-3d.dx"); 1724 1932 //load_volume_file(0, "./data/input_nd_dx_4"); //take a VERY long time? 1725 1933 //load_vector_file(1, "./data/J-wire-vec.dx"); … … 1728 1936 //load_volume_file(4, "./data/mu-wire-3d.dx"); 1729 1937 1730 init_transfer_function(); //initialize transfer function1731 1938 init_offscreen_buffer(); //frame buffer object for offscreen rendering 1732 1939 init_cg(); //create cg shader context … … 1734 1941 //create volume renderer and add volumes to it 1735 1942 vol_render = new VolumeRenderer(g_context); 1736 volume[0]->set_n_slice(512);1737 volume[0]->disable_cutplane(0);1738 volume[0]->disable_cutplane(1);1739 volume[0]->disable_cutplane(2);1740 vol_render->add_volume(volume[0], tf[0]);1741 1742 //volume[1]->move(Vector3(0.42, 0.1, 0.1));1743 //vol_render->add_volume(volume[1], tf[0]);1744 1745 //volume[3]->move(Vector3(0.2, -0.1, -0.1));1746 //vol_render->add_volume(volume[3], tf[0]);1747 //volume[4]->move(Vector3(0.2, 0.1, -0.1));1748 //vol_render->add_volume(volume[4], tf[0]);1749 1750 1943 1751 1944 //create an 2D plane renderer … … 1753 1946 make_test_2D_data(); 1754 1947 1755 plane_render->add_plane(plane[0], tf[0]); 1756 1757 1948 plane_render->add_plane(plane[0], get_transfunc("default")); 1949 1758 1950 //init_particle_system(); 1759 1951 //init_lic(); … … 1766 1958 Tcl_MakeSafe(interp); 1767 1959 1960 Tcl_DStringInit(&cmdbuffer); 1961 1768 1962 // manipulate the viewpoint 1769 1963 Tcl_CreateCommand(interp, "camera", CameraCmd, … … 1778 1972 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); 1779 1973 1974 // manipulate transfer functions 1975 Tcl_CreateCommand(interp, "transfunc", TransfuncCmd, 1976 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); 1977 1780 1978 // manipulate volume data 1781 1979 Tcl_CreateCommand(interp, "volume", VolumeCmd, 1782 1980 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); 1783 1981 1784 //create new transfer function 1785 Tcl_CreateCommand(interp, "tf_new", TransferFunctionNewCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL); 1786 //update an existing transfer function 1787 Tcl_CreateCommand(interp, "tf_update", TransferFunctionUpdateCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL); 1788 1789 1790 //create new volume 1791 Tcl_CreateCommand(interp, "volume_new", VolumeNewCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL); 1982 // create a default transfer function 1983 if (Tcl_Eval(interp, def_transfunc) != TCL_OK) { 1984 fprintf(stdin, "WARNING: bad default transfer function\n"); 1985 fprintf(stdin, Tcl_GetStringResult(interp)); 1986 } 1987 1988 1792 1989 //link an EXISTING volume and transfer function to the volume renderer. 1793 1990 //Only after being added, can a volume be rendered. This command does not create a volume nor a transfer function … … 1795 1992 //move an volume 1796 1993 Tcl_CreateCommand(interp, "volume_move", VolumeMoveCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL); 1797 //enable or disable an existing volume1798 Tcl_CreateCommand(interp, "volume_enable", VolumeEnableCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);1799 1994 //resize volume 1800 1995 Tcl_CreateCommand(interp, "volume_resize", VolumeResizeCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL); … … 1868 2063 void xinetd_listen(){ 1869 2064 1870 std::string data; 1871 char tmp[256]; 1872 bzero(tmp, 256); 1873 int status = read(0, tmp, 256); 1874 if (status <= 0) { 1875 exit(0); 1876 } 1877 data = tmp; 1878 1879 if (Tcl_Eval(interp, (char*)data.c_str()) != TCL_OK) { 1880 std::ostringstream errmsg; 1881 errmsg << "ERROR: " << Tcl_GetStringResult(interp) << std::endl; 1882 write(0, errmsg.str().c_str(), errmsg.str().size()); 1883 return; 1884 } 1885 2065 int flags = fcntl(0, F_GETFL, 0); 2066 fcntl(0, F_SETFL, flags & ~O_NONBLOCK); 2067 2068 int status = TCL_OK; 2069 int npass = 0; 2070 2071 // 2072 // Read and execute as many commands as we can from stdin... 2073 // 2074 while (status == TCL_OK) { 2075 // 2076 // Read the next command from the buffer. First time through 2077 // we block here and wait if necessary until a command comes in. 2078 // 2079 // BE CAREFUL: Read only one command, up to a newline. 2080 // The "volume data follows" command needs to be able to read 2081 // the data immediately following the command, and we shouldn't 2082 // consume it here. 2083 // 2084 while (1) { 2085 char c = getchar(); 2086 if (c <= 0) { 2087 if (npass == 0) { 2088 exit(0); // EOF -- we're done! 2089 } else { 2090 break; 2091 } 2092 } 2093 Tcl_DStringAppend(&cmdbuffer, &c, 1); 2094 2095 if (c=='\n' && Tcl_CommandComplete(Tcl_DStringValue(&cmdbuffer))) { 2096 break; 2097 } 2098 } 2099 2100 // no command? then we're done for now 2101 if (Tcl_DStringLength(&cmdbuffer) == 0) { 2102 break; 2103 } 2104 2105 // back to original flags during command evaluation... 2106 fcntl(0, F_SETFL, flags & ~O_NONBLOCK); 2107 2108 status = Tcl_Eval(interp, Tcl_DStringValue(&cmdbuffer)); 2109 Tcl_DStringSetLength(&cmdbuffer, 0); 2110 2111 // non-blocking for next read -- we might not get anything 2112 fcntl(0, F_SETFL, flags | O_NONBLOCK); 2113 npass++; 2114 } 2115 fcntl(0, F_SETFL, flags); 2116 2117 if (status != TCL_OK) { 2118 std::ostringstream errmsg; 2119 errmsg << "ERROR: " << Tcl_GetStringResult(interp) << std::endl; 2120 write(0, errmsg.str().c_str(), errmsg.str().size()); 2121 return; 2122 } 2123 2124 // 2125 // Generate the latest frame and send it back to the client 2126 // 1886 2127 display(); 1887 2128 … … 1936 2177 bmp_header_add_int(header, pos, 0); 1937 2178 1938 std::ostringstream buffer;1939 buffer<< "nv>image -bytes " << fsize << "\n";1940 write(0, buffer.str().c_str(), buffer.str().size());2179 std::ostringstream result; 2180 result << "nv>image -bytes " << fsize << "\n"; 2181 write(0, result.str().c_str(), result.str().size()); 1941 2182 1942 2183 write(0, header, sizeof(header)); 1943 2184 write(0, screen_buffer, win_width * win_height * 3); 1944 2185 #endif 1945 1946 cerr << "server: serve() image sent" << endl;1947 2186 } 1948 2187 … … 2643 2882 glutInit(&argc, argv); 2644 2883 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); 2645 2646 MainTransferFunctionWindow * tf_window;2647 tf_window = new MainTransferFunctionWindow();2648 tf_window->mainInit();2649 2884 2650 2885 glutInitWindowSize(win_width, win_height); 2651 2886 glutInitWindowPosition(10, 10); 2652 2887 render_window = glutCreateWindow(argv[0]); 2653 2654 2888 glutDisplayFunc(display); 2889 2655 2890 #ifndef XINETD 2891 MainTransferFunctionWindow * tf_window; 2892 tf_window = new MainTransferFunctionWindow(); 2893 tf_window->mainInit(); 2894 2656 2895 glutMouseFunc(mouse); 2657 2896 glutMotionFunc(motion); -
trunk/gui/vizservers/nanovis/nanovis.h
r431 r445 113 113 int iframe = 0; 114 114 int Npat = 64; 115 int alpha = ( 0.12*255);115 int alpha = (int)round(0.12*255); 116 116 float sa; 117 117 float tmax = NPIX/(SCALE*NPN);
Note: See TracChangeset
for help on using the changeset viewer.