71f5a9dafed7a4454558847c71e3babbbc045d86
[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          * - Image manager uploads images used by shaders.
137          * - Camera may be used for adapative subdivison.
138          * - Displacement shader must have all shader data available.
139          * - Light manager needs lookup tables and final mesh data to compute emission CDF.
140          */
141         
142         image_manager->set_pack_images(device->info.pack_images);
143
144         progress.set_status("Updating Shaders");
145         shader_manager->device_update(device, &dscene, this, progress);
146
147         if(progress.get_cancel()) return;
148
149         progress.set_status("Updating Images");
150         image_manager->device_update(device, &dscene, progress);
151
152         if(progress.get_cancel()) return;
153
154         progress.set_status("Updating Background");
155         background->device_update(device, &dscene, this);
156
157         if(progress.get_cancel()) return;
158
159         progress.set_status("Updating Camera");
160         camera->device_update(device, &dscene, this);
161
162         if(progress.get_cancel()) return;
163
164         progress.set_status("Updating Objects");
165         object_manager->device_update(device, &dscene, this, progress);
166
167         if(progress.get_cancel()) return;
168
169         progress.set_status("Updating Hair Systems");
170         curve_system_manager->device_update(device, &dscene, this, progress);
171
172         if(progress.get_cancel()) return;
173
174         progress.set_status("Updating Film");
175         film->device_update(device, &dscene, this);
176
177         if(progress.get_cancel()) return;
178
179         progress.set_status("Updating Lookup Tables");
180         lookup_tables->device_update(device, &dscene);
181
182         if(progress.get_cancel()) return;
183
184         progress.set_status("Updating Meshes");
185         mesh_manager->device_update(device, &dscene, this, progress);
186
187         if(progress.get_cancel()) return;
188
189         progress.set_status("Updating Lights");
190         light_manager->device_update(device, &dscene, this, progress);
191
192         if(progress.get_cancel()) return;
193
194         progress.set_status("Updating Particle Systems");
195         particle_system_manager->device_update(device, &dscene, this, progress);
196
197         if(progress.get_cancel()) return;
198
199         progress.set_status("Updating Integrator");
200         integrator->device_update(device, &dscene, this);
201
202         if(progress.get_cancel()) return;
203
204         progress.set_status("Updating Device", "Writing constant memory");
205         device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
206 }
207
208 Scene::MotionType Scene::need_motion(bool advanced_shading)
209 {
210         if(integrator->motion_blur)
211                 return (advanced_shading)? MOTION_BLUR: MOTION_NONE;
212         else if(Pass::contains(film->passes, PASS_MOTION))
213                 return MOTION_PASS;
214         else
215                 return MOTION_NONE;
216 }
217
218 bool Scene::need_global_attribute(AttributeStandard std)
219 {
220         if(std == ATTR_STD_UV)
221                 return Pass::contains(film->passes, PASS_UV);
222         if(std == ATTR_STD_MOTION_PRE || std == ATTR_STD_MOTION_POST)
223                 return need_motion() == MOTION_PASS;
224         
225         return false;
226 }
227
228 void Scene::need_global_attributes(AttributeRequestSet& attributes)
229 {
230         for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
231                 if(need_global_attribute((AttributeStandard)std))
232                         attributes.add((AttributeStandard)std);
233 }
234
235 bool Scene::need_update()
236 {
237         return (need_reset() || film->need_update);
238 }
239
240 bool Scene::need_reset()
241 {
242         return (background->need_update
243                 || image_manager->need_update
244                 || camera->need_update
245                 || object_manager->need_update
246                 || mesh_manager->need_update
247                 || light_manager->need_update
248                 || lookup_tables->need_update
249                 || integrator->need_update
250                 || shader_manager->need_update
251                 || particle_system_manager->need_update
252                 || curve_system_manager->need_update);
253 }
254
255 void Scene::reset()
256 {
257         shader_manager->reset(this);
258         shader_manager->add_default(this);
259
260         /* ensure all objects are updated */
261         camera->tag_update();
262         film->tag_update(this);
263         background->tag_update(this);
264         integrator->tag_update(this);
265 }
266
267 void Scene::device_free()
268 {
269         free_memory(false);
270 }
271
272 CCL_NAMESPACE_END
273