2

I have a Boolean property in my custom panel that I would like to either use a driver or can I use python to do make my option true/false Based on the shading type. I have searched up what I want, but the answers don't help and I am asking again because those were based on older blender versions.

For example, When I go into solid shading mode, Visibility of a object is set to hidden and vice versa for other shading types.

Yuneth Alwis
  • 332
  • 1
  • 11

1 Answers1

4

As in comments under the question, I think it's a duplicate of:

Automatically run a script when an object is transformed or a condition is met

Which points to a Space3DView draw callback solution:

Use a driver to programmatically set the positions of many vertices

Since we had a conversation in the comments about it, I decided to write an answer here. The principle is the same as under the link (the 2nd part, "If you don't want it for an animation") - on every draw, try to figure out if you don't have to do anything as soon as possible, and in such case just quit the function. That's the purpose of 'last_shading' variable - if you keep track of the last value, you now know if the value changed - if it didn't, you don't have to do anything and you can just quit. The sooner you realize the function has no work to do and can quit, the less CPU cycles you will waste. But, as I show in the benchmark you don't have to worry about it too much...

import bpy
from bpy import context as C, data as D
from bpy.types import SpaceView3D

visibility_data = { 'Cube': {'SOLID', 'MATERIAL', 'RENDERED'}, 'Sphere': {'MATERIAL'}, 'Suzanne': {'SOLID', 'MATERIAL'} }

last_shading = None

def test(): global last_shading if C.area.type != 'VIEW_3D': return shading_type = C.space_data.shading.type if shading_type == last_shading: return print(last_shading) # The lesson from edits... Use a print to inspect if the function isn't executed too often for ob_name, shadings in visibility_data.items(): ob = D.objects[ob_name] ob.hide_viewport = shading_type not in shadings last_shading = shading_type

try: SpaceView3D.draw_handler_remove(SpaceView3D.my_handler, 'WINDOW') except (AttributeError, ValueError): pass

SpaceView3D.my_handler = SpaceView3D.draw_handler_add(test, (), 'WINDOW', 'PRE_VIEW')

If you run the script with a project that has a cube, sphere and , all with default names, you should be able to see that they hide automatically based on the visibility_data dictionary:

Not sure if changing the rendering mode updates depsgraph, but for almost anything, consider replacing the view 3D callback with the application handler, as used here by Martynas Žiemys: Operator that runs when a value input is changed

Markus von Broady
  • 36,563
  • 3
  • 30
  • 99
  • Thank you for giving an example as well, it helped me understand how to do this. This works. – Yuneth Alwis Jan 29 '22 at 05:13
  • There is a tiny issue tho, This seems to run every second which heavily impacts the scene I am working on. is there something like Run once in python? – Yuneth Alwis Jan 29 '22 at 07:21
  • @YunethAlwis This runs much more often than once per second, but it doesn't affect the scene in my tests. If you can reproduce the issue in a .blend file you can share, I'll be willing to look into it. Running first 5 lines of the test function shouldn't be heavy on CPU even if it's run 100 times per frame. But perhaps there's an error there that causes more work to be done? Could you also tell me what's your hardware you're working on? – Markus von Broady Jan 29 '22 at 11:02
  • My Hardware is i7 9750H, GTX 1650m. – Yuneth Alwis Jan 29 '22 at 13:12
  • @YunethAlwis Your hardware is not an issue then. By "heavily impacts the scene", you mean lowered FPS? It could possibly happen if every time it runs there's an error printed to console... The only idea I can come up with is to add if not C.area: return as the first line to the test function. Otherwise I'd need to look at your project to find what's the issue. – Markus von Broady Jan 29 '22 at 13:19
  • I did a test of my own how performance correlates to your code, this is my results i found.

    160FPS when code isn't running 100FPS when Code is running

    The scene contains 1 million faces with the same setup as you did but with subdiv modifiers.

    Also the more geometry you have the more the fps exponentially slows donw with the code.

    – Yuneth Alwis Jan 29 '22 at 13:24
  • @YunethAlwis which code are we talking about? The code in this answer or the code in the linked benchmark? – Markus von Broady Jan 29 '22 at 13:28
  • The code in the answer – Yuneth Alwis Jan 29 '22 at 13:30
  • @YunethAlwis aaah I found the error, mea culpa – Markus von Broady Jan 29 '22 at 13:33
  • 1
    @YunethAlwis see the edit - that's the crucial part :) – Markus von Broady Jan 29 '22 at 13:35
  • Thank you Markus von Broady, Very cool :) – Yuneth Alwis Jan 29 '22 at 14:36
  • Markus there is a error in the code, UnboundLocalError: local variable 'last_shading' referenced before assignment, this got fixed by putting another = symbol on the new line of code you put, I just wanted to put. thank you:). Is it okay if I can edit your post. – Yuneth Alwis Jan 29 '22 at 14:48
  • @YunethAlwis it's getting embarassing... See another edit - this time I tested it and it works. – Markus von Broady Jan 29 '22 at 15:16