root / ase / visualize / vtk / module.py @ 5
Historique | Voir | Annoter | Télécharger (7,8 ko)
| 1 |
|
|---|---|
| 2 |
import numpy as np |
| 3 |
|
| 4 |
from vtk import vtkProp3D, vtkPolyDataMapper, vtkActor, vtkLODActor, \ |
| 5 |
vtkPointSet, vtkGlyph3D, vtkRenderer |
| 6 |
from ase.visualize.vtk.sources import vtkCustomGlyphSource, \ |
| 7 |
vtkClampedGlyphSource
|
| 8 |
|
| 9 |
# -------------------------------------------------------------------
|
| 10 |
|
| 11 |
class vtkModule: |
| 12 |
"""Modules represent a unified collection of VTK objects needed for
|
| 13 |
introducing basic visualization concepts such as surfaces or shapes.
|
| 14 |
|
| 15 |
A common trait of all modules is the need for an actor representation and
|
| 16 |
corresponding generic properties such as lighting, color and transparency.
|
| 17 |
|
| 18 |
"""
|
| 19 |
def __init__(self, vtk_act, vtk_property=None): |
| 20 |
"""Construct basic VTK-representation of a module.
|
| 21 |
|
| 22 |
vtk_act: Instance of vtkActor or subclass thereof
|
| 23 |
A vtkActor represents an entity in a rendering scene.
|
| 24 |
|
| 25 |
vtk_property = None: Instance of vtkProperty or subclass thereof
|
| 26 |
A vtkProperty represents e.g. lighting and other surface
|
| 27 |
properties of a geometric object, in this case the actor.
|
| 28 |
|
| 29 |
"""
|
| 30 |
self.vtk_act = None |
| 31 |
self.set_actor(vtk_act)
|
| 32 |
|
| 33 |
if vtk_property is not None: |
| 34 |
self.set_property(vtk_property)
|
| 35 |
|
| 36 |
def set_actor(self, vtk_act): |
| 37 |
"""Set the actor representing this module in a rendering scene."""
|
| 38 |
assert isinstance(vtk_act, vtkActor) |
| 39 |
self.vtk_act = vtk_act
|
| 40 |
|
| 41 |
def set_property(self, vtk_property): |
| 42 |
"""Set the property of the actor representing this module."""
|
| 43 |
self.vtk_act.SetProperty(vtk_property)
|
| 44 |
|
| 45 |
def get_actor(self): |
| 46 |
"""Return the actor representing this module in a rendering scene."""
|
| 47 |
return self.vtk_act |
| 48 |
|
| 49 |
# -------------------------------------------------------------------
|
| 50 |
|
| 51 |
class vtkLODModule(vtkModule): |
| 52 |
_vtk_actor_class = vtkLODActor |
| 53 |
|
| 54 |
def get_lod(self): |
| 55 |
return 100 |
| 56 |
|
| 57 |
def set_actor(self, vtk_act): |
| 58 |
vtkModule.set_actor(self, vtk_act)
|
| 59 |
|
| 60 |
if isinstance(vtk_act, vtkLODActor): |
| 61 |
vtk_act.SetNumberOfCloudPoints(self.get_lod())
|
| 62 |
|
| 63 |
class vtkPolyDataModule(vtkModule): |
| 64 |
_vtk_actor_class = vtkActor |
| 65 |
|
| 66 |
__doc__ = vtkModule.__doc__ + """
|
| 67 |
Poly data modules are based on polygonal data sets, which can be mapped
|
| 68 |
into graphics primitives suitable for rendering within the VTK framework.
|
| 69 |
|
| 70 |
"""
|
| 71 |
def __init__(self, vtk_polydata, vtk_property=None): |
| 72 |
"""Construct VTK-representation of a module containing polygonals.
|
| 73 |
|
| 74 |
vtk_polydata: Instance of vtkPolyData, subclass thereof or
|
| 75 |
vtkPolyDataAlgorithm, which produces vtkPolyData as output.
|
| 76 |
A vtkPolyData represents a polygonal data set consisting of
|
| 77 |
point and cell attributes, which can be mapped to graphics
|
| 78 |
primitives for subsequent rendering.
|
| 79 |
|
| 80 |
vtk_property = None: Instance of vtkProperty or subclass thereof
|
| 81 |
A vtkProperty represents e.g. lighting and other surface
|
| 82 |
properties of a geometric object, in this case the polydata.
|
| 83 |
|
| 84 |
"""
|
| 85 |
vtkModule.__init__(self, self._vtk_actor_class(), vtk_property) |
| 86 |
|
| 87 |
self.vtk_dmap = vtkPolyDataMapper()
|
| 88 |
self.vtk_dmap.SetInputConnection(vtk_polydata.GetOutputPort())
|
| 89 |
self.vtk_act.SetMapper(self.vtk_dmap) |
| 90 |
|
| 91 |
class vtkGlyphModule(vtkPolyDataModule): |
| 92 |
__doc__ = vtkPolyDataModule.__doc__ + """
|
| 93 |
Glyph modules construct these polygonal data sets by replicating a glyph
|
| 94 |
source across a specific set of points, using available scalar or vector
|
| 95 |
point data to scale and orientate the glyph source if desired.
|
| 96 |
|
| 97 |
Example:
|
| 98 |
|
| 99 |
>>> atoms = molecule('C60')
|
| 100 |
>>> cell = vtkUnitCellModule(atoms)
|
| 101 |
>>> apos = vtkAtomicPositions(atoms.get_positions(), cell)
|
| 102 |
>>> vtk_ugd = apos.get_unstructured_grid()
|
| 103 |
>>> glyph_source = vtkAtomSource('C')
|
| 104 |
>>> glyph_module = vtkGlyphModule(vtk_ugd, glyph_source)
|
| 105 |
|
| 106 |
"""
|
| 107 |
def __init__(self, vtk_pointset, glyph_source, |
| 108 |
scalemode=None, colormode=None): |
| 109 |
"""Construct VTK-representation of a module containing glyphs.
|
| 110 |
These glyphs share a common source, defining their geometrical
|
| 111 |
shape, which is cloned and oriented according to the input data.
|
| 112 |
|
| 113 |
vtk_pointset: Instance of vtkPointSet or subclass thereof
|
| 114 |
A vtkPointSet defines a set of positions, which may then be
|
| 115 |
assigned specific scalar of vector data across the entire set.
|
| 116 |
|
| 117 |
glyph_source: Instance of ~vtk.vtkCustomGlyphSource or subclass thereof
|
| 118 |
Provides the basic shape to distribute over the point set.
|
| 119 |
|
| 120 |
"""
|
| 121 |
assert isinstance(vtk_pointset, vtkPointSet) |
| 122 |
assert isinstance(glyph_source, vtkCustomGlyphSource) |
| 123 |
|
| 124 |
# Create VTK Glyph3D based on unstructured grid
|
| 125 |
self.vtk_g3d = vtkGlyph3D()
|
| 126 |
self.vtk_g3d.SetInput(vtk_pointset)
|
| 127 |
self.vtk_g3d.SetSource(glyph_source.get_output())
|
| 128 |
self.vtk_g3d.SetScaleFactor(glyph_source.get_scale())
|
| 129 |
|
| 130 |
# Clamping normalizes the glyph scaling to within the range [0,1].
|
| 131 |
# Setting a scale factor will then scale these by the given factor.
|
| 132 |
if isinstance(glyph_source, vtkClampedGlyphSource): |
| 133 |
self.vtk_g3d.SetClamping(True) |
| 134 |
self.vtk_g3d.SetRange(glyph_source.get_range())
|
| 135 |
|
| 136 |
if scalemode is 'off': |
| 137 |
self.vtk_g3d.SetScaleModeToDataScalingOff()
|
| 138 |
elif scalemode is 'scalar': |
| 139 |
self.vtk_g3d.SetScaleModeToScaleByScalar()
|
| 140 |
elif scalemode is 'vector': |
| 141 |
self.vtk_g3d.SetScaleModeToScaleByVector()
|
| 142 |
elif scalemode is not None: |
| 143 |
raise ValueError('Unrecognized scale mode \'%s\'.' % scalemode) |
| 144 |
|
| 145 |
if colormode is 'scale': |
| 146 |
self.vtk_g3d.SetColorModeToColorByScale()
|
| 147 |
elif colormode is 'scalar': |
| 148 |
self.vtk_g3d.SetColorModeToColorByScalar()
|
| 149 |
elif colormode is 'vector': |
| 150 |
self.vtk_g3d.SetColorModeToColorByVector()
|
| 151 |
elif colormode is not None: |
| 152 |
raise ValueError('Unrecognized scale mode \'%s\'.' % scalemode) |
| 153 |
|
| 154 |
vtkPolyDataModule.__init__(self, self.vtk_g3d, glyph_source.get_property()) |
| 155 |
|
| 156 |
# -------------------------------------------------------------------
|
| 157 |
|
| 158 |
class vtkLabelModule(vtkModule): |
| 159 |
def __init__(self, vtk_pointset, vtk_property=None): |
| 160 |
|
| 161 |
vtk_Module.__init__(self, vtkActor(), vtk_property)
|
| 162 |
|
| 163 |
assert isinstance(vtk_pointset, vtkPointSet) |
| 164 |
|
| 165 |
self.vtk_dmap = vtkLabeledDataMapper()
|
| 166 |
#self.vtk_dmap.SetLabelModeToLabelIds() #TODO XXX strings!!!
|
| 167 |
self.vtk_dmap.GetLabelTextProperty().SetFontSize(12) |
| 168 |
self.vtk_dmap.GetLabelTextProperty().SetJustificationToRight()
|
| 169 |
self.vtk_dmap.SetInputConnection(vtk_pointset.GetOutputPort())
|
| 170 |
self.vtk_act.SetMapper(self.vtk_dmap) |
| 171 |
|
| 172 |
#vtk_g3d.GetPointIdsName...
|
| 173 |
|
| 174 |
# -------------------------------------------------------------------
|
| 175 |
|
| 176 |
class vtkModuleAnchor: |
| 177 |
"""
|
| 178 |
TODO XXX
|
| 179 |
"""
|
| 180 |
def __init__(self): |
| 181 |
"""Construct an anchoring point for various VTK modules.
|
| 182 |
|
| 183 |
"""
|
| 184 |
self.modules = {}
|
| 185 |
|
| 186 |
def get_module(self, name): |
| 187 |
if name not in self.modules.keys(): |
| 188 |
raise RuntimeError('Module \'%s\' does not exists.' % name) |
| 189 |
|
| 190 |
return self.modules[name] |
| 191 |
|
| 192 |
def add_module(self, name, module): |
| 193 |
if not isinstance(module, vtkModule): |
| 194 |
raise ValueError('Module must be instance of vtkModule.') |
| 195 |
|
| 196 |
if name in self.modules.keys(): |
| 197 |
raise RuntimeError('Module \'%s\' already exists.' % name) |
| 198 |
|
| 199 |
self.modules[name] = module
|
| 200 |
|
| 201 |
def get_actor(self, name): |
| 202 |
return self.get_module(name).get_actor() |
| 203 |
|
| 204 |
def add_actors_to_renderer(self, vtk_renderer, name=None): |
| 205 |
assert isinstance(vtk_renderer, vtkRenderer) |
| 206 |
if name is None: |
| 207 |
for module in self.modules.values(): |
| 208 |
vtk_renderer.AddActor(module.get_actor()) |
| 209 |
else:
|
| 210 |
vtk_renderer.AddActor(self.get_actor(name))
|
| 211 |
|