[Bf-blender-cvs] [9d3cea5e542] greasepencil-object: Improvements in automatic weight calculation
Antonioya
noreply at git.blender.org
Thu Aug 23 10:34:08 CEST 2018
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);
}
More information about the Bf-blender-cvs
mailing list