diff options
Diffstat (limited to 'source/blender/blenkernel/intern/pbvh.c')
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 132 |
1 files changed, 75 insertions, 57 deletions
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index edeba9fd7e6..6e379f293d7 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -168,7 +168,7 @@ static void update_node_vb(PBVH *bvh, PBVHNode *node) // BB_expand(&node->vb, co); //} -static int face_materials_match(const MFace *f1, const MFace *f2) +static int face_materials_match(const MPoly *f1, const MPoly *f2) { return ((f1->flag & ME_SMOOTH) == (f2->flag & ME_SMOOTH) && (f1->mat_nr == f2->mat_nr)); @@ -201,21 +201,22 @@ static int partition_indices(int *prim_indices, int lo, int hi, int axis, /* Returns the index of the first element on the right of the partition */ static int partition_indices_material(PBVH *bvh, int lo, int hi) { - const MFace *faces = bvh->faces; + const MPoly *mpoly = bvh->mpoly; + const MLoopTri *looptri = bvh->looptri; const DMFlagMat *flagmats = bvh->grid_flag_mats; const int *indices = bvh->prim_indices; const void *first; int i = lo, j = hi; - if (bvh->faces) - first = &faces[bvh->prim_indices[lo]]; + if (bvh->looptri) + first = &looptri[bvh->prim_indices[lo]]; else first = &flagmats[bvh->prim_indices[lo]]; for (;; ) { - if (bvh->faces) { - for (; face_materials_match(first, &faces[indices[i]]); i++) ; - for (; !face_materials_match(first, &faces[indices[j]]); j--) ; + if (bvh->looptri) { + for (; face_materials_match(first, &mpoly[looptri[indices[i]].poly]); i++) ; + for (; !face_materials_match(first, &mpoly[looptri[indices[j]].poly]); j--) ; } else { for (; grid_materials_match(first, &flagmats[indices[i]]); i++) ; @@ -295,17 +296,18 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node) node->face_vert_indices = (const int (*)[4])face_vert_indices; for (i = 0; i < totface; ++i) { - const MFace *f = &bvh->faces[node->prim_indices[i]]; - int sides = f->v4 ? 4 : 3; + const MLoopTri *lt = &bvh->looptri[node->prim_indices[i]]; + const int sides = 3; for (j = 0; j < sides; ++j) { face_vert_indices[i][j] = map_insert_vert(bvh, map, &node->face_verts, - &node->uniq_verts, (&f->v1)[j]); + &node->uniq_verts, bvh->mloop[lt->tri[j]].v); } - if (!paint_is_face_hidden(f, bvh->verts)) + if (!paint_is_face_hidden(lt, bvh->verts, bvh->mloop)) { has_visible = true; + } } vert_indices = MEM_callocN(sizeof(int) * @@ -326,9 +328,8 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node) } for (i = 0; i < totface; ++i) { - const MFace *f = &bvh->faces[node->prim_indices[i]]; - int sides = f->v4 ? 4 : 3; - + const int sides = 3; + for (j = 0; j < sides; ++j) { if (face_vert_indices[i][j] < 0) face_vert_indices[i][j] = @@ -406,7 +407,7 @@ static void build_leaf(PBVH *bvh, int node_index, BBC *prim_bbc, /* Still need vb for searches */ update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count); - if (bvh->faces) + if (bvh->looptri) build_mesh_leaf_node(bvh, bvh->nodes + node_index); else { build_grid_leaf_node(bvh, bvh->nodes + node_index); @@ -417,25 +418,28 @@ static void build_leaf(PBVH *bvh, int node_index, BBC *prim_bbc, * same material (including flat/smooth shading), non-zero otherwise */ static int leaf_needs_material_split(PBVH *bvh, int offset, int count) { - int i, prim; + int i; if (count <= 1) return 0; - if (bvh->faces) { - const MFace *first = &bvh->faces[bvh->prim_indices[offset]]; + if (bvh->looptri) { + const MLoopTri *first = &bvh->looptri[bvh->prim_indices[offset]]; + const MPoly *mp = &bvh->mpoly[first->poly]; for (i = offset + count - 1; i > offset; --i) { - prim = bvh->prim_indices[i]; - if (!face_materials_match(first, &bvh->faces[prim])) + int prim = bvh->prim_indices[i]; + const MPoly *mp_other = &bvh->mpoly[bvh->looptri[prim].poly]; + if (!face_materials_match(mp, mp_other)) { return 1; + } } } else { const DMFlagMat *first = &bvh->grid_flag_mats[bvh->prim_indices[offset]]; for (i = offset + count - 1; i > offset; --i) { - prim = bvh->prim_indices[i]; + int prim = bvh->prim_indices[i]; if (!grid_materials_match(first, &bvh->grid_flag_mats[prim])) return 1; } @@ -534,15 +538,18 @@ static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim) /* Do a full rebuild with on Mesh data structure */ void BKE_pbvh_build_mesh( - PBVH *bvh, const MFace *faces, MVert *verts, - int totface, int totvert, struct CustomData *vdata) + PBVH *bvh, const MPoly *mpoly, const MLoop *mloop, MVert *verts, + int totvert, struct CustomData *vdata, + const MLoopTri *looptri, int looptri_num) { BBC *prim_bbc = NULL; BB cb; int i, j; bvh->type = PBVH_FACES; - bvh->faces = faces; + bvh->mpoly = mpoly; + bvh->mloop = mloop; + bvh->looptri = looptri; bvh->verts = verts; bvh->vert_bitmap = BLI_BITMAP_NEW(totvert, "bvh->vert_bitmap"); bvh->totvert = totvert; @@ -552,25 +559,25 @@ void BKE_pbvh_build_mesh( BB_reset(&cb); /* For each face, store the AABB and the AABB centroid */ - prim_bbc = MEM_mallocN(sizeof(BBC) * totface, "prim_bbc"); + prim_bbc = MEM_mallocN(sizeof(BBC) * looptri_num, "prim_bbc"); - for (i = 0; i < totface; ++i) { - const MFace *f = &faces[i]; - const int sides = f->v4 ? 4 : 3; + for (i = 0; i < looptri_num; ++i) { + const MLoopTri *lt = &looptri[i]; + const int sides = 3; BBC *bbc = prim_bbc + i; BB_reset((BB *)bbc); for (j = 0; j < sides; ++j) - BB_expand((BB *)bbc, verts[(&f->v1)[j]].co); + BB_expand((BB *)bbc, verts[bvh->mloop[lt->tri[j]].v].co); BBC_update_centroid(bbc); BB_expand(&cb, bbc->bcentroid); } - if (totface) - pbvh_build(bvh, &cb, prim_bbc, totface); + if (looptri_num) + pbvh_build(bvh, &cb, prim_bbc, looptri_num); MEM_freeN(prim_bbc); MEM_freeN(bvh->vert_bitmap); @@ -657,12 +664,13 @@ void BKE_pbvh_free(PBVH *bvh) /* if pbvh was deformed, new memory was allocated for verts/faces -- free it */ MEM_freeN((void *)bvh->verts); - if (bvh->faces) { - MEM_freeN((void *)bvh->faces); - } } } + if (bvh->looptri) { + MEM_freeN((void *)bvh->looptri); + } + if (bvh->nodes) MEM_freeN(bvh->nodes); @@ -983,20 +991,23 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes, totface = node->totprim; for (i = 0; i < totface; ++i) { - const MFace *f = &bvh->faces[faces[i]]; + const MLoopTri *lt = &bvh->looptri[faces[i]]; + const unsigned int vtri[3] = { + bvh->mloop[lt->tri[0]].v, + bvh->mloop[lt->tri[1]].v, + bvh->mloop[lt->tri[2]].v, + }; float fn[3]; - const unsigned int *fv = &f->v1; - int sides = (f->v4) ? 4 : 3; + const int sides = 3; - if (f->v4) - normal_quad_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co, - bvh->verts[f->v3].co, bvh->verts[f->v4].co); - else - normal_tri_v3(fn, bvh->verts[f->v1].co, bvh->verts[f->v2].co, - bvh->verts[f->v3].co); + normal_tri_v3( + fn, + bvh->verts[vtri[0]].co, + bvh->verts[vtri[1]].co, + bvh->verts[vtri[2]].co); for (j = 0; j < sides; ++j) { - int v = fv[j]; + int v = vtri[j]; if (bvh->verts[v].flag & ME_VERT_PBVH_UPDATE) { /* this seems like it could be very slow but profile @@ -1010,8 +1021,9 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes, } } - if (face_nors) - copy_v3_v3(face_nors[faces[i]], fn); + if (face_nors) { + copy_v3_v3(face_nors[lt->poly], fn); + } } } } @@ -1093,7 +1105,8 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode) case PBVH_FACES: node->draw_buffers = GPU_build_mesh_pbvh_buffers(node->face_vert_indices, - bvh->faces, bvh->verts, + bvh->mpoly, bvh->mloop, bvh->looptri, + bvh->verts, node->prim_indices, node->totprim); break; @@ -1515,15 +1528,16 @@ static bool pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node, const float ray_normal[3], float *dist) { const MVert *vert = bvh->verts; + const MLoop *mloop = bvh->mloop; const int *faces = node->prim_indices; int i, totface = node->totprim; bool hit = false; for (i = 0; i < totface; ++i) { - const MFace *f = bvh->faces + faces[i]; + const MLoopTri *lt = &bvh->looptri[faces[i]]; const int *face_verts = node->face_vert_indices[i]; - if (paint_is_face_hidden(f, vert)) + if (paint_is_face_hidden(lt, vert, mloop)) continue; if (origco) { @@ -1532,16 +1546,16 @@ static bool pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node, origco[face_verts[0]], origco[face_verts[1]], origco[face_verts[2]], - f->v4 ? origco[face_verts[3]] : NULL, + NULL, dist); } else { /* intersect with current coordinates */ hit |= ray_face_intersection(ray_start, ray_normal, - vert[f->v1].co, - vert[f->v2].co, - vert[f->v3].co, - f->v4 ? vert[f->v4].co : NULL, + vert[mloop[lt->tri[0]].v].co, + vert[mloop[lt->tri[1]].v].co, + vert[mloop[lt->tri[2]].v].co, + NULL, dist); } } @@ -1874,8 +1888,8 @@ void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3]) /* original data and applying new coords to this arrays would lead to */ /* unneeded deformation -- duplicate verts/faces to avoid this */ - pbvh->verts = MEM_dupallocN(pbvh->verts); - pbvh->faces = MEM_dupallocN(pbvh->faces); + pbvh->verts = MEM_dupallocN(pbvh->verts); + pbvh->looptri = MEM_dupallocN(pbvh->looptri); pbvh->deformed = 1; } @@ -1890,7 +1904,11 @@ void BKE_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3]) } /* coordinates are new -- normals should also be updated */ - BKE_mesh_calc_normals_tessface(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL); + BKE_mesh_calc_normals_looptri( + pbvh->verts, pbvh->totvert, + pbvh->mloop, + pbvh->looptri, pbvh->totprim, + NULL); for (a = 0; a < pbvh->totnode; ++a) BKE_pbvh_node_mark_update(&pbvh->nodes[a]); |