How to add "Overlay" buttons in custom panel?

Please help me. How to add normals section in custom panel?

Hello, I have a similar issue. Is it possible to access Viewport Overlays via Python? It seems that the data path to the overlay, where these settings seem to be located, is not available via e.g. bpy.data.screens[‘Scripting’].overlay. Could overlay be made available via bpy?

The “Scripting” screen doesn’t have an overlay attribute. To get this data, the best thing to do is use the correct context. A lot of the python tooltips you see in blender are context-sensitive, you can’t just drop them into the console and have them work. To get the overlay attribute (and all of the properties therein), you need to first get a reference to the correct screen object. The easiest way to do this outside of any ‘known’ context would be thus:

import bpy
from pprint import pprint as pp

for a in bpy.context.workspace.screens[0].areas:
    if a.type == 'VIEW_3D':
        pp(dir(a.spaces[0].overlay))

If you are already in the correct context (ie: you are running an operator that is guaranteed to be run from a VIEW_3D area), you can simply use context.area.spaces[0].overlay directly.

And to answer the OP’s original question that went unnoticed for 8 months until you bumped this thread, the code for most of the viewport hud’s UI is in space_view3d.py, relevant excerpt provided below for posterity:

class VIEW3D_PT_overlay_edit_mesh_normals(Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'HEADER'
    bl_parent_id = 'VIEW3D_PT_overlay_edit_mesh'
    bl_label = "Normals"

    @classmethod
    def poll(cls, context):
        return context.mode == 'EDIT_MESH'

    def draw(self, context):
        layout = self.layout

        view = context.space_data
        overlay = view.overlay
        display_all = overlay.show_overlays

        col = layout.column()
        col.active = display_all

        row = col.row(align=True)
        row.prop(overlay, "show_vertex_normals", text="", icon='NORMALS_VERTEX')
        row.prop(overlay, "show_split_normals", text="", icon='NORMALS_VERTEX_FACE')
        row.prop(overlay, "show_face_normals", text="", icon='NORMALS_FACE')

        sub = row.row(align=True)
        sub.active = overlay.show_vertex_normals or overlay.show_face_normals or overlay.show_split_normals
        sub.prop(overlay, "normals_length", text="Size")
1 Like

Thanks, this clarifies the usage of overlays a lot! Good to know that Python tool tip data paths may need to be modified.