[Bf-blender-cvs] [78fc5ea1c39] blender-v3.2-release: Workaround T81065: Merge UV's when applying modifiers

Campbell Barton noreply at git.blender.org
Thu May 5 12:39:10 CEST 2022


Commit: 78fc5ea1c398f70d22cda72be33c105146c0d542
Author: Campbell Barton
Date:   Thu May 5 20:36:15 2022 +1000
Branches: blender-v3.2-release
https://developer.blender.org/rB78fc5ea1c398f70d22cda72be33c105146c0d542

Workaround T81065: Merge UV's when applying modifiers

Support merging UV's that share the same vertex and are very close when
applying modifiers.

This is needed to prevent UV's becoming "detached" which can happen when
applying the subdivision surface modifier.

This regression was caused by [0] which removed selection threshold for
nearby coordinates. While restoring the UV selection threshold could be
done - some selection operations that walk around connected UV fans
wouldn't behave in a deterministic way (such as select shortest path).
There are also other cases where UV's may be compared without a
threshold such as tangent calculation and exporters which have their own
logic to handling UV's.

Also resolves T86896, T89903.

[0]: b88dd3b8e7b9c02ae08d4679bb427963c5d21250

Reviewed By: sergey

Ref D14841

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

M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/editors/object/object_add.cc
M	source/blender/editors/object/object_modifier.cc

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

diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index bd9bacb52c1..091f30825ae 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -893,6 +893,14 @@ struct Mesh *BKE_mesh_merge_verts(struct Mesh *mesh,
                                   int tot_vtargetmap,
                                   int merge_mode);
 
+/**
+ * Account for custom-data such as UV's becoming detached because of of imprecision
+ * in custom-data interpolation.
+ * Without running this operation subdivision surface can cause UV's to be disconnected,
+ * see: T81065.
+ */
+void BKE_mesh_merge_customdata_for_apply_modifier(struct Mesh *me);
+
 /* Flush flags. */
 
 /**
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 710e2900d78..a57d4d0a2bf 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -199,6 +199,7 @@ set(SRC
   intern/mesh_iterators.c
   intern/mesh_mapping.c
   intern/mesh_merge.c
+  intern/mesh_merge_customdata.cc
   intern/mesh_mirror.c
   intern/mesh_normals.cc
   intern/mesh_remap.c
diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc
index 5b857d2dba1..db8860efdd8 100644
--- a/source/blender/editors/object/object_add.cc
+++ b/source/blender/editors/object/object_add.cc
@@ -2894,6 +2894,7 @@ static int object_convert_exec(bContext *C, wmOperator *op)
   Object *ob1, *obact = CTX_data_active_object(C);
   const short target = RNA_enum_get(op->ptr, "target");
   bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
+  const bool do_merge_customdata = RNA_boolean_get(op->ptr, "merge_customdata");
 
   const float angle = RNA_float_get(op->ptr, "angle");
   const int thickness = RNA_int_get(op->ptr, "thickness");
@@ -3122,6 +3123,10 @@ static int object_convert_exec(bContext *C, wmOperator *op)
       Mesh *new_mesh = (Mesh *)newob->data;
       BKE_mesh_nomain_to_mesh(me_eval, new_mesh, newob, &CD_MASK_MESH, true);
 
+      if (do_merge_customdata) {
+        BKE_mesh_merge_customdata_for_apply_modifier(new_mesh);
+      }
+
       /* Anonymous attributes shouldn't be available on the applied geometry. */
       MeshComponent component;
       component.replace(new_mesh, GeometryOwnershipType::Editable);
@@ -3441,7 +3446,11 @@ static void object_convert_ui(bContext *UNUSED(C), wmOperator *op)
   uiItemR(layout, op->ptr, "target", 0, nullptr, ICON_NONE);
   uiItemR(layout, op->ptr, "keep_original", 0, nullptr, ICON_NONE);
 
-  if (RNA_enum_get(op->ptr, "target") == OB_GPENCIL) {
+  const int target = RNA_enum_get(op->ptr, "target");
+  if (target == OB_MESH) {
+    uiItemR(layout, op->ptr, "merge_customdata", 0, nullptr, ICON_NONE);
+  }
+  else if (target == OB_GPENCIL) {
     uiItemR(layout, op->ptr, "thickness", 0, nullptr, ICON_NONE);
     uiItemR(layout, op->ptr, "angle", 0, nullptr, ICON_NONE);
     uiItemR(layout, op->ptr, "offset", 0, nullptr, ICON_NONE);
@@ -3477,6 +3486,13 @@ void OBJECT_OT_convert(wmOperatorType *ot)
                   "Keep Original",
                   "Keep original objects instead of replacing them");
 
+  RNA_def_boolean(
+      ot->srna,
+      "merge_customdata",
+      true,
+      "Merge UV's",
+      "Merge UV coordinates that share a vertex to account for imprecision in some modifiers");
+
   prop = RNA_def_float_rotation(ot->srna,
                                 "angle",
                                 0,
diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc
index f90a31a7cbe..3328fe65f2e 100644
--- a/source/blender/editors/object/object_modifier.cc
+++ b/source/blender/editors/object/object_modifier.cc
@@ -1434,8 +1434,10 @@ static int modifier_apply_exec_ex(bContext *C, wmOperator *op, int apply_as, boo
   Scene *scene = CTX_data_scene(C);
   Object *ob = ED_object_active_context(C);
   ModifierData *md = edit_modifier_property_get(op, ob, 0);
+  const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
   const bool do_report = RNA_boolean_get(op->ptr, "report");
   const bool do_single_user = RNA_boolean_get(op->ptr, "single_user");
+  const bool do_merge_customdata = RNA_boolean_get(op->ptr, "merge_customdata");
 
   if (md == nullptr) {
     return OPERATOR_CANCELLED;
@@ -1460,6 +1462,11 @@ static int modifier_apply_exec_ex(bContext *C, wmOperator *op, int apply_as, boo
     return OPERATOR_CANCELLED;
   }
 
+  if (do_merge_customdata &&
+      (mti->type & (eModifierTypeType_Constructive | eModifierTypeType_Nonconstructive))) {
+    BKE_mesh_merge_customdata_for_apply_modifier((Mesh *)ob->data);
+  }
+
   DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
   DEG_relations_tag_update(bmain);
   WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -1518,6 +1525,12 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
   edit_modifier_properties(ot);
   edit_modifier_report_property(ot);
 
+  RNA_def_boolean(
+      ot->srna,
+      "merge_customdata",
+      true,
+      "Merge UV's",
+      "Merge UV coordinates that share a vertex to account for imprecision in some modifiers");
   PropertyRNA *prop = RNA_def_boolean(ot->srna,
                                       "single_user",
                                       false,
@@ -1599,11 +1612,18 @@ static int modifier_convert_exec(bContext *C, wmOperator *op)
   ViewLayer *view_layer = CTX_data_view_layer(C);
   Object *ob = ED_object_active_context(C);
   ModifierData *md = edit_modifier_property_get(op, ob, 0);
+  const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
+  const bool do_merge_customdata = RNA_boolean_get(op->ptr, "merge_customdata");
 
   if (!md || !ED_object_modifier_convert(op->reports, bmain, depsgraph, view_layer, ob, md)) {
     return OPERATOR_CANCELLED;
   }
 
+  if (do_merge_customdata &&
+      (mti->type & (eModifierTypeType_Constructive | eModifierTypeType_Nonconstructive))) {
+    BKE_mesh_merge_customdata_for_apply_modifier((Mesh *)ob->data);
+  }
+
   DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
   WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
 
@@ -1631,6 +1651,13 @@ void OBJECT_OT_modifier_convert(wmOperatorType *ot)
   /* flags */
   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
   edit_modifier_properties(ot);
+
+  RNA_def_boolean(
+      ot->srna,
+      "merge_customdata",
+      true,
+      "Merge UV's",
+      "Merge UV coordinates that share a vertex to account for imprecision in some modifiers");
 }
 
 /** \} */



More information about the Bf-blender-cvs mailing list