diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2019-04-07 05:08:45 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2019-04-07 05:08:45 +0300 |
commit | 42876e5f2de1f12796ec9d091fc6c5c9e0765f6c (patch) | |
tree | 1124444e9a7fd0d4c6a3b18eca9751210109dfd4 /intern/openvdb | |
parent | ade63efcdf46022b919f280f6f8ed50c63cd7763 (diff) |
OpenVDB: Add Filters and CSG operations to the Level Set C API
I also refactored the voxel remesher code to use the new API.
Diffstat (limited to 'intern/openvdb')
-rw-r--r-- | intern/openvdb/intern/openvdb_level_set.cc | 130 | ||||
-rw-r--r-- | intern/openvdb/intern/openvdb_level_set.h | 23 | ||||
-rw-r--r-- | intern/openvdb/openvdb_capi.cc | 39 | ||||
-rw-r--r-- | intern/openvdb/openvdb_capi.h | 50 |
4 files changed, 239 insertions, 3 deletions
diff --git a/intern/openvdb/intern/openvdb_level_set.cc b/intern/openvdb/intern/openvdb_level_set.cc index dad164e6f85..77dc76dd785 100644 --- a/intern/openvdb/intern/openvdb_level_set.cc +++ b/intern/openvdb/intern/openvdb_level_set.cc @@ -22,6 +22,136 @@ #include "openvdb_util.h" #include "openvdb_capi.h" #include "MEM_guardedalloc.h" +#include "openvdb/tools/Composite.h" + +OpenVDBLevelSet::OpenVDBLevelSet() +{ + openvdb::initialize(); +} + +OpenVDBLevelSet::~OpenVDBLevelSet() +{} + +void OpenVDBLevelSet::OpenVDB_mesh_to_level_set(const float *vertices, const unsigned int *faces, const unsigned int totvertices, + const unsigned int totfaces, const double voxel_size) +{ + std::vector<openvdb::Vec3s> points; + std::vector<openvdb::Vec3I > triangles; + std::vector<openvdb::Vec4I > quads; + std::vector<openvdb::Vec3s> out_points; + std::vector<openvdb::Vec4I > out_quads; + std::vector<openvdb::Vec3I > out_tris; + const openvdb::math::Transform xform; + + for(unsigned int i = 0; i < totvertices; i++) { + openvdb::Vec3s v(vertices[i * 3 ], vertices[i * 3 + 1], vertices[i * 3 + 2]); + points.push_back(v); + } + + for(unsigned int i = 0; i < totfaces; i++) { + openvdb::Vec3I f(faces[i * 3 ], faces[i * 3 + 1], faces[i * 3 + 2]); + triangles.push_back(f); + } + + openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(voxel_size); + this->grid = openvdb::tools::meshToLevelSet<openvdb::FloatGrid>(*transform, points, triangles, quads, 1); +} + +void OpenVDBLevelSet::OpenVDB_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(), 3 * sizeof (float), "openvdb remesher out verts"); + mesh->quads = (unsigned int*)MEM_malloc_arrayN(out_quads.size(), 4 * sizeof (unsigned int), "openvdb remesh out quads"); + mesh->triangles = NULL; + if (out_tris.size() > 0) { + mesh->triangles = (unsigned int*)MEM_malloc_arrayN(out_tris.size(), 3 * sizeof (unsigned int), "openvdb remesh out tris"); + } + + mesh->totvertices = out_points.size(); + mesh->tottriangles = out_tris.size(); + mesh->totquads = out_quads.size(); + + for(unsigned int 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(unsigned int 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(unsigned int 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::OpenVDB_level_set_filter(OpenVDBLevelSet_FilterType filter_type, int width, int iterations, int filter_bias){ + 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.dilate(iterations); + break; + case OPENVDB_LEVELSET_FILTER_ERODE: + filter.erode(iterations); + break; + } +} +void OpenVDBLevelSet::OpenVDB_CSG_operation(openvdb::FloatGrid::Ptr gridOut, openvdb::FloatGrid::Ptr gridA, openvdb::FloatGrid::Ptr gridB, + OpenVDBLevelSet_CSGOperation operation) +{ + openvdb::FloatGrid::Ptr gridA_copy = gridA->deepCopy(); + openvdb::FloatGrid::Ptr gridB_copy = gridB->deepCopy(); + + 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; + } + + gridOut = gridA->deepCopy(); + gridA = gridA_copy ->deepCopy(); + gridB = gridB_copy ->deepCopy(); +}; + +openvdb::FloatGrid::Ptr OpenVDBLevelSet::OpenVDB_level_set_get_grid(){ + return this->grid; +} + +void OpenVDBLevelSet::OpenVDB_level_set_set_grid(openvdb::FloatGrid::Ptr grid){ + this->grid = grid; +} void OpenVDB_level_set_remesh(struct OpenVDBRemeshData *rmd){ diff --git a/intern/openvdb/intern/openvdb_level_set.h b/intern/openvdb/intern/openvdb_level_set.h index 73dc5007f04..20a346334a6 100644 --- a/intern/openvdb/intern/openvdb_level_set.h +++ b/intern/openvdb/intern/openvdb_level_set.h @@ -25,7 +25,30 @@ #include <openvdb/tools/MeshToVolume.h> #include <openvdb/tools/VolumeToMesh.h> #include <openvdb/tools/LevelSetFilter.h> +#include "openvdb_capi.h" + void OpenVDB_level_set_remesh(struct OpenVDBRemeshData *rmd); +struct OpenVDBLevelSet { +private: + openvdb::FloatGrid::Ptr grid; + +public: + OpenVDBLevelSet(); + ~OpenVDBLevelSet(); + openvdb::FloatGrid::Ptr OpenVDB_level_set_get_grid(); + void OpenVDB_level_set_set_grid(openvdb::FloatGrid::Ptr); + void OpenVDB_mesh_to_level_set(const float *vertices, const unsigned int *faces, const unsigned int totvertices, + const unsigned int totfaces, const double voxel_size); + + void OpenVDB_volume_to_mesh(float *vertices, unsigned int *quads, unsigned int *triangles, + unsigned int *totvertices, unsigned int *totfaces, unsigned int *tottriangles, + const double isovalue, const double adaptivity, const bool relax_disoriented_triangles); + void OpenVDB_volume_to_mesh(struct OpenVDBVolumeToMeshData *mesh, const double isovalue, const double adaptivity, const bool relax_disoriented_triangles); + void OpenVDB_level_set_filter(OpenVDBLevelSet_FilterType filter_type, int width, int iterations, int filter_bias); + void OpenVDB_CSG_operation(openvdb::FloatGrid::Ptr gridOut, openvdb::FloatGrid::Ptr gridA, openvdb::FloatGrid::Ptr gridB, + OpenVDBLevelSet_CSGOperation operation); +}; + #endif /* __OPENVDB_LEVEL_SET_H__ */ diff --git a/intern/openvdb/openvdb_capi.cc b/intern/openvdb/openvdb_capi.cc index 07f44de231d..5fa18eaf9dd 100644 --- a/intern/openvdb/openvdb_capi.cc +++ b/intern/openvdb/openvdb_capi.cc @@ -22,7 +22,6 @@ #include "openvdb_util.h" #include "openvdb_level_set.h" -struct OpenVDBFloatGrid { int unused; }; struct OpenVDBIntGrid { int unused; }; struct OpenVDBVectorGrid { int unused; }; @@ -237,6 +236,42 @@ void OpenVDBReader_get_meta_mat4(OpenVDBReader *reader, const char *name, float } -void OpenVDB_voxel_remesh(struct OpenVDBRemeshData *rmd){ +void OpenVDB_voxel_remesh(struct OpenVDBRemeshData *rmd) +{ OpenVDB_level_set_remesh(rmd); } + +OpenVDBLevelSet *OpenVDBLevelSet_create() +{ + return new OpenVDBLevelSet(); +} + +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, const double voxel_size) +{ + level_set->OpenVDB_mesh_to_level_set(vertices, faces, totvertices, totfaces, voxel_size); +} + +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->OpenVDB_volume_to_mesh(mesh, isovalue, adaptivity, relax_disoriented_triangles); +} + +void OpenVDBLevelSet_filter(struct OpenVDBLevelSet *level_set, OpenVDBLevelSet_FilterType filter_type, int width, + int iterations, OpenVDBLevelSet_FilterBias bias) +{ + level_set->OpenVDB_level_set_filter(filter_type, width, iterations, bias); +} + +void OpenVDBLevelSet_CSG_operation(struct OpenVDBLevelSet *out, struct OpenVDBLevelSet *gridA, struct OpenVDBLevelSet *gridB, + OpenVDBLevelSet_CSGOperation operation) +{ + out->OpenVDB_CSG_operation(out->OpenVDB_level_set_get_grid(), gridA->OpenVDB_level_set_get_grid(), + gridB->OpenVDB_level_set_get_grid(), operation); +} diff --git a/intern/openvdb/openvdb_capi.h b/intern/openvdb/openvdb_capi.h index 84ef86946a8..2e615605952 100644 --- a/intern/openvdb/openvdb_capi.h +++ b/intern/openvdb/openvdb_capi.h @@ -24,7 +24,33 @@ extern "C" { #endif -/*filter_type */ +/* Level Set Filters */ +typedef enum OpenVDBLevelSet_FilterType { + OPENVDB_LEVELSET_FILTER_GAUSSIAN = 0, + OPENVDB_LEVELSET_FILTER_MEAN = 1, + OPENVDB_LEVELSET_FILTER_MEDIAN = 2, + OPENVDB_LEVELSET_FILTER_MEAN_CURVATURE = 3, + OPENVDB_LEVELSET_FILTER_LAPLACIAN = 4, + OPENVDB_LEVELSET_FILTER_DILATE = 5, + OPENVDB_LEVELSET_FILTER_ERODE = 6, +} 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; + enum { FILTER_NONE = 0, FILTER_GAUSSIAN, @@ -46,9 +72,20 @@ enum { struct OpenVDBReader; struct OpenVDBWriter; +struct OpenVDBLevelSet; struct OpenVDBFloatGrid; struct OpenVDBIntGrid; struct OpenVDBVectorGrid; +struct OpenVDBVolumeToMeshData { + int tottriangles; + int totquads; + int totvertices; + + float *vertices; + unsigned int *quads; + unsigned int *triangles; +}; + struct OpenVDBRemeshData { float *verts; unsigned int *faces; @@ -137,6 +174,17 @@ void OpenVDBReader_get_meta_mat4(struct OpenVDBReader *reader, const char *name, void OpenVDB_voxel_remesh(struct OpenVDBRemeshData *rmd); +struct OpenVDBLevelSet *OpenVDBLevelSet_create(void); +void OpenVDBLevelSet_free(struct OpenVDBLevelSet *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, const double voxel_size); +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, + int iterations, OpenVDBLevelSet_FilterBias bias); +void OpenVDBLevelSet_CSG_operation(struct OpenVDBLevelSet *out, struct OpenVDBLevelSet *gridA, struct OpenVDBLevelSet *gridB, + OpenVDBLevelSet_CSGOperation operation); + #ifdef __cplusplus } |