{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Extract Edges {#extract_edges_example}\n\nExtract edges from a surface.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import pyvista as pv\nfrom pyvista import examples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From vtk documentation, the edges of a mesh are one of the following:\n\n1. boundary (used by one polygon) or a line cell\n2. non-manifold (used by three or more polygons)\n3. feature edges (edges used by two triangles and whose dihedral angle\n \\> feature_angle)\n4. manifold edges (edges used by exactly two polygons).\n\nThe\n`extract_feature_edges() <pyvista.DataSetFilters.extract_feature_edges>`{.interpreted-text\nrole=\"func\"} filter will extract those edges given a feature angle and\nreturn a dataset with lines that represent the edges of the original\nmesh.\n\nTo demonstrate, we will first extract the edges around a sample CAD\nmodel:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Download the example CAD model and extract all feature edges above 45 degrees\nmesh = examples.download_cad_model()\nedges = mesh.extract_feature_edges(45)\n\n# Render the edge lines on top of the original mesh. Zoom in to provide a better figure.\np = pv.Plotter()\np.add_mesh(mesh, color=True)\np.add_mesh(edges, color=\"red\", line_width=5)\np.camera.zoom(1.5)\np.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can do this analysis for any `pyvista.PolyData`{.interpreted-text\nrole=\"class\"} object. Let\\'s try the cow mesh example:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mesh = examples.download_cow()\nedges = mesh.extract_feature_edges(20)\n\np = pv.Plotter()\np.add_mesh(mesh, color=True)\np.add_mesh(edges, color=\"red\", line_width=5)\np.camera_position = [(9.5, 3.0, 5.5), (2.5, 1, 0), (0, 1, 0)]\np.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can leverage the `pyvista.PolyData.n_open_edges`{.interpreted-text\nrole=\"any\"} property and\n`pyvista.DataSetFilters.extract_feature_edges`{.interpreted-text\nrole=\"func\"} filter to count and extract the open edges on a\n`pyvista.PolyData`{.interpreted-text role=\"class\"} mesh.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Download a sample surface mesh with visible open edges\nmesh = examples.download_bunny()\nmesh" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can get a count of the open edges with:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mesh.n_open_edges" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And we can extract those edges with the `boundary_edges` option of\n`pyvista.DataSetFilters.extract_feature_edges`{.interpreted-text\nrole=\"func\"}:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "edges = mesh.extract_feature_edges(boundary_edges=True, feature_edges=False, manifold_edges=False)\n\np = pv.Plotter()\np.add_mesh(mesh, color=True)\np.add_mesh(edges, color=\"red\", line_width=5)\np.camera_position = [(-0.2, -0.13, 0.12), (-0.015, 0.10, -0.0), (0.28, 0.26, 0.9)]\np.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 }