EditMode armature: mirrored editing feature.
authorTon Roosendaal <ton@blender.org>
Mon, 15 Aug 2005 14:02:03 +0000 (14:02 +0000)
committerTon Roosendaal <ton@blender.org>
Mon, 15 Aug 2005 14:02:03 +0000 (14:02 +0000)
- Option is in EditButtons, Armature panel.
- Currently only local X-axis mirror (seems to be default anyway)
- Transform then applies changes to the mirrored-name bone as well.
- Extrude: also does the counterpart Bone
- New: SHIFT+E extrude: extrudes 2 mirrored Bones out of a normal Bone.
  (creating names by appening _L and _R)

Or in short: you can now model a full rig without any manual naming!
Of course the names are not too nice... a couple of ideas to explore;
- rename a mirrored bone renames counterpart too
- allow in weightpaint mode to select Bones
- and of course mirrored edit in PoseMode (if that's useful...)

Important note: I tweaked the naming convention a bit; names like
Bone_L.005 and Bone_R.005 are considered counterparts. However, if
you use the "Flip names" option, the number extension is still
truncated.

BTW: Commits in Zr's code are fixes for gcc warnings. :)

16 files changed:
source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/include/BIF_editarmature.h
source/blender/makesdna/DNA_armature_types.h
source/blender/src/buttons_editing.c
source/blender/src/editarmature.c
source/blender/src/editmesh_mods.c
source/blender/src/header_view3d.c
source/blender/src/poseobject.c
source/blender/src/space.c
source/blender/src/toolbox.c
source/blender/src/transform_generics.c

index 354b065773c10c5d47c5f204da3bf9a70bcee23a..7196a6098ff0d2bf40860fb0b02965bc8a381b5d 100644 (file)
@@ -72,7 +72,7 @@ void unlink_armature(struct bArmature *arm);
 void free_armature(struct bArmature *arm);
 void make_local_armature(struct bArmature *arm);
 struct bArmature *copy_armature(struct bArmature *arm);
-void bone_flip_name (char *name);
+void bone_flip_name (char *name, int strip_number);
 
 void calc_armature_deform (struct Object *ob, float *co, int index);
 
index e27a4277ffaa3d1e96ac82fd1f5afab4cc8037f5..6ed73192d563c733078ce39fb17e62e8d6368cce 100644 (file)
@@ -651,7 +651,7 @@ static void emDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *u
        EditVert *eve, *preveve;
        EditFace *efa;
        float cent[3];
-       int i;
+       int i=0;        // gcc!
 
        if (emdm->vertexCos) {
                for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
index 9268b48ccb2c26faff6fc9c2e81e6b4c60bd15c7..a3cdaa2ca2bbf4d27579ca137c3359eafff4329a 100644 (file)
@@ -264,13 +264,15 @@ static char *strcasestr_(register char *s, register char *find)
 
 #define IS_SEPARATOR(a)        (a=='.' || a==' ' || a=='-' || a=='_')
 
-/* finds the best possible flipped name, removing number extensions. For renaming; check for unique names afterwards */
-void bone_flip_name (char *name)
+/* finds the best possible flipped name. For renaming; check for unique names afterwards */
+/* if strip_number: removes number extensions */
+void bone_flip_name (char *name, int strip_number)
 {
        int             len;
        char    prefix[128]={""};       /* The part before the facing */
        char    suffix[128]={""};       /* The part after the facing */
        char    replace[128]={""};      /* The replacement string */
+       char    number[128]={""};       /* The number extension string */
        char    *index=NULL;
 
        len= strlen(name);
@@ -280,6 +282,8 @@ void bone_flip_name (char *name)
        if(isdigit(name[len-1])) {
                index= strrchr(name, '.');      // last occurrance
                if (index && isdigit(index[1]) ) {              // doesnt handle case bone.1abc2 correct..., whatever!
+                       if(strip_number==0) 
+                               strcpy(number, index);
                        *index= 0;
                        len= strlen(name);
                }
@@ -365,7 +369,7 @@ void bone_flip_name (char *name)
                }               
        }
 
-       sprintf (name, "%s%s%s", prefix, replace, suffix);
+       sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
 }
 
 
index 5a7883122447ae541801760aec3e2c746f4215c3..8a58fe88a85c7213b701c8d59e250e908807ed00 100644 (file)
@@ -1430,10 +1430,11 @@ int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
                        if(ob->pd && ob->pd->deflect) {
                                DerivedMesh *dm=NULL;                           
                                int dmNeedsFree;                                
-                               Mesh *me;
+                               Mesh *me= NULL;
                                DispListMesh  *disp_mesh = 0;
                                MFace *mface;
                    Object *copyob;
+                               
                                /* do object level stuff */
                                /* need to have user control for that since it depends on model scale */
                                innerfacethickness =-ob->pd->pdef_sbift;
index 55f62446bfd5b5c22a3754e4b32678465f185876..820e3ba4b0442ee3d66ca24c9a8280d6043cff00 100644 (file)
@@ -1161,8 +1161,6 @@ static void hookModifier_deformVerts(ModifierData *md, Object *ob, void *derived
 
 static void hookModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts)
 {
-       HookModifierData *hmd = (HookModifierData*) md;
-
        hookModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts);
 }
 
@@ -1170,8 +1168,6 @@ static void hookModifier_deformVertsEM(ModifierData *md, Object *ob, void *editD
 
 static void softbodyModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts)
 {
-       SoftbodyModifierData *hmd = (SoftbodyModifierData*) md;
-
        sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts);
 }
 
