pyvista / pyvista-support

[moved] Please head over to the Discussions tab of the PyVista repository
https://github.com/pyvista/pyvista/discussions
60 stars 4 forks source link

Finding visible vertices of mesh #147

Closed anderspe73 closed 22 hours ago

anderspe73 commented 4 years ago

Hi everyone, new to pyvista and in need of some help. I have a triangular mesh in 3D and I am trying to determine which vertices are visible from a given position. I would like to do so without displaying/plotting the mesh or any manual clicking. Is this doable with pyvista? If not, any pointer/suggestions would be greatly appreciated.

banesullivan commented 4 years ago

So as somewhat alluded in your post, this type of selection is currently possible in an interactive fashion using the visible cell selection tool (Plotter.enable_cell_picking(through=False). We can leverage that same workflow in an automated fashion without user interaction as follows.

This might get a bit messy, but if we can make a streamlined routine for this, then we could add this as a feature in PyVista to make the user-facing side of this more simple.


So I managed to get this to work at one point, but I'm having trouble now with it crashing my kernel. I'm going to post the broken code for now and see if I or someone else can come back to this.

```py import pyvista as pv from pyvista import examples import vtk mesh = examples.load_random_hills() # this is the camera position I want to use cpos = [(6.57262195669236, 19.99388479424327, 6.691549967725345), (-1.399057787405183, 11.379489876926161, 3.061306711824895), (-0.15620748713919835, -0.2573168739454372, 0.9536179776748158)] p = pv.Plotter(notebook=False) p.add_mesh(mesh) p.camera_position = cpos ####### # perfrom the automatic picking selector = vtk.vtkOpenGLHardwareSelector() selector.SetFieldAssociation(vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS) selector.SetRenderer(p.renderer) selector.SetArea(0,0,p.window_size[0],p.window_size[1]) selection = selector.Select() extractor = vtk.vtkExtractSelection() extractor.SetInputData(0, mesh) extractor.SetInputData(1, selection) extractor.Update() visible = pv.wrap(extractor.GetOutput()) p.add_mesh(visible, color="pink", style="wireframe") p.show() ```
c0mm3nt commented 1 day ago

This is exactly what I have been looking for! The sample code is nearly functional. I just needed to add an initial render before performing the selection.

The following code should work without issue. I also tested it for FIELD_ASSOCIATION_POINTS to get vertices as well.

import pyvista as pv
from pyvista import examples
import vtk

mesh = examples.load_random_hills()

# this is the camera position I want to use
cpos = [(6.57262195669236, 19.99388479424327, 6.691549967725345),
 (-1.399057787405183, 11.379489876926161, 3.061306711824895),
 (-0.15620748713919835, -0.2573168739454372, 0.9536179776748158)]

p = pv.Plotter(notebook=False)
p.add_mesh(mesh)
p.camera_position = cpos

# Trigger a render to initialize OpenGL context
render_window = p.renderer.GetRenderWindow()
render_window.Render()  

# Now set up and perform selection
selector = vtk.vtkOpenGLHardwareSelector()
selector.SetFieldAssociation(vtk.vtkDataObject.FIELD_ASSOCIATION_CELLS)
selector.SetRenderer(p.renderer)
selector.SetArea(0, 0, p.window_size[0], p.window_size[1])
selection = selector.Select()

extractor = vtk.vtkExtractSelection()
extractor.SetInputData(0, mesh)
extractor.SetInputData(1, selection)
extractor.Update()

visible = pv.wrap(extractor.GetOutput())

p.add_mesh(visible, color="pink", style="wireframe")
p.show()
banesullivan commented 22 hours ago

awesome @c0mm3nt! Thanks for following up with the working code!

Considering this issue is 5 years old and you've made a working example, I'm going to mark this as closed. If you feel this is something that could be implemented as a part of the Plotter API, please feel free to contribute!