2025-12-09
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
Copyright (C) 2019 Remington Creative
|
||||
|
||||
This file is part of Atomic Data Manager.
|
||||
|
||||
Atomic Data Manager 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.
|
||||
|
||||
Atomic Data Manager 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 Atomic Data Manager. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
---
|
||||
|
||||
This package contains utility modules for version detection and API compatibility.
|
||||
|
||||
"""
|
||||
|
||||
from . import version
|
||||
from . import compat
|
||||
|
||||
__all__ = ['version', 'compat']
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
"""
|
||||
Copyright (C) 2019 Remington Creative
|
||||
|
||||
This file is part of Atomic Data Manager.
|
||||
|
||||
Atomic Data Manager 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.
|
||||
|
||||
Atomic Data Manager 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 Atomic Data Manager. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
---
|
||||
|
||||
This module provides API compatibility functions for handling differences
|
||||
between Blender 4.2 LTS, 4.5 LTS, and 5.0.
|
||||
|
||||
"""
|
||||
|
||||
import bpy
|
||||
from bpy.utils import register_class, unregister_class
|
||||
from . import version
|
||||
|
||||
|
||||
def safe_register_class(cls):
|
||||
"""
|
||||
Safely register a class, handling any version-specific registration issues.
|
||||
|
||||
Args:
|
||||
cls: The class to register
|
||||
|
||||
Returns:
|
||||
bool: True if registration succeeded, False otherwise
|
||||
"""
|
||||
try:
|
||||
register_class(cls)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Warning: Failed to register {cls.__name__}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def safe_unregister_class(cls):
|
||||
"""
|
||||
Safely unregister a class, handling any version-specific unregistration issues.
|
||||
|
||||
Args:
|
||||
cls: The class to unregister
|
||||
|
||||
Returns:
|
||||
bool: True if unregistration succeeded, False otherwise
|
||||
"""
|
||||
try:
|
||||
unregister_class(cls)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Warning: Failed to unregister {cls.__name__}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def get_addon_prefs():
|
||||
"""
|
||||
Get the addon preferences instance, compatible across versions.
|
||||
|
||||
Returns:
|
||||
AddonPreferences or None: The addon preferences instance if found
|
||||
"""
|
||||
prefs = bpy.context.preferences
|
||||
for addon in prefs.addons.values():
|
||||
ap = getattr(addon, "preferences", None)
|
||||
if ap and hasattr(ap, "enable_missing_file_warning"):
|
||||
return ap
|
||||
return None
|
||||
|
||||
|
||||
def get_geometry_nodes_modifier_node_group(modifier):
|
||||
"""
|
||||
Get the node group from a geometry nodes modifier, handling version differences.
|
||||
|
||||
Args:
|
||||
modifier: The modifier object
|
||||
|
||||
Returns:
|
||||
NodeGroup or None: The node group if available
|
||||
"""
|
||||
if not hasattr(modifier, 'type') or modifier.type != 'NODES':
|
||||
return None
|
||||
|
||||
# Check for node_group attribute (available in all supported versions)
|
||||
if hasattr(modifier, 'node_group') and modifier.node_group:
|
||||
return modifier.node_group
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def is_geometry_nodes_modifier(modifier):
|
||||
"""
|
||||
Check if a modifier is a geometry nodes modifier, compatible across versions.
|
||||
|
||||
Args:
|
||||
modifier: The modifier object
|
||||
|
||||
Returns:
|
||||
bool: True if the modifier is a geometry nodes modifier
|
||||
"""
|
||||
if not hasattr(modifier, 'type'):
|
||||
return False
|
||||
|
||||
return modifier.type == 'NODES'
|
||||
|
||||
|
||||
def get_node_tree_from_node(node):
|
||||
"""
|
||||
Get the node tree from a node, handling version differences.
|
||||
|
||||
Args:
|
||||
node: The node object
|
||||
|
||||
Returns:
|
||||
NodeTree or None: The node tree if available
|
||||
"""
|
||||
if hasattr(node, 'node_tree') and node.node_tree:
|
||||
return node.node_tree
|
||||
return None
|
||||
|
||||
|
||||
def get_scene_compositor_node_tree(scene):
|
||||
"""
|
||||
Get the compositor node tree from a scene, handling version differences.
|
||||
|
||||
In Blender 4.2/4.5: scene.node_tree
|
||||
In Blender 5.0+: scene.compositing_node_tree
|
||||
|
||||
Args:
|
||||
scene: The scene object
|
||||
|
||||
Returns:
|
||||
NodeTree or None: The compositor node tree if available
|
||||
"""
|
||||
# Blender 5.0+ uses compositing_node_tree
|
||||
if version.is_version_at_least(5, 0, 0):
|
||||
if hasattr(scene, 'compositing_node_tree') and scene.compositing_node_tree:
|
||||
return scene.compositing_node_tree
|
||||
else:
|
||||
# Blender 4.2/4.5 uses node_tree
|
||||
if hasattr(scene, 'node_tree') and scene.node_tree:
|
||||
return scene.node_tree
|
||||
return None
|
||||
@@ -0,0 +1,128 @@
|
||||
"""
|
||||
Copyright (C) 2019 Remington Creative
|
||||
|
||||
This file is part of Atomic Data Manager.
|
||||
|
||||
Atomic Data Manager 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.
|
||||
|
||||
Atomic Data Manager 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 Atomic Data Manager. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
---
|
||||
|
||||
This module provides version detection and comparison utilities for
|
||||
multi-version Blender support (4.2 LTS, 4.5 LTS, and 5.0).
|
||||
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
||||
# Version constants
|
||||
VERSION_4_2_LTS = (4, 2, 0)
|
||||
VERSION_4_5_LTS = (4, 5, 0)
|
||||
VERSION_5_0 = (5, 0, 0)
|
||||
|
||||
|
||||
def get_blender_version():
|
||||
"""
|
||||
Returns the current Blender version as a tuple (major, minor, patch).
|
||||
|
||||
Returns:
|
||||
tuple: (major, minor, patch) version numbers
|
||||
"""
|
||||
return bpy.app.version
|
||||
|
||||
|
||||
def get_version_string():
|
||||
"""
|
||||
Returns the current Blender version as a string (e.g., "4.2.0").
|
||||
|
||||
Returns:
|
||||
str: Version string in format "major.minor.patch"
|
||||
"""
|
||||
version = get_blender_version()
|
||||
return f"{version[0]}.{version[1]}.{version[2]}"
|
||||
|
||||
|
||||
def is_version_at_least(major, minor=0, patch=0):
|
||||
"""
|
||||
Check if the current Blender version is at least the specified version.
|
||||
|
||||
Args:
|
||||
major (int): Major version number
|
||||
minor (int): Minor version number (default: 0)
|
||||
patch (int): Patch version number (default: 0)
|
||||
|
||||
Returns:
|
||||
bool: True if current version >= specified version
|
||||
"""
|
||||
current = get_blender_version()
|
||||
target = (major, minor, patch)
|
||||
|
||||
if current[0] != target[0]:
|
||||
return current[0] > target[0]
|
||||
if current[1] != target[1]:
|
||||
return current[1] > target[1]
|
||||
return current[2] >= target[2]
|
||||
|
||||
|
||||
def is_version_less_than(major, minor=0, patch=0):
|
||||
"""
|
||||
Check if the current Blender version is less than the specified version.
|
||||
|
||||
Args:
|
||||
major (int): Major version number
|
||||
minor (int): Minor version number (default: 0)
|
||||
patch (int): Patch version number (default: 0)
|
||||
|
||||
Returns:
|
||||
bool: True if current version < specified version
|
||||
"""
|
||||
return not is_version_at_least(major, minor, patch)
|
||||
|
||||
|
||||
def get_version_category():
|
||||
"""
|
||||
Returns the version category string for the current Blender version.
|
||||
|
||||
Returns:
|
||||
str: '4.2', '4.5', or '5.0' based on the current version
|
||||
"""
|
||||
version = get_blender_version()
|
||||
major, minor = version[0], version[1]
|
||||
|
||||
if major == 4:
|
||||
if minor < 5:
|
||||
return '4.2'
|
||||
else:
|
||||
return '4.5'
|
||||
elif major >= 5:
|
||||
return '5.0'
|
||||
else:
|
||||
# Fallback for older versions
|
||||
return f"{major}.{minor}"
|
||||
|
||||
|
||||
def is_version_4_2():
|
||||
"""Check if running Blender 4.2 LTS (4.2.x only, not 4.3 or 4.4)."""
|
||||
version = get_blender_version()
|
||||
return version[0] == 4 and version[1] == 2
|
||||
|
||||
|
||||
def is_version_4_5():
|
||||
"""Check if running Blender 4.5 LTS."""
|
||||
return is_version_at_least(4, 5, 0) and is_version_less_than(5, 0, 0)
|
||||
|
||||
|
||||
def is_version_5_0():
|
||||
"""Check if running Blender 5.0 or later."""
|
||||
return is_version_at_least(5, 0, 0)
|
||||
|
||||
Reference in New Issue
Block a user