[Bf-blender-cvs] [e11ba956d21] sculpt-dev: Sculpt: various uv-related fixed

Joseph Eagar noreply at git.blender.org
Thu Oct 7 06:55:26 CEST 2021


Commit: e11ba956d21b298d24885af30aad4a40a301d125
Author: Joseph Eagar
Date:   Wed Oct 6 21:54:10 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rBe11ba956d21b298d24885af30aad4a40a301d125

Sculpt: various uv-related fixed

* The dyntopo collapse function now
  properly snaps UVs, including at
  island boundaries.
* PBVHTriBufs are now split by UVs
  (and face sets); this turned out
  to be surprising easy.
* Also fixed a few bugs relating to
  hiding/revealing stuff.

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/brush_engine_presets.c
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/editors/sculpt_paint/paint_hide.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_displacement.h
M	source/blender/editors/sculpt_paint/sculpt_smooth.c
M	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/windowmanager/intern/wm_init_exit.c

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 229fb7bb7e4..4b92a614cc6 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -505,6 +505,7 @@ void BKE_pbvh_bmesh_update_all_valence(PBVH *pbvh);
 void BKE_pbvh_bmesh_flag_all_disk_sort(PBVH *pbvh);
 bool BKE_pbvh_bmesh_mark_update_valence(PBVH *pbvh, SculptVertRef vertex);
 
+void BKE_pbvh_node_mark_update_triangulation(PBVHNode *node);
 void BKE_pbvh_node_mark_original_update(PBVHNode *node);
 void BKE_pbvh_node_mark_update_tri_area(PBVHNode *node);
 void BKE_pbvh_update_all_tri_areas(PBVH *pbvh);
@@ -642,7 +643,8 @@ typedef struct PBVHVertexIter {
   bool visible;
 } PBVHVertexIter;
 
-#define BKE_PBVH_SCULPTVERT(cd_sculpt_vert, v) ((MSculptVert *)BM_ELEM_CD_GET_VOID_P(v, cd_sculpt_vert))
+#define BKE_PBVH_SCULPTVERT(cd_sculpt_vert, v) \
+  ((MSculptVert *)BM_ELEM_CD_GET_VOID_P(v, cd_sculpt_vert))
 
 void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode);
 
@@ -851,7 +853,7 @@ void BKE_pbvh_set_symmetry(PBVH *pbvh, int symmetry, int boundary_symmetry);
 #if 0
 typedef enum {
   SCULPT_TEXTURE_UV = 1 << 0,  // per-uv
-  // SCULPT_TEXTURE_PTEX?
+  SCULPT_TEXTURE_GRIDS = 1<<1
 } SculptTextureType;
 
 typedef int TexLayerRef;
