Revision: 44918
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44918
Author:   campbellbarton
Date:     2012-03-16 08:26:22 +0000 (Fri, 16 Mar 2012)
Log Message:
-----------
bmesh py api:
initial support for editing bmesh customdata per vert/edge/face/loop

shapes, crease, bevel weights working, missing UVs and Vertex Colors still.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/bmesh_error.h
    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/bmesh/bmesh_py_types_customdata.c
    trunk/blender/source/blender/python/bmesh/bmesh_py_types_customdata.h

Modified: trunk/blender/source/blender/bmesh/bmesh_error.h
===================================================================
--- trunk/blender/source/blender/bmesh/bmesh_error.h    2012-03-16 05:25:02 UTC 
(rev 44917)
+++ trunk/blender/source/blender/bmesh/bmesh_error.h    2012-03-16 08:26:22 UTC 
(rev 44918)
@@ -49,7 +49,7 @@
  * errorcode is either the errorcode, or BMERR_ALL for any
  * error.*/
 
-/* not yet implimented.
+/* not yet implemented.
  * int BMO_error_catch_op(BMesh *bm, BMOperator *catchop, int errorcode, char 
**msg);
  */
 

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_types.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_types.c  2012-03-16 
05:25:02 UTC (rev 44917)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_types.c  2012-03-16 
08:26:22 UTC (rev 44918)
@@ -2097,6 +2097,9 @@
 /* Sequences
  * ========= */
 
+/* BMElemSeq / Iter
+ * ---------------- */
+
 static PyTypeObject *bpy_bm_itype_as_pytype(const char itype)
 {
        /* should cover all types */
@@ -2305,6 +2308,23 @@
        return 0;
 }
 
+/* BMElem (customdata)
+ * ------------------- */
+
+static PyObject *bpy_bmelem_subscript(BPy_BMElem *self, BPy_BMLayerItem *key)
+{
+       BPY_BM_CHECK_OBJ(self);
+
+       return BPy_BMLayerItem_GetItem(self, key);
+}
+
+static int bpy_bmelem_ass_subscript(BPy_BMElem *self, BPy_BMLayerItem *key, 
PyObject *value)
+{
+       BPY_BM_CHECK_INT(self);
+
+       return BPy_BMLayerItem_SetItem(self, key, value);
+}
+
 static PySequenceMethods bpy_bmelemseq_as_sequence = {
     (lenfunc)bpy_bmelemseq_length,                  /* sq_length */
     NULL,                                        /* sq_concat */
@@ -2324,6 +2344,13 @@
     (objobjargproc)NULL,                         /* mp_ass_subscript */
 };
 
+/* for customdata access */
+static PyMappingMethods bpy_bm_elem_as_mapping = {
+    (lenfunc)NULL,                           /* mp_length */ /* keep this 
empty, messes up 'if elem: ...' test */
+    (binaryfunc)bpy_bmelem_subscript,        /* mp_subscript */
+    (objobjargproc)bpy_bmelem_ass_subscript, /* mp_ass_subscript */
+};
+
 /* Iterator
  * -------- */
 
@@ -2613,6 +2640,10 @@
 
        BPy_BMElemSeq_Type.tp_as_sequence = &bpy_bmelemseq_as_sequence;
 
+       BPy_BMVert_Type.tp_as_mapping    = &bpy_bm_elem_as_mapping;
+       BPy_BMEdge_Type.tp_as_mapping    = &bpy_bm_elem_as_mapping;
+       BPy_BMFace_Type.tp_as_mapping    = &bpy_bm_elem_as_mapping;
+       BPy_BMLoop_Type.tp_as_mapping    = &bpy_bm_elem_as_mapping;
        BPy_BMElemSeq_Type.tp_as_mapping = &bpy_bmelemseq_as_mapping;
 
        BPy_BMElemSeq_Type.tp_iter = (getiterfunc)bpy_bmelemseq_iter;
@@ -3015,10 +3046,9 @@
  *
  * \return a sting like '(BMVert/BMEdge/BMFace/BMLoop)'
  */
-char *BPy_BMElem_StringFromHType(const char htype)
+char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32])
 {
        /* zero to ensure string is always NULL terminated */
-       static char ret[32];
        char *ret_ptr = ret;
        if (htype & BM_VERT) ret_ptr += sprintf(ret_ptr, "/%s", 
BPy_BMVert_Type.tp_name);
        if (htype & BM_EDGE) ret_ptr += sprintf(ret_ptr, "/%s", 
BPy_BMEdge_Type.tp_name);
@@ -3028,3 +3058,9 @@
        *ret_ptr = ')';
        return ret;
 }
