This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/python/api2_2x/NLA.c
Stephen Swaney a509b8adc9 Another round in the Great BPy Cleanup:
Run everything thru indent to cleanup spaces vs tabs.
Clean up some of the comments by hand.
BGL.c was not touched due to all that macro wackyness.

There are no functional changes to the code.
Pre-indent versions of source are tagged with
tag bpy-cleanup-20040925 , just in case.
2004-09-25 20:30:40 +00:00

470 lines
15 KiB
C

/*
* $Id$
*
* ***** 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 ( EXPP_ReturnPyObjError( 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 ( EXPP_ReturnPyObjError( 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 );
}