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/intern/geometry_set_instances.cc')
-rw-r--r--source/blender/blenkernel/intern/geometry_set_instances.cc123
1 files changed, 90 insertions, 33 deletions
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index 07d0e520c93..b6ee0337dbf 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -19,6 +19,7 @@
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_pointcloud.h"
+#include "BKE_spline.hh"
#include "DNA_collection_types.h"
#include "DNA_mesh_types.h"
@@ -50,6 +51,16 @@ static void add_final_mesh_as_geometry_component(const Object &object, GeometryS
}
}
+static void add_curve_data_as_geometry_component(const Object &object, GeometrySet &geometry_set)
+{
+ BLI_assert(object.type == OB_CURVE);
+ if (object.data != nullptr) {
+ std::unique_ptr<CurveEval> curve = curve_eval_from_dna_curve(*(Curve *)object.data);
+ CurveComponent &curve_component = geometry_set.get_component_for_write<CurveComponent>();
+ curve_component.replace(curve.release(), GeometryOwnershipType::Owned);
+ }
+}
+
/**
* \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances.
*/
@@ -73,6 +84,9 @@ static GeometrySet object_get_geometry_set_for_read(const Object &object)
if (object.type == OB_MESH) {
add_final_mesh_as_geometry_component(object, geometry_set);
}
+ else if (object.type == OB_CURVE) {
+ add_curve_data_as_geometry_component(object, geometry_set);
+ }
/* TODO: Cover the case of point-clouds without modifiers-- they may not be covered by the
* #geometry_set_eval case above. */
@@ -135,21 +149,28 @@ static void geometry_set_collect_recursive(const GeometrySet &geometry_set,
const InstancesComponent &instances_component =
*geometry_set.get_component_for_read<InstancesComponent>();
- Span<float4x4> transforms = instances_component.transforms();
- Span<InstancedData> instances = instances_component.instanced_data();
- for (const int i : instances.index_range()) {
- const InstancedData &data = instances[i];
+ Span<float4x4> transforms = instances_component.instance_transforms();
+ Span<int> handles = instances_component.instance_reference_handles();
+ Span<InstanceReference> references = instances_component.references();
+ for (const int i : transforms.index_range()) {
+ const InstanceReference &reference = references[handles[i]];
const float4x4 instance_transform = transform * transforms[i];
- if (data.type == INSTANCE_DATA_TYPE_OBJECT) {
- BLI_assert(data.data.object != nullptr);
- const Object &object = *data.data.object;
- geometry_set_collect_recursive_object(object, instance_transform, r_sets);
- }
- else if (data.type == INSTANCE_DATA_TYPE_COLLECTION) {
- BLI_assert(data.data.collection != nullptr);
- const Collection &collection = *data.data.collection;
- geometry_set_collect_recursive_collection_instance(collection, instance_transform, r_sets);
+ switch (reference.type()) {
+ case InstanceReference::Type::Object: {
+ Object &object = reference.object();
+ geometry_set_collect_recursive_object(object, instance_transform, r_sets);
+ break;
+ }
+ case InstanceReference::Type::Collection: {
+ Collection &collection = reference.collection();
+ geometry_set_collect_recursive_collection_instance(
+ collection, instance_transform, r_sets);
+ break;
+ }
+ case InstanceReference::Type::None: {
+ break;
+ }
}
}
}
@@ -253,19 +274,24 @@ static bool instances_attribute_foreach_recursive(const GeometrySet &geometry_se
return true;
}
- for (const InstancedData &data : instances_component->instanced_data()) {
- if (data.type == INSTANCE_DATA_TYPE_OBJECT) {
- BLI_assert(data.data.object != nullptr);
- const Object &object = *data.data.object;
- if (!object_instance_attribute_foreach(object, callback, limit, count)) {
- return false;
+ for (const InstanceReference &reference : instances_component->references()) {
+ switch (reference.type()) {
+ case InstanceReference::Type::Object: {
+ const Object &object = reference.object();
+ if (!object_instance_attribute_foreach(object, callback, limit, count)) {
+ return false;
+ }
+ break;
}
- }
- else if (data.type == INSTANCE_DATA_TYPE_COLLECTION) {
- BLI_assert(data.data.collection != nullptr);
- const Collection &collection = *data.data.collection;
- if (!collection_instance_attribute_foreach(collection, callback, limit, count)) {
- return false;
+ case InstanceReference::Type::Collection: {
+ const Collection &collection = reference.collection();
+ if (!collection_instance_attribute_foreach(collection, callback, limit, count)) {
+ return false;
+ }
+ break;
+ }
+ case InstanceReference::Type::None: {
+ break;
}
}
}
@@ -449,13 +475,15 @@ static void join_attributes(Span<GeometryInstanceGroup> set_groups,
const CPPType *cpp_type = bke::custom_data_type_to_cpp_type(data_type_output);
BLI_assert(cpp_type != nullptr);
- result.attribute_try_create(entry.key, domain_output, data_type_output);
- WriteAttributePtr write_attribute = result.attribute_try_get_for_write(name);
- if (!write_attribute || &write_attribute->cpp_type() != cpp_type ||
- write_attribute->domain() != domain_output) {
+ result.attribute_try_create(
+ entry.key, domain_output, data_type_output, AttributeInitDefault());
+ WriteAttributeLookup write_attribute = result.attribute_try_get_for_write(name);
+ if (!write_attribute || &write_attribute.varray->type() != cpp_type ||
+ write_attribute.domain != domain_output) {
continue;
}
- fn::GMutableSpan dst_span = write_attribute->get_span_for_write_only();
+
+ fn::GVMutableArray_GSpan dst_span{*write_attribute.varray};
int offset = 0;
for (const GeometryInstanceGroup &set_group : set_groups) {
@@ -467,11 +495,11 @@ static void join_attributes(Span<GeometryInstanceGroup> set_groups,
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(
+ GVArrayPtr 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();
+ fn::GVArray_GSpan src_span{*source_attribute};
const void *src_buffer = src_span.data();
for (const int UNUSED(i) : set_group.transforms.index_range()) {
void *dst_buffer = dst_span[offset];
@@ -486,10 +514,32 @@ static void join_attributes(Span<GeometryInstanceGroup> set_groups,
}
}
- write_attribute->apply_span();
+ dst_span.save();
}
}
+static void join_curve_splines(Span<GeometryInstanceGroup> set_groups, CurveComponent &result)
+{
+ CurveEval *new_curve = new CurveEval();
+ for (const GeometryInstanceGroup &set_group : set_groups) {
+ const GeometrySet &set = set_group.geometry_set;
+ if (!set.has_curve()) {
+ continue;
+ }
+
+ const CurveEval &source_curve = *set.get_curve_for_read();
+ for (const SplinePtr &source_spline : source_curve.splines()) {
+ for (const float4x4 &transform : set_group.transforms) {
+ SplinePtr new_spline = source_spline->copy();
+ new_spline->transform(transform);
+ new_curve->add_spline(std::move(new_spline));
+ }
+ }
+ }
+
+ result.replace(new_curve);
+}
+
static void join_instance_groups_mesh(Span<GeometryInstanceGroup> set_groups,
bool convert_points_to_vertices,
GeometrySet &result)
@@ -556,6 +606,12 @@ static void join_instance_groups_volume(Span<GeometryInstanceGroup> set_groups,
UNUSED_VARS(set_groups, dst_component);
}
+static void join_instance_groups_curve(Span<GeometryInstanceGroup> set_groups, GeometrySet &result)
+{
+ CurveComponent &dst_component = result.get_component_for_write<CurveComponent>();
+ join_curve_splines(set_groups, dst_component);
+}
+
GeometrySet geometry_set_realize_mesh_for_modifier(const GeometrySet &geometry_set)
{
if (!geometry_set.has_instances() && !geometry_set.has_pointcloud()) {
@@ -587,6 +643,7 @@ GeometrySet geometry_set_realize_instances(const GeometrySet &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);
+ join_instance_groups_curve(set_groups, new_geometry_set);
return new_geometry_set;
}