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>2012-10-23 09:20:02 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-10-23 09:20:02 +0400
commitbbe0deb8afb0094b169a9abb04df7458cd49786b (patch)
treefc32d80adbdef16059de1a3dac27fa5494d93efe
parent0636886715b4c5ac56ed7f903bf37a00cfbdc841 (diff)
add limited dissolve as a decimation type to the decimate modifier.
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py7
-rw-r--r--source/blender/bmesh/CMakeLists.txt1
-rw-r--r--source/blender/bmesh/intern/bmesh_decimate.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_decimate_dissolve.c226
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c174
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h7
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c18
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c6
8 files changed, 267 insertions, 178 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 1887c4786be..36e626d1a00 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -213,14 +213,17 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
def DECIMATE(self, layout, ob, md):
row = layout.row()
row.prop(md, "decimate_type", expand=True)
+ decimate_type = md.decimate_type
- if md.decimate_type == 'COLLAPSE':
+ if decimate_type == 'COLLAPSE':
layout.prop(md, "ratio")
row = layout.row()
row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
row.prop(md, "invert_vertex_group")
- else: # assume UNSUBDIV
+ elif decimate_type == 'UNSUBDIV':
layout.prop(md, "iterations")
+ else: # decimate_type == 'DISSOLVE':
+ layout.prop(md, "angle_limit")
layout.label(text="Face Count" + ": %d" % md.face_count)
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index a000cb59167..8b0e616515f 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -65,6 +65,7 @@ set(SRC
intern/bmesh_core.c
intern/bmesh_core.h
intern/bmesh_decimate_collapse.c
+ intern/bmesh_decimate_dissolve.c
intern/bmesh_decimate_unsubdivide.c
intern/bmesh_decimate.h
intern/bmesh_inline.h
diff --git a/source/blender/bmesh/intern/bmesh_decimate.h b/source/blender/bmesh/intern/bmesh_decimate.h
index 18d86cfb1a5..04aa392fcf0 100644
--- a/source/blender/bmesh/intern/bmesh_decimate.h
+++ b/source/blender/bmesh/intern/bmesh_decimate.h
@@ -32,4 +32,10 @@ void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights);
void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const int tag_only);
void BM_mesh_decimate_unsubdivide(BMesh *bm, const int iterations);
+void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit,
+ BMVert **vinput_arr, const int vinput_len,
+ BMEdge **einput_arr, const int einput_len);
+void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit);
+
+
#endif /* __BMESH_DECIMATE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c b/source/blender/bmesh/intern/bmesh_decimate_dissolve.c
new file mode 100644
index 00000000000..97cad114121
--- /dev/null
+++ b/source/blender/bmesh/intern/bmesh_decimate_dissolve.c
@@ -0,0 +1,226 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/intern/bmesh_decimate_dissolve.c
+ * \ingroup bmesh
+ *
+ * BMesh decimator that dissolves flat areas into polygons (ngons).
+ */
+
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "bmesh.h"
+#include "bmesh_decimate.h" /* own include */
+
+#define UNIT_TO_ANGLE DEG2RADF(90.0f)
+#define ANGLE_TO_UNIT (1.0f / UNIT_TO_ANGLE)
+
+/* multiply vertex edge angle by face angle
+ * this means we are not left with sharp corners between _almost_ planer faces
+ * convert angles [0-PI/2] -> [0-1], multiply together, then convert back to radians. */
+static float bm_vert_edge_face_angle(BMVert *v)
+{
+ const float angle = BM_vert_calc_edge_angle(v);
+ /* note: could be either edge, it doesn't matter */
+ if (v->e && BM_edge_is_manifold(v->e)) {
+ return ((angle * ANGLE_TO_UNIT) * (BM_edge_calc_face_angle(v->e) * ANGLE_TO_UNIT)) * UNIT_TO_ANGLE;
+ }
+ else {
+ return angle;
+ }
+}
+
+#undef UNIT_TO_ANGLE
+#undef ANGLE_TO_UNIT
+
+typedef struct DissolveElemWeight {
+ BMHeader *ele;
+ float weight;
+} DissolveElemWeight;
+
+static int dissolve_elem_cmp(const void *a1, const void *a2)
+{
+ const struct DissolveElemWeight *d1 = a1, *d2 = a2;
+
+ if (d1->weight > d2->weight) return 1;
+ else if (d1->weight < d2->weight) return -1;
+ return 0;
+}
+
+void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit,
+ BMVert **vinput_arr, const int vinput_len,
+ BMEdge **einput_arr, const int einput_len)
+{
+ const float angle_max = (float)M_PI / 2.0f;
+ DissolveElemWeight *weight_elems = MEM_mallocN(maxi(einput_len, vinput_len) *
+ sizeof(DissolveElemWeight), __func__);
+ int i, tot_found;
+
+ BMIter iter;
+ BMEdge *e_iter;
+ BMEdge **earray;
+
+ int *vert_reverse_lookup;
+
+ /* --- first edges --- */
+
+ /* wire -> tag */
+ BM_ITER_MESH (e_iter, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_elem_flag_set(e_iter, BM_ELEM_TAG, BM_edge_is_wire(e_iter));
+ }
+
+ /* go through and split edge */
+ for (i = 0, tot_found = 0; i < einput_len; i++) {
+ BMEdge *e = einput_arr[i];
+ const float angle = BM_edge_calc_face_angle(e);
+
+ if (angle < angle_limit) {
+ tot_found++;
+ }
+ weight_elems[i].ele = (BMHeader *)e;
+ weight_elems[i].weight = angle;
+ }
+
+ if (tot_found != 0) {
+ qsort(weight_elems, einput_len, sizeof(DissolveElemWeight), dissolve_elem_cmp);
+
+ for (i = 0; i < tot_found; i++) {
+ BMEdge *e = (BMEdge *)weight_elems[i].ele;
+
+ if (/* may have become non-manifold */
+ BM_edge_is_manifold(e) &&
+ /* check twice because cumulative effect could dissolve over angle limit */
+ (BM_edge_calc_face_angle(e) < angle_limit))
+ {
+ BMFace *nf = BM_faces_join_pair(bm, e->l->f,
+ e->l->radial_next->f,
+ e,
+ FALSE); /* join faces */
+
+ /* there may be some errors, we don't mind, just move on */
+ if (nf) {
+ BM_face_normal_update(nf);
+ }
+ else {
+ BMO_error_clear(bm);
+ }
+ }
+ }
+ }
+
+ /* prepare for cleanup */
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+ vert_reverse_lookup = MEM_mallocN(sizeof(int) * bm->totvert, __func__);
+ fill_vn_i(vert_reverse_lookup, bm->totvert, -1);
+ for (i = 0, tot_found = 0; i < vinput_len; i++) {
+ BMVert *v = vinput_arr[i];
+ vert_reverse_lookup[BM_elem_index_get(v)] = i;
+ }
+
+ /* --- cleanup --- */
+ earray = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, __func__);
+ BM_ITER_MESH_INDEX (e_iter, &iter, bm, BM_EDGES_OF_MESH, i) {
+ earray[i] = e_iter;
+ }
+ /* remove all edges/verts left behind from dissolving, NULL'ing the vertex array so we dont re-use */
+ for (i = bm->totedge - 1; i != -1; i--) {
+ e_iter = earray[i];
+
+ if (BM_edge_is_wire(e_iter) && (BM_elem_flag_test(e_iter, BM_ELEM_TAG) == FALSE)) {
+ /* edge has become wire */
+ int vidx_reverse;
+ BMVert *v1 = e_iter->v1;
+ BMVert *v2 = e_iter->v2;
+ BM_edge_kill(bm, e_iter);
+ if (v1->e == NULL) {
+ vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v1)];
+ if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
+ BM_vert_kill(bm, v1);
+ }
+ if (v2->e == NULL) {
+ vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v2)];
+ if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
+ BM_vert_kill(bm, v2);
+ }
+ }
+ }
+ MEM_freeN(vert_reverse_lookup);
+
+ MEM_freeN(earray);
+
+
+ /* --- second verts --- */
+ for (i = 0, tot_found = 0; i < vinput_len; i++) {
+ BMVert *v = vinput_arr[i];
+ const float angle = v ? bm_vert_edge_face_angle(v) : angle_limit;
+
+ if (angle < angle_limit) {
+ weight_elems[i].ele = (BMHeader *)v;
+ weight_elems[i].weight = angle;
+ tot_found++;
+ }
+ else {
+ weight_elems[i].ele = NULL;
+ weight_elems[i].weight = angle_max;
+ }
+ }
+
+ if (tot_found != 0) {
+ qsort(weight_elems, vinput_len, sizeof(DissolveElemWeight), dissolve_elem_cmp);
+
+ for (i = 0; i < tot_found; i++) {
+ BMVert *v = (BMVert *)weight_elems[i].ele;
+ if (/* topology changes may cause this to be un-collapsable */
+ (BM_vert_edge_count(v) == 2) &&
+ /* check twice because cumulative effect could dissolve over angle limit */
+ bm_vert_edge_face_angle(v) < angle_limit)
+ {
+ BMEdge *ne = BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */
+
+ if (ne && ne->l) {
+ BM_edge_normals_update(ne);
+ }
+ }
+ }
+ }
+
+ MEM_freeN(weight_elems);
+}
+
+void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit)
+{
+ int vinput_len;
+ int einput_len;
+
+ BMVert **vinput_arr = BM_iter_as_arrayN(bm, BM_VERTS_OF_MESH, NULL, &vinput_len);
+ BMEdge **einput_arr = BM_iter_as_arrayN(bm, BM_EDGES_OF_MESH, NULL, &einput_len);
+
+ BM_mesh_decimate_dissolve_ex(bm, angle_limit,
+ vinput_arr, vinput_len,
+ einput_arr, einput_len);
+
+ MEM_freeN(vinput_arr);
+ MEM_freeN(einput_arr);
+}
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 84f6cb27b3b..41fe6b4dfec 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -477,182 +477,14 @@ void dummy_exec(BMesh *bm, BMOperator *op)
#endif
/* Limited Dissolve */
-
-#define UNIT_TO_ANGLE DEG2RADF(90.0f)
-#define ANGLE_TO_UNIT (1.0f / UNIT_TO_ANGLE)
-
-/* multiply vertex edge angle by face angle
- * this means we are not left with sharp corners between _almost_ planer faces
- * convert angles [0-PI/2] -> [0-1], multiply together, then convert back to radians. */
-static float bm_vert_edge_face_angle(BMVert *v)
-{
- const float angle = BM_vert_calc_edge_angle(v);
- /* note: could be either edge, it doesn't matter */
- if (v->e && BM_edge_is_manifold(v->e)) {
- return ((angle * ANGLE_TO_UNIT) * (BM_edge_calc_face_angle(v->e) * ANGLE_TO_UNIT)) * UNIT_TO_ANGLE;
- }
- else {
- return angle;
- }
-}
-
-#undef UNIT_TO_ANGLE
-#undef ANGLE_TO_UNIT
-
-typedef struct DissolveElemWeight {
- BMHeader *ele;
- float weight;
-} DissolveElemWeight;
-
-static int dissolve_elem_cmp(const void *a1, const void *a2)
-{
- const struct DissolveElemWeight *d1 = a1, *d2 = a2;
-
- if (d1->weight > d2->weight) return 1;
- else if (d1->weight < d2->weight) return -1;
- return 0;
-}
-
void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op)
{
BMOpSlot *einput = BMO_slot_get(op, "edges");
BMOpSlot *vinput = BMO_slot_get(op, "verts");
const float angle_max = (float)M_PI / 2.0f;
const float angle_limit = minf(angle_max, BMO_slot_float_get(op, "angle_limit"));
- DissolveElemWeight *weight_elems = MEM_mallocN(MAX2(einput->len, vinput->len) *
- sizeof(DissolveElemWeight), __func__);
- int i, tot_found;
-
- BMIter iter;
- BMEdge *e_iter;
- BMEdge **earray;
-
- int *vert_reverse_lookup;
-
- BMEdge **einput_arr = (BMEdge **)einput->data.p;
- BMVert **vinput_arr = (BMVert **)vinput->data.p;
-
- /* --- first edges --- */
-
- /* wire -> tag */
- BM_ITER_MESH (e_iter, &iter, bm, BM_EDGES_OF_MESH) {
- BM_elem_flag_set(e_iter, BM_ELEM_TAG, BM_edge_is_wire(e_iter));
- }
-
- /* go through and split edge */
- for (i = 0, tot_found = 0; i < einput->len; i++) {
- BMEdge *e = einput_arr[i];
- const float angle = BM_edge_calc_face_angle(e);
-
- if (angle < angle_limit) {
- tot_found++;
- }
- weight_elems[i].ele = (BMHeader *)e;
- weight_elems[i].weight = angle;
- }
-
- if (tot_found != 0) {
- qsort(weight_elems, einput->len, sizeof(DissolveElemWeight), dissolve_elem_cmp);
-
- for (i = 0; i < tot_found; i++) {
- BMEdge *e = (BMEdge *)weight_elems[i].ele;
-
- if (/* may have become non-manifold */
- BM_edge_is_manifold(e) &&
- /* check twice because cumulative effect could dissolve over angle limit */
- (BM_edge_calc_face_angle(e) < angle_limit))
- {
- BMFace *nf = BM_faces_join_pair(bm, e->l->f,
- e->l->radial_next->f,
- e,
- FALSE); /* join faces */
-
- /* there may be some errors, we don't mind, just move on */
- if (nf) {
- BM_face_normal_update(nf);
- }
- else {
- BMO_error_clear(bm);
- }
- }
- }
- }
-
- /* prepare for cleanup */
- BM_mesh_elem_index_ensure(bm, BM_VERT);
- vert_reverse_lookup = MEM_mallocN(sizeof(int) * bm->totvert, __func__);
- fill_vn_i(vert_reverse_lookup, bm->totvert, -1);
- for (i = 0, tot_found = 0; i < vinput->len; i++) {
- BMVert *v = vinput_arr[i];
- vert_reverse_lookup[BM_elem_index_get(v)] = i;
- }
-
- /* --- cleanup --- */
- earray = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, __func__);
- BM_ITER_MESH_INDEX (e_iter, &iter, bm, BM_EDGES_OF_MESH, i) {
- earray[i] = e_iter;
- }
- /* remove all edges/verts left behind from dissolving, NULL'ing the vertex array so we dont re-use */
- for (i = bm->totedge - 1; i != -1; i--) {
- e_iter = earray[i];
-
- if (BM_edge_is_wire(e_iter) && (BM_elem_flag_test(e_iter, BM_ELEM_TAG) == FALSE)) {
- /* edge has become wire */
- int vidx_reverse;
- BMVert *v1 = e_iter->v1;
- BMVert *v2 = e_iter->v2;
- BM_edge_kill(bm, e_iter);
- if (v1->e == NULL) {
- vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v1)];
- if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
- BM_vert_kill(bm, v1);
- }
- if (v2->e == NULL) {
- vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v2)];
- if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
- BM_vert_kill(bm, v2);
- }
- }
- }
- MEM_freeN(vert_reverse_lookup);
-
- MEM_freeN(earray);
-
-
- /* --- second verts --- */
- for (i = 0, tot_found = 0; i < vinput->len; i++) {
- BMVert *v = vinput_arr[i];
- const float angle = v ? bm_vert_edge_face_angle(v) : angle_limit;
-
- if (angle < angle_limit) {
- weight_elems[i].ele = (BMHeader *)v;
- weight_elems[i].weight = angle;
- tot_found++;
- }
- else {
- weight_elems[i].ele = NULL;
- weight_elems[i].weight = angle_max;
- }
- }
-
- if (tot_found != 0) {
- qsort(weight_elems, vinput->len, sizeof(DissolveElemWeight), dissolve_elem_cmp);
-
- for (i = 0; i < tot_found; i++) {
- BMVert *v = (BMVert *)weight_elems[i].ele;
- if (/* topology changes may cause this to be un-collapsable */
- (BM_vert_edge_count(v) == 2) &&
- /* check twice because cumulative effect could dissolve over angle limit */
- bm_vert_edge_face_angle(v) < angle_limit)
- {
- BMEdge *ne = BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */
-
- if (ne && ne->l) {
- BM_edge_normals_update(ne);
- }
- }
- }
- }
- MEM_freeN(weight_elems);
+ BM_mesh_decimate_dissolve_ex(bm, angle_limit,
+ vinput->data.p, vinput->len,
+ einput->data.p, einput->len);
}
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index f53287beb9d..6853eefd2ec 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -362,7 +362,9 @@ typedef struct DecimateModifierData {
ModifierData modifier;
float percent; /* (mode == MOD_DECIM_MODE_COLLAPSE) */
- int iter; /* (mode == MOD_DECIM_MODE_UNSUBDIV) */
+ short iter; /* (mode == MOD_DECIM_MODE_UNSUBDIV) */
+ short pad;
+ float angle; /* (mode == MOD_DECIM_MODE_DISSOLVE) */
char defgrp_name[64]; /* MAX_VGROUP_NAME */
short flag, mode;
@@ -377,7 +379,8 @@ enum {
enum {
MOD_DECIM_MODE_COLLAPSE,
- MOD_DECIM_MODE_UNSUBDIV
+ MOD_DECIM_MODE_UNSUBDIV,
+ MOD_DECIM_MODE_DISSOLVE /* called planar in the UI */
};
/* Smooth modifier flags */
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 36bdb6cc896..47212c4a231 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -1113,6 +1113,7 @@ static void rna_def_modifier_decimate(BlenderRNA *brna)
static EnumPropertyItem modifier_decim_mode_items[] = {
{MOD_DECIM_MODE_COLLAPSE, "COLLAPSE", 0, "Collapse", "Use edge collapsing"},
{MOD_DECIM_MODE_UNSUBDIV, "UNSUBDIV", 0, "Un-Subdivide", "Use un-subdivide face reduction"},
+ {MOD_DECIM_MODE_DISSOLVE, "DISSOLVE", 0, "Planar", "Dissolve geometry to form planar polygons"},
{0, NULL, 0, NULL, NULL}
};
@@ -1130,20 +1131,31 @@ static void rna_def_modifier_decimate(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mode", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ /* (mode == MOD_DECIM_MODE_COLLAPSE) */
prop = RNA_def_property(srna, "ratio", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "percent");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_range(prop, 0, 1, 1, 4);
- RNA_def_property_ui_text(prop, "Ratio", "Ratio of triangles to reduce to");
+ RNA_def_property_ui_text(prop, "Ratio", "Ratio of triangles to reduce to (collapse only)");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ /* (mode == MOD_DECIM_MODE_UNSUBDIV) */
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "iter");
RNA_def_property_range(prop, 0, SHRT_MAX);
RNA_def_property_ui_range(prop, 1, 100, 1, 0);
- RNA_def_property_ui_text(prop, "Iterations", "Number of times to unsubdivide");
+ RNA_def_property_ui_text(prop, "Iterations", "Number of times reduce the geometry (unsubdivide only)");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ /* (mode == MOD_DECIM_MODE_DISSOLVE) */
+ prop = RNA_def_property(srna, "angle_limit", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "angle");
+ RNA_def_property_range(prop, 0, DEG2RAD(180));
+ RNA_def_property_ui_range(prop, 0, DEG2RAD(180), 100, 2);
+ RNA_def_property_ui_text(prop, "Angle Limit", "Only dissolve angles below this(planar/dissolve only)");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* (mode == MOD_DECIM_MODE_COLLAPSE) */
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
@@ -1154,7 +1166,9 @@ static void rna_def_modifier_decimate(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_DECIM_FLAG_INVERT_VGROUP);
RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ /* end collapse-only option */
+ /* all modes use this */
prop = RNA_def_property(srna, "face_count", PROP_INT, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Face Count", "The current number of faces in the decimated mesh");
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 6eb2f8d6c79..71b3b6c883b 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -64,6 +64,7 @@ static void initData(ModifierData *md)
DecimateModifierData *dmd = (DecimateModifierData *) md;
dmd->percent = 1.0;
+ dmd->angle = DEG2RADF(15.0f);
}
static void copyData(ModifierData *md, ModifierData *target)
@@ -73,6 +74,7 @@ static void copyData(ModifierData *md, ModifierData *target)
tdmd->percent = dmd->percent;
tdmd->iter = dmd->iter;
+ tdmd->angle = dmd->angle;
BLI_strncpy(tdmd->defgrp_name, dmd->defgrp_name, sizeof(tdmd->defgrp_name));
tdmd->flag = dmd->flag;
tdmd->mode = dmd->mode;
@@ -149,9 +151,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
case MOD_DECIM_MODE_UNSUBDIV:
BM_mesh_decimate_unsubdivide(bm, dmd->iter);
break;
+ case MOD_DECIM_MODE_DISSOLVE:
+ BM_mesh_decimate_dissolve(bm, dmd->angle);
+ break;
}
-
if (vweights) {
MEM_freeN(vweights);
}