diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 84b7307b820..e45d3a48047 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -44,15 +44,15 @@ #define SELECT 1 -typedef struct SearchFace { +typedef struct SortFace { unsigned int v[4]; unsigned int index; -} SearchFace; +} SortFace; typedef union { uint32_t verts[2]; int64_t edval; -} EdgeStore; +} EdgeUUID; static void edge_store_assign(uint32_t verts[2], const uint32_t v1, const uint32_t v2) { @@ -66,7 +66,7 @@ static void edge_store_assign(uint32_t verts[2], const uint32_t v1, const uint3 } } -static void edge_store_from_mface_quad(EdgeStore es[3], MFace *mf) +static void edge_store_from_mface_quad(EdgeUUID es[3], MFace *mf) { edge_store_assign(es[0].verts, mf->v1, mf->v2); edge_store_assign(es[1].verts, mf->v2, mf->v3); @@ -74,7 +74,7 @@ static void edge_store_from_mface_quad(EdgeStore es[3], MFace *mf) edge_store_assign(es[2].verts, mf->v4, mf->v1); } -static void edge_store_from_mface_tri(EdgeStore es[3], MFace *mf) +static void edge_store_from_mface_tri(EdgeUUID es[3], MFace *mf) { edge_store_assign(es[0].verts, mf->v1, mf->v2); edge_store_assign(es[1].verts, mf->v2, mf->v3); @@ -92,7 +92,7 @@ static int uint_cmp(const void *v1, const void *v2) static int search_face_cmp(const void *v1, const void *v2) { - const SearchFace *sfa= v1, *sfb= v2; + const SortFace *sfa= v1, *sfb= v2; if (sfa->v[0] > sfb->v[0]) return 1; else if (sfa->v[0] < sfb->v[0]) return -1; @@ -127,10 +127,10 @@ void BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), int totvert, MEdg EdgeHash *edge_hash = BLI_edgehash_new(); - SearchFace *search_faces= MEM_callocN(sizeof(SearchFace) * totface, "search faces"); - SearchFace *sf; - SearchFace *sf_prev; - int totsearchface= 0; + SortFace *sort_faces= MEM_callocN(sizeof(SortFace) * totface, "search faces"); + SortFace *sf; + SortFace *sf_prev; + int totsortface= 0; BLI_assert(!(do_fixes && me == NULL)); @@ -217,24 +217,24 @@ void BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), int totvert, MEdg } } - search_faces[totsearchface].index = i; + sort_faces[totsortface].index = i; if(mf->v4) { qsort(fverts, 4, sizeof(unsigned int), uint_cmp); - search_faces[i].v[0] = fverts[0]; - search_faces[i].v[1] = fverts[1]; - search_faces[i].v[2] = fverts[2]; - search_faces[i].v[3] = fverts[3]; + sort_faces[i].v[0] = fverts[0]; + sort_faces[i].v[1] = fverts[1]; + sort_faces[i].v[2] = fverts[2]; + sort_faces[i].v[3] = fverts[3]; } else { qsort(fverts, 3, sizeof(unsigned int), uint_cmp); - search_faces[i].v[0] = fverts[0]; - search_faces[i].v[1] = fverts[1]; - search_faces[i].v[2] = fverts[2]; - search_faces[i].v[3] = UINT_MAX; + sort_faces[i].v[0] = fverts[0]; + sort_faces[i].v[1] = fverts[1]; + sort_faces[i].v[2] = fverts[2]; + sort_faces[i].v[3] = UINT_MAX; } - totsearchface++; + totsortface++; } } if(remove) { @@ -242,13 +242,13 @@ void BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), int totvert, MEdg } } - qsort(search_faces, totsearchface, sizeof(SearchFace), search_face_cmp); + qsort(sort_faces, totsortface, sizeof(SortFace), search_face_cmp); - sf= search_faces; + sf= sort_faces; sf_prev= sf; sf++; - for(i=1; iv, sf_prev->v, sizeof(sf_prev->v)) == 0) { @@ -256,18 +256,18 @@ void BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), int totvert, MEdg MFace *mf= mfaces + sf->index; MFace *mf_prev= mfaces + sf_prev->index; - EdgeStore es[4]; - EdgeStore es_prev[4]; + EdgeUUID eu[4]; + EdgeUUID eu_prev[4]; if(mf->v4) { - edge_store_from_mface_quad(es, mf); - edge_store_from_mface_quad(es_prev, mf_prev); + edge_store_from_mface_quad(eu, mf); + edge_store_from_mface_quad(eu_prev, mf_prev); if( - ELEM4(es[0].edval, es_prev[0].edval, es_prev[1].edval, es_prev[2].edval, es_prev[3].edval) && - ELEM4(es[1].edval, es_prev[0].edval, es_prev[1].edval, es_prev[2].edval, es_prev[3].edval) && - ELEM4(es[2].edval, es_prev[0].edval, es_prev[1].edval, es_prev[2].edval, es_prev[3].edval) && - ELEM4(es[3].edval, es_prev[0].edval, es_prev[1].edval, es_prev[2].edval, es_prev[3].edval) + ELEM4(eu[0].edval, eu_prev[0].edval, eu_prev[1].edval, eu_prev[2].edval, eu_prev[3].edval) && + ELEM4(eu[1].edval, eu_prev[0].edval, eu_prev[1].edval, eu_prev[2].edval, eu_prev[3].edval) && + ELEM4(eu[2].edval, eu_prev[0].edval, eu_prev[1].edval, eu_prev[2].edval, eu_prev[3].edval) && + ELEM4(eu[3].edval, eu_prev[0].edval, eu_prev[1].edval, eu_prev[2].edval, eu_prev[3].edval) ) { PRINT(" face %d & %d: are duplicates ", sf->index, sf_prev->index); PRINT("(%d,%d,%d,%d) ", mf->v1, mf->v2, mf->v3, mf->v4); @@ -276,12 +276,12 @@ void BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), int totvert, MEdg } } else { - edge_store_from_mface_tri(es, mf); - edge_store_from_mface_tri(es_prev, mf); + edge_store_from_mface_tri(eu, mf); + edge_store_from_mface_tri(eu_prev, mf); if( - ELEM3(es[0].edval, es_prev[0].edval, es_prev[1].edval, es_prev[2].edval) && - ELEM3(es[1].edval, es_prev[0].edval, es_prev[1].edval, es_prev[2].edval) && - ELEM3(es[2].edval, es_prev[0].edval, es_prev[1].edval, es_prev[2].edval) + ELEM3(eu[0].edval, eu_prev[0].edval, eu_prev[1].edval, eu_prev[2].edval) && + ELEM3(eu[1].edval, eu_prev[0].edval, eu_prev[1].edval, eu_prev[2].edval) && + ELEM3(eu[2].edval, eu_prev[0].edval, eu_prev[1].edval, eu_prev[2].edval) ) { PRINT(" face %d & %d: are duplicates ", sf->index, sf_prev->index); PRINT("(%d,%d,%d) ", mf->v1, mf->v2, mf->v3); @@ -293,7 +293,7 @@ void BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), int totvert, MEdg if(remove) { REMOVE_FACE_TAG(mf); - /* keep sf_prev */ + /* keep sf_prev incase next face also matches*/ } else { sf_prev= sf; @@ -301,7 +301,7 @@ void BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), int totvert, MEdg } BLI_edgehash_free(edge_hash, NULL); - MEM_freeN(search_faces); + MEM_freeN(sort_faces); PRINT("BKE_mesh_validate: finished\n\n"); @@ -335,7 +335,6 @@ void BKE_mesh_validate_dm(DerivedMesh *dm) BKE_mesh_validate_arrays(NULL, dm->getVertArray(dm), dm->getNumVerts(dm), dm->getEdgeArray(dm), dm->getNumEdges(dm), dm->getFaceArray(dm), dm->getNumFaces(dm), TRUE, FALSE); } - void BKE_mesh_calc_edges(Mesh *mesh, int update) { CustomData edata; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 536e21b8f97..08a31923cda 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1116,6 +1116,15 @@ static int convert_exec(bContext *C, wmOperator *op) base->flag &= ~SELECT; ob->flag &= ~SELECT; } + + /* obdata already modified */ + if(!IS_TAGGED(ob->data)) { + /* When 2 objects with linked data are selected, converting both + * would keep modifiers on all but the converted object [#26003] */ + if(ob->type == OB_MESH) { + object_free_modifiers(ob); /* after derivedmesh calls! */ + } + } } else if (ob->type==OB_MESH && target == OB_CURVE) { ob->flag |= OB_DONE; diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index a3d75e0376a..27b4ea7a6bd 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -221,7 +221,7 @@ add_test(export_3ds_all_objects ${EXECUTABLE_OUTPUT_PATH}/blender ${GENERIC_ARGS --python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py -- --run={'FINISHED'}&bpy.ops.export_scene.autodesk_3ds\(filepath='${TEST_OUT_DIR}/export_3ds_all_objects.3ds',use_selection=False\) --md5_source=${TEST_OUT_DIR}/export_3ds_all_objects.3ds - --md5=1523ca2e31cf7d781c7de1e17bd14520 --md5_method=FILE + --md5=87349a4699f1006e8194fb0ac05ac9c8 --md5_method=FILE ) @@ -249,5 +249,5 @@ add_test(export_fbx_all_objects ${EXECUTABLE_OUTPUT_PATH}/blender ${GENERIC_ARGS --python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py -- --run={'FINISHED'}&bpy.ops.export_scene.fbx\(filepath='${TEST_OUT_DIR}/export_fbx_all_objects.fbx',use_selection=False,use_metadata=False\) --md5_source=${TEST_OUT_DIR}/export_fbx_all_objects.fbx - --md5=1b829a528f9bdfc054f5d70f455855ad --md5_method=FILE + --md5=be69cf0baf51dcf43f579183310cb383 --md5_method=FILE )