Changeset 2875 for trunk/packages/vizservers
- Timestamp:
- Mar 22, 2012, 5:17:27 PM (13 years ago)
- Location:
- trunk/packages/vizservers/nanovis
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/packages/vizservers/nanovis/FlowCmd.cpp
r2863 r2875 65 65 Rappture::SwitchSpec FlowCmd::_switches[] = { 66 66 {Rappture::SWITCH_BOOLEAN, "-arrows", "boolean", 67 67 offsetof(FlowValues, showArrows), 0}, 68 68 {Rappture::SWITCH_CUSTOM, "-axis", "axis", 69 69 offsetof(FlowValues, slicePos.axis), 0, 0, &axisSwitch}, 70 70 {Rappture::SWITCH_FLOAT, "-diffuse", "value", 71 71 offsetof(FlowValues, diffuse), 0}, 72 72 {Rappture::SWITCH_BOOLEAN, "-hide", "boolean", 73 73 offsetof(FlowValues, isHidden), 0}, 74 74 {Rappture::SWITCH_FLOAT, "-opacity", "value", 75 75 offsetof(FlowValues, opacity), 0}, 76 76 {Rappture::SWITCH_BOOLEAN, "-outline", "boolean", 77 77 offsetof(FlowValues, showOutline), 0}, 78 78 {Rappture::SWITCH_CUSTOM, "-position", "number", 79 79 offsetof(FlowValues, slicePos), 0, 0, &positionSwitch}, 80 80 {Rappture::SWITCH_BOOLEAN, "-slice", "boolean", 81 81 offsetof(FlowValues, sliceVisible), 0}, 82 82 {Rappture::SWITCH_FLOAT, "-specular", "value", 83 83 offsetof(FlowValues, specular), 0}, 84 84 {Rappture::SWITCH_CUSTOM, "-transferfunction", "name", 85 85 offsetof(FlowValues, tfPtr), 0, 0, &transferFunctionSwitch}, 86 86 {Rappture::SWITCH_BOOLEAN, "-volume", "boolean", 87 87 offsetof(FlowValues, showVolume), 0}, 88 88 {Rappture::SWITCH_END} 89 89 }; … … 91 91 Rappture::SwitchSpec FlowParticles::_switches[] = { 92 92 {Rappture::SWITCH_CUSTOM, "-axis", "string", 93 93 offsetof(FlowParticlesValues, position.axis), 0, 0, &axisSwitch}, 94 94 {Rappture::SWITCH_CUSTOM, "-color", "{r g b a}", 95 95 offsetof(FlowParticlesValues, color), 0, 0, &colorSwitch}, 96 96 {Rappture::SWITCH_BOOLEAN, "-hide", "boolean", 97 97 offsetof(FlowParticlesValues, isHidden), 0}, 98 98 {Rappture::SWITCH_CUSTOM, "-position", "number", 99 99 offsetof(FlowParticlesValues, position), 0, 0, &positionSwitch}, 100 100 {Rappture::SWITCH_FLOAT, "-size", "float", 101 101 offsetof(FlowParticlesValues, particleSize), 0}, 102 102 {Rappture::SWITCH_END} 103 103 }; … … 105 105 Rappture::SwitchSpec FlowBox::_switches[] = { 106 106 {Rappture::SWITCH_CUSTOM, "-color", "{r g b a}", 107 107 offsetof(FlowBoxValues, color), 0, 0, &colorSwitch}, 108 108 {Rappture::SWITCH_CUSTOM, "-corner1", "{x y z}", 109 109 offsetof(FlowBoxValues, corner1), 0, 0, &pointSwitch}, 110 110 {Rappture::SWITCH_CUSTOM, "-corner2", "{x y z}", 111 111 offsetof(FlowBoxValues, corner2), 0, 0, &pointSwitch}, 112 112 {Rappture::SWITCH_BOOLEAN, "-hide", "boolean", 113 113 offsetof(FlowBoxValues, isHidden), 0}, 114 114 {Rappture::SWITCH_FLOAT, "-linewidth", "number", 115 115 offsetof(FlowBoxValues, lineWidth), 0}, 116 116 {Rappture::SWITCH_END} 117 117 }; 118 118 119 120 119 static Tcl_ObjCmdProc FlowInstObjCmd; 121 120 static Tcl_CmdDeleteProc FlowInstDeleteProc; 122 121 123 124 FlowParticles::FlowParticles(const char *name, Tcl_HashEntry *hPtr) 125 { 126 memset(this, 0, sizeof(FlowParticles)); 127 _name = name; 128 _hashPtr = hPtr; 122 FlowParticles::FlowParticles(const char *name, Tcl_HashEntry *hPtr) : 123 _name(name), 124 _hashPtr(hPtr), 125 _rendererPtr(new NvParticleRenderer(NMESH, NMESH)) 126 { 127 _sv.position.value = 0.0f; 128 _sv.position.flags = RELPOS; 129 _sv.position.axis = 0; // X_AXIS 130 _sv.color.r = _sv.color.g = _sv.color.b = _sv.color.a = 1.0f; 129 131 _sv.isHidden = false; 130 _sv.position.axis = 0; /* X_AXIS */ 131 _sv.position.value = 0.0f; 132 _sv.position.flags = RELPOS; 133 _sv.color.r = _sv.color.b = _sv.color.g = _sv.color.a = 1.0f; 134 _rendererPtr = new NvParticleRenderer(NMESH, NMESH); 135 } 136 137 FlowParticles::~FlowParticles(void) 132 _sv.particleSize = 1.2; 133 } 134 135 FlowParticles::~FlowParticles() 138 136 { 139 137 if (_rendererPtr != NULL) { 140 138 delete _rendererPtr; 141 139 } 142 140 if (_hashPtr != NULL) { 143 141 Tcl_DeleteHashEntry(_hashPtr); 144 142 } 145 143 Rappture::FreeSwitches(_switches, &_sv, 0); … … 147 145 148 146 void 149 FlowParticles::Render( void)147 FlowParticles::Render() 150 148 { 151 149 TRACE("rendering particles %s\n", _name); … … 153 151 TRACE("rendering particles %s position=%g\n", _name, _sv.position.value); 154 152 TRACE("rendering particles %s position=%g\n", _name, 155 153 FlowCmd::GetRelativePosition(&_sv.position)); 156 154 157 155 _rendererPtr->setPos(FlowCmd::GetRelativePosition(&_sv.position)); … … 162 160 163 161 void 164 FlowParticles::Configure( void)162 FlowParticles::Configure() 165 163 { 166 164 _rendererPtr->setPos(FlowCmd::GetRelativePosition(&_sv.position)); 167 165 _rendererPtr->setColor(Vector4(_sv.color.r, _sv.color.g, _sv.color.b, 168 166 _sv.color.a)); 169 167 _rendererPtr->particleSize(_sv.particleSize); 170 168 _rendererPtr->setAxis(_sv.position.axis); … … 177 175 _hashPtr = hPtr; 178 176 _sv.isHidden = false; 179 _sv.corner1.x = 0.0f; 180 _sv.corner1.y = 0.0f; 181 _sv.corner1.z = 0.0f; 182 _sv.corner2.x = 1.0f; 183 _sv.corner2.y = 1.0f; 184 _sv.corner2.z = 1.0f; 177 _sv.corner1.x = 0.0f; 178 _sv.corner1.y = 0.0f; 179 _sv.corner1.z = 0.0f; 180 _sv.corner2.x = 1.0f; 181 _sv.corner2.y = 1.0f; 182 _sv.corner2.z = 1.0f; 185 183 _sv.lineWidth = 1.2f; 186 184 _sv.color.r = _sv.color.b = _sv.color.g = _sv.color.a = 1.0f; 187 188 185 } 189 186 … … 199 196 glDisable(GL_TEXTURE_2D); 200 197 glEnable(GL_BLEND); 201 198 202 199 glPushMatrix(); 203 200 Vector3 origin = volPtr->location(); … … 208 205 sy = volPtr->height / (double)volPtr->width; 209 206 if (volPtr->depth > 0.0) { 210 207 sz = volPtr->depth / (double)volPtr->width; 211 208 } 212 209 glScaled(sx, sy, sz); … … 218 215 219 216 TRACE("box is %g,%g %g,%g %g,%g\n", 220 221 222 217 _sv.corner1.x, _sv.corner2.x, 218 _sv.corner1.y, _sv.corner2.y, 219 _sv.corner1.z, _sv.corner2.z); 223 220 TRACE("world is %g,%g %g,%g %g,%g\n", 224 221 min.x, max.x, min.y, max.y, min.z, max.z); 225 222 226 223 float x0, y0, z0, x1, y1, z1; … … 228 225 x1 = y1 = z1 = 0.0f; 229 226 if (max.y > min.y) { 230 231 227 y0 = (_sv.corner1.y - min.y) / (max.y - min.y); 228 y1 = (_sv.corner2.y - min.y) / (max.y - min.y); 232 229 } 233 230 if (max.z > min.z) { 234 235 231 z0 = (_sv.corner1.z - min.z) / (max.z - min.z); 232 z1 = (_sv.corner2.z - min.z) / (max.z - min.z); 236 233 } 237 234 if (max.x > min.x) { 238 239 235 x0 = (_sv.corner1.x - min.x) / (max.x - min.x); 236 x1 = (_sv.corner2.x - min.x) / (max.x - min.x); 240 237 } 241 238 TRACE("rendering box %g,%g %g,%g %g,%g\n", x0, x1, y0, y1, z0, z1); … … 244 241 glBegin(GL_LINE_LOOP); 245 242 { 246 247 248 249 243 glVertex3d(x0, y0, z0); 244 glVertex3d(x1, y0, z0); 245 glVertex3d(x1, y1, z0); 246 glVertex3d(x0, y1, z0); 250 247 } 251 248 glEnd(); 252 249 glBegin(GL_LINE_LOOP); 253 250 { 254 255 256 257 251 glVertex3d(x0, y0, z1); 252 glVertex3d(x1, y0, z1); 253 glVertex3d(x1, y1, z1); 254 glVertex3d(x0, y1, z1); 258 255 } 259 256 glEnd(); … … 261 258 glBegin(GL_LINE_LOOP); 262 259 { 263 264 265 266 260 glVertex3d(x0, y0, z0); 261 glVertex3d(x0, y0, z1); 262 glVertex3d(x0, y1, z1); 263 glVertex3d(x0, y1, z0); 267 264 } 268 265 glEnd(); … … 270 267 glBegin(GL_LINE_LOOP); 271 268 { 272 273 274 275 269 glVertex3d(x1, y0, z0); 270 glVertex3d(x1, y0, z1); 271 glVertex3d(x1, y1, z1); 272 glVertex3d(x1, y1, z0); 276 273 } 277 274 glEnd(); … … 287 284 } 288 285 289 290 FlowCmd::FlowCmd(Tcl_Interp *interp, const char *name, Tcl_HashEntry *hPtr) 291 { 292 memset(this, 0, sizeof(FlowCmd)); 293 _name = name; 294 _interp = interp; 295 _hashPtr = hPtr; 296 _dataPtr = NULL; 286 FlowCmd::FlowCmd(Tcl_Interp *interp, const char *name, Tcl_HashEntry *hPtr) : 287 _interp(interp), 288 _hashPtr(hPtr), 289 _name(name), 290 _dataPtr(NULL), 291 _volPtr(NULL), 292 _fieldPtr(NULL) 293 { 294 memset(&_sv, 0, sizeof(FlowValues)); 297 295 _sv.sliceVisible = 1; 298 296 _sv.tfPtr = NanoVis::get_transfunc("default"); 299 _volPtr = NULL; 300 _cmdToken = Tcl_CreateObjCommand(interp, (char *)_name, 301 (Tcl_ObjCmdProc *)FlowInstObjCmd, this, FlowInstDeleteProc); 297 302 298 Tcl_InitHashTable(&_particlesTable, TCL_STRING_KEYS); 303 299 Tcl_InitHashTable(&_boxTable, TCL_STRING_KEYS); 304 } 305 306 FlowCmd::~FlowCmd(void) 300 301 _cmdToken = Tcl_CreateObjCommand(_interp, (char *)_name, 302 (Tcl_ObjCmdProc *)FlowInstObjCmd, 303 this, FlowInstDeleteProc); 304 } 305 306 FlowCmd::~FlowCmd() 307 307 { 308 308 Rappture::FreeSwitches(_switches, &_sv, 0); 309 309 if (_hashPtr != NULL) { 310 310 Tcl_DeleteHashEntry(_hashPtr); 311 311 } 312 312 if (_fieldPtr != NULL) { 313 313 delete _fieldPtr; 314 314 } 315 315 if (_dataPtr != NULL) { 316 317 } 318 319 320 316 delete _dataPtr; 317 } 318 if (_volPtr != NULL) { 319 NanoVis::remove_volume(_volPtr); 320 _volPtr = NULL; 321 321 } 322 322 … … 324 324 FlowBoxIterator boxIter; 325 325 for (boxPtr = FirstBox(&boxIter); boxPtr != NULL; 326 327 328 329 } 326 boxPtr = NextBox(&boxIter)) { 327 boxPtr->disconnect(); 328 delete boxPtr; 329 } 330 330 FlowParticles *particlesPtr; 331 331 FlowParticlesIterator partIter; 332 332 for (particlesPtr = FirstParticles(&partIter); particlesPtr != NULL; 333 334 335 336 } 333 particlesPtr = NextParticles(&partIter)) { 334 particlesPtr->disconnect(); 335 delete particlesPtr; 336 } 337 337 Tcl_DeleteHashTable(&_particlesTable); 338 338 Tcl_DeleteHashTable(&_boxTable); … … 340 340 341 341 void 342 FlowCmd::ResetParticles( void)342 FlowCmd::ResetParticles() 343 343 { 344 344 FlowParticlesIterator iter; 345 345 FlowParticles *particlesPtr; 346 346 for (particlesPtr = FirstParticles(&iter); particlesPtr != NULL; 347 348 347 particlesPtr = NextParticles(&iter)) { 348 particlesPtr->Reset(); 349 349 } 350 350 } 351 351 352 352 void 353 FlowCmd::Advect( void)353 FlowCmd::Advect() 354 354 { 355 355 NvVectorField *fieldPtr; … … 359 359 FlowParticles *particlesPtr; 360 360 for (particlesPtr = FirstParticles(&iter); particlesPtr != NULL; 361 362 363 364 361 particlesPtr = NextParticles(&iter)) { 362 if (particlesPtr->visible()) { 363 particlesPtr->Advect(); 364 } 365 365 } 366 366 } 367 367 368 368 void 369 FlowCmd::Render( void)369 FlowCmd::Render() 370 370 { 371 371 _fieldPtr->active(true); … … 374 374 FlowParticles *particlesPtr; 375 375 for (particlesPtr = FirstParticles(&iter); particlesPtr != NULL; 376 377 378 379 376 particlesPtr = NextParticles(&iter)) { 377 if (particlesPtr->visible()) { 378 particlesPtr->Render(); 379 } 380 380 } 381 381 TRACE("in Render before boxes %s\n", _name); … … 391 391 hPtr = Tcl_CreateHashEntry(&_particlesTable, particlesName, &isNew); 392 392 if (!isNew) { 393 394 395 393 Tcl_AppendResult(interp, "particle injection plane \"", 394 particlesName, "\" already exists.", (char *)NULL); 395 return TCL_ERROR; 396 396 } 397 397 particlesName = Tcl_GetHashKey(&_particlesTable, hPtr); … … 399 399 particlesPtr = new FlowParticles(particlesName, hPtr); 400 400 if (particlesPtr == NULL) { 401 402 403 404 401 Tcl_AppendResult(interp, "can't allocate particle injection plane", 402 (char *)NULL); 403 Tcl_DeleteHashEntry(hPtr); 404 return TCL_ERROR; 405 405 } 406 406 Tcl_SetHashValue(hPtr, particlesPtr); … … 410 410 int 411 411 FlowCmd::GetParticles(Tcl_Interp *interp, Tcl_Obj *objPtr, 412 412 FlowParticles **particlesPtrPtr) 413 413 { 414 414 Tcl_HashEntry *hPtr; 415 415 hPtr = Tcl_FindHashEntry(&_particlesTable, Tcl_GetString(objPtr)); 416 416 if (hPtr == NULL) { 417 418 419 420 421 417 if (interp != NULL) { 418 Tcl_AppendResult(interp, "can't find a particle injection plane \"", 419 Tcl_GetString(objPtr), "\"", (char *)NULL); 420 } 421 return TCL_ERROR; 422 422 } 423 423 *particlesPtrPtr = (FlowParticles *)Tcl_GetHashValue(hPtr); … … 429 429 { 430 430 iterPtr->hashPtr = Tcl_FirstHashEntry(&_particlesTable, 431 431 &iterPtr->hashSearch); 432 432 if (iterPtr->hashPtr == NULL) { 433 433 return NULL; 434 434 } 435 435 return (FlowParticles *)Tcl_GetHashValue(iterPtr->hashPtr); … … 440 440 { 441 441 if (iterPtr->hashPtr == NULL) { 442 442 return NULL; 443 443 } 444 444 iterPtr->hashPtr = Tcl_NextHashEntry(&iterPtr->hashSearch); 445 445 if (iterPtr->hashPtr == NULL) { 446 446 return NULL; 447 447 } 448 448 return (FlowParticles *)Tcl_GetHashValue(iterPtr->hashPtr); … … 456 456 hPtr = Tcl_CreateHashEntry(&_boxTable, Tcl_GetString(objPtr), &isNew); 457 457 if (!isNew) { 458 459 460 458 Tcl_AppendResult(interp, "box \"", Tcl_GetString(objPtr), 459 "\" already exists in flow \"", name(), "\"", (char *)NULL); 460 return TCL_ERROR; 461 461 } 462 462 const char *boxName; … … 465 465 boxPtr = new FlowBox(boxName, hPtr); 466 466 if (boxPtr == NULL) { 467 468 469 470 467 Tcl_AppendResult(interp, "can't allocate box \"", boxName, "\"", 468 (char *)NULL); 469 Tcl_DeleteHashEntry(hPtr); 470 return TCL_ERROR; 471 471 } 472 472 Tcl_SetHashValue(hPtr, boxPtr); … … 480 480 hPtr = Tcl_FindHashEntry(&_boxTable, Tcl_GetString(objPtr)); 481 481 if (hPtr == NULL) { 482 483 484 485 486 487 482 if (interp != NULL) { 483 Tcl_AppendResult(interp, "can't find a box \"", 484 Tcl_GetString(objPtr), "\" in flow \"", name(), "\"", 485 (char *)NULL); 486 } 487 return TCL_ERROR; 488 488 } 489 489 *boxPtrPtr = (FlowBox *)Tcl_GetHashValue(hPtr); … … 496 496 iterPtr->hashPtr = Tcl_FirstHashEntry(&_boxTable, &iterPtr->hashSearch); 497 497 if (iterPtr->hashPtr == NULL) { 498 498 return NULL; 499 499 } 500 500 return (FlowBox *)Tcl_GetHashValue(iterPtr->hashPtr); … … 505 505 { 506 506 if (iterPtr->hashPtr == NULL) { 507 507 return NULL; 508 508 } 509 509 iterPtr->hashPtr = Tcl_NextHashEntry(&iterPtr->hashSearch); 510 510 if (iterPtr->hashPtr == NULL) { 511 511 return NULL; 512 512 } 513 513 return (FlowBox *)Tcl_GetHashValue(iterPtr->hashPtr); 514 514 } 515 515 516 517 516 void 518 FlowCmd::InitializeParticles( void)517 FlowCmd::InitializeParticles() 519 518 { 520 519 FlowParticles *particlesPtr; 521 520 FlowParticlesIterator iter; 522 521 for (particlesPtr = FirstParticles(&iter); particlesPtr != NULL; 523 524 525 } 522 particlesPtr = NextParticles(&iter)) { 523 particlesPtr->Initialize(); 524 } 526 525 } 527 526 … … 530 529 { 531 530 if (_volPtr != NULL) { 532 533 534 531 TRACE("from ScaleVectorField volId=%s\n", _volPtr->name()); 532 NanoVis::remove_volume(_volPtr); 533 _volPtr = NULL; 535 534 } 536 535 float *vdata; 537 536 vdata = GetScaledVector(); 538 537 if (vdata == NULL) { 539 538 return false; 540 539 } 541 540 Volume *volPtr; … … 543 542 delete [] vdata; 544 543 if (volPtr == NULL) { 545 544 return false; 546 545 } 547 546 _volPtr = volPtr; … … 549 548 // Remove the associated vector field. 550 549 if (_fieldPtr != NULL) { 551 550 delete _fieldPtr; 552 551 } 553 552 _fieldPtr = new NvVectorField(); 554 553 if (_fieldPtr == NULL) { 555 554 return false; 556 555 } 557 556 … … 580 579 1.0f / _volPtr->aspect_ratio_depth, 581 580 _volPtr->wAxis.max()); 582 583 584 581 SetCurrentPosition(); 582 SetAxis(); 583 SetActive(); 585 584 } 586 585 … … 594 593 //,volPtr->wAxis.max() 595 594 ); 596 597 598 599 595 TRACE("Arrows enabled set to %d\n", _sv.showArrows); 596 NanoVis::velocityArrowsSlice->axis(_sv.slicePos.axis); 597 NanoVis::velocityArrowsSlice->slicePos(_sv.slicePos.value); 598 NanoVis::velocityArrowsSlice->enabled(_sv.showArrows); 600 599 } 601 600 FlowParticles *particlesPtr; 602 601 FlowParticlesIterator partIter; 603 602 for (particlesPtr = FirstParticles(&partIter); particlesPtr != NULL; 604 605 606 } 603 particlesPtr = NextParticles(&partIter)) { 604 particlesPtr->SetVectorField(_volPtr); 605 } 607 606 return true; 608 607 } 609 608 610 609 void 611 FlowCmd::RenderBoxes( void)610 FlowCmd::RenderBoxes() 612 611 { 613 612 FlowBoxIterator iter; 614 613 FlowBox *boxPtr; 615 614 for (boxPtr = FirstBox(&iter); boxPtr != NULL; boxPtr = NextBox(&iter)) { 616 617 618 619 615 TRACE("found box %s\n", boxPtr->name()); 616 if (boxPtr->visible()) { 617 boxPtr->Render(_volPtr); 618 } 620 619 } 621 620 } 622 621 623 622 float * 624 FlowCmd::GetScaledVector( void)623 FlowCmd::GetScaledVector() 625 624 { 626 625 assert(_dataPtr->nComponents() == 3); … … 628 627 float *data = new float[n]; 629 628 if (data == NULL) { 630 629 return NULL; 631 630 } 632 631 memset(data, 0, sizeof(float) * n); … … 634 633 const float *values = _dataPtr->values(); 635 634 for (size_t iz=0; iz < _dataPtr->zNum(); iz++) { 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 635 for (size_t iy=0; iy < _dataPtr->yNum(); iy++) { 636 for (size_t ix=0; ix < _dataPtr->xNum(); ix++) { 637 double vx, vy, vz, vm; 638 vx = values[0]; 639 vy = values[1]; 640 vz = values[2]; 641 vm = sqrt(vx*vx + vy*vy + vz*vz); 642 destPtr[0] = vm / NanoVis::magMax; 643 destPtr[1] = vx /(2.0*NanoVis::magMax) + 0.5; 644 destPtr[2] = vy /(2.0*NanoVis::magMax) + 0.5; 645 destPtr[3] = vz /(2.0*NanoVis::magMax) + 0.5; 646 values += 3; 647 destPtr += 4; 648 } 649 } 651 650 } 652 651 return data; … … 659 658 660 659 volPtr = NanoVis::load_volume(_name, _dataPtr->xNum(), _dataPtr->yNum(), 661 662 660 _dataPtr->zNum(), 4, data, 661 NanoVis::magMin, NanoVis::magMax, 0); 663 662 volPtr->xAxis.SetRange(_dataPtr->xMin(), _dataPtr->xMax()); 664 663 volPtr->yAxis.SetRange(_dataPtr->yMin(), _dataPtr->yMax()); … … 669 668 Vector3 physicalMax(NanoVis::xMax, NanoVis::yMax, NanoVis::zMax); 670 669 TRACE("min=%g %g %g max=%g %g %g mag=%g %g\n", 671 672 673 670 NanoVis::xMin, NanoVis::yMin, NanoVis::zMin, 671 NanoVis::xMax, NanoVis::yMax, NanoVis::zMax, 672 NanoVis::magMin, NanoVis::magMax); 674 673 volPtr->setPhysicalBBox(physicalMin, physicalMax); 675 674 //volPtr->set_n_slice(256 - _volIndex); … … 700 699 } 701 700 702 703 701 static int 704 702 FlowDataFileOp(ClientData clientData, Tcl_Interp *interp, int objc, 705 703 Tcl_Obj *const *objv) 706 704 { 707 705 Rappture::Outcome result; … … 716 714 } 717 715 if ((nComponents < 1) || (nComponents > 4)) { 718 719 720 716 Tcl_AppendResult(interp, "bad # of components \"", 717 Tcl_GetString(objv[4]), "\"", (char *)NULL); 718 return TCL_ERROR; 721 719 } 722 720 Rappture::Buffer buf; 723 721 if (!buf.load(result, fileName)) { 724 725 726 722 Tcl_AppendResult(interp, "can't load data from \"", fileName, "\": ", 723 result.remark(), (char *)NULL); 724 return TCL_ERROR; 727 725 } 728 726 … … 733 731 char *bytes = (char *)buf.bytes(); 734 732 if ((length > 4) && (strncmp(bytes, "<DX>", 4) == 0)) { 735 736 737 738 739 733 if (!dataPtr->ImportDx(result, nComponents, length-4, bytes+4)) { 734 Tcl_AppendResult(interp, result.remark(), (char *)NULL); 735 delete dataPtr; 736 return TCL_ERROR; 737 } 740 738 } else if ((length > 10) && (strncmp(bytes, "unirect3d ", 10) == 0)) { 741 742 743 744 739 if (dataPtr->ParseBuffer(interp, buf) != TCL_OK) { 740 delete dataPtr; 741 return TCL_ERROR; 742 } 745 743 } else if ((length > 10) && (strncmp(bytes, "unirect2d ", 10) == 0)) { 746 747 748 749 750 751 752 753 744 Rappture::Unirect2d *u2dPtr; 745 u2dPtr = new Rappture::Unirect2d(nComponents); 746 if (u2dPtr->ParseBuffer(interp, buf) != TCL_OK) { 747 delete u2dPtr; 748 return TCL_ERROR; 749 } 750 dataPtr->Convert(u2dPtr); 751 delete u2dPtr; 754 752 } else { 755 756 757 758 759 760 753 TRACE("header is %.14s\n", buf.bytes()); 754 if (!dataPtr->ImportDx(result, nComponents, length, bytes)) { 755 Tcl_AppendResult(interp, result.remark(), (char *)NULL); 756 delete dataPtr; 757 return TCL_ERROR; 758 } 761 759 } 762 760 if (dataPtr->nValues() == 0) { 763 764 765 766 761 delete dataPtr; 762 Tcl_AppendResult(interp, "no data found in \"", fileName, "\"", 763 (char *)NULL); 764 return TCL_ERROR; 767 765 } 768 766 flowPtr->data(dataPtr); … … 771 769 } 772 770 773 /* 771 /** 774 772 * $flow data follows nbytes nComponents 775 773 */ 776 774 static int 777 775 FlowDataFollowsOp(ClientData clientData, Tcl_Interp *interp, int objc, 778 776 Tcl_Obj *const *objv) 779 777 { 780 778 Rappture::Outcome result; … … 784 782 int nBytes; 785 783 if (Tcl_GetIntFromObj(interp, objv[3], &nBytes) != TCL_OK) { 786 784 ERROR("Bad nBytes \"%s\"\n", Tcl_GetString(objv[3])); 787 785 return TCL_ERROR; 788 786 } 789 787 if (nBytes <= 0) { 790 791 792 793 788 Tcl_AppendResult(interp, "bad # bytes request \"", 789 Tcl_GetString(objv[3]), "\" for \"data follows\"", (char *)NULL); 790 ERROR("Bad nbytes %d\n", nBytes); 791 return TCL_ERROR; 794 792 } 795 793 int nComponents; 796 794 if (Tcl_GetIntFromObj(interp, objv[4], &nComponents) != TCL_OK) { 797 795 ERROR("Bad # of components \"%s\"\n", Tcl_GetString(objv[4])); 798 796 return TCL_ERROR; 799 797 } 800 798 if (nComponents <= 0) { 801 802 803 804 799 Tcl_AppendResult(interp, "bad # of components request \"", 800 Tcl_GetString(objv[4]), "\" for \"data follows\"", (char *)NULL); 801 ERROR("Bad # of components %d\n", nComponents); 802 return TCL_ERROR; 805 803 } 806 804 Rappture::Buffer buf; … … 816 814 char *bytes = (char *)buf.bytes(); 817 815 if ((length > 4) && (strncmp(bytes, "<DX>", 4) == 0)) { 818 819 820 821 822 816 if (!dataPtr->ImportDx(result, nComponents, length - 4, bytes + 4)) { 817 Tcl_AppendResult(interp, result.remark(), (char *)NULL); 818 delete dataPtr; 819 return TCL_ERROR; 820 } 823 821 } else if ((length > 10) && (strncmp(bytes, "unirect3d ", 10) == 0)) { 824 825 826 827 822 if (dataPtr->ParseBuffer(interp, buf) != TCL_OK) { 823 delete dataPtr; 824 return TCL_ERROR; 825 } 828 826 } else if ((length > 10) && (strncmp(bytes, "unirect2d ", 10) == 0)) { 829 830 831 832 833 834 835 836 827 Rappture::Unirect2d *u2dPtr; 828 u2dPtr = new Rappture::Unirect2d(nComponents); 829 if (u2dPtr->ParseBuffer(interp, buf) != TCL_OK) { 830 delete u2dPtr; 831 return TCL_ERROR; 832 } 833 dataPtr->Convert(u2dPtr); 834 delete u2dPtr; 837 835 } else { 838 839 840 841 842 843 836 TRACE("header is %.14s\n", buf.bytes()); 837 if (!dataPtr->ImportDx(result, nComponents, length, bytes)) { 838 Tcl_AppendResult(interp, result.remark(), (char *)NULL); 839 delete dataPtr; 840 return TCL_ERROR; 841 } 844 842 } 845 843 if (dataPtr->nValues() == 0) { 846 847 848 844 delete dataPtr; 845 Tcl_AppendResult(interp, "no data found in stream", (char *)NULL); 846 return TCL_ERROR; 849 847 } 850 848 flowPtr->data(dataPtr); 851 849 { 852 850 char info[1024]; 853 854 851 ssize_t nWritten; 852 size_t length; 855 853 856 854 length = sprintf(info, "nv>data tag %s min %g max %g\n", 857 855 flowPtr->name(), dataPtr->magMin(), dataPtr->magMax()); 858 856 nWritten = write(1, info, length); 859 857 assert(nWritten == (ssize_t)strlen(info)); 860 858 } 861 859 NanoVis::EventuallyRedraw(NanoVis::MAP_FLOWS); … … 871 869 static int 872 870 FlowDataOp(ClientData clientData, Tcl_Interp *interp, int objc, 873 871 Tcl_Obj *const *objv) 874 872 { 875 873 Tcl_ObjCmdProc *proc; … … 887 885 { 888 886 if (posPtr->flags == RELPOS) { 889 887 return posPtr->value; 890 888 } 891 889 switch (posPtr->axis) { 892 890 case AXIS_X: 893 894 891 return (posPtr->value - NanoVis::xMin) / 892 (NanoVis::xMax - NanoVis::xMin); 895 893 case AXIS_Y: 896 897 894 return (posPtr->value - NanoVis::yMin) / 895 (NanoVis::yMax - NanoVis::yMin); 898 896 case AXIS_Z: 899 900 897 return (posPtr->value - NanoVis::zMin) / 898 (NanoVis::zMax - NanoVis::zMin); 901 899 } 902 900 return 0.0; … … 904 902 905 903 float 906 FlowCmd::GetRelativePosition( void)904 FlowCmd::GetRelativePosition() 907 905 { 908 906 return FlowCmd::GetRelativePosition(&_sv.slicePos); … … 912 910 913 911 void 914 NanoVis::InitFlows( void)912 NanoVis::InitFlows() 915 913 { 916 914 Tcl_InitHashTable(&flowTable, TCL_STRING_KEYS); … … 922 920 iterPtr->hashPtr = Tcl_FirstHashEntry(&flowTable, &iterPtr->hashSearch); 923 921 if (iterPtr->hashPtr == NULL) { 924 922 return NULL; 925 923 } 926 924 return (FlowCmd *)Tcl_GetHashValue(iterPtr->hashPtr); … … 931 929 { 932 930 if (iterPtr->hashPtr == NULL) { 933 931 return NULL; 934 932 } 935 933 iterPtr->hashPtr = Tcl_NextHashEntry(&iterPtr->hashSearch); 936 934 if (iterPtr->hashPtr == NULL) { 937 935 return NULL; 938 936 } 939 937 return (FlowCmd *)Tcl_GetHashValue(iterPtr->hashPtr); … … 946 944 hPtr = Tcl_FindHashEntry(&flowTable, Tcl_GetString(objPtr)); 947 945 if (hPtr == NULL) { 948 949 950 951 952 946 if (interp != NULL) { 947 Tcl_AppendResult(interp, "can't find a flow \"", 948 Tcl_GetString(objPtr), "\"", (char *)NULL); 949 } 950 return TCL_ERROR; 953 951 } 954 952 *flowPtrPtr = (FlowCmd *)Tcl_GetHashValue(hPtr); … … 965 963 hPtr = Tcl_CreateHashEntry(&flowTable, name, &isNew); 966 964 if (!isNew) { 967 968 969 965 Tcl_AppendResult(interp, "flow \"", name, "\" already exists.", 966 (char *)NULL); 967 return TCL_ERROR; 970 968 } 971 969 Tcl_CmdInfo cmdInfo; 972 970 if (Tcl_GetCommandInfo(interp, name, &cmdInfo)) { 973 974 975 976 } 971 Tcl_AppendResult(interp, "an another command \"", name, 972 "\" already exists.", (char *)NULL); 973 return TCL_ERROR; 974 } 977 975 FlowCmd *flowPtr; 978 976 name = Tcl_GetHashKey(&flowTable, hPtr); 979 977 flowPtr = new FlowCmd(interp, name, hPtr); 980 978 if (flowPtr == NULL) { 981 982 983 979 Tcl_AppendResult(interp, "can't allocate a flow object \"", name, 980 "\"", (char *)NULL); 981 return TCL_ERROR; 984 982 } 985 983 Tcl_SetHashValue(hPtr, flowPtr); … … 993 991 FlowIterator iter; 994 992 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 995 996 flowPtr->disconnect();/* Don't disrupt the hash walk */997 993 flowPtr = NextFlow(&iter)) { 994 flowPtr->disconnect(); /* Don't disrupt the hash walk */ 995 Tcl_DeleteCommand(interp, flowPtr->name()); 998 996 } 999 997 Tcl_DeleteHashTable(&flowTable); … … 1001 999 1002 1000 bool 1003 NanoVis::MapFlows( void)1001 NanoVis::MapFlows() 1004 1002 { 1005 1003 flags &= ~MAP_FLOWS; … … 1007 1005 1008 1006 /* 1009 * Step 1. 1010 * 1007 * Step 1. Get the overall min and max magnitudes of all the 1008 * flow vectors. 1011 1009 */ 1012 1010 magMin = DBL_MAX, magMax = -DBL_MAX; … … 1015 1013 FlowIterator iter; 1016 1014 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1015 flowPtr = NextFlow(&iter)) { 1016 double min, max; 1017 if (!flowPtr->isDataLoaded()) { 1018 continue; 1019 } 1020 Rappture::Unirect3d *dataPtr; 1021 dataPtr = flowPtr->data(); 1022 min = dataPtr->magMin(); 1023 max = dataPtr->magMax(); 1024 if (min < magMin) { 1025 magMin = min; 1026 } 1027 if (max > magMax) { 1028 magMax = max; 1029 } 1030 if (dataPtr->xMin() < xMin) { 1031 xMin = dataPtr->xMin(); 1032 } 1033 if (dataPtr->yMin() < yMin) { 1034 yMin = dataPtr->yMin(); 1035 } 1036 if (dataPtr->zMin() < zMin) { 1037 zMin = dataPtr->zMin(); 1038 } 1039 if (dataPtr->xMax() > xMax) { 1040 xMax = dataPtr->xMax(); 1041 } 1042 if (dataPtr->yMax() > yMax) { 1043 yMax = dataPtr->yMax(); 1044 } 1045 if (dataPtr->zMax() > zMax) { 1046 zMax = dataPtr->zMax(); 1047 } 1050 1048 } 1051 1049 TRACE("MapFlows magMin=%g magMax=%g\n", NanoVis::magMin, NanoVis::magMax); 1052 1050 1053 1051 /* 1054 * Step 2. 1052 * Step 2. Generate the vector field from each data set. 1055 1053 */ 1056 1054 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 1057 flowPtr = NextFlow(&iter)) { 1058 if (!flowPtr->isDataLoaded()) { 1059 continue; // Flow exists, but no data has 1060 // been loaded yet. 1061 } 1062 if (flowPtr->visible()) { 1063 flowPtr->InitializeParticles(); 1064 } 1065 if (!flowPtr->ScaleVectorField()) { 1066 return false; 1067 } 1068 // FIXME: This doesn't work when there is more than one flow. 1069 licRenderer->set_offset(flowPtr->GetRelativePosition()); 1055 flowPtr = NextFlow(&iter)) { 1056 if (!flowPtr->isDataLoaded()) { 1057 continue; // Flow exists, but no data has been loaded yet. 1058 } 1059 if (flowPtr->visible()) { 1060 flowPtr->InitializeParticles(); 1061 } 1062 if (!flowPtr->ScaleVectorField()) { 1063 return false; 1064 } 1065 // FIXME: This doesn't work when there is more than one flow. 1066 licRenderer->set_offset(flowPtr->GetRelativePosition()); 1070 1067 NanoVis::velocityArrowsSlice->slicePos(flowPtr->GetRelativePosition()); 1071 1068 … … 1076 1073 1077 1074 void 1078 NanoVis::RenderFlows( void)1075 NanoVis::RenderFlows() 1079 1076 { 1080 1077 FlowCmd *flowPtr; 1081 1078 FlowIterator iter; 1082 1079 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 1083 1084 1085 1086 1080 flowPtr = NextFlow(&iter)) { 1081 if ((flowPtr->isDataLoaded()) && (flowPtr->visible())) { 1082 flowPtr->Render(); 1083 } 1087 1084 } 1088 1085 flags &= ~REDRAW_PENDING; … … 1090 1087 1091 1088 void 1092 NanoVis::ResetFlows( void)1089 NanoVis::ResetFlows() 1093 1090 { 1094 1091 FlowCmd *flowPtr; … … 1096 1093 1097 1094 if (licRenderer->active()) { 1098 1095 NanoVis::licRenderer->reset(); 1099 1096 } 1100 1097 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 1101 1102 1103 1104 1098 flowPtr = NextFlow(&iter)) { 1099 if ((flowPtr->isDataLoaded()) && (flowPtr->visible())) { 1100 flowPtr->ResetParticles(); 1101 } 1105 1102 } 1106 1103 } 1107 1104 1108 1105 void 1109 NanoVis::AdvectFlows( void)1106 NanoVis::AdvectFlows() 1110 1107 { 1111 1108 FlowCmd *flowPtr; 1112 1109 FlowIterator iter; 1113 1110 for (flowPtr = FirstFlow(&iter); flowPtr != NULL; 1114 1115 1116 1117 1111 flowPtr = NextFlow(&iter)) { 1112 if ((flowPtr->isDataLoaded()) && (flowPtr->visible())) { 1113 flowPtr->Advect(); 1114 } 1118 1115 } 1119 1116 } 1120 1117 1121 /* 1122 *--------------------------------------------------------------------------- 1118 /** 1119 * \brief Convert a Tcl_Obj representing the label of a child node into its 1120 * integer node id. 1123 1121 * 1124 * AxisSwitchProc -- 1122 * \param clientData Flag indicating if the node is considered before or 1123 * after the insertion position. 1124 * \param interp Interpreter to send results back to 1125 * \param switchName Not used 1126 * \param objPtr String representation 1127 * \param record Structure record 1128 * \param offset Not used 1129 * \param flags Not used 1125 1130 * 1126 * Convert a Tcl_Obj representing the label of a child node into its 1127 * integer node id. 1128 * 1129 * Results: 1130 * The return value is a standard Tcl result. 1131 * 1132 *--------------------------------------------------------------------------- 1131 * \return The return value is a standard Tcl result. 1133 1132 */ 1134 /*ARGSUSED*/ 1135 static int 1136 AxisSwitchProc( 1137 ClientData clientData, /* Flag indicating if the node is considered 1138 * before or after the insertion position. */ 1139 Tcl_Interp *interp, /* Interpreter to send results back to */ 1140 const char *switchName, /* Not used. */ 1141 Tcl_Obj *objPtr, /* String representation */ 1142 char *record, /* Structure record */ 1143 int offset, /* Not used. */ 1144 int flags) /* Not used. */ 1133 static int 1134 AxisSwitchProc(ClientData clientData, Tcl_Interp *interp, 1135 const char *switchName, Tcl_Obj *objPtr, 1136 char *record, int offset, int flags) 1145 1137 { 1146 1138 const char *string = Tcl_GetString(objPtr); 1147 1139 if (string[1] == '\0') { 1148 1140 FlowCmd::SliceAxis *axisPtr = (FlowCmd::SliceAxis *)(record + offset); 1149 1141 char c; 1150 1142 c = tolower((unsigned char)string[0]); … … 1166 1158 } 1167 1159 1168 /* 1169 *--------------------------------------------------------------------------- 1160 /** 1161 * \brief Convert a Tcl_Obj representing the label of a list of four color 1162 * components in to a RGBA color value. 1170 1163 * 1171 * ColorSwitchProc -- 1172 * 1173 * Convert a Tcl_Obj representing the label of a list of four color 1174 * components in to a RGBA color value. 1175 * 1176 * Results: 1177 * The return value is a standard Tcl result. 1178 * 1179 *--------------------------------------------------------------------------- 1164 * \param clientData Flag indicating if the node is considered before or 1165 * after the insertion position. 1166 * \param interp Interpreter to send results back to 1167 * \param switchName Not used 1168 * \param objPtr String representation 1169 * \param record Structure record 1170 * \param offset Not used 1171 * \param flags Not used 1172 * 1173 * \return The return value is a standard Tcl result. 1180 1174 */ 1181 /*ARGSUSED*/ 1182 static int 1183 ColorSwitchProc( 1184 ClientData clientData, /* Flag indicating if the node is considered 1185 * before or after the insertion position. */ 1186 Tcl_Interp *interp, /* Interpreter to send results back to */ 1187 const char *switchName, /* Not used. */ 1188 Tcl_Obj *objPtr, /* String representation */ 1189 char *record, /* Structure record */ 1190 int offset, /* Not used. */ 1191 int flags) /* Not used. */ 1175 static int 1176 ColorSwitchProc(ClientData clientData, Tcl_Interp *interp, 1177 const char *switchName, Tcl_Obj *objPtr, 1178 char *record, int offset, int flags) 1192 1179 { 1193 1180 Tcl_Obj **objv; … … 1196 1183 1197 1184 if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { 1198 1185 return TCL_ERROR; 1199 1186 } 1200 1187 if ((objc < 3) || (objc > 4)) { 1201 1202 1203 1188 Tcl_AppendResult(interp, "wrong # of elements in color definition", 1189 (char *)NULL); 1190 return TCL_ERROR; 1204 1191 } 1205 1192 float values[4]; … … 1207 1194 values[3] = 1.0f; 1208 1195 for (i = 0; i < objc; i++) { 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 } 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 } 1222 1209 colorPtr->r = values[0]; 1223 1210 colorPtr->g = values[1]; … … 1227 1214 } 1228 1215 1229 /* 1230 * ---------------------------------------------------------------------------1216 /** 1217 * \brief Convert a Tcl_Obj representing the a 3-D coordinate into a point. 1231 1218 * 1232 * PointSwitchProc -- 1219 * \param clientData Flag indicating if the node is considered before or 1220 * after the insertion position. 1221 * \param interp Interpreter to send results back to 1222 * \param switchName Not used 1223 * \param objPtr String representation 1224 * \param record Structure record 1225 * \param offset Not used 1226 * \param flags Not used 1233 1227 * 1234 * Convert a Tcl_Obj representing the a 3-D coordinate into 1235 * a point. 1236 * 1237 * Results: 1238 * The return value is a standard Tcl result. 1239 * 1240 *--------------------------------------------------------------------------- 1228 * \return The return value is a standard Tcl result. 1241 1229 */ 1242 /*ARGSUSED*/ 1243 static int 1244 PointSwitchProc( 1245 ClientData clientData, /* Flag indicating if the node is considered 1246 * before or after the insertion position. */ 1247 Tcl_Interp *interp, /* Interpreter to send results back to */ 1248 const char *switchName, /* Not used. */ 1249 Tcl_Obj *objPtr, /* String representation */ 1250 char *record, /* Structure record */ 1251 int offset, /* Not used. */ 1252 int flags) /* Not used. */ 1230 static int 1231 PointSwitchProc(ClientData clientData, Tcl_Interp *interp, 1232 const char *switchName, Tcl_Obj *objPtr, 1233 char *record, int offset, int flags) 1253 1234 { 1254 1235 FlowPoint *pointPtr = (FlowPoint *)(record + offset); … … 1257 1238 1258 1239 if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { 1259 1240 return TCL_ERROR; 1260 1241 } 1261 1242 if (objc != 3) { 1262 1263 1264 1243 Tcl_AppendResult(interp, "wrong # of elements for box coordinates: " 1244 " should be \"x y z\"", (char *)NULL); 1245 return TCL_ERROR; 1265 1246 } 1266 1247 float values[3]; 1267 1248 int i; 1268 1249 for (i = 0; i < objc; i++) { 1269 1270 1271 1272 1273 1274 1275 } 1250 float value; 1251 1252 if (GetFloatFromObj(interp, objv[i], &value) != TCL_OK) { 1253 return TCL_ERROR; 1254 } 1255 values[i] = value; 1256 } 1276 1257 pointPtr->x = values[0]; 1277 1258 pointPtr->y = values[1]; … … 1280 1261 } 1281 1262 1282 /* 1283 * ---------------------------------------------------------------------------1263 /** 1264 * \brief Convert a Tcl_Obj representing the a 3-D coordinate into a point. 1284 1265 * 1285 * PositionSwitchProc -- 1266 * \param clientData Flag indicating if the node is considered before or 1267 * after the insertion position. 1268 * \param interp Interpreter to send results back to 1269 * \param switchName Not used 1270 * \param objPtr String representation 1271 * \param record Structure record 1272 * \param offset Not used 1273 * \param flags Not used 1286 1274 * 1287 * Convert a Tcl_Obj representing the a 3-D coordinate into 1288 * a point. 1289 * 1290 * Results: 1291 * The return value is a standard Tcl result. 1292 * 1293 *--------------------------------------------------------------------------- 1275 * \return The return value is a standard Tcl result. 1294 1276 */ 1295 /*ARGSUSED*/ 1296 static int 1297 PositionSwitchProc( 1298 ClientData clientData, /* Flag indicating if the node is considered 1299 * before or after the insertion position. */ 1300 Tcl_Interp *interp, /* Interpreter to send results back to */ 1301 const char *switchName, /* Not used. */ 1302 Tcl_Obj *objPtr, /* String representation */ 1303 char *record, /* Structure record */ 1304 int offset, /* Not used. */ 1305 int flags) /* Not used. */ 1277 static int 1278 PositionSwitchProc(ClientData clientData, Tcl_Interp *interp, 1279 const char *switchName, Tcl_Obj *objPtr, 1280 char *record, int offset, int flags) 1306 1281 { 1307 1282 FlowPosition *posPtr = (FlowPosition *)(record + offset); … … 1312 1287 p = strrchr((char *)string, '%'); 1313 1288 if (p == NULL) { 1314 1315 1316 1317 1318 1319 1320 1289 float value; 1290 1291 if (GetFloatFromObj(interp, objPtr, &value) != TCL_OK) { 1292 return TCL_ERROR; 1293 } 1294 posPtr->value = value; 1295 posPtr->flags = ABSPOS; 1321 1296 } else { 1322 double value; 1323 1324 *p = '\0'; 1325 if (Tcl_GetDouble(interp, string, &value) != TCL_OK) { 1326 return TCL_ERROR; 1327 } 1328 posPtr->value = (float)value * 0.01; 1329 posPtr->flags = RELPOS; 1330 } 1331 return TCL_OK; 1332 } 1333 1334 /* 1335 *--------------------------------------------------------------------------- 1297 double value; 1298 1299 *p = '\0'; 1300 if (Tcl_GetDouble(interp, string, &value) != TCL_OK) { 1301 return TCL_ERROR; 1302 } 1303 posPtr->value = (float)value * 0.01; 1304 posPtr->flags = RELPOS; 1305 } 1306 return TCL_OK; 1307 } 1308 1309 /** 1310 * \brief Convert a Tcl_Obj representing the transfer function into a 1311 * TransferFunction pointer. 1336 1312 * 1337 * T ransferFunctionSwitchProc --1313 * The transfer function must have been previously defined. 1338 1314 * 1339 * Convert a Tcl_Obj representing the transfer function into a 1340 * TransferFunction pointer. The transfer function must have been 1341 * previously defined. 1315 * \param clientData Flag indicating if the node is considered before or 1316 * after the insertion position. 1317 * \param interp Interpreter to send results back to 1318 * \param switchName Not used 1319 * \param objPtr String representation 1320 * \param record Structure record 1321 * \param offset Not used 1322 * \param flags Not used 1342 1323 * 1343 * Results: 1344 * The return value is a standard Tcl result. 1345 * 1346 *--------------------------------------------------------------------------- 1324 * \return The return value is a standard Tcl result. 1347 1325 */ 1348 /*ARGSUSED*/ 1349 static int 1350 TransferFunctionSwitchProc( 1351 ClientData clientData, /* Flag indicating if the node is considered 1352 * before or after the insertion position. */ 1353 Tcl_Interp *interp, /* Interpreter to send results back to */ 1354 const char *switchName, /* Not used. */ 1355 Tcl_Obj *objPtr, /* String representation */ 1356 char *record, /* Structure record */ 1357 int offset, /* Not used. */ 1358 int flags) /* Not used. */ 1326 static int 1327 TransferFunctionSwitchProc(ClientData clientData, Tcl_Interp *interp, 1328 const char *switchName, Tcl_Obj *objPtr, 1329 char *record, int offset, int flags) 1359 1330 { 1360 1331 TransferFunction **funcPtrPtr = (TransferFunction **)(record + offset); … … 1372 1343 static int 1373 1344 FlowConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, 1374 1345 Tcl_Obj *const *objv) 1375 1346 { 1376 1347 FlowCmd *flowPtr = (FlowCmd *)clientData; 1377 1348 1378 1349 if (flowPtr->ParseSwitches(interp, objc - 2, objv + 2) != TCL_OK) { 1379 1350 return TCL_ERROR; 1380 1351 } 1381 1352 NanoVis::EventuallyRedraw(NanoVis::MAP_FLOWS); … … 1385 1356 static int 1386 1357 FlowParticlesAddOp(ClientData clientData, Tcl_Interp *interp, int objc, 1387 1358 Tcl_Obj *const *objv) 1388 1359 { 1389 1360 FlowCmd *flowPtr = (FlowCmd *)clientData; 1390 1361 1391 1362 if (flowPtr->CreateParticles(interp, objv[3]) != TCL_OK) { 1392 1363 return TCL_ERROR; 1393 1364 } 1394 1365 FlowParticles *particlesPtr; 1395 1366 if (flowPtr->GetParticles(interp, objv[3], &particlesPtr) != TCL_OK) { 1396 1367 return TCL_ERROR; 1397 1368 } 1398 1369 if (particlesPtr->ParseSwitches(interp, objc - 4, objv + 4) != TCL_OK) { 1399 1400 1370 delete particlesPtr; 1371 return TCL_ERROR; 1401 1372 } 1402 1373 particlesPtr->Configure(); … … 1408 1379 static int 1409 1380 FlowParticlesConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, 1410 1381 Tcl_Obj *const *objv) 1411 1382 { 1412 1383 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1414 1385 FlowParticles *particlesPtr; 1415 1386 if (flowPtr->GetParticles(interp, objv[3], &particlesPtr) != TCL_OK) { 1416 1387 return TCL_ERROR; 1417 1388 } 1418 1389 if (particlesPtr->ParseSwitches(interp, objc - 4, objv + 4) != TCL_OK) { 1419 1390 return TCL_ERROR; 1420 1391 } 1421 1392 particlesPtr->Configure(); … … 1426 1397 static int 1427 1398 FlowParticlesDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, 1428 1399 Tcl_Obj *const *objv) 1429 1400 { 1430 1401 FlowCmd *flowPtr = (FlowCmd *)clientData; 1431 1402 int i; 1432 1403 for (i = 3; i < objc; i++) { 1433 1434 1435 1436 1437 1404 FlowParticles *particlesPtr; 1405 1406 if (flowPtr->GetParticles(NULL, objv[i], &particlesPtr) == TCL_OK) { 1407 delete particlesPtr; 1408 } 1438 1409 } 1439 1410 NanoVis::EventuallyRedraw(); … … 1443 1414 static int 1444 1415 FlowParticlesNamesOp(ClientData clientData, Tcl_Interp *interp, int objc, 1445 1416 Tcl_Obj *const *objv) 1446 1417 { 1447 1418 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1451 1422 FlowParticles *particlesPtr; 1452 1423 for (particlesPtr = flowPtr->FirstParticles(&iter); particlesPtr != NULL; 1453 1454 1455 1456 1457 1424 particlesPtr = flowPtr->NextParticles(&iter)) { 1425 Tcl_Obj *objPtr; 1426 1427 objPtr = Tcl_NewStringObj(particlesPtr->name(), -1); 1428 Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); 1458 1429 } 1459 1430 Tcl_SetObjResult(interp, listObjPtr); … … 1461 1432 } 1462 1433 1463 /*1464 *---------------------------------------------------------------------------1465 *1466 * FlowParticlesObjCmd --1467 *1468 * This procedure is invoked to process commands on behalf of the flow1469 * object.1470 *1471 * Results:1472 * A standard Tcl result.1473 *1474 * Side effects:1475 * See the user documentation.1476 *1477 * $flow particles oper $name1478 *---------------------------------------------------------------------------1479 */1480 1434 static Rappture::CmdSpec flowParticlesOps[] = { 1481 1435 {"add", 1, FlowParticlesAddOp, 4, 0, "name ?switches?",}, 1482 1436 {"configure", 1, FlowParticlesConfigureOp, 4, 0, "name ?switches?",}, 1483 {"delete", 1437 {"delete", 1, FlowParticlesDeleteOp, 4, 0, "?name...?"}, 1484 1438 {"names", 1, FlowParticlesNamesOp, 3, 4, "?pattern?"}, 1485 1439 }; … … 1487 1441 static int nFlowParticlesOps = NumCmdSpecs(flowParticlesOps); 1488 1442 1443 /** 1444 * \brief This procedure is invoked to process commands on behalf of the flow 1445 * object. 1446 * 1447 * Side effects: See the user documentation. 1448 * 1449 * $flow particles oper $name 1450 * 1451 * \return A standard Tcl result. 1452 */ 1489 1453 static int 1490 1454 FlowParticlesOp(ClientData clientData, Tcl_Interp *interp, int objc, 1491 1455 Tcl_Obj *const *objv) 1492 1456 { 1493 1457 Tcl_ObjCmdProc *proc; 1494 1458 proc = Rappture::GetOpFromObj(interp, nFlowParticlesOps, flowParticlesOps, 1495 1459 Rappture::CMDSPEC_ARG2, objc, objv, 0); 1496 1460 if (proc == NULL) { 1497 1461 return TCL_ERROR; 1498 1462 } 1499 1463 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1507 1471 static int 1508 1472 FlowBoxAddOp(ClientData clientData, Tcl_Interp *interp, int objc, 1509 1473 Tcl_Obj *const *objv) 1510 1474 { 1511 1475 FlowCmd *flowPtr = (FlowCmd *)clientData; 1512 1476 1513 1477 if (flowPtr->CreateBox(interp, objv[3]) != TCL_OK) { 1514 1478 return TCL_ERROR; 1515 1479 } 1516 1480 FlowBox *boxPtr; 1517 1481 if (flowPtr->GetBox(interp, objv[3], &boxPtr) != TCL_OK) { 1518 1482 return TCL_ERROR; 1519 1483 } 1520 1484 if (boxPtr->ParseSwitches(interp, objc - 4, objv + 4) != TCL_OK) { 1521 1522 1485 delete boxPtr; 1486 return TCL_ERROR; 1523 1487 } 1524 1488 NanoVis::EventuallyRedraw(); … … 1529 1493 static int 1530 1494 FlowBoxDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, 1531 1495 Tcl_Obj *const *objv) 1532 1496 { 1533 1497 FlowCmd *flowPtr = (FlowCmd *)clientData; 1534 1498 int i; 1535 1499 for (i = 3; i < objc; i++) { 1536 1537 1538 1539 1540 1500 FlowBox *boxPtr; 1501 1502 if (flowPtr->GetBox(NULL, objv[i], &boxPtr) == TCL_OK) { 1503 delete boxPtr; 1504 } 1541 1505 } 1542 1506 NanoVis::EventuallyRedraw(); … … 1546 1510 static int 1547 1511 FlowBoxNamesOp(ClientData clientData, Tcl_Interp *interp, int objc, 1548 Tcl_Obj *const *objv)1512 Tcl_Obj *const *objv) 1549 1513 { 1550 1514 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1554 1518 FlowBox *boxPtr; 1555 1519 for (boxPtr = flowPtr->FirstBox(&iter); boxPtr != NULL; 1556 1557 1558 1559 1560 1520 boxPtr = flowPtr->NextBox(&iter)) { 1521 Tcl_Obj *objPtr; 1522 1523 objPtr = Tcl_NewStringObj(boxPtr->name(), -1); 1524 Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); 1561 1525 } 1562 1526 Tcl_SetObjResult(interp, listObjPtr); … … 1566 1530 static int 1567 1531 FlowBoxConfigureOp(ClientData clientData, Tcl_Interp *interp, int objc, 1568 1532 Tcl_Obj *const *objv) 1569 1533 { 1570 1534 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1572 1536 FlowBox *boxPtr; 1573 1537 if (flowPtr->GetBox(interp, objv[3], &boxPtr) != TCL_OK) { 1574 1538 return TCL_ERROR; 1575 1539 } 1576 1540 if (boxPtr->ParseSwitches(interp, objc - 4, objv + 4) != TCL_OK) { 1577 1541 return TCL_ERROR; 1578 1542 } 1579 1543 NanoVis::EventuallyRedraw(); … … 1581 1545 } 1582 1546 1583 /*1584 *---------------------------------------------------------------------------1585 *1586 * FlowBoxOp--1587 *1588 * This procedure is invoked to process commands on behalf of the flow1589 * object.1590 *1591 * Results:1592 * A standard Tcl result.1593 *1594 * Side effects:1595 * See the user documentation.1596 *1597 *---------------------------------------------------------------------------1598 */1599 1547 static Rappture::CmdSpec flowBoxOps[] = { 1600 1548 {"add", 1, FlowBoxAddOp, 4, 0, "name ?switches?",}, 1601 1549 {"configure", 1, FlowBoxConfigureOp, 4, 0, "name ?switches?",}, 1602 {"delete", 1550 {"delete", 1, FlowBoxDeleteOp, 3, 0, "?name...?"}, 1603 1551 {"names", 1, FlowBoxNamesOp, 3, 0, "?pattern?"}, 1604 1552 }; … … 1606 1554 static int nFlowBoxOps = NumCmdSpecs(flowBoxOps); 1607 1555 1556 /** 1557 * \brief This procedure is invoked to process commands on behalf of the flow 1558 * object. 1559 * 1560 * Side effects: See the user documentation. 1561 * 1562 * \return A standard Tcl result. 1563 */ 1608 1564 static int 1609 1565 FlowBoxOp(ClientData clientData, Tcl_Interp *interp, int objc, 1610 1566 Tcl_Obj *const *objv) 1611 1567 { 1612 1568 Tcl_ObjCmdProc *proc; 1613 1569 proc = Rappture::GetOpFromObj(interp, nFlowBoxOps, flowBoxOps, 1614 1570 Rappture::CMDSPEC_ARG2, objc, objv, 0); 1615 1571 if (proc == NULL) { 1616 1572 return TCL_ERROR; 1617 1573 } 1618 1574 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1625 1581 1626 1582 /* 1627 * ----------------------------------------------------------------------1628 1583 * CLIENT COMMAND: 1629 1584 * $flow legend <width> <height> … … 1633 1588 * to one, drawn in the given transfer function. The resulting image 1634 1589 * is returned in the size <width> x <height>. 1635 * ----------------------------------------------------------------------1636 1590 */ 1637 1591 static int 1638 1592 FlowLegendOp(ClientData clientData, Tcl_Interp *interp, int objc, 1639 1593 Tcl_Obj *const *objv) 1640 1594 { 1641 1595 FlowCmd *flowPtr = (FlowCmd *)clientData; … … 1646 1600 if (tf == NULL) { 1647 1601 Tcl_AppendResult(interp, "unknown transfer function \"", string, "\"", 1648 1602 (char*)NULL); 1649 1603 return TCL_ERROR; 1650 1604 } … … 1663 1617 } 1664 1618 1665 /*1666 *---------------------------------------------------------------------------1667 *1668 * FlowInstObjCmd --1669 *1670 * This procedure is invoked to process commands on behalf of the flow1671 * object.1672 *1673 * Results:1674 * A standard Tcl result.1675 *1676 * Side effects:1677 * See the user documentation.1678 *1679 *---------------------------------------------------------------------------1680 */1681 1619 static Rappture::CmdSpec flowInstOps[] = { 1682 1620 {"box", 1, FlowBoxOp, 2, 0, "oper ?args?"}, 1683 1621 {"configure", 1, FlowConfigureOp, 2, 0, "?switches?"}, 1684 {"data", 1622 {"data", 1, FlowDataOp, 2, 0, "oper ?args?"}, 1685 1623 {"legend", 1, FlowLegendOp, 4, 4, "w h"}, 1686 1624 {"particles", 1, FlowParticlesOp, 2, 0, "oper ?args?"} … … 1688 1626 static int nFlowInstOps = NumCmdSpecs(flowInstOps); 1689 1627 1628 /** 1629 * \brief This procedure is invoked to process commands on behalf of the flow 1630 * object. 1631 * 1632 * Side effects: See the user documentation. 1633 * 1634 * \return A standard Tcl result. 1635 */ 1690 1636 static int 1691 1637 FlowInstObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, 1692 1638 Tcl_Obj *const *objv) 1693 1639 { 1694 1640 Tcl_ObjCmdProc *proc; 1695 1641 proc = Rappture::GetOpFromObj(interp, nFlowInstOps, flowInstOps, 1696 1642 Rappture::CMDSPEC_ARG1, objc, objv, 0); 1697 1643 if (proc == NULL) { 1698 1644 return TCL_ERROR; 1699 1645 } 1700 1646 assert(CheckGL(AT)); … … 1707 1653 } 1708 1654 1709 /* 1710 * ---------------------------------------------------------------------------1655 /** 1656 * \brief Deletes the command associated with the tree. 1711 1657 * 1712 * FlowInstDeleteProc -- 1713 * 1714 * Deletes the command associated with the tree. This is called only 1715 * when the command associated with the tree is destroyed. 1716 * 1717 * Results: 1718 * None. 1719 * 1720 *--------------------------------------------------------------------------- 1658 * This is called only when the command associated with the tree is destroyed. 1721 1659 */ 1722 1660 static void … … 1727 1665 } 1728 1666 1729 /*1730 *---------------------------------------------------------------------------1731 *1732 * FlowAddOp --1733 *1734 *---------------------------------------------------------------------------1735 */1736 /*ARGSUSED*/1737 1667 static int 1738 1668 FlowAddOp(ClientData clientData, Tcl_Interp *interp, int objc, 1739 1669 Tcl_Obj *const *objv) 1740 1670 { 1741 1671 if (NanoVis::CreateFlow(interp, objv[2]) != TCL_OK) { 1742 1672 return TCL_ERROR; 1743 1673 } 1744 1674 FlowCmd *flowPtr; 1745 1675 if (NanoVis::GetFlow(interp, objv[2], &flowPtr) != TCL_OK) { 1746 1676 return TCL_ERROR; 1747 1677 } 1748 1678 if (flowPtr->ParseSwitches(interp, objc - 3, objv + 3) != TCL_OK) { 1749 1750 1679 Tcl_DeleteCommand(interp, flowPtr->name()); 1680 return TCL_ERROR; 1751 1681 } 1752 1682 Tcl_SetObjResult(interp, objv[2]); … … 1755 1685 } 1756 1686 1757 /*1758 *---------------------------------------------------------------------------1759 *1760 * FlowDeleteOp --1761 *1762 *---------------------------------------------------------------------------1763 */1764 /*ARGSUSED*/1765 1687 static int 1766 1688 FlowDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc, 1767 1689 Tcl_Obj *const *objv) 1768 1690 { 1769 1691 int i; 1770 1692 1771 1693 for (i = 2; i < objc; i++) { 1772 1773 1774 1775 1776 1777 1694 FlowCmd *flowPtr; 1695 1696 if (NanoVis::GetFlow(interp, objv[i], &flowPtr) != TCL_OK) { 1697 return TCL_ERROR; 1698 } 1699 Tcl_DeleteCommand(interp, flowPtr->name()); 1778 1700 } 1779 1701 NanoVis::EventuallyRedraw(NanoVis::MAP_FLOWS); … … 1781 1703 } 1782 1704 1783 /*1784 *---------------------------------------------------------------------------1785 *1786 * FlowExistsOp --1787 *1788 *---------------------------------------------------------------------------1789 */1790 /*ARGSUSED*/1791 1705 static int 1792 1706 FlowExistsOp(ClientData clientData, Tcl_Interp *interp, int objc, 1793 1707 Tcl_Obj *const *objv) 1794 1708 { 1795 1709 bool value; … … 1798 1712 value = false; 1799 1713 if (NanoVis::GetFlow(NULL, objv[2], &flowPtr) == TCL_OK) { 1800 1714 value = true; 1801 1715 } 1802 1716 Tcl_SetBooleanObj(Tcl_GetObjResult(interp), (int)value); … … 1804 1718 } 1805 1719 1806 /* 1807 *--------------------------------------------------------------------------- 1808 * 1809 * FlowGotoOp -- 1810 * 1811 * flow goto number 1812 * 1813 *--------------------------------------------------------------------------- 1720 /** 1721 * \brief flow goto number 1814 1722 */ 1815 1723 static int 1816 1724 FlowGotoOp(ClientData clientData, Tcl_Interp *interp, int objc, 1817 1725 Tcl_Obj *const *objv) 1818 1726 { 1819 1727 int nSteps; … … 1822 1730 } 1823 1731 if ((nSteps < 0) || (nSteps > SHRT_MAX)) { 1824 1825 1826 1732 Tcl_AppendResult(interp, "flow goto: bad # of steps \"", 1733 Tcl_GetString(objv[2]), "\"", (char *)NULL); 1734 return TCL_ERROR; 1827 1735 } 1828 1736 NanoVis::ResetFlows(); 1829 1737 if (NanoVis::flags & NanoVis::MAP_FLOWS) { 1830 1738 NanoVis::MapFlows(); 1831 1739 } 1832 1740 int i; 1833 1741 NanoVis::AdvectFlows(); 1834 1742 for (i = 0; i < nSteps; i++) { 1835 1836 1837 1838 1743 if (NanoVis::licRenderer->active()) { 1744 NanoVis::licRenderer->convolve(); 1745 } 1746 NanoVis::AdvectFlows(); 1839 1747 } 1840 1748 NanoVis::EventuallyRedraw(); … … 1842 1750 } 1843 1751 1844 /*1845 *---------------------------------------------------------------------------1846 *1847 * FlowNamesOp --1848 *1849 *---------------------------------------------------------------------------1850 */1851 /*ARGSUSED*/1852 1752 static int 1853 1753 FlowNamesOp(ClientData clientData, Tcl_Interp *interp, int objc, 1854 1754 Tcl_Obj *const *objv) 1855 1755 { 1856 1756 Tcl_Obj *listObjPtr; … … 1859 1759 FlowIterator iter; 1860 1760 for (flowPtr = NanoVis::FirstFlow(&iter); flowPtr != NULL; 1861 1862 1863 1864 1865 1761 flowPtr = NanoVis::NextFlow(&iter)) { 1762 Tcl_Obj *objPtr; 1763 1764 objPtr = Tcl_NewStringObj(flowPtr->name(), -1); 1765 Tcl_ListObjAppendElement(interp, listObjPtr, objPtr); 1866 1766 } 1867 1767 Tcl_SetObjResult(interp, listObjPtr); … … 1871 1771 static int 1872 1772 FlowNextOp(ClientData clientData, Tcl_Interp *interp, int objc, 1873 1773 Tcl_Obj *const *objv) 1874 1774 { 1875 1775 assert(NanoVis::licRenderer != NULL); 1876 1776 if (NanoVis::flags & NanoVis::MAP_FLOWS) { 1877 1777 NanoVis::MapFlows(); 1878 1778 } 1879 1779 NanoVis::EventuallyRedraw(); … … 1885 1785 static int 1886 1786 FlowResetOp(ClientData clientData, Tcl_Interp *interp, int objc, 1887 1787 Tcl_Obj *const *objv) 1888 1788 { 1889 1789 NanoVis::ResetFlows(); … … 1893 1793 #ifdef HAVE_FFMPEG 1894 1794 1895 /* 1896 *--------------------------------------------------------------------------- 1795 /** 1796 * \brief Convert a Tcl_Obj representing the video format into its 1797 * integer id. 1897 1798 * 1898 * VideoFormatSwitchProc -- 1799 * \param clientData Not used 1800 * \param interp Interpreter to send results back to 1801 * \param switchName Not used 1802 * \param objPtr String representation 1803 * \param record Structure record 1804 * \param offset Not used 1805 * \param flags Not used 1899 1806 * 1900 * Convert a Tcl_Obj representing the video format into its 1901 * integer id. 1902 * 1903 * Results: 1904 * The return value is a standard Tcl result. 1905 * 1906 *--------------------------------------------------------------------------- 1807 * \return The return value is a standard Tcl result. 1907 1808 */ 1908 /*ARGSUSED*/ 1909 static int 1910 VideoFormatSwitchProc( 1911 ClientData clientData, /* Not used. */ 1912 Tcl_Interp *interp, /* Interpreter to send results back to */ 1913 const char *switchName, /* Not used. */ 1914 Tcl_Obj *objPtr, /* String representation */ 1915 char *record, /* Structure record */ 1916 int offset, /* Not used. */ 1917 int flags) /* Not used. */ 1809 static int 1810 VideoFormatSwitchProc(ClientData clientData, Tcl_Interp *interp, 1811 const char *switchName, Tcl_Obj *objPtr, 1812 char *record, int offset, int flags) 1918 1813 { 1919 1814 Rappture::AVTranslate::VideoFormats *formatPtr = 1920 1815 (Rappture::AVTranslate::VideoFormats *)(record + offset); 1921 1816 const char *string; 1922 1817 char c; … … 1925 1820 c = string[0]; 1926 1821 if ((c == 'm') && (strcmp(string, "mpeg") == 0)) { 1927 1822 *formatPtr = Rappture::AVTranslate::MPEG1; 1928 1823 } else if ((c == 't') && (strcmp(string, "theora") == 0)) { 1929 1824 *formatPtr = Rappture::AVTranslate::THEORA; 1930 1825 } else if ((c == 'm') && (strcmp(string, "mov") == 0)) { 1931 1826 *formatPtr = Rappture::AVTranslate::QUICKTIME; 1932 1827 } else { 1933 1934 "\": should be mpeg, theora, or mov", (char*)NULL);1828 Tcl_AppendResult(interp, "bad video format \"", string, 1829 "\": should be mpeg, theora, or mov", (char*)NULL); 1935 1830 } 1936 1831 return TCL_ERROR; … … 1938 1833 1939 1834 struct FlowVideoValues { 1940 float frameRate; /*Frame rate */1941 int bitRate; /*Video bitrate */1942 int width, height; /*Dimensions of video frame. */1835 float frameRate; /**< Frame rate */ 1836 int bitRate; /**< Video bitrate */ 1837 int width, height; /**< Dimensions of video frame. */ 1943 1838 int nFrames; 1944 1839 Rappture::AVTranslate::VideoFormats format; … … 1952 1847 Rappture::SwitchSpec FlowCmd::videoSwitches[] = { 1953 1848 {Rappture::SWITCH_INT, "-bitrate", "value", 1954 1849 offsetof(FlowVideoValues, bitRate), 0}, 1955 1850 {Rappture::SWITCH_CUSTOM, "-format", "string", 1956 1851 offsetof(FlowVideoValues, format), 0, 0, &videoFormatSwitch}, 1957 1852 {Rappture::SWITCH_FLOAT, "-framerate", "value", 1958 1853 offsetof(FlowVideoValues, frameRate), 0}, 1959 1854 {Rappture::SWITCH_INT, "-height", "integer", 1960 1855 offsetof(FlowVideoValues, height), 0}, 1961 1856 {Rappture::SWITCH_INT, "-numframes", "count", 1962 1857 offsetof(FlowVideoValues, nFrames), 0}, 1963 1858 {Rappture::SWITCH_INT, "-width", "integer", 1964 1859 offsetof(FlowVideoValues, width), 0}, 1965 1860 {Rappture::SWITCH_END} 1966 1861 }; … … 1968 1863 static int 1969 1864 FlowVideoOp(ClientData clientData, Tcl_Interp *interp, int objc, 1970 1865 Tcl_Obj *const *objv) 1971 1866 { 1972 1867 struct pollfd pollResults; … … 1976 1871 pollResults.events = POLLIN; 1977 1872 1978 #define PENDING_TIMEOUT 1873 #define PENDING_TIMEOUT 10 /* milliseconds. */ 1979 1874 timeout = PENDING_TIMEOUT; 1980 1875 … … 1983 1878 1984 1879 token = Tcl_GetString(objv[2]); 1985 values.frameRate = 25.0f; 1986 values.bitRate = 6000000; 1880 values.frameRate = 25.0f; // Default frame rate 25 fps 1881 values.bitRate = 6000000; // Default video bit rate. 1987 1882 values.width = NanoVis::win_width; 1988 1883 values.height = NanoVis::win_height; … … 1990 1885 values.format = Rappture::AVTranslate::MPEG1; 1991 1886 if (Rappture::ParseSwitches(interp, FlowCmd::videoSwitches, 1992 1993 1887 objc - 3, objv + 3, &values, SWITCH_DEFAULTS) < 0) { 1888 return TCL_ERROR; 1994 1889 } 1995 1890 if ((values.width < 0) || (values.width > SHRT_MAX) || 1996 1997 1998 1891 (values.height < 0) || (values.height > SHRT_MAX)) { 1892 Tcl_AppendResult(interp, "bad dimensions for video", (char *)NULL); 1893 return TCL_ERROR; 1999 1894 } 2000 1895 if ((values.frameRate < 0.0f) || (values.frameRate > 30.0f)) { 2001 2002 1896 Tcl_AppendResult(interp, "bad frame rate.", (char *)NULL); 1897 return TCL_ERROR; 2003 1898 } 2004 1899 if (values.bitRate < 0) { 2005 2006 1900 Tcl_AppendResult(interp, "bad bit rate.", (char *)NULL); 1901 return TCL_ERROR; 2007 1902 } 2008 1903 if (NanoVis::licRenderer == NULL) { 2009 2010 1904 Tcl_AppendResult(interp, "no lic renderer.", (char *)NULL); 1905 return TCL_ERROR; 2011 1906 } 2012 1907 // Save the old dimensions of the offscreen buffer. … … 2026 1921 if (!movie.init(context, tmpFileName)) { 2027 1922 Tcl_AppendResult(interp, "can't initialized movie \"", tmpFileName, 2028 2029 1923 "\": ", context.remark(), (char *)NULL); 1924 return TCL_ERROR; 2030 1925 } 2031 1926 if ((values.width != oldWidth) || (values.height != oldHeight)) { 2032 2033 1927 // Resize to the requested size. 1928 NanoVis::resize_offscreen_buffer(values.width, values.height); 2034 1929 } 2035 1930 // Now compute the line padding for the offscreen buffer. … … 2041 1936 bool canceled = false; 2042 1937 for (int i = 1; i <= values.nFrames; i++) { 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 1938 if (((i & 0xF) == 0) && (poll(&pollResults, 1, 0) > 0)) { 1939 /* If there's another command on stdin, that means the client is 1940 * trying to cancel this operation. */ 1941 canceled = true; 1942 break; 1943 } 1944 if (NanoVis::licRenderer->active()) { 1945 NanoVis::licRenderer->convolve(); 1946 } 1947 NanoVis::AdvectFlows(); 1948 NanoVis::offscreen_buffer_capture(); 2054 1949 NanoVis::display(); 2055 1950 NanoVis::read_screen(); … … 2060 1955 TRACE("FLOW end\n"); 2061 1956 if (!canceled) { 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 1957 Rappture::Buffer data; 1958 1959 /* FIXME: find a way to get the data from the movie object as a 1960 * void* */ 1961 if (!data.load(context, tmpFileName)) { 1962 Tcl_AppendResult(interp, "can't load data from temporary file \"", 1963 tmpFileName, "\": ", context.remark(), (char *)NULL); 1964 return TCL_ERROR; 1965 } 1966 1967 char command[200]; 1968 sprintf(command,"nv>image -bytes %lu -type movie -token \"%s\"\n", 1969 (unsigned long)data.size(), token); 1970 NanoVis::sendDataToClient(command, data.bytes(), data.size()); 2076 1971 } 2077 1972 if ((values.width != oldWidth) || (values.height != oldHeight)) { 2078 1973 NanoVis::resize_offscreen_buffer(oldWidth, oldHeight); 2079 1974 } 2080 1975 NanoVis::ResetFlows(); 2081 1976 if (unlink(tmpFileName) != 0) { 2082 1977 Tcl_AppendResult(interp, "can't unlink temporary movie file \"", 2083 2084 1978 tmpFileName, "\": ", Tcl_PosixError(interp), (char *)NULL); 1979 return TCL_ERROR; 2085 1980 } 2086 1981 return TCL_OK; 2087 1982 } 2088 1983 #else 1984 /** 1985 * Not implemented 1986 */ 2089 1987 static int 2090 1988 FlowVideoOp(ClientData clientData, Tcl_Interp *interp, int objc, 2091 Tcl_Obj *const *objv) 2092 { 2093 return TCL_OK; /* Not implemented */ 2094 } 2095 #endif /* HAVE_FFMPEG */ 2096 2097 /* 2098 *--------------------------------------------------------------------------- 2099 * 2100 * FlowObjCmd -- 2101 * 2102 *--------------------------------------------------------------------------- 2103 */ 1989 Tcl_Obj *const *objv) 1990 { 1991 return TCL_OK; 1992 } 1993 #endif /* HAVE_FFMPEG */ 1994 2104 1995 static Rappture::CmdSpec flowCmdOps[] = { 2105 1996 {"add", 1, FlowAddOp, 3, 0, "name ?option value...?",}, … … 2114 2005 static int nFlowCmdOps = NumCmdSpecs(flowCmdOps); 2115 2006 2116 /*ARGSUSED*/2117 2007 static int 2118 2008 FlowCmdProc(ClientData clientData, Tcl_Interp *interp, int objc, 2119 2009 Tcl_Obj *const *objv) 2120 2010 { 2121 2011 Tcl_ObjCmdProc *proc; 2122 2012 2123 2013 proc = Rappture::GetOpFromObj(interp, nFlowCmdOps, flowCmdOps, 2124 2014 Rappture::CMDSPEC_ARG1, objc, objv, 0); 2125 2015 if (proc == NULL) { 2126 2016 return TCL_ERROR; 2127 2017 } 2128 2018 return (*proc) (clientData, interp, objc, objv); 2129 2019 } 2130 2020 2131 /* 2132 *--------------------------------------------------------------------------- 2133 * 2134 * FlowCmdInitProc -- 2135 * 2136 * This procedure is invoked to initialize the "tree" command. 2137 * 2138 * Results: 2139 * None. 2021 /** 2022 *\brief This procedure is invoked to initialize the "tree" command. 2140 2023 * 2141 2024 * Side effects: 2142 * Creates the new command and adds a new entry into a global Tcl 2143 * associative array. 2144 * 2145 *--------------------------------------------------------------------------- 2025 * Creates the new command and adds a new entry into a global Tcl 2026 * associative array. 2146 2027 */ 2147 2028 int … … 2153 2034 } 2154 2035 2155 2156 2036 #ifdef notdef 2157 2037 … … 2162 2042 char *p, *endPtr; 2163 2043 2164 line = getline(&p, endPtr); 2165 if (line == endPtr) { 2166 vtkErrorMacro(<<"Premature EOF reading first line! " << " for file: " 2167 << (this->FileName?this->FileName:"(Null FileName)")); 2168 return false; 2169 } 2170 if (sscanf(line, "# vtk DataFile Version %s", version) != 1) { 2171 vtkErrorMacro(<< "Unrecognized file type: "<< line << " for file: " 2172 << (this->FileName?this->FileName:"(Null FileName)")); 2173 return false; 2174 } 2175 // Read title 2176 line = getline(&p, endPtr); 2177 if (line == endPtr) { 2178 vtkErrorMacro(<<"Premature EOF reading title! " << " for file: " 2179 << (this->FileName?this->FileName:"(Null FileName)")); 2180 return false; 2181 } 2182 if (_title != NULL) { 2183 delete [] _title; 2184 } 2185 _title = new char[strlen(line) + 1]; 2186 strcpy(_title, line); 2187 2188 // Read type 2189 line = getline(&p, endPtr); 2190 if (line == endPtr) { 2191 vtkErrorMacro(<<"Premature EOF reading file type!" << " for file: " 2192 << (this->FileName?this->FileName:"(Null FileName)")); 2193 return false; 2194 } 2195 word = GetWord(line, &endPtr); 2196 if (strncasecmp(word, "ascii", 5) == 0) { 2197 _fileType = VTK_ASCII; 2198 } else if (strcasecmp(word, "binary", 6) == 0) { 2199 _fileType = VTK_BINARY; 2200 } else { 2201 vtkErrorMacro(<< "Unrecognized file type: "<< line << " for file: " 2202 << (this->FileName?this->FileName:"(Null FileName)")); 2203 _fileType = 0; 2204 return false; 2205 2206 } 2207 // Read dataset type 2208 line = getline(&p, endPtr); 2209 if (line == endPtr) { 2210 vtkErrorMacro(<<"Premature EOF reading file type!" << " for file: " 2211 << (this->FileName?this->FileName:"(Null FileName)")); 2212 return false; 2213 } 2214 word = GetWord(line, &endPtr); 2215 if (strncasecmp(word, "dataset", 7) == 0) { 2216 // Read dataset type 2217 line = getline(&p, endPtr); 2218 if (line == endPtr) { 2219 // EOF 2220 } 2221 type = GetWord(line, &endPtr); 2222 if (strncasecmp(word, "structured_grid", 15) == 0) { 2223 vtkErrorMacro(<< "Cannot read dataset type: " << line); 2224 return 1; 2225 } 2226 // Read keyword and dimensions 2227 // 2228 while (!done) 2229 { 2230 if (!this->ReadString(line)) 2231 { 2232 break; 2233 } 2234 2235 // Have to read field data because it may be binary. 2236 if (! strncmp(this->LowerCase(line), "field", 5)) 2237 { 2238 vtkFieldData* fd = this->ReadFieldData(); 2239 fd->Delete(); 2240 } 2241 2242 if ( ! strncmp(this->LowerCase(line),"dimensions",10) ) 2243 { 2244 int ext[6]; 2245 if (!(this->Read(ext+1) && 2246 this->Read(ext+3) && 2247 this->Read(ext+5))) 2248 { 2249 vtkErrorMacro(<<"Error reading dimensions!"); 2250 this->CloseVTKFile (); 2251 return 1; 2252 } 2253 // read dimensions, change to extent; 2254 ext[0] = ext[2] = ext[4] = 0; 2255 --ext[1]; 2256 --ext[3]; 2257 --ext[5]; 2258 outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), 2259 ext, 6); 2260 // That is all we wanted !!!!!!!!!!!!!!! 2261 this->CloseVTKFile(); 2262 return 1; 2263 } 2264 } 2265 } 2266 2267 2268 2269 float progress=this->GetProgress(); 2270 this->UpdateProgress(progress + 0.5*(1.0 - progress)); 2271 2272 return 1; 2044 line = getline(&p, endPtr); 2045 if (line == endPtr) { 2046 vtkErrorMacro(<<"Premature EOF reading first line! " << " for file: " 2047 << (this->FileName?this->FileName:"(Null FileName)")); 2048 return false; 2049 } 2050 if (sscanf(line, "# vtk DataFile Version %s", version) != 1) { 2051 vtkErrorMacro(<< "Unrecognized file type: "<< line << " for file: " 2052 << (this->FileName?this->FileName:"(Null FileName)")); 2053 return false; 2054 } 2055 2056 // Read title 2057 line = getline(&p, endPtr); 2058 if (line == endPtr) { 2059 vtkErrorMacro(<<"Premature EOF reading title! " << " for file: " 2060 << (this->FileName?this->FileName:"(Null FileName)")); 2061 return false; 2062 } 2063 if (_title != NULL) { 2064 delete [] _title; 2065 } 2066 _title = new char[strlen(line) + 1]; 2067 strcpy(_title, line); 2068 2069 // Read type 2070 line = getline(&p, endPtr); 2071 if (line == endPtr) { 2072 vtkErrorMacro(<<"Premature EOF reading file type!" << " for file: " 2073 << (this->FileName?this->FileName:"(Null FileName)")); 2074 return false; 2075 } 2076 word = GetWord(line, &endPtr); 2077 if (strncasecmp(word, "ascii", 5) == 0) { 2078 _fileType = VTK_ASCII; 2079 } else if (strcasecmp(word, "binary", 6) == 0) { 2080 _fileType = VTK_BINARY; 2081 } else { 2082 vtkErrorMacro(<< "Unrecognized file type: "<< line << " for file: " 2083 << (this->FileName?this->FileName:"(Null FileName)")); 2084 _fileType = 0; 2085 return false; 2086 } 2087 2088 // Read dataset type 2089 line = getline(&p, endPtr); 2090 if (line == endPtr) { 2091 vtkErrorMacro(<<"Premature EOF reading file type!" << " for file: " 2092 << (this->FileName?this->FileName:"(Null FileName)")); 2093 return false; 2094 } 2095 word = GetWord(line, &endPtr); 2096 if (strncasecmp(word, "dataset", 7) == 0) { 2097 // Read dataset type 2098 line = getline(&p, endPtr); 2099 if (line == endPtr) { 2100 // EOF 2101 } 2102 type = GetWord(line, &endPtr); 2103 if (strncasecmp(word, "structured_grid", 15) == 0) { 2104 vtkErrorMacro(<< "Cannot read dataset type: " << line); 2105 return 1; 2106 } 2107 // Read keyword and dimensions 2108 // 2109 while (!done) { 2110 if (!this->ReadString(line)) { 2111 break; 2112 } 2113 2114 // Have to read field data because it may be binary. 2115 if (! strncmp(this->LowerCase(line), "field", 5)) { 2116 vtkFieldData* fd = this->ReadFieldData(); 2117 fd->Delete(); 2118 } 2119 2120 if ( ! strncmp(this->LowerCase(line),"dimensions",10) ) { 2121 int ext[6]; 2122 if (!(this->Read(ext+1) && 2123 this->Read(ext+3) && 2124 this->Read(ext+5))) { 2125 vtkErrorMacro(<<"Error reading dimensions!"); 2126 this->CloseVTKFile (); 2127 return 1; 2128 } 2129 // read dimensions, change to extent; 2130 ext[0] = ext[2] = ext[4] = 0; 2131 --ext[1]; 2132 --ext[3]; 2133 --ext[5]; 2134 outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), 2135 ext, 6); 2136 // That is all we wanted !!!!!!!!!!!!!!! 2137 this->CloseVTKFile(); 2138 return 1; 2139 } 2140 } 2141 } 2142 2143 float progress = this->GetProgress(); 2144 this->UpdateProgress(progress + 0.5*(1.0 - progress)); 2145 2146 return 1; 2273 2147 } 2274 2148 #endif -
trunk/packages/vizservers/nanovis/FlowCmd.h
r2844 r2875 49 49 50 50 struct FlowParticlesValues { 51 FlowPosition position; 52 FlowColor color; 51 FlowPosition position; ///< Position on axis of particle plane 52 FlowColor color; ///< Color of particles 53 53 /// Indicates if particle injection plane is active or not 54 54 int isHidden; 55 float particleSize; 55 float particleSize; ///< Size of the particles 56 56 }; 57 57 … … 130 130 const char *_name; 131 131 Tcl_HashEntry *_hashPtr; 132 NvParticleRenderer *_rendererPtr; 132 NvParticleRenderer *_rendererPtr; ///< Particle renderer 133 133 FlowParticlesValues _sv; 134 134 … … 142 142 143 143 struct FlowBoxValues { 144 float position; 145 FlowPoint corner1, corner2; 146 FlowColor color; 144 float position; ///< Position on axis of particle plane 145 FlowPoint corner1, corner2; ///< Coordinates of the box. 146 FlowColor color; ///< Color of particles 147 147 float lineWidth; 148 148 /// Indicates if particle injection plane is active or not … … 190 190 191 191 private: 192 const char *_name; /* Name of this box in the hash 193 * table. */ 194 Tcl_HashEntry *_hashPtr; /* Pointer to this entry in the hash 195 * table of boxes. */ 192 const char *_name; ///< Name of this box in the hash table. 193 Tcl_HashEntry *_hashPtr; ///< Pointer to this entry in the hash table of boxes. 196 194 FlowBoxValues _sv; 197 195 static Rappture::SwitchSpec _switches[]; … … 207 205 int showOutline; 208 206 int isHidden; 209 /* The following are settings for the volume.*/ 210 float diffuse; 211 float specular; 212 float opacity; 207 float diffuse; ///< Diffuse volume shading 208 float specular; ///< Specular volume shading 209 float opacity; ///< Volume opacity 213 210 }; 214 211 … … 230 227 231 228 int GetParticles(Tcl_Interp *interp, Tcl_Obj *objPtr, 232 229 FlowParticles **particlePtrPtr); 233 230 234 231 void Render();
Note: See TracChangeset
for help on using the changeset viewer.