Page MenuHome

Geometry Nodes: Add Nodes to Get/Set Built-in Attributes
ClosedPublic

Authored by Johnny Matthews (guitargeek) on Sep 29 2021, 4:43 AM.

Details

Summary

This is an implementation of T91780

Input Nodes

  • Radius
  • Curve Tilt
  • Curve Handle Positions
  • Is Shade Smooth
  • Spline Resolution
  • Is Spline Cyclic

'Set' Nodes

  • Curve Radius
  • Point Radius
  • Curve Tilt
  • Curve Handle Positions
  • Is Shade Smooth
  • Spline Resolution
  • Is Spline Cyclic

Diff Detail

Repository
rB Blender

Event Timeline

Johnny Matthews (guitargeek) requested review of this revision.Sep 29 2021, 4:43 AM
Johnny Matthews (guitargeek) created this revision.
Hans Goudey (HooglyBoogly) requested changes to this revision.Sep 29 2021, 6:24 AM

A good start! I think rather than being implicit fields, all of the value inputs except for the handle positions should be regular supports_field() inputs, so that you can just enter a value directly into the node.

Besides that, we'll need to decide on categories for the input nodes, I'm not quite sure what's best currently.

source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc
29–30

I just committed a constructor for making creating an AttributeFieldInput a bit simpler. This can just look like AttributeFieldInput::Create<float3>("handle_left") now.

source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
68–69

This can use attribute_try_get_for_output_only, which doesn't bother retrieving the current values if the attribute isn't stored as an array. It also means you don't have to supply the default value here.

Same applies for the other "Set" nodes.

86–87

This could be simplified a bit to not use the for loop. Same with the other nodes that only work on one component.

source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
54–60

Since it's working on point clouds too, the node name probably shouldn't include "curve"

This revision now requires changes to proceed.Sep 29 2021, 6:24 AM

