Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_canvas.cc')
-rw-r--r--source/blender/editors/sculpt_paint/paint_canvas.cc203
1 files changed, 203 insertions, 0 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_canvas.cc b/source/blender/editors/sculpt_paint/paint_canvas.cc
new file mode 100644
index 00000000000..9a1a61cf3ab
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/paint_canvas.cc
@@ -0,0 +1,203 @@
+/* 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_node_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_workspace_types.h"
+
+#include "BKE_context.h"
+#include "BKE_customdata.h"
+#include "BKE_material.h"
+#include "BKE_paint.h"
+#include "BKE_pbvh.h"
+
+#include "DEG_depsgraph.h"
+
+#include "NOD_shader.h"
+
+#include "WM_toolsystem.h"
+
+namespace blender::ed::sculpt_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::ed::sculpt_paint::canvas
+
+extern "C" {
+
+using namespace blender;
+using namespace blender::ed::sculpt_paint::canvas;
+
+/* Does the paint tool with the given idname uses a canvas. */
+static bool paint_tool_uses_canvas(StringRef idname)
+{
+ return ELEM(idname, "builtin_brush.Paint", "builtin_brush.Smear", "builtin.color_filter");
+}
+
+static bool paint_tool_shading_color_follows_last_used(StringRef idname)
+{
+ /* TODO(jbakker): complete this list. */
+ return ELEM(idname, "builtin_brush.Mask");
+}
+
+void ED_paint_tool_update_sticky_shading_color(struct bContext *C, struct Object *ob)
+{
+ if (ob == nullptr || ob->sculpt == nullptr) {
+ return;
+ }
+
+ bToolRef *tref = WM_toolsystem_ref_from_context(C);
+ if (tref == nullptr) {
+ return;
+ }
+ /* Do not modify when tool follows lat used tool. */
+ if (paint_tool_shading_color_follows_last_used(tref->idname)) {
+ return;
+ }
+
+ ob->sculpt->sticky_shading_color = paint_tool_uses_canvas(tref->idname);
+}
+
+static bool paint_tool_shading_color_follows_last_used_tool(struct bContext *C, struct Object *ob)
+{
+ if (ob == nullptr || ob->sculpt == nullptr) {
+ return false;
+ }
+
+ bToolRef *tref = WM_toolsystem_ref_from_context(C);
+ if (tref == nullptr) {
+ return false;
+ }
+
+ return paint_tool_shading_color_follows_last_used(tref->idname);
+}
+
+bool ED_paint_tool_use_canvas(struct bContext *C, bToolRef *tref)
+{
+ if (tref == nullptr) {
+ tref = WM_toolsystem_ref_from_context(C);
+ }
+ if (tref == nullptr) {
+ return false;
+ }
+
+ return paint_tool_uses_canvas(tref->idname);
+}
+
+eV3DShadingColorType ED_paint_shading_color_override(bContext *C,
+ const PaintModeSettings *settings,
+ Object *ob,
+ eV3DShadingColorType orig_color_type)
+{
+ if (!U.experimental.use_sculpt_texture_paint) {
+ return orig_color_type;
+ }
+ /* NOTE: This early exit is temporarily, until a paint mode has been added.
+ * For better integration with the vertex paint in sculpt mode we sticky
+ * with the last stoke when using tools like masking.
+ */
+ if (!ED_paint_tool_use_canvas(C, nullptr) &&
+ !(paint_tool_shading_color_follows_last_used_tool(C, ob) &&
+ ob->sculpt->sticky_shading_color)) {
+ return orig_color_type;
+ }
+
+ eV3DShadingColorType color_type = orig_color_type;
+ switch (settings->canvas_source) {
+ case PAINT_CANVAS_SOURCE_COLOR_ATTRIBUTE:
+ color_type = V3D_SHADING_VERTEX_COLOR;
+ break;
+ case PAINT_CANVAS_SOURCE_IMAGE:
+ color_type = V3D_SHADING_TEXTURE_COLOR;
+ break;
+ case PAINT_CANVAS_SOURCE_MATERIAL: {
+ TexPaintSlot *slot = get_active_slot(ob);
+ if (slot == nullptr) {
+ break;
+ }
+
+ if (slot->ima) {
+ color_type = V3D_SHADING_TEXTURE_COLOR;
+ }
+ if (slot->attribute_name) {
+ color_type = V3D_SHADING_VERTEX_COLOR;
+ }
+
+ break;
+ }
+ }
+
+ return color_type;
+}
+
+Image *ED_paint_canvas_image_get(const struct PaintModeSettings *settings, struct Object *ob)
+{
+ switch (settings->canvas_source) {
+ case PAINT_CANVAS_SOURCE_COLOR_ATTRIBUTE:
+ return nullptr;
+ case PAINT_CANVAS_SOURCE_IMAGE:
+ return settings->canvas_image;
+ case PAINT_CANVAS_SOURCE_MATERIAL: {
+ TexPaintSlot *slot = get_active_slot(ob);
+ if (slot == nullptr) {
+ break;
+ }
+ return slot->ima;
+ }
+ }
+ return nullptr;
+}
+
+int ED_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;
+}
+}