| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  | import importlib | 
					
						
							|  |  |  | import inspect | 
					
						
							|  |  |  | import pkgutil | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import lnx | 
					
						
							|  |  |  | import lnx.logicnode.lnx_nodes as lnx_nodes | 
					
						
							|  |  |  | from lnx.logicnode.lnx_props import * | 
					
						
							|  |  |  | import lnx.logicnode.lnx_sockets as lnx_sockets | 
					
						
							|  |  |  | from lnx.logicnode.replacement import NodeReplacement | 
					
						
							|  |  |  | from lnx.logicnode.lnx_advanced_draw import * | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if lnx.is_reload(__name__): | 
					
						
							|  |  |  |     lnx_nodes = lnx.reload_module(lnx_nodes) | 
					
						
							|  |  |  |     lnx.logicnode.lnx_props = lnx.reload_module(lnx.logicnode.lnx_props) | 
					
						
							|  |  |  |     from lnx.logicnode.lnx_props import * | 
					
						
							|  |  |  |     lnx_sockets = lnx.reload_module(lnx_sockets) | 
					
						
							|  |  |  |     lnx.logicnode.replacement = lnx.reload_module(lnx.logicnode.replacement) | 
					
						
							|  |  |  |     from lnx.logicnode.replacement import NodeReplacement | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     HAS_RELOADED = True | 
					
						
							|  |  |  | else: | 
					
						
							|  |  |  |     lnx.enable_reload(__name__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def init_categories(): | 
					
						
							|  |  |  |     """Register default node menu categories.""" | 
					
						
							|  |  |  |     lnx_nodes.add_category('Logic', icon='OUTLINER', section="basic", | 
					
						
							|  |  |  |                            description="Logic nodes are used to control execution flow using branching, loops, gates etc.") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Event', icon='INFO', section="basic") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Input', icon='GREASEPENCIL', section="basic") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Native', icon='MEMORY', section="basic", | 
					
						
							|  |  |  |                            description="The Native category contains nodes which interact with the system (Input/Output functionality, etc.) or Haxe.") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lnx_nodes.add_category('Browser', icon='URL', section="basic") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Camera', icon='OUTLINER_OB_CAMERA', section="data") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Material', icon='MATERIAL', section="data") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Light', icon='LIGHT', section="data") | 
					
						
							|  |  |  |     lnx_nodes.add_category('World', icon='WORLD', section="data") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Object', icon='OBJECT_DATA', section="data") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Scene', icon='SCENE_DATA', section="data") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Trait', icon='NODETREE', section="data") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Network', icon='WORLD', section="data") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Leenkx', icon='ORIENTATION_CURSOR', section="data") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lnx_nodes.add_category('Animation', icon='SEQUENCE', section="motion") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Navmesh', icon='UV_VERTEXSEL', section="motion") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Transform', icon='TRANSFORM_ORIGINS', section="motion") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Physics', icon='PHYSICS', section="motion") | 
					
						
							| 
									
										
										
										
											2025-05-22 22:06:41 +00:00
										 |  |  |     lnx_nodes.add_category('Particle', icon='PARTICLE_DATA', section="motion") | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2025-01-22 16:18:30 +01:00
										 |  |  |     lnx_nodes.add_category('Array', icon='MOD_ARRAY', section="values") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Map', icon='SHORTDISPLAY', section="values") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Database', icon='MESH_CYLINDER', section="values") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Math', icon='FORCE_HARMONIC', section="values") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Random', icon='SEQ_HISTOGRAM', section="values") | 
					
						
							|  |  |  |     lnx_nodes.add_category('String', icon='SORTALPHA', section="values") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Variable', icon='OPTIONS', section="values") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lnx_nodes.add_category('HTML', icon='SEQ_STRIP_META', section="graphics") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Draw', icon='GREASEPENCIL', section="graphics") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Canvas', icon='RENDERLAYERS', section="graphics", | 
					
						
							|  |  |  |                            description="Note: To get the canvas, be sure that the node(s) and the canvas (UI) is attached to the same object.") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Postprocess', icon='FREEZE', section="graphics") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Renderpath', icon='STICKY_UVS_LOC', section="graphics") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lnx_nodes.add_category('Sound', icon='OUTLINER_OB_SPEAKER', section="sound") | 
					
						
							|  |  |  |     lnx_nodes.add_category('3D_Audio', icon='SPEAKER', section="sound") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     lnx_nodes.add_category('Miscellaneous', icon='RESTRICT_COLOR_ON', section="misc") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Custom', icon='PLUGIN', section="misc") | 
					
						
							|  |  |  |     lnx_nodes.add_category('Layout', icon='SEQ_STRIP_DUPLICATE', section="misc") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Make sure that logic node extension packs are displayed at the end | 
					
						
							|  |  |  |     # of the menu by default unless they declare it otherwise | 
					
						
							|  |  |  |     lnx_nodes.add_category_section('default') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def init_nodes(base_path=__path__, base_package=__package__, subpackages_only=False): | 
					
						
							|  |  |  |     """Calls the `on_register()` method on all logic nodes in a given
 | 
					
						
							|  |  |  |     `base_package` and all its sub-packages relative to the given | 
					
						
							|  |  |  |     `base_path`, in order to initialize them and to register them to Leenkx. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Be aware that calling this function will import all modules in the | 
					
						
							|  |  |  |     given package, so module-level code will be executed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     If `subpackages_only` is true, modules directly inside the root of | 
					
						
							|  |  |  |     the base package are not searched and imported. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     for loader, module_name, is_pkg in pkgutil.walk_packages(base_path, base_package + '.'): | 
					
						
							|  |  |  |         if is_pkg: | 
					
						
							|  |  |  |             # 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) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Only look at modules in sub packages if specified | 
					
						
							|  |  |  |         elif not subpackages_only or module_name.rsplit('.', 1)[0] != base_package: | 
					
						
							|  |  |  |             if 'HAS_RELOADED' not in globals() or module_name not in sys.modules: | 
					
						
							|  |  |  |                 _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 in ("LnxLogicTreeNode", "LnxLogicVariableNodeMixin"): | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 if issubclass(obj, lnx_nodes.LnxLogicTreeNode): | 
					
						
							|  |  |  |                     obj.on_register() |