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:
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py3
-rw-r--r--source/blender/bmesh/intern/bmesh_decimate.c61
-rw-r--r--source/blender/bmesh/intern/bmesh_decimate.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h9
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c17
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c55
-rw-r--r--source/blender/modifiers/intern/MOD_util.h12
7 files changed, 134 insertions, 25 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 0398cb36b18..5d8144631b0 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -212,6 +212,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
def DECIMATE(self, layout, ob, md):
layout.prop(md, "ratio")
+ row = layout.row()
+ row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+ row.prop(md, "invert_vertex_group")
layout.label(text="Face Count" + ": %d" % md.face_count)
def DISPLACE(self, layout, ob, md):
diff --git a/source/blender/bmesh/intern/bmesh_decimate.c b/source/blender/bmesh/intern/bmesh_decimate.c
index dd836c7c4fc..978a1674121 100644
--- a/source/blender/bmesh/intern/bmesh_decimate.c
+++ b/source/blender/bmesh/intern/bmesh_decimate.c
@@ -144,7 +144,7 @@ static void bm_decim_calc_target_co(BMEdge *e, float optimize_co[3],
}
static void bm_decim_build_edge_cost_single(BMEdge *e,
- const Quadric *vquadrics,
+ const Quadric *vquadrics, const float *vweights,
Heap *eheap, HeapNode **eheap_table)
{
const Quadric *q1, *q2;
@@ -180,6 +180,16 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
eheap_table[BM_elem_index_get(e)] = NULL;
return;
}
+
+ if (vweights) {
+ if ((vweights[BM_elem_index_get(e->v1)] < FLT_EPSILON) &&
+ (vweights[BM_elem_index_get(e->v2)] < FLT_EPSILON))
+ {
+ /* skip collapsing this edge */
+ eheap_table[BM_elem_index_get(e)] = NULL;
+ return;
+ }
+ }
/* end sanity check */
@@ -188,14 +198,21 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
q1 = &vquadrics[BM_elem_index_get(e->v1)];
q2 = &vquadrics[BM_elem_index_get(e->v2)];
- cost = (BLI_quadric_evaluate(q1, optimize_co) + BLI_quadric_evaluate(q2, optimize_co));
+ if (vweights == NULL) {
+ cost = (BLI_quadric_evaluate(q1, optimize_co) +
+ BLI_quadric_evaluate(q2, optimize_co));
+ }
+ else {
+ cost = ((BLI_quadric_evaluate(q1, optimize_co) * vweights[BM_elem_index_get(e->v1)]) +
+ (BLI_quadric_evaluate(q2, optimize_co) * vweights[BM_elem_index_get(e->v2)]));
+ }
// print("COST %.12f\n");
eheap_table[BM_elem_index_get(e)] = BLI_heap_insert(eheap, cost, e);
}
static void bm_decim_build_edge_cost(BMesh *bm,
- const Quadric *vquadrics,
+ const Quadric *vquadrics, const float *vweights,
Heap *eheap, HeapNode **eheap_table)
{
BMIter iter;
@@ -204,7 +221,7 @@ static void bm_decim_build_edge_cost(BMesh *bm,
BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
eheap_table[i] = NULL; /* keep sanity check happy */
- bm_decim_build_edge_cost_single(e, vquadrics, eheap, eheap_table);
+ bm_decim_build_edge_cost_single(e, vquadrics, vweights, eheap, eheap_table);
#ifdef USE_PRESERVE_BOUNDARY
/* init: runs second! */
@@ -268,15 +285,16 @@ static int bm_decim_triangulate_begin(BMesh *bm)
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
if (f->len == 4) {
BMLoop *f_l[4];
- BMLoop *l_iter;
BMLoop *l_a, *l_b;
- l_iter = BM_FACE_FIRST_LOOP(f);
+ {
+ BMLoop *l_iter = BM_FACE_FIRST_LOOP(f);
- f_l[0] = l_iter; l_iter = l_iter->next;
- f_l[1] = l_iter; l_iter = l_iter->next;
- f_l[2] = l_iter; l_iter = l_iter->next;
- f_l[3] = l_iter; l_iter = l_iter->next;
+ f_l[0] = l_iter; l_iter = l_iter->next;
+ f_l[1] = l_iter; l_iter = l_iter->next;
+ f_l[2] = l_iter; l_iter = l_iter->next;
+ f_l[3] = l_iter;
+ }
if (len_squared_v3v3(f_l[0]->v->co, f_l[2]->v->co) <
len_squared_v3v3(f_l[1]->v->co, f_l[3]->v->co))
@@ -764,7 +782,7 @@ static int bm_edge_collapse(BMesh *bm, BMEdge *e_clear, BMVert *v_clear, int r_e
/* collapse e the edge, removing e->v2 */
static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
- Quadric *vquadrics,
+ Quadric *vquadrics, float *vweights,
Heap *eheap, HeapNode **eheap_table,
const CD_UseFlag customdata_flag)
{
@@ -796,6 +814,12 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
/* update collapse info */
int i;
+ if (vweights) {
+ const int fac = CLAMPIS(customdata_fac, 0.0f, 1.0f);
+ vweights[BM_elem_index_get(v_other)] = (vweights[v_clear_index] * (1.0f - fac)) +
+ (vweights[BM_elem_index_get(v_other)] * fac);
+ }
+
e = NULL; /* paranoid safety check */
copy_v3_v3(v_other->co, optimize_co);
@@ -825,7 +849,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
e_iter = e_first = v_other->e;
do {
BLI_assert(BM_edge_find_double(e_iter) == NULL);
- bm_decim_build_edge_cost_single(e_iter, vquadrics, eheap, eheap_table);
+ bm_decim_build_edge_cost_single(e_iter, vquadrics, vweights, eheap, eheap_table);
} while ((e_iter = bmesh_disk_edge_next(e_iter, v_other)) != e_first);
}
@@ -857,7 +881,14 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
/* Main Decimate Function
* ********************** */
-void BM_mesh_decimate(BMesh *bm, const float factor)
+/**
+ * \brief BM_mesh_decimate
+ * \param bm The mesh
+ * \param factor face count multiplier [0 - 1]
+ * \param vertex_weights Optional array of vertex aligned weights [0 - 1],
+ * a vertex group is the usual source for this.
+ */
+void BM_mesh_decimate(BMesh *bm, const float factor, float *vweights)
{
Heap *eheap; /* edge heap */
HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */
@@ -885,7 +916,7 @@ void BM_mesh_decimate(BMesh *bm, const float factor)
/* build initial edge collapse cost data */
bm_decim_build_quadrics(bm, vquadrics);
- bm_decim_build_edge_cost(bm, vquadrics, eheap, eheap_table);
+ bm_decim_build_edge_cost(bm, vquadrics, vweights, eheap, eheap_table);
face_tot_target = bm->totface * factor;
bm->elem_index_dirty |= BM_FACE | BM_EDGE | BM_VERT;
@@ -910,7 +941,7 @@ void BM_mesh_decimate(BMesh *bm, const float factor)
* but NULL just incase so we don't use freed node */
eheap_table[BM_elem_index_get(e)] = NULL;
- bm_decim_edge_collapse(bm, e, vquadrics, eheap, eheap_table, customdata_flag);
+ bm_decim_edge_collapse(bm, e, vquadrics, vweights, eheap, eheap_table, customdata_flag);
}
diff --git a/source/blender/bmesh/intern/bmesh_decimate.h b/source/blender/bmesh/intern/bmesh_decimate.h
index e44aa576bda..1724bbd16bb 100644
--- a/source/blender/bmesh/intern/bmesh_decimate.h
+++ b/source/blender/bmesh/intern/bmesh_decimate.h
@@ -27,6 +27,6 @@
* \ingroup bmesh
*/
-void BM_mesh_decimate(BMesh *bm, const float factor);
+void BM_mesh_decimate(BMesh *bm, const float factor, float *vweights);
#endif /* __BMESH_DECIMATE_H__ */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index fe82d27cfa8..05c1871ae41 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -362,9 +362,16 @@ typedef struct DecimateModifierData {
ModifierData modifier;
float percent;
- int faceCount;
+ int faceCount; /* runtime only */
+
+ char defgrp_name[64]; /* MAX_VGROUP_NAME */
+ int flag, pad;
} DecimateModifierData;
+enum {
+ MOD_DECIM_INVERT_VGROUP = (1 << 0)
+};
+
/* Smooth modifier flags */
#define MOD_SMOOTH_X (1<<1)
#define MOD_SMOOTH_Y (1<<2)
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 1fcf4107682..67ab1469318 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -377,6 +377,12 @@ static void rna_SolidifyModifier_vgroup_set(PointerRNA *ptr, const char *value)
rna_object_vgroup_name_set(ptr, value, smd->defgrp_name, sizeof(smd->defgrp_name));
}
+static void rna_DecimateModifier_vgroup_set(PointerRNA *ptr, const char *value)
+{
+ DecimateModifierData *dmd = (DecimateModifierData *)ptr->data;
+ rna_object_vgroup_name_set(ptr, value, dmd->defgrp_name, sizeof(dmd->defgrp_name));
+}
+
static void rna_WeightVGModifier_vgroup_set(PointerRNA *ptr, const char *value)
{
ModifierData *md = (ModifierData *)ptr->data;
@@ -1119,6 +1125,17 @@ static void rna_def_modifier_decimate(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Ratio", "Ratio of triangles to reduce to");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ 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");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_DecimateModifier_vgroup_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_DECIM_INVERT_VGROUP);
+ RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "face_count", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "faceCount");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index d55bc7ab9b1..a882e4f5854 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -32,9 +32,10 @@
* \ingroup modifiers
*/
-#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
#include "BLI_math.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -43,6 +44,7 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
+#include "BKE_deform.h"
#include "BKE_particle.h"
#include "BKE_cdderivedmesh.h"
@@ -70,9 +72,22 @@ static void copyData(ModifierData *md, ModifierData *target)
DecimateModifierData *tdmd = (DecimateModifierData *) target;
tdmd->percent = dmd->percent;
+ BLI_strncpy(tdmd->defgrp_name, dmd->defgrp_name, sizeof(tdmd->defgrp_name));
+ tdmd->flag = dmd->flag;
}
-static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
+static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
+{
+ DecimateModifierData *dmd = (DecimateModifierData *) md;
+ CustomDataMask dataMask = 0;
+
+ /* ask for vertexgroups if we need them */
+ if (dmd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT;
+
+ return dataMask;
+}
+
+static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
@@ -81,6 +96,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
BMEditMesh *em;
BMesh *bm;
+ float *vweights = NULL;
+
#ifdef USE_TIMEIT
TIMEIT_START(decim);
#endif
@@ -93,10 +110,40 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
return dm;
}
+ if (dmd->defgrp_name[0]) {
+ MDeformVert *dvert;
+ int defgrp_index;
+
+ modifier_get_vgroup(ob, dm, dmd->defgrp_name, &dvert, &defgrp_index);
+
+ if (dvert) {
+ const unsigned int vert_tot = dm->getNumVerts(dm);
+ unsigned int i;
+
+ vweights = MEM_mallocN(vert_tot * sizeof(float), __func__);
+
+ if (dmd->flag & MOD_DECIM_INVERT_VGROUP) {
+ for (i = 0; i < vert_tot; i++) {
+ vweights[i] = 1.0f - defvert_find_weight(&dvert[i], defgrp_index);
+ }
+ }
+ else {
+ for (i = 0; i < vert_tot; i++) {
+ vweights[i] = defvert_find_weight(&dvert[i], defgrp_index);
+ }
+ }
+ }
+ }
+
+
em = DM_to_editbmesh(dm, NULL, FALSE);
bm = em->bm;
- BM_mesh_decimate(bm, dmd->percent);
+ BM_mesh_decimate(bm, dmd->percent, vweights);
+
+ if (vweights) {
+ MEM_freeN(vweights);
+ }
dmd->faceCount = bm->totface;
@@ -126,7 +173,7 @@ ModifierTypeInfo modifierType_Decimate = {
/* applyModifier */ applyModifier,
/* applyModifierEM */ NULL,
/* initData */ initData,
- /* requiredDataMask */ NULL,
+ /* requiredDataMask */ requiredDataMask,
/* freeData */ NULL,
/* isDisabled */ NULL,
/* updateDepgraph */ NULL,
diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h
index eadf7af553b..6f05c9a957a 100644
--- a/source/blender/modifiers/intern/MOD_util.h
+++ b/source/blender/modifiers/intern/MOD_util.h
@@ -42,10 +42,14 @@ struct TexResult;
void modifier_init_texture(struct Scene *scene, struct Tex *texture);
void get_texture_value(struct Tex *texture, float *tex_co, struct TexResult *texres);
-void get_texture_coords(struct MappingInfoModifierData *dmd, struct Object *ob, struct DerivedMesh *dm, float (*co)[3], float (*texco)[3], int numVerts);
+void get_texture_coords(struct MappingInfoModifierData *dmd, struct Object *ob, struct DerivedMesh *dm,
+ float (*co)[3], float (*texco)[3], int numVerts);
void modifier_vgroup_cache(struct ModifierData *md, float (*vertexCos)[3]);
-struct DerivedMesh *get_cddm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3]);
-struct DerivedMesh *get_dm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3], int orco);
-void modifier_get_vgroup(struct Object *ob, struct DerivedMesh *dm, const char *name, struct MDeformVert **dvert, int *defgrp_index);
+struct DerivedMesh *get_cddm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm,
+ float (*vertexCos)[3]);
+struct DerivedMesh *get_dm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm,
+ float (*vertexCos)[3], int orco);
+void modifier_get_vgroup(struct Object *ob, struct DerivedMesh *dm,
+ const char *name, struct MDeformVert **dvert, int *defgrp_index);
#endif /* __MOD_UTIL_H__ */