diff options
Diffstat (limited to 'source/blender/blenkernel/intern/paint_canvas.cc')
-rw-r--r-- | source/blender/blenkernel/intern/paint_canvas.cc | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/paint_canvas.cc b/source/blender/blenkernel/intern/paint_canvas.cc new file mode 100644 index 00000000000..b72418d88c0 --- /dev/null +++ b/source/blender/blenkernel/intern/paint_canvas.cc @@ -0,0 +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; + +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: + break; + + case PAINT_CANVAS_SOURCE_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; + } + + *r_image = slot->ima; + *r_image_user = slot->image_user; + break; + } + } + 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()); +} +} |