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