UV: Fix (unreported) uv packing with pinned islands and original bounding box
buildbot/v360-code-daily-coordinator Build done. Details

Pinned islands with "Lock Position" were not interacting correctly
when the packing destination was not at the origin.

This could happen with "Pack To : Original Bounding Box", and also
when packing to a UDIM other than 1001.
This commit is contained in:
Chris Blackbourn 2023-05-27 16:01:49 +12:00
parent aa6414c8c8
commit 71d89dfa81
3 changed files with 18 additions and 24 deletions

View File

@ -1244,6 +1244,8 @@ static void uvedit_pack_islands_multi(const Scene *scene,
if ((selection_max_co[0] - selection_min_co[0]) * (selection_max_co[1] - selection_min_co[1]) >
1e-40f)
{
copy_v2_v2(params->udim_base_offset, selection_min_co);
params->target_extent = selection_max_co[1] - selection_min_co[1];
params->target_aspect_y = (selection_max_co[0] - selection_min_co[0]) /
(selection_max_co[1] - selection_min_co[1]);
}
@ -1342,20 +1344,6 @@ static void uvedit_pack_islands_multi(const Scene *scene,
/* Perform the transformation. */
island_uv_transform(island, matrix, pre_translate);
if (original_selection) {
const float rescale_x = (selection_max_co[0] - selection_min_co[0]) /
params->target_aspect_y;
const float rescale_y = (selection_max_co[1] - selection_min_co[1]);
const float rescale = params->scale_to_fit ? std::min(rescale_x, rescale_y) : 1.0f;
matrix[0][0] = rescale;
matrix[0][1] = 0.0f;
matrix[1][0] = 0.0f;
matrix[1][1] = rescale;
pre_translate[0] = selection_min_co[0] / rescale;
pre_translate[1] = selection_min_co[1] / rescale;
island_uv_transform(island, matrix, pre_translate);
}
}
for (const int64_t i : pack_island_vector.index_range()) {

View File

@ -92,6 +92,8 @@ class UVPackIsland_Params {
eUVPackIsland_MarginMethod margin_method;
/** Additional translation for bottom left corner. */
float udim_base_offset[2];
/** Target vertical extent. Should be 1.0f for the unit square. */
float target_extent;
/** Target aspect ratio. */
float target_aspect_y;
/** Which shape to use when packing. */

View File

@ -344,7 +344,8 @@ UVPackIsland_Params::UVPackIsland_Params()
margin_method = ED_UVPACK_MARGIN_SCALED;
udim_base_offset[0] = 0.0f;
udim_base_offset[1] = 0.0f;
target_aspect_y = 1.0f;
target_extent = 1.0f; /* Assume unit square. */
target_aspect_y = 1.0f; /* Assume unit square. */
shape_method = ED_UVPACK_SHAPE_AABB;
stop = nullptr;
do_update = nullptr;
@ -1240,17 +1241,19 @@ static int64_t pack_island_xatlas(const Span<UVAABBIsland *> island_indices,
}
PackIsland *island = islands[island_indices[i]->index];
uv_phi phi; /* Create an identity transform. */
if (!island->can_translate_(params)) {
uv_phi phi;
/* Move the pinned island into the correct coordinate system. */
phi.translation = island->pivot_;
sub_v2_v2(phi.translation, params.udim_base_offset);
phi.rotation = 0.0f;
phis[island_indices[i]->index] = phi;
i++;
placed_can_rotate = false;
continue;
placed_can_rotate = false; /* Further rotation will cause a translation. */
continue; /* `island` is now completed. */
}
const float island_scale = island->can_scale_(params) ? scale : 1.0f;
uv_phi phi;
int max_90_multiple = 1;
if (island->can_rotate_(params)) {
@ -1491,6 +1494,9 @@ static float pack_islands_scale_margin(const Span<PackIsland *> islands,
alpaca_cutoff = alpaca_cutoff_fast;
}
}
alpaca_cutoff = std::max(alpaca_cutoff, locked_island_count); /* ...TODO... */
Span<UVAABBIsland *> slow_aabbs = aabbs.as_span().take_front(
std::min(alpaca_cutoff, islands.size()));
rctf extent = {0.0f, 1e30f, 0.0f, 1e30f};
@ -1549,9 +1555,6 @@ static float pack_islands_margin_fraction(const Span<PackIsland *> &islands,
const bool rescale_margin,
const UVPackIsland_Params &params)
{
/* TODO: Support Pack To Original Bounding Box */
/*
* Root finding using a combined search / modified-secant method.
* First, use a robust search procedure to bracket the root within a factor of 10.
@ -1624,7 +1627,8 @@ static float pack_islands_margin_fraction(const Span<PackIsland *> &islands,
/* Evaluate our `f`. */
blender::Array<uv_phi> *phis_target = (phis_low == &phis_a) ? &phis_b : &phis_a;
const float margin = rescale_margin ? margin_fraction * scale : margin_fraction;
const float max_uv = pack_islands_scale_margin(islands, scale, margin, params, *phis_target);
const float max_uv = pack_islands_scale_margin(islands, scale, margin, params, *phis_target) /
params.target_extent;
const float value = sqrtf(max_uv) - 1.0f;
if (value <= 0.0f) {
@ -1884,7 +1888,7 @@ float pack_islands(const Span<PackIsland *> &islands, const UVPackIsland_Params
blender::Array<uv_phi> phis(islands.size());
const float scale = 1.0f;
const float max_uv = pack_islands_scale_margin(islands, scale, margin, params, phis);
const float result = can_scale_count > 0 ? 1.0f / max_uv : 1.0f;
const float result = can_scale_count > 0 ? params.target_extent / max_uv : 1.0f;
for (const int64_t i : islands.index_range()) {
BLI_assert(result == 1.0f || islands[i]->can_scale_(params));
islands[i]->place_(scale, phis[i]);