''' 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 . ''' 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')