forked from bartvdbraak/blender
Cleanup: Remove unused/unecessary OpenVDB C API
This commit uses OpenVDB more directly for the voxel remesher, without the extra indirection of copying to a Blender API. This makes the code simpler, shorter, and easier to understand (though I didn't observe any performance improvement). This also removes the rest of the unused and undocumented OpenVDB C API, which was written when Blender's code didn't really use C++, and doesn't serve a purpose anymore. Those features will be implemented as nodes in the future anyway (see D12100). Differential Revision: https://developer.blender.org/D12097
This commit is contained in:
parent
77187718e4
commit
67d56eb71e
@ -20,7 +20,6 @@
|
||||
|
||||
set(INC
|
||||
.
|
||||
intern
|
||||
../guardedalloc
|
||||
)
|
||||
|
||||
@ -42,14 +41,7 @@ if(WITH_OPENVDB)
|
||||
)
|
||||
|
||||
list(APPEND SRC
|
||||
intern/openvdb_level_set.cc
|
||||
intern/openvdb_transform.cc
|
||||
openvdb_capi.cc
|
||||
openvdb_util.cc
|
||||
|
||||
intern/openvdb_level_set.h
|
||||
intern/openvdb_transform.h
|
||||
openvdb_util.h
|
||||
)
|
||||
|
||||
list(APPEND LIB
|
||||
|
@ -1,173 +0,0 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2015 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "openvdb_level_set.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "openvdb/tools/Composite.h"
|
||||
#include "openvdb_capi.h"
|
||||
#include "openvdb_util.h"
|
||||
|
||||
OpenVDBLevelSet::OpenVDBLevelSet()
|
||||
{
|
||||
openvdb::initialize();
|
||||
}
|
||||
|
||||
OpenVDBLevelSet::~OpenVDBLevelSet()
|
||||
{
|
||||
}
|
||||
|
||||
void OpenVDBLevelSet::mesh_to_level_set(const float *vertices,
|
||||
const int *faces,
|
||||
const int totvertices,
|
||||
const int totfaces,
|
||||
const openvdb::math::Transform::Ptr &xform)
|
||||
{
|
||||
std::vector<openvdb::Vec3s> points(totvertices);
|
||||
std::vector<openvdb::Vec3I> triangles(totfaces);
|
||||
std::vector<openvdb::Vec4I> quads;
|
||||
|
||||
for (int i = 0; i < totvertices; i++) {
|
||||
points[i] = openvdb::Vec3s(vertices[i * 3], vertices[i * 3 + 1], vertices[i * 3 + 2]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < totfaces; i++) {
|
||||
triangles[i] = openvdb::Vec3I(faces[i * 3], faces[i * 3 + 1], faces[i * 3 + 2]);
|
||||
}
|
||||
|
||||
this->grid = openvdb::tools::meshToLevelSet<openvdb::FloatGrid>(
|
||||
*xform, points, triangles, quads, 1);
|
||||
}
|
||||
|
||||
void OpenVDBLevelSet::volume_to_mesh(OpenVDBVolumeToMeshData *mesh,
|
||||
const double isovalue,
|
||||
const double adaptivity,
|
||||
const bool relax_disoriented_triangles)
|
||||
{
|
||||
std::vector<openvdb::Vec3s> out_points;
|
||||
std::vector<openvdb::Vec4I> out_quads;
|
||||
std::vector<openvdb::Vec3I> out_tris;
|
||||
openvdb::tools::volumeToMesh<openvdb::FloatGrid>(*this->grid,
|
||||
out_points,
|
||||
out_tris,
|
||||
out_quads,
|
||||
isovalue,
|
||||
adaptivity,
|
||||
relax_disoriented_triangles);
|
||||
mesh->vertices = (float *)MEM_malloc_arrayN(out_points.size(), sizeof(float[3]), __func__);
|
||||
mesh->quads = (int *)MEM_malloc_arrayN(out_quads.size(), sizeof(int[4]), __func__);
|
||||
mesh->triangles = NULL;
|
||||
if (out_tris.size() > 0) {
|
||||
mesh->triangles = (int *)MEM_malloc_arrayN(out_tris.size(), sizeof(int[3]), __func__);
|
||||
}
|
||||
|
||||
mesh->totvertices = out_points.size();
|
||||
mesh->tottriangles = out_tris.size();
|
||||
mesh->totquads = out_quads.size();
|
||||
|
||||
for (size_t i = 0; i < out_points.size(); i++) {
|
||||
mesh->vertices[i * 3] = out_points[i].x();
|
||||
mesh->vertices[i * 3 + 1] = out_points[i].y();
|
||||
mesh->vertices[i * 3 + 2] = out_points[i].z();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < out_quads.size(); i++) {
|
||||
mesh->quads[i * 4] = out_quads[i].x();
|
||||
mesh->quads[i * 4 + 1] = out_quads[i].y();
|
||||
mesh->quads[i * 4 + 2] = out_quads[i].z();
|
||||
mesh->quads[i * 4 + 3] = out_quads[i].w();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < out_tris.size(); i++) {
|
||||
mesh->triangles[i * 3] = out_tris[i].x();
|
||||
mesh->triangles[i * 3 + 1] = out_tris[i].y();
|
||||
mesh->triangles[i * 3 + 2] = out_tris[i].z();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenVDBLevelSet::filter(OpenVDBLevelSet_FilterType filter_type,
|
||||
int width,
|
||||
float distance,
|
||||
OpenVDBLevelSet_FilterBias filter_bias)
|
||||
{
|
||||
|
||||
if (!this->grid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->grid->getGridClass() != openvdb::GRID_LEVEL_SET) {
|
||||
return;
|
||||
}
|
||||
|
||||
openvdb::tools::LevelSetFilter<openvdb::FloatGrid> filter(*this->grid);
|
||||
filter.setSpatialScheme((openvdb::math::BiasedGradientScheme)filter_bias);
|
||||
switch (filter_type) {
|
||||
case OPENVDB_LEVELSET_FILTER_GAUSSIAN:
|
||||
filter.gaussian(width);
|
||||
break;
|
||||
case OPENVDB_LEVELSET_FILTER_MEDIAN:
|
||||
filter.median(width);
|
||||
break;
|
||||
case OPENVDB_LEVELSET_FILTER_MEAN:
|
||||
filter.mean(width);
|
||||
break;
|
||||
case OPENVDB_LEVELSET_FILTER_MEAN_CURVATURE:
|
||||
filter.meanCurvature();
|
||||
break;
|
||||
case OPENVDB_LEVELSET_FILTER_LAPLACIAN:
|
||||
filter.laplacian();
|
||||
break;
|
||||
case OPENVDB_LEVELSET_FILTER_DILATE:
|
||||
filter.offset(distance);
|
||||
break;
|
||||
case OPENVDB_LEVELSET_FILTER_ERODE:
|
||||
filter.offset(distance);
|
||||
break;
|
||||
case OPENVDB_LEVELSET_FILTER_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
openvdb::FloatGrid::Ptr OpenVDBLevelSet::CSG_operation_apply(
|
||||
const openvdb::FloatGrid::Ptr &gridA,
|
||||
const openvdb::FloatGrid::Ptr &gridB,
|
||||
OpenVDBLevelSet_CSGOperation operation)
|
||||
{
|
||||
switch (operation) {
|
||||
case OPENVDB_LEVELSET_CSG_UNION:
|
||||
openvdb::tools::csgUnion(*gridA, *gridB);
|
||||
break;
|
||||
case OPENVDB_LEVELSET_CSG_DIFFERENCE:
|
||||
openvdb::tools::csgDifference(*gridA, *gridB);
|
||||
break;
|
||||
case OPENVDB_LEVELSET_CSG_INTERSECTION:
|
||||
openvdb::tools::csgIntersection(*gridA, *gridB);
|
||||
break;
|
||||
}
|
||||
|
||||
return gridA;
|
||||
}
|
||||
|
||||
const openvdb::FloatGrid::Ptr &OpenVDBLevelSet::get_grid()
|
||||
{
|
||||
return this->grid;
|
||||
}
|
||||
|
||||
void OpenVDBLevelSet::set_grid(const openvdb::FloatGrid::Ptr &grid)
|
||||
{
|
||||
this->grid = grid;
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2015 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __OPENVDB_LEVEL_SET_H__
|
||||
#define __OPENVDB_LEVEL_SET_H__
|
||||
|
||||
#include "openvdb_capi.h"
|
||||
#include <openvdb/math/FiniteDifference.h>
|
||||
#include <openvdb/openvdb.h>
|
||||
#include <openvdb/tools/GridTransformer.h>
|
||||
#include <openvdb/tools/LevelSetFilter.h>
|
||||
#include <openvdb/tools/MeshToVolume.h>
|
||||
#include <openvdb/tools/VolumeToMesh.h>
|
||||
|
||||
struct OpenVDBLevelSet {
|
||||
private:
|
||||
openvdb::FloatGrid::Ptr grid;
|
||||
|
||||
public:
|
||||
OpenVDBLevelSet();
|
||||
~OpenVDBLevelSet();
|
||||
const openvdb::FloatGrid::Ptr &get_grid();
|
||||
void set_grid(const openvdb::FloatGrid::Ptr &grid);
|
||||
|
||||
void mesh_to_level_set(const float *vertices,
|
||||
const int *faces,
|
||||
const int totvertices,
|
||||
const int totfaces,
|
||||
const openvdb::math::Transform::Ptr &transform);
|
||||
|
||||
void volume_to_mesh(struct OpenVDBVolumeToMeshData *mesh,
|
||||
const double isovalue,
|
||||
const double adaptivity,
|
||||
const bool relax_disoriented_triangles);
|
||||
void filter(OpenVDBLevelSet_FilterType filter_type,
|
||||
int width,
|
||||
float distance,
|
||||
OpenVDBLevelSet_FilterBias filter_bias);
|
||||
openvdb::FloatGrid::Ptr CSG_operation_apply(const openvdb::FloatGrid::Ptr &gridA,
|
||||
const openvdb::FloatGrid::Ptr &gridB,
|
||||
OpenVDBLevelSet_CSGOperation operation);
|
||||
};
|
||||
|
||||
#endif /* __OPENVDB_LEVEL_SET_H__ */
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2015 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "openvdb_transform.h"
|
||||
|
||||
OpenVDBTransform::OpenVDBTransform()
|
||||
{
|
||||
}
|
||||
|
||||
OpenVDBTransform::~OpenVDBTransform()
|
||||
{
|
||||
}
|
||||
|
||||
void OpenVDBTransform::create_linear_transform(double voxel_size)
|
||||
{
|
||||
this->transform = openvdb::math::Transform::createLinearTransform(voxel_size);
|
||||
}
|
||||
|
||||
const openvdb::math::Transform::Ptr &OpenVDBTransform::get_transform()
|
||||
{
|
||||
return this->transform;
|
||||
}
|
||||
|
||||
void OpenVDBTransform::set_transform(const openvdb::math::Transform::Ptr &transform)
|
||||
{
|
||||
this->transform = transform;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2015 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef OPENVDB_TRANSFORM_H
|
||||
#define OPENVDB_TRANSFORM_H
|
||||
|
||||
#include <openvdb/openvdb.h>
|
||||
|
||||
struct OpenVDBTransform {
|
||||
private:
|
||||
openvdb::math::Transform::Ptr transform;
|
||||
|
||||
public:
|
||||
OpenVDBTransform();
|
||||
~OpenVDBTransform();
|
||||
void create_linear_transform(double voxel_size);
|
||||
const openvdb::math::Transform::Ptr &get_transform();
|
||||
void set_transform(const openvdb::math::Transform::Ptr &transform);
|
||||
};
|
||||
|
||||
#endif // OPENVDB_TRANSFORM_H
|
@ -18,151 +18,9 @@
|
||||
*/
|
||||
|
||||
#include "openvdb_capi.h"
|
||||
#include "openvdb_level_set.h"
|
||||
#include "openvdb_transform.h"
|
||||
#include "openvdb_util.h"
|
||||
#include <openvdb/openvdb.h>
|
||||
|
||||
int OpenVDB_getVersionHex()
|
||||
{
|
||||
return openvdb::OPENVDB_LIBRARY_VERSION;
|
||||
}
|
||||
|
||||
OpenVDBLevelSet *OpenVDBLevelSet_create(bool initGrid, OpenVDBTransform *xform)
|
||||
{
|
||||
OpenVDBLevelSet *level_set = new OpenVDBLevelSet();
|
||||
if (initGrid) {
|
||||
openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create();
|
||||
grid->setGridClass(openvdb::GRID_LEVEL_SET);
|
||||
if (xform) {
|
||||
grid->setTransform(xform->get_transform());
|
||||
}
|
||||
level_set->set_grid(grid);
|
||||
}
|
||||
return level_set;
|
||||
}
|
||||
|
||||
OpenVDBTransform *OpenVDBTransform_create()
|
||||
{
|
||||
return new OpenVDBTransform();
|
||||
}
|
||||
|
||||
void OpenVDBTransform_free(OpenVDBTransform *transform)
|
||||
{
|
||||
delete transform;
|
||||
}
|
||||
|
||||
void OpenVDBTransform_create_linear_transform(OpenVDBTransform *transform, double voxel_size)
|
||||
{
|
||||
transform->create_linear_transform(voxel_size);
|
||||
}
|
||||
|
||||
void OpenVDBLevelSet_free(OpenVDBLevelSet *level_set)
|
||||
{
|
||||
delete level_set;
|
||||
}
|
||||
|
||||
void OpenVDBLevelSet_mesh_to_level_set(struct OpenVDBLevelSet *level_set,
|
||||
const float *vertices,
|
||||
const int *faces,
|
||||
const int totvertices,
|
||||
const int totfaces,
|
||||
OpenVDBTransform *xform)
|
||||
{
|
||||
level_set->mesh_to_level_set(vertices, faces, totvertices, totfaces, xform->get_transform());
|
||||
}
|
||||
|
||||
void OpenVDBLevelSet_mesh_to_level_set_transform(struct OpenVDBLevelSet *level_set,
|
||||
const float *vertices,
|
||||
const int *faces,
|
||||
const int totvertices,
|
||||
const int totfaces,
|
||||
OpenVDBTransform *transform)
|
||||
{
|
||||
level_set->mesh_to_level_set(vertices, faces, totvertices, totfaces, transform->get_transform());
|
||||
}
|
||||
|
||||
void OpenVDBLevelSet_volume_to_mesh(struct OpenVDBLevelSet *level_set,
|
||||
struct OpenVDBVolumeToMeshData *mesh,
|
||||
const double isovalue,
|
||||
const double adaptivity,
|
||||
const bool relax_disoriented_triangles)
|
||||
{
|
||||
level_set->volume_to_mesh(mesh, isovalue, adaptivity, relax_disoriented_triangles);
|
||||
}
|
||||
|
||||
void OpenVDBLevelSet_filter(struct OpenVDBLevelSet *level_set,
|
||||
OpenVDBLevelSet_FilterType filter_type,
|
||||
int width,
|
||||
float distance,
|
||||
OpenVDBLevelSet_FilterBias bias)
|
||||
{
|
||||
level_set->filter(filter_type, width, distance, bias);
|
||||
}
|
||||
|
||||
void OpenVDBLevelSet_CSG_operation(struct OpenVDBLevelSet *out,
|
||||
struct OpenVDBLevelSet *gridA,
|
||||
struct OpenVDBLevelSet *gridB,
|
||||
OpenVDBLevelSet_CSGOperation operation)
|
||||
{
|
||||
openvdb::FloatGrid::Ptr grid = out->CSG_operation_apply(
|
||||
gridA->get_grid(), gridB->get_grid(), operation);
|
||||
out->set_grid(grid);
|
||||
}
|
||||
|
||||
OpenVDBLevelSet *OpenVDBLevelSet_transform_and_resample(struct OpenVDBLevelSet *level_setA,
|
||||
struct OpenVDBLevelSet *level_setB,
|
||||
char sampler,
|
||||
float isolevel)
|
||||
{
|
||||
openvdb::FloatGrid::Ptr sourceGrid = level_setA->get_grid();
|
||||
openvdb::FloatGrid::Ptr targetGrid = level_setB->get_grid()->deepCopy();
|
||||
|
||||
const openvdb::math::Transform &sourceXform = sourceGrid->transform(),
|
||||
&targetXform = targetGrid->transform();
|
||||
|
||||
// Compute a source grid to target grid transform.
|
||||
// (For this example, we assume that both grids' transforms are linear,
|
||||
// so that they can be represented as 4 x 4 matrices.)
|
||||
openvdb::Mat4R xform = sourceXform.baseMap()->getAffineMap()->getMat4() *
|
||||
targetXform.baseMap()->getAffineMap()->getMat4().inverse();
|
||||
|
||||
// Create the transformer.
|
||||
openvdb::tools::GridTransformer transformer(xform);
|
||||
|
||||
switch (sampler) {
|
||||
case OPENVDB_LEVELSET_GRIDSAMPLER_POINT:
|
||||
// Resample using nearest-neighbor interpolation.
|
||||
transformer.transformGrid<openvdb::tools::PointSampler, openvdb::FloatGrid>(*sourceGrid,
|
||||
*targetGrid);
|
||||
// Prune the target tree for optimal sparsity.
|
||||
targetGrid->tree().prune();
|
||||
break;
|
||||
|
||||
case OPENVDB_LEVELSET_GRIDSAMPLER_BOX:
|
||||
// Resample using trilinear interpolation.
|
||||
transformer.transformGrid<openvdb::tools::BoxSampler, openvdb::FloatGrid>(*sourceGrid,
|
||||
*targetGrid);
|
||||
// Prune the target tree for optimal sparsity.
|
||||
targetGrid->tree().prune();
|
||||
break;
|
||||
|
||||
case OPENVDB_LEVELSET_GRIDSAMPLER_QUADRATIC:
|
||||
// Resample using triquadratic interpolation.
|
||||
transformer.transformGrid<openvdb::tools::QuadraticSampler, openvdb::FloatGrid>(*sourceGrid,
|
||||
*targetGrid);
|
||||
// Prune the target tree for optimal sparsity.
|
||||
targetGrid->tree().prune();
|
||||
break;
|
||||
|
||||
case OPENVDB_LEVELSET_GRIDSAMPLER_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
targetGrid = openvdb::tools::levelSetRebuild(*targetGrid, isolevel, 1.0f);
|
||||
openvdb::tools::pruneLevelSet(targetGrid->tree());
|
||||
|
||||
OpenVDBLevelSet *level_set = OpenVDBLevelSet_create(false, NULL);
|
||||
level_set->set_grid(targetGrid);
|
||||
|
||||
return level_set;
|
||||
}
|
||||
|
@ -24,124 +24,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Level Set Filters */
|
||||
typedef enum OpenVDBLevelSet_FilterType {
|
||||
OPENVDB_LEVELSET_FILTER_NONE = 0,
|
||||
OPENVDB_LEVELSET_FILTER_GAUSSIAN = 1,
|
||||
OPENVDB_LEVELSET_FILTER_MEAN = 2,
|
||||
OPENVDB_LEVELSET_FILTER_MEDIAN = 3,
|
||||
OPENVDB_LEVELSET_FILTER_MEAN_CURVATURE = 4,
|
||||
OPENVDB_LEVELSET_FILTER_LAPLACIAN = 5,
|
||||
OPENVDB_LEVELSET_FILTER_DILATE = 6,
|
||||
OPENVDB_LEVELSET_FILTER_ERODE = 7,
|
||||
} OpenVDBLevelSet_FilterType;
|
||||
|
||||
typedef enum OpenVDBLevelSet_FilterBias {
|
||||
OPENVDB_LEVELSET_FIRST_BIAS = 0,
|
||||
OPENVDB_LEVELSET_SECOND_BIAS,
|
||||
OPENVDB_LEVELSET_THIRD_BIAS,
|
||||
OPENVDB_LEVELSET_WENO5_BIAS,
|
||||
OPENVDB_LEVELSET_HJWENO5_BIAS,
|
||||
} OpenVDBLevelSet_FilterBias;
|
||||
|
||||
/* Level Set CSG Operations */
|
||||
typedef enum OpenVDBLevelSet_CSGOperation {
|
||||
OPENVDB_LEVELSET_CSG_UNION = 0,
|
||||
OPENVDB_LEVELSET_CSG_DIFFERENCE = 1,
|
||||
OPENVDB_LEVELSET_CSG_INTERSECTION = 2,
|
||||
} OpenVDBLevelSet_CSGOperation;
|
||||
|
||||
typedef enum OpenVDBLevelSet_GridSampler {
|
||||
OPENVDB_LEVELSET_GRIDSAMPLER_NONE = 0,
|
||||
OPENVDB_LEVELSET_GRIDSAMPLER_POINT = 1,
|
||||
OPENVDB_LEVELSET_GRIDSAMPLER_BOX = 2,
|
||||
OPENVDB_LEVELSET_GRIDSAMPLER_QUADRATIC = 3,
|
||||
} OpenVDBLevelSet_Gridsampler;
|
||||
|
||||
struct OpenVDBTransform;
|
||||
struct OpenVDBLevelSet;
|
||||
|
||||
struct OpenVDBVolumeToMeshData {
|
||||
int tottriangles;
|
||||
int totquads;
|
||||
int totvertices;
|
||||
|
||||
float *vertices;
|
||||
int *quads;
|
||||
int *triangles;
|
||||
};
|
||||
|
||||
struct OpenVDBRemeshData {
|
||||
float *verts;
|
||||
int *faces;
|
||||
int totfaces;
|
||||
int totverts;
|
||||
|
||||
float *out_verts;
|
||||
int *out_faces;
|
||||
int *out_tris;
|
||||
int out_totverts;
|
||||
int out_totfaces;
|
||||
int out_tottris;
|
||||
int filter_type;
|
||||
enum OpenVDBLevelSet_FilterType filter_bias;
|
||||
enum OpenVDBLevelSet_FilterBias filter_width; /* Parameter for gaussian, median, mean. */
|
||||
|
||||
float voxel_size;
|
||||
float isovalue;
|
||||
float adaptivity;
|
||||
int relax_disoriented_triangles;
|
||||
};
|
||||
|
||||
int OpenVDB_getVersionHex(void);
|
||||
|
||||
enum {
|
||||
VEC_INVARIANT = 0,
|
||||
VEC_COVARIANT = 1,
|
||||
VEC_COVARIANT_NORMALIZE = 2,
|
||||
VEC_CONTRAVARIANT_RELATIVE = 3,
|
||||
VEC_CONTRAVARIANT_ABSOLUTE = 4,
|
||||
};
|
||||
|
||||
struct OpenVDBTransform *OpenVDBTransform_create(void);
|
||||
void OpenVDBTransform_free(struct OpenVDBTransform *transform);
|
||||
void OpenVDBTransform_create_linear_transform(struct OpenVDBTransform *transform,
|
||||
double voxel_size);
|
||||
|
||||
struct OpenVDBLevelSet *OpenVDBLevelSet_create(bool initGrid, struct OpenVDBTransform *xform);
|
||||
void OpenVDBLevelSet_free(struct OpenVDBLevelSet *level_set);
|
||||
void OpenVDBLevelSet_mesh_to_level_set(struct OpenVDBLevelSet *level_set,
|
||||
const float *vertices,
|
||||
const int *faces,
|
||||
const int totvertices,
|
||||
const int totfaces,
|
||||
struct OpenVDBTransform *xform);
|
||||
void OpenVDBLevelSet_mesh_to_level_set_transform(struct OpenVDBLevelSet *level_set,
|
||||
const float *vertices,
|
||||
const int *faces,
|
||||
const int totvertices,
|
||||
const int totfaces,
|
||||
struct OpenVDBTransform *transform);
|
||||
void OpenVDBLevelSet_volume_to_mesh(struct OpenVDBLevelSet *level_set,
|
||||
struct OpenVDBVolumeToMeshData *mesh,
|
||||
const double isovalue,
|
||||
const double adaptivity,
|
||||
const bool relax_disoriented_triangles);
|
||||
void OpenVDBLevelSet_filter(struct OpenVDBLevelSet *level_set,
|
||||
OpenVDBLevelSet_FilterType filter_type,
|
||||
int width,
|
||||
float distance,
|
||||
OpenVDBLevelSet_FilterBias bias);
|
||||
void OpenVDBLevelSet_CSG_operation(struct OpenVDBLevelSet *out,
|
||||
struct OpenVDBLevelSet *gridA,
|
||||
struct OpenVDBLevelSet *gridB,
|
||||
OpenVDBLevelSet_CSGOperation operation);
|
||||
|
||||
struct OpenVDBLevelSet *OpenVDBLevelSet_transform_and_resample(struct OpenVDBLevelSet *level_setA,
|
||||
struct OpenVDBLevelSet *level_setB,
|
||||
char sampler,
|
||||
float isolevel);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2015 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "openvdb_util.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
ScopeTimer::ScopeTimer(const std::string &message) : m_message(message), m_timer()
|
||||
{
|
||||
}
|
||||
|
||||
ScopeTimer::~ScopeTimer()
|
||||
{
|
||||
#if OPENVDB_LIBRARY_MAJOR_VERSION_NUMBER >= 7
|
||||
double delta = m_timer.milliseconds();
|
||||
#else
|
||||
double delta = m_timer.delta(); /* Deprecated in OpenVDB 7. */
|
||||
#endif
|
||||
std::printf("%s: %fms\n", m_message.c_str(), delta);
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2015 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __OPENVDB_UTIL_H__
|
||||
#define __OPENVDB_UTIL_H__
|
||||
|
||||
#include <openvdb/openvdb.h>
|
||||
#include <openvdb/util/CpuTimer.h>
|
||||
|
||||
#define CATCH_KEYERROR \
|
||||
catch (const openvdb::KeyError &e) \
|
||||
{ \
|
||||
std::cerr << e.what() << '\n'; \
|
||||
}
|
||||
|
||||
//#define DEBUG_TIME
|
||||
|
||||
/* A utility class which prints the time elapsed during its lifetime, useful for
|
||||
* e.g. timing the overall execution time of a function */
|
||||
class ScopeTimer {
|
||||
std::string m_message;
|
||||
openvdb::util::CpuTimer m_timer;
|
||||
|
||||
public:
|
||||
ScopeTimer(const std::string &message);
|
||||
~ScopeTimer();
|
||||
};
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
# define Timer(x) ScopeTimer prof(x);
|
||||
#else
|
||||
# define Timer(x)
|
||||
#endif
|
||||
|
||||
#endif /* __OPENVDB_UTIL_H__ */
|
@ -23,10 +23,6 @@
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
# include "openvdb_capi.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_float3.hh"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
@ -48,7 +49,9 @@
|
||||
#include "bmesh_tools.h"
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
# include "openvdb_capi.h"
|
||||
# include <openvdb/openvdb.h>
|
||||
# include <openvdb/tools/MeshToVolume.h>
|
||||
# include <openvdb/tools/VolumeToMesh.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_QUADRIFLOW
|
||||
@ -58,6 +61,8 @@
|
||||
using blender::Array;
|
||||
using blender::float3;
|
||||
using blender::IndexRange;
|
||||
using blender::MutableSpan;
|
||||
using blender::Span;
|
||||
|
||||
#ifdef WITH_QUADRIFLOW
|
||||
static Mesh *remesh_quadriflow(const Mesh *input_mesh,
|
||||
@ -192,92 +197,81 @@ Mesh *BKE_mesh_remesh_quadriflow(const Mesh *mesh,
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
static struct OpenVDBLevelSet *remesh_voxel_level_set_create(const Mesh *mesh,
|
||||
struct OpenVDBTransform *transform)
|
||||
static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh,
|
||||
const float voxel_size)
|
||||
{
|
||||
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
||||
MVertTri *verttri = (MVertTri *)MEM_callocN(
|
||||
sizeof(*verttri) * BKE_mesh_runtime_looptri_len(mesh), "remesh_looptri");
|
||||
BKE_mesh_runtime_verttri_from_looptri(
|
||||
verttri, mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(mesh));
|
||||
Span<MLoop> mloop{mesh->mloop, mesh->totloop};
|
||||
Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh),
|
||||
BKE_mesh_runtime_looptri_len(mesh)};
|
||||
|
||||
const int totfaces = BKE_mesh_runtime_looptri_len(mesh);
|
||||
const int totverts = mesh->totvert;
|
||||
Array<float3> verts(totverts);
|
||||
Array<int> faces(totfaces * 3);
|
||||
std::vector<openvdb::Vec3s> points(mesh->totvert);
|
||||
std::vector<openvdb::Vec3I> triangles(looptris.size());
|
||||
|
||||
for (const int i : IndexRange(totverts)) {
|
||||
verts[i] = mesh->mvert[i].co;
|
||||
for (const int i : IndexRange(mesh->totvert)) {
|
||||
const float3 co = mesh->mvert[i].co;
|
||||
points[i] = openvdb::Vec3s(co.x, co.y, co.z);
|
||||
}
|
||||
|
||||
for (const int i : IndexRange(totfaces)) {
|
||||
MVertTri &vt = verttri[i];
|
||||
faces[i * 3] = vt.tri[0];
|
||||
faces[i * 3 + 1] = vt.tri[1];
|
||||
faces[i * 3 + 2] = vt.tri[2];
|
||||
for (const int i : IndexRange(looptris.size())) {
|
||||
const MLoopTri &loop_tri = looptris[i];
|
||||
triangles[i] = openvdb::Vec3I(
|
||||
mloop[loop_tri.tri[0]].v, mloop[loop_tri.tri[1]].v, mloop[loop_tri.tri[2]].v);
|
||||
}
|
||||
|
||||
struct OpenVDBLevelSet *level_set = OpenVDBLevelSet_create(false, nullptr);
|
||||
OpenVDBLevelSet_mesh_to_level_set(
|
||||
level_set, (const float *)verts.data(), faces.data(), totverts, totfaces, transform);
|
||||
openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(
|
||||
voxel_size);
|
||||
openvdb::FloatGrid::Ptr grid = openvdb::tools::meshToLevelSet<openvdb::FloatGrid>(
|
||||
*transform, points, triangles, 1.0f);
|
||||
|
||||
MEM_freeN(verttri);
|
||||
|
||||
return level_set;
|
||||
return grid;
|
||||
}
|
||||
|
||||
static Mesh *remesh_voxel_volume_to_mesh(struct OpenVDBLevelSet *level_set,
|
||||
double isovalue,
|
||||
double adaptivity,
|
||||
bool relax_disoriented_triangles)
|
||||
static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set_grid,
|
||||
const float isovalue,
|
||||
const float adaptivity,
|
||||
const bool relax_disoriented_triangles)
|
||||
{
|
||||
struct OpenVDBVolumeToMeshData output_mesh;
|
||||
OpenVDBLevelSet_volume_to_mesh(
|
||||
level_set, &output_mesh, isovalue, adaptivity, relax_disoriented_triangles);
|
||||
std::vector<openvdb::Vec3s> vertices;
|
||||
std::vector<openvdb::Vec4I> quads;
|
||||
std::vector<openvdb::Vec3I> tris;
|
||||
openvdb::tools::volumeToMesh<openvdb::FloatGrid>(
|
||||
*level_set_grid, vertices, tris, quads, isovalue, adaptivity, relax_disoriented_triangles);
|
||||
|
||||
Mesh *mesh = BKE_mesh_new_nomain(output_mesh.totvertices,
|
||||
0,
|
||||
0,
|
||||
(output_mesh.totquads * 4) + (output_mesh.tottriangles * 3),
|
||||
output_mesh.totquads + output_mesh.tottriangles);
|
||||
Mesh *mesh = BKE_mesh_new_nomain(
|
||||
vertices.size(), 0, 0, quads.size() * 4 + tris.size() * 3, quads.size() + tris.size());
|
||||
MutableSpan<MVert> mverts{mesh->mvert, mesh->totvert};
|
||||
MutableSpan<MLoop> mloops{mesh->mloop, mesh->totloop};
|
||||
MutableSpan<MPoly> mpolys{mesh->mpoly, mesh->totpoly};
|
||||
|
||||
for (const int i : IndexRange(output_mesh.totvertices)) {
|
||||
copy_v3_v3(mesh->mvert[i].co, &output_mesh.vertices[i * 3]);
|
||||
for (const int i : mverts.index_range()) {
|
||||
copy_v3_v3(mverts[i].co, float3(vertices[i].x(), vertices[i].y(), vertices[i].z()));
|
||||
}
|
||||
|
||||
for (const int i : IndexRange(output_mesh.totquads)) {
|
||||
MPoly &poly = mesh->mpoly[i];
|
||||
for (const int i : IndexRange(quads.size())) {
|
||||
MPoly &poly = mpolys[i];
|
||||
const int loopstart = i * 4;
|
||||
poly.loopstart = loopstart;
|
||||
poly.totloop = 4;
|
||||
mesh->mloop[loopstart].v = output_mesh.quads[loopstart];
|
||||
mesh->mloop[loopstart + 1].v = output_mesh.quads[loopstart + 1];
|
||||
mesh->mloop[loopstart + 2].v = output_mesh.quads[loopstart + 2];
|
||||
mesh->mloop[loopstart + 3].v = output_mesh.quads[loopstart + 3];
|
||||
mloops[loopstart].v = quads[i][0];
|
||||
mloops[loopstart + 1].v = quads[i][3];
|
||||
mloops[loopstart + 2].v = quads[i][2];
|
||||
mloops[loopstart + 3].v = quads[i][1];
|
||||
}
|
||||
|
||||
const int triangle_poly_start = output_mesh.totquads;
|
||||
const int triangle_loop_start = output_mesh.totquads * 4;
|
||||
for (const int i : IndexRange(output_mesh.tottriangles)) {
|
||||
MPoly &poly = mesh->mpoly[triangle_poly_start + i];
|
||||
const int triangle_loop_start = quads.size() * 4;
|
||||
for (const int i : IndexRange(tris.size())) {
|
||||
MPoly &poly = mpolys[quads.size() + i];
|
||||
const int loopstart = triangle_loop_start + i * 3;
|
||||
poly.loopstart = loopstart;
|
||||
poly.totloop = 3;
|
||||
mesh->mloop[loopstart].v = output_mesh.triangles[i * 3 + 2];
|
||||
mesh->mloop[loopstart + 1].v = output_mesh.triangles[i * 3 + 1];
|
||||
mesh->mloop[loopstart + 2].v = output_mesh.triangles[i * 3];
|
||||
mloops[loopstart].v = tris[i][2];
|
||||
mloops[loopstart + 1].v = tris[i][1];
|
||||
mloops[loopstart + 2].v = tris[i][0];
|
||||
}
|
||||
|
||||
BKE_mesh_calc_edges(mesh, false, false);
|
||||
BKE_mesh_calc_normals(mesh);
|
||||
|
||||
MEM_freeN(output_mesh.quads);
|
||||
MEM_freeN(output_mesh.vertices);
|
||||
|
||||
if (output_mesh.tottriangles > 0) {
|
||||
MEM_freeN(output_mesh.triangles);
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
#endif
|
||||
@ -288,14 +282,8 @@ Mesh *BKE_mesh_remesh_voxel(const Mesh *mesh,
|
||||
const float isovalue)
|
||||
{
|
||||
#ifdef WITH_OPENVDB
|
||||
struct OpenVDBTransform *xform = OpenVDBTransform_create();
|
||||
OpenVDBTransform_create_linear_transform(xform, (double)voxel_size);
|
||||
struct OpenVDBLevelSet *level_set = remesh_voxel_level_set_create(mesh, xform);
|
||||
Mesh *new_mesh = remesh_voxel_volume_to_mesh(
|
||||
level_set, (double)isovalue, (double)adaptivity, false);
|
||||
OpenVDBLevelSet_free(level_set);
|
||||
OpenVDBTransform_free(xform);
|
||||
return new_mesh;
|
||||
openvdb::FloatGrid::Ptr level_set = remesh_voxel_level_set_create(mesh, voxel_size);
|
||||
return remesh_voxel_volume_to_mesh(level_set, isovalue, adaptivity, false);
|
||||
#else
|
||||
UNUSED_VARS(mesh, voxel_size, adaptivity, isovalue);
|
||||
return nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user