Cleanup: Move curve length field input to blenkernel

To use in the geometry module when the resample curves code
is moved there (T97448).
This commit is contained in:
Hans Goudey 2022-05-05 12:41:36 +02:00
parent 18bcd8321a
commit be0417d690
5 changed files with 75 additions and 77 deletions

View File

@ -162,4 +162,14 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput {
bool is_equal_to(const fn::FieldNode &other) const override;
};
class CurveLengthFieldInput final : public GeometryFieldInput {
public:
CurveLengthFieldInput();
GVArray get_varray_for_context(const GeometryComponent &component,
AttributeDomain domain,
IndexMask mask) const final;
uint64_t hash() const override;
bool is_equal_to(const fn::FieldNode &other) const override;
};
} // namespace blender::bke

View File

@ -237,6 +237,69 @@ VArray<float3> curve_normals_varray(const CurveComponent &component, const Attri
return nullptr;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Curve Length Field Input
* \{ */
static VArray<float> construct_curve_length_gvarray(const CurveComponent &component,
const AttributeDomain domain)
{
if (!component.has_curves()) {
return {};
}
const Curves &curves_id = *component.get_for_read();
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
curves.ensure_evaluated_lengths();
VArray<bool> cyclic = curves.cyclic();
VArray<float> lengths = VArray<float>::ForFunc(
curves.curves_num(), [&curves, cyclic = std::move(cyclic)](int64_t index) {
return curves.evaluated_length_total_for_curve(index, cyclic[index]);
});
if (domain == ATTR_DOMAIN_CURVE) {
return lengths;
}
if (domain == ATTR_DOMAIN_POINT) {
return component.attribute_try_adapt_domain<float>(
std::move(lengths), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT);
}
return {};
}
CurveLengthFieldInput::CurveLengthFieldInput()
: GeometryFieldInput(CPPType::get<float>(), "Spline Length node")
{
category_ = Category::Generated;
}
GVArray CurveLengthFieldInput::get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const
{
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
return construct_curve_length_gvarray(curve_component, domain);
}
return {};
}
uint64_t CurveLengthFieldInput::hash() const
{
/* Some random constant hash. */
return 3549623580;
}
bool CurveLengthFieldInput::is_equal_to(const fn::FieldNode &other) const
{
return dynamic_cast<const CurveLengthFieldInput *>(&other) != nullptr;
}
} // namespace blender::bke
/** \} */

View File

@ -81,14 +81,4 @@ void separate_geometry(GeometrySet &geometry_set,
std::optional<CustomDataType> node_data_type_to_custom_data_type(eNodeSocketDatatype type);
std::optional<CustomDataType> node_socket_to_custom_data_type(const bNodeSocket &socket);
class CurveLengthFieldInput final : public GeometryFieldInput {
public:
CurveLengthFieldInput();
GVArray get_varray_for_context(const GeometryComponent &component,
AttributeDomain domain,
IndexMask mask) const final;
uint64_t hash() const override;
bool is_equal_to(const fn::FieldNode &other) const override;
};
} // namespace blender::nodes

View File

@ -535,7 +535,7 @@ static Field<int> get_curve_count_field(GeoNodeExecParams params,
auto get_count_op = std::make_shared<FieldOperation>(
FieldOperation(get_count_fn,
{Field<float>(std::make_shared<CurveLengthFieldInput>()),
{Field<float>(std::make_shared<bke::CurveLengthFieldInput>()),
params.extract_input<Field<float>>("Length")}));
return Field<int>(std::move(get_count_op));

View File

@ -4,71 +4,6 @@
#include "BKE_curves.hh"
namespace blender::nodes {
/* --------------------------------------------------------------------
* Spline Length
*/
static VArray<float> construct_curve_length_gvarray(const CurveComponent &component,
const AttributeDomain domain)
{
if (!component.has_curves()) {
return {};
}
const Curves &curves_id = *component.get_for_read();
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
curves.ensure_evaluated_lengths();
VArray<bool> cyclic = curves.cyclic();
VArray<float> lengths = VArray<float>::ForFunc(
curves.curves_num(), [&curves, cyclic = std::move(cyclic)](int64_t index) {
return curves.evaluated_length_total_for_curve(index, cyclic[index]);
});
if (domain == ATTR_DOMAIN_CURVE) {
return lengths;
}
if (domain == ATTR_DOMAIN_POINT) {
return component.attribute_try_adapt_domain<float>(
std::move(lengths), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT);
}
return {};
}
CurveLengthFieldInput::CurveLengthFieldInput()
: GeometryFieldInput(CPPType::get<float>(), "Spline Length node")
{
category_ = Category::Generated;
}
GVArray CurveLengthFieldInput::get_varray_for_context(const GeometryComponent &component,
const AttributeDomain domain,
IndexMask UNUSED(mask)) const
{
if (component.type() == GEO_COMPONENT_TYPE_CURVE) {
const CurveComponent &curve_component = static_cast<const CurveComponent &>(component);
return construct_curve_length_gvarray(curve_component, domain);
}
return {};
}
uint64_t CurveLengthFieldInput::hash() const
{
/* Some random constant hash. */
return 3549623580;
}
bool CurveLengthFieldInput::is_equal_to(const fn::FieldNode &other) const
{
return dynamic_cast<const CurveLengthFieldInput *>(&other) != nullptr;
}
} // namespace blender::nodes
namespace blender::nodes::node_geo_input_spline_length_cc {
static void node_declare(NodeDeclarationBuilder &b)
@ -136,7 +71,7 @@ class SplineCountFieldInput final : public GeometryFieldInput {
static void node_geo_exec(GeoNodeExecParams params)
{
Field<float> spline_length_field{std::make_shared<CurveLengthFieldInput>()};
Field<float> spline_length_field{std::make_shared<bke::CurveLengthFieldInput>()};
Field<int> spline_count_field{std::make_shared<SplineCountFieldInput>()};
params.set_output("Length", std::move(spline_length_field));