mesh.Mesh.smooth#
- Mesh.smooth(iterations=1, lamb=0.5, *, mu=None, border='sep', level=1, exclude=[], weight='uniform', data=None, **kargs)#
Smooth the geometry of a Mesh or data defined over a Mesh.
Uses Taubin lambda/mu method to smooth the node positions or any other float data defined on the nodes of the Mesh. This is a two-step iteration method. In the first (smoothing) step, the new nodal values are set to a weighted interpolation of the old values and the weighted mean values at the neighboring nodes. The relaxation factor lambda determines how far the value moves toward the local centroid. As this smoothing causes shrinkage of the model, it is followed by a compensating scaling (expansion) step, governed by the value mu. The more iterations the smoother the result will be, possibly at the cost of increased shrinkage. Options are available to tune the weights, exclude nodes from smoothing, or separately smooth border and inner nodes.
Parameters#
- iterations: int
The number of smoothing iterations to be performed.
- lamb: float
Relaxation factor (0 <= lamb <= 1) for the smoothing step. A value 0 keeps the old values, while a value 1 replaces them with the (weighted) mean values at the neighbors.
- mu: float
Relaxation factor for the expansion step (mu < -lambda). The value should be negative to undo the shrinkage of the first step. If not provided, the default value used is
-lamb / (1.0 - 0.1*lamb). The higher the absolute value of mu, the more the shrinkage is reduced, and the model may even start to expand. If a value of 0.0 is specified, no second step is done.- border: ‘sep’ | ‘fix’ | ‘incl’
Specifies how border nodes are handled. With ‘sep’ (default), border nodes are smoothed independently from internal nodes. Internal nodes still remain dependent on border nodes though. With ‘fix’, border nodes remain in place and do not take part in the smoothing. With ‘incl’, border nodes are included in the smoothing process just like other nodes. For a borderless mesh (like a closed surface), ‘sep’ and ‘incl’ are obviously the same.
- level: int
The level of connections between the nodes that will define the neighbors in the smoothing process. If an int, nodes are only considered neighbors if the belong to the same lower level entities: 1 for edges, 2 for faces, 3 for 3D-cells. The default uses neigbors by edge. A value 0 will use the highest (element) level. For simplex meshes (line2, tri3, tet4) the value makes no difference, as all nodes in an element are connected by an edge. Using a value different from 1 tends to produce more shrinkage. Therefore the default is set to 1 even for non-simplex meshes.
- exclude: list of int
A list of nodes that should retain their position throughout the smoothing process. When using
border='fix', the border nodes are automatically added to this list.- weight: ‘uniform’ | ‘inverse’ | ‘distance’
Specifies how the relative weight of the neighboring points is calculated. With ‘uniform’ all neighbor points have the same weight. With ‘distance’, neighbor points have a weight proportional to their distance to the point to be moved. With ‘inverse’, the weight is proportional to the inverse of the distances. Prepending ‘sq’ to ‘inverse’ or ‘distance’ will make the weights proportional to the square (inverse) distances (e.g. ‘sqdistance’).
- data: array_like
An array of floating point data defined at the nodes. The first dimension of the array should be equal to the number of nodes. If data is provided, returns the smoothed data instead of a Mesh with smoothed geometry.
Returns#
- Mesh | array
If no data was provided, returns a smoothed Mesh with otherwise same characteristics. If data was provided, returns an array of the same shape containing the smoothed data.
Notes#
For the smoothing algorithm, see Taubin, Curve and Surface Smoothing without Shrinkage, ICCV 1995.
The default
border='sep'works well in most cases. For models with a border, shrinkage is prominent near the border and the setting helps in reducing it. For models without a border, there is no difference between ‘sep’ and ‘incl’.The weights are currently only computed once before starting the smoothing iterations. As a result, there is a difference between using a single smooth with a number of iterations and using the same number of successive smooths with a single iteration. This behavior may be changed in future.
Examples#
>>> M = Mesh(eltype="quad4").subdivide(2) >>> print(M.smooth()) Mesh: n_nodes: 9, n_elems: 4, plexitude: 4, level: 2, eltype: quad4 BBox: [-0.0658 -0.0658 0. ], [1.0658 1.0658 0. ] Size: [1.1316 1.1316 0. ] Length: 3.665 Area: 0.9976