Implement basic addon reloading

This commit is contained in:
Moritz Brückner 2021-08-04 22:49:38 +02:00
parent b664e3a010
commit ea8c13686c
63 changed files with 738 additions and 83 deletions

View file

@ -0,0 +1,26 @@
import importlib
import types
# This gets cleared if this package/the __init__ module is reloaded
_module_cache: dict[str, types.ModuleType] = {}
def reload_module(module: types.ModuleType) -> types.ModuleType:
"""Wrapper around importlib.reload() to make sure no module is
reloaded twice.
Make sure to call this function in the same order in which the
modules are imported to make sure that the reloading respects the
module dependencies. Otherwise modules could depend on other modules
that are not yet reloaded.
If you import classes or functions from a module, make sure to
re-import them after the module is reloaded.
"""
mod = _module_cache.get(module.__name__, None)
if mod is None:
mod = importlib.reload(module)
_module_cache[module.__name__] = mod
return mod

View file

@ -4,7 +4,14 @@ from bpy.types import Material, UILayout
from arm.material.shader import ShaderContext
drivers: Dict[str, Dict] = dict()
if "DO_RELOAD_MODULE" in locals():
import arm
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import ShaderContext
else:
drivers: Dict[str, Dict] = dict()
DO_RELOAD_MODULE = True
def add_driver(driver_name: str,

View file

@ -6,6 +6,12 @@ import bpy
import arm.log as log
import arm.utils
if "DO_RELOAD_MODULE" in locals():
log = arm.reload_module(log)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
assets = []
reserved_names = ['return.']
khafile_params = []

View file

@ -32,7 +32,19 @@ import arm.material.mat_batch as mat_batch
import arm.utils
import arm.profiler
import arm.log as log
if "DO_RELOAD_MODULE" in locals():
assets = arm.reload_module(assets)
exporter_opt = arm.reload_module(exporter_opt)
log = arm.reload_module(log)
make_renderpath = arm.reload_module(make_renderpath)
cycles = arm.reload_module(cycles)
make_material = arm.reload_module(make_material)
mat_batch = arm.reload_module(mat_batch)
arm.utils = arm.reload_module(arm.utils)
arm.profiler = arm.reload_module(arm.profiler)
else:
DO_RELOAD_MODULE = True
@unique
class NodeType(Enum):

View file

@ -1,11 +1,20 @@
"""
Exports smaller geometry but is slower.
To be replaced with https://github.com/zeux/meshoptimizer
"""
from mathutils import *
import numpy as np
import arm.utils
import arm.log as log
import arm.utils
if "DO_RELOAD_MODULE" in locals():
log = arm.reload_module(log)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
# Exports smaller geometry but is slower
# To be replaced with https://github.com/zeux/meshoptimizer
class Vertex:
__slots__ = ("co", "normal", "uvs", "col", "loop_indices", "index", "bone_weights", "bone_indices", "bone_count", "vertex_index")

View file

@ -15,6 +15,18 @@ import arm.make_state as state
import arm.props as props
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm.api = arm.reload_module(arm.api)
live_patch = arm.reload_module(live_patch)
arm_nodes = arm.reload_module(arm_nodes)
arm.nodes_logic = arm.reload_module(arm.nodes_logic)
make = arm.reload_module(make)
state = arm.reload_module(state)
props = arm.reload_module(props)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
@persistent
def on_depsgraph_update_post(self):

View file

@ -1,8 +1,16 @@
import bpy
import arm.props_ui as props_ui
if "DO_RELOAD_MODULE" in locals():
import arm
props_ui = arm.reload_module(props_ui)
else:
DO_RELOAD_MODULE = True
arm_keymaps = []
def register():
wm = bpy.context.window_manager
addon_keyconfig = wm.keyconfigs.addon
@ -21,6 +29,7 @@ def register():
km.keymap_items.new("tlm.clean_lightmaps", type='F7', value='PRESS')
arm_keymaps.append(km)
def unregister():
wm = bpy.context.window_manager
for km in arm_keymaps:

View file

@ -20,9 +20,10 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
import struct
import io
import numpy as np
import struct
def _pack_integer(obj, fp):
if obj < 0:

View file

@ -1,7 +1,7 @@
import atexit
import http.server
import socketserver
import subprocess
import atexit
haxe_server = None

View file

@ -5,23 +5,37 @@ from typing import Any, Type
import bpy
import arm.assets
import arm.node_utils
from arm.exporter import ArmoryExporter
import arm.log as log
from arm.logicnode.arm_nodes import ArmLogicTreeNode
import arm.make as make
import arm.make_state as state
import arm.node_utils
import arm.utils
# Current patch id
patch_id = 0
if "DO_RELOAD_MODULE" in locals():
arm.assets = arm.reload_module(arm.assets)
arm.exporter = arm.reload_module(arm.exporter)
from arm.exporter import ArmoryExporter
log = arm.reload_module(log)
arm.logicnode.arm_nodes = arm.reload_module(arm.logicnode.arm_nodes)
from arm.logicnode.arm_nodes import ArmLogicTreeNode
make = arm.reload_module(make)
state = arm.reload_module(state)
arm.node_utils = arm.reload_module(arm.node_utils)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
patch_id = 0
"""Current patch id"""
__running = False
"""Whether live patch is currently active"""
# Any object can act as a message bus owner
msgbus_owner = object()
# Whether live patch is currently active
__running = False
def start():
"""Start the live patch session."""
@ -43,9 +57,10 @@ def start():
def stop():
"""Stop the live patch session."""
global __running
global __running, patch_id
if __running:
__running = False
patch_id = 0
log.debug("Live patch session stopped")
bpy.msgbus.clear_by_owner(msgbus_owner)

View file

@ -1,13 +1,29 @@
import importlib
import inspect
import pkgutil
import sys
import arm
import arm.logicnode.arm_nodes as arm_nodes
from arm.logicnode.arm_props import *
import arm.logicnode.arm_sockets as arm_sockets
from arm.logicnode.replacement import NodeReplacement
if "DO_RELOAD_MODULE" in locals():
arm_nodes = arm.reload_module(arm_nodes)
arm.logicnode.arm_props = arm.reload_module(arm.logicnode.arm_props)
from arm.logicnode.arm_props import *
arm_sockets = arm.reload_module(arm_sockets)
arm.logicnode.replacement = arm.reload_module(arm.logicnode.replacement)
from arm.logicnode.replacement import NodeReplacement
HAS_RELOADED = True
else:
DO_RELOAD_MODULE = True
def init_categories():
# Register node menu categories
"""Register default node menu categories."""
arm_nodes.add_category('Logic', icon='OUTLINER', section="basic",
description="Logic nodes are used to control execution flow using branching, loops, gates etc.")
arm_nodes.add_category('Event', icon='INFO', section="basic")
@ -56,8 +72,15 @@ def init_nodes():
# The package must be loaded as well so that the modules from that package can be accessed (see the
# pkgutil.walk_packages documentation for more information on this)
loader.find_module(module_name).load_module(module_name)
else:
_module = importlib.import_module(module_name)
# Only look at modules in sub packages
elif module_name.rsplit('.', 1)[0] != __package__:
if 'HAS_RELOADED' not in globals():
_module = importlib.import_module(module_name)
else:
# Reload the module if the SDK was reloaded at least once
_module = importlib.reload(sys.modules[module_name])
for name, obj in inspect.getmembers(_module, inspect.isclass):
if name == "ArmLogicTreeNode":
continue

View file

@ -1,5 +1,5 @@
import itertools
from collections import OrderedDict
import itertools
from typing import Any, Generator, List, Optional, Type
from typing import OrderedDict as ODict # Prevent naming conflicts
@ -14,6 +14,15 @@ from arm.logicnode.arm_props import *
from arm.logicnode.replacement import NodeReplacement
import arm.node_utils
if "DO_RELOAD_MODULE" in locals():
arm.logicnode.arm_props = arm.reload_module(arm.logicnode.arm_props)
from arm.logicnode.arm_props import *
arm.logicnode.replacement = arm.reload_module(arm.logicnode.replacement)
from arm.logicnode.replacement import NodeReplacement
arm.node_utils = arm.reload_module(arm.node_utils)
else:
DO_RELOAD_MODULE = True
# When passed as a category to add_node(), this will use the capitalized
# name of the package of the node as the category to make renaming
# categories easier.

View file

@ -15,6 +15,20 @@ from typing import Any, Callable, Sequence, Union
import bpy
from bpy.props import *
__all__ = [
'HaxeBoolProperty',
'HaxeBoolVectorProperty',
'HaxeCollectionProperty',
'HaxeEnumProperty',
'HaxeFloatProperty',
'HaxeFloatVectorProperty',
'HaxeIntProperty',
'HaxeIntVectorProperty',
'HaxePointerProperty',
'HaxeStringProperty',
'RemoveHaxeProperty'
]
def __haxe_prop(prop_type: Callable, prop_name: str, *args, **kwargs) -> Any:
"""Declares a logic node property as a property that will be

View file

@ -4,6 +4,11 @@ from bpy.types import NodeSocket
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def _on_update_socket(self, context):
self.node.on_socket_val_update(context, self)

View file

@ -20,6 +20,14 @@ import arm.logicnode.arm_nodes as arm_nodes
import arm.logicnode.arm_sockets
import arm.node_utils as node_utils
if "DO_RELOAD_MODULE" in locals():
log = arm.reload_module(log)
arm_nodes = arm.reload_module(arm_nodes)
arm.logicnode.arm_sockets = arm.reload_module(arm.logicnode.arm_sockets)
node_utils = arm.reload_module(node_utils)
else:
DO_RELOAD_MODULE = True
# List of errors that occurred during the replacement
# Format: (error identifier, node.bl_idname (or None), tree name, exception traceback (optional))
replacement_errors: List[Tuple[str, Optional[str], str, Optional[str]]] = []

View file

@ -27,6 +27,23 @@ import arm.make_world as make_world
import arm.utils
import arm.write_data as write_data
if "DO_RELOAD_MODULE" in locals():
assets = arm.reload_module(assets)
arm.exporter = arm.reload_module(arm.exporter)
from arm.exporter import ArmoryExporter
arm.lib.make_datas = arm.reload_module(arm.lib.make_datas)
arm.lib.server = arm.reload_module(arm.lib.server)
live_patch = arm.reload_module(live_patch)
log = arm.reload_module(log)
make_logic = arm.reload_module(make_logic)
make_renderpath = arm.reload_module(make_renderpath)
state = arm.reload_module(state)
make_world = arm.reload_module(make_world)
arm.utils = arm.reload_module(arm.utils)
write_data = arm.reload_module(write_data)
else:
DO_RELOAD_MODULE = True
scripts_mtime = 0 # Monitor source changes
profile_time = 0

View file

@ -8,6 +8,15 @@ import arm.log
import arm.node_utils
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm.exporter = arm.reload_module(arm.exporter)
from arm.exporter import ArmoryExporter
arm.log = arm.reload_module(arm.log)
arm.node_utils = arm.reload_module(arm.node_utils)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
parsed_nodes = []
parsed_ids = dict() # Sharing node data
function_nodes = dict()

View file

@ -1,9 +1,19 @@
import bpy
import arm.api
import arm.assets as assets
import arm.utils
import arm.log as log
import arm.make_state as state
import arm.api
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm.api = arm.reload_module(arm.api)
assets = arm.reload_module(assets)
log = arm.reload_module(log)
state = arm.reload_module(state)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
callback = None

View file

@ -1,15 +1,18 @@
redraw_ui = False
target = 'krom'
last_target = 'krom'
export_gapi = ''
last_resx = 0
last_resy = 0
last_scene = ''
last_world_defs = ''
proc_play = None
proc_build = None
proc_publish_build = None
mod_scripts = []
is_export = False
is_play = False
is_publish = False
if "DO_RELOAD_MODULE" not in locals():
DO_RELOAD_MODULE = True
redraw_ui = False
target = 'krom'
last_target = 'krom'
export_gapi = ''
last_resx = 0
last_resy = 0
last_scene = ''
last_world_defs = ''
proc_play = None
proc_build = None
proc_publish_build = None
mod_scripts = []
is_export = False
is_play = False
is_publish = False

View file

@ -12,6 +12,21 @@ import arm.node_utils as node_utils
import arm.utils
import arm.write_probes as write_probes
if "DO_RELOAD_MODULE" in locals():
arm.assets = arm.reload_module(arm.assets)
arm.log = arm.reload_module(arm.log)
arm.material = arm.reload_module(arm.material)
arm.material.parser_state = arm.reload_module(arm.material.parser_state)
from arm.material.parser_state import ParserState, ParserContext
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import ShaderContext, Shader
cycles = arm.reload_module(cycles)
node_utils = arm.reload_module(node_utils)
arm.utils = arm.reload_module(arm.utils)
write_probes = arm.reload_module(write_probes)
else:
DO_RELOAD_MODULE = True
callback = None
shader_datas = []

View file

@ -0,0 +1 @@
import arm

View file

@ -5,6 +5,17 @@ from arm.material.arm_nodes.arm_nodes import add_node
from arm.material.shader import Shader
from arm.material.cycles import *
if "DO_RELOAD_MODULE" in locals():
import arm
arm.material.arm_nodes.arm_nodes = arm.reload_module(arm.material.arm_nodes.arm_nodes)
from arm.material.arm_nodes.arm_nodes import add_node
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import Shader
arm.material.cycles = arm.reload_module(arm.material.cycles)
from arm.material.cycles import *
else:
DO_RELOAD_MODULE = True
class CustomParticleNode(Node):
"""Input data for paricles."""
@ -174,7 +185,7 @@ class CustomParticleNode(Node):
if self.posZ:
vertshdr.write(f'spos.z += {pos}.z;')
vertshdr.write('wposition = vec4(W * spos).xyz;')

View file

@ -4,6 +4,15 @@ from bpy.types import Node
from arm.material.arm_nodes.arm_nodes import add_node
from arm.material.shader import Shader
if "DO_RELOAD_MODULE" in locals():
import arm
arm.material.arm_nodes.arm_nodes = arm.reload_module(arm.material.arm_nodes.arm_nodes)
from arm.material.arm_nodes.arm_nodes import add_node
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import Shader
else:
DO_RELOAD_MODULE = True
class ShaderDataNode(Node):
"""Allows access to shader data such as uniforms and inputs."""

View file

@ -30,6 +30,23 @@ from arm.material.parser_state import ParserState, ParserContext
from arm.material.shader import Shader, ShaderContext, floatstr, vec3str
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm.assets = arm.reload_module(arm.assets)
log = arm.reload_module(log)
arm.make_state = arm.reload_module(arm.make_state)
c_functions = arm.reload_module(c_functions)
arm.material.cycles_nodes = arm.reload_module(arm.material.cycles_nodes)
from arm.material.cycles_nodes import *
mat_state = arm.reload_module(mat_state)
arm.material.parser_state = arm.reload_module(arm.material.parser_state)
from arm.material.parser_state import ParserState, ParserContext
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import Shader, ShaderContext, floatstr, vec3str
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
# Particle info export
particle_info: Dict[str, bool] = {}

View file

@ -6,6 +6,18 @@ import arm.material.cycles_functions as c_functions
from arm.material.parser_state import ParserState
from arm.material.shader import floatstr, vec3str
if "DO_RELOAD_MODULE" in locals():
import arm
log = arm.reload_module(log)
c = arm.reload_module(c)
c_functions = arm.reload_module(c_functions)
arm.material.parser_state = arm.reload_module(arm.material.parser_state)
from arm.material.parser_state import ParserState
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import floatstr, vec3str
else:
DO_RELOAD_MODULE = True
def parse_brightcontrast(node: bpy.types.ShaderNodeBrightContrast, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
out_col = c.parse_vector_input(node.inputs[0])

View file

@ -8,6 +8,19 @@ import arm.material.cycles_functions as c_functions
from arm.material.parser_state import ParserState
from arm.material.shader import floatstr, vec3str
if "DO_RELOAD_MODULE" in locals():
import arm
log = arm.reload_module(log)
c = arm.reload_module(c)
c_functions = arm.reload_module(c_functions)
arm.material.parser_state = arm.reload_module(arm.material.parser_state)
from arm.material.parser_state import ParserState
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import floatstr, vec3str
else:
DO_RELOAD_MODULE = True
def parse_maprange(node: bpy.types.ShaderNodeMapRange, out_socket: bpy.types.NodeSocket, state: ParserState) -> floatstr:
interp = node.interpolation_type
@ -40,7 +53,7 @@ def parse_maprange(node: bpy.types.ShaderNodeMapRange, out_socket: bpy.types.Nod
return f'map_range_smootherstep({value}, {fromMin}, {fromMax}, {toMin}, {toMax})'
def parse_blackbody(node: bpy.types.ShaderNodeBlackbody, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
t = c.parse_value_input(node.inputs[0])
state.curshader.add_function(c_functions.str_blackbody)

View file

@ -10,6 +10,18 @@ from arm.material.parser_state import ParserState, ParserContext
from arm.material.shader import floatstr, vec3str
import arm.utils
if "DO_RELOAD_MODULE" in locals():
log = arm.reload_module(log)
c = arm.reload_module(c)
c_functions = arm.reload_module(c_functions)
arm.material.parser_state = arm.reload_module(arm.material.parser_state)
from arm.material.parser_state import ParserState, ParserContext
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import floatstr, vec3str
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def parse_attribute(node: bpy.types.ShaderNodeAttribute, out_socket: bpy.types.NodeSocket, state: ParserState) -> Union[floatstr, vec3str]:
out_type = 'float' if out_socket.type == 'VALUE' else 'vec3'

View file

@ -4,6 +4,14 @@ from bpy.types import NodeSocket
import arm.material.cycles as c
from arm.material.parser_state import ParserState
if "DO_RELOAD_MODULE" in locals():
import arm
c = arm.reload_module(c)
arm.material.parser_state = arm.reload_module(arm.material.parser_state)
from arm.material.parser_state import ParserState
else:
DO_RELOAD_MODULE = True
def parse_mixshader(node: bpy.types.ShaderNodeMixShader, out_socket: NodeSocket, state: ParserState) -> None:
prefix = '' if node.inputs[0].is_linked else 'const '

View file

@ -6,13 +6,27 @@ import bpy
import arm.assets as assets
import arm.log as log
import arm.material.cycles_functions as c_functions
import arm.material.cycles as c
import arm.material.cycles_functions as c_functions
from arm.material.parser_state import ParserState, ParserContext
from arm.material.shader import floatstr, vec3str
import arm.utils
import arm.write_probes as write_probes
if "DO_RELOAD_MODULE" in locals():
assets = arm.reload_module(assets)
log = arm.reload_module(log)
c = arm.reload_module(c)
c_functions = arm.reload_module(c_functions)
arm.material.parser_state = arm.reload_module(arm.material.parser_state)
from arm.material.parser_state import ParserState, ParserContext
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import floatstr, vec3str
arm.utils = arm.reload_module(arm.utils)
write_probes = arm.reload_module(write_probes)
else:
DO_RELOAD_MODULE = True
def parse_tex_brick(node: bpy.types.ShaderNodeTexBrick, out_socket: bpy.types.NodeSocket, state: ParserState) -> Union[floatstr, vec3str]:
state.curshader.add_function(c_functions.str_tex_brick)

View file

@ -8,6 +8,17 @@ import arm.material.cycles_functions as c_functions
from arm.material.parser_state import ParserState
from arm.material.shader import floatstr, vec3str
if "DO_RELOAD_MODULE" in locals():
import arm
c = arm.reload_module(c)
c_functions = arm.reload_module(c_functions)
arm.material.parser_state = arm.reload_module(arm.material.parser_state)
from arm.material.parser_state import ParserState
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import floatstr, vec3str
else:
DO_RELOAD_MODULE = True
def parse_curvevec(node: bpy.types.ShaderNodeVectorCurve, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
fac = c.parse_value_input(node.inputs[0])
@ -144,7 +155,7 @@ def parse_displacement(node: bpy.types.ShaderNodeDisplacement, out_socket: bpy.t
return f'(vec3({height}) * {scale})'
def parse_vectorrotate(node: bpy.types.ShaderNodeVectorRotate, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str:
type = node.rotation_type
input_vector: bpy.types.NodeSocket = c.parse_vector_input(node.inputs[0])
input_center: bpy.types.NodeSocket = c.parse_vector_input(node.inputs[1])
@ -166,9 +177,9 @@ def parse_vectorrotate(node: bpy.types.ShaderNodeVectorRotate, out_socket: bpy.t
elif type == 'Y_AXIS':
return f'vec3( rotate_around_axis({input_vector} - {input_center}, vec3(0.0, 1.0, 0.0), {input_angle} * {input_invert}) + {input_center} )'
elif type == 'Z_AXIS':
return f'vec3( rotate_around_axis({input_vector} - {input_center}, vec3(0.0, 0.0, 1.0), {input_angle} * {input_invert}) + {input_center} )'
return f'vec3( rotate_around_axis({input_vector} - {input_center}, vec3(0.0, 0.0, 1.0), {input_angle} * {input_invert}) + {input_center} )'
elif type == 'EULER_XYZ':
state.curshader.add_function(c_functions.str_euler_to_mat3)
return f'vec3( mat3(({input_invert} < 0.0) ? transpose(euler_to_mat3({input_rotation})) : euler_to_mat3({input_rotation})) * ({input_vector} - {input_center}) + {input_center})'
return f'(vec3(1.0, 0.0, 0.0))'

View file

@ -10,6 +10,15 @@ import arm.material.mat_batch as mat_batch
import arm.node_utils
import arm.utils
if "DO_RELOAD_MODULE" in locals():
cycles = arm.reload_module(cycles)
make_shader = arm.reload_module(make_shader)
mat_batch = arm.reload_module(mat_batch)
arm.node_utils = arm.reload_module(arm.node_utils)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def glsl_value(val):
if str(type(val)) == "<class 'bpy_prop_array'>":

View file

@ -9,6 +9,19 @@ import arm.material.make_tess as make_tess
from arm.material.shader import Shader, ShaderContext
import arm.utils
if "DO_RELOAD_MODULE" in locals():
cycles = arm.reload_module(cycles)
mat_state = arm.reload_module(mat_state)
make_skin = arm.reload_module(make_skin)
make_particle = arm.reload_module(make_particle)
make_inst = arm.reload_module(make_inst)
make_tess = arm.reload_module(make_tess)
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import Shader, ShaderContext
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def write_vertpos(vert):
billboard = mat_state.material.arm_billboard

View file

@ -1,10 +1,19 @@
import bpy
import arm.material.cycles as cycles
import arm.material.mat_state as mat_state
import arm.material.mat_utils as mat_utils
import arm.material.make_finalize as make_finalize
import arm.utils
if "DO_RELOAD_MODULE" in locals():
cycles = arm.reload_module(cycles)
mat_state = arm.reload_module(mat_state)
make_finalize = arm.reload_module(make_finalize)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def make(context_id):
wrd = bpy.data.worlds['Arm']

View file

@ -1,4 +1,5 @@
import bpy
import arm.material.cycles as cycles
import arm.material.mat_state as mat_state
import arm.material.mat_utils as mat_utils
@ -10,6 +11,21 @@ import arm.material.make_finalize as make_finalize
import arm.assets as assets
import arm.utils
if "DO_RELOAD_MODULE" in locals():
cycles = arm.reload_module(cycles)
mat_state = arm.reload_module(mat_state)
mat_utils = arm.reload_module(mat_utils)
make_skin = arm.reload_module(make_skin)
make_inst = arm.reload_module(make_inst)
make_tess = arm.reload_module(make_tess)
make_particle = arm.reload_module(make_particle)
make_finalize = arm.reload_module(make_finalize)
assets = arm.reload_module(assets)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def make(context_id, rpasses, shadowmap=False):
is_disp = mat_utils.disp_linked(mat_state.output_node)

View file

@ -3,6 +3,14 @@ import bpy
import arm.material.make_tess as make_tess
from arm.material.shader import ShaderContext
if "DO_RELOAD_MODULE" in locals():
import arm
make_tess = arm.reload_module(make_tess)
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import ShaderContext
else:
DO_RELOAD_MODULE = True
def make(con_mesh: ShaderContext):
vert = con_mesh.vert

View file

@ -1,4 +1,5 @@
import bpy
import arm.assets as assets
import arm.material.mat_state as mat_state
import arm.material.mat_utils as mat_utils
@ -10,6 +11,20 @@ import arm.material.make_finalize as make_finalize
import arm.material.make_attrib as make_attrib
import arm.utils
if "DO_RELOAD_MODULE" in locals():
assets = arm.reload_module(assets)
mat_state = arm.reload_module(mat_state)
mat_utils = arm.reload_module(mat_utils)
cycles = arm.reload_module(cycles)
make_tess = arm.reload_module(make_tess)
make_particle = arm.reload_module(make_particle)
make_cluster = arm.reload_module(make_cluster)
make_finalize = arm.reload_module(make_finalize)
make_attrib = arm.reload_module(make_attrib)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
is_displacement = False
write_material_attribs = None
write_material_attribs_post = None

View file

@ -3,6 +3,15 @@ import arm.material.make_mesh as make_mesh
import arm.material.mat_state as mat_state
import arm.material.mat_utils as mat_utils
if "DO_RELOAD_MODULE" in locals():
import arm
make_finalize = arm.reload_module(make_finalize)
make_mesh = arm.reload_module(make_mesh)
mat_state = arm.reload_module(mat_state)
mat_utils = arm.reload_module(mat_utils)
else:
DO_RELOAD_MODULE = True
def make(context_id):
con = { 'name': context_id, 'depth_write': True, 'compare_mode': 'less', 'cull_mode': 'clockwise' }

View file

@ -1,7 +1,13 @@
import arm.utils
import arm.material.mat_state as mat_state
if "DO_RELOAD_MODULE" in locals():
arm.utils = arm.reload_module(arm.utils)
mat_state = arm.reload_module(mat_state)
else:
DO_RELOAD_MODULE = True
def write(vert, particle_info=None, shadowmap=False):
# Outs
@ -17,7 +23,7 @@ def write(vert, particle_info=None, shadowmap=False):
str_tex_hash = "float fhash(float n) { return fract(sin(n) * 43758.5453); }\n"
vert.add_function(str_tex_hash)
prep = 'float '
if out_age:
prep = ''
@ -45,7 +51,7 @@ def write(vert, particle_info=None, shadowmap=False):
vert.write('}')
# vert.write('p_age /= 2;') # Match
# object_align_factor / 2 + gxyz
prep = 'vec3 '
if out_velocity:

View file

@ -22,6 +22,26 @@ import arm.material.mat_utils as mat_utils
from arm.material.shader import Shader, ShaderContext, ShaderData
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm.api = arm.reload_module(arm.api)
assets = arm.reload_module(assets)
arm.exporter = arm.reload_module(arm.exporter)
log = arm.reload_module(log)
cycles = arm.reload_module(cycles)
make_decal = arm.reload_module(make_decal)
make_depth = arm.reload_module(make_depth)
make_mesh = arm.reload_module(make_mesh)
make_overlay = arm.reload_module(make_overlay)
make_transluc = arm.reload_module(make_transluc)
make_voxel = arm.reload_module(make_voxel)
mat_state = arm.reload_module(mat_state)
mat_utils = arm.reload_module(mat_utils)
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import Shader, ShaderContext, ShaderData
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
rpass_hook = None

View file

@ -1,5 +1,11 @@
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def skin_pos(vert):
vert.add_include('compiled.inc')
@ -15,6 +21,7 @@ def skin_pos(vert):
vert.write_attrib('spos.xyz += 2.0 * (skinA.w * skinB.xyz - skinB.w * skinA.xyz + cross(skinA.xyz, skinB.xyz)); // Translate')
vert.write_attrib('spos.xyz /= posUnpack;')
def skin_nor(vert, prep):
rpdat = arm.utils.get_rp()
vert.write_attrib(prep + 'wnormal = normalize(N * (vec3(nor.xy, pos.w) + 2.0 * cross(skinA.xyz, cross(skinA.xyz, vec3(nor.xy, pos.w)) + skinA.w * vec3(nor.xy, pos.w))));')

View file

@ -1,10 +1,22 @@
import bpy
import arm.material.cycles as cycles
import arm.material.mat_state as mat_state
import arm.material.make_mesh as make_mesh
import arm.material.make_finalize as make_finalize
import arm.assets as assets
if "DO_RELOAD_MODULE" in locals():
import arm
cycles = arm.reload_module(cycles)
mat_state = arm.reload_module(mat_state)
make_mesh = arm.reload_module(make_mesh)
make_finalize = arm.reload_module(make_finalize)
assets = arm.reload_module(assets)
else:
DO_RELOAD_MODULE = True
def make(context_id):
con_transluc = mat_state.data.add_context({ 'name': context_id, 'depth_write': False, 'compare_mode': 'less', 'cull_mode': 'clockwise', \
'blend_source': 'blend_one', 'blend_destination': 'blend_one', 'blend_operation': 'add', \
@ -26,7 +38,7 @@ def make(context_id):
if '_VoxelAOvar' in wrd.world_defs:
frag.write('indirect *= 0.25;')
frag.write('vec4 premultipliedReflect = vec4(vec3(direct + indirect * 0.5) * opacity, opacity);')
frag.write('float w = clamp(pow(min(1.0, premultipliedReflect.a * 10.0) + 0.01, 3.0) * 1e8 * pow(1.0 - (gl_FragCoord.z) * 0.9, 3.0), 1e-2, 3e3);')
frag.write('fragColor[0] = vec4(premultipliedReflect.rgb * w, premultipliedReflect.a);')
frag.write('fragColor[1] = vec4(premultipliedReflect.a * w, 0.0, 0.0, 1.0);')

View file

@ -1,11 +1,16 @@
import bpy
import arm.utils
import arm.assets as assets
import arm.material.cycles as cycles
import arm.material.mat_state as mat_state
import arm.material.mat_utils as mat_utils
import arm.material.make_particle as make_particle
import arm.make_state as state
if "DO_RELOAD_MODULE" in locals():
arm.utils = arm.reload_module(arm.utils)
assets = arm.reload_module(assets)
mat_state = arm.reload_module(mat_state)
else:
DO_RELOAD_MODULE = True
def make(context_id):
rpdat = arm.utils.get_rp()
@ -108,7 +113,7 @@ def make_ao(context_id):
if rpdat.arm_voxelgi_revoxelize and rpdat.arm_voxelgi_camera:
vert.add_uniform('vec3 eyeSnap', '_cameraPositionSnap')
vert.write('voxpositionGeom = (vec3(W * vec4(pos.xyz, 1.0)) - eyeSnap) / voxelgiHalfExtents;')
else:
else:
vert.write('voxpositionGeom = vec3(W * vec4(pos.xyz, 1.0)) / voxelgiHalfExtents;')
geom.add_out('vec3 voxposition')

View file

@ -1,8 +1,15 @@
import bpy
import arm.material.cycles as cycles
import arm.material.make_shader as make_shader
import arm.material.mat_state as mat_state
if "DO_RELOAD_MODULE" in locals():
import arm
cycles = arm.reload_module(cycles)
make_shader = arm.reload_module(make_shader)
mat_state = arm.reload_module(mat_state)
else:
DO_RELOAD_MODULE = True
# TODO: handle groups
# TODO: handle cached shaders
@ -21,7 +28,7 @@ def traverse_tree(node, sign):
def get_signature(mat):
nodes = mat.node_tree.nodes
output_node = cycles.node_by_type(nodes, 'OUTPUT_MATERIAL')
if output_node != None:
sign = traverse_tree(output_node, '')
# Append flags
@ -40,7 +47,7 @@ def traverse_tree2(node, ar):
def get_sorted(mat):
nodes = mat.node_tree.nodes
output_node = cycles.node_by_type(nodes, 'OUTPUT_MATERIAL')
if output_node != None:
ar = []
traverse_tree2(output_node, ar)

View file

@ -1,9 +1,18 @@
import bpy
import arm.utils
import arm.make_state as make_state
import arm.material.cycles as cycles
import arm.log as log
if "DO_RELOAD_MODULE" in locals():
arm.utils = arm.reload_module(arm.utils)
make_state = arm.reload_module(make_state)
cycles = arm.reload_module(cycles)
log = arm.reload_module(log)
else:
DO_RELOAD_MODULE = True
add_mesh_contexts = []
def disp_linked(output_node):
@ -42,7 +51,7 @@ def get_rpasses(material):
ar.append('voxel')
if rpdat.rp_renderer == 'Forward' and rpdat.rp_depthprepass and not material.arm_blending and not material.arm_particle_flag:
ar.append('depth')
if material.arm_cast_shadow and rpdat.rp_shadows and ('mesh' in ar):
ar.append('shadowmap')

View file

@ -5,6 +5,13 @@ import bpy
from arm.material.shader import Shader, ShaderContext, vec3str, floatstr
if "DO_RELOAD_MODULE" in locals():
import arm
arm.material.shader = arm.reload_module(arm.material.shader)
from arm.material.shader import Shader, ShaderContext, vec3str, floatstr
else:
DO_RELOAD_MODULE = True
class ParserContext(Enum):
"""Describes which kind of node tree is parsed."""

View file

@ -1,5 +1,10 @@
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
# Type aliases for type hints to make it easier to see which kind of
# shader data type is stored in a string
floatstr = str

View file

@ -10,6 +10,13 @@ import arm.log
import arm.logicnode.arm_sockets
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm.log = arm.reload_module(arm.log)
arm.logicnode.arm_sockets = arm.reload_module(arm.logicnode.arm_sockets)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def find_node_by_link(node_group, to_node, inp):
for link in node_group.links:

View file

@ -11,6 +11,16 @@ import arm.props_traits
import arm.ui_icons as ui_icons
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm_nodes = arm.reload_module(arm_nodes)
arm.logicnode.replacement = arm.reload_module(arm.logicnode.replacement)
arm.logicnode = arm.reload_module(arm.logicnode)
arm.props_traits = arm.reload_module(arm.props_traits)
ui_icons = arm.reload_module(ui_icons)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
registered_nodes = []
registered_categories = []

View file

@ -7,6 +7,14 @@ import arm.material.arm_nodes.arm_nodes as arm_nodes
# even if it looks unused
from arm.material.arm_nodes import *
if "DO_RELOAD_MODULE" in locals():
import arm
arm_nodes = arm.reload_module(arm_nodes)
arm.material.arm_nodes = arm.reload_module(arm.material.arm_nodes)
from arm.material.arm_nodes import *
else:
DO_RELOAD_MODULE = True
registered_nodes = []

View file

@ -5,6 +5,13 @@ import pstats
import arm.log as log
import arm.utils as utils
if "DO_RELOAD_MODULE" in locals():
import arm
log = arm.reload_module(log)
utils = arm.reload_module(utils)
else:
DO_RELOAD_MODULE = True
class Profile:
"""Context manager for profiling the enclosed code when the given condition is true.

View file

@ -10,6 +10,16 @@ import arm.nodes_logic
import arm.proxy
import arm.utils
if "DO_RELOAD_MODULE" in locals():
assets = arm.reload_module(assets)
arm.logicnode.replacement = arm.reload_module(arm.logicnode.replacement)
arm.make = arm.reload_module(arm.make)
arm.nodes_logic = arm.reload_module(arm.nodes_logic)
arm.proxy = arm.reload_module(arm.proxy)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
# Armory version
arm_version = '2021.7'
arm_commit = '$Id$'

View file

@ -1,10 +1,19 @@
import arm.utils
import arm.assets
import bpy
from bpy.types import Menu, Panel, UIList
from bpy.props import *
from arm.lightmapper import operators, properties, utility
import arm.assets
import arm.utils
if "DO_RELOAD_MODULE" in locals():
arm.assets = arm.reload_module(arm.assets)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
class ArmBakeListItem(bpy.types.PropertyGroup):
obj: PointerProperty(type=bpy.types.Object, description="The object to bake")
res_x: IntProperty(name="X", description="Texture resolution", default=1024)
@ -166,7 +175,7 @@ class ArmBakeButton(bpy.types.Operator):
img_node.image = img
img_node.select = True
nodes.active = img_node
obs = bpy.context.view_layer.objects
# Unwrap
@ -379,4 +388,4 @@ def unregister():
#Unregister lightmapper
operators.unregister()
properties.unregister()
properties.unregister()

View file

@ -1,14 +1,23 @@
import os
import shutil
import arm.assets as assets
import arm.utils
import bpy
import stat
import subprocess
import webbrowser
import bpy
from bpy.types import Menu, Panel, UIList
from bpy.props import *
import arm.assets as assets
import arm.utils
if "DO_RELOAD_MODULE" in locals():
assets = arm.reload_module(assets)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def remove_readonly(func, path, excinfo):
os.chmod(path, stat.S_IWRITE)
func(path)
@ -417,7 +426,7 @@ def register():
bpy.types.World.arm_exporterlist = CollectionProperty(type=ArmExporterListItem)
bpy.types.World.arm_exporterlist_index = IntProperty(name="Index for my_list", default=0)
bpy.types.World.arm_exporter_android_permission_list = CollectionProperty(type=ArmExporterAndroidPermissionListItem)
bpy.types.World.arm_exporter_android_permission_list_index = IntProperty(name="Index for my_list", default=0)
bpy.types.World.arm_exporter_android_permission_list_index = IntProperty(name="Index for my_list", default=0)
bpy.types.World.arm_exporter_android_abi_list = CollectionProperty(type=ArmExporterAndroidAbiListItem)
bpy.types.World.arm_exporter_android_abi_list_index = IntProperty(name="Index for my_list", default=0)

View file

@ -1,5 +1,4 @@
import bpy
from bpy.types import Menu, Panel, UIList
from bpy.props import *
def update_size_prop(self, context):

View file

@ -4,6 +4,12 @@ from bpy.props import *
import arm.assets as assets
import arm.utils
if "DO_RELOAD_MODULE" in locals():
assets = arm.reload_module(assets)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
atlas_sizes = [ ('256', '256', '256'),
('512', '512', '512'),
('1024', '1024', '1024'),

View file

@ -6,6 +6,7 @@ from typing import Union
import webbrowser
from bpy.types import NodeTree
from bpy.props import *
import bpy.utils.previews
import arm.make as make
@ -15,6 +16,17 @@ import arm.ui_icons as ui_icons
import arm.utils
import arm.write_data as write_data
if "DO_RELOAD_MODULE" in locals():
arm.make = arm.reload_module(arm.make)
arm.props_traits_props = arm.reload_module(arm.props_traits_props)
from arm.props_traits_props import *
proxy = arm.reload_module(proxy)
ui_icons = arm.reload_module(ui_icons)
arm.utils = arm.reload_module(arm.utils)
arm.write_data = arm.reload_module(arm.write_data)
else:
DO_RELOAD_MODULE = True
ICON_HAXE = ui_icons.get_id('haxe')
ICON_NODES = 'NODETREE'
ICON_CANVAS = 'NODE_COMPOSITING'
@ -103,13 +115,13 @@ class ARM_UL_TraitList(bpy.types.UIList):
custom_icon = "NONE"
custom_icon_value = 0
if item.type_prop == "Haxe Script":
custom_icon_value = ui_icons.get_id("haxe")
custom_icon_value = ICON_HAXE
elif item.type_prop == "WebAssembly":
custom_icon_value = ui_icons.get_id("wasm")
custom_icon_value = ICON_WASM
elif item.type_prop == "UI Canvas":
custom_icon = "NODE_COMPOSITING"
elif item.type_prop == "Bundled Script":
custom_icon_value = ui_icons.get_id("bundle")
custom_icon_value = ICON_BUNDLED
elif item.type_prop == "Logic Nodes":
custom_icon = 'NODETREE'

View file

@ -1,6 +1,8 @@
import bpy
from bpy.props import *
__all__ = ['ArmTraitPropWarning', 'ArmTraitPropListItem', 'ARM_UL_PropList']
PROP_TYPE_ICONS = {
"String": "SORTALPHA",
"Int": "CHECKBOX_DEHLT",

View file

@ -5,6 +5,8 @@ import shutil
import bpy
from bpy.props import *
from arm.lightmapper.panels import scene
import arm.api
import arm.assets as assets
from arm.exporter import ArmoryExporter
@ -20,10 +22,24 @@ import arm.proxy
import arm.ui_icons as ui_icons
import arm.utils
from arm.lightmapper.utility import icon
from arm.lightmapper.properties.denoiser import oidn, optix
from arm.lightmapper.panels import scene
import importlib
if "DO_RELOAD_MODULE" in locals():
arm.api = arm.reload_module(arm.api)
assets = arm.reload_module(assets)
arm.exporter = arm.reload_module(arm.exporter)
from arm.exporter import ArmoryExporter
log = arm.reload_module(log)
arm.logicnode.replacement = arm.reload_module(arm.logicnode.replacement)
make = arm.reload_module(make)
state = arm.reload_module(state)
props = arm.reload_module(props)
arm.props_properties = arm.reload_module(arm.props_properties)
arm.props_traits = arm.reload_module(arm.props_traits)
arm.nodes_logic = arm.reload_module(arm.nodes_logic)
arm.proxy = arm.reload_module(arm.proxy)
ui_icons = arm.reload_module(ui_icons)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
class ARM_PT_ObjectPropsPanel(bpy.types.Panel):
@ -213,7 +229,7 @@ class ARM_PT_PhysicsPropsPanel(bpy.types.Panel):
if obj.soft_body is not None:
layout.prop(obj, 'arm_soft_body_margin')
if obj.rigid_body_constraint is not None:
layout.prop(obj, 'arm_relative_physics_constraint')

View file

@ -6,6 +6,19 @@ from typing import Optional
import bpy.utils.previews
if "DO_RELOAD_MODULE" in locals():
# _unload_icons is not available in the module scope yet
def __unload():
_unload_icons()
# Refresh icons after reload
__unload()
else:
DO_RELOAD_MODULE = True
__all__ = ["get_id"]
_icons_dict: Optional[bpy.utils.previews.ImagePreviewCollection] = None
"""Dictionary of all loaded icons, or `None` if not loaded"""
@ -13,21 +26,28 @@ _icons_dir = os.path.join(os.path.dirname(__file__), "custom_icons")
"""Directory of the icon files"""
def _load_icons() -> None:
"""(Re)loads all icons"""
def _load_icons():
"""(Re)loads all icons."""
global _icons_dict
if _icons_dict is not None:
bpy.utils.previews.remove(_icons_dict)
_unload_icons()
_icons_dict = bpy.utils.previews.new()
_icons_dict.load("bundle", os.path.join(_icons_dir, "bundle.png"), 'IMAGE')
_icons_dict.load("haxe", os.path.join(_icons_dir, "haxe.png"), 'IMAGE')
_icons_dict.load("wasm", os.path.join(_icons_dir, "wasm.png"), 'IMAGE')
_icons_dict.load("bundle", os.path.join(_icons_dir, "bundle.png"), 'IMAGE', force_reload=True)
_icons_dict.load("haxe", os.path.join(_icons_dir, "haxe.png"), 'IMAGE', force_reload=True)
_icons_dict.load("wasm", os.path.join(_icons_dir, "wasm.png"), 'IMAGE', force_reload=True)
def _unload_icons():
"""Unloads all icons."""
global _icons_dict
if _icons_dict is not None:
bpy.utils.previews.remove(_icons_dict)
_icons_dict = None
def get_id(identifier: str) -> int:
"""Returns the icon ID from the given identifier"""
"""Returns the icon ID from the given identifier."""
if _icons_dict is None:
_load_icons()
return _icons_dict[identifier].icon_id

View file

@ -1,13 +1,14 @@
from enum import Enum, unique
import glob
import json
import locale
import os
import platform
import re
import shlex
import subprocess
from typing import Any, Dict, List, Optional, Tuple
import webbrowser
import shlex
import locale
import numpy as np
@ -18,7 +19,17 @@ from arm.lib.lz4 import LZ4
import arm.log as log
import arm.make_state as state
import arm.props_renderpath
from enum import Enum, unique
if "DO_RELOAD_MODULE" in locals():
arm.lib.armpack = arm.reload_module(arm.lib.armpack)
arm.lib.lz4 = arm.reload_module(arm.lib.lz4)
from arm.lib.lz4 import LZ4
log = arm.reload_module(log)
state = arm.reload_module(state)
arm.props_renderpath = arm.reload_module(arm.props_renderpath)
else:
DO_RELOAD_MODULE = True
class NumpyEncoder(json.JSONEncoder):
def default(self, obj):

View file

@ -11,6 +11,14 @@ import arm.assets as assets
import arm.make_state as state
import arm.utils
if "DO_RELOAD_MODULE" in locals():
import arm
assets = arm.reload_module(assets)
state = arm.reload_module(state)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def on_same_drive(path1: str, path2: str) -> bool:
drive_path1, _ = os.path.splitdrive(path1)

View file

@ -11,6 +11,14 @@ import arm.assets as assets
import arm.log as log
import arm.utils
if "DO_RELOAD_MODULE" in locals():
import arm
assets = arm.reload_module(assets)
log = arm.reload_module(log)
arm.utils = arm.reload_module(arm.utils)
else:
DO_RELOAD_MODULE = True
def add_irr_assets(output_file_irr):
assets.add(output_file_irr + '.arm')

View file

@ -1,3 +1,7 @@
import time
import arm
import arm.log
import arm.nodes_logic
import arm.nodes_material
import arm.props_traits_props
@ -15,8 +19,38 @@ import arm.handlers
import arm.utils
import arm.keymap
reload_started = 0
if "DO_RELOAD_MODULE" in locals():
arm.log.debug('Reloading Armory SDK...')
reload_started = time.time()
# Clear the module cache
import importlib
arm = importlib.reload(arm) # type: ignore
arm.nodes_logic = arm.reload_module(arm.nodes_logic)
arm.nodes_material = arm.reload_module(arm.nodes_material)
arm.props_traits_props = arm.reload_module(arm.props_traits_props)
arm.props_traits = arm.reload_module(arm.props_traits)
arm.props_lod = arm.reload_module(arm.props_lod)
arm.props_tilesheet = arm.reload_module(arm.props_tilesheet)
arm.props_exporter = arm.reload_module(arm.props_exporter)
arm.props_bake = arm.reload_module(arm.props_bake)
arm.props_renderpath = arm.reload_module(arm.props_renderpath)
arm.props_properties = arm.reload_module(arm.props_properties)
arm.props_collision_filter_mask = arm.reload_module(arm.props_collision_filter_mask)
arm.props = arm.reload_module(arm.props)
arm.props_ui = arm.reload_module(arm.props_ui)
arm.handlers = arm.reload_module(arm.handlers)
arm.utils = arm.reload_module(arm.utils)
arm.keymap = arm.reload_module(arm.keymap)
else:
DO_RELOAD_MODULE = True
registered = False
def register(local_sdk=False):
global registered
registered = True
@ -37,6 +71,10 @@ def register(local_sdk=False):
arm.handlers.register()
arm.props_collision_filter_mask.register()
if reload_started != 0:
arm.log.debug(f'Armory SDK: Reloading finished in {time.time() - reload_started:.3f}s')
def unregister():
global registered
registered = False