[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44332] trunk/blender/source/blender: bmesh python api change in internal behavior.

Campbell Barton ideasman42 at gmail.com
Wed Feb 22 17:08:38 CET 2012


Revision: 44332
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44332
Author:   campbellbarton
Date:     2012-02-22 16:08:30 +0000 (Wed, 22 Feb 2012)
Log Message:
-----------
bmesh python api change in internal behavior.

* Only have 1 python object per bmesh, vertex, edge, loop, face.
* Store pointers back to the python data in a custom data layer so as not to use more memory for normal editing operations (when pythons not running).
* Currently this data is created and freed along with the BMesh PyObject.
* Incidentally - this fixes comparisons for bmesh elements which wasnt working before.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/customdata.c
    trunk/blender/source/blender/bmesh/bmesh_class.h
    trunk/blender/source/blender/makesdna/DNA_customdata_types.h
    trunk/blender/source/blender/python/bmesh/bmesh_py_types.c

Modified: trunk/blender/source/blender/blenkernel/intern/customdata.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/customdata.c	2012-02-22 15:35:42 UTC (rev 44331)
+++ trunk/blender/source/blender/blenkernel/intern/customdata.c	2012-02-22 16:08:30 UTC (rev 44332)
@@ -159,6 +159,33 @@
 	}
 }
 
