diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2016-11-13 15:40:00 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2016-11-13 15:40:00 +0300 |
commit | 736e3cd434a5d45d398878bd826a210cf342b8b3 (patch) | |
tree | bfd53e4c744f2948e77acef2fc9e0b0ef0b42c18 | |
parent | 3d04df097a6d338763ac20a7f3faa92212ea8466 (diff) |
Proper volume data storage in Cycles when syncing from Blender data.
Previously a viewport render would continuously keep adding Volume instances
to the VolumeManager data, because there was no way to detect existing volume
data. Now the `id_map` model known from meshes and other data types is used for
volume data as well.
Note that the VolumeKey currently simply uses an Object ID pointer, thus
assuming a single Volume per object. In the future volumes could become a
real ID type in Blender, or the specific volume could be narrowed down with
additional info in the key.
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 2 | ||||
-rw-r--r-- | intern/cycles/blender/blender_util.h | 20 | ||||
-rw-r--r-- | intern/cycles/blender/blender_volume.cpp | 33 | ||||
-rw-r--r-- | intern/cycles/render/scene.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/volume.cpp | 14 | ||||
-rw-r--r-- | intern/cycles/render/volume.h | 4 |
8 files changed, 82 insertions, 3 deletions
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 02ca24ede8b..cf81c22a856 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -24,6 +24,7 @@ #include "nodes.h" #include "particles.h" #include "shader.h" +#include "volume.h" #include "blender_sync.h" #include "blender_util.h" @@ -575,6 +576,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) mesh_map.pre_sync(); object_map.pre_sync(); particle_system_map.pre_sync(); + volume_map.pre_sync(); motion_times.clear(); } else { @@ -709,6 +711,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) scene->object_manager->tag_update(scene); if(particle_system_map.post_sync()) scene->particle_system_manager->tag_update(scene); + if(volume_map.post_sync()) + scene->volume_manager->tag_update(scene); } if(motion) diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 4ca202ac40d..f99a4889d34 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -57,6 +57,7 @@ BlenderSync::BlenderSync(BL::RenderEngine& b_engine, mesh_map(&scene->meshes), light_map(&scene->lights), particle_system_map(&scene->particle_systems), + volume_map(&scene->volumes), world_map(NULL), world_recalc(false), scene(scene), @@ -150,6 +151,10 @@ bool BlenderSync::sync_recalc() for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) particle_system_map.set_recalc(*b_ob); } + + if(b_ob->is_updated()) { + volume_map.set_recalc(*b_ob); + } } BL::BlendData::meshes_iterator b_mesh; @@ -184,6 +189,7 @@ bool BlenderSync::sync_recalc() light_map.has_recalc() || mesh_map.has_recalc() || particle_system_map.has_recalc() || + volume_map.has_recalc() || BlendDataObjects_is_updated_get(&b_data.ptr) || world_recalc; diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index af8a1b48abe..812c5199b09 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -166,8 +166,10 @@ private: id_map<void*, Mesh> mesh_map; id_map<ObjectKey, Light> light_map; id_map<ParticleSystemKey, ParticleSystem> particle_system_map; + id_map<VolumeKey, Volume> volume_map; set<Mesh*> mesh_synced; set<Mesh*> mesh_motion_synced; + set<Volume*> volume_synced; set<float> motion_times; void *world_map; bool world_recalc; diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index f17a61f0ac8..c729f5f2a35 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -781,6 +781,26 @@ struct ParticleSystemKey { } }; +/* Volume Key */ + +/* XXX For now we just use Object ID as a volume key; + * Volumes may become a true ID block in Blender later, + * or the key can be augmented to distinguish multiple volumes inside the same object. + */ +struct VolumeKey { + void *ob; + + VolumeKey(void *ob_) + : ob(ob_) + { + } + + bool operator<(const VolumeKey& k) const + { + return ob < k.ob; + } +}; + CCL_NAMESPACE_END #endif /* __BLENDER_UTIL_H__ */ diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp index 3f55d4548ae..5c25668db6b 100644 --- a/intern/cycles/blender/blender_volume.cpp +++ b/intern/cycles/blender/blender_volume.cpp @@ -128,6 +128,7 @@ static void create_volume_attributes(Scene *scene, Volume *BlenderSync::sync_volume(BL::Object &b_ob) { + BL::ID key = b_ob; BL::Material material_override = render_layer.material_override; /* find shader indices */ @@ -156,7 +157,32 @@ Volume *BlenderSync::sync_volume(BL::Object &b_ob) fprintf(stderr, "%s: after material assignment\n", __func__); - Volume *volume = new Volume; + Volume *volume; + + if(!volume_map.sync(&volume, key)) { + /* test if shaders changed, these can be object level so mesh + * does not get tagged for recalc */ + if(volume->used_shaders != used_shaders); + else { + /* even if not tagged for recalc, we may need to sync anyway + * because the shader needs different volume attributes */ + bool attribute_recalc = false; + + foreach(Shader *shader, volume->used_shaders) + if(shader->need_update_attributes) + attribute_recalc = true; + + if(!attribute_recalc) + return volume; + } + } + + /* ensure we only sync instanced meshes once */ + if(volume_synced.find(volume) != volume_synced.end()) + return volume; + + volume_synced.insert(volume); + volume->used_shaders = used_shaders; volume->name = ustring(b_ob_data.name().c_str()); @@ -164,6 +190,11 @@ Volume *BlenderSync::sync_volume(BL::Object &b_ob) create_volume_attributes(scene, b_ob, volume, b_scene.frame_current()); + /* tag update */ + bool rebuild = false; + + volume->tag_update(scene, rebuild); + return volume; } diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index b55240aabe0..e631e7a1360 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -54,6 +54,7 @@ class ShaderManager; class Progress; class BakeManager; class BakeData; +class Volume; class VolumeManager; /* Scene Device Data */ @@ -186,6 +187,7 @@ public: vector<Shader*> shaders; vector<Light*> lights; vector<ParticleSystem*> particle_systems; + vector<Volume*> volumes; /* data managers */ ImageManager *image_manager; diff --git a/intern/cycles/render/volume.cpp b/intern/cycles/render/volume.cpp index 473d4a191ee..47c9e915180 100644 --- a/intern/cycles/render/volume.cpp +++ b/intern/cycles/render/volume.cpp @@ -28,6 +28,13 @@ CCL_NAMESPACE_BEGIN #define MAX_VOLUME 1024 +void Volume::tag_update(Scene *scene, bool /*rebuild*/) +{ + scene->volume_manager->need_update = true; +} + +/* ------------------------------------------------------------------------- */ + VolumeManager::VolumeManager() { #ifdef WITH_OPENVDB @@ -116,11 +123,9 @@ int VolumeManager::add_volume(Volume *volume, const std::string &filename, const add_grid_description(volume, filename, name, slot); volumes.push_back(volume); - need_update = true; } catch(...) { catch_exceptions(); - need_update = false; slot = -1; } @@ -509,4 +514,9 @@ void VolumeManager::device_free(Device */*device*/, DeviceScene */*dscene*/) { } +void VolumeManager::tag_update(Scene */*scene*/) +{ + need_update = true; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/volume.h b/intern/cycles/render/volume.h index 771aae270e1..537896591fd 100644 --- a/intern/cycles/render/volume.h +++ b/intern/cycles/render/volume.h @@ -47,6 +47,8 @@ public: vector<openvdb::FloatGrid::Ptr> scalar_grids; vector<openvdb::Vec3SGrid::Ptr> vector_grids; #endif + + void tag_update(Scene *scene, bool rebuild); }; class VolumeManager { @@ -94,6 +96,8 @@ public: void update_svm_attributes(Device *device, DeviceScene *dscene, Scene *scene, vector<AttributeRequestSet>& mesh_attributes); void device_free(Device *device, DeviceScene *dscene); + void tag_update(Scene *scene); + bool need_update; vector<Volume*> volumes; |