This isnt needed because the limit is alredy being set by rename_id() some other minor changed- use None returning maro
		
			
				
	
	
		
			1592 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1592 lines
		
	
	
		
			48 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" /*This must come first*/
 | |
| 
 | |
| #include "DNA_curve_types.h"
 | |
| #include "DNA_scene_types.h"
 | |
| #include "BKE_action.h"
 | |
| #include "BKE_nla.h"
 | |
| #include "BKE_global.h"
 | |
| #include "BKE_main.h"
 | |
| #include "BKE_library.h"
 | |
| #include "BLI_blenlib.h"
 | |
| #include "Object.h"
 | |
| #include "Ipo.h"
 | |
| #include "gen_utils.h"
 | |
| #include "blendef.h"
 | |
| #include "MEM_guardedalloc.h"
 | |
| 
 | |
| #define ACTSTRIP_STRIDEAXIS_X         0
 | |
| #define ACTSTRIP_STRIDEAXIS_Y         1
 | |
| #define ACTSTRIP_STRIDEAXIS_Z         2
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* 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_getFrameNumbers(BPy_Action *self);
 | |
| static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * args );
 | |
| static PyObject *Action_verifyChannel( 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"},
 | |
| 	{"getFrameNumbers", (PyCFunction) Action_getFrameNumbers, METH_NOARGS,
 | |
| 	"() - get the frame numbers at which keys have been inserted"},
 | |
| 	{"getChannelIpo", ( PyCFunction ) Action_getChannelIpo, METH_VARARGS,
 | |
| 	 "(str) -get the Ipo from a named action channel in this action"},
 | |
| 	{"verifyChannel", ( PyCFunction ) Action_verifyChannel, METH_VARARGS,
 | |
| 	 "(str) -verify the 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 int Action_compare( BPy_Action * a, BPy_Action * b );
 | |
| 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 */
 | |
| 	( cmpfunc ) Action_compare,		/* 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_unused, 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; /* no need to assign a user because alloc_libblock alredy assigns one */
 | |
| 	
 | |
| 
 | |
| 	/* 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_unused, 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_unused )
 | |
| {
 | |
| 	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;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*----------------------------------------------------------------------*/
 | |
| 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*/
 | |
| 	rename_id( &self->action->id, name);
 | |
| 
 | |
| 	Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| static PyObject *Action_getFrameNumbers(BPy_Action *self)
 | |
| {
 | |
| 	bActionChannel *achan = NULL;
 | |
| 	IpoCurve *icu = NULL;
 | |
| 	BezTriple *bezt = NULL;
 | |
| 	int verts;
 | |
| 	PyObject *py_list = NULL;
 | |
| 	
 | |
| 	py_list = PyList_New(0);
 | |
| 	for(achan = self->action->chanbase.first; achan; achan = achan->next){
 | |
| 		for (icu = achan->ipo->curve.first; icu; icu = icu->next){
 | |
| 			bezt= icu->bezt;
 | |
| 			if(bezt) {
 | |
| 				verts = icu->totvert;
 | |
| 				while(verts--) {
 | |
| 					PyObject *value;
 | |
| 					value = PyInt_FromLong((int)bezt->vec[1][0]);
 | |
| 					if ( PySequence_Contains(py_list, value) == 0){
 | |
| 						PyList_Append(py_list, value);
 | |
| 					}
 | |
| 					Py_DECREF(value);
 | |
| 					bezt++;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	PyList_Sort(py_list);
 | |
| 	return EXPP_incr_ret(py_list);
 | |
| }
 | |
| 
 | |
| static PyObject *Action_setActive( BPy_Action * self, PyObject * args )
 | |
| {
 | |
| 	BPy_Object *object;
 | |
| 
 | |
| 	if( !self->action )
 | |
| 		return 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" );
 | |
| 
 | |
| 	/* if object is already attached to an action, decrement user count */
 | |
| 	if( object->object->action )
 | |
| 		--object->object->action->id.us;
 | |
| 
 | |
| 	/* set the active action to object */
 | |
| 	object->object->action = self->action;
 | |
| 	++object->object->action->id.us;
 | |
| 
 | |
| 	Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * args )
 | |
| {
 | |
| 	char *chanName;
 | |
| 	bActionChannel *chan;
 | |
| 
 | |
| 	if( !PyArg_ParseTuple( args, "s", &chanName ) )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_AttributeError,
 | |
| 				       "string expected" );
 | |
| 
 | |
| 	chan = get_action_channel( self->action, chanName );
 | |
| 	if( !chan )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_ValueError,
 | |
| 				       "no channel with that name" );
 | |
| 	
 | |
| 	if( !chan->ipo ) {
 | |
| 		Py_RETURN_NONE;
 | |
| 	}
 | |
| 
 | |
| 	return Ipo_CreatePyObject( chan->ipo );
 | |
| }
 | |
| 
 | |
| /*----------------------------------------------------------------------*/
 | |
| static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * args )
 | |
| {
 | |
| 	char *chanName;
 | |
| 	bActionChannel *chan;
 | |
| 
 | |
| 	if( !self->action )
 | |
| 		( EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 					 "couldn't create channel for a NULL action" ) );
 | |
| 
 | |
| 	if( !PyArg_ParseTuple( args, "s", &chanName ) )
 | |
| 		return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
 | |
| 						"expected string argument" ) );
 | |
| 
 | |
| 	chan = verify_action_channel(self->action, chanName);
 | |
| 
 | |
| 	Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| 
 | |
| 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_action_channel( 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_RETURN_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;
 | |
| 	   	if( chan->ipo )
 | |
| 			ipo_attr = Ipo_CreatePyObject( chan->ipo );
 | |
| 		else {
 | |
| 			ipo_attr = Py_None;
 | |
| 			Py_INCREF( ipo_attr );
 | |
| 		}
 | |
| 		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 int Action_compare( BPy_Action * a, BPy_Action * b )
 | |
| {
 | |
| 	return ( a->action == b->action ) ? 0 : -1;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*----------------------------------------------------------------------*/
 | |
| 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;
 | |
| 
 | |
| 	if(!act)
 | |
| 		return EXPP_incr_ret(Py_None);
 | |
| 
 | |
| 	blen_action =
 | |
| 		( BPy_Action * ) PyObject_NEW( BPy_Action, &Action_Type );
 | |
| 
 | |
| 	if( !blen_action) {
 | |
| 		return ( EXPP_ReturnPyObjError
 | |
| 			 ( PyExc_RuntimeError, "failure to create object!" ) );
 | |
| 	}
 | |
| 	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 );
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* ActionStrip wrapper                                                       */
 | |
| /*****************************************************************************/
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Python BPy_ActionStrip attributes:                                        */
 | |
| /*****************************************************************************/
 | |
| 
 | |
| /*
 | |
|  * return the action for the action strip
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getAction( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return Action_CreatePyObject( self->strip->act );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the start frame of the action strip
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getStripStart( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyFloat_FromDouble( self->strip->start );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the start frame of the action strip
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setStripStart( BPy_ActionStrip * self, PyObject * value )
 | |
| {
 | |
| 	int retval;
 | |
| 
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	retval = EXPP_setFloatClamped( value, &self->strip->start,
 | |
| 			-1000.0, self->strip->end-1 );
 | |
| 	if( !retval ) {
 | |
| 		float max = self->strip->end - self->strip->start;
 | |
| 		if( self->strip->blendin > max )
 | |
| 			self->strip->blendin = max;
 | |
| 		if( self->strip->blendout > max )
 | |
| 			self->strip->blendout = max;
 | |
| 	}
 | |
| 	return retval;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the ending frame of the action strip
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getStripEnd( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyFloat_FromDouble( self->strip->end );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the ending frame of the action strip
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setStripEnd( BPy_ActionStrip * self, PyObject * value )
 | |
| {
 | |
| 	int retval;
 | |
| 
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	retval = EXPP_setFloatClamped( value, &self->strip->end,
 | |
| 			self->strip->start+1, MAXFRAMEF );
 | |
| 	if( !retval ) {
 | |
| 		float max = self->strip->end - self->strip->start;
 | |
| 		if( self->strip->blendin > max )
 | |
| 			self->strip->blendin = max;
 | |
| 		if( self->strip->blendout > max )
 | |
| 			self->strip->blendout = max;
 | |
| 	}
 | |
| 	return retval;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the start frame of the action
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getActionStart( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyFloat_FromDouble( self->strip->actstart );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the start frame of the action
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setActionStart( BPy_ActionStrip * self, PyObject * value )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	return EXPP_setFloatClamped( value, &self->strip->actstart,
 | |
| 			-1000.0, self->strip->actend-1 );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the ending frame of the action
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getActionEnd( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyFloat_FromDouble( self->strip->actend );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the ending frame of the action
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setActionEnd( BPy_ActionStrip * self, PyObject * value )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	return EXPP_setFloatClamped( value, &self->strip->actend,
 | |
| 			self->strip->actstart+1, MAXFRAMEF );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the repeat value of the action strip
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getRepeat( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyFloat_FromDouble( self->strip->repeat );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the repeat value of the action strip
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setRepeat( BPy_ActionStrip * self, PyObject * value )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	return EXPP_setFloatClamped( value, &self->strip->repeat,
 | |
| 			0.001, 1000.0f );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the blend in of the action strip
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getBlendIn( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyFloat_FromDouble( self->strip->blendin );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the blend in value of the action strip
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setBlendIn( BPy_ActionStrip * self, PyObject * value )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	return EXPP_setFloatClamped( value, &self->strip->blendin,
 | |
| 			0.0, self->strip->end - self->strip->start );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the blend out of the action strip
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getBlendOut( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyFloat_FromDouble( self->strip->blendout );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the blend out value of the action strip
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setBlendOut( BPy_ActionStrip * self, PyObject * value )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	return EXPP_setFloatClamped( value, &self->strip->blendout,
 | |
| 			0.0, self->strip->end - self->strip->start );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the blend mode of the action strip
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getBlendMode( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyInt_FromLong( (long)self->strip->mode ) ;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the blend mode value of the action strip
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setBlendMode( BPy_ActionStrip * self, PyObject * value )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	return EXPP_setIValueRange( value, &self->strip->mode,
 | |
| 				0, ACTSTRIPMODE_ADD, 'h' );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the flag settings of the action strip
 | |
|  */
 | |
| 
 | |
| #define ACTIONSTRIP_MASK (ACTSTRIP_SELECT | ACTSTRIP_USESTRIDE \
 | |
| 		| ACTSTRIP_HOLDLASTFRAME | ACTSTRIP_ACTIVE | ACTSTRIP_LOCK_ACTION)
 | |
| 
 | |
| static PyObject *ActionStrip_getFlag( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyInt_FromLong( (long)( self->strip->flag & ACTIONSTRIP_MASK ) ) ;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the flag settings out value of the action strip
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setFlag( BPy_ActionStrip * self, PyObject * arg )
 | |
| {
 | |
| 	PyObject *num = PyNumber_Int( arg );
 | |
| 	int value;
 | |
| 
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	if( !num )
 | |
| 		return EXPP_ReturnIntError( PyExc_TypeError,
 | |
| 				"expected int argument" );
 | |
| 	value = PyInt_AS_LONG( num );
 | |
| 	Py_DECREF( num );
 | |
| 
 | |
| 	if( ( value & ACTIONSTRIP_MASK ) != value ) {
 | |
| 		char errstr[128];
 | |
| 		sprintf ( errstr , "expected int bitmask of 0x%04x", ACTIONSTRIP_MASK );
 | |
| 		return EXPP_ReturnIntError( PyExc_TypeError, errstr );
 | |
| 	}
 | |
| 
 | |
| 	self->strip->flag = (short)value;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the stride axis of the action strip
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getStrideAxis( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyInt_FromLong( (long)self->strip->stride_axis ) ;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the stride axis of the action strip
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setStrideAxis( BPy_ActionStrip * self, PyObject * value )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	return EXPP_setIValueRange( value, &self->strip->stride_axis,
 | |
| 				ACTSTRIP_STRIDEAXIS_X, ACTSTRIP_STRIDEAXIS_Z, 'h' );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the stride length of the action strip
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getStrideLength( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyFloat_FromDouble( (double)self->strip->stridelen ) ;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the stride length of the action strip
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setStrideLength( BPy_ActionStrip * self, PyObject * value )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	return EXPP_setFloatClamped( value, &self->strip->stridelen,
 | |
| 			0.0001, 1000.0 );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * return the stride bone name
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_getStrideBone( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	return PyString_FromString( self->strip->stridechannel );
 | |
| }
 | |
| 
 | |
| static PyObject *ActionStrip_getGroupTarget( BPy_ActionStrip * self )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 				
 | |
| 	if (self->strip->object) {
 | |
| 		return Object_CreatePyObject( self->strip->object );
 | |
| 	} else {
 | |
| 		Py_RETURN_NONE;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * set the stride bone name
 | |
|  */
 | |
| 
 | |
| static int ActionStrip_setStrideBone( BPy_ActionStrip * self, PyObject * attr )
 | |
| {
 | |
| 	char *name = PyString_AsString( attr );
 | |
| 	if( !name )
 | |
| 		return EXPP_ReturnIntError( PyExc_TypeError, "expected string arg" );
 | |
| 
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	BLI_strncpy( self->strip->stridechannel, name, 32 );
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static int ActionStrip_setGroupTarget( BPy_ActionStrip * self, PyObject * args )
 | |
| {
 | |
| 	if( !self->strip )
 | |
| 		return EXPP_ReturnIntError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 
 | |
| 	if( (PyObject *)args == Py_None )
 | |
| 		self->strip->object = NULL;
 | |
| 	else if( BPy_Object_Check( args ) )
 | |
| 		self->strip->object = ((BPy_Object *)args)->object;
 | |
| 	else
 | |
| 		return EXPP_ReturnIntError( PyExc_TypeError,
 | |
| 				"expected an object or None" );
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Python BPy_Constraint attributes get/set structure:                       */
 | |
| /*****************************************************************************/
 | |
| static PyGetSetDef BPy_ActionStrip_getseters[] = {
 | |
| 	{"action",
 | |
| 	(getter)ActionStrip_getAction, (setter)NULL,
 | |
| 	 "Action associated with the strip", NULL},
 | |
| 	{"stripStart",
 | |
| 	(getter)ActionStrip_getStripStart, (setter)ActionStrip_setStripStart,
 | |
| 	 "Starting frame of the strip", NULL},
 | |
| 	{"stripEnd",
 | |
| 	(getter)ActionStrip_getStripEnd, (setter)ActionStrip_setStripEnd,
 | |
| 	 "Ending frame of the strip", NULL},
 | |
| 	{"actionStart",
 | |
| 	(getter)ActionStrip_getActionStart, (setter)ActionStrip_setActionStart,
 | |
| 	 "Starting frame of the action", NULL},
 | |
| 	{"actionEnd",
 | |
| 	(getter)ActionStrip_getActionEnd, (setter)ActionStrip_setActionEnd,
 | |
| 	 "Ending frame of the action", NULL},
 | |
| 	{"repeat",
 | |
| 	(getter)ActionStrip_getRepeat, (setter)ActionStrip_setRepeat,
 | |
| 	 "The number of times to repeat the action range", NULL},
 | |
| 	{"blendIn",
 | |
| 	(getter)ActionStrip_getBlendIn, (setter)ActionStrip_setBlendIn,
 | |
| 	 "Number of frames of motion blending", NULL},
 | |
| 	{"blendOut",
 | |
| 	(getter)ActionStrip_getBlendOut, (setter)ActionStrip_setBlendOut,
 | |
| 	 "Number of frames of ease-out", NULL},
 | |
| 	{"mode",
 | |
| 	(getter)ActionStrip_getBlendMode, (setter)ActionStrip_setBlendMode,
 | |
| 	 "Setting of blending mode", NULL},
 | |
| 	{"flag",
 | |
| 	(getter)ActionStrip_getFlag, (setter)ActionStrip_setFlag,
 | |
| 	 "Setting of blending flags", NULL},
 | |
| 	{"strideAxis",
 | |
| 	(getter)ActionStrip_getStrideAxis, (setter)ActionStrip_setStrideAxis,
 | |
| 	 "Dominant axis for stride bone", NULL},
 | |
| 	{"strideLength",
 | |
| 	(getter)ActionStrip_getStrideLength, (setter)ActionStrip_setStrideLength,
 | |
|   	 "Distance covered by one complete cycle of the action", NULL},
 | |
| 	{"strideBone",
 | |
| 	(getter)ActionStrip_getStrideBone, (setter)ActionStrip_setStrideBone,
 | |
|   	 "Name of Bone used for stride", NULL},
 | |
| 	{"groupTarget",
 | |
| 	(getter)ActionStrip_getGroupTarget, (setter)ActionStrip_setGroupTarget,
 | |
| 	 "Name of target armature within group", NULL},	
 | |
| 	{NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 | |
| };
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Python BPy_ActionStrip methods:                                           */
 | |
| /*****************************************************************************/
 | |
| 
 | |
| /*
 | |
|  * restore the values of ActionStart and ActionEnd to their defaults
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_resetLimits( BPy_ActionStrip *self )
 | |
| {
 | |
| 	bActionStrip *strip = self->strip;
 | |
| 
 | |
| 	if( !strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	calc_action_range( strip->act, &strip->actstart, &strip->actend, 1 );
 | |
| 
 | |
| 	Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * reset the strip size
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_resetStripSize( BPy_ActionStrip *self )
 | |
| {
 | |
| 	float mapping;
 | |
| 	bActionStrip *strip = self->strip;
 | |
| 
 | |
| 	if( !strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	mapping = (strip->actend - strip->actstart) / (strip->end - strip->start);
 | |
| 	strip->end = strip->start + mapping*(strip->end - strip->start);
 | |
| 
 | |
| 	Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * snap to start and end to nearest frames
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrip_snapToFrame( BPy_ActionStrip *self )
 | |
| {
 | |
| 	bActionStrip *strip = self->strip;
 | |
| 
 | |
| 	if( !strip )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 	
 | |
| 	strip->start= floor(strip->start+0.5);
 | |
| 	strip->end= floor(strip->end+0.5);
 | |
| 
 | |
| 	Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Python BPy_ActionStrip methods table:                                    */
 | |
| /*****************************************************************************/
 | |
| static PyMethodDef BPy_ActionStrip_methods[] = {
 | |
| 	/* name, method, flags, doc */
 | |
| 	{"resetActionLimits", ( PyCFunction ) ActionStrip_resetLimits, METH_NOARGS,
 | |
| 	 "Restores the values of ActionStart and ActionEnd to their defaults"},
 | |
| 	{"resetStripSize", ( PyCFunction ) ActionStrip_resetStripSize, METH_NOARGS,
 | |
| 	 "Resets the Action Strip size to its creation values"},
 | |
| 	{"snapToFrame", ( PyCFunction ) ActionStrip_snapToFrame, METH_NOARGS,
 | |
| 	 "Snaps the ends of the action strip to the nearest whole numbered frame"},
 | |
| 	{NULL, NULL, 0, NULL}
 | |
| };
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Python ActionStrip_Type structure definition:                            */
 | |
| /*****************************************************************************/
 | |
| PyTypeObject ActionStrip_Type = {
 | |
| 	PyObject_HEAD_INIT( NULL )  /* required py macro */
 | |
| 	0,                          /* ob_size */
 | |
| 	/*  For printing, in format "<module>.<name>" */
 | |
| 	"Blender.ActionStrip",     /* char *tp_name; */
 | |
| 	sizeof( BPy_ActionStrip ), /* int tp_basicsize; */
 | |
| 	0,                          /* tp_itemsize;  For allocation */
 | |
| 
 | |
| 	/* Methods to implement standard operations */
 | |
| 
 | |
| 	( destructor ) Action_dealloc,/* destructor tp_dealloc; */
 | |
| 	NULL,                       /* printfunc tp_print; */
 | |
| 	NULL,                       /* getattrfunc tp_getattr; */
 | |
| 	NULL,                       /* setattrfunc tp_setattr; */
 | |
| 	NULL,                       /* cmpfunc tp_compare; */
 | |
| 	( reprfunc ) NULL,          /* reprfunc tp_repr; */
 | |
| 
 | |
| 	/* Method suites for standard classes */
 | |
| 
 | |
| 	NULL,                       /* PyNumberMethods *tp_as_number; */
 | |
| 	NULL,                       /* PySequenceMethods *tp_as_sequence; */
 | |
| 	NULL,                       /* PyMappingMethods *tp_as_mapping; */
 | |
| 
 | |
| 	/* More standard operations (here for binary compatibility) */
 | |
| 
 | |
| 	NULL,                       /* hashfunc tp_hash; */
 | |
| 	NULL,                       /* ternaryfunc tp_call; */
 | |
| 	NULL,                       /* reprfunc tp_str; */
 | |
| 	NULL,                       /* getattrofunc tp_getattro; */
 | |
| 	NULL,                       /* setattrofunc tp_setattro; */
 | |
| 
 | |
| 	/* Functions to access object as input/output buffer */
 | |
| 	NULL,                       /* PyBufferProcs *tp_as_buffer; */
 | |
| 
 | |
|   /*** Flags to define presence of optional/expanded features ***/
 | |
| 	Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
 | |
| 
 | |
| 	NULL,                       /*  char *tp_doc;  Documentation string */
 | |
|   /*** Assigned meaning in release 2.0 ***/
 | |
| 	/* call function for all accessible objects */
 | |
| 	NULL,                       /* traverseproc tp_traverse; */
 | |
| 
 | |
| 	/* delete references to contained objects */
 | |
| 	NULL,                       /* inquiry tp_clear; */
 | |
| 
 | |
|   /***  Assigned meaning in release 2.1 ***/
 | |
|   /*** rich comparisons ***/
 | |
| 	NULL,                       /* richcmpfunc tp_richcompare; */
 | |
| 
 | |
|   /***  weak reference enabler ***/
 | |
| 	0,                          /* long tp_weaklistoffset; */
 | |
| 
 | |
|   /*** Added in release 2.2 ***/
 | |
| 	/*   Iterators */
 | |
| 	NULL,                        /* getiterfunc tp_iter; */
 | |
|     NULL,                        /* iternextfunc tp_iternext; */
 | |
| 
 | |
|   /*** Attribute descriptor and subclassing stuff ***/
 | |
| 	BPy_ActionStrip_methods,    /* struct PyMethodDef *tp_methods; */
 | |
| 	NULL,                       /* struct PyMemberDef *tp_members; */
 | |
| 	BPy_ActionStrip_getseters,  /* struct PyGetSetDef *tp_getset; */
 | |
| 	NULL,                       /* struct _typeobject *tp_base; */
 | |
| 	NULL,                       /* PyObject *tp_dict; */
 | |
| 	NULL,                       /* descrgetfunc tp_descr_get; */
 | |
| 	NULL,                       /* descrsetfunc tp_descr_set; */
 | |
| 	0,                          /* long tp_dictoffset; */
 | |
| 	NULL,                       /* initproc tp_init; */
 | |
| 	NULL,                       /* allocfunc tp_alloc; */
 | |
| 	NULL,                       /* newfunc tp_new; */
 | |
| 	/*  Low-level free-memory routine */
 | |
| 	NULL,                       /* freefunc tp_free;  */
 | |
| 	/* For PyObject_IS_GC */
 | |
| 	NULL,                       /* inquiry tp_is_gc;  */
 | |
| 	NULL,                       /* PyObject *tp_bases; */
 | |
| 	/* method resolution order */
 | |
| 	NULL,                       /* PyObject *tp_mro;  */
 | |
| 	NULL,                       /* PyObject *tp_cache; */
 | |
| 	NULL,                       /* PyObject *tp_subclasses; */
 | |
| 	NULL,                       /* PyObject *tp_weaklist; */
 | |
| 	NULL
 | |
| };
 | |
| 
 | |
| static PyObject *M_ActionStrip_FlagsDict( void )
 | |
| {
 | |
| 	PyObject *S = PyConstant_New(  );
 | |
| 	
 | |
| 	if( S ) {
 | |
| 		BPy_constant *d = ( BPy_constant * ) S;
 | |
| 		PyConstant_Insert( d, "SELECT",
 | |
| 				PyInt_FromLong( ACTSTRIP_SELECT ) );
 | |
| 		PyConstant_Insert( d, "STRIDE_PATH",
 | |
| 				PyInt_FromLong( ACTSTRIP_USESTRIDE ) );
 | |
| 		PyConstant_Insert( d, "HOLD",
 | |
| 				PyInt_FromLong( ACTSTRIP_HOLDLASTFRAME ) );
 | |
| 		PyConstant_Insert( d, "ACTIVE",
 | |
| 				PyInt_FromLong( ACTSTRIP_ACTIVE ) );
 | |
| 		PyConstant_Insert( d, "LOCK_ACTION",
 | |
| 				PyInt_FromLong( ACTSTRIP_LOCK_ACTION ) );
 | |
| 	}
 | |
| 	return S;
 | |
| }
 | |
| 
 | |
| static PyObject *M_ActionStrip_AxisDict( void )
 | |
| {
 | |
| 	PyObject *S = PyConstant_New(  );
 | |
| 	
 | |
| 	if( S ) {
 | |
| 		BPy_constant *d = ( BPy_constant * ) S;
 | |
| 		PyConstant_Insert( d, "STRIDEAXIS_X",
 | |
| 				PyInt_FromLong( ACTSTRIP_STRIDEAXIS_X ) );
 | |
| 		PyConstant_Insert( d, "STRIDEAXIS_Y",
 | |
| 				PyInt_FromLong( ACTSTRIP_STRIDEAXIS_Y ) );
 | |
| 		PyConstant_Insert( d, "STRIDEAXIS_Z",
 | |
| 				PyInt_FromLong( ACTSTRIP_STRIDEAXIS_Z ) );
 | |
| 	}
 | |
| 	return S;
 | |
| }
 | |
| 
 | |
| static PyObject *M_ActionStrip_ModeDict( void )
 | |
| {
 | |
| 	PyObject *S = PyConstant_New(  );
 | |
| 	
 | |
| 	if( S ) {
 | |
| 		BPy_constant *d = ( BPy_constant * ) S;
 | |
| 		PyConstant_Insert( d, "MODE_ADD",
 | |
| 				PyInt_FromLong( ACTSTRIPMODE_ADD ) );
 | |
| 	}
 | |
| 	return S;
 | |
| }
 | |
| 
 | |
| PyObject *ActionStrip_CreatePyObject( struct bActionStrip *strip )
 | |
| {
 | |
| 	BPy_ActionStrip *pyobj;
 | |
| 	pyobj = ( BPy_ActionStrip * ) PyObject_NEW( BPy_ActionStrip,
 | |
| 			&ActionStrip_Type );
 | |
| 	if( !pyobj )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_MemoryError,
 | |
| 					      "couldn't create BPy_ActionStrip object" );
 | |
| 	pyobj->strip = strip;
 | |
| 	return ( PyObject * ) pyobj;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* ActionStrip Sequence wrapper                                              */
 | |
| /*****************************************************************************/
 | |
| 
 | |
| /*
 | |
|  * Initialize the iterator
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrips_getIter( BPy_ActionStrips * self )
 | |
| {
 | |
| 	self->iter = (bActionStrip *)self->ob->nlastrips.first;
 | |
| 	return EXPP_incr_ret ( (PyObject *) self );
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Get the next action strip
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrips_nextIter( BPy_ActionStrips * self )
 | |
| {
 | |
| 	bActionStrip *strip = self->iter;
 | |
| 	if( strip ) {
 | |
| 		self->iter = strip->next;
 | |
| 		return ActionStrip_CreatePyObject( strip );
 | |
| 	}
 | |
| 
 | |
| 	return EXPP_ReturnPyObjError( PyExc_StopIteration,
 | |
| 			"iterator at end" );
 | |
| }
 | |
| 
 | |
| /* return the number of action strips */
 | |
| 
 | |
| static int ActionStrips_length( BPy_ActionStrips * self )
 | |
| {
 | |
| 	return BLI_countlist( &self->ob->nlastrips );
 | |
| }
 | |
| 
 | |
| /* return an action strip */
 | |
| 
 | |
| static PyObject *ActionStrips_item( BPy_ActionStrips * self, int i )
 | |
| {
 | |
| 	bActionStrip *strip = NULL;
 | |
| 
 | |
| 	/* if index is negative, start counting from the end of the list */
 | |
| 	if( i < 0 )
 | |
| 		i += ActionStrips_length( self );
 | |
| 
 | |
| 	/* skip through the list until we get the strip or end of list */
 | |
| 
 | |
| 	strip = self->ob->nlastrips.first;
 | |
| 
 | |
| 	while( i && strip ) {
 | |
| 		--i;
 | |
| 		strip = strip->next;
 | |
| 	}
 | |
| 
 | |
| 	if( strip )
 | |
| 		return ActionStrip_CreatePyObject( strip );
 | |
| 	else
 | |
| 		return EXPP_ReturnPyObjError( PyExc_IndexError,
 | |
| 				"array index out of range" );
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Python BPy_ActionStrips sequence table:                                  */
 | |
| /*****************************************************************************/
 | |
| static PySequenceMethods ActionStrips_as_sequence = {
 | |
| 	( inquiry ) ActionStrips_length,	/* sq_length */
 | |
| 	( binaryfunc ) 0,	/* sq_concat */
 | |
| 	( intargfunc ) 0,	/* sq_repeat */
 | |
| 	( intargfunc ) ActionStrips_item,	/* sq_item */
 | |
| 	( intintargfunc ) 0,	/* sq_slice */
 | |
| 	( intobjargproc ) 0,	/* sq_ass_item */
 | |
| 	( intintobjargproc ) 0,	/* sq_ass_slice */
 | |
| 	( objobjproc ) 0,	/* sq_contains */
 | |
| 	( binaryfunc ) 0,		/* sq_inplace_concat */
 | |
| 	( intargfunc ) 0,		/* sq_inplace_repeat */
 | |
| };
 | |
| 
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Python BPy_ActionStrip methods:                                           */
 | |
| /*****************************************************************************/
 | |
| 
 | |
| /*
 | |
|  * helper function to check for a valid action strip argument
 | |
|  */
 | |
| 
 | |
| static bActionStrip *locate_strip( BPy_ActionStrips *self, 
 | |
| 		PyObject *args, BPy_ActionStrip **stripobj )
 | |
| {
 | |
| 	bActionStrip *strip = NULL;
 | |
| 	BPy_ActionStrip *pyobj;
 | |
| 
 | |
| 	/* check that argument is a constraint */
 | |
| 	if( !PyArg_ParseTuple( args, "O!", &ActionStrip_Type, &pyobj ) ) {
 | |
| 		EXPP_ReturnPyObjError( PyExc_TypeError,
 | |
| 				"expected an action strip as an argument" );
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	if( !pyobj->strip ) {
 | |
| 		EXPP_ReturnPyObjError( PyExc_RuntimeError,
 | |
| 				"This strip has been removed!" );
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	/* if caller needs the object, return it */
 | |
| 	if( stripobj )
 | |
| 		*stripobj = pyobj;
 | |
| 
 | |
| 	/* find the action strip in the NLA */
 | |
| 	for( strip = self->ob->nlastrips.first; strip; strip = strip->next )
 | |
| 		if( strip == pyobj->strip )
 | |
| 			return strip;
 | |
| 
 | |
| 	/* return exception if we can't find the strip */
 | |
| 	EXPP_ReturnPyObjError( PyExc_AttributeError,
 | |
| 			"action strip does not belong to this object" );
 | |
| 	return NULL;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * remove an action strip from the NLA
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrips_remove( BPy_ActionStrips *self, PyObject * args )
 | |
| {
 | |
| 	BPy_ActionStrip *pyobj;
 | |
| 	bActionStrip *strip = locate_strip( self, args, &pyobj );
 | |
| 
 | |
| 	/* return exception if we can't find the strip */
 | |
| 	if( !strip )
 | |
| 		return (PyObject *)NULL;
 | |
| 
 | |
| 	/* do the actual removal */
 | |
| 	free_actionstrip(strip);
 | |
| 	BLI_remlink(&self->ob->nlastrips, strip);
 | |
| 	MEM_freeN(strip);
 | |
| 
 | |
| 	pyobj->strip = NULL;
 | |
| 	Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * move an action strip up in the strip list
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrips_moveUp( BPy_ActionStrips *self, PyObject * args )
 | |
| {
 | |
| 	bActionStrip *strip = locate_strip( self, args, NULL );
 | |
| 
 | |
| 	/* return exception if we can't find the strip */
 | |
| 	if( !strip )
 | |
| 		return (PyObject *)NULL;
 | |
| 
 | |
| 	/* if strip is not already the first, move it up */
 | |
| 	if( strip != self->ob->nlastrips.first ) {
 | |
| 		BLI_remlink(&self->ob->nlastrips, strip);
 | |
| 		BLI_insertlink(&self->ob->nlastrips, strip->prev->prev, strip);
 | |
| 	}
 | |
| 
 | |
| 	Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * move an action strip down in the strip list
 | |
|  */
 | |
| 
 | |
| static PyObject *ActionStrips_moveDown( BPy_ActionStrips *self, PyObject * args )
 | |
| {
 | |
| 	bActionStrip *strip = locate_strip( self, args, NULL );
 | |
| 
 | |
| 	/* return exception if we can't find the strip */
 | |
| 	if( !strip )
 | |
| 		return (PyObject *)NULL;
 | |
| 
 | |
| 	/* if strip is not already the last, move it down */
 | |
| 	if( strip != self->ob->nlastrips.last ) {
 | |
| 		BLI_remlink(&self->ob->nlastrips, strip);
 | |
| 		BLI_insertlink(&self->ob->nlastrips, strip->next, strip);
 | |
| 	}
 | |
| 
 | |
| 	Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| static PyObject *ActionStrips_append( BPy_ActionStrips *self, PyObject * args )
 | |
| {
 | |
| 	BPy_Action *pyobj;
 | |
| 	Object *ob;
 | |
| 	bActionStrip *strip;
 | |
| 	bAction *act;
 | |
| 
 | |
| 	/* check that argument is an action */
 | |
| 	if( !PyArg_ParseTuple( args, "O!", &Action_Type, &pyobj ) )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_TypeError,
 | |
| 				"expected an action as an argument" );
 | |
| 
 | |
| 	ob = self->ob;
 | |
| 	act = pyobj->action;
 | |
| 
 | |
| 	/* Initialize the new action block */
 | |
| 	strip = MEM_callocN( sizeof(bActionStrip), "bActionStrip" );
 | |
| 
 | |
|     strip->act = act;
 | |
|     calc_action_range( strip->act, &strip->actstart, &strip->actend, 1 );
 | |
|     strip->start = G.scene->r.cfra;
 | |
|     strip->end = strip->start + ( strip->actend - strip->actstart );
 | |
|         /* simple prevention of zero strips */
 | |
|     if( strip->start > strip->end-2 )
 | |
|         strip->end = strip->start+100;
 | |
| 
 | |
|     strip->flag = ACTSTRIP_LOCK_ACTION;
 | |
|     find_stridechannel(ob, strip);
 | |
| 
 | |
|     strip->repeat = 1.0;
 | |
|     act->id.us++;
 | |
| 
 | |
|     BLI_addtail(&ob->nlastrips, strip);
 | |
| 
 | |
| 	Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Python BPy_ActionStrips methods table:                                    */
 | |
| /*****************************************************************************/
 | |
| static PyMethodDef BPy_ActionStrips_methods[] = {
 | |
| 	/* name, method, flags, doc */
 | |
| 	{"append", ( PyCFunction ) ActionStrips_append, METH_VARARGS,
 | |
| 	 "(action) - append a new actionstrip using existing action"},
 | |
| 	{"remove", ( PyCFunction ) ActionStrips_remove, METH_VARARGS,
 | |
| 	 "(strip) - remove an existing strip from this actionstrips"},
 | |
| 	{"moveUp", ( PyCFunction ) ActionStrips_moveUp, METH_VARARGS,
 | |
| 	 "(strip) - move an existing strip up in the actionstrips"},
 | |
| 	{"moveDown", ( PyCFunction ) ActionStrips_moveDown, METH_VARARGS,
 | |
| 	 "(strip) - move an existing strip down in the actionstrips"},
 | |
| 	{NULL, NULL, 0, NULL}
 | |
| };
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Python ActionStrips_Type structure definition:                            */
 | |
| /*****************************************************************************/
 | |
| PyTypeObject ActionStrips_Type = {
 | |
| 	PyObject_HEAD_INIT( NULL )  /* required py macro */
 | |
| 	0,                          /* ob_size */
 | |
| 	/*  For printing, in format "<module>.<name>" */
 | |
| 	"Blender.ActionStrips",     /* char *tp_name; */
 | |
| 	sizeof( BPy_ActionStrips ), /* int tp_basicsize; */
 | |
| 	0,                          /* tp_itemsize;  For allocation */
 | |
| 
 | |
| 	/* Methods to implement standard operations */
 | |
| 
 | |
| 	( destructor ) Action_dealloc,/* destructor tp_dealloc; */
 | |
| 	NULL,                       /* printfunc tp_print; */
 | |
| 	NULL,                       /* getattrfunc tp_getattr; */
 | |
| 	NULL,                       /* setattrfunc tp_setattr; */
 | |
| 	NULL,                       /* cmpfunc tp_compare; */
 | |
| 	( reprfunc ) NULL,          /* reprfunc tp_repr; */
 | |
| 
 | |
| 	/* Method suites for standard classes */
 | |
| 
 | |
| 	NULL,                       /* PyNumberMethods *tp_as_number; */
 | |
| 	&ActionStrips_as_sequence,  /* PySequenceMethods *tp_as_sequence; */
 | |
| 	NULL,                       /* PyMappingMethods *tp_as_mapping; */
 | |
| 
 | |
| 	/* More standard operations (here for binary compatibility) */
 | |
| 
 | |
| 	NULL,                       /* hashfunc tp_hash; */
 | |
| 	NULL,                       /* ternaryfunc tp_call; */
 | |
| 	NULL,                       /* reprfunc tp_str; */
 | |
| 	NULL,                       /* getattrofunc tp_getattro; */
 | |
| 	NULL,                       /* setattrofunc tp_setattro; */
 | |
| 
 | |
| 	/* Functions to access object as input/output buffer */
 | |
| 	NULL,                       /* PyBufferProcs *tp_as_buffer; */
 | |
| 
 | |
|   /*** Flags to define presence of optional/expanded features ***/
 | |
| 	Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
 | |
| 
 | |
| 	NULL,                       /*  char *tp_doc;  Documentation string */
 | |
|   /*** Assigned meaning in release 2.0 ***/
 | |
| 	/* call function for all accessible objects */
 | |
| 	NULL,                       /* traverseproc tp_traverse; */
 | |
| 
 | |
| 	/* delete references to contained objects */
 | |
| 	NULL,                       /* inquiry tp_clear; */
 | |
| 
 | |
|   /***  Assigned meaning in release 2.1 ***/
 | |
|   /*** rich comparisons ***/
 | |
| 	NULL,                       /* richcmpfunc tp_richcompare; */
 | |
| 
 | |
|   /***  weak reference enabler ***/
 | |
| 	0,                          /* long tp_weaklistoffset; */
 | |
| 
 | |
|   /*** Added in release 2.2 ***/
 | |
| 	/*   Iterators */
 | |
| 	( getiterfunc )ActionStrips_getIter, /* getiterfunc tp_iter; */
 | |
|     ( iternextfunc )ActionStrips_nextIter, /* iternextfunc tp_iternext; */
 | |
| 
 | |
|   /*** Attribute descriptor and subclassing stuff ***/
 | |
| 	BPy_ActionStrips_methods,   /* struct PyMethodDef *tp_methods; */
 | |
| 	NULL,                       /* struct PyMemberDef *tp_members; */
 | |
| 	NULL,                       /* struct PyGetSetDef *tp_getset; */
 | |
| 	NULL,                       /* struct _typeobject *tp_base; */
 | |
| 	NULL,                       /* PyObject *tp_dict; */
 | |
| 	NULL,                       /* descrgetfunc tp_descr_get; */
 | |
| 	NULL,                       /* descrsetfunc tp_descr_set; */
 | |
| 	0,                          /* long tp_dictoffset; */
 | |
| 	NULL,                       /* initproc tp_init; */
 | |
| 	NULL,                       /* allocfunc tp_alloc; */
 | |
| 	NULL,                       /* newfunc tp_new; */
 | |
| 	/*  Low-level free-memory routine */
 | |
| 	NULL,                       /* freefunc tp_free;  */
 | |
| 	/* For PyObject_IS_GC */
 | |
| 	NULL,                       /* inquiry tp_is_gc;  */
 | |
| 	NULL,                       /* PyObject *tp_bases; */
 | |
| 	/* method resolution order */
 | |
| 	NULL,                       /* PyObject *tp_mro;  */
 | |
| 	NULL,                       /* PyObject *tp_cache; */
 | |
| 	NULL,                       /* PyObject *tp_subclasses; */
 | |
| 	NULL,                       /* PyObject *tp_weaklist; */
 | |
| 	NULL
 | |
| };
 | |
| 
 | |
| PyObject *ActionStrips_CreatePyObject( Object *ob )
 | |
| {
 | |
| 	BPy_ActionStrips *pyseq;
 | |
| 	pyseq = ( BPy_ActionStrips * ) PyObject_NEW( BPy_ActionStrips,
 | |
| 			&ActionStrips_Type );
 | |
| 	if( !pyseq )
 | |
| 		return EXPP_ReturnPyObjError( PyExc_MemoryError,
 | |
| 					      "couldn't create BPy_ActionStrips object" );
 | |
| 	pyseq->ob = ob;
 | |
| 	return ( PyObject * ) pyseq;
 | |
| }
 | |
| 
 | |
| /*****************************************************************************/
 | |
| /* Function:    NLA_Init                                                     */
 | |
| /*****************************************************************************/
 | |
| PyObject *NLA_Init( void )
 | |
| {
 | |
| 	PyObject *FlagsDict = M_ActionStrip_FlagsDict( );
 | |
| 	PyObject *AxisDict = M_ActionStrip_AxisDict( );
 | |
| 	PyObject *ModeDict = M_ActionStrip_ModeDict( );
 | |
| 	PyObject *submodule;
 | |
| 
 | |
| 	if( PyType_Ready( &Action_Type ) < 0
 | |
| 			|| PyType_Ready( &ActionStrip_Type ) < 0
 | |
| 			|| PyType_Ready( &ActionStrips_Type ) < 0 )
 | |
| 		return NULL;
 | |
| 
 | |
| 	submodule = Py_InitModule3( "Blender.Armature.NLA",
 | |
| 				    M_NLA_methods, M_NLA_doc );
 | |
| 
 | |
| 	if( FlagsDict )
 | |
| 		PyModule_AddObject( submodule, "Flags", FlagsDict );
 | |
| 	if( AxisDict )
 | |
| 		PyModule_AddObject( submodule, "StrideAxes", AxisDict );
 | |
| 	if( ModeDict )
 | |
| 		PyModule_AddObject( submodule, "Modes", ModeDict );
 | |
| 
 | |
| 	return submodule;
 | |
| }
 |