72#include <fmt/format.h>
201 new_operation->on_stroke_begin(*
C,
sample);
218 if (operation !=
nullptr) {
248 const bool use_duplicate_previous_key = [&]() ->
bool {
273 C, op, use_duplicate_previous_key);
312 ot->name =
"Grease Pencil Draw";
313 ot->idname =
"GREASE_PENCIL_OT_brush_stroke";
314 ot->description =
"Draw a new stroke in the active Grease Pencil object";
361 if (brush ==
nullptr) {
366 bool inserted_keyframe =
false;
369 const bool use_duplicate_previous_key =
true;
371 if (layer->is_editable() &&
373 *scene, grease_pencil, *layer, use_duplicate_previous_key, inserted_keyframe))
375 inserted_keyframe =
true;
378 if (!inserted_keyframe) {
418 ot->name =
"Grease Pencil Sculpt";
419 ot->idname =
"GREASE_PENCIL_OT_sculpt_paint";
420 ot->description =
"Sculpt strokes in the active Grease Pencil object";
462 if (brush ==
nullptr) {
513 ot->name =
"Grease Pencil Paint Weight";
514 ot->idname =
"GREASE_PENCIL_OT_weight_brush_stroke";
515 ot->description =
"Draw weight on stroke points in the active Grease Pencil object";
562 if (brush ==
nullptr) {
567 bool inserted_keyframe =
false;
570 const bool use_duplicate_previous_key =
true;
572 if (layer->is_editable() &&
574 *scene, grease_pencil, *layer, use_duplicate_previous_key, inserted_keyframe))
576 inserted_keyframe =
true;
579 if (!inserted_keyframe) {
619 ot->name =
"Grease Pencil Paint Vertex";
620 ot->idname =
"GREASE_PENCIL_OT_vertex_brush_stroke";
621 ot->description =
"Draw on vertex colors in the active Grease Pencil object";
690 const bool combined_invert = (
invert != brush_invert);
723 bvh_curve_offsets_data[
i] = drawings[
i].drawing.strokes().points_num();
726 bvh_curve_offsets_data, bvh_extension_range.
size());
730 const int max_bvh_lines = bvh_curve_offsets.
data().last();
740 for (
const int i_line : bvh_extension_range.
index_range()) {
745 const int bvh_index = bvh_extension_range[i_line];
746 view_starts[bvh_index] = start;
747 view_ends[bvh_index] = end;
749 const float bb[6] = {start.x, start.y, 0.0f, end.x, end.y, 0.0f};
754 for (
const int i_drawing : drawings.
index_range()) {
763 for (
const int i_curve :
curves.curves_range()) {
765 const IndexRange points = points_by_curve[i_curve];
767 for (
const int i_point : points.
drop_back(1)) {
771 const int bvh_index = bvh_curve_offsets[i_drawing][i_point];
772 view_starts[bvh_index] = start;
773 view_ends[bvh_index] = end;
775 const float bb[6] = {start.x, start.y, 0.0f, end.x, end.y, 0.0f};
783 const int bvh_index = bvh_curve_offsets[i_drawing][points.
last()];
784 view_starts[bvh_index] = start;
785 view_ends[bvh_index] = end;
787 const float bb[6] = {start.x, start.y, 0.0f, end.x, end.y, 0.0f};
806 const RaycastArgs &args = *
static_cast<const RaycastArgs *
>(userdata);
807 if (
ELEM(index, args.ignore_index1, args.ignore_index2)) {
812 const float2 ray_end = ray_start +
float2(ray->direction) * ray->radius;
813 const float2 &line_start = args.starts[index];
814 const float2 &line_end = args.ends[index];
820 if (dist >= hit->dist) {
827 hit->no[0] =
result.lambda;
833 for (
const int i_line : extension_data.
lines.
starts.index_range()) {
840 const int bvh_index = i_line;
841 const int origin_drawing = origin_drawings[i_line];
842 const int origin_point = origin_points[i_line];
843 const int bvh_origin_index = bvh_curve_offsets[origin_drawing][origin_point];
845 RaycastArgs args = {view_starts, view_ends, bvh_index, bvh_origin_index};
852 if (hit.
index >= 0) {
853 const float lambda = hit.
no[0];
858 new_extension_ends[i_line] = extension_data.
lines.
ends[i_line];
862 extension_data.
lines.
ends = std::move(new_extension_ends);
886 feature_points_range.
size());
890 const int max_kd_entries = kd_points_range.
size();
895 KDTree_2d *kdtree = BLI_kdtree_2d_new(max_kd_entries);
898 for (
const int point_i : circles_range.
index_range()) {
904 const int kd_index = circles_range[point_i];
905 view_centers[kd_index] = center;
906 view_radii[kd_index] = radius;
908 BLI_kdtree_2d_insert(kdtree, kd_index, center);
910 for (
const int i_point : feature_points_range.
index_range()) {
914 BLI_kdtree_2d_balance(kdtree);
924 for (
const int point_i : circles_range.
index_range()) {
925 const int kd_index = circles_range[point_i];
926 const float2 center = view_centers[kd_index];
927 const float radius = view_radii[kd_index];
930 BLI_kdtree_2d_range_search_cb_cpp(
934 [&](
const int other_point_i,
const float * ,
float ) {
935 if (other_point_i == kd_index) {
940 connection_lines.starts.append(extension_data.
circles.
centers[point_i]);
941 if (circles_range.
contains(other_point_i)) {
942 connection_lines.ends.append(extension_data.
circles.
centers[other_point_i]);
944 else if (feature_points_range.
contains(other_point_i)) {
946 connection_lines.ends.append(
float3(0));
955 keep_circle_indices.
append(point_i);
959 BLI_kdtree_2d_free(kdtree);
962 extension_data.
lines.
starts.extend(connection_lines.starts);
963 extension_data.
lines.
ends.extend(connection_lines.ends);
990 for (
const int i_drawing : drawings.
index_range()) {
996 const float4x4 layer_to_world = grease_pencil.layer(info.
layer_index).to_world_space(
object);
998 for (
const int i_curve :
curves.curves_range()) {
999 const IndexRange points = points_by_curve[i_curve];
1001 if (cyclic[i_curve]) {
1005 if (points.
size() < 2) {
1013 positions[points.
last(1)]);
1023 origin_drawings.
append(i_drawing);
1028 origin_drawings.
append(i_drawing);
1035 origin_drawings.
append(i_drawing);
1040 origin_drawings.
append(i_drawing);
1057 C, extension_data, origin_drawings, origin_points);
1061 return extension_data;
1073 fmt::format(
"{} ({})",
IFACE_(
"Mode"), (is_extend ?
IFACE_(
"Extend") :
IFACE_(
"Radius"))),
1075 status.item(fmt::format(
"{} ({:.3f})",
1078 ICON_MOUSE_MMB_SCROLL);
1105 if (op_data.show_boundaries) {
1110 const IndexMask curve_mask = info.drawing.strokes().curves_range();
1112 stroke_curves_color, info.drawing.strokes().points_num());
1113 const float4x4 layer_to_world = grease_pencil.layer(info.layer_index).to_world_space(
object);
1114 const bool use_xray =
false;
1115 const float radius_scale = 1.0f;
1129 if (op_data.show_extension) {
1133 const float line_width = 2.0f;
1138 extension_lines_color, lines_range.
size());
1150 extension_circles_color, circles_range.
size());
1170 if (needs_overlay) {
1195 BLI_assert(grease_pencil.has_active_layer());
1196 const IndexRange all_layers = grease_pencil.layers().index_range();
1197 const int active_layer_index = *grease_pencil.get_layer_index(*grease_pencil.get_active_layer());
1199 switch (fill_layer_mode) {
1202 return index != active_layer_index;
1206 return index != active_layer_index + 1;
1210 return index != active_layer_index - 1;
1214 return index <= active_layer_index;
1218 return index >= active_layer_index;
1222 return !grease_pencil.layers()[index]->is_visible();
1244 const bool use_multi_frame_editing = (toolsettings->
gpencil_flags &
1248 const int target_layer_index = *grease_pencil.get_layer_index(target_layer);
1254 if (use_multi_frame_editing) {
1255 for (
const Layer *layer : grease_pencil.layers()) {
1256 for (
const auto [frame_number, frame] : layer->frames().items()) {
1257 if (frame.is_selected()) {
1258 target_frames.
add(frame_number);
1266 for (
const int frame_number : target_frames) {
1268 if (use_duplicate_frame) {
1269 grease_pencil.insert_duplicate_frame(
1270 target_layer, *target_layer.
start_frame_at(frame_number), frame_number,
false);
1273 grease_pencil.insert_frame(target_layer, frame_number);
1280 for (
const int frame_number : target_frames) {
1281 if (
Drawing *target_drawing = grease_pencil.get_editable_drawing_at(target_layer,
1284 MutableDrawingInfo target = {*target_drawing, target_layer_index, frame_number, 1.0f};
1287 for (
const Layer *source_layer : grease_pencil.layers()) {
1288 if (
const Drawing *source_drawing = grease_pencil.get_drawing_at(*source_layer,
1291 const int source_layer_index = *grease_pencil.get_layer_index(*source_layer);
1292 sources.
append({*source_drawing, source_layer_index, frame_number, 0});
1296 drawings.
append({std::move(target), std::move(sources)});
1305 const int iterations = 20;
1329 curves.tag_positions_changed();
1340 const int curve_i = point_to_curve_map[
i];
1341 const IndexRange points = points_by_curve[curve_i];
1342 if (points.
size() <= 2) {
1345 const int local_i =
i - points.
start();
1361 constexpr const bool keep_images =
false;
1380 const std::optional<float> alpha_threshold =
1388 if (!grease_pencil.has_active_layer()) {
1393 scene, grease_pencil, *grease_pencil.get_active_layer());
1398 bool did_create_fill =
false;
1400 const Layer &layer = *grease_pencil.layers()[info.target.layer_index];
1416 op_data.material_index,
1424 if (simplify_levels > 0) {
1429 if (auto_remove_fill_guides) {
1447 Curves *dst_curves_id = curves_new_nomain(dst_curves);
1448 Curves *fill_curves_id = curves_new_nomain(fill_curves);
1452 const int num_new_curves = fill_curves.
curves_num();
1453 const IndexRange new_curves_range = (on_back ?
1464 scene, region, *view_context.
v3d,
object, &layer);
1466 &scene, ®ion, mouse_position, placement);
1468 info.target.drawing.set_texture_matrices(texture_matrices, new_curves_range);
1471 did_create_fill =
true;
1474 if (!did_create_fill) {
1499 Layer *layer = grease_pencil.get_active_layer();
1501 if (layer && layer->is_locked()) {
1504 if (layer ==
nullptr) {
1505 layer = &grease_pencil.add_layer(
"GP_Layer");
1527 op.
customdata = MEM_new<GreasePencilFillOpData>(
1544 if (op_data.overlay_cb_handle) {
1546 op_data.overlay_cb_handle =
nullptr;
1620 const float extension_delta = (op_data.precision ? 0.002f : 0.02f);
1622 switch (event->
val) {
1628 if (op_data.is_extension_drag_active) {
1632 op_data.fill_mouse_pos =
float2(event->
mval);
1637 if (op_data.show_extension) {
1650 op_data.extension_length = std::max(op_data.extension_length - extension_delta, 0.0f);
1655 op_data.extension_length = std::min(op_data.extension_length + extension_delta, 10.0f);
1662 op_data.is_extension_drag_active =
true;
1666 constexpr const float gap = 300.0f;
1667 op_data.extension_mouse_pos = (
math::distance(base_pos, op_data.fill_mouse_pos) >= gap ?
1669 base_pos -
float2(gap, 0));
1674 op_data.is_extension_drag_active =
false;
1683 if (op_data.show_extension) {
1684 op_data.extension_cut = !op_data.extension_cut;
1690 op_data.invert = !op_data.invert;
1694 op_data.precision = !op_data.precision;
1711 if (!op_data.show_extension) {
1713 op_data.fill_mouse_pos =
float2(event->
mval);
1718 switch (event->
type) {
1723 if (!op_data.is_extension_drag_active) {
1730 const float initial_dist =
math::distance(op_data.extension_mouse_pos,
1731 op_data.fill_mouse_pos);
1732 const float current_dist =
math::distance(mouse_pos, op_data.fill_mouse_pos);
1734 float delta = (current_dist - initial_dist) * pixel_size * 0.5f;
1735 op_data.extension_length = std::clamp(op_data.extension_length + delta, 0.0f, 10.0f);
1776 ot->name =
"Grease Pencil Fill";
1777 ot->idname =
"GREASE_PENCIL_OT_fill";
1778 ot->description =
"Fill with color the shape formed by strokes";
1788 ot->srna,
"invert",
false,
"Invert",
"Find boundary of unfilled instead of filled regions");
1792 ot->srna,
"precision",
false,
"Precision",
"Use precision movement for extension lines");
1800 const int current_frame = scene.
r.
cfra;
1801 Layer &layer = grease_pencil.layer(layer_index);
1806 const std::optional<int> previous_key_frame_start = layer.
start_frame_at(current_frame);
1807 const bool has_previous_key = previous_key_frame_start.has_value();
1809 grease_pencil.insert_duplicate_frame(layer, *previous_key_frame_start, current_frame,
false);
1811 return grease_pencil.get_drawing_at(layer, current_frame);
1822 bool changed =
false;
1823 for (
const int drawing_i : drawings.
index_range()) {
1824 const MutableDrawingInfo &info = drawings[drawing_i];
1825 const IndexMask points_to_remove = points_to_remove_per_drawing[drawing_i];
1831 scene, grease_pencil, info.layer_index))
1835 drawing->tag_topology_changed();
1845 if (point.x <
bounds.min.x) {
1848 if (point.x >
bounds.max.x) {
1851 if (point.y <
bounds.min.y) {
1854 if (point.y >
bounds.max.y) {
1863 point,
reinterpret_cast<const int (*)[2]
>(lasso.
data()),
uint(lasso.
size()));
1886 *scene, grease_pencil);
1890 for (const int drawing_i : range) {
1891 const MutableDrawingInfo &info = drawings[drawing_i];
1892 const bke::greasepencil::Layer &layer = grease_pencil.layer(info.layer_index);
1893 const bke::crazyspace::GeometryDeformation deformation =
1894 bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
1895 ob_eval, *object, info.drawing);
1896 const float4x4 layer_to_world = layer.to_world_space(*ob_eval);
1898 const bke::CurvesGeometry &curves = info.drawing.strokes();
1899 Array<float2> screen_space_positions(curves.points_num());
1900 threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange points) {
1901 for (const int point : points) {
1902 const float3 pos = math::transform_point(layer_to_world, deformation.positions[point]);
1903 eV3DProjStatus result = ED_view3d_project_float_global(
1904 region, pos, screen_space_positions[point], V3D_PROJ_TEST_NOP);
1905 if (result != V3D_PROJ_RET_OK) {
1906 screen_space_positions[point] = float2(0);
1911 const OffsetIndices<int> points_by_curve = curves.points_by_curve();
1912 Array<Bounds<float2>> screen_space_curve_bounds(curves.curves_num());
1913 threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange range) {
1914 for (const int curve : range) {
1915 screen_space_curve_bounds[curve] = *bounds::min_max(
1916 screen_space_positions.as_span().slice(points_by_curve[curve]));
1920 IndexMaskMemory &memory = memories[drawing_i];
1921 const IndexMask curve_selection = IndexMask::from_predicate(
1922 curves.curves_range(), GrainSize(512), memory, [&](const int64_t index) {
1926 const IndexRange points = points_by_curve[index];
1927 if (points.size() == 1) {
1928 return is_point_inside_bounds(lasso_bounds_int,
1929 int2(screen_space_positions[points.first()]));
1932 return bounds::intersect(lasso_bounds, screen_space_curve_bounds[index]).has_value();
1935 if (curve_selection.is_empty()) {
1939 Array<bool> points_to_remove(curves.points_num(), false);
1940 curve_selection.foreach_index(GrainSize(512), [&](const int64_t curve_i) {
1941 for (const int point : points_by_curve[curve_i]) {
1942 points_to_remove[point] = is_point_inside_lasso(lasso,
1943 int2(screen_space_positions[point]));
1946 points_to_remove_per_drawing[drawing_i] = IndexMask::from_bools(points_to_remove, memory);
1951 *scene, grease_pencil, drawings.as_span(), points_to_remove_per_drawing);
1962 ot->name =
"Grease Pencil Erase Lasso";
1963 ot->idname =
"GREASE_PENCIL_OT_erase_lasso";
1964 ot->description =
"Erase points in the lasso region";
1994 *scene, grease_pencil);
1998 for (const int drawing_i : range) {
1999 const MutableDrawingInfo &info = drawings[drawing_i];
2000 const bke::greasepencil::Layer &layer = grease_pencil.layer(info.layer_index);
2001 const bke::crazyspace::GeometryDeformation deformation =
2002 bke::crazyspace::get_evaluated_grease_pencil_drawing_deformation(
2003 ob_eval, *object, info.drawing);
2004 const float4x4 layer_to_world = layer.to_world_space(*ob_eval);
2006 const bke::CurvesGeometry &curves = info.drawing.strokes();
2007 Array<float2> screen_space_positions(curves.points_num());
2008 threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange points) {
2009 for (const int point : points) {
2010 const float3 pos = math::transform_point(layer_to_world, deformation.positions[point]);
2011 eV3DProjStatus result = ED_view3d_project_float_global(
2012 region, pos, screen_space_positions[point], V3D_PROJ_TEST_NOP);
2013 if (result != V3D_PROJ_RET_OK) {
2014 screen_space_positions[point] = float2(0);
2019 IndexMaskMemory &memory = memories[drawing_i];
2020 points_to_remove_per_drawing[drawing_i] = IndexMask::from_predicate(
2021 curves.points_range(), GrainSize(4096), memory, [&](const int64_t index) {
2022 return is_point_inside_bounds(box_bounds, int2(screen_space_positions[index]));
2027 const bool changed = remove_points_and_split_from_drawings(
2028 *scene, grease_pencil, drawings.as_span(), points_to_remove_per_drawing);
2039 ot->name =
"Grease Pencil Box Erase";
2040 ot->idname =
"GREASE_PENCIL_OT_erase_box";
2041 ot->description =
"Erase points in the box region";
2083 "EXTENSION_MODE_TOGGLE",
2085 "Toggle Extension Mode",
2088 "EXTENSION_LENGTHEN",
2090 "Lengthen Extensions",
2097 {0,
nullptr, 0,
nullptr,
nullptr},
Functions to insert, delete or modify keyframes.
void BKE_brush_init_gpencil_settings(Brush *brush)
void BKE_brush_tag_unsaved_changes(Brush *brush)
wmWindow * CTX_wm_window(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ToolSettings * CTX_data_tool_settings(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
Low-level operations for curves.
Low-level operations for grease pencil.
Material * BKE_grease_pencil_object_material_ensure_from_brush(Main *bmain, Object *ob, Brush *brush)
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
int BKE_object_material_index_get(Object *ob, const Material *ma)
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Paint * BKE_paint_get_active_from_context(const bContext *C)
Brush * BKE_paint_brush(Paint *paint)
PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define BLI_assert_unreachable()
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
void(*)(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) BVHTree_RayCastCallback
void BLI_bvhtree_balance(BVHTree *tree)
void BLI_bvhtree_free(BVHTree *tree)
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
A KD-tree for nearest neighbor search.
bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], unsigned int nr)
#define BLI_SCOPED_DEFER(function_to_defer)
bool BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2])
void DEG_id_tag_update(ID *id, unsigned int flags)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ GPVERTEX_BRUSH_TYPE_BLUR
@ GPVERTEX_BRUSH_TYPE_DRAW
@ GPVERTEX_BRUSH_TYPE_TINT
@ GPVERTEX_BRUSH_TYPE_REPLACE
@ GPVERTEX_BRUSH_TYPE_AVERAGE
@ GPVERTEX_BRUSH_TYPE_SMEAR
@ GPAINT_BRUSH_TYPE_ERASE
@ GP_BRUSH_FILL_SHOW_HELPLINES
@ GP_BRUSH_FILL_AUTO_REMOVE_FILL_GUIDES
@ GP_BRUSH_FILL_STROKE_COLLIDE
@ GP_BRUSH_MATERIAL_PINNED
@ GP_BRUSH_FILL_SHOW_EXTENDLINES
@ GPWEIGHT_BRUSH_TYPE_AVERAGE
@ GPWEIGHT_BRUSH_TYPE_DRAW
@ GPWEIGHT_BRUSH_TYPE_SMEAR
@ GPWEIGHT_BRUSH_TYPE_BLUR
@ GPSCULPT_BRUSH_TYPE_SMOOTH
@ GPSCULPT_BRUSH_TYPE_PUSH
@ GPSCULPT_BRUSH_TYPE_CLONE
@ GPSCULPT_BRUSH_TYPE_TWIST
@ GPSCULPT_BRUSH_TYPE_RANDOMIZE
@ GPSCULPT_BRUSH_TYPE_GRAB
@ GPSCULPT_BRUSH_TYPE_PINCH
@ GPSCULPT_BRUSH_TYPE_THICKNESS
@ GPSCULPT_BRUSH_TYPE_STRENGTH
@ GP_FILL_GPLMODE_ALL_ABOVE
@ GP_FILL_GPLMODE_VISIBLE
@ GP_FILL_GPLMODE_ALL_BELOW
@ GP_TOOL_FLAG_RETAIN_LAST
@ GP_TOOL_FLAG_PAINT_ONBACK
@ GP_USE_MULTI_FRAME_EDITING
#define OPERATOR_RETVAL_CHECK(ret)
void ED_workspace_status_text(bContext *C, const char *str)
void ED_region_tag_redraw(ARegion *region)
void * ED_region_draw_cb_activate(ARegionType *art, void(*draw)(const bContext *, ARegion *, void *), void *customdata, int type)
#define REGION_DRAW_POST_VIEW
bool ED_region_draw_cb_exit(ARegionType *art, void *handle)
float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
Read Guarded memory(de)allocation.
BPy_StructRNA * depsgraph
bool contains(const Key &key) const
void append(const T &value)
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
Span< T > as_span() const
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
constexpr int64_t first() const
constexpr IndexRange drop_back(int64_t n) const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr IndexRange after(int64_t n) const
constexpr int64_t start() const
constexpr bool contains(int64_t value) const
constexpr IndexRange index_range() const
constexpr IndexRange index_range() const
static VArray from_std_func(const int64_t size, std::function< T(int64_t index)> get_func)
static VArray from_single(T value, const int64_t size)
static VArray from_span(Span< T > values)
void append(const T &value)
IndexRange index_range() const
void reserve(const int64_t min_capacity)
Span< T > as_span() const
bool contains(StringRef attribute_id) const
IndexRange curves_range() const
MutableAttributeAccessor attributes_for_write()
void tag_topology_changed()
AttributeAccessor attributes() const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
const bke::CurvesGeometry & strokes() const
float4x4 to_world_space(const Object &object) const
const Map< FramesMapKeyT, GreasePencilFrame > & frames() const
bool has_drawing_at(const int frame_number) const
std::optional< int > start_frame_at(int frame_number) const
virtual void on_stroke_extended(const bContext &C, const InputSample &extension_sample)=0
virtual void on_stroke_done(const bContext &C)=0
static bool is_cyclic(const Nurb *nu)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
float length(VecOp< float, D >) RET
void ED_filltool_modal_keymap(wmKeyConfig *keyconf)
void ED_operatortypes_grease_pencil_draw()
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
bool is_autokey_on(const Scene *scene)
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
constexpr float LEGACY_RADIUS_CONVERSION_FACTOR
CurvesGeometry curves_copy_point_selection(const CurvesGeometry &curves, const IndexMask &points_to_copy, const AttributeFilter &attribute_filter)
std::optional< Bounds< T > > min_max(const std::optional< Bounds< T > > &a, const T &b)
void draw_lines(const float4x4 &transform, IndexRange indices, Span< float3 > start_positions, Span< float3 > end_positions, const VArray< ColorGeometry4f > &colors, float line_width)
void draw_grease_pencil_strokes(const RegionView3D &rv3d, const int2 &win_size, const Object &object, const bke::greasepencil::Drawing &drawing, const float4x4 &transform, const IndexMask &strokes_mask, const VArray< ColorGeometry4f > &colors, const bool use_xray, const float radius_scale)
void draw_circles(const float4x4 &transform, const IndexRange indices, Span< float3 > centers, const VArray< float > &radii, const VArray< ColorGeometry4f > &colors, const float2 &viewport_size, const float line_width, const bool fill)
bool ensure_active_keyframe(const Scene &scene, GreasePencil &grease_pencil, bke::greasepencil::Layer &layer, const bool duplicate_previous_key, bool &r_inserted_keyframe)
bool grease_pencil_vertex_painting_poll(bContext *C)
Vector< DrawingInfo > retrieve_visible_drawings(const Scene &scene, const GreasePencil &grease_pencil, const bool do_onion_skinning)
bool has_editable_layer(const GreasePencil &grease_pencil)
bool grease_pencil_sculpting_poll(bContext *C)
bool grease_pencil_weight_painting_poll(bContext *C)
wmOperatorStatus grease_pencil_draw_operator_invoke(bContext *C, wmOperator *op, const bool use_duplicate_previous_key)
bool remove_fill_guides(bke::CurvesGeometry &curves)
Vector< MutableDrawingInfo > retrieve_editable_drawings(const Scene &scene, GreasePencil &grease_pencil)
float4x2 calculate_texture_space(const Scene *scene, const ARegion *region, const float2 &mouse, const DrawingPlacement &placement)
bool grease_pencil_painting_poll(bContext *C)
std::unique_ptr< GreasePencilStrokeOperation > new_vertex_replace_operation()
std::unique_ptr< GreasePencilStrokeOperation > new_erase_operation(const bool temp_eraser)
std::unique_ptr< GreasePencilStrokeOperation > new_weight_paint_average_operation()
std::unique_ptr< GreasePencilStrokeOperation > new_strength_operation(BrushStrokeMode stroke_mode)
std::unique_ptr< GreasePencilStrokeOperation > new_grab_operation(BrushStrokeMode stroke_mode)
std::unique_ptr< GreasePencilStrokeOperation > new_weight_paint_blur_operation()
std::unique_ptr< GreasePencilStrokeOperation > new_tint_operation(bool temp_eraser=false)
std::unique_ptr< GreasePencilStrokeOperation > new_vertex_paint_operation(BrushStrokeMode stroke_mode)
std::unique_ptr< GreasePencilStrokeOperation > new_paint_operation(bool do_fill_guides=false)
std::unique_ptr< GreasePencilStrokeOperation > new_clone_operation(BrushStrokeMode stroke_mode)
std::unique_ptr< GreasePencilStrokeOperation > new_randomize_operation(BrushStrokeMode stroke_mode)
std::unique_ptr< GreasePencilStrokeOperation > new_vertex_blur_operation()
std::unique_ptr< GreasePencilStrokeOperation > new_weight_paint_draw_operation(const BrushStrokeMode &stroke_mode)
std::unique_ptr< GreasePencilStrokeOperation > new_thickness_operation(BrushStrokeMode stroke_mode)
std::unique_ptr< GreasePencilStrokeOperation > new_pinch_operation(BrushStrokeMode stroke_mode)
std::unique_ptr< GreasePencilStrokeOperation > new_push_operation(BrushStrokeMode stroke_mode)
std::unique_ptr< GreasePencilStrokeOperation > new_weight_paint_smear_operation()
std::unique_ptr< GreasePencilStrokeOperation > new_vertex_average_operation()
std::unique_ptr< GreasePencilStrokeOperation > new_twist_operation(BrushStrokeMode stroke_mode)
std::unique_ptr< GreasePencilStrokeOperation > new_smooth_operation(BrushStrokeMode stroke_mode, bool temp_smooth=false)
std::unique_ptr< GreasePencilStrokeOperation > new_vertex_smear_operation()
static void grease_pencil_fill_extension_lines_from_circles(const bContext &C, ed::greasepencil::ExtensionData &extension_data, Span< int >, Span< int >)
static bool is_point_inside_bounds(const Bounds< int2 > bounds, const int2 point)
static bool stroke_test_start(bContext *C, wmOperator *op, const float mouse[2])
static bool is_point_inside_lasso(const Array< int2 > lasso, const int2 point)
static bool grease_pencil_weight_brush_stroke_poll(bContext *C)
static void grease_pencil_sculpt_paint_cancel(bContext *C, wmOperator *op)
static wmOperatorStatus grease_pencil_weight_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void grease_pencil_fill_exit(bContext &C, wmOperator &op)
static wmOperatorStatus grease_pencil_vertex_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool remove_points_and_split_from_drawings(const Scene &scene, GreasePencil &grease_pencil, const Span< ed::greasepencil::MutableDrawingInfo > drawings, const Span< IndexMask > points_to_remove_per_drawing)
static void stroke_update_step(bContext *C, wmOperator *op, PaintStroke *, PointerRNA *stroke_element)
static void GREASE_PENCIL_OT_erase_lasso(wmOperatorType *ot)
static wmOperatorStatus grease_pencil_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool grease_pencil_sculpt_paint_poll(bContext *C)
static void grease_pencil_fill_cancel(bContext *C, wmOperator *op)
static wmOperatorStatus grease_pencil_sculpt_paint_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void GREASE_PENCIL_OT_weight_brush_stroke(wmOperatorType *ot)
static wmOperatorStatus grease_pencil_vertex_brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
static bool stroke_get_location(bContext *C, float out[3], const float mouse[2], bool)
static void grease_pencil_brush_stroke_cancel(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_brush_stroke(wmOperatorType *ot)
void paint_stroke_cancel(bContext *C, wmOperator *op, PaintStroke *stroke)
static void GREASE_PENCIL_OT_vertex_brush_stroke(wmOperatorType *ot)
static void stroke_done(const bContext *C, PaintStroke *stroke)
static void GREASE_PENCIL_OT_sculpt_paint(wmOperatorType *ot)
static void grease_pencil_fill_status_indicators(bContext &C, const GreasePencilFillOpData &op_data)
static wmOperatorStatus grease_pencil_fill_event_modal_map(bContext *C, wmOperator *op, const wmEvent *event)
static bke::greasepencil::Drawing * get_current_drawing_or_duplicate_for_autokey(const Scene &scene, GreasePencil &grease_pencil, const int layer_index)
static bool grease_pencil_vertex_brush_stroke_poll(bContext *C)
static void grease_pencil_vertex_brush_stroke_cancel(bContext *C, wmOperator *op)
wmOperatorStatus paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintStroke **stroke_p)
static wmOperatorStatus grease_pencil_sculpt_paint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus grease_pencil_weight_brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
static bke::CurvesGeometry simplify_fixed(bke::CurvesGeometry &curves, const int step)
static wmOperatorStatus grease_pencil_erase_box_exec(bContext *C, wmOperator *op)
static void stroke_redraw(const bContext *C, PaintStroke *, bool)
static void GREASE_PENCIL_OT_erase_box(wmOperatorType *ot)
static VArray< bool > get_fill_boundary_layers(const GreasePencil &grease_pencil, eGP_FillLayerModes fill_layer_mode)
static Vector< FillToolTargetInfo > ensure_editable_drawings(const Scene &scene, GreasePencil &grease_pencil, bke::greasepencil::Layer &target_layer)
static void grease_pencil_weight_brush_stroke_cancel(bContext *C, wmOperator *op)
static wmOperatorStatus grease_pencil_fill_invoke(bContext *C, wmOperator *op, const wmEvent *)
static void GREASE_PENCIL_OT_fill(wmOperatorType *ot)
static void grease_pencil_fill_overlay_cb(const bContext *C, ARegion *, void *arg)
void * paint_stroke_mode_data(PaintStroke *stroke)
static wmOperatorStatus grease_pencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus grease_pencil_erase_lasso_exec(bContext *C, wmOperator *op)
static bool grease_pencil_apply_fill(bContext &C, wmOperator &op, const wmEvent &event)
static wmOperatorStatus grease_pencil_brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void grease_pencil_fill_update_overlay(const ARegion ®ion, GreasePencilFillOpData &op_data)
PaintStroke * paint_stroke_new(bContext *C, wmOperator *op, StrokeGetLocation get_location, StrokeTestStart test_start, StrokeUpdateStep update_step, StrokeRedraw redraw, StrokeDone done, int event_type)
static ed::greasepencil::ExtensionData grease_pencil_fill_get_extension_data(const bContext &C, const GreasePencilFillOpData &op_data)
static void grease_pencil_fill_extension_cut(const bContext &C, ed::greasepencil::ExtensionData &extension_data, Span< int > origin_drawings, Span< int > origin_points)
static void smooth_fill_strokes(bke::CurvesGeometry &curves, const IndexMask &stroke_mask)
static std::unique_ptr< GreasePencilStrokeOperation > get_stroke_operation(bContext &C, wmOperator *op)
static bool grease_pencil_brush_stroke_poll(bContext *C)
static void grease_pencil_update_extend(bContext &C, GreasePencilFillOpData &op_data)
void paint_stroke_set_mode_data(PaintStroke *stroke, std::unique_ptr< PaintModeData > mode_data)
static bool grease_pencil_fill_init(bContext &C, wmOperator &op)
bke::GeometrySet join_geometries(Span< bke::GeometrySet > geometries, const bke::AttributeFilter &attribute_filter, const std::optional< Span< bke::GeometryComponent::Type > > &component_types_to_join=std::nullopt, bool allow_merging_instance_references=true)
bke::CurvesGeometry remove_points_and_split(const bke::CurvesGeometry &curves, const IndexMask &mask)
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 pow(const T &x, const T &power)
isect_result< VecBase< T, Size > > isect_seg_seg(const VecBase< T, Size > &v1, const VecBase< T, Size > &v2, const VecBase< T, Size > &v3, const VecBase< T, Size > &v4)
T distance(const T &a, const T &b)
QuaternionBase< T > normalize_and_get_length(const QuaternionBase< T > &q, T &out_length)
T average(const VecBase< T, Size > &a)
T interpolate(const T &a, const T &b, const FactorT &t)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > to_scale(const MatBase< T, NumCol, NumRow > &mat)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
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
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
MatBase< float, 4, 2 > float4x2
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
void paint_stroke_operator_properties(wmOperatorType *ot)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
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_flag(PropertyRNA *prop, PropertyFlag flag)
ARegionRuntimeHandle * runtime
struct CurveMapping * curve_sensitivity
struct CurveMapping * curve_strength
struct CurveMapping * curve_jitter
struct CurveMapping * curve_rand_pressure
struct CurveMapping * curve_rand_strength
struct CurveMapping * curve_rand_uv
struct Material * material
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
char gpencil_sculpt_brush_type
struct CurveMapping * curve_rand_value
char gpencil_weight_brush_type
struct BrushGpencilSettings * gpencil_settings
char gpencil_vertex_brush_type
struct ToolSettings * toolsettings
VecBase< T, 2 > xy() const
static GeometrySet from_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Curves * get_curves_for_write()
const bke::greasepencil::Drawing & drawing
struct blender::ed::greasepencil::ExtensionData::@020012301277233322117257155067364007210377153176 lines
struct blender::ed::greasepencil::ExtensionData::@137034222204205036366070174242001167366362372317 circles
blender::bke::greasepencil::Layer & layer
bool is_extension_drag_active
eGP_FillExtendModes extension_mode
static GreasePencilFillOpData from_context(bContext &C, blender::bke::greasepencil::Layer &layer, const int material_index, const bool invert, const bool precision)
float2 extension_mouse_pos
wmOperatorStatus(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
struct ReportList * reports
struct wmOperatorType * type
void WM_cursor_modal_set(wmWindow *win, int val)
void WM_cursor_set(wmWindow *win, int curs)
void WM_cursor_modal_restore(wmWindow *win)
void WM_main_add_notifier(uint type, void *reference)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_gesture_box_cancel(bContext *C, wmOperator *op)
Array< int2 > WM_gesture_lasso_path_to_array(bContext *, wmOperator *op)
wmOperatorStatus WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void WM_gesture_lasso_cancel(bContext *C, wmOperator *op)
wmOperatorStatus WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmKeyMap * WM_modalkeymap_ensure(wmKeyConfig *keyconf, const char *idname, const EnumPropertyItem *items)
void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
wmKeyMap * WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
blender::Bounds< blender::int2 > WM_operator_properties_border_to_bounds(wmOperator *op)
void WM_operator_properties_border(wmOperatorType *ot)
void WM_operator_properties_gesture_lasso(wmOperatorType *ot)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))