OpenVDB中网格上的转换和CSG操作

时间:2016-03-12 14:08:04

标签: c++ tree csg openvdb

OpenVDB看起来真的很棒,节点的寻址非常聪明。有一些我不理解的操作,特别是CSG操作。这是一个示例代码。它需要输入两个参数:

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

算法应该接受输入,

  1. 在gridA
  2. 中创建deepCopy
  3. 在gridB
  4. 中创建deepCopy
  5. 沿着M_PI / 4.0f
  6. 的Y轴旋转gridB
  7. 执行gridA和gridB之间的csgUnion
  8. 将所有网格保存在vdb输出文件中。
  9. 我正在尝试使用VDB网格作为数据容器来代替经典树种算法,用于在碰撞中需要高水平细节的物理模拟。

    我理解世界坐标和网格坐标之间的转换概念,我无法理解的是如何在树内执行数据转换,例如转换或旋转关卡集,如刚性对象。在这个例子中,我认为我只是在改变世界与格子之间的转换。

    这是结果(水平集和音量相同):gridA should be the original loaded grid初始网格gridB is the grid rotated of 45 degrees, and in fact it is格式化网格,似乎执行了旋转... result grid with the union... but no luck...没有最终导致?

    你有什么建议吗?

    附:我正在使用的 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;
    }
    

1 个答案:

答案 0 :(得分:0)

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

  1. 执行初始网格的简单元数据副本
  2. 执行转换(就像我的代码中的旋转一样)
  3. 使用quotes.data.frequency_counts[i].negative = Math.round(negative * -1)+'%'; quotes.data.frequency_counts[i].positive = Math.round(positive)+'%'; 从新转换的网格中的初始网格重新插入数据,选择其中一个插值器(在我的情况下为tools::resampleToMatch)。
  4. 继续csg操作
  5. 仅供参考,执行时间存在极端差异  使用优化标志tools::BoxSample(减少400%的时间)。

    -O3

    参考:OpenVDB Forum