Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_armature.h2
-rw-r--r--source/blender/blenkernel/intern/armature.c66
-rw-r--r--source/blender/blenloader/intern/readfile.c21
-rw-r--r--source/blender/include/BIF_editarmature.h17
-rw-r--r--source/blender/include/BIF_poseobject.h2
-rwxr-xr-xsource/blender/include/BIF_transform.h1
-rwxr-xr-xsource/blender/include/transform.h3
-rw-r--r--source/blender/makesdna/DNA_action_types.h17
-rw-r--r--source/blender/makesdna/DNA_armature_types.h15
-rw-r--r--source/blender/src/buttons_editing.c25
-rw-r--r--source/blender/src/drawarmature.c616
-rw-r--r--source/blender/src/editarmature.c338
-rw-r--r--source/blender/src/editdeform.c16
-rw-r--r--source/blender/src/editmesh.c4
-rw-r--r--source/blender/src/editobject.c7
-rw-r--r--source/blender/src/header_view3d.c40
-rw-r--r--source/blender/src/outliner.c25
-rw-r--r--source/blender/src/poseobject.c60
-rw-r--r--source/blender/src/space.c33
-rwxr-xr-xsource/blender/src/transform.c167
-rwxr-xr-xsource/blender/src/transform_conversions.c92
-rwxr-xr-xsource/blender/src/transform_generics.c18
-rw-r--r--source/blender/src/view.c1
23 files changed, 1236 insertions, 350 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 229ef7a297b..9c674971bbf 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -78,7 +78,7 @@ void init_armature_deform(struct Object *parent, struct Object *ob);
struct bArmature* get_armature (struct Object* ob);
struct Bone *get_named_bone (struct bArmature *arm, const char *name);
-float dist_to_bone (float vec[3], float b1[3], float b2[3]);
+float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist);
void where_is_armature (struct bArmature *arm);
void where_is_armature_bone(struct Bone *bone, struct Bone *prevbone);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 4f2d1ce3100..317659ade68 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -537,56 +537,74 @@ void init_armature_deform(Object *parent, Object *ob)
/* bone defmats are already in the channels, chan_mat */
}
-float dist_to_bone (float vec[3], float b1[3], float b2[3])
+/* using vec with dist to bone b1 - b2 */
+float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist)
{
-/* float dist=0; */
+ float dist=0.0f;
float bdelta[3];
float pdelta[3];
- float hsqr, a, l;
-
+ float hsqr, a, l, rad;
+
VecSubf (bdelta, b2, b1);
l = Normalise (bdelta);
-
+
VecSubf (pdelta, vec, b1);
-
+
a = bdelta[0]*pdelta[0] + bdelta[1]*pdelta[1] + bdelta[2]*pdelta[2];
hsqr = ((pdelta[0]*pdelta[0]) + (pdelta[1]*pdelta[1]) + (pdelta[2]*pdelta[2]));
-
+
if (a < 0.0F){
- //return 100000;
- /* If we're past the end of the bone, do some weird field attenuation thing */
- return ((b1[0]-vec[0])*(b1[0]-vec[0]) +(b1[1]-vec[1])*(b1[1]-vec[1]) +(b1[2]-vec[2])*(b1[2]-vec[2])) ;
+ /* If we're past the end of the bone, do a spherical field attenuation thing */
+ dist= ((b1[0]-vec[0])*(b1[0]-vec[0]) +(b1[1]-vec[1])*(b1[1]-vec[1]) +(b1[2]-vec[2])*(b1[2]-vec[2])) ;
+ rad= rad1;
}
else if (a > l){
- //return 100000;
- /* If we're past the end of the bone, do some weird field attenuation thing */
- return ((b2[0]-vec[0])*(b2[0]-vec[0]) +(b2[1]-vec[1])*(b2[1]-vec[1]) +(b2[2]-vec[2])*(b2[2]-vec[2])) ;
+ /* If we're past the end of the bone, do a spherical field attenuation thing */
+ dist= ((b2[0]-vec[0])*(b2[0]-vec[0]) +(b2[1]-vec[1])*(b2[1]-vec[1]) +(b2[2]-vec[2])*(b2[2]-vec[2])) ;
+ rad= rad2;
}
else {
- return (hsqr - (a*a));
+ dist= (hsqr - (a*a));
+
+ if(l!=0.0f) {
+ rad= a/l;
+ rad= rad*rad2 + (1.0-rad)*rad1;
+ }
+ else rad= rad1;
+ }
+
+ a= rad*rad;
+ if(dist < a)
+ return 1.0f;
+ else {
+ l= rad+rdist;
+ l*= l;
+ if(rdist==0.0f || dist >= l)
+ return 0.0f;
+ else {
+ a= sqrt(dist)-rad;
+ return 1.0-( a*a )/( rdist*rdist );
+ }
}
}
static float dist_bone_deform(bPoseChannel *pchan, float *vec, float *co)
{
Bone *bone= pchan->bone;
- float dist, fac, ifac;
+ float fac;
float cop[3];
- float bdsqr, contrib=0.0;
+ float contrib=0.0;
if(bone==NULL) return 0.0f;
- bdsqr = bone->dist*bone->dist;
VECCOPY (cop, co);
- dist = dist_to_bone(cop, bone->arm_head, bone->arm_tail);
+ fac= distfactor_to_bone(cop, bone->arm_head, bone->arm_tail, bone->rad_head, bone->rad_tail, bone->dist);
- if ((dist) <= bdsqr){
- fac = (dist)/bdsqr;
- ifac = 1.0F-fac;
+ if (fac>0.0){
- ifac*=bone->weight;
- contrib= ifac;
+ fac*=bone->weight;
+ contrib= fac;
if(contrib>0.0) {
VECCOPY (cop, co);
@@ -594,7 +612,7 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, float *co)
Mat4MulVecfl(pchan->chan_mat, cop);
VecSubf (cop, cop, co); // Make this a delta from the base position
- cop[0]*=ifac; cop[1]*=ifac; cop[2]*=ifac;
+ cop[0]*=fac; cop[1]*=fac; cop[2]*=fac;
VecAddf (vec, vec, cop);
}
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 9859496831f..928820f91fd 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3373,6 +3373,22 @@ static int map_223_keybd_code_to_224_keybd_code(int code)
}
}
+static void bone_version_238(ListBase *lb)
+{
+ Bone *bone;
+
+ for(bone= lb->first; bone; bone= bone->next) {
+ if(bone->rad_tail==0.0f && bone->rad_head==0.0f) {
+ bone->rad_head= 0.25f*bone->length;
+ bone->rad_tail= 0.1f*bone->length;
+
+ bone->dist-= bone->rad_head;
+ if(bone->dist<=0.0f) bone->dist= 0.0f;
+ }
+ bone_version_238(&bone->childbase);
+ }
+}
+
static void do_versions(FileData *fd, Library *lib, Main *main)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
@@ -4854,6 +4870,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if(main->versionfile <= 238) {
Lattice *lt;
Object *ob;
+ bArmature *arm;
for (lt=main->latt.first; lt; lt=lt->id.next) {
if (lt->fu==0.0 && lt->fv==0.0 && lt->fw==0.0) {
@@ -4880,6 +4897,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ob->softflag &= ~OB_SB_ENABLE;
}
}
+
+ for(arm=main->armature.first; arm; arm= arm->id.next) {
+ bone_version_238(&arm->bonebase);
+ }
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h
index 73807dab5dc..6afe0903a21 100644
--- a/source/blender/include/BIF_editarmature.h
+++ b/source/blender/include/BIF_editarmature.h
@@ -43,7 +43,7 @@ typedef struct EditBone
struct EditBone *parent;/* Editbones have a one-way link (i.e. children refer
to parents. This is converted to a two-way link for
normal bones when leaving editmode. */
- void *temp; /* Used to store temporary data */
+ void *temp; /* Used to store temporary data */
char name[32];
float roll; /* Roll along axis. We'll ultimately use the axis/angle method
@@ -59,17 +59,14 @@ typedef struct EditBone
int flag;
int parNr; /* Used for retrieving values from the menu system */
- /* Storage for transformation data used by the posing system.
- Maybe a better solution would be to make bones a blenderObject
- variant? Or perhaps to use a TOTALLY custom transformation scheme
- for pose element, rather than trying to use the existing transObject
- system?
- */
+
float dist, weight;
float xwidth, length, zwidth; /* put them in order! transform uses this as scale */
float ease1, ease2;
+ float rad_head, rad_tail;
short boneclass, segments;
-
+
+ float oldlength; /* for envelope scaling */
} EditBone;
@@ -127,6 +124,10 @@ void armature_bone_rename(struct bArmature *arm, char *oldname, char *newname);
void armature_flip_names(void);
EditBone *armature_bone_get_mirrored(EditBone *ebo);
+void hide_selected_armature_bones(void);
+void hide_unselected_armature_bones(void);
+void show_all_armature_bones(void);
+
#define BONESEL_ROOT 0x10000000
#define BONESEL_TIP 0x20000000
#define BONESEL_BONE 0x40000000
diff --git a/source/blender/include/BIF_poseobject.h b/source/blender/include/BIF_poseobject.h
index 3b707ad8dcc..ec201437488 100644
--- a/source/blender/include/BIF_poseobject.h
+++ b/source/blender/include/BIF_poseobject.h
@@ -55,6 +55,8 @@ void free_posebuf(void);
void copy_posebuf (void);
void paste_posebuf (int flip);
+void pose_adds_vgroups(struct Object *meshobj);
+
void pose_flip_names(void);
#endif
diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h
index 4a161181a5c..cff4dea2e14 100755
--- a/source/blender/include/BIF_transform.h
+++ b/source/blender/include/BIF_transform.h
@@ -51,6 +51,7 @@
#define TFM_CREASE 13
#define TFM_MIRROR 14
#define TFM_BONESIZE 15
+#define TFM_BONE_ENVELOPE 16
/* TRANSFORM CONTEXTS */
#define CTX_NONE 0
diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h
index 7842d9cbd5f..4e6eaa7150c 100755
--- a/source/blender/include/transform.h
+++ b/source/blender/include/transform.h
@@ -254,6 +254,9 @@ int Crease(TransInfo *t, short mval[2]);
void initBoneSize(TransInfo *t);
int BoneSize(TransInfo *t, short mval[2]);
+void initBoneEnvelope(TransInfo *t);
+int BoneEnvelope(TransInfo *t, short mval[2]);
+
/*********************** transform_conversions.c ********** */
struct ListBase;
void count_bone_select(TransInfo *t, struct ListBase *lb, int do_it);
diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h
index f80414312db..7a5d7520fca 100644
--- a/source/blender/makesdna/DNA_action_types.h
+++ b/source/blender/makesdna/DNA_action_types.h
@@ -1,20 +1,12 @@
-/* DNA_action_types.h May 2001
- *
- * support for the "action" datatype
- *
- * Reevan McKay
- *
+/*
* $Id$
*
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License. See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -28,9 +20,10 @@
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
+ * Contributor(s): Original design: Reevan McKay
* Contributor(s): Full recode, Ton Roosendaal, Crete 2005
*
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
*/
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index 819b2843eda..013b42876a1 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -49,7 +49,7 @@ typedef struct Bone {
ListBase childbase; /* Children */
char name[32]; /* Name of the bone - must be unique within the armature */
- float roll, length; /* roll is input for editmode, length calculated */
+ float roll; /* roll is input for editmode, length calculated */
float head[3];
float tail[3]; /* head/tail and roll in Bone Space */
float bone_mat[3][3]; /* rotation derived from head/tail/roll */
@@ -60,9 +60,10 @@ typedef struct Bone {
float arm_tail[3]; /* head/tail and roll in Armature Space (rest pos) */
float arm_mat[4][4]; /* matrix: (bonemat(b)+head(b))*arm_mat(b-1), rest pos*/
- float dist, weight; /* dist, weight: for non-deformgroup deforms */
- float xwidth, zwidth; /* width: for block bones */
- float ease1, ease2; /* length of bezier handles */
+ float dist, weight; /* dist, weight: for non-deformgroup deforms */
+ float xwidth, length, zwidth; /* width: for block bones. keep in this order, transform! */
+ float ease1, ease2; /* length of bezier handles */
+ float rad_head, rad_tail; /* radius for head/tail sphere, defining deform as well */
float size[3]; /* patch for upward compat, UNUSED! */
short boneclass;
@@ -99,6 +100,7 @@ typedef struct bArmature {
#define ARM_OCTA 0
#define ARM_LINE 1
#define ARM_B_BONE 2
+#define ARM_ENVELOPE 3
/* bone->flag */
@@ -109,13 +111,16 @@ typedef struct bArmature {
#define BONE_TRANSFORM 8
#define BONE_IK_TOPARENT 16
/* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */
-#define BONE_HIDDEN 64
+ /* hidden Bones when drawing Posechannels */
+#define BONE_HIDDEN_P 64
/* For detecting cyclic dependancies */
#define BONE_DONE 128
/* active is on mouse clicks only */
#define BONE_ACTIVE 256
/* No parent rotation or scale */
#define BONE_HINGE 512
+ /* hidden Bones when drawing Armature Editmode */
+#define BONE_HIDDEN_A 1024
/* bone->flag bits */
#define BONE_IK_TOPARENTBIT 4
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index e69c646579c..3ad4742730c 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -448,28 +448,28 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
if(me->medge) val= 1.0; else val= 0.0;
uiDefBut(block, LABEL, 0, "Edges", 10,70,70,20, 0, val, 0, 0, 0, "");
if(me->medge==NULL) {
- uiDefBut(block, BUT, B_MAKEEDGES, "Make", 80,70,84,19, 0, 0, 0, 0, 0, "Adds edges data to active Mesh object, enables creases/seams and faster wireframe draw");
+ uiDefBut(block, BUT, B_MAKEEDGES, "Make", 80,70,84,19, 0, 0, 0, 0, 0, "Adds edges data to active Mesh, enables creases/seams and faster wireframe draw");
}
- else uiDefBut(block, BUT, B_DELEDGES, "Delete", 80,70,84,19, 0, 0, 0, 0, 0, "Deletes edges data from active Mesh object");
+ else uiDefBut(block, BUT, B_DELEDGES, "Delete", 80,70,84,19, 0, 0, 0, 0, 0, "Deletes edges data from active Mesh");
if(me->mcol) val= 1.0; else val= 0.0;
uiDefBut(block, LABEL, 0, "VertCol", 10,50,70,20, 0, val, 0, 0, 0, "");
if(me->mcol==NULL) {
- uiDefBut(block, BUT, B_MAKEVERTCOL, "Make", 80,50,84,19, 0, 0, 0, 0, 0, "Enables vertex colour painting on active object");
+ uiDefBut(block, BUT, B_MAKEVERTCOL, "Make", 80,50,84,19, 0, 0, 0, 0, 0, "Enables vertex colour painting on active Mesh");
}
- else uiDefBut(block, BUT, B_DELVERTCOL, "Delete", 80,50,84,19, 0, 0, 0, 0, 0, "Deletes vertex colours on active object");
+ else uiDefBut(block, BUT, B_DELVERTCOL, "Delete", 80,50,84,19, 0, 0, 0, 0, 0, "Deletes vertex colours on active Mesh");
if(me->tface) val= 1.0; else val= 0.0;
uiDefBut(block, LABEL, 0, "TexFace", 10,30,70,20, 0, val, 0, 0, 0, "");
if(me->tface==NULL) {
- uiDefBut(block, BUT, B_MAKE_TFACES, "Make", 80,30,84,19, 0, 0, 0, 0, 0, "Enables the active object's faces for UV coordinate mapping");
+ uiDefBut(block, BUT, B_MAKE_TFACES, "Make", 80,30,84,19, 0, 0, 0, 0, 0, "Enables the active Mesh's faces for UV coordinate mapping");
}
- else uiDefBut(block, BUT, B_DEL_TFACES, "Delete", 80,30,84,19, 0, 0, 0, 0, 0, "Deletes UV coordinates for active object's faces");
+ else uiDefBut(block, BUT, B_DEL_TFACES, "Delete", 80,30,84,19, 0, 0, 0, 0, 0, "Deletes UV coordinates for active Mesh's faces");
if(me->msticky) val= 1.0; else val= 0.0;
uiDefBut(block, LABEL, 0, "Sticky", 10,10,70,20, 0, val, 0, 0, 0, "");
if(me->msticky==NULL) {
- uiDefBut(block, BUT, B_MAKESTICKY, "Make", 80,10,84,19, 0, 0, 0, 0, 0, "Creates Sticky coordinates for the active object from the current camera view background picture");
+ uiDefBut(block, BUT, B_MAKESTICKY, "Make", 80,10,84,19, 0, 0, 0, 0, 0, "Creates Sticky coordinates for the active Mesh from the current camera view background picture");
}
else uiDefBut(block, BUT, B_DELSTICKY, "Delete", 80,10,84,19, 0, 0, 0, 0, 0, "Deletes Sticky texture coordinates");
@@ -2217,9 +2217,10 @@ static void editing_panel_armature_type(Object *ob, bArmature *arm)
uiButSetFunc(but, armature_recalc_func, ob, NULL);
uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform", 160, 180,150,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode");
uiBlockBeginAlign(block);
- uiDefButI(block, ROW, REDRAWVIEW3D, "Octahedron", 10, 140,100,20, &arm->drawtype, 0, ARM_OCTA, 0, 0, "Draw bone as octahedra");
- uiDefButI(block, ROW, REDRAWVIEW3D, "Sticks", 110, 140,100,20, &arm->drawtype, 0, ARM_LINE, 0, 0, "Draw bone as simple 2d lines with dots");
- uiDefButI(block, ROW, REDRAWVIEW3D, "B-Bones", 210, 140,100,20, &arm->drawtype, 0, ARM_B_BONE, 0, 0, "Draw bone as boxes, showing subdivision and b-splines");
+ uiDefButI(block, ROW, REDRAWVIEW3D, "Octahedron", 10, 140,75,20, &arm->drawtype, 0, ARM_OCTA, 0, 0, "Draw bones as octahedra");
+ uiDefButI(block, ROW, REDRAWVIEW3D, "Stick", 85, 140,70,20, &arm->drawtype, 0, ARM_LINE, 0, 0, "Draw bones as simple 2d lines with dots");
+ uiDefButI(block, ROW, REDRAWVIEW3D, "B-Bone", 155, 140,70,20, &arm->drawtype, 0, ARM_B_BONE, 0, 0, "Draw bones as boxes, showing subdivision and b-splines");
+ uiDefButI(block, ROW, REDRAWVIEW3D, "Envelope", 225, 140,85,20, &arm->drawtype, 0, ARM_ENVELOPE, 0, 0, "Draw bones as extruded spheres, showing deformation influence volume");
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 110,100,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
@@ -2286,7 +2287,7 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm)
uiDefButBitI(block, TOG, BONE_HINGE, REDRAWVIEW3D, "Hinge", bx-10,by-38,117,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone");
uiDefButBitS(block, TOGN, 1,REDRAWVIEW3D, "Skinnable", bx+110, by-38, 105, 18, &curBone->boneclass, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone is included in automatic creation of vertex groups");
/* Hide in posemode flag */
- uiDefButBitI(block, TOG, BONE_HIDDEN, REDRAWVIEW3D, "Hide", bx+223,by-38,110,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in posemode");
+ uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", bx+223,by-38,110,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode");
uiBlockEndAlign(block);
by-=60;
@@ -2346,7 +2347,7 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
uiButSetFunc(but, armature_recalc_func, ob, NULL);
uiDefButBitS(block, TOGN, 1,REDRAWVIEW3D, "Skinnable", bx+110, by-38, 105, 18, &curBone->boneclass, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone is included in automatic creation of vertex groups");
/* Hide in posemode flag */
- uiDefButBitI(block, TOG, BONE_HIDDEN, REDRAWVIEW3D, "Hide", bx+223,by-38,110,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in posemode");
+ uiDefButBitI(block, TOG, BONE_HIDDEN_P, REDRAWVIEW3D, "Hide", bx+223,by-38,110,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in posemode");
uiBlockEndAlign(block);
by-=60;
diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c
index aa2a01d37c3..55cd70c6959 100644
--- a/source/blender/src/drawarmature.c
+++ b/source/blender/src/drawarmature.c
@@ -372,6 +372,388 @@ static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id)
}
+/* 16 values of sin function (still same result!) */
+static float si[16] = {
+ 0.00000000,
+ 0.20129852, 0.39435585,
+ 0.57126821, 0.72479278,
+ 0.84864425, 0.93775213,
+ 0.98846832, 0.99871650,
+ 0.96807711, 0.89780453,
+ 0.79077573, 0.65137248,
+ 0.48530196, 0.29936312,
+ 0.10116832
+};
+/* 16 values of cos function (still same result!) */
+static float co[16] ={
+ 1.00000000,
+ 0.97952994, 0.91895781,
+ 0.82076344, 0.68896691,
+ 0.52896401, 0.34730525,
+ 0.15142777, -0.05064916,
+ -0.25065253, -0.44039415,
+ -0.61210598, -0.75875812,
+ -0.87434661, -0.95413925,
+ -0.99486932
+};
+
+
+
+/* smat, imat = mat & imat to draw screenaligned */
+static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag, bPoseChannel *pchan, EditBone *ebone)
+{
+ float head, tail, length, dist;
+ float *headvec, *tailvec, dirvec[3];
+
+ /* figure out the sizes of spheres */
+ if(ebone) {
+ /* this routine doesn't call set_matrix_editbone() that calculates it */
+ ebone->length = VecLenf(ebone->head, ebone->tail);
+
+ length= ebone->length;
+ tail= ebone->rad_tail;
+ dist= ebone->dist;
+ if (ebone->parent && (ebone->flag & BONE_IK_TOPARENT))
+ head= ebone->parent->rad_tail;
+ else
+ head= ebone->rad_head;
+ headvec= ebone->head;
+ tailvec= ebone->tail;
+ }
+ else {
+ length= pchan->bone->length;
+ tail= pchan->bone->rad_tail;
+ dist= pchan->bone->dist;
+ if (pchan->parent && (pchan->bone->flag & BONE_IK_TOPARENT))
+ head= pchan->parent->bone->rad_tail;
+ else
+ head= pchan->bone->rad_head;
+ headvec= pchan->pose_head;
+ tailvec= pchan->pose_tail;
+ }
+
+ /* ***** draw it ***** */
+
+ /* move vector to viewspace */
+ VecSubf(dirvec, tailvec, headvec);
+ Mat4Mul3Vecfl(smat, dirvec);
+ /* clear zcomp */
+ dirvec[2]= 0.0;
+ /* move vector back */
+ Mat4Mul3Vecfl(imat, dirvec);
+
+ if(0.0f != Normalise(dirvec)) {
+ float norvec[3], vec1[3], vec2[3], vec[3];
+ int a;
+
+ //VecMulf(dirvec, head);
+ Crossf(norvec, dirvec, imat[2]);
+
+ glBegin(GL_QUAD_STRIP);
+
+ for(a=0; a<16; a++) {
+ vec[0]= - *(si+a) * dirvec[0] + *(co+a) * norvec[0];
+ vec[1]= - *(si+a) * dirvec[1] + *(co+a) * norvec[1];
+ vec[2]= - *(si+a) * dirvec[2] + *(co+a) * norvec[2];
+
+ vec1[0]= headvec[0] + head*vec[0];
+ vec1[1]= headvec[1] + head*vec[1];
+ vec1[2]= headvec[2] + head*vec[2];
+ vec2[0]= headvec[0] + (head+dist)*vec[0];
+ vec2[1]= headvec[1] + (head+dist)*vec[1];
+ vec2[2]= headvec[2] + (head+dist)*vec[2];
+
+ glColor4ub(255, 255, 255, 50);
+ glVertex3fv(vec1);
+ //glColor4ub(255, 255, 255, 0);
+ glVertex3fv(vec2);
+ }
+
+ for(a=15; a>=0; a--) {
+ vec[0]= *(si+a) * dirvec[0] + *(co+a) * norvec[0];
+ vec[1]= *(si+a) * dirvec[1] + *(co+a) * norvec[1];
+ vec[2]= *(si+a) * dirvec[2] + *(co+a) * norvec[2];
+
+ vec1[0]= tailvec[0] + tail*vec[0];
+ vec1[1]= tailvec[1] + tail*vec[1];
+ vec1[2]= tailvec[2] + tail*vec[2];
+ vec2[0]= tailvec[0] + (tail+dist)*vec[0];
+ vec2[1]= tailvec[1] + (tail+dist)*vec[1];
+ vec2[2]= tailvec[2] + (tail+dist)*vec[2];
+
+ //glColor4ub(255, 255, 255, 50);
+ glVertex3fv(vec1);
+ //glColor4ub(255, 255, 255, 0);
+ glVertex3fv(vec2);
+ }
+ /* make it cyclic... */
+
+ vec[0]= - *(si) * dirvec[0] + *(co) * norvec[0];
+ vec[1]= - *(si) * dirvec[1] + *(co) * norvec[1];
+ vec[2]= - *(si) * dirvec[2] + *(co) * norvec[2];
+
+ vec1[0]= headvec[0] + head*vec[0];
+ vec1[1]= headvec[1] + head*vec[1];
+ vec1[2]= headvec[2] + head*vec[2];
+ vec2[0]= headvec[0] + (head+dist)*vec[0];
+ vec2[1]= headvec[1] + (head+dist)*vec[1];
+ vec2[2]= headvec[2] + (head+dist)*vec[2];
+
+ //glColor4ub(255, 255, 255, 50);
+ glVertex3fv(vec1);
+ //glColor4ub(255, 255, 255, 0);
+ glVertex3fv(vec2);
+
+ glEnd();
+ }
+}
+
+
+/* smat, imat = mat & imat to draw screenaligned */
+static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone)
+{
+ float head, tail, length;
+ float *headvec, *tailvec, dirvec[3];
+
+ /* figure out the sizes of spheres */
+ if(ebone) {
+ /* this routine doesn't call set_matrix_editbone() that calculates it */
+ ebone->length = VecLenf(ebone->head, ebone->tail);
+
+ length= ebone->length;
+ tail= ebone->rad_tail;
+ if (ebone->parent && (boneflag & BONE_IK_TOPARENT))
+ head= ebone->parent->rad_tail;
+ else
+ head= ebone->rad_head;
+ headvec= ebone->head;
+ tailvec= ebone->tail;
+ }
+ else {
+ length= pchan->bone->length;
+ tail= pchan->bone->rad_tail;
+ if (pchan->parent && (boneflag & BONE_IK_TOPARENT))
+ head= pchan->parent->bone->rad_tail;
+ else
+ head= pchan->bone->rad_head;
+ headvec= pchan->pose_head;
+ tailvec= pchan->pose_tail;
+ }
+
+ /* sphere root color */
+ if(armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
+ else BIF_ThemeColor(TH_VERTEX);
+ }
+ else if(armflag & ARM_POSEMODE) {
+ /* in black or selection color */
+ if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
+ else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
+ else BIF_ThemeColor(TH_WIRE);
+ }
+
+ /* Draw root point if we have no IK parent */
+ if (!(boneflag & BONE_IK_TOPARENT)){
+ if (id != -1)
+ glLoadName (id | BONESEL_ROOT);
+
+ drawcircball(GL_LINE_LOOP, headvec, head, imat);
+ }
+
+ /* Draw tip point */
+ if(armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
+ else BIF_ThemeColor(TH_VERTEX);
+ }
+
+ if (id != -1)
+ glLoadName (id | BONESEL_TIP);
+
+ drawcircball(GL_LINE_LOOP, tailvec, tail, imat);
+
+ /* base */
+ if(armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_SELECT);
+ else BIF_ThemeColor(TH_WIRE);
+ }
+
+ VecSubf(dirvec, tailvec, headvec);
+
+ /* move vector to viewspace */
+ Mat4Mul3Vecfl(smat, dirvec);
+ /* clear zcomp */
+ dirvec[2]= 0.0;
+ /* move vector back */
+ Mat4Mul3Vecfl(imat, dirvec);
+
+ if(0.0f != Normalise(dirvec)) {
+ float norvech[3], norvect[3], vec[3];
+
+ VECCOPY(vec, dirvec);
+
+ VecMulf(dirvec, head);
+ Crossf(norvech, dirvec, imat[2]);
+
+ VecMulf(vec, tail);
+ Crossf(norvect, vec, imat[2]);
+
+ if (id != -1)
+ glLoadName (id | BONESEL_BONE);
+
+ glBegin(GL_LINES);
+ vec[0]= headvec[0] + norvech[0];
+ vec[1]= headvec[1] + norvech[1];
+ vec[2]= headvec[2] + norvech[2];
+ glVertex3fv(vec);
+ vec[0]= tailvec[0] + norvect[0];
+ vec[1]= tailvec[1] + norvect[1];
+ vec[2]= tailvec[2] + norvect[2];
+ glVertex3fv(vec);
+ vec[0]= headvec[0] - norvech[0];
+ vec[1]= headvec[1] - norvech[1];
+ vec[2]= headvec[2] - norvech[2];
+ glVertex3fv(vec);
+ vec[0]= tailvec[0] - norvect[0];
+ vec[1]= tailvec[1] - norvect[1];
+ vec[2]= tailvec[2] - norvect[2];
+ glVertex3fv(vec);
+
+ glEnd();
+ }
+}
+
+/* does wire only for outline selecting */
+static void draw_sphere_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone)
+{
+ GLUquadricObj *qobj;
+ float head, tail, length;
+ float fac1, fac2;
+
+ glPushMatrix();
+ qobj = gluNewQuadric();
+
+ /* figure out the sizes of spheres */
+ if(ebone) {
+ length= ebone->length;
+ tail= ebone->rad_tail;
+ if (ebone->parent && (boneflag & BONE_IK_TOPARENT))
+ head= ebone->parent->rad_tail;
+ else
+ head= ebone->rad_head;
+ }
+ else {
+ length= pchan->bone->length;
+ tail= pchan->bone->rad_tail;
+ if (pchan->parent && (boneflag & BONE_IK_TOPARENT))
+ head= pchan->parent->bone->rad_tail;
+ else
+ head= pchan->bone->rad_head;
+ }
+
+ /* move to z-axis space */
+ glRotatef (-90.0f, 1.0f, 0.0f, 0.0f);
+
+ if(dt==OB_SOLID) {
+ /* set up solid drawing */
+ glEnable(GL_COLOR_MATERIAL);
+ glEnable(GL_LIGHTING);
+
+ gluQuadricDrawStyle(qobj, GLU_FILL);
+ glShadeModel(GL_SMOOTH);
+ }
+ else {
+ gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
+ }
+
+ /* sphere root color */
+ if(armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_ROOTSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
+ else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
+ }
+ else if(armflag & ARM_POSEMODE) {
+ if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 10);
+ else if (boneflag & BONE_SELECTED) BIF_ThemeColorShade(TH_BONE_POSE, -30);
+ else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
+
+ }
+ else if(dt==OB_SOLID)
+ BIF_ThemeColorShade(TH_BONE_SOLID, -30);
+
+ /* Draw root point if we have no IK parent */
+ if (!(boneflag & BONE_IK_TOPARENT)){
+ if (id != -1)
+ glLoadName (id | BONESEL_ROOT);
+ gluSphere( qobj, head, 16, 10);
+ }
+
+ /* Draw tip point */
+ if(armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_TIPSEL) BIF_ThemeColor(TH_VERTEX_SELECT);
+ else BIF_ThemeColorShade(TH_BONE_SOLID, -30);
+ }
+
+ if (id != -1)
+ glLoadName (id | BONESEL_TIP);
+
+ glTranslatef(0.0, 0.0, length);
+ gluSphere( qobj, tail, 16, 10);
+ glTranslatef(0.0, 0.0, -length);
+
+ /* base */
+ if(armflag & ARM_EDITMODE) {
+ if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_SELECT);
+ else BIF_ThemeColor(TH_BONE_SOLID);
+ }
+ else if(armflag & ARM_POSEMODE) {
+ if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40);
+ else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE);
+ else BIF_ThemeColor(TH_BONE_SOLID);
+
+ }
+ else if(dt==OB_SOLID)
+ BIF_ThemeColor(TH_BONE_SOLID);
+
+ fac1= (length-head)/length;
+ fac2= (length-tail)/length;
+
+ if(length > head+tail) {
+ if (id != -1)
+ glLoadName (id | BONESEL_BONE);
+
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(-1.0, -1.0);
+
+ glTranslatef(0.0f, 0.0f, head);
+ gluCylinder(qobj, fac1*head + (1.0f-fac1)*tail, fac2*tail + (1.0f-fac2)*head, length-head-tail, 16, 1);
+ glTranslatef(0.0f, 0.0f, -head);
+
+ glDisable(GL_POLYGON_OFFSET_FILL);
+
+ /* draw sphere on extrema */
+ glTranslatef(0.0f, 0.0f, length-tail);
+ gluSphere( qobj, fac2*tail + (1.0f-fac2)*head, 16, 10);
+ glTranslatef(0.0f, 0.0f, -length+tail);
+
+ glTranslatef(0.0f, 0.0f, head);
+ gluSphere( qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
+ }
+ else {
+ /* 1 sphere in center */
+ glTranslatef(0.0f, 0.0f, (head + length-tail)/2.0);
+ gluSphere( qobj, fac1*head + (1.0f-fac1)*tail, 16, 10);
+ }
+
+ /* restore */
+ if(dt==OB_SOLID) {
+ glShadeModel(GL_FLAT);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ }
+
+ glPopMatrix();
+ gluDeleteQuadric(qobj);
+}
+
static char bm_dot6[]= {0x0, 0x18, 0x3C, 0x7E, 0x7E, 0x3C, 0x18, 0x0};
static char bm_dot8[]= {0x3C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3C};
@@ -606,12 +988,14 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
}
}
-static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id)
+static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, float length)
{
/* Draw a 3d octahedral bone, we use normalized space based on length,
for glDisplayLists */
+ glScalef(length, length, length);
+
/* set up solid drawing */
if(dt > OB_WIRE) {
glEnable(GL_COLOR_MATERIAL);
@@ -688,40 +1072,69 @@ static void draw_pose_channels(Base *base, int dt)
bPoseChannel *pchan;
Bone *bone;
GLfloat tmp;
+ float smat[4][4], imat[4][4];
int index= -1;
int do_dashed= 1;
short flag, constflag;
- /* little speedup, also make sure transparent only draws once */
- glCullFace(GL_BACK);
- glEnable(GL_CULL_FACE);
-
/* hacky... prevent outline select from drawing dashed helplines */
glGetFloatv(GL_LINE_WIDTH, &tmp);
if(tmp > 1.1) do_dashed= 0;
+
+ /* precalc inverse matrix for drawing screen aligned */
+ if(arm->drawtype==ARM_ENVELOPE) {
+ /* precalc inverse matrix for drawing screen aligned */
+ mygetmatrix(smat);
+ Mat4MulFloat3(smat[0], 1.0f/VecLength(ob->obmat[0]));
+ Mat4Invert(imat, smat);
+ /* and draw blended distances */
+ if(arm->flag & ARM_POSEMODE) {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ //glShadeModel(GL_SMOOTH);
+
+ if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ bone= pchan->bone;
+ if(bone && !(bone->flag & BONE_HIDDEN_P)) {
+ if(bone->flag & (BONE_SELECTED))
+ draw_sphere_bone_dist(smat, imat, bone->flag, pchan, NULL);
+ }
+ }
+
+ if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ glDisable(GL_BLEND);
+ //glShadeModel(GL_FLAT);
+ }
+ }
+
+ /* little speedup, also make sure transparent only draws once */
+ glCullFace(GL_BACK);
+ glEnable(GL_CULL_FACE);
+
/* if solid we draw that first, with selection codes, but without names, axes etc */
if(dt>OB_WIRE && arm->drawtype!=ARM_LINE) {
if(arm->flag & ARM_POSEMODE) index= base->selcol;
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
bone= pchan->bone;
- if(bone && !(bone->flag & BONE_HIDDEN)) {
+ if(bone && !(bone->flag & BONE_HIDDEN_P)) {
glPushMatrix();
glMultMatrixf(pchan->pose_mat);
/* catch exception for bone with hidden parent */
flag= bone->flag;
- if(bone->parent && (bone->parent->flag & BONE_HIDDEN))
+ if(bone->parent && (bone->parent->flag & BONE_HIDDEN_P))
flag &= ~BONE_IK_TOPARENT;
- if(arm->drawtype==ARM_B_BONE)
+ if(arm->drawtype==ARM_ENVELOPE)
+ draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
+ else if(arm->drawtype==ARM_B_BONE)
draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
else {
- /* scale the matrix to unit bone space */
- glScalef(bone->length, bone->length, bone->length);
-
- draw_bone(OB_SOLID, arm->flag, flag, 0, index);
+ draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length);
}
glPopMatrix();
}
@@ -747,7 +1160,7 @@ static void draw_pose_channels(Base *base, int dt)
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
bone= pchan->bone;
- if(bone && !(bone->flag & BONE_HIDDEN)) {
+ if(bone && !(bone->flag & BONE_HIDDEN_P)) {
// Draw a line from our root to the parent's tip
if (do_dashed && bone->parent && !(bone->flag & BONE_IK_TOPARENT) ){
@@ -763,12 +1176,14 @@ static void draw_pose_channels(Base *base, int dt)
setlinestyle(0);
}
- glPushMatrix();
- glMultMatrixf(pchan->pose_mat);
+ if(arm->drawtype!=ARM_ENVELOPE) {
+ glPushMatrix();
+ glMultMatrixf(pchan->pose_mat);
+ }
/* catch exception for bone with hidden parent */
flag= bone->flag;
- if(bone->parent && (bone->parent->flag & BONE_HIDDEN))
+ if(bone->parent && (bone->parent->flag & BONE_HIDDEN_P))
flag &= ~BONE_IK_TOPARENT;
/* extra draw service for pose mode */
@@ -776,18 +1191,20 @@ static void draw_pose_channels(Base *base, int dt)
if(pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE))
constflag |= PCHAN_HAS_ACTION;
- if(arm->drawtype==ARM_LINE)
+ if(arm->drawtype==ARM_ENVELOPE) {
+ if(dt<OB_SOLID)
+ draw_sphere_bone_wire(smat, imat, arm->flag, flag, constflag, index, pchan, NULL);
+ }
+ else if(arm->drawtype==ARM_LINE)
draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL);
else if(arm->drawtype==ARM_B_BONE)
draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL);
else {
- /* scale the matrix to unit bone space */
- glScalef(bone->length, bone->length, bone->length);
-
- draw_bone(OB_WIRE, arm->flag, flag, constflag, index);
+ draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length);
}
- glPopMatrix();
+ if(arm->drawtype!=ARM_ENVELOPE)
+ glPopMatrix();
}
if (index!= -1) index+= 0x10000; // pose bones count in higher 2 bytes only
}
@@ -864,24 +1281,58 @@ static void draw_ebones(Object *ob, int dt)
{
EditBone *eBone;
bArmature *arm= ob->data;
+ float smat[4][4], imat[4][4];
unsigned int index;
+ int flag;
+
+ /* envelope (deform distance) */
+ if(arm->drawtype==ARM_ENVELOPE) {
+ /* precalc inverse matrix for drawing screen aligned */
+ mygetmatrix(smat);
+ Mat4MulFloat3(smat[0], 1.0f/VecLength(ob->obmat[0]));
+ Mat4Invert(imat, smat);
+
+ /* and draw blended distances */
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ //glShadeModel(GL_SMOOTH);
+
+ if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
+
+ for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
+ if(!(eBone->flag & BONE_HIDDEN_A))
+ if(eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL))
+ draw_sphere_bone_dist(smat, imat, eBone->flag, NULL, eBone);
+ }
+
+ if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
+ glDisable(GL_BLEND);
+ //glShadeModel(GL_FLAT);
+ }
/* if solid we draw it first */
if(dt>OB_WIRE && arm->drawtype!=ARM_LINE) {
index= 0;
for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
- glPushMatrix();
- set_matrix_editbone(eBone);
-
- if(arm->drawtype==ARM_B_BONE)
- draw_b_bone(OB_SOLID, arm->flag, eBone->flag, 0, index, NULL, eBone);
- else {
- /* scale the matrix to unit bone space */
- glScalef(eBone->length, eBone->length, eBone->length);
- draw_bone(OB_SOLID, arm->flag, eBone->flag, 0, index);
+ if(!(eBone->flag & BONE_HIDDEN_A)) {
+ glPushMatrix();
+ set_matrix_editbone(eBone);
+
+ /* catch exception for bone with hidden parent */
+ flag= eBone->flag;
+ if(eBone->parent && (eBone->parent->flag & BONE_HIDDEN_A))
+ flag &= ~BONE_IK_TOPARENT;
+
+ if(arm->drawtype==ARM_ENVELOPE)
+ draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
+ else if(arm->drawtype==ARM_B_BONE)
+ draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
+ else {
+ draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length);
+ }
+
+ glPopMatrix();
}
-
- glPopMatrix();
}
}
@@ -897,36 +1348,47 @@ static void draw_ebones(Object *ob, int dt)
index= 0; // do selection codes
for (eBone=G.edbo.first; eBone; eBone=eBone->next){
-
- glPushMatrix();
- set_matrix_editbone(eBone);
-
- if(arm->drawtype==ARM_LINE)
- draw_line_bone(arm->flag, eBone->flag, 0, index, NULL, eBone);
- else if(arm->drawtype==ARM_B_BONE)
- draw_b_bone(OB_WIRE, arm->flag, eBone->flag, 0, index, NULL, eBone);
- else {
- /* scale the matrix to unit bone space */
- glScalef(eBone->length, eBone->length, eBone->length);
- draw_bone(OB_WIRE, arm->flag, eBone->flag, 0, index);
- }
- if(arm->flag & ARM_DRAWAXES)
- drawaxes(0.25f);
-
- glPopMatrix();
-
- /* offset to parent */
- if (eBone->parent) {
- BIF_ThemeColor(TH_WIRE);
- glLoadName (-1); // -1 here is OK!
- setlinestyle(3);
+ if(!(eBone->flag & BONE_HIDDEN_A)) {
- glBegin(GL_LINES);
- glVertex3fv(eBone->parent->tail);
- glVertex3fv(eBone->head);
- glEnd();
+ /* catch exception for bone with hidden parent */
+ flag= eBone->flag;
+ if(eBone->parent && (eBone->parent->flag & BONE_HIDDEN_A))
+ flag &= ~BONE_IK_TOPARENT;
- setlinestyle(0);
+ if(arm->drawtype==ARM_ENVELOPE) {
+ if(dt<OB_SOLID)
+ draw_sphere_bone_wire(smat, imat, arm->flag, flag, 0, index, NULL, eBone);
+ }
+ else {
+ glPushMatrix();
+ set_matrix_editbone(eBone);
+
+ if(arm->drawtype==ARM_LINE)
+ draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
+ else if(arm->drawtype==ARM_B_BONE)
+ draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone);
+ else
+ draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length);
+
+ if(arm->flag & ARM_DRAWAXES)
+ drawaxes(0.25f);
+
+ glPopMatrix();
+ }
+
+ /* offset to parent */
+ if (eBone->parent) {
+ BIF_ThemeColor(TH_WIRE);
+ glLoadName (-1); // -1 here is OK!
+ setlinestyle(3);
+
+ glBegin(GL_LINES);
+ glVertex3fv(eBone->parent->tail);
+ glVertex3fv(eBone->head);
+ glEnd();
+
+ setlinestyle(0);
+ }
}
if(index!=-1) index++;
}
@@ -944,20 +1406,21 @@ static void draw_ebones(Object *ob, int dt)
if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
-
- if(eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
- else BIF_ThemeColor(TH_TEXT);
-
- VecMidf(vec, eBone->head, eBone->tail);
- glRasterPos3fv(vec);
- BMF_DrawString(G.font, " ");
- BMF_DrawString(G.font, eBone->name);
+ if(!(eBone->flag & BONE_HIDDEN_A)) {
+
+ if(eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI);
+ else BIF_ThemeColor(TH_TEXT);
+
+ VecMidf(vec, eBone->head, eBone->tail);
+ glRasterPos3fv(vec);
+ BMF_DrawString(G.font, " ");
+ BMF_DrawString(G.font, eBone->name);
+ }
}
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
}
}
-
}
/* called from drawobject.c */
@@ -966,9 +1429,16 @@ void draw_armature(Base *base, int dt)
Object *ob= base->object;
bArmature *arm= ob->data;
- /* we use color for solid lighting */
- glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
- glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); // only for lighting...
+ if(dt>OB_WIRE) {
+ /* we use color for solid lighting */
+ glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
+ glEnable(GL_COLOR_MATERIAL);
+ glColor3ub(0,0,0); // clear spec
+ glDisable(GL_COLOR_MATERIAL);
+
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); // only for lighting...
+ }
/* arm->flag is being used to detect mode... */
/* editmode? */
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index 9db631cc3f7..16b7a52937c 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -163,8 +163,10 @@ static void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
eBone->zwidth= curBone->zwidth;
eBone->ease1= curBone->ease1;
eBone->ease2= curBone->ease2;
+ eBone->rad_head= curBone->rad_head;
+ eBone->rad_tail= curBone->rad_tail;
eBone->segments = curBone->segments;
- eBone->boneclass = curBone->boneclass;
+ eBone->boneclass = curBone->boneclass;
BLI_addtail (list, eBone);
@@ -256,6 +258,8 @@ static void editbones_to_armature (ListBase *list, Object *ob)
newBone->zwidth = eBone->zwidth;
newBone->ease1= eBone->ease1;
newBone->ease2= eBone->ease2;
+ newBone->rad_head= eBone->rad_head;
+ newBone->rad_tail= eBone->rad_tail;
newBone->segments= eBone->segments;
newBone->boneclass = eBone->boneclass;
@@ -1162,11 +1166,11 @@ static EditBone *add_editbone(void)
{
EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
- BLI_addtail(&G.edbo, bone);
-
strcpy (bone->name,"Bone");
unique_editbone_name (bone->name);
+ BLI_addtail(&G.edbo, bone);
+
bone->flag |= BONE_TIPSEL;
bone->weight= 1.0F;
bone->dist= 1.0F;
@@ -1174,6 +1178,8 @@ static EditBone *add_editbone(void)
bone->zwidth= 0.1;
bone->ease1= 1.0;
bone->ease2= 1.0;
+ bone->rad_head= 0.25;
+ bone->rad_tail= 0.1;
bone->segments= 1;
bone->boneclass = BONE_SKINNABLE;
@@ -1381,6 +1387,55 @@ void adduplicate_armature(void)
/* *************** END Adding stuff in editmode *************** */
/* *************** Tools in editmode *********** */
+
+void hide_selected_armature_bones(void)
+{
+ EditBone *ebone;
+
+ for (ebone = G.edbo.first; ebone; ebone=ebone->next){
+ if(ebone->flag & (BONE_SELECTED)) {
+ ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
+ ebone->flag |= BONE_HIDDEN_A;
+ }
+ }
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+}
+
+void hide_unselected_armature_bones(void)
+{
+ EditBone *ebone;
+
+ for (ebone = G.edbo.first; ebone; ebone=ebone->next){
+ if(ebone->flag & (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL));
+ else {
+ ebone->flag &= ~BONE_ACTIVE;
+ ebone->flag |= BONE_HIDDEN_A;
+ }
+ }
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+}
+
+void show_all_armature_bones(void)
+{
+ EditBone *ebone;
+
+ for (ebone = G.edbo.first; ebone; ebone=ebone->next){
+ if(ebone->flag & BONE_HIDDEN_A) {
+ ebone->flag |= (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
+ ebone->flag &= ~BONE_HIDDEN_A;
+ }
+ }
+ countall();
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+}
+
+
+
/* the "IK" button in editbuttons */
void attach_bone_to_parent_cb(void *bonev, void *arg2_unused)
{
@@ -1558,13 +1613,34 @@ void extrude_armature(int forked)
{
bArmature *arm= G.obedit->data;
EditBone *newbone, *ebone, *flipbone, *first=NULL, *partest;
- int a, totbone= 0;
+ int a, totbone= 0, do_extrude;
TEST_EDITARMATURE;
+ /* since we allow root extrude too, we have to make sure selection is OK */
+ for (ebone = G.edbo.first; ebone; ebone=ebone->next){
+ if(ebone->flag & BONE_ROOTSEL) {
+ if(ebone->parent && (ebone->flag & BONE_IK_TOPARENT)) {
+ if(ebone->parent->flag & BONE_TIPSEL)
+ ebone->flag &= ~BONE_ROOTSEL;
+ }
+ }
+ }
+
/* Duplicate the necessary bones */
for (ebone = G.edbo.first; ((ebone) && (ebone!=first)); ebone=ebone->next){
- if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED)) {
+
+ /* we extrude per definition the tip */
+ do_extrude= 0;
+ if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED))
+ do_extrude= 1;
+ else if(ebone->flag & BONE_ROOTSEL) {
+ /* but, a bone with parent deselected we do the root... */
+ if(ebone->parent && (ebone->parent->flag & BONE_TIPSEL));
+ else do_extrude= 2;
+ }
+
+ if (do_extrude) {
/* we re-use code for mirror editing... */
flipbone= NULL;
@@ -1572,7 +1648,7 @@ void extrude_armature(int forked)
flipbone= armature_bone_get_mirrored(ebone);
if (flipbone) {
forked= 0; // we extrude 2 different bones
- if(flipbone->flag & (BONE_TIPSEL|BONE_SELECTED))
+ if(flipbone->flag & (BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED))
/* don't want this bone to be selected... */
flipbone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
}
@@ -1592,29 +1668,43 @@ void extrude_armature(int forked)
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
+ if(do_extrude==1) {
+ 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
+ }
+ else {
+ VECCOPY(newbone->head, ebone->head);
+ VECCOPY(newbone->tail, ebone->head);
+ newbone->parent= ebone->parent;
+
+ newbone->flag= BONE_TIPSEL;
+ }
+
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->rad_head= ebone->rad_tail; // dont copy entire bone...
+ newbone->rad_tail= ebone->rad_tail;
+ newbone->segments= 1;
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(do_extrude==1) {
+ 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;
}
- if (!partest)
- newbone->flag |= BONE_IK_TOPARENT;
-
strcpy (newbone->name, ebone->name);
if(flipbone && forked) { // only set if mirror edit
@@ -1771,7 +1861,7 @@ static void deselect_bonechildren (Object *ob, Bone *bone, int mode)
if (mode==0)
bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
else if (mode==1) {
- if(!(bone->flag & BONE_HIDDEN))
+ if(!(bone->flag & BONE_HIDDEN_P))
bone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
}
else bone->flag &= ~BONE_ACTIVE;
@@ -2000,12 +2090,15 @@ static void add_verts_to_closest_dgroup(Object *ob, Object *par)
* on the subsurf limit surface is used to generate
* the weights rather than the verts on the cage
* mesh.
+ *
+ * ("Limit surface" = same amount of vertices as mesh, but vertices
+ * moved to the subsurfed position, like for 'optimal').
*/
bArmature *arm;
Bone **bonelist, **bonehandle, *bone;
bDeformGroup **dgrouplist, **dgrouphandle, *defgroup;
- float *distance, mindist = 0.0, weight = 0.0;
+ float *distance;
float root[3];
float tip[3];
float real_co[3];
@@ -2043,7 +2136,7 @@ static void add_verts_to_closest_dgroup(Object *ob, Object *par)
dgroup_skinnable);
/* create an array of floats that will be used for each vert
- * to hold the distance to each bone.
+ * to hold the distance-factor to each bone.
*/
distance = MEM_mallocN(numbones*sizeof(float), "distance");
@@ -2087,21 +2180,10 @@ static void add_verts_to_closest_dgroup(Object *ob, Object *par)
VECCOPY(tip, bone->arm_tail);
Mat4MulVecfl(par->obmat, tip);
- /* store the distance from the bone to
- * the vert
- */
- distance[j] = dist_to_bone(real_co, root, tip);
-
- /* if this is the first bone, or if this
- * bone is less than mindist, then set this
- * distance to mindist
+ /* store the distance-factor from the vertex to
+ * the bone
*/
- if (j == 0) {
- mindist = distance[j];
- }
- else if (distance[j] < mindist) {
- mindist = distance[j];
- }
+ distance[j]= distfactor_to_bone (real_co, root, tip, bone->rad_head, bone->rad_tail, bone->dist);
}
/* for each deform group ...
@@ -2109,31 +2191,12 @@ static void add_verts_to_closest_dgroup(Object *ob, Object *par)
for (j=0; j < numbones; ++j) {
defgroup = dgrouplist[j];
- /* if the cooresponding bone is the closest one
- * add the vert to the deform group with weight 1
+ /* add the vert to the deform group if weight!=0.0
*/
- if (distance[j] <= mindist) {
- add_vert_to_defgroup (ob, defgroup, i, 1.0, WEIGHT_REPLACE);
- }
-
- /* if the cooresponding bone is within 10% of the
- * nearest distance, add the vert to the
- * deform group with a weight that declines with
- * distance
- */
- else if (distance[j] <= mindist*1.10) {
- if (mindist > 0)
- weight = 1.0 - (distance[j] - mindist) / (mindist * 0.10);
- add_vert_to_defgroup (ob, defgroup, i, weight, WEIGHT_REPLACE);
- }
-
- /* if the cooresponding bone is outside of the 10% tolerance
- * then remove the vert from the weight group (if it is
- * in that group)
- */
- else {
+ if (distance[j]!=0.0)
+ add_vert_to_defgroup (ob, defgroup, i, distance[j], WEIGHT_REPLACE);
+ else
remove_vert_defgroup (ob, defgroup, i);
- }
}
}
@@ -2191,7 +2254,7 @@ void create_vgroups_from_armature(Object *ob, Object *par)
static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr)
{
if (bone->flag & BONE_SELECTED) {
- bone->flag |= BONE_HIDDEN;
+ bone->flag |= BONE_HIDDEN_P;
bone->flag &= ~BONE_SELECTED;
}
return 0;
@@ -2211,12 +2274,13 @@ void hide_selected_pose_bones(void)
hide_selected_pose_bone);
allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
}
static int hide_unselected_pose_bone(Object *ob, Bone *bone, void *ptr)
{
if (~bone->flag & BONE_SELECTED) {
- bone->flag |= BONE_HIDDEN;
+ bone->flag |= BONE_HIDDEN_P;
}
return 0;
}
@@ -2235,12 +2299,13 @@ void hide_unselected_pose_bones(void)
hide_unselected_pose_bone);
allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
}
static int show_pose_bone(Object *ob, Bone *bone, void *ptr)
{
- if (bone->flag & BONE_HIDDEN) {
- bone->flag &= ~BONE_HIDDEN;
+ if (bone->flag & BONE_HIDDEN_P) {
+ bone->flag &= ~BONE_HIDDEN_P;
bone->flag |= BONE_SELECTED;
}
@@ -2261,6 +2326,7 @@ void show_all_pose_bones(void)
show_pose_bone);
allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
}
@@ -2317,86 +2383,90 @@ void armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
char newname[MAXBONENAME];
char oldname[MAXBONENAME];
- /* we alter newname string... so make copy */
- BLI_strncpy(newname, newnamep, MAXBONENAME);
- /* we use oldname for search... so make copy */
- BLI_strncpy(oldname, oldnamep, MAXBONENAME);
-
- /* now check if we're in editmode, we need to find the unique name */
- if(G.obedit && G.obedit->data==arm) {
- EditBone *eBone;
-
- eBone= editbone_name_exists(oldname);
- if(eBone) {
- unique_editbone_name (newname);
- BLI_strncpy(eBone->name, newname, MAXBONENAME);
+ /* names better differ! */
+ if(strncmp(oldnamep, newnamep, MAXBONENAME)) {
+
+ /* we alter newname string... so make copy */
+ BLI_strncpy(newname, newnamep, MAXBONENAME);
+ /* we use oldname for search... so make copy */
+ BLI_strncpy(oldname, oldnamep, MAXBONENAME);
+
+ /* now check if we're in editmode, we need to find the unique name */
+ if(G.obedit && G.obedit->data==arm) {
+ EditBone *eBone;
+
+ eBone= editbone_name_exists(oldname);
+ if(eBone) {
+ unique_editbone_name (newname);
+ BLI_strncpy(eBone->name, newname, MAXBONENAME);
+ }
+ else return;
}
- else return;
- }
- else {
- Bone *bone= get_named_bone (arm, oldname);
+ else {
+ Bone *bone= get_named_bone (arm, oldname);
- if(bone) {
- unique_bone_name (arm, newname);
- BLI_strncpy(bone->name, newname, MAXBONENAME);
- }
- else return;
- }
-
- /* do entire dbase */
- for(ob= G.main->object.first; ob; ob= ob->id.next) {
- /* we have the object using the armature */
- if(arm==ob->data) {
- Object *cob;
- bAction *act;
- bActionChannel *chan;
-
- /* Rename action channel if necessary */
- act = ob->action;
- if (act && !act->id.lib){
- /* Find the appropriate channel */
- chan= get_named_actionchannel(act, oldname);
- if(chan) BLI_strncpy(chan->name, newname, MAXBONENAME);
+ if(bone) {
+ unique_bone_name (arm, newname);
+ BLI_strncpy(bone->name, newname, MAXBONENAME);
}
-
- /* Rename the pose channel, if it exists */
- if (ob->pose) {
- bPoseChannel *pchan = get_pose_channel(ob->pose, oldname);
- if (pchan) {
- BLI_strncpy (pchan->name, newname, MAXBONENAME);
+ else return;
+ }
+
+ /* do entire dbase */
+ for(ob= G.main->object.first; ob; ob= ob->id.next) {
+ /* we have the object using the armature */
+ if(arm==ob->data) {
+ Object *cob;
+ bAction *act;
+ bActionChannel *chan;
+
+ /* Rename action channel if necessary */
+ act = ob->action;
+ if (act && !act->id.lib){
+ /* Find the appropriate channel */
+ chan= get_named_actionchannel(act, oldname);
+ if(chan) BLI_strncpy(chan->name, newname, MAXBONENAME);
}
- }
-
- /* and actually do the NLA too */
- /* (todo) */
-
- /* Update any object constraints to use the new bone name */
- for(cob= G.main->object.first; cob; cob= cob->id.next) {
- if(cob->constraints.first)
- constraint_bone_name_fix(ob, &cob->constraints, oldname, newname);
- if (cob->pose) {
- bPoseChannel *pchan;
- for (pchan = cob->pose->chanbase.first; pchan; pchan=pchan->next) {
- constraint_bone_name_fix(ob, &pchan->constraints, oldname, newname);
+
+ /* Rename the pose channel, if it exists */
+ if (ob->pose) {
+ bPoseChannel *pchan = get_pose_channel(ob->pose, oldname);
+ if (pchan) {
+ BLI_strncpy (pchan->name, newname, MAXBONENAME);
+ }
+ }
+
+ /* and actually do the NLA too */
+ /* (todo) */
+
+ /* Update any object constraints to use the new bone name */
+ for(cob= G.main->object.first; cob; cob= cob->id.next) {
+ if(cob->constraints.first)
+ constraint_bone_name_fix(ob, &cob->constraints, oldname, newname);
+ if (cob->pose) {
+ bPoseChannel *pchan;
+ for (pchan = cob->pose->chanbase.first; pchan; pchan=pchan->next) {
+ constraint_bone_name_fix(ob, &pchan->constraints, oldname, newname);
+ }
}
}
- }
-
- }
- /* See if an object is parented to this armature */
- if (ob->parent && (ob->parent->data == arm)) {
- if(ob->partype==PARBONE) {
- /* bone name in object */
- if (!strcmp(ob->parsubstr, oldname))
- BLI_strncpy(ob->parsubstr, newname, MAXBONENAME);
}
- else if(ob->partype==PARSKEL) {
- bDeformGroup *dg;
- /* bone name in defgroup */
- for (dg=ob->defbase.first; dg; dg=dg->next) {
- if(!strcmp(dg->name, oldname))
- BLI_strncpy(dg->name, newname, MAXBONENAME);
+
+ /* See if an object is parented to this armature */
+ if (ob->parent && (ob->parent->data == arm)) {
+ if(ob->partype==PARBONE) {
+ /* bone name in object */
+ if (!strcmp(ob->parsubstr, oldname))
+ BLI_strncpy(ob->parsubstr, newname, MAXBONENAME);
+ }
+ else if(ob->partype==PARSKEL) {
+ bDeformGroup *dg;
+ /* bone name in defgroup */
+ for (dg=ob->defbase.first; dg; dg=dg->next) {
+ if(!strcmp(dg->name, oldname))
+ BLI_strncpy(dg->name, newname, MAXBONENAME);
+ }
}
}
}
diff --git a/source/blender/src/editdeform.c b/source/blender/src/editdeform.c
index f600c8e5537..053151e5c4b 100644
--- a/source/blender/src/editdeform.c
+++ b/source/blender/src/editdeform.c
@@ -193,9 +193,16 @@ void del_defgroup (Object *ob)
/* Update the active material index if necessary */
if (ob->actdef==BLI_countlist(&ob->defbase))
ob->actdef--;
-
+
/* Remove the group */
BLI_freelinkN (&ob->defbase, defgroup);
+
+ /* remove all dverts */
+ if(ob->actdef==0) {
+ Mesh *me= ob->data;
+ free_dverts(me->dvert, me->totvert);
+ me->dvert= NULL;
+ }
}
void create_dverts(Mesh *me)
@@ -288,8 +295,11 @@ void add_vert_defnr (Object *ob, int def_nr, int vertnum,
/* get the vert
*/
- dv = ((Mesh*)ob->data)->dvert + vertnum;
-
+ if(((Mesh*)ob->data)->dvert)
+ dv = ((Mesh*)ob->data)->dvert + vertnum;
+ else
+ return;
+
/* Lets first check to see if this vert is
* already in the weight group -- if so
* lets update it
diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c
index 04195d14cbf..aef790fa439 100644
--- a/source/blender/src/editmesh.c
+++ b/source/blender/src/editmesh.c
@@ -976,7 +976,9 @@ void load_editMesh(void)
if(G.totface==0) mface= NULL;
else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh face");
- if (G.totvert==0 || me->dvert==NULL) dvert= NULL;
+ /* are we adding dverts? */
+ if (G.totvert==0) dvert= NULL;
+ else if(G.obedit->defbase.first==NULL) dvert= NULL;
else dvert = MEM_callocN(G.totvert*sizeof(MDeformVert), "loadeditMesh3");
if (me->dvert) free_dverts(me->dvert, me->totvert);
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index eea9130ae04..f9ea1bd687e 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -1953,6 +1953,13 @@ void special_editmenu(void)
BIF_undo_push("Shared VertexCol");
}
}
+ else if(G.f & G_WEIGHTPAINT) {
+ if(ob->parent && (ob->parent->flag & OB_POSEMODE)) {
+ nr= pupmenu("Specials%t|Apply Bone Envelopes to VertexGroups %x1");
+ if(nr==1)
+ pose_adds_vgroups(ob);
+ }
+ }
else {
Base *base, *base_select= NULL;
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index 6f2d48b0ef0..fa26a05f386 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -3644,7 +3644,6 @@ static char *view3d_modeselect_pup(void)
sprintf(tempstr, formatstr, "Texture Paint", V3D_TEXTUREPAINTMODE_SEL, ICON_TPAINT_HLT);
strcat(string, tempstr);
-
if ( ((Mesh*)(ob->data))->dvert) {
sprintf(tempstr, formatstr, "Weight Paint", V3D_WEIGHTPAINTMODE_SEL, ICON_WPAINT_HLT);
strcat(string, tempstr);
@@ -3704,6 +3703,7 @@ static char *propfalloff_pup(void)
void do_view3d_buttons(short event)
{
+ Object *ob= OBACT;
int bit;
/* watch it: if curarea->win does not exist, check that when calling direct drawing routines */
@@ -3778,7 +3778,6 @@ void do_view3d_buttons(short event)
case B_MODESELECT:
if (G.vd->modeselect == V3D_OBJECTMODE_SEL) {
- Object *ob= OBACT;
G.vd->flag &= ~V3D_MODE;
G.f &= ~G_VERTEXPAINT; /* Switch off vertex paint */
@@ -3837,7 +3836,7 @@ void do_view3d_buttons(short event)
}
}
else if (G.vd->modeselect == V3D_WEIGHTPAINTMODE_SEL) {
- if (!(G.f & G_WEIGHTPAINT) && (OBACT && OBACT->type == OB_MESH) && ((((Mesh*)(OBACT->data))->dvert))) {
+ if (!(G.f & G_WEIGHTPAINT) && (ob && ob->type == OB_MESH) && ((((Mesh*)(ob->data))->dvert))) {
G.vd->flag &= ~V3D_MODE;
G.f &= ~G_VERTEXPAINT; /* Switch off vertex paint */
G.f &= ~G_TEXTUREPAINT; /* Switch off texture paint */
@@ -3847,7 +3846,6 @@ void do_view3d_buttons(short event)
}
}
else if (G.vd->modeselect == V3D_POSEMODE_SEL) {
- Object *ob= OBACT;
if (ob && !(ob->flag & OB_POSEMODE)) {
G.vd->flag &= ~V3D_MODE;
@@ -3944,6 +3942,7 @@ void do_view3d_buttons(short event)
static void view3d_header_pulldowns(uiBlock *block, short *xcoord)
{
+ Object *ob= OBACT;
short xmax, xco= *xcoord;
/* pull down menus */
@@ -3966,27 +3965,26 @@ static void view3d_header_pulldowns(uiBlock *block, short *xcoord)
xmax= GetButStringLength("Select");
if (G.obedit) {
- if (OBACT && OBACT->type == OB_MESH) {
+ if (ob && ob->type == OB_MESH) {
uiDefPulldownBut(block, view3d_select_meshmenu, NULL, "Select", xco,-2, xmax-3, 24, "");
- } else if (OBACT && (OBACT->type == OB_CURVE || OBACT->type == OB_SURF)) {
+ } else if (ob && (ob->type == OB_CURVE || ob->type == OB_SURF)) {
uiDefPulldownBut(block, view3d_select_curvemenu, NULL, "Select", xco,-2, xmax-3, 24, "");
- } else if (OBACT && OBACT->type == OB_FONT) {
+ } else if (ob && ob->type == OB_FONT) {
uiDefPulldownBut(block, view3d_select_meshmenu, NULL, "Select", xco, -2, xmax-3, 24, "");
- } else if (OBACT && OBACT->type == OB_MBALL) {
+ } else if (ob && ob->type == OB_MBALL) {
uiDefPulldownBut(block, view3d_select_metaballmenu, NULL, "Select", xco,-2, xmax-3, 24, "");
- } else if (OBACT && OBACT->type == OB_LATTICE) {
+ } else if (ob && ob->type == OB_LATTICE) {
uiDefPulldownBut(block, view3d_select_latticemenu, NULL, "Select", xco,-2, xmax-3, 24, "");
- } else if (OBACT && OBACT->type == OB_ARMATURE) {
+ } else if (ob && ob->type == OB_ARMATURE) {
uiDefPulldownBut(block, view3d_select_armaturemenu, NULL, "Select", xco,-2, xmax-3, 24, "");
}
} else if (G.f & G_FACESELECT) {
- if (OBACT && OBACT->type == OB_MESH) {
+ if (ob && ob->type == OB_MESH) {
uiDefPulldownBut(block, view3d_select_faceselmenu, NULL, "Select", xco,-2, xmax-3, 24, "");
}
} else if ((G.f & G_VERTEXPAINT) || (G.f & G_TEXTUREPAINT) || (G.f & G_WEIGHTPAINT)) {
uiDefBut(block, LABEL,0,"", xco, 0, xmax, 20, 0, 0, 0, 0, 0, "");
} else {
- Object *ob= OBACT;
if (ob && (ob->flag & OB_POSEMODE))
uiDefPulldownBut(block, view3d_select_pose_armaturemenu, NULL, "Select", xco,-2, xmax-3, 24, "");
@@ -3996,31 +3994,31 @@ static void view3d_header_pulldowns(uiBlock *block, short *xcoord)
xco+= xmax;
if (G.obedit) {
- if (OBACT && OBACT->type == OB_MESH) {
+ if (ob && ob->type == OB_MESH) {
xmax= GetButStringLength("Mesh");
uiDefPulldownBut(block, view3d_edit_meshmenu, NULL, "Mesh", xco,-2, xmax-3, 24, "");
xco+= xmax;
- } else if (OBACT && OBACT->type == OB_CURVE) {
+ } else if (ob && ob->type == OB_CURVE) {
xmax= GetButStringLength("Curve");
uiDefPulldownBut(block, view3d_edit_curvemenu, NULL, "Curve", xco,-2, xmax-3, 24, "");
xco+= xmax;
- } else if (OBACT && OBACT->type == OB_SURF) {
+ } else if (ob && ob->type == OB_SURF) {
xmax= GetButStringLength("Surface");
uiDefPulldownBut(block, view3d_edit_curvemenu, NULL, "Surface", xco,-2, xmax-3, 24, "");
xco+= xmax;
- } else if (OBACT && OBACT->type == OB_FONT) {
+ } else if (ob && ob->type == OB_FONT) {
xmax= GetButStringLength("Text");
uiDefPulldownBut(block, view3d_edit_textmenu, NULL, "Text", xco,-2, xmax-3, 24, "");
xco+= xmax;
- } else if (OBACT && OBACT->type == OB_MBALL) {
+ } else if (ob && ob->type == OB_MBALL) {
xmax= GetButStringLength("Metaball");
uiDefPulldownBut(block, view3d_edit_metaballmenu, NULL, "Metaball", xco,-2, xmax-3, 24, "");
xco+= xmax;
- } else if (OBACT && OBACT->type == OB_LATTICE) {
+ } else if (ob && ob->type == OB_LATTICE) {
xmax= GetButStringLength("Lattice");
uiDefPulldownBut(block, view3d_edit_latticemenu, NULL, "Lattice", xco,-2, xmax-3, 24, "");
xco+= xmax;
- } else if (OBACT && OBACT->type == OB_ARMATURE) {
+ } else if (ob && ob->type == OB_ARMATURE) {
xmax= GetButStringLength("Armature");
uiDefPulldownBut(block, view3d_edit_armaturemenu, NULL, "Armature", xco,-2, xmax-3, 24, "");
xco+= xmax;
@@ -4032,14 +4030,12 @@ static void view3d_header_pulldowns(uiBlock *block, short *xcoord)
xco+= xmax;
}
else if (G.f & G_FACESELECT) {
- if (OBACT && OBACT->type == OB_MESH) {
+ if (ob && ob->type == OB_MESH) {
xmax= GetButStringLength("Face");
uiDefPulldownBut(block, view3d_faceselmenu, NULL, "Face", xco,-2, xmax-3, 24, "");
xco+= xmax;
}
} else {
- Object *ob= OBACT;
-
if (ob && (ob->flag & OB_POSEMODE)) {
xmax= GetButStringLength("Pose");
uiDefPulldownBut(block, view3d_pose_armaturemenu, NULL, "Pose", xco,-2, xmax-3, 24, "");
diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c
index 66f02ed442b..af4218011de 100644
--- a/source/blender/src/outliner.c
+++ b/source/blender/src/outliner.c
@@ -1235,7 +1235,7 @@ static int tree_element_active_posechannel(TreeElement *te, TreeStoreElem *tsele
bPoseChannel *pchan= te->directdata;
if(set) {
- if(!(pchan->bone->flag & BONE_HIDDEN)) {
+ if(!(pchan->bone->flag & BONE_HIDDEN_P)) {
if(G.qual & LR_SHIFTKEY) deselectall_posearmature(ob, 2); // 2 = clear active tag
else deselectall_posearmature(ob, 0); // 0 = deselect
@@ -1260,7 +1260,7 @@ static int tree_element_active_bone(TreeElement *te, TreeStoreElem *tselem, int
Bone *bone= te->directdata;
if(set) {
- if(!(bone->flag & BONE_HIDDEN)) {
+ if(!(bone->flag & BONE_HIDDEN_P)) {
if(G.qual & LR_SHIFTKEY) deselectall_posearmature(OBACT, 2); // 2 is clear active tag
else deselectall_posearmature(OBACT, 0);
bone->flag |= BONE_SELECTED|BONE_ACTIVE;
@@ -1287,16 +1287,19 @@ static int tree_element_active_ebone(TreeElement *te, TreeStoreElem *tselem, int
EditBone *ebone= te->directdata;
if(set) {
- if(G.qual & LR_SHIFTKEY) deselectall_armature(2); // only clear active tag
- else deselectall_armature(0); // deselect
+ if(!(ebone->flag & BONE_HIDDEN_A)) {
+
+ if(G.qual & LR_SHIFTKEY) deselectall_armature(2); // only clear active tag
+ else deselectall_armature(0); // deselect
- ebone->flag |= BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL|BONE_ACTIVE;
- // flush to parent?
- if(ebone->parent && (ebone->flag & BONE_IK_TOPARENT)) ebone->parent->flag |= BONE_TIPSEL;
-
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWOOPS, 0);
- allqueue(REDRAWACTION, 0);
+ ebone->flag |= BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL|BONE_ACTIVE;
+ // flush to parent?
+ if(ebone->parent && (ebone->flag & BONE_IK_TOPARENT)) ebone->parent->flag |= BONE_TIPSEL;
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWOOPS, 0);
+ allqueue(REDRAWACTION, 0);
+ }
}
else {
if (ebone->flag & BONE_SELECTED) return 1;
diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c
index 75a10df9b6c..616089659f7 100644
--- a/source/blender/src/poseobject.c
+++ b/source/blender/src/poseobject.c
@@ -37,6 +37,8 @@
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -45,6 +47,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
+#include "BKE_deform.h"
#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_global.h"
@@ -54,6 +57,7 @@
#include "BIF_editarmature.h"
#include "BIF_editaction.h"
#include "BIF_editconstraint.h"
+#include "BIF_editdeform.h"
#include "BIF_gl.h"
#include "BIF_graphics.h"
#include "BIF_interface.h"
@@ -527,6 +531,62 @@ void paste_posebuf (int flip)
BIF_undo_push("Paste Action Pose");
}
+/* ********************************************** */
+
+void pose_adds_vgroups(Object *meshobj)
+{
+ Object *poseobj= meshobj->parent;
+ bPoseChannel *pchan;
+ Bone *bone;
+ bDeformGroup *dg;
+ Mesh *me= meshobj->data;
+ MVert *mvert;
+ float head[3], tail[3], vec[3], fac;
+ int i;
+
+ if(poseobj==NULL || (poseobj->flag & OB_POSEMODE)==0) return;
+
+ for(pchan= poseobj->pose->chanbase.first; pchan; pchan= pchan->next) {
+ bone= pchan->bone;
+ if(bone->flag & (BONE_SELECTED)) {
+
+ /* check if mesh has vgroups */
+ dg= get_named_vertexgroup(meshobj, bone->name);
+ if(dg==NULL)
+ dg= add_defgroup_name(meshobj, bone->name);
+
+ /* get the root of the bone in global coords */
+ VECCOPY(head, bone->arm_head);
+ Mat4MulVecfl(poseobj->obmat, head);
+
+ /* get the tip of the bone in global coords */
+ VECCOPY(tail, bone->arm_tail);
+ Mat4MulVecfl(poseobj->obmat, tail);
+
+ /* todo; get the optimal vertices instead of mverts */
+ mvert= me->mvert;
+ for ( i=0 ; i < me->totvert ; i++ , mvert++) {
+ VECCOPY(vec, mvert->co);
+ Mat4MulVecfl(meshobj->obmat, vec);
+
+ /* get the distance-factor from the vertex to bone */
+ fac= distfactor_to_bone (vec, head, tail, bone->rad_head, bone->rad_tail, bone->dist);
+
+ /* add to vgroup. this call also makes me->dverts */
+ if(fac!=0.0f)
+ add_vert_to_defgroup (meshobj, dg, i, fac, WEIGHT_REPLACE);
+ else
+ remove_vert_defgroup (meshobj, dg, i);
+ }
+ }
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+
+ DAG_object_flush_update(G.scene, meshobj, OB_RECALC_DATA); // and all its relations
+
+}
/* ********************************************** */
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 41b46933877..ce676cf87a2 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -54,6 +54,7 @@
#include "BLI_linklist.h"
#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_image_types.h"
#include "DNA_ipo_types.h"
@@ -1306,6 +1307,14 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if((G.qual==0))
hide_mball(0);
}
+ else if(G.obedit->type==OB_ARMATURE) {
+ if (G.qual==0)
+ hide_selected_armature_bones();
+ else if (G.qual==LR_SHIFTKEY)
+ hide_unselected_armature_bones();
+ else if (G.qual==LR_ALTKEY)
+ show_all_armature_bones();
+ }
}
else if(G.f & G_FACESELECT)
hide_tface();
@@ -1568,8 +1577,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(G.obedit) {
if(G.qual==LR_ALTKEY) {
- if(G.obedit->type==OB_ARMATURE)
+ if(G.obedit->type==OB_ARMATURE) {
initTransform(TFM_BONESIZE, CTX_NONE);
+ }
else
initTransform(TFM_SHRINKFATTEN, CTX_NONE);
Transform();
@@ -1581,7 +1591,15 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else if(G.qual==LR_SHIFTKEY)
snapmenu();
else if(G.qual==0) {
- initTransform(TFM_RESIZE, CTX_NONE);
+ if(G.obedit->type==OB_ARMATURE) {
+ bArmature *arm= G.obedit->data;
+ if(arm->drawtype==ARM_ENVELOPE)
+ initTransform(TFM_BONE_ENVELOPE, CTX_NONE);
+ else
+ initTransform(TFM_RESIZE, CTX_NONE);
+ }
+ else
+ initTransform(TFM_RESIZE, CTX_NONE);
Transform();
}
else if(G.qual==(LR_SHIFTKEY|LR_CTRLKEY)){
@@ -1591,6 +1609,17 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
else if(G.qual==LR_ALTKEY) {
+ if(G.f & G_WEIGHTPAINT)
+ ob= ob->parent;
+ if(ob && (ob->flag & OB_POSEMODE)) {
+ bArmature *arm= ob->data;
+ if( ELEM(arm->drawtype, ARM_B_BONE, ARM_ENVELOPE)) {
+ initTransform(TFM_BONESIZE, CTX_NONE);
+ Transform();
+ break;
+ }
+ }
+
if(okee("Clear size")) {
clear_object('s');
}
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index 624808aa85a..ea11b17f26d 100755
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -47,18 +47,19 @@
#include "MEM_guardedalloc.h"
+#include "DNA_armature_types.h"
+#include "DNA_ipo_types.h" /* some silly ipo flag */
#include "DNA_listBase.h"
-#include "DNA_userdef_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
#include "DNA_scene_types.h" /* PET modes */
#include "DNA_screen_types.h" /* area dimensions */
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_texture_types.h"
+#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
-#include "DNA_ipo_types.h" /* some silly ipo flag */
-#include "DNA_meshdata_types.h"
-#include "DNA_mesh_types.h"
#include "BIF_editview.h" /* arrows_move_cursor */
#include "BIF_gl.h"
@@ -285,6 +286,10 @@ static char *transform_to_undostr(TransInfo *t)
return "Push/Pull";
case TFM_CREASE:
return "Crease";
+ case TFM_BONESIZE:
+ return "Bone Width";
+ case TFM_BONE_ENVELOPE:
+ return "Bone Envelope";
}
return "Transform";
}
@@ -361,29 +366,39 @@ static void transformEvent(unsigned short event, short val) {
Trans.state = TRANS_CONFIRM;
break;
case GKEY:
- restoreTransObjects(&Trans);
- initTransModeFlags(&Trans, TFM_TRANSLATION);
- initTranslation(&Trans);
- Trans.redraw = 1;
+ /* only switch when... */
+ if( ELEM3(Trans.mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) {
+ restoreTransObjects(&Trans);
+ initTransModeFlags(&Trans, TFM_TRANSLATION);
+ initTranslation(&Trans);
+ Trans.redraw = 1;
+ }
break;
case SKEY:
- restoreTransObjects(&Trans);
- initTransModeFlags(&Trans, TFM_RESIZE);
- initResize(&Trans);
- Trans.redraw = 1;
- break;
- case RKEY:
- if (Trans.mode == TFM_ROTATION) {
+ /* only switch when... */
+ if( ELEM3(Trans.mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) {
restoreTransObjects(&Trans);
- initTransModeFlags(&Trans, TFM_TRACKBALL);
- initTrackball(&Trans);
+ initTransModeFlags(&Trans, TFM_RESIZE);
+ initResize(&Trans);
+ Trans.redraw = 1;
}
- else {
- restoreTransObjects(&Trans);
- initTransModeFlags(&Trans, TFM_ROTATION);
- initRotation(&Trans);
+ break;
+ case RKEY:
+ /* only switch when... */
+ if( ELEM4(Trans.mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
+
+ if (Trans.mode == TFM_ROTATION) {
+ restoreTransObjects(&Trans);
+ initTransModeFlags(&Trans, TFM_TRACKBALL);
+ initTrackball(&Trans);
+ }
+ else {
+ restoreTransObjects(&Trans);
+ initTransModeFlags(&Trans, TFM_ROTATION);
+ initRotation(&Trans);
+ }
+ Trans.redraw = 1;
}
- Trans.redraw = 1;
break;
case CKEY:
if (G.qual & LR_ALTKEY) {
@@ -595,7 +610,16 @@ void initTransform(int mode, int context) {
initCrease(&Trans);
break;
case TFM_BONESIZE:
- initBoneSize(&Trans);
+ { /* used for both B-Bone width (bonesize) as for deform-dist (envelope) */
+ bArmature *arm= Trans.poseobj->data;
+ if(arm->drawtype==ARM_ENVELOPE)
+ initBoneEnvelope(&Trans);
+ else
+ initBoneSize(&Trans);
+ }
+ break;
+ case TFM_BONE_ENVELOPE:
+ initBoneEnvelope(&Trans);
break;
}
}
@@ -675,6 +699,13 @@ void initManipulator(int mode)
Trans.state = TRANS_RUNNING;
Trans.context = CTX_NONE;
+
+ /* automatic switch to scaling bone envelopes */
+ if(mode==TFM_RESIZE && G.obedit && G.obedit->type==OB_ARMATURE) {
+ bArmature *arm= G.obedit->data;
+ if(arm->drawtype==ARM_ENVELOPE)
+ mode= TFM_BONE_ENVELOPE;
+ }
initTrans(&Trans); // internal data, mouse, vectors
@@ -2251,13 +2282,13 @@ void Mirror(short mode)
scrarea_queue_headredraw(curarea);
}
-/* ******************** EditBone scaling *************** */
+/* ******************** EditBone (B-bone) width scaling *************** */
static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3])
{
float tmat[3][3], smat[3][3], oldy;
float sizemat[3][3];
-
+
Mat3MulMat3(smat, mat, td->mtx);
Mat3MulMat3(tmat, td->smtx, smat);
@@ -2357,10 +2388,86 @@ void initBoneSize(TransInfo *t)
t->snap[2] = t->snap[1] * 0.1f;
t->transform = BoneSize;
t->fac = (float)sqrt( (float)(
- (t->center2d[1] - t->imval[1])*(t->center2d[1] - t->imval[1])
- +
- (t->center2d[0] - t->imval[0])*(t->center2d[0] - t->imval[0])
- ) );
+ (t->center2d[1] - t->imval[1])*(t->center2d[1] - t->imval[1])
+ +
+ (t->center2d[0] - t->imval[0])*(t->center2d[0] - t->imval[0])
+ ) );
+
+ if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
+}
+
+/* ******************** EditBone envelope *************** */
+
+int BoneEnvelope(TransInfo *t, short mval[2])
+{
+ TransData *td = t->data;
+ float ratio;
+ int i;
+ char str[50];
+
+ if(t->flag & T_SHIFT_MOD) {
+ /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
+ float dx= (float)(t->center2d[0] - t->shiftmval[0]);
+ float dy= (float)(t->center2d[1] - t->shiftmval[1]);
+ ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
+
+ dx= (float)(t->center2d[0] - mval[0]);
+ dy= (float)(t->center2d[1] - mval[1]);
+ ratio+= 0.1f*(float)(sqrt( dx*dx + dy*dy)/t->fac -ratio);
+
+ }
+ else {
+ float dx= (float)(t->center2d[0] - mval[0]);
+ float dy= (float)(t->center2d[1] - mval[1]);
+ ratio = (float)sqrt( dx*dx + dy*dy)/t->fac;
+ }
+
+ snapGrid(t, &ratio);
+
+ applyNumInput(&t->num, &ratio);
+
+ /* header print for NumInput */
+ if (hasNumInput(&t->num)) {
+ char c[20];
+
+ outputNumInput(&(t->num), c);
+ sprintf(str, "Envelope: %s", c);
+ }
+ else {
+ sprintf(str, "Envelope: %3f", ratio);
+ }
+
+ for(i = 0 ; i < t->total; i++, td++) {
+ if (td->flag & TD_NOACTION)
+ break;
+
+ if(td->val) *td->val= td->ival*ratio;
+ }
+
+ recalcData(t);
+
+ headerprint(str);
+
+ force_draw(0);
+
+ if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);
+
+ return 1;
+}
+
+void initBoneEnvelope(TransInfo *t)
+{
+ t->idx_max = 0;
+ t->num.idx_max = 0;
+ t->snap[0] = 0.0f;
+ t->snap[1] = 0.1f;
+ t->snap[2] = t->snap[1] * 0.1f;
+ t->transform = BoneEnvelope;
+ t->fac = (float)sqrt( (float)(
+ (t->center2d[1] - t->imval[1])*(t->center2d[1] - t->imval[1])
+ +
+ (t->center2d[0] - t->imval[0])*(t->center2d[0] - t->imval[0])
+ ) );
if(t->fac==0.0f) t->fac= 1.0f; // prevent Inf
}
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index a4ddf8d7096..88c0ce02452 100755
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -446,6 +446,22 @@ static int add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tra
Mat3MulMat3(td->axismtx, omat, pmat);
Mat3Ortho(td->axismtx);
+ if(t->mode==TFM_BONESIZE) {
+ bArmature *arm= t->poseobj->data;
+
+ if(arm->drawtype==ARM_ENVELOPE) {
+ td->loc= NULL;
+ td->val= &bone->dist;
+ td->ival= bone->dist;
+ }
+ else {
+ // abusive storage of scale in the loc pointer :)
+ td->loc= &bone->xwidth;
+ VECCOPY (td->iloc, td->loc);
+ td->val= NULL;
+ }
+ }
+
return 1;
}
}
@@ -466,9 +482,11 @@ static void createTransPose(Object *ob, TransInfo *t)
arm=get_armature (ob);
if (arm==NULL || ob->pose==NULL) return;
- if (arm->flag & ARM_RESTPOS){
- notice ("Pose edit not possible while Rest Position is enabled");
- return;
+ if (arm->flag & ARM_RESTPOS) {
+ if(t->mode!=TFM_BONESIZE) {
+ notice ("Pose edit not possible while Rest Position is enabled");
+ return;
+ }
}
if (!(ob->lay & G.vd->lay)) return;
@@ -507,6 +525,7 @@ static void createTransPose(Object *ob, TransInfo *t)
static void createTransArmatureVerts(TransInfo *t)
{
EditBone *ebo;
+ bArmature *arm= G.obedit->data;
TransData *td;
float mtx[3][3], smtx[3][3], delta[3], bonemat[3][3];
@@ -532,11 +551,57 @@ static void createTransArmatureVerts(TransInfo *t)
td = t->data = MEM_mallocN(t->total*sizeof(TransData), "TransEditBone");
for (ebo=G.edbo.first;ebo;ebo=ebo->next){
- if (t->mode==TFM_BONESIZE) {
+
+ ebo->oldlength= ebo->length; // might be used for scaling
+
+ if (t->mode==TFM_BONE_ENVELOPE) {
+
+ if (ebo->flag & BONE_ROOTSEL){
+ td->val= &ebo->rad_head;
+ td->ival= *td->val;
+
+ VECCOPY (td->center, ebo->head);
+ td->flag= TD_SELECTED;
+
+ Mat3CpyMat3(td->smtx, smtx);
+ Mat3CpyMat3(td->mtx, mtx);
+
+ td->loc = NULL;
+ td->ext = NULL;
+ td->tdi = NULL;
+
+ td++;
+ }
+ if (ebo->flag & BONE_TIPSEL){
+ td->val= &ebo->rad_tail;
+ td->ival= *td->val;
+ VECCOPY (td->center, ebo->tail);
+ td->flag= TD_SELECTED;
+
+ Mat3CpyMat3(td->smtx, smtx);
+ Mat3CpyMat3(td->mtx, mtx);
+
+ td->loc = NULL;
+ td->ext = NULL;
+ td->tdi = NULL;
+
+ td++;
+ }
+
+ }
+ else if (t->mode==TFM_BONESIZE) {
if (ebo->flag & BONE_SELECTED) {
- // abusive storage of scale in the loc pointer :)
- td->loc= &ebo->xwidth;
- VECCOPY (td->iloc, td->loc);
+ if(arm->drawtype==ARM_ENVELOPE) {
+ td->loc= NULL;
+ td->val= &ebo->dist;
+ td->ival= ebo->dist;
+ }
+ else {
+ // abusive storage of scale in the loc pointer :)
+ td->loc= &ebo->xwidth;
+ VECCOPY (td->iloc, td->loc);
+ td->val= NULL;
+ }
VECCOPY (td->center, ebo->head);
td->flag= TD_SELECTED;
@@ -551,7 +616,6 @@ static void createTransArmatureVerts(TransInfo *t)
td->ext = NULL;
td->tdi = NULL;
- td->val = NULL;
td++;
}
@@ -1363,7 +1427,10 @@ void special_aftertrans_update(TransInfo *t)
int redrawipo=0;
int cancelled= (t->state == TRANS_CANCEL);
- if(G.obedit); // nothing
+ if(G.obedit) {
+ if(t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
else if( (t->flag & T_POSE) && t->poseobj) {
bArmature *arm;
bAction *act;
@@ -1415,6 +1482,10 @@ void special_aftertrans_update(TransInfo *t)
ob->recalc= 0; // is set on OK position already by recalcData()
}
/* do not call DAG_object_flush_update always, we dont want actions to update, for inserting keys */
+
+ if(t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
+ allqueue(REDRAWBUTSEDIT, 0);
+
}
else {
base= FIRSTBASE;
@@ -1636,10 +1707,11 @@ void createTransData(TransInfo *t)
}
t->flag |= T_EDIT;
- /* exception... hackish, we want bonescale to use bone orientation matrix (ton) */
+ /* exception... hackish, we want bonesize to use bone orientation matrix (ton) */
if(t->mode==TFM_BONESIZE) {
t->flag &= ~T_EDIT;
t->flag |= T_POSE;
+ t->poseobj= ob; /* <- tsk tsk, this is going to give issues one day */
}
}
else if (ob && (ob->flag & OB_POSEMODE)) {
diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c
index d938b43299d..9ab175d2681 100755
--- a/source/blender/src/transform_generics.c
+++ b/source/blender/src/transform_generics.c
@@ -127,12 +127,16 @@ static void transform_armature_mirror_update(void)
eboflip->tail[0]= -ebo->tail[0];
eboflip->tail[1]= ebo->tail[1];
eboflip->tail[2]= ebo->tail[2];
+ eboflip->rad_tail= ebo->rad_tail;
}
if(ebo->flag & BONE_ROOTSEL) {
eboflip->head[0]= -ebo->head[0];
eboflip->head[1]= ebo->head[1];
eboflip->head[2]= ebo->head[2];
+ eboflip->rad_head= ebo->rad_head;
}
+ if(ebo->flag & BONE_SELECTED)
+ eboflip->dist= ebo->dist;
}
}
}
@@ -176,6 +180,17 @@ void recalcData(TransInfo *t)
VECCOPY (ebo->parent->tail, ebo->head);
}
}
+
+ if(arm->drawtype==ARM_ENVELOPE) {
+ if(ebo->oldlength==0.0f) {
+ ebo->rad_head= 0.25f*ebo->length;
+ ebo->rad_tail= 0.10f*ebo->length;
+ if(ebo->parent) {
+ if(ebo->rad_head > ebo->parent->rad_tail)
+ ebo->rad_head= ebo->parent->rad_tail;
+ }
+ }
+ }
}
if(arm->flag & ARM_MIRROR_EDIT)
transform_armature_mirror_update();
@@ -260,9 +275,8 @@ void initTransModeFlags(TransInfo *t, int mode)
t->flag |= T_NO_CONSTRAINT;
break;
case TFM_SHEAR:
- t->flag |= T_NO_CONSTRAINT;
- break;
case TFM_CREASE:
+ case TFM_BONE_ENVELOPE:
t->flag |= T_NO_CONSTRAINT;
break;
}
diff --git a/source/blender/src/view.c b/source/blender/src/view.c
index ba70a06489a..9b3eab557d0 100644
--- a/source/blender/src/view.c
+++ b/source/blender/src/view.c
@@ -809,6 +809,7 @@ void setwinmatrixview3d(rctf *rect) /* rect: for picking */
else y1= -G.vd->dist;
y2= -y1;
+ far*= 0.5; // otherwise too extreme low zbuffer quality
near= -far;
orth= 1;
}