Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Blackbourn <chrisbblend@gmail.com>2022-10-20 02:35:17 +0300
committerChris Blackbourn <chrisbblend@gmail.com>2022-10-20 02:44:56 +0300
commite3075f3cf7ce2fae086f3cd09867e4f0455e4115 (patch)
treefad8d58eee7346e0e8b80da2a77b05e82359a220
parent21a1c332b00a63afaa82cce00ca5175b1b8dbd96 (diff)
Cleanup: simplify uv packing api
Part of a wider set of changes to migrate UV packing from uv_parametrizer.cc to uvedit_islands.cc. This allows UV packing improvements including margin calculation, correctness fixes such as support for non-manifold geometry, and new packing algorithms including speed and quality improvements. See for example c2256bf7f714, T82637 This change migrates UV.unwrap and Live UV Unwrap. Differential Revision: https://developer.blender.org/D16296
-rw-r--r--source/blender/editors/include/ED_uvedit.h2
-rw-r--r--source/blender/editors/uvedit/uvedit_islands.cc26
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c75
3 files changed, 62 insertions, 41 deletions
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index c8ffbb9acb1..b97cd6a9099 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -345,12 +345,14 @@ typedef enum {
ED_UVPACK_MARGIN_FRACTION, /* Specify a precise fraction of final UV output. */
} eUVPackIsland_MarginMethod;
+/** See also #UnwrapOptions. */
struct UVPackIsland_Params {
uint rotate : 1;
uint only_selected_uvs : 1;
uint only_selected_faces : 1;
uint use_seams : 1;
uint correct_aspect : 1;
+ bool ignore_pinned; /* Ignore islands which have any pinned UVs. */
eUVPackIsland_MarginMethod margin_method; /* Which formula to use when scaling island margin. */
float margin; /* Additional space to add around each island. */
};
diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc
index bdd05b06d94..92745667505 100644
--- a/source/blender/editors/uvedit/uvedit_islands.cc
+++ b/source/blender/editors/uvedit/uvedit_islands.cc
@@ -600,6 +600,22 @@ static BoxPack *pack_islands_params(const blender::Vector<FaceIsland *> &island_
return box_array;
}
+static bool island_has_pins(FaceIsland *island)
+{
+ BMLoop *l;
+ BMIter iter;
+ const int cd_loop_uv_offset = island->cd_loop_uv_offset;
+ for (int i = 0; i < island->faces_len; i++) {
+ BM_ITER_ELEM (l, &iter, island->faces[i], BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = static_cast<MLoopUV *>(BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset));
+ if (luv->flag & MLOOPUV_PINNED) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/* -------------------------------------------------------------------- */
/** \name Public UV Island Packing
*
@@ -651,8 +667,14 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
aspect_y,
cd_loop_uv_offset);
- int index;
- LISTBASE_FOREACH_INDEX (struct FaceIsland *, island, &island_list, index) {
+ /* Remove from linked list and append to blender::Vector. */
+ LISTBASE_FOREACH_MUTABLE (struct FaceIsland *, island, &island_list) {
+ BLI_remlink(&island_list, island);
+ if (params->ignore_pinned && island_has_pins(island)) {
+ MEM_freeN(island->faces);
+ MEM_freeN(island);
+ continue;
+ }
island_vector.append(island);
}
}
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 2c977552e72..ecaba3234a7 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -1050,31 +1050,6 @@ void UV_OT_minimize_stretch(wmOperatorType *ot)
/** \name Pack UV Islands Operator
* \{ */
-/**
- * \warning Since this uses #ParamHandle it doesn't work with non-manifold meshes (see T82637).
- * Use #ED_uvedit_pack_islands_multi for a more general solution.
- *
- * TODO: remove this function, in favor of #ED_uvedit_pack_islands_multi.
- */
-static void uvedit_pack_islands_multi(const Scene *scene,
- Object **objects,
- const uint objects_len,
- const UnwrapOptions *options,
- bool rotate,
- bool ignore_pinned)
-{
- ParamHandle *handle = construct_param_handle_multi(scene, objects, objects_len, options);
- GEO_uv_parametrizer_pack(handle, scene->toolsettings->uvcalc_margin, rotate, ignore_pinned);
- GEO_uv_parametrizer_flush(handle);
- GEO_uv_parametrizer_delete(handle);
-
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY);
- WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data);
- }
-}
-
/* Packing targets. */
enum {
PACK_UDIM_SRC_CLOSEST = 0,
@@ -1119,16 +1094,22 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
const bool use_udim_params = ED_uvedit_udim_params_from_image_space(
sima, use_active, &udim_params);
- struct UVPackIsland_Params params = {
+ const struct UVPackIsland_Params pack_island_params = {
.rotate = RNA_boolean_get(op->ptr, "rotate"),
- .only_selected_uvs = true,
- .only_selected_faces = true,
- .correct_aspect = true,
+ .only_selected_uvs = options.only_selected_uvs,
+ .only_selected_faces = options.only_selected_faces,
+ .use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams,
+ .correct_aspect = options.correct_aspect,
+ .ignore_pinned = false,
.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, &params);
+ ED_uvedit_pack_islands_multi(scene,
+ objects,
+ objects_len,
+ NULL,
+ use_udim_params ? &udim_params : NULL,
+ &pack_island_params);
MEM_freeN(objects);
return OPERATOR_FINISHED;
@@ -1889,12 +1870,19 @@ void ED_uvedit_live_unwrap(const Scene *scene, Object **objects, int objects_len
.fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0,
.correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0,
};
-
- bool rotate = true;
- bool ignore_pinned = true;
-
uvedit_unwrap_multi(scene, objects, objects_len, &options, NULL);
- uvedit_pack_islands_multi(scene, objects, objects_len, &options, rotate, ignore_pinned);
+
+ const struct UVPackIsland_Params pack_island_params = {
+ .rotate = true,
+ .only_selected_uvs = options.only_selected_uvs,
+ .only_selected_faces = options.only_selected_faces,
+ .use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams,
+ .correct_aspect = options.correct_aspect,
+ .ignore_pinned = true,
+ .margin_method = ED_UVPACK_MARGIN_SCALED,
+ .margin = scene->toolsettings->uvcalc_margin,
+ };
+ ED_uvedit_pack_islands_multi(scene, objects, objects_len, NULL, NULL, &pack_island_params);
}
}
@@ -1926,8 +1914,6 @@ static int unwrap_exec(bContext *C, wmOperator *op)
.correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"),
};
- bool rotate = true;
- bool ignore_pinned = true;
if (CTX_wm_space_image(C)) {
/* Inside the UV Editor, only unwrap selected UVs. */
options.only_selected_uvs = true;
@@ -2032,7 +2018,18 @@ static int unwrap_exec(bContext *C, wmOperator *op)
.count_failed = 0,
};
uvedit_unwrap_multi(scene, objects, objects_len, &options, &result_info);
- uvedit_pack_islands_multi(scene, objects, objects_len, &options, rotate, ignore_pinned);
+
+ const struct UVPackIsland_Params pack_island_params = {
+ .rotate = true,
+ .only_selected_uvs = options.only_selected_uvs,
+ .only_selected_faces = options.only_selected_faces,
+ .use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams,
+ .correct_aspect = options.correct_aspect,
+ .ignore_pinned = true,
+ .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, NULL, &pack_island_params);
MEM_freeN(objects);