[Bf-blender-cvs] [ffa62ecb603] sculpt-dev: Sculpt: shapekey fixes

Joseph Eagar noreply at git.blender.org
Wed Oct 13 11:50:50 CEST 2021


Commit: ffa62ecb603d3f98b966047c6e01f5447da759e8
Author: Joseph Eagar
Date:   Tue Oct 12 15:18:59 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rBffa62ecb603d3f98b966047c6e01f5447da759e8

Sculpt: shapekey fixes

* Fixed the completely broken shapekey conversion
  in BM_mesh_bm_from_me; this bug is most likely
  in master as well.
* Note that, while shapekeys now work in dyntopo
  it does not represent a complete sculpt layers
  implementation; the layers are still stored in
  world space.
* The motivation for fixing this was to keep
  dyntopo from destroying shapekey data, which
  was the only form of custom attributes it didn't
  support.
* That was because shapekeys were never being converted
  to custom attributes for bmesh to begin with, the
  conversion code was quite broken.

In addition to all this, this commit also has
a fix dyntopo collapse fixes.

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

M	source/blender/blenkernel/intern/brush_channel_define.h
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/mesh.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/bmesh/intern/bmesh_core.c
M	source/blender/bmesh/intern/bmesh_log.c
M	source/blender/bmesh/intern/bmesh_mesh_convert.c
M	source/blender/bmesh/intern/bmesh_mesh_convert.h
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c

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

diff --git a/source/blender/blenkernel/intern/brush_channel_define.h b/source/blender/blenkernel/intern/brush_channel_define.h
index b44a04ca44c..992fcd5f93d 100644
--- a/source/blender/blenkernel/intern/brush_channel_define.h
+++ b/source/blender/blenkernel/intern/brush_channel_define.h
@@ -207,7 +207,7 @@ places in rna_engine_codebase are relevent:
                            "used for DynTopo", 1.0f, 0.001f, 5.0f, 0.01f, 2.0f, false, BRUSH_CHANNEL_INHERIT)
   MAKE_BOOL(dyntopo_disable_smooth, "Disable Dyntopo Smooth", "Disable the small amount of smoothing dyntopo applies to improve numerical stability", false)
   MAKE_FLOAT_EX(projection, "Projection", "Amount of volume preserving projection", 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, false)
-  MAKE_FLOAT_EX(autosmooth_projection, "Auto-Smooth Projection", "Amount of volume preserving projection", 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, false)
+  MAKE_FLOAT_EX(autosmooth_projection, "Auto-Smooth Projection", "Amount of volume preserving projection for autosmooth", 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, false)
   MAKE_FLOAT_EX(topology_rake_projection, "Rake Projection", "Amount of volume preserving projection", 0.975f, 0.0f, 1.0f, 0.0f, 1.0f, false)
   MAKE_FLOAT(fset_slide, "Face Set Projection", "Stick face set boundaries to surface of mesh", 1.0f, 0.0f, 1.0f)
   MAKE_FLOAT(boundary_smooth, "Boundary Smooth", "Smooth hard boundaries", 0.0f, 0.0f, 1.0f)
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 5cbdd109405..19caee327e1 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -41,12 +41,13 @@
 
 #define USE_NEW_SPLIT
 #define SCULPTVERT_SMOOTH_BOUNDARY \
-  (SCULPTVERT_BOUNDARY | SCULPTVERT_FSET_BOUNDARY | SCULPTVERT_SHARP_BOUNDARY)
+  (SCULPTVERT_BOUNDARY | SCULPTVERT_FSET_BOUNDARY | SCULPTVERT_SHARP_BOUNDARY | \
+   SCULPTVERT_SEAM_BOUNDARY)
 #define SCULPTVERT_ALL_BOUNDARY \
   (SCULPTVERT_BOUNDARY | SCULPTVERT_FSET_BOUNDARY | SCULPTVERT_SHARP_BOUNDARY | \
    SCULPTVERT_SEAM_BOUNDARY)
 #define SCULPTVERT_SMOOTH_CORNER \
-  (SCULPTVERT_CORNER | SCULPTVERT_FSET_CORNER | SCULPTVERT_SHARP_CORNER)
+  (SCULPTVERT_CORNER | SCULPTVERT_FSET_CORNER | SCULPTVERT_SHARP_CORNER | SCULPTVERT_SEAM_CORNER)
 #define SCULPTVERT_ALL_CORNER \
   (SCULPTVERT_CORNER | SCULPTVERT_FSET_CORNER | SCULPTVERT_SHARP_CORNER | SCULPTVERT_SEAM_CORNER)
 
