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:
Diffstat (limited to 'source/blender/python/api2_2x/Mesh.c')
-rw-r--r--source/blender/python/api2_2x/Mesh.c478
1 files changed, 348 insertions, 130 deletions
diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c
index 0bb882a046c..91b86947a83 100644
--- a/source/blender/python/api2_2x/Mesh.c
+++ b/source/blender/python/api2_2x/Mesh.c
@@ -82,8 +82,6 @@
#include "constant.h"
#include "gen_utils.h"
-#define MESH_TOOLS /* add access to mesh tools */
-
/* EXPP Mesh defines */
#define MESH_SMOOTHRESH 30
@@ -126,6 +124,7 @@ typedef struct SrchEdges {
typedef struct SrchFaces {
unsigned int v[4]; /* indices for verts */
+ unsigned int index; /* index in original param list of this edge */
unsigned char order; /* order of original verts, bitpacked */
} SrchFaces;
@@ -156,6 +155,22 @@ int medge_comp( const void *va, const void *vb )
}
/*
+ * compare edges by insert list indices
+ */
+
+int medge_index_comp( const void *va, const void *vb )
+{
+ const SrchEdges *a = (SrchEdges *)va;
+ const SrchEdges *b = (SrchEdges *)vb;
+
+ /* compare list indices for differences */
+
+ if (a->index < b->index) return -1;
+ else return (a->index > b->index);
+}
+
+
+/*
* compare faces by vertex indices
*/
@@ -191,6 +206,23 @@ int mface_comp( const void *va, const void *vb )
}
/*
+ * compare faces by insert list indices
+ */
+
+int mface_index_comp( const void *va, const void *vb )
+{
+ const SrchFaces *a = va;
+ const SrchFaces *b = vb;
+
+ /* compare indices, first to last, for differences */
+ if( a->index < b->index )
+ return -1;
+ if( a->index > b->index )
+ return 1;
+ return 0;
+}
+
+/*
* compare edges by vertex indices
*/
@@ -1386,7 +1418,7 @@ static PyObject *MVertSeq_item( BPy_MVertSeq * self, int i )
"array index out of range" );
return MVert_CreatePyObject( self->mesh, i );
-};
+}
/*
* retrieve a slice of the vertex list (as a Python list)
@@ -1453,7 +1485,7 @@ static int MVertSeq_assign_item( BPy_MVertSeq * self, int i,
memcpy( dst, src, sizeof(MVert) );
// mesh_update( self->mesh );
return 0;
-};
+}
static int MVertSeq_assign_slice( BPy_MVertSeq *self, int low, int high,
PyObject *args )
@@ -1566,39 +1598,42 @@ static PyObject *MVertSeq_extend( BPy_MVertSeq * self, PyObject *args )
Mesh *mesh = self->mesh;
/* make sure we get a sequence of tuples of something */
- switch( PySequence_Size ( args ) ) {
+ switch( PySequence_Size( args ) ) {
case 1: /* better be a list or a tuple */
tmp = PyTuple_GET_ITEM( args, 0 );
if( !VectorObject_Check ( tmp ) ) {
if( !PySequence_Check ( tmp ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected a sequence of tuple triplets" );
+ "expected a sequence of sequence triplets" );
args = tmp;
}
Py_INCREF( args ); /* so we can safely DECREF later */
break;
- case 3: /* take any three args and put into a tuple */
+ case 3:
tmp = PyTuple_GET_ITEM( args, 0 );
- if( PyTuple_Check( tmp ) ) {
- Py_INCREF( args );
- break;
- }
+ /* if first item is not a number, it's wrong */
+ if( !PyNumber_Check( tmp ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected a sequence of sequence triplets" );
+
+ /* otherwise, put into a new tuple */
args = Py_BuildValue( "((OOO))", tmp,
PyTuple_GET_ITEM( args, 1 ), PyTuple_GET_ITEM( args, 2 ) );
if( !args )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Py_BuildValue() failed" );
break;
+
default: /* anything else is definitely wrong */
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected a sequence of tuple triplets" );
+ "expected a sequence of sequence triplets" );
}
+ /* if no verts given, return quietly */
len = PySequence_Size( args );
if( len == 0 ) {
Py_DECREF ( args );
- return EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected at least one tuple" );
+ Py_RETURN_NONE;
}
newlen = mesh->totvert + len;
@@ -1620,18 +1655,19 @@ static PyObject *MVertSeq_extend( BPy_MVertSeq * self, PyObject *args )
}
for( j = 0; j < 3; ++j )
co[j] = ((VectorObject *)tmp)->vec[j];
- } else if( PyTuple_Check( tmp ) ) {
+ } else if( PySequence_Check( tmp ) ) {
int ok=1;
PyObject *flt;
- if( PyTuple_Size( tmp ) != 3 )
+ if( PySequence_Size( tmp ) != 3 )
ok = 0;
else
for( j = 0; ok && j < 3; ++j ) {
- flt = PyTuple_GET_ITEM( tmp, j );
+ flt = PySequence_ITEM( tmp, j );
if( !PyNumber_Check ( flt ) )
ok = 0;
else
co[j] = (float)PyFloat_AsDouble( flt );
+ Py_DECREF( flt );
}
if( !ok ) {
@@ -1639,9 +1675,16 @@ static PyObject *MVertSeq_extend( BPy_MVertSeq * self, PyObject *args )
Py_DECREF ( args );
Py_DECREF ( tmp );
return EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected tuple triplet of floats" );
+ "expected sequence triplet of floats" );
}
+ } else {
+ MEM_freeN( newvert );
+ Py_DECREF ( args );
+ Py_DECREF ( tmp );
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "expected sequence triplet of floats" );
}
+
Py_DECREF ( tmp );
/* add the coordinate to the new list */
@@ -1714,7 +1757,7 @@ static PyObject *MVertSeq_extend( BPy_MVertSeq * self, PyObject *args )
mesh_update( mesh );
Py_DECREF ( args );
- return EXPP_incr_ret( Py_None );
+ Py_RETURN_NONE;
}
static PyObject *MVertSeq_delete( BPy_MVertSeq * self, PyObject *args )
@@ -1725,15 +1768,20 @@ static PyObject *MVertSeq_delete( BPy_MVertSeq * self, PyObject *args )
Mesh *mesh = self->mesh;
MFace *tmpface;
- Py_INCREF( args ); /* so we can safely DECREF later */
-
- /* accept a sequence (lists or tuples) also */
+ /*
+ * if input tuple contains a single sequence, use it as input instead;
+ * otherwise use the sequence as-is and check later that it contains
+ * one or more integers or MVerts
+ */
if( PySequence_Size( args ) == 1 ) {
PyObject *tmp = PyTuple_GET_ITEM( args, 0 );
- if( PySequence_Check ( tmp ) ) {
- Py_DECREF( args ); /* release previous reference */
- args = tmp; /* PyTuple_GET_ITEM returns new ref */
- }
+ if( PySequence_Check( tmp ) )
+ args = tmp;
+ }
+
+ /* if sequence is empty, do nothing */
+ if( PySequence_Size( args ) == 0 ) {
+ Py_RETURN_NONE;
}
/* allocate vertex lookup table */
@@ -1747,18 +1795,15 @@ static PyObject *MVertSeq_delete( BPy_MVertSeq * self, PyObject *args )
if( BPy_MVert_Check( tmp ) ) {
if( (void *)self->mesh != ((BPy_MVert*)tmp)->data ) {
MEM_freeN( vert_table );
- Py_DECREF( args );
Py_DECREF( tmp );
return EXPP_ReturnPyObjError( PyExc_ValueError,
"MVert belongs to a different mesh" );
}
index = ((BPy_MVert*)tmp)->index;
- }
- else if( PyInt_CheckExact( tmp ) )
+ } else if( PyInt_CheckExact( tmp ) ) {
index = PyInt_AsLong ( tmp );
- else {
+ } else {
MEM_freeN( vert_table );
- Py_DECREF( args );
Py_DECREF( tmp );
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a sequence of ints or MVerts" );
@@ -1766,8 +1811,7 @@ static PyObject *MVertSeq_delete( BPy_MVertSeq * self, PyObject *args )
Py_DECREF( tmp );
if( index < 0 || index >= mesh->totvert ) {
MEM_freeN( vert_table );
- Py_DECREF( args );
- return EXPP_ReturnPyObjError( PyExc_ValueError,
+ return EXPP_ReturnPyObjError( PyExc_IndexError,
"array index out of range" );
}
vert_table[index] = UINT_MAX;
@@ -1802,8 +1846,7 @@ static PyObject *MVertSeq_delete( BPy_MVertSeq * self, PyObject *args )
/* clean up and exit */
MEM_freeN( vert_table );
mesh_update ( mesh );
- Py_DECREF( args );
- return EXPP_incr_ret( Py_None );
+ Py_RETURN_NONE;
}
static PyObject *MVertSeq_selected( BPy_MVertSeq * self )
@@ -2413,40 +2456,52 @@ static PyObject *MEdgeSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
MEdge *tmpedge;
Mesh *mesh = self->mesh;
- /* make sure we get a sequence of tuples of something */
-
- switch( PySequence_Size ( args ) ) {
- case 1: /* better be a list or a tuple */
- args = PyTuple_GET_ITEM( args, 0 );
- if( !PySequence_Check ( args ) )
+ /* make sure we get a tuple of sequences of something */
+ switch( PySequence_Size( args ) ) {
+ case 1:
+ /* if a sequence... */
+ tmp = PyTuple_GET_ITEM( args, 0 );
+ if( PySequence_Check( tmp ) ) {
+ /* if another sequence, use it */
+ PyObject *tmp2 = PySequence_ITEM( tmp, 0 );
+ if( PySequence_Check( tmp2 ) )
+ args = tmp;
+ Py_INCREF( args );
+ Py_DECREF( tmp2 );
+ } else
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected a sequence of tuple pairs" );
- Py_INCREF( args ); /* so we can safely DECREF later */
+ "expected a sequence of sequence pairs" );
break;
case 2:
case 3:
case 4: /* two to four args may be individual verts */
tmp = PyTuple_GET_ITEM( args, 0 );
- if( PyTuple_Check( tmp ) ) {/* maybe just tuples, so use args as-is */
+ /*
+ * if first item isn't a sequence, then assume it's a bunch of MVerts
+ * and wrap inside a tuple
+ */
+ if( !PySequence_Check( tmp ) ) {
+ args = Py_BuildValue( "(O)", args );
+ if( !args )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "Py_BuildValue() failed" );
+ /*
+ * otherwise, assume it already a bunch of sequences so use as-is
+ */
+ } else {
Py_INCREF( args ); /* so we can safely DECREF later */
- break;
}
- args = Py_BuildValue( "(O)", args );
- if( !args )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "Py_BuildValue() failed" );
break;
default: /* anything else is definitely wrong */
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected a sequence of tuple pairs" );
+ "expected a sequence of sequence pairs" );
}
/* make sure there is something to add */
len = PySequence_Size( args );
if( len == 0 ) {
- Py_DECREF( args );
- return EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected at least one tuple" );
+ Py_DECREF ( args );
+ Py_RETURN_NONE;
}
/* verify the param list and get a total count of number of edges */
@@ -2455,21 +2510,21 @@ static PyObject *MEdgeSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
tmp = PySequence_GetItem( args, i );
/* not a tuple of MVerts... error */
- if( !PyTuple_Check( tmp ) ||
+ if( !PySequence_Check( tmp ) ||
EXPP_check_sequence_consistency( tmp, &MVert_Type ) != 1 ) {
Py_DECREF( tmp );
Py_DECREF( args );
return EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected sequence of MVert tuples" );
+ "expected sequence of MVert sequences" );
}
/* not the right number of MVerts... error */
- nverts = PyTuple_Size( tmp );
+ nverts = PySequence_Size( tmp );
if( nverts < 2 || nverts > 4 ) {
Py_DECREF( tmp );
Py_DECREF( args );
return EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected 2 to 4 MVerts per tuple" );
+ "expected 2 to 4 MVerts per sequence" );
}
Py_DECREF( tmp );
@@ -2486,14 +2541,15 @@ static PyObject *MEdgeSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
/* scan the input list and build the new edge pair list */
len = PySequence_Size( args );
tmppair = newpair;
+ new_edge_count = 0;
for( i = 0; i < len; ++i ) {
int edge_count;
tmp = PySequence_GetItem( args, i );
- nverts = PyTuple_Size( tmp );
+ nverts = PySequence_Size( tmp );
- /* get copies of vertices */
+ /* get new references for the vertices */
for(j = 0; j < nverts; ++j )
- e[j] = (BPy_MVert *)PyTuple_GET_ITEM( tmp, j );
+ e[j] = (BPy_MVert *)PySequence_GetItem( tmp, j );
Py_DECREF( tmp );
if( nverts == 2 )
@@ -2518,12 +2574,20 @@ static PyObject *MEdgeSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
tmppair->swap = 1;
} else {
MEM_freeN( newpair );
+ for(j = 0; j < nverts; ++j )
+ Py_DECREF( e[j] );
Py_DECREF( args );
return EXPP_ReturnPyObjError( PyExc_ValueError,
"tuple contains duplicate vertices" );
}
+ tmppair->index = new_edge_count;
+ ++new_edge_count;
tmppair++;
}
+
+ /* free the new references */
+ for( j = 0; j < nverts; ++j )
+ Py_DECREF( e[j] );
}
/* sort the new edge pairs */
@@ -2605,6 +2669,9 @@ static PyObject *MEdgeSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
}
mesh->medge = tmpedge; /* point to the new edge list */
+ /* resort edges into original order */
+ qsort( newpair, new_edge_count, sizeof(SrchEdges), medge_index_comp );
+
/* point to the first edge we're going to add */
tmpedge = &mesh->medge[mesh->totedge];
tmppair = newpair;
@@ -2632,7 +2699,7 @@ static PyObject *MEdgeSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
mesh_update( mesh );
MEM_freeN( newpair );
Py_DECREF ( args );
- return EXPP_incr_ret( Py_None );
+ Py_RETURN_NONE;
}
static PyObject *MEdgeSeq_delete( BPy_MEdgeSeq * self, PyObject *args )
@@ -2644,19 +2711,23 @@ static PyObject *MEdgeSeq_delete( BPy_MEdgeSeq * self, PyObject *args )
int i, len;
int face_count, edge_count, vert_count;
- Py_INCREF( args ); /* so we can safely DECREF later */
-
- /* accept a sequence (lists or tuples) also */
+ /*
+ * if input tuple contains a single sequence, use it as input instead;
+ * otherwise use the sequence as-is and check later that it contains
+ * one or more integers or MVerts
+ */
if( PySequence_Size( args ) == 1 ) {
PyObject *tmp = PyTuple_GET_ITEM( args, 0 );
- if( PySequence_Check ( tmp ) ) {
- Py_DECREF( args ); /* release previous reference */
- args = tmp; /* PyTuple_GET_ITEM returns new ref */
- }
+ if( PySequence_Check( tmp ) )
+ args = tmp;
}
- /* see how many args we need to parse */
+ /* if sequence is empty, do nothing */
len = PySequence_Size( args );
+ if( len == 0 ) {
+ Py_RETURN_NONE;
+ }
+
edge_table = (unsigned int *)MEM_callocN( len*sizeof( unsigned int ),
"edge_table" );
@@ -2670,7 +2741,6 @@ static PyObject *MEdgeSeq_delete( BPy_MEdgeSeq * self, PyObject *args )
else {
MEM_freeN( edge_table );
Py_DECREF( tmp );
- Py_DECREF( args );
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a sequence of ints or MEdges" );
}
@@ -2679,7 +2749,6 @@ static PyObject *MEdgeSeq_delete( BPy_MEdgeSeq * self, PyObject *args )
/* if index out-of-range, throw exception */
if( edge_table[i] >= (unsigned int)mesh->totedge ) {
MEM_freeN( edge_table );
- Py_DECREF( args );
return EXPP_ReturnPyObjError( PyExc_ValueError,
"array index out of range" );
}
@@ -2773,9 +2842,8 @@ static PyObject *MEdgeSeq_delete( BPy_MEdgeSeq * self, PyObject *args )
MEM_freeN( del_table );
MEM_freeN( vert_table );
MEM_freeN( edge_table );
- Py_DECREF( args );
mesh_update ( mesh );
- return EXPP_incr_ret( Py_None );
+ Py_RETURN_NONE;
}
static PyObject *MEdgeSeq_selected( BPy_MEdgeSeq * self )
@@ -3388,21 +3456,22 @@ static int MFace_setUV( BPy_MFace * self, PyObject * value )
if( !MFace_get_pointer( self ) )
return -1;
- if( !PyTuple_Check( value ) ||
+ if( !PySequence_Check( value ) ||
EXPP_check_sequence_consistency( value, &vector_Type ) != 1 )
return EXPP_ReturnIntError( PyExc_TypeError,
- "expected tuple of vectors" );
+ "expected sequence of vectors" );
length = self->mesh->mface[self->index].v4 ? 4 : 3;
- if( length != PyTuple_Size( value ) )
+ if( length != PySequence_Size( value ) )
return EXPP_ReturnIntError( PyExc_TypeError,
- "size of vertex and UV lists differ" );
+ "size of vertex and UV sequences differ" );
face = &self->mesh->tface[self->index];
for( i=0; i<length; ++i ) {
- VectorObject *vector = (VectorObject *)PyTuple_GET_ITEM( value, i );
+ VectorObject *vector = (VectorObject *)PySequence_ITEM( value, i );
face->uv[i][0] = vector->vec[0];
face->uv[i][1] = vector->vec[1];
+ Py_DECREF( vector );
}
return 0;
}
@@ -3531,6 +3600,54 @@ static PyObject *MFace_getCol( BPy_MFace * self )
return attr;
}
+/*
+ * set a face's vertex colors
+ */
+
+static int MFace_setCol( BPy_MFace * self, PyObject *value )
+{
+ int length, i;
+ MCol * mcol;
+
+ /* if there's no mesh color vectors or texture faces, nothing to do */
+
+ if( !self->mesh->mcol && !self->mesh->tface )
+ return EXPP_ReturnIntError( PyExc_ValueError,
+ "face has no vertex colors" );
+
+ if( !MFace_get_pointer( self ) )
+ return -1;
+
+ if( self->mesh->tface )
+ mcol = (MCol *) self->mesh->tface[self->index].col;
+ else
+ mcol = &self->mesh->mcol[self->index*4];
+
+ length = self->mesh->mface[self->index].v4 ? 4 : 3;
+
+ if( !PyList_Check( value ) && !PyTuple_Check( value ) )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a sequence of MCols" );
+
+ if( EXPP_check_sequence_consistency( value, &MCol_Type ) != 1 )
+ return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a sequence of MCols" );
+
+ if( PySequence_Size( value ) != length )
+ return EXPP_ReturnIntError( PyExc_ValueError,
+ "incorrect number of colors for this face" );
+
+ for( i=0; i<length; ++i ) {
+ BPy_MCol *obj = (BPy_MCol *)PySequence_ITEM( value, i );
+ mcol[i].r = obj->color->r;
+ mcol[i].g = obj->color->g;
+ mcol[i].b = obj->color->b;
+ mcol[i].a = obj->color->a;
+ Py_DECREF( obj );
+ }
+ return 0;
+}
+
/************************************************************************
*
* Python MFace_Type attributes get/set structure
@@ -3575,7 +3692,7 @@ static PyGetSetDef BPy_MFace_getseters[] = {
/* attributes for texture faces (mostly, I think) */
{"col",
- (getter)MFace_getCol, (setter)NULL,
+ (getter)MFace_getCol, (setter)MFace_setCol,
"face's vertex colors",
NULL},
{"flag",
@@ -3888,43 +4005,56 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
tmp = MEdgeSeq_extend( self, args );
if( !tmp )
return NULL;
-
+
Py_DECREF( tmp );
- /* make sure we get a sequence of tuples of something */
+ /* make sure we get a tuple of sequences of something */
- switch( PySequence_Size ( args ) ) {
- case 1: /* better be a list or a tuple */
- args = PyTuple_GET_ITEM( args, 0 );
- if( !PySequence_Check ( args ) )
+ switch( PySequence_Size( args ) ) {
+ case 1: /* better be a sequence or a tuple */
+ /* if a sequence... */
+ tmp = PyTuple_GET_ITEM( args, 0 );
+ if( PySequence_Check( tmp ) ) {
+ /* if another sequence, use it */
+ PyObject *tmp2 = PySequence_ITEM( tmp, 0 );
+ if( PySequence_Check( tmp2 ) )
+ args = tmp;
+ Py_INCREF( args );
+ Py_DECREF( tmp2 );
+ } else
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected a sequence of tuple pairs" );
- Py_INCREF( args ); /* so we can safely DECREF later */
+ "expected a sequence of sequence pairs" );
break;
case 2:
case 3:
case 4: /* two to four args may be individual verts */
tmp = PyTuple_GET_ITEM( args, 0 );
- if( PyTuple_Check( tmp ) ) {/* maybe just tuples, so use args as-is */
+ /*
+ * if first item isn't a sequence, then assume it's a bunch of MVerts
+ * and wrap inside a tuple
+ */
+ if( !PySequence_Check( tmp ) ) {
+ args = Py_BuildValue( "(O)", args );
+ if( !args )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "Py_BuildValue() failed" );
+ /*
+ * otherwise, assume it already a bunch of sequences so use as-is
+ */
+ } else {
Py_INCREF( args ); /* so we can safely DECREF later */
- break;
}
- args = Py_BuildValue( "(O)", args );
- if( !args )
- return EXPP_ReturnPyObjError( PyExc_RuntimeError,
- "Py_BuildValue() failed" );
break;
default: /* anything else is definitely wrong */
return EXPP_ReturnPyObjError( PyExc_TypeError,
- "expected a sequence of tuple pairs" );
+ "expected a sequence of sequence pairs" );
}
- /* make sure there is something to add */
+ /* if nothing to add, just exit */
len = PySequence_Size( args );
if( len == 0 ) {
Py_DECREF( args );
- return EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected at least one tuple" );
+ Py_RETURN_NONE;
}
/* verify the param list and get a total count of number of edges */
@@ -3933,19 +4063,19 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
tmp = PySequence_GetItem( args, i );
/* not a tuple of MVerts... error */
- if( !PyTuple_Check( tmp ) ||
+ if( !PySequence_Check( tmp ) ||
EXPP_check_sequence_consistency( tmp, &MVert_Type ) != 1 ) {
Py_DECREF( args );
return EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected sequence of MVert tuples" );
+ "expected sequence of MVert sequences" );
}
/* not the right number of MVerts... error */
- nverts = PyTuple_Size( tmp );
+ nverts = PySequence_Size( tmp );
if( nverts < 2 || nverts > 4 ) {
Py_DECREF( args );
return EXPP_ReturnPyObjError( PyExc_ValueError,
- "expected 2 to 4 MVerts per tuple" );
+ "expected 2 to 4 MVerts per sequence" );
}
if( nverts != 2 ) /* new faces cannot have only 2 verts */
@@ -3965,7 +4095,7 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
unsigned int vert[4]={0,0,0,0};
unsigned char order[4]={0,1,2,3};
tmp = PySequence_GetItem( args, i );
- nverts = PyTuple_Size( tmp );
+ nverts = PySequence_Size( tmp );
if( nverts == 2 ) /* again, ignore 2-vert tuples */
break;
@@ -3975,15 +4105,19 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
* vertices are not index 0
*/
- e = (BPy_MVert *)PyTuple_GET_ITEM( tmp, 0 );
+ e = (BPy_MVert *)PySequence_ITEM( tmp, 0 );
tmpface.v1 = e->index;
- e = (BPy_MVert *)PyTuple_GET_ITEM( tmp, 1 );
+ Py_DECREF( e );
+ e = (BPy_MVert *)PySequence_ITEM( tmp, 1 );
tmpface.v2 = e->index;
- e = (BPy_MVert *)PyTuple_GET_ITEM( tmp, 2 );
+ Py_DECREF( e );
+ e = (BPy_MVert *)PySequence_ITEM( tmp, 2 );
tmpface.v3 = e->index;
+ Py_DECREF( e );
if( nverts == 4 ) {
- e = (BPy_MVert *)PyTuple_GET_ITEM( tmp, 3 );
+ e = (BPy_MVert *)PySequence_ITEM( tmp, 3 );
tmpface.v4 = e->index;
+ Py_DECREF( e );
}
Py_DECREF( tmp );
@@ -4016,6 +4150,7 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
}
tmppair->v[j] = vert[j];
}
+ tmppair->index = i;
/* pack order into a byte */
tmppair->order = order[0]|(order[1]<<2)|(order[2]<<4)|(order[3]<<6);
@@ -4111,6 +4246,9 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
mesh->tface = tmptface;
}
+ /* sort the faces back into their original input list order */
+ qsort( newpair, new_face_count, sizeof(SrchFaces), mface_index_comp );
+
/* allocate new face list */
tmpface = MEM_callocN(totface*sizeof(MFace), "Mesh_addFaces");
@@ -4157,7 +4295,7 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
mesh_update( mesh );
Py_DECREF ( args );
MEM_freeN( newpair );
- return EXPP_incr_ret( Py_None );
+ Py_RETURN_NONE;
}
struct fourEdges
@@ -4196,7 +4334,7 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
if( BPy_MFace_Check( tmp ) )
face_table[i] = ((BPy_MFace *)tmp)->index;
else if( PyInt_CheckExact( tmp ) )
- face_table[i] = PyInt_AsLong ( tmp );
+ face_table[i] = PyInt_AsLong( tmp );
else {
MEM_freeN( face_table );
Py_DECREF( tmp );
@@ -4276,7 +4414,7 @@ static PyObject *MFaceSeq_delete( BPy_MFaceSeq * self, PyObject *args )
verts[0] = tmpface->v1;
verts[1] = tmpface->v2;
verts[2] = tmpface->v3;
- if(len == 4)
+ if( len == 4 )
verts[3] = tmpface->v4;
for( j = 0; j < len; ++j ) {
k = (j+1) % len;
@@ -5373,7 +5511,53 @@ static PyObject *Mesh_getVertGroupNames( BPy_Mesh * self )
return list;
}
-#ifdef MESH_TOOLS
+static PyObject *Mesh_getVertexInfluences( BPy_Mesh * self, PyObject * args )
+{
+ int index;
+ PyObject *influence_list = NULL;
+ Object *object = self->object;
+ Mesh *me = self->mesh;
+
+ /* Get a reference to the mesh object wrapped in here. */
+ if( !object )
+ return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+ "This mesh must be linked to an object" );
+
+ /* Parse the parameters: only on integer (vertex index) */
+ if( !PyArg_ParseTuple( args, "i", &index ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected int argument (index of the vertex)" );
+
+ /* check for valid index */
+ if( index < 0 || index >= me->totvert )
+ return EXPP_ReturnPyObjError( PyExc_IndexError,
+ "vertex index out of range" );
+
+ influence_list = PyList_New( 0 );
+
+ /* Proceed only if we have vertex deformation information */
+ if( me->dvert ) {
+ int i;
+ MDeformWeight *sweight = NULL;
+
+ /* Number of bones influencing the vertex */
+ int totinfluences = me->dvert[index].totweight;
+
+ /* Get the reference of the first weight structure */
+ sweight = me->dvert[index].dw;
+
+ /* Build the list only with weights and names of the influent bones */
+ for( i = 0; i < totinfluences; i++, sweight++ ) {
+ bDeformGroup *defgroup = BLI_findlink( &object->defbase,
+ sweight->def_nr );
+ if( defgroup )
+ PyList_Append( influence_list, Py_BuildValue( "[sf]",
+ defgroup->name, sweight->weight ) );
+ }
+ }
+
+ return influence_list;
+}
static PyObject *Mesh_Tools( BPy_Mesh * self, int type, void **args )
{
@@ -5575,8 +5759,6 @@ static PyObject *Mesh_fill( BPy_Mesh * self )
return Mesh_Tools( self, MESH_TOOL_FILL, NULL );
}
-#endif
-
static struct PyMethodDef BPy_Mesh_methods[] = {
{"calcNormals", (PyCFunction)Mesh_calcNormals, METH_NOARGS,
"all recalculate vertex normals"},
@@ -5604,10 +5786,10 @@ static struct PyMethodDef BPy_Mesh_methods[] = {
"Rename an existing vertex group"},
{"getVertGroupNames", (PyCFunction)Mesh_getVertGroupNames, METH_NOARGS,
"Get names of vertex groups"},
+ {"getVertexInfluences", (PyCFunction)Mesh_getVertexInfluences, METH_VARARGS,
+ "Get list of the influences of bones for a given mesh vertex"},
-
-
-#ifdef MESH_TOOLS
+ /* Mesh tools */
{"smooth", (PyCFunction)Mesh_smooth, METH_NOARGS,
"Flattens angle of selected faces (experimental)"},
{"flipNormals", (PyCFunction)Mesh_flipNormals, METH_NOARGS,
@@ -5626,7 +5808,6 @@ static struct PyMethodDef BPy_Mesh_methods[] = {
"Removes duplicates from selected vertices (experimental)"},
{"recalcNormals", (PyCFunction)Mesh_recalcNormals, METH_VARARGS,
"Recalculates inside or outside normals (experimental)"},
-#endif
{NULL, NULL, 0, NULL}
};
@@ -5906,8 +6087,12 @@ static int Mesh_setFlag( BPy_Mesh * self, PyObject *value, void *type )
MEM_freeN( mesh->tface );
mesh->tface = NULL;
}
- } else if( !mesh->tface )
+ } else if( !mesh->tface ) {
+ if( !mesh->totface )
+ return EXPP_ReturnIntError( PyExc_RuntimeError,
+ "mesh has no faces" );
make_tfaces( mesh );
+ }
return 0;
case MESH_HASMCOL:
if( !param ) {
@@ -6098,8 +6283,6 @@ static PyGetSetDef BPy_Mesh_getseters[] = {
(getter)Mesh_getMode, (setter)Mesh_setMode,
"The mesh's mode bitfield",
NULL},
-
-
{"faceUV",
(getter)Mesh_getFlag, (setter)Mesh_setFlag,
"UV-mapped textured faces enabled",
@@ -6125,11 +6308,6 @@ static PyGetSetDef BPy_Mesh_getseters[] = {
};
/*****************************************************************************/
-/* Python Mesh_Type callback function prototypes: */
-/*****************************************************************************/
-static void Mesh_dealloc( BPy_Mesh * object );
-
-/*****************************************************************************/
/* Python Mesh_Type structure definition: */
/*****************************************************************************/
PyTypeObject Mesh_Type = {
@@ -6329,6 +6507,28 @@ static PyObject *M_Mesh_MVert( PyObject * self, PyObject * args )
return PVert_CreatePyObject( &vert );
}
+static PyObject *M_Mesh_Modes( PyObject * self, PyObject * args )
+{
+ int modes = 0;
+
+ if( !G.scene ) {
+ Py_RETURN_NONE;
+ }
+
+ if( !PyArg_ParseTuple( args, "|i", &modes ) )
+ return EXPP_ReturnPyObjError( PyExc_TypeError,
+ "expected optional int as argument" );
+
+ if( modes > ( SCE_SELECT_VERTEX | SCE_SELECT_EDGE | SCE_SELECT_FACE ) )
+ return EXPP_ReturnPyObjError( PyExc_ValueError,
+ "value out of range" );
+
+ if( modes > 0 )
+ G.scene->selectmode = modes;
+
+ return PyInt_FromLong( G.scene->selectmode );
+}
+
static struct PyMethodDef M_Mesh_methods[] = {
{"New", (PyCFunction)M_Mesh_New, METH_VARARGS,
"Create a new mesh"},
@@ -6336,10 +6536,12 @@ static struct PyMethodDef M_Mesh_methods[] = {
"Get a mesh by name"},
{"MVert", (PyCFunction)M_Mesh_MVert, METH_VARARGS,
"Create a new MVert"},
+ {"Mode", (PyCFunction)M_Mesh_Modes, METH_VARARGS,
+ "Get/set edit selection mode(s)"},
{NULL, NULL, 0, NULL},
};
-static PyObject *M_Mesh_Modes( void )
+static PyObject *M_Mesh_ModesDict( void )
{
PyObject *Modes = PyConstant_New( );
@@ -6444,18 +6646,32 @@ static PyObject *M_Mesh_VertAssignDict( void )
return Vert;
}
+
+static PyObject *M_Mesh_SelectModeDict( void )
+{
+ PyObject *Mode = PyConstant_New( );
+ if( Mode ) {
+ BPy_constant *d = ( BPy_constant * ) Mode;
+ PyConstant_Insert(d, "VERTEX", PyInt_FromLong(SCE_SELECT_VERTEX));
+ PyConstant_Insert(d, "EDGE", PyInt_FromLong(SCE_SELECT_EDGE));
+ PyConstant_Insert(d, "FACE", PyInt_FromLong(SCE_SELECT_FACE));
+ }
+ return Mode;
+}
+
static char M_Mesh_doc[] = "The Blender.Mesh submodule";
PyObject *Mesh_Init( void )
{
PyObject *submodule;
- PyObject *Modes = M_Mesh_Modes( );
- PyObject *FaceFlags = M_Mesh_FaceFlagsDict( );
- PyObject *FaceModes = M_Mesh_FaceModesDict( );
- PyObject *FaceTranspModes = M_Mesh_FaceTranspModesDict( );
+ PyObject *Modes = M_Mesh_ModesDict( );
+ PyObject *FaceFlags = M_Mesh_FaceFlagsDict( );
+ PyObject *FaceModes = M_Mesh_FaceModesDict( );
+ PyObject *FaceTranspModes = M_Mesh_FaceTranspModesDict( );
PyObject *EdgeFlags = M_Mesh_EdgeFlagsDict( );
- PyObject *AssignModes = M_Mesh_VertAssignDict( );
+ PyObject *AssignModes = M_Mesh_VertAssignDict( );
+ PyObject *SelectModes = M_Mesh_SelectModeDict( );
if( PyType_Ready( &MCol_Type ) < 0 )
return NULL;
@@ -6491,6 +6707,8 @@ PyObject *Mesh_Init( void )
PyModule_AddObject( submodule, "EdgeFlags", EdgeFlags );
if( AssignModes )
PyModule_AddObject( submodule, "AssignModes", AssignModes );
+ if( SelectModes )
+ PyModule_AddObject( submodule, "SelectModes", SelectModes );
return submodule;