[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45211] trunk/blender: bmesh py api:

Campbell Barton ideasman42 at gmail.com
Tue Mar 27 12:30:11 CEST 2012


Revision: 45211
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45211
Author:   campbellbarton
Date:     2012-03-27 10:30:10 +0000 (Tue, 27 Mar 2012)
Log Message:
-----------
bmesh py api:
  added access to deform weights, access to weights acts like a python dict so you can do...

  print(group in dvert)
  dvert[group] = 0.5
  print(dvert[group])
  del dvert[group]
  print(dvert.items())

Modified Paths:
--------------
    trunk/blender/doc/python_api/rst/include__bmesh.rst
    trunk/blender/doc/python_api/sphinx_doc_gen.py
    trunk/blender/source/blender/python/bmesh/bmesh_py_types.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_types_customdata.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_types_meshdata.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_types_meshdata.h
    trunk/blender/source/blender/python/mathutils/mathutils_Color.c

Modified: trunk/blender/doc/python_api/rst/include__bmesh.rst
===================================================================
--- trunk/blender/doc/python_api/rst/include__bmesh.rst	2012-03-27 10:28:06 UTC (rev 45210)
+++ trunk/blender/doc/python_api/rst/include__bmesh.rst	2012-03-27 10:30:10 UTC (rev 45211)
@@ -104,6 +104,25 @@
         print("Vert Shape: %f, %f, %f" % (shape.x, shape.y, shape.z))
 
 
+.. code-block:: python
+
+   # in this example the active vertex group index is used,
+   # this is stored in the object, not the BMesh
+   group_index = obj.vertex_groups.active_index
+
+   # only ever one deform weight layer
+   dvert_lay = bm.verts.layers.deform.active
+
+   for vert in bm.verts:
+       dvert = vert[dvert_lay]
+		
+       if group_index in dvert:
+           print("Weight %f" % dvert[group_index])
+       else:
+           print("Setting Weight")
+           dvert[group_index] = 0.5
+
+
 Keeping a Correct State
 -----------------------
 

Modified: trunk/blender/doc/python_api/sphinx_doc_gen.py
===================================================================
--- trunk/blender/doc/python_api/sphinx_doc_gen.py	2012-03-27 10:28:06 UTC (rev 45210)
+++ trunk/blender/doc/python_api/sphinx_doc_gen.py	2012-03-27 10:30:10 UTC (rev 45211)
@@ -342,7 +342,8 @@
                     "BMLayerCollection",
                     "BMLayerItem",
                     ("Custom-Data Layer Types", '-'),
-                    "BMLoopUV"
+                    "BMLoopUV",
+                    "BMDeformVert"
                     )
     }
 

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_types.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_types.c	2012-03-27 10:28:06 UTC (rev 45210)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_types.c	2012-03-27 10:30:10 UTC (rev 45211)
@@ -2836,6 +2836,7 @@
 	mod_type_add(submodule, BPy_BMLayerItem_Type);
 	/* bmesh_py_types_meshdata.c */
 	mod_type_add(submodule, BPy_BMLoopUV_Type);
