I’d like to know if an object is hidden ( with H / Alt-H) or not , then make all objects visible, do some stuff and then hide them again.
I can get the object visibility state with ob.visible_get() , but it mixes hide_viewport and hide with H, and beside that it’s not possible to set the visibility back.
I’ve managed to unhide everything with some context override and bpy.ops.object.hide_view_clear(override)
But I hope there is a simpler way to do that…
Why I need that :
In my old script that I’m converting from 2.7 to 2.8, I do a bunch of operation on several objects, copy some vertex groups, add some modifier , apply modifiers ect… At some point I need to use bpy.ops.object… and the script fail if objects are hidden.
The ‘H’ operator sets a visibility flag for objects internally in blender, and isn’t accessible by the python API. I asked about this a few weeks ago on devtalk.
It’s possible to test the following by properties alone:
If an object is hidden using only ‘H’ (or the eye icon in outliner)
If an object is hidden with (at least) the monitor icon:
It’s not (yet) possible to distinguish if an object is hidden only with the monitor icon by property. However, you can toggle hide_viewport and re-test the object to determine if the visible_get() returns True, and if so you’ll know that it was hidden using only the monitor icon. Performance wise it shouldn’t have an impact since the scene isn’t redrawn until after the script, or if something in the script calls a redraw.
A quick example:
import bpy
# prints the name of hidden objects
def get_hidden():
context = bpy.context
with_eye = []
with_monitor = []
with_eye_and_monitor = []
for o in context.view_layer.objects:
if not o.hide_viewport and not o.visible_get():
with_eye.append(o)
continue
if o.hide_viewport:
o.hide_viewport = False # toggle to test visibility
if o.visible_get():
with_monitor.append(o)
else:
with_eye_and_monitor.append(o)
o.hide_viewport = True # toggle back
if with_eye:
print(
"With eye only:\n",
[o.name for o in with_eye])
if with_monitor:
print(
"With monitor only:\n",
[o.name for o in with_monitor])
if with_eye_and_monitor:
print(
"With eye and monitor:\n",
[o.name for o in with_eye_and_monitor])
get_hidden()
As for hiding objects again with the appropriate setting;
Objects hidden with only hide_viewport only needs that property changed back.
Objects hidden with bpy.ops.object.hide_view_set(), however probably requires context override or selection by script, until the property this operator toggles is exposed.
I had the same problem for the collections but I found how to do with its two values Bpy.data.collections [" MyCollectionName "] hide_viewport bpy.context.view_layer.layer_collection.children [" MyCollectionName "] hide_viewport
But this work only with the collections
Do you have any idea when this property will be available for objects in the API?
I need unhide all objects and bpy.ops.object.hide_view_clear(select=False) return a error RuntimeError: Operator bpy.ops.object.hide_view_clear.poll() failed, context is incorrect