1

OpenVDB 看起来真的很神奇,节点的寻址真的很聪明。有些操作我不明白,特别是CSG操作。这是一个示例代码。它接受两个参数作为输入:

  • 一个只有一个网格的 vdb 输入文件,表示从三角形网格开始创建的水平集,
  • 存储操作结果的 vdb 输出。

该算法应该接受输入,

  1. 在 gridA 中创建 deepCopy
  2. 在 gridB 中创建 deepCopy
  3. 沿 M_PI/4.0f 的 Y 轴旋转 gridB
  4. 在 gridA 和 gridB 之间执行 csgUnion
  5. 将所有网格保存在 vdb 输出文件中。

我正在尝试使用 VDB 网格作为数据容器来代替经典八叉树算法,用于在碰撞中需要高度详细信息的物理模拟。

我理解世界坐标和网格坐标之间转换的概念,我不明白的是如何在树内执行数据的转换,比如平移或旋转水平集,就像一个刚性对象。在这个例子中,我认为我只是在改变世界和格子之间的转换。

这是结果(水平集和体积相同):gridA 应该是原始加载的网格Initial Grid gridB 是旋转了 45 度的网格,实际上是Trasformed 网格,似乎执行了旋转...与工会的结果网格......但没有运气......没有最终结果?

你有什么建议吗?

附:一个例子和一个链接到我正在使用的LINK REMOVED(对不起,它是 133MB ......)

#include <cmath>
#include "openvdb/openvdb.h"
#include "openvdb/util/Util.h"
#include "openvdb/io/Stream.h"
#include "openvdb/tools/Composite.h"

using namespace openvdb;
int main(int argc, char** argv) {
  openvdb::initialize();

  openvdb::io::File file(argv[1]);
  file.open();

  GridBase::Ptr baseGrid;
  for (openvdb::io::File::NameIterator nameIter = file.beginName(); 
       nameIter != file.endName(); ++nameIter) 
       { baseGrid = file.readGrid(nameIter.gridName()); }

  file.close();
  FloatGrid::Ptr gridA = gridPtrCast<FloatGrid>(baseGrid);
  FloatGrid::Ptr gridB = gridA->deepCopy();
  FloatGrid::Ptr result = gridA ->deepCopy();

  gridB->transform().postRotate(M_PI/4.0f, math::Y_AXIS);

  tools::csgUnion(*result, *gridB);

  openvdb::io::File file_out(argv[2]);
  GridPtrVec grids;

  grids.push_back(gridA);
  grids.push_back(gridB);
  grids.push_back(result);

  file_out.write(grids);
  file_out.close();

  return 0;
}
4

1 回答 1

0

由于 OpenVDB 论坛中的 VDB 支持,我的答案的解决方案是:

  1. 执行初始网格的简单元数据副本
  2. 执行转换(就像我的代码中的旋转)
  3. 使用,从新转换网格中的初始网格重新插入数据tools::resampleToMatch,选择可用的插值器之一(在我的情况下tools::BoxSample)。
  4. 继续 csg 操作

仅供参考,使用优化标志的执行时间存在极大差异-O3(减少 400% 时间)。

#include "openvdb/io/Stream.h"
#include "openvdb/openvdb.h"
#include "openvdb/tools/Composite.h"
#include "openvdb/tools/GridTransformer.h"
#include "openvdb/tools/Interpolation.h"
#include "openvdb/util/Util.h"

#include <cmath>

using namespace openvdb;
int main(int argc, char **argv) {
  openvdb::initialize();

  openvdb::io::File file(argv[1]);
  file.open();

  GridBase::Ptr baseGrid;
  for (openvdb::io::File::NameIterator nameIter = file.beginName();
       nameIter != file.endName(); ++nameIter) {
    baseGrid = file.readGrid(nameIter.gridName());
  }

  file.close();
  FloatGrid::Ptr gridA = gridPtrCast<FloatGrid>(baseGrid);
  FloatGrid::Ptr gridB = gridA->copy(CP_NEW);
  gridB->setTransform(gridA->transform().copy());
  gridB->transform().postRotate(M_PI / 4.0f, math::Y_AXIS);

  tools::resampleToMatch<tools::BoxSampler>(*gridA, *gridB);

  FloatGrid::Ptr result = gridA->deepCopy();
  FloatGrid::Ptr gridB2 = gridB->deepCopy();

  tools::csgUnion(*result, *gridB);

  openvdb::io::File file_out(argv[2]);
  GridPtrVec grids;

  grids.push_back(gridA);
  grids.push_back(gridB2);
  grids.push_back(result);

  file_out.write(grids);
  file_out.close();

  return 0;
}

参考:OpenVDB 论坛

于 2016-03-17T19:04:41.540 回答