{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Surface Smoothing {#surface_smoothing_example}\n\nSmoothing rough edges of a surface mesh\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": [ "Suppose you extract a volumetric subset of a dataset that has roughly\ndefined edges. Perhaps you\\'d like a smooth representation of that model\nregion. This can be achieved by extracting the bounding surface of the\nvolume and applying a `pyvista.PolyDataFilters.smooth`{.interpreted-text\nrole=\"func\"} filter.\n\nThe below code snippet loads a sample roughly edged volumetric dataset:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Vector to view rough edges\ncpos = [-2, 5, 3]\n\n# Load dataset\ndata = examples.load_uniform()\n# Extract a rugged volume\nvol = data.threshold_percent(30, invert=1)\nvol.plot(show_edges=True, cpos=cpos, show_scalar_bar=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Extract the outer surface of the volume using the\n`pyvista.DataSetFilters.extract_geometry`{.interpreted-text role=\"func\"}\nfilter and then apply the smoothing filter:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Get the out surface as PolyData\nsurf = vol.extract_geometry()\n# Smooth the surface\nsmooth = surf.smooth()\nsmooth.plot(show_edges=True, cpos=cpos, show_scalar_bar=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Not smooth enough? Try increasing the number of iterations for the\nLaplacian smoothing algorithm:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Smooth the surface even more\nsmooth = surf.smooth(n_iter=100)\nsmooth.plot(show_edges=True, cpos=cpos, show_scalar_bar=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Still not smooth enough? Increase the number of iterations for the\nLaplacian smoothing algorithm to a crazy high value. Note how this\ncauses the mesh to \\\"shrink\\\":\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Smooth the surface EVEN MORE\nsmooth = surf.smooth(n_iter=1000)\n\n# extract the edges of the original unsmoothed mesh\norig_edges = surf.extract_feature_edges()\n\npl = pv.Plotter()\npl.add_mesh(smooth, show_edges=True, show_scalar_bar=False)\npl.camera_position = cpos\npl.add_mesh(orig_edges, show_scalar_bar=False, color='k', line_width=2)\npl.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Taubin Smoothing\n\nYou can reduce the amount of surface shrinkage by using Taubin smoothing\nrather than the default laplacian smoothing implemented in `smooth()\n<pyvista.PolyDataFilters.smooth>`{.interpreted-text role=\"func\"}. In\nthis example, you can see how Taubin smoothing maintains the volume\nrelative to the original mesh.\n\nAlso, note that the number of iterations can be reduced to get the same\napproximate amount of smoothing. This is because Taubin smoothing is\nmore efficient.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "smooth_w_taubin = surf.smooth_taubin(n_iter=50, pass_band=0.05)\n\npl = pv.Plotter()\npl.add_mesh(smooth_w_taubin, show_edges=True, show_scalar_bar=False)\npl.camera_position = cpos\npl.add_mesh(orig_edges, show_scalar_bar=False, color='k', line_width=2)\npl.show()\n\n# output the volumes of the original and smoothed meshes\nprint(f'Original surface volume: {surf.volume:.1f}')\nprint(f'Laplacian smoothed volume: {smooth.volume:.1f}')\nprint(f'Taubin smoothed volume: {smooth_w_taubin.volume:.1f}')" ] } ], "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 }