GPencil: Only brushes with pinned materials have materials

Using GP_BRUSH_MATERIAL_PINNED to switch between active material and brush material, instead of updating all brushes on active material changes. This will allow brushes to have no material and therefore to not inflate the user count.

This fix T62465.

Patch contributed by @matc
Reviewers: @brecht @antoniov @billreynish @mendio
This commit is contained in:
Antonio Vazquez 2019-03-25 17:02:42 +01:00
parent 84240ebb3e
commit 7021bd5273
23 changed files with 292 additions and 262 deletions

View File

@ -832,6 +832,11 @@ class GreasePencilMaterialsPanel:
layout = self.layout
show_full_ui = (self.bl_space_type == 'PROPERTIES')
is_view3d = (self.bl_space_type == 'VIEW_3D')
tool_settings = context.scene.tool_settings
gpencil_paint = tool_settings.gpencil_paint
brush = gpencil_paint.brush
ob = context.object
row = layout.row()
@ -841,6 +846,12 @@ class GreasePencilMaterialsPanel:
row.template_list("GPENCIL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)
# if topbar popover and brush pinned, disable
if is_view3d and brush is not None:
gp_settings = brush.gpencil_settings
if gp_settings.use_material_pin:
row.enabled = False
col = row.column(align=True)
if show_full_ui:
col.operator("object.material_slot_add", icon='ADD', text="")

View File

@ -316,7 +316,8 @@ class _draw_left_context_mode:
def draw_color_selector():
ma = gp_settings.material
row = layout.row(align=True)
if not gp_settings.use_material_pin:
ma = context.object.active_material
icon_id = 0
if ma:
icon_id = ma.id_data.preview.icon_id

View File

@ -1679,7 +1679,15 @@ class VIEW3D_PT_tools_grease_pencil_brush(View3DPanel, Panel):
gp_settings = brush.gpencil_settings
if brush.gpencil_tool in {'DRAW', 'FILL'}:
layout.row(align=True).template_ID(gp_settings, "material")
row = layout.row(align=True)
row_mat = row.row()
if gp_settings.use_material_pin:
row_mat.template_ID(gp_settings, "material", live_icon=True)
else:
row_mat.template_ID(context.active_object, "active_material", live_icon=True)
row_mat.enabled = False # will otherwise allow to change material in active slot
row.prop(gp_settings, "use_material_pin", text="")
if not self.is_popover:
from .properties_paint_common import (

View File

@ -56,7 +56,6 @@ void BKE_brush_free(struct Brush *brush);
void BKE_brush_sculpt_reset(struct Brush *brush);
void BKE_brush_gpencil_presets(struct bContext *C);
void BKE_brush_update_material(struct Main *bmain, struct Material *ma, struct Brush *exclude_brush);
/* image icon function */
struct ImBuf *get_brush_icon(struct Brush *brush);

View File

@ -132,6 +132,21 @@ void BKE_gpencil_layer_setactive(struct bGPdata *gpd, struct bGPDlayer *active);
void BKE_gpencil_layer_delete(struct bGPdata *gpd, struct bGPDlayer *gpl);
struct Material *BKE_gpencil_get_material_from_brush(struct Brush *brush);
void BKE_gpencil_brush_set_material(struct Brush *brush, struct Material *material);
struct Material *BKE_gpencil_handle_brush_material(struct Main *bmain, struct Object *ob, struct Brush *brush);
int BKE_gpencil_handle_material(struct Main *bmain, struct Object *ob, struct Material *material);
struct Material *BKE_gpencil_handle_new_material(struct Main *bmain, struct Object *ob, const char *name, int *r_index);
struct Material *BKE_gpencil_get_material_for_brush(struct Object *ob, struct Brush *brush);
int BKE_gpencil_get_material_index_for_brush(struct Object *ob, struct Brush *brush);
struct Material *BKE_gpencil_current_input_toolsettings_material(struct Main *bmain, struct Object *ob, struct ToolSettings *ts);
struct Material *BKE_gpencil_current_input_brush_material(struct Main *bmain, struct Object *ob, struct Brush *brush);
struct Material *BKE_gpencil_current_input_material(struct Main *bmain, struct Object *ob);
struct Material *BKE_gpencil_material_ensure(struct Main *bmain, struct Object *ob);
/* object boundbox */

View File

@ -540,24 +540,6 @@ void BKE_brush_gpencil_presets(bContext *C)
}
void BKE_brush_update_material(Main *bmain, Material *ma, Brush *exclude_brush)
{
for (Brush *brush = bmain->brushes.first; brush; brush = brush->id.next) {
if ((exclude_brush != NULL) && (brush == exclude_brush)) {
continue;
}
if (brush->gpencil_settings != NULL) {
BrushGpencilSettings *gpencil_settings = brush->gpencil_settings;
if (((gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) == 0) &&
(gpencil_settings->material != ma))
{
gpencil_settings->material = ma;
}
}
}
}
struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode)
{
Brush *brush;

View File

@ -996,6 +996,136 @@ Material *BKE_gpencil_get_material_from_brush(Brush *brush)
return ma;
}
void BKE_gpencil_brush_set_material(Brush *brush, Material *ma)
{
BLI_assert(brush);
BLI_assert(brush->gpencil_settings);
if (brush->gpencil_settings->material != ma) {
if (brush->gpencil_settings->material) {
id_us_min(&brush->gpencil_settings->material->id);
}
if (ma) {
id_us_plus(&ma->id);
}
brush->gpencil_settings->material = ma;
}
}
/* Adds the pinned material to the object if necessary. */
Material *BKE_gpencil_handle_brush_material(Main *bmain, Object *ob, Brush *brush)
{
if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
Material *ma = BKE_gpencil_get_material_from_brush(brush);
/* check if the material is already on object material slots and add it if missing */
if (ma && BKE_gpencil_get_material_index(ob, ma) < 0) {
BKE_object_material_slot_add(bmain, ob);
assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
}
return ma;
}
else {
/* using active material instead */
return give_current_material(ob, ob->actcol);
}
}
/* Assigns the material to object (if not already present) and returns its index (mat_nr). */
int BKE_gpencil_handle_material(Main *bmain, Object *ob, Material *material)
{
if (!material) {
return -1;
}
int index = BKE_gpencil_get_material_index(ob, material);
if (index < 0) {
BKE_object_material_slot_add(bmain, ob);
assign_material(bmain, ob, material, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
return ob->totcol - 1;
}
return index;
}
/** Creates a new gpencil material and assigns it to object.
*
* \param *r_index: value is set to zero based index of the new material if r_index is not NULL
*/
Material *BKE_gpencil_handle_new_material(Main *bmain, Object *ob, const char *name, int *r_index)
{
Material *ma = BKE_material_add_gpencil(bmain, name);
id_us_min(&ma->id); /* no users yet */
BKE_object_material_slot_add(bmain, ob);
assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
if (r_index) {
*r_index = ob->actcol - 1;
}
return ma;
}
/* Returns the material for a brush with respect to its pinned state. */
Material *BKE_gpencil_get_material_for_brush(Object *ob, Brush *brush)
{
if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
Material *ma = BKE_gpencil_get_material_from_brush(brush);
return ma;
}
else {
return give_current_material(ob, ob->actcol);
}
}
/* Returns the material index for a brush with respect to its pinned state. */
int BKE_gpencil_get_material_index_for_brush(Object *ob, Brush *brush)
{
if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
return BKE_gpencil_get_material_index(ob, brush->gpencil_settings->material);
}
else {
return ob->actcol - 1;
}
}
/* Guaranteed to return a material assigned to object. Returns never NULL. */
Material *BKE_gpencil_current_input_toolsettings_material(Main *bmain, Object *ob, ToolSettings *ts)
{
if (ts && ts->gp_paint && ts->gp_paint->paint.brush) {
return BKE_gpencil_current_input_brush_material(bmain, ob, ts->gp_paint->paint.brush);
}
else {
return BKE_gpencil_current_input_brush_material(bmain, ob, NULL);
}
}
/* Guaranteed to return a material assigned to object. Returns never NULL. */
Material *BKE_gpencil_current_input_brush_material(Main *bmain, Object *ob, Brush *brush)
{
Material *ma;
if (brush) {
ma = BKE_gpencil_handle_brush_material(bmain, ob, brush);
if (!ma && brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
/* it is easier to just unpin a NULL material, instead of setting a new one */
brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED;
}
}
if (ma) {
return ma;
}
return BKE_gpencil_current_input_material(bmain, ob);
}
/* Guaranteed to return a material assigned to object. Returns never NULL. Only use this for materials unrelated to user input */
Material *BKE_gpencil_current_input_material(Main *bmain, Object *ob)
{
Material *ma;
ma = give_current_material(ob, ob->actcol);
if (ma) {
return ma;
}
return BKE_gpencil_handle_new_material(bmain, ob, "Material", NULL);
}
/* Get active color, and add all default settings if we don't find anything */
Material *BKE_gpencil_material_ensure(Main *bmain, Object *ob)
{
@ -1005,15 +1135,8 @@ Material *BKE_gpencil_material_ensure(Main *bmain, Object *ob)
if (ELEM(NULL, bmain, ob))
return NULL;
ma = give_current_material(ob, ob->actcol);
if (ma == NULL) {
if (ob->totcol == 0) {
BKE_object_material_slot_add(bmain, ob);
}
ma = BKE_material_add_gpencil(bmain, DATA_("Material"));
assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
}
else if (ma->gp_style == NULL) {
ma = BKE_gpencil_current_input_material(bmain, ob);
if (ma->gp_style == NULL) {
BKE_material_init_gpencil_settings(ma);
}
@ -1538,7 +1661,7 @@ void BKE_gpencil_stats_update(bGPdata *gpd)
}
/* get material index */
/* get material index (0-based like mat_nr not actcol) */
int BKE_gpencil_get_material_index(Object *ob, Material *ma)
{
short *totcol = give_totcolp(ob);
@ -1546,11 +1669,11 @@ int BKE_gpencil_get_material_index(Object *ob, Material *ma)
for (short i = 0; i < *totcol; i++) {
read_ma = give_current_material(ob, i + 1);
if (ma == read_ma) {
return i + 1;
return i;
}
}
return 0;
return -1;
}
/* Get points of stroke always flat to view not affected by camera view or view position */

View File

@ -164,7 +164,6 @@ Material *BKE_material_add_gpencil(Main *bmain, const char *name)
/* grease pencil settings */
if (ma != NULL) {
BKE_material_init_gpencil_settings(ma);
BKE_brush_update_material(bmain, ma, NULL);
}
return ma;
}

