diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh index dfe8bf8e75e..b85267abf37 100644 --- a/source/blender/blenkernel/BKE_pbvh_pixels.hh +++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh @@ -17,46 +17,9 @@ namespace blender::bke::pbvh::pixels { -/** - * Data shared between pixels that belong to the same triangle. - * - * Data is stored as a list of structs, grouped by usage to improve performance (improves CPU - * cache prefetching). - */ -struct PaintGeometryPrimitives { - /** Data accessed by the inner loop of the painting brush. */ - Vector vert_indices; - - public: - void append(const int3 vert_indices) - { - this->vert_indices.append(vert_indices); - } - - const int3 &get_vert_indices(const int index) const - { - return vert_indices[index]; - } - - void clear() - { - vert_indices.clear(); - } - - int64_t size() const - { - return vert_indices.size(); - } - - int64_t mem_size() const - { - return this->vert_indices.as_span().size_in_bytes(); - } -}; - struct UVPrimitivePaintInput { - /** Corresponding index into PaintGeometryPrimitives */ - int64_t geometry_primitive_index; + /** Corresponding index into triangles */ + int64_t tri_index; /** * Delta barycentric coordinates between 2 neighboring UVs in the U direction. * @@ -70,47 +33,12 @@ struct UVPrimitivePaintInput { * delta_barycentric_coord_u is initialized in a later stage as it requires image tile * dimensions. */ - UVPrimitivePaintInput(int64_t geometry_primitive_index) - : geometry_primitive_index(geometry_primitive_index), delta_barycentric_coord_u(0.0f, 0.0f) + UVPrimitivePaintInput(int64_t tri_index) + : tri_index(tri_index), delta_barycentric_coord_u(0.0f, 0.0f) { } }; -struct PaintUVPrimitives { - /** Data accessed by the inner loop of the painting brush. */ - Vector paint_input; - - void append(int64_t geometry_primitive_index) - { - this->paint_input.append(UVPrimitivePaintInput(geometry_primitive_index)); - } - - UVPrimitivePaintInput &last() - { - return paint_input.last(); - } - - const UVPrimitivePaintInput &get_paint_input(uint64_t index) const - { - return paint_input[index]; - } - - void clear() - { - paint_input.clear(); - } - - int64_t size() const - { - return paint_input.size(); - } - - int64_t mem_size() const - { - return size() * sizeof(UVPrimitivePaintInput); - } -}; - /** * Encode sequential pixels to reduce memory footprint. */ @@ -179,7 +107,7 @@ struct NodeData { Vector tiles; Vector undo_regions; - PaintUVPrimitives uv_primitives; + Vector uv_primitives; NodeData() { @@ -411,14 +339,14 @@ struct CopyPixelTiles { */ struct PBVHData { /* Per UVPRimitive contains the paint data. */ - PaintGeometryPrimitives geom_primitives; + Array vert_tris; /** Per ImageTile the pixels to copy to fix non-manifold bleeding. */ CopyPixelTiles tiles_copy_pixels; void clear_data() { - geom_primitives.clear(); + this->vert_tris = {}; } }; diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index c41eb109e9c..13cf65623e0 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -185,8 +185,8 @@ static void split_pixel_node( UDIMTilePixels *tile1 = &data1->tiles[i]; UDIMTilePixels *tile2 = &data2->tiles[i]; - UVPrimitivePaintInput &uv_prim = data.uv_primitives.paint_input[row.uv_primitive_index]; - int3 tri = pbvh_data.geom_primitives.vert_indices[uv_prim.geometry_primitive_index]; + const UVPrimitivePaintInput uv_prim = data.uv_primitives[row.uv_primitive_index]; + const int3 &tri = pbvh_data.vert_tris[uv_prim.tri_index]; float verts[3][3]; @@ -406,12 +406,9 @@ static void extract_barycentric_pixels(UDIMTilePixels &tile_data, static void update_geom_primitives(Tree &pbvh, const uv_islands::MeshData &mesh_data) { PBVHData &pbvh_data = data_get(pbvh); - pbvh_data.clear_data(); - for (const int3 &tri : mesh_data.corner_tris) { - pbvh_data.geom_primitives.append(int3(mesh_data.corner_verts[tri[0]], - mesh_data.corner_verts[tri[1]], - mesh_data.corner_verts[tri[2]])); - } + pbvh_data.vert_tris.reinitialize(mesh_data.corner_tris.size()); + bke::mesh::vert_tris_from_corner_tris( + mesh_data.corner_verts, mesh_data.corner_tris, pbvh_data.vert_tris); } struct UVPrimitiveLookup { diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index 521df141744..4db300e9336 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -154,18 +154,17 @@ template class PaintingKernel { init_brush_test(); } - bool paint(const PaintGeometryPrimitives &geom_primitives, - const PaintUVPrimitives &uv_primitives, + bool paint(const Span vert_tris, + const Span uv_primitives, const PackedPixelRow &pixel_row, ImBuf *image_buffer, auto_mask::NodeData *automask_data) { image_accessor_.set_image_position(image_buffer, pixel_row.start_image_coordinate); - const UVPrimitivePaintInput paint_input = uv_primitives.get_paint_input( - pixel_row.uv_primitive_index); - float3 pixel_pos = get_start_pixel_pos(geom_primitives, paint_input, pixel_row); + const UVPrimitivePaintInput paint_input = uv_primitives[pixel_row.uv_primitive_index]; + float3 pixel_pos = get_start_pixel_pos(vert_tris, paint_input, pixel_row); const float3 delta_pixel_pos = get_delta_pixel_pos( - geom_primitives, paint_input, pixel_row, pixel_pos); + vert_tris, paint_input, pixel_row, pixel_pos); bool pixels_painted = false; for (int x = 0; x < pixel_row.num_pixels; x++) { if (!brush_test_fn_(test_, pixel_pos)) { @@ -249,35 +248,34 @@ template class PaintingKernel { /** * Extract the starting pixel position from the given encoded_pixels belonging to the triangle. */ - float3 get_start_pixel_pos(const PaintGeometryPrimitives &geom_primitives, + float3 get_start_pixel_pos(const Span vert_tris, const UVPrimitivePaintInput &paint_input, const PackedPixelRow &encoded_pixels) const { - return init_pixel_pos(geom_primitives, paint_input, encoded_pixels.start_barycentric_coord); + return init_pixel_pos(vert_tris, paint_input, encoded_pixels.start_barycentric_coord); } /** * Extract the delta pixel position that will be used to advance a Pixel instance to the next * pixel. */ - float3 get_delta_pixel_pos(const PaintGeometryPrimitives &geom_primitives, + float3 get_delta_pixel_pos(const Span vert_tris, const UVPrimitivePaintInput &paint_input, const PackedPixelRow &encoded_pixels, const float3 &start_pixel) const { - float3 result = init_pixel_pos(geom_primitives, + float3 result = init_pixel_pos(vert_tris, paint_input, encoded_pixels.start_barycentric_coord + paint_input.delta_barycentric_coord_u); return result - start_pixel; } - float3 init_pixel_pos(const PaintGeometryPrimitives &geom_primitives, + float3 init_pixel_pos(const Span vert_tris, const UVPrimitivePaintInput &paint_input, const float2 &barycentric_weights) const { - const int3 &vert_indices = geom_primitives.get_vert_indices( - paint_input.geometry_primitive_index); + const int3 &vert_indices = vert_tris[paint_input.tri_index]; float3 result; const float3 barycentric(barycentric_weights.x, barycentric_weights.y, @@ -292,8 +290,8 @@ template class PaintingKernel { }; static BitVector<> init_uv_primitives_brush_test(SculptSession &ss, - PaintGeometryPrimitives &geom_primitives, - PaintUVPrimitives &uv_primitives, + const Span vert_tris, + const Span uv_primitives, const Span positions) { BitVector<> brush_test(uv_primitives.size()); @@ -305,10 +303,9 @@ static BitVector<> init_uv_primitives_brush_test(SculptSession &ss, float3 brush_max_bounds(test.location[0] + test.radius, test.location[1] + test.radius, test.location[2] + test.radius); - for (int uv_prim_index = 0; uv_prim_index < uv_primitives.size(); uv_prim_index++) { - const UVPrimitivePaintInput &paint_input = uv_primitives.get_paint_input(uv_prim_index); - const int3 &vert_indices = geom_primitives.get_vert_indices( - paint_input.geometry_primitive_index); + for (const int i : uv_primitives.index_range()) { + const UVPrimitivePaintInput &paint_input = uv_primitives[i]; + const int3 &vert_indices = vert_tris[paint_input.tri_index]; float3 triangle_min_bounds(positions[vert_indices[0]]); float3 triangle_max_bounds(triangle_min_bounds); @@ -321,7 +318,7 @@ static BitVector<> init_uv_primitives_brush_test(SculptSession &ss, triangle_max_bounds.y = max_ff(triangle_max_bounds.y, pos.y); triangle_max_bounds.z = max_ff(triangle_max_bounds.z, pos.z); } - brush_test[uv_prim_index].set(isect_aabb_aabb_v3( + brush_test[i].set(isect_aabb_aabb_v3( brush_min_bounds, brush_max_bounds, triangle_min_bounds, triangle_max_bounds)); } return brush_test; @@ -340,7 +337,7 @@ static void do_paint_pixels(TexturePaintingUserData *data, const int n) const Span positions = SCULPT_mesh_deformed_positions_get(ss); BitVector<> brush_test = init_uv_primitives_brush_test( - ss, pbvh_data.geom_primitives, node_data.uv_primitives, positions); + ss, pbvh_data.vert_tris, node_data.uv_primitives, positions); PaintingKernel kernel_float4(ss, brush, thread_id, positions); PaintingKernel kernel_byte4(ss, brush, thread_id, positions); @@ -390,14 +387,14 @@ static void do_paint_pixels(TexturePaintingUserData *data, const int n) } bool pixels_painted = false; if (image_buffer->float_buffer.data != nullptr) { - pixels_painted = kernel_float4.paint(pbvh_data.geom_primitives, + pixels_painted = kernel_float4.paint(pbvh_data.vert_tris, node_data.uv_primitives, pixel_row, image_buffer, &automask_data); } else { - pixels_painted = kernel_byte4.paint(pbvh_data.geom_primitives, + pixels_painted = kernel_byte4.paint(pbvh_data.vert_tris, node_data.uv_primitives, pixel_row, image_buffer,