@@ -870,6 +872,8 @@ typedef struct SculptTextureDef {
 
   void (*build_begin)(PBVH *pbvh, PBVHNode *node, TexLayerRef vdm);
 
+  void (*calc_bounds)(PBVH *pbvh, PBVHNode *node, float r_min[3], float r_max[3], TexLayerRef vdm);
+
   /*vdms can cache data per node, which is freed to maintain memory limit.
     they store cache in the same structure they return in buildNodeData.*/
   void (*freeCachedData)(PBVH *pbvh, PBVHNode *node, TexLayerRef vdm);
@@ -879,6 +883,8 @@ typedef struct SculptTextureDef {
   void *(*buildNodeData)(PBVH *pbvh, PBVHNode *node);
   bool (*validate)(PBVH *pbvh, TexLayerRef vdm);
 
+  void (*setVertexCos)(PBVH *pbvh, PBVHNode *node, SculptVertRef *verts, int totvert, TexLayerRef vdm);
+
   void (*getPointsFromNode)(PBVH *pbvh,
                             PBVHNode *node,
                             TexLayerRef vdm,
@@ -924,7 +930,7 @@ typedef struct SculptTextureDef {
       PBVH *pbvh, PBVHNode *node, TexLayerRef vdm, TexPointRef *ids, int totid);
 
   /*displacement texture stuff*/
-  // can be tangent, object space displacement, whatever
+  // can be tangent, object space displacement
   void (*worldToDelta)(PBVH *pbvh, PBVHNode *node, TexLayerRef vdm, TexPointRef *ids, int totid);
   void (*deltaToWorld)(PBVH *pbvh, PBVHNode *node, TexLayerRef vdm, TexPointRef *ids, int totid);
 } SculptDisplacementDef;
diff --git a/source/blender/blenkernel/intern/brush_engine_presets.c b/source/blender/blenkernel/intern/brush_engine_presets.c
index b94b4382fdc..8512ce9992c 100644
--- a/source/blender/blenkernel/intern/brush_engine_presets.c
+++ b/source/blender/blenkernel/intern/brush_engine_presets.c
@@ -298,6 +298,7 @@ static bool check_builtin_init()
   SETCAT(topology_rake_projection, "Smoothing");
   SETCAT(topology_rake_use_spacing, "Smoothing");
   SETCAT(topology_rake_spacing, "Smoothing");
+  SETCAT(topology_rake_mode, "Smoothing");
 
   SETCAT(boundary_smooth, "Smoothing");
   SETCAT(fset_slide, "Smoothing");
@@ -1367,6 +1368,7 @@ void BKE_brush_channelset_ui_init(Brush *brush, int tool)
     case SCULPT_TOOL_SIMPLIFY:
       SHOWCTX(autosmooth);
       SHOWCTX(topology_rake);
+      SHOWCTX(topology_rake_mode);
       break;
     case SCULPT_TOOL_LAYER:
       SHOWWRK(use_persistent);
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 67384fb9cb8..8818299ea33 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -3643,6 +3643,20 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     return;
   }
 
+  int uvidx = pbvh->bm->ldata.typemap[CD_MLOOPUV];
+  CustomDataLayer *uv_layer = NULL;
+  int totuv = 0;
+
+  if (uvidx >= 0) {
+    uv_layer = pbvh->bm->ldata.layers + uvidx;
+    totuv = 0;
+
+    while (uvidx < pbvh->bm->ldata.totlayer && pbvh->bm->ldata.layers[uvidx].type == CD_MLOOPUV) {
+      uvidx++;
+      totuv++;
+    }
+  }
+
   /*have to check edge flags directly, vertex flag test above isn't specific enough and
     can sometimes let bad edges through*/
   if ((mv1->flag & SCULPTVERT_SHARP_BOUNDARY) && (e->head.hflag & BM_ELEM_SMOOTH)) {
@@ -3783,72 +3797,109 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
 
     CustomData_bmesh_interp(&pbvh->bm->vdata, v_blocks, v_ws, NULL, 2, v_conn->head.data);
     BM_ELEM_CD_SET_INT(v_conn, pbvh->cd_vert_node_offset, ni_conn);
+  }
 
-    BMLoop **ls = NULL;
-    void **blocks = NULL;
-    float *ws = NULL;
-
-    BLI_array_staticdeclare(ls, 64);
-    BLI_array_staticdeclare(blocks, 64);
-    BLI_array_staticdeclare(ws, 64);
+  // deal with UVs
+  if (e->l) {
+    const int lflag = BM_ELEM_TAG_ALT;
 
     int totl = 0;
+    BMLoop *l = e->l;
 
-    BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
-      MSculptVert *mv_l = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, l->next->v);
-      MV_ADD_FLAG(mv_l, mupdateflag);
+    for (int step = 0; step < 2; step++) {
+      BMVert *v = step ? e->v2 : e->v1;
+      BMEdge *e2 = v->e;
 
-      BLI_array_append(ls, l);
-      totl++;
-    }
-    BM_LOOPS_OF_VERT_ITER_END;
+      if (!e2) {
+        continue;
+      }
 
-    BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
-      MSculptVert *mv_l = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, l->next->v);
-      MV_ADD_FLAG(mv_l, mupdateflag);
+      do {
+        BMLoop *l2 = e2->l;
 
-      BLI_array_append(ls, l);
-      totl++;
-    }
-    BM_LOOPS_OF_VERT_ITER_END;
+        if (!l2) {
+          continue;
+        }
 
-    float w = totl > 0 ? 1.0f / (float)(totl) : 1.0f;
+        do {
+          bool ok = true;
+          BMLoop *l3 = l2->v != v ? l2->next : l2;
 
-    for (int i = 0; i < totl; i++) {
-      BLI_array_append(blocks, ls[i]->head.data);
-      BLI_array_append(ws, w);
+          /* store visit bits for each uv layer in l3->head.index */
+          l3->head.index = 0;
+        } while ((l2 = l2->radial_next) != e2->l);
+      } while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
     }
 
-    // snap customdata
-    if (totl > 0) {
-      CustomData_bmesh_interp(
-          &pbvh->bm->ldata, (const void **)blocks, ws, NULL, totl, ls[0]->head.data);
-      //*
-      BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
-        BMLoop *l2 = l->v != v_del ? l->next : l;
+    float(*uv)[2] = alloca(sizeof(float) * 4 * totuv);
 
-        if (l2 == ls[0]) {
-          continue;
-        }
+    do {
+      BMLoop *ls2[2] = {l->head.data, l->next->head.data};
+      float ws2[2] = {0.5f, 0.5f};
 
-        CustomData_bmesh_copy_data(
-            &pbvh->bm->ldata, &pbvh->bm->ldata, ls[0]->head.data, &l2->head.data);
+      if (!snap) {
+        const int axis = l->v == v_del ? 0 : 1;
+
+        ws2[axis] = 0.0f;
+        ws2[axis ^ 1] = 1.0f;
       }
-      BM_LOOPS_OF_VERT_ITER_END;
 
-      BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
-        BMLoop *l2 = l->v != v_conn ? l->next : l;
+      float uv[2][2];
+      for (int step = 0; uv_layer && step < 2; step++) {
+        BMLoop *l1 = step ? l : l->next;
 
-        if (l2 == ls[0]) {
-          continue;
+        for (int k = 0; k < totuv; k++) {
+          MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l1, uv_layer[k].offset);
+
+          copy_v2_v2(uv[k * 2 + step], luv->uv);
         }
+      }
+
+      CustomData_bmesh_interp(&pbvh->bm->ldata, ls2, ws2, NULL, 2, l->head.data);
+      CustomData_bmesh_copy_data(
+          &pbvh->bm->ldata, &pbvh->bm->ldata, l->head.data, &l->next->head.data);
+
+      for (int step = 0; totuv >= 0 && step < 2; step++) {
+        BMVert *v = step ? l->next->v : l->v;
+        BMLoop *l1 = step ? l->next : l;
+        BMEdge *e2 = v->e;
+
+        do {
+          BMLoop *l2 = e2->l;
 
-        CustomData_bmesh_copy_data(
-            &pbvh->bm->ldata, &pbvh->bm->ldata, ls[0]->head.data, &l2->head.data);
+          do {
+            BMLoop *l3 = l2->v != v ? l2->next : l2;
+
+            if (!l3 || l3 == l1 || l3 == l || l3 == l->next) {
+              continue;
+            }
+
+            for (int k = 0; k < totuv; k++) {
+              const int flag = 1 << k;
+
+              if (l3->head.index & flag) {
+                continue;
+              }
+
+              const int cd_uv = uv_layer[k].offset;
+
+              MLoopUV *luv1 = BM_ELEM_CD_GET_VOID_P(l1, cd_uv);
+              MLoopUV *luv2 = BM_ELEM_CD_GET_VOID_P(l3, cd_uv);
+
+              float dx = luv2->uv[0] - uv[k * 2 + step][0];
+              float dy = luv2->uv[1] - uv[k * 2 + step][1];
+
+              float delta = dx * dx + dy * dy;
+
+              if (delta < 0.001) {
+                l3->head.index |= flag;
+                copy_v2_v2(luv2->uv, luv1->uv);
+              }
+            }
+          } while ((l2 = l2->radial_next) != e2->l);
+        } while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
       }
-      BM_LOOPS_OF_VERT_ITER_END;
-      //*/
-    }
+    } while ((l = l->radial_next) != e->l);
   }
 
   validate_vert_faces(pbvh, pbvh->bm, v_conn, false, true);
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index bb275b21c05..357e07c64ee 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -4044,6 +4044,11 @@ PBVHNode *BKE_pbvh_get_node(PBVH *pbvh, int node)
   return pbvh->nodes + node;
 }
 
+void BKE_pbvh_node_mark_update_triangulation(PBVHNode *node)
+{
+  node->flag |= PBVH_UpdateTris;
+}
+
 void BKE_pbvh_node_mark_update_tri_area(PBVHNode *node)
 {
   node->flag |= PBVH_UpdateTriAreas;
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 642c2b5ac3a..3c7d89bb7bb 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -41,6 +41,7 @@ Topology rake:
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_alloca.h"
 #include "BLI_array.h"
 #include "BLI_buffer.h"
 #include "BLI_ghash.h"
@@ -2149,25 +2150,30 @@ BLI_INLINE PBVHTri *pbv

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list