Geometry: generalize attribute filters beyond just for anonymous attributes

This introduces the concept of an #AttributeFilter. It's used to tell a geometry
algorithm which attributes it should process/propagate and which can be ignored.

We already had something similar before named
`AnonymousAttributePropagationInfo`. However, as the name implies, this was
specific to anonymous attributes. This had some downsides:
* A lot of code had to be aware of the concept of anonymous attributes even if
  it did nothing special with anonymous attributes.
* For non-anonymous attributes we often had a separate `Set<std::string> skip`
  parameter. It's not nice to have to pass two kinds of filters around and to
  have to construct a `Set<std::string>` in many cases.

`AttributeFilter` solves both of these downsides.

Technically, `AttributeFilter` could also just be a `FunctionRef<bool(StringRef
attribute_name)>`, but that also has some issues:
* The `bool` return value is often ambiguous, i.e. it's not clear if it means
  that the attribute should be processed or not. Using an enum works better.
* Passing function refs around and combining them works, but can very easily
  lead to dangling references.
* The default value of a `FunctionRef` is "empty", i.e. it can't be called. It's
  generally more nice to not have a special case for the default value. Now the
  default `AttributeFilter` propagates all attributes without any extra handling
  on the call-site.

Pull Request: https://projects.blender.org/blender/blender/pulls/127155
This commit is contained in:
Jacques Lucke
2024-09-05 11:33:35 +02:00
parent f883cb77ba
commit 871b25b219
95 changed files with 912 additions and 917 deletions

View File

