97 if (!(smooth_position || smooth_radius || smooth_opacity)) {
102 bool changed =
false;
106 if (curves.points_num() == 0) {
118 const OffsetIndices points_by_curve = curves.points_by_curve();
120 const VArray<bool> point_selection = *curves.attributes().lookup_or_default<
bool>(
123 if (smooth_position) {
179 ot->
name =
"Smooth Stroke";
180 ot->
idname =
"GREASE_PENCIL_OT_stroke_smooth";
211 if (dist1 + dist2 > 0) {
212 float interpolated_val =
interpf(valB, valA, dist1 / (dist1 + dist2));
224 int64_t total_points_to_delete = 0;
226 if (!curve_selection.
contains(
true)) {
227 return total_points_to_delete;
230 const bool is_last_segment_selected = (curve_selection.
first() && curve_selection.
last());
235 for (const IndexRange range : selection_ranges.as_span().slice(range_of_ranges)) {
236 total_points_to_delete += ramer_douglas_peucker_simplify(
237 range.shift(points.start()), epsilon, dist_function, points_to_delete);
242 if (cyclic && points.size() > 2 && is_last_segment_selected) {
243 const float dist = dist_function(points.last(1), points.first(), points.last());
244 if (dist <= epsilon) {
245 points_to_delete[points.last()] =
true;
246 total_points_to_delete++;
250 return total_points_to_delete;
261 bool changed =
false;
265 if (curves.points_num() == 0) {
270 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
280 const auto dist_function_positions =
283 positions[index], positions[first_index], positions[last_index]);
284 return dist_position;
286 const auto dist_function_positions_and_radii =
289 positions[index], positions[first_index], positions[last_index]);
291 positions[first_index],
292 positions[last_index],
296 return math::max(dist_position, dist_radii);
301 const VArray<bool> selection = *curves.attributes().lookup_or_default<
bool>(
302 ".selection", bke::AttrDomain::Point,
true);
305 Array<bool> points_to_delete(curves.points_num(),
false);
306 bke::curves::fill_points(points_by_curve, strokes,
true, points_to_delete.as_mutable_span());
308 std::atomic<int64_t> total_points_to_delete = 0;
309 if (radii.is_single()) {
311 const IndexRange points = points_by_curve[curve_i];
315 dist_function_positions,
316 points_to_delete.as_mutable_span());
319 else if (radii.is_span()) {
321 const IndexRange points = points_by_curve[curve_i];
325 dist_function_positions_and_radii,
326 points_to_delete.as_mutable_span());
330 if (total_points_to_delete > 0) {
332 curves.remove_points(IndexMask::from_bools(points_to_delete, memory), {});
349 ot->
name =
"Simplify Stroke";
350 ot->
idname =
"GREASE_PENCIL_OT_stroke_simplify";
376 const int total_points = points_to_delete.
as_span().count(
false);
379 if (total_points == 0) {
383 int curr_dst_point_id = 0;
389 for (
const int curve_i : curves.curves_range()) {
390 const IndexRange points = points_by_curve[curve_i];
391 const Span<bool> curve_points_to_delete = points_to_delete.
as_span().slice(points);
392 const bool curve_cyclic = src_cyclic[curve_i];
395 const Vector<IndexRange> ranges_to_keep = array_utils::find_all_ranges(curve_points_to_delete,
402 const bool is_last_segment_selected = curve_cyclic && ranges_to_keep.
first().first() == 0 &&
403 ranges_to_keep.
last().last() == points.size() - 1;
404 const bool is_curve_self_joined = is_last_segment_selected && ranges_to_keep.
size() != 1;
405 const bool is_cyclic = ranges_to_keep.
size() == 1 && is_last_segment_selected;
410 const IndexRange range = ranges_to_keep[range_i];
413 for (
const int src_point : range.shift(points.first())) {
414 dst_to_src_point[curr_dst_point_id++] = src_point;
418 if (is_curve_self_joined && range_i == range_ids.
last()) {
420 for (
const int src_point : first_range.
shift(points.first())) {
421 dst_to_src_point[curr_dst_point_id++] = src_point;
427 dst_to_src_curve.
append(curve_i);
432 const int total_curves = dst_to_src_curve.
size();
439 array_utils::copy(dst_curve_counts.
as_span(), new_curve_offsets.
drop_back(1));
440 offset_indices::accumulate_counts_to_offsets(new_curve_offsets);
446 gather_attributes(src_attributes,
447 bke::AttrDomain::Curve,
448 bke::AttrDomain::Curve,
449 bke::attribute_filter_from_skip_ref({
"cyclic"}),
455 gather_attributes(src_attributes,
456 bke::AttrDomain::Point,
457 bke::AttrDomain::Point,
475 scene->toolsettings);
477 bool changed =
false;
481 const IndexMask elements = ed::greasepencil::retrieve_editable_and_selected_elements(
483 if (elements.is_empty()) {
488 if (selection_domain == bke::AttrDomain::Curve) {
491 else if (selection_domain == bke::AttrDomain::Point) {
508 ot->
idname =
"GREASE_PENCIL_OT_delete";
533 {
int(DissolveMode::POINTS),
"POINTS", 0,
"Dissolve",
"Dissolve selected points"},
534 {
int(DissolveMode::BETWEEN),
538 "Dissolve points between selected points"},
539 {
int(DissolveMode::UNSELECT),
543 "Dissolve all unselected points"},
544 {0,
nullptr, 0,
nullptr,
nullptr},
551 const VArray<bool> selection = *curves.attributes().lookup_or_default<
bool>(
552 ".selection", bke::AttrDomain::Point,
true);
554 Array<bool> points_to_dissolve(curves.points_num(),
false);
555 selection.materialize(mask, points_to_dissolve);
557 if (mode == DissolveMode::POINTS) {
558 return points_to_dissolve;
563 BLI_assert(
ELEM(mode, DissolveMode::BETWEEN, DissolveMode::UNSELECT));
569 threading::parallel_for(curves.curves_range(), 128, [&](
const IndexRange range) {
570 for (const int64_t curve_i : range) {
571 const IndexRange points = points_by_curve[curve_i];
572 const Span<bool> curve_selection = points_to_dissolve.as_span().slice(points);
574 if (!curve_selection.contains(true)) {
575 points_to_keep.slice(points).fill(true);
581 if (mode != DissolveMode::BETWEEN) {
585 const Vector<IndexRange> deselection_ranges = array_utils::find_all_ranges(curve_selection,
588 if (deselection_ranges.size() != 0) {
589 const IndexRange first_range = deselection_ranges.first().shift(points.first());
590 const IndexRange last_range = deselection_ranges.last().shift(points.first());
594 if (first_range.first() == points.first()) {
595 points_to_keep.slice(first_range).fill(true);
597 if (last_range.last() == points.last()) {
598 points_to_keep.slice(last_range).fill(true);
604 array_utils::invert_booleans(points_to_dissolve);
606 return points_to_dissolve;
617 bool changed =
false;
621 if (curves.points_num() == 0) {
626 const IndexMask points = ed::greasepencil::retrieve_editable_and_selected_points(
628 if (points.is_empty()) {
633 if (points_to_dissolve.
as_span().contains(
true)) {
634 curves.remove_points(IndexMask::from_bools(points_to_dissolve, memory), {});
652 ot->
idname =
"GREASE_PENCIL_OT_dissolve";
653 ot->
description =
"Delete selected points without splitting strokes";
666 "Method used for dissolving stroke points");
685 {
int(DeleteFrameMode::ACTIVE_FRAME),
689 "Deletes current frame in the active layer"},
690 {
int(DeleteFrameMode::ALL_FRAMES),
694 "Delete active frames for all layers"},
695 {0,
nullptr, 0,
nullptr,
nullptr},
703 const int current_frame = scene->r.cfra;
707 bool changed =
false;
708 if (mode == DeleteFrameMode::ACTIVE_FRAME && grease_pencil.has_active_layer()) {
710 if (layer.is_editable() && layer.start_frame_at(current_frame)) {
711 changed |= grease_pencil.remove_frames(layer, {*layer.start_frame_at(current_frame)});
714 else if (mode == DeleteFrameMode::ALL_FRAMES) {
716 if (layer->is_editable() && layer->start_frame_at(current_frame)) {
717 changed |= grease_pencil.remove_frames(*layer, {*layer->start_frame_at(current_frame)});
735 ot->
name =
"Delete Frame";
736 ot->
idname =
"GREASE_PENCIL_OT_delete_frame";
750 "Method used for deleting Grease Pencil frames");
770 int material_index =
object->actcol - 1;
772 if (name[0] !=
'\0') {
783 if (material_index == -1) {
790 IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
798 curves.attributes_for_write().lookup_or_add_for_write_span<
int>(
"material_index",
799 bke::AttrDomain::Curve);
800 index_mask::masked_fill(materials.span, material_index, strokes);
812 ot->
name =
"Assign Material";
813 ot->
idname =
"GREASE_PENCIL_OT_stroke_material_set";
814 ot->
description =
"Assign the active material slot to the selected strokes";
822 ot->
srna,
"material",
nullptr,
MAX_ID_NAME - 2,
"Material",
"Name of the material");
841 {
int(CyclicalMode::CLOSE),
"CLOSE", 0,
"Close All",
""},
842 {
int(CyclicalMode::OPEN),
"OPEN", 0,
"Open All",
""},
843 {
int(CyclicalMode::TOGGLE),
"TOGGLE", 0,
"Toggle",
""},
844 {0,
nullptr, 0,
nullptr,
nullptr},
855 bool changed =
false;
859 if (mode == CyclicalMode::OPEN && !curves.attributes().contains(
"cyclic")) {
865 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
873 case CyclicalMode::CLOSE:
874 index_mask::masked_fill(cyclic,
true, strokes);
876 case CyclicalMode::OPEN:
877 index_mask::masked_fill(cyclic,
false, strokes);
879 case CyclicalMode::TOGGLE:
880 array_utils::invert_booleans(cyclic, strokes);
885 if (mode != CyclicalMode::CLOSE) {
886 if (array_utils::booleans_mix_calc(curves.cyclic()) == array_utils::BooleanMix::AllFalse) {
887 curves.attributes_for_write().remove(
"cyclic");
905 ot->
name =
"Set Cyclical State";
906 ot->
idname =
"GREASE_PENCIL_OT_cyclical_set";
907 ot->
description =
"Close or open the selected stroke adding a segment from last to first point";
931 if (object->totcol == 0) {
938 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
939 *
object, info.drawing, info.layer_index, memory);
945 const VArray<int> materials = *curves.attributes().lookup_or_default<
int>(
946 "material_index", bke::AttrDomain::Curve, 0);
947 object->actcol = materials[strokes.
first()] + 1;
958 ot->
name =
"Set Active Material";
959 ot->
idname =
"GREASE_PENCIL_OT_set_active_material";
960 ot->
description =
"Set the selected stroke material as the active material";
982 bool changed =
false;
986 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
995 bke::curves::fill_points<float>(points_by_curve, strokes, radius, radii);
1009 ot->
name =
"Set Uniform Thickness";
1010 ot->
idname =
"GREASE_PENCIL_OT_set_uniform_thickness";
1011 ot->
description =
"Set all stroke points to same thickness";
1019 ot->
srna,
"thickness", 0.1f, 0.0f, 1000.0f,
"Thickness",
"Thickness", 0.0f, 1000.0f);
1035 bool changed =
false;
1039 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
1048 bke::curves::fill_points<float>(points_by_curve, strokes, opacity, opacities);
1062 ot->
name =
"Set Uniform Opacity";
1063 ot->
idname =
"GREASE_PENCIL_OT_set_uniform_opacity";
1086 bool changed =
false;
1090 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
1114 ot->
name =
"Switch Direction";
1115 ot->
idname =
"GREASE_PENCIL_OT_stroke_switch_direction";
1116 ot->
description =
"Change direction of the points of the selected strokes";
1162 bool changed =
false;
1167 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
1175 if (
ELEM(mode, CapsMode::ROUND, CapsMode::FLAT)) {
1177 attributes.lookup_or_add_for_write_span<
int8_t>(
"start_cap", bke::AttrDomain::Curve);
1179 "end_cap", bke::AttrDomain::Curve);
1184 index_mask::masked_fill(start_caps.
span, flag_set, strokes);
1185 index_mask::masked_fill(end_caps.span, flag_set, strokes);
1191 case CapsMode::START: {
1193 "start_cap", bke::AttrDomain::Curve);
1198 case CapsMode::END: {
1200 "end_cap", bke::AttrDomain::Curve);
1205 case CapsMode::ROUND:
1206 case CapsMode::FLAT:
1225 {
int(CapsMode::ROUND),
"ROUND", 0,
"Rounded",
"Set as default rounded"},
1226 {
int(CapsMode::FLAT),
"FLAT", 0,
"Flat",
""},
1228 {
int(CapsMode::START),
"START", 0,
"Toggle Start",
""},
1229 {
int(CapsMode::END),
"END", 0,
"Toggle End",
""},
1230 {0,
nullptr, 0,
nullptr,
nullptr},
1233 ot->
name =
"Set Curve Caps";
1234 ot->
idname =
"GREASE_PENCIL_OT_caps_set";
1235 ot->
description =
"Change curve caps mode (rounded or flat)";
1262 if (ob ==
nullptr) {
1270 item_tmp.name = ma->id.name + 2;
1271 item_tmp.value = i + 1;
1272 item_tmp.icon = ma->preview ? ma->preview->runtime->icon_id : ICON_NONE;
1290 if ((slot < 1) || (slot > object->totcol)) {
1295 object->actcol = slot;
1304 ot->
name =
"Set Active Material";
1305 ot->
idname =
"GREASE_PENCIL_OT_set_material";
1330 scene->toolsettings);
1332 std::atomic<bool> changed =
false;
1338 if (elements.is_empty()) {
1343 if (selection_domain == bke::AttrDomain::Curve) {
1344 curves::duplicate_curves(curves, elements);
1346 else if (selection_domain == bke::AttrDomain::Point) {
1347 curves::duplicate_points(curves, elements);
1350 changed.store(
true, std::memory_order_relaxed);
1363 ot->
idname =
"GREASE_PENCIL_OT_duplicate";
1386 const IndexMask editable_strokes = ed::greasepencil::retrieve_editable_strokes(
1389 const IndexMask curves_to_delete = IndexMask::from_predicate(
1390 editable_strokes,
GrainSize(4096), memory, [&](
const int i) {
1391 return points_by_curve[i].
size() <= limit;
1394 curves.remove_curves(curves_to_delete, {});
1406 C, op, event,
IFACE_(
"Remove Loose Points"),
IFACE_(
"Delete"));
1411 ot->
name =
"Clean Loose Points";
1412 ot->
idname =
"GREASE_PENCIL_OT_clean_loose";
1427 "Number of points to consider stroke as loose",
1443 std::atomic<bool> changed =
false;
1449 scene->toolsettings);
1455 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
1464 if (selection_domain == bke::AttrDomain::Curve || !only_selected) {
1468 else if (selection_domain == bke::AttrDomain::Point) {
1472 const VArray<bool> selection = *curves.attributes().lookup_or_default<
bool>(
1473 ".selection", bke::AttrDomain::Point,
true);
1475 const OffsetIndices points_by_curve = curves.points_by_curve();
1481 for (
const int curve : curves.curves_range()) {
1484 for (
const int point : points_by_curve[
curve].drop_back(1)) {
1486 if (!selection[point]) {
1490 if (selection[point + 1]) {
1491 use_cuts[
point] = cuts;
1495 if (cyclic[curve]) {
1496 const int first_point = points_by_curve[
curve].
first();
1497 const int last_point = points_by_curve[
curve].last();
1498 if (selection[first_point] && selection[last_point]) {
1499 use_cuts[last_point] = cuts;
1506 curves = geometry::subdivide_curves(curves, strokes, vcuts);
1508 changed.store(
true, std::memory_order_relaxed);
1523 ot->
name =
"Subdivide Stroke";
1524 ot->
idname =
"GREASE_PENCIL_OT_stroke_subdivide";
1526 "Subdivide between continuous selected points of the stroke adding a point half way "
1531 ot->
poll = ed::greasepencil::editable_grease_pencil_poll;
1535 prop =
RNA_def_int(
ot->
srna,
"number_cuts", 1, 1, 32,
"Number of Cuts",
"", 1, 5);
1543 "Smooth only selected points in the stroke");
1569 if (
ELEM(direction, ReorderDirection::UP, ReorderDirection::DOWN)) {
1571 array_utils::fill_index_range<int>(indices);
1574 if (
ELEM(direction, ReorderDirection::TOP, ReorderDirection::BOTTOM)) {
1599 const IndexMask &A = (direction == ReorderDirection::BOTTOM) ? selected : unselected;
1600 const IndexMask &
B = (direction == ReorderDirection::BOTTOM) ? unselected : selected;
1602 A.to_indices(indices.as_mutable_span().take_front(A.size()));
1603 B.to_indices(indices.as_mutable_span().take_back(
B.size()));
1605 else if (direction == ReorderDirection::DOWN) {
1606 selected.foreach_index_optimized<
int>([&](
const int curve_i,
const int pos) {
1608 if (curve_i !=
pos) {
1610 std::swap(indices[curve_i], indices[curve_i - 1]);
1614 else if (direction == ReorderDirection::UP) {
1615 Array<int> selected_indices(selected.size());
1620 for (
const int i : selected_indices.
index_range()) {
1622 const int curve_i = selected_indices[
pos];
1625 if (curve_i != universe.
last(i)) {
1627 std::swap(indices[curve_i], indices[curve_i + 1]);
1643 std::atomic<bool> changed =
false;
1647 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
1655 if (strokes.
size() == curves.curves_num()) {
1661 curves = geometry::reorder_curves_geometry(curves, indices, {});
1663 changed.store(
true, std::memory_order_relaxed);
1677 {
int(ReorderDirection::TOP),
"TOP", 0,
"Bring to Front",
""},
1678 {
int(ReorderDirection::UP),
"UP", 0,
"Bring Forward",
""},
1680 {
int(ReorderDirection::DOWN),
"DOWN", 0,
"Send Backward",
""},
1681 {
int(ReorderDirection::BOTTOM),
"BOTTOM", 0,
"Send to Back",
""},
1682 {0,
nullptr, 0,
nullptr,
nullptr},
1686 ot->
idname =
"GREASE_PENCIL_OT_reorder";
1687 ot->
description =
"Change the display order of the selected strokes";
1695 ot->
srna,
"direction", prop_reorder_direction,
int(ReorderDirection::TOP),
"Direction",
"");
1706 using namespace bke::greasepencil;
1708 bool changed =
false;
1713 int target_layer_name_length;
1715 op->
ptr,
"target_layer_name",
nullptr, 0, &target_layer_name_length);
1718 if (add_new_layer) {
1719 grease_pencil.add_layer(target_layer_name);
1722 TreeNode *target_node = grease_pencil.find_node_by_name(target_layer_name);
1723 if (target_node ==
nullptr || !target_node->
is_layer()) {
1729 if (layer_dst.is_locked()) {
1740 const IndexMask selected_strokes = ed::curves::retrieve_selected_curves(curves_src, memory);
1747 Drawing &drawing_dst = *grease_pencil.insert_frame(layer_dst, info.frame_number);
1749 curves_src, selected_strokes, {});
1754 else if (
Drawing *drawing_dst = grease_pencil.get_editable_drawing_at(layer_dst,
1759 curves_src, selected_strokes, {});
1760 Curves *selected_curves = bke::curves_new_nomain(std::move(selected_elems));
1761 Curves *layer_curves = bke::curves_new_nomain(std::move(drawing_dst->strokes_for_write()));
1762 std::array<bke::GeometrySet, 2> geometry_sets{bke::GeometrySet::from_curves(selected_curves),
1763 bke::GeometrySet::from_curves(layer_curves)};
1769 drawing_dst->tag_topology_changed();
1772 info.drawing.tag_topology_changed();
1788 if (add_new_layer) {
1792 const std::string
unique_name = grease_pencil.unique_layer_name(
"Layer");
1796 C, op, event,
IFACE_(
"Move to New Layer"),
IFACE_(
"Create"));
1805 ot->
name =
"Move to Layer";
1806 ot->
idname =
"GREASE_PENCIL_OT_move_to_layer";
1816 ot->
srna,
"target_layer_name",
nullptr,
INT16_MAX,
"Name",
"Target Grease Pencil Layer");
1819 ot->
srna,
"add_new_layer",
false,
"New Layer",
"Move selection to a new layer");
1839 {
int(SeparateMode::SELECTED),
"SELECTED", 0,
"Selection",
"Separate selected geometry"},
1840 {
int(SeparateMode::MATERIAL),
"MATERIAL", 0,
"By Material",
"Separate by material"},
1841 {
int(SeparateMode::LAYER),
"LAYER", 0,
"By Layer",
"Separate by layer"},
1842 {0,
nullptr, 0,
nullptr,
nullptr},
1847 int actcol =
object->actcol;
1848 for (
int slot = 1; slot <=
object->totcol; slot++) {
1850 object->actcol = slot;
1855 if (actcol >= slot) {
1860 object->actcol = actcol;
1870 Base *base_new = object::add_duplicate(bmain, scene, view_layer, base_prev, dupflag);
1881 using namespace bke::greasepencil;
1884 const Layer &layer_src = grease_pencil_src.layer(layer_index);
1885 if (
TreeNode *node = grease_pencil_dst.find_node_by_name(layer_src.name())) {
1886 return node->as_layer();
1890 Layer &new_layer = grease_pencil_dst.add_layer(layer_src.name());
1893 bke::gather_attributes(grease_pencil_src.attributes(),
1894 bke::AttrDomain::Layer,
1895 bke::AttrDomain::Layer,
1897 Span({layer_index}),
1898 grease_pencil_dst.attributes_for_write());
1910 using namespace bke::greasepencil;
1911 bool changed =
false;
1915 &bmain, &scene, &view_layer, &base_prev, grease_pencil_src);
1924 const IndexMask selected_points = ed::curves::retrieve_selected_points(curves_src, memory);
1931 info.layer_index, grease_pencil_src, grease_pencil_dst);
1933 Drawing *drawing_dst = grease_pencil_dst.insert_frame(layer_dst, info.frame_number);
1939 curves_src, selected_points, {});
1942 info.drawing.tag_topology_changed();
1949 grease_pencil_dst.set_active_layer(
nullptr);
1972 using namespace bke::greasepencil;
1973 bool changed =
false;
1978 for (
const int layer_i : grease_pencil_src.layers().index_range()) {
1979 Layer &layer_src = grease_pencil_src.layer(layer_i);
1980 if (layer_src.is_selected() || layer_src.is_locked()) {
1985 &bmain, &scene, &view_layer, &base_prev, grease_pencil_src);
1988 layer_i, grease_pencil_src, grease_pencil_dst);
1992 scene, grease_pencil_src, layer_src);
1997 object_src, info.drawing, info.layer_index, memory);
2010 Drawing *drawing_dst = grease_pencil_dst.insert_frame(layer_dst, info.frame_number);
2016 info.drawing.strokes(), strokes, {});
2019 info.drawing.tag_topology_changed();
2042 using namespace bke::greasepencil;
2043 bool changed =
false;
2054 &bmain, &scene, &view_layer, &base_prev, grease_pencil_src);
2070 object_src, info.drawing, mat_i, memory);
2079 info.layer_index, grease_pencil_src, grease_pencil_dst);
2081 Drawing *drawing_dst = grease_pencil_dst.insert_frame(layer_dst, info.frame_number);
2086 drawing_dst->
strokes_for_write() = bke::curves_copy_curve_selection(curves_src, strokes, {});
2089 info.drawing.tag_topology_changed();
2109 using namespace bke::greasepencil;
2118 bool changed =
false;
2123 case SeparateMode::SELECTED: {
2127 const bool has_selection = std::any_of(
2129 return ed::curves::has_anything_selected(info.drawing.strokes());
2131 if (!has_selection) {
2138 *C, *bmain, *scene, *view_layer, *base_prev, *object_src);
2141 case SeparateMode::MATERIAL: {
2143 if (object_src->
totcol == 1) {
2150 *C, *bmain, *scene, *view_layer, *base_prev, *object_src);
2153 case SeparateMode::LAYER: {
2155 if (grease_pencil_src.layers().size() == 1) {
2161 *C, *bmain, *scene, *view_layer, *base_prev, *object_src);
2179 ot->
idname =
"GREASE_PENCIL_OT_separate";
2180 ot->
description =
"Separate the selected geometry into a new grease pencil object";
2207} *grease_pencil_clipboard =
nullptr;
2228 scene.toolsettings);
2234 if (!grease_pencil.has_active_layer()) {
2239 if (!active_layer.is_editable()) {
2245 bool inserted_keyframe =
false;
2252 if (target_drawing ==
nullptr) {
2262 ed::curves::fill_selection_false(selection_in_target.
span);
2263 selection_in_target.
finish();
2268 *bmain, *
object, *target_drawing, object_to_layer, keep_world_transform, paste_on_back);
2273 if (inserted_keyframe) {
2285 std::unique_ptr<bke::Instances> instances = std::make_unique<bke::Instances>();
2286 instances->resize(geometries.size());
2287 instances->transforms_for_write().copy_from(transforms);
2289 for (
const int i : geometries.index_range()) {
2294 options.keep_original_ids =
true;
2295 options.realize_instance_attributes =
false;
2296 return realize_instances(bke::GeometrySet::from_instances(instances.release()),
options);
2307 scene->toolsettings);
2311 bool anything_copied =
false;
2320 const Layer &layer = grease_pencil.layer(drawing_info.layer_index);
2321 const float4x4 layer_to_object = layer.to_object_space(*
object);
2323 if (curves.curves_num() == 0) {
2326 if (!ed::curves::has_anything_selected(curves)) {
2334 if (selection_domain == bke::AttrDomain::Curve) {
2335 const IndexMask selected_curves = ed::curves::retrieve_selected_curves(curves, memory);
2336 copied_curves = curves_copy_curve_selection(curves, selected_curves, {});
2339 else if (selection_domain == bke::AttrDomain::Point) {
2340 const IndexMask selected_points = ed::curves::retrieve_selected_points(curves, memory);
2341 copied_curves = curves_copy_point_selection(curves, selected_points, {});
2346 Curves *layer_curves = curves_new_nomain(std::move(copied_curves));
2347 set_of_copied_curves.
append(bke::GeometrySet::from_curves(layer_curves));
2348 set_of_transforms.
append(layer_to_object);
2349 anything_copied =
true;
2352 if (!anything_copied) {
2361 clipboard.
transform =
object->object_to_world();
2368 const VArraySpan<int> material_indices = *attributes.lookup_or_default<
int>(
2369 "material_index", bke::AttrDomain::Curve, 0);
2371 if (!material_indices.
contains(material_index)) {
2375 clipboard.
materials.
append({material->id.session_uid, material_index});
2379 if (selection_domain == bke::AttrDomain::Curve) {
2382 else if (selection_domain == bke::AttrDomain::Point) {
2402 ot->
name =
"Paste Strokes";
2403 ot->
idname =
"GREASE_PENCIL_OT_paste";
2405 "Paste Grease Pencil points or strokes from the internal clipboard to the active layer";
2413 ot->
srna,
"paste_back",
false,
"Paste on Back",
"Add pasted strokes behind all strokes");
2416 "keep_world_transform",
2418 "Keep World Transform",
2419 "Keep the world transform of strokes from the clipboard unchanged");
2424 ot->
name =
"Copy Strokes";
2425 ot->
idname =
"GREASE_PENCIL_OT_copy";
2426 ot->
description =
"Copy the selected Grease Pencil points or strokes to the internal clipboard";
2459 scene_materials.
add(material->id.session_uid, material);
2472 clipboard_material_remap[clipboard.
materials[i].second] = target_index;
2478 clipboard_material_remap[clipboard.
materials[i].second] = target_index;
2481 return clipboard_material_remap;
2488 const bool keep_world_transform,
2489 const bool paste_back)
2499 const Array<int> clipboard_material_remap = ed::greasepencil::clipboard_materials_remap(bmain,
2503 const IndexRange pasted_curves_range = paste_back ?
2513 bke::GeometrySet::from_curves(paste_back ? clipboard_id : target_id),
2514 bke::GeometrySet::from_curves(paste_back ? target_id : clipboard_id)};
2516 const float4x4 clipboard_transform = transform *
2517 (keep_world_transform ?
2518 object.world_to_object() * clipboard_to_world :
2519 float4x4::identity());
2522 float4x4::identity()} :
2531 "material_index", bke::AttrDomain::Curve);
2532 if (material_indices) {
2533 for (
const int i : pasted_curves_range) {
2534 material_indices.
span[i] = clipboard_material_remap[material_indices.
span[i]];
2536 material_indices.
finish();
2541 return pasted_curves_range;
2556 std::atomic<bool> changed =
false;
2562 const IndexMask points = use_unselected ?
2563 ed::greasepencil::retrieve_editable_points(
2565 ed::greasepencil::retrieve_editable_and_selected_points(
2567 if (points.is_empty()) {
2571 drawing.
strokes(), threshold, points, {});
2573 changed.store(
true, std::memory_order_relaxed);
2586 ot->
name =
"Merge by Distance";
2587 ot->
idname =
"GREASE_PENCIL_OT_stroke_merge_by_distance";
2595 prop =
RNA_def_float(
ot->
srna,
"threshold", 0.001f, 0.0f, 100.0f,
"Threshold",
"", 0.0f, 100.0f);
2603 "Use whole stroke, not only selected points");
2630 offset_indices::copy_group_sizes(
2636 int point_offset = 0;
2638 const IndexRange curve_points = points_by_curve[curve_index];
2640 const bool curve_cyclic = src_cyclic[curve_index];
2642 curve_points_to_extrude.
foreach_index([&](
const int src_point_index) {
2643 if (!curve_cyclic && (src_point_index == curve_points.
first())) {
2646 dst_to_src_points.
insert(src_point_index + point_offset, src_point_index);
2647 dst_selected.
insert(src_point_index + point_offset,
true);
2648 ++dst_curve_counts[curve_index];
2652 if (!curve_cyclic && (src_point_index == curve_points.
last())) {
2655 dst_to_src_points.
insert(src_point_index + point_offset + 1, src_point_index);
2656 dst_selected.
insert(src_point_index + point_offset + 1,
true);
2657 ++dst_curve_counts[curve_index];
2665 dst_to_src_points.
append(src_point_index);
2666 dst_selected.
append(
false);
2667 dst_to_src_points.
append(src_point_index);
2668 dst_selected.
append(
true);
2669 dst_to_src_curves.
append(curve_index);
2670 dst_curve_counts.
append(2);
2674 const int new_points_num = dst_to_src_points.
size();
2675 const int new_curves_num = dst_to_src_curves.
size();
2681 array_utils::copy(dst_curve_counts.
as_span(), new_curve_offsets.
drop_back(1));
2682 offset_indices::accumulate_counts_to_offsets(new_curve_offsets);
2691 selection.span.copy_from(dst_selected.
as_span());
2701 bke::gather_attributes(src_attributes,
2702 bke::AttrDomain::Curve,
2703 bke::AttrDomain::Curve,
2704 bke::attribute_filter_from_skip_ref({
"cyclic"}),
2708 bke::gather_attributes(src_attributes,
2709 bke::AttrDomain::Point,
2710 bke::AttrDomain::Point,
2711 bke::attribute_filter_from_skip_ref({
".selection"}),
2725 std::atomic<bool> changed =
false;
2731 if (points_to_extrude.
is_empty()) {
2739 changed.store(
true, std::memory_order_relaxed);
2752 ot->
name =
"Extrude Stroke Points";
2753 ot->
idname =
"GREASE_PENCIL_OT_extrude";
2784 if (mode == ReprojectMode::Surface) {
2789 scene.toolsettings);
2792 if (keep_original) {
2798 if (elements.is_empty()) {
2803 if (selection_domain == bke::AttrDomain::Curve) {
2804 curves::duplicate_curves(curves, elements);
2806 else if (selection_domain == bke::AttrDomain::Point) {
2807 curves::duplicate_points(curves, elements);
2816 std::atomic<bool> changed =
false;
2820 if (drawings.is_empty()) {
2823 const int current_frame_number = drawings.first().frame_number;
2825 if (mode == ReprojectMode::Surface) {
2826 scene.r.cfra = current_frame_number;
2834 if (points_to_reproject.
is_empty()) {
2841 scene, *region, *v3d, *
object, &layer, mode, offset, view_depths);
2845 positions[point_i] = drawing_placement.
reproject(positions[point_i]);
2849 changed.store(
true, std::memory_order_relaxed);
2853 if (mode == ReprojectMode::Surface) {
2854 scene.r.cfra = oldframe;
2878 if (type == ReprojectMode::Surface) {
2889 {
int(ReprojectMode::Front),
2893 "Reproject the strokes using the X-Z plane"},
2894 {
int(ReprojectMode::Side),
"SIDE", 0,
"Side",
"Reproject the strokes using the Y-Z plane"},
2895 {
int(ReprojectMode::Top),
"TOP", 0,
"Top",
"Reproject the strokes using the X-Y plane"},
2896 {
int(ReprojectMode::View),
2900 "Reproject the strokes to end up on the same plane, as if drawn from the current "
2902 "using 'Cursor' Stroke Placement"},
2903 {
int(ReprojectMode::Surface),
2907 "Reproject the strokes on to the scene geometry, as if drawn using 'Surface' placement"},
2908 {
int(ReprojectMode::Cursor),
2912 "Reproject the strokes using the orientation of 3D cursor"},
2913 {0,
nullptr, 0,
nullptr,
nullptr},
2917 ot->
name =
"Reproject Strokes";
2918 ot->
idname =
"GREASE_PENCIL_OT_reproject";
2920 "Reproject the selected strokes from the current viewpoint as if they had been newly "
2922 "(e.g. to fix problems from accidental 3D cursor movement or accidental viewport changes, "
2923 "or for matching deforming geometry)";
2936 ot->
srna,
"type", reproject_type,
int(ReprojectMode::View),
"Projection Type",
"");
2943 "Keep original strokes and create a copy before reprojecting");
2965 return (area !=
nullptr) && (area->spacetype ==
SPACE_VIEW3D);
2982 if (curves.curves_num() == 0) {
2985 if (!ed::curves::has_anything_selected(curves)) {
2990 const IndexMask selected_points = ed::curves::retrieve_selected_points(curves, memory);
2992 const Layer &layer = grease_pencil.layer(drawing_info.layer_index);
2993 const float4x4 layer_to_world = layer.to_world_space(
object);
2999 const float3 pos_snapped = grid_size *
math::floor(pos_world / grid_size + 0.5f);
3003 drawing_info.drawing.tag_positions_changed();
3015 ot->
name =
"Snap Selection to Grid";
3016 ot->
idname =
"GREASE_PENCIL_OT_snap_to_grid";
3017 ot->
description =
"Snap selected points to the nearest grid points";
3039 const float3 cursor_world = scene.cursor.location;
3044 if (curves.curves_num() == 0) {
3047 if (!ed::curves::has_anything_selected(curves)) {
3052 const IndexMask selected_points = ed::curves::retrieve_selected_points(curves,
3053 selected_points_memory);
3055 const Layer &layer = grease_pencil.layer(drawing_info.layer_index);
3056 const float4x4 layer_to_world = layer.to_world_space(
object);
3062 const OffsetIndices points_by_curve = curves.points_by_curve();
3064 const IndexMask selected_curves = ed::curves::retrieve_selected_curves(
3065 curves, selected_curves_memory);
3068 const IndexRange points = points_by_curve[curve_i];
3071 const float3 offset = cursor_layer - positions[points.first()];
3073 GrainSize(4096), [&](
const int point_i) { positions[point_i] += offset; });
3078 index_mask::masked_fill(positions, cursor_layer, selected_points);
3081 drawing_info.drawing.tag_positions_changed();
3094 ot->
name =
"Snap Selection to Cursor";
3095 ot->
idname =
"GREASE_PENCIL_OT_snap_to_cursor";
3096 ot->
description =
"Snap selected points/strokes to the cursor";
3110 "Offset the entire stroke instead of selected points only");
3128 int num_selected = 0;
3129 r_centroid =
float3(0.0f);
3130 r_min =
float3(std::numeric_limits<float>::max());
3131 r_max =
float3(std::numeric_limits<float>::lowest());
3134 for (
const DrawingInfo &drawing_info : drawings) {
3135 const Layer &layer = grease_pencil.layer(drawing_info.layer_index);
3136 if (layer.is_locked()) {
3140 if (curves.curves_num() == 0) {
3143 if (!ed::curves::has_anything_selected(curves)) {
3148 const IndexMask selected_points = ed::curves::retrieve_selected_points(curves,
3149 selected_points_memory);
3150 const float4x4 layer_to_world = layer.to_world_space(
object);
3155 r_centroid += pos_world;
3158 num_selected += selected_points.
size();
3160 if (num_selected == 0) {
3161 r_min = r_max =
float3(0.0f);
3165 r_centroid /= num_selected;
3174 float3 &cursor =
reinterpret_cast<float3 &
>(scene.cursor.location);
3176 float3 centroid, points_min, points_max;
3178 scene,
object, grease_pencil, centroid, points_min, points_max))
3183 switch (scene.toolsettings->transform_pivot_point) {
3206 ot->
name =
"Snap Cursor to Selected Points";
3207 ot->
idname =
"GREASE_PENCIL_OT_snap_cursor_to_selected";
3208 ot->
description =
"Snap cursor to center of selected points";
3232 strokemat4x3[2][2] = 0.0f;
3233 strokemat4x3[3][2] = 1.0f;
3235 return strokemat4x3;
3245 std::atomic<bool> changed =
false;
3249 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
3256 const float4x4 layer_space_to_world_space = layer.to_world_space(*
object);
3261 const float2 screen_direction = screen_end - screen_start;
3262 const float2 screen_tangent = screen_start +
float2(-screen_direction[1], screen_direction[0]);
3268 const VArray<int> materials = *curves.attributes().lookup_or_default<
int>(
3269 "material_index", bke::AttrDomain::Curve, 0);
3274 const int material_index = materials[curve_i];
3277 material_index + 1);
3288 positions[points_by_curve[curve_i].first()]);
3301 const float3 origin = start;
3307 if (
math::dot(tangent - start, v_dir) < 0.0f) {
3315 float3x2 offset_matrix = float3x2::identity();
3319 offset_matrix *= 0.5f;
3320 offset_matrix[2] +=
float2(0.5f, 0.5f);
3324 offset_matrix[2] -=
float2(0.5f, 0.5f);
3327 offset_matrix = texture_rotation * offset_matrix;
3328 offset_matrix[2] -= texture_offset;
3331 layer_space_to_world_space;
3336 changed.store(
true, std::memory_order_relaxed);
3355 ret &= ~OPERATOR_RUNNING_MODAL;
3383 ot->
name =
"Texture Gradient";
3384 ot->
idname =
"GREASE_PENCIL_OT_texture_gradient";
3385 ot->
description =
"Draw a line to set the fill material gradient for the selected strokes";
3415 bool changed =
false;
3420 const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
3427 options.convert_bezier_handles_to_poly_points = use_handles;
3428 options.convert_bezier_handles_to_catmull_rom_points = use_handles;
3429 options.keep_bezier_shape_as_nurbs = use_handles;
3430 options.keep_catmull_rom_shape_as_nurbs = use_handles;
3432 curves = geometry::convert_curves(curves, strokes, dst_type, {},
options);
3448 ot->
name =
"Set Curve Type";
3449 ot->
idname =
"GREASE_PENCIL_OT_set_curve_type";
3465 "Take handle information into account in the conversion");
3482 bool changed =
false;
3490 const IndexMask editable_strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
3492 const IndexMask bezier_curves = curves.indices_for_curve_type(
3497 ".selection", bke::AttrDomain::Point,
true);
3498 const VArraySpan<bool> selection_left = *attributes.lookup_or_default<
bool>(
3499 ".selection_handle_left", bke::AttrDomain::Point,
true);
3500 const VArraySpan<bool> selection_right = *attributes.lookup_or_default<
bool>(
3501 ".selection_handle_right", bke::AttrDomain::Point,
true);
3507 const IndexRange points = points_by_curve[curve_i];
3508 for (
const int point_i : points) {
3509 if (selection_left[point_i] || selection[point_i]) {
3510 handle_types_left[point_i] =
int8_t(dst_handle_type);
3512 if (selection_right[point_i] || selection[point_i]) {
3513 handle_types_right[point_i] =
int8_t(dst_handle_type);
3518 curves.calculate_bezier_auto_handles();
3519 curves.tag_topology_changed();
3535 ot->
name =
"Set Handle Type";
3536 ot->
idname =
"GREASE_PENCIL_OT_set_handle_type";
3563 bool changed =
false;
3568 const IndexMask editable_strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
3578 index_mask::masked_fill(curves.resolution_for_write(), resolution, editable_strokes);
3593 ot->
name =
"Set Curve Resolution";
3594 ot->
idname =
"GREASE_PENCIL_OT_set_curve_resolution";
3608 "The resolution to use for each curve segment",
3625 bool changed =
false;
3631 const IndexMask editable_strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
3637 if (attributes.contains(
"uv_rotation")) {
3638 if (editable_strokes.
size() == curves.curves_num()) {
3639 attributes.remove(
"uv_rotation");
3644 index_mask::masked_fill(uv_rotations.
span, 0.0f, editable_strokes);
3649 if (attributes.contains(
"uv_translation")) {
3650 if (editable_strokes.
size() == curves.curves_num()) {
3651 attributes.remove(
"uv_translation");
3655 attributes.lookup_for_write_span<
float2>(
"uv_translation");
3656 index_mask::masked_fill(uv_translations.
span,
float2(0.0f, 0.0f), editable_strokes);
3657 uv_translations.
finish();
3661 if (attributes.contains(
"uv_scale")) {
3662 if (editable_strokes.
size() == curves.curves_num()) {
3663 attributes.remove(
"uv_scale");
3668 index_mask::masked_fill(uv_scales.
span,
float2(1.0f, 1.0f), editable_strokes);
3673 if (attributes.contains(
"uv_shear")) {
3674 if (editable_strokes.
size() == curves.curves_num()) {
3675 attributes.remove(
"uv_shear");
3680 index_mask::masked_fill(uv_shears.
span, 0.0f, editable_strokes);
3701 ot->
idname =
"GREASE_PENCIL_OT_reset_uvs";
3702 ot->
description =
"Reset UV transformation to default values";
3767 Layer &layer_dst = grease_pencil_dst.add_layer(group_dst, layer_src.name());
3790 if (node->is_group()) {
3793 if (node->is_layer()) {
3794 Layer &layer_dst =
copy_layer(grease_pencil_dst, group_dst, node->as_layer());
3795 layer_name_map.
add_new(node->as_layer().name(), layer_dst.name());
3818 for (
const int i : material_index_map.
index_range()) {
3820 material_index_map[i] = materials.index_of_or_add(material);
3822 return material_index_map;
3834 for (const int curve_i : range) {
3835 material_writer.span[curve_i] = material_index_map[material_writer.span[curve_i]];
3838 material_writer.
finish();
3843 const ListBase &vertex_group_names)
3852 return vertex_group_map;
3859 STRNCPY(dg->name, vertex_group_map.
lookup(dg->name).c_str());
3883 const int orig_layers_num = grease_pencil_dst.layers().size();
3896 const IndexRange new_drawings_dst = IndexRange::from_begin_size(
3898 const IndexRange new_drawings_src = IndexRange::from_begin_size(
3901 copy_drawing_array(grease_pencil_dst.drawings(), new_drawings.
slice(new_drawings_dst));
3902 copy_drawing_array(grease_pencil_src.drawings(), new_drawings.
slice(new_drawings_src));
3905 grease_pencil_dst.resize_drawings(0);
3913 grease_pencil_dst.root_group(),
3914 grease_pencil_src.root_group(),
3922 grease_pencil_dst.layers().size());
3927 grease_pencil_src.layers().size());
3930 for (
const int layer_index : grease_pencil_dst.layers().index_range()) {
3931 Layer &layer = *grease_pencil_dst.layers_for_write()[layer_index];
3932 const bool is_orig_layer = (layer_index < orig_layers_num);
3933 const float4x4 old_layer_to_world = (is_orig_layer ? layer.to_world_space(ob_dst) :
3934 layer.to_world_space(ob_src));
3937 if (!is_orig_layer) {
3941 if (new_mask_name) {
3947 for (
const int key : layer.frames_for_write().keys()) {
3948 int &drawing_index = layer.frames_for_write().lookup(key).drawing_index;
3949 drawing_index = new_drawings_src[drawing_index];
3956 if (
ELEM(layer.parent, &ob_dst, &ob_src)) {
3957 layer.parent =
nullptr;
3963 const float4x4 new_layer_to_world = layer.to_world_space(ob_dst);
3964 for (
const int key : layer.frames_for_write().keys()) {
3965 const int drawing_index = layer.frames_for_write().lookup(key).drawing_index;
3974 if (!is_orig_layer) {
3983 if (
id == &grease_pencil_src.
id && fcu->
rna_path && strstr(fcu->
rna_path,
"layers[")) {
3985 for (auto [name_src, name_dst] : layer_name_map.items()) {
3986 if (name_dst != name_src) {
3987 const char *old_path = fcu->rna_path;
3988 fcu->rna_path = BKE_animsys_fix_rna_path_rename(
3989 id, fcu->rna_path,
"layers", name_src.c_str(), name_dst.c_str(), 0, 0, false);
3990 if (old_path != fcu->rna_path) {
3999 LISTBASE_FOREACH (DriverVar *, dvar, &fcu->driver->variables) {
4001 DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
4002 if (dtar->id != &grease_pencil_src.id) {
4005 dtar->id = &grease_pencil_dst.id;
4007 if (dtar->rna_path && strstr(dtar->rna_path,
"layers[")) {
4008 for (auto [name_src, name_dst] : layer_name_map.items()) {
4009 if (name_dst != name_src) {
4010 const char *old_path = fcu->rna_path;
4011 dtar->rna_path = BKE_animsys_fix_rna_path_rename(
4012 id, dtar->rna_path,
"layers", name_src.c_str(), name_dst.c_str(), 0, 0, false);
4013 if (old_path != dtar->rna_path) {
4020 DRIVER_TARGETS_LOOPER_END;
4027 if (ob_dst.adt ==
nullptr) {
4034 if (ob_dst.adt->action) {
4038 if (grease_pencil_src.adt) {
4039 if (grease_pencil_dst.adt ==
nullptr) {
4047 if (grease_pencil_dst.adt->action) {
4068 if (ob_iter == ob_active) {
4080 Object *ob_dst = ob_active;
4085 *grease_pencil_dst, materials);
4110 if (!materials.is_empty()) {
void BKE_animdata_merge_copy(Main *bmain, ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
AnimData * BKE_animdata_copy(Main *bmain, AnimData *adt, int flag)
void BKE_fcurves_main_cb(struct Main *bmain, blender::FunctionRef< void(ID *, FCurve *)> func)
#define CTX_DATA_BEGIN(C, Type, instance, member)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Base * CTX_data_active_base(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
bool CustomData_merge_layout(const CustomData *source, CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
Low-level operations for grease pencil.
void * BKE_grease_pencil_add(Main *bmain, const char *name)
Material * BKE_grease_pencil_object_material_new(Main *bmain, Object *ob, const char *name, int *r_index)
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)
ID * BKE_libblock_find_name(Main *bmain, short type, const char *name, const std::optional< Library * > lib=std::nullopt) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
General operations, lookup, etc. for materials.
bool BKE_object_material_slot_remove(struct Main *bmain, struct Object *ob)
struct Material * BKE_object_material_get(struct Object *ob, short act)
bool BKE_object_material_slot_used(struct Object *object, short actcol)
short * BKE_object_material_len_p(struct Object *ob)
struct Material *** BKE_object_material_array_p(struct Object *ob)
int BKE_object_material_ensure(Main *bmain, Object *ob, Material *material)
void BKE_object_material_array_assign(struct Main *bmain, struct Object *ob, struct Material ***matar, int totcol, bool to_object_only)
struct MaterialGPencilStyle * BKE_gpencil_material_settings(struct Object *ob, short act)
int BKE_object_material_index_get(Object *ob, const Material *ma)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
MINLINE float interpf(float target, float origin, float t)
float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3])
#define BLI_SCOPED_DEFER(function_to_defer)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
#define STRNCPY(dst, src)
#define BLT_I18NCONTEXT_ID_GPENCIL
#define BLT_I18NCONTEXT_ID_MOVIECLIP
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
float DEG_get_ctime(const Depsgraph *graph)
Object * DEG_get_original_object(Object *object)
@ ID_RECALC_ANIMATION_NO_FLUSH
@ GP_STROKE_CAP_TYPE_FLAT
@ GP_STROKE_CAP_TYPE_ROUND
@ GP_MATERIAL_GRADIENT_RADIAL
Object is a sort of wrapper for general info.
@ V3D_AROUND_CENTER_BOUNDS
@ V3D_AROUND_CENTER_MEDIAN
@ V3D_AROUND_LOCAL_ORIGINS
float ED_view3d_grid_view_scale(const Scene *scene, const View3D *v3d, const ARegion *region, const char **r_grid_unit)
void ED_view3d_depth_override(Depsgraph *depsgraph, ARegion *region, View3D *v3d, Object *obact, eV3DDepthOverrideMode mode, ViewDepths **r_depths)
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])
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
#define RNA_ENUM_ITEM_SEPR
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
IndexRange index_range() const
constexpr int64_t first() const
constexpr IndexRange shift(int64_t n) const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr IndexRange drop_front(int64_t n) const
const Value * lookup_ptr(const Key &key) const
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
Value lookup_default(const Key &key, const Value &default_value) const
void add_new(const Key &key, const Value &value)
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr MutableSpan drop_back(const int64_t n) const
constexpr void fill(const T &value) const
constexpr MutableSpan drop_front(const int64_t n) const
constexpr const T & first() const
constexpr int64_t size() const
constexpr const T & last(const int64_t n=0) const
constexpr bool contains(const T &value) const
constexpr const char * c_str() const
std::optional< T > get_if_single() const
void append(const T &value)
void insert(const int64_t insert_index, const T &value)
const T & last(const int64_t n=0) const
IndexRange index_range() const
MutableSpan< T > as_mutable_span()
Span< T > as_span() const
void reverse_curves(const IndexMask &curves_to_reverse)
void remove_attributes_based_on_types()
OffsetIndices< int > points_by_curve() const
IndexRange curves_range() const
void update_curve_types()
MutableAttributeAccessor attributes_for_write()
void resize(int points_num, int curves_num)
void remove_curves(const IndexMask &curves_to_delete, const AttributeFilter &attribute_filter)
AttributeAccessor attributes() const
MutableSpan< int > offsets_for_write()
void transform(const float4x4 &matrix)
VArray< bool > cyclic() const
MutableSpan< bool > cyclic_for_write()
Span< float3 > curve_plane_normals() const
MutableSpan< float > opacities_for_write()
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_topology_changed()
VArray< float > opacities() const
void set_texture_matrices(Span< float4x2 > matrices, const IndexMask &selection)
Span< const TreeNode * > nodes() const
const Map< FramesMapKeyT, GreasePencilFrame > & frames() const
void tag_frames_map_changed()
bool has_drawing_at(const int frame_number) const
float4x4 to_object_space(const Object &object) const
Map< FramesMapKeyT, GreasePencilFrame > & frames_for_write()
const Layer & as_layer() const
float3 reproject(float3 pos) const
IndexMask slice_content(IndexRange range) const
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
void foreach_index(Fn &&fn) const
CCL_NAMESPACE_BEGIN struct Options options
const Depsgraph * depsgraph
static bool is_cyclic(const Nurb *nu)
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
void ED_operatortypes_grease_pencil_edit()
int ED_grease_pencil_join_objects_exec(bContext *C, wmOperator *op)
blender::bke::AttrDomain ED_grease_pencil_edit_selection_domain_get(const ToolSettings *tool_settings)
void GREASE_PENCIL_OT_stroke_trim(wmOperatorType *ot)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
Vector< IndexRange > find_all_ranges(const Span< T > span, const T &value)
IndexMask retrieve_editable_and_selected_elements(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, const bke::AttrDomain selection_domain, IndexMaskMemory &memory)
static void GREASE_PENCIL_OT_extrude(wmOperatorType *ot)
static void GREASE_PENCIL_OT_texture_gradient(wmOperatorType *ot)
bool active_grease_pencil_poll(bContext *C)
static int grease_pencil_clean_loose_invoke(bContext *C, wmOperator *op, const wmEvent *event)
IndexMask retrieve_editable_and_selected_strokes(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
static int grease_pencil_set_material_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_caps_set(wmOperatorType *ot)
static int grease_pencil_move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
blender::bke::CurvesGeometry curves_merge_by_distance(const bke::CurvesGeometry &src_curves, const float merge_distance, const IndexMask &selection, const bke::AttributeFilter &attribute_filter)
static bke::greasepencil::Layer & copy_layer(GreasePencil &grease_pencil_dst, bke::greasepencil::LayerGroup &group_dst, const bke::greasepencil::Layer &layer_src)
static void grease_pencil_reproject_ui(bContext *, wmOperator *op)
IndexRange clipboard_paste_strokes(Main &bmain, Object &object, bke::greasepencil::Drawing &drawing, const float4x4 &transform, const bool keep_world_transform, const bool paste_back)
static void GREASE_PENCIL_OT_stroke_simplify(wmOperatorType *ot)
static int grease_pencil_stroke_merge_by_distance_exec(bContext *C, wmOperator *op)
static void join_object_with_active(Main &bmain, Object &ob_src, Object &ob_dst, VectorSet< Material * > &materials)
static int grease_pencil_clean_loose_exec(bContext *C, wmOperator *op)
bool ensure_active_keyframe(const Scene &scene, GreasePencil &grease_pencil, bke::greasepencil::Layer &layer, const bool duplicate_previous_key, bool &r_inserted_keyframe)
const bke::CurvesGeometry & clipboard_curves()
static int grease_pencil_texture_gradient_modal(bContext *C, wmOperator *op, const wmEvent *event)
static int grease_pencil_copy_strokes_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_set_curve_type(wmOperatorType *ot)
static void toggle_caps(MutableSpan< int8_t > caps, const IndexMask &strokes)
static void GREASE_PENCIL_OT_snap_cursor_to_selected(wmOperatorType *ot)
static Array< int > clipboard_materials_remap(Main &bmain, Object &object)
static int grease_pencil_reproject_exec(bContext *C, wmOperator *op)
static bool grease_pencil_paste_strokes_poll(bContext *C)
bool editable_grease_pencil_point_selection_poll(bContext *C)
static bke::CurvesGeometry extrude_grease_pencil_curves(const bke::CurvesGeometry &src, const IndexMask &points_to_extrude)
static int grease_pencil_reset_uvs_exec(bContext *C, wmOperator *)
static void GREASE_PENCIL_OT_delete(wmOperatorType *ot)
static int grease_pencil_snap_to_grid_exec(bContext *C, wmOperator *)
static int grease_pencil_delete_exec(bContext *C, wmOperator *)
static bool grease_pencil_separate_material(bContext &C, Main &bmain, Scene &scene, ViewLayer &view_layer, Base &base_prev, Object &object_src)
static int grease_pencil_snap_cursor_to_sel_exec(bContext *C, wmOperator *)
static void remove_unused_materials(Main *bmain, Object *object)
static void GREASE_PENCIL_OT_stroke_switch_direction(wmOperatorType *ot)
static int grease_pencil_duplicate_exec(bContext *C, wmOperator *)
Vector< DrawingInfo > retrieve_visible_drawings(const Scene &scene, const GreasePencil &grease_pencil, const bool do_onion_skinning)
static void GREASE_PENCIL_OT_set_active_material(wmOperatorType *ot)
static Clipboard & ensure_grease_pencil_clipboard()
static int grease_pencil_stroke_switch_direction_exec(bContext *C, wmOperator *)
static void remap_material_indices(bke::greasepencil::Drawing &drawing, const Span< int > material_index_map)
static int grease_pencil_set_curve_resolution_exec(bContext *C, wmOperator *op)
IndexMask retrieve_editable_strokes_by_material(Object &object, const bke::greasepencil::Drawing &drawing, const int mat_i, IndexMaskMemory &memory)
static int grease_pencil_snap_to_cursor_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem prop_separate_modes[]
static bke::greasepencil::Layer & find_or_create_layer_in_dst_by_name(const int layer_index, const GreasePencil &grease_pencil_src, GreasePencil &grease_pencil_dst)
static int grease_pencil_stroke_smooth_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_copy(wmOperatorType *ot)
static void GREASE_PENCIL_OT_separate(wmOperatorType *ot)
static int64_t stroke_simplify(const IndexRange points, const bool cyclic, const float epsilon, const FunctionRef< float(int64_t, int64_t, int64_t)> dist_function, MutableSpan< bool > points_to_delete)
static bool grease_pencil_separate_layer(bContext &C, Main &bmain, Scene &scene, ViewLayer &view_layer, Base &base_prev, Object &object_src)
static void GREASE_PENCIL_OT_delete_frame(wmOperatorType *ot)
static bke::greasepencil::LayerGroup & copy_layer_group_recursive(GreasePencil &grease_pencil_dst, bke::greasepencil::LayerGroup &parent_dst, const bke::greasepencil::LayerGroup &group_src, Map< StringRefNull, StringRefNull > &layer_name_map)
static void GREASE_PENCIL_OT_set_curve_resolution(wmOperatorType *ot)
static float4x3 expand_4x2_mat(float4x2 strokemat)
static int grease_pencil_delete_frame_exec(bContext *C, wmOperator *op)
bool editable_grease_pencil_poll(bContext *C)
static void remap_vertex_groups(bke::greasepencil::Drawing &drawing, const Map< StringRefNull, StringRefNull > &vertex_group_map)
static int grease_pencil_dissolve_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_set_uniform_opacity(wmOperatorType *ot)
static float dist_to_interpolated(float3 pos, float3 posA, float3 posB, float val, float valA, float valB)
static int grease_pencil_set_uniform_thickness_exec(bContext *C, wmOperator *op)
static int grease_pencil_cyclical_set_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_move_to_layer(wmOperatorType *ot)
static void GREASE_PENCIL_OT_snap_to_grid(wmOperatorType *ot)
static void GREASE_PENCIL_OT_clean_loose(wmOperatorType *ot)
static void GREASE_PENCIL_OT_stroke_smooth(wmOperatorType *ot)
static int grease_pencil_set_active_material_exec(bContext *C, wmOperator *)
IndexMask retrieve_editable_and_selected_points(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
static int grease_pencil_set_curve_type_exec(bContext *C, wmOperator *op)
static int grease_pencil_stroke_material_set_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_set_handle_type(wmOperatorType *ot)
static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_stroke_reorder(wmOperatorType *ot)
static void GREASE_PENCIL_OT_stroke_merge_by_distance(wmOperatorType *ot)
static int grease_pencil_stroke_reorder_exec(bContext *C, wmOperator *op)
static bool grease_pencil_snap_compute_centroid(const Scene &scene, const Object &object, const GreasePencil &grease_pencil, float3 &r_centroid, float3 &r_min, float3 &r_max)
static const EnumPropertyItem prop_dissolve_types[]
static int grease_pencil_caps_set_exec(bContext *C, wmOperator *op)
Vector< MutableDrawingInfo > retrieve_editable_drawings_from_layer(const Scene &scene, GreasePencil &grease_pencil, const blender::bke::greasepencil::Layer &layer)
static int grease_pencil_texture_gradient_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_stroke_subdivide(wmOperatorType *ot)
static bool grease_pencil_snap_poll(bContext *C)
static int grease_pencil_extrude_exec(bContext *C, wmOperator *)
static Array< int > add_materials_to_map(const GreasePencil &grease_pencil, VectorSet< Material * > &materials)
static int grease_pencil_set_handle_type_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_reproject(wmOperatorType *ot)
static int grease_pencil_move_to_layer_exec(bContext *C, wmOperator *op)
static Map< StringRefNull, StringRefNull > add_vertex_groups(Object &object, GreasePencil &grease_pencil, const ListBase &vertex_group_names)
static bke::CurvesGeometry remove_points_and_split(const bke::CurvesGeometry &curves, const IndexMask &mask)
static void copy_layer_group_content(GreasePencil &grease_pencil_dst, bke::greasepencil::LayerGroup &group_dst, const bke::greasepencil::LayerGroup &group_src, Map< StringRefNull, StringRefNull > &layer_name_map)
static int grease_pencil_separate_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_snap_to_cursor(wmOperatorType *ot)
IndexMask retrieve_editable_strokes(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
Vector< MutableDrawingInfo > retrieve_editable_drawings(const Scene &scene, GreasePencil &grease_pencil)
static struct blender::ed::greasepencil::Clipboard * grease_pencil_clipboard
static void GREASE_PENCIL_OT_stroke_material_set(wmOperatorType *ot)
static void GREASE_PENCIL_OT_set_uniform_thickness(wmOperatorType *ot)
static void GREASE_PENCIL_OT_reset_uvs(wmOperatorType *ot)
static void GREASE_PENCIL_OT_duplicate(wmOperatorType *ot)
static const EnumPropertyItem * material_enum_itemf(bContext *C, PointerRNA *, PropertyRNA *, bool *r_free)
static Object * duplicate_grease_pencil_object(Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base_prev, const GreasePencil &grease_pencil_src)
static void GREASE_PENCIL_OT_paste(wmOperatorType *ot)
static int gpencil_stroke_subdivide_exec(bContext *C, wmOperator *op)
std::mutex grease_pencil_clipboard_lock
static bke::GeometrySet join_geometries_with_transform(Span< bke::GeometrySet > geometries, Span< float4x4 > transforms)
static int grease_pencil_texture_gradient_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void GREASE_PENCIL_OT_cyclical_set(wmOperatorType *ot)
Array< Vector< MutableDrawingInfo > > retrieve_editable_drawings_grouped_per_frame(const Scene &scene, GreasePencil &grease_pencil)
static const EnumPropertyItem prop_cyclical_types[]
static void GREASE_PENCIL_OT_dissolve(wmOperatorType *ot)
bool active_grease_pencil_layer_poll(bContext *C)
static bool grease_pencil_separate_selected(bContext &C, Main &bmain, Scene &scene, ViewLayer &view_layer, Base &base_prev, Object &object_src)
static const EnumPropertyItem prop_greasepencil_deleteframe_types[]
static int grease_pencil_paste_strokes_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_set_material(wmOperatorType *ot)
static Array< bool > get_points_to_dissolve(bke::CurvesGeometry &curves, const IndexMask &mask, const DissolveMode mode)
static Array< int > get_reordered_indices(const IndexRange universe, const IndexMask &selected, const ReorderDirection direction)
static int grease_pencil_set_uniform_opacity_exec(bContext *C, wmOperator *op)
void base_free_and_unlink(Main *bmain, Scene *scene, Object *ob)
void smooth_curve_attribute(const IndexMask &curves_to_smooth, const OffsetIndices< int > points_by_curve, const VArray< bool > &point_selection, const VArray< bool > &cyclic, int iterations, float influence, bool smooth_ends, bool keep_shape, GMutableSpan attribute_data)
T length_squared(const VecBase< T, Size > &a)
MatBase< T, NumCol, NumRow > transpose(const MatBase< T, NumRow, NumCol > &mat)
T distance(const T &a, const T &b)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
CartesianBasis invert(const CartesianBasis &basis)
T midpoint(const T &a, const T &b)
AxisSigned cross(const AxisSigned a, const AxisSigned b)
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
void min_max(const T &value, T &min, T &max)
T distance_squared(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
T max(const T &a, const T &b)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
MatT from_rotation(const RotationT &rotation)
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))
float wrap(float value, float max, float min)
static void unique_name(bNode *node)
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen, int *r_len)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
const EnumPropertyItem rna_enum_curves_handle_type_items[]
const EnumPropertyItem rna_enum_curves_type_items[]
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
const EnumPropertyItem rna_enum_dummy_DEFAULT_items[]
ListBase vertex_group_names
GreasePencilLayerTreeNode base
struct Material ** material_array
ListBase vertex_group_names
GreasePencilDrawingBase ** drawing_array
Curves * get_curves_for_write()
MutableVArraySpan< T > span
Vector< std::pair< uint, int > > materials
int materials_in_source_num
bke::CurvesGeometry curves
bke::greasepencil::Drawing & drawing
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
void(* ui)(bContext *C, wmOperator *op)
void(* cancel)(bContext *C, wmOperator *op)
struct ReportList * reports
void WM_cursor_wait(bool val)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void WM_gesture_straightline_cancel(bContext *C, wmOperator *op)
int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *event)
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)
int WM_operator_props_popup_confirm_ex(bContext *C, wmOperator *op, const wmEvent *, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default)