1
$\begingroup$

The following command draws the Material interface:

layout.template_ID(obj, "active_material", new="material.new")

When a material is added additional functions can be shown such as:

row.prop(mat, "diffuse_color")
row.prop(mat, "alpha")

Oddly row.prop(mat, "diffuse_color") generates a python error code when no material is added:

File "C:\Users\info\Desktop\Claas UI.blend\Claas_UI_2.py", line 175, in draw

TypeError: UILayout.prop(): error with argument 1, "data" - Function.data does not support a 'None' assignment AnyType type

And because of the error everything after row.prop(mat, "diffuse_color") will be ignored.

So I am curious how one could create an argument switch that checks if there is a material and then ignores

Check For Material

layout.template_ID(obj, "active_material", new="material.new")
layout.template_ID(space, "pin_id")

If Material Present show the following as well

row = layout.row()
row.prop(mat, "diffuse_color")
row.prop(mat, "alpha")

But still render the following buttons:

row.prop(obj, "draw_type", text="Draw Type")           
row = layout.row()
row.label(text="Draw Option:")
row.prop(obj, "show_transparent", text="Transparency")
row.prop(obj, "show_x_ray", text="X-Ray")
row = layout.row()
$\endgroup$

1 Answer 1

2
$\begingroup$

It's easy to overthink this. A solution is to prevent those two lines from being executed (therefor not showing) if you don't have a material reference.

if mat:
    row.prop(mat, "diffuse_color")
    row.prop(mat, "alpha")
else:
    row.label('add a material')

if mat is a material reference, it will evaluate to True and show those two props, else it is None and this evaluates to False.

import bpy

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

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

        obj = context.active_object
        if obj:
            mat = obj.active_material

            if mat:
                row.prop(mat, "diffuse_color")
                row.prop(mat, "alpha")
            else:
                row.label('no materials')
        else:
            row.label('no object')


def register():
    bpy.utils.register_class(HelloWorldPanel)

def unregister():
    bpy.utils.unregister_class(HelloWorldPanel)

if __name__ == "__main__":
    register()

If your object has more than 1 material, you can use the return value obj.material_slots and loop over them and display their name, diffuse, alpha..etc.

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

    obj = context.active_object
    if obj:
        mats = obj.material_slots

        for slot in mats:
            mat = slot.material

            row = layout.row()
            row.prop(mat, "name")
            row.prop(mat, "diffuse_color")
            row.prop(mat, "alpha")

        if (not mats):
            row = layout.row()
            row.label("no materials for {}".format(obj.name))

    else:
        row = layout.row()
        row.label('no object')

You'll want to finetune how that displays yourself:

enter image description here

$\endgroup$
0

You must log in to answer this question.

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