[Bf-blender-cvs] [e3075f3cf7c] master: Cleanup: simplify uv packing api

Chris Blackbourn noreply at git.blender.org
Thu Oct 20 01:46:36 CEST 2022


Commit: e3075f3cf7ce2fae086f3cd09867e4f0455e4115
Author: Chris Blackbourn
Date:   Thu Oct 20 12:35:17 2022 +1300
Branches: master
https://developer.blender.org/rBe3075f3cf7ce2fae086f3cd09867e4f0455e4115

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

===================================================================

M	source/blender/editors/include/ED_uvedit.h
M	source/blender/editors/uvedit/uvedit_islands.cc
M	source/blender/editors/uvedit/uvedit_unwrap_ops.c

===================================================================

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);



More information about the Bf-blender-cvs mailing list