add access to bone add/remove from rna. eg.

bone = arm.edit_bones.new("SomeBone")
 arm.edit_bones.remove(bone)

regify (WIP)
This commit is contained in:
2009-11-25 11:05:11 +00:00
parent 50e3bb7f5f
commit b40307df16
12 changed files with 213 additions and 53 deletions

View File

@@ -22,7 +22,6 @@ from functools import reduce
# TODO, have these in a more general module
from rna_prop_ui import rna_idprop_ui_get, rna_idprop_ui_prop_get
empty_layer = [False] * 16
@@ -42,10 +41,44 @@ def get_bone_data(obj, bone_name):
def bone_basename(name):
return name.split(".")[0]
def add_bone(arm, name):
'''Must be in editmode'''
bpy.ops.armature.bone_primitive_add(name=name)
return arm.edit_bones[-1]
def add_stretch_to(obj, from_name, to_name, name):
'''
Adds a bone that stretches from one to another
'''
is_editmode = (obj.mode == 'EDIT')
if not is_editmode:
bpy.ops.object.mode_set(mode='EDIT')
arm = obj.data
stretch_ebone = arm.edit_bones.new(name)
stretch_name = stretch_ebone.name
head = stretch_ebone.head = arm.edit_bones[from_name].head.copy()
tail = stretch_ebone.tail = arm.edit_bones[to_name].head.copy()
# Now for the constraint
bpy.ops.object.mode_set(mode='OBJECT')
from_pbone = obj.pose.bones[from_name]
to_pbone = obj.pose.bones[to_name]
stretch_pbone = obj.pose.bones[stretch_name]
con = stretch_pbone.constraints.new('COPY_LOCATION')
con.target = obj
con.subtarget = from_name
con = stretch_pbone.constraints.new('STRETCH_TO')
con.target = obj
con.subtarget = to_name
con.original_length = (head-tail).length
con.keep_axis = 'PLANE_X'
con.volume = 'NO_VOLUME'
if is_editmode:
bpy.ops.object.mode_set(mode='EDIT')
#else:
# bpy.ops.object.mode_set(mode='OBJECT')
def gen_finger(obj, orig_bone_name):
@@ -64,7 +97,7 @@ def gen_finger(obj, orig_bone_name):
base_name = bone_basename(orig_pbone.name)
# first make a new bone at the location of the finger
control_ebone = add_bone(arm, base_name)
control_ebone = arm.edit_bones.new(base_name)
control_bone_name = control_ebone.name # we dont know if we get the name requested
# Place the finger bone
@@ -94,7 +127,7 @@ def gen_finger(obj, orig_bone_name):
driver_bone_name = child_bone_name.split('.')
driver_bone_name = driver_bone_name[0] + "_driver." + ".".join(driver_bone_name[1:])
driver_ebone = add_bone(arm, driver_bone_name)
driver_ebone = arm.edit_bones.new(driver_bone_name)
driver_bone_name = driver_ebone.name # cant be too sure!
driver_ebone.layer = other_layer
@@ -119,7 +152,7 @@ def gen_finger(obj, orig_bone_name):
del control_ebone
# *** POSEMODE
bpy.ops.object.mode_set(mode='OBJECT')
@@ -161,10 +194,10 @@ def gen_finger(obj, orig_bone_name):
obj, arm, driver_pbone, driver_bone = get_bone_data(obj, driver_bone_name)
driver_pbone.rotation_mode = 'YZX'
driver_pbone.driver_add("rotation_euler", 0)
fcurve_driver = driver_pbone.driver_add("rotation_euler", 0)
#obj.driver_add('pose.bones["%s"].scale', 1)
fcurve_driver = obj.animation_data.drivers[-1] # XXX, WATCH THIS
#obj.animation_data.drivers[-1] # XXX, WATCH THIS
driver = fcurve_driver.driver
# scale target
@@ -189,20 +222,133 @@ def gen_finger(obj, orig_bone_name):
driver.expression = '(-scale+1.0)*pi*2.0*br'
obj, arm, child_pbone, child_bone = get_bone_data(obj, child_bone_name)
# only allow X rotation
driver_pbone.lock_rotation = child_pbone.lock_rotation = (False, True, True)
i += 1
def gen_delta(obj, delta_name):
'''
Use this bone to define a delta thats applied to its child in pose mode.
'''
mode_orig = obj.mode
bpy.ops.object.mode_set(mode='OBJECT')
delta_pbone = obj.pose.bones[delta_name]
children = delta_pbone.children
if len(children) != 1:
print("only 1 child supported for delta")
child_name = children[0].name
delta_head = delta_pbone.head.copy()
delta_tail = delta_pbone.tail.copy()
delta_matrix = delta_pbone.matrix.copy()
children = delta_pbone.children
bpy.ops.object.mode_set(mode='EDIT')
arm = obj.data
# XXX -probably should allow via the UI
for ebone in arm.edit_bones:
ebone.selected = ebone.head_selected = ebone.tail_selected = False
# Select for deleting
delta_ebone = arm.edit_bones[delta_name]
delta_ebone.selected = delta_ebone.head_selected = delta_ebone.tail_selected = True
bpy.ops.armature.delete()
bpy.ops.object.mode_set(mode='OBJECT')
# Move the child bone to the deltas location
obj.animation_data_create()
child_pbone = obj.pose[child_name]
# ------------------- drivers
fcurve_driver = child_pbone.driver_add("rotation_euler", 0)
#fcurve_driver = obj.animation_data.drivers[-1] # XXX, WATCH THIS
driver = fcurve_driver.driver
driver.type = 'AVERAGE'
mod = driver.modifiers.new('GENERATOR')
obj, arm, parent_pbone, parent_bone = get_bone_data(obj, delta_name)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.object.mode_set(mode=mode_orig)
def gen_arm(obj, orig_bone_name):
"""
the bone with the 'arm' property is the upper arm, this assumes a chain as follows.
[shoulder, upper_arm, forearm, hand]
...where this bone is 'upper_arm'
"""
def validate_chain():
'''
Sanity check and return the arm as a list of bone names.
'''
# do a sanity check
obj, arm, orig_pbone, orig_ebone = get_bone_data(obj, orig_bone_name)
shoulder_pbone = arm_pbone.parent
if not shoulder_pbone:
print("could not find 'arm' parent, skipping:", orig_bone_name)
return
# We could have some bones attached, find the bone that has this as its 2nd parent
hands = []
for pbone in obj.pose.bones:
index = pbone.parent_index(orig_pbone)
if index == 2:
hands.append(pbone)
if len(hands) > 1:
print("more then 1 hand found on:", orig_bone_name)
return
# first add the 2 new bones
hand_pbone = hands[0]
forearm_pbone = hand_pbone.parent
return shoulder_pbone.name, orig_pbone.name, forearm_pbone.name, hand_pbone.name
shoulder_name, arm_name, forearm_name, hand_name = validate_chain()
obj, arm, hand_pbone, hand_ebone = get_bone_data(obj, hand_name)
# Add the edit bones
hand_ik_ebone = arm.edit_bones.new(hand_name + "_ik")
hand_ik_ebone.head = hand_ebone.head
hand_ik_ebone.tail = hand_ebone.tail
hand_ik_ebone.roll = hand_ebone.roll
gen_table = {
"":gen_none, \
"finger":gen_finger, \
"delta":gen_delta, \
"arm":gen_arm, \
}
def generate_rig(context, ob):
# add_stretch_to(ob, "a", "b", "c")
bpy.ops.object.mode_set(mode='OBJECT')
@@ -233,7 +379,7 @@ def generate_rig(context, ob):
bpy.ops.object.mode_set(mode='OBJECT')
# needed to update driver deps
context.scene.update()
# context.scene.update()
if __name__ == "__main__":
generate_rig(bpy.context, bpy.context.object)

View File

@@ -94,9 +94,6 @@ extern "C"
char *CustomData_get_layer_name(const struct CustomData *data, int type, int n);
// armature module internal func, it's not good to use it here? (Arystan)
struct EditBone *addEditBone(struct bArmature *arm, char *name);
const char *primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
{
using namespace COLLADAFW;
@@ -592,7 +589,7 @@ private:
}
// TODO rename from Node "name" attrs later
EditBone *bone = addEditBone(arm, (char*)get_joint_name(node));
EditBone *bone = ED_armature_edit_bone_add(arm, (char*)get_joint_name(node));
totbone++;
if (parent) bone->parent = parent;

View File

@@ -502,7 +502,7 @@ static short visualkey_can_use (PointerRNA *ptr, PropertyRNA *prop)
/* get first constraint and determine type of keyframe constraints to check for
* - constraints can be on either Objects or PoseChannels, so we only check if the
* ptr->type is RNA_Object or RNA_PoseChannel, which are the RNA wrapping-info for
* ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
* those structs, allowing us to identify the owner of the data
*/
if (ptr->type == &RNA_Object) {
@@ -600,7 +600,7 @@ static float visualkey_get_value (PointerRNA *ptr, PropertyRNA *prop, int array_
/* handle for Objects or PoseChannels only
* - constraints can be on either Objects or PoseChannels, so we only check if the
* ptr->type is RNA_Object or RNA_PoseChannel, which are the RNA wrapping-info for
* ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
* those structs, allowing us to identify the owner of the data
* - assume that array_index will be sane
*/

View File

@@ -137,7 +137,6 @@ struct EditBone;
struct ListBase;
EditBone *make_boneList(struct ListBase *edbo, struct ListBase *bones, struct EditBone *parent, struct Bone *actBone);
struct EditBone *addEditBone(struct bArmature *arm, char *name);
void BIF_sk_selectStroke(struct bContext *C, short mval[2], short extend);
/* duplicate method */

View File

@@ -141,7 +141,7 @@ void ED_armature_validate_active(struct bArmature *arm)
}
}
void free_edit_bone(bArmature *arm, EditBone *bone)
void ED_armature_edit_bone_remove(bArmature *arm, EditBone *bone)
{
if(arm->act_edbone==bone)
arm->act_edbone= NULL;
@@ -305,7 +305,7 @@ void ED_armature_from_edit(Object *obedit)
fBone->parent= eBone->parent;
}
printf("Warning: removed zero sized bone: %s\n", eBone->name);
free_edit_bone(arm, eBone);
ED_armature_edit_bone_remove(arm, eBone);
}
}
@@ -1035,7 +1035,7 @@ static void separate_armature_bones (Scene *scene, Object *ob, short sel)
free_pose_channel(pchan);
/* get rid of unneeded bone */
free_edit_bone(arm, curbone);
ED_armature_edit_bone_remove(arm, curbone);
BLI_freelinkN(&ob->pose->chanbase, pchan);
}
}
@@ -1684,7 +1684,7 @@ static void delete_bone(bArmature *arm, EditBone* exBone)
}
}
free_edit_bone(arm, exBone);
ED_armature_edit_bone_remove(arm, exBone);
}
/* context: editmode armature */
@@ -2245,7 +2245,7 @@ void undo_push_armature(bContext *C, char *name)
/* *************** Adding stuff in editmode *************** */
/* default bone add, returns it selected, but without tail set */
EditBone *addEditBone(bArmature *arm, char *name)
EditBone *ED_armature_edit_bone_add(bArmature *arm, char *name)
{
EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
@@ -2269,14 +2269,6 @@ EditBone *addEditBone(bArmature *arm, char *name)
return bone;
}
/* default bone add, returns it selected, but without tail set */
static EditBone *add_editbone(Object *obedit, char *name)
{
bArmature *arm= obedit->data;
return addEditBone(arm, name);
}
/* v3d and rv3d are allowed to be NULL */
void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
@@ -2301,7 +2293,7 @@ void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d)
ED_armature_deselectall(obedit, 0, 0);
/* Create a bone */
bone= add_editbone(obedit, "Bone");
bone= ED_armature_edit_bone_add(obedit->data, "Bone");
VECCOPY(bone->head, curs);
@@ -2367,7 +2359,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *op)
}
}
newbone= add_editbone(obedit, ebone->name);
newbone= ED_armature_edit_bone_add(arm, ebone->name);
arm->act_edbone= newbone;
if (to_root) {
@@ -2484,7 +2476,7 @@ static EditBone *add_points_bone (Object *obedit, float head[], float tail[])
{
EditBone *ebo;
ebo= add_editbone(obedit, "Bone");
ebo= ED_armature_edit_bone_add(obedit->data, "Bone");
VECCOPY(ebo->head, head);
VECCOPY(ebo->tail, tail);
@@ -3110,7 +3102,7 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone
/* step 3: delete all bones between and including start and end */
for (ebo= end; ebo; ebo= ebone) {
ebone= (ebo == start) ? (NULL) : (ebo->parent);
free_edit_bone(arm, ebo);
ED_armature_edit_bone_remove(arm, ebo);
}
}
@@ -3465,7 +3457,7 @@ static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op)
ED_armature_deselectall(obedit, 0, 0);
/* Create a bone */
bone= add_editbone(obedit, name);
bone= ED_armature_edit_bone_add(obedit->data, name);
VECCOPY(bone->head, curs);
@@ -5623,7 +5615,7 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode
EditBone *root = NULL;
float angleLimit = (float)cos(scene->toolsettings->skgen_angle_limit * M_PI / 180.0f);
parent = add_editbone(obedit, "Bone");
parent = ED_armature_edit_bone_add(arm, "Bone");
parent->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
VECCOPY(parent->head, head->p);
@@ -5652,7 +5644,7 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode
{
VECCOPY(parent->tail, previous);
child = add_editbone(obedit, "Bone");
child = ED_armature_edit_bone_add(arm, "Bone");
VECCOPY(child->head, parent->tail);
child->parent = parent;
child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
@@ -5858,7 +5850,7 @@ void generateSkeletonFromReebGraph(Scene *scene, ReebGraph *rg)
if (lastBone == NULL)
{
EditBone *bone;
bone = add_editbone(obedit, "Bone");
bone = ED_armature_edit_bone_add(obedit->data, "Bone");
bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
VECCOPY(bone->head, head->p);

View File

@@ -294,7 +294,7 @@ EditBone * subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *
IT_head(iter);
parent = addEditBone(arm, "Bone");
parent = ED_armature_edit_bone_add(arm, "Bone");
VECCOPY(parent->head, iter->p);
if (iter->size > 0)
@@ -309,7 +309,7 @@ EditBone * subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *
{
IT_peek(iter, index);
child = addEditBone(arm, "Bone");
child = ED_armature_edit_bone_add(arm, "Bone");
VECCOPY(child->head, parent->tail);
child->parent = parent;
child->flag |= BONE_CONNECTED;

View File

@@ -1538,7 +1538,7 @@ void sk_convertStroke(bContext *C, SK_Stroke *stk)
if (bone == NULL)
{
bone = addEditBone(arm, "Bone");
bone = ED_armature_edit_bone_add(arm, "Bone");
VECCOPY(bone->head, head->p);
VECCOPY(bone->tail, pt->p);

View File

@@ -311,7 +311,7 @@ typedef enum eAnimChannels_SetFlag {
ACHANNEL_SETFLAG_TOGGLE
} eAnimChannels_SetFlag;
/* types of settings for AnimChanels */
/* types of settings for AnimChannels */
typedef enum eAnimChannel_Settings {
ACHANNEL_SETTING_SELECT = 0,
ACHANNEL_SETTING_PROTECT, // warning: for drawing UI's, need to check if this is off (maybe inverse this later)

View File

@@ -116,7 +116,8 @@ void ED_armature_sync_selection(struct ListBase *edbo);
void ED_armature_validate_active(struct bArmature *arm);
void add_primitive_bone(struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d);
EditBone *addEditBone(struct bArmature *arm, char *name); /* used by COLLADA importer */
struct EditBone *ED_armature_edit_bone_add(struct bArmature *arm, char *name);
void ED_armature_edit_bone_remove(struct bArmature *arm, EditBone *bone);
void transform_armature_mirror_update(struct Object *obedit);
void clear_armature(struct Scene *scene, struct Object *ob, char mode);

View File

@@ -93,6 +93,15 @@ static void rna_Armature_act_edit_bone_set(PointerRNA *ptr, PointerRNA value)
}
}
EditBone *rna_Armature_edit_bone_new(bArmature *arm, char *name)
{
return ED_armature_edit_bone_add(arm, name);
}
void rna_Armature_edit_bone_remove(bArmature *arm, EditBone *ebone)
{
ED_armature_edit_bone_remove(arm, ebone);
}
static void rna_Armature_redraw_data(bContext *C, PointerRNA *ptr)
{
@@ -661,8 +670,8 @@ static void rna_def_armature_edit_bones(BlenderRNA *brna, PropertyRNA *cprop)
StructRNA *srna;
PropertyRNA *prop;
// FunctionRNA *func;
// PropertyRNA *parm;
FunctionRNA *func;
PropertyRNA *parm;
RNA_def_property_srna(cprop, "ArmatureEditBones");
srna= RNA_def_struct(brna, "ArmatureEditBones", NULL);
@@ -679,6 +688,22 @@ static void rna_def_armature_edit_bones(BlenderRNA *brna, PropertyRNA *cprop)
/* todo, redraw */
// RNA_def_property_collection_active(prop, prop_act);
/* add target */
func= RNA_def_function(srna, "new", "rna_Armature_edit_bone_new");
RNA_def_function_ui_description(func, "Add a new bone.");
parm= RNA_def_string(func, "name", "Object", 0, "", "New name for the bone.");
RNA_def_property_flag(parm, PROP_REQUIRED);
/* return type */
parm= RNA_def_pointer(func, "bone", "EditBone", "", "Newly created edit bone.");
RNA_def_function_return(func, parm);
/* remove target */
func= RNA_def_function(srna, "remove", "rna_Armature_edit_bone_remove");
RNA_def_function_ui_description(func, "Remove an existing bone from the armature.");
/* target to remove*/
parm= RNA_def_pointer(func, "bone", "EditBone", "", "EditBone to remove.");
RNA_def_property_flag(parm, PROP_REQUIRED);
}
static void rna_def_armature(BlenderRNA *brna)

View File

@@ -276,7 +276,7 @@ static void rna_Fmodifier_active_update(bContext *C, PointerRNA *ptr)
}
static int rna_FM_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
static int rna_FModifierGenerator_coefficients_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
FModifier *fm= (FModifier*)ptr->data;
FMod_Generator *gen= fm->data;
@@ -289,14 +289,14 @@ static int rna_FM_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION
return length[0];
}
static void rna_FM_get(PointerRNA *ptr, float *values)
static void rna_FModifierGenerator_coefficients_get(PointerRNA *ptr, float *values)
{
FModifier *fm= (FModifier*)ptr->data;
FMod_Generator *gen= fm->data;
memcpy(values, gen->coefficients, gen->arraysize * sizeof(float));
}
static void rna_FM_set(PointerRNA *ptr, const float *values)
static void rna_FModifierGenerator_coefficients_set(PointerRNA *ptr, const float *values)
{
FModifier *fm= (FModifier*)ptr->data;
FMod_Generator *gen= fm->data;
@@ -342,8 +342,8 @@ static void rna_def_fmodifier_generator(BlenderRNA *brna)
prop= RNA_def_property(srna, "coefficients", PROP_FLOAT, PROP_NONE);
RNA_def_property_array(prop, 32);
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_dynamic_array_funcs(prop, "rna_FM_get_length");
RNA_def_property_float_funcs(prop, "rna_FM_get", "rna_FM_set", NULL);
RNA_def_property_dynamic_array_funcs(prop, "rna_FModifierGenerator_coefficients_get_length");
RNA_def_property_float_funcs(prop, "rna_FModifierGenerator_coefficients_get", "rna_FModifierGenerator_coefficients_set", NULL);
RNA_def_property_ui_text(prop, "Coefficients", "Coefficients for 'x' (starting from lowest power of x^0).");
/* coefficients array */

View File

@@ -120,7 +120,7 @@ static IDProperty *rna_PoseBone_idproperties(PointerRNA *ptr, int create)
if(create && !pchan->prop) {
IDPropertyTemplate val = {0};
pchan->prop= IDP_New(IDP_GROUP, val, "RNA_PoseChannel group");
pchan->prop= IDP_New(IDP_GROUP, val, "RNA_PoseBone group");
}
return pchan->prop;