43#include "RNA_prototypes.hh"
51using bke::greasepencil::Drawing;
87 if (mmd->duplications <= 1) {
97 int &r_original_point_count)
101 curves, unselected_mask, {});
103 r_original_point_count = masked_curves.
points_num();
111 std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
121 options.keep_original_ids =
true;
122 options.realize_instance_attributes =
true;
142 const IndexMask unselected_mask = curves_mask.
complement(curves.curves_range(), mask_memory);
146 curves, curves_mask, unselected_mask, mmd.
duplications, src_point_count);
149 const float distance = mmd.
distance;
171 for (const int curve : range) {
172 for (const int point : points_by_curve[curve]) {
173 const float3 miter = math::cross(normals[curve], tangents[point]) * distance;
174 pos_l[point] = positions[point] + miter;
175 pos_r[point] = positions[point] - miter;
180 const Span<float3> stroke_pos_l = pos_l.as_span();
181 const Span<float3> stroke_pos_r = pos_r.as_span();
183 for (
const int i : IndexRange(mmd.duplications)) {
185 const IndexRange stroke = IndexRange(src_point_count * i, src_point_count);
186 MutableSpan<float3> instance_positions = positions.slice(stroke);
187 MutableSpan<float> instance_opacity = opacities.span.slice(stroke);
188 MutableSpan<float> instance_radii = radii.span.slice(stroke);
189 const float offset_fac = (mmd.duplications == 1) ?
191 (1.0f - (
float(i) /
float(mmd.duplications - 1)));
192 const float fading_fac =
fabsf(offset_fac - fading_center);
193 const float thickness_factor = use_fading ? mix2(fading_fac, 1.0f, 1.0f - fading_thickness) :
195 const float opacity_factor = use_fading ? mix2(fading_fac, 1.0f, 1.0f - fading_opacity) : 1.0f;
197 for (const int point : range) {
198 const float fac = mix2(float(i) / float(mmd.duplications - 1), 1 + offset, offset);
199 const int old_point = point % src_point_count;
200 instance_positions[point] = mix2(fac, stroke_pos_l[old_point], stroke_pos_r[old_point]);
201 instance_radii[point] *= thickness_factor;
202 instance_opacity[point] *= opacity_factor;
210 curves = std::move(duplicated_strokes);
211 drawing.tag_topology_changed();
224 const int frame = grease_pencil.
runtime->eval_frame;
227 const IndexMask layer_mask = modifier::greasepencil::get_filtered_layer_mask(
228 grease_pencil, mmd->influence, memory);
229 const Vector<Drawing *> drawings = modifier::greasepencil::get_drawings_for_write(
230 grease_pencil, layer_mask, frame);
231 threading::parallel_for_each(drawings,
252 C, layout,
ptr,
"open_fading_panel",
IFACE_(
"Fade")))
266 C, layout,
ptr,
"open_influence_panel",
IFACE_(
"Influence")))
268 modifier::greasepencil::draw_layer_filter_settings(C, influence_panel,
ptr);
269 modifier::greasepencil::draw_material_filter_settings(C, influence_panel,
ptr);
285 modifier::greasepencil::write_influence_data(writer, &mmd->influence);
292 modifier::greasepencil::read_influence_data(reader, &mmd->influence);
298 "GreasePencilMultiply",
299 N_(
"Multiple Strokes"),
300 "GreasePencilMultiModifierData",
302 &RNA_GreasePencilMultiplyModifier,
Low-level operations for curves.
Low-level operations for grease pencil.
General operations, lookup, etc. for materials.
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_SupportsMapping
@ eModifierTypeFlag_AcceptsGreasePencil
@ eModifierTypeFlag_EnableInEditmode
@ eModifierTypeFlag_SupportsEditmode
void(*)(void *user_data, Object *ob, ID **idpoin, int cb_flag) IDWalkFunc
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define DNA_struct_default_get(struct_name)
@ MOD_GREASE_PENCIL_MULTIPLY_ENABLE_FADING
@ eModifierType_GreasePencilMultiply
struct GreasePencilMultiModifierData GreasePencilMultiModifierData
Read Guarded memory(de)allocation.
static void panel_register(ARegionType *region_type)
static void blend_read(BlendDataReader *, ModifierData *md)
static void panel_draw(const bContext *, Panel *panel)
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
ModifierTypeInfo modifierType_GreasePencilMultiply
static void modify_geometry_set(ModifierData *md, const ModifierEvalContext *ctx, blender::bke::GeometrySet *geometry_set)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
PanelLayout uiLayoutPanelProp(const bContext *C, uiLayout *layout, PointerRNA *open_prop_owner, const char *open_prop_name)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
MutableSpan< float3 > positions_for_write()
MutableAttributeAccessor attributes_for_write()
Span< float3 > evaluated_tangents() const
Span< float3 > curve_plane_normals() const
bke::CurvesGeometry & strokes_for_write()
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
CCL_NAMESPACE_BEGIN struct Options options
draw_view in_light_buf[] float
T mix2(float factor, const T &a, const T &b)
CurvesGeometry curves_copy_curve_selection(const CurvesGeometry &curves, const IndexMask &curves_to_copy, const AttributeFilter &attribute_filter)
Curves * curves_new_nomain(int points_num, int curves_num)
bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, const RealizeInstancesOptions &options)
T length(const VecBase< T, Size > &a)
VecBase< T, 3 > to_scale(const MatBase< T, NumCol, NumRow > &mat)
void init_influence_data(GreasePencilModifierInfluenceData *influence_data, const bool has_custom_curve)
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)
void free_influence_data(GreasePencilModifierInfluenceData *influence_data)
void foreach_influence_ID_link(GreasePencilModifierInfluenceData *influence_data, Object *ob, IDWalkFunc walk, void *user_data)
void copy_influence_data(const GreasePencilModifierInfluenceData *influence_data_src, GreasePencilModifierInfluenceData *influence_data_dst, const int)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
static void init_data(ModifierData *md)
static bke::CurvesGeometry duplicate_strokes(const bke::CurvesGeometry &curves, const IndexMask curves_mask, const IndexMask unselected_mask, const int count, int &r_original_point_count)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void modify_geometry_set(ModifierData *md, const ModifierEvalContext *ctx, bke::GeometrySet *geometry_set)
static void free_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static bool is_disabled(const Scene *, ModifierData *md, bool)
static void blend_read(BlendDataReader *reader, ModifierData *md)
static void generate_curves(GreasePencilMultiModifierData &mmd, const ModifierEvalContext &ctx, Drawing &drawing)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
GreasePencilModifierInfluenceData influence
GreasePencilRuntimeHandle * runtime
static MatBase identity()
static GeometrySet from_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
static GeometrySet from_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Curves * get_curves_for_write()
bool has_grease_pencil() const
GreasePencil * get_grease_pencil_for_write()