View File

@ -2617,8 +2617,19 @@ static void lib_link_brush(FileData *fd, Main *main)
brush->paint_curve = newlibadr_us(fd, brush->id.lib, brush->paint_curve);
/* link default grease pencil palette */
if (brush->gpencil_settings != NULL) {
brush->gpencil_settings->material = newlibadr_us(fd, brush->id.lib, brush->gpencil_settings->material);
if (brush->gpencil_settings != NULL)
{
if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)
{
brush->gpencil_settings->material = newlibadr_us(fd, brush->id.lib, brush->gpencil_settings->material);
if (!brush->gpencil_settings->material) {
brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED;
}
}
else {
brush->gpencil_settings->material = NULL;
}
}
brush->id.tag &= ~LIB_TAG_NEED_LINK;

View File

@ -1355,7 +1355,7 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T
float obscale = mat4_to_scale(ob->obmat);
/* use the brush material */
Material *ma = BKE_gpencil_get_material_from_brush(brush);
Material *ma = BKE_gpencil_get_material_for_brush(ob, brush);
if (ma != NULL) {
gp_style = ma->gp_style;
}

View File

@ -60,11 +60,10 @@ static int gpencil_monkey_color(
}
}
int idx;
/* create a new one */
BKE_object_material_slot_add(bmain, ob);
ma = BKE_material_add_gpencil(bmain, pct->name);
assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
id_us_min(&ma->id);
ma = BKE_gpencil_handle_new_material(bmain, ob, pct->name, &idx);
copy_v4_v4(ma->gp_style->stroke_rgba, pct->line);
copy_v4_v4(ma->gp_style->fill_rgba, pct->fill);
@ -80,7 +79,7 @@ static int gpencil_monkey_color(
ma->gp_style->flag |= GP_STYLE_FILL_SHOW;
}
return BKE_gpencil_get_material_index(ob, ma) - 1;
return idx;
}
/* ***************************************************************** */
@ -1447,10 +1446,6 @@ void ED_gpencil_create_monkey(bContext *C, Object *ob, float mat[4][4])
/* set first color as active */
ob->actcol = color_Black + 1;
Material *ma = give_current_material(ob, ob->actcol);
if (ma != NULL) {
BKE_brush_update_material(bmain, ma, NULL);
}
/* layers */
/* NOTE: For now, we just add new layers, to make it easier to separate out old/new instances */