+char *BPy_BMElem_StringFromHType(const char htype)
+{
+       /* zero to ensure string is always NULL terminated */
+       static char ret[32];
+       return BPy_BMElem_StringFromHType_ex(htype, ret);
+}

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_types.h
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_types.h  2012-03-16 
05:25:02 UTC (rev 44917)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_types.h  2012-03-16 
08:26:22 UTC (rev 44918)
@@ -145,6 +145,7 @@
 
 PyObject *BPy_BMElem_Array_As_Tuple(BMesh *bm, BMHeader **elem, Py_ssize_t 
elem_len);
 int       BPy_BMElem_CheckHType(PyTypeObject *type, const char htype);
+char     *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]);
 char     *BPy_BMElem_StringFromHType(const char htype);
 
 

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-16 05:25:02 UTC (rev 44917)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_types_customdata.c       
2012-03-16 08:26:22 UTC (rev 44918)
@@ -32,13 +32,20 @@
 
 #include <Python.h>
 
+#include "BLI_string.h"
+#include "BLI_math_vector.h"
+
 #include "bmesh.h"
 
 #include "bmesh_py_types.h"
 #include "bmesh_py_types_customdata.h"
 
+#include "../mathutils/mathutils.h"
+
 #include "BKE_customdata.h"
 
+#include "DNA_meshdata_types.h"
+
 static CustomData *bpy_bm_customdata_get(BMesh *bm, char htype)
 {
        switch (htype) {
@@ -95,7 +102,7 @@
     {(char *)"color", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, 
(char *)NULL, (void *)CD_MLOOPCOL},
 
     {(char *)"shape",        (getter)bpy_bmlayeraccess_collection_get, 
(setter)NULL, (char *)NULL, (void *)CD_SHAPEKEY},
-    {(char *)"bevel_weight", (getter)bpy_bmlayeraccess_collection_get, 
(setter)NULL, (char *)NULL, (void *)CD_SHAPEKEY},
+    {(char *)"bevel_weight", (getter)bpy_bmlayeraccess_collection_get, 
(setter)NULL, (char *)NULL, (void *)CD_BWEIGHT},
     {(char *)"crease",       (getter)bpy_bmlayeraccess_collection_get, 
(setter)NULL, (char *)NULL, (void *)CD_CREASE},
 
     {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
@@ -545,3 +552,252 @@
        PyType_Ready(&BPy_BMLayerCollection_Type);
        PyType_Ready(&BPy_BMLayerItem_Type);
 }
+
+
+/* Per Element Get/Set
+ * ******************* */
+
+/**
+ * helper function for get/set, NULL return means the error is set
+*/
+static void *bpy_bmlayeritem_ptr_get(BPy_BMElem *py_ele, BPy_BMLayerItem 
*py_layer)
+{
+       void *value;
+       BMElem *ele = py_ele->ele;
+       CustomData *data;
+
+       /* error checking */
+       if (UNLIKELY(!BPy_BMLayerItem_Check(py_layer))) {
+               PyErr_SetString(PyExc_AttributeError,
+                               "BMElem[key]: invalid key, must be a 
BMLayerItem");
+               return NULL;
+       }
+       else if (UNLIKELY(py_ele->bm != py_layer->bm)) {
+               PyErr_SetString(PyExc_ValueError,
+                               "BMElem[layer]: layer is from another mesh");
+               return NULL;
+       }
+       else if (UNLIKELY(ele->head.htype != py_layer->htype)) {
+               char namestr_1[32], namestr_2[32];
+               PyErr_Format(PyExc_ValueError,
+                            "Layer/Element type mismatch, expected %.200s got 
layer type %.200s",
+                            BPy_BMElem_StringFromHType_ex(ele->head.htype, 
namestr_1),
+                            BPy_BMElem_StringFromHType_ex(py_layer->htype, 
namestr_2));
+               return NULL;
+       }
+
+       data = bpy_bm_customdata_get(py_layer->bm, py_layer->htype);
+
+       value = CustomData_bmesh_get_n(data, ele->head.data, py_layer->type, 
py_layer->index);
+
+       if (UNLIKELY(value == NULL)) {
+               /* this should be fairly unlikely but possible if layers move 
about after we get them */
+               PyErr_SetString(PyExc_KeyError,
+                            "BMElem[key]: layer not found");
+               return NULL;
+       }
+       else {
+               return value;
+       }
+}
+
+
+/**
+ *\brief BMElem.__getitem__()
+ *
+ * assume all error checks are done, eg:
+ *
+ *     uv = vert[uv_layer]
+ */
+PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem 
*py_layer)
+{
+       void *value = bpy_bmlayeritem_ptr_get(py_ele, py_layer);
+       PyObject *ret;
+
+       if (UNLIKELY(value == NULL)) {
+               return NULL;
+       }
+
+       switch (py_layer->type) {
+               case CD_MDEFORMVERT:
+               {
+                       ret = Py_NotImplemented; /* TODO */
+                       Py_INCREF(ret);
+                       break;
+               }
+               case CD_PROP_FLT:
+               {
+                       ret = PyFloat_FromDouble(*(float *)value);
+                       break;
+               }
+               case CD_PROP_INT:
+               {
+                       ret = PyLong_FromSsize_t((Py_ssize_t)(*(int *)value));
+                       break;
+               }
+               case CD_PROP_STR:
+               {
+                       MStringProperty *mstring = value;
+                       ret = PyBytes_FromStringAndSize(mstring->s, 
BLI_strnlen(mstring->s, sizeof(mstring->s)));
+                       break;
+               }
+               case CD_MTEXPOLY:
+               {
+                       ret = Py_NotImplemented; /* TODO */
+                       Py_INCREF(ret);
+                       break;
+               }
+               case CD_MLOOPUV:
+               {
+                       ret = Py_NotImplemented; /* TODO */
+                       Py_INCREF(ret);
+                       break;
+               }
+               case CD_MLOOPCOL:
+               {
+                       ret = Py_NotImplemented; /* TODO */
+                       Py_INCREF(ret);
+                       break;
+               }
+               case CD_SHAPEKEY:
+               {
+                       ret = Vector_CreatePyObject((float *)value, 3, Py_WRAP, 
NULL);
+                       break;
+               }
+               case CD_BWEIGHT:
+               {
+                       ret = PyFloat_FromDouble(*(float *)value);
+                       break;
+               }
+               case CD_CREASE:
+               {
+                       ret = PyFloat_FromDouble(*(float *)value);
+                       break;
+               }
+               default:
+               {
+                       ret = Py_NotImplemented; /* TODO */
+                       Py_INCREF(ret);
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, 
PyObject *py_value)
+{
+       int ret = 0;
+       void *value = bpy_bmlayeritem_ptr_get(py_ele, py_layer);
+
+       if (UNLIKELY(value == NULL)) {
+               return -1;
+       }
+
+       switch (py_layer->type) {
+               case CD_MDEFORMVERT:
+               {
+                       PyErr_SetString(PyExc_AttributeError, "readonly"); /* 
could make this writeable later */
+                       ret = -1;
+                       break;
+               }
+               case CD_PROP_FLT:
+               {
+                       float tmp_val = PyFloat_AsDouble(py_value);
+                       if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
+                               PyErr_Format(PyExc_TypeError, "expected a 
float, not a %.200s", Py_TYPE(py_value)->tp_name);
+                               ret = -1;
+                       }
+                       else {
+                               *(float *)value = tmp_val;
+                       }
+                       break;
+               }
+               case CD_PROP_INT:
+               {
+                       int tmp_val = PyLong_AsSsize_t(py_value);
+                       if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
+                               PyErr_Format(PyExc_TypeError, "expected an int, 
not a %.200s", Py_TYPE(py_value)->tp_name);
+                               ret = -1;
+                       }
+                       else {
+                               *(int *)value = tmp_val;
+                       }
+                       break;
+               }
+               case CD_PROP_STR:
+               {
+                       MStringProperty *mstring = value;
+                       const char *tmp_val = PyBytes_AsString(py_value);
+                       if (UNLIKELY(tmp_val == NULL)) {
+                               PyErr_Format(PyExc_TypeError, "expected bytes, 
not a %.200s", Py_TYPE(py_value)->tp_name);
+                               ret = -1;
+                       }
+                       else {
+                               BLI_strncpy(mstring->s, tmp_val, 
sizeof(mstring->s));
+                       }
+                       break;
+               }
+               case CD_MTEXPOLY:
+               {
+                       PyErr_SetString(PyExc_AttributeError, "readonly"); /* 
could make this writeable later */
+                       ret = -1;
+                       break;
+               }
+               case CD_MLOOPUV:
+               {
+                       PyErr_SetString(PyExc_AttributeError, "readonly"); /* 
could make this writeable later */
+                       ret = -1;
+                       break;
+               }
+               case CD_MLOOPCOL:
+               {
+                       PyErr_SetString(PyExc_AttributeError, "readonly");
+                       ret = -1;
+                       break;
+               }
+               case CD_SHAPEKEY:
+               {
+                       float tmp_val[3];
+                       if (UNLIKELY(mathutils_array_parse(tmp_val, 3, 3, 
py_value, "BMVert[shape] = value") == -1)) {
+                               ret = -1;
+                       }
+                       else {

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to