Solved BaseDocument.StartPickSession() Documentation

Hi,

I'm trying to work with doc.StartPickSession(callback, multi) and I'm running into some questions.

Trying this simple code...

import c4d
from c4d import gui

def OnPick(active, multi):
    print "active: ", active
    print "multi: ", multi

# Main function
def main():
    doc.StartPickSession(OnPick, multi=True)

# Execute main()
if __name__=='__main__':
    main()

I'm able to start a multi-object pick session, but once I double-click to complete it, I get this error:
TypeError: OnPick() takes exactly 2 arguments (3 given)

After a bit of detective work, it seems that adding a mystery variable to my callback function def OnPick(mystery, active, multi): fixes the error. When I run this:

import c4d
from c4d import gui

def OnPick(mystery, active, multi):
    print "mystery: ", mystery
    print "active: ", active
    print "multi: ", multi

# Main function
def main():
    doc.StartPickSession(OnPick, multi=True)

# Execute main()
if __name__=='__main__':
    main()

I get this console output:

mystery:  0
active:  [<c4d.BaseObject object called 'Cube/Cube' with ID 5159 at 0x00000290184D2B90>, <c4d.BaseObject object called 'Cube.1/Cube' with ID 5159 at 0x00000290184D2130>, <c4d.BaseObject object called 'Cube.2/Cube' with ID 5159 at 0x00000290184D2170>]
multi:  True

After a bit more detective work, it seems that mystery is 0 if I complete the pick-session by double-clicking, and it's 1 if I press Esc to finish the pick session.

Questions

  1. What is the mystery variable, and what is it actually returning.
  2. Is there a way to trigger a multi-pick session where the user doesn't have to hold down shift/ctrl to select multiple elements?
  3. I'm noticing some weirdness in terms of which objects are selected in the Editor/Viewport after a pick session (especially if I end it by pressing Esc). What messages/redraws do I need to call after a pick session? Do I need to handle undo or will C4D?

Thanks,

Donovan

Hi, Donovan thanks for reaching us.

  1. The mystery variable is actually an int flag to retrieve if the user cancels the PickSession or not.
def OnPick(flags, active, multi):
    if flags & c4d.PICKSESSION_FLAG_CANCELED:
        print "User cancel"
        
    print "active: ", active
    print "multi: ", multi


def main():
    doc.StartPickSession(OnPick, multi=True)
  1. No there is no way.
  2. Actually nothing, it's up to you to detect when the user cancels with PICKSESSION_FLAG_CANCELED and do whatever you want. Cinema 4D handle automatically undo. But you can call BaseDocument.GetSelection before and BaseDocument.SetSelection after if the user cancels the pick session)

Finally, note the C++ version offer to adds userdata ( For more information please read the C++ documentation https://developers.maxon.net/docs/Cinema4DCPPSDK/html/struct_pick_session_data_struct.html)

If you have any question, please let me know.
Cheers,
Maxime.