0
$\begingroup$

How would I go about making a property box that contained all the materials in a scene (in a Toolshelf (T) panel for example) and is able to pass the material in the list to another operator that assigned the material that was selected in the property box?

$\endgroup$
1
$\begingroup$

Here is an example of how this can be achieved:

import bpy

def mat_update(self, context):
    ob = context.active_object
    mats = bpy.data.materials
    selected_mat = context.scene.mymats
    if selected_mat != 'None':
        if ob.data.materials:
            ob.data.materials[0] = mats[selected_mat]
        else:
            ob.data.materials.append(mats[selected_mat])

class MyListPanelExample(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "My Panel"
    bl_idname = "OBJECT_PT_example"
    bl_space_type = 'VIEW_3D'
    bl_region_type = "TOOLS"
    bl_category = 'My Panel'

    @classmethod
    def poll(cls, context):
        return context.active_object is not None 

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

        obj = context.object
        row = layout.row()
        row.prop(context.scene, "mymats")

def register():
    def getsets(self, context):
        sets = []
        mats = bpy.data.materials
        for mat in mats:
            sets.append((mat.name, mat.name, mat.name))
        if not sets:
            sets = [('None', 'None', 'None')]
        return sets

    bpy.utils.register_module(__name__)
    bpy.types.Scene.mymats = bpy.props.EnumProperty(items=getsets, update=mat_update)

def unregister():
    bpy.utils.unregister_module(__name__)

if __name__ == "__main__":
    register()
$\endgroup$
  • 1
    $\begingroup$ Rewrote the code because I read the question wrong. $\endgroup$ – cmomoney Jan 29 '17 at 21:11
1
$\begingroup$

Finding only the materials in the scene would be doable (make a set of all materials of all objects in scene) but is probably not necessary, instead suggest using bpy.data.materials the list of all materials in the file.

A UILayout.prop_search can be used as a UI to assign a material's name to a string property.

import bpy
from bpy.props import StringProperty

class LayoutDemoPanel(bpy.types.Panel):
    bl_label = "Set Active Material"
    bl_idname = "OBJECT_PT_example"
    bl_space_type = 'VIEW_3D'
    bl_region_type = "TOOLS"
    bl_category = 'Materials'

    @classmethod
    def poll(cls, context):
        return len(bpy.data.materials) > 0

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

        scene = context.scene

        layout.prop_search(scene,
                           "selected_mat",
                           bpy.data,
                           "materials")

def register():
    bpy.types.Scene.selected_mat = StringProperty(default="None")    
    bpy.utils.register_class(LayoutDemoPanel)


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


if __name__ == "__main__":
    register()

enter image description here

In an operator can use the property like so.

scene = context.scene
material = bpy.data.materials.get(scene.selected_mat)
if material is None:
    # no material has it been renamed?
    return {'CANCELLED'}
# do something with material
$\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.