Fix T59848: precisely represent the dependencies of Armature modifier.

When the modifier uses vertex groups, the set of the bones it actually
needs is precisely defined by the set of the group names. If envelopes
are enabled, this refinement is not available, because any bone can
potentially be used.

This can be used in the dependency graph construction to allow objects
deformed by a part of the armature to be used in constraints on other
bones, e.g. for placing cartoon-style face elements on top of the body
mesh via Shrinkwrap constraints.

Since the list of vertex group names is now used as an input by
the dependency graph, adding/removing/renaming groups should now
be triggering a graph rebuild.

Differential Revision: https://developer.blender.org/D4715
This commit is contained in:
Alexander Gavrilov 2019-04-24 16:24:53 +03:00
parent 413ffd4606
commit 0470818411
Notes: blender-bot 2023-02-14 11:21:43 +01:00
Referenced by issue #64153, RenderEngine update_result() not showing intermediate result anymore
Referenced by issue #59848, Bone won't deform mesh
10 changed files with 65 additions and 8 deletions

View File

@ -480,6 +480,8 @@ static void gpencil_object_vgroup_calc_from_armature(const bContext *C,
*/
gpencil_add_verts_to_dgroups(C, ob, ob_arm, ratio, decay);
}
DEG_relations_tag_update(CTX_data_main(C));
}
bool ED_gpencil_add_armature_weights(

View File

@ -88,6 +88,7 @@ typedef struct tGP_BrushEditData {
/* Current editor/region/etc. */
/* NOTE: This stuff is mainly needed to handle 3D view projection stuff... */
Depsgraph *depsgraph;
struct Main *bmain;
Scene *scene;
Object *object;
@ -907,6 +908,7 @@ static bool gp_brush_weight_apply(
if (gso->vrgroup == -1) {
if (gso->object) {
BKE_object_defgroup_add(gso->object);
DEG_relations_tag_update(gso->bmain);
gso->vrgroup = 0;
}
}
@ -1220,6 +1222,7 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
op->customdata = gso;
gso->depsgraph = CTX_data_depsgraph(C);
gso->bmain = CTX_data_main(C);
/* store state */
gso->settings = gpsculpt_get_settings(scene);
gso->gp_brush = gpsculpt_get_brush(scene, is_weight_mode);

View File

@ -842,6 +842,7 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op)
BLI_freelistN(&ctx_objects);
}
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
return OPERATOR_FINISHED;

View File

@ -58,6 +58,7 @@
#include "BKE_lattice.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "DNA_armature_types.h"
#include "RNA_access.h"
@ -2702,6 +2703,7 @@ static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op))
Object *ob = ED_object_context(C);
BKE_object_defgroup_add(ob);
DEG_relations_tag_update(CTX_data_main(C));
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@ -2739,6 +2741,7 @@ static int vertex_group_remove_exec(bContext *C, wmOperator *op)
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
@ -2942,6 +2945,7 @@ static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op))
vgroup_duplicate(ob);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob->data);
@ -3472,6 +3476,7 @@ static int vertex_group_mirror_exec(bContext *C, wmOperator *op)
ED_mesh_report_mirror(op, totmirr, totfail);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
@ -3560,6 +3565,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
if (obact != ob) {
if (ED_vgroup_array_copy(ob, obact)) {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob);
changed_tot++;
}

View File

@ -255,11 +255,13 @@ static int output_toggle_exec(bContext *C, wmOperator *op)
else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
if (!exists) {
BKE_object_defgroup_add_name(ob, name);
DEG_relations_tag_update(CTX_data_main(C));
}
else {
bDeformGroup *defgroup = defgroup_find_name(ob, name);
if (defgroup) {
BKE_object_defgroup_remove(ob, defgroup);
DEG_relations_tag_update(CTX_data_main(C));
}
}
}

View File

@ -130,6 +130,7 @@ static int weight_from_bones_exec(bContext *C, wmOperator *op)
op->reports, depsgraph, scene, ob, armob, type, (me->editflag & ME_EDIT_MIRROR_X));
DEG_id_tag_update(&me->id, 0);
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
return OPERATOR_FINISHED;

View File

