Page MenuHome

sculpt_mode_features_voxel_remesh_modifier_5th_April_2019.diff

Subscribers
None
Tokens
"Love" token, awarded by juri3d.

File Metadata

Author
Martin Felke (scorpion81)
Created
Apr 5 2019, 3:07 PM

sculpt_mode_features_voxel_remesh_modifier_5th_April_2019.diff

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 59bf820560e..a0eb3eef033 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1195,18 +1195,23 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.prop(md, "mode")
- row = layout.row()
- row.prop(md, "octree_depth")
- row.prop(md, "scale")
+ if md.mode != 'VOXEL':
+ row = layout.row()
+ row.prop(md, "octree_depth")
+ row.prop(md, "scale")
if md.mode == 'SHARP':
layout.prop(md, "sharpness")
- layout.prop(md, "use_smooth_shade")
- layout.prop(md, "use_remove_disconnected")
- row = layout.row()
- row.active = md.use_remove_disconnected
- row.prop(md, "threshold")
+ if md.mode == 'VOXEL':
+ layout.prop(md, "voxel_size")
+ layout.prop(md, "smooth_normals")
+ else:
+ layout.prop(md, "use_smooth_shade")
+ layout.prop(md, "use_remove_disconnected")
+ row = layout.row()
+ row.active = md.use_remove_disconnected
+ row.prop(md, "threshold")
@staticmethod
def vertex_weight_mask(layout, ob, md):
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 18d3d99ca54..95925d86319 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1749,7 +1749,6 @@ void OBJECT_OT_link_to_collection(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-
static int remesh_exec(bContext *C, wmOperator *op)
{
bool linked_data = false;
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 126ef912b15..b8be60e2033 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1489,6 +1489,7 @@ enum {
typedef enum eRemeshModifierFlags {
MOD_REMESH_FLOOD_FILL = (1 << 0),
MOD_REMESH_SMOOTH_SHADING = (1 << 1),
+ MOD_REMESH_SMOOTH_NORMALS = (1 << 2),
} RemeshModifierFlags;
typedef enum eRemeshModifierMode {
@@ -1498,6 +1499,8 @@ typedef enum eRemeshModifierMode {
MOD_REMESH_MASS_POINT = 1,
/* keeps sharp edges */
MOD_REMESH_SHARP_FEATURES = 2,
+ /* OpenVDB voxel remesh */
+ MOD_REMESH_VOXEL = 3,
} eRemeshModifierMode;
typedef struct RemeshModifierData {
@@ -1511,6 +1514,10 @@ typedef struct RemeshModifierData {
float hermite_num;
+ /* for voxelremesher */
+ float voxel_size;
+ float _pad1;
+
/* octree depth */
char depth;
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 6dca81415f3..71f1d369b0c 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -4063,6 +4063,7 @@ static void rna_def_modifier_remesh(BlenderRNA *brna)
{MOD_REMESH_MASS_POINT, "SMOOTH", 0, "Smooth", "Output a smooth surface with no sharp-features detection"},
{MOD_REMESH_SHARP_FEATURES, "SHARP", 0, "Sharp",
"Output a surface that reproduces sharp edges and corners from the input mesh"},
+ {MOD_REMESH_VOXEL, "VOXEL", 0, "Voxel", "Invokes the OpenVDB voxel remesher and generates quad only meshes"},
{0, NULL, 0, NULL, NULL},
};
@@ -4118,6 +4119,18 @@ static void rna_def_modifier_remesh(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_REMESH_SMOOTH_SHADING);
RNA_def_property_ui_text(prop, "Smooth Shading", "Output faces with smooth shading rather than flat shaded");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "voxel_size", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_range(prop, 0.001, 1.0);
+ RNA_def_property_float_default(prop, 0.1f);
+ RNA_def_property_ui_range(prop, 0.0001, 1, 0.01, 4);
+ RNA_def_property_ui_text(prop, "Voxel Size", "Voxel size used for volume evaluation");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "smooth_normals", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_REMESH_SMOOTH_NORMALS);
+ RNA_def_property_ui_text(prop, "Smooth Normals", "Smooth normals on the resulting mesh");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_ocean(BlenderRNA *brna)
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 30dab865196..5ee1da8e59b 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -138,6 +138,19 @@ 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()
+
# So we can have special tricks in modifier system.
add_definitions(${GL_DEFINITIONS})
diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c
index 345ee6477ac..ef960e22871 100644
--- a/source/blender/modifiers/intern/MOD_remesh.c
+++ b/source/blender/modifiers/intern/MOD_remesh.c
@@ -46,6 +46,10 @@
# include "dualcon.h"
#endif
+#ifdef WITH_OPENVDB
+ #include "openvdb_capi.h"
+#endif
+
static void initData(ModifierData *md)
{
RemeshModifierData *rmd = (RemeshModifierData *) md;
@@ -56,6 +60,7 @@ static void initData(ModifierData *md)
rmd->flag = MOD_REMESH_FLOOD_FILL;
rmd->mode = MOD_REMESH_SHARP_FEATURES;
rmd->threshold = 1;
+ rmd->voxel_size = 0.1f;
}
#ifdef WITH_MOD_REMESH
@@ -134,6 +139,77 @@ static void dualcon_add_quad(void *output_v, const int vert_indices[4])
output->curface++;
}
+#if WITH_OPENVDB
+static Mesh* voxel_remesh(Mesh* mesh, float voxel_size, bool smooth_normals)
+{
+ struct OpenVDBRemeshData rmd;
+
+ 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");
+ rmd.voxel_size = voxel_size;
+ 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];
+ newMesh->mface[i].v3 = rmd.out_faces[i * 4 + 1];
+ newMesh->mface[i].v2 = rmd.out_faces[i * 4 + 2];
+ newMesh->mface[i].v1 = rmd.out_faces[i * 4 + 3];
+ }
+
+ BKE_mesh_calc_edges_tessface(newMesh);
+ BKE_mesh_convert_mfaces_to_mpolys(newMesh);
+ BKE_mesh_calc_normals(newMesh);
+
+ if (smooth_normals) {
+ MPoly *mpoly = newMesh->mpoly;
+ int i, totpoly = newMesh->totpoly;
+
+ /* Apply smooth shading to output faces */
+ for (i = 0; i < totpoly; i++) {
+ mpoly[i].flag |= ME_SMOOTH;
+ }
+ }
+
+ MEM_freeN(rmd.faces);
+ MEM_freeN(rmd.verts);
+ MEM_freeN(verttri);
+ MEM_freeN(rmd.out_verts);
+ MEM_freeN(rmd.out_faces);
+
+ return newMesh;
+}
+#endif
+
static Mesh *applyModifier(
ModifierData *md,
const ModifierEvalContext *UNUSED(ctx),
@@ -148,6 +224,22 @@ static Mesh *applyModifier(
rmd = (RemeshModifierData *)md;
+ if (rmd->mode == MOD_REMESH_VOXEL)
+ {
+#if WITH_OPENVDB
+ //invoke an operator ? nah, better make a function
+ if (rmd->voxel_size > 0.0f) {
+ return voxel_remesh(mesh, rmd->voxel_size, rmd->flag & MOD_REMESH_SMOOTH_NORMALS);
+ }
+ else {
+ return mesh;
+ }
+#else
+ modifier_setError((ModifierData*)rmd, "Built without OpenVDB support, cant execute voxel remesh");
+ return mesh;
+#endif
+ }
+
init_dualcon_mesh(&input, mesh);
if (rmd->flag & MOD_REMESH_FLOOD_FILL)

Event Timeline