diff options
author | Joseph Eagar <joeedh@gmail.com> | 2020-10-24 03:19:47 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2020-10-24 03:19:47 +0300 |
commit | 6c9c7f14ec87c62ff5eca5e200640b4bd6ccdedf (patch) | |
tree | f0abb70051b1801b932e037ed74969bb9af38fdd | |
parent | 8f6326d494fad50305e406557dee7d2d2cb44dd3 (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.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_pbvh.h | 14 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_bmesh.c | 83 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_intern.h | 4 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 86 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_detail.c | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_dyntopo.c | 70 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_smooth.c | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_undo.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_info/info_stats.c | 6 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object.c | 2 |
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 |