GPencil: New Eyedropper tool for Material creation.

This patch is only for the eyedropper to create materials.

Options:
Click: Create Stroke Material
Shift+Click: Create Fill Material.
Shift+Ctrl+Click: Create Stroke and Fill Material.

Toolbar:

{F7718606}

Reviewed By: brecht, mendio

Differential Revision: https://developer.blender.org/D5688
This commit is contained in:
Antonio Vazquez 2019-10-11 13:28:22 +02:00 committed by Antonio Vazquez
parent ec295c1168
commit 5adb3b6882
Notes: blender-bot 2023-09-11 20:36:20 +02:00
Referenced by issue #111736, Grease Pencil: Add eyedropper to palette popup
7 changed files with 356 additions and 0 deletions

View File

@ -5869,6 +5869,18 @@ def km_3d_view_tool_paint_gpencil_cutter(params):
)
def km_3d_view_tool_paint_gpencil_eyedropper(params):
return (
"3D View Tool: Paint Gpencil, Eyedropper",
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
("ui.eyedropper_gpencil_color", {"type": params.tool_mouse, "value": 'PRESS'}, None),
("ui.eyedropper_gpencil_color", {"type": params.tool_mouse, "value": 'PRESS', "shift": True}, None),
("ui.eyedropper_gpencil_color", {"type": params.tool_mouse, "value": 'PRESS', "shift": True, "ctrl": True}, None),
]},
)
def km_3d_view_tool_edit_gpencil_select(params):
return (
"3D View Tool: Edit Gpencil, Tweak",
@ -6206,6 +6218,7 @@ def generate_keymaps(params=None):
km_3d_view_tool_paint_gpencil_arc(params),
km_3d_view_tool_paint_gpencil_curve(params),
km_3d_view_tool_paint_gpencil_cutter(params),
km_3d_view_tool_paint_gpencil_eyedropper(params),
km_3d_view_tool_edit_gpencil_select(params),
km_3d_view_tool_edit_gpencil_select_box(params),
km_3d_view_tool_edit_gpencil_select_circle(params),

View File

@ -1393,6 +1393,17 @@ class _defs_gpencil_paint:
)
@ToolDef.from_fn
def eyedropper():
return dict(
idname="builtin.eyedropper",
label="Eyedropper",
icon="ops.paint.weight_sample",
cursor='EYEDROPPER',
widget=None,
keymap=(),
)
class _defs_gpencil_edit:
@ToolDef.from_fn
def bend():
@ -2044,6 +2055,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
_defs_gpencil_paint.generate_from_brushes,
_defs_gpencil_paint.cutter,
None,
_defs_gpencil_paint.eyedropper,
None,
_defs_gpencil_paint.line,
_defs_gpencil_paint.arc,
_defs_gpencil_paint.curve,

View File

@ -50,6 +50,7 @@ set(SRC
interface_eyedropper_datablock.c
interface_eyedropper_depth.c
interface_eyedropper_driver.c
interface_eyedropper_gpencil_color.c
interface_handlers.c
interface_icons.c
interface_icons_event.c

View File

@ -69,6 +69,7 @@ wmKeyMap *eyedropper_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_id");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_depth");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_driver");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_gpencil_color");
return keymap;
}

View File

