Hi,
I just spent a bit of time debugging a couple issues when trying to Solo a Layer in the Layer Manager, and figured I would post my findings to save someone else some trouble:
Q: How do you solo a layer?
layer_root = doc.GetLayerObjectRoot()
if not layer_root: return
# Get the first layer in the scene
layer = layer_root.GetDown()
if not layer: return
# Be sure to use the `rawdata` flag so that you get the stored layer state, not the "effective" layer state
layer_data = layer.GetLayerData(doc, rawdata=True)
start_solo_state = layer_data["solo"]
solo_state = True
layer_data["solo"] = True
# SetLayerData needs a complete LayerData dict, it doesn't work with something like `{"solo": True}`
# doing that will force all other layer state flags to be False
layer.SetLayerData(doc, layer_data)
# This isn't documented near SetLayerData, but you must call this method or C4D won't know to update the
# solo state of layers in the scene.
set_or_clear =
doc.ChangeNBit(c4d.NBIT_SOLO_LAYER, c4d.NBITCONTROL_SET)
# Let C4D know something has changed to trigger a redraw
c4d.EventAdd()
Documentation Request:
Please update the docs for SetLayerData to include an example like the above, and make a note that if you plan to SetLayerData you should call GetLayerData with rawdata=True
.
Thanks,
Donovan
-- Edit 2020/03/20 --
Actually this isn't working well in all circumstances. If all layers are unsoloed I'm not getting the expected refresh.
Okay, I think I figured out the issue (but haven't updated the logic above to account for it):
If you turn off solo on all layers, you need to use doc.ChangeNBit(c4d.NBIT_SOLO_LAYER, c4d.NBITCONTROL_CLEAR)
, but if even one layer has the solo flag on, you need to use doc.ChangeNBit(c4d.NBIT_SOLO_LAYER, c4d.NBITCONTROL_SET)
.
...I think.