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:
authorTon Roosendaal <ton@blender.org>2005-12-13 23:32:39 +0300
committerTon Roosendaal <ton@blender.org>2005-12-13 23:32:39 +0300
commit4f235db6e6480881677678e2a9d4bc362d690bee (patch)
tree4d560b27550bb597f3d7b6d6a646577f2707ec19 /source/blender
parent904a478d9d7b7b633356ad638e4291ff79bbd067 (diff)
parentd1cc4b7a15efaeea5de1f70762c3507572fe186d (diff)
Tuesday merger of Orange branch with bf-blender
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_text.h5
-rw-r--r--source/blender/blenkernel/intern/action.c35
-rw-r--r--source/blender/blenkernel/intern/key.c3
-rw-r--r--source/blender/blenkernel/intern/text.c165
-rw-r--r--source/blender/python/api2_2x/Armature.c559
-rw-r--r--source/blender/python/api2_2x/Armature.h11
-rw-r--r--source/blender/python/api2_2x/Bone.c788
-rw-r--r--source/blender/python/api2_2x/Bone.h78
-rw-r--r--source/blender/python/api2_2x/Image.c45
-rw-r--r--source/blender/python/api2_2x/Library.c1
-rw-r--r--source/blender/python/api2_2x/Mesh.c21
-rw-r--r--source/blender/python/api2_2x/doc/API_intro.py2
-rw-r--r--source/blender/python/api2_2x/doc/Armature.py234
-rw-r--r--source/blender/python/api2_2x/doc/Image.py7
-rw-r--r--source/blender/python/api2_2x/sceneTimeLine.c68
-rw-r--r--source/blender/render/intern/source/rendercore.c131
-rw-r--r--source/blender/render/intern/source/vanillaRenderPipe.c12
-rw-r--r--source/blender/renderconverter/intern/convertBlenderScene.c177
-rw-r--r--source/blender/src/buttons_object.c12
-rw-r--r--source/blender/src/editarmature.c4
-rw-r--r--source/blender/src/editipo.c8
-rw-r--r--source/blender/src/editobject.c4
-rw-r--r--source/blender/src/fluidsim.c4
-rw-r--r--source/blender/src/poseobject.c7
-rwxr-xr-xsource/blender/src/transform_numinput.c55
-rw-r--r--source/blender/src/writeimage.c5
26 files changed, 1619 insertions, 822 deletions
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index c76d6c9231b..447a94dd487 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -131,6 +131,11 @@ int setcurr_tab (struct Text *text);
/* Misc */
#define UNDO_SWAP 031 /* Swap cursors */
+#define UNDO_INDENT 032
+#define UNDO_UNINDENT 033
+#define UNDO_COMMENT 034
+#define UNDO_UNCOMMENT 035
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 211e552f493..32bddfd4628 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -355,6 +355,23 @@ bActionChannel *verify_action_channel(bAction *act, const char *name)
/* ************************ Blending with NLA *************** */
+static void blend_pose_strides(bPose *dst, bPose *src, float srcweight, short mode)
+{
+ float dstweight;
+
+ switch (mode){
+ case POSE_BLEND:
+ dstweight = 1.0F - srcweight;
+ break;
+ case POSE_ADD:
+ dstweight = 1.0F;
+ break;
+ default :
+ dstweight = 1.0F;
+ }
+
+ VecLerpf(dst->stride_offset, dst->stride_offset, src->stride_offset, srcweight);
+}
/* Only allowed for Poses with identical channels */
void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
@@ -407,8 +424,6 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode)
dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight;
}
}
-
- VecLerpf(dst->stride_offset, dst->stride_offset, src->stride_offset, srcweight);
}
@@ -796,7 +811,7 @@ static void do_nla(Object *ob, int blocktype)
bActionStrip *strip;
float striptime, frametime, length, actlength;
float blendfac, stripframe;
- int doit;
+ int doit, dostride;
if(blocktype==ID_AR) {
copy_pose(&tpose, ob->pose, 1);
@@ -807,7 +822,7 @@ static void do_nla(Object *ob, int blocktype)
}
for (strip=ob->nlastrips.first; strip; strip=strip->next){
- doit=0;
+ doit=dostride= 0;
if (strip->act){ /* so theres an action */
@@ -865,7 +880,7 @@ static void do_nla(Object *ob, int blocktype)
if(key)
extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
}
- doit=1;
+ doit=dostride= 1;
}
}
}
@@ -894,9 +909,8 @@ static void do_nla(Object *ob, int blocktype)
/* Handle extend */
else{
if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
- striptime = 1.0;
-
- frametime = (striptime * actlength) + strip->actstart;
+ /* we want the strip to hold on the exact fraction of the repeat value */
+ frametime = actlength * (strip->repeat-(int)strip->repeat);
frametime= bsystem_time(ob, 0, frametime, 0.0);
if(blocktype==ID_AR)
@@ -923,8 +937,11 @@ static void do_nla(Object *ob, int blocktype)
else
blendfac = 1;
- if(blocktype==ID_AR) /* Blend this pose with the accumulated pose */
+ if(blocktype==ID_AR) {/* Blend this pose with the accumulated pose */
blend_poses (ob->pose, tpose, blendfac, strip->mode);
+ if(dostride)
+ blend_pose_strides (ob->pose, tpose, blendfac, strip->mode);
+ }
else {
blend_ipochannels(&chanbase, &tchanbase, blendfac, strip->mode);
BLI_freelistN(&tchanbase);
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 0fd0a864d4d..a2e372f33d5 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -943,6 +943,9 @@ static int do_mesh_key(Object *ob, Mesh *me)
if(me->key==NULL) return 0;
if(me->key->block.first==NULL) return 0;
+ /* prevent python from screwing this up? anyhoo, the from pointer could be dropped */
+ me->key->from= (ID *)me;
+
if(me->key->slurph && me->key->type!=KEY_RELATIVE ) {
delta= me->key->slurph;
delta/= me->totvert;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 4557bd0404d..330d46c959f 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -1337,6 +1337,14 @@ void txt_print_undo(Text *text)
ops= "Delete text block";
} else if (op==UNDO_IBLOCK) {
ops= "Insert text block";
+ } else if (op==UNDO_INDENT) {
+ ops= "Indent ";
+ } else if (op==UNDO_UNINDENT) {
+ ops= "Unindent ";
+ } else if (op==UNDO_COMMENT) {
+ ops= "Comment ";
+ } else if (op==UNDO_UNCOMMENT) {
+ ops= "Uncomment ";
} else {
ops= "Unknown";
}
@@ -1388,6 +1396,28 @@ void txt_print_undo(Text *text)
linep= linep+(text->undo_buf[i]<<16); i++;
linep= linep+(text->undo_buf[i]<<24); i++;
printf ("> (%d)", linep);
+ } else if (op==UNDO_INDENT || op==UNDO_UNINDENT) {
+ i++;
+
+ charp= text->undo_buf[i]; i++;
+ charp= charp+(text->undo_buf[i]<<8); i++;
+
+ linep= text->undo_buf[i]; i++;
+ linep= linep+(text->undo_buf[i]<<8); i++;
+ linep= linep+(text->undo_buf[i]<<16); i++;
+ linep= linep+(text->undo_buf[i]<<24); i++;
+
+ printf ("to <%d, %d> ", linep, charp);
+
+ charp= text->undo_buf[i]; i++;
+ charp= charp+(text->undo_buf[i]<<8); i++;
+
+ linep= text->undo_buf[i]; i++;
+ linep= linep+(text->undo_buf[i]<<8); i++;
+ linep= linep+(text->undo_buf[i]<<16); i++;
+ linep= linep+(text->undo_buf[i]<<24); i++;
+
+ printf ("from <%d, %d>", linep, charp);
}
printf (" %d\n", i);
@@ -1660,7 +1690,54 @@ void txt_do_undo(Text *text)
text->undo_pos--;
break;
+ case UNDO_INDENT:
+ case UNDO_UNINDENT:
+ case UNDO_COMMENT:
+ case UNDO_UNCOMMENT:
+ linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
+ linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ //linep is now the end line of the selection
+
+ charp = text->undo_buf[text->undo_pos]; text->undo_pos--;
+ charp = (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ //charp is the last char selected or text->line->len
+ //set the selcetion for this now
+ text->selc = charp;
+ text->sell = text->lines.first;
+ for (i= 0; i < linep; i++) {
+ text->sell = text->sell->next;
+ }
+
+ linep= text->undo_buf[text->undo_pos]; text->undo_pos--;
+ linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ linep = (linep<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ //first line to be selected
+
+ charp = text->undo_buf[text->undo_pos]; text->undo_pos--;
+ charp = (charp<<8)+text->undo_buf[text->undo_pos]; text->undo_pos--;
+ //first postion to be selected
+ text->curc = charp;
+ text->curl = text->lines.first;
+ for (i = 0; i < linep; i++) {
+ text->curl = text->curl->next;
+ }
+
+ if (op==UNDO_INDENT) {
+ unindent(text);
+ } else if (op== UNDO_UNINDENT) {
+ indent(text);
+ } else if (op == UNDO_COMMENT) {
+ uncomment(text);
+ } else if (op == UNDO_UNCOMMENT) {
+ comment(text);
+ }
+
+ text->undo_pos--;
+ break;
default:
error("Undo buffer error - resetting");
text->undo_pos= -1;
@@ -1677,6 +1754,7 @@ void txt_do_redo(Text *text)
unsigned int linep;
unsigned short charp;
char *buf;
+ int i;
text->undo_pos++;
op= text->undo_buf[text->undo_pos];
@@ -1687,7 +1765,7 @@ void txt_do_redo(Text *text)
}
undoing= 1;
-
+
switch(op) {
case UNDO_CLEFT:
txt_move_left(text, 0);
@@ -1815,7 +1893,52 @@ void txt_do_redo(Text *text)
linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
break;
+ case UNDO_INDENT:
+ case UNDO_UNINDENT:
+ case UNDO_COMMENT:
+ case UNDO_UNCOMMENT:
+ text->undo_pos++;
+ charp = text->undo_buf[text->undo_pos]; text->undo_pos++;
+ charp = charp+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
+ //charp is the first char selected or 0
+
+ linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
+ linep = linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
+ linep = linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
+ linep = linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
+ //linep is now the first line of the selection
+ //set the selcetion for this now
+ text->curc = charp;
+ text->curl = text->lines.first;
+ for (i= 0; i < linep; i++) {
+ text->curl = text->curl->next;
+ }
+
+ charp = text->undo_buf[text->undo_pos]; text->undo_pos++;
+ charp = charp+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
+ //last postion to be selected
+ linep= text->undo_buf[text->undo_pos]; text->undo_pos++;
+ linep = linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++;
+ linep = linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++;
+ linep = linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++;
+ //Last line to be selected
+
+ text->selc = charp;
+ text->sell = text->lines.first;
+ for (i = 0; i < linep; i++) {
+ text->sell = text->sell->next;
+ }
+ if (op==UNDO_INDENT) {
+ indent(text);
+ } else if (op== UNDO_UNINDENT) {
+ unindent(text);
+ } else if (op == UNDO_COMMENT) {
+ comment(text);
+ } else if (op == UNDO_UNCOMMENT) {
+ uncomment(text);
+ }
+ break;
default:
error("Undo buffer error - resetting");
text->undo_pos= -1;
@@ -2033,6 +2156,7 @@ void indent(Text *text)
if (!text) return;
if (!text->curl) return;
if (!text->sell) return;
+
num = 0;
while (TRUE)
{
@@ -2069,21 +2193,27 @@ void indent(Text *text)
text->curl = text->curl->prev;
num--;
}
+
+ if(!undoing)
+ {
+ txt_undo_add_toop(text, UNDO_INDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ }
}
void unindent(Text *text)
{
int num = 0;
+ char remove = '\t';
if (!text) return;
if (!text->curl) return;
if (!text->sell) return;
-
+
while(TRUE)
{
int i = 0;
- if (text->curl->line[i] == '\t')
+ if (text->curl->line[i] == remove)
{
while(i< text->curl->len) {
text->curl->line[i]= text->curl->line[i+1];
@@ -2106,12 +2236,17 @@ void unindent(Text *text)
}
}
-
+ text->curc = 0;
while( num > 0 )
{
text->curl = text->curl->prev;
num--;
}
+
+ if(!undoing)
+ {
+ txt_undo_add_toop(text, UNDO_UNINDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ }
}
void comment(Text *text)
@@ -2122,7 +2257,8 @@ void comment(Text *text)
if (!text) return;
if (!text->curl) return;
- if (!text->sell) return;
+ if (!text->sell) return;// Need to change this need to check if only one line is selected ot more then one
+
num = 0;
while (TRUE)
{
@@ -2153,27 +2289,33 @@ void comment(Text *text)
num++;
}
}
-
+ text->curc = 0;
while( num > 0 )
{
text->curl = text->curl->prev;
num--;
}
+
+ if(!undoing)
+ {
+ txt_undo_add_toop(text, UNDO_COMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ }
}
void uncomment(Text *text)
{
int num = 0;
+ char remove = '#';
if (!text) return;
if (!text->curl) return;
if (!text->sell) return;
-
+
while(TRUE)
{
int i = 0;
- if (text->curl->line[i] == '#')
+ if (text->curl->line[i] == remove)
{
while(i< text->curl->len) {
text->curl->line[i]= text->curl->line[i+1];
@@ -2196,12 +2338,17 @@ void uncomment(Text *text)
}
}
-
+ text->curc = 0;
while( num > 0 )
{
text->curl = text->curl->prev;
num--;
}
+
+ if(!undoing)
+ {
+ txt_undo_add_toop(text, UNDO_UNCOMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ }
}
int setcurr_tab (Text *text)
diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c
index f728f3f19d1..05a89dbda21 100644
--- a/source/blender/python/api2_2x/Armature.c
+++ b/source/blender/python/api2_2x/Armature.c
@@ -48,7 +48,7 @@
//These are evil 'extern' declarations for functions with no anywhere
extern void free_editArmature(void);
extern void make_boneList(ListBase* list, ListBase *bones, EditBone *parent);
-extern void editbones_to_armature (ListBase *list, Object *ob, bArmature *armature);
+extern void editbones_to_armature (ListBase *list, Object *ob);
//------------------------ERROR CODES---------------------------------
//This is here just to make me happy and to have more consistant error strings :)
@@ -71,9 +71,9 @@ static const char sModuleBadArgs[] = "Blender.Armature - Bad Arguments: ";
PyObject* BonesDict_items(BPy_BonesDict *self)
{
if (self->editmode_flag){
- return PyDict_Items(self->editBoneDict);
+ return PyDict_Items(self->editbonesMap);
}else{
- return PyDict_Items(self->dict);
+ return PyDict_Items(self->bonesMap);
}
}
//------------------------Armature.bones.keys()
@@ -81,9 +81,9 @@ PyObject* BonesDict_items(BPy_BonesDict *self)
PyObject* BonesDict_keys(BPy_BonesDict *self)
{
if (self->editmode_flag){
- return PyDict_Keys(self->editBoneDict);
+ return PyDict_Keys(self->editbonesMap);
}else{
- return PyDict_Keys(self->dict);
+ return PyDict_Keys(self->bonesMap);
}
}
//------------------------Armature.bones.values()
@@ -91,13 +91,13 @@ PyObject* BonesDict_keys(BPy_BonesDict *self)
PyObject* BonesDict_values(BPy_BonesDict *self)
{
if (self->editmode_flag){
- return PyDict_Values(self->editBoneDict);
+ return PyDict_Values(self->editbonesMap);
}else{
- return PyDict_Values(self->dict);
+ return PyDict_Values(self->bonesMap);
}
}
//------------------ATTRIBUTE IMPLEMENTATION---------------------------
-//------------------TYPE_OBECT IMPLEMENTATION--------------------------
+//------------------TYPE_OBECT IMPLEMENTATION-----------------------
//------------------------tp_doc
//The __doc__ string for this object
static char BPy_BonesDict_doc[] = "This is an internal subobject of armature\
@@ -114,32 +114,59 @@ static PyMethodDef BPy_BonesDict_methods[] = {
"() - Returns the values from the dictionary"},
{NULL}
};
+//-----------------(internal)
+static int BoneMapping_Init(PyObject *dictionary, ListBase *bones){
+ Bone *bone = NULL;
+ PyObject *py_bone = NULL;
-//------------------------tp_new
-//This methods creates a new object (note it does not initialize it - only the building)
-static PyObject *BonesDict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- BPy_BonesDict *py_BonesDict = NULL;
-
- py_BonesDict = (BPy_BonesDict*)type->tp_alloc(type, 0);
- if (!py_BonesDict)
- goto RuntimeError;
-
- py_BonesDict->dict = PyDict_New();
- if(!py_BonesDict->dict)
- goto RuntimeError;
-
- py_BonesDict->editBoneDict = PyDict_New();
- if (py_BonesDict->editBoneDict == NULL)
- goto RuntimeError;
+ for (bone = bones->first; bone; bone = bone->next){
+ py_bone = PyBone_FromBone(bone);
+ if (!py_bone)
+ return -1;
- py_BonesDict->editmode_flag = 0;
+ if(PyDict_SetItem(dictionary,
+ PyString_FromString(bone->name), py_bone) == -1){
+ return -1;
+ }
+ Py_DECREF(py_bone);
+ if (bone->childbase.first)
+ BoneMapping_Init(dictionary, &bone->childbase);
+ }
+ return 0;
+}
+//-----------------(internal)
+static int EditBoneMapping_Init(PyObject *dictionary, ListBase *editbones){
+ EditBone *editbone = NULL;
+ PyObject *py_editbone = NULL;
- return (PyObject*)py_BonesDict;
+ for (editbone = editbones->first; editbone; editbone = editbone->next){
+ py_editbone = PyEditBone_FromEditBone(editbone);
+ if (!py_editbone)
+ return -1;
-RuntimeError:
- return EXPP_objError(PyExc_RuntimeError, "%s%s",
- sBoneDictError, "Failed to create dictionary!");
+ if(PyDict_SetItem(dictionary,
+ PyString_FromString(editbone->name), py_editbone) == -1){
+ return -1;
+ }
+ Py_DECREF(py_editbone);
+ }
+ return 0;
+}
+//----------------- BonesDict_InitBones
+static int BonesDict_InitBones(BPy_BonesDict *self)
+{
+ PyDict_Clear(self->bonesMap);
+ if (BoneMapping_Init(self->bonesMap, self->bones) == -1)
+ return 0;
+ return 1;
+}
+//----------------- BonesDict_InitEditBones
+static int BonesDict_InitEditBones(BPy_BonesDict *self)
+{
+ PyDict_Clear(self->editbonesMap);
+ if (EditBoneMapping_Init(self->editbonesMap, &self->editbones) == -1)
+ return 0;
+ return 1;
}
//------------------------tp_repr
//This is the string representation of the object
@@ -153,13 +180,13 @@ static PyObject *BonesDict_repr(BPy_BonesDict *self)
sprintf(buffer, "[Bone Dict: {");
strcat(str,buffer);
if (self->editmode_flag){
- while (PyDict_Next(self->editBoneDict, &pos, &key, &value)) {
+ while (PyDict_Next(self->editbonesMap, &pos, &key, &value)) {
sprintf(buffer, "%s : %s, ", PyString_AsString(key),
PyString_AsString(value->ob_type->tp_repr(value)));
strcat(str,buffer);
}
}else{
- while (PyDict_Next(self->dict, &pos, &key, &value)) {
+ while (PyDict_Next(self->bonesMap, &pos, &key, &value)) {
sprintf(buffer, "%s : %s, ", PyString_AsString(key),
PyString_AsString(value->ob_type->tp_repr(value)));
strcat(str,buffer);
@@ -174,9 +201,10 @@ static PyObject *BonesDict_repr(BPy_BonesDict *self)
//This tells how to 'tear-down' our object when ref count hits 0
static void BonesDict_dealloc(BPy_BonesDict * self)
{
- Py_DECREF(self->dict);
- Py_DECREF(self->editBoneDict);
- ((PyObject*)self)->ob_type->tp_free((PyObject*)self);
+ Py_DECREF(self->bonesMap);
+ Py_DECREF(self->editbonesMap);
+ BLI_freelistN(&self->editbones);
+ BonesDict_Type.tp_free(self);
return;
}
//------------------------mp_length
@@ -184,9 +212,9 @@ static void BonesDict_dealloc(BPy_BonesDict * self)
int BonesDict_len(BPy_BonesDict *self)
{
if (self->editmode_flag){
- return PyDict_Size(self->editBoneDict);
+ return BLI_countlist(&self->editbones);
}else{
- return PyDict_Size(self->dict);
+ return BLI_countlist(self->bones);
}
}
//-----------------------mp_subscript
@@ -196,9 +224,9 @@ PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key)
PyObject *value = NULL;
if (self->editmode_flag){
- value = PyDict_GetItem(self->editBoneDict, key);
+ value = PyDict_GetItem(self->editbonesMap, key);
}else{
- value = PyDict_GetItem(self->dict, key);
+ value = PyDict_GetItem(self->bonesMap, key);
}
if(value == NULL){
return EXPP_incr_ret(Py_None);
@@ -209,29 +237,106 @@ PyObject *BonesDict_GetItem(BPy_BonesDict *self, PyObject* key)
//This does dict assignment - Bones['key'] = value
int BonesDict_SetItem(BPy_BonesDict *self, PyObject *key, PyObject *value)
{
- char *key_str = "", *name = "", *misc = "";
- static char *kwlist[] = {"name", "misc", NULL};
+ BPy_EditBone *editbone_for_deletion;
+ struct EditBone *editbone = NULL;
+ char *key_str = "";
- //Get the key name
- if(key && PyString_Check(key)){
- key_str = PyString_AsString(key);
- }else{
- goto AttributeError;
- }
-
- //Parse the value for assignment
- if(value && PyDict_Check(value)){
- if(!PyArg_ParseTupleAndKeywords(Py_BuildValue("()"), value, "|ss", kwlist, &name, &misc)){
+ if (self->editmode_flag){
+ //Get the key name
+ if(key && PyString_Check(key)){
+ key_str = PyString_AsString(key);
+ }else{
goto AttributeError;
}
+ //parse value for assignment
+ if (value && EditBoneObject_Check(value)){
+ //create a new editbone
+ editbone = MEM_callocN(sizeof(EditBone), "eBone");
+ BLI_strncpy(editbone->name, key_str, 32);
+ unique_editbone_name(editbone->name);
+ editbone->dist = ((BPy_EditBone*)value)->dist;
+ editbone->ease1 = ((BPy_EditBone*)value)->ease1;
+ editbone->ease2 = ((BPy_EditBone*)value)->ease2;
+ editbone->flag = ((BPy_EditBone*)value)->flag;
+ editbone->parent = ((BPy_EditBone*)value)->parent;
+ editbone->rad_head = ((BPy_EditBone*)value)->rad_head;
+ editbone->rad_tail = ((BPy_EditBone*)value)->rad_tail;
+ editbone->roll = ((BPy_EditBone*)value)->roll;
+ editbone->segments = ((BPy_EditBone*)value)->segments;
+ editbone->weight = ((BPy_EditBone*)value)->weight;
+ editbone->xwidth = ((BPy_EditBone*)value)->xwidth;
+ editbone->zwidth = ((BPy_EditBone*)value)->zwidth;
+ VECCOPY(editbone->head, ((BPy_EditBone*)value)->head);
+ VECCOPY(editbone->tail, ((BPy_EditBone*)value)->tail);
+
+ //set object pointer
+ ((BPy_EditBone*)value)->editbone = editbone;
+
+ //fix the bone's head position if flags indicate that it is 'connected'
+ if (editbone->flag & BONE_CONNECTED){
+ if(!editbone->parent){
+ ((BPy_EditBone*)value)->editbone = NULL;
+ MEM_freeN(editbone);
+ goto AttributeError3;
+ }else{
+ VECCOPY(editbone->head, editbone->parent->tail);
+ }
+ }
+
+ //set in editbonelist
+ BLI_addtail(&self->editbones, editbone);
+
+ //set the new editbone in the mapping
+ if(PyDict_SetItemString(self->editbonesMap, key_str, value) == -1){
+ ((BPy_EditBone*)value)->editbone = NULL;
+ BLI_freelinkN(&self->editbones, editbone);
+ goto RuntimeError;
+ }
+ }else if(!value){
+ //they are trying to delete the bone using 'del'
+ if(PyDict_GetItem(self->editbonesMap, key) != NULL){
+ /*first kill the datastruct then remove the item from the dict
+ and wait for GC to pick it up.
+ We have to delete the datastruct here because the tp_dealloc
+ doesn't handle it*/
+ editbone_for_deletion = (BPy_EditBone*)PyDict_GetItem(self->editbonesMap, key);
+ /*this is ugly but you have to set the parent to NULL for else
+ editbones_to_armature will crash looking for this bone*/
+ for (editbone = self->editbones.first; editbone; editbone = editbone->next){
+ if (editbone->parent == editbone_for_deletion->editbone)
+ editbone->parent = NULL;
+ /*any parent's were connected to this we must remove the flag
+ or else the 'root' ball doesn't get draw*/
+ if (editbone->flag & BONE_CONNECTED)
+ editbone->flag &= ~BONE_CONNECTED;
+ }
+ BLI_freelinkN(&self->editbones, editbone_for_deletion->editbone);
+ if(PyDict_DelItem(self->editbonesMap, key) == -1)
+ goto RuntimeError;
+ }else{
+ goto KeyError;
+ }
+ }
+ return 0;
}else{
- goto AttributeError;
+ goto AttributeError2;
}
- return 0;
+KeyError:
+return EXPP_intError(PyExc_KeyError, "%s%s%s%s",
+ sBoneDictError, "The key: ", key_str, " is not present in this dictionary!");
+RuntimeError:
+ return EXPP_intError(PyExc_RuntimeError, "%s%s",
+ sBoneDictError, "Unable to access dictionary!");
AttributeError:
return EXPP_intError(PyExc_AttributeError, "%s%s",
- sBoneDictBadArgs, "Expects (optional) name='string', misc='string'");
+ sBoneDictBadArgs, "Expects EditboneType Object");
+AttributeError2:
+ return EXPP_intError(PyExc_AttributeError, "%s%s",
+ sBoneDictBadArgs, "You must call makeEditable() first");
+AttributeError3:
+ return EXPP_intError(PyExc_AttributeError, "%s%s",
+ sBoneDictBadArgs, "The 'connected' flag is set but the bone has no parent!");
}
//------------------TYPE_OBECT DEFINITION--------------------------
//Mapping Protocol
@@ -242,35 +347,35 @@ static PyMappingMethods BonesDict_MapMethods = {
};
//BonesDict TypeObject
PyTypeObject BonesDict_Type = {
- PyObject_HEAD_INIT(NULL) //tp_head
+ PyObject_HEAD_INIT(NULL) //tp_head
0, //tp_internal
"BonesDict", //tp_name
- sizeof(BPy_BonesDict), //tp_basicsize
+ sizeof(BPy_BonesDict), //tp_basicsize
0, //tp_itemsize
- (destructor)BonesDict_dealloc, //tp_dealloc
+ (destructor)BonesDict_dealloc, //tp_dealloc
0, //tp_print
0, //tp_getattr
0, //tp_setattr
0, //tp_compare
- (reprfunc) BonesDict_repr, //tp_repr
+ (reprfunc) BonesDict_repr, //tp_repr
0, //tp_as_number
0, //tp_as_sequence
- &BonesDict_MapMethods, //tp_as_mapping
+ &BonesDict_MapMethods, //tp_as_mapping
0, //tp_hash
0, //tp_call
0, //tp_str
0, //tp_getattro
0, //tp_setattro
0, //tp_as_buffer
- Py_TPFLAGS_DEFAULT, //tp_flags
- BPy_BonesDict_doc, //tp_doc
+ Py_TPFLAGS_DEFAULT, //tp_flags
+ BPy_BonesDict_doc, //tp_doc
0, //tp_traverse
0, //tp_clear
0, //tp_richcompare
0, //tp_weaklistoffset
0, //tp_iter
0, //tp_iternext
- BPy_BonesDict_methods, //tp_methods
+ BPy_BonesDict_methods, //tp_methods
0, //tp_members
0, //tp_getset
0, //tp_base
@@ -278,9 +383,9 @@ PyTypeObject BonesDict_Type = {
0, //tp_descr_get
0, //tp_descr_set
0, //tp_dictoffset
- 0, //tp_init
+ 0, //tp_init
0, //tp_alloc
- (newfunc)BonesDict_new, //tp_new
+ 0, //tp_new
0, //tp_free
0, //tp_is_gc
0, //tp_bases
@@ -290,232 +395,88 @@ PyTypeObject BonesDict_Type = {
0, //tp_weaklist
0 //tp_del
};
-//-----------------(internal)
-static int BonesDict_Init(PyObject *dictionary, ListBase *bones){
- Bone *bone = NULL;
- PyObject *py_bone = NULL;
+//-----------------------PyBonesDict_FromPyArmature
+static PyObject *PyBonesDict_FromPyArmature(BPy_Armature *py_armature)
+{
+ BPy_BonesDict *py_BonesDict = NULL;
- for (bone = bones->first; bone; bone = bone->next){
- py_bone = PyBone_FromBone(bone);
- if (py_bone == NULL)
- return -1;
+ //create py object
+ py_BonesDict = (BPy_BonesDict *)BonesDict_Type.tp_alloc(&BonesDict_Type, 0);
+ if (!py_BonesDict)
+ goto RuntimeError;
- if(PyDict_SetItem(dictionary, PyString_FromString(bone->name), py_bone) == -1){
- goto RuntimeError;
- }
- if (bone->childbase.first)
- BonesDict_Init(dictionary, &bone->childbase);
- }
- return 0;
+ //create internal dictionaries
+ py_BonesDict->bonesMap = PyDict_New();
+ py_BonesDict->editbonesMap = PyDict_New();
+ if (!py_BonesDict->bonesMap || !py_BonesDict->editbonesMap)
+ goto RuntimeError;
+
+ //set listbase pointer
+ py_BonesDict->bones = &py_armature->armature->bonebase;
+
+ //now that everything is setup - init the mappings
+ if (!BonesDict_InitBones(py_BonesDict))
+ goto RuntimeError;
+ if (!BonesDict_InitEditBones(py_BonesDict))
+ goto RuntimeError;
+
+ //set editmode flag
+ py_BonesDict->editmode_flag = 0;
+
+ return (PyObject*)py_BonesDict;
RuntimeError:
- return EXPP_intError(PyExc_RuntimeError, "%s%s",
- sBoneDictError, "Internal error trying to wrap blender bones!");
+ return EXPP_objError(PyExc_RuntimeError, "%s%s",
+ sBoneDictError, "Failed to create class");
}
//######################### Armature_Type #############################
/*This type represents a thin wrapper around bArmature data types
* internal to blender. It contains the psuedo-dictionary BonesDict
* as an assistant in manipulating it's own bone collection*/
-//#####################################################################
+//#################################################################
//------------------METHOD IMPLEMENTATION------------------------------
-//This is a help function for Armature_makeEditable
-static int PyArmature_InitEditBoneDict(PyObject *dictionary, ListBase *branch)
-{
- struct Bone *bone = NULL;
- PyObject *args, *py_editBone = NULL, *py_bone = NULL;
-
- for (bone = branch->first; bone; bone = bone->next){
-
- //create a new editbone based on the bone data
- py_bone = PyBone_FromBone(bone); //new
- if (py_bone == NULL)
- goto RuntimeError;
-
- args = Py_BuildValue("(O)",py_bone); //new
-
- py_editBone = EditBone_Type.tp_new(&EditBone_Type, args, NULL); //new
- if (py_editBone == NULL)
- goto RuntimeError;
-
- //add the new editbone to the dictionary
- if (PyDict_SetItemString(dictionary, bone->name, py_editBone) == -1)
- goto RuntimeError;
-
- if(bone->childbase.first){
- PyArmature_InitEditBoneDict(dictionary, &bone->childbase);
- }
- }
- return 0;
-
-RuntimeError:
- return EXPP_intError(PyExc_RuntimeError, "%s%s",
- sArmatureError, "Internal error trying to construct an edit armature!");
-
-}
//------------------------Armature.makeEditable()
static PyObject *Armature_makeEditable(BPy_Armature *self)
{
- if (PyArmature_InitEditBoneDict(((BPy_BonesDict*)self->Bones)->editBoneDict,
- &self->armature->bonebase) == -1){
- return NULL; //error already set
- }
- ((BPy_BonesDict*)self->Bones)->editmode_flag = 1;
- return EXPP_incr_ret(Py_None);
-}
-
-static void PyArmature_FixRolls(ListBase *branch, PyObject *dictionary)
-{
- float premat[3][3],postmat[3][3];
- float difmat[3][3],imat[3][3], delta[3];
- BPy_EditBone *py_editBone = NULL;
- struct Bone *bone = NULL;
- int keyCheck = -1;
-
- for (bone = branch->first; bone; bone = bone->next){
-
- where_is_armature_bone(bone, bone->parent); //set bone_mat, arm_mat, length, etc.
-
- keyCheck = PySequence_Contains(dictionary, PyString_FromString(bone->name));
- if (keyCheck == 1){
-
- py_editBone = (BPy_EditBone*)PyDict_GetItem(dictionary,
- PyString_FromString(bone->name)); //borrowed
- VecSubf (delta, py_editBone->tail, py_editBone->head);
- vec_roll_to_mat3(delta, py_editBone->roll, premat); //pre-matrix
- Mat3CpyMat4(postmat, bone->arm_mat); //post-matrix
- Mat3Inv(imat, premat);
- Mat3MulMat3(difmat, imat, postmat);
-
- bone->roll = (float)-atan(difmat[2][0]/difmat[2][2]); //YEA!!
- if (difmat[0][0]<0.0){
- bone->roll += (float)M_PI;
- }
+ if (self->armature->flag & ARM_EDITMODE)
+ goto AttributeError;
- where_is_armature_bone(bone, bone->parent); //gotta do it again...
- }else if (keyCheck == 0){
- //oops we couldn't find it
- }else{
- //error
- }
- PyArmature_FixRolls (&bone->childbase, dictionary);
- }
-}
-//------------------------(internal)EditBoneDict_CheckForKey
-static BPy_EditBone *EditBoneDict_CheckForKey(BPy_BonesDict *dictionary, char *name)
-{
- BPy_EditBone *editbone;
- PyObject *value, *key;
- int pos = 0;
+ make_boneList(&self->Bones->editbones, self->Bones->bones, NULL);
+ if (!BonesDict_InitEditBones(self->Bones))
+ return NULL;
+ self->Bones->editmode_flag = 1;
+ return EXPP_incr_ret(Py_None);
- while (PyDict_Next(dictionary->editBoneDict, &pos, &key, &value)) {
- editbone = (BPy_EditBone *)value;
- if (STREQ(editbone->name, name)){
- Py_INCREF(editbone);
- return editbone;
- }
- }
- return NULL;
+AttributeError:
+ return EXPP_objError(PyExc_AttributeError, "%s%s",
+ sArmatureBadArgs, "The armature cannot be placed manually in editmode before you call makeEditable()!");
}
-//------------------------Armature.saveChanges()
-static PyObject *Armature_saveChanges(BPy_Armature *self)
+//------------------------Armature.update()
+//This is a bit ugly because you need an object link to do this
+static PyObject *Armature_update(BPy_Armature *self)
{
- float M_boneRest[3][3], M_parentRest[3][3];
- float iM_parentRest[3][3], delta[3];
- BPy_EditBone *parent = NULL, *editbone = NULL;
- struct Bone *bone = NULL;
- struct Object *obj = NULL;
- PyObject *key, *value;
- int pos = 0;
+ Object *obj = NULL;
- //empty armature of old bones
- free_bones(self->armature);
-
- //create a new set based on the editbones
- while (PyDict_Next(((BPy_BonesDict*)self->Bones)->editBoneDict, &pos, &key, &value)) {
-
- editbone = (BPy_EditBone*)value;
- bone = MEM_callocN (sizeof(Bone), "bone");
- editbone->temp = bone; //save temp pointer
-
- strcpy (bone->name, editbone->name);
- memcpy (bone->head, editbone->head, sizeof(float)*3);
- memcpy (bone->tail, editbone->tail, sizeof(float)*3);
- bone->flag= editbone->flag;
- bone->roll = 0.0f; //is fixed later
- bone->weight = editbone->weight;
- bone->dist = editbone->dist;
- bone->xwidth = editbone->xwidth;
- bone->zwidth = editbone->zwidth;
- bone->ease1= editbone->ease1;
- bone->ease2= editbone->ease2;
- bone->rad_head= editbone->rad_head;
- bone->rad_tail= editbone->rad_tail;
- bone->segments= editbone->segments;
+ for (obj = G.main->object.first; obj; obj = obj->id.next){
+ if (obj->data == self->armature)
+ break;
}
+ if (obj){
+ editbones_to_armature (&self->Bones->editbones, obj);
+ if (!BonesDict_InitBones(self->Bones))
+ return NULL;
+ self->Bones->editmode_flag = 0;
+ }else{
+ goto AttributeError;
- pos = 0;
- //place bones in their correct heirarchy
- while (PyDict_Next(((BPy_BonesDict*)self->Bones)->editBoneDict,
- &pos, &key, &value)) {
-
- editbone = (BPy_EditBone*)value;
- bone = editbone->temp; //get bone pointer
-
- if (!STREQ(editbone->parent, "")){
- parent = EditBoneDict_CheckForKey((BPy_BonesDict*)self->Bones, editbone->parent);
- if(parent != NULL){
-
- //parent found in dictionary
- bone->parent = parent->temp;
- BLI_addtail (&parent->temp->childbase, bone);
- //Parenting calculations
- VecSubf (delta, parent->tail, parent->head);
- vec_roll_to_mat3(delta, parent->roll, M_parentRest); //M_parentRest = parent matrix
- VecSubf (delta, editbone->tail, editbone->head);
- vec_roll_to_mat3(delta, editbone->roll, M_boneRest); //M_boneRest = bone matrix
- Mat3Inv(iM_parentRest, M_parentRest); //iM_parentRest = 1/parent matrix
- //get head/tail
- VecSubf (bone->head, editbone->head, parent->tail);
- VecSubf (bone->tail, editbone->tail, parent->tail);
- //put them in parentspace
- Mat3MulVecfl(iM_parentRest, bone->head);
- Mat3MulVecfl(iM_parentRest, bone->tail);
-
- Py_DECREF(parent);
- }else{
- //was not found - most likely parent was deleted
- parent = NULL;
- BLI_addtail (&self->armature->bonebase, bone);
- }
- }else{
- BLI_addtail (&self->armature->bonebase, bone);
- }
- }
- //fix rolls and generate matrices
- PyArmature_FixRolls(&self->armature->bonebase,
- ((BPy_BonesDict*)self->Bones)->editBoneDict);
-
- //update linked objects
- for(obj = G.main->object.first; obj; obj = obj->id.next) {
- if(obj->data == self->armature){
- armature_rebuild_pose(obj, self->armature);
- }
}
- DAG_object_flush_update(G.scene, obj, OB_RECALC_DATA);
-
- //clear the editbone dictionary and set edit flag
- PyDict_Clear(((BPy_BonesDict*)self->Bones)->editBoneDict);
- ((BPy_BonesDict*)self->Bones)->editmode_flag = 0;
-
- //rebuild py_bones
- PyDict_Clear(((BPy_BonesDict*)self->Bones)->dict);
- if (BonesDict_Init(((BPy_BonesDict*)self->Bones)->dict,
- &self->armature->bonebase) == -1)
- return NULL; //error string already set
-
return EXPP_incr_ret(Py_None);
+
+AttributeError:
+ return EXPP_objError(PyExc_AttributeError, "%s%s",
+ sArmatureBadArgs, "The armature must be linked to an object before you can save changes!");
}
//------------------ATTRIBUTE IMPLEMENTATION---------------------------
//------------------------Armature.autoIK (getter)
@@ -945,7 +906,7 @@ AttributeError:
//Gets the name of the armature
static PyObject *Armature_getBoneDict(BPy_Armature *self, void *closure)
{
- return EXPP_incr_ret(self->Bones);
+ return EXPP_incr_ret((PyObject*)self->Bones);
}
//------------------------Armature.bones (setter)
//Sets the name of the armature
@@ -963,17 +924,15 @@ AttributeError:
//------------------------tp_doc
//The __doc__ string for this object
static char BPy_Armature_doc[] = "This object wraps a Blender Armature object.";
-
//------------------------tp_methods
//This contains a list of all methods the object contains
static PyMethodDef BPy_Armature_methods[] = {
{"makeEditable", (PyCFunction) Armature_makeEditable, METH_NOARGS,
"() - Unlocks the ability to modify armature bones"},
- {"saveChanges", (PyCFunction) Armature_saveChanges, METH_NOARGS,
+ {"update", (PyCFunction) Armature_update, METH_NOARGS,
"() - Rebuilds the armature based on changes to bones since the last call to makeEditable"},
{NULL}
};
-
//------------------------tp_getset
//This contains methods for attributes that require checking
static PyGetSetDef BPy_Armature_getset[] = {
@@ -1014,7 +973,6 @@ static PyObject *Armature_new(PyTypeObject *type, PyObject *args, PyObject *kwds
{
BPy_Armature *py_armature = NULL;
bArmature *bl_armature;
- int success;
bl_armature = add_armature();
if(bl_armature) {
@@ -1026,13 +984,11 @@ static PyObject *Armature_new(PyTypeObject *type, PyObject *args, PyObject *kwds
py_armature->armature = bl_armature;
- py_armature->Bones = BonesDict_new(&BonesDict_Type, NULL, NULL);
- if (py_armature->Bones == NULL)
+ //create armature.bones
+ py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature);
+ if (!py_armature->Bones)
goto RuntimeError;
- success = BonesDict_Init(((BPy_BonesDict*)py_armature->Bones)->dict, &bl_armature->bonebase);
- if (success == -1)
- return NULL; //error string already set
} else {
goto RuntimeError;
}
@@ -1061,7 +1017,6 @@ static int Armature_init(BPy_Armature *self, PyObject *args, PyObject *kwds)
PyOS_snprintf(buf, sizeof(buf), "%s", name);
rename_id(&self->armature->id, buf);
}
-
return 0;
AttributeError:
@@ -1075,21 +1030,19 @@ static PyObject *Armature_richcmpr(BPy_Armature *self, PyObject *v, int op)
{
return EXPP_incr_ret(Py_None);
}
-
//------------------------tp_repr
//This is the string representation of the object
static PyObject *Armature_repr(BPy_Armature *self)
{
return PyString_FromFormat( "[Armature: \"%s\"]", self->armature->id.name + 2 ); //*new*
}
-
//------------------------tp_dealloc
//This tells how to 'tear-down' our object when ref count hits 0
///tp_dealloc
static void Armature_dealloc(BPy_Armature * self)
{
Py_DECREF(self->Bones);
- ((PyObject*)self)->ob_type->tp_free((PyObject*)self);
+ Armature_Type.tp_free(self);
return;
}
//------------------TYPE_OBECT DEFINITION--------------------------
@@ -1159,7 +1112,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
size = PySequence_Length(args);
if (size == 1) {
seq = PySequence_GetItem(args, 0); //*new*
- if (seq == NULL)
+ if (!seq)
goto RuntimeError;
if(!PyString_Check(seq)){
if (PySequence_Check(seq)) {
@@ -1176,7 +1129,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
if(!PyString_Check(seq)){
for(i = 0; i < size; i++){
item = PySequence_GetItem(seq, i); //*new*
- if (item == NULL) {
+ if (!item) {
Py_DECREF(seq);
goto RuntimeError;
}
@@ -1191,7 +1144,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
//GET ARMATURES
if(size != 1){
dict = PyDict_New(); //*new*
- if(dict == NULL){
+ if(!dict){
Py_DECREF(seq);
goto RuntimeError;
}
@@ -1204,6 +1157,7 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
EXPP_decr3(seq, dict, py_armature);
goto RuntimeError;
}
+ Py_DECREF(py_armature);
data = ((ID*)data)->next;
}
Py_DECREF(seq);
@@ -1219,16 +1173,18 @@ static PyObject *M_Armature_Get(PyObject * self, PyObject * args)
EXPP_decr3(seq, dict, py_armature);
goto RuntimeError;
}
+ Py_DECREF(py_armature);
}else{
if(PyDict_SetItemString(dict, name, Py_None) == -1){ //add to dictionary
EXPP_decr2(seq, dict);
goto RuntimeError;
}
+ Py_DECREF(Py_None);
}
}
Py_DECREF(seq);
}
- return dict; //transfering ownership to caller
+ return dict;
}else{ //GET SINGLE ARMATURE
if(!PyString_Check(seq)){ //This handles the bizarre case where (['s']) is passed
item = PySequence_GetItem(seq, 0); //*new*
@@ -1272,22 +1228,18 @@ struct PyMethodDef M_Armature_methods[] = {
PyObject *PyArmature_FromArmature(struct bArmature *armature)
{
BPy_Armature *py_armature = NULL;
- int success;
+ //create armature type
py_armature = (BPy_Armature*)Armature_Type.tp_alloc(&Armature_Type, 0); //*new*
- if (py_armature == NULL)
+ if (!py_armature)
goto RuntimeError;
-
py_armature->armature = armature;
- py_armature->Bones = BonesDict_new(&BonesDict_Type, NULL, NULL); //*new*
- if (py_armature->Bones == NULL)
+ //create armature.bones
+ py_armature->Bones = (BPy_BonesDict*)PyBonesDict_FromPyArmature(py_armature);
+ if (!py_armature->Bones)
goto RuntimeError;
- success = BonesDict_Init(((BPy_BonesDict*)py_armature->Bones)->dict, &armature->bonebase);
- if (success == -1)
- return NULL; //error string already set
-
return (PyObject *) py_armature;
RuntimeError:
@@ -1307,7 +1259,7 @@ PyObject *Armature_Init(void)
//Initializes TypeObject.ob_type
if (PyType_Ready(&Armature_Type) < 0 || PyType_Ready(&BonesDict_Type) < 0 ||
- PyType_Ready(&EditBone_Type) < 0 || PyType_Ready(&Bone_Type) < 0){
+ PyType_Ready(&EditBone_Type) < 0 || PyType_Ready(&Bone_Type) < 0) {
return EXPP_incr_ret(Py_None);
}
@@ -1316,10 +1268,12 @@ PyObject *Armature_Init(void)
"The Blender Armature module");
//Add TYPEOBJECTS to the module
- PyModule_AddObject(module, "ArmatureType",
+ PyModule_AddObject(module, "Armature",
EXPP_incr_ret((PyObject *)&Armature_Type)); //*steals*
- PyModule_AddObject(module, "BoneType",
+ PyModule_AddObject(module, "Bone",
EXPP_incr_ret((PyObject *)&Bone_Type)); //*steals*
+ PyModule_AddObject(module, "Editbone",
+ EXPP_incr_ret((PyObject *)&EditBone_Type)); //*steals*
//Add CONSTANTS to the module
PyModule_AddObject(module, "CONNECTED",
@@ -1332,13 +1286,12 @@ PyObject *Armature_Init(void)
EXPP_incr_ret(PyConstant_NewInt("MULTIPLY", BONE_MULT_VG_ENV)));
PyModule_AddObject(module, "HIDDEN_EDIT",
EXPP_incr_ret(PyConstant_NewInt("HIDDEN_EDIT", BONE_HIDDEN_A)));
-
- PyModule_AddObject(module, "BONESPACE",
- EXPP_incr_ret(PyConstant_NewString("BONESPACE", "bone_space")));
- PyModule_AddObject(module, "ARMATURESPACE",
- EXPP_incr_ret(PyConstant_NewString("ARMATURESPACE", "armature_space")));
- PyModule_AddObject(module, "WORLDSPACE",
- EXPP_incr_ret(PyConstant_NewString("WORLDSPACE", "world_space")));
+ PyModule_AddObject(module, "ROOT_SELECTED",
+ EXPP_incr_ret(PyConstant_NewInt("ROOT_SELECTED", BONE_ROOTSEL)));
+ PyModule_AddObject(module, "BONE_SELECTED",
+ EXPP_incr_ret(PyConstant_NewInt("BONE_SELECTED", BONE_SELECTED)));
+ PyModule_AddObject(module, "TIP_SELECTED",
+ EXPP_incr_ret(PyConstant_NewInt("TIP_SELECTED", BONE_TIPSEL)));
PyModule_AddObject(module, "OCTAHEDRON",
EXPP_incr_ret(PyConstant_NewInt("OCTAHEDRON", ARM_OCTA)));
diff --git a/source/blender/python/api2_2x/Armature.h b/source/blender/python/api2_2x/Armature.h
index 473a2392931..4d14b41fdc8 100644
--- a/source/blender/python/api2_2x/Armature.h
+++ b/source/blender/python/api2_2x/Armature.h
@@ -43,18 +43,19 @@ PyObject *Armature_Init( void );
PyTypeObject Armature_Type;
PyTypeObject BonesDict_Type;
//-------------------STRUCT DEFINITION---------------------------
-
typedef struct {
PyObject_HEAD
- PyObject *dict;
- PyObject *editBoneDict;
- short editmode_flag; //1 = in , 0 = not in
+ PyObject *bonesMap; //wrapper for bones
+ PyObject *editbonesMap; //wrapper for editbones
+ ListBase *bones; //pointer to armature->bonebase
+ ListBase editbones; //allocated list of EditBones
+ short editmode_flag; //1 = in , 0 = not in
} BPy_BonesDict;
typedef struct {
PyObject_HEAD
struct bArmature * armature;
- PyObject *Bones;
+ BPy_BonesDict *Bones; //BPy_BonesDict
} BPy_Armature;
//-------------------VISIBLE PROTOTYPES-------------------------
diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c
index 2fe7faf3b90..d4f59e67ee5 100644
--- a/source/blender/python/api2_2x/Bone.c
+++ b/source/blender/python/api2_2x/Bone.c
@@ -36,6 +36,11 @@
#include "gen_utils.h"
#include "BKE_armature.h"
#include "Mathutils.h"
+#include "BKE_library.h"
+
+//these must come in this order
+#include "DNA_object_types.h" //1
+#include "BIF_editarmature.h" //2
//------------------------ERROR CODES---------------------------------
//This is here just to make me happy and to have more consistant error strings :)
@@ -43,6 +48,8 @@ static const char sEditBoneError[] = "EditBone (internal) - Error: ";
static const char sEditBoneBadArgs[] = "EditBone (internal) - Bad Arguments: ";
static const char sBoneError[] = "Bone - Error: ";
static const char sBoneBadArgs[] = "Bone - Bad Arguments: ";
+static const char sConstListError[] = "ConstantList - Error: ";
+static const char sConstListBadArgs[] = "ConstantList - Bad Arguments: ";
//----------------------(internal)
//gets the bone->roll (which is a localspace roll) and puts it in parentspace
@@ -68,18 +75,53 @@ double boneRoll_ToArmatureSpace(struct Bone *bone)
}
return roll; //result is in radians
}
-//################## EditBone_Type (internal) ########################
+
+//################## EditBone_Type ########################
/*This type is a wrapper for a tempory bone. This is an 'unparented' bone
*object. The armature->bonebase will be calculated from these temporary
*python tracked objects.*/
-//#####################################################################
+//####################################################
//------------------METHOD IMPLEMENTATIONS-----------------------------
+//-------------------------EditBone.hasParent()
+PyObject *EditBone_hasParent(BPy_EditBone *self)
+{
+ if (self->editbone){
+ if (self->editbone->parent)
+ return EXPP_incr_ret(Py_True);
+ else
+ return EXPP_incr_ret(Py_False);
+ }else{
+ goto AttributeError;
+ }
+
+AttributeError:
+ return EXPP_objError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".hasParent: ", "EditBone must be added to the armature first");
+}
+//-------------------------EditBone.clearParent()
+PyObject *EditBone_clearParent(BPy_EditBone *self)
+{
+ if (self->editbone){
+ if (self->editbone->parent)
+ self->editbone->parent = NULL;
+ return EXPP_incr_ret(Py_None);
+ }else{
+ goto AttributeError;
+ }
+
+AttributeError:
+ return EXPP_objError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".clearParent: ", "EditBone must be added to the armature first");
+}
//------------------ATTRIBUTE IMPLEMENTATION---------------------------
//------------------------EditBone.name (get)
static PyObject *EditBone_getName(BPy_EditBone *self, void *closure)
{
- return PyString_FromString(self->name);
+ if (self->editbone)
+ return PyString_FromString(self->editbone->name);
+ else
+ return PyString_FromString(self->name);
}
//------------------------EditBone.name (set)
//check for char[] overflow here...
@@ -90,7 +132,10 @@ static int EditBone_setName(BPy_EditBone *self, PyObject *value, void *closure)
if (!PyArg_Parse(value, "s", &name))
goto AttributeError;
- BLI_strncpy(self->name, name, 32);
+ if (self->editbone)
+ BLI_strncpy(self->editbone->name, name, 32);
+ else
+ BLI_strncpy(self->name, name, 32);
return 0;
AttributeError:
@@ -100,43 +145,116 @@ AttributeError:
//------------------------EditBone.roll (get)
static PyObject *EditBone_getRoll(BPy_EditBone *self, void *closure)
{
- return Py_BuildValue("{s:O}",
- "ARMATURESPACE", PyFloat_FromDouble((self->roll * (180/Py_PI))));
+ if (self->editbone){
+ return Py_BuildValue("f", PyFloat_FromDouble((self->editbone->roll * (180/Py_PI))));
+ }else{
+ return Py_BuildValue("f", PyFloat_FromDouble((self->roll * (180/Py_PI))));
+ }
}
//------------------------EditBone.roll (set)
static int EditBone_setRoll(BPy_EditBone *self, PyObject *value, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return 1;
+ float roll = 0.0f;
+
+ if (!PyArg_Parse(value, "f", &roll))
+ goto AttributeError;
+
+ if (self->editbone){
+ self->editbone->roll = (float)(roll * (Py_PI/180));
+ }else{
+ self->roll = (float)(roll * (Py_PI/180));
+ }
+ return 0;
+
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".roll: ", "expects a float");
}
//------------------------EditBone.head (get)
static PyObject *EditBone_getHead(BPy_EditBone *self, void *closure)
{
- return Py_BuildValue("{s:O, s:O}",
- "BONESPACE", newVectorObject(self->head, 3, Py_WRAP));;
+ if (self->editbone){
+ return newVectorObject(self->editbone->head, 3, Py_WRAP);
+ }else{
+ return newVectorObject(self->head, 3, Py_NEW);
+ }
}
//------------------------EditBone.head (set)
static int EditBone_setHead(BPy_EditBone *self, PyObject *value, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return 1;
+ VectorObject *vec = NULL;
+ int x;
+
+ if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
+ goto AttributeError;
+ if (vec->size != 3)
+ goto AttributeError2;
+
+ if (self->editbone){
+ for (x = 0; x < 3; x++){
+ self->editbone->head[x] = vec->vec[x];
+ }
+ }else{
+ for (x = 0; x < 3; x++){
+ self->head[x] = vec->vec[x];
+ }
+ }
+ return 0;
+
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".head: ", "expects a Vector Object");
+
+AttributeError2:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".head: ", "Vector Object needs to be (x,y,z)");
}
//------------------------EditBone.tail (get)
static PyObject *EditBone_getTail(BPy_EditBone *self, void *closure)
{
- return Py_BuildValue("{s:O, s:O}",
- "BONESPACE", newVectorObject(self->tail, 3, Py_WRAP));
+ if (self->editbone){
+ return newVectorObject(self->editbone->tail, 3, Py_WRAP);
+ }else{
+ return newVectorObject(self->tail, 3, Py_NEW);
+ }
}
//------------------------EditBone.tail (set)
static int EditBone_setTail(BPy_EditBone *self, PyObject *value, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return 1;
+ VectorObject *vec = NULL;
+ int x;
+
+ if (!PyArg_Parse(value, "O!", &vector_Type, &vec))
+ goto AttributeError;
+ if (vec->size != 3)
+ goto AttributeError2;
+
+ if (self->editbone){
+ for (x = 0; x < 3; x++){
+ self->editbone->tail[x] = vec->vec[x];
+ }
+ }else{
+ for (x = 0; x < 3; x++){
+ self->tail[x] = vec->vec[x];
+ }
+ }
+ return 0;
+
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".tail: ", "expects a Vector Object");
+
+AttributeError2:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".tail: ", "Vector Object needs to be (x,y,z)");
}
//------------------------EditBone.weight (get)
static PyObject *EditBone_getWeight(BPy_EditBone *self, void *closure)
{
- return PyFloat_FromDouble(self->weight);
+ if (self->editbone)
+ return PyFloat_FromDouble(self->editbone->weight);
+ else
+ return PyFloat_FromDouble(self->weight);
}
//------------------------EditBone.weight (set)
static int EditBone_setWeight(BPy_EditBone *self, PyObject *value, void *closure)
@@ -147,7 +265,10 @@ static int EditBone_setWeight(BPy_EditBone *self, PyObject *value, void *closure
goto AttributeError;
CLAMP(weight, 0.0f, 1000.0f);
- self->weight = weight;
+ if (self->editbone)
+ self->editbone->weight = weight;
+ else
+ self->weight = weight;
return 0;
AttributeError:
@@ -157,7 +278,10 @@ AttributeError:
//------------------------EditBone.deform_dist (get)
static PyObject *EditBone_getDeform_dist(BPy_EditBone *self, void *closure)
{
- return PyFloat_FromDouble(self->dist);
+ if (self->editbone)
+ return PyFloat_FromDouble(self->editbone->dist);
+ else
+ return PyFloat_FromDouble(self->dist);
}
//------------------------EditBone.deform_dist (set)
static int EditBone_setDeform_dist(BPy_EditBone *self, PyObject *value, void *closure)
@@ -168,7 +292,10 @@ static int EditBone_setDeform_dist(BPy_EditBone *self, PyObject *value, void *cl
goto AttributeError;
CLAMP(deform, 0.0f, 1000.0f);
- self->dist = deform;
+ if (self->editbone)
+ self->editbone->dist = deform;
+ else
+ self->dist = deform;
return 0;
AttributeError:
@@ -178,7 +305,10 @@ AttributeError:
//------------------------EditBone.subdivisions (get)
static PyObject *EditBone_getSubdivisions(BPy_EditBone *self, void *closure)
{
- return PyInt_FromLong(self->segments);
+ if (self->editbone)
+ return PyInt_FromLong(self->editbone->segments);
+ else
+ return PyInt_FromLong(self->segments);
}
//------------------------EditBone.subdivisions (set)
static int EditBone_setSubdivisions(BPy_EditBone *self, PyObject *value, void *closure)
@@ -189,7 +319,10 @@ static int EditBone_setSubdivisions(BPy_EditBone *self, PyObject *value, void *c
goto AttributeError;
CLAMP(segs, 1, 32);
- self->segments = (short)segs;
+ if (self->editbone)
+ self->editbone->segments = (short)segs;
+ else
+ self->segments = (short)segs;
return 0;
AttributeError:
@@ -202,29 +335,76 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure)
PyObject *list = NULL;
list = PyList_New(0);
- if (list == NULL)
+ if (!list)
goto RuntimeError;
- if(self->flag & BONE_CONNECTED)
- if (PyList_Append(list,
- EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
- goto RuntimeError;
- if(self->flag & BONE_HINGE)
- if (PyList_Append(list,
- EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
- goto RuntimeError;
- if(self->flag & BONE_NO_DEFORM)
- if (PyList_Append(list,
- EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
- goto RuntimeError;
- if(self->flag & BONE_MULT_VG_ENV)
- if (PyList_Append(list,
- EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
- goto RuntimeError;
- if(self->flag & BONE_HIDDEN_A)
- if (PyList_Append(list,
- EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
- goto RuntimeError;
+ if(self->editbone){
+ if(self->editbone->flag & BONE_CONNECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_HINGE)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_NO_DEFORM)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_MULT_VG_ENV)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_HIDDEN_A)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_ROOTSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_SELECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->editbone->flag & BONE_TIPSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
+ goto RuntimeError;
+ }else{
+ if(self->flag & BONE_CONNECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "CONNECTED")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_HINGE)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HINGE")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_NO_DEFORM)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "NO_DEFORM")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_MULT_VG_ENV)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "MULTIPLY")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_HIDDEN_A)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_ROOTSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_SELECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->flag & BONE_TIPSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
+ goto RuntimeError;
+ }
return EXPP_incr_ret(list);
@@ -240,13 +420,14 @@ static int EditBone_CheckValidConstant(PyObject *constant)
if (constant){
if (BPy_Constant_Check(constant)){
name = PyDict_GetItemString(((BPy_constant*)constant)->dict, "name");
- if (!name) return 0;
- if (!(STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM")
- || STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT"))){
- return 0;
- }else{
- return 1;
- }
+ if (!name)
+ return 0;
+ if (!STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM") &&
+ !STREQ3(PyString_AsString(name), "ROOT_SELECTED", "BONE_SELECTED", "TIP_SELECTED") &&
+ !STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT"))
+ return 0;
+ else
+ return 1;
}else{
return 0;
}
@@ -275,7 +456,19 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur
goto AttributeError2;
}
}
- self->flag = new_flag;
+
+ //set the options
+ if(self->editbone){
+ //make sure the 'connected' property is set up correctly
+ if (new_flag & BONE_CONNECTED)
+ if(!self->editbone->parent)
+ goto AttributeError3;
+ else
+ VECCOPY(self->editbone->head, self->editbone->parent->tail);
+ self->editbone->flag = new_flag;
+ }else{
+ self->flag = new_flag;
+ }
return 0;
}else if (BPy_Constant_Check(value)){
if (!EditBone_CheckValidConstant(value))
@@ -283,7 +476,18 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur
val = PyDict_GetItemString(((BPy_constant*)value)->dict, "value");
if (PyInt_Check(val)){
numeric_value = (int)PyInt_AS_LONG(val);
- self->flag = numeric_value;
+
+ if(self->editbone){
+ //make sure the 'connected' property is set up correctly
+ if (numeric_value & BONE_CONNECTED)
+ if(!self->editbone->parent)
+ goto AttributeError3;
+ else
+ VECCOPY(self->editbone->head, self->editbone->parent->tail);
+ self->editbone->flag = numeric_value;
+ }else{
+ self->flag = numeric_value;
+ }
return 0;
}else{
goto AttributeError2;
@@ -294,64 +498,112 @@ static int EditBone_setOptions(BPy_EditBone *self, PyObject *value, void *closur
AttributeError1:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
- sEditBoneError, ".options(): ", "Expects a constant or list of constants");
-
+ sEditBoneError, ".options: ", "Expects a constant or list of constants");
AttributeError2:
return EXPP_intError(PyExc_AttributeError, "%s%s%s",
- sEditBoneError, ".options(): ", "Please use a constant defined in the Armature module");
+ sEditBoneError, ".options: ", "Please use a constant defined in the Armature module");
+AttributeError3:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".options: ", "You can't connect to parent because no parent is set");
}
//------------------------EditBone.parent (get)
static PyObject *EditBone_getParent(BPy_EditBone *self, void *closure)
{
- //if (!STREQ(self->parent, ""))
- // return PyString_FromString(PyBone_FromBone(self->parent));
- //else
- printf("Sorry this isn't implemented yet.... :/");
- return EXPP_incr_ret(Py_None);
+ if (self->editbone){
+ if (self->editbone->parent)
+ return PyEditBone_FromEditBone(self->editbone->parent);
+ else
+ return EXPP_incr_ret(Py_None);
+ }else{
+ return EXPP_incr_ret(Py_None); //not in the list yet can't have a parent
+ }
}
//------------------------EditBone.parent (set)
static int EditBone_setParent(BPy_EditBone *self, PyObject *value, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return 1;
-}
+ BPy_EditBone *parent = NULL;
+
+ if (!PyArg_Parse(value, "O!", &EditBone_Type, &parent))
+ goto AttributeError;
+
+ if (!parent->editbone)
+ goto AttributeError2;
-//------------------------EditBone.children (get)
-static PyObject *EditBone_getChildren(BPy_EditBone *self, void *closure)
+ if (self->editbone){
+ self->editbone->parent = parent->editbone;
+ }else{
+ self->parent = parent->editbone;
+ }
+ return 0;
+
+AttributeError:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".parent: ", "expects a EditBone Object");
+
+AttributeError2:
+ return EXPP_intError(PyExc_AttributeError, "%s%s%s",
+ sEditBoneError, ".parent: ", "This object is not in the armature's bone list!");
+}
+//------------------------EditBone.matrix (get)
+static PyObject *EditBone_getMatrix(BPy_EditBone *self, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return EXPP_incr_ret(Py_None);
+ float boneMatrix[3][3];
+ float axis[3];
+
+ if (self->editbone){
+ VECSUB(axis, self->editbone->tail, self->editbone->head);
+ vec_roll_to_mat3(axis, self->editbone->roll, boneMatrix);
+ }else{
+ VECSUB(axis, self->tail, self->head);
+ vec_roll_to_mat3(axis, self->roll, boneMatrix);
+ }
+
+ return newMatrixObject((float*)boneMatrix, 3, 3, Py_NEW);
}
-//------------------------EditBone.children (set)
-static int EditBone_setChildren(BPy_EditBone *self, PyObject *value, void *closure)
+//------------------------EditBone.matrix (set)
+static int EditBone_setMatrix(BPy_EditBone *self, PyObject *value, void *closure)
{
printf("Sorry this isn't implemented yet.... :/");
return 1;
}
-//------------------------EditBone.matrix (get)
-static PyObject *EditBone_getMatrix(BPy_EditBone *self, void *closure)
+//------------------------Bone.length (get)
+static PyObject *EditBone_getLength(BPy_EditBone *self, void *closure)
{
- printf("Sorry this isn't implemented yet.... :/");
- return EXPP_incr_ret(Py_None);
+ float delta[3];
+ double dot = 0.0f;
+ int x;
+
+ if (self->editbone){
+ VECSUB(delta, self->editbone->tail, self->editbone->head);
+ for(x = 0; x < 3; x++){
+ dot += (delta[x] * delta[x]);
+ }
+ return PyFloat_FromDouble(sqrt(dot));
+ }else{
+ VECSUB(delta, self->tail, self->head);
+ for(x = 0; x < 3; x++){
+ dot += (delta[x] * delta[x]);
+ }
+ return PyFloat_FromDouble(sqrt(dot));
+ }
}
-//------------------------EditBone.matrix (set)
-static int EditBone_setMatrix(BPy_EditBone *self, PyObject *value, void *closure)
+//------------------------Bone.length (set)
+static int EditBone_setLength(BPy_EditBone *self, PyObject *value, void *closure)
{
printf("Sorry this isn't implemented yet.... :/");
return 1;
}
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
-//TODO: We need to think about the below methods
//------------------------tp_methods
//This contains a list of all methods the object contains
-//static PyMethodDef BPy_Bone_methods[] = {
-// {"clearParent", (PyCFunction) Bone_clearParent, METH_NOARGS,
-// "() - disconnects this bone from it's parent"},
-// {"clearChildren", (PyCFunction) Bone_clearChildren, METH_NOARGS,
-// "() - disconnects all the children from this bone"},
-// {NULL}
-//};
-//------------------------tp_getset
+static PyMethodDef BPy_EditBone_methods[] = {
+ {"hasParent", (PyCFunction) EditBone_hasParent, METH_NOARGS,
+ "() - True/False - Bone has a parent"},
+ {"clearParent", (PyCFunction) EditBone_clearParent, METH_NOARGS,
+ "() - sets the parent to None"},
+ {NULL}
+};
+///------------------------tp_getset
//This contains methods for attributes that require checking
static PyGetSetDef BPy_EditBone_getset[] = {
{"name", (getter)EditBone_getName, (setter)EditBone_setName,
@@ -366,7 +618,7 @@ static PyGetSetDef BPy_EditBone_getset[] = {
"The matrix of the bone", NULL},
{"weight", (getter)EditBone_getWeight, (setter)EditBone_setWeight,
"The weight of the bone in relation to a parented mesh", NULL},
- {"deform_dist", (getter)EditBone_getDeform_dist, (setter)EditBone_setDeform_dist,
+ {"deformDist", (getter)EditBone_getDeform_dist, (setter)EditBone_setDeform_dist,
"The distance at which deformation has effect", NULL},
{"subdivisions", (getter)EditBone_getSubdivisions, (setter)EditBone_setSubdivisions,
"The number of subdivisions (for B-Bones)", NULL},
@@ -374,8 +626,8 @@ static PyGetSetDef BPy_EditBone_getset[] = {
"The options effective on this bone", NULL},
{"parent", (getter)EditBone_getParent, (setter)EditBone_setParent,
"The parent bone of this bone", NULL},
- {"children", (getter)EditBone_getChildren, (setter)EditBone_setChildren,
- "The child bones of this bone", NULL},
+ {"length", (getter)EditBone_getLength, (setter)EditBone_setLength,
+ "The length of this bone", NULL},
{NULL}
};
@@ -383,7 +635,10 @@ static PyGetSetDef BPy_EditBone_getset[] = {
//This is the string representation of the object
static PyObject *EditBone_repr(BPy_EditBone *self)
{
- return PyString_FromFormat( "[EditBone \"%s\"]", self->name );
+ if (self->editbone)
+ return PyString_FromFormat( "[EditBone \"%s\"]", self->editbone->name );
+ else
+ return PyString_FromFormat( "[EditBone \"%s\"]", self->name );
}
//------------------------tp_doc
@@ -395,114 +650,121 @@ designed to act as a wrapper for an 'edit bone'.";
//This methods creates a new object (note it does not initialize it - only the building)
static PyObject *EditBone_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
+ char *name = "myEditBone";
BPy_EditBone *py_editBone = NULL;
- PyObject *py_bone;
- struct Bone *bone;
- int i;
-
- if(!PyArg_ParseTuple(args, "O!", &Bone_Type, &py_bone))
- goto AttributeError;
+ float head[3], tail[3];
py_editBone = (BPy_EditBone*)type->tp_alloc(type, 0); //new
if (py_editBone == NULL)
goto RuntimeError;
- bone = ((BPy_Bone*)py_bone)->bone;
-
- BLI_strncpy(py_editBone->name, bone->name, 32);
- py_editBone->flag = bone->flag;
- py_editBone->length = bone->length;
- py_editBone->weight = bone->weight;
- py_editBone->dist = bone->dist;
- py_editBone->xwidth = bone->xwidth;
- py_editBone->zwidth = bone->zwidth;
- py_editBone->ease1 = bone->ease1;
- py_editBone->ease2 = bone->ease2;
- py_editBone->rad_head = bone->rad_head;
- py_editBone->rad_tail = bone->rad_tail;
- py_editBone->segments = bone->segments;
- py_editBone->temp = NULL;
-
- if (bone->parent){
- BLI_strncpy(py_editBone->parent, bone->parent->name, 32);
- }else{
- BLI_strncpy(py_editBone->parent, "", 32);
- }
+ //this pointer will be set when this bone is placed in ListBase
+ //otherwise this will act as a py_object
+ py_editBone->editbone = NULL;
- py_editBone->roll = (float)boneRoll_ToArmatureSpace(bone);
+ unique_editbone_name(name);
+ BLI_strncpy(py_editBone->name, name, 32);
+ py_editBone->parent = NULL;
+ py_editBone->weight= 1.0f;
+ py_editBone->dist= 0.25f;
+ py_editBone->xwidth= 0.1f;
+ py_editBone->zwidth= 0.1f;
+ py_editBone->ease1= 1.0f;
+ py_editBone->ease2= 1.0f;
+ py_editBone->rad_head= 0.10f;
+ py_editBone->rad_tail= 0.05f;
+ py_editBone->segments= 1;
+ py_editBone->flag = 0;
+ py_editBone->roll = 0.0f;
+
+ head[0] = head[1] = head[2] = 0.0f;
+ tail[1] = tail[2] = 0.0f;
+ tail[0] = 1.0f;
+ VECCOPY(py_editBone->head, head);
+ VECCOPY(py_editBone->tail, tail);
- for (i = 0; i < 3; i++){
- py_editBone->head[i] = bone->arm_head[i];
- py_editBone->tail[i] = bone->arm_tail[i];
- }
return (PyObject*)py_editBone;
RuntimeError:
return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
sEditBoneError, " __new__: ", "Internal Error");
-AttributeError:
- return EXPP_objError(PyExc_AttributeError, "%s%s%s",
- sEditBoneBadArgs, " __new__: ", "Expects PyBone and optional float");
}
//------------------------tp_dealloc
//This tells how to 'tear-down' our object when ref count hits 0
+//the struct EditBone pointer will be handled by the BPy_BonesDict class
static void EditBone_dealloc(BPy_EditBone * self)
{
- ((PyObject*)self)->ob_type->tp_free((PyObject*)self);
+ EditBone_Type.tp_free(self);
return;
}
//------------------TYPE_OBECT DEFINITION--------------------------
PyTypeObject EditBone_Type = {
PyObject_HEAD_INIT(NULL) //tp_head
- 0, //tp_internal
- "EditBone", //tp_name
- sizeof(BPy_EditBone), //tp_basicsize
- 0, //tp_itemsize
- (destructor)EditBone_dealloc, //tp_dealloc
- 0, //tp_print
- 0, //tp_getattr
- 0, //tp_setattr
- 0, //tp_compare
- (reprfunc)EditBone_repr, //tp_repr
- 0, //tp_as_number
- 0, //tp_as_sequence
- 0, //tp_as_mapping
- 0, //tp_hash
- 0, //tp_call
- 0, //tp_str
- 0, //tp_getattro
- 0, //tp_setattro
- 0, //tp_as_buffer
- Py_TPFLAGS_DEFAULT, //tp_flags
- BPy_EditBone_doc, //tp_doc
- 0, //tp_traverse
- 0, //tp_clear
- 0, //tp_richcompare
- 0, //tp_weaklistoffset
- 0, //tp_iter
- 0, //tp_iternext
- 0, //tp_methods
- 0, //tp_members
- BPy_EditBone_getset, //tp_getset
- 0, //tp_base
- 0, //tp_dict
- 0, //tp_descr_get
- 0, //tp_descr_set
- 0, //tp_dictoffset
- 0, //tp_init
- 0, //tp_alloc
- (newfunc)EditBone_new, //tp_new
- 0, //tp_free
- 0, //tp_is_gc
- 0, //tp_bases
- 0, //tp_mro
- 0, //tp_cache
- 0, //tp_subclasses
- 0, //tp_weaklist
- 0 //tp_del
+ 0, //tp_internal
+ "EditBone", //tp_name
+ sizeof(BPy_EditBone), //tp_basicsize
+ 0, //tp_itemsize
+ (destructor)EditBone_dealloc, //tp_dealloc
+ 0, //tp_print
+ 0, //tp_getattr
+ 0, //tp_setattr
+ 0, //tp_compare
+ (reprfunc)EditBone_repr, //tp_repr
+ 0, //tp_as_number
+ 0, //tp_as_sequence
+ 0, //tp_as_mapping
+ 0, //tp_hash
+ 0, //tp_call
+ 0, //tp_str
+ 0, //tp_getattro
+ 0, //tp_setattro
+ 0, //tp_as_buffer
+ Py_TPFLAGS_DEFAULT, //tp_flags
+ BPy_EditBone_doc, //tp_doc
+ 0, //tp_traverse
+ 0, //tp_clear
+ 0, //tp_richcompare
+ 0, //tp_weaklistoffset
+ 0, //tp_iter
+ 0, //tp_iternext
+ BPy_EditBone_methods, //tp_methods
+ 0, //tp_members
+ BPy_EditBone_getset, //tp_getset
+ 0, //tp_base
+ 0, //tp_dict
+ 0, //tp_descr_get
+ 0, //tp_descr_set
+ 0, //tp_dictoffset
+ 0, //tp_init
+ 0, //tp_alloc
+ (newfunc)EditBone_new, //tp_new
+ 0, //tp_free
+ 0, //tp_is_gc
+ 0, //tp_bases
+ 0, //tp_mro
+ 0, //tp_cache
+ 0, //tp_subclasses
+ 0, //tp_weaklist
+ 0 //tp_del
};
//------------------METHOD IMPLEMENTATIONS--------------------------------
+//-------------------------Bone.hasParent()
+PyObject *Bone_hasParent(BPy_Bone *self)
+{
+ if (self->bone->parent)
+ return EXPP_incr_ret(Py_True);
+ else
+ return EXPP_incr_ret(Py_False);
+}
+//-------------------------Bone.hasChildren()
+PyObject *Bone_hasChildren(BPy_Bone *self)
+{
+ if (self->bone->childbase.first)
+ return EXPP_incr_ret(Py_True);
+ else
+ return EXPP_incr_ret(Py_False);
+}
//------------------ATTRIBUTE IMPLEMENTATIONS-----------------------------
//------------------------Bone.name (get)
static PyObject *Bone_getName(BPy_Bone *self, void *closure)
@@ -514,7 +776,7 @@ static PyObject *Bone_getName(BPy_Bone *self, void *closure)
static int Bone_setName(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.roll (get)
static PyObject *Bone_getRoll(BPy_Bone *self, void *closure)
@@ -527,7 +789,7 @@ static PyObject *Bone_getRoll(BPy_Bone *self, void *closure)
static int Bone_setRoll(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.head (get)
static PyObject *Bone_getHead(BPy_Bone *self, void *closure)
@@ -540,7 +802,7 @@ static PyObject *Bone_getHead(BPy_Bone *self, void *closure)
static int Bone_setHead(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.tail (get)
static PyObject *Bone_getTail(BPy_Bone *self, void *closure)
@@ -553,7 +815,7 @@ static PyObject *Bone_getTail(BPy_Bone *self, void *closure)
static int Bone_setTail(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.weight (get)
static PyObject *Bone_getWeight(BPy_Bone *self, void *closure)
@@ -564,7 +826,7 @@ static PyObject *Bone_getWeight(BPy_Bone *self, void *closure)
static int Bone_setWeight(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.deform_dist (get)
static PyObject *Bone_getDeform_dist(BPy_Bone *self, void *closure)
@@ -575,7 +837,7 @@ static PyObject *Bone_getDeform_dist(BPy_Bone *self, void *closure)
static int Bone_setDeform_dist(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.subdivisions (get)
static PyObject *Bone_getSubdivisions(BPy_Bone *self, void *closure)
@@ -586,7 +848,7 @@ static PyObject *Bone_getSubdivisions(BPy_Bone *self, void *closure)
static int Bone_setSubdivisions(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.connected (get)
static PyObject *Bone_getOptions(BPy_Bone *self, void *closure)
@@ -617,6 +879,18 @@ static PyObject *Bone_getOptions(BPy_Bone *self, void *closure)
if (PyList_Append(list,
EXPP_GetModuleConstant("Blender.Armature", "HIDDEN_EDIT")) == -1)
goto RuntimeError;
+ if(self->bone->flag & BONE_ROOTSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "ROOT_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->bone->flag & BONE_SELECTED)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "BONE_SELECTED")) == -1)
+ goto RuntimeError;
+ if(self->bone->flag & BONE_TIPSEL)
+ if (PyList_Append(list,
+ EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1)
+ goto RuntimeError;
return EXPP_incr_ret(list);
@@ -628,7 +902,7 @@ RuntimeError:
static int Bone_setOptions(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.parent (get)
static PyObject *Bone_getParent(BPy_Bone *self, void *closure)
@@ -642,7 +916,7 @@ static PyObject *Bone_getParent(BPy_Bone *self, void *closure)
static int Bone_setParent(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------(internal) PyBone_ChildrenAsList
static int PyBone_ChildrenAsList(PyObject *list, ListBase *bones){
@@ -685,7 +959,7 @@ static PyObject *Bone_getChildren(BPy_Bone *self, void *closure)
static int Bone_setChildren(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------------Bone.matrix (get)
static PyObject *Bone_getMatrix(BPy_Bone *self, void *closure)
@@ -698,9 +972,29 @@ static PyObject *Bone_getMatrix(BPy_Bone *self, void *closure)
static int Bone_setMatrix(BPy_Bone *self, PyObject *value, void *closure)
{
return EXPP_intError(PyExc_ValueError, "%s%s",
- sBoneError, "You must first call Armature.makeEditable() to edit the armature");
+ sBoneError, "You must first call .makeEditable() to edit the armature");
+}
+//------------------------Bone.length (get)
+static PyObject *Bone_getLength(BPy_Bone *self, void *closure)
+{
+ return Py_BuildValue("f", self->bone->length);
+}
+//------------------------Bone.length (set)
+static int Bone_setLength(BPy_Bone *self, PyObject *value, void *closure)
+{
+ return EXPP_intError(PyExc_ValueError, "%s%s",
+ sBoneError, "You must first call .makeEditable() to edit the armature");
}
//------------------TYPE_OBECT IMPLEMENTATION--------------------------
+//------------------------tp_methods
+//This contains a list of all methods the object contains
+static PyMethodDef BPy_Bone_methods[] = {
+ {"hasParent", (PyCFunction) Bone_hasParent, METH_NOARGS,
+ "() - True/False - Bone has a parent"},
+ {"hasChildren", (PyCFunction) Bone_hasChildren, METH_NOARGS,
+ "() - True/False - Bone has 1 or more children"},
+ {NULL}
+};
//------------------------tp_getset
//This contains methods for attributes that require checking
static PyGetSetDef BPy_Bone_getset[] = {
@@ -726,37 +1020,23 @@ static PyGetSetDef BPy_Bone_getset[] = {
"The parent bone of this bone", NULL},
{"children", (getter)Bone_getChildren, (setter)Bone_setChildren,
"The child bones of this bone", NULL},
+ {"length", (getter)Bone_getLength, (setter)Bone_setLength,
+ "The length of this bone", NULL},
{NULL}
};
-
-//------------------------tp_new
-static PyObject *Bone_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- return EXPP_incr_ret(Py_None);
-}
-
-//------------------------tp_richcompare
-//This method allows the object to use comparison operators
-static PyObject *Bone_richcmpr(BPy_Bone *self, PyObject *v, int op)
-{
- return EXPP_incr_ret(Py_None);
-}
-
//------------------------tp_repr
//This is the string representation of the object
static PyObject *Bone_repr(BPy_Bone *self)
{
return PyString_FromFormat( "[Bone \"%s\"]", self->bone->name );
}
-
//------------------------tp_dealloc
//This tells how to 'tear-down' our object when ref count hits 0
static void Bone_dealloc(BPy_Bone * self)
{
- ((PyObject*)self)->ob_type->tp_free((PyObject*)self);
+ Bone_Type.tp_free(self);
return;
}
-
//------------------------tp_doc
//The __doc__ string for this object
static char BPy_Bone_doc[] = "This object wraps a Blender Boneobject.\n\
@@ -764,56 +1044,74 @@ static char BPy_Bone_doc[] = "This object wraps a Blender Boneobject.\n\
//------------------TYPE_OBECT DEFINITION--------------------------
PyTypeObject Bone_Type = {
- PyObject_HEAD_INIT(NULL) //tp_head
- 0, //tp_internal
- "Bone", //tp_name
- sizeof(BPy_Bone), //tp_basicsize
- 0, //tp_itemsize
- (destructor)Bone_dealloc, //tp_dealloc
- 0, //tp_print
- 0, //tp_getattr
- 0, //tp_setattr
- 0, //tp_compare
- (reprfunc) Bone_repr, //tp_repr
- 0, //tp_as_number
- 0, //tp_as_sequence
- 0, //tp_as_mapping
- 0, //tp_hash
- 0, //tp_call
- 0, //tp_str
- 0, //tp_getattro
- 0, //tp_setattro
- 0, //tp_as_buffer
- Py_TPFLAGS_DEFAULT, //tp_flags
- BPy_Bone_doc, //tp_doc
- 0, //tp_traverse
- 0, //tp_clear
- (richcmpfunc)Bone_richcmpr, //tp_richcompare
- 0, //tp_weaklistoffset
- 0, //tp_iter
- 0, //tp_iternext
- 0, //tp_methods
- 0, //tp_members
- BPy_Bone_getset, //tp_getset
- 0, //tp_base
- 0, //tp_dict
- 0, //tp_descr_get
- 0, //tp_descr_set
- 0, //tp_dictoffset
- 0, //tp_init
- 0, //tp_alloc
- (newfunc)Bone_new, //tp_new
- 0, //tp_free
- 0, //tp_is_gc
- 0, //tp_bases
- 0, //tp_mro
- 0, //tp_cache
- 0, //tp_subclasses
- 0, //tp_weaklist
- 0 //tp_del
+ PyObject_HEAD_INIT(NULL) //tp_head
+ 0, //tp_internal
+ "Bone", //tp_name
+ sizeof(BPy_Bone), //tp_basicsize
+ 0, //tp_itemsize
+ (destructor)Bone_dealloc, //tp_dealloc
+ 0, //tp_print
+ 0, //tp_getattr
+ 0, //tp_setattr
+ 0, //tp_compare
+ (reprfunc) Bone_repr, //tp_repr
+ 0, //tp_as_number
+ 0, //tp_as_sequence
+ 0, //tp_as_mapping
+ 0, //tp_hash
+ 0, //tp_call
+ 0, //tp_str
+ 0, //tp_getattro
+ 0, //tp_setattro
+ 0, //tp_as_buffer
+ Py_TPFLAGS_DEFAULT, //tp_flags
+ BPy_Bone_doc, //tp_doc
+ 0, //tp_traverse
+ 0, //tp_clear
+ 0, //tp_richcompare
+ 0, //tp_weaklistoffset
+ 0, //tp_iter
+ 0, //tp_iternext
+ BPy_Bone_methods, //tp_methods
+ 0, //tp_members
+ BPy_Bone_getset, //tp_getset
+ 0, //tp_base
+ 0, //tp_dict
+ 0, //tp_descr_get
+ 0, //tp_descr_set
+ 0, //tp_dictoffset
+ 0, //tp_init
+ 0, //tp_alloc
+ 0, //tp_new
+ 0, //tp_free
+ 0, //tp_is_gc
+ 0, //tp_bases
+ 0, //tp_mro
+ 0, //tp_cache
+ 0, //tp_subclasses
+ 0, //tp_weaklist
+ 0 //tp_del
};
//------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
//-----------------(internal)
+//Converts a struct EditBone to a BPy_EditBone
+PyObject *PyEditBone_FromEditBone(struct EditBone *editbone)
+{
+ BPy_EditBone *py_editbone = NULL;
+
+ py_editbone = (BPy_EditBone*)EditBone_Type.tp_alloc(&EditBone_Type, 0); //*new*
+ if (!py_editbone)
+ goto RuntimeError;
+
+ py_editbone->editbone = editbone;
+
+ return (PyObject *) py_editbone;
+
+RuntimeError:
+ return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
+ sEditBoneError, "PyEditBone_FromEditBone: ", "Internal Error Ocurred");
+}
+//-----------------(internal)
//Converts a struct Bone to a BPy_Bone
PyObject *PyBone_FromBone(struct Bone *bone)
{
diff --git a/source/blender/python/api2_2x/Bone.h b/source/blender/python/api2_2x/Bone.h
index 2bdcfb2b120..aa095733d05 100644
--- a/source/blender/python/api2_2x/Bone.h
+++ b/source/blender/python/api2_2x/Bone.h
@@ -41,6 +41,7 @@
PyTypeObject EditBone_Type;
PyTypeObject Bone_Type;
//-------------------STRUCT DEFINITION----------------------------
+
typedef struct {
PyObject_HEAD
Bone * bone;
@@ -48,14 +49,13 @@ typedef struct {
typedef struct {
PyObject_HEAD
- struct Bone *temp; //temp tracking
- char parent[32];
+ struct EditBone *editbone;
+ struct EditBone *parent;
char name[32];
float roll;
float head[3];
float tail[3];
int flag;
- float length;
float dist;
float weight;
float xwidth;
@@ -69,75 +69,7 @@ typedef struct {
//-------------------VISIBLE PROTOTYPES-------------------------
PyObject *PyBone_FromBone(struct Bone *bone);
struct Bone *PyBone_AsBone(BPy_Bone *py_Bone);
+PyObject *PyEditBone_FromBone(Bone *bone);
+PyObject *PyEditBone_FromEditBone(struct EditBone *editbone);
#endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*
-#ifndef EXPP_BONE_H
-#define EXPP_BONE_H
-
-#include <Python.h>
-#include "DNA_armature_types.h"
-#include "Mathutils.h"
-
-//--------------------------Python BPy_Bone structure definition.-------
-typedef struct {
- PyObject_HEAD
- //reference to data if bone is linked to an armature
- Bone * bone;
- //list of vars that define the bone
- char *name;
- char *parent;
- float roll;
- int flag;
- float dist;
- float weight;
- VectorObject *head;
- VectorObject *tail;
- VectorObject *loc;
- VectorObject *dloc;
- VectorObject *size;
- VectorObject *dsize;
- QuaternionObject *quat;
- QuaternionObject *dquat;
- MatrixObject *obmat;
- MatrixObject *parmat;
- MatrixObject *defmat;
- MatrixObject *irestmat;
- MatrixObject *posemat;
-} BPy_Bone;
-
-//------------------------------visible prototypes----------------------
-PyObject *Bone_CreatePyObject( struct Bone *obj );
-int Bone_CheckPyObject( PyObject * py_obj );
-Bone *Bone_FromPyObject( PyObject * py_obj );
-PyObject *Bone_Init( void );
-int updateBoneData( BPy_Bone * self, Bone * parent );
-
-#endif
-
-*/
diff --git a/source/blender/python/api2_2x/Image.c b/source/blender/python/api2_2x/Image.c
index b81fb1aa5d2..70f69ac840b 100644
--- a/source/blender/python/api2_2x/Image.c
+++ b/source/blender/python/api2_2x/Image.c
@@ -69,6 +69,7 @@ short IMB_saveiff( struct ImBuf *ibuf, char *naam, int flags );
/*static PyObject *M_Image_New( PyObject * self, PyObject * args,
PyObject * keywords );*/
static PyObject *M_Image_Get( PyObject * self, PyObject * args );
+static PyObject *M_Image_GetCurrent( PyObject * self );
static PyObject *M_Image_Load( PyObject * self, PyObject * args );
/*****************************************************************************/
@@ -86,6 +87,10 @@ static char M_Image_Get_doc[] =
returns None if not found.\n If 'name' is not specified, \
it returns a list of all images in the\ncurrent scene.";
+static char M_Image_GetCurrent_doc[] =
+ "() - return the current image, from last active the uv/image view, \
+returns None no image is in the view.\n";
+
static char M_Image_Load_doc[] =
"(filename) - return image from file filename as Image Object, \
returns None if not found.\n";
@@ -96,9 +101,10 @@ returns None if not found.\n";
struct PyMethodDef M_Image_methods[] = {
/*{"New", ( PyCFunction ) M_Image_New, METH_VARARGS | METH_KEYWORDS,
M_Image_New_doc}, */
- {"Get", M_Image_Get, METH_VARARGS, M_Image_Get_doc},
- {"get", M_Image_Get, METH_VARARGS, M_Image_Get_doc},
- {"Load", M_Image_Load, METH_VARARGS, M_Image_Load_doc},
+ {"Get", (PyCFunction) M_Image_Get, METH_VARARGS, M_Image_Get_doc},
+ {"GetCurrent", (PyCFunction) M_Image_GetCurrent, METH_NOARGS, M_Image_GetCurrent_doc},
+ {"get", (PyCFunction) M_Image_Get, METH_VARARGS, M_Image_Get_doc},
+ {"Load", (PyCFunction) M_Image_Load, METH_VARARGS, M_Image_Load_doc},
{NULL, NULL, 0, NULL}
};
@@ -170,11 +176,6 @@ static PyObject *M_Image_Get( PyObject * self, PyObject * args )
while( img_iter ) {
pyobj = Image_CreatePyObject( img_iter );
- if( !pyobj )
- return ( EXPP_ReturnPyObjError
- ( PyExc_MemoryError,
- "couldn't create PyObject" ) );
-
PyList_SET_ITEM( img_list, index, pyobj );
img_iter = img_iter->id.next;
@@ -185,6 +186,28 @@ static PyObject *M_Image_Get( PyObject * self, PyObject * args )
}
}
+
+
+/*****************************************************************************/
+/* Function: M_Image_GetCurrent */
+/* Python equivalent: Blender.Image.GetCurrent */
+/* Description: Returns the active current (G.sima) */
+/* This will be the image last under the mouse cursor */
+/* None if there is no Image. */
+/*****************************************************************************/
+static PyObject *M_Image_GetCurrent( PyObject * self )
+{
+ PyObject *current_img;
+ if (!G.sima || !G.sima->image) {
+ Py_RETURN_NONE;
+ }
+ current_img = Image_CreatePyObject( G.sima->image );
+ return current_img;
+}
+
+
+
+
/*****************************************************************************/
/* Function: M_Image_Load */
/* Python equivalent: Blender.Image.Load */
@@ -674,15 +697,13 @@ static void Image_dealloc( BPy_Image * self )
PyObject *Image_CreatePyObject( Image * image )
{
BPy_Image *py_img;
-
py_img = ( BPy_Image * ) PyObject_NEW( BPy_Image, &Image_Type );
-
+
if( !py_img )
return EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create BPy_Image object" );
-
+
py_img->image = image;
-
return ( PyObject * ) py_img;
}
diff --git a/source/blender/python/api2_2x/Library.c b/source/blender/python/api2_2x/Library.c
index a4b97bfeef6..32c2c9792d4 100644
--- a/source/blender/python/api2_2x/Library.c
+++ b/source/blender/python/api2_2x/Library.c
@@ -42,6 +42,7 @@
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BLI_blenlib.h"
#include "BLO_readfile.h"
#include "BLI_linklist.h"
#include "MEM_guardedalloc.h"
diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c
index d4ef5b79c0e..ec5d75f16df 100644
--- a/source/blender/python/api2_2x/Mesh.c
+++ b/source/blender/python/api2_2x/Mesh.c
@@ -1696,6 +1696,18 @@ static PyObject *MVertSeq_extend( BPy_MVertSeq * self, PyObject *args )
}
}
+ /*
+ * if there are vertex groups, also have to fix them
+ */
+
+ if( mesh->dvert ) {
+ MDeformVert *newdvert;
+ newdvert = MEM_callocN( sizeof(MDeformVert)*newlen , "mesh defVert" );
+ memcpy( newdvert, mesh->dvert, sizeof(MDeformVert)*mesh->totvert );
+ MEM_freeN( mesh->dvert );
+ mesh->dvert = newdvert;
+ }
+
/* set final vertex list size */
mesh->totvert = newlen;
@@ -4842,13 +4854,18 @@ static PyObject *Mesh_getFromObject( BPy_Mesh * self, PyObject * args )
/* save a copy of our ID, dup the temporary mesh, restore the ID */
tmpid = self->mesh->id;
memcpy( self->mesh, tmpmesh, sizeof( Mesh ) );
- self->mesh->id= tmpid;
+ self->mesh->id = tmpid;
+
+ /* if mesh has keys, make sure they point back to this mesh */
+ if( self->mesh->key )
+ self->mesh->key->from = (ID *)self->mesh;
+
/* remove the temporary mesh */
BLI_remlink( &G.main->mesh, tmpmesh );
MEM_freeN( tmpmesh );
/* make sure materials get updated in objects */
- test_object_materials( ( ID * ) self->mesh );
+ test_object_materials( ( ID * ) self->mesh );
mesh_update( self->mesh );
return EXPP_incr_ret( Py_None );
diff --git a/source/blender/python/api2_2x/doc/API_intro.py b/source/blender/python/api2_2x/doc/API_intro.py
index 31ab333f231..9a7c16d5168 100644
--- a/source/blender/python/api2_2x/doc/API_intro.py
+++ b/source/blender/python/api2_2x/doc/API_intro.py
@@ -13,7 +13,7 @@ The Blender Python API Reference
Submodules:
-----------
- - L{Armature} (work in progress)
+ - L{Armature}
- L{NLA}
- L{BGL}
- L{Camera}
diff --git a/source/blender/python/api2_2x/doc/Armature.py b/source/blender/python/api2_2x/doc/Armature.py
index 93fec9e96fb..79f9481192d 100644
--- a/source/blender/python/api2_2x/doc/Armature.py
+++ b/source/blender/python/api2_2x/doc/Armature.py
@@ -12,14 +12,60 @@ example.
Example::
import Blender
- from Blender import Armature
+ from Blender import Armature as A
+ from Blender.Mathutils import *
#
- armatures = Armature.Get()
- for a in armatures:
- print "Armature ", a
- for bone_name, bone in a.bones.items():
- print bone_name, bone.weight
+ arms = A.Get()
+ for arm in arms.values():
+ arm.drawType = A.STICK #set the draw type
+ arm.makeEditable() #enter editmode
+ #generating new editbone
+ eb = A.Editbone()
+ eb.roll = 10
+ eb.parent = arm.bones['Bone.003']
+ eb.head = Vector(1,1,1)
+ eb.tail = Vector(0,0,1)
+ eb.options = [A.HINGE, A.CONNECTED]
+
+ #add the bone
+ arm.bones['myNewBone'] = eb
+
+ #delete an old bone
+ del arm.bones['Bone.002']
+
+ arm.update() #save changes
+
+ for bone in arm.bones.values():
+ #print bone.matrix['ARMATURESPACE']
+ print bone.parent, bone.name
+ print bone.children, bone.name
+ print bone.options, bone.name
+
+@var CONNECTED: Connect this bone to parent
+@type CONNECTED: Constant
+@var HINGE: Don't inherit rotation or scale from parent
+@type HINGE: Constant
+@var NO_DEFORM: If bone will not deform geometry
+@type NO_DEFORM: Constant
+@var MULTIPLY: Multiply bone with vertex group
+@type MULTIPLY: Constant
+@var HIDDEN_EDIT: Bone is hidden in editmode
+@type HIDDEN_EDIT: Constant
+@var ROOT_SELECTED: Root of the Bone is selected
+@type ROOT_SELECTED: Constant
+@var BONE_SELECTED: Bone is selected
+@type BONE_SELECTED: Constant
+@var TIP_SELECTED: Tip of the Bone is selected
+@type TIP_SELECTED: Constant
+@var OCTAHEDRON: Bones drawn as octahedrons
+@type OCTAHEDRON: Constant
+@var STICK: Bones drawn as a line
+@type STICK: Constant
+@var BBONE: Bones draw as a segmented B-spline
+@type BBONE: Constant
+@var ENVELOPE: Bones draw as a stick with envelope influence
+@type ENVELOPE: Constant
"""
def Get (name = None):
@@ -34,58 +80,85 @@ def Get (name = None):
- (): A list with all Armature objects in the current scene.
"""
-class ArmatureType:
+class Armature:
"""
- The ArmatureType object
- =======================
+ The Armature object
+ ===================
This object gives access to Armature-specific data in Blender.
@ivar name: The Armature name.
- @ivar bones: A Dictionary of Bones that make up this armature.
- @ivar vertexGroups: (bool) Whether vertex groups define deformation
- @ivar envelopes: (bool) Whether bone envelopes define deformation
- @ivar restPosition: (bool) Show rest position (no posing possible)
- @ivar delayDeform: (bool) Dont deform children when manipulating bones
- @ivar drawAxes: (bool) Draw bone axes
- @ivar drawNames: (bool) Draw bone names
+ @type name: String
+ @ivar bones: A Dictionary of Bones (BonesDict) that make up this armature.
+ @type bones: BonesDict Object
+ @ivar vertexGroups: Whether vertex groups define deformation
+ @type vertexGroups: Bool
+ @ivar envelopes: Whether bone envelopes define deformation
+ @type envelopes: Bool
+ @ivar restPosition: Show rest position (no posing possible)
+ @type restPosition: Bool
+ @ivar delayDeform: Dont deform children when manipulating bones
+ @type delayDeform: Bool
+ @ivar drawAxes: Draw bone axes
+ @type drawAxes: Bool
+ @ivar drawNames: Draw bone names
+ @type drawNames: Bool
@ivar ghost: Draw ghosts around frame for current Action
+ @type ghost: Bool
@ivar ghostStep: Number of frames between ghosts
+ @type ghostStep: Int
@ivar drawType: The drawing type that is used to display the armature
Acceptable values are:
- Armature.OCTAHEDRON: bones drawn as octahedrons
- Armature.STICK: bones drawn as sticks
- Armature.BBONE: bones drawn as b-bones
- Armature.ENVELOPE: bones drawn as sticks with envelopes
- @ivar mirrorEdit: (bool) X-axis mirrored editing
- @ivar autoIK: (bool) Adds temporary IK chains while grabbing bones
+ @type drawType: Constant Object
+ @ivar mirrorEdit: X-axis mirrored editing
+ @type mirrorEdit: Bool
+ @ivar autoIK: Adds temporary IK chains while grabbing bones
+ @type autoIK: Bool
"""
def __init__(name = 'myArmature'):
"""
- Initializer for the ArmatureType TypeObject.
+ Initializer for the Armature TypeObject.
Example::
- myNewArmature = Blender.Armature.ArmatureType('AR_1')
+ myNewArmature = Blender.Armature.Armature('AR_1')
@param name: The name for the new armature
@type name: string
+ @return: New Armature Object
+ @rtype: Armature Object
"""
def makeEditable():
"""
Put the armature into EditMode for editing purposes.
@warning: The armature should not be in manual editmode
- prior to calling this method.
+ prior to calling this method. The armature must be parented
+ to an object prior to editing.
+ @rtype: None
"""
- def saveChanges():
+ def update():
"""
Save all changes and update the armature.
@note: Must have called makeEditable() first.
+ @rtype: None
"""
class BonesDict:
"""
The BonesDict object
====================
- This object gives gives dictionary like access to the bones in an armature.
+ This object gives gives dictionary like access to the bones in an armature.
+ It is internal to blender but is called as 'Armature.bones'
+
+ Removing a bone:
+ Example::
+ del myArmature.bones['bone_name']
+ Adding a bone:
+ Example::
+ myEditBone = Armature.Editbone()
+ myArmature.bones['bone_name'] = myEditBone
"""
def items():
@@ -109,25 +182,116 @@ class BonesDict:
@return: All BPy_bones in this dictionary
"""
-class BoneType:
+class Bone:
"""
- The BoneType object
- ===================
- This object gives access to Bone-specific data in Blender.
+ The Bone object
+ ===============
+ This object gives access to Bone-specific data in Blender. This object
+ cannot be instantiated but is returned by BonesDict when the armature is not in editmode.
@ivar name: The name of this Bone.
+ @type name: String
@ivar roll: This Bone's roll value.
+ Keys are:
+ - 'ARMATURESPACE' - this roll in relation to the armature
+ - 'BONESPACE' - the roll in relation to itself
+ @type roll: Dictionary
@ivar head: This Bone's "head" ending position when in rest state.
+ Keys are:
+ - 'ARMATURESPACE' - this head position in relation to the armature
+ - 'BONESPACE' - the head position in relation to itself
+ @type head: Dictionary
@ivar tail: This Bone's "tail" ending position when in rest state.
- @ivar matrix: This Bone's matrix.
+ Keys are:
+ - 'ARMATURESPACE' - this tail position in relation to the armature
+ - 'BONESPACE' - the tail position in relation to itself
+ @type tail: Dictionary
+ @ivar matrix: This Bone's matrix. This cannot be set.
+ Keys are:
+ - 'ARMATURESPACE' - this matrix of the bone in relation to the armature
+ - 'BONESPACE' - the matrix of the bone in relation to itself
+ @type matrix: Matrix Object
@ivar parent: The parent Bone.
+ @type parent: Bone Object
@ivar children: The children bones.
+ @type children: List of Bone Objects
+ @ivar weight: The bone's weight.
+ @type weight: Float
+ @ivar options: Various bone options which can be:
+ - Armature.CONNECTED: IK to parent
+ - Armature.HINGE: No parent rotation or scaling
+ - Armature.NO_DEFORM: The bone does not deform geometetry
+ - Armature.MULTIPLY: Multiply vgroups by envelope
+ - Armature.HIDDEN_EDIT: Hide bones in editmode
+ - Armature.ROOT_SELECTED: Selection of root ball of bone
+ - Armature.BONE_SELECTED: Selection of bone
+ - Armature.TIP_SELECTED: Selection of tip ball of bone
+ @type options: List of Constants
+ @ivar subdivision: The number of bone subdivisions.
+ @type subdivision: Int
+ @ivar deformDist: The deform distance of the bone
+ @type deformDist: Float
+ @ivar length: The length of the bone. This cannot be set.
+ @type length: Float
+ """
+
+ def hasParent():
+ """
+ Whether or not this bone has a parent
+ @rtype: Bool
+ """
+
+ def hasChildren():
+ """
+ Whether or not this bone has children
+ @rtype: Bool
+ """
+
+class Editbone:
+ """
+ The Editbone Object
+ ===================
+ This object is a wrapper for editbone data and is used only in the manipulation
+ of the armature in editmode.
+ @ivar name: The name of this Bone.
+ @type name: String
+ @ivar roll: This Bone's roll value (armaturespace).
+ @type roll: Float
+ @ivar head: This Bone's "head" ending position when in rest state (armaturespace).
+ @type head: Vector Object
+ @ivar tail: This Bone's "tail" ending position when in rest state (armaturespace).
+ @type tail: Vector Object
+ @ivar matrix: This Bone's matrix. (armaturespace) This cannot be set.
+ @type matrix: Matrix Object
+ @ivar parent: The parent Bone.
+ @type parent: Editbone Object
@ivar weight: The bone's weight.
+ @type weight: Float
@ivar options: Various bone options which can be:
- -CONNECTED: IK to parent
- -HINGE: No parent rotation or scaling
- -NO_DEFORM: The bone does not deform geometetry
- -MULTIPLY: Multiply vgroups by envelope
- -HIDDEN_EDIT: Hide bones in editmode
+ - Armature.CONNECTED: IK to parent
+ - Armature.HINGE: No parent rotation or scaling
+ - Armature.NO_DEFORM: The bone does not deform geometetry
+ - Armature.MULTIPLY: Multiply vgroups by envelope
+ - Armature.HIDDEN_EDIT: Hide bones in editmode
+ - Armature.ROOT_SELECTED: Selection of root ball of bone
+ - Armature.BONE_SELECTED: Selection of bone
+ - Armature.TIP_SELECTED: Selection of tip ball of bone
+ @type options: List of Constants
@ivar subdivision: The number of bone subdivisions.
- @ivar deform_dist: The deform distance of the bone
- """ \ No newline at end of file
+ @type subdivision: Int
+ @ivar deformDist: The deform distance of the bone
+ @type deformDist: Float
+ @ivar length: The length of the bone. This cannot be set.
+ @type length: Float
+ """
+
+ def hasParent():
+ """
+ Whether or not this bone has a parent
+ @rtype: Bool
+ """
+
+ def clearParent():
+ """
+ Set the parent to None
+ @rtype: None
+ """
diff --git a/source/blender/python/api2_2x/doc/Image.py b/source/blender/python/api2_2x/doc/Image.py
index aad3d84781b..1d25c550b3d 100644
--- a/source/blender/python/api2_2x/doc/Image.py
+++ b/source/blender/python/api2_2x/doc/Image.py
@@ -52,6 +52,13 @@ def Get (name = None):
- (): A list with all Image objects in the current scene.
"""
+def GetCurrent ():
+ """
+ Get the currently displayed Image from Blenders UV/Image window.
+ When multiple images are displayed, the last active UV/Image windows image is used.
+ @rtype: Blender Image
+ @return: The Current Blender Image, If there is no current image it returns None.
+ """
class Image:
"""
diff --git a/source/blender/python/api2_2x/sceneTimeLine.c b/source/blender/python/api2_2x/sceneTimeLine.c
index 58830d28ab4..89c55acc352 100644
--- a/source/blender/python/api2_2x/sceneTimeLine.c
+++ b/source/blender/python/api2_2x/sceneTimeLine.c
@@ -166,56 +166,72 @@ PyObject *M_TimeLine_Get (PyObject *self, PyObject *args) {
static PyObject *TimeLine_getFramesMarked (BPy_TimeLine *self, PyObject *args) {
- PyObject *marker_dict= PyDict_New ();
+ PyObject *marker_dict= NULL;
TimeMarker *marker_it= NULL;
PyObject *tmarker= NULL, *pyo= NULL;
if (!PyArg_ParseTuple (args, "|O", &tmarker))
- return EXPP_ReturnPyObjError (PyExc_TypeError,
- "expected nothing, string or int.");
+ return EXPP_ReturnPyObjError (PyExc_AttributeError,
+ "expected nothing, string or int as arguments.");
if (tmarker) {
- int f= (int)PyInt_AS_LONG (tmarker);
char s[64];
+ int frm= 0;
- if (PyString_Check (tmarker) && (BLI_strncpy (s, PyString_AsString(tmarker), 64)) )
+ if (PyString_Check (tmarker) && (BLI_strncpy(s, PyString_AsString (tmarker), 64)) ) {
for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next)
if (!strcmp (marker_it->name, s)) {
- f= (int)marker_it->frame;
- tmarker= PyInt_FromLong ((long int)marker_it->frame);
+ frm= (int)marker_it->frame;
break;
}
- if (PyInt_Check (tmarker) && f!=0)
- for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next)
- if (marker_it->frame==f) {
- if ((pyo= PyDict_GetItem ((PyObject*)marker_dict, PyInt_FromLong ((long int)marker_it->frame))) )
+ }
+ else if (PyInt_Check (tmarker))
+ frm= (int)PyInt_AS_LONG (tmarker);
+ else
+ return EXPP_ReturnPyObjError (PyExc_AttributeError,
+ "expected nothing, string or int as arguments.");
+ if (frm>0) {
+ marker_dict= PyDict_New ();
+ for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next){
+ if (marker_it->frame==frm) {
+ pyo= PyDict_GetItem ((PyObject*)marker_dict, PyInt_FromLong ((long int)marker_it->frame));
+ if (pyo) {
PyList_Append (pyo, PyString_FromString (marker_it->name));
- else {
- if (!pyo) pyo= PyList_New (0);
+ Py_INCREF (pyo);
+ }else{
+ pyo = PyList_New (0);
PyList_Append (pyo, PyString_FromString (marker_it->name));
}
-
- PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo);
+ PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo);
+ if (pyo) {
+ Py_DECREF (pyo);
+ pyo= NULL;
+ }
}
- }
- else
+ }
+ }
+
+ }else {
+ marker_dict= PyDict_New ();
for (marker_it= self->marker_list->first; marker_it; marker_it= marker_it->next) {
- if ((pyo= PyDict_GetItem ((PyObject *)marker_dict, PyInt_FromLong ((long int)marker_it->frame))) )
+ pyo=PyDict_GetItem ((PyObject*)marker_dict, PyInt_FromLong ((long int)marker_it->frame));
+ if (pyo) {
PyList_Append (pyo, PyString_FromString (marker_it->name));
- else {
+ Py_INCREF (pyo);
+ }else{
pyo= PyList_New (0);
PyList_Append (pyo, PyString_FromString (marker_it->name));
}
- PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo);
- }
-
- if (pyo) { /** because warnings messages **/
- Py_DECREF (pyo);
+ PyDict_SetItem (marker_dict, PyInt_FromLong ((long int)marker_it->frame), pyo);
+ if (pyo) {
+ Py_DECREF (pyo);
+ pyo= NULL;
+ }
}
+ }
- return marker_dict;
+ return marker_dict;
}
-
static PyObject *TimeLine_addMarker (BPy_TimeLine *self, PyObject *args) {
int frame= 0;
TimeMarker *marker= NULL, *marker_it= NULL;
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 68be4cdbb83..1a2f942fd2a 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -1893,60 +1893,81 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i
/* calculate U and V, for scanline (normal u and v are -1 to 0) */
if(u==1.0) {
- /* exception case for wire render of edge */
- if(vlr->v2==vlr->v3);
- else if( (vlr->flag & R_SMOOTH) || (texco & NEED_UV) ) {
- float detsh, t00, t10, t01, t11;
-
- if(vlr->snproj==0) {
- t00= v3->co[0]-v1->co[0]; t01= v3->co[1]-v1->co[1];
- t10= v3->co[0]-v2->co[0]; t11= v3->co[1]-v2->co[1];
- }
- else if(vlr->snproj==1) {
- t00= v3->co[0]-v1->co[0]; t01= v3->co[2]-v1->co[2];
- t10= v3->co[0]-v2->co[0]; t11= v3->co[2]-v2->co[2];
- }
- else {
- t00= v3->co[1]-v1->co[1]; t01= v3->co[2]-v1->co[2];
- t10= v3->co[1]-v2->co[1]; t11= v3->co[2]-v2->co[2];
- }
-
- detsh= 1.0/(t00*t11-t10*t01);
- t00*= detsh; t01*=detsh;
- t10*=detsh; t11*=detsh;
-
- if(vlr->snproj==0) {
- u= (shi->co[0]-v3->co[0])*t11-(shi->co[1]-v3->co[1])*t10;
- v= (shi->co[1]-v3->co[1])*t00-(shi->co[0]-v3->co[0])*t01;
- if(shi->osatex) {
- shi->dxuv[0]= shi->dxco[0]*t11- shi->dxco[1]*t10;
- shi->dxuv[1]= shi->dxco[1]*t00- shi->dxco[0]*t01;
- shi->dyuv[0]= shi->dyco[0]*t11- shi->dyco[1]*t10;
- shi->dyuv[1]= shi->dyco[1]*t00- shi->dyco[0]*t01;
+ if( (vlr->flag & R_SMOOTH) || (texco & NEED_UV) ) {
+ /* exception case for wire render of edge */
+ if(vlr->v2==vlr->v3) {
+ float lend, lenc;
+
+ lend= VecLenf(v2->co, v1->co);
+ lenc= VecLenf(shi->co, v1->co);
+
+ if(lend==0.0f) {
+ u=v= 0.0f;
}
- }
- else if(vlr->snproj==1) {
- u= (shi->co[0]-v3->co[0])*t11-(shi->co[2]-v3->co[2])*t10;
- v= (shi->co[2]-v3->co[2])*t00-(shi->co[0]-v3->co[0])*t01;
+ else {
+ u= - (1.0f - lenc/lend);
+ v= 0.0f;
+ }
+
if(shi->osatex) {
- shi->dxuv[0]= shi->dxco[0]*t11- shi->dxco[2]*t10;
- shi->dxuv[1]= shi->dxco[2]*t00- shi->dxco[0]*t01;
- shi->dyuv[0]= shi->dyco[0]*t11- shi->dyco[2]*t10;
- shi->dyuv[1]= shi->dyco[2]*t00- shi->dyco[0]*t01;
+ shi->dxuv[0]= 0.0f;
+ shi->dxuv[1]= 0.0f;
+ shi->dyuv[0]= 0.0f;
+ shi->dyuv[1]= 0.0f;
}
}
else {
- u= (shi->co[1]-v3->co[1])*t11-(shi->co[2]-v3->co[2])*t10;
- v= (shi->co[2]-v3->co[2])*t00-(shi->co[1]-v3->co[1])*t01;
- if(shi->osatex) {
- shi->dxuv[0]= shi->dxco[1]*t11- shi->dxco[2]*t10;
- shi->dxuv[1]= shi->dxco[2]*t00- shi->dxco[1]*t01;
- shi->dyuv[0]= shi->dyco[1]*t11- shi->dyco[2]*t10;
- shi->dyuv[1]= shi->dyco[2]*t00- shi->dyco[1]*t01;
+ float detsh, t00, t10, t01, t11;
+
+ if(vlr->snproj==0) {
+ t00= v3->co[0]-v1->co[0]; t01= v3->co[1]-v1->co[1];
+ t10= v3->co[0]-v2->co[0]; t11= v3->co[1]-v2->co[1];
+ }
+ else if(vlr->snproj==1) {
+ t00= v3->co[0]-v1->co[0]; t01= v3->co[2]-v1->co[2];
+ t10= v3->co[0]-v2->co[0]; t11= v3->co[2]-v2->co[2];
+ }
+ else {
+ t00= v3->co[1]-v1->co[1]; t01= v3->co[2]-v1->co[2];
+ t10= v3->co[1]-v2->co[1]; t11= v3->co[2]-v2->co[2];
+ }
+
+ detsh= 1.0/(t00*t11-t10*t01);
+ t00*= detsh; t01*=detsh;
+ t10*=detsh; t11*=detsh;
+
+ if(vlr->snproj==0) {
+ u= (shi->co[0]-v3->co[0])*t11-(shi->co[1]-v3->co[1])*t10;
+ v= (shi->co[1]-v3->co[1])*t00-(shi->co[0]-v3->co[0])*t01;
+ if(shi->osatex) {
+ shi->dxuv[0]= shi->dxco[0]*t11- shi->dxco[1]*t10;
+ shi->dxuv[1]= shi->dxco[1]*t00- shi->dxco[0]*t01;
+ shi->dyuv[0]= shi->dyco[0]*t11- shi->dyco[1]*t10;
+ shi->dyuv[1]= shi->dyco[1]*t00- shi->dyco[0]*t01;
+ }
+ }
+ else if(vlr->snproj==1) {
+ u= (shi->co[0]-v3->co[0])*t11-(shi->co[2]-v3->co[2])*t10;
+ v= (shi->co[2]-v3->co[2])*t00-(shi->co[0]-v3->co[0])*t01;
+ if(shi->osatex) {
+ shi->dxuv[0]= shi->dxco[0]*t11- shi->dxco[2]*t10;
+ shi->dxuv[1]= shi->dxco[2]*t00- shi->dxco[0]*t01;
+ shi->dyuv[0]= shi->dyco[0]*t11- shi->dyco[2]*t10;
+ shi->dyuv[1]= shi->dyco[2]*t00- shi->dyco[0]*t01;
+ }
+ }
+ else {
+ u= (shi->co[1]-v3->co[1])*t11-(shi->co[2]-v3->co[2])*t10;
+ v= (shi->co[2]-v3->co[2])*t00-(shi->co[1]-v3->co[1])*t01;
+ if(shi->osatex) {
+ shi->dxuv[0]= shi->dxco[1]*t11- shi->dxco[2]*t10;
+ shi->dxuv[1]= shi->dxco[2]*t00- shi->dxco[1]*t01;
+ shi->dyuv[0]= shi->dyco[1]*t11- shi->dyco[2]*t10;
+ shi->dyuv[1]= shi->dyco[2]*t00- shi->dyco[1]*t01;
+ }
}
}
- }
-
+ }
}
l= 1.0+u+v;
@@ -2086,10 +2107,9 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i
cp2= (char *)(vlr->vcol+j2);
cp3= (char *)(vlr->vcol+j3);
- shi->vcol[0]= (l*cp3[3]-u*cp1[3]-v*cp2[3])/255.0;
- shi->vcol[1]= (l*cp3[2]-u*cp1[2]-v*cp2[2])/255.0;
- shi->vcol[2]= (l*cp3[1]-u*cp1[1]-v*cp2[1])/255.0;
-
+ shi->vcol[0]= (l*((float)cp3[3]) - u*((float)cp1[3]) - v*((float)cp2[3]))/255.0;
+ shi->vcol[1]= (l*((float)cp3[2]) - u*((float)cp1[2]) - v*((float)cp2[2]))/255.0;
+ shi->vcol[2]= (l*((float)cp3[1]) - u*((float)cp1[1]) - v*((float)cp2[1]))/255.0;
}
else {
shi->vcol[0]= 0.0;
@@ -2548,9 +2568,14 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, floa
if(shr.alpha!=1.0 || alpha!=1.0) {
if(shi.mat->mode & MA_RAYTRANSP) {
- // sky was applied allready for ray transp, only do mist
- col[3]= shr.alpha;
fac= alpha;
+ if(R.r.mode & R_UNIFIED)
+ /* unified alpha overs everything... */
+ col[3]= 1.0f;
+ else {
+ /* sky was applied allready for ray transp, only do mist */
+ col[3]= shr.alpha;
+ }
}
else {
fac= alpha*(shr.alpha);
diff --git a/source/blender/render/intern/source/vanillaRenderPipe.c b/source/blender/render/intern/source/vanillaRenderPipe.c
index 5ab38b589e8..1b74adaae9c 100644
--- a/source/blender/render/intern/source/vanillaRenderPipe.c
+++ b/source/blender/render/intern/source/vanillaRenderPipe.c
@@ -1064,9 +1064,6 @@ static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2
j[2]= collector[2]; j[3]= collector[3];
}
- sampleFloatColV2FloatColVFilter(sampcol, colbuf1, colbuf2, colbuf3, osaNr);
-
-
/* Spothalos are part of the normal pixelshader, so for covered */
/* pixels they are handled ok. They are 'normally' alpha blended */
/* onto the existing colour in the collector. */
@@ -1077,8 +1074,15 @@ static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2
collector[1]= gammaCorrect(collector[1]);
collector[2]= gammaCorrect(collector[2]);
}
- addAlphaOverFloat(colbuf2+4, collector);
+
+ j = sampcol;
+ for(i = 0; i < osaNr; i++, j+=4) {
+ addAlphaOverFloat(j, collector);
+ }
}
+
+ sampleFloatColV2FloatColVFilter(sampcol, colbuf1, colbuf2, colbuf3, osaNr);
+
}
}
}
diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c
index 0f200a9e0e1..88a3136b567 100644
--- a/source/blender/renderconverter/intern/convertBlenderScene.c
+++ b/source/blender/renderconverter/intern/convertBlenderScene.c
@@ -1028,7 +1028,6 @@ static void static_particle_strand(Object *ob, Material *ma, float *orco, float
/* turn cross in pixelsize */
w= vec[2]*R.winmat[2][3] + R.winmat[3][3];
-
dx= R.rectx*cross[0]*R.winmat[0][0]/w;
dy= R.recty*cross[1]*R.winmat[1][1]/w;
w= sqrt(dx*dx + dy*dy);
@@ -1154,6 +1153,7 @@ static void render_static_particle_system(Object *ob, PartEff *paf)
orco[1] = (vec1[1]-loc_tex[1])/size_tex[1];
orco[2] = (vec1[2]-loc_tex[2])/size_tex[2];
}
+ MTC_Mat4MulVecfl(mat, vec1);
mtime= pa->time+pa->lifetime+paf->staticstep-1;
first= 1;
@@ -1441,6 +1441,161 @@ static void init_render_mball(Object *ob)
/* ------------------------------------------------------------------------- */
/* convert */
+struct edgesort {
+ int v1, v2;
+ int has_mcol;
+ TFace *tface;
+ float uv1[2], uv2[2];
+ unsigned int mcol1, mcol2;
+};
+
+/* edges have to be added with lowest index first for sorting */
+static void to_edgesort(struct edgesort *ed, int i1, int i2, int v1, int v2, unsigned int *mcol, TFace *tface)
+{
+ if(v1<v2) {
+ ed->v1= v1; ed->v2= v2;
+ }
+ else {
+ ed->v1= v2; ed->v2= v1;
+ SWAP(int, i1, i2);
+ }
+ /* copy color and tface, edges use different ordering */
+ ed->tface= tface;
+ if(tface) {
+ ed->uv1[0]= tface->uv[i1][0];
+ ed->uv1[1]= tface->uv[i1][1];
+ ed->uv2[0]= tface->uv[i2][0];
+ ed->uv2[1]= tface->uv[i2][1];
+
+ ed->mcol1= tface->col[i1];
+ ed->mcol2= tface->col[i2];
+ }
+ ed->has_mcol= mcol!=NULL;
+ if(mcol) {
+ ed->mcol1= mcol[i1];
+ ed->mcol2= mcol[i2];
+ }
+}
+
+static int vergedgesort(const void *v1, const void *v2)
+{
+ const struct edgesort *x1=v1, *x2=v2;
+
+ if( x1->v1 > x2->v1) return 1;
+ else if( x1->v1 < x2->v1) return -1;
+ else if( x1->v2 > x2->v2) return 1;
+ else if( x1->v2 < x2->v2) return -1;
+
+ return 0;
+}
+
+static struct edgesort *make_mesh_edge_lookup(Mesh *me, DispListMesh *dlm, int *totedgesort)
+{
+ MFace *mf, *mface;
+ TFace *tface=NULL;
+ struct edgesort *edsort, *ed;
+ unsigned int *mcol=NULL;
+ int a, totedge=0, totface;
+
+ if (dlm) {
+ mface= dlm->mface;
+ totface= dlm->totface;
+ if (dlm->tface)
+ tface= dlm->tface;
+ else if (dlm->mcol)
+ mcol= (unsigned int *)dlm->mcol;
+ } else {
+ mface= me->mface;
+ totface= me->totface;
+ if (me->tface)
+ tface= me->tface;
+ else if (me->mcol)
+ mcol= (unsigned int *)me->mcol;
+ }
+
+ if(mcol==NULL && tface==NULL) return NULL;
+
+ /* make sorted table with edges and and tface/mcol pointers in it */
+ for(a= totface, mf= mface; a>0; a--, mf++) {
+ if(mf->v4) totedge+=4;
+ else if(mf->v3) totedge+=3;
+ }
+ if(totedge==0) return NULL;
+
+ ed= edsort= MEM_mallocN(totedge*sizeof(struct edgesort), "edgesort");
+
+ for(a= me->totface, mf= mface; a>0; a--, mf++) {
+ if(mface->v4 || mface->v3) {
+ to_edgesort(ed++, 0, 1, mf->v1, mf->v2, mcol, tface);
+ to_edgesort(ed++, 1, 2, mf->v2, mf->v3, mcol, tface);
+ if(mf->v4) {
+ to_edgesort(ed++, 2, 3, mf->v3, mf->v4, mcol, tface);
+ to_edgesort(ed++, 3, 0, mf->v4, mf->v1, mcol, tface);
+ }
+ else if(mf->v3) {
+ to_edgesort(ed++, 2, 3, mf->v3, mf->v1, mcol, tface);
+ }
+ }
+ if(mcol) mcol+=4;
+ if(tface) tface++;
+ }
+
+ qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort);
+
+ *totedgesort= totedge;
+ return edsort;
+}
+
+static void use_mesh_edge_lookup(Mesh *me, DispListMesh *dlm, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge)
+{
+ struct edgesort ed, *edp;
+
+ if(medge->v1 < medge->v2) {
+ ed.v1= medge->v1; ed.v2= medge->v2;
+ }
+ else {
+ ed.v1= medge->v2; ed.v2= medge->v1;
+ }
+
+ edp= bsearch(&ed, edgetable, totedge, sizeof(struct edgesort), vergedgesort);
+ if(edp) {
+ /* since edges have different index ordering, we have to duplicate mcol and tface */
+ if(edp->tface) {
+ vlr->tface= BLI_memarena_alloc(R.memArena, sizeof(TFace));
+ vlr->vcol= vlr->tface->col;
+ memcpy(vlr->tface, edp->tface, sizeof(TFace));
+
+ if(edp->v1==medge->v1) {
+ vlr->vcol[0]= edp->mcol1;
+ vlr->vcol[1]= edp->mcol2;
+ }
+ else {
+ vlr->vcol[0]= edp->mcol2;
+ vlr->vcol[1]= edp->mcol1;
+ }
+ vlr->vcol[2]= vlr->vcol[1];
+ vlr->vcol[3]= vlr->vcol[1];
+
+ if(edp->v1==medge->v1) {
+ memcpy(vlr->tface->uv[0], edp->uv1, 2*sizeof(float));
+ memcpy(vlr->tface->uv[1], edp->uv2, 2*sizeof(float));
+ }
+ else {
+ memcpy(vlr->tface->uv[0], edp->uv2, 2*sizeof(float));
+ memcpy(vlr->tface->uv[1], edp->uv1, 2*sizeof(float));
+ }
+ memcpy(vlr->tface->uv[2], vlr->tface->uv[1], 2*sizeof(float));
+ memcpy(vlr->tface->uv[3], vlr->tface->uv[1], 2*sizeof(float));
+ }
+ else if(edp->has_mcol) {
+ vlr->vcol= BLI_memarena_alloc(R.memArena, sizeof(MCol)*4);
+ vlr->vcol[0]= edp->mcol1;
+ vlr->vcol[1]= edp->mcol2;
+ vlr->vcol[2]= vlr->vcol[1];
+ vlr->vcol[3]= vlr->vcol[1];
+ }
+ }
+}
static void init_render_mesh(Object *ob)
{
@@ -1626,13 +1781,13 @@ static void init_render_mesh(Object *ob)
else {
if(dlm) {
if(tface) {
- vlr->tface= BLI_memarena_alloc(R.memArena, sizeof(*vlr->tface));
+ vlr->tface= BLI_memarena_alloc(R.memArena, sizeof(TFace));
vlr->vcol= vlr->tface->col;
- memcpy(vlr->tface, tface, sizeof(*tface));
+ memcpy(vlr->tface, tface, sizeof(TFace));
}
else if (vertcol) {
- vlr->vcol= BLI_memarena_alloc(R.memArena, sizeof(int)*16);
- memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*16);
+ vlr->vcol= BLI_memarena_alloc(R.memArena, sizeof(int)*4);
+ memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*4);
}
} else {
if(tface) {
@@ -1658,8 +1813,14 @@ static void init_render_mesh(Object *ob)
ma= give_render_material(ob, 1);
if(end && (ma->mode & MA_WIRE)) {
MEdge *medge;
+ struct edgesort *edgetable;
+ int totedge;
+
medge= dlm?dlm->medge:me->medge;
+ /* we want edges to have UV and vcol too... */
+ edgetable= make_mesh_edge_lookup(me, dlm, &totedge);
+
for(a1=0; a1<end; a1++, medge++) {
if (medge->flag&ME_EDGERENDER) {
MVert *v0 = &mvert[medge->v1];
@@ -1672,6 +1833,10 @@ static void init_render_mesh(Object *ob)
vlr->v3= vlr->v2;
vlr->v4= NULL;
+ if(edgetable) {
+ use_mesh_edge_lookup(me, dlm, medge, vlr, edgetable, totedge);
+ }
+
xn= (v0->no[0]+v1->no[0]);
yn= (v0->no[1]+v1->no[1]);
zn= (v0->no[2]+v1->no[2]);
@@ -1687,6 +1852,8 @@ static void init_render_mesh(Object *ob)
vlr->lay= ob->lay;
}
}
+ if(edgetable)
+ MEM_freeN(edgetable);
}
}
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index f9679c3be92..ff980a91f89 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -2220,14 +2220,14 @@ static void object_panel_fluidsim(Object *ob)
&ob->fluidsimFlag, 0, 0, 0, 0, "Sets object to participate in fluid simulation");
if(ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
- FluidsimSettings *fss= ob->fluidsimSettings;
-
- if(fss==NULL) {
- fss = ob->fluidsimSettings = fluidsimSettingsNew(ob);
- }
if(ob->type==OB_MESH) {
-
+ FluidsimSettings *fss= ob->fluidsimSettings;
+
+ if(fss==NULL) {
+ fss = ob->fluidsimSettings = fluidsimSettingsNew(ob);
+ }
+
uiBlockBeginAlign(block);
uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Domain", 90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_DOMAIN, 20.0, 1.0, "Bounding box of this object represents the computational domain of the fluid simulation.");
uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Fluid", 160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_FLUID, 20.0, 2.0, "Object represents a volume of fluid in the simulation.");
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index 22490645799..c1d892bfc35 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -111,7 +111,7 @@ extern float centre[3], centroid[3]; /* Originally defined in editobject.c */
/* **************** tools on Editmode Armature **************** */
/* converts Bones to EditBone list, used for tools as well */
-static void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
+void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
{
EditBone *eBone;
Bone *curBone;
@@ -228,7 +228,7 @@ static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist)
}
/* converts the editbones back to the armature */
-static void editbones_to_armature (ListBase *list, Object *ob)
+void editbones_to_armature (ListBase *list, Object *ob)
{
bArmature *arm;
EditBone *eBone;
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index c50597605d7..9834bdc704c 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -186,6 +186,12 @@ EditIpo *get_active_editipo(void)
if(G.sipo==NULL)
return NULL;
+ /* prevent confusing situations, like for sequencer */
+ if(G.sipo->totipo==1) {
+ ei= G.sipo->editipo;
+ ei->flag |= IPO_ACTIVE;
+ return ei;
+ }
for(a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++)
if(ei->flag & IPO_ACTIVE)
return ei;
@@ -976,7 +982,7 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
else if(blocktype==ID_SEQ) {
extern Sequence *last_seq;
- if(last_seq && (last_seq->type & SEQ_EFFECT)) {
+ if(last_seq && ((last_seq->type & SEQ_EFFECT)||(last_seq->type == SEQ_SOUND))) {
*from= (ID *)last_seq;
*ipo= last_seq->ipo;
}
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index baf31bbf4ca..129e0fe2c66 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -2086,9 +2086,9 @@ void special_editmenu(void)
break;
case 3:
if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
- waitcursor(1);
randfac= 10;
if(button(&randfac, 1, 100, "Rand fac:")==0) return;
+ waitcursor(1);
fac= -( (float)randfac )/100;
esubdivideflag(1, fac, G.scene->toolsettings->editbutflag, numcuts, 0);
BIF_undo_push("Subdivide Fractal");
@@ -3687,6 +3687,7 @@ void single_obdata_users(int flag)
id= ob->data;
if(id && id->us>1 && id->lib==0) {
+ ob->recalc= OB_RECALC_DATA;
switch(ob->type) {
case OB_LAMP:
@@ -4186,7 +4187,6 @@ static void adduplicate__forwardModifierLinks(void *userData, Object *ob, Object
}
void adduplicate(int noTrans)
-/* dtrans is 3 x 3xfloat dloc, drot en dsize */
{
Base *base, *basen;
Object *ob, *obn;
diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c
index b73329175b5..a89c5e876f9 100644
--- a/source/blender/src/fluidsim.c
+++ b/source/blender/src/fluidsim.c
@@ -143,6 +143,10 @@ FluidsimSettings *fluidsimSettingsNew(struct Object *srcob)
{
//char blendDir[FILE_MAXDIR], blendFile[FILE_MAXFILE];
FluidsimSettings *fss;
+
+ /* this call uses derivedMesh methods... */
+ if(srcob->type!=OB_MESH) return NULL;
+
fss= MEM_callocN( sizeof(FluidsimSettings), "fluidsimsettings memory");
fss->type = 0;
diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c
index 8b749b809c0..865db9fe000 100644
--- a/source/blender/src/poseobject.c
+++ b/source/blender/src/poseobject.c
@@ -170,13 +170,18 @@ bPoseChannel *get_active_posechannel (Object *ob)
return NULL;
}
+/* only for real IK, not for auto-IK */
int pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
{
bConstraint *con;
Bone *bone;
for(con= pchan->constraints.first; con; con= con->next) {
- if(con->type==CONSTRAINT_TYPE_KINEMATIC) return 1;
+ if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
+ bKinematicConstraint *data= con->data;
+ if((data->flag & CONSTRAINT_IK_AUTO)==0)
+ return 1;
+ }
}
for(bone= pchan->bone->childbase.first; bone; bone= bone->next) {
pchan= get_pose_channel(ob->pose, bone->name);
diff --git a/source/blender/src/transform_numinput.c b/source/blender/src/transform_numinput.c
index aa35af7d312..8ea83463bc0 100755
--- a/source/blender/src/transform_numinput.c
+++ b/source/blender/src/transform_numinput.c
@@ -59,32 +59,35 @@ void outputNumInput(NumInput *n, char *str)
else
cur = '|';
- switch (n->ctrl[i]) {
- case 0:
- sprintf(&str[j*20], "NONE%c", cur);
- break;
- case 1:
- case -1:
- sprintf(&str[j*20], "%.0f%c", n->val[i], cur);
- break;
- case 10:
- case -10:
- sprintf(&str[j*20], "%.f.%c", n->val[i], cur);
- break;
- case 100:
- case -100:
- sprintf(&str[j*20], "%.1f%c", n->val[i], cur);
- break;
- case 1000:
- case -1000:
- sprintf(&str[j*20], "%.2f%c", n->val[i], cur);
- case 10000:
- case -10000:
- sprintf(&str[j*20], "%.3f%c", n->val[i], cur);
- break;
- default:
- sprintf(&str[j*20], "%.4f%c", n->val[i], cur);
- }
+ if( n->val[i] > 1e10 || n->val[i] < -1e10 )
+ sprintf(&str[j*20], "%.4e%c", n->val[i], cur);
+ else
+ switch (n->ctrl[i]) {
+ case 0:
+ sprintf(&str[j*20], "NONE%c", cur);
+ break;
+ case 1:
+ case -1:
+ sprintf(&str[j*20], "%.0f%c", n->val[i], cur);
+ break;
+ case 10:
+ case -10:
+ sprintf(&str[j*20], "%.f.%c", n->val[i], cur);
+ break;
+ case 100:
+ case -100:
+ sprintf(&str[j*20], "%.1f%c", n->val[i], cur);
+ break;
+ case 1000:
+ case -1000:
+ sprintf(&str[j*20], "%.2f%c", n->val[i], cur);
+ case 10000:
+ case -10000:
+ sprintf(&str[j*20], "%.3f%c", n->val[i], cur);
+ break;
+ default:
+ sprintf(&str[j*20], "%.4e%c", n->val[i], cur);
+ }
}
}
diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c
index 40160c42367..f386ea3ecf0 100644
--- a/source/blender/src/writeimage.c
+++ b/source/blender/src/writeimage.c
@@ -100,8 +100,9 @@ void BIF_save_envmap(EnvMap *env, char *str)
int dx;
/* all interactive stuff is handled in buttons.c */
-
- dx= (env->cuberes * R.r.size) / 100;
+ if(env->cube[0]->ibuf==NULL) return;
+
+ dx= env->cube[0]->ibuf->x;
ibuf= IMB_allocImBuf(3*dx, 2*dx, 24, IB_rect, 0);
IMB_rectop(ibuf, env->cube[0]->ibuf,