Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoward Trickey <howard.trickey@gmail.com>2021-03-08 02:13:19 +0300
committerHoward Trickey <howard.trickey@gmail.com>2021-03-08 02:13:19 +0300
commit1ba15f1f7f94616d52e8bbd80e22c9e34e45a81e (patch)
tree5437bbfec345fa2d931ff2754d04fd3e282c8d0a /source/blender/modifiers
parent7a34bd7c2886dfc812345c0b1649d63a9ee4666f (diff)
Speedup for usual non-manifold exact boolean case.
The commit rB6f63417b500d that made exact boolean work on meshes with holes (like Suzanne) unfortunately dramatically slowed things down on other non-manifold meshes that don't have holes and didn't need the per-triangle insideness test. This adds a hole_tolerant parameter, false by default, that the user can enable to get good results on non-manifold meshes with holes. Using false for this parameter speeds up the time from 90 seconds to 10 seconds on an example with 1.2M triangles.
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 070ba3a1bcf..0bfd0e54304 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -21,7 +21,7 @@
* \ingroup modifiers
*/
-// #ifdef DEBUG_TIME
+// #define DEBUG_TIME
#include <stdio.h>
@@ -422,7 +422,7 @@ static void BMD_mesh_intersection(BMesh *bm,
if (use_exact) {
BM_mesh_boolean(
- bm, looptris, tottri, bm_face_isect_pair, NULL, 2, use_self, false, bmd->operation);
+ bm, looptris, tottri, bm_face_isect_pair, NULL, 2, use_self, false, false, bmd->operation);
}
else {
BM_mesh_intersect(bm,
@@ -587,8 +587,16 @@ static Mesh *collection_boolean_exact(BooleanModifierData *bmd,
}
BM_mesh_elem_index_ensure(bm, BM_FACE);
- BM_mesh_boolean(
- bm, looptris, tottri, bm_face_isect_nary, shape, num_shapes, true, false, bmd->operation);
+ BM_mesh_boolean(bm,
+ looptris,
+ tottri,
+ bm_face_isect_nary,
+ shape,
+ num_shapes,
+ true,
+ false,
+ false,
+ bmd->operation);
result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
BM_mesh_free(bm);
@@ -651,10 +659,12 @@ static Mesh *exact_boolean_mesh(BooleanModifierData *bmd,
}
const bool use_self = (bmd->flag & eBooleanModifierFlag_Self) != 0;
+ const bool hole_tolerant = (bmd->flag & eBooleanModifierFlag_HoleTolerant) != 0;
result = BKE_mesh_boolean((const Mesh **)meshes,
(const float(**)[4][4])obmats,
BLI_array_len(meshes),
use_self,
+ hole_tolerant,
bmd->operation);
BLI_array_free(meshes);
@@ -846,31 +856,43 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "collection", 0, NULL, ICON_NONE);
}
- const bool use_exact = RNA_enum_get(ptr, "solver") == eBooleanModifierSolver_Exact;
-
uiItemR(layout, ptr, "solver", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ modifier_panel_end(layout, ptr);
+}
+
+static void solver_options_panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+ uiLayout *col = uiLayoutColumn(layout, true);
+
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+
+ const bool use_exact = RNA_enum_get(ptr, "solver") == eBooleanModifierSolver_Exact;
+ const bool operand_object = RNA_enum_get(ptr, "operand_type") == eBooleanModifierFlag_Object;
+
if (use_exact) {
/* When operand is collection, we always use_self. */
if (operand_object) {
- uiItemR(layout, ptr, "use_self", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "use_self", 0, NULL, ICON_NONE);
}
+ uiItemR(col, ptr, "hole_tolerant", 0, NULL, ICON_NONE);
}
else {
- uiItemR(layout, ptr, "double_threshold", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "double_threshold", 0, NULL, ICON_NONE);
}
if (G.debug) {
- uiLayout *col = uiLayoutColumn(layout, true);
+ col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "debug_options", 0, NULL, ICON_NONE);
}
-
- modifier_panel_end(layout, ptr);
}
static void panelRegister(ARegionType *region_type)
{
- modifier_panel_register(region_type, eModifierType_Boolean, panel_draw);
+ PanelType *panel = modifier_panel_register(region_type, eModifierType_Boolean, panel_draw);
+ modifier_subpanel_register(
+ region_type, "solver_options", "Solver Options", NULL, solver_options_panel_draw, panel);
}
ModifierTypeInfo modifierType_Boolean = {