36 std::optional<bke::AttributeMetaData> meta_data = attributes.
lookup_meta_data(
".selection");
48 const IndexRange points = points_by_curve[curve_i];
51 selection.materialize_compressed(points, point_selection);
52 return point_selection.
as_span().contains(
true);
88 static const std::array<StringRef, 1> selection_attribute_names{
".selection"};
90 return (attributes.
contains(
"handle_type_left") && attributes.
contains(
"handle_type_right")) ?
92 selection_attribute_names;
97 static const std::array<StringRef, 3> selection_attribute_names{
98 ".selection",
".selection_handle_left",
".selection_handle_right"};
99 return selection_attribute_names;
104 static const std::array<StringRef, 2> selection_attribute_names{
".selection_handle_left",
105 ".selection_handle_right"};
107 return (attributes.
contains(
"handle_type_left") && attributes.
contains(
"handle_type_right")) ?
108 selection_attribute_names :
115 for (
const StringRef selection_name : selection_attribute_names) {
116 attributes.
remove(selection_name);
125 if (attribute_name ==
".selection") {
128 if (attribute_name ==
".selection_handle_left") {
129 return curves.handle_positions_left();
131 if (attribute_name ==
".selection_handle_right") {
132 return curves.handle_positions_right();
144 for (
const int i : selection_attribute_names.
index_range()) {
146 curves, selection_domain, create_type, selection_attribute_names[i]));
153 for (
auto &attribute_writer : attribute_writers) {
154 attribute_writer.finish();
166 if (attribute_name.
size() == selection_attribute_names[index].
size()) {
167 return selections[index];
171 return selections[0];
182 fn(selection_writer);
197 if (r_bezier_attribute_names.
size() > 0) {
198 r_bezier_handle_positions[0] =
curves.handle_positions_left();
199 r_bezier_handle_positions[1] =
curves.handle_positions_right();
210 std::array<Span<float3>, 2> bezier_handle_positions;
215 bezier_attribute_names,
217 bezier_handle_positions,
221 range_consumer(
curves.points_range(), positions,
".selection");
224 for (
const int attribute_i : bezier_attribute_names.
index_range()) {
226 range_consumer(points_by_curve[curve_i],
227 bezier_handle_positions[attribute_i],
228 bezier_attribute_names[attribute_i]);
239 std::array<Span<float3>, 2> bezier_handle_positions;
244 bezier_attribute_names,
246 bezier_handle_positions,
250 range_consumer(
curves.curves_range(), positions,
".selection");
252 for (
const int attribute_i : bezier_attribute_names.
index_range()) {
255 curves_range, bezier_handle_positions[attribute_i], bezier_attribute_names[attribute_i]);
266 if (attributes.
contains(attribute_name)) {
269 if (selection_attr.
domain == selection_domain) {
270 return selection_attr;
273 attributes.
remove(attribute_name);
275 const int domain_size = attributes.
domain_size(selection_domain);
276 switch (create_type) {
278 attributes.
add(attribute_name,
284 attributes.
add(attribute_name,
321 selection.typed<
float>().fill(value ? 1.0f : 0.0f);
351 return *
static_cast<const bool *
>(info.
data) == value;
364 if (std::optional<IndexRange> range = sliced_mask.to_range()) {
365 return span.slice(*range).contains(value);
368 const IndexMaskSegment segment = sliced_mask.segment(segment_i);
369 for (const int i : segment) {
370 if (span[i] == value) {
380 indices_to_check.index_range(),
387 constexpr int64_t MaxChunkSize = 512;
389 for (
int64_t start = range.
start(); start < slice_end; start += MaxChunkSize) {
390 const int64_t end = std::min<int64_t>(start + MaxChunkSize, slice_end);
391 const int64_t size = end - start;
392 const IndexMask sliced_mask = indices_to_check.slice(start, size);
393 std::array<bool, MaxChunkSize> values;
394 auto values_end = values.begin() + size;
395 varray.materialize_compressed(sliced_mask, values);
396 if (std::find(values.begin(), values_end, value) != values_end) {
412 return contains(varray, range_to_check,
true);
417 return contains(varray, indices_to_check,
true);
452 for (
const float elem :
selection.typed<
float>()) {
464 for (const int i : range) {
465 selection[i] = 1.0f - selection[i];
502 std::optional<IndexRange> range =
mask.to_range();
503 if (range.has_value() &&
541 for (
const int i : selection_writers.
index_range()) {
546 for (
const int j : selection_writers.
index_range()) {
569 const bool deselect_ends)
582 const IndexRange points = points_by_curve[curve_i];
587 const int half_of_size = points.
size() / 2;
590 for (
const int i :
IndexRange(half_of_size)) {
591 const int index = i * 2;
592 selection_typed[selected[index]] =
true;
593 selection_typed[deselected[index]] =
false;
596 selection_typed[points.
first()] = !deselect_ends;
597 const bool end_parity_to_selected = bool(points.
size() % 2);
598 const bool selected_end = cyclic[curve_i] || end_parity_to_selected;
599 selection_typed[points.
last()] = !deselect_ends && selected_end;
603 if (!deselect_ends && cyclic[curve_i] && !curve_body.
is_empty()) {
604 selection_typed[curve_body.
last()] =
false;
632 const IndexRange points = points_by_curve[curve_i];
633 const int first_point = points.
first();
634 const int last_point = points.
last();
637 for (
int point_i = first_point; point_i < last_point; point_i++) {
638 if (!selection_typed[point_i] && selection_typed[point_i + 1]) {
639 selection_typed[point_i] =
true;
644 for (
int point_i = last_point; point_i > first_point; point_i--) {
645 if (!selection_typed[point_i] && selection_typed[point_i - 1]) {
646 selection_typed[point_i] =
true;
650 if (!selection_typed[first_point]) {
651 selection_typed[first_point] =
true;
653 if (!selection_typed[last_point]) {
654 selection_typed[last_point] =
true;
658 if (cyclic[curve_i]) {
659 if (selection_typed[first_point] != selection_typed[last_point]) {
660 selection_typed[first_point] =
true;
661 selection_typed[last_point] =
true;
666 else if (
selection.span.type().is<
float>()) {
669 const IndexRange points = points_by_curve[curve_i];
670 const int first_point = points.
first();
671 const int last_point = points.
last();
674 for (
int point_i = first_point; point_i < last_point; point_i++) {
675 if ((selection_typed[point_i] == 0.0f) && (selection_typed[point_i + 1] > 0.0f)) {
676 selection_typed[point_i] = 1.0f;
681 for (
int point_i = last_point; point_i > first_point; point_i--) {
682 if ((selection_typed[point_i] == 0.0f) && (selection_typed[point_i - 1] > 0.0f)) {
683 selection_typed[point_i] = 1.0f;
688 if (cyclic[curve_i]) {
689 if (selection_typed[first_point] != selection_typed[last_point]) {
690 selection_typed[first_point] = 1.0f;
691 selection_typed[last_point] = 1.0f;
718 selection_typed[index] =
true;
721 selection_typed[index] =
false;
724 selection_typed[index] = !selection_typed[index];
735 selection_typed[index] = 1.0f;
738 selection_typed[index] = 0.0f;
741 selection_typed[index] = 1.0f - selection_typed[index];
758 const float radius_sq =
pow2f(radius);
764 FindClosestData best_match = init;
765 for (const int index : point_indicies_range) {
766 const int point_i = points_mask[index];
767 const float3 pos = positions[point_i];
770 const float2 pos_proj = ED_view3d_project_float_v2_m4(region, pos, projection);
772 const float distance_proj_sq = math::distance_squared(pos_proj, mouse_pos);
773 if (distance_proj_sq > radius_sq ||
774 distance_proj_sq > best_match.distance * best_match.distance)
780 FindClosestData better_candidate;
781 better_candidate.index = point_i;
782 better_candidate.distance = std::sqrt(distance_proj_sq);
784 best_match = better_candidate;
788 [](
const FindClosestData &a,
const FindClosestData &
b) {
789 if (a.distance <
b.distance) {
795 if (new_closest_data.distance < initial_closest.distance) {
796 return new_closest_data;
813 const float radius_sq =
pow2f(radius);
820 FindClosestData best_match = init;
821 for (const int index : curves_indices_range) {
822 const int curve_i = curves_mask[index];
823 const IndexRange points = points_by_curve[curve_i];
824 if (points.size() == 1) {
825 const float3 pos = positions[points.first()];
828 const float2 pos_proj = ED_view3d_project_float_v2_m4(region, pos, projection);
830 const float distance_proj_sq = math::distance_squared(pos_proj, mouse_pos);
831 if (distance_proj_sq > radius_sq ||
832 distance_proj_sq > best_match.distance * best_match.distance)
839 FindClosestData better_candidate;
840 better_candidate.index = curve_i;
841 better_candidate.distance = std::sqrt(distance_proj_sq);
843 best_match = better_candidate;
847 auto process_segment = [&](const int segment_i, const int next_i) {
848 const float3 pos1 = positions[segment_i];
849 const float3 pos2 = positions[next_i];
850 const float2 pos1_proj = ED_view3d_project_float_v2_m4(region, pos1, projection);
851 const float2 pos2_proj = ED_view3d_project_float_v2_m4(region, pos2, projection);
853 const float distance_proj_sq = dist_squared_to_line_segment_v2(
854 mouse_pos, pos1_proj, pos2_proj);
855 if (distance_proj_sq > radius_sq ||
856 distance_proj_sq > best_match.distance * best_match.distance)
863 FindClosestData better_candidate;
864 better_candidate.index = curve_i;
865 better_candidate.distance = std::sqrt(distance_proj_sq);
867 best_match = better_candidate;
869 for (const int segment_i : points.drop_back(1)) {
870 process_segment(segment_i, segment_i + 1);
872 if (cyclic[curve_i]) {
873 process_segment(points.last(), points.first());
878 [](
const FindClosestData &a,
const FindClosestData &
b) {
879 if (a.distance <
b.distance) {
885 if (new_closest_data.distance < initial_closest.distance) {
886 return new_closest_data;
941 bool changed =
false;
954 const IndexMask &
mask = (selection_attribute_name ==
".selection") ? selection_mask :
956 mask.slice_content(range).foreach_index(
GrainSize(1024), [&](
const int point_i) {
958 vc.
region, positions[point_i], projection);
980 mask.slice_content(range).foreach_index(
GrainSize(512), [&](
const int curve_i) {
981 const IndexRange points = points_by_curve[curve_i];
982 if (points.
size() == 1) {
993 auto process_segment = [&](
const int segment_i,
const int next_i) {
994 const float3 pos1 = positions[segment_i];
995 const float3 pos2 = positions[next_i];
1009 bool segment_selected =
false;
1010 for (
const int segment_i : points.
drop_back(1)) {
1011 if (process_segment(segment_i, segment_i + 1)) {
1012 segment_selected =
true;
1016 if (!segment_selected && cyclic[curve_i]) {
1017 process_segment(points.
last(), points.
first());
1040 bool changed =
false;
1053 const IndexMask &
mask = (selection_attribute_name ==
".selection") ? selection_mask :
1055 mask.slice_content(range).foreach_index(
GrainSize(1024), [&](
const int point_i) {
1057 vc.
region, positions[point_i], projection_matrix);
1061 lasso_coords,
int(pos_proj.x),
int(pos_proj.y),
IS_CLIPPED))
1083 mask.slice_content(range).foreach_index(
GrainSize(512), [&](
const int curve_i) {
1084 const IndexRange points = points_by_curve[curve_i];
1085 if (points.
size() == 1) {
1087 vc.
region, positions[points.
first()], projection_matrix);
1091 lasso_coords,
int(pos_proj.x),
int(pos_proj.y),
IS_CLIPPED))
1100 auto process_segment = [&](
const int segment_i,
const int next_i) {
1101 const float3 pos1 = positions[segment_i];
1102 const float3 pos2 = positions[next_i];
1105 vc.
region, pos1, projection_matrix);
1107 vc.
region, pos2, projection_matrix);
1126 bool segment_selected =
false;
1127 for (
const int segment_i : points.
drop_back(cyclic[curve_i] ? 0 : 1)) {
1128 if (process_segment(segment_i, segment_i + 1)) {
1129 segment_selected =
true;
1133 if (!segment_selected && cyclic[curve_i]) {
1134 process_segment(points.
last(), points.
first());
1154 const float radius_sq =
pow2f(radius);
1157 bool changed =
false;
1170 const IndexMask &
mask = (selection_attribute_name ==
".selection") ? selection_mask :
1172 mask.slice_content(range).foreach_index(
GrainSize(1024), [&](
const int point_i) {
1174 vc.
region, positions[point_i], projection);
1196 mask.slice_content(range).foreach_index(
GrainSize(512), [&](
const int curve_i) {
1197 const IndexRange points = points_by_curve[curve_i];
1198 if (points.
size() == 1) {
1200 vc.
region, positions[points.
first()], projection);
1209 auto process_segments = [&](
const int segment_i,
const int next_i) {
1210 const float3 pos1 = positions[segment_i];
1211 const float3 pos2 = positions[next_i];
1217 float2(coord), pos1_proj, pos2_proj);
1218 if (distance_proj_sq <= radius_sq) {
1227 bool segment_selected =
false;
1228 for (
const int segment_i : points.
drop_back(1)) {
1229 if (process_segments(segment_i, segment_i + 1)) {
1230 segment_selected =
true;
1234 if (!segment_selected && cyclic[curve_i]) {
1235 process_segments(points.
last(), points.
first());
1244template<
typename Po
intSelectFn,
typename LineSelectFn>
1249 PointSelectFn &&point_predicate,
1250 LineSelectFn &&line_predicate)
1264 [&](
const int curve_i) ->
bool {
1265 const IndexRange points = points_by_curve[curve_i];
1269 if (points.
size() == 1) {
1270 return point_predicate(points.
first());
1273 for (
const int point_i : points.
drop_back(1)) {
1274 if (line_predicate(curve_i, point_i, point_i + 1)) {
1279 if (line_predicate(curve_i, points.
last(), points.
first())) {
1292 const bool deselect,
1304 auto is_point_changed1 = [&](
const int point,
const int neighbor) {
1308 auto is_point_changed2 = [&](
const int point,
const int neighbor1,
const int neighbor2) {
1314 const IndexRange points = points_by_curve[curve_i];
1315 if (points.
size() == 1) {
1320 if (cyclic[curve_i]) {
1321 changed_points[points.
first()] = is_point_changed2(
1324 changed_points[point_i] = is_point_changed2(point_i, point_i - 1, point_i + 1);
1326 changed_points[points.
last()] = is_point_changed2(
1330 changed_points[points.
first()] = is_point_changed1(points.
first(), points.
first() + 1);
1332 changed_points[point_i] = is_point_changed2(point_i, point_i - 1, point_i + 1);
1334 changed_points[points.
last()] = is_point_changed1(points.
last(), points.
last() - 1);
1343 const bool deselect,
1361 curves, deformation, attribute_name);
1363 auto point_predicate = [&](
const int point_i) {
1365 vc.
region, positions[point_i], projection);
1369 auto line_predicate = [&](
const int ,
const int point_i,
const int next_point_i) {
1371 vc.
region, positions[point_i], projection);
1373 vc.
region, positions[next_point_i], projection);
1378 attribute_name ==
".selection") ?
1382 curves,
mask, selection_domain, memory, point_predicate, line_predicate);
1399 curves, deformation, attribute_name);
1401 auto point_predicate = [&](
const int point_i) {
1403 vc.
region, positions[point_i], projection);
1408 auto line_predicate = [&](
const int ,
const int point_i,
const int next_point_i) {
1410 vc.
region, positions[point_i], projection);
1412 vc.
region, positions[next_point_i], projection);
1417 int(next_pos_proj.x),
1418 int(next_pos_proj.y),
1423 attribute_name ==
".selection") ?
1427 curves,
mask, selection_domain, memory, point_predicate, line_predicate);
1442 const float radius_sq =
pow2f(radius);
1444 curves, deformation, attribute_name);
1446 auto point_predicate = [&](
const int point_i) {
1448 vc.
region, positions[point_i], projection);
1450 return distance_proj_sq <= radius_sq;
1452 auto line_predicate = [&](
const int ,
const int point_i,
const int next_point_i) {
1454 vc.
region, positions[point_i], projection);
1456 vc.
region, positions[next_point_i], projection);
1458 float2(coord), pos_proj, next_pos_proj);
1459 return distance_proj_sq <= radius_sq;
1463 attribute_name ==
".selection") ?
1467 curves,
mask, selection_domain, memory, point_predicate, line_predicate);
Low-level operations for curves.
#define BLI_assert_unreachable()
bool BLI_lasso_is_point_inside(blender::Span< blender::int2 > mcoords, int sx, int sy, int error_value)
void BLI_lasso_boundbox(rcti *rect, blender::Span< blender::int2 > mcoords)
bool BLI_lasso_is_edge_inside(blender::Span< blender::int2 > mcoords, int x0, int y0, int x1, int y1, int error_value)
MINLINE float pow2f(float x)
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
bool BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2])
bool BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2])
blender::float2 ED_view3d_project_float_v2_m4(const ARegion *region, const float co[3], const blender::float4x4 &mat)
float ED_view3d_select_dist_px()
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
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
Span< T > as_span() const
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
constexpr int64_t first() const
constexpr int64_t one_after_last() const
constexpr IndexRange shift(int64_t n) 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 int64_t start() const
constexpr IndexRange drop_front(int64_t n) const
constexpr IndexRange index_range() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool contains(const T &value) const
constexpr int64_t size() const
CommonVArrayInfo common_info() const
static VArray ForSingle(T value, const int64_t size)
void append(const T &value)
IndexRange index_range() const
std::optional< AttributeMetaData > lookup_meta_data(const StringRef attribute_id) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const void *default_value=nullptr) const
int domain_size(const AttrDomain domain) const
bool contains(const StringRef attribute_id) const
bool remove(const StringRef attribute_id)
bool add(const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
IndexMask slice(IndexRange range) const
IndexRange index_range() const
void foreach_range(Fn &&fn) const
void foreach_index(Fn &&fn) const
local_group_size(16, 16) .push_constant(Type b
VecBase< float, 2 > float2
static bool is_cyclic(const Nurb *nu)
ccl_device_inline float4 mask(const int4 mask, const float4 a)
void invert_booleans(MutableSpan< bool > span)
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)
IndexMask select_circle_mask(const ViewContext &vc, const bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &deformation, const float4x4 &projection, const IndexMask &selection_mask, const IndexMask &bezier_mask, const bke::AttrDomain selection_domain, const StringRef attribute_name, const int2 coord, const float radius, IndexMaskMemory &memory)
static bool has_anything_selected(const Span< Curves * > curves_ids)
static std::optional< FindClosestData > find_closest_point_to_screen_co(const ARegion *region, const Span< float3 > positions, const float4x4 &projection, const IndexMask &points_mask, const float2 mouse_pos, float radius, const FindClosestData &initial_closest)
IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
void remove_selection_attributes(bke::MutableAttributeAccessor &attributes, Span< StringRef > selection_attribute_names)
static Vector< bke::GSpanAttributeWriter > init_selection_writers(bke::CurvesGeometry &curves, bke::AttrDomain selection_domain)
void select_all(bke::CurvesGeometry &curves, const IndexMask &mask, const bke::AttrDomain selection_domain, int action)
IndexMask select_mask_from_predicates(const bke::CurvesGeometry &curves, const IndexMask &mask, const bke::AttrDomain selection_domain, IndexMaskMemory &memory, PointSelectFn &&point_predicate, LineSelectFn &&line_predicate)
void select_alternate(bke::CurvesGeometry &curves, const IndexMask &curves_mask, const bool deselect_ends)
Span< float3 > get_selection_attribute_positions(const bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &deformation, const StringRef attribute_name)
static void invert_selection(MutableSpan< float > selection)
static void init_selectable_foreach(const bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &deformation, Span< StringRef > &r_bezier_attribute_names, Span< float3 > &r_positions, std::array< Span< float3 >, 2 > &r_bezier_handle_positions, IndexMaskMemory &r_memory, IndexMask &r_bezier_curves)
void foreach_selectable_point_range(const bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &deformation, SelectionRangeFn range_consumer)
void select_adjacent(bke::CurvesGeometry &curves, const IndexMask &curves_mask, const bool deselect)
void foreach_selection_attribute_writer(bke::CurvesGeometry &curves, bke::AttrDomain selection_domain, blender::FunctionRef< void(bke::GSpanAttributeWriter &selection)> fn)
static bke::GSpanAttributeWriter & selection_attribute_writer_by_name(MutableSpan< bke::GSpanAttributeWriter > selections, StringRef attribute_name)
Span< StringRef > get_curves_bezier_selection_attribute_names(const bke::CurvesGeometry &curves)
void fill_selection_false(GMutableSpan selection)
IndexMask select_lasso_mask(const ViewContext &vc, const bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &deformation, const float4x4 &projection, const IndexMask &selection_mask, const IndexMask &bezier_mask, const bke::AttrDomain selection_domain, const StringRef attribute_name, const Span< int2 > lasso_coords, IndexMaskMemory &memory)
bool select_circle(const ViewContext &vc, bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &deformation, const float4x4 &projection, const IndexMask &selection_mask, const IndexMask &bezier_mask, const bke::AttrDomain selection_domain, const int2 coord, const float radius, const eSelectOp sel_op)
static void finish_attribute_writers(MutableSpan< bke::GSpanAttributeWriter > attribute_writers)
IndexMask select_adjacent_mask(const bke::CurvesGeometry &curves, const IndexMask &curves_mask, const StringRef attribute_name, const bool deselect, IndexMaskMemory &memory)
void fill_selection_true(GMutableSpan selection)
Span< StringRef > get_curves_selection_attribute_names(const bke::CurvesGeometry &curves)
void fill_selection(GMutableSpan selection, bool value)
std::optional< FindClosestData > closest_elem_find_screen_space(const ViewContext &vc, const OffsetIndices< int > points_by_curve, const Span< float3 > positions, const VArray< bool > &cyclic, const float4x4 &projection, const IndexMask &mask, const bke::AttrDomain domain, const int2 coord, const FindClosestData &initial_closest)
Span< StringRef > get_curves_all_selection_attribute_names()
FunctionRef< void( IndexRange range, Span< float3 > positions, StringRef selection_attribute_name)> SelectionRangeFn
static std::optional< FindClosestData > find_closest_curve_to_screen_co(const ARegion *region, const OffsetIndices< int > points_by_curve, const Span< float3 > positions, const VArray< bool > &cyclic, const float4x4 &projection, const IndexMask &curves_mask, const float2 mouse_pos, float radius, const FindClosestData &initial_closest)
IndexMask select_box_mask(const ViewContext &vc, const bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &deformation, const float4x4 &projection, const IndexMask &selection_mask, const IndexMask &bezier_mask, const bke::AttrDomain selection_domain, const StringRef attribute_name, const rcti &rect, IndexMaskMemory &memory)
bke::GSpanAttributeWriter ensure_selection_attribute(bke::CurvesGeometry &curves, bke::AttrDomain selection_domain, eCustomDataType create_type, StringRef attribute_name)
static bool contains(const VArray< bool > &varray, const IndexMask &indices_to_check, const bool value)
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
void foreach_selectable_curve_range(const bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &deformation, SelectionRangeFn range_consumer)
bool select_lasso(const ViewContext &vc, bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &deformation, const float4x4 &projection_matrix, const IndexMask &selection_mask, const IndexMask &bezier_mask, const bke::AttrDomain selection_domain, const Span< int2 > lasso_coords, const eSelectOp sel_op)
bool select_box(const ViewContext &vc, bke::CurvesGeometry &curves, const bke::crazyspace::GeometryDeformation &deformation, const float4x4 &projection, const IndexMask &selection_mask, const IndexMask &bezier_mask, const bke::AttrDomain selection_domain, const rcti &rect, const eSelectOp sel_op)
void masked_fill(MutableSpan< T > data, const T &value, const IndexMask &mask)
T distance_squared(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
MatBase< float, 4, 4 > float4x4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
static void init(bNodeTree *, bNode *node)
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]