Is there a way to programmatically mark/select cells for extraction?

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()

Instead of a selection source, I have often done this. Don’t know if this is better?

   polydataConnect = vtkPolyDataConnectivityFilter()
   polydataConnect.SetExtractionModeToCellSeededRegions()
   polydataConnect.InitializeSeedList()
   for i in range(nCells):
      // Here your criteria on the dot product
      polydataConnect.AddSeed(i)
  polydataConnect.SetInputData(pd);
  polydataConnect.Update()

That’s an interesting class, but for my particular use case there isn’t a topological way of extracting the region (I don’t think there is …).

I think you’ll need to use VTK: vtkThreshold Class Reference

Oh, I like that. So, for instance, I would define a node/cell data array, assign integers to it (inlet pressure = 1, wall = 2, etc.) and then threshold:

(swiped from here):

    selector = vtkThreshold()
    selector.SetInputArrayToProcess(0, 0, 0, vtkDataObject().FIELD_ASSOCIATION_CELLS,
                                    vtkDataSetAttributes().SCALARS)
    selector.SetInputConnection(pad.GetOutputPort())
    selector.SetLowerThreshold(start_label)
    selector.SetUpperThreshold(end_label)
    selector.Update()