77#include "RNA_prototypes.hh"
107 grease_pencil->
root_group_ptr = MEM_new<greasepencil::LayerGroup>(__func__);
108 grease_pencil->set_active_node(
nullptr);
113 grease_pencil->
runtime = MEM_new<GreasePencilRuntime>(__func__);
128 "RNA struct GreasePencilLayer is expected to have a 'hide' property.");
132 "RNA struct GreasePencilLayerGroup is expected to have a 'hide' property.");
136 &id_dst, &RNA_GreasePencilLayerGroup, layer_group);
141 "It should be possible to construct the RNA path of a grease pencil layer group.");
143 layer_group->runtime->is_visibility_animated_ = animdata::prop_is_animated(
144 grease_pencil.
adt, rna_path->c_str(), 0);
149 if (parent.runtime->is_visibility_animated_) {
154 return parent_group_visibility_animated(*parent_group);
160 if (parent_group_visibility_animated(layer->parent_group())) {
161 layer->runtime->is_visibility_animated_ =
true;
168 "It should be possible to construct the RNA path of a grease pencil layer.");
169 layer->runtime->is_visibility_animated_ = animdata::prop_is_animated(
170 grease_pencil.
adt, rna_path.value(), 0);
175 std::optional<Library *> ,
192 grease_pencil_dst->
root_group_ptr = MEM_new<bke::greasepencil::LayerGroup>(
193 __func__, grease_pencil_src->root_group());
196 if (grease_pencil_src->get_active_node()) {
198 grease_pencil_src->get_active_node()->name());
200 grease_pencil_dst->set_active_node(active_node);
206 grease_pencil_dst->layers().size());
214 grease_pencil_dst->
runtime = MEM_new<bke::GreasePencilRuntime>(__func__);
216 if (grease_pencil_src->
runtime->bake_materials) {
217 grease_pencil_dst->
runtime->bake_materials = std::make_unique<bke::bake::BakeMaterialsList>(
218 *grease_pencil_src->
runtime->bake_materials);
235 MEM_delete(&grease_pencil->root_group());
241 MEM_delete(grease_pencil->
runtime);
242 grease_pencil->
runtime =
nullptr;
276 {{AttrDomain::Layer, &layers_data_layers}},
280 grease_pencil->layers().size(),
283 grease_pencil->attribute_storage.dna_attributes = attribute_data.attributes.data();
284 grease_pencil->attribute_storage.dna_attributes_num = attribute_data.attributes.size();
291 &grease_pencil->layers_data,
293 grease_pencil->layers().size(),
296 grease_pencil->attribute_storage.wrap().blend_write(*writer, attribute_data);
305 writer, grease_pencil->material_array_num, grease_pencil->material_array);
333 grease_pencil->
runtime = MEM_new<blender::bke::GreasePencilRuntime>(__func__);
337 GreasePencil::id_type,
343 N_(
"grease_pencils_v3"),
386 const T default_value =
T())
396 if (
data !=
nullptr) {
401 if (span.
first() != default_value) {
402 span.
fill(default_value);
414 this->
runtime = MEM_new<bke::greasepencil::DrawingRuntime>(__func__);
424 this->
runtime = MEM_new<bke::greasepencil::DrawingRuntime>(__func__);
426 this->
runtime->triangle_offsets_cache = other.
runtime->triangle_offsets_cache;
428 this->
runtime->curve_plane_normals_cache = other.
runtime->curve_plane_normals_cache;
429 this->
runtime->curve_texture_matrices = other.
runtime->curve_texture_matrices;
442 other.runtime =
nullptr;
447 if (
this == &other) {
450 std::destroy_at(
this);
457 if (
this == &other) {
460 std::destroy_at(
this);
461 new (
this)
Drawing(std::move(other));
480 for (
const int curve_i : points_by_curve.index_range()) {
481 const IndexRange points = points_by_curve[curve_i];
482 r_offsets[curve_i] = offset;
483 offset += std::max(
int(points.
size() - 2), 0);
485 r_offsets.
last() = offset;
487 return this->
runtime->triangle_offsets_cache.
data().as_span();
497 struct LocalMemArena {
503 if (pf_arena !=
nullptr) {
511 for (
const int curve_i : mask_segment) {
512 const IndexRange points = points_by_curve[curve_i];
513 if (points.
size() < 3) {
518 float(*projverts)[2] =
static_cast<float(*)[2]
>(
529 projverts, points.
size(), 0,
reinterpret_cast<uint32_t(*)[3]
>(r_tris.
data()), pf_arena);
540 const int total_triangles = triangle_offsets.
total_size();
541 r_data.
resize(total_triangles);
544 this->curve_plane_normals(),
551 return this->
runtime->triangles_cache.data().as_span();
560 const IndexRange points = points_by_curve[curve_i];
561 if (points.
size() < 2) {
562 normals[curve_i] = float3(1.0f, 0.0f, 0.0f);
569 for (
const int point_i : points) {
570 const float3 curr_point = positions[point_i];
572 prev_point = curr_point;
579 for (
const int point_i : points.
drop_back(1)) {
580 float3 segment_vec = positions[point_i] - positions[point_i + 1];
602 return this->
runtime->curve_plane_normals_cache.
data().as_span();
613 if (positions.
size() <= 2) {
617 const float3 point_0 = positions[0];
618 const float3 point_1 = positions[1];
625 if (length_squared(local_x) == 0.0f || length_squared(local_y) == 0.0f) {
641 const float2 uv_translation,
646 const float2 uv_scale_inv = safe_rcp(uv_scale);
647 const float s =
sin(uv_rotation);
648 const float c =
cos(uv_rotation);
665 texture_matrix = from_scale<float2x2>(uv_scale_inv) * texture_matrix;
668 texture_matrix =
rot * texture_matrix;
671 texture_matrix[2] += uv_translation;
673 return texture_matrix;
690 strokemat4x3[2][2] = 0.0f;
691 strokemat4x3[3][2] = 1.0f;
715 for (const int curve_i : range) {
716 const IndexRange points = points_by_curve[curve_i];
717 const float3 normal = normals[curve_i];
718 const float4x2 strokemat = get_local_to_stroke_matrix(positions.slice(points), normal);
719 const float3x2 texture_matrix = get_stroke_to_texture_matrix(
720 uv_rotations[curve_i], uv_translations[curve_i], uv_scales[curve_i]);
722 const float4x2 texspace = texture_matrix * expand_4x2_mat(strokemat);
724 r_data[curve_i] = texspace;
728 return this->runtime->curve_texture_matrices.
data().as_span();
744 if (!uv_rotations || !uv_translations || !uv_scales) {
754 const IndexRange points = points_by_curve[curve_i];
780 const double3x4 right_inverse = transpose_strokemat *
786 const float2 uv_translation = texture_matrix[2];
789 const float uv_rotation =
math::atan2(texture_matrix[0][1], texture_matrix[0][0]);
799 uv_rotations.
span[curve_i] = uv_rotation;
800 uv_translations.span[curve_i] = uv_translation;
801 uv_scales.span[curve_i] = uv_scale;
804 uv_translations.finish();
807 this->tag_texture_matrices_changed();
812 return this->geometry.wrap();
817 return this->geometry.wrap();
822 return *this->strokes().attributes().lookup_or_default<
float>(
834 return *this->strokes().attributes().lookup_or_default<
float>(
846 return *this->strokes().attributes().lookup_or_default<
ColorGeometry4f>(
860 return *this->strokes().attributes().lookup_or_default<
ColorGeometry4f>(
874 this->runtime->curve_texture_matrices.tag_dirty();
879 this->strokes_for_write().tag_positions_changed();
880 this->runtime->curve_plane_normals_cache.tag_dirty();
881 this->runtime->triangles_cache.tag_dirty();
882 this->tag_texture_matrices_changed();
895 if (changed_curves.
size() >
this->strokes().curves_num() / 2) {
896 this->tag_positions_changed();
899 if (!this->runtime->triangles_cache.is_cached() ||
900 !
this->runtime->curve_plane_normals_cache.is_cached())
902 this->tag_positions_changed();
907 this->strokes_for_write().tag_positions_changed();
913 this->runtime->triangles_cache.update([&](
Vector<int3> &triangles) {
916 this->curve_plane_normals(),
918 this->triangle_offsets(),
922 this->tag_texture_matrices_changed();
927 this->runtime->triangle_offsets_cache.tag_dirty();
928 this->tag_positions_changed();
929 this->strokes_for_write().tag_topology_changed();
942 if (changed_curves.
size() >
this->strokes().curves_num() / 2) {
943 this->tag_topology_changed();
946 if (!this->runtime->triangles_cache.is_cached() ||
947 !
this->runtime->curve_plane_normals_cache.is_cached())
949 this->tag_topology_changed();
954 this->strokes_for_write().tag_positions_changed();
962 const Array<int> src_triangle_offset_data(this->triangle_offsets().
data());
966 this->runtime->triangle_offsets_cache.tag_dirty();
968 this->runtime->triangles_cache.update([&](
Vector<int3> &triangles) {
978 dst_triangle_offsets,
984 this->curve_plane_normals(),
986 dst_triangle_offsets,
990 this->tag_texture_matrices_changed();
993DrawingReference::DrawingReference()
998 this->id_reference =
nullptr;
1009DrawingReference::~DrawingReference() =
default;
1017 switch (src_drawing_base->
type) {
1022 MEM_new<bke::greasepencil::Drawing>(__func__, src_drawing->wrap()));
1029 MEM_new<bke::greasepencil::DrawingReference>(__func__, src_drawing_reference->wrap()));
1038 this->
next = this->prev =
nullptr;
1039 this->parent =
nullptr;
1043 this->color[0] = this->color[1] = this->color[2] = 0;
1077 return *
reinterpret_cast<const LayerGroup *
>(
this);
1082 return *
reinterpret_cast<const Layer *
>(
this);
1087 return *
reinterpret_cast<LayerGroup *
>(
this);
1092 return *
reinterpret_cast<Layer *
>(
this);
1097 return (this->
parent) ? &this->
parent->wrap() :
nullptr;
1101 return (this->
parent) ? &this->
parent->wrap() :
nullptr;
1115 if (parent ==
nullptr) {
1119 return 1 +
parent->as_node().depth();
1150 masks_.clear_and_shrink();
1179 this->
runtime = MEM_new<LayerRuntime>(__func__);
1192 LayerMask *new_mask = MEM_new<LayerMask>(__func__, *
reinterpret_cast<LayerMask *
>(other_mask));
1212 this->
runtime->sorted_keys_cache_ = other.
runtime->sorted_keys_cache_;
1221 this->
base.wrap().~TreeNode();
1240 return this->
runtime->frames_;
1245 return this->
runtime->frames_;
1252 while (next_it != end && this->
frames().lookup(*next_it).is_end()) {
1255 next_it = std::next(next_it);
1262 if (!this->
frames().contains(frame_number)) {
1282 if (
frame ==
nullptr) {
1290 if (next_key_it !=
sorted_keys.end() && *next_key_it == end_key) {
1293 next_key_it = this->remove_leading_end_frames_in_range(next_key_it,
sorted_keys.end());
1295 if (duration == 0) {
1301 if (next_key_it ==
sorted_keys.end() || *next_key_it > end_key) {
1323 if (std::next(remove_key_it) !=
sorted_keys.end()) {
1325 this->remove_leading_end_frames_in_range(next_key_it,
sorted_keys.end());
1333 if (!prev_frame.is_implicit_hold() && !prev_frame.is_end()) {
1355 std::sort(r_data.
begin(), r_data.
end());
1380 return std::prev(it);
1383std::optional<FramesMapKeyT> Layer::frame_key_at(
const int frame_number)
const
1386 if (it ==
nullptr) {
1394 const std::optional<FramesMapKeyT> frame_key = this->frame_key_at(frame_number);
1396 if (frame_key && !this->
frames().lookup_ptr(*frame_key)->is_end()) {
1405 if (it ==
nullptr) {
1418 const std::optional<FramesMapKeyT> frame_key = this->frame_key_at(frame_number);
1424 if (frame_ptr ==
nullptr || frame_ptr->is_end()) {
1438 const std::optional<FramesMapKeyT> frame_key = this->frame_key_at(frame_number);
1444 if (frame_ptr ==
nullptr || frame_ptr->is_end()) {
1454 return (
frame !=
nullptr) ?
frame->drawing_index : -1;
1459 return frame_at(frame_number) !=
nullptr;
1465 if (it ==
nullptr) {
1471 if (
frame->is_implicit_hold()) {
1475 if (
frame->is_end()) {
1479 const int next_frame_number = *(std::next(it));
1491 this->
runtime->sorted_keys_cache_.tag_dirty();
1504 const size_t frames_num = size_t(
frames().
size());
1527 runtime = MEM_new<blender::bke::greasepencil::LayerRuntime>(__func__);
1537 if (this->
parent ==
nullptr) {
1546 if (this->
parent ==
nullptr) {
1572 const float4x4 &parent_object_to_world =
parent.object_to_world();
1575 this->parent_bone_name().c_str()))
1577 return parent_object_to_world *
float4x4_view(channel->pose_mat);
1580 return parent_object_to_world;
1625 this->
runtime = MEM_new<LayerGroupRuntime>(__func__);
1638 switch (child->type) {
1641 Layer *dup_layer = MEM_new<Layer>(__func__, layer->wrap());
1647 LayerGroup *dup_group = MEM_new<LayerGroup>(__func__, group->wrap());
1659 this->
base.wrap().~TreeNode();
1662 switch (child->type) {
1665 MEM_delete(&layer->wrap());
1670 MEM_delete(&group->wrap());
1682 if (
this == &other) {
1701 this->tag_nodes_cache_dirty();
1709 this->tag_nodes_cache_dirty();
1716 this->tag_nodes_cache_dirty();
1722 this->tag_nodes_cache_dirty();
1727 this->tag_nodes_cache_dirty();
1733 this->tag_nodes_cache_dirty();
1739 this->tag_nodes_cache_dirty();
1749 this->ensure_nodes_cache();
1750 return this->
runtime->nodes_cache_.size();
1764 link_children.
first);
1773 if (link.
next !=
nullptr) {
1777 if (link.
prev !=
nullptr) {
1794 this->tag_nodes_cache_dirty();
1799 this->tag_nodes_cache_dirty();
1807 this->ensure_nodes_cache();
1808 return this->
runtime->nodes_cache_.as_span();
1813 this->ensure_nodes_cache();
1814 return this->
runtime->nodes_cache_.as_span();
1819 this->ensure_nodes_cache();
1820 return this->
runtime->layer_cache_.as_span();
1825 this->ensure_nodes_cache();
1826 return this->
runtime->layer_cache_.as_span();
1831 this->ensure_nodes_cache();
1832 return this->
runtime->layer_group_cache_.as_span();
1837 this->ensure_nodes_cache();
1838 return this->
runtime->layer_group_cache_.as_span();
1873 std::cout << header << std::endl;
1877 next_node.
push(std::make_pair(1, child));
1880 auto [indent,
node] = next_node.
pop();
1881 for (
int i = 0; i < indent; i++) {
1884 if (
node->is_layer()) {
1885 std::cout <<
node->name();
1887 else if (
node->is_group()) {
1888 std::cout <<
node->name() <<
": ";
1891 next_node.
push(std::make_pair(indent + 1, child));
1894 std::cout << std::endl;
1896 std::cout << std::endl;
1899void LayerGroup::ensure_nodes_cache()
const
1901 this->
runtime->nodes_cache_mutex_.ensure([&]() {
1902 this->
runtime->nodes_cache_.clear_and_shrink();
1903 this->
runtime->layer_cache_.clear_and_shrink();
1904 this->
runtime->layer_group_cache_.clear_and_shrink();
1908 this->
runtime->nodes_cache_.append(node);
1909 switch (
node->type) {
1917 this->
runtime->nodes_cache_.append(child);
1918 if (child->is_layer()) {
1919 this->
runtime->layer_cache_.append(&child->as_layer());
1921 else if (child->is_group()) {
1922 this->
runtime->layer_group_cache_.append(&child->as_group());
1932void LayerGroup::tag_nodes_cache_dirty()
const
1934 this->
runtime->nodes_cache_mutex_.tag_dirty();
1936 this->
base.
parent->wrap().tag_nodes_cache_dirty();
1943 switch (child->type) {
1945 child->as_layer().prepare_for_dna_write();
1949 child->as_group().prepare_for_dna_write();
1959 switch (child->type) {
1961 child->as_layer().update_from_dna_read();
1965 child->as_group().update_from_dna_read();
1975 if (layer->name().is_empty()) {
1976 grease_pencil.rename_node(bmain, layer->as_node(),
DATA_(
"Layer"));
1991 return std::nullopt;
2000 return std::nullopt;
2012 data.data = new_sharing_info->data.data();
2034 return grease_pencil;
2040 return grease_pencil;
2047 grease_pencil->
runtime->eval_frame = grease_pencil_src->
runtime->eval_frame;
2048 return grease_pencil;
2073 LayerMask *new_mask = MEM_new<LayerMask>(__func__, *
reinterpret_cast<LayerMask *
>(src_mask));
2113 grease_pencil_dst->
drawing_array[i] = &MEM_new<Drawing>(__func__, src_drawing)->base;
2121 &MEM_new<DrawingReference>(__func__, src_drawing_ref)->base;
2129 MEM_delete(&grease_pencil_dst->root_group());
2132 grease_pencil_dst->
root_group_ptr = MEM_new<bke::greasepencil::LayerGroup>(
2134 BLI_assert(grease_pencil_src->layers().size() == grease_pencil_dst->layers().size());
2142 grease_pencil_src->layers().size());
2157 if (
STREQ(vgroup->name, old_name)) {
2158 STRNCPY(vgroup->name, new_name);
2190 for (; tmd; tmd = tmd->
next) {
2207 for (; md; md = md->
next) {
2227 using namespace bke::greasepencil;
2231 struct LayerDrawingInfo {
2233 const int layer_index;
2238 for (
const int layer_i : grease_pencil.layers().index_range()) {
2239 const Layer &layer = grease_pencil.layer(layer_i);
2241 if (
Drawing *drawing = grease_pencil.get_eval_drawing(layer)) {
2242 if (all_drawings.
add(drawing)) {
2243 drawing_infos.
append({drawing, layer_i});
2248 if (layer_attributes.
contains(
"radius_offset")) {
2252 if (radius_offsets[
info.layer_index] == 0.0f) {
2257 for (const int i : range) {
2258 radii[i] += radius_offsets[info.layer_index];
2264 if (layer_attributes.contains(
"tint_color")) {
2266 return base * (1.0 - tint.w) + tint * tint.w;
2272 if (tint_colors[
info.layer_index].a == 0.0f) {
2277 for (const int i : range) {
2278 vertex_colors[i] = ColorGeometry4f(
2279 mix_tint(float4(vertex_colors[i]), float4(tint_colors[info.layer_index])));
2284 for (const int i : range) {
2285 fill_colors[i] = ColorGeometry4f(
2286 mix_tint(float4(fill_colors[i]), float4(tint_colors[info.layer_index])));
2303 Layer *layer = layers[layer_i];
2305 layer->
runtime->orig_layer_index_ = layer_i;
2309 if (layer->is_visible() || layer->
runtime->is_visibility_animated_) {
2314 grease_pencil.remove_layer(*layer);
2335 GeometrySet geometry_set = GeometrySet::from_grease_pencil(grease_pencil,
2336 GeometryOwnershipType::ReadOnly);
2341 if (layer_attributes.
contains(
"tint_color") || layer_attributes.
contains(
"radius_offset")) {
2376 object->runtime->geometry_set_eval =
new GeometrySet(std::move(geometry_set));
2388 grease_pencil_dst->drawings());
2422 int total_points = 0;
2424 for (
const int layer_i : grease_pencil.layers().index_range()) {
2426 const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.
frames();
2427 frames.foreach_item(
2440 return total_points;
2449 for (
const int layer_i : grease_pencil.layers().index_range()) {
2452 const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.
frames();
2453 frames.foreach_item(
2468 all_radii[index] = radii[i];
2476 const int index_pos = index * 3;
2478 handle_positions_left[i]);
2481 handle_positions_right[i]);
2482 all_radii[index] = radii[i];
2496 for (
const int layer_i : grease_pencil.layers().index_range()) {
2500 const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.
frames();
2515 radii[i] = all_radii[index];
2523 const int index_pos = index * 3;
2525 all_positions[index_pos]);
2528 all_positions[index_pos + 2]);
2529 radii[i] = all_radii[index];
2548 for (
const int layer_i : grease_pencil.layers().index_range()) {
2552 const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.
frames();
2567 radii[i] = all_radii[index] * scalef;
2575 const int index_pos = index * 3;
2577 all_positions[index_pos]);
2579 all_positions[index_pos + 1]);
2581 all_positions[index_pos + 2]);
2582 radii[i] = all_radii[index] * scalef;
2603 for (
short i = 0; i < *totcol; i++) {
2625 *r_index = ob->
actcol - 1;
2669 const bool change_active_material =
false;
2712 material_alt =
reinterpret_cast<Material *
>(
2715 return material_alt;
2734 if (!material_indices) {
2738 for (
const int i : material_indices.
span.index_range()) {
2741 material_indices.
span[i] = remap[material_indices.
span[i]];
2743 material_indices.
finish();
2760 if (!material_indices) {
2764 for (
const int i : material_indices.
span.index_range()) {
2765 if (material_indices.
span[i] > 0 && material_indices.
span[i] >= index) {
2766 material_indices.
span[i]--;
2769 material_indices.
finish();
2785 "material_index", AttrDomain::Curve, 0);
2787 if (material_indices.
contains(index)) {
2806 if (id_reference == reference->id_reference) {
2831 int mode) =
nullptr;
2836 if (grease_pencil->
runtime && grease_pencil->
runtime->batch_cache) {
2843 if (grease_pencil->
runtime && grease_pencil->
runtime->batch_cache) {
2857 const int new_array_num = *
num + add_num;
2861 if (*
array !=
nullptr) {
2866 *
num = new_array_num;
2871 const int new_array_num = *
num - shrink_num;
2872 if (new_array_num == 0) {
2885 *
num = new_array_num;
2896 this->drawing_array_num};
2904 MEM_delete(&drawing->wrap());
2910 MEM_delete(&drawing_reference->wrap());
2916void GreasePencil::resize_drawings(
const int new_num)
2921 const int prev_num = int(this->drawings().
size());
2922 if (new_num == prev_num) {
2925 if (new_num > prev_num) {
2926 const int add_num = new_num - prev_num;
2930 const int shrink_num = prev_num - new_num;
2932 for (
const int64_t i : old_drawings.index_range()) {
2938 &this->drawing_array, &this->drawing_array_num, shrink_num);
2942void GreasePencil::add_empty_drawings(
const int add_num)
2946 const int prev_num = this->drawings().size();
2949 for (
const int i : new_drawings.index_range()) {
2951 MEM_new<blender::bke::greasepencil::Drawing>(__func__));
2955void GreasePencil::add_duplicate_drawings(
const int duplicate_num,
2960 const int prev_num = this->drawings().size();
2962 &this->drawing_array, &this->drawing_array_num, duplicate_num);
2964 for (
const int i : new_drawings.index_range()) {
2966 MEM_new<bke::greasepencil::Drawing>(__func__, drawing));
2972 const int frame_number,
2978 if (
frame ==
nullptr) {
2981 this->add_empty_drawings(1);
2982 frame->drawing_index = this->drawings().index_range().last();
2988 return &drawing->wrap();
2992 const int frame_number,
3005 if (
frame !=
nullptr) {
3014 this->add_empty_drawings(frames.
size());
3016 for (
const int frame_i : frames.index_range()) {
3018 frame->drawing_index = new_drawings[frame_i];
3024 const int src_frame_number,
3025 const int dst_frame_number,
3026 const bool do_instance)
3034 if (layer.is_locked()) {
3045 if (dst_frame ==
nullptr) {
3052 switch (src_drawing_base->
type) {
3065 this->add_duplicate_drawings(1, src_drawing);
3082 bool removed_any_drawing_user =
false;
3083 for (
const int frame_number : frame_numbers) {
3093 if (frame_to_remove.is_end()) {
3105 removed_any_drawing_user =
true;
3107 if (removed_any_drawing_user) {
3108 this->remove_drawings_with_no_users();
3117 const std::optional<int> frame_select)
3124 for (
auto [frame_number, src_frame] : src_layer.frames().items()) {
3125 if (frame_select && *frame_select != frame_number) {
3130 int dst_drawing_index = drawing_index_map[src_drawing_index];
3131 if (dst_drawing_index < 0) {
3132 switch (src_drawings[src_drawing_index]->type) {
3137 this->add_duplicate_drawings(1, src_drawing);
3142 this->add_empty_drawings(1);
3145 dst_drawing_index = this->drawings().size() - 1;
3146 drawing_index_map[src_drawing_index] = dst_drawing_index;
3148 BLI_assert(this->drawings().index_range().contains(dst_drawing_index));
3156void GreasePencil::add_layers_with_empty_drawings_for_eval(
const int num)
3160 const int old_drawings_num = this->drawing_array_num;
3161 const int old_layers_num = this->layers().
size();
3162 this->add_empty_drawings(
num);
3163 this->add_layers_for_eval(
num);
3165 for (
const int i :
range) {
3166 const int new_drawing_i = old_drawings_num + i;
3167 const int new_layer_i = old_layers_num + i;
3168 Layer &layer = this->layer(new_layer_i);
3171 frame->drawing_index = new_drawing_i;
3176void GreasePencil::remove_drawings_with_no_users()
3194 auto is_drawing_used = [&](
const int drawing_index) {
3202 return drawing->wrap().has_users();
3207 constexpr const int unchanged_index = -1;
3210 int first_unused_drawing = -1;
3211 int last_used_drawing = drawings.
size() - 1;
3214 auto find_next_swap_index = [&]() ->
bool {
3216 ++first_unused_drawing;
3217 }
while (first_unused_drawing <= last_used_drawing && is_drawing_used(first_unused_drawing));
3218 while (last_used_drawing >= 0 && !is_drawing_used(last_used_drawing)) {
3219 --last_used_drawing;
3222 return first_unused_drawing < last_used_drawing;
3225 while (find_next_swap_index()) {
3227 std::swap(drawings[first_unused_drawing], drawings[last_used_drawing]);
3228 drawing_index_map[last_used_drawing] = first_unused_drawing;
3234 BLI_assert(last_used_drawing == first_unused_drawing - 1);
3236 for (
const int i : drawings.index_range()) {
3237 if (i < first_unused_drawing) {
3247 const IndexRange drawings_to_remove = (first_unused_drawing > 0) ?
3249 first_unused_drawing) :
3251 if (drawings_to_remove.
is_empty()) {
3256 for (
const int i : drawings_to_remove) {
3258 switch (unused_drawing_base->
type) {
3261 MEM_delete(&unused_drawing->wrap());
3266 unused_drawing_base);
3267 MEM_delete(&unused_drawing_ref->wrap());
3273 &this->drawing_array, &this->drawing_array_num, drawings_to_remove.
size());
3276 for (
Layer *layer :
this->layers_for_write()) {
3277 for (
auto [
key,
value] : layer->frames_for_write().items()) {
3278 const int new_drawing_index = drawing_index_map[
value.drawing_index];
3279 if (new_drawing_index != unchanged_index) {
3280 value.drawing_index = new_drawing_index;
3290 for (
auto [
key,
value] : layer.frames().items()) {
3291 BLI_assert(this->drawings().index_range().contains(
value.drawing_index));
3307 this->move_duplicate_frames(
3311void GreasePencil::move_duplicate_frames(
3317 Map<int, GreasePencilFrame> layer_frames_copy = layer.
frames();
3320 Map<int, int> src_layer_frames_durations;
3321 for (
const auto [frame_number,
frame] : layer.frames().items()) {
3328 for (
const auto src_frame_number : frame_number_destinations.keys()) {
3329 if (!duplicate_frames.
contains(src_frame_number)) {
3335 auto get_source_frame = [&](
const int frame_number) ->
const GreasePencilFrame * {
3339 return layer_frames_copy.lookup_ptr(frame_number);
3342 for (
const auto [src_frame_number, dst_frame_number] : frame_number_destinations.items()) {
3347 const int duration = src_layer_frames_durations.lookup_default(src_frame_number, 0);
3359 *
frame = *src_frame;
3363 this->remove_drawings_with_no_users();
3369 if (this->drawings().is_empty()) {
3373 if (drawing_index == -1) {
3383 return &drawing->wrap();
3389 if (this->drawings().is_empty()) {
3393 if (drawing_index == -1) {
3403 return &drawing->wrap();
3409 if (!layer.is_editable()) {
3412 if (this->drawings().is_empty()) {
3416 if (drawing_index == -1) {
3426 return &drawing->wrap();
3432 return this->get_drawing_at(layer, this->runtime->eval_frame);
3438 return this->get_drawing_at(layer, this->runtime->eval_frame);
3448 for (const int i : range) {
3449 dst[i] = blender::math::transform_point(transform, src[i]);
3454std::optional<blender::Bounds<blender::float3>> GreasePencil::bounds_min_max(
3455 const int frame,
const bool use_radius)
const
3458 std::optional<Bounds<float3>> bounds;
3460 for (
const int layer_i : layers.index_range()) {
3463 if (!layer.is_visible()) {
3486 if (
const std::optional radius_single = radius.
get_if_single()) {
3488 drawing_bounds.
pad(*radius_single);
3503 radii_eval.as_span());
3509std::optional<blender::Bounds<blender::float3>> GreasePencil::bounds_min_max_eval(
3510 const bool use_radius)
const
3512 return this->bounds_min_max(this->runtime->eval_frame, use_radius);
3528std::optional<int> GreasePencil::material_index_max()
const
3532 std::optional<int> max_index;
3539 const std::optional<int> max_index_in_drawing = drawing->wrap().strokes().material_index_max();
3541 if (max_index_in_drawing) {
3542 max_index = std::max(*max_index, *max_index_in_drawing);
3546 max_index = max_index_in_drawing;
3555 return this->root_group().layers();
3561 return this->root_group().layers_for_write();
3567 return this->root_group().groups();
3573 return this->root_group().groups_for_write();
3579 return this->root_group().nodes();
3585 return this->root_group().nodes_for_write();
3588std::optional<int> GreasePencil::get_layer_index(
3591 const int index = int(this->layers().first_index_try(&layer));
3600 if (this->active_node ==
nullptr) {
3612 if (this->active_node ==
nullptr) {
3627 this->autolock_inactive_layers();
3633 if (layer ==
nullptr) {
3636 return this->get_active_layer() == layer;
3639void GreasePencil::autolock_inactive_layers()
3643 for (
Layer *layer :
this->layers_for_write()) {
3644 if (this->is_layer_active(layer)) {
3645 layer->set_locked(
false);
3648 layer->set_locked(
true);
3654 if (this->active_node ==
nullptr) {
3666 if (this->active_node ==
nullptr) {
3678 if (this->active_node ==
nullptr) {
3681 return &this->active_node->wrap();
3686 if (this->active_node ==
nullptr) {
3689 return &this->active_node->wrap();
3737 const bool check_name_is_unique)
3740 std::string
unique_name = check_name_is_unique ? unique_layer_name(
name) : std::string(
name);
3741 const int numLayers = layers().
size();
3763 const bool check_name_is_unique)
3767 move_node_into(new_layer.
as_node(), parent_group);
3771void GreasePencil::add_layers_for_eval(
const int num_new_layers)
3774 const int num_layers = this->layers().
size();
3776 for ([[maybe_unused]]
const int i :
IndexRange(num_new_layers)) {
3780 this->root_group().add_node(new_layer->
as_node());
3788 std::string
unique_name = unique_layer_name(duplicate_layer.name());
3789 std::optional<int> duplicate_layer_idx = get_layer_index(duplicate_layer);
3791 const int numLayers = layers().
size();
3793 for (
const int layer_index :
IndexRange(layers_data.totlayer)) {
3795 &layers_data, &layers_data, layer_index, layer_index, *duplicate_layer_idx, numLayers, 1);
3799 root_group().add_node(new_layer->
as_node());
3800 this->update_drawing_users_for_layer(*new_layer);
3811 move_node_into(new_layer.
as_node(), parent_group);
3823 return root_group().add_node(new_group->
as_node()).as_group();
3829 const bool check_name_is_unique)
3833 move_node_into(new_group.
as_node(), parent_group);
3842 for (
const int old_i : new_by_old_map.
index_range()) {
3843 const int new_i = new_by_old_map[old_i];
3857 Map<const bke::greasepencil::Layer *, int> old_layer_index_by_layer;
3858 old_layer_index_by_layer.reserve(layers.
size());
3860 old_layer_index_by_layer.add_new(layers[i], i);
3864 do_layer_order_changes();
3865 layers = grease_pencil.layers();
3870 for (
const int layer_i_new : layers.
index_range()) {
3872 BLI_assert(old_layer_index_by_layer.contains(layer));
3873 const int layer_i_old = old_layer_index_by_layer.pop(layer);
3874 new_by_old_map[layer_i_old] = layer_i_new;
3876 BLI_assert(old_layer_index_by_layer.is_empty());
3885 if (!
node.parent_group()) {
3893 if (!
node.parent_group()) {
3901 if (!
node.parent_group()) {
3909 if (!
node.parent_group()) {
3923 node.parent_group()->unlink_node(
node);
3936 node.parent_group()->unlink_node(
node);
3945 if (!
node.parent_group()) {
3949 node.parent_group()->unlink_node(
node);
3957 return this->root_group().find_node_by_name(
name);
3963 return this->root_group().find_node_by_name(
name);
3975 if (
node->is_layer()) {
3976 const int index = *this->get_layer_index(
node->as_layer());
3979 if (
node->is_group()) {
3981 for (
const int64_t layer_index :
this->layers().index_range()) {
3982 const Layer &layer = *this->layers()[layer_index];
3983 if (layer.is_child_of(
node->as_group())) {
3984 layer_indices.
append(layer_index);
4103void GreasePencil::rename_node(
Main &bmain,
4108 if (
node.name() == new_name) {
4113 std::string old_name =
node.name();
4114 if (
node.is_layer()) {
4115 node.set_name(unique_layer_name(new_name));
4117 else if (
node.is_group()) {
4122 if (
node.is_layer()) {
4127 if (
STREQ(
mask->layer_name, old_name.c_str())) {
4136 if (object->data !=
this) {
4142 char *dst_layer_name =
nullptr;
4143 size_t dst_layer_name_len = 0;
4148 dst_layer_name_len =
sizeof(lmd->target_layer);
4153 dst_layer_name = influence_data->layer_name;
4154 dst_layer_name_len =
sizeof(influence_data->layer_name);
4156 if (dst_layer_name &&
STREQ(dst_layer_name, old_name.c_str())) {
4170 const IndexRange range_before(index_to_remove);
4171 const IndexRange range_after(index_to_remove + 1,
size - index_to_remove - 1);
4191 if (
node.prev !=
nullptr) {
4192 grease_pencil.set_active_node(
reinterpret_cast<TreeNode *
>(
node.prev));
4196 else if (
node.next !=
nullptr) {
4197 grease_pencil.set_active_node(
reinterpret_cast<TreeNode *
>(
node.next));
4202 grease_pencil.set_active_node(&
node.parent->wrap().as_node());
4206 grease_pencil.set_active_node(
nullptr);
4214 if (&layer.
as_node() ==
this->get_active_node()) {
4219 const int layer_index = *this->get_layer_index(layer);
4233 drawing->wrap().remove_user();
4235 this->remove_drawings_with_no_users();
4242 const bool keep_children)
4246 if (&group.
as_node() ==
this->get_active_node()) {
4248 if (keep_children && !group.
is_empty()) {
4256 if (!keep_children) {
4259 switch (child->type) {
4280void GreasePencil::print_layer_tree()
4283 this->root_group().print_nodes(
"Layer Tree:");
4315 drawing->wrap().strokes_for_write().blend_read(*reader);
4317 drawing->
runtime = MEM_new<blender::bke::greasepencil::DrawingRuntime>(__func__);
4341 bke::CurvesGeometry::BlendWriteData write_data(scope);
4343 drawing_copy.
runtime =
nullptr;
4361 grease_pencil.resize_drawings(0);
4375 node->base.parent = parent;
4393 node->runtime =
nullptr;
4394 node->wrap().update_from_dna_read();
4402 node->base.parent = parent;
4406 switch (child->type) {
4420 node->wrap().runtime = MEM_new<blender::bke::greasepencil::LayerGroupRuntime>(__func__);
4431 grease_pencil.
root_group_ptr = MEM_new<blender::bke::greasepencil::LayerGroup>(__func__);
4432 grease_pencil.set_active_node(
nullptr);
4464 switch (child->type) {
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
void BKE_animdata_free(ID *id, bool do_id_user)
void BKE_animdata_fix_paths_rename_all(struct ID *ref_id, const char *prefix, const char *oldName, const char *newName)
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
void CustomData_blend_write_prepare(CustomData &data, blender::bke::AttrDomain domain, int domain_size, blender::Vector< CustomDataLayer, 16 > &layers_to_write, blender::bke::AttributeStorage::BlendWriteData &write_data)
void CustomData_realloc(CustomData *data, int old_size, int new_size, eCDAllocType alloctype=CD_CONSTRUCT)
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
void CustomData_reset(CustomData *data)
void CustomData_blend_write(BlendWriter *writer, CustomData *data, blender::Span< CustomDataLayer > layers_to_write, int count, eCustomDataMask cddata_mask, ID *id)
void CustomData_copy_data_layer(const CustomData *source, CustomData *dest, int src_layer_index, int dst_layer_index, int src_index, int dst_index, int count)
void CustomData_free(CustomData *data)
void CustomData_init_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count)
void CustomData_init_layout_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
Low-level operations for grease pencil that cannot be defined in the C++ header yet.
void(* BKE_grease_pencil_batch_cache_dirty_tag_cb)(GreasePencil *grease_pencil, int mode)
void BKE_grease_pencil_batch_cache_dirty_tag(GreasePencil *grease_pencil, int mode)
void BKE_grease_pencil_batch_cache_free(GreasePencil *grease_pencil)
void(* BKE_grease_pencil_batch_cache_free_cb)(GreasePencil *grease_pencil)
Low-level operations for grease pencil.
void BKE_grease_pencil_point_coords_apply(GreasePencil &grease_pencil, blender::Span< blender::float3 > all_positions, blender::Span< float > all_radii)
void BKE_grease_pencil_copy_parameters(const GreasePencil &src, GreasePencil &dst)
void BKE_grease_pencil_material_remap(GreasePencil *grease_pencil, const uint *remap, int totcol)
void BKE_grease_pencil_material_index_remove(GreasePencil *grease_pencil, int index)
void BKE_grease_pencil_vgroup_name_update(Object *ob, const char *old_name, const char *new_name)
Material * BKE_grease_pencil_object_material_alt_ensure_from_brush(Main *bmain, Object *ob, Brush *brush)
void BKE_grease_pencil_point_coords_apply_with_mat4(GreasePencil &grease_pencil, blender::Span< blender::float3 > all_positions, blender::Span< float > all_radii, const blender::float4x4 &mat)
void BKE_grease_pencil_point_coords_get(const GreasePencil &grease_pencil, blender::MutableSpan< blender::float3 > all_positions, blender::MutableSpan< float > all_radii)
void BKE_object_eval_grease_pencil(Depsgraph *depsgraph, Scene *scene, Object *object)
bool BKE_grease_pencil_references_cyclic_check(const GreasePencil *id_reference, const GreasePencil *grease_pencil)
Material * BKE_grease_pencil_object_material_new(Main *bmain, Object *ob, const char *name, int *r_index)
GreasePencil * BKE_grease_pencil_add(Main *bmain, const char *name)
Material * BKE_grease_pencil_object_material_ensure_from_brush(Main *bmain, Object *ob, Brush *brush)
void BKE_grease_pencil_nomain_to_grease_pencil(GreasePencil *grease_pencil_src, GreasePencil *grease_pencil_dst)
void BKE_grease_pencil_eval_geometry(Depsgraph *depsgraph, GreasePencil *grease_pencil)
void BKE_grease_pencil_duplicate_drawing_array(const GreasePencil *grease_pencil_src, GreasePencil *grease_pencil_dst)
bool BKE_grease_pencil_has_curve_with_type(const GreasePencil &grease_pencil, CurveType type)
Material * BKE_grease_pencil_object_material_from_brush_get(Object *ob, Brush *brush)
int BKE_grease_pencil_stroke_point_count(const GreasePencil &grease_pencil)
GreasePencil * BKE_grease_pencil_new_nomain()
void BKE_grease_pencil_copy_layer_parameters(const blender::bke::greasepencil::Layer &src, blender::bke::greasepencil::Layer &dst)
void BKE_grease_pencil_copy_layer_group_parameters(const blender::bke::greasepencil::LayerGroup &src, blender::bke::greasepencil::LayerGroup &dst)
bool BKE_grease_pencil_drawing_attribute_required(const GreasePencilDrawing *, blender::StringRef name)
GreasePencil * BKE_grease_pencil_copy_for_eval(const GreasePencil *grease_pencil_src)
bool BKE_grease_pencil_material_index_used(GreasePencil *grease_pencil, int index)
int BKE_grease_pencil_object_material_index_get_by_name(Object *ob, const char *name)
Material * BKE_grease_pencil_object_material_ensure_by_name(Main *bmain, Object *ob, const char *name, int *r_index)
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
void BKE_id_free(Main *bmain, void *idv)
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
void * BKE_id_new(Main *bmain, short type, const char *name)
void * BKE_id_new_nomain(short type, const char *name)
void BKE_id_blend_write(BlendWriter *writer, ID *id)
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
General operations, lookup, etc. for materials.
short * BKE_object_material_len_p(Object *ob)
short BKE_object_material_slot_find_index(Object *ob, Material *ma)
Material * BKE_gpencil_material_add(Main *bmain, const char *name)
bool BKE_object_material_slot_add(Main *bmain, Object *ob, bool set_active=true)
Material * BKE_material_default_gpencil()
Material * BKE_object_material_get(Object *ob, short act)
@ BKE_MAT_ASSIGN_USERPREF
void BKE_object_material_assign(Main *bmain, Object *ob, Material *ma, short act, int assign_type)
int BKE_object_material_index_get(Object *ob, const Material *ma)
void BKE_modifiers_clear_errors(Object *ob)
bool BKE_modifier_is_enabled(const Scene *scene, ModifierData *md, int required_mode)
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *data)
General operations, lookup, etc. for blender objects.
bool BKE_object_is_in_editmode(const Object *ob)
void BKE_object_eval_assign_data(Object *object, ID *data, bool is_owned)
void BKE_object_free_derived_caches(Object *ob)
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void void void bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL()
bool BLI_remlink_safe(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void void void void void BLI_duplicatelist(ListBase *dst, const ListBase *src) ATTR_NONNULL(1
void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
float mat4_to_scale(const float mat[4][4])
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void unit_m4(float m[4][4])
MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void zero_v3(float r[3])
#define BLI_MEMARENA_STD_BUFSIZE
MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void BLI_memarena_free(MemArena *ma) ATTR_NONNULL(1)
void * BLI_memarena_alloc(MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
ATTR_WARN_UNUSED_RESULT const size_t num
void BLI_polyfill_calc_arena(const float(*coords)[2], unsigned int coords_num, int coords_sign, unsigned int(*r_tris)[3], struct MemArena *arena)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC
char * STRNCPY(char(&dst)[N], const char *src)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
#define UNUSED_VARS_NDEBUG(...)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
void BLO_write_int32_array(BlendWriter *writer, int64_t num, const int32_t *data_ptr)
void BLO_read_int32_array(BlendDataReader *reader, int64_t array_size, int32_t **ptr_p)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p)
#define BLO_write_struct_list(writer, struct_name, list_ptr)
#define BLO_read_struct(reader, struct_name, ptr_p)
void BLO_write_pointer_array(BlendWriter *writer, int64_t num, const void *data_ptr)
void BLO_read_pointer_array(BlendDataReader *reader, int64_t array_size, void **ptr_p)
#define BLO_write_struct_at_address(writer, struct_name, address, data_ptr)
#define BLT_I18NCONTEXT_ID_GPENCIL
void DEG_id_tag_update(ID *id, unsigned int flags)
float DEG_get_ctime(const Depsgraph *graph)
bool DEG_is_evaluated(const T *id)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
T * DEG_get_original(T *id)
ID and Library types, which are fundamental for SDNA.
Enumerations for DNA_ID.h.
@ GP_BRUSH_MATERIAL_PINNED
#define DNA_struct_default_get(struct_name)
@ GP_LAYER_FRAMES_STORAGE_DIRTY
struct GreasePencil GreasePencil
GreasePencilLayerTreeNodeType
@ GP_LAYER_TREE_NODE_EXPANDED
@ GP_LAYER_TREE_NODE_USE_LIGHTS
@ GP_LAYER_TREE_NODE_HIDE_MASKS
@ GREASE_PENCIL_AUTOLOCK_LAYERS
@ eModifierType_GreasePencilSmooth
@ eModifierType_GreasePencilWeightProximity
@ eModifierType_GreasePencilMirror
@ eModifierType_GreasePencilOffset
@ eModifierType_GreasePencilThickness
@ eModifierType_GreasePencilEnvelope
@ eModifierType_GreasePencilArmature
@ eModifierType_GreasePencilSubdiv
@ eModifierType_GreasePencilTint
@ eModifierType_GreasePencilNoise
@ eModifierType_GreasePencilMultiply
@ eModifierType_GreasePencilBuild
@ eModifierType_GreasePencilTime
@ eModifierType_GreasePencilTexture
@ eModifierType_GreasePencilSimplify
@ eModifierType_GreasePencilColor
@ eModifierType_GreasePencilDash
@ eModifierType_GreasePencilLineart
@ eModifierType_GreasePencilOutline
@ eModifierType_GreasePencilWeightAngle
@ eModifierType_GreasePencilOpacity
@ eModifierType_GreasePencilLength
@ eModifierType_GreasePencilShrinkwrap
@ eModifierType_GreasePencilLattice
@ eModifierType_GreasePencilHook
@ eModifierType_GreasePencilArray
@ OB_MODE_VERTEX_GREASE_PENCIL
@ OB_MODE_SCULPT_GREASE_PENCIL
@ OB_MODE_WEIGHT_GREASE_PENCIL
Read Guarded memory(de)allocation.
static const char * ATTR_POSITION
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
Span< T > as_span() const
IndexRange index_range() const
static const CPPType & get()
ImplicitSharingPtr sharing_info
constexpr IndexRange drop_back(int64_t n) const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr int64_t start() const
constexpr IndexRange take_back(int64_t n) const
static constexpr IndexRange from_single(const int64_t index)
constexpr IndexRange drop_front(int64_t n) const
const Value * lookup_ptr(const Key &key) const
bool add_overwrite(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
void remove_contained(const Key &key)
void add_new(const Key &key, const Value &value)
KeyIterator keys() const &
bool contains(const Key &key) const
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr bool is_empty() const
constexpr T * data() const
constexpr void fill(const T &value) const
constexpr MutableSpan drop_front(const int64_t n) const
constexpr T & first() const
constexpr IndexRange index_range() const
T & construct(Args &&...args)
constexpr Span slice(int64_t start, int64_t size) const
constexpr const T * data() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
constexpr bool contains(const T &value) const
void push(const T &value)
constexpr bool is_empty() const
constexpr int64_t size() const
constexpr const char * data() const
std::optional< T > get_if_single() const
Span< T > get_internal_span() const
bool contains(const Key &key) const
void append(const T &value)
const T & last(const int64_t n=0) const
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
void reserve(const int64_t min_capacity)
void reinitialize(const int64_t new_size)
Span< T > as_span() const
bool contains(StringRef attribute_id) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
MutableSpan< float3 > positions_for_write()
OffsetIndices< int > points_by_curve() const
void ensure_can_interpolate_to_evaluated() const
IndexRange curves_range() const
MutableSpan< float3 > handle_positions_left_for_write()
MutableAttributeAccessor attributes_for_write()
MutableSpan< float3 > handle_positions_right_for_write()
VArray< float > radius() const
void blend_write(BlendWriter &writer, ID &id, const BlendWriteData &write_data)
void blend_write_prepare(BlendWriteData &write_data)
Span< float3 > handle_positions_left() const
int evaluated_points_num() const
void interpolate_to_evaluated(int curve_index, GSpan src, GMutableSpan dst) const
IndexRange points_range() const
Span< float3 > positions() const
OffsetIndices< int > evaluated_points_by_curve() const
bool has_curve_with_type(CurveType type) const
Span< float3 > handle_positions_right() const
AttributeAccessor attributes() const
void count_memory(MemoryCounter &memory) const
bool is_single_type(CurveType type) const
std::optional< Bounds< float3 > > bounds_min_max(bool use_radius=true) const
Span< float3 > evaluated_positions() const
std::unique_ptr< GreasePencilEditHints > grease_pencil_edit_hints_
std::optional< MutableSpan< float3 > > positions_for_write()
const greasepencil::Drawing * drawing_orig
std::optional< Span< float3 > > positions() const
ImplicitSharingPtrAndData positions_data
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
VArray< ColorGeometry4f > vertex_colors() const
Drawing & operator=(const Drawing &other)
Span< float3 > curve_plane_normals() const
MutableSpan< float > opacities_for_write()
Span< float4x2 > texture_matrices() const
MutableSpan< float > radii_for_write()
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
VArray< float > radii() const
void tag_positions_changed()
void tag_texture_matrices_changed()
Span< int3 > triangles() const
void tag_topology_changed()
VArray< ColorGeometry4f > fill_colors() const
VArray< float > opacities() const
MutableSpan< ColorGeometry4f > fill_colors_for_write()
MutableSpan< ColorGeometry4f > vertex_colors_for_write()
void set_texture_matrices(Span< float4x2 > matrices, const IndexMask &selection)
void move_node_top(TreeNode &node)
void prepare_for_dna_write()
void set_expanded(bool expanded)
TreeNode & add_node(TreeNode &node)
void move_node_down(TreeNode &node, int step=1)
void move_node_bottom(TreeNode &node)
bool unlink_node(TreeNode &link, bool keep_children=false)
const TreeNode & as_node() const
int64_t num_direct_nodes() const
int64_t num_nodes_total() const
Span< TreeNode * > nodes_for_write()
const TreeNode * find_node_by_name(StringRef name) const
Span< const Layer * > layers() const
void update_from_dna_read()
Span< Layer * > layers_for_write()
void add_node_before(TreeNode &node, TreeNode &link)
void add_node_after(TreeNode &node, TreeNode &link)
void move_node_up(TreeNode &node, int step=1)
void print_nodes(StringRef header) const
LayerGroup & operator=(const LayerGroup &other)
Span< const LayerGroup * > groups() const
Span< LayerGroup * > groups_for_write()
Span< const TreeNode * > nodes() const
SharedCache< Vector< FramesMapKeyT > > sorted_keys_cache_
Map< FramesMapKeyT, GreasePencilFrame > frames_
LayerTransformData trans_data_
Vector< LayerMask > masks_
SortedKeysIterator sorted_keys_iterator_at(int frame_number) const
StringRefNull parent_bone_name() const
int sorted_keys_index_at(int frame_number) const
float4x4 to_world_space(const Object &object) const
StringRefNull view_layer_name() const
void set_local_transform(const float4x4 &transform)
void set_view_layer_name(StringRef new_name)
void tag_frames_map_keys_changed()
bool remove_frame(FramesMapKeyT key)
const Map< FramesMapKeyT, GreasePencilFrame > & frames() const
float4x4 local_transform() const
GreasePencilFrame * add_frame(FramesMapKeyT key, int duration=0)
const TreeNode & as_node() const
const GreasePencilFrame * frame_at(const int frame_number) const
void tag_frames_map_changed()
bool has_drawing_at(const int frame_number) const
const int * SortedKeysIterator
int drawing_index_at(const int frame_number) const
int get_frame_duration_at(const int frame_number) const
std::optional< int > start_frame_at(int frame_number) const
float4x4 to_object_space(const Object &object) const
void update_from_dna_read()
Span< FramesMapKeyT > sorted_keys() const
float4x4 parent_inverse() const
void prepare_for_dna_write()
const LayerGroup & parent_group() const
Map< FramesMapKeyT, GreasePencilFrame > & frames_for_write()
void set_parent_bone_name(StringRef new_name)
const TreeNode * parent_node() const
const LayerGroup & as_group() const
const Layer & as_layer() const
const LayerGroup * parent_group() const
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
void foreach_index(Fn &&fn) const
void foreach_segment(Fn &&fn) const
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
const Depsgraph * depsgraph
static float normals[][3]
VecBase< float, D > normalize(VecOp< float, D >) RET
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
MatBase< R, C > transpose(MatBase< C, R >) RET
VecBase< float, 3 > cross(VecOp< float, 3 >, VecOp< float, 3 >) RET
static void shrink_array(T **array, int *num, const int shrink_num)
static void transform_positions(const Span< blender::float3 > src, const blender::float4x4 &transform, blender::MutableSpan< blender::float3 > dst)
static void read_layer_tree_group(BlendDataReader *reader, GreasePencilLayerTreeGroup *node, GreasePencilLayerTreeGroup *parent)
static void read_drawing_array(GreasePencil &grease_pencil, BlendDataReader *reader)
static void grease_pencil_evaluate_layers(GreasePencil &grease_pencil)
static GreasePencilModifierInfluenceData * influence_data_from_modifier(ModifierData *md)
static void grow_array(T **array, int *num, const int add_num)
static bool grease_pencil_references_cyclic_check_internal(const GreasePencil *id_reference, const GreasePencil *grease_pencil)
static void grease_pencil_free_data(ID *id)
static std::string unique_node_name(const GreasePencil &grease_pencil, const blender::StringRef name)
static void reorder_layer_data(GreasePencil &grease_pencil, const blender::FunctionRef< void()> do_layer_order_changes)
static void free_drawing_array(GreasePencil &grease_pencil)
static void write_layer_tree_group(BlendWriter *writer, GreasePencilLayerTreeGroup *node)
static void update_active_node_from_node_to_remove(GreasePencil &grease_pencil, const blender::bke::greasepencil::TreeNode &node)
static void grease_pencil_do_layer_adjustments(GreasePencil &grease_pencil)
static const char * ATTR_POSITION
static void shrink_customdata(CustomData &data, const int index_to_remove, const int size)
static void grease_pencil_copy_data(Main *, std::optional< Library * >, ID *id_dst, const ID *id_src, const int)
void BKE_grease_pencil_batch_cache_free(GreasePencil *grease_pencil)
static void reorder_customdata(CustomData &data, const Span< int > new_by_old_map)
static void read_layer_tree(GreasePencil &grease_pencil, BlendDataReader *reader)
static void write_layer(BlendWriter *writer, GreasePencilLayer *node)
static Material * grease_pencil_object_material_ensure_from_brush_pinned(Main *bmain, Object *ob, Brush *brush)
static std::string unique_layer_group_name(const GreasePencil &grease_pencil, blender::StringRef name)
static void write_layer_tree(GreasePencil &grease_pencil, BlendWriter *writer)
static void grease_pencil_set_runtime_visibilities(ID &id_dst, GreasePencil &grease_pencil)
static void delete_drawing(GreasePencilDrawingBase *drawing_base)
static void grease_pencil_blend_read_data(BlendDataReader *reader, ID *id)
static void write_drawing_array(GreasePencil &grease_pencil, blender::ResourceScope &scope, BlendWriter *writer)
static blender::VectorSet< blender::StringRef > get_node_names(const GreasePencil &grease_pencil)
void BKE_grease_pencil_duplicate_drawing_array(const GreasePencil *grease_pencil_src, GreasePencil *grease_pencil_dst)
static void grease_pencil_foreach_id(ID *id, LibraryForeachIDData *data)
static void grease_pencil_blend_write(BlendWriter *writer, ID *id, const void *id_address)
static void grease_pencil_init_data(ID *id)
static void read_layer(BlendDataReader *reader, GreasePencilLayer *node, GreasePencilLayerTreeGroup *parent)
static void grease_pencil_evaluate_modifiers(Depsgraph *depsgraph, Scene *scene, Object *object, blender::bke::GeometrySet &geometry_set)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void copy_group_to_group(OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, GSpan src, GMutableSpan dst)
GAttributeReader lookup(const void *owner, const StringRef name)
void ensure_non_empty_layer_names(Main &bmain, GreasePencil &grease_pencil)
static void update_curve_plane_normal_cache(const Span< float3 > positions, const OffsetIndices< int > points_by_curve, const IndexMask &curve_mask, MutableSpan< float3 > normals)
static int domain_num(const CurvesGeometry &curves, const AttrDomain domain)
static CustomData & domain_custom_data(CurvesGeometry &curves, const AttrDomain domain)
constexpr StringRef ATTR_RADIUS
static void update_triangle_cache(const Span< float3 > positions, const Span< float3 > normals, const OffsetIndices< int > points_by_curve, const OffsetIndices< int > triangle_offsets, const IndexMask &curve_mask, MutableSpan< int3 > triangles)
static float4x2 get_local_to_stroke_matrix(const Span< float3 > positions, const float3 normal)
constexpr StringRef ATTR_VERTEX_COLOR
static MutableSpan< T > get_mutable_attribute(CurvesGeometry &curves, const AttrDomain domain, const StringRef name, const T default_value=T())
static float3x2 get_stroke_to_texture_matrix(const float uv_rotation, const float2 uv_translation, const float2 uv_scale)
const AttributeAccessorFunctions & get_attribute_accessor_functions()
constexpr StringRef ATTR_OPACITY
constexpr StringRef ATTR_FILL_COLOR
static float4x3 expand_4x2_mat(float4x2 strokemat)
void copy_drawing_array(Span< const GreasePencilDrawingBase * > src_drawings, MutableSpan< GreasePencilDrawingBase * > dst_drawings)
constexpr StringRef ATTR_RADIUS
static MutableSpan< T > get_mutable_attribute(CurvesGeometry &curves, const AttrDomain domain, const StringRef name, const T default_value=T())
auto attribute_filter_from_skip_ref(const Span< StringRef > skip)
void fill_attribute_range_default(MutableAttributeAccessor dst_attributes, AttrDomain domain, const AttributeFilter &attribute_filter, IndexRange range)
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type)
ID * asset_edit_id_find_local(Main &global_main, ID &id)
void grease_pencil_convert_storage_to_customdata(GreasePencil &grease_pencil)
ID * asset_edit_id_ensure_local(Main &global_main, ID &id)
Bounds< T > merge(const Bounds< T > &a, const Bounds< T > &b)
std::optional< Bounds< T > > min_max_with_radii(const Span< T > values, const Span< RadiusT > radii)
std::optional< Bounds< T > > min_max(const std::optional< Bounds< T > > &a, const T &b)
T length_squared(const VecBase< T, Size > &a)
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
T distance(const T &a, const T &b)
T length(const VecBase< T, Size > &a)
QuaternionBase< T > normalize_and_get_length(const QuaternionBase< T > &q, T &out_length)
CartesianBasis invert(const CartesianBasis &basis)
T atan2(const T &y, const T &x)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
void to_loc_rot_scale_safe(const MatBase< T, 4, 4 > &mat, VecBase< T, 3 > &r_location, RotationT &r_rotation, VecBase< T, 3 > &r_scale)
T determinant(const MatBase< T, Size, Size > &mat)
MatT from_loc_rot_scale(const typename MatT::loc_type &location, const RotationT &rotation, const VecBase< typename MatT::base_type, ScaleDim > &scale)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
void parallel_for_each(Range &&range, const Function &function)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
MatBase< double, 4, 2 > double4x2
MatBase< float, 2, 2 > float2x2
MatBase< float, 2, 4 > float2x4
VecBase< float, 4 > float4
MatView< float, 4, 4, 4, 4, 0, 0, alignof(float)> float4x4_view
VecBase< float, 2 > float2
MatBase< float, 3, 2 > float3x2
MatBase< float, 4, 3 > float4x3
void uninitialized_relocate_n(T *src, int64_t n, T *dst)
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
MatBase< double, 4, 3 > double4x3
void uninitialized_move_n(T *src, int64_t n, T *dst)
float wrap(float value, float max, float min)
static void unique_name(bNode *node)
PropertyRNA * RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
std::optional< std::string > RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
struct Material * material
struct Material * material_alt
struct BrushGpencilSettings * gpencil_settings
CurvesGeometryRuntimeHandle * runtime
ListBase vertex_group_names
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
struct GreasePencil * id_reference
GreasePencilDrawingBase base
GreasePencilDrawingBase base
GreasePencilDrawingRuntimeHandle * runtime
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilFrame * values
GreasePencilLayerTreeNode base
GreasePencilLayerGroupRuntimeHandle * runtime
struct GreasePencilLayerTreeNode * next
struct GreasePencilLayerTreeNode * prev
struct GreasePencilLayerTreeGroup * parent
GreasePencilLayerRuntimeHandle * runtime
GreasePencilLayerTreeNode base
GreasePencilLayerFramesMapStorage frames_storage
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
int attributes_active_index
GreasePencilLayerTreeNode * active_node
struct Material ** material_array
int vertex_group_active_index
ListBase vertex_group_names
GreasePencilLayerTreeGroup * root_group_ptr
GreasePencilRuntimeHandle * runtime
GreasePencilDrawingBase ** drawing_array
GreasePencilOnionSkinningSettings onion_skinning_settings
struct AttributeStorage attribute_storage
struct ModifierData * next
void(* modify_geometry_set)(ModifierData *md, const ModifierEvalContext *ctx, blender::bke::GeometrySet *geometry_set)
void pad(const PaddingT &padding)
const c_style_mat & ptr() const
static MatBase identity()
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
const GreasePencil * get_grease_pencil() const
bool has_grease_pencil() const
GreasePencil * get_grease_pencil_for_write()
void replace_grease_pencil(GreasePencil *grease_pencil, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
MutableVArraySpan< T > span