Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-04-30 22:54:14 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-04-30 22:54:14 +0400
commit1d743d11dcd48807c4dc13c109f5199573015b9d (patch)
treeac38b4a0af53bd23198bd8281afb525e863cf5fb /source
parentdf74a51bac173b8e47882801bf0f5d47d856f897 (diff)
bmesh - python api
- bm.*.layers.*.verify() - bm.*.layers.*.is_singleton - bm.*.layers.*.copy_from(other) also added api functons - BM_data_layer_copy(...) - CustomData_layertype_is_singleton(type)
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_customdata.h1
-rw-r--r--source/blender/blenkernel/intern/customdata.c16
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c46
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.h2
-rw-r--r--source/blender/editors/mesh/mesh_data.c46
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c114
6 files changed, 181 insertions, 44 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 6a3625e2133..4b52189d8b7 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -305,6 +305,7 @@ int CustomData_sizeof(int type);
/* get the name of a layer type */
const char *CustomData_layertype_name(int type);
+int CustomData_layertype_is_singleton(int type);
/* make sure the name of layer at index is unique */
void CustomData_set_layer_unique_name(struct CustomData *data, int index);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 4666aa6a456..4cf48ff6005 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -71,7 +71,11 @@ typedef struct LayerTypeInfo {
int size; /* the memory size of one element of this layer's data */
const char *structname; /* name of the struct used, for file writing */
int structnum; /* number of structs per element, for file writing */
- const char *defaultname; /* default layer name */
+
+ /* default layer name.
+ * note! when NULL this is a way to ensure there is only ever one item
+ * see: CustomData_layertype_is_singleton() */
+ const char *defaultname;
/* a function to copy count elements of this layer's data
* (deep copy if appropriate)
@@ -2601,6 +2605,16 @@ const char *CustomData_layertype_name(int type)
return layerType_getName(type);
}
+
+/**
+ * Can only ever be one of these.
+ */
+int CustomData_layertype_is_singleton(int type)
+{
+ const LayerTypeInfo *typeInfo = layerType_getInfo(type);
+ return typeInfo->defaultname != NULL;
+}
+
static int CustomData_is_property_layer(int type)
{
if ((type == CD_PROP_FLT) || (type == CD_PROP_INT) || (type == CD_PROP_STR))
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 5149a5436a2..c774880332b 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -853,6 +853,52 @@ void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n)
if (olddata.layers) MEM_freeN(olddata.layers);
}
+void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int dst_n)
+{
+ BMIter iter;
+
+ if (&bm->vdata == data) {
+ BMVert *eve;
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ void *ptr = CustomData_bmesh_get_n(data, eve->head.data, type, dst_n);
+ CustomData_bmesh_set_n(data, eve->head.data, type, src_n, ptr);
+ }
+ }
+ else if (&bm->edata == data) {
+ BMEdge *eed;
+
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ void *ptr = CustomData_bmesh_get_n(data, eed->head.data, type, dst_n);
+ CustomData_bmesh_set_n(data, eed->head.data, type, src_n, ptr);
+ }
+ }
+ else if (&bm->pdata == data) {
+ BMFace *efa;
+
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ void *ptr = CustomData_bmesh_get_n(data, efa->head.data, type, dst_n);
+ CustomData_bmesh_set_n(data, efa->head.data, type, src_n, ptr);
+ }
+ }
+ else if (&bm->ldata == data) {
+ BMIter liter;
+ BMFace *efa;
+ BMLoop *l;
+
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ void *ptr = CustomData_bmesh_get_n(data, l->head.data, type, dst_n);
+ CustomData_bmesh_set_n(data, l->head.data, type, src_n, ptr);
+ }
+ }
+ }
+ else {
+ /* should never reach this! */
+ BLI_assert(0);
+ }
+}
+
float BM_elem_float_data_get(CustomData *cd, void *element, int type)
{
float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h
index 0d97fbcc0ec..3380a3e6b1b 100644
--- a/source/blender/bmesh/intern/bmesh_interp.h
+++ b/source/blender/bmesh/intern/bmesh_interp.h
@@ -36,6 +36,8 @@ void BM_data_layer_add(BMesh *em, CustomData *data, int type);
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name);
void BM_data_layer_free(BMesh *em, CustomData *data, int type);
void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n);
+void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int dst_n);
+
float BM_elem_float_data_get(CustomData *cd, void *element, int type);
void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val);
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 5aea6f8d1c3..fb9b012a31a 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -189,42 +189,6 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la
}
}
-/* copies from active to 'index' */
-static void editmesh_face_copy_customdata(BMEditMesh *em, int type, int index)
-{
- BMesh *bm = em->bm;
- CustomData *pdata = &bm->pdata;
- BMIter iter;
- BMFace *efa;
- const int n = CustomData_get_active_layer(pdata, type);
-
- /* ensure all current elements follow new customdata layout */
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- void *data = CustomData_bmesh_get_n(pdata, efa->head.data, type, n);
- CustomData_bmesh_set_n(pdata, efa->head.data, type, index, data);
- }
-}
-
-/* copies from active to 'index' */
-static void editmesh_loop_copy_customdata(BMEditMesh *em, int type, int index)
-{
- BMesh *bm = em->bm;
- CustomData *ldata = &bm->ldata;
- BMIter iter;
- BMIter liter;
- BMFace *efa;
- BMLoop *loop;
- const int n = CustomData_get_active_layer(ldata, type);
-
- /* ensure all current elements follow new customdata layout */
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) {
- void *data = CustomData_bmesh_get_n(ldata, loop->head.data, type, n);
- CustomData_bmesh_set_n(ldata, loop->head.data, type, index, data);
- }
- }
-}
-
int ED_mesh_uv_loop_reset_ex(struct bContext *C, struct Mesh *me, const int layernum)
{
BMEditMesh *em = me->edit_btmesh;
@@ -360,7 +324,8 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
BM_data_layer_add_named(em->bm, &em->bm->pdata, CD_MTEXPOLY, name);
/* copy data from active UV */
if (layernum) {
- editmesh_face_copy_customdata(em, CD_MTEXPOLY, layernum);
+ const int layernum_dst = CustomData_get_active_layer(&em->bm->pdata, CD_MTEXPOLY);
+ BM_data_layer_copy(em->bm, &em->bm->pdata, CD_MTEXPOLY, layernum, layernum_dst);
}
if (active_set || layernum == 0) {
CustomData_set_layer_active(&em->bm->pdata, CD_MTEXPOLY, layernum);
@@ -370,7 +335,9 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s
BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_MLOOPUV, name);
/* copy data from active UV */
if (layernum) {
- editmesh_loop_copy_customdata(em, CD_MLOOPUV, layernum);
+ const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPUV);
+ BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum, layernum_dst);
+
is_init = TRUE;
}
if (active_set || layernum == 0) {
@@ -457,7 +424,8 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes
BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_MLOOPCOL, name);
/* copy data from active vertex color layer */
if (layernum) {
- editmesh_loop_copy_customdata(em, CD_MLOOPCOL, layernum);
+ const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPCOL);
+ BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum, layernum_dst);
}
if (active_set || layernum == 0) {
CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum);
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 6a02d8e4a25..86cfa727e97 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -124,7 +124,7 @@ static PyObject *bpy_bmlayeraccess_collection_get(BPy_BMLayerAccess *self, void
PyDoc_STRVAR(bpy_bmlayercollection_active_doc,
-"This meshes vert sequence (read-only).\n\n:type: :class:`BMVertSeq`"
+"The active layer of this type (read-only).\n\n:type: :class:`BMLayerItem`"
);
static PyObject *bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *UNUSED(flag))
{
@@ -145,6 +145,17 @@ static PyObject *bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *U
}
}
+
+PyDoc_STRVAR(bpy_bmlayercollection_is_singleton_doc,
+"This meshes vert sequence (read-only).\n\n:type: :class:`BMVertSeq`"
+);
+static PyObject *bpy_bmlayercollection_is_singleton_get(BPy_BMLayerItem *self, void *UNUSED(flag))
+{
+ BPY_BM_CHECK_OBJ(self);
+
+ return PyBool_FromLong(CustomData_layertype_is_singleton(self->type));
+}
+
PyDoc_STRVAR(bpy_bmlayercollection_name_doc,
"The layers unique name (read-only).\n\n:type: string"
);
@@ -211,7 +222,8 @@ static PyGetSetDef bpy_bmlayeraccess_loop_getseters[] = {
static PyGetSetDef bpy_bmlayercollection_getseters[] = {
/* BMESH_TODO, make writeable */
- {(char *)"active", (getter)bpy_bmlayercollection_active_get, (setter)NULL, (char *)bpy_bmlayercollection_active_doc, NULL},
+ {(char *)"active", (getter)bpy_bmlayercollection_active_get, (setter)NULL, (char *)bpy_bmlayercollection_active_doc, NULL},
+ {(char *)"is_singleton", (getter)bpy_bmlayercollection_is_singleton_get, (setter)NULL, (char *)bpy_bmlayercollection_is_singleton_doc, NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -230,6 +242,87 @@ static PyGetSetDef bpy_bmlayeritem_getseters[] = {
/* BMLayerCollection
* ----------------- */
+PyDoc_STRVAR(bpy_bmlayeritem_copy_from_doc,
+".. method:: copy_from(other)\n"
+"\n"
+" Return a copy of the layer\n"
+"\n"
+" :arg other: Another layer to copy from.\n"
+" :arg other: :class:`BMLayerItem`\n"
+);
+static PyObject *bpy_bmlayeritem_copy_from(BPy_BMLayerItem *self, BPy_BMLayerItem *value)
+{
+ CustomData *data;
+
+ if (!BPy_BMLayerItem_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "layer.copy_from(x): expected BMLayerItem, not '%.200s'",
+ Py_TYPE(value)->tp_name);
+ return NULL;
+ }
+
+ BPY_BM_CHECK_OBJ(self);
+ BPY_BM_CHECK_OBJ(value);
+
+ if (self->bm != value->bm) {
+ PyErr_SetString(PyExc_ValueError,
+ "layer.copy_from(): layer is from another mesh");
+ return NULL;
+ }
+
+ else if ((self->htype != value->htype) ||
+ (self->type != value->type) ||
+ (self->index != value->index))
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "layer.copy_from(other): layer type mismatch");
+ }
+
+ data = bpy_bm_customdata_get(self->bm, self->htype);
+
+ if ((bpy_bmlayeritem_get(self) == NULL) ||
+ (bpy_bmlayeritem_get(value) == NULL))
+ {
+ return NULL;
+ }
+
+ BM_data_layer_copy(self->bm, data, self->type, value->index, self->index);
+
+ Py_RETURN_NONE;
+}
+
+/* similar to new(), but no name arg. */
+PyDoc_STRVAR(bpy_bmlayercollection_verify_doc,
+".. method:: verify()\n"
+"\n"
+" Create a new layer or return an existing active layer\n"
+"\n"
+" :return: The newly verified layer.\n"
+" :rtype: :class:`BMLayerItem`\n"
+);
+static PyObject *bpy_bmlayercollection_verify(BPy_BMLayerCollection *self)
+{
+ int index;
+ CustomData *data;
+
+ BPY_BM_CHECK_OBJ(self);
+
+ data = bpy_bm_customdata_get(self->bm, self->htype);
+
+ index = CustomData_get_layer_index(data, self->type);
+
+ if (index == -1) {
+ BM_data_layer_add(self->bm, data, self->type);
+ index = 0;
+ }
+ else {
+ index = CustomData_get_active_layer_index(data, self->type) - index; /* make relative */
+ }
+
+ BLI_assert(index >= 0);
+
+ return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
+}
PyDoc_STRVAR(bpy_bmlayercollection_new_doc,
".. method:: new(name)\n"
@@ -255,6 +348,14 @@ static PyObject *bpy_bmlayercollection_new(BPy_BMLayerCollection *self, PyObject
data = bpy_bm_customdata_get(self->bm, self->htype);
+ if (CustomData_layertype_is_singleton(self->type) &&
+ CustomData_has_layer(data, self->type))
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "layers.new(): is a singleton, use verify() instead");
+ return NULL;
+ }
+
if (name) {
BM_data_layer_add_named(self->bm, data, self->type, name);
}
@@ -451,7 +552,13 @@ static PyObject *bpy_bmlayercollection_get(BPy_BMLayerCollection *self, PyObject
return Py_INCREF(def), def;
}
+static struct PyMethodDef bpy_bmlayeritem_methods[] = {
+ {"copy_from", (PyCFunction)bpy_bmlayeritem_copy_from, METH_O, bpy_bmlayeritem_copy_from_doc},
+ {NULL, NULL, 0, NULL}
+};
+
static struct PyMethodDef bpy_bmelemseq_methods[] = {
+ {"verify", (PyCFunction)bpy_bmlayercollection_verify, METH_NOARGS, bpy_bmlayercollection_verify_doc},
{"new", (PyCFunction)bpy_bmlayercollection_new, METH_VARARGS, bpy_bmlayercollection_new_doc},
{"remove", (PyCFunction)bpy_bmlayercollection_remove, METH_O, bpy_bmlayercollection_remove_doc},
@@ -462,8 +569,6 @@ static struct PyMethodDef bpy_bmelemseq_methods[] = {
{NULL, NULL, 0, NULL}
};
-
-
/* Sequences
* ========= */
@@ -763,6 +868,7 @@ void BPy_BM_init_types_customdata(void)
// BPy_BMLayerAccess_Type.tp_methods = bpy_bmeditselseq_methods;
BPy_BMLayerCollection_Type.tp_methods = bpy_bmelemseq_methods;
+ BPy_BMLayerItem_Type.tp_methods = bpy_bmlayeritem_methods;
BPy_BMLayerCollection_Type.tp_as_sequence = &bpy_bmlayercollection_as_sequence;