{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Volume Rendering {#volume_rendering_example}\n\nVolume render uniform mesh types like\n`pyvista.ImageData`{.interpreted-text role=\"class\"} or 3D NumPy arrays.\n\nThis also explores how to extract a volume of interest (VOI) from a\n`pyvista.ImageData`{.interpreted-text role=\"class\"} using the\n`pyvista.ImageDataFilters.extract_subset`{.interpreted-text role=\"func\"}\nfilter.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import pyvista as pv\nfrom pyvista import examples\n\n\n# Download a volumetric dataset\nvol = examples.download_knee_full()\nvol"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Simple Volume Render\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# A nice camera position\ncpos = [(-381.74, -46.02, 216.54), (74.8305, 89.2905, 100.0), (0.23, 0.072, 0.97)]\n\nvol.plot(volume=True, cmap=\"bone\", cpos=cpos)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Opacity Mappings\n\nOr use the `pyvista.Plotter.add_volume`{.interpreted-text role=\"func\"}\nmethod like below. Note that here we use a non-default opacity mapping\nto a sigmoid:\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "pl = pv.Plotter()\npl.add_volume(vol, cmap=\"bone\", opacity=\"sigmoid\")\npl.camera_position = cpos\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "You can also use a custom opacity mapping\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "opacity = [0, 0, 0, 0.1, 0.3, 0.6, 1]\n\npl = pv.Plotter()\npl.add_volume(vol, cmap=\"viridis\", opacity=opacity)\npl.camera_position = cpos\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We can also use a shading technique when volume rendering with the\n`shade` option\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "pl = pv.Plotter(shape=(1, 2))\npl.add_volume(vol, cmap=\"viridis\", opacity=opacity, shade=False)\npl.add_text(\"No shading\")\npl.camera_position = cpos\npl.subplot(0, 1)\npl.add_volume(vol, cmap=\"viridis\", opacity=opacity, shade=True)\npl.add_text(\"Shading\")\npl.link_views()\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Cool Volume Examples\n\nHere are a few more cool volume rendering examples.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Head Dataset\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "head = examples.download_head()\n\npl = pv.Plotter()\npl.add_volume(head, cmap=\"cool\", opacity=\"sigmoid_6\", show_scalar_bar=False)\npl.camera_position = [(-228.0, -418.0, -158.0), (94.0, 122.0, 82.0), (-0.2, -0.3, 0.9)]\npl.camera.zoom(1.5)\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Bolt-Nut MultiBlock Dataset\n\n::: note\n::: title\nNote\n:::\n\nSee how we set interpolation to `'linear'` here to smooth out scalars of\neach individual cell to make a more appealing plot. Two actor are\nreturned by `add_volume` because `bolt_nut` is a\n`pyvista.MultiBlock`{.interpreted-text role=\"class\"} dataset.\n:::\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "bolt_nut = examples.download_bolt_nut()\n\npl = pv.Plotter()\nactors = pl.add_volume(bolt_nut, cmap=\"coolwarm\", opacity=\"sigmoid_5\", show_scalar_bar=False)\nactors[0].prop.interpolation_type = 'linear'\nactors[1].prop.interpolation_type = 'linear'\npl.camera_position = [(127.4, -68.3, 88.2), (30.3, 54.3, 26.0), (-0.25, 0.28, 0.93)]\ncpos = pl.show(return_cpos=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Frog Dataset\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "frog = examples.download_frog()\n\npl = pv.Plotter()\npl.add_volume(frog, cmap=\"viridis\", opacity=\"sigmoid_6\", show_scalar_bar=False)\npl.camera_position = [(929.0, 1067.0, -278.9), (249.5, 234.5, 101.25), (-0.2048, -0.2632, -0.9427)]\npl.camera.zoom(1.5)\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Extracting a VOI\n\nUse the `pyvista.ImageDataFilters.extract_subset`{.interpreted-text\nrole=\"func\"} filter to extract a volume of interest/subset volume to\nvolume render. This is ideal when dealing with particularly large\nvolumes and you want to volume render only a specific region.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Load a particularly large volume\nlarge_vol = examples.download_damavand_volcano()\nlarge_vol"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "opacity = [0, 0.75, 0, 0.75, 1.0]\nclim = [0, 100]\n\npl = pv.Plotter()\npl.add_volume(\n    large_vol,\n    cmap=\"magma\",\n    clim=clim,\n    opacity=opacity,\n    opacity_unit_distance=6000,\n)\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Woah, that\\'s a big volume. We probably don\\'t want to volume render the\nwhole thing. So let\\'s extract a region of interest under the volcano.\n\nThe region we will extract will be between nodes 175 and 200 on the\nx-axis, between nodes 105 and 132 on the y-axis, and between nodes 98\nand 170 on the z-axis.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "voi = large_vol.extract_subset([175, 200, 105, 132, 98, 170])\n\npl = pv.Plotter()\npl.add_mesh(large_vol.outline(), color=\"k\")\npl.add_mesh(voi, cmap=\"magma\")\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Ah, much better. Let\\'s now volume render that region of interest.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "pl = pv.Plotter()\npl.add_volume(voi, cmap=\"magma\", clim=clim, opacity=opacity, opacity_unit_distance=2000)\npl.camera_position = [\n    (531554.5542909054, 3944331.800171338, 26563.04809259223),\n    (599088.1433822059, 3982089.287834022, -11965.14728669936),\n    (0.3738545892415734, 0.244312810377319, 0.8947312427698892),\n]\npl.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.12.2"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}