Fix T84520: Make the different weight paint code paths exclusive to each other
Before this change, you could have the new sculpt symmetry code and the older weight paint symmetry code active at the same time. This would lead to users easily trashing their weigh paint data if they were not careful when switching between modes. Now the specific weight paint symmetry code is an exclusive toggle so the user can't accidentally mirror strokes and vertex groups at the same time. This also paves the way of supporting Y and Z symmetry in the future for weight groups mirroring if we decide to add it in the future. Reviewed By: Sybren Differential Revision: http://developer.blender.org/D10426
This commit is contained in:
@@ -161,9 +161,9 @@ class VIEW3D_HT_tool_header(Header):
|
||||
elif mode_string in {'EDIT_MESH', 'PAINT_WEIGHT', 'SCULPT', 'PAINT_VERTEX', 'PAINT_TEXTURE'}:
|
||||
# Mesh Modes, Use Mesh Symmetry
|
||||
row, sub = row_for_mirror()
|
||||
sub.prop(context.object.data, "use_mirror_x", text="X", toggle=True)
|
||||
sub.prop(context.object.data, "use_mirror_y", text="Y", toggle=True)
|
||||
sub.prop(context.object.data, "use_mirror_z", text="Z", toggle=True)
|
||||
sub.prop(context.object, "use_mesh_mirror_x", text="X", toggle=True)
|
||||
sub.prop(context.object, "use_mesh_mirror_y", text="Y", toggle=True)
|
||||
sub.prop(context.object, "use_mesh_mirror_z", text="Z", toggle=True)
|
||||
if mode_string == 'EDIT_MESH':
|
||||
tool_settings = context.tool_settings
|
||||
layout.prop(tool_settings, "use_mesh_automerge", text="")
|
||||
|
||||
@@ -123,13 +123,15 @@ class View3DPanel:
|
||||
# **************** standard tool clusters ******************
|
||||
|
||||
# Used by vertex & weight paint
|
||||
def draw_vpaint_symmetry(layout, vpaint, mesh):
|
||||
def draw_vpaint_symmetry(layout, vpaint, obj):
|
||||
col = layout.column()
|
||||
row = col.row(heading="Mirror", align=True)
|
||||
row.prop(mesh, "use_mirror_x", text="X", toggle=True)
|
||||
row.prop(mesh, "use_mirror_y", text="Y", toggle=True)
|
||||
row.prop(mesh, "use_mirror_z", text="Z", toggle=True)
|
||||
row.prop(obj, "use_mesh_mirror_x", text="X", toggle=True)
|
||||
row.prop(obj, "use_mesh_mirror_y", text="Y", toggle=True)
|
||||
row.prop(obj, "use_mesh_mirror_z", text="Z", toggle=True)
|
||||
|
||||
col = layout.column()
|
||||
col.active = not obj.data.use_mirror_vertex_groups
|
||||
col.prop(vpaint, "radial_symmetry", text="Radial")
|
||||
|
||||
|
||||
@@ -977,12 +979,12 @@ class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel):
|
||||
wpaint = tool_settings.weight_paint
|
||||
mesh = context.object.data
|
||||
|
||||
draw_vpaint_symmetry(layout, wpaint, mesh)
|
||||
layout.prop(mesh, 'use_mirror_vertex_groups')
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(mesh, 'use_mirror_vertex_group_x', text="Vertex Group X")
|
||||
row = col.row()
|
||||
row.active = mesh.use_mirror_vertex_group_x
|
||||
draw_vpaint_symmetry(layout, wpaint, context.object)
|
||||
|
||||
row = layout.row()
|
||||
row.active = mesh.use_mirror_vertex_groups
|
||||
row.prop(mesh, "use_mirror_topology")
|
||||
|
||||
|
||||
@@ -1057,7 +1059,7 @@ class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel):
|
||||
tool_settings = context.tool_settings
|
||||
vpaint = tool_settings.vertex_paint
|
||||
|
||||
draw_vpaint_symmetry(layout, vpaint, context.object.data)
|
||||
draw_vpaint_symmetry(layout, vpaint, context.object)
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_vertexpaint_symmetry_for_topbar(Panel):
|
||||
|
||||
@@ -397,7 +397,7 @@ static void drw_mesh_weight_state_extract(Object *ob,
|
||||
wstate->flags |= DRW_MESH_WEIGHT_STATE_MULTIPAINT |
|
||||
(ts->auto_normalize ? DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE : 0);
|
||||
|
||||
if (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) {
|
||||
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
|
||||
BKE_object_defgroup_mirror_selection(ob,
|
||||
wstate->defgroup_len,
|
||||
wstate->defgroup_sel,
|
||||
|
||||
@@ -1751,7 +1751,7 @@ static bool *vgroup_selected_get(Object *ob)
|
||||
/* Mirror the selection if X Mirror is enabled. */
|
||||
Mesh *me = BKE_mesh_from_object(ob);
|
||||
|
||||
if (me && (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) != 0) {
|
||||
if (me && ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
|
||||
BKE_object_defgroup_mirror_selection(ob, defbase_tot, mask, mask, &sel_count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -769,8 +769,8 @@ static void do_weight_paint_vertex_single(
|
||||
MDeformVert *dv_mirr;
|
||||
MDeformWeight *dw_mirr;
|
||||
|
||||
/* from now on we can check if mirrors enabled if this var is -1 and not bother with the flag */
|
||||
if (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) {
|
||||
/* Check if we should mirror vertex groups (X-axis). */
|
||||
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
|
||||
index_mirr = mesh_get_x_mirror_vert(ob, NULL, index, topology);
|
||||
vgroup_mirr = wpi->mirror.index;
|
||||
|
||||
@@ -979,8 +979,8 @@ static void do_weight_paint_vertex_multi(
|
||||
float curw, curw_real, oldw, neww, change, curw_mirr, change_mirr;
|
||||
float dw_rel_free, dw_rel_locked;
|
||||
|
||||
/* from now on we can check if mirrors enabled if this var is -1 and not bother with the flag */
|
||||
if (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) {
|
||||
/* Check if we should mirror vertex groups (X-axis). */
|
||||
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
|
||||
index_mirr = mesh_get_x_mirror_vert(ob, NULL, index, topology);
|
||||
|
||||
if (!ELEM(index_mirr, -1, index)) {
|
||||
@@ -1629,7 +1629,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
|
||||
int i;
|
||||
bDeformGroup *dg;
|
||||
|
||||
if (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) {
|
||||
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
|
||||
BKE_object_defgroup_mirror_selection(
|
||||
ob, defbase_tot, defbase_sel, defbase_sel, &defbase_tot_sel);
|
||||
}
|
||||
@@ -2191,7 +2191,7 @@ static void wpaint_paint_leaves(bContext *C,
|
||||
|
||||
/* NOTE: current mirroring code cannot be run in parallel */
|
||||
TaskParallelSettings settings;
|
||||
const bool use_threading = ((me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) == 0);
|
||||
const bool use_threading = !ME_USING_MIRROR_X_VERTEX_GROUPS(me);
|
||||
BKE_pbvh_parallel_range_settings(&settings, use_threading, totnode);
|
||||
|
||||
switch ((eBrushWeightPaintTool)brush->weightpaint_tool) {
|
||||
@@ -2322,6 +2322,13 @@ static void wpaint_do_symmetrical_brush_actions(
|
||||
|
||||
cache->symmetry = symm;
|
||||
|
||||
if (me->editflag & ME_EDIT_MIRROR_VERTEX_GROUPS) {
|
||||
/* We don't do any symmetry strokes when mirroing vertex groups. */
|
||||
copy_v3_v3(cache->true_last_location, cache->true_location);
|
||||
cache->is_last_valid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/* symm is a bit combination of XYZ - 1 is mirror
|
||||
* X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
|
||||
for (i = 1; i <= symm; i++) {
|
||||
|
||||
@@ -235,7 +235,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
||||
vc.obact, defbase_tot, &defbase_tot_sel);
|
||||
|
||||
if (defbase_tot_sel > 1) {
|
||||
if (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) {
|
||||
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
|
||||
BKE_object_defgroup_mirror_selection(
|
||||
vc.obact, defbase_tot, defbase_sel, defbase_sel, &defbase_tot_sel);
|
||||
}
|
||||
@@ -461,7 +461,7 @@ static bool weight_paint_set(Object *ob, float paintweight)
|
||||
vgroup_active = ob->actdef - 1;
|
||||
|
||||
/* if mirror painting, find the other group */
|
||||
if (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) {
|
||||
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
|
||||
vgroup_mirror = ED_wpaint_mirror_vgroup_ensure(ob, vgroup_active);
|
||||
}
|
||||
|
||||
@@ -489,7 +489,8 @@ static bool weight_paint_set(Object *ob, float paintweight)
|
||||
dw_prev->weight = dw->weight; /* set the undo weight */
|
||||
dw->weight = paintweight;
|
||||
|
||||
if (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) { /* x mirror painting */
|
||||
if (me->symmetry & ME_SYMMETRY_X) {
|
||||
/* x mirror painting */
|
||||
int j = mesh_get_x_mirror_vert(ob, NULL, vidx, topology);
|
||||
if (j >= 0) {
|
||||
/* copy, not paint again */
|
||||
|
||||
@@ -118,7 +118,7 @@ bool ED_wpaint_ensure_data(bContext *C,
|
||||
}
|
||||
|
||||
if (flag & WPAINT_ENSURE_MIRROR) {
|
||||
if (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) {
|
||||
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
|
||||
int mirror = ED_wpaint_mirror_vgroup_ensure(ob, ob->actdef - 1);
|
||||
if (vgroup_index) {
|
||||
vgroup_index->mirror = mirror;
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
.face_sets_color_seed = 0, \
|
||||
.face_sets_color_default = 1, \
|
||||
.flag = ME_REMESH_FIX_POLES | ME_REMESH_REPROJECT_VOLUME, \
|
||||
.editflag = ME_EDIT_MIRROR_VERTEX_GROUPS \
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -263,7 +263,7 @@ enum {
|
||||
|
||||
/* me->editflag */
|
||||
enum {
|
||||
ME_EDIT_VERTEX_GROUPS_X_SYMMETRY = 1 << 0,
|
||||
ME_EDIT_MIRROR_VERTEX_GROUPS = 1 << 0,
|
||||
ME_EDIT_MIRROR_Y = 1 << 1, /* unused so far */
|
||||
ME_EDIT_MIRROR_Z = 1 << 2, /* unused so far */
|
||||
|
||||
@@ -272,12 +272,16 @@ enum {
|
||||
ME_EDIT_PAINT_VERT_SEL = 1 << 5,
|
||||
};
|
||||
|
||||
/* we cant have both flags enabled at once,
|
||||
/* Helper macro to see if vertex group X mirror is on. */
|
||||
#define ME_USING_MIRROR_X_VERTEX_GROUPS(_me) \
|
||||
(((_me)->editflag & ME_EDIT_MIRROR_VERTEX_GROUPS) && ((_me)->symmetry & ME_SYMMETRY_X))
|
||||
|
||||
/* We cant have both flags enabled at once,
|
||||
* flags defined in DNA_scene_types.h */
|
||||
#define ME_EDIT_PAINT_SEL_MODE(_me) \
|
||||
(((_me)->editflag & ME_EDIT_PAINT_FACE_SEL) ? \
|
||||
SCE_SELECT_FACE : \
|
||||
((_me)->editflag & ME_EDIT_PAINT_VERT_SEL) ? SCE_SELECT_VERTEX : 0)
|
||||
(((_me)->editflag & ME_EDIT_PAINT_FACE_SEL) ? SCE_SELECT_FACE : \
|
||||
((_me)->editflag & ME_EDIT_PAINT_VERT_SEL) ? SCE_SELECT_VERTEX : \
|
||||
0)
|
||||
|
||||
/* me->flag */
|
||||
enum {
|
||||
|
||||
@@ -3289,10 +3289,12 @@ static void rna_def_mesh(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Z", "Enable symmetry in the Z axis");
|
||||
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
|
||||
|
||||
prop = RNA_def_property(srna, "use_mirror_vertex_group_x", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_VERTEX_GROUPS_X_SYMMETRY);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Vertex Groups X Symmetry", "Mirror the left/right vertex groups when painting");
|
||||
prop = RNA_def_property(srna, "use_mirror_vertex_groups", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_MIRROR_VERTEX_GROUPS);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Mirror Vertex Groups",
|
||||
"Mirror the left/right vertex groups when painting. The symmetry axis "
|
||||
"is determined by the symmetry settings");
|
||||
RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
|
||||
/* End Symmetry */
|
||||
|
||||
|
||||
@@ -2106,6 +2106,81 @@ static void rna_object_lineart_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
|
||||
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ptr->owner_id);
|
||||
}
|
||||
|
||||
static bool mesh_symmetry_get_common(PointerRNA *ptr, const eMeshSymmetryType sym)
|
||||
{
|
||||
const Object *ob = (Object *)ptr->owner_id;
|
||||
if (ob->type != OB_MESH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const Mesh *mesh = ob->data;
|
||||
return mesh->symmetry & sym;
|
||||
}
|
||||
|
||||
static bool rna_Object_mesh_symmetry_x_get(PointerRNA *ptr)
|
||||
{
|
||||
return mesh_symmetry_get_common(ptr, ME_SYMMETRY_X);
|
||||
}
|
||||
|
||||
static bool rna_Object_mesh_symmetry_y_get(PointerRNA *ptr)
|
||||
{
|
||||
return mesh_symmetry_get_common(ptr, ME_SYMMETRY_Y);
|
||||
}
|
||||
|
||||
static bool rna_Object_mesh_symmetry_z_get(PointerRNA *ptr)
|
||||
{
|
||||
return mesh_symmetry_get_common(ptr, ME_SYMMETRY_Z);
|
||||
}
|
||||
|
||||
static void mesh_symmetry_set_common(PointerRNA *ptr,
|
||||
const bool value,
|
||||
const eMeshSymmetryType sym)
|
||||
{
|
||||
Object *ob = (Object *)ptr->owner_id;
|
||||
if (ob->type != OB_MESH) {
|
||||
return;
|
||||
}
|
||||
|
||||
Mesh *mesh = ob->data;
|
||||
if (value) {
|
||||
mesh->symmetry |= sym;
|
||||
}
|
||||
else {
|
||||
mesh->symmetry &= ~sym;
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_Object_mesh_symmetry_x_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
mesh_symmetry_set_common(ptr, value, ME_SYMMETRY_X);
|
||||
}
|
||||
|
||||
static void rna_Object_mesh_symmetry_y_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
mesh_symmetry_set_common(ptr, value, ME_SYMMETRY_Y);
|
||||
}
|
||||
|
||||
static void rna_Object_mesh_symmetry_z_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
mesh_symmetry_set_common(ptr, value, ME_SYMMETRY_Z);
|
||||
}
|
||||
|
||||
static int rna_Object_mesh_symmetry_yz_editable(PointerRNA *ptr, const char **UNUSED(r_info))
|
||||
{
|
||||
const Object *ob = (Object *)ptr->owner_id;
|
||||
if (ob->type != OB_MESH) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Mesh *mesh = ob->data;
|
||||
if (ob->mode == OB_MODE_WEIGHT_PAINT && mesh->editflag & ME_EDIT_MIRROR_VERTEX_GROUPS) {
|
||||
/* Only X symmetry is available in weightpaint mode. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PROP_EDITABLE;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_vertex_group(BlenderRNA *brna)
|
||||
@@ -3499,6 +3574,28 @@ static void rna_def_object(BlenderRNA *brna)
|
||||
RNA_def_property_struct_type(prop, "ObjectLineArt");
|
||||
RNA_def_property_ui_text(prop, "Line Art", "Line art settings for the object");
|
||||
|
||||
/* Mesh Symmetry Settings */
|
||||
|
||||
prop = RNA_def_property(srna, "use_mesh_mirror_x", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_Object_mesh_symmetry_x_get", "rna_Object_mesh_symmetry_x_set");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "X", "Enable mesh symmetry in the X axis");
|
||||
|
||||
prop = RNA_def_property(srna, "use_mesh_mirror_y", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_Object_mesh_symmetry_y_get", "rna_Object_mesh_symmetry_y_set");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_editable_func(prop, "rna_Object_mesh_symmetry_yz_editable");
|
||||
RNA_def_property_ui_text(prop, "Y", "Enable mesh symmetry in the Y axis");
|
||||
|
||||
prop = RNA_def_property(srna, "use_mesh_mirror_z", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_Object_mesh_symmetry_z_get", "rna_Object_mesh_symmetry_z_set");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_editable_func(prop, "rna_Object_mesh_symmetry_yz_editable");
|
||||
RNA_def_property_ui_text(prop, "Z", "Enable mesh symmetry in the Z axis");
|
||||
|
||||
RNA_define_lib_overridable(false);
|
||||
|
||||
/* anim */
|
||||
|
||||
Reference in New Issue
Block a user