[Bf-blender-cvs] [6945602ae30] newboolean: Keep track of other orig faces besides eg for a face.

Howard Trickey noreply at git.blender.org
Mon Dec 2 15:05:39 CET 2019


Commit: 6945602ae303bccba379091d6cd924452e6acd0c
Author: Howard Trickey
Date:   Thu Nov 7 09:25:07 2019 -0500
Branches: newboolean
https://developer.blender.org/rB6945602ae303bccba379091d6cd924452e6acd0c

Keep track of other orig faces besides eg for a face.

===================================================================

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 5c90affc5f0..126a87164ef 100644
--- a/source/blender/bmesh/tools/bmesh_boolean.c
+++ b/source/blender/bmesh/tools/bmesh_boolean.c
@@ -139,6 +139,7 @@ typedef struct NewFace {
   IntPair *vert_edge_pairs; /* Array of len (vert, edge) pairs. */
   int len;
   int example; /* If not -1, example face in IMesh. */
+  IntSet *other_examples; /* rest of faces in IMesh that are originals for this face */
 } NewFace;
 
 /* MeshDelete holds an incremental deletion to an IMesh.
@@ -1581,7 +1582,7 @@ static int meshadd_add_edge(
 
 /* This assumes that vert_edge is an arena-allocated array that will persist. */
 static int meshadd_add_face(
-    BoolState *bs, MeshAdd *meshadd, IntPair *vert_edge, int len, int example)
+    BoolState *bs, MeshAdd *meshadd, IntPair *vert_edge, int len, int example, IntSet *other_examples)
 {
   NewFace *newf;
   MemArena *arena = bs->mem_arena;
@@ -1590,6 +1591,7 @@ static int meshadd_add_face(
   newf->vert_edge_pairs = vert_edge;
   newf->len = len;
   newf->example = example;
+  newf->other_examples = other_examples;
   BLI_linklist_append_arena(&meshadd->faces, newf, arena);
   return meshadd->findex_start + BLI_linklist_count(meshadd->faces.list) - 1;
 }
@@ -2002,13 +2004,21 @@ static bool part_may_intersect_partset(const MeshPart *part, const MeshPartSet *
   return isect_aabb_aabb_v3_db(part->bbmin, part->bbmax, partset->bbmin, partset->bbmax);
 }
 
-/* Return true if a_plane and b_plane are the same plane, to within eps. */
+/* Return true if a_plane and b_plane are the same plane, to within eps.
+ * Assume normal part of plane is normalized. */
 static bool planes_are_coplanar(const double a_plane[4], const double b_plane[4], double eps)
 {
-  if (fabs(a_plane[3] - b_plane[3]) > eps) {
-    return false;
+  double norms_dot;
+
+  /* They are the same plane even if they have opposite-facing normals,
+   * in which case the 4th constants will also be opposite. */
+  norms_dot = dot_v3v3_db(a_plane, b_plane);
+  if (norms_dot > 0.0) {
+    return fabs(norms_dot - 1.0) <= eps && fabs(a_plane[3] - b_plane[3]) <= eps;
+  }
+  else {
+    return fabs(norms_dot + 1.0) <= eps && fabs(a_plane[3] + b_plane[3]) <= eps;
   }
-  return fabs(dot_v3v3_db(a_plane, b_plane) - 1.0f) <= eps;
 }
 
 /* Return the MeshPart in partset for plane.
@@ -2208,7 +2218,7 @@ static PartPartIntersect *self_intersect_part_and_ppis(BoolState *bs,
   IMeshPlus imp;
   int i, j, part_nf, part_ne, part_nv, tot_ne, face_len, v, e, f, v1, v2;
   int nfaceverts, v_index, e_index, f_index, faces_index;
-  int in_v, out_v, out_v2, start, in_e, out_e, in_f, out_f, e_eg, f_eg;
+  int in_v, out_v, out_v2, start, in_e, out_e, in_f, out_f, e_eg, f_eg, f_eg_o, eg_len;
   int *imp_v, *imp_e;
   IntPair *new_face_data;
   IMesh *im = &bs->im;
@@ -2218,6 +2228,7 @@ static PartPartIntersect *self_intersect_part_and_ppis(BoolState *bs,
   IntIntMap in_to_vmap;
   IntIntMap in_to_emap;
   IntIntMap in_to_fmap;
+  IntSet *f_other_egs;
   double mat_2d[3][3];
   double mat_2d_inv[3][3];
   double xyz[3], save_z, p[3], q[3], fno[3];
@@ -2226,7 +2237,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 = 0;
+  int dbg_level = 1;
 #endif
 
 #ifdef BOOLDEBUG
@@ -2599,13 +2610,27 @@ static PartPartIntersect *self_intersect_part_and_ppis(BoolState *bs,
   for (out_f = 0; out_f < out->faces_len; out_f++) {
     in_f = -1;
     f_eg = -1;
+    f_other_egs = NULL;
     if (out->faces_orig_len_table[out_f] > 0) {
       start = out->faces_orig_start_table[out_f];
-      in_f = min_int_in_array(&out->faces_orig[start], out->faces_orig_len_table[out_f]);
+      eg_len = out->faces_orig_len_table[out_f];
+      in_f = min_int_in_array(&out->faces_orig[start], eg_len);
       if (!find_in_intintmap(&in_to_fmap, in_f, &f_eg)) {
         printf("shouldn't happen, %d not in in_to_fmap\n", in_f);
         BLI_assert(false);
       }
+      if (eg_len > 1) {
+        /* Record the other examples too. They may be needed for boolean operations. */
+        f_other_egs = BLI_memarena_alloc(arena, sizeof(*f_other_egs));
+        for (i = start; i < start + eg_len; i++) {
+          if (!find_in_intintmap(&in_to_fmap, out->faces_orig[i], &f_eg_o)) {
+            printf("shouldn't happen, %d not in in_to_fmap\n", out->faces_orig[i]);
+          }
+          if (f_eg_o != f_eg) {
+            add_to_intset(bs, f_other_egs, f_eg_o);
+          }
+        }
+      }
       /* If f_eg is in IMesh then need to record f_eg and any other faces
        * in the orig for out_f as deleted. */
       if (f_eg < imesh_totface(im)) {
@@ -2645,7 +2670,7 @@ static PartPartIntersect *self_intersect_part_and_ppis(BoolState *bs,
       }
       new_face_data[i].second = e;
     }
-    f = meshadd_add_face(bs, meshadd, new_face_data, face_len, f_eg);
+    f = meshadd_add_face(bs, meshadd, new_face_data, face_len, f_eg, f_other_egs);
     add_face_to_partpartintersect(bs, ppi_out, f);
   }
 
@@ -2901,7 +2926,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 = 0;
+  int dbg_level = 1;
 #endif
 
 #ifdef BOOLDEBUG
@@ -3153,7 +3178,7 @@ static void intersect_partset_pair(BoolState *bs,
   PartPartIntersect *isect;
   BLI_bitmap *bpart_coplanar_with_apart;
 #ifdef BOOLDEBUG
-  int dbg_level = 0;
+  int dbg_level = 1;
 #endif
 
 #ifdef BOOLDEBUG
@@ -3279,7 +3304,7 @@ bool BM_mesh_boolean(BMesh *bm,
   MeshPartSet all_parts, a_parts, b_parts;
   MeshChange meshchange;
 #ifdef BOOLDEBUG
-  int dbg_level = 1;
+  int dbg_level = 2;
 #endif
 
   init_imesh_from_bmesh(&bs.im, bm);
@@ -3307,6 +3332,10 @@ bool BM_mesh_boolean(BMesh *bm,
     intersect_partset_pair(&bs, &a_parts, &b_parts, &meshchange);
   }
 
+  if (dbg_level > 1) {
+    dump_meshchange(&meshchange, "change for intersection");
+  }
+
   apply_meshchange_to_imesh(&bs.im, &meshchange);
 
   if (boolean_mode != -1) {
@@ -3657,7 +3686,10 @@ ATTU static void dump_meshadd(const MeshAdd *ma, const char *label)
     i = ma->findex_start;
     for (ln = ma->faces.list; ln; ln = ln->next) {
       nf = (NewFace *)ln->link;
-      printf("  %d: face of length %d, example %d\n     ", i, nf->len, nf->example);
+      printf("  %d: face of length %d, example %d\n", i, nf->len, nf->example);
+      if (nf->other_examples) {
+        dump_intset(nf->other_examples, "other examples", "    ");
+      }
       for (j = 0; j < nf->len; j++) {
         printf("(v=%d,e=%d)", nf->vert_edge_pairs[j].first, nf->vert_edge_pairs[j].second);
       }
@@ -3705,7 +3737,7 @@ ATTU static void dump_intset(const IntSet *set, const char *label, const char *p
   LinkNode *ln;
   int v;
 
-  printf("%sindexedintset %s\n", prefix, label);
+  printf("%sintset %s\n%s", prefix, label, prefix);
   for (ln = set->list; ln; ln = ln->next) {
     v = POINTER_AS_INT(ln->link);
     printf("%d ", v);



More information about the Bf-blender-cvs mailing list