diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_boolean.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_boolean.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index e649c8821fa..5811017f745 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -57,6 +57,7 @@ #include "BLI_alloca.h" #include "BLI_math_geom.h" #include "BKE_material.h" +#include "BKE_global.h" /* only to check G.debug */ #include "MEM_guardedalloc.h" #include "bmesh.h" @@ -206,6 +207,8 @@ static DerivedMesh *applyModifier_bmesh( result = get_quick_derivedMesh(ob, dm, bmd->object, dm_other, bmd->operation); if (result == NULL) { + const bool is_flip = (is_negative_m4(ob->obmat) != is_negative_m4(bmd->object->obmat)); + BMesh *bm; const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_DM(dm, dm_other); @@ -217,6 +220,16 @@ static DerivedMesh *applyModifier_bmesh( &((struct BMeshCreateParams){.use_toolflags = false,})); DM_to_bmesh_ex(dm_other, bm, true); + + if (UNLIKELY(is_flip)) { + const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS); + BMIter iter; + BMFace *efa; + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + BM_face_normal_flip_ex(bm, efa, cd_loop_mdisp_offset, true); + } + } + DM_to_bmesh_ex(dm, bm, true); /* main bmesh intersection setup */ @@ -228,7 +241,7 @@ static DerivedMesh *applyModifier_bmesh( looptris = MEM_mallocN(sizeof(*looptris) * looptris_tot, __func__); - BM_mesh_calc_tessellation(bm, looptris, &tottri); + BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri); /* postpone this until after tessellating * so we can use the original normals before the vertex are moved */ @@ -244,7 +257,6 @@ static DerivedMesh *applyModifier_bmesh( invert_m4_m4(imat, ob->obmat); mul_m4_m4m4(omat, imat, bmd->object->obmat); - BMVert *eve; i = 0; BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { @@ -257,8 +269,13 @@ static DerivedMesh *applyModifier_bmesh( /* we need face normals because of 'BM_face_split_edgenet' * we could calculate on the fly too (before calling split). */ { - float nmat[4][4]; - invert_m4_m4(nmat, omat); + float nmat[3][3]; + copy_m3_m4(nmat, omat); + invert_m3(nmat); + + if (UNLIKELY(is_flip)) { + negate_m3(nmat); + } const short ob_src_totcol = bmd->object->totcol; short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1); @@ -268,7 +285,7 @@ static DerivedMesh *applyModifier_bmesh( BMFace *efa; i = 0; BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - mul_transposed_mat3_m4_v3(nmat, efa->no); + mul_transposed_m3_v3(nmat, efa->no); normalize_v3(efa->no); BM_elem_flag_enable(efa, BM_FACE_TAG); /* temp tag to test which side split faces are from */ @@ -288,11 +305,17 @@ static DerivedMesh *applyModifier_bmesh( * currently this is ok for 'BM_mesh_intersect' */ // BM_mesh_normals_update(bm); - /* change for testing */ bool use_separate = false; bool use_dissolve = true; bool use_island_connect = true; + /* change for testing */ + if (G.debug & G_DEBUG) { + use_separate = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_Separate) != 0; + use_dissolve = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoDissolve) == 0; + use_island_connect = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoConnectRegions) == 0; + } + BM_mesh_intersect( bm, looptris, tottri, @@ -402,8 +425,8 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED( } static DerivedMesh *applyModifier( - ModifierData *md, Object *ob, - DerivedMesh *derivedData, + ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), + Object *ob, DerivedMesh *derivedData, ModifierApplyFlag flag) { BooleanModifierData *bmd = (BooleanModifierData *)md; |