Skip to content

Commit

Permalink
3D export fixes and tests (#4368)
Browse files Browse the repository at this point in the history
* WIP 3D export fixes and tests

* print

* errant copypasta

* move rewrite asset logic to scene_3d

* cleanup 3d import/export tests a bit
  • Loading branch information
swheaton authored May 9, 2024
1 parent 89f312d commit 47919b4
Show file tree
Hide file tree
Showing 3 changed files with 359 additions and 38 deletions.
44 changes: 44 additions & 0 deletions fiftyone/core/threed/scene_3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,57 @@ def traverse(self, include_self=False):
Args:
include_self: whether to include the current node in the traversal
Yields:
:class:`Object3D`
"""
if include_self:
yield self

for child in self.children:
yield from child.traverse(include_self=True)

def update_asset_paths(self, asset_rewrite_paths: dict):
"""Update asset paths in this scene according to an input dict mapping.
Asset path is unchanged if it does not exist in ``asset_rewrite_paths``
Args:
asset_rewrite_paths: ``dict`` mapping asset path to new asset path
Returns:
``True`` if the scene was modified.
"""
scene_modified = False
for node in self.traverse():
for path_attribute in node._asset_path_fields:
asset_path = getattr(node, path_attribute, None)
new_asset_path = asset_rewrite_paths.get(asset_path)

if asset_path is not None and asset_path != new_asset_path:
setattr(node, path_attribute, new_asset_path)
scene_modified = True

# modify scene background paths, if any
if self.background is not None:
if self.background.image is not None:
new_asset_path = asset_rewrite_paths.get(self.background.image)
if new_asset_path != self.background.image:
self.background.image = new_asset_path
scene_modified = True

if self.background.cube is not None:
new_cube = [
asset_rewrite_paths.get(face)
for face in self.background.cube
]
if new_cube != self.background.cube:
self.background.cube = new_cube
scene_modified = True

return scene_modified

def get_scene_summary(self):
"""Returns a summary of the scene."""
node_types = Counter(map(type, self.traverse()))
Expand Down
46 changes: 8 additions & 38 deletions fiftyone/utils/data/exporters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,7 @@ def _handle_fo3d_file(self, fo3d_path, fo3d_output_path, export_mode):
scene = fo3d.Scene.from_fo3d(fo3d_path)
asset_paths = scene.get_asset_paths()

input_to_output_paths = {}
for asset_path in asset_paths:
if not os.path.isabs(asset_path):
absolute_asset_path = os.path.join(
Expand All @@ -1181,12 +1182,15 @@ def _handle_fo3d_file(self, fo3d_path, fo3d_output_path, export_mode):

seen = self._filename_maker.seen_input_path(absolute_asset_path)

if seen:
continue

asset_output_path = self._filename_maker.get_output_path(
absolute_asset_path
)
input_to_output_paths[asset_path] = os.path.relpath(
asset_output_path, os.path.dirname(fo3d_output_path)
)

if seen:
continue

if export_mode is True:
etau.copy_file(absolute_asset_path, asset_output_path)
Expand All @@ -1195,41 +1199,7 @@ def _handle_fo3d_file(self, fo3d_path, fo3d_output_path, export_mode):
elif export_mode == "symlink":
etau.symlink_file(absolute_asset_path, asset_output_path)

is_scene_modified = False

for node in scene.traverse():
path_attribute = next(
(
attr
for attr in fo3d.fo3d_path_attributes
if hasattr(node, attr)
),
None,
)

if path_attribute is not None:
asset_path = getattr(node, path_attribute)

is_nested_path = os.path.split(asset_path)[0] != ""

if asset_path is not None and is_nested_path:
setattr(node, path_attribute, os.path.basename(asset_path))
is_scene_modified = True

# modify scene background paths, if any
if scene.background is not None:
if scene.background.image is not None:
scene.background.image = os.path.basename(
scene.background.image
)
is_scene_modified = True

if scene.background.cube is not None:
scene.background.cube = [
os.path.basename(face_path)
for face_path in scene.background.cube
]
is_scene_modified = True
is_scene_modified = scene.update_asset_paths(input_to_output_paths)

if is_scene_modified:
# note: we can't have different behavior for "symlink" because
Expand Down
Loading

0 comments on commit 47919b4

Please sign in to comment.