2.5 - More work on Bone Groups
* Added a new UI Template for the 3-colour picker used to visualise + select the custom colours for a bone group. * Finished wrapping the colour properties for Bone Groups in RNA. Although changing the colour-set used will change the displayed/cached colours, changing the colours via the colour wells will not change the colour set to 'custom' (as per 2.4x) yet. This needs a nice solution... * Fixed context-related bugs with the Assign/Remove operators for bone groups. These were using context-iterators for selected posechannels, but that was only defined/valid for the 3d view (but not for the buttons window), hence a failure in that case.
This commit is contained in:
@@ -101,8 +101,13 @@ class DATA_PT_bone_groups(DataButtonsPanel):
|
||||
|
||||
group = pose.active_bone_group
|
||||
if group:
|
||||
row = layout.row()
|
||||
row.itemR(group, "name")
|
||||
col = layout.column()
|
||||
col.itemR(group, "name")
|
||||
|
||||
split = layout.split(0.5)
|
||||
split.itemR(group, "color_set")
|
||||
if group.color_set:
|
||||
split.template_triColorSet(group, "colors")
|
||||
|
||||
row = layout.row(align=True)
|
||||
|
||||
|
||||
@@ -1035,7 +1035,7 @@ static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt)
|
||||
ob= CTX_data_active_object(C);
|
||||
|
||||
/* only continue if there's an object, and a pose there too */
|
||||
if (ELEM(NULL, ob, ob->pose))
|
||||
if (ELEM(NULL, ob, ob->pose))
|
||||
return OPERATOR_CANCELLED;
|
||||
pose= ob->pose;
|
||||
|
||||
@@ -1065,7 +1065,7 @@ static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt)
|
||||
else {
|
||||
/* just use the active group index, and call the exec callback for the calling operator */
|
||||
RNA_int_set(op->ptr, "type", pose->active_group);
|
||||
return op->type->exec;
|
||||
return op->type->exec(C, op);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1074,7 +1074,9 @@ static int pose_group_assign_exec (bContext *C, wmOperator *op)
|
||||
{
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
Object *ob;
|
||||
bArmature *arm;
|
||||
bPose *pose;
|
||||
bPoseChannel *pchan;
|
||||
short done= 0;
|
||||
|
||||
/* since this call may also be used from the buttons window, we need to check for where to get the object */
|
||||
@@ -1086,18 +1088,29 @@ static int pose_group_assign_exec (bContext *C, wmOperator *op)
|
||||
/* only continue if there's an object, and a pose there too */
|
||||
if (ELEM(NULL, ob, ob->pose))
|
||||
return OPERATOR_CANCELLED;
|
||||
arm= ob->data;
|
||||
pose= ob->pose;
|
||||
|
||||
/* set the active group number to the one from operator props */
|
||||
/* set the active group number to the one from operator props
|
||||
* - if 0 after this, make a new group...
|
||||
*/
|
||||
pose->active_group= RNA_int_get(op->ptr, "type");
|
||||
if (pose->active_group == 0)
|
||||
pose_add_group(ob);
|
||||
|
||||
/* add selected bones to group then */
|
||||
CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
|
||||
{
|
||||
pchan->agrp_index= pose->active_group;
|
||||
done= 1;
|
||||
// NOTE: unfortunately, we cannot use the context-iterators here, since they might not be defined...
|
||||
// CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
|
||||
for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
/* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
|
||||
// NOTE: sync this view3d_context() in space_view3d.c
|
||||
if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
|
||||
if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) {
|
||||
pchan->agrp_index= pose->active_group;
|
||||
done= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
/* notifiers for updates */
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
|
||||
@@ -1133,7 +1146,9 @@ static int pose_group_unassign_exec (bContext *C, wmOperator *op)
|
||||
{
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
Object *ob;
|
||||
bArmature *arm;
|
||||
bPose *pose;
|
||||
bPoseChannel *pchan;
|
||||
short done= 0;
|
||||
|
||||
/* since this call may also be used from the buttons window, we need to check for where to get the object */
|
||||
@@ -1146,16 +1161,23 @@ static int pose_group_unassign_exec (bContext *C, wmOperator *op)
|
||||
if (ELEM(NULL, ob, ob->pose))
|
||||
return OPERATOR_CANCELLED;
|
||||
pose= ob->pose;
|
||||
arm= ob->data;
|
||||
|
||||
/* add selected bones to ungroup then */
|
||||
CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
|
||||
{
|
||||
if (pchan->agrp_index) {
|
||||
pchan->agrp_index= 0;
|
||||
done= 1;
|
||||
// NOTE: unfortunately, we cannot use the context-iterators here, since they might not be defined...
|
||||
// CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
|
||||
for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
/* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
|
||||
// NOTE: sync this view3d_context() in space_view3d.c
|
||||
if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
|
||||
if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) {
|
||||
if (pchan->agrp_index) {
|
||||
pchan->agrp_index= 0;
|
||||
done= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
/* notifiers for updates */
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
|
||||
@@ -1228,55 +1250,6 @@ void POSE_OT_groups_menu (wmOperatorType *ot)
|
||||
ot->flag= OPTYPE_REGISTER;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Ctrl-G in 3D-View while in PoseMode */
|
||||
void pgroup_operation_with_menu (Scene *scene)
|
||||
{
|
||||
Object *ob= OBACT;
|
||||
bArmature *arm= (ob) ? ob->data : NULL;
|
||||
bPose *pose= (ob) ? ob->pose : NULL;
|
||||
bPoseChannel *pchan= NULL;
|
||||
int mode;
|
||||
|
||||
/* sanity checks */
|
||||
if (ELEM3(NULL, ob, pose, arm))
|
||||
return;
|
||||
|
||||
/* check that something is selected */
|
||||
for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer))
|
||||
break;
|
||||
}
|
||||
if (pchan == NULL)
|
||||
return;
|
||||
|
||||
/* get mode of action */
|
||||
if (pchan)
|
||||
mode= pupmenu("Bone Groups%t|Add Selected to Active Group%x1|Add Selected to Group%x2|%|Remove Selected From Groups%x3|Remove Active Group%x4");
|
||||
else
|
||||
mode= pupmenu("Bone Groups%t|Add New Group%x5|Remove Active Group%x4");
|
||||
|
||||
/* handle mode */
|
||||
switch (mode) {
|
||||
case 1:
|
||||
pose_assign_to_posegroup(scene, 1);
|
||||
break;
|
||||
case 2:
|
||||
pose_assign_to_posegroup(scene, 0);
|
||||
break;
|
||||
case 5:
|
||||
pose_add_posegroup(scene);
|
||||
break;
|
||||
case 3:
|
||||
pose_remove_from_posegroups(scene);
|
||||
break;
|
||||
case 4:
|
||||
pose_remove_posegroup(scene);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ********************************************** */
|
||||
|
||||
static short pose_select_same_group (Object *ob)
|
||||
|
||||
@@ -622,6 +622,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
|
||||
void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent);
|
||||
void uiTemplateColorRamp(uiLayout *layout, struct ColorBand *coba, int expand);
|
||||
void uiTemplateCurveMapping(uiLayout *layout, struct CurveMapping *cumap, int type);
|
||||
void uiTemplateTriColorSet(uiLayout *layout, struct PointerRNA *ptr, char *propname);
|
||||
void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname);
|
||||
void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser);
|
||||
void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C);
|
||||
|
||||
@@ -1173,7 +1173,7 @@ void uiTemplatePreview(uiLayout *layout, ID *id, ID *parent)
|
||||
{
|
||||
uiLayout *row, *col;
|
||||
uiBlock *block;
|
||||
Material *ma;
|
||||
Material *ma= NULL;
|
||||
ID *pid, *pparent;
|
||||
|
||||
if(id && !ELEM4(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA)) {
|
||||
@@ -1265,6 +1265,34 @@ void uiTemplateCurveMapping(uiLayout *layout, CurveMapping *cumap, int type)
|
||||
}
|
||||
}
|
||||
|
||||
/********************* TriColor (ThemeWireColorSet) Template ************************/
|
||||
|
||||
void uiTemplateTriColorSet(uiLayout *layout, PointerRNA *ptr, char *propname)
|
||||
{
|
||||
uiLayout *row;
|
||||
PropertyRNA *prop;
|
||||
PointerRNA csPtr;
|
||||
|
||||
if (!ptr->data)
|
||||
return;
|
||||
|
||||
prop= RNA_struct_find_property(ptr, propname);
|
||||
if (!prop) {
|
||||
printf("uiTemplateTriColorSet: property not found: %s\n", propname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* we lay out the data in a row as 3 color swatches */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
|
||||
/* nselected, selected, active color swatches */
|
||||
csPtr= RNA_property_pointer_get(ptr, prop);
|
||||
|
||||
uiItemR(row, "", 0, &csPtr, "normal", 0, 0, 0);
|
||||
uiItemR(row, "", 0, &csPtr, "selected", 0, 0, 0);
|
||||
uiItemR(row, "", 0, &csPtr, "active", 0, 0, 0);
|
||||
}
|
||||
|
||||
/********************* Layer Buttons Template ************************/
|
||||
|
||||
// TODO:
|
||||
@@ -1299,7 +1327,10 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname)
|
||||
groups= ((cols / 2) < 5) ? (1) : (cols / 2);
|
||||
|
||||
/* layers are laid out going across rows, with the columns being divided into groups */
|
||||
uSplit= uiLayoutSplit(layout, (1.0f/(float)groups));
|
||||
if (groups > 1)
|
||||
uSplit= uiLayoutSplit(layout, (1.0f/(float)groups));
|
||||
else
|
||||
uSplit= layout;
|
||||
|
||||
for (group= 0; group < groups; group++) {
|
||||
uCol= uiLayoutColumn(uSplit, 1);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Contributor(s): Blender Foundation (2008), Roland Hess
|
||||
* Contributor(s): Blender Foundation (2008), Roland Hess, Joshua Leung
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
@@ -39,8 +39,12 @@
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_idprop.h"
|
||||
@@ -54,6 +58,41 @@ static void rna_Pose_update(bContext *C, PointerRNA *ptr)
|
||||
DAG_object_flush_update(CTX_data_scene(C), ptr->id.data, OB_RECALC_DATA);
|
||||
}
|
||||
|
||||
static void rna_BoneGroup_color_set_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
bActionGroup *grp= ptr->data;
|
||||
|
||||
/* if valid value, set the new enum value, then copy the relevant colours? */
|
||||
if ((value >= -1) && (value < 21))
|
||||
grp->customCol= value;
|
||||
else
|
||||
return;
|
||||
|
||||
/* only do color copying if using a custom color (i.e. not default colour) */
|
||||
if (grp->customCol) {
|
||||
if (grp->customCol > 0) {
|
||||
/* copy theme colors on-to group's custom color in case user tries to edit color */
|
||||
bTheme *btheme= U.themes.first;
|
||||
ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
|
||||
|
||||
memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
|
||||
}
|
||||
else {
|
||||
/* init custom colors with a generic multi-color rgb set, if not initialised already (for custom color set) */
|
||||
if (grp->cs.solid[0] == 0) {
|
||||
/* define for setting colors in theme below */
|
||||
#define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
|
||||
|
||||
SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
|
||||
SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
|
||||
SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
|
||||
|
||||
#undef SETCOL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IDProperty *rna_PoseChannel_idproperties(PointerRNA *ptr, int create)
|
||||
{
|
||||
bPoseChannel *pchan= ptr->data;
|
||||
@@ -189,23 +228,60 @@ void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *result,
|
||||
|
||||
static void rna_def_bone_group(BlenderRNA *brna)
|
||||
{
|
||||
static EnumPropertyItem prop_colorSets_items[] = {
|
||||
{0, "DEFAULT", 0, "Default Colors", ""},
|
||||
{1, "THEME01", 0, "01 - Theme Color Set", ""},
|
||||
{2, "THEME02", 0, "02 - Theme Color Set", ""},
|
||||
{3, "THEME03", 0, "03 - Theme Color Set", ""},
|
||||
{4, "THEME04", 0, "04 - Theme Color Set", ""},
|
||||
{5, "THEME05", 0, "05 - Theme Color Set", ""},
|
||||
{6, "THEME06", 0, "06 - Theme Color Set", ""},
|
||||
{7, "THEME07", 0, "07 - Theme Color Set", ""},
|
||||
{8, "THEME08", 0, "08 - Theme Color Set", ""},
|
||||
{9, "THEME09", 0, "09 - Theme Color Set", ""},
|
||||
{10, "THEME10", 0, "10 - Theme Color Set", ""},
|
||||
{11, "THEME11", 0, "11 - Theme Color Set", ""},
|
||||
{12, "THEME12", 0, "12 - Theme Color Set", ""},
|
||||
{13, "THEME13", 0, "13 - Theme Color Set", ""},
|
||||
{14, "THEME14", 0, "14 - Theme Color Set", ""},
|
||||
{15, "THEME15", 0, "15 - Theme Color Set", ""},
|
||||
{16, "THEME16", 0, "16 - Theme Color Set", ""},
|
||||
{17, "THEME17", 0, "17 - Theme Color Set", ""},
|
||||
{18, "THEME18", 0, "18 - Theme Color Set", ""},
|
||||
{19, "THEME19", 0, "19 - Theme Color Set", ""},
|
||||
{20, "THEME20", 0, "20 - Theme Color Set", ""},
|
||||
{-1, "CUSTOM", 0, "Custom Color Set", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
|
||||
/* struct */
|
||||
srna= RNA_def_struct(brna, "BoneGroup", NULL);
|
||||
RNA_def_struct_sdna(srna, "bActionGroup");
|
||||
RNA_def_struct_ui_text(srna, "Bone Group", "Groups of Pose Channels (Bones).");
|
||||
|
||||
|
||||
/* name */
|
||||
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Name", "");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
|
||||
// TODO: add some runtime-collections stuff to access grouped bones
|
||||
|
||||
// FIXME: this needs more work - probably a custom template?
|
||||
prop= RNA_def_property(srna, "custom_color", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "customCol");
|
||||
RNA_def_property_ui_text(prop, "Custom Color", "Index of custom color set.");
|
||||
/* color set + colors */
|
||||
prop= RNA_def_property(srna, "color_set", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "customCol");
|
||||
RNA_def_property_enum_items(prop, prop_colorSets_items);
|
||||
RNA_def_property_enum_funcs(prop, NULL, "rna_BoneGroup_color_set_set", NULL);
|
||||
RNA_def_property_ui_text(prop, "Color Set", "Custom color set to use.");
|
||||
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
|
||||
|
||||
// TODO: editing the colors for this should result in changes to the color type...
|
||||
prop= RNA_def_property(srna, "colors", PROP_POINTER, PROP_NEVER_NULL);
|
||||
RNA_def_property_struct_type(prop, "ThemeBoneColorSet");
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "cs"); /* NOTE: the DNA data is not really a pointer, but this code works :) */
|
||||
RNA_def_property_ui_text(prop, "Colors", "Copy of the colors associated with the group's color set.");
|
||||
RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_update");
|
||||
}
|
||||
|
||||
static void rna_def_pose_channel(BlenderRNA *brna)
|
||||
@@ -272,7 +348,6 @@ static void rna_def_pose_channel(BlenderRNA *brna)
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "selectflag", BONE_SELECTED);
|
||||
RNA_def_property_ui_text(prop, "Selected", "");
|
||||
|
||||
/* XXX note: bone groups are stored internally as bActionGroups :) - Aligorith */
|
||||
prop= RNA_def_property(srna, "bone_group_index", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "agrp_index");
|
||||
RNA_def_property_ui_text(prop, "Bone Group Index", "Bone Group this pose channel belongs to (0=no group).");
|
||||
|
||||
@@ -256,6 +256,9 @@ void RNA_api_ui_layout(StructRNA *srna)
|
||||
|
||||
func= RNA_def_function(srna, "template_layers", "uiTemplateLayers");
|
||||
api_ui_item_rna_common(func);
|
||||
|
||||
func= RNA_def_function(srna, "template_triColorSet", "uiTemplateTriColorSet");
|
||||
api_ui_item_rna_common(func);
|
||||
|
||||
func= RNA_def_function(srna, "template_image_layers", "uiTemplateImageLayers");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
|
||||
Reference in New Issue
Block a user