[Bf-blender-cvs] [57286eed8d6] temp_bmesh_multires: Sculpt dyntopo: Add support for multiple materials to dyntopo pbvh drawing.
Joseph Eagar
noreply at git.blender.org
Fri Jul 2 22:15:44 CEST 2021
Commit: 57286eed8d67e59dd799a4de6d80fb9a0ce037ab
Author: Joseph Eagar
Date: Fri Jul 2 13:14:00 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB57286eed8d67e59dd799a4de6d80fb9a0ce037ab
Sculpt dyntopo: Add support for multiple materials to dyntopo
pbvh drawing.
* Dyntopo now stores a list of PBVHTriBufs in leaf nodes, one per material
used by the node.
* Actual drawing buffers live in a new mat_draw_buffers PBVHNode member.
===================================================================
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/pbvh.c
M source/blender/blenkernel/intern/pbvh_bmesh.c
M source/blender/blenkernel/intern/pbvh_intern.h
M source/blender/gpu/GPU_buffers.h
M source/blender/gpu/intern/gpu_buffers.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 5a0893535b0..d84144f53e8 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -64,10 +64,11 @@ typedef struct PBVHTriBuf {
PBVHTri *tris;
SculptVertRef *verts;
int tottri, totvert;
+ int tris_size, verts_size;
// private field
intptr_t *loops;
- int totloop;
+ int totloop, mat_nr;
float min[3], max[3];
} PBVHTriBuf;
@@ -703,7 +704,7 @@ bool BKE_pbvh_curvature_update_get(PBVHNode *node);
int BKE_pbvh_get_totnodes(PBVH *pbvh);
-void BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node);
+bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node);
PBVHTriBuf *BKE_pbvh_bmesh_get_tris(PBVH *pbvh, PBVHNode *node);
void BKE_pbvh_bmesh_free_tris(PBVH *pbvh, PBVHNode *node);
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 5b0a5cbf29e..03f520741cf 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -705,9 +705,8 @@ void BKE_pbvh_free(PBVH *pbvh)
PBVHNode *node = &pbvh->nodes[i];
if (node->flag & PBVH_Leaf) {
- if (node->draw_buffers) {
- GPU_pbvh_buffers_free(node->draw_buffers);
- }
+ pbvh_free_all_draw_buffers(node);
+
if (node->vert_indices) {
MEM_freeN((void *)node->vert_indices);
}
@@ -1320,10 +1319,23 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
node->totprim,
pbvh->mesh);
break;
- case PBVH_BMESH:
- node->draw_buffers = GPU_pbvh_bmesh_buffers_build(pbvh->flags &
- PBVH_DYNTOPO_SMOOTH_SHADING);
+ case PBVH_BMESH: {
+ BKE_pbvh_bmesh_check_tris(pbvh, node);
+
+ node->tot_mat_draw_buffers = node->tot_tri_buffers;
+
+ if (node->tot_tri_buffers) {
+ node->mat_draw_buffers = MEM_malloc_arrayN(
+ node->tot_tri_buffers, sizeof(void *), "node->mat_draw_buffers");
+ }
+
+ for (int i = 0; i < node->tot_tri_buffers; i++) {
+ node->mat_draw_buffers[i] = GPU_pbvh_bmesh_buffers_build(pbvh->flags &
+ PBVH_DYNTOPO_SMOOTH_SHADING);
+ }
+
break;
+ }
}
}
@@ -1357,19 +1369,41 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
update_flags);
break;
case PBVH_BMESH:
- BKE_pbvh_bmesh_check_tris(pbvh, node);
- GPU_pbvh_bmesh_buffers_update(node->draw_buffers,
- pbvh->bm,
- node->bm_faces,
- node->bm_unique_verts,
- node->bm_other_verts,
- node->tribuf,
- update_flags,
- pbvh->cd_vert_node_offset,
- pbvh->face_sets_color_seed,
- pbvh->face_sets_color_default,
- data->flat_vcol_shading,
- data->active_vcol_only);
+ if (BKE_pbvh_bmesh_check_tris(pbvh, node)) {
+ pbvh_free_all_draw_buffers(node);
+ node->tot_mat_draw_buffers = node->tot_tri_buffers;
+
+ if (node->tot_tri_buffers) {
+ node->mat_draw_buffers = MEM_malloc_arrayN(
+ node->tot_tri_buffers, sizeof(void *), "node->mat_draw_buffers");
+
+ for (int i = 0; i < node->tot_tri_buffers; i++) {
+ node->mat_draw_buffers[i] = GPU_pbvh_bmesh_buffers_build(
+ pbvh->flags & PBVH_DYNTOPO_SMOOTH_SHADING);
+ }
+ }
+ }
+
+ for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
+ if (i >= node->tot_tri_buffers) {
+ printf("pbvh corruption!\n");
+ continue;
+ }
+
+ GPU_pbvh_bmesh_buffers_update(node->mat_draw_buffers[i],
+ pbvh->bm,
+ node->bm_faces,
+ node->bm_unique_verts,
+ node->bm_other_verts,
+ node->tri_buffers + i,
+ update_flags,
+ pbvh->cd_vert_node_offset,
+ pbvh->face_sets_color_seed,
+ pbvh->face_sets_color_default,
+ data->flat_vcol_shading,
+ data->active_vcol_only,
+ node->tri_buffers[i].mat_nr);
+ }
break;
}
}
@@ -1392,6 +1426,36 @@ void BKE_pbvh_set_flat_vcol_shading(PBVH *pbvh, bool value)
pbvh->flat_vcol_shading = value;
}
+void pbvh_free_all_draw_buffers(PBVHNode *node)
+{
+ if (node->draw_buffers) {
+ GPU_pbvh_buffers_free(node->draw_buffers);
+ node->draw_buffers = NULL;
+ }
+
+ for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
+ GPU_pbvh_buffers_free(node->mat_draw_buffers[i]);
+ }
+
+ MEM_SAFE_FREE(node->mat_draw_buffers);
+
+ node->mat_draw_buffers = NULL;
+ node->tot_mat_draw_buffers = 0;
+}
+
+void pbvh_update_free_all_draw_buffers(PBVH *pbvh, PBVHNode *node)
+{
+ if (pbvh->type == PBVH_GRIDS) {
+ GPU_pbvh_grid_buffers_update_free(
+ node->draw_buffers, pbvh->grid_flag_mats, node->prim_indices);
+ }
+ else if (pbvh->type == PBVH_BMESH) {
+ for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
+ GPU_pbvh_bmesh_buffers_update_free(node->mat_draw_buffers[i]);
+ }
+ }
+}
+
static void pbvh_update_draw_buffers(
PBVH *pbvh, PBVHNode **nodes, int totnode, int update_flag, bool active_vcol_only)
{
@@ -1400,17 +1464,10 @@ static void pbvh_update_draw_buffers(
for (int n = 0; n < totnode; n++) {
PBVHNode *node = nodes[n];
if (node->flag & PBVH_RebuildDrawBuffers) {
- GPU_pbvh_buffers_free(node->draw_buffers);
- node->draw_buffers = NULL;
+ pbvh_free_all_draw_buffers(node);
}
- else if ((node->flag & PBVH_UpdateDrawBuffers) && node->draw_buffers) {
- if (pbvh->type == PBVH_GRIDS) {
- GPU_pbvh_grid_buffers_update_free(
- node->draw_buffers, pbvh->grid_flag_mats, node->prim_indices);
- }
- else if (pbvh->type == PBVH_BMESH) {
- GPU_pbvh_bmesh_buffers_update_free(node->draw_buffers);
- }
+ else if ((node->flag & PBVH_UpdateDrawBuffers)) {
+ pbvh_update_free_all_draw_buffers(pbvh, node);
}
}
}
@@ -1449,7 +1506,13 @@ static void pbvh_update_draw_buffers(
if (node->flag & PBVH_UpdateDrawBuffers) {
/* Flush buffers uses OpenGL, so not in parallel. */
- GPU_pbvh_buffers_update_flush(node->draw_buffers);
+ if (node->draw_buffers) {
+ GPU_pbvh_buffers_update_flush(node->draw_buffers);
+ }
+
+ for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
+ GPU_pbvh_buffers_update_flush(node->mat_draw_buffers[i]);
+ }
}
node->flag &= ~(PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers);
@@ -2898,7 +2961,13 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
for (int i = 0; i < totnode; i++) {
PBVHNode *node = nodes[i];
if (!(node->flag & PBVH_FullyHidden)) {
- draw_fn(user_data, node->draw_buffers);
+ if (node->draw_buffers) {
+ draw_fn(user_data, node->draw_buffers);
+ }
+
+ for (int i = 0; i < node->tot_mat_draw_buffers; i++) {
+ draw_fn(user_data, node->mat_draw_buffers[i]);
+ }
}
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 14919bd5386..b99bbaeb62f 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -53,6 +53,8 @@ Topology rake:
#include "PIL_time.h"
#include "atomic_ops.h"
+#include "DNA_material_types.h"
+
#include "BKE_DerivedMesh.h"
#include "BKE_ccg.h"
#include "BKE_pbvh.h"
@@ -506,10 +508,7 @@ static void pbvh_bmesh_node_split(
n->bm_other_verts = NULL;
n->layer_disp = NULL;
- if (n->draw_buffers) {
- GPU_pbvh_buffers_free(n->draw_buffers);
- n->draw_buffers = NULL;
- }
+ pbvh_free_all_draw_buffers(n);
n->flag &= ~PBVH_Leaf;
/* Recurse */
@@ -3999,6 +3998,20 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh,
return modified;
}
+static void pbvh_free_tribuf(PBVHTriBuf *tribuf)
+{
+ MEM_SAFE_FREE(tribuf->verts);
+ MEM_SAFE_FREE(tribuf->tris);
+ MEM_SAFE_FREE(tribuf->loops);
+
+ tribuf->verts = NULL;
+ tribuf->tris = NULL;
+ tribuf->loops = NULL;
+
+ tribuf->verts_size = 0;
+ tribuf->tris_size = 0;
+}
+
PBVHTriBuf *BKE_pbvh_bmesh_get_tris(PBVH *pbvh, PBVHNode *node)
{
BKE_pbvh_bmesh_check_tris(pbvh, node);
@@ -4009,12 +4022,21 @@ PBVHTriBuf *BKE_pbvh_bmesh_get_tris(PBVH *pbvh, PBVHNode *node)
void BKE_pbvh_bmesh_free_tris(PBVH *pbvh, PBVHNode *node)
{
if (node->tribuf) {
- MEM_SAFE_FREE(node->tribuf->verts);
- MEM_SAFE_FREE(node->tribuf->tris);
- MEM_SAFE_FREE(node->tribuf->loops);
+ pbvh_free_tribuf(node->tribuf);
MEM_freeN(node->tribuf);
node->tribuf = NULL;
}
+
+ if (node->tri_buffers) {
+ for (int i = 0; i < node->tot_tri_buffers; i++) {
+ pbvh_free_tribuf(node->tri_buffers + i);
+ }
+
+ MEM_SAFE_FREE(node->tri_buffers);
+
+ node->tri_buffers = NULL;
+ node->tot_tri_buffers = 0;
+ }
}
/*
@@ -4138,41 +4160,87 @@ static bool pbvh_bmesh_split_tris(PBVH *pbvh, PBVHNode *node)
return true;
}
+
+ATTR_NO_OPT BLI_INLINE PBVHTri *pbvh_tribuf_add_tri(PBVHTriBuf *tribuf)
+{
+ tribuf->tottri++;
+
+ if (tribuf->tottri >= tribuf->tris_size) {
+ size_t newsize = (size_t)32 + (size_t)tribuf->tris_size + (size_t)(tribuf->tris_size >> 1);
+
+ if (!tribuf->tris) {
+ tribuf->tris = MEM_mallocN(sizeof(*tribuf->tris) * newsize, "
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list