GPv3: Opacity modifier #116946

Merged
Lukas Tönne merged 52 commits from LukasTonne/blender:gp3-opacity-modifier into main 2024-01-16 16:56:22 +01:00
3 changed files with 74 additions and 38 deletions
Showing only changes of commit cbd61664ab - Show all commits

View File

@ -93,18 +93,24 @@ static void free_data(ModifierData *md)
}
static void modify_curves(ModifierData *md,
const ModifierEvalContext * /*ctx*/,
const ModifierEvalContext *ctx,
bke::CurvesGeometry &curves)
LukasTonne marked this conversation as resolved Outdated

Use the * operator overload to just store the VArray directly here

Use the * operator overload to just store the VArray directly here
{
GreasePencilOpacityModifierData *omd = (GreasePencilOpacityModifierData *)md;
UNUSED_VARS(omd);
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
bke::SpanAttributeWriter<float> opacities = attributes.lookup_or_add_for_write_span<float>(
"opacity", bke::AttrDomain::Point);
for (const int i : opacities.span.index_range()) {
opacities.span[i] *= 0.5f;
OffsetIndices<int> points_by_curve = curves.points_by_curve();
IndexMaskMemory mask_memory;
IndexMask curves_mask = greasepencil::get_filtered_stroke_mask(
ctx->object, curves, omd->filter, mask_memory);
for (const int64_t i : curves_mask.index_range()) {
const int64_t curve_i = curves_mask[i];
for (const int64_t point_i : points_by_curve[curve_i]) {
opacities.span[point_i] *= 0.5f;
}
}
opacities.finish();
@ -114,12 +120,10 @@ static void modify_geometry_set(ModifierData *md,
const ModifierEvalContext *ctx,
bke::GeometrySet *geometry_set)
{
GreasePencilOpacityModifierData *omd = (GreasePencilOpacityModifierData *)md;
const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
const int frame = scene->r.cfra;
LukasTonne marked this conversation as resolved Outdated

remove this and pass vgroup_weight to clamp fn? 😅

remove this and pass `vgroup_weight` to clamp fn? 😅

Haha yeah, this is the result of me trying to make sense of the logic of the old modifier.

Haha yeah, this is the result of me trying to make sense of the logic of the old modifier.
GreasePencilOpacityModifierData *omd = (GreasePencilOpacityModifierData *)md;
UNUSED_VARS(omd);
GreasePencil *grease_pencil = geometry_set->get_grease_pencil_for_write();
if (grease_pencil == nullptr) {
return;

View File

@ -125,6 +125,10 @@ static IndexMask get_filtered_layer_mask(const GreasePencil &grease_pencil,
const bool layer_pass_filter_invert,
IndexMaskMemory &memory)
{
if (!layer_name_filter && !layer_pass_filter) {
return {};
}
bke::AttributeAccessor layer_attributes = grease_pencil.attributes();
const Span<const Layer *> layers = grease_pencil.layers();
const VArray<int> layer_passes =
@ -166,44 +170,64 @@ IndexMask get_filtered_layer_mask(const GreasePencil &grease_pencil,
memory);
}
static Vector<bool> is_material_affected_by_modifier(const Object *ob,
const bke::CurvesGeometry &curves,
const Material *material_filter,
const std::optional<int> material_pass_filter,
const bool material_filter_invert,
const bool material_pass_filter_invert)
static IndexMask get_filtered_stroke_mask(const Object *ob,
const bke::CurvesGeometry &curves,
const Material *material_filter,
const std::optional<int> material_pass_filter,
const bool material_filter_invert,
const bool material_pass_filter_invert,
IndexMaskMemory &memory)
{
if (!material_filter && !material_pass_filter) {
return {};
}
const int material_filter_index = BKE_grease_pencil_object_material_index_get(
const_cast<Object *>(ob), const_cast<Material *>(material_filter));
const Vector<int> material_pass_by_index = get_grease_pencil_material_passes(ob);
bke::AttributeAccessor attributes = curves.attributes();
VArray<int> stroke_materials =
attributes.lookup_or_default<int>("material_index", bke::AttrDomain::Curve, 0).varray;
Vector<bool> result(curves.curves_num(), true);
if (material_filter != nullptr) {
const int material_filter_index = BKE_grease_pencil_object_material_index_get(
const_cast<Object *>(ob), const_cast<Material *>(material_filter));
for (const int stroke_i : result.index_range()) {
const int material_index = stroke_materials.get(stroke_i);
const bool match = (material_index == material_filter_index);
if (match == material_filter_invert) {
result[stroke_i] = false;
}
}
}
if (material_pass_filter) {
const Vector<int> material_pass_by_index = get_grease_pencil_material_passes(ob);
for (const int stroke_i : result.index_range()) {
const int material_index = stroke_materials.get(stroke_i);
const int material_pass = material_pass_by_index[material_index];
const bool match = (material_pass == material_pass_filter.value());
if (match == material_pass_filter_invert) {
result[stroke_i] = false;
}
}
}
IndexMask result = IndexMask::from_predicate(
curves.curves_range(), GrainSize(4096), memory, [&](const int64_t stroke_i) {
const int material_index = stroke_materials.get(stroke_i);
if (material_filter != nullptr) {
const bool match = (material_index == material_filter_index);
if (match == material_filter_invert) {
return false;
}
}
if (material_pass_filter) {
const int material_pass = material_pass_by_index[material_index];
const bool match = (material_pass == material_pass_filter.value());
if (match == material_pass_filter_invert) {
return false;
}
}
return true;
});
return result;
}
IndexMask get_filtered_stroke_mask(const Object *ob,
const bke::CurvesGeometry &curves,
const GreasePencilModifierFilterData &filter_data,
IndexMaskMemory &memory)
{
/* TODO Add an option to toggle pass filter on and off, instead of using "pass > 0". */
return get_filtered_stroke_mask(ob,
curves,
filter_data.material,
filter_data.material_pass > 0 ?
std::make_optional<int>(filter_data.material_pass) :
std::nullopt,
filter_data.flag & GREASE_PENCIL_FILTER_INVERT_MATERIAL,
filter_data.flag & GREASE_PENCIL_FILTER_INVERT_MATERIAL_PASS,
memory);
}
Vector<bke::greasepencil::Drawing *> get_drawings_for_write(GreasePencil &grease_pencil,
const IndexMask &layer_mask,
int frame)

View File

@ -17,9 +17,12 @@ struct ARegionType;
struct GreasePencil;
struct GreasePencilModifierFilterData;
struct PanelType;
namespace blender::bke::greasepencil {
namespace blender::bke {
class CurvesGeometry;
namespace greasepencil {
class Drawing;
}
} // namespace blender::bke
namespace blender::greasepencil {
@ -38,6 +41,11 @@ IndexMask get_filtered_layer_mask(const GreasePencil &grease_pencil,
const GreasePencilModifierFilterData &filter_data,
IndexMaskMemory &memory);
IndexMask get_filtered_stroke_mask(const Object *ob,
const bke::CurvesGeometry &curves,
const GreasePencilModifierFilterData &filter_data,
IndexMaskMemory &memory);
Vector<bke::greasepencil::Drawing *> get_drawings_for_write(GreasePencil &grease_pencil,
const IndexMask &layer_mask,
int frame);