root / ase / visualize / vtk / module.py @ 1
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 |
|