[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11060] branches/pyapi_devel/source/ blender/python/api2_2x: PyAPI: added extra checks to mesh api ( some of these should be added to trunk & 2.44 stable)
Campbell Barton
cbarton at metavr.com
Tue Jun 26 10:06:32 CEST 2007
Revision: 11060
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11060
Author: campbellbarton
Date: 2007-06-26 10:06:32 +0200 (Tue, 26 Jun 2007)
Log Message:
-----------
PyAPI: added extra checks to mesh api (some of these should be added to trunk & 2.44 stable)
Added a PyObject to the vector struct, so a vector can reference an PyObject with an ID or a matrix.
added checks so that a wrapped vector will raise an error if the (ID) data it references is removed.
This means a scenes cursor (vector) complain if its used when the scenes deleted. before this would mess up memory.
removed checks for the creation of PyInts
Still need to make
Modified Paths:
--------------
branches/pyapi_devel/source/blender/python/api2_2x/Mesh.c
branches/pyapi_devel/source/blender/python/api2_2x/vector.c
branches/pyapi_devel/source/blender/python/api2_2x/vector.h
Modified: branches/pyapi_devel/source/blender/python/api2_2x/Mesh.c
===================================================================
--- branches/pyapi_devel/source/blender/python/api2_2x/Mesh.c 2007-06-26 04:28:23 UTC (rev 11059)
+++ branches/pyapi_devel/source/blender/python/api2_2x/Mesh.c 2007-06-26 08:06:32 UTC (rev 11060)
@@ -126,7 +126,13 @@
static PyObject *MFace_CreatePyObject( BPy_Mesh * bpymesh, int i );
static PyObject *MEdge_CreatePyObject( BPy_Mesh * bpymesh, int i );
+/* These checks are only needed if we allow users to remove meshes */
+// #define MESH_DEL_CHECK_PY(_mesh) if (!(_mesh)) return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "This mesh has been removed" ) )
+// #define MESH_DEL_CHECK_INT(_mesh) if (!(_mesh)) return ( EXPP_ReturnIntError( PyExc_RuntimeError, "This mesh has been removed" ) )
+#define MFACE_VERT_BADRANGE_CHECK(me, face) ((int)face->v1 >= me->totvert || (int)face->v2 >= me->totvert || (int)face->v3 >= me->totvert || (int)face->v4 >= me->totvert)
+#define MEDGE_VERT_BADRANGE_CHECK(me, edge) ((int)edge->v1 >= me->totvert || (int)edge->v2 >= me->totvert)
+
/************************************************************************
*
* internal utilities
@@ -588,8 +594,11 @@
static PyObject *MCol_getAttr( BPy_MCol * self, void *type )
{
unsigned char param;
- PyObject *attr;
-
+
+ // MESH_DEL_CHECK_PY(self->bpymesh->mesh);
+
+ /* TODO - Check the face was still there */
+
switch( (long)type ) {
case 'R': /* these are backwards, but that how it works */
param = self->color->b;
@@ -612,12 +621,7 @@
}
}
- attr = PyInt_FromLong( param );
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed");
+ return PyInt_FromLong( param );
}
/*
@@ -627,7 +631,9 @@
static int MCol_setAttr( BPy_MCol * self, PyObject * value, void * type )
{
unsigned char *param;
-
+
+ // MESH_DEL_CHECK_INT(self->bpymesh->mesh);
+
switch( (long)type ) {
case 'R': /* these are backwards, but that how it works */
param = (unsigned char *)&self->color->b;
@@ -690,7 +696,9 @@
static PyObject *MCol_item(BPy_MCol * self, int i)
{
unsigned char param;
- PyObject *attr;
+
+ // MESH_DEL_CHECK_PY(self->bpymesh->mesh);
+
switch (i) {
case 0:
param = self->color->b;
@@ -709,12 +717,7 @@
"vector[index] = x: assignment index out of range\n");
}
- attr = PyInt_FromLong( param );
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed");
+ return PyInt_FromLong( param );
}
/*----------------------------object[]-------------------------
@@ -723,6 +726,8 @@
{
unsigned char *param;
+ // MESH_DEL_CHECK_INT(self->bpymesh->mesh);
+
switch (i) {
case 0:
param = (unsigned char *)&self->color->b; /* reversed? why */
@@ -752,9 +757,13 @@
static PyObject *MCol_repr( BPy_MCol * self )
{
+ if (self->bpymesh->mesh) {
return PyString_FromFormat( "[MCol %d %d %d %d]",
(int)self->color->b, (int)self->color->g,
- (int)self->color->r, (int)self->color->a );
+ (int)self->color->r, (int)self->color->a );
+ } else {
+ return PyString_FromString( "[MCol <deleted>]" );
+ }
}
/*-----------------PROTCOL DECLARATIONS--------------------------*/
@@ -878,16 +887,15 @@
static MVert * MVert_get_pointer( BPy_MVert * self )
{
- //if( BPy_MVert_Check( self ) ) {
+ if( BPy_MVert_Check( self ) ) {
if (!self->bpymesh->mesh || self->index >= ((Mesh *)(self->bpymesh->mesh))->totvert)
return (MVert *)EXPP_ReturnPyObjError( PyExc_RuntimeError,
"MVert is no longer valid" );
- return &((Mesh *)self->bpymesh->mesh)->mvert[self->index];
- //}
- /* TODO - pvert support */
- //else
- // return (MVert *)self->data;
+ return &(self->bpymesh->mesh)->mvert[self->index];
+ } else {
+ return (MVert *)self->bpymesh;
+ }
}
/*
@@ -897,10 +905,10 @@
static PyObject *MVert_getCoord( BPy_MVert * self )
{
MVert *v;
-
+
v = MVert_get_pointer( self );
if( !v )
- return NULL;
+ return NULL; /* error is set */
return newVectorObject( v->co, 3, Py_WRAP, (BPy_GenericLib *)self->bpymesh );
}
@@ -916,7 +924,7 @@
v = MVert_get_pointer( self );
if( !v )
- return -1;
+ return -1; /* error is set */
if( !VectorObject_Check( value ) || value->size != 3 )
return EXPP_ReturnIntError( PyExc_TypeError,
@@ -934,18 +942,13 @@
static PyObject *MVert_getIndex( BPy_MVert * self )
{
- PyObject *attr;
-
+ // MESH_DEL_CHECK_PY(self->bpymesh->mesh);
+
if( self->index >= self->bpymesh->mesh->totvert )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"MVert is no longer valid" );
- attr = PyInt_FromLong( self->index );
- if( attr )
- return attr;
-
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "PyInt_FromLong() failed" );
+ return PyInt_FromLong( self->index );
}
@@ -960,8 +963,7 @@
v = MVert_get_pointer( self );
if (!v)
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "This mesh is no longer valid" );
+ return NULL; /* error is set */
if( self->index >= self->bpymesh->mesh->totvert )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -983,8 +985,7 @@
v = MVert_get_pointer( self );
if (!v)
- return EXPP_ReturnIntError( PyExc_RuntimeError,
- "This mesh is no longer valid" );
+ return -1; /* error is set */
if( self->index >= self->bpymesh->mesh->totvert )
return EXPP_ReturnIntError( PyExc_RuntimeError,
@@ -1007,7 +1008,7 @@
v = MVert_get_pointer( self );
if( !v )
- return NULL;
+ return NULL; /* error set */
for( i = 0; i < 3; ++i )
no[i] = (float)(v->no[i] / 32767.0);
@@ -1026,7 +1027,7 @@
v = MVert_get_pointer( self );
if( !v )
- return -1;
+ return -1; /* error set */
if( !VectorObject_Check( value ) || value->size != 3 )
return EXPP_ReturnIntError( PyExc_TypeError,
@@ -1055,7 +1056,7 @@
v = MVert_get_pointer( self );
if( !v )
- return NULL;
+ return NULL; /* error is set */
return EXPP_getBitfield( &v->flag, SELECT, 'b' );
}
@@ -1094,7 +1095,11 @@
static PyObject *MVert_getUVco( BPy_MVert *self )
{
Mesh *me = self->bpymesh->mesh;
-
+
+ if( !me )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "mesh has been removed" );
+
if( !me->msticky )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"mesh has no 'sticky' coordinates" );
@@ -1123,7 +1128,7 @@
*/
if( !me )
return EXPP_ReturnIntError( PyExc_RuntimeError,
- "This mesh is no longer valid" );
+ "This mesh has been removed" );
if( !me->msticky )
return EXPP_ReturnIntError( PyExc_AttributeError,
@@ -1135,15 +1140,12 @@
if( VectorObject_Check( value ) ) {
VectorObject *vect = (VectorObject *)value;
- if( vect->size != 2 )
- return EXPP_ReturnIntError( PyExc_AttributeError,
- "expected 2D vector" );
- for( i = 0; i < vect->size; ++i )
+ for( i = 0; i < vect->size; ++i ) /* allow 3d vectors, just use the 2d part */
uvco[i] = vect->vec[i];
} else if( !PyArg_ParseTuple( value, "ff",
&uvco[0], &uvco[1] ) )
return EXPP_ReturnIntError( PyExc_TypeError,
- "expected 2D vector" );
+ "expected 2D vector or a float pair" );
v = &me->msticky[self->index];
@@ -1226,11 +1228,12 @@
{
char format[512];
char index[24];
- MVert *v;
+ MVert *v = MVert_get_pointer( self );
- v = MVert_get_pointer( self );
- if( !v )
- return NULL;
+ if( !v ) {
+ PyErr_Clear(); /* clear error from MFace_get_pointer */
+ return PyString_FromString( "[MVert <deleted>]");
+ }
if( BPy_MVert_Check( self ) )
sprintf( index, "%d", self->index );
@@ -1717,7 +1720,7 @@
"MEM_callocN() failed" );
memcpy( newvert, vert, sizeof( MVert ) );
- //obj->bpydata = newvert; // TODO - add support back.
+ obj->bpymesh = ( BPy_GenericLib *)newvert;
return (PyObject *)obj;
}
@@ -1729,6 +1732,8 @@
static int MVertSeq_len( BPy_MVertSeq * self )
{
+ if (!self->bpymesh->mesh)
+ return 0;
return self->bpymesh->mesh->totvert;
}
@@ -1738,6 +1743,8 @@
static PyObject *MVertSeq_item( BPy_MVertSeq * self, int i )
{
+ // MESH_DEL_CHECK_PY(self->bpymesh->mesh);
+
if( i < 0 || i >= self->bpymesh->mesh->totvert )
return EXPP_ReturnPyObjError( PyExc_IndexError,
"array index out of range" );
@@ -1759,12 +1766,14 @@
PyObject *list;
int i;
+ // MESH_DEL_CHECK_PY(self->bpymesh->mesh);
+
/*
* Python list slice operator returns empty list when asked for a slice
* outside the list, or if indices are reversed (low > high). Clamp
* our input to do the same.
*/
-
+
if( low < 0 ) low = 0;
if( high > self->bpymesh->mesh->totvert ) high = self->bpymesh->mesh->totvert;
if( low > high ) low = high;
@@ -1791,9 +1800,13 @@
static int MVertSeq_assign_item( BPy_MVertSeq * self, int i,
BPy_MVert *v )
{
- MVert *dst = &self->bpymesh->mesh->mvert[i];
+ MVert *dst;
MVert *src;
-
+
+ // MESH_DEL_CHECK_INT(self->bpymesh->mesh);
+
+ dst = &self->bpymesh->mesh->mvert[i];
+
if( !v )
return EXPP_ReturnIntError( PyExc_IndexError,
"del() not supported" );
@@ -1804,8 +1817,8 @@
if( BPy_MVert_Check( v ) )
src = &((Mesh *)v->bpymesh->mesh)->mvert[v->index];
- //else
- // src = v->data; /* TODO - add pvert support */
+ else
+ src = (MVert *)v->bpymesh;
memcpy( dst, src, sizeof(MVert) );
/* mesh_update( self->mesh );*/
@@ -1820,7 +1833,9 @@
if( !PyList_Check( args ) )
return EXPP_ReturnIntError( PyExc_IndexError,
"can only assign lists of MVerts" );
-
+
+ // MESH_DEL_CHECK_INT(self->bpymesh->mesh);
+
len = PyList_Size( args );
/*
@@ -1891,6 +1906,8 @@
static PyObject *MVertSeq_getIter( BPy_MVertSeq * self )
{
+ // MESH_DEL_CHECK_PY(self->bpymesh->mesh);
+
if (self->iter==-1) { /* iteration for this pyobject is not yet used, just return self */
self->iter = 0;
return EXPP_incr_ret ( (PyObject *) self );
@@ -1908,6 +1925,8 @@
static PyObject *MVertSeq_nextIter( BPy_MVertSeq * self )
{
+ // MESH_DEL_CHECK_PY(self->bpymesh->mesh);
+
if( self->iter == self->bpymesh->mesh->totvert ) {
self->iter= -1; /* allow it to be used as an iterator again without creating a new BPy_MVertSeq */
return EXPP_ReturnPyObjError( PyExc_StopIteration,
@@ -1933,6 +1952,8 @@
CustomData vdata;
/* make sure we get a sequence of tuples of something */
+ // MESH_DEL_CHECK_PY(mesh);
+
switch( PySequence_Size( args ) ) {
case 1: /* better be a list or a tuple */
tmp = PyTuple_GET_ITEM( args, 0 );
@@ -2096,6 +2117,8 @@
Mesh *mesh = self->bpymesh->mesh;
MFace *tmpface;
+ // MESH_DEL_CHECK_PY(mesh);
+
/*
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list