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