41#include "RNA_prototypes.hh"
54 : region_(®ion), view3d_(&
view3d)
56 layer_space_to_world_space_ = (layer !=
nullptr) ? layer->
to_world_space(eval_object) :
57 eval_object.object_to_world();
58 world_space_to_layer_space_ =
math::invert(layer_space_to_world_space_);
61 case GP_LOCKAXIS_VIEW:
62 plane_ = DrawingPlacementPlane::View;
65 plane_ = DrawingPlacementPlane::Front;
66 placement_normal_ = float3(0, 1, 0);
69 plane_ = DrawingPlacementPlane::Side;
70 placement_normal_ = float3(1, 0, 0);
73 plane_ = DrawingPlacementPlane::Top;
74 placement_normal_ = float3(0, 0, 1);
76 case GP_LOCKAXIS_CURSOR: {
77 plane_ = DrawingPlacementPlane::Cursor;
78 placement_normal_ = scene.cursor.matrix<float3x3>() * float3(0, 0, 1);
86 placement_normal_ = math::transform_direction(math::transpose(world_space_to_layer_space_),
91 const char align_flag = scene.toolsettings->gpencil_v3d_align;
95 surface_offset_ = 0.0f;
96 placement_loc_ =
float3(scene.cursor.location);
101 use_project_only_selected_ =
true;
103 surface_offset_ = scene.toolsettings->gpencil_surface_offset;
105 placement_loc_ = layer_space_to_world_space_.location();
109 surface_offset_ = 0.0f;
111 placement_loc_ = layer_space_to_world_space_.location();
115 surface_offset_ = 0.0f;
116 placement_loc_ = layer_space_to_world_space_.location();
121 surface_offset_ = 0.0f;
122 placement_loc_ =
float3(0.0f);
126 placement_plane_ =
float4();
134 const Object &eval_object,
137 const float surface_offset,
141 depth_cache_(view_depths),
142 surface_offset_(surface_offset)
144 layer_space_to_world_space_ = (layer !=
nullptr) ? layer->
to_world_space(eval_object) :
145 eval_object.object_to_world();
146 world_space_to_layer_space_ =
math::invert(layer_space_to_world_space_);
154 placement_normal_ =
float3(0, 1, 0);
158 placement_normal_ =
float3(1, 0, 0);
162 placement_normal_ =
float3(0, 0, 1);
181 switch (reproject_mode) {
184 surface_offset_ = 0.0f;
189 surface_offset_ = 0.0f;
190 placement_loc_ = layer_space_to_world_space_.location();
194 placement_loc_ = layer_space_to_world_space_.location();
198 surface_offset_ = 0.0f;
199 placement_loc_ = layer_space_to_world_space_.location();
204 placement_plane_ =
float4();
211 region_ = other.region_;
212 view3d_ = other.view3d_;
214 depth_ = other.depth_;
215 plane_ = other.plane_;
217 if (other.depth_cache_ !=
nullptr) {
221 use_project_only_selected_ = other.use_project_only_selected_;
223 surface_offset_ = other.surface_offset_;
225 placement_loc_ = other.placement_loc_;
226 placement_normal_ = other.placement_normal_;
227 placement_plane_ = other.placement_plane_;
229 layer_space_to_world_space_ = other.layer_space_to_world_space_;
230 world_space_to_layer_space_ = other.world_space_to_layer_space_;
235 region_ = other.region_;
236 view3d_ = other.view3d_;
238 depth_ = other.depth_;
239 plane_ = other.plane_;
241 std::swap(depth_cache_, other.depth_cache_);
242 use_project_only_selected_ = other.use_project_only_selected_;
244 surface_offset_ = other.surface_offset_;
246 placement_loc_ = other.placement_loc_;
247 placement_normal_ = other.placement_normal_;
248 placement_plane_ = other.placement_plane_;
250 layer_space_to_world_space_ = other.layer_space_to_world_space_;
251 world_space_to_layer_space_ = other.world_space_to_layer_space_;
256 if (
this == &other) {
259 std::destroy_at(
this);
266 if (
this == &other) {
269 std::destroy_at(
this);
276 if (depth_cache_ !=
nullptr) {
293 const short previous_gp_flag =
view3d->gp_flag;
297 if (use_project_only_selected_) {
312 view3d->gp_flag = previous_gp_flag;
317 std::optional<float> depth =
get_depth(co);
326 proj_point -= view_normal * surface_offset_;
341float3 DrawingPlacement::try_project_depth(
const float2 co)
const
343 if (std::optional<float3> proj_point = this->
project_depth(co)) {
358 proj_point = this->try_project_depth(co);
362 if (placement_plane_) {
374 [[maybe_unused]]
bool clipped_unused;
375 return this->
project(co, clipped_unused);
383 proj_point = this->try_project_depth(co);
386 if (placement_plane_) {
399 for (const int i : range) {
400 dst[i] = this->project(src[i]);
424 proj_point = this->try_project_depth(co);
438 if (placement_plane_) {
439 plane = *placement_plane_;
447 proj_point = world_pos + ray_no * lambda;
459 for (const int i : range) {
460 dst[i] = this->reproject(src[i]);
467 return layer_space_to_world_space_;
471 const int frame_number,
472 const int active_frame,
476 if (!use_multi_frame_falloff || !frame_bounds.has_value() || falloff_curve ==
nullptr) {
480 const int min_frame = frame_bounds->min;
481 const int max_frame = frame_bounds->max;
484 if (frame_number < active_frame) {
485 const float frame_factor = 0.5f *
float(frame_number - min_frame) / (active_frame - min_frame);
489 if (frame_number > active_frame) {
490 const float frame_factor = 0.5f *
float(frame_number - active_frame) /
491 (max_frame - active_frame);
502 if (!layer.is_editable()) {
506 for (
const auto [frame_number, frame] : layer.
frames().
items()) {
507 if (frame.is_selected()) {
508 frame_numbers.
append(frame_number);
516 const int current_frame)
518 std::optional<int> current_start_frame = layer.
start_frame_at(current_frame);
519 if (!current_start_frame && frame_bounds) {
520 return math::clamp(current_frame, frame_bounds->min, frame_bounds->max);
522 return *current_start_frame;
527 const int frame_number,
528 const int frame_index,
529 const int current_frame,
530 const int current_frame_index,
531 const int last_frame,
532 const int last_frame_index,
533 const bool use_multi_frame_editing,
534 const bool do_onion_skinning,
535 const bool is_before_first,
538 if (use_multi_frame_editing) {
539 if (frame.is_selected()) {
540 if (do_onion_skinning) {
541 return (frame_number < current_frame) ? -1 : 1;
547 if (do_onion_skinning && layer.use_onion_skinning()) {
549 if (onion_settings.
filter != 0 && (onion_settings.
filter & (1 << frame.
type)) == 0) {
559 delta = frame_number - current_frame;
562 delta = frame_index - current_frame_index;
565 if (is_before_first) {
578 shift = last_frame_index;
580 delta += (delta < 0) ? (shift + 1) : -(shift + 1);
599 const int current_frame,
600 const bool use_multi_frame_editing,
601 const bool do_onion_skinning)
610 const int last_frame = sorted_keys.
last();
612 const bool is_before_first = (current_frame < sorted_keys.
first());
613 const std::optional<int> current_start_frame = layer.
start_frame_at(current_frame);
614 for (
const int frame_i : sorted_keys.
index_range()) {
615 const int frame_number = sorted_keys[frame_i];
616 if (current_start_frame && *current_start_frame == frame_number) {
628 use_multi_frame_editing,
632 if (!frame_id.has_value()) {
637 frame_numbers.
append({frame_number, *frame_id});
640 frame_numbers.
append({current_frame, 0});
642 return frame_numbers.
as_span();
647 const int current_frame,
648 const bool use_multi_frame_editing)
653 if (use_multi_frame_editing) {
654 const Drawing *current_drawing = grease_pencil.get_drawing_at(layer, current_frame);
655 for (
const auto [frame_number, frame] : layer.
frames().
items()) {
656 if (!frame.is_selected()) {
659 frame_numbers.
append(frame_number);
660 added_drawings.
add(grease_pencil.get_drawing_at(layer, frame_number));
662 if (added_drawings.
contains(current_drawing)) {
663 return frame_numbers.
as_span();
667 frame_numbers.
append(current_frame);
668 return frame_numbers.
as_span();
675 const int current_frame = scene.
r.
cfra;
677 const bool use_multi_frame_editing = (toolsettings->
gpencil_flags &
683 const Layer &layer = *layers[layer_i];
684 if (!layer.is_editable()) {
688 grease_pencil, layer, current_frame, use_multi_frame_editing);
689 for (
const int frame_number : frame_numbers) {
690 if (
Drawing *drawing = grease_pencil.get_editable_drawing_at(layer, frame_number)) {
691 editable_drawings.
append({*drawing, layer_i, frame_number, 1.0f});
696 return editable_drawings;
703 const int current_frame = scene.
r.
cfra;
705 const bool use_multi_frame_editing = (toolsettings->
gpencil_flags &
707 const bool use_multi_frame_falloff = use_multi_frame_editing &&
710 if (use_multi_frame_falloff) {
717 const Layer &layer = *layers[layer_i];
718 if (!layer.is_editable()) {
724 grease_pencil, layer, current_frame, use_multi_frame_editing);
725 for (
const int frame_number : frame_numbers) {
726 if (
Drawing *drawing = grease_pencil.get_editable_drawing_at(layer, frame_number)) {
732 editable_drawings.
append({*drawing, layer_i, frame_number, falloff});
737 return editable_drawings;
744 int current_frame = scene.
r.
cfra;
746 const bool use_multi_frame_editing = (toolsettings->
gpencil_flags &
748 const bool use_multi_frame_falloff = use_multi_frame_editing &&
751 if (use_multi_frame_falloff) {
758 if (use_multi_frame_editing) {
760 const Layer &layer = *layers[layer_i];
761 if (!layer.is_editable()) {
764 for (
const auto [frame_number, frame] : layer.
frames().
items()) {
765 if (frame_number != current_frame && frame.is_selected()) {
766 selected_frames.
add(frame_number);
771 selected_frames.
add(current_frame);
777 const Layer &layer = *layers[layer_i];
778 if (!layer.is_editable()) {
785 if (use_multi_frame_editing) {
786 for (
const auto [frame_number, frame] : layer.
frames().
items()) {
787 Drawing *drawing = grease_pencil.get_editable_drawing_at(layer, frame_number);
788 if (!frame.is_selected() || drawing ==
nullptr || added_drawings.
contains(drawing)) {
796 const int frame_group = selected_frames.
index_of(frame_number);
797 drawings_grouped_per_frame[frame_group].append({*drawing, layer_i, frame_number, falloff});
798 added_drawings.
add_new(drawing);
803 Drawing *current_drawing = grease_pencil.get_drawing_at(layer, current_frame);
804 if (current_drawing !=
nullptr && !added_drawings.
contains(current_drawing)) {
810 const int frame_group = selected_frames.
index_of(current_frame);
811 drawings_grouped_per_frame[frame_group].append(
812 {*current_drawing, layer_i, current_frame, falloff});
813 added_drawings.
add_new(current_drawing);
817 return drawings_grouped_per_frame;
826 const int current_frame = scene.
r.
cfra;
828 const bool use_multi_frame_editing = (toolsettings->
gpencil_flags &
830 const int layer_index = *grease_pencil.get_layer_index(layer);
834 grease_pencil, layer, current_frame, use_multi_frame_editing);
835 for (
const int frame_number : frame_numbers) {
836 if (
Drawing *drawing = grease_pencil.get_editable_drawing_at(layer, frame_number)) {
837 editable_drawings.
append({*drawing, layer_index, frame_number, 1.0f});
841 return editable_drawings;
850 const int current_frame = scene.
r.
cfra;
852 const bool use_multi_frame_editing = (toolsettings->
gpencil_flags &
854 const bool use_multi_frame_falloff = use_multi_frame_editing &&
857 const int layer_index = *grease_pencil.get_layer_index(layer);
858 std::optional<Bounds<int>> frame_bounds;
859 if (use_multi_frame_falloff) {
868 grease_pencil, layer, current_frame, use_multi_frame_editing);
869 for (
const int frame_number : frame_numbers) {
870 if (
Drawing *drawing = grease_pencil.get_editable_drawing_at(layer, frame_number)) {
876 editable_drawings.
append({*drawing, layer_index, frame_number, falloff});
880 return editable_drawings;
885 const bool do_onion_skinning)
890 const bool use_multi_frame_editing = (toolsettings->
gpencil_flags &
896 const Layer &layer = *layers[layer_i];
897 if (!layer.is_visible()) {
901 grease_pencil, layer, current_frame, use_multi_frame_editing, do_onion_skinning);
902 for (
const auto &[frame_number, onion_id] : frames) {
903 if (
const Drawing *drawing = grease_pencil.get_drawing_at(layer, frame_number)) {
904 visible_drawings.
append({*drawing, layer_i, frame_number, onion_id});
909 return visible_drawings;
916 for (
const int mat_i :
IndexRange(
object.totcol)) {
919 if (material !=
nullptr && material->
gp_style !=
nullptr &&
923 locked_material_indices.
add_new(mat_i);
926 return locked_material_indices;
933 for (
const int mat_i :
IndexRange(
object.totcol)) {
935 if (material !=
nullptr && material->
gp_style !=
nullptr &&
938 hidden_material_indices.
add_new(mat_i);
941 return hidden_material_indices;
948 for (
const int mat_i :
IndexRange(
object.totcol)) {
950 if (material !=
nullptr && material->
gp_style !=
nullptr &&
953 fill_material_indices.
add_new(mat_i);
956 return fill_material_indices;
968 if (
object.totcol == 0) {
976 if (layer.ignore_locked_materials()) {
982 if (locked_material_indices.
is_empty()) {
991 if (locked_material_indices.
contains(0)) {
999 return !locked_material_indices.
contains(materials[curve_i]);
1010 object, drawing, layer_index, memory);
1024 if (editable_strokes.
contains(0) && fill_material_indices.contains(0)) {
1025 return curves_range;
1031 const int material_index = materials[curve_i];
1032 return fill_material_indices.contains(material_index);
1056 if (locked_material_indices.
contains(0)) {
1059 return curves_range;
1064 const int material_index = materials[curve_i];
1065 if (material_index == mat_i) {
1066 return !locked_material_indices.
contains(material_index);
1080 if (
object.totcol == 0) {
1088 if (layer.ignore_locked_materials()) {
1094 if (locked_material_indices.
is_empty()) {
1095 return points_range;
1104 if (locked_material_indices.
contains(0)) {
1107 return points_range;
1112 return !locked_material_indices.
contains(materials[point_i]);
1141 if (hidden_material_indices.
is_empty()) {
1154 const int material_index = materials[curve_i];
1155 return !hidden_material_indices.
contains(material_index);
1166 if (hidden_material_indices.
is_empty()) {
1177 if (
const std::optional<int> single_material = materials.
get_if_single()) {
1178 if (!hidden_material_indices.
contains(*single_material)) {
1179 return points_range;
1187 const int material_index = materials[point_i];
1188 return !hidden_material_indices.
contains(material_index);
1204 const std::array<int, CURVE_TYPES_NUM> type_counts =
curves.curve_type_counts();
1210 object, drawing, memory);
1226 object, drawing, memory);
1233 const int handle_display,
1247 object, drawing, memory);
1250 return visible_bezier_strokes;
1260 const int layer_index,
1261 const int handle_display,
1289 object, drawing, layer_index, memory);
1293 const bool is_selected = selected_point[point_i] || selected_left[point_i] ||
1294 selected_right[point_i];
1296 return is_selected && is_bezier;
1304 const int layer_index,
1306 const int handle_display,
1311 object, drawing, handle_display, memory);
1315 object, drawing, layer_index, handle_display, memory);
1329 object, drawing, layer_index, memory);
1344 object, drawing, layer_index, memory);
1371 object, drawing, layer_index, memory);
1375 object, drawing, layer_index, memory);
1390 curves, handle_display, memory);
1398 for (
const Layer *layer : grease_pencil.layers()) {
1399 if (layer->is_editable()) {
1410 const bool keep_caps)
1416 int dst_points_num = 0;
1418 dst_points_num += src_transfer_data.size();
1420 if (dst_points_num == 0) {
1432 Array<int> src_pivot_point(src_curves_num, -1);
1433 Array<int> dst_interm_curves_offsets(src_curves_num + 1, 0);
1436 const IndexRange src_points = src_points_by_curve[src_curve];
1438 for (
const int src_point : src_points) {
1439 for (
const PointTransferData &dst_point_transfer : src_to_dst_points[src_point]) {
1440 if (dst_point_transfer.is_src_point) {
1441 dst_transfer_data[++dst_point] = dst_point_transfer;
1446 dst_transfer_data[++dst_point] = dst_point_transfer;
1451 if (src_cyclic[src_curve] && dst_point_transfer.is_cut) {
1452 src_pivot_point[src_curve] = dst_point;
1460 dst_interm_curves_offsets[src_curve + 1] = dst_point + 1;
1466 for (const int src_curve : src_curves) {
1467 const int pivot_point = src_pivot_point[src_curve];
1469 if (pivot_point == -1) {
1471 src_now_cyclic[src_curve] = src_cyclic[src_curve];
1479 src_now_cyclic[src_curve] = false;
1481 const int dst_interm_first = dst_interm_curves_offsets[src_curve];
1482 const int dst_interm_last = dst_interm_curves_offsets[src_curve + 1];
1483 std::rotate(dst_transfer_data.begin() + dst_interm_first,
1484 dst_transfer_data.begin() + pivot_point,
1485 dst_transfer_data.begin() + dst_interm_last);
1492 dst_curves_offset.
append(0);
1493 for (
int src_curve : src.curves_range()) {
1494 const IndexRange dst_points(dst_interm_curves_offsets[src_curve],
1495 dst_interm_curves_offsets[src_curve + 1] -
1496 dst_interm_curves_offsets[src_curve]);
1497 int length_of_current = 0;
1499 for (
int dst_point : dst_points) {
1501 if ((length_of_current > 0) && dst_transfer_data[dst_point].is_cut) {
1503 dst_curves_offset.
append(dst_point);
1504 dst_to_src_curve.
append(src_curve);
1505 length_of_current = 0;
1507 ++length_of_current;
1510 if (length_of_current != 0) {
1512 dst_curves_offset.
append(dst_points.one_after_last());
1513 dst_to_src_curve.
append(src_curve);
1516 const int dst_curves_num = dst_curves_offset.
size() - 1;
1517 if (dst_curves_num == 0) {
1519 return dst_transfer_data;
1523 dst.resize(dst_points_num, dst_curves_num);
1525 const OffsetIndices<int> dst_points_by_curve = dst.points_by_curve();
1532 const bke::AttributeAccessor src_attributes = src.attributes();
1533 bke::MutableAttributeAccessor dst_attributes = dst.attributes_for_write();
1542 if (src_cyclic.get_if_single().value_or(
true)) {
1544 src_now_cyclic.as_span(), dst_to_src_curve.as_span(), dst.cyclic_for_write());
1547 dst.update_curve_types();
1551 bke::SpanAttributeWriter<int8_t> dst_start_caps =
1553 bke::SpanAttributeWriter<int8_t> dst_end_caps =
1557 for (const int dst_curve : dst_curves) {
1558 const IndexRange dst_curve_points = dst_points_by_curve[dst_curve];
1559 const PointTransferData &start_point_transfer =
1560 dst_transfer_data[dst_curve_points.first()];
1561 const PointTransferData &end_point_transfer = dst_transfer_data[dst_curve_points.last()];
1563 if (dst_start_caps && start_point_transfer.is_cut) {
1564 dst_start_caps.span[dst_curve] = GP_STROKE_CAP_TYPE_FLAT;
1568 if (dst_end_caps && !end_point_transfer.is_src_end_point()) {
1569 dst_end_caps.span[dst_curve] = GP_STROKE_CAP_TYPE_FLAT;
1575 dst_end_caps.finish();
1583 using T = decltype(dummy);
1584 auto src_attr = attribute.src.typed<T>();
1585 auto dst_attr = attribute.dst.span.typed<T>();
1587 threading::parallel_for(dst.points_range(), 4096, [&](const IndexRange dst_points) {
1588 for (const int dst_point : dst_points) {
1589 const PointTransferData &point_transfer = dst_transfer_data[dst_point];
1590 if (point_transfer.is_src_point) {
1591 dst_attr[dst_point] = src_attr[point_transfer.src_point];
1594 dst_attr[dst_point] = bke::attribute_math::mix2<T>(
1595 point_transfer.factor,
1596 src_attr[point_transfer.src_point],
1597 src_attr[point_transfer.src_next_point]);
1602 attribute.dst.finish();
1606 return dst_transfer_data;
1613 const float pixel_radius)
1636 rv3d, region, location, to_world,
float(
brush->size) / 2.0f);
1638 return brush->unprojected_size / 2.0f;
1644 const float pressure,
1660 float opacity =
brush->alpha;
1669 const bool use_duplicate_previous_key)
1678 if (!grease_pencil.has_active_layer()) {
1685 if (
brush ==
nullptr) {
1691 if (!active_layer.is_editable()) {
1697 bool inserted_keyframe =
false;
1699 *scene, grease_pencil, active_layer, use_duplicate_previous_key, inserted_keyframe))
1704 if (inserted_keyframe) {
1726 u_dir =
float3(1.0f, 0.0f, 0.0f);
1727 v_dir =
float3(0.0f, 0.0f, 1.0f);
1730 u_dir =
float3(0.0f, 1.0f, 0.0f);
1731 v_dir =
float3(0.0f, 0.0f, 1.0f);
1734 u_dir =
float3(1.0f, 0.0f, 0.0f);
1735 v_dir =
float3(0.0f, 1.0f, 0.0f);
1739 u_dir = mat *
float3(1.0f, 0.0f, 0.0f);
1740 v_dir = mat *
float3(0.0f, 1.0f, 0.0f);
1755 if (grease_pencil ==
nullptr) {
1758 grease_pencil =
static_cast<GreasePencil *
>(
object->data);
1761 return grease_pencil;
1767 const int num_old_points =
curves.points_num();
1769 curves.offsets_for_write().last(1) = num_old_points;
1775 offsets.
first() = 0;
1778 for (
int i =
curves.curves_num() - 2;
i >= 0;
i--) {
1779 offsets[
i + 1] = offsets[
i] + 1;
1789 using T = decltype(dummy);
1790 MutableSpan<T> span_data = attribute_data.typed<T>();
1793 for (int i = span_data.size() - 2; i >= 0; i--) {
1794 span_data[i + 1] = span_data[i];
1805 const int curve_index = at_end ?
curves.curves_range().last() : 0;
1806 const int current_points_num = points_by_curve[curve_index].
size();
1807 if (new_points_num == current_points_num) {
1812 const int diff_points_num = new_points_num - current_points_num;
1814 curves.offsets_for_write().last() =
curves.points_num();
1818 if (current_points_num < new_points_num) {
1819 const int last_active_point = points_by_curve[0].last();
1821 const int added_points_num = new_points_num - current_points_num;
1825 for (
const int src_curve :
curves.curves_range().drop_front(1)) {
1826 offsets[src_curve] = offsets[src_curve] + added_points_num;
1840 using T = decltype(dummy);
1841 MutableSpan<T> span_data = attribute_data.typed<T>();
1844 for (int i = span_data.size() - 1 - added_points_num; i >= last_active_point; i--) {
1845 span_data[i + added_points_num] = span_data[i];
1853 const int removed_points_num = current_points_num - new_points_num;
1864 using T = decltype(dummy);
1865 MutableSpan<T> span_data = attribute_data.typed<T>();
1868 span_data.index_range().drop_front(new_points_num).drop_back(removed_points_num))
1870 span_data[i] = span_data[i + removed_points_num];
1876 curves.resize(curves.points_num() - removed_points_num, curves.curves_num());
1877 MutableSpan<int> offsets = curves.offsets_for_write();
1878 for (
const int src_curve : curves.curves_range().drop_front(1)) {
1879 offsets[src_curve] = offsets[src_curve] - removed_points_num;
1881 offsets.
last() = curves.points_num();
1886 const int eval_frame,
1890 using namespace bke;
1895 const Layer &layer = orig_grease_pencil.layer(layer_i);
1896 orig_layers_to_apply.
add(&layer);
1900 const int old_layers_num = eval_grease_pencil.layers().size();
1903 for (
const int layer_i :
IndexRange(old_layers_num)) {
1904 const Layer &layer = eval_grease_pencil.layer(layer_i);
1906 layer.name(), [&]() { return layers_map.append_and_get_index_as(); });
1907 layers_map[new_layer_index].
append(layer_i);
1910 eval_grease_pencil, layers_map, {});
1917 for (
Layer *layer : orig_grease_pencil.layers_for_write()) {
1919 if (layer->is_visible()) {
1920 orig_layers_to_clear.
add(layer);
1923 for (
const TreeNode *node_eval : merged_layers_grease_pencil.nodes()) {
1925 TreeNode *node_orig = orig_grease_pencil.find_node_by_name(node_eval->name());
1928 if (!node_eval->is_layer()) {
1932 const bool has_valid_orig_layer = (node_orig !=
nullptr && node_orig->
is_layer());
1933 if (!has_valid_orig_layer) {
1935 Layer &layer_orig = orig_grease_pencil.add_layer(node_eval->name(),
true);
1936 orig_layers_to_apply.
add(&layer_orig);
1938 orig_grease_pencil.insert_frame(layer_orig, eval_frame);
1939 node_orig = &layer_orig.
as_node();
1944 orig_layers_to_clear.
remove(&layer_orig);
1946 if (orig_layers_to_apply.
contains(&layer_orig)) {
1948 const Layer &layer_eval = node_eval->as_layer();
1953 eval_to_orig_layer_map.add_new(&layer_eval, &layer_orig);
1959 for (
Layer *layer_orig : orig_layers_to_clear) {
1961 Drawing *drawing_orig = orig_grease_pencil.insert_frame(*layer_orig, eval_frame);
1962 if (drawing_orig ==
nullptr) {
1964 drawing_orig = orig_grease_pencil.get_drawing_at(*layer_orig, eval_frame);
1975 orig_vgroup_names.
add(dg->name);
1982 for (
auto [layer_eval, layer_orig] : eval_to_orig_layer_map.items()) {
1983 Drawing *drawing_eval = merged_layers_grease_pencil.get_drawing_at(*layer_eval, eval_frame);
1984 Drawing *drawing_orig = orig_grease_pencil.get_drawing_at(*layer_orig, eval_frame);
1986 if (drawing_orig && drawing_eval) {
1991 if (!orig_vgroup_names.
contains(dg->name)) {
1992 new_vgroup_names.
add(dg->name);
2001 all_updated_drawings.
add_new(drawing_orig);
2006 for (
StringRef new_vgroup_name : new_vgroup_names) {
2008 new_vgroup_name.copy_utf8_truncated(dst->
name);
2016 for (
Material *eval_material : eval_materials) {
2017 if (!eval_material) {
2030 for (
const int mat_i : orig_material_indices) {
2032 const int map_index = original_materials.
index_of_try(material);
2033 if (map_index != -1) {
2034 material_indices_map[mat_i] = map_index;
2039 if (!material_indices_map.
is_empty() &&
2047 if (all_updated_drawings.
contains(&drawing)) {
2052 if (!attributes.
contains(
"material_index")) {
2057 for (
int &material_index : material_indices.
span) {
2059 material_index = material_indices_map[material_index];
2062 material_indices.
finish();
2068 for (
const int layer_eval_i : merged_layers_grease_pencil.layers().index_range()) {
2069 const Layer *layer_eval = &merged_layers_grease_pencil.layer(layer_eval_i);
2070 if (eval_to_orig_layer_map.contains(layer_eval)) {
2071 const Layer *layer_orig = eval_to_orig_layer_map.lookup(layer_eval);
2072 const int layer_orig_index = *orig_grease_pencil.get_layer_index(*layer_orig);
2073 eval_to_orig_layer_indices_map.
add(layer_eval_i, layer_orig_index);
2095 using T = decltype(dummy);
2096 Span<T> src_span = src.typed<T>();
2097 MutableSpan<T> dst_span = dst.span.typed<T>();
2098 for (const auto [src_i, dst_i] : eval_to_orig_layer_indices_map.items()) {
2099 dst_span[dst_i] = src_span[src_i];
2106 BKE_id_free(
nullptr, &merged_layers_grease_pencil);
2111 if (!
curves.attributes().contains(
".is_fill_guide")) {
2121 curves.remove_curves(fill_guides, {});
2123 curves.attributes_for_write().remove(
".is_fill_guide");
bool BKE_brush_use_alpha_pressure(const Brush *brush)
bool BKE_brush_use_size_pressure(const Brush *brush)
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Low-level operations for curves.
Low-level operations for grease pencil.
void BKE_id_free(Main *bmain, void *idv)
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Paint * BKE_paint_get_active_from_context(const bContext *C)
void BKE_report(ReportList *reports, eReportType type, const char *message)
float BKE_scene_ctime_get(const Scene *scene)
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
bool isect_ray_plane_v3(const float ray_origin[3], const float ray_direction[3], const float plane[4], float *r_lambda, bool clip)
T * DEG_get_original(T *id)
@ GP_ONION_SKINNING_MODE_ABSOLUTE
@ GP_ONION_SKINNING_MODE_SELECTED
@ GP_ONION_SKINNING_MODE_RELATIVE
@ GP_ONION_SKINNING_SHOW_LOOP
Object is a sort of wrapper for general info.
@ GP_SCULPT_SETT_FLAG_FRAME_FALLOFF
@ GP_PROJECT_DEPTH_STROKE
@ GP_PROJECT_DEPTH_ONLY_SELECTED
@ GP_USE_MULTI_FRAME_EDITING
@ V3D_GP_FORCE_STROKE_ORDER_3D
bool ED_view3d_depth_read_cached(const ViewDepths *vd, const int mval[2], int margin, float *r_depth)
void ED_view3d_win_to_delta(const ARegion *region, const float xy_delta[2], float zfac, float r_out[3], bool precise=false)
void ED_view3d_depth_override(Depsgraph *depsgraph, ARegion *region, View3D *v3d, Object *obact, eV3DDepthOverrideMode mode, bool use_overlay, ViewDepths **r_depths)
void ED_view3d_win_to_3d(const View3D *v3d, const ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
bool ED_view3d_unproject_v3(const ARegion *region, float regionx, float regiony, float regionz, float world[3])
void ED_view3d_win_to_3d_with_shift(const View3D *v3d, const ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3])
void ED_view3d_depths_free(ViewDepths *depths)
@ V3D_DEPTH_SELECTED_ONLY
bool ED_view3d_win_to_3d_on_plane(const ARegion *region, const float plane[4], const float mval[2], bool do_clip, float r_out[3])
void ED_view3d_win_to_vector(const ARegion *region, const float mval[2], float r_out[3])
bool ED_view3d_depth_unproject_v3(const ARegion *region, const int mval[2], double depth, float r_location_world[3])
eV3DProjStatus ED_view3d_project_float_global(const ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
switch((BMIterType) itype)
BPy_StructRNA * depsgraph
const Value & lookup(const Key &key) const
ItemIterator items() const &
constexpr T & last(const int64_t n=0) const
IndexRange index_range() const
const CPPType & type() const
const CPPType & type() const
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_ranges(OffsetIndices< T > offsets, const IndexMask &mask, IndexMaskMemory &memory)
static IndexMask from_intersection(const IndexMask &mask_a, const IndexMask &mask_b, IndexMaskMemory &memory)
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
constexpr int64_t last(const int64_t n=0) const
constexpr bool contains(int64_t value) const
bool add(const Key &key, const Value &value)
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
constexpr T & first() const
constexpr T & last(const int64_t n=0) const
bool contains(const Key &key) const
void add_new(const Key &key)
bool remove(const Key &key)
constexpr const T & first() const
constexpr const T & last(const int64_t n=0) const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
std::optional< T > get_if_single() const
int64_t index_of_try(const Key &key) const
int64_t index_of(const Key &key) const
bool contains(const Key &key) const
void add_new(const Key &key)
void append(const T &value)
Span< T > as_span() const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
bool contains(StringRef attribute_id) const
GAttributeReader lookup(const StringRef attribute_id) const
GAttributeReader get() const
OffsetIndices< int > points_by_curve() const
IndexRange curves_range() const
MutableAttributeAccessor attributes_for_write()
IndexRange points_range() const
void resize(int points_num, int curves_num)
VArray< bool > cyclic() const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, AttrType data_type)
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
void tag_topology_changed()
int sorted_keys_index_at(int frame_number) const
float4x4 to_world_space(const Object &object) const
void set_local_transform(const float4x4 &transform)
const Map< FramesMapKeyT, GreasePencilFrame > & frames() const
float4x4 local_transform() const
const TreeNode & as_node() const
std::optional< int > start_frame_at(int frame_number) const
Span< FramesMapKeyT > sorted_keys() const
const Layer & as_layer() const
DrawingPlacement & operator=(const DrawingPlacement &other)
bool use_project_to_surface() const
std::optional< float > get_depth(float2 co) const
void cache_viewport_depths(Depsgraph *depsgraph, ARegion *region, View3D *view3d)
float3 place(float2 co, float depth) const
bool use_project_to_stroke() const
std::optional< float3 > project_depth(float2 co) const
float4x4 to_world_space() const
float3 project_with_shift(float2 co) const
DrawingPlacement()=default
float3 reproject(float3 pos) const
float3 project(float2 co, bool &clipped) const
bool contains(int64_t query_index) const
void foreach_index(Fn &&fn) const
void * MEM_callocN(size_t len, const char *str)
void * MEM_dupallocN(const void *vmemh)
void copy(const GVArray &src, GMutableSpan dst, int64_t grain_size=4096)
bool indices_are_range(Span< int > indices, IndexRange range)
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
IndexMask indices_for_type(const VArray< int8_t > &types, const std::array< int, CURVE_TYPES_NUM > &type_counts, const CurveType type, const IndexMask &selection, IndexMaskMemory &memory)
bool attribute_name_is_anonymous(const StringRef name)
Vector< AttributeTransferData > retrieve_attributes_for_transfer(const AttributeAccessor src_attributes, MutableAttributeAccessor dst_attributes, AttrDomainMask domain_mask, const AttributeFilter &attribute_filter={})
auto attribute_filter_from_skip_ref(const Span< StringRef > skip)
void gather_attributes(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
std::optional< Bounds< T > > min_max(const std::optional< Bounds< T > > &a, const T &b)
IndexMask retrieve_all_selected_points(const bke::CurvesGeometry &curves, const int handle_display, IndexMaskMemory &memory)
IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
IndexMask retrieve_editable_and_selected_elements(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, const bke::AttrDomain selection_domain, IndexMaskMemory &memory)
IndexMask retrieve_visible_bezier_handle_points(Object &object, const bke::greasepencil::Drawing &drawing, const int layer_index, const int handle_display, IndexMaskMemory &memory)
IndexMask retrieve_editable_and_selected_strokes(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
static Array< int > get_editable_frames_for_layer(const GreasePencil &grease_pencil, const bke::greasepencil::Layer &layer, const int current_frame, const bool use_multi_frame_editing)
void resize_single_curve(bke::CurvesGeometry &curves, const bool at_end, const int new_points_num)
static float get_frame_falloff(const bool use_multi_frame_falloff, const int frame_number, const int active_frame, const std::optional< Bounds< int > > frame_bounds, const CurveMapping *falloff_curve)
static std::optional< int > get_frame_id(const bke::greasepencil::Layer &layer, const GreasePencilFrame &frame, const int frame_number, const int frame_index, const int current_frame, const int current_frame_index, const int last_frame, const int last_frame_index, const bool use_multi_frame_editing, const bool do_onion_skinning, const bool is_before_first, const GreasePencilOnionSkinningSettings onion_settings)
IndexMask retrieve_editable_points(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
IndexMask retrieve_visible_bezier_handle_strokes(Object &object, const bke::greasepencil::Drawing &drawing, const int handle_display, IndexMaskMemory &memory)
bool ensure_active_keyframe(const Scene &scene, GreasePencil &grease_pencil, bke::greasepencil::Layer &layer, const bool duplicate_previous_key, bool &r_inserted_keyframe)
GreasePencil * from_context(bContext &C)
IndexMask retrieve_editable_and_all_selected_points(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, int handle_display, IndexMaskMemory &memory)
IndexMask retrieve_editable_fill_strokes(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
float opacity_from_input_sample(const float pressure, const Brush *brush, const BrushGpencilSettings *settings)
IndexMask retrieve_editable_elements(Object &object, const MutableDrawingInfo &info, const bke::AttrDomain selection_domain, IndexMaskMemory &memory)
IndexMask retrieve_visible_bezier_strokes(Object &object, const bke::greasepencil::Drawing &drawing, IndexMaskMemory &memory)
void add_single_curve(bke::CurvesGeometry &curves, const bool at_end)
bke::CurvesGeometry fill_strokes(const ViewContext &view_context, const Brush &brush, const Scene &scene, const bke::greasepencil::Layer &layer, const VArray< bool > &boundary_layers, Span< DrawingInfo > src_drawings, bool invert, const std::optional< float > alpha_threshold, const float2 &fill_point, const ExtensionData &extensions, FillToolFitMethod fit_method, int stroke_material_index, bool keep_images)
IndexMask retrieve_visible_points(Object &object, const bke::greasepencil::Drawing &drawing, IndexMaskMemory &memory)
Vector< DrawingInfo > retrieve_visible_drawings(const Scene &scene, const GreasePencil &grease_pencil, const bool do_onion_skinning)
IndexMask retrieve_editable_strokes_by_material(Object &object, const bke::greasepencil::Drawing &drawing, const int mat_i, IndexMaskMemory &memory)
IndexMask retrieve_editable_and_selected_fill_strokes(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
bool has_editable_layer(const GreasePencil &grease_pencil)
static float pixel_radius_to_world_space_radius(const RegionView3D *rv3d, const ARegion *region, const float3 center, const float4x4 to_world, const float pixel_radius)
IndexMask retrieve_visible_bezier_points(Object &object, const bke::greasepencil::Drawing &drawing, IndexMaskMemory &memory)
static float brush_radius_at_location(const RegionView3D *rv3d, const ARegion *region, const Brush *brush, const float3 location, const float4x4 to_world)
static Array< std::pair< int, int > > get_visible_frames_for_layer(const GreasePencil &grease_pencil, const bke::greasepencil::Layer &layer, const int current_frame, const bool use_multi_frame_editing, const bool do_onion_skinning)
Array< PointTransferData > compute_topology_change(const bke::CurvesGeometry &src, bke::CurvesGeometry &dst, const Span< Vector< PointTransferData > > src_to_dst_points, const bool keep_caps)
IndexMask retrieve_visible_bezier_handle_elements(Object &object, const bke::greasepencil::Drawing &drawing, const int layer_index, const bke::AttrDomain selection_domain, const int handle_display, IndexMaskMemory &memory)
static VectorSet< int > get_locked_material_indices(Object &object)
IndexMask retrieve_editable_and_selected_points(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
static std::optional< Bounds< int > > get_selected_frame_number_bounds(const bke::greasepencil::Layer &layer)
static VectorSet< int > get_fill_material_indices(Object &object)
static VectorSet< int > get_hidden_material_indices(Object &object)
static int get_active_frame_for_falloff(const bke::greasepencil::Layer &layer, const std::optional< Bounds< int > > frame_bounds, const int current_frame)
Vector< MutableDrawingInfo > retrieve_editable_drawings_from_layer(const Scene &scene, GreasePencil &grease_pencil, const blender::bke::greasepencil::Layer &layer)
IndexMask retrieve_visible_strokes(Object &object, const bke::greasepencil::Drawing &drawing, IndexMaskMemory &memory)
Vector< MutableDrawingInfo > retrieve_editable_drawings_from_layer_with_falloff(const Scene &scene, GreasePencil &grease_pencil, const blender::bke::greasepencil::Layer &layer)
Vector< MutableDrawingInfo > retrieve_editable_drawings_with_falloff(const Scene &scene, GreasePencil &grease_pencil)
wmOperatorStatus grease_pencil_draw_operator_invoke(bContext *C, wmOperator *op, const bool use_duplicate_previous_key)
IndexMask retrieve_editable_strokes(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
bool remove_fill_guides(bke::CurvesGeometry &curves)
Vector< MutableDrawingInfo > retrieve_editable_drawings(const Scene &scene, GreasePencil &grease_pencil)
float radius_from_input_sample(const RegionView3D *rv3d, const ARegion *region, const Brush *brush, const float pressure, const float3 &location, const float4x4 &to_world, const BrushGpencilSettings *settings)
float4x2 calculate_texture_space(const Scene *scene, const ARegion *region, const float2 &mouse, const DrawingPlacement &placement)
Array< Vector< MutableDrawingInfo > > retrieve_editable_drawings_grouped_per_frame(const Scene &scene, GreasePencil &grease_pencil)
void apply_eval_grease_pencil_data(const GreasePencil &eval_grease_pencil, const int eval_frame, const IndexMask &orig_layers, GreasePencil &orig_grease_pencil)
GreasePencil * merge_layers(const GreasePencil &src_grease_pencil, Span< Vector< int > > layers_to_merge, const bke::AttributeFilter &attribute_filter)
constexpr double inv_sqrt3
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
T clamp(const T &a, const T &min, const T &max)
T safe_divide(const T &a, const T &b)
T length(const VecBase< T, Size > &a)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
CartesianBasis invert(const CartesianBasis &basis)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
MatBase< float, 4, 4 > float4x4
MatBase< float, 2, 4 > float2x4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
MatBase< float, 4, 2 > float4x2
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
float wrap(float value, float max, float min)
struct CurveMapping * curve_sensitivity
struct CurveMapping * curve_strength
ListBase vertex_group_names
struct CurveMapping * cur_falloff
int16_t num_frames_before
struct Material ** material_array
ListBase vertex_group_names
GreasePencilOnionSkinningSettings onion_skinning_settings
struct MaterialGPencilStyle * gp_style
struct ToolSettings * toolsettings
MutableVArraySpan< T > span
bke::greasepencil::Drawing & drawing
struct ReportList * reports
void WM_event_add_notifier(const bContext *C, uint type, void *reference)