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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
52
source/blender/blenkernel/BKE_attribute_filter.hh
Normal file
52
source/blender/blenkernel/BKE_attribute_filter.hh
Normal 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
|
||||
83
source/blender/blenkernel/BKE_attribute_filters.hh
Normal file
83
source/blender/blenkernel/BKE_attribute_filters.hh
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -25,7 +25,7 @@ struct RealizeInstancesOptions {
|
||||
*/
|
||||
bool realize_instance_attributes = true;
|
||||
|
||||
bke::AnonymousAttributePropagationInfo propagation_info;
|
||||
bke::AttributeFilter attribute_filter = {};
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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});
|
||||
});
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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});
|
||||
});
|
||||
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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});
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user