[Bf-blender-cvs] [786781304c1] temp_bmesh_multires: * Got box trim tool working for dyntopo - This required implementing SCULPT_UNDO_GEOMETRY for dyntopo. That turned out to be more work then I expected. Basically it writes an entire Mesh to BMLogEntry, which can be swapped with current bmesh. Tricky part was patching bm log ids.

Joseph Eagar noreply at git.blender.org
Tue Apr 27 22:21:39 CEST 2021


Commit: 786781304c16f44704ac45fe0d5d804dc0f8f927
Author: Joseph Eagar
Date:   Tue Apr 27 13:04:36 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB786781304c16f44704ac45fe0d5d804dc0f8f927

* Got box trim tool working for dyntopo
  - This required implementing SCULPT_UNDO_GEOMETRY for dyntopo.
    That turned out to be more work then I expected.  Basically
    it writes an entire Mesh to BMLogEntry, which can be swapped
    with current bmesh.  Tricky part was patching bm log ids.

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

M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/customdata.c
M	source/blender/blenkernel/intern/mesh.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/bmesh/intern/bmesh_log.c
M	source/blender/bmesh/intern/bmesh_log.h
M	source/blender/bmesh/intern/bmesh_mesh_convert.c
M	source/blender/bmesh/intern/bmesh_mesh_convert.h
M	source/blender/bmesh/operators/bmo_dissolve.c
M	source/blender/editors/sculpt_paint/paint_mask.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c

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

diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 5e8eb60f94d..5c73f4e3ca1 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -602,6 +602,9 @@ void CustomData_blend_write(struct BlendWriter *writer,
                             struct ID *id);
 void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count);
 
+void CustomData_unmark_temporary_nocopy(struct CustomData *data);
+void CustomData_mark_temporary_nocopy(struct CustomData *data);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index ee327c48a66..59818dbfb3a 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -73,6 +73,7 @@ typedef struct PBVHTriBuf {
 struct BMLog;
 struct BMesh;
 struct BMVert;
+struct BMEdge;
 struct BMFace;
 struct CCGElem;
 struct CCGKey;
@@ -699,6 +700,17 @@ void BKE_pbvh_bmesh_free_tris(PBVH *pbvh, PBVHNode *node);
 void BKE_pbvh_recalc_bmesh_boundary(PBVH *pbvh);
 void BKE_pbvh_bmesh_face_kill(PBVH *pbvh, struct BMFace *f);
 
+// note that e_tri and f_example are allowed to be NULL
+struct BMFace *BKE_pbvh_face_create_bmesh(PBVH *pbvh,
+                                          struct BMVert *v_tri[3],
+                                          struct BMEdge *e_tri[3],
+                                          const struct BMFace *f_example);
+
+// if node is NULL, one will be foudn in the pbvh, which potentially can be slow
+struct BMVert *BKE_pbvh_vert_create_bmesh(
+    PBVH *pbvh, float co[3], float no[3], PBVHNode *node, struct BMVert *v_example);
+PBVHNode *BKE_pbvh_node_from_face_bmesh(PBVH *pbvh, struct BMFace *f);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 54d7960e9b9..c065c448328 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -2943,6 +2943,22 @@ bool CustomData_is_referenced_layer(struct CustomData *data, int type)
   return (layer->flag & CD_FLAG_NOFREE) != 0;
 }
 
