Statistiques
| Révision :

root / ase / visualize / vtk / pipeline.py @ 1

Historique | Voir | Annoter | Télécharger (6,74 ko)

1 1 tkerber
2 1 tkerber
import numpy as np
3 1 tkerber
4 1 tkerber
from vtk import vtkPolyDataMapper, vtkPolyDataNormals, \
5 1 tkerber
                vtkLinearSubdivisionFilter, vtkSmoothPolyDataFilter, \
6 1 tkerber
                vtkDepthSortPolyData, vtkAlgorithm, vtkAlgorithmOutput
7 1 tkerber
from ase.visualize.vtk.grid import vtkVolumeGrid
8 1 tkerber
9 1 tkerber
# -------------------------------------------------------------------
10 1 tkerber
11 1 tkerber
class vtkPipeline:
12 1 tkerber
    _branchable = False
13 1 tkerber
14 1 tkerber
    def __init__(self, vtkish_data=None):
15 1 tkerber
16 1 tkerber
        self.vtkish_data = None
17 1 tkerber
        self.closed = False
18 1 tkerber
        self.pending = False
19 1 tkerber
        self.filters = tuple()
20 1 tkerber
21 1 tkerber
        if vtkish_data is not None:
22 1 tkerber
            self.set_data(vtkish_data)
23 1 tkerber
24 1 tkerber
    def hasdata(self):
25 1 tkerber
        return (self.vtkish_data is not None)
26 1 tkerber
27 1 tkerber
    def hasfilters(self):
28 1 tkerber
        return len(self.filters)>0
29 1 tkerber
30 1 tkerber
    def set_data(self, vtkish_data):
31 1 tkerber
32 1 tkerber
        assert vtkish_data is not None
33 1 tkerber
34 1 tkerber
        if self.hasdata():
35 1 tkerber
            raise RuntimeError('Pipeline already has input.')
36 1 tkerber
        elif vtkish_data in self:
37 1 tkerber
            raise ValueError('Pipeline loop detected.')
38 1 tkerber
39 1 tkerber
        if isinstance(vtkish_data, vtkPipeline):
40 1 tkerber
            # The embedded pipeline takes over
41 1 tkerber
            vtkish_data.signal_close()
42 1 tkerber
43 1 tkerber
        self.vtkish_data = vtkish_data
44 1 tkerber
45 1 tkerber
        if not self.hasfilters():
46 1 tkerber
            return
47 1 tkerber
48 1 tkerber
        vtkish_inner = self.filters[0]
49 1 tkerber
50 1 tkerber
        if isinstance(vtkish_inner, vtkPipeline):
51 1 tkerber
            vtkish_inner.set_data(vtkish_data) #TODO does this work?
52 1 tkerber
        else:
53 1 tkerber
            assert isinstance(vtkish_inner, vtkAlgorithm)
54 1 tkerber
55 1 tkerber
            if isinstance(vtkish_data, vtkPipeline):
56 1 tkerber
                # The embedded pipeline takes over
57 1 tkerber
                vtkish_data.connect(vtkish_inner)
58 1 tkerber
            else:
59 1 tkerber
                assert isinstance(vtkish_data, vtkAlgorithm)
60 1 tkerber
                vtkish_inner.SetInputConnection(vtkish_data.GetOutputPort())
61 1 tkerber
62 1 tkerber
    def isempty(self):
63 1 tkerber
        return not self.hasdata() and not self.hasfilters()
64 1 tkerber
65 1 tkerber
    def isclosed(self):
66 1 tkerber
        if self.pending:
67 1 tkerber
            raise RuntimeError('Pipeline output port state is pending.')
68 1 tkerber
        return self.closed
69 1 tkerber
70 1 tkerber
    def signal_close(self):
71 1 tkerber
        if self.closed:
72 1 tkerber
            raise RuntimeError('Pipeline output port is already closed.')
73 1 tkerber
        elif not self._branchable:
74 1 tkerber
            self.pending = True
