[Bf-blender-cvs] [42876e5f2de] sculpt-mode-features: OpenVDB: Add Filters and CSG operations to the Level Set C API

Pablo Dobarro noreply at git.blender.org
Sun Apr 7 04:10:06 CEST 2019


Commit: 42876e5f2de1f12796ec9d091fc6c5c9e0765f6c
Author: Pablo Dobarro
Date:   Sun Apr 7 04:08:45 2019 +0200
Branches: sculpt-mode-features
https://developer.blender.org/rB42876e5f2de1f12796ec9d091fc6c5c9e0765f6c

OpenVDB: Add Filters and CSG operations to the Level Set C API

I also refactored the voxel remesher code to use the new API.

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

M	intern/openvdb/intern/openvdb_level_set.cc
M	intern/openvdb/intern/openvdb_level_set.h
M	intern/openvdb/openvdb_capi.cc
M	intern/openvdb/openvdb_capi.h
M	source/blender/editors/object/object_edit.c

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

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;
+	unsign

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list