+void CustomData_unmark_temporary_nocopy(CustomData *data) {
+  for (int i=0; i<data->totlayer; i++) {
+    if (data->layers[i].flag & CD_FLAG_TEMPORARY) {
+      data->layers[i].flag &= ~CD_FLAG_NOCOPY;
+    }
+  }
+}
+
+void CustomData_mark_temporary_nocopy(CustomData *data) {
+  for (int i = 0; i < data->totlayer; i++) {
+    if (data->layers[i].flag & CD_FLAG_TEMPORARY) {
+      data->layers[i].flag |= CD_FLAG_NOCOPY;
+    }
+  }
+}
+
 void CustomData_free_temporary(CustomData *data, int totelem)
 {
   int i, j;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 3e730448ce8..13efde374d0 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1040,7 +1040,11 @@ Mesh *BKE_mesh_from_bmesh_nomain(BMesh *bm,
   BLI_assert(params->calc_object_remap == false);
   Mesh *mesh = BKE_id_new_nomain(ID_ME, NULL);
   BM_mesh_bm_to_me(NULL, NULL, bm, mesh, params);
-  BKE_mesh_copy_settings(mesh, me_settings);
+
+  if (me_settings) {
+    BKE_mesh_copy_settings(mesh, me_settings);
+  }
+
   return mesh;
 }
 
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 2ff61fa1e91..a6052390d7b 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -596,6 +596,7 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
                                       int node_index,
                                       const float co[3],
                                       const float no[3],
+                                      BMVert *v_example,
                                       const int cd_vert_mask_offset)
 {
   PBVHNode *node = &pbvh->nodes[node_index];
@@ -606,15 +607,27 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
   BMVert *v = BM_vert_create(pbvh->bm, co, NULL, BM_CREATE_SKIP_CD);
   CustomData_bmesh_set_default(&pbvh->bm->vdata, &v->head.data);
 
-  MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
+  if (v_example) {
+    v->head.hflag = v_example->head.hflag;
+
+    CustomData_bmesh_copy_data(&pbvh->bm->vdata, &pbvh->bm->vdata, v_example->head.data, &v->head.data);
+
+    /* This value is logged below */
+    copy_v3_v3(v->no, no);
+
+    //keep MDynTopoVert copied from v_example as-is
+  }
+  else {
+    MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
 
-  copy_v3_v3(mv->origco, co);
-  copy_v3_v3(mv->origno, no);
-  mv->origmask = 0.0f;
-  mv->flag = 0;
+    copy_v3_v3(mv->origco, co);
+    copy_v3_v3(mv->origno, no);
+    mv->origmask = 0.0f;
+    mv->flag = 0;
 
-  /* This value is logged below */
-  copy_v3_v3(v->no, no);
+    /* This value is logged below */
+    copy_v3_v3(v->no, no);
+  }
 
   BLI_table_gset_insert(node->bm_unique_verts, v);
   BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, node_index);
@@ -653,7 +666,9 @@ static BMFace *pbvh_bmesh_face_create(PBVH *pbvh,
     f = BM_face_create(pbvh->bm, v_tri, e_tri, 3, f_example, BM_CREATE_NOP);
   }
 
-  f->head.hflag = f_example->head.hflag;
+  if (f_example) {
+    f->head.hflag = f_example->head.hflag;
+  }
 
   BLI_table_gset_insert(node->bm_faces, f);
   BM_ELEM_CD_SET_INT(f, pbvh->cd_face_node_offset, node_index);
@@ -689,6 +704,136 @@ static BMFace *pbvh_bmesh_face_create(PBVH *pbvh,
   return f;
 }
 
