Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2016-11-13 15:40:00 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2016-11-13 15:40:00 +0300
commit736e3cd434a5d45d398878bd826a210cf342b8b3 (patch)
treebfd53e4c744f2948e77acef2fc9e0b0ef0b42c18
parent3d04df097a6d338763ac20a7f3faa92212ea8466 (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.cpp4
-rw-r--r--intern/cycles/blender/blender_sync.cpp6
-rw-r--r--intern/cycles/blender/blender_sync.h2
-rw-r--r--intern/cycles/blender/blender_util.h20
-rw-r--r--intern/cycles/blender/blender_volume.cpp33
-rw-r--r--intern/cycles/render/scene.h2
-rw-r--r--intern/cycles/render/volume.cpp14
-rw-r--r--intern/cycles/render/volume.h4
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;