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!
This commit is contained in:
parent
c30c3fde51
commit
930fc7d157
|
@ -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--) {
|
||||
|
|
Loading…
Reference in New Issue