Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Gilbert <ascotan@gmail.com>2006-05-14 22:24:11 +0400
committerJoseph Gilbert <ascotan@gmail.com>2006-05-14 22:24:11 +0400
commitd305965b3d39ed7c8012b41ab22785a5125143aa (patch)
tree21ba0226456154b2cb509fe1698c0a3d50962ab6 /source/blender/python/api2_2x/Pose.c
parent1b7f9dfee636a02e34e7acdd8416415e12aee571 (diff)
*applying patch
[ #4143 ] Methods for reading bone movement limits Submitted By: Aron Cristian (criller) Gives the ability to return/set the limitations on a posebone when that bone is part of an IK chain.
Diffstat (limited to 'source/blender/python/api2_2x/Pose.c')
-rw-r--r--source/blender/python/api2_2x/Pose.c202
1 files changed, 195 insertions, 7 deletions
diff --git a/source/blender/python/api2_2x/Pose.c b/source/blender/python/api2_2x/Pose.c
index 4a78208046c..4a168fbb862 100644
--- a/source/blender/python/api2_2x/Pose.c
+++ b/source/blender/python/api2_2x/Pose.c
@@ -39,6 +39,7 @@
#include "BKE_utildefines.h"
#include "BIF_editaction.h"
#include "BIF_space.h"
+#include "BIF_poseobject.h"
#include "BKE_depsgraph.h"
#include "DNA_object_types.h"
#include "DNA_ipo_types.h"
@@ -712,13 +713,175 @@ static PyObject *PoseBone_getConstraints(BPy_PoseBone *self, void *closure)
{
return PoseConstraintSeq_CreatePyObject( self->posechannel );
}
-////------------------------PoseBone.constraints (setter)
-////Sets the constraints list
-//static int PoseBone_setConstraints(BPy_PoseBone *self, PyObject *value, void *closure)
-//{
-// printf("This is not implemented yet...");
-// return 1;
-//}
+//------------------------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;
+}
//------------------------PoseBone.head (getter)
//Gets the pose head position
static PyObject *PoseBone_getHead(BPy_PoseBone *self, void *closure)
@@ -765,6 +928,10 @@ static PyGetSetDef BPy_PoseBone_getset[] = {
"The pose bone's head positon", NULL},
{"tail", (getter)PoseBone_getTail, (setter)PoseBone_setTail,
"The pose bone's tail positon", NULL},
+ {"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},
{"constraints", (getter)PoseBone_getConstraints, (setter)NULL,
"The list of contraints that pertain to this pose bone", NULL},
{NULL, NULL, NULL, NULL, NULL}
@@ -921,3 +1088,24 @@ RuntimeError:
return EXPP_objError(PyExc_RuntimeError, "%s%s%s",
sPoseBoneError, "PyPoseBone_FromPosechannel: ", "Internal Error Ocurred");
}
+//------------------------------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;
+}