def write_result(link: bpy.types.NodeLink) -> Optional[str]: """Write the parsed result of the given node link to the shader.""" res_var = res_var_name(link.from_node, link.from_socket) # Unparsed node if not is_parsed(res_var): state.parsed.add(res_var) st = link.from_socket.type if st in ('RGB', 'RGBA', 'VECTOR'): res = parse_vector(link.from_node, link.from_socket) if res is None: log.error( f'{link.from_node.name} returned `None` while parsing!') return None state.curshader.write(f'vec3 {res_var} = {res};') elif st == 'VALUE': res = parse_value(link.from_node, link.from_socket) if res is None: log.error( f'{link.from_node.name} returned `None` while parsing!') return None if link.from_node.type == "VALUE" and not link.from_node.arm_material_param: state.curshader.add_const('float', res_var, res) else: state.curshader.write(f'float {res_var} = {res};') # Normal map already parsed, return elif link.from_node.type == 'NORMAL_MAP': return None return res_var
def done_vs_build(): if state.proc_publish_build == None: return result = state.proc_publish_build.poll() if result == 0: state.proc_publish_build = None wrd = bpy.data.worlds['Arm'] project_path = os.path.join(arm.utils.get_fp_build(), arm.utils.get_kha_target(state.target)) + '-build' if wrd.arm_project_win_build_arch == 'x64': path = os.path.join(project_path, 'x64', wrd.arm_project_win_build_mode) else: path = os.path.join(project_path, wrd.arm_project_win_build_mode) print('\nCompilation completed in ' + path) # Run if int(wrd.arm_project_win_build) == 3: # Copying the executable file res_path = os.path.join(arm.utils.get_fp_build(), arm.utils.get_kha_target(state.target)) file_name = arm.utils.safesrc(wrd.arm_project_name +'-'+ wrd.arm_project_version) + '.exe' print('\nCopy the executable file from ' + path + ' to ' + res_path) shutil.copyfile(os.path.join(path, file_name), os.path.join(res_path, file_name)) path = res_path # Run project cmd = os.path.join('"' + res_path, file_name + '"') print('Run the executable file to ' + cmd) os.chdir(res_path) # set work folder subprocess.Popen(cmd, shell=True) # Open Build Directory if wrd.arm_project_win_build_open: arm.utils.open_folder(path) state.redraw_ui = True else: state.proc_publish_build = None state.redraw_ui = True log.error('Compile failed, check console')
def done_gradlew_build(): if state.proc_publish_build == None: return result = state.proc_publish_build.poll() if result == 0: state.proc_publish_build = None wrd = bpy.data.worlds['Arm'] path_apk = os.path.join(arm.utils.get_fp_build(), arm.utils.get_kha_target(state.target)) path_apk = os.path.join(path_apk + '-build', arm.utils.safestr(wrd.arm_project_name), "app", "build", "outputs", "apk", "debug") print("\nBuild APK to " + path_apk) # Open directory with APK if arm.utils.get_android_open_build_apk_directory(): arm.utils.open_folder(path_apk) # Running emulator if wrd.arm_project_android_run_avd: run_android_emulators(arm.utils.get_android_emulator_name()) state.redraw_ui = True else: state.proc_publish_build = None state.redraw_ui = True os.environ['ANDROID_SDK_ROOT'] = '' log.error('Building the APK failed, check console')
def compilation_server_done(): if state.proc_build == None: return result = state.proc_build.poll() if result == 0: build_done() else: state.proc_build = None state.redraw_ui = True log.error('Build failed, check console')
def assets_done(): if state.proc_build == None: return result = state.proc_build.poll() if result == 0: # Connect to the compilation server os.chdir(arm.utils.build_dir() + '/debug/') cmd = [arm.utils.get_haxe_path(), '--connect', '6000', 'project-krom.hxml'] state.proc_build = run_proc(cmd, compilation_server_done) else: state.proc_build = None state.redraw_ui = True log.error('Build failed, check console')
def compilation_server_done(): if state.proc_build == None: return result = state.proc_build.poll() if result == 0: if os.path.exists('krom/krom.js.temp'): os.chmod('krom/krom.js', stat.S_IWRITE) os.remove('krom/krom.js') os.rename('krom/krom.js.temp', 'krom/krom.js') build_done() else: state.proc_build = None state.redraw_ui = True log.error('Build failed, check console')
def build_done(): print('Finished in ' + str(time.time() - profile_time)) if log.num_warnings > 0: log.print_warn(f'{log.num_warnings} warnings occurred during compilation') if state.proc_build is None: return result = state.proc_build.poll() state.proc_build = None state.redraw_ui = True if result == 0: bpy.data.worlds['Arm'].arm_recompile = False build_success() else: log.error('Build failed, check console')
def done_vs_vars(): if state.proc_publish_build == None: return result = state.proc_publish_build.poll() if result == 0: state.proc_publish_build = None # MSBuild wrd = bpy.data.worlds['Arm'] list_vs, err = arm.utils.get_list_installed_vs(True, True, True) # Current VS vs_path = '' vs_name = '' for vs in list_vs: if vs[0] == wrd.arm_project_win_list_vs: vs_name = vs[1] vs_path = vs[2] break msbuild = os.path.join(vs_path, 'MSBuild', 'Current', 'Bin', 'MSBuild.exe') if not os.path.isfile(msbuild): print('File "' + msbuild + '" not found. Verify ' + vs_name + ' was installed correctly') log.error('Compile failed, check console') state.redraw_ui = True return project_name = arm.utils.safesrc(wrd.arm_project_name + '-' + wrd.arm_project_version) project_path = os.path.join(arm.utils.get_fp_build(), arm.utils.get_kha_target( state.target)) + '-build' cmd = '"' + msbuild + '" "' + os.path.join(project_path, project_name + '.vcxproj"') # Arguments platform = 'x64' if wrd.arm_project_win_build_arch == 'x64' else 'win32' log_param = wrd.arm_project_win_build_log if log_param == 'WarningsAndErrorsOnly': log_param = 'WarningsOnly;ErrorsOnly' cmd = cmd + ' -m:' + str( wrd.arm_project_win_build_cpu ) + ' -clp:' + log_param + ' /p:Configuration=' + wrd.arm_project_win_build_mode + ' /p:Platform=' + platform print('\nCompiling the project ' + os.path.join(project_path, project_name + '.vcxproj"')) state.proc_publish_build = run_proc(cmd, done_vs_build) state.redraw_ui = True else: state.proc_publish_build = None state.redraw_ui = True log.error('\nCompile failed, check console')
def done_gradlew_build(): if state.proc_publish_build == None: return result = state.proc_publish_build.poll() if result == 0: state.proc_publish_build = None wrd = bpy.data.worlds['Arm'] path_apk = os.path.join(arm.utils.get_fp_build(), arm.utils.get_kha_target(state.target)) project_name = arm.utils.safesrc(wrd.arm_project_name + '-' + wrd.arm_project_version) path_apk = os.path.join(path_apk + '-build', project_name, 'app', 'build', 'outputs', 'apk', 'debug') print("\nBuild APK to " + path_apk) # Rename APK apk_name = 'app-debug.apk' file_name = os.path.join(path_apk, apk_name) if wrd.arm_project_android_rename_apk: apk_name = project_name + '.apk' os.rename(file_name, os.path.join(path_apk, apk_name)) file_name = os.path.join(path_apk, apk_name) print("\nRename APK to " + apk_name) # Copy APK if wrd.arm_project_android_copy_apk: shutil.copyfile( file_name, os.path.join(arm.utils.get_android_apk_copy_path(), apk_name)) print("Copy APK to " + arm.utils.get_android_apk_copy_path()) # Open directory with APK if arm.utils.get_android_open_build_apk_directory(): arm.utils.open_folder(path_apk) # Open directory after copy APK if arm.utils.get_android_apk_copy_open_directory(): arm.utils.open_folder(arm.utils.get_android_apk_copy_path()) # Running emulator if wrd.arm_project_android_run_avd: run_android_emulators(arm.utils.get_android_emulator_name()) state.redraw_ui = True else: state.proc_publish_build = None state.redraw_ui = True os.environ['ANDROID_SDK_ROOT'] = '' log.error('Building the APK failed, check console')
def parse_tex_sky(node: bpy.types.ShaderNodeTexSky, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str: if state.context == ParserContext.OBJECT: # Pass through return c.to_vec3([0.0, 0.0, 0.0]) state.world.world_defs += '_EnvSky' if node.sky_type == 'PREETHAM' or node.sky_type == 'HOSEK_WILKIE': if node.sky_type == 'PREETHAM': log.info('Info: Preetham sky model is not supported, using Hosek Wilkie sky model instead') return parse_sky_hosekwilkie(node, state) elif node.sky_type == 'NISHITA': return parse_sky_nishita(node, state) else: log.error(f'Unsupported sky model: {node.sky_type}!') return c.to_vec3([0.0, 0.0, 0.0])
def build_success(): log.clear() wrd = bpy.data.worlds['Arm'] if state.is_play: if wrd.arm_runtime == 'Browser': # Start server os.chdir(arm.utils.get_fp()) t = threading.Thread(name='localserver', target=arm.lib.server.run_tcp) t.daemon = True t.start() html5_app_path = 'http://localhost:8040/' + arm.utils.build_dir( ) + '/debug/html5' webbrowser.open(html5_app_path) elif wrd.arm_runtime == 'Krom': if wrd.arm_live_patch: open(arm.utils.get_fp_build() + '/debug/krom/krom.patch', 'w').close() krom_location, krom_path = arm.utils.krom_paths() os.chdir(krom_location) cmd = [ krom_path, arm.utils.get_fp_build() + '/debug/krom', arm.utils.get_fp_build() + '/debug/krom-resources' ] if arm.utils.get_os() == 'win': cmd.append('--consolepid') cmd.append(str(os.getpid())) if wrd.arm_audio == 'Disabled': cmd.append('--nosound') if wrd.arm_verbose_output: print("Running: ", *cmd) state.proc_play = run_proc(cmd, play_done) elif state.is_publish: sdk_path = arm.utils.get_sdk_path() target_name = arm.utils.get_kha_target(state.target) files_path = os.path.join(arm.utils.get_fp_build(), target_name) if (target_name == 'html5' or target_name == 'krom') and wrd.arm_minify_js: # Minify JS minifier_path = sdk_path + '/lib/armory_tools/uglifyjs/bin/uglifyjs' if target_name == 'html5': jsfile = files_path + '/kha.js' else: jsfile = files_path + '/krom.js' args = [ arm.utils.get_node_path(), minifier_path, jsfile, '-o', jsfile ] proc = subprocess.Popen(args) proc.wait() if target_name == 'krom': # Copy Krom binaries if state.target == 'krom-windows': gapi = state.export_gapi ext = '' if gapi == 'direct3d11' else '_' + gapi krom_location = sdk_path + '/Krom/Krom' + ext + '.exe' shutil.copy(krom_location, files_path + '/Krom.exe') krom_exe = arm.utils.safestr(wrd.arm_project_name) + '.exe' os.rename(files_path + '/Krom.exe', files_path + '/' + krom_exe) elif state.target == 'krom-linux': krom_location = sdk_path + '/Krom/Krom' shutil.copy(krom_location, files_path) krom_exe = arm.utils.safestr(wrd.arm_project_name) os.rename(files_path + '/Krom', files_path + '/' + krom_exe) krom_exe = './' + krom_exe else: krom_location = sdk_path + '/Krom/Krom.app' shutil.copytree(krom_location, files_path + '/Krom.app') game_files = os.listdir(files_path) for f in game_files: f = files_path + '/' + f if os.path.isfile(f): shutil.move(f, files_path + '/Krom.app/Contents/MacOS') krom_exe = arm.utils.safestr(wrd.arm_project_name) + '.app' os.rename(files_path + '/Krom.app', files_path + '/' + krom_exe) # Rename ext = state.target.split('-')[-1] # krom-windows new_files_path = files_path + '-' + ext os.rename(files_path, new_files_path) files_path = new_files_path if target_name == 'html5': project_path = files_path print('Exported HTML5 package to ' + project_path) elif target_name.startswith('ios') or target_name.startswith( 'osx'): # TODO: to macos project_path = files_path + '-build' print('Exported XCode project to ' + project_path) elif target_name.startswith('windows'): project_path = files_path + '-build' vs_ver, vs_year, vs_name, vs_id = arm.utils.get_visual_studio_from_version( wrd.arm_project_win_list_vs) print('Exported ' + vs_name + ' project to ' + project_path) elif target_name.startswith('android'): project_name = arm.utils.safesrc(wrd.arm_project_name + '-' + wrd.arm_project_version) project_path = os.path.join(files_path + '-build', project_name) print('Exported Android Studio project to ' + project_path) elif target_name.startswith('krom'): project_path = files_path print('Exported Krom package to ' + project_path) else: project_path = files_path + '-build' print('Exported makefiles to ' + project_path) if arm.utils.get_arm_preferences().open_build_directory: arm.utils.open_folder(project_path) # Android build APK if target_name.startswith('android'): if (arm.utils.get_project_android_build_apk()) and (len( arm.utils.get_android_sdk_root_path()) > 0): print("\nBuilding APK") # Check settings path_sdk = arm.utils.get_android_sdk_root_path() if len(path_sdk) > 0: # Check Environment Variables - ANDROID_SDK_ROOT if os.getenv('ANDROID_SDK_ROOT') == None: # Set value from settings os.environ['ANDROID_SDK_ROOT'] = path_sdk else: project_path = '' # Build start if len(project_path) > 0: os.chdir(project_path) # set work folder if arm.utils.get_os_is_windows(): state.proc_publish_build = run_proc( os.path.join(project_path, "gradlew.bat assembleDebug"), done_gradlew_build) else: cmd = shlex.split( os.path.join(project_path, "gradlew assembleDebug")) state.proc_publish_build = run_proc( cmd, done_gradlew_build) else: print( '\nBuilding APK Warning: ANDROID_SDK_ROOT is not specified in environment variables and "Android SDK Path" setting is not specified in preferences: \n- If you specify an environment variable ANDROID_SDK_ROOT, then you need to restart Blender;\n- If you specify the setting "Android SDK Path" in the preferences, then repeat operation "Publish"' ) # HTML5 After Publish if target_name.startswith('html5'): if len(arm.utils.get_html5_copy_path()) > 0 and ( wrd.arm_project_html5_copy): project_name = arm.utils.safesrc(wrd.arm_project_name + '-' + wrd.arm_project_version) dst = os.path.join(arm.utils.get_html5_copy_path(), project_name) if os.path.exists(dst): shutil.rmtree(dst) try: shutil.copytree(project_path, dst) print("Copied files to " + dst) except OSError as exc: if exc.errno == errno.ENOTDIR: shutil.copy(project_path, dst) else: raise if len(arm.utils.get_link_web_server()) and ( wrd.arm_project_html5_start_browser): link_html5_app = arm.utils.get_link_web_server( ) + '/' + project_name print("Running a browser with a link " + link_html5_app) webbrowser.open(link_html5_app) # Windows After Publish if target_name.startswith('windows'): list_vs = [] err = '' # Print message project_name = arm.utils.safesrc(wrd.arm_project_name + '-' + wrd.arm_project_version) if int(wrd.arm_project_win_build) == 1: print('\nOpen in Visual Studio ' + os.path.join(project_path, project_name + '.sln"')) if int(wrd.arm_project_win_build) == 2: print('\nCompile project ' + os.path.join(project_path, project_name + '.vcxproj')) if int(wrd.arm_project_win_build) == 3: print('\nCompile and run project ' + os.path.join(project_path, project_name + '.vcxproj')) if int(wrd.arm_project_win_build) > 0: # Check Visual Studio list_vs, err = arm.utils.get_list_installed_vs( True, True, True) if len(err) > 0: print(err) return if len(list_vs) == 0: print('No Visual Studio found') return is_check = False for vs in list_vs: if vs[0] == wrd.arm_project_win_list_vs: is_check = True break if not is_check: vs_ver, vs_year, vs_name, vs_id = arm.utils.get_visual_studio_from_version( wrd.arm_project_win_list_vs) print(vs_name + ' not found.') print('The following are installed on the PC:') for vs in list_vs: print('- ' + vs[1] + ' (version ' + vs[3] + ')') return # Current VS vs_path = '' for vs in list_vs: if vs[0] == wrd.arm_project_win_list_vs: vs_path = vs[2] break # Open in Visual Studio if int(wrd.arm_project_win_build) == 1: cmd = os.path.join( 'start "' + vs_path, 'Common7', 'IDE', 'devenv.exe" "' + os.path.join(project_path, project_name + '.sln"')) subprocess.Popen(cmd, shell=True) # Compile if int(wrd.arm_project_win_build) > 1: bits = '64' if wrd.arm_project_win_build_arch == 'x64' else '32' # vcvars cmd = os.path.join(vs_path, 'VC', 'Auxiliary', 'Build', 'vcvars' + bits + '.bat') if not os.path.isfile(cmd): print('File "' + cmd + '" not found. Verify ' + vs_name + ' was installed correctly') log.error('Compile failed, check console') return state.proc_publish_build = run_proc(cmd, done_vs_vars)
def replace_all(): """Iterate through all logic node trees in the file and check for node updates/replacements to execute.""" global replacement_errors replacement_errors.clear() for tree in bpy.data.node_groups: if tree.bl_idname == "ArmLogicTreeType": # Use list() to make a "static" copy. It's possible to iterate over it because nodes which get removed # from the tree leave python objects in the list for node in list(tree.nodes): # Blender nodes (layout) if not isinstance(node, arm_nodes.ArmLogicTreeNode): continue # That node has been removed from the tree without replace() being called on it somehow elif node.type == '': continue # Node type deleted. That's unusual. Or it has been replaced for a looong time elif not node.is_registered_node_type(): replacement_errors.append(('unregistered', None, tree.name, None)) # Invalid version number elif not isinstance(type(node).arm_version, int): replacement_errors.append(('bad version', node.bl_idname, tree.name, None)) # Actual replacement elif node.arm_version < type(node).arm_version: try: replace(tree, node) except LookupError as err: replacement_errors.append(('update failed', node.bl_idname, tree.name, traceback.format_exc())) except Exception as err: replacement_errors.append(('misc.', node.bl_idname, tree.name, traceback.format_exc())) # Node version is newer than supported by the class elif node.arm_version > type(node).arm_version: replacement_errors.append(('future version', node.bl_idname, tree.name, None)) # If possible, make a popup about the errors and write an error report into the .blend file's folder if len(replacement_errors) > 0: basedir = os.path.dirname(bpy.data.filepath) reportfile = os.path.join( basedir, 'node_update_failure.{:s}.txt'.format( time.strftime("%Y-%m-%dT%H-%M-%S%z") ) ) with open(reportfile, 'w') as reportf: for error_type, node_class, tree_name, tb in replacement_errors: if error_type == 'unregistered': print(f"A node whose class doesn't exist was found in node tree \"{tree_name}\"", file=reportf) elif error_type == 'update failed': print(f"A node of type {node_class} in tree \"{tree_name}\" failed to be updated, " f"because there is no (longer?) an update routine for this version of the node. Original exception:" "\n" + tb + "\n", file=reportf) elif error_type == 'future version': print(f"A node of type {node_class} in tree \"{tree_name}\" seemingly comes from a future version of armory. " f"Please check whether your version of armory is up to date", file=reportf) elif error_type == 'bad version': print(f"A node of type {node_class} in tree \"{tree_name}\" doesn't have version information attached to it. " f"If so, please check that the nodes in the file are compatible with the in-code node classes. " f"If this nodes comes from an add-on, please check that it is compatible with this version of armory.", file=reportf) elif error_type == 'misc.': print(f"A node of type {node_class} in tree \"{tree_name}\" failed to be updated, " f"because the node's update procedure itself failed. Original exception:" "\n" + tb + "\n", file=reportf) else: print(f"Whoops, we don't know what this error type (\"{error_type}\") means. You might want to report a bug here. " f"All we know is that it comes form a node of class {node_class} in the node tree called \"{tree_name}\".", file=reportf) log.error(f'There were errors in the node update procedure, a detailed report has been written to {reportfile}') bpy.ops.arm.show_node_update_errors()