scene_helpers.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. """
  2. Copyright (c) Contributors to the Open 3D Engine Project.
  3. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. SPDX-License-Identifier: Apache-2.0 OR MIT
  5. """
  6. import traceback, logging, json
  7. from typing import Tuple, List
  8. import azlmbr.bus
  9. from scene_api import scene_data as sceneData
  10. from scene_api.scene_data import SceneGraphName
  11. def log_exception_traceback():
  12. """
  13. Outputs an exception stacktrace.
  14. """
  15. data = traceback.format_exc()
  16. logger = logging.getLogger('python')
  17. logger.error(data)
  18. def sanitize_name_for_disk(name: str):
  19. """
  20. Removes illegal filename characters from a string.
  21. :param name: String to clean.
  22. :return: Name with illegal characters removed.
  23. """
  24. return "".join(char for char in name if char not in "|<>:\"/?*\\")
  25. def get_mesh_node_names(scene_graph: sceneData.SceneGraph) -> Tuple[List[SceneGraphName], List[str]]:
  26. """
  27. Returns a tuple of all the mesh nodes as well as all the node paths
  28. :param scene_graph: Scene graph to search
  29. :return: Tuple of [Mesh Nodes, All Node Paths]
  30. """
  31. import azlmbr.scene as sceneApi
  32. import azlmbr.scene.graph
  33. mesh_data_list = []
  34. node = scene_graph.get_root()
  35. children = []
  36. paths = []
  37. while node.IsValid():
  38. # store children to process after siblings
  39. if scene_graph.has_node_child(node):
  40. children.append(scene_graph.get_node_child(node))
  41. node_name = sceneData.SceneGraphName(scene_graph.get_node_name(node))
  42. paths.append(node_name.get_path())
  43. # store any node that has mesh data content
  44. node_content = scene_graph.get_node_content(node)
  45. if node_content.CastWithTypeName('MeshData'):
  46. if scene_graph.is_node_end_point(node) is False:
  47. if len(node_name.get_path()):
  48. mesh_data_list.append(sceneData.SceneGraphName(scene_graph.get_node_name(node)))
  49. # advance to next node
  50. if scene_graph.has_node_sibling(node):
  51. node = scene_graph.get_node_sibling(node)
  52. elif children:
  53. node = children.pop()
  54. else:
  55. node = azlmbr.scene.graph.NodeIndex()
  56. return mesh_data_list, paths
  57. def create_prefab(scene_manifest: sceneData.SceneManifest, prefab_name: str, entities: list) -> None:
  58. prefab_filename = prefab_name + ".prefab"
  59. created_template_id = azlmbr.prefab.PrefabSystemScriptingBus(azlmbr.bus.Broadcast, "CreatePrefab", entities,
  60. prefab_filename)
  61. if created_template_id is None or created_template_id == azlmbr.prefab.InvalidTemplateId:
  62. raise RuntimeError("CreatePrefab {} failed".format(prefab_filename))
  63. # Convert the prefab to a JSON string
  64. output = azlmbr.prefab.PrefabLoaderScriptingBus(azlmbr.bus.Broadcast, "SaveTemplateToString", created_template_id)
  65. if output is not None and output.IsSuccess():
  66. json_string = output.GetValue()
  67. uuid = azlmbr.math.Uuid_CreateRandom().ToString()
  68. json_result = json.loads(json_string)
  69. # Add a PrefabGroup to the manifest and store the JSON on it
  70. scene_manifest.add_prefab_group(prefab_name, uuid, json_result)
  71. else:
  72. raise RuntimeError(
  73. "SaveTemplateToString failed for template id {}, prefab {}".format(created_template_id, prefab_filename))