VDB R&D

VDB Data value visualize: 结论从houdini得知.

API常用文字:

interior:内部

Narrow-band:窄带

background:窄带外

SDF: XY plane Data visualize:

{

  (1)用法:vdb sdf levelset球,采样其体素值到对应的点位置的颜色观察。houdini节点vdb from polygons(参数上Exterior band voxels:3,Interior band voxels:3)没有开启Fill interior

  则形成体素值:

    interior是-0.3 (这个值是由Interior band voxels:3 得到)

    Narrow-band: 从interior到narrow-band方向:-0.3 到 0

      background:从narrow-band到background方向:0.3 (Exterior band voxels:3)

  (2)用法:

  假如要让interior成为一个梯度值,而不是恒定值,houdini做了一个牛逼的按钮,Fill interior.

  interior里的体素值立马成为梯度的,大概是从-3.73过渡到narrow-band

}

FOG Volume: XY plane Data visualize:

{

  (1) 普通不勾选fill interior:

  interior是1

  Narrow-band: 从interior到narrow-band方向:1 到 0

    background:从narrow-band到background方向:0

  (2) 勾选fill interior:

  interior到narrow-band方向从1->0.3有个过渡

  Narrow-band: 从interior到narrow-band方向:0.3 到 0

    background:从narrow-band到background方向:0

}

==================================================================START======================================================

<1> ,make vdb sphere,and convert to volume

VDB R&D

