Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,9 @@ def set_scene_file(self, data: dict) -> None:
Opens a scene file in 3dsMax in quiet mode. This means that any popups after start up get ignored
(e.g. missing XRefs) so they don't halt the adaptor.

The scene is loaded with its authored system units so it is not rescaled when the host's
unit scale differs.

:param data: The data given from the Adaptor. Keys expected: ['scene_file']

:raises: FileNotFoundError: If the file provided in the data dictionary does not exist.
Expand All @@ -518,11 +521,12 @@ def set_scene_file(self, data: dict) -> None:
if not os.path.isfile(file_path):
self.log_to_console(f"Error: The scene file '{file_path}' does not exist")
raise FileNotFoundError(f"Error: The scene file '{file_path}' does not exist")
self._log_system_units("before scene load")
try:
rt.SetQuietMode(True)
# Make sure any renderered frames are re-rendered.
rt.skipRenderedFrames = False
rt.loadMaxFile(file_path, quiet=True)
rt.loadMaxFile(file_path, quiet=True, useFileUnits=True)

# Apply path mapping after scene load
if self.map_path is not None:
Expand All @@ -531,6 +535,21 @@ def set_scene_file(self, data: dict) -> None:
except Exception:
self.log_to_console(f"Error: while opening '{file_path}'")
raise RuntimeError(f"Error: while opening '{file_path}'")
self._log_system_units("after scene load")

def _log_system_units(self, when: str) -> None:
"""
Writes the current system unit type and scale to the session log. This is diagnostic only:
a failure to read the units is logged as a warning and never affects the scene load.

:param when: Short label for where in the load sequence this is logged.
"""
try:
self.log_to_console(
f"System units {when}: type={rt.units.SystemType}, scale={rt.units.SystemScale}"
)
except Exception as e:
self.log_to_console(f"Warning: could not read system units {when}: {e}")

def _apply_path_mapping(self) -> None:
"""
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
from __future__ import annotations
from unittest.mock import patch, Mock
from unittest.mock import patch, Mock, PropertyMock

import pytest
from deadline.max_adaptor.MaxClient.render_handlers import DefaultMaxHandler
Expand Down Expand Up @@ -165,6 +165,72 @@ def test_cleanup_render_elements_success(self, maxhandlerbase: DefaultMaxHandler
# THEN
mock_render_element_manager.restore_render_elements.assert_called_once()

@patch("deadline.max_adaptor.MaxClient.render_handlers.default_max_handler.os.path.isfile")
@patch("deadline.max_adaptor.MaxClient.render_handlers.default_max_handler.rt")
def test_set_scene_file_loads_with_file_units(
self, mock_rt: Mock, mock_isfile: Mock, maxhandlerbase: DefaultMaxHandler
) -> None:
"""Tests that the scene is loaded with its own units instead of being rescaled to the session's"""
# GIVEN
mock_isfile.return_value = True
maxhandlerbase.map_path = None

# WHEN
maxhandlerbase.set_scene_file({"scene_file": "/path/to/scene.max"})

# THEN
mock_rt.loadMaxFile.assert_called_once_with(
"/path/to/scene.max", quiet=True, useFileUnits=True
)

@patch("deadline.max_adaptor.MaxClient.render_handlers.default_max_handler.os.path.isfile")
@patch("deadline.max_adaptor.MaxClient.render_handlers.default_max_handler.rt")
def test_set_scene_file_logs_system_units(
self, mock_rt: Mock, mock_isfile: Mock, maxhandlerbase: DefaultMaxHandler
) -> None:
"""Tests that system units are logged before and after the scene is loaded"""
# GIVEN
mock_isfile.return_value = True
mock_rt.units.SystemType = "#Inches"
mock_rt.units.SystemScale = 1.0
maxhandlerbase.map_path = None
maxhandlerbase.log_to_console = Mock() # type: ignore[method-assign]

# WHEN
maxhandlerbase.set_scene_file({"scene_file": "/path/to/scene.max"})

# THEN
messages = [call.args[0] for call in maxhandlerbase.log_to_console.call_args_list]
assert "System units before scene load: type=#Inches, scale=1.0" in messages
assert "System units after scene load: type=#Inches, scale=1.0" in messages

@patch("deadline.max_adaptor.MaxClient.render_handlers.default_max_handler.os.path.isfile")
@patch("deadline.max_adaptor.MaxClient.render_handlers.default_max_handler.rt")
def test_set_scene_file_units_read_failure_does_not_fail_load(
self, mock_rt: Mock, mock_isfile: Mock, maxhandlerbase: DefaultMaxHandler
) -> None:
"""Tests that a failure to read system units is only a warning and does not stop the load"""
# GIVEN
mock_isfile.return_value = True
type(mock_rt.units).SystemType = PropertyMock(side_effect=RuntimeError("no units"))
maxhandlerbase.map_path = Mock()
maxhandlerbase._apply_path_mapping = Mock() # type: ignore[method-assign]
maxhandlerbase.log_to_console = Mock() # type: ignore[method-assign]

# WHEN
maxhandlerbase.set_scene_file({"scene_file": "/path/to/scene.max"})

# THEN
mock_rt.loadMaxFile.assert_called_once_with(
"/path/to/scene.max", quiet=True, useFileUnits=True
)
maxhandlerbase._apply_path_mapping.assert_called_once()
messages = [call.args[0] for call in maxhandlerbase.log_to_console.call_args_list]
assert messages == [
"Warning: could not read system units before scene load: no units",
"Warning: could not read system units after scene load: no units",
]


class TestBatchRender:
"""Tests for batch rendering functionality in DefaultMaxHandler."""
Expand Down
Loading