Changeset 829
- Timestamp:
- Dec 17, 2007 8:17:29 AM (13 years ago)
- Location:
- trunk/vizservers/nanovis
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/vizservers/nanovis/Makefile.in
r828 r829 46 46 newmatrm.o nm_misc.o solution.o sort.o svd.o submat.o \ 47 47 Image.o ImageLoader.o ImageLoaderImpl.o BMPImageLoaderImpl.o ImageLoaderFactory.o \ 48 Util.o \48 Util.o Command.o \ 49 49 R2string.o R2FilePath.o R2Fonts.o R2Object.o R2Geometry.o R2IndexBuffer.o R2VertexBuffer.o 50 50 … … 219 219 220 220 Util.o: Util.cpp Util.h 221 Command.o: Command.cpp Command.h 221 222 222 223 nanovis.o: nanovis.cpp nanovis.h $(AUXSRC) -
trunk/vizservers/nanovis/config.h
r434 r829 14 14 */ 15 15 16 #ifndef __CONFIG_H__ 17 #define __CONFIG_H__ 16 18 17 19 #define NV40 //Uncomment if using 6 series card. By default we assume older card the 5xxx series … … 19 21 //#define EVENTLOG //enable event logging 20 22 //#define DO_RLE //do run length compression 23 24 #endif -
trunk/vizservers/nanovis/nanovis.cpp
r827 r829 55 55 #include "Grid.h" 56 56 57 //#define _LOCAL_ZINC_TEST_58 //59 // FOR testing new functions60 //#include "Test.h"61 57 62 58 // R2 headers … … 122 118 bool axis_on = true; 123 119 120 // in Command.cpp 121 extern void xinetd_listen(); 122 extern void initTcl(); 123 124 124 125 // forward declarations 125 126 //void init_particles(); … … 155 156 // pointers to volumes, currently handle up to 10 volumes 156 157 vector<Volume*> volume; 157 158 158 vector<HeightMap*> g_heightMap; 159 159 vector<PointSet*> g_pointSet; … … 178 178 179 179 extern R2Fonts* g_fonts; 180 181 // FOR NANOVIS.H 182 //variables for mouse events 183 float live_rot_x = 90.; //object rotation angles 184 float live_rot_y = 180.; 185 float live_rot_z = -135; 186 187 float live_obj_x = -0.0; //object translation location from the origin 188 float live_obj_y = -0.0; 189 float live_obj_z = -2.5; 190 191 float live_diffuse = 1.; 192 float live_specular = 3.; 193 194 int left_last_x, left_last_y, right_last_x, right_last_y; //last locations mouse events 195 bool left_down = false; 196 bool right_down = false; 197 198 float lic_slice_x=0, lic_slice_y=0, lic_slice_z=0.3;//image based flow visualization slice location 199 200 int win_width = NPIX; //size of the render window 201 int win_height = NPIX; //size of the render window 202 203 204 //image based flow visualization variables 205 int iframe = 0; 206 int Npat = 64; 207 int alpha = (int)round(0.12*255); 208 float sa; 209 float tmax = NPIX/(SCALE*NPN); 210 float dmax = SCALE/NPIX; 211 212 213 //currently active shader, default renders one volume only 214 int cur_shader = 0; 180 215 181 216 /* … … 202 237 int renderMode = RM_VOLUME; 203 238 204 // Tcl interpreter for incoming messages 205 static Tcl_Interp *interp; 206 static Tcl_DString cmdbuffer; 207 208 static int ScreenShotCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 209 static int CameraCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 210 static int CutplaneCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 211 static int LegendCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 212 static int ScreenCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 213 static int TransfuncCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 214 static int UpCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 215 static int VolumeCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 216 217 static int PlaneNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 218 static int PlaneLinkCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 219 static int PlaneEnableCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 220 221 static int GridCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 222 static int AxisCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])); 223 224 static int GetVolumeIndices _ANSI_ARGS_((Tcl_Interp *interp, int argc, CONST84 char *argv[], vector<int>* vectorPtr)); 225 static int GetIndices(Tcl_Interp *interp, int argc, CONST84 char *argv[], vector<int>* vectorPtr); 226 static int GetAxis _ANSI_ARGS_((Tcl_Interp *interp, char *str, int *valPtr)); 227 static int GetColor _ANSI_ARGS_((Tcl_Interp *interp, char *str, float *rgbPtr)); 228 229 /* 230 * ---------------------------------------------------------------------- 231 * CLIENT COMMAND: 232 * camera aim <x0> <y0> <z0> 233 * camera angle <xAngle> <yAngle> <zAngle> 234 * camera zoom <factor> 235 * 236 * Clients send these commands to manipulate the camera. The "angle" 237 * operation controls the angle of the camera around the focal point. 238 * The "zoom" operation sets the zoom factor, moving the camera in 239 * and out. 240 * ---------------------------------------------------------------------- 241 */ 242 static int 243 CameraCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) 244 { 245 if (argc < 2) { 246 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 247 " option arg arg...\"", (char*)NULL); 248 return TCL_ERROR; 249 } 250 251 char c = *argv[1]; 252 if (c == 'a' && strcmp(argv[1],"angle") == 0) { 253 if (argc != 5) { 254 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 255 " angle xangle yangle zangle\"", (char*)NULL); 256 return TCL_ERROR; 257 } 258 259 double xangle, yangle, zangle; 260 if (Tcl_GetDouble(interp, argv[2], &xangle) != TCL_OK) { 261 return TCL_ERROR; 262 } 263 if (Tcl_GetDouble(interp, argv[3], &yangle) != TCL_OK) { 264 return TCL_ERROR; 265 } 266 if (Tcl_GetDouble(interp, argv[4], &zangle) != TCL_OK) { 267 return TCL_ERROR; 268 } 269 cam->rotate(xangle, yangle, zangle); 270 271 return TCL_OK; 272 } 273 else if (c == 'a' && strcmp(argv[1],"aim") == 0) { 274 if (argc != 5) { 275 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 276 " aim x y z\"", (char*)NULL); 277 return TCL_ERROR; 278 } 279 280 double x0, y0, z0; 281 if (Tcl_GetDouble(interp, argv[2], &x0) != TCL_OK) { 282 return TCL_ERROR; 283 } 284 if (Tcl_GetDouble(interp, argv[3], &y0) != TCL_OK) { 285 return TCL_ERROR; 286 } 287 if (Tcl_GetDouble(interp, argv[4], &z0) != TCL_OK) { 288 return TCL_ERROR; 289 } 290 cam->aim(x0, y0, z0); 291 292 return TCL_OK; 293 } 294 else if (c == 'z' && strcmp(argv[1],"zoom") == 0) { 295 if (argc != 3) { 296 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 297 " zoom factor\"", (char*)NULL); 298 return TCL_ERROR; 299 } 300 301 double zoom; 302 if (Tcl_GetDouble(interp, argv[2], &zoom) != TCL_OK) { 303 return TCL_ERROR; 304 } 305 306 live_obj_z = -2.5/zoom; 307 cam->move(live_obj_x, live_obj_y, live_obj_z); 308 309 return TCL_OK; 310 } 311 312 Tcl_AppendResult(interp, "bad option \"", argv[1], 313 "\": should be aim, angle, or zoom", (char*)NULL); 314 return TCL_ERROR; 315 } 316 317 static int 318 ScreenShotCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) 319 { 320 int old_win_width = win_width; 321 int old_win_height = win_height; 322 323 #ifdef XINETD 324 resize_offscreen_buffer(1024, 1024); 325 cam->set_screen_size(30, 90, 1024 - 60, 1024 - 120); 326 offscreen_buffer_capture(); //enable offscreen render 327 display(); 328 329 // INSOO 330 // TBD 331 Volume* vol = volume[0]; 332 TransferFunction* tf = g_vol_render->get_volume_shading(vol); 333 if (tf) 334 { 335 float data[512]; 336 for (int i=0; i < 256; i++) { 337 data[i] = data[i+256] = (float)(i/255.0); 338 } 339 Texture2D* plane = new Texture2D(256, 2, GL_FLOAT, GL_LINEAR, 1, data); 340 g_color_table_renderer->render(1024, 1024, plane, tf, vol->range_min(), vol->range_max()); 341 delete plane; 342 } 343 344 read_screen(); 345 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); 346 347 bmp_write("nv>screenshot -bytes"); 348 349 resize_offscreen_buffer(old_win_width, old_win_height); 350 #endif 351 352 return TCL_OK; 353 } 354 355 /* 356 * ---------------------------------------------------------------------- 357 * CLIENT COMMAND: 358 * cutplane state on|off <axis> ?<volume>...? 359 * cutplane position <relvalue> <axis> ?<volume>...? 360 * 361 * Clients send these commands to manipulate the cutplanes in one or 362 * more data volumes. The "state" command turns a cutplane on or 363 * off. The "position" command changes the position to a relative 364 * value in the range 0-1. The <axis> can be x, y, or z. These 365 * operations are applied to the volumes represented by one or more 366 * <volume> indices. If no volumes are specified, then all volumes 367 * are updated. 368 * ---------------------------------------------------------------------- 369 */ 370 static int 371 CutplaneCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) 372 { 373 if (argc < 2) { 374 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 375 " option ?arg arg...?\"", (char*)NULL); 376 return TCL_ERROR; 377 } 378 379 char c = *argv[1]; 380 if (c == 's' && strcmp(argv[1],"state") == 0) { 381 if (argc < 4) { 382 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 383 " state on|off axis ?volume ...? \"", (char*)NULL); 384 return TCL_ERROR; 385 } 386 387 int state; 388 if (Tcl_GetBoolean(interp, argv[2], &state) != TCL_OK) { 389 return TCL_ERROR; 390 } 391 392 int axis; 393 if (GetAxis(interp, (char*) argv[3], &axis) != TCL_OK) { 394 return TCL_ERROR; 395 } 396 397 vector<int> ivol; 398 if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) { 399 return TCL_ERROR; 400 } 401 402 vector<int>::iterator iter = ivol.begin(); 403 while (iter != ivol.end()) { 404 if (state) { 405 volume[*iter]->enable_cutplane(axis); 406 } else { 407 volume[*iter]->disable_cutplane(axis); 408 } 409 ++iter; 410 } 411 return TCL_OK; 412 } 413 else if (c == 'p' && strcmp(argv[1],"position") == 0) { 414 if (argc < 4) { 415 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 416 " position relval axis ?volume ...? \"", (char*)NULL); 417 return TCL_ERROR; 418 } 419 420 double relval; 421 if (Tcl_GetDouble(interp, argv[2], &relval) != TCL_OK) { 422 return TCL_ERROR; 423 } 424 // keep this just inside the volume so it doesn't disappear 425 if (relval < 0.01) { relval = 0.01; } 426 if (relval > 0.99) { relval = 0.99; } 427 428 int axis; 429 if (GetAxis(interp, (char*) argv[3], &axis) != TCL_OK) { 430 return TCL_ERROR; 431 } 432 433 vector<int> ivol; 434 if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) { 435 return TCL_ERROR; 436 } 437 438 vector<int>::iterator iter = ivol.begin(); 439 while (iter != ivol.end()) { 440 volume[*iter]->move_cutplane(axis, (float)relval); 441 ++iter; 442 } 443 return TCL_OK; 444 } 445 446 Tcl_AppendResult(interp, "bad option \"", argv[1], 447 "\": should be position or state", (char*)NULL); 448 return TCL_ERROR; 449 } 450 451 /* 452 * ---------------------------------------------------------------------- 453 * CLIENT COMMAND: 454 * legend <volumeIndex> <width> <height> 455 * 456 * Clients use this to generate a legend image for the specified 457 * transfer function. The legend image is a color gradient from 0 458 * to one, drawn in the given transfer function. The resulting image 459 * is returned in the size <width> x <height>. 460 * ---------------------------------------------------------------------- 461 */ 462 static int 463 LegendCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) 464 { 465 if (argc != 4) { 466 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 467 " transfunc width height\"", (char*)NULL); 468 return TCL_ERROR; 469 } 470 471 TransferFunction *tf = NULL; 472 int ivol; 473 if (Tcl_GetInt(interp, argv[1], &ivol) != TCL_OK) { 474 return TCL_ERROR; 475 } 476 if (ivol < n_volumes) { 477 tf = g_vol_render->get_volume_shading(volume[ivol]); 478 } 479 if (tf == NULL) { 480 Tcl_AppendResult(interp, "transfer function not defined for volume ", argv[1], (char*)NULL); 481 return TCL_ERROR; 482 } 483 484 int old_width = win_width; 485 int old_height = win_height; 486 487 int width, height; 488 if (Tcl_GetInt(interp, argv[2], &width) != TCL_OK) { 489 return TCL_ERROR; 490 } 491 if (Tcl_GetInt(interp, argv[3], &height) != TCL_OK) { 492 return TCL_ERROR; 493 } 494 495 plane_render->set_screen_size(width, height); 496 resize_offscreen_buffer(width, height); 497 498 // generate data for the legend 499 float data[512]; 500 for (int i=0; i < 256; i++) { 501 data[i] = data[i+256] = (float)(i/255.0); 502 } 503 plane[0] = new Texture2D(256, 2, GL_FLOAT, GL_LINEAR, 1, data); 504 int index = plane_render->add_plane(plane[0], tf); 505 plane_render->set_active_plane(index); 506 507 offscreen_buffer_capture(); 508 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear screen 509 plane_render->render(); 510 511 // INSOO 512 glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, screen_buffer); 513 //glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, screen_buffer); // INSOO's 514 515 std::ostringstream result; 516 result << "nv>legend " << argv[1]; 517 result << " " << volume[ivol]->range_min(); 518 result << " " << volume[ivol]->range_max(); 519 bmp_write(result.str().c_str()); 520 write(0, "\n", 1); 521 522 plane_render->remove_plane(index); 523 resize_offscreen_buffer(old_width, old_height); 524 525 return TCL_OK; 526 } 527 528 529 530 /* 531 * ---------------------------------------------------------------------- 532 * CLIENT COMMAND: 533 * screen <width> <height> 534 * 535 * Clients send this command to set the size of the rendering area. 536 * Future images are generated at the specified width/height. 537 * ---------------------------------------------------------------------- 538 */ 539 static int 540 ScreenCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) 541 { 542 int w, h; 543 544 if (argc != 3) { 545 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 546 " width height\"", (char*)NULL); 547 return TCL_ERROR; 548 } 549 if (Tcl_GetInt(interp, argv[1], &w) != TCL_OK) { 550 return TCL_ERROR; 551 } 552 if (Tcl_GetInt(interp, argv[2], &h) != TCL_OK) { 553 return TCL_ERROR; 554 } 555 resize_offscreen_buffer(w, h); 556 557 return TCL_OK; 558 } 559 560 /* 561 * ---------------------------------------------------------------------- 562 * CLIENT COMMAND: 563 * transfunc define <name> <colormap> <alphamap> 564 * where <colormap> = { <v> <r> <g> <b> ... } 565 * <alphamap> = { <v> <w> ... } 566 * 567 * Clients send these commands to manipulate the transfer functions. 568 * ---------------------------------------------------------------------- 569 */ 570 static int 571 TransfuncCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) 572 { 573 if (argc < 2) { 574 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 575 " option arg arg...\"", (char*)NULL); 576 return TCL_ERROR; 577 } 578 579 char c = *argv[1]; 580 if (c == 'd' && strcmp(argv[1],"define") == 0) { 581 if (argc != 5) { 582 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 583 argv[1], " define name colormap alphamap\"", (char*)NULL); 584 return TCL_ERROR; 585 } 586 587 // decode the data and store in a series of fields 588 Rappture::Field1D rFunc, gFunc, bFunc, wFunc; 589 int cmapc, wmapc, i, j; 590 char **cmapv, **wmapv; 591 592 if (Tcl_SplitList(interp, argv[3], &cmapc, (const char***)&cmapv) != TCL_OK) { 593 return TCL_ERROR; 594 } 595 if (cmapc % 4 != 0) { 596 Tcl_Free((char*)cmapv); 597 Tcl_AppendResult(interp, "bad colormap in transfunc: should be ", 598 "{ v r g b ... }", (char*)NULL); 599 return TCL_ERROR; 600 } 601 602 if (Tcl_SplitList(interp, argv[4], &wmapc, (const char***)&wmapv) != TCL_OK) { 603 return TCL_ERROR; 604 } 605 if (wmapc % 2 != 0) { 606 Tcl_Free((char*)cmapv); 607 Tcl_Free((char*)wmapv); 608 Tcl_AppendResult(interp, "bad alphamap in transfunc: should be ", 609 "{ v w ... }", (char*)NULL); 610 return TCL_ERROR; 611 } 612 613 for (i=0; i < cmapc; i += 4) { 614 double vals[4]; 615 for (j=0; j < 4; j++) { 616 if (Tcl_GetDouble(interp, cmapv[i+j], &vals[j]) != TCL_OK) { 617 Tcl_Free((char*)cmapv); 618 Tcl_Free((char*)wmapv); 619 return TCL_ERROR; 620 } 621 if (vals[j] < 0 || vals[j] > 1) { 622 Tcl_Free((char*)cmapv); 623 Tcl_Free((char*)wmapv); 624 Tcl_AppendResult(interp, "bad value \"", cmapv[i+j], 625 "\": should be in the range 0-1", (char*)NULL); 626 return TCL_ERROR; 627 } 628 } 629 rFunc.define(vals[0], vals[1]); 630 gFunc.define(vals[0], vals[2]); 631 bFunc.define(vals[0], vals[3]); 632 } 633 634 for (i=0; i < wmapc; i += 2) { 635 double vals[2]; 636 for (j=0; j < 2; j++) { 637 if (Tcl_GetDouble(interp, wmapv[i+j], &vals[j]) != TCL_OK) { 638 Tcl_Free((char*)cmapv); 639 Tcl_Free((char*)wmapv); 640 return TCL_ERROR; 641 } 642 if (vals[j] < 0 || vals[j] > 1) { 643 Tcl_Free((char*)cmapv); 644 Tcl_Free((char*)wmapv); 645 Tcl_AppendResult(interp, "bad value \"", wmapv[i+j], 646 "\": should be in the range 0-1", (char*)NULL); 647 return TCL_ERROR; 648 } 649 } 650 wFunc.define(vals[0], vals[1]); 651 } 652 Tcl_Free((char*)cmapv); 653 Tcl_Free((char*)wmapv); 654 655 // sample the given function into discrete slots 656 const int nslots = 256; 657 float data[4*nslots]; 658 for (i=0; i < nslots; i++) { 659 double xval = double(i)/(nslots-1); 660 data[4*i] = rFunc.value(xval); 661 data[4*i+1] = gFunc.value(xval); 662 data[4*i+2] = bFunc.value(xval); 663 data[4*i+3] = wFunc.value(xval); 664 } 665 666 // find or create this transfer function 667 int newEntry; 668 Tcl_HashEntry *entryPtr; 669 TransferFunction *tf; 670 671 entryPtr = Tcl_CreateHashEntry(&tftable, argv[2], &newEntry); 672 if (newEntry) { 673 tf = new TransferFunction(nslots, data); 674 Tcl_SetHashValue(entryPtr, (ClientData)tf); 675 } else { 676 tf = (TransferFunction*)Tcl_GetHashValue(entryPtr); 677 tf->update(data); 678 } 679 680 return TCL_OK; 681 } 682 683 684 Tcl_AppendResult(interp, "bad option \"", argv[1], 685 "\": should be define", (char*)NULL); 686 return TCL_ERROR; 687 } 688 689 /* 690 * ---------------------------------------------------------------------- 691 * CLIENT COMMAND: 692 * up axis 693 * 694 * Clients use this to set the "up" direction for all volumes. Volumes 695 * are oriented such that this direction points upward. 696 * ---------------------------------------------------------------------- 697 */ 698 static int 699 UpCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) 700 { 701 if (argc != 2) { 702 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 703 " x|y|z|-x|-y|-z\"", (char*)NULL); 704 return TCL_ERROR; 705 } 706 707 int sign = 1; 708 char *axisName = (char*)argv[1]; 709 if (*axisName == '-') { 710 sign = -1; 711 axisName++; 712 } 713 714 int axis; 715 if (GetAxis(interp, axisName, &axis) != TCL_OK) { 716 return TCL_ERROR; 717 } 718 719 updir = (axis+1)*sign; 720 721 return TCL_OK; 722 } 723 724 /* 725 * ---------------------------------------------------------------------- 726 * CLIENT COMMAND: 727 * volume axis label x|y|z <value> ?<volumeId> ...? 728 * volume data state on|off ?<volumeId> ...? 729 * volume outline state on|off ?<volumeId> ...? 730 * volume outline color on|off ?<volumeId> ...? 731 * volume shading transfunc <name> ?<volumeId> ...? 732 * volume shading diffuse <value> ?<volumeId> ...? 733 * volume shading specular <value> ?<volumeId> ...? 734 * volume shading opacity <value> ?<volumeId> ...? 735 * volume state on|off ?<volumeId> ...? 736 * 737 * Clients send these commands to manipulate the volumes. 738 * ---------------------------------------------------------------------- 739 */ 740 void NvLoadVolumeBinFile2(int index, char* filename); 741 static int 742 VolumeCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]) 743 { 744 if (argc < 2) { 745 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 746 " option arg arg...\"", (char*)NULL); 747 return TCL_ERROR; 748 } 749 750 char c = *argv[1]; 751 if (c == 'a' && strcmp(argv[1],"axis") == 0) { 752 if (argc < 3) { 753 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 754 argv[1], " option ?arg arg...?\"", (char*)NULL); 755 return TCL_ERROR; 756 } 757 c = *argv[2]; 758 if (c == 'l' && strcmp(argv[2],"label") == 0) { 759 if (argc < 4) { 760 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 761 argv[1], " label x|y|z string ?volume ...?\"", (char*)NULL); 762 return TCL_ERROR; 763 } 764 765 int axis; 766 if (GetAxis(interp, (char*)argv[3], &axis) != TCL_OK) { 767 return TCL_ERROR; 768 } 769 770 vector<int> ivol; 771 if (GetVolumeIndices(interp, argc-5, argv+5, &ivol) != TCL_OK) { 772 return TCL_ERROR; 773 } 774 775 vector<int>::iterator iter = ivol.begin(); 776 while (iter != ivol.end()) { 777 volume[*iter]->set_label(axis, (char*)argv[4]); 778 ++iter; 779 } 780 return TCL_OK; 781 } 782 783 Tcl_AppendResult(interp, "bad option \"", argv[2], 784 "\": should be label", (char*)NULL); 785 return TCL_ERROR; 786 } 787 else if (c == 'd' && strcmp(argv[1],"data") == 0) { 788 if (argc < 3) { 789 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 790 argv[1], " option ?arg arg...?\"", (char*)NULL); 791 return TCL_ERROR; 792 } 793 c = *argv[2]; 794 if (c == 's' && strcmp(argv[2],"state") == 0) { 795 if (argc < 4) { 796 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 797 argv[1], " state on|off ?volume ...?\"", (char*)NULL); 798 return TCL_ERROR; 799 } 800 801 int state; 802 if (Tcl_GetBoolean(interp, argv[3], &state) != TCL_OK) { 803 return TCL_ERROR; 804 } 805 806 vector<int> ivol; 807 if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) { 808 return TCL_ERROR; 809 } 810 811 vector<int>::iterator iter = ivol.begin(); 812 while (iter != ivol.end()) { 813 if (state) { 814 volume[*iter]->enable_data(); 815 } else { 816 volume[*iter]->disable_data(); 817 } 818 ++iter; 819 } 820 return TCL_OK; 821 } 822 else if (c == 'f' && strcmp(argv[2],"follows") == 0) { 823 printf("Data Loading\n"); 824 //fflush(stdout); 825 //return TCL_OK; 826 827 int nbytes; 828 if (Tcl_GetInt(interp, argv[3], &nbytes) != TCL_OK) { 829 return TCL_ERROR; 830 } 831 832 Rappture::Outcome err; 833 Rappture::Buffer buf; 834 835 // DEBUG 836 int totalsize = nbytes; 837 char buffer[8096]; 838 while (nbytes > 0) 839 { 840 int chunk = (sizeof(buffer) < nbytes) ? sizeof(buffer) : nbytes; 841 int status = fread(buffer, 1, chunk, stdin); 842 //printf("Begin Reading [%d Read : %d Left]\n", status, nbytes - status); 843 fflush(stdout); 844 if (status > 0) { 845 buf.append(buffer,status); 846 nbytes -= status; 847 } else { 848 printf("data unpacking failed\n"); 849 Tcl_AppendResult(interp, "data unpacking failed: unexpected EOF", 850 (char*)NULL); 851 return TCL_ERROR; 852 } 853 } 854 855 err = Rappture::encoding::decode(buf,RPENC_Z|RPENC_B64|RPENC_HDR); 856 if (err) { 857 printf("ERROR -- DECODING\n"); 858 fflush(stdout); 859 Tcl_AppendResult(interp, err.remark().c_str(), (char*)NULL); 860 return TCL_ERROR; 861 } 862 863 int n = n_volumes; 864 char header[6]; 865 memcpy(header, buf.bytes(), sizeof(char) * 5); 866 header[5] = '\0'; 867 868 #ifdef _LOCAL_ZINC_TEST_ 869 //FILE* fp = fopen("/home/nanohub/vrinside/nv/data/HOON/QDWL_100_100_50_strain_8000i.nd_zatom_12_1", "rb"); 870 FILE* fp = fopen("/home/nanohub/vrinside/nv/data/HOON/GaAs_AlGaAs_2QD_B4.nd_zc_1_wf", "rb"); 871 unsigned char* b = (unsigned char*) malloc(buf.size()); 872 if (fp == 0) 873 { 874 printf("cannot open the file\n"); 875 fflush(stdout); 876 return TCL_ERROR; 877 } 878 fread(b, buf.size(), 1, fp); 879 fclose(fp); 880 #endif 881 882 883 printf("Checking header[%s]\n", header); 884 fflush(stdout); 885 if (!strcmp(header, "<HDR>")) 886 { 887 Volume* vol = NULL; 888 889 printf("ZincBlende stream is in\n"); 890 fflush(stdout); 891 //std::stringstream fdata(std::ios_base::out|std::ios_base::in|std::ios_base::binary); 892 //fdata.write(buf.bytes(),buf.size()); 893 //vol = NvZincBlendeReconstructor::getInstance()->loadFromStream(fdata); 894 895 #ifdef _LOCAL_ZINC_TEST_ 896 vol = NvZincBlendeReconstructor::getInstance()->loadFromMemory(b); 897 #else 898 vol = NvZincBlendeReconstructor::getInstance()->loadFromMemory((void*) buf.bytes()); 899 #endif 900 901 printf("finish loading\n"); 902 fflush(stdout); 903 if (vol) 904 { 905 while (n_volumes <= n) 906 { 907 volume.push_back((Volume*) NULL); 908 n_volumes++; 909 } 910 911 if (volume[n] != NULL) 912 { 913 delete volume[n]; 914 volume[n] = NULL; 915 } 916 917 float dx0 = -0.5; 918 float dy0 = -0.5*vol->height/vol->width; 919 float dz0 = -0.5*vol->depth/vol->width; 920 vol->move(Vector3(dx0, dy0, dz0)); 921 922 volume[n] = vol; 923 } 924 } 925 #ifdef __TEST_CODE__ 926 else if (!strcmp(header, "<FET>")) 927 { 928 printf("FET loading...\n"); 929 fflush(stdout); 930 std::stringstream fdata; 931 fdata.write(buf.bytes(),buf.size()); 932 err = load_volume_stream3(n, fdata); 933 934 if (err) { 935 Tcl_AppendResult(interp, err.remark().c_str(), (char*)NULL); 936 return TCL_ERROR; 937 } 938 } 939 #endif 940 else 941 { 942 printf("OpenDX loading...\n"); 943 fflush(stdout); 944 std::stringstream fdata; 945 fdata.write(buf.bytes(),buf.size()); 946 err = load_volume_stream(n, fdata); 947 //err = load_volume_stream2(n, fdata); 948 if (err) { 949 Tcl_AppendResult(interp, err.remark().c_str(), (char*)NULL); 950 return TCL_ERROR; 951 } 952 } 953 954 955 // 956 // BE CAREFUL: Set the number of slices to something 957 // slightly different for each volume. If we have 958 // identical volumes at exactly the same position 959 // with exactly the same number of slices, the second 960 // volume will overwrite the first, so the first won't 961 // appear at all. 962 // 963 if (volume[n]) 964 { 965 volume[n]->set_n_slice(256-n); 966 volume[n]->disable_cutplane(0); 967 volume[n]->disable_cutplane(1); 968 volume[n]->disable_cutplane(2); 969 970 g_vol_render->add_volume(volume[n], get_transfunc("default")); 971 } 972 973 return TCL_OK; 974 } 975 Tcl_AppendResult(interp, "bad option \"", argv[2], 976 "\": should be follows or state", (char*)NULL); 977 return TCL_ERROR; 978 } 979 else if (c == 'o' && strcmp(argv[1],"outline") == 0) { 980 if (argc < 3) { 981 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 982 argv[1], " option ?arg arg...?\"", (char*)NULL); 983 return TCL_ERROR; 984 } 985 c = *argv[2]; 986 if (c == 's' && strcmp(argv[2],"state") == 0) { 987 if (argc < 3) { 988 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 989 argv[1], " state on|off ?volume ...? \"", (char*)NULL); 990 return TCL_ERROR; 991 } 992 993 int state; 994 if (Tcl_GetBoolean(interp, argv[3], &state) != TCL_OK) { 995 return TCL_ERROR; 996 } 997 998 vector<int> ivol; 999 if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) { 1000 return TCL_ERROR; 1001 } 1002 1003 vector<int>::iterator iter = ivol.begin(); 1004 while (iter != ivol.end()) { 1005 if (state) { 1006 volume[*iter]->enable_outline(); 1007 } else { 1008 volume[*iter]->disable_outline(); 1009 } 1010 ++iter; 1011 } 1012 return TCL_OK; 1013 } 1014 else if (c == 'v' && strcmp(argv[2],"visible") == 0) { 1015 if (argv[3] == "false") 1016 { 1017 for (int i = 0; i < n_volumes; ++i) 1018 { 1019 if (volume[i]) volume[i]->disable_outline(); 1020 } 1021 } 1022 else if (argv[3] == "true") 1023 { 1024 for (int i = 0; i < n_volumes; ++i) 1025 { 1026 if (volume[i]) volume[i]->enable_outline(); 1027 } 1028 } 1029 1030 return TCL_OK; 1031 } 1032 else if (c == 'c' && strcmp(argv[2],"color") == 0) { 1033 if (argc < 3) { 1034 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1035 argv[1], " color {R G B} ?volume ...? \"", (char*)NULL); 1036 return TCL_ERROR; 1037 } 1038 1039 float rgb[3]; 1040 if (GetColor(interp, (char*) argv[3], rgb) != TCL_OK) { 1041 return TCL_ERROR; 1042 } 1043 1044 vector<int> ivol; 1045 if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) { 1046 return TCL_ERROR; 1047 } 1048 1049 vector<int>::iterator iter = ivol.begin(); 1050 while (iter != ivol.end()) { 1051 volume[*iter]->set_outline_color(rgb); 1052 ++iter; 1053 } 1054 return TCL_OK; 1055 } 1056 1057 Tcl_AppendResult(interp, "bad option \"", argv[2], 1058 "\": should be color or state", (char*)NULL); 1059 return TCL_ERROR; 1060 } 1061 else if (c == 's' && strcmp(argv[1],"shading") == 0) { 1062 if (argc < 3) { 1063 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1064 argv[1], " option ?arg arg...?\"", (char*)NULL); 1065 return TCL_ERROR; 1066 } 1067 c = *argv[2]; 1068 if (c == 't' && strcmp(argv[2],"transfunc") == 0) { 1069 if (argc < 4) { 1070 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1071 argv[1], " transfunc name ?volume ...?\"", (char*)NULL); 1072 return TCL_ERROR; 1073 } 1074 1075 TransferFunction *tf = get_transfunc((char*)argv[3]); 1076 if (tf == NULL) { 1077 Tcl_AppendResult(interp, "transfer function \"", argv[3], 1078 "\" is not defined", (char*)NULL); 1079 return TCL_ERROR; 1080 } 1081 1082 vector<int> ivol; 1083 if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) { 1084 return TCL_ERROR; 1085 } 1086 1087 vector<int>::iterator iter = ivol.begin(); 1088 while (iter != ivol.end()) { 1089 g_vol_render->shade_volume(volume[*iter], tf); 1090 ++iter; 1091 } 1092 return TCL_OK; 1093 } 1094 else if (c == 'd' && strcmp(argv[2],"diffuse") == 0) { 1095 if (argc < 4) { 1096 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1097 argv[1], " diffuse value ?volume ...?\"", (char*)NULL); 1098 return TCL_ERROR; 1099 } 1100 1101 double dval; 1102 if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) { 1103 return TCL_ERROR; 1104 } 1105 1106 vector<int> ivol; 1107 if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) { 1108 return TCL_ERROR; 1109 } 1110 1111 vector<int>::iterator iter = ivol.begin(); 1112 while (iter != ivol.end()) { 1113 volume[*iter]->set_diffuse((float)dval); 1114 ++iter; 1115 } 1116 return TCL_OK; 1117 } 1118 else if (c == 'o' && strcmp(argv[2],"opacity") == 0) { 1119 if (argc < 4) { 1120 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1121 argv[1], " opacity value ?volume ...?\"", (char*)NULL); 1122 return TCL_ERROR; 1123 } 1124 1125 double dval; 1126 if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) { 1127 return TCL_ERROR; 1128 } 1129 1130 vector<int> ivol; 1131 if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) { 1132 return TCL_ERROR; 1133 } 1134 1135 vector<int>::iterator iter = ivol.begin(); 1136 while (iter != ivol.end()) { 1137 volume[*iter]->set_opacity_scale((float)dval); 1138 ++iter; 1139 } 1140 return TCL_OK; 1141 } 1142 else if (c == 's' && strcmp(argv[2],"specular") == 0) { 1143 if (argc < 4) { 1144 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1145 argv[1], " specular value ?volume ...?\"", (char*)NULL); 1146 return TCL_ERROR; 1147 } 1148 1149 double dval; 1150 if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) { 1151 return TCL_ERROR; 1152 } 1153 1154 vector<int> ivol; 1155 if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) { 1156 return TCL_ERROR; 1157 } 1158 1159 vector<int>::iterator iter = ivol.begin(); 1160 while (iter != ivol.end()) { 1161 volume[*iter]->set_specular((float)dval); 1162 ++iter; 1163 } 1164 return TCL_OK; 1165 } 1166 Tcl_AppendResult(interp, "bad option \"", argv[2], 1167 "\": should be diffuse, opacity, specular, or transfunc", (char*)NULL); 1168 return TCL_ERROR; 1169 } 1170 else if (c == 's' && strcmp(argv[1],"state") == 0) { 1171 if (argc < 3) { 1172 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1173 argv[1], " on|off ?volume...?\"", (char*)NULL); 1174 return TCL_ERROR; 1175 } 1176 1177 int state; 1178 if (Tcl_GetBoolean(interp, argv[2], &state) != TCL_OK) { 1179 return TCL_ERROR; 1180 } 1181 1182 vector<int> ivol; 1183 if (GetVolumeIndices(interp, argc-3, argv+3, &ivol) != TCL_OK) { 1184 return TCL_ERROR; 1185 } 1186 1187 vector<int>::iterator iter = ivol.begin(); 1188 while (iter != ivol.end()) { 1189 if (state) { 1190 volume[*iter]->enable(); 1191 } else { 1192 volume[*iter]->disable(); 1193 } 1194 ++iter; 1195 } 1196 return TCL_OK; 1197 } 1198 else if (c == 't' && strcmp(argv[1],"test2") == 0) { 1199 volume[1]->disable_data(); 1200 volume[1]->disable(); 1201 return TCL_OK; 1202 } 1203 1204 Tcl_AppendResult(interp, "bad option \"", argv[1], 1205 "\": should be data, outline, shading, or state", (char*)NULL); 1206 return TCL_ERROR; 1207 } 1208 1209 int HeightMapCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])) 1210 { 1211 if (argc < 2) 1212 { 1213 { 1214 srand( (unsigned)time( NULL ) ); 1215 int size = 20 * 20; 1216 float sigma = 5.0f; 1217 float mean = exp(0.0f) / (sigma * sqrt(2.0f)); 1218 float* data = (float*) malloc(sizeof(float) * size); 1219 1220 float x; 1221 for (int i = 0; i < size; ++i) 1222 { 1223 x = - 10 + i%20; 1224 data[i] = exp(- (x * x)/(2 * sigma * sigma)) / (sigma * sqrt(2.0f)) / mean; 1225 } 1226 1227 HeightMap* heightMap = new HeightMap(); 1228 heightMap->setHeight(0, 0, 1, 1, 20, 20, data); 1229 heightMap->setColorMap(get_transfunc("default")); 1230 heightMap->setVisible(true); 1231 heightMap->setLineContourVisible(true); 1232 g_heightMap.push_back(heightMap); 1233 } 1234 1235 return TCL_OK; 1236 } 1237 1238 char c = *argv[1]; 1239 if (c == 'd' && strcmp(argv[1],"data") == 0) 1240 { 1241 //bytes 1242 vector<int> indices; 1243 if (strcmp(argv[2],"visible") == 0) 1244 { 1245 bool visible = !strcmp(argv[3], "true"); 1246 1247 if (GetIndices(interp, argc-4, argv+4, &indices) != TCL_OK) 1248 { 1249 return TCL_ERROR; 1250 } 1251 1252 for (int i = 0; i < indices.size(); ++i) 1253 { 1254 if ((indices[i] < g_heightMap.size()) && (g_heightMap[indices[i]] != NULL)) 1255 { 1256 g_heightMap[indices[i]]->setVisible(visible); 1257 } 1258 } 1259 return TCL_OK; 1260 } 1261 else if (c == 'f' && strcmp(argv[2],"follows") == 0) { 1262 int nbytes; 1263 if (Tcl_GetInt(interp, argv[3], &nbytes) != TCL_OK) { 1264 return TCL_ERROR; 1265 } 1266 } 1267 } 1268 else if (c == 'l' && (strcmp(argv[1], "linecontour") == 0)) 1269 { 1270 //bytes 1271 vector<int> indices; 1272 if (strcmp(argv[2],"visible") == 0) 1273 { 1274 1275 bool visible = !(strcmp("true", argv[3])); 1276 printf("heightmap linecontour visible %s\n", (visible)?"true":"false"); 1277 if (GetIndices(interp, argc-4, argv+4, &indices) != TCL_OK) 1278 { 1279 return TCL_ERROR; 1280 } 1281 1282 for (int i = 0; i < indices.size(); ++i) 1283 { 1284 printf("heightmap index %d\n"); 1285 if ((indices[i] < g_heightMap.size()) && (g_heightMap[indices[i]] != NULL)) 1286 { 1287 printf("heightmap index %d visible applied\n"); 1288 g_heightMap[indices[i]]->setLineContourVisible(visible); 1289 } 1290 } 1291 return TCL_OK; 1292 } 1293 else if (strcmp(argv[2],"color") == 0) 1294 { 1295 double r, g, b; 1296 if ((Tcl_GetDouble(interp, argv[3], &r) == TCL_OK) && 1297 (Tcl_GetDouble(interp, argv[4], &g) == TCL_OK) && 1298 (Tcl_GetDouble(interp, argv[5], &b) == TCL_OK)) { 1299 r = r / 255.0; 1300 g = g / 255.0; 1301 b = b / 255.0; 1302 } 1303 else 1304 { 1305 return TCL_ERROR; 1306 } 1307 1308 vector<int> indices; 1309 if (GetIndices(interp, argc-6, argv+6, &indices) != TCL_OK) 1310 { 1311 return TCL_ERROR; 1312 } 1313 for (int i = 0; i < indices.size(); ++i) 1314 { 1315 if ((indices[i] < g_heightMap.size()) && (g_heightMap[indices[i]] != NULL)) 1316 { 1317 g_heightMap[indices[i]]->setLineContourColor(r, g, b); 1318 } 1319 } 1320 1321 return TCL_OK; 1322 } 1323 } 1324 else if (c == 't' && (strcmp(argv[1], "transfunc") == 0)) 1325 { 1326 TransferFunction *tf = get_transfunc((char*)argv[2]); 1327 if (tf == NULL) { 1328 Tcl_AppendResult(interp, "transfer function \"", argv[3], 1329 "\" is not defined", (char*)NULL); 1330 return TCL_ERROR; 1331 } 1332 1333 vector<int> indices; 1334 if (GetVolumeIndices(interp, argc - 3, argv + 3, &indices) != TCL_OK) 1335 { 1336 for (int i = 0; i < indices.size(); ++i) 1337 { 1338 if ((indices[i] < g_heightMap.size()) && (g_heightMap[indices[i]] != NULL)) 1339 { 1340 g_heightMap[indices[i]]->setColorMap(tf); 1341 } 1342 } 1343 } 1344 return TCL_OK; 1345 } 1346 1347 Tcl_AppendResult(interp, "bad option \"", argv[1], 1348 "\": should be data, outline, shading, or state", (char*)NULL); 1349 return TCL_ERROR; 1350 } 1351 1352 int GridCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])) 1353 { 1354 char c = *argv[1]; 1355 if (c == 'v' && strcmp(argv[1],"visible") == 0) 1356 { 1357 if (strcmp(argv[2],"true") == 0) 1358 { 1359 g_grid->setVisible(true); 1360 return TCL_OK; 1361 } 1362 else if (strcmp(argv[2],"false") == 0) 1363 { 1364 g_grid->setVisible(false); 1365 return TCL_OK; 1366 } 1367 } 1368 else if (c == 'l' && strcmp(argv[1],"linecount") == 0) 1369 { 1370 int x, y, z; 1371 1372 if ((Tcl_GetInt(interp, argv[2], &x) == TCL_OK) && 1373 (Tcl_GetInt(interp, argv[3], &y) == TCL_OK) && 1374 (Tcl_GetInt(interp, argv[4], &z) == TCL_OK)) { 1375 1376 if (g_grid) g_grid->setGridLineCount(x, y, z); 1377 1378 return TCL_OK; 1379 } 1380 } 1381 else if (c == 'a' && strcmp(argv[1],"axiscolor") == 0) 1382 { 1383 int r, g, b; 1384 if ((Tcl_GetInt(interp, argv[2], &r) == TCL_OK) && 1385 (Tcl_GetInt(interp, argv[3], &g) == TCL_OK) && 1386 (Tcl_GetInt(interp, argv[4], &b) == TCL_OK)) { 1387 1388 if (g_grid) g_grid->setAxisColor(r / 255.0f, g / 255.0f, b / 255.0f); 1389 return TCL_OK; 1390 } 1391 } 1392 else if (c == 'l' && strcmp(argv[1],"linecolor") == 0) 1393 { 1394 int r, g, b; 1395 if ((Tcl_GetInt(interp, argv[2], &r) == TCL_OK) && 1396 (Tcl_GetInt(interp, argv[3], &g) == TCL_OK) && 1397 (Tcl_GetInt(interp, argv[4], &b) == TCL_OK)) { 1398 1399 if (g_grid) g_grid->setGridLineColor(r / 255.0f, g / 255.0f, b / 255.0f); 1400 return TCL_OK; 1401 } 1402 } 1403 else if (c == 'm') 1404 { 1405 if (strcmp(argv[1],"minmax") == 0) 1406 { 1407 double x1, y1, z1, x2, y2, z2; 1408 if ((Tcl_GetDouble(interp, argv[2], &x1) == TCL_OK) && 1409 (Tcl_GetDouble(interp, argv[3], &y1) == TCL_OK) && 1410 (Tcl_GetDouble(interp, argv[4], &z1) == TCL_OK) && 1411 (Tcl_GetDouble(interp, argv[5], &x2) == TCL_OK) && 1412 (Tcl_GetDouble(interp, argv[6], &y2) == TCL_OK) && 1413 (Tcl_GetDouble(interp, argv[7], &z2) == TCL_OK)) { 1414 1415 if (g_grid) g_grid->setMinMax(Vector3(x1, y1, z1), Vector3(x2, y2, z2)); 1416 1417 return TCL_OK; 1418 } 1419 } 1420 } 1421 else if (c == 'a' && strcmp(argv[1],"axisname") == 0) 1422 { 1423 int axisID = 0; 1424 if (!strcmp(argv[2], "x")) axisID = 0; 1425 if (!strcmp(argv[2], "y")) axisID = 1; 1426 if (!strcmp(argv[2], "z")) axisID = 2; 1427 1428 if (g_grid) g_grid->setAxisName(axisID, argv[3]); 1429 return TCL_OK; 1430 } 1431 1432 Tcl_AppendResult(interp, "bad option \"", argv[1], 1433 "\": should be data, outline, shading, or state", (char*)NULL); 1434 return TCL_ERROR; 1435 } 1436 1437 int AxisCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])) 1438 { 1439 if (argc < 2) { 1440 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1441 " option arg arg...\"", (char*)NULL); 1442 return TCL_ERROR; 1443 } 1444 1445 char c = *argv[1]; 1446 if (c == 'v' && strcmp(argv[1],"visible") == 0) 1447 { 1448 if (strcmp(argv[2],"true") == 0) 1449 { 1450 axis_on = true; 1451 } 1452 else if (strcmp(argv[2],"false") == 0) 1453 { 1454 axis_on = false; 1455 } 1456 1457 return TCL_OK; 1458 } 1459 1460 Tcl_AppendResult(interp, "bad option \"", argv[1], 1461 "\": should be data, outline, shading, or state", (char*)NULL); 1462 return TCL_ERROR; 1463 } 1464 1465 /* 1466 * ---------------------------------------------------------------------- 1467 * FUNCTION: GetVolumeIndices() 1468 * 1469 * Used internally to decode a series of volume index values and 1470 * store then in the specified vector. If there are no volume index 1471 * arguments, this means "all volumes" to most commands, so all 1472 * active volume indices are stored in the vector. 1473 * 1474 * Updates pushes index values into the vector. Returns TCL_OK or 1475 * TCL_ERROR to indicate an error. 1476 * ---------------------------------------------------------------------- 1477 */ 1478 static int 1479 GetVolumeIndices(Tcl_Interp *interp, int argc, CONST84 char *argv[], 1480 vector<int>* vectorPtr) 1481 { 1482 if (argc == 0) { 1483 for (int n=0; n < volume.size(); n++) { 1484 if (volume[n] != NULL) { 1485 vectorPtr->push_back(n); 1486 } 1487 } 1488 } else { 1489 int ivol; 1490 for (int n=0; n < argc; n++) { 1491 if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) { 1492 return TCL_ERROR; 1493 } 1494 if (ivol < 0 || ivol >= volume.size()) { 1495 Tcl_AppendResult(interp, "bad volume index \"", argv[n], 1496 "\"", (char*)NULL); 1497 return TCL_ERROR; 1498 } 1499 if (volume[ivol] != NULL) { 1500 vectorPtr->push_back(ivol); 1501 } 1502 } 1503 } 1504 return TCL_OK; 1505 } 1506 1507 static int 1508 GetIndices(Tcl_Interp *interp, int argc, CONST84 char *argv[], 1509 vector<int>* vectorPtr) 1510 { 1511 int ivol; 1512 for (int n=0; n < argc; n++) 1513 { 1514 if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) { 1515 return TCL_ERROR; 1516 } 1517 vectorPtr->push_back(ivol); 1518 } 1519 return TCL_OK; 1520 } 1521 1522 /* 1523 * ---------------------------------------------------------------------- 1524 * FUNCTION: GetAxis() 1525 * 1526 * Used internally to decode an axis value from a string ("x", "y", 1527 * or "z") to its index (0, 1, or 2). Returns TCL_OK if successful, 1528 * along with a value in valPtr. Otherwise, it returns TCL_ERROR 1529 * and an error message in the interpreter. 1530 * ---------------------------------------------------------------------- 1531 */ 1532 static int 1533 GetAxis(Tcl_Interp *interp, char *str, int *valPtr) 1534 { 1535 if (strcmp(str,"x") == 0) { 1536 *valPtr = 0; 1537 return TCL_OK; 1538 } 1539 else if (strcmp(str,"y") == 0) { 1540 *valPtr = 1; 1541 return TCL_OK; 1542 } 1543 else if (strcmp(str,"z") == 0) { 1544 *valPtr = 2; 1545 return TCL_OK; 1546 } 1547 Tcl_AppendResult(interp, "bad axis \"", str, 1548 "\": should be x, y, or z", (char*)NULL); 1549 return TCL_ERROR; 1550 } 1551 1552 /* 1553 * ---------------------------------------------------------------------- 1554 * FUNCTION: GetColor() 1555 * 1556 * Used internally to decode a color value from a string ("R G B") 1557 * as a list of three numbers 0-1. Returns TCL_OK if successful, 1558 * along with RGB values in valPtr. Otherwise, it returns TCL_ERROR 1559 * and an error message in the interpreter. 1560 * ---------------------------------------------------------------------- 1561 */ 1562 static int 1563 GetColor(Tcl_Interp *interp, char *str, float *rgbPtr) 1564 { 1565 int rgbc; 1566 char **rgbv; 1567 if (Tcl_SplitList(interp, str, &rgbc, (const char***)&rgbv) != TCL_OK) { 1568 return TCL_ERROR; 1569 } 1570 if (rgbc != 3) { 1571 Tcl_AppendResult(interp, "bad color \"", str, 1572 "\": should be {R G B} as double values 0-1", (char*)NULL); 1573 return TCL_ERROR; 1574 } 1575 1576 double rval, gval, bval; 1577 if (Tcl_GetDouble(interp, rgbv[0], &rval) != TCL_OK) { 1578 Tcl_Free((char*)rgbv); 1579 return TCL_ERROR; 1580 } 1581 if (Tcl_GetDouble(interp, rgbv[1], &gval) != TCL_OK) { 1582 Tcl_Free((char*)rgbv); 1583 return TCL_ERROR; 1584 } 1585 if (Tcl_GetDouble(interp, rgbv[2], &bval) != TCL_OK) { 1586 Tcl_Free((char*)rgbv); 1587 return TCL_ERROR; 1588 } 1589 Tcl_Free((char*)rgbv); 1590 1591 rgbPtr[0] = (float)rval; 1592 rgbPtr[1] = (float)gval; 1593 rgbPtr[2] = (float)bval; 1594 1595 return TCL_OK; 1596 } 239 1597 240 1598 241 /* … … 1634 277 sprintf(buffer, str, v1, v2, v3); 1635 278 write(0, buffer, strlen(buffer)); 1636 }1637 1638 1639 static int1640 PlaneNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])){1641 fprintf(stderr, "load plane for 2D visualization command\n");1642 1643 int index, w, h;1644 1645 if (argc != 4) {1646 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],1647 " plane_index w h \"", (char*)NULL);1648 return TCL_ERROR;1649 }1650 if (Tcl_GetInt(interp, argv[1], &index) != TCL_OK) {1651 return TCL_ERROR;1652 }1653 if (Tcl_GetInt(interp, argv[2], &w) != TCL_OK) {1654 return TCL_ERROR;1655 }1656 if (Tcl_GetInt(interp, argv[3], &h) != TCL_OK) {1657 return TCL_ERROR;1658 }1659 1660 //Now read w*h*4 bytes. The server expects the plane to be a stream of floats1661 char* tmp = new char[int(w*h*sizeof(float))];1662 bzero(tmp, w*h*4);1663 int status = read(0, tmp, w*h*sizeof(float));1664 if (status <= 0){1665 exit(0);1666 }1667 1668 plane[index] = new Texture2D(w, h, GL_FLOAT, GL_LINEAR, 1, (float*)tmp);1669 1670 delete[] tmp;1671 return TCL_OK;1672 }1673 1674 1675 static1676 int PlaneLinkCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])){1677 fprintf(stderr, "link the plane to the 2D renderer command\n");1678 1679 int plane_index, tf_index;1680 1681 if (argc != 3) {1682 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],1683 " plane_index tf_index \"", (char*)NULL);1684 return TCL_ERROR;1685 }1686 if (Tcl_GetInt(interp, argv[1], &plane_index) != TCL_OK) {1687 return TCL_ERROR;1688 }1689 if (Tcl_GetInt(interp, argv[2], &tf_index) != TCL_OK) {1690 return TCL_ERROR;1691 }1692 1693 //plane_render->add_plane(plane[plane_index], tf[tf_index]);1694 1695 return TCL_OK;1696 }1697 1698 1699 //Enable a 2D plane for render1700 //The plane_index is the index mantained in the 2D plane renderer1701 static1702 int PlaneEnableCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])){1703 fprintf(stderr, "enable a plane so the 2D renderer can render it command\n");1704 1705 int plane_index, mode;1706 1707 if (argc != 3) {1708 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],1709 " plane_index mode \"", (char*)NULL);1710 return TCL_ERROR;1711 }1712 if (Tcl_GetInt(interp, argv[1], &plane_index) != TCL_OK) {1713 return TCL_ERROR;1714 }1715 if (Tcl_GetInt(interp, argv[2], &mode) != TCL_OK) {1716 return TCL_ERROR;1717 }1718 1719 if(mode==0)1720 plane_render->set_active_plane(-1);1721 else1722 plane_render->set_active_plane(plane_index);1723 1724 return TCL_OK;1725 279 } 1726 280 … … 2708 1262 } 2709 1263 1264 1265 int renderLegend(int ivol, int width, int height, const char* volArg) 1266 { 1267 TransferFunction *tf = NULL; 1268 1269 if (ivol < n_volumes) { 1270 tf = g_vol_render->get_volume_shading(volume[ivol]); 1271 } 1272 1273 if (tf == NULL) { 1274 return TCL_ERROR; 1275 } 1276 1277 int old_width = win_width; 1278 int old_height = win_height; 1279 1280 plane_render->set_screen_size(width, height); 1281 resize_offscreen_buffer(width, height); 1282 1283 // generate data for the legend 1284 float data[512]; 1285 for (int i=0; i < 256; i++) { 1286 data[i] = data[i+256] = (float)(i/255.0); 1287 } 1288 plane[0] = new Texture2D(256, 2, GL_FLOAT, GL_LINEAR, 1, data); 1289 int index = plane_render->add_plane(plane[0], tf); 1290 plane_render->set_active_plane(index); 1291 1292 offscreen_buffer_capture(); 1293 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear screen 1294 plane_render->render(); 1295 1296 // INSOO 1297 glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, screen_buffer); 1298 //glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, screen_buffer); // INSOO's 1299 1300 std::ostringstream result; 1301 result << "nv>legend " << volArg; 1302 result << " " << volume[ivol]->range_min(); 1303 result << " " << volume[ivol]->range_max(); 1304 bmp_write(result.str().c_str()); 1305 write(0, "\n", 1); 1306 1307 plane_render->remove_plane(index); 1308 resize_offscreen_buffer(old_width, old_height); 1309 1310 return TCL_OK; 1311 } 2710 1312 2711 1313 //initialize frame buffer objects for offscreen rendering … … 2942 1544 } 2943 1545 2944 2945 2946 void initTcl()2947 {2948 interp = Tcl_CreateInterp();2949 Tcl_MakeSafe(interp);2950 2951 Tcl_DStringInit(&cmdbuffer);2952 2953 // manipulate the viewpoint2954 Tcl_CreateCommand(interp, "camera", CameraCmd,2955 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2956 2957 // turn on/off cut planes in x/y/z directions2958 Tcl_CreateCommand(interp, "cutplane", CutplaneCmd,2959 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2960 2961 // request the legend for a plot (transfer function)2962 Tcl_CreateCommand(interp, "legend", LegendCmd,2963 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2964 2965 // change the size of the screen (size of picture generated)2966 Tcl_CreateCommand(interp, "screen", ScreenCmd,2967 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2968 2969 // manipulate transfer functions2970 Tcl_CreateCommand(interp, "transfunc", TransfuncCmd,2971 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2972 2973 // set the "up" direction for volumes2974 Tcl_CreateCommand(interp, "up", UpCmd,2975 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2976 2977 // manipulate volume data2978 Tcl_CreateCommand(interp, "volume", VolumeCmd,2979 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2980 2981 Tcl_CreateCommand(interp, "axis", AxisCmd,2982 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2983 2984 Tcl_CreateCommand(interp, "grid", GridCmd,2985 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2986 2987 Tcl_CreateCommand(interp, "heightmap", HeightMapCmd,2988 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2989 2990 // get screenshot2991 Tcl_CreateCommand(interp, "screenshot", ScreenShotCmd,2992 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2993 2994 #ifdef __TEST_CODE__2995 Tcl_CreateCommand(interp, "test", TestCmd,2996 (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);2997 #endif2998 2999 // create a default transfer function3000 if (Tcl_Eval(interp, def_transfunc) != TCL_OK) {3001 fprintf(stdin, "WARNING: bad default transfer function\n");3002 fprintf(stdin, Tcl_GetStringResult(interp));3003 }3004 }3005 3006 3007 1546 void read_screen() 3008 1547 { … … 3207 1746 } 3208 1747 3209 3210 void xinetd_listen(){3211 3212 int flags = fcntl(0, F_GETFL, 0);3213 fcntl(0, F_SETFL, flags & ~O_NONBLOCK);3214 3215 int status = TCL_OK;3216 int npass = 0;3217 3218 //3219 // Read and execute as many commands as we can from stdin...3220 //3221 while (status == TCL_OK) {3222 //3223 // Read the next command from the buffer. First time through3224 // we block here and wait if necessary until a command comes in.3225 //3226 // BE CAREFUL: Read only one command, up to a newline.3227 // The "volume data follows" command needs to be able to read3228 // the data immediately following the command, and we shouldn't3229 // consume it here.3230 //3231 while (1) {3232 char c = getchar();3233 if (c <= 0) {3234 if (npass == 0) {3235 exit(0); // EOF -- we're done!3236 } else {3237 break;3238 }3239 }3240 Tcl_DStringAppend(&cmdbuffer, &c, 1);3241 3242 if (c=='\n' && Tcl_CommandComplete(Tcl_DStringValue(&cmdbuffer))) {3243 break;3244 }3245 }3246 3247 // no command? then we're done for now3248 if (Tcl_DStringLength(&cmdbuffer) == 0) {3249 break;3250 }3251 3252 // back to original flags during command evaluation...3253 fcntl(0, F_SETFL, flags & ~O_NONBLOCK);3254 3255 status = Tcl_Eval(interp, Tcl_DStringValue(&cmdbuffer));3256 Tcl_DStringSetLength(&cmdbuffer, 0);3257 3258 // non-blocking for next read -- we might not get anything3259 fcntl(0, F_SETFL, flags | O_NONBLOCK);3260 npass++;3261 }3262 fcntl(0, F_SETFL, flags);3263 3264 if (status != TCL_OK) {3265 std::ostringstream errmsg;3266 errmsg << "ERROR: " << Tcl_GetStringResult(interp) << std::endl;3267 write(0, errmsg.str().c_str(), errmsg.str().size());3268 return;3269 }3270 3271 //3272 // Generate the latest frame and send it back to the client3273 //3274 // INSOO3275 offscreen_buffer_capture(); //enable offscreen render3276 3277 display();3278 3279 // INSOO3280 #ifdef XINETD3281 read_screen();3282 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);3283 #else3284 display_offscreen_buffer(); //display the final rendering on screen3285 read_screen();3286 glutSwapBuffers();3287 #endif3288 3289 #if DO_RLE3290 do_rle();3291 int sizes[2] = { offsets_size*sizeof(offsets[0]), rle_size };3292 fprintf(stderr, "Writing %d,%d\n", sizes[0], sizes[1]); fflush(stderr);3293 write(0, &sizes, sizeof(sizes));3294 write(0, offsets, offsets_size*sizeof(offsets[0]));3295 write(0, rle, rle_size); //unsigned byte3296 #else3297 bmp_write("nv>image -bytes");3298 #endif3299 }3300 3301 3302 1748 /* 3303 1749 //draw vectors … … 3337 1783 3338 1784 #ifdef XINETD 1785 // in Command.cpp 3339 1786 xinetd_listen(); 3340 1787 #else -
trunk/vizservers/nanovis/nanovis.h
r457 r829 13 13 * ====================================================================== 14 14 */ 15 #ifndef __NANOVIS_H__ 16 #define __NANOVIS_H__ 15 17 16 18 #include <GL/glew.h> … … 24 26 #include <assert.h> 25 27 #include <float.h> 28 #include <getopt.h> 29 #include <stdio.h> 30 #include <math.h> 31 #include <fstream> 32 #include <sstream> 33 #include <string> 34 #include <sys/time.h> 35 #include <sys/types.h> 36 #include <unistd.h> 37 #include <fcntl.h> 38 #include <signal.h> 26 39 27 40 #include "define.h" … … 87 100 88 101 102 /* 89 103 //variables for mouse events 90 104 float live_rot_x = 90.; //object rotation angles … … 120 134 //currently active shader, default renders one volume only 121 135 int cur_shader = 0; 136 */ 137 138 #endif
Note: See TracChangeset
for help on using the changeset viewer.