@@ -10,6 +10,8 @@
#include "BLI_set.hh"
#include "BLI_string_ref.hh"
#include "BKE_attribute_filter.hh"
namespace blender::bke {
/**
@@ -26,26 +28,26 @@ class AnonymousAttributeSet {
};
/**
* Can be passed to algorithms which propagate attributes. It can tell the algorithm which
* anonymous attributes should be propagated and can be skipped.
* Checks if the attribute name has the `.a_` prefix which indicates that it is an anonymous
* attribute. I.e. it is just internally used by Blender and the name should not be exposed to the
* user.
*
* Use #hash_to_anonymous_attribute_name to generate names for anonymous attributes.
*/
class AnonymousAttributePropagationInfo {
inline bool attribute_name_is_anonymous(const StringRef name)
{
return name.startswith(".a_");
}
class ProcessAllAttributeExceptAnonymous : public AttributeFilter {
public:
/**
* This uses `std::shared_ptr` because it's usually initialized from an #AnonymousAttributeSet
* and then the set doesn't have to be copied.
*/
std::shared_ptr<Set<std::string>> names;
/**
* Propagate all anonymous attributes even if the set above is empty.
*/
bool propagate_all = true;
/**
* Return true when the anonymous attribute should be propagated and false otherwise.
*/
bool propagate(StringRef anonymous_id) const;
Result filter(const StringRef name) const override
{
if (attribute_name_is_anonymous(name)) {
return AttributeFilter::Result::AllowSkip;
}
return AttributeFilter::Result::Process;
}
};
} // namespace blender::bke

View File

@@ -16,6 +16,7 @@
#include "BKE_anonymous_attribute_id.hh"
#include "BKE_attribute.h"
#include "BKE_attribute_filters.hh"
struct Mesh;
struct PointCloud;
@@ -48,18 +49,6 @@ enum class AttrDomain : int8_t {
};
#define ATTR_DOMAIN_NUM 7
/**
* Checks if the attribute name has the `.a_` prefix which indicates that it is an anonymous
* attribute. I.e. it is just internally used by Blender and the name should not be exposed to the
* user.
*
* Use #hash_to_anonymous_attribute_name to generate names for anonymous attributes.
*/
inline bool attribute_name_is_anonymous(const StringRef name)
{
return name.startswith(".a_");
}
const CPPType *custom_data_type_to_cpp_type(eCustomDataType type);
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type);
@@ -813,8 +802,7 @@ Vector<AttributeTransferData> retrieve_attributes_for_transfer(
const AttributeAccessor src_attributes,
MutableAttributeAccessor dst_attributes,
AttrDomainMask domain_mask,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip = {});
const AttributeFilter &attribute_filter = {});
bool allow_procedural_attribute_access(StringRef attribute_name);
extern const char *no_procedural_access_message;
@@ -828,8 +816,7 @@ AttrDomain attribute_domain_highest_priority(Span<AttrDomain> domains);
void gather_attributes(AttributeAccessor src_attributes,
AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
const IndexMask &selection,
MutableAttributeAccessor dst_attributes);
@@ -838,8 +825,7 @@ void gather_attributes(AttributeAccessor src_attributes,
*/
void gather_attributes(AttributeAccessor src_attributes,
AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
Span<int> indices,
MutableAttributeAccessor dst_attributes);
@@ -850,8 +836,7 @@ void gather_attributes(AttributeAccessor src_attributes,
*/
void gather_attributes_group_to_group(AttributeAccessor src_attributes,
AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
OffsetIndices<int> src_offsets,
OffsetIndices<int> dst_offsets,
const IndexMask &selection,
@@ -859,22 +844,19 @@ void gather_attributes_group_to_group(AttributeAccessor src_attributes,
void gather_attributes_to_groups(AttributeAccessor src_attributes,
AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
OffsetIndices<int> dst_offsets,
const IndexMask &src_selection,
MutableAttributeAccessor dst_attributes);
void copy_attributes(const AttributeAccessor src_attributes,
const AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
MutableAttributeAccessor dst_attributes);
void copy_attributes_group_to_group(AttributeAccessor src_attributes,
AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
OffsetIndices<int> src_offsets,
OffsetIndices<int> dst_offsets,
const IndexMask &selection,
@@ -882,7 +864,7 @@ void copy_attributes_group_to_group(AttributeAccessor src_attributes,
void fill_attribute_range_default(MutableAttributeAccessor dst_attributes,
AttrDomain domain,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
IndexRange range);
} // namespace blender::bke

View File

@@ -0,0 +1,52 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "BLI_function_ref.hh"
#include "BLI_string_ref.hh"
namespace blender::bke {
/**
* Many geometry algorithms need to deal with attributes. For example, the Subdivide Curves code
* has to properly interpolate attributes to the intermediate points. However, sometimes certain
* attributes are not necessary after the operation anymore, so they can just be skipped for
* optimization purposes. This is where #AttributeFilter comes in. It allows the caller to specify
* which attributes should be processed and which should be ignored.
*
* \note It depends on the algorithm whether the output of the filter is followed exactly. For
* example, some algorithm might not be able to propagate attributes on some domain, even if the
* filter says that the attribute should be propagated.
*/
struct AttributeFilter {
public:
enum class Result {
/** The algorithm is allowed to skip processing the attribute. */
AllowSkip,
/** The attribute should be processed/propagated if at all possible. */
Process,
};
virtual ~AttributeFilter() = default;
/**
* This function has different implementations in each derived class. By default, all attributes
* should be processed.
*/
virtual Result filter(const StringRef /*name*/) const
{
return Result::Process;
}
/**
* Utility to simplify the check for whether some attribute can be skipped.
*/
bool allow_skip(const StringRef name) const
{
return this->filter(name) == Result::AllowSkip;
}
};
} // namespace blender::bke

View File

@@ -0,0 +1,83 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "BKE_anonymous_attribute_id.hh"
#include "BKE_attribute_filter.hh"
#include "BLI_set.hh"
namespace blender::bke {
/**
* Utility to create an #AttributeFilter from a lambda.
*/
template<typename Fn> struct AttributeFilterFromFunc : public AttributeFilter {
private:
Fn fn_;
static_assert(std::is_invocable_r_v<Result, Fn, StringRef>);
public:
constexpr AttributeFilterFromFunc(Fn fn) : fn_(std::move(fn)) {}
Result filter(const StringRef name) const override
{
return fn_(name);
}
};
/**
* Combines an existing #AttributeFilter and tags a few additional attributes that can/should be
* skipped.
*/
inline auto attribute_filter_with_skip_ref(AttributeFilter filter, const Span<StringRef> skip)
{
return AttributeFilterFromFunc([filter, skip](const StringRef name) {
if (skip.contains(name)) {
return AttributeFilter::Result::AllowSkip;
}
return filter.filter(name);
});
}
/** Same as above but with a #Set. */
template<typename StringT>
inline auto attribute_filter_with_skip_ref(AttributeFilter filter, const Set<StringT> &skip)
{
return AttributeFilterFromFunc([filter, &skip](const StringRef name) {
if (skip.contains_as(name)) {
return AttributeFilter::Result::AllowSkip;
}
return filter.filter(name);
});
}
/**
* Creates a simple #AttributeFilter that skips allows the given attributes to be skipped, while
* all others should be processed.
*/
inline auto attribute_filter_from_skip_ref(const Span<StringRef> skip)
{
return AttributeFilterFromFunc([skip](const StringRef name) {
if (skip.contains(name)) {
return AttributeFilter::Result::AllowSkip;
}
return AttributeFilter::Result::Process;
});
}
/** Same as above but with a #Set. */
template<typename StringT> inline auto attribute_filter_from_skip_ref(const Set<StringT> &skip)
{
return AttributeFilterFromFunc([&skip](const StringRef name) {
if (skip.contains_as(name)) {
return AttributeFilter::Result::AllowSkip;
}
return AttributeFilter::Result::Process;
});
}
} // namespace blender::bke

View File

@@ -10,10 +10,11 @@ struct Mesh;
* \ingroup bke
*/
#include "BKE_attribute_filter.hh"
namespace blender::bke {
class CurvesGeometry;
class AnonymousAttributePropagationInfo;
/**
* Extrude all splines in the profile curve along the path of every spline in the curve input.
@@ -28,12 +29,12 @@ class AnonymousAttributePropagationInfo;
Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
const CurvesGeometry &profile,
bool fill_caps,
const AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter = {});
/**
* Create a loose-edge mesh based on the evaluated path of the curve's splines.
* Transfer curve attributes to the mesh.
*/
Mesh *curve_to_wire_mesh(const CurvesGeometry &curve,
const AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter = {});
} // namespace blender::bke

View File

@@ -29,7 +29,6 @@ struct BlendDataReader;
struct BlendWriter;
struct MDeformVert;
namespace blender::bke {
class AnonymousAttributePropagationInfo;
class AttributeAccessor;
class MutableAttributeAccessor;
enum class AttrDomain : int8_t;
@@ -395,10 +394,8 @@ class CurvesGeometry : public ::CurvesGeometry {
void calculate_bezier_auto_handles();
void remove_points(const IndexMask &points_to_delete,
const AnonymousAttributePropagationInfo &propagation_info);
void remove_curves(const IndexMask &curves_to_delete,
const AnonymousAttributePropagationInfo &propagation_info);
void remove_points(const IndexMask &points_to_delete, const AttributeFilter &attribute_filter);
void remove_curves(const IndexMask &curves_to_delete, const AttributeFilter &attribute_filter);
/**
* Change the direction of selected curves (switch the start and end) without changing their
@@ -854,15 +851,13 @@ Curves *curves_new_nomain_single(int points_num, CurveType type);
*/
void curves_copy_parameters(const Curves &src, Curves &dst);
CurvesGeometry curves_copy_point_selection(
const CurvesGeometry &curves,
const IndexMask &points_to_copy,
const AnonymousAttributePropagationInfo &propagation_info);
CurvesGeometry curves_copy_point_selection(const CurvesGeometry &curves,
const IndexMask &points_to_copy,
const AttributeFilter &attribute_filter);
CurvesGeometry curves_copy_curve_selection(
const CurvesGeometry &curves,
const IndexMask &curves_to_copy,
const AnonymousAttributePropagationInfo &propagation_info);
CurvesGeometry curves_copy_curve_selection(const CurvesGeometry &curves,
const IndexMask &curves_to_copy,
const AttributeFilter &attribute_filter);
std::array<int, CURVE_TYPES_NUM> calculate_type_counts(const VArray<int8_t> &types);

View File

@@ -28,7 +28,6 @@ struct PointCloud;
struct Volume;
struct GreasePencil;
namespace blender::bke {
class AnonymousAttributePropagationInfo;
struct AttributeKind;
class AttributeAccessor;
struct AttributeMetaData;
@@ -259,12 +258,12 @@ struct GeometrySet {
static void propagate_attributes_from_layer_to_instances(
const AttributeAccessor src_attributes,
MutableAttributeAccessor dst_attributes,
const AnonymousAttributePropagationInfo &propagation_info);
const AttributeFilter &attribute_filter);
void gather_attributes_for_propagation(Span<GeometryComponent::Type> component_types,
GeometryComponent::Type dst_component_type,
bool include_instances,
const AnonymousAttributePropagationInfo &propagation_info,
const AttributeFilter &attribute_filter,
Map<StringRef, AttributeKind> &r_attributes) const;
Vector<GeometryComponent::Type> gather_component_types(bool include_instances,

View File

@@ -33,10 +33,11 @@
#include "DNA_customdata_types.h"
#include "BKE_attribute_filter.hh"
struct Object;
struct Collection;
namespace blender::bke {
class AnonymousAttributePropagationInfo;
class AttributeAccessor;
class MutableAttributeAccessor;
} // namespace blender::bke
@@ -192,7 +193,7 @@ class Instances {
* Remove the indices that are not contained in the mask input, and remove unused instance
* references afterwards.
*/
void remove(const IndexMask &mask, const AnonymousAttributePropagationInfo &propagation_info);
void remove(const IndexMask &mask, const AttributeFilter &attribute_filter);
/**
* Get an id for every instance. These can be used for e.g. motion blur.
*/

View File

@@ -328,6 +328,8 @@ set(SRC
BKE_animsys.h
BKE_anonymous_attribute_id.hh
BKE_anonymous_attribute_make.hh
BKE_attribute_filter.hh
BKE_attribute_filters.hh
BKE_appdir.hh
BKE_armature.hh
BKE_asset.hh

View File

@@ -6,15 +6,4 @@
namespace blender::bke {
bool AnonymousAttributePropagationInfo::propagate(const StringRef attribute) const
{
if (this->propagate_all) {
return true;
}
if (!this->names) {
return false;
}
return this->names->contains_as(attribute);
}
} // namespace blender::bke

View File

@@ -794,18 +794,14 @@ Vector<AttributeTransferData> retrieve_attributes_for_transfer(
const AttributeAccessor src_attributes,
MutableAttributeAccessor dst_attributes,
const AttrDomainMask domain_mask,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip)
const bke::AttributeFilter &attribute_filter)
{
Vector<AttributeTransferData> attributes;
src_attributes.for_all([&](const StringRef id, const AttributeMetaData meta_data) {
if (!(ATTR_DOMAIN_AS_MASK(meta_data.domain) & domain_mask)) {
return true;
}
if (attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
return true;
}
if (skip.contains(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
@@ -823,8 +819,7 @@ Vector<AttributeTransferData> retrieve_attributes_for_transfer(
void gather_attributes(const AttributeAccessor src_attributes,
const AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
const IndexMask &selection,
MutableAttributeAccessor dst_attributes)
{
@@ -836,10 +831,7 @@ void gather_attributes(const AttributeAccessor src_attributes,
if (meta_data.data_type == CD_PROP_STRING) {
return true;
}
if (attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
return true;
}
if (skip.contains(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
const GAttributeReader src = src_attributes.lookup(id, domain);
@@ -862,13 +854,12 @@ void gather_attributes(const AttributeAccessor src_attributes,
void gather_attributes(const AttributeAccessor src_attributes,
const AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
const Span<int> indices,
MutableAttributeAccessor dst_attributes)
{
if (array_utils::indices_are_range(indices, IndexRange(src_attributes.domain_size(domain)))) {
copy_attributes(src_attributes, domain, propagation_info, skip, dst_attributes);
copy_attributes(src_attributes, domain, attribute_filter, dst_attributes);
}
else {
src_attributes.for_all([&](const StringRef id, const AttributeMetaData meta_data) {
@@ -878,10 +869,7 @@ void gather_attributes(const AttributeAccessor src_attributes,
if (meta_data.data_type == CD_PROP_STRING) {
return true;
}
if (attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
return true;
}
if (skip.contains(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
const GAttributeReader src = src_attributes.lookup(id, domain);
@@ -899,8 +887,7 @@ void gather_attributes(const AttributeAccessor src_attributes,
void gather_attributes_group_to_group(const AttributeAccessor src_attributes,
const AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
const OffsetIndices<int> src_offsets,
const OffsetIndices<int> dst_offsets,
const IndexMask &selection,
@@ -913,10 +900,7 @@ void gather_attributes_group_to_group(const AttributeAccessor src_attributes,
if (meta_data.data_type == CD_PROP_STRING) {
return true;
}
if (attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
return true;
}
if (skip.contains(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
const GVArraySpan src = *src_attributes.lookup(id, domain);
@@ -933,8 +917,7 @@ void gather_attributes_group_to_group(const AttributeAccessor src_attributes,
void gather_attributes_to_groups(const AttributeAccessor src_attributes,
const AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
const OffsetIndices<int> dst_offsets,
const IndexMask &src_selection,
MutableAttributeAccessor dst_attributes)
@@ -946,10 +929,7 @@ void gather_attributes_to_groups(const AttributeAccessor src_attributes,
if (meta_data.data_type == CD_PROP_STRING) {
return true;
}
if (attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
return true;
}
if (skip.contains(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
const GVArraySpan src = *src_attributes.lookup(id, domain);
@@ -966,23 +946,20 @@ void gather_attributes_to_groups(const AttributeAccessor src_attributes,
void copy_attributes(const AttributeAccessor src_attributes,
const AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
MutableAttributeAccessor dst_attributes)
{
BLI_assert(src_attributes.domain_size(domain) == dst_attributes.domain_size(domain));
return gather_attributes(src_attributes,
domain,
propagation_info,
skip,
attribute_filter,
IndexMask(src_attributes.domain_size(domain)),
dst_attributes);
}
void copy_attributes_group_to_group(const AttributeAccessor src_attributes,
const AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
const OffsetIndices<int> src_offsets,
const OffsetIndices<int> dst_offsets,
const IndexMask &selection,
@@ -998,10 +975,7 @@ void copy_attributes_group_to_group(const AttributeAccessor src_attributes,
if (meta_data.data_type == CD_PROP_STRING) {
return true;
}
if (attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
return true;
}
if (skip.contains(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
const GVArraySpan src = *src_attributes.lookup(id, domain);
@@ -1018,14 +992,14 @@ void copy_attributes_group_to_group(const AttributeAccessor src_attributes,
void fill_attribute_range_default(MutableAttributeAccessor attributes,
const AttrDomain domain,
const Set<std::string> &skip,
const AttributeFilter &attribute_filter,
const IndexRange range)
{
attributes.for_all([&](const StringRef id, const AttributeMetaData meta_data) {
if (meta_data.domain != domain) {
return true;
}
if (skip.contains(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
if (meta_data.data_type == CD_PROP_STRING) {

View File

@@ -365,7 +365,7 @@ static bool should_add_attribute_to_mesh(const AttributeAccessor &curve_attribut
const AttributeAccessor &mesh_attributes,
const StringRef id,
const AttributeMetaData &meta_data,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
/* The position attribute has special non-generic evaluation. */
@@ -376,7 +376,7 @@ static bool should_add_attribute_to_mesh(const AttributeAccessor &curve_attribut
if (curve_attributes.is_builtin(id) && !mesh_attributes.is_builtin(id)) {
return false;
}
if (bke::attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
if (attribute_filter.allow_skip(id)) {
return false;
}
if (meta_data.data_type == CD_PROP_STRING) {
@@ -815,7 +815,7 @@ static void write_sharp_bezier_edges(const CurvesInfo &curves_info,
Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
const CurvesGeometry &profile,
const bool fill_caps,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const CurvesInfo curves_info = get_curves_info(main, profile);
@@ -913,7 +913,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
const AttributeAccessor main_attributes = main.attributes();
main_attributes.for_all([&](const StringRef id, const AttributeMetaData meta_data) {
if (!should_add_attribute_to_mesh(
main_attributes, mesh_attributes, id, meta_data, propagation_info))
main_attributes, mesh_attributes, id, meta_data, attribute_filter))
{
return true;
}
@@ -949,7 +949,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
return true;
}
if (!should_add_attribute_to_mesh(
profile_attributes, mesh_attributes, id, meta_data, propagation_info))
profile_attributes, mesh_attributes, id, meta_data, attribute_filter))
{
return true;
}
@@ -993,11 +993,10 @@ static CurvesGeometry get_curve_single_vert()
return curves;
}
Mesh *curve_to_wire_mesh(const CurvesGeometry &curve,
const AnonymousAttributePropagationInfo &propagation_info)
Mesh *curve_to_wire_mesh(const CurvesGeometry &curve, const AttributeFilter &attribute_filter)
{
static const CurvesGeometry vert_curve = get_curve_single_vert();
return curve_to_mesh_sweep(curve, vert_curve, false, propagation_info);
return curve_to_mesh_sweep(curve, vert_curve, false, attribute_filter);
}
} // namespace blender::bke

View File

@@ -1204,10 +1204,9 @@ void CurvesGeometry::count_memory(MemoryCounter &memory) const
CustomData_count_memory(this->curve_data, this->curve_num, memory);
}
CurvesGeometry curves_copy_point_selection(
const CurvesGeometry &curves,
const IndexMask &points_to_copy,
const AnonymousAttributePropagationInfo &propagation_info)
CurvesGeometry curves_copy_point_selection(const CurvesGeometry &curves,
const IndexMask &points_to_copy,
const AttributeFilter &attribute_filter)
{
const Array<int> point_to_curve_map = curves.point_to_curve_map();
Array<int> curve_point_counts(curves.curves_num(), 0);
@@ -1238,14 +1237,12 @@ CurvesGeometry curves_copy_point_selection(
[&]() {
gather_attributes(curves.attributes(),
AttrDomain::Point,
propagation_info,
{},
attribute_filter,
points_to_copy,
dst_curves.attributes_for_write());
gather_attributes(curves.attributes(),
AttrDomain::Curve,
propagation_info,
{},
attribute_filter,
curves_to_copy,
dst_curves.attributes_for_write());
});
@@ -1261,7 +1258,7 @@ CurvesGeometry curves_copy_point_selection(
}
void CurvesGeometry::remove_points(const IndexMask &points_to_delete,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
if (points_to_delete.is_empty()) {
return;
@@ -1272,13 +1269,12 @@ void CurvesGeometry::remove_points(const IndexMask &points_to_delete,
}
IndexMaskMemory memory;
const IndexMask points_to_copy = points_to_delete.complement(this->points_range(), memory);
*this = curves_copy_point_selection(*this, points_to_copy, propagation_info);
*this = curves_copy_point_selection(*this, points_to_copy, attribute_filter);
}
CurvesGeometry curves_copy_curve_selection(
const CurvesGeometry &curves,
const IndexMask &curves_to_copy,
const AnonymousAttributePropagationInfo &propagation_info)
CurvesGeometry curves_copy_curve_selection(const CurvesGeometry &curves,
const IndexMask &curves_to_copy,
const AttributeFilter &attribute_filter)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
CurvesGeometry dst_curves(0, curves_to_copy.size());
@@ -1293,15 +1289,14 @@ CurvesGeometry curves_copy_curve_selection(
gather_attributes_group_to_group(src_attributes,
AttrDomain::Point,
propagation_info,
{},
attribute_filter,
points_by_curve,
dst_points_by_curve,
curves_to_copy,
dst_attributes);
gather_attributes(
src_attributes, AttrDomain::Curve, propagation_info, {}, curves_to_copy, dst_attributes);
src_attributes, AttrDomain::Curve, attribute_filter, curves_to_copy, dst_attributes);
dst_curves.update_curve_types();
dst_curves.remove_attributes_based_on_types();
@@ -1310,7 +1305,7 @@ CurvesGeometry curves_copy_curve_selection(
}
void CurvesGeometry::remove_curves(const IndexMask &curves_to_delete,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
if (curves_to_delete.is_empty()) {
return;
@@ -1321,7 +1316,7 @@ void CurvesGeometry::remove_curves(const IndexMask &curves_to_delete,
}
IndexMaskMemory memory;
const IndexMask curves_to_copy = curves_to_delete.complement(this->curves_range(), memory);
*this = curves_copy_curve_selection(*this, curves_to_copy, propagation_info);
*this = curves_copy_curve_selection(*this, curves_to_copy, attribute_filter);
}
template<typename T>

View File

@@ -631,10 +631,10 @@ void GeometrySet::attribute_foreach(const Span<GeometryComponent::Type> componen
void GeometrySet::propagate_attributes_from_layer_to_instances(
const AttributeAccessor src_attributes,
MutableAttributeAccessor dst_attributes,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
src_attributes.for_all([&](const StringRef id, const AttributeMetaData meta_data) {
if (bke::attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
const GAttributeReader src = src_attributes.lookup(id, AttrDomain::Layer);
@@ -659,7 +659,7 @@ void GeometrySet::gather_attributes_for_propagation(
const Span<GeometryComponent::Type> component_types,
const GeometryComponent::Type dst_component_type,
bool include_instances,
const AnonymousAttributePropagationInfo &propagation_info,
const AttributeFilter &attribute_filter,
Map<StringRef, AttributeKind> &r_attributes) const
{
/* Only needed right now to check if an attribute is built-in on this component type.
@@ -682,9 +682,7 @@ void GeometrySet::gather_attributes_for_propagation(
/* Propagating string attributes is not supported yet. */
return;
}
if (bke::attribute_name_is_anonymous(attribute_id) &&
!propagation_info.propagate(attribute_id))
{
if (attribute_filter.allow_skip(attribute_id)) {
return;
}

View File

@@ -273,8 +273,7 @@ Span<InstanceReference> Instances::references() const
return references_;
}
void Instances::remove(const IndexMask &mask,
const AnonymousAttributePropagationInfo &propagation_info)
void Instances::remove(const IndexMask &mask, const AttributeFilter &attribute_filter)
{
const std::optional<IndexRange> masked_range = mask.to_range();
if (masked_range.has_value() && masked_range->start() == 0) {
@@ -290,8 +289,7 @@ void Instances::remove(const IndexMask &mask,
gather_attributes(this->attributes(),
AttrDomain::Instance,
propagation_info,
{},
attribute_filter,
mask,
new_instances.attributes_for_write());

View File

@@ -709,8 +709,7 @@ static Mesh *mesh_new_from_evaluated_curve_type_object(const Object *evaluated_o
return BKE_mesh_copy_for_eval(*mesh);
}
if (const Curves *curves = get_evaluated_curves_from_object(evaluated_object)) {
const blender::bke::AnonymousAttributePropagationInfo propagation_info;
return blender::bke::curve_to_wire_mesh(curves->geometry.wrap(), propagation_info);
return blender::bke::curve_to_wire_mesh(curves->geometry.wrap());
}
return nullptr;
}

View File

@@ -935,30 +935,32 @@ static int curves_draw_exec(bContext *C, wmOperator *op)
if (attributes.contains("resolution")) {
curves.resolution_for_write()[curve_index] = 12;
}
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Point,
{"position",
"radius",
"handle_left",
"handle_right",
"handle_type_left",
"handle_type_right",
"nurbs_weight",
".selection",
".selection_handle_left",
".selection_handle_right"},
curves.points_by_curve()[curve_index]);
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Curve,
{"curve_type",
"resolution",
"cyclic",
"nurbs_order",
"knots_mode",
".selection",
".selection_handle_left",
".selection_handle_right"},
IndexRange(curve_index, 1));
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Point,
bke::attribute_filter_from_skip_ref({"position",
"radius",
"handle_left",
"handle_right",
"handle_type_left",
"handle_type_right",
"nurbs_weight",
".selection",
".selection_handle_left",
".selection_handle_right"}),
curves.points_by_curve()[curve_index]);
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Curve,
bke::attribute_filter_from_skip_ref({"curve_type",
"resolution",
"cyclic",
"nurbs_order",
"knots_mode",
".selection",
".selection_handle_left",
".selection_handle_right"}),
IndexRange(curve_index, 1));
}
if (corners_index) {
@@ -1014,12 +1016,17 @@ static int curves_draw_exec(bContext *C, wmOperator *op)
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Point,
{"position", "radius", ".selection", ".selection_handle_left", ".selection_handle_right"},
bke::attribute_filter_from_skip_ref({"position",
"radius",
".selection",
".selection_handle_left",
".selection_handle_right"}),
new_points);
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Curve,
{"curve_type", ".selection", ".selection_handle_left", ".selection_handle_right"},
bke::attribute_filter_from_skip_ref(
{"curve_type", ".selection", ".selection_handle_left", ".selection_handle_right"}),
IndexRange(curve_index, 1));
}

View File

@@ -338,8 +338,8 @@ static void extrude_curves(Curves &curves_id)
src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_POINT,
{},
{".selection", ".selection_handle_left", ".selection_handle_right"}))
bke::attribute_filter_from_skip_ref(
{".selection", ".selection_handle_left", ".selection_handle_right"})))
{
const CPPType &type = attribute.src.type();
threading::parallel_for(IndexRange(intervals.size() - 1), 512, [&](IndexRange range) {

View File

@@ -434,13 +434,15 @@ static bke::CurvesGeometry remove_points_and_split(const bke::CurvesGeometry &cu
const bke::AttributeAccessor src_attributes = curves.attributes();
/* Transfer curve attributes. */
gather_attributes(
src_attributes, bke::AttrDomain::Curve, {}, {"cyclic"}, dst_to_src_curve, dst_attributes);
gather_attributes(src_attributes,
bke::AttrDomain::Curve,
bke::attribute_filter_from_skip_ref({"cyclic"}),
dst_to_src_curve,
dst_attributes);
array_utils::copy(dst_cyclic.as_span(), dst_curves.cyclic_for_write());
/* Transfer point attributes. */
gather_attributes(
src_attributes, bke::AttrDomain::Point, {}, {}, dst_to_src_point, dst_attributes);
gather_attributes(src_attributes, bke::AttrDomain::Point, {}, dst_to_src_point, dst_attributes);
dst_curves.update_curve_types();
dst_curves.remove_attributes_based_on_types();
@@ -1511,7 +1513,7 @@ static int gpencil_stroke_subdivide_exec(bContext *C, wmOperator *op)
vcuts = VArray<int>::ForContainer(std::move(use_cuts));
}
curves = geometry::subdivide_curves(curves, strokes, vcuts, {});
curves = geometry::subdivide_curves(curves, strokes, vcuts);
info.drawing.tag_topology_changed();
changed.store(true, std::memory_order_relaxed);
});
@@ -1905,7 +1907,6 @@ static bke::greasepencil::Layer &find_or_create_layer_in_dst_by_name(
bke::gather_attributes(grease_pencil_src.attributes(),
bke::AttrDomain::Layer,
{},
{},
Span({layer_index}),
grease_pencil_dst.attributes_for_write());
@@ -2657,10 +2658,10 @@ static bke::CurvesGeometry extrude_grease_pencil_curves(const bke::CurvesGeometr
bke::MutableAttributeAccessor dst_attributes = dst.attributes_for_write();
bke::gather_attributes(
src_attributes, bke::AttrDomain::Curve, {}, {}, dst_to_src_curves, dst_attributes);
src_attributes, bke::AttrDomain::Curve, {}, dst_to_src_curves, dst_attributes);
bke::gather_attributes(
src_attributes, bke::AttrDomain::Point, {}, {}, dst_to_src_points, dst_attributes);
src_attributes, bke::AttrDomain::Point, {}, dst_to_src_points, dst_attributes);
/* Selection attribute. */
const std::string &selection_attr_name = ".selection";

View File

@@ -209,11 +209,10 @@ int curve_merge_by_distance(const IndexRange points,
}
/* NOTE: The code here is an adapted version of #blender::geometry::point_merge_by_distance. */
blender::bke::CurvesGeometry curves_merge_by_distance(
const bke::CurvesGeometry &src_curves,
const float merge_distance,
const IndexMask &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info)
blender::bke::CurvesGeometry curves_merge_by_distance(const bke::CurvesGeometry &src_curves,
const float merge_distance,
const IndexMask &selection,
const bke::AttributeFilter &attribute_filter)
{
const int src_point_size = src_curves.points_num();
if (src_point_size == 0) {
@@ -304,7 +303,7 @@ blender::bke::CurvesGeometry curves_merge_by_distance(
bke::AttributeAccessor src_attributes = src_curves.attributes();
bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
src_attributes.for_all([&](const StringRef id, const bke::AttributeMetaData &meta_data) {
if (bke::attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
if (meta_data.domain != bke::AttrDomain::Point) {
@@ -350,7 +349,7 @@ bke::CurvesGeometry curves_merge_endpoints_by_distance(
const float4x4 &layer_to_world,
const float merge_distance,
const IndexMask &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
const Span<float3> src_positions = src_curves.positions();
@@ -433,7 +432,7 @@ bke::CurvesGeometry curves_merge_endpoints_by_distance(
BLI_kdtree_2d_free(tree);
return geometry::curves_merge_endpoints(
src_curves, connect_to_curve, flip_direction, propagation_info);
src_curves, connect_to_curve, flip_direction, attribute_filter);
}
/* Generate points in an counter-clockwise arc between two directions. */
@@ -807,14 +806,12 @@ bke::CurvesGeometry create_curves_outline(const bke::greasepencil::Drawing &draw
bke::gather_attributes(src_attributes,
bke::AttrDomain::Point,
{},
{"position", "radius"},
bke::attribute_filter_from_skip_ref({"position", "radius"}),
dst_point_map,
dst_attributes);
bke::gather_attributes(src_attributes,
bke::AttrDomain::Curve,
{},
{"cyclic", "material_index"},
bke::attribute_filter_from_skip_ref({"cyclic", "material_index"}),
dst_curve_map,
dst_attributes);

View File

@@ -505,14 +505,16 @@ static void grease_pencil_primitive_update_curves(PrimitiveToolOperation &ptd)
/* Initialize the rest of the attributes with default values. */
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Point,
skipped_attribute_ids(ptd, bke::AttrDomain::Point),
curve_points);
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Curve,
skipped_attribute_ids(ptd, bke::AttrDomain::Curve),
curves.curves_range().take_back(1));
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Point,
bke::attribute_filter_from_skip_ref(skipped_attribute_ids(ptd, bke::AttrDomain::Point)),
curve_points);
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Curve,
bke::attribute_filter_from_skip_ref(skipped_attribute_ids(ptd, bke::AttrDomain::Curve)),
curves.curves_range().take_back(1));
ptd.drawing->tag_topology_changed();
ptd.drawing->set_texture_matrices({ptd.texture_space},
@@ -567,14 +569,16 @@ static void grease_pencil_primitive_init_curves(PrimitiveToolOperation &ptd)
curves.update_curve_types();
/* Initialize the rest of the attributes with default values. */
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Point,
skipped_attribute_ids(ptd, bke::AttrDomain::Point),
curves.points_range().take_back(1));
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Curve,
skipped_attribute_ids(ptd, bke::AttrDomain::Curve),
curves.curves_range().take_back(1));
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Point,
bke::attribute_filter_from_skip_ref(skipped_attribute_ids(ptd, bke::AttrDomain::Point)),
curves.points_range().take_back(1));
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Curve,
bke::attribute_filter_from_skip_ref(skipped_attribute_ids(ptd, bke::AttrDomain::Curve)),
curves.curves_range().take_back(1));
grease_pencil_primitive_update_curves(ptd);
}

View File

@@ -1290,13 +1290,11 @@ Array<PointTransferData> compute_topology_change(
/* Attributes. */
const bke::AttributeAccessor src_attributes = src.attributes();
bke::MutableAttributeAccessor dst_attributes = dst.attributes_for_write();
const bke::AnonymousAttributePropagationInfo propagation_info{};
/* Copy curves attributes. */
bke::gather_attributes(src_attributes,
bke::AttrDomain::Curve,
propagation_info,
{"cyclic"},
bke::attribute_filter_from_skip_ref({"cyclic"}),
dst_to_src_curve,
dst_attributes);
if (src_cyclic.get_if_single().value_or(true)) {
@@ -1337,7 +1335,7 @@ Array<PointTransferData> compute_topology_change(
/* Copy/Interpolate point attributes. */
for (bke::AttributeTransferData &attribute : bke::retrieve_attributes_for_transfer(
src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info))
src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT))
{
bke::attribute_math::convert_to_static_type(attribute.dst.span.type(), [&](auto dummy) {
using T = decltype(dummy);

View File

@@ -8,9 +8,9 @@
#pragma once
#include "BKE_anonymous_attribute_id.hh"
#include "BKE_grease_pencil.hh"
#include "BKE_attribute_filter.hh"
#include "BLI_generic_span.hh"
#include "BLI_index_mask_fwd.hh"
#include "BLI_math_matrix_types.hh"
@@ -402,11 +402,10 @@ IndexMask polyline_detect_corners(Span<float2> points,
* Merge points that are close together on each selected curve.
* Points are not merged across curves.
*/
bke::CurvesGeometry curves_merge_by_distance(
const bke::CurvesGeometry &src_curves,
const float merge_distance,
const IndexMask &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info);
bke::CurvesGeometry curves_merge_by_distance(const bke::CurvesGeometry &src_curves,
const float merge_distance,
const IndexMask &selection,
const bke::AttributeFilter &attribute_filter);
/**
* Merge points on the same curve that are close together.
@@ -426,7 +425,7 @@ bke::CurvesGeometry curves_merge_endpoints_by_distance(
const float4x4 &layer_to_world,
const float merge_distance,
const IndexMask &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter);
/**
* Structure describing a point in the destination relatively to the source.

View File

@@ -3705,9 +3705,8 @@ static int object_convert_exec(bContext *C, wmOperator *op)
new_mesh->attributes_for_write().remove_anonymous();
}
else if (const Curves *curves_eval = geometry.get_curves()) {
bke::AnonymousAttributePropagationInfo propagation_info;
propagation_info.propagate_all = false;
Mesh *mesh = bke::curve_to_wire_mesh(curves_eval->geometry.wrap(), propagation_info);
Mesh *mesh = bke::curve_to_wire_mesh(curves_eval->geometry.wrap(),
bke::ProcessAllAttributeExceptAnonymous{});
if (!mesh) {
mesh = BKE_mesh_new_nomain(0, 0, 0, 0);
}

View File

@@ -739,7 +739,6 @@ struct EraseOperationExecutor {
/* Set opacity. */
bke::MutableAttributeAccessor dst_attributes = dst.attributes_for_write();
const bke::AnonymousAttributePropagationInfo propagation_info{};
bke::SpanAttributeWriter<float> dst_opacity =
dst_attributes.lookup_or_add_for_write_span<float>(opacity_attr, bke::AttrDomain::Point);

View File

@@ -668,10 +668,14 @@ static bke::CurvesGeometry boundary_to_curves(const Scene &scene,
opacities.finish();
/* Initialize the rest of the attributes with default values. */
bke::fill_attribute_range_default(
attributes, bke::AttrDomain::Curve, skip_curve_attributes, curves.curves_range());
bke::fill_attribute_range_default(
attributes, bke::AttrDomain::Point, skip_point_attributes, curves.points_range());
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Curve,
bke::attribute_filter_from_skip_ref(skip_curve_attributes),
curves.curves_range());
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Point,
bke::attribute_filter_from_skip_ref(skip_point_attributes),
curves.points_range());
return curves;
}

View File

@@ -600,12 +600,16 @@ struct PaintOperationExecutor {
curves.update_curve_types();
/* Initialize the rest of the attributes with default values. */
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Point,
point_attributes_to_skip,
IndexRange(last_active_point, 1));
bke::fill_attribute_range_default(
attributes, bke::AttrDomain::Curve, curve_attributes_to_skip, IndexRange(active_curve, 1));
attributes,
bke::AttrDomain::Point,
bke::attribute_filter_from_skip_ref(point_attributes_to_skip),
IndexRange(last_active_point, 1));
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Curve,
bke::attribute_filter_from_skip_ref(curve_attributes_to_skip),
IndexRange(active_curve, 1));
drawing_->tag_topology_changed();
}
@@ -960,10 +964,11 @@ struct PaintOperationExecutor {
}
/* Initialize the rest of the attributes with default values. */
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Point,
point_attributes_to_skip,
curves.points_range().take_back(1));
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Point,
bke::attribute_filter_from_skip_ref(point_attributes_to_skip),
curves.points_range().take_back(1));
drawing_->set_texture_matrices({self.texture_space_}, IndexRange::from_single(active_curve));
}

View File

@@ -28,6 +28,6 @@ bke::CurvesGeometry extend_curves(bke::CurvesGeometry &src_curves,
float max_angle,
bool invert_curvature,
GeometryNodeCurveSampleMode sample_mode,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter);
} // namespace blender::geometry

View File

@@ -11,19 +11,17 @@
namespace blender::geometry {
bke::CurvesGeometry fillet_curves_poly(
const bke::CurvesGeometry &src_curves,
const IndexMask &curve_selection,
const VArray<float> &radius,
const VArray<int> &counts,
bool limit_radius,
const bke::AnonymousAttributePropagationInfo &propagation_info);
bke::CurvesGeometry fillet_curves_poly(const bke::CurvesGeometry &src_curves,
const IndexMask &curve_selection,
const VArray<float> &radius,
const VArray<int> &counts,
bool limit_radius,
const bke::AttributeFilter &attribute_filter);
bke::CurvesGeometry fillet_curves_bezier(
const bke::CurvesGeometry &src_curves,
const IndexMask &curve_selection,
const VArray<float> &radius,
bool limit_radius,
const bke::AnonymousAttributePropagationInfo &propagation_info);
bke::CurvesGeometry fillet_curves_bezier(const bke::CurvesGeometry &src_curves,
const IndexMask &curve_selection,
const VArray<float> &radius,
bool limit_radius,
const bke::AttributeFilter &attribute_filter);
} // namespace blender::geometry

View File

@@ -10,7 +10,7 @@
namespace blender::geometry {
bke::GeometrySet join_geometries(Span<bke::GeometrySet> geometries,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter);
void join_attributes(const Span<const bke::GeometryComponent *> src_components,
bke::GeometryComponent &r_result,

View File

@@ -15,10 +15,9 @@ namespace blender::geometry {
* (set to -1 to leave a curve disconnected).
* \param flip_direction: Flip direction of input curves.
*/
bke::CurvesGeometry curves_merge_endpoints(
const bke::CurvesGeometry &src_curves,
Span<int> connect_to_curve,
Span<bool> flip_direction,
const bke::AnonymousAttributePropagationInfo &propagation_info);
bke::CurvesGeometry curves_merge_endpoints(const bke::CurvesGeometry &src_curves,
Span<int> connect_to_curve,
Span<bool> flip_direction,
const bke::AttributeFilter &attribute_filter);
}; // namespace blender::geometry

View File

@@ -8,6 +8,8 @@
#include "BLI_index_mask.hh"
#include "BKE_attribute_filter.hh"
struct Mesh;
namespace blender {
namespace fn {
@@ -15,28 +17,26 @@ template<typename T> class Field;
}
namespace bke {
enum class AttrDomain : int8_t;
class AnonymousAttributePropagationInfo;
} // namespace bke
} // namespace blender
namespace blender::geometry {
std::optional<Mesh *> mesh_copy_selection(
const Mesh &src_mesh,
const VArray<bool> &selection,
bke::AttrDomain selection_domain,
const bke::AnonymousAttributePropagationInfo &propagation_info);
std::optional<Mesh *> mesh_copy_selection(const Mesh &src_mesh,
const VArray<bool> &selection,
bke::AttrDomain selection_domain,
const bke::AttributeFilter &attribute_filter = {});
std::optional<Mesh *> mesh_copy_selection_keep_verts(
const Mesh &src_mesh,
const VArray<bool> &selection,
bke::AttrDomain selection_domain,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter = {});
std::optional<Mesh *> mesh_copy_selection_keep_edges(
const Mesh &mesh,
const VArray<bool> &selection,
bke::AttrDomain selection_domain,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter = {});
} // namespace blender::geometry

View File

@@ -6,15 +6,14 @@
#include "BLI_index_mask.hh"
#include "BKE_attribute_filter.hh"
struct Mesh;
namespace blender::bke {
class AnonymousAttributePropagationInfo;
}
namespace blender::geometry {
void split_edges(Mesh &mesh,
const IndexMask &mask,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter = {});
} // namespace blender::geometry

View File

@@ -21,16 +21,14 @@ namespace blender::geometry {
* intersections of more than three edges will become breaks in curves. Attributes that
* are not built-in on meshes and not curves are transferred to the result curve.
*/
bke::CurvesGeometry mesh_to_curve_convert(
const Mesh &mesh,
const IndexMask &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info);
bke::CurvesGeometry mesh_to_curve_convert(const Mesh &mesh,
const IndexMask &selection,
const bke::AttributeFilter &attribute_filter);
bke::CurvesGeometry create_curve_from_vert_indices(
const bke::AttributeAccessor &mesh_attributes,
Span<int> vert_indices,
Span<int> curve_offsets,
IndexRange cyclic_curves,
const bke::AnonymousAttributePropagationInfo &propagation_info);
bke::CurvesGeometry create_curve_from_vert_indices(const bke::AttributeAccessor &mesh_attributes,
Span<int> vert_indices,
Span<int> curve_offsets,
IndexRange cyclic_curves,
const bke::AttributeFilter &attribute_filter);
} // namespace blender::geometry

View File

@@ -6,10 +6,9 @@
#include "BLI_index_mask.hh"
#include "BKE_attribute_filter.hh"
struct PointCloud;
namespace blender::bke {
class AnonymousAttributePropagationInfo;
}
/** \file
* \ingroup geo
@@ -21,10 +20,9 @@ namespace blender::geometry {
* Merge selected points into other selected points within the \a merge_distance. The merged
* indices favor speed over accuracy, since the results will depend on the order of the points.
*/
PointCloud *point_merge_by_distance(
const PointCloud &src_points,
const float merge_distance,
const IndexMask &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info);
PointCloud *point_merge_by_distance(const PointCloud &src_points,
const float merge_distance,
const IndexMask &selection,
const bke::AttributeFilter &attribute_filter);
} // namespace blender::geometry

View File

@@ -25,7 +25,7 @@ struct RealizeInstancesOptions {
*/
bool realize_instance_attributes = true;
bke::AnonymousAttributePropagationInfo propagation_info;
bke::AttributeFilter attribute_filter = {};
};
/**

View File

@@ -20,29 +20,27 @@ components_supported_reordering();
Mesh *reorder_mesh(const Mesh &src_mesh,
Span<int> old_by_new_map,
bke::AttrDomain domain,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter);
PointCloud *reorder_points(const PointCloud &src_pointcloud,
Span<int> old_by_new_map,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter);
bke::CurvesGeometry reorder_curves_geometry(
const bke::CurvesGeometry &src_curves,
Span<int> old_by_new_map,
const bke::AnonymousAttributePropagationInfo &propagation_info);
bke::CurvesGeometry reorder_curves_geometry(const bke::CurvesGeometry &src_curves,
Span<int> old_by_new_map,
const bke::AttributeFilter &attribute_filter);
Curves *reorder_curves(const Curves &src_curves,
Span<int> old_by_new_map,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter);
bke::Instances *reorder_instaces(const bke::Instances &src_instances,
Span<int> old_by_new_map,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter);
bke::GeometryComponentPtr reordered_component(
const bke::GeometryComponent &src_component,
Span<int> old_by_new_map,
bke::AttrDomain domain,
const bke::AnonymousAttributePropagationInfo &propagation_info);
bke::GeometryComponentPtr reordered_component(const bke::GeometryComponent &src_component,
Span<int> old_by_new_map,
bke::AttrDomain domain,
const bke::AttributeFilter &attribute_filter);
}; // namespace blender::geometry

View File

@@ -22,7 +22,7 @@ void separate_geometry(bke::GeometrySet &geometry_set,
bke::AttrDomain domain,
GeometryNodeDeleteGeometryMode mode,
const fn::Field<bool> &selection_field,
const bke::AnonymousAttributePropagationInfo &propagation_info,
const bke::AttributeFilter &attribute_filter,
bool &r_is_error);
} // namespace blender::geometry

View File

@@ -32,7 +32,7 @@ struct ConvertCurvesOptions {
bke::CurvesGeometry convert_curves(const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
CurveType dst_type,
const bke::AnonymousAttributePropagationInfo &propagation_info,
const bke::AttributeFilter &attribute_filter,
const ConvertCurvesOptions &options = {});
} // namespace blender::geometry

View File

@@ -8,6 +8,7 @@
#include "BLI_index_mask.hh"
#include "BLI_virtual_array.hh"
#include "BKE_attribute_filter.hh"
#include "BKE_curves.hh"
namespace blender::geometry {
@@ -19,10 +20,9 @@ namespace blender::geometry {
*
* \param selection: A selection of curves to consider when subdividing.
*/
bke::CurvesGeometry subdivide_curves(
const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const VArray<int> &cuts,
const bke::AnonymousAttributePropagationInfo &propagation_info);
bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const VArray<int> &cuts,
const bke::AttributeFilter &attribute_filter = {});
} // namespace blender::geometry

View File

@@ -22,6 +22,6 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
const VArray<float> &starts,
const VArray<float> &ends,
GeometryNodeCurveSampleMode mode,
const bke::AnonymousAttributePropagationInfo &propagation_info);
const bke::AttributeFilter &attribute_filter);
} // namespace blender::geometry

View File

@@ -485,12 +485,15 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves,
}
/* Explicitly set all other attributes besides those processed above to default values. */
bke::fill_attribute_range_default(
attributes, bke::AttrDomain::Point, {"position", "radius"}, outputs.new_points_range);
bke::fill_attribute_range_default(attributes,
bke::AttrDomain::Curve,
{"curve_type", "surface_uv_coordinate", "resolution"},
outputs.new_curves_range);
bke::AttrDomain::Point,
bke::attribute_filter_from_skip_ref({"position", "radius"}),
outputs.new_points_range);
bke::fill_attribute_range_default(
attributes,
bke::AttrDomain::Curve,
bke::attribute_filter_from_skip_ref({"curve_type", "surface_uv_coordinate", "resolution"}),
outputs.new_curves_range);
return outputs;
}

View File

@@ -210,7 +210,7 @@ bke::CurvesGeometry extend_curves(bke::CurvesGeometry &src_curves,
const float max_angle,
const bool invert_curvature,
const GeometryNodeCurveSampleMode sample_mode,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
if (src_curves.points_num() < 2) {
return src_curves;
@@ -302,8 +302,7 @@ bke::CurvesGeometry extend_curves(bke::CurvesGeometry &src_curves,
/* Transfer point attributes. */
gather_attributes(src_attributes,
bke::AttrDomain::Point,
propagation_info,
{},
attribute_filter,
dst_to_src_point,
dst_attributes);
}

View File

@@ -362,14 +362,13 @@ static void calculate_bezier_handles_poly_mode(const Span<float3> src_handles_l,
});
}
static bke::CurvesGeometry fillet_curves(
const bke::CurvesGeometry &src_curves,
const IndexMask &curve_selection,
const VArray<float> &radius_input,
const VArray<int> &counts,
const bool limit_radius,
const bool use_bezier_mode,
const bke::AnonymousAttributePropagationInfo &propagation_info)
static bke::CurvesGeometry fillet_curves(const bke::CurvesGeometry &src_curves,
const IndexMask &curve_selection,
const VArray<float> &radius_input,
const VArray<int> &counts,
const bool limit_radius,
const bool use_bezier_mode,
const bke::AttributeFilter &attribute_filter)
{
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
const Span<float3> positions = src_curves.positions();
@@ -490,8 +489,12 @@ static bke::CurvesGeometry fillet_curves(
src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_POINT,
propagation_info,
{"position", "handle_type_left", "handle_type_right", "handle_right", "handle_left"}))
bke::attribute_filter_with_skip_ref(attribute_filter,
{"position",
"handle_type_left",
"handle_type_right",
"handle_right",
"handle_left"})))
{
duplicate_fillet_point_data(src_points_by_curve,
dst_points_by_curve,
@@ -504,8 +507,7 @@ static bke::CurvesGeometry fillet_curves(
bke::copy_attributes_group_to_group(src_attributes,
bke::AttrDomain::Point,
propagation_info,
{},
attribute_filter,
src_points_by_curve,
dst_points_by_curve,
unselected,
@@ -514,24 +516,22 @@ static bke::CurvesGeometry fillet_curves(
return dst_curves;
}
bke::CurvesGeometry fillet_curves_poly(
const bke::CurvesGeometry &src_curves,
const IndexMask &curve_selection,
const VArray<float> &radius,
const VArray<int> &count,
const bool limit_radius,
const bke::AnonymousAttributePropagationInfo &propagation_info)
bke::CurvesGeometry fillet_curves_poly(const bke::CurvesGeometry &src_curves,
const IndexMask &curve_selection,
const VArray<float> &radius,
const VArray<int> &count,
const bool limit_radius,
const bke::AttributeFilter &attribute_filter)
{
return fillet_curves(
src_curves, curve_selection, radius, count, limit_radius, false, propagation_info);
src_curves, curve_selection, radius, count, limit_radius, false, attribute_filter);
}
bke::CurvesGeometry fillet_curves_bezier(
const bke::CurvesGeometry &src_curves,
const IndexMask &curve_selection,
const VArray<float> &radius,
const bool limit_radius,
const bke::AnonymousAttributePropagationInfo &propagation_info)
bke::CurvesGeometry fillet_curves_bezier(const bke::CurvesGeometry &src_curves,
const IndexMask &curve_selection,
const VArray<float> &radius,
const bool limit_radius,
const bke::AttributeFilter &attribute_filter)
{
return fillet_curves(src_curves,
curve_selection,
@@ -539,7 +539,7 @@ bke::CurvesGeometry fillet_curves_bezier(
VArray<int>::ForSingle(1, src_curves.points_num()),
limit_radius,
true,
propagation_info);
attribute_filter);
}
} // namespace blender::geometry

View File

@@ -140,7 +140,7 @@ static void join_volumes(const Span<const GeometryComponent *> /*src_components*
static void join_component_type(const bke::GeometryComponent::Type component_type,
const Span<GeometrySet> src_geometry_sets,
const bke::AnonymousAttributePropagationInfo &propagation_info,
const bke::AttributeFilter &attribute_filter,
GeometrySet &result)
{
Vector<const GeometryComponent *> components;
@@ -183,14 +183,14 @@ static void join_component_type(const bke::GeometryComponent::Type component_typ
RealizeInstancesOptions options;
options.keep_original_ids = true;
options.realize_instance_attributes = false;
options.propagation_info = propagation_info;
options.attribute_filter = attribute_filter;
GeometrySet joined_components = realize_instances(
GeometrySet::from_instances(instances.release()), options);
result.add(joined_components.get_component_for_write(component_type));
}
GeometrySet join_geometries(const Span<GeometrySet> geometries,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
GeometrySet result;
result.name = geometries.is_empty() ? "" : geometries[0].name;
@@ -203,7 +203,7 @@ GeometrySet join_geometries(const Span<GeometrySet> geometries,
GeometryComponent::Type::GreasePencil,
GeometryComponent::Type::Edit});
for (const GeometryComponent::Type type : supported_types) {
join_component_type(type, geometries, propagation_info, result);
join_component_type(type, geometries, attribute_filter, result);
}
return result;

View File

@@ -167,7 +167,6 @@ static bke::CurvesGeometry reorder_and_flip_curves(const bke::CurvesGeometry &sr
bke::gather_attributes(src_curves.attributes(),
bke::AttrDomain::Curve,
{},
{},
old_by_new_map,
dst_curves.attributes_for_write());
@@ -254,8 +253,7 @@ static bke::CurvesGeometry join_curves_ranges(const bke::CurvesGeometry &src_cur
const Span<int> old_by_new_map = old_curves_by_new.data().drop_back(1);
bke::gather_attributes(src_curves.attributes(),
bke::AttrDomain::Curve,
{},
{"cyclic"},
bke::attribute_filter_from_skip_ref({"cyclic"}),
old_by_new_map,
dst_curves.attributes_for_write());
@@ -272,17 +270,16 @@ static bke::CurvesGeometry join_curves_ranges(const bke::CurvesGeometry &src_cur
/* Point attributes copied without changes. */
bke::copy_attributes(
src_curves.attributes(), bke::AttrDomain::Point, {}, {}, dst_curves.attributes_for_write());
src_curves.attributes(), bke::AttrDomain::Point, {}, dst_curves.attributes_for_write());
dst_curves.tag_topology_changed();
return dst_curves;
}
bke::CurvesGeometry curves_merge_endpoints(
const bke::CurvesGeometry &src_curves,
Span<int> connect_to_curve,
Span<bool> flip_direction,
const bke::AnonymousAttributePropagationInfo & /*propagation_info*/)
bke::CurvesGeometry curves_merge_endpoints(const bke::CurvesGeometry &src_curves,
Span<int> connect_to_curve,
Span<bool> flip_direction,
const bke::AttributeFilter & /*attribute_filter*/)
{
BLI_assert(connect_to_curve.size() == src_curves.curves_num());
const VArraySpan<bool> src_cyclic = src_curves.cyclic();

View File

@@ -95,7 +95,7 @@ static void copy_overlapping_hint(const Mesh &src, Mesh &dst)
/** Gather vertex group data and array attributes in separate loops. */
static void gather_vert_attributes(const Mesh &mesh_src,
const bke::AnonymousAttributePropagationInfo &propagation_info,
const bke::AttributeFilter &attribute_filter,
const IndexMask &vert_mask,
Mesh &mesh_dst)
{
@@ -112,17 +112,15 @@ static void gather_vert_attributes(const Mesh &mesh_src,
bke::gather_attributes(mesh_src.attributes(),
bke::AttrDomain::Point,
propagation_info,
vertex_group_names,
bke::attribute_filter_with_skip_ref(attribute_filter, vertex_group_names),
vert_mask,
mesh_dst.attributes_for_write());
}
std::optional<Mesh *> mesh_copy_selection(
const Mesh &src_mesh,
const VArray<bool> &selection,
const bke::AttrDomain selection_domain,
const bke::AnonymousAttributePropagationInfo &propagation_info)
std::optional<Mesh *> mesh_copy_selection(const Mesh &src_mesh,
const VArray<bool> &selection,
const bke::AttrDomain selection_domain,
const bke::AttributeFilter &attribute_filter)
{
const Span<int2> src_edges = src_mesh.edges();
const OffsetIndices src_faces = src_mesh.faces();
@@ -238,27 +236,24 @@ std::optional<Mesh *> mesh_copy_selection(
dst_corner_edges);
},
[&]() {
gather_vert_attributes(src_mesh, propagation_info, vert_mask, *dst_mesh);
bke::gather_attributes(src_attributes,
bke::AttrDomain::Edge,
propagation_info,
{".edge_verts"},
edge_mask,
dst_attributes);
bke::gather_attributes(src_attributes,
bke::AttrDomain::Face,
propagation_info,
{},
face_mask,
dst_attributes);
bke::gather_attributes_group_to_group(src_attributes,
bke::AttrDomain::Corner,
propagation_info,
{".corner_edge", ".corner_vert"},
src_faces,
dst_faces,
face_mask,
dst_attributes);
gather_vert_attributes(src_mesh, attribute_filter, vert_mask, *dst_mesh);
bke::gather_attributes(
src_attributes,
bke::AttrDomain::Edge,
bke::attribute_filter_with_skip_ref(attribute_filter, {".edge_verts"}),
edge_mask,
dst_attributes);
bke::gather_attributes(
src_attributes, bke::AttrDomain::Face, attribute_filter, face_mask, dst_attributes);
bke::gather_attributes_group_to_group(
src_attributes,
bke::AttrDomain::Corner,
bke::attribute_filter_with_skip_ref(attribute_filter,
{".corner_edge", ".corner_vert"}),
src_faces,
dst_faces,
face_mask,
dst_attributes);
});
if (selection_domain == bke::AttrDomain::Edge) {
@@ -273,11 +268,10 @@ std::optional<Mesh *> mesh_copy_selection(
return dst_mesh;
}
std::optional<Mesh *> mesh_copy_selection_keep_verts(
const Mesh &src_mesh,
const VArray<bool> &selection,
const bke::AttrDomain selection_domain,
const bke::AnonymousAttributePropagationInfo &propagation_info)
std::optional<Mesh *> mesh_copy_selection_keep_verts(const Mesh &src_mesh,
const VArray<bool> &selection,
const bke::AttrDomain selection_domain,
const bke::AttributeFilter &attribute_filter)
{
const Span<int2> src_edges = src_mesh.edges();
const OffsetIndices src_faces = src_mesh.faces();
@@ -356,27 +350,19 @@ std::optional<Mesh *> mesh_copy_selection_keep_verts(
},
[&]() {
bke::copy_attributes(
src_attributes, bke::AttrDomain::Point, propagation_info, {}, dst_attributes);
bke::gather_attributes(src_attributes,
bke::AttrDomain::Edge,
propagation_info,
{},
edge_mask,
dst_attributes);
bke::gather_attributes(src_attributes,
bke::AttrDomain::Face,
propagation_info,
{},
face_mask,
dst_attributes);
bke::gather_attributes_group_to_group(src_attributes,
bke::AttrDomain::Corner,
propagation_info,
{".corner_edge"},
src_faces,
dst_faces,
face_mask,
dst_attributes);
src_attributes, bke::AttrDomain::Point, attribute_filter, dst_attributes);
bke::gather_attributes(
src_attributes, bke::AttrDomain::Edge, attribute_filter, edge_mask, dst_attributes);
bke::gather_attributes(
src_attributes, bke::AttrDomain::Face, attribute_filter, face_mask, dst_attributes);
bke::gather_attributes_group_to_group(
src_attributes,
bke::AttrDomain::Corner,
bke::attribute_filter_with_skip_ref(attribute_filter, {".corner_edge"}),
src_faces,
dst_faces,
face_mask,
dst_attributes);
});
/* Positions are not changed by the operation, so the bounds are the same. */
@@ -389,11 +375,10 @@ std::optional<Mesh *> mesh_copy_selection_keep_verts(
return dst_mesh;
}
std::optional<Mesh *> mesh_copy_selection_keep_edges(
const Mesh &src_mesh,
const VArray<bool> &selection,
const bke::AttrDomain selection_domain,
const bke::AnonymousAttributePropagationInfo &propagation_info)
std::optional<Mesh *> mesh_copy_selection_keep_edges(const Mesh &src_mesh,
const VArray<bool> &selection,
const bke::AttrDomain selection_domain,
const bke::AttributeFilter &attribute_filter)
{
const OffsetIndices src_faces = src_mesh.faces();
const bke::AttributeAccessor src_attributes = src_mesh.attributes();
@@ -437,16 +422,13 @@ std::optional<Mesh *> mesh_copy_selection_keep_edges(
dst_attributes.add<int>(".corner_vert", bke::AttrDomain::Corner, bke::AttributeInitConstruct());
dst_attributes.add<int>(".corner_edge", bke::AttrDomain::Corner, bke::AttributeInitConstruct());
bke::copy_attributes(
src_attributes, bke::AttrDomain::Point, propagation_info, {}, dst_attributes);
bke::copy_attributes(
src_attributes, bke::AttrDomain::Edge, propagation_info, {}, dst_attributes);
bke::copy_attributes(src_attributes, bke::AttrDomain::Point, attribute_filter, dst_attributes);
bke::copy_attributes(src_attributes, bke::AttrDomain::Edge, attribute_filter, dst_attributes);
bke::gather_attributes(
src_attributes, bke::AttrDomain::Face, propagation_info, {}, face_mask, dst_attributes);
src_attributes, bke::AttrDomain::Face, attribute_filter, face_mask, dst_attributes);
bke::gather_attributes_group_to_group(src_attributes,
bke::AttrDomain::Corner,
propagation_info,
{},
attribute_filter,
src_faces,
dst_faces,
face_mask,

View File

@@ -512,7 +512,7 @@ static Array<int> offsets_to_map(const IndexMask &mask, const OffsetIndices<int>
void split_edges(Mesh &mesh,
const IndexMask &selected_edges,
const bke::AnonymousAttributePropagationInfo & /*propagation_info*/)
const bke::AttributeFilter & /*attribute_filter*/)
{
const int orig_verts_num = mesh.verts_num;
const Span<int2> orig_edges = mesh.edges();

View File

@@ -22,7 +22,7 @@ BLI_NOINLINE bke::CurvesGeometry create_curve_from_vert_indices(
const Span<int> vert_indices,
const Span<int> curve_offsets,
const IndexRange cyclic_curves,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
bke::CurvesGeometry curves(vert_indices.size(), curve_offsets.size());
curves.offsets_for_write().drop_back(1).copy_from(curve_offsets);
@@ -42,11 +42,12 @@ BLI_NOINLINE bke::CurvesGeometry create_curve_from_vert_indices(
skip.add(id);
}
}
const auto attribute_filter_with_skip = bke::attribute_filter_with_skip_ref(attribute_filter,
skip);
bke::gather_attributes(mesh_attributes,
bke::AttrDomain::Point,
propagation_info,
skip,
attribute_filter_with_skip,
vert_indices,
curves_attributes);
@@ -57,10 +58,7 @@ BLI_NOINLINE bke::CurvesGeometry create_curve_from_vert_indices(
if (meta_data.data_type == CD_PROP_STRING) {
return true;
}
if (skip.contains(id)) {
return true;
}
if (bke::attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
if (attribute_filter_with_skip.allow_skip(id)) {
return true;
}
@@ -204,30 +202,27 @@ BLI_NOINLINE static CurveFromEdgesOutput edges_to_curve_point_indices(const int
}
BLI_NOINLINE static bke::CurvesGeometry edges_to_curves_convert(
const Mesh &mesh,
const Span<int2> edges,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const Mesh &mesh, const Span<int2> edges, const bke::AttributeFilter &attribute_filter)
{
CurveFromEdgesOutput output = edges_to_curve_point_indices(mesh.verts_num, edges);
return create_curve_from_vert_indices(mesh.attributes(),
output.vert_indices,
output.curve_offsets,
output.cyclic_curves,
propagation_info);
attribute_filter);
}
bke::CurvesGeometry mesh_to_curve_convert(
const Mesh &mesh,
const IndexMask &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info)
bke::CurvesGeometry mesh_to_curve_convert(const Mesh &mesh,
const IndexMask &selection,
const bke::AttributeFilter &attribute_filter)
{
const Span<int2> edges = mesh.edges();
if (selection.size() == edges.size()) {
return edges_to_curves_convert(mesh, edges, propagation_info);
return edges_to_curves_convert(mesh, edges, attribute_filter);
}
Array<int2> selected_edges(selection.size());
array_utils::gather(edges, selection, selected_edges.as_mutable_span());
return edges_to_curves_convert(mesh, selected_edges, propagation_info);
return edges_to_curves_convert(mesh, selected_edges, attribute_filter);
}
} // namespace blender::geometry

View File

@@ -20,7 +20,7 @@ namespace blender::geometry {
PointCloud *point_merge_by_distance(const PointCloud &src_points,
const float merge_distance,
const IndexMask &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
const bke::AttributeAccessor src_attributes = src_points.attributes();
const Span<float3> positions = src_points.positions();
@@ -123,7 +123,7 @@ PointCloud *point_merge_by_distance(const PointCloud &src_points,
/* Transfer all other attributes. */
for (const StringRef id : attribute_ids) {
if (bke::attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
if (attribute_filter.allow_skip(id)) {
continue;
}

View File

@@ -839,7 +839,7 @@ static void gather_attributes_for_propagation(
const bke::GeometryComponent::Type dst_component_type,
const VArray<int> &instance_depth,
const IndexMask selection,
const bke::AnonymousAttributePropagationInfo &propagation_info,
const bke::AttributeFilter &attribute_filter,
Map<StringRef, AttributeKind> &r_attributes)
{
/* Only needed right now to check if an attribute is built-in on this component type.
@@ -866,9 +866,7 @@ static void gather_attributes_for_propagation(
/* Propagating string attributes is not supported yet. */
return;
}
if (bke::attribute_name_is_anonymous(attribute_id) &&
!propagation_info.propagate(attribute_id))
{
if (attribute_filter.allow_skip(attribute_id)) {
return;
}
@@ -913,7 +911,7 @@ static OrderedAttributes gather_generic_instance_attributes_to_propagate(
bke::GeometryComponent::Type::Instance,
varied_depth_option.depths,
varied_depth_option.selection,
options.propagation_info,
options.attribute_filter,
attributes_to_propagate);
attributes_to_propagate.pop_try("id");
OrderedAttributes ordered_attributes;
@@ -1042,7 +1040,7 @@ static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate(
bke::GeometryComponent::Type::PointCloud,
varied_depth_option.depths,
varied_depth_option.selection,
options.propagation_info,
options.attribute_filter,
attributes_to_propagate);
attributes_to_propagate.remove("position");
@@ -1251,7 +1249,7 @@ static OrderedAttributes gather_generic_mesh_attributes_to_propagate(
bke::GeometryComponent::Type::Mesh,
varied_depth_option.depths,
varied_depth_option.selection,
options.propagation_info,
options.attribute_filter,
attributes_to_propagate);
attributes_to_propagate.remove("position");
attributes_to_propagate.remove(".edge_verts");
@@ -1621,7 +1619,7 @@ static OrderedAttributes gather_generic_curve_attributes_to_propagate(
bke::GeometryComponent::Type::Curve,
varied_depth_option.depths,
varied_depth_option.selection,
options.propagation_info,
options.attribute_filter,
attributes_to_propagate);
attributes_to_propagate.remove("position");
attributes_to_propagate.remove("radius");
@@ -1963,7 +1961,7 @@ static OrderedAttributes gather_generic_grease_pencil_attributes_to_propagate(
bke::GeometryComponent::Type::GreasePencil,
varied_depth_options.depths,
varied_depth_options.selection,
options.propagation_info,
options.attribute_filter,
attributes_to_propagate);
OrderedAttributes ordered_attributes;
@@ -2185,11 +2183,10 @@ static void remove_id_attribute_from_instances(bke::GeometrySet &geometry_set)
/** Propagate instances from the old geometry set to the new geometry set if they are not
* realized.
*/
static void propagate_instances_to_keep(
const bke::GeometrySet &geometry_set,
const IndexMask &selection,
bke::GeometrySet &new_geometry_set,
const bke::AnonymousAttributePropagationInfo &propagation_info)
static void propagate_instances_to_keep(const bke::GeometrySet &geometry_set,
const IndexMask &selection,
bke::GeometrySet &new_geometry_set,
const bke::AttributeFilter &attribute_filter)
{
const Instances &instances = *geometry_set.get_instances();
IndexMaskMemory inverse_selection_indices;
@@ -2201,7 +2198,7 @@ static void propagate_instances_to_keep(
}
std::unique_ptr<Instances> new_instances = std::make_unique<Instances>(instances);
new_instances->remove(inverse_selection, propagation_info);
new_instances->remove(inverse_selection, attribute_filter);
bke::InstancesComponent &new_instances_components =
new_geometry_set.get_component_for_write<bke::InstancesComponent>();
@@ -2239,7 +2236,7 @@ bke::GeometrySet realize_instances(bke::GeometrySet geometry_set,
bke::GeometrySet not_to_realize_set;
propagate_instances_to_keep(
geometry_set, varied_depth_option.selection, not_to_realize_set, options.propagation_info);
geometry_set, varied_depth_option.selection, not_to_realize_set, options.attribute_filter);
if (options.keep_original_ids) {
remove_id_attribute_from_instances(geometry_set);

View File

@@ -92,7 +92,6 @@ static void reorder_mesh_verts_exec(const Mesh &src_mesh,
bke::gather_attributes(src_mesh.attributes(),
bke::AttrDomain::Point,
{},
{},
old_by_new_map,
dst_mesh.attributes_for_write());
const Array<int> new_by_old_map = invert_permutation(old_by_new_map);
@@ -110,7 +109,6 @@ static void reorder_mesh_edges_exec(const Mesh &src_mesh,
bke::gather_attributes(src_mesh.attributes(),
bke::AttrDomain::Edge,
{},
{},
old_by_new_map,
dst_mesh.attributes_for_write());
const Array<int> new_by_old_map = invert_permutation(old_by_new_map);
@@ -125,7 +123,6 @@ static void reorder_mesh_faces_exec(const Mesh &src_mesh,
bke::gather_attributes(src_mesh.attributes(),
bke::AttrDomain::Face,
{},
{},
old_by_new_map,
dst_mesh.attributes_for_write());
const Span<int> old_offsets = src_mesh.face_offsets();
@@ -169,7 +166,6 @@ static void reorder_points_exec(const PointCloud &src_pointcloud,
bke::gather_attributes(src_pointcloud.attributes(),
bke::AttrDomain::Point,
{},
{},
old_by_new_map,
dst_pointcloud.attributes_for_write());
dst_pointcloud.tag_positions_changed();
@@ -183,7 +179,6 @@ static void reorder_curves_exec(const bke::CurvesGeometry &src_curves,
bke::gather_attributes(src_curves.attributes(),
bke::AttrDomain::Curve,
{},
{},
old_by_new_map,
dst_curves.attributes_for_write());
@@ -208,12 +203,11 @@ static void reorder_instaces_exec(const bke::Instances &src_instances,
bke::gather_attributes(src_instances.attributes(),
bke::AttrDomain::Instance,
{},
{},
old_by_new_map,
dst_instances.attributes_for_write());
}
static void clean_unused_attributes(const bke::AnonymousAttributePropagationInfo &propagation_info,
static void clean_unused_attributes(const bke::AttributeFilter &attribute_filter,
bke::MutableAttributeAccessor attributes)
{
Vector<std::string> unused_ids;
@@ -224,7 +218,7 @@ static void clean_unused_attributes(const bke::AnonymousAttributePropagationInfo
if (meta_data.data_type == CD_PROP_STRING) {
return true;
}
if (propagation_info.propagate(id)) {
if (!attribute_filter.allow_skip(id)) {
return true;
}
unused_ids.append(id);
@@ -239,61 +233,59 @@ static void clean_unused_attributes(const bke::AnonymousAttributePropagationInfo
Mesh *reorder_mesh(const Mesh &src_mesh,
Span<int> old_by_new_map,
bke::AttrDomain domain,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
Mesh *dst_mesh = BKE_mesh_copy_for_eval(src_mesh);
clean_unused_attributes(propagation_info, dst_mesh->attributes_for_write());
clean_unused_attributes(attribute_filter, dst_mesh->attributes_for_write());
reorder_mesh_exec(src_mesh, old_by_new_map, domain, *dst_mesh);
return dst_mesh;
}
PointCloud *reorder_points(const PointCloud &src_pointcloud,
Span<int> old_by_new_map,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
PointCloud *dst_pointcloud = BKE_pointcloud_copy_for_eval(&src_pointcloud);
clean_unused_attributes(propagation_info, dst_pointcloud->attributes_for_write());
clean_unused_attributes(attribute_filter, dst_pointcloud->attributes_for_write());
reorder_points_exec(src_pointcloud, old_by_new_map, *dst_pointcloud);
return dst_pointcloud;
}
bke::CurvesGeometry reorder_curves_geometry(
const bke::CurvesGeometry &src_curves,
Span<int> old_by_new_map,
const bke::AnonymousAttributePropagationInfo &propagation_info)
bke::CurvesGeometry reorder_curves_geometry(const bke::CurvesGeometry &src_curves,
Span<int> old_by_new_map,
const bke::AttributeFilter &attribute_filter)
{
bke::CurvesGeometry dst_curves = bke::CurvesGeometry(src_curves);
clean_unused_attributes(propagation_info, dst_curves.attributes_for_write());
clean_unused_attributes(attribute_filter, dst_curves.attributes_for_write());
reorder_curves_exec(src_curves, old_by_new_map, dst_curves);
return dst_curves;
}
Curves *reorder_curves(const Curves &src_curves,
Span<int> old_by_new_map,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
const bke::CurvesGeometry src_curve_geometry = src_curves.geometry.wrap();
Curves *dst_curves = BKE_curves_copy_for_eval(&src_curves);
dst_curves->geometry.wrap() = reorder_curves_geometry(
src_curve_geometry, old_by_new_map, propagation_info);
src_curve_geometry, old_by_new_map, attribute_filter);
return dst_curves;
}
bke::Instances *reorder_instaces(const bke::Instances &src_instances,
Span<int> old_by_new_map,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
bke::Instances *dst_instances = new bke::Instances(src_instances);
clean_unused_attributes(propagation_info, dst_instances->attributes_for_write());
clean_unused_attributes(attribute_filter, dst_instances->attributes_for_write());
reorder_instaces_exec(src_instances, old_by_new_map, *dst_instances);
return dst_instances;
}
bke::GeometryComponentPtr reordered_component(
const bke::GeometryComponent &src_component,
const Span<int> old_by_new_map,
const bke::AttrDomain domain,
const bke::AnonymousAttributePropagationInfo &propagation_info)
bke::GeometryComponentPtr reordered_component(const bke::GeometryComponent &src_component,
const Span<int> old_by_new_map,
const bke::AttrDomain domain,
const bke::AttributeFilter &attribute_filter)
{
BLI_assert(!src_component.is_empty());
@@ -301,28 +293,28 @@ bke::GeometryComponentPtr reordered_component(
&src_component))
{
Mesh *result_mesh = reorder_mesh(
*src_mesh_component->get(), old_by_new_map, domain, propagation_info);
*src_mesh_component->get(), old_by_new_map, domain, attribute_filter);
return bke::GeometryComponentPtr(new bke::MeshComponent(result_mesh));
}
else if (const bke::PointCloudComponent *src_points_component =
dynamic_cast<const bke::PointCloudComponent *>(&src_component))
{
PointCloud *result_point_cloud = reorder_points(
*src_points_component->get(), old_by_new_map, propagation_info);
*src_points_component->get(), old_by_new_map, attribute_filter);
return bke::GeometryComponentPtr(new bke::PointCloudComponent(result_point_cloud));
}
else if (const bke::CurveComponent *src_curves_component =
dynamic_cast<const bke::CurveComponent *>(&src_component))
{
Curves *result_curves = reorder_curves(
*src_curves_component->get(), old_by_new_map, propagation_info);
*src_curves_component->get(), old_by_new_map, attribute_filter);
return bke::GeometryComponentPtr(new bke::CurveComponent(result_curves));
}
else if (const bke::InstancesComponent *src_instances_component =
dynamic_cast<const bke::InstancesComponent *>(&src_component))
{
bke::Instances *result_instances = reorder_instaces(
*src_instances_component->get(), old_by_new_map, propagation_info);
*src_instances_component->get(), old_by_new_map, attribute_filter);
return bke::GeometryComponentPtr(new bke::InstancesComponent(result_instances));
}

View File

@@ -26,7 +26,7 @@ static std::optional<bke::CurvesGeometry> separate_curves_selection(
const fn::FieldContext &field_context,
const fn::Field<bool> &selection_field,
const AttrDomain domain,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
const int domain_size = src_curves.attributes().domain_size(domain);
fn::FieldEvaluator evaluator{field_context, domain_size};
@@ -41,10 +41,10 @@ static std::optional<bke::CurvesGeometry> separate_curves_selection(
}
if (domain == AttrDomain::Point) {
return bke::curves_copy_point_selection(src_curves, selection, propagation_info);
return bke::curves_copy_point_selection(src_curves, selection, attribute_filter);
}
else if (domain == AttrDomain::Curve) {
return bke::curves_copy_curve_selection(src_curves, selection, propagation_info);
return bke::curves_copy_curve_selection(src_curves, selection, attribute_filter);
}
BLI_assert_unreachable();
return std::nullopt;
@@ -54,7 +54,7 @@ static std::optional<bke::CurvesGeometry> separate_curves_selection(
static std::optional<PointCloud *> separate_point_cloud_selection(
const PointCloud &src_pointcloud,
const fn::Field<bool> &selection_field,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
const bke::PointCloudFieldContext context{src_pointcloud};
fn::FieldEvaluator evaluator{context, src_pointcloud.totpoint};
@@ -71,17 +71,15 @@ static std::optional<PointCloud *> separate_point_cloud_selection(
PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size());
bke::gather_attributes(src_pointcloud.attributes(),
AttrDomain::Point,
propagation_info,
{},
attribute_filter,
selection,
pointcloud->attributes_for_write());
return pointcloud;
}
static void delete_selected_instances(
bke::GeometrySet &geometry_set,
const fn::Field<bool> &selection_field,
const bke::AnonymousAttributePropagationInfo &propagation_info)
static void delete_selected_instances(bke::GeometrySet &geometry_set,
const fn::Field<bool> &selection_field,
const bke::AttributeFilter &attribute_filter)
{
bke::Instances &instances = *geometry_set.get_instances_for_write();
bke::InstancesFieldContext field_context{instances};
@@ -95,15 +93,14 @@ static void delete_selected_instances(
return;
}
instances.remove(selection, propagation_info);
instances.remove(selection, attribute_filter);
}
static std::optional<Mesh *> separate_mesh_selection(
const Mesh &mesh,
const fn::Field<bool> &selection_field,
const AttrDomain selection_domain,
const GeometryNodeDeleteGeometryMode mode,
const bke::AnonymousAttributePropagationInfo &propagation_info)
static std::optional<Mesh *> separate_mesh_selection(const Mesh &mesh,
const fn::Field<bool> &selection_field,
const AttrDomain selection_domain,
const GeometryNodeDeleteGeometryMode mode,
const bke::AttributeFilter &attribute_filter)
{
const bke::AttributeAccessor attributes = mesh.attributes();
const bke::MeshFieldContext context(mesh, selection_domain);
@@ -114,11 +111,11 @@ static std::optional<Mesh *> separate_mesh_selection(
switch (mode) {
case GEO_NODE_DELETE_GEOMETRY_MODE_ALL:
return mesh_copy_selection(mesh, selection, selection_domain, propagation_info);
return mesh_copy_selection(mesh, selection, selection_domain, attribute_filter);
case GEO_NODE_DELETE_GEOMETRY_MODE_EDGE_FACE:
return mesh_copy_selection_keep_verts(mesh, selection, selection_domain, propagation_info);
return mesh_copy_selection_keep_verts(mesh, selection, selection_domain, attribute_filter);
case GEO_NODE_DELETE_GEOMETRY_MODE_ONLY_FACE:
return mesh_copy_selection_keep_edges(mesh, selection, selection_domain, propagation_info);
return mesh_copy_selection_keep_edges(mesh, selection, selection_domain, attribute_filter);
}
return nullptr;
}
@@ -126,7 +123,7 @@ static std::optional<Mesh *> separate_mesh_selection(
static std::optional<GreasePencil *> separate_grease_pencil_layer_selection(
const GreasePencil &src_grease_pencil,
const fn::Field<bool> &selection_field,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
const bke::AttributeAccessor attributes = src_grease_pencil.attributes();
const bke::GeometryFieldContext context(src_grease_pencil);
@@ -153,8 +150,7 @@ static std::optional<GreasePencil *> separate_grease_pencil_layer_selection(
bke::gather_attributes(src_grease_pencil.attributes(),
AttrDomain::Layer,
propagation_info,
{},
attribute_filter,
selection,
dst_grease_pencil->attributes_for_write());
@@ -165,14 +161,14 @@ void separate_geometry(bke::GeometrySet &geometry_set,
const AttrDomain domain,
const GeometryNodeDeleteGeometryMode mode,
const fn::Field<bool> &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info,
const bke::AttributeFilter &attribute_filter,
bool &r_is_error)
{
bool some_valid_domain = false;
if (const PointCloud *points = geometry_set.get_pointcloud()) {
if (domain == AttrDomain::Point) {
std::optional<PointCloud *> dst_points = separate_point_cloud_selection(
*points, selection, propagation_info);
*points, selection, attribute_filter);
if (dst_points) {
geometry_set.replace_pointcloud(*dst_points);
}
@@ -182,7 +178,7 @@ void separate_geometry(bke::GeometrySet &geometry_set,
if (const Mesh *mesh = geometry_set.get_mesh()) {
if (ELEM(domain, AttrDomain::Point, AttrDomain::Edge, AttrDomain::Face)) {
std::optional<Mesh *> dst_mesh = separate_mesh_selection(
*mesh, selection, domain, mode, propagation_info);
*mesh, selection, domain, mode, attribute_filter);
if (dst_mesh) {
if (*dst_mesh) {
const char *active_layer = CustomData_get_active_layer_name(&mesh->corner_data,
@@ -215,7 +211,7 @@ void separate_geometry(bke::GeometrySet &geometry_set,
const bke::CurvesGeometry &src_curves = src_curves_id->geometry.wrap();
const bke::CurvesFieldContext field_context{src_curves, domain};
std::optional<bke::CurvesGeometry> dst_curves = separate_curves_selection(
src_curves, field_context, selection, domain, propagation_info);
src_curves, field_context, selection, domain, attribute_filter);
if (dst_curves) {
if (dst_curves->points_num() == 0) {
geometry_set.remove<bke::CurveComponent>();
@@ -234,7 +230,7 @@ void separate_geometry(bke::GeometrySet &geometry_set,
if (domain == AttrDomain::Layer) {
const GreasePencil &grease_pencil = *geometry_set.get_grease_pencil();
std::optional<GreasePencil *> dst_grease_pencil = separate_grease_pencil_layer_selection(
grease_pencil, selection, propagation_info);
grease_pencil, selection, attribute_filter);
if (dst_grease_pencil) {
geometry_set.replace_grease_pencil(*dst_grease_pencil);
}
@@ -250,7 +246,7 @@ void separate_geometry(bke::GeometrySet &geometry_set,
const bke::CurvesGeometry &src_curves = drawing->strokes();
const bke::GreasePencilLayerFieldContext field_context(grease_pencil, domain, layer_index);
std::optional<bke::CurvesGeometry> dst_curves = separate_curves_selection(
src_curves, field_context, selection, domain, propagation_info);
src_curves, field_context, selection, domain, attribute_filter);
if (!dst_curves) {
continue;
}
@@ -262,7 +258,7 @@ void separate_geometry(bke::GeometrySet &geometry_set,
}
if (geometry_set.has_instances()) {
if (domain == AttrDomain::Instance) {
delete_selected_instances(geometry_set, selection, propagation_info);
delete_selected_instances(geometry_set, selection, attribute_filter);
some_valid_domain = true;
}
}

View File

@@ -265,10 +265,9 @@ static int to_nurbs_size(const CurveType src_type, const int src_size)
}
}
static bke::CurvesGeometry convert_curves_to_bezier(
const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info)
static bke::CurvesGeometry convert_curves_to_bezier(const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const bke::AttributeFilter &attribute_filter)
{
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
const VArray<int8_t> src_knot_modes = src_curves.nurbs_knots_modes();
@@ -309,8 +308,7 @@ static bke::CurvesGeometry convert_curves_to_bezier(
src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_POINT,
propagation_info,
attributes_to_skip);
bke::attribute_filter_with_skip_ref(attribute_filter, attributes_to_skip));
auto catmull_rom_to_bezier = [&](const IndexMask &selection) {
bke::curves::fill_points<int8_t>(
@@ -440,8 +438,7 @@ static bke::CurvesGeometry convert_curves_to_bezier(
bke::copy_attributes_group_to_group(src_attributes,
bke::AttrDomain::Point,
propagation_info,
{},
attribute_filter,
src_points_by_curve,
dst_points_by_curve,
unselected,
@@ -450,10 +447,9 @@ static bke::CurvesGeometry convert_curves_to_bezier(
return dst_curves;
}
static bke::CurvesGeometry convert_curves_to_nurbs(
const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const bke::AnonymousAttributePropagationInfo &propagation_info)
static bke::CurvesGeometry convert_curves_to_nurbs(const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const bke::AttributeFilter &attribute_filter)
{
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
const VArray<int8_t> src_types = src_curves.curve_types();
@@ -481,13 +477,13 @@ static bke::CurvesGeometry convert_curves_to_nurbs(
src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_POINT,
propagation_info,
{"position",
"handle_type_left",
"handle_type_right",
"handle_right",
"handle_left",
"nurbs_weight"});
bke::attribute_filter_with_skip_ref(attribute_filter,
{"position",
"handle_type_left",
"handle_type_right",
"handle_right",
"handle_left",
"nurbs_weight"}));
auto fill_weights_if_necessary = [&](const IndexMask &selection) {
if (src_attributes.contains("nurbs_weight")) {
@@ -609,8 +605,7 @@ static bke::CurvesGeometry convert_curves_to_nurbs(
bke::copy_attributes_group_to_group(src_attributes,
bke::AttrDomain::Point,
propagation_info,
{},
attribute_filter,
src_points_by_curve,
dst_points_by_curve,
unselected,
@@ -633,7 +628,7 @@ static bke::CurvesGeometry convert_curves_to_catmull_rom_or_poly(
const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const CurveType dst_type,
const bke::AnonymousAttributePropagationInfo &propagation_info,
const bke::AttributeFilter &attribute_filter,
const ConvertCurvesOptions &options)
{
const bool use_bezier_handles = (dst_type == CURVE_TYPE_CATMULL_ROM) ?
@@ -677,13 +672,13 @@ static bke::CurvesGeometry convert_curves_to_catmull_rom_or_poly(
src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_POINT,
propagation_info,
{"position",
"handle_type_left",
"handle_type_right",
"handle_right",
"handle_left",
"nurbs_weight"});
bke::attribute_filter_with_skip_ref(attribute_filter,
{"position",
"handle_type_left",
"handle_type_right",
"handle_right",
"handle_left",
"nurbs_weight"}));
auto convert_from_catmull_rom_or_poly_or_nurbs = [&](const IndexMask &selection) {
array_utils::copy_group_to_group(
@@ -741,8 +736,7 @@ static bke::CurvesGeometry convert_curves_to_catmull_rom_or_poly(
bke::copy_attributes_group_to_group(src_attributes,
bke::AttrDomain::Point,
propagation_info,
{},
attribute_filter,
src_points_by_curve,
dst_points_by_curve,
unselected,
@@ -779,24 +773,24 @@ static bke::CurvesGeometry convert_bezier_or_catmull_rom_to_poly_before_conversi
bke::CurvesGeometry convert_curves(const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const CurveType dst_type,
const bke::AnonymousAttributePropagationInfo &propagation_info,
const bke::AttributeFilter &attribute_filter,
const ConvertCurvesOptions &options)
{
switch (dst_type) {
case CURVE_TYPE_CATMULL_ROM:
case CURVE_TYPE_POLY:
return convert_curves_to_catmull_rom_or_poly(
src_curves, selection, dst_type, propagation_info, options);
src_curves, selection, dst_type, attribute_filter, options);
case CURVE_TYPE_BEZIER:
return convert_curves_to_bezier(src_curves, selection, propagation_info);
return convert_curves_to_bezier(src_curves, selection, attribute_filter);
case CURVE_TYPE_NURBS: {
if (!options.keep_bezier_shape_as_nurbs || !options.keep_catmull_rom_shape_as_nurbs) {
const bke::CurvesGeometry tmp_src_curves =
convert_bezier_or_catmull_rom_to_poly_before_conversion_to_nurbs(
src_curves, selection, options);
return convert_curves_to_nurbs(tmp_src_curves, selection, propagation_info);
return convert_curves_to_nurbs(tmp_src_curves, selection, attribute_filter);
}
return convert_curves_to_nurbs(src_curves, selection, propagation_info);
return convert_curves_to_nurbs(src_curves, selection, attribute_filter);
}
}
BLI_assert_unreachable();

View File

@@ -268,11 +268,10 @@ static void subdivide_bezier_positions(const Span<float3> src_positions,
cyclic, dst_types_l, dst_types_r, dst_positions, dst_handles_l, dst_handles_r);
}
bke::CurvesGeometry subdivide_curves(
const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const VArray<int> &cuts,
const bke::AnonymousAttributePropagationInfo &propagation_info)
bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const VArray<int> &cuts,
const bke::AttributeFilter &attribute_filter)
{
if (src_curves.points_num() == 0) {
return src_curves;
@@ -320,7 +319,7 @@ bke::CurvesGeometry subdivide_curves(
auto subdivide_catmull_rom = [&](const IndexMask &selection) {
for (auto &attribute : bke::retrieve_attributes_for_transfer(
src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info))
src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, attribute_filter))
{
subdivide_attribute_catmull_rom(src_points_by_curve,
dst_points_by_curve,
@@ -335,7 +334,7 @@ bke::CurvesGeometry subdivide_curves(
auto subdivide_poly = [&](const IndexMask &selection) {
for (auto &attribute : bke::retrieve_attributes_for_transfer(
src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info))
src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, attribute_filter))
{
subdivide_attribute_linear(src_points_by_curve,
dst_points_by_curve,
@@ -380,12 +379,16 @@ bke::CurvesGeometry subdivide_curves(
dst_handles_r.slice(dst_points));
});
for (auto &attribute : bke::retrieve_attributes_for_transfer(
src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_POINT,
propagation_info,
{"position", "handle_type_left", "handle_type_right", "handle_right", "handle_left"}))
for (auto &attribute :
bke::retrieve_attributes_for_transfer(src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_POINT,
attribute_filter_with_skip_ref(attribute_filter,
{"position",
"handle_type_left",
"handle_type_right",
"handle_right",
"handle_left"})))
{
subdivide_attribute_linear(src_points_by_curve,
dst_points_by_curve,
@@ -411,8 +414,7 @@ bke::CurvesGeometry subdivide_curves(
bke::copy_attributes_group_to_group(src_attributes,
bke::AttrDomain::Point,
propagation_info,
{},
attribute_filter,
src_points_by_curve,
dst_points_by_curve,
unselected,

View File

@@ -931,7 +931,7 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
const VArray<float> &starts,
const VArray<float> &ends,
const GeometryNodeCurveSampleMode mode,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
IndexMaskMemory memory;
@@ -977,13 +977,13 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_POINT,
propagation_info,
{"position",
"handle_left",
"handle_right",
"handle_type_left",
"handle_type_right",
"nurbs_weight"});
bke::attribute_filter_with_skip_ref(attribute_filter,
{"position",
"handle_left",
"handle_right",
"handle_type_left",
"handle_type_right",
"nurbs_weight"}));
auto trim_catmull = [&](const IndexMask &selection) {
trim_catmull_rom_curves(src_curves,
@@ -1058,14 +1058,14 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves,
copy_point_skip.add("nurbs_weight");
}
bke::copy_attributes_group_to_group(src_attributes,
bke::AttrDomain::Point,
propagation_info,
copy_point_skip,
src_points_by_curve,
dst_points_by_curve,
unselected,
dst_attributes);
bke::copy_attributes_group_to_group(
src_attributes,
bke::AttrDomain::Point,
bke::attribute_filter_with_skip_ref(attribute_filter, copy_point_skip),
src_points_by_curve,
dst_points_by_curve,
unselected,
dst_attributes);
}
dst_curves.remove_attributes_based_on_types();

View File

@@ -273,10 +273,9 @@ Mesh *ABCCurveMeshWriter::get_export_mesh(Object *object_eval, bool &r_needsfree
}
case OB_CURVES:
const bke::AnonymousAttributePropagationInfo propagation_info;
Curves *curves = static_cast<Curves *>(object_eval->data);
r_needsfree = true;
return bke::curve_to_wire_mesh(curves->geometry.wrap(), propagation_info);
return bke::curve_to_wire_mesh(curves->geometry.wrap());
}
return nullptr;

View File

@@ -213,7 +213,6 @@ static bke::CurvesGeometry create_array_copies(const Object &ob,
geometry::RealizeInstancesOptions options;
options.keep_original_ids = true;
options.realize_instance_attributes = false; /* Should this be true? */
options.propagation_info = {};
bke::GeometrySet result_geo = geometry::realize_instances(
bke::GeometrySet::from_instances(instances.release()), options);
return std::move(result_geo.get_curves_for_write()->geometry.wrap());

View File

@@ -258,10 +258,8 @@ static bke::CurvesGeometry build_concurrent(bke::greasepencil::Drawing &drawing,
const bke::AttributeAccessor src_attributes = curves.attributes();
bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
gather_attributes(
src_attributes, bke::AttrDomain::Point, {}, {}, dst_to_src_point, dst_attributes);
gather_attributes(
src_attributes, bke::AttrDomain::Curve, {}, {}, dst_to_src_curve, dst_attributes);
gather_attributes(src_attributes, bke::AttrDomain::Point, {}, dst_to_src_point, dst_attributes);
gather_attributes(src_attributes, bke::AttrDomain::Curve, {}, dst_to_src_curve, dst_attributes);
dst_curves.update_curve_types();
@@ -413,10 +411,8 @@ static bke::CurvesGeometry build_sequential(bke::greasepencil::Drawing &drawing,
const bke::AttributeAccessor src_attributes = curves.attributes();
bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
gather_attributes(
src_attributes, bke::AttrDomain::Point, {}, {}, dst_to_src_point, dst_attributes);
gather_attributes(
src_attributes, bke::AttrDomain::Curve, {}, {}, dst_to_src_curve, dst_attributes);
gather_attributes(src_attributes, bke::AttrDomain::Point, {}, dst_to_src_point, dst_attributes);
gather_attributes(src_attributes, bke::AttrDomain::Curve, {}, dst_to_src_curve, dst_attributes);
dst_curves.update_curve_types();

View File

@@ -303,14 +303,12 @@ static bke::CurvesGeometry create_dashes(const PatternInfo &pattern_info,
bke::gather_attributes(src_attributes,
bke::AttrDomain::Point,
{},
{"radius", "opacity"},
bke::attribute_filter_from_skip_ref({"radius", "opacity"}),
src_point_indices,
dst_attributes);
bke::gather_attributes(src_attributes,
bke::AttrDomain::Curve,
{},
{"cyclic", "material_index"},
bke::attribute_filter_from_skip_ref({"cyclic", "material_index"}),
src_curve_indices,
dst_attributes);

View File

@@ -576,11 +576,10 @@ static void create_envelope_strokes(const EnvelopeInfo &info,
dst_curves.offsets_for_write().last() = dst_point_num;
bke::gather_attributes(
src_attributes, bke::AttrDomain::Point, {}, {}, src_point_indices, dst_attributes);
src_attributes, bke::AttrDomain::Point, {}, src_point_indices, dst_attributes);
bke::gather_attributes(src_attributes,
bke::AttrDomain::Curve,
{},
{"cyclic", "material_index"},
bke::attribute_filter_from_skip_ref({"cyclic", "material_index"}),
src_curve_indices,
dst_attributes);

View File

@@ -131,7 +131,6 @@ static bke::CurvesGeometry create_mirror_copies(const Object &ob,
geometry::RealizeInstancesOptions options;
options.keep_original_ids = true;
options.realize_instance_attributes = false;
options.propagation_info = {};
bke::GeometrySet result_geo = geometry::realize_instances(
bke::GeometrySet::from_instances(instances.release()), options);
return std::move(result_geo.get_curves_for_write()->geometry.wrap());

View File

@@ -120,7 +120,6 @@ static bke::CurvesGeometry duplicate_strokes(const bke::CurvesGeometry &curves,
geometry::RealizeInstancesOptions options;
options.keep_original_ids = true;
options.realize_instance_attributes = true;
options.propagation_info = {};
bke::GeometrySet result_geo = geometry::realize_instances(
bke::GeometrySet::from_instances(instances.release()), options);
return std::move(result_geo.get_curves_for_write()->geometry.wrap());

View File

@@ -149,7 +149,7 @@ static bke::CurvesGeometry reorder_cyclic_curve_points(const bke::CurvesGeometry
* source indices are not ordered. */
bke::CurvesGeometry dst_curves(src_curves);
bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
bke::gather_attributes(src_attributes, bke::AttrDomain::Point, {}, {}, indices, dst_attributes);
bke::gather_attributes(src_attributes, bke::AttrDomain::Point, {}, indices, dst_attributes);
return dst_curves;
}

View File

@@ -11,6 +11,7 @@
#include "FN_lazy_function.hh"
#include "FN_multi_function_builder.hh"
#include "BKE_attribute_filter.hh"
#include "BKE_attribute_math.hh"
#include "BKE_geometry_fields.hh"
#include "BKE_geometry_set.hh"
@@ -24,10 +25,10 @@
namespace blender::nodes {
using bke::AnonymousAttributePropagationInfo;
using bke::AttrDomain;
using bke::AttributeAccessor;
using bke::AttributeFieldInput;
using bke::AttributeFilter;
using bke::AttributeKind;
using bke::AttributeMetaData;
using bke::AttributeReader;
@@ -56,6 +57,16 @@ using fn::GField;
using geo_eval_log::NamedAttributeUsage;
using geo_eval_log::NodeWarningType;
class NodeAttributeFilter : public AttributeFilter {
private:
const bke::AnonymousAttributeSet &set_;
public:
NodeAttributeFilter(const bke::AnonymousAttributeSet &set) : set_(set) {}
Result filter(StringRef attribute_name) const override;
};
class GeoNodeExecParams {
private:
const bNode &node_;
@@ -282,20 +293,16 @@ class GeoNodeExecParams {
}
/**
* Get information about which anonymous attributes should be propagated to the given output.
* Get information about which attributes should be propagated to the given output.
*/
AnonymousAttributePropagationInfo get_output_propagation_info(
const StringRef output_identifier) const
NodeAttributeFilter get_attribute_filter(const StringRef output_identifier) const
{
const int lf_index =
lf_input_for_attribute_propagation_to_output_[node_.output_by_identifier(output_identifier)
.index_in_all_outputs()];
const bke::AnonymousAttributeSet &set = params_.get_input<bke::AnonymousAttributeSet>(
lf_index);
AnonymousAttributePropagationInfo info;
info.names = set.names;
info.propagate_all = false;
return info;
return NodeAttributeFilter(set);
}
private:

View File

@@ -169,8 +169,8 @@ static void node_operators()
WM_operatortype_append(NODE_OT_capture_attribute_item_move);
}
static void clean_unused_attributes(const AnonymousAttributePropagationInfo &propagation_info,
const Set<StringRef> &skip,
static void clean_unused_attributes(const AttributeFilter &attribute_filter,
const Set<StringRef> &keep,
GeometryComponent &component)
{
std::optional<MutableAttributeAccessor> attributes = component.attributes_for_write();
@@ -183,10 +183,10 @@ static void clean_unused_attributes(const AnonymousAttributePropagationInfo &pro
if (!bke::attribute_name_is_anonymous(id)) {
return true;
}
if (skip.contains(id)) {
if (keep.contains(id)) {
return true;
}
if (propagation_info.propagate(id)) {
if (!attribute_filter.allow_skip(id)) {
return true;
}
unused_ids.append(id);
@@ -251,7 +251,7 @@ static void node_geo_exec(GeoNodeExecParams params)
/* Changing of the anonymous attributes may require removing attributes that are no longer
* needed. */
clean_unused_attributes(
params.get_output_propagation_info("Geometry"), used_attribute_ids_set, component);
params.get_attribute_filter("Geometry"), used_attribute_ids_set, component);
};
/* Run on the instances component separately to only affect the top level of instances. */

View File

@@ -62,7 +62,7 @@ static bke::CurvesGeometry fillet_curve(const bke::CurvesGeometry &src_curves,
const std::optional<Field<int>> &count_field,
const Field<float> &radius_field,
const bool limit_radius,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
fn::FieldEvaluator evaluator{field_context, src_curves.points_num()};
evaluator.add(radius_field);
@@ -74,7 +74,7 @@ static bke::CurvesGeometry fillet_curve(const bke::CurvesGeometry &src_curves,
src_curves.curves_range(),
evaluator.get_evaluated<float>(0),
limit_radius,
propagation_info);
attribute_filter);
}
case GEO_NODE_CURVE_FILLET_POLY: {
evaluator.add(*count_field);
@@ -84,7 +84,7 @@ static bke::CurvesGeometry fillet_curve(const bke::CurvesGeometry &src_curves,
evaluator.get_evaluated<float>(0),
evaluator.get_evaluated<int>(1),
limit_radius,
propagation_info);
attribute_filter);
}
}
return bke::CurvesGeometry();
@@ -95,7 +95,7 @@ static void fillet_grease_pencil(GreasePencil &grease_pencil,
const std::optional<Field<int>> &count_field,
const Field<float> &radius_field,
const bool limit_radius,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
using namespace blender::bke::greasepencil;
for (const int layer_index : grease_pencil.layers().index_range()) {
@@ -115,7 +115,7 @@ static void fillet_grease_pencil(GreasePencil &grease_pencil,
count_field,
radius_field,
limit_radius,
propagation_info);
attribute_filter);
drawing->strokes_for_write() = std::move(dst_curves);
drawing->tag_topology_changed();
}
@@ -136,8 +136,7 @@ static void node_geo_exec(GeoNodeExecParams params)
count_field.emplace(params.extract_input<Field<int>>("Count"));
}
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Curve");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Curve");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (geometry_set.has_curves()) {
@@ -150,7 +149,7 @@ static void node_geo_exec(GeoNodeExecParams params)
count_field,
radius_field,
limit_radius,
propagation_info);
attribute_filter);
Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves));
bke::curves_copy_parameters(curves_id, *dst_curves_id);
geometry_set.replace_curves(dst_curves_id);
@@ -158,7 +157,7 @@ static void node_geo_exec(GeoNodeExecParams params)
if (geometry_set.has_grease_pencil()) {
GreasePencil &grease_pencil = *geometry_set.get_grease_pencil_for_write();
fillet_grease_pencil(
grease_pencil, mode, count_field, radius_field, limit_radius, propagation_info);
grease_pencil, mode, count_field, radius_field, limit_radius, attribute_filter);
}
});

View File

@@ -67,7 +67,7 @@ static void node_geo_exec(GeoNodeExecParams params)
}
bke::CurvesGeometry dst_curves = geometry::convert_curves(
src_curves, selection, dst_type, params.get_output_propagation_info("Curve"));
src_curves, selection, dst_type, params.get_attribute_filter("Curve"));
Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves));
bke::curves_copy_parameters(src_curves_id, *dst_curves_id);
geometry_set.replace_curves(dst_curves_id);

View File

@@ -24,7 +24,7 @@ static void node_declare(NodeDeclarationBuilder &b)
static Curves *subdivide_curves(const Curves &src_curves_id,
Field<int> &cuts_field,
const AnonymousAttributePropagationInfo &propagation_info)
const bke::AttributeFilter &attribute_filter)
{
const bke::CurvesGeometry &src_curves = src_curves_id.geometry.wrap();
@@ -39,17 +39,16 @@ static Curves *subdivide_curves(const Curves &src_curves_id,
}
bke::CurvesGeometry dst_curves = geometry::subdivide_curves(
src_curves, src_curves.curves_range(), cuts, propagation_info);
src_curves, src_curves.curves_range(), cuts, attribute_filter);
Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves));
bke::curves_copy_parameters(src_curves_id, *dst_curves_id);
return dst_curves_id;
}
static void subdivide_grease_pencil_curves(
GreasePencil &grease_pencil,
Field<int> &cuts_field,
const AnonymousAttributePropagationInfo &propagation_info)
static void subdivide_grease_pencil_curves(GreasePencil &grease_pencil,
Field<int> &cuts_field,
const AttributeFilter &attribute_filter)
{
using namespace bke::greasepencil;
for (const int layer_index : grease_pencil.layers().index_range()) {
@@ -73,7 +72,7 @@ static void subdivide_grease_pencil_curves(
}
bke::CurvesGeometry dst_curves = geometry::subdivide_curves(
src_curves, src_curves.curves_range(), cuts, propagation_info);
src_curves, src_curves.curves_range(), cuts, attribute_filter);
drawing->strokes_for_write() = std::move(dst_curves);
drawing->tag_topology_changed();
@@ -86,20 +85,19 @@ static void node_geo_exec(GeoNodeExecParams params)
Field<int> cuts_field = params.extract_input<Field<int>>("Cuts");
GeometryComponentEditData::remember_deformed_positions_if_necessary(geometry_set);
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Curve");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Curve");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (geometry_set.has_curves()) {
const Curves &src_curves_id = *geometry_set.get_curves();
Curves *dst_curves_id = subdivide_curves(src_curves_id, cuts_field, propagation_info);
Curves *dst_curves_id = subdivide_curves(src_curves_id, cuts_field, attribute_filter);
if (dst_curves_id) {
geometry_set.replace_curves(dst_curves_id);
}
}
if (geometry_set.has_grease_pencil()) {
GreasePencil &grease_pencil = *geometry_set.get_grease_pencil_for_write();
subdivide_grease_pencil_curves(grease_pencil, cuts_field, propagation_info);
subdivide_grease_pencil_curves(grease_pencil, cuts_field, attribute_filter);
}
});
params.set_output("Curve", geometry_set);

View File

@@ -32,16 +32,16 @@ static void node_declare(NodeDeclarationBuilder &b)
static Mesh *curve_to_mesh(const bke::CurvesGeometry &curves,
const GeometrySet &profile_set,
const bool fill_caps,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
Mesh *mesh;
if (profile_set.has_curves()) {
const Curves *profile_curves = profile_set.get_curves();
mesh = bke::curve_to_mesh_sweep(
curves, profile_curves->geometry.wrap(), fill_caps, propagation_info);
curves, profile_curves->geometry.wrap(), fill_caps, attribute_filter);
}
else {
mesh = bke::curve_to_wire_mesh(curves, propagation_info);
mesh = bke::curve_to_wire_mesh(curves, attribute_filter);
}
geometry::debug_randomize_mesh_order(mesh);
return mesh;
@@ -50,7 +50,7 @@ static Mesh *curve_to_mesh(const bke::CurvesGeometry &curves,
static void grease_pencil_to_mesh(GeometrySet &geometry_set,
const GeometrySet &profile_set,
const bool fill_caps,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
using namespace blender::bke::greasepencil;
@@ -63,7 +63,7 @@ static void grease_pencil_to_mesh(GeometrySet &geometry_set,
continue;
}
const bke::CurvesGeometry &curves = drawing->strokes();
mesh_by_layer[layer_index] = curve_to_mesh(curves, profile_set, fill_caps, propagation_info);
mesh_by_layer[layer_index] = curve_to_mesh(curves, profile_set, fill_caps, attribute_filter);
}
if (mesh_by_layer.is_empty()) {
@@ -93,7 +93,7 @@ static void grease_pencil_to_mesh(GeometrySet &geometry_set,
GeometrySet::propagate_attributes_from_layer_to_instances(
geometry_set.get_grease_pencil()->attributes(),
geometry_set.get_instances_for_write()->attributes_for_write(),
propagation_info);
attribute_filter);
geometry_set.replace_grease_pencil(nullptr);
}
@@ -104,17 +104,16 @@ static void node_geo_exec(GeoNodeExecParams params)
const bool fill_caps = params.extract_input<bool>("Fill Caps");
bke::GeometryComponentEditData::remember_deformed_positions_if_necessary(curve_set);
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Mesh");
const AttributeFilter &attribute_filter = params.get_attribute_filter("Mesh");
curve_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (geometry_set.has_curves()) {
const Curves &curves = *geometry_set.get_curves();
Mesh *mesh = curve_to_mesh(curves.geometry.wrap(), profile_set, fill_caps, propagation_info);
Mesh *mesh = curve_to_mesh(curves.geometry.wrap(), profile_set, fill_caps, attribute_filter);
geometry_set.replace_mesh(mesh);
}
if (geometry_set.has_grease_pencil()) {
grease_pencil_to_mesh(geometry_set, profile_set, fill_caps, propagation_info);
grease_pencil_to_mesh(geometry_set, profile_set, fill_caps, attribute_filter);
}
geometry_set.keep_only_during_modify({GeometryComponent::Type::Mesh});
});

View File

@@ -213,7 +213,7 @@ static void grease_pencil_to_points(GeometrySet &geometry_set,
const GeometryNodeCurveResampleMode mode,
geometry::ResampleCurvesOutputAttributeIDs resample_attributes,
const std::optional<StringRef> &rotation_anonymous_id,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
Field<int> count;
Field<float> length;
@@ -298,7 +298,7 @@ static void grease_pencil_to_points(GeometrySet &geometry_set,
GeometrySet::propagate_attributes_from_layer_to_instances(
geometry.get_grease_pencil()->attributes(),
geometry.get_instances_for_write()->attributes_for_write(),
propagation_info);
attribute_filter);
}
}
});
@@ -324,15 +324,14 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry::ResampleCurvesOutputAttributeIDs resample_attributes;
resample_attributes.tangent_id = tangent_anonymous_id;
resample_attributes.normal_id = normal_anonymous_id;
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Points");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Points");
if (geometry_set.has_curves()) {
curve_to_points(geometry_set, params, mode, resample_attributes, rotation_anonymous_id);
}
if (geometry_set.has_grease_pencil()) {
grease_pencil_to_points(
geometry_set, params, mode, resample_attributes, rotation_anonymous_id, propagation_info);
geometry_set, params, mode, resample_attributes, rotation_anonymous_id, attribute_filter);
}
params.set_output("Points", std::move(geometry_set));

View File

@@ -121,7 +121,7 @@ static bool trim_curves(const bke::CurvesGeometry &src_curves,
Field<bool> &selection_field,
Field<float> &start_field,
Field<float> &end_field,
const AnonymousAttributePropagationInfo &propagation_info,
const AttributeFilter &attribute_filter,
bke::CurvesGeometry &dst_curves)
{
if (src_curves.curves_num() == 0) {
@@ -141,7 +141,7 @@ static bool trim_curves(const bke::CurvesGeometry &src_curves,
return false;
}
dst_curves = geometry::trim_curves(src_curves, selection, starts, ends, mode, propagation_info);
dst_curves = geometry::trim_curves(src_curves, selection, starts, ends, mode, attribute_filter);
return true;
}
@@ -150,7 +150,7 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set,
Field<bool> &selection_field,
Field<float> &start_field,
Field<float> &end_field,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
if (geometry_set.has_curves()) {
const Curves &src_curves_id = *geometry_set.get_curves();
@@ -163,7 +163,7 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set,
selection_field,
start_field,
end_field,
propagation_info,
attribute_filter,
dst_curves))
{
Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves));
@@ -189,7 +189,7 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set,
selection_field,
start_field,
end_field,
propagation_info,
attribute_filter,
dst_curves))
{
drawing->strokes_for_write() = std::move(dst_curves);
@@ -207,8 +207,7 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet geometry_set = params.extract_input<GeometrySet>("Curve");
GeometryComponentEditData::remember_deformed_positions_if_necessary(geometry_set);
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Curve");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Curve");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
if (mode == GEO_NODE_CURVE_SAMPLE_FACTOR) {
@@ -216,7 +215,7 @@ static void node_geo_exec(GeoNodeExecParams params)
Field<float> end_field = params.extract_input<Field<float>>("End");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
geometry_set_curve_trim(
geometry_set, mode, selection_field, start_field, end_field, propagation_info);
geometry_set, mode, selection_field, start_field, end_field, attribute_filter);
});
}
else if (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) {
@@ -224,7 +223,7 @@ static void node_geo_exec(GeoNodeExecParams params)
Field<float> end_field = params.extract_input<Field<float>>("End_001");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
geometry_set_curve_trim(
geometry_set, mode, selection_field, start_field, end_field, propagation_info);
geometry_set, mode, selection_field, start_field, end_field, attribute_filter);
});
}

View File

@@ -28,7 +28,7 @@ static GreasePencil *curves_to_grease_pencil_with_one_layer(
const Curves &curves_id,
const Field<bool> &selection_field,
const StringRefNull layer_name,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
bke::CurvesGeometry curves = curves_id.geometry.wrap();
@@ -39,7 +39,7 @@ static GreasePencil *curves_to_grease_pencil_with_one_layer(
const IndexMask curves_selection = evaluator.get_evaluated_selection_as_mask();
IndexMaskMemory memory;
const IndexMask curves_to_delete = curves_selection.complement(curves.curves_range(), memory);
curves.remove_curves(curves_to_delete, propagation_info);
curves.remove_curves(curves_to_delete, attribute_filter);
GreasePencil *grease_pencil = BKE_grease_pencil_new_nomain();
bke::greasepencil::Layer &layer = grease_pencil->add_layer(layer_name);
@@ -60,7 +60,7 @@ static GreasePencil *curves_to_grease_pencil_with_one_layer(
static GreasePencil *curve_instances_to_grease_pencil_layers(
const bke::Instances &instances,
const Field<bool> &selection_field,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const Span<int> reference_handles = instances.reference_handles();
const Span<bke::InstanceReference> references = instances.references();
@@ -139,9 +139,7 @@ static GreasePencil *curve_instances_to_grease_pencil_layers(
if (ELEM(attribute_id, "opacity")) {
return true;
}
if (bke::attribute_name_is_anonymous(attribute_id) &&
!propagation_info.propagate(attribute_id))
{
if (attribute_filter.allow_skip(attribute_id)) {
return true;
}
const GAttributeReader src_attribute = instances_attributes.lookup(attribute_id);
@@ -190,8 +188,7 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet curves_geometry = params.extract_input<GeometrySet>("Curves");
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
const bool instances_as_layers = params.extract_input<bool>("Instances as Layers");
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Grease Pencil");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Grease Pencil");
GreasePencil *grease_pencil = nullptr;
if (instances_as_layers) {
@@ -204,7 +201,7 @@ static void node_geo_exec(GeoNodeExecParams params)
return;
}
grease_pencil = curve_instances_to_grease_pencil_layers(
*instances, selection_field, propagation_info);
*instances, selection_field, attribute_filter);
}
else {
if (curves_geometry.has_instances()) {
@@ -216,7 +213,7 @@ static void node_geo_exec(GeoNodeExecParams params)
return;
}
grease_pencil = curves_to_grease_pencil_with_one_layer(
*curves_id, selection_field, curves_geometry.name, propagation_info);
*curves_id, selection_field, curves_geometry.name, attribute_filter);
}
GeometrySet grease_pencil_geometry = GeometrySet::from_grease_pencil(grease_pencil);

View File

@@ -64,19 +64,18 @@ static void node_geo_exec(GeoNodeExecParams params)
const AttrDomain domain = AttrDomain(storage.domain);
const GeometryNodeDeleteGeometryMode mode = (GeometryNodeDeleteGeometryMode)storage.mode;
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Geometry");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Geometry");
if (domain == AttrDomain::Instance) {
bool is_error;
geometry::separate_geometry(geometry_set, domain, mode, selection, propagation_info, is_error);
geometry::separate_geometry(geometry_set, domain, mode, selection, attribute_filter, is_error);
}
else {
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
bool is_error;
/* Invert here because we want to keep the things not in the selection. */
geometry::separate_geometry(
geometry_set, domain, mode, selection, propagation_info, is_error);
geometry_set, domain, mode, selection, attribute_filter, is_error);
});
}

View File

@@ -558,7 +558,7 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
geometry_set.gather_attributes_for_propagation({GeometryComponent::Type::Mesh},
GeometryComponent::Type::PointCloud,
false,
params.get_output_propagation_info("Points"),
params.get_attribute_filter("Points"),
attributes);
/* Position is set separately. */

View File

@@ -133,7 +133,7 @@ static void transfer_attributes(
const Span<int> new_to_old_edges_map,
const Span<int> new_to_old_face_corners_map,
const Span<std::pair<int, int>> boundary_vertex_to_relevant_face_map,
const AnonymousAttributePropagationInfo &propagation_info,
const AttributeFilter &attribute_filter,
const AttributeAccessor src_attributes,
MutableAttributeAccessor dst_attributes)
{
@@ -145,9 +145,7 @@ static void transfer_attributes(
attribute_ids.remove(".corner_vert");
attribute_ids.remove(".corner_edge");
attribute_ids.remove("sharp_face");
attribute_ids.remove_if([&](const StringRef id) {
return bke::attribute_name_is_anonymous(id) && !propagation_info.propagate(id);
});
attribute_ids.remove_if([&](const StringRef id) { return attribute_filter.allow_skip(id); });
for (const StringRef id : attribute_ids) {
GAttributeReader src = src_attributes.lookup(id);
@@ -615,7 +613,7 @@ static void dissolve_redundant_verts(const Span<int2> edges,
*/
static Mesh *calc_dual_mesh(const Mesh &src_mesh,
const bool keep_boundaries,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const Span<float3> src_positions = src_mesh.vert_positions();
const Span<int2> src_edges = src_mesh.edges();
@@ -898,7 +896,7 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh,
new_to_old_edges_map,
new_to_old_face_corners_map,
boundary_vertex_to_relevant_face_map,
propagation_info,
attribute_filter,
src_mesh.attributes(),
mesh_out->attributes_for_write());
@@ -923,7 +921,7 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (const Mesh *mesh = geometry_set.get_mesh()) {
Mesh *new_mesh = calc_dual_mesh(
*mesh, keep_boundaries, params.get_output_propagation_info("Dual Mesh"));
*mesh, keep_boundaries, params.get_attribute_filter("Dual Mesh"));
geometry::debug_randomize_mesh_order(new_mesh);
geometry_set.replace_mesh(new_mesh);
}

View File

@@ -156,21 +156,20 @@ static void copy_stable_id_point(const OffsetIndices<int> offsets,
* Copies the attributes for curve duplicates. If copying the curve domain, the attributes are
* copied with an offset fill, otherwise a mapping is used.
*/
static void copy_curve_attributes_without_id(
const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const OffsetIndices<int> curve_offsets,
const AnonymousAttributePropagationInfo &propagation_info,
bke::CurvesGeometry &dst_curves)
static void copy_curve_attributes_without_id(const bke::CurvesGeometry &src_curves,
const IndexMask &selection,
const OffsetIndices<int> curve_offsets,
const AttributeFilter &attribute_filter,
bke::CurvesGeometry &dst_curves)
{
const OffsetIndices src_points_by_curve = src_curves.points_by_curve();
const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve();
for (auto &attribute : bke::retrieve_attributes_for_transfer(src_curves.attributes(),
dst_curves.attributes_for_write(),
ATTR_DOMAIN_MASK_ALL,
propagation_info,
{"id"}))
for (auto &attribute : bke::retrieve_attributes_for_transfer(
src_curves.attributes(),
dst_curves.attributes_for_write(),
ATTR_DOMAIN_MASK_ALL,
bke::attribute_filter_with_skip_ref(attribute_filter, {"id"})))
{
switch (attribute.meta_data.domain) {
case AttrDomain::Curve:
@@ -244,7 +243,7 @@ static void duplicate_curves(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
if (!geometry_set.has_curves()) {
geometry_set.remove_geometry_during_modify();
@@ -310,7 +309,7 @@ static void duplicate_curves(GeometrySet &geometry_set,
all_dst_offsets.last() = dst_points_num;
copy_curve_attributes_without_id(curves, selection, curve_offsets, propagation_info, new_curves);
copy_curve_attributes_without_id(curves, selection, curve_offsets, attribute_filter, new_curves);
copy_stable_id_curves(curves, selection, curve_offsets, new_curves);
@@ -336,22 +335,21 @@ static void duplicate_curves(GeometrySet &geometry_set,
* Copies the attributes for face duplicates. If copying the face domain, the attributes are
* copied with an offset fill, otherwise a mapping is used.
*/
static void copy_face_attributes_without_id(
const Span<int> edge_mapping,
const Span<int> vert_mapping,
const Span<int> loop_mapping,
const OffsetIndices<int> offsets,
const IndexMask &selection,
const AnonymousAttributePropagationInfo &propagation_info,
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes)
static void copy_face_attributes_without_id(const Span<int> edge_mapping,
const Span<int> vert_mapping,
const Span<int> loop_mapping,
const OffsetIndices<int> offsets,
const IndexMask &selection,
const AttributeFilter &attribute_filter,
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes)
{
for (auto &attribute : bke::retrieve_attributes_for_transfer(
src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_ALL,
propagation_info,
{"id", ".corner_vert", ".corner_edge", ".edge_verts"}))
bke::attribute_filter_with_skip_ref(
attribute_filter, {"id", ".corner_vert", ".corner_edge", ".edge_verts"})))
{
switch (attribute.meta_data.domain) {
case AttrDomain::Point:
@@ -430,7 +428,7 @@ static void duplicate_faces(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
if (!geometry_set.has_mesh()) {
geometry_set.remove_geometry_during_modify();
@@ -509,7 +507,7 @@ static void duplicate_faces(GeometrySet &geometry_set,
loop_mapping,
duplicates,
selection,
propagation_info,
attribute_filter,
mesh.attributes(),
new_mesh->attributes_for_write());
@@ -541,20 +539,18 @@ static void duplicate_faces(GeometrySet &geometry_set,
* Copies the attributes for edge duplicates. If copying the edge domain, the attributes are
* copied with an offset fill, for point domain a mapping is used.
*/
static void copy_edge_attributes_without_id(
const Span<int> point_mapping,
const OffsetIndices<int> offsets,
const IndexMask &selection,
const AnonymousAttributePropagationInfo &propagation_info,
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes)
static void copy_edge_attributes_without_id(const Span<int> point_mapping,
const OffsetIndices<int> offsets,
const IndexMask &selection,
const AttributeFilter &attribute_filter,
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes)
{
for (auto &attribute :
bke::retrieve_attributes_for_transfer(src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_EDGE,
propagation_info,
{"id", ".edge_verts"}))
for (auto &attribute : bke::retrieve_attributes_for_transfer(
src_attributes,
dst_attributes,
ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_EDGE,
bke::attribute_filter_with_skip_ref(attribute_filter, {"id", ".edge_verts"})))
{
switch (attribute.meta_data.domain) {
case AttrDomain::Edge:
@@ -618,7 +614,7 @@ static void duplicate_edges(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
if (!geometry_set.has_mesh()) {
geometry_set.remove_geometry_during_modify();
@@ -670,7 +666,7 @@ static void duplicate_edges(GeometrySet &geometry_set,
copy_edge_attributes_without_id(vert_orig_indices,
duplicates,
selection,
propagation_info,
attribute_filter,
mesh.attributes(),
new_mesh->attributes_for_write());
@@ -700,7 +696,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const Curves &src_curves_id = *geometry_set.get_curves();
const bke::CurvesGeometry &src_curves = src_curves_id.geometry.wrap();
@@ -730,17 +726,16 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
bke::gather_attributes_to_groups(src_curves.attributes(),
AttrDomain::Point,
propagation_info,
{},
attribute_filter,
duplicates,
selection,
new_curves.attributes_for_write());
for (auto &attribute : bke::retrieve_attributes_for_transfer(src_curves.attributes(),
new_curves.attributes_for_write(),
ATTR_DOMAIN_MASK_CURVE,
propagation_info,
{"id"}))
for (auto &attribute : bke::retrieve_attributes_for_transfer(
src_curves.attributes(),
new_curves.attributes_for_write(),
ATTR_DOMAIN_MASK_CURVE,
bke::attribute_filter_with_skip_ref(attribute_filter, {"id"})))
{
bke::attribute_math::convert_to_static_type(attribute.src.type(), [&](auto dummy) {
using T = decltype(dummy);
@@ -777,7 +772,7 @@ static void duplicate_points_mesh(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const Mesh &mesh = *geometry_set.get_mesh();
@@ -797,8 +792,7 @@ static void duplicate_points_mesh(GeometrySet &geometry_set,
bke::gather_attributes_to_groups(mesh.attributes(),
AttrDomain::Point,
propagation_info,
{"id"},
bke::attribute_filter_with_skip_ref(attribute_filter, {"id"}),
duplicates,
selection,
new_mesh->attributes_for_write());
@@ -828,7 +822,7 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const PointCloud &src_points = *geometry_set.get_pointcloud();
@@ -848,8 +842,7 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set,
bke::gather_attributes_to_groups(src_points.attributes(),
AttrDomain::Point,
propagation_info,
{"id"},
bke::attribute_filter_with_skip_ref(attribute_filter, {"id"}),
duplicates,
selection,
pointcloud->attributes_for_write());
@@ -876,7 +869,7 @@ static void duplicate_points(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
Vector<GeometryComponent::Type> component_types = geometry_set.gather_component_types(true,
true);
@@ -885,19 +878,19 @@ static void duplicate_points(GeometrySet &geometry_set,
case GeometryComponent::Type::PointCloud:
if (geometry_set.has_pointcloud()) {
duplicate_points_pointcloud(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
geometry_set, count_field, selection_field, attribute_outputs, attribute_filter);
}
break;
case GeometryComponent::Type::Mesh:
if (geometry_set.has_mesh()) {
duplicate_points_mesh(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
geometry_set, count_field, selection_field, attribute_outputs, attribute_filter);
}
break;
case GeometryComponent::Type::Curve:
if (geometry_set.has_curves()) {
duplicate_points_curve(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
geometry_set, count_field, selection_field, attribute_outputs, attribute_filter);
}
break;
default:
@@ -918,7 +911,7 @@ static void duplicate_instances(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
const IndexAttributes &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
if (!geometry_set.has_instances()) {
geometry_set.clear();
@@ -957,13 +950,13 @@ static void duplicate_instances(GeometrySet &geometry_set,
dst_instances->reference_handles_for_write().slice(range).fill(new_handle);
}
bke::gather_attributes_to_groups(src_instances.attributes(),
AttrDomain::Instance,
propagation_info,
{"id", ".reference_index"},
duplicates,
selection,
dst_instances->attributes_for_write());
bke::gather_attributes_to_groups(
src_instances.attributes(),
AttrDomain::Instance,
bke::attribute_filter_with_skip_ref(attribute_filter, {"id", ".reference_index"}),
duplicates,
selection,
dst_instances->attributes_for_write());
if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(dst_instances->attributes_for_write(),
@@ -1001,31 +994,30 @@ static void node_geo_exec(GeoNodeExecParams params)
attribute_outputs.duplicate_index = params.get_output_anonymous_attribute_id_if_needed(
"Duplicate Index");
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Geometry");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Geometry");
if (duplicate_domain == AttrDomain::Instance) {
duplicate_instances(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
geometry_set, count_field, selection_field, attribute_outputs, attribute_filter);
}
else {
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
switch (duplicate_domain) {
case AttrDomain::Curve:
duplicate_curves(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
geometry_set, count_field, selection_field, attribute_outputs, attribute_filter);
break;
case AttrDomain::Face:
duplicate_faces(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
geometry_set, count_field, selection_field, attribute_outputs, attribute_filter);
break;
case AttrDomain::Edge:
duplicate_edges(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
geometry_set, count_field, selection_field, attribute_outputs, attribute_filter);
break;
case AttrDomain::Point:
duplicate_points(
geometry_set, count_field, selection_field, attribute_outputs, propagation_info);
geometry_set, count_field, selection_field, attribute_outputs, attribute_filter);
break;
default:
BLI_assert_unreachable();

View File

@@ -20,11 +20,10 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>("Curves").propagate_all();
}
static Curves *edge_paths_to_curves_convert(
const Mesh &mesh,
const IndexMask &start_verts_mask,
const Span<int> next_indices,
const AnonymousAttributePropagationInfo &propagation_info)
static Curves *edge_paths_to_curves_convert(const Mesh &mesh,
const IndexMask &start_verts_mask,
const Span<int> next_indices,
const AttributeFilter &attribute_filter)
{
Vector<int> vert_indices;
Vector<int> curve_offsets;
@@ -63,7 +62,7 @@ static Curves *edge_paths_to_curves_convert(
return nullptr;
}
Curves *curves_id = bke::curves_new_nomain(geometry::create_curve_from_vert_indices(
mesh.attributes(), vert_indices, curve_offsets, IndexRange(0), propagation_info));
mesh.attributes(), vert_indices, curve_offsets, IndexRange(0), attribute_filter));
return curves_id;
}
@@ -92,7 +91,7 @@ static void node_geo_exec(GeoNodeExecParams params)
}
geometry_set.replace_curves(edge_paths_to_curves_convert(
*mesh, start_verts, next_vert, params.get_output_propagation_info("Curves")));
*mesh, start_verts, next_vert, params.get_attribute_filter("Curves")));
geometry_set.keep_only({GeometryComponent::Type::Curve, GeometryComponent::Type::Instance});
});

View File

@@ -35,7 +35,7 @@ static void node_geo_exec(GeoNodeExecParams params)
}
geometry::split_edges(
*geometry_set.get_mesh_for_write(), mask, params.get_output_propagation_info("Mesh"));
*geometry_set.get_mesh_for_write(), mask, params.get_attribute_filter("Mesh"));
}
});

View File

@@ -88,22 +88,11 @@ static void save_selection_as_attribute(MutableAttributeAccessor attributes,
attribute.finish();
}
static void remove_non_propagated_attributes(
MutableAttributeAccessor attributes, const AnonymousAttributePropagationInfo &propagation_info)
static void remove_non_propagated_attributes(MutableAttributeAccessor attributes,
const AttributeFilter &attribute_filter)
{
if (propagation_info.propagate_all) {
return;
}
Set<StringRefNull> ids_to_remove = attributes.all_ids();
ids_to_remove.remove_if([&](const StringRef id) {
if (!bke::attribute_name_is_anonymous(id)) {
return true;
}
if (propagation_info.propagate(id)) {
return true;
}
return false;
});
ids_to_remove.remove_if([&](const StringRef id) { return !attribute_filter.allow_skip(id); });
for (const StringRef id : ids_to_remove) {
attributes.remove(id);
}
@@ -389,7 +378,7 @@ static void extrude_mesh_vertices(Mesh &mesh,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
const AttributeOutputs &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const int orig_vert_size = mesh.verts_num;
const int orig_edge_size = mesh.edges_num;
@@ -408,7 +397,7 @@ static void extrude_mesh_vertices(Mesh &mesh,
}
MutableAttributeAccessor attributes = mesh.attributes_for_write();
remove_non_propagated_attributes(attributes, propagation_info);
remove_non_propagated_attributes(attributes, attribute_filter);
const IDsByDomain ids_by_domain = attribute_ids_by_domain(attributes,
{"position", ".edge_verts"});
@@ -570,7 +559,7 @@ static void extrude_mesh_edges(Mesh &mesh,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
const AttributeOutputs &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const int orig_vert_size = mesh.verts_num;
const Span<int2> orig_edges = mesh.edges();
@@ -618,7 +607,7 @@ static void extrude_mesh_edges(Mesh &mesh,
const IndexRange new_loop_range{orig_loop_size, new_face_range.size() * 4};
MutableAttributeAccessor attributes = mesh.attributes_for_write();
remove_non_propagated_attributes(attributes, propagation_info);
remove_non_propagated_attributes(attributes, attribute_filter);
Array<int> edge_to_face_offsets;
Array<int> edge_to_face_indices;
@@ -851,7 +840,7 @@ static void extrude_mesh_face_regions(Mesh &mesh,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
const AttributeOutputs &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const int orig_vert_size = mesh.verts_num;
const Span<int2> orig_edges = mesh.edges();
@@ -973,7 +962,7 @@ static void extrude_mesh_face_regions(Mesh &mesh,
const IndexRange side_loop_range{orig_corner_verts.size(), side_face_range.size() * 4};
MutableAttributeAccessor attributes = mesh.attributes_for_write();
remove_non_propagated_attributes(attributes, propagation_info);
remove_non_propagated_attributes(attributes, attribute_filter);
remove_unsupported_vert_data(mesh);
remove_unsupported_edge_data(mesh);
@@ -1225,12 +1214,11 @@ static void extrude_mesh_face_regions(Mesh &mesh,
tag_mesh_added_faces(mesh);
}
static void extrude_individual_mesh_faces(
Mesh &mesh,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
const AttributeOutputs &attribute_outputs,
const AnonymousAttributePropagationInfo &propagation_info)
static void extrude_individual_mesh_faces(Mesh &mesh,
const Field<bool> &selection_field,
const Field<float3> &offset_field,
const AttributeOutputs &attribute_outputs,
const AttributeFilter &attribute_filter)
{
const int orig_vert_size = mesh.verts_num;
const int orig_edge_size = mesh.edges_num;
@@ -1269,7 +1257,7 @@ static void extrude_individual_mesh_faces(
const IndexRange side_loop_range{orig_loop_size, side_face_range.size() * 4};
MutableAttributeAccessor attributes = mesh.attributes_for_write();
remove_non_propagated_attributes(attributes, propagation_info);
remove_non_propagated_attributes(attributes, attribute_filter);
remove_unsupported_vert_data(mesh);
remove_unsupported_edge_data(mesh);
@@ -1498,8 +1486,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const bool extrude_individual = mode == GEO_NODE_EXTRUDE_MESH_FACES &&
params.extract_input<bool>("Individual");
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Mesh");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Mesh");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (Mesh *mesh = geometry_set.get_mesh_for_write()) {
@@ -1507,19 +1494,19 @@ static void node_geo_exec(GeoNodeExecParams params)
switch (mode) {
case GEO_NODE_EXTRUDE_MESH_VERTICES:
extrude_mesh_vertices(
*mesh, selection, final_offset, attribute_outputs, propagation_info);
*mesh, selection, final_offset, attribute_outputs, attribute_filter);
break;
case GEO_NODE_EXTRUDE_MESH_EDGES:
extrude_mesh_edges(*mesh, selection, final_offset, attribute_outputs, propagation_info);
extrude_mesh_edges(*mesh, selection, final_offset, attribute_outputs, attribute_filter);
break;
case GEO_NODE_EXTRUDE_MESH_FACES: {
if (extrude_individual) {
extrude_individual_mesh_faces(
*mesh, selection, final_offset, attribute_outputs, propagation_info);
*mesh, selection, final_offset, attribute_outputs, attribute_filter);
}
else {
extrude_mesh_face_regions(
*mesh, selection, final_offset, attribute_outputs, propagation_info);
*mesh, selection, final_offset, attribute_outputs, attribute_filter);
}
break;
}

View File

@@ -129,7 +129,8 @@ static void node_geo_exec(GeoNodeExecParams params)
const bool layers_as_instances = params.get_input<bool>("Layers as Instances");
if (!layers_as_instances) {
geometry::RealizeInstancesOptions options;
options.propagation_info = params.get_output_propagation_info("Curves");
const NodeAttributeFilter attribute_filter = params.get_attribute_filter("Curves");
options.attribute_filter = attribute_filter;
curves_geometry = geometry::realize_instances(curves_geometry, options);
}

View File

@@ -184,8 +184,7 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet geometry_set = params.extract_input<GeometrySet>("Points");
GeometrySet instance = params.get_input<GeometrySet>("Instance");
instance.ensure_owns_direct_data();
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Instances");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Instances");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
/* It's important not to invalidate the existing #InstancesComponent because it owns references
@@ -206,7 +205,7 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.gather_attributes_for_propagation(types,
GeometryComponent::Type::Instance,
false,
propagation_info,
attribute_filter,
attributes_to_propagate);
attributes_to_propagate.remove("position");
attributes_to_propagate.remove(".reference_index");
@@ -258,7 +257,7 @@ static void node_geo_exec(GeoNodeExecParams params)
GeometrySet::propagate_attributes_from_layer_to_instances(
geometry_set.get_grease_pencil()->attributes(),
geometry_set.get_instances_for_write()->attributes_for_write(),
propagation_info);
attribute_filter);
}
geometry_set.replace_grease_pencil(nullptr);
}

View File

@@ -31,7 +31,7 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
Field<float3> position_field,
Field<float> radius_field,
Field<bool> selection_field,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const bke::Instances &instances = *geometry_set.get_instances();
@@ -63,7 +63,7 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
geometry_set.gather_attributes_for_propagation({GeometryComponent::Type::Instance},
GeometryComponent::Type::PointCloud,
false,
propagation_info,
attribute_filter,
attributes_to_propagate);
/* These two attributes are added by the implicit inputs above. */
attributes_to_propagate.remove("position");
@@ -98,7 +98,7 @@ static void node_geo_exec(GeoNodeExecParams params)
params.extract_input<Field<float3>>("Position"),
params.extract_input<Field<float>>("Radius"),
params.extract_input<Field<bool>>("Selection"),
params.get_output_propagation_info("Points"));
params.get_attribute_filter("Points"));
geometry_set.keep_only({GeometryComponent::Type::PointCloud, GeometryComponent::Type::Edit});
params.set_output("Points", std::move(geometry_set));
}

View File

@@ -444,7 +444,7 @@ static void interpolate_curve_shapes(bke::CurvesGeometry &child_curves,
static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves,
const bke::CurvesGeometry &guide_curves,
const AttributeAccessor &point_attributes,
const AnonymousAttributePropagationInfo &propagation_info,
const AttributeFilter &attribute_filter,
const int max_neighbors,
const Span<int> all_neighbor_indices,
const Span<float> all_neighbor_weights,
@@ -462,7 +462,7 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves,
/* Interpolate attributes from guide curves to child curves. Attributes stay on the same domain
* that they had on the guides. */
guide_curve_attributes.for_all([&](const StringRef id, const AttributeMetaData &meta_data) {
if (bke::attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
const eCustomDataType type = meta_data.data_type;
@@ -601,7 +601,7 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves,
if (guide_curve_attributes.contains(id)) {
return true;
}
if (bke::attribute_name_is_anonymous(id) && !propagation_info.propagate(id)) {
if (attribute_filter.allow_skip(id)) {
return true;
}
if (meta_data.data_type == CD_PROP_STRING) {
@@ -687,7 +687,7 @@ static GeometrySet generate_interpolated_curves(
const VArray<int> &guide_group_ids,
const VArray<int> &point_group_ids,
const int max_neighbors,
const AnonymousAttributePropagationInfo &propagation_info,
const AttributeFilter &attribute_filter,
const std::optional<StringRef> &index_attribute_id,
const std::optional<StringRef> &weight_attribute_id)
{
@@ -761,7 +761,7 @@ static GeometrySet generate_interpolated_curves(
interpolate_curve_attributes(child_curves,
guide_curves,
point_attributes,
propagation_info,
attribute_filter,
max_neighbors,
all_neighbor_indices,
all_neighbor_weights,
@@ -843,8 +843,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const VArray<float3> points_up = points_evaluator.get_evaluated<float3>(0);
const VArray<int> point_group_ids = points_evaluator.get_evaluated<int>(1);
const AnonymousAttributePropagationInfo propagation_info = params.get_output_propagation_info(
"Curves");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Curves");
std::optional<std::string> index_attribute_id =
params.get_output_anonymous_attribute_id_if_needed("Closest Index");
@@ -858,7 +857,7 @@ static void node_geo_exec(GeoNodeExecParams params)
guide_group_ids,
point_group_ids,
max_neighbors,
propagation_info,
attribute_filter,
index_attribute_id,
weight_attribute_id);

View File

@@ -18,14 +18,13 @@ static void node_geo_exec(GeoNodeExecParams params)
{
Vector<GeometrySet> geometry_sets = params.extract_input<Vector<GeometrySet>>("Geometry");
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Geometry");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Geometry");
for (GeometrySet &geometry : geometry_sets) {
GeometryComponentEditData::remember_deformed_positions_if_necessary(geometry);
}
GeometrySet geometry_set_result = geometry::join_geometries(geometry_sets, propagation_info);
GeometrySet geometry_set_result = geometry::join_geometries(geometry_sets, attribute_filter);
params.set_output("Geometry", std::move(geometry_set_result));
}

View File

@@ -42,11 +42,10 @@ static void node_init(bNodeTree * /*tree*/, bNode *node)
node->storage = data;
}
static PointCloud *pointcloud_merge_by_distance(
const PointCloud &src_points,
const float merge_distance,
const Field<bool> &selection_field,
const AnonymousAttributePropagationInfo &propagation_info)
static PointCloud *pointcloud_merge_by_distance(const PointCloud &src_points,
const float merge_distance,
const Field<bool> &selection_field,
const AttributeFilter &attribute_filter)
{
const bke::PointCloudFieldContext context{src_points};
FieldEvaluator evaluator{context, src_points.totpoint};
@@ -59,7 +58,7 @@ static PointCloud *pointcloud_merge_by_distance(
}
return geometry::point_merge_by_distance(
src_points, merge_distance, selection, propagation_info);
src_points, merge_distance, selection, attribute_filter);
}
static std::optional<Mesh *> mesh_merge_by_distance_connected(const Mesh &mesh,
@@ -105,7 +104,7 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
if (const PointCloud *pointcloud = geometry_set.get_pointcloud()) {
PointCloud *result = pointcloud_merge_by_distance(
*pointcloud, merge_distance, selection, params.get_output_propagation_info("Geometry"));
*pointcloud, merge_distance, selection, params.get_attribute_filter("Geometry"));
if (result) {
geometry_set.replace_pointcloud(result);
}

View File

@@ -39,7 +39,7 @@ static void node_geo_exec(GeoNodeExecParams params)
}
bke::CurvesGeometry curves = geometry::mesh_to_curve_convert(
*mesh, selection, params.get_output_propagation_info("Curve"));
*mesh, selection, params.get_attribute_filter("Curve"));
geometry_set.replace_curves(bke::curves_new_nomain(std::move(curves)));
geometry_set.keep_only_during_modify({GeometryComponent::Type::Curve});
});

View File

@@ -53,7 +53,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
const Field<float> &radius_field,
const Field<bool> &selection_field,
const AttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const Mesh *mesh = geometry_set.get_mesh();
if (mesh == nullptr) {
@@ -109,7 +109,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
geometry_set.gather_attributes_for_propagation({GeometryComponent::Type::Mesh},
GeometryComponent::Type::PointCloud,
false,
propagation_info,
attribute_filter,
attributes);
attributes.remove("radius");
attributes.remove("position");
@@ -158,8 +158,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const NodeGeometryMeshToPoints &storage = node_storage(params.node());
const GeometryNodeMeshToPointsMode mode = (GeometryNodeMeshToPointsMode)storage.mode;
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Points");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Points");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
switch (mode) {
@@ -169,7 +168,7 @@ static void node_geo_exec(GeoNodeExecParams params)
positive_radius,
selection,
AttrDomain::Point,
propagation_info);
attribute_filter);
break;
case GEO_NODE_MESH_TO_POINTS_EDGES:
geometry_set_mesh_to_points(geometry_set,
@@ -177,7 +176,7 @@ static void node_geo_exec(GeoNodeExecParams params)
positive_radius,
selection,
AttrDomain::Edge,
propagation_info);
attribute_filter);
break;
case GEO_NODE_MESH_TO_POINTS_FACES:
geometry_set_mesh_to_points(geometry_set,
@@ -185,7 +184,7 @@ static void node_geo_exec(GeoNodeExecParams params)
positive_radius,
selection,
AttrDomain::Face,
propagation_info);
attribute_filter);
break;
case GEO_NODE_MESH_TO_POINTS_CORNERS:
geometry_set_mesh_to_points(geometry_set,
@@ -193,7 +192,7 @@ static void node_geo_exec(GeoNodeExecParams params)
positive_radius,
selection,
AttrDomain::Corner,
propagation_info);
attribute_filter);
break;
}
});

View File

@@ -88,14 +88,14 @@ static int identifiers_to_indices(MutableSpan<int> r_identifiers_to_indices)
static Curves *curve_from_points(const AttributeAccessor attributes,
const VArray<float> &weights_varray,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const int domain_size = weights_varray.size();
Curves *curves_id = bke::curves_new_nomain_single(domain_size, CURVE_TYPE_POLY);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
if (weights_varray.is_single()) {
bke::copy_attributes(
attributes, AttrDomain::Point, propagation_info, {}, curves.attributes_for_write());
attributes, AttrDomain::Point, attribute_filter, curves.attributes_for_write());
return curves_id;
}
Array<int> indices(domain_size);
@@ -103,14 +103,14 @@ static Curves *curve_from_points(const AttributeAccessor attributes,
const VArraySpan<float> weights(weights_varray);
grouped_sort(OffsetIndices<int>({0, domain_size}), weights, indices);
bke::gather_attributes(
attributes, AttrDomain::Point, propagation_info, {}, indices, curves.attributes_for_write());
attributes, AttrDomain::Point, attribute_filter, indices, curves.attributes_for_write());
return curves_id;
}
static Curves *curves_from_points(const PointCloud &points,
const Field<int> &group_id_field,
const Field<float> &weight_field,
const bke::AnonymousAttributePropagationInfo &propagation_info)
const AttributeFilter &attribute_filter)
{
const int domain_size = points.totpoint;
if (domain_size == 0) {
@@ -127,14 +127,14 @@ static Curves *curves_from_points(const PointCloud &points,
const VArray<float> weights_varray = evaluator.get_evaluated<float>(1);
if (group_ids_varray.is_single()) {
return curve_from_points(points.attributes(), weights_varray, propagation_info);
return curve_from_points(points.attributes(), weights_varray, attribute_filter);
}
Array<int> group_ids(domain_size);
group_ids_varray.materialize(group_ids.as_mutable_span());
const int total_curves = identifiers_to_indices(group_ids);
if (total_curves == 1) {
return curve_from_points(points.attributes(), weights_varray, propagation_info);
return curve_from_points(points.attributes(), weights_varray, attribute_filter);
}
Curves *curves_id = bke::curves_new_nomain(domain_size, total_curves);
@@ -152,8 +152,7 @@ static Curves *curves_from_points(const PointCloud &points,
}
bke::gather_attributes(points.attributes(),
AttrDomain::Point,
propagation_info,
{},
attribute_filter,
indices,
curves.attributes_for_write());
@@ -167,13 +166,12 @@ static void node_geo_exec(GeoNodeExecParams params)
const Field<int> group_id_field = params.extract_input<Field<int>>("Curve Group ID");
const Field<float> weight_field = params.extract_input<Field<float>>("Weight");
const bke::AnonymousAttributePropagationInfo propagation_info =
params.get_output_propagation_info("Curves");
const NodeAttributeFilter attribute_filter = params.get_attribute_filter("Curves");
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
geometry_set.replace_curves(nullptr);
if (const PointCloud *points = geometry_set.get_pointcloud()) {
Curves *curves_id = curves_from_points(
*points, group_id_field, weight_field, propagation_info);
*points, group_id_field, weight_field, attribute_filter);
geometry_set.replace_curves(curves_id);
}
geometry_set.keep_only_during_modify({GeometryComponent::Type::Curve});

View File

@@ -21,10 +21,9 @@ static void node_declare(NodeDeclarationBuilder &b)
}
/* One improvement would be to move the attribute arrays directly to the mesh when possible. */
static void geometry_set_points_to_vertices(
GeometrySet &geometry_set,
Field<bool> &selection_field,
const AnonymousAttributePropagationInfo &propagation_info)
static void geometry_set_points_to_vertices(GeometrySet &geometry_set,
Field<bool> &selection_field,
const AttributeFilter &attribute_filter)
{
const PointCloud *points = geometry_set.get_pointcloud();
if (points == nullptr) {
@@ -46,7 +45,7 @@ static void geometry_set_points_to_vertices(
geometry_set.gather_attributes_for_propagation({GeometryComponent::Type::PointCloud},
GeometryComponent::Type::Mesh,
false,
propagation_info,
attribute_filter,
attributes);
Mesh *mesh;
@@ -94,7 +93,7 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
geometry_set_points_to_vertices(
geometry_set, selection_field, params.get_output_propagation_info("Mesh"));
geometry_set, selection_field, params.get_attribute_filter("Mesh"));
});
params.set_output("Mesh", std::move(geometry_set));

View File

@@ -76,7 +76,8 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry::RealizeInstancesOptions options;
options.keep_original_ids = false;
options.realize_instance_attributes = true;
options.propagation_info = params.get_output_propagation_info("Geometry");
const NodeAttributeFilter attribute_filter = params.get_attribute_filter("Geometry");
options.attribute_filter = attribute_filter;
GeometrySet new_geometry_set = geometry::realize_instances(
geometry_set, options, varied_depth_option);
new_geometry_set.name = geometry_set.name;

View File

@@ -54,42 +54,41 @@ static void node_geo_exec(GeoNodeExecParams params)
const NodeGeometrySeparateGeometry &storage = node_storage(params.node());
const AttrDomain domain = AttrDomain(storage.domain);
auto separate_geometry_maybe_recursively =
[&](GeometrySet &geometry_set,
const Field<bool> &selection,
const AnonymousAttributePropagationInfo &propagation_info) {
bool is_error;
if (domain == AttrDomain::Instance) {
/* Only delete top level instances. */
geometry::separate_geometry(geometry_set,
domain,
GEO_NODE_DELETE_GEOMETRY_MODE_ALL,
selection,
propagation_info,
is_error);
}
else {
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
geometry::separate_geometry(geometry_set,
domain,
GEO_NODE_DELETE_GEOMETRY_MODE_ALL,
selection,
propagation_info,
is_error);
});
}
};
auto separate_geometry_maybe_recursively = [&](GeometrySet &geometry_set,
const Field<bool> &selection,
const AttributeFilter &attribute_filter) {
bool is_error;
if (domain == AttrDomain::Instance) {
/* Only delete top level instances. */
geometry::separate_geometry(geometry_set,
domain,
GEO_NODE_DELETE_GEOMETRY_MODE_ALL,
selection,
attribute_filter,
is_error);
}
else {
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
geometry::separate_geometry(geometry_set,
domain,
GEO_NODE_DELETE_GEOMETRY_MODE_ALL,
selection,
attribute_filter,
is_error);
});
}
};
GeometrySet second_set(geometry_set);
if (params.output_is_required("Selection")) {
separate_geometry_maybe_recursively(
geometry_set, selection_field, params.get_output_propagation_info("Selection"));
geometry_set, selection_field, params.get_attribute_filter("Selection"));
params.set_output("Selection", std::move(geometry_set));
}
if (params.output_is_required("Inverted")) {
separate_geometry_maybe_recursively(second_set,
fn::invert_boolean_field(selection_field),
params.get_output_propagation_info("Inverted"));
params.get_attribute_filter("Inverted"));
params.set_output("Inverted", std::move(second_set));
}
}

View File

@@ -199,8 +199,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const Field<float> weight_field = params.extract_input<Field<float>>("Sort Weight");
const bke::AttrDomain domain = bke::AttrDomain(params.node().custom1);
const bke::AnonymousAttributePropagationInfo propagation_info =
params.get_output_propagation_info("Geometry");
const NodeAttributeFilter attribute_filter = params.get_attribute_filter("Geometry");
GeometryComponentEditData::remember_deformed_positions_if_necessary(geometry_set);
@@ -216,7 +215,7 @@ static void node_geo_exec(GeoNodeExecParams params)
weight_field))
{
bke::Instances *result = geometry::reorder_instaces(
*instances, *indices, propagation_info);
*instances, *indices, attribute_filter);
geometry_set.replace_instances(result);
has_reorder = true;
}
@@ -244,7 +243,7 @@ static void node_geo_exec(GeoNodeExecParams params)
continue;
}
bke::GeometryComponentPtr dst_component = geometry::reordered_component(
*src_component, *indices, domain, propagation_info);
*src_component, *indices, domain, attribute_filter);
geometry_set.remove(type);
geometry_set.add(*dst_component.get());
}

View File

@@ -101,7 +101,7 @@ static void split_mesh_groups(const MeshComponent &component,
const AttrDomain domain,
const Field<bool> &selection_field,
const Field<int> &group_id_field,
const AnonymousAttributePropagationInfo &propagation_info,
const AttributeFilter &attribute_filter,
Map<int, std::unique_ptr<GeometrySet>> &geometry_by_group_id)
{
SplitGroups split_groups;
@@ -129,7 +129,7 @@ static void split_mesh_groups(const MeshComponent &component,
/* Using #mesh_copy_selection here is not ideal, because it can lead to O(n^2) behavior
* when there are many groups. */
std::optional<Mesh *> group_mesh_opt = geometry::mesh_copy_selection(
src_mesh, group_selection_varray, domain, propagation_info);
src_mesh, group_selection_varray, domain, attribute_filter);
GeometrySet &group_geometry = *geometry_by_group_id.lookup(group_id);
if (group_mesh_opt.has_value()) {
if (Mesh *group_mesh = *group_mesh_opt) {
@@ -152,7 +152,7 @@ static void split_mesh_groups(const MeshComponent &component,
static void split_pointcloud_groups(const PointCloudComponent &component,
const Field<bool> &selection_field,
const Field<int> &group_id_field,
const AnonymousAttributePropagationInfo &propagation_info,
const AttributeFilter &attribute_filter,
Map<int, std::unique_ptr<GeometrySet>> &geometry_by_group_id)
{
SplitGroups split_groups;
@@ -176,7 +176,7 @@ static void split_pointcloud_groups(const PointCloudComponent &component,
const AttributeAccessor src_attributes = src_pointcloud.attributes();
MutableAttributeAccessor dst_attributes = group_pointcloud->attributes_for_write();
bke::gather_attributes(
src_attributes, AttrDomain::Point, propagation_info, {}, mask, dst_attributes);
src_attributes, AttrDomain::Point, attribute_filter, mask, dst_attributes);
GeometrySet &group_geometry = *geometry_by_group_id.lookup(group_id);
group_geometry.replace_pointcloud(group_pointcloud);
@@ -188,7 +188,7 @@ static void split_curve_groups(const bke::CurveComponent &component,
const AttrDomain domain,
const Field<bool> &selection_field,
const Field<int> &group_id_field,
const AnonymousAttributePropagationInfo &propagation_info,
const AttributeFilter &attribute_filter,
Map<int, std::unique_ptr<GeometrySet>> &geometry_by_group_id)
{
SplitGroups split_groups;
@@ -205,10 +205,10 @@ static void split_curve_groups(const bke::CurveComponent &component,
bke::CurvesGeometry group_curves;
if (domain == AttrDomain::Point) {
group_curves = bke::curves_copy_point_selection(src_curves, mask, propagation_info);
group_curves = bke::curves_copy_point_selection(src_curves, mask, attribute_filter);
}
else {
group_curves = bke::curves_copy_curve_selection(src_curves, mask, propagation_info);
group_curves = bke::curves_copy_curve_selection(src_curves, mask, attribute_filter);
}
Curves *group_curves_id = bke::curves_new_nomain(std::move(group_curves));
GeometrySet &group_geometry = *geometry_by_group_id.lookup(group_id);
@@ -220,7 +220,7 @@ static void split_curve_groups(const bke::CurveComponent &component,
static void split_instance_groups(const InstancesComponent &component,
const Field<bool> &selection_field,
const Field<int> &group_id_field,
const AnonymousAttributePropagationInfo &propagation_info,
const AttributeFilter &attribute_filter,
Map<int, std::unique_ptr<GeometrySet>> &geometry_by_group_id)
{
SplitGroups split_groups;
@@ -248,8 +248,7 @@ static void split_instance_groups(const InstancesComponent &component,
bke::gather_attributes(src_instances.attributes(),
AttrDomain::Instance,
propagation_info,
{},
attribute_filter,
mask,
group_instances->attributes_for_write());
group_instances->remove_unused_references();
@@ -269,8 +268,7 @@ static void node_geo_exec(GeoNodeExecParams params)
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
const Field<int> group_id_field = params.extract_input<Field<int>>("Group ID");
const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info(
"Instances");
const NodeAttributeFilter &attribute_filter = params.get_attribute_filter("Instances");
Map<int, std::unique_ptr<GeometrySet>> geometry_by_group_id;
@@ -282,13 +280,13 @@ static void node_geo_exec(GeoNodeExecParams params)
domain,
selection_field,
group_id_field,
propagation_info,
attribute_filter,
geometry_by_group_id);
}
if (src_geometry.has_pointcloud() && domain == AttrDomain::Point) {
const auto &component = *src_geometry.get_component<PointCloudComponent>();
split_pointcloud_groups(
component, selection_field, group_id_field, propagation_info, geometry_by_group_id);
component, selection_field, group_id_field, attribute_filter, geometry_by_group_id);
}
if (src_geometry.has_curves() && ELEM(domain, AttrDomain::Point, AttrDomain::Curve)) {
const auto &component = *src_geometry.get_component<bke::CurveComponent>();
@@ -296,13 +294,13 @@ static void node_geo_exec(GeoNodeExecParams params)
domain,
selection_field,
group_id_field,
propagation_info,
attribute_filter,
geometry_by_group_id);
}
if (src_geometry.has_instances() && domain == AttrDomain::Instance) {
const auto &component = *src_geometry.get_component<bke::InstancesComponent>();
split_instance_groups(
component, selection_field, group_id_field, propagation_info, geometry_by_group_id);
component, selection_field, group_id_field, attribute_filter, geometry_by_group_id);
}
bke::Instances *dst_instances = new bke::Instances();

View File

@@ -243,4 +243,18 @@ void GeoNodeExecParams::check_output_access(StringRef identifier, const CPPType
}
}
AttributeFilter::Result NodeAttributeFilter::filter(const StringRef attribute_name) const
{
if (!bke::attribute_name_is_anonymous(attribute_name)) {
return AttributeFilter::Result::Process;
}
if (!set_.names) {
return AttributeFilter::Result::AllowSkip;
}
if (set_.names->contains(attribute_name)) {
return AttributeFilter::Result::Process;
}
return AttributeFilter::Result::AllowSkip;
}
} // namespace blender::nodes