Commit: 39b0e9df816a1a308ca8bdde0df8e71f42248530 Author: Joseph Eagar Date: Sat Aug 28 12:14:59 2021 -0700 Branches: temp_bmesh_multires https://developer.blender.org/rB39b0e9df816a1a308ca8bdde0df8e71f42248530
Sculpt dyntopo: Add edge API * Added a minimal edge API to query edge boundary states. * This is necassary because the previous approximation, testing if two adjacent verts are boundaries, breaks for triangles. =================================================================== M source/blender/blenkernel/BKE_pbvh.h M source/blender/editors/sculpt_paint/sculpt.c M source/blender/editors/sculpt_paint/sculpt_intern.h M source/blender/editors/sculpt_paint/sculpt_smooth.c =================================================================== diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 9a6e6983293..b4299ab54b1 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -37,6 +37,10 @@ typedef struct SculptVertRef { intptr_t i; } SculptVertRef; +typedef struct SculptEdgeRef { + intptr_t i; +} SculptEdgeRef; + typedef struct SculptFaceRef { intptr_t i; } SculptFaceRef; @@ -53,12 +57,20 @@ BLI_INLINE SculptVertRef BKE_pbvh_make_vref(intptr_t i) return ret; } +BLI_INLINE SculptEdgeRef BKE_pbvh_make_eref(intptr_t i) +{ + SculptEdgeRef ret = {i}; + return ret; +} + BLI_INLINE SculptFaceRef BKE_pbvh_make_fref(intptr_t i) { SculptFaceRef ret = {i}; return ret; } +#define SCULPT_REF_NONE ((intptr_t)-1) + typedef struct PBVHTri { int v[3]; // references into PBVHTriBuf->verts intptr_t l[3]; // loops diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 29e07efc5d5..146e6da9fee 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1322,10 +1322,11 @@ int SCULPT_face_set_next_available_get(SculptSession *ss) static void sculpt_vertex_neighbor_add(SculptVertexNeighborIter *iter, SculptVertRef neighbor, + SculptEdgeRef edge, int neighbor_index) { for (int i = 0; i < iter->size; i++) { - if (iter->neighbors[i].i == neighbor.i) { + if (iter->neighbors[i].vertex.i == neighbor.i) { return; } } @@ -1334,48 +1335,55 @@ static void sculpt_vertex_neighbor_add(SculptVertexNeighborIter *iter, iter->capacity += SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY; if (iter->neighbors == iter->neighbors_fixed) { - iter->neighbors = MEM_mallocN(iter->capacity * sizeof(SculptVertRef), "neighbor array"); + iter->neighbors = MEM_mallocN(iter->capacity * sizeof(struct _SculptNeighborRef), + "neighbor array"); iter->neighbor_indices = MEM_mallocN(iter->capacity * sizeof(int), "neighbor array"); - memcpy(iter->neighbors, iter->neighbors_fixed, sizeof(SculptVertRef) * iter->size); + memcpy( + iter->neighbors, iter->neighbors_fixed, sizeof(struct _SculptNeighborRef) * iter->size); memcpy(iter->neighbor_indices, iter->neighbor_indices_fixed, sizeof(int) * iter->size); } else { iter->neighbors = MEM_reallocN_id( - iter->neighbors, iter->capacity * sizeof(SculptVertRef), "neighbor array"); + iter->neighbors, iter->capacity * sizeof(struct _SculptNeighborRef), "neighbor array"); iter->neighbor_indices = MEM_reallocN_id( iter->neighbor_indices, iter->capacity * sizeof(int), "neighbor array"); } } - iter->neighbors[iter->size] = neighbor; + iter->neighbors[iter->size].vertex = neighbor; + iter->neighbors[iter->size].edge = edge; iter->neighbor_indices[iter->size] = neighbor_index; iter->size++; } static void sculpt_vertex_neighbor_add_nocheck(SculptVertexNeighborIter *iter, SculptVertRef neighbor, + SculptEdgeRef edge, int neighbor_index) { if (iter->size >= iter->capacity) { iter->capacity += SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY; if (iter->neighbors == iter->neighbors_fixed) { - iter->neighbors = MEM_mallocN(iter->capacity * sizeof(SculptVertRef), "neighbor array"); + iter->neighbors = MEM_mallocN(iter->capacity * sizeof(struct _SculptNeighborRef), + "neighbor array"); iter->neighbor_indices = MEM_mallocN(iter->capacity * sizeof(int), "neighbor array"); - memcpy(iter->neighbors, iter->neighbors_fixed, sizeof(SculptVertRef) * iter->size); + memcpy( + iter->neighbors, iter->neighbors_fixed, sizeof(struct _SculptNeighborRef) * iter->size); memcpy(iter->neighbor_indices, iter->neighbor_indices_fixed, sizeof(int) * iter->size); } else { iter->neighbors = MEM_reallocN_id( - iter->neighbors, iter->capacity * sizeof(SculptVertRef), "neighbor array"); + iter->neighbors, iter->capacity * sizeof(struct _SculptNeighborRef), "neighbor array"); iter->neighbor_indices = MEM_reallocN_id( iter->neighbor_indices, iter->capacity * sizeof(int), "neighbor array"); } } - iter->neighbors[iter->size] = neighbor; + iter->neighbors[iter->size].vertex = neighbor; + iter->neighbors[iter->size].edge = edge; iter->neighbor_indices[iter->size] = neighbor_index; iter->size++; } @@ -1416,12 +1424,27 @@ static void sculpt_vertex_neighbors_get_bmesh(const SculptSession *ss, MDynTopoVert *mv = BKE_PBVH_DYNVERT(ss->cd_dyn_vert, v2); - e = e2; if (!(mv->flag & DYNVERT_VERT_FSET_HIDDEN)) { - sculpt_vertex_neighbor_add_nocheck( - iter, BKE_pbvh_make_vref((intptr_t)v2), BM_elem_index_get(v2)); + sculpt_vertex_neighbor_add_nocheck(iter, + BKE_pbvh_make_vref((intptr_t)v2), + BKE_pbvh_make_eref((intptr_t)e), + BM_elem_index_get(v2)); } + + e = e2; } while (e != v->e); + + if (ss->fake_neighbors.use_fake_neighbors) { + int index = BM_elem_index_get(v); + + BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL); + if (ss->fake_neighbors.fake_neighbor_index[index].i != FAKE_NEIGHBOR_NONE) { + sculpt_vertex_neighbor_add(iter, + ss->fake_neighbors.fake_neighbor_index[index], + BKE_pbvh_make_eref(SCULPT_REF_NONE), + ss->fake_neighbors.fake_neighbor_index[index].i); + } + } } static void sculpt_vertex_neighbors_get_faces(const SculptSession *ss, @@ -1447,8 +1470,21 @@ static void sculpt_vertex_neighbors_get_faces(const SculptSession *ss, uint f_adj_v[2]; if (poly_get_adj_loops_from_vert(p, ss->mloop, index, f_adj_v) != -1) { for (int j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) { + int e = 0; + if (f_adj_v[j] != index) { - sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(f_adj_v[j]), f_adj_v[j]); + int loopidx = p->loopstart; + + for (int k = 0; k < p->totloop; k++, loopidx++) { + const MEdge *e2 = &ss->medge[ss->mloop[loopidx].e]; + if ((e2->v1 == index && e2->v2 == f_adj_v[j]) || + (e2->v2 == index && e2->v1 == f_adj_v[j])) { + e = e2 - ss->medge; + } + } + + sculpt_vertex_neighbor_add( + iter, BKE_pbvh_make_vref(f_adj_v[j]), BKE_pbvh_make_eref(e), f_adj_v[j]); } } } @@ -1459,6 +1495,7 @@ static void sculpt_vertex_neighbors_get_faces(const SculptSession *ss, if (ss->fake_neighbors.fake_neighbor_index[index].i != FAKE_NEIGHBOR_NONE) { sculpt_vertex_neighbor_add(iter, ss->fake_neighbors.fake_neighbor_index[index], + BKE_pbvh_make_eref(SCULPT_REF_NONE), ss->fake_neighbors.fake_neighbor_index[index].i); } } @@ -1488,7 +1525,8 @@ static void sculpt_vertex_neighbors_get_faces_vemap(const SculptSession *ss, continue; } - sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(v), v); + sculpt_vertex_neighbor_add( + iter, BKE_pbvh_make_vref(v), BKE_pbvh_make_eref(vert_map->indices[i]), v); } if (ss->fake_neighbors.use_fake_neighbors) { @@ -1496,6 +1534,7 @@ static void sculpt_vertex_neighbors_get_faces_vemap(const SculptSession *ss, if (ss->fake_neighbors.fake_neighbor_index[index].i != FAKE_NEIGHBOR_NONE) { sculpt_vertex_neighbor_add(iter, ss->fake_neighbors.fake_neighbor_index[index], + BKE_pbvh_make_eref(SCULPT_REF_NONE), ss->fake_neighbors.fake_neighbor_index[index].i); } } @@ -1534,7 +1573,8 @@ static void sculpt_vertex_neighbors_get_grids(const SculptSession *ss, int idx = neighbors.coords[i].grid_index * key->grid_area + neighbors.coords[i].y * key->grid_size + neighbors.coords[i].x; - sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(idx), idx); + sculpt_vertex_neighbor_add( + iter, BKE_pbvh_make_vref(idx), BKE_pbvh_make_eref(SCULPT_REF_NONE), idx); } if (ss->fake_neighbors.use_fake_neighbors) { @@ -1542,6 +1582,7 @@ static void sculpt_vertex_neighbors_get_grids(const SculptSession *ss, if (ss->fake_neighbors.fake_neighbor_index[index].i != FAKE_NEIGHBOR_NONE) { sculpt_vertex_neighbor_add(iter, ss->fake_neighbors.fake_neighbor_index[index], + BKE_pbvh_make_eref(SCULPT_REF_NONE), ss->fake_neighbors.fake_neighbor_index[index].i); } } @@ -1575,6 +1616,110 @@ void SCULPT_vertex_neighbors_get(const SculptSession *ss, } } +SculptBoundaryType SCULPT_edge_is_boundary(const SculptSession *ss, + const SculptEdgeRef edge, + SculptBoundaryType typemask) +{ + + int ret = 0; + + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_BMESH: { + BMEdge *e = (BMEdge *)edge.i; + + if (typemask & SCULPT_BOUNDARY_MESH) { + ret |= (!e->l || e->l == e->l->radial_next) ? SCULPT_BOUNDARY_MESH : 0; + } + + if ((typemask & SCULPT_BOUNDARY_FACE_SET) && e->l && e->l != e->l->radial_next) { + int fset1 = BM_ELEM_CD_GET_INT(e->l->f, ss->cd_faceset_offset); + int fset2 = BM_ELEM_CD_GET_INT(e->l->f, ss->cd_faceset_offset); + + bool ok = (fset1 < 0) != (fset2 < 0); + ok = ok || fset1 != fset2; + + ret |= ok ? SCULPT_BOUNDARY_FACE_SET : 0; + } + + if (typemask & SCULPT_BOUNDARY_SHARP) { + ret |= !BM_elem_flag_test(e, B @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs