Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/pbvh.c
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| if (pbvh->respect_hide == false) { | if (pbvh->respect_hide == false) { | ||||
| has_visible = true; | has_visible = true; | ||||
| } | } | ||||
| for (int i = 0; i < totface; i++) { | for (int i = 0; i < totface; i++) { | ||||
| const MLoopTri *lt = &pbvh->looptri[node->prim_indices[i]]; | const MLoopTri *lt = &pbvh->looptri[node->prim_indices[i]]; | ||||
| for (int j = 0; j < 3; j++) { | for (int j = 0; j < 3; j++) { | ||||
| face_vert_indices[i][j] = map_insert_vert( | face_vert_indices[i][j] = map_insert_vert( | ||||
| pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->mloop[lt->tri[j]].v); | pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->corner_verts[lt->tri[j]]); | ||||
| } | } | ||||
| if (has_visible == false) { | if (has_visible == false) { | ||||
| if (!paint_is_face_hidden(lt, pbvh->hide_poly)) { | if (!paint_is_face_hidden(lt, pbvh->hide_poly)) { | ||||
| has_visible = true; | has_visible = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| args->node = node; | args->node = node; | ||||
| BKE_pbvh_node_num_verts(pbvh, node, NULL, &args->node_verts_num); | BKE_pbvh_node_num_verts(pbvh, node, NULL, &args->node_verts_num); | ||||
| args->grid_hidden = pbvh->grid_hidden; | args->grid_hidden = pbvh->grid_hidden; | ||||
| args->face_sets_color_default = pbvh->face_sets_color_default; | args->face_sets_color_default = pbvh->face_sets_color_default; | ||||
| args->face_sets_color_seed = pbvh->face_sets_color_seed; | args->face_sets_color_seed = pbvh->face_sets_color_seed; | ||||
| args->vert_positions = pbvh->vert_positions; | args->vert_positions = pbvh->vert_positions; | ||||
| args->mloop = pbvh->mloop; | args->corner_verts = pbvh->corner_verts; | ||||
| args->corner_edges = pbvh->mesh ? BKE_mesh_corner_edges(pbvh->mesh) : NULL; | |||||
| args->mpoly = pbvh->mpoly; | args->mpoly = pbvh->mpoly; | ||||
| args->mlooptri = pbvh->looptri; | args->mlooptri = pbvh->looptri; | ||||
| if (ELEM(pbvh->header.type, PBVH_FACES, PBVH_GRIDS)) { | if (ELEM(pbvh->header.type, PBVH_FACES, PBVH_GRIDS)) { | ||||
| args->hide_poly = pbvh->pdata ? | args->hide_poly = pbvh->pdata ? | ||||
| CustomData_get_layer_named(pbvh->pdata, CD_PROP_BOOL, ".hide_poly") : | CustomData_get_layer_named(pbvh->pdata, CD_PROP_BOOL, ".hide_poly") : | ||||
| NULL; | NULL; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| MEM_SAFE_FREE(facemap); | MEM_SAFE_FREE(facemap); | ||||
| } | } | ||||
| #endif | #endif | ||||
| void BKE_pbvh_build_mesh(PBVH *pbvh, | void BKE_pbvh_build_mesh(PBVH *pbvh, | ||||
| Mesh *mesh, | Mesh *mesh, | ||||
| const MPoly *mpoly, | const MPoly *mpoly, | ||||
| const MLoop *mloop, | const int *corner_verts, | ||||
| float (*vert_positions)[3], | float (*vert_positions)[3], | ||||
| int totvert, | int totvert, | ||||
| struct CustomData *vdata, | struct CustomData *vdata, | ||||
| struct CustomData *ldata, | struct CustomData *ldata, | ||||
| struct CustomData *pdata, | struct CustomData *pdata, | ||||
| const MLoopTri *looptri, | const MLoopTri *looptri, | ||||
| int looptri_num) | int looptri_num) | ||||
| { | { | ||||
| BBC *prim_bbc = NULL; | BBC *prim_bbc = NULL; | ||||
| BB cb; | BB cb; | ||||
| pbvh->mesh = mesh; | pbvh->mesh = mesh; | ||||
| pbvh->header.type = PBVH_FACES; | pbvh->header.type = PBVH_FACES; | ||||
| pbvh->mpoly = mpoly; | pbvh->mpoly = mpoly; | ||||
| pbvh->hide_poly = (bool *)CustomData_get_layer_named_for_write( | pbvh->hide_poly = (bool *)CustomData_get_layer_named_for_write( | ||||
| &mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly); | &mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly); | ||||
| pbvh->material_indices = (const int *)CustomData_get_layer_named( | pbvh->material_indices = (const int *)CustomData_get_layer_named( | ||||
| &mesh->pdata, CD_PROP_INT32, "material_index"); | &mesh->pdata, CD_PROP_INT32, "material_index"); | ||||
| pbvh->mloop = mloop; | pbvh->corner_verts = corner_verts; | ||||
| pbvh->looptri = looptri; | pbvh->looptri = looptri; | ||||
| pbvh->vert_positions = vert_positions; | pbvh->vert_positions = vert_positions; | ||||
| BKE_mesh_vertex_normals_ensure(mesh); | BKE_mesh_vertex_normals_ensure(mesh); | ||||
| 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_for_write( | pbvh->hide_vert = (bool *)CustomData_get_layer_named_for_write( | ||||
| &mesh->vdata, CD_PROP_BOOL, ".hide_vert", mesh->totvert); | &mesh->vdata, CD_PROP_BOOL, ".hide_vert", mesh->totvert); | ||||
| 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; | ||||
| Show All 23 Lines | |||||
| for (int i = 0; i < looptri_num; i++) { | for (int i = 0; i < looptri_num; i++) { | ||||
| const MLoopTri *lt = &looptri[i]; | const MLoopTri *lt = &looptri[i]; | ||||
| const int sides = 3; | const int sides = 3; | ||||
| BBC *bbc = prim_bbc + i; | BBC *bbc = prim_bbc + i; | ||||
| BB_reset((BB *)bbc); | BB_reset((BB *)bbc); | ||||
| for (int j = 0; j < sides; j++) { | for (int j = 0; j < sides; j++) { | ||||
| BB_expand((BB *)bbc, vert_positions[pbvh->mloop[lt->tri[j]].v]); | BB_expand((BB *)bbc, vert_positions[pbvh->corner_verts[lt->tri[j]]]); | ||||
| } | } | ||||
| BBC_update_centroid(bbc); | BBC_update_centroid(bbc); | ||||
| BB_expand(&cb, bbc->bcentroid); | BB_expand(&cb, bbc->bcentroid); | ||||
| } | } | ||||
| if (looptri_num) { | if (looptri_num) { | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | |||||
| 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->mpoly = BKE_mesh_polys(me); | ||||
| pbvh->mloop = BKE_mesh_loops(me); | pbvh->corner_verts = BKE_mesh_corner_verts(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 */ | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| float fn[3]; | float fn[3]; | ||||
| const int *faces = node->prim_indices; | const int *faces = node->prim_indices; | ||||
| const int totface = node->totprim; | const int totface = node->totprim; | ||||
| for (int i = 0; i < totface; i++) { | for (int i = 0; i < totface; i++) { | ||||
| const MLoopTri *lt = &pbvh->looptri[faces[i]]; | const MLoopTri *lt = &pbvh->looptri[faces[i]]; | ||||
| const uint vtri[3] = { | const uint vtri[3] = { | ||||
| pbvh->mloop[lt->tri[0]].v, | pbvh->corner_verts[lt->tri[0]], | ||||
| pbvh->mloop[lt->tri[1]].v, | pbvh->corner_verts[lt->tri[1]], | ||||
| pbvh->mloop[lt->tri[2]].v, | pbvh->corner_verts[lt->tri[2]], | ||||
| }; | }; | ||||
| const int sides = 3; | const int sides = 3; | ||||
| /* Face normal and mask */ | /* Face normal and mask */ | ||||
| if (lt->poly != mpoly_prev) { | if (lt->poly != mpoly_prev) { | ||||
| const MPoly *mp = &pbvh->mpoly[lt->poly]; | const MPoly *mp = &pbvh->mpoly[lt->poly]; | ||||
| BKE_mesh_calc_poly_normal(mp, &pbvh->mloop[mp->loopstart], pbvh->vert_positions, fn); | BKE_mesh_calc_poly_normal( | ||||
| mp, &pbvh->corner_verts[mp->loopstart], pbvh->vert_positions, fn); | |||||
| mpoly_prev = lt->poly; | mpoly_prev = lt->poly; | ||||
| } | } | ||||
| for (int j = sides; j--;) { | for (int j = sides; j--;) { | ||||
| const int v = vtri[j]; | const int v = vtri[j]; | ||||
| if (pbvh->vert_bitmap[v]) { | if (pbvh->vert_bitmap[v]) { | ||||
| /* NOTE: This avoids `lock, add_v3_v3, unlock` | /* NOTE: This avoids `lock, add_v3_v3, unlock` | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| BLI_assert(pbvh->header.type == PBVH_FACES); | BLI_assert(pbvh->header.type == PBVH_FACES); | ||||
| pbvh->vert_bitmap[vertex.i] = true; | pbvh->vert_bitmap[vertex.i] = true; | ||||
| } | } | ||||
| void BKE_pbvh_node_get_loops(PBVH *pbvh, | void BKE_pbvh_node_get_loops(PBVH *pbvh, | ||||
| PBVHNode *node, | PBVHNode *node, | ||||
| const int **r_loop_indices, | const int **r_loop_indices, | ||||
| const MLoop **r_loops) | const int **r_corner_verts) | ||||
| { | { | ||||
| BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); | BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); | ||||
| if (r_loop_indices) { | if (r_loop_indices) { | ||||
| *r_loop_indices = node->loop_indices; | *r_loop_indices = node->loop_indices; | ||||
| } | } | ||||
| if (r_loops) { | if (r_corner_verts) { | ||||
| *r_loops = pbvh->mloop; | *r_corner_verts = pbvh->corner_verts; | ||||
| } | } | ||||
| } | } | ||||
| int BKE_pbvh_num_faces(const PBVH *pbvh) | int BKE_pbvh_num_faces(const PBVH *pbvh) | ||||
| { | { | ||||
| switch (pbvh->header.type) { | switch (pbvh->header.type) { | ||||
| case PBVH_GRIDS: | case PBVH_GRIDS: | ||||
| case PBVH_FACES: | case PBVH_FACES: | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| const float ray_normal[3], | const float ray_normal[3], | ||||
| struct IsectRayPrecalc *isect_precalc, | struct IsectRayPrecalc *isect_precalc, | ||||
| float *depth, | float *depth, | ||||
| PBVHVertRef *r_active_vertex, | PBVHVertRef *r_active_vertex, | ||||
| int *r_active_face_index, | int *r_active_face_index, | ||||
| float *r_face_normal) | float *r_face_normal) | ||||
| { | { | ||||
| const float(*positions)[3] = pbvh->vert_positions; | const float(*positions)[3] = pbvh->vert_positions; | ||||
| const MLoop *mloop = pbvh->mloop; | const int *corner_verts = pbvh->corner_verts; | ||||
| const int *faces = node->prim_indices; | const int *faces = node->prim_indices; | ||||
| int totface = node->totprim; | int totface = node->totprim; | ||||
| bool hit = false; | bool hit = false; | ||||
| float nearest_vertex_co[3] = {0.0f}; | float nearest_vertex_co[3] = {0.0f}; | ||||
| for (int i = 0; i < totface; i++) { | for (int i = 0; i < totface; i++) { | ||||
| const MLoopTri *lt = &pbvh->looptri[faces[i]]; | const MLoopTri *lt = &pbvh->looptri[faces[i]]; | ||||
| const int *face_verts = node->face_vert_indices[i]; | const int *face_verts = node->face_vert_indices[i]; | ||||
| if (pbvh->respect_hide && paint_is_face_hidden(lt, pbvh->hide_poly)) { | if (pbvh->respect_hide && paint_is_face_hidden(lt, pbvh->hide_poly)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| const float *co[3]; | const float *co[3]; | ||||
| if (origco) { | if (origco) { | ||||
| /* Intersect with backed up original coordinates. */ | /* Intersect with backed up original coordinates. */ | ||||
| co[0] = origco[face_verts[0]]; | co[0] = origco[face_verts[0]]; | ||||
| co[1] = origco[face_verts[1]]; | co[1] = origco[face_verts[1]]; | ||||
| co[2] = origco[face_verts[2]]; | co[2] = origco[face_verts[2]]; | ||||
| } | } | ||||
| else { | else { | ||||
| /* intersect with current coordinates */ | /* intersect with current coordinates */ | ||||
| co[0] = positions[mloop[lt->tri[0]].v]; | co[0] = positions[corner_verts[lt->tri[0]]]; | ||||
| co[1] = positions[mloop[lt->tri[1]].v]; | co[1] = positions[corner_verts[lt->tri[1]]]; | ||||
| co[2] = positions[mloop[lt->tri[2]].v]; | co[2] = positions[corner_verts[lt->tri[2]]]; | ||||
| } | } | ||||
| if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) { | if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) { | ||||
| hit = true; | hit = true; | ||||
| if (r_face_normal) { | if (r_face_normal) { | ||||
| normal_tri_v3(r_face_normal, co[0], co[1], co[2]); | normal_tri_v3(r_face_normal, co[0], co[1], co[2]); | ||||
| } | } | ||||
| if (r_active_vertex) { | if (r_active_vertex) { | ||||
| float location[3] = {0.0f}; | float location[3] = {0.0f}; | ||||
| madd_v3_v3v3fl(location, ray_start, ray_normal, *depth); | madd_v3_v3v3fl(location, ray_start, ray_normal, *depth); | ||||
| for (int j = 0; j < 3; j++) { | for (int j = 0; j < 3; j++) { | ||||
| /* Always assign nearest_vertex_co in the first iteration to avoid comparison against | /* Always assign nearest_vertex_co in the first iteration to avoid comparison against | ||||
| * uninitialized values. This stores the closest vertex in the current intersecting | * uninitialized values. This stores the closest vertex in the current intersecting | ||||
| * triangle. */ | * triangle. */ | ||||
| if (j == 0 || | if (j == 0 || | ||||
| len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co)) { | len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co)) { | ||||
| copy_v3_v3(nearest_vertex_co, co[j]); | copy_v3_v3(nearest_vertex_co, co[j]); | ||||
| r_active_vertex->i = mloop[lt->tri[j]].v; | r_active_vertex->i = corner_verts[lt->tri[j]]; | ||||
| *r_active_face_index = lt->poly; | *r_active_face_index = lt->poly; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return hit; | return hit; | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| const PBVHNode *node, | const PBVHNode *node, | ||||
| float (*origco)[3], | float (*origco)[3], | ||||
| const float ray_start[3], | const float ray_start[3], | ||||
| const float ray_normal[3], | const float ray_normal[3], | ||||
| float *depth, | float *depth, | ||||
| float *dist_sq) | float *dist_sq) | ||||
| { | { | ||||
| const float(*positions)[3] = pbvh->vert_positions; | const float(*positions)[3] = pbvh->vert_positions; | ||||
| const MLoop *mloop = pbvh->mloop; | const int *corner_verts = pbvh->corner_verts; | ||||
| const int *faces = node->prim_indices; | const int *faces = node->prim_indices; | ||||
| int i, totface = node->totprim; | int i, totface = node->totprim; | ||||
| bool hit = false; | bool hit = false; | ||||
| for (i = 0; i < totface; i++) { | for (i = 0; i < totface; i++) { | ||||
| const MLoopTri *lt = &pbvh->looptri[faces[i]]; | const MLoopTri *lt = &pbvh->looptri[faces[i]]; | ||||
| const int *face_verts = node->face_vert_indices[i]; | const int *face_verts = node->face_vert_indices[i]; | ||||
| Show All 10 Lines | |||||
| origco[face_verts[2]], | origco[face_verts[2]], | ||||
| depth, | depth, | ||||
| dist_sq); | dist_sq); | ||||
| } | } | ||||
| else { | else { | ||||
| /* intersect with current coordinates */ | /* intersect with current coordinates */ | ||||
| hit |= ray_face_nearest_tri(ray_start, | hit |= ray_face_nearest_tri(ray_start, | ||||
| ray_normal, | ray_normal, | ||||
| positions[mloop[lt->tri[0]].v], | positions[corner_verts[lt->tri[0]]], | ||||
| positions[mloop[lt->tri[1]].v], | positions[corner_verts[lt->tri[1]]], | ||||
| positions[mloop[lt->tri[2]].v], | positions[corner_verts[lt->tri[2]]], | ||||
| depth, | depth, | ||||
| dist_sq); | dist_sq); | ||||
| } | } | ||||
| } | } | ||||
| return hit; | return hit; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| fd->face_set = fd->face_sets_ + face_index; | fd->face_set = fd->face_sets_ + face_index; | ||||
| } | } | ||||
| if (fd->hide_poly_) { | if (fd->hide_poly_) { | ||||
| fd->hide = fd->hide_poly_ + face_index; | fd->hide = fd->hide_poly_ + face_index; | ||||
| } | } | ||||
| pbvh_face_iter_verts_reserve(fd, mp->totloop); | pbvh_face_iter_verts_reserve(fd, mp->totloop); | ||||
| const MLoop *ml = fd->mloop_ + mp->loopstart; | |||||
| const int grid_area = fd->subdiv_key_.grid_area; | const int grid_area = fd->subdiv_key_.grid_area; | ||||
| for (int i = 0; i < mp->totloop; i++, ml++) { | for (int i = 0; i < mp->totloop; i++) { | ||||
| if (fd->pbvh_type_ == PBVH_GRIDS) { | if (fd->pbvh_type_ == PBVH_GRIDS) { | ||||
| /* Grid corners. */ | /* Grid corners. */ | ||||
| fd->verts[i].i = (mp->loopstart + i) * grid_area + grid_area - 1; | fd->verts[i].i = (mp->loopstart + i) * grid_area + grid_area - 1; | ||||
| } | } | ||||
| else { | else { | ||||
| fd->verts[i].i = ml->v; | fd->verts[i].i = fd->corner_verts_[mp->loopstart + i]; | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void BKE_pbvh_face_iter_step(PBVHFaceIter *fd) | void BKE_pbvh_face_iter_step(PBVHFaceIter *fd) | ||||
| Show All 12 Lines | |||||
| switch (BKE_pbvh_type(pbvh)) { | switch (BKE_pbvh_type(pbvh)) { | ||||
| case PBVH_GRIDS: | case PBVH_GRIDS: | ||||
| fd->subdiv_ccg_ = pbvh->subdiv_ccg; | fd->subdiv_ccg_ = pbvh->subdiv_ccg; | ||||
| fd->subdiv_key_ = pbvh->gridkey; | fd->subdiv_key_ = pbvh->gridkey; | ||||
| ATTR_FALLTHROUGH; | ATTR_FALLTHROUGH; | ||||
| case PBVH_FACES: | case PBVH_FACES: | ||||
| fd->mpoly_ = pbvh->mpoly; | fd->mpoly_ = pbvh->mpoly; | ||||
| fd->mloop_ = pbvh->mloop; | fd->corner_verts_ = pbvh->corner_verts; | ||||
| fd->looptri_ = pbvh->looptri; | fd->looptri_ = pbvh->looptri; | ||||
| fd->hide_poly_ = pbvh->hide_poly; | fd->hide_poly_ = pbvh->hide_poly; | ||||
| fd->face_sets_ = pbvh->face_sets; | fd->face_sets_ = pbvh->face_sets; | ||||
| fd->last_face_index_ = -1; | fd->last_face_index_ = -1; | ||||
| break; | break; | ||||
| case PBVH_BMESH: | case PBVH_BMESH: | ||||
| fd->bm = pbvh->header.bm; | fd->bm = pbvh->header.bm; | ||||
| ▲ Show 20 Lines • Show All 92 Lines • Show Last 20 Lines | |||||