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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs