Fix T93084: Area stretch overlay full red on large scale mesh

Issue arises when face areas are really large combined with small UV
areas (report has a mesh ~1.5 km), then precission of shorts is
insufficient.

Now use floats instead.
This also removes this negative signed version of the total area ratio
(since with floats it is no longer used).

Thx @brecht for a lot of hand-holding!

NOTE: this is an alternative to D15805 (and quick tests show this does
not introduce the tiny performance hit as D15805 did).

Maniphest Tasks: T93084

Differential Revision: https://developer.blender.org/D15810
This commit is contained in:
Philipp Oeser 2022-08-30 13:35:03 +02:00
parent 3306b4a86b
commit f20d0de3b7
Notes: blender-bot 2023-02-14 09:38:57 +01:00
Referenced by issue #88449: Blender LTS: Maintenance Task 2.93
Referenced by issue #88449, Blender LTS: Maintenance Task 2.93
Referenced by issue #93084, blender uv stretch with area show full red (on large scale mesh)
5 changed files with 10 additions and 23 deletions

View File

@ -160,7 +160,6 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
pd->edit_uv.draw_type = sima->dt_uvstretch;
BLI_listbase_clear(&pd->edit_uv.totals);
pd->edit_uv.total_area_ratio = 0.0f;
pd->edit_uv.total_area_ratio_inv = 0.0f;
/* During engine initialization phase the `sima` isn't locked and
* we are able to retrieve the needed data.
@ -280,8 +279,6 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_block(pd->edit_uv_stretching_grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_float(
pd->edit_uv_stretching_grp, "totalAreaRatio", &pd->edit_uv.total_area_ratio, 1);
DRW_shgroup_uniform_float(
pd->edit_uv_stretching_grp, "totalAreaRatioInv", &pd->edit_uv.total_area_ratio_inv, 1);
}
}
@ -510,7 +507,6 @@ static void edit_uv_stretching_update_ratios(OVERLAY_Data *vedata)
if (total_area > FLT_EPSILON && total_area_uv > FLT_EPSILON) {
pd->edit_uv.total_area_ratio = total_area / total_area_uv;
pd->edit_uv.total_area_ratio_inv = total_area_uv / total_area;
}
}
BLI_freelistN(&pd->edit_uv.totals);

View File

@ -384,7 +384,6 @@ typedef struct OVERLAY_PrivateData {
eSpaceImage_UVDT_Stretch draw_type;
ListBase totals;
float total_area_ratio;
float total_area_ratio_inv;
/* stencil overlay */
struct Image *stencil_image;

View File

@ -293,7 +293,6 @@ GPU_SHADER_CREATE_INFO(overlay_edit_uv_stretching_area)
.do_static_compilation(true)
.vertex_in(1, Type::FLOAT, "ratio")
.push_constant(Type::FLOAT, "totalAreaRatio")
.push_constant(Type::FLOAT, "totalAreaRatioInv")
.additional_info("overlay_edit_uv_stretching");
GPU_SHADER_CREATE_INFO(overlay_edit_uv_stretching_angle)

View File

@ -55,9 +55,9 @@ float angle_normalized_v2v2(vec2 v1, vec2 v2)
return (q) ? a : M_PI - a;
}
float area_ratio_to_stretch(float ratio, float tot_ratio, float inv_tot_ratio)
float area_ratio_to_stretch(float ratio, float tot_ratio)
{
ratio *= (ratio > 0.0f) ? tot_ratio : -inv_tot_ratio;
ratio *= tot_ratio;
return (ratio > 1.0f) ? (1.0f / ratio) : ratio;
}
@ -74,7 +74,7 @@ void main()
stretch = stretch;
stretch = 1.0 - stretch * stretch;
#else
float stretch = 1.0 - area_ratio_to_stretch(ratio, totalAreaRatio, totalAreaRatioInv);
float stretch = 1.0 - area_ratio_to_stretch(ratio, totalAreaRatio);
#endif

View File

@ -27,7 +27,7 @@ static void extract_edituv_stretch_area_init(const MeshRenderData *mr,
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
GPU_vertformat_attr_add(&format, "ratio", GPU_COMP_I16, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
GPU_vertformat_attr_add(&format, "ratio", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
}
GPU_vertbuf_init_with_format(vbo, &format);
@ -37,15 +37,14 @@ static void extract_edituv_stretch_area_init(const MeshRenderData *mr,
BLI_INLINE float area_ratio_get(float area, float uvarea)
{
if (area >= FLT_EPSILON && uvarea >= FLT_EPSILON) {
/* Tag inversion by using the sign. */
return (area > uvarea) ? (uvarea / area) : -(area / uvarea);
return uvarea / area;
}
return 0.0f;
}
BLI_INLINE float area_ratio_to_stretch(float ratio, float tot_ratio, float inv_tot_ratio)
BLI_INLINE float area_ratio_to_stretch(float ratio, float tot_ratio)
{
ratio *= (ratio > 0.0f) ? tot_ratio : -inv_tot_ratio;
ratio *= tot_ratio;
return (ratio > 1.0f) ? (1.0f / ratio) : ratio;
}
@ -97,14 +96,8 @@ static void extract_edituv_stretch_area_finish(const MeshRenderData *mr,
float *area_ratio = static_cast<float *>(MEM_mallocN(sizeof(float) * mr->poly_len, __func__));
compute_area_ratio(mr, area_ratio, cache->tot_area, cache->tot_uv_area);
/* Convert in place to avoid an extra allocation */
uint16_t *poly_stretch = (uint16_t *)area_ratio;
for (int mp_index = 0; mp_index < mr->poly_len; mp_index++) {
poly_stretch[mp_index] = area_ratio[mp_index] * SHRT_MAX;
}
/* Copy face data for each loop. */
uint16_t *loop_stretch = (uint16_t *)GPU_vertbuf_get_data(vbo);
float *loop_stretch = (float *)GPU_vertbuf_get_data(vbo);
if (mr->extract_type == MR_EXTRACT_BMESH) {
BMFace *efa;
@ -112,7 +105,7 @@ static void extract_edituv_stretch_area_finish(const MeshRenderData *mr,
int f, l_index = 0;
BM_ITER_MESH_INDEX (efa, &f_iter, mr->bm, BM_FACES_OF_MESH, f) {
for (int i = 0; i < efa->len; i++, l_index++) {
loop_stretch[l_index] = poly_stretch[f];
loop_stretch[l_index] = area_ratio[f];
}
}
}
@ -121,7 +114,7 @@ static void extract_edituv_stretch_area_finish(const MeshRenderData *mr,
const MPoly *mp = mr->mpoly;
for (int mp_index = 0, l_index = 0; mp_index < mr->poly_len; mp_index++, mp++) {
for (int i = 0; i < mp->totloop; i++, l_index++) {
loop_stretch[l_index] = poly_stretch[mp_index];
loop_stretch[l_index] = area_ratio[mp_index];
}
}
}