framework/cg/blender/scripts/addons/BakeWrangler/__init__.py
2023-10-25 10:54:36 +00:00

207 lines
13 KiB
Python

'''
Copyright (C) 2019-2023 Dancing Fortune Software All Rights Reserved
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/>.
'''
bl_info = {
'name': 'Bake Wrangler',
'description': 'Bake Wrangler aims to improve all baking tasks with a node based interface and provides additional bake passes',
'author': 'DFS',
'version': (1, 5, 'b11'),
'blender': (3, 6, 0),
'location': 'Editor Type > Bake Node Editor',
"warning": "Beta Version",
'doc_url': 'https://bake-wrangler.readthedocs.io',
"tracker_url": "https://blenderartists.org/t/bake-wrangler-node-based-baking-tool-set/",
"support": "COMMUNITY",
'category': 'Baking'}
import bpy
from . import nodes
from . import status_bar
# Preferences
class BakeWrangler_Preferences(bpy.types.AddonPreferences):
bl_idname = __package__
def update_icon(self, context):
if not self.show_icon:
status_bar.status_bar_icon.disable_bw_icon()
else:
status_bar.status_bar_icon.ensure_bw_icon()
# Message prefs
show_icon: bpy.props.BoolProperty(name="Show BW Icon in Status Bar", description="Shows an icon that changes color based on baking state and can be clicked on to bring up the log", default=True, update=update_icon)
text_msgs: bpy.props.BoolProperty(name="Messages to Text editor", description="Write messages to a text block in addition to the console", default=True)
clear_msgs: bpy.props.BoolProperty(name="Clear Old Messages", description="Clear the text block before each new bake", default=True)
wind_msgs: bpy.props.BoolProperty(name="Open Text in new Window", description="A new window will be opened displaying the text block each time a new bake is started", default=False)
wind_close: bpy.props.BoolProperty(name="Auto Close Text Window", description="Close the text window on successful bake completion", default=False)
# Node prefs
show_node_prefs: bpy.props.BoolProperty(name="Node Defaults", description="Default general node options", default=False)
def_filter_mesh: bpy.props.BoolProperty(name="Meshes", description="Show mesh type objects", default=True)
def_filter_curve: bpy.props.BoolProperty(name="Curves", description="Show curve type objects", default=True)
def_filter_surface: bpy.props.BoolProperty(name="Surfaces", description="Show surface type objects", default=True)
def_filter_meta: bpy.props.BoolProperty(name="Metas", description="Show meta type objects", default=True)
def_filter_font: bpy.props.BoolProperty(name="Fonts", description="Show font type objects", default=True)
def_filter_light: bpy.props.BoolProperty(name="Lights", description="Show light type objects", default=True)
def_filter_collection: bpy.props.BoolProperty(name="Collections", description="Toggle only collections", default=False)
def_show_adv: bpy.props.BoolProperty(name="Expand Advanced Settings", description="Expand advanced settings on node creation instead of starting with them collapsed", default=False)
invert_bakemod: bpy.props.BoolProperty(name="Invert Selected in Bake Modifiers", description="Inverts the selection method used by the Bake Modifiers option from ignoring viewport hidden modifiers to baking them", default=False)
# Render prefs
show_render_prefs: bpy.props.BoolProperty(name="Render Defaults", description="Default settings for rendering options", default=False)
def_samples: bpy.props.IntProperty(name="Default Bake Samples", description="The number of samples per pixel that new Pass nodes will be set to when created", default=1, min=1)
def_xres: bpy.props.IntProperty(name="Default Bake X Resolution", description="The X resolution new Pass nodes will be set to when created", default=1024, min=1, subtype='PIXEL')
def_yres: bpy.props.IntProperty(name="Default Bake Y Resolution", description="The Y resolution new Pass nodes will be set to when created", default=1024, min=1, subtype='PIXEL')
def_device: bpy.props.EnumProperty(name="Default Device", description="The render device new Pass nodes will be set to when created", items=nodes.node_tree.BakeWrangler_PassSettings.cycles_devices, default='CPU')
def_raydist: bpy.props.FloatProperty(name="Default Ray Distance", description="The ray distance that new Mesh nodes will use when created", default=0.01, step=1, min=0.0, unit='LENGTH')
def_max_ray_dist: bpy.props.FloatProperty(name="Default Max Ray Dist", description="The max ray distance that new Mesh nodes will use when created", default=0.0, step=1, min=0.0, unit='LENGTH')
def_margin: bpy.props.IntProperty(name="Default Margin", description="The margin that new Mesh nodes will use when created", default=0, min=0, subtype='PIXEL')
def_mask_margin: bpy.props.IntProperty(name="Default Mask Margin", description="The mask margin that new Mesh nodes will use when created", default=0, min=0, subtype='PIXEL')
ignore_vis: bpy.props.BoolProperty(name="Objects Always Visible", description="Enable to ignore the visibility of selected objects when baking, making them visible regardless of settings in blender", default=False)
# Ouput prefs
show_output_prefs: bpy.props.BoolProperty(name="Output Defaults", description="Default settings for output options", default=False)
def_format: bpy.props.EnumProperty(name="Default Output Format", description="The format new Output nodes will use when created", items=nodes.node_tree.BakeWrangler_OutputSettings.img_format, default='PNG')
def_xout: bpy.props.IntProperty(name="Default Output X Resolution", description="The X resolution new Output nodes will be set to when created", default=1024, min=1, subtype='PIXEL')
def_yout: bpy.props.IntProperty(name="Default Output Y Resolution", description="The Y resolution new Output nodes will be set to when created", default=1024, min=1, subtype='PIXEL')
def_outpath: bpy.props.StringProperty(name="Default Output Path", description="The path new Output nodes will use when created", default="", subtype='DIR_PATH')
def_outname: bpy.props.StringProperty(name="Default Output Name", description="The name new Output nodes will use when created", default="Image", subtype='FILE_NAME')
make_dirs: bpy.props.BoolProperty(name="Create Paths", description="If selected path doesn't exist, try to create it", default=False)
auto_open: bpy.props.BoolProperty(name="Auto open bakes", description="Automatically open the baked image in blender if it isn't already open", default=True)
save_packed: bpy.props.BoolProperty(name="Save packed images", description="Prior to baking, save any packed images with changes or they will not apply during the bake", default=False)
save_images: bpy.props.BoolProperty(name="Save unpacked images", description="Prior to baking, save any unpacked images with changes or they will not apply during the bake", default=False)
img_non_color: bpy.props.EnumProperty(name="Non-Color", description="Color space to use as non-color when alternative color spaces are in use", items=nodes.node_tree.BakeWrangler_OutputSettings.img_color_spaces)
# Performance prefs
fact_start: bpy.props.BoolProperty(name="Disable Add-ons", description="Disable add-ons in the background baking instance (faster load times and some 3rd party add-ons can crash the process)", default=True)
retrys: bpy.props.IntProperty(name="Retries", description="On bake failure retry this many times", default=0)
# Dev prefs
debug: bpy.props.BoolProperty(name="Debug", description="Enable additional debugging output", default=False)
def draw(self, context):
layout = self.layout
colprefs = layout.column(align=False)
coltext = colprefs.column(align=False)
coltext.prop(self, "show_icon")
coltext.prop(self, "text_msgs")
if self.text_msgs:
box = coltext.box()
box.prop(self, "clear_msgs")
box.prop(self, "wind_msgs")
row = box.row(align=True)
row.label(icon='THREE_DOTS')
row.prop(self, "wind_close")
if self.wind_msgs:
row.enabled = True
else:
row.enabled = False
# Node prefs
box = colprefs.box()
if not self.show_node_prefs:
box.prop(self, "show_node_prefs", icon="DISCLOSURE_TRI_RIGHT", emboss=False)
else:
box.prop(self, "show_node_prefs", icon="DISCLOSURE_TRI_DOWN", emboss=False)
col = box.column(align=False)
row = col.row(align=True)
row.alignment = 'LEFT'
row.label(text="Filter:")
row1 = row.row(align=True)
row1.alignment = 'LEFT'
row1.prop(self, "def_filter_mesh", text="", icon='MESH_DATA')
row1.prop(self, "def_filter_curve", text="", icon='CURVE_DATA')
row1.prop(self, "def_filter_surface", text="", icon='SURFACE_DATA')
row1.prop(self, "def_filter_meta", text="", icon='META_DATA')
row1.prop(self, "def_filter_font", text="", icon='FONT_DATA')
row1.prop(self, "def_filter_light", text="", icon='LIGHT_DATA')
if self.def_filter_collection:
row1.enabled = False
row2 = row.row(align=False)
row2.alignment = 'LEFT'
row2.prop(self, "def_filter_collection", text="", icon='GROUP')
col.prop(self, "def_show_adv")
col.prop(self, "invert_bakemod")
# Render prefs
box = colprefs.box()
if not self.show_render_prefs:
box.prop(self, "show_render_prefs", icon="DISCLOSURE_TRI_RIGHT", emboss=False)
else:
box.prop(self, "show_render_prefs", icon="DISCLOSURE_TRI_DOWN", emboss=False)
col = box.column(align=False)
col.prop(self, "def_samples", text="Samples")
col1 = col.column(align=True)
col1.prop(self, "def_xres", text="X")
col1.prop(self, "def_yres", text="Y")
col.prop(self, "def_device", text="Device")
col.prop(self, "def_margin", text="Margin")
col.prop(self, "def_mask_margin", text="Mask Margin")
col.prop(self, "def_raydist", text="Ray Distance")
col.prop(self, "def_max_ray_dist", text="Max Ray Dist")
col.prop(self, "ignore_vis")
# Output prefs
box = colprefs.box()
if not self.show_output_prefs:
box.prop(self, "show_output_prefs", icon="DISCLOSURE_TRI_RIGHT", emboss=False)
else:
box.prop(self, "show_output_prefs", icon="DISCLOSURE_TRI_DOWN", emboss=False)
col = box.column(align=False)
col.prop(self, "def_format", text="Format")
col1 = col.column(align=True)
col1.prop(self, "def_xout", text="X")
col1.prop(self, "def_yout", text="Y")
col2 = col.column(align=True)
col2.prop(self, "def_outpath", text="Image Path")
col2.prop(self, "def_outname", text="Image Name")
col.prop(self, "make_dirs")
col.prop(self, "auto_open")
# Dev prefs
col = colprefs.column(align=True)
col.prop(self, "fact_start")
col.prop(self, "save_packed")
col.prop(self, "save_images")
col.prop(self, "retrys")
if 'Non-Color' not in bpy.types.ColorManagedInputColorspaceSettings.bl_rna.properties['name'].enum_items.keys():
col.prop(self, "img_non_color")
col.prop(self, "debug")
def register():
from bpy.utils import register_class
register_class(BakeWrangler_Preferences)
# Add status property to the window manager
bpy.types.WindowManager.bw_status = bpy.props.IntProperty(name="Bake Wrangler Status", default=0)
bpy.types.WindowManager.bw_lastlog = bpy.props.StringProperty(name="Bake Wangler Log", default="")
bpy.types.WindowManager.bw_lastfile = bpy.props.StringProperty(name="Bake Wangler Temp Blend", default="")
nodes.register()
status_bar.register()
def unregister():
from bpy.utils import unregister_class
nodes.unregister()
status_bar.unregister()
unregister_class(BakeWrangler_Preferences)
# Remove status property from window manager
delattr(bpy.types.WindowManager, 'bw_status')