Skip to content

Commit

Permalink
Merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
AlvaroHG committed Jun 6, 2024
2 parents ad8286b + 3ff34cd commit 60738d9
Show file tree
Hide file tree
Showing 21 changed files with 884 additions and 580 deletions.
2 changes: 1 addition & 1 deletion ai2thor/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
TEST_OUTPUT_DIRECTORY = "../../images-debug"

LOCAL_BUILD_COMMIT_ID = "local"
AUTO_BUILD_PLATFORMS = [CloudRendering, Linux64, OSXIntel64]
AUTO_BUILD_PLATFORMS = [CloudRendering, OSXIntel64]

COMMIT_ID = None
try:
Expand Down
2 changes: 1 addition & 1 deletion ai2thor/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -1460,7 +1460,7 @@ def find_platform_builds(
commit_build = ai2thor.build.Build(
plat, commit_id, self.include_private_scenes, releases_dir
)

print(f"commit_build base_dir: {commit_build.base_dir}")
try:
if os.path.isdir(commit_build.base_dir) or (
not local_build and commit_build.exists()
Expand Down
212 changes: 194 additions & 18 deletions ai2thor/hooks/procedural_asset_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,27 @@
import logging
import os
import warnings
import pathlib

from typing import Dict, Any, List

from objathor.asset_conversion.util import create_asset, get_existing_thor_asset_file_path
from objathor.asset_conversion.util import (
get_existing_thor_asset_file_path,
create_runtime_asset_file,
get_existing_thor_asset_file_path,
change_asset_paths,
add_default_annotations,
load_existing_thor_asset_file
)

logger = logging.getLogger(__name__)

EXTENSIONS_LOADABLE_IN_UNITY = {
".json",
".json.gz",
".msgpack",
".msgpack.gz",
}

def get_all_asset_ids_recursively(
objects: List[Dict[str, Any]], asset_ids: List[str]
Expand All @@ -31,6 +46,143 @@ def get_all_asset_ids_recursively(
assets_set.remove("")
return list(assets_set)

def create_asset(
thor_controller,
asset_id,
asset_directory,
copy_to_dir=None,
verbose=False,
load_file_in_unity=False,
extension=None,
raise_for_failure=True,
fail_if_not_unity_loadable=False
):
return create_assets(
thor_controller=thor_controller,
asset_ids=[asset_id],
assets_dir=asset_directory,
copy_to_dir=copy_to_dir,
verbose=verbose,
load_file_in_unity=load_file_in_unity,
extension=extension,
fail_if_not_unity_loadable=fail_if_not_unity_loadable,
raise_for_failure=raise_for_failure,
)

def create_assets(
thor_controller: Any,
asset_ids: List[str],
assets_dir: str,
copy_to_dir=None,
verbose=False,
load_file_in_unity=False,
extension=None,
fail_if_not_unity_loadable=False,
raise_for_failure=True,
):
copy_to_dir = (
os.path.join(thor_controller._build.base_dir)
if copy_to_dir is None
else copy_to_dir
)

multi_create_unity_loadable = dict(
action="CreateRuntimeAssets",
assets=[],
dir=copy_to_dir,
raise_for_failure=raise_for_failure,
)

create_with_data_actions = []
errors = []

for asset_id in asset_ids:
asset_dir = os.path.join(assets_dir, asset_id)
# Verifies the file exists
asset_path = get_existing_thor_asset_file_path(
out_dir=asset_dir, asset_id=asset_id, force_extension=extension
)
file_extension = (
"".join(pathlib.Path(asset_path).suffixes) if extension is None else extension
)
load_asset_in_unity = load_file_in_unity

if file_extension not in EXTENSIONS_LOADABLE_IN_UNITY:
load_asset_in_unity = False
if fail_if_not_unity_loadable:
errors.append(asset_path)
continue

# save_dir = os.path.join(controller._build.base_dir, "processed_models")
os.makedirs(copy_to_dir, exist_ok=True)

if verbose:
logger.info(f"Copying asset to THOR build dir: {copy_to_dir}.")

asset = create_runtime_asset_file(
asset_directory=asset_dir,
save_dir=copy_to_dir,
asset_id=asset_id,
load_file_in_unity=load_asset_in_unity,
verbose=verbose
)

if not load_asset_in_unity:
# TODO refactor to this when objathor changes
# asset = load_existing_thor_asset_file(
# out_dir=asset_target_dir, object_name=asset_id, force_extension=file_extension
# )
asset = change_asset_paths(asset=asset, save_dir=copy_to_dir)
asset = add_default_annotations(
asset=asset, asset_directory=asset_dir, verbose=verbose
)
create_prefab_action = {
"action": "CreateRuntimeAsset",
"asset": asset,
"raise_for_failure": raise_for_failure,
}
create_with_data_actions.append(create_prefab_action)
else:
asset_args = {
"id": asset_id,
"extension": file_extension,
}
asset_args = add_default_annotations(
asset=asset_args, asset_directory=asset_dir, verbose=verbose
)
multi_create_unity_loadable["assets"].append(
asset_args
)

if fail_if_not_unity_loadable:
error_strs = ', '.join(errors)
extensions = ', '.join(EXTENSIONS_LOADABLE_IN_UNITY)
raise RuntimeError(f"Set to fail if files are not loadable in unity. Invalid extension of files `{error_strs}` must be of any of extensions {extensions}")

events = []
# Slow pass asset data to pipe
if len(create_with_data_actions):
for create_asset_action in create_with_data_actions:
evt = thor_controller.step(**create_asset_action)
events.append(evt)
if verbose:
logger.info(f"Last Action: {thor_controller.last_action['action']}")

if len(multi_create_unity_loadable):
evt = thor_controller.step(**multi_create_unity_loadable)
events.append(evt)
if verbose:
logger.debug(f"Last Action: {thor_controller.last_action['action']}")

for evt in events:
if not evt.metadata["lastActionSuccess"]:
logger.error(
f'Error: {evt.metadata["errorMessage"]}'
f"\nLast Action: {thor_controller.last_action['action']}"
f"\nAction success: {evt.metadata['lastActionSuccess']}"
)
return events


def create_assets_if_not_exist(
controller,
Expand All @@ -43,6 +195,7 @@ def create_assets_if_not_exist(
extension=None,
verbose=False,
raise_for_failure=True,
fail_if_not_unity_loadable=False
):
evt = controller.step(
action="AssetsInDatabase", assetIds=asset_ids, updateProceduralLRUCache=True
Expand All @@ -52,27 +205,50 @@ def create_assets_if_not_exist(
assets_not_created = [
asset_id for (asset_id, in_db) in asset_in_db.items() if not in_db
]
for asset_id in assets_not_created:
asset_dir = os.path.abspath(os.path.join(asset_directory, asset_id))
# print(f"Create {asset_id}")
evt = create_asset(
thor_controller=controller,
asset_id=asset_id,
asset_directory=asset_dir,
copy_to_dir=copy_to_dir,
verbose=verbose,
load_file_in_unity=load_file_in_unity,
extension=None,
# raise_for_failure=raise_for_failure,
)

events = create_assets(
thor_controller=controller,
asset_ids=assets_not_created,
assets_dir=asset_directory,
copy_to_dir=copy_to_dir,
verbose=verbose,
load_file_in_unity=load_file_in_unity,
extension=extension,
fail_if_not_unity_loadable=fail_if_not_unity_loadable
)
for (evt, i) in zip(events, range(len(events))) :
if not evt.metadata["lastActionSuccess"]:
# TODO do a better matching of asset_ids and event
asset_id = assets_not_created[i] if i < len(events) else None
asset_path = get_existing_thor_asset_file_path(out_dir=asset_directory, asset_id=asset_id) if asset_id is not None else ""
warnings.warn(
f"Could not create asset `{get_existing_thor_asset_file_path(out_dir=asset_dir, asset_id=asset_id)}`."
f"Could not create asset `{asset_path}`."
f"\nError: {evt.metadata['errorMessage']}"
)
if stop_if_fail:
return evt
return evt
return events[-1]

# slower
# for asset_id in assets_not_created:
# asset_dir = os.path.abspath(os.path.join(asset_directory, asset_id))
# # print(f"Create {asset_id}")
# evt = create_asset(
# thor_controller=controller,
# asset_id=asset_id,
# asset_directory=asset_dir,
# copy_to_dir=copy_to_dir,
# verbose=verbose,
# load_file_in_unity=load_file_in_unity,
# extension=None,
# # raise_for_failure=raise_for_failure,
# )
# if not evt.metadata["lastActionSuccess"]:
# warnings.warn(
# f"Could not create asset `{get_existing_thor_asset_file_path(out_dir=asset_dir, asset_id=asset_id)}`."
# f"\nError: {evt.metadata['errorMessage']}"
# )
# if stop_if_fail:
# return evt



class ProceduralAssetHookRunner:
Expand Down
2 changes: 1 addition & 1 deletion ai2thor/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def executable_path(cls, base_dir, name):

def select_platforms(request):
candidates = []
system_platform_map = dict(Linux=(Linux64,), Darwin=(OSXIntel64,), Windows=(StandaloneWindows64,))
system_platform_map = dict(Linux=(Linux64,CloudRendering), Darwin=(OSXIntel64,), Windows=(StandaloneWindows64,))
for p in system_platform_map.get(request.system, ()):
if not p.enabled:
continue
Expand Down
18 changes: 16 additions & 2 deletions ai2thor/tests/build_controller.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
import warnings
import os
from ai2thor.controller import Controller

class TestController(Controller):
def __init__(self, **kwargs):
self.force_opengl = os.environ.get("FORCE_OPENGL", False)
if type(self.force_opengl) != bool or self.force_opengl != False:
self.force_opengl = self.force_opengl.lower() in ("true", "1", "t")
super().__init__(**kwargs)

def unity_command(self, width, height, headless):
command = super().unity_command(width, height, headless)
# force OpenGLCore to get used so that the tests run in a consistent way
# With low power graphics cards (such as those in the test environment)
# Metal behaves in inconsistent ways causing test failures
command.append("-force-glcore")

# This is not needed for cloudrendering
if self.force_opengl:
command.append("-force-glcore")
return command

def build_controller(**args):
default_args = dict(local_build=True)
platform = os.environ.get("TEST_PLATFORM")
if platform:
default_args = dict(platform=platform)
else:
default_args = dict(local_build=True)

default_args.update(args)
# during a ci-build we will get a warning that we are using a commit_id for the
Expand Down
Loading

0 comments on commit 60738d9

Please sign in to comment.