View File

@ -60,11 +60,10 @@ static int gp_stroke_material(
}
}
int idx;
/* create a new one */
BKE_object_material_slot_add(bmain, ob);
ma = BKE_material_add_gpencil(bmain, pct->name);
assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
id_us_min(&ma->id);
ma = BKE_gpencil_handle_new_material(bmain, ob, pct->name, &idx);
copy_v4_v4(ma->gp_style->stroke_rgba, pct->line);
copy_v4_v4(ma->gp_style->fill_rgba, pct->fill);
@ -73,7 +72,7 @@ static int gp_stroke_material(
ma->gp_style->flag |= GP_STYLE_FILL_SHOW;
}
return BKE_gpencil_get_material_index(ob, ma) - 1;
return idx;
}
/* ***************************************************************** */
@ -231,10 +230,6 @@ void ED_gpencil_create_stroke(bContext *C, Object *ob, float mat[4][4])
/* set first color as active and in brushes */
ob->actcol = color_black + 1;
Material *ma = give_current_material(ob, ob->actcol);
if (ma != NULL) {
BKE_brush_update_material(bmain, ma, NULL);
}
/* layers */
bGPDlayer *colors = BKE_gpencil_layer_addnew(gpd, "Colors", false);

View File

@ -1101,14 +1101,10 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
/* Fix color references */
Material *ma = BLI_ghash_lookup(data->new_colors, &new_stroke->mat_nr);
if ((ma) && (BKE_gpencil_get_material_index(ob, ma) > 0)) {
gps->mat_nr = BKE_gpencil_get_material_index(ob, ma) - 1;
CLAMP_MIN(gps->mat_nr, 0);
gps->mat_nr = BKE_gpencil_get_material_index(ob, ma);
if (!ma || gps->mat_nr) {
gps->mat_nr = 0;
}
else {
gps->mat_nr = 0; /* only if the color is not found */
}
/* Adjust all the stroke's points, so that the strokes
* get pasted relative to where the cursor is now
*/

View File

@ -514,15 +514,10 @@ static int gp_layer_duplicate_object_exec(bContext *C, wmOperator *op)
* otherwise add the slot with the material
*/
Material *ma_src = give_current_material(ob_src, gps_src->mat_nr + 1);
int idx = BKE_gpencil_get_material_index(ob_dst, ma_src);
if (idx == 0) {
BKE_object_material_slot_add(bmain, ob_dst);
assign_material(bmain, ob_dst, ma_src, ob_dst->totcol, BKE_MAT_ASSIGN_USERPREF);
idx = ob_dst->totcol;
}
int idx = BKE_gpencil_handle_material(bmain, ob_dst, ma_src);
/* reasign the stroke material to the right slot in destination object */
gps_dst->mat_nr = idx - 1;
gps_dst->mat_nr = idx;
/* add new stroke to frame */
BLI_addtail(&gpf_dst->strokes, gps_dst);
@ -1377,7 +1372,7 @@ static int gp_stroke_change_color_exec(bContext *C, wmOperator *op)
}
}
/* try to find slot */
int idx = BKE_gpencil_get_material_index(ob, ma) - 1;
int idx = BKE_gpencil_get_material_index(ob, ma);
if (idx < 0) {
return OPERATOR_CANCELLED;
}
@ -2052,10 +2047,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
for (short i = 0; i < *totcol; i++) {
Material *tmp_ma = give_current_material(ob_src, i + 1);
if (BKE_gpencil_get_material_index(ob_dst, tmp_ma) == 0) {
BKE_object_material_slot_add(bmain, ob_dst);
assign_material(bmain, ob_dst, tmp_ma, ob_dst->totcol, BKE_MAT_ASSIGN_USERPREF);
}
BKE_gpencil_handle_material(bmain, ob_dst, tmp_ma);
}
/* duplicate bGPDlayers */
@ -2085,24 +2077,12 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
invert_m4_m4(inverse_diff_mat, diff_mat);
Material *ma_src = NULL;
int idx;
for (bGPDframe *gpf = gpl_new->frames.first; gpf; gpf = gpf->next) {
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
/* reasign material. Look old material and try to find in dst */
ma_src = give_current_material(ob_src, gps->mat_nr + 1);
if (ma_src != NULL) {
idx = BKE_gpencil_get_material_index(ob_dst, ma_src);
if (idx > 0) {
gps->mat_nr = idx - 1;
}
else {
gps->mat_nr = 0;
}
}
else {
gps->mat_nr = 0;
}
gps->mat_nr = BKE_gpencil_handle_material(bmain, ob_dst, ma_src);
bGPDspoint *pt;
int i;

View File

@ -1074,10 +1074,7 @@ GHash *gp_copybuf_validate_colormap(bContext *C)
char *ma_name = BLI_ghashIterator_getValue(&gh_iter);
Material *ma = BLI_ghash_lookup(name_to_ma, ma_name);
if (ma != NULL && BKE_gpencil_get_material_index(ob, ma) == 0) {
BKE_object_material_slot_add(bmain, ob);
assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
}
BKE_gpencil_handle_material(bmain, ob, ma);
/* Store this mapping (for use later when pasting) */
if (!BLI_ghash_haskey(new_colors, POINTER_FROM_INT(*key))) {
@ -1331,14 +1328,8 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
/* Remap material */
Material *ma = BLI_ghash_lookup(new_colors, POINTER_FROM_INT(new_stroke->mat_nr));
if ((ma) && (BKE_gpencil_get_material_index(ob, ma) > 0)) {
new_stroke->mat_nr = BKE_gpencil_get_material_index(ob, ma) - 1;
CLAMP_MIN(new_stroke->mat_nr, 0);
}
else {
new_stroke->mat_nr = 0; /* only if the color is not found */
}
new_stroke->mat_nr = BKE_gpencil_get_material_index(ob, ma);
BLI_assert(new_stroke >= 0); /* have to add the material first */
}
}
}
@ -3914,10 +3905,7 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
/* create new grease pencil datablock */
gpd_dst = BKE_gpencil_data_addnew(bmain, gpd_src->id.name + 2);
ob_dst->data = (bGPdata *)gpd_dst;
int totslots = ob_dst->totcol;
int totadd = 0;
/* loop old datablock and separate parts */
if ((mode == GP_SEPARATE_POINT) || (mode == GP_SEPARATE_STROKE)) {
CTX_DATA_BEGIN(C, bGPDlayer *, gpl, editable_gpencil_layers)
@ -3962,21 +3950,8 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
}
/* add duplicate materials */
ma = give_current_material(ob, gps->mat_nr + 1);
idx = BKE_gpencil_get_material_index(ob_dst, ma);
if (idx == 0) {
totadd++;
ob_dst->actcol = totadd;
ob_dst->totcol = totadd;
if (totadd > totslots) {
BKE_object_material_slot_add(bmain, ob_dst);
}
assign_material(bmain, ob_dst, ma, ob_dst->totcol, BKE_MAT_ASSIGN_USERPREF);
idx = totadd;
}
ma = give_current_material(ob, gps->mat_nr + 1); /* XXX same material can be in multiple slots */
idx = BKE_gpencil_handle_material(bmain, ob_dst, ma);
/* selected points mode */
if (mode == GP_SEPARATE_POINT) {
@ -3984,7 +3959,7 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps);
/* reasign material */
gps_dst->mat_nr = idx - 1;
gps_dst->mat_nr = idx;
/* link to destination frame */
BLI_addtail(&gpf_dst->strokes, gps_dst);
@ -4010,7 +3985,7 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
/* relink to destination frame */
BLI_addtail(&gpf_dst->strokes, gps);
/* reasign material */
gps->mat_nr = idx - 1;
gps->mat_nr = idx;
}
}
}
@ -4048,21 +4023,7 @@ static int gp_stroke_separate_exec(bContext *C, wmOperator *op)
continue;
}
ma = give_current_material(ob, gps->mat_nr + 1);
idx = BKE_gpencil_get_material_index(ob_dst, ma);
if (idx == 0) {
totadd++;
ob_dst->actcol = totadd;
ob_dst->totcol = totadd;
if (totadd > totslots) {
BKE_object_material_slot_add(bmain, ob_dst);
}
assign_material(bmain, ob_dst, ma, ob_dst->totcol, BKE_MAT_ASSIGN_USERPREF);
idx = totadd;
}
/* reasign material */
gps->mat_nr = idx - 1;
gps->mat_nr = BKE_gpencil_handle_material(bmain, ob_dst, ma);
}
}
}

