[Bf-blender-cvs] [c6da2a827fd] temp-T96710-pbvh-pixels: Merge branch 'master' into temp-T96710-pbvh-pixels
Jeroen Bakker
noreply at git.blender.org
Wed Apr 13 14:46:06 CEST 2022
Commit: c6da2a827fdfbda6b3f3a7b42443fe8f37b32879
Author: Jeroen Bakker
Date: Wed Apr 13 14:45:56 2022 +0200
Branches: temp-T96710-pbvh-pixels
https://developer.blender.org/rBc6da2a827fdfbda6b3f3a7b42443fe8f37b32879
Merge branch 'master' into temp-T96710-pbvh-pixels
===================================================================
===================================================================
diff --cc source/blender/blenkernel/BKE_paint.h
index ca9c88d771d,db773d34cdc..4ae37095411
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@@ -30,7 -30,7 +30,9 @@@ struct EdgeSet
struct EnumPropertyItem;
struct GHash;
struct GridPaintMask;
++struct Image;
struct ImagePool;
++struct ImageUser;
struct ListBase;
struct MLoop;
struct MLoopTri;
@@@ -730,6 -726,12 +733,20 @@@ enum
SCULPT_MASK_LAYER_CALC_LOOP = (1 << 1),
};
+ /* paint_canvas.cc */
-struct Image *BKE_paint_canvas_image_get(const struct PaintModeSettings *settings,
- struct Object *ob);
++/**
++ * Create a key that can be used to compare with previous ones to identify changes.
++ * The resulting 'string' is owned by the caller.
++ */
++char *BKE_paint_canvas_key_get(struct PaintModeSettings *settings, struct Object *ob);
++
++bool BKE_paint_canvas_image_get(struct PaintModeSettings *settings,
++ struct Object *ob,
++ struct Image **r_image,
++ struct ImageUser **r_image_user);
+ int BKE_paint_canvas_uvmap_layer_index_get(const struct PaintModeSettings *settings,
+ struct Object *ob);
+
#ifdef __cplusplus
}
#endif
diff --cc source/blender/blenkernel/intern/paint.c
index f75c5c58709,eb3f47760fc..f1eec157dee
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@@ -1776,24 -1771,6 +1776,24 @@@ static void sculpt_update_object(Depsgr
}
}
+ /*
+ * We should rebuild the PBVH_pixels when painting canvas changes.
+ *
+ * The relevant changes are stored/encoded in the paint canvas key.
+ * These include the active uv map, and resolutions.
+ */
+ if (U.experimental.use_sculpt_texture_paint && ss->pbvh) {
- char *paint_canvas_key = ED_paint_canvas_key_get(&scene->toolsettings->paint_mode, ob);
++ char *paint_canvas_key = BKE_paint_canvas_key_get(&scene->toolsettings->paint_mode, ob);
+ if (ss->last_paint_canvas_key == NULL || !STREQ(paint_canvas_key, ss->last_paint_canvas_key)) {
+ MEM_SAFE_FREE(ss->last_paint_canvas_key);
+ ss->last_paint_canvas_key = paint_canvas_key;
+ BKE_pbvh_mark_rebuild_pixels(ss->pbvh);
+ }
+ else {
+ MEM_freeN(paint_canvas_key);
+ }
+ }
+
/* We could be more precise when we have access to the active tool. */
const bool use_paint_slots = (ob->mode & OB_MODE_SCULPT) != 0;
if (use_paint_slots) {
diff --cc source/blender/blenkernel/intern/paint_canvas.cc
index 00000000000,c1145164642..b72418d88c0
mode 000000,100644..100644
--- a/source/blender/blenkernel/intern/paint_canvas.cc
+++ b/source/blender/blenkernel/intern/paint_canvas.cc
@@@ -1,0 -1,90 +1,131 @@@
+ /* SPDX-License-Identifier: GPL-2.0-or-later */
+ #include "BLI_compiler_compat.h"
+
+ #include "DNA_material_types.h"
+ #include "DNA_mesh_types.h"
+ #include "DNA_scene_types.h"
+
+ #include "BKE_customdata.h"
++#include "BKE_image.h"
+ #include "BKE_material.h"
+ #include "BKE_paint.h"
+
++#include "IMB_imbuf_types.h"
++
+ namespace blender::bke::paint::canvas {
+ static TexPaintSlot *get_active_slot(Object *ob)
+ {
+ Material *mat = BKE_object_material_get(ob, ob->actcol);
+ if (mat == nullptr) {
+ return nullptr;
+ }
+ if (mat->texpaintslot == nullptr) {
+ return nullptr;
+ }
+ if (mat->paint_active_slot >= mat->tot_slots) {
+ return nullptr;
+ }
+
+ TexPaintSlot *slot = &mat->texpaintslot[mat->paint_active_slot];
+ return slot;
+ }
+
+ } // namespace blender::bke::paint::canvas
+
+ extern "C" {
+
+ using namespace blender::bke::paint::canvas;
+
-Image *BKE_paint_canvas_image_get(const struct PaintModeSettings *settings, struct Object *ob)
++bool BKE_paint_canvas_image_get(PaintModeSettings *settings,
++ Object *ob,
++ Image **r_image,
++ ImageUser **r_image_user)
+ {
++ *r_image = nullptr;
++ *r_image_user = nullptr;
++
+ switch (settings->canvas_source) {
+ case PAINT_CANVAS_SOURCE_COLOR_ATTRIBUTE:
- return nullptr;
++ break;
++
+ case PAINT_CANVAS_SOURCE_IMAGE:
- return settings->canvas_image;
++ *r_image = settings->canvas_image;
++ *r_image_user = &settings->image_user;
++ break;
++
+ case PAINT_CANVAS_SOURCE_MATERIAL: {
+ TexPaintSlot *slot = get_active_slot(ob);
+ if (slot == nullptr) {
+ break;
+ }
- return slot->ima;
++
++ *r_image = slot->ima;
++ *r_image_user = slot->image_user;
++ break;
+ }
+ }
- return nullptr;
++ return *r_image != nullptr;
+ }
+
+ int BKE_paint_canvas_uvmap_layer_index_get(const struct PaintModeSettings *settings,
+ struct Object *ob)
+ {
+ switch (settings->canvas_source) {
+ case PAINT_CANVAS_SOURCE_COLOR_ATTRIBUTE:
+ return -1;
+ case PAINT_CANVAS_SOURCE_IMAGE: {
+ /* Use active uv map of the object. */
+ if (ob->type != OB_MESH) {
+ return -1;
+ }
+
+ const Mesh *mesh = static_cast<Mesh *>(ob->data);
+ return CustomData_get_active_layer_index(&mesh->ldata, CD_MLOOPUV);
+ }
+ case PAINT_CANVAS_SOURCE_MATERIAL: {
+ /* Use uv map of the canvas. */
+ TexPaintSlot *slot = get_active_slot(ob);
+ if (slot == nullptr) {
+ break;
+ }
+
+ if (ob->type != OB_MESH) {
+ return -1;
+ }
+
+ if (slot->uvname == nullptr) {
+ return -1;
+ }
+
+ const Mesh *mesh = static_cast<Mesh *>(ob->data);
+ return CustomData_get_named_layer_index(&mesh->ldata, CD_MLOOPUV, slot->uvname);
+ }
+ }
+ return -1;
+ }
++
++char *BKE_paint_canvas_key_get(struct PaintModeSettings *settings, struct Object *ob)
++{
++ std::stringstream ss;
++ int active_uv_map_layer_index = BKE_paint_canvas_uvmap_layer_index_get(settings, ob);
++ ss << "UV_MAP:" << active_uv_map_layer_index;
++
++ Image *image;
++ ImageUser *image_user;
++ if (BKE_paint_canvas_image_get(settings, ob, &image, &image_user)) {
++ ImageUser tile_user = *image_user;
++ LISTBASE_FOREACH (ImageTile *, image_tile, &image->tiles) {
++ tile_user.tile = image_tile->tile_number;
++ ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &tile_user, nullptr);
++ if (!image_buffer) {
++ continue;
++ }
++ ss << ",TILE_" << image_tile->tile_number;
++ ss << "(" << image_buffer->x << "," << image_buffer->y << ")";
++ BKE_image_release_ibuf(image, image_buffer, nullptr);
++ }
++ }
++
++ return BLI_strdup(ss.str().c_str());
++}
+ }
diff --cc source/blender/editors/sculpt_paint/sculpt_paint_image.cc
index d47fa2e8482,00000000000..7b6d6091dce
mode 100644,000000..100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc
@@@ -1,422 -1,0 +1,422 @@@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+#include "DNA_image_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+
+#include "ED_paint.h"
+#include "ED_uvedit.h"
+
+#include "BLI_math.h"
+#include "BLI_math_color_blend.h"
+#include "BLI_task.h"
+
+#include "IMB_colormanagement.h"
+#include "IMB_imbuf.h"
+
+#include "BKE_brush.h"
+#include "BKE_image_wrappers.hh"
+#include "BKE_material.h"
+#include "BKE_pbvh.h"
+#include "BKE_pbvh_pixels.hh"
+
+#include "bmesh.h"
+
+#include "NOD_shader.h"
+
+#include "sculpt_intern.h"
+
+namespace blender::ed::sculpt_paint::paint::image {
+
+using namespace blender::bke::pbvh::pixels;
+using namespace blender::bke::image;
+
+struct ImageData {
+ void *lock = nullptr;
+ Image *image = nullptr;
+ ImageUser *image_user = nullptr;
+
+ ~ImageData()
+ {
+ }
+
+ static bool init_active_image(Object *ob,
+ ImageData *r_image_data,
+ PaintModeSettings *paint_mode_settings)
+ {
- return ED_paint_canvas_image_get(
++ return BKE_paint_canvas_image_get(
+ paint_mode_settings, ob, &r_image_data->image, &r_image_data->image_user);
+ }
+};
+
+struct TexturePaintingUserData {
+ Object *ob;
+ Brush *brush;
+ PBVHNode **nodes;
+ ImageData image_data;
+};
+
+/** Reading and writing to image buffer with 4 float channels. */
+class ImageBufferFloat4 {
+ private:
+ int pixel_offset;
+
+ public:
+ void set_image_position(ImBuf *image_buffer, ushort2 image_pixel_position)
+ {
+ pixel_offset = int(image_pixel_position.y) * image_buffer->x + int(image_pixel_position.x);
+ }
+
+ void next_pixel()
+ {
+ pixel_offset += 1;
+ }
+
+ float4 read_pixel(ImBuf *image_buffer) const
+ {
+ return &image_buffer->rect_float[pixel_offset * 4];
+ }
+
+ void write_pixel(ImBuf *image_buffer, const float4 pixel_data) const
+ {
+ copy_v4_v4(&image_buffer->rect_float[pixel_offset * 4], pixel_data);
+ }
+
+ const char *get_colorspace_name(ImBuf *image_buffer)
+ {
+ return IMB_colormanagement_get_float_colorspace(image_buffer);
+ }
+};
+
+/** Reading and writing to image buffer with 4 byte channels. */
+class ImageBufferByte4 {
+ private:
+ int pixel_offset;
+
+ public:
+ void set_image_position(ImBuf *image_buffer, ushort2 image_pixel_position)
+ {
+ pixel_offset = int(image_pixel_position.y) * image_buffer->x + int(image_pixel_position.x);
+ }
+
+ void next_pixel()
+ {
+ pixel_offset += 1;
+ }
+
+ float4 read_pixel(ImBuf *image_buffer) const
+ {
+ float4 result;
+ rgba_uchar_to_float(result,
+ static_cast<const uchar *>(
+ static_cast<const void *>(&(image_buffer->rect[pixel_offset]))));
+ return result;
+ }
+
+ void write_pixel(ImBuf *image_buffer, const float4 pixel_data) const
+ {
+ rgba_float_to_uchar(
+ static_cast<uchar *>(static_cast
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list