[Bf-blender-cvs] [83d4cf9db1c] temp-T96710-pbvh-pixels: PBVH: triangle brush test.
Jeroen Bakker
noreply at git.blender.org
Wed Apr 13 10:53:41 CEST 2022
Commit: 83d4cf9db1c95ec9f784aa64ab69b27bbcf106be
Author: Jeroen Bakker
Date: Wed Apr 13 10:53:18 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rB83d4cf9db1c95ec9f784aa64ab69b27bbcf106be
PBVH: triangle brush test.
===================================================================
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/BKE_pbvh_pixels.hh
M source/blender/blenkernel/intern/pbvh.c
M source/blender/blenkernel/intern/pbvh_intern.h
M source/blender/blenkernel/intern/pbvh_pixels.cc
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
M source/blender/editors/sculpt_paint/sculpt_paint_image.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index ea4a4efca87..7c5ff94f188 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -308,6 +308,7 @@ void BKE_pbvh_node_fully_unmasked_set(PBVHNode *node, int fully_masked);
bool BKE_pbvh_node_fully_unmasked_get(PBVHNode *node);
void BKE_pbvh_mark_update_pixels(PBVH *pbvh);
+void BKE_pbvh_pixels_free_brush_test(PBVH *pbvh);
void BKE_pbvh_vert_mark_update(PBVH *pbvh, int index);
void BKE_pbvh_node_get_grids(PBVH *pbvh,
diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh
index b2cdb9353e3..3df78d7cdfb 100644
--- a/source/blender/blenkernel/BKE_pbvh_pixels.hh
+++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh
@@ -53,6 +53,12 @@ struct Triangles {
/** Data accessed by the inner loop of the painting brush. */
Vector<TrianglePaintInput> paint_input;
+ /**
+ * For storing brush tests per triangle during painting.
+ * Will be freed after a painting a stroke.
+ */
+ std::vector<bool> brush_test;
+
public:
void append(const int3 vert_indices)
{
@@ -74,6 +80,18 @@ struct Triangles {
paint_input.clear();
}
+ void init_brush_test()
+ {
+ if (brush_test.size() != size()) {
+ brush_test.resize(size(), false);
+ }
+ }
+
+ void clear_brush_test()
+ {
+ brush_test.resize(0, false);
+ }
+
uint64_t size() const
{
return paint_input.size();
@@ -81,7 +99,7 @@ struct Triangles {
uint64_t mem_size() const
{
- return paint_input.size() * sizeof(TrianglePaintInput);
+ return paint_input.size() * sizeof(TrianglePaintInput) + brush_test.size() / 8;
}
};
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 979446a496e..08dcd8f34b6 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1496,6 +1496,16 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag)
}
}
+void BKE_pbvh_pixels_free_brush_test(PBVH *pbvh)
+{
+ for (int n = 0; n < pbvh->totnode; n++) {
+ PBVHNode *node = &pbvh->nodes[n];
+ if (node->flag & PBVH_Leaf && node->pixels.node_data != NULL) {
+ pbvh_pixels_free_brush_test(node);
+ }
+ }
+}
+
static void pbvh_faces_node_visibility_update(PBVH *pbvh, PBVHNode *node)
{
MVert *mvert;
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index f75bd1e36f8..1dcc62fb260 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -258,6 +258,7 @@ void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode);
/* pbvh_pixels.hh */
void pbvh_pixels_free(PBVHNode *node);
+void pbvh_pixels_free_brush_test(PBVHNode *node);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 52f16cdb3fa..576fb5504e7 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -410,4 +410,11 @@ void pbvh_pixels_free(PBVHNode *node)
MEM_delete(node_data);
node->pixels.node_data = nullptr;
}
+
+void pbvh_pixels_free_brush_test(PBVHNode *node)
+{
+ NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
+ BLI_assert(node_data);
+ node_data->triangles.clear_brush_test();
+}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index fc1df1635bd..1ceda950e45 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5214,6 +5214,10 @@ void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType up
}
}
+ if (update_flags & SCULPT_FREE_BRUSH_TEST) {
+ BKE_pbvh_pixels_free_brush_test(ss->pbvh);
+ }
+
if (update_flags & SCULPT_UPDATE_COORDS) {
BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateOriginalBB);
@@ -5420,7 +5424,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
}
else if (brush->sculpt_tool == SCULPT_TOOL_PAINT) {
if (SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) {
- SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_IMAGE);
+ SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_IMAGE | SCULPT_FREE_BRUSH_TEST);
}
}
else {
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 4c11be18758..39ce22b21b8 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -47,6 +47,7 @@ typedef enum SculptUpdateType {
SCULPT_UPDATE_VISIBILITY = 1 << 2,
SCULPT_UPDATE_COLOR = 1 << 3,
SCULPT_UPDATE_IMAGE = 1 << 4,
+ SCULPT_FREE_BRUSH_TEST = 1 << 5,
} SculptUpdateType;
typedef struct SculptCursorGeometryInfo {
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
index 13cfad1c9ae..d47fa2e8482 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
@@ -256,6 +256,36 @@ template<typename ImageBuffer> class PaintingKernel {
}
};
+static void update_triangle_brush_test(SculptSession *ss, Triangles &triangles, const MVert *mvert)
+{
+ triangles.init_brush_test();
+ SculptBrushTest test;
+ SCULPT_brush_test_init(ss, &test);
+ float3 brush_min_bounds(test.location[0] - test.radius,
+ test.location[1] - test.radius,
+ test.location[2] - test.radius);
+ float3 brush_max_bounds(test.location[0] + test.radius,
+ test.location[1] + test.radius,
+ test.location[2] + test.radius);
+ for (int triangle_index = 0; triangle_index < triangles.size(); triangle_index++) {
+ TrianglePaintInput &triangle = triangles.get_paint_input(triangle_index);
+
+ float3 triangle_min_bounds(mvert[triangle.vert_indices[0]].co);
+ float3 triangle_max_bounds(triangle_min_bounds);
+ for (int i = 1; i < 3; i++) {
+ const float3 &pos = mvert[triangle.vert_indices[i]].co;
+ triangle_min_bounds.x = min_ff(triangle_min_bounds.x, pos.x);
+ triangle_min_bounds.y = min_ff(triangle_min_bounds.y, pos.y);
+ triangle_min_bounds.z = min_ff(triangle_min_bounds.z, pos.z);
+ triangle_max_bounds.x = max_ff(triangle_max_bounds.x, pos.x);
+ triangle_max_bounds.y = max_ff(triangle_max_bounds.y, pos.y);
+ triangle_max_bounds.z = max_ff(triangle_max_bounds.z, pos.z);
+ }
+ triangles.brush_test[triangle_index] = isect_aabb_aabb_v3(
+ brush_min_bounds, brush_max_bounds, triangle_min_bounds, triangle_max_bounds);
+ }
+}
+
static void do_paint_pixels(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
@@ -267,9 +297,11 @@ static void do_paint_pixels(void *__restrict userdata,
PBVHNode *node = data->nodes[n];
NodeData &node_data = BKE_pbvh_pixels_node_data_get(*node);
-
const int thread_id = BLI_task_parallel_thread_id(tls);
MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss);
+
+ update_triangle_brush_test(ss, node_data.triangles, mvert);
+
PaintingKernel<ImageBufferFloat4> kernel_float4(ss, brush, thread_id, mvert);
PaintingKernel<ImageBufferByte4> kernel_byte4(ss, brush, thread_id, mvert);
@@ -294,6 +326,9 @@ static void do_paint_pixels(void *__restrict userdata,
}
for (const PackedPixelRow &pixel_row : tile_data.pixel_rows) {
+ if (!node_data.triangles.brush_test[pixel_row.triangle_index]) {
+ continue;
+ }
bool pixels_painted = false;
if (image_buffer->rect_float != nullptr) {
pixels_painted = kernel_float4.paint(node_data.triangles, pixel_row, image_buffer);
More information about the Bf-blender-cvs
mailing list