Merged changes in the trunk up to revision 52118.
[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 "scene.h"
33 #include "svm.h"
34 #include "osl.h"
35
36 #include "util_foreach.h"
37 #include "util_progress.h"
38
39 CCL_NAMESPACE_BEGIN
40
41 Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
42 : params(params_)
43 {
44         device = NULL;
45         memset(&dscene.data, 0, sizeof(dscene.data));
46
47         /* OSL only works on the CPU */
48         if(device_info_.type != DEVICE_CPU)
49                 params.shadingsystem = SceneParams::SVM;
50
51         camera = new Camera();
52         filter = new Filter();
53         film = new Film();
54         background = new Background();
55         light_manager = new LightManager();
56         mesh_manager = new MeshManager();
57         object_manager = new ObjectManager();
58         integrator = new Integrator();
59         image_manager = new ImageManager();
60         shader_manager = ShaderManager::create(this);
61         particle_system_manager = new ParticleSystemManager();
62
63         if (device_info_.type == DEVICE_CPU)
64                 image_manager->set_extended_image_limits();
65 }
66
67 Scene::~Scene()
68 {
69         free_memory(true);
70 }
71
72 void Scene::free_memory(bool final)
73 {
74         foreach(Shader *s, shaders)
75                 delete s;
76         foreach(Mesh *m, meshes)
77                 delete m;
78         foreach(Object *o, objects)
79                 delete o;
80         foreach(Light *l, lights)
81                 delete l;
82         foreach(ParticleSystem *p, particle_systems)
83                 delete p;
84
85         if(device) {
86                 camera->device_free(device, &dscene);
87                 filter->device_free(device, &dscene);
88                 film->device_free(device, &dscene);
89                 background->device_free(device, &dscene);
90                 integrator->device_free(device, &dscene);
91
92                 object_manager->device_free(device, &dscene);
93                 mesh_manager->device_free(device, &dscene);
94                 shader_manager->device_free(device, &dscene);
95                 light_manager->device_free(device, &dscene);
96
97                 particle_system_manager->device_free(device, &dscene);
98
99                 if(!params.persistent_images || final)
100                         image_manager->device_free(device, &dscene);
101         }
102
103         if(final) {
104                 delete filter;
105                 delete camera;
106                 delete film;
107                 delete background;
108                 delete integrator;
109                 delete object_manager;
110                 delete mesh_manager;
111                 delete shader_manager;
112                 delete light_manager;
113                 delete particle_system_manager;
114                 delete image_manager;
115         }
116         else {
117                 shaders.clear();
118                 meshes.clear();
119                 objects.clear();
120                 lights.clear();
121                 particle_systems.clear();
122         }
123 }
124
125 void Scene::device_update(Device *device_, Progress& progress)
126 {
127         if(!device)
128                 device = device_;
129         
130         /* The order of updates is important, because there's dependencies between
131          * the different managers, using data computed by previous managers.
132          *
133          * - Background generates shader graph compiled by shader manager.
134          * - Image manager uploads images used by shaders.
135          * - Camera may be used for adapative subdivison.
136          * - Displacement shader must have all shader data available.
137          * - Light manager needs final mesh data to compute emission CDF.
138          */
139         
140         image_manager->set_pack_images(device->info.pack_images);
141
142         progress.set_status("Updating Background");
143         background->device_update(device, &dscene, this);
144
145         if(progress.get_cancel()) return;
146
147         progress.set_status("Updating Shaders");
148         shader_manager->device_update(device, &dscene, this, progress);
149
150         if(progress.get_cancel()) return;
151
152         progress.set_status("Updating Images");
153         image_manager->device_update(device, &dscene, progress);
154
155         if(progress.get_cancel()) return;
156
157         progress.set_status("Updating Camera");
158         camera->device_update(device, &dscene, this);
159
160         if(progress.get_cancel()) return;
161
162         progress.set_status("Updating Objects");
163         object_manager->device_update(device, &dscene, this, progress);
164
165         if(progress.get_cancel()) return;
166
167         progress.set_status("Updating Meshes");
168         mesh_manager->device_update(device, &dscene, this, progress);
169
170         if(progress.get_cancel()) return;
171
172         progress.set_status("Updating Lights");
173         light_manager->device_update(device, &dscene, this, progress);
174
175         if(progress.get_cancel()) return;
176
177         progress.set_status("Updating Particle Systems");
178         particle_system_manager->device_update(device, &dscene, this, progress);
179
180         if(progress.get_cancel()) return;
181
182         progress.set_status("Updating Filter");
183         filter->device_update(device, &dscene);
184
185         if(progress.get_cancel()) return;
186
187         progress.set_status("Updating Film");
188         film->device_update(device, &dscene);
189
190         if(progress.get_cancel()) return;
191
192         progress.set_status("Updating Integrator");
193         integrator->device_update(device, &dscene, this);
194
195         if(progress.get_cancel()) return;
196
197         progress.set_status("Updating Device", "Writing constant memory");
198         device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
199 }
200
201 Scene::MotionType Scene::need_motion(bool advanced_shading)
202 {
203         if(integrator->motion_blur)
204                 return (advanced_shading)? MOTION_BLUR: MOTION_NONE;
205         else if(Pass::contains(film->passes, PASS_MOTION))
206                 return MOTION_PASS;
207         else
208                 return MOTION_NONE;
209 }
210
211 bool Scene::need_global_attribute(AttributeStandard std)
212 {
213         if(std == ATTR_STD_UV)
214                 return Pass::contains(film->passes, PASS_UV);
215         if(std == ATTR_STD_MOTION_PRE || ATTR_STD_MOTION_POST)
216                 return need_motion() == MOTION_PASS;
217         
218         return false;
219 }
220
221 void Scene::need_global_attributes(AttributeRequestSet& attributes)
222 {
223         for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
224                 if(need_global_attribute((AttributeStandard)std))
225                         attributes.add((AttributeStandard)std);
226 }
227
228 bool Scene::need_update()
229 {
230         return (need_reset() || film->need_update);
231 }
232
233 bool Scene::need_reset()
234 {
235         return (background->need_update
236                 || image_manager->need_update
237                 || camera->need_update
238                 || object_manager->need_update
239                 || mesh_manager->need_update
240                 || light_manager->need_update
241                 || filter->need_update
242                 || integrator->need_update
243                 || shader_manager->need_update
244                 || particle_system_manager->need_update);
245 }
246
247 void Scene::reset()
248 {
249         shader_manager->add_default(this);
250
251         /* ensure all objects are updated */
252         camera->tag_update();
253         filter->tag_update(this);
254         film->tag_update(this);
255         background->tag_update(this);
256         integrator->tag_update(this);
257 }
258
259 void Scene::device_free()
260 {
261         free_memory(false);
262 }
263
264 CCL_NAMESPACE_END
265