diff options
Diffstat (limited to 'source/blender/blenkernel/intern/pbvh.c')
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 143 |
1 files changed, 138 insertions, 5 deletions
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 3ed3c7badc3..5d307697208 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -17,8 +17,10 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "BKE_attribute.h" #include "BKE_ccg.h" #include "BKE_mesh.h" +#include "BKE_mesh_mapping.h" #include "BKE_paint.h" #include "BKE_pbvh.h" #include "BKE_subdiv_ccg.h" @@ -599,6 +601,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, /* Clear the bitmap so it can be used as an update tag later on. */ BLI_bitmap_set_all(pbvh->vert_bitmap, false, totvert); + + BKE_pbvh_update_active_vcol(pbvh, mesh); } void BKE_pbvh_build_grids(PBVH *pbvh, @@ -667,6 +671,9 @@ void BKE_pbvh_free(PBVH *pbvh) if (node->vert_indices) { MEM_freeN((void *)node->vert_indices); } + if (node->loop_indices) { + MEM_freeN(node->loop_indices); + } if (node->face_vert_indices) { MEM_freeN((void *)node->face_vert_indices); } @@ -1254,6 +1261,30 @@ static int pbvh_get_buffers_update_flags(PBVH *UNUSED(pbvh)) return update_flags; } +bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, AttributeDomain *r_attr) +{ + CustomDataLayer *layer = BKE_id_attributes_active_color_get((ID *)me); + + if (!layer || !ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) { + *r_layer = NULL; + *r_attr = ATTR_DOMAIN_NUM; + return false; + } + + AttributeDomain domain = BKE_id_attribute_domain((ID *)me, layer); + + if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) { + *r_layer = NULL; + *r_attr = ATTR_DOMAIN_NUM; + return false; + } + + *r_layer = layer; + *r_attr = domain; + + return true; +} + static void pbvh_update_draw_buffer_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) @@ -1304,18 +1335,25 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata, &pbvh->gridkey, update_flags); break; - case PBVH_FACES: + case PBVH_FACES: { + CustomDataLayer *layer = NULL; + AttributeDomain domain; + + BKE_pbvh_get_color_layer(pbvh->mesh, &layer, &domain); + GPU_pbvh_mesh_buffers_update(node->draw_buffers, pbvh->verts, pbvh->vert_normals, CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK), - CustomData_get_layer(pbvh->ldata, CD_MLOOPCOL), + layer ? layer->data : NULL, + layer ? layer->type : -1, + layer ? domain : ATTR_DOMAIN_AUTO, CustomData_get_layer(pbvh->pdata, CD_SCULPT_FACE_SETS), pbvh->face_sets_color_seed, pbvh->face_sets_color_default, - CustomData_get_layer(pbvh->vdata, CD_PROP_COLOR), update_flags); break; + } case PBVH_BMESH: GPU_pbvh_bmesh_buffers_update(node->draw_buffers, pbvh->bm, @@ -1442,7 +1480,9 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag) } if (flag & (PBVH_UpdateColor)) { - /* Do nothing */ + for (int i = 0; i < totnode; i++) { + nodes[i]->flag |= PBVH_UpdateRedraw | PBVH_UpdateDrawBuffers | PBVH_UpdateColor; + } } if (flag & (PBVH_UpdateVisibility)) { @@ -1820,6 +1860,22 @@ void BKE_pbvh_vert_mark_update(PBVH *pbvh, int index) BLI_BITMAP_ENABLE(pbvh->vert_bitmap, index); } +void BKE_pbvh_node_get_loops(PBVH *pbvh, + PBVHNode *node, + const int **r_loop_indices, + const MLoop **r_loops) +{ + BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); + + if (r_loop_indices) { + *r_loop_indices = node->loop_indices; + } + + if (r_loops) { + *r_loops = pbvh->mloop; + } +} + void BKE_pbvh_node_get_verts(PBVH *pbvh, PBVHNode *node, const int **r_vert_indices, @@ -2980,7 +3036,6 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m vi->vert_normals = pbvh->vert_normals; vi->vmask = CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK); - vi->vcol = CustomData_get_layer(pbvh->vdata, CD_PROP_COLOR); } } @@ -3072,3 +3127,81 @@ void BKE_pbvh_respect_hide_set(PBVH *pbvh, bool respect_hide) { pbvh->respect_hide = respect_hide; } +bool BKE_pbvh_is_drawing(const PBVH *pbvh) +{ + return pbvh->is_drawing; +} + +void BKE_pbvh_is_drawing_set(PBVH *pbvh, bool val) +{ + pbvh->is_drawing = val; +} + +void BKE_pbvh_node_num_loops(PBVH *pbvh, PBVHNode *node, int *r_totloop) +{ + UNUSED_VARS(pbvh); + BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); + + if (r_totloop) { + *r_totloop = node->loop_indices_num; + } +} + +void BKE_pbvh_update_active_vcol(PBVH *pbvh, const Mesh *mesh) +{ + BKE_pbvh_get_color_layer(mesh, &pbvh->color_layer, &pbvh->color_domain); +} + +void BKE_pbvh_pmap_set(PBVH *pbvh, const MeshElemMap *pmap) +{ + pbvh->pmap = pmap; +} + +void BKE_pbvh_ensure_node_loops(PBVH *pbvh) +{ + BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); + + int totloop = 0; + + /* Check if nodes already have loop indices. */ + for (int i = 0; i < pbvh->totnode; i++) { + PBVHNode *node = pbvh->nodes + i; + + if (!(node->flag & PBVH_Leaf)) { + continue; + } + + if (node->loop_indices) { + return; + } + + totloop += node->totprim * 3; + } + + BLI_bitmap *visit = BLI_BITMAP_NEW(totloop, __func__); + + /* Create loop indices from node loop triangles. */ + for (int i = 0; i < pbvh->totnode; i++) { + PBVHNode *node = pbvh->nodes + i; + + if (!(node->flag & PBVH_Leaf)) { + continue; + } + + node->loop_indices = MEM_malloc_arrayN(node->totprim * 3, sizeof(int), __func__); + node->loop_indices_num = 0; + + for (int j = 0; j < node->totprim; j++) { + const MLoopTri *mlt = pbvh->looptri + node->prim_indices[j]; + + for (int k = 0; k < 3; k++) { + if (!BLI_BITMAP_TEST(visit, mlt->tri[k])) { + node->loop_indices[node->loop_indices_num++] = mlt->tri[k]; + BLI_BITMAP_ENABLE(visit, mlt->tri[k]); + } + } + } + } + + MEM_SAFE_FREE(visit); +} |