[Bf-blender-cvs] [71959181ade] temp_bmesh_multires: * Fix bug with symmetrize creating non-manifold geometry. * Fix bug in pbvh face create

Joseph Eagar noreply at git.blender.org
Wed May 19 07:27:24 CEST 2021


Commit: 71959181ade3bff4640ea594eb582a9ac8c53e20
Author: Joseph Eagar
Date:   Tue May 18 22:26:49 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB71959181ade3bff4640ea594eb582a9ac8c53e20

* Fix bug with symmetrize creating non-manifold geometry.
* Fix bug in pbvh face create

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

M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/bmesh/intern/bmesh_log.c
M	source/blender/bmesh/operators/bmo_symmetrize.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c
M	source/blender/makesdna/DNA_meshdata_types.h

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

diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 7758a84e9e8..f2635856a64 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1060,7 +1060,7 @@ static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
   BM_FACES_OF_VERT_ITER_END;
 }
 
-static void pbvh_bmesh_face_remove(PBVH *pbvh, BMFace *f, bool log_face)
+static void pbvh_bmesh_face_remove(PBVH *pbvh, BMFace *f, bool log_face, bool check_verts)
 {
   PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
 
@@ -1072,32 +1072,30 @@ static void pbvh_bmesh_face_remove(PBVH *pbvh, BMFace *f, bool log_face)
 
   /* Check if any of this face's vertices need to be removed
    * from the node */
-  BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
-  BMLoop *l_iter = l_first;
-  do {
-    BMVert *v = l_iter->v;
-    if (pbvh_bmesh_node_vert_use_count_is_equal(pbvh, f_node, v, 1)) {
-      if (BLI_table_gset_haskey(f_node->bm_unique_verts, v)) {
-        /* Find a different node that uses 'v' */
-        PBVHNode *new_node;
+  if (check_verts) {
+    BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+    BMLoop *l_iter = l_first;
+    do {
+      BMVert *v = l_iter->v;
+      if (pbvh_bmesh_node_vert_use_count_is_equal(pbvh, f_node, v, 1)) {
+        if (BLI_table_gset_haskey(f_node->bm_unique_verts, v)) {
+          /* Find a different node that uses 'v' */
+          PBVHNode *new_node;
 
-        new_node = pbvh_bmesh_vert_other_node_find(pbvh, v);
-        BLI_assert(new_node || BM_vert_face_count_is_equal(v, 1));
+          new_node = pbvh_bmesh_vert_other_node_find(pbvh, v);
+          BLI_assert(new_node || BM_vert_face_count_is_equal(v, 1));
 
-        if (new_node) {
-          pbvh_bmesh_vert_ownership_transfer(pbvh, new_node, v);
+          if (new_node) {
+            pbvh_bmesh_vert_ownership_transfer(pbvh, new_node, v);
+          }
         }
         else {
-          BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
-          BLI_table_gset_remove(f_node->bm_unique_verts, v, NULL);
+          /* Remove from other verts */
+          BLI_table_gset_remove(f_node->bm_other_verts, v, NULL);
         }
       }
-      else {
-        /* Remove from other verts */
-        BLI_table_gset_remove(f_node->bm_other_verts, v, NULL);
-      }
-    }
-  } while ((l_iter = l_iter->next) != l_first);
+    } while ((l_iter = l_iter->next) != l_first);
+  }
 
   /* Remove face from node and top level */
   BLI_table_gset_remove(f_node->bm_faces, f, NULL);
@@ -1114,7 +1112,7 @@ static void pbvh_bmesh_face_remove(PBVH *pbvh, BMFace *f, bool log_face)
 
 void BKE_pbvh_bmesh_remove_face(PBVH *pbvh, BMFace *f, bool log_face)
 {
-  pbvh_bmesh_face_remove(pbvh, f, log_face);
+  pbvh_bmesh_face_remove(pbvh, f, log_face, true);
 }
 
 void BKE_pbvh_bmesh_remove_vertex(PBVH *pbvh, BMVert *v, bool log_vert)
@@ -2660,7 +2658,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
         &pbvh->bm->ldata, (const void **)lsrcs, lws, lws, 1, f_new->l_first->prev->head.data);
 
     /* Delete original */
-    pbvh_bmesh_face_remove(pbvh, f_adj, true);
+    pbvh_bmesh_face_remove(pbvh, f_adj, true, true);
     BM_face_kill(pbvh->bm, f_adj);
 
     /* Ensure new vertex is in the node */
@@ -2841,7 +2839,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
       l = l->next;
     } while (l != f_adj->l_first);
 
-    pbvh_bmesh_face_remove(pbvh, f_adj, true);
+    pbvh_bmesh_face_remove(pbvh, f_adj, true, true);
     BM_face_kill(pbvh->bm, f_adj);
   }
 
