Geometry Nodes: reduce code duplication with new GeometyrFieldInput
Most of our field inputs are currently specific to geometry. This patch introduces a new `GeometryFieldInput` that reduces the overhead of adding new geometry field input. Differential Revision: https://developer.blender.org/D13489
This commit is contained in:
@@ -744,13 +744,26 @@ class GeometryComponentFieldContext : public fn::FieldContext {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class AttributeFieldInput : public fn::FieldInput {
|
class GeometryFieldInput : public fn::FieldInput {
|
||||||
|
public:
|
||||||
|
using fn::FieldInput::FieldInput;
|
||||||
|
|
||||||
|
GVArray get_varray_for_context(const fn::FieldContext &context,
|
||||||
|
IndexMask mask,
|
||||||
|
ResourceScope &scope) const override;
|
||||||
|
|
||||||
|
virtual GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
|
const AttributeDomain domain,
|
||||||
|
IndexMask mask) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AttributeFieldInput : public GeometryFieldInput {
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AttributeFieldInput(std::string name, const CPPType &type)
|
AttributeFieldInput(std::string name, const CPPType &type)
|
||||||
: fn::FieldInput(type, name), name_(std::move(name))
|
: GeometryFieldInput(type, name), name_(std::move(name))
|
||||||
{
|
{
|
||||||
category_ = Category::NamedAttribute;
|
category_ = Category::NamedAttribute;
|
||||||
}
|
}
|
||||||
@@ -767,9 +780,9 @@ class AttributeFieldInput : public fn::FieldInput {
|
|||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask mask,
|
const AttributeDomain domain,
|
||||||
ResourceScope &scope) const override;
|
IndexMask mask) const override;
|
||||||
|
|
||||||
std::string socket_inspection_name() const override;
|
std::string socket_inspection_name() const override;
|
||||||
|
|
||||||
@@ -777,16 +790,16 @@ class AttributeFieldInput : public fn::FieldInput {
|
|||||||
bool is_equal_to(const fn::FieldNode &other) const override;
|
bool is_equal_to(const fn::FieldNode &other) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IDAttributeFieldInput : public fn::FieldInput {
|
class IDAttributeFieldInput : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
IDAttributeFieldInput() : fn::FieldInput(CPPType::get<int>())
|
IDAttributeFieldInput() : GeometryFieldInput(CPPType::get<int>())
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask mask,
|
const AttributeDomain domain,
|
||||||
ResourceScope &scope) const override;
|
IndexMask mask) const override;
|
||||||
|
|
||||||
std::string socket_inspection_name() const override;
|
std::string socket_inspection_name() const override;
|
||||||
|
|
||||||
@@ -794,7 +807,7 @@ class IDAttributeFieldInput : public fn::FieldInput {
|
|||||||
bool is_equal_to(const fn::FieldNode &other) const override;
|
bool is_equal_to(const fn::FieldNode &other) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AnonymousAttributeFieldInput : public fn::FieldInput {
|
class AnonymousAttributeFieldInput : public GeometryFieldInput {
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* A strong reference is required to make sure that the referenced attribute is not removed
|
* A strong reference is required to make sure that the referenced attribute is not removed
|
||||||
@@ -807,7 +820,7 @@ class AnonymousAttributeFieldInput : public fn::FieldInput {
|
|||||||
AnonymousAttributeFieldInput(StrongAnonymousAttributeID anonymous_id,
|
AnonymousAttributeFieldInput(StrongAnonymousAttributeID anonymous_id,
|
||||||
const CPPType &type,
|
const CPPType &type,
|
||||||
std::string producer_name)
|
std::string producer_name)
|
||||||
: fn::FieldInput(type, anonymous_id.debug_name()),
|
: GeometryFieldInput(type, anonymous_id.debug_name()),
|
||||||
anonymous_id_(std::move(anonymous_id)),
|
anonymous_id_(std::move(anonymous_id)),
|
||||||
producer_name_(producer_name)
|
producer_name_(producer_name)
|
||||||
{
|
{
|
||||||
@@ -823,9 +836,9 @@ class AnonymousAttributeFieldInput : public fn::FieldInput {
|
|||||||
return fn::Field<T>{field_input};
|
return fn::Field<T>{field_input};
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask mask,
|
const AttributeDomain domain,
|
||||||
ResourceScope &scope) const override;
|
IndexMask mask) const override;
|
||||||
|
|
||||||
std::string socket_inspection_name() const override;
|
std::string socket_inspection_name() const override;
|
||||||
|
|
||||||
|
|||||||
@@ -1421,23 +1421,27 @@ OutputAttribute GeometryComponent::attribute_try_get_for_output_only(
|
|||||||
|
|
||||||
namespace blender::bke {
|
namespace blender::bke {
|
||||||
|
|
||||||
GVArray AttributeFieldInput::get_varray_for_context(const fn::FieldContext &context,
|
GVArray GeometryFieldInput::get_varray_for_context(const fn::FieldContext &context,
|
||||||
IndexMask UNUSED(mask),
|
IndexMask mask,
|
||||||
ResourceScope &UNUSED(scope)) const
|
ResourceScope &UNUSED(scope)) const
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (const GeometryComponentFieldContext *geometry_context =
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
const GeometryComponent &component = geometry_context->geometry_component();
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
const AttributeDomain domain = geometry_context->domain();
|
||||||
const CustomDataType data_type = cpp_type_to_custom_data_type(*type_);
|
return this->get_varray_for_context(component, domain, mask);
|
||||||
GVArray attribute = component.attribute_try_get_for_read(name_, domain, data_type);
|
|
||||||
if (attribute) {
|
|
||||||
return attribute;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GVArray AttributeFieldInput::get_varray_for_context(const GeometryComponent &component,
|
||||||
|
const AttributeDomain domain,
|
||||||
|
IndexMask UNUSED(mask)) const
|
||||||
|
{
|
||||||
|
const CustomDataType data_type = cpp_type_to_custom_data_type(*type_);
|
||||||
|
return component.attribute_try_get_for_read(name_, domain, data_type);
|
||||||
|
}
|
||||||
|
|
||||||
std::string AttributeFieldInput::socket_inspection_name() const
|
std::string AttributeFieldInput::socket_inspection_name() const
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
@@ -1469,25 +1473,20 @@ static StringRef get_random_id_attribute_name(const AttributeDomain domain)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray IDAttributeFieldInput::get_varray_for_context(const fn::FieldContext &context,
|
GVArray IDAttributeFieldInput::get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask mask,
|
const AttributeDomain domain,
|
||||||
ResourceScope &scope) const
|
IndexMask mask) const
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
const StringRef name = get_random_id_attribute_name(domain);
|
|
||||||
GVArray attribute = component.attribute_try_get_for_read(name, domain, CD_PROP_INT32);
|
|
||||||
if (attribute) {
|
|
||||||
BLI_assert(attribute.size() == component.attribute_domain_size(domain));
|
|
||||||
return attribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use the index as the fallback if no random ID attribute exists. */
|
const StringRef name = get_random_id_attribute_name(domain);
|
||||||
return fn::IndexFieldInput::get_index_varray(mask, scope);
|
GVArray attribute = component.attribute_try_get_for_read(name, domain, CD_PROP_INT32);
|
||||||
|
if (attribute) {
|
||||||
|
BLI_assert(attribute.size() == component.attribute_domain_size(domain));
|
||||||
|
return attribute;
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
|
/* Use the index as the fallback if no random ID attribute exists. */
|
||||||
|
return fn::IndexFieldInput::get_index_varray(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string IDAttributeFieldInput::socket_inspection_name() const
|
std::string IDAttributeFieldInput::socket_inspection_name() const
|
||||||
@@ -1507,20 +1506,12 @@ bool IDAttributeFieldInput::is_equal_to(const fn::FieldNode &other) const
|
|||||||
return dynamic_cast<const IDAttributeFieldInput *>(&other) != nullptr;
|
return dynamic_cast<const IDAttributeFieldInput *>(&other) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray AnonymousAttributeFieldInput::get_varray_for_context(const fn::FieldContext &context,
|
GVArray AnonymousAttributeFieldInput::get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const
|
IndexMask UNUSED(mask)) const
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
const CustomDataType data_type = cpp_type_to_custom_data_type(*type_);
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
return component.attribute_try_get_for_read(anonymous_id_.get(), domain, data_type);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
const CustomDataType data_type = cpp_type_to_custom_data_type(*type_);
|
|
||||||
GVArray attribute = component.attribute_try_get_for_read(
|
|
||||||
anonymous_id_.get(), domain, data_type);
|
|
||||||
return attribute;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AnonymousAttributeFieldInput::socket_inspection_name() const
|
std::string AnonymousAttributeFieldInput::socket_inspection_name() const
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ class IndexFieldInput final : public FieldInput {
|
|||||||
public:
|
public:
|
||||||
IndexFieldInput();
|
IndexFieldInput();
|
||||||
|
|
||||||
static GVArray get_index_varray(IndexMask mask, ResourceScope &scope);
|
static GVArray get_index_varray(IndexMask mask);
|
||||||
|
|
||||||
GVArray get_varray_for_context(const FieldContext &context,
|
GVArray get_varray_for_context(const FieldContext &context,
|
||||||
IndexMask mask,
|
IndexMask mask,
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ IndexFieldInput::IndexFieldInput() : FieldInput(CPPType::get<int>(), "Index")
|
|||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray IndexFieldInput::get_index_varray(IndexMask mask, ResourceScope &UNUSED(scope))
|
GVArray IndexFieldInput::get_index_varray(IndexMask mask)
|
||||||
{
|
{
|
||||||
auto index_func = [](int i) { return i; };
|
auto index_func = [](int i) { return i; };
|
||||||
return VArray<int>::ForFunc(mask.min_array_size(), index_func);
|
return VArray<int>::ForFunc(mask.min_array_size(), index_func);
|
||||||
@@ -539,10 +539,10 @@ GVArray IndexFieldInput::get_index_varray(IndexMask mask, ResourceScope &UNUSED(
|
|||||||
|
|
||||||
GVArray IndexFieldInput::get_varray_for_context(const fn::FieldContext &UNUSED(context),
|
GVArray IndexFieldInput::get_varray_for_context(const fn::FieldContext &UNUSED(context),
|
||||||
IndexMask mask,
|
IndexMask mask,
|
||||||
ResourceScope &scope) const
|
ResourceScope &UNUSED(scope)) const
|
||||||
{
|
{
|
||||||
/* TODO: Investigate a similar method to IndexRange::as_span() */
|
/* TODO: Investigate a similar method to IndexRange::as_span() */
|
||||||
return get_index_varray(mask, scope);
|
return get_index_varray(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t IndexFieldInput::hash() const
|
uint64_t IndexFieldInput::hash() const
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ using bke::AttributeFieldInput;
|
|||||||
using bke::AttributeIDRef;
|
using bke::AttributeIDRef;
|
||||||
using bke::geometry_set_realize_instances;
|
using bke::geometry_set_realize_instances;
|
||||||
using bke::GeometryComponentFieldContext;
|
using bke::GeometryComponentFieldContext;
|
||||||
|
using bke::GeometryFieldInput;
|
||||||
using bke::OutputAttribute;
|
using bke::OutputAttribute;
|
||||||
using bke::OutputAttribute_Typed;
|
using bke::OutputAttribute_Typed;
|
||||||
using bke::ReadAttributeLookup;
|
using bke::ReadAttributeLookup;
|
||||||
|
|||||||
@@ -51,69 +51,61 @@ static void select_by_spline(const int start, const int end, MutableSpan<bool> r
|
|||||||
r_selection.slice(size - end_use, end_use).fill(true);
|
r_selection.slice(size - end_use, end_use).fill(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EndpointFieldInput final : public fn::FieldInput {
|
class EndpointFieldInput final : public GeometryFieldInput {
|
||||||
Field<int> start_size_;
|
Field<int> start_size_;
|
||||||
Field<int> end_size_;
|
Field<int> end_size_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EndpointFieldInput(Field<int> start_size, Field<int> end_size)
|
EndpointFieldInput(Field<int> start_size, Field<int> end_size)
|
||||||
: FieldInput(CPPType::get<bool>(), "Endpoint Selection node"),
|
: GeometryFieldInput(CPPType::get<bool>(), "Endpoint Selection node"),
|
||||||
start_size_(start_size),
|
start_size_(start_size),
|
||||||
end_size_(end_size)
|
end_size_(end_size)
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
return nullptr;
|
||||||
|
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() != GEO_COMPONENT_TYPE_CURVE || domain != ATTR_DOMAIN_POINT) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
|
||||||
const CurveEval *curve = curve_component.get_for_read();
|
|
||||||
|
|
||||||
Array<int> control_point_offsets = curve->control_point_offsets();
|
|
||||||
|
|
||||||
if (curve == nullptr || control_point_offsets.last() == 0) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE};
|
|
||||||
fn::FieldEvaluator evaluator{size_context, curve->splines().size()};
|
|
||||||
evaluator.add(start_size_);
|
|
||||||
evaluator.add(end_size_);
|
|
||||||
evaluator.evaluate();
|
|
||||||
const VArray<int> &start_size = evaluator.get_evaluated<int>(0);
|
|
||||||
const VArray<int> &end_size = evaluator.get_evaluated<int>(1);
|
|
||||||
|
|
||||||
const int point_size = control_point_offsets.last();
|
|
||||||
Array<bool> selection(point_size, false);
|
|
||||||
int current_point = 0;
|
|
||||||
MutableSpan<bool> selection_span = selection.as_mutable_span();
|
|
||||||
for (int i : IndexRange(curve->splines().size())) {
|
|
||||||
const SplinePtr &spline = curve->splines()[i];
|
|
||||||
if (start_size[i] <= 0 && end_size[i] <= 0) {
|
|
||||||
selection_span.slice(current_point, spline->size()).fill(false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int start_use = std::max(start_size[i], 0);
|
|
||||||
int end_use = std::max(end_size[i], 0);
|
|
||||||
select_by_spline(
|
|
||||||
start_use, end_use, selection_span.slice(current_point, spline->size()));
|
|
||||||
}
|
|
||||||
current_point += spline->size();
|
|
||||||
}
|
|
||||||
return VArray<bool>::ForContainer(std::move(selection));
|
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
|
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
||||||
|
const CurveEval *curve = curve_component.get_for_read();
|
||||||
|
|
||||||
|
Array<int> control_point_offsets = curve->control_point_offsets();
|
||||||
|
|
||||||
|
if (curve == nullptr || control_point_offsets.last() == 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE};
|
||||||
|
fn::FieldEvaluator evaluator{size_context, curve->splines().size()};
|
||||||
|
evaluator.add(start_size_);
|
||||||
|
evaluator.add(end_size_);
|
||||||
|
evaluator.evaluate();
|
||||||
|
const VArray<int> &start_size = evaluator.get_evaluated<int>(0);
|
||||||
|
const VArray<int> &end_size = evaluator.get_evaluated<int>(1);
|
||||||
|
|
||||||
|
const int point_size = control_point_offsets.last();
|
||||||
|
Array<bool> selection(point_size, false);
|
||||||
|
int current_point = 0;
|
||||||
|
MutableSpan<bool> selection_span = selection.as_mutable_span();
|
||||||
|
for (int i : IndexRange(curve->splines().size())) {
|
||||||
|
const SplinePtr &spline = curve->splines()[i];
|
||||||
|
if (start_size[i] <= 0 && end_size[i] <= 0) {
|
||||||
|
selection_span.slice(current_point, spline->size()).fill(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int start_use = std::max(start_size[i], 0);
|
||||||
|
int end_use = std::max(end_size[i], 0);
|
||||||
|
select_by_spline(start_use, end_use, selection_span.slice(current_point, spline->size()));
|
||||||
|
}
|
||||||
|
current_point += spline->size();
|
||||||
|
}
|
||||||
|
return VArray<bool>::ForContainer(std::move(selection));
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64_t hash() const override
|
uint64_t hash() const override
|
||||||
|
|||||||
@@ -83,44 +83,40 @@ static void select_by_handle_type(const CurveEval &curve,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HandleTypeFieldInput final : public fn::FieldInput {
|
class HandleTypeFieldInput final : public GeometryFieldInput {
|
||||||
BezierSpline::HandleType type_;
|
BezierSpline::HandleType type_;
|
||||||
GeometryNodeCurveHandleMode mode_;
|
GeometryNodeCurveHandleMode mode_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HandleTypeFieldInput(BezierSpline::HandleType type, GeometryNodeCurveHandleMode mode)
|
HandleTypeFieldInput(BezierSpline::HandleType type, GeometryNodeCurveHandleMode mode)
|
||||||
: FieldInput(CPPType::get<bool>(), "Handle Type Selection node"), type_(type), mode_(mode)
|
: GeometryFieldInput(CPPType::get<bool>(), "Handle Type Selection node"),
|
||||||
|
type_(type),
|
||||||
|
mode_(mode)
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask mask,
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask mask) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() != GEO_COMPONENT_TYPE_CURVE) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
const CurveEval *curve = curve_component.get_for_read();
|
||||||
if (component.type() != GEO_COMPONENT_TYPE_CURVE) {
|
if (curve == nullptr) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
if (domain == ATTR_DOMAIN_POINT) {
|
||||||
const CurveEval *curve = curve_component.get_for_read();
|
Array<bool> selection(mask.min_array_size());
|
||||||
if (curve == nullptr) {
|
select_by_handle_type(*curve, type_, mode_, selection);
|
||||||
return {};
|
return VArray<bool>::ForContainer(std::move(selection));
|
||||||
}
|
|
||||||
|
|
||||||
if (domain == ATTR_DOMAIN_POINT) {
|
|
||||||
Array<bool> selection(mask.min_array_size());
|
|
||||||
select_by_handle_type(*curve, type_, mode_, selection);
|
|
||||||
return VArray<bool>::ForContainer(std::move(selection));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
};
|
}
|
||||||
|
|
||||||
uint64_t hash() const override
|
uint64_t hash() const override
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -202,29 +202,22 @@ static VArray<int> construct_index_on_spline_varray(const CurveEval &curve,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
class CurveParameterFieldInput final : public fn::FieldInput {
|
class CurveParameterFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
CurveParameterFieldInput() : fn::FieldInput(CPPType::get<float>(), "Curve Parameter node")
|
CurveParameterFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Curve Parameter node")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask mask,
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask mask) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
||||||
|
const CurveEval *curve = curve_component.get_for_read();
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
if (curve) {
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
return construct_curve_parameter_varray(*curve, mask, domain);
|
||||||
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
|
||||||
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
|
||||||
const CurveEval *curve = curve_component.get_for_read();
|
|
||||||
if (curve) {
|
|
||||||
return construct_curve_parameter_varray(*curve, mask, domain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
@@ -242,28 +235,22 @@ class CurveParameterFieldInput final : public fn::FieldInput {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CurveLengthFieldInput final : public fn::FieldInput {
|
class CurveLengthFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
CurveLengthFieldInput() : fn::FieldInput(CPPType::get<float>(), "Curve Length node")
|
CurveLengthFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Curve Length node")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask mask,
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask mask) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
||||||
|
const CurveEval *curve = curve_component.get_for_read();
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
if (curve) {
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
return construct_curve_length_varray(*curve, mask, domain);
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
|
||||||
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
|
||||||
const CurveEval *curve = curve_component.get_for_read();
|
|
||||||
if (curve) {
|
|
||||||
return construct_curve_length_varray(*curve, mask, domain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
@@ -281,28 +268,22 @@ class CurveLengthFieldInput final : public fn::FieldInput {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IndexOnSplineFieldInput final : public fn::FieldInput {
|
class IndexOnSplineFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
IndexOnSplineFieldInput() : fn::FieldInput(CPPType::get<int>(), "Spline Index")
|
IndexOnSplineFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Spline Index")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask mask,
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask mask) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
||||||
|
const CurveEval *curve = curve_component.get_for_read();
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
if (curve) {
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
return construct_index_on_spline_varray(*curve, mask, domain);
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
|
||||||
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
|
||||||
const CurveEval *curve = curve_component.get_for_read();
|
|
||||||
if (curve) {
|
|
||||||
return construct_index_on_spline_varray(*curve, mask, domain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -61,29 +61,24 @@ static VArray<int> construct_edge_vertices_gvarray(const MeshComponent &componen
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
class EdgeVerticesFieldInput final : public fn::FieldInput {
|
class EdgeVerticesFieldInput final : public GeometryFieldInput {
|
||||||
private:
|
private:
|
||||||
VertexNumber vertex_;
|
VertexNumber vertex_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EdgeVerticesFieldInput(VertexNumber vertex)
|
EdgeVerticesFieldInput(VertexNumber vertex)
|
||||||
: fn::FieldInput(CPPType::get<int>(), "Edge Vertices Field"), vertex_(vertex)
|
: GeometryFieldInput(CPPType::get<int>(), "Edge Vertices Field"), vertex_(vertex)
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
return construct_edge_vertices_gvarray(mesh_component, vertex_, domain);
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
|
||||||
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
|
||||||
return construct_edge_vertices_gvarray(mesh_component, vertex_, domain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -128,29 +123,24 @@ static VArray<float3> construct_edge_positions_gvarray(const MeshComponent &comp
|
|||||||
domain);
|
domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EdgePositionFieldInput final : public fn::FieldInput {
|
class EdgePositionFieldInput final : public GeometryFieldInput {
|
||||||
private:
|
private:
|
||||||
VertexNumber vertex_;
|
VertexNumber vertex_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EdgePositionFieldInput(VertexNumber vertex)
|
EdgePositionFieldInput(VertexNumber vertex)
|
||||||
: fn::FieldInput(CPPType::get<float3>(), "Edge Position Field"), vertex_(vertex)
|
: GeometryFieldInput(CPPType::get<float3>(), "Edge Position Field"), vertex_(vertex)
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
return construct_edge_positions_gvarray(mesh_component, vertex_, domain);
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
|
||||||
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
|
||||||
return construct_edge_positions_gvarray(mesh_component, vertex_, domain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,25 +47,20 @@ static VArray<float> construct_face_area_gvarray(const MeshComponent &component,
|
|||||||
VArray<float>::ForFunc(mesh->totpoly, area_fn), ATTR_DOMAIN_FACE, domain);
|
VArray<float>::ForFunc(mesh->totpoly, area_fn), ATTR_DOMAIN_FACE, domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FaceAreaFieldInput final : public fn::FieldInput {
|
class FaceAreaFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
FaceAreaFieldInput() : fn::FieldInput(CPPType::get<float>(), "Face Area Field")
|
FaceAreaFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Face Area Field")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
return construct_face_area_gvarray(mesh_component, domain);
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
|
||||||
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
|
||||||
return construct_face_area_gvarray(mesh_component, domain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,25 +58,21 @@ static VArray<int> construct_neighbor_count_gvarray(const MeshComponent &compone
|
|||||||
VArray<int>::ForContainer(std::move(poly_count)), ATTR_DOMAIN_FACE, domain);
|
VArray<int>::ForContainer(std::move(poly_count)), ATTR_DOMAIN_FACE, domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FaceNeighborCountFieldInput final : public fn::FieldInput {
|
class FaceNeighborCountFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
FaceNeighborCountFieldInput() : fn::FieldInput(CPPType::get<int>(), "Face Neighbor Count Field")
|
FaceNeighborCountFieldInput()
|
||||||
|
: GeometryFieldInput(CPPType::get<int>(), "Face Neighbor Count Field")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
return construct_neighbor_count_gvarray(mesh_component, domain);
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
|
||||||
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
|
||||||
return construct_neighbor_count_gvarray(mesh_component, domain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -108,25 +104,20 @@ static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component
|
|||||||
domain);
|
domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
class FaceVertexCountFieldInput final : public fn::FieldInput {
|
class FaceVertexCountFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
FaceVertexCountFieldInput() : fn::FieldInput(CPPType::get<int>(), "Vertex Count Field")
|
FaceVertexCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Count Field")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
return construct_vertex_count_gvarray(mesh_component, domain);
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
|
||||||
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
|
||||||
return construct_vertex_count_gvarray(mesh_component, domain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,25 +52,20 @@ static VArray<int> construct_vertex_count_gvarray(const MeshComponent &component
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
class VertexCountFieldInput final : public fn::FieldInput {
|
class VertexCountFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
VertexCountFieldInput() : fn::FieldInput(CPPType::get<int>(), "Vertex Count Field")
|
VertexCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Count Field")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
return construct_vertex_count_gvarray(mesh_component, domain);
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
|
||||||
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
|
||||||
return construct_vertex_count_gvarray(mesh_component, domain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -106,25 +101,20 @@ static VArray<int> construct_face_count_gvarray(const MeshComponent &component,
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
class VertexFaceCountFieldInput final : public fn::FieldInput {
|
class VertexFaceCountFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
VertexFaceCountFieldInput() : fn::FieldInput(CPPType::get<int>(), "Vertex Face Count Field")
|
VertexFaceCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Vertex Face Count Field")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
return construct_face_count_gvarray(mesh_component, domain);
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
|
||||||
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
|
||||||
return construct_face_count_gvarray(mesh_component, domain);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,8 +93,7 @@ static VArray<float3> mesh_vertex_normals(const Mesh &mesh,
|
|||||||
static VArray<float3> construct_mesh_normals_gvarray(const MeshComponent &mesh_component,
|
static VArray<float3> construct_mesh_normals_gvarray(const MeshComponent &mesh_component,
|
||||||
const Mesh &mesh,
|
const Mesh &mesh,
|
||||||
const IndexMask mask,
|
const IndexMask mask,
|
||||||
const AttributeDomain domain,
|
const AttributeDomain domain)
|
||||||
ResourceScope &UNUSED(scope))
|
|
||||||
{
|
{
|
||||||
Span<MVert> verts{mesh.mvert, mesh.totvert};
|
Span<MVert> verts{mesh.mvert, mesh.totvert};
|
||||||
Span<MEdge> edges{mesh.medge, mesh.totedge};
|
Span<MEdge> edges{mesh.medge, mesh.totedge};
|
||||||
@@ -199,8 +198,7 @@ static Array<float3> curve_normal_point_domain(const CurveEval &curve)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VArray<float3> construct_curve_normal_gvarray(const CurveComponent &component,
|
static VArray<float3> construct_curve_normal_gvarray(const CurveComponent &component,
|
||||||
const AttributeDomain domain,
|
const AttributeDomain domain)
|
||||||
ResourceScope &UNUSED(scope))
|
|
||||||
{
|
{
|
||||||
const CurveEval *curve = component.get_for_read();
|
const CurveEval *curve = component.get_for_read();
|
||||||
if (curve == nullptr) {
|
if (curve == nullptr) {
|
||||||
@@ -231,36 +229,29 @@ static VArray<float3> construct_curve_normal_gvarray(const CurveComponent &compo
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
class NormalFieldInput final : public fn::FieldInput {
|
class NormalFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
NormalFieldInput() : fn::FieldInput(CPPType::get<float3>(), "Normal node")
|
NormalFieldInput() : GeometryFieldInput(CPPType::get<float3>(), "Normal node")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask mask,
|
const AttributeDomain domain,
|
||||||
ResourceScope &scope) const final
|
IndexMask mask) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
||||||
|
const Mesh *mesh = mesh_component.get_for_read();
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
if (mesh == nullptr) {
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
return {};
|
||||||
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_MESH) {
|
|
||||||
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
|
||||||
const Mesh *mesh = mesh_component.get_for_read();
|
|
||||||
if (mesh == nullptr) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return construct_mesh_normals_gvarray(mesh_component, *mesh, mask, domain, scope);
|
|
||||||
}
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
|
||||||
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
|
||||||
return construct_curve_normal_gvarray(curve_component, domain, scope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return construct_mesh_normals_gvarray(mesh_component, *mesh, mask, domain);
|
||||||
|
}
|
||||||
|
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
||||||
|
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
||||||
|
return construct_curve_normal_gvarray(curve_component, domain);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static VArray<float> construct_spline_length_gvarray(const CurveComponent &component,
|
static VArray<float> construct_spline_length_gvarray(const CurveComponent &component,
|
||||||
const AttributeDomain domain,
|
const AttributeDomain domain)
|
||||||
ResourceScope &UNUSED(scope))
|
|
||||||
{
|
{
|
||||||
const CurveEval *curve = component.get_for_read();
|
const CurveEval *curve = component.get_for_read();
|
||||||
if (curve == nullptr) {
|
if (curve == nullptr) {
|
||||||
@@ -54,26 +53,20 @@ static VArray<float> construct_spline_length_gvarray(const CurveComponent &compo
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
class SplineLengthFieldInput final : public fn::FieldInput {
|
class SplineLengthFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
SplineLengthFieldInput() : fn::FieldInput(CPPType::get<float>(), "Spline Length node")
|
SplineLengthFieldInput() : GeometryFieldInput(CPPType::get<float>(), "Spline Length node")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &scope) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
||||||
|
return construct_spline_length_gvarray(curve_component, domain);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
|
||||||
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
|
||||||
return construct_spline_length_gvarray(curve_component, domain, scope);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -95,8 +88,7 @@ class SplineLengthFieldInput final : public fn::FieldInput {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static VArray<int> construct_spline_count_gvarray(const CurveComponent &component,
|
static VArray<int> construct_spline_count_gvarray(const CurveComponent &component,
|
||||||
const AttributeDomain domain,
|
const AttributeDomain domain)
|
||||||
ResourceScope &UNUSED(scope))
|
|
||||||
{
|
{
|
||||||
const CurveEval *curve = component.get_for_read();
|
const CurveEval *curve = component.get_for_read();
|
||||||
if (curve == nullptr) {
|
if (curve == nullptr) {
|
||||||
@@ -118,26 +110,20 @@ static VArray<int> construct_spline_count_gvarray(const CurveComponent &componen
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
class SplineCountFieldInput final : public fn::FieldInput {
|
class SplineCountFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
SplineCountFieldInput() : fn::FieldInput(CPPType::get<int>(), "Spline Point Count")
|
SplineCountFieldInput() : GeometryFieldInput(CPPType::get<int>(), "Spline Point Count")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &scope) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
||||||
|
return construct_spline_count_gvarray(curve_component, domain);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
|
||||||
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
|
||||||
return construct_spline_count_gvarray(curve_component, domain, scope);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,8 +85,7 @@ static Array<float3> curve_tangent_point_domain(const CurveEval &curve)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &component,
|
static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &component,
|
||||||
const AttributeDomain domain,
|
const AttributeDomain domain)
|
||||||
ResourceScope &UNUSED(scope))
|
|
||||||
{
|
{
|
||||||
const CurveEval *curve = component.get_for_read();
|
const CurveEval *curve = component.get_for_read();
|
||||||
if (curve == nullptr) {
|
if (curve == nullptr) {
|
||||||
@@ -118,27 +117,20 @@ static VArray<float3> construct_curve_tangent_gvarray(const CurveComponent &comp
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
class TangentFieldInput final : public fn::FieldInput {
|
class TangentFieldInput final : public GeometryFieldInput {
|
||||||
public:
|
public:
|
||||||
TangentFieldInput() : fn::FieldInput(CPPType::get<float3>(), "Tangent node")
|
TangentFieldInput() : GeometryFieldInput(CPPType::get<float3>(), "Tangent node")
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask UNUSED(mask),
|
const AttributeDomain domain,
|
||||||
ResourceScope &scope) const final
|
IndexMask UNUSED(mask)) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
||||||
|
return construct_curve_tangent_gvarray(curve_component, domain);
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
|
|
||||||
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
|
|
||||||
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
|
|
||||||
return construct_curve_tangent_gvarray(curve_component, domain, scope);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,44 +54,39 @@ static void select_mesh_by_material(const Mesh &mesh,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class MaterialSelectionFieldInput final : public fn::FieldInput {
|
class MaterialSelectionFieldInput final : public GeometryFieldInput {
|
||||||
Material *material_;
|
Material *material_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaterialSelectionFieldInput(Material *material)
|
MaterialSelectionFieldInput(Material *material)
|
||||||
: fn::FieldInput(CPPType::get<bool>(), "Material Selection node"), material_(material)
|
: GeometryFieldInput(CPPType::get<bool>(), "Material Selection node"), material_(material)
|
||||||
{
|
{
|
||||||
category_ = Category::Generated;
|
category_ = Category::Generated;
|
||||||
}
|
}
|
||||||
|
|
||||||
GVArray get_varray_for_context(const fn::FieldContext &context,
|
GVArray get_varray_for_context(const GeometryComponent &component,
|
||||||
IndexMask mask,
|
const AttributeDomain domain,
|
||||||
ResourceScope &UNUSED(scope)) const final
|
IndexMask mask) const final
|
||||||
{
|
{
|
||||||
if (const GeometryComponentFieldContext *geometry_context =
|
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
|
||||||
dynamic_cast<const GeometryComponentFieldContext *>(&context)) {
|
return {};
|
||||||
const GeometryComponent &component = geometry_context->geometry_component();
|
|
||||||
const AttributeDomain domain = geometry_context->domain();
|
|
||||||
if (component.type() != GEO_COMPONENT_TYPE_MESH) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
|
||||||
const Mesh *mesh = mesh_component.get_for_read();
|
|
||||||
if (mesh == nullptr) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (domain == ATTR_DOMAIN_FACE) {
|
|
||||||
Array<bool> selection(mask.min_array_size());
|
|
||||||
select_mesh_by_material(*mesh, material_, mask, selection);
|
|
||||||
return VArray<bool>::ForContainer(std::move(selection));
|
|
||||||
}
|
|
||||||
|
|
||||||
Array<bool> selection(mesh->totpoly);
|
|
||||||
select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
|
|
||||||
return mesh_component.attribute_try_adapt_domain<bool>(
|
|
||||||
VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain);
|
|
||||||
}
|
}
|
||||||
|
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
|
||||||
|
const Mesh *mesh = mesh_component.get_for_read();
|
||||||
|
if (mesh == nullptr) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domain == ATTR_DOMAIN_FACE) {
|
||||||
|
Array<bool> selection(mask.min_array_size());
|
||||||
|
select_mesh_by_material(*mesh, material_, mask, selection);
|
||||||
|
return VArray<bool>::ForContainer(std::move(selection));
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<bool> selection(mesh->totpoly);
|
||||||
|
select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection);
|
||||||
|
return mesh_component.attribute_try_adapt_domain<bool>(
|
||||||
|
VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user