Page MenuHome

Geometry Nodes: Relaxed Catmull-Rom Trim (improvement suggestion)
Needs ReviewPublic

Authored by Mattias Fredriksson (Osares) on Sep 25 2022, 10:23 PM.

Details

Summary

Plausible improvement to current behavior for trimming of a Catmull-Rom spline. Instead of simply setting the endpoint of the curve to the trimmed point it relaxes the neighboring control point to avoid looping the segment as the trim point approaches the control point (see behavior in the gif below).

Problem description

Trimming a Catmull-Rom spline without discretization or conversion to Bezier form is not really possible since the influence from neighboring control points to the trimmed segment is constant. Using the current behavior where endpoints has multiplicity of 2 the last segment starts to form a loop as the endpoint approaches the neighboring control point (see gif). This occur due to the segment approaching a point on the line defined by the two neighboring control points to the curve endpoint as the endpoint approaches it's neighbor. This point (or 'extrema') can be found by evaluating the spline segment at t = 1/3 (or 2/3 depending where the endpoint/multiplicity lies) as it is the point where the influence for the second neighbor reaches it's maxima.

Solution

The curve is 'relaxed' by moving the neighboring control point toward t = 1/3 (or 2/3) within the neighboring segment. This value is not strictly related to the maximum for the influence but is related to it. Once the trim point passes the endpoint the relaxed point is removed rather then the endpoint causing the curve the snap back.

Relaxed Trim


Relaxed Trim, control points are visualized with a point cloud geometry. Original (cyclic) curve including a split copy of it is also displayed.

Current behavior


Current behavior, control points are visualized with a point cloud geometry. Original (cyclic) curve including a split copy of it is also displayed.

Limitations

Animating the behavior causes the behavior to curve to snap back as the trim point passes over a control point (see gif), current behavior causes a similar behavior as the spline no longer bends toward it's extrema.

This is just a suggested improvement to current behavior based on my understanding of current desired behavior.

Other plausible solutions

Change the Catmull-Rom endpoint behavior to not be multiplicity of 2. Trimming Catmull-Rom splines would still be approximations but behavior could likely be improved further.

Conversion to Bezier form (https://link.springer.com/article/10.1007/s42979-021-00770-x). To my current understanding conversion is not preferred behavior due to compute cost/type change as discretization was not desired in D14481.

Diff Detail

Repository
rB Blender
Branch
catmull_rom_trim (branched from master)
Build Status
Buildable 23929
Build 23929: arc lint + arc unit

Event Timeline

Mattias Fredriksson (Osares) requested review of this revision.Sep 25 2022, 10:23 PM
Mattias Fredriksson (Osares) created this revision.
  • Correction to IndexRangeCyclic asserts.
  • Added const to input arguments, added overloads instead of n = 1 default args
Mattias Fredriksson (Osares) retitled this revision from Relaxed Catmull-Rom Trim to Relaxed Catmull-Rom Trim (plausible improvement).Sep 26 2022, 12:08 AM
Mattias Fredriksson (Osares) edited the summary of this revision. (Show Details)
Mattias Fredriksson (Osares) edited the summary of this revision. (Show Details)
Mattias Fredriksson (Osares) retitled this revision from Relaxed Catmull-Rom Trim (plausible improvement) to Geometry Nodes: Relaxed Catmull-Rom Trim (improvement suggestion).Sep 26 2022, 12:13 AM

Based on the description, I liked the idea. However, testing this with the Add > Curves > Random primitive (with experimental option "New Curve Tools" enabled), I don't really like the results more in practice. When dragging the slider, I'm noticing a lot more jumping than before.

I wonder if it's preferable to make sure it's possible to accomplish something like this after the trim process.
Or maybe it needs to be an option, because the results are better sometimes as well. It's just a bit hard to justify that without seeing people complain about the existing behavior.

Sampling within segments, interpolating, etc. seems like something to pursue more generally anyway. That makes me thing that it might be helpful to think about how the trim node could be split up to smaller components for this sort of behavior.
I do think that this is preferable to converting to Bezier curves implicitly, at least as a default. Otherwise people will end up paying for that later without realizing it. If this imperfect sampling is really bothering people, they can resample or convert the curves beforehand (though that does have a performance cost).

In short, I'm intrigued, but not totally convinced, and I think there's some opportunity to find a more general design here.

source/blender/blenkernel/BKE_curves_utils.hh
163

I think it's clearer to call member functions with this-> in front, that's typically done elsewhere too.

Based on the description, I liked the idea. However, testing this with the Add > Curves > Random primitive (with experimental option "New Curve Tools" enabled), I don't really like the results more in practice. When dragging the slider, I'm noticing a lot more jumping than before.

Yes the snapping/jumping is a bit more obvious so for animation purposes I suppose it would be worse. Experimented a bit with other approaches and there was another approach that was intriguing where you shift the trim point toward the line intersecting the two neighboring points since once you have formed a line one can add/remove points however one wants. The issue with such an approach was that the trim point isn't really following the curve (which might be unintuitive) and one ends up with a linear segment which isn't really a natural or nice shape. On the positive side you could actually avoid jumping/snapping behavior as one is removing the point from a linear segment and the shape remains the same.

Thought about adding/removing multiple points but the issue with doing that is you essentially are:

a) Likely changing the shape of multiple segments.
b) At some point you are adding removing points and you end up with the same problem you started with but you are just doing it somewhere else.

In the end I thought this behavior was good because I thought the primary use case for this would be for hair in which case this method seemed the cheapest and best solution as long one is not considering animating the trim effect. But if animating the trim effect is of interest I think we should consider implementing a node for converting from Catmull-Rom -> Cubic Bezier as that seems like the proper solution rather then trying to invent some heuristic solution better then this one. Because I think the output curve is always better which I think is the issue with the current solution in certain cases the output is just bad. But this approach will be unintuitive for some as the curve jumps/snaps, but it already does that in but it could be 'more intuitive' when it hapends?

That makes me thing that it might be helpful to think about how the trim node could be split up to smaller components for this sort of behavior.

Could be possible but most likely such a node would impact more points on the curve then just the endpoints since it would have to be more general.