[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44317] trunk/blender/source/blender/ python: bmesh py api - generalize bmesg sequences to use the iterator type and optionally another bmesh element .

Campbell Barton ideasman42 at gmail.com
Wed Feb 22 11:41:13 CET 2012


Revision: 44317
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44317
Author:   campbellbarton
Date:     2012-02-22 10:41:07 +0000 (Wed, 22 Feb 2012)
Log Message:
-----------
bmesh py api - generalize bmesg sequences to use the iterator type and optionally another bmesh element.

This allows BMFace.verts to be added without defining a new sequence type.

Modified Paths:
--------------
    trunk/blender/source/blender/python/bmesh/bmesh_py_api.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_types.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_types.h
    trunk/blender/source/blender/python/intern/bpy_interface.c

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_api.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_api.c	2012-02-22 09:19:53 UTC (rev 44316)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_api.c	2012-02-22 10:41:07 UTC (rev 44317)
@@ -75,7 +75,7 @@
 );
 static struct PyModuleDef BPy_BM_module_def = {
 	PyModuleDef_HEAD_INIT,
-	"bme",  /* m_name */
+	"bmesh",  /* m_name */
 	BPy_BM_doc,  /* m_doc */
 	0,  /* m_size */
 	BPy_BM_methods,  /* m_methods */

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_types.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_types.c	2012-02-22 09:19:53 UTC (rev 44316)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_types.c	2012-02-22 10:41:07 UTC (rev 44317)
@@ -163,33 +163,18 @@
 /* Mesh
  * ^^^^ */
 
-PyDoc_STRVAR(bpy_bmesh_verts_doc,
-"The :class:`bme.types.BMVertSeq` object this mesh"
-);
-static PyObject *bpy_bmesh_verts_get(BPy_BMesh *self)
+static PyObject *bpy_bmesh_seq_get(BPy_BMesh *self, void *itype)
 {
 	BPY_BM_CHECK_OBJ(self);
-	return BPy_BMVertSeq_CreatePyObject(self->bm);
+	return BPy_BMElemSeq_CreatePyObject(self->bm, NULL, GET_INT_FROM_POINTER(itype));
 }
 
-PyDoc_STRVAR(bpy_bmesh_edges_doc,
-"The :class:`bme.types.BMEdgeSeq` object this mesh"
-);
-static PyObject *bpy_bmesh_edges_get(BPy_BMesh *self)
+static PyObject *bpy_bmesh_seq_elem_get(BPy_BMElem *self, void *itype)
 {
 	BPY_BM_CHECK_OBJ(self);
-	return BPy_BMEdgeSeq_CreatePyObject(self->bm);
+	return BPy_BMElemSeq_CreatePyObject(self->bm, self, GET_INT_FROM_POINTER(itype));
 }
 
-PyDoc_STRVAR(bpy_bmesh_faces_doc,
-"The :class:`bme.types.BMFaceSeq` object this mesh"
-);
-static PyObject *bpy_bmesh_faces_get(BPy_BMesh *self)
-{
-	BPY_BM_CHECK_OBJ(self);
-	return BPy_BMFaceSeq_CreatePyObject(self->bm);
-}
-
 PyDoc_STRVAR(bpy_bmesh_select_mode_doc,
 "The selection mode for this mesh"
 );
@@ -289,9 +274,9 @@
 }
 
 static PyGetSetDef bpy_bmesh_getseters[] = {
-	{(char *)"verts", (getter)bpy_bmesh_verts_get, (setter)NULL, (char *)bpy_bmesh_verts_doc, NULL},
-	{(char *)"edges", (getter)bpy_bmesh_edges_get, (setter)NULL, (char *)bpy_bmesh_edges_doc, NULL},
-	{(char *)"faces", (getter)bpy_bmesh_faces_get, (setter)NULL, (char *)bpy_bmesh_faces_doc, NULL},
+	{(char *)"verts", (getter)bpy_bmesh_seq_get, (setter)NULL, NULL, (void *)BM_VERTS_OF_MESH},
+	{(char *)"edges", (getter)bpy_bmesh_seq_get, (setter)NULL, NULL, (void *)BM_EDGES_OF_MESH},
+	{(char *)"faces", (getter)bpy_bmesh_seq_get, (setter)NULL, NULL, (void *)BM_FACES_OF_MESH},
     {(char *)"select_mode", (getter)bpy_bmesh_select_mode_get, (setter)bpy_bmesh_select_mode_set, (char *)bpy_bmesh_select_mode_doc, NULL},
 	{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
 };
@@ -332,6 +317,8 @@
 
 	{(char *)"normal", (getter)bpy_bmface_normal_get, (setter)bpy_bmface_normal_set, (char *)bpy_bmface_normal_doc, NULL},
 
+    {(char *)"verts", (getter)bpy_bmesh_seq_elem_get, (setter)NULL, NULL, (void *)BM_VERTS_OF_FACE},
+
 	{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
 };
 
@@ -548,12 +535,7 @@
 /* Vert Seq
  * -------- */
 
-PyDoc_STRVAR(bpy_bmvert_seq_new_doc,
-".. method:: new()\n"
-"\n"
-"   Create a new vertex.\n"
-);
-static PyObject *bpy_bmvert_seq_new(BPy_BMGeneric *self, PyObject *args)
+static PyObject *bpy_bmvert_seq_new(BPy_BMElemSeq *self, PyObject *args)
 {
 	PyObject *py_co = NULL;
 
@@ -586,12 +568,7 @@
 /* Edge Seq
  * -------- */
 
-PyDoc_STRVAR(bpy_bmedge_seq_new_doc,
-".. method:: new()\n"
-"\n"
-"   Create a new edge.\n"
-);
-static PyObject *bpy_bmedge_seq_new(BPy_BMGeneric *self, PyObject *args)
+static PyObject *bpy_bmedge_seq_new(BPy_BMElemSeq *self, PyObject *args)
 {
 	BPy_BMVert *v1;
     BPy_BMVert *v2;
@@ -635,15 +612,10 @@
 	}
 }
 
-/* Edge Seq
+/* Face Seq
  * -------- */
 
-PyDoc_STRVAR(bpy_bmface_seq_new_doc,
-".. method:: new()\n"
-"\n"
-"   Create a new face.\n"
-);
-static PyObject *bpy_bmface_seq_new(BPy_BMGeneric *self, PyObject *args)
+static PyObject *bpy_bmface_seq_new(BPy_BMElemSeq *self, PyObject *args)
 {
 	PyObject *vert_seq;
 
@@ -748,7 +720,26 @@
 	}
 }
 
