2

I'm new to Python

I would like to display in the 3D viewport a better representation of the Xray mode. The header icon is not visible enough to me. Not always easy to see the difference between ON and OFF.

I have search for a potential addon or script without success.

enter image description here

Duarte Farrajota Ramos
  • 59,425
  • 39
  • 130
  • 187

2 Answers2

3

enter image description here

Make some visual overlay

Could not help but see the link between this and Bug in addon to Change header color dynamically The addon there was to remind user they are in automatic keyframe mode.

Remember at the time thinking would make an interesting addon if given a generic way to link a property toggle with toggling a setting. However have not returned until now

Similarly an edit to change the behaviour to instead change the bg color of the 3d view if in xray mode.

Consider this a "proof of concept" test script, a more subtle indicator could be used.

paste into text editor click run script.

import blf
import bpy

bl_info = { "name": "New Object", "author": "Your Name Here", "version": (1, 0), "blender": (2, 80, 0), "location": "View3D > Add > Mesh > New Object", "description": "Adds a new Mesh Object", "warning": "", "wiki_url": "", "category": "Add Mesh", }

highlight_color = (0.4, 0, 0)

class DrawingClass: def init(self, prop): from bpy import context self.prop = prop self.col = context.preferences.themes[0].view_3d.space.gradients.high_gradient[:] self.handle = bpy.types.SpaceView3D.draw_handler_add( self.draw_text_callback, (), 'WINDOW', 'POST_PIXEL')

def draw_text_callback(self):
    from bpy import context
    font_id = 0  # XXX, need to find out how best to get this.
    if not hasattr(context, "scene"):
        return None
    shading = context.space_data.shading
    if shading.show_xray:
        context.preferences.themes[0].view_3d.space.gradients.high_gradient = highlight_color
        # draw some text
        blf.position(font_id, 18, 50, 0)
        blf.size(font_id, 50, 72)
        blf.draw(font_id, f"{self.prop}")

    else:
        context.preferences.themes[0].view_3d.space.gradients.high_gradient = self.col

def remove_handle(self):
    from bpy import context
    context.preferences.themes[0].view_3d.space.gradients.high_gradient = self.col
    bpy.types.SpaceView3D.draw_handler_remove(self.handle, 'WINDOW')


dc = None

def register(): global dc dc = DrawingClass("XRay Mode")

def unregister(): global dc if dc: dc.remove_handle() dc = None

if name == "main": register()

Leads to more questions.

An issue could be since a draw handler is defined for type, could be an issue with syncing when more than 1 view 3d is being drawn on the screen. Also setting the theme bg color of the viewport is blend file wide.

enter image description here

A quick test confirmed my fears. Notice the text is correct but the theme bg color is not.

What is interesting is having what is like two themes active at once

batFINGER
  • 84,216
  • 10
  • 108
  • 233
1

Here is the final script if anyone is interested ;)

import blf
import bpy

bl_info = { "name": "Better Xray Visualization", "author": "Stefakapapy", "version": (1, 0), "blender": (2, 80, 0), "location": "Toggle Xray", "description": "Displays better visual representation on screen", "category": "Interface", }

class DrawingClass: def init(self, prop): from bpy import context

    self.prop = prop
    self.handle = bpy.types.SpaceView3D.draw_handler_add(
        self.draw_text_callback, (), 'WINDOW', 'POST_PIXEL')

def draw_text_callback(self):
    from bpy import context

    if not hasattr(context, "scene"):
        return None

    shading = context.space_data.shading
    shading_type = context.space_data.shading.type
    xray = shading.show_xray
    xray_wireframe = shading.show_xray_wireframe

    if (shading_type=="SOLID" and xray) or (shading_type=="WIREFRAME" and xray_wireframe):
        display_xray = True
    else:
        display_xray = False

    if display_xray:
            font_id = 0  # XXX, need to find out how best to get this.
            color1 = (0, 0.624, 1.0, 1.0)
            width = context.area.width

            blf.size(font_id, 40, 72)
            dim_x = blf.dimensions(font_id, self.prop)[0]/2
            blf.position(font_id, width/2-dim_x, 18, 0)
            blf.color(font_id, *color1)
            blf.draw(font_id, f"{self.prop}")

def remove_handle(self):
    from bpy import context
    bpy.types.SpaceView3D.draw_handler_remove(self.handle, 'WINDOW')


dc = None

def register(): global dc dc = DrawingClass("XRay Mode")

def unregister(): global dc if dc: dc.remove_handle() dc = None

if name == "main": register()

  • 1
    Good one. For future ref, can simply edit your previous answer. At a certain rep deleted answers are visible. This post is hidden. It was deleted 55 mins ago by the post author. – batFINGER Oct 14 '20 at 13:35