Perhaps there is a more elegant way of doing this, but I wanted to select cells where either the normal had a positive dot product with a given unit vector, or that had a positive dot product with a direction to a point in space. (Like directional light and point light in a graphics sense).
Right now I am doing it with something like this (and the selection is frustratingly not-quite-hemispherical):
import numpy as np
import vtkmodules.vtkRenderingOpenGL2
from vtkmodules.util.numpy_support import vtk_to_numpy
from vtkmodules.vtkFiltersCore import vtkPolyDataNormals
from vtkmodules.vtkFiltersExtraction import vtkExtractSelection
from vtkmodules.vtkFiltersGeneral import vtkShrinkFilter
from vtkmodules.vtkFiltersSources import vtkSelectionSource, vtkSphereSource
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleTrackballCamera
from vtkmodules.vtkRenderingCore import (
vtkActor,
vtkDataSetMapper,
vtkRenderer,
vtkRenderWindow,
vtkRenderWindowInteractor)
s = vtkSphereSource()
s.SetPhiResolution(20)
s.SetThetaResolution(20)
nf = vtkPolyDataNormals()
nf.ComputeCellNormalsOn()
nf.SetInputConnection(s.GetOutputPort())
nf.Update()
pd = nf.GetOutput()
normals = vtk_to_numpy(pd.GetCellData().GetNormals())
direction = np.array((1, 1, 0))
direction = direction/np.sqrt(np.dot(direction, direction))
ss = vtkSelectionSource()
ss.SetContentType(3) # supposed to be SelectionContent::INDICES ... python equiv?
ss.SetFieldType(0) # supposed to be SelectionField::CELL ... python equiv?
ci = pd.NewCellIterator()
ci.InitTraversal()
while True:
ci.GoToNextCell()
if ci.IsDoneWithTraversal():
break
idx = ci.GetCellId()
cell_normal = normals[idx, :]
if np.dot(cell_normal, direction) >= 0:
ss.AddID(-1, idx)
es = vtkExtractSelection()
es.SetInputConnection(0, nf.GetOutputPort())
es.SetInputConnection(1, ss.GetOutputPort())
es.Update()
sf = vtkShrinkFilter()
sf.SetInputConnection(es.GetOutputPort())
sf.SetShrinkFactor(0.9)
mapper = vtkDataSetMapper()
mapper.SetInputConnection(sf.GetOutputPort())
actor = vtkActor()
actor.SetMapper(mapper)
ren = vtkRenderer()
ren_win = vtkRenderWindow()
ren_win.SetWindowName("Selected Sphere")
ren_win.SetSize(600, 600)
ren_win.AddRenderer(ren)
iren = vtkRenderWindowInteractor()
iren.SetRenderWindow(ren_win)
style = vtkInteractorStyleTrackballCamera()
iren.SetInteractorStyle(style)
ren.AddActor(actor)
ren.ResetCamera()
ren_win.Render()
iren.Start()