adding ed.key and face.edge_keys

avoids a lot of boiler place code in scripts that need to build connectivity.
This commit is contained in:
Campbell Barton
2006-12-16 23:46:43 +00:00
parent a9447e4273
commit 47ee194922
2 changed files with 139 additions and 2 deletions

View File

@@ -2223,7 +2223,7 @@ static PyObject *MEdge_getIndex( BPy_MEdge * self )
}
/*
* get an edge's select state
* get an edge's flag
*/
static PyObject *MEdge_getMFlagBits( BPy_MEdge * self, void * type )
@@ -2237,7 +2237,7 @@ static PyObject *MEdge_getMFlagBits( BPy_MEdge * self, void * type )
}
/*
* get an edge's select state
* get an edge's length
*/
static PyObject *MEdge_getLength( BPy_MEdge * self )
@@ -2262,6 +2262,24 @@ static PyObject *MEdge_getLength( BPy_MEdge * self )
return PyFloat_FromDouble( sqrt( dot ) );
}
/*
* get an key for using in a dictionary or set key
*/
static PyObject *MEdge_getKey( BPy_MEdge * self )
{
MEdge *edge = MEdge_get_pointer( self );
PyObject *attr = PyTuple_New( 2 );
if (edge->v1 > edge->v2) {
PyTuple_SetItem( attr, 0, PyInt_FromLong(edge->v2) );
PyTuple_SetItem( attr, 1, PyInt_FromLong(edge->v1) );
} else {
PyTuple_SetItem( attr, 0, PyInt_FromLong(edge->v1) );
PyTuple_SetItem( attr, 1, PyInt_FromLong(edge->v2) );
}
return attr;
}
/*
* set an edge's select state
*/
@@ -2335,6 +2353,10 @@ static PyGetSetDef BPy_MEdge_getseters[] = {
{"length",
(getter)MEdge_getLength, (setter)NULL,
"edge's length, read only",
NULL},
{"key",
(getter)MEdge_getKey, (setter)NULL,
"edge's key for using with sets or dictionaries, read only",
NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */
};
@@ -4150,6 +4172,95 @@ static int MFace_setCol( BPy_MFace * self, PyObject *value )
return 0;
}
/*
* get edge keys for using in a dictionary or set key
*/
static PyObject *MFace_getEdgeKeys( BPy_MFace * self )
{
MFace *face = MFace_get_pointer( self );
PyObject *attr, *edpair;
if (face->v4) {
attr = PyTuple_New( 4 );
edpair = PyTuple_New( 2 );
if (face->v1 > face->v2) {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v2) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v1) );
} else {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v1) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v2) );
}
PyTuple_SetItem( attr, 0, edpair );
edpair = PyTuple_New( 2 );
if (face->v2 > face->v3) {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v3) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v2) );
} else {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v2) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v3) );
}
PyTuple_SetItem( attr, 1, edpair );
edpair = PyTuple_New( 2 );
if (face->v3 > face->v4) {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v4) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v3) );
} else {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v3) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v4) );
}
PyTuple_SetItem( attr, 2, edpair );
edpair = PyTuple_New( 2 );
if (face->v4 > face->v1) {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v1) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v4) );
} else {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v4) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v1) );
}
PyTuple_SetItem( attr, 3, edpair );
} else {
attr = PyTuple_New( 3 );
edpair = PyTuple_New( 2 );
if (face->v1 > face->v2) {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v2) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v1) );
} else {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v1) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v2) );
}
PyTuple_SetItem( attr, 0, edpair );
edpair = PyTuple_New( 2 );
if (face->v2 > face->v3) {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v3) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v2) );
} else {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v2) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v3) );
}
PyTuple_SetItem( attr, 1, edpair );
edpair = PyTuple_New( 2 );
if (face->v3 > face->v1) {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v1) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v3) );
} else {
PyTuple_SetItem( edpair, 0, PyInt_FromLong(face->v3) );
PyTuple_SetItem( edpair, 1, PyInt_FromLong(face->v1) );
}
PyTuple_SetItem( attr, 2, edpair );
}
return attr;
}
/************************************************************************
*
* Python MFace_Type attributes get/set structure
@@ -4228,6 +4339,10 @@ static PyGetSetDef BPy_MFace_getseters[] = {
{"uvSel",
(getter)MFace_getUVSel, (setter)MFace_setUVSel,
"face's UV coordinates select status",
NULL},
{"edge_keys",
(getter)MFace_getEdgeKeys, (setter)NULL,
"for each edge this face uses return an ordered tuple edge pair that can be used as a key in a dictionary or set",
NULL},
{NULL,NULL,NULL,NULL,NULL} /* Sentinel */

View File

@@ -381,6 +381,10 @@ class MEdge:
changing the select state of an edge changes the select state of the edge's
vertices.
@type sel: int
@ivar key: The edges vert indicies in an ordered tuple, this can be used as a dictionary key. Read-only.
This is the same as (min(ed.v1.index, ed.v2.index), max(ed.v1.index, ed.v2.index))
@type key: typle
"""
def __iter__():
@@ -576,6 +580,24 @@ class MFace:
@type cent: vector
@ivar area: The area of the face. Read-only.
@type area: float
@ivar edge_keys: A tuple, each item a key that can reference an edge by its ordered indicies. Read-only.
This is usefull for building connectivity data
Example::
from Blender import Mesh
me = Mesh.Get('Cube')
# a dictionary where the edge is the key, and a list of faces that use it are the value
edge_faces = dict([(ed.key, []) for ed in me.edges])
# Add the faces to the dict
for f in me.faces:
for key in f.edge_keys:
edge_faces[key].append(f) # add this face to the edge as a user
# Print the edges and the number of face users
for key, face_users in edge_faces.iteritems():
print 'Edge:', key, 'uses:', len(face_users),'faces'
@type edge_keys: tuple
@note: there are regular faces and textured faces in Blender, both currently
with their own selection and visibility states, due to a mix of old and new
code. To (un)select or (un)hide regular faces (visible in EditMode), use