Cleanup: GPv3: Add drawing API for fill color
This adds two functions to the `Drawing` class: `fill_colors()` and `fill_colors_for_write()`. In places where the attribute API was used directly, these functions are now used instead. This is part of #119080. The point is that developers shouldn't need to remember the name, type, default value, and domain of built-in attributes (e.g. used by the renderer). Pull Request: https://projects.blender.org/blender/blender/pulls/120296
This commit is contained in:
@@ -79,7 +79,7 @@ class Drawing : public ::GreasePencilDrawing {
|
||||
|
||||
/**
|
||||
* Returns the matrices that transform from a 3D point in layer-space to a 2D point in
|
||||
* texture-space.
|
||||
* texture-space. This is stored per curve.
|
||||
*/
|
||||
Span<float4x2> texture_matrices() const;
|
||||
/**
|
||||
@@ -103,11 +103,19 @@ class Drawing : public ::GreasePencilDrawing {
|
||||
MutableSpan<float> opacities_for_write();
|
||||
|
||||
/**
|
||||
* Vertex colors of the points. Default is black.
|
||||
* Vertex colors of the points. Default is black. This is mixed on top of the base material
|
||||
* stroke color.
|
||||
*/
|
||||
VArray<ColorGeometry4f> vertex_colors() const;
|
||||
MutableSpan<ColorGeometry4f> vertex_colors_for_write();
|
||||
|
||||
/**
|
||||
* Fill colors of the curves. Default is black and fully transparent. This is mixed on top of the
|
||||
* base material fill color.
|
||||
*/
|
||||
VArray<ColorGeometry4f> fill_colors() const;
|
||||
MutableSpan<ColorGeometry4f> fill_colors_for_write();
|
||||
|
||||
/**
|
||||
* Add a user for this drawing. When a drawing has multiple users, both users are allowed to
|
||||
* modify this drawings data.
|
||||
|
||||
@@ -255,6 +255,7 @@ namespace blender::bke::greasepencil {
|
||||
static const std::string ATTR_RADIUS = "radius";
|
||||
static const std::string ATTR_OPACITY = "opacity";
|
||||
static const std::string ATTR_VERTEX_COLOR = "vertex_color";
|
||||
static const std::string ATTR_FILL_COLOR = "fill_color";
|
||||
|
||||
/* Curves attributes getters */
|
||||
static int domain_num(const CurvesGeometry &curves, const AttrDomain domain)
|
||||
@@ -680,6 +681,20 @@ MutableSpan<ColorGeometry4f> Drawing::vertex_colors_for_write()
|
||||
ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
VArray<ColorGeometry4f> Drawing::fill_colors() const
|
||||
{
|
||||
return *this->strokes().attributes().lookup_or_default<ColorGeometry4f>(
|
||||
ATTR_FILL_COLOR, AttrDomain::Curve, ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
MutableSpan<ColorGeometry4f> Drawing::fill_colors_for_write()
|
||||
{
|
||||
return get_mutable_attribute<ColorGeometry4f>(this->strokes_for_write(),
|
||||
AttrDomain::Curve,
|
||||
ATTR_FILL_COLOR,
|
||||
ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
void Drawing::tag_texture_matrices_changed()
|
||||
{
|
||||
this->runtime->curve_texture_matrices.tag_dirty();
|
||||
|
||||
@@ -389,8 +389,7 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
"delta_time", AttrDomain::Point);
|
||||
SpanAttributeWriter<float> rotations = attributes.lookup_or_add_for_write_span<float>(
|
||||
"rotation", AttrDomain::Point);
|
||||
SpanAttributeWriter<ColorGeometry4f> vertex_colors =
|
||||
attributes.lookup_or_add_for_write_span<ColorGeometry4f>("vertex_color", AttrDomain::Point);
|
||||
MutableSpan<ColorGeometry4f> vertex_colors = drawing.fill_colors_for_write();
|
||||
SpanAttributeWriter<bool> selection = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".selection", AttrDomain::Point);
|
||||
MutableSpan<MDeformVert> dverts = use_dverts ? curves.wrap().deform_verts_for_write() :
|
||||
@@ -410,12 +409,7 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
"hardness", AttrDomain::Curve);
|
||||
SpanAttributeWriter<float> stroke_point_aspect_ratios =
|
||||
attributes.lookup_or_add_for_write_span<float>("aspect_ratio", AttrDomain::Curve);
|
||||
SpanAttributeWriter<ColorGeometry4f> stroke_fill_colors =
|
||||
attributes.lookup_or_add_for_write_span<ColorGeometry4f>(
|
||||
"fill_color",
|
||||
AttrDomain::Curve,
|
||||
bke::AttributeInitVArray(VArray<ColorGeometry4f>::ForSingle(
|
||||
ColorGeometry4f(float4(0.0f)), curves.curves_num())));
|
||||
MutableSpan<ColorGeometry4f> stroke_fill_colors = drawing.fill_colors_for_write();
|
||||
SpanAttributeWriter<int> stroke_materials = attributes.lookup_or_add_for_write_span<int>(
|
||||
"material_index", AttrDomain::Curve);
|
||||
|
||||
@@ -431,7 +425,7 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
stroke_hardnesses.span[stroke_i] = gps->hardness;
|
||||
stroke_point_aspect_ratios.span[stroke_i] = gps->aspect_ratio[0] /
|
||||
max_ff(gps->aspect_ratio[1], 1e-8);
|
||||
stroke_fill_colors.span[stroke_i] = ColorGeometry4f(gps->vert_color_fill);
|
||||
stroke_fill_colors[stroke_i] = ColorGeometry4f(gps->vert_color_fill);
|
||||
stroke_materials.span[stroke_i] = gps->mat_nr;
|
||||
|
||||
IndexRange points = points_by_curve[stroke_i];
|
||||
@@ -458,7 +452,7 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
MutableSpan<float> dst_opacities = opacities.slice(points);
|
||||
MutableSpan<float> dst_deltatimes = delta_times.span.slice(points);
|
||||
MutableSpan<float> dst_rotations = rotations.span.slice(points);
|
||||
MutableSpan<ColorGeometry4f> dst_vertex_colors = vertex_colors.span.slice(points);
|
||||
MutableSpan<ColorGeometry4f> dst_vertex_colors = vertex_colors.slice(points);
|
||||
MutableSpan<bool> dst_selection = selection.span.slice(points);
|
||||
MutableSpan<MDeformVert> dst_dverts = use_dverts ? dverts.slice(points) :
|
||||
MutableSpan<MDeformVert>();
|
||||
@@ -526,7 +520,6 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
|
||||
delta_times.finish();
|
||||
rotations.finish();
|
||||
vertex_colors.finish();
|
||||
selection.finish();
|
||||
|
||||
stroke_cyclic.finish();
|
||||
@@ -535,7 +528,6 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
||||
stroke_end_caps.finish();
|
||||
stroke_hardnesses.finish();
|
||||
stroke_point_aspect_ratios.finish();
|
||||
stroke_fill_colors.finish();
|
||||
stroke_materials.finish();
|
||||
}
|
||||
|
||||
|
||||
@@ -533,9 +533,7 @@ static void grease_pencil_geom_batch_ensure(Object &object,
|
||||
"hardness", bke::AttrDomain::Curve, 1.0f);
|
||||
const VArray<float> stroke_point_aspect_ratios = *attributes.lookup_or_default<float>(
|
||||
"aspect_ratio", bke::AttrDomain::Curve, 1.0f);
|
||||
const VArray<ColorGeometry4f> stroke_fill_colors =
|
||||
*attributes.lookup_or_default<ColorGeometry4f>(
|
||||
"fill_color", bke::AttrDomain::Curve, ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
const VArray<ColorGeometry4f> stroke_fill_colors = info.drawing.fill_colors();
|
||||
const VArray<int> materials = *attributes.lookup_or_default<int>(
|
||||
"material_index", bke::AttrDomain::Curve, 0);
|
||||
const VArray<float> u_translations = *attributes.lookup_or_default<float>(
|
||||
|
||||
@@ -166,13 +166,7 @@ void TintOperation::execute_tint(const bContext &C, const InputSample &extension
|
||||
bke::CurvesGeometry &strokes = drawing.strokes_for_write();
|
||||
|
||||
MutableSpan<ColorGeometry4f> vertex_colors = drawing.vertex_colors_for_write();
|
||||
bke::MutableAttributeAccessor stroke_attributes = strokes.attributes_for_write();
|
||||
bke::SpanAttributeWriter<ColorGeometry4f> fill_colors =
|
||||
stroke_attributes.lookup_or_add_for_write_span<ColorGeometry4f>(
|
||||
"fill_color",
|
||||
bke::AttrDomain::Curve,
|
||||
bke::AttributeInitVArray(VArray<ColorGeometry4f>::ForSingle(
|
||||
ColorGeometry4f(float4(0.0f)), strokes.curves_num())));
|
||||
MutableSpan<ColorGeometry4f> fill_colors = drawing.fill_colors_for_write();
|
||||
OffsetIndices<int> points_by_curve = strokes.points_by_curve();
|
||||
|
||||
const Span<float2> screen_space_positions =
|
||||
@@ -215,7 +209,7 @@ void TintOperation::execute_tint(const bContext &C, const InputSample &extension
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tint_fills && !fill_colors.span.is_empty()) {
|
||||
if (tint_fills && !fill_colors.is_empty()) {
|
||||
/* Will tint fill color when either the brush being inside the fill region or touching
|
||||
* the stroke. */
|
||||
const bool fill_effective = stroke_touched ||
|
||||
@@ -225,12 +219,12 @@ void TintOperation::execute_tint(const bContext &C, const InputSample &extension
|
||||
mouse_position);
|
||||
if (fill_effective) {
|
||||
float4 premultiplied;
|
||||
straight_to_premul_v4_v4(premultiplied, fill_colors.span[curve]);
|
||||
straight_to_premul_v4_v4(premultiplied, fill_colors[curve]);
|
||||
float4 rgba = float4(
|
||||
math::interpolate(float3(premultiplied), float3(color_), fill_strength),
|
||||
fill_colors.span[curve][3]);
|
||||
fill_colors[curve][3]);
|
||||
rgba[3] = rgba[3] * (1.0f - fill_strength) + fill_strength;
|
||||
premul_to_straight_v4_v4(fill_colors.span[curve], rgba);
|
||||
premul_to_straight_v4_v4(fill_colors[curve], rgba);
|
||||
stroke_touched = true;
|
||||
}
|
||||
}
|
||||
@@ -239,7 +233,6 @@ void TintOperation::execute_tint(const bContext &C, const InputSample &extension
|
||||
}
|
||||
}
|
||||
});
|
||||
fill_colors.finish();
|
||||
};
|
||||
|
||||
threading::parallel_for_each(drawings_, [&](const MutableDrawingInfo &info) {
|
||||
|
||||
@@ -136,14 +136,13 @@ static void modify_stroke_color(Object &ob,
|
||||
|
||||
static void modify_fill_color(Object &ob,
|
||||
const GreasePencilColorModifierData &cmd,
|
||||
bke::CurvesGeometry &curves,
|
||||
Drawing &drawing,
|
||||
const IndexMask &curves_mask)
|
||||
{
|
||||
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
const bke::AttributeAccessor attributes = curves.attributes();
|
||||
/* Fill color per stroke. */
|
||||
bke::SpanAttributeWriter<ColorGeometry4f> fill_colors =
|
||||
attributes.lookup_or_add_for_write_span<ColorGeometry4f>("fill_color",
|
||||
bke::AttrDomain::Curve);
|
||||
MutableSpan<ColorGeometry4f> fill_colors = drawing.fill_colors_for_write();
|
||||
const VArray<int> stroke_materials = *attributes.lookup_or_default<int>(
|
||||
"material_index", bke::AttrDomain::Curve, 0);
|
||||
|
||||
@@ -153,10 +152,8 @@ static void modify_fill_color(Object &ob,
|
||||
const ColorGeometry4f material_color = (gp_style ? ColorGeometry4f(gp_style->fill_rgba) :
|
||||
ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
|
||||
apply_color_factor(fill_colors.span[curve_i], material_color, cmd.hsv);
|
||||
apply_color_factor(fill_colors[curve_i], material_color, cmd.hsv);
|
||||
});
|
||||
|
||||
fill_colors.finish();
|
||||
}
|
||||
|
||||
static void modify_drawing(ModifierData &md, const ModifierEvalContext &ctx, Drawing &drawing)
|
||||
@@ -174,12 +171,12 @@ static void modify_drawing(ModifierData &md, const ModifierEvalContext &ctx, Dra
|
||||
*ctx.object, cmd, curves, curves_mask, drawing.vertex_colors_for_write());
|
||||
break;
|
||||
case MOD_GREASE_PENCIL_COLOR_FILL:
|
||||
modify_fill_color(*ctx.object, cmd, curves, curves_mask);
|
||||
modify_fill_color(*ctx.object, cmd, drawing, curves_mask);
|
||||
break;
|
||||
case MOD_GREASE_PENCIL_COLOR_BOTH:
|
||||
modify_stroke_color(
|
||||
*ctx.object, cmd, curves, curves_mask, drawing.vertex_colors_for_write());
|
||||
modify_fill_color(*ctx.object, cmd, curves, curves_mask);
|
||||
modify_fill_color(*ctx.object, cmd, drawing, curves_mask);
|
||||
break;
|
||||
case MOD_GREASE_PENCIL_COLOR_HARDNESS:
|
||||
BLI_assert_unreachable();
|
||||
|
||||
@@ -239,12 +239,13 @@ static void modify_stroke_color(Object &ob,
|
||||
|
||||
static void modify_fill_color(Object &ob,
|
||||
const GreasePencilTintModifierData &tmd,
|
||||
bke::CurvesGeometry &curves,
|
||||
Drawing &drawing,
|
||||
const IndexMask &curves_mask)
|
||||
{
|
||||
const bool use_weight_as_factor = (tmd.flag & MOD_GREASE_PENCIL_TINT_USE_WEIGHT_AS_FACTOR);
|
||||
const bool invert_vertex_group = (tmd.influence.flag &
|
||||
GREASE_PENCIL_INFLUENCE_INVERT_VERTEX_GROUP);
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
|
||||
const GreasePencilTintModifierMode tint_mode = GreasePencilTintModifierMode(tmd.tint_mode);
|
||||
|
||||
@@ -253,14 +254,9 @@ static void modify_fill_color(Object &ob,
|
||||
return;
|
||||
}
|
||||
|
||||
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
|
||||
bke::MutableAttributeAccessor attributes = drawing.strokes_for_write().attributes_for_write();
|
||||
/* Fill color per stroke. */
|
||||
bke::SpanAttributeWriter<ColorGeometry4f> fill_colors =
|
||||
attributes.lookup_or_add_for_write_span<ColorGeometry4f>(
|
||||
"fill_color",
|
||||
bke::AttrDomain::Curve,
|
||||
bke::AttributeInitVArray(VArray<ColorGeometry4f>::ForSingle(
|
||||
ColorGeometry4f(float4(0.0f)), curves.curves_num())));
|
||||
MutableSpan<ColorGeometry4f> fill_colors = drawing.fill_colors_for_write();
|
||||
const VArray<int> stroke_materials = *attributes.lookup_or_default<int>(
|
||||
"material_index", bke::AttrDomain::Curve, 0);
|
||||
const VArray<float> vgroup_weights = modifier::greasepencil::get_influence_vertex_weights(
|
||||
@@ -288,10 +284,8 @@ static void modify_fill_color(Object &ob,
|
||||
case MOD_GREASE_PENCIL_TINT_UNIFORM: {
|
||||
curves_mask.foreach_index(GrainSize(512), [&](int64_t curve_i) {
|
||||
const ColorGeometry4f material_color = get_material_color(curve_i);
|
||||
fill_colors.span[curve_i] = apply_uniform_tint(
|
||||
tmd,
|
||||
get_base_color(fill_colors.span[curve_i], material_color),
|
||||
get_curve_factor(curve_i));
|
||||
fill_colors[curve_i] = apply_uniform_tint(
|
||||
tmd, get_base_color(fill_colors[curve_i], material_color), get_curve_factor(curve_i));
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -308,18 +302,16 @@ static void modify_fill_color(Object &ob,
|
||||
const float3 pos = points.is_empty() ? float3(0.0f, 0.0f, 0.0f) :
|
||||
positions[points.first()];
|
||||
|
||||
fill_colors.span[curve_i] = apply_gradient_tint(
|
||||
fill_colors[curve_i] = apply_gradient_tint(
|
||||
tmd,
|
||||
matrix,
|
||||
pos,
|
||||
get_base_color(fill_colors.span[curve_i], material_color),
|
||||
get_base_color(fill_colors[curve_i], material_color),
|
||||
get_curve_factor(curve_i));
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fill_colors.finish();
|
||||
}
|
||||
|
||||
static void modify_opacity(const GreasePencilTintModifierData &tmd,
|
||||
@@ -365,12 +357,12 @@ static void modify_curves(ModifierData &md, const ModifierEvalContext &ctx, Draw
|
||||
*ctx.object, tmd, curves, curves_mask, drawing.vertex_colors_for_write());
|
||||
break;
|
||||
case MOD_GREASE_PENCIL_COLOR_FILL:
|
||||
modify_fill_color(*ctx.object, tmd, curves, curves_mask);
|
||||
modify_fill_color(*ctx.object, tmd, drawing, curves_mask);
|
||||
break;
|
||||
case MOD_GREASE_PENCIL_COLOR_BOTH:
|
||||
modify_stroke_color(
|
||||
*ctx.object, tmd, curves, curves_mask, drawing.vertex_colors_for_write());
|
||||
modify_fill_color(*ctx.object, tmd, curves, curves_mask);
|
||||
modify_fill_color(*ctx.object, tmd, drawing, curves_mask);
|
||||
break;
|
||||
case MOD_GREASE_PENCIL_COLOR_HARDNESS:
|
||||
BLI_assert_unreachable();
|
||||
|
||||
Reference in New Issue
Block a user