3
$\begingroup$

I want to isolate one object in the viewport (I know I can do that with "/"), but I want the rest of the lighting and models to still affect it.

I mainly want to use this for texturing certain elements in a big scene. Is there a way to do this or is it a bit of a reach?

$\endgroup$
4
  • 3
    $\begingroup$ I could write a Python script that assigns a temporary material to all other objects, with Blend Mode set to Alpha Blend, and Alpha set to 0.0: i.imgur.com/zu36q8C.png as well as make those objects unselectable. It could also hide cameras. You would still see light objects as on the screenshot. $\endgroup$ – Markus von Broady Jun 5 at 8:29
  • $\begingroup$ Well...That would be simply INCREDIBLE ! Also an alternative (not sure if easier/less taxing on system ? or not ? ) I wonder if instead of assigning a temp material maybe doing this : 1-Select object 2-Invert selection 3-Object properties 4-deselect camera in Ray visibility 5-Copy to selected. AND then doing the reverse to bring them back to normal again $\endgroup$ – kay777 Jun 5 at 9:41
  • $\begingroup$ I'm not sure what are the upsides of disabling Ray Visibility -> Camera, but the downside is it only works in Cycles... $\endgroup$ – Markus von Broady Jun 5 at 9:48
  • $\begingroup$ @markusvonbroady oopps You’re actually right hah totally forgot! $\endgroup$ – kay777 Jun 5 at 9:59
2
$\begingroup$

Python script

As promised. After running the script, press Alt + Numpad / to hide/unhide. Everything except the active object, lights and meshes is hidden. Meshes other than the active object have their materials replaced with a temporary material using Alpha Blend and Alpha=0. If there's no material slot, it is created. All data is saved to a textblock, so you can hide other objects, save the file, return to it later, and unhide the objects. However, messing with material slots of "hidden" meshes, or renaming them, will hurt you.

import bpy, json

shortcut_key = "NUMPAD_SLASH"
shortcut_modifiers = {"alt": True}
save_name = "hidden"

C = bpy.context
D = bpy.data
addon_keymaps = []  # store keymaps here to access after registration

class CUSTOM_LOCAL_OT_With_Light(bpy.types.Operator):
    """Make other objects invisible, but still affect light paths
    https://blender.stackexchange.com/q/226679/60486 """
    bl_idname = "custom_local.with_light"
    bl_label = "Local view with light still affected by hidden objects"
    
    def make_invisible_material(self):
        name = "Temp.Invisible.Material"
        m = D.materials.get(name)
        if not m:
            m = D.materials.new(name)
            m.use_nodes = True
            m.blend_method = 'BLEND'
            m.node_tree.nodes['Principled BSDF'].inputs['Alpha'].default_value = 0.0
        return m
            
    def hide(self):
        engine = bpy.context.scene.render.engine
        invisible_mat = self.make_invisible_material()
        objs = []
        mats_with_fake_user = set()
        
        to_hide = (o for o in C.scene.objects
                   if o.type != 'LIGHT' and not o.hide_get() and o is not C.active_object)
        for o in to_hide: 
            entry = {"name": o.name}
            objs.append(entry)
            if o.type != 'MESH':
                o.hide_set(True)
                continue
            if o.hide_select:
                entry["was_unselectable"] = True
            else:
                o.hide_select = True
            if engine == 'CYCLES':
                if o.cycles_visibility.camera:
                    entry["camera_ray"] = True
                    o.cycles_visibility.camera = False
                continue
            entry["materials"] = []
            if not o.material_slots:  # no slot
                entry["slot_added"] = True
                bpy.ops.object.material_slot_add({'object': o})
                o.material_slots[0].material = invisible_mat
                continue
            for slot in o.material_slots:
                mat = slot.material
                slot.material = invisible_mat
                if not mat:  # empty slot
                    entry["materials"].append("")
                    continue
                if mat.use_fake_user:
                    mats_with_fake_user.add(mat.name)
                mat.use_fake_user = True
                entry["materials"].append(mat.name)
        return {"materials_with_fake_user": list(mats_with_fake_user), "objects": objs}
                
    
    def unhide(self, data):
        for entry in data["objects"]:
            o = D.objects[entry["name"]]
            o.hide_set(False)  # hidden objects were ignored, so all objects saved
                               # are objects hidden by this script
            if "was_unselectable" not in entry:
                o.hide_select = False
            if "camera_ray" in entry:
                o.cycles_visibility.camera = True
            mats = entry.get("materials")
            if mats is None:
                continue
            if "slot_added" in entry:  # remove the added slot
                bpy.ops.object.material_slot_remove({'object': o})
            for i, name in enumerate(entry["materials"]):
                mat = D.materials[name] if name else None
                o.material_slots[i].material = mat
                if mat and mat not in data["materials_with_fake_user"]:
                    mat.use_fake_user = False            
    
    def execute(self, context):
        txt = D.texts.get(save_name)
        if txt:
            self.unhide(json.loads(txt.as_string()))
            D.texts.remove(txt)
        else:
            txt = D.texts.new(save_name)
            txt.from_string(json.dumps(self.hide()))
        return {"FINISHED"}

def register():
    bpy.utils.register_class(CUSTOM_LOCAL_OT_With_Light)
    # handle the keymap
    wm = bpy.context.window_manager
    km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D')
    kmi = km.keymap_items.new(CUSTOM_LOCAL_OT_With_Light.bl_idname, shortcut_key, 'PRESS', **shortcut_modifiers)
    addon_keymaps.append(km)

def unregister():
    bpy.utils.unregister_class(CUSTOM_LOCAL_OT_With_Light)
    # handle the keymap
    wm = bpy.context.window_manager
    for km in addon_keymaps:
        wm.keyconfigs.addon.keymaps.remove(km)
    # clear the list
    del addon_keymaps[:]

if __name__ == "__main__":
    register()
$\endgroup$
2
  • $\begingroup$ Thanks a lot ! This is Incredible !!! PS:It only works in EEVEE though, is something like this possible with cycles too or not really ? Thank you again!! $\endgroup$ – kay777 Jun 15 at 21:22
  • $\begingroup$ @kay777 oh, so you were right with camera visibility after all. I updated the script, though I were unable to make the floor behind hidden meshes visible in Cycles :(. $\endgroup$ – Markus von Broady Jun 16 at 12:44
4
$\begingroup$

Create a new Collection.

With an object selected, press M -it moves the specific object into the collection.

Enter image description here

Use the Isolate icon to turn OFF/ON the main Collection.

Enter image description here

Notes:

  • Shift clicking on the Isolate icon will set all nested collections
  • I moved lights into a solo collection just to make it organised, but you can keep it in a main collection. Lights are not affected.
  • Cycles only (so it is useless for texturing)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.