{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Linear Cells {#linear_cells_example}\n\nThis example extends the `create_unstructured_example`{.interpreted-text\nrole=\"ref\"} example by including an explanation of linear VTK cell types\nand how you can create them in PyVista.\n\nLinear cells are cells where points only occur at the edges of each\ncell. Non-linear cells contain additional points along the edges of the\ncell.\n\nFor more details regarding what a\n`pyvista.UnstructuredGrid`{.interpreted-text role=\"class\"} is, please\nsee `point_sets_api`{.interpreted-text role=\"ref\"}.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n\nimport pyvista as pv\nfrom pyvista.examples import cells as example_cells, plot_cell\n\n# random generator for examples\nrng = np.random.default_rng(2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Plot an example cell\n\nPyVista contains a simple utility to plot a single cell, which is the\nfundamental unit of each `pyvista.UnstructuredGrid`{.interpreted-text\nrole=\"class\"}. For example, let\\'s plot a simple\n`Wedge <pyvista.examples.cells.Wedge>`{.interpreted-text role=\"func\"}.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "grid = example_cells.Wedge()\nexample_cells.plot_cell(grid)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This linear cell is composed of 6 points.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "grid.points" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The UnstructuredGrid is also composed of a single cell and the point\nindices of that cell are defined in\n`cells <pyvista.UnstructuredGrid.cells>`{.interpreted-text role=\"attr\"}.\n\n::: note\n::: title\nNote\n:::\n\nThe leading `6` is the number of points in the cell.\n:::\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "grid.cells" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Combine two UnstructuredGrids\n\nWe can combine two unstructured grids to create a single unstructured\ngrid using the `+` operator.\n\n::: note\n::: title\nNote\n:::\n\nThis is an inefficient way of creating\n`pyvista.UnstructuredGrid`{.interpreted-text role=\"class\"} objects. To\nsee a more efficient implementation see\n`create_unstructured_example`{.interpreted-text role=\"ref\"}.\n:::\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "grid_a = example_cells.Hexahedron()\ngrid_a.points += [0, 2.5, 0]\n\ngrid_b = example_cells.HexagonalPrism()\n\ncombined = grid_b + grid_a\n\nplot_cell(combined, cpos='iso')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This example helps to illustrate meaning behind the `cells\n<pyvista.UnstructuredGrid.cells>`{.interpreted-text role=\"attr\"}\nattribute. The first cell, a hexahedron contains 8 points and the\nhexagonal prism contains 12 points. The `cells` attribute shows this\nalong with indices composing each cell.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "combined.cells" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Cell Types\n\nPyVista contains the `pyvista.CellType`{.interpreted-text role=\"class\"}\nenumerator, which contains all the available VTK cell types mapped to a\nPython enumerator. These cell types are used when creating cells and\nalso can be used when checking the\n`celltypes <pyvista.UnstructuredGrid.celltypes>`{.interpreted-text\nrole=\"attr\"} attribute. For example `combined.celltypes` contains both\nthe `pv.CellType.HEXAHEDRON` and `pv.CellType.HEXAGONAL_PRISM` cell\ntypes.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print(pv.CellType.HEXAHEDRON, pv.CellType.HEXAGONAL_PRISM)\ncombined.celltypes == (pv.CellType.HEXAHEDRON, pv.CellType.HEXAGONAL_PRISM)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Create an UnstructuredGrid with a single linear cell\n\nNow that you know the three main inputs of an\n`pyvista.UnstructuredGrid`{.interpreted-text role=\"class\"}, it\\'s quite\nstraightforward to create an unstructured grid with a one or more cells.\nIf you need to reference point ordering or additional, you can either\nread the source of\n[cells.py](https://github.com/pyvista/pyvista/blob/main/pyvista/examples/cells.py)\nor simply create a cell from the `pyvista.core.cells` module and inspect\nits attributes.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "points = [\n [1.0, 1.0, 0.0],\n [-1.0, 1.0, 0.0],\n [-1.0, -1.0, 0.0],\n [1.0, -1.0, 0.0],\n [0.0, 0.0, 1.60803807],\n]\ncells = [len(points), *list(range(len(points)))]\npyrmaid = pv.UnstructuredGrid(cells, [pv.CellType.PYRAMID], points)\nexample_cells.plot_cell(pyrmaid)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Plot all linear cell Types\n\nLet\\'s create a `(4, 4)` `pyvista.Plotter`{.interpreted-text\nrole=\"class\"} and plot all 16 linear cells in a single plot.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def add_cell_helper(pl, text, grid, subplot, cpos=None):\n \"\"\"Add a single cell to a plotter with fancy plotting.\"\"\"\n pl.subplot(*subplot)\n pl.add_text(text, 'lower_edge', color='k', font_size=8)\n pl.add_mesh(grid, opacity=0.5, color='lightblue', line_width=5)\n edges = grid.extract_all_edges()\n if edges.n_cells:\n pl.add_mesh(grid.extract_all_edges(), line_width=5, color='k')\n pl.add_points(grid, render_points_as_spheres=True, point_size=20, color='r')\n pl.add_point_labels(\n grid.points,\n range(grid.n_points),\n always_visible=True,\n fill_shape=False,\n margin=0,\n shape_opacity=0.0,\n font_size=20,\n text_color='k',\n )\n if cpos is None:\n pl.camera.azimuth = 20\n pl.camera.elevation = -20\n else:\n pl.camera_position = cpos\n pl.camera.zoom(0.8)\n\n\npl = pv.Plotter(shape=(4, 4))\nadd_cell_helper(pl, f'VERTEX ({pv.CellType.VERTEX})', example_cells.Vertex(), (0, 0))\nadd_cell_helper(pl, f'POLY_VERTEX ({pv.CellType.POLY_VERTEX})', example_cells.PolyVertex(), (0, 1))\nadd_cell_helper(pl, f'LINE ({pv.CellType.LINE})', example_cells.Line(), (0, 2))\nadd_cell_helper(pl, f'POLY_LINE ({pv.CellType.POLY_LINE})', example_cells.PolyLine(), (0, 3))\n\nadd_cell_helper(\n pl,\n f'TRIANGLE ({pv.CellType.TRIANGLE})',\n example_cells.Triangle(),\n (1, 0),\n cpos='xy',\n)\nadd_cell_helper(\n pl,\n f'TRIANGLE_STRIP ({pv.CellType.TRIANGLE_STRIP})',\n example_cells.TriangleStrip().rotate_z(90, inplace=False),\n (1, 1),\n cpos='xy',\n)\nadd_cell_helper(pl, f'POLYGON ({pv.CellType.POLYGON})', example_cells.Polygon(), (1, 2), cpos='xy')\nadd_cell_helper(pl, f'PIXEL ({pv.CellType.PIXEL})', example_cells.Pixel(), (1, 3), cpos='xy')\n\n# make irregular\nquad_grid = example_cells.Quadrilateral()\nquad_grid.points += rng.random((4, 3)) * 0.5\n\nadd_cell_helper(pl, f'QUAD ({pv.CellType.QUAD})', quad_grid, (2, 0))\nadd_cell_helper(pl, f'TETRA ({pv.CellType.TETRA})', example_cells.Tetrahedron(), (2, 1))\nadd_cell_helper(pl, f'VOXEL ({pv.CellType.VOXEL})', example_cells.Voxel(), (2, 2))\n\n# make irregular\nhex_grid = example_cells.Hexahedron()\nhex_grid.points += rng.random((8, 3)) * 0.4\nadd_cell_helper(pl, f'HEXAHEDRON ({pv.CellType.HEXAHEDRON})', hex_grid, (2, 3))\n\nadd_cell_helper(pl, f'WEDGE ({pv.CellType.WEDGE})', example_cells.Wedge(), (3, 0))\nadd_cell_helper(pl, f'PYRAMID ({pv.CellType.PYRAMID})', example_cells.Pyramid(), (3, 1))\nadd_cell_helper(\n pl,\n f'PENTAGONAL_PRISM ({pv.CellType.PENTAGONAL_PRISM})',\n example_cells.PentagonalPrism(),\n (3, 2),\n)\nadd_cell_helper(\n pl,\n f'HEXAGONAL_PRISM ({pv.CellType.HEXAGONAL_PRISM})',\n example_cells.HexagonalPrism(),\n (3, 3),\n)\n\npl.background_color = 'w'\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 }