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 03:19:47 +0300
committerJoseph Eagar <joeedh@gmail.com>2020-10-24 03:19:47 +0300
commit6c9c7f14ec87c62ff5eca5e200640b4bd6ccdedf (patch)
treef0abb70051b1801b932e037ed74969bb9af38fdd
parent8f6326d494fad50305e406557dee7d2d2cb44dd3 (diff)
* Migrated optimizations from trimesh to bmesh dyntopo:
- Original coordinate/normals are now stored in customdata layers, instead of being looked up in the BMLog - Vertex "indices" are now actually pointers to BMVerts. - Dyntopo split/collapse is now time-limited - Increased pbvh->leaf_limit to 2000 - Nodes are split after topolgy updates, not just after the user lets up the mouse. * Also, renamed TMElemSet to TableGSet TODO: - Migrate PBVHNode->bm_[unique_verts/other_verts/faces] to TableGSet. Currently GHash is completely inlined in this branch which does almost the same thing performance-size; inlining GHash seems beyond the scope of this project however.
-rw-r--r--source/blender/blenkernel/BKE_paint.h2
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h14
-rw-r--r--source/blender/blenkernel/intern/paint.c6
-rw-r--r--source/blender/blenkernel/intern/pbvh.c4
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c83
-rw-r--r--source/blender/blenkernel/intern/pbvh_intern.h4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c86
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_detail.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_dyntopo.c70
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h1
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c8
-rw-r--r--source/blender/editors/space_info/info_stats.c6
-rw-r--r--source/blender/makesrna/intern/rna_object.c2
14 files changed, 230 insertions, 60 deletions
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index a35dc63d9bd..46e2e56a552 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -478,6 +478,8 @@ typedef struct SculptSession {
struct BMesh *bm;
int cd_vert_node_offset;
int cd_face_node_offset;
+ int cd_origco_offset;
+ int cd_origno_offset;
bool bm_smooth_shading;
/* Undo/redo log for dynamic topology sculpting */
struct BMLog *bm_log;
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 721763178fe..4ea9a1cf6a0 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -232,7 +232,9 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
bool smooth_shading,
struct BMLog *log,
const int cd_vert_node_offset,
- const int cd_face_node_offset);
+ const int cd_face_node_offset,
+ const int cd_origco_offset,
+ const int cd_origno_offset);
void BKE_pbvh_build_trimesh(PBVH *bvh,
struct TM_TriMesh *bm,
bool smooth_shading,
@@ -240,6 +242,9 @@ void BKE_pbvh_build_trimesh(PBVH *bvh,
const int cd_vert_node_offset,
const int cd_face_node_offset);
+struct BMVert;
+void BKE_pbvh_bmesh_update_origvert(PBVH *bvh, struct BMVert *v);
+
void BKE_pbvh_free(PBVH *bvh);
// void BKE_pbvh_free_layer_disp(PBVH *bvh);
@@ -368,7 +373,8 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
const float view_normal[3],
float radius,
const bool use_frontface,
- const bool use_projected);
+ const bool use_projected,
+ int sym_axis);
bool BKE_pbvh_trimesh_update_topology(PBVH *bvh,
PBVHTopologyUpdateMode mode,
@@ -507,6 +513,8 @@ typedef struct PBVHVertexIter {
struct CustomData *tm_vdata;
int cd_vert_mask_offset;
+ int cd_origco_offset;
+ int cd_origno_offset;
/* result: these are all computed in the macro, but we assume
* that compiler optimization's will skip the ones we don't use */
@@ -705,7 +713,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
} \
vi.co = vi.bm_vert->co; \
vi.fno = vi.bm_vert->no; \
- vi.index = BM_elem_index_get(vi.bm_vert); \
+ vi.index = (SculptIdx)vi.bm_vert; \
vi.mask = BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset); \
}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 074fc4ecff5..f2e6c52a61a 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1467,7 +1467,7 @@ void BKE_sculptsession_free(Object *ob)
if (ob && ob->sculpt) {
SculptSession *ss = ob->sculpt;
- if (ss->tm) {
+ if (ss->tm || ss->bm) {
#ifdef WITH_TRIMESH
BKE_sculptsession_tm_to_me(ob, true);
TMesh_free(ss->tm);
@@ -2065,7 +2065,9 @@ static PBVH *build_pbvh_for_dynamic_topology(Object *ob)
ob->sculpt->bm_smooth_shading,
ob->sculpt->bm_log,
ob->sculpt->cd_vert_node_offset,
- ob->sculpt->cd_face_node_offset);
+ ob->sculpt->cd_face_node_offset,
+ ob->sculpt->cd_origco_offset,
+ ob->sculpt->cd_origno_offset);
#endif
pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
pbvh_show_face_sets_set(pbvh, false);
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index d042ac359c0..3140837ebac 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -2441,7 +2441,7 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh,
face_normal);
break;
case PBVH_BMESH:
- BM_mesh_elem_index_ensure(pbvh->bm, BM_VERT);
+ //BM_mesh_elem_index_ensure(pbvh->bm, BM_VERT);
hit = pbvh_bmesh_node_raycast(node,
ray_start,
ray_normal,
@@ -3111,6 +3111,8 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
BLI_gsetIterator_init(&vi->bm_unique_verts, node->bm_unique_verts);
BLI_gsetIterator_init(&vi->bm_other_verts, node->bm_other_verts);
vi->bm_vdata = &pbvh->bm->vdata;
+ vi->cd_origco_offset = pbvh->cd_origco_offset;
+ vi->cd_origno_offset = pbvh->cd_origno_offset;
vi->cd_vert_mask_offset = CustomData_get_offset(vi->bm_vdata, CD_PAINT_MASK);
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 7c3b9edcc70..0d31494daa8 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -26,6 +26,7 @@
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
+#include "PIL_time.h"
#include "BKE_DerivedMesh.h"
#include "BKE_ccg.h"
@@ -36,6 +37,9 @@
#include "bmesh.h"
#include "pbvh_intern.h"
+#define DYNTOPO_TIME_LIMIT 0.015
+#define DYNTOPO_RUN_INTERVAL 0.01
+
/* Avoid skinny faces */
#define USE_EDGEQUEUE_EVEN_SUBDIV
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
@@ -1236,8 +1240,13 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
BLI_Buffer *edge_loops)
{
bool any_subdivided = false;
+ double time = PIL_check_seconds_timer();
while (!BLI_heapsimple_is_empty(eq_ctx->q->heap)) {
+ if (PIL_check_seconds_timer() - time > DYNTOPO_TIME_LIMIT) {
+ break;
+ }
+
BMVert **pair = BLI_heapsimple_pop_min(eq_ctx->q->heap);
BMVert *v1 = pair[0], *v2 = pair[1];
BMEdge *e;
@@ -1451,6 +1460,17 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BM_vert_kill(pbvh->bm, v_del);
}
+void BKE_pbvh_bmesh_update_origvert(PBVH *pbvh, BMVert *v)
+{
+ BM_log_vert_before_modified(pbvh->bm_log, v, pbvh->cd_vert_mask_offset);
+
+ float *co = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_origco_offset);
+ float *no = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_origno_offset);
+
+ copy_v3_v3(co, v->co);
+ copy_v3_v3(no, v->no);
+}
+
static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
PBVH *pbvh,
BLI_Buffer *deleted_faces)
@@ -1460,7 +1480,13 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
/* deleted verts point to vertices they were merged into, or NULL when removed. */
GHash *deleted_verts = BLI_ghash_ptr_new("deleted_verts");
+ double time = PIL_check_seconds_timer();
+
while (!BLI_heapsimple_is_empty(eq_ctx->q->heap)) {
+ if (PIL_check_seconds_timer() - time > DYNTOPO_TIME_LIMIT) {
+ break;
+ }
+
BMVert **pair = BLI_heapsimple_pop_min(eq_ctx->q->heap);
BMVert *v1 = pair[0], *v2 = pair[1];
BLI_mempool_free(eq_ctx->pool, pair);
@@ -1556,7 +1582,7 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
if (len_squared_v3v3(location, v_tri[j]->co) <
len_squared_v3v3(location, nearest_vertex_co)) {
copy_v3_v3(nearest_vertex_co, v_tri[j]->co);
- *r_active_vertex_index = BM_elem_index_get(v_tri[j]);
+ *r_active_vertex_index = (SculptIdx)v_tri[j]; // BM_elem_index_get(v_tri[j]);
}
}
}
@@ -1880,10 +1906,16 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
bool smooth_shading,
BMLog *log,
const int cd_vert_node_offset,
- const int cd_face_node_offset)
+ const int cd_face_node_offset,
+ const int cd_origco_offset,
+ const int cd_origno_offset)
{
pbvh->cd_vert_node_offset = cd_vert_node_offset;
pbvh->cd_face_node_offset = cd_face_node_offset;
+ pbvh->cd_origco_offset = cd_origco_offset;
+ pbvh->cd_origno_offset = cd_origno_offset;
+ pbvh->cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+
pbvh->bm = bm;
BKE_pbvh_bmesh_detail_size_set(pbvh, 0.75);
@@ -1892,7 +1924,7 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
pbvh->bm_log = log;
/* TODO: choose leaf limit better */
- pbvh->leaf_limit = 100;
+ pbvh->leaf_limit = 2000;
if (smooth_shading) {
pbvh->flags |= PBVH_DYNTOPO_SMOOTH_SHADING;
@@ -1952,6 +1984,10 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
MEM_freeN(nodeinfo);
}
+static double last_update_time[128] = {
+ 0,
+};
+
/* Collapse short edges, subdivide long edges */
bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
PBVHTopologyUpdateMode mode,
@@ -1959,8 +1995,19 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
const float view_normal[3],
float radius,
const bool use_frontface,
- const bool use_projected)
+ const bool use_projected,
+ int sym_axis)
{
+ if (sym_axis >= 0 &&
+ PIL_check_seconds_timer() - last_update_time[sym_axis] < DYNTOPO_RUN_INTERVAL) {
+ return false;
+ // return false;
+ }
+
+ if (sym_axis >= 0) {
+ last_update_time[sym_axis] = PIL_check_seconds_timer();
+ }
+
/* 2 is enough for edge faces - manifold edge */
BLI_buffer_declare_static(BMLoop *, edge_loops, BLI_BUFFER_NOP, 2);
BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
@@ -2012,14 +2059,32 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
BLI_mempool_destroy(queue_pool);
}
- /* Unmark nodes */
- for (int n = 0; n < pbvh->totnode; n++) {
- PBVHNode *node = &pbvh->nodes[n];
+ if (modified) {
+ for (int i = 0; i < pbvh->totnode; i++) {
+ PBVHNode *node = pbvh->nodes + i;
- if (node->flag & PBVH_Leaf && node->flag & PBVH_UpdateTopology) {
- node->flag &= ~PBVH_UpdateTopology;
+ if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) &&
+ !(node->flag & PBVH_FullyHidden)) {
+ /* Recursively split nodes that have gotten too many
+ * elements */
+ pbvh_bmesh_node_limit_ensure(pbvh, i);
+ }
+
+ if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology)) {
+ node->flag &= ~PBVH_UpdateTopology;
+ }
+ }
+ }
+ else { // still unmark nodes
+ for (int i = 0; i < pbvh->totnode; i++) {
+ PBVHNode *node = pbvh->nodes + i;
+
+ if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology)) {
+ node->flag &= ~PBVH_UpdateTopology;
+ }
}
}
+
BLI_buffer_free(&edge_loops);
BLI_buffer_free(&deleted_faces);
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index b91060cd951..7a920f99491 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -188,8 +188,12 @@ struct PBVH {
BMesh *bm;
float bm_max_edge_len;
float bm_min_edge_len;
+
int cd_vert_node_offset;
int cd_face_node_offset;
+ int cd_origco_offset;
+ int cd_origno_offset;
+ int cd_vert_mask_offset;
float planes[6][4];
int num_planes;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 4b2dca91c3a..98d9581a43f 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -148,8 +148,11 @@ const float *SCULPT_vertex_co_get(SculptSession *ss, SculptIdx index)
}
return ss->mvert[index].co;
}
- case PBVH_BMESH:
- return BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co;
+ case PBVH_BMESH: {
+ BMVert *v = (BMVert *)index;
+ return v->co;
+ }
+ // return BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co;
case PBVH_TRIMESH: {
TMVert *v = (TMVert *)index;
return v->co;
@@ -194,9 +197,14 @@ void SCULPT_vertex_normal_get(SculptSession *ss, SculptIdx index, float no[3])
}
break;
}
- case PBVH_BMESH:
- copy_v3_v3(no, BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->no);
+ case PBVH_BMESH: {
+ BMVert *v = (BMVert *)index;
+ copy_v3_v3(no, v->no);
break;
+ }
+ // case PBVH_BMESH:
+ // copy_v3_v3(no, BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->no);
+ // break;
case PBVH_TRIMESH: {
TMVert *v = (TMVert *)index;
copy_v3_v3(no, v->no);
@@ -278,7 +286,7 @@ float SCULPT_vertex_mask_get(SculptSession *ss, SculptIdx index)
case PBVH_FACES:
return ss->vmask[index];
case PBVH_BMESH:
- v = BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index);
+ v = (BMVert *)index; // BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index);
mask = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK));
return *mask;
case PBVH_TRIMESH: {
@@ -362,9 +370,11 @@ void SCULPT_vertex_visible_set(SculptSession *ss, SculptIdx index, bool visible)
SET_FLAG_FROM_TEST(ss->mvert[index].flag, !visible, ME_HIDE);
ss->mvert[index].flag |= ME_VERT_PBVH_UPDATE;
break;
- case PBVH_BMESH:
- BM_elem_flag_set(BM_vert_at_index(ss->bm, index), BM_ELEM_HIDDEN, !visible);
+ case PBVH_BMESH: {
+ BMVert *v = (BMVert *)index;
+ BM_elem_flag_set(v, BM_ELEM_HIDDEN, !visible);
break;
+ }
case PBVH_TRIMESH: {
TMVert *v = (TMVert *)index;
TM_elem_flag_set(v, TM_ELEM_HIDDEN, !visible);
@@ -380,8 +390,10 @@ bool SCULPT_vertex_visible_get(SculptSession *ss, SculptIdx index)
switch (BKE_pbvh_type(ss->pbvh)) {
case PBVH_FACES:
return !(ss->mvert[index].flag & ME_HIDE);
- case PBVH_BMESH:
- return !BM_elem_flag_test(BM_vert_at_index(ss->bm, index), BM_ELEM_HIDDEN);
+ case PBVH_BMESH: {
+ BMVert *v = (BMVert *)index;
+ return !BM_elem_flag_test(v, BM_ELEM_HIDDEN);
+ }
case PBVH_TRIMESH: {
TMVert *v = (TMVert *)index;
return !TM_elem_flag_test(v, TM_ELEM_HIDDEN);
@@ -807,7 +819,7 @@ static void sculpt_vertex_neighbors_get_bmesh(SculptSession *ss,
SculptIdx index,
SculptVertexNeighborIter *iter)
{
- BMVert *v = BM_vert_at_index(ss->bm, index);
+ BMVert *v = (BMVert *)index; // BM_vert_at_index(ss->bm, index);
BMIter liter;
BMLoop *l;
iter->size = 0;
@@ -819,8 +831,8 @@ static void sculpt_vertex_neighbors_get_bmesh(SculptSession *ss,
const BMVert *adj_v[2] = {l->prev->v, l->next->v};
for (int i = 0; i < ARRAY_SIZE(adj_v); i++) {
const BMVert *v_other = adj_v[i];
- if (BM_elem_index_get(v_other) != (int)index) {
- sculpt_vertex_neighbor_add(iter, BM_elem_index_get(v_other));
+ if ((SculptIdx)v_other != index) {
+ sculpt_vertex_neighbor_add(iter, (SculptIdx)v_other);
}
}
}
@@ -936,8 +948,7 @@ bool SCULPT_vertex_is_boundary(const SculptSession *ss, const SculptIdx index)
return sculpt_check_boundary_vertex_in_base_mesh(ss, index);
}
case PBVH_BMESH: {
- BMVert *v = BM_vert_at_index(ss->bm, index);
- return BM_vert_is_boundary(v);
+ return BM_vert_is_boundary((BMVert *)index);
}
case PBVH_TRIMESH: {
TMVert *v = (TMVert *)index;
@@ -1376,7 +1387,15 @@ void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter
TM_log_original_vert_data(orig_data->tm_log, iter->tm_vert, &orig_data->co, &orig_data->no);
}
else if (orig_data->bm_log) {
- BM_log_original_vert_data(orig_data->bm_log, iter->bm_vert, &orig_data->co, &orig_data->no);
+ float *co = BM_ELEM_CD_GET_VOID_P(iter->bm_vert, iter->cd_origco_offset);
+ float *no = BM_ELEM_CD_GET_VOID_P(iter->bm_vert, iter->cd_origno_offset);
+
+ orig_data->co = co;
+ orig_data->no = orig_data->_no;
+
+ normal_float_to_short_v3(orig_data->_no, no);
+ // BM_log_original_vert_data(orig_data->bm_log, iter->bm_vert, &orig_data->co,
+ // &orig_data->no);
}
else {
orig_data->co = orig_data->coords[iter->i];
@@ -1511,8 +1530,11 @@ static void sculpt_project_v3(const SculptProjectVector *spvc, const float vec[3
* Same goes for alt-key smoothing. */
bool SCULPT_stroke_is_dynamic_topology(const SculptSession *ss, const Brush *brush)
{
+#ifdef WITH_TRIMESH
return ((BKE_pbvh_type(ss->pbvh) == PBVH_TRIMESH) &&
-
+#else
+ return ((BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) &&
+#endif
(!ss->cache || (!ss->cache->alt_smooth)) &&
/* Requires mesh restore, which doesn't work with
@@ -2113,11 +2135,19 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
if (use_original) {
if (unode->bm_entry) {
+ float *temp_co = BM_ELEM_CD_GET_VOID_P(vd.bm_vert, vd.cd_origco_offset);
+ float *temp_no = BM_ELEM_CD_GET_VOID_P(vd.bm_vert, vd.cd_origno_offset);
+
+ copy_v3_v3(co, temp_co);
+ normal_float_to_short_v3(no_s, temp_no);
+
+ /*
const float *temp_co;
const short *temp_no_s;
BM_log_original_vert_data(ss->bm_log, vd.bm_vert, &temp_co, &temp_no_s);
copy_v3_v3(co, temp_co);
copy_v3_v3_short(no_s, temp_no_s);
+ */
}
else {
copy_v3_v3(co, unode->co[vd.i]);
@@ -5780,6 +5810,11 @@ static void sculpt_topology_update(Sculpt *sd,
}
}
+ int symidx = ss->cache->mirror_symmetry_pass + (ss->cache->radial_symmetry_pass * 8);
+ if (symidx > 127) {
+ symidx = 127;
+ }
+
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
BKE_pbvh_bmesh_update_topology(ss->pbvh,
mode,
@@ -5787,15 +5822,11 @@ static void sculpt_topology_update(Sculpt *sd,
ss->cache->view_normal,
ss->cache->radius,
(brush->flag & BRUSH_FRONTFACE) != 0,
- (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
+ (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE),
+ symidx);
}
if (BKE_pbvh_type(ss->pbvh) == PBVH_TRIMESH) {
- int symidx = ss->cache->mirror_symmetry_pass + (ss->cache->radial_symmetry_pass * 8);
- if (symidx > 127) {
- symidx = 127;
- }
-
BKE_pbvh_trimesh_update_topology(ss->pbvh,
mode,
ss->cache->location,
@@ -6113,8 +6144,11 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
}
if (sculpt_brush_use_topology_rake(ss, brush)) {
- // bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
+#ifdef WITH_TRIMESH
trimesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
+#else
+ bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
+#endif
}
/* The cloth brush adds the gravity as a regular force and it is processed in the solver. */
@@ -6200,7 +6234,9 @@ static void sculpt_combine_proxies_task_cb(void *__restrict userdata,
if (use_orco) {
if (ss->bm) {
- copy_v3_v3(val, BM_log_original_vert_co(ss->bm_log, vd.bm_vert));
+ float *co = BM_ELEM_CD_GET_VOID_P(vd.bm_vert, ss->cd_origco_offset);
+ copy_v3_v3(val, co);
+ // copy_v3_v3(val, BM_log_original_vert_co(ss->bm_log, vd.bm_vert));
}
else if (ss->tm) {
copy_v3_v3(val, TM_log_original_vert_co(ss->tm_log, vd.tm_vert));
@@ -7447,7 +7483,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
/* Update the active vertex of the SculptSession. */
ss->active_vertex_index = srd.active_vertex_index;
- if (BKE_pbvh_type(ss->pbvh) != PBVH_TRIMESH) {
+ if (!ELEM(BKE_pbvh_type(ss->pbvh), PBVH_TRIMESH, PBVH_BMESH)) {
SCULPT_vertex_random_access_ensure(ss);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c
index 69c92f2baeb..871e445c108 100644
--- a/source/blender/editors/sculpt_paint/sculpt_detail.c
+++ b/source/blender/editors/sculpt_paint/sculpt_detail.c
@@ -126,7 +126,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_COORDS);
while (BKE_pbvh_bmesh_update_topology(
- ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, NULL, size, false, false)) {
+ ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, NULL, size, false, false, -1)) {
for (int i = 0; i < totnodes; i++) {
BKE_pbvh_node_mark_topology_update(nodes[i]);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
index 525b10b3661..ac48f928da9 100644
--- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
@@ -292,19 +292,68 @@ void SCULPT_dynamic_topology_disable(bContext *C, SculptUndoNode *unode)
}
#else
+void SCULPT_dyntopo_save_origverts(SculptSession *ss)
+{
+ BMIter iter;
+ BMVert *v;
+
+ BM_ITER_MESH (v, &iter, ss->bm, BM_VERTS_OF_MESH) {
+ float *co = BM_ELEM_CD_GET_VOID_P(v, ss->cd_origco_offset);
+ float *no = BM_ELEM_CD_GET_VOID_P(v, ss->cd_origno_offset);
+
+ copy_v3_v3(co, v->co);
+ copy_v3_v3(co, v->no);
+ }
+}
+
void SCULPT_dyntopo_node_layers_add(SculptSession *ss)
{
- int cd_node_layer_index;
+ int cd_node_layer_index, cd_face_node_layer_index;
char layer_id[] = "_dyntopo_node_id";
+ char origco_id[] = "_dyntopop_orig_co";
+ char origno_id[] = "_dyntopop_orig_no";
+
+ int cd_origco_index, cd_origno_index;
+
+ cd_origco_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_FLOAT3, origco_id);
+ if (cd_origco_index == -1) {
+ BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_FLOAT3, origco_id);
+ }
+
+ cd_origno_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_FLOAT3, origno_id);
+ if (cd_origno_index == -1) {
+ BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_FLOAT3, origno_id);
+ }
cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_INT32, layer_id);
if (cd_node_layer_index == -1) {
BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_INT32, layer_id);
- cd_node_layer_index = CustomData_get_named_layer_index(
- &ss->bm->vdata, CD_PROP_INT32, layer_id);
}
+ cd_face_node_layer_index = CustomData_get_named_layer_index(&ss->bm->pdata, CD_PROP_INT32, layer_id);
+ if (cd_face_node_layer_index == -1) {
+ BM_data_layer_add_named(ss->bm, &ss->bm->pdata, CD_PROP_INT32, layer_id);
+ }
+
+ //get indices again, as they might have changed after adding new layers
+ cd_origco_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_FLOAT3, origco_id);
+ cd_origno_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_FLOAT3, origno_id);
+ cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_INT32, layer_id);
+ cd_face_node_layer_index = CustomData_get_named_layer_index(&ss->bm->pdata, CD_PROP_INT32, layer_id);
+
+ ss->cd_origco_offset = CustomData_get_n_offset(
+ &ss->bm->vdata,
+ CD_PROP_FLOAT3,
+ cd_origco_index - CustomData_get_layer_index(&ss->bm->vdata, CD_PROP_FLOAT3));
+ ss->bm->vdata.layers[cd_origco_index].flag |= CD_FLAG_TEMPORARY;
+
+ ss->cd_origno_offset = CustomData_get_n_offset(
+ &ss->bm->vdata,
+ CD_PROP_FLOAT3,
+ cd_origno_index - CustomData_get_layer_index(&ss->bm->vdata, CD_PROP_FLOAT3));
+ ss->bm->vdata.layers[cd_origno_index].flag |= CD_FLAG_TEMPORARY;
+
ss->cd_vert_node_offset = CustomData_get_n_offset(
&ss->bm->vdata,
CD_PROP_INT32,
@@ -312,19 +361,14 @@ void SCULPT_dyntopo_node_layers_add(SculptSession *ss)
ss->bm->vdata.layers[cd_node_layer_index].flag |= CD_FLAG_TEMPORARY;
- cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->pdata, CD_PROP_INT32, layer_id);
- if (cd_node_layer_index == -1) {
- BM_data_layer_add_named(ss->bm, &ss->bm->pdata, CD_PROP_INT32, layer_id);
- cd_node_layer_index = CustomData_get_named_layer_index(
- &ss->bm->pdata, CD_PROP_INT32, layer_id);
- }
-
ss->cd_face_node_offset = CustomData_get_n_offset(
&ss->bm->pdata,
CD_PROP_INT32,
- cd_node_layer_index - CustomData_get_layer_index(&ss->bm->pdata, CD_PROP_INT32));
+ cd_face_node_layer_index - CustomData_get_layer_index(&ss->bm->pdata, CD_PROP_INT32));
+
+ ss->bm->pdata.layers[cd_face_node_layer_index].flag |= CD_FLAG_TEMPORARY;
- ss->bm->pdata.layers[cd_node_layer_index].flag |= CD_FLAG_TEMPORARY;
+ SCULPT_dyntopo_save_origverts(ss);
}
void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
@@ -514,7 +558,7 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(o
WM_cursor_wait(true);
- if (ss->tm) {
+ if (ss->tm || ss->bm) {
sculpt_dynamic_topology_disable_with_undo(bmain, depsgraph, scene, ob);
}
else {
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 3da89eadd75..d02077605b4 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -230,6 +230,7 @@ typedef struct {
const short *no;
float mask;
const float *col;
+ const short _no[3];
} SculptOrigVertData;
void SCULPT_orig_vert_data_init(SculptOrigVertData *data, Object *ob, PBVHNode *node);
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index dff5f225d5f..00f803a3243 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -515,7 +515,7 @@ void SCULPT_smooth(Sculpt *sd,
return;
}
- if (type != PBVH_TRIMESH) {
+ if (!ELEM(type, PBVH_TRIMESH, PBVH_BMESH)) {
SCULPT_vertex_random_access_ensure(ss);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index d298e569ffe..d73298204b3 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -1357,7 +1357,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
* 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_bmesh_update_origvert(ss->pbvh, vd.bm_vert);
}
BKE_pbvh_vertex_iter_end;
break;
@@ -1367,7 +1367,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
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_bmesh_update_origvert(ss->pbvh, vd.bm_vert);
}
BKE_pbvh_vertex_iter_end;
@@ -1447,7 +1447,7 @@ static SculptUndoNode *sculpt_undo_trimesh_push(Object *ob, PBVHNode *node, Scul
* 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_bmesh_update_origvert(ss->pbvh, vd.bm_vert);
}
BKE_pbvh_vertex_iter_end;
break;
@@ -1457,7 +1457,7 @@ static SculptUndoNode *sculpt_undo_trimesh_push(Object *ob, PBVHNode *node, Scul
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_bmesh_update_origvert(ss->pbvh, vd.bm_vert);
}
BKE_pbvh_vertex_iter_end;
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index eff9736e556..88389a463f2 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -67,6 +67,7 @@
#include "GPU_capabilities.h"
#include "trimesh.h"
+#include "bmesh.h"
#define MAX_INFO_NUM_LEN 16
@@ -354,8 +355,13 @@ static void stats_object_pose(Object *ob, SceneStats *stats)
static void stats_object_sculpt_dynamic_topology(Object *ob, SceneStats *stats)
{
+#ifdef WITH_TRIMESH
stats->totvert = ob->sculpt->tm->totvert;
stats->tottri = ob->sculpt->tm->tottri;
+#else
+ stats->totvert = ob->sculpt->bm->totvert;
+ stats->tottri = ob->sculpt->bm->totface;
+#endif
}
static bool stats_is_object_dynamic_topology_sculpt(Object *ob, const eObjectMode object_mode)
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index bd3a1a217f3..5f0a7772783 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -2036,7 +2036,7 @@ bool rna_GPencil_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
int rna_Object_use_dynamic_topology_sculpting_get(PointerRNA *ptr)
{
SculptSession *ss = ((Object *)ptr->owner_id)->sculpt;
- return (ss && ss->tm);
+ return (ss && (ss->tm || ss->bm));
}
#else