Commit: 9d3cea5e542334fe123de00879837098afff37f0 Author: Antonioya Date: Mon Aug 20 11:22:25 2018 +0200 Branches: greasepencil-object https://developer.blender.org/rB9d3cea5e542334fe123de00879837098afff37f0
Improvements in automatic weight calculation =================================================================== M release/scripts/startup/bl_ui/space_view3d.py M source/blender/editors/gpencil/gpencil_armature.c =================================================================== diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 2edd1815c08..261129ed55c 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3539,6 +3539,15 @@ class VIEW3D_MT_edit_armature_delete(Menu): # ********** Grease Pencil Stroke menus ********** +class VIEW3D_MT_gpencil_autoweights(Menu): + bl_label = "Generate Weights" + + def draw(self, context): + layout = self.layout + layout.operator("gpencil.generate_weights", text="With Empty Groups").mode = 'NAME' + layout.operator("gpencil.generate_weights", text="With Automatic Weights").mode = 'AUTO' + + class VIEW3D_MT_gpencil_simplify(Menu): bl_label = "Simplify" @@ -3686,6 +3695,9 @@ class VIEW3D_MT_weight_gpencil(Menu): layout.operator("gpencil.vertex_group_invert", text="Invert") layout.operator("gpencil.vertex_group_smooth", text="Smooth") + layout.separator() + layout.menu("VIEW3D_MT_gpencil_autoweights") + class VIEW3D_MT_gpencil_animation(Menu): bl_label = "Animation" @@ -4967,7 +4979,6 @@ class VIEW3D_MT_gpencil_sculpt_specials(Menu): def draw(self, context): layout = self.layout - is_3d_view = context.space_data.type == 'VIEW_3D' layout.operator_context = 'INVOKE_REGION_WIN' layout.menu("VIEW3D_MT_assign_material") @@ -4982,6 +4993,9 @@ class VIEW3D_MT_gpencil_sculpt_specials(Menu): layout.operator("gpencil.stroke_simplify_fixed", text="Simplify") layout.operator("gpencil.stroke_simplify", text="Simplify Adaptative") + if context.mode == 'GPENCIL_WEIGHT': + layout.separator() + layout.menu("VIEW3D_MT_gpencil_autoweights") classes = ( VIEW3D_HT_header, @@ -5126,6 +5140,7 @@ classes = ( VIEW3D_PT_object_type_visibility, VIEW3D_PT_grease_pencil, VIEW3D_PT_gpencil_multi_frame, + VIEW3D_MT_gpencil_autoweights, VIEW3D_MT_gpencil_edit_specials, VIEW3D_MT_gpencil_sculpt_specials, VIEW3D_PT_quad_view, diff --git a/source/blender/editors/gpencil/gpencil_armature.c b/source/blender/editors/gpencil/gpencil_armature.c index 0f0b176dbb3..d7b00d86812 100644 --- a/source/blender/editors/gpencil/gpencil_armature.c +++ b/source/blender/editors/gpencil/gpencil_armature.c @@ -71,6 +71,7 @@ #include "ED_mesh.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" #include "gpencil_intern.h" @@ -276,9 +277,24 @@ static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap) return 0; } +/* get weight value depending of distance and decay value */ +static float get_weight(float dist, float decay_rad, float dif_rad) +{ + float weight = 1.0f; + if (dist < decay_rad) { + weight = 1.0f; + } + else { + weight = interpf(0.0f, 0.9f, (dist - decay_rad) / dif_rad); + } + + return weight; +} + /* This functions implements the automatic computation of vertex group weights */ static void gpencil_add_verts_to_dgroups(bContext *C, - ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, Object *ob_arm) + ReportList *reports, Depsgraph *depsgraph, Scene *scene, + Object *ob, Object *ob_arm, const float ratio, const float decay) { bArmature *arm = ob_arm->data; Bone **bonelist, *bone; @@ -372,7 +388,7 @@ static void gpencil_add_verts_to_dgroups(bContext *C, lensqr[j] = len_squared_v3v3(root[j], tip[j]); /* calculate radius squared */ - radsqr[j] = lensqr[j] / 6.0f; + radsqr[j] = lensqr[j] * ratio; } /* loop all strokes */ @@ -412,6 +428,9 @@ static void gpencil_add_verts_to_dgroups(bContext *C, continue; } + float decay_rad = radsqr[j] - (radsqr[j] * decay); + float dif_rad = radsqr[j] - decay_rad; + for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { MDeformVert *dvert = &gps->dvert[i]; float dist = test_point_in_cylynder(root[j], tip[j], @@ -420,21 +439,20 @@ static void gpencil_add_verts_to_dgroups(bContext *C, if (dist < 0) { /* if not in cylinder, check if inside sphere of extremes */ weight = 0.0f; - float rad = radsqr[j] * 0.75f; dist = len_squared_v3v3(root[j], &pt->x); - if (dist < rad) { - weight = interpf(0.0f, 0.9f, dist / rad); + if (dist < radsqr[j]) { + weight = get_weight(dist, decay_rad, dif_rad); } else { dist = len_squared_v3v3(tip[j], &pt->x); - if (dist < rad) { - weight = interpf(0.0f, 0.9f, dist / rad); + if (dist < radsqr[j]) { + weight = get_weight(dist, decay_rad, dif_rad); } } } else { /* inside bone cylinder */ - weight = 1.0f; + weight = get_weight(dist, decay_rad, dif_rad); } /* assign weight */ @@ -466,7 +484,7 @@ static void gpencil_add_verts_to_dgroups(bContext *C, static void gpencil_object_vgroup_calc_from_armature(bContext *C, ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, Object *ob_arm, - const int mode, const bool mirror) + const int mode, const float ratio, const float decay) { /* Lets try to create some vertex groups * based on the bones of the parent armature. @@ -492,17 +510,34 @@ static void gpencil_object_vgroup_calc_from_armature(bContext *C, * with the corresponding vertice weights for which the * bone is closest. */ - gpencil_add_verts_to_dgroups(C, reports, depsgraph, scene, ob, ob_arm); + gpencil_add_verts_to_dgroups(C, reports, depsgraph, scene, ob, ob_arm, + ratio, decay); } } /* ***************** Generate armature weights ************************** */ bool gpencil_generate_weights_poll(bContext *C) { - bGPdata *gpd = ED_gpencil_data_get_active(C); - bGPDlayer *gpl = BKE_gpencil_layer_getactive(gpd); + Depsgraph *depsgraph = CTX_data_depsgraph(C); + Object *ob = CTX_data_active_object(C); + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); + bGPdata *gpd = (bGPdata *)ob->data; + int t = BLI_listbase_count(&gpd->layers); - return (gpl != NULL); + if (t == 0) { + return false; + } + + GpencilModifierData *md = BKE_gpencil_modifiers_findByType(ob_eval, eGpencilModifierType_Armature); + if (md == NULL) { + return false; + } + ArmatureGpencilModifierData *mmd = (ArmatureGpencilModifierData *)md; + if (mmd->object == NULL) { + return false; + } + + return true; } static int gpencil_generate_weights_exec(bContext *C, wmOperator *op) @@ -510,16 +545,19 @@ static int gpencil_generate_weights_exec(bContext *C, wmOperator *op) Depsgraph *depsgraph = CTX_data_depsgraph(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); bGPdata *gpd = (bGPdata *)ob->data; - int mode = RNA_enum_get(op->ptr, "mode"); + const int mode = RNA_enum_get(op->ptr, "mode"); + const float ratio = RNA_float_get(op->ptr, "ratio"); + const float decay = RNA_float_get(op->ptr, "decay"); /* sanity checks */ if (ELEM(NULL, ob, gpd)) return OPERATOR_CANCELLED; /* get armature from modifier */ - GpencilModifierData *md = BKE_gpencil_modifiers_findByType(ob, eGpencilModifierType_Armature); + GpencilModifierData *md = BKE_gpencil_modifiers_findByType(ob_eval, eGpencilModifierType_Armature); if (md == NULL) { BKE_report(op->reports, RPT_ERROR, "The grease pencil object need an Armature modifier"); @@ -534,7 +572,7 @@ static int gpencil_generate_weights_exec(bContext *C, wmOperator *op) } gpencil_object_vgroup_calc_from_armature(C, op->reports,depsgraph, scene, - ob, mmd->object, mode, false); + ob, mmd->object, mode, ratio, decay); /* notifiers */ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA); @@ -546,15 +584,15 @@ static int gpencil_generate_weights_exec(bContext *C, wmOperator *op) void GPENCIL_OT_generate_weights(wmOperatorType *ot) { static const EnumPropertyItem mode_type[] = { - {GP_ARMATURE_NAME, "NAME", 0, "With Empty Groups", ""}, - {GP_ARMATURE_AUTO, "AUTO", 0, "With Automatic Weights", ""}, + {GP_ARMATURE_NAME, "NAME", 0, "Empty Groups", ""}, + {GP_ARMATURE_AUTO, "AUTO", 0, "Automatic Weights", ""}, {0, NULL, 0, NULL, NULL} }; /* identifiers */ ot->name = "Generate Automatic Weights"; ot->idname = "GPENCIL_OT_generate_weights"; - ot->description = "Generate automatic weights for armatures"; + ot->description = "Generate automatic weights for armatures (requires armature modifier)"; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -563,4 +601,10 @@ void GPENCIL_OT_generate_weights(wmOperatorType *ot) ot->poll = gpencil_generate_weights_poll; ot->prop = RNA_def_enum(ot->srna, "mode", mode_type, 0, "Mode", ""); + + RNA_def_float(ot->srna, "ratio", 0.15f, 0.0f, 2.0f, "Ratio", + "Ratio between bone length and influence radius", 0.001f, 1.0f); + + RNA_def_float(ot->srna, "decay", 0.1f, 0.0f, 1.0f, "Decay", + "Factor to reduce influence depending of distance to bone axis", 0.0f, 1.0f); } _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs