How to receive the high definition / Interpolation version of a spline?
-
How to receive the high definition version / Interpolation of a spline even when the user has set it to "low" detail?
How high definition can I get ? is there more than the user Interface of C4D offers ?E.g. Interpolation adaptive, angle 0.0
Or am I using c4d.utils.SplineHelp() wrong and there is a another helper that gives me requested amount of points from a spline?
helper = c4d.utils.SplineHelp() if not helper.InitSplineWith(spline, c4d.SPLINEHELPFLAGS_RETAINLINEOBJECT): raise RuntimeError("Could not initialize spline helper.") line = helper.GetLineObject() points = line.GetAllPoints()
cheers
mogh -
Hey @mogh,
Thank you for reaching out to us. What do you mean with "low" detail? Something like the sampling angle of a spline in "adaptive" mode? The interpolation settings of a spline only apply when you quantize it, i.e., the degree of precision with which a
SplineObject
is being quantized into itsLineObject
cache (i.e., what is returned forBaseObject.GetCache()
for a spline).Splines themselves are just series of polynomials and therefore have no inherent precision. So, when you call for example
SplineHelp.GetMatrix()
to get all the metadata for an offset, you are not subject to the interpolation settings. That is within the limits of what computers can do regarding arithmetic of irrational numbers. You can quite quickly get subject to floating point precision problems when working with splines. If they are fixable and how to fix them, depends on the concrete case.Cheers,
Ferdinand -
Ok I guess I have been vague what my issue is.
from the above helper I only get the points the spline is set to (eg. adaptive 5°) but I perhaps want more points in between. That of course only makes sense in certain scenarios but even though if the spline is a straight line there must be a solution to get points in between.
Example different adaptive degree values and the resulting points displayed as lines on the spline - Spline is a copy so no altering of the gizmos.
sorry to be so basic
mogh -
@mogh said in How to receive the high definition / Interpolation version of a spline?:
from the above helper I only get the points the spline is set to (eg. adaptive 5°) but I perhaps want more points in between.
That is not correct. As I said, splines have theoretically infinite precision, you are only bound in practice by the floating point precision you use for your computations - double, i.e., 64 bit in Cinema 4D. You get in your code just the cache of your spline and iterate over its points. That is more or less the same as if you would have just called
BaseObject.GetCache()
on yourSplineObject
which I mentioned above.When you want to interpolate your spline manually, you must use the interpolation methods of
SplineHelp
, e.g.,GetMatrix
, which is sort of the most potent of all, as it gives you a full frame for each sample (i.e., not just a point but also an orientation).I have a hunch that the actual question is how to build the cache of a spline as if it would have higher interpolation settings. And for that you should copy your input (unless it is already a dangling, i.e., non-inserted node), change its settings, insert it into a dummy document, and then call
ExecutePasses
on that document. Then you can get the cache, and iterate over its points.Cheers,
Ferdinandimport c4d doc: c4d.documents.BaseDocument # The currently active document. op: c4d.BaseObject | None # The primary selected object in `doc`. Can be `None`. def main() -> None: """Called by Cinema 4D when the script is being executed. """ if not op: return helper = c4d.utils.SplineHelp() if not helper.InitSplineWith(op, c4d.SPLINEHELPFLAGS_RETAINLINEOBJECT): raise RuntimeError("Could not initialize spline helper.") # Take exactly ten samples over the length of the spline, no matter how many vertices it has, # and how many points its current LineObject cache has. steps: int = 10 for i in range(steps + 1): # Get a frame for the offset #t. t: float = i/float(steps) m: c4d.Matrix = helper.GetMatrix(t) # Print the #t, the point #p on the spline, its normal #n, tangent #t, and bi-tangent #bt. print(f"{t = }, p = {m.off}, n = {m.v3}, t = {m.v1}, bt = {m.v2}") if __name__ == '__main__': main()
-
@ferdinand
Thank you for your answer, exactly what i need, I am trying to incorporate the additional data but get weird results.Is there a switch up /typo in the above code I get m.v3 <-> m.v1 ? meaning v1 is the normal ?
Is there a page in the SDK besides the "Matrix" one that explains the additional values and their features ?
Thank you for your Time.
mogh -
Hey @mogh,
that could be that I was wrong. But it was at least not an unintentional typo. That is how I remembered it and what is also usually the case in Cinema 4D. v3 is an alias for the k component of an i, j, k frame, i.e., the "z-axis". This is usually considered to be "the normal", i.e., when one constructs a frame, one makes it so that v3/k becomes the normal of what one is constructing that frame for. And to be verbose here, frame (of reference) is just some math slang for a coordinate system, i.e., what on a more general level is also called a "transform", or even more generic and how Cinema 4D handles it, a "matrix".
Bottom line is here, when v1 works for you as a normal, just use it, there is nothing which inherently makes k/v3 "the normal" of a frame. Maxime also touched spline transport some time ago, it could be that he switched things around.
There is only the Matrix Manual in Python, in C++ is nothing at all. Users are just supposed "to know" such stuff. I never find the time to do more than what I once did there. And just as warning, the normals of a spline are usually not what non-math people expect them to be, due to the fact that they are defined by curvature and that the concept of inflection points does exist. We once talked here about this, including an illustration.
That is why in CGI the normals of a spline are usually not the normals, but the parallel transport of some normal plus some upvector which determines the initial orientation. E.g.,
SplineHelp
realizes parallel transport, so that you can for example have an "outline" of a spline which makes sense for artists. But as you might have noticed in the past as a user, outlining a spline does not always produce results a human would consider correct. Just search for "parallel tranport" here on the forum and limit the results to my user, we talked many times about it, including code examples etc.So, long story short again, there is no mathematical way to compute the "perfect" normals for a spline, at least what humans consider this to be. And depending on the spline and the fanciness with which you implement parallel transport, you might be subject to normal banking and/or flipping issues. So,
SplineHelp
tries to give you normals/frames that humans would consider correct, but the quality of its efforts might vary.Cheers,
Ferdinand -
Ok Understood,
Ok I guess that explains my "nice" comb from the cache and my jagged flip/flop . sometimes zero comb from the "full" matrix normal ...
I also have different tangents from manually "calculating" them then v3, v2. But I will make a "sanity" check this weekend (feed manual matrixes into my code instead of spline "point" matrixes), before I post about this.
Thanks Ferdinand
I'll divide and conquer away.