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.
This commit is contained in:
Campbell Barton 2016-07-13 17:45:55 +10:00
parent 95b1cf6f7d
commit 2aa0569861
5 changed files with 62 additions and 55 deletions

@ -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()

@ -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;
}
}
}
}
}
}

@ -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;

@ -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");
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_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");
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)

@ -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,