Changeset 1899 for trunk/packages/vizservers/nanovis/FlowCmd.cpp
- Timestamp:
- Aug 31, 2010, 8:29:13 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/packages/vizservers/nanovis/FlowCmd.cpp
r1850 r1899 4 4 #include <stddef.h> 5 5 #include <limits.h> 6 #include <stdint.h> 6 7 #include <poll.h> 7 8 #include <tcl.h> … … 55 56 Rappture::SwitchSpec FlowCmd::_switches[] = { 56 57 {Rappture::SWITCH_BOOLEAN, "-arrows", "boolean", 57 58 offsetof(FlowValues, showArrows), 0}, 58 59 {Rappture::SWITCH_CUSTOM, "-axis", "axis", 59 60 offsetof(FlowValues, slicePos.axis), 0, 0, &axisSwitch}, 60 61 {Rappture::SWITCH_FLOAT, "-diffuse", "value", 61 62 offsetof(FlowValues, diffuse), 0}, 62 63 {Rappture::SWITCH_BOOLEAN, "-hide", "boolean", 63 64 offsetof(FlowValues, isHidden), 0}, 64 65 {Rappture::SWITCH_FLOAT, "-opacity", "value", 65 66 offsetof(FlowValues, opacity), 0}, 66 67 {Rappture::SWITCH_BOOLEAN, "-outline", "boolean", 67 68 offsetof(FlowValues, showOutline), 0}, 68 69 {Rappture::SWITCH_CUSTOM, "-position", "number", 69 70 offsetof(FlowValues, slicePos), 0, 0, &positionSwitch}, 70 71 {Rappture::SWITCH_BOOLEAN, "-slice", "boolean", 71 72 offsetof(FlowValues, sliceVisible), 0}, 72 73 {Rappture::SWITCH_FLOAT, "-specular", "value", 73 74 offsetof(FlowValues, specular), 0}, 74 75 {Rappture::SWITCH_CUSTOM, "-transferfunction", "name", 75 76 offsetof(FlowValues, tfPtr), 0, 0, &transferFunctionSwitch}, 76 77 {Rappture::SWITCH_BOOLEAN, "-volume", "boolean", 77 78 offsetof(FlowValues, showVolume), 0}, 78 79 {Rappture::SWITCH_END} 79 80 }; … … 87 88 offsetof(FlowParticlesValues, isHidden), 0}, 88 89 {Rappture::SWITCH_CUSTOM, "-position", "number", 89 90 offsetof(FlowParticlesValues, position), 0, 0, &positionSwitch}, 90 91 {Rappture::SWITCH_FLOAT, "-size", "float", 91 92 offsetof(FlowParticlesValues, particleSize), 0}, … … 118 119 _hashPtr = hPtr; 119 120 _sv.isHidden = false; 120 _sv.position.axis = 0; 121 _sv.position.value = 0.0f; 121 _sv.position.axis = 0; /* X_AXIS */ 122 _sv.position.value = 0.0f; 122 123 _sv.position.flags = RELPOS; 123 124 _sv.color.r = _sv.color.b = _sv.color.g = _sv.color.a = 1.0f; 124 125 _rendererPtr = new NvParticleRenderer(NMESH, NMESH, 125 126 /* Global nVidia Cg context */g_context); 126 127 } 127 128 … … 129 130 { 130 131 if (_rendererPtr != NULL) { 131 132 delete _rendererPtr; 132 133 } 133 134 if (_hashPtr != NULL) { 134 135 Tcl_DeleteHashEntry(_hashPtr); 135 136 } 136 137 Rappture::FreeSwitches(_switches, &_sv, 0); … … 144 145 Trace("rendering particles %s position=%g\n", _name, _sv.position.value); 145 146 Trace("rendering particles %s position=%g\n", _name, 146 147 FlowCmd::GetRelativePosition(&_sv.position)); 147 148 148 149 _rendererPtr->setPos(FlowCmd::GetRelativePosition(&_sv.position)); … … 157 158 _rendererPtr->setPos(FlowCmd::GetRelativePosition(&_sv.position)); 158 159 _rendererPtr->setColor(Vector4(_sv.color.r, _sv.color.g, _sv.color.b, 159 160 _sv.color.a)); 160 161 _rendererPtr->particleSize(_sv.particleSize); 161 162 _rendererPtr->setAxis(_sv.position.axis); … … 168 169 _hashPtr = hPtr; 169 170 _sv.isHidden = false; 170 _sv.corner1.x = 0.0f; 171 _sv.corner1.y = 0.0f; 172 _sv.corner1.z = 0.0f; 173 _sv.corner2.x = 1.0f; 174 _sv.corner2.y = 1.0f; 175 _sv.corner2.z = 1.0f; 171 _sv.corner1.x = 0.0f; 172 _sv.corner1.y = 0.0f; 173 _sv.corner1.z = 0.0f; 174 _sv.corner2.x = 1.0f; 175 _sv.corner2.y = 1.0f; 176 _sv.corner2.z = 1.0f; 176 177 _sv.lineWidth = 1.2f; 177 178 _sv.color.r = _sv.color.b = _sv.color.g = _sv.color.a = 1.0f; … … 199 200 sy = volPtr->height / (double)volPtr->width; 200 201 if (volPtr->depth > 0.0) { 201 202 sz = volPtr->depth / (double)volPtr->width; 202 203 } 203 204 glScaled(sx, sy, sz); … … 209 210 210 211 Trace("box is %g,%g %g,%g %g,%g\n", 211 212 213 212 _sv.corner1.x, _sv.corner2.x, 213 _sv.corner1.y, _sv.corner2.y, 214 _sv.corner1.z, _sv.corner2.z); 214 215 Trace("world is %g,%g %g,%g %g,%g\n", 215 216 min.x, max.x, min.y, max.y, min.z, max.z); 216 217 217 218 float x0, y0, z0, x1, y1, z1; … … 219 220 x1 = y1 = z1 = 0.0f; 220 221 if (max.y > min.y) { 221 222 222 y0 = (_sv.corner1.y - min.y) / (max.y - min.y); 223 y1 = (_sv.corner2.y - min.y) / (max.y - min.y); 223 224 } 224 225 if (max.z > min.z) { 225 226 226 z0 = (_sv.corner1.z - min.z) / (max.z - min.z); 227 z1 = (_sv.corner2.z - min.z) / (max.z - min.z); 227 228 } 228 229 if (max.x > min.x) { 229 230 230 x0 = (_sv.corner1.x - min.x) / (max.x - min.x); 231 x1 = (_sv.corner2.x - min.x) / (max.x - min.x); 231 232 } 232 233 Trace("rendering box %g,%g %g,%g %g,%g\n", x0, x1, y0, y1, z0, z1); … … 235 236 glBegin(GL_LINE_LOOP); 236 237 { 237 238 239 240 238 glVertex3d(x0, y0, z0); 239 glVertex3d(x1, y0, z0); 240 glVertex3d(x1, y1, z0); 241 glVertex3d(x0, y1, z0); 241 242 } 242 243 glEnd(); 243 244 glBegin(GL_LINE_LOOP); 244 245 { 245 246 247 248 246 glVertex3d(x0, y0, z1); 247 glVertex3d(x1, y0, z1); 248 glVertex3d(x1, y1, z1); 249 glVertex3d(x0, y1, z1); 249 250 } 250 251 glEnd(); … … 252 253 glBegin(GL_LINE_LOOP); 253 254 { 254 255 256 257 255 glVertex3d(x0, y0, z0); 256 glVertex3d(x0, y0, z1); 257 glVertex3d(x0, y1, z1); 258 glVertex3d(x0, y1, z0); 258 259 } 259 260 glEnd(); … … 261 262 glBegin(GL_LINE_LOOP); 262 263 { 263 264 265 266 264 glVertex3d(x1, y0, z0); 265 glVertex3d(x1, y0, z1); 266 glVertex3d(x1, y1, z1); 267 glVertex3d(x1, y1, z0); 267 268 } 268 269 glEnd(); … … 290 291 _volPtr = NULL; 291 292 _cmdToken = Tcl_CreateObjCommand(interp, (char *)_name, 292 293 (Tcl_ObjCmdProc *)FlowInstObjCmd, this, FlowInstDeleteProc); 293 294 Tcl_InitHashTable(&_particlesTable, TCL_STRING_KEYS); 294 295 Tcl_InitHashTable(&_boxTable, TCL_STRING_KEYS); … … 299 300 Rappture::FreeSwitches(_switches, &_sv, 0); 300 301 if (_hashPtr != NULL) { 301 302 Tcl_DeleteHashEntry(_hashPtr); 302 303 } 303 304 if (_fieldPtr != NULL) { 304 305 delete _fieldPtr; 305 306 } 306 307 if (_dataPtr != NULL) { 307 308 delete _dataPtr; 308 309 } 309 310 if (_volPtr != NULL) { 310 311 311 NanoVis::remove_volume(_volPtr); 312 _volPtr = NULL; 312 313 } 313 314 … … 315 316 FlowBoxIterator boxIter; 316 317 for (boxPtr = FirstBox(&boxIter); boxPtr != NULL; 317 318 319 320 } 318 boxPtr = NextBox(&boxIter)) { 319 boxPtr->disconnect(); 320 delete boxPtr; 321 } 321 322 FlowParticles *particlesPtr; 322 323 FlowParticlesIterator partIter; 323 324 for (particlesPtr = FirstParticles(&partIter); particlesPtr != NULL; 324 325 326 327 } 325 particlesPtr = NextParticles(&partIter)) { 326 particlesPtr->disconnect(); 327 delete particlesPtr; 328 } 328 329 Tcl_DeleteHashTable(&_particlesTable); 329 330 Tcl_DeleteHashTable(&_boxTable); … … 336 337 FlowParticles *particlesPtr; 337 338 for (particlesPtr = FirstParticles(&iter); particlesPtr != NULL; 338 339 339 particlesPtr = NextParticles(&iter)) { 340 particlesPtr->Reset(); 340 341 } 341 342 } … … 350 351 FlowParticles *particlesPtr; 351 352 for (particlesPtr = FirstParticles(&iter); particlesPtr != NULL; 352 353 354 355 353 particlesPtr = NextParticles(&iter)) { 354 if (particlesPtr->visible()) { 355 particlesPtr->Advect(); 356 } 356 357 } 357 358 } … … 365 366 FlowParticles *particlesPtr; 366 367 for (particlesPtr = FirstParticles(&iter); particlesPtr != NULL; 367 368 369 370 368 particlesPtr = NextParticles(&iter)) { 369 if (particlesPtr->visible()) { 370 particlesPtr->Render(); 371 } 371 372 } 372 373 Trace("in Render before boxes %s\n", _name); … … 382 383 hPtr = Tcl_CreateHashEntry(&_particlesTable, particlesName, &isNew); 383 384 if (!isNew) { 384 385 386 385 Tcl_AppendResult(interp, "particle injection plane \"", 386 particlesName, "\" already exists.", (char *)NULL); 387 return TCL_ERROR; 387 388 } 388 389 particlesName = Tcl_GetHashKey(&_particlesTable, hPtr); … … 390 391 particlesPtr = new FlowParticles(particlesName, hPtr); 391 392 if (particlesPtr == NULL) { 392 393 394 395 393 Tcl_AppendResult(interp, "can't allocate particle injection plane", 394 (char *)NULL); 395 Tcl_DeleteHashEntry(hPtr); 396 return TCL_ERROR; 396 397 } 397 398 Tcl_SetHashValue(hPtr, particlesPtr); … … 401 402 int 402 403 FlowCmd::GetParticles(Tcl_Interp *interp, Tcl_Obj *objPtr, 403 404 FlowParticles **particlesPtrPtr) 404 405 { 405 406 Tcl_HashEntry *hPtr; 406 407 hPtr = Tcl_FindHashEntry(&_particlesTable, Tcl_GetString(objPtr)); 407 408 if (hPtr == NULL) { 408 409 410 411 412 409 if (interp != NULL) { 410 Tcl_AppendResult(interp, "can't find a particle injection plane \"", 411 Tcl_GetString(objPtr), "\"", (char *)NULL); 412 } 413 return TCL_ERROR; 413 414 } 414 415 *particlesPtrPtr = (FlowParticles *)Tcl_GetHashValue(hPtr); … … 420 421 { 421 422 iterPtr->hashPtr = Tcl_FirstHashEntry(&_particlesTable, 422 423 &iterPtr->hashSearch); 423 424 if (iterPtr->hashPtr == NULL) { 424 425 return NULL; 425 426 } 426 427 return (FlowParticles *)Tcl_GetHashValue(iterPtr->hashPtr); … … 431 432 { 432 433 if (iterPtr->hashPtr == NULL) { 433 434 return NULL; 434 435 } 435 436 iterPtr->hashPtr = Tcl_NextHashEntry(&iterPtr->hashSearch); 436 437 if (iterPtr->hashPtr == NULL) { 437 438 return NULL; 438 439 } 439 440 return (FlowParticles *)Tcl_GetHashValue(iterPtr->hashPtr); … … 447 448 hPtr = Tcl_CreateHashEntry(&_boxTable, Tcl_GetString(objPtr), &isNew); 448 449 if (!isNew) { 449 450 451 450 Tcl_AppendResult(interp, "box \"", Tcl_GetString(objPtr), 451 "\" already exists in flow \"", name(), "\"", (char *)NULL); 452 return TCL_ERROR; 452 453 } 453 454 const char *boxName; … … 456 457 boxPtr = new FlowBox(boxName, hPtr); 457 458 if (boxPtr == NULL) { 458 459 460 461 459 Tcl_AppendResult(interp, "can't allocate box \"", boxName, "\"", 460 (char *)NULL); 461 Tcl_DeleteHashEntry(hPtr); 462 return TCL_ERROR; 462 463 } 463 464 Tcl_SetHashValue(hPtr, boxPtr); … … 471 472 hPtr = Tcl_FindHashEntry(&_boxTable, Tcl_GetString(objPtr)); 472 473 if (hPtr == NULL) { 473 474 475 476 477 478 474 if (interp != NULL) { 475 Tcl_AppendResult(interp, "can't find a box \"", 476 Tcl_GetString(objPtr), "\" in flow \"", name(), "\"", 477 (char *)NULL); 478 } 479 return TCL_ERROR; 479 480 } 480 481 *boxPtrPtr = (FlowBox *)Tcl_GetHashValue(hPtr); … … 487 488 iterPtr->hashPtr = Tcl_FirstHashEntry(&_boxTable, &iterPtr->hashSearch); 488 489 if (iterPtr->hashPtr == NULL) { 489 490 return NULL; 490 491 } 491 492 return (FlowBox *)Tcl_GetHashValue(iterPtr->hashPtr); … … 496 497 { 497 498 if (iterPtr->hashPtr == NULL) { 498 499 return NULL; 499 500 } 500 501 iterPtr->hashPtr = Tcl_NextHashEntry(&iterPtr->hashSearch); 501 502 if (iterPtr->hashPtr == NULL) { 502 503 return NULL; 503 504 } 504 505 return (FlowBox *)Tcl_GetHashValue(iterPtr->hashPtr); … … 512 513 FlowParticlesIterator iter; 513 514 for (particlesPtr = FirstParticles(&iter); particlesPtr != NULL; 514 515 516 } 515 particlesPtr = NextParticles(&iter)) { 516 particlesPtr->Initialize(); 517 } 517 518 } 518 519 … … 521 522 { 522 523 if (_volPtr != NULL) { 523 524 525 524 fprintf(stderr, "from ScaleVectorField volId=%s\n", _volPtr->name()); 525 NanoVis::remove_volume(_volPtr); 526 _volPtr = NULL; 526 527 } 527 528 float *vdata; 528 529 vdata = GetScaledVector(); 529 530 if (vdata == NULL) { 530 531 return false; 531 532 } 532 533 Volume *volPtr; … … 534 535 delete [] vdata; 535 536 if (volPtr == NULL) { 536 537 return false; 537 538 } 538 539 _volPtr = volPtr; … … 540 541 // Remove the associated vector field. 541 542 if (_fieldPtr != NULL) { 542 543 delete _fieldPtr; 543 544 } 544 545 _fieldPtr = new NvVectorField(); 545 546 if (_fieldPtr == NULL) { 546 547 return false; 547 548 } 548 549 … … 559 560 560 561 _fieldPtr->setVectorField(_volPtr, loc, 561 562 1.0f, height / width, depth / width, NanoVis::magMax); 562 563 563 564 if (NanoVis::licRenderer != NULL) { 564 565 NanoVis::licRenderer->setVectorField(_volPtr->id, loc, 565 566 567 568 569 570 571 566 1.0f / _volPtr->aspect_ratio_width, 567 1.0f / _volPtr->aspect_ratio_height, 568 1.0f / _volPtr->aspect_ratio_depth, 569 _volPtr->wAxis.max()); 570 SetCurrentPosition(); 571 SetAxis(); 572 SetActive(); 572 573 } 573 574 … … 576 577 //*(volPtr->get_location()), 577 578 1.0f, 578 579 579 _volPtr->aspect_ratio_height / _volPtr->aspect_ratio_width, 580 _volPtr->aspect_ratio_depth / _volPtr->aspect_ratio_width 580 581 //,volPtr->wAxis.max() 581 582 ); 582 583 584 585 583 Trace("Arrows enabled set to %d\n", _sv.showArrows); 584 NanoVis::velocityArrowsSlice->axis(_sv.slicePos.axis); 585 NanoVis::velocityArrowsSlice->slicePos(_sv.slicePos.value); 586 NanoVis::velocityArrowsSlice->enabled(_sv.showArrows); 586 587 } 587 588 FlowParticles *particlesPtr; 588 589 FlowParticlesIterator partIter; 589 590 for (particlesPtr = FirstParticles(&partIter); particlesPtr != NULL; 590 591 592 } 591 particlesPtr = NextParticles(&partIter)) { 592 particlesPtr->SetVectorField(_volPtr); 593 } 593 594 return true; 594 595 } … … 600 601 FlowBox *boxPtr; 601 602 for (boxPtr = FirstBox(&iter); boxPtr != NULL; boxPtr = NextBox(&iter)) { 602 603 604 605 603 Trace("found box %s\n", boxPtr->name()); 604 if (boxPtr->visible()) { 605 boxPtr->Render(_volPtr); 606 } 606 607 } 607 608 } … … 614 615 float *data = new float[n]; 615 616 if (data == NULL) { 616 617 return NULL; 617 618 } 618 619 memset(data, 0, sizeof(float) * n); … … 620 621 const float *values = _dataPtr->values(); 621 622 for (size_t iz=0; iz < _dataPtr->zNum(); iz++) { 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 623 for (size_t iy=0; iy < _dataPtr->yNum(); iy++) { 624 for (size_t ix=0; ix < _dataPtr->xNum(); ix++) { 625 double vx, vy, vz, vm; 626 vx = values[0]; 627 vy = values[1]; 628 vz = values[2]; 629 vm = sqrt(vx*vx + vy*vy + vz*vz); 630 destPtr[0] = vm / NanoVis::magMax; 631 destPtr[1] = vx /(2.0*NanoVis::magMax) + 0.5; 632 destPtr[2] = vy /(2.0*NanoVis::magMax) + 0.5; 633 destPtr[3] = vz /(2.0*NanoVis::magMax) + 0.5; 634 values += 3; 635 destPtr += 4; 636 } 637 } 637 638 } 638 639 return data; … … 645 646 646 647 volPtr = NanoVis::load_volume(_name, _dataPtr->xNum(), _dataPtr->yNum(), 647 648 648 _dataPtr->zNum(), 4, data, 649 NanoVis::magMin, NanoVis::magMax, 0); 649 650 volPtr->xAxis.SetRange(_dataPtr->xMin(), _dataPtr->xMax()); 650 651 volPtr->yAxis.SetRange(_dataPtr->yMin(), _dataPtr->yMax()); … … 655 656 Vector3 physicalMax(NanoVis::xMax, NanoVis::yMax, NanoVis::zMax); 656 657 Trace("min=%g %g %g max=%g %g %g mag=%g %g\n", 657 658 659 658 NanoVis::xMin, NanoVis::yMin, NanoVis::zMin, 659 NanoVis::xMax, NanoVis::yMax, NanoVis::zMax, 660 NanoVis::magMin, NanoVis::magMax); 660 661 volPtr->setPhysicalBBox(physicalMin, physicalMax); 661 662 //volPtr->set_n_slice(256 - _volIndex); … … 689 690 static int 690 691 FlowDataFileOp(ClientData clientData, Tcl_Interp *interp, int objc, 691 692 Tcl_Obj *const *objv) 692 693 { 693 694 Rappture::Outcome result; … … 702 703 } 703 704 if ((nComponents < 1) || (nComponents > 4)) { 704 705 706 705 Tcl_AppendResult(interp, "bad # of components \"", 706 Tcl_GetString(objv[4]), "\"", (char *)NULL); 707 return TCL_ERROR; 707 708 } 708 709 Rappture::Buffer buf; 709 710 if (!buf.load(result, fileName)) { 710 711 712 711 Tcl_AppendResult(interp, "can't load data from \"", fileName, "\": ", 712 result.remark(), (char *)NULL); 713 return TCL_ERROR; 713 714 } 714 715 … … 719 720 char *bytes = (char *)buf.bytes(); 720 721 if ((length > 4) && (strncmp(bytes, "<DX>", 4) == 0)) { 721 722 723 724 725 722 if (!dataPtr->ImportDx(result, nComponents, length-4, bytes+4)) { 723 Tcl_AppendResult(interp, result.remark(), (char *)NULL); 724 delete dataPtr; 725 return TCL_ERROR; 726 } 726 727 } else if ((length > 10) && (strncmp(bytes, "unirect3d ", 10) == 0)) { 727 728 729 730 728 if (dataPtr->ParseBuffer(interp, buf) != TCL_OK) { 729 delete dataPtr; 730 return TCL_ERROR; 731 } 731 732 } else if ((length > 10) && (strncmp(bytes, "unirect2d ", 10) == 0)) { 732 733 734 735 736 737 738 739 733 Rappture::Unirect2d *u2dPtr; 734 u2dPtr = new Rappture::Unirect2d(nComponents); 735 if (u2dPtr->ParseBuffer(interp, buf) != TCL_OK) { 736 delete u2dPtr; 737 return TCL_ERROR; 738 } 739 dataPtr->Convert(u2dPtr); 740 delete u2dPtr; 740 741 } else { 741 742 743 744 745 746 742 fprintf(stderr, "header is %.14s\n", buf.bytes()); 743 if (!dataPtr->ImportDx(result, nComponents, length, bytes)) { 744 Tcl_AppendResult(interp, result.remark(), (char *)NULL); 745 delete dataPtr; 746 return TCL_ERROR; 747 } 747 748 } 748 749 if (dataPtr->nValues() == 0) { 749 750 751 752 750 delete dataPtr; 751 Tcl_AppendResult(interp, "no data found in \"", fileName, "\"", 752 (char *)NULL); 753 return TCL_ERROR; 753 754 } 754 755 flowPtr->data(dataPtr); … … 770 771 int nBytes; 771 772 if (Tcl_GetIntFromObj(interp, objv[3], &nBytes) != TCL_OK) { 772 773 Trace("Bad nBytes \"%s\"\n", Tcl_GetString(objv[3])); 773 774 return TCL_ERROR; 774 775 } 775 776 if (nBytes <= 0) { 776 777 778 779 777 Tcl_AppendResult(interp, "bad # bytes request \"", 778 Tcl_GetString(objv[3]), "\" for \"data follows\"", (char *)NULL); 779 Trace("Bad nbytes %d\n", nBytes); 780 return TCL_ERROR; 780 781 } 781 782 int nComponents; 782 783 if (Tcl_GetIntFromObj(interp, objv[4], &nComponents) != TCL_OK) { 783 784 Trace("Bad # of components \"%s\"\n", Tcl_GetString(objv[4])); 784 785 return TCL_ERROR; 785 786 } 786 787 if (nComponents <= 0) { 787 788 789 790 788 Tcl_AppendResult(interp, "bad # of components request \"", 789 Tcl_GetString(objv[4]), "\" for \"data follows\"", (char *)NULL); 790 Trace("Bad # of components %d\n", nComponents); 791 return TCL_ERROR; 791 792 } 792 793 Rappture::Buffer buf; … … 802 803 char *bytes = (char *)buf.bytes(); 803 804 if ((length > 4) && (strncmp(bytes, "<DX>", 4) == 0)) { 804 805 806 807 808 805 if (!dataPtr->ImportDx(result, nComponents, length - 4, bytes + 4)) { 806 Tcl_AppendResult(interp, result.remark(), (char *)NULL); 807 delete dataPtr; 808 return TCL_ERROR; 809 } 809 810 } else if ((length > 10) && (strncmp(bytes, "unirect3d ", 10) == 0)) { 810 811 812 813 811 if (dataPtr->ParseBuffer(interp, buf) != TCL_OK) { 812 delete dataPtr; 813 return TCL_ERROR; 814 } 814 815 } else if ((length > 10) && (strncmp(bytes, "unirect2d ", 10) == 0)) { 815 816 817 818 819 820 821 822 816 Rappture::Unirect2d *u2dPtr; 817 u2dPtr = new Rappture::Unirect2d(nComponents); 818 if (u2dPtr->ParseBuffer(interp, buf) != TCL_OK) { 819 delete u2dPtr; 820 return TCL_ERROR; 821 } 822 dataPtr->Convert(u2dPtr); 823 delete u2dPtr; 823 824 } else { 824 825 826 827 828 829 825 fprintf(stderr, "header is %.14s\n", buf.bytes()); 826 if (!dataPtr->ImportDx(result, nComponents, length, bytes)) { 827 Tcl_AppendResult(interp, result.remark(), (char *)NULL); 828 delete dataPtr; 829 return TCL_ERROR; 830 } 830 831 } 831 832 if (dataPtr->nValues() == 0) { 832 833 834 833 delete dataPtr; 834 Tcl_AppendResult(interp, "no data found in stream", (char *)NULL); 835 return TCL_ERROR; 835 836 } 836 837 flowPtr->data(dataPtr); 837 838 { 838 839 char info[1024]; 839 840 840 ssize_t nWritten; 841 size_t length; 841 842 842 843 length = sprintf(info, "nv>data tag %s min %g max %g\n", 843 844 flowPtr->name(), dataPtr->magMin(), dataPtr->magMax()); 844 845 nWritten = write(0, info, length); 845 846 assert(nWritten == (ssize_t)strlen(info)); 846 847 } 847 848 NanoVis::EventuallyRedraw(NanoVis::MAP_FLOWS); … … 857 858 static int 858 859 FlowDataOp(ClientData clientData, Tcl_Interp *interp, int objc, 859 860 Tcl_Obj *const *objv) 860 861 { 861 862 Tcl_ObjCmdProc *proc; … … 873 874 { 874 875 if (posPtr->flags == RELPOS) { 875 876 return posPtr->value; 876 877 } 877 878 switch (posPtr->axis) { 878 879 case AXIS_X: 879 880 880 return (posPtr->value - NanoVis::xMin) / 881 (NanoVis::xMax - NanoVis::xMin); 881 882 case AXIS_Y: 882 883 883 return (posPtr->value - NanoVis::yMin) / 884 (NanoVis::yMax - NanoVis::yMin); 884 885 case AXIS_Z: 885 886 886 return (posPtr->value - NanoVis::zMin) / 887 (NanoVis::zMax - NanoVis::zMin); 887 888 } 888 889 return 0.0; … … 908 909 iterPtr->hashPtr = Tcl_FirstHashEntry(&flowTable, &iterPtr->hashSearch); 909 910 if (iterPtr->hashPtr == NULL) { 910 911 return NULL; 911 912 } 912 913 return (FlowCmd *)Tcl_GetHashValue(iterPtr->hashPtr); … … 917 918 { 918 919 if (iterPtr->hashPtr == NULL) { 919 920 return NULL; 920 921 } 921 922 iterPtr->hashPtr = Tcl_NextHashEntry(&iterPtr->hashSearch); 922 923 if (iterPtr->hashPtr == NULL) { 923 924 return NULL; 924 925 } 925 926 return (FlowCmd *)Tcl_GetHashValue(iterPtr->hashPtr); … … 932 933 hPtr = Tcl_FindHashEntry(&flowTable, Tcl_GetString(objPtr)); 933 934 if (hPtr == NULL) { 934 935 936 937 938 935 if (interp != NULL) { 936 Tcl_AppendResult(interp, "can't find a flow \"", 937 Tcl_GetString(objPtr), "\"", (char *)NULL); 938 } 939 return TCL_ERROR; 939 940 } 940 941 *flowPtrPtr = (FlowCmd *)Tcl_GetHashValue(hPtr); … … 951 952 hPtr = Tcl_CreateHashEntry(&flowTable, name, &isNew); 952 953 if (!isNew) { 953 954 955 954 Tcl_AppendResult(interp, "flow \"", name, "\" already exists.", 955 (char *)NULL); 956 return TCL_ERROR; 956 957 } 957 958 Tcl_CmdInfo cmdInfo; 958 959 if (Tcl_GetCommandInfo(interp, name, &cmdInfo)) { 959 960 961 962 } 960 Tcl_AppendResult(interp, "an another command \"", name, 961 "\" already exists.", (char *)NULL); 962 return TCL_ERROR; 963 } 963 964 FlowCmd *flowPtr; 964 965 name = Tcl_GetHashKey(&flowTable, hPtr); 965 966 flowPtr = new FlowCmd(interp, name, hPtr); 966 967 if (flowPtr == NULL) { 967 968 969 968 Tcl_AppendResult(interp, "can't allocate a flow object \"", name, 969 "\"", (char *)NULL); 970 return TCL_ERROR; 970 971 } 971 972 Tcl_SetHashValue(hPtr, flowPtr); … … 979 980 FlowIterator iter; 980 981 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 981 982 flowPtr->disconnect();/* Don't disrupt the hash walk */983 982 flowPtr = NextFlow(&iter)) { 983 flowPtr->disconnect(); /* Don't disrupt the hash walk */ 984 Tcl_DeleteCommand(interp, flowPtr->name()); 984 985 } 985 986 Tcl_DeleteHashTable(&flowTable); … … 994 995 /* 995 996 * Step 1. Get the overall min and max magnitudes of all the 996 * 997 * flow vectors. 997 998 */ 998 999 magMin = DBL_MAX, magMax = -DBL_MAX; … … 1001 1002 FlowIterator iter; 1002 1003 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1004 flowPtr = NextFlow(&iter)) { 1005 double min, max; 1006 if (!flowPtr->isDataLoaded()) { 1007 continue; 1008 } 1009 Rappture::Unirect3d *dataPtr; 1010 dataPtr = flowPtr->data(); 1011 min = dataPtr->magMin(); 1012 max = dataPtr->magMax(); 1013 if (min < magMin) { 1014 magMin = min; 1015 } 1016 if (max > magMax) { 1017 magMax = max; 1018 } 1019 if (dataPtr->xMin() < xMin) { 1020 xMin = dataPtr->xMin(); 1021 } 1022 if (dataPtr->yMin() < yMin) { 1023 yMin = dataPtr->yMin(); 1024 } 1025 if (dataPtr->zMin() < zMin) { 1026 zMin = dataPtr->zMin(); 1027 } 1028 if (dataPtr->xMax() > xMax) { 1029 xMax = dataPtr->xMax(); 1030 } 1031 if (dataPtr->yMax() > yMax) { 1032 yMax = dataPtr->yMax(); 1033 } 1034 if (dataPtr->zMax() > zMax) { 1035 zMax = dataPtr->zMax(); 1036 } 1036 1037 } 1037 1038 Trace("MapFlows magMin=%g magMax=%g\n", NanoVis::magMin, NanoVis::magMax); … … 1041 1042 */ 1042 1043 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 1043 1044 1045 continue;// Flow exists, but no data has1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1044 flowPtr = NextFlow(&iter)) { 1045 if (!flowPtr->isDataLoaded()) { 1046 continue; // Flow exists, but no data has 1047 // been loaded yet. 1048 } 1049 if (flowPtr->visible()) { 1050 flowPtr->InitializeParticles(); 1051 } 1052 if (!flowPtr->ScaleVectorField()) { 1053 return false; 1054 } 1055 // FIXME: This doesn't work when there is more than one flow. 1056 licRenderer->set_offset(flowPtr->GetRelativePosition()); 1056 1057 NanoVis::velocityArrowsSlice->slicePos(flowPtr->GetRelativePosition()); 1057 1058 … … 1067 1068 FlowIterator iter; 1068 1069 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 1069 1070 1071 1072 1070 flowPtr = NextFlow(&iter)) { 1071 if ((flowPtr->isDataLoaded()) && (flowPtr->visible())) { 1072 flowPtr->Render(); 1073 } 1073 1074 } 1074 1075 flags &= ~REDRAW_PENDING; … … 1082 1083 1083 1084 if (licRenderer->active()) { 1084 1085 NanoVis::licRenderer->reset(); 1085 1086 } 1086 1087 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 1087 1088 1089 1090 1088 flowPtr = NextFlow(&iter)) { 1089 if ((flowPtr->isDataLoaded()) && (flowPtr->visible())) { 1090 flowPtr->ResetParticles(); 1091 } 1091 1092 } 1092 1093 } … … 1098 1099 FlowIterator iter; 1099 1100 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 1100 1101 1102 1103 1101 flowPtr = NextFlow(&iter)) { 1102 if ((flowPtr->isDataLoaded()) && (flowPtr->visible())) { 1103 flowPtr->Advect(); 1104 } 1104 1105 } 1105 1106 } … … 1110 1111 * AxisSwitchProc -- 1111 1112 * 1112 * 1113 * 1113 * Convert a Tcl_Obj representing the label of a child node into its 1114 * integer node id. 1114 1115 * 1115 1116 * Results: 1116 * 1117 * The return value is a standard Tcl result. 1117 1118 * 1118 1119 *--------------------------------------------------------------------------- … … 1121 1122 static int 1122 1123 AxisSwitchProc( 1123 ClientData clientData, 1124 1125 Tcl_Interp *interp, 1126 const char *switchName, 1127 Tcl_Obj *objPtr, 1128 char *record, 1129 int offset, 1130 int flags) 1124 ClientData clientData, /* Flag indicating if the node is considered 1125 * before or after the insertion position. */ 1126 Tcl_Interp *interp, /* Interpreter to send results back to */ 1127 const char *switchName, /* Not used. */ 1128 Tcl_Obj *objPtr, /* String representation */ 1129 char *record, /* Structure record */ 1130 int offset, /* Not used. */ 1131 int flags) /* Not used. */ 1131 1132 { 1132 1133 const char *string = Tcl_GetString(objPtr); 1133 1134 if (string[1] == '\0') { 1134 1135 FlowCmd::SliceAxis *axisPtr = (FlowCmd::SliceAxis *)(record + offset); 1135 1136 char c; 1136 1137 c = tolower((unsigned char)string[0]); … … 1157 1158 * ColorSwitchProc -- 1158 1159 * 1159 * 1160 * 1160 * Convert a Tcl_Obj representing the label of a list of four color 1161 * components in to a RGBA color value. 1161 1162 * 1162 1163 * Results: 1163 * 1164 * The return value is a standard Tcl result. 1164 1165 * 1165 1166 *--------------------------------------------------------------------------- … … 1168 1169 static int 1169 1170 ColorSwitchProc( 1170 ClientData clientData, 1171 1172 Tcl_Interp *interp, 1173 const char *switchName, 1174 Tcl_Obj *objPtr, 1175 char *record, 1176 int offset, 1177 int flags) 1171 ClientData clientData, /* Flag indicating if the node is considered 1172 * before or after the insertion position. */ 1173 Tcl_Interp *interp, /* Interpreter to send results back to */ 1174 const char *switchName, /* Not used. */ 1175 Tcl_Obj *objPtr, /* String representation */ 1176 char *record, /* Structure record */ 1177 int offset, /* Not used. */ 1178 int flags) /* Not used. */ 1178 1179 { 1179 1180 Tcl_Obj **objv; … … 1182 1183 1183 1184 if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { 1184 1185 return TCL_ERROR; 1185 1186 } 1186 1187 if ((objc < 3) || (objc > 4)) { 1187 1188 1189 1188 Tcl_AppendResult(interp, "wrong # of elements in color definition", 1189 (char *)NULL); 1190 return TCL_ERROR; 1190 1191 } 1191 1192 float values[4]; … … 1193 1194 values[3] = 1.0f; 1194 1195 for (i = 0; i < objc; i++) { 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 } 1196 float value; 1197 1198 if (GetFloatFromObj(interp, objv[i], &value) != TCL_OK) { 1199 return TCL_ERROR; 1200 } 1201 if ((value < 0.0) || (value > 1.0)) { 1202 Tcl_AppendResult(interp, "bad component value in \"", 1203 Tcl_GetString(objPtr), "\": color values must be [0..1]", 1204 (char *)NULL); 1205 return TCL_ERROR; 1206 } 1207 values[i] = value; 1208 } 1208 1209 colorPtr->r = values[0]; 1209 1210 colorPtr->g = values[1]; … … 1218 1219 * PointSwitchProc -- 1219 1220 * 1220 * 1221 * 1221 * Convert a Tcl_Obj representing the a 3-D coordinate into 1222 * a point. 1222 1223 * 1223 1224 * Results: 1224 * 1225 * The return value is a standard Tcl result. 1225 1226 * 1226 1227 *--------------------------------------------------------------------------- … … 1229 1230 static int 1230 1231 PointSwitchProc( 1231 ClientData clientData, 1232 1233 Tcl_Interp *interp, 1234 const char *switchName, 1235 Tcl_Obj *objPtr, 1236 char *record, 1237 int offset, 1238 int flags) 1232 ClientData clientData, /* Flag indicating if the node is considered 1233 * before or after the insertion position. */ 1234 Tcl_Interp *interp, /* Interpreter to send results back to */ 1235 const char *switchName, /* Not used. */ 1236 Tcl_Obj *objPtr, /* String representation */ 1237 char *record, /* Structure record */ 1238 int offset, /* Not used. */ 1239 int flags) /* Not used. */ 1239 1240 { 1240 1241 FlowPoint *pointPtr = (FlowPoint *)(record + offset); … … 1243 1244 1244 1245 if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { 1245 1246 return TCL_ERROR; 1246 1247 } 1247 1248 if (objc != 3) { 1248 1249 1250 1249 Tcl_AppendResult(interp, "wrong # of elements for box coordinates: " 1250 " should be \"x y z\"", (char *)NULL); 1251 return TCL_ERROR; 1251 1252 } 1252 1253 float values[3]; 1253 1254 int i; 1254 1255 for (i = 0; i < objc; i++) { 1255 1256 1257 1258 1259 1260 1261 } 1256 float value; 1257 1258 if (GetFloatFromObj(interp, objv[i], &value) != TCL_OK) { 1259 return TCL_ERROR; 1260 } 1261 values[i] = value; 1262 } 1262 1263 pointPtr->x = values[0]; 1263 1264 pointPtr->y = values[1]; … … 1271 1272 * PositionSwitchProc -- 1272 1273 * 1273 * 1274 * 1274 * Convert a Tcl_Obj representing the a 3-D coordinate into 1275 * a point. 1275 1276 * 1276 1277 * Results: 1277 * 1278 * The return value is a standard Tcl result. 1278 1279 * 1279 1280 *--------------------------------------------------------------------------- … … 1282 1283 static int 1283 1284 PositionSwitchProc( 1284 ClientData clientData, 1285 1286 Tcl_Interp *interp, 1287 const char *switchName, 1288 Tcl_Obj *objPtr, 1289 char *record, 1290 int offset, 1291 int flags) 1285 ClientData clientData, /* Flag indicating if the node is considered 1286 * before or after the insertion position. */ 1287 Tcl_Interp *interp, /* Interpreter to send results back to */ 1288 const char *switchName, /* Not used. */ 1289 Tcl_Obj *objPtr, /* String representation */ 1290 char *record, /* Structure record */ 1291 int offset, /* Not used. */ 1292 int flags) /* Not used. */ 1292 1293 { 1293 1294 FlowPosition *posPtr = (FlowPosition *)(record + offset); … … 1298 1299 p = strrchr((char *)string, '%'); 1299 1300 if (p == NULL) { 1300 1301 1302 1303 1304 1305 1306 1301 float value; 1302 1303 if (GetFloatFromObj(interp, objPtr, &value) != TCL_OK) { 1304 return TCL_ERROR; 1305 } 1306 posPtr->value = value; 1307 posPtr->flags = ABSPOS; 1307 1308 } else { 1308 1309 1310 1311 1312 1313 1314 1315 1309 double value; 1310 1311 *p = '\0'; 1312 if (Tcl_GetDouble(interp, string, &value) != TCL_OK) { 1313 return TCL_ERROR; 1314 } 1315 posPtr->value = (float)value * 0.01; 1316 posPtr->flags = RELPOS; 1316 1317 } 1317 1318 return TCL_OK; … … 1323 1324 * TransferFunctionSwitchProc -- 1324 1325 * 1325 * 1326 * 1327 * 1326 * Convert a Tcl_Obj representing the transfer function into a 1327 * TransferFunction pointer. The transfer function must have been 1328 * previously defined. 1328 1329 * 1329 1330 * Results: 1330 * 1331 * The return value is a standard Tcl result. 1331 1332 * 1332 1333 *--------------------------------------------------------------------------- … … 1335 1336 static int 1336 1337 TransferFunctionSwitchProc( 1337 ClientData clientData, 1338 1339 Tcl_Interp *interp, 1340 const char *switchName, 1341 Tcl_Obj *objPtr, 1342 char *record, 1343 int offset, 1344 int flags) 1338 ClientData clientData, /* Flag indicating if the node is considered 1339 * before or after the insertion position. */ 1340 Tcl_Interp *interp, /* Interpreter to send results back to */ 1341 const char *switchName, /* Not used. */ 1342 Tcl_Obj *objPtr, /* String representation */ 1343 char *record, /* Structure record */ 1344 int offset, /* Not used. */ 1345 int flags) /* Not used. */ 1345 1346 { 1346 1347 TransferFunction **funcPtrPtr = (TransferFunction **)(record + offset); … … 1361 1362 * VideoFormatSwitchProc -- 1362 1363 * 1363 * 1364 * 1364 * Convert a Tcl_Obj representing the video format into its 1365 * integer id. 1365 1366 * 1366 1367 * Results: 1367 * 1368 * The return value is a standard Tcl result. 1368 1369 * 1369 1370 *--------------------------------------------------------------------------- … … 1372 1373 static int 1373 1374 VideoFormatSwitchProc( 1374 ClientData clientData, 1375 Tcl_Interp *interp, 1376 const char *switchName, 1377 Tcl_Obj *objPtr, 1378 char *record, 1379 int offset, 1380 int flags) 1375 ClientData clientData, /* Not used. */ 1376 Tcl_Interp *interp, /* Interpreter to send results back to */ 1377 const char *switchName, /* Not used. */ 1378 Tcl_Obj *objPtr, /* String representation */ 1379 char *record, /* Structure record */ 1380 int offset, /* Not used. */ 1381 int flags) /* Not used. */ 1381 1382 { 1382 1383 Rappture::AVTranslate::VideoFormats *formatPtr = 1383 1384 (Rappture::AVTranslate::VideoFormats *)(record + offset); 1384 1385 const char *string; 1385 1386 char c; … … 1388 1389 c = string[0]; 1389 1390 if ((c == 'm') && (strcmp(string, "mpeg") == 0)) { 1390 1391 *formatPtr = Rappture::AVTranslate::MPEG1; 1391 1392 } else if ((c == 't') && (strcmp(string, "theora") == 0)) { 1392 1393 *formatPtr = Rappture::AVTranslate::THEORA; 1393 1394 } else if ((c == 'm') && (strcmp(string, "mov") == 0)) { 1394 1395 *formatPtr = Rappture::AVTranslate::QUICKTIME; 1395 1396 } else { 1396 1397 Tcl_AppendResult(interp, "bad video format \"", string, 1397 1398 "\": should be mpeg, theora, or mov", (char*)NULL); 1398 1399 } … … 1402 1403 static int 1403 1404 FlowConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, 1404 1405 Tcl_Obj *const *objv) 1405 1406 { 1406 1407 FlowCmd *flowPtr = (FlowCmd *)clientData; 1407 1408 1408 1409 if (flowPtr->ParseSwitches(interp, objc - 2, objv + 2) != TCL_OK) { 1409 1410 return TCL_ERROR; 1410 1411 } 1411 1412 NanoVis::EventuallyRedraw(NanoVis::MAP_FLOWS); … … 1415 1416 static int 1416 1417 FlowParticlesAddOp(ClientData clientData, Tcl_Interp *interp, int objc, 1417 1418 Tcl_Obj *const *objv) 1418 1419 { 1419 1420 FlowCmd *flowPtr = (FlowCmd *)clientData; 1420 1421 1421 1422 if (flowPtr->CreateParticles(interp, objv[3]) != TCL_OK) { 1422 1423 return TCL_ERROR; 1423 1424 } 1424 1425 FlowParticles *particlesPtr; 1425 1426 if (flowPtr->GetParticles(interp, objv[3], &particlesPtr) != TCL_OK) { 1426 1427 return TCL_ERROR; 1427 1428 } 1428 1429 if (particlesPtr->ParseSwitches(interp, objc - 4, objv + 4) != TCL_OK) { 1429 1430 1430 delete particlesPtr; 1431 return TCL_ERROR; 1431 1432 } 1432 1433 particlesPtr->Configure(); … … 1438 1439 static int 1439 1440 FlowParticlesConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, 1440 1441 Tcl_Obj *const *objv) 1441 1442 { 1442 1443 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1444 1445 FlowParticles *particlesPtr; 1445 1446 if (flowPtr->GetParticles(interp, objv[3], &particlesPtr) != TCL_OK) { 1446 1447 return TCL_ERROR; 1447 1448 } 1448 1449 if (particlesPtr->ParseSwitches(interp, objc - 4, objv + 4) != TCL_OK) { 1449 1450 return TCL_ERROR; 1450 1451 } 1451 1452 particlesPtr->Configure(); … … 1456 1457 static int 1457 1458 FlowParticlesDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, 1458 1459 Tcl_Obj *const *objv) 1459 1460 { 1460 1461 FlowCmd *flowPtr = (FlowCmd *)clientData; 1461 1462 int i; 1462 1463 for (i = 3; i < objc; i++) { 1463 1464 1465 1466 1467 1464 FlowParticles *particlesPtr; 1465 1466 if (flowPtr->GetParticles(NULL, objv[i], &particlesPtr) == TCL_OK) { 1467 delete particlesPtr; 1468 } 1468 1469 } 1469 1470 NanoVis::EventuallyRedraw(); … … 1473 1474 static int 1474 1475 FlowParticlesNamesOp(ClientData clientData, Tcl_Interp *interp, int objc, 1475 1476 Tcl_Obj *const *objv) 1476 1477 { 1477 1478 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1481 1482 FlowParticles *particlesPtr; 1482 1483 for (particlesPtr = flowPtr->FirstParticles(&iter); particlesPtr != NULL; 1483 1484 1485 1486 1487 1484 particlesPtr = flowPtr->NextParticles(&iter)) { 1485 Tcl_Obj *objPtr; 1486 1487 objPtr = Tcl_NewStringObj(particlesPtr->name(), -1); 1488 Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); 1488 1489 } 1489 1490 Tcl_SetObjResult(interp, listObjPtr); … … 1496 1497 * FlowParticlesObjCmd -- 1497 1498 * 1498 * 1499 * 1499 * This procedure is invoked to process commands on behalf of the flow 1500 * object. 1500 1501 * 1501 1502 * Results: 1502 * 1503 * A standard Tcl result. 1503 1504 * 1504 1505 * Side effects: 1505 * 1506 * See the user documentation. 1506 1507 * 1507 1508 * $flow particles oper $name … … 1511 1512 {"add", 1, FlowParticlesAddOp, 4, 0, "name ?switches?",}, 1512 1513 {"configure", 1, FlowParticlesConfigureOp, 4, 0, "name ?switches?",}, 1513 {"delete", 1514 {"delete", 1, FlowParticlesDeleteOp, 4, 0, "?name...?"}, 1514 1515 {"names", 1, FlowParticlesNamesOp, 3, 4, "?pattern?"}, 1515 1516 }; … … 1519 1520 static int 1520 1521 FlowParticlesOp(ClientData clientData, Tcl_Interp *interp, int objc, 1521 1522 Tcl_Obj *const *objv) 1522 1523 { 1523 1524 Tcl_ObjCmdProc *proc; 1524 1525 proc = Rappture::GetOpFromObj(interp, nFlowParticlesOps, flowParticlesOps, 1525 1526 Rappture::CMDSPEC_ARG2, objc, objv, 0); 1526 1527 if (proc == NULL) { 1527 1528 return TCL_ERROR; 1528 1529 } 1529 1530 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1537 1538 static int 1538 1539 FlowBoxAddOp(ClientData clientData, Tcl_Interp *interp, int objc, 1539 1540 Tcl_Obj *const *objv) 1540 1541 { 1541 1542 FlowCmd *flowPtr = (FlowCmd *)clientData; 1542 1543 1543 1544 if (flowPtr->CreateBox(interp, objv[3]) != TCL_OK) { 1544 1545 return TCL_ERROR; 1545 1546 } 1546 1547 FlowBox *boxPtr; 1547 1548 if (flowPtr->GetBox(interp, objv[3], &boxPtr) != TCL_OK) { 1548 1549 return TCL_ERROR; 1549 1550 } 1550 1551 if (boxPtr->ParseSwitches(interp, objc - 4, objv + 4) != TCL_OK) { 1551 1552 1552 delete boxPtr; 1553 return TCL_ERROR; 1553 1554 } 1554 1555 NanoVis::EventuallyRedraw(); … … 1559 1560 static int 1560 1561 FlowBoxDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, 1561 1562 Tcl_Obj *const *objv) 1562 1563 { 1563 1564 FlowCmd *flowPtr = (FlowCmd *)clientData; 1564 1565 int i; 1565 1566 for (i = 3; i < objc; i++) { 1566 1567 1568 1569 1570 1567 FlowBox *boxPtr; 1568 1569 if (flowPtr->GetBox(NULL, objv[i], &boxPtr) == TCL_OK) { 1570 delete boxPtr; 1571 } 1571 1572 } 1572 1573 NanoVis::EventuallyRedraw(); … … 1584 1585 FlowBox *boxPtr; 1585 1586 for (boxPtr = flowPtr->FirstBox(&iter); boxPtr != NULL; 1586 1587 1588 1589 1590 1587 boxPtr = flowPtr->NextBox(&iter)) { 1588 Tcl_Obj *objPtr; 1589 1590 objPtr = Tcl_NewStringObj(boxPtr->name(), -1); 1591 Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); 1591 1592 } 1592 1593 Tcl_SetObjResult(interp, listObjPtr); … … 1596 1597 static int 1597 1598 FlowBoxConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, 1598 1599 Tcl_Obj *const *objv) 1599 1600 { 1600 1601 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1602 1603 FlowBox *boxPtr; 1603 1604 if (flowPtr->GetBox(interp, objv[3], &boxPtr) != TCL_OK) { 1604 1605 return TCL_ERROR; 1605 1606 } 1606 1607 if (boxPtr->ParseSwitches(interp, objc - 4, objv + 4) != TCL_OK) { 1607 1608 return TCL_ERROR; 1608 1609 } 1609 1610 NanoVis::EventuallyRedraw(); … … 1616 1617 * FlowBoxOp-- 1617 1618 * 1618 * 1619 * 1619 * This procedure is invoked to process commands on behalf of the flow 1620 * object. 1620 1621 * 1621 1622 * Results: 1622 * 1623 * A standard Tcl result. 1623 1624 * 1624 1625 * Side effects: 1625 * 1626 * See the user documentation. 1626 1627 * 1627 1628 *--------------------------------------------------------------------------- … … 1630 1631 {"add", 1, FlowBoxAddOp, 4, 0, "name ?switches?",}, 1631 1632 {"configure", 1, FlowBoxConfigureOp, 4, 0, "name ?switches?",}, 1632 {"delete", 1633 {"delete", 1, FlowBoxDeleteOp, 3, 0, "?name...?"}, 1633 1634 {"names", 1, FlowBoxNamesOp, 3, 0, "?pattern?"}, 1634 1635 }; … … 1638 1639 static int 1639 1640 FlowBoxOp(ClientData clientData, Tcl_Interp *interp, int objc, 1640 1641 Tcl_Obj *const *objv) 1641 1642 { 1642 1643 Tcl_ObjCmdProc *proc; 1643 1644 proc = Rappture::GetOpFromObj(interp, nFlowBoxOps, flowBoxOps, 1644 1645 Rappture::CMDSPEC_ARG2, objc, objv, 0); 1645 1646 if (proc == NULL) { 1646 1647 return TCL_ERROR; 1647 1648 } 1648 1649 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1667 1668 static int 1668 1669 FlowLegendOp(ClientData clientData, Tcl_Interp *interp, int objc, 1669 1670 Tcl_Obj *const *objv) 1670 1671 { 1671 1672 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1698 1699 * FlowInstObjCmd -- 1699 1700 * 1700 * 1701 * 1701 * This procedure is invoked to process commands on behalf of the flow 1702 * object. 1702 1703 * 1703 1704 * Results: 1704 * 1705 * A standard Tcl result. 1705 1706 * 1706 1707 * Side effects: 1707 * 1708 * See the user documentation. 1708 1709 * 1709 1710 *--------------------------------------------------------------------------- … … 1712 1713 {"box", 1, FlowBoxOp, 2, 0, "oper ?args?"}, 1713 1714 {"configure", 1, FlowConfigureOp, 2, 0, "?switches?"}, 1714 {"data", 1715 {"data", 1, FlowDataOp, 2, 0, "oper ?args?"}, 1715 1716 {"legend", 1, FlowLegendOp, 4, 4, "w h"}, 1716 1717 {"particles", 1, FlowParticlesOp, 2, 0, "oper ?args?"} … … 1720 1721 static int 1721 1722 FlowInstObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, 1722 1723 Tcl_Obj *const *objv) 1723 1724 { 1724 1725 Tcl_ObjCmdProc *proc; 1725 1726 proc = Rappture::GetOpFromObj(interp, nFlowInstOps, flowInstOps, 1726 1727 Rappture::CMDSPEC_ARG1, objc, objv, 0); 1727 1728 if (proc == NULL) { 1728 1729 return TCL_ERROR; 1729 1730 } 1730 1731 assert(CheckGL(AT)); … … 1742 1743 * FlowInstDeleteProc -- 1743 1744 * 1744 * 1745 * 1745 * Deletes the command associated with the tree. This is called only 1746 * when the command associated with the tree is destroyed. 1746 1747 * 1747 1748 * Results: 1748 * 1749 * None. 1749 1750 * 1750 1751 *--------------------------------------------------------------------------- … … 1767 1768 static int 1768 1769 FlowAddOp(ClientData clientData, Tcl_Interp *interp, int objc, 1769 1770 Tcl_Obj *const *objv) 1770 1771 { 1771 1772 if (NanoVis::CreateFlow(interp, objv[2]) != TCL_OK) { 1772 1773 return TCL_ERROR; 1773 1774 } 1774 1775 FlowCmd *flowPtr; 1775 1776 if (NanoVis::GetFlow(interp, objv[2], &flowPtr) != TCL_OK) { 1776 1777 return TCL_ERROR; 1777 1778 } 1778 1779 if (flowPtr->ParseSwitches(interp, objc - 3, objv + 3) != TCL_OK) { 1779 1780 1780 Tcl_DeleteCommand(interp, flowPtr->name()); 1781 return TCL_ERROR; 1781 1782 } 1782 1783 Tcl_SetObjResult(interp, objv[2]); … … 1795 1796 static int 1796 1797 FlowDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, 1797 1798 Tcl_Obj *const *objv) 1798 1799 { 1799 1800 int i; 1800 1801 1801 1802 for (i = 2; i < objc; i++) { 1802 1803 1804 1805 1806 1807 1803 FlowCmd *flowPtr; 1804 1805 if (NanoVis::GetFlow(interp, objv[i], &flowPtr) != TCL_OK) { 1806 return TCL_ERROR; 1807 } 1808 Tcl_DeleteCommand(interp, flowPtr->name()); 1808 1809 } 1809 1810 NanoVis::EventuallyRedraw(NanoVis::MAP_FLOWS); … … 1821 1822 static int 1822 1823 FlowExistsOp(ClientData clientData, Tcl_Interp *interp, int objc, 1823 1824 Tcl_Obj *const *objv) 1824 1825 { 1825 1826 bool value; … … 1828 1829 value = false; 1829 1830 if (NanoVis::GetFlow(NULL, objv[2], &flowPtr) == TCL_OK) { 1830 1831 value = true; 1831 1832 } 1832 1833 Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (int)value); … … 1839 1840 * FlowGotoOp -- 1840 1841 * 1841 * 1842 * flow goto number 1842 1843 * 1843 1844 *--------------------------------------------------------------------------- … … 1852 1853 } 1853 1854 if ((nSteps < 0) || (nSteps > SHRT_MAX)) { 1854 1855 1856 1855 Tcl_AppendResult(interp, "flow goto: bad # of steps \"", 1856 Tcl_GetString(objv[2]), "\"", (char *)NULL); 1857 return TCL_ERROR; 1857 1858 } 1858 1859 NanoVis::ResetFlows(); 1859 1860 if (NanoVis::flags & NanoVis::MAP_FLOWS) { 1860 1861 NanoVis::MapFlows(); 1861 1862 } 1862 1863 int i; 1863 1864 NanoVis::AdvectFlows(); 1864 1865 for (i = 0; i < nSteps; i++) { 1865 1866 1867 1868 1866 if (NanoVis::licRenderer->active()) { 1867 NanoVis::licRenderer->convolve(); 1868 } 1869 NanoVis::AdvectFlows(); 1869 1870 } 1870 1871 NanoVis::EventuallyRedraw(); … … 1882 1883 static int 1883 1884 FlowNamesOp(ClientData clientData, Tcl_Interp *interp, int objc, 1884 1885 Tcl_Obj *const *objv) 1885 1886 { 1886 1887 Tcl_Obj *listObjPtr; … … 1889 1890 FlowIterator iter; 1890 1891 for (flowPtr = NanoVis::FirstFlow(&iter); flowPtr != NULL; 1891 1892 1893 1894 1895 1892 flowPtr = NanoVis::NextFlow(&iter)) { 1893 Tcl_Obj *objPtr; 1894 1895 objPtr = Tcl_NewStringObj(flowPtr->name(), -1); 1896 Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); 1896 1897 } 1897 1898 Tcl_SetObjResult(interp, listObjPtr); … … 1905 1906 assert(NanoVis::licRenderer != NULL); 1906 1907 if (NanoVis::flags & NanoVis::MAP_FLOWS) { 1907 1908 NanoVis::MapFlows(); 1908 1909 } 1909 1910 NanoVis::EventuallyRedraw(); … … 1922 1923 1923 1924 struct FlowVideoValues { 1924 float frameRate; 1925 int bitRate; 1926 int width, height; 1925 float frameRate; /* Frame rate */ 1926 int bitRate; /* Video bitrate */ 1927 int width, height; /* Dimensions of video frame. */ 1927 1928 int nFrames; 1928 1929 Rappture::AVTranslate::VideoFormats format; … … 1936 1937 Rappture::SwitchSpec FlowCmd::videoSwitches[] = { 1937 1938 {Rappture::SWITCH_FLOAT, "-bitrate", "value", 1938 1939 offsetof(FlowVideoValues, bitRate), 0}, 1939 1940 {Rappture::SWITCH_CUSTOM, "-format", "string", 1940 1941 offsetof(FlowVideoValues, format), 0, 0, &videoFormatSwitch}, 1941 1942 {Rappture::SWITCH_FLOAT, "-framerate", "value", 1942 1943 offsetof(FlowVideoValues, frameRate), 0}, 1943 1944 {Rappture::SWITCH_INT, "-height", "integer", 1944 1945 offsetof(FlowVideoValues, height), 0}, 1945 1946 {Rappture::SWITCH_INT, "-numframes", "count", 1946 1947 offsetof(FlowVideoValues, nFrames), 0}, 1947 1948 {Rappture::SWITCH_INT, "-width", "integer", 1948 1949 offsetof(FlowVideoValues, width), 0}, 1949 1950 {Rappture::SWITCH_END} 1950 1951 }; … … 1952 1953 static int 1953 1954 FlowVideoOp(ClientData clientData, Tcl_Interp *interp, int objc, 1954 1955 Tcl_Obj *const *objv) 1955 1956 { 1956 1957 struct pollfd pollResults; … … 1960 1961 pollResults.events = POLLIN; 1961 1962 1962 #define PENDING_TIMEOUT 1963 #define PENDING_TIMEOUT 10 /* milliseconds. */ 1963 1964 timeout = PENDING_TIMEOUT; 1964 1965 … … 1967 1968 1968 1969 token = Tcl_GetString(objv[2]); 1969 values.frameRate = 25.0f; 1970 values.bitRate = 6.0e+6f; 1970 values.frameRate = 25.0f; // Default frame rate 25 fps 1971 values.bitRate = 6.0e+6f; // Default video bit rate. 1971 1972 values.width = NanoVis::win_width; 1972 1973 values.height = NanoVis::win_height; … … 1974 1975 values.format = Rappture::AVTranslate::MPEG1; 1975 1976 if (Rappture::ParseSwitches(interp, FlowCmd::videoSwitches, 1976 1977 1977 objc - 3, objv + 3, &values, SWITCH_DEFAULTS) < 0) { 1978 return TCL_ERROR; 1978 1979 } 1979 1980 if ((values.width < 0) || (values.width > SHRT_MAX) || 1980 1981 1982 1981 (values.height < 0) || (values.height > SHRT_MAX)) { 1982 Tcl_AppendResult(interp, "bad dimensions for video", (char *)NULL); 1983 return TCL_ERROR; 1983 1984 } 1984 1985 if ((values.frameRate < 0.0f) || (values.frameRate > 30.0f)) { 1985 1986 1986 Tcl_AppendResult(interp, "bad frame rate.", (char *)NULL); 1987 return TCL_ERROR; 1987 1988 } 1988 1989 if (values.bitRate < 0.0f) { 1989 1990 1990 Tcl_AppendResult(interp, "bad bit rate.", (char *)NULL); 1991 return TCL_ERROR; 1991 1992 } 1992 1993 if (NanoVis::licRenderer == NULL) { 1993 1994 1994 Tcl_AppendResult(interp, "no lic renderer.", (char *)NULL); 1995 return TCL_ERROR; 1995 1996 } 1996 1997 // Save the old dimensions of the offscreen buffer. … … 2004 2005 2005 2006 Rappture::AVTranslate movie(values.width, values.height, values.bitRate, 2006 2007 values.frameRate); 2007 2008 char tmpFileName[200]; 2008 2009 sprintf(tmpFileName,"/tmp/flow%d.mpeg", getpid()); 2009 2010 if (!movie.init(context, tmpFileName)) { 2010 2011 Tcl_AppendResult(interp, "can't initialized movie \"", tmpFileName, 2011 2012 2012 "\": ", context.remark(), (char *)NULL); 2013 return TCL_ERROR; 2013 2014 } 2014 2015 if ((values.width != oldWidth) || (values.height != oldHeight)) { 2015 2016 2016 // Resize to the requested size. 2017 NanoVis::resize_offscreen_buffer(values.width, values.height); 2017 2018 } 2018 2019 // Now compute the line padding for the offscreen buffer. … … 2024 2025 bool canceled = false; 2025 2026 for (int i = 1; i <= values.nFrames; i++) { 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2027 if (((i & 0xF) == 0) && (poll(&pollResults, 1, 0) > 0)) { 2028 /* If there's another command on stdin, that means the client is 2029 * trying to cancel this operation. */ 2030 canceled = true; 2031 break; 2032 } 2033 if (NanoVis::licRenderer->active()) { 2034 NanoVis::licRenderer->convolve(); 2035 } 2036 NanoVis::AdvectFlows(); 2037 NanoVis::offscreen_buffer_capture(); 2037 2038 NanoVis::display(); 2038 2039 NanoVis::read_screen(); … … 2043 2044 Trace("FLOW end\n"); 2044 2045 if (!canceled) { 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2046 Rappture::Buffer data; 2047 2048 /* FIXME: find a way to get the data from the movie object as a 2049 * void* */ 2050 if (!data.load(context, tmpFileName)) { 2051 Tcl_AppendResult(interp, "can't load data from temporary file \"", 2052 tmpFileName, "\": ", context.remark(), (char *)NULL); 2053 return TCL_ERROR; 2054 } 2055 2056 char command[200]; 2057 sprintf(command,"nv>image -bytes %lu -type movie -token \"%s\"\n", 2058 (unsigned long)data.size(), token); 2059 NanoVis::sendDataToClient(command, data.bytes(), data.size()); 2059 2060 } 2060 2061 if ((values.width != oldWidth) || (values.height != oldHeight)) { 2061 2062 NanoVis::resize_offscreen_buffer(oldWidth, oldHeight); 2062 2063 } 2063 2064 NanoVis::ResetFlows(); 2064 2065 if (unlink(tmpFileName) != 0) { 2065 2066 Tcl_AppendResult(interp, "can't unlink temporary movie file \"", 2066 2067 2067 tmpFileName, "\": ", Tcl_PosixError(interp), (char *)NULL); 2068 return TCL_ERROR; 2068 2069 } 2069 2070 return TCL_OK; … … 2093 2094 static int 2094 2095 FlowCmdProc(ClientData clientData, Tcl_Interp *interp, int objc, 2095 2096 Tcl_Obj *const *objv) 2096 2097 { 2097 2098 Tcl_ObjCmdProc *proc; 2098 2099 2099 2100 proc = Rappture::GetOpFromObj(interp, nFlowCmdOps, flowCmdOps, 2100 2101 Rappture::CMDSPEC_ARG1, objc, objv, 0); 2101 2102 if (proc == NULL) { 2102 2103 return TCL_ERROR; 2103 2104 } 2104 2105 return (*proc) (clientData, interp, objc, objv); … … 2110 2111 * FlowCmdInitProc -- 2111 2112 * 2112 * 2113 * This procedure is invoked to initialize the "tree" command. 2113 2114 * 2114 2115 * Results: 2115 * 2116 * None. 2116 2117 * 2117 2118 * Side effects: 2118 * 2119 * 2119 * Creates the new command and adds a new entry into a global Tcl 2120 * associative array. 2120 2121 * 2121 2122 *--------------------------------------------------------------------------- … … 2141 2142 if (line == endPtr) { 2142 2143 vtkErrorMacro(<<"Premature EOF reading first line! " << " for file: " 2143 2144 << (this->FileName?this->FileName:"(Null FileName)")); 2144 2145 return false; 2145 2146 } 2146 2147 if (sscanf(line, "# vtk DataFile Version %s", version) != 1) { 2147 2148 vtkErrorMacro(<< "Unrecognized file type: "<< line << " for file: " 2148 2149 << (this->FileName?this->FileName:"(Null FileName)")); 2149 2150 return false; 2150 2151 } … … 2153 2154 if (line == endPtr) { 2154 2155 vtkErrorMacro(<<"Premature EOF reading title! " << " for file: " 2155 2156 << (this->FileName?this->FileName:"(Null FileName)")); 2156 2157 return false; 2157 2158 } … … 2166 2167 if (line == endPtr) { 2167 2168 vtkErrorMacro(<<"Premature EOF reading file type!" << " for file: " 2168 2169 << (this->FileName?this->FileName:"(Null FileName)")); 2169 2170 return false; 2170 2171 } … … 2176 2177 } else { 2177 2178 vtkErrorMacro(<< "Unrecognized file type: "<< line << " for file: " 2178 2179 << (this->FileName?this->FileName:"(Null FileName)")); 2179 2180 _fileType = 0; 2180 2181 return false; … … 2185 2186 if (line == endPtr) { 2186 2187 vtkErrorMacro(<<"Premature EOF reading file type!" << " for file: " 2187 2188 << (this->FileName?this->FileName:"(Null FileName)")); 2188 2189 return false; 2189 2190 } … … 2193 2194 line = getline(&p, endPtr); 2194 2195 if (line == endPtr) { 2195 2196 // EOF 2196 2197 } 2197 2198 type = GetWord(line, &endPtr); 2198 2199 if (strncasecmp(word, "structured_grid", 15) == 0) { 2199 2200 2200 vtkErrorMacro(<< "Cannot read dataset type: " << line); 2201 return 1; 2201 2202 } 2202 2203 // Read keyword and dimensions
Note: See TracChangeset
for help on using the changeset viewer.