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:
Diffstat (limited to 'source/blender/editors/object/object_vgroup.c')
-rw-r--r--source/blender/editors/object/object_vgroup.c158
1 files changed, 106 insertions, 52 deletions
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 352c90e805a..4619f998a11 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -257,7 +257,6 @@ void ED_vgroup_parray_mirror_sync(Object *ob,
BMEditMesh *em = BKE_editmesh_from_object(ob);
MDeformVert **dvert_array_all = NULL;
int dvert_tot_all;
- int i;
/* get an array of all verts, not only selected */
if (ED_vgroup_parray_alloc(ob->data, &dvert_array_all, &dvert_tot_all, false) == false) {
@@ -268,22 +267,26 @@ void ED_vgroup_parray_mirror_sync(Object *ob,
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
}
- for (i = 0; i < dvert_tot; i++) {
- if (dvert_array[i] == NULL) {
- /* its unselected, check if its mirror is */
- int i_sel = ED_mesh_mirror_get_vert(ob, i);
- if ((i_sel != -1) && (i_sel != i) && (dvert_array[i_sel])) {
+ int flip_map_len;
+ const int *flip_map = defgroup_flip_map(ob, &flip_map_len, true);
+
+ for (int i_src = 0; i_src < dvert_tot; i_src++) {
+ if (dvert_array[i_src] != NULL) {
+ /* its selected, check if its mirror exists */
+ int i_dst = ED_mesh_mirror_get_vert(ob, i_src);
+ if (i_dst != -1 && dvert_array_all[i_dst] != NULL) {
/* we found a match! */
- MDeformVert *dv_src = dvert_array[i_sel];
- MDeformVert *dv_dst = dvert_array_all[i];
+ const MDeformVert *dv_src = dvert_array[i_src];
+ MDeformVert *dv_dst = dvert_array_all[i_dst];
- defvert_copy_subset(dv_dst, dv_src, vgroup_validmap, vgroup_tot);
+ defvert_mirror_subset(dv_dst, dv_src, vgroup_validmap, vgroup_tot, flip_map, flip_map_len);
- dvert_array[i] = dvert_array_all[i];
+ dvert_array[i_dst] = dvert_array_all[i_dst];
}
}
}
+ MEM_freeN((void *)flip_map);
MEM_freeN(dvert_array_all);
}
@@ -517,7 +520,7 @@ static void ED_mesh_defvert_mirror_update_ob(Object *ob, int def_nr, int vidx)
if (vidx == -1)
return;
- vidx_mirr = mesh_get_x_mirror_vert(ob, vidx, use_topology);
+ vidx_mirr = mesh_get_x_mirror_vert(ob, NULL, vidx, use_topology);
if ((vidx_mirr) >= 0 && (vidx_mirr != vidx)) {
MDeformVert *dvert_src = &me->dvert[vidx];
@@ -566,7 +569,7 @@ static void vgroup_remove_weight(Object *ob, const int def_nr)
}
-static void vgroup_normalize_active(Object *ob, eVGroupSelect subset_type)
+static bool vgroup_normalize_active_vertex(Object *ob, eVGroupSelect subset_type)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
@@ -585,7 +588,7 @@ static void vgroup_normalize_active(Object *ob, eVGroupSelect subset_type)
}
if (dvert_act == NULL) {
- return;
+ return false;
}
vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
@@ -601,6 +604,8 @@ static void vgroup_normalize_active(Object *ob, eVGroupSelect subset_type)
ED_mesh_defvert_mirror_update_ob(ob, -1, v_act);
}
}
+
+ return true;
}
static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type)
@@ -1067,7 +1072,7 @@ static void vgroup_duplicate(Object *ob)
}
}
-static void vgroup_normalize(Object *ob)
+static bool vgroup_normalize(Object *ob)
{
MDeformWeight *dw;
MDeformVert *dv, **dvert_array = NULL;
@@ -1077,7 +1082,7 @@ static void vgroup_normalize(Object *ob)
const int use_vert_sel = vertex_group_use_vert_sel(ob);
if (!BLI_findlink(&ob->defbase, def_nr)) {
- return;
+ return false;
}
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
@@ -1117,7 +1122,11 @@ static void vgroup_normalize(Object *ob)
}
MEM_freeN(dvert_array);
+
+ return true;
}
+
+ return false;
}
/* This finds all of the vertices face-connected to vert by an edge and returns a
@@ -1521,11 +1530,13 @@ static void vgroup_levels_subset(Object *ob, const bool *vgroup_validmap, const
}
}
-static void vgroup_normalize_all(Object *ob,
- const bool *vgroup_validmap,
- const int vgroup_tot,
- const int subset_count,
- const bool lock_active)
+static bool vgroup_normalize_all(
+ Object *ob,
+ const bool *vgroup_validmap,
+ const int vgroup_tot,
+ const int subset_count,
+ const bool lock_active,
+ ReportList *reports)
{
MDeformVert *dv, **dvert_array = NULL;
int i, dvert_tot = 0;
@@ -1533,8 +1544,9 @@ static void vgroup_normalize_all(Object *ob,
const int use_vert_sel = vertex_group_use_vert_sel(ob);
- if ((lock_active && !BLI_findlink(&ob->defbase, def_nr)) || subset_count == 0) {
- return;
+ if (subset_count == 0) {
+ BKE_report(reports, RPT_ERROR, "No vertex groups to operate on");
+ return false;
}
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
@@ -1542,6 +1554,7 @@ static void vgroup_normalize_all(Object *ob,
if (dvert_array) {
const int defbase_tot = BLI_listbase_count(&ob->defbase);
bool *lock_flags = BKE_object_defgroup_lock_flags_get(ob, defbase_tot);
+ bool changed = false;
if ((lock_active == true) &&
(lock_flags != NULL) &&
@@ -1550,6 +1563,19 @@ static void vgroup_normalize_all(Object *ob,
lock_flags[def_nr] = true;
}
+ if (lock_flags) {
+ for (i = 0; i < defbase_tot; i++) {
+ if (lock_flags[i] == false) {
+ break;
+ }
+ }
+
+ if (i == defbase_tot) {
+ BKE_report(reports, RPT_ERROR, "All groups are locked");
+ goto finally;
+ }
+ }
+
for (i = 0; i < dvert_tot; i++) {
/* in case its not selected */
if ((dv = dvert_array[i])) {
@@ -1567,12 +1593,19 @@ static void vgroup_normalize_all(Object *ob,
}
}
+ changed = true;
+
+finally:
if (lock_flags) {
MEM_freeN(lock_flags);
}
MEM_freeN(dvert_array);
+
+ return changed;
}
+
+ return false;
}
enum {
@@ -1688,7 +1721,7 @@ static void vgroup_smooth_subset(
{
const float ifac = 1.0f - fac;
MDeformVert **dvert_array = NULL;
- int i, dvert_tot = 0;
+ int dvert_tot = 0;
int *vgroup_subset_map = BLI_array_alloca(vgroup_subset_map, subset_count);
float *vgroup_subset_weights = BLI_array_alloca(vgroup_subset_weights, subset_count);
const bool use_mirror = (ob->type == OB_MESH) ? (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X) != 0 : false;
@@ -1738,7 +1771,7 @@ static void vgroup_smooth_subset(
/* initialize used verts */
if (bm) {
- for (i = 0; i < dvert_tot; i++) {
+ for (int i = 0; i < dvert_tot; i++) {
BMVert *v = BM_vert_at_index(bm, i);
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
BMIter eiter;
@@ -1756,14 +1789,11 @@ static void vgroup_smooth_subset(
}
}
else {
- for (i = 0; i < dvert_tot; i++) {
+ for (int i = 0; i < dvert_tot; i++) {
MVert *v = &me->mvert[i];
if (v->flag & SELECT) {
- int j;
- for (j = 0; j < emap[i].count; j++) {
- MEdge *e = &me->medge[emap[i].indices[j]];
- const int i_other = (e->v1 == i ? e->v2 : e->v1);
- MVert *v_other = &me->mvert[i_other];
+ for (int j = 0; j < emap[i].count; j++) {
+ MVert *v_other = &me->mvert[emap[i].indices[j]];
if ((source == WEIGHT_SMOOTH_ALL) ||
(source == ((v_other->flag & SELECT) != 0)))
{
@@ -1798,13 +1828,13 @@ static void vgroup_smooth_subset(
float tot_factor = 1.0f; \
if (expand_sign == 1) { /* expand */ \
if (weight_other < weight_accum_prev[i]) { \
- weight_other = (weight_accum_prev[i_other] * iexpand) + (weight_other * expand); \
+ weight_other = (weight_accum_prev[i] * expand) + (weight_other * iexpand); \
tot_factor = iexpand; \
} \
} \
else if (expand_sign == -1) { /* contract */ \
if (weight_other > weight_accum_prev[i]) { \
- weight_other = (weight_accum_prev[i_other] * iexpand) + (weight_other * expand); \
+ weight_other = (weight_accum_prev[i] * expand) + (weight_other * iexpand); \
tot_factor = iexpand; \
} \
} \
@@ -2093,7 +2123,7 @@ static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr,
defvert_copy(dvert, dvert_mirr);
}
else {
- defvert_copy_index(dvert, dvert_mirr, act_vgroup);
+ defvert_copy_index(dvert, act_vgroup, dvert_mirr, act_vgroup);
}
}
@@ -2214,7 +2244,7 @@ void ED_vgroup_mirror(Object *ob,
for (vidx = 0, mv = me->mvert; vidx < me->totvert; vidx++, mv++) {
if ((mv->flag & ME_VERT_TMP_TAG) == 0) {
- if ((vidx_mirr = mesh_get_x_mirror_vert(ob, vidx, use_topology)) != -1) {
+ if ((vidx_mirr = mesh_get_x_mirror_vert(ob, NULL, vidx, use_topology)) != -1) {
if (vidx != vidx_mirr) {
mv_mirr = &me->mvert[vidx_mirr];
if ((mv_mirr->flag & ME_VERT_TMP_TAG) == 0) {
@@ -2826,14 +2856,20 @@ void OBJECT_OT_vertex_group_levels(wmOperatorType *ot)
static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
+ bool changed;
- vgroup_normalize(ob);
+ changed = vgroup_normalize(ob);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ if (changed) {
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void OBJECT_OT_vertex_group_normalize(wmOperatorType *ot)
@@ -2856,18 +2892,24 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_context(C);
bool lock_active = RNA_boolean_get(op->ptr, "lock_active");
eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode");
-
+ bool changed;
int subset_count, vgroup_tot;
-
const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(ob, subset_type, &vgroup_tot, &subset_count);
- vgroup_normalize_all(ob, vgroup_validmap, vgroup_tot, subset_count, lock_active);
+
+ changed = vgroup_normalize_all(ob, vgroup_validmap, vgroup_tot, subset_count, lock_active, op->reports);
MEM_freeN((void *)vgroup_validmap);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+ if (changed) {
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
+ }
+ else {
+ /* allow to adjust settings */
+ return OPERATOR_FINISHED;
+ }
}
void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot)
@@ -3285,8 +3327,14 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
if (obact != ob) {
- if (ED_vgroup_array_copy(ob, obact)) changed_tot++;
- else fail++;
+ if (ED_vgroup_array_copy(ob, obact)) {
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob);
+ changed_tot++;
+ }
+ else {
+ fail++;
+ }
}
}
CTX_DATA_END;
@@ -3825,13 +3873,19 @@ static int vertex_weight_normalize_active_vertex_exec(bContext *C, wmOperator *U
Object *ob = ED_object_context(C);
ToolSettings *ts = CTX_data_tool_settings(C);
eVGroupSelect subset_type = ts->vgroupsubset;
+ bool changed;
- vgroup_normalize_active(ob, subset_type);
+ changed = vgroup_normalize_active_vertex(ob, subset_type);
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+ if (changed) {
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void OBJECT_OT_vertex_weight_normalize_active_vertex(wmOperatorType *ot)