@ -0,0 +1,324 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2009 Blender Foundation.
* All rights reserved.
*/
/** \file
* \ingroup edinterface
*
* Eyedropper (RGB Color)
*
* Defines:
* - #UI_OT_eyedropper_gpencil_color
*/
#include "MEM_guardedalloc.h"
#include "BLI_string.h"
#include "BLT_translation.h"
#include "DNA_gpencil_types.h"
#include "DNA_space_types.h"
#include "BKE_context.h"
#include "BKE_gpencil.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_report.h"
#include "UI_interface.h"
#include "IMB_colormanagement.h"
#include "WM_api.h"
#include "WM_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "ED_gpencil.h"
#include "ED_screen.h"
#include "ED_undo.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "interface_eyedropper_intern.h"
typedef struct EyedropperGPencil {
struct ColorManagedDisplay *display;
/** color under cursor RGB */
float color[3];
} EyedropperGPencil;
/* Helper: Draw status message while the user is running the operator */
static void eyedropper_gpencil_status_indicators(bContext *C, EyedropperGPencil *eye)
{
char msg_str[UI_MAX_DRAW_STR];
BLI_strncpy(
msg_str, TIP_("LMB: Stroke - Shift: Fill - Shift+Ctrl: Stroke + Fill"), UI_MAX_DRAW_STR);
ED_workspace_status_text(C, msg_str);
}
/* Initialize. */
static bool eyedropper_gpencil_init(bContext *C, wmOperator *op)
{
EyedropperGPencil *eye = MEM_callocN(sizeof(EyedropperGPencil), __func__);
op->customdata = eye;
Scene *scene = CTX_data_scene(C);
const char *display_device;
display_device = scene->display_settings.display_device;
eye->display = IMB_colormanagement_display_get_named(display_device);
return true;
}
/* Exit and free memory. */
static void eyedropper_gpencil_exit(bContext *C, wmOperator *op)
{
/* Clear status message area. */
ED_workspace_status_text(C, NULL);
MEM_SAFE_FREE(op->customdata);
}
/* Set the material. */
static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, EyedropperGPencil *eye)
{
Main *bmain = CTX_data_main(C);
Object *ob = CTX_data_active_object(C);
Material *ma = NULL;
const bool only_stroke = ((!event->ctrl) && (!event->shift));
const bool only_fill = ((!event->ctrl) && (event->shift));
const bool both = ((event->ctrl) && (event->shift));
float col_conv[4];
bool found = false;
/* Convert from linear rgb space to display space because grease pencil colors are in display
* space, and this conversion is needed to undo the conversion to linear performed by
* eyedropper_color_sample_fl. */
if (eye->display) {
copy_v3_v3(col_conv, eye->color);
IMB_colormanagement_scene_linear_to_display_v3(col_conv, eye->display);
}
else {
copy_v3_v3(col_conv, eye->color);
}
/* Look for a similar material in grease pencil slots. */
short *totcol = give_totcolp(ob);
for (short i = 0; i < *totcol; i++) {
ma = give_current_material(ob, i + 1);
if (ma == NULL) {
continue;
}
MaterialGPencilStyle *gp_style = ma->gp_style;
if (gp_style != NULL) {
/* Check stroke color. */
bool found_stroke = compare_v3v3(gp_style->stroke_rgba, col_conv, 0.01f) &&
(gp_style->flag & GP_STYLE_STROKE_SHOW);
/* Check fill color. */
bool found_fill = compare_v3v3(gp_style->fill_rgba, col_conv, 0.01f) &&
(gp_style->flag & GP_STYLE_FILL_SHOW);
if ((only_stroke) && (found_stroke) && ((gp_style->flag & GP_STYLE_FILL_SHOW) == 0)) {
found = true;
}
else if ((only_fill) && (found_fill) && ((gp_style->flag & GP_STYLE_STROKE_SHOW) == 0)) {
found = true;
}
else if ((both) && (found_stroke) && (found_fill)) {
found = true;
}
/* Found existing material. */
if (found) {
ob->actcol = i + 1;
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_LINKS, NULL);
WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, NULL);
return;
}
}
}
/* If material was not found add a new material with stroke and/or fill color
* depending of the secondary key (LMB: Stroke, Shift: Fill, Shift+Ctrl: Stroke/Fill)
*/
int idx;
Material *ma_new = BKE_gpencil_object_material_new(bmain, ob, "Material", &idx);
WM_main_add_notifier(NC_OBJECT | ND_OB_SHADING, &ob->id);
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_LINKS, NULL);
DEG_relations_tag_update(bmain);
BLI_assert(ma_new != NULL);
MaterialGPencilStyle *gp_style_new = ma_new->gp_style;
BLI_assert(gp_style_new != NULL);
/* Only create Stroke (default option). */
if (only_stroke) {
/* Stroke color. */
gp_style_new->flag |= GP_STYLE_STROKE_SHOW;
gp_style_new->flag &= ~GP_STYLE_FILL_SHOW;
copy_v3_v3(gp_style_new->stroke_rgba, col_conv);
zero_v4(gp_style_new->fill_rgba);
}
/* Fill Only. */
else if (only_fill) {
/* Fill color. */
gp_style_new->flag &= ~GP_STYLE_STROKE_SHOW;
gp_style_new->flag |= GP_STYLE_FILL_SHOW;
zero_v4(gp_style_new->stroke_rgba);
copy_v3_v3(gp_style_new->fill_rgba, col_conv);
}
/* Stroke and Fill. */
else if (both) {
gp_style_new->flag |= GP_STYLE_STROKE_SHOW | GP_STYLE_FILL_SHOW;
copy_v3_v3(gp_style_new->stroke_rgba, col_conv);
copy_v3_v3(gp_style_new->fill_rgba, col_conv);
}
/* Push undo for new created material. */
ED_undo_push(C, "Add Grease Pencil Material");
}
/* Sample the color below cursor. */
static void eyedropper_gpencil_color_sample(bContext *C, EyedropperGPencil *eye, int mx, int my)
{
eyedropper_color_sample_fl(C, mx, my, eye->color);
}
/* Cancel operator. */
static void eyedropper_gpencil_cancel(bContext *C, wmOperator *op)
{
eyedropper_gpencil_exit(C, op);
}
/* Main modal status check. */
static int eyedropper_gpencil_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
EyedropperGPencil *eye = (EyedropperGPencil *)op->customdata;
/* Handle modal keymap */
switch (event->type) {
case EVT_MODAL_MAP: {
switch (event->val) {
case EYE_MODAL_SAMPLE_BEGIN: {
return OPERATOR_RUNNING_MODAL;
}
case EYE_MODAL_CANCEL: {
eyedropper_gpencil_cancel(C, op);
return OPERATOR_CANCELLED;
}
case EYE_MODAL_SAMPLE_CONFIRM: {
eyedropper_gpencil_color_sample(C, eye, event->x, event->y);
/* Create material. */
eyedropper_gpencil_color_set(C, event, eye);
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
eyedropper_gpencil_exit(C, op);
return OPERATOR_FINISHED;
break;
}
default: {
break;
}
}
break;
}
case MOUSEMOVE:
case INBETWEEN_MOUSEMOVE: {
eyedropper_gpencil_color_sample(C, eye, event->x, event->y);
break;
}
default: {
break;
}
}
return OPERATOR_RUNNING_MODAL;
}
/* Modal Operator init */
static int eyedropper_gpencil_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* Init. */
if (eyedropper_gpencil_init(C, op)) {
/* Add modal temp handler. */
WM_event_add_modal_handler(C, op);
/* Status message. */
EyedropperGPencil *eye = (EyedropperGPencil *)op->customdata;
eyedropper_gpencil_status_indicators(C, eye);
return OPERATOR_RUNNING_MODAL;
}
else {
return OPERATOR_PASS_THROUGH;
}
}
/* Repeat operator */
static int eyedropper_gpencil_exec(bContext *C, wmOperator *op)
{
/* init */
if (eyedropper_gpencil_init(C, op)) {
/* cleanup */
eyedropper_gpencil_exit(C, op);
return OPERATOR_FINISHED;
}
else {
return OPERATOR_PASS_THROUGH;
}
}
static bool eyedropper_gpencil_poll(bContext *C)
{
/* Only valid if the current active object is grease pencil. */
Object *obact = CTX_data_active_object(C);
if ((obact == NULL) || (obact->type != OB_GPENCIL)) {
return false;
}
/* Test we have a window below. */
return (CTX_wm_window(C) != NULL);
}
void UI_OT_eyedropper_gpencil_color(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Grease Pencil Eyedropper";
ot->idname = "UI_OT_eyedropper_gpencil_color";
ot->description = "Sample a color from the Blender Window and create Grease Pencil material";
/* api callbacks */
ot->invoke = eyedropper_gpencil_invoke;
ot->modal = eyedropper_gpencil_modal;
ot->cancel = eyedropper_gpencil_cancel;
ot->exec = eyedropper_gpencil_exec;
ot->poll = eyedropper_gpencil_poll;
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
}

View File

@ -971,6 +971,9 @@ void UI_OT_eyedropper_depth(struct wmOperatorType *ot);
/* interface_eyedropper_driver.c */
void UI_OT_eyedropper_driver(struct wmOperatorType *ot);
/* interface_eyedropper_gpencil_color.c */
void UI_OT_eyedropper_gpencil_color(struct wmOperatorType *ot);
/* interface_util.c */
/**

View File

@ -1751,6 +1751,7 @@ void ED_operatortypes_ui(void)
WM_operatortype_append(UI_OT_eyedropper_id);
WM_operatortype_append(UI_OT_eyedropper_depth);
WM_operatortype_append(UI_OT_eyedropper_driver);
WM_operatortype_append(UI_OT_eyedropper_gpencil_color);
}
/**