40#include "RNA_prototypes.hh"
83 if (mmd->object !=
nullptr) {
106 const int time_alignment,
107 const int transition,
109 const bool clamp_points,
113 const int stroke_count = curves.curves_num();
117 curves.ensure_evaluated_lengths();
118 float max_length = 0;
119 for (
const int stroke : curves.curves_range()) {
120 const bool stroke_cyclic = cyclic[stroke];
121 const float len = curves.evaluated_length_total_for_curve(stroke, stroke_cyclic);
128 r_curves_num = r_points_num = 0;
129 factor_to_keep = std::clamp(factor_to_keep, 0.0f, 1.0f);
132 auto get_stroke_factor = [&](
const float factor,
const int index) {
133 const bool stroke_cyclic = cyclic[index];
134 const float max_factor = max_length /
135 curves.evaluated_length_total_for_curve(index, stroke_cyclic);
138 return std::clamp(factor * max_factor, 0.0f, 1.0f);
140 return factor * max_factor;
143 const float min_factor = max_factor - 1.0f;
144 const float use_factor = factor * max_factor;
146 return std::clamp(use_factor - min_factor, 0.0f, 1.0f);
148 return use_factor - min_factor;
154 selection.to_bools(
select.as_mutable_span());
156 for (
const int curve : curves.curves_range()) {
157 const float local_factor =
select[
curve] ? get_stroke_factor(factor_to_keep, curve) : 1.0f;
158 const int num_points = points_by_curve[
curve].
size() * local_factor;
159 result[
curve] = num_points;
161 r_points_num += num_points;
162 if (num_points > 0) {
173 const int time_alignment,
174 const int transition,
176 const float factor_start,
177 const float factor_opacity,
178 const float factor_radii,
181 int dst_curves_num, dst_points_num;
182 const bool has_fade = factor_start != factor;
184 curves, selection, time_alignment, transition, factor,
true, dst_curves_num, dst_points_num);
185 if (dst_curves_num == 0) {
223 for (
const int curve : curves.curves_range()) {
224 if (!point_counts_to_keep[curve]) {
228 dst_offsets[next_curve] = point_counts_to_keep[
curve];
229 const int curve_size = points.
size();
231 auto get_fade_weight = [&](
const int local_index) {
232 const float fade_range = std::abs(ends_per_curve[curve] - starts_per_curve[curve]);
234 const float factor_from_start = local_index - curve_size + ends_per_curve[
curve];
235 return 1.0f - std::clamp(factor_from_start / fade_range, 0.0f, 1.0f);
237 const float factor_from_start = local_index - starts_per_curve[
curve];
238 return std::clamp(factor_from_start / fade_range, 0.0f, 1.0f);
241 const int extra_offset = is_vanishing ? points.size() - point_counts_to_keep[
curve] : 0;
242 for (
const int stroke_point :
IndexRange(point_counts_to_keep[curve])) {
243 const int src_point_index = points.
first() + extra_offset + stroke_point;
245 const float fade_weight = get_fade_weight(extra_offset + stroke_point);
246 opacities[src_point_index] = opacities[src_point_index] *
247 (1.0f - fade_weight * factor_opacity);
248 radii[src_point_index] = radii[src_point_index] * (1.0f - fade_weight * factor_radii);
249 if (!weights.
span.is_empty()) {
250 weights.
span[src_point_index] = fade_weight;
253 dst_to_src_point[next_point] = src_point_index;
256 dst_to_src_curve[next_curve] =
curve;
266 gather_attributes(src_attributes,
272 gather_attributes(src_attributes,
286 const int transition,
288 const bool clamp_points,
298 factor_to_keep = std::clamp(factor_to_keep, 0.0f, 1.0f);
305 const int untouched_points_num = points_by_curve.
total_size() - effective_points_num;
306 effective_points_num *= factor_to_keep;
307 effective_points_num += untouched_points_num;
309 r_points_num = effective_points_num;
313 selection.to_bools(
select.as_mutable_span());
315 int counted_points_num = 0;
316 for (
const int i : curves.curves_range()) {
317 const int stroke = is_vanishing ? stroke_count - i - 1 : i;
318 if (
select[stroke] && counted_points_num >= effective_points_num) {
321 counted_points_num += points_by_curve[stroke].
size();
329 const int transition,
331 const float factor_start,
332 const float factor_opacity,
333 const float factor_radii,
336 const bool has_fade = factor_start != factor;
337 int dst_curves_num, dst_points_num;
338 int start_points_num, end_points_num, dummy_curves_num;
340 curves, selection, transition, factor,
true, dst_curves_num, dst_points_num);
342 if (dst_curves_num == 0) {
347 curves, selection, transition, factor_start,
false, dummy_curves_num, start_points_num);
349 curves, selection, transition, factor,
false, dummy_curves_num, end_points_num);
366 int next_curve = 1, next_point = 0;
368 selection.complement(curves.curves_range(), memory).foreach_index([&](
const int stroke) {
369 for (
const int point : points_by_curve[stroke]) {
370 dst_to_src_point[next_point] =
point;
373 dst_offsets[next_curve] = next_point;
377 const int stroke_count = curves.curves_num();
378 bool done_scanning =
false;
379 selection.foreach_index([&](
const int i) {
380 const int stroke = is_vanishing ? stroke_count - i - 1 : i;
381 if (done_scanning || next_point >= dst_points_num) {
382 done_scanning =
true;
386 auto get_fade_weight = [&](
const int next_point_count) {
387 return std::clamp(
float(next_point_count - start_points_num) /
388 float(
abs(end_points_num - start_points_num)),
393 const IndexRange points = points_by_curve[stroke];
394 for (
const int point : points) {
395 const int local_index = point - points.first();
396 const int src_point_index = is_vanishing ? points.last() - local_index :
point;
397 dst_to_src_point[next_point] = src_point_index;
400 const float fade_weight = get_fade_weight(next_point);
401 opacities[src_point_index] = opacities[src_point_index] *
402 (1.0f - fade_weight * factor_opacity);
403 radii[src_point_index] = radii[src_point_index] * (1.0f - fade_weight * factor_radii);
404 if (!weights.
span.is_empty()) {
405 weights.
span[src_point_index] = fade_weight;
410 if (next_point >= dst_points_num) {
411 done_scanning =
true;
415 dst_offsets[next_curve] = next_point;
416 dst_to_src_curve[next_curve - 1] = i;
421 BLI_assert(next_curve == (dst_curves_num + 1));
427 gather_attributes(src_attributes,
433 gather_attributes(src_attributes,
452 const float3 center =
object.object_to_world().location();
461 for (
const int stroke : curves.curves_range()) {
462 const IndexRange points = points_by_curve[stroke];
463 const float3 p1 = positions[points.first()];
464 const float3 p2 = positions[points.last()];
466 distances[stroke].index = stroke;
467 distances[stroke].selected =
select[stroke];
471 distances.
begin(), distances.
end(), [](Pair &a, Pair &
b) { return a.value < b.value; });
474 for (
const int i : curves.curves_range()) {
475 new_order[i] = distances[i].index;
476 r_selection[i] = distances[i].selected;
483 const float time_elapsed,
484 const float speed_fac,
489 const VArray<float> init_times = *attributes.lookup_or_default<
float>(
491 const VArray<float> delta_times = *attributes.lookup_or_default<
float>(
496 float accumulated_shift_delta_time = init_times[0];
497 for (
const int curve : curves.curves_range().drop_front(1)) {
498 const float previous_start_time = start_times[curve - 1];
499 const float previous_delta_time = delta_times[points_by_curve[curve - 1].last()];
500 const float previous_end_time = previous_start_time + previous_delta_time;
502 const float shifted_start_time = init_times[
curve] - accumulated_shift_delta_time;
503 const float gap_delta_time =
math::min(shifted_start_time - previous_end_time, max_gap);
505 start_times[
curve] = previous_end_time + gap_delta_time;
506 accumulated_shift_delta_time +=
math::max(shifted_start_time - start_times[curve], 0.0f);
508 const float limit = time_elapsed * speed_fac;
509 for (
const int curve : curves.curves_range()) {
510 const float start_time = start_times[
curve];
511 for (
const int point : points_by_curve[
curve]) {
512 if (start_time + delta_times[point] >= limit) {
513 return math::clamp(
float(point) /
float(curves.points_num()), 0.0f, 1.0f);
522 const int current_frame,
523 const int start_frame,
525 const float percentage,
527 const float scene_fps,
528 const float speed_fac,
533 float(current_frame - start_frame) / length, 0.0f, 1.0f) *
537 return build_factor_frames;
539 return percentage * (1.0f +
fade);
543 if (!curves.attributes().contains(
"delta_time")) {
544 return build_factor_frames;
547 curves,
float(current_frame) / scene_fps, speed_fac, max_gap) *
558 const int current_time,
559 const float scene_fps)
564 if (curves.points_num() == 0) {
575 const int prev_strokes = prev_curves.
curves_num();
576 const int added_strokes = curves.curves_num() - prev_strokes;
577 if (added_strokes > 0) {
586 const int curves_num = curves.curves_num();
588 selection.to_bools(
select);
606 float factor_start = factor - fade_factor;
608 std::swap(factor, factor_start);
666 const int eval_frame = grease_pencil.
runtime->eval_frame;
670 grease_pencil, mmd->influence, mask_memory);
675 if (eval_frame < mmd->start_frame || eval_frame > mmd->end_frame) {
681 const float scene_fps =
float(scene.r.frs_sec) / scene.r.frs_sec_base;
688 layer, eval_frame - 1);
692 const int start_frame = *layer.start_frame_at(eval_frame);
695 const int relative_start_frame = eval_frame - start_frame;
697 const int frame_index = layer.sorted_keys_index_at(eval_frame);
700 int time = relative_start_frame;
701 if (frame_index != layer.sorted_keys().index_range().last()) {
702 const int next_frame = layer.sorted_keys()[frame_index + 1];
703 const int frame_duration =
math::distance(start_frame, next_frame);
705 math::min(
float(frame_duration), mmd->length) * mmd->length);
766 C, layout,
ptr,
"open_frame_range_panel",
IFACE_(
"Effective Range")))
795 "target_vertex_group",
803 C, layout,
ptr,
"open_influence_panel",
IFACE_(
"Influence")))
820 "GreasePencilBuildModifier",
822 "GreasePencilBuildModifierData",
824 &RNA_GreasePencilBuildModifier,
Low-level operations for curves.
Low-level operations for grease pencil.
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_AcceptsGreasePencil
@ eModifierTypeFlag_EnableInEditmode
@ eModifierTypeFlag_SupportsEditmode
void(*)(void *user_data, Object *ob, ID **idpoin, int cb_flag) IDWalkFunc
#define BLI_assert_unreachable()
#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)
void DEG_add_object_relation(DepsNodeHandle *node_handle, Object *object, eDepsObjectComponentType component, const char *description)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
#define DNA_struct_default_get(struct_name)
GreasePencilBuildTimeMode
@ MOD_GREASE_PENCIL_BUILD_TIMEMODE_PERCENTAGE
@ MOD_GREASE_PENCIL_BUILD_TIMEMODE_DRAWSPEED
@ MOD_GREASE_PENCIL_BUILD_TIMEMODE_FRAMES
@ MOD_GREASE_PENCIL_BUILD_TIMEALIGN_START
@ MOD_GREASE_PENCIL_BUILD_TIMEALIGN_END
@ MOD_GREASE_PENCIL_BUILD_MODE_SEQUENTIAL
@ MOD_GREASE_PENCIL_BUILD_MODE_ADDITIVE
@ MOD_GREASE_PENCIL_BUILD_MODE_CONCURRENT
@ MOD_GREASE_PENCIL_BUILD_RESTRICT_TIME
@ MOD_GREASE_PENCIL_BUILD_USE_FADING
@ eModifierType_GreasePencilBuild
struct GreasePencilBuildModifierData GreasePencilBuildModifierData
@ MOD_GREASE_PENCIL_BUILD_TRANSITION_VANISH
@ MOD_GREASE_PENCIL_BUILD_TRANSITION_GROW
Object is a sort of wrapper for general info.
ModifierTypeInfo modifierType_GreasePencilBuild
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)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
void uiItemPointerR(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *searchptr, const char *searchpropname, const char *name, int icon)
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)
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
void update_curve_types()
MutableAttributeAccessor attributes_for_write()
MutableSpan< int > offsets_for_write()
MutableSpan< float > opacities_for_write()
MutableSpan< float > radii_for_write()
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
void tag_topology_changed()
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
bke::CurvesGeometry reorder_curves_geometry(const bke::CurvesGeometry &src_curves, Span< int > old_by_new_map, const bke::AttributeFilter &attribute_filter)
T clamp(const T &a, const T &min, const T &max)
T distance(const T &a, const T &b)
T min(const T &a, const T &b)
T max(const T &a, const T &b)
void read_influence_data(BlendDataReader *reader, GreasePencilModifierInfluenceData *influence_data)
void init_influence_data(GreasePencilModifierInfluenceData *influence_data, const bool has_custom_curve)
Vector< LayerDrawingInfo > get_drawing_infos_by_layer(GreasePencil &grease_pencil, const IndexMask &layer_mask, const int frame)
static IndexMask get_filtered_layer_mask(const GreasePencil &grease_pencil, const std::optional< StringRef > layer_name_filter, const std::optional< int > layer_pass_filter, const bool layer_filter_invert, const bool layer_pass_filter_invert, IndexMaskMemory &memory)
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 write_influence_data(BlendWriter *writer, const GreasePencilModifierInfluenceData *influence_data)
void draw_material_filter_settings(const bContext *, uiLayout *layout, PointerRNA *ptr)
void draw_layer_filter_settings(const bContext *, uiLayout *layout, PointerRNA *ptr)
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 ensure_no_bezier_curves(Drawing &drawing)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
int sum_group_sizes(OffsetIndices< int > offsets, const IndexMask &mask)
void parallel_for_each(Range &&range, const Function &function)
static Array< int > point_counts_to_keep_concurrent(const bke::CurvesGeometry &curves, const IndexMask &selection, const int time_alignment, const int transition, const float factor, const bool clamp_points, int &r_curves_num, int &r_points_num)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
static bke::CurvesGeometry build_sequential(bke::greasepencil::Drawing &drawing, bke::CurvesGeometry &curves, const IndexMask &selection, const int transition, const float factor, const float factor_start, const float factor_opacity, const float factor_radii, StringRefNull target_vgname)
static void init_data(ModifierData *md)
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
static void points_info_sequential(const bke::CurvesGeometry &curves, const IndexMask &selection, const int transition, const float factor, const bool clamp_points, int &r_curves_num, int &r_points_num)
static void panel_draw(const bContext *C, Panel *panel)
static void modify_geometry_set(ModifierData *md, const ModifierEvalContext *ctx, bke::GeometrySet *geometry_set)
void parallel_sort(RandomAccessIterator begin, RandomAccessIterator end)
static void build_drawing(const GreasePencilBuildModifierData &mmd, const Object &ob, bke::greasepencil::Drawing &drawing, const bke::greasepencil::Drawing *previous_drawing, const int current_time, const float scene_fps)
static bke::CurvesGeometry reorder_strokes(const bke::CurvesGeometry &curves, const Span< bool > select, const Object &object, MutableSpan< bool > r_selection)
static void free_data(ModifierData *md)
static void panel_register(ARegionType *region_type)
static float get_factor_from_draw_speed(const bke::CurvesGeometry &curves, const float time_elapsed, const float speed_fac, const float max_gap)
static float get_build_factor(const GreasePencilBuildTimeMode time_mode, const int current_frame, const int start_frame, const int length, const float percentage, const bke::CurvesGeometry &curves, const float scene_fps, const float speed_fac, const float max_gap, const float fade)
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
static void blend_read(BlendDataReader *reader, ModifierData *md)
static bke::CurvesGeometry build_concurrent(bke::greasepencil::Drawing &drawing, bke::CurvesGeometry &curves, const IndexMask &selection, const int time_alignment, const int transition, const float factor, const float factor_start, const float factor_opacity, const float factor_radii, StringRefNull target_vgname)
CCL_NAMESPACE_BEGIN ccl_device float fade(float t)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
GreasePencilModifierInfluenceData influence
float fade_opacity_strength
float fade_thickness_strength
GreasePencilRuntimeHandle * runtime
bool has_grease_pencil() const
GreasePencil * get_grease_pencil_for_write()
MutableVArraySpan< T > span
bke::greasepencil::Drawing * drawing
ccl_device_inline int abs(int x)