[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44549] trunk/blender/source/blender/ python/bmesh: bmesh py api - initial support for selection history.

Campbell Barton ideasman42 at gmail.com
Wed Feb 29 15:05:08 CET 2012


Revision: 44549
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44549
Author:   campbellbarton
Date:     2012-02-29 14:05:03 +0000 (Wed, 29 Feb 2012)
Log Message:
-----------
bmesh py api - initial support for selection history.

Modified Paths:
--------------
    trunk/blender/source/blender/python/bmesh/CMakeLists.txt
    trunk/blender/source/blender/python/bmesh/bmesh_py_api.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_types.c

Added Paths:
-----------
    trunk/blender/source/blender/python/bmesh/bmesh_py_select.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_select.h

Modified: trunk/blender/source/blender/python/bmesh/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/python/bmesh/CMakeLists.txt	2012-02-29 13:48:19 UTC (rev 44548)
+++ trunk/blender/source/blender/python/bmesh/CMakeLists.txt	2012-02-29 14:05:03 UTC (rev 44549)
@@ -33,10 +33,12 @@
 
 set(SRC
 	bmesh_py_api.c
+	bmesh_py_select.c
 	bmesh_py_types.c
 	bmesh_py_utils.c
 
 	bmesh_py_api.h
+	bmesh_py_select.h
 	bmesh_py_types.h
 	bmesh_py_utils.h
 )

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_api.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_api.c	2012-02-29 13:48:19 UTC (rev 44548)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_api.c	2012-02-29 14:05:03 UTC (rev 44549)
@@ -35,6 +35,7 @@
 
 #include "bmesh_py_types.h"
 #include "bmesh_py_utils.h"
+#include "bmesh_py_select.h"
 
 #include "BLI_utildefines.h"
 
@@ -96,7 +97,9 @@
 	PyObject *sys_modules = PySys_GetObject("modules"); /* not pretty */
 
 	BPy_BM_init_types();
+	BPy_BM_init_select_types();
 
+
 	mod = PyModule_Create(&BPy_BM_module_def);
 
 	/* bmesh.types */

