| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | /* 
 | 
					
						
							|  |  |  |  * $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. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Joseph Gilbert | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL/BL DUAL LICENSE BLOCK ***** | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Pose.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "mydevice.h"
 | 
					
						
							|  |  |  | #include "BKE_armature.h"
 | 
					
						
							|  |  |  | #include "BKE_main.h"
 | 
					
						
							|  |  |  | #include "BKE_global.h"
 | 
					
						
							|  |  |  | #include "BKE_action.h"
 | 
					
						
							|  |  |  | #include "BKE_utildefines.h"
 | 
					
						
							|  |  |  | #include "BIF_editaction.h"
 | 
					
						
							|  |  |  | #include "BIF_space.h"
 | 
					
						
							| 
									
										
										
										
											2006-05-14 18:24:11 +00:00
										 |  |  | #include "BIF_poseobject.h"
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | #include "BKE_depsgraph.h"
 | 
					
						
							|  |  |  | #include "DNA_object_types.h"
 | 
					
						
							|  |  |  | #include "DNA_ipo_types.h"
 | 
					
						
							|  |  |  | #include "DNA_scene_types.h"
 | 
					
						
							|  |  |  | #include "DNA_space_types.h"	//1 - this order
 | 
					
						
							|  |  |  | #include "BSE_editipo.h"			//2
 | 
					
						
							|  |  |  | #include "BLI_blenlib.h"
 | 
					
						
							|  |  |  | #include "BLI_arithb.h"
 | 
					
						
							|  |  |  | #include "Mathutils.h"
 | 
					
						
							|  |  |  | #include "Object.h"
 | 
					
						
							| 
									
										
										
										
											2006-05-07 14:57:58 +00:00
										 |  |  | #include "Constraint.h"
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | #include "NLA.h"
 | 
					
						
							|  |  |  | #include "gen_utils.h"
 | 
					
						
							| 
									
										
										
										
											2007-03-11 04:05:45 +00:00
										 |  |  | #include "gen_library.h"
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-31 09:26:49 +00:00
										 |  |  | #include "DNA_armature_types.h" /*used for pose bone select*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-05 04:17:55 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | extern void chan_calc_mat(bPoseChannel *chan); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------ERROR CODES---------------------------------
 | 
					
						
							|  |  |  | //This is here just to make me happy and to have more consistant error strings :)
 | 
					
						
							|  |  |  | static const char sPoseError[] = "Pose - Error: "; | 
					
						
							| 
									
										
										
										
											2006-01-28 20:17:48 +00:00
										 |  |  | //static const char sPoseBadArgs[] = "Pose - Bad Arguments: ";
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | static const char sPoseBoneError[] = "PoseBone - Error: "; | 
					
						
							| 
									
										
										
										
											2006-01-28 20:17:48 +00:00
										 |  |  | //static const char sPoseBoneBadArgs[] = "PoseBone - Bad Arguments: ";
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | static const char sPoseBonesDictError[] = "PoseBone - Error: "; | 
					
						
							| 
									
										
										
										
											2006-01-28 20:17:48 +00:00
										 |  |  | //static const char sPoseBonesDictBadArgs[] = "PoseBone - Bad Arguments: ";
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | //################## PoseBonesDict_Type (internal) ########################
 | 
					
						
							|  |  |  | /*This is an internal psuedo-dictionary type that allows for manipulation
 | 
					
						
							|  |  |  | * of posechannels inside of a pose structure. It is a subobject of pose. | 
					
						
							|  |  |  | * i.e. Pose.bones['key']*/ | 
					
						
							|  |  |  | //################################################################
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------METHOD IMPLEMENTATIONS-----------------------------
 | 
					
						
							|  |  |  | //------------------------Pose.bones.items()
 | 
					
						
							|  |  |  | //Returns a list of key:value pairs like dict.items()
 | 
					
						
							| 
									
										
										
										
											2006-04-16 15:28:50 +00:00
										 |  |  | static PyObject* PoseBonesDict_items(BPy_PoseBonesDict *self) | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return PyDict_Items(self->bonesMap);  | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------Pose.bones.keys()
 | 
					
						
							|  |  |  | //Returns a list of keys like dict.keys()
 | 
					
						
							| 
									
										
										
										
											2006-04-16 15:28:50 +00:00
										 |  |  | static PyObject* PoseBonesDict_keys(BPy_PoseBonesDict *self) | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return PyDict_Keys(self->bonesMap); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------Armature.bones.values()
 | 
					
						
							|  |  |  | //Returns a list of values like dict.values()
 | 
					
						
							| 
									
										
										
										
											2006-04-16 15:28:50 +00:00
										 |  |  | static PyObject* PoseBonesDict_values(BPy_PoseBonesDict *self) | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return PyDict_Values(self->bonesMap); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------ATTRIBUTE IMPLEMENTATION---------------------------
 | 
					
						
							|  |  |  | //------------------TYPE_OBECT IMPLEMENTATION-----------------------
 | 
					
						
							|  |  |  | //------------------------tp_doc
 | 
					
						
							|  |  |  | //The __doc__ string for this object
 | 
					
						
							|  |  |  | static char BPy_PoseBonesDict_doc[] = "This is an internal subobject of pose\
 | 
					
						
							|  |  |  | designed to act as a Py_PoseBone dictionary."; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------tp_methods
 | 
					
						
							|  |  |  | //This contains a list of all methods the object contains
 | 
					
						
							|  |  |  | static PyMethodDef BPy_PoseBonesDict_methods[] = { | 
					
						
							|  |  |  | 	{"items", (PyCFunction) PoseBonesDict_items, METH_NOARGS,  | 
					
						
							|  |  |  | 		"() - Returns the key:value pairs from the dictionary"}, | 
					
						
							|  |  |  | 	{"keys", (PyCFunction) PoseBonesDict_keys, METH_NOARGS,  | 
					
						
							|  |  |  | 		"() - Returns the keys the dictionary"}, | 
					
						
							|  |  |  | 	{"values", (PyCFunction) PoseBonesDict_values, METH_NOARGS,  | 
					
						
							|  |  |  | 		"() - Returns the values from the dictionary"}, | 
					
						
							| 
									
										
										
										
											2006-01-16 17:55:03 +00:00
										 |  |  | 	{NULL, NULL, 0, NULL} | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | //-----------------(internal)
 | 
					
						
							|  |  |  | static int PoseBoneMapping_Init(PyObject *dictionary, ListBase *posechannels){ | 
					
						
							|  |  |  | 	bPoseChannel *pchan = NULL; | 
					
						
							|  |  |  | 	PyObject *py_posechannel = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (pchan = posechannels->first; pchan; pchan = pchan->next){ | 
					
						
							|  |  |  | 		py_posechannel = PyPoseBone_FromPosechannel(pchan); | 
					
						
							|  |  |  | 		if (!py_posechannel) | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-10 21:05:30 +00:00
										 |  |  | 		if(PyDict_SetItemString(dictionary, | 
					
						
							|  |  |  | 					pchan->name, py_posechannel) == -1){ | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_DECREF(py_posechannel); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //----------------- BonesDict_InitBones
 | 
					
						
							|  |  |  | static int PoseBonesDict_InitBones(BPy_PoseBonesDict *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyDict_Clear(self->bonesMap); | 
					
						
							|  |  |  | 	if (PoseBoneMapping_Init(self->bonesMap, self->bones) == -1) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------tp_repr
 | 
					
						
							|  |  |  | //This is the string representation of the object
 | 
					
						
							|  |  |  | static PyObject *PoseBonesDict_repr(BPy_PoseBonesDict *self) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-09-05 04:17:55 +00:00
										 |  |  | 	char buffer[128], *str; | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	PyObject *key, *value; | 
					
						
							|  |  |  | 	int pos = 0; | 
					
						
							| 
									
										
										
										
											2007-09-05 04:17:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* probably a bit of overkill but better then crashing */ | 
					
						
							|  |  |  | 	str = MEM_mallocN( 64 + ( PyDict_Size( self->bonesMap ) * 128), "PoseBonesDict_repr" ); | 
					
						
							|  |  |  | 	str[0] = '\0'; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	sprintf(buffer, "[Pose Bone Dict: {"); | 
					
						
							|  |  |  | 	strcat(str,buffer); | 
					
						
							|  |  |  | 	while (PyDict_Next(self->bonesMap, &pos, &key, &value)) { | 
					
						
							|  |  |  | 		sprintf(buffer, "%s : %s, ", PyString_AsString(key),  | 
					
						
							|  |  |  | 			PyString_AsString(value->ob_type->tp_repr(value))); | 
					
						
							|  |  |  | 		strcat(str,buffer); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	sprintf(buffer, "}]\n"); | 
					
						
							|  |  |  | 	strcat(str,buffer); | 
					
						
							| 
									
										
										
										
											2007-09-05 04:17:55 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	MEM_freeN( str ); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	return PyString_FromString(str); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------tp_dealloc
 | 
					
						
							|  |  |  | //This tells how to 'tear-down' our object when ref count hits 0
 | 
					
						
							|  |  |  | static void PoseBonesDict_dealloc(BPy_PoseBonesDict * self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Py_DECREF(self->bonesMap); | 
					
						
							|  |  |  | 	PoseBonesDict_Type.tp_free(self); | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------mp_length
 | 
					
						
							|  |  |  | //This gets the size of the dictionary
 | 
					
						
							| 
									
										
										
										
											2006-04-16 15:28:50 +00:00
										 |  |  | static int PoseBonesDict_len(BPy_PoseBonesDict *self) | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return BLI_countlist(self->bones); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //-----------------------mp_subscript
 | 
					
						
							|  |  |  | //This defines getting a bone from the dictionary - x = Bones['key']
 | 
					
						
							| 
									
										
										
										
											2006-04-16 15:28:50 +00:00
										 |  |  | static PyObject *PoseBonesDict_GetItem(BPy_PoseBonesDict *self, PyObject* key) | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | {  | 
					
						
							|  |  |  | 	PyObject *value = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	value = PyDict_GetItem(self->bonesMap, key); | 
					
						
							| 
									
										
										
										
											2006-12-27 05:04:20 +00:00
										 |  |  | 	if(value == NULL) | 
					
						
							|  |  |  |         Py_RETURN_NONE; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	return EXPP_incr_ret(value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------TYPE_OBECT DEFINITION--------------------------
 | 
					
						
							|  |  |  | //Mapping Protocol
 | 
					
						
							|  |  |  | static PyMappingMethods PoseBonesDict_MapMethods = { | 
					
						
							|  |  |  | 	(inquiry) PoseBonesDict_len,					//mp_length
 | 
					
						
							|  |  |  | 	(binaryfunc)PoseBonesDict_GetItem,		//mp_subscript
 | 
					
						
							|  |  |  | 	0,														//mp_ass_subscript
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | //PoseBonesDict TypeObject
 | 
					
						
							|  |  |  | PyTypeObject PoseBonesDict_Type = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(NULL)			//tp_head
 | 
					
						
							|  |  |  | 	0,												//tp_internal
 | 
					
						
							|  |  |  | 	"PoseBonesDict",								//tp_name
 | 
					
						
							|  |  |  | 	sizeof(BPy_PoseBonesDict),					//tp_basicsize
 | 
					
						
							|  |  |  | 	0,												//tp_itemsize
 | 
					
						
							|  |  |  | 	(destructor)PoseBonesDict_dealloc,		//tp_dealloc
 | 
					
						
							|  |  |  | 	0,												//tp_print
 | 
					
						
							|  |  |  | 	0,												//tp_getattr
 | 
					
						
							|  |  |  | 	0,												//tp_setattr
 | 
					
						
							|  |  |  | 	0,												//tp_compare
 | 
					
						
							|  |  |  | 	(reprfunc) PoseBonesDict_repr,				//tp_repr
 | 
					
						
							|  |  |  | 	0,												//tp_as_number
 | 
					
						
							|  |  |  | 	0,												//tp_as_sequence
 | 
					
						
							|  |  |  | 	&PoseBonesDict_MapMethods,				//tp_as_mapping
 | 
					
						
							|  |  |  | 	0,												//tp_hash
 | 
					
						
							|  |  |  | 	0,												//tp_call
 | 
					
						
							|  |  |  | 	0,												//tp_str
 | 
					
						
							|  |  |  | 	0,												//tp_getattro
 | 
					
						
							|  |  |  | 	0,												//tp_setattro
 | 
					
						
							|  |  |  | 	0,												//tp_as_buffer
 | 
					
						
							|  |  |  | 	Py_TPFLAGS_DEFAULT,					//tp_flags
 | 
					
						
							|  |  |  | 	BPy_PoseBonesDict_doc,						//tp_doc
 | 
					
						
							|  |  |  | 	0,												//tp_traverse
 | 
					
						
							|  |  |  | 	0,												//tp_clear
 | 
					
						
							|  |  |  | 	0,												//tp_richcompare
 | 
					
						
							|  |  |  | 	0,												//tp_weaklistoffset
 | 
					
						
							|  |  |  | 	0,												//tp_iter
 | 
					
						
							|  |  |  | 	0,												//tp_iternext
 | 
					
						
							|  |  |  | 	BPy_PoseBonesDict_methods,				//tp_methods
 | 
					
						
							|  |  |  | 	0,												//tp_members
 | 
					
						
							|  |  |  | 	0,												//tp_getset
 | 
					
						
							|  |  |  | 	0,												//tp_base
 | 
					
						
							|  |  |  | 	0,												//tp_dict
 | 
					
						
							|  |  |  | 	0,												//tp_descr_get
 | 
					
						
							|  |  |  | 	0,												//tp_descr_set
 | 
					
						
							|  |  |  | 	0,												//tp_dictoffset
 | 
					
						
							|  |  |  | 	0, 				                                //tp_init
 | 
					
						
							|  |  |  | 	0,												//tp_alloc
 | 
					
						
							|  |  |  | 	0,												//tp_new
 | 
					
						
							|  |  |  | 	0,												//tp_free
 | 
					
						
							|  |  |  | 	0,												//tp_is_gc
 | 
					
						
							|  |  |  | 	0,												//tp_bases
 | 
					
						
							|  |  |  | 	0,												//tp_mro
 | 
					
						
							|  |  |  | 	0,												//tp_cache
 | 
					
						
							|  |  |  | 	0,												//tp_subclasses
 | 
					
						
							|  |  |  | 	0,												//tp_weaklist
 | 
					
						
							|  |  |  | 	0												//tp_del
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | //-----------------------PyPoseBonesDict_FromPyPose
 | 
					
						
							|  |  |  | static PyObject *PyPoseBonesDict_FromPyPose(BPy_Pose *py_pose) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPy_PoseBonesDict *py_posebonesdict = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//create py object
 | 
					
						
							|  |  |  | 	py_posebonesdict = (BPy_PoseBonesDict *)PoseBonesDict_Type.tp_alloc(&PoseBonesDict_Type, 0);  | 
					
						
							|  |  |  | 	if (!py_posebonesdict) | 
					
						
							|  |  |  | 		goto RuntimeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//create internal dictionaries
 | 
					
						
							|  |  |  | 	py_posebonesdict->bonesMap = PyDict_New(); | 
					
						
							|  |  |  | 	if (!py_posebonesdict->bonesMap) | 
					
						
							|  |  |  | 		goto RuntimeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//set listbase pointer
 | 
					
						
							|  |  |  | 	py_posebonesdict->bones = &py_pose->pose->chanbase; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//now that everything is setup - init the mappings
 | 
					
						
							|  |  |  | 	if (!PoseBonesDict_InitBones(py_posebonesdict)) | 
					
						
							|  |  |  | 		goto RuntimeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (PyObject*)py_posebonesdict; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RuntimeError: | 
					
						
							|  |  |  | 	return EXPP_objError(PyExc_RuntimeError, "%s%s",  | 
					
						
							|  |  |  | 		sPoseBonesDictError, "Failed to create class"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //################## Pose_Type ##########################
 | 
					
						
							|  |  |  | /*This type is a wrapper for a pose*/ | 
					
						
							|  |  |  | //####################################################
 | 
					
						
							|  |  |  | //------------------METHOD IMPLEMENTATIONS------------------------------
 | 
					
						
							|  |  |  | static PyObject *Pose_update(BPy_Pose *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Object *daddy = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	self->pose->flag |= POSE_RECALC; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (daddy = G.main->object.first; daddy; daddy = daddy->id.next){ | 
					
						
							|  |  |  | 		if (daddy->pose == self->pose){ | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(daddy) | 
					
						
							|  |  |  | 		where_is_pose(daddy); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-27 05:04:20 +00:00
										 |  |  | 	Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | } | 
					
						
							|  |  |  | //------------------------tp_methods
 | 
					
						
							|  |  |  | //This contains a list of all methods the object contains
 | 
					
						
							|  |  |  | static PyMethodDef BPy_Pose_methods[] = { | 
					
						
							|  |  |  | 	{"update", (PyCFunction) Pose_update, METH_NOARGS,  | 
					
						
							|  |  |  | 		"() - Rebuilds the pose with new values"}, | 
					
						
							| 
									
										
										
										
											2006-01-16 17:55:03 +00:00
										 |  |  | 	{NULL, NULL, 0, NULL} | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | //------------------ATTRIBUTE IMPLEMENTATIONS---------------------------
 | 
					
						
							|  |  |  | //------------------------Pose.bones (getter)
 | 
					
						
							|  |  |  | //Gets the bones attribute
 | 
					
						
							|  |  |  | static PyObject *Pose_getBoneDict(BPy_Pose *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return EXPP_incr_ret((PyObject*)self->Bones); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------Pose.bones (setter)
 | 
					
						
							|  |  |  | //Sets the bones attribute
 | 
					
						
							|  |  |  | static int Pose_setBoneDict(BPy_Pose *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	goto AttributeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AttributeError: | 
					
						
							|  |  |  | 	return EXPP_intError(PyExc_AttributeError, "%s%s",  | 
					
						
							|  |  |  | 		sPoseError, "You are not allowed to change the .bones attribute"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------TYPE_OBECT IMPLEMENTATION---------------------------
 | 
					
						
							|  |  |  | //------------------------tp_getset
 | 
					
						
							|  |  |  | //This contains methods for attributes that require checking
 | 
					
						
							|  |  |  | static PyGetSetDef BPy_Pose_getset[] = { | 
					
						
							|  |  |  | 	{"bones", (getter)Pose_getBoneDict, (setter)Pose_setBoneDict,  | 
					
						
							|  |  |  | 		"The pose's Bone dictionary", NULL}, | 
					
						
							| 
									
										
										
										
											2006-01-16 17:55:03 +00:00
										 |  |  | 	{NULL, NULL, NULL, NULL, NULL} | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | //------------------------tp_dealloc
 | 
					
						
							|  |  |  | //This tells how to 'tear-down' our object when ref count hits 0
 | 
					
						
							|  |  |  | static void Pose_dealloc(BPy_Pose *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Py_DECREF(self->Bones); | 
					
						
							|  |  |  | 	Pose_Type.tp_free(self); | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-10-06 16:48:28 +00:00
										 |  |  | //------------------------tp_cmp
 | 
					
						
							|  |  |  | //This compares 2 pose types
 | 
					
						
							|  |  |  | static int Pose_compare(BPy_Pose *a, BPy_Pose *b ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ( a->pose== b->pose ) ? 0 : -1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | //------------------------tp_repr
 | 
					
						
							|  |  |  | //This is the string representation of the object
 | 
					
						
							|  |  |  | static PyObject *Pose_repr(BPy_Pose *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return PyString_FromFormat( "[Pose \"%s\"]", self->name);  | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------tp_doc
 | 
					
						
							|  |  |  | //The __doc__ string for this object
 | 
					
						
							|  |  |  | static char BPy_Pose_doc[] = "This object wraps a Blender Pose object."; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------TYPE_OBECT DEFINITION--------------------------
 | 
					
						
							|  |  |  | PyTypeObject Pose_Type = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(NULL)   //tp_head
 | 
					
						
							|  |  |  | 	0,										//tp_internal
 | 
					
						
							| 
									
										
										
										
											2007-03-11 04:05:45 +00:00
										 |  |  | 	"Pose",									//tp_name
 | 
					
						
							|  |  |  | 	sizeof(BPy_Pose),						//tp_basicsize
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	0,										//tp_itemsize
 | 
					
						
							| 
									
										
										
										
											2007-03-11 04:05:45 +00:00
										 |  |  | 	(destructor)Pose_dealloc,				//tp_dealloc
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	0,										//tp_print
 | 
					
						
							|  |  |  | 	0,										//tp_getattr
 | 
					
						
							|  |  |  | 	0,										//tp_setattr
 | 
					
						
							| 
									
										
										
										
											2007-03-11 04:05:45 +00:00
										 |  |  | 	(cmpfunc)Pose_compare,					//tp_compare
 | 
					
						
							|  |  |  | 	(reprfunc)Pose_repr,					//tp_repr
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	0,										//tp_as_number
 | 
					
						
							|  |  |  | 	0,										//tp_as_sequence
 | 
					
						
							|  |  |  | 	0,										//tp_as_mapping
 | 
					
						
							|  |  |  | 	0,										//tp_hash
 | 
					
						
							|  |  |  | 	0,										//tp_call
 | 
					
						
							|  |  |  | 	0,										//tp_str
 | 
					
						
							|  |  |  | 	0,										//tp_getattro
 | 
					
						
							|  |  |  | 	0,										//tp_setattro
 | 
					
						
							|  |  |  | 	0,										//tp_as_buffer
 | 
					
						
							| 
									
										
										
										
											2007-03-11 04:05:45 +00:00
										 |  |  | 	Py_TPFLAGS_DEFAULT,     			    //tp_flags
 | 
					
						
							|  |  |  | 	BPy_Pose_doc,							//tp_doc
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	0,										//tp_traverse
 | 
					
						
							|  |  |  | 	0,										//tp_clear
 | 
					
						
							|  |  |  | 	0,										//tp_richcompare
 | 
					
						
							|  |  |  | 	0,										//tp_weaklistoffset
 | 
					
						
							|  |  |  | 	0,										//tp_iter
 | 
					
						
							|  |  |  | 	0,										//tp_iternext
 | 
					
						
							| 
									
										
										
										
											2007-03-11 04:05:45 +00:00
										 |  |  | 	BPy_Pose_methods,						//tp_methods
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	0,										//tp_members
 | 
					
						
							| 
									
										
										
										
											2007-03-11 04:05:45 +00:00
										 |  |  | 	BPy_Pose_getset,						//tp_getset
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	0,										//tp_base
 | 
					
						
							|  |  |  | 	0,										//tp_dict
 | 
					
						
							|  |  |  | 	0,										//tp_descr_get
 | 
					
						
							|  |  |  | 	0,										//tp_descr_set
 | 
					
						
							|  |  |  | 	0,										//tp_dictoffset
 | 
					
						
							|  |  |  | 	0,										//tp_init
 | 
					
						
							|  |  |  | 	0,										//tp_alloc
 | 
					
						
							|  |  |  | 	0,										//tp_new
 | 
					
						
							|  |  |  | 	0,										//tp_free
 | 
					
						
							|  |  |  | 	0,										//tp_is_gc
 | 
					
						
							|  |  |  | 	0,										//tp_bases
 | 
					
						
							|  |  |  | 	0,										//tp_mro
 | 
					
						
							|  |  |  | 	0,										//tp_cache
 | 
					
						
							|  |  |  | 	0,										//tp_subclasses
 | 
					
						
							|  |  |  | 	0,										//tp_weaklist
 | 
					
						
							|  |  |  | 	0										//tp_del
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | //################## PoseBone_Type #####################
 | 
					
						
							|  |  |  | /*This type is a wrapper for a posechannel*/ | 
					
						
							|  |  |  | //####################################################
 | 
					
						
							|  |  |  | //------------------METHOD IMPLEMENTATIONS------------------------------
 | 
					
						
							|  |  |  | //------------------------------PoseBone.insertKey()
 | 
					
						
							|  |  |  | static PyObject *PoseBone_insertKey(BPy_PoseBone *self, PyObject *args) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *parent_object = NULL; | 
					
						
							|  |  |  | 	PyObject *constants = NULL, *item = NULL; | 
					
						
							| 
									
										
										
										
											2007-03-03 01:29:22 +00:00
										 |  |  | 	int frame = 1, oldframe, length, x, numeric_value = 0, oldflag, no_ipo_update = 0; | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	bPoseChannel *pchan = NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-03-03 01:29:22 +00:00
										 |  |  | 	if (!PyArg_ParseTuple(args, "O!i|Oi", &Object_Type, &parent_object, &frame, &constants, &no_ipo_update )) | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 		goto AttributeError; | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* incase we ever have a value other then 1 for fast */ | 
					
						
							|  |  |  | 	if (no_ipo_update) | 
					
						
							|  |  |  | 		no_ipo_update = 1; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	//verify that this pchannel is part of the object->pose
 | 
					
						
							|  |  |  | 	for (pchan = ((BPy_Object*)parent_object)->object->pose->chanbase.first;  | 
					
						
							|  |  |  | 		pchan; pchan = pchan->next){ | 
					
						
							|  |  |  | 		if (pchan == self->posechannel) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!pchan) | 
					
						
							|  |  |  | 		goto AttributeError2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//verify that there is an action bound to this object
 | 
					
						
							|  |  |  | 	if (!((BPy_Object*)parent_object)->object->action){ | 
					
						
							|  |  |  | 		goto AttributeError5; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	oldflag = self->posechannel->flag; | 
					
						
							|  |  |  | 	self->posechannel->flag = 0; | 
					
						
							|  |  |  | 	//set the flags for this posechannel
 | 
					
						
							|  |  |  | 	if (constants){ | 
					
						
							|  |  |  | 		if(PySequence_Check(constants)){ | 
					
						
							|  |  |  | 			length = PySequence_Length(constants); | 
					
						
							|  |  |  | 			for (x = 0; x < length; x++){ | 
					
						
							|  |  |  | 				item = PySequence_GetItem(constants, x); | 
					
						
							|  |  |  | 				if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "ROT")){ | 
					
						
							|  |  |  | 					numeric_value |= POSE_ROT; | 
					
						
							|  |  |  | 				}else if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "LOC")){ | 
					
						
							|  |  |  | 					numeric_value |= POSE_LOC; | 
					
						
							|  |  |  | 				}else if (item == EXPP_GetModuleConstant("Blender.Object.Pose", "SIZE")){ | 
					
						
							|  |  |  | 					numeric_value |= POSE_SIZE; | 
					
						
							|  |  |  | 				}else{ | 
					
						
							|  |  |  | 					Py_DECREF(item); | 
					
						
							|  |  |  | 					self->posechannel->flag = (short)oldflag; | 
					
						
							|  |  |  | 					goto AttributeError4; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				Py_DECREF(item); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			self->posechannel->flag = (short)numeric_value; | 
					
						
							|  |  |  | 		}else if (BPy_Constant_Check(constants)){ | 
					
						
							|  |  |  | 			if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "ROT")){ | 
					
						
							|  |  |  | 				numeric_value |= POSE_ROT; | 
					
						
							|  |  |  | 			}else if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "LOC")){ | 
					
						
							|  |  |  | 				numeric_value |= POSE_LOC; | 
					
						
							|  |  |  | 			}else if (constants == EXPP_GetModuleConstant("Blender.Object.Pose", "SIZE")){ | 
					
						
							|  |  |  | 				numeric_value |= POSE_SIZE; | 
					
						
							|  |  |  | 			}else{ | 
					
						
							|  |  |  | 				self->posechannel->flag = (short)oldflag; | 
					
						
							|  |  |  | 				goto AttributeError4; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			self->posechannel->flag = (short)numeric_value; | 
					
						
							|  |  |  | 		}else{ | 
					
						
							|  |  |  | 			goto AttributeError3; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}else{ //nothing passed so set them all
 | 
					
						
							|  |  |  | 		self->posechannel->flag |= POSE_ROT; | 
					
						
							|  |  |  | 		self->posechannel->flag |= POSE_LOC; | 
					
						
							|  |  |  | 		self->posechannel->flag |= POSE_SIZE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//set the frame we want insertion on
 | 
					
						
							|  |  |  | 	oldframe = G.scene->r.cfra; | 
					
						
							| 
									
										
										
										
											2006-05-07 08:23:51 +00:00
										 |  |  | 	G.scene->r.cfra = frame; | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	//add the action channel if it's not there
 | 
					
						
							|  |  |  | 	verify_action_channel(((BPy_Object*)parent_object)->object->action,  | 
					
						
							|  |  |  | 		self->posechannel->name); | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	//insert the pose keys
 | 
					
						
							|  |  |  | 	if (self->posechannel->flag & POSE_ROT){ | 
					
						
							|  |  |  | 		insertkey(&((BPy_Object*)parent_object)->object->id,  | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 			ID_PO, self->posechannel->name, NULL, AC_QUAT_X, no_ipo_update); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 		insertkey(&((BPy_Object*)parent_object)->object->id,  | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 			ID_PO, self->posechannel->name, NULL, AC_QUAT_Y, no_ipo_update); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 		insertkey(&((BPy_Object*)parent_object)->object->id,  | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 			ID_PO, self->posechannel->name, NULL, AC_QUAT_Z, no_ipo_update); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 		insertkey(&((BPy_Object*)parent_object)->object->id,  | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 			ID_PO, self->posechannel->name, NULL, AC_QUAT_W, no_ipo_update); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (self->posechannel->flag & POSE_LOC){ | 
					
						
							|  |  |  | 		insertkey(&((BPy_Object*)parent_object)->object->id,  | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 			ID_PO, self->posechannel->name, NULL, AC_LOC_X, no_ipo_update); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 		insertkey(&((BPy_Object*)parent_object)->object->id,  | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 			ID_PO, self->posechannel->name, NULL, AC_LOC_Y, no_ipo_update); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 		insertkey(&((BPy_Object*)parent_object)->object->id,  | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 			ID_PO, self->posechannel->name, NULL, AC_LOC_Z, no_ipo_update); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (self->posechannel->flag & POSE_SIZE){ | 
					
						
							|  |  |  | 		insertkey(&((BPy_Object*)parent_object)->object->id,  | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 			ID_PO, self->posechannel->name, NULL, AC_SIZE_X, no_ipo_update); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 		insertkey(&((BPy_Object*)parent_object)->object->id,  | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 			ID_PO, self->posechannel->name, NULL, AC_SIZE_Y, no_ipo_update); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 		insertkey(&((BPy_Object*)parent_object)->object->id,  | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 			ID_PO, self->posechannel->name, NULL, AC_SIZE_Z, no_ipo_update); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//flip the frame back
 | 
					
						
							| 
									
										
										
										
											2006-05-07 08:23:51 +00:00
										 |  |  | 	G.scene->r.cfra = oldframe; | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	//update the IPOs
 | 
					
						
							| 
									
										
										
										
											2007-09-18 06:41:29 +00:00
										 |  |  | 	if (no_ipo_update==0) | 
					
						
							| 
									
										
										
										
											2007-03-03 01:29:22 +00:00
										 |  |  | 		remake_action_ipos (((BPy_Object*)parent_object)->object->action); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-27 05:04:20 +00:00
										 |  |  | 	Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | AttributeError: | 
					
						
							|  |  |  | 	return EXPP_objError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".insertKey: ", "expects an Object, int, (optional) constants"); | 
					
						
							|  |  |  | AttributeError2: | 
					
						
							|  |  |  | 	return EXPP_objError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".insertKey: ", "wrong object detected. \
 | 
					
						
							|  |  |  | 		Use the object this pose came from"); | 
					
						
							|  |  |  | AttributeError3: | 
					
						
							|  |  |  | 	return EXPP_objError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".insertKey: ", "Expects a constant or list of constants"); | 
					
						
							|  |  |  | AttributeError4: | 
					
						
							|  |  |  | 	return EXPP_objError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".insertKey: ", "Please use a constant defined in the Pose module"); | 
					
						
							|  |  |  | AttributeError5: | 
					
						
							|  |  |  | 	return EXPP_objError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".insertKey: ", "You must set up and link an Action to this object first"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------tp_methods
 | 
					
						
							|  |  |  | //This contains a list of all methods the object contains
 | 
					
						
							|  |  |  | static PyMethodDef BPy_PoseBone_methods[] = { | 
					
						
							|  |  |  | 	{"insertKey", (PyCFunction) PoseBone_insertKey, METH_VARARGS,  | 
					
						
							|  |  |  | 		"() - insert a key for this pose into an action"}, | 
					
						
							| 
									
										
										
										
											2006-01-16 17:55:03 +00:00
										 |  |  | 	{NULL, NULL, 0, NULL} | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | //------------------ATTRIBUTE IMPLEMENTATIONS---------------------------
 | 
					
						
							|  |  |  | //------------------------PoseBone.name (getter)
 | 
					
						
							|  |  |  | //Gets the name attribute
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getName(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return PyString_FromString(self->posechannel->name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.name (setter)
 | 
					
						
							|  |  |  | //Sets the name attribute
 | 
					
						
							|  |  |  | static int PoseBone_setName(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char *name = ""; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_Parse(value, "s", &name)) | 
					
						
							|  |  |  | 		goto AttributeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BLI_strncpy(self->posechannel->name, name, 32); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AttributeError: | 
					
						
							|  |  |  | 	return EXPP_intError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".name: ", "expects a string"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.loc (getter)
 | 
					
						
							|  |  |  | //Gets the loc attribute
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getLoc(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return newVectorObject(self->posechannel->loc, 3, Py_WRAP); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.loc (setter)
 | 
					
						
							|  |  |  | //Sets the loc attribute
 | 
					
						
							|  |  |  | static int PoseBone_setLoc(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	VectorObject *vec = NULL; | 
					
						
							|  |  |  | 	int x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_Parse(value, "O!", &vector_Type, &vec)) | 
					
						
							|  |  |  | 		goto AttributeError; | 
					
						
							|  |  |  | 	if (vec->size != 3) | 
					
						
							|  |  |  | 		goto AttributeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (x = 0; x < 3; x++){ | 
					
						
							|  |  |  | 		self->posechannel->loc[x] = vec->vec[x]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AttributeError: | 
					
						
							|  |  |  | 	return EXPP_intError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".loc: ", "expects a 3d vector object"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.size (getter)
 | 
					
						
							|  |  |  | //Gets the size attribute
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getSize(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return newVectorObject(self->posechannel->size, 3, Py_WRAP); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.size (setter)
 | 
					
						
							|  |  |  | //Sets the size attribute
 | 
					
						
							|  |  |  | static int PoseBone_setSize(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	VectorObject *vec = NULL; | 
					
						
							|  |  |  | 	int x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_Parse(value, "O!", &vector_Type, &vec)) | 
					
						
							|  |  |  | 		goto AttributeError; | 
					
						
							|  |  |  | 	if (vec->size != 3) | 
					
						
							|  |  |  | 		goto AttributeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (x = 0; x < 3; x++){ | 
					
						
							|  |  |  | 		self->posechannel->size[x] = vec->vec[x]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AttributeError: | 
					
						
							|  |  |  | 	return EXPP_intError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".size: ", "expects a 3d vector object"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.quat (getter)
 | 
					
						
							|  |  |  | //Gets the quat attribute
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getQuat(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return newQuaternionObject(self->posechannel->quat, Py_WRAP); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.quat (setter)
 | 
					
						
							|  |  |  | //Sets the quat attribute
 | 
					
						
							|  |  |  | static int PoseBone_setQuat(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	QuaternionObject *quat = NULL; | 
					
						
							|  |  |  | 	int x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_Parse(value, "O!", &quaternion_Type, &quat)) | 
					
						
							|  |  |  | 		goto AttributeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (x = 0; x < 4; x++){ | 
					
						
							|  |  |  | 		self->posechannel->quat[x] = quat->quat[x]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AttributeError: | 
					
						
							|  |  |  | 	return EXPP_intError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".quat: ", "expects a quaternion object"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.localMatrix (getter)
 | 
					
						
							|  |  |  | //Gets the chan_mat
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getLocalMatrix(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return newMatrixObject((float*)self->posechannel->chan_mat, 4, 4, Py_WRAP); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.localMatrix (setter)
 | 
					
						
							|  |  |  | //Sets the chan_mat 
 | 
					
						
							|  |  |  | static int PoseBone_setLocalMatrix(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	MatrixObject *matrix = NULL; | 
					
						
							|  |  |  | 	float size[3], quat[4], loc[3]; | 
					
						
							|  |  |  | 	float mat3[3][3], mat4[4][4]; | 
					
						
							|  |  |  | 	int matsize = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!PyArg_Parse(value, "O!", &matrix_Type, &matrix)) | 
					
						
							|  |  |  | 		goto AttributeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (matrix->rowSize == 3 && matrix->colSize == 3){ | 
					
						
							|  |  |  | 		matsize = 3; | 
					
						
							|  |  |  | 		Mat3CpyMat3(mat3, (float(*)[3])*matrix->matrix); | 
					
						
							|  |  |  | 	}else if (matrix->rowSize == 4 && matrix->colSize == 4){ | 
					
						
							|  |  |  | 		matsize = 4; | 
					
						
							|  |  |  | 		Mat4CpyMat4(mat4, (float(*)[4])*matrix->matrix); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (matsize != 3 && matsize != 4){ | 
					
						
							|  |  |  | 		goto AttributeError; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//get size and rotation
 | 
					
						
							|  |  |  | 	if (matsize == 3){ | 
					
						
							|  |  |  | 		Mat3ToSize(mat3, size); | 
					
						
							|  |  |  | 		Mat3Ortho(mat3); | 
					
						
							|  |  |  | 		Mat3ToQuat(mat3, quat); | 
					
						
							|  |  |  | 	}else if (matsize == 4){ | 
					
						
							|  |  |  | 		Mat4ToSize(mat4, size); | 
					
						
							|  |  |  | 		Mat4Ortho(mat4); | 
					
						
							|  |  |  | 		Mat4ToQuat(mat4, quat); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//get loc
 | 
					
						
							| 
									
										
										
										
											2007-09-17 06:11:06 +00:00
										 |  |  | 	if (matsize == 4) { | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 		VECCOPY(loc, matrix->matrix[3]); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2007-09-17 06:11:06 +00:00
										 |  |  | 	else { | 
					
						
							|  |  |  | 		loc[0]= loc[1]= loc[2]= 0.0f; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	//copy new attributes
 | 
					
						
							|  |  |  | 	VECCOPY(self->posechannel->size, size); | 
					
						
							|  |  |  | 	QUATCOPY(self->posechannel->quat, quat); | 
					
						
							|  |  |  | 	if (matsize == 4){ | 
					
						
							|  |  |  | 		VECCOPY(self->posechannel->loc, loc); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//rebuild matrix
 | 
					
						
							|  |  |  | 	chan_calc_mat(self->posechannel); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AttributeError: | 
					
						
							|  |  |  | 	return EXPP_intError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".localMatrix: ", "expects a 3x3 or 4x4 matrix object"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.poseMatrix (getter)
 | 
					
						
							|  |  |  | //Gets the pose_mat
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getPoseMatrix(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return newMatrixObject((float*)self->posechannel->pose_mat, 4, 4, Py_WRAP); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.poseMatrix (setter)
 | 
					
						
							|  |  |  | //Sets the pose_mat
 | 
					
						
							| 
									
										
										
										
											2007-10-20 11:28:58 +00:00
										 |  |  | static int PoseBone_setPoseMatrix(BPy_PoseBone *self, MatrixObject *value, void *closure) | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-10-20 11:28:58 +00:00
										 |  |  | 	float delta_mat[4][4], quat[4]; /* rotation */ | 
					
						
							|  |  |  | 	float size[4]; /* size only */ | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if( !MatrixObject_Check( value ) ) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 									"expected matrix object as argument" ); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if( value->colSize != 4 || value->rowSize != 4 ) | 
					
						
							| 
									
										
										
										
											2007-10-21 16:48:12 +00:00
										 |  |  | 		return EXPP_ReturnIntError( PyExc_AttributeError, | 
					
						
							| 
									
										
										
										
											2007-10-20 11:28:58 +00:00
										 |  |  | 			"matrix must be a 4x4 transformation matrix\n" | 
					
						
							|  |  |  | 			"for example as returned by object.matrixWorld" ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* get bone-space cursor matrix and extract location */ | 
					
						
							|  |  |  | 	armature_mat_pose_to_bone(self->posechannel, (float (*)[4]) *value->matrix, delta_mat); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* Visual Location */ | 
					
						
							|  |  |  | 	VECCOPY(self->posechannel->loc, delta_mat[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Visual Size */ | 
					
						
							|  |  |  | 	Mat4ToSize(delta_mat, size); | 
					
						
							|  |  |  | 	VECCOPY(self->posechannel->size, size); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* Visual Rotation */ | 
					
						
							|  |  |  | 	Mat4ToQuat(delta_mat, quat); | 
					
						
							|  |  |  | 	QUATCOPY(self->posechannel->quat, quat); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2006-05-07 14:57:58 +00:00
										 |  |  | //------------------------PoseBone.constraints (getter)
 | 
					
						
							|  |  |  | //Gets the constraints sequence
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getConstraints(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return PoseConstraintSeq_CreatePyObject( self->posechannel ); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-05-14 18:24:11 +00:00
										 |  |  | //------------------------PoseBone.limitmin (getter)
 | 
					
						
							|  |  |  | //Gets the pose bone limitmin value
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getLimitMin(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float mylimitmin[3]; | 
					
						
							|  |  |  | 	Object *obj = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	obj = Object_FromPoseChannel(self->posechannel); | 
					
						
							|  |  |  | 	if (obj==NULL){ | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError(PyExc_AttributeError, "Bone data is not found"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mylimitmin[0]=0.0f; | 
					
						
							|  |  |  | 	mylimitmin[1]=0.0f; | 
					
						
							|  |  |  | 	mylimitmin[2]=0.0f; | 
					
						
							|  |  |  | 	if(pose_channel_in_IK_chain(obj, self->posechannel)){ | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) { | 
					
						
							|  |  |  | 			if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) { | 
					
						
							|  |  |  | 				mylimitmin[0] = self->posechannel->limitmin[0]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) { | 
					
						
							|  |  |  | 			if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) { | 
					
						
							|  |  |  | 				mylimitmin[1] = self->posechannel->limitmin[1]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) { | 
					
						
							|  |  |  | 			if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) { | 
					
						
							|  |  |  | 				mylimitmin[2] = self->posechannel->limitmin[2]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return newVectorObject(mylimitmin, 3, Py_NEW); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.limitmin (setter)
 | 
					
						
							|  |  |  | //Sets the pose bone limitmin value
 | 
					
						
							|  |  |  | static int PoseBone_setLimitMin(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float newlimitmin[3]; | 
					
						
							|  |  |  | 	int x; | 
					
						
							|  |  |  | 	Object *obj = NULL; | 
					
						
							|  |  |  | 	if(!PySequence_Check(value)){ | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError(PyExc_AttributeError, "Argument is not a sequence"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (PySequence_Size(value) !=3){ | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError(PyExc_AttributeError, "Argument size must be 3"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	newlimitmin[0]=0.0f; | 
					
						
							|  |  |  | 	newlimitmin[1]=0.0f; | 
					
						
							|  |  |  | 	newlimitmin[2]=0.0f; | 
					
						
							|  |  |  | 	for (x = 0; x<3;x++){ | 
					
						
							|  |  |  | 		PyObject *item; | 
					
						
							|  |  |  | 		item = PySequence_GetItem(value, x); //new reference
 | 
					
						
							|  |  |  | 		if (PyFloat_Check(item)){ | 
					
						
							|  |  |  | 			newlimitmin[x] = (float)PyFloat_AsDouble(item); | 
					
						
							|  |  |  | 		}else if (PyInt_Check(item)){ | 
					
						
							|  |  |  | 			newlimitmin[x] = (float)PyInt_AsLong(item); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_DECREF(item); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	obj = Object_FromPoseChannel(self->posechannel); | 
					
						
							|  |  |  | 	if (obj==NULL){ | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError(PyExc_AttributeError, "Bone data is not found"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(!pose_channel_in_IK_chain(obj, self->posechannel)){ | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError(PyExc_AttributeError, "Bone is not part of an IK chain"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) { | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) { | 
					
						
							|  |  |  | 			self->posechannel->limitmin[0] = EXPP_ClampFloat(newlimitmin[0], -180.0f, 0.0f); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) { | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) { | 
					
						
							|  |  |  | 			self->posechannel->limitmin[1] = EXPP_ClampFloat(newlimitmin[1], -180.0f, 0.0f); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) { | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) { | 
					
						
							|  |  |  | 			self->posechannel->limitmin[2] = EXPP_ClampFloat(newlimitmin[2], -180.0f, 0.0f); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	DAG_object_flush_update(G.scene, obj, OB_RECALC_DATA); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.limitmax (getter)
 | 
					
						
							|  |  |  | //Gets the pose bone limitmax value
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getLimitMax(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float mylimitmax[3]; | 
					
						
							|  |  |  | 	Object *obj = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	obj = Object_FromPoseChannel(self->posechannel); | 
					
						
							|  |  |  | 	if (obj==NULL){ | 
					
						
							|  |  |  | 		return EXPP_ReturnPyObjError(PyExc_AttributeError, "Bone data is not found"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	mylimitmax[0]=0.0f; | 
					
						
							|  |  |  | 	mylimitmax[1]=0.0f; | 
					
						
							|  |  |  | 	mylimitmax[2]=0.0f; | 
					
						
							|  |  |  | 	if(pose_channel_in_IK_chain(obj, self->posechannel)){ | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) { | 
					
						
							|  |  |  | 			if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) { | 
					
						
							|  |  |  | 				mylimitmax[0] = self->posechannel->limitmax[0]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) { | 
					
						
							|  |  |  | 			if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) { | 
					
						
							|  |  |  | 				mylimitmax[1] = self->posechannel->limitmax[1]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) { | 
					
						
							|  |  |  | 			if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) { | 
					
						
							|  |  |  | 				mylimitmax[2] = self->posechannel->limitmax[2]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return newVectorObject(mylimitmax, 3, Py_NEW); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.limitmax (setter)
 | 
					
						
							|  |  |  | //Sets the pose bone limitmax value
 | 
					
						
							|  |  |  | static int PoseBone_setLimitMax(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float newlimitmax[3]; | 
					
						
							|  |  |  | 	int x; | 
					
						
							|  |  |  | 	Object *obj = NULL; | 
					
						
							|  |  |  | 	if(!PySequence_Check(value)){ | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError(PyExc_AttributeError, "Argument is not a sequence"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (PySequence_Size(value) !=3){ | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError(PyExc_AttributeError, "Argument size must be 3"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	newlimitmax[0]=0.0f; | 
					
						
							|  |  |  | 	newlimitmax[1]=0.0f; | 
					
						
							|  |  |  | 	newlimitmax[2]=0.0f; | 
					
						
							|  |  |  | 	for (x = 0; x<3;x++){ | 
					
						
							|  |  |  | 		PyObject *item; | 
					
						
							|  |  |  | 		item = PySequence_GetItem(value, x); //new reference
 | 
					
						
							|  |  |  | 		if (PyFloat_Check(item)){ | 
					
						
							|  |  |  | 			newlimitmax[x] = (float)PyFloat_AsDouble(item); | 
					
						
							|  |  |  | 		}else if (PyInt_Check(item)){ | 
					
						
							|  |  |  | 			newlimitmax[x] = (float)PyInt_AsLong(item); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Py_DECREF(item); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	obj = Object_FromPoseChannel(self->posechannel); | 
					
						
							|  |  |  | 	if (obj==NULL){ | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError(PyExc_AttributeError, "Bone data is not found"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if(!pose_channel_in_IK_chain(obj, self->posechannel)){ | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError(PyExc_AttributeError, "Bone is not part of an IK chain"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if ((self->posechannel->ikflag & BONE_IK_NO_XDOF)==0) { | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_XLIMIT)) { | 
					
						
							|  |  |  | 			self->posechannel->limitmax[0] = EXPP_ClampFloat(newlimitmax[0], 0.0f, 180.0f); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if ((self->posechannel->ikflag & BONE_IK_NO_YDOF)==0) { | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_YLIMIT)) { | 
					
						
							|  |  |  | 			self->posechannel->limitmax[1] = EXPP_ClampFloat(newlimitmax[1], 0.0f, 180.0f); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if ((self->posechannel->ikflag & BONE_IK_NO_ZDOF)==0) { | 
					
						
							|  |  |  | 		if ((self->posechannel->ikflag & BONE_IK_ZLIMIT)) { | 
					
						
							|  |  |  | 			self->posechannel->limitmax[2] = EXPP_ClampFloat(newlimitmax[2], 0.0f, 180.0f); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	DAG_object_flush_update(G.scene, obj, OB_RECALC_DATA); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-01-13 15:53:22 +00:00
										 |  |  | //------------------------PoseBone.head (getter)
 | 
					
						
							|  |  |  | //Gets the pose head position
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getHead(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return newVectorObject(self->posechannel->pose_head, 3, Py_NEW); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.head (setter)
 | 
					
						
							|  |  |  | //Sets the pose head position
 | 
					
						
							|  |  |  | static int PoseBone_setHead(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return EXPP_intError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".head: ", "not able to set this property"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.tail (getter)
 | 
					
						
							|  |  |  | //Gets the pose tail position
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getTail(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return newVectorObject(self->posechannel->pose_tail, 3, Py_NEW); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.tail (setter)
 | 
					
						
							|  |  |  | //Sets the pose tail position
 | 
					
						
							|  |  |  | static int PoseBone_setTail(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return EXPP_intError(PyExc_AttributeError, "%s%s%s", | 
					
						
							|  |  |  | 		sPoseBoneError, ".tail: ", "not able to set this property"); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-08-31 09:26:49 +00:00
										 |  |  | //------------------------PoseBone.sel (getter)
 | 
					
						
							|  |  |  | //Gets the pose bones selection
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getSelect(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (self->posechannel->bone->flag & BONE_SELECTED) | 
					
						
							|  |  |  | 		Py_RETURN_TRUE; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		Py_RETURN_FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------PoseBone.sel (setter)
 | 
					
						
							|  |  |  | //Sets the pose bones selection
 | 
					
						
							|  |  |  | static int PoseBone_setSelect(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-07-12 11:51:21 +00:00
										 |  |  | 	int param = PyObject_IsTrue( value ); | 
					
						
							|  |  |  | 	if( param == -1 ) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 				"expected True/False or 0/1" ); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if ( param ) | 
					
						
							| 
									
										
										
										
											2006-08-31 09:26:49 +00:00
										 |  |  | 		self->posechannel->bone->flag |= BONE_SELECTED; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		self->posechannel->bone->flag &= ~(BONE_SELECTED | BONE_ACTIVE); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.parent (getter)
 | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | //Gets the bones parent if any
 | 
					
						
							| 
									
										
										
										
											2006-08-31 09:26:49 +00:00
										 |  |  | static PyObject *PoseBone_getParent(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-12-27 05:04:20 +00:00
										 |  |  | 	if (self->posechannel->parent) | 
					
						
							| 
									
										
										
										
											2006-08-31 09:26:49 +00:00
										 |  |  | 		return PyPoseBone_FromPosechannel(self->posechannel->parent); | 
					
						
							| 
									
										
										
										
											2006-12-27 05:04:20 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  |         Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2006-08-31 09:26:49 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-30 01:04:19 +00:00
										 |  |  | //------------------------PoseBone.displayObject (getter)
 | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | //Gets the pose bones object used for display
 | 
					
						
							| 
									
										
										
										
											2006-12-30 01:04:19 +00:00
										 |  |  | static PyObject *PoseBone_getDisplayObject(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (self->posechannel->custom) | 
					
						
							|  |  |  | 		return Object_CreatePyObject(self->posechannel->custom); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  |         Py_RETURN_NONE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.displayObject (setter)
 | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | //Sets the pose bones object used for display
 | 
					
						
							| 
									
										
										
										
											2006-12-30 01:04:19 +00:00
										 |  |  | static int PoseBone_setDisplayObject(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-03-08 14:37:34 +00:00
										 |  |  | 	return GenericLib_assignData(value, (void **) &self->posechannel->custom, 0, 0, ID_OB, 0); | 
					
						
							| 
									
										
										
										
											2006-12-30 01:04:19 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-02-21 23:14:01 +00:00
										 |  |  | //------------------------PoseBone.hasIK (getter)
 | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | //Returns True/False if the bone has IK's
 | 
					
						
							| 
									
										
										
										
											2007-02-21 23:14:01 +00:00
										 |  |  | static PyObject *PoseBone_hasIK(BPy_PoseBone *self, void *closure) | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	Object *obj = NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	obj = Object_FromPoseChannel(self->posechannel); | 
					
						
							|  |  |  | 	if (obj==NULL) | 
					
						
							|  |  |  | 		Py_RETURN_FALSE; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if( pose_channel_in_IK_chain(obj, self->posechannel) ) | 
					
						
							|  |  |  | 		Py_RETURN_TRUE; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	Py_RETURN_FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.stretch (getter)
 | 
					
						
							|  |  |  | //Gets the pose bones IK Stretch value
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getStretch(BPy_PoseBone *self, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return PyFloat_FromDouble( self->posechannel->ikstretch ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.stretch (setter)
 | 
					
						
							|  |  |  | //Sets the pose bones IK Stretch value
 | 
					
						
							|  |  |  | static int PoseBone_setStretch(BPy_PoseBone *self, PyObject *value, void *closure) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float ikstretch; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if( !PyNumber_Check( value ) ) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 					"expected float argument" ); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2007-03-01 21:30:48 +00:00
										 |  |  | 	ikstretch = (float)PyFloat_AsDouble(value); | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 	if (ikstretch<0) ikstretch = 0.0; | 
					
						
							|  |  |  | 	if (ikstretch>1) ikstretch = 1.0; | 
					
						
							|  |  |  | 	self->posechannel->ikstretch = ikstretch; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.stiffX/Y/Z (getter)
 | 
					
						
							|  |  |  | //Gets the pose bones IK stiffness
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getStiff(BPy_PoseBone *self, void *axis) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return PyFloat_FromDouble( self->posechannel->stiffness[(int)axis] ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.stiffX/Y/Z (setter)
 | 
					
						
							|  |  |  | //Sets the pose bones IK stiffness
 | 
					
						
							|  |  |  | static int PoseBone_setStiff(BPy_PoseBone *self, PyObject *value, void *axis) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float stiff; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if( !PyNumber_Check( value ) ) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 					"expected float argument" ); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2007-03-01 21:30:48 +00:00
										 |  |  | 	stiff = (float)PyFloat_AsDouble(value); | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 	if (stiff<0) stiff = 0; | 
					
						
							| 
									
										
										
										
											2007-03-01 21:30:48 +00:00
										 |  |  | 	if (stiff>0.990) stiff = 0.990f; | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 	self->posechannel->stiffness[(int)axis] = stiff; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.* (getter)
 | 
					
						
							|  |  |  | //Gets the pose bones flag
 | 
					
						
							| 
									
										
										
										
											2007-02-21 23:14:01 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | static PyObject *PoseBone_getFlag(BPy_PoseBone *self, void *flag) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-02-21 23:14:01 +00:00
										 |  |  | 	if (self->posechannel->flag & (int)flag) | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 		Py_RETURN_TRUE; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		Py_RETURN_FALSE; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-02-21 23:14:01 +00:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.* (setter)
 | 
					
						
							|  |  |  | //Gets the pose bones flag
 | 
					
						
							| 
									
										
										
										
											2007-02-21 23:14:01 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | static int PoseBone_setFlag(BPy_PoseBone *self, PyObject *value, void *flag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if ( PyObject_IsTrue(value) ) | 
					
						
							| 
									
										
										
										
											2007-02-21 23:14:01 +00:00
										 |  |  | 		self->posechannel->flag |= (int)flag; | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 	else | 
					
						
							| 
									
										
										
										
											2007-02-21 23:14:01 +00:00
										 |  |  | 		self->posechannel->flag &= ~(int)flag; | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-02-21 23:14:01 +00:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.* (getter)
 | 
					
						
							|  |  |  | //Gets the pose bones ikflag
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getIKFlag(BPy_PoseBone *self, void *flag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (self->posechannel->ikflag & (int)flag) | 
					
						
							|  |  |  | 		Py_RETURN_TRUE; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		Py_RETURN_FALSE; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------------PoseBone.* (setter)
 | 
					
						
							|  |  |  | //Sets the pose bones ikflag
 | 
					
						
							|  |  |  | static int PoseBone_setIKFlag(BPy_PoseBone *self, PyObject *value, void *flag) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-07-12 11:51:21 +00:00
										 |  |  | 	int param = PyObject_IsTrue( value ); | 
					
						
							|  |  |  | 	if( param == -1 ) | 
					
						
							|  |  |  | 		return EXPP_ReturnIntError( PyExc_TypeError, | 
					
						
							|  |  |  | 				"expected True/False or 0/1" ); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if ( param ) | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 		self->posechannel->ikflag |= (int)flag; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		self->posechannel->ikflag &= ~(int)flag; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-26 22:38:15 +00:00
										 |  |  | //------------------------Bone.layerMask (get)
 | 
					
						
							|  |  |  | static PyObject *PoseBone_getLayerMask(BPy_PoseBone *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* do this extra stuff because the short's bits can be negative values */ | 
					
						
							|  |  |  | 	unsigned short laymask = 0; | 
					
						
							|  |  |  | 	laymask |= self->posechannel->bone->layer; | 
					
						
							|  |  |  | 	return PyInt_FromLong((int)laymask); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------Bone.layerMask (set)
 | 
					
						
							|  |  |  | static int PoseBone_setLayerMask(BPy_PoseBone *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->posechannel->bone->layer = 0; | 
					
						
							|  |  |  | 	self->posechannel->bone->layer |= laymask; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | //------------------TYPE_OBECT IMPLEMENTATION---------------------------
 | 
					
						
							|  |  |  | //------------------------tp_getset
 | 
					
						
							|  |  |  | //This contains methods for attributes that require checking
 | 
					
						
							|  |  |  | static PyGetSetDef BPy_PoseBone_getset[] = { | 
					
						
							|  |  |  | 	{"name", (getter)PoseBone_getName, (setter)PoseBone_setName,  | 
					
						
							|  |  |  | 		"The pose bone's name", NULL}, | 
					
						
							|  |  |  | 	{"loc", (getter)PoseBone_getLoc, (setter)PoseBone_setLoc,  | 
					
						
							|  |  |  | 		"The pose bone's change in location as a vector", NULL}, | 
					
						
							|  |  |  | 	{"size", (getter)PoseBone_getSize, (setter)PoseBone_setSize,  | 
					
						
							|  |  |  | 		"The pose bone's change in size as a vector", NULL}, | 
					
						
							|  |  |  | 	{"quat", (getter)PoseBone_getQuat, (setter)PoseBone_setQuat,  | 
					
						
							|  |  |  | 		"The pose bone's change in rotation as a quat", NULL}, | 
					
						
							|  |  |  | 	{"localMatrix", (getter)PoseBone_getLocalMatrix, (setter)PoseBone_setLocalMatrix,  | 
					
						
							|  |  |  | 		"The pose bone's change matrix built from the quat, loc, and size", NULL}, | 
					
						
							|  |  |  | 	{"poseMatrix", (getter)PoseBone_getPoseMatrix, (setter)PoseBone_setPoseMatrix,  | 
					
						
							|  |  |  | 		"The pose bone's matrix", NULL}, | 
					
						
							| 
									
										
										
										
											2006-01-13 15:53:22 +00:00
										 |  |  | 	{"head", (getter)PoseBone_getHead, (setter)PoseBone_setHead,  | 
					
						
							|  |  |  | 		"The pose bone's head positon", NULL}, | 
					
						
							|  |  |  | 	{"tail", (getter)PoseBone_getTail, (setter)PoseBone_setTail,  | 
					
						
							|  |  |  | 		"The pose bone's tail positon", NULL}, | 
					
						
							| 
									
										
										
										
											2006-08-31 09:26:49 +00:00
										 |  |  | 	{"sel", (getter)PoseBone_getSelect, (setter)PoseBone_setSelect,  | 
					
						
							|  |  |  | 		"The pose selection state", NULL}, | 
					
						
							| 
									
										
										
										
											2006-05-14 18:24:11 +00:00
										 |  |  |     {"limitMin", (getter)PoseBone_getLimitMin, (setter)PoseBone_setLimitMin, | 
					
						
							|  |  |  |         "The pose bone dof min", NULL}, | 
					
						
							|  |  |  |     {"limitMax", (getter)PoseBone_getLimitMax, (setter)PoseBone_setLimitMax, | 
					
						
							|  |  |  |         "The pose bone dof max", NULL}, | 
					
						
							| 
									
										
										
										
											2006-05-07 14:57:58 +00:00
										 |  |  | 	{"constraints", (getter)PoseBone_getConstraints, (setter)NULL,  | 
					
						
							|  |  |  | 		"The list of contraints that pertain to this pose bone", NULL}, | 
					
						
							| 
									
										
										
										
											2006-08-31 09:26:49 +00:00
										 |  |  | 	{"parent", (getter)PoseBone_getParent, (setter)NULL,  | 
					
						
							|  |  |  | 		"The bones parent (read only for posebones)", NULL}, | 
					
						
							| 
									
										
										
										
											2006-12-30 01:04:19 +00:00
										 |  |  | 	{"displayObject", (getter)PoseBone_getDisplayObject, (setter)PoseBone_setDisplayObject,  | 
					
						
							|  |  |  | 		"The poseMode object to draw in place of this bone", NULL}, | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2007-02-21 23:14:01 +00:00
										 |  |  | 	{"hasIK", (getter)PoseBone_hasIK, (setter)NULL,  | 
					
						
							| 
									
										
										
										
											2007-02-20 23:23:54 +00:00
										 |  |  | 		"True if the pose bone has IK (readonly)", NULL }, | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	{"stretch", (getter)PoseBone_getStretch, (setter)PoseBone_setStretch,  | 
					
						
							|  |  |  | 		"Stretch the bone to the IK Target", NULL }, | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	{"stiffX", (getter)PoseBone_getStiff, (setter)PoseBone_setStiff,  | 
					
						
							|  |  |  | 		"bones stiffness on the X axis", (void *)0 }, | 
					
						
							|  |  |  | 	{"stiffY", (getter)PoseBone_getStiff, (setter)PoseBone_setStiff,  | 
					
						
							|  |  |  | 		"bones stiffness on the Y axis", (void *)1 }, | 
					
						
							|  |  |  | 	{"stiffZ", (getter)PoseBone_getStiff, (setter)PoseBone_setStiff,  | 
					
						
							|  |  |  | 		"bones stiffness on the Z axis", (void *)2 }, | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	{"limitX", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag,  | 
					
						
							|  |  |  | 		"limit rotation over X axis when part of an IK", (void *)BONE_IK_XLIMIT }, | 
					
						
							|  |  |  | 	{"limitY", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag,  | 
					
						
							|  |  |  | 		"limit rotation over Y axis when part of an IK", (void *)BONE_IK_YLIMIT }, | 
					
						
							|  |  |  | 	{"limitZ", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag,  | 
					
						
							|  |  |  | 		"limit rotation over Z axis when part of an IK", (void *)BONE_IK_ZLIMIT }, | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	{"lockXRot", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag, | 
					
						
							|  |  |  | 		"disable X DoF when part of an IK", (void *)BONE_IK_NO_XDOF }, | 
					
						
							|  |  |  | 	{"lockYRot", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag,  | 
					
						
							|  |  |  | 		"disable Y DoF when part of an IK", (void *)BONE_IK_NO_YDOF }, | 
					
						
							|  |  |  | 	{"lockZRot", (getter)PoseBone_getIKFlag, (setter)PoseBone_setIKFlag, | 
					
						
							|  |  |  | 		"disable Z DoF when part of an IK", (void *)BONE_IK_NO_ZDOF }, | 
					
						
							| 
									
										
										
										
											2007-10-26 22:38:15 +00:00
										 |  |  | 	{"layerMask", (getter)PoseBone_getLayerMask, (setter)PoseBone_setLayerMask,  | 
					
						
							|  |  |  | 		"Layer bitmask", NULL }, | 
					
						
							| 
									
										
										
										
											2006-01-16 17:55:03 +00:00
										 |  |  | 	{NULL, NULL, NULL, NULL, NULL} | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | //------------------------tp_dealloc
 | 
					
						
							|  |  |  | //This tells how to 'tear-down' our object when ref count hits 0
 | 
					
						
							|  |  |  | static void PoseBone_dealloc(BPy_PoseBone *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PoseBone_Type.tp_free(self); | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------tp_repr
 | 
					
						
							|  |  |  | //This is the string representation of the object
 | 
					
						
							|  |  |  | static PyObject *PoseBone_repr(BPy_PoseBone *self) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return PyString_FromFormat( "[PoseBone \"%s\"]", self->posechannel->name);  | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------tp_doc
 | 
					
						
							|  |  |  | //The __doc__ string for this object
 | 
					
						
							|  |  |  | static char BPy_PoseBone_doc[] = "This object wraps a Blender PoseBone object."; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //------------------TYPE_OBECT DEFINITION--------------------------
 | 
					
						
							|  |  |  | PyTypeObject PoseBone_Type = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(NULL)   //tp_head
 | 
					
						
							|  |  |  | 	0,										//tp_internal
 | 
					
						
							|  |  |  | 	"PoseBone",							//tp_name
 | 
					
						
							|  |  |  | 	sizeof(BPy_PoseBone),			//tp_basicsize
 | 
					
						
							|  |  |  | 	0,										//tp_itemsize
 | 
					
						
							|  |  |  | 	(destructor)PoseBone_dealloc,		//tp_dealloc
 | 
					
						
							|  |  |  | 	0,										//tp_print
 | 
					
						
							|  |  |  | 	0,										//tp_getattr
 | 
					
						
							|  |  |  | 	0,										//tp_setattr
 | 
					
						
							|  |  |  | 	0,										//tp_compare
 | 
					
						
							|  |  |  | 	(reprfunc)PoseBone_repr,		//tp_repr
 | 
					
						
							|  |  |  | 	0,										//tp_as_number
 | 
					
						
							|  |  |  | 	0,										//tp_as_sequence
 | 
					
						
							|  |  |  | 	0,										//tp_as_mapping
 | 
					
						
							|  |  |  | 	0,										//tp_hash
 | 
					
						
							|  |  |  | 	0,										//tp_call
 | 
					
						
							|  |  |  | 	0,										//tp_str
 | 
					
						
							|  |  |  | 	0,										//tp_getattro
 | 
					
						
							|  |  |  | 	0,										//tp_setattro
 | 
					
						
							|  |  |  | 	0,										//tp_as_buffer
 | 
					
						
							|  |  |  | 	Py_TPFLAGS_DEFAULT,         //tp_flags
 | 
					
						
							|  |  |  | 	BPy_PoseBone_doc,				//tp_doc
 | 
					
						
							|  |  |  | 	0,										//tp_traverse
 | 
					
						
							|  |  |  | 	0,										//tp_clear
 | 
					
						
							|  |  |  | 	0,										//tp_richcompare
 | 
					
						
							|  |  |  | 	0,										//tp_weaklistoffset
 | 
					
						
							|  |  |  | 	0,										//tp_iter
 | 
					
						
							|  |  |  | 	0,										//tp_iternext
 | 
					
						
							|  |  |  | 	BPy_PoseBone_methods,		//tp_methods
 | 
					
						
							|  |  |  | 	0,										//tp_members
 | 
					
						
							|  |  |  | 	BPy_PoseBone_getset,			//tp_getset
 | 
					
						
							|  |  |  | 	0,										//tp_base
 | 
					
						
							|  |  |  | 	0,										//tp_dict
 | 
					
						
							|  |  |  | 	0,										//tp_descr_get
 | 
					
						
							|  |  |  | 	0,										//tp_descr_set
 | 
					
						
							|  |  |  | 	0,										//tp_dictoffset
 | 
					
						
							|  |  |  | 	0,										//tp_init
 | 
					
						
							|  |  |  | 	0,										//tp_alloc
 | 
					
						
							|  |  |  | 	0,										//tp_new
 | 
					
						
							|  |  |  | 	0,										//tp_free
 | 
					
						
							|  |  |  | 	0,										//tp_is_gc
 | 
					
						
							|  |  |  | 	0,										//tp_bases
 | 
					
						
							|  |  |  | 	0,										//tp_mro
 | 
					
						
							|  |  |  | 	0,										//tp_cache
 | 
					
						
							|  |  |  | 	0,										//tp_subclasses
 | 
					
						
							|  |  |  | 	0,										//tp_weaklist
 | 
					
						
							|  |  |  | 	0										//tp_del
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | //-------------------MODULE METHODS IMPLEMENTATION------------------------
 | 
					
						
							|  |  |  | //-------------------MODULE METHODS DEFINITION-----------------------------
 | 
					
						
							|  |  |  | struct PyMethodDef M_Pose_methods[] = { | 
					
						
							| 
									
										
										
										
											2006-01-16 17:55:03 +00:00
										 |  |  | 	{NULL, NULL, 0, NULL} | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | //-------------------MODULE INITIALIZATION--------------------------------
 | 
					
						
							|  |  |  | PyObject *Pose_Init(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PyObject *module; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//Initializes TypeObject.ob_type
 | 
					
						
							|  |  |  | 	if (PyType_Ready(&Pose_Type) < 0 || PyType_Ready(&PoseBone_Type)  < 0 || | 
					
						
							|  |  |  | 		PyType_Ready(&PoseBonesDict_Type) < 0) { | 
					
						
							| 
									
										
										
										
											2006-12-27 05:04:20 +00:00
										 |  |  | 		Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//Register the module
 | 
					
						
							|  |  |  | 	module = Py_InitModule3("Blender.Object.Pose", M_Pose_methods,  | 
					
						
							|  |  |  | 		"The Blender Pose module");  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//Add TYPEOBJECTS to the module
 | 
					
						
							|  |  |  | 	PyModule_AddObject(module, "Pose",  | 
					
						
							|  |  |  | 		EXPP_incr_ret((PyObject *)&Pose_Type)); //*steals*
 | 
					
						
							|  |  |  | 	PyModule_AddObject(module, "PoseBone",  | 
					
						
							|  |  |  | 		EXPP_incr_ret((PyObject *)&PoseBone_Type)); //*steals*
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//Add CONSTANTS to the module
 | 
					
						
							|  |  |  | 	PyModule_AddObject(module, "ROT",  | 
					
						
							| 
									
										
										
										
											2007-05-21 19:42:11 +00:00
										 |  |  | 		PyConstant_NewInt("ROT", POSE_ROT)); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	PyModule_AddObject(module, "LOC",  | 
					
						
							| 
									
										
										
										
											2007-05-21 19:42:11 +00:00
										 |  |  | 		PyConstant_NewInt("LOC", POSE_LOC)); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	PyModule_AddObject(module, "SIZE",  | 
					
						
							| 
									
										
										
										
											2007-05-21 19:42:11 +00:00
										 |  |  | 		PyConstant_NewInt("SIZE", POSE_SIZE)); | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return module; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
 | 
					
						
							|  |  |  | //------------------------------PyPose_FromPose (internal)
 | 
					
						
							|  |  |  | //Returns a PyPose from a bPose - return PyNone if bPose is NULL
 | 
					
						
							|  |  |  | PyObject *PyPose_FromPose(bPose *pose, char *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPy_Pose *py_pose = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (pose){ | 
					
						
							|  |  |  | 		py_pose = (BPy_Pose*)Pose_Type.tp_alloc(&Pose_Type, 0); | 
					
						
							|  |  |  | 		if (!py_pose) | 
					
						
							|  |  |  | 			goto RuntimeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		py_pose->pose = pose; | 
					
						
							|  |  |  | 		BLI_strncpy(py_pose->name, name, 24); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		//create armature.bones
 | 
					
						
							|  |  |  | 		py_pose->Bones = (BPy_PoseBonesDict*)PyPoseBonesDict_FromPyPose(py_pose); | 
					
						
							|  |  |  | 		if (!py_pose->Bones) | 
					
						
							|  |  |  | 			goto RuntimeError; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return (PyObject*)py_pose; | 
					
						
							|  |  |  | 	}else{ | 
					
						
							| 
									
										
										
										
											2006-12-27 05:04:20 +00:00
										 |  |  | 		Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RuntimeError: | 
					
						
							|  |  |  | 	return EXPP_objError(PyExc_RuntimeError, "%s%s%s",  | 
					
						
							|  |  |  | 		sPoseError, "PyPose_FromPose: ", "Internal Error Ocurred"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | //------------------------------PyPoseBone_FromPosechannel (internal)
 | 
					
						
							|  |  |  | //Returns a PyPoseBone from a bPoseChannel - return PyNone if bPoseChannel is NULL
 | 
					
						
							|  |  |  | PyObject *PyPoseBone_FromPosechannel(bPoseChannel *pchan) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BPy_PoseBone *py_posechannel = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (pchan){ | 
					
						
							|  |  |  | 		py_posechannel = (BPy_PoseBone*)PoseBone_Type.tp_alloc(&PoseBone_Type, 0); | 
					
						
							|  |  |  | 		if (!py_posechannel) | 
					
						
							|  |  |  | 			goto RuntimeError; | 
					
						
							|  |  |  | 		py_posechannel->posechannel = pchan; | 
					
						
							|  |  |  | 		return (PyObject*)py_posechannel; | 
					
						
							|  |  |  | 	}else{ | 
					
						
							| 
									
										
										
										
											2006-12-27 05:04:20 +00:00
										 |  |  | 		Py_RETURN_NONE; | 
					
						
							| 
									
										
										
										
											2006-01-11 19:41:01 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RuntimeError: | 
					
						
							|  |  |  | 	return EXPP_objError(PyExc_RuntimeError, "%s%s%s",  | 
					
						
							|  |  |  | 		sPoseBoneError, "PyPoseBone_FromPosechannel: ", "Internal Error Ocurred"); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2006-05-14 18:24:11 +00:00
										 |  |  | //------------------------------Object_FromPoseChannel (internal)
 | 
					
						
							|  |  |  | //An ugly method for determining where the pchan chame from
 | 
					
						
							|  |  |  | Object *Object_FromPoseChannel(bPoseChannel *curr_pchan) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int success = 0; | 
					
						
							|  |  |  | 	Object *obj = NULL; | 
					
						
							|  |  |  | 	bPoseChannel *pchan = NULL; | 
					
						
							|  |  |  | 	for(obj = G.main->object.first; obj; obj = obj->id.next){ | 
					
						
							|  |  |  | 		if (obj->pose){ | 
					
						
							|  |  |  | 			for (pchan = obj->pose->chanbase.first; pchan; pchan = pchan->next){ | 
					
						
							|  |  |  | 				if (curr_pchan == pchan){ | 
					
						
							|  |  |  | 					success = 1; | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (success) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return obj; | 
					
						
							|  |  |  | } |