Cleanup: move some geometry field inputs to more correct header
This commit is contained in:
parent
c9ad858d9d
commit
7042db684f
|
@ -422,6 +422,47 @@ class CurveLengthFieldInput final : public CurvesFieldInput {
|
|||
std::optional<AttrDomain> preferred_domain(const bke::CurvesGeometry &curves) const final;
|
||||
};
|
||||
|
||||
class EvaluateAtIndexInput final : public bke::GeometryFieldInput {
|
||||
private:
|
||||
fn::Field<int> index_field_;
|
||||
fn::GField value_field_;
|
||||
AttrDomain value_field_domain_;
|
||||
|
||||
public:
|
||||
EvaluateAtIndexInput(fn::Field<int> index_field,
|
||||
fn::GField value_field,
|
||||
AttrDomain value_field_domain);
|
||||
|
||||
GVArray get_varray_for_context(const bke::GeometryFieldContext &context,
|
||||
const IndexMask &mask) const final;
|
||||
|
||||
std::optional<AttrDomain> preferred_domain(const GeometryComponent & /*component*/) const final
|
||||
{
|
||||
return value_field_domain_;
|
||||
}
|
||||
};
|
||||
|
||||
void copy_with_checked_indices(const GVArray &src,
|
||||
const VArray<int> &indices,
|
||||
const IndexMask &mask,
|
||||
GMutableSpan dst);
|
||||
|
||||
class EvaluateOnDomainInput final : public bke::GeometryFieldInput {
|
||||
private:
|
||||
fn::GField src_field_;
|
||||
AttrDomain src_domain_;
|
||||
|
||||
public:
|
||||
EvaluateOnDomainInput(fn::GField field, AttrDomain domain);
|
||||
|
||||
GVArray get_varray_for_context(const bke::GeometryFieldContext &context,
|
||||
const IndexMask & /*mask*/) const final;
|
||||
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const override;
|
||||
|
||||
std::optional<AttrDomain> preferred_domain(
|
||||
const GeometryComponent & /*component*/) const override;
|
||||
};
|
||||
|
||||
bool try_capture_field_on_geometry(MutableAttributeAccessor attributes,
|
||||
const fn::FieldContext &field_context,
|
||||
const AttributeIDRef &attribute_id,
|
||||
|
|
|
@ -594,6 +594,132 @@ std::optional<AttrDomain> NamedLayerSelectionFieldInput::preferred_domain(
|
|||
return AttrDomain::Layer;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void copy_with_checked_indices(const VArray<T> &src,
|
||||
const VArray<int> &indices,
|
||||
const IndexMask &mask,
|
||||
MutableSpan<T> dst)
|
||||
{
|
||||
const IndexRange src_range = src.index_range();
|
||||
devirtualize_varray2(src, indices, [&](const auto src, const auto indices) {
|
||||
mask.foreach_index(GrainSize(4096), [&](const int i) {
|
||||
const int index = indices[i];
|
||||
if (src_range.contains(index)) {
|
||||
dst[i] = src[index];
|
||||
}
|
||||
else {
|
||||
dst[i] = {};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void copy_with_checked_indices(const GVArray &src,
|
||||
const VArray<int> &indices,
|
||||
const IndexMask &mask,
|
||||
GMutableSpan dst)
|
||||
{
|
||||
bke::attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
|
||||
using T = decltype(dummy);
|
||||
copy_with_checked_indices(src.typed<T>(), indices, mask, dst.typed<T>());
|
||||
});
|
||||
}
|
||||
|
||||
EvaluateAtIndexInput::EvaluateAtIndexInput(fn::Field<int> index_field,
|
||||
fn::GField value_field,
|
||||
AttrDomain value_field_domain)
|
||||
: bke::GeometryFieldInput(value_field.cpp_type(), "Evaluate at Index"),
|
||||
index_field_(std::move(index_field)),
|
||||
value_field_(std::move(value_field)),
|
||||
value_field_domain_(value_field_domain)
|
||||
{
|
||||
}
|
||||
|
||||
GVArray EvaluateAtIndexInput::get_varray_for_context(const bke::GeometryFieldContext &context,
|
||||
const IndexMask &mask) const
|
||||
{
|
||||
const std::optional<AttributeAccessor> attributes = context.attributes();
|
||||
if (!attributes) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const bke::GeometryFieldContext value_context{context, value_field_domain_};
|
||||
fn::FieldEvaluator value_evaluator{value_context, attributes->domain_size(value_field_domain_)};
|
||||
value_evaluator.add(value_field_);
|
||||
value_evaluator.evaluate();
|
||||
const GVArray &values = value_evaluator.get_evaluated(0);
|
||||
|
||||
fn::FieldEvaluator index_evaluator{context, &mask};
|
||||
index_evaluator.add(index_field_);
|
||||
index_evaluator.evaluate();
|
||||
const VArray<int> indices = index_evaluator.get_evaluated<int>(0);
|
||||
|
||||
GArray<> dst_array(values.type(), mask.min_array_size());
|
||||
copy_with_checked_indices(values, indices, mask, dst_array);
|
||||
return GVArray::ForGArray(std::move(dst_array));
|
||||
}
|
||||
|
||||
EvaluateOnDomainInput::EvaluateOnDomainInput(fn::GField field, AttrDomain domain)
|
||||
: bke::GeometryFieldInput(field.cpp_type(), "Evaluate on Domain"),
|
||||
src_field_(std::move(field)),
|
||||
src_domain_(domain)
|
||||
{
|
||||
}
|
||||
|
||||
GVArray EvaluateOnDomainInput::get_varray_for_context(const bke::GeometryFieldContext &context,
|
||||
const IndexMask & /*mask*/) const
|
||||
{
|
||||
const AttrDomain dst_domain = context.domain();
|
||||
const int dst_domain_size = context.attributes()->domain_size(dst_domain);
|
||||
const CPPType &cpp_type = src_field_.cpp_type();
|
||||
|
||||
if (context.type() == GeometryComponent::Type::GreasePencil &&
|
||||
(src_domain_ == AttrDomain::Layer) != (dst_domain == AttrDomain::Layer))
|
||||
{
|
||||
/* Evaluate field just for the current layer. */
|
||||
if (src_domain_ == AttrDomain::Layer) {
|
||||
const bke::GeometryFieldContext src_domain_context{context, AttrDomain::Layer};
|
||||
const int layer_index = context.grease_pencil_layer_index();
|
||||
|
||||
const IndexMask single_layer_mask = IndexRange(layer_index, 1);
|
||||
fn::FieldEvaluator value_evaluator{src_domain_context, &single_layer_mask};
|
||||
value_evaluator.add(src_field_);
|
||||
value_evaluator.evaluate();
|
||||
|
||||
const GVArray &values = value_evaluator.get_evaluated(0);
|
||||
|
||||
BUFFER_FOR_CPP_TYPE_VALUE(cpp_type, value);
|
||||
BLI_SCOPED_DEFER([&]() { cpp_type.destruct(value); });
|
||||
values.get_to_uninitialized(layer_index, value);
|
||||
return GVArray::ForSingle(cpp_type, dst_domain_size, value);
|
||||
}
|
||||
/* We don't adapt from curve to layer domain currently. */
|
||||
return GVArray::ForSingleDefault(cpp_type, dst_domain_size);
|
||||
}
|
||||
|
||||
const bke::AttributeAccessor attributes = *context.attributes();
|
||||
|
||||
const bke::GeometryFieldContext other_domain_context{context, src_domain_};
|
||||
const int64_t src_domain_size = attributes.domain_size(src_domain_);
|
||||
GArray<> values(cpp_type, src_domain_size);
|
||||
fn::FieldEvaluator value_evaluator{other_domain_context, src_domain_size};
|
||||
value_evaluator.add_with_destination(src_field_, values.as_mutable_span());
|
||||
value_evaluator.evaluate();
|
||||
return attributes.adapt_domain(GVArray::ForGArray(std::move(values)), src_domain_, dst_domain);
|
||||
}
|
||||
|
||||
void EvaluateOnDomainInput::for_each_field_input_recursive(
|
||||
FunctionRef<void(const FieldInput &)> fn) const
|
||||
{
|
||||
src_field_.node().for_each_field_input_recursive(fn);
|
||||
}
|
||||
|
||||
std::optional<AttrDomain> EvaluateOnDomainInput::preferred_domain(
|
||||
const GeometryComponent & /*component*/) const
|
||||
{
|
||||
return src_domain_;
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -61,45 +61,6 @@ void get_closest_in_bvhtree(BVHTreeFromMesh &tree_data,
|
|||
|
||||
int apply_offset_in_cyclic_range(IndexRange range, int start_index, int offset);
|
||||
|
||||
class EvaluateAtIndexInput final : public bke::GeometryFieldInput {
|
||||
private:
|
||||
Field<int> index_field_;
|
||||
GField value_field_;
|
||||
AttrDomain value_field_domain_;
|
||||
|
||||
public:
|
||||
EvaluateAtIndexInput(Field<int> index_field, GField value_field, AttrDomain value_field_domain);
|
||||
|
||||
GVArray get_varray_for_context(const bke::GeometryFieldContext &context,
|
||||
const IndexMask &mask) const final;
|
||||
|
||||
std::optional<AttrDomain> preferred_domain(const GeometryComponent & /*component*/) const final
|
||||
{
|
||||
return value_field_domain_;
|
||||
}
|
||||
};
|
||||
|
||||
class EvaluateOnDomainInput final : public bke::GeometryFieldInput {
|
||||
private:
|
||||
GField src_field_;
|
||||
AttrDomain src_domain_;
|
||||
|
||||
public:
|
||||
EvaluateOnDomainInput(GField field, AttrDomain domain);
|
||||
|
||||
GVArray get_varray_for_context(const bke::GeometryFieldContext &context,
|
||||
const IndexMask & /*mask*/) const final;
|
||||
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const override;
|
||||
|
||||
std::optional<AttrDomain> preferred_domain(
|
||||
const GeometryComponent & /*component*/) const override;
|
||||
};
|
||||
|
||||
void copy_with_checked_indices(const GVArray &src,
|
||||
const VArray<int> &indices,
|
||||
const IndexMask &mask,
|
||||
GMutableSpan dst);
|
||||
|
||||
void mix_baked_data_item(eNodeSocketDatatype socket_type,
|
||||
void *prev,
|
||||
const void *next,
|
||||
|
|
|
@ -100,12 +100,12 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
if (params.output_is_required("Curve Index")) {
|
||||
params.set_output(
|
||||
"Curve Index",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
point_index, Field<int>(std::make_shared<CurveOfPointInput>()), AttrDomain::Point)));
|
||||
}
|
||||
if (params.output_is_required("Index in Curve")) {
|
||||
params.set_output("Index in Curve",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
point_index,
|
||||
Field<int>(std::make_shared<PointIndexInCurveInput>()),
|
||||
AttrDomain::Point)));
|
||||
|
|
|
@ -223,7 +223,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
const Field<int> curve_index = params.extract_input<Field<int>>("Curve Index");
|
||||
if (params.output_is_required("Total")) {
|
||||
params.set_output("Total",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
curve_index,
|
||||
Field<int>(std::make_shared<CurvePointCountInput>()),
|
||||
AttrDomain::Curve)));
|
||||
|
|
|
@ -17,44 +17,6 @@
|
|||
|
||||
#include "NOD_socket_search_link.hh"
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
EvaluateAtIndexInput::EvaluateAtIndexInput(Field<int> index_field,
|
||||
GField value_field,
|
||||
AttrDomain value_field_domain)
|
||||
: bke::GeometryFieldInput(value_field.cpp_type(), "Evaluate at Index"),
|
||||
index_field_(std::move(index_field)),
|
||||
value_field_(std::move(value_field)),
|
||||
value_field_domain_(value_field_domain)
|
||||
{
|
||||
}
|
||||
|
||||
GVArray EvaluateAtIndexInput::get_varray_for_context(const bke::GeometryFieldContext &context,
|
||||
const IndexMask &mask) const
|
||||
{
|
||||
const std::optional<AttributeAccessor> attributes = context.attributes();
|
||||
if (!attributes) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const bke::GeometryFieldContext value_context{context, value_field_domain_};
|
||||
FieldEvaluator value_evaluator{value_context, attributes->domain_size(value_field_domain_)};
|
||||
value_evaluator.add(value_field_);
|
||||
value_evaluator.evaluate();
|
||||
const GVArray &values = value_evaluator.get_evaluated(0);
|
||||
|
||||
FieldEvaluator index_evaluator{context, &mask};
|
||||
index_evaluator.add(index_field_);
|
||||
index_evaluator.evaluate();
|
||||
const VArray<int> indices = index_evaluator.get_evaluated<int>(0);
|
||||
|
||||
GArray<> dst_array(values.type(), mask.min_array_size());
|
||||
copy_with_checked_indices(values, indices, mask, dst_array);
|
||||
return GVArray::ForGArray(std::move(dst_array));
|
||||
}
|
||||
|
||||
} // namespace blender::nodes
|
||||
|
||||
namespace blender::nodes::node_geo_evaluate_at_index_cc {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
|
@ -109,7 +71,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
const bNode &node = params.node();
|
||||
const AttrDomain domain = AttrDomain(node.custom1);
|
||||
|
||||
GField output_field{std::make_shared<EvaluateAtIndexInput>(
|
||||
GField output_field{std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
params.extract_input<Field<int>>("Index"), params.extract_input<GField>("Value"), domain)};
|
||||
params.set_output<GField>("Value", std::move(output_field));
|
||||
}
|
||||
|
|
|
@ -19,71 +19,6 @@
|
|||
|
||||
#include "NOD_socket_search_link.hh"
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
EvaluateOnDomainInput::EvaluateOnDomainInput(GField field, AttrDomain domain)
|
||||
: bke::GeometryFieldInput(field.cpp_type(), "Evaluate on Domain"),
|
||||
src_field_(std::move(field)),
|
||||
src_domain_(domain)
|
||||
{
|
||||
}
|
||||
|
||||
GVArray EvaluateOnDomainInput::get_varray_for_context(const bke::GeometryFieldContext &context,
|
||||
const IndexMask & /*mask*/) const
|
||||
{
|
||||
const AttrDomain dst_domain = context.domain();
|
||||
const int dst_domain_size = context.attributes()->domain_size(dst_domain);
|
||||
const CPPType &cpp_type = src_field_.cpp_type();
|
||||
|
||||
if (context.type() == GeometryComponent::Type::GreasePencil &&
|
||||
(src_domain_ == AttrDomain::Layer) != (dst_domain == AttrDomain::Layer))
|
||||
{
|
||||
/* Evaluate field just for the current layer. */
|
||||
if (src_domain_ == AttrDomain::Layer) {
|
||||
const bke::GeometryFieldContext src_domain_context{context, AttrDomain::Layer};
|
||||
const int layer_index = context.grease_pencil_layer_index();
|
||||
|
||||
const IndexMask single_layer_mask = IndexRange(layer_index, 1);
|
||||
FieldEvaluator value_evaluator{src_domain_context, &single_layer_mask};
|
||||
value_evaluator.add(src_field_);
|
||||
value_evaluator.evaluate();
|
||||
|
||||
const GVArray &values = value_evaluator.get_evaluated(0);
|
||||
|
||||
BUFFER_FOR_CPP_TYPE_VALUE(cpp_type, value);
|
||||
BLI_SCOPED_DEFER([&]() { cpp_type.destruct(value); });
|
||||
values.get_to_uninitialized(layer_index, value);
|
||||
return GVArray::ForSingle(cpp_type, dst_domain_size, value);
|
||||
}
|
||||
/* We don't adapt from curve to layer domain currently. */
|
||||
return GVArray::ForSingleDefault(cpp_type, dst_domain_size);
|
||||
}
|
||||
|
||||
const bke::AttributeAccessor attributes = *context.attributes();
|
||||
|
||||
const bke::GeometryFieldContext other_domain_context{context, src_domain_};
|
||||
const int64_t src_domain_size = attributes.domain_size(src_domain_);
|
||||
GArray<> values(cpp_type, src_domain_size);
|
||||
FieldEvaluator value_evaluator{other_domain_context, src_domain_size};
|
||||
value_evaluator.add_with_destination(src_field_, values.as_mutable_span());
|
||||
value_evaluator.evaluate();
|
||||
return attributes.adapt_domain(GVArray::ForGArray(std::move(values)), src_domain_, dst_domain);
|
||||
}
|
||||
|
||||
void EvaluateOnDomainInput::for_each_field_input_recursive(
|
||||
FunctionRef<void(const FieldInput &)> fn) const
|
||||
{
|
||||
src_field_.node().for_each_field_input_recursive(fn);
|
||||
}
|
||||
|
||||
std::optional<AttrDomain> EvaluateOnDomainInput::preferred_domain(
|
||||
const GeometryComponent & /*component*/) const
|
||||
{
|
||||
return src_domain_;
|
||||
}
|
||||
|
||||
} // namespace blender::nodes
|
||||
|
||||
namespace blender::nodes::node_geo_evaluate_on_domain_cc {
|
||||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
|
@ -130,7 +65,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
const AttrDomain domain = AttrDomain(node.custom1);
|
||||
|
||||
GField src_field = params.extract_input<GField>("Value");
|
||||
GField dst_field{std::make_shared<EvaluateOnDomainInput>(std::move(src_field), domain)};
|
||||
GField dst_field{std::make_shared<bke::EvaluateOnDomainInput>(std::move(src_field), domain)};
|
||||
params.set_output<GField>("Value", std::move(dst_field));
|
||||
}
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
const Field<int> edge_index = params.extract_input<Field<int>>("Edge Index");
|
||||
if (params.output_is_required("Total")) {
|
||||
params.set_output("Total",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
edge_index,
|
||||
Field<int>(std::make_shared<CornersOfEdgeCountInput>()),
|
||||
AttrDomain::Edge)));
|
||||
|
|
|
@ -175,7 +175,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
const Field<int> face_index = params.extract_input<Field<int>>("Face Index");
|
||||
if (params.output_is_required("Total")) {
|
||||
params.set_output("Total",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
face_index,
|
||||
Field<int>(std::make_shared<CornersOfFaceCountInput>()),
|
||||
AttrDomain::Face)));
|
||||
|
|
|
@ -181,7 +181,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
const Field<int> vert_index = params.extract_input<Field<int>>("Vertex Index");
|
||||
if (params.output_is_required("Total")) {
|
||||
params.set_output("Total",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
vert_index,
|
||||
Field<int>(std::make_shared<CornersOfVertCountInput>()),
|
||||
AttrDomain::Point)));
|
||||
|
|
|
@ -103,14 +103,14 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
const Field<int> corner_index = params.extract_input<Field<int>>("Corner Index");
|
||||
if (params.output_is_required("Next Edge Index")) {
|
||||
params.set_output("Next Edge Index",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
corner_index,
|
||||
Field<int>(std::make_shared<CornerNextEdgeFieldInput>()),
|
||||
AttrDomain::Corner)));
|
||||
}
|
||||
if (params.output_is_required("Previous Edge Index")) {
|
||||
params.set_output("Previous Edge Index",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
corner_index,
|
||||
Field<int>(std::make_shared<CornerPreviousEdgeFieldInput>()),
|
||||
AttrDomain::Corner)));
|
||||
|
|
|
@ -186,7 +186,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
const Field<int> vert_index = params.extract_input<Field<int>>("Vertex Index");
|
||||
if (params.output_is_required("Total")) {
|
||||
params.set_output("Total",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
vert_index,
|
||||
Field<int>(std::make_shared<EdgesOfVertCountInput>()),
|
||||
AttrDomain::Point)));
|
||||
|
|
|
@ -93,14 +93,14 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
const Field<int> corner_index = params.extract_input<Field<int>>("Corner Index");
|
||||
if (params.output_is_required("Face Index")) {
|
||||
params.set_output("Face Index",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
corner_index,
|
||||
Field<int>(std::make_shared<CornerFaceIndexInput>()),
|
||||
AttrDomain::Corner)));
|
||||
}
|
||||
if (params.output_is_required("Index in Face")) {
|
||||
params.set_output("Index in Face",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
corner_index,
|
||||
Field<int>(std::make_shared<CornerIndexInFaceInput>()),
|
||||
AttrDomain::Corner)));
|
||||
|
|
|
@ -56,7 +56,7 @@ class CornerVertFieldInput final : public bke::MeshFieldInput {
|
|||
static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
params.set_output("Vertex Index",
|
||||
Field<int>(std::make_shared<EvaluateAtIndexInput>(
|
||||
Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
|
||||
params.extract_input<Field<int>>("Corner Index"),
|
||||
Field<int>(std::make_shared<CornerVertFieldInput>()),
|
||||
AttrDomain::Corner)));
|
||||
|
|
|
@ -15,37 +15,6 @@
|
|||
|
||||
namespace blender::nodes {
|
||||
|
||||
template<typename T>
|
||||
void copy_with_checked_indices(const VArray<T> &src,
|
||||
const VArray<int> &indices,
|
||||
const IndexMask &mask,
|
||||
MutableSpan<T> dst)
|
||||
{
|
||||
const IndexRange src_range = src.index_range();
|
||||
devirtualize_varray2(src, indices, [&](const auto src, const auto indices) {
|
||||
mask.foreach_index(GrainSize(4096), [&](const int i) {
|
||||
const int index = indices[i];
|
||||
if (src_range.contains(index)) {
|
||||
dst[i] = src[index];
|
||||
}
|
||||
else {
|
||||
dst[i] = {};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void copy_with_checked_indices(const GVArray &src,
|
||||
const VArray<int> &indices,
|
||||
const IndexMask &mask,
|
||||
GMutableSpan dst)
|
||||
{
|
||||
bke::attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
|
||||
using T = decltype(dummy);
|
||||
copy_with_checked_indices(src.typed<T>(), indices, mask, dst.typed<T>());
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace blender::nodes
|
||||
|
||||
namespace blender::nodes::node_geo_sample_index_cc {
|
||||
|
@ -220,7 +189,7 @@ class SampleIndexFunction : public mf::MultiFunction {
|
|||
});
|
||||
}
|
||||
else {
|
||||
copy_with_checked_indices(*src_data_, indices, mask, dst);
|
||||
bke::copy_with_checked_indices(*src_data_, indices, mask, dst);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -57,13 +57,13 @@ static void set_curve_normal(bke::CurvesGeometry &curves,
|
|||
fn::make_constant_field<int8_t>(mode));
|
||||
|
||||
if (mode == NORMAL_MODE_FREE) {
|
||||
bke::try_capture_field_on_geometry(
|
||||
curves.attributes_for_write(),
|
||||
point_context,
|
||||
"custom_normal",
|
||||
AttrDomain::Point,
|
||||
Field<bool>(std::make_shared<EvaluateOnDomainInput>(selection_field, AttrDomain::Curve)),
|
||||
custom_normal);
|
||||
bke::try_capture_field_on_geometry(curves.attributes_for_write(),
|
||||
point_context,
|
||||
"custom_normal",
|
||||
AttrDomain::Point,
|
||||
Field<bool>(std::make_shared<bke::EvaluateOnDomainInput>(
|
||||
selection_field, AttrDomain::Curve)),
|
||||
custom_normal);
|
||||
}
|
||||
|
||||
curves.tag_normals_changed();
|
||||
|
|
Loading…
Reference in New Issue