+PyDoc_STRVAR(bpy_bm_seq_new_doc,
+".. method:: new()\n"
+"\n"
+"   Create a new vert/edge/face.\n"
+);
+static PyObject *bpy_bm_seq_new(BPy_BMElemSeq *self, PyObject *args)
+{
+	switch (self->itype) {
+		case BM_VERTS_OF_MESH:
+			return bpy_bmvert_seq_new(self, args);
+		case BM_EDGES_OF_MESH:
+			return bpy_bmedge_seq_new(self, args);
+		case BM_FACES_OF_MESH:
+			return bpy_bmface_seq_new(self, args);
+	}
 
+	PyErr_SetString(PyExc_TypeError,
+	                ".new(...): function is not valid for this sequence");
+	return NULL;
+}
 
 
 static struct PyMethodDef bpy_bmesh_methods[] = {
@@ -782,97 +773,113 @@
 	{NULL, NULL, 0, NULL}
 };
 
-static struct PyMethodDef bpy_bmvert_seq_methods[] = {
-	{"new", (PyCFunction)bpy_bmvert_seq_new, METH_VARARGS, bpy_bmvert_seq_new_doc},
+static struct PyMethodDef bpy_bm_seq_methods[] = {
+	{"new", (PyCFunction)bpy_bm_seq_new, METH_VARARGS, bpy_bm_seq_new_doc},
 	{NULL, NULL, 0, NULL}
 };
 
-static struct PyMethodDef bpy_bmedge_seq_methods[] = {
-	{"new", (PyCFunction)bpy_bmedge_seq_new, METH_VARARGS, bpy_bmedge_seq_new_doc},
-	{NULL, NULL, 0, NULL}
-};
-
-static struct PyMethodDef bpy_bmface_seq_methods[] = {
-	{"new", (PyCFunction)bpy_bmface_seq_new, METH_VARARGS, bpy_bmface_seq_new_doc},
-	{NULL, NULL, 0, NULL}
-};
-
 /* Sequences
  * ========= */
 
-static Py_ssize_t bpy_bmvert_seq_length(BPy_BMGeneric *self)
-{
-	BPY_BM_CHECK_INT(self);
-	return self->bm->totvert;
-}
-static Py_ssize_t bpy_bmedge_seq_length(BPy_BMGeneric *self)
-{
-	BPY_BM_CHECK_INT(self);
-	return self->bm->totedge;
-}
-static Py_ssize_t bpy_bmface_seq_length(BPy_BMGeneric *self)
-{
-	BPY_BM_CHECK_INT(self);
-	return self->bm->totface;
-}
+#define BM_ITER_BPY_BM_SEQ(ele, iter, bpy_bm_seq) \
+	BM_ITER(ele, iter, (bpy_bm_seq)->bm, (bpy_bm_seq)->itype,\
+	(bpy_bm_seq)->py_ele ? ((BPy_BMElem *)(bpy_bm_seq)->py_ele)->ele : NULL)
 
-static PyObject *bpy_bmvert_seq_subscript_int(BPy_BMGeneric *self, int keynum)
+
+static PyTypeObject *bpy_bm_itype_as_pytype(const char itype)
 {
-	int len;
+	/* should cover all types */
+	switch (itype) {
+		case BM_VERTS_OF_MESH:
+		case BM_VERTS_OF_FACE:
+			return &BPy_BMVert_Type;
 
-	BPY_BM_CHECK_OBJ(self);
+		case BM_EDGES_OF_MESH:
+		case BM_EDGES_OF_FACE:
+		case BM_EDGES_OF_VERT:
+			return &BPy_BMEdge_Type;
 
-	len = self->bm->totvert;
-	if (keynum < 0) keynum += len;
-	if (keynum >= 0 && keynum < len) {
-		return BPy_BMVert_CreatePyObject(self->bm, BM_iter_at_index(self->bm, BM_VERTS_OF_MESH, NULL, keynum));
+		case BM_FACES_OF_MESH:
+		case BM_FACES_OF_EDGE:
+		case BM_FACES_OF_VERT:
+			return &BPy_BMFace_Type;
+
+		case BM_LOOPS_OF_FACE:
+		case BM_LOOPS_OF_EDGE:
+		case BM_LOOPS_OF_VERT:
+		case BM_LOOPS_OF_LOOP:
+			return &BPy_BMLoop_Type;
 	}
-	PyErr_Format(PyExc_IndexError,
-	             "bm.verts[index]: index %d out of range", keynum);
+
 	return NULL;
 }
 
-static PyObject *bpy_bmedge_seq_subscript_int(BPy_BMGeneric *self, int keynum)
+static Py_ssize_t bpy_bm_seq_length(BPy_BMElemSeq *self)
 {
-	int len;
+	BPY_BM_CHECK_INT(self);
 
-	BPY_BM_CHECK_OBJ(self);
+	switch (self->itype) {
+		/* main-types */
+		case BM_VERTS_OF_MESH:
+			return self->bm->totvert;
+		case BM_EDGES_OF_MESH:
+			return self->bm->totedge;
+		case BM_FACES_OF_MESH:
+			return self->bm->totface;
 
-	len = self->bm->totedge;
-	if (keynum < 0) keynum += len;
-	if (keynum >= 0 && keynum < len) {
-		return BPy_BMEdge_CreatePyObject(self->bm, BM_iter_at_index(self->bm, BM_EDGES_OF_MESH, NULL, keynum));
+		/* sub-types */
+		case BM_VERTS_OF_FACE:
+		case BM_EDGES_OF_FACE:
+		case BM_LOOPS_OF_FACE:
+			BPY_BM_CHECK_INT(self->py_ele);
+			return ((BMFace *)self->py_ele->ele)->len;
 	}
-	PyErr_Format(PyExc_IndexError,
-	             "bm.edges[index]: index %d out of range", keynum);
-	return NULL;
-}
 
 
-static PyObject *bpy_bmface_seq_subscript_int(BPy_BMGeneric *self, int keynum)
+	/* loop over all items, avoid this if we can */
+	{
+		BMIter iter;
+		BMHeader *ele;
+		Py_ssize_t tot = 0;
+
+		BM_ITER_BPY_BM_SEQ(ele, &iter, self) {
+			tot++;
+		}
+		return tot;
+	}
+}
+
+static PyObject *bpy_bm_seq_subscript_int(BPy_BMElemSeq *self, int keynum)
 {
 	int len;
 
 	BPY_BM_CHECK_OBJ(self);
 
-	len = self->bm->totface;
+	len = self->bm->totvert;
 	if (keynum < 0) keynum += len;
 	if (keynum >= 0 && keynum < len) {
-		return BPy_BMFace_CreatePyObject(self->bm, BM_iter_at_index(self->bm, BM_FACES_OF_MESH, NULL, keynum));
+		BMHeader *ele = BM_iter_at_index(self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL, keynum);
+
+		if (ele == NULL) {
+			PyErr_SetString(PyExc_SystemError, "internal error");
+			return NULL;
+		}
+
+		return BPy_BMElem_CreatePyObject(self->bm, ele);
 	}
 	PyErr_Format(PyExc_IndexError,
-	             "bm.faces[index]: index %d out of range", keynum);
+	             "bm.verts[index]: index %d out of range", keynum);
 	return NULL;
 }
 
-static PyObject *bpy_bmvert_seq_subscript(BPy_BMGeneric *self, PyObject *key)
+static PyObject *bpy_bm_seq_subscript(BPy_BMElemSeq *self, PyObject *key)
 {
 	/* dont need error check here */
 	if (PyIndex_Check(key)) {
 		Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
 		if (i == -1 && PyErr_Occurred())
 			return NULL;
-		return bpy_bmvert_seq_subscript_int(self, i);
+		return bpy_bm_seq_subscript_int(self, i);
 	}
 	/* TODO, slice */
 	else {
@@ -881,187 +888,58 @@
 	}
 }
 
-static PyObject *bpy_bmedge_seq_subscript(BPy_BMGeneric *self, PyObject *key)
+static int bpy_bm_seq_contains(BPy_BMElemSeq *self, PyObject *value)
 {
-	/* dont need error check here */
-	if (PyIndex_Check(key)) {
-		Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
-		if (i == -1 && PyErr_Occurred())
-			return NULL;
-		return bpy_bmedge_seq_subscript_int(self, i);
-	}
-	/* TODO, slice */
-	else {
-		PyErr_SetString(PyExc_AttributeError, "bm.edges[key]: invalid key, key must be an int");
-		return NULL;
-	}
-}
-
-static PyObject *bpy_bmface_seq_subscript(BPy_BMGeneric *self, PyObject *key)
-{
-	/* dont need error check here */
-	if (PyIndex_Check(key)) {
-		Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
-		if (i == -1 && PyErr_Occurred())
-			return NULL;
-		return bpy_bmface_seq_subscript_int(self, i);
-	}
-	/* TODO, slice */
-	else {
-		PyErr_SetString(PyExc_AttributeError, "bm.faces[key]: invalid key, key must be an int");
-		return NULL;
-	}
-}
-

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list