75 1 tkerber
76 1 tkerber
    def get_output_port(self):
77 1 tkerber
        if self.closed:
78 1 tkerber
            raise RuntimeError('Pipeline output port is closed.')
79 1 tkerber
        elif self.pending:
80 1 tkerber
            self.closed = True
81 1 tkerber
            self.pending = False
82 1 tkerber
83 1 tkerber
        if self.hasfilters():
84 1 tkerber
            vtkish_outer = self.filters[-1]
85 1 tkerber
        elif self.hasdata():
86 1 tkerber
            vtkish_outer = self.vtkish_data
87 1 tkerber
        else:
88 1 tkerber
            raise RuntimeError('Pipeline output port unavailable.')
89 1 tkerber
90 1 tkerber
        if isinstance(vtkish_outer, vtkPipeline):
91 1 tkerber
            return vtkish_outer.get_output_port()
92 1 tkerber
        else:
93 1 tkerber
            assert isinstance(vtkish_outer, vtkAlgorithm)
94 1 tkerber
            return vtkish_outer.GetOutputPort()
95 1 tkerber
96 1 tkerber
    def set_input_connection(self, vtk_port):
97 1 tkerber
        assert isinstance(vtk_port, vtkAlgorithmOutput)
98 1 tkerber
99 1 tkerber
        vtkish_inner = self.filters[0]
100 1 tkerber
101 1 tkerber
        if isinstance(vtkish_inner, vtkPipeline):
102 1 tkerber
            # Connect must be passed down
103 1 tkerber
            vtkish_inner.set_input_connection(vtk_port)
104 1 tkerber
        else:
105 1 tkerber
            vtkish_inner.SetInputConnection(vtk_port)
106 1 tkerber
107 1 tkerber
    def connect(self, vtkish_filter):
108 1 tkerber
        if vtkish_filter in self:
109 1 tkerber
            raise ValueError('Pipeline loop detected.')
110 1 tkerber
111 1 tkerber
        if isinstance(vtkish_filter, vtkPipeline):
112 1 tkerber
            # Connection must be passed down
113 1 tkerber
            if not self.isempty():
114 1 tkerber
                vtkish_filter.set_input_connection(self.get_output_port())
115 1 tkerber
116 1 tkerber
            # The containing pipeline takes over
117 1 tkerber
            vtkish_filter.signal_close()
118 1 tkerber
119 1 tkerber
        elif not self.isempty():
120 1 tkerber
            assert isinstance(vtkish_filter, vtkAlgorithm)
121 1 tkerber
            vtkish_filter.SetInputConnection(self.get_output_port())
122 1 tkerber
123 1 tkerber
    def append(self, vtkish_filter):
124 1 tkerber
        self.connect(vtkish_filter)
125 1 tkerber
        self.filters += (vtkish_filter,)
126 1 tkerber
127 1 tkerber
    def extend(self, vtkish_filters):
128 1 tkerber
        map(self.append, vtkish_filters)
129 1 tkerber
130 1 tkerber
    def __contains__(self, vtkish_candidate):
131 1 tkerber
        if vtkish_candidate == self:
132 1 tkerber
            return True
133 1 tkerber
134 1 tkerber
        if self.hasdata():
135 1 tkerber
            if isinstance(self.vtkish_data, vtkPipeline):
136 1 tkerber
                if vtkish_candidate in self.vtkish_data:
137 1 tkerber
                    return True
138 1 tkerber
            else:
139 1 tkerber
                if vtkish_candidate == self.vtkish_data:
140 1 tkerber
                    return True
141 1 tkerber
142 1 tkerber
        if vtkish_candidate in self.filters:
143 1 tkerber
            return True
144 1 tkerber
145 1 tkerber
        for vtkish_filter in self.filters:
146 1 tkerber
            if isinstance(vtkish_filter, vtkPipeline) \
147 1 tkerber
                and vtkish_candidate in vtkish_filter:
