[Bf-blender-cvs] [8ed4c5fc61b] temp_bmesh_multires: Merge branch 'master' into temp_bmesh_multires
Joseph Eagar
noreply at git.blender.org
Fri Aug 6 21:51:50 CEST 2021
Commit: 8ed4c5fc61b6fd78dea219f62644faf7e05650bc
Author: Joseph Eagar
Date: Fri Aug 6 12:51:18 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB8ed4c5fc61b6fd78dea219f62644faf7e05650bc
Merge branch 'master' into temp_bmesh_multires
Also fixed a pbvh corruption bug
===================================================================
===================================================================
diff --cc release/scripts/addons
index c2c5392e004,4475cbd11a6..aebb668f75b
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit c2c5392e004bb8bafea84d8d69df31ef9f03d46f
-Subproject commit 4475cbd11a636382d57571e0f5dfeff1f90bd6b7
++Subproject commit aebb668f75b57ba7cbd8f8f8ad41f0ddb4f27389
diff --cc release/scripts/addons_contrib
index 788441f2930,788441f2930..98f6085e9d7
--- a/release/scripts/addons_contrib
+++ b/release/scripts/addons_contrib
@@@ -1,1 -1,1 +1,1 @@@
--Subproject commit 788441f2930465bbfba8f0797b12dcef1d46694d
++Subproject commit 98f6085e9d71ba35d41e5aafbcb7981bd7c48275
diff --cc source/blender/blenkernel/intern/dyntopo.c
index 374cb3c8941,00000000000..49da8fcd8e4
mode 100644,000000..100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@@ -1,2952 -1,0 +1,2996 @@@
+#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);
+
+ /* 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;
+
+ /* This value is logged below */
+ copy_v3_v3(v->no, no);
+ }
+
+ BLI_table_gset_insert(node->bm_unique_verts, v);
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list