Cleanup: simplify udim parameters when uv packing

Migrate (some) of the UDIM offset calculation from inside one
of the packing engines (where it's consumed) to the packing
operator (where it's produced).

This change (and others) will help simplify the future migration
of the packing engine inside editors/uvedit/uvedit_islands.cc
to the Geometry module, so it can eventually replace the other
packing engine in geometry/intern/uv_parametrizer.cc
This commit is contained in:
Chris Blackbourn 2022-12-07 15:26:06 +13:00
parent a5f9f7e2fc
commit 0e90896cba
3 changed files with 47 additions and 88 deletions

View File

@ -332,12 +332,7 @@ struct UVMapUDIM_Params {
const struct Image *image;
/** Copied from #SpaceImage.tile_grid_shape */
int grid_shape[2];
bool use_target_udim;
int target_udim;
};
bool ED_uvedit_udim_params_from_image_space(const struct SpaceImage *sima,
bool use_active,
struct UVMapUDIM_Params *udim_params);
typedef enum {
ED_UVPACK_MARGIN_SCALED = 0, /* Use scale of existing UVs to multiply margin. */
@ -356,6 +351,7 @@ struct UVPackIsland_Params {
bool pin_unselected; /* Treat unselected UVs as if they were pinned. */
eUVPackIsland_MarginMethod margin_method; /* Which formula to use when scaling island margin. */
float margin; /* Additional space to add around each island. */
float udim_base_offset[2]; /* Additional translation for bottom left corner. */
};
/**
@ -382,7 +378,7 @@ void ED_uvedit_pack_islands_multi(const struct Scene *scene,
Object **objects,
uint objects_len,
struct BMesh **bmesh_override,
const struct UVMapUDIM_Params *udim_params,
const struct UVMapUDIM_Params *closest_udim,
const struct UVPackIsland_Params *params);
#ifdef __cplusplus

View File

@ -647,7 +647,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
Object **objects,
const uint objects_len,
BMesh **bmesh_override,
const struct UVMapUDIM_Params *udim_params,
const struct UVMapUDIM_Params *closest_udim,
const struct UVPackIsland_Params *params)
{
blender::Vector<FaceIsland *> island_vector;
@ -716,19 +716,12 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
for (int index = 0; index < island_vector.size(); index++) {
FaceIsland *island = island_vector[index];
/* Skip calculation if using specified UDIM option. */
if (udim_params && (udim_params->use_target_udim == false)) {
float bounds_min[2], bounds_max[2];
INIT_MINMAX2(bounds_min, bounds_max);
if (closest_udim) {
/* Only calculate selection bounding box if using closest_udim. */
for (int i = 0; i < island->faces_len; i++) {
BMFace *f = island->faces[i];
BM_face_uv_minmax(f, bounds_min, bounds_max, island->cd_loop_uv_offset);
BM_face_uv_minmax(f, selection_min_co, selection_max_co, island->cd_loop_uv_offset);
}
selection_min_co[0] = MIN2(bounds_min[0], selection_min_co[0]);
selection_min_co[1] = MIN2(bounds_min[1], selection_min_co[1]);
selection_max_co[0] = MAX2(bounds_max[0], selection_max_co[0]);
selection_max_co[1] = MAX2(bounds_max[1], selection_max_co[1]);
}
if (params->rotate) {
@ -741,7 +734,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
/* Center of bounding box containing all selected UVs. */
float selection_center[2];
if (udim_params && (udim_params->use_target_udim == false)) {
if (closest_udim) {
selection_center[0] = (selection_min_co[0] + selection_max_co[0]) / 2.0f;
selection_center[1] = (selection_min_co[1] + selection_max_co[1]) / 2.0f;
}
@ -749,25 +742,12 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
float scale[2] = {1.0f, 1.0f};
BoxPack *box_array = pack_islands_params(island_vector, *params, scale);
/* Tile offset. */
float base_offset[2] = {0.0f, 0.0f};
copy_v2_v2(base_offset, params->udim_base_offset);
/* CASE: ignore UDIM. */
if (udim_params == nullptr) {
/* pass */
}
/* CASE: Active/specified(smart uv project) UDIM. */
else if (udim_params->use_target_udim) {
/* Calculate offset based on specified_tile_index. */
base_offset[0] = (udim_params->target_udim - 1001) % 10;
base_offset[1] = (udim_params->target_udim - 1001) / 10;
}
/* CASE: Closest UDIM. */
else {
const Image *image = udim_params->image;
const int *udim_grid = udim_params->grid_shape;
if (closest_udim) {
const Image *image = closest_udim->image;
const int *udim_grid = closest_udim->grid_shape;
/* Check if selection lies on a valid UDIM grid tile. */
bool is_valid_udim = uv_coords_isect_udim(image, udim_grid, selection_center);
if (is_valid_udim) {

View File

@ -134,54 +134,32 @@ static bool ED_uvedit_ensure_uvs(Object *obedit)
/** \name UDIM Access
* \{ */
bool ED_uvedit_udim_params_from_image_space(const SpaceImage *sima,
bool use_active,
struct UVMapUDIM_Params *udim_params)
static void ED_uvedit_udim_params_from_image_space(const SpaceImage *sima,
struct UVPackIsland_Params *r_params)
{
memset(udim_params, 0, sizeof(*udim_params));
udim_params->grid_shape[0] = 1;
udim_params->grid_shape[1] = 1;
udim_params->target_udim = 0;
udim_params->use_target_udim = false;
if (sima == NULL) {
return false;
if (!sima) {
return; /* Nothing to do. */
}
udim_params->image = sima->image;
udim_params->grid_shape[0] = sima->tile_grid_shape[0];
udim_params->grid_shape[1] = sima->tile_grid_shape[1];
if (use_active) {
int active_udim = 1001;
/* NOTE: Presently, when UDIM grid and tiled image are present together, only active tile for
* the tiled image is considered. */
const Image *image = sima->image;
if (image && image->source == IMA_SRC_TILED) {
ImageTile *active_tile = BLI_findlink(&image->tiles, image->active_tile_index);
if (active_tile) {
active_udim = active_tile->tile_number;
}
/* NOTE: Presently, when UDIM grid and tiled image are present together, only active tile for
* the tiled image is considered. */
const Image *image = sima->image;
if (image && image->source == IMA_SRC_TILED) {
ImageTile *active_tile = BLI_findlink(&image->tiles, image->active_tile_index);
if (active_tile) {
r_params->udim_base_offset[0] = (active_tile->tile_number - 1001) % 10;
r_params->udim_base_offset[1] = (active_tile->tile_number - 1001) / 10;
}
else {
/* TODO: Support storing an active UDIM when there are no tiles present.
* Until then, use 2D cursor to find the active tile index for the UDIM grid. */
if (uv_coords_isect_udim(sima->image, sima->tile_grid_shape, sima->cursor)) {
int tile_number = 1001;
tile_number += floorf(sima->cursor[1]) * 10;
tile_number += floorf(sima->cursor[0]);
active_udim = tile_number;
}
}
udim_params->target_udim = active_udim;
udim_params->use_target_udim = true;
return;
}
return true;
/* TODO: Support storing an active UDIM when there are no tiles present.
* Until then, use 2D cursor to find the active tile index for the UDIM grid. */
if (uv_coords_isect_udim(sima->image, sima->tile_grid_shape, sima->cursor)) {
r_params->udim_base_offset[0] = floorf(sima->cursor[0]);
r_params->udim_base_offset[1] = floorf(sima->cursor[1]);
}
}
/** \} */
/* -------------------------------------------------------------------- */
@ -1088,12 +1066,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin);
}
struct UVMapUDIM_Params udim_params;
const bool use_active = (udim_source == PACK_UDIM_SRC_ACTIVE);
const bool use_udim_params = ED_uvedit_udim_params_from_image_space(
sima, use_active, &udim_params);
const struct UVPackIsland_Params pack_island_params = {
struct UVPackIsland_Params pack_island_params = {
.rotate = RNA_boolean_get(op->ptr, "rotate"),
.only_selected_uvs = options.only_selected_uvs,
.only_selected_faces = options.only_selected_faces,
@ -1104,12 +1077,22 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
.margin_method = RNA_enum_get(op->ptr, "margin_method"),
.margin = RNA_float_get(op->ptr, "margin"),
};
ED_uvedit_pack_islands_multi(scene,
objects,
objects_len,
NULL,
use_udim_params ? &udim_params : NULL,
&pack_island_params);
struct UVMapUDIM_Params closest_udim_buf;
struct UVMapUDIM_Params *closest_udim = NULL;
if (udim_source == PACK_UDIM_SRC_ACTIVE) {
ED_uvedit_udim_params_from_image_space(sima, &pack_island_params);
}
else if (sima) {
BLI_assert(udim_source == PACK_UDIM_SRC_CLOSEST);
closest_udim = &closest_udim_buf;
closest_udim->image = sima->image;
closest_udim->grid_shape[0] = sima->tile_grid_shape[0];
closest_udim->grid_shape[1] = sima->tile_grid_shape[1];
}
ED_uvedit_pack_islands_multi(
scene, objects, objects_len, NULL, closest_udim, &pack_island_params);
MEM_freeN(objects);
return OPERATOR_FINISHED;