diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2019-08-14 18:46:20 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2019-08-14 19:13:56 +0300 |
commit | 9ac3964be198a9bcbbcf2cda2ecd99047eae560f (patch) | |
tree | 714d82a675e228e2da4cafa73956d0da60e5f0ca /intern/openvdb/openvdb_capi.cc | |
parent | 5ca5357e08f25b1fcda95c084ac24722c5177b5e (diff) |
OpenVDB: mesh/level set conversion, filters and CSG operations
This code is needed to implement the Voxel Remesher as well as other features like a better remesh modifier with filters and CSG operations.
Done by Martin Felke and Pablo Dobarro
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D5364
Diffstat (limited to 'intern/openvdb/openvdb_capi.cc')
-rw-r--r-- | intern/openvdb/openvdb_capi.cc | 152 |
1 files changed, 142 insertions, 10 deletions
diff --git a/intern/openvdb/openvdb_capi.cc b/intern/openvdb/openvdb_capi.cc index aff27ee6c62..22d0d20ea4e 100644 --- a/intern/openvdb/openvdb_capi.cc +++ b/intern/openvdb/openvdb_capi.cc @@ -20,16 +20,8 @@ #include "openvdb_capi.h" #include "openvdb_dense_convert.h" #include "openvdb_util.h" - -struct OpenVDBFloatGrid { - int unused; -}; -struct OpenVDBIntGrid { - int unused; -}; -struct OpenVDBVectorGrid { - int unused; -}; +#include "openvdb_level_set.h" +#include "openvdb_transform.h" int OpenVDB_getVersionHex() { @@ -238,3 +230,143 @@ void OpenVDBReader_get_meta_mat4(OpenVDBReader *reader, const char *name, float { reader->mat4sMeta(name, value); } + +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 unsigned int *faces, + const unsigned int totvertices, + const unsigned 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 unsigned int *faces, + const unsigned int totvertices, + const unsigned 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; +} |