From ef85f6ea21c0af43b96c6c3cbb1b80f23ac00266 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 26 Oct 2007 08:19:40 +0000 Subject: ==Python API== layerMask access for bone and armatures Window.PoseMode() similar to Window.EditMode() --- source/blender/python/api2_2x/Armature.c | 36 ++++++++++++-- source/blender/python/api2_2x/Bone.c | 68 +++++++++++++++++++++++++++ source/blender/python/api2_2x/Bone.h | 1 + source/blender/python/api2_2x/Window.c | 33 +++++++++++++ source/blender/python/api2_2x/doc/Armature.py | 10 ++++ source/blender/python/api2_2x/doc/Window.py | 14 ++++++ source/blender/src/drawimage.c | 2 +- 7 files changed, 160 insertions(+), 4 deletions(-) diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c index 1ad5938c17e..47ee2564698 100644 --- a/source/blender/python/api2_2x/Armature.c +++ b/source/blender/python/api2_2x/Armature.c @@ -297,9 +297,7 @@ static int BonesDict_SetItem(BPy_BonesDict *self, PyObject *key, PyObject *value editbone->zwidth = ((BPy_EditBone*)value)->zwidth; VECCOPY(editbone->head, ((BPy_EditBone*)value)->head); VECCOPY(editbone->tail, ((BPy_EditBone*)value)->tail); - - // FIXME, should be exposed via python. this avoids creating bones with no layers. - editbone->layer= 1; + editbone->layer= ((BPy_EditBone*)value)->layer; //set object pointer ((BPy_EditBone*)value)->editbone = editbone; @@ -927,6 +925,36 @@ AttributeError: return EXPP_intError(PyExc_AttributeError, "%s%s", sArmatureError, "You are not allowed to change the .Bones attribute"); } + +//------------------------Bone.layerMask (get) +static PyObject *Armature_getLayerMask(BPy_Armature *self) +{ + /* do this extra stuff because the short's bits can be negative values */ + unsigned short laymask = 0; + laymask |= self->armature->layer; + return PyInt_FromLong((int)laymask); +} +//------------------------Bone.layerMask (set) +static int Armature_setLayerMask(BPy_Armature *self, PyObject *value) +{ + int laymask; + if (!PyInt_Check(value)) { + return EXPP_ReturnIntError( PyExc_AttributeError, + "expected an integer (bitmask) as argument" ); + } + + laymask = PyInt_AsLong(value); + + if (laymask <= 0 || laymask > (1<<16) - 1) + return EXPP_ReturnIntError( PyExc_AttributeError, + "bitmask must have from 1 up to 16 bits set"); + + self->armature->layer = 0; + self->armature->layer |= laymask; + + return 0; +} + //------------------TYPE_OBECT IMPLEMENTATION-------------------------- //------------------------tp_doc //The __doc__ string for this object @@ -974,6 +1002,8 @@ static PyGetSetDef BPy_Armature_getset[] = { "Adds temporal IK chains while grabbing bones", NULL}, {"layers", (getter)Armature_getLayers, (setter)Armature_setLayers, "List of layers for the armature", NULL}, + {"layerMask", (getter)Armature_getLayerMask, (setter)Armature_setLayerMask, + "Layer bitmask", NULL }, {NULL, NULL, NULL, NULL, NULL} }; //------------------------tp_new diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c index 733b8251215..5eeb4bb2817 100644 --- a/source/blender/python/api2_2x/Bone.c +++ b/source/blender/python/api2_2x/Bone.c @@ -709,6 +709,40 @@ AttributeError: sEditBoneError, ".tailRadius: ", "expects a float"); } +//------------------------Bone.layerMask (get) +static PyObject *EditBone_getLayerMask(BPy_EditBone *self) +{ + /* do this extra stuff because the short's bits can be negative values */ + unsigned short laymask = 0; + if (self->editbone) laymask |= self->editbone->layer; + else laymask |= self->layer; + return PyInt_FromLong((int)laymask); +} +//------------------------Bone.layerMask (set) +static int EditBone_setLayerMask(BPy_EditBone *self, PyObject *value) +{ + int laymask; + if (!PyInt_Check(value)) { + return EXPP_ReturnIntError( PyExc_AttributeError, + "expected an integer (bitmask) as argument" ); + } + + laymask = PyInt_AsLong(value); + + if (laymask <= 0 || laymask > (1<<16) - 1) + return EXPP_ReturnIntError( PyExc_AttributeError, + "bitmask must have from 1 up to 16 bits set"); + + if (self->editbone) { + self->editbone->layer = 0; + self->editbone->layer |= laymask; + } else { + self->layer = 0; + self->layer |= laymask; + } + + return 0; +} //------------------TYPE_OBECT IMPLEMENTATION-------------------------- //------------------------tp_methods @@ -749,6 +783,8 @@ static PyGetSetDef BPy_EditBone_getset[] = { "Set the radius of this bones tip", NULL}, {"headRadius", (getter)EditBone_getHeadRadius, (setter)EditBone_setHeadRadius, "Set the radius of this bones head", NULL}, + {"layerMask", (getter)EditBone_getLayerMask, (setter)EditBone_setLayerMask, + "Layer bitmask", NULL }, {NULL, NULL, NULL, NULL,NULL} }; @@ -803,6 +839,7 @@ static PyObject *EditBone_new(PyTypeObject *type, PyObject *args, PyObject *kwds py_editBone->rad_head= 0.10f; py_editBone->rad_tail= 0.05f; py_editBone->segments= 1; + py_editBone->layer= 1; py_editBone->flag = 0; py_editBone->roll = 0.0f; @@ -1203,6 +1240,35 @@ AttributeError: sEditBoneError, ".headRadius: ", "expects a float"); } +//------------------------Bone.layerMask (get) +static PyObject *Bone_getLayerMask(BPy_Bone *self) +{ + /* do this extra stuff because the short's bits can be negative values */ + unsigned short laymask = 0; + laymask |= self->bone->layer; + return PyInt_FromLong((int)laymask); +} +//------------------------Bone.layerMask (set) +static int Bone_setLayerMask(BPy_Bone *self, PyObject *value) +{ + int laymask; + if (!PyInt_Check(value)) { + return EXPP_ReturnIntError( PyExc_AttributeError, + "expected an integer (bitmask) as argument" ); + } + + laymask = PyInt_AsLong(value); + + if (laymask <= 0 || laymask > (1<<16) - 1) + return EXPP_ReturnIntError( PyExc_AttributeError, + "bitmask must have from 1 up to 16 bits set"); + + self->bone->layer = 0; + self->bone->layer |= laymask; + + return 0; +} + //------------------TYPE_OBECT IMPLEMENTATION-------------------------- //------------------------tp_methods //This contains a list of all methods the object contains @@ -1246,6 +1312,8 @@ static PyGetSetDef BPy_Bone_getset[] = { "Set the radius of this bones tip", NULL}, {"headRadius", (getter)Bone_getHeadRadius, (setter)Bone_setHeadRadius, "Set the radius of this bones head", NULL}, + {"layerMask", (getter)Bone_getLayerMask, (setter)Bone_setLayerMask, + "Layer bitmask", NULL }, {NULL, NULL, NULL, NULL,NULL} }; //------------------------tp_repr diff --git a/source/blender/python/api2_2x/Bone.h b/source/blender/python/api2_2x/Bone.h index c3f5de81714..aa076afbed7 100644 --- a/source/blender/python/api2_2x/Bone.h +++ b/source/blender/python/api2_2x/Bone.h @@ -65,6 +65,7 @@ typedef struct { float rad_head; float rad_tail; short segments; + short layer; } BPy_EditBone; /*-------------------VISIBLE PROTOTYPES-------------------------*/ PyObject *PyBone_FromBone(struct Bone *bone); diff --git a/source/blender/python/api2_2x/Window.c b/source/blender/python/api2_2x/Window.c index 9bcf1290bb0..323f209651a 100644 --- a/source/blender/python/api2_2x/Window.c +++ b/source/blender/python/api2_2x/Window.c @@ -47,6 +47,7 @@ #include "BIF_screen.h" #include "BIF_space.h" #include "BIF_drawtext.h" +#include "BIF_poseobject.h" #include "DNA_view3d_types.h" #include "DNA_space_types.h" #include "DNA_scene_types.h" @@ -86,6 +87,7 @@ static PyObject *M_Window_GetPerspMatrix( PyObject * self ); static PyObject *M_Window_FileSelector( PyObject * self, PyObject * args ); static PyObject *M_Window_ImageSelector( PyObject * self, PyObject * args ); static PyObject *M_Window_EditMode( PyObject * self, PyObject * args ); +static PyObject *M_Window_PoseMode( PyObject * self, PyObject * args ); static PyObject *M_Window_ViewLayers( PyObject * self, PyObject * args ); static PyObject *M_Window_CameraView( PyObject * self, PyObject * args ); static PyObject *M_Window_QTest( PyObject * self ); @@ -180,6 +182,9 @@ Returns the current status. This function is mostly useful to leave\n\ edit mode before applying changes to a mesh (otherwise the changes will\n\ be lost) and then returning to it upon leaving."; +static char M_Window_PoseMode_doc[] = + "() - Get the current status -- 0: not in pose mode; 1: in edit mode"; + static char M_Window_ViewLayers_doc[] = "(layers = [], winid = None) - Get/set active layers in all 3d View windows.\n\ () - Make no changes, only return currently visible layers.\n\ @@ -325,6 +330,8 @@ struct PyMethodDef M_Window_methods[] = { M_Window_GetPerspMatrix_doc}, {"EditMode", ( PyCFunction ) M_Window_EditMode, METH_VARARGS, M_Window_EditMode_doc}, + {"PoseMode", ( PyCFunction ) M_Window_PoseMode, METH_VARARGS, + M_Window_PoseMode_doc}, {"ViewLayers", ( PyCFunction ) M_Window_ViewLayers, METH_VARARGS, M_Window_ViewLayers_doc}, /* typo, deprecate someday: */ @@ -949,6 +956,32 @@ static PyObject *M_Window_EditMode( PyObject * self, PyObject * args ) return Py_BuildValue( "h", G.obedit ? 1 : 0 ); } +static PyObject *M_Window_PoseMode( PyObject * self, PyObject * args ) +{ + short status = -1; + short is_posemode = 0; + Base *base; + + if( !PyArg_ParseTuple( args, "|h", &status ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected optional int (bool) as argument" ); + + if( status >= 0 ) { + if( status ) { + enter_posemode(); + } else if( G.obedit ) { + exit_posemode(); + } + } + + base= BASACT; + if (base && base->object->flag & OB_POSEMODE) { + is_posemode = 1; + } + + return Py_BuildValue( "h", is_posemode ); +} + static PyObject *M_Window_ViewLayers( PyObject * self, PyObject * args ) { PyObject *item = NULL; diff --git a/source/blender/python/api2_2x/doc/Armature.py b/source/blender/python/api2_2x/doc/Armature.py index 157e8b28656..0dbaf28d6f8 100644 --- a/source/blender/python/api2_2x/doc/Armature.py +++ b/source/blender/python/api2_2x/doc/Armature.py @@ -156,6 +156,11 @@ class Armature: @type mirrorEdit: Bool @ivar autoIK: Adds temporary IK chains while grabbing bones @type autoIK: Bool + @ivar layerMask: Layer bitmask + Example:: + # set armature to layers 14 and 16 + armature.layerMask = (1<<13) + (1<<15) + @type layerMask: Int """ def __init__(name = 'myArmature'): @@ -282,6 +287,11 @@ class Bone: @type headRadius: Float @ivar tailRadius: The radius of this bones head (used for envalope bones) @type tailRadius: Float + @ivar layerMask: Layer bitmask + Example:: + # set bone to layers 14 and 16 + bone.layerMask = (1<<13) + (1<<15) + @type layerMask: Int """ def hasParent(): diff --git a/source/blender/python/api2_2x/doc/Window.py b/source/blender/python/api2_2x/doc/Window.py index d59b5ec9fa6..b5145d34ca2 100644 --- a/source/blender/python/api2_2x/doc/Window.py +++ b/source/blender/python/api2_2x/doc/Window.py @@ -284,6 +284,20 @@ def EditMode(enable = -1, undo_msg = 'From script', undo = 1): because the normal mesh will be rebuilt based on its unchanged edit mesh. """ +def PoseMode(enable = -1): + """ + Get and optionally set the current pose mode status: in or out. + @type enable: int + @param enable: get/set current status: + - -1: just return current status (default); + - 0: leave edit mode; + - 1: enter edit mode. + + @return: 0 if Blender is not in edit mode right now, 1 otherwise. + @warn: This uses the active armature objects posemode status, enabling pose + mode for non armature objects will always fail. + """ + def ViewLayers (layers = [], winid = None): """ Get and optionally set the currently visible layers in all 3d Views. diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index 85be4298922..f75de0bb331 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -424,7 +424,7 @@ static void drawcursor_sima(float xuser_asp, float yuser_asp) int wi, hi; float w, h; - if (!G.obedit) return; + if (!G.obedit || !CustomData_has_layer(&G.editMesh->fdata, CD_MTFACE)) return; transform_width_height_tface_uv(&wi, &hi); w = (((float)wi)/256.0f)*G.sima->zoom * xuser_asp; -- cgit v1.2.3