Geometry Nodes: Optimize start point case of Points of Curve node
In the node groups for T103730, the "Points of Curve" node is often used to retrieve the root point of every curve. Since the curve point offsets array already contains that data directly, we can detect this as a special case and avoid all the other work. Differential Revision: https://developer.blender.org/D17128
This commit is contained in:
parent
e99ae0a75d
commit
000e722c7d
Notes:
blender-bot
2023-09-09 19:17:09 +02:00
Referenced by pull request #112185, Fix #112184: Adapt optimized case of Points of Curve node for domain
Referenced by commit 3b44fd3655
, Fix #112184: Adapt optimized case of Points of Curve node for domain
|
@ -174,6 +174,57 @@ class CurvePointCountInput final : public bke::CurvesFieldInput {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The node is often used to retrieve the root point of the curve. If the curve indices are in
|
||||
* order, the sort weights have no effect, and the sort index is the first point, then we can just
|
||||
* return the curve offsets as a span directly.
|
||||
*/
|
||||
static bool use_start_point_special_case(const Field<int> &curve_index,
|
||||
const Field<int> &sort_index,
|
||||
const Field<float> &sort_weights)
|
||||
{
|
||||
if (!dynamic_cast<const fn::IndexFieldInput *>(&curve_index.node())) {
|
||||
return false;
|
||||
}
|
||||
if (sort_index.node().depends_on_input() || sort_weights.node().depends_on_input()) {
|
||||
return false;
|
||||
}
|
||||
return fn::evaluate_constant_field(sort_index) == 0;
|
||||
}
|
||||
|
||||
class CurveStartPointInput final : public bke::CurvesFieldInput {
|
||||
public:
|
||||
CurveStartPointInput() : bke::CurvesFieldInput(CPPType::get<int>(), "Point of Curve")
|
||||
{
|
||||
category_ = Category::Generated;
|
||||
}
|
||||
|
||||
GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
|
||||
const eAttrDomain /*domain*/,
|
||||
const IndexMask /*mask*/) const final
|
||||
{
|
||||
return VArray<int>::ForSpan(curves.offsets());
|
||||
}
|
||||
|
||||
uint64_t hash() const final
|
||||
{
|
||||
return 2938459815345;
|
||||
}
|
||||
|
||||
bool is_equal_to(const fn::FieldNode &other) const final
|
||||
{
|
||||
if (dynamic_cast<const CurveStartPointInput *>(&other)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/)
|
||||
{
|
||||
return ATTR_DOMAIN_CURVE;
|
||||
}
|
||||
};
|
||||
|
||||
static void node_geo_exec(GeoNodeExecParams params)
|
||||
{
|
||||
const Field<int> curve_index = params.extract_input<Field<int>>("Curve Index");
|
||||
|
@ -185,11 +236,16 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
ATTR_DOMAIN_CURVE)));
|
||||
}
|
||||
if (params.output_is_required("Point Index")) {
|
||||
params.set_output("Point Index",
|
||||
Field<int>(std::make_shared<PointsOfCurveInput>(
|
||||
curve_index,
|
||||
params.extract_input<Field<int>>("Sort Index"),
|
||||
params.extract_input<Field<float>>("Weights"))));
|
||||
Field<int> sort_index = params.extract_input<Field<int>>("Sort Index");
|
||||
Field<int> sort_weight = params.extract_input<Field<float>>("Weights");
|
||||
if (use_start_point_special_case(curve_index, sort_index, sort_weight)) {
|
||||
params.set_output("Point Index", Field<int>(std::make_shared<CurveStartPointInput>()));
|
||||
}
|
||||
else {
|
||||
params.set_output("Point Index",
|
||||
Field<int>(std::make_shared<PointsOfCurveInput>(
|
||||
curve_index, std::move(sort_index), std::move(sort_weight))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue