Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2015-06-04 12:49:59 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-06-04 19:56:11 +0300
commit455ca1b28f140482f2834c9bba0adc730aff6637 (patch)
tree33203edd53c9bbc8b0b8cd8a897487952597c298
parentc64f491f9f45d802bc3a3cb168255dc680ea0d13 (diff)
BMesh decimate, improve behavior with weights
Add slider to adjust the influence of weights relative to geometry distortion. This allows subtle influences to be applied - without drastic changes in behavior.
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py19
-rw-r--r--source/blender/blenloader/intern/versioning_270.c14
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate.h4
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c67
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c7
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c13
7 files changed, 91 insertions, 36 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index d6d4e03df39..381c9add34f 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -262,24 +262,37 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
row.prop(md, "decimate_type", expand=True)
if decimate_type == 'COLLAPSE':
+ has_vgroup = bool(md.vertex_group)
layout.prop(md, "ratio")
split = layout.split()
- row = split.row(align=True)
+
+ col = split.column()
+ row = col.row(align=True)
row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
- split.prop(md, "use_collapse_triangulate")
+ layout_info = col
+
+ col = split.column()
+ row = col.row()
+ row.active = has_vgroup
+ row.prop(md, "vertex_group_factor")
+
+ col.prop(md, "use_collapse_triangulate")
+
elif decimate_type == 'UNSUBDIV':
layout.prop(md, "iterations")
+ layout_info = layout
else: # decimate_type == 'DISSOLVE':
layout.prop(md, "angle_limit")
layout.prop(md, "use_dissolve_boundaries")
layout.label("Delimit:")
row = layout.row()
row.prop(md, "delimit")
+ layout_info = layout
- layout.label(text=iface_("Face Count: %d") % md.face_count, translate=False)
+ layout_info.label(text=iface_("Faces: %d") % md.face_count, translate=False)
def DISPLACE(self, layout, ob, md):
has_texture = (md.texture is not None)
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index df985448ccd..37c255620d9 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -830,5 +830,19 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
scene->r.simplify_particles_render = scene->r.simplify_particles;
}
}
+
+ if (!DNA_struct_elem_find(fd->filesdna, "DecimateModifierData", "float", "defgrp_factor")) {
+ Object *ob;
+
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ ModifierData *md;
+ for (md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Decimate) {
+ DecimateModifierData *dmd = (DecimateModifierData *)md;
+ dmd->defgrp_factor = 1.0f;
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/bmesh/tools/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h
index 17b55be52dc..b0a85b09d5a 100644
--- a/source/blender/bmesh/tools/bmesh_decimate.h
+++ b/source/blender/bmesh/tools/bmesh_decimate.h
@@ -42,8 +42,4 @@ void BM_mesh_decimate_dissolve(
BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
const BMO_Delimit delimit);
-/* these weights are accumulated so too high values may reach 'inf' too quickly */
-#define BM_MESH_DECIM_WEIGHT_MAX 100000.0f
-#define BM_MESH_DECIM_WEIGHT_EPS (1.0f / BM_MESH_DECIM_WEIGHT_MAX)
-
#endif /* __BMESH_DECIMATE_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 3bcf9a3cd0b..6b6219ca321 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -212,10 +212,15 @@ static bool bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_
*
* This avoids cases where a flat (or near flat) areas get very un-even geometry.
*/
-static float bm_decim_build_edge_cost_single__topology(BMEdge *e)
+static float bm_decim_build_edge_cost_single_squared__topology(BMEdge *e)
{
return fabsf(dot_v3v3(e->v1->no, e->v2->no)) / min_ff(-len_squared_v3v3(e->v1->co, e->v2->co), -FLT_EPSILON);
}
+static float bm_decim_build_edge_cost_single__topology(BMEdge *e)
+{
+ return fabsf(dot_v3v3(e->v1->no, e->v2->no)) / min_ff(-len_v3v3(e->v1->co, e->v2->co), -FLT_EPSILON);
+}
+
#endif /* USE_TOPOLOGY_FALLBACK */
static void bm_decim_build_edge_cost_single(
@@ -253,15 +258,6 @@ static void bm_decim_build_edge_cost_single(
else {
goto clear;
}
-
- if (vweights) {
- if ((vweights[BM_elem_index_get(e->v1)] >= BM_MESH_DECIM_WEIGHT_MAX) &&
- (vweights[BM_elem_index_get(e->v2)] >= BM_MESH_DECIM_WEIGHT_MAX))
- {
- /* skip collapsing this edge */
- goto clear;
- }
- }
/* end sanity check */
@@ -270,21 +266,21 @@ static void bm_decim_build_edge_cost_single(
q1 = &vquadrics[BM_elem_index_get(e->v1)];
q2 = &vquadrics[BM_elem_index_get(e->v2)];
- if (vweights == NULL) {
- cost = (BLI_quadric_evaluate(q1, optimize_co) +
- BLI_quadric_evaluate(q2, optimize_co));
- }
- else {
- /* add 1.0 so planar edges are still weighted against */
- cost = (((BLI_quadric_evaluate(q1, optimize_co) + 1.0f) * vweights[BM_elem_index_get(e->v1)]) +
- ((BLI_quadric_evaluate(q2, optimize_co) + 1.0f) * vweights[BM_elem_index_get(e->v2)]));
- }
+ cost = (BLI_quadric_evaluate(q1, optimize_co) +
+ BLI_quadric_evaluate(q2, optimize_co));
+
+
// print("COST %.12f\n");
/* note, 'cost' shouldn't be negative but happens sometimes with small values.
* this can cause faces that make up a flat surface to over-collapse, see [#37121] */
cost = fabsf(cost);
+ /* edge weights can be 2 max, ((2 * 2) ^ 2) == 16x max,
+ * a high weight means being inserted into the heap ahead of 16x better edges.
+ * but thats fine since its the purpose of weighting. */
+#define VWEIGHT_SCALE 2
+
#ifdef USE_TOPOLOGY_FALLBACK
if (UNLIKELY(cost < TOPOLOGY_FALLBACK_EPS)) {
/* subtract existing cost to further differentiate edges from one another
@@ -292,10 +288,35 @@ static void bm_decim_build_edge_cost_single(
* keep topology cost below 0.0 so their values don't interfere with quadric cost,
* (and they get handled first).
* */
- cost = bm_decim_build_edge_cost_single__topology(e) - cost;
- BLI_assert(cost <= 0.0f);
+ if (vweights == NULL) {
+ cost = bm_decim_build_edge_cost_single_squared__topology(e) - cost;
+ }
+ else {
+ /* with weights we need to use the real length so we can scale them properly */
+ float e_weight = (vweights[BM_elem_index_get(e->v1)] +
+ vweights[BM_elem_index_get(e->v2)]);
+ cost = bm_decim_build_edge_cost_single__topology(e) - cost;
+ /* note, this is rather arbitrary max weight is 2 here,
+ * allow for skipping edges 4x the length, based on weights */
+ if (e_weight) {
+ e_weight *= VWEIGHT_SCALE;
+ cost *= 1.0f + SQUARE(e_weight);
+ }
+
+ BLI_assert(cost <= 0.0f);
+ }
}
+ else
#endif
+ if (vweights) {
+ float e_weight = 2.0f - (vweights[BM_elem_index_get(e->v1)] +
+ vweights[BM_elem_index_get(e->v2)]);
+ if (e_weight) {
+ e_weight *= VWEIGHT_SCALE;
+ cost += (BM_edge_calc_length(e) * SQUARE(e_weight));
+ }
+ }
+#undef VWEIGHT_SCALE
eheap_table[BM_elem_index_get(e)] = BLI_heap_insert(eheap, cost, e);
return;
@@ -950,7 +971,9 @@ static void bm_decim_edge_collapse(
int i;
if (vweights) {
- vweights[v_other_index] += vweights[v_clear_index];
+ float v_other_weight = interpf(vweights[v_other_index], vweights[v_clear_index], customdata_fac);
+ CLAMP(v_other_weight, 0.0f, 1.0f);
+ vweights[v_other_index] = v_other_weight;
}
e = NULL; /* paranoid safety check */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index f3c61f0ab6c..1fc66b9b016 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -431,10 +431,11 @@ typedef struct DecimateModifierData {
float angle; /* (mode == MOD_DECIM_MODE_DISSOLVE) */
char defgrp_name[64]; /* MAX_VGROUP_NAME */
+ float defgrp_factor;
short flag, mode;
/* runtime only */
- int face_count, pad2;
+ int face_count;
} DecimateModifierData;
enum {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 1c719b1376b..6f1f6f97a15 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -1506,6 +1506,13 @@ static void rna_def_modifier_decimate(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_DECIM_FLAG_TRIANGULATE);
RNA_def_property_ui_text(prop, "Triangulate", "Keep triangulated faces resulting from decimation (collapse only)");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "vertex_group_factor", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "defgrp_factor");
+ RNA_def_property_range(prop, 0, 1.0f);
+ RNA_def_property_ui_range(prop, 0, 1, 1, 4);
+ RNA_def_property_ui_text(prop, "Factor", "Vertex group strength");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
/* end collapse-only option */
/* (mode == MOD_DECIM_MODE_DISSOLVE) */
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 7c13774ee99..878015c7a7b 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -61,6 +61,7 @@ static void initData(ModifierData *md)
dmd->percent = 1.0;
dmd->angle = DEG2RADF(5.0f);
+ dmd->defgrp_factor = 1.0;
}
static void copyData(ModifierData *md, ModifierData *target)
@@ -78,7 +79,9 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
CustomDataMask dataMask = 0;
/* ask for vertexgroups if we need them */
- if (dmd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT;
+ if (dmd->defgrp_name[0] && (dmd->defgrp_factor > 0.0f)) {
+ dataMask |= CD_MASK_MDEFORMVERT;
+ }
return dataMask;
}
@@ -130,7 +133,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
if (dmd->mode == MOD_DECIM_MODE_COLLAPSE) {
- if (dmd->defgrp_name[0]) {
+ if (dmd->defgrp_name[0] && (dmd->defgrp_factor > 0.0f)) {
MDeformVert *dvert;
int defgrp_index;
@@ -144,14 +147,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (dmd->flag & MOD_DECIM_FLAG_INVERT_VGROUP) {
for (i = 0; i < vert_tot; i++) {
- const float f = 1.0f - defvert_find_weight(&dvert[i], defgrp_index);
- vweights[i] = f > BM_MESH_DECIM_WEIGHT_EPS ? (1.0f / f) : BM_MESH_DECIM_WEIGHT_MAX;
+ vweights[i] = (1.0f - defvert_find_weight(&dvert[i], defgrp_index)) * dmd->defgrp_factor;
}
}
else {
for (i = 0; i < vert_tot; i++) {
- const float f = defvert_find_weight(&dvert[i], defgrp_index);
- vweights[i] = f > BM_MESH_DECIM_WEIGHT_EPS ? (1.0f / f) : BM_MESH_DECIM_WEIGHT_MAX;
+ vweights[i] = (defvert_find_weight(&dvert[i], defgrp_index)) * dmd->defgrp_factor;
}
}
}