Exemple #1
0
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
Exemple #2
0
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')
Exemple #3
0
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')
Exemple #4
0
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')
Exemple #5
0
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')
Exemple #6
0
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')
Exemple #7
0
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')
Exemple #8
0
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')
Exemple #9
0
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')
Exemple #10
0
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])
Exemple #11
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)
Exemple #12
0
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()