[Bf-blender-cvs] [bb1096f4756] temp_bmesh_multires: Sculpt dyntopo:
Joseph Eagar
noreply at git.blender.org
Thu Sep 9 01:57:06 CEST 2021
Commit: bb1096f4756247a9ed0f7c4c95da0f96ccfdff9f
Author: Joseph Eagar
Date: Wed Sep 8 15:51:56 2021 -0800
Branches: temp_bmesh_multires
https://developer.blender.org/rBbb1096f4756247a9ed0f7c4c95da0f96ccfdff9f
Sculpt dyntopo:
* Collapse now uses code from decimate to detect
degenerate cases.
* Remaining, unknown (and rare) degenerate cases
are now detected (via presence of duplicate verts
in faces) and fixed.
* DynTopo fills in undo size properly now,
so undo memory limiting works.
===================================================================
M release/scripts/startup/bl_ui/space_view3d_toolbar.py
M source/blender/blenkernel/intern/brush.c
M source/blender/blenkernel/intern/dyntopo.c
M source/blender/blenkernel/intern/paint.c
M source/blender/bmesh/intern/bmesh_core.c
M source/blender/bmesh/intern/bmesh_log.c
M source/blender/bmesh/intern/bmesh_log.h
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_replay.c
M source/blender/editors/sculpt_paint/sculpt_undo.c
M source/blender/makesdna/DNA_brush_defaults.h
M source/blender/makesdna/DNA_brush_enums.h
M source/blender/makesdna/DNA_brush_types.h
M source/blender/makesdna/DNA_scene_types.h
M source/blender/makesrna/intern/rna_brush.c
M source/blender/makesrna/intern/rna_sculpt_paint.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index e362ae31247..27920a9a57a 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -820,6 +820,7 @@ class VIEW3D_PT_sculpt_dyntopo_advanced(Panel, View3DPaintPanel):
do_prop("detail_percent")
do_prop("constant_detail")
do_prop("mode")
+ do_prop("radius_scale")
# TODO, move to space_view3d.py
class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
@@ -878,6 +879,7 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
col.prop(sculpt, "use_flat_vcol_shading")
col.prop(sculpt, "dyntopo_spacing")
+ col.prop(sculpt, "dyntopo_radius_scale");
class VIEW3D_PT_sculpt_voxel_remesh(Panel, View3DPaintPanel):
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 0942cc10994..7c27648161e 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -250,6 +250,11 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
{
Brush *brush = (Brush *)id;
+ if (brush->dyntopo.radius_scale == 0.0f) {
+ brush->dyntopo.radius_scale = 1.0f;
+ brush->dyntopo.inherit |= DYNTOPO_INHERIT_RADIUS_SCALE;
+ }
+
// detect old file data
if (brush->autosmooth_radius_factor == 0.0f) {
brush->autosmooth_radius_factor = 1.0f;
@@ -2681,6 +2686,10 @@ void BKE_brush_get_dyntopo(Brush *brush, Sculpt *sd, DynTopoSettings *out)
}
}
+ if (inherit & DYNTOPO_INHERIT_RADIUS_SCALE) {
+ out->radius_scale = sd->dyntopo_radius_scale;
+ }
+
if (inherit & DYNTOPO_INHERIT_DETAIL_SIZE) {
out->detail_size = sd->detail_size;
}
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 8370de2af69..35f242f2d22 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -181,11 +181,112 @@ static void edge_queue_create_local(struct EdgeQueueContext *eq_ctx,
const bool use_projected,
bool is_collapse);
+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 void fix_mesh(PBVH *pbvh, BMesh *bm)
+{
+ BMIter iter;
+ BMVert *v;
+ BMEdge *e;
+ BMFace *f;
+
+ printf("fixing mesh. . .\n");
+
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ v->e = NULL;
+ MDynTopoVert *mv = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v);
+
+ mv->flag |= DYNVERT_NEED_VALENCE | DYNVERT_NEED_BOUNDARY | DYNVERT_NEED_DISK_SORT |
+ DYNVERT_NEED_TRIANGULATE;
+ }
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ e->v1_disk_link.next = e->v1_disk_link.prev = NULL;
+ e->v2_disk_link.next = e->v2_disk_link.prev = NULL;
+ e->l = NULL;
+
+ if (e->v1 == e->v2) {
+ bm_kill_only_edge(bm, e);
+ }
+ }
+
+ // 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!", e);
+ bm_kill_only_edge(bm, e);
+
+ continue;
+ }
+
+ bmesh_disk_edge_append(e, e->v1);
+ bmesh_disk_edge_append(e, e->v2);
+ }
+
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l = f->l_first;
+
+ do {
+ if (f->len < 3) {
+ break;
+ }
+
+ if (l->next->v == l->v) {
+ BMLoop *l_del = l->next;
+
+ l->next = l_del->next;
+ l_del->next->prev = l;
+
+ f->len--;
+
+ if (f->l_first == l_del) {
+ f->l_first = l;
+ }
+
+ bm_kill_only_loop(bm, l_del);
+
+ if (f->len < 3) {
+ break;
+ }
+ }
+ } while ((l = l->next) != f->l_first);
+
+ if (f->len < 3) {
+ int ni = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
+
+ if (ni >= 0 && ni < pbvh->totnode && (pbvh->nodes[ni].flag & PBVH_Leaf)) {
+ BLI_table_gset_remove(pbvh->nodes[ni].bm_faces, f, NULL);
+ }
+
+ bm_kill_only_face(bm, f);
+ continue;
+ }
+
+ do {
+ l->e = BM_edge_exists(l->v, l->next->v);
+
+ if (!l->e) {
+ l->e = BM_edge_create(bm, l->v, l->next->v, NULL, BM_CREATE_NOP);
+ }
+
+ bmesh_radial_loop_append(l->e, l);
+ } while ((l = l->next) != f->l_first);
+ }
+
+ bm->elem_table_dirty |= BM_VERT | BM_EDGE | BM_FACE;
+ bm->elem_index_dirty |= BM_VERT | BM_EDGE | BM_FACE;
+
+ printf("done fixing mesh.\n");
+}
+
//#define CHECKMESH
//#define TEST_INVALID_NORMALS
#ifndef CHECKMESH
-# define fix_mesh(bm)
# define validate_vert(pbvh, bm, v, autofix, check_manifold) true
# define validate_edge(pbvh, bm, e, autofix, check_manifold) true
# define validate_face(pbvh, bm, f, autofix, check_manifold) true
@@ -203,16 +304,13 @@ CHECKMESH_ATTR static void _debugprint(const char *fmt, ...)
va_end(args);
}
-void bmesh_disk_edge_append(BMEdge *e, BMVert *v);
-void bmesh_radial_loop_append(BMEdge *e, BMLoop *l);
-
CHECKMESH_ATTR static bool check_face_is_manifold(PBVH *pbvh, BMesh *bm, BMFace *f)
{
BMLoop *l = f->l_first;
do {
if (l->radial_next != l && l->radial_next->radial_next != l) {
- _debugprint("non-manifold edge in loop\n");
+ //_debugprint("non-manifold edge in loop\n");
BMVert *v1 = l->e->v1, *v2 = l->e->v2;
@@ -220,7 +318,15 @@ CHECKMESH_ATTR static bool check_face_is_manifold(PBVH *pbvh, BMesh *bm, BMFace
BMVert *v = i ? v2 : v1;
BMEdge *e = v->e;
+ if (!e) {
+ continue;
+ }
+
do {
+ if (!e) {
+ break;
+ }
+
bool same = e->v1 == v1 && e->v2 == v2;
same = same || (e->v1 == v2 && e->v2 == v1);
if (same && e != l->e) {
@@ -248,45 +354,6 @@ CHECKMESH_ATTR static bool check_face_is_manifold(PBVH *pbvh, BMesh *bm, BMFace
return true;
}
-CHECKMESH_ATTR
-static void fix_mesh(BMesh *bm)
-{
- BMIter iter;
- BMVert *v;
- BMEdge *e;
- BMFace *f;
-
- _debugprint("fixing mesh. . .\n");
-
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- v->e = NULL;
- }
-
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- e->v1_disk_link.next = e->v1_disk_link.prev = NULL;
- e->v2_disk_link.next = e->v2_disk_link.prev = NULL;
- }
-
- // rebuild disk cycles
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- e->l = NULL;
-
- bmesh_disk_edge_append(e, e->v1);
- bmesh_disk_edge_append(e, e->v2);
- }
-
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- BMLoop *l = f->l_first;
-
- do {
- l->e = BM_edge_exists(l->v, l->next->v);
-
- bmesh_radial_loop_append(l->e, l);
- } while ((l = l->next) != f->l_first);
- }
- _debugprint("done fixing mesh.\n");
-}
-
CHECKMESH_ATTR
static bool validate_vert(PBVH *pbvh, BMesh *bm, BMVert *v, bool autofix, bool check_manifold)
{
@@ -348,7 +415,7 @@ static bool validate_vert(PBVH *pbvh, BMesh *bm, BMVert *v, bool autofix, bool c
error:
if (autofix) {
- fix_mesh(bm);
+ fix_mesh(pbvh, bm);
}
return false;
@@ -366,7 +433,7 @@ static bool validate_edge(PBVH *pbvh, BMesh *bm, BMEdge *e, bool autofix, bool c
validate_vert(pbvh, bm, e->v2, false, check_manifold);
if (!ret && autofix) {
- fix_mesh(bm);
+ fix_mesh(pbvh, bm);
}
return ret;
@@ -424,7 +491,7 @@ error:
BLI_array_free(ls);
if (autofix) {
- fix_mesh(bm);
+ fix_mesh(pbvh, bm);
}
return false;
@@ -465,7 +532,7 @@ CHECKMESH_ATTR bool validate_vert_faces(
error:
if (autofix) {
- fix_mesh(bm);
+ fix_mesh(pbvh, bm);
}
return false;
@@ -2138,7 +2205,7 @@ static bool check_face_is_tri(PBVH *pbvh, BMFace *f)
return false;
}
-ATTR_NO_OPT static bool check_for_flaps(PBVH *pbvh, BMVert *v)
+static bool check_for_flaps(PBVH *pbvh, BMVert *v)
{
const int updateflag = DYNVERT_NEED_VALENCE | DYNVERT_NEED_DISK_SORT | DYNVERT_NEED_BOUNDARY;
@@ -3161,13 +3228,141 @@ static bool pbvh_bmesh_subdivide_long_edges(
return any_subdivided;
}
-ATTR_NO_OPT static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
- BMEdge *e,
- BMVert *v1,
- BMVert *v2,
- GHash *deleted_verts,
- BLI_Buffer *deleted_faces,
- EdgeQueueContext *eq_ctx)
+static bool bm_edge_tag_test(BMEdge *e)
+{
+ /* is the edge or one of its faces tagged? */
+ return (BM_elem_flag_test(e->v1, BM_ELEM_TAG) || BM_elem_flag_test(e->v2, BM_ELEM_TAG) ||
+ (e->l &&
+ (BM_elem_flag_test(e->l->f, BM_ELEM_TAG) ||
+ (e->l != e->l->radial_next && BM_elem_flag_test(e->l->radial_next->f, BM_ELEM_TAG)))));
+}
+
+static void bm_edge_tag_disable(BMEdge *e)
+{
+ BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
+ if (e->l) {
+ BM_elem_flag_disable(e->l->f, BM_ELEM_TAG);
+ if (e->l != e->l->radial_next) {
+ BM_elem_flag_disable(e->l->radial_next->f, BM_ELEM_TAG);
+ }
+ }
+}
+
+/* takes the edges loop */
+BLI_INLINE int bm_edge_is_manifold_or_boundary(BMLoop *l)
+{
+#if 0
+ /* less optimized version of check below */
+ return (BM_edge_is_manifold(l->e) || BM_edge_is_boundary(l->e);
+#else
+ /* if the edge is a boundary it points to its self, else this must be a manifold */
+ return LIKELY(l) && LIKELY(l->radial_next->radial_next == l);
+#endif
+}
+
+static void bm_edge_tag_enable(BMEdge *e)
+{
+ BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
+ if (e->l) {
+ BM_elem_flag_enable(e->l->f, BM_ELEM_TAG);
+ if (e->l != e->l->radial_next) {
+ BM_elem_flag_enable(e->l->radial_next->f, BM_ELEM_TAG);
+ }
+ }
+}
+
+// copied from decimate modifier code
+static bool bm_edge_collapse
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list