40
40
#include "DNA_anim_types.h"
41
#include "DNA_mesh_types.h"
41
42
#include "DNA_armature_types.h"
42
43
#include "DNA_constraint_types.h"
43
44
#include "DNA_meshdata_types.h"
124
124
EditBone *ebone= arm->act_edbone;
127
if(ebone->flag & BONE_HIDDEN_A)
127
if (ebone->flag & BONE_HIDDEN_A)
128
128
arm->act_edbone= NULL;
132
132
static void bone_free(bArmature *arm, EditBone *bone)
134
if(arm->act_edbone==bone)
134
if (arm->act_edbone==bone)
135
135
arm->act_edbone= NULL;
138
138
IDP_FreeProperty(bone->prop);
139
139
MEM_freeN(bone->prop);
181
181
/* helper function for tools to work on mirrored parts.
182
it leaves mirrored bones selected then too, which is a good indication of what happened */
182
* it leaves mirrored bones selected then too, which is a good indication of what happened */
183
183
static void armature_select_mirrored(bArmature *arm)
185
185
/* Select mirrored bones */
276
276
/* if the bone is not selected, but connected to its parent
277
277
* copy the parents tip selection state */
278
if(eBone->parent && (eBone->flag & BONE_CONNECTED)) {
278
if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
279
279
/* selecting with the mouse gives this behavior */
280
if(eBone->parent->flag & BONE_TIPSEL) {
280
if (eBone->parent->flag & BONE_TIPSEL) {
281
281
eBone->flag |= BONE_ROOTSEL;
284
284
eBone->flag &= ~BONE_ROOTSEL;
287
/* probably not selected but just incase */
287
/* probably not selected but just in case */
288
288
eBone->flag &= ~BONE_TIPSEL;
306
306
eBone->segments = curBone->segments;
307
307
eBone->layer = curBone->layer;
310
310
eBone->prop= IDP_CopyProperty(curBone->prop);
312
312
BLI_addtail(edbo, eBone);
314
314
/* Add children if necessary */
315
315
if (curBone->childbase.first) {
316
316
eBoneTest= make_boneList(edbo, &curBone->childbase, eBone, actBone);
318
318
eBoneAct= eBoneTest;
321
if (curBone==actBone)
434
434
newBone->segments= eBone->segments;
435
435
newBone->layer = eBone->layer;
438
438
newBone->prop= IDP_CopyProperty(eBone->prop);
441
/* Fix parenting in a separate pass to ensure ebone->bone connections
442
are valid at this point */
441
/* Fix parenting in a separate pass to ensure ebone->bone connections
442
* are valid at this point */
443
443
for (eBone=arm->edbo->first;eBone;eBone=eBone->next) {
444
444
newBone= (Bone *)eBone->temp;
445
445
if (eBone->parent) {
554
554
mul_m4_v3(ob->imat, cent);
557
if(around==V3D_CENTROID) {
557
if (around==V3D_CENTROID) {
560
560
for (ebone= arm->edbo->first; ebone; ebone=ebone->next) {
584
584
/* Turn the list into an armature */
586
586
ED_armature_from_edit(ob);
587
587
ED_armature_edit_free(ob);
590
590
/* Adjust object location for new centerpoint */
591
if(centermode && obedit==NULL) {
591
if (centermode && obedit==NULL) {
592
592
mul_mat3_m4_v3(ob->obmat, cent); /* ommit translation part */
593
593
add_v3_v3(ob->loc, cent);
729
729
void POSE_OT_armature_apply (wmOperatorType *ot)
731
731
/* identifiers */
732
ot->name= "Apply Pose as Rest Pose";
733
ot->idname= "POSE_OT_armature_apply";
734
ot->description= "Apply the current pose as the new rest pose";
732
ot->name = "Apply Pose as Rest Pose";
733
ot->idname = "POSE_OT_armature_apply";
734
ot->description = "Apply the current pose as the new rest pose";
737
ot->exec= apply_armature_pose2bones_exec;
738
ot->poll= ED_operator_posemode;
737
ot->exec = apply_armature_pose2bones_exec;
738
ot->poll = ED_operator_posemode;
741
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
741
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
780
780
void POSE_OT_visual_transform_apply (wmOperatorType *ot)
782
782
/* identifiers */
783
ot->name= "Apply Visual Transform to Pose";
784
ot->idname= "POSE_OT_visual_transform_apply";
785
ot->description= "Apply final constrained position of pose bones to their transform";
783
ot->name = "Apply Visual Transform to Pose";
784
ot->idname = "POSE_OT_visual_transform_apply";
785
ot->description = "Apply final constrained position of pose bones to their transform";
788
ot->exec= pose_visual_transform_apply_exec;
789
ot->poll= ED_operator_posemode;
788
ot->exec = pose_visual_transform_apply_exec;
789
ot->poll = ED_operator_posemode;
792
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
792
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
795
795
/* ---------------------- */
1044
1044
if (ct->subtarget[0] != 0) {
1045
1045
if (ct->tar == origArm) {
1046
if(BLI_findstring(npchans, ct->subtarget, offsetof(bPoseChannel, name))) {
1046
if (BLI_findstring(npchans, ct->subtarget, offsetof(bPoseChannel, name))) {
1047
1047
ct->tar= newArm;
1050
1050
else if (ct->tar == newArm) {
1051
if(BLI_findstring(opchans, ct->subtarget, offsetof(bPoseChannel, name))) {
1051
if (BLI_findstring(opchans, ct->subtarget, offsetof(bPoseChannel, name))) {
1052
1052
ct->tar= origArm;
1079
1079
* - the target isn't origArm/newArm itself
1080
1080
* - the target is one that can be found in newArm/origArm
1082
if(ct->subtarget[0] != '\0') {
1082
if (ct->subtarget[0] != '\0') {
1083
1083
if (ct->tar == origArm) {
1084
if(BLI_findstring(npchans, ct->subtarget, offsetof(bPoseChannel, name))) {
1084
if (BLI_findstring(npchans, ct->subtarget, offsetof(bPoseChannel, name))) {
1085
1085
ct->tar= newArm;
1088
1088
else if (ct->tar == newArm) {
1089
if(BLI_findstring(opchans, ct->subtarget, offsetof(bPoseChannel, name))) {
1089
if (BLI_findstring(opchans, ct->subtarget, offsetof(bPoseChannel, name))) {
1090
1090
ct->tar= origArm;
1104
1104
if (ob->parent && (ob->parent == origArm)) {
1105
1105
/* Is object parented to a bone of this src armature? */
1106
1106
if ((ob->partype == PARBONE) && (ob->parsubstr[0] != '\0')) {
1107
if(BLI_findstring(npchans, ob->parsubstr, offsetof(bPoseChannel, name))) {
1107
if (BLI_findstring(npchans, ob->parsubstr, offsetof(bPoseChannel, name))) {
1108
1108
ob->parent= newArm;
1243
1243
void ARMATURE_OT_separate (wmOperatorType *ot)
1245
1245
/* identifiers */
1246
ot->name= "Separate Bones";
1247
ot->idname= "ARMATURE_OT_separate";
1248
ot->description= "Isolate selected bones into a separate armature";
1246
ot->name = "Separate Bones";
1247
ot->idname = "ARMATURE_OT_separate";
1248
ot->description = "Isolate selected bones into a separate armature";
1250
1250
/* callbacks */
1251
ot->invoke= WM_operator_confirm;
1252
ot->exec= separate_armature_exec;
1253
ot->poll= ED_operator_editarmature;
1251
ot->invoke = WM_operator_confirm;
1252
ot->exec = separate_armature_exec;
1253
ot->poll = ED_operator_editarmature;
1256
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1256
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1259
1259
/* **************** END tools on Editmode Armature **************** */
1263
1263
Bone *get_indexed_bone (Object *ob, int index)
1265
1265
bPoseChannel *pchan;
1266
if(ob->pose==NULL) return NULL;
1266
if (ob->pose==NULL) return NULL;
1267
1267
index>>=16; // bone selection codes use left 2 bytes
1269
1269
pchan= BLI_findlink(&ob->pose->chanbase, index);
1281
1281
unsigned int hitresult;
1282
1282
short i, takeNext=0, sel;
1284
for (i=0; i< hits; i++){
1284
for (i=0; i< hits; i++) {
1285
1285
hitresult = buffer[3+(i*4)];
1287
1287
if (!(hitresult & BONESEL_NOSEL)) { // -1
1288
if(hitresult & BONESEL_ANY) { // to avoid including objects in selection
1288
if (hitresult & BONESEL_ANY) { // to avoid including objects in selection
1290
1290
hitresult &= ~(BONESEL_ANY);
1291
1291
/* Determine what the current bone is */
1292
1292
if (obedit==NULL || base->object!=obedit) {
1293
1293
/* no singular posemode, so check for correct object */
1294
if(base->selcol == (hitresult & 0xFFFF)) {
1294
if (base->selcol == (hitresult & 0xFFFF)) {
1295
1295
bone = get_indexed_bone(base->object, hitresult);
1355
1355
view3d_set_viewcontext(C, &vc);
1357
// rect.xmin= ... mouseco!
1358
rect.xmin= rect.xmax= x;
1359
rect.ymin= rect.ymax= y;
1357
// rect.xmin = ... mouseco!
1358
rect.xmin = rect.xmax = x;
1359
rect.ymin = rect.ymax = y;
1362
1362
hits= view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect);
1430
1430
return OPERATOR_CANCELLED;
1432
1432
/* Select parents */
1433
for (curBone=bone; curBone; curBone=next){
1433
for (curBone=bone; curBone; curBone=next) {
1434
1434
/* ignore bone if cannot be selected */
1435
1435
if ((curBone->flag & BONE_UNSELECTABLE) == 0) {
1436
1436
// XXX old cruft! use notifiers instead
1467
1467
void POSE_OT_select_linked(wmOperatorType *ot)
1469
1469
/* identifiers */
1470
ot->name= "Select Connected";
1471
ot->idname= "POSE_OT_select_linked";
1472
ot->description= "Select bones related to selected ones by parent/child relationships";
1470
ot->name = "Select Connected";
1471
ot->idname = "POSE_OT_select_linked";
1472
ot->description = "Select bones related to selected ones by parent/child relationships";
1474
1474
/* api callbacks */
1476
ot->invoke= pose_select_connected_invoke;
1477
ot->poll= pose_select_linked_poll;
1476
ot->invoke = pose_select_connected_invoke;
1477
ot->poll = pose_select_linked_poll;
1480
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1480
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1483
1483
RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
1561
1561
void ARMATURE_OT_select_linked(wmOperatorType *ot)
1563
1563
/* identifiers */
1564
ot->name= "Select Connected";
1565
ot->idname= "ARMATURE_OT_select_linked";
1566
ot->description= "Select bones related to selected ones by parent/child relationships";
1564
ot->name = "Select Connected";
1565
ot->idname = "ARMATURE_OT_select_linked";
1566
ot->description = "Select bones related to selected ones by parent/child relationships";
1568
1568
/* api callbacks */
1570
ot->invoke= armature_select_linked_invoke;
1571
ot->poll= armature_select_linked_poll;
1570
ot->invoke = armature_select_linked_invoke;
1571
ot->poll = armature_select_linked_poll;
1574
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1574
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1576
1576
/* properties s*/
1577
1577
RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first");
1593
rect.xmin= mval[0]-5;
1594
rect.xmax= mval[0]+5;
1595
rect.ymin= mval[1]-5;
1596
rect.ymax= mval[1]+5;
1593
rect.xmin = mval[0]-5;
1594
rect.xmax = mval[0]+5;
1595
rect.ymin = mval[1]-5;
1596
rect.ymax = mval[1]+5;
1598
1598
hits= view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
1600
rect.xmin= mval[0]-12;
1601
rect.xmax= mval[0]+12;
1602
rect.ymin= mval[1]-12;
1603
rect.ymax= mval[1]+12;
1600
rect.xmin = mval[0]-12;
1601
rect.xmax = mval[0]+12;
1602
rect.ymin = mval[1]-12;
1603
rect.ymax = mval[1]+12;
1604
1604
hits= view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
1606
1606
/* See if there are any selected bones in this group */
1610
1610
if (!(buffer[3] & BONESEL_NOSEL))
1611
1611
besthitresult= buffer[3];
1619
1619
ebone = BLI_findlink(edbo, hitresult & ~BONESEL_ANY);
1621
1621
/* clicks on bone points get advantage */
1622
if( hitresult & (BONESEL_ROOT|BONESEL_TIP)) {
1622
if ( hitresult & (BONESEL_ROOT|BONESEL_TIP)) {
1623
1623
/* but also the unselected one */
1625
if( (hitresult & BONESEL_ROOT) && (ebone->flag & BONE_ROOTSEL)==0)
1625
if ( (hitresult & BONESEL_ROOT) && (ebone->flag & BONE_ROOTSEL)==0)
1627
else if( (hitresult & BONESEL_TIP) && (ebone->flag & BONE_TIPSEL)==0)
1627
else if ( (hitresult & BONESEL_TIP) && (ebone->flag & BONE_TIPSEL)==0)
1729
1729
ebone_next= curBone->next;
1730
1730
if (arm->layer & curBone->layer) {
1731
1731
if (curBone->flag & BONE_SELECTED) {
1732
if(curBone==arm->act_edbone) arm->act_edbone= NULL;
1732
if (curBone==arm->act_edbone) arm->act_edbone= NULL;
1733
1733
ED_armature_edit_bone_remove(arm, curBone);
1746
1746
void ARMATURE_OT_delete(wmOperatorType *ot)
1748
1748
/* identifiers */
1749
ot->name= "Delete Selected Bone(s)";
1750
ot->idname= "ARMATURE_OT_delete";
1751
ot->description= "Remove selected bones from the armature";
1749
ot->name = "Delete Selected Bone(s)";
1750
ot->idname = "ARMATURE_OT_delete";
1751
ot->description = "Remove selected bones from the armature";
1753
1753
/* api callbacks */
1754
1754
ot->invoke = WM_operator_confirm;
1769
1769
EditBone *eBone;
1773
/* Determine if there are any selected bones
1774
And therefore whether we are selecting or deselecting */
1775
for (eBone=arm->edbo->first;eBone;eBone=eBone->next){
1776
// if(arm->layer & eBone->layer) {
1777
if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)){
1773
/* Determine if there are any selected bones
1774
* and therefore whether we are selecting or deselecting */
1775
for (eBone=arm->edbo->first;eBone;eBone=eBone->next) {
1776
// if (arm->layer & eBone->layer) {
1777
if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) {
1787
1787
for (eBone=arm->edbo->first;eBone;eBone=eBone->next) {
1789
1789
/* invert selection of bone */
1790
if(EBONE_VISIBLE(arm, eBone)) {
1790
if (EBONE_VISIBLE(arm, eBone)) {
1791
1791
eBone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1792
if(arm->act_edbone==eBone)
1792
if (arm->act_edbone==eBone)
1793
1793
arm->act_edbone= NULL;
1796
1796
else if (sel==1) {
1797
1797
/* select bone */
1798
if(EBONE_VISIBLE(arm, eBone)) {
1798
if (EBONE_VISIBLE(arm, eBone)) {
1799
1799
eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1801
1801
eBone->parent->flag |= (BONE_TIPSEL);
1805
1805
/* deselect bone */
1806
1806
eBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1807
if(arm->act_edbone==eBone)
1807
if (arm->act_edbone==eBone)
1808
1808
arm->act_edbone= NULL;
1830
1830
/* accounts for connected parents */
1831
1831
static int ebone_select_flag(EditBone *ebone)
1833
if(ebone->parent && (ebone->flag & BONE_CONNECTED)) {
1833
if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
1834
1834
return ((ebone->parent->flag & BONE_TIPSEL) ? BONE_ROOTSEL : 0) | (ebone->flag & (BONE_SELECTED|BONE_TIPSEL));
1858
1858
ED_armature_deselect_all(obedit, 0);
1860
1860
/* by definition the non-root connected bones have no root point drawn,
1861
so a root selection needs to be delivered to the parent tip */
1861
* so a root selection needs to be delivered to the parent tip */
1863
if(selmask & BONE_SELECTED) {
1864
if(nearBone->parent && (nearBone->flag & BONE_CONNECTED)) {
1863
if (selmask & BONE_SELECTED) {
1864
if (nearBone->parent && (nearBone->flag & BONE_CONNECTED)) {
1865
1865
/* click in a chain */
1867
1867
/* hold shift inverts this bone's selection */
1868
if(nearBone->flag & BONE_SELECTED) {
1868
if (nearBone->flag & BONE_SELECTED) {
1869
1869
/* deselect this bone */
1870
1870
nearBone->flag &= ~(BONE_TIPSEL|BONE_SELECTED);
1871
1871
/* only deselect parent tip if it is not selected */
1872
if(!(nearBone->parent->flag & BONE_SELECTED))
1872
if (!(nearBone->parent->flag & BONE_SELECTED))
1873
1873
nearBone->parent->flag &= ~BONE_TIPSEL;
1889
1889
/* hold shift inverts this bone's selection */
1890
if(nearBone->flag & BONE_SELECTED)
1890
if (nearBone->flag & BONE_SELECTED)
1891
1891
nearBone->flag &= ~(BONE_TIPSEL|BONE_ROOTSEL);
1893
1893
nearBone->flag |= (BONE_TIPSEL|BONE_ROOTSEL);
1905
1905
ED_armature_sync_selection(arm->edbo);
1908
1908
/* then now check for active status */
1909
if(ebone_select_flag(nearBone)) {
1909
if (ebone_select_flag(nearBone)) {
1910
1910
arm->act_edbone= nearBone;
1965
1965
sub_v3_v3v3(nor, bone->tail, bone->head);
1966
1966
vec_roll_to_mat3(nor, 0.0f, mat);
1968
/* check the bone isnt aligned with the axis */
1969
if(!is_zero_v3(align_axis) && angle_v3v3(align_axis, mat[2]) > FLT_EPSILON) {
1968
/* check the bone isn't aligned with the axis */
1969
if (!is_zero_v3(align_axis) && angle_v3v3(align_axis, mat[2]) > FLT_EPSILON) {
1970
1970
float vec[3], align_axis_proj[3], roll;
1972
1972
/* project the new_up_axis along the normal */
1973
1973
project_v3_v3v3(vec, align_axis, nor);
1974
1974
sub_v3_v3v3(align_axis_proj, align_axis, vec);
1977
if(angle_v3v3(align_axis_proj, mat[2]) > (float)(M_PI/2.0)) {
1977
if (angle_v3v3(align_axis_proj, mat[2]) > (float)(M_PI/2.0)) {
1978
1978
negate_v3(align_axis_proj);
2020
2020
copy_m3_m4(imat, ob->obmat);
2021
2021
invert_m3(imat);
2023
if(type==7) { /* Cursor */
2023
if (type==7) { /* Cursor */
2024
2024
Scene *scene= CTX_data_scene(C);
2025
2025
View3D *v3d= CTX_wm_view3d(C); /* can be NULL */
2026
2026
float cursor_local[3];
2031
2031
mul_m3_v3(imat, cursor_local);
2034
for(ebone= arm->edbo->first; ebone; ebone= ebone->next) {
2035
if(EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
2034
for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
2035
if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
2036
2036
float cursor_rel[3];
2037
2037
sub_v3_v3v3(cursor_rel, cursor_local, ebone->head);
2038
if(axis_flip) negate_v3(cursor_rel);
2038
if (axis_flip) negate_v3(cursor_rel);
2039
2039
ebone->roll= ED_rollBoneToVector(ebone, cursor_rel, axis_only);
2044
2044
float vec[3]= {0.0f, 0.0f, 0.0f};
2045
if(type==6) { /* View */
2045
if (type==6) { /* View */
2046
2046
RegionView3D *rv3d= CTX_wm_region_view3d(C);
2048
2048
BKE_report(op->reports, RPT_ERROR, "No region view3d available");
2049
2049
return OPERATOR_CANCELLED;
2067
2067
else { /* Axis */
2068
2068
assert(type >= 0 && type <= 5);
2069
if(type<3) vec[type]= 1.0f;
2069
if (type<3) vec[type]= 1.0f;
2070
2070
else vec[type-2]= -1.0f;
2071
2071
mul_m3_v3(imat, vec);
2074
if(axis_flip) negate_v3(vec);
2074
if (axis_flip) negate_v3(vec);
2076
for(ebone= arm->edbo->first; ebone; ebone= ebone->next) {
2077
if(EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
2076
for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
2077
if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
2078
2078
/* roll func is a callback which assumes that all is well */
2079
2079
ebone->roll= ED_rollBoneToVector(ebone, vec, axis_only);
2084
2084
if (arm->flag & ARM_MIRROR_EDIT) {
2085
for(ebone= arm->edbo->first; ebone; ebone= ebone->next) {
2086
if((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) {
2085
for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
2086
if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) {
2087
2087
EditBone *ebone_mirr= ED_armature_bone_get_mirrored(arm->edbo, ebone);
2088
2088
if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) {
2089
2089
ebone->roll= -ebone_mirr->roll;
2101
2101
void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
2103
2103
/* identifiers */
2104
ot->name= "Recalculate Roll";
2105
ot->idname= "ARMATURE_OT_calculate_roll";
2106
ot->description= "Automatically fix alignment of select bones' axes";
2104
ot->name = "Recalculate Roll";
2105
ot->idname = "ARMATURE_OT_calculate_roll";
2106
ot->description = "Automatically fix alignment of select bones' axes";
2108
2108
/* api callbacks */
2109
2109
ot->invoke = WM_menu_invoke;
2111
2111
ot->poll = ED_operator_editarmature;
2114
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
2114
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
2116
2116
/* properties */
2117
ot->prop= RNA_def_enum(ot->srna, "type", prop_calc_roll_types, 0, "Type", "");
2117
ot->prop = RNA_def_enum(ot->srna, "type", prop_calc_roll_types, 0, "Type", "");
2118
2118
RNA_def_boolean(ot->srna, "axis_flip", 0, "Flip Axis", "Negate the alignment axis");
2119
2119
RNA_def_boolean(ot->srna, "axis_only", 0, "Shortest Rotation", "Ignore the axis direction, use the shortest rotation to align");
2127
2127
} UndoArmature;
2129
static void undoBones_to_editBones(void *uarmv, void *armv)
2129
static void undoBones_to_editBones(void *uarmv, void *armv, void *UNUSED(data))
2131
2131
UndoArmature *uarm= uarmv;
2132
2132
bArmature *arm= armv;
2135
2135
BLI_freelistN(arm->edbo);
2138
for(ebo= uarm->lb.first; ebo; ebo= ebo->next) {
2138
for (ebo= uarm->lb.first; ebo; ebo= ebo->next) {
2139
2139
newebo= MEM_dupallocN(ebo);
2140
2140
ebo->temp= newebo;
2141
2141
BLI_addtail(arm->edbo, newebo);
2144
2144
/* active bone */
2145
if(uarm->act_edbone) {
2145
if (uarm->act_edbone) {
2146
2146
ebo= uarm->act_edbone;
2147
2147
arm->act_edbone= ebo->temp;
2150
2150
arm->act_edbone= NULL;
2152
2152
/* set pointers */
2153
for(newebo= arm->edbo->first; newebo; newebo= newebo->next) {
2154
if(newebo->parent) newebo->parent= newebo->parent->temp;
2153
for (newebo= arm->edbo->first; newebo; newebo= newebo->next) {
2154
if (newebo->parent) newebo->parent= newebo->parent->temp;
2156
/* be sure they dont hang ever */
2157
for(newebo= arm->edbo->first; newebo; newebo= newebo->next) {
2156
/* be sure they don't hang ever */
2157
for (newebo= arm->edbo->first; newebo; newebo= newebo->next) {
2158
2158
newebo->temp= NULL;
2162
static void *editBones_to_undoBones(void *armv)
2162
static void *editBones_to_undoBones(void *armv, void *UNUSED(obdata))
2164
2164
bArmature *arm= armv;
2165
2165
UndoArmature *uarm;
2168
2168
uarm= MEM_callocN(sizeof(UndoArmature), "listbase undo");
2171
for(ebo= arm->edbo->first; ebo; ebo= ebo->next) {
2171
for (ebo= arm->edbo->first; ebo; ebo= ebo->next) {
2172
2172
newebo= MEM_dupallocN(ebo);
2173
2173
ebo->temp= newebo;
2174
2174
BLI_addtail(&uarm->lb, newebo);
2177
2177
/* active bone */
2178
if(arm->act_edbone) {
2178
if (arm->act_edbone) {
2179
2179
ebo= arm->act_edbone;
2180
2180
uarm->act_edbone= ebo->temp;
2183
2183
/* set pointers */
2184
for(newebo= uarm->lb.first; newebo; newebo= newebo->next) {
2185
if(newebo->parent) newebo->parent= newebo->parent->temp;
2184
for (newebo= uarm->lb.first; newebo; newebo= newebo->next) {
2185
if (newebo->parent) newebo->parent= newebo->parent->temp;
2375
2375
static int armature_click_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
2377
2377
/* TODO most of this code is copied from set3dcursor_invoke,
2378
it would be better to reuse code in set3dcursor_invoke */
2378
* it would be better to reuse code in set3dcursor_invoke */
2380
2380
/* temporarily change 3d cursor position */
2408
2408
void ARMATURE_OT_click_extrude(wmOperatorType *ot)
2410
2410
/* identifiers */
2411
ot->name= "Click-Extrude";
2412
ot->idname= "ARMATURE_OT_click_extrude";
2413
ot->description= "Create a new bone going from the last selected joint to the mouse position";
2411
ot->name = "Click-Extrude";
2412
ot->idname = "ARMATURE_OT_click_extrude";
2413
ot->description = "Create a new bone going from the last selected joint to the mouse position";
2415
2415
/* api callbacks */
2416
2416
ot->invoke = armature_click_extrude_invoke;
2542
2541
BLI_addtail(editbones, eBone);
2544
2543
/* copy the ID property */
2546
2545
eBone->prop= IDP_CopyProperty(curBone->prop);
2548
2547
/* Lets duplicate the list of constraints that the
2677
2676
void ARMATURE_OT_duplicate(wmOperatorType *ot)
2679
2678
/* identifiers */
2680
ot->name= "Duplicate Selected Bone(s)";
2681
ot->idname= "ARMATURE_OT_duplicate";
2682
ot->description= "Make copies of the selected bones within the same armature";
2679
ot->name = "Duplicate Selected Bone(s)";
2680
ot->idname = "ARMATURE_OT_duplicate";
2681
ot->description = "Make copies of the selected bones within the same armature";
2684
2683
/* api callbacks */
2685
2684
ot->exec = armature_duplicate_selected_exec;
2686
2685
ot->poll = ED_operator_editarmature;
2689
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
2688
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
2936
2935
// FIXME.. figure out a method for multiple bones
2937
BKE_reportf(op->reports, RPT_ERROR, "Too many points selected: %d \n", count);
2936
BKE_reportf(op->reports, RPT_ERROR, "Too many points selected: %d\n", count);
2938
2937
BLI_freelistN(&points);
2939
2938
return OPERATOR_CANCELLED;
2951
2950
void ARMATURE_OT_fill (wmOperatorType *ot)
2953
2952
/* identifiers */
2954
ot->name= "Fill Between Joints";
2955
ot->idname= "ARMATURE_OT_fill";
2956
ot->description= "Add bone between selected joint(s) and/or 3D-Cursor";
2953
ot->name = "Fill Between Joints";
2954
ot->idname = "ARMATURE_OT_fill";
2955
ot->description = "Add bone between selected joint(s) and/or 3D-Cursor";
2958
2957
/* callbacks */
2959
ot->exec= armature_fill_bones_exec;
2960
ot->poll= ED_operator_editarmature;
2958
ot->exec = armature_fill_bones_exec;
2959
ot->poll = ED_operator_editarmature;
2963
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
2962
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
2966
2965
/* --------------------- */
2978
2977
/* check if same bone */
2979
2978
if (start == end) {
2980
if (G.f & G_DEBUG) {
2981
printf("Error: same bone! \n");
2982
printf("\tstart = %s, end = %s \n", start->name, end->name);
2979
if (G.debug & G_DEBUG) {
2980
printf("Error: same bone!\n");
2981
printf("\tstart = %s, end = %s\n", start->name, end->name);
3056
3055
short type= RNA_enum_get(op->ptr, "type");
3058
3057
/* sanity checks */
3059
if ELEM(NULL, obedit, arm)
3058
if (ELEM(NULL, obedit, arm))
3060
3059
return OPERATOR_CANCELLED;
3062
3061
/* for now, there's only really one type of merging that's performed... */
3137
3136
/* identifiers */
3138
ot->name= "Merge Bones";
3139
ot->idname= "ARMATURE_OT_merge";
3140
ot->description= "Merge continuous chains of selected bones";
3137
ot->name = "Merge Bones";
3138
ot->idname = "ARMATURE_OT_merge";
3139
ot->description = "Merge continuous chains of selected bones";
3142
3141
/* callbacks */
3143
ot->invoke= WM_menu_invoke;
3144
ot->exec= armature_merge_exec;
3145
ot->poll= ED_operator_editarmature;
3142
ot->invoke = WM_menu_invoke;
3143
ot->exec = armature_merge_exec;
3144
ot->poll = ED_operator_editarmature;
3148
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
3147
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
3150
3149
/* properties */
3151
ot->prop= RNA_def_enum(ot->srna, "type", merge_types, 0, "Type", "");
3150
ot->prop = RNA_def_enum(ot->srna, "type", merge_types, 0, "Type", "");
3154
3153
/* ************** END Add/Remove stuff in editmode ************ */
3184
3183
void ARMATURE_OT_hide(wmOperatorType *ot)
3186
3185
/* identifiers */
3187
ot->name= "Hide Selected Bones";
3188
ot->idname= "ARMATURE_OT_hide";
3189
ot->description= "Tag selected bones to not be visible in Edit Mode";
3186
ot->name = "Hide Selected Bones";
3187
ot->idname = "ARMATURE_OT_hide";
3188
ot->description = "Tag selected bones to not be visible in Edit Mode";
3191
3190
/* api callbacks */
3192
ot->exec= armature_hide_exec;
3193
ot->poll= ED_operator_editarmature;
3191
ot->exec = armature_hide_exec;
3192
ot->poll = ED_operator_editarmature;
3196
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
3195
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
3199
3198
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected");
3206
3205
EditBone *ebone;
3208
3207
for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
3209
if(arm->layer & ebone->layer) {
3208
if (arm->layer & ebone->layer) {
3210
3209
if (ebone->flag & BONE_HIDDEN_A) {
3211
3210
ebone->flag |= (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
3212
3211
ebone->flag &= ~BONE_HIDDEN_A;
3224
3223
void ARMATURE_OT_reveal(wmOperatorType *ot)
3226
3225
/* identifiers */
3227
ot->name= "Reveal Bones";
3228
ot->idname= "ARMATURE_OT_reveal";
3229
ot->description= "Unhide all bones that have been tagged to be hidden in Edit Mode";
3226
ot->name = "Reveal Bones";
3227
ot->idname = "ARMATURE_OT_reveal";
3228
ot->description = "Unhide all bones that have been tagged to be hidden in Edit Mode";
3231
3230
/* api callbacks */
3232
ot->exec= armature_reveal_exec;
3233
ot->poll= ED_operator_editarmature;
3231
ot->exec = armature_reveal_exec;
3232
ot->poll = ED_operator_editarmature;
3236
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
3235
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
3239
3238
#if 0 // remove this?
3282
3281
EditBone *ebone;
3284
3283
for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
3285
if(arm->layer & ebone->layer) {
3284
if (arm->layer & ebone->layer) {
3286
3285
if (ebone->flag & BONE_HIDDEN_A) {
3287
3286
ebone->flag |= (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
3288
3287
ebone->flag &= ~BONE_HIDDEN_A;
3387
3386
newbone->zwidth= ebone->zwidth;
3388
3387
newbone->ease1= ebone->ease1;
3389
3388
newbone->ease2= ebone->ease2;
3390
newbone->rad_head= ebone->rad_tail; // dont copy entire bone...
3389
newbone->rad_head= ebone->rad_tail; // don't copy entire bone...
3391
3390
newbone->rad_tail= ebone->rad_tail;
3392
3391
newbone->segments= 1;
3393
3392
newbone->layer= ebone->layer;
3433
3432
void ARMATURE_OT_extrude(wmOperatorType *ot)
3435
3434
/* identifiers */
3436
ot->name= "Extrude";
3437
ot->idname= "ARMATURE_OT_extrude";
3438
ot->description= "Create new bones from the selected joints";
3435
ot->name = "Extrude";
3436
ot->idname = "ARMATURE_OT_extrude";
3437
ot->description = "Create new bones from the selected joints";
3440
3439
/* api callbacks */
3441
ot->exec= armature_extrude_exec;
3442
ot->poll= ED_operator_editarmature;
3440
ot->exec = armature_extrude_exec;
3441
ot->poll = ED_operator_editarmature;
3445
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
3444
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
3448
3447
RNA_def_boolean(ot->srna, "forked", 0, "Forked", "");
3483
3482
copy_v3_v3(bone->head, curs);
3485
if(rv3d && (U.flag & USER_ADD_VIEWALIGNED))
3484
if (rv3d && (U.flag & USER_ADD_VIEWALIGNED))
3486
3485
add_v3_v3v3(bone->tail, bone->head, imat[1]); // bone with unit length 1
3488
3487
add_v3_v3v3(bone->tail, bone->head, imat[2]); // bone with unit length 1, pointing up Z
3496
3495
void ARMATURE_OT_bone_primitive_add(wmOperatorType *ot)
3498
3497
/* identifiers */
3499
ot->name= "Add Bone";
3500
ot->idname= "ARMATURE_OT_bone_primitive_add";
3501
ot->description= "Add a new bone located at the 3D-Cursor";
3498
ot->name = "Add Bone";
3499
ot->idname = "ARMATURE_OT_bone_primitive_add";
3500
ot->description = "Add a new bone located at the 3D-Cursor";
3503
3502
/* api callbacks */
3504
3503
ot->exec = armature_bone_primitive_add_exec;
3505
3504
ot->poll = ED_operator_editarmature;
3508
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
3507
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
3510
3509
RNA_def_string(ot->srna, "name", "Bone", MAXBONENAME, "Name", "Name of the newly created bone");
3586
3585
void ARMATURE_OT_subdivide(wmOperatorType *ot)
3588
3589
/* identifiers */
3589
ot->name= "Subdivide Multi";
3590
ot->idname= "ARMATURE_OT_subdivide";
3591
ot->description= "Break selected bones into chains of smaller bones";
3590
ot->name = "Subdivide Multi";
3591
ot->idname = "ARMATURE_OT_subdivide";
3592
ot->description = "Break selected bones into chains of smaller bones";
3593
3594
/* api callbacks */
3594
3595
ot->exec = armature_subdivide_exec;
3595
3596
ot->poll = ED_operator_editarmature;
3598
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
3599
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
3600
3601
/* Properties */
3601
RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10);
3602
prop = RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10);
3603
/* avoid re-using last var because it can cause _very_ high poly meshes and annoy users (or worse crash) */
3604
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
3604
3607
/* ----------- */
3606
3609
/* Switch Direction operator:
3607
3610
* Currently, this does not use context loops, as context loops do not make it
3608
* easy to retrieve any hierarchial/chain relationships which are necessary for
3611
* easy to retrieve any hierarchical/chain relationships which are necessary for
3609
3612
* this to be done easily.
3688
3691
void ARMATURE_OT_switch_direction(wmOperatorType *ot)
3690
3693
/* identifiers */
3691
ot->name= "Switch Direction";
3692
ot->idname= "ARMATURE_OT_switch_direction";
3693
ot->description= "Change the direction that a chain of bones points in (head <-> tail swap)";
3694
ot->name = "Switch Direction";
3695
ot->idname = "ARMATURE_OT_switch_direction";
3696
ot->description = "Change the direction that a chain of bones points in (head <-> tail swap)";
3695
3698
/* api callbacks */
3696
3699
ot->exec = armature_switch_direction_exec;
3697
3700
ot->poll = ED_operator_editarmature;
3700
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
3703
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
3702
3705
/* ***************** Parenting *********************** */
3783
3786
else if (arm->flag & ARM_MIRROR_EDIT) {
3784
3787
/* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
3785
3788
* - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
3786
* (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
3787
* This is useful for arm-chains, for example parenting lower arm to upper arm
3789
* (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
3790
* This is useful for arm-chains, for example parenting lower arm to upper arm
3788
3791
* - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
3789
* then just use actbone. Useful when doing upper arm to spine.
3792
* then just use actbone. Useful when doing upper arm to spine.
3791
3794
actmirb= ED_armature_bone_get_mirrored(arm->edbo, actbone);
3792
3795
if (actmirb == NULL)
3812
3815
* - the context iterator contains both selected bones and their mirrored copies,
3813
3816
* so we assume that unselected bones are mirrored copies of some selected bone
3814
3817
* - since the active one (and/or its mirror) will also be selected, we also need
3815
* to check that we are not trying to opearate on them, since such an operation
3818
* to check that we are not trying to operate on them, since such an operation
3816
3819
* would cause errors
3863
3866
void ARMATURE_OT_parent_set(wmOperatorType *ot)
3865
3868
/* identifiers */
3866
ot->name= "Make Parent";
3867
ot->idname= "ARMATURE_OT_parent_set";
3868
ot->description= "Set the active bone as the parent of the selected bones";
3869
ot->name = "Make Parent";
3870
ot->idname = "ARMATURE_OT_parent_set";
3871
ot->description = "Set the active bone as the parent of the selected bones";
3870
3873
/* api callbacks */
3871
3874
ot->invoke = armature_parent_set_invoke;
3873
3876
ot->poll = ED_operator_editarmature;
3876
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
3879
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
3878
3881
RNA_def_enum(ot->srna, "type", prop_editarm_make_parent_types, 0, "ParentType", "Type of parenting");
3917
3920
void ARMATURE_OT_parent_clear(wmOperatorType *ot)
3919
3922
/* identifiers */
3920
ot->name= "Clear Parent";
3921
ot->idname= "ARMATURE_OT_parent_clear";
3922
ot->description= "Remove the parent-child relationship between selected bones and their parents";
3923
ot->name = "Clear Parent";
3924
ot->idname = "ARMATURE_OT_parent_clear";
3925
ot->description = "Remove the parent-child relationship between selected bones and their parents";
3924
3927
/* api callbacks */
3925
3928
ot->invoke = WM_menu_invoke;
3927
3930
ot->poll = ED_operator_editarmature;
3930
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
3933
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
3932
ot->prop= RNA_def_enum(ot->srna, "type", prop_editarm_clear_parent_types, 0, "ClearType", "What way to clear parenting");
3935
ot->prop = RNA_def_enum(ot->srna, "type", prop_editarm_clear_parent_types, 0, "ClearType", "What way to clear parenting");
3935
3938
/* **************** Selections ******************/
3954
3957
void ARMATURE_OT_select_inverse(wmOperatorType *ot)
3956
3959
/* identifiers */
3957
ot->name= "Select Inverse";
3958
ot->idname= "ARMATURE_OT_select_inverse";
3959
ot->description= "Flip the selection status of bones (selected -> unselected, unselected -> selected)";
3960
ot->name = "Select Inverse";
3961
ot->idname = "ARMATURE_OT_select_inverse";
3962
ot->description = "Flip the selection status of bones (selected -> unselected, unselected -> selected)";
3961
3964
/* api callbacks */
3962
ot->exec= armature_select_inverse_exec;
3963
ot->poll= ED_operator_editarmature;
3965
ot->exec = armature_select_inverse_exec;
3966
ot->poll = ED_operator_editarmature;
3966
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
3969
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
3969
3972
static int armature_de_select_all_exec(bContext *C, wmOperator *op)
3973
3976
if (action == SEL_TOGGLE) {
3974
3977
action = SEL_SELECT;
3975
/* Determine if there are any selected bones
3976
And therefore whether we are selecting or deselecting */
3978
/* Determine if there are any selected bones
3979
* And therefore whether we are selecting or deselecting */
3977
3980
if (CTX_DATA_COUNT(C, selected_bones) > 0)
3978
3981
action = SEL_DESELECT;
4014
4017
void ARMATURE_OT_select_all(wmOperatorType *ot)
4016
4019
/* identifiers */
4017
ot->name= "Select or Deselect All";
4018
ot->idname= "ARMATURE_OT_select_all";
4019
ot->description= "Toggle selection status of all bones";
4020
ot->name = "(De)select All";
4021
ot->idname = "ARMATURE_OT_select_all";
4022
ot->description = "Toggle selection status of all bones";
4021
4024
/* api callbacks */
4022
ot->exec= armature_de_select_all_exec;
4023
ot->poll= ED_operator_editarmature;
4025
ot->exec = armature_de_select_all_exec;
4026
ot->poll = ED_operator_editarmature;
4026
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
4029
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
4028
4031
WM_operator_properties_select_all(ot);
4097
4100
/* identifiers */
4098
ot->name= "Select Hierarchy";
4099
ot->idname= "ARMATURE_OT_select_hierarchy";
4100
ot->description= "Select immediate parent/children of selected bones";
4101
ot->name = "Select Hierarchy";
4102
ot->idname = "ARMATURE_OT_select_hierarchy";
4103
ot->description = "Select immediate parent/children of selected bones";
4102
4105
/* api callbacks */
4103
ot->exec= armature_select_hierarchy_exec;
4104
ot->poll= ED_operator_editarmature;
4106
ot->exec = armature_select_hierarchy_exec;
4107
ot->poll = ED_operator_editarmature;
4107
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
4110
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
4110
4113
RNA_def_enum(ot->srna, "direction", direction_items,
4158
4161
selbone->roll = actbone->roll;
4160
4163
/* if the bone being aligned has connected descendants they must be moved
4161
according to their parent new position, otherwise they would be left
4162
in an unconsistent state: connected but away from the parent*/
4164
* according to their parent new position, otherwise they would be left
4165
* in an inconsistent state: connected but away from the parent*/
4163
4166
fix_editbone_connected_children(edbo, selbone);
4179
4182
else if (arm->flag & ARM_MIRROR_EDIT) {
4180
4183
/* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
4181
4184
* - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone
4182
* (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
4183
* This is useful for arm-chains, for example parenting lower arm to upper arm
4185
* (i.e. selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
4186
* This is useful for arm-chains, for example parenting lower arm to upper arm
4184
4187
* - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
4185
* then just use actbone. Useful when doing upper arm to spine.
4188
* then just use actbone. Useful when doing upper arm to spine.
4187
4190
actmirb= ED_armature_bone_get_mirrored(arm->edbo, actbone);
4188
4191
if (actmirb == NULL)
4208
4211
* - the context iterator contains both selected bones and their mirrored copies,
4209
4212
* so we assume that unselected bones are mirrored copies of some selected bone
4210
4213
* - since the active one (and/or its mirror) will also be selected, we also need
4211
* to check that we are not trying to opearate on them, since such an operation
4212
* would cause errors
4214
* to check that we are not trying to operate on them, since such an operation
4215
* would cause errors
4215
4218
/* align selected bones to the active one */
4234
4237
void ARMATURE_OT_align(wmOperatorType *ot)
4236
4239
/* identifiers */
4237
ot->name= "Align Bones";
4238
ot->idname= "ARMATURE_OT_align";
4239
ot->description= "Align selected bones to the active bone (or to their parent)";
4240
ot->name = "Align Bones";
4241
ot->idname = "ARMATURE_OT_align";
4242
ot->description = "Align selected bones to the active bone (or to their parent)";
4241
4244
/* api callbacks */
4242
4245
ot->invoke = WM_operator_confirm;
4254
4257
int (*bone_func)(Object *, Bone *, void *))
4256
4259
/* We want to apply the function bone_func to every bone
4257
* in an armature -- feed bone_looper the first bone and
4258
* a pointer to the bone_func and watch it go!. The int count
4259
* can be useful for counting bones with a certain property
4260
* in an armature -- feed bone_looper the first bone and
4261
* a pointer to the bone_func and watch it go!. The int count
4262
* can be useful for counting bones with a certain property
4269
4272
count += bone_looper(ob, bone->childbase.first, data, bone_func);
4271
4274
/* try to execute bone_func for the next bone at this
4272
* depth of the recursion.
4275
* depth of the recursion.
4274
4277
count += bone_looper(ob, bone->next, data, bone_func);
4297
4300
* armature object was not active yet.
4298
4301
* note, special exception for armature mode so we can do multi-select
4299
4302
* we could check for multi-select explicitly but think its fine to
4300
* always give pradictable behavior in weight paint mode - campbell */
4303
* always give predictable behavior in weight paint mode - campbell */
4301
4304
if (!extend || ((ob_act && (ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT)==0))) {
4302
4305
ED_pose_deselectall(ob, 0);
4303
4306
nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
4310
4313
if (nearBone->flag & BONE_SELECTED) {
4311
4314
/* if not active, we make it active */
4312
if(nearBone != arm->act_bone) {
4315
if (nearBone != arm->act_bone) {
4313
4316
arm->act_bone= nearBone;
4344
4347
/* test==0: deselect all
4345
test==1: swap select (apply to all the opposite of current situation)
4346
test==2: only clear active tag
4347
test==3: swap select (no test / inverse selection status of all independently)
4348
* test==1: swap select (apply to all the opposite of current situation)
4349
* test==2: only clear active tag
4350
* test==3: swap select (no test / inverse selection status of all independently)
4349
4352
void ED_pose_deselectall (Object *ob, int test)
4351
4354
bArmature *arm= ob->data;
4413
4416
int a, segments;
4414
4417
struct { Object *armob; void *list; int heat; } *data = datap;
4416
if(!(ob->mode & OB_MODE_WEIGHT_PAINT) || !(bone->flag & BONE_HIDDEN_P)) {
4419
if (!(ob->mode & OB_MODE_WEIGHT_PAINT) || !(bone->flag & BONE_HIDDEN_P)) {
4417
4420
if (!(bone->flag & BONE_NO_DEFORM)) {
4418
4421
if (data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
4419
4422
segments = bone->segments;
4437
4440
static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
4439
4442
/* This group creates a vertex group to ob that has the
4440
* same name as bone (provided the bone is skinnable).
4443
* same name as bone (provided the bone is skinnable).
4441
4444
* If such a vertex group aleady exist the routine exits.
4443
4446
if (!(bone->flag & BONE_NO_DEFORM)) {
4444
4447
if (!defgroup_find_name(ob,bone->name)) {
4445
4448
ED_vgroup_add_name(ob, bone->name);
4490
if(!wpmode || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED)))
4493
if (!wpmode || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED)))
4491
4494
if (!(defgroup = defgroup_find_name(ob, bone->name)))
4492
4495
defgroup = ED_vgroup_add_name(ob, bone->name);
4508
static void add_vgroups__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
4511
static void add_vgroups__mapFunc(void *userData, int index, const float co[3],
4512
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
4510
4514
/* DerivedMesh mapFunc for getting final coords in weight paint mode */
4689
4693
else if (modifiers_findByType(ob, eModifierType_Subsurf)) {
4690
4694
/* is subsurf on? Lets use the verts on the limit surface then.
4691
* = same amount of vertices as mesh, but vertices moved to the
4695
* = same amount of vertices as mesh, but vertices moved to the
4692
4696
* subsurfed position, like for 'optimal'. */
4693
4697
subsurf_calculate_limit_positions(mesh, verts);
4694
4698
vertsfilled = 1;
4707
4711
heat_bone_weighting(ob, mesh, verts, numbones, dgrouplist, dgroupflip,
4708
4712
root, tip, selected, &error);
4711
4715
BKE_report(reports, RPT_WARNING, error);
4737
4741
bArmature *arm= par->data;
4739
if(mode == ARM_GROUPS_NAME) {
4743
if (mode == ARM_GROUPS_NAME) {
4740
4744
/* Traverse the bone list, trying to create empty vertex
4741
* groups cooresponding to the bone.
4745
* groups corresponding to the bone.
4743
4747
bone_looper(ob, arm->bonebase.first, NULL, vgroup_add_unique_bone_cb);
4745
4749
if (ob->type == OB_MESH)
4746
4750
ED_vgroup_data_create(ob->data);
4748
else if(mode == ARM_GROUPS_ENVELOPE || mode == ARM_GROUPS_AUTO) {
4752
else if (mode == ARM_GROUPS_ENVELOPE || mode == ARM_GROUPS_AUTO) {
4749
4753
/* Traverse the bone list, trying to create vertex groups
4750
4754
* that are populated with the vertices for which the
4751
4755
* bone is closest.
4895
4899
short autokey = 0;
4897
4901
/* sanity checks */
4898
if ELEM(NULL, clear_func, default_ksName) {
4902
if (ELEM(NULL, clear_func, default_ksName)) {
4899
4903
BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name");
4900
4904
return OPERATOR_CANCELLED;
4954
4958
void POSE_OT_scale_clear(wmOperatorType *ot)
4956
4960
/* identifiers */
4957
ot->name= "Clear Pose Scale";
4958
ot->idname= "POSE_OT_scale_clear";
4961
ot->name = "Clear Pose Scale";
4962
ot->idname = "POSE_OT_scale_clear";
4959
4963
ot->description = "Reset scaling of selected bones to their default values";
4961
4965
/* api callbacks */
4975
4979
void POSE_OT_rot_clear(wmOperatorType *ot)
4977
4981
/* identifiers */
4978
ot->name= "Clear Pose Rotation";
4979
ot->idname= "POSE_OT_rot_clear";
4982
ot->name = "Clear Pose Rotation";
4983
ot->idname = "POSE_OT_rot_clear";
4980
4984
ot->description = "Reset rotations of selected bones to their default values";
4982
4986
/* api callbacks */
4996
5000
void POSE_OT_loc_clear(wmOperatorType *ot)
4998
5002
/* identifiers */
4999
ot->name= "Clear Pose Location";
5000
ot->idname= "POSE_OT_loc_clear";
5003
ot->name = "Clear Pose Location";
5004
ot->idname = "POSE_OT_loc_clear";
5001
5005
ot->description = "Reset locations of selected bones to their default values";
5003
5007
/* api callbacks */
5017
5021
void POSE_OT_transforms_clear(wmOperatorType *ot)
5019
5023
/* identifiers */
5020
ot->name= "Clear Pose Transforms";
5021
ot->idname= "POSE_OT_transforms_clear";
5024
ot->name = "Clear Pose Transforms";
5025
ot->idname = "POSE_OT_transforms_clear";
5022
5026
ot->description = "Reset location, rotation, and scaling of selected bones to their default values";
5024
5028
/* api callbacks */
5078
5082
void POSE_OT_select_all(wmOperatorType *ot)
5080
5084
/* identifiers */
5081
ot->name= "Select or Deselect All";
5082
ot->idname= "POSE_OT_select_all";
5083
ot->description= "Toggle selection status of all bones";
5085
ot->name = "(De)select All";
5086
ot->idname = "POSE_OT_select_all";
5087
ot->description = "Toggle selection status of all bones";
5085
5089
/* api callbacks */
5086
ot->exec= pose_de_select_all_exec;
5087
ot->poll= ED_operator_posemode;
5090
ot->exec = pose_de_select_all_exec;
5091
ot->poll = ED_operator_posemode;
5090
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
5094
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
5092
5096
WM_operator_properties_select_all(ot);
5122
5126
void POSE_OT_select_parent(wmOperatorType *ot)
5124
5128
/* identifiers */
5125
ot->name= "Select Parent Bone";
5126
ot->idname= "POSE_OT_select_parent";
5127
ot->description= "Select bones that are parents of the currently selected bones";
5129
ot->name = "Select Parent Bone";
5130
ot->idname = "POSE_OT_select_parent";
5131
ot->description = "Select bones that are parents of the currently selected bones";
5129
5133
/* api callbacks */
5130
ot->exec= pose_select_parent_exec;
5131
ot->poll= ED_operator_posemode;
5134
ot->exec = pose_select_parent_exec;
5135
ot->poll = ED_operator_posemode;
5134
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
5138
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
5173
5177
Object *ob= object_pose_armature_get(CTX_data_active_object(C));
5174
5178
bArmature *arm= ob->data;
5176
if(RNA_boolean_get(op->ptr, "unselected"))
5180
if (RNA_boolean_get(op->ptr, "unselected"))
5177
5181
bone_looper(ob, arm->bonebase.first, NULL, hide_unselected_pose_bone_cb);
5179
5183
bone_looper(ob, arm->bonebase.first, NULL, hide_selected_pose_bone_cb);
5187
5191
void POSE_OT_hide(wmOperatorType *ot)
5189
5193
/* identifiers */
5190
ot->name= "Hide Selected";
5191
ot->idname= "POSE_OT_hide";
5192
ot->description= "Tag selected bones to not be visible in Pose Mode";
5194
ot->name = "Hide Selected";
5195
ot->idname = "POSE_OT_hide";
5196
ot->description = "Tag selected bones to not be visible in Pose Mode";
5194
5198
/* api callbacks */
5195
ot->exec= pose_hide_exec;
5196
ot->poll= ED_operator_posemode;
5199
ot->exec = pose_hide_exec;
5200
ot->poll = ED_operator_posemode;
5199
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
5203
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
5202
5206
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "");
5233
5237
void POSE_OT_reveal(wmOperatorType *ot)
5235
5239
/* identifiers */
5236
ot->name= "Reveal Selected";
5237
ot->idname= "POSE_OT_reveal";
5238
ot->description= "Unhide all bones that have been tagged to be hidden in Pose Mode";
5240
ot->name = "Reveal Selected";
5241
ot->idname = "POSE_OT_reveal";
5242
ot->description = "Unhide all bones that have been tagged to be hidden in Pose Mode";
5240
5244
/* api callbacks */
5241
ot->exec= pose_reveal_exec;
5242
ot->poll= ED_operator_posemode;
5245
ot->exec = pose_reveal_exec;
5246
ot->poll = ED_operator_posemode;
5245
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
5249
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
5248
5252
/* ************* RENAMING DISASTERS ************ */
5293
5297
char oldname[MAXBONENAME];
5295
5299
/* names better differ! */
5296
if(strncmp(oldnamep, newnamep, MAXBONENAME)) {
5300
if (strncmp(oldnamep, newnamep, MAXBONENAME)) {
5298
5302
/* we alter newname string... so make copy */
5299
5303
BLI_strncpy(newname, newnamep, MAXBONENAME);
5369
5373
if (modifiers_usesArmature(ob, arm)) {
5370
5374
bDeformGroup *dg= defgroup_find_name(ob, oldname);
5372
5376
BLI_strncpy(dg->name, newname, MAXBONENAME);
5390
5394
/* Fix all animdata that may refer to this bone - we can't just do the ones attached to objects, since
5391
5395
* other ID-blocks may have drivers referring to this bone [#29822]
5393
BKE_all_animdata_fix_paths_rename("pose.bones", oldname, newname);
5399
BKE_all_animdata_fix_paths_rename(&arm->id, "pose.bones", oldname, newname);
5395
5402
/* correct view locking */
5397
5404
bScreen *screen;
5398
for(screen= G.main->screen.first; screen; screen= screen->id.next) {
5405
for (screen= G.main->screen.first; screen; screen= screen->id.next) {
5400
5407
/* add regions */
5401
for(sa= screen->areabase.first; sa; sa= sa->next) {
5408
for (sa= screen->areabase.first; sa; sa= sa->next) {
5403
5410
for (sl= sa->spacedata.first; sl; sl= sl->next) {
5404
if(sl->spacetype==SPACE_VIEW3D) {
5411
if (sl->spacetype==SPACE_VIEW3D) {
5405
5412
View3D *v3d= (View3D *)sl;
5406
if(v3d->ob_centre && v3d->ob_centre->data == arm) {
5413
if (v3d->ob_centre && v3d->ob_centre->data == arm) {
5407
5414
if (!strcmp(v3d->ob_centre_bone, oldname)) {
5408
5415
BLI_strncpy(v3d->ob_centre_bone, newname, MAXBONENAME);
5448
5455
void ARMATURE_OT_flip_names (wmOperatorType *ot)
5450
5457
/* identifiers */
5451
ot->name= "Flip Names";
5452
ot->idname= "ARMATURE_OT_flip_names";
5453
ot->description= "Flips (and corrects) the axis suffixes of the names of selected bones";
5458
ot->name = "Flip Names";
5459
ot->idname = "ARMATURE_OT_flip_names";
5460
ot->description = "Flips (and corrects) the axis suffixes of the names of selected bones";
5455
5462
/* api callbacks */
5456
ot->exec= armature_flip_names_exec;
5457
ot->poll= ED_operator_editarmature;
5463
ot->exec = armature_flip_names_exec;
5464
ot->poll = ED_operator_editarmature;
5460
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
5467
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
5477
5484
CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
5479
5486
BLI_strncpy(newname, ebone->name, sizeof(newname));
5480
if(bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]))
5487
if (bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]))
5481
5488
ED_armature_bone_rename(arm, ebone->name, newname);
5500
5507
{0, NULL, 0, NULL, NULL}};
5502
5509
/* identifiers */
5503
ot->name= "AutoName by Axis";
5504
ot->idname= "ARMATURE_OT_autoside_names";
5505
ot->description= "Automatically renames the selected bones according to which side of the target axis they fall on";
5510
ot->name = "AutoName by Axis";
5511
ot->idname = "ARMATURE_OT_autoside_names";
5512
ot->description = "Automatically renames the selected bones according to which side of the target axis they fall on";
5507
5514
/* api callbacks */
5508
ot->invoke= WM_menu_invoke;
5509
ot->exec= armature_autoside_names_exec;
5510
ot->poll= ED_operator_editarmature;
5515
ot->invoke = WM_menu_invoke;
5516
ot->exec = armature_autoside_names_exec;
5517
ot->poll = ED_operator_editarmature;
5513
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
5520
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
5516
ot->prop= RNA_def_enum(ot->srna, "type", axis_items, 0, "Axis", "Axis tag names with");
5523
ot->prop = RNA_def_enum(ot->srna, "type", axis_items, 0, "Axis", "Axis tag names with");
5557
5564
eboflip->roll= -ebo->roll;
5559
5566
/* Also move connected parent, in case parent's name isn't mirrored properly */
5560
if (eboflip->parent && eboflip->flag & BONE_CONNECTED)
5567
if (eboflip->parent && eboflip->flag & BONE_CONNECTED) {
5562
5568
EditBone *parent = eboflip->parent;
5563
5569
copy_v3_v3(parent->tail, eboflip->head);
5564
5570
parent->rad_tail = ebo->rad_head;
5589
5595
bArmature *arm= obedit->data;
5590
5596
EditBone *lastBone = NULL;
5592
if (scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE)
5598
if (scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE) {
5594
5599
ReebArcIterator arc_iter;
5595
5600
BArcIterator *iter = (BArcIterator*)&arc_iter;
5596
5601
float *previous = NULL, *current = NULL;
5624
5629
len1 = normalize_v3(vec1);
5625
5630
len2 = normalize_v3(vec2);
5627
if (len1 > 0.0f && len2 > 0.0f && dot_v3v3(vec1, vec2) < angleLimit)
5632
if (len1 > 0.0f && len2 > 0.0f && dot_v3v3(vec1, vec2) < angleLimit) {
5629
5633
copy_v3_v3(parent->tail, previous);
5631
5635
child = ED_armature_edit_bone_add(arm, "Bone");
5641
5645
/* If the bone wasn't subdivided, delete it and return NULL
5642
5646
* to let subsequent subdivision methods do their thing.
5646
if(parent==arm->act_edbone) arm->act_edbone= NULL;
5648
if (parent == root) {
5649
if (parent==arm->act_edbone) arm->act_edbone= NULL;
5647
5650
ED_armature_edit_bone_remove(arm, parent);
5659
5662
EditBone *lastBone = NULL;
5661
if (scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION)
5664
if (scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION) {
5663
5665
float invmat[4][4]= MAT4_UNITY;
5664
5666
float tmat[3][3]= MAT3_UNITY;
5665
5667
ReebArcIterator arc_iter;
5683
5685
arcLength = len_v3v3(arc->head->p, arc->tail->p);
5685
if (arc->bcount > 0)
5687
if (arc->bcount > 0) {
5687
5688
/* Add the embedding */
5688
for ( i = 1; i < arc->bcount; i++)
5689
for ( i = 1; i < arc->bcount; i++) {
5690
5690
embedLength += len_v3v3(arc->buckets[i - 1].p, arc->buckets[i].p);
5692
5692
/* Add head and tail -> embedding vectors */
5693
5693
embedLength += len_v3v3(arc->head->p, arc->buckets[0].p);
5694
5694
embedLength += len_v3v3(arc->tail->p, arc->buckets[arc->bcount - 1].p);
5698
5697
embedLength = arcLength;
5772
5770
* Finally, the arc direction is stored in its flag: 1 (low -> high), -1 (high -> low)
5775
/* if arc is a symmetry axis, internal bones go up the tree */
5776
if (arc->symmetry_level == 1 && arc->tail->degree != 1)
5773
/* if arc is a symmetry axis, internal bones go up the tree */
5774
if (arc->symmetry_level == 1 && arc->tail->degree != 1) {
5778
5775
head = arc->tail;
5779
5776
tail = arc->head;
5781
5778
arc->flag = -1; /* mark arc direction */
5783
5780
/* Bones point AWAY from the symmetry axis */
5784
else if (arc->head->symmetry_level == 1)
5781
else if (arc->head->symmetry_level == 1) {
5786
5782
head = arc->head;
5787
5783
tail = arc->tail;
5789
5785
arc->flag = 1; /* mark arc direction */
5791
else if (arc->tail->symmetry_level == 1)
5787
else if (arc->tail->symmetry_level == 1) {
5793
5788
head = arc->tail;
5794
5789
tail = arc->head;
5796
5791
arc->flag = -1; /* mark arc direction */
5798
5793
/* otherwise, always go from low weight to high weight */
5801
5795
head = arc->head;
5802
5796
tail = arc->tail;
5807
5801
/* Loop over subdivision methods */
5808
for (i = 0; lastBone == NULL && i < SKGEN_SUB_TOTAL; i++)
5810
switch(scene->toolsettings->skgen_subdivisions[i])
5802
for (i = 0; lastBone == NULL && i < SKGEN_SUB_TOTAL; i++) {
5803
switch(scene->toolsettings->skgen_subdivisions[i]) {
5812
5804
case SKGEN_SUB_LENGTH:
5813
5805
lastBone = test_subdivideByLength(scene, obedit, arc, head, tail);
5843
5834
ReebArc *incomingArc = NULL;
5846
for (i = 0; i < node->degree; i++)
5837
for (i = 0; i < node->degree; i++) {
5848
5838
arc = (ReebArc*)node->arcs[i];
5850
5840
/* if arc is incoming into the node */
5851
if ((arc->head == node && arc->flag == -1) || (arc->tail == node && arc->flag == 1))
5841
if ((arc->head == node && arc->flag == -1) ||
5842
(arc->tail == node && arc->flag == 1))
5853
if (incomingArc == NULL)
5844
if (incomingArc == NULL) {
5855
5845
incomingArc = arc;
5856
5846
/* loop further to make sure there's only one incoming arc */
5860
5849
/* skip this node if more than one incomingArc */
5861
5850
incomingArc = NULL;
5862
5851
break; /* No need to look further, we are skipping already */
5874
5862
arc = node->arcs[i];
5876
5864
/* if arc is outgoing from the node */
5877
if ((arc->head == node && arc->flag == 1) || (arc->tail == node && arc->flag == -1))
5865
if ((arc->head == node && arc->flag == 1) || (arc->tail == node && arc->flag == -1)) {
5879
5866
EditBone *childBone = BLI_ghash_lookup(arcBoneMap, arc);
5881
5868
/* find the root bone */
5882
while(childBone->parent != NULL)
5869
while (childBone->parent != NULL)
5884
5871
childBone = childBone->parent;