[Bf-blender-cvs] [d3a8855da3d] newboolean: Plumbed through faces that are on both sides of boolean op.
Howard Trickey
noreply at git.blender.org
Mon Dec 2 15:05:42 CET 2019
Commit: d3a8855da3dd8d0bbc87558c4a932943b2ab15eb
Author: Howard Trickey
Date: Fri Nov 8 09:13:41 2019 -0500
Branches: newboolean
https://developer.blender.org/rBd3a8855da3dd8d0bbc87558c4a932943b2ab15eb
Plumbed through faces that are on both sides of boolean op.
===================================================================
M source/blender/bmesh/tools/bmesh_boolean.c
===================================================================
diff --git a/source/blender/bmesh/tools/bmesh_boolean.c b/source/blender/bmesh/tools/bmesh_boolean.c
index 126a87164ef..8302513bc58 100644
--- a/source/blender/bmesh/tools/bmesh_boolean.c
+++ b/source/blender/bmesh/tools/bmesh_boolean.c
@@ -1158,7 +1158,11 @@ static int resolve_merge(int v, const IntIntMap *vert_merge_map)
return vmapped;
}
-static void apply_meshchange_to_bmesh(BMesh *bm, MeshChange *change)
+/* Apply the change to the BMesh. Ensure that indices are valid afterwards.
+ * Also, fill in r_both_side_faces with (new) indices of faces that have examples from
+ * both sides of the boolean operation (because they came from coplanar face intersections).
+ */
+static void apply_meshchange_to_bmesh(BoolState *bs, BMesh *bm, MeshChange *change, IntSet *r_both_side_faces)
{
int bm_tot_v, bm_tot_e, bm_tot_f, tot_new_v, tot_new_e, tot_new_f;
int i, v, e, f, v1, v2;
@@ -1171,6 +1175,8 @@ static void apply_meshchange_to_bmesh(BMesh *bm, MeshChange *change)
BMEdge **new_bmes, **face_bmes;
BMEdge *bme, *bme_eg;
BMFace *bmf, *bmf_eg;
+ LinkNode *both_side_bmfaces, *ln;
+ bool both_sides;
MeshAdd *meshadd = &change->add;
MeshDelete *meshdelete = &change->delete;
IntIntMap *vert_merge_map = &change->vert_merge_map;
@@ -1268,6 +1274,7 @@ static void apply_meshchange_to_bmesh(BMesh *bm, MeshChange *change)
}
/* Now the faces. */
+ both_side_bmfaces = NULL;
bm_tot_f = bm->totface;
tot_new_f = meshadd_totface(meshadd);
if (tot_new_f > 0) {
@@ -1283,8 +1290,30 @@ static void apply_meshchange_to_bmesh(BMesh *bm, MeshChange *change)
for (f = meshadd->findex_start; f < meshadd->findex_start + tot_new_f; f++) {
newface = meshadd_get_newface(meshadd, f);
BLI_assert(newface != NULL);
+ both_sides = false;
if (newface->example != -1) {
bmf_eg = bm->ftable[newface->example];
+
+ /* See if newface has examples on both sides of the boolean operation.
+ * Add its BMFace to both_sides_faces if so. */
+ if (newface->other_examples) {
+ bool in_a, in_b;
+ int testval, f_o;;
+ BMFace *bmf_eg_o;
+
+ testval = bs->test_fn(bmf_eg, bs->test_fn_user_data);
+ in_a = (testval == TEST_A);
+ in_b = (testval == TEST_B);
+ intset_iter_init(&is_iter, newface->other_examples);
+ for (; !intset_iter_done(&is_iter); intset_iter_step(&is_iter)) {
+ f_o = intset_iter_value(&is_iter);
+ bmf_eg_o = bm->ftable[f_o];
+ testval = bs->test_fn(bmf_eg_o, bs->test_fn_user_data);
+ in_a |= (testval == TEST_A);
+ in_b |= (testval == TEST_B);
+ }
+ both_sides = in_a && in_b;
+ }
}
else {
bmf_eg = NULL;
@@ -1314,6 +1343,9 @@ static void apply_meshchange_to_bmesh(BMesh *bm, MeshChange *change)
bmf = BM_face_create(bm, face_bmvs, face_bmes, facelen, bmf_eg, 0);
if (bmf_eg) {
BM_elem_select_copy(bm, bmf, bmf_eg);
+ if (both_sides) {
+ BLI_linklist_prepend_arena(&both_side_bmfaces, bmf, bs->mem_arena);
+ }
}
if (find_in_intset(&change->face_flip, f)) {
BM_face_normal_flip(bm, bmf);
@@ -1395,12 +1427,26 @@ static void apply_meshchange_to_bmesh(BMesh *bm, MeshChange *change)
}
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE | BM_FACE);
BM_mesh_elem_table_ensure(bm, BM_VERT | BM_EDGE | BM_FACE);
+
+ if (r_both_side_faces) {
+ /* Turn both_side_bmfaces list into face indices in r_both_side_faces. */
+ for (ln = both_side_bmfaces; ln; ln = ln->next) {
+ bmf = (BMFace *)ln->link;
+ f = BM_elem_index_get(bmf);
+ add_to_intset(bs, r_both_side_faces, f);
+#ifdef BOOLDEBUG
+ if (dbg_level > 0) {
+ printf("added %d to both_sides set, for bmf=%p\n", f, bmf);
+ }
+#endif
+ }
+ }
}
-static void apply_meshchange_to_imesh(IMesh *im, MeshChange *change)
+static void apply_meshchange_to_imesh(BoolState *bs, IMesh *im, MeshChange *change, IntSet *r_both_side_faces)
{
if (im->bm) {
- apply_meshchange_to_bmesh(im->bm, change);
+ apply_meshchange_to_bmesh(bs, im->bm, change, r_both_side_faces);
}
else {
/* TODO */
@@ -2237,7 +2283,7 @@ static PartPartIntersect *self_intersect_part_and_ppis(BoolState *bs,
MeshDelete *meshdelete = &change->delete;
IntIntMap *vert_merge_map = &change->vert_merge_map;
#ifdef BOOLDEBUG
- int dbg_level = 1;
+ int dbg_level = 0;
#endif
#ifdef BOOLDEBUG
@@ -2926,7 +2972,7 @@ static PartPartIntersect *non_coplanar_part_part_intersect(BoolState *bs,
MeshAdd *meshadd = &change->add;
IntSet *intersection_edges = &change->intersection_edges;
#ifdef BOOLDEBUG
- int dbg_level = 1;
+ int dbg_level = 0;
#endif
#ifdef BOOLDEBUG
@@ -3178,7 +3224,7 @@ static void intersect_partset_pair(BoolState *bs,
PartPartIntersect *isect;
BLI_bitmap *bpart_coplanar_with_apart;
#ifdef BOOLDEBUG
- int dbg_level = 1;
+ int dbg_level = 0;
#endif
#ifdef BOOLDEBUG
@@ -3282,7 +3328,7 @@ static void intersect_partset_pair(BoolState *bs,
}
}
-static void do_boolean_op(BoolState *bm, const int boolean_mode);
+static void do_boolean_op(BoolState *bm, const int boolean_mode, IntSet *both_side_faces);
/**
* Intersect faces
@@ -3303,8 +3349,9 @@ bool BM_mesh_boolean(BMesh *bm,
BoolState bs = {NULL};
MeshPartSet all_parts, a_parts, b_parts;
MeshChange meshchange;
+ IntSet both_side_faces;
#ifdef BOOLDEBUG
- int dbg_level = 2;
+ int dbg_level = 1;
#endif
init_imesh_from_bmesh(&bs.im, bm);
@@ -3321,6 +3368,7 @@ bool BM_mesh_boolean(BMesh *bm,
#endif
init_meshchange(&bs, &meshchange);
+ init_intset(&both_side_faces);
if (use_self) {
find_coplanar_parts(&bs, &all_parts, TEST_ALL, "all");
@@ -3334,12 +3382,13 @@ bool BM_mesh_boolean(BMesh *bm,
if (dbg_level > 1) {
dump_meshchange(&meshchange, "change for intersection");
+ dump_intset(&both_side_faces, "both side faces", "");
}
- apply_meshchange_to_imesh(&bs.im, &meshchange);
+ apply_meshchange_to_imesh(&bs, &bs.im, &meshchange, &both_side_faces);
if (boolean_mode != -1) {
- do_boolean_op(&bs, boolean_mode);
+ do_boolean_op(&bs, boolean_mode, &both_side_faces);
}
BLI_memarena_free(bs.mem_arena);
@@ -3491,17 +3540,17 @@ static bool point_is_inside_side(BoolState *bs, int side, const double co[3])
return (fabs(gwn) >= 0.5);
}
-static void do_boolean_op(BoolState *bs, const int boolean_mode)
+static void do_boolean_op(BoolState *bs, const int boolean_mode, IntSet *both_side_faces)
{
int *groups_array;
int(*group_index)[2];
int group_tot, totface;
double co[3];
int i, f, fg, fg_end, side, otherside;
- bool do_remove, do_flip, inside;
+ bool do_remove, do_flip, inside, both_sides;
MeshChange meshchange;
# ifdef BOOLDEBUG
- bool dbg_level = 0;
+ bool dbg_level = 1;
if (dbg_level > 0) {
printf("\nDO_BOOLEAN_OP, boolean_mode=%d\n\n", boolean_mode);
@@ -3542,9 +3591,10 @@ static void do_boolean_op(BoolState *bs, const int boolean_mode)
/* Test if first face of group is inside. */
f = groups_array[fg];
side = imesh_test_face(&bs->im, bs->test_fn, bs->test_fn_user_data, f);
+ both_sides = find_in_intset(both_side_faces, f);
# ifdef BOOLDEBUG
if (dbg_level > 0) {
- printf("group %d side = %d\n", i, side);
+ printf("group %d side = %d, both_sides = %d\n", i, side, both_sides);
}
# endif
@@ -3604,7 +3654,7 @@ static void do_boolean_op(BoolState *bs, const int boolean_mode)
}
# endif
- apply_meshchange_to_imesh(&bs->im, &meshchange);
+ apply_meshchange_to_imesh(bs, &bs->im, &meshchange, NULL);
MEM_freeN(group_index);
}
More information about the Bf-blender-cvs
mailing list