#include <openvdb/openvdb.h>
#include <openvdb/tools/LevelSetSphere.h>
using namespace std; // Populate the given grid with a narrow-band level set representation of a sphere.
// The width of the narrow band is determined by the grid's background value.
// (Example code only; use tools::createSphereSDF() in production.)
template<class GridType>
void
static makeSphere(GridType& grid, float radius, const openvdb::Vec3f& c)
{
typedef typename GridType::ValueType ValueT;
// Distance value for the constant region exterior to the narrow band
const ValueT outside = grid.background();
// Distance value for the constant region interior to the narrow band
// (by convention, the signed distance is negative in the interior of
// a level set)
const ValueT inside = -outside;
// Use the background value as the width in voxels of the narrow band.
// (The narrow band is centered on the surface of the sphere, which
// has distance 0.)
int padding = int(openvdb::math::RoundUp(openvdb::math::Abs(outside)));
// The bounding box of the narrow band is 2*dim voxels on a side.
int dim = int(radius + padding);
// Get a voxel accessor.
typename GridType::Accessor accessor = grid.getAccessor();
// Compute the signed distance from the surface of the sphere of each
// voxel within the bounding box and insert the value into the grid
// if it is smaller in magnitude than the background value.
openvdb::Coord ijk;
int &i = ijk[];
int &j = ijk[];
int &k = ijk[];
for (i = c[] - dim; i < c[] + dim; ++i) {
const float x2 = openvdb::math::Pow2(i - c[]);
for (j = c[] - dim; j < c[] + dim; ++j) {
const float x2y2 = openvdb::math::Pow2(j - c[]) + x2;
for (k = c[] - dim; k < c[] + dim; ++k) {
// The distance from the sphere surface in voxels
const float dist = openvdb::math::Sqrt(x2y2
+ openvdb::math::Pow2(k - c[])) - radius;
// Convert the floating-point distance to the grid's value type.
ValueT val = ValueT(dist);
// Only insert distances that are smaller in magnitude than
// the background value.
if (val < inside || outside < val) continue;
// Set the distance for voxel (i,j,k).
accessor.setValue(ijk, val);
}
}
}
// Propagate the outside/inside sign information from the narrow band
// throughout the grid.
openvdb::tools::signedFloodFill(grid.tree()); } template <class T>
static void convertToVolume(T &grid)
{ // Convert the level set sphere to a narrow-band fog volume, in which
// interior voxels have value 1, exterior voxels have value 0, and
// narrow-band voxels have values varying linearly from 0 to 1.
const float outside = grid->background();
const float width = 2.0 * outside;
// Visit and update all of the grid's active values, which correspond to
// voxels on the narrow band.
for (openvdb::FloatGrid::ValueOnIter iter = grid->beginValueOn(); iter; ++iter) {
float dist = iter.getValue();
iter.setValue((outside - dist) / width);
}
// Visit all of the grid's inactive tile and voxel values and update the values
// that correspond to the interior region.
for (openvdb::FloatGrid::ValueOffIter iter = grid->beginValueOff(); iter; ++iter) {
if (iter.getValue() < 0.0) {
iter.setValue(1.0);
iter.setValueOff();
} else{
iter.setValue();
iter.setValueOff();
}
} } int main()
{ openvdb::initialize();
// Create a shared pointer to a newly-allocated grid of a built-in type:
// in this case, a FloatGrid, which stores one single-precision floating point
// value per voxel. Other built-in grid types include BoolGrid, DoubleGrid,
// Int32Grid and Vec3SGrid (see openvdb.h for the complete list).
// The grid comprises a sparse tree representation of voxel data,
// user-supplied metadata and a voxel space to world space transform,
// which defaults to the identity transform.
openvdb::FloatGrid::Ptr grid =
openvdb::FloatGrid::create(/*background value=*/2.0);
// Populate the grid with a sparse, narrow-band level set representation
// of a sphere with radius 50 voxels, located at (1.5, 2, 3) in index space.
makeSphere(*grid, /*radius=*/50.0, /*center=*/openvdb::Vec3f(1.5, , ));
// Associate some metadata with the grid.
grid->insertMeta("radius", openvdb::FloatMetadata(50.0));
// Associate a scaling transform with the grid that sets the voxel size
// to 0.5 units in world space.
grid->setTransform(
openvdb::math::Transform::createLinearTransform(/*voxel size=*/0.5));
// Identify the grid as a level set.
grid->setGridClass(openvdb::GRID_LEVEL_SET);
//grid->setGridClass(openvdb::GRID_FOG_VOLUME);
// Name the grid "LevelSetSphere".
grid->setName("LevelSetSphere");
// Create a VDB file object.
openvdb::io::File file("mygrids.vdb");
// Add the grid pointer to a container.
openvdb::GridPtrVec grids; // Write out the contents of the container. grids.push_back(grid);
file.write(grids);
file.close(); // ============================================================= convert level set sphere to a fog volume sphere =====================================================
std::cout << "read a new sdf volume and change it to fog\n";
openvdb::io::File readFile("mygrids.vdb");
readFile.open();
openvdb::GridBase::Ptr readGrid;
for(openvdb::io::File::NameIterator nameIter = readFile.beginName();nameIter!=readFile.endName();++nameIter)
{
if(nameIter.gridName() == "LevelSetSphere")
{
readGrid = readFile.readGrid(nameIter.gridName());
} else
{
std::cout << "skip other grid modifile " << nameIter.gridName() <<std::endl;
}
}
openvdb::FloatGrid::Ptr cast_grid = openvdb::gridPtrCast<openvdb::FloatGrid>(readGrid);
cast_grid->setGridClass(openvdb::GRID_FOG_VOLUME);
readFile.close();
convertToVolume(cast_grid);
openvdb::GridPtrVec WM_grids;
WM_grids.push_back(cast_grid);
openvdb::io::File WM_file("mygrids_convertToVolume.vdb");
WM_file.write(WM_grids);
WM_file.close(); return ;
}

<2> vdb from particles

VDB R&D

主要观察粒子的density,velocity

#include <openvdb/openvdb.h>

#include <openvdb/tools/ParticlesToLevelSet.h>

#include <iostream>
#include <vector>

