[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11964] trunk/blender/source/blender/ python/api2_2x: =Python Bugfix=

Joseph Eagar joeedh at gmail.com
Sat Sep 8 02:04:32 CEST 2007


Revision: 11964
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11964
Author:   joeedh
Date:     2007-09-08 02:04:32 +0200 (Sat, 08 Sep 2007)

Log Message:
-----------
=Python Bugfix=
The python wrapper code for shape keys was really bad; whoever wrote it
(mis)read the wrong section of blender's codebase and got the totally wrong
idea.  The code was definitely broken to the point where either it had to be
fixed for 2.45, or else the entire keyblock wrapper would have to be removed
from the stable branch.  The fact that it didn't crash is just sheer luck;
the code assume mesh keys were MVerts, when in fact mesh keys are just
arrays of three-float vectors.

So shapekey data can now be editing directly, and is exposed as Mathutils.Vectors.
Also I updated the epydocs to explain how it all works now.

Modified Paths:
--------------
    trunk/blender/source/blender/python/api2_2x/Key.c
    trunk/blender/source/blender/python/api2_2x/doc/Key.py

Modified: trunk/blender/source/blender/python/api2_2x/Key.c
===================================================================
--- trunk/blender/source/blender/python/api2_2x/Key.c	2007-09-07 23:33:30 UTC (rev 11963)
+++ trunk/blender/source/blender/python/api2_2x/Key.c	2007-09-08 00:04:32 UTC (rev 11964)
@@ -519,23 +519,12 @@
 	case ID_ME:
 
 		for (i=0, datap = kb->keyblock->data; i<kb->keyblock->totelem; i++) {
+			PyObject *vec = newVectorObject((float*)datap, 3, Py_WRAP);
+			
+			if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+					  "could not allocate memory for Blender.Mathutils.Vector wrapper!" );
 
-			BPy_NMVert *mv = PyObject_NEW( BPy_NMVert, &NMVert_Type );
-			MVert *vert = (MVert *) datap;
-
-			mv->co[0]=vert->co[0];
-			mv->co[1]=vert->co[1];
-			mv->co[2]=vert->co[2];
-			mv->no[0] = 0.0;
-			mv->no[1] = 0.0;
-			mv->no[2] = 0.0;
-
-			mv->uvco[0] = mv->uvco[1] = mv->uvco[2] = 0.0;
-			mv->index = i;
-			mv->flag = 0;
-
-			PyList_SetItem(l, i, ( PyObject * ) mv);
-
+			PyList_SetItem(l, i, vec);
 			datap += kb->key->elemsize;
 		}
 		break;
@@ -552,44 +541,63 @@
 			Py_DECREF (l);	
 			l = PyList_New( datasize );
 			for( i = 0, datap = kb->keyblock->data; i < datasize;
-					i++, datap += sizeof(float)*12 ) {
-				/* 
-				 * since the key only stores the control point and not the
-				 * other BezTriple attributes, build a Py_NEW BezTriple
-				 */
-				PyObject *pybt = newBezTriple( (float *)datap );
-				PyList_SetItem( l, i, pybt );
+					i++, datap += sizeof(float)*3*4) {
+				PyObject *tuple = PyTuple_New(4), *vec;
+				float *vecs = (float*)datap;
+				
+				if (!tuple) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+					  "PyTuple_New() failed!" );
+					  
+				vec = newVectorObject(vecs, 3, Py_WRAP);
+				if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+					  "Could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+					  
+				PyTuple_SET_ITEM( tuple, 0, vec);
+				
+				vecs += 3;
+				vec = newVectorObject(vecs, 3, Py_WRAP);
+				if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+					  "Could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+
+				PyTuple_SET_ITEM( tuple, 1, vec);
+				
+				vecs += 3;
+				vec = newVectorObject(vecs, 3, Py_WRAP);
+				if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+					  "Could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+
+				PyTuple_SET_ITEM( tuple, 2, vec);
+				
+				/*tilts*/
+				vecs += 3;				
+				vec = newVectorObject(vecs, 3, Py_WRAP);
+				if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+					  "Could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+
+				PyTuple_SET_ITEM( tuple, 3, vec);
+				
+				PyList_SetItem( l, i, tuple );
 			}
 		} else {
 			for( i = 0, datap = kb->keyblock->data; i < datasize;
 					i++, datap += kb->key->elemsize ) {
-				PyObject *pybt;
-				float *fp = (float *)datap;
-				pybt = Py_BuildValue( "[f,f,f]", fp[0],fp[1],fp[2]);
-				if( !pybt ) {
-					Py_DECREF( l );
-					return EXPP_ReturnPyObjError( PyExc_MemoryError,
-					      "Py_BuildValue() failed" );							
-				}
-				PyList_SetItem( l, i, pybt );
+				PyObject *vec = newVectorObject((float*)datap, 4, Py_WRAP);
+				if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+					  "could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+				
+				PyList_SetItem( l, i, vec );
 			}
 		}
 		break;
 
 	case ID_LT:
-
 		for( i = 0, datap = kb->keyblock->data; i < kb->keyblock->totelem;
 				i++, datap += kb->key->elemsize ) {
-			/* Lacking a python class for BPoint, use a list of three floats */
-			PyObject *pybt;
-			float *fp = (float *)datap;
-			pybt = Py_BuildValue( "[f,f,f]", fp[0],fp[1],fp[2]);
-			if( !pybt ) {
-				Py_DECREF( l );
-				return EXPP_ReturnPyObjError( PyExc_MemoryError,
-					  "Py_BuildValue() failed" );							
-			}
-			PyList_SetItem( l, i, pybt );
+			PyObject *vec = newVectorObject((float*)datap, 3, Py_WRAP);
+			if (!vec) return EXPP_ReturnPyObjError( PyExc_MemoryError,
+					  "Could not allocate memory for Blender.Mathutils.Vector wrapper!" );
+			
+			PyList_SetItem( l, i, vec );
 		}
 		break;
 	}

Modified: trunk/blender/source/blender/python/api2_2x/doc/Key.py
===================================================================
--- trunk/blender/source/blender/python/api2_2x/doc/Key.py	2007-09-07 23:33:30 UTC (rev 11963)
+++ trunk/blender/source/blender/python/api2_2x/doc/Key.py	2007-09-08 00:04:32 UTC (rev 11964)
@@ -89,16 +89,33 @@
 	def getData():
 		"""
 		Get the data of a KeyBlock, as a list of data items. Each item
-		will have a different data type depending on the type of this
+		will have a different data format depending on the type of this
 		Key.
-			- Mesh keys have a list of L{NMVert<NMesh.NMVert>} objects in the data
+		
+		Note that prior to 2.45 the behaviour of this function
+		was different (and very wrong).  Old scripts might need to be
+		updated.
+		
+			- Mesh keys have a list of L{Vectors<Mathutils.Vector>} objects in the data
 			block.
-			- Lattice keys have a list of BPoints in the data block. These
-			don't have corresponding Python objects yet, so each BPoint is
-			represented using a list of three floating-point numbers (the
-			coordinate for each lattice vertex).
-			- Curve keys return either a list of L{BezTriple<BezTriple.BezTriple>}
-			objects in the data if the curve is a Bezier curve, otherwise it 
-			returns lists of three floats for each NURB or poly coordinate.
+			- Lattice keys have a list of L{Vectors<Mathutils.Vector>} objects in the data
+			block.
+			- Curve keys return either a list of tuples, eacn containing
+			 four L{Vectors<Mathutils.Vector>} (if the curve is a Bezier curve),
+			 or otherwise just a list of L{Vectors<Mathutils.Vector>}.
+			 
+			 For bezier keys, the first three vectors in the tuple are the Bezier
+			 triple vectors, while the fourth vector's first element is the curve tilt
+			 (the other two elements are reserved and are currently unused).
+			 
+			 For non-Bezier keys, the first three elements of the returned vector is
+			 the curve handle point, while the fourth element is the tilt.
+			 
+		
+		A word on relative shape keys; relative shape keys are not actually
+		stored as offsets to the base shape key (like you'd expect).  Instead, 
+		the additive relative offset is calculated on the fly by comparing a 
+		shape key with its base key, which is always the very first shapekey 
+		in the keyblock list.
 		"""
 





More information about the Bf-blender-cvs mailing list