diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2019-03-14 23:54:27 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2019-03-14 23:54:27 +0300 |
commit | e2f23d91b989e05ff743260d18c85a17f78439a9 (patch) | |
tree | 7c62da8669a4c81533e703944e18ff510167ef10 /intern/openvdb | |
parent | b342c293a93fcd572f20a62803bedc3323ccb496 (diff) |
OpenVDB Voxel remesher: Initial implementation
This introduces a new workflow for sculpting. The voxel remesher works
with Dyntopo disabled. The user needs to run it manually once he/she
considers that the topology is too stretched to continue sculpting
normally. OpenVDB evaluates the mesh volume as a level set with a given
voxel size and it always outputs an all quads manifold mesh. It
automatically solves self-intersections and geometry errors produced by
booleans, which Dyntopo can't solve right now. Once the new mesh is
calculated, the user can continue sculpting without the overhead of
having Dyntopo enabled.
It still needs a proper UI and it has some issues. Undo is not working
on a remeshed object.
Diffstat (limited to 'intern/openvdb')
-rw-r--r-- | intern/openvdb/CMakeLists.txt | 3 | ||||
-rw-r--r-- | intern/openvdb/intern/openvdb_level_set.cc | 66 | ||||
-rw-r--r-- | intern/openvdb/intern/openvdb_level_set.h | 29 | ||||
-rw-r--r-- | intern/openvdb/openvdb_capi.cc | 6 | ||||
-rw-r--r-- | intern/openvdb/openvdb_capi.h | 18 |
5 files changed, 122 insertions, 0 deletions
diff --git a/intern/openvdb/CMakeLists.txt b/intern/openvdb/CMakeLists.txt index ddec43f30a3..c231099bb03 100644 --- a/intern/openvdb/CMakeLists.txt +++ b/intern/openvdb/CMakeLists.txt @@ -21,6 +21,7 @@ set(INC . intern + ../guardedalloc ) set(INC_SYS @@ -53,12 +54,14 @@ if(WITH_OPENVDB) intern/openvdb_dense_convert.cc intern/openvdb_reader.cc intern/openvdb_writer.cc + intern/openvdb_level_set.cc openvdb_capi.cc openvdb_util.cc intern/openvdb_dense_convert.h intern/openvdb_reader.h intern/openvdb_writer.h + intern/openvdb_level_set.h openvdb_util.h ) diff --git a/intern/openvdb/intern/openvdb_level_set.cc b/intern/openvdb/intern/openvdb_level_set.cc new file mode 100644 index 00000000000..068148f4e04 --- /dev/null +++ b/intern/openvdb/intern/openvdb_level_set.cc @@ -0,0 +1,66 @@ +/* + * 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 "openvdb_util.h" +#include "openvdb_capi.h" +#include "MEM_guardedalloc.h" + +void OpenVDB_level_set_remesh(struct OpenVDBRemeshData *rmd){ + + 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; + const openvdb::math::Transform xform; + + for(int i = 0; i < rmd->totverts; i++) { + openvdb::Vec3s v(rmd->verts[i * 3 ], rmd->verts[i * 3 + 1], rmd->verts[i * 3 + 2]); + points.push_back(v); + } + + for(int i = 0; i < rmd->totfaces; i++) { + openvdb::Vec3I f(rmd->faces[i * 3 ], rmd->faces[i * 3 + 1], rmd->faces[i * 3 + 2]); + triangles.push_back(f); + } + + openvdb::initialize(); + openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform((double)rmd->voxel_size); + const openvdb::FloatGrid::Ptr grid = openvdb::tools::meshToLevelSet<openvdb::FloatGrid>(*transform, points, triangles, quads, 1); + openvdb::tools::volumeToMesh<openvdb::FloatGrid>(*grid, out_points, out_quads, (double)rmd->isovalue); + rmd->out_verts = (float *)MEM_malloc_arrayN(out_points.size(), 3 * sizeof (float), "openvdb remesher out verts"); + rmd->out_faces = (unsigned int*)MEM_malloc_arrayN(out_quads.size(), 4 * sizeof (unsigned int), "openvdb remesh out quads"); + rmd->out_totverts = out_points.size(); + rmd->out_totfaces = out_quads.size(); + + for(int i = 0; i < out_points.size(); i++) { + rmd->out_verts[i * 3] = out_points[i].x(); + rmd->out_verts[i * 3 + 1] = out_points[i].y(); + rmd->out_verts[i * 3 + 2] = out_points[i].z(); + } + + for(int i = 0; i < out_quads.size(); i++) { + rmd->out_faces[i * 4] = out_quads[i].x(); + rmd->out_faces[i * 4 + 1] = out_quads[i].y(); + rmd->out_faces[i * 4 + 2] = out_quads[i].z(); + rmd->out_faces[i * 4 + 3] = out_quads[i].w(); + } +} diff --git a/intern/openvdb/intern/openvdb_level_set.h b/intern/openvdb/intern/openvdb_level_set.h new file mode 100644 index 00000000000..bd1c57a4e86 --- /dev/null +++ b/intern/openvdb/intern/openvdb_level_set.h @@ -0,0 +1,29 @@ +/* + * 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/openvdb.h> +#include <openvdb/tools/MeshToVolume.h> +#include <openvdb/tools/VolumeToMesh.h> + +void OpenVDB_level_set_remesh(struct OpenVDBRemeshData *rmd); + +#endif /* __OPENVDB_LEVEL_SET_H__ */ diff --git a/intern/openvdb/openvdb_capi.cc b/intern/openvdb/openvdb_capi.cc index 997c7638537..07f44de231d 100644 --- a/intern/openvdb/openvdb_capi.cc +++ b/intern/openvdb/openvdb_capi.cc @@ -20,6 +20,7 @@ #include "openvdb_capi.h" #include "openvdb_dense_convert.h" #include "openvdb_util.h" +#include "openvdb_level_set.h" struct OpenVDBFloatGrid { int unused; }; struct OpenVDBIntGrid { int unused; }; @@ -234,3 +235,8 @@ void OpenVDBReader_get_meta_mat4(OpenVDBReader *reader, const char *name, float { reader->mat4sMeta(name, value); } + + +void OpenVDB_voxel_remesh(struct OpenVDBRemeshData *rmd){ + OpenVDB_level_set_remesh(rmd); +} diff --git a/intern/openvdb/openvdb_capi.h b/intern/openvdb/openvdb_capi.h index 7af16509753..1af81f70e1b 100644 --- a/intern/openvdb/openvdb_capi.h +++ b/intern/openvdb/openvdb_capi.h @@ -29,6 +29,21 @@ struct OpenVDBWriter; struct OpenVDBFloatGrid; struct OpenVDBIntGrid; struct OpenVDBVectorGrid; +struct OpenVDBRemeshData { + float *verts; + unsigned int *faces; + int totfaces; + int totverts; + + float *out_verts; + unsigned int *out_faces; + int out_totverts; + int out_totfaces; + + float voxel_size; + float isovalue; +}; + int OpenVDB_getVersionHex(void); @@ -93,6 +108,9 @@ void OpenVDBReader_get_meta_v3(struct OpenVDBReader *reader, const char *name, f void OpenVDBReader_get_meta_v3_int(struct OpenVDBReader *reader, const char *name, int value[3]); void OpenVDBReader_get_meta_mat4(struct OpenVDBReader *reader, const char *name, float value[4][4]); +void OpenVDB_voxel_remesh(struct OpenVDBRemeshData *rmd); + + #ifdef __cplusplus } #endif |