c4d.BaseTag.Remove() method negates all the changes I made from the object

  • Hi.

    You can see an illustration of the problem here:

    Without the .Remove() method, the script works as expected (i.e. the sphere snaps to the circle).
    When I add the .Remove Method. It no longer works. (i.e. the sphere no longer snaps to the circle)

    You can check the working code here:

    import c4d
    from c4d import gui
    def create_constraint(mo=False):
        obj_sel = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELECTIONORDER)
        driven = obj_sel[-1]
        driver = obj_sel[0]
        tag = c4d.BaseTag(1019364)
        tag[c4d.ID_CA_CONSTRAINT_TAG_PSR] = True
        if mo == True:
            tag[c4d.ID_CA_CONSTRAINT_TAG_PSR_MAINTAIN] = True
            tag[c4d.ID_CA_CONSTRAINT_TAG_PSR_MAINTAIN] = False
        tag[10001] = driver
    if __name__=='__main__':

    Thank you for looking at my problem

  • Okay, but what do you expect that script to do? You create a constraint - and then you throw the constraint away. Once you have thrown it away, it will no longer influence the scene and, naturally, do nothing.

    Do you perhaps assume that the influence of a constraint permanently alters the position of the affected object?

  • So, I checked that issue with a manual setup. I found that, indeed, removing an active PSR constraint will leave the affected object in the place where it was last. The original position is apparently lost.

    Unfortunately, I was not yet able to make the "live" version do what your script seems to be doing (restoring the original position), with neither option from the script.

    I can only guess that it has something to do with EventAdd() not being executed after the insertion. Will keep looking...

  • Ahyup. If you add the following line after setting the driver but before removing the tag:

    doc.ExecutePasses(None, True, True, True, c4d.BUILDFLAGS_0)

    then the affected object will stay where it is. I would assume the explanation is that between creating and deleting the tag, you didn't give Cinema 4D the chance to actually apply the tag to the object (to move it to the target position). ExecutePasses will enforce the evaluation of the tree and therefore the tag, reposition the target object, and then you can delete the tag again.

    EventAdd() doesn't seem to suffice here, as it only refreshes the GUI? I'll leave that for an actual Maxon person to explain ;-)

  • Hi bentraje, thanks for reaching out us.

    With regard to your request, be aware that call c4d.EventsAdd() just add an event to the Cinema 4D scene evaluation queue, but you're actually not granted this to be executed immediately. Rather different instead is to call c4d.BaseDocument.ExecutePasses() which instead has the direct effect to the have Cinema 4D immediately evaluating a scene.

    Finally assuming that the final intent was, as shown in the screen-recording, to align orientation of items in the scene why not taking advantage of BaseObject.SetMg() / BaseObject.GetMg()?

    Best, R

  • @Cairyn and @r_gigante

    Apologies for the late response.
    Yes, the ExecutePasses works as expected. Thanks for the solution.

    I can't use the SetMg()/GetMg() because the script is part of a larger base code which is not limited only to the PSR tag.

    Thanks again. Have a great day ahead!

Log in to reply