32 devirtualize_varray(b, [&](const auto b) {
33 for (const int i : range) {
34 if (index_map[i] != -1) {
35 a[i] = bke::attribute_math::mix2(factor, a[i], b[index_map[i]]);
47 bke::attribute_math::convert_to_static_type(a.type(), [&](
auto dummy) {
48 using T = decltype(dummy);
49 mix_with_indices(a.typed<T>(), b.typed<T>(), index_map, factor);
55 threading::parallel_for(a.index_range(), 1024, [&](
const IndexRange range) {
56 devirtualize_varray(b, [&](const auto b) {
57 for (const int i : range) {
58 a[i] = bke::attribute_math::mix2(factor, a[i], b[i]);
66 bke::attribute_math::convert_to_static_type(a.type(), [&](
auto dummy) {
67 using T = decltype(dummy);
68 mix(a.typed<T>(), b.typed<T>(), factor);
81 for (
const StringRef name : names_to_skip) {
85 for (
const StringRef
id : ids) {
86 const bke::GAttributeReader attribute_a = attributes_a.
lookup(
id);
87 const bke::AttrDomain domain = attribute_a.
domain;
88 if (domain != mix_domain) {
91 const eCustomDataType type = bke::cpp_type_to_custom_data_type(attribute_a.varray.type());
96 const bke::GAttributeReader attribute_b = b_attributes.
lookup(
id, attribute_a.domain, type);
109 mix(dst.span, attribute_b.varray, factor);
119 for (
const int i : values.index_range()) {
120 map.add(values[i], i);
130 if (!ids_a || !ids_b) {
143 for (const int i : range) {
144 index_map[i] = id_map_b.lookup_default(ids_span_a[i], -1);
152 if (
Mesh *mesh_a = a.get_mesh_for_write()) {
153 if (
const Mesh *mesh_b =
b.get_mesh()) {
156 mesh_b->attributes(),
158 bke::AttrDomain::Point,
163 if (
PointCloud *points_a = a.get_pointcloud_for_write()) {
164 if (
const PointCloud *points_b =
b.get_pointcloud()) {
166 points_b->attributes());
168 points_b->attributes(),
170 bke::AttrDomain::Point,
174 if (
Curves *curves_a = a.get_curves_for_write()) {
175 if (
const Curves *curves_b =
b.get_curves()) {
183 bke::AttrDomain::Point,
185 {
"curve_type",
"nurbs_order",
"knots_mode",
"handle_type_left",
"handle_type_right"});
191 instances_b->attributes());
193 instances_b->attributes(),
195 bke::AttrDomain::Instance,
197 {
".reference_index"});
Low-level operations for curves.
bool remove_as(const ForwardKey &key)
bool remove(const Key &key)
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
GAttributeReader lookup(const StringRef attribute_id) const
Set< StringRefNull > all_ids() const
int domain_size(const AttrDomain domain) const
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
local_group_size(16, 16) .push_constant(Type b
static void mix_attributes(bke::MutableAttributeAccessor attributes_a, const bke::AttributeAccessor b_attributes, const Span< int > index_map, const bke::AttrDomain mix_domain, const float factor, const Set< std::string > &names_to_skip={})
void mix_with_indices(MutableSpan< T > a, const VArray< T > &b, const Span< int > index_map, const float factor)
static bool sharing_info_equal(const ImplicitSharingInfo *a, const ImplicitSharingInfo *b)
bke::GeometrySet mix_geometries(bke::GeometrySet a, const bke::GeometrySet &b, float factor)
static Map< int, int > create_value_to_first_index_map(const Span< int > values)
static Array< int > create_id_index_map(const bke::AttributeAccessor attributes_a, const bke::AttributeAccessor b_attributes)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
const ImplicitSharingInfo * sharing_info