View File

@ -1017,12 +1017,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
gps->flag |= GP_STROKE_CYCLIC;
gps->flag |= GP_STROKE_3DSPACE;
gps->mat_nr = BKE_gpencil_get_material_index(tgpf->ob, tgpf->mat) - 1;
if (gps->mat_nr < 0) {
BKE_object_material_slot_add(tgpf->bmain, tgpf->ob);
assign_material(tgpf->bmain, tgpf->ob, tgpf->mat, tgpf->ob->totcol, BKE_MAT_ASSIGN_USERPREF);
gps->mat_nr = tgpf->ob->totcol - 1;
}
gps->mat_nr = BKE_gpencil_handle_material(tgpf->bmain, tgpf->ob, tgpf->mat);
/* allocate memory for storage points */
gps->totpoints = tgpf->sbuffer_size;
@ -1215,17 +1210,18 @@ static tGPDfill *gp_session_init_fill(bContext *C, wmOperator *UNUSED(op))
tgpf->fill_draw_mode = brush->gpencil_settings->fill_draw_mode;
tgpf->fill_factor = (short)max_ii(1, min_ii((int)brush->gpencil_settings->fill_factor, 8));
int totcol = tgpf->ob->totcol;
/* get color info */
Material *ma = BKE_gpencil_get_material_from_brush(brush);
/* if no brush defaults, get material and color info */
if ((ma == NULL) || (ma->gp_style == NULL)) {
ma = BKE_gpencil_material_ensure(bmain, tgpf->ob);
/* assign always the first material to the brush */
brush->gpencil_settings->material = give_current_material(tgpf->ob, 1);
}
Material *ma = BKE_gpencil_current_input_brush_material(bmain, tgpf->ob, brush);
tgpf->mat = ma;
/* check whether the material was newly added */
if (totcol != tgpf->ob->totcol) {
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_PROPERTIES, NULL);
}
/* init undo */
gpencil_undo_init(tgpf->gpd);

