How do I make an addon from this code?

I have this piece of code that I am using to remove duplicate materials. What I do is I open the Text Editor, paste it in and click Run Script. I would like to make it a Tools Shelf button. This is the code:

import bpy

mat_list = bpy.data.materials

for o in bpy.data.objects:
for s in o.material_slots:
if s.material.name[-3:].isnumeric():
# the last 3 characters are numbers
if s.material.name[:-4] in mat_list:
# there is a material without the numeric extension so use it
s.material = mat_list[s.material.name[:-4]]


I tried following the instructions here, but I get this error:

This is my first time messing around with Blender scripts, any help appreciated!

EDIT: This is my complete addon:

import bpy

bl_info = {
"name": "Remove Duplicate Materials",
"author": "Me",
"version": (1, 0, 0),
"blender": (2, 7, 8),
"location": "3D View > Tool Shelf > My Tools",
"description": "Remove duplicate materials",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "User"}

import bpy

mat_list = bpy.data.materials

for o in bpy.data.objects:
for s in o.material_slots:
if s.material.name[-3:].isnumeric():
# the last 3 characters are numbers
if s.material.name[:-4] in mat_list:
# there is a material without the numeric extension so use it
s.material = mat_list[s.material.name[:-4]]

• Post your complete addon code, please. A while ago, data access was restricted from the addon registration code so you must now put it into very specific places. Sep 13 '17 at 19:01
• Also see this: blender.stackexchange.com/questions/8702/… Sep 13 '17 at 19:03
• To make a button, you have to make a panel and tell it where to show up - as well as make sure that you register and unregister your classes including your panel. See my code below for what I got to work. Sep 13 '17 at 19:22

Maybe try this and see if it makes sense to you. It really should also poll to see if objects are selected in the operator.

bl_info = {
"name": "Material Button Panel",
"version": (1, 0),
"blender": (2, 78, 0),
"location": "View3D > Toolbar",
"description": "Button to Remove Duplicate MAterials",
"warning": "",
"wiki_url": "",
"category": "Material",
}

import bpy

class RemoveDupmatl(bpy.types.Operator):
"""Remove Duplicate Materials"""
bl_idname = "object.remove_dupmatl"

bl_label = "Remove Duplicate Materials"
bl_options = { 'REGISTER', 'UNDO' }

def execute(self, context):

scene = context.scene

#new code
mat_list = bpy.data.materials

for o in bpy.data.objects:
for s in o.material_slots:
if s.material.name[-3:].isnumeric():
# the last 3 characters are numbers
if s.material.name[:-4] in mat_list:
# there is a material without the numeric extension so use it
s.material = mat_list[s.material.name[:-4]]

return {'FINISHED'}

class TestPanel(bpy.types.Panel):
"""A custom panel in the viewport toolbar"""
bl_label = "Test Panel"
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
bl_category = "Tests"

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

row = layout.row()

row.label(text="Single Button")
row = layout.row()
row.operator("object.remove_dupmatl", text = "Remove Dup Material", icon = 'ROTACTIVE')

def register():
bpy.utils.register_class(RemoveDupmatl)
bpy.utils.register_class(TestPanel)

def unregister():
bpy.utils.unregister_class(RemoveDupmatl)
bpy.utils.unregister_class(TestPanel)

if __name__ == "__main__":
register()

• Thanks for the edit - I haven't posted code enough to know how it should be here. Sep 13 '17 at 20:40
• Also don't forget to click Save User Settings to make sure it stays enabled on restart. Sep 13 '17 at 23:03