diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-06-26 08:17:41 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-06-26 08:17:41 +0400 |
commit | c0c9f5386bac539e3824a5a97bd2243484598594 (patch) | |
tree | e1b40ad75e51f7c76707b7506312a11339742f4e /source | |
parent | 7d608452d0c10da9b71ca37cb3bdbdfe0e5ebe36 (diff) |
fix [#35507] BMesh module: Crash on to_mesh() if faces.layers.tex is used but no loops.layers.uv
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh_conv.c | 36 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh_conv.h | 1 | ||||
-rw-r--r-- | source/blender/python/bmesh/bmesh_py_api.c | 6 | ||||
-rw-r--r-- | source/blender/python/bmesh/bmesh_py_types.c | 3 |
4 files changed, 46 insertions, 0 deletions
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 9d330075a3a..7c4af8eaa3b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -98,6 +98,42 @@ #include "bmesh.h" #include "intern/bmesh_private.h" /* for element checking */ +/** + * Currently this is only used for Python scripts + * which may fail to keep matching UV/TexFace layers. + * + * \note This should only perform any changes in exceptional cases, + * if we need this to be faster we could inline #BM_data_layer_add and only + * call #update_data_blocks once at the end. + */ +void BM_mesh_cd_validate(BMesh *bm) +{ + int totlayer_mtex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); + int totlayer_uv = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV); + + if (LIKELY(totlayer_mtex == totlayer_uv)) { + /* pass */ + } + else if (totlayer_mtex < totlayer_uv) { + const int uv_index_first = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV); + do { + const char *from_name = bm->ldata.layers[uv_index_first + totlayer_mtex].name; + BM_data_layer_add_named(bm, &bm->pdata, CD_MTEXPOLY, from_name); + CustomData_set_layer_unique_name(&bm->pdata, totlayer_mtex); + } while (totlayer_uv != ++totlayer_mtex); + } + else if (totlayer_uv < totlayer_mtex) { + const int mtex_index_first = CustomData_get_layer_index(&bm->pdata, CD_MTEXPOLY); + do { + const char *from_name = bm->pdata.layers[mtex_index_first + totlayer_uv].name; + BM_data_layer_add_named(bm, &bm->ldata, CD_MLOOPUV, from_name); + CustomData_set_layer_unique_name(&bm->ldata, totlayer_uv); + } while (totlayer_mtex != ++totlayer_uv); + } + + BLI_assert(totlayer_mtex == totlayer_uv); +} + void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag) { const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag; diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h index 754ae8bcad4..ab9d7a0ccf3 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.h +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h @@ -34,6 +34,7 @@ struct Mesh; +void BM_mesh_cd_validate(BMesh *bm); void BM_mesh_cd_flag_ensure(BMesh *bm, struct Mesh *mesh, const char cd_flag); void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag); char BM_mesh_cd_flag_from_bmesh(BMesh *bm); diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c index 99fd3429973..c7b10d0aa4b 100644 --- a/source/blender/python/bmesh/bmesh_py_api.c +++ b/source/blender/python/bmesh/bmesh_py_api.c @@ -138,6 +138,12 @@ static PyObject *bpy_bm_update_edit_mesh(PyObject *UNUSED(self), PyObject *args, { extern void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_destructive); + BMEditMesh *em = me->edit_btmesh; + BMesh *bm = em->bm; + + /* python won't ensure matching uv/mtex */ + BM_mesh_cd_validate(bm); + EDBM_update_generic(me->edit_btmesh, do_tessface, is_destructive); } diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 6ea8d6c68ce..0db8b07d5f5 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -907,6 +907,9 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args) bm = self->bm; + /* python won't ensure matching uv/mtex */ + BM_mesh_cd_validate(bm); + BM_mesh_bm_to_me(bm, me, false); /* we could have the user do this but if they forget blender can easy crash |