Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2020-10-24 01:53:39 +0300
committerJoseph Eagar <joeedh@gmail.com>2020-10-24 01:53:39 +0300
commit8f6326d494fad50305e406557dee7d2d2cb44dd3 (patch)
tree154e0264575ccdf5fea6949125cdd0823d9709ef
parent4faa2b4bc9f56cc2ab7260e5d464fcee27a7adbb (diff)
BMesh dyntopo works again, if you disable WITH_TRIMESH in BKE_pbvh.h
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h285
-rw-r--r--source/blender/blenkernel/intern/paint.c19
-rw-r--r--source/blender/blenkernel/intern/pbvh.c6
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h4
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c8
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c162
-rw-r--r--source/blender/gpu/GPU_buffers.h4
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c59
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;