Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/pbvh.c
| Show First 20 Lines • Show All 740 Lines • ▼ Show 20 Lines | void BKE_pbvh_build_mesh(PBVH *pbvh, | ||||
| pbvh->vert_normals = BKE_mesh_vertex_normals_for_write(mesh); | pbvh->vert_normals = BKE_mesh_vertex_normals_for_write(mesh); | ||||
| pbvh->hide_vert = (bool *)CustomData_get_layer_named(&mesh->vdata, CD_PROP_BOOL, ".hide_vert"); | pbvh->hide_vert = (bool *)CustomData_get_layer_named(&mesh->vdata, CD_PROP_BOOL, ".hide_vert"); | ||||
| pbvh->vert_bitmap = MEM_calloc_arrayN(totvert, sizeof(bool), "bvh->vert_bitmap"); | pbvh->vert_bitmap = MEM_calloc_arrayN(totvert, sizeof(bool), "bvh->vert_bitmap"); | ||||
| pbvh->totvert = totvert; | pbvh->totvert = totvert; | ||||
| pbvh->leaf_limit = LEAF_LIMIT; | pbvh->leaf_limit = LEAF_LIMIT; | ||||
| pbvh->vdata = vdata; | pbvh->vdata = vdata; | ||||
| pbvh->ldata = ldata; | pbvh->ldata = ldata; | ||||
| pbvh->pdata = pdata; | pbvh->pdata = pdata; | ||||
| pbvh->faces_num = mesh->totpoly; | |||||
| pbvh->face_sets_color_seed = mesh->face_sets_color_seed; | pbvh->face_sets_color_seed = mesh->face_sets_color_seed; | ||||
| pbvh->face_sets_color_default = mesh->face_sets_color_default; | pbvh->face_sets_color_default = mesh->face_sets_color_default; | ||||
| BB_reset(&cb); | BB_reset(&cb); | ||||
| /* For each face, store the AABB and the AABB centroid */ | /* For each face, store the AABB and the AABB centroid */ | ||||
| prim_bbc = MEM_mallocN(sizeof(BBC) * looptri_num, "prim_bbc"); | prim_bbc = MEM_mallocN(sizeof(BBC) * looptri_num, "prim_bbc"); | ||||
| ▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | void BKE_pbvh_build_grids(PBVH *pbvh, | ||||
| pbvh->header.type = PBVH_GRIDS; | pbvh->header.type = PBVH_GRIDS; | ||||
| pbvh->grids = grids; | pbvh->grids = grids; | ||||
| pbvh->gridfaces = gridfaces; | pbvh->gridfaces = gridfaces; | ||||
| pbvh->grid_flag_mats = flagmats; | pbvh->grid_flag_mats = flagmats; | ||||
| pbvh->totgrid = totgrid; | pbvh->totgrid = totgrid; | ||||
| pbvh->gridkey = *key; | pbvh->gridkey = *key; | ||||
| pbvh->grid_hidden = grid_hidden; | pbvh->grid_hidden = grid_hidden; | ||||
| pbvh->subdiv_ccg = subdiv_ccg; | pbvh->subdiv_ccg = subdiv_ccg; | ||||
| pbvh->faces_num = me->totpoly; | |||||
| /* Find maximum number of grids per face. */ | /* Find maximum number of grids per face. */ | ||||
| int max_grids = 1; | int max_grids = 1; | ||||
| const MPoly *mpoly = BKE_mesh_polys(me); | const MPoly *mpoly = BKE_mesh_polys(me); | ||||
| for (int i = 0; i < me->totpoly; i++) { | for (int i = 0; i < me->totpoly; i++) { | ||||
| max_grids = max_ii(max_grids, mpoly[i].totloop); | max_grids = max_ii(max_grids, mpoly[i].totloop); | ||||
| } | } | ||||
| /* Ensure leaf limit is at least 4 so there's room | /* Ensure leaf limit is at least 4 so there's room | ||||
| * to split at original face boundaries. | * to split at original face boundaries. | ||||
| * Fixes T102209. | * Fixes T102209. | ||||
| */ | */ | ||||
| pbvh->leaf_limit = max_ii(LEAF_LIMIT / (gridsize * gridsize), max_grids); | pbvh->leaf_limit = max_ii(LEAF_LIMIT / (gridsize * gridsize), max_grids); | ||||
| /* We need the base mesh attribute layout for PBVH draw. */ | /* We need the base mesh attribute layout for PBVH draw. */ | ||||
| pbvh->vdata = &me->vdata; | pbvh->vdata = &me->vdata; | ||||
| pbvh->ldata = &me->ldata; | pbvh->ldata = &me->ldata; | ||||
| pbvh->pdata = &me->pdata; | pbvh->pdata = &me->pdata; | ||||
| pbvh->mpoly = BKE_mesh_polys(me); | |||||
| pbvh->mloop = BKE_mesh_loops(me); | |||||
| /* We also need the base mesh for PBVH draw. */ | /* We also need the base mesh for PBVH draw. */ | ||||
| pbvh->mesh = me; | pbvh->mesh = me; | ||||
| BB cb; | BB cb; | ||||
| BB_reset(&cb); | BB_reset(&cb); | ||||
| /* For each grid, store the AABB and the AABB centroid */ | /* For each grid, store the AABB and the AABB centroid */ | ||||
| BBC *prim_bbc = MEM_mallocN(sizeof(BBC) * totgrid, "prim_bbc"); | BBC *prim_bbc = MEM_mallocN(sizeof(BBC) * totgrid, "prim_bbc"); | ||||
| ▲ Show 20 Lines • Show All 1,146 Lines • ▼ Show 20 Lines | void BKE_pbvh_node_mark_update_mask(PBVHNode *node) | ||||
| node->flag |= PBVH_UpdateMask | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; | node->flag |= PBVH_UpdateMask | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; | ||||
| } | } | ||||
| void BKE_pbvh_node_mark_update_color(PBVHNode *node) | void BKE_pbvh_node_mark_update_color(PBVHNode *node) | ||||
| { | { | ||||
| node->flag |= PBVH_UpdateColor | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; | node->flag |= PBVH_UpdateColor | PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; | ||||
| } | } | ||||
| void BKE_pbvh_node_mark_update_face_sets(PBVHNode *node) | |||||
| { | |||||
| node->flag |= PBVH_UpdateDrawBuffers | PBVH_UpdateRedraw; | |||||
| } | |||||
| void BKE_pbvh_mark_rebuild_pixels(PBVH *pbvh) | void BKE_pbvh_mark_rebuild_pixels(PBVH *pbvh) | ||||
| { | { | ||||
| for (int n = 0; n < pbvh->totnode; n++) { | for (int n = 0; n < pbvh->totnode; n++) { | ||||
| PBVHNode *node = &pbvh->nodes[n]; | PBVHNode *node = &pbvh->nodes[n]; | ||||
| if (node->flag & PBVH_Leaf) { | if (node->flag & PBVH_Leaf) { | ||||
| node->flag |= PBVH_RebuildPixels; | node->flag |= PBVH_RebuildPixels; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | if (r_loop_indices) { | ||||
| *r_loop_indices = node->loop_indices; | *r_loop_indices = node->loop_indices; | ||||
| } | } | ||||
| if (r_loops) { | if (r_loops) { | ||||
| *r_loops = pbvh->mloop; | *r_loops = pbvh->mloop; | ||||
| } | } | ||||
| } | } | ||||
| int BKE_pbvh_num_faces(const PBVH *pbvh) | |||||
| { | |||||
| switch (pbvh->header.type) { | |||||
| case PBVH_GRIDS: | |||||
| case PBVH_FACES: | |||||
| return pbvh->faces_num; | |||||
| case PBVH_BMESH: | |||||
| return pbvh->header.bm->totface; | |||||
| } | |||||
| BLI_assert_unreachable(); | |||||
| return 0; | |||||
HooglyBoogly: Tiny thing, but IMO this white space (new lines) isn't helpful here | |||||
| } | |||||
| void BKE_pbvh_node_get_verts(PBVH *pbvh, | void BKE_pbvh_node_get_verts(PBVH *pbvh, | ||||
| PBVHNode *node, | PBVHNode *node, | ||||
| const int **r_vert_indices, | const int **r_vert_indices, | ||||
| MVert **r_verts) | MVert **r_verts) | ||||
| { | { | ||||
| if (r_vert_indices) { | if (r_vert_indices) { | ||||
| *r_vert_indices = node->vert_indices; | *r_vert_indices = node->vert_indices; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,476 Lines • ▼ Show 20 Lines | case PBVH_GRIDS: { | ||||
| } | } | ||||
| BKE_mesh_flush_hidden_from_polys(mesh); | BKE_mesh_flush_hidden_from_polys(mesh); | ||||
| BKE_pbvh_update_hide_attributes_from_mesh(pbvh); | BKE_pbvh_update_hide_attributes_from_mesh(pbvh); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void pbvh_face_iter_verts_reserve(PBVHFaceIter *fd, int verts_num) | |||||
| { | |||||
| if (verts_num >= fd->verts_size_) { | |||||
| fd->verts_size_ = (verts_num + 1) << 2; | |||||
| if (fd->verts != fd->verts_reserved_) { | |||||
| MEM_SAFE_FREE(fd->verts); | |||||
| } | |||||
| fd->verts = MEM_malloc_arrayN(fd->verts_size_, sizeof(void *), __func__); | |||||
| } | |||||
| fd->verts_num = verts_num; | |||||
| } | |||||
| BLI_INLINE int face_iter_prim_to_face(PBVHFaceIter *fd, int prim_index) | |||||
| { | |||||
| if (fd->subdiv_ccg_) { | |||||
| return BKE_subdiv_ccg_grid_to_face_index(fd->subdiv_ccg_, prim_index); | |||||
| } | |||||
| else { | |||||
| return fd->looptri_[prim_index].poly; | |||||
| } | |||||
| } | |||||
| void pbvh_face_iter_step(PBVHFaceIter *fd, bool do_step) | |||||
| { | |||||
| if (do_step) { | |||||
| fd->i++; | |||||
| } | |||||
| switch (fd->pbvh_type_) { | |||||
| case PBVH_BMESH: { | |||||
| if (do_step) { | |||||
| BLI_gsetIterator_step(&fd->bm_faces_iter_); | |||||
| if (BLI_gsetIterator_done(&fd->bm_faces_iter_)) { | |||||
| return; | |||||
| } | |||||
| } | |||||
| BMFace *f = (BMFace *)BLI_gsetIterator_getKey(&fd->bm_faces_iter_); | |||||
| fd->face.i = (intptr_t)f; | |||||
| fd->index = f->head.index; | |||||
| if (fd->cd_face_set_ != -1) { | |||||
| fd->face_set = (int *)BM_ELEM_CD_GET_VOID_P(f, fd->cd_face_set_); | |||||
| } | |||||
| if (fd->cd_hide_poly_ != -1) { | |||||
| fd->hide = (bool *)BM_ELEM_CD_GET_VOID_P(f, fd->cd_hide_poly_); | |||||
| } | |||||
| pbvh_face_iter_verts_reserve(fd, f->len); | |||||
| int vertex_i = 0; | |||||
| BMLoop *l = f->l_first; | |||||
| do { | |||||
| fd->verts[vertex_i++].i = (intptr_t)l->v; | |||||
| } while ((l = l->next) != f->l_first); | |||||
| break; | |||||
| } | |||||
| case PBVH_GRIDS: | |||||
| case PBVH_FACES: { | |||||
| int face_index = 0; | |||||
| if (do_step) { | |||||
| fd->prim_index_++; | |||||
| while (fd->prim_index_ < fd->node_->totprim) { | |||||
| face_index = face_iter_prim_to_face(fd, fd->node_->prim_indices[fd->prim_index_]); | |||||
| if (face_index != fd->last_face_index_) { | |||||
| break; | |||||
| } | |||||
| fd->prim_index_++; | |||||
| } | |||||
| } | |||||
| else if (fd->prim_index_ < fd->node_->totprim) { | |||||
| face_index = face_iter_prim_to_face(fd, fd->node_->prim_indices[fd->prim_index_]); | |||||
| } | |||||
| if (fd->prim_index_ >= fd->node_->totprim) { | |||||
| return; | |||||
| } | |||||
| fd->last_face_index_ = face_index; | |||||
| const MPoly *mp = fd->mpoly_ + face_index; | |||||
| fd->face.i = fd->index = face_index; | |||||
| if (fd->face_sets_) { | |||||
| fd->face_set = fd->face_sets_ + face_index; | |||||
| } | |||||
| if (fd->hide_poly_) { | |||||
| fd->hide = fd->hide_poly_ + face_index; | |||||
| } | |||||
| pbvh_face_iter_verts_reserve(fd, mp->totloop); | |||||
| const MLoop *ml = fd->mloop_ + mp->loopstart; | |||||
| for (int i = 0; i < mp->totloop; i++, ml++) { | |||||
| if (fd->pbvh_type_ == PBVH_GRIDS) { | |||||
| /* Grid corners. */ | |||||
| fd->verts[i].i = mp->loopstart + i; | |||||
| } | |||||
| else { | |||||
| fd->verts[i].i = ml->v; | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| void BKE_pbvh_face_iter_step(PBVHFaceIter *fd) | |||||
| { | |||||
| pbvh_face_iter_step(fd, true); | |||||
| } | |||||
| void BKE_pbvh_face_iter_init(PBVH *pbvh, PBVHNode *node, PBVHFaceIter *fd) | |||||
| { | |||||
| memset(fd, 0, sizeof(*fd)); | |||||
| fd->node_ = node; | |||||
| fd->pbvh_type_ = BKE_pbvh_type(pbvh); | |||||
| fd->verts = fd->verts_reserved_; | |||||
| fd->verts_size_ = PBVH_FACE_ITER_VERTS_RESERVED; | |||||
| switch (BKE_pbvh_type(pbvh)) { | |||||
| case PBVH_GRIDS: | |||||
| fd->subdiv_ccg_ = pbvh->subdiv_ccg; | |||||
| case PBVH_FACES: | |||||
| fd->mpoly_ = pbvh->mpoly; | |||||
| fd->mloop_ = pbvh->mloop; | |||||
| fd->looptri_ = pbvh->looptri; | |||||
| fd->hide_poly_ = pbvh->hide_poly; | |||||
| fd->face_sets_ = pbvh->face_sets; | |||||
| fd->last_face_index_ = -1; | |||||
| break; | |||||
| case PBVH_BMESH: | |||||
| fd->bm = pbvh->header.bm; | |||||
| fd->cd_face_set_ = CustomData_get_offset_named( | |||||
| &pbvh->header.bm->pdata, CD_PROP_INT32, ".sculpt_face_set"); | |||||
| fd->cd_hide_poly_ = CustomData_get_offset_named( | |||||
| &pbvh->header.bm->pdata, CD_PROP_INT32, ".hide_poly"); | |||||
| BLI_gsetIterator_init(&fd->bm_faces_iter_, node->bm_faces); | |||||
| break; | |||||
| } | |||||
| if (!BKE_pbvh_face_iter_done(fd)) { | |||||
| pbvh_face_iter_step(fd, false); | |||||
| } | |||||
| } | |||||
| void BKE_pbvh_face_iter_finish(PBVHFaceIter *fd) | |||||
| { | |||||
| if (fd->verts != fd->verts_reserved_) { | |||||
| MEM_SAFE_FREE(fd->verts); | |||||
| } | |||||
| } | |||||
| bool BKE_pbvh_face_iter_done(PBVHFaceIter *fd) | |||||
| { | |||||
| switch (fd->pbvh_type_) { | |||||
| case PBVH_FACES: | |||||
| case PBVH_GRIDS: | |||||
| return fd->prim_index_ >= fd->node_->totprim; | |||||
| case PBVH_BMESH: | |||||
| return BLI_gsetIterator_done(&fd->bm_faces_iter_); | |||||
| default: | |||||
| BLI_assert_unreachable(); | |||||
| return true; | |||||
| } | |||||
| } | |||||
Tiny thing, but IMO this white space (new lines) isn't helpful here