Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2015-07-16 20:36:03 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-07-16 20:55:14 +0300
commit595a491e63d6f3f3462675d38cfa71b4e784fe9c (patch)
treedf32ec17691b9280d7b2fa675cd5e5a0f87ea849 /source/blender/blenkernel/intern/pbvh.c
parentc8f6313487dfbbee030c6796220cc0d91228d658 (diff)
Add tessellation data to DerivedMesh (LoopTri)
This stores loop indices into the loop array giving easier acess to data such as vertex-colors and UV's, removing the need to store an MFace duplicate of custom-data. This doesn't yet move all internal code from MFace to LoopTri just yet. Only applies to: - opengl drawing - sculpting (pbvh) - vertex/weight paint Thanks to @psy-fi for review, fixes and improvements to drawing!
Diffstat (limited to 'source/blender/blenkernel/intern/pbvh.c')
-rw-r--r--source/blender/blenkernel/intern/pbvh.c132
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]);