Fix default weight in grease pencil modifiers when vertex group not set

Grease pencil modifiers were using a default weight of 1.0 if the
influence vertex group is not found. Whether or not that is correct
depends on whether a vertex group is set (name not empty). In case the
name is set but the group is not found a weight of zero should be used.
This can happen in GP3 when no vertex is assigned to a vertex group,
since each drawing only has a subset of all the vertex groups.

A utility function was added to make this consistent and less error
prone.

Pull Request: https://projects.blender.org/blender/blender/pulls/117671
This commit is contained in:
Lukas Tönne
2024-01-30 17:19:35 +01:00
parent 236881ff9c
commit 237babd2e8
5 changed files with 31 additions and 19 deletions
@@ -134,8 +134,8 @@ static void modify_stroke_random(const Object &ob,
bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_span<float>(
"radius", bke::AttrDomain::Point);
const MutableSpan<float3> positions = curves.positions_for_write();
const VArray<float> vgroup_weights = *attributes.lookup_or_default<float>(
omd.influence.vertex_group_name, bke::AttrDomain::Point, 1.0f);
const VArray<float> vgroup_weights = modifier::greasepencil::get_influence_vertex_weights(
curves, omd.influence);
/* Make sure different modifiers get different seeds. */
const int seed = omd.seed + BLI_hash_string(ob.id.name + 2) + BLI_hash_string(omd.modifier.name);
@@ -204,8 +204,8 @@ static void modify_stroke_by_index(const GreasePencilOffsetModifierData &omd,
bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_span<float>(
"radius", bke::AttrDomain::Point);
const MutableSpan<float3> positions = curves.positions_for_write();
const VArray<float> vgroup_weights = *attributes.lookup_or_default<float>(
omd.influence.vertex_group_name, bke::AttrDomain::Point, 1.0f);
const VArray<float> vgroup_weights = modifier::greasepencil::get_influence_vertex_weights(
curves, omd.influence);
curves_mask.foreach_index(GrainSize(512), [&](const int64_t curve_i) {
const IndexRange points = points_by_curve[curve_i];
@@ -237,8 +237,8 @@ static void modify_stroke_by_material(const Object &ob,
bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_span<float>(
"radius", bke::AttrDomain::Point);
const MutableSpan<float3> positions = curves.positions_for_write();
const VArray<float> vgroup_weights = *attributes.lookup_or_default<float>(
omd.influence.vertex_group_name, bke::AttrDomain::Point, 1.0f);
const VArray<float> vgroup_weights = modifier::greasepencil::get_influence_vertex_weights(
curves, omd.influence);
const VArray<int> stroke_materials = *attributes.lookup_or_default<int>(
"material_index", bke::AttrDomain::Curve, 0);
@@ -270,8 +270,8 @@ static void modify_stroke_by_layer(const GreasePencilOffsetModifierData &omd,
bke::SpanAttributeWriter<float> radii = attributes.lookup_or_add_for_write_span<float>(
"radius", bke::AttrDomain::Point);
const MutableSpan<float3> positions = curves.positions_for_write();
const VArray<float> vgroup_weights = *attributes.lookup_or_default<float>(
omd.influence.vertex_group_name, bke::AttrDomain::Point, 1.0f);
const VArray<float> vgroup_weights = modifier::greasepencil::get_influence_vertex_weights(
curves, omd.influence);
const float factor = get_factor_from_index(omd, layers_num, layer_index);
@@ -87,10 +87,8 @@ static void modify_stroke_color(const GreasePencilOpacityModifierData &omd,
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
bke::SpanAttributeWriter<float> opacities = attributes.lookup_or_add_for_write_span<float>(
"opacity", bke::AttrDomain::Point);
const VArray<float> vgroup_weights =
attributes
.lookup_or_default<float>(omd.influence.vertex_group_name, bke::AttrDomain::Point, 1.0f)
.varray;
const VArray<float> vgroup_weights = modifier::greasepencil::get_influence_vertex_weights(
curves, omd.influence);
curves_mask.foreach_index(GrainSize(512), [&](const int64_t curve_i) {
const IndexRange points = points_by_curve[curve_i];
@@ -138,9 +136,8 @@ static void modify_fill_color(const GreasePencilOpacityModifierData &omd,
/* Fill color opacity per stroke. */
bke::SpanAttributeWriter<float> fill_opacities = attributes.lookup_or_add_for_write_span<float>(
"fill_opacity", bke::AttrDomain::Curve);
const StringRef vgroup_name = omd.influence.vertex_group_name;
const VArray<float> vgroup_weights =
attributes.lookup_or_default<float>(vgroup_name, bke::AttrDomain::Point, 1.0f).varray;
const VArray<float> vgroup_weights = modifier::greasepencil::get_influence_vertex_weights(
curves, omd.influence);
curves_mask.foreach_index(GrainSize(512), [&](int64_t curve_i) {
if (use_vgroup_opacity) {
@@ -174,8 +174,8 @@ static void modify_stroke_color(Object &ob,
bke::AttributeAccessor attributes = curves.attributes();
const VArray<int> stroke_materials = *attributes.lookup_or_default<int>(
"material_index", bke::AttrDomain::Curve, 0);
const VArray<float> vgroup_weights = *attributes.lookup_or_default<float>(
tmd.influence.vertex_group_name, bke::AttrDomain::Point, 1.0f);
const VArray<float> vgroup_weights = modifier::greasepencil::get_influence_vertex_weights(
curves, tmd.influence);
/* Common input color and base factor calculation. */
auto get_material_color = [&](const int64_t curve_i) {
@@ -261,8 +261,8 @@ static void modify_fill_color(Object &ob,
bke::AttrDomain::Curve);
const VArray<int> stroke_materials = *attributes.lookup_or_default<int>(
"material_index", bke::AttrDomain::Curve, 0);
const VArray<float> vgroup_weights = *attributes.lookup_or_default<float>(
tmd.influence.vertex_group_name, bke::AttrDomain::Point, 1.0f);
const VArray<float> vgroup_weights = modifier::greasepencil::get_influence_vertex_weights(
curves, tmd.influence);
/* Common input color and base factor calculation. */
auto get_material_color = [&](const int64_t curve_i) {
@@ -309,6 +309,18 @@ IndexMask get_filtered_stroke_mask(const Object *ob,
memory);
}
VArray<float> get_influence_vertex_weights(const bke::CurvesGeometry &curves,
const GreasePencilModifierInfluenceData &influence_data)
{
if (influence_data.vertex_group_name[0] == '\0') {
/* If vertex group is not set, use full weight for all vertices. */
return VArray<float>::ForSingle(1.0f, curves.point_num);
}
/* Vertex group weights, with zero weight as fallback. */
return *curves.attributes().lookup_or_default<float>(
influence_data.vertex_group_name, bke::AttrDomain::Point, 0.0f);
}
Vector<bke::greasepencil::Drawing *> get_drawings_for_write(GreasePencil &grease_pencil,
const IndexMask &layer_mask,
const int frame)
@@ -59,6 +59,9 @@ IndexMask get_filtered_stroke_mask(const Object *ob,
const GreasePencilModifierInfluenceData &influence_data,
IndexMaskMemory &memory);
VArray<float> get_influence_vertex_weights(
const bke::CurvesGeometry &curves, const GreasePencilModifierInfluenceData &influence_data);
Vector<bke::greasepencil::Drawing *> get_drawings_for_write(GreasePencil &grease_pencil,
const IndexMask &layer_mask,
int frame);