Fix T39114: cycles lamp ray visibility not working.
[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          * - Film needs light manager to run for use_light_visibility
141          * - Lookup tables are done a second time to handle film tables
142          */
143         
144         image_manager->set_pack_images(device->info.pack_images);
145
146         progress.set_status("Updating Shaders");
147         shader_manager->device_update(device, &dscene, this, progress);
148
149         if(progress.get_cancel()) return;
150
151         progress.set_status("Updating Images");
152         image_manager->device_update(device, &dscene, progress);
153
154         if(progress.get_cancel()) return;
155
156         progress.set_status("Updating Background");
157         background->device_update(device, &dscene, this);
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 Lookup Tables");
177         lookup_tables->device_update(device, &dscene);
178
179         if(progress.get_cancel()) return;
180
181         progress.set_status("Updating Meshes");
182         mesh_manager->device_update(device, &dscene, this, progress);
183
184         if(progress.get_cancel()) return;
185
186         progress.set_status("Updating Lights");
187         light_manager->device_update(device, &dscene, this, progress);
188
189         if(progress.get_cancel()) return;
190
191         progress.set_status("Updating Particle Systems");
192         particle_system_manager->device_update(device, &dscene, this, progress);
193
194         if(progress.get_cancel()) return;
195
196         progress.set_status("Updating Film");
197         film->device_update(device, &dscene, this);
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 Lookup Tables");
207         lookup_tables->device_update(device, &dscene);
208
209         if(progress.get_cancel()) return;
210
211         progress.set_status("Updating Device", "Writing constant memory");
212         device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
213 }
214
215 Scene::MotionType Scene::need_motion(bool advanced_shading)
216 {
217         if(integrator->motion_blur)
218                 return (advanced_shading)? MOTION_BLUR: MOTION_NONE;
219         else if(Pass::contains(film->passes, PASS_MOTION))
220                 return MOTION_PASS;
221         else
222                 return MOTION_NONE;
223 }
224
225 bool Scene::need_global_attribute(AttributeStandard std)
226 {
227         if(std == ATTR_STD_UV)
228                 return Pass::contains(film->passes, PASS_UV);
229         if(std == ATTR_STD_MOTION_PRE || std == ATTR_STD_MOTION_POST)
230                 return need_motion() == MOTION_PASS;
231         
232         return false;
233 }
234
235 void Scene::need_global_attributes(AttributeRequestSet& attributes)
236 {
237         for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
238                 if(need_global_attribute((AttributeStandard)std))
239                         attributes.add((AttributeStandard)std);
240 }
241
242 bool Scene::need_update()
243 {
244         return (need_reset() || film->need_update);
245 }
246
247 bool Scene::need_reset()
248 {
249         return (background->need_update
250                 || image_manager->need_update
251                 || camera->need_update
252                 || object_manager->need_update
253                 || mesh_manager->need_update
254                 || light_manager->need_update
255                 || lookup_tables->need_update
256                 || integrator->need_update
257                 || shader_manager->need_update
258                 || particle_system_manager->need_update
259                 || curve_system_manager->need_update);
260 }
261
262 void Scene::reset()
263 {
264         shader_manager->reset(this);
265         shader_manager->add_default(this);
266
267         /* ensure all objects are updated */
268         camera->tag_update();
269         film->tag_update(this);
270         background->tag_update(this);
271         integrator->tag_update(this);
272 }
273
274 void Scene::device_free()
275 {
276         free_memory(false);
277 }
278
279 CCL_NAMESPACE_END
280