struct MyParticle
{
openvdb::Vec3R p, v;
openvdb::Real r;
}; class MyParticleList
{ // change protected to the public,direct find the mRadiusScale,mVelocityScale
public: openvdb::Real mRadiusScale;
openvdb::Real mVelocityScale;
std::vector<MyParticle> mParticleList; public:
std::vector<MyParticle> &get_mPartcileList()
{
return mParticleList;
} public: typedef openvdb::Vec3R PosType; MyParticleList(openvdb::Real rScale=, openvdb::Real vScale=)
: mRadiusScale(rScale), mVelocityScale(vScale) {}
void add(const openvdb::Vec3R &p, const openvdb::Real &r,
const openvdb::Vec3R &v=openvdb::Vec3R(,,))
{
MyParticle pa;
pa.p = p;
pa.r = r;
pa.v = v;
mParticleList.push_back(pa);
}
/// @return coordinate bbox in the space of the specified transfrom
openvdb::CoordBBox getBBox(const openvdb::GridBase& grid) {
openvdb::CoordBBox bbox;
openvdb::Coord &min= bbox.min(), &max = bbox.max();
openvdb::Vec3R pos;
openvdb::Real rad, invDx = /grid.voxelSize()[];
for (size_t n=, e=this->size(); n<e; ++n) {
this->getPosRad(n, pos, rad);
const openvdb::Vec3d xyz = grid.worldToIndex(pos);
const openvdb::Real r = rad * invDx;
for (int i=; i<; ++i) {
min[i] = openvdb::math::Min(min[i], openvdb::math::Floor(xyz[i] - r));
max[i] = openvdb::math::Max(max[i], openvdb::math::Ceil( xyz[i] + r));
}
}
return bbox;
}
//typedef int AttributeType;
// The methods below are only required for the unit-tests
openvdb::Vec3R pos(int n) const {return mParticleList[n].p;}
openvdb::Vec3R vel(int n) const {return mVelocityScale*mParticleList[n].v;}
openvdb::Real radius(int n) const {return mRadiusScale*mParticleList[n].r;} //////////////////////////////////////////////////////////////////////////////
/// The methods below are the only ones required by tools::ParticleToLevelSet
/// @note We return by value since the radius and velocities are modified
/// by the scaling factors! Also these methods are all assumed to
/// be thread-safe. /// Return the total number of particles in list.
/// Always required!
size_t size() const { return mParticleList.size(); } /// Get the world space position of n'th particle.
/// Required by ParticledToLevelSet::rasterizeSphere(*this,radius).
void getPos(size_t n, openvdb::Vec3R&pos) const { pos = mParticleList[n].p; } void getPosRad(size_t n, openvdb::Vec3R& pos, openvdb::Real& rad) const {
pos = mParticleList[n].p;
rad = mRadiusScale*mParticleList[n].r;
}
void getPosRadVel(size_t n, openvdb::Vec3R& pos, openvdb::Real& rad, openvdb::Vec3R& vel) const {
pos = mParticleList[n].p;
rad = mRadiusScale*mParticleList[n].r;
vel = mVelocityScale*mParticleList[n].v;
}
// The method below is only required for attribute transfer
void getAtt(size_t n, openvdb::Index32& att) const { att = openvdb::Index32(n); }
};

Particles IO

Buiding the density,and write it out.

int main()
{ const float voxelSize = 0.2f, halfWidth = 2.0f;
openvdb::FloatGrid::Ptr density_grid = openvdb::createLevelSet<openvdb::FloatGrid>(voxelSize, halfWidth); MyParticleList pa(,); // this multiply is radius scale , velocity scale // This particle radius = 1 < 1.5 i.e. it's below the Nyquist frequency and hence ignored
pa.add(openvdb::Vec3R( , , ), , openvdb::Vec3R( , , ));
pa.add(openvdb::Vec3R( , , ), , openvdb::Vec3R( , , ));
pa.add(openvdb::Vec3R( , , ), , openvdb::Vec3R( , , ));
pa.add(openvdb::Vec3R( , , ), , openvdb::Vec3R( , , ));
pa.add(openvdb::Vec3R( , , ), , openvdb::Vec3R( , , )); openvdb::tools::ParticlesToLevelSet<openvdb::FloatGrid> raster(*density_grid);
raster.rasterizeTrails(pa, 0.75);//scale offset between two instances // always prune to produce a valid narrow-band level set.
raster.finalize(true); density_grid->setGridClass(openvdb::GRID_LEVEL_SET);
density_grid->setName("density");
convertToVolume(density_grid); // Create a VDB file object.
openvdb::io::File file("mygrids.vdb");
// Add the grid pointer to a container.
openvdb::GridPtrVec grids;
grids.push_back(density_grid); // Write out the contents of the container.
file.write(grids);
file.close(); }

