1 |
""" |
2 |
Class and functions associated with a pyvisi Scene |
3 |
|
4 |
@var __author__: name of author |
5 |
@var __license__: licence agreement |
6 |
@var __copyright__: copyrights |
7 |
@var __url__: url entry point on documentation |
8 |
@var __version__: version |
9 |
@var __date__: date of the version |
10 |
""" |
11 |
|
12 |
__copyright__=""" Copyright (c) 2006 by ACcESS MNRF |
13 |
http://www.access.edu.au |
14 |
Primary Business: Queensland, Australia""" |
15 |
__license__="""Licensed under the Open Software License version 3.0 |
16 |
http://www.opensource.org/licenses/osl-3.0.php""" |
17 |
__author__="Paul Cochrane" |
18 |
__url__="http://www.iservo.edu.au/esys" |
19 |
__version__="$Revision$" |
20 |
__date__="$Date$" |
21 |
|
22 |
|
23 |
# generic imports |
24 |
from common import debugMsg, overrideWarning, fileCheck |
25 |
|
26 |
from renderer import Renderer |
27 |
|
28 |
class Scene(object): |
29 |
""" |
30 |
The main object controlling the scene. |
31 |
|
32 |
This is the base Scene object. It should be inherited, and then its |
33 |
methods overridden. |
34 |
""" |
35 |
|
36 |
def __init__(self): |
37 |
""" |
38 |
The init function |
39 |
""" |
40 |
object.__init__(self) |
41 |
debugMsg("Called Scene.__init__()") |
42 |
|
43 |
self.renderer = Renderer() |
44 |
|
45 |
self.xSize = 640 |
46 |
self.ySize = 480 |
47 |
|
48 |
def add(self, obj): |
49 |
""" |
50 |
Add a new item to the scene |
51 |
|
52 |
@param obj: The object to add to the scene |
53 |
@type obj: object |
54 |
""" |
55 |
debugMsg("Called Scene.add()") |
56 |
|
57 |
if obj is None: |
58 |
raise ValueError, "You must specify an object to add" |
59 |
|
60 |
# print a warning message if get to here |
61 |
overrideWarning("Scene.add") |
62 |
|
63 |
return |
64 |
|
65 |
def delete(self, obj): |
66 |
""" |
67 |
Delete an item from the scene |
68 |
|
69 |
@param obj: The object to remove |
70 |
@type obj: object |
71 |
""" |
72 |
debugMsg("Called Scene.delete()") |
73 |
|
74 |
if obj is None: |
75 |
raise ValueError, "You must specify an object to delete" |
76 |
|
77 |
# print a warning message if get to here |
78 |
overrideWarning("Scene.delete") |
79 |
|
80 |
return |
81 |
|
82 |
def place(self, obj): |
83 |
""" |
84 |
Place an object within a scene |
85 |
|
86 |
@param obj: The object to place within the scene |
87 |
@type obj: object |
88 |
""" |
89 |
debugMsg("Called Scene.place()") |
90 |
|
91 |
if obj is None: |
92 |
raise ValueError, "You must specify an object to place" |
93 |
|
94 |
# print a warning message if get to here |
95 |
overrideWarning("Scene.place") |
96 |
|
97 |
return |
98 |
|
99 |
def render(self, pause=False, interactive=False): |
100 |
""" |
101 |
Render (or re-render) the scene |
102 |
|
103 |
Render the scene, either to screen, or to a buffer waiting for a save |
104 |
|
105 |
@param pause: Flag to wait at end of script evaluation for user input |
106 |
@type pause: boolean |
107 |
|
108 |
@param interactive: Whether or not to have interactive use of the output |
109 |
@type interactive: boolean |
110 |
""" |
111 |
debugMsg("Called Scene.render()") |
112 |
renderer = self.renderer |
113 |
|
114 |
# I don't yet know where to put this, but just to get stuff going... |
115 |
renderer.runString("# Scene.render()\n") |
116 |
|
117 |
# optionally print out the evaluation stack to make sure we're doing |
118 |
# the right thing |
119 |
debugMsg("Here is the evaluation stack") |
120 |
debugMsg(60*"#") |
121 |
debugMsg(renderer.getEvalStack()) |
122 |
debugMsg(60*"#") |
123 |
|
124 |
# execute the eval stack |
125 |
evalStack = renderer.getEvalStack() |
126 |
exec evalStack in self.renderer.renderDict |
127 |
|
128 |
# flush the evaluation stack |
129 |
debugMsg("Flusing evaluation stack") |
130 |
renderer.resetEvalStack() |
131 |
|
132 |
# this is just to stop lint from complaining that pause and |
133 |
# interactive aren't used |
134 |
if pause is not True or pause is not False: |
135 |
raise ValueError, "\'pause\' must be either True or False" |
136 |
|
137 |
if interactive is not True or pause is not False: |
138 |
raise ValueError, "\'interactive\' must be either True or False" |
139 |
|
140 |
return |
141 |
|
142 |
def save(self, fname, format): |
143 |
""" |
144 |
Save the scene to a file |
145 |
|
146 |
@param fname: The name of the file to save the scene to |
147 |
@type fname: string |
148 |
|
149 |
@param format: The format in which to save the scene |
150 |
@type format: Image object or string |
151 |
""" |
152 |
debugMsg("Called Scene.save()") |
153 |
|
154 |
if fname is None or fname == "": |
155 |
raise ValueError, "You must specify an output filename" |
156 |
|
157 |
if format is None or format == "": |
158 |
raise ValueError, "You must specify an image format" |
159 |
|
160 |
# now check the type of arguments sent in |
161 |
if __debug__: |
162 |
assert isinstance(fname, str), "Incorrect data type; expected str" |
163 |
assert isinstance(format, str), "Incorrect data type; expected str" |
164 |
|
165 |
# do a check to see if the file exists |
166 |
fileCheck(fname) |
167 |
|
168 |
# print a warning message if get to here |
169 |
overrideWarning("Scene.save") |
170 |
|
171 |
return |
172 |
|
173 |
write = save |
174 |
|
175 |
def setBackgroundColor(self, *color): |
176 |
""" |
177 |
Sets the background color of the Scene |
178 |
|
179 |
@param color: The color to set the background to. Can be RGB or CMYK |
180 |
@type color: tuple |
181 |
""" |
182 |
debugMsg("Called Scene.setBackgroundColor()") |
183 |
|
184 |
# print a warning message if get to here |
185 |
overrideWarning("Scene.setBackgroundColor") |
186 |
|
187 |
# pity this code doesn't work.... |
188 |
# need to check on the values given in the *color array. |
189 |
# if they're greater than 1, scale so that the largest is 1 |
190 |
#maxColor = None |
191 |
#for i in range(len(color)): |
192 |
#if color[i] > 1: |
193 |
#maxColor = color[i] |
194 |
#print maxColor |
195 |
|
196 |
## if a maximum colour is found, then scale the colours |
197 |
#if maxColor is not None: |
198 |
#for i in range(len(color)): |
199 |
#color[i] = color[i]/maxColor |
200 |
|
201 |
# if color is of length 3, then we have rgb |
202 |
# if length is 4 then cmyk |
203 |
# if length is 1 then greyscale |
204 |
# otherwise barf |
205 |
if len(color) == 3: |
206 |
# ok, using rgb |
207 |
# probably should use a Color object or something |
208 |
# this will do in the meantime |
209 |
pass |
210 |
else: |
211 |
raise ValueError, "Sorry, only RGB color is supported at present" |
212 |
|
213 |
return |
214 |
|
215 |
def getBackgroundColor(self): |
216 |
""" |
217 |
Gets the current background color setting of the Scene |
218 |
""" |
219 |
debugMsg("Called Scene.getBackgroundColor()") |
220 |
|
221 |
# print a warning message if get to here |
222 |
overrideWarning("Scene.getBackgroundColor") |
223 |
|
224 |
return |
225 |
|
226 |
def setSize(self, xSize, ySize): |
227 |
""" |
228 |
Sets the size of the scene. |
229 |
|
230 |
This size is effectively the renderer window size. |
231 |
|
232 |
@param xSize: the size to set the x dimension |
233 |
@type xSize: int |
234 |
|
235 |
@param ySize: the size to set the y dimension |
236 |
@type ySize: int |
237 |
""" |
238 |
debugMsg("Called Scene.setSize()") |
239 |
|
240 |
# make sure that the arguments are the right kind of thing |
241 |
if __debug__: |
242 |
assert isinstance(xSize, int), "Incorrect data type; expected int" |
243 |
assert isinstance(ySize, int), "Incorrect data type; expected int" |
244 |
|
245 |
self.xSize = xSize |
246 |
self.ySize = ySize |
247 |
|
248 |
return |
249 |
|
250 |
def getSize(self): |
251 |
""" |
252 |
Gets the current size of the scene |
253 |
|
254 |
This size is effectively the renderer window size. Returns a tuple |
255 |
of the x and y dimensions respectively, in pixel units(??). |
256 |
""" |
257 |
debugMsg("Called Scene.getSize()") |
258 |
|
259 |
return (self.xSize, self.ySize) |
260 |
|
261 |
def rendererCommand(self, command): |
262 |
""" |
263 |
Allows the user to run a low-level renderer-specific command directly |
264 |
|
265 |
@param command: The renderer command to run as a string |
266 |
@type command: string |
267 |
""" |
268 |
debugMsg("Called Scene.rendererCommand()") |
269 |
# check that we get a string as input |
270 |
if __debug__: |
271 |
assert isinstance(command, str), "Incorrect data type; expected str" |
272 |
|
273 |
evalString = "%s" % command |
274 |
self.renderer.runString(evalString) |
275 |
return |
276 |
|
277 |
# vim: expandtab shiftwidth=4: |