Linking something to a handle

  • Python, C4D R20

    Hi !
    I'd like to know if it's possible to get the position of a handle from a bend or twist object.

    alt text

    I fear that these handles only exists when the object is selected, if so, I don't think linking this handle to follow an object is possible... or is it ?

  • In the SDK example file roundedtube.cpp, you can see how handles are used. Here, the values from handles are stored in the object's BaseContainer. Of course, you can also store it in class members (make sure to override CopyTo() and the other related functions).
    It should not be a problem to access those values, either via the container or via custom Get()/Set() functions.

    EDIT: Oh wait, you want it specifically for those two objects? In that case, you might be able to call those objects' NodeData's GetHandle() function and then find the position in the HandleInfo struct.


  • Hello Flavio,

    I'm not completely sure what exactly you would like to achieve.

    Indeed a handle's position is handled internally inside of generator objects and can not be accessed from outside. But in this case (at least for the use-cases I can imagine) I see no need to retrieve the handles position directly as it is implicitly defined by the parameters of the deformer object (Twist and Bend parameter: Angle (DEFORMOBJECT_ANGLE) and Bend parameter: Strength (DEFORMOBJECT_STRENGTH)).

    For the Bend deformer:
    The angle defines the angle between the X-axis of the deformer and the handle. And the strength parameter is the length of the handle or thew distance of the handle to the deformer's origin.

    For the Twist deformer:
    It's a bit different as the angle parameter actually is translated into the length of the handle.

    I hope this helps,

  • Thanks @fwilleke80 and @a_block :^)
    Sorry if I was unclear about what my question was, maybe my question is not that appropriate to Plugincafe, since it's not too related to making a plugin, but to make a simple rig with a bend and a null object. Maybe I should have posted in C4Dcafe .. I don't know 😬

    In short, my intention was to link the handle of a bend to a null, so I can move the null and affect the bend:

    alt text

    I know it's possible to do it with xpresso (in this case, the handle isn't attached to the null, but matematically in the same position... ), but I was curious if it's possible to do with python too!

    thanks 😁

  • Hi Flavio,

    no, worries, as long as at least a little bit of scripting is involved, this forum is the correct place. Even if it's about translating Xpresso to Python for learning purposes.

    @fwilleke80: you might be able to call those objects' NodeData's GetHandle() function

    Frank's suggestion won't work in Python (while certainly being an optin in C++), as there are no means to get the NodeData belonging to a deformer's BaseObject.

    I assume, the code you show in the screen recording is in the Python tag on the "Finger" Null object?
    There are a few things to consider:

    1. You simply wrote your code into a function gethandle() without calling this function. You can not expect C4D to call this arbitrary function.
    2. A tag (or expression) must only modify its host object (please leave aside Xpresso tags, e.g. the object nodes there contain special code to make an exception from this rule). So the Python tag should be placed on the Bend deformer.
    3. The "Control" Null object can move freely in 3D space, while the handle can not. So, you'd either need to also constrain the Null object in some way or live with the fact that the Null can move away from the handle in Y axis.

    With all this said, a very simply version of a Python tag's code could look like so (ignoring the fact the Null can be moved away in Y axis):

    import c4d, math
    def main():
        # Somehow get the control object
        # In this example it's simply the first object,
        # but it could also come from e.g. a user data parameter (type Link)
        opControl = doc.GetFirstObject()
        # Get the host object of the Python tag (the Bend deformer)
        opBend = op.GetObject()
        # Get the position of the Bend deformer and the controlling Null object
        mgBend = opBend.GetMg()
        offBend =
        mgControl = opControl.GetMg()
        offControl =
        # diff is basically the position of the controlling Null in Bend deformer's local space
        diff = offControl - offBend
        diff.y = 0.0 # ignoring any differences in y direction in this example
        # calculate the strength and angle parameters
        strength = diff.GetLength() / (opBend[c4d.DEFORMOBJECT_SIZE].y  * 0.5)
        angle = c4d.utils.GetAngle(diff, c4d.Vector(1.0, 0.0, 0.0))
        if diff.z < 0.0:
            angle = 2.0 * math.pi - angle
        # set the parameters
        opBend[c4d.DEFORMOBJECT_STRENGTH] = strength
        opBend[c4d.DEFORMOBJECT_ANGLE] = angle



  • @a_block Nice!
    Thanks a lot for explaining very well and for explaining the good practices when using a python tag, I used to use it wrong many times !

    I'll certainly try to convert this script in to a plugin, since this rig is very popular in the studio I work.

    I'll post on GENERAL PROGRAMMING & PLUGIN DISCUSSIONS when its done :^)

    Thanks again!

  • Oh, one more thing I forgot. There's a slight difference between this thread's tags (saying you are dealing with R20) and your screen recording obviously showing some pre R20 version. In this case it probably does not matter much, but please consider providing infos as accurately as possible. In the end it helps us to help you faster.


  • Sorry @a_block !
    That's because I have R19 at home and R20 at the studio I work.

    But look the amazing result I got so far! it's almost done, I just need to test a little bit more to see if I find any bug and maybe implement some time saving utility.
    alt text

    Thanks again!

  • Nice, congrats ☺

    I have to admit, I forgot to turn this thread into a question. I did so now and I also marked it as solved, as your last post seems to imply.


Log in to reply