From 2aa056986152c7e17a4c85b4dafb7c16bd692ed1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 13 Jul 2016 17:45:55 +1000 Subject: Boolean Modifier: Add back BMesh option There are still issues with overlapping geometry, however some of the issues reported are are causing problems, or fail entirely with Carve too. --- .../startup/bl_ui/properties_data_modifier.py | 15 +++------ source/blender/blenloader/intern/versioning_270.c | 13 ++++++++ source/blender/makesdna/DNA_modifier_types.h | 16 ++++----- source/blender/makesrna/intern/rna_modifier.c | 38 ++++++++-------------- source/blender/modifiers/intern/MOD_boolean.c | 35 +++++++++++++------- 5 files changed, 62 insertions(+), 55 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 7863c075344..c6bb6ccf05f 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -151,21 +151,16 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column() col.label(text="Operation:") col.prop(md, "operation", text="") + row = layout.row() + row.label("Solver:") + row.prop(md, "solver", expand=True) col = split.column() col.label(text="Object:") col.prop(md, "object", text="") - """ - layout.prop(md, "use_bmesh") - if md.use_bmesh: - box = layout.box() - box.label("BMesh Options:") - box.prop(md, "use_bmesh_separate") - box.prop(md, "use_bmesh_dissolve") - box.prop(md, "use_bmesh_connect_regions") - box.prop(md, "threshold") - """ + if md.solver == 'BMESH': + layout.prop(md, "double_threshold") def BUILD(self, layout, ob, md): split = layout.split() diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index b7b6ace3c1a..ac2811aeb06 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -1212,5 +1212,18 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } } + + if (!DNA_struct_elem_find(fd->filesdna, "BooleanModifierData", "float", "double_threshold")) { + Object *ob; + for (ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Boolean) { + BooleanModifierData *bmd = (BooleanModifierData *)md; + bmd->double_threshold = 1e-6f; + } + } + } + } } } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index a58e995f1c6..bbc8edf4344 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -641,8 +641,9 @@ typedef struct BooleanModifierData { struct Object *object; char operation; - char bm_flag, pad[2]; - float threshold; + char solver; + char pad[2]; + float double_threshold; } BooleanModifierData; typedef enum { @@ -651,13 +652,10 @@ typedef enum { eBooleanModifierOp_Difference = 2, } BooleanModifierOp; -/* temp bm_flag (debugging only) */ -enum { - eBooleanModifierBMeshFlag_Enabled = (1 << 0), - eBooleanModifierBMeshFlag_BMesh_Separate = (1 << 1), - eBooleanModifierBMeshFlag_BMesh_NoDissolve = (1 << 2), - eBooleanModifierBMeshFlag_BMesh_NoConnectRegions = (1 << 3), -}; +typedef enum { + eBooleanModifierSolver_Carve = 0, + eBooleanModifierSolver_BMesh = 1, +} BooleanSolver; typedef struct MDefInfluence { int vertex; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index ef74f01f9be..a9102000fac 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1895,6 +1895,12 @@ static void rna_def_modifier_boolean(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem prop_solver_items[] = { + {eBooleanModifierSolver_Carve, "CARVE", 0, "Carve", "Use the Carve boolean solver"}, + {eBooleanModifierSolver_BMesh, "BMESH", 0, "BMesh", "Use the BMesh boolean solver"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "BooleanModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Boolean Modifier", "Boolean operations modifier"); RNA_def_struct_sdna(srna, "BooleanModifierData"); @@ -1911,35 +1917,17 @@ static void rna_def_modifier_boolean(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Operation", ""); RNA_def_property_update(prop, 0, "rna_Modifier_update"); -#if 0 /* WITH_MOD_BOOLEAN */ - /* BMesh intersection options */ - prop = RNA_def_property(srna, "use_bmesh", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "bm_flag", eBooleanModifierBMeshFlag_Enabled); - RNA_def_property_ui_text(prop, "Use BMesh", "Use BMesh boolean calculation"); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - - prop = RNA_def_property(srna, "use_bmesh_separate", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "bm_flag", eBooleanModifierBMeshFlag_BMesh_Separate); - RNA_def_property_ui_text(prop, "Separate", "Keep edges separate"); + prop = RNA_def_property(srna, "solver", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_solver_items); + RNA_def_property_ui_text(prop, "Solver", ""); RNA_def_property_update(prop, 0, "rna_Modifier_update"); - prop = RNA_def_property(srna, "use_bmesh_dissolve", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "bm_flag", eBooleanModifierBMeshFlag_BMesh_NoDissolve); - RNA_def_property_ui_text(prop, "Dissolve", "Dissolve verts created from tessellated intersection"); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - - prop = RNA_def_property(srna, "use_bmesh_connect_regions", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "bm_flag", eBooleanModifierBMeshFlag_BMesh_NoConnectRegions); - RNA_def_property_ui_text(prop, "Calculate Holes", "Connect regions (needed for hole filling)"); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - - prop = RNA_def_property(srna, "threshold", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_sdna(prop, NULL, "threshold"); + prop = RNA_def_property(srna, "double_threshold", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_sdna(prop, NULL, "double_threshold"); RNA_def_property_range(prop, 0, 1.0f); - RNA_def_property_ui_range(prop, 0, 1, 1, 7); - RNA_def_property_ui_text(prop, "Threshold", ""); + RNA_def_property_ui_range(prop, 0, 1, 0.0001, 7); + RNA_def_property_ui_text(prop, "Overlap Threshold", "Threshold for checking overlapping geometry"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); -#endif } static void rna_def_modifier_array(BlenderRNA *brna) diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index 3f418fa16f3..693db961950 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -33,7 +33,7 @@ */ // #ifdef DEBUG_TIME -// #define USE_BMESH +#define USE_BMESH #ifdef WITH_MOD_BOOLEAN # define USE_CARVE WITH_MOD_BOOLEAN #endif @@ -71,6 +71,13 @@ #include "PIL_time_utildefines.h" #endif +static void initData(ModifierData *md) +{ + BooleanModifierData *bmd = (BooleanModifierData *)md; + + bmd->double_threshold = 1e-6f; +} + static void copyData(ModifierData *md, ModifierData *target) { #if 0 @@ -222,7 +229,9 @@ static DerivedMesh *applyModifier_bmesh( #ifdef DEBUG_TIME TIMEIT_START(boolean_bmesh); #endif - bm = BM_mesh_create_ex(&allocsize, ); + bm = BM_mesh_create( + &allocsize, + &((struct BMeshCreateParams){.use_toolflags = false,})); DM_to_bmesh_ex(dm_other, bm, true); DM_to_bmesh_ex(dm, bm, true); @@ -296,16 +305,21 @@ 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; + BM_mesh_intersect( bm, looptris, tottri, bm_face_isect_pair, NULL, false, - (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_Separate) != 0, - (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoDissolve) == 0, - (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoConnectRegions) == 0, + use_separate, + use_dissolve, + use_island_connect, bmd->operation, - bmd->threshold); + bmd->double_threshold); MEM_freeN(looptris); } @@ -409,15 +423,14 @@ static DerivedMesh *applyModifier( ModifierApplyFlag flag) { BooleanModifierData *bmd = (BooleanModifierData *)md; - const int method = (bmd->bm_flag & eBooleanModifierBMeshFlag_Enabled) ? 1 : 0; - switch (method) { + switch (bmd->solver) { #ifdef USE_CARVE - case 0: + case eBooleanModifierSolver_Carve: return applyModifier_carve(md, ob, derivedData, flag); #endif #ifdef USE_BMESH - case 1: + case eBooleanModifierSolver_BMesh: return applyModifier_bmesh(md, ob, derivedData, flag); #endif default: @@ -441,7 +454,7 @@ ModifierTypeInfo modifierType_Boolean = { /* deformMatricesEM */ NULL, /* applyModifier */ applyModifier, /* applyModifierEM */ NULL, - /* initData */ NULL, + /* initData */ initData, /* requiredDataMask */ requiredDataMask, /* freeData */ NULL, /* isDisabled */ isDisabled, -- cgit v1.2.3