Skip to content

Commit

Permalink
add smooth_data() to smooth/diffuse data attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
marcomusy committed Dec 14, 2023
1 parent 63c40a5 commit f92ab80
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 1 deletion.
2 changes: 2 additions & 0 deletions docs/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- add `transformations.__call__()` to apply it
- fix small bug in `pointcloud.distance_to()`
- add `applications.MorphPlotter()` to morph a polygonal mesh to a target mesh
- add `smooth_data()` to smooth/diffuse data attributes


## Breaking changes
Expand All @@ -40,6 +41,7 @@
## New/Revised Examples
```
examples/advanced/warp4c.py
examples/advanced/diffuse_data.py
examples/volumetric/slab_vol.py
examples/other/madcad1.py
examples/other/tetgen1.py
Expand Down
8 changes: 8 additions & 0 deletions docs/examples_db.js
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,14 @@ vedo_example_db =
long : 'Interpolate cell values from a quad-mesh to a tri-mesh of different resolution',
imgsrc: 'images/advanced/interpolateScalar4.png',
},
{
pyname: 'diffuse_data',
kbd : '',
categ : 'advanced',
short : 'smooth array',
long : 'Smooth/diffuse an array of scalars on a mesh',
imgsrc: 'images/advanced/diffuse_data.png',
},
{
pyname: 'cut_with_mesh1',
kbd : '',
Expand Down
36 changes: 36 additions & 0 deletions examples/advanced/diffuse_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import numpy as np
from vedo import Grid, settings, show
from vedo.pyplot import histogram

settings.default_font = "FiraMonoMedium"

grid = Grid(res=[50,50])
grid.wireframe(False).lw(0)

values = np.zeros(grid.npoints)
values[int(grid.npoints/2)] = 1
values[int(grid.npoints/5)] = 1

grid.pointdata["scalars"] = values
grid.cmap("Set1_r").add_scalarbar()

grid2 = grid.clone()
grid2.smooth_data(niter=750, relaxation_factor=0.1, strategy=1)
grid2.cmap("Set1_r").add_scalarbar()

his = histogram(
grid2.pointdata["scalars"],
c='k4',
xtitle="Concentration",
ytitle="Frequency",
axes=dict(htitle="", axes_linewidth=2, xyframe_line=0),
)
his = his.clone2d() # fix it to screen coords

print("integrated over domain:", grid2.integrate_arrays_over_domain())

show([
["Initial state", grid],
["After diffusion", grid2, his]],
N=2, axes=1,
).close()
57 changes: 57 additions & 0 deletions vedo/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1384,6 +1384,63 @@ def shrink(self, fraction=0.8):
)
return self

def smooth_data(self,
niter=10, relaxation_factor=0.1, strategy=0, mask=None,
exclude=("Normals", "TextureCoordinates"),
):
"""
Smooth point attribute data using distance weighted Laplacian kernel.
The effect is to blur regions of high variation and emphasize low variation regions.
Arguments:
niter : (int)
number of iterations
relaxation_factor : (float)
relaxation factor controlling the amount of Laplacian smoothing applied
strategy : (int)
strategy to use for Laplacian smoothing
- 0: use all points, all point data attributes are smoothed
- 1: smooth all point attribute data except those on the boundary
- 2: only point data connected to a boundary point are smoothed
mask : (str, np.ndarray)
array to be used as a mask (ignore then the strategy keyword)
exclude : (list)
list of arrays to be excluded from smoothing
"""
saf = vtk.new("AttributeSmoothingFilter")
saf.SetInputData(self.dataset)
saf.SetRelaxationFactor(relaxation_factor)
saf.SetNumberOfIterations(niter)

for ex in exclude:
saf.AddExcludedArray(ex)

saf.SetWeightsTypeToDistance2()

saf.SetSmoothingStrategy(strategy)
if mask is not None:
saf.SetSmoothingStrategyToSmoothingMask()
if isinstance(mask, str):
mask_ = self.dataset.GetPointData().GetArray(mask)
if not mask_:
vedo.logger.error(f"smooth_data(): mask array {mask} not found")
return self
mask_array = vtk.vtkUnsignedCharArray()
mask_array.ShallowCopy(mask_)
mask_array.SetName(mask_.GetName())
else:
mask_array = utils.numpy2vtk(mask, dtype=np.uint8)
saf.SetSmoothingMask(mask_array)

saf.Update()

self._update(saf.GetOutput())
self.pipeline = utils.OperationNode(
"smooth_data", comment=f"strategy {strategy}", parents=[self], c="#9e2a2b"
)
return self


###############################################################################
class PointAlgorithms(CommonAlgorithms):
Expand Down
3 changes: 2 additions & 1 deletion vedo/vtkclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,9 @@
location["vtkCellTreeLocator"] = "vtkFiltersGeneral"


location["vtkGeometryFilter"] = "vtkFiltersGeometry"
location["vtkAttributeSmoothingFilter"] = "vtkFiltersGeometry"
location["vtkDataSetSurfaceFilter"] = "vtkFiltersGeometry"
location["vtkGeometryFilter"] = "vtkFiltersGeometry"
location["vtkImageDataGeometryFilter"] = "vtkFiltersGeometry"


Expand Down

0 comments on commit f92ab80

Please sign in to comment.