94 grease_pencil->
root_group_ptr = MEM_new<greasepencil::LayerGroup>(__func__);
95 grease_pencil->set_active_node(
nullptr);
99 grease_pencil->
runtime = MEM_new<GreasePencilRuntime>(__func__);
103 std::optional<Library *> ,
120 grease_pencil_dst->
root_group_ptr = MEM_new<bke::greasepencil::LayerGroup>(
121 __func__, grease_pencil_src->root_group());
124 if (grease_pencil_src->get_active_node()) {
126 grease_pencil_src->get_active_node()->name());
128 grease_pencil_dst->set_active_node(active_node);
134 grease_pencil_dst->layers().size());
140 grease_pencil_dst->
runtime = MEM_new<bke::GreasePencilRuntime>(__func__);
142 if (grease_pencil_src->
runtime->bake_materials) {
143 grease_pencil_dst->
runtime->bake_materials = std::make_unique<bke::bake::BakeMaterialsList>(
144 *grease_pencil_src->
runtime->bake_materials);
158 MEM_delete(&grease_pencil->root_group());
164 MEM_delete(grease_pencil->
runtime);
165 grease_pencil->
runtime =
nullptr;
202 grease_pencil->layers().size(),
237 grease_pencil->
runtime = MEM_new<blender::bke::GreasePencilRuntime>(__func__);
247 N_(
"grease_pencils_v3"),
290 const T default_value =
T())
300 if (data !=
nullptr) {
305 if (span.
first() != default_value) {
306 span.
fill(default_value);
318 this->
runtime = MEM_new<bke::greasepencil::DrawingRuntime>(__func__);
328 this->
runtime = MEM_new<bke::greasepencil::DrawingRuntime>(__func__);
330 this->
runtime->triangle_offsets_cache = other.
runtime->triangle_offsets_cache;
332 this->
runtime->curve_plane_normals_cache = other.
runtime->curve_plane_normals_cache;
333 this->
runtime->curve_texture_matrices = other.
runtime->curve_texture_matrices;
346 other.runtime =
nullptr;
351 if (
this == &other) {
354 std::destroy_at(
this);
361 if (
this == &other) {
364 std::destroy_at(
this);
365 new (
this)
Drawing(std::move(other));
384 for (
const int curve_i : points_by_curve.index_range()) {
385 const IndexRange points = points_by_curve[curve_i];
386 r_offsets[curve_i] = offset;
387 offset += std::max(
int(points.size() - 2), 0);
389 r_offsets.
last() = offset;
391 return this->
runtime->triangle_offsets_cache.
data().as_span();
401 struct LocalMemArena {
407 if (pf_arena !=
nullptr) {
415 for (
const int curve_i : mask_segment) {
416 const IndexRange points = points_by_curve[curve_i];
417 if (points.size() < 3) {
422 float(*projverts)[2] =
static_cast<float(*)[2]
>(
428 for (
const int i :
IndexRange(points.size())) {
433 projverts, points.size(), 0,
reinterpret_cast<uint32_t(*)[3]
>(r_tris.
data()), pf_arena);
444 const int total_triangles = triangle_offsets.
total_size();
445 r_data.
resize(total_triangles);
448 this->curve_plane_normals(),
449 curves.evaluated_points_by_curve(),
451 curves.curves_range(),
455 return this->
runtime->triangles_cache.data().as_span();
464 const IndexRange points = points_by_curve[curve_i];
465 if (points.size() < 2) {
466 normals[curve_i] = float3(1.0f, 0.0f, 0.0f);
472 float3 prev_point = positions[points.last()];
473 for (
const int point_i : points) {
474 const float3 curr_point = positions[point_i];
476 prev_point = curr_point;
483 for (
const int point_i : points.drop_back(1)) {
484 float3 segment_vec = positions[point_i] - positions[point_i + 1];
492 normals[curve_i] = normal;
502 curves.points_by_curve(),
503 curves.curves_range(),
506 return this->
runtime->curve_plane_normals_cache.
data().as_span();
517 if (positions.size() <= 2) {
521 const float3 point_0 = positions[0];
522 const float3 point_1 = positions[1];
529 if (length_squared(local_x) == 0.0f || length_squared(local_y) == 0.0f) {
545 const float2 uv_translation,
550 const float2 uv_scale_inv = safe_rcp(uv_scale);
551 const float s = sin(uv_rotation);
552 const float c =
cos(uv_rotation);
569 texture_matrix = from_scale<float2x2>(uv_scale_inv) * texture_matrix;
572 texture_matrix =
rot * texture_matrix;
575 texture_matrix[2] += uv_translation;
577 return texture_matrix;
594 strokemat4x3[2][2] = 0.0f;
595 strokemat4x3[3][2] = 1.0f;
606 const VArray<float> uv_rotations = *attributes.lookup_or_default<
float>(
619 for (const int curve_i : range) {
620 const IndexRange points = points_by_curve[curve_i];
621 const float3 normal = normals[curve_i];
622 const float4x2 strokemat = get_local_to_stroke_matrix(positions.slice(points), normal);
623 const float3x2 texture_matrix = get_stroke_to_texture_matrix(
624 uv_rotations[curve_i], uv_translations[curve_i], uv_scales[curve_i]);
626 const float4x2 texspace = texture_matrix * expand_4x2_mat(strokemat);
628 r_data[curve_i] = texspace;
632 return this->runtime->curve_texture_matrices.
data().as_span();
651 const Span<float3> normals = this->curve_plane_normals();
654 const IndexRange points = points_by_curve[curve_i];
655 const float3 normal = normals[curve_i];
680 const double3x4 right_inverse = transpose_strokemat *
681 invert(strokemat4x3 * transpose_strokemat);
686 const float2 uv_translation = texture_matrix[2];
689 const float uv_rotation = atan2(texture_matrix[0][1], texture_matrix[0][0]);
696 const float2 uv_scale = safe_rcp(
699 uv_rotations.
span[curve_i] = uv_rotation;
700 uv_translations.span[curve_i] = uv_translation;
701 uv_scales.span[curve_i] = uv_scale;
704 uv_translations.finish();
707 this->tag_texture_matrices_changed();
712 return this->geometry.wrap();
717 return this->geometry.wrap();
722 return *this->strokes().attributes().lookup_or_default<
float>(
734 return *this->strokes().attributes().lookup_or_default<
float>(
746 return *this->strokes().attributes().lookup_or_default<
ColorGeometry4f>(
760 return *this->strokes().attributes().lookup_or_default<
ColorGeometry4f>(
774 this->runtime->curve_texture_matrices.tag_dirty();
779 this->strokes_for_write().tag_positions_changed();
780 this->runtime->curve_plane_normals_cache.tag_dirty();
781 this->runtime->triangles_cache.tag_dirty();
782 this->tag_texture_matrices_changed();
795 if (changed_curves.
size() > this->strokes().curves_num() / 2) {
796 this->tag_positions_changed();
799 if (!this->runtime->triangles_cache.is_cached() ||
800 !this->runtime->curve_plane_normals_cache.is_cached())
802 this->tag_positions_changed();
807 this->strokes_for_write().tag_positions_changed();
808 this->runtime->curve_plane_normals_cache.update([&](
Vector<float3> &normals) {
811 curves.positions(), curves.points_by_curve(), changed_curves, normals);
813 this->runtime->triangles_cache.update([&](
Vector<uint3> &triangles) {
816 this->curve_plane_normals(),
817 curves.evaluated_points_by_curve(),
818 this->triangle_offsets(),
819 curves.curves_range(),
822 this->tag_texture_matrices_changed();
827 this->runtime->triangle_offsets_cache.tag_dirty();
828 this->tag_positions_changed();
829 this->strokes_for_write().tag_topology_changed();
842 if (changed_curves.
size() > this->strokes().curves_num() / 2) {
843 this->tag_topology_changed();
846 if (!this->runtime->triangles_cache.is_cached() ||
847 !this->runtime->curve_plane_normals_cache.is_cached())
849 this->tag_topology_changed();
854 this->strokes_for_write().tag_positions_changed();
855 this->runtime->curve_plane_normals_cache.update([&](
Vector<float3> &normals) {
858 curves.positions(), curves.points_by_curve(), changed_curves, normals);
862 const Array<int> src_triangle_offset_data(this->triangle_offsets().
data());
866 this->runtime->triangle_offsets_cache.tag_dirty();
868 this->runtime->triangles_cache.update([&](
Vector<uint3> &triangles) {
876 triangles.reinitialize(dst_triangle_offsets.
total_size());
879 triangles.as_mutable_span()
880 .slice(dst_triangle_offsets[i])
881 .copy_from(src_triangles.
as_span().slice(src_triangle_offsets[i]));
885 this->curve_plane_normals(),
886 curves.evaluated_points_by_curve(),
887 dst_triangle_offsets,
891 this->tag_texture_matrices_changed();
894DrawingReference::DrawingReference()
899 this->id_reference =
nullptr;
905 this->base.flag = other.base.flag;
907 this->id_reference = other.id_reference;
910DrawingReference::~DrawingReference() =
default;
918 switch (src_drawing_base->
type) {
923 MEM_new<bke::greasepencil::Drawing>(__func__, src_drawing->wrap()));
930 MEM_new<bke::greasepencil::DrawingReference>(__func__, src_drawing_reference->wrap()));
939 this->
next = this->prev =
nullptr;
940 this->parent =
nullptr;
944 this->color[0] = this->color[1] = this->color[2] = 0;
978 return *
reinterpret_cast<const LayerGroup *
>(
this);
983 return *
reinterpret_cast<const Layer *
>(
this);
993 return *
reinterpret_cast<Layer *
>(
this);
998 return (this->
parent) ? &this->
parent->wrap() :
nullptr;
1002 return (this->
parent) ? &this->
parent->wrap() :
nullptr;
1016 if (parent ==
nullptr) {
1020 return 1 +
parent->as_node().depth();
1051 masks_.clear_and_shrink();
1080 this->
runtime = MEM_new<LayerRuntime>(__func__);
1093 LayerMask *new_mask = MEM_new<LayerMask>(__func__, *
reinterpret_cast<LayerMask *
>(other_mask));
1113 this->
runtime->sorted_keys_cache_ = other.
runtime->sorted_keys_cache_;
1122 this->
base.wrap().~TreeNode();
1128 MEM_delete(
reinterpret_cast<LayerMask *
>(mask));
1141 return this->
runtime->frames_;
1146 return this->
runtime->frames_;
1153 while (next_it != end && this->
frames().lookup(*next_it).is_end()) {
1156 next_it = std::next(next_it);
1163 if (!this->
frames().contains(frame_number)) {
1183 if (frame ==
nullptr) {
1191 if (next_key_it !=
sorted_keys.end() && *next_key_it == end_key) {
1194 next_key_it = this->remove_leading_end_frames_in_range(next_key_it,
sorted_keys.end());
1196 if (duration == 0) {
1202 if (next_key_it ==
sorted_keys.end() || *next_key_it > end_key) {
1212 if (!this->
frames().contains(key)) {
1224 if (std::next(remove_key_it) !=
sorted_keys.end()) {
1226 this->remove_leading_end_frames_in_range(next_key_it,
sorted_keys.end());
1234 if (!prev_frame.is_implicit_hold() && !prev_frame.is_end()) {
1256 std::sort(r_data.
begin(), r_data.
end());
1281 return std::prev(it);
1284std::optional<FramesMapKeyT> Layer::frame_key_at(
const int frame_number)
const
1287 if (it ==
nullptr) {
1295 const std::optional<FramesMapKeyT> frame_key = this->frame_key_at(frame_number);
1297 if (frame_key && !this->
frames().lookup_ptr(*frame_key)->is_end()) {
1306 if (it ==
nullptr) {
1309 return std::distance(this->
sorted_keys().begin(), it);
1319 const std::optional<FramesMapKeyT> frame_key = this->frame_key_at(frame_number);
1325 if (frame_ptr ==
nullptr || frame_ptr->is_end()) {
1339 const std::optional<FramesMapKeyT> frame_key = this->frame_key_at(frame_number);
1345 if (frame_ptr ==
nullptr || frame_ptr->is_end()) {
1360 return frame_at(frame_number) !=
nullptr;
1366 if (it ==
nullptr) {
1372 if (frame->is_implicit_hold()) {
1376 if (frame->is_end()) {
1380 const int next_frame_number = *(std::next(it));
1392 this->
runtime->sorted_keys_cache_.tag_dirty();
1405 const size_t frames_num = size_t(
frames().
size());
1428 runtime = MEM_new<blender::bke::greasepencil::LayerRuntime>(__func__);
1438 if (this->
parent ==
nullptr) {
1447 if (this->
parent ==
nullptr) {
1470 const float4x4 &parent_object_to_world =
parent.object_to_world();
1473 this->parent_bone_name().c_str()))
1475 return parent_object_to_world *
float4x4_view(channel->pose_mat);
1478 return parent_object_to_world;
1497 *
reinterpret_cast<float3 *
>(this->scale));
1520 this->
runtime = MEM_new<LayerGroupRuntime>(__func__);
1533 switch (child->type) {
1536 Layer *dup_layer = MEM_new<Layer>(__func__, layer->wrap());
1542 LayerGroup *dup_group = MEM_new<LayerGroup>(__func__, group->wrap());
1554 this->
base.wrap().~TreeNode();
1557 switch (child->type) {
1560 MEM_delete(&layer->wrap());
1565 MEM_delete(&group->wrap());
1577 if (
this == &other) {
1591 this->tag_nodes_cache_dirty();
1599 this->tag_nodes_cache_dirty();
1606 this->tag_nodes_cache_dirty();
1612 this->tag_nodes_cache_dirty();
1617 this->tag_nodes_cache_dirty();
1623 this->tag_nodes_cache_dirty();
1629 this->tag_nodes_cache_dirty();
1639 this->ensure_nodes_cache();
1640 return this->
runtime->nodes_cache_.size();
1654 link_children.
first);
1663 if (link.
next !=
nullptr) {
1667 if (link.
prev !=
nullptr) {
1684 this->tag_nodes_cache_dirty();
1689 this->tag_nodes_cache_dirty();
1697 this->ensure_nodes_cache();
1698 return this->
runtime->nodes_cache_.as_span();
1703 this->ensure_nodes_cache();
1704 return this->
runtime->nodes_cache_.as_span();
1709 this->ensure_nodes_cache();
1710 return this->
runtime->layer_cache_.as_span();
1715 this->ensure_nodes_cache();
1716 return this->
runtime->layer_cache_.as_span();
1721 this->ensure_nodes_cache();
1722 return this->
runtime->layer_group_cache_.as_span();
1727 this->ensure_nodes_cache();
1728 return this->
runtime->layer_group_cache_.as_span();
1753 std::cout << header << std::endl;
1757 next_node.
push(std::make_pair(1, child));
1760 auto [indent,
node] = next_node.
pop();
1761 for (
int i = 0; i < indent; i++) {
1764 if (node->is_layer()) {
1765 std::cout << node->name();
1767 else if (node->is_group()) {
1768 std::cout << node->name() <<
": ";
1771 next_node.
push(std::make_pair(indent + 1, child));
1774 std::cout << std::endl;
1776 std::cout << std::endl;
1779void LayerGroup::ensure_nodes_cache()
const
1781 this->
runtime->nodes_cache_mutex_.ensure([&]() {
1782 this->
runtime->nodes_cache_.clear_and_shrink();
1783 this->
runtime->layer_cache_.clear_and_shrink();
1784 this->
runtime->layer_group_cache_.clear_and_shrink();
1788 this->
runtime->nodes_cache_.append(node);
1789 switch (node->type) {
1797 this->
runtime->nodes_cache_.append(child);
1798 if (child->is_layer()) {
1799 this->
runtime->layer_cache_.append(&child->as_layer());
1801 else if (child->is_group()) {
1802 this->
runtime->layer_group_cache_.append(&child->as_group());
1812void LayerGroup::tag_nodes_cache_dirty()
const
1814 this->
runtime->nodes_cache_mutex_.tag_dirty();
1816 this->
base.
parent->wrap().tag_nodes_cache_dirty();
1823 switch (child->type) {
1825 child->as_layer().prepare_for_dna_write();
1829 child->as_group().prepare_for_dna_write();
1839 switch (child->type) {
1841 child->as_layer().update_from_dna_read();
1845 child->as_group().update_from_dna_read();
1862 return std::nullopt;
1871 return std::nullopt;
1883 data.data = new_sharing_info->data.data();
1905 return grease_pencil;
1912 return grease_pencil;
1919 grease_pencil->
runtime->eval_frame = grease_pencil_src->
runtime->eval_frame;
1920 return grease_pencil;
1945 LayerMask *new_mask = MEM_new<LayerMask>(__func__, *
reinterpret_cast<LayerMask *
>(src_mask));
1985 grease_pencil_dst->
drawing_array[i] = &MEM_new<Drawing>(__func__, src_drawing)->base;
1993 &MEM_new<DrawingReference>(__func__, src_drawing_ref)->base;
2001 MEM_delete(&grease_pencil_dst->root_group());
2004 grease_pencil_dst->
root_group_ptr = MEM_new<bke::greasepencil::LayerGroup>(
2006 BLI_assert(grease_pencil_src->layers().size() == grease_pencil_dst->layers().size());
2014 grease_pencil_src->layers().size());
2029 if (strcmp(vgroup->name, old_name) == 0) {
2030 STRNCPY(vgroup->name, new_name);
2062 for (; tmd; tmd = tmd->
next) {
2079 for (; md; md = md->
next) {
2099 using namespace bke::greasepencil;
2103 struct LayerDrawingInfo {
2105 const int layer_index;
2108 Set<Drawing *> all_drawings;
2109 Vector<LayerDrawingInfo> drawing_infos;
2110 for (
const int layer_i : grease_pencil.layers().index_range()) {
2111 const Layer &layer = grease_pencil.layer(layer_i);
2113 if (
Drawing *drawing = grease_pencil.get_eval_drawing(layer)) {
2114 if (all_drawings.add(drawing)) {
2115 drawing_infos.append({drawing, layer_i});
2120 if (layer_attributes.
contains(
"radius_offset")) {
2124 if (radius_offsets[info.layer_index] == 0.0f) {
2129 for (const int i : range) {
2130 radii[i] += radius_offsets[info.layer_index];
2136 if (layer_attributes.contains(
"tint_color")) {
2138 return base * (1.0 - tint.w) + tint * tint.w;
2144 if (tint_colors[info.layer_index].a == 0.0f) {
2149 for (const int i : range) {
2150 vertex_colors[i] = ColorGeometry4f(
2151 mix_tint(float4(vertex_colors[i]), float4(tint_colors[info.layer_index])));
2156 for (const int i : range) {
2157 fill_colors[i] = ColorGeometry4f(
2158 mix_tint(float4(fill_colors[i]), float4(tint_colors[info.layer_index])));
2176 GeometrySet geometry_set = GeometrySet::from_grease_pencil(grease_pencil,
2177 GeometryOwnershipType::ReadOnly);
2182 if (layer_attributes.
contains(
"tint_color") || layer_attributes.
contains(
"radius_offset")) {
2212 object->runtime->geometry_set_eval =
new GeometrySet(std::move(geometry_set));
2221 grease_pencil_dst->
drawing_array = MEM_cnew_array<GreasePencilDrawingBase *>(
2224 grease_pencil_dst->drawings());
2239 int total_points = 0;
2241 for (
const int layer_i : grease_pencil.layers().index_range()) {
2243 const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.frames();
2244 frames.foreach_item(
2257 return total_points;
2265 for (
const int layer_i : grease_pencil.layers().index_range()) {
2267 const float4x4 layer_to_object = layer.local_transform();
2268 const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.frames();
2269 frames.foreach_item(
2281 for (
const int i : curves.points_range()) {
2283 elem_data->
radius = radii[i];
2295 for (
const int layer_i : grease_pencil.layers().index_range()) {
2297 const float4x4 layer_to_object = layer.local_transform();
2299 const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.frames();
2311 for (
const int i : curves.points_range()) {
2313 radii[i] = elem_data->
radius;
2328 for (
const int layer_i : grease_pencil.layers().index_range()) {
2330 const float4x4 layer_to_object = layer.local_transform();
2332 const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.frames();
2344 for (
const int i : curves.points_range()) {
2346 radii[i] = elem_data->
radius * scalef;
2363 for (
short i = 0; i < *totcol; i++) {
2385 *r_index = ob->
actcol - 1;
2417 if (brush ==
nullptr) {
2450 if (brush ==
nullptr) {
2492 if (!material_indices) {
2496 for (
const int i : material_indices.
span.index_range()) {
2499 material_indices.
span[i] = remap[material_indices.
span[i]];
2501 material_indices.
finish();
2518 if (!material_indices) {
2522 for (
const int i : material_indices.
span.index_range()) {
2523 if (material_indices.
span[i] > 0 && material_indices.
span[i] >= index) {
2524 material_indices.
span[i]--;
2527 material_indices.
finish();
2542 const VArraySpan<int> material_indices = *attributes.lookup_or_default<
int>(
2543 "material_index", AttrDomain::Curve, 0);
2545 if (material_indices.
contains(index)) {
2564 if (id_reference == reference->id_reference) {
2589 int mode) =
nullptr;
2594 if (grease_pencil->
runtime && grease_pencil->
runtime->batch_cache) {
2601 if (grease_pencil->
runtime && grease_pencil->
runtime->batch_cache) {
2615 const int new_array_num = *num + add_num;
2616 T *new_array = MEM_cnew_array<T>(new_array_num, __func__);
2619 if (*
array !=
nullptr) {
2624 *num = new_array_num;
2629 const int new_array_num = *num - shrink_num;
2630 if (new_array_num == 0) {
2637 T *new_array = MEM_cnew_array<T>(new_array_num, __func__);
2643 *num = new_array_num;
2654 this->drawing_array_num};
2662 MEM_delete(&drawing->wrap());
2668 MEM_delete(&drawing_reference->wrap());
2674void GreasePencil::resize_drawings(
const int new_num)
2679 const int prev_num =
int(this->drawings().
size());
2680 if (new_num == prev_num) {
2683 if (new_num > prev_num) {
2684 const int add_num = new_num - prev_num;
2688 const int shrink_num = prev_num - new_num;
2690 for (
const int64_t i : old_drawings.index_range()) {
2696 &this->drawing_array, &this->drawing_array_num, shrink_num);
2700void GreasePencil::add_empty_drawings(
const int add_num)
2704 const int prev_num = this->drawings().size();
2707 for (
const int i : new_drawings.index_range()) {
2709 MEM_new<blender::bke::greasepencil::Drawing>(__func__));
2713void GreasePencil::add_duplicate_drawings(
const int duplicate_num,
2718 const int prev_num = this->drawings().size();
2720 &this->drawing_array, &this->drawing_array_num, duplicate_num);
2722 for (
const int i : new_drawings.index_range()) {
2724 MEM_new<bke::greasepencil::Drawing>(__func__, drawing));
2730 const int frame_number,
2736 if (frame ==
nullptr) {
2739 this->add_empty_drawings(1);
2740 frame->
drawing_index = this->drawings().index_range().last();
2746 return &drawing->wrap();
2750 const int frame_number,
2755 if (layers.is_empty()) {
2758 Vector<GreasePencilFrame *> frames;
2759 frames.reserve(layers.size());
2763 if (frame !=
nullptr) {
2764 frames.append(frame);
2768 if (frames.is_empty()) {
2772 this->add_empty_drawings(frames.size());
2774 for (
const int frame_i : frames.index_range()) {
2782 const int src_frame_number,
2783 const int dst_frame_number,
2784 const bool do_instance)
2788 if (!layer.frames().contains(src_frame_number)) {
2797 const int duration = layer.get_frame_duration_at(src_frame_number);
2799 if (dst_frame ==
nullptr) {
2806 switch (src_drawing_base->
type) {
2819 this->add_duplicate_drawings(1, src_drawing);
2826 layer.remove_frame(dst_frame_number);
2836 bool removed_any_drawing_user =
false;
2837 for (
const int frame_number : frame_numbers) {
2838 if (!layer.frames().contains(frame_number)) {
2843 if (!layer.remove_frame(frame_number)) {
2847 if (frame_to_remove.is_end()) {
2859 removed_any_drawing_user =
true;
2861 if (removed_any_drawing_user) {
2862 this->remove_drawings_with_no_users();
2868void GreasePencil::add_layers_with_empty_drawings_for_eval(
const int num)
2872 const int old_drawings_num = this->drawing_array_num;
2873 const int old_layers_num = this->layers().
size();
2874 this->add_empty_drawings(num);
2875 this->add_layers_for_eval(num);
2877 for (
const int i : range) {
2878 const int new_drawing_i = old_drawings_num + i;
2879 const int new_layer_i = old_layers_num + i;
2882 Layer &layer = this->layer(new_layer_i);
2891void GreasePencil::remove_drawings_with_no_users()
2909 auto is_drawing_used = [&](
const int drawing_index) {
2917 return drawing->wrap().has_users();
2922 constexpr const int unchanged_index = -1;
2925 int first_unused_drawing = -1;
2926 int last_used_drawing = drawings.
size() - 1;
2929 auto find_next_swap_index = [&]() ->
bool {
2931 ++first_unused_drawing;
2932 }
while (first_unused_drawing <= last_used_drawing && is_drawing_used(first_unused_drawing));
2933 while (last_used_drawing >= 0 && !is_drawing_used(last_used_drawing)) {
2934 --last_used_drawing;
2937 return first_unused_drawing < last_used_drawing;
2940 while (find_next_swap_index()) {
2942 std::swap(drawings[first_unused_drawing], drawings[last_used_drawing]);
2943 drawing_index_map[last_used_drawing] = first_unused_drawing;
2949 BLI_assert(last_used_drawing == first_unused_drawing - 1);
2951 for (
const int i : drawings.index_range()) {
2952 if (i < first_unused_drawing) {
2962 const IndexRange drawings_to_remove = (first_unused_drawing > 0) ?
2964 first_unused_drawing) :
2966 if (drawings_to_remove.
is_empty()) {
2971 for (
const int i : drawings_to_remove) {
2973 switch (unused_drawing_base->
type) {
2976 MEM_delete(&unused_drawing->wrap());
2981 unused_drawing_base);
2982 MEM_delete(&unused_drawing_ref->wrap());
2988 &this->drawing_array, &this->drawing_array_num, drawings_to_remove.
size());
2991 for (Layer *layer : this->layers_for_write()) {
2992 for (
auto [key, value] : layer->frames_for_write().items()) {
2993 const int new_drawing_index = drawing_index_map[value.drawing_index];
2994 if (new_drawing_index != unchanged_index) {
2995 value.drawing_index = new_drawing_index;
2996 layer->tag_frames_map_changed();
3005 for (
auto [key, value] : layer.frames().items()) {
3006 BLI_assert(this->drawings().index_range().contains(value.drawing_index));
3022 return this->move_duplicate_frames(
3026void GreasePencil::move_duplicate_frames(
3032 Map<int, GreasePencilFrame> layer_frames_copy = layer.frames();
3035 Map<int, int> src_layer_frames_durations;
3036 for (
const auto [frame_number, frame] : layer.frames().items()) {
3037 src_layer_frames_durations.add(frame_number, layer.get_frame_duration_at(frame_number));
3043 for (
const auto src_frame_number : frame_number_destinations.keys()) {
3044 if (!duplicate_frames.
contains(src_frame_number)) {
3046 layer.remove_frame(src_frame_number);
3050 auto get_source_frame = [&](
const int frame_number) ->
const GreasePencilFrame * {
3054 return layer_frames_copy.lookup_ptr(frame_number);
3057 for (
const auto [src_frame_number, dst_frame_number] : frame_number_destinations.items()) {
3062 const int duration = src_layer_frames_durations.lookup_default(src_frame_number, 0);
3065 if (layer.frames().contains(dst_frame_number)) {
3071 layer.remove_frame(dst_frame_number);
3074 *frame = *src_frame;
3078 this->remove_drawings_with_no_users();
3084 const int drawing_index = layer.drawing_index_at(frame_number);
3085 if (drawing_index == -1) {
3095 return &drawing->wrap();
3101 const int drawing_index = layer.drawing_index_at(frame_number);
3102 if (drawing_index == -1) {
3112 return &drawing->wrap();
3118 if (!layer.is_editable()) {
3122 const int drawing_index = layer.drawing_index_at(frame_number);
3123 if (drawing_index == -1) {
3133 return &drawing->wrap();
3139 return this->get_drawing_at(layer, this->runtime->eval_frame);
3145 return this->get_drawing_at(layer, this->runtime->eval_frame);
3155 for (const int i : range) {
3156 dst[i] = blender::math::transform_point(transform, src[i]);
3161std::optional<blender::Bounds<blender::float3>> GreasePencil::bounds_min_max(
const int frame)
const
3164 std::optional<Bounds<float3>> bounds;
3166 for (
const int layer_i : layers.index_range()) {
3168 const float4x4 layer_to_object = layer.local_transform();
3169 if (!layer.is_visible()) {
3175 Array<float3> world_pos(curves.evaluated_positions().size());
3183std::optional<blender::Bounds<blender::float3>> GreasePencil::bounds_min_max_eval()
const
3185 return this->bounds_min_max(this->runtime->eval_frame);
3204 return this->root_group().layers();
3210 return this->root_group().layers_for_write();
3216 return this->root_group().groups();
3222 return this->root_group().groups_for_write();
3228 return this->root_group().nodes();
3234 return this->root_group().nodes_for_write();
3237std::optional<int> GreasePencil::get_layer_index(
3240 const int index =
int(this->layers().first_index_try(&layer));
3249 if (this->active_node ==
nullptr) {
3261 if (this->active_node ==
nullptr) {
3276 this->autolock_inactive_layers();
3282 if (layer ==
nullptr) {
3285 return this->get_active_layer() == layer;
3288void GreasePencil::autolock_inactive_layers()
3292 for (Layer *layer : this->layers_for_write()) {
3293 if (this->is_layer_active(layer)) {
3294 layer->set_locked(
false);
3297 layer->set_locked(
true);
3303 if (this->active_node ==
nullptr) {
3315 if (this->active_node ==
nullptr) {
3327 if (this->active_node ==
nullptr) {
3330 return &this->active_node->wrap();
3335 if (this->active_node ==
nullptr) {
3338 return &this->active_node->wrap();
3351 names.
add(node->name());
3364 const char *default_name,
3371 const char *default_name,
3394 const bool check_name_is_unique)
3397 std::string
unique_name = check_name_is_unique ? unique_layer_name(name) : name.c_str();
3398 const int numLayers = layers().size();
3418 const bool check_name_is_unique)
3422 move_node_into(new_layer.
as_node(), parent_group);
3426void GreasePencil::add_layers_for_eval(
const int num_new_layers)
3429 const int num_layers = this->layers().
size();
3431 for ([[maybe_unused]]
const int i :
IndexRange(num_new_layers)) {
3435 this->root_group().add_node(new_layer->
as_node());
3443 std::string
unique_name = unique_layer_name(duplicate_layer.name());
3444 std::optional<int> duplicate_layer_idx = get_layer_index(duplicate_layer);
3445 const int numLayers = layers().size();
3447 if (duplicate_layer_idx.has_value()) {
3448 for (
const int layer_index :
IndexRange(layers_data.totlayer)) {
3453 *duplicate_layer_idx,
3460 root_group().add_node(new_layer->
as_node());
3461 this->update_drawing_users_for_layer(*new_layer);
3472 move_node_into(new_layer.
as_node(), parent_group);
3484 return root_group().add_node(new_group->
as_node()).as_group();
3490 const bool check_name_is_unique)
3494 move_node_into(new_group.
as_node(), parent_group);
3503 for (
const int old_i : new_by_old_map.
index_range()) {
3504 const int new_i = new_by_old_map[old_i];
3518 Map<const bke::greasepencil::Layer *, int> old_layer_index_by_layer;
3519 old_layer_index_by_layer.reserve(layers.size());
3520 for (
const int i : layers.index_range()) {
3521 old_layer_index_by_layer.add_new(layers[i], i);
3525 do_layer_order_changes();
3526 layers = grease_pencil.layers();
3527 BLI_assert(layers.size() == old_layer_index_by_layer.size());
3531 for (
const int layer_i_new : layers.index_range()) {
3533 BLI_assert(old_layer_index_by_layer.contains(layer));
3534 const int layer_i_old = old_layer_index_by_layer.pop(layer);
3535 new_by_old_map[layer_i_old] = layer_i_new;
3537 BLI_assert(old_layer_index_by_layer.is_empty());
3546 if (!node.parent_group()) {
3554 if (!node.parent_group()) {
3557 reorder_layer_data(*
this, [&]() { node.parent_group()->move_node_down(node, step); });
3562 if (!node.parent_group()) {
3570 if (!node.parent_group()) {
3580 if (!target_node.
parent_group() || !node.parent_group()) {
3584 node.parent_group()->unlink_node(node);
3585 target_node.
parent_group()->add_node_after(node, target_node);
3593 if (!target_node.
parent_group() || !node.parent_group()) {
3597 node.parent_group()->unlink_node(node);
3598 target_node.
parent_group()->add_node_before(node, target_node);
3606 if (!node.parent_group()) {
3610 node.parent_group()->unlink_node(node);
3618 return this->root_group().find_node_by_name(name);
3624 return this->root_group().find_node_by_name(name);
3631 const TreeNode *node = this->find_node_by_name(name);
3636 if (node->is_layer()) {
3637 const int index = *this->get_layer_index(node->as_layer());
3640 if (node->is_group()) {
3642 for (
const int64_t layer_index : this->layers().index_range()) {
3643 const Layer &layer = *this->layers()[layer_index];
3644 if (layer.is_child_of(node->as_group())) {
3645 layer_indices.
append(layer_index);
3764void GreasePencil::rename_node(
Main &bmain,
3769 if (node.name() == new_name) {
3774 std::string old_name = node.name();
3775 if (node.is_layer()) {
3776 node.set_name(unique_layer_name(new_name));
3778 else if (node.is_group()) {
3783 if (node.is_layer()) {
3788 if (
STREQ(mask->layer_name, old_name.c_str())) {
3789 mask->layer_name =
BLI_strdup(node.name().c_str());
3797 if (object->data !=
this) {
3803 char *dst_layer_name =
nullptr;
3804 size_t dst_layer_name_len = 0;
3809 dst_layer_name_len =
sizeof(lmd->target_layer);
3814 dst_layer_name = influence_data->layer_name;
3815 dst_layer_name_len =
sizeof(influence_data->layer_name);
3817 if (dst_layer_name &&
STREQ(dst_layer_name, old_name.c_str())) {
3818 BLI_strncpy(dst_layer_name, node.name().c_str(), dst_layer_name_len);
3831 const IndexRange range_before(index_to_remove);
3832 const IndexRange range_after(index_to_remove + 1, size - index_to_remove - 1);
3836 &data, &new_data, range_before.
start(), range_before.
start(), range_before.
size());
3840 &data, &new_data, range_after.
start(), range_after.
start() - 1, range_after.
size());
3852 if (node.prev !=
nullptr) {
3853 grease_pencil.set_active_node(
reinterpret_cast<TreeNode *
>(node.prev));
3857 else if (node.next !=
nullptr) {
3858 grease_pencil.set_active_node(
reinterpret_cast<TreeNode *
>(node.next));
3863 grease_pencil.set_active_node(&node.parent->wrap().as_node());
3867 grease_pencil.set_active_node(
nullptr);
3875 if (&layer.as_node() == this->get_active_node()) {
3880 const int layer_index = *this->get_layer_index(layer);
3884 layer.parent_group().unlink_node(layer.as_node());
3894 drawing->wrap().remove_user();
3896 this->remove_drawings_with_no_users();
3903 const bool keep_children)
3907 if (&group.as_node() == this->get_active_node()) {
3909 if (keep_children && !group.is_empty()) {
3910 this->set_active_node(
reinterpret_cast<TreeNode *
>(group.children.last));
3917 if (!keep_children) {
3920 switch (child->type) {
3937 group.as_node().parent_group()->unlink_node(group.as_node(),
true);
3941void GreasePencil::print_layer_tree()
3944 this->root_group().print_nodes(
"Layer Tree:");
3964 drawing->wrap().strokes_for_write().blend_read(*reader);
3966 drawing->
runtime = MEM_new<blender::bke::greasepencil::DrawingRuntime>(__func__);
3985 bke::CurvesGeometry::BlendWriteData write_data =
3986 drawing->wrap().strokes_for_write().blend_write_prepare();
3988 drawing->wrap().strokes_for_write().blend_write(*writer, grease_pencil.
id, write_data);
4003 grease_pencil.resize_drawings(0);
4017 node->base.parent = parent;
4024 reader,
GreasePencilFrame, node->frames_storage.num, &node->frames_storage.values);
4035 node->runtime =
nullptr;
4036 node->wrap().update_from_dna_read();
4044 node->base.parent = parent;
4048 switch (child->type) {
4062 node->wrap().runtime = MEM_new<blender::bke::greasepencil::LayerGroupRuntime>(__func__);
4073 grease_pencil.
root_group_ptr = MEM_new<blender::bke::greasepencil::LayerGroup>(__func__);
4074 grease_pencil.set_active_node(
nullptr);
4093 writer,
GreasePencilFrame, node->frames_storage.num, node->frames_storage.values);
4106 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::Vector< CustomDataLayer, 16 > &layers_to_write, const blender::Set< std::string > &skip_names={})
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_init_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
void CustomData_free(CustomData *data, 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_get(const GreasePencil &grease_pencil, GreasePencilPointCoordinates *elem_data)
void * BKE_grease_pencil_add(Main *bmain, const char *name)
Material * BKE_grease_pencil_object_material_ensure_from_active_input_brush(Main *bmain, Object *ob, Brush *brush)
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)
Material * BKE_grease_pencil_object_material_ensure_active(Object *ob)
void BKE_grease_pencil_point_coords_apply_with_mat4(GreasePencil &grease_pencil, GreasePencilPointCoordinates *elem_data, const blender::float4x4 &mat)
void BKE_grease_pencil_vgroup_name_update(Object *ob, const char *old_name, const char *new_name)
void BKE_grease_pencil_point_coords_apply(GreasePencil &grease_pencil, GreasePencilPointCoordinates *elem_data)
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)
Material * BKE_grease_pencil_object_material_ensure_from_brush(Main *bmain, Object *ob, Brush *brush)
void BKE_grease_pencil_data_update(Depsgraph *depsgraph, Scene *scene, Object *object)
void BKE_grease_pencil_nomain_to_grease_pencil(GreasePencil *grease_pencil_src, GreasePencil *grease_pencil_dst)
bool BKE_grease_pencil_drawing_attribute_required(const GreasePencilDrawing *, const char *name)
Material * BKE_grease_pencil_object_material_ensure_from_active_input_material(Object *ob)
void BKE_grease_pencil_duplicate_drawing_array(const GreasePencil *grease_pencil_src, GreasePencil *grease_pencil_dst)
Material * BKE_grease_pencil_object_material_from_brush_get(Object *ob, Brush *brush)
Material * BKE_grease_pencil_brush_material_get(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)
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.
struct Material * BKE_gpencil_material_add(struct Main *bmain, const char *name)
struct Material * BKE_object_material_get(struct Object *ob, short act)
short * BKE_object_material_len_p(struct Object *ob)
void BKE_object_material_assign(struct Main *bmain, struct Object *ob, struct Material *ma, short act, int assign_type)
@ BKE_MAT_ASSIGN_USERPREF
void BKE_gpencil_material_attr_init(struct Material *ma)
bool BKE_object_material_slot_add(struct Main *bmain, struct Object *ob)
int BKE_object_material_index_get(Object *ob, const Material *ma)
struct Material * BKE_material_default_gpencil(void)
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()
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
void void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
bool BLI_remlink_safe(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void void void bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL()
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT 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 unit_m4(float m[4][4])
void copy_m4_m4(float m1[4][4], const float m2[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_uchar(unsigned char r[3], const unsigned char a[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])
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
#define BLI_MEMARENA_STD_BUFSIZE
void void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
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
#define STRNCPY(dst, src)
char * BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
size_t void BLI_uniquename_cb(UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(1
#define UNUSED_VARS_NDEBUG(...)
#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, uint num, const int32_t *data_ptr)
void BLO_read_int32_array(BlendDataReader *reader, int 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)
void BLO_read_pointer_array(BlendDataReader *reader, int array_size, void **ptr_p)
#define BLO_read_struct(reader, struct_name, ptr_p)
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
#define BLT_I18NCONTEXT_ID_GPENCIL
void DEG_id_tag_update(ID *id, unsigned int flags)
float DEG_get_ctime(const Depsgraph *graph)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
Object * DEG_get_original_object(Object *object)
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_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
Read Guarded memory(de)allocation.
static const char * ATTR_POSITION
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
btMatrix3x3 transpose() const
Return the transpose of the matrix.
btScalar determinant() const
Return the determinant of the matrix.
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
Span< T > as_span() const
static const CPPType & get()
ImplicitSharingPtr sharing_info
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)
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
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 const char * c_str() 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 reinitialize(const int64_t new_size)
Span< T > as_span() 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
MutableAttributeAccessor attributes_for_write()
AttributeAccessor attributes() const
void count_memory(MemoryCounter &memory) 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
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< uint3 > 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()
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()
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(StringRefNull header) const
LayerGroup & operator=(const LayerGroup &other)
Span< const LayerGroup * > groups() const
Span< LayerGroup * > groups_for_write()
Span< const TreeNode * > nodes() const
const TreeNode * find_node_by_name(StringRefNull name) 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
void set_parent_bone_name(const char *new_name)
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(const char *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()
Map< FramesMapKeyT, GreasePencilFrame > & frames_for_write()
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
const Depsgraph * depsgraph
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
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 std::string unique_node_name(const GreasePencil &grease_pencil, const char *default_name, blender::StringRef name)
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 blender::VectorSet< blender::StringRefNull > get_node_names(const GreasePencil &grease_pencil)
static bool check_unique_node_cb(void *arg, const char *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 void write_layer_tree(GreasePencil &grease_pencil, BlendWriter *writer)
static void delete_drawing(GreasePencilDrawingBase *drawing_base)
static void grease_pencil_blend_read_data(BlendDataReader *reader, ID *id)
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 write_drawing_array(GreasePencil &grease_pencil, BlendWriter *writer)
static void unique_node_name_ex(VectorSet< blender::StringRefNull > &names, const char *default_name, char *name)
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)
static std::string unique_layer_group_name(const GreasePencil &grease_pencil, blender::StringRefNull name)
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
void MEM_freeN(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
ccl_device_inline float cross(const float2 a, const float2 b)
ccl_device_inline float3 cos(float3 v)
GAttributeReader lookup(const void *owner, const StringRef attribute_id)
static const std::string ATTR_OPACITY
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 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< uint3 > triangles)
static const std::string ATTR_RADIUS
static int domain_num(const CurvesGeometry &curves, const AttrDomain domain)
static CustomData & domain_custom_data(CurvesGeometry &curves, const AttrDomain domain)
static const std::string ATTR_VERTEX_COLOR
static float4x2 get_local_to_stroke_matrix(const Span< float3 > positions, const float3 normal)
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)
static float4x3 expand_4x2_mat(float4x2 strokemat)
static const std::string ATTR_FILL_COLOR
void copy_drawing_array(Span< const GreasePencilDrawingBase * > src_drawings, MutableSpan< GreasePencilDrawingBase * > dst_drawings)
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)
static const std::string ATTR_RADIUS
Bounds< T > merge(const Bounds< T > &a, const Bounds< T > &b)
std::optional< Bounds< T > > min_max(const std::optional< Bounds< T > > &a, const T &b)
T length_squared(const VecBase< T, Size > &a)
T distance(const T &a, const T &b)
QuaternionBase< T > normalize_and_get_length(const QuaternionBase< T > &q, T &out_length)
CartesianBasis invert(const CartesianBasis &basis)
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)
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)
struct Material * material
struct BrushGpencilSettings * gpencil_settings
CurvesGeometryRuntimeHandle * runtime
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
GreasePencilModifierInfluenceData influence
struct GreasePencil * id_reference
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 MaterialGPencilStyle * gp_style
struct ModifierData * next
void(* modify_geometry_set)(ModifierData *md, const ModifierEvalContext *ctx, blender::bke::GeometrySet *geometry_set)
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