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

| 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.