From 8f6326d494fad50305e406557dee7d2d2cb44dd3 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 23 Oct 2020 15:53:39 -0700 Subject: BMesh dyntopo works again, if you disable WITH_TRIMESH in BKE_pbvh.h --- source/blender/blenkernel/BKE_pbvh.h | 285 ++++++++++++++-------- source/blender/blenkernel/intern/paint.c | 19 +- source/blender/blenkernel/intern/pbvh.c | 6 +- source/blender/blenkernel/intern/pbvh_intern.h | 4 +- source/blender/editors/sculpt_paint/paint_hide.c | 4 +- source/blender/editors/sculpt_paint/sculpt.c | 8 +- source/blender/editors/sculpt_paint/sculpt_undo.c | 162 ++++++------ source/blender/gpu/GPU_buffers.h | 4 +- source/blender/gpu/intern/gpu_buffers.c | 59 ++++- 9 files changed, 357 insertions(+), 194 deletions(-) diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 6ae99aabe9b..721763178fe 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -165,19 +165,19 @@ typedef struct PBVHFrustumPlanes { int num_planes; } PBVHFrustumPlanes; -typedef struct TMElemSet { +typedef struct TableGSet { struct GHash *ptr_to_idx; void **elems; int size, length; int cur; -} TMElemSet; +} TableGSet; -TMElemSet *TMElemSet_new(); -void TMElemSet_free(TMElemSet *ts); -void TMElemSet_insert(TMElemSet *ts, void *elem); -bool TMElemSet_add(TMElemSet *ts, void *elem); -void TMElemSet_remove(TMElemSet *ts, void *elem, bool ignoreExist); -bool TMElemSet_has(TMElemSet *ts, void *elem); +TableGSet *BLI_table_gset_new(); +void BLI_table_gset_free(TableGSet *ts); +void BLI_table_gset_insert(TableGSet *ts, void *elem); +bool BLI_table_gset_add(TableGSet *ts, void *elem); +void BLI_table_gset_remove(TableGSet *ts, void *elem, bool ignoreExist); +bool BLI_table_gset_has(TableGSet *ts, void *elem); #define TMS_ITER(v, ts) \ { \ @@ -206,6 +206,8 @@ typedef void (*BKE_pbvh_SearchNearestCallback)(PBVHNode *node, void *data, float /* Building */ +struct TM_TriMesh; + PBVH *BKE_pbvh_new(void); void BKE_pbvh_build_mesh(PBVH *pbvh, const struct Mesh *mesh, @@ -422,8 +424,8 @@ struct GSet *BKE_pbvh_bmesh_node_faces(PBVHNode *node); void BKE_pbvh_bmesh_node_save_orig(struct BMesh *bm, PBVHNode *node); void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh); -struct TMElemSet *BKE_pbvh_trimesh_node_unique_verts(PBVHNode *node); -struct TMElemSet *BKE_pbvh_trimesh_node_other_verts(PBVHNode *node); +struct TableGSet *BKE_pbvh_trimesh_node_unique_verts(PBVHNode *node); +struct TableGSet *BKE_pbvh_trimesh_node_other_verts(PBVHNode *node); struct GSet *BKE_pbvh_trimesh_node_faces(PBVHNode *node); void BKE_pbvh_trimesh_node_save_orig(struct TM_TriMesh *tm, PBVHNode *node); void BKE_pbvh_trimesh_after_stroke(PBVH *bvh); @@ -499,9 +501,9 @@ typedef struct PBVHVertexIter { struct CustomData *bm_vdata; int ti; - struct TMElemSet *tm_cur_set; - struct TMElemSet *tm_unique_verts; - struct TMElemSet *tm_other_verts; + struct TableGSet *tm_cur_set; + struct TableGSet *tm_unique_verts; + struct TableGSet *tm_other_verts; struct CustomData *tm_vdata; int cd_vert_mask_offset; @@ -521,114 +523,193 @@ typedef struct PBVHVertexIter { void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode); -#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode) \ - pbvh_vertex_iter_init(pbvh, node, &vi, mode); \ +#ifdef WITH_TRIMESH + +# define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode) \ + pbvh_vertex_iter_init(pbvh, node, &vi, mode); \ \ - for (vi.i = 0, vi.g = 0; vi.g < vi.totgrid; vi.g++) { \ - if (vi.grids) { \ - vi.width = vi.gridsize; \ - vi.height = vi.gridsize; \ - vi.index = vi.grid_indices[vi.g] * vi.key.grid_area - 1; \ - vi.grid = vi.grids[vi.grid_indices[vi.g]]; \ - if (mode == PBVH_ITER_UNIQUE) { \ - vi.gh = vi.grid_hidden[vi.grid_indices[vi.g]]; \ + for (vi.i = 0, vi.g = 0; vi.g < vi.totgrid; vi.g++) { \ + if (vi.grids) { \ + vi.width = vi.gridsize; \ + vi.height = vi.gridsize; \ + vi.index = vi.grid_indices[vi.g] * vi.key.grid_area - 1; \ + vi.grid = vi.grids[vi.grid_indices[vi.g]]; \ + if (mode == PBVH_ITER_UNIQUE) { \ + vi.gh = vi.grid_hidden[vi.grid_indices[vi.g]]; \ + } \ + } \ + else { \ + vi.width = vi.totvert; \ + vi.height = 1; \ } \ - } \ - else { \ - vi.width = vi.totvert; \ - vi.height = 1; \ - } \ \ - for (vi.gy = 0; vi.gy < vi.height; vi.gy++) { \ - for (vi.gx = 0; vi.gx < vi.width; vi.gx++, vi.i++) { \ - if (vi.grid) { \ - vi.co = CCG_elem_co(&vi.key, vi.grid); \ - vi.fno = CCG_elem_no(&vi.key, vi.grid); \ - vi.mask = vi.key.has_mask ? CCG_elem_mask(&vi.key, vi.grid) : NULL; \ - vi.grid = CCG_elem_next(&vi.key, vi.grid); \ - vi.index++; \ - vi.visible = true; \ - if (vi.gh) { \ - if (BLI_BITMAP_TEST(vi.gh, vi.gy * vi.gridsize + vi.gx)) { \ - continue; \ + for (vi.gy = 0; vi.gy < vi.height; vi.gy++) { \ + for (vi.gx = 0; vi.gx < vi.width; vi.gx++, vi.i++) { \ + if (vi.grid) { \ + vi.co = CCG_elem_co(&vi.key, vi.grid); \ + vi.fno = CCG_elem_no(&vi.key, vi.grid); \ + vi.mask = vi.key.has_mask ? CCG_elem_mask(&vi.key, vi.grid) : NULL; \ + vi.grid = CCG_elem_next(&vi.key, vi.grid); \ + vi.index++; \ + vi.visible = true; \ + if (vi.gh) { \ + if (BLI_BITMAP_TEST(vi.gh, vi.gy * vi.gridsize + vi.gx)) { \ + continue; \ + } \ } \ } \ - } \ - else if (vi.mverts) { \ - vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \ - if (vi.respect_hide) { \ - vi.visible = !(vi.mvert->flag & ME_HIDE); \ - if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \ - continue; \ + else if (vi.mverts) { \ + vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \ + if (vi.respect_hide) { \ + vi.visible = !(vi.mvert->flag & ME_HIDE); \ + if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \ + continue; \ + } \ + } \ + else { \ + BLI_assert(vi.visible); \ + } \ + vi.co = vi.mvert->co; \ + vi.no = vi.mvert->no; \ + vi.index = vi.vert_indices[vi.i]; \ + if (vi.vmask) { \ + vi.mask = &vi.vmask[vi.index]; \ + } \ + if (vi.vcol) { \ + vi.col = vi.vcol[vi.index].color; \ } \ } \ - else { \ - BLI_assert(vi.visible); \ - } \ - vi.co = vi.mvert->co; \ - vi.no = vi.mvert->no; \ - vi.index = vi.vert_indices[vi.i]; \ - if (vi.vmask) { \ - vi.mask = &vi.vmask[vi.index]; \ - } \ - if (vi.vcol) { \ - vi.col = vi.vcol[vi.index].color; \ - } \ - } \ - else if (vi.tm_vdata) { \ - TMVert *tv = NULL; \ - while (!tv) { \ - if (!vi.tm_cur_set->elems || vi.ti >= vi.tm_cur_set->cur) { \ - if (vi.tm_cur_set != vi.tm_other_verts) { \ - vi.tm_cur_set = vi.tm_other_verts; \ - vi.ti = 0; \ - if (!vi.tm_cur_set->elems || vi.ti >= vi.tm_other_verts->cur) { \ + else if (vi.tm_vdata) { \ + TMVert *tv = NULL; \ + while (!tv) { \ + if (!vi.tm_cur_set->elems || vi.ti >= vi.tm_cur_set->cur) { \ + if (vi.tm_cur_set != vi.tm_other_verts) { \ + vi.tm_cur_set = vi.tm_other_verts; \ + vi.ti = 0; \ + if (!vi.tm_cur_set->elems || vi.ti >= vi.tm_other_verts->cur) { \ + break; \ + } \ + } \ + else { \ break; \ } \ } \ else { \ - break; \ + tv = vi.tm_cur_set->elems[vi.ti++]; \ + if (tv && BLI_safepool_elem_is_dead(tv)) { \ + printf("dead vert: %p\n", tv); \ + tv = NULL; \ + } \ } \ } \ + if (!tv) { \ + continue; \ + } \ + vi.tm_vert = tv; \ + vi.visible = !TM_elem_flag_test_bool(vi.tm_vert, TM_ELEM_HIDDEN); \ + if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \ + continue; \ + } \ + vi.co = vi.tm_vert->co; \ + vi.fno = vi.tm_vert->no; \ + vi.index = (SculptIdx)vi.tm_vert; \ + vi.mask = TM_ELEM_CD_GET_VOID_P(vi.tm_vert, vi.cd_vert_mask_offset); \ + } \ + else { \ + if (!BLI_gsetIterator_done(&vi.bm_unique_verts)) { \ + vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_unique_verts); \ + BLI_gsetIterator_step(&vi.bm_unique_verts); \ + } \ else { \ - tv = vi.tm_cur_set->elems[vi.ti++]; \ - if (tv && BLI_safepool_elem_is_dead(tv)) { \ - printf("dead vert: %p\n", tv); \ - tv = NULL; \ + vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_other_verts); \ + BLI_gsetIterator_step(&vi.bm_other_verts); \ + } \ + vi.visible = !BM_elem_flag_test_bool(vi.bm_vert, BM_ELEM_HIDDEN); \ + if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \ + continue; \ + } \ + vi.co = vi.bm_vert->co; \ + vi.fno = vi.bm_vert->no; \ + vi.index = BM_elem_index_get(vi.bm_vert); \ + vi.mask = BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset); \ + } + +#else + +# define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode) \ + pbvh_vertex_iter_init(pbvh, node, &vi, mode); \ +\ + for (vi.i = 0, vi.g = 0; vi.g < vi.totgrid; vi.g++) { \ + if (vi.grids) { \ + vi.width = vi.gridsize; \ + vi.height = vi.gridsize; \ + vi.index = vi.grid_indices[vi.g] * vi.key.grid_area - 1; \ + vi.grid = vi.grids[vi.grid_indices[vi.g]]; \ + if (mode == PBVH_ITER_UNIQUE) { \ + vi.gh = vi.grid_hidden[vi.grid_indices[vi.g]]; \ + } \ + } \ + else { \ + vi.width = vi.totvert; \ + vi.height = 1; \ + } \ +\ + for (vi.gy = 0; vi.gy < vi.height; vi.gy++) { \ + for (vi.gx = 0; vi.gx < vi.width; vi.gx++, vi.i++) { \ + if (vi.grid) { \ + vi.co = CCG_elem_co(&vi.key, vi.grid); \ + vi.fno = CCG_elem_no(&vi.key, vi.grid); \ + vi.mask = vi.key.has_mask ? CCG_elem_mask(&vi.key, vi.grid) : NULL; \ + vi.grid = CCG_elem_next(&vi.key, vi.grid); \ + vi.index++; \ + vi.visible = true; \ + if (vi.gh) { \ + if (BLI_BITMAP_TEST(vi.gh, vi.gy * vi.gridsize + vi.gx)) { \ + continue; \ } \ } \ } \ - if (!tv) { \ - continue; \ - } \ - vi.tm_vert = tv; \ - vi.visible = !TM_elem_flag_test_bool(vi.tm_vert, TM_ELEM_HIDDEN); \ - if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \ - continue; \ - } \ - vi.co = vi.tm_vert->co; \ - vi.fno = vi.tm_vert->no; \ - vi.index = (SculptIdx)vi.tm_vert; \ - vi.mask = TM_ELEM_CD_GET_VOID_P(vi.tm_vert, vi.cd_vert_mask_offset); \ - } \ - else { \ - if (!BLI_gsetIterator_done(&vi.bm_unique_verts)) { \ - vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_unique_verts); \ - BLI_gsetIterator_step(&vi.bm_unique_verts); \ + else if (vi.mverts) { \ + vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \ + if (vi.respect_hide) { \ + vi.visible = !(vi.mvert->flag & ME_HIDE); \ + if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \ + continue; \ + } \ + } \ + else { \ + BLI_assert(vi.visible); \ + } \ + vi.co = vi.mvert->co; \ + vi.no = vi.mvert->no; \ + vi.index = vi.vert_indices[vi.i]; \ + if (vi.vmask) { \ + vi.mask = &vi.vmask[vi.index]; \ + } \ + if (vi.vcol) { \ + vi.col = vi.vcol[vi.index].color; \ + } \ } \ else { \ - vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_other_verts); \ - BLI_gsetIterator_step(&vi.bm_other_verts); \ - } \ - vi.visible = !BM_elem_flag_test_bool(vi.bm_vert, BM_ELEM_HIDDEN); \ - if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \ - continue; \ - } \ - vi.co = vi.bm_vert->co; \ - vi.fno = vi.bm_vert->no; \ - vi.index = BM_elem_index_get(vi.bm_vert); \ - vi.mask = BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset); \ - } + if (!BLI_gsetIterator_done(&vi.bm_unique_verts)) { \ + vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_unique_verts); \ + BLI_gsetIterator_step(&vi.bm_unique_verts); \ + } \ + else { \ + vi.bm_vert = BLI_gsetIterator_getKey(&vi.bm_other_verts); \ + BLI_gsetIterator_step(&vi.bm_other_verts); \ + } \ + vi.visible = !BM_elem_flag_test_bool(vi.bm_vert, BM_ELEM_HIDDEN); \ + if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \ + continue; \ + } \ + vi.co = vi.bm_vert->co; \ + vi.fno = vi.bm_vert->no; \ + vi.index = BM_elem_index_get(vi.bm_vert); \ + vi.mask = BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset); \ + } + +#endif #define BKE_pbvh_vertex_iter_end \ } \ diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index d940ad5cf9d..074fc4ecff5 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -1468,8 +1468,15 @@ void BKE_sculptsession_free(Object *ob) SculptSession *ss = ob->sculpt; if (ss->tm) { +#ifdef WITH_TRIMESH BKE_sculptsession_tm_to_me(ob, true); TMesh_free(ss->tm); + ss->tm = NULL; +#else + BKE_sculptsession_bm_to_me(ob, true); + BM_mesh_free(ss->bm); + ss->bm = NULL; +#endif } sculptsession_free_pbvh(ob); @@ -2044,12 +2051,22 @@ void BKE_sculpt_sync_face_set_visibility(struct Mesh *mesh, struct SubdivCCG *su static PBVH *build_pbvh_for_dynamic_topology(Object *ob) { PBVH *pbvh = BKE_pbvh_new(); + +#ifdef WITH_TRIMESH BKE_pbvh_build_trimesh(pbvh, ob->sculpt->tm, ob->sculpt->bm_smooth_shading, ob->sculpt->tm_log, ob->sculpt->cd_vert_node_offset, ob->sculpt->cd_face_node_offset); +#else + BKE_pbvh_build_bmesh(pbvh, + ob->sculpt->bm, + ob->sculpt->bm_smooth_shading, + ob->sculpt->bm_log, + ob->sculpt->cd_vert_node_offset, + ob->sculpt->cd_face_node_offset); +#endif pbvh_show_mask_set(pbvh, ob->sculpt->show_mask); pbvh_show_face_sets_set(pbvh, false); return pbvh; @@ -2144,7 +2161,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob) return pbvh; } - if (ob->sculpt->tm != NULL) { + if (ob->sculpt->tm != NULL || ob->sculpt->bm != NULL) { /* Sculpting on a TriMesh (dynamic-topology) gets a special PBVH. */ pbvh = build_pbvh_for_dynamic_topology(ob); } diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index f718904963e..d042ac359c0 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -713,11 +713,11 @@ void BKE_pbvh_free(PBVH *pbvh) } if (node->tm_unique_verts) { - TMElemSet_free(node->tm_unique_verts); + BLI_table_gset_free(node->tm_unique_verts); } if (node->tm_other_verts) { - TMElemSet_free(node->tm_other_verts); + BLI_table_gset_free(node->tm_other_verts); } if (node->tm_faces) { @@ -1584,7 +1584,7 @@ static void pbvh_bmesh_node_visibility_update(PBVHNode *node) static void pbvh_trimesh_node_visibility_update(PBVHNode *node) { - TMElemSet *unique, *other; + TableGSet *unique, *other; TMVert *v; unique = BKE_pbvh_trimesh_node_unique_verts(node); diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index 0dfa8bd16e6..b91060cd951 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -112,8 +112,8 @@ struct PBVHNode { /* trimesh */ GSet *tm_faces; - TMElemSet *tm_unique_verts; - TMElemSet *tm_other_verts; + TableGSet *tm_unique_verts; + TableGSet *tm_other_verts; float (*tm_orco)[3]; int (*tm_ortri)[3]; int tm_tot_ortri; diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index c271a4b668b..40e5e8080dd 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -288,7 +288,7 @@ static void partialvis_update_bmesh(Object *ob, } static void partialvis_update_trimesh_verts(TM_TriMesh *bm, - TMElemSet *verts, + TableGSet *verts, PartialVisAction action, PartialVisArea area, float planes[4][4], @@ -351,7 +351,7 @@ static void partialvis_update_trimesh(Object *ob, float planes[4][4]) { TM_TriMesh *bm; - TMElemSet *unique, *other; + TableGSet *unique, *other; GSet *faces; bool any_changed = false, any_visible = false; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 8eb557f95c3..4b2dca91c3a 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -7290,7 +7290,7 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) bool use_origco = false; if (srd->original && srd->ss->cache) { - if (BKE_pbvh_type(srd->ss->pbvh), PBVH_TRIMESH) { + if (ELEM(BKE_pbvh_type(srd->ss->pbvh), PBVH_TRIMESH, PBVH_BMESH)) { use_origco = true; } else { @@ -7326,7 +7326,7 @@ static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *t bool use_origco = false; if (srd->original && srd->ss->cache) { - if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_TRIMESH) { + if (ELEM(BKE_pbvh_type(srd->ss->pbvh), PBVH_TRIMESH, PBVH_BMESH)) { use_origco = true; } else { @@ -7462,6 +7462,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, ss->active_face_index = 0; ss->active_grid_index = srd.active_face_grid_index; break; + case PBVH_BMESH: case PBVH_TRIMESH: ss->active_face_index = 0; ss->active_grid_index = 0; @@ -7810,6 +7811,9 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up if (BKE_pbvh_type(ss->pbvh) == PBVH_TRIMESH) { BKE_pbvh_trimesh_after_stroke(ss->pbvh); } + if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) { + BKE_pbvh_bmesh_after_stroke(ss->pbvh); + } /* Optimization: if there is locked key and active modifiers present in */ /* the stack, keyblock is updating at each step. otherwise we could update */ diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 14a21e104dd..d298e569ffe 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -68,8 +68,8 @@ #include "ED_undo.h" #include "bmesh.h" -#include "trimesh.h" #include "sculpt_intern.h" +#include "trimesh.h" /* Implementation of undo system for objects in sculpt mode. * @@ -403,18 +403,19 @@ static bool sculpt_undo_restore_face_sets(bContext *C, SculptUndoNode *unode) return false; } - static void sculpt_undo_trimesh_restore_generic_task_cb( - void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) + void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) { PBVHNode **nodes = userdata; BKE_pbvh_node_mark_redraw(nodes[n]); } -static void sculpt_undo_trimesh_restore_generic(SculptUndoNode *unode, Object *ob, SculptSession *ss) +static void sculpt_undo_trimesh_restore_generic(SculptUndoNode *unode, + Object *ob, + SculptSession *ss) { - //XXX + // XXX return; if (unode->applied) { BM_log_undo(ss->bm, ss->bm_log); @@ -434,7 +435,7 @@ static void sculpt_undo_trimesh_restore_generic(SculptUndoNode *unode, Object *o TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); BLI_task_parallel_range( - 0, totnode, nodes, sculpt_undo_trimesh_restore_generic_task_cb, &settings); + 0, totnode, nodes, sculpt_undo_trimesh_restore_generic_task_cb, &settings); if (nodes) { MEM_freeN(nodes); @@ -455,7 +456,7 @@ static void sculpt_undo_bmesh_restore_generic_task_cb( static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob, SculptSession *ss) { - //XXX + // XXX return; if (unode->applied) { BM_log_undo(ss->bm, ss->bm_log); @@ -569,9 +570,9 @@ static void sculpt_undo_trimesh_enable(Object *ob, SculptUndoNode *unode) } static void sculpt_undo_trimesh_restore_begin(bContext *C, - SculptUndoNode *unode, - Object *ob, - SculptSession *ss) + SculptUndoNode *unode, + Object *ob, + SculptSession *ss) { if (unode->applied) { SCULPT_dynamic_topology_disable(C, unode); @@ -579,24 +580,20 @@ static void sculpt_undo_trimesh_restore_begin(bContext *C, } else { sculpt_undo_trimesh_enable(ob, unode); - - /* Restore the mesh from the first log entry. */ - //XXX BM_log_redo(ss->bm, ss->bm_log); - unode->applied = true; } } static void sculpt_undo_trimesh_restore_end(bContext *C, - SculptUndoNode *unode, - Object *ob, - SculptSession *ss) + SculptUndoNode *unode, + Object *ob, + SculptSession *ss) { if (unode->applied) { sculpt_undo_trimesh_enable(ob, unode); /* Restore the mesh from the last log entry. */ - //XXX BM_log_undo(ss->bm, ss->bm_log); + // XXX BM_log_undo(ss->bm, ss->bm_log); unode->applied = false; } @@ -716,30 +713,47 @@ static int sculpt_undo_bmesh_restore(bContext *C, } /* Handle all dynamic-topology updates -* -* Returns true if this was a dynamic-topology undo step, otherwise -* returns false to indicate the non-dyntopo code should run. */ + * + * Returns true if this was a dynamic-topology undo step, otherwise + * returns false to indicate the non-dyntopo code should run. */ static int sculpt_undo_trimesh_restore(bContext *C, - SculptUndoNode *unode, - Object *ob, - SculptSession *ss) + SculptUndoNode *unode, + Object *ob, + SculptSession *ss) { +#ifdef WITH_TRIMESH switch (unode->type) { - case SCULPT_UNDO_DYNTOPO_BEGIN: - sculpt_undo_trimesh_restore_begin(C, unode, ob, ss); - return true; + case SCULPT_UNDO_DYNTOPO_BEGIN: + sculpt_undo_trimesh_restore_begin(C, unode, ob, ss); + return true; - case SCULPT_UNDO_DYNTOPO_END: - sculpt_undo_trimesh_restore_end(C, unode, ob, ss); - return true; - default: - if (ss->bm_log) { - sculpt_undo_trimesh_restore_generic(unode, ob, ss); + case SCULPT_UNDO_DYNTOPO_END: + sculpt_undo_trimesh_restore_end(C, unode, ob, ss); return true; - } - break; + default: + if (ss->tm_log) { + sculpt_undo_trimesh_restore_generic(unode, ob, ss); + return true; + } + break; } +#else + switch (unode->type) { + case SCULPT_UNDO_DYNTOPO_BEGIN: + sculpt_undo_bmesh_restore_begin(C, unode, ob, ss); + return true; + case SCULPT_UNDO_DYNTOPO_END: + sculpt_undo_bmesh_restore_end(C, unode, ob, ss); + return true; + default: + if (ss->bm_log) { + sculpt_undo_bmesh_restore_generic(unode, ob, ss); + return true; + } + break; + } +#endif return false; } @@ -1408,10 +1422,10 @@ static SculptUndoNode *sculpt_undo_trimesh_push(Object *ob, PBVHNode *node, Scul } else if (type == SCULPT_UNDO_DYNTOPO_BEGIN) { /* Store a copy of the mesh's current vertices, loops, and - * polys. A full copy like this is needed because entering - * dynamic-topology immediately does topological edits - * (converting polys to triangles) that the BMLog can't - * fully restore from. */ + * polys. A full copy like this is needed because entering + * dynamic-topology immediately does topological edits + * (converting polys to triangles) that the BMLog can't + * fully restore from. */ SculptUndoNodeGeometry *geometry = &unode->geometry_bmesh_enter; sculpt_undo_geometry_store_data(geometry, ob); @@ -1427,40 +1441,40 @@ static SculptUndoNode *sculpt_undo_trimesh_push(Object *ob, PBVHNode *node, Scul if (node) { switch (type) { - case SCULPT_UNDO_COORDS: - case SCULPT_UNDO_MASK: - /* Before any vertex values get modified, ensure their - * original positions are logged. */ - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) - { - BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset); - } - BKE_pbvh_vertex_iter_end; - break; + case SCULPT_UNDO_COORDS: + case SCULPT_UNDO_MASK: + /* Before any vertex values get modified, ensure their + * original positions are logged. */ + BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) + { + BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset); + } + BKE_pbvh_vertex_iter_end; + break; - case SCULPT_UNDO_HIDDEN: { - GSetIterator gs_iter; - GSet *faces = BKE_pbvh_bmesh_node_faces(node); - BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) - { - BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset); - } - BKE_pbvh_vertex_iter_end; + case SCULPT_UNDO_HIDDEN: { + GSetIterator gs_iter; + GSet *faces = BKE_pbvh_bmesh_node_faces(node); + BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) + { + BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset); + } + BKE_pbvh_vertex_iter_end; - GSET_ITER (gs_iter, faces) { - BMFace *f = BLI_gsetIterator_getKey(&gs_iter); - BM_log_face_modified(ss->bm_log, f); + GSET_ITER (gs_iter, faces) { + BMFace *f = BLI_gsetIterator_getKey(&gs_iter); + BM_log_face_modified(ss->bm_log, f); + } + break; } - break; - } - case SCULPT_UNDO_DYNTOPO_BEGIN: - case SCULPT_UNDO_DYNTOPO_END: - case SCULPT_UNDO_DYNTOPO_SYMMETRIZE: - case SCULPT_UNDO_GEOMETRY: - case SCULPT_UNDO_FACE_SETS: - case SCULPT_UNDO_COLOR: - break; + case SCULPT_UNDO_DYNTOPO_BEGIN: + case SCULPT_UNDO_DYNTOPO_END: + case SCULPT_UNDO_DYNTOPO_SYMMETRIZE: + case SCULPT_UNDO_GEOMETRY: + case SCULPT_UNDO_FACE_SETS: + case SCULPT_UNDO_COLOR: + break; } } @@ -1478,6 +1492,7 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType ss->needs_flush_to_id = 1; +#ifdef WITH_TRIMESH if (ss->tm || ELEM(type, SCULPT_UNDO_DYNTOPO_BEGIN, SCULPT_UNDO_DYNTOPO_END)) { /* Dynamic topology stores only one undo node per stroke, * regardless of the number of PBVH nodes modified. */ @@ -1485,6 +1500,15 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType BLI_thread_unlock(LOCK_CUSTOM1); return unode; } +#else + if (ss->bm || ELEM(type, SCULPT_UNDO_DYNTOPO_BEGIN, SCULPT_UNDO_DYNTOPO_END)) { + /* Dynamic topology stores only one undo node per stroke, + * regardless of the number of PBVH nodes modified. */ + unode = sculpt_undo_bmesh_push(ob, node, type); + BLI_thread_unlock(LOCK_CUSTOM1); + return unode; + } +#endif if (type == SCULPT_UNDO_GEOMETRY) { unode = sculpt_undo_geometry_push(ob, type); BLI_thread_unlock(LOCK_CUSTOM1); diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index 69d1248e1ff..f7bc6fd3249 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -98,8 +98,8 @@ struct TM_TriMesh; void GPU_pbvh_trimesh_buffers_update(GPU_PBVH_Buffers *buffers, struct TM_TriMesh *bm, struct GSet *bm_faces, - struct TMElemSet *bm_unique_verts, - struct TMElemSet *bm_other_verts, + struct TableGSet *bm_unique_verts, + struct TableGSet *bm_other_verts, const int update_flags, const int cd_vert_node_offset); void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers, diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 9ca965373f4..90617f226dd 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -796,7 +796,8 @@ static void gpu_bmesh_vert_to_buffer_copy(BMVert *v, const int cd_vert_mask_offset, const bool show_mask, const bool show_vcol, - bool *empty_mask) + bool *empty_mask, + int cd_vcol_offset) { /* Vertex should always be visible if it's used by a visible face. */ BLI_assert(!BM_elem_flag_test(v, BM_ELEM_HIDDEN)); @@ -815,9 +816,42 @@ static void gpu_bmesh_vert_to_buffer_copy(BMVert *v, *empty_mask = *empty_mask && (cmask == 0); } - if (show_vcol) { + if (show_vcol && cd_vcol_offset >= 0) { + ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; + int col[4] = {0, 0, 0, 0}; + int tot = 0; + + BMIter iter; + BMLoop *l; + + BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { + MLoopCol *ml = BM_ELEM_CD_GET_VOID_P(l, cd_vcol_offset); + + col[0] += ml->r; + col[1] += ml->g; + col[2] += ml->b; + col[3] += ml->a; + tot++; + } + + if (tot) { + col[0] /= tot; + col[1] /= tot; + col[2] /= tot; + col[3] /= tot; + + vcol[0] = (ushort)(col[0] * 257); + vcol[1] = (ushort)(col[1] * 257); + vcol[2] = (ushort)(col[2] * 257); + vcol[3] = (ushort)(col[3] * 257); + // printf("%d %d %d %d %d\n", vcol[0], vcol[1], vcol[2], vcol[3], tot); + } + // const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; + GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, v_index, vcol); + } + else if (show_vcol) { const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; - GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, v_index, &vcol); + GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, v_index, vcol); } /* Add default face sets color to avoid artifacts. */ @@ -890,9 +924,9 @@ static void gpu_trimesh_vert_to_buffer_copy(TMVert *v, vcol[1] = (ushort)(col[1] * 257); vcol[2] = (ushort)(col[2] * 257); vcol[3] = (ushort)(col[3] * 257); - //printf("%d %d %d %d %d\n", vcol[0], vcol[1], vcol[2], vcol[3], tot); + // printf("%d %d %d %d %d\n", vcol[0], vcol[1], vcol[2], vcol[3], tot); } - //const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; + // const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}; GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, v_index, vcol); } else if (show_vcol) { @@ -908,7 +942,7 @@ static void gpu_trimesh_vert_to_buffer_copy(TMVert *v, } /* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */ -static int gpu_trimesh_vert_visible_count(TMElemSet *bm_unique_verts, TMElemSet *bm_other_verts) +static int gpu_trimesh_vert_visible_count(TableGSet *bm_unique_verts, TableGSet *bm_other_verts) { int totvert = 0; TMVert *v; @@ -1056,6 +1090,7 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers, /* TODO, make mask layer optional for bmesh buffer */ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK); + const int cd_vcol_offset = CustomData_get_offset(&bm->vdata, CD_MLOOPCOL); /* Fill vertex buffer */ if (!gpu_pbvh_vert_buf_data_set(buffers, totvert)) { @@ -1096,7 +1131,8 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers, cd_vert_mask_offset, show_mask, show_vcol, - &empty_mask); + &empty_mask, + cd_vcol_offset); idx[i] = v_index; v_index++; @@ -1163,7 +1199,8 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers, cd_vert_mask_offset, show_mask, show_vcol, - &empty_mask); + &empty_mask, + cd_vcol_offset); } } } @@ -1186,13 +1223,13 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers, void GPU_pbvh_trimesh_buffers_update(GPU_PBVH_Buffers *buffers, TM_TriMesh *bm, GSet *tm_faces, - TMElemSet *bm_unique_verts, - TMElemSet *bm_other_verts, + TableGSet *bm_unique_verts, + TableGSet *bm_other_verts, const int update_flags, const int cd_vert_node_offset) { const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; - const bool show_vcol = true; //(update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0; + const bool show_vcol = true; //(update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0; int tottri, totvert; bool empty_mask = true; TMFace *f = NULL; -- cgit v1.2.3