Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/geometry_set_instances.cc
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGroup> set_groups, | static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGroup> set_groups) | ||||
| const bool convert_points_to_vertices) | |||||
| { | { | ||||
| int totverts = 0; | int totverts = 0; | ||||
| int totloops = 0; | int totloops = 0; | ||||
| Context not available. | |||||
| materials.add(material); | materials.add(material); | ||||
| } | } | ||||
| } | } | ||||
| if (convert_points_to_vertices && set.has_pointcloud()) { | |||||
| const PointCloud &pointcloud = *set.get_pointcloud_for_read(); | |||||
| totverts += pointcloud.totpoint * tot_transforms; | |||||
| } | |||||
| } | } | ||||
| /* Don't create an empty mesh. */ | /* Don't create an empty mesh. */ | ||||
| Context not available. | |||||
| poly_offset += mesh.totpoly; | poly_offset += mesh.totpoly; | ||||
| } | } | ||||
| } | } | ||||
| const float3 point_normal{0.0f, 0.0f, 1.0f}; | |||||
| short point_normal_short[3]; | |||||
| normal_float_to_short_v3(point_normal_short, point_normal); | |||||
| if (convert_points_to_vertices && set.has_pointcloud()) { | |||||
| const PointCloud &pointcloud = *set.get_pointcloud_for_read(); | |||||
| for (const float4x4 &transform : set_group.transforms) { | |||||
| for (const int i : IndexRange(pointcloud.totpoint)) { | |||||
| MVert &new_vert = new_mesh->mvert[vert_offset + i]; | |||||
| const float3 old_position = pointcloud.co[i]; | |||||
| const float3 new_position = transform * old_position; | |||||
| copy_v3_v3(new_vert.co, new_position); | |||||
| memcpy(&new_vert.no, point_normal_short, sizeof(point_normal_short)); | |||||
| } | |||||
| vert_offset += pointcloud.totpoint; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /* A possible optimization is to only tag the normals dirty when there are transforms that change | /* A possible optimization is to only tag the normals dirty when there are transforms that change | ||||
| Context not available. | |||||
| return new_curve; | return new_curve; | ||||
| } | } | ||||
| static void join_instance_groups_mesh(Span<GeometryInstanceGroup> set_groups, | static void join_instance_groups_mesh(Span<GeometryInstanceGroup> set_groups, GeometrySet &result) | ||||
| bool convert_points_to_vertices, | |||||
| GeometrySet &result) | |||||
| { | { | ||||
| Mesh *new_mesh = join_mesh_topology_and_builtin_attributes(set_groups, | Mesh *new_mesh = join_mesh_topology_and_builtin_attributes(set_groups); | ||||
| convert_points_to_vertices); | |||||
| if (new_mesh == nullptr) { | if (new_mesh == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| Context not available. | |||||
| MeshComponent &dst_component = result.get_component_for_write<MeshComponent>(); | MeshComponent &dst_component = result.get_component_for_write<MeshComponent>(); | ||||
| dst_component.replace(new_mesh); | dst_component.replace(new_mesh); | ||||
| Vector<GeometryComponentType> component_types; | |||||
| component_types.append(GEO_COMPONENT_TYPE_MESH); | |||||
| if (convert_points_to_vertices) { | |||||
| component_types.append(GEO_COMPONENT_TYPE_POINT_CLOUD); | |||||
| } | |||||
| /* Don't copy attributes that are stored directly in the mesh data structs. */ | /* Don't copy attributes that are stored directly in the mesh data structs. */ | ||||
| Map<AttributeIDRef, AttributeKind> attributes; | Map<AttributeIDRef, AttributeKind> attributes; | ||||
| geometry_set_gather_instances_attribute_info( | geometry_set_gather_instances_attribute_info( | ||||
| set_groups, | set_groups, | ||||
| component_types, | {GEO_COMPONENT_TYPE_MESH}, | ||||
| {"position", "material_index", "normal", "shade_smooth", "crease"}, | {"position", "material_index", "normal", "shade_smooth", "crease"}, | ||||
| attributes); | attributes); | ||||
| join_attributes( | join_attributes(set_groups, | ||||
| set_groups, component_types, attributes, static_cast<GeometryComponent &>(dst_component)); | {GEO_COMPONENT_TYPE_MESH}, | ||||
| attributes, | |||||
| static_cast<GeometryComponent &>(dst_component)); | |||||
| } | } | ||||
| static void join_instance_groups_pointcloud(Span<GeometryInstanceGroup> set_groups, | static void join_instance_groups_pointcloud(Span<GeometryInstanceGroup> set_groups, | ||||
| Context not available. | |||||
| static_cast<GeometryComponent &>(dst_component)); | static_cast<GeometryComponent &>(dst_component)); | ||||
| } | } | ||||
| GeometrySet geometry_set_realize_mesh_for_modifier(const GeometrySet &geometry_set) | |||||
| { | |||||
| if (!geometry_set.has_instances() && !geometry_set.has_pointcloud()) { | |||||
| return geometry_set; | |||||
| } | |||||
| GeometrySet new_geometry_set = geometry_set; | |||||
| Vector<GeometryInstanceGroup> set_groups; | |||||
| geometry_set_gather_instances(geometry_set, set_groups); | |||||
| join_instance_groups_mesh(set_groups, true, new_geometry_set); | |||||
| /* Remove all instances, even though some might contain other non-mesh data. We can't really | |||||
| * keep only non-mesh instances in general. */ | |||||
| new_geometry_set.remove<InstancesComponent>(); | |||||
| /* If there was a point cloud, it is now part of the mesh. */ | |||||
| new_geometry_set.remove<PointCloudComponent>(); | |||||
| return new_geometry_set; | |||||
| } | |||||
| GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set) | GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set) | ||||
| { | { | ||||
| if (!geometry_set.has_instances()) { | if (!geometry_set.has_instances()) { | ||||
| Context not available. | |||||
| Vector<GeometryInstanceGroup> set_groups; | Vector<GeometryInstanceGroup> set_groups; | ||||
| geometry_set_gather_instances(geometry_set, set_groups); | geometry_set_gather_instances(geometry_set, set_groups); | ||||
| join_instance_groups_mesh(set_groups, false, new_geometry_set); | join_instance_groups_mesh(set_groups, new_geometry_set); | ||||
| join_instance_groups_pointcloud(set_groups, new_geometry_set); | join_instance_groups_pointcloud(set_groups, new_geometry_set); | ||||
| join_instance_groups_volume(set_groups, new_geometry_set); | join_instance_groups_volume(set_groups, new_geometry_set); | ||||
| join_instance_groups_curve(set_groups, new_geometry_set); | join_instance_groups_curve(set_groups, new_geometry_set); | ||||
| Context not available. | |||||