particles to volume

一个更好的方法Buiding the density.and write it out

// Note densityGrid allocation memory in this function and transform same as densityGrid
void buildingDensityGrid(openvdb::FloatGrid::Ptr &densityGrid,
openvdb::math::Transform::Ptr &transform,MyParticleList &pa,bool isRasterToSphere = true)
{
float backGround = 0.1f;
float voxelSize = 0.1;
transform = openvdb::math::Transform::createLinearTransform(voxelSize);
densityGrid = openvdb::FloatGrid::create(backGround);
std::cout << "set density grid class type\n";
densityGrid->setGridClass(openvdb::GRID_LEVEL_SET);
densityGrid->setTransform(transform);
openvdb::tools::ParticlesToLevelSet<openvdb::FloatGrid> raster(*densityGrid);
if(isRasterToSphere)
{
raster.rasterizeSpheres(pa,pa.mRadiusScale);
} else{
raster.rasterizeTrails(pa,0.75);
}
raster.finalize(true);
std::cout << "raster to end\n";
} int main()
{
MyParticleList pa(,);
pa.add(openvdb::Vec3R( , , ), , openvdb::Vec3R( , , ));
pa.add(openvdb::Vec3R( , , ), , openvdb::Vec3R( , , ));
pa.add(openvdb::Vec3R( , , ), , openvdb::Vec3R( , , ));
pa.add(openvdb::Vec3R( , , ), , openvdb::Vec3R( , , ));
pa.add(openvdb::Vec3R( , , ), , openvdb::Vec3R( , , )); openvdb::FloatGrid::Ptr densityGrid;
openvdb::math::Transform::Ptr transform;
buildingDensityGrid(densityGrid,transform,pa);
densityGrid->setName("density");
convertToVolume(densityGrid); // Create a VDB file object.
std::cout << "write vdb \n";
openvdb::io::File file("mygrids.vdb");
// Add the grid pointer to a container.
openvdb::GridPtrVec grids;
grids.push_back(densityGrid);
// Write out the contents of the container.
file.write(grids);
file.close(); }

接下来VelocityBuilding,直接写了个包裹库,并且在houdini测试了下openvdb::Vec3sGrid的运动模糊。

VDB R&D

VDB R&D

GLY_OpenVdbWrapper.h

