"""
Module consisting of explorers and tracks that connect arbitrary VTK
pipelines to cinema stores.
"""
import cinema_python.adaptors.explorers as explorers
import vtk
from vtk.numpy_interface import dataset_adapter as dsa
import numpy as np
[docs]class ImageExplorer(explorers.Explorer):
"""
An explorer that connects a VTK program's render window to a store
and makes it save new images into the store.
"""
def __init__(self, store, parameters, engines, rw):
super(ImageExplorer, self).__init__(store, parameters, engines)
self.rw = rw
self.w2i = vtk.vtkWindowToImageFilter()
# self.w2i.ReadFrontBufferOff()
self.w2i.SetInput(self.rw)
self.vp = None
self.lp = None
[docs] def insert(self, document):
"""overridden to use VTK to generate an image and create a
the document for it"""
r = self.rw.GetRenderers().GetFirstRenderer()
r.Clear() # TODO: shouldn't be necessary
# import time
# time.sleep(1)
self.w2i.Modified()
self.w2i.Update()
image = self.w2i.GetOutput()
npview = dsa.WrapDataObject(image)
idata = npview.PointData[0]
ext = image.GetExtent()
width = ext[1] - ext[0] + 1
height = ext[3] - ext[2] + 1
if image.GetNumberOfScalarComponents() == 1:
imageslice = np.flipud(idata.reshape(height, width))
else:
imageslice = np.flipud(
idata.reshape(
height, width, image.GetNumberOfScalarComponents()))
document.data = imageslice
super(ImageExplorer, self).insert(document)
[docs] def setDrawMode(self, choice, **kwargs):
""" helper for Color tracks so that they can cause ParaView to
render in the right mode."""
self.rw.GetRenderers().GetFirstRenderer().SetPass(None)
if choice == 'color':
self.w2i.SetInputBufferTypeToRGB()
if choice == 'depth':
self.w2i.SetInputBufferTypeToZBuffer()
if choice == 'value':
self.w2i.SetInputBufferTypeToRGB()
if not self.vp:
self.vp = vtk.vtkValuePass()
self.vp.SetInputArrayToProcess(kwargs['field'], kwargs['name'])
self.vp.SetInputComponentToProcess(kwargs['component'])
self.vp.SetScalarRange(kwargs['range'][0], kwargs['range'][1])
self.rw.GetRenderers().GetFirstRenderer().SetPass(self.vp)
if choice == 'luminance':
self.w2i.SetInputBufferTypeToRGB()
if not self.lp:
self.lp = vtk.vtkLightingMapPass()
self.rw.GetRenderers().GetFirstRenderer().SetPass(self.lp)
[docs]class Clip(explorers.Track):
"""
A track that connects clip filters to a scalar valued parameter.
"""
def __init__(self, argument, clip):
super(Clip, self).__init__()
self.argument = argument
self.clip = clip
[docs] def prepare(self, explorer):
super(Clip, self).prepare(explorer)
[docs] def execute(self, doc):
if self.argument in doc.descriptor:
o = doc.descriptor[self.argument]
self.clip.SetValue(o) # <---- the most important thing!
[docs]class Contour(explorers.Track):
"""
A track that connects clip filters to a scalar valued parameter.
"""
def __init__(self, argument, filter, method):
super(Contour, self).__init__()
self.argument = argument
self.filter = filter
self.method = method
[docs] def prepare(self, explorer):
super(Contour, self).prepare(explorer)
[docs] def execute(self, doc):
if self.argument in doc.descriptor:
o = doc.descriptor[self.argument]
getattr(self.filter, self.method)(0, o)
self.filter.Update()
[docs]class ColorList():
"""
A helper that creates a dictionary of color controls for VTK. The Color
track takes in a color name from the Explorer and looks up into a
ColorList to determine exactly what needs to be set to apply the color.
"""
def __init__(self):
self._dict = {}
[docs] def AddSolidColor(self, name, RGB):
self._dict[name] = {'type': 'rgb', 'content': RGB}
[docs] def AddLUT(self, name, lut, field, arrayname):
self._dict[name] = {
'type': 'lut', 'content': lut, 'field': field,
'arrayname': arrayname}
[docs] def AddDepth(self, name):
self._dict[name] = {'type': 'depth'}
[docs] def AddLuminance(self, name):
self._dict[name] = {'type': 'luminance'}
[docs] def AddValueRender(self, name, field, arrayname, component, range):
self._dict[name] = {
'type': 'value',
'field': field, 'arrayname': arrayname,
'component': component, 'range': range}
[docs] def getColor(self, name):
if name in self._dict:
return self._dict[name]
else:
return {'type': 'none'}
[docs]class ColorActors(explorers.Track):
"""
A track that connects a parameter to a choice of surface rendered color
maps.
"""
def __init__(self, parameter, colorlist, actors):
super(ColorActors, self).__init__()
self.parameter = parameter
self.colorlist = colorlist
self.actors = actors
self.imageExplorer = None
[docs] def execute(self, doc):
"""tells VTK to color the object we've been assigned
using the color definition we've been given that corresponds
to the value we've been assigned to watch in the doc.descriptor"""
if self.parameter in doc.descriptor:
o = doc.descriptor[self.parameter]
spec = self.colorlist.getColor(o)
if spec['type'] == 'rgb':
if self.imageExplorer:
self.imageExplorer.setDrawMode("color")
for a in self.actors:
a.GetMapper().ScalarVisibilityOff()
a.GetProperty().SetColor(spec['content'])
if spec['type'] == 'lut':
if self.imageExplorer:
self.imageExplorer.setDrawMode("color")
for a in self.actors:
a.GetMapper().ScalarVisibilityOn()
a.GetMapper().SetLookupTable(spec['content'])
a.GetMapper().SetScalarMode(spec['field'])
a.GetMapper().SelectColorArray(spec['arrayname'])
if spec['type'] == 'depth':
if self.imageExplorer:
self.imageExplorer.setDrawMode("depth")
for a in self.actors:
a.GetMapper().ScalarVisibilityOff()
if spec['type'] == 'luminance':
if self.imageExplorer:
self.imageExplorer.setDrawMode('luminance')
for a in self.actors:
a.GetMapper().ScalarVisibilityOff()
if spec['type'] == 'value':
if self.imageExplorer:
self.imageExplorer.setDrawMode("value",
field=spec['field'],
name=spec['arrayname'],
component=spec['component'],
range=spec['range'])
for a in self.actors:
a.GetMapper().ScalarVisibilityOn()
[docs]class Color(ColorActors):
def __init__(self, parameter, colorlist, actor):
super(Color, self).__init__(parameter, colorlist, [actor])
[docs]class ActorInLayer(explorers.LayerControl):
"""
A track that turns on and off an actor in a layer
"""
[docs] def showme(self):
# print self.name, "\tON"
self.actor.VisibilityOn()
[docs] def hideme(self):
# print self.name, "\tOFF"
self.actor.VisibilityOff()
def __init__(self, parameter, actor):
super(ActorInLayer, self).__init__(parameter, self.showme, self.hideme)
self.actor = actor
[docs]class Camera(explorers.Track):
"""
A track that connects a VTK script's camera to the phi and theta tracks.
This allows the creation of spherical camera stores where the user can
view the data from many points around it.
"""
def __init__(self, center, axis, distance, camera):
super(Camera, self).__init__()
try:
# Z => 0 | Y => 2 | X => 1
self.offset = (axis.index(1) + 1) % 3
except ValueError:
raise Exception("Rotation axis not supported", axis)
self.center = center
self.distance = distance
self.camera = camera
[docs] def execute(self, document):
import math
theta = document.descriptor['theta']
phi = document.descriptor['phi']
theta_rad = float(theta) / 180.0 * math.pi
phi_rad = float(phi) / 180.0 * math.pi
pos = [
float(self.center[0]) - (
math.cos(phi_rad) * self.distance * math.cos(theta_rad)),
float(self.center[1]) + (
math.sin(phi_rad) * self.distance * math.cos(theta_rad)),
float(self.center[2]) + math.sin(theta_rad) * self.distance
]
up = [
+ math.cos(phi_rad) * math.sin(theta_rad),
- math.sin(phi_rad) * math.sin(theta_rad),
+ math.cos(theta_rad)
]
self.camera.SetPosition(pos)
self.camera.SetViewUp(up)
self.camera.SetFocalPoint(self.center)
@staticmethod
[docs] def obtain_angles(angular_steps=[10, 15]):
thetas = []
phis = []
theta_offset = 90 % angular_steps[1]
if theta_offset == 0:
theta_offset += angular_steps[1]
for theta in range(-90 + theta_offset,
90 - theta_offset + 1, angular_steps[1]):
for phi in range(0, 360, angular_steps[0]):
thetas.append(theta)
phis.append(phi)
return thetas, phis