46 return std::clamp(index,
int(range.
first()),
int(range.
last()));
58 const int curve_index,
67 const IndexRange segments = segments_by_curve[curve_index];
69 for (
const int segment_i : segments) {
73 if (segment_i < segments.
last()) {
74 const int next_segment_i = segment_i + 1;
79 const int first_point_i = (segment_fraction == 0.0f ?
82 const int next_first_point_i = (next_segment_fraction == 0.0f ?
83 next_segment_point_i :
93 const int first_point_i = (segment_fraction == 0.0f ?
97 const int next_first_point_i = (first_segment_fraction == 0.0f ?
98 first_segment_point_i :
105 fn(segment_i, points_range1, points_range2);
108 return segments.
size();
143 if (attribute_name !=
".selection") {
148 if (point_selection_mask.
is_empty()) {
161 curves, changed_curve_mask, screen_space_positions, tree_data, tree_data_range);
169 point_selection_mask.
to_bools(changed_points);
171 auto test_points_range = [&](
const IndexRange range) ->
bool {
172 for (
const int point_i : range) {
173 if (changed_points[point_i]) {
179 auto update_points_range = [&](
const IndexRange range) {
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;
232 if (drawings.is_empty()) {
235 const int frame_number = drawings.first().frame_number;
240 if (use_segment_selection) {
242 *vc, *ob_eval, grease_pencil, drawings, frame_number);
246 for (
const int i_drawing : drawings.index_range()) {
257 *
object, info, selection_domain, memory);
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_or_add_for_write_span<
bool>(
270 attribute_name, selection_domain))
273 selection.span.index_range(), memory);
280 if (use_segment_selection) {
283 const IndexRange tree_data_range = tree_data_by_drawing[i_drawing];
285 changed_element_mask,
294 changed_element_mask,
329 *
object, info, selection_domain, memory);
330 if (selectable_elements.
is_empty()) {
353 ot->name =
"(De)select All Strokes";
354 ot->idname =
"GREASE_PENCIL_OT_select_all";
355 ot->description =
"(De)select all visible strokes";
391 ot->name =
"Select More";
392 ot->idname =
"GREASE_PENCIL_OT_select_more";
393 ot->description =
"Grow the selection by one point";
427 ot->name =
"Select Less";
428 ot->idname =
"GREASE_PENCIL_OT_select_less";
429 ot->description =
"Shrink the selection by one point";
448 if (selectable_strokes.
is_empty()) {
464 ot->name =
"Select Linked";
465 ot->idname =
"GREASE_PENCIL_OT_select_linked";
466 ot->description =
"Select all points in curves with any point selection";
500 *
object, info, selection_domain, memory);
501 if (selectable_elements.
is_empty()) {
504 return random_mask(selectable_elements,
521 ot->name =
"Select Random";
522 ot->idname =
"GREASE_PENCIL_OT_select_random";
523 ot->description =
"Selects random points from the current strokes selection";
555 ot->name =
"Select Alternate";
556 ot->idname =
"GREASE_PENCIL_OT_select_alternate";
557 ot->description =
"Select alternated points in strokes with already selected points";
568 "(De)select the first and last point of each stroke");
585 {0,
nullptr, 0,
nullptr,
nullptr},
593 const int handle_display,
602 attribute_id, domain, default_value);
610 Set<T> &local_value_set = value_set_by_thread.local();
611 local_value_set.
add(values[index]);
619 Set<T> &local_value_set = value_set_by_thread.local();
620 local_value_set.
add(values[index]);
627 for (
const Set<T> &local_value_set : value_set_by_thread) {
629 for (
const T &key : local_value_set) {
630 r_value_set.
add(key);
635template<
typename T,
typename DistanceFn>
641 const int handle_display,
643 DistanceFn distance_fn)
656 object, info, selection_domain, attribute_id, handle_display, selected_values);
665 attribute_id, selection_domain, default_value);
669 for (
const int i : selection_attribute_names.index_range()) {
675 if (selection[index]) {
678 for (
const T &test_value : selected_values) {
679 if (distance_fn(values[index], test_value) <= threshold) {
680 selection[index] =
true;
685 selection_writer.
finish();
702 *info.drawing.strokes().attributes().lookup_or_default<
bool>(
".selection", domain,
true);
705 selected_layers.
add(info.layer_index);
775 [](
const float a,
const float b) ->
float {
return math::distance(a,
b); });
786 [](
const float a,
const float b) ->
float {
return math::distance(a,
b); });
798 ot->name =
"Select Similar";
799 ot->idname =
"GREASE_PENCIL_OT_select_similar";
800 ot->description =
"Select all strokes with similar characteristics";
832 info.
drawing.
strokes(), selectable_strokes, amount_start, amount_end,
false, memory);
845 ot->name =
"Select Ends";
846 ot->idname =
"GREASE_PENCIL_OT_select_ends";
847 ot->description =
"Select end points of strokes";
860 "Number of points to select from the start",
869 "Number of points to select from the end",
876 bool changed =
false;
898 const std::optional<bke::AttributeMetaData> meta_data = attributes.
lookup_meta_data(
900 if ((!meta_data) || (meta_data->domain == domain)) {
911 const GVArray src = *attributes.
lookup(
".selection", domain);
917 attributes.
remove(
".selection");
918 if (!attributes.
add(
".selection",
944 bool changed =
false;
977 ot->name =
"Select Mode";
978 ot->idname = __func__;
979 ot->description =
"Change the selection mode for Grease Pencil strokes";
998 const int material_index =
object->actcol - 1;
1001 if (material_index == -1) {
1011 *
object, info.
drawing, material_index, memory);
1020 for (
const int i : selection_attribute_names.
index_range()) {
1030 const IndexRange points = points_by_curve[curve_index];
1051 ot->name =
"Select Material";
1052 ot->idname =
"GREASE_PENCIL_OT_material_select";
1053 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)
View3D * CTX_wm_view3d(const bContext *C)
Low-level operations for curves.
Low-level operations for grease pencil.
General operations, lookup, etc. for blender objects.
bool BKE_object_is_mode_compat(const Object *ob, eObjectMode object_mode)
#define BLI_assert_unreachable()
#define BLI_SCOPED_DEFER(function_to_defer)
void DEG_id_tag_update(ID *id, unsigned int flags)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ 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)
static unsigned long seed
static const CPPType & get()
void default_construct(void *ptr) const
GMutableSpan slice(const int64_t start, int64_t size) const
MutableSpan< T > typed() const
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
constexpr bool is_empty() 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
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
GAttributeReader lookup(const StringRef attribute_id) const
int domain_size(const AttrDomain domain) const
std::optional< AttributeMetaData > lookup_meta_data(StringRef attribute_id) const
bool add(const StringRef attribute_id, const AttrDomain domain, const AttrType data_type, const AttributeInit &initializer)
bool remove(const StringRef attribute_id)
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
void to_bools(MutableSpan< bool > r_bools) const
void foreach_index(Fn &&fn) const
IndexRange index_range() const
static wmOperatorStatus select_linked_exec(bContext *C, wmOperator *)
VecBase< float, 4 > float4
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)
bool ED_grease_pencil_any_vertex_mask_selection(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 wmOperatorStatus select_all_exec(bContext *C, wmOperator *op)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
AttrType cpp_type_to_attribute_type(const CPPType &type)
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)
void fill_selection_false(GMutableSpan selection)
IndexMask select_adjacent_mask(const bke::CurvesGeometry &curves, const IndexMask &curves_mask, const StringRef attribute_name, const bool deselect, IndexMaskMemory &memory)
Span< StringRef > get_curves_selection_attribute_names(const bke::CurvesGeometry &curves)
void fill_selection(GMutableSpan selection, bool value)
IndexMask end_points(const bke::CurvesGeometry &curves, const IndexMask &curves_mask, const int amount_start, const int amount_end, const bool inverted, IndexMaskMemory &memory)
bke::GSpanAttributeWriter ensure_selection_attribute(bke::CurvesGeometry &curves, bke::AttrDomain selection_domain, bke::AttrType create_type, StringRef attribute_name)
static void GREASE_PENCIL_OT_select_linked(wmOperatorType *ot)
IndexMask retrieve_editable_and_selected_strokes(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
static wmOperatorStatus select_ends_exec(bContext *C, wmOperator *op)
FunctionRef< IndexMask(const ed::greasepencil::MutableDrawingInfo &info, const IndexMask &universe, StringRef attribute_name, IndexMaskMemory &memory)> SelectionUpdateFunc
IndexMask retrieve_editable_points(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
static void GREASE_PENCIL_OT_select_more(wmOperatorType *ot)
static wmOperatorStatus select_set_mode_exec(bContext *C, wmOperator *op)
bool selection_update(const ViewContext *vc, const eSelectOp sel_op, SelectionUpdateFunc select_operation)
bool ensure_selection_domain(ToolSettings *ts, Object *object)
IndexMask retrieve_editable_and_all_selected_points(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, int handle_display, IndexMaskMemory &memory)
static wmOperatorStatus select_more_exec(bContext *C, wmOperator *)
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)
void insert_selected_values(Object *object, const MutableDrawingInfo &info, const bke::AttrDomain domain, const StringRef attribute_id, const int handle_display, blender::Set< T > &r_value_set)
void free_curves_2d_bvh_data(Curves2DBVHTree &data)
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 wmOperatorStatus select_alternate_exec(bContext *C, wmOperator *op)
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 wmOperatorStatus select_all_exec(bContext *C, wmOperator *op)
static wmOperatorStatus select_random_exec(bContext *C, wmOperator *op)
int clamp_range(const IndexRange range, const int index)
bool editable_grease_pencil_poll(bContext *C)
static wmOperatorStatus select_similar_exec(bContext *C, wmOperator *op)
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)
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 select_similar_by_value(Scene *scene, Object *object, GreasePencil &grease_pencil, const bke::AttrDomain selection_domain, const StringRef attribute_id, const int handle_display, float threshold, DistanceFn distance_fn)
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)
IndexMask retrieve_editable_strokes(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
static wmOperatorStatus select_less_exec(bContext *C, wmOperator *)
Vector< MutableDrawingInfo > retrieve_editable_drawings(const Scene &scene, GreasePencil &grease_pencil)
Curves2DBVHTree build_curves_2d_bvh_from_visible(const ViewContext &vc, const Object &object, const GreasePencil &grease_pencil, Span< MutableDrawingInfo > drawings, const int frame_number)
static wmOperatorStatus select_linked_exec(bContext *C, wmOperator *)
static void GREASE_PENCIL_OT_select_random(wmOperatorType *ot)
static wmOperatorStatus grease_pencil_material_select_exec(bContext *C, wmOperator *op)
static void GREASE_PENCIL_OT_material_select(wmOperatorType *ot)
static void GREASE_PENCIL_OT_set_selection_mode(wmOperatorType *ot)
Array< Vector< MutableDrawingInfo > > retrieve_editable_drawings_grouped_per_frame(const Scene &scene, GreasePencil &grease_pencil)
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)
void masked_fill(MutableSpan< T > data, const T &value, const IndexMask &mask)
T distance(const T &a, const T &b)
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))
uint64_t get_default_hash(const T &v, const Args &...args)
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
static wmOperatorStatus select_random_exec(bContext *C, wmOperator *op)
static wmOperatorStatus select_less_exec(bContext *C, wmOperator *)
static wmOperatorStatus select_more_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
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
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 *))
wmOperatorStatus WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *)