[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