[Bf-blender-cvs] [019700583bb] temp_bmesh_multires: Sculpt dyntopo: undo bugfixes
Joseph Eagar
noreply at git.blender.org
Fri Aug 27 11:01:26 CEST 2021
Commit: 019700583bb5bcd937957e3766011ea26d0612f9
Author: Joseph Eagar
Date: Fri Aug 27 01:51:56 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB019700583bb5bcd937957e3766011ea26d0612f9
Sculpt dyntopo: undo bugfixes
* Fixed nasty undo bug related
to now rewinding BMLogEntry subchains properly.
* Fixed bug in dyntopo collapse
===================================================================
M source/blender/blenkernel/intern/dyntopo.c
M source/blender/blenkernel/intern/paint.c
M source/blender/blenkernel/intern/pbvh.c
M source/blender/blenkernel/intern/pbvh_bmesh.c
M source/blender/bmesh/intern/bmesh_log.c
M source/blender/bmesh/intern/bmesh_mesh_convert.c
M source/blender/bmesh/intern/bmesh_mesh_convert.h
M source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M source/blender/editors/sculpt_paint/sculpt_undo.c
===================================================================
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 05a14219bc1..b8d170ca450 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -159,6 +159,7 @@ static bool check_vert_fan_are_tris(PBVH *pbvh, BMVert *v);
static void pbvh_split_edges(
PBVH *pbvh, BMesh *bm, BMEdge **edges, int totedge, bool ignore_isolated_edges);
void bm_log_message(const char *fmt, ...);
+void pbvh_bmesh_check_nodes_simple(PBVH *pbvh);
static BMEdge *bmesh_edge_create_log(PBVH *pbvh, BMVert *v1, BMVert *v2, BMEdge *e_example)
{
@@ -804,7 +805,7 @@ static void pbvh_bmesh_face_remove(
else if (ensure_ownership_transfer && !BM_vert_face_count_is_equal(v, 1)) {
pbvh_bmesh_vert_remove(pbvh, v);
- f_node->flag |= PBVH_RebuildNodeVerts;
+ f_node->flag |= PBVH_RebuildNodeVerts | PBVH_UpdateOtherVerts;
// printf("failed to find new_node\n");
}
}
@@ -2391,6 +2392,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
check_vert_fan_are_tris(pbvh, e->v1);
check_vert_fan_are_tris(pbvh, e->v2);
+ // pbvh_bmesh_check_nodes_simple(pbvh);
+
bm_log_message(" == collapse == ");
// make sure origdata is up to date prior to interpolation
@@ -2440,6 +2443,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
/* Remove the merge vertex from the PBVH */
pbvh_bmesh_vert_remove(pbvh, v_del);
+ // pbvh_bmesh_check_nodes_simple(pbvh);
+
/* Remove all faces adjacent to the edge */
BMLoop *l_adj;
while ((l_adj = e->l)) {
@@ -2473,6 +2478,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BM_face_kill(pbvh->bm, f_adj);
}
+ // pbvh_bmesh_check_nodes_simple(pbvh);
+
/* Kill the edge */
BLI_assert(BM_edge_is_wire(e));
@@ -2553,6 +2560,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
//*/
}
+ // pbvh_bmesh_check_nodes_simple(pbvh);
+
#if 1
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
BMFace *existing_face;
@@ -2601,6 +2610,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
PBVHNode *n = pbvh_bmesh_node_from_face(pbvh, f);
int ni = n - pbvh->nodes;
+ n->flag |= PBVH_UpdateOtherVerts;
+
bm_edges_from_tri(pbvh, old_tri, e_tri);
bm_edges_from_tri_example(pbvh, v_tri, e_tri);
@@ -2633,6 +2644,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BM_LOOPS_OF_VERT_ITER_END;
#endif
+ // pbvh_bmesh_check_nodes_simple(pbvh);
+
/* Delete the tagged faces */
for (int i = 0; i < (int)deleted_faces->count; i++) {
BMFace *f_del = BLI_buffer_at(deleted_faces, BMFace *, i);
@@ -2729,12 +2742,41 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
mv_conn->flag |= DYNVERT_NEED_DISK_SORT | DYNVERT_NEED_VALENCE | DYNVERT_NEED_BOUNDARY;
}
+ if (v_del->e) {
+ BMEdge *e = v_del->e;
+
+ do {
+ if (e->l) {
+ BMLoop *l = e->l;
+ do {
+ printf("error in collapse_edge\n");
+ int ni = BM_ELEM_CD_GET_INT(l->f, pbvh->cd_face_node_offset);
+
+ BM_log_face_removed(pbvh->bm_log, l->f);
+
+ if (ni >= 0) {
+ PBVHNode *node = pbvh->nodes + ni;
+ BLI_table_gset_remove(node->bm_faces, l->f, NULL);
+ BM_ELEM_CD_SET_INT(l->f, pbvh->cd_face_node_offset, DYNTOPO_NODE_NONE);
+ }
+ else {
+ printf("face did not have a node ref\n");
+ }
+ } while ((l = l->radial_next) != e->l);
+ }
+
+ e = BM_DISK_EDGE_NEXT(e, v_del);
+ } while (e != v_del->e);
+ }
+
/* Delete v_del */
pbvh_kill_vert(pbvh, v_del);
BLI_array_free(ws);
BLI_array_free(blocks);
BLI_array_free(ls);
+
+ // pbvh_bmesh_check_nodes_simple(pbvh);
}
static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index be0dd435526..1c7a4303754 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -79,9 +79,11 @@
#include "bmesh.h"
-// XXX todo: work our bad module cross ref
+// XXX todo: figure out bad cross module refs
void SCULPT_dynamic_topology_sync_layers(Object *ob, Mesh *me);
void SCULPT_on_sculptsession_bmesh_free(SculptSession *ss);
+void SCULPT_dyntopo_node_layers_add(SculptSession *ss);
+BMesh *SCULPT_dyntopo_empty_bmesh();
static void palette_init_data(ID *id)
{
@@ -1383,17 +1385,29 @@ static void sculptsession_bm_to_me_update_data_only(Object *ob, bool reorder)
if (ss->bm) {
if (ob->data) {
- if (reorder && ss->bm_log) {
- BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
- }
+ Mesh *me = BKE_object_get_original_mesh(ob);
+
+ BM_mesh_bm_to_me(
+ NULL,
+ NULL,
+ ss->bm,
+ ob->data,
+ (&(struct BMeshToMeshParams){.calc_object_remap = false,
+#ifdef WHEN_GLOBAL_UNDO_WORKS
+
+ /*
+ for memfile undo steps we need to
+ save id and temporary layers
+ */
+ .copy_temp_cdlayers = true,
+ .copy_mesh_id_layers = true,
+ .cd_mask_extra = CD_MASK_MESH_ID | CD_MASK_DYNTOPO_VERT
+#else
+ .copy_temp_cdlayers = false,
+ .copy_mesh_id_layers = false
+#endif
- BM_mesh_bm_to_me(NULL,
- NULL,
- ss->bm,
- ob->data,
- (&(struct BMeshToMeshParams){
- .calc_object_remap = false,
- }));
+ }));
}
}
}
@@ -2254,6 +2268,46 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
ob->sculpt->pbvh = pbvh;
}
else {
+#ifdef WHEN_GLOBAL_UNDO_WORKS
+ /*detect if we are loading from an undo memfile step*/
+ Mesh *mesh_orig = BKE_object_get_original_mesh(ob);
+ bool is_dyntopo = (mesh_orig->flag & ME_SCULPT_DYNAMIC_TOPOLOGY);
+
+ is_dyntopo = is_dyntopo && CustomData_has_layer(&mesh_orig->vdata, CD_MESH_ID);
+ is_dyntopo = is_dyntopo && CustomData_has_layer(&mesh_orig->edata, CD_MESH_ID);
+ is_dyntopo = is_dyntopo && CustomData_has_layer(&mesh_orig->pdata, CD_MESH_ID);
+
+ if (is_dyntopo) {
+ BMesh *bm = SCULPT_dyntopo_empty_bmesh();
+
+ ob->sculpt->bm = bm;
+
+ BM_mesh_bm_from_me(NULL,
+ bm,
+ mesh_orig,
+ (&(struct BMeshFromMeshParams){.calc_face_normal = true,
+ .use_shapekey = true,
+ .active_shapekey = ob->shapenr,
+ .copy_id_layers = true,
+ .copy_temp_cdlayers = true,
+ .cd_mask_extra = CD_MASK_DYNTOPO_VERT}));
+
+ SCULPT_dyntopo_node_layers_add(ob->sculpt);
+
+ pbvh = build_pbvh_for_dynamic_topology(ob);
+ }
+ else {
+ Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
+ Mesh *mesh_eval = object_eval->data;
+ if (mesh_eval->runtime.subdiv_ccg != NULL) {
+ pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subdiv_ccg, respect_hide);
+ }
+ else if (ob->type == OB_MESH) {
+ Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
+ pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform, respect_hide);
+ }
+ }
+#else
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
Mesh *mesh_eval = object_eval->data;
if (mesh_eval->runtime.subdiv_ccg != NULL) {
@@ -2263,6 +2317,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval;
pbvh = build_pbvh_from_regular_mesh(ob, me_eval_deform, respect_hide);
}
+#endif
}
ob->sculpt->pbvh = pbvh;
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 84c45b7bafc..cbf95a035e0 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1418,7 +1418,9 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
if (i >= node->tot_tri_buffers) {
- printf("pbvh corruption!\n");
+ printf("node->tot_mat_draw_buffers >= node->tot_tri_buffers! %d %d\n",
+ node->tot_mat_draw_buffers,
+ node->tot_tri_buffers);
continue;
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index f8d16b2e7db..d8dadd707e2 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -70,6 +70,42 @@ Topology rake:
#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
+
+static void _debugprint(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+}
+
+void pbvh_bmesh_check_nodes_simple(PBVH *pbvh)
+{
+#if 0
+ for (int i = 0; i < pbvh->totnode; i++) {
+ PBVHNode *node = pbvh->nodes + i;
+ BMFace *f;
+
+ if (!(node->flag & PBVH_Leaf)) {
+ continue;
+ }
+
+ TGSET_ITER (f, node->bm_faces) {
+ if (!f || f->head.htype != BM_FACE) {
+ _debugprint("Corrupted (freed?) face in node->bm_faces\n");
+ continue;
+ }
+
+ if (BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset) != i) {
+ _debugprint("Face in more then one node\n");
+ }
+ }
+ TGSET_ITER_END;
+ }
+#endif
+}
+
void pbvh_bmesh_check_nodes(PBVH *pbvh)
{
#if 0
@@ -88,11 +124,12 @@ void pbvh_bmesh_check_nodes(PBVH *pbvh)
int ni = BM_ELEM_CD_GET_INT(v, pbvh->cd_vert_node_offset);
if (ni >= 0 && !v->e || !v->e->l) {
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list