[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11100] branches/pyapi_devel/source/ blender/python/api2_2x: Mesh UV vectors not point back to their faces.

Campbell Barton cbarton at metavr.com
Thu Jun 28 16:41:08 CEST 2007


Revision: 11100
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11100
Author:   campbellbarton
Date:     2007-06-28 16:41:07 +0200 (Thu, 28 Jun 2007)

Log Message:
-----------
Mesh UV vectors not point back to their faces. so if the face is removed or UV's deleted, the vector knows its removed (rather then accessing free'd memory).

Modified Paths:
--------------
    branches/pyapi_devel/source/blender/python/api2_2x/Mesh.c
    branches/pyapi_devel/source/blender/python/api2_2x/matrix.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-28 13:46:42 UTC (rev 11099)
+++ branches/pyapi_devel/source/blender/python/api2_2x/Mesh.c	2007-06-28 14:41:07 UTC (rev 11100)
@@ -1007,10 +1007,6 @@
 	
 	if (!v)
 		return NULL; /* error is set */
-	
-	if( self->index >= self->bpymesh->mesh->totvert )
-		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-				"MVert is no longer valid" );
 
 	return EXPP_getBitfield( &v->flag, (int)((long)type & 0xff), 'b' );
 }
@@ -1029,10 +1025,6 @@
 
 	if (!v)
 		return -1; /* error is set */
-	
-	if( self->index >= self->bpymesh->mesh->totvert )
-		return EXPP_ReturnIntError( PyExc_RuntimeError,
-				"MVert is no longer valid" );
 
 	return EXPP_setBitfield( value, &v->flag, 
 			(int)((long)type & 0xff), 'b' );
@@ -1113,9 +1105,8 @@
 	MVert *v = MVert_get_pointer( self );
 	Mesh *me = self->bpymesh->mesh;
 	if (!v)
-		return EXPP_ReturnIntError( PyExc_RuntimeError,
-				"This mesh is no longer valid" );
-	
+		return -1; /* error is set */
+
 	/* 
 	 * if vertex exists and setting status is OK, delete select storage
 	 * of the edges and faces as well
@@ -1921,8 +1912,8 @@
 
 		if( BPy_MVert_Check( v ) )
 			src = &((Mesh *)v->bpymesh->mesh)->mvert[v->index];
-		//else
-		//	src = (MVert *)v->data;
+		else
+			src = (MVert *)v->bpymesh;
 
 		memcpy( dst, src, sizeof(MVert) );
 	}
@@ -2271,7 +2262,13 @@
 	tmpvert = mesh->mvert;
 	for( i = 0; i < mesh->totvert; ++i, ++tmpvert ) {
 		if( tmpvert->flag & SELECT ) {
-			PyList_SET_ITEM( list, count, PyInt_FromLong( i ) );
+			PyObject *tmp = PyInt_FromLong( i );
+			if( !tmp ) {
+				Py_DECREF( list );
+				return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+						"PyInt_FromLong() failed" );
+			}
+			PyList_SET_ITEM( list, count, tmp );
 			++count;
 		}
 	}
@@ -2816,7 +2813,7 @@
 	struct MEdge *edge = MEdge_get_pointer( self );
 
 	if( !edge ) {
-		PyErr_Clear();
+		PyErr_Clear(); /* allow printing a removed edge */
 		return PyString_FromFormat( "[MEdge <deleted>]" );
 	}
 
@@ -3706,7 +3703,13 @@
 	for( i = 0; i < mesh->totedge; ++i, ++tmpedge ) {
 		if( (mesh->mvert[tmpedge->v1].flag & SELECT) &&
 				(mesh->mvert[tmpedge->v2].flag & SELECT) ) {
-			PyList_SET_ITEM( list, count, PyInt_FromLong( i ) );
+			PyObject *tmp = PyInt_FromLong( i );
+			if( !tmp ) {
+				Py_DECREF( list );
+				return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+						"PyInt_FromLong() failed" );
+			}
+			PyList_SET_ITEM( list, count, tmp );
 			++count;
 		}
 	}
@@ -4006,8 +4009,7 @@
 	MFace *face = MFace_get_pointer( self );
 
 	if( !face )
-		return EXPP_ReturnIntError( PyExc_RuntimeError,
-				"This mesh is no longer valid" );
+		return -1; /* error is set */
 
 	return EXPP_setIValueRange( value, &face->mat_nr, 0, 15, 'b' );
 }
@@ -4021,8 +4023,7 @@
 	MFace *face = MFace_get_pointer( self );
 
 	if( !face )
