pyvista / pyvista

3D plotting and mesh analysis through a streamlined interface for the Visualization Toolkit (VTK)
https://docs.pyvista.org
MIT License
2.64k stars 485 forks source link

Mesh clip box doesn't work with smooth shading enabled. #2322

Open JacobBumgarner opened 2 years ago

JacobBumgarner commented 2 years ago

Describe the bug, what's wrong, and what you expect:

To Reproduce

Please include a code snippet to reproduce the bug in the block below:

import pyvista as pv

p = pv.Plotter(shape=(1,2)
sphere = pv.Sphere()

p.subplot(0,0)
p.add_mesh_clip_box(sphere)
p.subplot(0,1)
p.add_mesh_clip_box(sphere, smooth_shading=True)

p.link_views()
p.show()

Screenshots

https://user-images.githubusercontent.com/70919881/157747019-a1089449-2e13-40d3-a3ed-2dde7999fbc2.mov

banesullivan commented 2 years ago

I'm at least aware of this. It's because sometimes (all the time??) we create a new mesh with face normals for smooth shading and plot that. The clip box function keeps a reference to the original mesh and updates that. Thus the smoothly shaded mesh isn't clipped/updated.

I don't have a good fix for this at the moment and a full solution might require refactoring the smooth shading code a bit

JacobBumgarner commented 2 years ago

@banesullivan Started looking into this a little bit today. For my own implementation purposes, I'd love to help you get this one figured out

Even if you call pyvista.plotting._plotting.prepare_smooth_shading on the mesh before passing it into plotter.add_mesh_clip_box(), it doesn't show smooth shading.

Is that what you would've expected?

A thought I have is that we somehow have to extract the property from the vtkBoxClipDataSet to run prop.SetInterpolationToPhong(), but calling GetProperty() doesn't work. Does the vtkBoxClipDataSet even behave like an vtkActor?

Here is a link to the vtkBoxClipDataSet for convenience.


Another naïve approach could also be just to add a box_widget and then re-clip/re-plot the mesh each time the widget is updated... but adding/removing the mesh from the scene every time it's updated seems like it would be too slow.

JacobBumgarner commented 2 years ago

I haven't tested the timing of the above mentioned naive approach against the add_mesh_clip_box() speeds, but honestly it isn't terrible and allows you to use clipping on smooth meshes :)

I also tried implementing real-time clipping. It's pretty, but does not scale well with the approach where the new mesh is clipped and added during each instance of the box moving.

An example of this can be seen in my repository below https://github.com/JacobBumgarner/pyvista_clip_demo