''' Copyright (C) 2021 - 2023 Akaneyu This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ''' import bpy from . import operators from . import app def get_icon_id(icon_name): session = app.get_session() if icon_name in session.icons: return session.icons[icon_name].icon_id else: return 0 def menu_func_3d(self, context): layout = self.layout layout.separator() layout.menu(SYMMETRIZE_TEXTURE_MT_menu_3d.bl_idname, text='Symmetrize Texture') def menu_func_2d(self, context): layout = self.layout if context.area.spaces.active.mode != 'UV' \ and context.area.spaces.active.image != None \ and not context.area.spaces.active.image.use_view_as_render: layout.separator() layout.menu(SYMMETRIZE_TEXTURE_MT_menu_2d.bl_idname, text='Symmetrize Texture') class SYMMETRIZE_TEXTURE_MT_menu_3d(bpy.types.Menu): bl_idname = "SYMMETRIZE_TEXTURE_MT_menu_3d" bl_label = "Symmetrize Texture" def draw(self, context): layout = self.layout layout.operator(operators.SYMMETRIZE_TEXTURE_OT_use_3d_brush.bl_idname, text='3D Brush', icon_value=get_icon_id('sym_brush')) layout.operator(operators.SYMMETRIZE_TEXTURE_OT_save_image.bl_idname, text='Save Image', icon="FILE_TICK") class SYMMETRIZE_TEXTURE_MT_menu_2d(bpy.types.Menu): bl_idname = "SYMMETRIZE_TEXTURE_MT_menu_2d" bl_label = "Symmetrize Texture" def draw(self, context): layout = self.layout layout.operator(operators.SYMMETRIZE_TEXTURE_OT_mirrored_copy.bl_idname, text='Mirrored Copy', icon_value=get_icon_id('mirror_copy')) layout.operator(operators.SYMMETRIZE_TEXTURE_OT_use_2d_brush.bl_idname, text='2D Brush', icon_value=get_icon_id('sym_brush')) class SYMMETRIZE_TEXTURE_PT_panel_3d(bpy.types.Panel): bl_label = "Symmetrize Texture" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "Symmetrize Texture" @classmethod def poll(cls, context): return context.mode == 'OBJECT' def draw(self, context): session = app.get_session() wm = context.window_manager props = wm.symmetrizetexture_properties if context.object != session.previous_object: imgs = self.find_texture_images(context) if imgs: props.image_preview = imgs[0].name session.previous_object = context.object layout = self.layout row = layout.row() op = row.operator(operators.SYMMETRIZE_TEXTURE_OT_use_3d_brush.bl_idname, text='3D Brush', icon_value=get_icon_id('sym_brush')) row = layout.row() row.label(text='Texture:') row = layout.row() row.prop(wm.symmetrizetexture_properties, 'image_preview', text='') row = layout.row() op = row.operator(operators.SYMMETRIZE_TEXTURE_OT_save_image.bl_idname, text='Save Image', icon="FILE_TICK") row = layout.row() row.label(text='Brush:') row = layout.split(align=True) row.alignment = 'RIGHT' row.label(text='Strength') row.prop(props, "brush_strength", text='', slider=True) row = layout.split(align=True) row.alignment = 'RIGHT' row.label(text='Falloff') row.prop(props, "brush_falloff", text='') row = layout.row() row.label(text='Image Mirror Axis:') row = layout.row() row.prop(props, "image_mirror_axis", expand=True) def find_texture_images(self, context): imgs = [] for mat_slot in context.object.material_slots: self.find_texture_images_from_node_tree(imgs, mat_slot.material.node_tree) return imgs def find_texture_images_from_node_tree(self, imgs, node_tree): for node in node_tree.nodes: if node.bl_idname == 'ShaderNodeTexImage': if node.image not in imgs: imgs.append(node.image) elif node.bl_idname == 'ShaderNodeGroup': self.find_texture_images_from_node_tree(imgs, node.node_tree) class SYMMETRIZE_TEXTURE_PT_panel_2d(bpy.types.Panel): bl_label = "Symmetrize Texture" bl_space_type = "IMAGE_EDITOR" bl_region_type = "UI" bl_category = "Symmetrize Texture" @classmethod def poll(cls, context): return context.area.spaces.active.mode != 'UV' \ and context.area.spaces.active.image != None \ and not context.area.spaces.active.image.use_view_as_render def draw(self, context): session = app.get_session() wm = context.window_manager props = wm.symmetrizetexture_properties layout = self.layout row = layout.row() op = row.operator(operators.SYMMETRIZE_TEXTURE_OT_mirrored_copy.bl_idname, text='Mirrored Copy', icon_value=get_icon_id('mirror_copy')) row = layout.row() op = row.operator(operators.SYMMETRIZE_TEXTURE_OT_use_2d_brush.bl_idname, text='2D Brush', icon_value=get_icon_id('sym_brush')) row = layout.row() row.label(text='Brush:') row = layout.split(align=True) row.alignment = 'RIGHT' row.label(text='Strength') row.prop(props, "brush_strength", text='', slider=True) row = layout.split(align=True) row.alignment = 'RIGHT' row.label(text='Falloff') row.prop(props, "brush_falloff", text='') row = layout.row() row.label(text='Image Mirror Axis:') row = layout.row() row.prop(props, "image_mirror_axis", expand=True)