{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Clipping with a Surface {#clip_with_surface_example}\n\nClip any PyVista dataset by a `pyvista.PolyData`{.interpreted-text\nrole=\"class\"} surface mesh using the\n`pyvista.DataSetFilters.clip_surface`{.interpreted-text role=\"func\"}\nfilter.\n\nNote that we first demonstrate how the clipping is performed by\ncomputing an implicit distance and thresholding the mesh. This\nthresholding is one approach to clip by a surface, and preserve the\noriginal geometry of the given mesh, but many folks leverage the\n`clip_surface` filter to triangulate/tessellate the mesh geometries\nalong the clip.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\n\nimport pyvista as pv\nfrom pyvista import examples"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "surface = pv.Cone(direction=(0, 0, -1), height=3.0, radius=1, resolution=50, capping=False)\n\n# Make a gridded dataset\nn = 51\nxx = yy = zz = 1 - np.linspace(0, n, n) * 2 / (n - 1)\ndataset = pv.RectilinearGrid(xx, yy, zz)\n\n# Preview the problem\np = pv.Plotter()\np.add_mesh(surface, color='w', label='Surface')\np.add_mesh(dataset, color='gold', show_edges=True, opacity=0.75, label='To Clip')\np.add_legend()\np.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Take a look at the implicit function used to perform the surface\nclipping by using the\n`pyvista.DataSetFilters.compute_implicit_distance`{.interpreted-text\nrole=\"func\"} filter. The clipping operation field is performed where the\n`implicit_distance` field is zero and the `invert` flag controls which\nsides of zero to preserve.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "dataset.compute_implicit_distance(surface, inplace=True)\n\ninner = dataset.threshold(0.0, scalars=\"implicit_distance\", invert=True)\nouter = dataset.threshold(0.0, scalars=\"implicit_distance\", invert=False)\n\np = pv.Plotter()\np.add_mesh(surface, color='w', label='Surface', opacity=0.75)\np.add_mesh(\n    inner,\n    scalars=\"implicit_distance\",\n    show_edges=True,\n    opacity=0.75,\n    label='Inner region',\n    clim=[-1, 1],\n    cmap=\"bwr\",\n)\np.add_legend()\np.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "p = pv.Plotter()\np.add_mesh(surface, color='w', label='Surface', opacity=0.75)\np.add_mesh(\n    outer,\n    scalars=\"implicit_distance\",\n    show_edges=True,\n    opacity=0.75,\n    label='Outer region',\n    clim=[-1, 1],\n    cmap=\"bwr\",\n)\np.add_legend()\np.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Clip the rectilinear grid dataset using the\n`pyvista.PolyData`{.interpreted-text role=\"class\"} surface mesh via the\n`pyvista.DataSetFilters.clip_surface`{.interpreted-text role=\"func\"}\nfilter. This will triangulate/tessellate the mesh geometries along the\nclip.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "clipped = dataset.clip_surface(surface, invert=False)\n\n# Visualize the results\np = pv.Plotter()\np.add_mesh(surface, color='w', opacity=0.75, label='Surface')\np.add_mesh(clipped, color='gold', show_edges=True, label=\"clipped\", opacity=0.75)\np.add_legend()\np.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Here is another example of clipping a mesh by a surface. This time,\nwe\\'ll generate a `pyvista.ImageData`{.interpreted-text role=\"class\"}\naround a topography surface and then clip that grid using the surface to\ncreate a closed 3D model of the surface\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "surface = examples.load_random_hills()\n\n# Create a grid around that surface\ngrid = pv.create_grid(surface)\n\n# Clip the grid using the surface\nmodel = grid.clip_surface(surface)\n\n# Compute height and display it\nmodel.elevation().plot()"
      ]
    }
  ],
  "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
}