Added: trunk/blender/source/blender/python/bmesh/bmesh_py_select.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_select.c	                        (rev 0)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_select.c	2012-02-29 14:05:03 UTC (rev 44549)
@@ -0,0 +1,312 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/bmesh/bmesh_py_api.c
+ *  \ingroup pybmesh
+ *
+ * This file defines the 'bmesh' module.
+ */
+
+#include <Python.h>
+
+#include "bmesh.h"
+
+#include "bmesh_py_types.h"
+#include "bmesh_py_select.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+
+#include "BKE_tessmesh.h"
+
+#include "DNA_mesh_types.h"
+
+#include "../generic/py_capi_utils.h"
+
+#include "bmesh_py_api.h" /* own include */
+
+static PyGetSetDef bpy_bmeditselseq_getseters[] = {
+    // {(char *)"verts", (getter)bpy_bmeditselseq_get, (setter)NULL, (char *)bpy_bmesh_verts_doc, (void *)BM_VERTS_OF_MESH},
+
+    {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
+};
+
+static struct PyMethodDef bpy_bmeditselseq_methods[] = {
+    // {"select_flush_mode", (PyCFunction)bpy_bmesh_select_flush_mode, METH_NOARGS, bpy_bmesh_select_flush_mode_doc},
+    {NULL, NULL, 0, NULL}
+};
+
+
+/* Sequences
+ * ========= */
+
+static Py_ssize_t bpy_bmeditselseq_length(BPy_BMEditSelSeq *self)
+{
+	BPY_BM_CHECK_INT(self);
+
+	return BLI_countlist(&self->bm->selected);
+}
+
+static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keynum)
+{
+	BPY_BM_CHECK_OBJ(self);
+
+	if (keynum < 0) keynum += bpy_bmeditselseq_length(self); /* only get length on negative value, may loop entire seq */
+	if (keynum >= 0) {
+		BMEditSelection *ese = BLI_findlink(&self->bm->selected, keynum);
+		if (ese) {
+			return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
+		}
+	}
+
+	PyErr_Format(PyExc_IndexError,
+	             "BMElemSeq[index]: index %d out of range", keynum);
+	return NULL;
+}
+
+static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, Py_ssize_t start, Py_ssize_t stop)
+{
+	int count = 0;
+	int ok;
+
+	PyObject *list;
+	PyObject *item;
+	BMEditSelection *ese;
+
+	BPY_BM_CHECK_OBJ(self);
+
+	list = PyList_New(0);
+
+	ese = self->bm->selected.first;
+
+	ok = (ese != NULL);
+
+	if (UNLIKELY(ok == FALSE)) {
+		return list;
+	}
+
+	/* first loop up-until the start */
+	for (ok = TRUE; ok; ok = ((ese = ese->next) != NULL)) {
+		if (count == start) {
+			break;
+		}
+		count++;
+	}
+
+	/* add items until stop */
+	while ((ese = ese->next)) {
+		item = BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
+		PyList_Append(list, item);
+		Py_DECREF(item);
+
+		count++;
+		if (count == stop) {
+			break;
+		}
+	}
+
+	return list;
+}
+
+static PyObject *bpy_bmeditselseq_subscript(BPy_BMEditSelSeq *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_bmeditselseq_subscript_int(self, i);
+	}
+	else if (PySlice_Check(key)) {
+		PySliceObject *key_slice = (PySliceObject *)key;
+		Py_ssize_t step = 1;
+
+		if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
+			return NULL;
+		}
+		else if (step != 1) {
+			PyErr_SetString(PyExc_TypeError,
+			                "BMElemSeq[slice]: slice steps not supported");
+			return NULL;
+		}
+		else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
+			return bpy_bmeditselseq_subscript_slice(self, 0, PY_SSIZE_T_MAX);
+		}
+		else {
+			Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
+
+			/* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
+			if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL;
+			if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop))    return NULL;
+
+			if (start < 0 || stop < 0) {
+				/* only get the length for negative values */
+				Py_ssize_t len = bpy_bmeditselseq_length(self);
+				if (start < 0) start += len;
+				if (stop < 0) start += len;
+			}
+
+			if (stop - start <= 0) {
+				return PyList_New(0);
+			}
+			else {
+				return bpy_bmeditselseq_subscript_slice(self, start, stop);
+			}
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_AttributeError,
+		                "BMElemSeq[key]: invalid key, key must be an int");
+		return NULL;
+	}
+}
+
+static int bpy_bmeditselseq_contains(BPy_BMEditSelSeq *self, PyObject *value)
+{
+	BPy_BMElem *value_bm_ele;
+
+	BPY_BM_CHECK_INT(self);
+
+	value_bm_ele = (BPy_BMElem *)value;
+	if (value_bm_ele->bm == self->bm) {
+		BMEditSelection *ese_test;
+		BMElem *ele;
+
+		ele = value_bm_ele->ele;
+		for (ese_test = self->bm->selected.first; ese_test; ese_test = ese_test->next) {
+			if (ele == ese_test->ele) {
+				return 1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static PySequenceMethods bpy_bmeditselseq_as_sequence = {
+    (lenfunc)bpy_bmeditselseq_length,                  /* sq_length */
+    NULL,                                        /* sq_concat */
+    NULL,                                        /* sq_repeat */
+    (ssizeargfunc)bpy_bmeditselseq_subscript_int,      /* sq_item */ /* Only set this so PySequence_Check() returns True */
+    NULL,                                        /* sq_slice */
+    (ssizeobjargproc)NULL,                       /* sq_ass_item */
+    NULL,                                        /* *was* sq_ass_slice */
+    (objobjproc)bpy_bmeditselseq_contains,             /* sq_contains */
+    (binaryfunc) NULL,                           /* sq_inplace_concat */
+    (ssizeargfunc) NULL,                         /* sq_inplace_repeat */
+};
+
+static PyMappingMethods bpy_bmeditselseq_as_mapping = {
+    (lenfunc)bpy_bmeditselseq_length,                  /* mp_length */
+    (binaryfunc)bpy_bmeditselseq_subscript,            /* mp_subscript */
+    (objobjargproc)NULL,                         /* mp_ass_subscript */
+};
+
+
+/* Iterator
+ * -------- */
+
+static PyObject *bpy_bmeditselseq_iter(BPy_BMEditSelSeq *self)
+{
+	BPy_BMEditSelIter *py_iter;
+
+	BPY_BM_CHECK_OBJ(self);
+	py_iter = (BPy_BMEditSelIter *)BPy_BMEditSelIter_CreatePyObject(self->bm);
+	py_iter->ese = self->bm->selected.first;
+	return (PyObject *)py_iter;
+}
+
+static PyObject *bpy_bmeditseliter_next(BPy_BMEditSelIter *self)
+{
+	BMEditSelection *ese = self->ese;
+	if (ese == NULL) {
+		PyErr_SetString(PyExc_StopIteration,
+		                "bpy_bmiter_next stop");
+		return NULL;
+	}
+	else {
+		self->ese = ese->next;
+		return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
+	}
+}
+
+PyTypeObject BPy_BMEditSelSeq_Type     = {{{0}}};
+PyTypeObject BPy_BMEditSelIter_Type = {{{0}}};
+
+
+PyObject *BPy_BMEditSel_CreatePyObject(BMesh *bm)
+{
+	BPy_BMEditSelSeq *self = PyObject_New(BPy_BMEditSelSeq, &BPy_BMEditSelSeq_Type);
+	self->bm = bm;
+	/* caller must initialize 'iter' member */
+	return (PyObject *)self;
+}
+
+PyObject *BPy_BMEditSelIter_CreatePyObject(BMesh *bm)
+{
+	BPy_BMEditSelIter *self = PyObject_New(BPy_BMEditSelIter, &BPy_BMEditSelIter_Type);
+	self->bm = bm;
+	/* caller must initialize 'iter' member */
+	return (PyObject *)self;
+}
+
+void BPy_BM_init_select_types(void)
+{
+	BPy_BMEditSelSeq_Type.tp_basicsize     = sizeof(BPy_BMEditSelSeq);
+	BPy_BMEditSelIter_Type.tp_basicsize    = sizeof(BPy_BMEditSelIter);
+
+	BPy_BMEditSelSeq_Type.tp_name  = "BMEditSelSeq";
+	BPy_BMEditSelIter_Type.tp_name = "BMEditSelIter";
+
+	BPy_BMEditSelSeq_Type.tp_doc   = NULL; // todo
+	BPy_BMEditSelIter_Type.tp_doc  = NULL;
+
+	BPy_BMEditSelSeq_Type.tp_repr  = (reprfunc)NULL;
+	BPy_BMEditSelIter_Type.tp_repr = (reprfunc)NULL;
+
+	BPy_BMEditSelSeq_Type.tp_getset     = bpy_bmeditselseq_getseters;
+	BPy_BMEditSelIter_Type.tp_getset = NULL;
+
+	BPy_BMEditSelSeq_Type.tp_methods     = bpy_bmeditselseq_methods;
+	BPy_BMEditSelIter_Type.tp_methods = NULL;
+
+	BPy_BMEditSelSeq_Type.tp_as_sequence = &bpy_bmeditselseq_as_sequence;
+
+	BPy_BMEditSelSeq_Type.tp_as_mapping = &bpy_bmeditselseq_as_mapping;
+
+	BPy_BMEditSelSeq_Type.tp_iter = (getiterfunc)bpy_bmeditselseq_iter;
+
+	/* only 1 iteratir so far */
+	BPy_BMEditSelIter_Type.tp_iternext = (iternextfunc)bpy_bmeditseliter_next;
+
+	BPy_BMEditSelSeq_Type.tp_dealloc     = NULL; //(destructor)bpy_bmeditselseq_dealloc;
+	BPy_BMEditSelIter_Type.tp_dealloc = NULL; //(destructor)bpy_bmvert_dealloc;
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list