View File

@ -112,9 +112,7 @@ static int gpencil_convert_old_files_exec(bContext *C, wmOperator *UNUSED(op))
for (bGPDpalettecolor *palcolor = palette->colors.first; palcolor; palcolor = palcolor->next) {
/* create material slot */
BKE_object_material_slot_add(bmain, ob);
Material *ma = BKE_material_add_gpencil(bmain, palcolor->info);
assign_material(bmain, ob, ma, ob->totcol, BKE_MAT_ASSIGN_USERPREF);
Material *ma = BKE_gpencil_handle_new_material(bmain, ob, palcolor->info, NULL);
/* copy color settings */
MaterialGPencilStyle *gp_style = ma->gp_style;

View File

@ -302,6 +302,12 @@ static bool gpencil_draw_poll(bContext *C)
return false;
}
ToolSettings *ts = CTX_data_scene(C)->toolsettings;
if (!ts->gp_paint->paint.brush) {
CTX_wm_operator_poll_msg_set(C, "Grease Pencil has no active paint tool");
return false;
}
return true;
}
else {
@ -1217,7 +1223,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
}
/* Save material index */
gps->mat_nr = BKE_gpencil_get_material_index(p->ob, p->material) - 1;
gps->mat_nr = BKE_gpencil_get_material_index_for_brush(p->ob, p->brush);
/* calculate UVs along the stroke */
ED_gpencil_calc_stroke_uv(obact, gps);
@ -1834,31 +1840,10 @@ static void gp_init_colors(tGPsdata *p)
bGPdata *gpd = p->gpd;
Brush *brush = p->brush;
Material *ma = NULL;
MaterialGPencilStyle *gp_style = NULL;
/* use brush material */
ma = BKE_gpencil_get_material_from_brush(brush);
/* if no brush defaults, get material and color info
* NOTE: Ensures that everything we need will exist...
*/
if ((ma == NULL) || (ma->gp_style == NULL)) {
BKE_gpencil_material_ensure(p->bmain, p->ob);
/* assign always the first material to the brush */
p->material = give_current_material(p->ob, 1);
brush->gpencil_settings->material = p->material;
}
else {
p->material = ma;
}
/* check if the material is already on object material slots and add it if missing */
if (BKE_gpencil_get_material_index(p->ob, p->material) == 0) {
BKE_object_material_slot_add(p->bmain, p->ob);
assign_material(p->bmain, p->ob, ma, p->ob->totcol, BKE_MAT_ASSIGN_USERPREF);
}
p->material = BKE_gpencil_current_input_brush_material(p->bmain, p->ob, brush);
/* assign color information to temp tGPsdata */
gp_style = p->material->gp_style;
@ -1996,7 +1981,14 @@ static bool gp_session_initdata(bContext *C, wmOperator *op, tGPsdata *p)
/* NOTE: This is only done for 3D view, as Materials aren't used for
* annotations in 2D editors
*/
int totcol = p->ob->totcol;
gp_init_colors(p);
/* check whether the material was newly added */
if (totcol != p->ob->totcol) {
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_PROPERTIES, NULL);
}
}
/* lock axis (in some modes, disable) */