@ -41,6 +41,8 @@
#include "BKE_report.h"
#include "BKE_object.h"
#include "DEG_depsgraph_build.h"
/* Only for blend modes. */
#include "IMB_imbuf.h"
@ -93,6 +95,7 @@ bool ED_wpaint_ensure_data(bContext *C,
bDeformGroup *dg = defgroup_find_name(ob, pchan->name);
if (dg == NULL) {
dg = BKE_object_defgroup_add_name(ob, pchan->name); /* sets actdef */
DEG_relations_tag_update(CTX_data_main(C));
}
else {
int actdef = 1 + BLI_findindex(&ob->defbase, dg);
@ -105,6 +108,7 @@ bool ED_wpaint_ensure_data(bContext *C,
}
if (BLI_listbase_is_empty(&ob->defbase)) {
BKE_object_defgroup_add(ob);
DEG_relations_tag_update(CTX_data_main(C));
}
/* ensure we don't try paint onto an invalid group */

View File

@ -2119,13 +2119,15 @@ static void rna_def_modifier_armature(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_bone_envelopes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "deformflag", ARM_DEF_ENVELOPE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Use Bone Envelopes", "Bind Bone envelopes to armature modifier");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "use_vertex_groups", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "deformflag", ARM_DEF_VGROUP);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Use Vertex Groups", "Bind vertex groups to armature modifier");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "use_deform_preserve_volume", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "deformflag", ARM_DEF_QUATERNION);

View File

@ -381,6 +381,12 @@ void rna_Object_internal_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene),
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ptr->id.data);
}
void rna_Object_internal_update_data_dependency(Main *bmain, Scene *scene, PointerRNA *ptr)
{
DEG_relations_tag_update(bmain);
rna_Object_internal_update_data(bmain, scene, ptr);
}
static void rna_Object_active_shape_update(bContext *C, PointerRNA *ptr)
{
Object *ob = ptr->id.data;
@ -1539,16 +1545,20 @@ static void rna_Object_boundbox_get(PointerRNA *ptr, float *values)
}
}
static bDeformGroup *rna_Object_vgroup_new(Object *ob, const char *name)
static bDeformGroup *rna_Object_vgroup_new(Object *ob, Main *bmain, const char *name)
{
bDeformGroup *defgroup = BKE_object_defgroup_add_name(ob, name);
DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
return defgroup;
}
static void rna_Object_vgroup_remove(Object *ob, ReportList *reports, PointerRNA *defgroup_ptr)
static void rna_Object_vgroup_remove(Object *ob,
Main *bmain,
ReportList *reports,
PointerRNA *defgroup_ptr)
{
bDeformGroup *defgroup = defgroup_ptr->data;
if (BLI_findindex(&ob->defbase, defgroup) == -1) {
@ -1563,13 +1573,15 @@ static void rna_Object_vgroup_remove(Object *ob, ReportList *reports, PointerRNA
BKE_object_defgroup_remove(ob, defgroup);
RNA_POINTER_INVALIDATE(defgroup_ptr);
DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}
static void rna_Object_vgroup_clear(Object *ob)
static void rna_Object_vgroup_clear(Object *ob, Main *bmain)
{
BKE_object_defgroup_remove_all(ob);
DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}
@ -1757,7 +1769,8 @@ static void rna_def_vertex_group(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_VertexGroup_name_set");
/* update data because modifiers may use [#24761] */
RNA_def_property_update(prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data");
RNA_def_property_update(
prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data_dependency");
prop = RNA_def_property(srna, "lock_weight", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "", "Maintain the relative weights for the group");
@ -2160,19 +2173,21 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
/* vertex groups */ /* add_vertex_group */
func = RNA_def_function(srna, "new", "rna_Object_vgroup_new");
RNA_def_function_flag(func, FUNC_USE_MAIN);
RNA_def_function_ui_description(func, "Add vertex group to object");
RNA_def_string(func, "name", "Group", 0, "", "Vertex group name"); /* optional */
parm = RNA_def_pointer(func, "group", "VertexGroup", "", "New vertex group");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "remove", "rna_Object_vgroup_remove");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Delete vertex group from object");
parm = RNA_def_pointer(func, "group", "VertexGroup", "", "Vertex group to remove");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
func = RNA_def_function(srna, "clear", "rna_Object_vgroup_clear");
RNA_def_function_flag(func, FUNC_USE_MAIN);
RNA_def_function_ui_description(func, "Delete all vertex groups from object");
}

View File

@ -24,11 +24,13 @@
#include <string.h>
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
#include "BKE_action.h"
#include "BKE_editmesh.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
@ -91,7 +93,26 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
{
ArmatureModifierData *amd = (ArmatureModifierData *)md;
if (amd->object != NULL) {
DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_EVAL_POSE, "Armature Modifier");
/* If not using envelopes, create relations to individual bones for more rigging flexibility. */
if ((amd->deformflag & ARM_DEF_ENVELOPE) == 0 && (amd->object->pose != NULL) &&
ELEM(ctx->object->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
/* If neither vertex groups nor envelopes are used, the modifier has no bone dependencies. */
if ((amd->deformflag & ARM_DEF_VGROUP) != 0) {
/* Enumerate groups that match existing bones. */
LISTBASE_FOREACH (bDeformGroup *, dg, &ctx->object->defbase) {
if (BKE_pose_channel_find_name(amd->object->pose, dg->name) != NULL) {
/* Can't check BONE_NO_DEFORM because it can be animated. */
DEG_add_bone_relation(
ctx->node, amd->object, dg->name, DEG_OB_COMP_BONE, "Armature Modifier");
}
}
}
}
/* Otherwise require the whole pose to be complete. */
else {
DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_EVAL_POSE, "Armature Modifier");
}
DEG_add_object_relation(ctx->node, amd->object, DEG_OB_COMP_TRANSFORM, "Armature Modifier");
}
DEG_add_modifier_to_transform_relation(ctx->node, "Armature Modifier");