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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to