1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# references
# https://s-nako.work/2020/09/blender-error-attributeerror-_restrictcontext-object-has-no-attribute-view_layer/
# https://web.archive.org/web/20210925181415/https://blenderbrew.com/custom-application-templates-in-blender/
# elemental python modules blenxy needs
# that the python interpreter must have built in
import bpy, importlib, sys, subprocess, os, shutil
import math, mathutils, warnings, struct, site
# elemental python modules blenxy needs
# that the python interpreter probably does not have built in/needs to be updated
pip_modules = ["pip", "wheel", "setuptools"]
new_modules = ["lxml", "numpy"]
# check which of the new modules needs to be installed
def new_mod_check(mod_names):
rtn = []
for mod_name in mod_names:
try:
importlib.import_module(mod_name)
except:
rtn.append(mod_name)
return rtn
# install given modules with pip but be sure to have pip first
def new_mod_install(mod_names):
# get python's interpreter binary path
py_bin = bpy.app.binary_path_python
pip_install = [py_bin, "-B", "-m", "pip", "install",
"--trusted-host", "pypi.python.org",
"--trusted-host", "files.pythonhosted.org",
"--trusted-host", "pypi.org",
"-U", "--force-reinstall", "--only-binary", ":all:"]
# check if pip is available
pip = None
try: # import the pip module
pip = importlib.import_module("pip")
except: # install pip
subprocess.run([py_bin, "-B", "-m", "ensurepip"])
subprocess.run(pip_install + pip_modules)
# install the rest of the modules
if (mod_names != []):
for mod_name in mod_names:
if (mod_name == "numpy"): # specific to the numpy module
# get the numpy package path
numpy_path = None
for path in site.getsitepackages():
if ("2.79" in path):
numpy_path = path + "/numpy"
break
os.rename(numpy_path, numpy_path + "_bad")
# normal module installation
subprocess.run(pip_install + [mod_name])
return True
return False
# all blenxy custom modules
blenxy_modules = ["basic_settings", # user settings blenxy has
"collada_superbmd_import", # custom importer for SuperBMD collada files
"collada_superbmd_export", # custom exporter for SuperBMD collada files
"obj_kcl_export", # custom exporter for OBJ files (collision)
"obj_neokclcreate_import", # custom importer for OBJ files (collision, NeoKCLCreate)
"bck_import", # custom importer for SMG BCK files
"bck_export"] # custom exporter for SMG BCK files
# function used to refresh blenxy's custom modules
# so that they can be updated without closing blender
@bpy.app.handlers.persistent
def unload_blenxy_stuff(dummy):
# execute the unregister functions from each module
# these functions won't die if the stuff to unregister isn't there
for mod_name in blenxy_modules:
mod = importlib.import_module("." + mod_name, __package__)
mod.unregister()
# reload the modules in case they were modified (dev stuff)
for mod_name in blenxy_modules:
mod = importlib.import_module("." + mod_name, __package__)
importlib.reload(mod)
# register function that blender will call when the template is loaded
def register():
# print the welcome
print("\nWelcome to Blenxy!")
print("Running on Blender: %s\n" % (bpy.app.version.__str__()))
# checking python modules
if (new_mod_install(new_mod_check(new_modules)) == True):
print("New modules installed. Exiting...")
exit(0)
for mod_name in new_modules:
mod = importlib.import_module(mod_name)
print("%s %s is installed!" % (mod_name, mod.__version__))
# add this function to load_post first
bpy.app.handlers.load_post.append(unload_blenxy_stuff)
# add the register functions to load_post
for mod_name in blenxy_modules:
mod = importlib.import_module("." + mod_name, __package__)
bpy.app.handlers.load_post.append(mod.register)
# unregister function that blender will call when a new template is loaded
def unregister():
# print the goodbye
print("\nLeaving Blenxy!\n")
# remove the stuff added to the load_post list
bpy.app.handlers.load_post.remove(unload_blenxy_stuff)
for mod_name in blenxy_modules:
mod = importlib.import_module("." + mod_name, __package__)
for func in bpy.app.handlers.load_post:
if (mod.__name__ in func.__module__):
bpy.app.handlers.load_post.remove(func)
break
# execute module's unregister functions
for mod_name in blenxy_modules:
mod = importlib.import_module("." + mod_name, __package__)
mod.unregister()
|