+	mod_type_add(submodule, BPy_BMDeformVert_Type);
 
 #undef mod_type_add
 

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_types_customdata.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_types_customdata.c	2012-03-27 10:28:06 UTC (rev 45210)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_types_customdata.c	2012-03-27 10:30:10 UTC (rev 45211)
@@ -361,10 +361,10 @@
 }
 
 static struct PyMethodDef bpy_bmelemseq_methods[] = {
-    {"keys",     (PyCFunction)bpy_bmlayercollection_keys,     METH_NOARGS,  bpy_bmlayercollection_keys_doc},
-    {"values",   (PyCFunction)bpy_bmlayercollection_values,   METH_NOARGS,  bpy_bmlayercollection_values_doc},
-    {"items",    (PyCFunction)bpy_bmlayercollection_items,    METH_NOARGS,  bpy_bmlayercollection_items_doc},
-    {"get",      (PyCFunction)bpy_bmlayercollection_get,      METH_VARARGS, bpy_bmlayercollection_get_doc},
+    {"keys",    (PyCFunction)bpy_bmlayercollection_keys,     METH_NOARGS,  bpy_bmlayercollection_keys_doc},
+    {"values",  (PyCFunction)bpy_bmlayercollection_values,   METH_NOARGS,  bpy_bmlayercollection_values_doc},
+    {"items",   (PyCFunction)bpy_bmlayercollection_items,    METH_NOARGS,  bpy_bmlayercollection_items_doc},
+    {"get",     (PyCFunction)bpy_bmlayercollection_get,      METH_VARARGS, bpy_bmlayercollection_get_doc},
 
     /* for later! */
 #if 0
@@ -774,8 +774,7 @@
 	switch (py_layer->type) {
 		case CD_MDEFORMVERT:
 		{
-			ret = Py_NotImplemented; /* TODO */
-			Py_INCREF(ret);
+			ret = BPy_BMDeformVert_CreatePyObject(value);
 			break;
 		}
 		case CD_PROP_FLT:
@@ -848,8 +847,7 @@
 	switch (py_layer->type) {
 		case CD_MDEFORMVERT:
 		{
-			PyErr_SetString(PyExc_AttributeError, "readonly"); /* could make this writeable later */
-			ret = -1;
+			ret = BPy_BMDeformVert_AssignPyObject(value, py_value);
 			break;
 		}
 		case CD_PROP_FLT:

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_types_meshdata.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_types_meshdata.c	2012-03-27 10:28:06 UTC (rev 45210)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_types_meshdata.c	2012-03-27 10:30:10 UTC (rev 45211)
@@ -39,6 +39,10 @@
 #include "BLI_utildefines.h"
 #include "BLI_math_vector.h"
 
+#include "BKE_deform.h"
+
+#include "bmesh_py_types_meshdata.h"
+
 /* Mesh Loop UV
  * ************ */
 
@@ -138,7 +142,7 @@
 		return -1;
 	}
 	else {
-		*((MLoopUV *)mloopuv) = *((MLoopUV *)((BPy_BMLoopUV *)value)->data);
+		*((MLoopUV *)mloopuv) = *(((BPy_BMLoopUV *)value)->data);
 		return 0;
 	}
 }
@@ -252,9 +256,333 @@
 /* --- End Mesh Loop Color --- */
 
 
+/* Mesh Deform Vert
+ * **************** */
+
+/**
+ * This is python type wraps a deform vert as a python dictionary,
+ * hiding the #MDeformWeight on access, since the mapping is very close, eg:
+ *
+ * C:
+ *     weight = defvert_find_weight(dv, group_nr);
+ *     defvert_remove_group(dv, dw)
+ *
+ * Py:
+ *     weight = dv[group_nr]
+ *     del dv[group_nr]
+ *
+ * \note: there is nothing BMesh spesific here,
+ * its only that BMesh is the only part of blender that uses a hand written api like this.
+ * This type could eventually be used to access lattice weights.
+ *
+ * \note: Many of blender-api's dict-like-wrappers act like ordered dicts,
+ * This is intentional _not_ ordered, the weights can be in any order and it wont matter,
+ * the order should not be used in the api in any meaningful way (as with a python dict)
+ * only expose as mapping, not a sequence.
+ */
+
+#define BPy_BMDeformVert_Check(v)  (Py_TYPE(v) == &BPy_BMDeformVert_Type)
+
+typedef struct BPy_BMDeformVert {
+	PyObject_VAR_HEAD
+	MDeformVert *data;
+} BPy_BMDeformVert;
+
+
+/* Mapping Protocols
+ * ================= */
+
+static int bpy_bmdeformvert_len(BPy_BMDeformVert *self)
+{
+	return self->data->totweight;
+}
+
+static PyObject *bpy_bmdeformvert_subscript(BPy_BMDeformVert *self, PyObject *key)
+{
+	if (PyIndex_Check(key)) {
+		int i;
+		i = PyNumber_AsSsize_t(key, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred()) {
+			return NULL;
+		}
+		else {
+			MDeformWeight *dw = defvert_find_index(self->data, i);
+
+			if (dw == NULL) {
+				PyErr_SetString(PyExc_KeyError, "BMDeformVert[key] = x: "
+				                "key not found");
+				return NULL;
+			}
+			else {
+				return PyFloat_FromDouble(dw->weight);
+			}
+		}
+	}
+	else {
+		PyErr_Format(PyExc_TypeError,
+		             "BMDeformVert keys must be integers, not %.200s",
+		             Py_TYPE(key)->tp_name);
+		return NULL;
+	}
+}
+
+static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key, PyObject *value)
+{
+	if (PyIndex_Check(key)) {
+		int i;
+
+		i = PyNumber_AsSsize_t(key, PyExc_IndexError);
+		if (i == -1 && PyErr_Occurred()) {
+			return -1;
+		}
+
+		if (value) {
+			/* dvert[group_index] = 0.5 */
+			if (i < 0) {
+				PyErr_SetString(PyExc_KeyError, "BMDeformVert[key] = x: "
+								"weight keys can't be negative");
+				return -1;
+			}
+			else {
+				MDeformWeight *dw = defvert_verify_index(self->data, i);
+				const float f = PyFloat_AsDouble(value);
+				if (f == -1 && PyErr_Occurred()) { // parsed key not a number
+					PyErr_SetString(PyExc_TypeError,
+									"BMDeformVert[key] = x: "
+									"argument not a number");
+					return -1;
+				}
+
+				dw->weight = CLAMPIS(f, 0.0f, 1.0f);
+			}
+		}
+		else {
+			/* del dvert[group_index] */
+			MDeformWeight *dw = defvert_find_index(self->data, i);
+
+			if (dw == NULL) {
+				PyErr_SetString(PyExc_KeyError, "del BMDeformVert[key]: "
+				                "key not found");
+			}
+			defvert_remove_group(self->data, dw);
+		}
+
+		return 0;
+
+	}
+	else {
+		PyErr_Format(PyExc_TypeError,
+		             "BMDeformVert keys must be integers, not %.200s",
+		             Py_TYPE(key)->tp_name);
+		return -1;
+	}
+}
+
+static int bpy_bmdeformvert_contains(BPy_BMDeformVert *self, PyObject *value)
+{
+	const int key = PyLong_AsSsize_t(value);
+
+	if (key == -1 && PyErr_Occurred()) {
+		PyErr_SetString(PyExc_TypeError,
+		                "BMDeformVert.__contains__: expected an int");
+		return -1;
+	}
+
+	return (defvert_find_index(self->data, key) != NULL) ? 1 : 0;
+}
+
+/* only defined for __contains__ */
+static PySequenceMethods bpy_bmdeformvert_as_sequence = {
+    (lenfunc)bpy_bmdeformvert_len,               /* sq_length */
+    NULL,                                        /* sq_concat */
+    NULL,                                        /* sq_repeat */
+
+    /* note: if this is set PySequence_Check() returns True,
+     * but in this case we dont want to be treated as a seq */
+    NULL,                                        /* sq_item */
+
+    NULL,                                        /* sq_slice */
+    NULL,                                        /* sq_ass_item */
+    NULL,                                        /* *was* sq_ass_slice */
+    (objobjproc)bpy_bmdeformvert_contains,  /* sq_contains */
+    (binaryfunc) NULL,                           /* sq_inplace_concat */
+    (ssizeargfunc) NULL,                         /* sq_inplace_repeat */
+};
+
+static PyMappingMethods bpy_bmdeformvert_as_mapping = {
+	(lenfunc)bpy_bmdeformvert_len,
+	(binaryfunc)bpy_bmdeformvert_subscript,
+	(objobjargproc)bpy_bmdeformvert_ass_subscript
+};
+
+/* Methods
+ * ======= */
+
+PyDoc_STRVAR(bpy_bmdeformvert_keys_doc,
+".. method:: keys()\n"
+"\n"
+"   Return the group indices used by this vertex\n"
+"   (matching pythons dict.keys() functionality).\n"
+"\n"
+"   :return: the deform group this vertex uses\n"
+"   :rtype: list of ints\n"
+);
+static PyObject *bpy_bmdeformvert_keys(BPy_BMDeformVert *self)
+{
+	PyObject *ret;
+	int i;
+	MDeformWeight *dw = self->data->dw;
+
+	ret = PyList_New(self->data->totweight);
+	for (i = 0; i < self->data->totweight; i++, dw++) {
+		PyList_SET_ITEM(ret, i, PyLong_FromSsize_t(dw->def_nr));
+	}
+
+	return ret;
+}
+
+PyDoc_STRVAR(bpy_bmdeformvert_values_doc,
+".. method:: items()\n"
+"\n"
+"   Return (group, weight) pairs for this vertex\n"
+"   (matching pythons dict.items() functionality).\n"
+"\n"
+"   :return: (key, value) pairs for each deform weight of this vertex.\n"
+"   :rtype: list of tuples\n"
+);
+static PyObject *bpy_bmdeformvert_values(BPy_BMDeformVert *self)
+{
+	PyObject *ret;
+	int i;
+	MDeformWeight *dw = self->data->dw;
+
+	ret = PyList_New(self->data->totweight);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list