Merged changes in the trunk up to revision 54594.
[blender.git] / intern / cycles / render / scene.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include <stdlib.h>
20
21 #include "background.h"
22 #include "camera.h"
23 #include "device.h"
24 #include "film.h"
25 #include "filter.h"
26 #include "integrator.h"
27 #include "light.h"
28 #include "shader.h"
29 #include "mesh.h"
30 #include "object.h"
31 #include "particles.h"
32 #include "curves.h"
33 #include "scene.h"
34 #include "svm.h"
35 #include "osl.h"
36
37 #include "util_foreach.h"
38 #include "util_progress.h"
39
40 CCL_NAMESPACE_BEGIN
41
42 Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
43 : params(params_)
44 {
45         device = NULL;
46         memset(&dscene.data, 0, sizeof(dscene.data));
47
48         camera = new Camera();
49         filter = new Filter();
50         film = new Film();
51         background = new Background();
52         light_manager = new LightManager();
53         mesh_manager = new MeshManager();
54         object_manager = new ObjectManager();
55         integrator = new Integrator();
56         image_manager = new ImageManager();
57         particle_system_manager = new ParticleSystemManager();
58         curve_system_manager = new CurveSystemManager();
59
60         /* OSL only works on the CPU */
61         if(device_info_.type == DEVICE_CPU)
62                 shader_manager = ShaderManager::create(this, params.shadingsystem);
63         else
64                 shader_manager = ShaderManager::create(this, SceneParams::SVM);
65
66         if (device_info_.type == DEVICE_CPU)
67                 image_manager->set_extended_image_limits();
68 }
69
70 Scene::~Scene()
71 {
72         free_memory(true);
73 }
74
75 void Scene::free_memory(bool final)
76 {
77         foreach(Shader *s, shaders)
78                 delete s;
79         foreach(Mesh *m, meshes)
80                 delete m;
81         foreach(Object *o, objects)
82                 delete o;
83         foreach(Light *l, lights)
84                 delete l;
85         foreach(ParticleSystem *p, particle_systems)
86                 delete p;
87
88         shaders.clear();
89         meshes.clear();
90         objects.clear();
91         lights.clear();
92         particle_systems.clear();
93
94         if(device) {
95                 camera->device_free(device, &dscene);
96                 filter->device_free(device, &dscene);
97                 film->device_free(device, &dscene);
98                 background->device_free(device, &dscene);
99                 integrator->device_free(device, &dscene);
100
101                 object_manager->device_free(device, &dscene);
102                 mesh_manager->device_free(device, &dscene);
103                 shader_manager->device_free(device, &dscene);
104                 light_manager->device_free(device, &dscene);
105
106                 particle_system_manager->device_free(device, &dscene);
107                 curve_system_manager->device_free(device, &dscene);
108
109                 if(!params.persistent_data || final)
110                         image_manager->device_free(device, &dscene);
111         }
112
113         if(final) {
114                 delete filter;
115                 delete camera;
116                 delete film;
117                 delete background;
118                 delete integrator;
119                 delete object_manager;
120                 delete mesh_manager;
121                 delete shader_manager;
122                 delete light_manager;
123                 delete particle_system_manager;
124                 delete curve_system_manager;
125                 delete image_manager;
126         }
127 }
128
129 void Scene::device_update(Device *device_, Progress& progress)
130 {
131         if(!device)
132                 device = device_;
133         
134         /* The order of updates is important, because there's dependencies between
135          * the different managers, using data computed by previous managers.
136          *
137          * - Background generates shader graph compiled by shader manager.
138          * - Image manager uploads images used by shaders.
139          * - Camera may be used for adapative subdivison.
140          * - Displacement shader must have all shader data available.
141          * - Light manager needs final mesh data to compute emission CDF.
142          */
143         
144         image_manager->set_pack_images(device->info.pack_images);
145
146         progress.set_status("Updating Background");
147         background->device_update(device, &dscene, this);
148
149         if(progress.get_cancel()) return;
150
151         progress.set_status("Updating Shaders");
152         shader_manager->device_update(device, &dscene, this, progress);
153
154         if(progress.get_cancel()) return;
155
156         progress.set_status("Updating Images");
157         image_manager->device_update(device, &dscene, progress);
158
159         if(progress.get_cancel()) return;
160
161         progress.set_status("Updating Camera");
162         camera->device_update(device, &dscene, this);
163
164         if(progress.get_cancel()) return;
165
166         progress.set_status("Updating Objects");
167         object_manager->device_update(device, &dscene, this, progress);
168
169         if(progress.get_cancel()) return;
170
171         progress.set_status("Updating Hair Systems");
172         curve_system_manager->device_update(device, &dscene, this, progress);
173
174         if(progress.get_cancel()) return;
175
176         progress.set_status("Updating Meshes");
177         mesh_manager->device_update(device, &dscene, this, progress);
178
179         if(progress.get_cancel()) return;
180
181         progress.set_status("Updating Lights");
182         light_manager->device_update(device, &dscene, this, progress);
183
184         if(progress.get_cancel()) return;
185
186         progress.set_status("Updating Particle Systems");
187         particle_system_manager->device_update(device, &dscene, this, progress);
188
189         if(progress.get_cancel()) return;
190
191         progress.set_status("Updating Filter");
192         filter->device_update(device, &dscene);
193
194         if(progress.get_cancel()) return;
195
196         progress.set_status("Updating Film");
197         film->device_update(device, &dscene);
198
199         if(progress.get_cancel()) return;
200
201         progress.set_status("Updating Integrator");
202         integrator->device_update(device, &dscene, this);
203
204         if(progress.get_cancel()) return;
205
206         progress.set_status("Updating Device", "Writing constant memory");
207         device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
208 }
209
210 Scene::MotionType Scene::need_motion(bool advanced_shading)
211 {
212         if(integrator->motion_blur)
213                 return (advanced_shading)? MOTION_BLUR: MOTION_NONE;
214         else if(Pass::contains(film->passes, PASS_MOTION))
215                 return MOTION_PASS;
216         else
217                 return MOTION_NONE;
218 }
219
220 bool Scene::need_global_attribute(AttributeStandard std)
221 {
222         if(std == ATTR_STD_UV)
223                 return Pass::contains(film->passes, PASS_UV);
224         if(std == ATTR_STD_MOTION_PRE || ATTR_STD_MOTION_POST)
225                 return need_motion() == MOTION_PASS;
226         
227         return false;
228 }
229
230 void Scene::need_global_attributes(AttributeRequestSet& attributes)
231 {
232         for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
233                 if(need_global_attribute((AttributeStandard)std))
234                         attributes.add((AttributeStandard)std);
235 }
236
237 bool Scene::need_update()
238 {
239         return (need_reset() || film->need_update);
240 }
241
242 bool Scene::need_reset()
243 {
244         return (background->need_update
245                 || image_manager->need_update
246                 || camera->need_update
247                 || object_manager->need_update
248                 || mesh_manager->need_update
249                 || light_manager->need_update
250                 || filter->need_update
251                 || integrator->need_update
252                 || shader_manager->need_update
253                 || particle_system_manager->need_update
254                 || curve_system_manager->need_update);
255 }
256
257 void Scene::reset()
258 {
259         shader_manager->reset(this);
260         shader_manager->add_default(this);
261
262         /* ensure all objects are updated */
263         camera->tag_update();
264         filter->tag_update(this);
265         film->tag_update(this);
266         background->tag_update(this);
267         integrator->tag_update(this);
268 }
269
270 void Scene::device_free()
271 {
272         free_memory(false);
273 }
274
275 CCL_NAMESPACE_END
276