diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5b08dc1..e59ed99 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -31,7 +31,9 @@ jobs: run: uv sync --frozen - name: Lint - run: uv run --frozen ruff check . + run: | + uv run --frozen ruff format --check . + uv run --frozen ruff check . # - name: Test # TODO everything after pytest might not be needed @@ -54,20 +56,11 @@ jobs: uses: automas-dev/reusable-workflows/increment_version@main id: version - - name: Install Python - uses: actions/setup-python@v5 - with: - python-version-file: .python-version - - - name: Install UV - uses: astral-sh/setup-uv@v7 - - name: Set Version env: VERSION: ${{ steps.version.outputs.version }} run: | - uv version $VERSION - sed -i "s/DEV_BUILD/${VERSION}/g" src/quickbake/blender_manifest.toml + sed -i "s/^version = \"[^\"]\+\"$/version=\"${VERSION}\"/g" src/quickbake/blender_manifest.toml - name: Create Archive env: diff --git a/.gitignore b/.gitignore index b242830..675d2a5 100644 --- a/.gitignore +++ b/.gitignore @@ -95,3 +95,5 @@ dmypy.json # Cython debug symbols cython_debug/ + +release/ diff --git a/Makefile b/Makefile index 7aaeec1..50d2b83 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,32 @@ +INSTALL_DIR=$(HOME)/.config/blender/5.0/extensions/user_default/quickbake +ZIP_ARCHIVE_NAME=quickbake_0.0.0.zip + setup: uv sync +build_dev: + @mkdir -p release/ + @cd src/quickbake && zip $(PWD)/release/$(ZIP_ARCHIVE_NAME) * + +install: + rm -rf $(INSTALL_DIR)/* + cp -r src/quickbake/* $(INSTALL_DIR)/ + +run: install + blender + checks: lint test lint: + uv run ruff format --check uv run ruff check . format: + uv run ruff format uv run ruff check --fix . test: uv run pytest -.PHONY: setup install checks lint format test +.PHONY: setup build_dev install checks lint format test diff --git a/src/quickbake/bake.py b/src/quickbake/bake.py index 26d0a2c..fb769be 100644 --- a/src/quickbake/bake.py +++ b/src/quickbake/bake.py @@ -8,7 +8,7 @@ def setup_bake_nodes(obj): - '''Create material nodes required for baking.''' + """Create material nodes required for baking.""" _l.info('Creating bake nodes for object %s', obj.name) bake_nodes = [] @@ -27,7 +27,7 @@ def setup_bake_nodes(obj): def cleanup_bake_nodes(obj): - '''Remove material nodes created for baking by setup_bake_nodes.''' + """Remove material nodes created for baking by setup_bake_nodes.""" _l.info('Cleaning up bake nodes for object %s', obj.name) for mat in obj.data.materials: @@ -40,7 +40,7 @@ def cleanup_bake_nodes(obj): def setup_bake_uv(obj, name): - '''Create a uv layer to unwrap obj for baking.''' + """Create a uv layer to unwrap obj for baking.""" _l.info('Creating uv layer %s for baking', name) def unwrap_uv(obj, uv): @@ -75,7 +75,9 @@ def unwrap_uv(obj, uv): return bake_uv -def setup_bake_image(obj, bake_nodes, bake_name, bake_size, pass_name, reuse_tex, is_data=False): +def setup_bake_image( + obj, bake_nodes, bake_name, bake_size, pass_name, reuse_tex, is_data=False +): _l.info('Creating image for baking object %s', obj.name) image_name = obj.name + '_' + bake_name + '_' + pass_name diff --git a/src/quickbake/blender_manifest.toml b/src/quickbake/blender_manifest.toml index 2330f7c..b89e851 100644 --- a/src/quickbake/blender_manifest.toml +++ b/src/quickbake/blender_manifest.toml @@ -3,8 +3,7 @@ schema_version = "1.0.0" # Example of manifest file for a Blender extension # Change the values according to your extension id = "quickbake" -# the value DEV_BUILD is replaced with the version string by ci -version = "DEV_BUILD" +version = "0.0.0" name = "Quick Bake" tagline = "Fast baking for blender" maintainer = "Thomas Harrison " diff --git a/src/quickbake/material.py b/src/quickbake/material.py index 46887ab..b37971c 100644 --- a/src/quickbake/material.py +++ b/src/quickbake/material.py @@ -8,7 +8,9 @@ _l = logging.getLogger(__name__) -def setup_bake_material(obj, name, bake_uv_name, diffuse=None, roughness=None, normal=None): +def setup_bake_material( + obj, name, bake_uv_name, diffuse=None, roughness=None, normal=None +): _l.info('Creating material %s for object %s', name, obj.name) mat = bpy.data.materials.get(name) @@ -53,13 +55,11 @@ def make_tex_node(img, y): if diffuse is not None: diff_node = make_tex_node(diffuse, 400) - links.new(diff_node.outputs['Color'], - principled_node.inputs['Base Color']) + links.new(diff_node.outputs['Color'], principled_node.inputs['Base Color']) if roughness is not None: rough_node = make_tex_node(roughness, 100) - links.new(rough_node.outputs['Color'], - principled_node.inputs['Roughness']) + links.new(rough_node.outputs['Color'], principled_node.inputs['Roughness']) if normal is not None: norm_node = make_tex_node(normal, -200) @@ -67,7 +67,6 @@ def make_tex_node(img, y): norm_map_node.location.x -= 200 norm_map_node.location.y -= 200 links.new(norm_node.outputs['Color'], norm_map_node.inputs['Color']) - links.new(norm_map_node.outputs['Normal'], - principled_node.inputs['Normal']) + links.new(norm_map_node.outputs['Normal'], principled_node.inputs['Normal']) return mat diff --git a/src/quickbake/panel.py b/src/quickbake/panel.py index f9048a2..7aecc4d 100644 --- a/src/quickbake/panel.py +++ b/src/quickbake/panel.py @@ -8,15 +8,18 @@ class QuickBake_PT_main(bpy.types.Panel): """Creates a Sub-Panel in the Property Area of the 3D View.""" - bl_label = "Quick Bake" - bl_space_type = "VIEW_3D" - bl_region_type = "UI" - bl_category = "Tool" - bl_context = "objectmode" + bl_label = 'Quick Bake' + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_category = 'Tool' + bl_context = 'objectmode' def draw(self, context): """Override Panel draw method.""" layout = self.layout + assert layout is not None, 'Missing layout' + + assert context.scene is not None, 'Missing scene from context' row = layout.row() row.operator(QuickBake_OT_bake.bl_idname) @@ -26,31 +29,31 @@ def draw(self, context): layout.label(text='Texture') row = layout.row() - row.prop(props, "bake_name") + row.prop(props, 'bake_name') row = layout.row() - row.prop(props, "bake_uv") + row.prop(props, 'bake_uv') row = layout.row() - row.prop(props, "bake_size") + row.prop(props, 'bake_size') layout.separator() layout.label(text='Material') row = layout.row() - row.prop(props, "create_mat") + row.prop(props, 'create_mat') row = layout.row() - row.prop(props, "mat_name") + row.prop(props, 'mat_name') layout.separator() layout.label(text='Options') row = layout.row() row.enabled = not props.create_mat - row.prop(props, "reuse_tex") + row.prop(props, 'reuse_tex') row = layout.row() row.enabled = not props.create_mat - row.prop(props, "clean_up") + row.prop(props, 'clean_up') # layout.separator() # layout.label(text='Output') diff --git a/src/quickbake/properties.py b/src/quickbake/properties.py index 7911d4c..7585100 100644 --- a/src/quickbake/properties.py +++ b/src/quickbake/properties.py @@ -1,126 +1,101 @@ +# pyright: reportInvalidTypeForm=false import bpy class QuickBakeToolPropertyGroup(bpy.types.PropertyGroup): - reuse_tex: bpy.props.BoolProperty( # type: ignore - name="Re-use Texture", - description="Use the texture from previous bakes", - default=True + reuse_tex: bpy.props.BoolProperty( + name='Re-use Texture', + description='Use the texture from previous bakes', + default=True, ) - clean_up: bpy.props.BoolProperty( # type: ignore - name="Clean Up", - description="Remove generated nodes after baking", - default=True + clean_up: bpy.props.BoolProperty( + name='Clean Up', description='Remove generated nodes after baking', default=True ) - create_mat: bpy.props.BoolProperty( # type: ignore - name="Create Material", - description="Create a material after baking and assign it.", - default=True + create_mat: bpy.props.BoolProperty( + name='Create Material', + description='Create a material after baking and assign it.', + default=True, ) - mat_name: bpy.props.StringProperty( # type: ignore - name="Name", - description="Name used to create a new material after baking", - default="BakeMaterial" + mat_name: bpy.props.StringProperty( + name='Name', + description='Name used to create a new material after baking', + default='BakeMaterial', ) - save_img: bpy.props.BoolProperty( # type: ignore - name="Save Images", - description="Write images to file after baking", - default=False + save_img: bpy.props.BoolProperty( + name='Save Images', + description='Write images to file after baking', + default=False, ) - image_path: bpy.props.StringProperty( # type: ignore - name="Texture Path", - description="Directory for baking output", + image_path: bpy.props.StringProperty( + name='Texture Path', + description='Directory for baking output', default='', - subtype='DIR_PATH' + subtype='DIR_PATH', ) - bake_name: bpy.props.StringProperty( # type: ignore - name="Name", - description="Name used fot the baked texture images", - default="BakeTexture" + bake_name: bpy.props.StringProperty( + name='Name', + description='Name used fot the baked texture images', + default='BakeTexture', ) - bake_uv: bpy.props.StringProperty( # type: ignore - name="UV", - description="Name used fot the uv bake layer", - default="bake_uv" + bake_uv: bpy.props.StringProperty( + name='UV', description='Name used fot the uv bake layer', default='bake_uv' ) - bake_size: bpy.props.IntProperty( # type: ignore - name="Size", - description="Resolution for the bake texture", + bake_size: bpy.props.IntProperty( + name='Size', + description='Resolution for the bake texture', default=1024, soft_min=1024, - step=1024 + step=1024, ) - diffuse_enabled: bpy.props.BoolProperty( # type: ignore - name="Diffuse", - description="Bake the diffuse map", - default=True + diffuse_enabled: bpy.props.BoolProperty( + name='Diffuse', description='Bake the diffuse map', default=True ) - normal_enabled: bpy.props.BoolProperty( # type: ignore - name="Normal", - description="Bake the normal map", - default=True + normal_enabled: bpy.props.BoolProperty( + name='Normal', description='Bake the normal map', default=True ) - roughness_enabled: bpy.props.BoolProperty( # type: ignore - name="Roughness", - description="Bake the roughness map", - default=True + roughness_enabled: bpy.props.BoolProperty( + name='Roughness', description='Bake the roughness map', default=True ) - ao_enabled: bpy.props.BoolProperty( # type: ignore - name="Ao", - description="Bake the Ao map", - default=False + ao_enabled: bpy.props.BoolProperty( + name='Ao', description='Bake the Ao map', default=False ) - shadow_enabled: bpy.props.BoolProperty( # type: ignore - name="Shadow", - description="Bake the Shadow map", - default=False + shadow_enabled: bpy.props.BoolProperty( + name='Shadow', description='Bake the Shadow map', default=False ) - position_enabled: bpy.props.BoolProperty( # type: ignore - name="Position", - description="Bake the Position map", - default=False + position_enabled: bpy.props.BoolProperty( + name='Position', description='Bake the Position map', default=False ) - uv_enabled: bpy.props.BoolProperty( # type: ignore - name="Uv", - description="Bake the Uv map", - default=False + uv_enabled: bpy.props.BoolProperty( + name='Uv', description='Bake the Uv map', default=False ) - emit_enabled: bpy.props.BoolProperty( # type: ignore - name="Emit", - description="Bake the Emit map", - default=False + emit_enabled: bpy.props.BoolProperty( + name='Emit', description='Bake the Emit map', default=False ) - environment_enabled: bpy.props.BoolProperty( # type: ignore - name="Environment", - description="Bake the Environment map", - default=False + environment_enabled: bpy.props.BoolProperty( + name='Environment', description='Bake the Environment map', default=False ) - glossy_enabled: bpy.props.BoolProperty( # type: ignore - name="Glossy", - description="Bake the Glossy map", - default=False + glossy_enabled: bpy.props.BoolProperty( + name='Glossy', description='Bake the Glossy map', default=False ) - transmission_enabled: bpy.props.BoolProperty( # type: ignore - name="Transmission", - description="Bake the Transmission map", - default=False + transmission_enabled: bpy.props.BoolProperty( + name='Transmission', description='Bake the Transmission map', default=False ) diff --git a/src/quickbake/tmp.py b/src/quickbake/tmp.py index ee73bc9..178ed32 100644 --- a/src/quickbake/tmp.py +++ b/src/quickbake/tmp.py @@ -16,7 +16,6 @@ # Due to the presence of any multiple materials, it seems necessary to iterate on all the materials, and assign them a node + the image to bake. for mat in obj.data.materials: - mat.use_nodes = True # Here it is assumed that the materials have been created with nodes, otherwise it would not be possible to assign a node for the Bake, so this step is a bit useless nodes = mat.node_tree.nodes texture_node = nodes.new('ShaderNodeTexImage')