diff options
author | Campbell Barton <ideasman42@gmail.com> | 2021-09-30 10:32:45 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2021-09-30 10:32:45 +0300 |
commit | fdcae48663e87ebc2ed0a97916dcdecb3bd03e61 (patch) | |
tree | c49eb93dd56bd31b738f68b6648cd582f78146b9 /source/blender | |
parent | 2c2516bfc92ba8fa0850ca6b6151dbc058b2cbce (diff) |
Cleanup: isolate UDIM parameters into a struct
Passing multiple UDIM arguments into the packing function
is awkward especially since the caller may not be using UDIM.
Use an argument to store UDIM packing parameters which can be NULL,
which operates without any UDIM support.
Add a function that extracts these parameters out of the image space
allowing for multiple functions to take UDIM parameters in the future.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/include/ED_uvedit.h | 20 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_islands.c | 41 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_unwrap_ops.c | 103 |
3 files changed, 97 insertions, 67 deletions
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 516239a7176..f3aba12a924 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -237,6 +237,18 @@ void ED_image_draw_cursor(struct ARegion *region, const float cursor[2]); void ED_uvedit_buttons_register(struct ARegionType *art); /* uvedit_islands.c */ + +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); + struct UVPackIsland_Params { uint rotate : 1; /** -1 not to align to axis, otherwise 0,1 for X,Y. */ @@ -247,13 +259,13 @@ struct UVPackIsland_Params { uint correct_aspect : 1; }; -bool uv_coords_isect_udim(const struct Image *image, const int udim_grid[2], float coords[2]); +bool uv_coords_isect_udim(const struct Image *image, + const int udim_grid[2], + const float coords[2]); void ED_uvedit_pack_islands_multi(const struct Scene *scene, - const struct SpaceImage *sima, Object **objects, const uint objects_len, - const bool use_target_udim, - int target_udim, + const struct UVMapUDIM_Params *udim_params, const struct UVPackIsland_Params *params); #ifdef __cplusplus diff --git a/source/blender/editors/uvedit/uvedit_islands.c b/source/blender/editors/uvedit/uvedit_islands.c index 62173f4eaff..6159758dbcd 100644 --- a/source/blender/editors/uvedit/uvedit_islands.c +++ b/source/blender/editors/uvedit/uvedit_islands.c @@ -237,8 +237,10 @@ static void bm_face_array_uv_scale_y(BMFace **faces, /** \name UDIM packing helper functions * \{ */ -/* Returns true if UV coordinates lie on a valid tile in UDIM grid or tiled image. */ -bool uv_coords_isect_udim(const Image *image, const int udim_grid[2], float coords[2]) +/** + * Returns true if UV coordinates lie on a valid tile in UDIM grid or tiled image. + */ +bool uv_coords_isect_udim(const Image *image, const int udim_grid[2], const float coords[2]) { const float coords_floor[2] = {floorf(coords[0]), floorf(coords[1])}; const bool is_tiled_image = image && (image->source == IMA_SRC_TILED); @@ -452,11 +454,9 @@ static int bm_mesh_calc_uv_islands(const Scene *scene, * \{ */ void ED_uvedit_pack_islands_multi(const Scene *scene, - const SpaceImage *sima, Object **objects, const uint objects_len, - const bool use_target_udim, - int target_udim, + const struct UVMapUDIM_Params *udim_params, const struct UVPackIsland_Params *params) { /* Align to the Y axis, could make this configurable. */ @@ -512,7 +512,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, LISTBASE_FOREACH_INDEX (struct FaceIsland *, island, &island_list, index) { /* Skip calculation if using specified UDIM option. */ - if (!use_target_udim) { + if (udim_params && (udim_params->use_target_udim == false)) { float bounds_min[2], bounds_max[2]; INIT_MINMAX2(bounds_min, bounds_max); for (int i = 0; i < island->faces_len; i++) { @@ -525,6 +525,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, 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) { if (island->aspect_y != 1.0f) { bm_face_array_uv_scale_y( @@ -559,7 +560,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, /* Center of bounding box containing all selected UVs. */ float selection_center[2]; - if (!use_target_udim) { + if (udim_params && (udim_params->use_target_udim == false)) { 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; } @@ -590,24 +591,22 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, /* Tile offset. */ float base_offset[2] = {0.0f, 0.0f}; + /* CASE: ignore UDIM. */ + if (udim_params == NULL) { + /* pass */ + } /* CASE: Active/specified(smart uv project) UDIM. */ - if (use_target_udim) { + else if (udim_params->use_target_udim) { + /* Calculate offset based on specified_tile_index. */ - base_offset[0] = (target_udim - 1001) % 10; - base_offset[1] = (target_udim - 1001) / 10; + 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; - int udim_grid[2] = {1, 1}; - /* To handle cases where `sima == NULL` - Smart UV project in 3D viewport. */ - if (sima != NULL) { - image = sima->image; - udim_grid[0] = sima->tile_grid_shape[0]; - udim_grid[1] = sima->tile_grid_shape[1]; - } - + const Image *image = udim_params->image; + const int *udim_grid = udim_params->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) { @@ -643,8 +642,8 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, island->bounds_rect.ymin, }; const float offset[2] = { - (boxarray[i].x * scale[0]) - island->bounds_rect.xmin + base_offset[0], - (boxarray[i].y * scale[1]) - island->bounds_rect.ymin + base_offset[1], + ((boxarray[i].x * scale[0]) - island->bounds_rect.xmin) + base_offset[0], + ((boxarray[i].y * scale[1]) - island->bounds_rect.ymin) + base_offset[1], }; for (int j = 0; j < island->faces_len; j++) { BMFace *efa = island->faces[j]; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 4e183732db9..38233b55d15 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -145,6 +145,61 @@ 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) +{ + 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; + } + + 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. */ + 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; + } + } + 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. */ + const float cursor_loc[2] = {sima->cursor[0], sima->cursor[1]}; + if (uv_coords_isect_udim(sima->image, sima->tile_grid_shape, cursor_loc)) { + int tile_number = 1001; + tile_number += floorf(cursor_loc[1]) * 10; + tile_number += floorf(cursor_loc[0]); + active_udim = tile_number; + } + } + + udim_params->target_udim = active_udim; + udim_params->use_target_udim = true; + } + + return true; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Parametrizer Conversion * \{ */ @@ -1040,7 +1095,6 @@ static int pack_islands_exec(bContext *C, wmOperator *op) /* RNA props */ const bool rotate = RNA_boolean_get(op->ptr, "rotate"); const int udim_source = RNA_enum_get(op->ptr, "udim_source"); - bool use_target_udim = false; if (RNA_struct_property_is_set(op->ptr, "margin")) { scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); } @@ -1048,46 +1102,15 @@ static int pack_islands_exec(bContext *C, wmOperator *op) RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); } - int target_udim = 1001; - if (udim_source == PACK_UDIM_SRC_CLOSEST) { - /* pass */ - } - else if (udim_source == PACK_UDIM_SRC_ACTIVE) { - int active_udim = 1001; - /* NOTE: Presently, when UDIM grid and tiled image are present together, only active tile for - * the tiled imgae is considered. */ - if (sima && sima->image) { - Image *image = sima->image; - ImageTile *active_tile = BLI_findlink(&image->tiles, image->active_tile_index); - if (active_tile) { - active_udim = active_tile->tile_number; - } - } - else if (sima && !sima->image) { - /* Use 2D cursor to find the active tile index for the UDIM grid. */ - float cursor_loc[2] = {sima->cursor[0], sima->cursor[1]}; - if (uv_coords_isect_udim(sima->image, sima->tile_grid_shape, cursor_loc)) { - int tile_number = 1001; - tile_number += floorf(cursor_loc[1]) * 10; - tile_number += floorf(cursor_loc[0]); - active_udim = tile_number; - } - /* TODO: Support storing an active UDIM when there are no tiles present. */ - } - - target_udim = active_udim; - use_target_udim = true; - } - else { - BLI_assert_unreachable(); - } + 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); ED_uvedit_pack_islands_multi(scene, - sima, objects, objects_len, - use_target_udim, - target_udim, + use_udim_params ? &udim_params : NULL, &(struct UVPackIsland_Params){ .rotate = rotate, .rotate_align_axis = -1, @@ -2114,7 +2137,6 @@ static int smart_project_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - const SpaceImage *sima = CTX_wm_space_image(C); /* May be NULL. */ View3D *v3d = CTX_wm_view3d(C); @@ -2125,7 +2147,6 @@ static int smart_project_exec(bContext *C, wmOperator *op) const float project_angle_limit_cos = cosf(project_angle_limit); const float project_angle_limit_half_cos = cosf(project_angle_limit / 2); - const int target_udim = 1001; /* 0-1 UV space. */ /* Memory arena for list links (cleared for each object). */ MemArena *arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); @@ -2265,11 +2286,9 @@ static int smart_project_exec(bContext *C, wmOperator *op) /* Depsgraph refresh functions are called here. */ const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); ED_uvedit_pack_islands_multi(scene, - sima, objects_changed, object_changed_len, - true, - target_udim, + NULL, &(struct UVPackIsland_Params){ .rotate = true, /* We could make this optional. */ |