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
$\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

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thank you so very much! :) $\endgroup$ – R-800 May 29 at 13:49
2
$\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).

| improve this answer | |
$\endgroup$
  • $\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 May 29 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$ – Viplav Prakash May 29 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$ – Ray Mairlot May 29 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$ – Ray Mairlot May 29 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$ – Ray Mairlot May 29 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)
| improve this answer | |
$\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.