//
// Created by gearslogy on 4/13/17.
// #ifndef ARNOLDVDBPOINTS_GLY_OPENVDBWAPPER_H
#define ARNOLDVDBPOINTS_GLY_OPENVDBWAPPER_H #include <memory>
#include <openvdb/openvdb.h>
#include <openvdb/tools/ParticlesToLevelSet.h>
#include <openvdb/tools/LevelSetUtil.h>
#include <openvdb/tools/TopologyToLevelSet.h> // DEFINE OUR PARTICLES STRUCT
namespace TopVertex
{ struct MyParticle
{
openvdb::Vec3R p, v;
openvdb::Real r; // per particle has own radius
}; class MyParticleList
{
// change protected to the public,direct find the mRadiusScale,mVelocityScale
public:
openvdb::Real mRadiusScale;
openvdb::Real mVelocityScale;
std::vector<MyParticle> mParticleList;
typedef openvdb::Vec3R PosType;
MyParticleList(openvdb::Real rScale=, openvdb::Real vScale=)
: mRadiusScale(rScale), mVelocityScale(vScale) {}
void add(const openvdb::Vec3R &p, const openvdb::Real &r,
const openvdb::Vec3R &v=openvdb::Vec3R(,,))
{
MyParticle pa;
pa.p = p;
pa.r = r;
pa.v = v;
mParticleList.push_back(pa);
}
/// @return coordinate bbox in the space of the specified transfrom
openvdb::CoordBBox getBBox(const openvdb::GridBase& grid) {
openvdb::CoordBBox bbox;
openvdb::Coord &min= bbox.min(), &max = bbox.max();
openvdb::Vec3R pos;
openvdb::Real rad, invDx = /grid.voxelSize()[];
for (size_t n=, e=this->size(); n<e; ++n) {
this->getPosRad(n, pos, rad);
const openvdb::Vec3d xyz = grid.worldToIndex(pos);
const openvdb::Real r = rad * invDx;
for (int i=; i<; ++i) {
min[i] = openvdb::math::Min(min[i], openvdb::math::Floor(xyz[i] - r));
max[i] = openvdb::math::Max(max[i], openvdb::math::Ceil( xyz[i] + r));
}
}
return bbox;
}
//typedef int AttributeType;
// The methods below are only required for the unit-tests
openvdb::Vec3R pos(int n) const {return mParticleList[n].p;}
openvdb::Vec3R vel(int n) const {return mVelocityScale*mParticleList[n].v;}
openvdb::Real radius(int n) const {return mRadiusScale*mParticleList[n].r;} //////////////////////////////////////////////////////////////////////////////
/// The methods below are the only ones required by tools::ParticleToLevelSet
/// @note We return by value since the radius and velocities are modified
/// by the scaling factors! Also these methods are all assumed to
/// be thread-safe. /// Return the total number of particles in list.
/// Always required!
size_t size() const { return mParticleList.size(); } /// Get the world space position of n'th particle.
/// Required by ParticledToLevelSet::rasterizeSphere(*this,radius).
void getPos(size_t n, openvdb::Vec3R&pos) const { pos = mParticleList[n].p; } void getPosRad(size_t n, openvdb::Vec3R& pos, openvdb::Real& rad) const {
pos = mParticleList[n].p;
rad = mRadiusScale*mParticleList[n].r;
}
void getPosRadVel(size_t n, openvdb::Vec3R& pos, openvdb::Real& rad, openvdb::Vec3R& vel) const {
pos = mParticleList[n].p;
rad = mRadiusScale*mParticleList[n].r;
vel = mVelocityScale*mParticleList[n].v;
}
// The method below is only required for attribute transfer
void getAtt(size_t n, openvdb::Index32& att) const { att = openvdb::Index32(n); }
}; } //
namespace TopVertex
{
class GLY_OpenVdbWrapper
{
public:
// Rater point parm
struct RasterParms
{
float backGround;
float voxelSize;
float halfWidth;
}; // define some variable type
using Ptr = std::shared_ptr<GLY_OpenVdbWrapper>;
using RasterT = openvdb::tools::ParticlesToLevelSet<openvdb::FloatGrid, openvdb::Index32>;
enum POINT_RASTER_TYPE{RS_Sphere=0x0,RS_trailer=0x1}; // define a static pointer to our class
static GLY_OpenVdbWrapper* creator(); //
GLY_OpenVdbWrapper();
~GLY_OpenVdbWrapper(); // SAMPLE POINTS API
void samplePointsSetPoints(const std::vector<openvdb::Vec3R> &posList);
void samplePointsSetPoints(double *array,int rawSize);
void samplePointsSetRadius(double *array,int rawSize);
void samplePointsSetRadius(const std::vector<openvdb::Real> &radiusList);
void samplePointsSetVelocity(const std::vector<openvdb::Vec3R> &vel);
void samplePointsSetVelocity(double *array,int rawsize);
void samplePointsSetRadiusScale(double radius);
void samplePointsSetVelocityScale(double v);
void samplePointsAppendPoint(openvdb::Vec3R p,openvdb::Vec3R v,openvdb::Real radius);
void samplePointsRasterDensityGrid(POINT_RASTER_TYPE type,openvdb::FloatGrid::Ptr &gridPtr,RasterParms &rasterParm);
void samplePointsRasterVelocityGrid(openvdb::math::Transform::Ptr &density_transform,openvdb::Vec3SGrid::Ptr &velocityGrid); private:
class SamplePoints;
std::unique_ptr<SamplePoints> mPimplSamplePoints;
};
} #endif //ARNOLDVDBPOINTS_GLY_OPENVDBWAPPER_H