-		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-				"This mesh is no longer valid" );
+		return NULL; /* error is set */
 
 	return PyInt_FromLong( self->index );
 }
@@ -4039,8 +4040,7 @@
 	Mesh *me = self->bpymesh->mesh;
 	
 	if( !face )
-		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-				"This mesh is no longer valid" );
+	return NULL; /* error is set */
 	
 	if MFACE_VERT_BADRANGE_CHECK(me, face)
 		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@@ -4106,9 +4106,6 @@
 	float *v1,*v2,*v3,*v4;
 	MFace *face;
 	Mesh *me = self->bpymesh->mesh;
-	if( !me )
-		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-				"This mesh is no longer valid" );
 	
 	face = MFace_get_pointer( self );
 	
@@ -4293,10 +4290,14 @@
 				"PyTuple_New() failed" );
 
 	for( i=0; i<length; ++i ) {
-		PyObject *vector = newVectorObject( face->uv[i], 2, (PyObject *)self->bpymesh );
-		if( !vector )
+		VectorObject *vector = (VectorObject *)newVectorObject( face->uv[i], 2, (PyObject *)self );
+		
+		if( !vector ) {
+			Py_DECREF(attr);
 			return NULL;
-		PyTuple_SetItem( attr, i, vector );
+		}
+		vector->sub_index = i;
+		PyTuple_SET_ITEM( attr, i, (PyObject *)vector );
 	}
 
 	return attr;
@@ -4372,7 +4373,13 @@
 	/* get coord select state, one bit at a time */
 	mask = TF_SEL1;
 	for( i=0; i<length; ++i, mask <<= 1 ) {
-		PyTuple_SetItem( attr, i, PyInt_FromLong( face->flag & mask ? 1 : 0 ) );
+		PyObject *value = PyInt_FromLong( face->flag & mask ? 1 : 0 );
+		if( !value ) {
+			Py_DECREF( attr );
+			return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+				"PyInt_FromLong() failed" );
+		}
+		PyTuple_SetItem( attr, i, value );
 	}
 
 	return attr;
@@ -4531,12 +4538,10 @@
 static PyObject *MFace_getEdgeKeys( BPy_MFace * self )
 {
 	MFace *face = MFace_get_pointer( self );
-	
 	PyObject *attr, *edpair;
 	
 	if (!face)
-		return EXPP_ReturnPyObjError( PyExc_RuntimeError,
-				"This face is no longer valid" );
+		return NULL; /* error set */
 	
 	if (face->v4) {
 		attr = PyTuple_New( 4 );
@@ -5652,7 +5657,13 @@
 	tmpface = mesh->mface;
 	for( i = 0; i < mesh->totface; ++i, ++tmpface ) {
 		if( tmpface->flag & ME_FACE_SEL ) {
-			PyList_SET_ITEM( list, count, PyInt_FromLong( i ) );
+			PyObject *tmp = PyInt_FromLong( i );
+			if( !tmp ) {
+				Py_DECREF( list );
+				return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+						"PyInt_FromLong() failed" );
+			}
+			PyList_SET_ITEM( list, count, tmp );
 			++count;
 		}
 	}
@@ -5909,7 +5920,11 @@
 	for( i = 0; i < self->mesh->totedge; ++i ) {
 		if( ( edge->v1 == v1 && edge->v2 == v2 )
 				|| ( edge->v1 == v2 && edge->v2 == v1 ) ) {
-			return PyInt_FromLong( i );
+			tmp = PyInt_FromLong( i );
+			if( tmp )
+				return tmp;
+			return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+					"PyInt_FromLong() failed" );
 		}
 		++edge;
 	}
@@ -6065,11 +6080,18 @@
 		/* search edge list for a match; result is index or None */
 		result = bsearch( &target, oldpair, mesh->totedge,
 				sizeof(SrchEdges), medge_comp );
-		
 		if( result )
-			PyList_SET_ITEM( list, i, PyInt_FromLong( result->index ) );
+			tmp = PyInt_FromLong( result->index );
 		else
-			PyList_SET_ITEM( list, i, EXPP_incr_ret( Py_None ) );
+			tmp = EXPP_incr_ret( Py_None );
+		if( !tmp ) {
+			MEM_freeN( oldpair );
+			Py_DECREF( args );
+			Py_DECREF( list );
+			return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+				"PyInt_FromLong() failed" );
+		}
+		PyList_SET_ITEM( list, i, tmp );
 	}
 
 	MEM_freeN( oldpair );
@@ -7206,6 +7228,9 @@
 		result = removedoublesflag( 1, *((float *)args[0]) );
 
 		attr = PyInt_FromLong( result );
