В Blender в любое контекстное меню, вызывающееся по нажатию правой кнопки мышки, можно добавить свои кастомные пункты для быстрого вызова нужных операторов.
Разберем для примера добавление нового пункта в контекстное меню 3D вьюпорта.
Для начала определим оператор, который мы будем вызывать через добавленный в контекстное меню новый пункт.
1 2 3 4 5 6 7 8 9 |
class TEST_OT_material_init(bpy.types.Operator): bl_idname = 'test.material_init' bl_label = 'Material Init' def execute(self, context): if bpy.context.object: bpy.ops.material.new() bpy.context.object.active_material = bpy.data.materials[-1] return {'FINISHED'} |
В функции execute мы создаем новый материал при помощи системного оператора material.new() и назначаем этот материал (он идет последним в списке всех материалов bpy.data.materials) на активный объект.
Зарегистрируем класс нашего оператора в Blender Python API:
1 |
bpy.utils.register_class(TEST_OT_material_init) |
Теперь для отрисовки нового пункта в контекстном меню нам нужно определить функцию, которая свяжет пункт меню с нашим оператором, а также будет выводить этот пункт на экран.
1 2 3 |
def menu_item_draw_func(self, context): self.layout.separator() self.layout.operator('test.material_init', icon='MATERIAL') |
По структуре эта функция аналогична любой функции draw в классах пользовательского интерфейса UI.
В нашей функции мы добавляем на layout меню разделитель, и следом за ним – наш оператор, указывая значение его идентификатор bl_idname в первом параметре функции operator().
Осталось добавить вызов отрисовки нашей функции вместе с контекстным меню 3D вьюпорта.
Класс контекстного меню 3D вьюпорта: VIEW3D_MT_object_context_menu
Добавим указатель на нашу функцию в этот класс при помощи команды append:
1 |
bpy.types.VIEW3D_MT_object_context_menu.append(menu_item_draw_func) |
Теперь контекстное меню 3D вьюпорта добавлен новый пункт ‘Material Init’
Выбрав который, мы создадим новый материал и назначим его текущему активному объекту.
Новые пункты в контекстное меню можно добавлять как в конец, так и в начало. Для того чтобы новый добавленный пункт шел в меню первым нужно вместо функции append использовать функцию prepend:
1 |
bpy.types.VIEW3D_MT_object_context_menu.prepend(menu_item_draw_func) |