[Bf-blender-cvs] [39b0e9df816] temp_bmesh_multires: Sculpt dyntopo: Add edge API
Joseph Eagar
noreply at git.blender.org
Sat Aug 28 21:16:12 CEST 2021
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. @@
More information about the Bf-blender-cvs
mailing list