190 lines
6.2 KiB
Python
190 lines
6.2 KiB
Python
'''
|
|
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 <http://www.gnu.org/licenses/>.
|
|
'''
|
|
|
|
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)
|