Операции трансформации и CSG на сетке в OpenVDB

OpenVDB кажется действительно удивительным, а адресация узлов очень умной. Есть некоторые операции, которые я не понимаю, в частности операции CSG. Это пример кода. В качестве входных данных он принимает два аргумента:

  • входной файл vdb только с одной сеткой, представляющий набор уровней, созданный начиная с треугольной сетки,
  • вывод vdb, в котором хранятся результаты операций.

Алгоритм должен принимать входные данные,

  1. создает deepCopy в gridA
  2. создает deepCopy в gridB
  3. вращает gridB вдоль оси Y M_PI/4.0f
  4. выполняет csgUnion между gridA и gridB
  5. сохраняет все сетки в выходной файл VDB.

Я пытаюсь использовать сетки VDB в качестве контейнера данных вместо алгоритма классического дерева, для физического моделирования, которое требует высокого уровня детализации при столкновениях.

Я понимаю концепцию преобразования между мировыми координатами и координатами сетки, но я не могу понять, как выполнить преобразование данных внутри дерева, например, перевести или повернуть наборы уровней, как жесткий объект. В этом примере, я думаю, я только меняю трансформацию между миром и решеткой.

Это результат (то же самое для уровня и громкости): gridA должна быть исходной загруженной сеткой Начальная сетка gridB - это сетка, повернутая на 45 градусов, и на самом деле это Сформирована сетка, кажется, что вращение выполняется... результат сетки с объединением... но не повезло нет окончательного результата?

Есть ли у вас предложения?

Прикреплено: один пример и ссылка на ССЫЛКУ УДАЛЕНО, которую я использую (извините, это 133 МБ...)

#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 ответ

Решение

Решение моего ответа, благодаря поддержке VDB на форуме OpenVDB:

  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

Другие вопросы по тегам