mirror of
https://github.com/ynput/ayon-core.git
synced 2026-01-01 16:34:53 +01:00
Merge pull request #1528 from pypeclub/bugfix/1050-blender-cannot-initialize-avalon-if-blender_user_scripts-is-already-used
This commit is contained in:
commit
1373d7f8a1
3 changed files with 149 additions and 6 deletions
|
|
@ -23,18 +23,32 @@ def add_implementation_envs(env, _app):
|
||||||
env["PYTHONPATH"] = os.pathsep.join(python_path_parts)
|
env["PYTHONPATH"] = os.pathsep.join(python_path_parts)
|
||||||
|
|
||||||
# Modify Blender user scripts path
|
# Modify Blender user scripts path
|
||||||
|
previous_user_scripts = set()
|
||||||
|
# Implementation path is added to set for easier paths check inside loops
|
||||||
|
# - will be removed at the end
|
||||||
|
previous_user_scripts.add(implementation_user_script_path)
|
||||||
|
|
||||||
|
openpype_blender_user_scripts = (
|
||||||
|
env.get("OPENPYPE_BLENDER_USER_SCRIPTS") or ""
|
||||||
|
)
|
||||||
|
for path in openpype_blender_user_scripts.split(os.pathsep):
|
||||||
|
if path and os.path.exists(path):
|
||||||
|
previous_user_scripts.add(os.path.normpath(path))
|
||||||
|
|
||||||
blender_user_scripts = env.get("BLENDER_USER_SCRIPTS") or ""
|
blender_user_scripts = env.get("BLENDER_USER_SCRIPTS") or ""
|
||||||
previous_user_scripts = []
|
|
||||||
for path in blender_user_scripts.split(os.pathsep):
|
for path in blender_user_scripts.split(os.pathsep):
|
||||||
if path and os.path.exists(path):
|
if path and os.path.exists(path):
|
||||||
path = os.path.normpath(path)
|
previous_user_scripts.add(os.path.normpath(path))
|
||||||
if path != implementation_user_script_path:
|
|
||||||
previous_user_scripts.append(path)
|
|
||||||
|
|
||||||
|
# Remove implementation path from user script paths as is set to
|
||||||
|
# `BLENDER_USER_SCRIPTS`
|
||||||
|
previous_user_scripts.remove(implementation_user_script_path)
|
||||||
|
env["BLENDER_USER_SCRIPTS"] = implementation_user_script_path
|
||||||
|
|
||||||
|
# Set custom user scripts env
|
||||||
env["OPENPYPE_BLENDER_USER_SCRIPTS"] = os.pathsep.join(
|
env["OPENPYPE_BLENDER_USER_SCRIPTS"] = os.pathsep.join(
|
||||||
previous_user_scripts
|
previous_user_scripts
|
||||||
)
|
)
|
||||||
env["BLENDER_USER_SCRIPTS"] = implementation_user_script_path
|
|
||||||
|
|
||||||
# Define Qt binding if not defined
|
# Define Qt binding if not defined
|
||||||
if not env.get("QT_PREFERRED_BINDING"):
|
if not env.get("QT_PREFERRED_BINDING"):
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ import traceback
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
|
from .lib import append_user_scripts
|
||||||
|
|
||||||
from avalon import api as avalon
|
from avalon import api as avalon
|
||||||
from pyblish import api as pyblish
|
from pyblish import api as pyblish
|
||||||
|
|
||||||
|
|
@ -29,7 +31,7 @@ def install():
|
||||||
pyblish.register_plugin_path(str(PUBLISH_PATH))
|
pyblish.register_plugin_path(str(PUBLISH_PATH))
|
||||||
avalon.register_plugin_path(avalon.Loader, str(LOAD_PATH))
|
avalon.register_plugin_path(avalon.Loader, str(LOAD_PATH))
|
||||||
avalon.register_plugin_path(avalon.Creator, str(CREATE_PATH))
|
avalon.register_plugin_path(avalon.Creator, str(CREATE_PATH))
|
||||||
|
append_user_scripts()
|
||||||
avalon.on("new", on_new)
|
avalon.on("new", on_new)
|
||||||
avalon.on("open", on_open)
|
avalon.on("open", on_open)
|
||||||
|
|
||||||
|
|
|
||||||
127
openpype/hosts/blender/api/lib.py
Normal file
127
openpype/hosts/blender/api/lib.py
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
import os
|
||||||
|
import traceback
|
||||||
|
import importlib
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
import addon_utils
|
||||||
|
|
||||||
|
|
||||||
|
def load_scripts(paths):
|
||||||
|
"""Copy of `load_scripts` from Blender's implementation.
|
||||||
|
|
||||||
|
It is possible that whis function will be changed in future and usage will
|
||||||
|
be based on Blender version.
|
||||||
|
"""
|
||||||
|
import bpy_types
|
||||||
|
|
||||||
|
loaded_modules = set()
|
||||||
|
|
||||||
|
previous_classes = [
|
||||||
|
cls
|
||||||
|
for cls in bpy.types.bpy_struct.__subclasses__()
|
||||||
|
]
|
||||||
|
|
||||||
|
def register_module_call(mod):
|
||||||
|
register = getattr(mod, "register", None)
|
||||||
|
if register:
|
||||||
|
try:
|
||||||
|
register()
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
else:
|
||||||
|
print("\nWarning! '%s' has no register function, "
|
||||||
|
"this is now a requirement for registerable scripts" %
|
||||||
|
mod.__file__)
|
||||||
|
|
||||||
|
def unregister_module_call(mod):
|
||||||
|
unregister = getattr(mod, "unregister", None)
|
||||||
|
if unregister:
|
||||||
|
try:
|
||||||
|
unregister()
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
def test_reload(mod):
|
||||||
|
# reloading this causes internal errors
|
||||||
|
# because the classes from this module are stored internally
|
||||||
|
# possibly to refresh internal references too but for now, best not to.
|
||||||
|
if mod == bpy_types:
|
||||||
|
return mod
|
||||||
|
|
||||||
|
try:
|
||||||
|
return importlib.reload(mod)
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
def test_register(mod):
|
||||||
|
if mod:
|
||||||
|
register_module_call(mod)
|
||||||
|
bpy.utils._global_loaded_modules.append(mod.__name__)
|
||||||
|
|
||||||
|
from bpy_restrict_state import RestrictBlend
|
||||||
|
|
||||||
|
with RestrictBlend():
|
||||||
|
for base_path in paths:
|
||||||
|
for path_subdir in bpy.utils._script_module_dirs:
|
||||||
|
path = os.path.join(base_path, path_subdir)
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
continue
|
||||||
|
|
||||||
|
bpy.utils._sys_path_ensure_prepend(path)
|
||||||
|
|
||||||
|
# Only add to 'sys.modules' unless this is 'startup'.
|
||||||
|
if path_subdir != "startup":
|
||||||
|
continue
|
||||||
|
for mod in bpy.utils.modules_from_path(path, loaded_modules):
|
||||||
|
test_register(mod)
|
||||||
|
|
||||||
|
addons_paths = []
|
||||||
|
for base_path in paths:
|
||||||
|
addons_path = os.path.join(base_path, "addons")
|
||||||
|
if not os.path.exists(addons_path):
|
||||||
|
continue
|
||||||
|
addons_paths.append(addons_path)
|
||||||
|
addons_module_path = os.path.join(addons_path, "modules")
|
||||||
|
if os.path.exists(addons_module_path):
|
||||||
|
bpy.utils._sys_path_ensure_prepend(addons_module_path)
|
||||||
|
|
||||||
|
if addons_paths:
|
||||||
|
# Fake addons
|
||||||
|
origin_paths = addon_utils.paths
|
||||||
|
|
||||||
|
def new_paths():
|
||||||
|
paths = origin_paths() + addons_paths
|
||||||
|
return paths
|
||||||
|
|
||||||
|
addon_utils.paths = new_paths
|
||||||
|
addon_utils.modules_refresh()
|
||||||
|
|
||||||
|
# load template (if set)
|
||||||
|
if any(bpy.utils.app_template_paths()):
|
||||||
|
import bl_app_template_utils
|
||||||
|
bl_app_template_utils.reset(reload_scripts=False)
|
||||||
|
del bl_app_template_utils
|
||||||
|
|
||||||
|
for cls in bpy.types.bpy_struct.__subclasses__():
|
||||||
|
if cls in previous_classes:
|
||||||
|
continue
|
||||||
|
if not getattr(cls, "is_registered", False):
|
||||||
|
continue
|
||||||
|
for subcls in cls.__subclasses__():
|
||||||
|
if not subcls.is_registered:
|
||||||
|
print(
|
||||||
|
"Warning, unregistered class: %s(%s)" %
|
||||||
|
(subcls.__name__, cls.__name__)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def append_user_scripts():
|
||||||
|
user_scripts = os.environ.get("OPENPYPE_BLENDER_USER_SCRIPTS")
|
||||||
|
if not user_scripts:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
load_scripts(user_scripts.split(os.pathsep))
|
||||||
|
except Exception:
|
||||||
|
print("Couldn't load user scripts \"{}\"".format(user_scripts))
|
||||||
|
traceback.print_exc()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue