[Bf-blender-cvs] [95767bade85] sculpt-mode-features: Sculpt: Mesh abstaction API [WIP]
Pablo Dobarro
noreply at git.blender.org
Fri Jul 26 23:52:28 CEST 2019
Commit: 95767bade8520bdda8fe26e2a6329457fe37aa0e
Author: Pablo Dobarro
Date: Fri Jul 26 23:53:32 2019 +0200
Branches: sculpt-mode-features
https://developer.blender.org/rB95767bade8520bdda8fe26e2a6329457fe37aa0e
Sculpt: Mesh abstaction API [WIP]
Using this API, all new tools for the sculpt branch should work with
both mesh and bmesh. I also ported mask by normal, mask expand and the
transform operator (with its mesh filter cache) in order to test it
===================================================================
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/pbvh_bmesh.c
M source/blender/editors/sculpt_paint/paint_vertex.c
M source/blender/editors/sculpt_paint/sculpt.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index f9f06cb2fc8..ea2c24b632c 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -311,6 +311,7 @@ typedef struct PBVHVertexIter {
int gx;
int gy;
int i;
+ int index;
/* grid */
struct CCGElem **grids;
@@ -381,6 +382,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
continue; \
vi.co = vi.mvert->co; \
vi.no = vi.mvert->no; \
+ vi.index = vi.vert_indices[vi.i]; \
if (vi.vmask) \
vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
if (vi.vcol) \
@@ -399,6 +401,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node, PBVHVertexIter *vi, int mo
continue; \
vi.co = vi.bm_vert->co; \
vi.fno = vi.bm_vert->no; \
+ vi.index = BM_elem_index_get(vi.bm_vert); \
vi.mask = BM_ELEM_CD_GET_VOID_P(vi.bm_vert, vi.cd_vert_mask_offset); \
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index e58d95d86b4..868adb19afc 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1550,6 +1550,7 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
if (len_squared_v3v3(location, v_tri[j]->co) <
len_squared_v3v3(location, output_data->nearest_vertex_co)) {
copy_v3_v3(output_data->nearest_vertex_co, v_tri[j]->co);
+ output_data->active_vertex_mesh_index = BM_elem_index_get(v_tri[j]);
}
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 7b50f35070d..d5e8c2a1825 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -1,4 +1,4 @@
- /*
+/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 4c60a2df1aa..327fe2c2638 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -95,6 +95,223 @@
#include <stdlib.h>
#include <string.h>
+/* Sculpt PBVH abstraction API */
+
+typedef int VertexHandle;
+
+VertexHandle sculpt_active_vertex_get(SculptSession *ss)
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ return ss->active_vertex_mesh_index;
+ case PBVH_BMESH:
+ return ss->active_vertex_mesh_index;
+ default:
+ return 0;
+ }
+}
+
+unsigned int sculpt_vertex_count_get(SculptSession *ss)
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ return (unsigned int)ss->totvert;
+ case PBVH_BMESH:
+ return (unsigned int)BM_mesh_elem_count(BKE_pbvh_get_bmesh(ss->pbvh), BM_VERT);
+ default:
+ return 0;
+ }
+}
+
+void sculpt_vertex_normal_get(SculptSession *ss, VertexHandle index, float no[3])
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ normal_short_to_float_v3(no, ss->mvert[(int)index].no);
+ return;
+ case PBVH_BMESH:
+ copy_v3_v3(no, BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->no);
+ default:
+ return;
+ }
+}
+
+float *sculpt_vertex_co_get(SculptSession *ss, int index)
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ return ss->mvert[index].co;
+ case PBVH_BMESH:
+ return BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co;
+ default:
+ return NULL;
+ }
+}
+
+void sculpt_vertex_co_set(SculptSession *ss, int index, float co[3])
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ copy_v3_v3(ss->mvert[index].co, co);
+ return;
+ case PBVH_BMESH:
+ copy_v3_v3(BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co, co);
+ return;
+ default:
+ return;
+ }
+}
+
+void sculpt_vertex_mask_set(SculptSession *ss, VertexHandle index, float mask)
+{
+ BMVert *v;
+ float *mask_p;
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ ss->vmask[(int)index] = mask;
+ return;
+ case PBVH_BMESH:
+ v = BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index);
+ mask_p = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK));
+ *(mask_p) = mask;
+ return;
+ default:
+ return;
+ }
+}
+
+float sculpt_vertex_mask_get(SculptSession *ss, int index)
+{
+ BMVert *v;
+ float *mask;
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ return ss->vmask[index];
+ case PBVH_BMESH:
+ v = BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index);
+ mask = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK));
+ return *mask;
+ default:
+ return 0;
+ }
+}
+
+void sculpt_vertex_tag_update(SculptSession *ss, int index)
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ ss->mvert[index].flag |= ME_VERT_PBVH_UPDATE;
+ case PBVH_BMESH:
+ break;
+ default:
+ break;
+ }
+}
+
+typedef struct SculptVertexNeighbourIter {
+ VertexHandle *neighbours;
+ int count;
+ VertexHandle index;
+ int i;
+} SculptVertexNeighbourIter;
+
+void sculpt_vertex_neighbours_get_bmesh(SculptSession *ss,
+ VertexHandle index,
+ SculptVertexNeighbourIter *iter)
+{
+ BMVert *v = BM_vert_at_index(ss->bm, index);
+ BMIter liter;
+ BMLoop *l;
+ GSet *n_set;
+ n_set = BLI_gset_new(BLI_ghashutil_uinthash, BLI_ghashutil_intcmp, "neighbour set");
+ int i = 0;
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ const BMVert *adj_v[2] = {l->prev->v, l->next->v};
+ for (i = 0; i < ARRAY_SIZE(adj_v); i++) {
+ const BMVert *v_other = adj_v[i];
+ if (BM_elem_index_get(v_other) != (int)index) {
+ BLI_gset_add(n_set, BM_elem_index_get(v_other));
+ }
+ }
+ }
+
+ iter->count = BLI_gset_len(n_set);
+ iter->neighbours = MEM_mallocN(BLI_gset_len(n_set) * sizeof(int), "neighbour array");
+
+ int c_index = 0;
+ GSetIterator *gsi = BLI_gsetIterator_new(n_set);
+ for (BLI_gsetIterator_init(gsi, n_set); !BLI_gsetIterator_done(gsi);
+ BLI_gsetIterator_step(gsi)) {
+ iter->neighbours[c_index] = BLI_gsetIterator_getKey(gsi);
+ c_index++;
+ }
+ BLI_gsetIterator_free(gsi);
+ BLI_gset_free(n_set, NULL);
+}
+
+void sculpt_vertex_neighbours_get_faces(SculptSession *ss,
+ VertexHandle index,
+ SculptVertexNeighbourIter *iter)
+{
+ GSet *n_set;
+ int i;
+ MeshElemMap *vert_map = &ss->pmap[(int)index];
+ n_set = BLI_gset_new(BLI_ghashutil_uinthash, BLI_ghashutil_intcmp, "neighbour set");
+ for (i = 0; i < ss->pmap[(int)index].count; i++) {
+ const MPoly *p = &ss->mpoly[vert_map->indices[i]];
+ unsigned f_adj_v[2];
+ if (poly_get_adj_loops_from_vert(p, ss->mloop, (int)index, f_adj_v) != -1) {
+ int j;
+ for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
+ if (vert_map->count != 2 || ss->pmap[f_adj_v[j]].count <= 2) {
+ if (f_adj_v[j] != (int)index) {
+ BLI_gset_add(n_set, f_adj_v[j]);
+ }
+ }
+ }
+ }
+ }
+
+ iter->count = BLI_gset_len(n_set);
+ iter->neighbours = MEM_mallocN(BLI_gset_len(n_set) * sizeof(int), "neighbour array");
+
+ int c_index = 0;
+ GSetIterator *gsi = BLI_gsetIterator_new(n_set);
+ for (BLI_gsetIterator_init(gsi, n_set); !BLI_gsetIterator_done(gsi);
+ BLI_gsetIterator_step(gsi)) {
+ iter->neighbours[c_index] = BLI_gsetIterator_getKey(gsi);
+ c_index++;
+ }
+ BLI_gsetIterator_free(gsi);
+ BLI_gset_free(n_set, NULL);
+}
+
+void sculpt_vertex_neighbours_get(SculptSession *ss,
+ VertexHandle index,
+ SculptVertexNeighbourIter *iter)
+{
+ switch (BKE_pbvh_type(ss->pbvh)) {
+ case PBVH_FACES:
+ sculpt_vertex_neighbours_get_faces(ss, index, iter);
+ return;
+ case PBVH_BMESH:
+ sculpt_vertex_neighbours_get_bmesh(ss, index, iter);
+ return;
+ default:
+ break;
+ }
+}
+
+#define sculpt_vertex_neighbours_iter_begin(ss, v_index, neighbour_iterator) \
+ sculpt_vertex_neighbours_get(ss, v_index, &neighbour_iterator); \
+ for (neighbour_iterator.i = 0; neighbour_iterator.i < neighbour_iterator.count; \
+ neighbour_iterator.i++) { \
+ neighbour_iterator.index = ni.neighbours[ni.i];
+
+#define sculpt_vertex_neighbours_iter_end(neighbour_iterator) \
+ } \
+ MEM_freeN(neighbour_iterator.neighbours);
+
/** \name Tool Capabilities
*
* Avoid duplicate checks, internal logic only,
@@ -4899,6 +5116,10 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
update_brush_local_mat(sd, ob);
}
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BM_mesh_elem_index_ensure(BKE_pbvh_get_bmesh(ss->pbvh), BM_VERT);
+ }
+
/* Init topological automasking */
if (sculpt_automasking_enabled(ss, brush)) {
if (sculpt_automasking_needs_updates(brush) || ss->cache->first_time) {
@@ -6112,6 +6333,9 @@ bool sculpt_stroke_get_geometry_info(bContext *C, StrokeGeometryInfo *out, const
return false;
}
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BM_mesh_elem_index_ensure(ss->bm, BM_VERT);
+ }
depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, original);
sculpt_stroke_modifiers_check(C, ob, brush);
@@ -7743,11 +7967,11 @@ static void filter_cache_init_task_cb(void *__restrict userdata,
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
{
- int vi = vd.vert_indices[vd.i];
- if (vd.mask && (*vd.mask) < 1.0f) {
+ int vi = vd.index;
+ if (*vd.mask < 1.0f) {
data->node_mask[i] = 1;
}
- copy_v3_v3(ss->filter_cache->orco[vi], ss->mvert[vi].co);
+ copy_v3_v3(ss->filt
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list