{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Lesson Overview\n\nThis exercise provides an overview of the example in the initial lesson\nfor you to try out!\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import numpy as np\nimport pyvista as pv\nfrom pyvista import examples"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# What is a Point?\n\nLet\\'s start with a point cloud - this is a mesh type that only has\nvertices. You can create one by defining a 2D array of Cartesian\ncoordinates like so:\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "points = np.random.rand(100, 3)\npoints[:5, :]  # output first 5 rows"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Pass numpy array of points (n by 3) to PolyData\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mesh = pv.PolyData(points)\nmesh"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mesh.plot(point_size=10, style=\"points\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "But it\\'s important to note that most meshes have some sort of\nconnectivity between points such as this gridded mesh:\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mesh = examples.load_hexbeam()\ncpos = [(6.20, 3.00, 7.50), (0.16, 0.13, 2.65), (-0.28, 0.94, -0.21)]\n\npl = pv.Plotter()\npl.add_mesh(mesh, show_edges=True, color=\"white\")\npl.add_points(mesh.points, color=\"red\", point_size=20, render_points_as_spheres=True)\npl.camera_position = cpos\npl.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mesh = examples.download_bunny_coarse()\n\npl = pv.Plotter()\npl.add_mesh(mesh, show_edges=True, color=\"white\")\npl.add_points(mesh.points, color=\"red\", point_size=10)\npl.camera_position = [(0.02, 0.30, 0.73), (0.02, 0.03, -0.022), (-0.03, 0.94, -0.34)]\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# What is a Cell?\n\nA cell is the geometry between points that defines the connectivity or\ntopology of a mesh. In the examples above, cells are defined by the\nlines (edges colored in black) connecting points (colored in red). For\nexample, a cell in the beam example is a voxel defined by the region\nbetween eight points in that mesh. Here we can extract one of the cells\nfrom the mesh, show some information about it, and plot its location\namong the mesh.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mesh = examples.load_hexbeam()\n\nsingle_cell = mesh.get_cell(mesh.n_cells - 1)\nsingle_cell"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "pl = pv.Plotter()\npl.add_mesh(mesh, show_edges=True, color=\"white\")\npl.add_points(mesh.points, color=\"red\", point_size=20)\npl.add_mesh(\n    single_cell.cast_to_unstructured_grid(),\n    color=\"pink\",\n    edge_color=\"blue\",\n    line_width=5,\n    show_edges=True,\n)\npl.camera_position = [(6.20, 3.00, 7.50), (0.16, 0.13, 2.65), (-0.28, 0.94, -0.21)]\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Cells aren\\'t limited to voxels, they could be a triangle between three\npoints, a line between two points, or even a single point could be its\nown cell (but that\\'s a special case).\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# What are attributes?\n\nAttributes are data values that live on either the points or cells of a\nmesh. In PyVista, we work with both point data and cell data and allow\neasy access to data dictionaries to hold arrays for attributes that live\neither on all points or on all cells of a mesh. These attributes can be\naccessed in a dictionary-like attribute attached to any PyVista mesh\naccessible as one of the following:\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Point Data\n\nPoint data refers to arrays of values (scalars, vectors, etc.) that live\non each point of the mesh. Each element in an attribute array\ncorresponds to a point in the mesh. Let\\'s create some point data for\nthe beam mesh. When plotting, the values between points are interpolated\nacross the cells.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mesh.point_data[\"my point values\"] = np.arange(mesh.n_points)\nmesh.plot(scalars=\"my point values\", cpos=cpos, show_edges=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Cell Data\n\nCell data refers to arrays of values (scalars, vectors, etc.) that live\nthroughout each cell of the mesh. That is the entire cell (2D face or 3D\nvolume) is assigned the value of that attribute.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mesh.cell_data[\"my cell values\"] = np.arange(mesh.n_cells)\nmesh.plot(scalars=\"my cell values\", cpos=cpos, show_edges=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Here\\'s a comparison of point data versus cell data and how point data\nis interpolated across cells when mapping colors. This is unlike cell\ndata which has a single value across the cell\\'s domain:\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import pyvista as pv\nfrom pyvista import examples\n\nuni = examples.load_uniform()\n\npl = pv.Plotter(shape=(1, 2), border=False)\npl.add_mesh(uni, scalars=\"Spatial Point Data\", show_edges=True)\npl.subplot(0, 1)\npl.add_mesh(uni, scalars=\"Spatial Cell Data\", show_edges=True)\npl.link_views()\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Field Data\n\nField data is not directly associated with either the points or cells\nbut still should be attached to the mesh. This may be a string array\nstoring notes.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mesh = pv.Cube()\nmesh.field_data[\"metadata\"] = [\"Foo\", \"bar\"]\nmesh.field_data"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Assigning Scalars to a Mesh\n\nHere\\'s how we assign values to cell attributes and plot it. Here, we\ngenerate cube containing 6 faces and assign each face an integer from\n`range(6)` and then have it plotted.\n\nNote how this varies from assigning scalars to each point\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "cube = pv.Cube()\ncube.cell_data[\"myscalars\"] = range(6)\n\nother_cube = cube.copy()\nother_cube.point_data[\"myscalars\"] = range(8)\n\npl = pv.Plotter(shape=(1, 2), border_width=1)\npl.add_mesh(cube, cmap=\"coolwarm\")\npl.subplot(0, 1)\npl.add_mesh(other_cube, cmap=\"coolwarm\")\npl.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "```{=html}\n<center>\n  <a target=\"_blank\" href=\"https://colab.research.google.com/github/pyvista/pyvista-tutorial/blob/gh-pages/notebooks/tutorial/02_mesh/a_lesson_mesh.ipynb\">\n    <img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/ width=\"150px\">\n  </a>\n</center>\n```\n"
      ]
    }
  ],
  "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.11"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}