Oh, also, the "set" code should be nested in geometry_set.modify_geometry_set([&](GeometrySet &geometry_set) {...
That way the nodes can act on instances as well, and even instances nested in other instances, etc.

Johnny Matthews (guitargeek) marked 4 inline comments as done.
Johnny Matthews (guitargeek) edited the summary of this revision. (Show Details)

Use AttributeFieldInput::Create in input files
Use attribute_try_get_for_output_only in set files
Cleanup Loops
Remove curve name from radius
Use geometry_set.modify_geometry_sets()

Jacques Lucke (JacquesLucke) requested changes to this revision.Sep 29 2021, 3:20 PM
  • The Set Radius node shows up twice in the search.
  • The default radius should be e.g. 0.1.
  • Set Spline Resolution node should show an info when the input contains only poly splines.
  • Think the Shade Smooth node should be renamed to Is Shade Smooth.
  • Similarly with the Spline Cyclic node. Is Spline Cyclic sounds better to me.
  • The Set Curve Handle Position node crashes for me, probably because the spline type isn't correct.
This revision now requires changes to proceed.Sep 29 2021, 3:20 PM
  • The Set Radius node shows up twice in the search.

I think this is because what I suggested, adding the node to both categories. So looks like that won't work here.
Maybe we could use separate "Set Point Radius" and "Set Curve Radius" nodes? That would help the defaults too actually, for point clouds, 0.05m is usually the default, but for curves something like 1m probably makes more sense.


Also, the set handle position node could use a bit of special behavior with handle types that we couldn't do easily before. It could change them for the selected points like we do in edit mode:

  • Vector -> Free
  • Auto -> Align

I think this is because what I suggested, adding the node to both categories. So looks like that won't work here.

Think we can also just fix the search so that it doesn't add the same node twice with the same props.

Ok, I'm fine with having two nodes for the radius.

Johnny Matthews (guitargeek) edited the summary of this revision. (Show Details)

The Set Radius was split into two, one for curve and one for point
Set Spline Resolution node shows an info when the input contains only poly splines.
Shade Smooth node is renamed to 'Is Shade Smooth.'
The Spline Cyclic node is renamed to 'Is Spline Cyclic'
Curve Handle Position is working with new commit of exposed attributes
Curve Handle Position also works like edit mode where changing the position of a vector handle makes it free and changing an auto makes it aligned.

Jacques Lucke (JacquesLucke) requested changes to this revision.Sep 30 2021, 6:56 PM
  • Still crashes when I pass a poly spline into the Set Curve Handle Positions node as in the screenshot below.
  • If we go with the Set Curve Handle Positions node, it should be a bit wider so that the name fits in the header.

source/blender/nodes/NOD_static_types.h
379

typo (Sahde)

source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
26 ↗(On Diff #42701)

Minimum should be zero.

source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc
33

Should be a bool field. This hits an assert in a debug build.

This revision now requires changes to proceed.Sep 30 2021, 6:56 PM

Personally I don't think "Curve" is necessary in "Set Curve Handle Positions", since it's already in the curve category.

source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc
27

This can use PROP_ANGLE, as a hint that tilt is an angle for rotation about the tangent.

  • "Set Node Handles" skips Curves that do not contain a Bezier and give an info warning in this case.
  • Changed "Set Curve Handle Positions" name to "Set Handle Positions".
  • Set PROP_ANGLE for tilt.
  • Typos, Min values, etc.
Hans Goudey (HooglyBoogly) requested changes to this revision.Sep 30 2021, 8:59 PM

Some "set" nodes are missing the "modify_geometry_sets" nesting.

source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc
31

Marking this as "implicit_field" doesn't do quite enough, MOD_nodes_evaluator needs to be modified to input the right or left field.

78

I think it's better to keep it a reference, since we don't expect it to be null: BezierSpline &bezier = static_cast<BezierSpline &>(*spline);

103
/home/hans/Blender-Git/blender/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc: In function ‘void blender::nodes::set_position_in_component(GeometryNodeCurveHandleMode, GeometryComponent&, const blender::fn::Field<bool>&, const blender::fn::Field<blender::float3>&)’:
/home/hans/Blender-Git/blender/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc:102:16: warning: unused variable ‘i’ [-Wunused-variable]
  102 |       for (int i : spline->positions().index_range()) {
      |                ^
130

This should be initialized to false.

source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
61–62

This only works on curves now, so no need for the loop.

source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc
60–61 ↗(On Diff #42735)

This should only work on point clouds now.

source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
20

No need for semicolon here.

This revision now requires changes to proceed.Sep 30 2021, 8:59 PM

All "set" nodes use "modify_geometry_sets" nesting.
Set Handle Position Implicit fields set correctly
Other small fixes

The radius input node should just be called "Radius", since it works with point clouds too. Other than that and my inline comment, this looks good to me.

source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc
27

This could have a min of 0

Minimum for curve set radius

The Curve Handle Positions node should be a bit wider by default, so that the name fits in the header.

Do we have a rule for when the term "Curve" and when "Spline" is used?

The Set Spline Cyclic node has a different name in the search vs node header.

Do we have a rule for when the term "Curve" and when "Spline" is used?

I've tried to make it when it specifically pertains to the spline domain to use spline, otherwise use curve.

Johnny Matthews (guitargeek) edited the summary of this revision. (Show Details)

Fix naming
Make Handle Position node NODE_SIZE_MIDDLE instead of default

I'd like to get an okay for this tomorrow, but I think it might be clearer if the input nodes are also in their corresponding categories, but with separators like this:

def curve_node_items(context):
    if context is None:
        return
    space = context.space_data
    if not space:
        return
    if not space.edit_tree:
        return

    if geometry_nodes_legacy_poll(context):
        yield NodeItem("GeometryNodeLegacyCurveSubdivide")
        yield NodeItem("GeometryNodeLegacyCurveReverse")
        yield NodeItem("GeometryNodeLegacyCurveSplineType")
        yield NodeItem("GeometryNodeLegacyCurveSetHandles")
        yield NodeItem("GeometryNodeLegacyCurveSelectHandles")
        yield NodeItem("GeometryNodeLegacyMeshToCurve")
        yield NodeItem("GeometryNodeLegacyCurveToPoints")
        yield NodeItem("GeometryNodeLegacyCurveEndpoints")

    yield NodeItem("GeometryNodeCurveToMesh")
    yield NodeItem("GeometryNodeCurveResample")
    yield NodeItem("GeometryNodeCurveFill")
    yield NodeItem("GeometryNodeCurveTrim")
    yield NodeItem("GeometryNodeCurveLength")
    yield NodeItem("GeometryNodeCurveSplineType")
    yield NodeItem("GeometryNodeCurveSubdivide")
    yield NodeItem("GeometryNodeCurveSample")
    yield NodeItem("GeometryNodeCurveFillet")
    yield NodeItem("GeometryNodeCurveReverse")
    yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
    yield NodeItem("GeometryNodeCurveParameter")
    yield NodeItem("GeometryNodeCurveHandleTypeSelection")
    yield NodeItem("GeometryNodeInputTangent")
    yield NodeItem("GeometryNodeInputCurveTilt")
    yield NodeItem("GeometryNodeInputCurveHandlePositions")
    yield NodeItem("GeometryNodeInputSplineResolution")
    yield NodeItem("GeometryNodeInputSplineCyclic")
    yield NodeItem("GeometryNodeSplineLength")
    yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
    yield NodeItem("GeometryNodeSetCurveRadius")
    yield NodeItem("GeometryNodeCurveSetHandles")
    yield NodeItem("GeometryNodeSetCurveTilt")
    yield NodeItem("GeometryNodeSetCurveHandlePositions")
    yield NodeItem("GeometryNodeSetSplineResolution")
    yield NodeItem("GeometryNodeSetSplineCyclic")
source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc
29

The default here could be 12 for consistency.

Split out Curve, Mesh and Point menus
Reorganize Menus / Add separators
Set a default

I like the separators, it makes things clearer. IMO the input category also needs this to separate nodes like Position Normal Index from nodes like Object Info Collection Info etc. But this perhaps is more relevant to T91542

I just fixed merge conflicts in this patch, so I'll commit it. Thanks for the work Johnny. I think the code is pretty straightforward, and it's consistent with what we discussed before, so I'm removing Jacques as a blocking reviewer.

This revision is now accepted and ready to land.Oct 11 2021, 5:46 PM