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