44 return std::clamp(index,
int(range.first()),
int(range.last()));
56 const int curve_index,
60 if (points.is_empty()) {
65 const IndexRange segments = segments_by_curve[curve_index];
67 for (
const int segment_i : segments) {
71 if (segment_i < segments.
last()) {
72 const int next_segment_i = segment_i + 1;
77 const int first_point_i = (segment_fraction == 0.0f ?
80 const int next_first_point_i = (next_segment_fraction == 0.0f ?
81 next_segment_point_i :
91 const int first_point_i = (segment_fraction == 0.0f ?
95 const int next_first_point_i = (first_segment_fraction == 0.0f ?
96 first_segment_point_i :
103 fn(segment_i, points_range1, points_range2);
106 return segments.
size();
122 curves, selection_domain, create_type, attribute_name);
142 if (attribute_name !=
".selection") {
147 if (point_selection_mask.
is_empty()) {
153 curves, point_selection_mask,
GrainSize(512), memory);
155 const OffsetIndices points_by_curve = curves.points_by_curve();
160 curves, changed_curve_mask, screen_space_positions, tree_data, tree_data_range);
169 point_selection_mask.
to_bools(changed_points);
172 for (
const int point_i :
range) {
173 if (changed_points[point_i]) {
180 for (
const int point_i :
range) {
187 for (const int curve_i : range) {
188 const IndexRange points = points_by_curve[curve_i];
190 const int num_segments = foreach_curve_segment(
194 [&](const int , const IndexRange points1, const IndexRange points2) {
195 if (test_points_range(points1) || test_points_range(points2)) {
196 update_points_range(points1);
197 update_points_range(points2);
200 if (num_segments == 0 && test_points_range(points)) {
202 update_points_range(points);
207 attribute_writer.finish();
227 bool changed =
false;
229 ed::greasepencil::retrieve_editable_drawings_grouped_per_frame(*vc->
scene, grease_pencil);
232 if (drawings.is_empty()) {
235 const int frame_number = drawings.first().frame_number;
239 BLI_SCOPED_DEFER([&]() { ed::greasepencil::free_curves_2d_bvh_data(tree_data); });
240 if (use_segment_selection) {
241 tree_data = ed::greasepencil::build_curves_2d_bvh_from_visible(
242 *vc, *ob_eval, grease_pencil, drawings, frame_number);
246 for (
const int i_drawing : drawings.index_range()) {
253 ed::curves::get_curves_selection_attribute_names(curves);
256 const IndexMask elements = ed::greasepencil::retrieve_editable_elements(
257 *
object, info, selection_domain, memory);
258 if (elements.is_empty()) {
262 for (
const StringRef attribute_name : selection_attribute_names) {
263 const IndexMask changed_element_mask = select_operation(
264 info, elements, attribute_name, memory);
269 curves.attributes_for_write().lookup_for_write_span(attribute_name))
271 ed::curves::fill_selection_false(selection.span);
276 if (use_segment_selection) {
279 const IndexRange tree_data_range = tree_data_by_drawing[i_drawing];
280 changed |= ed::greasepencil::apply_mask_as_segment_selection(curves,
281 changed_element_mask,
289 changed |= ed::greasepencil::apply_mask_as_selection(curves,
290 changed_element_mask,
325 *
object, info, selection_domain, memory);
326 if (selectable_elements.
is_empty()) {
349 ot->
name =
"(De)select All Strokes";
350 ot->
idname =
"GREASE_PENCIL_OT_select_all";
367 ed::greasepencil::selection_update(&vc,
388 ot->
idname =
"GREASE_PENCIL_OT_select_more";
403 ed::greasepencil::selection_update(&vc,
424 ot->
idname =
"GREASE_PENCIL_OT_select_less";
442 const IndexMask selectable_strokes = ed::greasepencil::retrieve_editable_strokes(
444 if (selectable_strokes.
is_empty()) {
460 ot->
name =
"Select Linked";
461 ot->
idname =
"GREASE_PENCIL_OT_select_linked";
462 ot->
description =
"Select all points in curves with any point selection";
488 ed::greasepencil::selection_update(
496 *
object, info, selection_domain, memory);
497 if (selectable_elements.
is_empty()) {
518 ot->
name =
"Select Random";
519 ot->
idname =
"GREASE_PENCIL_OT_select_random";
520 ot->
description =
"Selects random points from the current strokes selection";
552 ot->
name =
"Select Alternate";
553 ot->
idname =
"GREASE_PENCIL_OT_select_alternate";
554 ot->
description =
"Select alternated points in strokes with already selected points";
565 "(De)select the first and last point of each stroke");
577 {
int(SelectSimilarMode::LAYER),
"LAYER", 0,
"Layer",
""},
578 {
int(SelectSimilarMode::MATERIAL),
"MATERIAL", 0,
"Material",
""},
579 {
int(SelectSimilarMode::VERTEX_COLOR),
"VERTEX_COLOR", 0,
"Vertex Color",
""},
580 {
int(SelectSimilarMode::RADIUS),
"RADIUS", 0,
"Radius",
""},
581 {
int(SelectSimilarMode::OPACITY),
"OPACITY", 0,
"Opacity",
""},
582 {0,
nullptr, 0,
nullptr,
nullptr},
592 CPPType::get<T>().default_construct(&default_value);
596 ".selection", domain,
true);
597 const VArraySpan<T> values = *attributes.lookup_or_default<T>(
598 attribute_id, domain, default_value);
601 threading::parallel_for(
603 Set<T> &local_value_set = value_set_by_thread.local();
604 for (const int i : range) {
606 local_value_set.add(values[i]);
611 for (
const Set<T> &local_value_set : value_set_by_thread) {
613 for (
const T &key : local_value_set) {
614 r_value_set.add(key);
619template<
typename T,
typename DistanceFn>
626 DistanceFn distance_fn)
631 CPPType::get<T>().default_construct(&default_value);
644 const int domain_size = attributes.domain_size(domain);
646 attributes.lookup_or_add_for_write_span<
bool>(
650 const VArraySpan<T> values = *attributes.lookup_or_default<T>(
651 attribute_id, domain, default_value);
654 const IndexMask mask = ed::greasepencil::retrieve_editable_points(
657 mask.foreach_index(
GrainSize(1024), [&](
const int index) {
658 if (selection_writer.
span[index]) {
661 for (
const T &test_value : selected_values) {
662 if (distance_fn(values[index], test_value) <= threshold) {
663 selection_writer.
span[index] =
true;
668 selection_writer.
finish();
684 *info.drawing.strokes().attributes().lookup_or_default<
bool>(
".selection", domain,
true);
685 for (
const int i : selection.index_range()) {
687 selected_layers.
add(info.layer_index);
703 ed::curves::select_all(
721 case SelectSimilarMode::LAYER:
724 case SelectSimilarMode::MATERIAL:
725 select_similar_by_value<int>(
734 case SelectSimilarMode::VERTEX_COLOR:
735 select_similar_by_value<ColorGeometry4f>(
746 case SelectSimilarMode::RADIUS:
747 select_similar_by_value<float>(
754 [](
const float a,
const float b) ->
float {
return math::distance(a,
b); });
756 case SelectSimilarMode::OPACITY:
757 select_similar_by_value<float>(
764 [](
const float a,
const float b) ->
float {
return math::distance(a,
b); });
776 ot->
name =
"Select Similar";
777 ot->
idname =
"GREASE_PENCIL_OT_select_similar";
778 ot->
description =
"Select all strokes with similar characteristics";
800 ed::greasepencil::selection_update(
807 const IndexMask selectable_strokes = ed::greasepencil::retrieve_editable_strokes(
809 return ed::curves::end_points(
810 info.
drawing.
strokes(), selectable_strokes, amount_start, amount_end,
false, memory);
824 ot->
idname =
"GREASE_PENCIL_OT_select_ends";
838 "Number of points to select from the start",
847 "Number of points to select from the end",
877 if (curves.points_num() == 0) {
884 const std::optional<bke::AttributeMetaData> meta_data = attributes.
lookup_meta_data(
886 if ((!meta_data) || (meta_data->domain == domain)) {
892 if (domain == bke::AttrDomain::Curve) {
897 const GVArray src = *attributes.lookup(
".selection", domain);
900 void *dst =
MEM_malloc_arrayN(attributes.domain_size(domain), type.size(), __func__);
903 attributes.remove(
".selection");
904 if (!attributes.add(
".selection",
906 bke::cpp_type_to_custom_data_type(type),
936 ot->
description =
"Change the selection mode for Grease Pencil strokes";
954 const int material_index =
object->actcol - 1;
956 if (material_index == -1) {
966 *
object, info.
drawing, material_index, memory);
972 index_mask::masked_fill(selection.span.typed<
bool>(),
select, strokes);
985 ot->
name =
"Select Material";
986 ot->
idname =
"GREASE_PENCIL_OT_material_select";
987 ot->
description =
"Select/Deselect all Grease Pencil strokes using current material";
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
ToolSettings * CTX_data_tool_settings(const bContext *C)
Low-level operations for curves.
Low-level operations for grease pencil.
#define BLI_SCOPED_DEFER(function_to_defer)
void DEG_id_tag_update(ID *id, unsigned int flags)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ OB_MODE_VERTEX_GREASE_PENCIL
@ OB_MODE_SCULPT_GREASE_PENCIL
Object is a sort of wrapper for general info.
@ GP_SCULPT_MASK_SELECTMODE_POINT
@ GP_SCULPT_MASK_SELECTMODE_STROKE
@ GP_SCULPT_MASK_SELECTMODE_SEGMENT
@ GP_VERTEX_MASK_SELECTMODE_SEGMENT
@ GP_VERTEX_MASK_SELECTMODE_STROKE
@ GP_VERTEX_MASK_SELECTMODE_POINT
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
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 or normal between and object coordinate space Combine Create a color from its and value channels VERTEX_COLOR
static unsigned long seed
const CPPType & type() const
void materialize(void *dst) const
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
static constexpr IndexRange from_begin_end_inclusive(const int64_t begin, const int64_t last)
bool contains(const Key &key) const
constexpr IndexRange index_range() const
std::optional< AttributeMetaData > lookup_meta_data(const StringRef attribute_id) const
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
void to_bools(MutableSpan< bool > r_bools) const
void foreach_index(Fn &&fn) const
IndexRange index_range() const
local_group_size(16, 16) .push_constant(Type b
static int select_linked_exec(bContext *C, wmOperator *)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
blender::bke::AttrDomain ED_grease_pencil_sculpt_selection_domain_get(const ToolSettings *tool_settings)
bool ED_grease_pencil_sculpt_segment_selection_enabled(const ToolSettings *tool_settings)
blender::bke::AttrDomain ED_grease_pencil_edit_selection_domain_get(const ToolSettings *tool_settings)
bool ED_grease_pencil_edit_segment_selection_enabled(const ToolSettings *tool_settings)
blender::bke::AttrDomain ED_grease_pencil_vertex_selection_domain_get(const ToolSettings *tool_settings)
void ED_operatortypes_grease_pencil_select()
blender::bke::AttrDomain ED_grease_pencil_selection_domain_get(const ToolSettings *tool_settings, const Object *object)
bool ED_grease_pencil_segment_selection_enabled(const ToolSettings *tool_settings, const Object *object)
bool ED_grease_pencil_vertex_segment_selection_enabled(const ToolSettings *tool_settings)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
static int select_all_exec(bContext *C, wmOperator *op)
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
void select_linked(bke::CurvesGeometry &curves, const IndexMask &curves_mask)
void apply_selection_operation_at_index(GMutableSpan selection, const int index, const eSelectOp sel_op)
static bool has_anything_selected(const Span< Curves * > curves_ids)
void select_all(bke::CurvesGeometry &curves, const IndexMask &mask, const bke::AttrDomain selection_domain, int action)
void select_alternate(bke::CurvesGeometry &curves, const IndexMask &curves_mask, const bool deselect_ends)
IndexMask curve_mask_from_points(const bke::CurvesGeometry &curves, const IndexMask &point_mask, const GrainSize grain_size, IndexMaskMemory &memory)
IndexMask select_adjacent_mask(const bke::CurvesGeometry &curves, const IndexMask &curves_mask, const StringRef attribute_name, const bool deselect, IndexMaskMemory &memory)
bke::GSpanAttributeWriter ensure_selection_attribute(bke::CurvesGeometry &curves, bke::AttrDomain selection_domain, eCustomDataType create_type, StringRef attribute_name)
static void GREASE_PENCIL_OT_select_linked(wmOperatorType *ot)
static void GREASE_PENCIL_OT_select_more(wmOperatorType *ot)
bool selection_update(const ViewContext *vc, const eSelectOp sel_op, SelectionUpdateFunc select_operation)
static int select_ends_exec(bContext *C, wmOperator *op)
bool editable_grease_pencil_point_selection_poll(bContext *C)
IndexMask retrieve_editable_elements(Object &object, const MutableDrawingInfo &info, const bke::AttrDomain selection_domain, IndexMaskMemory &memory)
static void select_similar_by_value(Scene *scene, Object *object, GreasePencil &grease_pencil, const bke::AttrDomain domain, const StringRef attribute_id, float threshold, DistanceFn distance_fn)
static int select_set_mode_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem select_similar_mode_items[]
CurveSegmentsData find_curve_segments(const bke::CurvesGeometry &curves, const IndexMask &curve_mask, const Span< float2 > screen_space_positions, const Curves2DBVHTree &tree_data, const IndexRange tree_data_range)
static void select_similar_by_layer(Scene *scene, Object *object, GreasePencil &grease_pencil, bke::AttrDomain domain)
IndexMask retrieve_editable_strokes_by_material(Object &object, const bke::greasepencil::Drawing &drawing, const int mat_i, IndexMaskMemory &memory)
static int select_alternate_exec(bContext *C, wmOperator *op)
static int grease_pencil_material_select_exec(bContext *C, wmOperator *op)
int clamp_range(const IndexRange range, const int index)
bool editable_grease_pencil_poll(bContext *C)
static int foreach_curve_segment(const CurveSegmentsData &segment_data, const int curve_index, const IndexRange points, Fn &&fn)
static void GREASE_PENCIL_OT_select_less(wmOperatorType *ot)
void insert_selected_values(const bke::CurvesGeometry &curves, const bke::AttrDomain domain, const StringRef attribute_id, blender::Set< T > &r_value_set)
bool apply_mask_as_selection(bke::CurvesGeometry &curves, const IndexMask &selection_mask, const bke::AttrDomain selection_domain, const StringRef attribute_name, const GrainSize grain_size, const eSelectOp sel_op)
static void GREASE_PENCIL_OT_select_all(wmOperatorType *ot)
static void GREASE_PENCIL_OT_select_alternate(wmOperatorType *ot)
static void GREASE_PENCIL_OT_select_ends(wmOperatorType *ot)
static void GREASE_PENCIL_OT_select_similar(wmOperatorType *ot)
Vector< MutableDrawingInfo > retrieve_editable_drawings(const Scene &scene, GreasePencil &grease_pencil)
static void GREASE_PENCIL_OT_select_random(wmOperatorType *ot)
static void GREASE_PENCIL_OT_material_select(wmOperatorType *ot)
static void GREASE_PENCIL_OT_set_selection_mode(wmOperatorType *ot)
bool apply_mask_as_segment_selection(bke::CurvesGeometry &curves, const IndexMask &point_selection_mask, const StringRef attribute_name, const Curves2DBVHTree &tree_data, const IndexRange tree_data_range, const GrainSize grain_size, const eSelectOp sel_op)
static int select_similar_exec(bContext *C, wmOperator *op)
T distance(const T &a, const T &b)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
uint64_t get_default_hash(const T &v)
static int select_random_exec(bContext *C, wmOperator *op)
static int select_more_exec(bContext *C, wmOperator *)
static int select_less_exec(bContext *C, wmOperator *)
int RNA_int_get(PointerRNA *ptr, const char *name)
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)
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)
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)
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_grease_pencil_selectmode_items[]
struct ToolSettings * toolsettings
struct bContext::@80 data
MutableVArraySpan< T > span
Array< int > segment_offsets
Array< int > segment_start_points
Array< float > segment_start_fractions
Array< int > drawing_offsets
Array< float2 > start_positions
bke::greasepencil::Drawing & drawing
bool(* poll)(bContext *C) 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 WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
int WM_operator_properties_select_random_seed_increment_get(wmOperator *op)
void WM_operator_properties_select_random(wmOperatorType *ot)
void WM_operator_properties_select_all(wmOperatorType *ot)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)