[Bf-blender-cvs] [e656d07] openvdb: Implementation of VDB ray intersectors.

Kévin Dietrich noreply at git.blender.org
Fri Jun 5 14:07:33 CEST 2015


Commit: e656d07cbc6402918a92ec83d6c15ef4af02e849
Author: Kévin Dietrich
Date:   Sat May 23 02:17:48 2015 +0200
Branches: openvdb
https://developer.blender.org/rBe656d07cbc6402918a92ec83d6c15ef4af02e849

Implementation of VDB ray intersectors.

They are not used yet though.

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

M	intern/cycles/util/util_openvdb.h

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

diff --git a/intern/cycles/util/util_openvdb.h b/intern/cycles/util/util_openvdb.h
index 3ae2a3d..fb8a5f8 100644
--- a/intern/cycles/util/util_openvdb.h
+++ b/intern/cycles/util/util_openvdb.h
@@ -4,23 +4,32 @@
 #include "util_map.h"
 #include "util_types.h"
 
+#include "kernel_types.h"
+
 CCL_NAMESPACE_BEGIN
 
+struct Ray;
+struct Intersection;
+
 enum {
 	OPENVDB_SAMPLE_POINT = 0,
 	OPENVDB_SAMPLE_BOX   = 1,
 };
 
-class float_volume_sampler {
+class float_volume {
 public:
-	virtual ~float_volume_sampler() {}
+	virtual ~float_volume() {}
 	virtual float sample(int sampling, float3 co) = 0;
+	virtual bool intersect(const Ray *ray, Intersection *isect) = 0;
+	virtual bool march(float *t0, float *t1) = 0;
 };
 
-class float3_volume_sampler {
+class float3_volume {
 public:
-	virtual ~float3_volume_sampler() {}
+	virtual ~float3_volume() {}
 	virtual float3 sample(int sampling, float3 co) = 0;
+	virtual bool intersect(const Ray *ray, Intersection *isect) = 0;
+	virtual bool march(float *t0, float *t1) = 0;
 };
 
 CCL_NAMESPACE_END
@@ -29,6 +38,7 @@ CCL_NAMESPACE_END
 
 #include <openvdb/openvdb.h>
 #include <openvdb/tools/Interpolation.h>
+#include <openvdb/tools/RayIntersector.h>
 
 CCL_NAMESPACE_BEGIN
 
@@ -38,32 +48,50 @@ using std::isfinite;
 using boost::math::isfinite;
 #endif
 
-typedef openvdb::tools::GridSampler<openvdb::FloatGrid::ConstAccessor, openvdb::tools::PointSampler> vdb_fsampler_p;
-typedef openvdb::tools::GridSampler<openvdb::FloatGrid::ConstAccessor, openvdb::tools::BoxSampler> vdb_fsampler_b;
-typedef openvdb::tools::GridSampler<openvdb::Vec3SGrid::ConstAccessor, openvdb::tools::PointSampler> vdb_vsampler_p;
-typedef openvdb::tools::GridSampler<openvdb::Vec3SGrid::ConstAccessor, openvdb::tools::BoxSampler> vdb_vsampler_b;
+class vdb_float_volume : public float_volume {
+	typedef openvdb::tools::GridSampler<openvdb::FloatGrid::ConstAccessor, openvdb::tools::PointSampler> point_sampler_t;
+	typedef openvdb::tools::GridSampler<openvdb::FloatGrid::ConstAccessor, openvdb::tools::BoxSampler> box_sampler_t;
+	point_sampler_t *point_sampler;
+	box_sampler_t *box_sampler;
 
-class vdb_float_sampler : public float_volume_sampler {
-	vdb_fsampler_p *point_sampler;
-	vdb_fsampler_b *box_sampler;
+	typedef openvdb::tools::VolumeRayIntersector<openvdb::FloatGrid> isector_t;
+	typedef isector_t::RayType vdb_ray_t;
 
 	/* mainly used to ensure thread safety for the accessors */
-	typedef unordered_map<pthread_t, vdb_fsampler_p *> point_map;
-	typedef unordered_map<pthread_t, vdb_fsampler_b *> box_map;
+	typedef unordered_map<pthread_t, isector_t *> isect_map;
+	typedef unordered_map<pthread_t, point_sampler_t *> point_map;
+	typedef unordered_map<pthread_t, box_sampler_t *> box_map;
+	isect_map isectors;
 	point_map point_samplers;
 	box_map box_samplers;
 
 	openvdb::FloatGrid::ConstAccessor *accessor;
 
+	/* Main intersector, its purpose is to initialize the voxels' bounding box
+	 * so the ones for the various threads do not do this, rather they are
+	 * generated from of copy of it */
+	isector_t *main_isector;
+
+	bool uniform_voxels;
+
 public:
-	vdb_float_sampler(openvdb::FloatGrid::Ptr grid)
+	vdb_float_volume(openvdb::FloatGrid::Ptr grid)
 	{
 		accessor = new openvdb::FloatGrid::ConstAccessor(grid->getConstAccessor());
-		point_sampler = new vdb_fsampler_p(*accessor, grid->transform());
-		box_sampler = new vdb_fsampler_b(*accessor, grid->transform());
+		point_sampler = new point_sampler_t(*accessor, grid->transform());
+		box_sampler = new box_sampler_t(*accessor, grid->transform());
+
+		/* only grids with uniform voxels can be used with VolumeRayIntersector */
+		if(grid->hasUniformVoxels()) {
+			uniform_voxels = true;
+			main_isector = new isector_t(*grid);
+		}
+		else {
+			uniform_voxels = false;
+		}
 	}
 
-	~vdb_float_sampler()
+	~vdb_float_volume()
 	{
 		delete point_sampler;
 		delete box_sampler;
@@ -75,12 +103,12 @@ public:
 
 		if(sampling == OPENVDB_SAMPLE_POINT) {
 			point_map::iterator iter = point_samplers.find(thread);
-			vdb_fsampler_p *sampler;
+			point_sampler_t *sampler;
 
 			if(iter == point_samplers.end()) {
 				openvdb::FloatGrid::ConstAccessor *acc = new openvdb::FloatGrid::ConstAccessor(*accessor);
-				sampler = new vdb_fsampler_p(*acc, point_sampler->transform());
-				pair<pthread_t, vdb_fsampler_p *> sampl(thread, sampler);
+				sampler = new point_sampler_t(*acc, point_sampler->transform());
+				pair<pthread_t, point_sampler_t *> sampl(thread, sampler);
 				point_samplers.insert(sampl);
 			}
 			else {
@@ -91,12 +119,12 @@ public:
 		}
 		else {
 			box_map::iterator iter = box_samplers.find(thread);
-			vdb_fsampler_b *sampler;
+			box_sampler_t *sampler;
 
 			if(iter == box_samplers.end()) {
 				openvdb::FloatGrid::ConstAccessor *acc = new openvdb::FloatGrid::ConstAccessor(*accessor);
-				sampler = new vdb_fsampler_b(*acc, box_sampler->transform());
-				pair<pthread_t, vdb_fsampler_b *> sampl(thread, sampler);
+				sampler = new box_sampler_t(*acc, box_sampler->transform());
+				pair<pthread_t, box_sampler_t *> sampl(thread, sampler);
 				box_samplers.insert(sampl);
 			}
 			else {
@@ -106,28 +134,126 @@ public:
 			return sampler->wsSample(openvdb::Vec3d(co.x, co.y, co.z));
 		}
 	}
+
+	ccl_always_inline bool intersect(const Ray *ray, Intersection */*isect*/)
+	{
+		if(!uniform_voxels) {
+			return false;
+		}
+
+		pthread_t thread = pthread_self();
+		isect_map::iterator iter = isectors.find(thread);
+		isector_t *vdb_isect;
+
+		if(iter == isectors.end()) {
+			vdb_isect = new isector_t(*main_isector);
+			pair<pthread_t, isector_t *> inter(thread, vdb_isect);
+			isectors.insert(inter);
+		}
+		else {
+			vdb_isect = iter->second;
+		}
+
+		vdb_ray_t::Vec3Type P(ray->P.x, ray->P.y, ray->P.z);
+		vdb_ray_t::Vec3Type D(ray->D.x, ray->D.y, ray->D.z);
+		D.normalize();
+
+		vdb_ray_t vdb_ray(P, D, 1e-5f, ray->t);
+
+		if(vdb_isect->setWorldRay(vdb_ray)) {
+			// TODO
+//			isect->t = t;
+//			isect->u = isect->v = 1.0f;
+//			isect->type = ;
+//			isect->shad = shader;
+//			isect->norm = ;
+//			isect->prim = 0;
+//			isect->object = 0;
+
+			return true;
+		}
+
+		return false;
+	}
+
+	ccl_always_inline bool march(float *t0, float *t1)
+	{
+		if(!uniform_voxels) {
+			return false;
+		}
+
+		pthread_t thread = pthread_self();
+		isect_map::iterator iter = isectors.find(thread);
+		isector_t *vdb_isect;
+
+		if(iter == isectors.end()) {
+			vdb_isect = new isector_t(*main_isector);
+			pair<pthread_t, isector_t *> inter(thread, vdb_isect);
+			isectors.insert(inter);
+		}
+		else {
+			vdb_isect = iter->second;
+		}
+
+		openvdb::Real vdb_t0(*t0), vdb_t1(*t1);
+
+		if(vdb_isect->march(vdb_t0, vdb_t1)) {
+			*t0 = (float)vdb_t0;
+			*t1 = (float)vdb_t1;
+
+			return true;
+		}
+
+		return false;
+	}
 };
 
-class vdb_float3_sampler : public float3_volume_sampler {
-	vdb_vsampler_p *point_sampler;
-	vdb_vsampler_b *box_sampler;
+/* Same as above, except for vector grids */
+/* TODO(kevin): staggered velocity grid sampling */
+class vdb_float3_volume : public float3_volume {
+	typedef openvdb::tools::GridSampler<openvdb::Vec3SGrid::ConstAccessor, openvdb::tools::PointSampler> point_sampler_t;
+	typedef openvdb::tools::GridSampler<openvdb::Vec3SGrid::ConstAccessor, openvdb::tools::BoxSampler> box_sampler_t;
+	point_sampler_t *point_sampler;
+	box_sampler_t *box_sampler;
+
+	typedef openvdb::tools::VolumeRayIntersector<openvdb::Vec3SGrid> isector_t;
+	typedef isector_t::RayType vdb_ray_t;
 
 	/* mainly used to ensure thread safety for the accessors */
-	typedef unordered_map<pthread_t, vdb_vsampler_p *> point_map;
-	typedef unordered_map<pthread_t, vdb_vsampler_b *> box_map;
+	typedef unordered_map<pthread_t, isector_t *> isect_map;
+	typedef unordered_map<pthread_t, point_sampler_t *> point_map;
+	typedef unordered_map<pthread_t, box_sampler_t *> box_map;
+	isect_map isectors;
 	point_map point_samplers;
 	box_map box_samplers;
 
 	openvdb::Vec3SGrid::ConstAccessor *accessor;
 
+	/* Main intersector, its purpose is to initialize the voxels' bounding box
+	 * so the ones for the various threads do not do this, rather they are
+	 * generated from of copy of it. */
+	isector_t *main_isector;
+
+	bool uniform_voxels;
+
 public:
-	vdb_float3_sampler(openvdb::Vec3SGrid::Ptr grid)
+	vdb_float3_volume(openvdb::Vec3SGrid::Ptr grid)
 	{
-		point_sampler = new vdb_vsampler_p(grid->tree(), grid->transform());
-		box_sampler = new vdb_vsampler_b(grid->tree(), grid->transform());
+		accessor = new openvdb::Vec3SGrid::ConstAccessor(grid->getConstAccessor());
+		point_sampler = new point_sampler_t(grid->tree(), grid->transform());
+		box_sampler = new box_sampler_t(grid->tree(), grid->transform());
+
+		/* only grids with uniform voxels can be used with VolumeRayIntersector */
+		if(grid->hasUniformVoxels()) {
+			uniform_voxels = true;
+			main_isector = new isector_t(*grid);
+		}
+		else {
+			uniform_voxels = false;
+		}
 	}
 
-	~vdb_float3_sampler()
+	~vdb_float3_volume()
 	{
 		delete point_sampler;
 		delete box_sampler;
@@ -140,12 +266,12 @@ public:
 
 		if(sampling == OPENVDB_SAMPLE_POINT) {
 			point_map::iterator iter = point_samplers.find(thread);
-			vdb_vsampler_p *sampler;
+			point_sampler_t *sampler;
 
 			if(iter == point_samplers.end()) {
 				openvdb::Vec3SGrid::ConstAccessor *acc = new openvdb::Vec3SGrid::ConstAccessor(*accessor);
-				sampler = new vdb_vsampler_p(*acc, point_sampler->transform());
-				pair<pthread_t, vdb_vsampler_p *> sampl(thread, sampler);
+				sampler = new point_sampler_t(*acc, point_sampler->transform());
+				pair<pthread_t, point_sampler_t *> sampl(thread, sampler);
 				point_samplers.insert(sampl);
 			}
 			else {
@@ -155,13 +281,13 @@ public:
 			r = sampler->wsSample(openvdb::Vec3d(co.x, co.y, co.z));
 		}
 		else {
-			point_map::iterator iter = box_samplers.find(thread);
-			vdb_vsampler_b *sampler;
+			box_map::iterator iter = box_samplers.find(thread);
+			box_sampler_t *sampler;
 
 			if(iter == box_samplers.end()) {
 				openvdb::Vec3SGrid::ConstAccessor *acc = new openvdb::Vec3SGrid::ConstAccessor(*accessor);
-				sampler = new vdb_vsampler_b(*acc, box_sampler->transform());
-				pair<pthread_t, vdb_vsampler_b *> sampl(thread, sampler);
+	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list