View File

@ -137,29 +137,10 @@ static void gp_init_colors(tGPDprimitive *p)
bGPdata *gpd = p->gpd;
Brush *brush = p->brush;
Material *ma = NULL;
MaterialGPencilStyle *gp_style = NULL;
/* use brush material */
ma = BKE_gpencil_get_material_from_brush(brush);
/* if no brush defaults, get material and color info */
if ((ma == NULL) || (ma->gp_style == NULL)) {
BKE_gpencil_material_ensure(p->bmain, p->ob);
/* assign always the first material to the brush */
p->mat = give_current_material(p->ob, 1);
brush->gpencil_settings->material = p->mat;
}
else {
p->mat = ma;
}
/* check if the material is already on object material slots and add it if missing */
if (BKE_gpencil_get_material_index(p->ob, p->mat) == 0) {
BKE_object_material_slot_add(p->bmain, p->ob);
assign_material(p->bmain, p->ob, ma, p->ob->totcol, BKE_MAT_ASSIGN_USERPREF);
}
p->mat = BKE_gpencil_current_input_brush_material(p->bmain,p->ob, brush);
/* assign color information to temp data */
gp_style = p->mat->gp_style;
@ -350,7 +331,7 @@ static void gp_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
gps->flag |= GP_STROKE_3DSPACE;
gps->mat_nr = BKE_gpencil_get_material_index(tgpi->ob, tgpi->mat) - 1;
gps->mat_nr = BKE_gpencil_get_material_index(tgpi->ob, tgpi->mat);
/* allocate memory for storage points, but keep empty */
gps->totpoints = 0;
@ -1130,7 +1111,7 @@ static void gpencil_primitive_init(bContext *C, wmOperator *op)
tgpi->gpd->runtime.tot_cp_points = 0;
/* getcolor info */
tgpi->mat = BKE_gpencil_material_ensure(bmain, tgpi->ob);
tgpi->mat = BKE_gpencil_current_input_toolsettings_material(bmain, tgpi->ob, ts);
/* set parameters */
tgpi->type = RNA_enum_get(op->ptr, "type");