148 1 tkerber
                return True
149 1 tkerber
150 1 tkerber
        return False
151 1 tkerber
152 1 tkerber
    def __getitem__(self, i): #TODO XXX this is a hack
153 1 tkerber
        return self.filters[i]
154 1 tkerber
155 1 tkerber
# -------------------------------------------------------------------
156 1 tkerber
157 1 tkerber
class vtkPolyDataPipeline(vtkPipeline):
158 1 tkerber
    def __init__(self, vtkish_polydata=None):
159 1 tkerber
        vtkPipeline.__init__(self, vtkish_polydata)
160 1 tkerber
161 1 tkerber
    def connect(self, vtkish_filter):
162 1 tkerber
        if isinstance(vtkish_filter, vtkPolyDataMapper):
163 1 tkerber
            self.signal_close()
164 1 tkerber
        vtkPipeline.connect(self, vtkish_filter)
165 1 tkerber
166 1 tkerber
class vtkSurfaceSmootherPipeline(vtkPolyDataPipeline):
167 1 tkerber
    def __init__(self, grid, vtkish_polydata=None, angle=15):
168 1 tkerber
169 1 tkerber
        vtkPolyDataPipeline.__init__(self, vtkish_polydata)
170 1 tkerber
171 1 tkerber
        # Make sure grid argument is correct type
172 1 tkerber
        assert isinstance(grid, vtkVolumeGrid)
173 1 tkerber
        self.grid = grid
174 1 tkerber
175 1 tkerber
        # Split polys with intersection angles greater than angle
176 1 tkerber
        vtk_dnorm = vtkPolyDataNormals()
177 1 tkerber
        vtk_dnorm.SetFeatureAngle(angle)
178 1 tkerber
        vtk_dnorm.SplittingOn()
179 1 tkerber
        vtk_dnorm.ComputeCellNormalsOff()
180 1 tkerber
        vtk_dnorm.ComputePointNormalsOff()
181 1 tkerber
        self.append(vtk_dnorm)
182 1 tkerber
183 1 tkerber
        relax = self.grid.get_relaxation_factor()
184 1 tkerber
185 1 tkerber
        if relax is not None:
186 1 tkerber
            print 'relax=',relax
187 1 tkerber
            #vtk_subdiv = vtkButterflySubdivisionFilter()
188 1 tkerber
            vtk_subdiv = vtkLinearSubdivisionFilter()
189 1 tkerber
            self.append(vtk_subdiv)
190 1 tkerber
191 1 tkerber
            # Smooth out some of the sharp points.
192 1 tkerber
            vtk_smooth = vtkSmoothPolyDataFilter()
193 1 tkerber
            vtk_smooth.SetRelaxationFactor(relax)
194 1 tkerber
            self.append(vtk_smooth)
195 1 tkerber
196 1 tkerber
class vtkDepthSortPipeline(vtkPolyDataPipeline):
197 1 tkerber
    def __init__(self, vtk_renderer, vtkish_polydata=None):
198 1 tkerber
199 1 tkerber
        vtkPolyDataPipeline.__init__(self, vtkish_polydata)
200 1 tkerber
201 1 tkerber
        # The depht sort object is set up to generate scalars representing
202 1 tkerber
        # the sort depth. A camera is assigned for the sorting. The camera
203 1 tkerber
        # defines the sort vector (position and focal point).
204 1 tkerber
        vtk_ds = vtkDepthSortPolyData()
205 1 tkerber
        vtk_ds.SetCamera(vtk_renderer.GetActiveCamera())
206 1 tkerber
        vtk_ds.SetDirectionToBackToFront()
207 1 tkerber
        #vtk_ds.SetVector(1, 1, 1)
208 1 tkerber
        #vtk_ds.SortScalarsOn()
209 1 tkerber
        #vtk_ds.Update()
210 1 tkerber
        self.append(vtk_ds)
211 1 tkerber
212 1 tkerber
        vtk_renderer.ResetCamera()