├── .gitignore ├── .ipynb_checkpoints ├── volumes_example-checkpoint.ipynb └── vtk_example-checkpoint.ipynb ├── LICENSE ├── README.md ├── color_map_med.ipynb ├── color_map_world.ipynb ├── color_maps ├── med0.png └── world0.png ├── intro_data.zip ├── satellite_example.ipynb ├── volume_data.zip ├── volume_screens ├── Captura.PNG ├── Captura10.PNG ├── Captura11.PNG ├── Captura12.PNG ├── Captura2.PNG ├── Captura3.PNG ├── Captura4.PNG ├── Captura5.PNG ├── Captura6.PNG ├── Captura7.PNG ├── Captura8.PNG ├── Captura9.PNG └── Thumbs.db ├── volumes_example.ipynb ├── vtk-intro.pptx └── vtk_example ├── screen1.PNG ├── screen2.PNG ├── screen3.PNG ├── screen4.PNG ├── screen5.PNG ├── screen6.PNG ├── screen7.PNG └── screen8.PNG /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | bin/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # Installer logs 26 | pip-log.txt 27 | pip-delete-this-directory.txt 28 | 29 | # Unit test / coverage reports 30 | htmlcov/ 31 | .tox/ 32 | .coverage 33 | .cache 34 | nosetests.xml 35 | coverage.xml 36 | 37 | # Translations 38 | *.mo 39 | 40 | # Mr Developer 41 | .mr.developer.cfg 42 | .project 43 | .pydevproject 44 | 45 | # Rope 46 | .ropeproject 47 | 48 | # Django stuff: 49 | *.log 50 | *.pot 51 | 52 | # Sphinx documentation 53 | docs/_build/ 54 | 55 | -------------------------------------------------------------------------------- /.ipynb_checkpoints/volumes_example-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "", 4 | "signature": "sha256:5476d817dae7001a20d01364b19d4daf60c122af3cb6bc736f63f145edec9041" 5 | }, 6 | "nbformat": 3, 7 | "nbformat_minor": 0, 8 | "worksheets": [ 9 | { 10 | "cells": [ 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "# Exploring Volumetric data with VTK\n", 16 | "\n", 17 | "Based on [this example](http://www.vtk.org/Wiki/index.php?title=VTK/Examples/Cxx/Visualization/StreamLines)" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "collapsed": false, 23 | "input": [ 24 | "import os\n", 25 | "os.chdir(\"D:/vtk_data/VTKData/Data\")\n", 26 | "#os.chdir(r\"C:\\Users\\Diego\\Programas\\vtk\\VTKData\\Data\")\n", 27 | "import vtk" 28 | ], 29 | "language": "python", 30 | "metadata": {}, 31 | "outputs": [], 32 | "prompt_number": 9 33 | }, 34 | { 35 | "cell_type": "code", 36 | "collapsed": false, 37 | "input": [ 38 | "pl3d = vtk.vtkMultiBlockPLOT3DReader()\n", 39 | "\n", 40 | "xyx_file = \"combxyz.bin\"\n", 41 | "q_file = \"combq.bin\"\n", 42 | "pl3d.SetXYZFileName(xyx_file)\n", 43 | "pl3d.SetQFileName(q_file)\n", 44 | "pl3d.SetScalarFunctionNumber(100)\n", 45 | "pl3d.SetVectorFunctionNumber(202)\n", 46 | "pl3d.Update()" 47 | ], 48 | "language": "python", 49 | "metadata": {}, 50 | "outputs": [], 51 | "prompt_number": 10 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "From the example code:\n", 58 | "\n", 59 | "Here we read data from a annular combustor. A combustor burns fuel\n", 60 | "and air in a gas turbine (e.g., a jet engine) and the hot gas\n", 61 | "eventually makes its way to the turbine section." 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "collapsed": false, 67 | "input": [ 68 | "blocks = pl3d.GetOutput()\n", 69 | "b0 = blocks.GetBlock(0)" 70 | ], 71 | "language": "python", 72 | "metadata": {}, 73 | "outputs": [], 74 | "prompt_number": 11 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "Loot at what is inside the data set" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "collapsed": false, 86 | "input": [ 87 | "# uncomment to get long output\n", 88 | "# print b0" 89 | ], 90 | "language": "python", 91 | "metadata": {}, 92 | "outputs": [], 93 | "prompt_number": 12 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": {}, 98 | "source": [ 99 | "Set up vtk environment" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "collapsed": false, 105 | "input": [ 106 | "renderer = vtk.vtkRenderer()\n", 107 | "render_window = vtk.vtkRenderWindow()\n", 108 | "render_window.AddRenderer(renderer)\n", 109 | "interactor = vtk.vtkRenderWindowInteractor()\n", 110 | "interactor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())\n", 111 | "render_window.SetInteractor(interactor)\n", 112 | "renderer.SetBackground(0.2,0.2,0.2)\n", 113 | "interactor.Initialize()\n", 114 | "render_window.Render()" 115 | ], 116 | "language": "python", 117 | "metadata": {}, 118 | "outputs": [], 119 | "prompt_number": 13 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "Look at an outline of the data for context" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "collapsed": false, 131 | "input": [ 132 | "outline = vtk.vtkStructuredGridOutlineFilter()\n", 133 | "outline.SetInputData(b0)\n", 134 | "outline_mapper = vtk.vtkPolyDataMapper()\n", 135 | "outline_mapper.SetInputConnection(outline.GetOutputPort())\n", 136 | "outline_actor = vtk.vtkActor()\n", 137 | "outline_actor.SetMapper(outline_mapper)\n", 138 | "outline_actor.GetProperty().SetColor(1,1,1)\n", 139 | "renderer.AddActor(outline_actor)\n", 140 | "renderer.ResetCamera()" 141 | ], 142 | "language": "python", 143 | "metadata": {}, 144 | "outputs": [], 145 | "prompt_number": 14 146 | }, 147 | { 148 | "cell_type": "code", 149 | "collapsed": false, 150 | "input": [ 151 | "\n", 152 | "render_window.Render()\n", 153 | "interactor.Start()" 154 | ], 155 | "language": "python", 156 | "metadata": {}, 157 | "outputs": [], 158 | "prompt_number": 15 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "## Scalars\n", 165 | "\n", 166 | "The data contains two scalar arrays and one vector array. We are going to start exploring the data set by looking at the first scalar array \"Density\". We will use several different methods to *look* at this data" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "metadata": {}, 172 | "source": [ 173 | "### Points" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "collapsed": false, 179 | "input": [ 180 | "points = vtk.vtkVertexGlyphFilter()\n", 181 | "points.SetInputData(b0)\n", 182 | "scalars_mapper = vtk.vtkPolyDataMapper()\n", 183 | "scalars_actor = vtk.vtkActor()\n", 184 | "scalars_actor.SetMapper(scalars_mapper)\n", 185 | "scalars_mapper.SetInputConnection(points.GetOutputPort())" 186 | ], 187 | "language": "python", 188 | "metadata": {}, 189 | "outputs": [], 190 | "prompt_number": 59 191 | }, 192 | { 193 | "cell_type": "code", 194 | "collapsed": false, 195 | "input": [ 196 | "scalars_mapper.SetScalarModeToUsePointData()\n", 197 | "#print scalars_mapper.GetLookupTable()" 198 | ], 199 | "language": "python", 200 | "metadata": {}, 201 | "outputs": [], 202 | "prompt_number": 60 203 | }, 204 | { 205 | "cell_type": "code", 206 | "collapsed": false, 207 | "input": [ 208 | "renderer.AddActor(scalars_actor)\n", 209 | "render_window.Render()\n", 210 | "interactor.Start()\n", 211 | "renderer.RemoveActor(scalars_actor)\n", 212 | "render_window.Render()" 213 | ], 214 | "language": "python", 215 | "metadata": {}, 216 | "outputs": [], 217 | "prompt_number": 61 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "metadata": {}, 222 | "source": [ 223 | "![Points with scalar data](volume_screens/Captura.PNG)" 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": {}, 229 | "source": [ 230 | "### Solid" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "collapsed": false, 236 | "input": [ 237 | "poly = vtk.vtkGeometryFilter()\n", 238 | "poly.SetInputData(b0)\n", 239 | "#scalars_mapper = vtk.vtkPolyDataMapper()\n", 240 | "#scalars_actor = vtk.vtkActor()\n", 241 | "#scalars_actor.SetMapper(scalars_mapper)\n", 242 | "scalars_mapper.SetInputConnection(poly.GetOutputPort())" 243 | ], 244 | "language": "python", 245 | "metadata": {}, 246 | "outputs": [], 247 | "prompt_number": 62 248 | }, 249 | { 250 | "cell_type": "code", 251 | "collapsed": false, 252 | "input": [ 253 | "renderer.AddActor(scalars_actor)\n", 254 | "render_window.Render()\n", 255 | "interactor.Start()\n", 256 | "renderer.RemoveActor(scalars_actor)\n", 257 | "render_window.Render()" 258 | ], 259 | "language": "python", 260 | "metadata": {}, 261 | "outputs": [], 262 | "prompt_number": 63 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "![Solid with scalar data](volume_screens/Captura2.PNG)" 269 | ] 270 | }, 271 | { 272 | "cell_type": "markdown", 273 | "metadata": {}, 274 | "source": [ 275 | "### Sample with plane" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "collapsed": false, 281 | "input": [ 282 | "samples = vtk.vtkPlaneWidget()\n", 283 | "samples.SetResolution(24)\n", 284 | "samples.SetOrigin(2,-2,26)\n", 285 | "samples.SetPoint1(2, 2,26)\n", 286 | "samples.SetPoint2(2,-2,32)\n", 287 | "samples_pd = samples.GetPolyDataAlgorithm()\n", 288 | "samples.SetInteractor(interactor)\n", 289 | "samples.SetRepresentationToOutline()\n", 290 | "samples.On()" 291 | ], 292 | "language": "python", 293 | "metadata": {}, 294 | "outputs": [], 295 | "prompt_number": 64 296 | }, 297 | { 298 | "cell_type": "code", 299 | "collapsed": false, 300 | "input": [ 301 | "probe = vtk.vtkProbeFilter()\n", 302 | "probe.SetSourceData(b0)\n", 303 | "probe.SetInputConnection(samples_pd.GetOutputPort())\n", 304 | "probed_mapper = vtk.vtkPolyDataMapper()\n", 305 | "probed_mapper.SetInputConnection(probe.GetOutputPort())\n", 306 | "probed_actor = vtk.vtkActor()\n", 307 | "probed_actor.SetMapper(probed_mapper)" 308 | ], 309 | "language": "python", 310 | "metadata": {}, 311 | "outputs": [], 312 | "prompt_number": 65 313 | }, 314 | { 315 | "cell_type": "code", 316 | "collapsed": false, 317 | "input": [ 318 | "samples.On()\n", 319 | "renderer.AddActor(probed_actor)\n", 320 | "render_window.Render()\n", 321 | "interactor.Start()\n", 322 | "samples.Off()\n", 323 | "renderer.RemoveActor(probed_actor)" 324 | ], 325 | "language": "python", 326 | "metadata": {}, 327 | "outputs": [], 328 | "prompt_number": 66 329 | }, 330 | { 331 | "cell_type": "markdown", 332 | "metadata": {}, 333 | "source": [ 334 | "![Sampling with a plane](volume_screens/Captura3.PNG)" 335 | ] 336 | }, 337 | { 338 | "cell_type": "markdown", 339 | "metadata": {}, 340 | "source": [ 341 | "### Iso-surfaces" 342 | ] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "collapsed": false, 347 | "input": [ 348 | "min_s, max_s = b0.GetScalarRange()\n", 349 | "print min_s, max_s" 350 | ], 351 | "language": "python", 352 | "metadata": {}, 353 | "outputs": [ 354 | { 355 | "output_type": "stream", 356 | "stream": "stdout", 357 | "text": [ 358 | "0.197813093662 0.710419237614\n" 359 | ] 360 | } 361 | ], 362 | "prompt_number": 67 363 | }, 364 | { 365 | "cell_type": "code", 366 | "collapsed": false, 367 | "input": [ 368 | "contours = vtk.vtkContourFilter()\n", 369 | "contours.SetInputData(b0)\n", 370 | "contours.GenerateValues(5, (min_s,max_s))\n", 371 | "contours_mapper = vtk.vtkPolyDataMapper()\n", 372 | "contours_mapper.SetInputConnection(contours.GetOutputPort())\n", 373 | "contours_actor = vtk.vtkActor()\n", 374 | "contours_actor.SetMapper(contours_mapper)\n" 375 | ], 376 | "language": "python", 377 | "metadata": {}, 378 | "outputs": [], 379 | "prompt_number": 68 380 | }, 381 | { 382 | "cell_type": "code", 383 | "collapsed": false, 384 | "input": [ 385 | "renderer.AddActor(contours_actor)\n", 386 | "render_window.Render()\n", 387 | "interactor.Start()\n", 388 | "renderer.RemoveActor(contours_actor)\n", 389 | "render_window.Render()" 390 | ], 391 | "language": "python", 392 | "metadata": {}, 393 | "outputs": [], 394 | "prompt_number": 69 395 | }, 396 | { 397 | "cell_type": "markdown", 398 | "metadata": {}, 399 | "source": [ 400 | "![Iso-surfaces](volume_screens/Captura4.PNG)" 401 | ] 402 | }, 403 | { 404 | "cell_type": "markdown", 405 | "metadata": {}, 406 | "source": [ 407 | "We will add some transparency to be able to look inside" 408 | ] 409 | }, 410 | { 411 | "cell_type": "code", 412 | "collapsed": false, 413 | "input": [ 414 | "contours_actor.GetProperty().SetOpacity(0.5)" 415 | ], 416 | "language": "python", 417 | "metadata": {}, 418 | "outputs": [], 419 | "prompt_number": 70 420 | }, 421 | { 422 | "cell_type": "code", 423 | "collapsed": false, 424 | "input": [ 425 | "renderer.AddActor(contours_actor)\n", 426 | "render_window.Render()\n", 427 | "interactor.Start()\n", 428 | "renderer.RemoveActor(contours_actor)\n", 429 | "render_window.Render()" 430 | ], 431 | "language": "python", 432 | "metadata": {}, 433 | "outputs": [], 434 | "prompt_number": 71 435 | }, 436 | { 437 | "cell_type": "markdown", 438 | "metadata": {}, 439 | "source": [ 440 | "![Iso surfaces with opacity](volume_screens/Captura5.PNG)" 441 | ] 442 | }, 443 | { 444 | "cell_type": "markdown", 445 | "metadata": {}, 446 | "source": [ 447 | "### Volume Rendering" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "collapsed": false, 453 | "input": [ 454 | "volume_mapper = vtk.vtkUnstructuredGridVolumeRayCastMapper()\n", 455 | "#volume_mapper = vtk.vtkProjectedTetrahedraMapper()\n", 456 | "#volume_mapper = vtk.vtkUnstructuredGridVolumeZSweepMapper()\n", 457 | "\n", 458 | "#volume_mapper.SetBlendModeToComposite() # try others\n", 459 | "#volume_mapper.SetBlendModeToMinimumIntensity()\n", 460 | "tri_filter = vtk.vtkDataSetTriangleFilter()\n", 461 | "tri_filter.SetInputData(b0)\n", 462 | "volume_mapper.SetInputConnection(tri_filter.GetOutputPort())\n", 463 | "volume = vtk.vtkVolume()\n", 464 | "volume.SetMapper(volume_mapper)\n", 465 | "volume_property = volume.GetProperty()\n" 466 | ], 467 | "language": "python", 468 | "metadata": {}, 469 | "outputs": [], 470 | "prompt_number": 72 471 | }, 472 | { 473 | "cell_type": "code", 474 | "collapsed": false, 475 | "input": [ 476 | "intensity = vtk.vtkPiecewiseFunction()\n", 477 | "intensity.AddPoint(min_s,0.1)\n", 478 | "intensity.AddPoint((max_s+min_s)/2.0, 1.0)\n", 479 | "intensity.AddPoint(max_s, 1.0)\n", 480 | "color = vtk.vtkColorTransferFunction()\n", 481 | "color.AddRGBPoint(min_s,0,1,0)\n", 482 | "color.AddRGBPoint(max_s,1,0,0)\n", 483 | "volume_property.SetScalarOpacity(intensity)\n", 484 | "volume_property.SetInterpolationTypeToLinear()\n", 485 | "volume_property.SetColor(color)\n", 486 | "volume_property.ShadeOff()\n", 487 | "volume.VisibilityOn()" 488 | ], 489 | "language": "python", 490 | "metadata": {}, 491 | "outputs": [], 492 | "prompt_number": 73 493 | }, 494 | { 495 | "cell_type": "code", 496 | "collapsed": false, 497 | "input": [ 498 | "renderer.AddViewProp(volume)\n", 499 | "render_window.Render()\n", 500 | "interactor.Start()\n", 501 | "renderer.RemoveViewProp(volume)" 502 | ], 503 | "language": "python", 504 | "metadata": {}, 505 | "outputs": [], 506 | "prompt_number": 74 507 | }, 508 | { 509 | "cell_type": "markdown", 510 | "metadata": {}, 511 | "source": [ 512 | "![Volume rendering](volume_screens/Captura6.PNG)" 513 | ] 514 | }, 515 | { 516 | "cell_type": "markdown", 517 | "metadata": {}, 518 | "source": [ 519 | "## Vectors\n", 520 | "\n", 521 | "Now we are going to explore the vector data inside the dataset. We will use two methods" 522 | ] 523 | }, 524 | { 525 | "cell_type": "markdown", 526 | "metadata": {}, 527 | "source": [ 528 | "### Glyphs" 529 | ] 530 | }, 531 | { 532 | "cell_type": "code", 533 | "collapsed": false, 534 | "input": [ 535 | "arrow = vtk.vtkArrowSource()\n", 536 | "glyphs = vtk.vtkGlyph3D()\n", 537 | "glyphs.SetInputData(b0)\n", 538 | "glyphs.SetSourceConnection(arrow.GetOutputPort())" 539 | ], 540 | "language": "python", 541 | "metadata": {}, 542 | "outputs": [], 543 | "prompt_number": 75 544 | }, 545 | { 546 | "cell_type": "code", 547 | "collapsed": false, 548 | "input": [ 549 | "glyph_mapper = vtk.vtkPolyDataMapper()\n", 550 | "glyph_mapper.SetInputConnection(glyphs.GetOutputPort())\n", 551 | "glyph_actor = vtk.vtkActor()\n", 552 | "glyph_actor.SetMapper(glyph_mapper)" 553 | ], 554 | "language": "python", 555 | "metadata": {}, 556 | "outputs": [], 557 | "prompt_number": 76 558 | }, 559 | { 560 | "cell_type": "code", 561 | "collapsed": false, 562 | "input": [ 563 | "glyphs.SetVectorModeToUseVector()\n", 564 | "glyphs.SetScaleModeToScaleByScalar()\n", 565 | "#glyphs.SetScaleModeToDataScalingOff()\n", 566 | "\n", 567 | "glyph_mapper.UseLookupTableScalarRangeOn()" 568 | ], 569 | "language": "python", 570 | "metadata": {}, 571 | "outputs": [], 572 | "prompt_number": 77 573 | }, 574 | { 575 | "cell_type": "code", 576 | "collapsed": false, 577 | "input": [ 578 | "renderer.AddActor(glyph_actor)\n", 579 | "render_window.Render()\n", 580 | "interactor.Start()\n", 581 | "renderer.RemoveActor(glyph_actor)\n", 582 | "render_window.Render()" 583 | ], 584 | "language": "python", 585 | "metadata": {}, 586 | "outputs": [], 587 | "prompt_number": 78 588 | }, 589 | { 590 | "cell_type": "markdown", 591 | "metadata": {}, 592 | "source": [ 593 | "![Vectors as glyphs](volume_screens/Captura7.PNG)" 594 | ] 595 | }, 596 | { 597 | "cell_type": "markdown", 598 | "metadata": {}, 599 | "source": [ 600 | "Now lets scale by the norm of the vectors" 601 | ] 602 | }, 603 | { 604 | "cell_type": "code", 605 | "collapsed": false, 606 | "input": [ 607 | "glyphs.SetScaleModeToScaleByVector()\n", 608 | "glyphs.SetScaleFactor(0.001)\n", 609 | "glyphs.SetColorModeToColorByVector()" 610 | ], 611 | "language": "python", 612 | "metadata": {}, 613 | "outputs": [], 614 | "prompt_number": 79 615 | }, 616 | { 617 | "cell_type": "code", 618 | "collapsed": false, 619 | "input": [ 620 | "glyphs.Update()\n", 621 | "s0,sf = glyphs.GetOutput().GetScalarRange()\n", 622 | "lut = vtk.vtkColorTransferFunction()\n", 623 | "lut.AddRGBPoint(s0, 1,0,0)\n", 624 | "lut.AddRGBPoint(sf, 0,1,0)\n", 625 | "glyph_mapper.SetLookupTable(lut)" 626 | ], 627 | "language": "python", 628 | "metadata": {}, 629 | "outputs": [], 630 | "prompt_number": 80 631 | }, 632 | { 633 | "cell_type": "code", 634 | "collapsed": false, 635 | "input": [ 636 | "renderer.AddActor(glyph_actor)\n", 637 | "render_window.Render()\n", 638 | "interactor.Start()\n", 639 | "renderer.RemoveActor(glyph_actor)\n", 640 | "render_window.Render()" 641 | ], 642 | "language": "python", 643 | "metadata": {}, 644 | "outputs": [], 645 | "prompt_number": 81 646 | }, 647 | { 648 | "cell_type": "markdown", 649 | "metadata": {}, 650 | "source": [ 651 | "![Scaled glyphs](volume_screens/Captura8.PNG)" 652 | ] 653 | }, 654 | { 655 | "cell_type": "markdown", 656 | "metadata": {}, 657 | "source": [ 658 | "The above graph is very crowded, we can simplify it by showing a random sampleof vectors. We can now also make them bigger." 659 | ] 660 | }, 661 | { 662 | "cell_type": "code", 663 | "collapsed": false, 664 | "input": [ 665 | "mask = vtk.vtkMaskPoints()\n", 666 | "mask.SetInputData(b0)\n", 667 | "mask.GenerateVerticesOn()\n", 668 | "mask.SetMaximumNumberOfPoints(10000)\n", 669 | "mask.SetRandomModeType(1)\n", 670 | "mask.RandomModeOn()\n", 671 | "glyphs.SetInputConnection(mask.GetOutputPort())\n", 672 | "glyphs.SetScaleFactor(0.005)" 673 | ], 674 | "language": "python", 675 | "metadata": {}, 676 | "outputs": [], 677 | "prompt_number": 82 678 | }, 679 | { 680 | "cell_type": "code", 681 | "collapsed": false, 682 | "input": [ 683 | "renderer.AddActor(glyph_actor)\n", 684 | "render_window.Render()\n", 685 | "interactor.Start()\n", 686 | "renderer.RemoveActor(glyph_actor)\n", 687 | "render_window.Render()" 688 | ], 689 | "language": "python", 690 | "metadata": {}, 691 | "outputs": [], 692 | "prompt_number": 83 693 | }, 694 | { 695 | "cell_type": "markdown", 696 | "metadata": {}, 697 | "source": [ 698 | "![Random subset of glyphs](volume_screens/Captura9.PNG)" 699 | ] 700 | }, 701 | { 702 | "cell_type": "markdown", 703 | "metadata": {}, 704 | "source": [ 705 | "Here we risk loosing important features in the dataset. Another approach is showing only the vectors above a threshold" 706 | ] 707 | }, 708 | { 709 | "cell_type": "code", 710 | "collapsed": false, 711 | "input": [ 712 | "threshold = vtk.vtkThresholdPoints()\n", 713 | "threshold.SetInputData(b0)\n", 714 | "print b0.GetScalarRange()\n", 715 | "threshold.ThresholdByUpper(0.5)\n", 716 | "glyphs.SetInputConnection(threshold.GetOutputPort())" 717 | ], 718 | "language": "python", 719 | "metadata": {}, 720 | "outputs": [ 721 | { 722 | "output_type": "stream", 723 | "stream": "stdout", 724 | "text": [ 725 | "(0.19781309366226196, 0.710419237613678)\n" 726 | ] 727 | } 728 | ], 729 | "prompt_number": 84 730 | }, 731 | { 732 | "cell_type": "code", 733 | "collapsed": false, 734 | "input": [ 735 | "renderer.AddActor(glyph_actor)\n", 736 | "render_window.Render()\n", 737 | "interactor.Start()\n", 738 | "renderer.RemoveActor(glyph_actor)\n", 739 | "render_window.Render()" 740 | ], 741 | "language": "python", 742 | "metadata": {}, 743 | "outputs": [], 744 | "prompt_number": 85 745 | }, 746 | { 747 | "cell_type": "markdown", 748 | "metadata": {}, 749 | "source": [ 750 | "![Filtered glyohs](volume_screens/Captura10.PNG)" 751 | ] 752 | }, 753 | { 754 | "cell_type": "markdown", 755 | "metadata": {}, 756 | "source": [ 757 | "## Streamlines" 758 | ] 759 | }, 760 | { 761 | "cell_type": "code", 762 | "collapsed": false, 763 | "input": [ 764 | "seeds = vtk.vtkPlaneWidget()\n", 765 | "seeds.SetResolution(8)\n", 766 | "seeds.SetOrigin(2,-2,26)\n", 767 | "seeds.SetPoint1(2, 2,26)\n", 768 | "seeds.SetPoint2(2,-2,32)\n", 769 | "seeds_pd = seeds.GetPolyDataAlgorithm()\n", 770 | "seeds.SetInteractor(interactor)\n", 771 | "seeds.On()\n" 772 | ], 773 | "language": "python", 774 | "metadata": {}, 775 | "outputs": [], 776 | "prompt_number": 86 777 | }, 778 | { 779 | "cell_type": "code", 780 | "collapsed": false, 781 | "input": [ 782 | "streamline = vtk.vtkStreamLine()\n", 783 | "streamline.SetInputData(pl3d.GetOutput().GetBlock(0))\n", 784 | "streamline.SetSourceConnection(seeds_pd.GetOutputPort())\n", 785 | "streamline.SetMaximumPropagationTime(200)\n", 786 | "streamline.SetIntegrationStepLength(.2)\n", 787 | "streamline.SetStepLength(0.001)\n", 788 | "streamline.SetNumberOfThreads(1)\n", 789 | "streamline.SetIntegrationDirectionToForward()\n", 790 | "streamline.VorticityOn()\n", 791 | "\n", 792 | "streamline_mapper = vtk.vtkPolyDataMapper()\n", 793 | "streamline_mapper.SetInputConnection(streamline.GetOutputPort())\n", 794 | "streamline_actor = vtk.vtkActor()\n", 795 | "streamline_actor.SetMapper(streamline_mapper)\n", 796 | "streamline_actor.VisibilityOn()\n" 797 | ], 798 | "language": "python", 799 | "metadata": {}, 800 | "outputs": [], 801 | "prompt_number": 87 802 | }, 803 | { 804 | "cell_type": "code", 805 | "collapsed": false, 806 | "input": [ 807 | "renderer.AddActor(streamline_actor)\n", 808 | "seeds.On()\n", 809 | "render_window.Render()\n", 810 | "interactor.Start()\n", 811 | "renderer.RemoveActor(streamline_actor)\n", 812 | "render_window.Render()\n", 813 | "seeds.Off()" 814 | ], 815 | "language": "python", 816 | "metadata": {}, 817 | "outputs": [], 818 | "prompt_number": 88 819 | }, 820 | { 821 | "cell_type": "markdown", 822 | "metadata": {}, 823 | "source": [ 824 | "![Streamlines](volume_screens/Captura11.PNG)" 825 | ] 826 | }, 827 | { 828 | "cell_type": "markdown", 829 | "metadata": {}, 830 | "source": [ 831 | "## Stream Tubes" 832 | ] 833 | }, 834 | { 835 | "cell_type": "code", 836 | "collapsed": false, 837 | "input": [ 838 | "tubes =vtk.vtkTubeFilter()\n", 839 | "tubes.SetInputConnection(streamline.GetOutputPort())\n", 840 | "tubes.SetRadius(0.1)\n", 841 | "tubes.SetNumberOfSides(8)\n", 842 | "tubes.SetVaryRadiusToVaryRadiusByScalar()\n", 843 | "tubes.SetRadiusFactor(3)\n", 844 | "\n", 845 | "tubes_mapper = vtk.vtkPolyDataMapper()\n", 846 | "tubes_mapper.SetInputConnection(tubes.GetOutputPort())\n", 847 | "tubes_actor = vtk.vtkActor()\n", 848 | "tubes_actor.SetMapper(tubes_mapper)\n" 849 | ], 850 | "language": "python", 851 | "metadata": {}, 852 | "outputs": [], 853 | "prompt_number": 89 854 | }, 855 | { 856 | "cell_type": "code", 857 | "collapsed": false, 858 | "input": [ 859 | "renderer.AddActor(tubes_actor)\n", 860 | "seeds.On()\n", 861 | "render_window.Render()\n", 862 | "interactor.Start()\n", 863 | "renderer.RemoveActor(tubes_actor)\n", 864 | "render_window.Render()\n", 865 | "seeds.Off()" 866 | ], 867 | "language": "python", 868 | "metadata": {}, 869 | "outputs": [], 870 | "prompt_number": 90 871 | }, 872 | { 873 | "cell_type": "markdown", 874 | "metadata": {}, 875 | "source": [ 876 | "![Streamtubes](volume_screens/Captura12.PNG)" 877 | ] 878 | }, 879 | { 880 | "cell_type": "markdown", 881 | "metadata": {}, 882 | "source": [ 883 | "## Next\n", 884 | "\n", 885 | "We have looked at several techniques one at a time. Now you could try mixing them up to show a complete visualization. Also up to now we have ignored the third scalar in the data..." 886 | ] 887 | }, 888 | { 889 | "cell_type": "markdown", 890 | "metadata": {}, 891 | "source": [ 892 | "## Additional sources\n", 893 | "\n", 894 | "- http://www.vtk.org/Wiki/VTK/Examples/Cxx/Visualization/VectorField\n", 895 | "- http://www.bu.edu/tech/support/research/training-consulting/online-tutorials/vtk/\n", 896 | "- http://vis.computer.org/vis2004/dvd/tutorial/tut_5/notes_3.pdf" 897 | ] 898 | }, 899 | { 900 | "cell_type": "code", 901 | "collapsed": false, 902 | "input": [], 903 | "language": "python", 904 | "metadata": {}, 905 | "outputs": [], 906 | "prompt_number": 90 907 | } 908 | ], 909 | "metadata": {} 910 | } 911 | ] 912 | } -------------------------------------------------------------------------------- /.ipynb_checkpoints/vtk_example-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "", 4 | "signature": "sha256:8031f848a4efe72adaa26b934b1d38198faafd98ecb4f3b52bda467d4a4e47ea" 5 | }, 6 | "nbformat": 3, 7 | "nbformat_minor": 0, 8 | "worksheets": [ 9 | { 10 | "cells": [ 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "# VTK Python Example: Looking at satellite data\n", 16 | "\n", 17 | "For this example we are going to be looking at the data from the [SCIVIS Contest 2014](http://www.viscontest.rwth-aachen.de/data.html). All data can be downloaded from the following url:\n", 18 | "http://www.viscontest.rwth-aachen.de/download.html\n" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "Test that vtk is correctly installed" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "collapsed": false, 31 | "input": [ 32 | "import vtk" 33 | ], 34 | "language": "python", 35 | "metadata": {}, 36 | "outputs": [] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "## 1: Loading the data\n", 43 | "\n", 44 | "All the data comes in vtk format, therefore it is straightforward to read it in vtk. " 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "collapsed": false, 50 | "input": [ 51 | "import os\n", 52 | "os.chdir(r\"D:\\viscontest\\viscontest14-data\\mipas\")\n", 53 | "reader = vtk.vtkPolyDataReader()\n", 54 | "reader.SetFileName(\"2011-MIPAS-VisContest.vtk\")\n", 55 | "reader.Update()\n", 56 | "mipas=reader.GetOutput()" 57 | ], 58 | "language": "python", 59 | "metadata": {}, 60 | "outputs": [], 61 | "prompt_number": 1 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "This contains the data for several orbits of the satellite, we are going to extract just the first orbit to makes thing easier" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "collapsed": false, 73 | "input": [ 74 | "c1 = mipas.GetCell(0)\n", 75 | "pids = c1.GetPointIds()\n", 76 | "nps = pids.GetNumberOfIds()\n", 77 | "# we are going to store the points in this new array\n", 78 | "points = vtk.vtkPoints()\n", 79 | "points.SetNumberOfPoints(nps)\n", 80 | "for i in xrange(nps):\n", 81 | " pid = pids.GetId(i)\n", 82 | " p = mipas.GetPoint(pid)\n", 83 | " points.SetPoint(i,(p[0],p[1],20)) # 20 will be a fixed height for now\n", 84 | "\n", 85 | "# and we are going to encapsulate them in this polydata\n", 86 | "pd = vtk.vtkPolyData()\n", 87 | "pd.SetPoints(points)" 88 | ], 89 | "language": "python", 90 | "metadata": {}, 91 | "outputs": [], 92 | "prompt_number": 2 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": {}, 97 | "source": [ 98 | "Now lets create a filter to make it easier to visualize the points" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "collapsed": false, 104 | "input": [ 105 | "vfilter = vtk.vtkVertexGlyphFilter()\n", 106 | "vfilter.SetInputData(pd)\n", 107 | "vfilter.Update()" 108 | ], 109 | "language": "python", 110 | "metadata": {}, 111 | "outputs": [], 112 | "prompt_number": 3 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "Lets setup the vtk environment" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "collapsed": false, 124 | "input": [ 125 | "ren_win = vtk.vtkRenderWindow()\n", 126 | "ren = vtk.vtkRenderer()\n", 127 | "iren = vtk.vtkRenderWindowInteractor()\n", 128 | "ren_win.SetInteractor(iren)\n", 129 | "ren_win.AddRenderer(ren)\n", 130 | "iren.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())\n", 131 | "ren.GradientBackgroundOn()\n", 132 | "ren.SetBackground2((0.5, 0.5, 0.5))\n", 133 | "ren.SetBackground((0.2, 0.2, 0.2))\n", 134 | "iren.Initialize()" 135 | ], 136 | "language": "python", 137 | "metadata": {}, 138 | "outputs": [], 139 | "prompt_number": 4 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "Finally, lets add the points to the viewer" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "collapsed": false, 151 | "input": [ 152 | "points_mapper = vtk.vtkPolyDataMapper()\n", 153 | "points_mapper.SetInputConnection(vfilter.GetOutputPort())\n", 154 | "points_ac = vtk.vtkActor()\n", 155 | "points_ac.SetMapper(points_mapper)\n", 156 | "\n", 157 | "#make points bigger\n", 158 | "p = points_ac.GetProperty()\n", 159 | "p.SetPointSize(2)\n", 160 | "ren.AddActor(points_ac)" 161 | ], 162 | "language": "python", 163 | "metadata": {}, 164 | "outputs": [], 165 | "prompt_number": 5 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "The vtk window should now be open but frozen, with the following command we can make it interactive. To exit interactive mode, press q while having focus on the vtk window" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "collapsed": false, 177 | "input": [ 178 | "iren.Start()\n", 179 | "#press q to stop interaction" 180 | ], 181 | "language": "python", 182 | "metadata": {}, 183 | "outputs": [], 184 | "prompt_number": 6 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "You should see the following image in the 3d viewer\n", 191 | "\n", 192 | "" 193 | ] 194 | }, 195 | { 196 | "cell_type": "markdown", 197 | "metadata": {}, 198 | "source": [ 199 | "##2: Adding some context\n", 200 | "The above image is hard to interpret, lets add the map of the earth to make it easier to understand" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "collapsed": false, 206 | "input": [ 207 | "os.chdir( r\"D:\\viscontest\\viscontest14-data\\support\")\n", 208 | "reader = vtk.vtkPolyDataReader()\n", 209 | "reader.SetFileName(\"coastlines.vtk\")\n", 210 | "reader.Update()\n", 211 | "cl = reader.GetOutput()\n", 212 | "cl_mapper = vtk.vtkPolyDataMapper()\n", 213 | "cl_mapper.SetInputData(cl)\n", 214 | "cl_actor = vtk.vtkActor()\n", 215 | "cl_actor.SetMapper(cl_mapper)\n", 216 | "ren.AddActor(cl_actor)\n", 217 | "ren_win.Render()" 218 | ], 219 | "language": "python", 220 | "metadata": {}, 221 | "outputs": [], 222 | "prompt_number": 7 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": {}, 227 | "source": [ 228 | "Notice in this case we don't need the vertex filter because the polydata is made of lines (instead of points). Now lets start the interactive window again" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "collapsed": false, 234 | "input": [ 235 | "iren.Start()\n", 236 | "#remember: q to stop interaction" 237 | ], 238 | "language": "python", 239 | "metadata": {}, 240 | "outputs": [], 241 | "prompt_number": 8 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "You should see the following image in the 3d viewer\n", 248 | "\n", 249 | "" 250 | ] 251 | }, 252 | { 253 | "cell_type": "markdown", 254 | "metadata": {}, 255 | "source": [ 256 | "# 3: Mapping the samples attitude\n", 257 | "\n", 258 | "Now we are going to map the attitude of the points over the map using the attitude data from the satellites. First lets look at this data" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "collapsed": false, 264 | "input": [ 265 | "pdata = mipas.GetPointData()\n", 266 | "print pdata" 267 | ], 268 | "language": "python", 269 | "metadata": {}, 270 | "outputs": [ 271 | { 272 | "output_type": "stream", 273 | "stream": "stdout", 274 | "text": [ 275 | "vtkPointData (000000000417BDD0)\n", 276 | " Debug: Off\n", 277 | " Modified Time: 215\n", 278 | " Reference Count: 2\n", 279 | " Registered Events: (none)\n", 280 | " Number Of Arrays: 5\n", 281 | " Array 0 name = time\n", 282 | " Array 1 name = altitude\n", 283 | " Array 2 name = orbit_id\n", 284 | " Array 3 name = profile_id\n", 285 | " Array 4 name = detection\n", 286 | " Number Of Components: 5\n", 287 | " Number Of Tuples: 1295837\n", 288 | " Copy Tuple Flags: ( 1 1 1 1 1 0 1 1 )\n", 289 | " Interpolate Flags: ( 1 1 1 1 1 0 0 1 )\n", 290 | " Pass Through Flags: ( 1 1 1 1 1 1 1 1 )\n", 291 | " Scalars: (none)\n", 292 | " Vectors: (none)\n", 293 | " Normals: (none)\n", 294 | " TCoords: (none)\n", 295 | " Tensors: (none)\n", 296 | " GlobalIds: (none)\n", 297 | " PedigreeIds: (none)\n", 298 | " EdgeFlag: (none)\n", 299 | "\n", 300 | "\n" 301 | ] 302 | } 303 | ], 304 | "prompt_number": 9 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": {}, 309 | "source": [ 310 | "We can see the altitude is stored in Array 1, now lets find its range" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "collapsed": false, 316 | "input": [ 317 | "altitude = pdata.GetArray(1)\n", 318 | "print altitude.GetRange()" 319 | ], 320 | "language": "python", 321 | "metadata": {}, 322 | "outputs": [ 323 | { 324 | "output_type": "stream", 325 | "stream": "stdout", 326 | "text": [ 327 | "(4.515999794006348, 30.0)\n" 328 | ] 329 | } 330 | ], 331 | "prompt_number": 10 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "In the above drawing we used a constant height of 20, so this range looks appropriate. Now lets recreate the points polydata using this new information" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "collapsed": false, 343 | "input": [ 344 | "for i in xrange(nps):\n", 345 | " pid = pids.GetId(i)\n", 346 | " alt = altitude.GetValue(pid)\n", 347 | " p = mipas.GetPoint(pid)\n", 348 | " points.SetPoint(i,(p[0],p[1],alt))\n", 349 | "pd = vtk.vtkPolyData()\n", 350 | "pd.SetPoints(points)\n", 351 | "vfilter.SetInputData(pd)" 352 | ], 353 | "language": "python", 354 | "metadata": {}, 355 | "outputs": [], 356 | "prompt_number": 11 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "metadata": {}, 361 | "source": [ 362 | "And finally let start the viewer again in order to see the changes" 363 | ] 364 | }, 365 | { 366 | "cell_type": "code", 367 | "collapsed": false, 368 | "input": [ 369 | "ren_win.Render()\n", 370 | "iren.Start()\n", 371 | "# remember, q to stop" 372 | ], 373 | "language": "python", 374 | "metadata": {}, 375 | "outputs": [], 376 | "prompt_number": 12 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "metadata": {}, 381 | "source": [ 382 | "You should see the following image in the 3d viewer\n", 383 | "\n", 384 | "" 385 | ] 386 | }, 387 | { 388 | "cell_type": "markdown", 389 | "metadata": {}, 390 | "source": [ 391 | "## 4: Scalar data\n", 392 | "Now we are going to look at some other scalars included in the data. \n", 393 | "\n", 394 | "### 4.1: Time data\n", 395 | "Lets start by looking at the *time* to get a better feeling of the direction in which the satellite travels" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "collapsed": false, 401 | "input": [ 402 | "# array to use inside our new polydata\n", 403 | "time_array = vtk.vtkFloatArray()\n", 404 | "time_array.SetNumberOfComponents(1)\n", 405 | "time_array.SetNumberOfTuples(nps)\n", 406 | "\n", 407 | "#original time array\n", 408 | "time_array_big = pdata.GetArray(0)\n", 409 | "\n", 410 | "for i in xrange(nps):\n", 411 | " pid = pids.GetId(i)\n", 412 | " t = time_array_big.GetValue(pid)\n", 413 | " time_array.SetComponent(i,0,t)\n", 414 | "\n", 415 | "time_array.SetName(\"time\")\n", 416 | "pdata2 = pd.GetPointData()\n", 417 | "pdata2.SetScalars(time_array)\n", 418 | "print pd" 419 | ], 420 | "language": "python", 421 | "metadata": {}, 422 | "outputs": [ 423 | { 424 | "output_type": "stream", 425 | "stream": "stdout", 426 | "text": [ 427 | "vtkPolyData (00000000042E57C0)\n", 428 | " Debug: Off\n", 429 | " Modified Time: 79460\n", 430 | " Reference Count: 3\n", 431 | " Registered Events: (none)\n", 432 | " Information: 00000000042EB8E0\n", 433 | " Data Released: False\n", 434 | " Global Release Data: Off\n", 435 | " UpdateTime: 79049\n", 436 | " Field Data:\n", 437 | " Debug: Off\n", 438 | " Modified Time: 78913\n", 439 | " Reference Count: 1\n", 440 | " Registered Events: (none)\n", 441 | " Number Of Arrays: 0\n", 442 | " Number Of Components: 0\n", 443 | " Number Of Tuples: 0\n", 444 | " Number Of Points: 1326\n", 445 | " Number Of Cells: 0\n", 446 | " Cell Data:\n", 447 | " Debug: Off\n", 448 | " Modified Time: 78916\n", 449 | " Reference Count: 1\n", 450 | " Registered Events: (none)\n", 451 | " Number Of Arrays: 0\n", 452 | " Number Of Components: 0\n", 453 | " Number Of Tuples: 0\n", 454 | " Copy Tuple Flags: ( 1 1 1 1 1 0 1 1 )\n", 455 | " Interpolate Flags: ( 1 1 1 1 1 0 0 1 )\n", 456 | " Pass Through Flags: ( 1 1 1 1 1 1 1 1 )\n", 457 | " Scalars: (none)\n", 458 | " Vectors: (none)\n", 459 | " Normals: (none)\n", 460 | " TCoords: (none)\n", 461 | " Tensors: (none)\n", 462 | " GlobalIds: (none)\n", 463 | " PedigreeIds: (none)\n", 464 | " EdgeFlag: (none)\n", 465 | " Point Data:\n", 466 | " Debug: Off\n", 467 | " Modified Time: 79460\n", 468 | " Reference Count: 2\n", 469 | " Registered Events: (none)\n", 470 | " Number Of Arrays: 1\n", 471 | " Array 0 name = time\n", 472 | " Number Of Components: 1\n", 473 | " Number Of Tuples: 1326\n", 474 | " Copy Tuple Flags: ( 1 1 1 1 1 0 1 1 )\n", 475 | " Interpolate Flags: ( 1 1 1 1 1 0 0 1 )\n", 476 | " Pass Through Flags: ( 1 1 1 1 1 1 1 1 )\n", 477 | " Scalars: \n", 478 | " Debug: Off\n", 479 | " Modified Time: 79457\n", 480 | " Reference Count: 2\n", 481 | " Registered Events: (none)\n", 482 | " Name: time\n", 483 | " Data type: float\n", 484 | " Size: 1326\n", 485 | " MaxId: 1325\n", 486 | " NumberOfComponents: 1\n", 487 | " Information: 0000000000000000\n", 488 | " Name: time\n", 489 | " Number Of Components: 1\n", 490 | " Number Of Tuples: 1326\n", 491 | " Size: 1326\n", 492 | " MaxId: 1325\n", 493 | " LookupTable: (none)\n", 494 | " Array: 00000000042C28E0\n", 495 | " Vectors: (none)\n", 496 | " Normals: (none)\n", 497 | " TCoords: (none)\n", 498 | " Tensors: (none)\n", 499 | " GlobalIds: (none)\n", 500 | " PedigreeIds: (none)\n", 501 | " EdgeFlag: (none)\n", 502 | " Bounds: \n", 503 | " Xmin,Xmax: (-148.527, 145.782)\n", 504 | " Ymin,Ymax: (-87.2112, 89.4011)\n", 505 | " Zmin,Zmax: (4.878, 29.963)\n", 506 | " Compute Time: 79462\n", 507 | " Number Of Points: 1326\n", 508 | " Point Coordinates: 0000000002CB3560\n", 509 | " Locator: 0000000000000000\n", 510 | " Number Of Vertices: 0\n", 511 | " Number Of Lines: 0\n", 512 | " Number Of Polygons: 0\n", 513 | " Number Of Triangle Strips: 0\n", 514 | " Number Of Pieces: 1\n", 515 | " Piece: 0\n", 516 | " Ghost Level: 0\n", 517 | "\n", 518 | "\n" 519 | ] 520 | } 521 | ], 522 | "prompt_number": 13 523 | }, 524 | { 525 | "cell_type": "markdown", 526 | "metadata": {}, 527 | "source": [ 528 | "We can see the time array is now located inside the point data. Now lets update the viewer and look at the changes" 529 | ] 530 | }, 531 | { 532 | "cell_type": "code", 533 | "collapsed": false, 534 | "input": [ 535 | "vfilter.SetInputData(pd)" 536 | ], 537 | "language": "python", 538 | "metadata": {}, 539 | "outputs": [], 540 | "prompt_number": 14 541 | }, 542 | { 543 | "cell_type": "code", 544 | "collapsed": false, 545 | "input": [ 546 | "ren_win.Render()\n", 547 | "iren.Start()\n", 548 | "# remember, q to stop" 549 | ], 550 | "language": "python", 551 | "metadata": {}, 552 | "outputs": [], 553 | "prompt_number": 15 554 | }, 555 | { 556 | "cell_type": "markdown", 557 | "metadata": {}, 558 | "source": [ 559 | "You should see the following image in the 3d viewer\n", 560 | "\n", 561 | "" 562 | ] 563 | }, 564 | { 565 | "cell_type": "markdown", 566 | "metadata": {}, 567 | "source": [ 568 | "In order to look properly at scalar data we need a look up table. Lets create one" 569 | ] 570 | }, 571 | { 572 | "cell_type": "code", 573 | "collapsed": false, 574 | "input": [ 575 | "t0,tf = time_array.GetRange()\n", 576 | "lut = vtk.vtkColorTransferFunction()\n", 577 | "lut.AddRGBPoint(t0 ,0,1,0) # green\n", 578 | "lut.AddRGBPoint(tf ,1,0,0) # red\n", 579 | "points_mapper.SetLookupTable(lut)" 580 | ], 581 | "language": "python", 582 | "metadata": {}, 583 | "outputs": [], 584 | "prompt_number": 16 585 | }, 586 | { 587 | "cell_type": "markdown", 588 | "metadata": {}, 589 | "source": [ 590 | "And now lets look at the changes" 591 | ] 592 | }, 593 | { 594 | "cell_type": "code", 595 | "collapsed": false, 596 | "input": [ 597 | "ren_win.Render()\n", 598 | "iren.Start()\n", 599 | "# remember, q to stop" 600 | ], 601 | "language": "python", 602 | "metadata": {}, 603 | "outputs": [], 604 | "prompt_number": 17 605 | }, 606 | { 607 | "cell_type": "markdown", 608 | "metadata": {}, 609 | "source": [ 610 | "You should see the following image in the 3d viewer\n", 611 | "\n", 612 | "" 613 | ] 614 | }, 615 | { 616 | "cell_type": "markdown", 617 | "metadata": {}, 618 | "source": [ 619 | "### 4.2: Detection data\n", 620 | "\n", 621 | "Now lets look at the more interesting data about the detections of the satellite. From the [web page](http://www.viscontest.rwth-aachen.de/data.html) we see the posible values are as follows:\n", 622 | "\n", 623 | "0: A value of 0 designates a clear air measurement, i.e. the sample detected nothing. These measurements are included for providing context only, i.e. in order to show the satellite's track. \n", 624 | "1: The least significant bit is used for ice detections. \n", 625 | "2: The second bit stands for ash detections. \n", 626 | "4: Finally, the third bit designates sulfate aerosol. \n", 627 | "\n", 628 | "As before we start by loading the scalars" 629 | ] 630 | }, 631 | { 632 | "cell_type": "code", 633 | "collapsed": false, 634 | "input": [ 635 | "detection_array = vtk.vtkFloatArray()\n", 636 | "detection_array.SetNumberOfComponents(1)\n", 637 | "detection_array.SetNumberOfTuples(nps)\n", 638 | "detection_array_big = pdata.GetArray(4)\n", 639 | "\n", 640 | "for i in xrange(nps):\n", 641 | " pid = pids.GetId(i)\n", 642 | " d = detection_array_big.GetValue(pid)\n", 643 | " detection_array.SetComponent(i,0,d)\n", 644 | "\n", 645 | "detection_array.SetName(\"detection\")\n", 646 | "pdata2 = pd.GetPointData()\n", 647 | "pdata2.SetScalars(detection_array)\n", 648 | "vfilter.SetInputData(pd)" 649 | ], 650 | "language": "python", 651 | "metadata": {}, 652 | "outputs": [], 653 | "prompt_number": 18 654 | }, 655 | { 656 | "cell_type": "markdown", 657 | "metadata": {}, 658 | "source": [ 659 | "Now lets create a more appropriate lookuptable" 660 | ] 661 | }, 662 | { 663 | "cell_type": "code", 664 | "collapsed": false, 665 | "input": [ 666 | "lut = vtk.vtkColorTransferFunction()\n", 667 | "lut.AddRGBPoint(0 ,0,0.2,0) # green\n", 668 | "lut.AddRGBPoint(1 ,0,0,0.9) # blue\n", 669 | "lut.AddRGBPoint(2 ,0,0.9,0.9) # cyan\n", 670 | "lut.AddRGBPoint(4 ,0.9,0,0) # red\n", 671 | "points_mapper.SetLookupTable(lut)\n", 672 | "points_mapper.UseLookupTableScalarRangeOn()" 673 | ], 674 | "language": "python", 675 | "metadata": {}, 676 | "outputs": [], 677 | "prompt_number": 19 678 | }, 679 | { 680 | "cell_type": "markdown", 681 | "metadata": {}, 682 | "source": [ 683 | "And now lets look at the changes" 684 | ] 685 | }, 686 | { 687 | "cell_type": "code", 688 | "collapsed": false, 689 | "input": [ 690 | "ren_win.Render()\n", 691 | "iren.Start()\n", 692 | "# remember, q to stop" 693 | ], 694 | "language": "python", 695 | "metadata": {}, 696 | "outputs": [], 697 | "prompt_number": 20 698 | }, 699 | { 700 | "cell_type": "markdown", 701 | "metadata": {}, 702 | "source": [ 703 | "You should see the following image in the 3d viewer\n", 704 | "\n", 705 | "" 706 | ] 707 | }, 708 | { 709 | "cell_type": "markdown", 710 | "metadata": {}, 711 | "source": [ 712 | "## 5: Multple orbits\n", 713 | "\n", 714 | "Now we are going to repeat what we did above for a random set of 20 orbits." 715 | ] 716 | }, 717 | { 718 | "cell_type": "code", 719 | "collapsed": false, 720 | "input": [ 721 | "import random\n", 722 | "norbits = mipas.GetNumberOfCells()\n", 723 | "sample = [random.randrange(0,norbits) for _ in xrange(20)]\n", 724 | "\n", 725 | "#remove original orbit\n", 726 | "ren.RemoveActor(points_ac)\n", 727 | "actors_dict = {}\n", 728 | "\n", 729 | "#We will reuse the lut from the last section\n", 730 | "lut = vtk.vtkColorTransferFunction()\n", 731 | "lut.AddRGBPoint(0 ,0,0.2,0) # green\n", 732 | "lut.AddRGBPoint(1 ,0,0,0.9) # blue\n", 733 | "lut.AddRGBPoint(2 ,0,0.9,0.9) # cyan\n", 734 | "lut.AddRGBPoint(4 ,0.9,0,0) # red\n", 735 | "\n", 736 | "for orb in sample:\n", 737 | " c1 = mipas.GetCell(orb)\n", 738 | " pids = c1.GetPointIds()\n", 739 | " nps = pids.GetNumberOfIds()\n", 740 | " points = vtk.vtkPoints()\n", 741 | " points.SetNumberOfPoints(nps)\n", 742 | " for i in xrange(nps):\n", 743 | " pid = pids.GetId(i)\n", 744 | " alt = altitude.GetValue(pid)\n", 745 | " p = mipas.GetPoint(pid)\n", 746 | " points.SetPoint(i,(p[0],p[1],alt))\n", 747 | " \n", 748 | " pd = vtk.vtkPolyData()\n", 749 | " pd.SetPoints(points)\n", 750 | " detection_array = vtk.vtkFloatArray()\n", 751 | " detection_array.SetNumberOfComponents(1)\n", 752 | " detection_array.SetNumberOfTuples(nps)\n", 753 | "\n", 754 | " for i in xrange(nps):\n", 755 | " pid = pids.GetId(i)\n", 756 | " d = detection_array_big.GetValue(pid)\n", 757 | " detection_array.SetComponent(i,0,d)\n", 758 | "\n", 759 | " detection_array.SetName(\"detection\")\n", 760 | " pdata2 = pd.GetPointData()\n", 761 | " pdata2.SetScalars(detection_array)\n", 762 | "\n", 763 | " vfilter = vtk.vtkVertexGlyphFilter()\n", 764 | " vfilter.SetInputData(pd)\n", 765 | " #add points to viewer\n", 766 | " points_mapper = vtk.vtkPolyDataMapper()\n", 767 | " points_mapper.SetInputConnection(vfilter.GetOutputPort())\n", 768 | " points_mapper.SetLookupTable(lut)\n", 769 | " # to keep the mapper from adjusting the range of the lut\n", 770 | " points_mapper.UseLookupTableScalarRangeOn()\n", 771 | " points_ac = vtk.vtkActor()\n", 772 | " points_ac.SetMapper(points_mapper)\n", 773 | "\n", 774 | " #make points bigger\n", 775 | " p = points_ac.GetProperty()\n", 776 | " p.SetPointSize(2)\n", 777 | " ren.AddActor(points_ac)\n", 778 | " actors_dict[points_ac] = orb\n" 779 | ], 780 | "language": "python", 781 | "metadata": {}, 782 | "outputs": [], 783 | "prompt_number": 21 784 | }, 785 | { 786 | "cell_type": "markdown", 787 | "metadata": {}, 788 | "source": [ 789 | "When showing multiple datasets it is important that the lookuptables for all of them matches. Here we are looking at 20 orbits with altitude and detection scalars. Lets look at the results" 790 | ] 791 | }, 792 | { 793 | "cell_type": "code", 794 | "collapsed": false, 795 | "input": [ 796 | "ren_win.Render()\n", 797 | "iren.Start()\n", 798 | "# remember, q to stop" 799 | ], 800 | "language": "python", 801 | "metadata": {}, 802 | "outputs": [], 803 | "prompt_number": 22 804 | }, 805 | { 806 | "cell_type": "markdown", 807 | "metadata": {}, 808 | "source": [ 809 | "You should see the following image in the 3d viewer\n", 810 | "\n", 811 | "" 812 | ] 813 | }, 814 | { 815 | "cell_type": "markdown", 816 | "metadata": {}, 817 | "source": [ 818 | "## 6: Some interaction\n", 819 | "\n", 820 | "It is easy to get lost when there is so much data in the screen. Lets add some interaction in order to help fix this. We are going to make a small example by adding tooltips when you hover the mouse over an orbit." 821 | ] 822 | }, 823 | { 824 | "cell_type": "code", 825 | "collapsed": false, 826 | "input": [ 827 | "balloon = vtk.vtkBalloonWidget()\n", 828 | "balloon.SetInteractor(iren)\n", 829 | "balloon.On()\n", 830 | "for ac,orb in actors_dict.iteritems():\n", 831 | " message = \"orbit number: %d\"%orb\n", 832 | " balloon.AddBalloon(ac,message)" 833 | ], 834 | "language": "python", 835 | "metadata": {}, 836 | "outputs": [], 837 | "prompt_number": 23 838 | }, 839 | { 840 | "cell_type": "markdown", 841 | "metadata": {}, 842 | "source": [ 843 | "Lets test this, after starting the interaction leave the mouse over one of the points." 844 | ] 845 | }, 846 | { 847 | "cell_type": "code", 848 | "collapsed": false, 849 | "input": [ 850 | "ren_win.Render()\n", 851 | "iren.Start()\n", 852 | "# remember, q to stop" 853 | ], 854 | "language": "python", 855 | "metadata": {}, 856 | "outputs": [], 857 | "prompt_number": 24 858 | }, 859 | { 860 | "cell_type": "markdown", 861 | "metadata": {}, 862 | "source": [ 863 | "You should see the following image in the 3d viewer\n", 864 | "\n", 865 | "" 866 | ] 867 | }, 868 | { 869 | "cell_type": "markdown", 870 | "metadata": {}, 871 | "source": [ 872 | "## 7: What's next?\n", 873 | "\n", 874 | "We have seen the basics of vtk. What follows is a list of possible improvements to the visualization you could try:\n", 875 | "\n", 876 | "- Add more complete messages to the tooltips\n", 877 | "- Show time and detection information at the same time\n", 878 | "- You can use [vtkGlyph3D](http://www.vtk.org/doc/nightly/html/classvtkGlyph3D.html) insted of GlyphFilter to get more complex representations for the points\n", 879 | "- You could embed the application inside a GUI (GTK, QT, TK) and add controls for all the operations\n", 880 | "- You could map the data to a sphere\n", 881 | "- You could filter the data and only show certain times or data with detections\n", 882 | "- You could add the rest of the data from the contest\n", 883 | "\n", 884 | "Feel free to try any other ideas you have. VTK is a very flexible and powerful platform. The documentation can be found [here](http://www.vtk.org/doc/nightly/html/index.html); and the [wiki](http://www.vtk.org/Wiki/VTK/Examples) contains several useful examples" 885 | ] 886 | }, 887 | { 888 | "cell_type": "code", 889 | "collapsed": false, 890 | "input": [], 891 | "language": "python", 892 | "metadata": {}, 893 | "outputs": [], 894 | "prompt_number": 24 895 | } 896 | ], 897 | "metadata": {} 898 | } 899 | ] 900 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 diego0020 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #vtk-python Tutorial 2 | 3 | This repository contains some iPython notebooks with vtk-python examples 4 | 5 | ## Satellite data 6 | 7 | ![Satellite example](vtk_example/screen8.PNG) 8 | 9 | Displays data from the [SCIVIS Contest 2014](http://www.viscontest.rwth-aachen.de/data.html), which contains information from satellites near volcano eruptions. 10 | 11 | [Satellite Example](https://github.com/diego0020/tutorial-vtk-python/blob/master/satellite_example.ipynb) 12 | 13 | ## Volumetric data 14 | ![Volume data example](volume_screens/Captura5.PNG) 15 | 16 | Based on a [vtk-example](http://www.vtk.org/Wiki/index.php?title=VTK/Examples/Cxx/Visualization/StreamLines) shows various techniques to visualize volumetric data. 17 | 18 | [Volumetric data example](https://github.com/diego0020/tutorial-vtk-python/blob/master/volumes_example.ipynb) 19 | 20 | ## Images and color mapping (not vtk) 21 | 22 | ![Medical data](color_maps/med0.png)![Climate data](color_maps/world0.png) 23 | 24 | Two examples of how to look at 2D data and apply color tables, this examples only uses matplotlib. 25 | 26 | 27 | [Medical Data](https://github.com/diego0020/tutorial-vtk-python/blob/master/color_map_med.ipynb) 28 | [World Map](https://github.com/diego0020/tutorial-vtk-python/blob/master/color_map_world.ipynb) 29 | -------------------------------------------------------------------------------- /color_maps/med0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/color_maps/med0.png -------------------------------------------------------------------------------- /color_maps/world0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/color_maps/world0.png -------------------------------------------------------------------------------- /intro_data.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/intro_data.zip -------------------------------------------------------------------------------- /satellite_example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "", 4 | "signature": "sha256:8031f848a4efe72adaa26b934b1d38198faafd98ecb4f3b52bda467d4a4e47ea" 5 | }, 6 | "nbformat": 3, 7 | "nbformat_minor": 0, 8 | "worksheets": [ 9 | { 10 | "cells": [ 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "# VTK Python Example: Looking at satellite data\n", 16 | "\n", 17 | "For this example we are going to be looking at the data from the [SCIVIS Contest 2014](http://www.viscontest.rwth-aachen.de/data.html). All data can be downloaded from the following url:\n", 18 | "http://www.viscontest.rwth-aachen.de/download.html\n" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "Test that vtk is correctly installed" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "collapsed": false, 31 | "input": [ 32 | "import vtk" 33 | ], 34 | "language": "python", 35 | "metadata": {}, 36 | "outputs": [] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "## 1: Loading the data\n", 43 | "\n", 44 | "All the data comes in vtk format, therefore it is straightforward to read it in vtk. " 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "collapsed": false, 50 | "input": [ 51 | "import os\n", 52 | "os.chdir(r\"D:\\viscontest\\viscontest14-data\\mipas\")\n", 53 | "reader = vtk.vtkPolyDataReader()\n", 54 | "reader.SetFileName(\"2011-MIPAS-VisContest.vtk\")\n", 55 | "reader.Update()\n", 56 | "mipas=reader.GetOutput()" 57 | ], 58 | "language": "python", 59 | "metadata": {}, 60 | "outputs": [], 61 | "prompt_number": 1 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "This contains the data for several orbits of the satellite, we are going to extract just the first orbit to makes thing easier" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "collapsed": false, 73 | "input": [ 74 | "c1 = mipas.GetCell(0)\n", 75 | "pids = c1.GetPointIds()\n", 76 | "nps = pids.GetNumberOfIds()\n", 77 | "# we are going to store the points in this new array\n", 78 | "points = vtk.vtkPoints()\n", 79 | "points.SetNumberOfPoints(nps)\n", 80 | "for i in xrange(nps):\n", 81 | " pid = pids.GetId(i)\n", 82 | " p = mipas.GetPoint(pid)\n", 83 | " points.SetPoint(i,(p[0],p[1],20)) # 20 will be a fixed height for now\n", 84 | "\n", 85 | "# and we are going to encapsulate them in this polydata\n", 86 | "pd = vtk.vtkPolyData()\n", 87 | "pd.SetPoints(points)" 88 | ], 89 | "language": "python", 90 | "metadata": {}, 91 | "outputs": [], 92 | "prompt_number": 2 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": {}, 97 | "source": [ 98 | "Now lets create a filter to make it easier to visualize the points" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "collapsed": false, 104 | "input": [ 105 | "vfilter = vtk.vtkVertexGlyphFilter()\n", 106 | "vfilter.SetInputData(pd)\n", 107 | "vfilter.Update()" 108 | ], 109 | "language": "python", 110 | "metadata": {}, 111 | "outputs": [], 112 | "prompt_number": 3 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "Lets setup the vtk environment" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "collapsed": false, 124 | "input": [ 125 | "ren_win = vtk.vtkRenderWindow()\n", 126 | "ren = vtk.vtkRenderer()\n", 127 | "iren = vtk.vtkRenderWindowInteractor()\n", 128 | "ren_win.SetInteractor(iren)\n", 129 | "ren_win.AddRenderer(ren)\n", 130 | "iren.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())\n", 131 | "ren.GradientBackgroundOn()\n", 132 | "ren.SetBackground2((0.5, 0.5, 0.5))\n", 133 | "ren.SetBackground((0.2, 0.2, 0.2))\n", 134 | "iren.Initialize()" 135 | ], 136 | "language": "python", 137 | "metadata": {}, 138 | "outputs": [], 139 | "prompt_number": 4 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "Finally, lets add the points to the viewer" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "collapsed": false, 151 | "input": [ 152 | "points_mapper = vtk.vtkPolyDataMapper()\n", 153 | "points_mapper.SetInputConnection(vfilter.GetOutputPort())\n", 154 | "points_ac = vtk.vtkActor()\n", 155 | "points_ac.SetMapper(points_mapper)\n", 156 | "\n", 157 | "#make points bigger\n", 158 | "p = points_ac.GetProperty()\n", 159 | "p.SetPointSize(2)\n", 160 | "ren.AddActor(points_ac)" 161 | ], 162 | "language": "python", 163 | "metadata": {}, 164 | "outputs": [], 165 | "prompt_number": 5 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "The vtk window should now be open but frozen, with the following command we can make it interactive. To exit interactive mode, press q while having focus on the vtk window" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "collapsed": false, 177 | "input": [ 178 | "iren.Start()\n", 179 | "#press q to stop interaction" 180 | ], 181 | "language": "python", 182 | "metadata": {}, 183 | "outputs": [], 184 | "prompt_number": 6 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "You should see the following image in the 3d viewer\n", 191 | "\n", 192 | "" 193 | ] 194 | }, 195 | { 196 | "cell_type": "markdown", 197 | "metadata": {}, 198 | "source": [ 199 | "##2: Adding some context\n", 200 | "The above image is hard to interpret, lets add the map of the earth to make it easier to understand" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "collapsed": false, 206 | "input": [ 207 | "os.chdir( r\"D:\\viscontest\\viscontest14-data\\support\")\n", 208 | "reader = vtk.vtkPolyDataReader()\n", 209 | "reader.SetFileName(\"coastlines.vtk\")\n", 210 | "reader.Update()\n", 211 | "cl = reader.GetOutput()\n", 212 | "cl_mapper = vtk.vtkPolyDataMapper()\n", 213 | "cl_mapper.SetInputData(cl)\n", 214 | "cl_actor = vtk.vtkActor()\n", 215 | "cl_actor.SetMapper(cl_mapper)\n", 216 | "ren.AddActor(cl_actor)\n", 217 | "ren_win.Render()" 218 | ], 219 | "language": "python", 220 | "metadata": {}, 221 | "outputs": [], 222 | "prompt_number": 7 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": {}, 227 | "source": [ 228 | "Notice in this case we don't need the vertex filter because the polydata is made of lines (instead of points). Now lets start the interactive window again" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "collapsed": false, 234 | "input": [ 235 | "iren.Start()\n", 236 | "#remember: q to stop interaction" 237 | ], 238 | "language": "python", 239 | "metadata": {}, 240 | "outputs": [], 241 | "prompt_number": 8 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "You should see the following image in the 3d viewer\n", 248 | "\n", 249 | "" 250 | ] 251 | }, 252 | { 253 | "cell_type": "markdown", 254 | "metadata": {}, 255 | "source": [ 256 | "# 3: Mapping the samples attitude\n", 257 | "\n", 258 | "Now we are going to map the attitude of the points over the map using the attitude data from the satellites. First lets look at this data" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "collapsed": false, 264 | "input": [ 265 | "pdata = mipas.GetPointData()\n", 266 | "print pdata" 267 | ], 268 | "language": "python", 269 | "metadata": {}, 270 | "outputs": [ 271 | { 272 | "output_type": "stream", 273 | "stream": "stdout", 274 | "text": [ 275 | "vtkPointData (000000000417BDD0)\n", 276 | " Debug: Off\n", 277 | " Modified Time: 215\n", 278 | " Reference Count: 2\n", 279 | " Registered Events: (none)\n", 280 | " Number Of Arrays: 5\n", 281 | " Array 0 name = time\n", 282 | " Array 1 name = altitude\n", 283 | " Array 2 name = orbit_id\n", 284 | " Array 3 name = profile_id\n", 285 | " Array 4 name = detection\n", 286 | " Number Of Components: 5\n", 287 | " Number Of Tuples: 1295837\n", 288 | " Copy Tuple Flags: ( 1 1 1 1 1 0 1 1 )\n", 289 | " Interpolate Flags: ( 1 1 1 1 1 0 0 1 )\n", 290 | " Pass Through Flags: ( 1 1 1 1 1 1 1 1 )\n", 291 | " Scalars: (none)\n", 292 | " Vectors: (none)\n", 293 | " Normals: (none)\n", 294 | " TCoords: (none)\n", 295 | " Tensors: (none)\n", 296 | " GlobalIds: (none)\n", 297 | " PedigreeIds: (none)\n", 298 | " EdgeFlag: (none)\n", 299 | "\n", 300 | "\n" 301 | ] 302 | } 303 | ], 304 | "prompt_number": 9 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": {}, 309 | "source": [ 310 | "We can see the altitude is stored in Array 1, now lets find its range" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "collapsed": false, 316 | "input": [ 317 | "altitude = pdata.GetArray(1)\n", 318 | "print altitude.GetRange()" 319 | ], 320 | "language": "python", 321 | "metadata": {}, 322 | "outputs": [ 323 | { 324 | "output_type": "stream", 325 | "stream": "stdout", 326 | "text": [ 327 | "(4.515999794006348, 30.0)\n" 328 | ] 329 | } 330 | ], 331 | "prompt_number": 10 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "In the above drawing we used a constant height of 20, so this range looks appropriate. Now lets recreate the points polydata using this new information" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "collapsed": false, 343 | "input": [ 344 | "for i in xrange(nps):\n", 345 | " pid = pids.GetId(i)\n", 346 | " alt = altitude.GetValue(pid)\n", 347 | " p = mipas.GetPoint(pid)\n", 348 | " points.SetPoint(i,(p[0],p[1],alt))\n", 349 | "pd = vtk.vtkPolyData()\n", 350 | "pd.SetPoints(points)\n", 351 | "vfilter.SetInputData(pd)" 352 | ], 353 | "language": "python", 354 | "metadata": {}, 355 | "outputs": [], 356 | "prompt_number": 11 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "metadata": {}, 361 | "source": [ 362 | "And finally let start the viewer again in order to see the changes" 363 | ] 364 | }, 365 | { 366 | "cell_type": "code", 367 | "collapsed": false, 368 | "input": [ 369 | "ren_win.Render()\n", 370 | "iren.Start()\n", 371 | "# remember, q to stop" 372 | ], 373 | "language": "python", 374 | "metadata": {}, 375 | "outputs": [], 376 | "prompt_number": 12 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "metadata": {}, 381 | "source": [ 382 | "You should see the following image in the 3d viewer\n", 383 | "\n", 384 | "" 385 | ] 386 | }, 387 | { 388 | "cell_type": "markdown", 389 | "metadata": {}, 390 | "source": [ 391 | "## 4: Scalar data\n", 392 | "Now we are going to look at some other scalars included in the data. \n", 393 | "\n", 394 | "### 4.1: Time data\n", 395 | "Lets start by looking at the *time* to get a better feeling of the direction in which the satellite travels" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "collapsed": false, 401 | "input": [ 402 | "# array to use inside our new polydata\n", 403 | "time_array = vtk.vtkFloatArray()\n", 404 | "time_array.SetNumberOfComponents(1)\n", 405 | "time_array.SetNumberOfTuples(nps)\n", 406 | "\n", 407 | "#original time array\n", 408 | "time_array_big = pdata.GetArray(0)\n", 409 | "\n", 410 | "for i in xrange(nps):\n", 411 | " pid = pids.GetId(i)\n", 412 | " t = time_array_big.GetValue(pid)\n", 413 | " time_array.SetComponent(i,0,t)\n", 414 | "\n", 415 | "time_array.SetName(\"time\")\n", 416 | "pdata2 = pd.GetPointData()\n", 417 | "pdata2.SetScalars(time_array)\n", 418 | "print pd" 419 | ], 420 | "language": "python", 421 | "metadata": {}, 422 | "outputs": [ 423 | { 424 | "output_type": "stream", 425 | "stream": "stdout", 426 | "text": [ 427 | "vtkPolyData (00000000042E57C0)\n", 428 | " Debug: Off\n", 429 | " Modified Time: 79460\n", 430 | " Reference Count: 3\n", 431 | " Registered Events: (none)\n", 432 | " Information: 00000000042EB8E0\n", 433 | " Data Released: False\n", 434 | " Global Release Data: Off\n", 435 | " UpdateTime: 79049\n", 436 | " Field Data:\n", 437 | " Debug: Off\n", 438 | " Modified Time: 78913\n", 439 | " Reference Count: 1\n", 440 | " Registered Events: (none)\n", 441 | " Number Of Arrays: 0\n", 442 | " Number Of Components: 0\n", 443 | " Number Of Tuples: 0\n", 444 | " Number Of Points: 1326\n", 445 | " Number Of Cells: 0\n", 446 | " Cell Data:\n", 447 | " Debug: Off\n", 448 | " Modified Time: 78916\n", 449 | " Reference Count: 1\n", 450 | " Registered Events: (none)\n", 451 | " Number Of Arrays: 0\n", 452 | " Number Of Components: 0\n", 453 | " Number Of Tuples: 0\n", 454 | " Copy Tuple Flags: ( 1 1 1 1 1 0 1 1 )\n", 455 | " Interpolate Flags: ( 1 1 1 1 1 0 0 1 )\n", 456 | " Pass Through Flags: ( 1 1 1 1 1 1 1 1 )\n", 457 | " Scalars: (none)\n", 458 | " Vectors: (none)\n", 459 | " Normals: (none)\n", 460 | " TCoords: (none)\n", 461 | " Tensors: (none)\n", 462 | " GlobalIds: (none)\n", 463 | " PedigreeIds: (none)\n", 464 | " EdgeFlag: (none)\n", 465 | " Point Data:\n", 466 | " Debug: Off\n", 467 | " Modified Time: 79460\n", 468 | " Reference Count: 2\n", 469 | " Registered Events: (none)\n", 470 | " Number Of Arrays: 1\n", 471 | " Array 0 name = time\n", 472 | " Number Of Components: 1\n", 473 | " Number Of Tuples: 1326\n", 474 | " Copy Tuple Flags: ( 1 1 1 1 1 0 1 1 )\n", 475 | " Interpolate Flags: ( 1 1 1 1 1 0 0 1 )\n", 476 | " Pass Through Flags: ( 1 1 1 1 1 1 1 1 )\n", 477 | " Scalars: \n", 478 | " Debug: Off\n", 479 | " Modified Time: 79457\n", 480 | " Reference Count: 2\n", 481 | " Registered Events: (none)\n", 482 | " Name: time\n", 483 | " Data type: float\n", 484 | " Size: 1326\n", 485 | " MaxId: 1325\n", 486 | " NumberOfComponents: 1\n", 487 | " Information: 0000000000000000\n", 488 | " Name: time\n", 489 | " Number Of Components: 1\n", 490 | " Number Of Tuples: 1326\n", 491 | " Size: 1326\n", 492 | " MaxId: 1325\n", 493 | " LookupTable: (none)\n", 494 | " Array: 00000000042C28E0\n", 495 | " Vectors: (none)\n", 496 | " Normals: (none)\n", 497 | " TCoords: (none)\n", 498 | " Tensors: (none)\n", 499 | " GlobalIds: (none)\n", 500 | " PedigreeIds: (none)\n", 501 | " EdgeFlag: (none)\n", 502 | " Bounds: \n", 503 | " Xmin,Xmax: (-148.527, 145.782)\n", 504 | " Ymin,Ymax: (-87.2112, 89.4011)\n", 505 | " Zmin,Zmax: (4.878, 29.963)\n", 506 | " Compute Time: 79462\n", 507 | " Number Of Points: 1326\n", 508 | " Point Coordinates: 0000000002CB3560\n", 509 | " Locator: 0000000000000000\n", 510 | " Number Of Vertices: 0\n", 511 | " Number Of Lines: 0\n", 512 | " Number Of Polygons: 0\n", 513 | " Number Of Triangle Strips: 0\n", 514 | " Number Of Pieces: 1\n", 515 | " Piece: 0\n", 516 | " Ghost Level: 0\n", 517 | "\n", 518 | "\n" 519 | ] 520 | } 521 | ], 522 | "prompt_number": 13 523 | }, 524 | { 525 | "cell_type": "markdown", 526 | "metadata": {}, 527 | "source": [ 528 | "We can see the time array is now located inside the point data. Now lets update the viewer and look at the changes" 529 | ] 530 | }, 531 | { 532 | "cell_type": "code", 533 | "collapsed": false, 534 | "input": [ 535 | "vfilter.SetInputData(pd)" 536 | ], 537 | "language": "python", 538 | "metadata": {}, 539 | "outputs": [], 540 | "prompt_number": 14 541 | }, 542 | { 543 | "cell_type": "code", 544 | "collapsed": false, 545 | "input": [ 546 | "ren_win.Render()\n", 547 | "iren.Start()\n", 548 | "# remember, q to stop" 549 | ], 550 | "language": "python", 551 | "metadata": {}, 552 | "outputs": [], 553 | "prompt_number": 15 554 | }, 555 | { 556 | "cell_type": "markdown", 557 | "metadata": {}, 558 | "source": [ 559 | "You should see the following image in the 3d viewer\n", 560 | "\n", 561 | "" 562 | ] 563 | }, 564 | { 565 | "cell_type": "markdown", 566 | "metadata": {}, 567 | "source": [ 568 | "In order to look properly at scalar data we need a look up table. Lets create one" 569 | ] 570 | }, 571 | { 572 | "cell_type": "code", 573 | "collapsed": false, 574 | "input": [ 575 | "t0,tf = time_array.GetRange()\n", 576 | "lut = vtk.vtkColorTransferFunction()\n", 577 | "lut.AddRGBPoint(t0 ,0,1,0) # green\n", 578 | "lut.AddRGBPoint(tf ,1,0,0) # red\n", 579 | "points_mapper.SetLookupTable(lut)" 580 | ], 581 | "language": "python", 582 | "metadata": {}, 583 | "outputs": [], 584 | "prompt_number": 16 585 | }, 586 | { 587 | "cell_type": "markdown", 588 | "metadata": {}, 589 | "source": [ 590 | "And now lets look at the changes" 591 | ] 592 | }, 593 | { 594 | "cell_type": "code", 595 | "collapsed": false, 596 | "input": [ 597 | "ren_win.Render()\n", 598 | "iren.Start()\n", 599 | "# remember, q to stop" 600 | ], 601 | "language": "python", 602 | "metadata": {}, 603 | "outputs": [], 604 | "prompt_number": 17 605 | }, 606 | { 607 | "cell_type": "markdown", 608 | "metadata": {}, 609 | "source": [ 610 | "You should see the following image in the 3d viewer\n", 611 | "\n", 612 | "" 613 | ] 614 | }, 615 | { 616 | "cell_type": "markdown", 617 | "metadata": {}, 618 | "source": [ 619 | "### 4.2: Detection data\n", 620 | "\n", 621 | "Now lets look at the more interesting data about the detections of the satellite. From the [web page](http://www.viscontest.rwth-aachen.de/data.html) we see the posible values are as follows:\n", 622 | "\n", 623 | "0: A value of 0 designates a clear air measurement, i.e. the sample detected nothing. These measurements are included for providing context only, i.e. in order to show the satellite's track. \n", 624 | "1: The least significant bit is used for ice detections. \n", 625 | "2: The second bit stands for ash detections. \n", 626 | "4: Finally, the third bit designates sulfate aerosol. \n", 627 | "\n", 628 | "As before we start by loading the scalars" 629 | ] 630 | }, 631 | { 632 | "cell_type": "code", 633 | "collapsed": false, 634 | "input": [ 635 | "detection_array = vtk.vtkFloatArray()\n", 636 | "detection_array.SetNumberOfComponents(1)\n", 637 | "detection_array.SetNumberOfTuples(nps)\n", 638 | "detection_array_big = pdata.GetArray(4)\n", 639 | "\n", 640 | "for i in xrange(nps):\n", 641 | " pid = pids.GetId(i)\n", 642 | " d = detection_array_big.GetValue(pid)\n", 643 | " detection_array.SetComponent(i,0,d)\n", 644 | "\n", 645 | "detection_array.SetName(\"detection\")\n", 646 | "pdata2 = pd.GetPointData()\n", 647 | "pdata2.SetScalars(detection_array)\n", 648 | "vfilter.SetInputData(pd)" 649 | ], 650 | "language": "python", 651 | "metadata": {}, 652 | "outputs": [], 653 | "prompt_number": 18 654 | }, 655 | { 656 | "cell_type": "markdown", 657 | "metadata": {}, 658 | "source": [ 659 | "Now lets create a more appropriate lookuptable" 660 | ] 661 | }, 662 | { 663 | "cell_type": "code", 664 | "collapsed": false, 665 | "input": [ 666 | "lut = vtk.vtkColorTransferFunction()\n", 667 | "lut.AddRGBPoint(0 ,0,0.2,0) # green\n", 668 | "lut.AddRGBPoint(1 ,0,0,0.9) # blue\n", 669 | "lut.AddRGBPoint(2 ,0,0.9,0.9) # cyan\n", 670 | "lut.AddRGBPoint(4 ,0.9,0,0) # red\n", 671 | "points_mapper.SetLookupTable(lut)\n", 672 | "points_mapper.UseLookupTableScalarRangeOn()" 673 | ], 674 | "language": "python", 675 | "metadata": {}, 676 | "outputs": [], 677 | "prompt_number": 19 678 | }, 679 | { 680 | "cell_type": "markdown", 681 | "metadata": {}, 682 | "source": [ 683 | "And now lets look at the changes" 684 | ] 685 | }, 686 | { 687 | "cell_type": "code", 688 | "collapsed": false, 689 | "input": [ 690 | "ren_win.Render()\n", 691 | "iren.Start()\n", 692 | "# remember, q to stop" 693 | ], 694 | "language": "python", 695 | "metadata": {}, 696 | "outputs": [], 697 | "prompt_number": 20 698 | }, 699 | { 700 | "cell_type": "markdown", 701 | "metadata": {}, 702 | "source": [ 703 | "You should see the following image in the 3d viewer\n", 704 | "\n", 705 | "" 706 | ] 707 | }, 708 | { 709 | "cell_type": "markdown", 710 | "metadata": {}, 711 | "source": [ 712 | "## 5: Multple orbits\n", 713 | "\n", 714 | "Now we are going to repeat what we did above for a random set of 20 orbits." 715 | ] 716 | }, 717 | { 718 | "cell_type": "code", 719 | "collapsed": false, 720 | "input": [ 721 | "import random\n", 722 | "norbits = mipas.GetNumberOfCells()\n", 723 | "sample = [random.randrange(0,norbits) for _ in xrange(20)]\n", 724 | "\n", 725 | "#remove original orbit\n", 726 | "ren.RemoveActor(points_ac)\n", 727 | "actors_dict = {}\n", 728 | "\n", 729 | "#We will reuse the lut from the last section\n", 730 | "lut = vtk.vtkColorTransferFunction()\n", 731 | "lut.AddRGBPoint(0 ,0,0.2,0) # green\n", 732 | "lut.AddRGBPoint(1 ,0,0,0.9) # blue\n", 733 | "lut.AddRGBPoint(2 ,0,0.9,0.9) # cyan\n", 734 | "lut.AddRGBPoint(4 ,0.9,0,0) # red\n", 735 | "\n", 736 | "for orb in sample:\n", 737 | " c1 = mipas.GetCell(orb)\n", 738 | " pids = c1.GetPointIds()\n", 739 | " nps = pids.GetNumberOfIds()\n", 740 | " points = vtk.vtkPoints()\n", 741 | " points.SetNumberOfPoints(nps)\n", 742 | " for i in xrange(nps):\n", 743 | " pid = pids.GetId(i)\n", 744 | " alt = altitude.GetValue(pid)\n", 745 | " p = mipas.GetPoint(pid)\n", 746 | " points.SetPoint(i,(p[0],p[1],alt))\n", 747 | " \n", 748 | " pd = vtk.vtkPolyData()\n", 749 | " pd.SetPoints(points)\n", 750 | " detection_array = vtk.vtkFloatArray()\n", 751 | " detection_array.SetNumberOfComponents(1)\n", 752 | " detection_array.SetNumberOfTuples(nps)\n", 753 | "\n", 754 | " for i in xrange(nps):\n", 755 | " pid = pids.GetId(i)\n", 756 | " d = detection_array_big.GetValue(pid)\n", 757 | " detection_array.SetComponent(i,0,d)\n", 758 | "\n", 759 | " detection_array.SetName(\"detection\")\n", 760 | " pdata2 = pd.GetPointData()\n", 761 | " pdata2.SetScalars(detection_array)\n", 762 | "\n", 763 | " vfilter = vtk.vtkVertexGlyphFilter()\n", 764 | " vfilter.SetInputData(pd)\n", 765 | " #add points to viewer\n", 766 | " points_mapper = vtk.vtkPolyDataMapper()\n", 767 | " points_mapper.SetInputConnection(vfilter.GetOutputPort())\n", 768 | " points_mapper.SetLookupTable(lut)\n", 769 | " # to keep the mapper from adjusting the range of the lut\n", 770 | " points_mapper.UseLookupTableScalarRangeOn()\n", 771 | " points_ac = vtk.vtkActor()\n", 772 | " points_ac.SetMapper(points_mapper)\n", 773 | "\n", 774 | " #make points bigger\n", 775 | " p = points_ac.GetProperty()\n", 776 | " p.SetPointSize(2)\n", 777 | " ren.AddActor(points_ac)\n", 778 | " actors_dict[points_ac] = orb\n" 779 | ], 780 | "language": "python", 781 | "metadata": {}, 782 | "outputs": [], 783 | "prompt_number": 21 784 | }, 785 | { 786 | "cell_type": "markdown", 787 | "metadata": {}, 788 | "source": [ 789 | "When showing multiple datasets it is important that the lookuptables for all of them matches. Here we are looking at 20 orbits with altitude and detection scalars. Lets look at the results" 790 | ] 791 | }, 792 | { 793 | "cell_type": "code", 794 | "collapsed": false, 795 | "input": [ 796 | "ren_win.Render()\n", 797 | "iren.Start()\n", 798 | "# remember, q to stop" 799 | ], 800 | "language": "python", 801 | "metadata": {}, 802 | "outputs": [], 803 | "prompt_number": 22 804 | }, 805 | { 806 | "cell_type": "markdown", 807 | "metadata": {}, 808 | "source": [ 809 | "You should see the following image in the 3d viewer\n", 810 | "\n", 811 | "" 812 | ] 813 | }, 814 | { 815 | "cell_type": "markdown", 816 | "metadata": {}, 817 | "source": [ 818 | "## 6: Some interaction\n", 819 | "\n", 820 | "It is easy to get lost when there is so much data in the screen. Lets add some interaction in order to help fix this. We are going to make a small example by adding tooltips when you hover the mouse over an orbit." 821 | ] 822 | }, 823 | { 824 | "cell_type": "code", 825 | "collapsed": false, 826 | "input": [ 827 | "balloon = vtk.vtkBalloonWidget()\n", 828 | "balloon.SetInteractor(iren)\n", 829 | "balloon.On()\n", 830 | "for ac,orb in actors_dict.iteritems():\n", 831 | " message = \"orbit number: %d\"%orb\n", 832 | " balloon.AddBalloon(ac,message)" 833 | ], 834 | "language": "python", 835 | "metadata": {}, 836 | "outputs": [], 837 | "prompt_number": 23 838 | }, 839 | { 840 | "cell_type": "markdown", 841 | "metadata": {}, 842 | "source": [ 843 | "Lets test this, after starting the interaction leave the mouse over one of the points." 844 | ] 845 | }, 846 | { 847 | "cell_type": "code", 848 | "collapsed": false, 849 | "input": [ 850 | "ren_win.Render()\n", 851 | "iren.Start()\n", 852 | "# remember, q to stop" 853 | ], 854 | "language": "python", 855 | "metadata": {}, 856 | "outputs": [], 857 | "prompt_number": 24 858 | }, 859 | { 860 | "cell_type": "markdown", 861 | "metadata": {}, 862 | "source": [ 863 | "You should see the following image in the 3d viewer\n", 864 | "\n", 865 | "" 866 | ] 867 | }, 868 | { 869 | "cell_type": "markdown", 870 | "metadata": {}, 871 | "source": [ 872 | "## 7: What's next?\n", 873 | "\n", 874 | "We have seen the basics of vtk. What follows is a list of possible improvements to the visualization you could try:\n", 875 | "\n", 876 | "- Add more complete messages to the tooltips\n", 877 | "- Show time and detection information at the same time\n", 878 | "- You can use [vtkGlyph3D](http://www.vtk.org/doc/nightly/html/classvtkGlyph3D.html) insted of GlyphFilter to get more complex representations for the points\n", 879 | "- You could embed the application inside a GUI (GTK, QT, TK) and add controls for all the operations\n", 880 | "- You could map the data to a sphere\n", 881 | "- You could filter the data and only show certain times or data with detections\n", 882 | "- You could add the rest of the data from the contest\n", 883 | "\n", 884 | "Feel free to try any other ideas you have. VTK is a very flexible and powerful platform. The documentation can be found [here](http://www.vtk.org/doc/nightly/html/index.html); and the [wiki](http://www.vtk.org/Wiki/VTK/Examples) contains several useful examples" 885 | ] 886 | }, 887 | { 888 | "cell_type": "code", 889 | "collapsed": false, 890 | "input": [], 891 | "language": "python", 892 | "metadata": {}, 893 | "outputs": [], 894 | "prompt_number": 24 895 | } 896 | ], 897 | "metadata": {} 898 | } 899 | ] 900 | } -------------------------------------------------------------------------------- /volume_data.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_data.zip -------------------------------------------------------------------------------- /volume_screens/Captura.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura.PNG -------------------------------------------------------------------------------- /volume_screens/Captura10.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura10.PNG -------------------------------------------------------------------------------- /volume_screens/Captura11.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura11.PNG -------------------------------------------------------------------------------- /volume_screens/Captura12.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura12.PNG -------------------------------------------------------------------------------- /volume_screens/Captura2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura2.PNG -------------------------------------------------------------------------------- /volume_screens/Captura3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura3.PNG -------------------------------------------------------------------------------- /volume_screens/Captura4.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura4.PNG -------------------------------------------------------------------------------- /volume_screens/Captura5.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura5.PNG -------------------------------------------------------------------------------- /volume_screens/Captura6.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura6.PNG -------------------------------------------------------------------------------- /volume_screens/Captura7.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura7.PNG -------------------------------------------------------------------------------- /volume_screens/Captura8.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura8.PNG -------------------------------------------------------------------------------- /volume_screens/Captura9.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Captura9.PNG -------------------------------------------------------------------------------- /volume_screens/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/volume_screens/Thumbs.db -------------------------------------------------------------------------------- /volumes_example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "", 4 | "signature": "sha256:5476d817dae7001a20d01364b19d4daf60c122af3cb6bc736f63f145edec9041" 5 | }, 6 | "nbformat": 3, 7 | "nbformat_minor": 0, 8 | "worksheets": [ 9 | { 10 | "cells": [ 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "# Exploring Volumetric data with VTK\n", 16 | "\n", 17 | "Based on [this example](http://www.vtk.org/Wiki/index.php?title=VTK/Examples/Cxx/Visualization/StreamLines)" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "collapsed": false, 23 | "input": [ 24 | "import os\n", 25 | "os.chdir(\"D:/vtk_data/VTKData/Data\")\n", 26 | "#os.chdir(r\"C:\\Users\\Diego\\Programas\\vtk\\VTKData\\Data\")\n", 27 | "import vtk" 28 | ], 29 | "language": "python", 30 | "metadata": {}, 31 | "outputs": [], 32 | "prompt_number": 9 33 | }, 34 | { 35 | "cell_type": "code", 36 | "collapsed": false, 37 | "input": [ 38 | "pl3d = vtk.vtkMultiBlockPLOT3DReader()\n", 39 | "\n", 40 | "xyx_file = \"combxyz.bin\"\n", 41 | "q_file = \"combq.bin\"\n", 42 | "pl3d.SetXYZFileName(xyx_file)\n", 43 | "pl3d.SetQFileName(q_file)\n", 44 | "pl3d.SetScalarFunctionNumber(100)\n", 45 | "pl3d.SetVectorFunctionNumber(202)\n", 46 | "pl3d.Update()" 47 | ], 48 | "language": "python", 49 | "metadata": {}, 50 | "outputs": [], 51 | "prompt_number": 10 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "From the example code:\n", 58 | "\n", 59 | "Here we read data from a annular combustor. A combustor burns fuel\n", 60 | "and air in a gas turbine (e.g., a jet engine) and the hot gas\n", 61 | "eventually makes its way to the turbine section." 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "collapsed": false, 67 | "input": [ 68 | "blocks = pl3d.GetOutput()\n", 69 | "b0 = blocks.GetBlock(0)" 70 | ], 71 | "language": "python", 72 | "metadata": {}, 73 | "outputs": [], 74 | "prompt_number": 11 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "Loot at what is inside the data set" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "collapsed": false, 86 | "input": [ 87 | "# uncomment to get long output\n", 88 | "# print b0" 89 | ], 90 | "language": "python", 91 | "metadata": {}, 92 | "outputs": [], 93 | "prompt_number": 12 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": {}, 98 | "source": [ 99 | "Set up vtk environment" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "collapsed": false, 105 | "input": [ 106 | "renderer = vtk.vtkRenderer()\n", 107 | "render_window = vtk.vtkRenderWindow()\n", 108 | "render_window.AddRenderer(renderer)\n", 109 | "interactor = vtk.vtkRenderWindowInteractor()\n", 110 | "interactor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())\n", 111 | "render_window.SetInteractor(interactor)\n", 112 | "renderer.SetBackground(0.2,0.2,0.2)\n", 113 | "interactor.Initialize()\n", 114 | "render_window.Render()" 115 | ], 116 | "language": "python", 117 | "metadata": {}, 118 | "outputs": [], 119 | "prompt_number": 13 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "Look at an outline of the data for context" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "collapsed": false, 131 | "input": [ 132 | "outline = vtk.vtkStructuredGridOutlineFilter()\n", 133 | "outline.SetInputData(b0)\n", 134 | "outline_mapper = vtk.vtkPolyDataMapper()\n", 135 | "outline_mapper.SetInputConnection(outline.GetOutputPort())\n", 136 | "outline_actor = vtk.vtkActor()\n", 137 | "outline_actor.SetMapper(outline_mapper)\n", 138 | "outline_actor.GetProperty().SetColor(1,1,1)\n", 139 | "renderer.AddActor(outline_actor)\n", 140 | "renderer.ResetCamera()" 141 | ], 142 | "language": "python", 143 | "metadata": {}, 144 | "outputs": [], 145 | "prompt_number": 14 146 | }, 147 | { 148 | "cell_type": "code", 149 | "collapsed": false, 150 | "input": [ 151 | "\n", 152 | "render_window.Render()\n", 153 | "interactor.Start()" 154 | ], 155 | "language": "python", 156 | "metadata": {}, 157 | "outputs": [], 158 | "prompt_number": 15 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "## Scalars\n", 165 | "\n", 166 | "The data contains two scalar arrays and one vector array. We are going to start exploring the data set by looking at the first scalar array \"Density\". We will use several different methods to *look* at this data" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "metadata": {}, 172 | "source": [ 173 | "### Points" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "collapsed": false, 179 | "input": [ 180 | "points = vtk.vtkVertexGlyphFilter()\n", 181 | "points.SetInputData(b0)\n", 182 | "scalars_mapper = vtk.vtkPolyDataMapper()\n", 183 | "scalars_actor = vtk.vtkActor()\n", 184 | "scalars_actor.SetMapper(scalars_mapper)\n", 185 | "scalars_mapper.SetInputConnection(points.GetOutputPort())" 186 | ], 187 | "language": "python", 188 | "metadata": {}, 189 | "outputs": [], 190 | "prompt_number": 59 191 | }, 192 | { 193 | "cell_type": "code", 194 | "collapsed": false, 195 | "input": [ 196 | "scalars_mapper.SetScalarModeToUsePointData()\n", 197 | "#print scalars_mapper.GetLookupTable()" 198 | ], 199 | "language": "python", 200 | "metadata": {}, 201 | "outputs": [], 202 | "prompt_number": 60 203 | }, 204 | { 205 | "cell_type": "code", 206 | "collapsed": false, 207 | "input": [ 208 | "renderer.AddActor(scalars_actor)\n", 209 | "render_window.Render()\n", 210 | "interactor.Start()\n", 211 | "renderer.RemoveActor(scalars_actor)\n", 212 | "render_window.Render()" 213 | ], 214 | "language": "python", 215 | "metadata": {}, 216 | "outputs": [], 217 | "prompt_number": 61 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "metadata": {}, 222 | "source": [ 223 | "![Points with scalar data](volume_screens/Captura.PNG)" 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": {}, 229 | "source": [ 230 | "### Solid" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "collapsed": false, 236 | "input": [ 237 | "poly = vtk.vtkGeometryFilter()\n", 238 | "poly.SetInputData(b0)\n", 239 | "#scalars_mapper = vtk.vtkPolyDataMapper()\n", 240 | "#scalars_actor = vtk.vtkActor()\n", 241 | "#scalars_actor.SetMapper(scalars_mapper)\n", 242 | "scalars_mapper.SetInputConnection(poly.GetOutputPort())" 243 | ], 244 | "language": "python", 245 | "metadata": {}, 246 | "outputs": [], 247 | "prompt_number": 62 248 | }, 249 | { 250 | "cell_type": "code", 251 | "collapsed": false, 252 | "input": [ 253 | "renderer.AddActor(scalars_actor)\n", 254 | "render_window.Render()\n", 255 | "interactor.Start()\n", 256 | "renderer.RemoveActor(scalars_actor)\n", 257 | "render_window.Render()" 258 | ], 259 | "language": "python", 260 | "metadata": {}, 261 | "outputs": [], 262 | "prompt_number": 63 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "![Solid with scalar data](volume_screens/Captura2.PNG)" 269 | ] 270 | }, 271 | { 272 | "cell_type": "markdown", 273 | "metadata": {}, 274 | "source": [ 275 | "### Sample with plane" 276 | ] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "collapsed": false, 281 | "input": [ 282 | "samples = vtk.vtkPlaneWidget()\n", 283 | "samples.SetResolution(24)\n", 284 | "samples.SetOrigin(2,-2,26)\n", 285 | "samples.SetPoint1(2, 2,26)\n", 286 | "samples.SetPoint2(2,-2,32)\n", 287 | "samples_pd = samples.GetPolyDataAlgorithm()\n", 288 | "samples.SetInteractor(interactor)\n", 289 | "samples.SetRepresentationToOutline()\n", 290 | "samples.On()" 291 | ], 292 | "language": "python", 293 | "metadata": {}, 294 | "outputs": [], 295 | "prompt_number": 64 296 | }, 297 | { 298 | "cell_type": "code", 299 | "collapsed": false, 300 | "input": [ 301 | "probe = vtk.vtkProbeFilter()\n", 302 | "probe.SetSourceData(b0)\n", 303 | "probe.SetInputConnection(samples_pd.GetOutputPort())\n", 304 | "probed_mapper = vtk.vtkPolyDataMapper()\n", 305 | "probed_mapper.SetInputConnection(probe.GetOutputPort())\n", 306 | "probed_actor = vtk.vtkActor()\n", 307 | "probed_actor.SetMapper(probed_mapper)" 308 | ], 309 | "language": "python", 310 | "metadata": {}, 311 | "outputs": [], 312 | "prompt_number": 65 313 | }, 314 | { 315 | "cell_type": "code", 316 | "collapsed": false, 317 | "input": [ 318 | "samples.On()\n", 319 | "renderer.AddActor(probed_actor)\n", 320 | "render_window.Render()\n", 321 | "interactor.Start()\n", 322 | "samples.Off()\n", 323 | "renderer.RemoveActor(probed_actor)" 324 | ], 325 | "language": "python", 326 | "metadata": {}, 327 | "outputs": [], 328 | "prompt_number": 66 329 | }, 330 | { 331 | "cell_type": "markdown", 332 | "metadata": {}, 333 | "source": [ 334 | "![Sampling with a plane](volume_screens/Captura3.PNG)" 335 | ] 336 | }, 337 | { 338 | "cell_type": "markdown", 339 | "metadata": {}, 340 | "source": [ 341 | "### Iso-surfaces" 342 | ] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "collapsed": false, 347 | "input": [ 348 | "min_s, max_s = b0.GetScalarRange()\n", 349 | "print min_s, max_s" 350 | ], 351 | "language": "python", 352 | "metadata": {}, 353 | "outputs": [ 354 | { 355 | "output_type": "stream", 356 | "stream": "stdout", 357 | "text": [ 358 | "0.197813093662 0.710419237614\n" 359 | ] 360 | } 361 | ], 362 | "prompt_number": 67 363 | }, 364 | { 365 | "cell_type": "code", 366 | "collapsed": false, 367 | "input": [ 368 | "contours = vtk.vtkContourFilter()\n", 369 | "contours.SetInputData(b0)\n", 370 | "contours.GenerateValues(5, (min_s,max_s))\n", 371 | "contours_mapper = vtk.vtkPolyDataMapper()\n", 372 | "contours_mapper.SetInputConnection(contours.GetOutputPort())\n", 373 | "contours_actor = vtk.vtkActor()\n", 374 | "contours_actor.SetMapper(contours_mapper)\n" 375 | ], 376 | "language": "python", 377 | "metadata": {}, 378 | "outputs": [], 379 | "prompt_number": 68 380 | }, 381 | { 382 | "cell_type": "code", 383 | "collapsed": false, 384 | "input": [ 385 | "renderer.AddActor(contours_actor)\n", 386 | "render_window.Render()\n", 387 | "interactor.Start()\n", 388 | "renderer.RemoveActor(contours_actor)\n", 389 | "render_window.Render()" 390 | ], 391 | "language": "python", 392 | "metadata": {}, 393 | "outputs": [], 394 | "prompt_number": 69 395 | }, 396 | { 397 | "cell_type": "markdown", 398 | "metadata": {}, 399 | "source": [ 400 | "![Iso-surfaces](volume_screens/Captura4.PNG)" 401 | ] 402 | }, 403 | { 404 | "cell_type": "markdown", 405 | "metadata": {}, 406 | "source": [ 407 | "We will add some transparency to be able to look inside" 408 | ] 409 | }, 410 | { 411 | "cell_type": "code", 412 | "collapsed": false, 413 | "input": [ 414 | "contours_actor.GetProperty().SetOpacity(0.5)" 415 | ], 416 | "language": "python", 417 | "metadata": {}, 418 | "outputs": [], 419 | "prompt_number": 70 420 | }, 421 | { 422 | "cell_type": "code", 423 | "collapsed": false, 424 | "input": [ 425 | "renderer.AddActor(contours_actor)\n", 426 | "render_window.Render()\n", 427 | "interactor.Start()\n", 428 | "renderer.RemoveActor(contours_actor)\n", 429 | "render_window.Render()" 430 | ], 431 | "language": "python", 432 | "metadata": {}, 433 | "outputs": [], 434 | "prompt_number": 71 435 | }, 436 | { 437 | "cell_type": "markdown", 438 | "metadata": {}, 439 | "source": [ 440 | "![Iso surfaces with opacity](volume_screens/Captura5.PNG)" 441 | ] 442 | }, 443 | { 444 | "cell_type": "markdown", 445 | "metadata": {}, 446 | "source": [ 447 | "### Volume Rendering" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "collapsed": false, 453 | "input": [ 454 | "volume_mapper = vtk.vtkUnstructuredGridVolumeRayCastMapper()\n", 455 | "#volume_mapper = vtk.vtkProjectedTetrahedraMapper()\n", 456 | "#volume_mapper = vtk.vtkUnstructuredGridVolumeZSweepMapper()\n", 457 | "\n", 458 | "#volume_mapper.SetBlendModeToComposite() # try others\n", 459 | "#volume_mapper.SetBlendModeToMinimumIntensity()\n", 460 | "tri_filter = vtk.vtkDataSetTriangleFilter()\n", 461 | "tri_filter.SetInputData(b0)\n", 462 | "volume_mapper.SetInputConnection(tri_filter.GetOutputPort())\n", 463 | "volume = vtk.vtkVolume()\n", 464 | "volume.SetMapper(volume_mapper)\n", 465 | "volume_property = volume.GetProperty()\n" 466 | ], 467 | "language": "python", 468 | "metadata": {}, 469 | "outputs": [], 470 | "prompt_number": 72 471 | }, 472 | { 473 | "cell_type": "code", 474 | "collapsed": false, 475 | "input": [ 476 | "intensity = vtk.vtkPiecewiseFunction()\n", 477 | "intensity.AddPoint(min_s,0.1)\n", 478 | "intensity.AddPoint((max_s+min_s)/2.0, 1.0)\n", 479 | "intensity.AddPoint(max_s, 1.0)\n", 480 | "color = vtk.vtkColorTransferFunction()\n", 481 | "color.AddRGBPoint(min_s,0,1,0)\n", 482 | "color.AddRGBPoint(max_s,1,0,0)\n", 483 | "volume_property.SetScalarOpacity(intensity)\n", 484 | "volume_property.SetInterpolationTypeToLinear()\n", 485 | "volume_property.SetColor(color)\n", 486 | "volume_property.ShadeOff()\n", 487 | "volume.VisibilityOn()" 488 | ], 489 | "language": "python", 490 | "metadata": {}, 491 | "outputs": [], 492 | "prompt_number": 73 493 | }, 494 | { 495 | "cell_type": "code", 496 | "collapsed": false, 497 | "input": [ 498 | "renderer.AddViewProp(volume)\n", 499 | "render_window.Render()\n", 500 | "interactor.Start()\n", 501 | "renderer.RemoveViewProp(volume)" 502 | ], 503 | "language": "python", 504 | "metadata": {}, 505 | "outputs": [], 506 | "prompt_number": 74 507 | }, 508 | { 509 | "cell_type": "markdown", 510 | "metadata": {}, 511 | "source": [ 512 | "![Volume rendering](volume_screens/Captura6.PNG)" 513 | ] 514 | }, 515 | { 516 | "cell_type": "markdown", 517 | "metadata": {}, 518 | "source": [ 519 | "## Vectors\n", 520 | "\n", 521 | "Now we are going to explore the vector data inside the dataset. We will use two methods" 522 | ] 523 | }, 524 | { 525 | "cell_type": "markdown", 526 | "metadata": {}, 527 | "source": [ 528 | "### Glyphs" 529 | ] 530 | }, 531 | { 532 | "cell_type": "code", 533 | "collapsed": false, 534 | "input": [ 535 | "arrow = vtk.vtkArrowSource()\n", 536 | "glyphs = vtk.vtkGlyph3D()\n", 537 | "glyphs.SetInputData(b0)\n", 538 | "glyphs.SetSourceConnection(arrow.GetOutputPort())" 539 | ], 540 | "language": "python", 541 | "metadata": {}, 542 | "outputs": [], 543 | "prompt_number": 75 544 | }, 545 | { 546 | "cell_type": "code", 547 | "collapsed": false, 548 | "input": [ 549 | "glyph_mapper = vtk.vtkPolyDataMapper()\n", 550 | "glyph_mapper.SetInputConnection(glyphs.GetOutputPort())\n", 551 | "glyph_actor = vtk.vtkActor()\n", 552 | "glyph_actor.SetMapper(glyph_mapper)" 553 | ], 554 | "language": "python", 555 | "metadata": {}, 556 | "outputs": [], 557 | "prompt_number": 76 558 | }, 559 | { 560 | "cell_type": "code", 561 | "collapsed": false, 562 | "input": [ 563 | "glyphs.SetVectorModeToUseVector()\n", 564 | "glyphs.SetScaleModeToScaleByScalar()\n", 565 | "#glyphs.SetScaleModeToDataScalingOff()\n", 566 | "\n", 567 | "glyph_mapper.UseLookupTableScalarRangeOn()" 568 | ], 569 | "language": "python", 570 | "metadata": {}, 571 | "outputs": [], 572 | "prompt_number": 77 573 | }, 574 | { 575 | "cell_type": "code", 576 | "collapsed": false, 577 | "input": [ 578 | "renderer.AddActor(glyph_actor)\n", 579 | "render_window.Render()\n", 580 | "interactor.Start()\n", 581 | "renderer.RemoveActor(glyph_actor)\n", 582 | "render_window.Render()" 583 | ], 584 | "language": "python", 585 | "metadata": {}, 586 | "outputs": [], 587 | "prompt_number": 78 588 | }, 589 | { 590 | "cell_type": "markdown", 591 | "metadata": {}, 592 | "source": [ 593 | "![Vectors as glyphs](volume_screens/Captura7.PNG)" 594 | ] 595 | }, 596 | { 597 | "cell_type": "markdown", 598 | "metadata": {}, 599 | "source": [ 600 | "Now lets scale by the norm of the vectors" 601 | ] 602 | }, 603 | { 604 | "cell_type": "code", 605 | "collapsed": false, 606 | "input": [ 607 | "glyphs.SetScaleModeToScaleByVector()\n", 608 | "glyphs.SetScaleFactor(0.001)\n", 609 | "glyphs.SetColorModeToColorByVector()" 610 | ], 611 | "language": "python", 612 | "metadata": {}, 613 | "outputs": [], 614 | "prompt_number": 79 615 | }, 616 | { 617 | "cell_type": "code", 618 | "collapsed": false, 619 | "input": [ 620 | "glyphs.Update()\n", 621 | "s0,sf = glyphs.GetOutput().GetScalarRange()\n", 622 | "lut = vtk.vtkColorTransferFunction()\n", 623 | "lut.AddRGBPoint(s0, 1,0,0)\n", 624 | "lut.AddRGBPoint(sf, 0,1,0)\n", 625 | "glyph_mapper.SetLookupTable(lut)" 626 | ], 627 | "language": "python", 628 | "metadata": {}, 629 | "outputs": [], 630 | "prompt_number": 80 631 | }, 632 | { 633 | "cell_type": "code", 634 | "collapsed": false, 635 | "input": [ 636 | "renderer.AddActor(glyph_actor)\n", 637 | "render_window.Render()\n", 638 | "interactor.Start()\n", 639 | "renderer.RemoveActor(glyph_actor)\n", 640 | "render_window.Render()" 641 | ], 642 | "language": "python", 643 | "metadata": {}, 644 | "outputs": [], 645 | "prompt_number": 81 646 | }, 647 | { 648 | "cell_type": "markdown", 649 | "metadata": {}, 650 | "source": [ 651 | "![Scaled glyphs](volume_screens/Captura8.PNG)" 652 | ] 653 | }, 654 | { 655 | "cell_type": "markdown", 656 | "metadata": {}, 657 | "source": [ 658 | "The above graph is very crowded, we can simplify it by showing a random sampleof vectors. We can now also make them bigger." 659 | ] 660 | }, 661 | { 662 | "cell_type": "code", 663 | "collapsed": false, 664 | "input": [ 665 | "mask = vtk.vtkMaskPoints()\n", 666 | "mask.SetInputData(b0)\n", 667 | "mask.GenerateVerticesOn()\n", 668 | "mask.SetMaximumNumberOfPoints(10000)\n", 669 | "mask.SetRandomModeType(1)\n", 670 | "mask.RandomModeOn()\n", 671 | "glyphs.SetInputConnection(mask.GetOutputPort())\n", 672 | "glyphs.SetScaleFactor(0.005)" 673 | ], 674 | "language": "python", 675 | "metadata": {}, 676 | "outputs": [], 677 | "prompt_number": 82 678 | }, 679 | { 680 | "cell_type": "code", 681 | "collapsed": false, 682 | "input": [ 683 | "renderer.AddActor(glyph_actor)\n", 684 | "render_window.Render()\n", 685 | "interactor.Start()\n", 686 | "renderer.RemoveActor(glyph_actor)\n", 687 | "render_window.Render()" 688 | ], 689 | "language": "python", 690 | "metadata": {}, 691 | "outputs": [], 692 | "prompt_number": 83 693 | }, 694 | { 695 | "cell_type": "markdown", 696 | "metadata": {}, 697 | "source": [ 698 | "![Random subset of glyphs](volume_screens/Captura9.PNG)" 699 | ] 700 | }, 701 | { 702 | "cell_type": "markdown", 703 | "metadata": {}, 704 | "source": [ 705 | "Here we risk loosing important features in the dataset. Another approach is showing only the vectors above a threshold" 706 | ] 707 | }, 708 | { 709 | "cell_type": "code", 710 | "collapsed": false, 711 | "input": [ 712 | "threshold = vtk.vtkThresholdPoints()\n", 713 | "threshold.SetInputData(b0)\n", 714 | "print b0.GetScalarRange()\n", 715 | "threshold.ThresholdByUpper(0.5)\n", 716 | "glyphs.SetInputConnection(threshold.GetOutputPort())" 717 | ], 718 | "language": "python", 719 | "metadata": {}, 720 | "outputs": [ 721 | { 722 | "output_type": "stream", 723 | "stream": "stdout", 724 | "text": [ 725 | "(0.19781309366226196, 0.710419237613678)\n" 726 | ] 727 | } 728 | ], 729 | "prompt_number": 84 730 | }, 731 | { 732 | "cell_type": "code", 733 | "collapsed": false, 734 | "input": [ 735 | "renderer.AddActor(glyph_actor)\n", 736 | "render_window.Render()\n", 737 | "interactor.Start()\n", 738 | "renderer.RemoveActor(glyph_actor)\n", 739 | "render_window.Render()" 740 | ], 741 | "language": "python", 742 | "metadata": {}, 743 | "outputs": [], 744 | "prompt_number": 85 745 | }, 746 | { 747 | "cell_type": "markdown", 748 | "metadata": {}, 749 | "source": [ 750 | "![Filtered glyohs](volume_screens/Captura10.PNG)" 751 | ] 752 | }, 753 | { 754 | "cell_type": "markdown", 755 | "metadata": {}, 756 | "source": [ 757 | "## Streamlines" 758 | ] 759 | }, 760 | { 761 | "cell_type": "code", 762 | "collapsed": false, 763 | "input": [ 764 | "seeds = vtk.vtkPlaneWidget()\n", 765 | "seeds.SetResolution(8)\n", 766 | "seeds.SetOrigin(2,-2,26)\n", 767 | "seeds.SetPoint1(2, 2,26)\n", 768 | "seeds.SetPoint2(2,-2,32)\n", 769 | "seeds_pd = seeds.GetPolyDataAlgorithm()\n", 770 | "seeds.SetInteractor(interactor)\n", 771 | "seeds.On()\n" 772 | ], 773 | "language": "python", 774 | "metadata": {}, 775 | "outputs": [], 776 | "prompt_number": 86 777 | }, 778 | { 779 | "cell_type": "code", 780 | "collapsed": false, 781 | "input": [ 782 | "streamline = vtk.vtkStreamLine()\n", 783 | "streamline.SetInputData(pl3d.GetOutput().GetBlock(0))\n", 784 | "streamline.SetSourceConnection(seeds_pd.GetOutputPort())\n", 785 | "streamline.SetMaximumPropagationTime(200)\n", 786 | "streamline.SetIntegrationStepLength(.2)\n", 787 | "streamline.SetStepLength(0.001)\n", 788 | "streamline.SetNumberOfThreads(1)\n", 789 | "streamline.SetIntegrationDirectionToForward()\n", 790 | "streamline.VorticityOn()\n", 791 | "\n", 792 | "streamline_mapper = vtk.vtkPolyDataMapper()\n", 793 | "streamline_mapper.SetInputConnection(streamline.GetOutputPort())\n", 794 | "streamline_actor = vtk.vtkActor()\n", 795 | "streamline_actor.SetMapper(streamline_mapper)\n", 796 | "streamline_actor.VisibilityOn()\n" 797 | ], 798 | "language": "python", 799 | "metadata": {}, 800 | "outputs": [], 801 | "prompt_number": 87 802 | }, 803 | { 804 | "cell_type": "code", 805 | "collapsed": false, 806 | "input": [ 807 | "renderer.AddActor(streamline_actor)\n", 808 | "seeds.On()\n", 809 | "render_window.Render()\n", 810 | "interactor.Start()\n", 811 | "renderer.RemoveActor(streamline_actor)\n", 812 | "render_window.Render()\n", 813 | "seeds.Off()" 814 | ], 815 | "language": "python", 816 | "metadata": {}, 817 | "outputs": [], 818 | "prompt_number": 88 819 | }, 820 | { 821 | "cell_type": "markdown", 822 | "metadata": {}, 823 | "source": [ 824 | "![Streamlines](volume_screens/Captura11.PNG)" 825 | ] 826 | }, 827 | { 828 | "cell_type": "markdown", 829 | "metadata": {}, 830 | "source": [ 831 | "## Stream Tubes" 832 | ] 833 | }, 834 | { 835 | "cell_type": "code", 836 | "collapsed": false, 837 | "input": [ 838 | "tubes =vtk.vtkTubeFilter()\n", 839 | "tubes.SetInputConnection(streamline.GetOutputPort())\n", 840 | "tubes.SetRadius(0.1)\n", 841 | "tubes.SetNumberOfSides(8)\n", 842 | "tubes.SetVaryRadiusToVaryRadiusByScalar()\n", 843 | "tubes.SetRadiusFactor(3)\n", 844 | "\n", 845 | "tubes_mapper = vtk.vtkPolyDataMapper()\n", 846 | "tubes_mapper.SetInputConnection(tubes.GetOutputPort())\n", 847 | "tubes_actor = vtk.vtkActor()\n", 848 | "tubes_actor.SetMapper(tubes_mapper)\n" 849 | ], 850 | "language": "python", 851 | "metadata": {}, 852 | "outputs": [], 853 | "prompt_number": 89 854 | }, 855 | { 856 | "cell_type": "code", 857 | "collapsed": false, 858 | "input": [ 859 | "renderer.AddActor(tubes_actor)\n", 860 | "seeds.On()\n", 861 | "render_window.Render()\n", 862 | "interactor.Start()\n", 863 | "renderer.RemoveActor(tubes_actor)\n", 864 | "render_window.Render()\n", 865 | "seeds.Off()" 866 | ], 867 | "language": "python", 868 | "metadata": {}, 869 | "outputs": [], 870 | "prompt_number": 90 871 | }, 872 | { 873 | "cell_type": "markdown", 874 | "metadata": {}, 875 | "source": [ 876 | "![Streamtubes](volume_screens/Captura12.PNG)" 877 | ] 878 | }, 879 | { 880 | "cell_type": "markdown", 881 | "metadata": {}, 882 | "source": [ 883 | "## Next\n", 884 | "\n", 885 | "We have looked at several techniques one at a time. Now you could try mixing them up to show a complete visualization. Also up to now we have ignored the third scalar in the data..." 886 | ] 887 | }, 888 | { 889 | "cell_type": "markdown", 890 | "metadata": {}, 891 | "source": [ 892 | "## Additional sources\n", 893 | "\n", 894 | "- http://www.vtk.org/Wiki/VTK/Examples/Cxx/Visualization/VectorField\n", 895 | "- http://www.bu.edu/tech/support/research/training-consulting/online-tutorials/vtk/\n", 896 | "- http://vis.computer.org/vis2004/dvd/tutorial/tut_5/notes_3.pdf" 897 | ] 898 | }, 899 | { 900 | "cell_type": "code", 901 | "collapsed": false, 902 | "input": [], 903 | "language": "python", 904 | "metadata": {}, 905 | "outputs": [], 906 | "prompt_number": 90 907 | } 908 | ], 909 | "metadata": {} 910 | } 911 | ] 912 | } -------------------------------------------------------------------------------- /vtk-intro.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/vtk-intro.pptx -------------------------------------------------------------------------------- /vtk_example/screen1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/vtk_example/screen1.PNG -------------------------------------------------------------------------------- /vtk_example/screen2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/vtk_example/screen2.PNG -------------------------------------------------------------------------------- /vtk_example/screen3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/vtk_example/screen3.PNG -------------------------------------------------------------------------------- /vtk_example/screen4.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/vtk_example/screen4.PNG -------------------------------------------------------------------------------- /vtk_example/screen5.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/vtk_example/screen5.PNG -------------------------------------------------------------------------------- /vtk_example/screen6.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/vtk_example/screen6.PNG -------------------------------------------------------------------------------- /vtk_example/screen7.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/vtk_example/screen7.PNG -------------------------------------------------------------------------------- /vtk_example/screen8.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/diego0020/tutorial-vtk-python/afa0070ede60404b6b41b0ecd76318888e051a0a/vtk_example/screen8.PNG --------------------------------------------------------------------------------