1 |
""" |
2 |
@author: John NGUI |
3 |
""" |
4 |
|
5 |
import vtk |
6 |
from constant import Renderer, Color, Viewport |
7 |
|
8 |
class Scene: |
9 |
""" |
10 |
Class that defines a scene in which objects are to be rendered on. |
11 |
""" |
12 |
|
13 |
def __init__(self, renderer = Renderer.ONLINE, num_viewport = 1, |
14 |
x_size = 1152, y_size = 864): |
15 |
""" |
16 |
Initialise the scene. |
17 |
|
18 |
@type renderer: String |
19 |
@param renderer: Type of rendering (i.e.Renderer.ONLINE, etc) |
20 |
@type num_viewport: Number |
21 |
@param num_viewport: Number of viewport(s) in the scene. Either 1 or 4 |
22 |
@type x_size: Number |
23 |
@param x_size: Size of the render window along the x-axis |
24 |
@type y_size: Number |
25 |
@param y_size: Size of the render window along the y-axis |
26 |
""" |
27 |
|
28 |
self.__renderer = renderer |
29 |
self.__num_viewport = num_viewport |
30 |
self.__x_size = x_size |
31 |
self.__y_size = y_size |
32 |
|
33 |
self.__vtk_render_window = vtk.vtkRenderWindow() |
34 |
self.__setupScene() |
35 |
|
36 |
def __setupScene(self): |
37 |
""" |
38 |
Setup the scene. |
39 |
""" |
40 |
|
41 |
self.__createViewport() |
42 |
self.__addRenderer() |
43 |
self.setBackground(Color.WHITE) # Default background color is white. |
44 |
|
45 |
# Default title bar. |
46 |
self.setTitleBar("Earth Systems Science Computational Centre (ESSCC)") |
47 |
self.__setSize(self.__x_size, self.__y_size) |
48 |
|
49 |
if(self.__renderer == Renderer.ONLINE): # True for online rendering. |
50 |
self.__setupOnlineRendering() |
51 |
else: # True for offline rendering. |
52 |
self.__setupOfflineRendering() |
53 |
|
54 |
|
55 |
def __createViewport(self): |
56 |
""" |
57 |
Create the viewport(s) in the scene. |
58 |
""" |
59 |
|
60 |
# Create the renderer(s) for the viewport(s). |
61 |
self.__vtk_renderer = [] |
62 |
for viewport in range(0, self.__num_viewport): |
63 |
self.__vtk_renderer.append(vtk.vtkRenderer()) |
64 |
|
65 |
if(self.__num_viewport == 4): |
66 |
# Renderer for the entire scene (background to the viewports). |
67 |
self.__vtk_renderer_background = vtk.vtkRenderer() |
68 |
|
69 |
# Specify the positioning of the four viewports (between 0 and 1). |
70 |
self.__vtk_renderer[Viewport.SOUTH_WEST].SetViewport( |
71 |
0.0, 0.0, 0.5, 0.5) |
72 |
self.__vtk_renderer[Viewport.NORTH_WEST].SetViewport( |
73 |
0.0, 0.5013, 0.5, 1) |
74 |
self.__vtk_renderer[Viewport.NORTH_EAST].SetViewport( |
75 |
0.501, 0.5013, 1, 1) |
76 |
self.__vtk_renderer[Viewport.SOUTH_EAST].SetViewport( |
77 |
0.501, 0.0, 1.0, 0.5) |
78 |
|
79 |
def setBackground(self, color): |
80 |
""" |
81 |
Set the background color of the scene. |
82 |
|
83 |
@type color: L{Color <constant.Color>} constant |
84 |
@param color: Scene background color |
85 |
""" |
86 |
|
87 |
# Color the entire scene (background) black initially. |
88 |
# This is carried out mainly to have the borders between |
89 |
# the viewports visibly black. |
90 |
if(self.__num_viewport == 4): |
91 |
self.__vtk_renderer_background.SetBackground(Color.BLACK) |
92 |
|
93 |
for viewport in range(0, self.__num_viewport): |
94 |
self.__vtk_renderer[viewport].SetBackground(color) |
95 |
|
96 |
def __addRenderer(self): |
97 |
""" |
98 |
Add the renderer(s) to the render window. |
99 |
""" |
100 |
# Renderer for the black scene (background). |
101 |
if(self.__num_viewport == 4): |
102 |
self.__vtk_render_window.AddRenderer( |
103 |
self.__vtk_renderer_background) |
104 |
|
105 |
for viewport in range(0, self.__num_viewport): |
106 |
self.__vtk_render_window.AddRenderer(self.__vtk_renderer[viewport]) |
107 |
|
108 |
def setTitleBar(self, text): |
109 |
""" |
110 |
Set the text on the title bar of the render window. |
111 |
|
112 |
@type text: String |
113 |
@param text: Text on the title bar |
114 |
""" |
115 |
|
116 |
self.__vtk_render_window.SetWindowName(text) |
117 |
|
118 |
def __setSize(self, x_size, y_size): |
119 |
""" |
120 |
Set the size of the render window. |
121 |
|
122 |
@type x_size: Number |
123 |
@param x_size: Size of the render window along the x-axis |
124 |
@type y_size: Number |
125 |
@param y_size: Size of the render window along the y-axis |
126 |
""" |
127 |
|
128 |
self.__vtk_render_window.SetSize(x_size, y_size) |
129 |
|
130 |
def __setupOnlineRendering(self): |
131 |
""" |
132 |
Setup the window interactor for online rendering. |
133 |
""" |
134 |
|
135 |
# Associate the window interactor with the render window. |
136 |
self.__vtk_render_window_interactor = vtk.vtkRenderWindowInteractor( ) |
137 |
self.__vtk_render_window_interactor.SetRenderWindow( |
138 |
self.__vtk_render_window) |
139 |
self.__vtk_render_window_interactor.Initialize() |
140 |
|
141 |
def __setupOfflineRendering(self): |
142 |
""" |
143 |
Setup the window to image filter for offline rendering. |
144 |
""" |
145 |
|
146 |
# Enable offscreen rendering. |
147 |
self.__vtk_render_window.OffScreenRenderingOn() |
148 |
# Convert the output of the render window into an image. |
149 |
self.__vtk_window_to_image = vtk.vtkWindowToImageFilter() |
150 |
self.__vtk_window_to_image.SetInput(self.__vtk_render_window) |
151 |
self.__vtk_image_writer = self.__getImageWriter() |
152 |
|
153 |
def __getImageWriter(self): |
154 |
""" |
155 |
Return the appropriate image writer based on the specified offline |
156 |
renderer. |
157 |
|
158 |
@rtype: vtkImageWriter |
159 |
@return: Image writer |
160 |
""" |
161 |
|
162 |
if(self.__renderer == Renderer.OFFLINE_JPG): |
163 |
return vtk.vtkJPEGWriter() |
164 |
elif(self.__renderer == Renderer.OFFLINE_BMP): |
165 |
return vtk.vtkBMPWriter() |
166 |
elif(self.__renderer == Renderer.OFFLINE_PNM): |
167 |
return vtk.vtkPNMWriter() |
168 |
elif(self.__renderer == Renderer.OFFLINE_PNG): |
169 |
return vtk.vtkPNGWriter() |
170 |
elif(self.__renderer == Renderer.OFFLINE_TIF): |
171 |
return vtk.vtkTIFFWriter() |
172 |
elif(self.__renderer == Renderer.OFFLINE_PS): |
173 |
return vtk.vtkPostScriptWriter() |
174 |
|
175 |
def saveImage(self, image_name): |
176 |
""" |
177 |
Save the rendered object as an image. |
178 |
|
179 |
@type image_name: String |
180 |
@param image_name: Name of the saved image. |
181 |
""" |
182 |
|
183 |
# NOTE: Render and Modified must be called everytime before writing |
184 |
# an image. Otherwise, only the first image will always be saved. |
185 |
# This is due to the architecture of VTK. |
186 |
self.__vtk_render_window.Render() |
187 |
self.__vtk_window_to_image.Modified() |
188 |
|
189 |
# Retrieve rendered object from the window and convert it into an |
190 |
# image. |
191 |
self.__vtk_image_writer.SetInput( |
192 |
self.__vtk_window_to_image.GetOutput()) |
193 |
self.__vtk_image_writer.SetFileName(image_name) |
194 |
self.__vtk_image_writer.Write() |
195 |
|
196 |
def animate(self): |
197 |
""" |
198 |
Render the object onto the scene on-the-fly. No interaction can occur. |
199 |
""" |
200 |
|
201 |
self.__vtk_render_window.Render() |
202 |
|
203 |
def render(self): |
204 |
""" |
205 |
Render the object onto the scene. |
206 |
""" |
207 |
|
208 |
self.__vtk_render_window.Render() |
209 |
|
210 |
# NOTE: Once Start is executed, the driver will not further execute |
211 |
# any subsequent codes thereafter. |
212 |
self.__vtk_render_window_interactor.Start() |
213 |
|
214 |
def _addActor3D(self, viewport, actor): |
215 |
""" |
216 |
Add the actor3D to the appropriate viewport. |
217 |
|
218 |
@type viewport: L{Viewport <constant.Viewport>} constant |
219 |
@param viewport: Viewport which the actor3D is to be added to |
220 |
@type actor: L{Actor3D <actor.Actor3D>} object |
221 |
@param actor: Actor3D which is to be added to the viewport |
222 |
""" |
223 |
|
224 |
self.__vtk_renderer[viewport].AddActor(actor) |
225 |
|
226 |
def _addActor2D(self, viewport, actor): |
227 |
""" |
228 |
Add the actor2D to the appropriate viewport. |
229 |
|
230 |
@type viewport: L{Viewport <constant.Viewport>} constant |
231 |
@param viewport: Viewport which the actor2D is to be added to |
232 |
@type actor: L{Actor2D <actor.Actor2D>} object |
233 |
@param actor: Actor2D which is to be added to the viewport |
234 |
""" |
235 |
|
236 |
self.__vtk_renderer[viewport].AddActor2D(actor) |
237 |
|
238 |
def _setActiveCamera(self, viewport, camera): |
239 |
""" |
240 |
Set the camera to the appropriate viewport. |
241 |
|
242 |
@type viewport: L{Viewport <constant.Viewport>} constant |
243 |
@param viewport: Viewport which the camera is to be added to |
244 |
@type camera: L{Camera <camera.Camera>} object |
245 |
@param camera: Camera which is to be assigned to the viewport |
246 |
""" |
247 |
|
248 |
self.__vtk_renderer[viewport].SetActiveCamera(camera) |
249 |
|
250 |
def _addLight(self, viewport, light): |
251 |
""" |
252 |
Add the light to the appropriate viewport. |
253 |
|
254 |
@type viewport: L{Viewport <constant.Viewport>} constant |
255 |
@param viewport: Viewport which the camera is to be added to |
256 |
@type light: L{Light <light.Light>} object |
257 |
@param light: Light which is to be assigned to the viewport |
258 |
""" |
259 |
|
260 |
self.__vtk_renderer[viewport].AddLight(light) |
261 |
|
262 |
def _getRenderer(self): |
263 |
""" |
264 |
Return the renderer(s) |
265 |
|
266 |
@rtype: One or more column tuple of vtkRenderer |
267 |
@return: Renderer(s) |
268 |
""" |
269 |
|
270 |
return self.__vtk_renderer |