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 OffSo 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 checksnap.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 theVIEWPORT_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/py/2023_2/search.html?q=VIEWPORT_SOLO&check_keywords=yes&area=defaultand 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 :
-
@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.