[Bf-blender-cvs] [a915814] openvdb: Fix for undefined density slot when using OpenVDB nodes without connecting the density socket.

Lukas Tönne noreply at git.blender.org
Fri Jun 12 11:29:55 CEST 2015


Commit: a9158140f7967b0acde079f718ea9ea56fdf09ef
Author: Lukas Tönne
Date:   Fri Jun 12 11:27:05 2015 +0200
Branches: openvdb
https://developer.blender.org/rBa9158140f7967b0acde079f718ea9ea56fdf09ef

Fix for undefined density slot when using OpenVDB nodes without
connecting the density socket.

The density grid is used for the primary intersection tests, so it needs
to be identified among others. The slot index used before was not
initialized when the density node socket is not connected. Further and
invalid index (-1) is not recognized and leads to buffer underrun.

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

M	intern/cycles/kernel/kernel_volume.h
M	intern/cycles/render/openvdb.cpp
M	intern/cycles/render/openvdb.h

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

diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index 9924a38..cc958a0 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -216,7 +216,7 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg, PathState
 	bool has_vdb_volume = kernel_data.tables.num_volumes > 0;
 	float t1 = 0.0f;
 
-	if(has_vdb_volume && kg->float_volumes[vdb_index]->has_uniform_voxels()) {
+	if(has_vdb_volume && vdb_index >= 0 && kg->float_volumes[vdb_index]->has_uniform_voxels()) {
 		/* TODO(kevin): this call should be moved out of here, all it does is
 		 * checking if we have an intersection with the boundbox of the volumue
 		 * which in most cases corresponds to the boundbox of the object that has
@@ -615,7 +615,7 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
 	int vdb_index = kernel_data.tables.density_index;
 	bool has_vdb_volume = kernel_data.tables.num_volumes > 0;
 
-	if(has_vdb_volume && kg->float_volumes[vdb_index]->has_uniform_voxels()) {
+	if(has_vdb_volume && vdb_index >= 0 && kg->float_volumes[vdb_index]->has_uniform_voxels()) {
 		/* TODO(kevin): this call should be moved out of here, all it does is
 		 * checking if we have an intersection with the boundbox of the volumue
 		 * which in most cases corresponds to the boundbox of the object that has
diff --git a/intern/cycles/render/openvdb.cpp b/intern/cycles/render/openvdb.cpp
index 13d8722..0abf816 100644
--- a/intern/cycles/render/openvdb.cpp
+++ b/intern/cycles/render/openvdb.cpp
@@ -74,10 +74,6 @@ int VolumeManager::add_volume(const string& filename, const string& name, int sa
 			slot = add_openvdb_volume(filename, name, sampling, grid_type);
 		}
 
-		if(string_iequals(name, "density") || string_iequals(name, "density high")) {
-			density_index = slot;
-		}
-
 		add_grid_description(filename, name, sampling, slot);
 
 		need_update = true;
@@ -122,6 +118,24 @@ int VolumeManager::find_existing_slot(const string& filename, const string& name
 	return -1;
 }
 
+int VolumeManager::find_density_slot()
+{
+	/* first try finding a matching grid name */
+	for (size_t i = 0; i < current_grids.size(); ++i) {
+		GridDescription grid = current_grids[i];
+		
+		if (string_iequals(grid.name, "density") || string_iequals(grid.name, "density high"))
+			return (int)i;
+	}
+	
+	/* try using the first scalar float grid instead */
+	if (!float_volumes.empty()) {
+		return 0;
+	}
+	
+	return -1;
+}
+
 bool VolumeManager::is_openvdb_file(const string& filename) const
 {
 	return string_endswith(filename, ".vdb");
@@ -237,7 +251,7 @@ void VolumeManager::device_update(Device *device, DeviceScene *dscene, Scene *sc
 	}
 
 	dscene->data.tables.num_volumes = float_volumes.size() + float3_volumes.size();
-	dscene->data.tables.density_index = density_index;
+	dscene->data.tables.density_index = find_density_slot();
 
 	VLOG(1) << "Volume samplers allocate: __float_volume, " << float_volumes.size() * sizeof(float_volume) << " bytes";
 	VLOG(1) << "Volume samplers allocate: __float3_volume, " << float3_volumes.size() * sizeof(float3_volume) << " bytes";
diff --git a/intern/cycles/render/openvdb.h b/intern/cycles/render/openvdb.h
index bc658d5..2aa2162 100644
--- a/intern/cycles/render/openvdb.h
+++ b/intern/cycles/render/openvdb.h
@@ -56,13 +56,12 @@ public:
 	~VolumeManager();
 
 	int add_volume(const string& filename, const string& name, int sampling, int grid_type);
+	int find_density_slot();
 
 	void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
 	void device_free(Device *device, DeviceScene *dscene);
 
 	bool need_update;
-	/* index for the density field, the one that will be used for ray intersection */
-	int density_index;
 
 	vector<float_volume*> float_volumes;
 	vector<float3_volume*> float3_volumes;




More information about the Bf-blender-cvs mailing list