Blender V2.61 - r43446

blender_sync.cpp

Go to the documentation of this file.
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