Geometry Nodes: remove old method to iterate over attributes

The previous commit added a new method to the same in a better way.
This commit is contained in:
Jacques Lucke 2021-09-23 17:59:14 +02:00
parent 38af29df5c
commit 502543e46b
3 changed files with 13 additions and 138 deletions

View File

@ -39,10 +39,6 @@ struct GeometryInstanceGroup {
Vector<float4x4> transforms;
};
void geometry_set_instances_attribute_foreach(const GeometrySet &geometry_set,
const AttributeForeachCallback callback,
const int limit);
void geometry_set_gather_instances(const GeometrySet &geometry_set,
Vector<GeometryInstanceGroup> &r_instance_groups);

View File

@ -189,134 +189,6 @@ void geometry_set_gather_instances(const GeometrySet &geometry_set,
geometry_set_collect_recursive(geometry_set, unit_transform, r_instance_groups);
}
static bool collection_instance_attribute_foreach(const Collection &collection,
const AttributeForeachCallback callback,
const int limit,
int &count);
static bool instances_attribute_foreach_recursive(const GeometrySet &geometry_set,
const AttributeForeachCallback callback,
const int limit,
int &count);
static bool object_instance_attribute_foreach(const Object &object,
const AttributeForeachCallback callback,
const int limit,
int &count)
{
GeometrySet instance_geometry_set = object_get_geometry_set_for_read(object);
if (!instances_attribute_foreach_recursive(instance_geometry_set, callback, limit, count)) {
return false;
}
if (object.type == OB_EMPTY) {
const Collection *collection_instance = object.instance_collection;
if (collection_instance != nullptr) {
if (!collection_instance_attribute_foreach(*collection_instance, callback, limit, count)) {
return false;
}
}
}
return true;
}
static bool collection_instance_attribute_foreach(const Collection &collection,
const AttributeForeachCallback callback,
const int limit,
int &count)
{
LISTBASE_FOREACH (const CollectionObject *, collection_object, &collection.gobject) {
BLI_assert(collection_object->ob != nullptr);
const Object &object = *collection_object->ob;
if (!object_instance_attribute_foreach(object, callback, limit, count)) {
return false;
}
}
LISTBASE_FOREACH (const CollectionChild *, collection_child, &collection.children) {
BLI_assert(collection_child->collection != nullptr);
const Collection &collection = *collection_child->collection;
if (!collection_instance_attribute_foreach(collection, callback, limit, count)) {
return false;
}
}
return true;
}
/**
* \return True if the recursive iteration should continue, false if the limit is reached or the
* callback has returned false indicating it should stop.
*/
static bool instances_attribute_foreach_recursive(const GeometrySet &geometry_set,
const AttributeForeachCallback callback,
const int limit,
int &count)
{
for (const GeometryComponent *component : geometry_set.get_components_for_read()) {
if (!component->attribute_foreach(callback)) {
return false;
}
}
/* Now that this geometry set is visited, increase the count and check with the limit. */
if (limit > 0 && count++ > limit) {
return false;
}
const InstancesComponent *instances_component =
geometry_set.get_component_for_read<InstancesComponent>();
if (instances_component == nullptr) {
return true;
}
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;
}
case InstanceReference::Type::Collection: {
const Collection &collection = reference.collection();
if (!collection_instance_attribute_foreach(collection, callback, limit, count)) {
return false;
}
break;
}
case InstanceReference::Type::GeometrySet: {
const GeometrySet &geometry_set = reference.geometry_set();
if (!instances_attribute_foreach_recursive(geometry_set, callback, limit, count)) {
return false;
}
break;
}
case InstanceReference::Type::None: {
break;
}
}
}
return true;
}
/**
* Call the callback on all of this geometry set's components, including geometry sets from
* instances and recursive instances. This is necessary to access available attributes without
* making all of the set's geometry real.
*
* \param limit: The total number of geometry sets to visit before returning early. This is used
* to avoid looking through too many geometry sets recursively, as an explicit tradeoff in favor
* of performance at the cost of visiting every unique attribute.
*/
void geometry_set_instances_attribute_foreach(const GeometrySet &geometry_set,
const AttributeForeachCallback callback,
const int limit)
{
int count = 0;
instances_attribute_foreach_recursive(geometry_set, callback, limit, count);
}
void geometry_set_gather_instances_attribute_info(Span<GeometryInstanceGroup> set_groups,
Span<GeometryComponentType> component_types,
const Set<std::string> &ignored_attributes,

View File

@ -159,15 +159,22 @@ const SocketLog *NodeLog::lookup_socket_log(const bNode &node, const bNodeSocket
GeometryValueLog::GeometryValueLog(const GeometrySet &geometry_set, bool log_full_geometry)
{
bke::geometry_set_instances_attribute_foreach(
geometry_set,
[&](const bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
static std::array all_component_types = {GEO_COMPONENT_TYPE_CURVE,
GEO_COMPONENT_TYPE_INSTANCES,
GEO_COMPONENT_TYPE_MESH,
GEO_COMPONENT_TYPE_POINT_CLOUD,
GEO_COMPONENT_TYPE_VOLUME};
geometry_set.attribute_foreach(
all_component_types,
true,
[&](const bke::AttributeIDRef &attribute_id,
const AttributeMetaData &meta_data,
const GeometryComponent &UNUSED(component)) {
if (attribute_id.is_named()) {
this->attributes_.append({attribute_id.name(), meta_data.domain, meta_data.data_type});
}
return true;
},
8);
});
for (const GeometryComponent *component : geometry_set.get_components_for_read()) {
component_types_.append(component->type());
switch (component->type()) {