Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "background.h" 00020 #include "film.h" 00021 #include "../render/filter.h" 00022 #include "graph.h" 00023 #include "integrator.h" 00024 #include "light.h" 00025 #include "mesh.h" 00026 #include "nodes.h" 00027 #include "object.h" 00028 #include "scene.h" 00029 #include "shader.h" 00030 00031 #include "device.h" 00032 00033 #include "blender_sync.h" 00034 #include "blender_util.h" 00035 00036 #include "util_debug.h" 00037 #include "util_foreach.h" 00038 00039 CCL_NAMESPACE_BEGIN 00040 00041 /* Constructor */ 00042 00043 BlenderSync::BlenderSync(BL::BlendData b_data_, BL::Scene b_scene_, Scene *scene_, bool preview_) 00044 : b_data(b_data_), b_scene(b_scene_), 00045 shader_map(&scene_->shaders), 00046 object_map(&scene_->objects), 00047 mesh_map(&scene_->meshes), 00048 light_map(&scene_->lights), 00049 world_map(NULL), 00050 world_recalc(false), 00051 experimental(false), 00052 active_layer(0) 00053 { 00054 scene = scene_; 00055 preview = preview_; 00056 } 00057 00058 BlenderSync::~BlenderSync() 00059 { 00060 } 00061 00062 /* Sync */ 00063 00064 bool BlenderSync::sync_recalc() 00065 { 00066 /* sync recalc flags from blender to cycles. actual update is done separate, 00067 so we can do it later on if doing it immediate is not suitable */ 00068 00069 BL::BlendData::materials_iterator b_mat; 00070 00071 for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) 00072 if(b_mat->is_updated() || (b_mat->node_tree() && b_mat->node_tree().is_updated())) 00073 shader_map.set_recalc(*b_mat); 00074 00075 BL::BlendData::lamps_iterator b_lamp; 00076 00077 for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) 00078 if(b_lamp->is_updated() || (b_lamp->node_tree() && b_lamp->node_tree().is_updated())) 00079 shader_map.set_recalc(*b_lamp); 00080 00081 BL::BlendData::objects_iterator b_ob; 00082 00083 for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) { 00084 if(b_ob->is_updated()) { 00085 object_map.set_recalc(*b_ob); 00086 light_map.set_recalc(*b_ob); 00087 } 00088 00089 if(object_is_mesh(*b_ob)) { 00090 if(b_ob->is_updated_data() || b_ob->data().is_updated()) { 00091 BL::ID key = object_is_modified(*b_ob)? *b_ob: b_ob->data(); 00092 mesh_map.set_recalc(key); 00093 } 00094 } 00095 else if(object_is_light(*b_ob)) { 00096 if(b_ob->is_updated_data() || b_ob->data().is_updated()) 00097 light_map.set_recalc(*b_ob); 00098 } 00099 } 00100 00101 BL::BlendData::meshes_iterator b_mesh; 00102 00103 for(b_data.meshes.begin(b_mesh); b_mesh != b_data.meshes.end(); ++b_mesh) 00104 if(b_mesh->is_updated()) 00105 mesh_map.set_recalc(*b_mesh); 00106 00107 BL::BlendData::worlds_iterator b_world; 00108 00109 for(b_data.worlds.begin(b_world); b_world != b_data.worlds.end(); ++b_world) 00110 if(world_map == b_world->ptr.data && 00111 (b_world->is_updated() || (b_world->node_tree() && b_world->node_tree().is_updated()))) 00112 world_recalc = true; 00113 00114 bool recalc = 00115 shader_map.has_recalc() || 00116 object_map.has_recalc() || 00117 light_map.has_recalc() || 00118 mesh_map.has_recalc() || 00119 BlendDataObjects_is_updated_get(&b_data.ptr) || 00120 world_recalc; 00121 00122 return recalc; 00123 } 00124 00125 void BlenderSync::sync_data(BL::SpaceView3D b_v3d, int layer) 00126 { 00127 sync_render_layers(b_v3d); 00128 sync_integrator(layer); 00129 sync_film(); 00130 sync_shaders(); 00131 sync_objects(b_v3d); 00132 } 00133 00134 /* Integrator */ 00135 00136 void BlenderSync::sync_integrator(int layer) 00137 { 00138 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); 00139 00140 experimental = (RNA_enum_get(&cscene, "feature_set") != 0); 00141 00142 Integrator *integrator = scene->integrator; 00143 Integrator previntegrator = *integrator; 00144 00145 integrator->min_bounce = get_int(cscene, "min_bounces"); 00146 integrator->max_bounce = get_int(cscene, "max_bounces"); 00147 00148 integrator->max_diffuse_bounce = get_int(cscene, "diffuse_bounces"); 00149 integrator->max_glossy_bounce = get_int(cscene, "glossy_bounces"); 00150 integrator->max_transmission_bounce = get_int(cscene, "transmission_bounces"); 00151 00152 integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces"); 00153 integrator->transparent_min_bounce = get_int(cscene, "transparent_min_bounces"); 00154 integrator->transparent_shadows = get_boolean(cscene, "use_transparent_shadows"); 00155 00156 integrator->no_caustics = get_boolean(cscene, "no_caustics"); 00157 integrator->seed = get_int(cscene, "seed"); 00158 integrator->layer_flag = render_layers[layer].layer; 00159 00160 if(integrator->modified(previntegrator)) 00161 integrator->tag_update(scene); 00162 } 00163 00164 /* Film */ 00165 00166 void BlenderSync::sync_film() 00167 { 00168 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); 00169 00170 Film *film = scene->film; 00171 Film prevfilm = *film; 00172 00173 film->exposure = get_float(cscene, "film_exposure"); 00174 00175 if(film->modified(prevfilm)) 00176 film->tag_update(scene); 00177 00178 Filter *filter = scene->filter; 00179 Filter prevfilter = *filter; 00180 00181 filter->filter_type = (FilterType)RNA_enum_get(&cscene, "filter_type"); 00182 filter->filter_width = (filter->filter_type == FILTER_BOX)? 1.0f: get_float(cscene, "filter_width"); 00183 00184 if(filter->modified(prevfilter)) 00185 filter->tag_update(scene); 00186 } 00187 00188 /* Render Layer */ 00189 00190 void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d) 00191 { 00192 render_layers.clear(); 00193 00194 if(b_v3d) { 00195 RenderLayerInfo rlay; 00196 00197 rlay.scene_layer = get_layer(b_v3d.layers()); 00198 rlay.layer = rlay.scene_layer; 00199 rlay.material_override = PointerRNA_NULL; 00200 00201 render_layers.push_back(rlay); 00202 } 00203 else { 00204 BL::RenderSettings r = b_scene.render(); 00205 BL::RenderSettings::layers_iterator b_rlay; 00206 00207 for(r.layers.begin(b_rlay); b_rlay != r.layers.end(); ++b_rlay) { 00208 /* single layer for now */ 00209 RenderLayerInfo rlay; 00210 00211 rlay.scene_layer = get_layer(b_scene.layers()); 00212 rlay.layer = get_layer(b_rlay->layers()); 00213 rlay.material_override = b_rlay->material_override(); 00214 00215 render_layers.push_back(rlay); 00216 } 00217 } 00218 } 00219 00220 /* Scene Parameters */ 00221 00222 SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background) 00223 { 00224 SceneParams params; 00225 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); 00226 int shadingsystem = RNA_enum_get(&cscene, "shading_system"); 00227 00228 if(shadingsystem == 0) 00229 params.shadingsystem = SceneParams::SVM; 00230 else if(shadingsystem == 1) 00231 params.shadingsystem = SceneParams::OSL; 00232 00233 if(background) 00234 params.bvh_type = SceneParams::BVH_STATIC; 00235 else 00236 params.bvh_type = (SceneParams::BVHType)RNA_enum_get(&cscene, "debug_bvh_type"); 00237 00238 params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits"); 00239 params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false; 00240 00241 return params; 00242 } 00243 00244 /* Session Parameters */ 00245 00246 bool BlenderSync::get_session_pause(BL::Scene b_scene, bool background) 00247 { 00248 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); 00249 return (background)? false: get_boolean(cscene, "preview_pause"); 00250 } 00251 00252 SessionParams BlenderSync::get_session_params(BL::UserPreferences b_userpref, BL::Scene b_scene, bool background) 00253 { 00254 SessionParams params; 00255 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); 00256 00257 /* feature set */ 00258 params.experimental = (RNA_enum_get(&cscene, "feature_set") != 0); 00259 00260 /* device type */ 00261 vector<DeviceInfo>& devices = Device::available_devices(); 00262 00263 /* device default CPU */ 00264 params.device = devices[0]; 00265 00266 if(RNA_enum_get(&cscene, "device") != 0) { 00267 /* find GPU device with given id */ 00268 PointerRNA systemptr = b_userpref.system().ptr; 00269 PropertyRNA *deviceprop = RNA_struct_find_property(&systemptr, "compute_device"); 00270 int device_id = b_userpref.system().compute_device(); 00271 00272 const char *id; 00273 00274 if(RNA_property_enum_identifier(NULL, &systemptr, deviceprop, device_id, &id)) { 00275 foreach(DeviceInfo& info, devices) 00276 if(info.id == id) 00277 params.device = info; 00278 } 00279 } 00280 00281 /* Background */ 00282 params.background = background; 00283 00284 /* samples */ 00285 if(background) { 00286 params.samples = get_int(cscene, "samples"); 00287 } 00288 else { 00289 params.samples = get_int(cscene, "preview_samples"); 00290 if(params.samples == 0) 00291 params.samples = INT_MAX; 00292 } 00293 00294 /* other parameters */ 00295 params.threads = b_scene.render().threads(); 00296 params.tile_size = get_int(cscene, "debug_tile_size"); 00297 params.min_size = get_int(cscene, "debug_min_size"); 00298 params.cancel_timeout = get_float(cscene, "debug_cancel_timeout"); 00299 params.reset_timeout = get_float(cscene, "debug_reset_timeout"); 00300 params.text_timeout = get_float(cscene, "debug_text_timeout"); 00301 00302 if(background) { 00303 params.progressive = true; 00304 params.min_size = INT_MAX; 00305 } 00306 else 00307 params.progressive = true; 00308 00309 /* todo: multi device only works with single tiles now */ 00310 if(params.device.type == DEVICE_MULTI) 00311 params.tile_size = INT_MAX; 00312 00313 return params; 00314 } 00315 00316 CCL_NAMESPACE_END 00317