GLY_OpenVdbWrapper.cpp

//
// Created by gearslogy on 4/13/17.
// #include "GLY_OpenVdbWrapper.h"
#include <assert.h>
#include <algorithm>
using namespace TopVertex; //=======================================SamplePoints details=================================
//
class GLY_OpenVdbWrapper::SamplePoints
{
public:
SamplePoints():mParticleListPtr(new MyParticleList(,))
{
}
~SamplePoints()
{
std::cout << "Release SamplePoints memory\n";
}
void setRadiusScale(double radius)
{
mParticleListPtr->mRadiusScale = radius;
}
void setVelocityScale(double v)
{
mParticleListPtr->mVelocityScale = v;
} void setPoints(const std::vector<openvdb::Vec3R> &posList)
{
auto &pa = mParticleListPtr->mParticleList;
pa.resize(posList.size());
for(int i=;i<posList.size();i++)
{
pa[i].p = posList[i];
}
}
void setPoints(double *array,int rawsize)
{
assert(rawsize%==);
auto &pa = mParticleListPtr->mParticleList;
pa.resize(rawsize/);
for(int i=;i<rawsize/;i++)
{
double x = array[i];
double y = array[i+];
double z = array[i+];
auto t = openvdb::Vec3R(x,y,z);
pa[i].p = t;
}
}
void setRadius(const std::vector<openvdb::Real> &radiusList)
{
assert(radiusList.size()==mParticleListPtr->mParticleList.size());
auto &pa = mParticleListPtr->mParticleList;
for(int i=;i<pa.size();i++)
{
pa[i].r = radiusList[i];
}
}
void setRadius(double *array,int pointsNum)
{
assert(pointsNum==mParticleListPtr->mParticleList.size());
auto &pa = mParticleListPtr->mParticleList;
for(int i=;i<pa.size();i++)
{
pa[i].r = array[i];
}
}
void setVelocity(const std::vector<openvdb::Vec3R> &vel)
{
assert(vel.size() == mParticleListPtr->mParticleList.size());
auto &pa = mParticleListPtr->mParticleList;
for(int i=;i<vel.size();i++)
{
pa[i].v = vel[i];
}
}
void setVelocity(double *array,int rawsize)
{
assert(rawsize%==);
auto &pa = mParticleListPtr->mParticleList;
for(int i=;i<rawsize/;i++)
{
double x = array[i];
double y = array[i+];
double z = array[i+];
auto t = openvdb::Vec3R(x,y,z);
pa[i].v = t;
}
}
void appendPoint(openvdb::Vec3R p,openvdb::Vec3R v,openvdb::Real radius)
{
mParticleListPtr->add(p,radius,v);
}
void clearPoints(){mParticleListPtr->mParticleList.clear();}
void rasterDensity(POINT_RASTER_TYPE type,openvdb::FloatGrid::Ptr &gridPtr,RasterParms &rasterParm)
{ std::cout << "Start process samplePoints Raster Density\n";
float backGround = rasterParm.backGround;
float voxelSize = rasterParm.voxelSize;
float halfWidth = rasterParm.halfWidth;
openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(voxelSize);
//gridPtr = openvdb::FloatGrid::create(backGround); //this is simple and can work
gridPtr = openvdb::createLevelSet<openvdb::FloatGrid>(voxelSize, halfWidth); gridPtr->setGridClass(openvdb::GRID_LEVEL_SET);
gridPtr->setTransform(transform);
openvdb::tools::ParticlesToLevelSet<openvdb::FloatGrid,openvdb::Index> raster(*gridPtr);
if(type==0x0) // RS_Sphere
{
raster.rasterizeSpheres(*mParticleListPtr);
} else
{
raster.rasterizeTrails(*mParticleListPtr,0.75);
}
raster.finalize(true);
openvdb::tools::sdfToFogVolume(*gridPtr);
gridPtr->setName("density");
mId=raster.attributeGrid();
} void rasterVelocityGrid(openvdb::math::Transform::Ptr &density_transform,openvdb::Vec3SGrid::Ptr &gridPtr)
{
typedef typename openvdb::Int32Grid::TreeType::ValueConverter<openvdb::Vec3s >::Type TreeTypeWarpVec;
typedef typename openvdb::Grid<TreeTypeWarpVec> GridType;
typename TreeTypeWarpVec::Ptr tree(
new TreeTypeWarpVec(mId->tree(), openvdb::Vec3s(,,) , openvdb::TopologyCopy()));
//typename GridType::Ptr velocity_grid(GridType::create(tree)); //为grid开辟内存*/ gridPtr = openvdb::Vec3SGrid::create(tree);
gridPtr->setVectorType(openvdb::VecType());
// MY Method
openvdb::Coord ijk;
openvdb::Vec3SGrid::Accessor vel_accessor = gridPtr->getAccessor();
for(auto iter = mId->beginValueOn();iter.test();++iter)
{
auto d = *iter;
//std::cout << " D:..." <<d <<std::endl;
ijk = iter.getCoord();
openvdb::math::Vec3s vel = mParticleListPtr->vel(d);
vel*=;
vel_accessor.setValue(ijk,vel); }
gridPtr->setName("vel");
gridPtr->setTransform(density_transform);
} private:
std::unique_ptr<MyParticleList > mParticleListPtr;
RasterT::AttGridType::Ptr mId; //remeber the id of point in voxel
}; // //============================================GLY_OpenVdbWrapper==================================================
// GLY_OpenVdbWrapper Details GLY_OpenVdbWrapper::GLY_OpenVdbWrapper():mPimplSamplePoints(new GLY_OpenVdbWrapper::SamplePoints())
{
}
GLY_OpenVdbWrapper::~GLY_OpenVdbWrapper()
{
std::cout << "Release Wrapper memory\n";
}
void GLY_OpenVdbWrapper::samplePointsSetPoints(const std::vector<openvdb::Vec3R> &posList)
{
mPimplSamplePoints->setPoints(posList);
}
void GLY_OpenVdbWrapper::samplePointsSetPoints(double *array,int rawSize)
{
mPimplSamplePoints->setPoints(array,rawSize);
}
void GLY_OpenVdbWrapper::samplePointsSetRadius(double *array, int rawSize) {
mPimplSamplePoints->setRadius(array,rawSize);
}
void GLY_OpenVdbWrapper::samplePointsSetRadius(const std::vector<openvdb::Real> &radiusList) {
mPimplSamplePoints->setRadius(radiusList);
}
void GLY_OpenVdbWrapper::samplePointsSetVelocity(const std::vector<openvdb::Vec3R> &vel) {
mPimplSamplePoints->setVelocity(vel);
}
void GLY_OpenVdbWrapper::samplePointsSetVelocity(double *array, int rawsize) {
mPimplSamplePoints->setVelocity(array,rawsize);
}
void GLY_OpenVdbWrapper::samplePointsSetRadiusScale(double radius) {
mPimplSamplePoints->setRadiusScale(radius);
}
void GLY_OpenVdbWrapper::samplePointsSetVelocityScale(double v) {
mPimplSamplePoints->setVelocityScale(v);
}
void GLY_OpenVdbWrapper::samplePointsAppendPoint(openvdb::Vec3R p, openvdb::Vec3R v, openvdb::Real radius)
{
mPimplSamplePoints->appendPoint(p,v,radius);
}
GLY_OpenVdbWrapper* GLY_OpenVdbWrapper::creator() {
return new GLY_OpenVdbWrapper;
}
void GLY_OpenVdbWrapper::samplePointsRasterDensityGrid(POINT_RASTER_TYPE type, openvdb::FloatGrid::Ptr &gridPtr,
RasterParms &rasterParm) {
mPimplSamplePoints->rasterDensity(type,gridPtr,rasterParm);
}
void GLY_OpenVdbWrapper::samplePointsRasterVelocityGrid(openvdb::math::Transform::Ptr &density_transform,
openvdb::Vec3SGrid::Ptr &velocityGrid)
{
mPimplSamplePoints->rasterVelocityGrid(density_transform,velocityGrid);
}

