GPv3: Brush radius unit option
This implements and exposes the `View`/`Scene` brush radius option. * `View`: Brush units are in pixels. Zooming in and out in the viewport will make the brush stay the same size relative to the view, but grow/shrink relative to the scene. * `Scene`: Brush units are in meters. Zooming in and out in the viewport will make the brush grow/shrink relative to the view, but stay the same size relative to the scene. The default radius unit is `Scene`, which is what GPv2 did. The "2D Animation Template" was updated to disable using the radius in the unified paint settings. This means that using the template by default will use the brush radius, which also mimics the behavior of GPv2. The user can change the radius brush unit from the `Advanced` panel. Pull Request: https://projects.blender.org/blender/blender/pulls/120257
This commit is contained in:
@@ -915,6 +915,7 @@ def brush_shared_settings(layout, context, brush, popover=False):
|
||||
|
||||
# Grease Pencil #
|
||||
if mode == 'PAINT_GREASE_PENCIL':
|
||||
size_mode = True
|
||||
size = True
|
||||
strength = True
|
||||
|
||||
@@ -1446,13 +1447,21 @@ def brush_basic_grease_pencil_paint_settings(layout, context, brush, *, compact=
|
||||
if gp_settings is None:
|
||||
return
|
||||
|
||||
tool_settings = context.tool_settings
|
||||
ups = tool_settings.unified_paint_settings
|
||||
|
||||
grease_pencil_tool = brush.gpencil_tool
|
||||
|
||||
size = "size"
|
||||
size_owner = ups if ups.use_unified_size else brush
|
||||
if size_owner.use_locked_size == 'SCENE':
|
||||
size = "unprojected_radius"
|
||||
|
||||
UnifiedPaintPanel.prop_unified(
|
||||
layout,
|
||||
context,
|
||||
brush,
|
||||
"size",
|
||||
size,
|
||||
unified_name="use_unified_size",
|
||||
pressure_name="use_pressure_size",
|
||||
text="Radius",
|
||||
@@ -1511,13 +1520,6 @@ def brush_basic_grease_pencil_paint_settings(layout, context, brush, *, compact=
|
||||
if settings.use_thickness_curve:
|
||||
# Pressure curve.
|
||||
layout.template_curve_mapping(settings, "thickness_primitive_curve", brush=True)
|
||||
elif grease_pencil_tool == 'DRAW':
|
||||
layout.prop(gp_settings, "active_smooth_factor")
|
||||
row = layout.row(align=True)
|
||||
if compact:
|
||||
row.prop(gp_settings, "caps_type", text="", expand=True)
|
||||
else:
|
||||
row.prop(gp_settings, "caps_type", text="Caps Type")
|
||||
elif grease_pencil_tool == 'ERASE':
|
||||
layout.prop(gp_settings, "eraser_mode", expand=True)
|
||||
if gp_settings.eraser_mode == 'HARD':
|
||||
|
||||
@@ -114,6 +114,18 @@ class VIEW3D_HT_tool_header(Header):
|
||||
layout.popover("VIEW3D_PT_tools_grease_pencil_brush_stroke")
|
||||
|
||||
layout.popover("VIEW3D_PT_tools_grease_pencil_paint_appearance")
|
||||
elif tool_mode == 'PAINT_GREASE_PENCIL':
|
||||
if is_valid_context:
|
||||
brush = context.tool_settings.gpencil_paint.brush
|
||||
if brush:
|
||||
if brush.gpencil_tool != 'ERASE':
|
||||
if brush.gpencil_tool != 'TINT':
|
||||
layout.popover("VIEW3D_PT_tools_grease_pencil_v3_brush_advanced")
|
||||
|
||||
if brush.gpencil_tool not in {'FILL', 'TINT'}:
|
||||
layout.popover("VIEW3D_PT_tools_grease_pencil_brush_stroke")
|
||||
|
||||
# layout.popover("VIEW3D_PT_tools_grease_pencil_paint_appearance")
|
||||
elif tool_mode == 'SCULPT_GPENCIL':
|
||||
if is_valid_context:
|
||||
brush = context.tool_settings.gpencil_sculpt_paint.brush
|
||||
@@ -701,7 +713,6 @@ class _draw_tool_settings_context_mode:
|
||||
row.prop_with_popover(brush, "color", text="", panel="TOPBAR_PT_gpencil_vertexcolor")
|
||||
|
||||
from bl_ui.properties_paint_common import (
|
||||
brush_basic__draw_color_selector,
|
||||
brush_basic_grease_pencil_paint_settings,
|
||||
)
|
||||
|
||||
|
||||
@@ -2583,6 +2583,97 @@ class VIEW3D_PT_tools_grease_pencil_v3_brush_settings(Panel, View3DPanel, Grease
|
||||
brush_basic_grease_pencil_paint_settings(layout, context, brush, compact=False)
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_grease_pencil_v3_brush_advanced(View3DPanel, Panel):
|
||||
bl_context = ".greasepencil_paint"
|
||||
bl_label = "Advanced"
|
||||
bl_parent_id = "VIEW3D_PT_tools_grease_pencil_brush_settings"
|
||||
bl_category = "Tool"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_ui_units_x = 13
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.active_object
|
||||
if ob.type != 'GREASEPENCIL':
|
||||
return False
|
||||
brush = context.tool_settings.gpencil_paint.brush
|
||||
return brush is not None and brush.gpencil_tool not in {'ERASE', 'TINT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
tool_settings = context.scene.tool_settings
|
||||
ups = tool_settings.unified_paint_settings
|
||||
gpencil_paint = tool_settings.gpencil_paint
|
||||
brush = gpencil_paint.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
|
||||
col = layout.column(align=True)
|
||||
if brush is None:
|
||||
return
|
||||
if brush.gpencil_tool != 'FILL':
|
||||
size_owner = ups if ups.use_unified_size else brush
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(size_owner, "use_locked_size", expand=True)
|
||||
col.separator()
|
||||
|
||||
col.prop(gp_settings, "input_samples")
|
||||
col.separator()
|
||||
|
||||
col.prop(gp_settings, "active_smooth_factor")
|
||||
col.separator()
|
||||
|
||||
col.prop(gp_settings, "angle", slider=True)
|
||||
col.prop(gp_settings, "angle_factor", text="Factor", slider=True)
|
||||
|
||||
ob = context.object
|
||||
ma = None
|
||||
if ob and brush.gpencil_settings.use_material_pin is False:
|
||||
ma = ob.active_material
|
||||
elif brush.gpencil_settings.material:
|
||||
ma = brush.gpencil_settings.material
|
||||
|
||||
col.separator()
|
||||
col.prop(gp_settings, "hardness", slider=True)
|
||||
subcol = col.column(align=True)
|
||||
if ma and ma.grease_pencil.mode == 'LINE':
|
||||
subcol.enabled = False
|
||||
subcol.prop(gp_settings, "aspect")
|
||||
|
||||
elif brush.gpencil_tool == 'FILL':
|
||||
row = col.row(align=True)
|
||||
row.prop(gp_settings, "fill_draw_mode", text="Boundary", text_ctxt=i18n_contexts.id_gpencil)
|
||||
row.prop(
|
||||
gp_settings,
|
||||
"show_fill_boundary",
|
||||
icon='HIDE_OFF' if gp_settings.show_fill_boundary else 'HIDE_ON',
|
||||
text="",
|
||||
)
|
||||
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.prop(gp_settings, "fill_layer_mode", text="Layers")
|
||||
|
||||
col.separator()
|
||||
col.prop(gp_settings, "fill_simplify_level", text="Simplify")
|
||||
if gp_settings.fill_draw_mode != 'STROKE':
|
||||
col = layout.column(align=False, heading="Ignore Transparent")
|
||||
col.use_property_decorate = False
|
||||
row = col.row(align=True)
|
||||
sub = row.row(align=True)
|
||||
sub.prop(gp_settings, "show_fill", text="")
|
||||
sub = sub.row(align=True)
|
||||
sub.active = gp_settings.show_fill
|
||||
sub.prop(gp_settings, "fill_threshold", text="")
|
||||
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.prop(gp_settings, "use_fill_limit")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_grease_pencil_v3_brush_mixcolor(View3DPanel, Panel):
|
||||
bl_context = ".grease_pencil_paint"
|
||||
bl_label = "Color"
|
||||
@@ -2780,6 +2871,7 @@ classes = (
|
||||
|
||||
VIEW3D_PT_tools_grease_pencil_v3_brush_select,
|
||||
VIEW3D_PT_tools_grease_pencil_v3_brush_settings,
|
||||
VIEW3D_PT_tools_grease_pencil_v3_brush_advanced,
|
||||
VIEW3D_PT_tools_grease_pencil_v3_brush_mixcolor,
|
||||
VIEW3D_PT_tools_grease_pencil_v3_brush_mix_palette,
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ extern "C" {
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 35
|
||||
#define BLENDER_FILE_SUBVERSION 36
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "BKE_brush.hh"
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_idtype.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.hh"
|
||||
@@ -692,6 +693,7 @@ static void brush_gpencil_curvemap_reset(CurveMap *cuma, int tot, eGPCurveMappin
|
||||
|
||||
void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
{
|
||||
using namespace blender;
|
||||
#define SMOOTH_STROKE_RADIUS 40
|
||||
#define SMOOTH_STROKE_FACTOR 0.9f
|
||||
#define ACTIVE_SMOOTH 0.35f
|
||||
@@ -708,6 +710,11 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
brush->smooth_stroke_radius = SMOOTH_STROKE_RADIUS;
|
||||
brush->smooth_stroke_factor = SMOOTH_STROKE_FACTOR;
|
||||
|
||||
/* GPv3 uses the `Scene` size aka BRUSH_LOCK_SIZE by default. */
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
brush->flag |= BRUSH_LOCK_SIZE;
|
||||
}
|
||||
|
||||
brush->rgb[0] = 0.498f;
|
||||
brush->rgb[1] = 1.0f;
|
||||
brush->rgb[2] = 0.498f;
|
||||
@@ -733,6 +740,10 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
switch (type) {
|
||||
case GP_BRUSH_PRESET_AIRBRUSH: {
|
||||
brush->size = 300.0f;
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
brush->unprojected_radius = brush->size *
|
||||
bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->gpencil_settings->draw_strength = 0.4f;
|
||||
@@ -755,8 +766,11 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
break;
|
||||
}
|
||||
case GP_BRUSH_PRESET_INK_PEN: {
|
||||
|
||||
brush->size = 60.0f;
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
brush->unprojected_radius = brush->size *
|
||||
bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->gpencil_settings->draw_strength = 1.0f;
|
||||
@@ -792,6 +806,10 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
}
|
||||
case GP_BRUSH_PRESET_INK_PEN_ROUGH: {
|
||||
brush->size = 60.0f;
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
brush->unprojected_radius = brush->size *
|
||||
bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->gpencil_settings->draw_strength = 1.0f;
|
||||
@@ -829,6 +847,10 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
}
|
||||
case GP_BRUSH_PRESET_MARKER_BOLD: {
|
||||
brush->size = 150.0f;
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
brush->unprojected_radius = brush->size *
|
||||
bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
brush->gpencil_settings->flag &= ~GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->gpencil_settings->draw_strength = 0.3f;
|
||||
@@ -866,6 +888,10 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
}
|
||||
case GP_BRUSH_PRESET_MARKER_CHISEL: {
|
||||
brush->size = 150.0f;
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
brush->unprojected_radius = brush->size *
|
||||
bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->gpencil_settings->draw_strength = 1.0f;
|
||||
@@ -907,6 +933,10 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
}
|
||||
case GP_BRUSH_PRESET_PEN: {
|
||||
brush->size = 25.0f;
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
brush->unprojected_radius = brush->size *
|
||||
bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
brush->gpencil_settings->flag &= ~GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->gpencil_settings->draw_strength = 1.0f;
|
||||
@@ -938,6 +968,10 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
}
|
||||
case GP_BRUSH_PRESET_PENCIL_SOFT: {
|
||||
brush->size = 80.0f;
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
brush->unprojected_radius = brush->size *
|
||||
bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->gpencil_settings->draw_strength = 0.4f;
|
||||
@@ -972,6 +1006,10 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
|
||||
}
|
||||
case GP_BRUSH_PRESET_PENCIL: {
|
||||
brush->size = 20.0f;
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
brush->unprojected_radius = brush->size *
|
||||
bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
|
||||
|
||||
brush->gpencil_settings->draw_strength = 0.6f;
|
||||
|
||||
@@ -3535,6 +3535,19 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 36)) {
|
||||
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
|
||||
/* Only for grease pencil brushes. */
|
||||
if (brush->gpencil_settings) {
|
||||
/* Use the `Scene` radius unit by default (confusingly named `BRUSH_LOCK_SIZE`).
|
||||
* Convert the radius to be the same visual size as in GPv2. */
|
||||
brush->flag |= BRUSH_LOCK_SIZE;
|
||||
brush->unprojected_radius = brush->size *
|
||||
blender::bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
||||
|
||||
@@ -911,6 +911,13 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
|
||||
}
|
||||
}
|
||||
|
||||
if (app_template && STREQ(app_template, "2D_Animation")) {
|
||||
/* Disable the unified paint setting for the brush radius. */
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
scene->toolsettings->unified_paint_settings.flag &= ~UNIFIED_PAINT_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
LISTBASE_FOREACH (Light *, light, &bmain->lights) {
|
||||
light->shadow_maximum_resolution = 0.001f;
|
||||
|
||||
@@ -1515,6 +1515,7 @@ static void grease_pencil_brush_cursor_draw(PaintCursorContext *pcontext)
|
||||
return;
|
||||
}
|
||||
|
||||
GreasePencil *grease_pencil = static_cast<GreasePencil *>(object->data);
|
||||
Paint *paint = pcontext->paint;
|
||||
Brush *brush = pcontext->brush;
|
||||
if ((brush == nullptr) || (brush->gpencil_settings == nullptr)) {
|
||||
@@ -1526,9 +1527,9 @@ static void grease_pencil_brush_cursor_draw(PaintCursorContext *pcontext)
|
||||
}
|
||||
|
||||
/* default radius and color */
|
||||
float color[3] = {1.0f, 1.0f, 1.0f};
|
||||
float radius = BKE_brush_size_get(pcontext->scene, brush);
|
||||
pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush);
|
||||
|
||||
float3 color(1.0f);
|
||||
const int x = pcontext->x;
|
||||
const int y = pcontext->y;
|
||||
|
||||
@@ -1540,9 +1541,17 @@ static void grease_pencil_brush_cursor_draw(PaintCursorContext *pcontext)
|
||||
return;
|
||||
}
|
||||
|
||||
if (BKE_brush_use_locked_size(pcontext->scene, brush)) {
|
||||
const bke::greasepencil::Layer &layer = *grease_pencil->get_active_layer();
|
||||
const ed::greasepencil::DrawingPlacement placement(
|
||||
*pcontext->scene, *pcontext->region, *pcontext->vc.v3d, *object, layer);
|
||||
const float radius = BKE_brush_unprojected_radius_get(pcontext->scene, brush);
|
||||
const float3 location = placement.project(float2(pcontext->x, pcontext->y));
|
||||
pcontext->pixel_radius = project_brush_radius(&pcontext->vc, radius, location);
|
||||
}
|
||||
|
||||
/* Get current drawing material. */
|
||||
Material *ma = BKE_grease_pencil_object_material_from_brush_get(object, brush);
|
||||
if (ma) {
|
||||
if (Material *ma = BKE_grease_pencil_object_material_from_brush_get(object, brush)) {
|
||||
MaterialGPencilStyle *gp_style = ma->gp_style;
|
||||
|
||||
/* Follow user settings for the size of the draw cursor:
|
||||
@@ -1560,8 +1569,7 @@ static void grease_pencil_brush_cursor_draw(PaintCursorContext *pcontext)
|
||||
ELEM(brush->gpencil_settings->vertex_mode,
|
||||
GPPAINT_MODE_STROKE,
|
||||
GPPAINT_MODE_BOTH);
|
||||
|
||||
copy_v3_v3(color, use_vertex_color_stroke ? brush->rgb : gp_style->stroke_rgba);
|
||||
color = use_vertex_color_stroke ? float3(brush->rgb) : float4(gp_style->stroke_rgba).xyz();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1571,14 +1579,13 @@ static void grease_pencil_brush_cursor_draw(PaintCursorContext *pcontext)
|
||||
|
||||
GPU_line_width(1.0f);
|
||||
/* Inner Ring: Color from UI panel */
|
||||
immUniformColor4f(color[0], color[1], color[2], 0.8f);
|
||||
imm_draw_circle_wire_2d(pcontext->pos, x, y, radius, 32);
|
||||
immUniformColor4f(color.x, color.y, color.z, 0.8f);
|
||||
imm_draw_circle_wire_2d(pcontext->pos, x, y, pcontext->pixel_radius, 32);
|
||||
|
||||
/* Outer Ring: Dark color for contrast on light backgrounds (e.g. gray on white) */
|
||||
float darkcolor[3];
|
||||
mul_v3_v3fl(darkcolor, color, 0.40f);
|
||||
const float3 darkcolor = color * 0.40f;
|
||||
immUniformColor4f(darkcolor[0], darkcolor[1], darkcolor[2], 0.8f);
|
||||
imm_draw_circle_wire_2d(pcontext->pos, x, y, radius + 1, 32);
|
||||
imm_draw_circle_wire_2d(pcontext->pos, x, y, pcontext->pixel_radius + 1, 32);
|
||||
|
||||
/* Draw line for lazy mouse */
|
||||
/* TODO: No stabilize mode yet. */
|
||||
|
||||
Reference in New Issue
Block a user