Statistiques
| Révision :

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