From 2a2aa6abd0ae45133b083368be4bee77a1a420c4 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 7 May 2020 12:34:13 +0200 Subject: Fix T75793: Mirror modifier UV flip only works on first UDIM Tile Was flipping around the 0-1 range, now (optionally) flip around each tile. Also added this option for BMesh bmo_mirror. Reviewed By: campbellbarton Maniphest Tasks: T75793 Differential Revision: https://developer.blender.org/D7460 --- .../scripts/startup/bl_ui/properties_data_modifier.py | 2 ++ source/blender/blenkernel/intern/mesh_mirror.c | 18 ++++++++++++++++-- source/blender/bmesh/intern/bmesh_opdefines.c | 1 + source/blender/bmesh/operators/bmo_mirror.c | 17 +++++++++++++++-- source/blender/makesdna/DNA_modifier_types.h | 1 + source/blender/makesrna/intern/rna_modifier.c | 6 ++++++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index b9fc7431a9a..8f1337b156d 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -655,6 +655,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): row = layout.row() row.prop(md, "use_mirror_u", text="Flip U") row.prop(md, "use_mirror_v", text="Flip V") + row = layout.row() + row.prop(md, "use_mirror_udim", text="Flip UDIM") col = layout.column(align=True) diff --git a/source/blender/blenkernel/intern/mesh_mirror.c b/source/blender/blenkernel/intern/mesh_mirror.c index 49ffa9561ce..d9be9a99b2b 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.c +++ b/source/blender/blenkernel/intern/mesh_mirror.c @@ -290,6 +290,8 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis(MirrorModifierData *mmd, (is_zero_v2(mmd->uv_offset_copy) == false)) { const bool do_mirr_u = (mmd->flag & MOD_MIR_MIRROR_U) != 0; const bool do_mirr_v = (mmd->flag & MOD_MIR_MIRROR_V) != 0; + /* If set, flip around center of each tile. */ + const bool do_mirr_udim = (mmd->flag & MOD_MIR_MIRROR_UDIM) != 0; const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV); @@ -299,10 +301,22 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis(MirrorModifierData *mmd, dmloopuv += j; /* second set of loops only */ for (; j-- > 0; dmloopuv++) { if (do_mirr_u) { - dmloopuv->uv[0] = 1.0f - dmloopuv->uv[0] + mmd->uv_offset[0]; + float u = dmloopuv->uv[0]; + if (do_mirr_udim) { + dmloopuv->uv[0] = ceilf(u) - fmodf(u, 1.0f) + mmd->uv_offset[0]; + } + else { + dmloopuv->uv[0] = 1.0f - u + mmd->uv_offset[0]; + } } if (do_mirr_v) { - dmloopuv->uv[1] = 1.0f - dmloopuv->uv[1] + mmd->uv_offset[1]; + float v = dmloopuv->uv[1]; + if (do_mirr_udim) { + dmloopuv->uv[1] = ceilf(v) - fmodf(v, 1.0f) + mmd->uv_offset[1]; + } + else { + dmloopuv->uv[1] = 1.0f - v + mmd->uv_offset[1]; + } } dmloopuv->uv[0] += mmd->uv_offset_copy[0]; dmloopuv->uv[1] += mmd->uv_offset_copy[1]; diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 4fa7bf64834..14e3c57f038 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -320,6 +320,7 @@ static BMOpDefine bmo_mirror_def = { {"axis", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_axis_xyz}, /* the axis to use. */ {"mirror_u", BMO_OP_SLOT_BOOL}, /* mirror UVs across the u axis */ {"mirror_v", BMO_OP_SLOT_BOOL}, /* mirror UVs across the v axis */ + {"mirror_udim", BMO_OP_SLOT_BOOL}, /* mirror UVs in each tile */ {{'\0'}}, }, /* slots_out */ diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c index 36297b3f816..b5b56f4432d 100644 --- a/source/blender/bmesh/operators/bmo_mirror.c +++ b/source/blender/bmesh/operators/bmo_mirror.c @@ -48,6 +48,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) int axis = BMO_slot_int_get(op->slots_in, "axis"); bool mirror_u = BMO_slot_bool_get(op->slots_in, "mirror_u"); bool mirror_v = BMO_slot_bool_get(op->slots_in, "mirror_v"); + bool mirror_udim = BMO_slot_bool_get(op->slots_in, "mirror_udim"); BMOpSlot *slot_targetmap; ototvert = bm->totvert; @@ -94,10 +95,22 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) for (i = 0; i < totlayer; i++) { luv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i); if (mirror_u) { - luv->uv[0] = 1.0f - luv->uv[0]; + float uv_u = luv->uv[0]; + if (mirror_udim) { + luv->uv[0] = ceilf(uv_u) - fmodf(uv_u, 1.0f); + } + else { + luv->uv[0] = 1.0f - uv_u; + } } if (mirror_v) { - luv->uv[1] = 1.0f - luv->uv[1]; + float uv_v = luv->uv[1]; + if (mirror_udim) { + luv->uv[1] = ceilf(uv_v) - fmodf(uv_v, 1.0f); + } + else { + luv->uv[1] = 1.0f - uv_v; + } } } } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 9e58d7df042..24e5aa496b9 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -363,6 +363,7 @@ enum { MOD_MIR_BISECT_FLIP_AXIS_X = (1 << 11), MOD_MIR_BISECT_FLIP_AXIS_Y = (1 << 12), MOD_MIR_BISECT_FLIP_AXIS_Z = (1 << 13), + MOD_MIR_MIRROR_UDIM = (1 << 14), }; typedef struct EdgeSplitModifierData { diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index e13b9caa90c..4dd8053218c 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2111,6 +2111,12 @@ static void rna_def_modifier_mirror(BlenderRNA *brna) prop, "Mirror V", "Mirror the V texture coordinate around the flip offset point"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "use_mirror_udim", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_MIRROR_UDIM); + RNA_def_property_ui_text( + prop, "Mirror UDIM", "Mirror the texture coordinate around each tile center"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "mirror_offset_u", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "uv_offset[0]"); RNA_def_property_range(prop, -1, 1); -- cgit v1.2.3