40#include "RNA_prototypes.hh"
83 if (mmd->object !=
nullptr) {
106 const int time_alignment,
107 const int transition,
109 const bool clamp_points,
118 float max_length = 0;
120 const bool stroke_cyclic = cyclic[stroke];
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 /
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;
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) {
224 if (!point_counts_to_keep[curve]) {
227 const IndexRange points = points_by_curve[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;
315 int counted_points_num = 0;
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;
369 for (
const int point : points_by_curve[stroke]) {
370 dst_to_src_point[next_point] =
point;
373 dst_offsets[next_curve] = next_point;
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();
462 const IndexRange points = points_by_curve[stroke];
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; });
475 new_order[i] = distances[i].index;
476 r_selection[i] = distances[i].selected;
483 const float time_elapsed,
484 const float speed_fac,
486 const float frame_duration)
497 float accumulated_shift_delta_time = init_times[0];
499 const float previous_start_time = start_times[curve - 1];
500 const float previous_delta_time = delta_times[points_by_curve[curve - 1].last()];
501 const float previous_end_time = previous_start_time + previous_delta_time;
503 const float shifted_start_time = init_times[curve] - accumulated_shift_delta_time;
504 const float gap_delta_time =
math::min(shifted_start_time - previous_end_time, max_gap);
506 start_times[curve] = previous_end_time + gap_delta_time;
507 accumulated_shift_delta_time +=
math::max(shifted_start_time - start_times[curve], 0.0f);
514 const float max_time = start_times.
last() + delta_times.last();
519 const float time_compress_factor =
math::max(max_time / speed_fac / frame_duration, 1.0f);
522 const float limit = time_elapsed * speed_fac * time_compress_factor;
525 const float start_time = start_times[curve];
526 for (
const int point : points_by_curve[curve]) {
527 if (start_time + delta_times[
point] >= limit) {
537 const int current_frame,
538 const int start_frame,
539 const int frame_duration,
541 const float percentage,
543 const float scene_fps,
544 const float speed_fac,
551 float(use_time - start_frame) /
length, 0.0f, 1.0f) *
555 return build_factor_frames;
557 return percentage * (1.0f +
fade);
562 return build_factor_frames;
565 float(current_frame) / scene_fps,
568 float(frame_duration) / scene_fps) *
579 const int current_time,
580 const int frame_duration,
581 const float scene_fps)
597 const int prev_strokes = prev_curves.
curves_num();
598 const int added_strokes = curves.
curves_num() - prev_strokes;
599 if (added_strokes > 0) {
629 float factor_start = factor - fade_factor;
631 std::swap(factor, factor_start);
689 const int eval_frame = grease_pencil.
runtime->eval_frame;
693 grease_pencil, mmd->influence, mask_memory);
698 if (eval_frame < mmd->start_frame || eval_frame > mmd->end_frame) {
711 layer, eval_frame - 1);
718 const int relative_start_frame = eval_frame - start_frame;
723 int frame_duration = INT_MAX;
724 if (frame_index != layer.
sorted_keys().index_range().last()) {
725 const int next_frame = layer.
sorted_keys()[frame_index + 1];
733 relative_start_frame,
793 C, layout,
ptr,
"open_frame_range_panel",
IFACE_(
"Effective Range")))
822 "target_vertex_group",
830 C, layout,
ptr,
"open_influence_panel",
IFACE_(
"Influence")))
847 "GreasePencilBuildModifier",
849 "GreasePencilBuildModifierData",
851 &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
@ 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)
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr IndexRange drop_front(int64_t n) const
T last(const int64_t n=0) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
bool contains(const StringRef attribute_id) const
OffsetIndices< int > points_by_curve() const
IndexRange curves_range() const
void update_curve_types()
MutableAttributeAccessor attributes_for_write()
Span< float3 > positions() const
AttributeAccessor attributes() const
float evaluated_length_total_for_curve(int curve_index, bool cyclic) const
MutableSpan< int > offsets_for_write()
void ensure_evaluated_lengths() const
VArray< bool > cyclic() const
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
MutableSpan< float > opacities_for_write()
MutableSpan< float > radii_for_write()
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
void tag_topology_changed()
int sorted_keys_index_at(int frame_number) const
std::optional< int > start_frame_at(int frame_number) const
Span< FramesMapKeyT > sorted_keys() const
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 float get_factor_from_draw_speed(const bke::CurvesGeometry &curves, const float time_elapsed, const float speed_fac, const float max_gap, const float frame_duration)
static float get_build_factor(const GreasePencilBuildTimeMode time_mode, const int current_frame, const int start_frame, const int frame_duration, 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 modify_geometry_set(ModifierData *md, const ModifierEvalContext *ctx, bke::GeometrySet *geometry_set)
void parallel_sort(RandomAccessIterator begin, RandomAccessIterator end)
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 build_drawing(const GreasePencilBuildModifierData &mmd, const Object &ob, bke::greasepencil::Drawing &drawing, const bke::greasepencil::Drawing *previous_drawing, const int current_time, const int frame_duration, const float scene_fps)
static void panel_register(ARegionType *region_type)
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
VecBase< float, 3 > float3
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)
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]
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)