From d97b97460ca9a28027041e5666dbfeb3a5295155 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 26 Mar 2015 09:20:37 +0100 Subject: Fix T44138: Crash in DataTransfer modifier when selecting a source with no loops. Simply check and early return in case we have no source or destination items (verts/edges/loops/polys) available... Also, fix an assert in `BKE_mesh_calc_normals_poly()`, when called with no poly. --- source/blender/blenkernel/intern/data_transfer.c | 40 +++++++++++++++++++++--- source/blender/blenkernel/intern/mesh_evaluate.c | 4 +-- 2 files changed, 38 insertions(+), 6 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c index 8f6d4385b55..da00aecf9c0 100644 --- a/source/blender/blenkernel/intern/data_transfer.c +++ b/source/blender/blenkernel/intern/data_transfer.c @@ -1157,12 +1157,20 @@ bool BKE_object_data_transfer_dm( const int num_verts_dst = dm_dst ? dm_dst->getNumVerts(dm_dst) : me_dst->totvert; if (!geom_map_init[VDATA]) { - if ((map_vert_mode == MREMAP_MODE_TOPOLOGY) && (num_verts_dst != dm_src->getNumVerts(dm_src))) { + const int num_verts_src = dm_src->getNumVerts(dm_src); + + if ((map_vert_mode == MREMAP_MODE_TOPOLOGY) && (num_verts_dst != num_verts_src)) { BKE_report(reports, RPT_ERROR, "Source and destination meshes do not have the same amount of vertices, " "'Topology' mapping cannot be used in this case"); return changed; } + if (ELEM(0, num_verts_dst, num_verts_src)) { + BKE_report(reports, RPT_ERROR, + "Source or destination meshes do not have any vertices, cannot transfer vertex data"); + return changed; + } + BKE_mesh_remap_calc_verts_from_dm( map_vert_mode, space_transform, max_distance, ray_radius, verts_dst, num_verts_dst, dirty_nors_dst, dm_src, &geom_map[VDATA]); @@ -1197,12 +1205,20 @@ bool BKE_object_data_transfer_dm( const int num_edges_dst = dm_dst ? dm_dst->getNumEdges(dm_dst) : me_dst->totedge; if (!geom_map_init[EDATA]) { - if ((map_edge_mode == MREMAP_MODE_TOPOLOGY) && (num_edges_dst != dm_src->getNumEdges(dm_src))) { + const int num_edges_src = dm_src->getNumEdges(dm_src); + + if ((map_edge_mode == MREMAP_MODE_TOPOLOGY) && (num_edges_dst != num_edges_src)) { BKE_report(reports, RPT_ERROR, "Source and destination meshes do not have the same amount of edges, " "'Topology' mapping cannot be used in this case"); return changed; } + if (ELEM(0, num_edges_dst, num_edges_src)) { + BKE_report(reports, RPT_ERROR, + "Source or destination meshes do not have any edges, cannot transfer edge data"); + return changed; + } + BKE_mesh_remap_calc_edges_from_dm( map_edge_mode, space_transform, max_distance, ray_radius, verts_dst, num_verts_dst, edges_dst, num_edges_dst, dirty_nors_dst, @@ -1248,12 +1264,20 @@ bool BKE_object_data_transfer_dm( MeshRemapIslandsCalc island_callback = data_transfer_get_loop_islands_generator(cddata_type); if (!geom_map_init[LDATA]) { - if ((map_loop_mode == MREMAP_MODE_TOPOLOGY) && (num_loops_dst != dm_src->getNumLoops(dm_src))) { + const int num_loops_src = dm_src->getNumLoops(dm_src); + + if ((map_loop_mode == MREMAP_MODE_TOPOLOGY) && (num_loops_dst != num_loops_src)) { BKE_report(reports, RPT_ERROR, "Source and destination meshes do not have the same amount of face corners, " "'Topology' mapping cannot be used in this case"); return changed; } + if (ELEM(0, num_loops_dst, num_loops_src)) { + BKE_report(reports, RPT_ERROR, + "Source or destination meshes do not have any polygons, cannot transfer loop data"); + return changed; + } + BKE_mesh_remap_calc_loops_from_dm( map_loop_mode, space_transform, max_distance, ray_radius, verts_dst, num_verts_dst, edges_dst, num_edges_dst, @@ -1298,12 +1322,20 @@ bool BKE_object_data_transfer_dm( CustomData *pdata_dst = dm_dst ? dm_dst->getPolyDataLayout(dm_dst) : &me_dst->pdata; if (!geom_map_init[PDATA]) { - if ((map_poly_mode == MREMAP_MODE_TOPOLOGY) && (num_polys_dst != dm_src->getNumPolys(dm_src))) { + const int num_polys_src = dm_src->getNumPolys(dm_src); + + if ((map_poly_mode == MREMAP_MODE_TOPOLOGY) && (num_polys_dst != num_polys_src)) { BKE_report(reports, RPT_ERROR, "Source and destination meshes do not have the same amount of faces, " "'Topology' mapping cannot be used in this case"); return changed; } + if (ELEM(0, num_polys_dst, num_polys_src)) { + BKE_report(reports, RPT_ERROR, + "Source or destination meshes do not have any polygons, cannot transfer poly data"); + return changed; + } + BKE_mesh_remap_calc_polys_from_dm( map_poly_mode, space_transform, max_distance, ray_radius, verts_dst, num_verts_dst, loops_dst, num_loops_dst, diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 6c835a72a40..ceb9b016ff2 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -226,7 +226,7 @@ void BKE_mesh_calc_normals_poly(MVert *mverts, int numVerts, MLoop *mloop, MPoly MPoly *mp; if (only_face_normals) { - BLI_assert(pnors != NULL); + BLI_assert((pnors != NULL) || (numPolys == 0)); #pragma omp parallel for if (numPolys > BKE_MESH_OMP_LIMIT) for (i = 0; i < numPolys; i++) { @@ -252,12 +252,12 @@ void BKE_mesh_calc_normals_poly(MVert *mverts, int numVerts, MLoop *mloop, MPoly } } - /* following Mesh convention; we use vertex coordinate itself for normal in this case */ for (i = 0; i < numVerts; i++) { MVert *mv = &mverts[i]; float *no = tnorms[i]; if (UNLIKELY(normalize_v3(no) == 0.0f)) { + /* following Mesh convention; we use vertex coordinate itself for normal in this case */ normalize_v3_v3(no, mv->co); } -- cgit v1.2.3