forked from bartvdbraak/blender
Add bone_groups.new() and bone_groups.remove() methods to RNA.
To do so, matching BKE 'API' was also refactored a bit: * Get Pose data instead of Object, as parameter; * Removed some sanity checks not needed at such a low level (callers are supposed to do that); * You can now remove an arbitrary bone group, not only the active one. Based on patch by pkrime (Paolo Acampora), with own edits. Reviewers: #python, pkrime, aligorith Reviewed By: aligorith Differential Revision: https://developer.blender.org/D522
This commit is contained in:
parent
02eb03f868
commit
08eac0c367
@ -180,10 +180,12 @@ void framechange_poses_clear_unkeyed(void);
|
||||
/* Bone Groups API --------------------- */
|
||||
|
||||
/* Adds a new bone-group */
|
||||
void BKE_pose_add_group(struct Object *ob);
|
||||
struct bActionGroup *BKE_pose_add_group(struct bPose *pose, const char *name);
|
||||
|
||||
/* Remove the active bone-group */
|
||||
void BKE_pose_remove_group(struct Object *ob);
|
||||
/* Remove a bone-group */
|
||||
void BKE_pose_remove_group(struct bPose *pose, struct bActionGroup *grp, const int index);
|
||||
/* Remove the matching bone-group from its index */
|
||||
void BKE_pose_remove_group_index(struct bPose *pose, const int index);
|
||||
|
||||
/* Assorted Evaluation ----------------- */
|
||||
|
||||
|
@ -952,52 +952,52 @@ void framechange_poses_clear_unkeyed(void)
|
||||
|
||||
/* ************************** Bone Groups ************************** */
|
||||
|
||||
/* Adds a new bone-group */
|
||||
void BKE_pose_add_group(Object *ob)
|
||||
/* Adds a new bone-group (name may be NULL) */
|
||||
bActionGroup *BKE_pose_add_group(bPose *pose, const char *name)
|
||||
{
|
||||
bPose *pose = (ob) ? ob->pose : NULL;
|
||||
bActionGroup *grp;
|
||||
|
||||
if (ELEM(NULL, ob, ob->pose))
|
||||
return;
|
||||
if (!name) {
|
||||
name = DATA_("Group");
|
||||
}
|
||||
|
||||
grp = MEM_callocN(sizeof(bActionGroup), "PoseGroup");
|
||||
BLI_strncpy(grp->name, DATA_("Group"), sizeof(grp->name));
|
||||
BLI_strncpy(grp->name, name, sizeof(grp->name));
|
||||
BLI_addtail(&pose->agroups, grp);
|
||||
BLI_uniquename(&pose->agroups, grp, DATA_("Group"), '.', offsetof(bActionGroup, name), sizeof(grp->name));
|
||||
BLI_uniquename(&pose->agroups, grp, name, '.', offsetof(bActionGroup, name), sizeof(grp->name));
|
||||
|
||||
pose->active_group = BLI_countlist(&pose->agroups);
|
||||
|
||||
return grp;
|
||||
}
|
||||
|
||||
/* Remove the active bone-group */
|
||||
void BKE_pose_remove_group(Object *ob)
|
||||
/* Remove the given bone-group (expects 'virtual' index (+1 one, used by active_group etc.))
|
||||
* index might be invalid ( < 1), in which case it will be find from grp. */
|
||||
void BKE_pose_remove_group(bPose *pose, bActionGroup *grp, const int index)
|
||||
{
|
||||
bPose *pose = (ob) ? ob->pose : NULL;
|
||||
bActionGroup *grp = NULL;
|
||||
bPoseChannel *pchan;
|
||||
int idx = index;
|
||||
|
||||
/* sanity checks */
|
||||
if (ELEM(NULL, ob, pose))
|
||||
return;
|
||||
if (pose->active_group <= 0)
|
||||
return;
|
||||
if (idx < 1) {
|
||||
idx = BLI_findindex(&pose->agroups, grp) + 1;
|
||||
}
|
||||
|
||||
/* get group to remove */
|
||||
grp = BLI_findlink(&pose->agroups, pose->active_group - 1);
|
||||
if (grp) {
|
||||
/* adjust group references (the trouble of using indices!):
|
||||
* - firstly, make sure nothing references it
|
||||
* - also, make sure that those after this item get corrected
|
||||
*/
|
||||
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (pchan->agrp_index == pose->active_group)
|
||||
pchan->agrp_index = 0;
|
||||
else if (pchan->agrp_index > pose->active_group)
|
||||
pchan->agrp_index--;
|
||||
}
|
||||
BLI_assert(idx > 0);
|
||||
|
||||
/* now, remove it from the pose */
|
||||
BLI_freelinkN(&pose->agroups, grp);
|
||||
/* adjust group references (the trouble of using indices!):
|
||||
* - firstly, make sure nothing references it
|
||||
* - also, make sure that those after this item get corrected
|
||||
*/
|
||||
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (pchan->agrp_index == idx)
|
||||
pchan->agrp_index = 0;
|
||||
else if (pchan->agrp_index > idx)
|
||||
pchan->agrp_index--;
|
||||
}
|
||||
|
||||
/* now, remove it from the pose */
|
||||
BLI_freelinkN(&pose->agroups, grp);
|
||||
if (pose->active_group >= idx) {
|
||||
pose->active_group--;
|
||||
if (pose->active_group < 0 || BLI_listbase_is_empty(&pose->agroups)) {
|
||||
pose->active_group = 0;
|
||||
@ -1005,6 +1005,18 @@ void BKE_pose_remove_group(Object *ob)
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the indexed bone-group (expects 'virtual' index (+1 one, used by active_group etc.)) */
|
||||
void BKE_pose_remove_group_index(bPose *pose, const int index)
|
||||
{
|
||||
bActionGroup *grp = NULL;
|
||||
|
||||
/* get group to remove */
|
||||
grp = BLI_findlink(&pose->agroups, index - 1);
|
||||
if (grp) {
|
||||
BKE_pose_remove_group(pose, grp, index);
|
||||
}
|
||||
}
|
||||
|
||||
/* ************** F-Curve Utilities for Actions ****************** */
|
||||
|
||||
/* Check if the given action has any keyframes */
|
||||
|
@ -62,12 +62,12 @@ static int pose_group_add_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Object *ob = ED_pose_object_from_context(C);
|
||||
|
||||
/* only continue if there's an object */
|
||||
if (ob == NULL)
|
||||
/* only continue if there's an object and pose */
|
||||
if (ELEM(NULL, ob, ob->pose))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* for now, just call the API function for this */
|
||||
BKE_pose_add_group(ob);
|
||||
BKE_pose_add_group(ob->pose, NULL);
|
||||
|
||||
/* notifiers for updates */
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
|
||||
@ -95,12 +95,12 @@ static int pose_group_remove_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Object *ob = ED_pose_object_from_context(C);
|
||||
|
||||
/* only continue if there's an object */
|
||||
if (ob == NULL)
|
||||
/* only continue if there's an object and pose */
|
||||
if (ELEM(NULL, ob, ob->pose))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
/* for now, just call the API function for this */
|
||||
BKE_pose_remove_group(ob);
|
||||
BKE_pose_remove_group_index(ob->pose, ob->pose->active_group);
|
||||
|
||||
/* notifiers for updates */
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
|
||||
@ -189,7 +189,7 @@ static int pose_group_assign_exec(bContext *C, wmOperator *op)
|
||||
*/
|
||||
pose->active_group = RNA_int_get(op->ptr, "type");
|
||||
if (pose->active_group == 0)
|
||||
BKE_pose_add_group(ob);
|
||||
BKE_pose_add_group(ob->pose, NULL);
|
||||
|
||||
/* add selected bones to group then */
|
||||
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
|
||||
|
@ -140,7 +140,32 @@ static char *rna_PoseBone_path(PointerRNA *ptr)
|
||||
return BLI_sprintfN("pose.bones[\"%s\"]", name_esc);
|
||||
}
|
||||
|
||||
/* Bone groups only. */
|
||||
|
||||
static bActionGroup *rna_bone_group_new(ID *id, bPose *pose, const char *name)
|
||||
{
|
||||
bActionGroup *grp = BKE_pose_add_group(pose, name);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_POSE | NA_ADDED, id);
|
||||
return grp;
|
||||
}
|
||||
|
||||
static void rna_bone_group_remove(ID *id, bPose *pose, ReportList *reports, PointerRNA *grp_ptr)
|
||||
{
|
||||
bActionGroup *grp = grp_ptr->data;
|
||||
const int grp_idx = BLI_findindex(&pose->agroups, grp);
|
||||
|
||||
if (grp_idx == -1) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Bone group '%s' not found in this object", grp->name);
|
||||
return;
|
||||
}
|
||||
|
||||
BKE_pose_remove_group(pose, grp, grp_idx + 1);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_POSE | NA_REMOVED, id);
|
||||
}
|
||||
|
||||
|
||||
/* shared for actions groups and bone groups */
|
||||
|
||||
void rna_ActionGroup_colorset_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
bActionGroup *grp = ptr->data;
|
||||
@ -1241,14 +1266,30 @@ static void rna_def_bone_groups(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* FunctionRNA *func; */
|
||||
/* PropertyRNA *parm; */
|
||||
FunctionRNA *func;
|
||||
PropertyRNA *parm;
|
||||
|
||||
RNA_def_property_srna(cprop, "BoneGroups");
|
||||
srna = RNA_def_struct(brna, "BoneGroups", NULL);
|
||||
RNA_def_struct_sdna(srna, "bPose");
|
||||
RNA_def_struct_ui_text(srna, "Bone Groups", "Collection of bone groups");
|
||||
|
||||
func = RNA_def_function(srna, "new", "rna_bone_group_new");
|
||||
RNA_def_function_ui_description(func, "Add a new bone group to the object");
|
||||
RNA_def_function_flag(func, FUNC_USE_SELF_ID); /* ID needed for refresh */
|
||||
RNA_def_string(func, "name", "Group", MAX_NAME, "", "Name of the new group");
|
||||
/* return type */
|
||||
parm = RNA_def_pointer(func, "group", "BoneGroup", "", "New bone group");
|
||||
RNA_def_function_return(func, parm);
|
||||
|
||||
func = RNA_def_function(srna, "remove", "rna_bone_group_remove");
|
||||
RNA_def_function_ui_description(func, "Remove a bone group from this object");
|
||||
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); /* ID needed for refresh */
|
||||
/* bone group to remove */
|
||||
parm = RNA_def_pointer(func, "group", "BoneGroup", "", "Removed bone group");
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR);
|
||||
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
|
||||
|
||||
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "BoneGroup");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
|
Loading…
Reference in New Issue
Block a user