main.cpp:

//
// Created by gearslogy on 4/14/17.
// #include "GLY_OpenVdbWrapper.h"
using namespace std;
using namespace TopVertex;
int main()
{
GLY_OpenVdbWrapper::Ptr wrapper(GLY_OpenVdbWrapper::creator());
wrapper->samplePointsAppendPoint(openvdb::Vec3R(, , ), openvdb::Vec3R( , , ) ,);
wrapper->samplePointsAppendPoint(openvdb::Vec3R(, , ), openvdb::Vec3R( , , ) ,1.5);
wrapper->samplePointsAppendPoint(openvdb::Vec3R(, , ), openvdb::Vec3R( , , ) ,2.0);
wrapper->samplePointsAppendPoint(openvdb::Vec3R(, , ), openvdb::Vec3R( , , ) ,2.5);
wrapper->samplePointsAppendPoint(openvdb::Vec3R(, , ), openvdb::Vec3R( , , ) ,3.0); // create grid named "density"
openvdb::FloatGrid::Ptr densityGrid;
GLY_OpenVdbWrapper::RasterParms parms;
parms.backGround = 0.1;
parms.voxelSize = 0.1;
parms.halfWidth = 0.5;
wrapper->samplePointsRasterDensityGrid(GLY_OpenVdbWrapper::RS_Sphere,densityGrid,parms); // Create velocity Grid "velocity"
openvdb::Vec3SGrid::Ptr velocityGrid;
auto densityTransform = densityGrid->transformPtr();
wrapper->samplePointsRasterVelocityGrid(densityTransform,velocityGrid); // IO Operator
openvdb::io::File file("mygrids.vdb");
openvdb::GridPtrVec grids;
grids.push_back(densityGrid);
grids.push_back(velocityGrid);
file.write(grids);
file.close(); }

Test plugin for katana:

VDB R&D

Update katana plugin:

升级了光线求交,直接快的飞起来

Arnold粒子体积渲染(Arnold particles volume rendering):

插件loading模式:AlembicAPI->OpenvdbAPI->ArnoldAPI

然后KatanaAPI再写个插件 读取这个ArnoldAPI写出来的proc,

VDB R&D

update volume:

重要的事情不说两遍,static 关键字在一个so上被一个进程,2个instance调用,全局的static object内存地址是他妈一样的,也就是说是共享的地址。会导致你假如创建两个instance,你却希望有两份不一样的全局变量内容,结果,太感人了,确实是错的,是一样的。

如果独立进程,独立instance调用so上的全局变量,ok没问题。VDB R&D

Rendering the cd field:

VDB R&D

VDB R&D

上一篇:Spring @Qualifier l转


下一篇:161209、简要分析ZooKeeper基本原理及安装部署