index 5c4a89ce76da3cac471883347f1a19d43673726e..1b20c92e81e0fd9a6f435385169c8417ed4cbf3a 100644 (file)
@@ -447,7 +447,6 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i
                }
 
                for (S=0; S<numVerts; S++) {
-                       VertData *gridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
                        int prevS= (S-1+numVerts)%numVerts;
 
                        for (y=0; y<gridSize-1; y++) {
@@ -1293,7 +1292,6 @@ static void ccgDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
        CCGSubSurf *ss = ccgdm->ss;
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
-       int gridSize = ccgSubSurf_getGridSize(ss);
 
        for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
index 77c6c5d446d4fae5a6eff92d481ce18c105d259b..ae5acf3071558c2f3adab8bd68441ea2c43379d1 100644 (file)
@@ -85,7 +85,7 @@ void  delete_armature(void);
 void   deselectall_armature(int toggle);
 void   deselectall_posearmature (struct Object *ob, int test);
 void   draw_armature(struct Base *base, int dt);
-void   extrude_armature(void);
+void   extrude_armature(int forked);
 void   free_editArmature(void);
 struct Bone *get_indexed_bone (struct Object *ob, int index);
 
@@ -125,7 +125,7 @@ int ik_chain_looper(Object *ob, struct Bone *bone, void *data,
 void undo_push_armature(char *name);
 void armature_bone_rename(struct bArmature *arm, char *oldname, char *newname);
 void armature_flip_names(void);
-
+EditBone *armature_bone_get_mirrored(EditBone *ebo);
 
 #define        BONESEL_ROOT    0x10000000
 #define        BONESEL_TIP             0x20000000
index 54b9e76d4a5faa579d66ec8b77945f913fa7761c..819b2843edaa07694bbdd53f15e2f0cd1ff6f2e0 100644 (file)
@@ -92,6 +92,7 @@ typedef struct bArmature {
 #define                ARM_EDITMODE    0x0020
 #define                ARM_DELAYDEFORM 0x0040
 #define                ARM_DONT_USE    0x0080
+#define                ARM_MIRROR_EDIT 0x0100
 
 /* armature->drawtype */
 
index 6f805a89a7e0257c28e0de08d73c10036462ec6b..018ba024dc85f488f4dc2c2cdae6cddfe4666767 100644 (file)
@@ -850,7 +850,6 @@ static void modifiers_cursorHookCenter(void *ob_v, void *md_v)
 
 static void modifiers_selectHook(void *ob_v, void *md_v)
 {
-       Object *ob = ob_v;
        ModifierData *md = md_v;
        HookModifierData *hmd = (HookModifierData*) md;
 
@@ -859,7 +858,6 @@ static void modifiers_selectHook(void *ob_v, void *md_v)
 
 static void modifiers_reassignHook(void *ob_v, void *md_v)
 {
-       Object *ob = ob_v;
        ModifierData *md = md_v;
        HookModifierData *hmd = (HookModifierData*) md;
        float cent[3];
@@ -897,12 +895,12 @@ static void modifiers_convertToReal(void *ob_v, void *md_v)
 static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco, int *yco, int index, int cageIndex, int lastCageIndex)
 {
        ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+       uiBut *but;
        int isVirtual = md->mode&eModifierMode_Virtual;
        int x = *xco, y = *yco, color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
        int editing = (G.obedit==ob);
-    short height, width = 295, buttonWidth = width-120-10;
+    short height=26, width = 295, buttonWidth = width-120-10;
        char str[128];
-       uiBut *but;
 
        if (isVirtual) {
                uiSetButLock(1, "Modifier is virtual and cannot be edited.");
@@ -2229,6 +2227,9 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm)
        uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 110,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
        uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 110,110,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
        uiDefButBitC(block, TOG, OB_DRAWXRAY,REDRAWVIEW3D, "X-Ray",                     210,110,100,20, &ob->dtx, 0, 0, 0, 0, "Draw armature in front of solid objects");
+       
+       uiBlockBeginAlign(block);
+       uiDefButBitI(block, TOG, ARM_MIRROR_EDIT, B_DIFF, "X-Axis Mirror Edit", 10, 80,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
 }
 
 static void editing_panel_armature_bones(Object *ob, bArmature *arm)
index 16e0c6b61d6ba1bef9af7c7786e265bf907a9565..7c6036b313ecc7e01cbe20f873c6c925beca1be9 100644 (file)
@@ -890,7 +890,7 @@ void delete_armature(void)
        BIF_undo_push("Delete bone(s)");
 }
 
-/* editmode version */
+/* context: editmode armature */
 void mouse_armature(void)
 {
        EditBone *nearBone = NULL, *ebone;
@@ -950,13 +950,13 @@ void mouse_armature(void)
                }
 
                countall(); // flushes selection!
-       
+               
                if(nearBone) {
                        /* then now check for active status */
                        for (ebone=G.edbo.first;ebone;ebone=ebone->next) ebone->flag &= ~BONE_ACTIVE;
                        if(nearBone->flag & BONE_SELECTED) nearBone->flag |= BONE_ACTIVE;
                }
-          
+               
                allqueue(REDRAWVIEW3D, 0);
                allqueue(REDRAWBUTSEDIT, 0);
                allqueue(REDRAWBUTSOBJECT, 0);
@@ -1384,24 +1384,24 @@ void adduplicate_armature(void)
 /* the "IK" button in editbuttons */
 void attach_bone_to_parent_cb(void *bonev, void *arg2_unused)
 {
-       EditBone *curBone= bonev;
-       attach_bone_to_parent(curBone);
+       EditBone *ebone= bonev;
+       attach_bone_to_parent(ebone);
 }
 
 void attach_bone_to_parent(EditBone *bone)
 {
-       EditBone *curbone;
+       EditBone *ebone;
 
        if (bone->flag & BONE_IK_TOPARENT) {
 
                /* See if there are any other bones that refer to the same 
                 * parent and disconnect them 
                 */
-               for (curbone = G.edbo.first; curbone; curbone=curbone->next){
-                       if (curbone!=bone){
-                               if (curbone->parent && (curbone->parent == bone->parent) && 
-                                       (curbone->flag & BONE_IK_TOPARENT))
-                                               curbone->flag &= ~BONE_IK_TOPARENT;
+               for (ebone = G.edbo.first; ebone; ebone=ebone->next){
+                       if (ebone!=bone){
+                               if (ebone->parent && (ebone->parent == bone->parent) && 
+                                       (ebone->flag & BONE_IK_TOPARENT))
+                                               ebone->flag &= ~BONE_IK_TOPARENT;
                        }
                }
 
@@ -1552,53 +1552,93 @@ void unique_editbone_name (char *name)
        }
 }
 
-void extrude_armature(void)
+/* context; editmode armature */
+/* if forked && mirror-edit: makes two bones with flipped names */
+void extrude_armature(int forked)
 {
-       EditBone *newbone, *curbone, *first=NULL, *partest;
-       int totbone= 0;
+       bArmature *arm= G.obedit->data;
+       EditBone *newbone, *ebone, *flipbone, *first=NULL, *partest;
+       int a, totbone= 0;
        
        TEST_EDITARMATURE;
        
        /* Duplicate the necessary bones */
-       for (curbone = G.edbo.first; ((curbone) && (curbone!=first)); curbone=curbone->next){
-               if (curbone->flag & (BONE_TIPSEL|BONE_SELECTED)){
-                       totbone++;
-                       newbone = MEM_callocN(sizeof(EditBone), "extrudebone");
-                       
-                       VECCOPY (newbone->head, curbone->tail);
-                       VECCOPY (newbone->tail, newbone->head);
-                       newbone->parent = curbone;
+       for (ebone = G.edbo.first; ((ebone) && (ebone!=first)); ebone=ebone->next){
+               if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED)) {
                        
-                       newbone->flag = BONE_TIPSEL;
-                       newbone->weight= curbone->weight;
-                       newbone->dist= curbone->dist;
-                       newbone->xwidth= curbone->xwidth;
-                       newbone->zwidth= curbone->zwidth;
-                       newbone->ease1= curbone->ease1;
-                       newbone->ease2= curbone->ease2;
-                       newbone->segments= curbone->segments;
-                       newbone->boneclass= curbone->boneclass;
-                       
-                       /* See if there are any ik children of the parent */
-                       for (partest = G.edbo.first; partest; partest=partest->next){
-                               if ((partest->parent == curbone) && (partest->flag & BONE_IK_TOPARENT))
-                                       break;
+                       /* we re-use code for mirror editing... */
+                       flipbone= NULL;
+                       if(arm->flag & ARM_MIRROR_EDIT) {
+                               flipbone= armature_bone_get_mirrored(ebone);
+                               if (flipbone) {
+                                       forked= 0;      // we extrude 2 different bones
+                                       if(flipbone->flag & (BONE_TIPSEL|BONE_SELECTED))
+                                               /* don't want this bone to be selected... */
+                                               flipbone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
+                               }
+                               if(flipbone==NULL && forked)
+                                       flipbone= ebone;
                        }
                        
-                       if (!partest)
-                               newbone->flag |= BONE_IK_TOPARENT;
-                       
-                       strcpy (newbone->name, curbone->name);
-                       unique_editbone_name(newbone->name);
-                       
-                       /* Add the new bone to the list */
-                       BLI_addtail(&G.edbo, newbone);
-                       if (!first)
-                               first = newbone;
+                       for(a=0; a<2; a++) {
+                               if(a==1) {
+                                       if(flipbone==NULL)
+                                               break;
+                                       else {
+                                               SWAP(EditBone *, flipbone, ebone);
+                                       }
+                               }
+                               
+                               totbone++;
+                               newbone = MEM_callocN(sizeof(EditBone), "extrudebone");
+                               
+                               VECCOPY (newbone->head, ebone->tail);
+                               VECCOPY (newbone->tail, newbone->head);
+                               newbone->parent = ebone;
+                               
+                               newbone->flag = ebone->flag & BONE_TIPSEL;      // copies it, in case mirrored bone
+                               newbone->weight= ebone->weight;
+                               newbone->dist= ebone->dist;
+                               newbone->xwidth= ebone->xwidth;
+                               newbone->zwidth= ebone->zwidth;
+                               newbone->ease1= ebone->ease1;
+                               newbone->ease2= ebone->ease2;
+                               newbone->segments= ebone->segments;
+                               newbone->boneclass= ebone->boneclass;
+                               
+                               /* See if there are any ik children of the parent */
+                               for (partest = G.edbo.first; partest; partest=partest->next){
+                                       if ((partest->parent == ebone) && (partest->flag & BONE_IK_TOPARENT))
+                                               break;
+                               }
+                               
+                               if (!partest)
+                                       newbone->flag |= BONE_IK_TOPARENT;
+                               
+                               strcpy (newbone->name, ebone->name);
+                               
+                               if(flipbone && forked) {        // only set if mirror edit
+                                       if(strlen(newbone->name)<30) {
+                                               if(a==0) strcat(newbone->name, "_L");
+                                               else strcat(newbone->name, "_R");
+                                       }
+                               }
+                               unique_editbone_name(newbone->name);
+                               
+                               /* Add the new bone to the list */
+                               BLI_addtail(&G.edbo, newbone);
+                               if (!first)
+                                       first = newbone;
+                               
+                               /* restore ebone if we were flipping */
+                               if(a==1 && flipbone) 
+                                       SWAP(EditBone *, flipbone, ebone);
+
+                       }
                }
                
                /* Deselect the old bone */
-               curbone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
+               ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
                
        }
        /* if only one bone, make this one active */
@@ -2365,7 +2405,7 @@ void armature_flip_names(void)
        for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
                if(ebone->flag & BONE_SELECTED) {
                        BLI_strncpy(newname, ebone->name, sizeof(newname));
-                       bone_flip_name(newname);
+                       bone_flip_name(newname, 1);             // 1 = do strip off number extensions
                        armature_bone_rename(G.obedit->data, ebone->name, newname);
                }
        }
@@ -2379,3 +2419,19 @@ void armature_flip_names(void)
        
 }
 
+/* context; editmode armature */
+EditBone *armature_bone_get_mirrored(EditBone *ebo)
+{
+       EditBone *eboflip= NULL;
+       char name[32];
+       
+       BLI_strncpy(name, ebo->name, sizeof(name));
+       bone_flip_name(name, 0);                // 0 = don't strip off number extensions
+
+       for (eboflip=G.edbo.first; eboflip; eboflip=eboflip->next)
+               if(ebo!=eboflip)
+                       if (!strcmp (name, eboflip->name)) break;
+       
+       return eboflip;
+}
+
index 89ee15af77a14f2aa7976cae47e0c50df21f0e7e..de07b865f215715c818d28c8f2be35ae8fa5c7af 100644 (file)
@@ -604,7 +604,7 @@ static EditFace *findnearestface(short *dist)
 
                        data.mval[0] = mval[0];
                        data.mval[1] = mval[1];
-                       data.dist = (1<<20); // just a big number
+                       data.dist = 0x7FFF;             // largest short
                        data.toFace = efa;
 
                        mesh_foreachScreenFace(findnearestface__getDistance, &data);
index ccf64b40452ae27c0a2f39b46d8d248fa360ff1a..031a6fec5e0b9a9f0b94d5b6f2e1e5298710c0c6 100644 (file)
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_armature_types.h"
 #include "DNA_ID.h"
+#include "DNA_image_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_view3d_types.h"
-#include "DNA_image_types.h"
 #include "DNA_text_types.h" /* for space handlers */
 #include "DNA_texture_types.h"
 
-#include "BKE_library.h"
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
 #include "BKE_displist.h"
 #include "BKE_effect.h"
 #include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_mesh.h"
-#include "BKE_image.h"
 
 #include "BLI_arithb.h"
 #include "BLI_blenlib.h"
@@ -2142,8 +2143,6 @@ static uiBlock *view3d_edit_mesh_edgesmenu(void *arg_unused)
 {
        uiBlock *block;
        short yco = 20, menuwidth = 120;
-       
-       Mesh *me= get_mesh(OBACT);
 
        block= uiNewBlock(&curarea->uiblocks, "view3d_edit_mesh_edgesmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
        uiBlockSetButmFunc(block, do_view3d_edit_mesh_edgesmenu, NULL);
@@ -3051,7 +3050,7 @@ static void do_view3d_edit_armaturemenu(void *arg, int event)
                mainqenter(NKEY, 1);
                break;
        case 3: /* extrude */
-               extrude_armature();
+               extrude_armature(0);
                break;
        case 4: /* duplicate */
                duplicate_context_selected();
@@ -3072,12 +3071,16 @@ static void do_view3d_edit_armaturemenu(void *arg, int event)
        case 9:
                clear_bone_parent();
                break;
+       case 10: /* forked! */
+               extrude_armature(1);
+               break;
        }
        allqueue(REDRAWVIEW3D, 0);
 }
 
 static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
 {
+       bArmature *arm= G.obedit->data;
        uiBlock *block;
        short yco= 0, menuwidth=120;
        
@@ -3096,6 +3099,9 @@ static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrude|E",                              0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+       if(arm->flag & ARM_MIRROR_EDIT)
+               uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extrude Forked|Shift E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
+               
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D",              0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X",                               0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Parent...|Ctrl P",  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
index 91edf21fd6bd939322c8b774270deae6ef0d5f5c..75a10df9b6c169e49d97449395661e7189613322 100644 (file)
@@ -462,7 +462,7 @@ void paste_posebuf (int flip)
                if (chan->flag & POSE_KEY) {
                        BLI_strncpy(name, chan->name, sizeof(name));
                        if (flip)
-                               bone_flip_name (name);
+                               bone_flip_name (name, 0);               // 0 = don't strip off number extensions
                                
                        /* only copy when channel exists, poses are not meant to add random channels to anymore */
                        pchan= get_pose_channel(ob->pose, name);
@@ -544,7 +544,7 @@ void pose_flip_names(void)
        for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
                        BLI_strncpy(newname, pchan->name, sizeof(newname));
-                       bone_flip_name(newname);
+                       bone_flip_name(newname, 1);     // 1 = do strip off number extensions
                        armature_bone_rename(ob->data, pchan->name, newname);
                }
        }
index a91841afe7c2db5d4468beef57db5b29dad12025..2f17181874ef5a6a7a28e98d4f9d88276ab6f604 100644 (file)
@@ -1184,7 +1184,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                                else if(G.obedit->type==OB_SURF)
                                                        extrude_nurb();
                                                else if(G.obedit->type==OB_ARMATURE)
-                                                       extrude_armature();
+                                                       extrude_armature(0);
                                        }
                                }
                                else if (G.qual==LR_CTRLKEY) {
@@ -1196,6 +1196,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                                initTransform(TFM_CREASE, CTX_EDGE);
                                                Transform();
                                        }
+                                       else if (G.obedit && G.obedit->type==OB_ARMATURE) {
+                                               extrude_armature(1);
+                                       }
                                }
                                break;
                        case FKEY:
index 4bf86b1fbcb971c9183761dd30fd067832e86f8a..712eaa47020f0093ce6c21d9c0dbc985f99d9153 100644 (file)
@@ -1802,7 +1802,6 @@ static TBitem tb_obdata_hide[]= {
 {  -1, "",                     0, tb_do_hotkey}};
 
 static void tb_do_mesh(void *arg, int event){
-       Mesh *me= get_mesh(OBACT);
        switch(event) {
        case 1: common_insertkey(); break;
        case 2: G.f ^= G_DRAWEDGES; break;
index 9a6839a8c322482fc4cb0bb5f6fe3ef20cf175b3..32afcd6ea204d7ddef71be9a1a4fa29eb3b2ae37 100755 (executable)
@@ -67,6 +67,7 @@
 #include "BSE_view.h"
 
 #include "BLI_arithb.h"
+#include "BLI_blenlib.h"
 
 #include "blendef.h"
 
@@ -109,22 +110,41 @@ void getViewVector(float coord[3], float vec[3]) {
 
 /* ************************** GENERICS **************************** */
 
+/* if editbone (partial) selected, copy data */
+/* context; editmode armature, with mirror editing enabled */
+static void transform_armature_mirror_update(void)
+{
+       EditBone *ebo, *eboflip;
+       
+       for (ebo=G.edbo.first; ebo; ebo=ebo->next) {
+               if(ebo->flag & (BONE_TIPSEL|BONE_ROOTSEL)) {
+                       
+                       eboflip= armature_bone_get_mirrored(ebo);
+                       
+                       if(eboflip) {
+                               /* we assume X-axis flipping for now */
+                               if(ebo->flag & BONE_TIPSEL) {
+                                       eboflip->tail[0]= -ebo->tail[0];
+                                       eboflip->tail[1]= ebo->tail[1];
+                                       eboflip->tail[2]= ebo->tail[2];
+                               }
+                               if(ebo->flag & BONE_ROOTSEL) {
+                                       eboflip->head[0]= -ebo->head[0];
+                                       eboflip->head[1]= ebo->head[1];
+                                       eboflip->head[2]= ebo->head[2];
+                               }
+                       }
+               }
+       }
+}
+
+
 /* called for objects updating while transform acts, once per redraw */
 void recalcData(TransInfo *t)
 {
        Object *ob= OBACT;
        
-       if(ob && (ob->flag & OB_POSEMODE)) {
-               bArmature *arm= ob->data;
-
-               /* old optimize trick... this enforces to bypass the depgraph */
-               if (!(arm->flag & ARM_DELAYDEFORM)) 
-                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);  /* sets recalc flags */
-               else
-                       where_is_pose(ob);
-       }
-       else if (G.obedit) {
-               
+       if (G.obedit) {
                if (G.obedit->type == OB_MESH) {
                        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);  /* sets recalc flags */
                        
@@ -141,6 +161,7 @@ void recalcData(TransInfo *t)
                        }
                }
                else if(G.obedit->type==OB_ARMATURE){   /* no recalc flag, does pose */
+                       bArmature *arm= G.obedit->data;
                        EditBone *ebo;
                        
                        /* Ensure all bones are correctly adjusted */
@@ -157,6 +178,9 @@ void recalcData(TransInfo *t)
                                        }
                                }
                        }
+                       if(arm->flag & ARM_MIRROR_EDIT) 
+                               transform_armature_mirror_update();
+                       
                }
                else if(G.obedit->type==OB_LATTICE) {
                        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);  /* sets recalc flags */
@@ -167,6 +191,15 @@ void recalcData(TransInfo *t)
                        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);  /* sets recalc flags */
                }
        }
+       else if(ob && (ob->flag & OB_POSEMODE)) {
+               bArmature *arm= ob->data;
+               
+               /* old optimize trick... this enforces to bypass the depgraph */
+               if (!(arm->flag & ARM_DELAYDEFORM)) 
+                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);  /* sets recalc flags */
+               else
+                       where_is_pose(ob);
+       }
        else {
                Base *base;