Skip to content

Commit

Permalink
Merge branch 'Dev' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
xavier150 committed Nov 14, 2024
2 parents 79aa6c1 + 17dcb3f commit b91cb2d
Show file tree
Hide file tree
Showing 48 changed files with 365 additions and 210 deletions.
3 changes: 2 additions & 1 deletion ReleaseLogs/Version_4.3.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ Release Logs: https://github.com/xavier150/Blender-For-UnrealEngine-Addons/wiki/

### Version 4.3.2

- New: Addon renamed from "Blender For Unreal Engine" To "Unreal Engine Assets Exporter". This was needed to follow [Blender Extensions Terms of Service](https://extensions.blender.org/terms-of-service/) (Branding)
- New: Addon renamed from "Blender For Unreal Engine" To "Unreal Engine Assets Exporter".
This was needed to follow [Blender Extensions Terms of Service](https://extensions.blender.org/terms-of-service/) (Branding)
11 changes: 11 additions & 0 deletions ReleaseLogs/Version_4.3.9.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Unreal Engine Assets Exporter - Release Log
Release Logs: https://github.com/xavier150/Blender-For-UnrealEngine-Addons/wiki/Release-Logs

### Version 4.3.9

- Changes: Updated fbxio for Blender 4.3.
- Fixed: Animation UI not visible on linked Armatures.
- Fixed: Generated Builds for Blender 4.1 and olders version is wrong.
- Fixed: Import scripts do not works. (wrong import call in the scripts)
- Fixed: UI Script produce scripts errors when object is not select.
- Fixed: UI is hiddend when bfu_export_type is not "export_recursive".
2 changes: 0 additions & 2 deletions blender-for-unrealengine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,6 @@
if "bfu_cached_asset_list" in locals():
importlib.reload(bfu_cached_asset_list)

bl_info = {}

class BFUCachedAction(bpy.types.PropertyGroup):
"""
Represents a cached action for Blender File Utils (BFU).
Expand Down
2 changes: 1 addition & 1 deletion blender-for-unrealengine/addon_generate_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"schema_version": [1,0,0],
"blender_manifest": {
"id": "unrealengine_assets_exporter",
"version": [4,3,8],
"version": [4,3,9],
"name": "Unreal Engine Assets Exporter",
"tagline": "Allows to batch export and import in Unreal Engine",
"maintainer": "Loux Xavier (BleuRaven) [email protected]",
Expand Down
2 changes: 1 addition & 1 deletion blender-for-unrealengine/bbam/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def install_from_blender_with_build_data(addon_path, addon_manifest_data):
for target_build_name in addon_manifest_data["builds"]:
# Create temporary addon folder
temp_addon_path = addon_file_management.create_temp_addon_folder(
addon_path, addon_manifest_data, target_build_name
addon_path, addon_manifest_data, target_build_name, config.show_debug
)
# Zip the addon folder for installation
zip_file = addon_file_management.zip_addon_folder(
Expand Down
2 changes: 1 addition & 1 deletion blender-for-unrealengine/bbam/addon_file_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def zip_addon_folder(src, addon_path, addon_manifest_data, target_build_name, bl
print("Start creating simple ZIP file with root folder using shutil")

# Specify the root folder name inside the ZIP file
root_folder_name = "my_addon_root_folder"
root_folder_name = build_data["module"]

# Create a temporary directory
with tempfile.TemporaryDirectory() as temp_dir:
Expand Down
122 changes: 96 additions & 26 deletions blender-for-unrealengine/bbam/bl_info_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@
# ----------------------------------------------

import os
import re
import ast
from . import config
from . import utils

def generate_new_bl_info(addon_generate_config_data, target_build_name):
"""
Expand Down Expand Up @@ -63,6 +64,18 @@ def generate_new_bl_info(addon_generate_config_data, target_build_name):

return data

def format_bl_info_lines(data):
# Format the new `bl_info` dictionary with line breaks and indentation
new_bl_info_lines = ["bl_info = {"]
items = list(data.items())
for i, (key, value) in enumerate(items):
if i < len(items) - 1:
new_bl_info_lines.append(f" '{key}': {repr(value)},")
else:
new_bl_info_lines.append(f" '{key}': {repr(value)}")
new_bl_info_lines.append("}\n") # Close `bl_info` and add an extra line break for readability
return new_bl_info_lines

def update_file_bl_info(addon_path, data, show_debug=False):
"""
Updates the `bl_info` dictionary in the addon's __init__.py file with new data.
Expand All @@ -74,28 +87,85 @@ def update_file_bl_info(addon_path, data, show_debug=False):
"""
addon_init_file_path = os.path.join(addon_path, "__init__.py")

# Format the new `bl_info` dictionary with line breaks and indentation
new_bl_info_lines = ["bl_info = {\n"]
for key, value in data.items():
new_bl_info_lines.append(f" '{key}': {repr(value)},\n")
new_bl_info_lines.append("}\n\n") # Close `bl_info` and add an extra line break for readability

# Read the existing lines of the __init__.py file
with open(addon_init_file_path, 'r') as file:
lines = file.readlines()

# Write the updated lines, replacing the old `bl_info` if it exists
with open(addon_init_file_path, "w") as file:
in_bl_info = False
for line in lines:
# Detect the start of `bl_info`
if line.strip().startswith("bl_info = {") and not in_bl_info:
in_bl_info = True
file.writelines(new_bl_info_lines) # Write the new `bl_info` dictionary
elif in_bl_info and line.strip() == "}":
in_bl_info = False # End of `bl_info`, but skip this closing brace line
elif not in_bl_info:
file.write(line) # Write all other lines unchanged

if show_debug:
print(f"Addon bl_info successfully updated at: {addon_init_file_path}")
result = replace_file_bl_info(addon_init_file_path, data)
if result is False:
result = add_new_bl_info(addon_init_file_path, data)

if result is False:
utils.print_red(f"Failed to replace or add bl_info! File: {addon_init_file_path}")

if search_file_bl_info(addon_init_file_path):
if show_debug:
print(f"Addon bl_info successfully updated at: {addon_init_file_path}")
return
else:
utils.print_red(f"Failed to found bl_info after update!: {addon_init_file_path}")



def search_file_bl_info(file_path):
with open(file_path, "r") as file:
content = file.read()
tree = ast.parse(content)

# Locate existing `bl_info` definition
for node in tree.body:
if isinstance(node, ast.Assign) and any(target.id == "bl_info" for target in node.targets):
return True
return False

def replace_file_bl_info(file_path, data):
with open(file_path, "r") as file:
content = file.read()
tree = ast.parse(content)

# Locate existing `bl_info` definition
start_bl_info = None
end_bl_info = None
for index, node in enumerate(tree.body):
if isinstance(node, ast.Assign) and any(target.id == "bl_info" for target in node.targets):
start_bl_info = node.lineno - 1 # Start line of `bl_info`
end_bl_info = node.end_lineno # End line of `bl_info`
break

if start_bl_info is not None and end_bl_info is not None:
lines = content.splitlines()
# Remove the existing `bl_info` block
del lines[start_bl_info:end_bl_info]
# Insert the new `bl_info` block at the same position
new_bl_info_lines = format_bl_info_lines(data)
lines[start_bl_info:start_bl_info] = new_bl_info_lines

# Write the updated content back to the file
with open(file_path, "w") as file:
file.write("\n".join(lines))
return True
return False

def add_new_bl_info(file_path, data):
with open(file_path, "r") as file:
content = file.read()
tree = ast.parse(content)

# Find the line number of the `register` function
index_register = None
for index, node in enumerate(tree.body):
if isinstance(node, ast.FunctionDef) and node.name == "register":
index_register = node.lineno - 1 # `lineno` starts at 1, so we subtract 1 for zero-based index
break

lines = content.splitlines()
new_bl_info_lines = format_bl_info_lines(data)

if index_register is not None:
# Insert `bl_info` lines before the `register` function
for i, line in enumerate(new_bl_info_lines):
lines.insert(index_register + i, line)
else:
# If `register` is not found, append `bl_info` at the end
lines.extend(new_bl_info_lines)

# Write the updated content back to the file
with open(file_path, "w") as file:
file.write("\n".join(lines))
return True
17 changes: 12 additions & 5 deletions blender-for-unrealengine/bbam/blender_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
# ----------------------------------------------

import os
from . import utils

def uninstall_addon_from_blender(bpy, pkg_id, module):
"""
Expand Down Expand Up @@ -56,11 +57,17 @@ def install_zip_addon_from_blender(bpy, zip_file, module):
if bpy.app.version >= (4, 2, 0):
# For Blender version 4.2.0 and above, install as an extension
print("Installing as extension...", zip_file)
bpy.ops.extensions.package_install_files(repo="user_default", filepath=zip_file, enable_on_install=True)
print("Extension installation complete.")
try:
bpy.ops.extensions.package_install_files(repo="user_default", filepath=zip_file, enable_on_install=True)
print("Extension installation complete.")
except Exception as e:
utils.print_red("An error occurred during installation:", str(e))
else:
# For earlier versions, install and enable as an addon
print("Installing as add-on...", zip_file)
bpy.ops.preferences.addon_install(overwrite=True, filepath=zip_file)
bpy.ops.preferences.addon_enable(module=module)
print("Add-on installation complete.")
try:
bpy.ops.preferences.addon_install(overwrite=True, filepath=zip_file)
bpy.ops.preferences.addon_enable(module=module)
print("Add-on installation complete.")
except Exception as e:
utils.print_red("An error occurred during installation:", str(e))
2 changes: 2 additions & 0 deletions blender-for-unrealengine/bbam/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@

# Folder where the generated build files will be stored
build_output_folder = "generated_builds"

show_debug = False
72 changes: 46 additions & 26 deletions blender-for-unrealengine/bbam/manifest_generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,11 @@
# ----------------------------------------------

import os
import toml
from toml.encoder import TomlEncoder

from . import config
from . import utils
from . import blender_utils

class MultiLineTomlEncoder(TomlEncoder):
"""
Custom TOML encoder that formats lists to display on multiple lines in the output.
"""
def dump_list(self, v):
"""
Formats a list to display each item on a new line in the TOML output.
Parameters:
v (list): The list to format for multi-line display.
Returns:
str: A formatted multi-line string representation of the list.
"""
output = "[\n"
for item in v:
output += f" {toml.encoder._dump_str(item)},\n" # Indent each item
output += "]"
return output

def generate_new_manifest(addon_generate_config_data, target_build_name):
"""
Expand Down Expand Up @@ -81,15 +60,53 @@ def generate_new_manifest(addon_generate_config_data, target_build_name):
data["website"] = manifest_data["website_url"]
data["type"] = manifest_data["type"]
data["tags"] = manifest_data["tags"]
data["permissions"] = manifest_data["permissions"]
data["blender_version_min"] = utils.get_str_version(build_data["blender_version_min"])
data["license"] = manifest_data["license"]
data["copyright"] = manifest_data["copyright"]
data["permissions"] = manifest_data["permissions"]
return data

def dump_list(v):
"""
Formats a list to display each item on a new line in the TOML output.
Parameters:
v (list): The list to format for multi-line display.
Returns:
str: A formatted multi-line string representation of the list.
"""
output = "[\n"
for item in v:
output += f" \"{str(item)}\",\n" # Indent each item and escape as a string
output += "]"
return output

def dict_to_toml(data):
"""
Convert a dictionary to a TOML-formatted string.
Parameters:
data (dict): The dictionary to format.
Returns:
str: A TOML-formatted string representation of the dictionary.
"""
toml_string = ""
for key, value in data.items():
if isinstance(value, dict):
toml_string += f"[{key}]\n" + dict_to_toml(value) # Recursive call for nested dictionaries
elif isinstance(value, list):
toml_string += f"{key} = {dump_list(value)}\n"
elif isinstance(value, str):
toml_string += f"{key} = \"{value}\"\n" # Add quotes for strings
else:
toml_string += f"{key} = {value}\n"
return toml_string

def save_addon_manifest(addon_path, data, show_debug=False):
"""
Saves the addon manifest as a TOML file using the MultiLineTomlEncoder for custom formatting.
Saves the addon manifest as a TOML file manually.
Parameters:
addon_path (str): Path to the addon's root folder.
Expand All @@ -98,9 +115,12 @@ def save_addon_manifest(addon_path, data, show_debug=False):
"""
addon_manifest_path = os.path.join(addon_path, config.blender_manifest)

# Save the manifest as a TOML file with custom encoder for multi-line list formatting
# Generate TOML content manually
toml_content = dict_to_toml(data)

# Save to file
with open(addon_manifest_path, "w") as file:
toml.dump(data, file, encoder=MultiLineTomlEncoder())
file.write(toml_content)

if show_debug:
print(f"Addon manifest saved successfully at: {addon_manifest_path}")
print(f"Addon manifest saved successfully at: {addon_manifest_path}")
3 changes: 3 additions & 0 deletions blender-for-unrealengine/bbam/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
# XavierLoux.com
# ----------------------------------------------

def print_red(*values):
print("\033[91m", *values, "\033[0m")

def get_str_version(data):
"""
Converts a list of version components into a version string.
Expand Down
4 changes: 2 additions & 2 deletions blender-for-unrealengine/bfu_addon_parts/bfu_panel_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ def draw(self, context: bpy.types.Context):
bfu_collision.bfu_collision_ui.draw_ui_object(layout, obj)
bfu_uv_map.bfu_uv_map_ui.draw_obj_ui(layout, obj)
bfu_light_map.bfu_light_map_ui.draw_obj_ui(layout, obj)
bfu_material.bfu_material_ui.draw_ui_object(layout)
bfu_vertex_color.bfu_vertex_color_ui.draw_ui_object(layout)
bfu_material.bfu_material_ui.draw_ui_object(layout, obj)
bfu_vertex_color.bfu_vertex_color_ui.draw_ui_object(layout, obj)
bfu_assets_references.bfu_asset_ref_ui.draw_ui(layout, obj)

# Animations
Expand Down
3 changes: 0 additions & 3 deletions blender-for-unrealengine/bfu_adv_object/bfu_adv_obj_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@

def draw_ui(layout: bpy.types.UILayout, obj: bpy.types.Object):

if obj is None:
return

scene = bpy.context.scene
addon_prefs = bfu_basics.GetAddonPrefs()

Expand Down
Loading

0 comments on commit b91cb2d

Please sign in to comment.