[Bf-blender-cvs] [4e76cc86b07] sculpt-dev: sculpt-dev: Cleanup dyntopo.cc

Joseph Eagar noreply at git.blender.org
Sat Jan 28 09:35:02 CET 2023


Commit: 4e76cc86b073ae9f06fb291a3ec2eff00839c6f8
Author: Joseph Eagar
Date:   Fri Jan 27 17:27:44 2023 -0800
Branches: sculpt-dev
https://developer.blender.org/rB4e76cc86b073ae9f06fb291a3ec2eff00839c6f8

sculpt-dev: Cleanup dyntopo.cc

* Split into dyntopo.cc, dyntopo_collapse.cc and dyntopo_intern.hh
* Removed various unused functions.

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

M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/dyntopo.cc
A	source/blender/blenkernel/intern/dyntopo_collapse.cc
A	source/blender/blenkernel/intern/dyntopo_intern.hh
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/bmesh/intern/bmesh_idmap.h

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

diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 3196b89fb56..b70bedc471a 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -132,6 +132,7 @@ set(SRC
   intern/displist.cc
   intern/dynamicpaint.c
   intern/dyntopo.cc
+  intern/dyntopo_collapse.cc
   intern/editlattice.c
   intern/editmesh.cc
   intern/editmesh_bvh.c
@@ -514,6 +515,7 @@ set(SRC
   intern/CCGSubSurf.h
   intern/CCGSubSurf_inline.h
   intern/CCGSubSurf_intern.h
+  intern/dyntopo_intern.hh
   intern/attribute_access_intern.hh
   intern/data_transfer_intern.h
   intern/lib_intern.h
diff --git a/source/blender/blenkernel/intern/dyntopo.cc b/source/blender/blenkernel/intern/dyntopo.cc
index 307fe476010..09c8acc393d 100644
--- a/source/blender/blenkernel/intern/dyntopo.cc
+++ b/source/blender/blenkernel/intern/dyntopo.cc
@@ -41,10 +41,13 @@
 #include "bmesh.h"
 #include "bmesh_log.h"
 
+#include "dyntopo_intern.hh"
 #include "pbvh_intern.h"
 
 #include <stdio.h>
 
+namespace blender::dyntopo {
+
 using blender::float2;
 using blender::float3;
 using blender::float4;
@@ -53,178 +56,21 @@ using blender::Map;
 using blender::Set;
 using blender::Vector;
 
-//#define DYNTOPO_VALIDATE_LOG
-
-#ifdef DYNTOPO_VALIDATE_LOG
-#  define VALIDATE_LOG(log) BM_log_validate_cur(log)
-#else
-#  define VALIDATE_LOG(log)
-#endif
-
-//#define DYNTOPO_REPORT
-//#define WITH_ADAPTIVE_CURVATURE
-//#define DYNTOPO_NO_THREADING
-
-#define SCULPTVERT_VALENCE_TEMP SCULPTVERT_SPLIT_TEMP
-
-#define SCULPTVERT_SMOOTH_BOUNDARY \
-  (SCULPT_BOUNDARY_MESH | SCULPT_BOUNDARY_FACE_SET | SCULPT_BOUNDARY_SHARP | \
-   SCULPT_BOUNDARY_SEAM | SCULPT_BOUNDARY_UV)
-#define SCULPTVERT_ALL_BOUNDARY \
-  (SCULPT_BOUNDARY_MESH | SCULPT_BOUNDARY_FACE_SET | SCULPT_BOUNDARY_SHARP | \
-   SCULPT_BOUNDARY_SEAM | SCULPT_BOUNDARY_UV)
-#define SCULPTVERT_SMOOTH_CORNER \
-  (SCULPT_CORNER_MESH | SCULPT_CORNER_FACE_SET | SCULPT_CORNER_SHARP | SCULPT_CORNER_SEAM | \
-   SCULPT_CORNER_UV)
-#define SCULPTVERT_ALL_CORNER \
-  (SCULPT_CORNER_MESH | SCULPT_CORNER_FACE_SET | SCULPT_CORNER_SHARP | SCULPT_CORNER_SEAM | \
-   SCULPT_CORNER_UV)
-
-#define DYNTOPO_MAX_ITER 4096
-
-#define DYNTOPO_USE_HEAP
-#define DYNTOPO_USE_MINMAX_HEAP
-
-#ifndef DYNTOPO_USE_HEAP
-/* don't add edges into the queue multiple times */
-#  define USE_EDGEQUEUE_TAG
-#endif
-
-/* Avoid skinny faces */
-#define USE_EDGEQUEUE_EVEN_SUBDIV
-
-/* How much longer we need to be to consider for subdividing
- * (avoids subdividing faces which are only *slightly* skinny) */
-#define EVEN_EDGELEN_THRESHOLD 1.2f
-/* How much the limit increases per recursion
- * (avoids performing subdivisions too far away). */
-#define EVEN_GENERATION_SCALE 1.1f
-
-/* recursion depth to start applying front face test */
-#define DEPTH_START_LIMIT 5
-
-//#define FANCY_EDGE_WEIGHTS <= too slow
-//#define SKINNY_EDGE_FIX
-
-/* slightly relax geometry by this factor along surface tangents
-   to improve convergence of remesher */
-#define DYNTOPO_SAFE_SMOOTH_FAC 0.05f
-
-#define DYNTOPO_SAFE_SMOOTH_SUBD_ONLY_FAC 0.075f
-
-#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
-#  include "BKE_global.h"
-#endif
-
-/* Support for only operating on front-faces */
-#define USE_EDGEQUEUE_FRONTFACE
-
-/**
- * Ensure we don't have dirty tags for the edge queue, and that they are left cleared.
- * (slow, even for debug mode, so leave disabled for now).
- */
-#if defined(USE_EDGEQUEUE_TAG) && 0
-#  if !defined(NDEBUG)
-#    define USE_EDGEQUEUE_TAG_VERIFY
-#  endif
-#endif
-
-// #define USE_VERIFY
-
-#define DYNTOPO_MASK(cd_mask_offset, v) BM_ELEM_CD_GET_FLOAT(v, cd_mask_offset)
-
-#ifdef USE_VERIFY
-static void pbvh_bmesh_verify(PBVH *pbvh);
-#endif
-
-/* -------------------------------------------------------------------- */
-/** \name BMesh Utility API
- *
- * Use some local functions which assume triangles.
- * \{ */
-
-/**
- * Typically using BM_LOOPS_OF_VERT and BM_FACES_OF_VERT iterators are fine,
- * however this is an area where performance matters so do it in-line.
- *
- * Take care since 'break' won't works as expected within these macros!
- */
-
-#define BM_DISK_EDGE(e, v) (&((&(e)->v1_disk_link)[(v) == (e)->v2]))
-
-#define BM_LOOPS_OF_VERT_ITER_BEGIN(l_iter_radial_, v_) \
-  { \
-    struct { \
-      BMVert *v; \
-      BMEdge *e_iter, *e_first; \
-      BMLoop *l_iter_radial; \
-    } _iter; \
-    _iter.v = v_; \
-    if (_iter.v->e) { \
-      _iter.e_iter = _iter.e_first = _iter.v->e; \
-      do { \
-        if (_iter.e_iter->l) { \
-          _iter.l_iter_radial = _iter.e_iter->l; \
-          do { \
-            if (_iter.l_iter_radial->v == _iter.v) { \
-              l_iter_radial_ = _iter.l_iter_radial;
-
-#define BM_LOOPS_OF_VERT_ITER_END \
-  } \
-  } \
-  while ((_iter.l_iter_radial = _iter.l_iter_radial->radial_next) != _iter.e_iter->l) \
-    ; \
-  } \
-  } \
-  while ((_iter.e_iter = BM_DISK_EDGE_NEXT(_iter.e_iter, _iter.v)) != _iter.e_first) \
-    ; \
-  } \
-  } \
-  ((void)0)
-
-#define BM_FACES_OF_VERT_ITER_BEGIN(f_iter_, v_) \
-  { \
-    BMLoop *l_iter_radial_; \
-    BM_LOOPS_OF_VERT_ITER_BEGIN (l_iter_radial_, v_) { \
-      f_iter_ = l_iter_radial_->f;
-
-#define BM_FACES_OF_VERT_ITER_END \
-  } \
-  BM_LOOPS_OF_VERT_ITER_END; \
-  } \
-  ((void)0)
-
-struct EdgeQueueContext;
-
-bool pbvh_boundary_needs_update_bmesh(PBVH *pbvh, BMVert *v)
-{
-  int *flags = (int *)BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_boundary_flag);
-
-  return *flags & SCULPT_BOUNDARY_NEEDS_UPDATE;
-}
-
-void pbvh_boundary_update_bmesh(PBVH *pbvh, BMVert *v)
-{
-  if (pbvh->cd_boundary_flag == -1) {
-    printf("%s: error!\n", __func__);
-    return;
-  }
-
-  int *flags = (int *)BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_boundary_flag);
-  *flags |= SCULPT_BOUNDARY_NEEDS_UPDATE;
-}
-
-static bool destroy_nonmanifold_fins(PBVH *pbvh, BMEdge *e_root);
-static bool check_face_is_tri(PBVH *pbvh, BMFace *f);
-static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v);
 static void pbvh_split_edges(struct EdgeQueueContext *eq_ctx,
                              PBVH *pbvh,
                              BMesh *bm,
                              BMEdge **edges,
                              int totedge,
                              bool ignore_isolated_edges);
-extern "C" void bm_log_message(const char *fmt, ...);
+extern "C" {
+void bmesh_disk_edge_append(BMEdge *e, BMVert *v);
+void bmesh_radial_loop_append(BMEdge *e, BMLoop *l);
+void bm_kill_only_edge(BMesh *bm, BMEdge *e);
+void bm_kill_only_loop(BMesh *bm, BMLoop *l);
+void bm_kill_only_face(BMesh *bm, BMFace *f);
+}
 
+static bool edge_queue_test(struct EdgeQueueContext *eq_ctx, PBVH *pbvh, BMEdge *e);
 static void edge_queue_create_local(struct EdgeQueueContext *eq_ctx,
                                     PBVH *pbvh,
                                     const float center[3],
@@ -234,1791 +80,1074 @@ static void edge_queue_create_local(struct EdgeQueueContext *eq_ctx,
                                     const bool use_projected,
                                     PBVHTopologyUpdateMode local_mode);
 
-extern "C" {
-void bmesh_disk_edge_append(BMEdge *e, BMVert *v);
-void bmesh_radial_loop_append(BMEdge *e, BMLoop *l);
-void bm_kill_only_edge(BMesh *bm, BMEdge *e);
-void bm_kill_only_loop(BMesh *bm, BMLoop *l);
-void bm_kill_only_face(BMesh *bm, BMFace *f);
-}
-static bool edge_queue_test(struct EdgeQueueContext *eq_ctx, PBVH *pbvh, BMEdge *e);
 
-static void fix_mesh(PBVH *pbvh, BMesh *bm)
+BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v, float fac)
 {
-  BMIter iter;
-  BMVert *v;
-  BMEdge *e;
-  BMFace *f;
-
-  printf("fixing mesh. . .\n");
+  float co[3];
+  float origco[3], origco1[3];
+  float origno1[3];
+  float tan[3];
+  float tot = 0.0;
 
-  BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
-    v->e = nullptr;
-    MSculptVert *mv = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, v);
+  MSculptVert *mv1 = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, v);
 
-    MV_ADD_FLAG(mv,
-                SCULPTVERT_NEED_VALENCE | SCULPTVERT_NEED_DISK_SORT | SCULPTVERT_NEED_TRIANGULATE);
+  if (mv1->stroke_id != pbvh->stroke_id) {
+    copy_v3_v3(origco1, v->co);
+    copy_v3_v3(origno1, v->no);
   }
-
-  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
-    e->v1_disk_link.next = e->v1_disk_link.prev = nullptr;
-    e->v2_disk_link.next = e->v2_disk_link.prev = nullptr;
-    e->l = nullptr;
-
-    if (e->v1 == e->v2) {
-      bm_kill_only_edge(bm, e);
-    }
+  else {
+    copy_v3_v3(origco1, mv1->origco);
+    copy_v3_v3(origno1, dot_v3v3(mv1->origno, mv1->origno) == 0.0f ? v->no : mv1->origno);
   }
 
-  // rebuild disk cycles
-  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
-    if (BM_edge_exists(e->v1, e->v2)) {
-      printf("duplicate edge %p!\n", e);
-      bm_kill_only_edge(bm, e);
+  zero_v3(co);
+  zero_v3(origco);
 
-      continue;
-    }
+  // this is a manual edge walk
 
-    bmesh_disk_edge_append(e, e->v1);
-    bmesh_disk_edge_append(e, e->v2);
+  BMEdge *e = v->e;
+  if (!e) {
+    return;
   }
 
-  BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
-    BMLoop *l = f->l_first;
+  if (pbvh_boundary_needs_update_bmesh(pbvh, v)) {
+    pbvh_check_vert_boundary(pbvh, v);
+  }
 
-    do {
-      if (f->len < 3) {
-        break;
-      }
+  // pbvh_check_vert_boundary(pbvh, v);
 
-      if (l->next->v == l->v) {
-        BMLoop *l_del = l->next;
+  const int cd_sculpt_vert = pbvh->cd_sculpt_vert;
+  const int boundflag = BM_ELEM_CD_GET_INT(v, pbvh->cd_boundary_flag);
 
-        l->next = l_del->next;
-        l_del->next->prev = l;
+  const bool bound1 = boundflag & SCULPTVERT_SMOOTH_BOUNDARY;
 
-        f->len--;
+  if (boundflag & SCULPTVERT_SMOOTH_CORNER) {
+    return;
+  }
 
-        if (f->l_first == l_del) {
-          f->l_first = l;
-        }
+  if (bound1) {
+    fac *= 0.1;
+  }
 
-        bm_kill_only_loop(bm, l_del);
+  do {
+    BMVert *v2 = e->v1 == v ? e->v2 : e->v1;
 
-        if (f->len < 3) {
-          break;
-        }
-      }
-    } while ((l = l->next) != f->l_first);
+    // can't check for boundary here, thread
+    // pbvh_check_vert_boundary(pbvh, v2);
 
-    if (f->len < 3) {
-      int ni = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_of

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list