Solo Toggle



  • Hi!

    So my goal is to create a simple command to toggle the solo function, instead of one command to solo, and one command to solo_off.

    How can I go to create a python script in order to toggle these two commands :
    431000059, # Viewport Solo Single
    431000058) # Viewport Solo Off

    So far, my attempt has been not working :

    import c4d
    from c4d import gui
    
    def main():
        #obj = doc.GetActiveObject()
        #print(obj)
        values = (431000059, # Viewport Solo Single
                            431000058) # Viewport Solo Off
        done = False
        for num,x in enumerate(values):
            if x == doc.GetAction():
                new_v = values[(num+1)%len(values)]
                doc.SetAction(new_v)
                done = True
                break
            
        if not done:
            doc.setAction(values[0])
            
        c4d.EventAdd()
    
    
    if __name__=='__main__':
        main()
        c4d.EventAdd()
    

    So you can tell that I don't really know what I'm doing.

    How can I tell python to look at the current obj selected? Then how can I tell it to execute the solo function?
    Where can I find what environment the solo command lives in, as it doesn't seems to be with the doc.GetAction().

    Any help to connect the dots would be very much appreciated.

    Thanks!



  • Hmm, that is an interesting issue.

    First, there are three states in the soloing modes: off, single, and hierarchy, so you can build either a function that cycles through all three, or restrict yourself to toggling between off and hierarchy which is probably the most used mode.

    Second, the Solo Selection is (obviously) a Boolean toggle and not one of the above states (well, duh...)

    Third, the VIEWPORT_SOLO_xxx constants are found under the snap settings, so it makes sense to check snap.GetSnapSettings for the proper current values and change them there.

    I get the following script (which does work; in this case it cycles through all three states):

    import c4d
    from c4d.modules import snap
    
    def main():
        bc = snap.GetSnapSettings(doc)
        # VIEWPORT_SOLO_MODE any of:
        #    VIEWPORT_SOLO_MODE_OFF 0
        #    VIEWPORT_SOLO_MODE_SINGLE 1
        #    VIEWPORT_SOLO_MODE_HIERARCHY 2
        # VIEWPORT_SOLO_SELECTION Bool
        currentMode = bc[c4d.VIEWPORT_SOLO_MODE]
        if currentMode == None:
            #bc[c4d.VIEWPORT_SOLO_MODE] = c4d.VIEWPORT_SOLO_MODE_SINGLE
            c4d.CallCommand(431000059) # Viewport Solo Single
        elif currentMode == c4d.VIEWPORT_SOLO_MODE_OFF:
            #bc[c4d.VIEWPORT_SOLO_MODE] = c4d.VIEWPORT_SOLO_MODE_SINGLE
            c4d.CallCommand(431000059) # Viewport Solo Single
        elif currentMode == c4d.VIEWPORT_SOLO_MODE_SINGLE:
            #bc[c4d.VIEWPORT_SOLO_MODE] = c4d.VIEWPORT_SOLO_MODE_HIERARCHY
            c4d.CallCommand(431000060) # Viewport Solo Hierarchy
        elif currentMode == c4d.VIEWPORT_SOLO_MODE_HIERARCHY:
            #bc[c4d.VIEWPORT_SOLO_MODE] = c4d.VIEWPORT_SOLO_MODE_OFF
            c4d.CallCommand(431000058) # Viewport Solo Off
        # bc[c4d.VIEWPORT_SOLO_SELECTION] = ???
        # c4d.CallCommand(431000061) # Viewport Solo Selection
        #snap.SetSnapSettings(doc, bc)
        c4d.EventAdd()
    
    if __name__=='__main__':
        main()
    

    Now, the interesting thing is that I really need to execute the CallCommand. I tried to set the VIEWPORT_SOLO_MODE value by itself (see the commented-out lines) but while the GUI reacts by switching the icons, the viewport is not properly refreshed and does not even show the proper solo-ing when I move the view or click into the object tree (which should trigger a redraw).

    I'll leave it to the C4D engineers to tell us the proper refresh method for this usecase 😁



  • @Cairyn
    Thank you for your feedback!

    I just watched : https://www.cineversity.com/vidplaylist/introduction_to_python_in_c4d/introduction_to_python_in_c4d_part_3c

    And I'm obviously still a newbie.

    One question : how do you know that the VIEWPORT_SOLO_xxx constants are found under the snap settings in the first place?

    I tried looking for this here :
    https://developers.maxon.net/docs/Cinema4DPythonSDK/html/search.html?q=VIEWPORT_SOLO&check_keywords=yes&area=default

    and it returned nothing.

    Just trying to get the proper reflexes to figure shit up by myself when possible :)



  • @mrpinoux Adding that my first attempt came from :
    https://youtu.be/0SNhZgmGd2k?t=1126



  • @mrpinoux
    That's great, I ended up using :

    import c4d
    from c4d.modules import snap
    
    def main():
        bc = snap.GetSnapSettings(doc)
        currentMode = bc[c4d.VIEWPORT_SOLO_MODE]
        if currentMode == None:
            c4d.CallCommand(431000060) #  Viewport Solo Hierarchy
        elif currentMode == c4d.VIEWPORT_SOLO_MODE_OFF:
            c4d.CallCommand(431000060) #  Viewport Solo Hierarchy
        elif currentMode == c4d.VIEWPORT_SOLO_MODE_HIERARCHY:
            #bc[c4d.VIEWPORT_SOLO_MODE] = c4d.VIEWPORT_SOLO_MODE_OFF
            c4d.CallCommand(431000058) # Viewport Solo Off
        c4d.EventAdd()
    
    if __name__=='__main__':
        main()
    

    Thanks again!



  • @mrpinoux said in Solo Toggle:

    One question : how do you know that the VIEWPORT_SOLO_xxx constants are found under the snap settings in the first place?

    hmm, I think I searched the C++ documentation instead. There are manuals and other stuff that simply don't exist in the Python version (although there is no specific Solo information either...). Also, sometimes you need to search for thing A and find thing B which leads to item C and then actually you get a reference for thing A again - kinda like browsing Wikipedia.

    I'm currently trying to make a Python course on Patreon:
    https://www.patreon.com/cairyn
    First two parts are publicly accessible. This is just a beginning so far and you probably know already more about Python but I'm trying to topicize the whole matter and provide a more directed approach to C4D programming in Python. May become a book later.



  • Hi the CallCommand is the correct way to go.
    And @Cairyn it's in the Snap module because it uses some logic that is already implemented in the snap module such as the enabling state or other internal parameters storage logic. So using the CallCommand make sure everything is setup correctly.

    Note that in the end the solo things are only setting/clearing the NBIT_EHIDE of objects.

    Cheers,
    Maxime.


Log in to reply