scene_helpers.py 3.5 KB

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