@@ -3015,7 +3013,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     } while (l1 != f_del->l_first);
 
     /* Remove the face */
-    pbvh_bmesh_face_remove(pbvh, f_del, true);
+    pbvh_bmesh_face_remove(pbvh, f_del, true, true);
     BM_face_kill(pbvh->bm, f_del);
 
     /* Check if any of the face's edges are now unused by any
@@ -3939,8 +3937,6 @@ static bool cleanup_valence_3_4(PBVH *pbvh,
       continue;
     }
 
-    PBVHVertexIter vi;
-    GSetIterator gi;
     BMVert *v;
 
     TGSET_ITER (v, node->bm_unique_verts) {
@@ -4022,7 +4018,7 @@ static bool cleanup_valence_3_4(PBVH *pbvh,
           BLI_table_gset_remove(node2->bm_unique_verts, v, NULL);
           BLI_table_gset_remove(node2->bm_other_verts, v, NULL);
 
-          pbvh_bmesh_face_remove(pbvh, f, true);
+          pbvh_bmesh_face_remove(pbvh, f, true, true);
         }
       }
 
@@ -4037,6 +4033,8 @@ static bool cleanup_valence_3_4(PBVH *pbvh,
       BMFace *f1 = NULL;
       if (vs[0] != vs[1] && vs[1] != vs[2] && vs[0] != vs[2]) {
         f1 = pbvh_bmesh_face_create(pbvh, n, vs, NULL, l->f, false, false);
+        normal_tri_v3(
+            f1->no, f1->l_first->v->co, f1->l_first->next->v->co, f1->l_first->prev->v->co);
       }
 
       if (val == 4 && vs[0] != vs[2] && vs[2] != vs[3] && vs[0] != vs[3]) {
@@ -4052,6 +4050,8 @@ static bool cleanup_valence_3_4(PBVH *pbvh,
         CustomData_bmesh_copy_data(
             &pbvh->bm->ldata, &pbvh->bm->ldata, ls[2]->head.data, &f2->l_first->next->head.data);
 
+        normal_tri_v3(
+            f2->no, f2->l_first->v->co, f2->l_first->next->v->co, f2->l_first->prev->v->co);
         BM_log_face_added(pbvh->bm_log, f2);
       }
 
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index f1b42072a86..c01bc92fd0d 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -57,12 +57,6 @@
 
 struct Mesh;
 
-typedef struct BMLogEdge {
-  uint v1, v2;
-  void *data;
-  int flag;
-} BMLogEdge;
-
 struct BMLogEntry {
   struct BMLogEntry *next, *prev;
 
@@ -142,6 +136,7 @@ struct BMLog {
   BMLogEntry *current_entry;
 
   int cd_dyn_vert;
+  bool dead;
 };
 
 typedef struct {
@@ -168,8 +163,8 @@ typedef struct {
 
 static void full_copy_swap(BMesh *bm, BMLog *log, BMLogEntry *entry);
 static void full_copy_load(BMesh *bm, BMLog *log, BMLogEntry *entry);
-
 static void bm_log_entry_free(BMLogEntry *entry);
+static bool bm_log_free_direct(BMLog *log, bool safe_mode);
 
 static void *log_ghash_lookup(BMLog *log, GHash *gh, const void *key)
 {
@@ -608,10 +603,10 @@ static void bm_log_vert_values_swap(
   }
 }
 
-ATTR_NO_OPT static void bm_log_face_values_swap(BMLog *log,
-                                                GHash *faces,
-                                                BMLogEntry *entry,
-                                                BMLogCallbacks *callbacks)
+static void bm_log_face_values_swap(BMLog *log,
+                                    GHash *faces,
+                                    BMLogEntry *entry,
+                                    BMLogCallbacks *callbacks)
 {
   void *scratch = log->bm->pdata.pool ? BLI_mempool_alloc(log->bm->pdata.pool) : NULL;
 
@@ -737,13 +732,18 @@ static BMLogEntry *bm_log_entry_create(void)
  * Note: does not free the log entry itself */
 static void bm_log_entry_free(BMLogEntry *entry)
 {
-  if (entry->log) {
-    entry->log->refcount--;
+  BMLog *log = entry->log;
+  bool kill_log = false;
+
+  if (log) {
+    log->refcount--;
 
-    if (entry->log->refcount < 0) {
+    if (log->refcount < 0) {
       fprintf(stderr, "BMLog refcount error\n");
-      entry->log->refcount = 0;
+      log->refcount = 0;
     }
+
+    kill_log = !log->refcount;
   }
 
   if (entry->full_copy_mesh) {
@@ -781,6 +781,10 @@ static void bm_log_entry_free(BMLogEntry *entry)
   CustomData_free(&entry->edata, 0);
   CustomData_free(&entry->ldata, 0);
   CustomData_free(&entry->pdata, 0);
+
+  if (kill_log) {
+    bm_log_free_direct(log, true);
+  }
 }
 
 static void bm_log_id_ghash_retake(RangeTreeUInt *unused_ids, GHash *id_ghash)
@@ -981,7 +985,7 @@ BMLog *BM_log_unfreeze(BMesh *bm, BMLogEntry *entry)
 /* Free all the data in a BMLog including the log itself
  * safe_mode means log->refcount will be checked, and if nonzero log will not be freed
  */
-bool BM_log_free(BMLog *log, bool safe_mode)
+static bool bm_log_free_direct(BMLog *log, bool safe_mode)
 {
   BMLogEntry *entry;
 
@@ -998,6 +1002,8 @@ bool BM_log_free(BMLog *log, bool safe_mode)
     return false;
   }
 
+  log->dead = true;
+
   BLI_rw_mutex_end(&log->lock);
 
   if (log->unused_ids) {
@@ -1018,11 +1024,24 @@ bool BM_log_free(BMLog *log, bool safe_mode)
     entry->log = NULL;
   }
 
-  MEM_freeN(log);
-
   return true;
 }
 
+bool BM_log_free(BMLog *log, bool safe_mode)
+{
+  if (log->dead) {
+    MEM_freeN(log);
+    return true;
+  }
+
+  if (bm_log_free_direct(log, safe_mode)) {
+    MEM_freeN(log);
+    return true;
+  }
+
+  return false;
+}
+
 /* Get the number of log entries */
 int BM_log_length(const BMLog *log)
 {
@@ -1127,6 +1146,12 @@ BMLogEntry *BM_log_entry_add(BMesh *bm, BMLog *log)
 
 BMLogEntry *BM_log_entry_add_ex(BMesh *bm, BMLog *log, bool combine_with_last)
 {
+  if (log->dead) {
+    fprintf(stderr, "BMLog Error: log is dead\n");
+    fflush(stderr);
+    return NULL;
+  }
+
   log->bm = bm;
 
   /* WARNING: this is now handled by the UndoSystem: BKE_UNDOSYS_TYPE_SCULPT
diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c
index f5bfd22bd51..6565df13ea8 100644
--- a/source/blender/bmesh/operators/bmo_symmetrize.c
+++ b/source/blender/bmesh/operators/bmo_symmetrize.c
@@ -28,6 +28,8 @@
 
 #define ELE_OUT 1
 
+#include "BLI_compiler_attrs.h"
+
 void bmo_symmetrize_exec(BMesh *bm, BMOperator *op)
 {
   const float dist = BMO_slot_float_get(op->slots_in, "dist");
@@ -96,6 +98,10 @@ void bmo_symmetrize_exec(BMesh *bm, BMOperator *op)
   slot_targetmap = BMO_slot_get(op_weld.slots_in, "targetmap");
 
   BMO_ITER (v, &siter, op_bisect.slots_out, "geom_cut.out", BM_VERT) {
+    if (!BM_vert_is_boundary(v)) {
+      continue;
+    }
+
     BMVert *v_dupe = BMO_slot_map_elem_get(slot_vertmap, v);
     BMO_slot_map_elem_insert(&op_weld, slot_targetmap, v_dupe, v);
   }
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 2ed195c5c41..ed676aaccf8 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -872,7 +872,7 @@ int SCULPT_vertex_face_set_get(S

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list