From 930fc7d1575304977b4a82b1986d2d8db0498e50 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 7 Aug 2015 16:14:54 +0200 Subject: Mesh remap: Fix two potential numeric issues in corner cases, and enhance poly projection. Null-area face could generate an int overflow, and potential numerical imprecision in face area computation could lead to negative number of rays-to-cast (though highly unlikely). Also, use domnant axis of poly normal as 'flattening' one, instead of always using Z axis. Points raised by Campbell, thanks! --- source/blender/blenkernel/intern/mesh_remap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c index 978ea37a8cc..827a1bf895f 100644 --- a/source/blender/blenkernel/intern/mesh_remap.c +++ b/source/blender/blenkernel/intern/mesh_remap.c @@ -2106,7 +2106,6 @@ void BKE_mesh_remap_calc_polys_from_dm( int tot_rays, done_rays = 0; float poly_area_2d_inv, done_area = 0.0f; - const float zvec[3] = {0.0f, 0.0f, 1.0f}; float pcent_dst[3]; float to_pnor_2d_mat[3][3], from_pnor_2d_mat[3][3]; float poly_dst_2d_min[2], poly_dst_2d_max[2], poly_dst_2d_z; @@ -2135,7 +2134,7 @@ void BKE_mesh_remap_calc_polys_from_dm( tri_vidx_2d = MEM_reallocN(tri_vidx_2d, sizeof(*tri_vidx_2d) * (tmp_poly_size - 2)); } - rotation_between_vecs_to_mat3(to_pnor_2d_mat, tmp_no, zvec); + axis_dominant_v3_to_m3(to_pnor_2d_mat, tmp_no); invert_m3_m3(from_pnor_2d_mat, to_pnor_2d_mat); mul_m3_v3(to_pnor_2d_mat, pcent_dst); @@ -2168,7 +2167,9 @@ void BKE_mesh_remap_calc_polys_from_dm( } tot_rays *= tot_rays; - poly_area_2d_inv = 1.0f / area_poly_v2((const float(*)[2])poly_vcos_2d, (unsigned int)mp->totloop); + poly_area_2d_inv = area_poly_v2((const float(*)[2])poly_vcos_2d, (unsigned int)mp->totloop); + /* In case we have a null-area degenerated poly... */ + poly_area_2d_inv = 1.0f / max_ff(poly_area_2d_inv, 1e-9f); /* Tessellate our poly. */ if (mp->totloop == 3) { @@ -2198,7 +2199,7 @@ void BKE_mesh_remap_calc_polys_from_dm( /* All this allows us to get 'absolute' number of rays for each tri, avoiding accumulating * errors over iterations, and helping better even distribution. */ done_area += area_tri_v2(v1, v2, v3); - rays_num = (int)((float)tot_rays * done_area * poly_area_2d_inv + 0.5f) - done_rays; + rays_num = max_ii((int)((float)tot_rays * done_area * poly_area_2d_inv + 0.5f) - done_rays, 0); done_rays += rays_num; while (rays_num--) { -- cgit v1.2.3