45 return this->kinds.
size();
252 if (this->result_domain) {
254 if (this->result_domain != domain) {
259 this->result_domain = domain;
272 const std::optional<bke::AttributeMetaData> custom_normal = attributes.
lookup_meta_data(
274 if (!custom_normal) {
456 for (const int i : range) {
457 dst[i] = math::transform_point(transform, src[i]);
466 for (const int i : range) {
467 positions[i] = math::transform_point(transform, positions[i]);
477 src.type().copy_construct_n(src.slice(range).data(), dst.slice(range).data(), range.size());
485 value.type()->fill_construct_n(value.get(), dst.slice(range).data(), range.size());
490 const Span<std::optional<GVArraySpan>> src_attributes,
496 threading::parallel_for(
498 for (const int attribute_index : attribute_range) {
499 const bke::AttrDomain domain = ordered_attributes.kinds[attribute_index].domain;
500 const IndexRange element_slice = range_fn(domain);
502 GSpanAttributeWriter &writer = dst_attribute_writers[attribute_index];
506 GMutableSpan dst_span = writer.span.slice(element_slice);
507 if (src_attributes[attribute_index].has_value()) {
508 threaded_copy(*src_attributes[attribute_index], dst_span);
511 const CPPType &cpp_type = dst_span.type();
512 const void *fallback = attribute_fallbacks.array[attribute_index] == nullptr ?
513 cpp_type.default_value() :
514 attribute_fallbacks.array[attribute_index];
515 threaded_fill({cpp_type, fallback}, dst_span);
526 if (
options.keep_original_ids) {
537 for (const int i : range) {
538 dst_ids[i] = noise::hash(task_id, i);
544 for (const int i : range) {
545 dst_ids[i] = noise::hash(task_id, stored_ids[i]);
558 const int current_depth,
559 const int target_depth,
560 const bke::GeometrySet &geometry_set,
562 const InstanceContext &base_instance_context);
577 const int attribute_index = ordered_attributes.
ids.index_of_try(iter.
name);
578 if (attribute_index == -1) {
590 const CPPType &to_type = *bke::custom_data_type_to_cpp_type(expected_type);
597 std::unique_ptr<GArray<>> temporary_array = std::make_unique<GArray<>>(
600 span = temporary_array->as_span();
603 attributes_to_override.
append({attribute_index, span});
605 return attributes_to_override;
621 fn(geometry_set, base_transform,
id);
625 const int current_depth,
626 const int target_depth,
639 stored_instance_ids = ids.
varray.get_internal_span();
656 const bool is_top_level = current_depth == 0;
660 indices.foreach_index([&](
const int i) {
662 const int child_target_depth = is_top_level ? gather_info.
depths[i] : target_depth;
669 for (
const std::pair<int, GSpan> &pair : pointcloud_attributes_to_override) {
672 for (
const std::pair<int, GSpan> &pair : mesh_attributes_to_override) {
673 instance_context.
meshes.
array[pair.first] = pair.second[i];
675 for (
const std::pair<int, GSpan> &pair : curve_attributes_to_override) {
676 instance_context.
curves.
array[pair.first] = pair.second[i];
678 for (
const std::pair<int, GSpan> &pair : grease_pencil_attributes_to_override) {
681 for (
const std::pair<int, GSpan> &pair : instance_attributes_to_override) {
687 if (stored_instance_ids.
is_empty()) {
691 local_instance_id =
uint32_t(stored_instance_ids[i]);
694 const uint32_t instance_id = noise::hash(base_instance_context.
id, local_instance_id);
703 instance_context.
id = id;
707 instance_geometry_set,
718 const int current_depth,
719 const int target_depth,
727 case bke::GeometryComponent::Type::Mesh: {
735 base_instance_context.
meshes,
736 base_instance_context.
id});
744 case bke::GeometryComponent::Type::PointCloud: {
747 const PointCloud *pointcloud = pointcloud_component.get();
748 if (pointcloud !=
nullptr && pointcloud->
totpoint > 0) {
756 base_instance_context.
id});
761 case bke::GeometryComponent::Type::Curve: {
763 const Curves *curves = curve_component.get();
770 base_instance_context.
curves,
771 base_instance_context.
id});
778 case bke::GeometryComponent::Type::GreasePencil: {
781 const GreasePencil *grease_pencil = grease_pencil_component.get();
782 if (grease_pencil !=
nullptr && !grease_pencil->layers().is_empty()) {
795 case bke::GeometryComponent::Type::Instance: {
796 if (current_depth == target_depth) {
804 if (instances !=
nullptr && instances->
instances_num() > 0) {
810 base_instance_context);
815 case bke::GeometryComponent::Type::Volume: {
825 case bke::GeometryComponent::Type::Edit: {
828 if (edit_component->gizmo_edit_hints_ || edit_component->curves_edit_hints_) {
841 const int current_depth,
842 const std::optional<int> max_depth,
846 if (r_components.
add_as(component)) {
847 component->add_user();
850 if (current_depth == max_depth) {
854 if (!instances_component) {
861 if (
options.realize_instance_attributes) {
862 if (r_components.
add_as(instances_component)) {
863 instances_component->add_user();
870 reference_geometry, component_type,
options, current_depth + 1, max_depth, r_components);
882 if (r_components.
add_as(component)) {
883 component->add_user();
887 if (!instances_component) {
897 const int references_num = references.
size();
901 const int reference_i =
handles[instance_i];
902 const int instance_depth = varied_depth_option.
depths[instance_i];
903 std::optional<int> &max_depth = max_reference_depth[reference_i];
904 if (!max_depth.has_value()) {
908 if (instance_depth == VariedDepthOptions::MAX_DEPTH) {
912 max_depth = std::max<int>(*max_depth, instance_depth);
915 bool is_anything_realized =
false;
916 for (
const int reference_i :
IndexRange(references_num)) {
917 const std::optional<int> max_depth = max_reference_depth[reference_i];
918 if (max_depth == 0) {
925 reference_geometry, component_type,
options, 1, max_depth, r_components);
926 is_anything_realized =
true;
929 if (is_anything_realized) {
930 if (
options.realize_instance_attributes) {
931 if (r_components.
add_as(instances_component)) {
932 instances_component->add_user();
948 const int top_level_instances_num = top_level_instances_component ?
950 AttrDomain::Instance) :
956 varied_depth_option.
selection.
size() == top_level_instances_num)
960 geometry, component_type,
options, 0, std::nullopt, components);
964 geometry, component_type,
options, varied_depth_option, components);
973 if (!bke::attribute_is_builtin_on_component_type(component_type, iter.
name)) {
979 if (component->type() == bke::GeometryComponent::Type::Instance) {
980 if (
ELEM(iter.
name,
"instance_transform",
".reference_index")) {
994 AttrDomain dst_domain = iter.
domain;
995 if (component_type != bke::GeometryComponent::Type::Instance &&
996 dst_domain == AttrDomain::Instance)
998 if (component_type == bke::GeometryComponent::Type::GreasePencil) {
1000 dst_domain = AttrDomain::Layer;
1004 dst_domain = AttrDomain::Point;
1008 kind->domain = dst_domain;
1012 kind->domain = bke::attribute_domain_highest_priority({kind->domain, dst_domain});
1013 kind->data_type = bke::attribute_data_type_highest_complexity(
1020 return attributes_to_propagate;
1035 in_geometry_set, bke::GeometryComponent::Type::Instance,
options, varied_depth_option);
1036 attributes_to_propagate.
pop_try(
"id");
1038 for (
const auto item : attributes_to_propagate.
items()) {
1039 ordered_attributes.
ids.add_new(item.key);
1040 ordered_attributes.
kinds.append(item.value);
1042 return ordered_attributes;
1053 src_components.
size() == attribute_fallback.
size());
1059 for (
const int component_index : src_components.
index_range()) {
1061 *src_components[component_index]);
1064 const OffsetIndices offsets = offset_indices::accumulate_counts_to_offsets(offsets_data);
1066 std::unique_ptr<bke::Instances> dst_instances = std::make_unique<bke::Instances>();
1070 for (
const int attribute_index : all_instances_attributes.
index_range()) {
1072 const StringRef id = all_instances_attributes.
ids[attribute_index];
1074 dst_instances->attributes_for_write()
1075 .lookup_or_add_for_write_only_span(
id, domain, type)
1080 MutableSpan<int> all_handles = dst_instances->reference_handles_for_write();
1082 for (
const int component_index : src_components.
index_range()) {
1084 *src_components[component_index]);
1086 const blender::float4x4 &src_base_transform = src_base_transforms[component_index];
1087 const Span<const void *> attribute_fallback_array = attribute_fallback[component_index].array;
1091 for (
const int src_handle : src_references.
index_range()) {
1092 handle_map[src_handle] = dst_instances->add_reference(src_references[src_handle]);
1094 const IndexRange dst_range = offsets[component_index];
1095 for (
const int attribute_index : all_instances_attributes.
index_range()) {
1096 const StringRef id = all_instances_attributes.
ids[attribute_index];
1098 const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(type);
1101 dst_instances->attributes_for_write().lookup_for_write_span(
id);
1104 const void *attribute_ptr;
1105 if (attribute_fallback_array[attribute_index] !=
nullptr) {
1106 attribute_ptr = attribute_fallback_array[attribute_index];
1113 write_attribute.
finish();
1117 array_utils::gather(handle_map.
as_span(), src_handles, all_handles.
slice(dst_range));
1118 array_utils::copy(src_instances.
transforms(), all_transforms.
slice(dst_range));
1130 for_join_attributes.
append(component.get());
1135 join_attributes(for_join_attributes, dst_component, {
".reference_index",
"instance_transform"});
1148 bool &r_create_radii,
1152 in_geometry_set, bke::GeometryComponent::Type::PointCloud,
options, varied_depth_option);
1153 attributes_to_propagate.
remove(
"position");
1154 r_create_id = attributes_to_propagate.
pop_try(
"id").has_value();
1155 r_create_radii = attributes_to_propagate.
pop_try(
"radius").has_value();
1157 for (
const auto item : attributes_to_propagate.
items()) {
1158 ordered_attributes.
ids.add_new(item.key);
1159 ordered_attributes.
kinds.append(item.value);
1161 return ordered_attributes;
1168 if (pointcloud->totpoint > 0) {
1169 r_pointclouds.
add(pointcloud);
1173 instances->foreach_referenced_geometry([&](
const bke::GeometrySet &instance_geometry_set) {
1186 varied_depth_option,
1187 info.create_radius_attribute,
1188 info.create_id_attribute);
1191 info.realize_info.reinitialize(
info.order.size());
1192 for (
const int pointcloud_index :
info.realize_info.index_range()) {
1200 for (
const int attribute_index :
info.attributes.index_range()) {
1201 const StringRef attribute_id =
info.attributes.ids[attribute_index];
1204 if (attributes.
contains(attribute_id)) {
1206 pointcloud_info.
attributes[attribute_index].emplace(std::move(attribute));
1209 if (
info.create_id_attribute) {
1211 if (ids_attribute) {
1215 if (
info.create_radius_attribute) {
1217 "radius", bke::AttrDomain::Point, 0.01f);
1220 "position", bke::AttrDomain::Point,
float3(0));
1256 BLI_assert(domain == bke::AttrDomain::Point);
1257 UNUSED_VARS_NDEBUG(domain);
1260 dst_attribute_writers);
1268 for (
const int attribute_index : ordered_attributes.
index_range()) {
1269 const void *
value = attribute_fallbacks.
array[attribute_index];
1275 const CPPType &cpp_type = *bke::custom_data_type_to_cpp_type(data_type);
1277 attributes.
add(ordered_attributes.
ids[attribute_index],
1293 if (tasks.
size() == 1) {
1298 new_points->tag_positions_changed();
1321 "position", bke::AttrDomain::Point);
1327 bke::AttrDomain::Point);
1332 bke::AttrDomain::Point);
1337 for (
const int attribute_index : ordered_attributes.
index_range()) {
1338 const StringRef attribute_id = ordered_attributes.
ids[attribute_index];
1341 attribute_id, bke::AttrDomain::Point, data_type));
1346 for (const int task_index : task_range) {
1347 const RealizePointCloudTask &task = tasks[task_index];
1348 execute_realize_pointcloud_task(options,
1351 dst_attribute_writers,
1359 for (GSpanAttributeWriter &dst_attribute : dst_attribute_writers) {
1360 dst_attribute.finish();
1363 point_radii.finish();
1378 bool &r_create_material_index)
1381 in_geometry_set, bke::GeometryComponent::Type::Mesh,
options, varied_depth_option);
1382 attributes_to_propagate.
remove(
"position");
1383 attributes_to_propagate.
remove(
".edge_verts");
1384 attributes_to_propagate.
remove(
".corner_vert");
1385 attributes_to_propagate.
remove(
".corner_edge");
1386 attributes_to_propagate.
remove(
"custom_normal");
1387 r_create_id = attributes_to_propagate.
pop_try(
"id").has_value();
1388 r_create_material_index = attributes_to_propagate.
pop_try(
"material_index").has_value();
1390 for (
const auto item : attributes_to_propagate.
items()) {
1391 ordered_attributes.
ids.add_new(item.key);
1392 ordered_attributes.
kinds.append(item.value);
1394 return ordered_attributes;
1406 instances->foreach_referenced_geometry([&](
const bke::GeometrySet &instance_geometry_set) {
1420 varied_depth_option,
1421 info.create_id_attribute,
1422 info.create_material_index_attribute);
1428 info.materials.add(
nullptr);
1439 info.custom_normal_info.add_mesh(*
mesh);
1442 info.create_material_index_attribute |=
info.materials.size() > 1;
1443 info.realize_info.reinitialize(
info.order.size());
1444 for (
const int mesh_index :
info.realize_info.index_range()) {
1462 const int new_slot_index =
info.materials.index_of(
material);
1470 for (
const int attribute_index :
info.attributes.index_range()) {
1471 const StringRef attribute_id =
info.attributes.ids[attribute_index];
1474 if (attributes.
contains(attribute_id)) {
1476 mesh_info.
attributes[attribute_index].emplace(std::move(attribute));
1479 if (
info.create_id_attribute) {
1481 if (ids_attribute) {
1486 "material_index", bke::AttrDomain::Face, 0);
1488 switch (
info.custom_normal_info.result_type) {
1489 case MeshNormalInfo::Output::None: {
1492 case MeshNormalInfo::Output::CornerFan: {
1495 bke::AttrDomain::Corner);
1499 case MeshNormalInfo::Output::Free: {
1500 switch (*
info.custom_normal_info.result_domain) {
1501 case bke::AttrDomain::Point:
1504 case bke::AttrDomain::Face:
1507 case bke::AttrDomain::Corner:
1518 info.no_loose_edges_hint = std::all_of(
1520 return mesh->runtime->loose_edges_cache.is_cached() && mesh->loose_edges().count == 0;
1522 info.no_loose_verts_hint = std::all_of(
1524 return mesh->runtime->loose_verts_cache.is_cached() && mesh->loose_verts().count == 0;
1526 info.no_overlapping_hint = std::all_of(
1528 return mesh->no_overlapping_topology();
1568 for (const int i : vert_range) {
1569 dst_positions[i] = math::transform_point(task.transform, src_positions[i]);
1572 threading::parallel_for(src_edges.index_range(), 1024, [&](
const IndexRange edge_range) {
1573 for (const int i : edge_range) {
1574 dst_edges[i] = src_edges[i] + task.start_indices.vertex;
1577 threading::parallel_for(src_corner_verts.index_range(), 1024, [&](
const IndexRange loop_range) {
1578 for (const int i : loop_range) {
1579 dst_corner_verts[i] = src_corner_verts[i] + task.start_indices.vertex;
1582 threading::parallel_for(src_corner_edges.index_range(), 1024, [&](
const IndexRange loop_range) {
1583 for (const int i : loop_range) {
1584 dst_corner_edges[i] = src_corner_edges[i] + task.start_indices.edge;
1587 threading::parallel_for(src_faces.index_range(), 1024, [&](
const IndexRange face_range) {
1588 for (const int i : face_range) {
1589 dst_face_offsets[i] = src_faces[i].start() + task.start_indices.loop;
1592 if (!all_dst_material_indices.is_empty()) {
1593 const Span<int> material_index_map = mesh_info.material_index_map;
1594 MutableSpan<int> dst_material_indices = all_dst_material_indices.
slice(dst_face_range);
1597 dst_material_indices.
fill(material_index_map.first());
1600 if (mesh_info.material_indices.is_single()) {
1601 const int src_index = mesh_info.material_indices.get_internal_single();
1602 const bool valid = IndexRange(
mesh.
totcol).contains(src_index);
1603 dst_material_indices.fill(valid ? material_index_map[src_index] : 0);
1606 VArraySpan<int> indices_span(mesh_info.material_indices);
1607 threading::parallel_for(src_faces.index_range(), 1024, [&](
const IndexRange face_range) {
1608 for (const int i : face_range) {
1609 const int src_index = indices_span[i];
1610 const bool valid = IndexRange(mesh.totcol).contains(src_index);
1611 dst_material_indices[i] = valid ? material_index_map[src_index] : 0;
1618 if (!all_dst_vertex_ids.is_empty()) {
1620 mesh_info.stored_vertex_ids,
1622 all_dst_vertex_ids.slice(task.start_indices.vertex,
mesh.
verts_num));
1625 const auto domain_to_range = [&](
const bke::AttrDomain domain) {
1627 case bke::AttrDomain::Point:
1628 return dst_vert_range;
1629 case bke::AttrDomain::Edge:
1630 return dst_edge_range;
1631 case bke::AttrDomain::Face:
1632 return dst_face_range;
1633 case bke::AttrDomain::Corner:
1634 return dst_loop_range;
1637 return IndexRange();
1641 if (all_dst_custom_normals) {
1642 if (all_dst_custom_normals.span.type().is<
short2>()) {
1643 if (mesh_info.custom_normal.is_empty()) {
1644 all_dst_custom_normals.span.typed<
short2>().slice(dst_loop_range).fill(
short2(0));
1647 all_dst_custom_normals.span.typed<
short2>()
1648 .slice(dst_loop_range)
1649 .copy_from(mesh_info.custom_normal.typed<
short2>());
1653 const IndexRange dst_range = domain_to_range(all_dst_custom_normals.domain);
1656 all_dst_custom_normals.span.typed<
float3>().slice(dst_range));
1661 task.attribute_fallbacks,
1664 dst_attribute_writers);
1671 const int attribute_index = ordered_attributes.
ids.index_of_try(src_name);
1672 if (attribute_index == -1) {
1693 existing_names.
add(defgroup->name);
1695 for (
const Mesh *
mesh : src_meshes) {
1697 if (existing_names.
contains(src->name)) {
1716 if (tasks.
size() == 1) {
1720 bke::mesh_transform(*new_mesh, task.
transform,
false);
1752 *dst_mesh, ordered_attributes, all_meshes_info.
order.
as_span().drop_front(1));
1765 bke::AttrDomain::Point);
1771 "material_index", bke::AttrDomain::Face);
1776 case MeshNormalInfo::Output::None: {
1779 case MeshNormalInfo::Output::CornerFan: {
1784 case MeshNormalInfo::Output::Free: {
1794 for (
const int attribute_index : ordered_attributes.
index_range()) {
1795 const StringRef attribute_id = ordered_attributes.
ids[attribute_index];
1798 dst_attribute_writers.
append(
1803 if (active_layer !=
nullptr) {
1811 if (render_layer !=
nullptr) {
1819 for (const int task_index : task_range) {
1820 const RealizeMeshTask &task = tasks[task_index];
1821 execute_realize_mesh_task(options,
1824 dst_attribute_writers,
1831 material_indices.span,
1837 for (GSpanAttributeWriter &dst_attribute : dst_attribute_writers) {
1838 dst_attribute.finish();
1840 vertex_ids.finish();
1841 material_indices.finish();
1842 custom_normals.finish();
1844 if (all_meshes_info.no_loose_edges_hint) {
1845 dst_mesh->tag_loose_edges_none();
1847 if (all_meshes_info.no_loose_verts_hint) {
1848 dst_mesh->tag_loose_verts_none();
1850 if (all_meshes_info.no_overlapping_hint) {
1851 dst_mesh->tag_overlapping_none();
1868 in_geometry_set, bke::GeometryComponent::Type::Curve,
options, varied_depth_option);
1869 attributes_to_propagate.
remove(
"position");
1870 attributes_to_propagate.
remove(
"radius");
1871 attributes_to_propagate.
remove(
"handle_right");
1872 attributes_to_propagate.
remove(
"handle_left");
1873 attributes_to_propagate.
remove(
"custom_normal");
1874 r_create_id = attributes_to_propagate.
pop_try(
"id").has_value();
1876 for (
const auto item : attributes_to_propagate.
items()) {
1877 ordered_attributes.
ids.add_new(item.key);
1878 ordered_attributes.
kinds.append(item.value);
1880 return ordered_attributes;
1887 if (curves->geometry.curve_num != 0) {
1888 r_curves.
add(curves);
1892 instances->foreach_referenced_geometry([&](
const bke::GeometrySet &instance_geometry_set) {
1904 geometry_set,
options, varied_depth_option,
info.create_id_attribute);
1907 info.realize_info.reinitialize(
info.order.size());
1908 for (
const int curve_index :
info.realize_info.index_range()) {
1910 const Curves *curves_id =
info.order[curve_index];
1912 curve_info.
curves = curves_id;
1917 for (
const int attribute_index :
info.attributes.index_range()) {
1919 const StringRef attribute_id =
info.attributes.ids[attribute_index];
1921 if (attributes.
contains(attribute_id)) {
1923 curve_info.
attributes[attribute_index].emplace(std::move(attribute));
1926 if (
info.create_id_attribute) {
1933 if (attributes.
contains(
"radius")) {
1935 attributes.
lookup<
float>(
"radius", bke::AttrDomain::Point).varray.get_internal_span();
1936 info.create_radius_attribute =
true;
1938 if (attributes.
contains(
"handle_right")) {
1940 .varray.get_internal_span();
1942 .varray.get_internal_span();
1943 info.create_handle_postion_attributes =
true;
1945 if (attributes.
contains(
"custom_normal")) {
1947 .varray.get_internal_span();
1948 info.create_custom_normal_attribute =
true;
2015 all_radii.
slice(dst_point_range).
fill(1.0f);
2029 all_custom_normals.
slice(dst_point_range));
2037 for (const int i : range) {
2038 dst_offsets[i] = task.start_indices.point + src_offsets[i];
2042 dst_curves.nurbs_custom_knots_for_write()
2043 .
slice(dst_custom_knot_range)
2044 .
copy_from(curves.nurbs_custom_knots());
2046 if (!all_dst_ids.is_empty()) {
2048 options, curves_info.stored_ids, task.id, all_dst_ids.slice(dst_point_range));
2051 copy_generic_attributes_to_result(
2052 curves_info.attributes,
2053 task.attribute_fallbacks,
2055 [&](
const bke::AttrDomain domain) {
2057 case bke::AttrDomain::Point:
2058 return IndexRange(task.start_indices.point, curves.points_num());
2059 case bke::AttrDomain::Curve:
2060 return IndexRange(task.start_indices.curve, curves.curves_num());
2062 BLI_assert_unreachable();
2063 return IndexRange();
2066 dst_attribute_writers);
2075 existing_names.
add(defgroup->name);
2077 for (
const Curves *src_curve : src_curves) {
2079 if (existing_names.
contains(src->name)) {
2083 existing_names.
add(src->name);
2098 if (tasks.
size() == 1) {
2106 new_curves->
geometry.wrap().attributes_for_write());
2119 Curves *dst_curves_id = bke::curves_new_nomain(points_num, curves_num);
2121 if (custom_knot_num) {
2131 bke::curves_copy_parameters(first_curves_id, *dst_curves_id);
2139 bke::AttrDomain::Point);
2144 for (
const int attribute_index : ordered_attributes.
index_range()) {
2145 const StringRef attribute_id = ordered_attributes.
ids[attribute_index];
2148 dst_attribute_writers.
append(
2157 bke::AttrDomain::Point);
2159 "handle_right", bke::AttrDomain::Point);
2165 bke::AttrDomain::Point);
2170 "custom_normal", bke::AttrDomain::Point);
2175 for (const int task_index : task_range) {
2176 const RealizeCurveTask &task = tasks[task_index];
2177 execute_realize_curve_task(options,
2182 dst_attribute_writers,
2187 custom_normal.span);
2192 dst_curves.runtime->type_counts.fill(0);
2193 for (
const RealizeCurveTask &task : tasks) {
2195 dst_curves.runtime->type_counts[i] +=
2196 task.curve_info->curves->geometry.runtime->type_counts[i];
2201 for (GSpanAttributeWriter &dst_attribute : dst_attribute_writers) {
2202 dst_attribute.finish();
2206 handle_left.finish();
2207 handle_right.finish();
2208 custom_normal.finish();
2223 in_geometry_set, bke::GeometryComponent::Type::GreasePencil,
options, varied_depth_options);
2225 for (
auto &&item : attributes_to_propagate.
items()) {
2226 ordered_attributes.
ids.add_new(item.key);
2227 ordered_attributes.
kinds.append(item.value);
2229 return ordered_attributes;
2236 if (!grease_pencil->layers().is_empty()) {
2237 r_grease_pencils.
add(grease_pencil);
2241 instances->foreach_referenced_geometry([&](
const bke::GeometrySet &instance_geometry_set) {
2254 geometry_set,
options, varied_depth_options);
2257 info.realize_info.reinitialize(
info.order.size());
2258 for (
const int grease_pencil_index :
info.realize_info.index_range()) {
2264 grease_pencil_info.
attributes.reinitialize(
info.attributes.size());
2265 for (
const int attribute_index :
info.attributes.index_range()) {
2266 const StringRef attribute_id =
info.attributes.ids[attribute_index];
2269 if (attributes.
contains(attribute_id)) {
2271 grease_pencil_info.
attributes[attribute_index].emplace(std::move(attribute));
2297 for (
const int layer_i : src_layers.
index_range()) {
2302 dst_layer.set_name(src_layer.name());
2313 dst_curves = src_curves;
2319 for (
int &material_index : material_indices.
span) {
2324 material_indices.
finish();
2332 BLI_assert(domain == bke::AttrDomain::Layer);
2333 UNUSED_VARS_NDEBUG(domain);
2334 return dst_layers_slice;
2336 dst_attribute_writers);
2343 layer->set_local_transform(
transform * layer->local_transform());
2357 if (tasks.
size() == 1) {
2370 const int new_layers_num = last_task.
start_index +
2376 *dst_grease_pencil);
2380 dst_grease_pencil->add_layers_with_empty_drawings_for_eval(new_layers_num);
2396 for (
const int attribute_index : ordered_attributes.
index_range()) {
2397 const StringRef attribute_id = ordered_attributes.
ids[attribute_index];
2400 attribute_id, bke::AttrDomain::Layer, data_type));
2405 for (const int task_index : task_range) {
2406 const RealizeGreasePencilTask &task = tasks[task_index];
2407 execute_realize_grease_pencil_task(
2408 task, ordered_attributes, *dst_grease_pencil, dst_attribute_writers);
2413 for (GSpanAttributeWriter &dst_attribute : dst_attribute_writers) {
2414 dst_attribute.finish();
2430 if (!component.curves_edit_hints_) {
2431 if (task.edit_data->curves_edit_hints_) {
2433 *task.edit_data->curves_edit_hints_);
2436 if (
const bke::GizmoEditHints *src_gizmo_edit_hints = task.edit_data->gizmo_edit_hints_.get())
2438 if (!component.gizmo_edit_hints_) {
2439 component.gizmo_edit_hints_ = std::make_unique<bke::GizmoEditHints>();
2441 for (
auto item : src_gizmo_edit_hints->gizmo_transforms.items()) {
2442 component.gizmo_edit_hints_->gizmo_transforms.add(item.key, task.transform * item.value);
2458 instances->attributes_for_write().remove(
"id");
2474 inverse_selection_indices);
2476 if (inverse_selection.
is_empty()) {
2480 std::unique_ptr<Instances> new_instances = std::make_unique<Instances>(instances);
2481 new_instances->remove(inverse_selection, attribute_filter);
2485 new_instances_components.
replace(new_instances.release(), bke::GeometryOwnershipType::Owned);
2492 return geometry_set;
2514 return geometry_set;
2519 geometry_set, varied_depth_option.
selection, not_to_realize_set,
options.attribute_filter);
2521 if (
options.keep_original_ids) {
2526 geometry_set,
options, varied_depth_option);
2530 geometry_set,
options, varied_depth_option);
2532 geometry_set,
options, varied_depth_option);
2541 all_grease_pencils_info,
2542 all_instance_attributes,
2543 create_id_attribute,
2545 varied_depth_option.
depths,
2561 gather_info, 0, VariedDepthOptions::MAX_DEPTH, geometry_set,
transform, attribute_fallbacks);
2566 all_instance_attributes,
2573 const int64_t approximate_used_bytes_num = total_points_num * 32;
2574 threading::memory_bandwidth_bound_task(approximate_used_bytes_num, [&]() {
2576 all_pointclouds_info,
2601 return new_geometry_set;
struct Curves * BKE_curves_copy_for_eval(const struct Curves *curves_src)
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_named_layer(const CustomData *data, eCustomDataType type, blender::StringRef name)
void CustomData_set_layer_render(CustomData *data, eCustomDataType type, int n)
const char * CustomData_get_render_layer_name(const CustomData *data, eCustomDataType type)
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
void CustomData_set_layer_active(CustomData *data, eCustomDataType type, int n)
Low-level operations for grease pencil.
void BKE_grease_pencil_copy_parameters(const GreasePencil &src, GreasePencil &dst)
GreasePencil * BKE_grease_pencil_new_nomain()
void BKE_grease_pencil_copy_layer_parameters(const blender::bke::greasepencil::Layer &src, blender::bke::greasepencil::Layer &dst)
GreasePencil * BKE_grease_pencil_copy_for_eval(const GreasePencil *grease_pencil_src)
General operations, lookup, etc. for materials.
void BKE_id_material_eval_assign(ID *id, int slot, Material *material)
void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
General operations for point clouds.
PointCloud * BKE_pointcloud_copy_for_eval(const PointCloud *pointcloud_src)
PointCloud * BKE_pointcloud_new_nomain(int totpoint)
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Object is a sort of wrapper for general info.
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Span< T > as_span() const
IndexRange index_range() const
void reinitialize(const int64_t new_size)
void fill_assign_n(const void *value, void *dst, int64_t n) const
const void * default_value() const
GMutableSpan slice(const int64_t start, int64_t size) const
const CPPType & type() const
const CPPType & type() const
GSpan get_internal_span() const
constexpr int64_t size() const
std::optional< Value > pop_try(const Key &key)
bool remove(const Key &key)
auto add_or_modify(const Key &key, const CreateValueF &create_value, const ModifyValueF &modify_value) -> decltype(create_value(nullptr))
ItemIterator items() const &
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr bool is_empty() const
constexpr void fill(const T &value) const
constexpr IndexRange index_range() const
constexpr void copy_from(Span< T > values) const
constexpr T & last(const int64_t n=0) const
bool add_as(ForwardKey &&key)
bool contains(const Key &key) const
constexpr const T & first() const
constexpr int64_t size() const
constexpr const T & last(const int64_t n=0) const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void copy_utf8_truncated(char *dst, int64_t dst_size) const
std::optional< T > get_if_single() const
void materialize(MutableSpan< T > r_span) const
Span< T > get_internal_span() const
int64_t index_of(const Key &key) const
Span< Key > as_span() const
void append(const T &value)
IndexRange index_range() const
bool is_builtin(const StringRef attribute_id) const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
GPointer get_builtin_default(const StringRef attribute_id) const
bool contains(StringRef attribute_id) const
GAttributeReader lookup(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
std::optional< AttributeMetaData > lookup_meta_data(StringRef attribute_id) const
eCustomDataType data_type
GAttributeReader get() const
MutableSpan< float3 > positions_for_write()
IndexRange curves_range() const
MutableAttributeAccessor attributes_for_write()
void nurbs_custom_knots_resize(int knots_num)
Span< int > offsets() const
Span< float3 > positions() const
AttributeAccessor attributes() const
MutableSpan< int > offsets_for_write()
OffsetIndices< int > nurbs_custom_knots_by_curve() const
void convert_to_initialized_n(GSpan from_span, GMutableSpan to_span) const
bool is_convertible(const CPPType &from_type, const CPPType &to_type) const
std::unique_ptr< CurvesEditHints > curves_edit_hints_
int attribute_domain_size(AttrDomain domain) const
void to_geometry_set(GeometrySet &r_geometry_set) const
const Instances * get() const
GeometryComponentPtr copy() const override
void replace(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Span< int > reference_handles() const
Span< float4x4 > transforms() const
Span< InstanceReference > references() const
bke::AttributeAccessor attributes() const
int instances_num() const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool add(const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type)
bke::CurvesGeometry & strokes_for_write()
const bke::CurvesGeometry & strokes() const
void set_local_transform(const float4x4 &transform)
float4x4 local_transform() const
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
void foreach_index(Fn &&fn) const
CCL_NAMESPACE_BEGIN struct Options options
VecBase< short, 2 > short2
VecBase< float, 3 > float3
static void transform_positions(const Span< blender::float3 > src, const blender::float4x4 &transform, blender::MutableSpan< blender::float3 > dst)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_dupallocN(const void *vmemh)
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
static void propagate_instances_to_keep(const bke::GeometrySet &geometry_set, const IndexMask &selection, bke::GeometrySet &new_geometry_set, const bke::AttributeFilter &attribute_filter)
static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, const AllMeshesInfo &all_meshes_info, const Span< RealizeMeshTask > tasks, const OrderedAttributes &ordered_attributes, const VectorSet< Material * > &ordered_materials, bke::GeometrySet &r_realized_geometry)
static void gather_realize_tasks_recursive(GatherTasksInfo &gather_info, const int current_depth, const int target_depth, const bke::GeometrySet &geometry_set, const float4x4 &base_transform, const InstanceContext &base_instance_context)
static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate(const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_option, bool &r_create_radii, bool &r_create_id)
static void execute_realize_pointcloud_tasks(const RealizeInstancesOptions &options, const AllPointCloudsInfo &all_pointclouds_info, const Span< RealizePointCloudTask > tasks, const OrderedAttributes &ordered_attributes, bke::GeometrySet &r_realized_geometry)
static void copy_vertex_group_name(ListBase *dst_deform_group, const OrderedAttributes &ordered_attributes, const bDeformGroup &src_deform_group)
static void threaded_copy(const GSpan src, GMutableSpan dst)
static AllMeshesInfo preprocess_meshes(const bke::GeometrySet &geometry_set, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_option)
static void gather_grease_pencils_to_realize(const bke::GeometrySet &geometry_set, VectorSet< const GreasePencil * > &r_grease_pencils)
static void execute_realize_pointcloud_task(const RealizeInstancesOptions &options, const RealizePointCloudTask &task, const OrderedAttributes &ordered_attributes, MutableSpan< GSpanAttributeWriter > dst_attribute_writers, MutableSpan< float > all_dst_radii, MutableSpan< int > all_dst_ids, MutableSpan< float3 > all_dst_positions)
static int64_t get_final_points_num(const GatherTasks &tasks)
static void gather_pointclouds_to_realize(const bke::GeometrySet &geometry_set, VectorSet< const PointCloud * > &r_pointclouds)
static void execute_realize_grease_pencil_task(const RealizeGreasePencilTask &task, const OrderedAttributes &ordered_attributes, GreasePencil &dst_grease_pencil, MutableSpan< GSpanAttributeWriter > dst_attribute_writers)
static void execute_realize_curve_tasks(const RealizeInstancesOptions &options, const AllCurvesInfo &all_curves_info, const Span< RealizeCurveTask > tasks, const OrderedAttributes &ordered_attributes, bke::GeometrySet &r_realized_geometry)
static void execute_realize_mesh_task(const RealizeInstancesOptions &options, const RealizeMeshTask &task, const OrderedAttributes &ordered_attributes, MutableSpan< GSpanAttributeWriter > dst_attribute_writers, MutableSpan< float3 > all_dst_positions, MutableSpan< int2 > all_dst_edges, MutableSpan< int > all_dst_face_offsets, MutableSpan< int > all_dst_corner_verts, MutableSpan< int > all_dst_corner_edges, MutableSpan< int > all_dst_vertex_ids, MutableSpan< int > all_dst_material_indices, GSpanAttributeWriter &all_dst_custom_normals)
static OrderedAttributes gather_generic_curve_attributes_to_propagate(const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_option, bool &r_create_id)
static Map< StringRef, AttributeDomainAndType > gather_attributes_to_propagate(const bke::GeometrySet &geometry, const bke::GeometryComponent::Type component_type, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_option)
static void gather_realize_tasks_for_instances(GatherTasksInfo &gather_info, const int current_depth, const int target_depth, const Instances &instances, const float4x4 &base_transform, const InstanceContext &base_instance_context)
static void remove_id_attribute_from_instances(bke::GeometrySet &geometry_set)
static void initialize_curves_builtin_attribute_defaults(const AllCurvesInfo &all_curves_info, InstanceContext &attribute_fallbacks)
static void create_result_ids(const RealizeInstancesOptions &options, const Span< int > stored_ids, const int task_id, MutableSpan< int > dst_ids)
static void gather_curves_to_realize(const bke::GeometrySet &geometry_set, VectorSet< const Curves * > &r_curves)
static void transform_grease_pencil_layers(Span< bke::greasepencil::Layer * > layers, const float4x4 &transform)
static void copy_generic_attributes_to_result(const Span< std::optional< GVArraySpan > > src_attributes, const AttributeFallbacksArray &attribute_fallbacks, const OrderedAttributes &ordered_attributes, const FunctionRef< IndexRange(bke::AttrDomain)> &range_fn, MutableSpan< GSpanAttributeWriter > dst_attribute_writers)
void join_attributes(const Span< const bke::GeometryComponent * > src_components, bke::GeometryComponent &r_result, const Span< StringRef > ignored_attributes={})
static void gather_attribute_propagation_components_with_custom_depths(const bke::GeometrySet &geometry, const bke::GeometryComponent::Type component_type, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_option, Set< bke::GeometryComponentPtr > &r_components)
static Vector< std::pair< int, GSpan > > prepare_attribute_fallbacks(GatherTasksInfo &gather_info, const Instances &instances, const OrderedAttributes &ordered_attributes)
static AllPointCloudsInfo preprocess_pointclouds(const bke::GeometrySet &geometry_set, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_option)
static void execute_realize_curve_task(const RealizeInstancesOptions &options, const AllCurvesInfo &all_curves_info, const RealizeCurveTask &task, const OrderedAttributes &ordered_attributes, bke::CurvesGeometry &dst_curves, MutableSpan< GSpanAttributeWriter > dst_attribute_writers, MutableSpan< int > all_dst_ids, MutableSpan< float3 > all_handle_left, MutableSpan< float3 > all_handle_right, MutableSpan< float > all_radii, MutableSpan< float3 > all_custom_normals)
static void copy_vertex_group_names(Mesh &dst_mesh, const OrderedAttributes &ordered_attributes, const Span< const Mesh * > src_meshes)
static bke::AttrDomain normal_domain_to_domain(bke::MeshNormalDomain domain)
static AllCurvesInfo preprocess_curves(const bke::GeometrySet &geometry_set, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_option)
static void gather_meshes_to_realize(const bke::GeometrySet &geometry_set, VectorSet< const Mesh * > &r_meshes)
static void add_instance_attributes_to_single_geometry(const OrderedAttributes &ordered_attributes, const AttributeFallbacksArray &attribute_fallbacks, bke::MutableAttributeAccessor attributes)
static AllGreasePencilsInfo preprocess_grease_pencils(const bke::GeometrySet &geometry_set, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_options)
static OrderedAttributes gather_generic_instance_attributes_to_propagate(const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_option)
static void foreach_geometry_in_reference(const InstanceReference &reference, const float4x4 &base_transform, const uint32_t id, FunctionRef< void(const bke::GeometrySet &geometry_set, const float4x4 &transform, uint32_t id)> fn)
static void threaded_fill(const GPointer value, GMutableSpan dst)
static void execute_realize_edit_data_tasks(const Span< RealizeEditDataTask > tasks, bke::GeometrySet &r_realized_geometry)
static bool skip_transform(const float4x4 &transform)
static OrderedAttributes gather_generic_grease_pencil_attributes_to_propagate(const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_options)
bke::GeometrySet realize_instances(bke::GeometrySet geometry_set, const RealizeInstancesOptions &options)
constexpr bke::AttributeMetaData CORNER_FAN_META_DATA
static void gather_attribute_propagation_components(const bke::GeometrySet &geometry, const bke::GeometryComponent::Type component_type, const RealizeInstancesOptions &options, const int current_depth, const std::optional< int > max_depth, Set< bke::GeometryComponentPtr > &r_components)
static void execute_instances_tasks(const Span< bke::GeometryComponentPtr > src_components, const Span< blender::float4x4 > src_base_transforms, const OrderedAttributes &all_instances_attributes, const Span< blender::geometry::AttributeFallbacksArray > attribute_fallback, bke::GeometrySet &r_realized_geometry)
static void execute_realize_grease_pencil_tasks(const AllGreasePencilsInfo &all_grease_pencils_info, const Span< RealizeGreasePencilTask > tasks, const OrderedAttributes &ordered_attributes, bke::GeometrySet &r_realized_geometry)
static void copy_transformed_positions(const Span< float3 > src, const float4x4 &transform, MutableSpan< float3 > dst)
static OrderedAttributes gather_generic_mesh_attributes_to_propagate(const bke::GeometrySet &in_geometry_set, const RealizeInstancesOptions &options, const VariedDepthOptions &varied_depth_option, bool &r_create_id, bool &r_create_material_index)
void transform_normals(const float3x3 &transform, MutableSpan< float3 > normals)
bool is_equal(const MatBase< T, NumCol, NumRow > &a, const MatBase< T, NumCol, NumRow > &b, const T epsilon=T(0))
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
void uninitialized_copy_n(const T *src, int64_t n, T *dst)
ListBase vertex_group_names
struct Material ** material_array
ListBase vertex_group_names
int vertex_group_active_index
static MatBase identity()
eCustomDataType data_type
bool allow_skip(const StringRef name) const
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
void replace_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Instances * get_instances_for_write()
const GreasePencil * get_grease_pencil() const
Vector< const GeometryComponent * > get_components() const
void replace_pointcloud(PointCloud *pointcloud, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const GeometryComponent * get_component(GeometryComponent::Type component_type) const
const Curves * get_curves() const
const Instances * get_instances() const
bool has_instances() const
void replace_curves(Curves *curves, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
const PointCloud * get_pointcloud() const
const Mesh * get_mesh() const
void modify_geometry_sets(ForeachSubGeometryCallback callback)
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
void add(const GeometryComponent &component)
void replace_grease_pencil(GreasePencil *grease_pencil, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
MutableVArraySpan< T > span
bool create_handle_postion_attributes
OrderedAttributes attributes
bool create_radius_attribute
bool create_custom_normal_attribute
VectorSet< const Curves * > order
Array< RealizeCurveInfo > realize_info
VectorSet< Material * > materials
VectorSet< const GreasePencil * > order
OrderedAttributes attributes
Array< GreasePencilRealizeInfo > realize_info
Vector< AttributeFallbacksArray > attribute_fallback
Vector< float4x4 > instances_components_transforms
Vector< bke::GeometryComponentPtr > instances_components_to_merge
MeshNormalInfo custom_normal_info
VectorSet< Material * > materials
VectorSet< const Mesh * > order
bool create_material_index_attribute
OrderedAttributes attributes
Array< MeshRealizeInfo > realize_info
Array< PointCloudRealizeInfo > realize_info
VectorSet< const PointCloud * > order
OrderedAttributes attributes
bool create_radius_attribute
AttributeFallbacksArray(int size)
Array< const void * > array
MeshElementStartIndices mesh_offsets
int grease_pencil_layer_offset
CurvesElementStartIndices curves_offsets
const AllPointCloudsInfo & pointclouds
const AllCurvesInfo & curves
const VArray< int > & depths
const AllMeshesInfo & meshes
bool create_id_attribute_on_any_component
AllInstancesInfo instances
Vector< std::unique_ptr< GArray<> > > & r_temporary_arrays
const OrderedAttributes & instances_attriubutes
const AllGreasePencilsInfo & grease_pencils
Vector< RealizeMeshTask > mesh_tasks
Vector< RealizeEditDataTask > edit_data_tasks
Vector< RealizePointCloudTask > pointcloud_tasks
Vector< RealizeCurveTask > curve_tasks
ImplicitSharingPtr< const bke::VolumeComponent > first_volume
Vector< RealizeGreasePencilTask > grease_pencil_tasks
Array< std::optional< GVArraySpan > > attributes
Array< int > material_index_map
const GreasePencil * grease_pencil
AttributeFallbacksArray grease_pencils
AttributeFallbacksArray instances
InstanceContext(const GatherTasksInfo &gather_info)
AttributeFallbacksArray meshes
AttributeFallbacksArray pointclouds
AttributeFallbacksArray curves
std::optional< bke::AttrDomain > result_domain
void add_corner_fan_normals()
void add_mesh(const Mesh &mesh)
void add_domain(const bke::AttrDomain domain)
void add_free_normals(const bke::AttrDomain domain)
void add_no_custom_normals(const bke::MeshNormalDomain domain)
Span< int > stored_vertex_ids
VArray< int > material_indices
GVArraySpan custom_normal
OffsetIndices< int > faces
Array< std::optional< GVArraySpan > > attributes
Array< int > material_index_map
IndexRange index_range() const
VectorSet< StringRef > ids
Vector< AttributeDomainAndType > kinds
Array< std::optional< GVArraySpan > > attributes
const PointCloud * pointcloud
Span< float3 > custom_normal
Span< float3 > handle_left
Span< float3 > handle_right
Array< std::optional< GVArraySpan > > attributes
Span< float > nurbs_weight
const RealizeCurveInfo * curve_info
AttributeFallbacksArray attribute_fallbacks
CurvesElementStartIndices start_indices
const bke::GeometryComponentEditData * edit_data
AttributeFallbacksArray attribute_fallbacks
const GreasePencilRealizeInfo * grease_pencil_info
AttributeFallbacksArray attribute_fallbacks
const MeshRealizeInfo * mesh_info
MeshElementStartIndices start_indices
AttributeFallbacksArray attribute_fallbacks
const PointCloudRealizeInfo * pointcloud_info