diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_add.cc | 18 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.cc | 27 |
4 files changed, 53 insertions, 1 deletions
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"); } /** \} */ |