[Bf-blender-cvs] [736e3cd] openvdb: Proper volume data storage in Cycles when syncing from Blender data.

Lukas Tönne noreply at git.blender.org
Sun Nov 13 21:44:51 CET 2016


Commit: 736e3cd434a5d45d398878bd826a210cf342b8b3
Author: Lukas Tönne
Date:   Sun Nov 13 13:40:00 2016 +0100
Branches: openvdb
https://developer.blender.org/rB736e3cd434a5d45d398878bd826a210cf342b8b3

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.

===================================================================

M	intern/cycles/blender/blender_object.cpp
M	intern/cycles/blender/blender_sync.cpp
M	intern/cycles/blender/blender_sync.h
M	intern/cycles/blender/blender_util.h
M	intern/cycles/blender/blender_volume.cpp
M	intern/cycles/render/scene.h
M	intern/cycles/render/volume.cpp
M	intern/cycles/render/volume.h

===================================================================

diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 02ca24e..cf81c22 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 4ca202a..f99a488 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 af8a1b4..812c519 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 f17a61f..c729f5f 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 3f55d45..5c25668 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 b55240a..e631e7a 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 473d4a1..47c9e91 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 771aae2..5378965 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;




More information about the Bf-blender-cvs mailing list