Total rewrite of my question
From this post, I've greatly simplified my approach:
bpy.ops.wm.append(
filepath="Skin.blend",
directory=(addon_path, "Skin.blend"),
filename="Skin")
bpy.ops.wm.append(
filepath="Skin.blend",
directory=(addon_path, "Skin.blend"),
filename="imggen")
Obviously, the problem I have is addon_path
there. I have as yet been unable to figure a way of calling the packed blend file from within the addon zip. If I use the OS path to the file it works perfectly.
Update
Trying a different approach now, with this bit of code:
with bpy.data.libraries.load(filepath, link=True) as (data_from, data_to):
data_to.objects = [name for name in data_from.objects if name.startswith("S")]
Blender now sees the file properly, but it won't load it.
Traceback (most recent call last): File "/path/to/file/addon test.blend/ui template", line 53, in < module >
OSError: load:path/to/file/addon test/skin/Skin.blend failed to open blend file
It's not telling me why it fails, it's just failing.
If I pack it up and try to install it I get this:
File "/home/maker/Downloads/blender-2.93.6-linux-x64/2.93/scripts/modules/addon_utils.py", line 351, in enable
mod = __import__(module_name)
File "/home/maker/.config/blender/2.93/scripts/addons/DIPSS/__init__.py", line 53, in <module>
with bpy.data.libraries.load(filepath, link=True) as (data_from, data_to):
AttributeError: '_RestrictData' object has no attribute 'libraries'
Update I've tried a hundred different things to get the file paths to work and the closest I've got now is this:
skindir = os.path.dirname(os.path.abspath(__file__))
skinmat = "\\Material\\"
skingen = "\\Text\\"
bpy.ops.wm.append(
filepath="Skin.blend",
directory=skindir + skinmat,
filename="Skin")
bpy.ops.wm.append(
filepath="Skin.blend",
directory=skindir + skingen,
filename="imggen")
This almost works. When I try to run it in my test file it tells me
cannot use current file as library
When I pack it and try to install the addon, I get something a bit more involved:
File "/home/maker/Downloads/blender-2.93.6-linux-x64/2.93/scripts/modules/addon_utils.py", line 351, in enable
mod = __import__(module_name)
File "/home/maker/.config/blender/2.93/scripts/addons/DIPSS/__init__.py", line 74, in <module>
bpy.ops.wm.append(
File "/home/maker/Downloads/blender-2.93.6-linux-x64/2.93/scripts/modules/bpy/ops.py", line 126, in __call__
_BPyOpsSubModOp._view_layer_update(context)
File "/home/maker/Downloads/blender-2.93.6-linux-x64/2.93/scripts/modules/bpy/ops.py", line 88, in _view_layer_update
view_layer = context.view_layer
AttributeError: '_RestrictContext' object has no attribute 'view_layer'
I'm not sure why it's even looking for a view layer here. The register section of this script doesn't call for it as far as I can tell, but I may be missing something.
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
bpy.types.Scene.my_tool = PointerProperty(type=MyProperties)
def unregister():
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
del bpy.types.Scene.my_tool
if __name__ == "__main__":
register()
Update I've managed to make a button in an init file that will append and load the texture, thanks to this question.
Now I'm having trouble doing the same with my other script files. It would be neat if I could have them load the same way, from the same packed blend file, with the same button. But as-is I can't get them to append at all, with their own button. It doesn't spit out an error either, it just doesn't do anything.
USER = Path(resource_path('USER'))
ADDON = "DIPSS"
SKIN = "Skin.blend"
srcPath = USER / "scripts/addons" / ADDON / "assets" / SKIN
srcFile = str(srcPath)
skinmat = "\\Material\\"
skinscript = "\\Text\\"
This is the code that allows me to reference the packed blend file in the addon folder, no matter where blender puts it.
Ignore the order of these snippets, the buttons are in the right order, and I'll rearrange things once I have them working.
class WM_OT_Menu(Operator):
bl_label = "Load Menu"
bl_idname = "wm.load_menu"
def execute(self, context):
text_main= bpy.data.texts['menu_script.py']
context_c = context.copy()
context_c['edit_text'] = text_main
bpy.ops.text.run_script(context_c)
return {'FINISHED'}
class WM_OT_Mat(Operator):
bl_label = "Load Mat"
bl_idname = "wm.load_mat"
def execute(self, context):
bpy.ops.wm.append(
filepath="Skin.blend",
directory=srcFile + skinmat,
filename="Skin",
set_fake=True)
return {'FINISHED'}
class WM_OT_Script(Operator):
bl_label = "Load Scripts"
bl_idname = "wm.load_script"
def execute(self,context):
bpy.ops.wm.append(
filepath="Skin.blend",
directory=srcFile + skinscript,
filename="menu_script.py, imggen.py")
return {'FINISHED'}
These are the buttons. Load Mat
now works perfectly.
Load Scripts
doesn't do anything at all, not even spit an error.
And of course, Load Menu
is supposed to invoke one of the appended scripts, which it can't because the script isn't being appended.