From 7a7a7bf800f599e390d893dec9b0f1e74b2c6aa3 Mon Sep 17 00:00:00 2001 From: SimonNordon4 Date: Thu, 12 Sep 2024 13:40:45 +1000 Subject: [PATCH] stable and feature complete. --- lightmapper/lightmapper_operators.py | 42 ++++++++++++++++- lightmapper/lightmapper_panel.py | 66 +++++++++++++++++++++------ lightmapper/lightmapper_properties.py | 6 +-- 3 files changed, 97 insertions(+), 17 deletions(-) diff --git a/lightmapper/lightmapper_operators.py b/lightmapper/lightmapper_operators.py index f96aedb..7d0127e 100644 --- a/lightmapper/lightmapper_operators.py +++ b/lightmapper/lightmapper_operators.py @@ -2,6 +2,10 @@ import bpy.utils import bmesh +import bpy.ops + +import os.path + class LIGHTMAPPER_OT_create_lightmap_uv(bpy.types.Operator): @@ -154,6 +158,35 @@ def __init__(self): self.scene_state = SceneState() self.lightmapper_props = bpy.context.scene.lightmapper_properties + + def _validate_export_path(self, context): + export_path = self.lightmapper_props.export_path + if not export_path: + self.report({'ERROR'}, "Export path not set.") + return False + + if not os.path.exists(export_path): + self.report({'ERROR'}, "Export path does not exist.") + return False + + if not os.path.isdir(export_path): + self.report({'ERROR'}, "Export path is not a directory.") + return False + + return True + + def _validate_bake_objects(self, context): + """ Ensure the object is in a state that supports baking. """ + if not self.bake_object: + self.report({'ERROR'}, "No mesh objects selected.") + return False + + # Ensure we're in object mode. + if context.mode != 'OBJECT': + self.report({'ERROR'}, "Lightmap baking requires object mode.") + return False + pass + def _validate_mesh_objects(self, context, mesh_objects): """ Ensure the object is in a state that supports baking. """ @@ -391,12 +424,17 @@ def execute(self, context): return {'RUNNING_MODAL'} def bake(self, context): + + yield 1 - print("Starting lightmapping process...") # 1. Validate that the selected objects are suitable for lightmapping. mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH'] + # deselect everything so we're not baking lights and empties. + bpy.ops.object.select_all(action='DESELECT') + if not self._validate_export_path(context): + yield -1 if not self._validate_mesh_objects(context, mesh_objects): yield -1 @@ -416,6 +454,7 @@ def bake(self, context): yield 1 self._setup_bake_settings() + while bpy.ops.object.bake('INVOKE_DEFAULT', type='DIFFUSE') != {'RUNNING_MODAL'}: yield 1 # 'INVOKE_DEFAULT' will give us the progress bar. while not self.bake_image.is_dirty: @@ -476,3 +515,4 @@ def unregister(): if __name__ == "__main__": register() + diff --git a/lightmapper/lightmapper_panel.py b/lightmapper/lightmapper_panel.py index 6d9b784..a7a685c 100644 --- a/lightmapper/lightmapper_panel.py +++ b/lightmapper/lightmapper_panel.py @@ -1,6 +1,8 @@ import bpy -class LightmapperPanel(bpy.types.Panel): +import bpy.utils + +class LIGHTMAPPER_PT_main_panel(bpy.types.Panel): bl_idname = "OBJECT_PT_lightmapper_panel" bl_label = "Lightmapper Panel" bl_description = "This is a lightmapper panel, for starting a new addon." @@ -16,24 +18,62 @@ def draw_header(self, context): def draw(self, context): layout = self.layout scene = context.scene - lightmapper_props = scene.lightmapper_properties + props = scene.lightmapper_properties + + # Create UV Lightmap + box = layout.box() + box.label(text="Lightmap UV", icon='UV') + box.operator("lightmapper.create_lightmap_uv", icon='ADD') + # Lightmap Resolution + box = layout.box() + box.label(text="Lightmap Resolution", icon='TEXTURE') + col = box.column(align=True) + row = col.row(align=True) + row.prop(props, "lightmap_width", text="Width") + row.prop(props, "lightmap_height", text="Height") - - layout.operator("lightmapper.create_lightmap_uv") - + # Resolution Presets + row = col.row(align=True) + row.operator("lightmapper.set_resolution", text="1K").resolution = 1024 + row.operator("lightmapper.set_resolution", text="2K").resolution = 2048 + row.operator("lightmapper.set_resolution", text="4K").resolution = 4096 + row.operator("lightmapper.set_resolution", text="8K").resolution = 8192 - layout.prop(scene.lightmapper_properties, "lightmap_width") - layout.prop(scene.lightmapper_properties, "lightmap_height") - layout.prop(scene.lightmapper_properties, "export_path") - layout.prop(scene.lightmapper_properties, "bake_target", expand=True) - - layout.operator("lightmapper.bake_lightmap") + # Export Settings + box = layout.box() + box.label(text="Export Settings", icon='EXPORT') + box.prop(props, "export_path") + box.label(text="Bake Name", icon='TEXTURE') + export_row = box.row(align=True) + export_row.prop(props, "bake_name", expand=True) + + # Bake Button + layout.separator() + row = layout.row() + row.scale_y = 2 + row.operator("lightmapper.bake_lightmap", text="Bake Lightmap", icon='RENDER_STILL') + +class LIGHTMAPPER_OT_set_resolution(bpy.types.Operator): + bl_idname = "lightmapper.set_resolution" + bl_label = "Set Resolution" + bl_description = "Set the resolution for the lightmap" + resolution: bpy.props.IntProperty() + + def execute(self, context): + scene = context.scene + scene.lightmapper_properties.lightmap_width = self.resolution + scene.lightmapper_properties.lightmap_height = self.resolution + self.report({'INFO'}, f"Resolution set to {self.resolution}x{self.resolution}") + return {'FINISHED'} + def register(): - bpy.utils.register_class(LightmapperPanel) + bpy.utils.register_class(LIGHTMAPPER_OT_set_resolution) + bpy.utils.register_class(LIGHTMAPPER_PT_main_panel) def unregister(): - bpy.utils.unregister_class(LightmapperPanel) + bpy.utils.unregister_class(LIGHTMAPPER_PT_main_panel) + bpy.utils.unregister_class(LIGHTMAPPER_OT_set_resolution) diff --git a/lightmapper/lightmapper_properties.py b/lightmapper/lightmapper_properties.py index 21f36ed..122fef4 100644 --- a/lightmapper/lightmapper_properties.py +++ b/lightmapper/lightmapper_properties.py @@ -26,8 +26,8 @@ class LIGHTMAPPER_PT_properties(bpy.types.PropertyGroup): subtype='DIR_PATH' ) # type: ignore - bake_target: EnumProperty( - name="Bake Target", + bake_name: EnumProperty( + name="Bake Name", description="Choose the bake target", items=[ ('ACTIVE_OBJECT', "Active Object", "Bake the active object"), @@ -35,7 +35,7 @@ class LIGHTMAPPER_PT_properties(bpy.types.PropertyGroup): ], default='ACTIVE_OBJECT' ) # type: ignore - + def register():