From aa8c1a016b58eae03baf85f7b3c846b147b2a98f Mon Sep 17 00:00:00 2001 From: Ken Hughes Date: Sun, 1 Jan 2006 15:54:30 +0000 Subject: [PATCH] Created local function check_NMeshLists(), which performs checking on NMesh lists before trying to build a new mesh (used by mesh.PutRaw() and mesh.update()). It was possible to put junk into the NMesh lists, resulting in some messed-up meshes. --- source/blender/python/api2_2x/NMesh.c | 106 ++++++++++++++++++++------ 1 file changed, 84 insertions(+), 22 deletions(-) diff --git a/source/blender/python/api2_2x/NMesh.c b/source/blender/python/api2_2x/NMesh.c index a22307c7574..f285557d5ee 100644 --- a/source/blender/python/api2_2x/NMesh.c +++ b/source/blender/python/api2_2x/NMesh.c @@ -317,6 +317,77 @@ void mesh_update( Mesh * mesh, Object * ob ) } } +/* + * before trying to convert NMesh data back to mesh, verify that the + * lists contain the right type of data + */ + +static int check_NMeshLists( BPy_NMesh *nmesh ) +{ + int i; + + if( !PySequence_Check( nmesh->verts ) ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "nmesh verts are not a sequence" ); + if( !PySequence_Check( nmesh->edges ) ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "nmesh edges are not a sequence" ); + if( !PySequence_Check( nmesh->faces ) ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "nmesh faces are not a sequence" ); + if( !PySequence_Check( nmesh->materials ) ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "nmesh materials are not a sequence" ); + + if( EXPP_check_sequence_consistency( nmesh->verts, &NMVert_Type ) != 1 ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "nmesh vertices must be NMVerts" ); + if( EXPP_check_sequence_consistency( nmesh->edges, &NMEdge_Type ) != 1 ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "nmesh edges must be NMEdges" ); + if( EXPP_check_sequence_consistency( nmesh->faces, &NMFace_Type ) != 1 ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "nmesh faces must be NMFaces" ); + for( i = 0 ; i < PySequence_Length(nmesh->faces); ++i ) { + int j, err=0; + PyObject *col, *v, *uv; + BPy_NMFace *face=(BPy_NMFace *)PySequence_GetItem(nmesh->faces, i); + + col = face->col; + uv = face->uv; + v = face->v; + Py_DECREF( face ); + if( EXPP_check_sequence_consistency( face->col, &NMCol_Type ) != 1 ) { + return EXPP_ReturnIntError( PyExc_AttributeError, + "nmesh face col must be NMCols" ); + } + if( EXPP_check_sequence_consistency( face->v, &NMVert_Type ) != 1 ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "nmesh face v must be NMVerts" ); + + for( j = 0 ; !err && j < PySequence_Length( face->uv ); ++j ) { + PyObject *uv = PySequence_GetItem( face->uv, j); + if( PySequence_Check(uv) && PySequence_Length(uv) == 2 ) { + PyObject *p1 = PySequence_GetItem(uv, 0); + PyObject *p2 = PySequence_GetItem(uv, 1); + if( !PyNumber_Check(p1) || !PyNumber_Check(p2) ) + err = 1; + Py_DECREF( p1 ); + Py_DECREF( p2 ); + } + else { + err = 1; + } + + Py_DECREF( uv ); + } + if( err ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "nmesh face uv must contain sequence of 2 floats" ); + } + return 0; +} + /*****************************/ /* Mesh Color Object */ @@ -602,7 +673,7 @@ static int NMFace_setattr( PyObject * self, char *name, PyObject * v ) if( strcmp( name, "v" ) == 0 ) { - if( PyList_Check( v ) ) { + if( PySequence_Check( v ) ) { Py_DECREF( mf->v ); mf->v = EXPP_incr_ret( v ); @@ -610,7 +681,7 @@ static int NMFace_setattr( PyObject * self, char *name, PyObject * v ) } } else if( strcmp( name, "col" ) == 0 ) { - if( PyList_Check( v ) ) { + if( PySequence_Check( v ) ) { Py_DECREF( mf->col ); mf->col = EXPP_incr_ret( v ); @@ -642,7 +713,7 @@ static int NMFace_setattr( PyObject * self, char *name, PyObject * v ) } else if( strcmp( name, "uv" ) == 0 ) { - if( PyList_Check( v ) ) { + if( PySequence_Check( v ) ) { Py_DECREF( mf->uv ); mf->uv = EXPP_incr_ret( v ); @@ -1327,6 +1398,9 @@ static PyObject *NMesh_update( PyObject *self, PyObject *a, PyObject *kwd ) return EXPP_ReturnPyObjError( PyExc_AttributeError, "expected nothing or one to three bool(s) (0 or 1) as argument" ); + if( check_NMeshLists( nmesh ) ) + return NULL; + if( mesh ) { old_totvert = mesh->totvert; unlink_existingMeshData( mesh ); @@ -1767,7 +1841,7 @@ static int NMesh_setattr( PyObject * self, char *name, PyObject * v ) else if( !strcmp( name, "verts" ) || !strcmp( name, "faces" ) || !strcmp( name, "materials" ) ) { - if( PyList_Check( v ) ) { + if( PySequence_Check( v ) ) { if( strcmp( name, "materials" ) == 0 ) { Py_DECREF( me->materials ); @@ -2988,6 +3062,10 @@ static int convert_NMeshToMesh( Mesh * mesh, BPy_NMesh * nmesh) mesh->subdiv = nmesh->subdiv[0]; mesh->subdivr = nmesh->subdiv[1]; + + + + /*@ material assignment moved to PutRaw */ mesh->totvert = PySequence_Length( nmesh->verts ); if( mesh->totvert ) { @@ -3144,24 +3222,8 @@ static PyObject *M_NMesh_PutRaw( PyObject * self, PyObject * args ) return EXPP_ReturnPyObjError( PyExc_AttributeError, "expected an NMesh object and optionally also a string and two ints" ); - if( !PySequence_Check( nmesh->verts ) ) - return EXPP_ReturnPyObjError( PyExc_AttributeError, - "nmesh vertices are not a sequence" ); - if( !PySequence_Check( nmesh->faces ) ) - return EXPP_ReturnPyObjError( PyExc_AttributeError, - "nmesh faces are not a sequence" ); - if( !PySequence_Check( nmesh->materials ) ) - return EXPP_ReturnPyObjError( PyExc_AttributeError, - "nmesh materials are not a sequence" ); - - if( EXPP_check_sequence_consistency( nmesh->verts, &NMVert_Type ) != - 1 ) - return EXPP_ReturnPyObjError( PyExc_AttributeError, - "nmesh vertices must be NMVerts" ); - if( EXPP_check_sequence_consistency( nmesh->faces, &NMFace_Type ) != - 1 ) - return EXPP_ReturnPyObjError( PyExc_AttributeError, - "nmesh faces must be NMFaces" ); + if( check_NMeshLists( nmesh ) ) + return NULL; if( name ) mesh = ( Mesh * ) GetIdFromList( &( G.main->mesh ), name );