Post Deformer Spline



  • Hello!

    I'm currently messing around with the final output of a Spline Object affected by a deformer.

    I'm trying to get the Spline Object, post-deformed, not the Line Object. So in the case of the Circle spline I would expect four points to be returned with tangents, instead of a linear sixty-eight point Line Object.

    I'm aware of the Cache and DeformCaches and I don't think either of those give me what I'm looking for.

    As an example of what I'm talking about. The deform cache would appear like this as I understand it.

    Deformer.png

    This looks to me like the Line Object of the Spline that is then deformed through the Bend Object.

    When I use a Matrix object setup to match the vertexs of the Circle though, it returns four points, not the sixty-eight points of the Deformed Cache and they are in the correct place on the deformed spline.

    Matrix.png

    I'm using the Matrix Object to illustrate that it seems to be possible to get the Spline Points post deformer as opposed to the Line Points post deformer.

    Is it possible to get the Spline Object in this circumstance or am I stuck with just retrieving the Line Object from the deform cache? Thanks for any help!

    Dan



  • hi,

    it's even more straight forward than what i though.

    use SPLINEHELPFLAGS_USERDEFORMERS when you init your splinehelper and you just need to ask the matrix of the corresponding point.

    import c4d
    #Welcome to the world of Python
    
    
    def main():
        spline = op[c4d.ID_USERDATA,1]
        splineIndex = 2
        shelp = c4d.utils.SplineHelp()
        if not shelp.InitSplineWith(spline, c4d.SPLINEHELPFLAGS_GLOBALSPACE | c4d.SPLINEHELPFLAGS_CONTINUECURVE | c4d.SPLINEHELPFLAGS_USERDEFORMERS):
            return
        
        lineIndex = shelp.SplineToLineIndex(splineIndex)
        orienttMat = shelp.GetVertexMatrix(lineIndex)
        
      
        obj = op.GetObject()
        
        obj.SetMg(orienttMat)
    

    You just need to iterate for each point of the original spline and convert them to the deformed position.

    Cheers,
    Manuel



  • Hi,

    I do not quite understand what you are trying to do. I might be misunderstanding you, but:

    1. If you want the spline parameters (i.e. its vertices and tagents), they are attached to the SplineObject.
    2. To arbitrarily deform a parametric spline, you have to quantise it, because a cubic spline patch (i.e. two vertices and two control points) is bound to the cubic polynomial which is represented by said points, i.e. you simply cannot express more complex shapes in this patch without subdividing it.
    3. If you want to reinterpret a deformed linear spline as a bezier curve, Cinema has a spline fitting function. But I do not see the point in doing this, because it would just add a lot of noise.
    4. If you just want to find the offsets for the vertices of the parametric spline on the deformed linear spline, you could use SplineHelp and SplineLengthData. Alternatively you could do it by hand, but the arc-length parameterization is probably a can of worms that I did not want to open if avoidable.

    Long story short: You cannot arbitrarily deform a parametric spline.

    Cheers.
    zipit



  • hi,

    as @zipit said, it's not possible.
    The deformer is working with the cache of the spline witch is already the line object (with lost of points)

    Cheers,
    Manuel



  • @m_magalhaes @zipit Thank you for the replies!

    That all mostly makes sense to me. I'm only really confused about why the Matrix object seems to be able to track the original spline points. Is it just placing a point along the same percentages of the spline as before the spline is deformed?

    Dan



  • hi,

    so sorry, i just looked at it and you are right.

    it's just using the SplineToLineIndex function from the SplineHelp.

    I did a quick test with python (without error check sorry)

    This function convert from the spline index to the line index. After that, just retrieve the deformed cache (on a spline you have to use a CSTO) and just retrieve the position of the deformed line.

    import c4d
    #Welcome to the world of Python
    
    
    def main():
        spline = op[c4d.ID_USERDATA,1]
        shelp = c4d.utils.SplineHelp()
        
        if not shelp.InitSplineWith(spline):
            return 
        
        lineIndex = shelp.SplineToLineIndex(1)
        
        tempDoc = c4d.documents.IsolateObjects(doc, [spline])
        newSpline = tempDoc.GetFirstObject()
        resultCSTO = c4d.utils.SendModelingCommand(command=c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[newSpline], doc=tempDoc)
        
        deformedSpline = resultCSTO[0]
        points = deformedSpline.GetAllPoints()
        obj = op.GetObject()
        obj.SetRelPos(points[lineIndex])
            
    

    Cheers,
    Manuel



  • hi,

    it's even more straight forward than what i though.

    use SPLINEHELPFLAGS_USERDEFORMERS when you init your splinehelper and you just need to ask the matrix of the corresponding point.

    import c4d
    #Welcome to the world of Python
    
    
    def main():
        spline = op[c4d.ID_USERDATA,1]
        splineIndex = 2
        shelp = c4d.utils.SplineHelp()
        if not shelp.InitSplineWith(spline, c4d.SPLINEHELPFLAGS_GLOBALSPACE | c4d.SPLINEHELPFLAGS_CONTINUECURVE | c4d.SPLINEHELPFLAGS_USERDEFORMERS):
            return
        
        lineIndex = shelp.SplineToLineIndex(splineIndex)
        orienttMat = shelp.GetVertexMatrix(lineIndex)
        
      
        obj = op.GetObject()
        
        obj.SetMg(orienttMat)
    

    You just need to iterate for each point of the original spline and convert them to the deformed position.

    Cheers,
    Manuel



  • @m_magalhaes said in Post Deformer Spline:

    Thanks, Manuel! This is what I was looking for!


Log in to reply