summaryrefslogtreecommitdiff
path: root/__init__.py
blob: e2971fd58d263544e416bc1e795aa927405e3bde (plain)
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()