diff options
Diffstat (limited to 'source/blender/python/bmesh/bmesh_py_types.c')
-rw-r--r-- | source/blender/python/bmesh/bmesh_py_types.c | 265 |
1 files changed, 222 insertions, 43 deletions
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 5db9962e690..052496e3ed7 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -50,6 +50,8 @@ #include "bmesh_py_types_customdata.h" #include "bmesh_py_types_meshdata.h" +static void bm_dealloc_editmode_warn(BPy_BMesh *self); + /* Common Flags * ************ */ @@ -77,11 +79,11 @@ PyC_FlagSet bpy_bm_htype_all_flags[] = { }; PyC_FlagSet bpy_bm_hflag_all_flags[] = { - {BM_ELEM_SELECT, "SELECT"}, - {BM_ELEM_HIDDEN, "HIDE"}, - {BM_ELEM_SEAM, "SEAM"}, - {BM_ELEM_SMOOTH, "SMOOTH"}, - {BM_ELEM_TAG, "TAG"}, + {BM_ELEM_SELECT, "SELECT"}, + {BM_ELEM_HIDDEN, "HIDE"}, + {BM_ELEM_SEAM, "SEAM"}, + {BM_ELEM_SMOOTH, "SMOOTH"}, + {BM_ELEM_TAG, "TAG"}, {0, NULL} }; @@ -101,7 +103,6 @@ PyDoc_STRVAR(bpy_bm_elem_tag_doc, "Generic attribute scripts can use for own PyDoc_STRVAR(bpy_bm_elem_smooth_doc, "Smooth state of this element.\n\n:type: boolean"); PyDoc_STRVAR(bpy_bm_elem_seam_doc, "Seam for UV unwrapping.\n\n:type: boolean"); - static PyObject *bpy_bm_elem_hflag_get(BPy_BMElem *self, void *flag) { const char hflag = (char)GET_INT_FROM_POINTER(flag); @@ -120,11 +121,11 @@ static int bpy_bm_elem_hflag_set(BPy_BMElem *self, PyObject *value, void *flag) param = PyLong_AsLong(value); - if (param == TRUE) { + if (param == true) { BM_elem_flag_enable(self->ele, hflag); return 0; } - else if (param == FALSE) { + else if (param == false) { BM_elem_flag_disable(self->ele, hflag); return 0; } @@ -412,6 +413,14 @@ static PyObject *bpy_bmedge_is_manifold_get(BPy_BMEdge *self) return PyBool_FromLong(BM_edge_is_manifold(self->e)); } +PyDoc_STRVAR(bpy_bmedge_is_contiguous_doc, +"True when this edge is manifold, between two faces with the same winding (read-only).\n\n:type: boolean" +); +static PyObject *bpy_bmedge_is_contiguous_get(BPy_BMEdge *self) +{ + BPY_BM_CHECK_OBJ(self); + return PyBool_FromLong(BM_edge_is_contiguous(self->e)); +} PyDoc_STRVAR(bpy_bmedge_is_wire_doc, "True when this edge is not connected to any faces (read-only).\n\n:type: boolean" @@ -432,6 +441,47 @@ static PyObject *bpy_bmedge_is_boundary_get(BPy_BMEdge *self) return PyBool_FromLong(BM_edge_is_boundary(self->e)); } +#ifdef WITH_FREESTYLE +PyDoc_STRVAR(bpy_bmedge_freestyle_edge_mark_doc, +"Freestyle edge mark.\n\n:type: boolean" +); +static PyObject *bpy_bmedge_freestyle_edge_mark_get(BPy_BMEdge *self) +{ + FreestyleEdge *fed; + + BPY_BM_CHECK_OBJ(self); + fed = CustomData_bmesh_get(&self->bm->edata, self->e->head.data, CD_FREESTYLE_EDGE); + return PyBool_FromLong(fed->flag & FREESTYLE_EDGE_MARK); +} + +static int bpy_bmedge_freestyle_edge_mark_set(BPy_BMEdge *self, PyObject *value) +{ + int param; + FreestyleEdge *fed; + + BPY_BM_CHECK_INT(self); + + param = PyLong_AsLong(value); + if (param != false && param != true) { + PyErr_SetString(PyExc_TypeError, + "expected a boolean type 0/1"); + return -1; + } + + if (!CustomData_has_layer(&self->bm->edata, CD_FREESTYLE_EDGE)) { + BM_data_layer_add(self->bm, &self->bm->edata, CD_FREESTYLE_EDGE); + } + + fed = CustomData_bmesh_get(&self->bm->edata, self->e->head.data, CD_FREESTYLE_EDGE); + if (param) + fed->flag &= ~FREESTYLE_EDGE_MARK; + else + fed->flag |= FREESTYLE_EDGE_MARK; + + return 0; +} +#endif + /* Face * ^^^^ */ @@ -491,6 +541,48 @@ static int bpy_bmface_material_index_set(BPy_BMFace *self, PyObject *value) } } +#ifdef WITH_FREESTYLE +PyDoc_STRVAR(bpy_bmface_freestyle_face_mark_doc, +"Freestyle face mark.\n\n:type: boolean" +); +static PyObject *bpy_bmface_freestyle_face_mark_get(BPy_BMFace *self) +{ + FreestyleFace *ffa; + + BPY_BM_CHECK_OBJ(self); + ffa = CustomData_bmesh_get(&self->bm->pdata, self->f->head.data, CD_FREESTYLE_FACE); + return PyBool_FromLong(ffa->flag & FREESTYLE_FACE_MARK); +} + +static int bpy_bmface_freestyle_face_mark_set(BPy_BMFace *self, PyObject *value) +{ + int param; + FreestyleFace *ffa; + + BPY_BM_CHECK_INT(self); + + param = PyLong_AsLong(value); + if (param != false && param != true) { + PyErr_SetString(PyExc_TypeError, + "expected a boolean type 0/1"); + return -1; + } + + if (!CustomData_has_layer(&self->bm->pdata, CD_FREESTYLE_FACE)) { + BM_data_layer_add(self->bm, &self->bm->pdata, CD_FREESTYLE_FACE); + } + + ffa = CustomData_bmesh_get(&self->bm->pdata, self->f->head.data, CD_FREESTYLE_FACE); + if (param) + ffa->flag &= ~FREESTYLE_FACE_MARK; + else + ffa->flag |= FREESTYLE_FACE_MARK; + + return 0; +} +#endif + + /* Loop * ^^^^ */ @@ -559,6 +651,15 @@ static PyObject *bpy_bmloop_link_loop_radial_prev_get(BPy_BMLoop *self) return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_prev); } +PyDoc_STRVAR(bpy_bm_is_convex_doc, +"True when this loop is at the convex corner of a face, depends on a valid face normal (read-only).\n\n:type: :class:`BMLoop`" +); +static PyObject *bpy_bm_is_convex_get(BPy_BMLoop *self) +{ + BPY_BM_CHECK_OBJ(self); + return PyBool_FromLong(BM_loop_is_convex(self->l)); +} + /* ElemSeq * ^^^^^^^ */ @@ -662,6 +763,10 @@ static PyGetSetDef bpy_bmedge_getseters[] = { {(char *)"smooth", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_smooth_doc, (void *)BM_ELEM_SMOOTH}, {(char *)"seam", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_seam_doc, (void *)BM_ELEM_SEAM}, +#ifdef WITH_FREESTYLE + {(char *)"freestyle_edge_mark", (getter)bpy_bmedge_freestyle_edge_mark_get, (setter)bpy_bmedge_freestyle_edge_mark_set, (char *)bpy_bmedge_freestyle_edge_mark_doc, NULL}, +#endif + /* connectivity data */ {(char *)"verts", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmedge_verts_doc, (void *)BM_VERTS_OF_EDGE}, @@ -669,10 +774,11 @@ static PyGetSetDef bpy_bmedge_getseters[] = { {(char *)"link_loops", (getter)bpy_bmelemseq_elem_get, (setter)NULL, (char *)bpy_bmedge_link_loops_doc, (void *)BM_LOOPS_OF_EDGE}, /* readonly checks */ - {(char *)"is_manifold", (getter)bpy_bmedge_is_manifold_get, (setter)NULL, (char *)bpy_bmedge_is_manifold_doc, NULL}, - {(char *)"is_wire", (getter)bpy_bmedge_is_wire_get, (setter)NULL, (char *)bpy_bmedge_is_wire_doc, NULL}, + {(char *)"is_manifold", (getter)bpy_bmedge_is_manifold_get, (setter)NULL, (char *)bpy_bmedge_is_manifold_doc, NULL}, + {(char *)"is_contiguous", (getter)bpy_bmedge_is_contiguous_get, (setter)NULL, (char *)bpy_bmedge_is_contiguous_doc, NULL}, + {(char *)"is_wire", (getter)bpy_bmedge_is_wire_get, (setter)NULL, (char *)bpy_bmedge_is_wire_doc, NULL}, {(char *)"is_boundary", (getter)bpy_bmedge_is_boundary_get, (setter)NULL, (char *)bpy_bmedge_is_boundary_doc, NULL}, - {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL}, + {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -686,6 +792,10 @@ static PyGetSetDef bpy_bmface_getseters[] = { {(char *)"smooth", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_smooth_doc, (void *)BM_ELEM_SMOOTH}, +#ifdef WITH_FREESTYLE + {(char *)"freestyle_face_mark", (getter)bpy_bmface_freestyle_face_mark_get, (setter)bpy_bmface_freestyle_face_mark_set, (char *)bpy_bmface_freestyle_face_mark_doc, NULL}, +#endif + {(char *)"normal", (getter)bpy_bmface_normal_get, (setter)bpy_bmface_normal_set, (char *)bpy_bmface_normal_doc, NULL}, {(char *)"material_index", (getter)bpy_bmface_material_index_get, (setter)bpy_bmface_material_index_set, (char *)bpy_bmface_material_index_doc, NULL}, @@ -721,7 +831,8 @@ static PyGetSetDef bpy_bmloop_getseters[] = { {(char *)"link_loop_radial_prev", (getter)bpy_bmloop_link_loop_radial_prev_get, (setter)NULL, (char *)bpy_bmloop_link_loop_radial_prev_doc, NULL}, /* readonly checks */ - {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL}, + {(char *)"is_convex", (getter)bpy_bm_is_convex_get, (setter)NULL, (char *)bpy_bm_is_convex_doc, NULL}, + {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -813,6 +924,8 @@ static PyObject *bpy_bmesh_free(BPy_BMesh *self) if (self->bm) { BMesh *bm = self->bm; + bm_dealloc_editmode_warn(self); + if ((self->flag & BPY_BMFLAG_IS_WRAPPED) == 0) { BM_mesh_free(bm); } @@ -854,7 +967,7 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args) bm = self->bm; - BM_mesh_bm_to_me(bm, me, FALSE); + BM_mesh_bm_to_me(bm, me, false); /* we could have the user do this but if they forget blender can easy crash * since the references arrays for the objects derived meshes are now invalid */ @@ -884,9 +997,9 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args) Object *ob; struct Scene *scene; BMesh *bm; - int use_deform = TRUE; - int use_render = FALSE; - int use_cage = FALSE; + int use_deform = true; + int use_render = false; + int use_cage = false; DerivedMesh *dm; const int mask = CD_MASK_BMESH; @@ -984,7 +1097,7 @@ static PyObject *bpy_bmesh_from_mesh(BPy_BMesh *self, PyObject *args, PyObject * BMesh *bm; PyObject *py_mesh; Mesh *me; - int use_shape_key = FALSE; + int use_shape_key = false; int shape_key_index = 0; if (!PyArg_ParseTupleAndKeywords(args, kw, "O|ii:from_mesh", (char **)kwlist, @@ -1032,7 +1145,7 @@ static PyObject *bpy_bmesh_select_flush(BPy_BMesh *self, PyObject *value) BPY_BM_CHECK_OBJ(self); param = PyLong_AsLong(value); - if (param != FALSE && param != TRUE) { + if (param != false && param != true) { PyErr_SetString(PyExc_TypeError, "expected a boolean type 0/1"); return NULL; @@ -1056,7 +1169,7 @@ PyDoc_STRVAR(bpy_bmesh_normal_update_doc, static PyObject *bpy_bmesh_normal_update(BPy_BMesh *self, PyObject *args) { - int skip_hidden = FALSE; + int skip_hidden = false; BPY_BM_CHECK_OBJ(self); @@ -1163,7 +1276,7 @@ static PyObject *bpy_bm_elem_select_set(BPy_BMElem *self, PyObject *value) BPY_BM_CHECK_OBJ(self); param = PyLong_AsLong(value); - if (param != FALSE && param != TRUE) { + if (param != false && param != true) { PyErr_SetString(PyExc_TypeError, "expected a boolean type 0/1"); return NULL; @@ -1191,7 +1304,7 @@ static PyObject *bpy_bm_elem_hide_set(BPy_BMElem *self, PyObject *value) BPY_BM_CHECK_OBJ(self); param = PyLong_AsLong(value); - if (param != FALSE && param != TRUE) { + if (param != false && param != true) { PyErr_SetString(PyExc_TypeError, "expected a boolean type 0/1"); return NULL; @@ -1258,7 +1371,7 @@ static PyObject *bpy_bmvert_copy_from_vert_interp(BPy_BMVert *self, PyObject *ar vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, - TRUE, TRUE, "BMVert.copy_from_vert_interp(...)"); + true, true, "BMVert.copy_from_vert_interp(...)"); if (vert_array == NULL) { return NULL; @@ -1508,8 +1621,8 @@ static PyObject *bpy_bmface_copy(BPy_BMFace *self, PyObject *args, PyObject *kw) static const char *kwlist[] = {"verts", "edges", NULL}; BMesh *bm = self->bm; - int do_verts = TRUE; - int do_edges = TRUE; + int do_verts = true; + int do_edges = true; BMFace *f_cpy; BPY_BM_CHECK_OBJ(self); @@ -1616,6 +1729,21 @@ static PyObject *bpy_bmface_normal_update(BPy_BMFace *self) } +PyDoc_STRVAR(bpy_bmface_normal_flip_doc, +".. method:: normal_flip()\n" +"\n" +" Reverses winding of a face, which flips its normal.\n" +); +static PyObject *bpy_bmface_normal_flip(BPy_BMFace *self) +{ + BPY_BM_CHECK_OBJ(self); + + BM_face_normal_flip(self->bm, self->f); + + Py_RETURN_NONE; +} + + /* Loop * ---- */ @@ -1634,8 +1762,8 @@ PyDoc_STRVAR(bpy_bmloop_copy_from_face_interp_doc, static PyObject *bpy_bmloop_copy_from_face_interp(BPy_BMLoop *self, PyObject *args) { BPy_BMFace *py_face = NULL; - int do_vertex = TRUE; - int do_multires = TRUE; + int do_vertex = true; + int do_multires = true; BPY_BM_CHECK_OBJ(self); @@ -1803,7 +1931,7 @@ static PyObject *bpy_bmedgeseq_new(BPy_BMElemSeq *self, PyObject *args) vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, - TRUE, TRUE, "edges.new(...)"); + true, true, "edges.new(...)"); if (vert_array == NULL) { return NULL; @@ -1881,7 +2009,7 @@ static PyObject *bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args) vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 3, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, - TRUE, TRUE, "faces.new(...)"); + true, true, "faces.new(...)"); if (vert_array == NULL) { return NULL; @@ -2034,7 +2162,7 @@ static PyObject *bpy_bmedgeseq_get__method(BPy_BMElemSeq *self, PyObject *args) vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, - TRUE, TRUE, "edges.get(...)"); + true, true, "edges.get(...)"); if (vert_array == NULL) { return NULL; @@ -2086,7 +2214,7 @@ static PyObject *bpy_bmfaceseq_get__method(BPy_BMElemSeq *self, PyObject *args) vert_array = BPy_BMElem_PySeq_As_Array(&bm, vert_seq, 1, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, - TRUE, TRUE, "faces.get(...)"); + true, true, "faces.get(...)"); if (vert_array == NULL) { return NULL; @@ -2213,7 +2341,7 @@ static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObjec { static const char *kwlist[] = {"key", "reverse", NULL}; PyObject *keyfunc = NULL; /* optional */ - int reverse = FALSE; /* optional */ + int do_reverse = false; /* optional */ const char htype = bm_iter_itype_htype_map[self->itype]; int n_elem; @@ -2238,7 +2366,7 @@ static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObjec if (!PyArg_ParseTupleAndKeywords(args, kw, "|Oi:BMElemSeq.sort", (char **)kwlist, - &keyfunc, &reverse)) + &keyfunc, &do_reverse)) { return NULL; } @@ -2308,7 +2436,7 @@ static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, PyObjec range_vn_i(elem_idx, n_elem, 0); /* Sort the index array according to the order of the 'keys' array */ - if (reverse) + if (do_reverse) elem_idx_compare_by_keys = bpy_bmelemseq_sort_cmp_by_keys_descending; else elem_idx_compare_by_keys = bpy_bmelemseq_sort_cmp_by_keys_ascending; @@ -2424,6 +2552,7 @@ static struct PyMethodDef bpy_bmface_methods[] = { {"calc_center_bounds", (PyCFunction)bpy_bmface_calc_center_bounds, METH_NOARGS, bpy_bmface_calc_center_bounds_doc}, {"normal_update", (PyCFunction)bpy_bmface_normal_update, METH_NOARGS, bpy_bmface_normal_update_doc}, + {"normal_flip", (PyCFunction)bpy_bmface_normal_flip, METH_NOARGS, bpy_bmface_normal_flip_doc}, {NULL, NULL, 0, NULL} }; @@ -2585,7 +2714,7 @@ static PyObject *bpy_bmelemseq_subscript_slice(BPy_BMElemSeq *self, Py_ssize_t s { BMIter iter; int count = 0; - int ok; + bool ok; PyObject *list; PyObject *item; @@ -2597,14 +2726,14 @@ static PyObject *bpy_bmelemseq_subscript_slice(BPy_BMElemSeq *self, Py_ssize_t s ok = BM_iter_init(&iter, self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL); - BLI_assert(ok == TRUE); + BLI_assert(ok == true); - if (UNLIKELY(ok == FALSE)) { + if (UNLIKELY(ok == false)) { return list; } /* first loop up-until the start */ - for (ok = TRUE; ok; ok = (BM_iter_step(&iter) != NULL)) { + for (ok = true; ok; ok = (BM_iter_step(&iter) != NULL)) { if (count == start) { break; } @@ -2778,6 +2907,8 @@ static void bpy_bmesh_dealloc(BPy_BMesh *self) /* have have been freed by bmesh */ if (bm) { + bm_dealloc_editmode_warn(self); + 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); @@ -3403,7 +3534,7 @@ int bpy_bm_generic_valid_check(BPy_BMGeneric *self) * function where the actual error will be caused by * the previous action. */ #if 0 - if (BM_mesh_validate(self->bm) == FALSE) { + if (BM_mesh_validate(self->bm) == false) { PyErr_Format(PyExc_ReferenceError, "BMesh used by %.200s has become invalid", Py_TYPE(self)->tp_name); @@ -3448,7 +3579,7 @@ void bpy_bm_generic_invalidate(BPy_BMGeneric *self) */ void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size, const char htype, - const char do_unique_check, const char do_bm_check, + const bool do_unique_check, const bool do_bm_check, const char *error_prefix) { BMesh *bm = (r_bm && *r_bm) ? *r_bm : NULL; @@ -3515,17 +3646,17 @@ void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ if (do_unique_check) { /* check for double verts! */ - int ok = TRUE; + bool ok = true; for (i = 0; i < seq_len; i++) { - if (UNLIKELY(BM_elem_flag_test(alloc[i], BM_ELEM_INTERNAL_TAG) == FALSE)) { - ok = FALSE; + if (UNLIKELY(BM_elem_flag_test(alloc[i], BM_ELEM_INTERNAL_TAG) == false)) { + ok = false; } /* ensure we don't leave this enabled */ BM_elem_flag_disable(alloc[i], BM_ELEM_INTERNAL_TAG); } - if (ok == FALSE) { + if (ok == false) { PyErr_Format(PyExc_ValueError, "%s: found the same %.200s used multiple times", error_prefix, BPy_BMElem_StringFromHType(htype)); @@ -3588,3 +3719,51 @@ char *BPy_BMElem_StringFromHType(const char htype) static char ret[32]; return BPy_BMElem_StringFromHType_ex(htype, ret); } + + +/* -------------------------------------------------------------------- */ +/* keep at bottom */ +/* BAD INCLUDES */ + +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_tessmesh.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_mesh_types.h" +#include "MEM_guardedalloc.h" + +/* there are cases where this warning isnt needed, otherwise it could be made into an error */ +static void bm_dealloc_warn(const char *mesh_name) +{ + PySys_WriteStdout("Modified BMesh '%.200s' from a wrapped editmesh is freed without a call " + "to bmesh.update_edit_mesh(mesh, destructive=True), this is will likely cause a crash\n", + mesh_name); +} + +/* this function is called on free, it should stay quite fast */ +static void bm_dealloc_editmode_warn(BPy_BMesh *self) +{ + if (self->flag & BPY_BMFLAG_IS_WRAPPED) { + /* likely editmesh */ + BMesh *bm = self->bm; + Scene *scene; + for (scene = G.main->scene.first; scene; scene = scene->id.next) { + Base *base = scene->basact; + if (base && base->object->type == OB_MESH) { + Mesh *me = base->object->data; + BMEditMesh *em = me->edit_btmesh; + if (em && em->bm == bm) { + /* not foolproof, scripter may have added/removed verts */ + if (((em->vert_index && (MEM_allocN_len(em->vert_index) / sizeof(*em->vert_index)) != bm->totvert)) || + ((em->edge_index && (MEM_allocN_len(em->edge_index) / sizeof(*em->edge_index)) != bm->totedge)) || + ((em->face_index && (MEM_allocN_len(em->face_index) / sizeof(*em->face_index)) != bm->totface))) + { + bm_dealloc_warn(me->id.name + 2); + break; + } + } + } + } + } +} |