EditMode armature: mirrored editing feature.
- 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. :)
This commit is contained in:
@@ -72,7 +72,7 @@ void unlink_armature(struct bArmature *arm);
|
|||||||
void free_armature(struct bArmature *arm);
|
void free_armature(struct bArmature *arm);
|
||||||
void make_local_armature(struct bArmature *arm);
|
void make_local_armature(struct bArmature *arm);
|
||||||
struct bArmature *copy_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);
|
void calc_armature_deform (struct Object *ob, float *co, int index);
|
||||||
|
|
||||||
|
|||||||
@@ -651,7 +651,7 @@ static void emDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *u
|
|||||||
EditVert *eve, *preveve;
|
EditVert *eve, *preveve;
|
||||||
EditFace *efa;
|
EditFace *efa;
|
||||||
float cent[3];
|
float cent[3];
|
||||||
int i;
|
int i=0; // gcc!
|
||||||
|
|
||||||
if (emdm->vertexCos) {
|
if (emdm->vertexCos) {
|
||||||
for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
|
for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
|
||||||
|
|||||||
@@ -264,13 +264,15 @@ static char *strcasestr_(register char *s, register char *find)
|
|||||||
|
|
||||||
#define IS_SEPARATOR(a) (a=='.' || a==' ' || a=='-' || a=='_')
|
#define IS_SEPARATOR(a) (a=='.' || a==' ' || a=='-' || a=='_')
|
||||||
|
|
||||||
/* finds the best possible flipped name, removing number extensions. For renaming; check for unique names afterwards */
|
/* finds the best possible flipped name. For renaming; check for unique names afterwards */
|
||||||
void bone_flip_name (char *name)
|
/* if strip_number: removes number extensions */
|
||||||
|
void bone_flip_name (char *name, int strip_number)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char prefix[128]={""}; /* The part before the facing */
|
char prefix[128]={""}; /* The part before the facing */
|
||||||
char suffix[128]={""}; /* The part after the facing */
|
char suffix[128]={""}; /* The part after the facing */
|
||||||
char replace[128]={""}; /* The replacement string */
|
char replace[128]={""}; /* The replacement string */
|
||||||
|
char number[128]={""}; /* The number extension string */
|
||||||
char *index=NULL;
|
char *index=NULL;
|
||||||
|
|
||||||
len= strlen(name);
|
len= strlen(name);
|
||||||
@@ -280,6 +282,8 @@ void bone_flip_name (char *name)
|
|||||||
if(isdigit(name[len-1])) {
|
if(isdigit(name[len-1])) {
|
||||||
index= strrchr(name, '.'); // last occurrance
|
index= strrchr(name, '.'); // last occurrance
|
||||||
if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
|
if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
|
||||||
|
if(strip_number==0)
|
||||||
|
strcpy(number, index);
|
||||||
*index= 0;
|
*index= 0;
|
||||||
len= strlen(name);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1430,10 +1430,11 @@ int SoftBodyDetectCollision(float opco[3], float npco[3], float colco[3],
|
|||||||
if(ob->pd && ob->pd->deflect) {
|
if(ob->pd && ob->pd->deflect) {
|
||||||
DerivedMesh *dm=NULL;
|
DerivedMesh *dm=NULL;
|
||||||
int dmNeedsFree;
|
int dmNeedsFree;
|
||||||
Mesh *me;
|
Mesh *me= NULL;
|
||||||
DispListMesh *disp_mesh = 0;
|
DispListMesh *disp_mesh = 0;
|
||||||
MFace *mface;
|
MFace *mface;
|
||||||
Object *copyob;
|
Object *copyob;
|
||||||
|
|
||||||
/* do object level stuff */
|
/* do object level stuff */
|
||||||
/* need to have user control for that since it depends on model scale */
|
/* need to have user control for that since it depends on model scale */
|
||||||
innerfacethickness =-ob->pd->pdef_sbift;
|
innerfacethickness =-ob->pd->pdef_sbift;
|
||||||
|
|||||||
@@ -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)
|
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);
|
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)
|
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);
|
sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -447,7 +447,6 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (S=0; S<numVerts; S++) {
|
for (S=0; S<numVerts; S++) {
|
||||||
VertData *gridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
|
|
||||||
int prevS= (S-1+numVerts)%numVerts;
|
int prevS= (S-1+numVerts)%numVerts;
|
||||||
|
|
||||||
for (y=0; y<gridSize-1; y++) {
|
for (y=0; y<gridSize-1; y++) {
|
||||||
@@ -1293,7 +1292,6 @@ static void ccgDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *
|
|||||||
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
|
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
|
||||||
CCGSubSurf *ss = ccgdm->ss;
|
CCGSubSurf *ss = ccgdm->ss;
|
||||||
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
|
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
|
||||||
int gridSize = ccgSubSurf_getGridSize(ss);
|
|
||||||
|
|
||||||
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
|
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
|
||||||
CCGFace *f = ccgFaceIterator_getCurrent(fi);
|
CCGFace *f = ccgFaceIterator_getCurrent(fi);
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ void delete_armature(void);
|
|||||||
void deselectall_armature(int toggle);
|
void deselectall_armature(int toggle);
|
||||||
void deselectall_posearmature (struct Object *ob, int test);
|
void deselectall_posearmature (struct Object *ob, int test);
|
||||||
void draw_armature(struct Base *base, int dt);
|
void draw_armature(struct Base *base, int dt);
|
||||||
void extrude_armature(void);
|
void extrude_armature(int forked);
|
||||||
void free_editArmature(void);
|
void free_editArmature(void);
|
||||||
struct Bone *get_indexed_bone (struct Object *ob, int index);
|
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 undo_push_armature(char *name);
|
||||||
void armature_bone_rename(struct bArmature *arm, char *oldname, char *newname);
|
void armature_bone_rename(struct bArmature *arm, char *oldname, char *newname);
|
||||||
void armature_flip_names(void);
|
void armature_flip_names(void);
|
||||||
|
EditBone *armature_bone_get_mirrored(EditBone *ebo);
|
||||||
|
|
||||||
#define BONESEL_ROOT 0x10000000
|
#define BONESEL_ROOT 0x10000000
|
||||||
#define BONESEL_TIP 0x20000000
|
#define BONESEL_TIP 0x20000000
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ typedef struct bArmature {
|
|||||||
#define ARM_EDITMODE 0x0020
|
#define ARM_EDITMODE 0x0020
|
||||||
#define ARM_DELAYDEFORM 0x0040
|
#define ARM_DELAYDEFORM 0x0040
|
||||||
#define ARM_DONT_USE 0x0080
|
#define ARM_DONT_USE 0x0080
|
||||||
|
#define ARM_MIRROR_EDIT 0x0100
|
||||||
|
|
||||||
/* armature->drawtype */
|
/* armature->drawtype */
|
||||||
|
|
||||||
|
|||||||
@@ -850,7 +850,6 @@ static void modifiers_cursorHookCenter(void *ob_v, void *md_v)
|
|||||||
|
|
||||||
static void modifiers_selectHook(void *ob_v, void *md_v)
|
static void modifiers_selectHook(void *ob_v, void *md_v)
|
||||||
{
|
{
|
||||||
Object *ob = ob_v;
|
|
||||||
ModifierData *md = md_v;
|
ModifierData *md = md_v;
|
||||||
HookModifierData *hmd = (HookModifierData*) md;
|
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)
|
static void modifiers_reassignHook(void *ob_v, void *md_v)
|
||||||
{
|
{
|
||||||
Object *ob = ob_v;
|
|
||||||
ModifierData *md = md_v;
|
ModifierData *md = md_v;
|
||||||
HookModifierData *hmd = (HookModifierData*) md;
|
HookModifierData *hmd = (HookModifierData*) md;
|
||||||
float cent[3];
|
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)
|
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);
|
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||||
|
uiBut *but;
|
||||||
int isVirtual = md->mode&eModifierMode_Virtual;
|
int isVirtual = md->mode&eModifierMode_Virtual;
|
||||||
int x = *xco, y = *yco, color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
|
int x = *xco, y = *yco, color = md->error?TH_REDALERT:TH_BUT_NEUTRAL;
|
||||||
int editing = (G.obedit==ob);
|
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];
|
char str[128];
|
||||||
uiBut *but;
|
|
||||||
|
|
||||||
if (isVirtual) {
|
if (isVirtual) {
|
||||||
uiSetButLock(1, "Modifier is virtual and cannot be edited.");
|
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_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");
|
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");
|
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)
|
static void editing_panel_armature_bones(Object *ob, bArmature *arm)
|
||||||
|
|||||||
@@ -890,7 +890,7 @@ void delete_armature(void)
|
|||||||
BIF_undo_push("Delete bone(s)");
|
BIF_undo_push("Delete bone(s)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* editmode version */
|
/* context: editmode armature */
|
||||||
void mouse_armature(void)
|
void mouse_armature(void)
|
||||||
{
|
{
|
||||||
EditBone *nearBone = NULL, *ebone;
|
EditBone *nearBone = NULL, *ebone;
|
||||||
@@ -1384,24 +1384,24 @@ void adduplicate_armature(void)
|
|||||||
/* the "IK" button in editbuttons */
|
/* the "IK" button in editbuttons */
|
||||||
void attach_bone_to_parent_cb(void *bonev, void *arg2_unused)
|
void attach_bone_to_parent_cb(void *bonev, void *arg2_unused)
|
||||||
{
|
{
|
||||||
EditBone *curBone= bonev;
|
EditBone *ebone= bonev;
|
||||||
attach_bone_to_parent(curBone);
|
attach_bone_to_parent(ebone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attach_bone_to_parent(EditBone *bone)
|
void attach_bone_to_parent(EditBone *bone)
|
||||||
{
|
{
|
||||||
EditBone *curbone;
|
EditBone *ebone;
|
||||||
|
|
||||||
if (bone->flag & BONE_IK_TOPARENT) {
|
if (bone->flag & BONE_IK_TOPARENT) {
|
||||||
|
|
||||||
/* See if there are any other bones that refer to the same
|
/* See if there are any other bones that refer to the same
|
||||||
* parent and disconnect them
|
* parent and disconnect them
|
||||||
*/
|
*/
|
||||||
for (curbone = G.edbo.first; curbone; curbone=curbone->next){
|
for (ebone = G.edbo.first; ebone; ebone=ebone->next){
|
||||||
if (curbone!=bone){
|
if (ebone!=bone){
|
||||||
if (curbone->parent && (curbone->parent == bone->parent) &&
|
if (ebone->parent && (ebone->parent == bone->parent) &&
|
||||||
(curbone->flag & BONE_IK_TOPARENT))
|
(ebone->flag & BONE_IK_TOPARENT))
|
||||||
curbone->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;
|
bArmature *arm= G.obedit->data;
|
||||||
int totbone= 0;
|
EditBone *newbone, *ebone, *flipbone, *first=NULL, *partest;
|
||||||
|
int a, totbone= 0;
|
||||||
|
|
||||||
TEST_EDITARMATURE;
|
TEST_EDITARMATURE;
|
||||||
|
|
||||||
/* Duplicate the necessary bones */
|
/* Duplicate the necessary bones */
|
||||||
for (curbone = G.edbo.first; ((curbone) && (curbone!=first)); curbone=curbone->next){
|
for (ebone = G.edbo.first; ((ebone) && (ebone!=first)); ebone=ebone->next){
|
||||||
if (curbone->flag & (BONE_TIPSEL|BONE_SELECTED)){
|
if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED)) {
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(a=0; a<2; a++) {
|
||||||
|
if(a==1) {
|
||||||
|
if(flipbone==NULL)
|
||||||
|
break;
|
||||||
|
else {
|
||||||
|
SWAP(EditBone *, flipbone, ebone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
totbone++;
|
totbone++;
|
||||||
newbone = MEM_callocN(sizeof(EditBone), "extrudebone");
|
newbone = MEM_callocN(sizeof(EditBone), "extrudebone");
|
||||||
|
|
||||||
VECCOPY (newbone->head, curbone->tail);
|
VECCOPY (newbone->head, ebone->tail);
|
||||||
VECCOPY (newbone->tail, newbone->head);
|
VECCOPY (newbone->tail, newbone->head);
|
||||||
newbone->parent = curbone;
|
newbone->parent = ebone;
|
||||||
|
|
||||||
newbone->flag = BONE_TIPSEL;
|
newbone->flag = ebone->flag & BONE_TIPSEL; // copies it, in case mirrored bone
|
||||||
newbone->weight= curbone->weight;
|
newbone->weight= ebone->weight;
|
||||||
newbone->dist= curbone->dist;
|
newbone->dist= ebone->dist;
|
||||||
newbone->xwidth= curbone->xwidth;
|
newbone->xwidth= ebone->xwidth;
|
||||||
newbone->zwidth= curbone->zwidth;
|
newbone->zwidth= ebone->zwidth;
|
||||||
newbone->ease1= curbone->ease1;
|
newbone->ease1= ebone->ease1;
|
||||||
newbone->ease2= curbone->ease2;
|
newbone->ease2= ebone->ease2;
|
||||||
newbone->segments= curbone->segments;
|
newbone->segments= ebone->segments;
|
||||||
newbone->boneclass= curbone->boneclass;
|
newbone->boneclass= ebone->boneclass;
|
||||||
|
|
||||||
/* See if there are any ik children of the parent */
|
/* See if there are any ik children of the parent */
|
||||||
for (partest = G.edbo.first; partest; partest=partest->next){
|
for (partest = G.edbo.first; partest; partest=partest->next){
|
||||||
if ((partest->parent == curbone) && (partest->flag & BONE_IK_TOPARENT))
|
if ((partest->parent == ebone) && (partest->flag & BONE_IK_TOPARENT))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!partest)
|
if (!partest)
|
||||||
newbone->flag |= BONE_IK_TOPARENT;
|
newbone->flag |= BONE_IK_TOPARENT;
|
||||||
|
|
||||||
strcpy (newbone->name, curbone->name);
|
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);
|
unique_editbone_name(newbone->name);
|
||||||
|
|
||||||
/* Add the new bone to the list */
|
/* Add the new bone to the list */
|
||||||
BLI_addtail(&G.edbo, newbone);
|
BLI_addtail(&G.edbo, newbone);
|
||||||
if (!first)
|
if (!first)
|
||||||
first = newbone;
|
first = newbone;
|
||||||
|
|
||||||
|
/* restore ebone if we were flipping */
|
||||||
|
if(a==1 && flipbone)
|
||||||
|
SWAP(EditBone *, flipbone, ebone);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deselect the old bone */
|
/* 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 */
|
/* 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) {
|
for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
|
||||||
if(ebone->flag & BONE_SELECTED) {
|
if(ebone->flag & BONE_SELECTED) {
|
||||||
BLI_strncpy(newname, ebone->name, sizeof(newname));
|
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);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -604,7 +604,7 @@ static EditFace *findnearestface(short *dist)
|
|||||||
|
|
||||||
data.mval[0] = mval[0];
|
data.mval[0] = mval[0];
|
||||||
data.mval[1] = mval[1];
|
data.mval[1] = mval[1];
|
||||||
data.dist = (1<<20); // just a big number
|
data.dist = 0x7FFF; // largest short
|
||||||
data.toFace = efa;
|
data.toFace = efa;
|
||||||
|
|
||||||
mesh_foreachScreenFace(findnearestface__getDistance, &data);
|
mesh_foreachScreenFace(findnearestface__getDistance, &data);
|
||||||
|
|||||||
@@ -47,26 +47,27 @@
|
|||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
|
#include "DNA_armature_types.h"
|
||||||
#include "DNA_ID.h"
|
#include "DNA_ID.h"
|
||||||
|
#include "DNA_image_types.h"
|
||||||
#include "DNA_mesh_types.h"
|
#include "DNA_mesh_types.h"
|
||||||
#include "DNA_object_types.h"
|
#include "DNA_object_types.h"
|
||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_screen_types.h"
|
#include "DNA_screen_types.h"
|
||||||
#include "DNA_space_types.h"
|
#include "DNA_space_types.h"
|
||||||
#include "DNA_view3d_types.h"
|
#include "DNA_view3d_types.h"
|
||||||
#include "DNA_image_types.h"
|
|
||||||
#include "DNA_text_types.h" /* for space handlers */
|
#include "DNA_text_types.h" /* for space handlers */
|
||||||
#include "DNA_texture_types.h"
|
#include "DNA_texture_types.h"
|
||||||
|
|
||||||
#include "BKE_library.h"
|
|
||||||
#include "BKE_curve.h"
|
#include "BKE_curve.h"
|
||||||
#include "BKE_depsgraph.h"
|
#include "BKE_depsgraph.h"
|
||||||
#include "BKE_displist.h"
|
#include "BKE_displist.h"
|
||||||
#include "BKE_effect.h"
|
#include "BKE_effect.h"
|
||||||
#include "BKE_global.h"
|
#include "BKE_global.h"
|
||||||
|
#include "BKE_image.h"
|
||||||
|
#include "BKE_library.h"
|
||||||
#include "BKE_main.h"
|
#include "BKE_main.h"
|
||||||
#include "BKE_mesh.h"
|
#include "BKE_mesh.h"
|
||||||
#include "BKE_image.h"
|
|
||||||
|
|
||||||
#include "BLI_arithb.h"
|
#include "BLI_arithb.h"
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
@@ -2143,8 +2144,6 @@ static uiBlock *view3d_edit_mesh_edgesmenu(void *arg_unused)
|
|||||||
uiBlock *block;
|
uiBlock *block;
|
||||||
short yco = 20, menuwidth = 120;
|
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);
|
block= uiNewBlock(&curarea->uiblocks, "view3d_edit_mesh_edgesmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
|
||||||
uiBlockSetButmFunc(block, do_view3d_edit_mesh_edgesmenu, NULL);
|
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);
|
mainqenter(NKEY, 1);
|
||||||
break;
|
break;
|
||||||
case 3: /* extrude */
|
case 3: /* extrude */
|
||||||
extrude_armature();
|
extrude_armature(0);
|
||||||
break;
|
break;
|
||||||
case 4: /* duplicate */
|
case 4: /* duplicate */
|
||||||
duplicate_context_selected();
|
duplicate_context_selected();
|
||||||
@@ -3072,12 +3071,16 @@ static void do_view3d_edit_armaturemenu(void *arg, int event)
|
|||||||
case 9:
|
case 9:
|
||||||
clear_bone_parent();
|
clear_bone_parent();
|
||||||
break;
|
break;
|
||||||
|
case 10: /* forked! */
|
||||||
|
extrude_armature(1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
allqueue(REDRAWVIEW3D, 0);
|
allqueue(REDRAWVIEW3D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
|
static uiBlock *view3d_edit_armaturemenu(void *arg_unused)
|
||||||
{
|
{
|
||||||
|
bArmature *arm= G.obedit->data;
|
||||||
uiBlock *block;
|
uiBlock *block;
|
||||||
short yco= 0, menuwidth=120;
|
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, "");
|
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, "");
|
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, "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, "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, "");
|
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make Parent...|Ctrl P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
|
||||||
|
|||||||
@@ -462,7 +462,7 @@ void paste_posebuf (int flip)
|
|||||||
if (chan->flag & POSE_KEY) {
|
if (chan->flag & POSE_KEY) {
|
||||||
BLI_strncpy(name, chan->name, sizeof(name));
|
BLI_strncpy(name, chan->name, sizeof(name));
|
||||||
if (flip)
|
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 */
|
/* only copy when channel exists, poses are not meant to add random channels to anymore */
|
||||||
pchan= get_pose_channel(ob->pose, name);
|
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) {
|
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||||
if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
|
if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
|
||||||
BLI_strncpy(newname, pchan->name, sizeof(newname));
|
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);
|
armature_bone_rename(ob->data, pchan->name, newname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1184,7 +1184,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
|||||||
else if(G.obedit->type==OB_SURF)
|
else if(G.obedit->type==OB_SURF)
|
||||||
extrude_nurb();
|
extrude_nurb();
|
||||||
else if(G.obedit->type==OB_ARMATURE)
|
else if(G.obedit->type==OB_ARMATURE)
|
||||||
extrude_armature();
|
extrude_armature(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (G.qual==LR_CTRLKEY) {
|
else if (G.qual==LR_CTRLKEY) {
|
||||||
@@ -1196,6 +1196,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
|||||||
initTransform(TFM_CREASE, CTX_EDGE);
|
initTransform(TFM_CREASE, CTX_EDGE);
|
||||||
Transform();
|
Transform();
|
||||||
}
|
}
|
||||||
|
else if (G.obedit && G.obedit->type==OB_ARMATURE) {
|
||||||
|
extrude_armature(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FKEY:
|
case FKEY:
|
||||||
|
|||||||
@@ -1802,7 +1802,6 @@ static TBitem tb_obdata_hide[]= {
|
|||||||
{ -1, "", 0, tb_do_hotkey}};
|
{ -1, "", 0, tb_do_hotkey}};
|
||||||
|
|
||||||
static void tb_do_mesh(void *arg, int event){
|
static void tb_do_mesh(void *arg, int event){
|
||||||
Mesh *me= get_mesh(OBACT);
|
|
||||||
switch(event) {
|
switch(event) {
|
||||||
case 1: common_insertkey(); break;
|
case 1: common_insertkey(); break;
|
||||||
case 2: G.f ^= G_DRAWEDGES; break;
|
case 2: G.f ^= G_DRAWEDGES; break;
|
||||||
|
|||||||
@@ -67,6 +67,7 @@
|
|||||||
#include "BSE_view.h"
|
#include "BSE_view.h"
|
||||||
|
|
||||||
#include "BLI_arithb.h"
|
#include "BLI_arithb.h"
|
||||||
|
#include "BLI_blenlib.h"
|
||||||
|
|
||||||
#include "blendef.h"
|
#include "blendef.h"
|
||||||
|
|
||||||
@@ -109,22 +110,41 @@ void getViewVector(float coord[3], float vec[3]) {
|
|||||||
|
|
||||||
/* ************************** GENERICS **************************** */
|
/* ************************** 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 */
|
/* called for objects updating while transform acts, once per redraw */
|
||||||
void recalcData(TransInfo *t)
|
void recalcData(TransInfo *t)
|
||||||
{
|
{
|
||||||
Object *ob= OBACT;
|
Object *ob= OBACT;
|
||||||
|
|
||||||
if(ob && (ob->flag & OB_POSEMODE)) {
|
if (G.obedit) {
|
||||||
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->type == OB_MESH) {
|
if (G.obedit->type == OB_MESH) {
|
||||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* sets recalc flags */
|
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 */
|
else if(G.obedit->type==OB_ARMATURE){ /* no recalc flag, does pose */
|
||||||
|
bArmature *arm= G.obedit->data;
|
||||||
EditBone *ebo;
|
EditBone *ebo;
|
||||||
|
|
||||||
/* Ensure all bones are correctly adjusted */
|
/* 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) {
|
else if(G.obedit->type==OB_LATTICE) {
|
||||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* sets recalc flags */
|
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 */
|
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 {
|
else {
|
||||||
Base *base;
|
Base *base;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user