View File

@ -1341,17 +1341,6 @@ void ED_gpencil_add_defaults(bContext *C, Object *ob)
Main *bmain = CTX_data_main(C);
ToolSettings *ts = CTX_data_tool_settings(C);
/* first try to reuse default material */
if (ob->actcol > 0) {
Material *ma = give_current_material(ob, ob->actcol);
if ((ma) && (ma->gp_style == NULL)) {
BKE_material_init_gpencil_settings(ma);
}
}
/* ensure color exist */
BKE_gpencil_material_ensure(bmain, ob);
BKE_paint_ensure(ts, (Paint **)&ts->gp_paint);
Paint *paint = &ts->gp_paint->paint;
/* if not exist, create a new one */
@ -1360,6 +1349,9 @@ void ED_gpencil_add_defaults(bContext *C, Object *ob)
BKE_brush_gpencil_presets(C);
}
/* ensure a color exists and is assigned to object */
BKE_gpencil_current_input_toolsettings_material(bmain, ob, ts);
/* ensure multiframe falloff curve */
if (ts->gp_sculpt.cur_falloff == NULL) {
ts->gp_sculpt.cur_falloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
@ -1728,30 +1720,27 @@ static void gp_brush_cursor_draw(bContext *C, int x, int y, void *customdata)
}
/* get current drawing color */
ma = BKE_gpencil_get_material_from_brush(brush);
if (ma == NULL) {
BKE_gpencil_material_ensure(bmain, ob);
/* assign the first material to the brush */
ma = give_current_material(ob, 1);
brush->gpencil_settings->material = ma;
}
gp_style = ma->gp_style;
ma = BKE_gpencil_get_material_for_brush(ob, brush);
/* after some testing, display the size of the brush is not practical because
* is too disruptive and the size of cursor does not change with zoom factor.
* The decision was to use a fix size, instead of brush->thickness value.
*/
if ((gp_style) && (GPENCIL_PAINT_MODE(gpd)) &&
((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) &&
((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) &&
(brush->gpencil_tool == GPAINT_TOOL_DRAW))
{
radius = 2.0f;
copy_v3_v3(color, gp_style->stroke_rgba);
}
else {
radius = 5.0f;
copy_v3_v3(color, brush->add_col);
if (ma) {
gp_style = ma->gp_style;
/* after some testing, display the size of the brush is not practical because
* is too disruptive and the size of cursor does not change with zoom factor.
* The decision was to use a fix size, instead of brush->thickness value.
*/
if ((gp_style) && (GPENCIL_PAINT_MODE(gpd)) &&
((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) &&
((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) &&
(brush->gpencil_tool == GPAINT_TOOL_DRAW))
{
radius = 2.0f;
copy_v3_v3(color, gp_style->stroke_rgba);
}
else {
radius = 5.0f;
copy_v3_v3(color, brush->add_col);
}
}
}

View File

@ -559,11 +559,6 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
Material *new_ma = NULL;
BKE_id_copy_ex(bmain, &ma->id, (ID **)&new_ma, LIB_ID_COPY_DEFAULT | LIB_ID_COPY_ACTIONS);
ma = new_ma;
if (ob != NULL && ob->type == OB_GPENCIL) {
BKE_brush_update_material(bmain, new_ma, NULL);
}
}
else {
const char *name = DATA_("Material");

View File

@ -159,6 +159,7 @@ static EnumPropertyItem rna_enum_gpencil_brush_icons_items[] = {
#include "BKE_icons.h"
#include "BKE_gpencil.h"
#include "BKE_paint.h"
#include "BKE_material.h"
#include "WM_api.h"
@ -444,27 +445,8 @@ static void rna_Brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR
static void rna_Brush_material_update(bContext *C, PointerRNA *ptr)
{
Main *bmain = CTX_data_main(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
Brush *br = (Brush *)ptr->id.data;
int index;
/* set material slot to same material */
if ((ob) && (ob->type == OB_GPENCIL) && (br->gpencil_settings != NULL)) {
BrushGpencilSettings *gpencil_settings = br->gpencil_settings;
if (gpencil_settings->material != NULL) {
index = BKE_gpencil_get_material_index(ob, gpencil_settings->material);
if ((index > 0) && (ob->actcol != index)) {
ob->actcol = index;
/* update other brushes to keep all synchro */
BKE_brush_update_material(bmain, gpencil_settings->material, br);
}
}
WM_main_add_notifier(NC_SPACE | ND_SPACE_PROPERTIES, NULL);
}
/* number of material users changed */
WM_main_add_notifier(NC_SPACE | ND_SPACE_PROPERTIES, NULL);
}
static void rna_Brush_main_tex_update(bContext *C, PointerRNA *ptr)
@ -723,6 +705,24 @@ static void rna_BrushGpencilSettings_default_eraser_update(Main *bmain, Scene *s
}
}
static void rna_BrushGpencilSettings_use_material_pin_update(bContext *C, PointerRNA *ptr)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
Brush *brush = ptr->id.data;
if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
Material *material = give_current_material(ob, ob->actcol);
BKE_gpencil_brush_set_material(brush, material);
}
else {
BKE_gpencil_brush_set_material(brush, NULL);
}
/* number of material users changed */
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_PROPERTIES, NULL);
}
static void rna_BrushGpencilSettings_eraser_mode_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
ToolSettings *ts = scene->toolsettings;
@ -1337,9 +1337,11 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_material_pin", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_MATERIAL_PINNED);
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_ui_icon(prop, ICON_UNPINNED, 1);
RNA_def_property_ui_text(prop, "Pin Material", "Keep material assigned to brush");
RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_use_material_pin_update");
prop = RNA_def_property(srna, "show_lasso", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_BRUSH_DISSABLE_LASSO);

View File

@ -277,14 +277,10 @@ static void rna_Object_hide_update(Main *bmain, Scene *UNUSED(scene), PointerRNA
static void rna_MaterialIndex_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
/* update the material of all brushes not pinned */
Object *ob = (Object *)ptr->id.data;
if (ob && ob->type == OB_GPENCIL) {
Material *ma = give_current_material(ob, ob->actcol);
if (ma != NULL) {
BKE_brush_update_material(bmain, ma, NULL);
WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
/* notifying material property in topbar */
WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
}
@ -821,6 +817,11 @@ static void rna_Object_active_material_set(PointerRNA *ptr, PointerRNA value)
BLI_assert(BKE_id_is_in_global_main(&ob->id));
BLI_assert(BKE_id_is_in_global_main(value.data));
assign_material(G_MAIN, ob, value.data, ob->actcol, BKE_MAT_ASSIGN_EXISTING);
if (ob && ob->type == OB_GPENCIL) {
/* notifying material property in topbar */
WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
}
static int rna_Object_active_material_editable(PointerRNA *ptr, const char **UNUSED(r_info))