Struggling with FFD - [FFDOBJECT_SIZE]



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 03/08/2011 at 14:19, xxxxxxxx wrote:

    Hi guys. I can't change the Grid size of an FFD sucessfully via python.
    When I do, the values in the attribute manager change, but the FFD itself doesn't.
    Obviously, I need to do something additional to make this change work but I'm not sure what or where.
    Think it might be in BaseList2D.Message() but I have no idea how to use this and no example is provided.

    To see my problem, add an ffd in cinema, drag it to the console and type:

    FFD[FFDOBJECT_SIZE] = Vector(10,10,10)

    for example. You see the attribute manager values change but the deformer doesn't update.
    Any pointers would be great.
    Thanks for your time.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 03/08/2011 at 15:43, xxxxxxxx wrote:

    Here's an example:

    import c4d  
    from c4d import gui  
      
    def main() :  
        obj = doc.GetActiveObject()                    #Assigns the FFD to a variable  
        obj[c4d.FFDOBJECT_SIZE]= c4d.Vector(10,10,10) #Sets the GridSize  
        obj.Message(c4d.MSG_UPDATE)                    #Updates the object changes   
        c4d.EventAdd()                                 #Tells C4D that something has changed  
      
    if __name__=='__main__':  
        main()
    

    You almost always need to use c4d.EventAdd() in order to get a proper update to your code. So you'll see it in just about every script. It tells C4D that something has changed. So do a refresh.

    In this case. obj.Message(c4d.MSG_UPDATE) isn't absolutely needed.  But it is needed in some cases when doing things like moving the individual verts. of an object or spline around.

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 04/08/2011 at 00:57, xxxxxxxx wrote:

    Thanks for your reply ScottA.
    I should have said, I normally would use an EventAdd() in the code.
    Unfortunately, your code still does the same thing.
    If you copy it to your python script manager and exexute it, you will see that the FFD does not update, even though the grid size values change.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 04/08/2011 at 08:36, xxxxxxxx wrote:

    Sorry about that. I could have sworn it worked yesterday when I tried it.

    Looks like it might a bug. Because it works properly in coffee:

    var obj = doc->GetActiveObject();  
    obj#FFDOBJECT_SIZE= vector(10,10,10); 
    

    *Shrug*

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 04/08/2011 at 09:37, xxxxxxxx wrote:

    BTW.
    Here's how to scale an object's matrix:

    #Python version to scale an object's matrix  
      
    import c4d  
    from c4d import gui  
      
    def main() :  
      m = op.GetMg()  
      scale = c4d.Vector(m.v1.GetLength()+.3,  #Change number as needed   
                     m.v2.GetLength()+.3,      #Change number as needed   
                     m.v3.GetLength()+.3)      #Change number as needed   
      
      m.v1 = m.v1.GetNormalized() * scale.x  
      m.v2 = m.v2.GetNormalized() * scale.y  
      m.v3 = m.v3.GetNormalized() * scale.z  
      op.SetMg(m);  
      
      c4d.EventAdd()  
      
    if __name__=='__main__':  
      main()
    

    Maybe that will bail you out until they fix it?

    -ScottA



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 05/08/2011 at 00:53, xxxxxxxx wrote:

    Thanks for that Scott, I'll have a play with it when I get time, might work as a work around.
    If anyone from maxon could confirm if its a bug or a gap in my knowledge that would be great.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 20/08/2011 at 08:13, xxxxxxxx wrote:

    Hi Scott, I tried scaling the matrix but the FFD doesn't work properly when its non-uniformly scaled.
    Unfortunately I can't use CallCommand with Reset Scale because it has a dialogue and I don't want the user to have to use it.
    Do you know of a way to scale the FFDs points without affecting the object scale, or a way to correct it after ?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 20/08/2011 at 10:20, xxxxxxxx wrote:

    ASFAIK. The only way to change the scale of the FFD without changing the scale of the mesh is to use Model Tool Mode when changing it.
    I did some checking using GetCache on the FFD deformer.
    The container cache is updating properly. Which is why the values change properly in the attributes.
    But the matrix cache always returns None. So that's probably why scale is not working properly.

    I'm not seeing any problems when I scale the matrix by hand to a non uniform scale.
    I'm just testing it on a cube. And when I change the size of the matrix to something like 390,330,300 the FFD still deform the cube as expected.:

    import c4d  
    from c4d import gui  
      
    def main() :  
      m = op.GetMg()  
      scale = c4d.Vector(m.v1.GetLength()+.3,       #Sets FFD X size to 390  
                     m.v2.GetLength()+.1,              #Sets FFD Y size to 330  
                     m.v3.GetLength()+0)               #Leaves FFD Z size at default(300)  
      
      m.v1 = m.v1.GetNormalized() * scale.x  
      m.v2 = m.v2.GetNormalized() * scale.y  
      m.v3 = m.v3.GetNormalized() * scale.z  
      op.SetMg(m);  
      
      c4d.EventAdd()  
      
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 18/01/2013 at 07:14, xxxxxxxx wrote:

    Hi,

    I up this topic because I faced the same problem, and it seems to still be a bug in R14.
    I notice that the PointTag isn't correctly updated when you set the FFD size via Python.

    Here the solution I found :

    1. Get the Point Tag (c4d.Tpoint)
    2. Get Point tag data : pointTag.GetAllHighlevelData()
    3. Multiply each point position by the scale factor (newSize / currentSize)

    point.x *= newSize.x / currentSize.x

    4. Set the FFD size : ffd[c4d.FFDOBJECT_SIZE] = size

    I hope this will be useful for someone.



  • On 18/01/2013 at 10:36, xxxxxxxx wrote:

    Can you please post an example?
    Because I don't understand where you're getting the newSize.x & currentSize.x values from.

    Example:

    import c4d  
    def main() :  
      obj = doc.GetActiveObject()                #Assigns the FFD to a variable      
      count = obj.GetPointCount()                #The number of points in the deformer  
      
      tag = obj.GetTag(c4d.Tpoint)               #Get the deformer's default(hidden) point tag  
      pd = tag.GetAllHighlevelData()             #The vector positions of each point in the deformer  
      
      for i in xrange(0, count) :  
          pd[i].x *= 100 / 300                #<----- newSize.x / oldSize.x ?  
      
      obj[c4d.FFDOBJECT_SIZE] = c4d.Vector(100,300,300)  #<----Still does not work!  
      
      obj.Message(c4d.MSG_UPDATE)                #Updates the object changes  
      c4d.EventAdd()                             #Tells C4D that something has changed  
      
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 18/01/2013 at 10:53, xxxxxxxx wrote:

    Here an example :

    import c4d   
      
    def setFFDSize(ffd, size) :   
        tag = ffd.GetTag(c4d.Tpoint)   
        points = tag.GetAllHighlevelData()   
        oldSize = ffd[c4d.FFDOBJECT_SIZE]   
        scaleFactor = c4d.Vector(size.x / oldSize.x, size.y / oldSize.y, size.z / oldSize.z)   
        for i, point in enumerate(points) :   
            points[i].x *= scaleFactor.x   
            points[i].y *= scaleFactor.y   
            points[i].z *= scaleFactor.z   
        tag.SetAllHighlevelData(points)   
        ffd[c4d.FFDOBJECT_SIZE] = size   
      
        ffd.Message(c4d.MSG_UPDATE)      
           
      
    def main() :   
        setFFDSize(doc.GetActiveObject(), c4d.Vector(1200, 350, 100))   
        c4d.EventAdd()                       
      
    if __name__=='__main__':   
        main()
    


  • On 18/01/2013 at 11:03, xxxxxxxx wrote:

    You just forgot to set the data :

    tag.SetAllHighlevelData(pd)
    


  • On 18/01/2013 at 11:29, xxxxxxxx wrote:

    Got it.
    Thanks for posting your solution. 👍

    -ScottA



  • On 20/01/2013 at 14:55, xxxxxxxx wrote:

    Hi XSYANN, thanks for posting this workaround, annoying that they never fixed it properly yet. I even reported the bug to maxon tech support.
    My original intention was to write a plugin for adding deformers correctly sized & orientated to the selected objects.
    I got quite far without finishing it. Since then, Marc Pearson has written py-deform which supports everything apart from the ffd, for this reason (I spoke with him in a thread about it).
    I think I'll give him a heads up that there is a workaround.
    Thanks for both of your help on this.


Log in to reply