Merging r50049 through r50076 from trunk into soc-2011-tomato
[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 "scene.h"
32 #include "svm.h"
33 #include "osl.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         filter = new Filter();
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         shader_manager = ShaderManager::create(this);
56
57         if (device_info_.type == DEVICE_CPU)
58                 image_manager->set_extended_image_limits();
59 }
60
61 Scene::~Scene()
62 {
63         if(device) camera->device_free(device, &dscene);
64         delete camera;
65
66         if(device) filter->device_free(device, &dscene);
67         delete filter;
68
69         if(device) film->device_free(device, &dscene);
70         delete film;
71
72         if(device) background->device_free(device, &dscene);
73         delete background;
74
75         if(device) mesh_manager->device_free(device, &dscene);
76         delete mesh_manager;
77
78         if(device) object_manager->device_free(device, &dscene);
79         delete object_manager;
80
81         if(device) integrator->device_free(device, &dscene);
82         delete integrator;
83
84         if(device) shader_manager->device_free(device, &dscene);
85         delete shader_manager;
86
87         if(device) light_manager->device_free(device, &dscene);
88         delete light_manager;
89
90         foreach(Shader *s, shaders)
91                 delete s;
92         foreach(Mesh *m, meshes)
93                 delete m;
94         foreach(Object *o, objects)
95                 delete o;
96         foreach(Light *l, lights)
97                 delete l;
98
99         if(device) image_manager->device_free(device, &dscene);
100         delete image_manager;
101 }
102
103 void Scene::device_update(Device *device_, Progress& progress)
104 {
105         if(!device)
106                 device = device_;
107         
108         /* The order of updates is important, because there's dependencies between
109          * the different managers, using data computed by previous managers.
110          *
111          * - Background generates shader graph compiled by shader manager.
112          * - Image manager uploads images used by shaders.
113          * - Camera may be used for adapative subdivison.
114          * - Displacement shader must have all shader data available.
115          * - Light manager needs final mesh data to compute emission CDF.
116          */
117         
118         image_manager->set_pack_images(device->info.pack_images);
119
120         progress.set_status("Updating Background");
121         background->device_update(device, &dscene, this);
122
123         if(progress.get_cancel()) return;
124
125         progress.set_status("Updating Shaders");
126         shader_manager->device_update(device, &dscene, this, progress);
127
128         if(progress.get_cancel()) return;
129
130         progress.set_status("Updating Images");
131         image_manager->device_update(device, &dscene, progress);
132
133         if(progress.get_cancel()) return;
134
135         progress.set_status("Updating Camera");
136         camera->device_update(device, &dscene, this);
137
138         if(progress.get_cancel()) return;
139
140         progress.set_status("Updating Objects");
141         object_manager->device_update(device, &dscene, this, progress);
142
143         if(progress.get_cancel()) return;
144
145         progress.set_status("Updating Meshes");
146         mesh_manager->device_update(device, &dscene, this, progress);
147
148         if(progress.get_cancel()) return;
149
150         progress.set_status("Updating Lights");
151         light_manager->device_update(device, &dscene, this, progress);
152
153         if(progress.get_cancel()) return;
154
155         progress.set_status("Updating Filter");
156         filter->device_update(device, &dscene);
157
158         if(progress.get_cancel()) return;
159
160         progress.set_status("Updating Film");
161         film->device_update(device, &dscene);
162
163         if(progress.get_cancel()) return;
164
165         progress.set_status("Updating Integrator");
166         integrator->device_update(device, &dscene, this);
167
168         if(progress.get_cancel()) return;
169
170         progress.set_status("Updating Device", "Writing constant memory");
171         device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
172 }
173
174 Scene::MotionType Scene::need_motion()
175 {
176         if(integrator->motion_blur)
177                 return MOTION_BLUR;
178         else if(Pass::contains(film->passes, PASS_MOTION))
179                 return MOTION_PASS;
180         else
181                 return MOTION_NONE;
182 }
183
184 bool Scene::need_global_attribute(AttributeStandard std)
185 {
186         if(std == ATTR_STD_UV)
187                 return Pass::contains(film->passes, PASS_UV);
188         if(std == ATTR_STD_MOTION_PRE || ATTR_STD_MOTION_POST)
189                 return need_motion() == MOTION_PASS;
190         
191         return false;
192 }
193
194 void Scene::need_global_attributes(AttributeRequestSet& attributes)
195 {
196         for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
197                 if(need_global_attribute((AttributeStandard)std))
198                         attributes.add((AttributeStandard)std);
199 }
200
201 bool Scene::need_update()
202 {
203         return (need_reset() || film->need_update);
204 }
205
206 bool Scene::need_reset()
207 {
208         return (background->need_update
209                 || image_manager->need_update
210                 || camera->need_update
211                 || object_manager->need_update
212                 || mesh_manager->need_update
213                 || light_manager->need_update
214                 || filter->need_update
215                 || integrator->need_update
216                 || shader_manager->need_update);
217 }
218
219 CCL_NAMESPACE_END
220