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:
authorJeroen Bakker <jbakker>2022-04-08 17:37:35 +0300
committerJeroen Bakker <jeroen@blender.org>2022-04-08 17:42:50 +0300
commit8b7cd1ed2a17e40661101eea4adae99e8e3d02e9 (patch)
tree8c3f1f2a14d699fad0367ce529254f2efb517acf /source/blender/editors/sculpt_paint
parent63d2980efa2fb170b471e4905ec81cd1472e5268 (diff)
Painting: Canvas switcher for painting brushes/tools.
This patch adds color attributes to TexPaintSlot. This allows an easier selection when painting color attributes. Previously when selecting a paint tool the user had to start a stroke, before the UI reflected the correct TexPaintSlot. Now when switching the slot the active tool is checked and immediate the UI is drawn correctly. In the future the canvas selector will also be used to select an image or image texture node to paint on. Basic implementation has already been done inside this patch. A limitation of this patch is that is isn't possible anymore to rename images directly from the selection panel. This is currently allowed in master. But as CustomDataLayers aren't ID fields and not owned by the material supporting this wouldn't be easy. {F12953989} In the future we should update the create slot operator to also include color attributes. Sources could also be extended to use other areas of the object that use image textures (particles, geom nodes, etc... ). Reviewed By: brecht Maniphest Tasks: T96709 Differential Revision: https://developer.blender.org/D14455
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt1
-rw-r--r--source/blender/editors/sculpt_paint/paint_canvas.cc203
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c5
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_color.c2
6 files changed, 216 insertions, 5 deletions
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index fe7683d12f5..b89cbcf87fa 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -34,6 +34,7 @@ set(SRC
curves_sculpt_grow_shrink.cc
curves_sculpt_ops.cc
curves_sculpt_snake_hook.cc
+ paint_canvas.cc
paint_cursor.c
paint_curve.c
paint_curve_undo.c
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;
+}
+}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 233cfc3b33d..1303da71435 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -6336,7 +6336,7 @@ bool ED_paint_proj_mesh_data_check(
hasmat = true;
if (ma->texpaintslot == NULL) {
/* refresh here just in case */
- BKE_texpaint_slot_refresh_cache(scene, ma);
+ BKE_texpaint_slot_refresh_cache(scene, ma, ob);
}
if (ma->texpaintslot != NULL &&
(ma->texpaintslot[ma->paint_active_slot].ima == NULL ||
@@ -6607,7 +6607,7 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
nodePositionPropagate(out_node);
if (ima) {
- BKE_texpaint_slot_refresh_cache(scene, ma);
+ BKE_texpaint_slot_refresh_cache(scene, ma, ob);
BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE);
WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima);
}
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 4b5ac51a525..3f26f590b70 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -281,7 +281,7 @@ static void imapaint_pick_uv(
float p[2], w[3], absw, minabsw;
float matrix[4][4], proj[4][4];
int view[4];
- const eImagePaintMode mode = scene->toolsettings->imapaint.mode;
+ const ePaintCanvasSource mode = scene->toolsettings->imapaint.mode;
const MLoopTri *lt = BKE_mesh_runtime_looptri_ensure(me_eval);
const int tottri = me_eval->runtime.looptris.len;
@@ -317,7 +317,7 @@ static void imapaint_pick_uv(
copy_v3_v3(tri_co[j], mvert[mloop[lt->tri[j]].v].co);
}
- if (mode == IMAGEPAINT_MODE_MATERIAL) {
+ if (mode == PAINT_CANVAS_SOURCE_MATERIAL) {
const Material *ma;
const TexPaintSlot *slot;
@@ -431,7 +431,7 @@ void paint_sample_color(
Material *ma = BKE_object_material_get(ob_eval, mp->mat_nr + 1);
/* Force refresh since paint slots are not updated when changing interpolation. */
- BKE_texpaint_slot_refresh_cache(scene, ma);
+ BKE_texpaint_slot_refresh_cache(scene, ma, ob);
if (ma && ma->texpaintslot) {
image = ma->texpaintslot[ma->paint_active_slot].ima;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index e03f12025c8..24c5a9fce52 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -70,6 +70,7 @@
#include "WM_types.h"
#include "ED_object.h"
+#include "ED_paint.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
#include "ED_view3d.h"
@@ -4991,6 +4992,8 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op)
* earlier steps modifying the data. */
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
BKE_sculpt_update_object_for_edit(depsgraph, ob, need_pmap, need_mask, needs_colors);
+
+ ED_paint_tool_update_sticky_shading_color(C, ob);
}
static void sculpt_restore_mesh(Sculpt *sd, Object *ob)
@@ -5191,6 +5194,8 @@ static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const f
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
+ /* NOTE: This should be removed when paint mode is available. Paint mode can force based on the
+ * canvas it is painting on. (ref. use_sculpt_texture_paint). */
if (brush && SCULPT_TOOL_NEEDS_COLOR(brush->sculpt_tool)) {
View3D *v3d = CTX_wm_view3d(C);
if (v3d) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
index cbb9180a209..e4180a36a98 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
@@ -36,6 +36,7 @@
#include "WM_types.h"
#include "ED_object.h"
+#include "ED_paint.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
#include "paint_intern.h"
@@ -293,6 +294,7 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent
FilterCache *filter_cache = ss->filter_cache;
filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
filter_cache->automasking = SCULPT_automasking_cache_init(sd, NULL, ob);
+ ED_paint_tool_update_sticky_shading_color(C, ob);
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;