Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_geometry_set_instances.hh3
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.cc5
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc170
3 files changed, 113 insertions, 65 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set_instances.hh b/source/blender/blenkernel/BKE_geometry_set_instances.hh
index 4f3c9c65203..f918adaff7c 100644
--- a/source/blender/blenkernel/BKE_geometry_set_instances.hh
+++ b/source/blender/blenkernel/BKE_geometry_set_instances.hh
@@ -41,6 +41,7 @@ struct GeometryInstanceGroup {
Vector<GeometryInstanceGroup> geometry_set_gather_instances(const GeometrySet &geometry_set);
+GeometrySet geometry_set_realize_mesh_for_modifier(const GeometrySet &geometry_set);
GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set);
struct AttributeInfo {
@@ -54,7 +55,7 @@ struct AttributeInfo {
* attribute with the given name on all of the input components.
*/
void gather_attribute_info(Map<std::string, AttributeInfo> &attributes,
- const GeometryComponentType component_type,
+ Span<GeometryComponentType> component_types,
Span<bke::GeometryInstanceGroup> set_groups,
const Set<std::string> &ignored_attributes);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index 213e72d496b..4aa7cfae009 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -890,7 +890,7 @@ void BKE_mesh_wrapper_deferred_finalize(Mesh *me_eval,
*/
static Mesh *prepare_geometry_set_for_mesh_modifier(Mesh *mesh, GeometrySet &r_geometry_set)
{
- if (!r_geometry_set.has_instances()) {
+ if (!r_geometry_set.has_instances() && !r_geometry_set.has_pointcloud()) {
return mesh;
}
@@ -901,7 +901,8 @@ static Mesh *prepare_geometry_set_for_mesh_modifier(Mesh *mesh, GeometrySet &r_g
}
{
/* Combine mesh and all instances into a single mesh that can be passed to the modifier. */
- GeometrySet new_geometry_set = blender::bke::geometry_set_realize_instances(r_geometry_set);
+ GeometrySet new_geometry_set = blender::bke::geometry_set_realize_mesh_for_modifier(
+ r_geometry_set);
MeshComponent &mesh_component = new_geometry_set.get_component_for_write<MeshComponent>();
Mesh *new_mesh = mesh_component.release();
r_geometry_set = new_geometry_set;
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index 436fc0f1d1d..66c7f53cdf5 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -24,6 +24,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+#include "DNA_pointcloud_types.h"
namespace blender::bke {
@@ -165,44 +166,47 @@ Vector<GeometryInstanceGroup> geometry_set_gather_instances(const GeometrySet &g
}
void gather_attribute_info(Map<std::string, AttributeInfo> &attributes,
- const GeometryComponentType component_type,
+ Span<GeometryComponentType> component_types,
Span<GeometryInstanceGroup> set_groups,
const Set<std::string> &ignored_attributes)
{
for (const GeometryInstanceGroup &set_group : set_groups) {
const GeometrySet &set = set_group.geometry_set;
- if (!set.has(component_type)) {
- continue;
- }
- const GeometryComponent &component = *set.get_component_for_read(component_type);
-
- for (const std::string &name : component.attribute_names()) {
- if (ignored_attributes.contains(name)) {
+ for (const GeometryComponentType component_type : component_types) {
+ if (!set.has(component_type)) {
continue;
}
- const ReadAttributePtr read_attribute = component.attribute_try_get_for_read(name);
- if (!read_attribute) {
- continue;
+ const GeometryComponent &component = *set.get_component_for_read(component_type);
+
+ for (const std::string &name : component.attribute_names()) {
+ if (ignored_attributes.contains(name)) {
+ continue;
+ }
+ const ReadAttributePtr read_attribute = component.attribute_try_get_for_read(name);
+ if (!read_attribute) {
+ continue;
+ }
+ const AttributeDomain domain = read_attribute->domain();
+ const CustomDataType data_type = read_attribute->custom_data_type();
+
+ auto add_info = [&, data_type, domain](AttributeInfo *info) {
+ info->domain = domain;
+ info->data_type = data_type;
+ };
+ auto modify_info = [&, data_type, domain](AttributeInfo *info) {
+ info->domain = domain; /* TODO: Use highest priority domain. */
+ info->data_type = bke::attribute_data_type_highest_complexity(
+ {info->data_type, data_type});
+ };
+
+ attributes.add_or_modify(name, add_info, modify_info);
}
- const AttributeDomain domain = read_attribute->domain();
- const CustomDataType data_type = read_attribute->custom_data_type();
-
- auto add_info = [&, data_type, domain](AttributeInfo *info) {
- info->domain = domain;
- info->data_type = data_type;
- };
- auto modify_info = [&, data_type, domain](AttributeInfo *info) {
- info->domain = domain; /* TODO: Use highest priority domain. */
- info->data_type = bke::attribute_data_type_highest_complexity(
- {info->data_type, data_type});
- };
-
- attributes.add_or_modify(name, add_info, modify_info);
}
}
}
-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 totloops = 0;
@@ -214,17 +218,22 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou
int64_t cd_dirty_loop = 0;
for (const GeometryInstanceGroup &set_group : set_groups) {
const GeometrySet &set = set_group.geometry_set;
+ const int tot_transforms = set_group.transforms.size();
if (set.has_mesh()) {
const Mesh &mesh = *set.get_mesh_for_read();
- totverts += mesh.totvert * set_group.transforms.size();
- totloops += mesh.totloop * set_group.transforms.size();
- totedges += mesh.totedge * set_group.transforms.size();
- totpolys += mesh.totpoly * set_group.transforms.size();
+ totverts += mesh.totvert * tot_transforms;
+ totloops += mesh.totloop * tot_transforms;
+ totedges += mesh.totedge * tot_transforms;
+ totpolys += mesh.totpoly * tot_transforms;
cd_dirty_vert |= mesh.runtime.cd_dirty_vert;
cd_dirty_poly |= mesh.runtime.cd_dirty_poly;
cd_dirty_edge |= mesh.runtime.cd_dirty_edge;
cd_dirty_loop |= mesh.runtime.cd_dirty_loop;
}
+ if (convert_points_to_vertices && set.has_pointcloud()) {
+ const PointCloud &pointcloud = *set.get_pointcloud_for_read();
+ totverts += pointcloud.totpoint * tot_transforms;
+ }
}
Mesh *new_mesh = BKE_mesh_new_nomain(totverts, totedges, 0, totloops, totpolys);
@@ -287,13 +296,25 @@ static Mesh *join_mesh_topology_and_builtin_attributes(Span<GeometryInstanceGrou
poly_offset += mesh.totpoly;
}
}
+ 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);
+ }
+ vert_offset += pointcloud.totpoint;
+ }
+ }
}
return new_mesh;
}
static void join_attributes(Span<GeometryInstanceGroup> set_groups,
- const GeometryComponentType component_type,
+ Span<GeometryComponentType> component_types,
const Map<std::string, AttributeInfo> &attribute_info,
GeometryComponent &result)
{
@@ -315,26 +336,28 @@ static void join_attributes(Span<GeometryInstanceGroup> set_groups,
int offset = 0;
for (const GeometryInstanceGroup &set_group : set_groups) {
const GeometrySet &set = set_group.geometry_set;
- if (set.has(component_type)) {
- const GeometryComponent &component = *set.get_component_for_read(component_type);
- const int domain_size = component.attribute_domain_size(domain_output);
- if (domain_size == 0) {
- continue; /* Domain size is 0, so no need to increment the offset. */
- }
- ReadAttributePtr source_attribute = component.attribute_try_get_for_read(
- name, domain_output, data_type_output);
-
- if (source_attribute) {
- fn::GSpan src_span = source_attribute->get_span();
- const void *src_buffer = src_span.data();
- for (const int UNUSED(i) : set_group.transforms.index_range()) {
- void *dst_buffer = dst_span[offset];
- cpp_type->copy_to_initialized_n(src_buffer, dst_buffer, domain_size);
- offset += domain_size;
+ for (const GeometryComponentType component_type : component_types) {
+ if (set.has(component_type)) {
+ const GeometryComponent &component = *set.get_component_for_read(component_type);
+ const int domain_size = component.attribute_domain_size(domain_output);
+ if (domain_size == 0) {
+ continue; /* Domain size is 0, so no need to increment the offset. */
+ }
+ ReadAttributePtr source_attribute = component.attribute_try_get_for_read(
+ name, domain_output, data_type_output);
+
+ if (source_attribute) {
+ fn::GSpan src_span = source_attribute->get_span();
+ const void *src_buffer = src_span.data();
+ for (const int UNUSED(i) : set_group.transforms.index_range()) {
+ void *dst_buffer = dst_span[offset];
+ cpp_type->copy_to_initialized_n(src_buffer, dst_buffer, domain_size);
+ offset += domain_size;
+ }
+ }
+ else {
+ offset += domain_size * set_group.transforms.size();
}
- }
- else {
- offset += domain_size * set_group.transforms.size();
}
}
}
@@ -343,21 +366,27 @@ static void join_attributes(Span<GeometryInstanceGroup> set_groups,
}
}
-static void join_instance_groups_mesh(Span<GeometryInstanceGroup> set_groups, GeometrySet &result)
+static void join_instance_groups_mesh(Span<GeometryInstanceGroup> set_groups,
+ 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);
MeshComponent &dst_component = result.get_component_for_write<MeshComponent>();
dst_component.replace(new_mesh);
+ Vector<GeometryComponentType> component_types;
+ component_types.append(GeometryComponentType::Mesh);
+ if (convert_points_to_vertices) {
+ component_types.append(GeometryComponentType::PointCloud);
+ }
+
/* Don't copy attributes that are stored directly in the mesh data structs. */
Map<std::string, AttributeInfo> attributes;
- gather_attribute_info(
- attributes, GeometryComponentType::Mesh, set_groups, {"position", "material_index"});
- join_attributes(set_groups,
- GeometryComponentType::Mesh,
- attributes,
- static_cast<GeometryComponent &>(dst_component));
+ gather_attribute_info(attributes, component_types, set_groups, {"position", "material_index"});
+ join_attributes(
+ set_groups, component_types, attributes, static_cast<GeometryComponent &>(dst_component));
}
static void join_instance_groups_pointcloud(Span<GeometryInstanceGroup> set_groups,
@@ -376,9 +405,9 @@ static void join_instance_groups_pointcloud(Span<GeometryInstanceGroup> set_grou
PointCloud *pointcloud = BKE_pointcloud_new_nomain(totpoint);
dst_component.replace(pointcloud);
Map<std::string, AttributeInfo> attributes;
- gather_attribute_info(attributes, GeometryComponentType::Mesh, set_groups, {});
+ gather_attribute_info(attributes, {GeometryComponentType::PointCloud}, set_groups, {});
join_attributes(set_groups,
- GeometryComponentType::PointCloud,
+ {GeometryComponentType::PointCloud},
attributes,
static_cast<GeometryComponent &>(dst_component));
}
@@ -392,6 +421,23 @@ static void join_instance_groups_volume(Span<GeometryInstanceGroup> set_groups,
UNUSED_VARS(set_groups, 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);
+ 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)
{
if (!geometry_set.has_instances()) {
@@ -400,8 +446,8 @@ GeometrySet geometry_set_realize_instances(const GeometrySet &geometry_set)
GeometrySet new_geometry_set;
- Vector<GeometryInstanceGroup> set_groups = bke::geometry_set_gather_instances(geometry_set);
- join_instance_groups_mesh(set_groups, new_geometry_set);
+ Vector<GeometryInstanceGroup> set_groups = geometry_set_gather_instances(geometry_set);
+ join_instance_groups_mesh(set_groups, false, new_geometry_set);
join_instance_groups_pointcloud(set_groups, new_geometry_set);
join_instance_groups_volume(set_groups, new_geometry_set);