+		if( !attr )
+			return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+					"PyInt_FromLong() failed" );
 		break;
 	case MESH_TOOL_FILL:
 		fill_mesh();

Modified: branches/pyapi_devel/source/blender/python/api2_2x/matrix.c
===================================================================
--- branches/pyapi_devel/source/blender/python/api2_2x/matrix.c	2007-06-28 13:46:42 UTC (rev 11099)
+++ branches/pyapi_devel/source/blender/python/api2_2x/matrix.c	2007-06-28 14:41:07 UTC (rev 11100)
@@ -512,13 +512,17 @@
   the wrapped vector gives direct access to the matrix data*/
 static PyObject *Matrix_item(MatrixObject * self, int i)
 {
+	VectorObject *vec;
 	CHECK_MAT_ERROR_PY(self);
 	
+	
 	if(i < 0 || i >= self->rowSize)
 		return EXPP_ReturnPyObjError(PyExc_IndexError,
 		"matrix[attribute]: array index out of range\n");
 
-	return newVectorObject(self->matrix[i], self->colSize, (PyObject *)self);
+	vec = newVectorObject(self->matrix[i], self->colSize, (PyObject *)self);
+	vec->sub_index = (char)i;
+	return (PyObject *)vec; 
 }
 /*----------------------------object[]-------------------------
   sequence accessor (set)*/
@@ -575,7 +579,8 @@
 
 	PyObject *list = NULL;
 	int count;
-
+	VectorObject *vec;
+	
 	CHECK_MAT_ERROR_PY(self);
 	
 	CLAMP(begin, 0, self->rowSize);
@@ -584,8 +589,9 @@
 
 	list = PyList_New(end - begin);
 	for(count = begin; count < end; count++) {
-		PyList_SetItem(list, count - begin,
-				newVectorObject(self->matrix[count], self->colSize, (PyObject *)self));
+		vec = newVectorObject(self->matrix[count], self->colSize, (PyObject *)self);
+		vec->sub_index = (char)count;
+		PyList_SetItem(list, count - begin,	(PyObject *)vec);
 	}
 
 	return list;

Modified: branches/pyapi_devel/source/blender/python/api2_2x/vector.c
===================================================================
--- branches/pyapi_devel/source/blender/python/api2_2x/vector.c	2007-06-28 13:46:42 UTC (rev 11099)
+++ branches/pyapi_devel/source/blender/python/api2_2x/vector.c	2007-06-28 14:41:07 UTC (rev 11100)
@@ -1270,10 +1270,15 @@
 
 /*------------------------newVectorObject (internal)-------------
   creates a new vector object
-  pass Py_WRAP - if vector is a WRAPPER for data allocated by BLENDER
- (i.e. it was allocated elsewhere by MEM_mallocN())
-  pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON
- (i.e. it must be created here with PyMEM_malloc())*/
+  if source is NULL, this is not a wrapped.
+  Py_None - wrapped but its pointer wont be updated  
+  Matrix - an item of a pointer, use vec->sub_index to set the row
+  Vertex - location
+  Face - UV, vec->sub_index for the point in the face (0-3)
+  PVert - ignored, like None
+  
+  checkVectorObject to see how different data is updated from its source.
+  */
 PyObject *newVectorObject(float *vec, int size, PyObject * source)
 {
 	int i;
@@ -1315,25 +1320,15 @@
 			if (!checkMatrixObject((MatrixObject *)self->source)) {
 				return 0;
 			} else {
-				/* Dont update the vector pointer 
-				 * This requires the vector to remember its index from the matrix */
-				/*
 				MatrixObject *mat = (MatrixObject *)self->source;
-				// now refresh the pointer and size 
+				
+				/* the matrix was resized to remove this vector slice */
+				if (mat->rowSize < self->sub_index)
+					return 0;
+				
 				self->size = mat->colSize;
-				self->vec = mat->matrix[self->wrapped-1];
+				self->vec = mat->matrix[self->sub_index];
 				return 1;
-				*/
-				MatrixObject *mat = (MatrixObject *)self->source;
-				
-				int i;
-				for (i=0; i < mat->colSize; i++) {
-					if (self->vec == mat->matrix[i]) {
-						return 1;
-					}
-				}
-				/* vector is not in matrix anymore */
-				return 0;
 			}
 		} else if (BPy_MVert_Check(self->source)) {
 			/* make sure the MVert is valid and update this pointer
@@ -1341,13 +1336,13 @@
 			 * The way things work at the moment,
 			 * - the vector is a user of the vertex,
 			 * - the vertex is a user of the bpymesh

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list