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:
authorHans Goudey <h.goudey@me.com>2021-02-03 08:22:35 +0300
committerHans Goudey <h.goudey@me.com>2021-02-03 08:22:35 +0300
commitc9383993f88e2e7b9ddef19e88c275300cd758cc (patch)
tree6b99f6cf406581e590b170cda2f8272add5eb456
parent89d5710830d41f8bac9925c2cdc482ec9f8d7c3b (diff)
Add a second idea for the instances API
-rw-r--r--source/blender/blenkernel/intern/geometry_set.cc80
1 files changed, 76 insertions, 4 deletions
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc
index 005d07688d7..b0023e2ad0c 100644
--- a/source/blender/blenkernel/intern/geometry_set.cc
+++ b/source/blender/blenkernel/intern/geometry_set.cc
@@ -571,10 +571,6 @@ bool InstancesComponent::is_empty() const
return transforms_.size() == 0;
}
-static void foreach_geometry_component_recursive(const GeometrySet &geometry_set,
- const ForeachGeometryCallbackConst &callback,
- const float4x4 &transform);
-
static GeometrySet object_get_geometry_set_for_read(const Object &object)
{
/* Objects evaluated with a nodes modifier will have a geometry set already. */
@@ -605,6 +601,10 @@ static GeometrySet object_get_geometry_set_for_read(const Object &object)
return new_geometry_set;
}
+static void foreach_geometry_component_recursive(const GeometrySet &geometry_set,
+ const ForeachGeometryCallbackConst &callback,
+ const float4x4 &transform);
+
static void foreach_collection_geometry_set_recursive(const Collection &collection,
const ForeachGeometryCallbackConst &callback,
const float4x4 &transform)
@@ -673,6 +673,78 @@ void BKE_foreach_geometry_component_recursive(const GeometrySet &geometry_set,
foreach_geometry_component_recursive(geometry_set, callback, unit_transform);
}
+/* ============= API 2 =============== */
+
+using GeometrySetGroup = std::pair<GeometrySet, Vector<float4x4>>;
+
+static void collect_geometry_set_recursive(
+ const GeometrySet &geometry_set,
+ const float4x4 &transform,
+ Vector<std::pair<GeometrySet, Vector<float4x4>>> &r_sets);
+
+static void collect_collection_geometry_set_recursive(const Collection &collection,
+ const float4x4 &transform,
+ Vector<GeometrySetGroup> &r_sets)
+{
+ LISTBASE_FOREACH (const CollectionObject *, collection_object, &collection.gobject) {
+ BLI_assert(collection_object->ob != nullptr);
+ const Object &object = *collection_object->ob;
+ GeometrySet instance_geometry_set = object_get_geometry_set_for_read(object);
+
+ /* TODO: This seems to work-- validate this. */
+ const float4x4 instance_transform = transform * object.obmat;
+ collect_geometry_set_recursive(instance_geometry_set, instance_transform, r_sets);
+ }
+ LISTBASE_FOREACH (const CollectionChild *, collection_child, &collection.children) {
+ BLI_assert(collection_child->collection != nullptr);
+ const Collection &collection = *collection_child->collection;
+ collect_collection_geometry_set_recursive(collection, transform, r_sets);
+ }
+}
+
+static void collect_geometry_set_recursive(const GeometrySet &geometry_set,
+ const float4x4 &transform,
+ Vector<GeometrySetGroup> &r_sets)
+{
+ r_sets.append({geometry_set, {transform}});
+
+ if (geometry_set.has_instances()) {
+ 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];
+ const float4x4 &transform = transforms[i];
+
+ if (data.type == INSTANCE_DATA_TYPE_OBJECT) {
+ BLI_assert(data.data.object != nullptr);
+ const Object &object = *data.data.object;
+ GeometrySet instance_geometry_set = object_get_geometry_set_for_read(object);
+ collect_geometry_set_recursive(instance_geometry_set, transform, r_sets);
+ }
+ else if (data.type == INSTANCE_DATA_TYPE_COLLECTION) {
+ BLI_assert(data.data.collection != nullptr);
+ const Collection &collection = *data.data.collection;
+ collect_collection_geometry_set_recursive(collection, transform, r_sets);
+ }
+ }
+ }
+}
+
+Vector<GeometrySetGroup> BKE_geometry_set_gather_instanced(const GeometrySet &geometry_set)
+{
+ Vector<GeometrySetGroup> result_vector;
+
+ float4x4 unit_transform;
+ unit_m4(unit_transform.values);
+
+ collect_geometry_set_recursive(geometry_set, unit_transform, result_vector);
+
+ return result_vector;
+}
+
/** \} */
/* -------------------------------------------------------------------- */