+BMVert *BKE_pbvh_vert_create_bmesh(
+    PBVH *pbvh, float co[3], float no[3], PBVHNode *node, BMVert *v_example)
+{
+  if (!node) {
+    for (int i = 0; i < pbvh->totnode; i++) {
+      PBVHNode *node2 = pbvh->nodes + i;
+
+      if (!(node2->flag & PBVH_Leaf)) {
+        continue;
+      }
+
+      // ensure we have at least some node somewhere picked
+      node = node2;
+
+      bool ok = true;
+
+      for (int j = 0; j < 3; j++) {
+        if (co[j] < node2->vb.bmin[j] || co[j] >= node2->vb.bmax[j]) {
+          continue;
+        }
+      }
+
+      if (ok) {
+        break;
+      }
+    }
+  }
+
+  BMVert *v;
+
+  if (!node) {
+    printf("possible pbvh error\n");
+    v = BM_vert_create(pbvh->bm, co, v_example, BM_CREATE_NOP);
+    BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, DYNTOPO_NODE_NONE);
+
+    MDynTopoVert *mv = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_dyn_vert);
+
+    copy_v3_v3(mv->origco, co);
+
+    return v;
+  }
+
+  return pbvh_bmesh_vert_create(
+      pbvh, node - pbvh->nodes, co, no, v_example, pbvh->cd_vert_mask_offset);
+}
+
+PBVHNode *BKE_pbvh_node_from_face_bmesh(PBVH *pbvh, BMFace *f)
+{
+  return BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
+}
+
+BMFace *BKE_pbvh_face_create_bmesh(PBVH *pbvh,
+                                   BMVert *v_tri[3],
+                                   BMEdge *e_tri[3],
+                                   const BMFace *f_example)
+{
+  int ni = DYNTOPO_NODE_NONE;
+
+  for (int i = 0; i < 3; i++) {
+    BMVert *v = v_tri[i];
+    BMLoop *l;
+    BMIter iter;
+
+    BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+      int ni2 = BM_ELEM_CD_GET_INT(l->f, pbvh->cd_face_node_offset);
+      if (ni2 != DYNTOPO_NODE_NONE) {
+        ni = ni2;
+        break;
+      }
+    }
+  }
+
+  if (ni == DYNTOPO_NODE_NONE) {
+    BMFace *f;
+
+    // no existing nodes? find one
+    for (int i = 0; i < pbvh->totnode; i++) {
+      PBVHNode *node = pbvh->nodes + i;
+
+      if (!(node->flag & PBVH_Leaf)) {
+        continue;
+      }
+
+      for (int j = 0; j < 3; j++) {
+        BMVert *v = v_tri[j];
+
+        bool ok = true;
+
+        for (int k = 0; k < 3; k++) {
+          if (v->co[k] < node->vb.bmin[k] || v->co[k] >= node->vb.bmax[k]) {
+            ok = false;
+          }
+        }
+
+        if (ok &&
+            (ni == DYNTOPO_NODE_NONE || BLI_table_gset_len(node->bm_faces) < pbvh->leaf_limit)) {
+          ni = i;
+          break;
+        }
+      }
+
+      if (ni != DYNTOPO_NODE_NONE) {
+        break;
+      }
+    }
+
+    if (ni == DYNTOPO_NODE_NONE) {
+      // empty pbvh?
+      printf("possibly pbvh error\n");
+
+      if (e_tri) {
+        f = BM_face_create_verts(pbvh->bm, v_tri, 3, f_example, BM_CREATE_NOP, true);
+      }
+      else {
+        f = BM_face_create(pbvh->bm, v_tri, e_tri, 3, f_example, BM_CREATE_NOP);
+      }
+
+      if (f_example) {
+        f->head.hflag = f_example->head.hflag;
+      }
+
+      BM_ELEM_CD_SET_INT(f, pbvh->cd_face_node_offset, DYNTOPO_NODE_NONE);
+
+      return f;
+    }
+  }
+
+  return pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f_example, true, true);
+}
+
 /* Return the number of faces in 'node' that use vertex 'v' */
 #if 0
 static int pbvh_bmesh_node_vert_use_count(PBVH *pbvh, PBVHNode *node, BMVert *v)
@@ -2014,7 +2159,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
 
   int node_index = BM_ELEM_CD_GET_INT(e->v1, eq_ctx->cd_vert_node_offset);
   BMVert *v_new = pbvh_bmesh_vert_create(
-      pbvh, node_index, co_mid, no_mid, eq_ctx->cd_vert_mask_offset);
+      pbvh, node_index, co_mid, no_mid, NULL, eq_ctx->cd_vert_mask_offset);
   // transfer edge flags
 
   BMEdge *e1 = BM_edge_create(pbvh->bm, e->v1, v_new, e, BM_CREATE_NOP);
@@ -3904,6 +4049,11 @@ void BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
       tri.v[j] = (intptr_t)val[0];
 
       j++;
+
+      if (j >= 3) {
+        break;
+      }
+
       l = l->next;
     } while (l != f->l_first);
 
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 73dfd17a9fb..ab0af9f905d 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -32,6 +32,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_array.h"
+#include "BLI_compiler_attrs.h"
 #include "BLI_ghash.h"
 #include "BLI_listbase.h"
 #include "BLI_math.h"
@@ -39,9 +41,11 @@
 #include "BLI_threads.h"
 #include "BLI_utildefines.h"
 
+#include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 
 #include "BKE_customdata.h"
+#include "BKE_mesh.h"
 
 #include "bmesh.h"
 #include "bmesh_log.h"
@@ -51,6 +55,14 @@
 
 #define C

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list