1
$\begingroup$

I'm trying to create some corrective shape keys, and I am finding that it would be very handy if I could hide the currently visible parts of a mesh while, at the same time, unhiding the currently hidden parts of the mesh. Is there a way to do this? 'H' will hide everything selected, Alt-H will reveal everything hidden, and Shift-H will hide everything not selected. But I want a change in hidden status that is only based on what is and isn't hidden, not on what is or isn't selected. If I could swap what is hidden and unhidden back and forth, I could really nail these problem areas quickly. As it is, the only solution I can think of is to create vertex groups for the problem areas so that I can easily select them, and then hide/unhide parts based on selection. But this means extra steps.

EDIT: If anyone can post a script which does this in one operation, I will mark it as the accepted answer.

$\endgroup$

3 Answers 3

3
$\begingroup$
bl_info = {
    "name": "InvertHide",
    "author": "Martynas Žiemys",
    "version": (1, 0),
    "blender": (2, 82, 0),
    "location": "ctrl+alt+shift+h",
    "description": "Inverts hiden mesh parts",
    "warning": "",
    "wiki_url": "",
    "category": "Mesh",
}


import bpy


def main(context):
    bpy.ops.mesh.select_all(action='DESELECT')
    bpy.ops.mesh.reveal()
    bpy.ops.mesh.select_all(action='INVERT')
    bpy.ops.mesh.hide(unselected=False)


class InvertHide(bpy.types.Operator):
    """Inverts hidden parts of mesh"""
    bl_idname = "mesh.invert_hide"
    bl_label = "Invert Hide"

    @classmethod
    def poll(cls, context):
        return context.mode == 'EDIT_MESH'
    def execute(self, context):
        main(context)
        return {'FINISHED'}

addon_keymaps = []
def registerKeymaps():
    wm = bpy.context.window_manager
    if wm.keyconfigs.addon:
        km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
        kmi = km.keymap_items.new('mesh.invert_hide', 'H', 'PRESS', shift=True, alt=True,ctrl=True)
        addon_keymaps.append((km, kmi))


def unregisterKeymaps():
    for km, kmi in addon_keymaps:
        km.keymap_items.remove(kmi)
    addon_keymaps.clear()


def register():
    bpy.utils.register_class(InvertHide)
    registerKeymaps()


def unregister():
    unregisterKeymaps()
    bpy.utils.unregister_class(InvertHide)

if __name__ == "__main__":
    register()

Save this with Blender's text editor(UTF-8 encoding needed) to a .py file and install it as an add-on. You will have the functionality with alt+ctrl+ shift+h

$\endgroup$
1
  • $\begingroup$ Thank you so very much! :) $\endgroup$
    – R-800
    Commented May 29, 2020 at 13:49
3
$\begingroup$
  1. Hide the part of the mesh you want to hide (H).
  2. Deselect everything (Double tap A).
  3. Unhide everything (Alt+H).

The part that was unhidden will be automatically selected by default.

Simply invert the selection (Ctrl+I) and hide the selection (H).

$\endgroup$
10
  • $\begingroup$ I thought I tried this already and couldn't get it to work. I even almost mentioned this method in the question as being something I could alternatively do, except that I thought it took a lot of steps, and I couldn't get it to work besides. So I edited it out. But when I follow your steps just now, it does work. I still want a faster way, though. $\endgroup$
    – R-800
    Commented May 29, 2020 at 11:21
  • 1
    $\begingroup$ A faster way would be using an addon called command recorder and saving this as an action in it. Then you can pretty much do this with 1 press of a button. github.com/Muthird/CommandRecorder2.8 $\endgroup$ Commented May 29, 2020 at 11:28
  • 1
    $\begingroup$ Hi. Nice answer. Please use <kbd> tags around keyboard keys (see my edits), e.g. <kbd>H</kbd>. Thanks. $\endgroup$ Commented May 29, 2020 at 12:55
  • 1
    $\begingroup$ @HikariTW Neither of those links seem to say that you shouldn't use kbd tags, and it's standard on this site to do so. $\endgroup$ Commented May 29, 2020 at 13:15
  • 1
    $\begingroup$ @HikariTW If you want to discuss this further I've created a chatroom and replied to you there: chat.stackexchange.com/rooms/108631/… $\endgroup$ Commented May 29, 2020 at 13:34
1
$\begingroup$

BMesh version

For the sake of for the sake of, here is an alternative main for @MartinZ's answer using an edit mode bmesh instead of operators.

Thought I could simply toggle each elements hide property, instead

  • Make a set for each geometry type (particularly edges and verts)
  • Toggle hidden faces. Remove edges and verts from their respective set (they've come with the face)
  • Similarly for edges.
  • Finally for verts.

Test script.

import bpy
import bmesh


def main(context):
    meshes = [ob.data for ob in context.objects_in_mode_unique_data if ob.type == 'MESH']
    for me in meshes:
        #print(f"unhide {me.name}")
        bm = bmesh.from_edit_mesh(me)
        faces = set(bm.faces)
        edges = set(bm.edges)
        verts = set(bm.verts)
        for f in faces:
            f.hide_set(not f.hide)

            edges -= set(f.edges)
            verts -= set(f.verts)
        for e in edges:
            e.hide_set(not e.hide)
            verts -= set(e.verts)
        for v in verts:
            v.hide_set(not v.hide)

        bmesh.update_edit_mesh(me)        

# test call
main(bpy.context)
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .