[Bf-blender-cvs] [b243eb2646f] temp_bmesh_multires: Merge branch 'master' into temp_bmesh_multires Also:

Joseph Eagar noreply at git.blender.org
Fri Jul 30 01:12:52 CEST 2021


Commit: b243eb2646f69a236b65ade05281f0571f341ee1
Author: Joseph Eagar
Date:   Thu Jul 29 16:08:14 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rBb243eb2646f69a236b65ade05281f0571f341ee1

Merge branch 'master' into temp_bmesh_multires
Also:

* added BMLog function to save mesh IDs.
  - Used by SCULPT_UNDO_DYNTOPO_BEGIN/END instead of
    saving the whole mesh, which was the previous behavior.
* SCULPT_UNDO_DYNTOPO_BEGIN no longer pushes a non-dyntopo
  geomtry undo node, as this is no longer necassary.

This greatly speeds up going into/out of sculpt mode
with dyntopo enabled, as before it was copying
the mesh twice.

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



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

diff --cc release/datafiles/locale
index f3791fbfdb8,62e82958a76..ca39c1459bc
--- a/release/datafiles/locale
+++ b/release/datafiles/locale
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit f3791fbfdb839860035241ba477bf8872966af93
 -Subproject commit 62e82958a760dad775d9b3387d7fb535fd6de4c6
++Subproject commit ca39c1459bcd99300afe3591fa5ffe40f5ba5eef
diff --cc release/scripts/addons
index e25068ef471,4475cbd11a6..c2c5392e004
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit e25068ef471c6d6cd5ee64a2eef9b7d672c57029
 -Subproject commit 4475cbd11a636382d57571e0f5dfeff1f90bd6b7
++Subproject commit c2c5392e004bb8bafea84d8d69df31ef9f03d46f
diff --cc source/blender/blenkernel/CMakeLists.txt
index 714ea8b1c23,e8f31ae72c0..04083d4a79a
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@@ -285,9 -286,10 +287,10 @@@ set(SR
    intern/workspace.c
    intern/world.c
    intern/writeavi.c
 -
 +  
    BKE_DerivedMesh.h
    BKE_action.h
+   BKE_action.hh
    BKE_addon.h
    BKE_anim_data.h
    BKE_anim_path.h
diff --cc source/blender/blenkernel/intern/dyntopo.c
index b2e909d1f36,00000000000..374cb3c8941
mode 100644,000000..100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@@ -1,2947 -1,0 +1,2952 @@@
 +#include "MEM_guardedalloc.h"
 +
 +#include "DNA_customdata_types.h"
 +#include "DNA_mesh_types.h"
 +#include "DNA_meshdata_types.h"
 +#include "DNA_modifier_types.h"
 +
 +#include "BLI_array.h"
 +#include "BLI_bitmap.h"
 +#include "BLI_buffer.h"
 +#include "BLI_compiler_attrs.h"
 +#include "BLI_compiler_compat.h"
 +#include "BLI_ghash.h"
 +#include "BLI_heap.h"
 +#include "BLI_heap_simple.h"
 +#include "BLI_linklist.h"
 +#include "BLI_math.h"
 +#include "BLI_memarena.h"
 +#include "BLI_rand.h"
 +#include "BLI_task.h"
 +#include "BLI_utildefines.h"
 +#include "PIL_time.h"
 +#include "atomic_ops.h"
 +
 +#include "BKE_customdata.h"
 +#include "BKE_dyntopo.h"
 +#include "BKE_pbvh.h"
 +
 +#include "bmesh.h"
 +#include "pbvh_intern.h"
 +
 +#include <stdio.h>
 +
 +#define DYNVERT_ALL_BOUNDARY (DYNVERT_BOUNDARY | DYNVERT_FSET_BOUNDARY)
 +
 +#define DYNTOPO_MAX_ITER 4096
 +
 +#define DYNTOPO_USE_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
 +#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
 +
 +#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_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)
 +
 +static bool check_face_is_tri(PBVH *pbvh, BMFace *f);
 +static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v);
 +
 +BLI_INLINE void surface_smooth_v_safe(PBVH *pbvh, BMVert *v)
 +{
 +  float co[3];
 +  float tan[3];
 +  float tot = 0.0;
 +
 +  zero_v3(co);
 +
 +  // this is a manual edge walk
 +
 +  BMEdge *e = v->e;
 +  if (!e) {
 +    return;
 +  }
 +  pbvh_check_vert_boundary(pbvh, v);
 +
 +  const int cd_dyn_vert = pbvh->cd_dyn_vert;
 +
 +  MDynTopoVert *mv1 = BKE_PBVH_DYNVERT(cd_dyn_vert, v);
 +  const bool bound1 = mv1->flag & DYNVERT_ALL_BOUNDARY;
 +
 +  do {
 +    BMVert *v2 = e->v1 == v ? e->v2 : e->v1;
 +
 +    pbvh_check_vert_boundary(pbvh, v2);
 +
 +    MDynTopoVert *mv2 = BKE_PBVH_DYNVERT(cd_dyn_vert, v2);
 +    const bool bound2 = mv2->flag & DYNVERT_ALL_BOUNDARY;
 +
 +    if (bound1 != bound2) {
 +      e = v == e->v1 ? e->v1_disk_link.next : e->v2_disk_link.next;
 +      continue;
 +    }
 +
 +    sub_v3_v3v3(tan, v2->co, v->co);
 +    float d = dot_v3v3(tan, v->no);
 +
 +    madd_v3_v3fl(tan, v->no, -d * 0.99f);
 +    add_v3_v3(co, tan);
 +    tot += 1.0f;
 +
 +    e = v == e->v1 ? e->v1_disk_link.next : e->v2_disk_link.next;
 +  } while (e != v->e);
 +
 +  if (tot == 0.0f) {
 +    return;
 +  }
 +
 +  mul_v3_fl(co, 1.0f / tot);
 +  float x = v->co[0], y = v->co[1], z = v->co[2];
 +
 +  // conflicts here should be pretty rare.
 +  atomic_cas_float(&v->co[0], x, x + co[0] * DYNTOPO_SAFE_SMOOTH_FAC);
 +  atomic_cas_float(&v->co[1], y, y + co[1] * DYNTOPO_SAFE_SMOOTH_FAC);
 +  atomic_cas_float(&v->co[2], z, z + co[2] * DYNTOPO_SAFE_SMOOTH_FAC);
 +}
 +
 +static void bm_edges_from_tri(BMesh *bm, BMVert *v_tri[3], BMEdge *e_tri[3])
 +{
 +  e_tri[0] = BM_edge_create(bm, v_tri[0], v_tri[1], NULL, BM_CREATE_NO_DOUBLE);
 +  e_tri[1] = BM_edge_create(bm, v_tri[1], v_tri[2], NULL, BM_CREATE_NO_DOUBLE);
 +  e_tri[2] = BM_edge_create(bm, v_tri[2], v_tri[0], NULL, BM_CREATE_NO_DOUBLE);
 +}
 +
 +BLI_INLINE void bm_face_as_array_index_tri(BMFace *f, int r_index[3])
 +{
 +  BMLoop *l = BM_FACE_FIRST_LOOP(f);
 +
 +  BLI_assert(f->len == 3);
 +
 +  r_index[0] = BM_elem_index_get(l->v);
 +  l = l->next;
 +  r_index[1] = BM_elem_index_get(l->v);
 +  l = l->next;
 +  r_index[2] = BM_elem_index_get(l->v);
 +}
 +
 +/**
 + * A version of #BM_face_exists, optimized for triangles
 + * when we know the loop and the opposite vertex.
 + *
 + * Check if any triangle is formed by (l_radial_first->v, l_radial_first->next->v, v_opposite),
 + * at either winding (since its a triangle no special checks are needed).
 + *
 + * <pre>
 + * l_radial_first->v & l_radial_first->next->v
 + * +---+
 + * |  /
 + * | /
 + * + v_opposite
 + * </pre>
 + *
 + * Its assumed that \a l_radial_first is never forming the target face.
 + */
 +static BMFace *bm_face_exists_tri_from_loop_vert(BMLoop *l_radial_first, BMVert *v_opposite)
 +{
 +  BLI_assert(
 +      !ELEM(v_opposite, l_radial_first->v, l_radial_first->next->v, l_radial_first->prev->v));
 +  if (l_radial_first->radial_next != l_radial_first) {
 +    BMLoop *l_radial_iter = l_radial_first->radial_next;
 +    do {
 +      BLI_assert(l_radial_iter->f->len == 3);
 +      if (l_radial_iter->prev->v == v_opposite) {
 +        return l_radial_iter->f;
 +      }
 +    } while ((l_radial_iter = l_radial_iter->radial_next) != l_radial_first);
 +  }
 +  return NULL;
 +}
 +
 +/**
 + * Uses a map of vertices to lookup the final target.
 + * References can't point to previous items (would cause infinite loop).
 + */
 +static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v)
 +{
 +  while (true) {
 +    BMVert **v_next_p = (BMVert **)BLI_ghash_lookup_p(deleted_verts, v);
 +    if (v_next_p == NULL) {
 +      /* Not remapped. */
 +      return v;
 +    }
 +    if (*v_next_p == NULL) {
 +      /* removed and not remapped */
 +      return NULL;
 +    }
 +
 +    /* remapped */
 +    v = *v_next_p;
 +  }
 +}
 +
 +static void pbvh_bmesh_copy_facedata(BMesh *bm, BMFace *dest, BMFace *src)
 +{
 +  dest->head.hflag = src->head.hflag;
 +  dest->mat_nr = src->mat_nr;
 +  CustomData_bmesh_copy_data(&bm->pdata, &bm->pdata, src->head.data, &dest->head.data);
 +}
 +
 +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];
 +
 +  BLI_assert((pbvh->totnode == 1 || node_index) && node_index <= pbvh->totnode);
 +
 +  /* avoid initializing customdata because its quite involved */
 +  BMVert *v = BM_vert_create(pbvh->bm, co, NULL, BM_CREATE_NOP);
 +
 +  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);
 +
 +    /* 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list