[Bf-blender-cvs] [e2f23d91b98] sculpt-mode-features: OpenVDB Voxel remesher: Initial implementation

Pablo Dobarro noreply at git.blender.org
Thu Mar 14 21:56:27 CET 2019


Commit: e2f23d91b989e05ff743260d18c85a17f78439a9
Author: Pablo Dobarro
Date:   Thu Mar 14 21:54:27 2019 +0100
Branches: sculpt-mode-features
https://developer.blender.org/rBe2f23d91b989e05ff743260d18c85a17f78439a9

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.

===================================================================

M	intern/openvdb/CMakeLists.txt
A	intern/openvdb/intern/openvdb_level_set.cc
A	intern/openvdb/intern/openvdb_level_set.h
M	intern/openvdb/openvdb_capi.cc
M	intern/openvdb/openvdb_capi.h
M	source/blender/editors/object/CMakeLists.txt
M	source/blender/editors/object/object_edit.c
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_ops.c

===================================================================

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
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index f15427e61ac..3211784e126 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -78,4 +78,17 @@ if(WITH_INTERNATIONAL)
 	add_definitions(-DWITH_INTERNATIONAL)
 endif()
 
+if(WITH_OPENVDB)
+	add_definitions(-DWITH_OPENVDB)
+	list(APPEND INC
+		 ../../../../intern/openvdb
+	)
+
+	if(WITH_OPENVDB_BLOSC)
+		add_definitions(
+			-DWITH_OPENVDB_BLOSC
+		)
+	endif()
+endif()
+
 blender_add_lib(bf_editor_object "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 977f5f30d94..88cdb74ac71 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -32,6 +32,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
+#include "BLI_math.h"
 #include "BLI_utildefines.h"
 #include "BLI_ghash.h"
 
@@ -78,6 +79,8 @@
 #include "BKE_editmesh.h"
 #include "BKE_report.h"
 #include "BKE_workspace.h"
+#include "BKE_mesh_runtime.h"
+#include "BKE_library.h"
 
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_build.h"
@@ -110,6 +113,10 @@
 
 #include "object_intern.h"  // own include
 
+#ifdef WITH_OPENVDB
+	#include "openvdb_capi.h"
+#endif
+
 /* prototypes */
 typedef struct MoveToCollectionData MoveToCollectionData;
 static void move_to_collection_menus_items(struct uiLayout *layout, struct MoveToCollectionData *menu);
@@ -1735,3 +1742,107 @@ void OBJECT_OT_link_to_collection(wmOperatorType *ot)
 	                      "Name of the newly added collection");
 	RNA_def_property_flag(prop, PROP_SKIP_SAVE);
 }
+
+
+static int remesh_exec(bContext *C, wmOperator *op)
+{
+	bool linked_data = false;
+
+	Object *ob = CTX_data_active_object(C);
+	Main *bmain = CTX_data_main(C);
+	struct OpenVDBRemeshData rmd;
+
+	ID *data;
+	data = ob->data;
+	if (data && ID_IS_LINKED(data)) {
+		linked_data = true;
+		return OPERATOR_CANCELLED;
+	}
+
+	if (ob->type == OB_MESH) {
+		Mesh *mesh = ob->data;
+		BKE_mesh_runtime_looptri_recalc(mesh);
+		const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
+		MVertTri *verttri = 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));
+
+		rmd.totfaces = BKE_mesh_runtime_looptri_len(mesh);
+		rmd.totverts = mesh->totvert;
+		rmd.verts = (float *)MEM_calloc_arrayN(rmd.totverts * 3, sizeof(float), "remesh_input_verts");
+		rmd.faces = (unsigned int *)MEM_calloc_arrayN(rmd.totfaces * 3, sizeof(unsigned int), "remesh_intput_faces");
+		PropertyRNA *prop = RNA_struct_find_property(op->ptr, "voxel_size");
+		rmd.voxel_size = RNA_property_float_get(op->ptr, prop);
+		rmd.isovalue = 0.0f;
+
+		for(int i = 0; i < mesh->totvert; i++) {
+			MVert mvert = mesh->mvert[i];
+			rmd.verts[i * 3] = mvert.co[0];
+			rmd.verts[i * 3 + 1] = mvert.co[1];
+			rmd.verts[i * 3 + 2] = mvert.co[2];
+		}
+
+		for(int i = 0; i < rmd.totfaces; i++) {
+			MVertTri vt = verttri[i];
+			rmd.faces[i * 3] = vt.tri[0];
+			rmd.faces[i * 3 + 1] = vt.tri[1];
+			rmd.faces[i * 3 + 2] = vt.tri[2];
+		}
+
+		OpenVDB_voxel_remesh(&rmd);
+
+		Mesh *newMesh = BKE_mesh_new_nomain(rmd.out_totverts, 0, rmd.out_totfaces, 0, 0);
+
+		for(int i = 0; i < rmd.out_totverts; i++) {
+			float vco[3] = { rmd.out_verts[i * 3], rmd.out_verts[i * 3 + 1], rmd.out_verts[i * 3 + 2]};
+			copy_v3_v3(newMesh->mvert[i].co, vco);
+
+		}
+		for(int i = 0; i < rmd.out_totfaces; i++) {
+			newMesh->mface[i].v4 = rmd.out_faces[i * 4];
+			

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list