@@ -175,7 +176,7 @@ static void pbvh_split_edges(struct EdgeQueueContext *eq_ctx,
                              int totedge,
                              bool ignore_isolated_edges);
 void bm_log_message(const char *fmt, ...);
-void pbvh_bmesh_check_nodes_simple(PBVH *pbvh);
+
 static void edge_queue_create_local(struct EdgeQueueContext *eq_ctx,
                                     PBVH *pbvh,
                                     const float center[3],
@@ -288,7 +289,7 @@ static void fix_mesh(PBVH *pbvh, BMesh *bm)
   printf("done fixing mesh.\n");
 }
 
-//#define CHECKMESH
+#define CHECKMESH
 //#define TEST_INVALID_NORMALS
 
 #ifndef CHECKMESH
@@ -3963,6 +3964,15 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
 #endif
   BMEdge *e2;
 
+  for (int step = 0; step < 2; step++) {
+    BMVert *v_step = step ? v_del : v_conn;
+
+    e2 = v_step->e;
+    do {
+      e2->head.hflag &= ~tag;
+    } while ((e2 = BM_DISK_EDGE_NEXT(e2, v_step)) != v_step->e);
+  }
+
   for (int step = 0; step < 2; step++) {
     BMVert *v_step = step ? v_del : v_conn;
 
@@ -3972,12 +3982,12 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     do {
       BMLoop *l = e2->l;
 
-      e2->head.hflag |= tag;
-
-      if (e2 != e) {
+      if (e2 != e && !(e2->head.hflag & tag)) {
         BM_log_edge_removed(pbvh->bm_log, e2);
       }
 
+      e2->head.hflag |= tag;
+
       if (!l) {
         continue;  // edge will be killed later
       }
@@ -3997,6 +4007,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
 
   BLI_ghash_insert(deleted_verts, (void *)v_del, NULL);
 
+  pbvh_bmesh_check_nodes(pbvh);
+
   if (!snap) {
     float co[3];
 
@@ -4019,6 +4031,25 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     copy_v3_v3(v_conn->co, co);
   }
 
+  e2 = v_conn->e;
+  do {
+    BMLoop *l = e2->l;
+
+    if (!l) {
+      continue;
+    }
+
+    do {
+      BMLoop *l2 = l->f->l_first;
+      do {
+        MSculptVert *mv = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, l2->v);
+        mv->flag |= mupdateflag;
+      } while ((l2 = l2->next) != l->f->l_first);
+    } while ((l = l->radial_next) != e2->l);
+  } while ((e2 = BM_DISK_EDGE_NEXT(e2, v_conn)) != v_conn->e);
+
+  pbvh_bmesh_check_nodes(pbvh);
+
   for (int i = 0; i < BLI_array_len(delvs); i++) {
     BMVert *v = delvs[i];
     BMEdge *e = v->e;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 6595c8e90d7..28f58b54816 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1148,6 +1148,7 @@ BMesh *BKE_mesh_to_bmesh(Mesh *me,
                                   .calc_face_normal = false,
                                   .add_key_index = add_key_index,
                                   .use_shapekey = true,
+                                  .create_shapekey_layers = true,
                                   .active_shapekey = ob->shapenr,
                               });
 }
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 45cfeb3bcb1..144f64a6b82 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -28,6 +28,7 @@
 
 #include "DNA_brush_types.h"
 #include "DNA_gpencil_types.h"
+#include "DNA_key_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
@@ -85,6 +86,7 @@ void SCULPT_on_sculptsession_bmesh_free(SculptSession *ss);
 void SCULPT_dyntopo_node_layers_add(SculptSession *ss);
 BMesh *SCULPT_dyntopo_empty_bmesh();
 void SCULPT_undo_ensure_bmlog(Object *ob);
+void SCULPT_update_customdata_refs(SculptSession *ss);
 
 static void init_mdyntopo_layer(SculptSession *ss, PBVH *pbvh, int totvert);
 
@@ -1401,7 +1403,7 @@ static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
 
   if (ss->bm) {
     if (ob->data) {
-      Mesh *me = BKE_object_get_original_mesh(ob);
+      // Mesh *me = BKE_object_get_original_mesh(ob);
 
       BM_mesh_bm_to_me(
           NULL,
@@ -1415,6 +1417,7 @@ static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
                                        */
                                        .copy_temp_cdlayers = false,
                                        .ignore_mesh_id_layers = false,
+                                       .update_shapekey_indices = true,
                                        .cd_mask_extra = CD_MASK_MESH_ID | CD_MASK_DYNTOPO_VERT
 
           }));
@@ -1852,6 +1855,58 @@ static void sculpt_update_object(Depsgraph *depsgraph,
   }
 
   BKE_sculptsession_check_mdyntopo(ob->sculpt, pbvh, totvert);
+  if (ss->bm && me->key && ob->shapenr != ss->bm->shapenr) {
+    KeyBlock *actkey = BLI_findlink(&me->key->block, ss->bm->shapenr - 1);
+    KeyBlock *newkey = BLI_findlink(&me->key->block, ob->shapenr - 1);
+
+    if (!actkey) {
+      printf("%s: failed to find active shapekey\n", __func__);
+    }
+    if (!newkey) {
+      printf("%s: failed to find new active shapekey\n", __func__);
+    }
+
+    if (actkey && newkey) {
+      int cd_co1 = CustomData_get_named_layer_index(&ss->bm->vdata, CD_SHAPEKEY, actkey->name);
+      int cd_co2 = CustomData_get_named_layer_index(&ss->bm->vdata, CD_SHAPEKEY, newkey->name);
+
+      if (cd_co1 == -1) {  // non-recoverable error
+        printf("%s: failed to find active shapekey in customdata.\n", __func__);
+        return;
+      }
+      else if (cd_co2 == -1) {
+        BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_SHAPEKEY, newkey->name);
+        cd_co2 = CustomData_get_named_layer_index(&ss->bm->vdata, CD_SHAPEKEY, newkey->name);
+        SCULPT_update_customdata_refs(ss);
+      }
+
+      cd_co1 = ss->bm->vdata.layers[cd_co1].offset;
+      cd_co2 = ss->bm->vdata.layers[cd_co2].offset;
+
+      BMVert *v;
+      BMIter iter;
+      BM_ITER_MESH (v, &iter, ss->bm, BM_VERTS_OF_MESH) {
+        float *co1 = BM_ELEM_CD_GET_VOID_P(v, cd_co1);
+        float *co2 = BM_ELEM_CD_GET_VOID_P(v, cd_co2);
+
+        copy_v3_v3(co1, v->co);
+        copy_v3_v3(v->co, co2);
+      }
+
+      ss->bm->shapenr = ob->shapenr;
+
+      if (ss->pbvh) {
+        PBVHNode **nodes;
+        int totnode;
+        BKE_pbvh_get_nodes(ss->pbvh, PBVH_Leaf, &nodes, &totnode);
+
+        for (int i = 0; i < totnode; i++) {
+          BKE_pbvh_node_mark_update(nodes[i]);
+          BKE_pbvh_node_mark_update_tri_area(nodes[i]);
+        }
+      }
+    }
+  }
 }
 
 void BKE_sculpt_update_object_before_eval(Object *ob)
@@ -2433,7 +2488,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
       }
     }
     else if (BKE_pbvh_type(pbvh) == PBVH_BMESH) {
-      Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
+      // Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
 
       SCULPT_dynamic_topology_sync_layers(ob, BKE_object_get_original_mesh(ob));
     }
@@ -2452,8 +2507,6 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
     Mesh *mesh_orig = BKE_object_get_original_mesh(ob);
     bool is_dyntopo = (mesh_orig->flag & ME_SCULPT_DYNAMIC_TOPOLOGY);
 
-    void SCULPT_update_customdata_refs(SculptSession * ss);
-
     if (is_dyntopo) {
       BMesh *bm = SCULPT_dyntopo_empty_bmesh();
 
@@ -2467,6 +2520,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
                                                         .active_shapekey = ob->shapenr,
                                                         .ignore_id_layers = false,
                                                         .copy_temp_cdlayers = true,
+                                                        .create_shapekey_layers = true,
                                                         .cd_mask_extra = CD_MASK_DYNTOPO_VERT}));
 
       

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list