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:
authorJoseph Gilbert <ascotan@gmail.com>2004-04-19 10:57:41 +0400
committerJoseph Gilbert <ascotan@gmail.com>2004-04-19 10:57:41 +0400
commita6a32cf50414b5660c802dcd9067d422aaf5537f (patch)
treecaf1a009946eef9ec9c74fdb90bc43b70a29f806 /source/blender/python/api2_2x/NLA.c
parent713a0ceefea27ea3d0b3a18a5d21cbe65803b93c (diff)
-NLA module added
-ability to set poses for the armatures - allows for keyframing armatures -adds support for actions/actionchannels -additional checking for addBone and clear parenting -moved getActionIpos from object module to NLA module
Diffstat (limited to 'source/blender/python/api2_2x/NLA.c')
-rw-r--r--source/blender/python/api2_2x/NLA.c468
1 files changed, 468 insertions, 0 deletions
diff --git a/source/blender/python/api2_2x/NLA.c b/source/blender/python/api2_2x/NLA.c
new file mode 100644
index 00000000000..9ae6bd66bbc
--- /dev/null
+++ b/source/blender/python/api2_2x/NLA.c
@@ -0,0 +1,468 @@
+/*
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * This is a new part of Blender.
+ *
+ * Contributor(s): Joseph Gilbert
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+*/
+
+#include "NLA.h"
+#include "Object.h"
+#include <BKE_action.h>
+#include <BKE_global.h>
+#include <BKE_main.h>
+#include "Types.h"
+
+/*****************************************************************************/
+/* Python API function prototypes for the NLA module. */
+/*****************************************************************************/
+static PyObject *M_NLA_NewAction (PyObject * self, PyObject * args);
+static PyObject *M_NLA_CopyAction (PyObject * self, PyObject * args);
+static PyObject *M_NLA_GetActions(PyObject* self);
+
+/*****************************************************************************/
+/* The following string definitions are used for documentation strings. */
+/* In Python these will be written to the console when doing a */
+/* Blender.Armature.NLA.__doc__ */
+/*****************************************************************************/
+char M_NLA_doc[] = "The Blender NLA module -This module provides control over Armature keyframing in Blender.";
+char M_NLA_NewAction_doc[] = "(name) - Create new action for linking to an object.";
+char M_NLA_CopyAction_doc[] = "(name) - Copy action and return copy.";
+char M_NLA_GetActions_doc[] = "(name) - Returns a dictionary of actions.";
+
+/*****************************************************************************/
+/* Python method structure definition for Blender.Armature.NLA module: */
+/*****************************************************************************/
+struct PyMethodDef M_NLA_methods[] = {
+ {"NewAction", (PyCFunction) M_NLA_NewAction, METH_VARARGS,
+ M_NLA_NewAction_doc},
+ {"CopyAction", (PyCFunction) M_NLA_CopyAction, METH_VARARGS,
+ M_NLA_CopyAction_doc},
+ {"GetActions", (PyCFunction) M_NLA_GetActions, METH_NOARGS,
+ M_NLA_GetActions_doc},
+ {NULL, NULL, 0, NULL}
+};
+/*****************************************************************************/
+/* Python BPy_Action methods declarations: */
+/*****************************************************************************/
+static PyObject *Action_getName (BPy_Action * self);
+static PyObject *Action_setName (BPy_Action * self, PyObject * args);
+static PyObject *Action_setActive (BPy_Action * self, PyObject * args);
+static PyObject *Action_getChannelIpo(BPy_Action * self, PyObject * args);
+static PyObject *Action_removeChannel(BPy_Action * self, PyObject * args);
+static PyObject *Action_getAllChannelIpos(BPy_Action*self);
+
+/*****************************************************************************/
+/* Python BPy_Action methods table: */
+/*****************************************************************************/
+static PyMethodDef BPy_Action_methods[] = {
+ /* name, method, flags, doc */
+ {"getName", (PyCFunction) Action_getName, METH_NOARGS,
+ "() - return Action name"},
+ {"setName", (PyCFunction) Action_setName, METH_VARARGS,
+ "(str) - rename Action"},
+ {"setActive", (PyCFunction) Action_setActive, METH_VARARGS,
+ "(str) -set this action as the active action for an object"},
+ {"getChannelIpo", (PyCFunction) Action_getChannelIpo, METH_VARARGS,
+ "(str) -get the Ipo from a named action channel in this action"},
+ {"removeChannel", (PyCFunction) Action_removeChannel, METH_VARARGS,
+ "(str) -remove the channel from the action"},
+ {"getAllChannelIpos", (PyCFunction)Action_getAllChannelIpos, METH_NOARGS,
+ "() - Return a dict of (name:ipo)-keys containing each channel in the object's action"},
+ {NULL, NULL, 0, NULL}
+};
+
+/*****************************************************************************/
+/* Python TypeAction callback function prototypes: */
+/*****************************************************************************/
+static void Action_dealloc (BPy_Action * bone);
+static PyObject *Action_getAttr (BPy_Action * bone, char *name);
+static int Action_setAttr (BPy_Action * bone, char *name, PyObject * v);
+static PyObject *Action_repr (BPy_Action * bone);
+
+/*****************************************************************************/
+/* Python TypeAction structure definition: */
+/*****************************************************************************/
+PyTypeObject Action_Type = {
+ PyObject_HEAD_INIT (NULL) 0, /* ob_size */
+ "Blender Action", /* tp_name */
+ sizeof (BPy_Action), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor) Action_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc) Action_getAttr, /* tp_getattr */
+ (setattrfunc) Action_setAttr, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc) Action_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_as_hash */
+ 0, 0, 0, 0, 0, 0,
+ 0, /* tp_doc */
+ 0, 0, 0, 0, 0, 0,
+ BPy_Action_methods, /* tp_methods */
+ 0, /* tp_members */
+};
+
+//-------------------------------------------------------------------------------------------------------------------------------
+static PyObject *
+M_NLA_NewAction (PyObject * self, PyObject * args)
+{
+ char *name_str = "DefaultAction";
+ BPy_Action *py_action = NULL; /* for Action Data object wrapper in Python */
+ bAction *bl_action = NULL; /* for actual Action Data we create in Blender */
+
+ if (!PyArg_ParseTuple (args, "|s", &name_str)){
+ EXPP_ReturnPyObjError (PyExc_AttributeError,
+ "expected string or nothing");
+ return NULL;
+ }
+
+ //Create new action globally
+ bl_action = alloc_libblock(&G.main->action, ID_AC, name_str);
+ bl_action->id.flag |= LIB_FAKEUSER;
+ bl_action->id.us++;
+
+ // now create the wrapper obj in Python
+ if (bl_action)
+ py_action = (BPy_Action *) PyObject_NEW (BPy_Action, &Action_Type);
+ else{
+ EXPP_ReturnPyObjError (PyExc_RuntimeError,
+ "couldn't create Action Data in Blender");
+ return NULL;
+ }
+
+ if (py_action == NULL){
+ EXPP_ReturnPyObjError (PyExc_MemoryError,
+ "couldn't create Action Data object");
+ return NULL;
+ }
+
+ py_action->action = bl_action; // link Python action wrapper with Blender Action
+
+ Py_INCREF(py_action);
+ return (PyObject *) py_action;
+}
+
+static PyObject *
+M_NLA_CopyAction(PyObject* self, PyObject * args)
+{
+ BPy_Action *py_action = NULL;
+ bAction *copyAction = NULL;
+
+ if (!PyArg_ParseTuple (args, "O!", &Action_Type, &py_action)){
+ EXPP_ReturnPyObjError (PyExc_AttributeError,
+ "expected python action type");
+ return NULL;
+ }
+ copyAction = copy_action(py_action->action);
+ return Action_CreatePyObject (copyAction);
+}
+
+static PyObject *
+M_NLA_GetActions(PyObject* self)
+{
+ PyObject *dict=PyDict_New ();
+ bAction *action = NULL;
+
+ for(action = G.main->action.first; action; action = action->id.next){
+ PyObject * py_action = Action_CreatePyObject (action);
+ if (py_action) {
+ // Insert dict entry using the bone name as key
+ if (PyDict_SetItemString (dict, action->id.name + 2, py_action) !=0) {
+ Py_DECREF (py_action);
+ Py_DECREF ( dict );
+
+ return EXPP_ReturnPyObjError (PyExc_RuntimeError,
+ "NLA_GetActions: couldn't set dict item");
+ }
+ Py_DECREF (py_action);
+ } else {
+ Py_DECREF ( dict );
+ return (PythonReturnErrorObject (PyExc_RuntimeError,
+ "NLA_GetActions: could not create Action object"));
+ }
+ }
+ return dict;
+}
+
+/*****************************************************************************/
+/* Function: NLA_Init */
+/*****************************************************************************/
+PyObject *
+NLA_Init (void)
+{
+ PyObject *submodule;
+
+ Action_Type.ob_type = &PyType_Type;
+
+ submodule = Py_InitModule3 ("Blender.Armature.NLA",
+ M_NLA_methods, M_NLA_doc);
+
+ return (submodule);
+}
+
+//-------------------------------------------------------------------------------------------------------------------------------
+static PyObject *
+Action_getName (BPy_Action * self)
+{
+ PyObject *attr = NULL;
+
+ if (!self->action)
+ (EXPP_ReturnPyObjError (PyExc_RuntimeError,
+ "couldn't get attribute from a NULL action"));
+
+ attr = PyString_FromString (self->action->id.name+2);
+
+ if (attr)
+ return attr;
+
+ return (EXPP_ReturnPyObjError (PyExc_RuntimeError,
+ "couldn't get Action.name attribute"));
+}
+//-------------------------------------------------------------------------------------------------------------------------------
+static PyObject *
+Action_setName (BPy_Action * self, PyObject * args)
+{
+ char *name;
+
+ if (!self->action)
+ (EXPP_ReturnPyObjError (PyExc_RuntimeError,
+ "couldn't get attribute from a NULL action"));
+
+ if (!PyArg_ParseTuple (args, "s", &name))
+ return (EXPP_ReturnPyObjError (PyExc_AttributeError,
+ "expected string argument"));
+
+ //change name
+ strcpy(self->action->id.name+2, name);
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Action_setActive(BPy_Action * self, PyObject * args)
+{
+ BPy_Object *object;
+
+ if (!self->action)
+ (EXPP_ReturnPyObjError (PyExc_RuntimeError,
+ "couldn't get attribute from a NULL action"));
+
+ if (!PyArg_ParseTuple (args, "O!", &Object_Type, &object))
+ return (EXPP_ReturnPyObjError (PyExc_AttributeError,
+ "expected python object argument"));
+
+ if(object->object->type != OB_ARMATURE) {
+ return (EXPP_ReturnPyObjError (PyExc_AttributeError,
+ "object not of type armature"));
+ }
+
+ //set the active action to object
+ object->object->action = self->action;
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Action_getChannelIpo(BPy_Action * self, PyObject * args)
+{
+ char *chanName;
+ bActionChannel *chan;
+
+ if(!PyArg_ParseTuple(args, "s", &chanName)){
+ EXPP_ReturnPyObjError(PyExc_AttributeError, "string expected");
+ return NULL;
+ }
+
+ chan = get_named_actionchannel(self->action,chanName);
+ if(chan == NULL){
+ EXPP_ReturnPyObjError(PyExc_AttributeError, "no channel with that name...");
+ return NULL;
+ }
+
+ //return IPO
+ return Ipo_CreatePyObject (chan->ipo);
+}
+
+static PyObject *
+Action_removeChannel(BPy_Action * self, PyObject * args)
+{
+ char *chanName;
+ bActionChannel *chan;
+
+ if(!PyArg_ParseTuple(args, "s", &chanName)){
+ EXPP_ReturnPyObjError(PyExc_AttributeError, "string expected");
+ return NULL;
+ }
+
+ chan = get_named_actionchannel(self->action,chanName);
+ if(chan == NULL){
+ EXPP_ReturnPyObjError(PyExc_AttributeError, "no channel with that name...");
+ return NULL;
+ }
+
+ //release ipo
+ if(chan->ipo)
+ chan->ipo->id.us--;
+
+ //remove channel
+ BLI_freelinkN (&self->action->chanbase, chan);
+
+ Py_INCREF (Py_None);
+ return (Py_None);
+}
+
+static PyObject *Action_getAllChannelIpos (BPy_Action *self)
+{
+ PyObject *dict=PyDict_New ();
+ bActionChannel *chan = NULL;
+
+ for(chan = self->action->chanbase.first; chan; chan = chan->next){
+ PyObject * ipo_attr = Ipo_CreatePyObject (chan->ipo);
+ if (ipo_attr) {
+ // Insert dict entry using the bone name as key
+ if (PyDict_SetItemString (dict, chan->name, ipo_attr) !=0) {
+ Py_DECREF ( ipo_attr );
+ Py_DECREF ( dict );
+
+ return EXPP_ReturnPyObjError (PyExc_RuntimeError,
+ "Action_getAllChannelIpos: couldn't set dict item");
+ }
+ Py_DECREF (ipo_attr);
+ } else {
+ Py_DECREF ( dict );
+ return (PythonReturnErrorObject (PyExc_RuntimeError,
+ "Action_getAllChannelIpos: could not create Ipo object"));
+ }
+ }
+ return dict;
+}
+
+//-------------------------------------------------------------------------------------------------------------------------------
+static void
+Action_dealloc (BPy_Action * self)
+{
+ PyObject_DEL (self);
+}
+//-------------------------------------------------------------------------------------------------------------------------------
+static PyObject *
+Action_getAttr (BPy_Action * self, char *name)
+{
+ PyObject *attr = Py_None;
+
+ if (strcmp (name, "name") == 0)
+ attr = Action_getName (self);
+ else if (strcmp (name, "__members__") == 0) {
+ attr = Py_BuildValue ("[s]",
+ "name");
+ }
+
+ if (!attr)
+ return (EXPP_ReturnPyObjError (PyExc_MemoryError,
+ "couldn't create PyObject"));
+
+ if (attr != Py_None)
+ return attr; /* member attribute found, return it */
+
+ /* not an attribute, search the methods table */
+ return Py_FindMethod (BPy_Action_methods, (PyObject *) self, name);
+}
+
+//-------------------------------------------------------------------------------------------------------------------------------
+static int
+Action_setAttr (BPy_Action * self, char *name, PyObject * value)
+{
+ PyObject *valtuple;
+ PyObject *error = NULL;
+
+ valtuple = Py_BuildValue ("(O)", value); /* the set* functions expect a tuple */
+
+ if (!valtuple)
+ return EXPP_ReturnIntError (PyExc_MemoryError,
+ "ActionSetAttr: couldn't create tuple");
+
+ if (strcmp (name, "name") == 0)
+ error = Action_setName (self, valtuple);
+ else
+ { /* Error */
+ Py_DECREF (valtuple);
+
+ /* ... member with the given name was found */
+ return (EXPP_ReturnIntError (PyExc_KeyError, "attribute not found"));
+ }
+
+ Py_DECREF (valtuple);
+
+ if (error != Py_None)
+ return -1;
+
+ Py_DECREF (Py_None); /* was incref'ed by the called Action_set* function */
+ return 0; /* normal exit */
+}
+//-------------------------------------------------------------------------------------------------------------------------------
+static PyObject *
+Action_repr (BPy_Action * self)
+{
+ if (self->action)
+ return PyString_FromFormat ("[Action \"%s\"]", self->action->id.name + 2);
+ else
+ return PyString_FromString ("NULL");
+}
+//-------------------------------------------------------------------------------------------------------------------------------
+PyObject *
+Action_CreatePyObject (struct bAction * act)
+{
+ BPy_Action *blen_action;
+
+ blen_action = (BPy_Action *) PyObject_NEW (BPy_Action, &Action_Type);
+
+ if (blen_action == NULL)
+ {
+ return (NULL);
+ }
+ blen_action->action = act;
+ return ((PyObject *) blen_action);
+}
+//-------------------------------------------------------------------------------------------------------------------------------
+int
+Action_CheckPyObject (PyObject * py_obj)
+{
+ return (py_obj->ob_type == &Action_Type);
+}
+//-------------------------------------------------------------------------------------------------------------------------------
+struct bAction *
+Action_FromPyObject (PyObject * py_obj)
+{
+ BPy_Action *blen_obj;
+
+ blen_obj = (BPy_Action *) py_obj;
+ return (blen_obj->action);
+}