+/* copy just zeros in this case */
+static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest,
+                                        int count)
+{
+	int i, size = sizeof(void *);
+
+	for(i = 0; i < count; ++i) {
+		void **ptr = (void  **)((char *)dest + i * size);
+		*ptr = NULL;
+	}
+}
+
+static void layerFree_bmesh_elem_py_ptr(void *data, int count, int size)
+{
+	extern void bpy_bm_generic_invalidate(void *self);
+
+	int i;
+
+	for(i = 0; i < count; ++i) {
+		void **ptr = (void *)((char *)data + i * size);
+		if (*ptr) {
+			bpy_bm_generic_invalidate(*ptr);
+		}
+	}
+}
+
+
 static void linklist_free_simple(void *link)
 {
 	MEM_freeN(link);
@@ -1003,6 +1030,10 @@
 	{sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
 	 layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
 	 layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
+	/* 33: CD_BM_ELEM_PYPTR */
+	{sizeof(void *), "", 1, NULL, layerCopy_bmesh_elem_py_ptr,
+	 layerFree_bmesh_elem_py_ptr, NULL, NULL, NULL},
+
 /* END BMESH ONLY */
 
 

Modified: trunk/blender/source/blender/bmesh/bmesh_class.h
===================================================================
--- trunk/blender/source/blender/bmesh/bmesh_class.h	2012-02-22 15:35:42 UTC (rev 44331)
+++ trunk/blender/source/blender/bmesh/bmesh_class.h	2012-02-22 16:08:30 UTC (rev 44332)
@@ -179,6 +179,8 @@
 	ListBase errorstack;
 	struct Object *ob; /* owner object */
 	
+	void *py_handle;
+
 	int opflag; /* current operator flag */
 } BMesh;
 

Modified: trunk/blender/source/blender/makesdna/DNA_customdata_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_customdata_types.h	2012-02-22 15:35:42 UTC (rev 44331)
+++ trunk/blender/source/blender/makesdna/DNA_customdata_types.h	2012-02-22 16:08:30 UTC (rev 44332)
@@ -63,10 +63,9 @@
  * layers, each with a data type (e.g. MTFace, MDeformVert, etc.). */
 typedef struct CustomData {
 	CustomDataLayer *layers;      /* CustomDataLayers, ordered by type */
-	int typemap[33];              /* runtime only! - maps types to indices of first layer of that type,
+	int typemap[34];              /* runtime only! - maps types to indices of first layer of that type,
 	                               * MUST be >= CD_NUMTYPES, but we cant use a define here.
 	                               * Correct size is ensured in CustomData_update_typemap assert() */
-	int pad1;
 
 	int totlayer, maxlayer;       /* number of layers, size of layers array */
 	int totsize, pad2;             /* in editmode, total size of all data layers */
@@ -110,9 +109,10 @@
 #define CD_CREASE		30
 #define CD_ORIGSPACE_MLOOP	31
 #define CD_WEIGHT_MLOOPCOL	32
+#define CD_BM_ELEM_PYPTR	33
 /* BMESH ONLY END */
 
-#define CD_NUMTYPES		33
+#define CD_NUMTYPES		34
 
 /* Bits for CustomDataMask */
 #define CD_MASK_MVERT		(1 << CD_MVERT)
@@ -148,6 +148,7 @@
 #define CD_MASK_CREASE		(1 << CD_CREASE)
 #define CD_MASK_ORIGSPACE_MLOOP	(1 << CD_ORIGSPACE_MLOOP)
 #define CD_MASK_WEIGHT_MLOOPCOL (1LL << CD_WEIGHT_MLOOPCOL)
+#define CD_MASK_BM_ELEM_PYPTR (1LL << CD_BM_ELEM_PYPTR)
 /* BMESH ONLY END */
 
 /* CustomData.flag */

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_types.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_types.c	2012-02-22 15:35:42 UTC (rev 44331)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_types.c	2012-02-22 16:08:30 UTC (rev 44332)
@@ -31,6 +31,8 @@
 
 #include "BLI_math.h"
 
+#include "BKE_customdata.h"
+
 #include "bmesh.h"
 
 #include "../mathutils/mathutils.h"
@@ -1129,7 +1131,7 @@
 			return NULL;
 		}
 		else if (step != 1) {
-			PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
+			PyErr_SetString(PyExc_TypeError, "BMElemSeq[slice]: slice steps not supported");
 			return NULL;
 		}
 		else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
@@ -1231,6 +1233,60 @@
 /* Dealloc Functions
  * ================= */
 
+static void bpy_bmesh_dealloc(BPy_BMesh *self)
+{
+	BMesh *bm = self->bm;
+
+	BM_data_layer_free(bm, &bm->vdata, CD_BM_ELEM_PYPTR);
+	BM_data_layer_free(bm, &bm->edata, CD_BM_ELEM_PYPTR);
+	BM_data_layer_free(bm, &bm->pdata, CD_BM_ELEM_PYPTR);
+	BM_data_layer_free(bm, &bm->ldata, CD_BM_ELEM_PYPTR);
+
+	bm->py_handle = NULL;
+
+	PyObject_DEL(self);
+}
+
+static void bpy_bmvert_dealloc(BPy_BMElem *self)
+{
+	BMesh *bm = self->bm;
+	if (bm) {
+		void **ptr = CustomData_bmesh_get(&bm->vdata, self->ele->data, CD_BM_ELEM_PYPTR);
+		*ptr = NULL;
+	}
+	PyObject_DEL(self);
+}
+
+static void bpy_bmedge_dealloc(BPy_BMElem *self)
+{
+	BMesh *bm = self->bm;
+	if (bm) {
+		void **ptr = CustomData_bmesh_get(&bm->edata, self->ele->data, CD_BM_ELEM_PYPTR);
+		*ptr = NULL;
+	}
+	PyObject_DEL(self);
+}
+
+static void bpy_bmface_dealloc(BPy_BMElem *self)
+{
+	BMesh *bm = self->bm;
+	if (bm) {
+		void **ptr = CustomData_bmesh_get(&bm->pdata, self->ele->data, CD_BM_ELEM_PYPTR);
+		*ptr = NULL;
+	}
+	PyObject_DEL(self);
+}
+
+static void bpy_bmloop_dealloc(BPy_BMElem *self)
+{
+	BMesh *bm = self->bm;
+	if (bm) {
+		void **ptr = CustomData_bmesh_get(&bm->ldata, self->ele->data, CD_BM_ELEM_PYPTR);
+		*ptr = NULL;
+	}
+	PyObject_DEL(self);
+}
+
 static void bpy_bm_seq_dealloc(BPy_BMElemSeq *self)
 {
 	Py_XDECREF(self->py_ele);
@@ -1309,11 +1365,11 @@
 	/* only 1 iteratir so far */
 	BPy_BMIter_Type.tp_iternext = (iternextfunc)bpy_bm_iter_next;
 
-	BPy_BMesh_Type.tp_dealloc     = NULL;
-	BPy_BMVert_Type.tp_dealloc    = NULL;
-	BPy_BMEdge_Type.tp_dealloc    = NULL;
-	BPy_BMFace_Type.tp_dealloc    = NULL;
-	BPy_BMLoop_Type.tp_dealloc    = NULL;
+	BPy_BMesh_Type.tp_dealloc     = (destructor)bpy_bmesh_dealloc;
+	BPy_BMVert_Type.tp_dealloc    = (destructor)bpy_bmvert_dealloc;
+	BPy_BMEdge_Type.tp_dealloc    = (destructor)bpy_bmedge_dealloc;
+	BPy_BMFace_Type.tp_dealloc    = (destructor)bpy_bmface_dealloc;
+	BPy_BMLoop_Type.tp_dealloc    = (destructor)bpy_bmloop_dealloc;
 	BPy_BMElemSeq_Type.tp_dealloc = (destructor)bpy_bm_seq_dealloc;
 	BPy_BMIter_Type.tp_dealloc    = NULL;
 
@@ -1351,44 +1407,104 @@
 
 PyObject *BPy_BMesh_CreatePyObject(BMesh *bm)
 {
-	BPy_BMesh *self = PyObject_New(BPy_BMesh, &BPy_BMesh_Type);
-	self->bm = bm;
+	BPy_BMesh *self;
+
+	if (bm->py_handle) {
+		self = bm->py_handle;
+		Py_INCREF(self);
+	}
+	else {
+		self = PyObject_New(BPy_BMesh, &BPy_BMesh_Type);
+		self->bm = bm;
+
+		BM_data_layer_add(bm, &bm->vdata, CD_BM_ELEM_PYPTR);
+		BM_data_layer_add(bm, &bm->edata, CD_BM_ELEM_PYPTR);
+		BM_data_layer_add(bm, &bm->pdata, CD_BM_ELEM_PYPTR);
+		BM_data_layer_add(bm, &bm->ldata, CD_BM_ELEM_PYPTR);
+	}
+
 	return (PyObject *)self;
 }
 
+
+
 PyObject *BPy_BMVert_CreatePyObject(BMesh *bm, BMVert *v)
 {
-	BPy_BMVert *self = PyObject_New(BPy_BMVert, &BPy_BMVert_Type);
-	BLI_assert(v != NULL);
-	self->bm = bm;
-	self->v  = v;
+	BPy_BMVert *self;
+
+	void **ptr = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_BM_ELEM_PYPTR);
+
+	if (*ptr != NULL) {
+		self = *ptr;
+		Py_INCREF(self);
+	}
+	else {
+		self = PyObject_New(BPy_BMVert, &BPy_BMVert_Type);
+		BLI_assert(v != NULL);
+		self->bm = bm;
+		self->v  = v;
+		*ptr = self;
+	}
 	return (PyObject *)self;
 }
 
 PyObject *BPy_BMEdge_CreatePyObject(BMesh *bm, BMEdge *e)
 {
-	BPy_BMEdge *self = PyObject_New(BPy_BMEdge, &BPy_BMEdge_Type);
-	BLI_assert(e != NULL);
-	self->bm = bm;
-	self->e  = e;
+	BPy_BMEdge *self;
+
+	void **ptr = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BM_ELEM_PYPTR);
+
+	if (*ptr != NULL) {
+		self = *ptr;
+		Py_INCREF(self);
+	}
+	else {
+		self = PyObject_New(BPy_BMEdge, &BPy_BMEdge_Type);
+		BLI_assert(e != NULL);
+		self->bm = bm;
+		self->e  = e;
+		*ptr = self;
+	}
 	return (PyObject *)self;
 }
 
 PyObject *BPy_BMFace_CreatePyObject(BMesh *bm, BMFace *f)
 {
-	BPy_BMFace *self = PyObject_New(BPy_BMFace, &BPy_BMFace_Type);
-	BLI_assert(f != NULL);
-	self->bm = bm;
-	self->f  = f;
+	BPy_BMFace *self;
+
+	void **ptr = CustomData_bmesh_get(&bm->pdata, f->head.data, CD_BM_ELEM_PYPTR);
+
+	if (*ptr != NULL) {
+		self = *ptr;
+		Py_INCREF(self);
+	}
+	else {
+		self = PyObject_New(BPy_BMFace, &BPy_BMFace_Type);
+		BLI_assert(f != NULL);
+		self->bm = bm;
+		self->f  = f;
+		*ptr = self;
+	}
 	return (PyObject *)self;
 }
 
 PyObject *BPy_BMLoop_CreatePyObject(BMesh *bm, BMLoop *l)
 {
-	BPy_BMLoop *self = PyObject_New(BPy_BMLoop, &BPy_BMLoop_Type);
-	BLI_assert(l != NULL);
-	self->bm = bm;
-	self->l  = l;
+	BPy_BMLoop *self;
+
+	void **ptr = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_BM_ELEM_PYPTR);
+
+	if (*ptr != NULL) {
+		self = *ptr;
+		Py_INCREF(self);
+	}
+	else {
+		self = PyObject_New(BPy_BMLoop, &BPy_BMLoop_Type);
+		BLI_assert(l != NULL);
+		self->bm = bm;
+		self->l  = l;
+		*ptr = self;
+	}
 	return (PyObject *)self;
 }
 




More information about the Bf-blender-cvs mailing list