From 0f13a71bd284a22254b628b94c81241a22ce0ade Mon Sep 17 00:00:00 2001 From: Chris Galvan Date: Wed, 14 Apr 2021 16:01:26 -0500 Subject: [PATCH 01/20] [LYN-2255] Refactored some EditorEntityHelpers so they can be re-used. --- .../Entity/EditorEntityHelpers.cpp | 81 +++++++++++++++++++ .../Entity/EditorEntityHelpers.h | 6 ++ .../Prefab/PrefabPublicHandler.cpp | 19 +---- .../Prefab/PrefabPublicHandler.h | 1 - .../Tests/Entity/EditorEntityHelpersTests.cpp | 71 ++++++++++++++++ .../Tests/aztoolsframeworktests_files.cmake | 2 + .../SandboxIntegration.cpp | 16 +++- 7 files changed, 174 insertions(+), 22 deletions(-) create mode 100644 Code/Framework/AzToolsFramework/Tests/Entity/EditorEntityHelpersTests.cpp diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp index 6ab3625dd2..629dcd639d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.cpp @@ -136,6 +136,48 @@ namespace AzToolsFramework return entity->GetName(); } + EntityList EntityIdListToEntityList(const EntityIdList& inputEntityIds) + { + EntityList entities; + entities.reserve(inputEntityIds.size()); + + for (AZ::EntityId entityId : inputEntityIds) + { + if (!entityId.IsValid()) + { + continue; + } + + if (auto entity = GetEntityById(entityId)) + { + entities.emplace_back(entity); + } + } + + return entities; + } + + EntityList EntityIdSetToEntityList(const EntityIdSet& inputEntityIds) + { + EntityList entities; + entities.reserve(inputEntityIds.size()); + + for (AZ::EntityId entityId : inputEntityIds) + { + if (!entityId.IsValid()) + { + continue; + } + + if (auto entity = GetEntityById(entityId)) + { + entities.emplace_back(entity); + } + } + + return entities; + } + void GetAllComponentsForEntity(const AZ::Entity* entity, AZ::Entity::ComponentArrayType& componentsOnEntity) { if (entity) @@ -1068,6 +1110,45 @@ namespace AzToolsFramework return !allEntityClonesContainer.m_entities.empty(); } + EntityIdSet GetCulledEntityHierarchy(const EntityIdList& entities) + { + EntityIdSet culledEntities; + + for (const AZ::EntityId& entityId : entities) + { + bool selectionIncludesTransformHeritage = false; + AZ::EntityId parentEntityId = entityId; + do + { + AZ::EntityId nextParentId; + AZ::TransformBus::EventResult( + /*result*/ nextParentId, + /*address*/ parentEntityId, + &AZ::TransformBus::Events::GetParentId); + parentEntityId = nextParentId; + if (!parentEntityId.IsValid()) + { + break; + } + for (const AZ::EntityId& parentCheck : entities) + { + if (parentCheck == parentEntityId) + { + selectionIncludesTransformHeritage = true; + break; + } + } + } while (parentEntityId.IsValid() && !selectionIncludesTransformHeritage); + + if (!selectionIncludesTransformHeritage) + { + culledEntities.insert(entityId); + } + } + + return culledEntities; + } + namespace Internal { void CloneSliceEntitiesAndChildren( diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.h index 39f4c37c29..3ef03296f4 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/EditorEntityHelpers.h @@ -47,6 +47,9 @@ namespace AzToolsFramework AZStd::string GetEntityName(const AZ::EntityId& entityId, const AZStd::string_view& nameOverride = {}); + EntityList EntityIdListToEntityList(const EntityIdList& inputEntityIds); + EntityList EntityIdSetToEntityList(const EntityIdSet & inputEntityIds); + template struct AddComponents { @@ -202,4 +205,7 @@ namespace AzToolsFramework /// Wrap EBus SetSelectedEntities call. void SelectEntities(const AzToolsFramework::EntityIdList& entities); + /// Return a set of entities, culling any that have an ancestor in the list. + EntityIdSet GetCulledEntityHierarchy(const EntityIdList & entities); + }; // namespace AzToolsFramework diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp index 417a524e77..43ee7b7033 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.cpp @@ -61,8 +61,7 @@ namespace AzToolsFramework PrefabOperationResult PrefabPublicHandler::CreatePrefab(const AZStd::vector& entityIds, AZStd::string_view filePath) { // Retrieve entityList from entityIds - EntityList inputEntityList; - EntityIdListToEntityList(entityIds, inputEntityList); + EntityList inputEntityList = EntityIdListToEntityList(entityIds); // Find common root and top level entities bool entitiesHaveCommonRoot = false; @@ -419,8 +418,7 @@ namespace AzToolsFramework InstanceOptionalReference instance = GetOwnerInstanceByEntityId(entityIds[0]); // Retrieve entityList from entityIds - EntityList inputEntityList; - EntityIdListToEntityList(entityIds, inputEntityList); + EntityList inputEntityList = EntityIdListToEntityList(entityIds); AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); @@ -767,18 +765,5 @@ namespace AzToolsFramework return true; } - - void PrefabPublicHandler::EntityIdListToEntityList(const EntityIdList& inputEntityIds, EntityList& outEntities) - { - outEntities.reserve(inputEntityIds.size()); - - for (AZ::EntityId entityId : inputEntityIds) - { - if (entityId.IsValid()) - { - outEntities.emplace_back(GetEntityById(entityId)); - } - } - } } } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h index 46a7f946ba..4eb03a7abb 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabPublicHandler.h @@ -70,7 +70,6 @@ namespace AzToolsFramework static Instance* GetParentInstance(Instance* instance); static Instance* GetAncestorOfInstanceThatIsChildOfRoot(const Instance* ancestor, Instance* descendant); static void GenerateContainerEntityTransform(const EntityList& topLevelEntities, AZ::Vector3& translation, AZ::Quaternion& rotation); - static void EntityIdListToEntityList(const EntityIdList& inputEntityIds, EntityList& outEntities); InstanceEntityMapperInterface* m_instanceEntityMapperInterface = nullptr; InstanceToTemplateInterface* m_instanceToTemplateInterface = nullptr; diff --git a/Code/Framework/AzToolsFramework/Tests/Entity/EditorEntityHelpersTests.cpp b/Code/Framework/AzToolsFramework/Tests/Entity/EditorEntityHelpersTests.cpp new file mode 100644 index 0000000000..6bf6beb878 --- /dev/null +++ b/Code/Framework/AzToolsFramework/Tests/Entity/EditorEntityHelpersTests.cpp @@ -0,0 +1,71 @@ +/* +* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +* its licensors. +* +* For complete copyright and license terms please see the LICENSE at the root of this +* distribution (the "License"). All use of this software is governed by the License, +* or, if provided, by the license below or the license accompanying this file. Do not +* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* +*/ + +#include + +#include +#include +#include + +namespace UnitTest +{ + using namespace AZ; + using namespace AzToolsFramework; + + class EditorEntityHelpersTest + : public ToolsApplicationFixture + { + void SetUpEditorFixtureImpl() override + { + m_parent1 = CreateDefaultEditorEntity("Parent1"); + m_child1 = CreateDefaultEditorEntity("Child1"); + m_child2 = CreateDefaultEditorEntity("Child2"); + m_grandChild1 = CreateDefaultEditorEntity("GrandChild1"); + m_parent2 = CreateDefaultEditorEntity("Parent2"); + + AZ::TransformBus::Event(m_child1, &AZ::TransformBus::Events::SetParent, m_parent1); + AZ::TransformBus::Event(m_child2, &AZ::TransformBus::Events::SetParent, m_parent1); + AZ::TransformBus::Event(m_grandChild1, &AZ::TransformBus::Events::SetParent, m_child1); + } + + public: + AZ::EntityId m_parent1; + AZ::EntityId m_child1; + AZ::EntityId m_child2; + AZ::EntityId m_grandChild1; + AZ::EntityId m_parent2; + }; + + TEST_F(EditorEntityHelpersTest, EditorEntityHelpersTests_GetCulledEntityHierarchy) + { + EntityIdList testEntityIds{ m_parent1, m_child1, m_child2, m_grandChild1, m_parent2 }; + + EntityIdSet culledSet = GetCulledEntityHierarchy(testEntityIds); + + // There should only be two EntityIds returned (m_parent1, and m_parent2), + // since all the others should be culled out since they have a common ancestor + // in the list already + EXPECT_EQ(culledSet.size(), 2); + + EntityIdList foundEntityIds{ m_parent1, m_parent2 }; + for (auto& entityId : foundEntityIds) + { + EXPECT_TRUE(AZStd::find(culledSet.begin(), culledSet.end(), entityId) != culledSet.end()); + } + + EntityIdList culledEntityIds{ m_child1, m_child2, m_grandChild1 }; + for (auto& entityId : culledEntityIds) + { + EXPECT_FALSE(AZStd::find(culledSet.begin(), culledSet.end(), entityId) != culledSet.end()); + } + } +} diff --git a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake index 7a2cd373a2..e54aa187e4 100644 --- a/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake +++ b/Code/Framework/AzToolsFramework/Tests/aztoolsframeworktests_files.cmake @@ -85,7 +85,9 @@ set(FILES Prefab/SpawnableSortEntitiesTestFixture.cpp Prefab/SpawnableSortEntitiesTestFixture.h Entity/EditorEntityContextComponentTests.cpp + Entity/EditorEntityHelpersTests.cpp Entity/EditorEntitySearchComponentTests.cpp + Entity/EditorEntitySelectionTests.cpp SliceStabilityTests/SliceStabilityTestFramework.h SliceStabilityTests/SliceStabilityTestFramework.cpp SliceStabilityTests/SliceStabilityCreateTests.cpp diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp index e5311dbea9..69040245f8 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp @@ -670,9 +670,13 @@ void SandboxIntegrationManager::PopulateEditorGlobalContextMenu(QMenu* menu, con action = menu->addAction(QObject::tr("Create layer")); QObject::connect(action, &QAction::triggered, [this] { ContextMenu_NewLayer(); }); + AzToolsFramework::EntityIdList entities; + AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult( + entities, + &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities); + SetupLayerContextMenu(menu); - AzToolsFramework::EntityIdSet flattenedSelection; - GetSelectedEntitiesSetWithFlattenedHierarchy(flattenedSelection); + AzToolsFramework::EntityIdSet flattenedSelection = AzToolsFramework::GetCulledEntityHierarchy(entities); AzToolsFramework::SetupAddToLayerMenu(menu, flattenedSelection, [this] { return ContextMenu_NewLayer(); }); SetupSliceContextMenu(menu); @@ -1220,8 +1224,12 @@ void SandboxIntegrationManager::CloneSelection(bool& handled) { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzToolsFramework); - AzToolsFramework::EntityIdSet duplicationSet; - GetSelectedEntitiesSetWithFlattenedHierarchy(duplicationSet); + AzToolsFramework::EntityIdList entities; + AzToolsFramework::ToolsApplicationRequests::Bus::BroadcastResult( + entities, + &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities); + + AzToolsFramework::EntityIdSet duplicationSet = AzToolsFramework::GetCulledEntityHierarchy(entities); if (duplicationSet.size() > 0) { From 53e84b38209532ba2071232162b40b98f93cfe4f Mon Sep 17 00:00:00 2001 From: luissemp Date: Thu, 15 Apr 2021 09:35:09 -0700 Subject: [PATCH 02/20] Fixed scoping rules for variables --- .../Code/Source/Widgets/GraphCanvasLabel.cpp | 2 + .../Code/Editor/Components/EditorGraph.cpp | 2 +- .../Editor/Model/EntityMimeDataHandler.cpp | 2 +- .../GraphValidationDockWidget.cpp | 2 +- .../VariablePanel/GraphVariablesTableView.cpp | 29 +++++++++++- .../VariablePanel/VariableDockWidget.cpp | 2 +- .../Include/ScriptCanvas/Utils/NodeUtils.cpp | 2 + .../ScriptCanvas/Variable/GraphVariable.cpp | 44 ++++++++++++++----- .../ScriptCanvas/Variable/GraphVariable.h | 8 +++- .../GraphVariableManagerComponent.cpp | 8 +++- .../Variable/GraphVariableManagerComponent.h | 2 +- .../ScriptCanvas/Variable/VariableBus.h | 2 +- .../VariableListFullCreation.cpp | 2 +- .../ScriptCanvasActions/VariableActions.cpp | 4 +- .../Framework/ScriptCanvasTestUtilities.h | 2 +- .../Code/Tests/ScriptCanvas_Variables.cpp | 34 +++++++------- 16 files changed, 103 insertions(+), 44 deletions(-) diff --git a/Gems/GraphCanvas/Code/Source/Widgets/GraphCanvasLabel.cpp b/Gems/GraphCanvas/Code/Source/Widgets/GraphCanvasLabel.cpp index 21f56e2f39..11b230515a 100644 --- a/Gems/GraphCanvas/Code/Source/Widgets/GraphCanvasLabel.cpp +++ b/Gems/GraphCanvas/Code/Source/Widgets/GraphCanvasLabel.cpp @@ -437,5 +437,7 @@ namespace GraphCanvas default: return QGraphicsWidget::sizeHint(which, constraint); } + + return QGraphicsWidget::sizeHint(which, constraint); } } diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp index b14fd7d4c2..9c9297ec1c 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp @@ -2347,7 +2347,7 @@ namespace ScriptCanvasEditor AZ::Outcome addOutcome; // #functions2 slot<->variable re-use the activeDatum, send the pointer (actually, all of the source slot information, and make a special conversion) - ScriptCanvas::GraphVariableManagerRequestBus::EventResult(addOutcome, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, variableDatum); + ScriptCanvas::GraphVariableManagerRequestBus::EventResult(addOutcome, GetScriptCanvasId(), &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, variableDatum, true); if (addOutcome.IsSuccess()) { diff --git a/Gems/ScriptCanvas/Code/Editor/Model/EntityMimeDataHandler.cpp b/Gems/ScriptCanvas/Code/Editor/Model/EntityMimeDataHandler.cpp index 97b9078fab..040019a74e 100644 --- a/Gems/ScriptCanvas/Code/Editor/Model/EntityMimeDataHandler.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Model/EntityMimeDataHandler.cpp @@ -172,7 +172,7 @@ namespace ScriptCanvasEditor { ScriptCanvas::Datum datum = ScriptCanvas::Datum(entityId); - AZ::Outcome addVariableOutcome = variableManagerRequests->AddVariable(variableName, datum); + AZ::Outcome addVariableOutcome = variableManagerRequests->AddVariable(variableName, datum, false); if (addVariableOutcome.IsSuccess()) { diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp index f3eb7a18d1..fb31fbbb7e 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp @@ -1011,7 +1011,7 @@ namespace ScriptCanvasEditor ScriptCanvas::Datum datum(variableType, ScriptCanvas::Datum::eOriginality::Original); AZ::Outcome outcome = AZ::Failure(AZStd::string()); - ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_activeGraphIds.scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, varName, datum); + ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_activeGraphIds.scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, varName, datum, false); if (outcome.IsSuccess()) { diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/GraphVariablesTableView.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/GraphVariablesTableView.cpp index 7f6abe9b3c..946f30bde8 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/GraphVariablesTableView.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/GraphVariablesTableView.cpp @@ -41,6 +41,7 @@ #include #include +#include namespace ScriptCanvasEditor { @@ -538,7 +539,24 @@ namespace ScriptCanvasEditor } else if (index.column() == ColumnIndex::Scope) { - // Scope is not changed by users + ScriptCanvas::GraphVariable* graphVariable = nullptr; + ScriptCanvas::GraphVariableManagerRequestBus::EventResult(graphVariable, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::FindVariableById, varId.m_identifier); + + if (graphVariable) + { + QString comboBoxValue = value.toString(); + + if (!comboBoxValue.isEmpty()) + { + AZStd::string scopeLabel = ScriptCanvas::VariableFlags::GetScopeDisplayLabel(graphVariable->GetScope()); + if (scopeLabel.compare(comboBoxValue.toUtf8().data()) != 0) + { + modifiedData = true; + graphVariable->SetScope(ScriptCanvas::VariableFlags::GetScopeFromLabel(comboBoxValue.toUtf8().data())); + AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&AzToolsFramework::PropertyEditorGUIMessages::RequestRefresh, AzToolsFramework::Refresh_EntireTree); + } + } + } } else if (index.column() == ColumnIndex::InitialValueSource) { @@ -607,8 +625,17 @@ namespace ScriptCanvasEditor } else if (index.column() == ColumnIndex::Scope) { + ScriptCanvas::GraphScopedVariableId varId = FindScopedVariableIdForIndex(index); + + ScriptCanvas::GraphVariable* graphVariable = nullptr; + ScriptCanvas::GraphVariableManagerRequestBus::EventResult(graphVariable, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::FindVariableById, varId.m_identifier); + + if (graphVariable->GetScope() != ScriptCanvas::VariableFlags::Scope::FunctionReadOnly) + { itemFlags |= Qt::ItemIsEditable; } + + } else if (index.column() == ColumnIndex::InitialValueSource) { itemFlags |= Qt::ItemIsEditable; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/VariableDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/VariableDockWidget.cpp index 6668df21f9..b86532d283 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/VariableDockWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/VariableDockWidget.cpp @@ -812,7 +812,7 @@ namespace ScriptCanvasEditor ScriptCanvas::Datum datum(varType, ScriptCanvas::Datum::eOriginality::Original); AZ::Outcome outcome = AZ::Failure(AZStd::string()); - ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, datum); + ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, datum, false); AZ_Warning("VariablePanel", outcome.IsSuccess(), "Could not create new variable: %s", outcome.GetError().c_str()); GeneralRequestBus::Broadcast(&GeneralRequests::PostUndoPoint, m_scriptCanvasId); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.cpp index c1eb2eed36..06ad79c21d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/NodeUtils.cpp @@ -81,6 +81,8 @@ namespace ScriptCanvas { return ConstructCustomNodeIdentifier(scriptCanvasNode->RTTI_GetType()); } + + return NodeTypeIdentifier(0); } NodeTypeIdentifier NodeUtils::ConstructEBusIdentifier(ScriptCanvas::EBusBusId ebusIdentifier) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp index f9c1c0c357..6e5fe82720 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp @@ -43,20 +43,12 @@ namespace ScriptCanvas { const char* GetScopeDisplayLabel(Scope scopeType) { - switch (scopeType) - { - case Scope::Graph: - return "Graph"; - case Scope::Function: - return "Function"; - default: - return "?"; - } + return GraphVariable::s_ScopeNames[static_cast(scopeType)]; } Scope GetScopeFromLabel(const char* label) { - if (strcmp("Function", label) == 0) + if (strcmp(GraphVariable::s_ScopeNames[static_cast(VariableFlags::Scope::Function)], label) == 0) { return Scope::Function; } @@ -71,6 +63,7 @@ namespace ScriptCanvas case Scope::Graph: return "Variable is accessible in the entire graph."; case Scope::Function: + case Scope::FunctionReadOnly: return "Variable is accessible only in the execution path of the function that defined it"; default: return "?"; @@ -162,6 +155,14 @@ namespace ScriptCanvas "From Component" }; + const char* GraphVariable::s_ScopeNames[static_cast(VariableFlags::Scope::COUNT)] = + { + "Graph", + "Function", + "Function", + }; + + void GraphVariable::Reflect(AZ::ReflectContext* context) { if (auto serializeContext = azrtti_cast(context)) @@ -197,6 +198,13 @@ namespace ScriptCanvas return choices; }; + auto scopeChoices = [] { + AZStd::vector< AZStd::pair> choices; + choices.emplace_back(AZStd::make_pair(VariableFlags::Scope::Graph, s_ScopeNames[0])); + choices.emplace_back(AZStd::make_pair(VariableFlags::Scope::Function, s_ScopeNames[1])); + return choices; + }; + editContext->Class("Variable", "Represents a Variable field within a Script Canvas Graph") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::Visibility, &GraphVariable::GetVisibility) @@ -215,8 +223,8 @@ namespace ScriptCanvas ->Attribute(AZ::Edit::Attributes::ChangeNotify, &GraphVariable::OnValueChanged) ->DataElement(AZ::Edit::UIHandlers::ComboBox, &GraphVariable::m_scope, "Scope", "Controls the scope of this variable. i.e. If this is exposed as input to this script, or output from this script, or if the variable is just locally scoped.") - ->Attribute(AZ::Edit::Attributes::Visibility, &GraphVariable::GetInputControlVisibility) - ->Attribute(AZ::Edit::Attributes::GenericValueList, &GraphVariable::GetScopes) + ->Attribute(AZ::Edit::Attributes::Visibility, &GraphVariable::GetScopeControlVisibility) + ->Attribute(AZ::Edit::Attributes::GenericValueList, scopeChoices) ->Attribute(AZ::Edit::Attributes::ChangeNotify, &GraphVariable::OnScopeTypedChanged) ->DataElement(AZ::Edit::UIHandlers::Default, &GraphVariable::m_networkProperties, "Network Properties", "Enables whether or not this value should be network synchronized") @@ -382,6 +390,16 @@ namespace ScriptCanvas m_inputControlVisibility = inputControlVisibility; } + AZ::Crc32 GraphVariable::GetScopeControlVisibility() const + { + if (m_scope == VariableFlags::Scope::FunctionReadOnly) + { + return AZ::Edit::PropertyVisibility::Hide; + } + + return GetInputControlVisibility(); + } + AZ::Crc32 GraphVariable::GetInputControlVisibility() const { return m_inputControlVisibility; @@ -462,6 +480,8 @@ namespace ScriptCanvas return m_scope == VariableFlags::Scope::Graph; // All graph variables are in function local scope case VariableFlags::Scope::Function: + case VariableFlags::Scope::FunctionReadOnly: + return true; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h index 9b5e5cc9d1..4aa3729d7c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h @@ -52,8 +52,10 @@ namespace ScriptCanvas enum class Scope : AZ::u8 { - Graph = 0, - Function = 1, + Graph, + Function, + FunctionReadOnly, + COUNT }; enum InitialValueSource : AZ::u8 @@ -142,6 +144,7 @@ namespace ScriptCanvas void SetScriptInputControlVisibility(const AZ::Crc32& inputControlVisibility); AZ::Crc32 GetInputControlVisibility() const; + AZ::Crc32 GetScopeControlVisibility() const; AZ::Crc32 GetScriptInputControlVisibility() const; AZ::Crc32 GetNetworkSettingsVisibility() const; AZ::Crc32 GetFunctionInputControlVisibility() const; @@ -181,6 +184,7 @@ namespace ScriptCanvas int GetSortPriority() const; static const char* s_InitialValueSourceNames[VariableFlags::InitialValueSource::COUNT]; + static const char* GraphVariable::s_ScopeNames[VariableFlags::Scope::COUNT]; private: diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp index 47f76af4ee..fc5d39148d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp @@ -225,7 +225,7 @@ namespace ScriptCanvas } // #functions2 slot<->variable add this to the graph, using the old datum - AZ::Outcome GraphVariableManagerComponent::AddVariable(AZStd::string_view name, const Datum& value) + AZ::Outcome GraphVariableManagerComponent::AddVariable(AZStd::string_view name, const Datum& value, bool functionScope) { if (FindVariable(name)) { @@ -245,6 +245,10 @@ namespace ScriptCanvas GraphVariable* variable = m_variableData.FindVariable(newId); variable->SetOwningScriptCanvasId(GetScriptCanvasId()); + if (functionScope) + { + variable->SetScope(VariableFlags::Scope::FunctionReadOnly); + } VariableRequestBus::MultiHandler::BusConnect(GraphScopedVariableId(m_scriptCanvasId, newId)); GraphVariableManagerNotificationBus::Event(GetScriptCanvasId(), &GraphVariableManagerNotifications::OnVariableAddedToGraph, newId, name); @@ -254,7 +258,7 @@ namespace ScriptCanvas AZ::Outcome GraphVariableManagerComponent::AddVariablePair(const AZStd::pair& keyValuePair) { - return AddVariable(keyValuePair.first, keyValuePair.second); + return AddVariable(keyValuePair.first, keyValuePair.second, false); } VariableValidationOutcome GraphVariableManagerComponent::IsNameValid(AZStd::string_view varName) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.h index 38d8200a4c..5a75d339d0 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableManagerComponent.h @@ -63,7 +63,7 @@ namespace ScriptCanvas //// GraphVariableManagerRequestBus AZ::Outcome CloneVariable(const GraphVariable& variableConfiguration) override; AZ::Outcome RemapVariable(const GraphVariable& variableConfiguration) override; - AZ::Outcome AddVariable(AZStd::string_view name, const Datum& value) override; + AZ::Outcome AddVariable(AZStd::string_view name, const Datum& value, bool functionScope) override; AZ::Outcome AddVariablePair(const AZStd::pair& nameValuePair) override; VariableValidationOutcome IsNameValid(AZStd::string_view key) override; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/VariableBus.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/VariableBus.h index 7c486ff5c7..f7948907af 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/VariableBus.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/VariableBus.h @@ -90,7 +90,7 @@ namespace ScriptCanvas //! returns an AZ::Outcome which on success contains the VariableId and on Failure contains a string with error information virtual AZ::Outcome CloneVariable(const GraphVariable& baseVariable) = 0; virtual AZ::Outcome RemapVariable(const GraphVariable& variableConfiguration) = 0; - virtual AZ::Outcome AddVariable(AZStd::string_view key, const Datum& value) = 0; + virtual AZ::Outcome AddVariable(AZStd::string_view key, const Datum& value, bool functionScope) = 0; virtual AZ::Outcome AddVariablePair(const AZStd::pair& keyValuePair) = 0; virtual VariableValidationOutcome IsNameValid(AZStd::string_view variableName) = 0; diff --git a/Gems/ScriptCanvasDeveloper/Code/Editor/Source/AutomationActions/VariableListFullCreation.cpp b/Gems/ScriptCanvasDeveloper/Code/Editor/Source/AutomationActions/VariableListFullCreation.cpp index fd3d7b3e9b..9a523aaf61 100644 --- a/Gems/ScriptCanvasDeveloper/Code/Editor/Source/AutomationActions/VariableListFullCreation.cpp +++ b/Gems/ScriptCanvasDeveloper/Code/Editor/Source/AutomationActions/VariableListFullCreation.cpp @@ -63,7 +63,7 @@ namespace ScriptCanvasDeveloperEditor ScriptCanvas::Datum datum(dataType, ScriptCanvas::Datum::eOriginality::Original); AZ::Outcome outcome = AZ::Failure(AZStd::string()); - m_variableRequests->AddVariable(variableName, datum); + m_variableRequests->AddVariable(variableName, datum, false); ++m_variableCounter; } diff --git a/Gems/ScriptCanvasDeveloper/Code/Editor/Source/EditorAutomation/EditorAutomationActions/ScriptCanvasActions/VariableActions.cpp b/Gems/ScriptCanvasDeveloper/Code/Editor/Source/EditorAutomation/EditorAutomationActions/ScriptCanvasActions/VariableActions.cpp index 18bebecd2a..2e338e5d01 100644 --- a/Gems/ScriptCanvasDeveloper/Code/Editor/Source/EditorAutomation/EditorAutomationActions/ScriptCanvasActions/VariableActions.cpp +++ b/Gems/ScriptCanvasDeveloper/Code/Editor/Source/EditorAutomation/EditorAutomationActions/ScriptCanvasActions/VariableActions.cpp @@ -144,7 +144,7 @@ namespace ScriptCanvasDeveloper { ScriptCanvasEditor::SceneCounterRequestBus::EventResult(variableCounter, m_scriptCanvasId, &ScriptCanvasEditor::SceneCounterRequests::GetNewVariableCounter); - // Cribbed from VariableDockWidget. Shuld always be in sync with that. + // From VariableDockWidget, Should always be in sync with that. variableName = AZStd::string::format("Variable %u", variableCounter); ScriptCanvas::GraphVariableManagerRequestBus::EventResult(nameAvailable, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::IsNameAvailable, variableName); @@ -154,7 +154,7 @@ namespace ScriptCanvasDeveloper ScriptCanvas::Datum datum(m_dataType, ScriptCanvas::Datum::eOriginality::Original); AZ::Outcome outcome = AZ::Failure(AZStd::string()); - ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, datum); + ScriptCanvas::GraphVariableManagerRequestBus::EventResult(outcome, m_scriptCanvasId, &ScriptCanvas::GraphVariableManagerRequests::AddVariable, variableName, datum, false); if (outcome) { diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.h b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.h index b9ca80c6ff..dcaad30479 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.h +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.h @@ -96,7 +96,7 @@ namespace ScriptCanvasTests { using namespace ScriptCanvas; AZ::Outcome addVariableOutcome = AZ::Failure(AZStd::string()); - GraphVariableManagerRequestBus::EventResult(addVariableOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, variableName, Datum(value)); + GraphVariableManagerRequestBus::EventResult(addVariableOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, variableName, Datum(value), false); if (!addVariableOutcome) { AZ_Warning("Script Canvas Test", false, "%s", addVariableOutcome.GetError().data()); diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_Variables.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_Variables.cpp index 1c23048405..2a8be6688c 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_Variables.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_Variables.cpp @@ -104,27 +104,27 @@ TEST_F(ScriptCanvasTestFixture, CreateVariableTest) auto stringArrayDatum = Datum(StringArray()); AZ::Outcome addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized"))); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector3", vector3Datum1); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector3", vector3Datum1, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "SecondVector3", vector3Datum2); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "SecondVector3", vector3Datum2, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector4", vector4Datum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector4", vector4Datum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); @@ -169,12 +169,12 @@ TEST_F(ScriptCanvasTestFixture, AddVariableFailTest) const AZStd::string_view propertyName = "SameName"; AZ::Outcome addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized"))); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, vector3Datum1); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, vector3Datum1, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, vector3Datum2); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, vector3Datum2, false); EXPECT_FALSE(addPropertyOutcome); propertyEntity.reset(); @@ -208,35 +208,35 @@ TEST_F(ScriptCanvasTestFixture, RemoveVariableTest) size_t numVariablesAdded = 0U; AZ::Outcome addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized"))); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector3", vector3Datum1); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector3", vector3Datum1, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); const VariableId firstVector3Id = addPropertyOutcome.GetValue(); ++numVariablesAdded; addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "SecondVector3", vector3Datum2); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "SecondVector3", vector3Datum2, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); const VariableId secondVector3Id = addPropertyOutcome.GetValue(); ++numVariablesAdded; addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector4", vector4Datum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "FirstVector4", vector4Datum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); const VariableId firstVector4Id = addPropertyOutcome.GetValue(); ++numVariablesAdded; addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); const VariableId projectionMatrixId = addPropertyOutcome.GetValue(); ++numVariablesAdded; addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); const VariableId stringArrayId = addPropertyOutcome.GetValue(); @@ -294,7 +294,7 @@ TEST_F(ScriptCanvasTestFixture, RemoveVariableTest) { // Re-add removed Property addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "ProjectionMatrix", behaviorMatrix4x4Datum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); @@ -332,7 +332,7 @@ TEST_F(ScriptCanvasTestFixture, FindVariableTest) const AZStd::string_view propertyName = "StringProperty"; AZ::Outcome addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized"))); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, stringVariableDatum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, stringVariableDatum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); const VariableId stringVariableId = addPropertyOutcome.GetValue(); @@ -391,7 +391,7 @@ TEST_F(ScriptCanvasTestFixture, ModifyVariableTest) const AZStd::string_view propertyName = "StringProperty"; AZ::Outcome addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized"))); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, stringVariableDatum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, propertyName, stringVariableDatum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); const VariableId stringVariableId = addPropertyOutcome.GetValue(); @@ -449,7 +449,7 @@ TEST_F(ScriptCanvasTestFixture, SerializationTest) auto stringArrayDatum = Datum(StringArray()); AZ::Outcome addPropertyOutcome(AZ::Failure(AZStd::string("Uninitialized"))); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "My String Array", stringArrayDatum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); @@ -493,7 +493,7 @@ TEST_F(ScriptCanvasTestFixture, SerializationTest) auto identityMatrixDatum = Datum(Data::Matrix3x3Type::CreateIdentity()); addPropertyOutcome = AZ::Failure(AZStd::string("Uninitialized")); - GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "Super Matrix Bros", identityMatrixDatum); + GraphVariableManagerRequestBus::EventResult(addPropertyOutcome, scriptCanvasId, &GraphVariableManagerRequests::AddVariable, "Super Matrix Bros", identityMatrixDatum, false); EXPECT_TRUE(addPropertyOutcome); EXPECT_TRUE(addPropertyOutcome.GetValue().IsValid()); From f5791ee60a9b4f1982fdc81bae554ea1f5af99ee Mon Sep 17 00:00:00 2001 From: luissemp Date: Thu, 15 Apr 2021 10:08:07 -0700 Subject: [PATCH 03/20] Fixed compile error and added Setters to Node Palette --- .../Editor/View/Widgets/NodePalette/NodePaletteModel.cpp | 8 ++++++++ .../Code/Include/ScriptCanvas/Variable/GraphVariable.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp index bce247aee7..4154c3982e 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp @@ -578,6 +578,14 @@ namespace categoryPath.append(displayName.c_str()); } + for (auto property : behaviorClass->m_properties) + { + if (property.second->m_setter) + { + RegisterMethod(nodePaletteModel, behaviorContext, categoryPath, behaviorClass, property.first, *property.second->m_setter, behaviorClass->IsMethodOverloaded(property.first)); + } + } + for (auto methodIter : behaviorClass->m_methods) { if (!IsExplicitOverload(*methodIter.second)) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h index 4aa3729d7c..af25100fbe 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h @@ -184,7 +184,7 @@ namespace ScriptCanvas int GetSortPriority() const; static const char* s_InitialValueSourceNames[VariableFlags::InitialValueSource::COUNT]; - static const char* GraphVariable::s_ScopeNames[VariableFlags::Scope::COUNT]; + static const char* GraphVariable::s_ScopeNames[static_cast(VariableFlags::Scope::COUNT)]; private: From 80f8c0f68b3e8b511fa7fe106adc20e23c3180eb Mon Sep 17 00:00:00 2001 From: jackalbe <23512001+jackalbe@users.noreply.github.com> Date: Thu, 15 Apr 2021 13:21:24 -0500 Subject: [PATCH 04/20] behavior context class SceneGraph::NodeIndex -> "NodeIndex" --- .../Gem/PythonTests/CMakeLists.txt | 25 ++++++++++++++++--- .../SceneCore/Containers/SceneGraph.cpp | 4 +-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index ea9c365978..056c7982a6 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -117,12 +117,30 @@ endif() #endif() ## Editor Python Bindings ## +#if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) +# ly_add_pytest( +# NAME AutomatedTesting::EditorPythonBindings +# TEST_SUITE sandbox +# TEST_SERIAL +# PATH ${CMAKE_CURRENT_LIST_DIR}/EditorPythonBindings +# TIMEOUT 3600 +# RUNTIME_DEPENDENCIES +# Legacy::Editor +# Legacy::CryRenderNULL +# AZ::AssetProcessor +# AutomatedTesting.Assets +# Gem::EditorPythonBindings.Editor +# COMPONENT TestTools +# ) +#endif() + +## Python Asset Builder ## if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) ly_add_pytest( - NAME AutomatedTesting::EditorPythonBindings - TEST_SUITE sandbox + NAME AutomatedTesting::PythonAssetBuilder + TEST_SUITE periodic TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/EditorPythonBindings + PATH ${CMAKE_CURRENT_LIST_DIR}/PythonAssetBuilder TIMEOUT 3600 RUNTIME_DEPENDENCIES Legacy::Editor @@ -130,6 +148,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) AZ::AssetProcessor AutomatedTesting.Assets Gem::EditorPythonBindings.Editor + Gem::PythonAssetBuilder.Editor COMPONENT TestTools ) endif() diff --git a/Code/Tools/SceneAPI/SceneCore/Containers/SceneGraph.cpp b/Code/Tools/SceneAPI/SceneCore/Containers/SceneGraph.cpp index 934b0154c9..87c265481f 100644 --- a/Code/Tools/SceneAPI/SceneCore/Containers/SceneGraph.cpp +++ b/Code/Tools/SceneAPI/SceneCore/Containers/SceneGraph.cpp @@ -43,7 +43,7 @@ namespace AZ AZ::BehaviorContext* behaviorContext = azrtti_cast(context); if (behaviorContext) { - behaviorContext->Class() + behaviorContext->Class("NodeIndex") ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Attribute(AZ::Script::Attributes::Module, "scene.graph") ->Constructor<>() @@ -57,7 +57,7 @@ namespace AZ ->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString) ; - behaviorContext->Class() + behaviorContext->Class("SceneGraphName") ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Attribute(AZ::Script::Attributes::Module, "scene.graph") ->Constructor() From f938fde4b0f7549c4975cf5c6ebf95e77e89de8c Mon Sep 17 00:00:00 2001 From: luissemp Date: Thu, 15 Apr 2021 11:54:45 -0700 Subject: [PATCH 05/20] Compile fix --- .../Code/Include/ScriptCanvas/Variable/GraphVariable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h index af25100fbe..d305bedd08 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.h @@ -184,7 +184,7 @@ namespace ScriptCanvas int GetSortPriority() const; static const char* s_InitialValueSourceNames[VariableFlags::InitialValueSource::COUNT]; - static const char* GraphVariable::s_ScopeNames[static_cast(VariableFlags::Scope::COUNT)]; + static const char* s_ScopeNames[static_cast(VariableFlags::Scope::COUNT)]; private: From ba04c7858fd7bc9f400f779859ec9e77ff41f5ac Mon Sep 17 00:00:00 2001 From: luissemp Date: Thu, 15 Apr 2021 16:01:36 -0700 Subject: [PATCH 06/20] Fixed ability to set Array as data input into function definition node, WIP --- .../View/Widgets/VariablePanel/SlotTypeSelectorWidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/SlotTypeSelectorWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/SlotTypeSelectorWidget.cpp index 99bec928cc..d345778f71 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/SlotTypeSelectorWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/VariablePanel/SlotTypeSelectorWidget.cpp @@ -73,6 +73,8 @@ namespace ScriptCanvasEditor { ui->setupUi(this); + ui->variablePalette->SetActiveScene(scriptCanvasId); + ui->searchFilter->setClearButtonEnabled(true); QObject::connect(ui->searchFilter, &QLineEdit::textChanged, this, &SlotTypeSelectorWidget::OnQuickFilterChanged); QObject::connect(ui->slotName, &QLineEdit::returnPressed, this, &SlotTypeSelectorWidget::OnReturnPressed); From f0cf27b8d35ba6f9ec3aa3d22aaa50fcda8cc9bf Mon Sep 17 00:00:00 2001 From: jackalbe <23512001+jackalbe@users.noreply.github.com> Date: Fri, 16 Apr 2021 13:58:57 -0500 Subject: [PATCH 07/20] adding the testing files for testing for python asset building and scripting the scene_api gets a small update for mesh_group_add_advanced_coordinate_system(self, --- .../Gem/Editor/Scripts/__init__.py | 10 ++ .../Gem/Editor/Scripts/bootstrap.py | 13 ++ .../PythonAssetBuilder/AssetBuilder_test.py | 57 +++++++++ .../AssetBuilder_test_case.py | 52 ++++++++ .../PythonAssetBuilder/__init__.py | 10 ++ .../PythonAssetBuilder/bootstrap_tests.py | 17 +++ .../export_chunks_builder.py | 88 +++++++++++++ .../PythonAssetBuilder/geom_group.fbx | 3 + .../geom_group.fbx.assetinfo | 9 ++ .../PythonAssetBuilder/mock_asset_builder.py | 121 ++++++++++++++++++ .../PythonAssetBuilder/test_asset.mock | 1 + .../Editor/Scripts/scene_api/scene_data.py | 15 ++- 12 files changed, 391 insertions(+), 5 deletions(-) create mode 100644 AutomatedTesting/Gem/Editor/Scripts/__init__.py create mode 100644 AutomatedTesting/Gem/Editor/Scripts/bootstrap.py create mode 100644 AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py create mode 100644 AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py create mode 100644 AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/__init__.py create mode 100644 AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/bootstrap_tests.py create mode 100644 AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/export_chunks_builder.py create mode 100644 AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/geom_group.fbx create mode 100644 AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/geom_group.fbx.assetinfo create mode 100644 AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/mock_asset_builder.py create mode 100644 AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/test_asset.mock diff --git a/AutomatedTesting/Gem/Editor/Scripts/__init__.py b/AutomatedTesting/Gem/Editor/Scripts/__init__.py new file mode 100644 index 0000000000..79f8fa4422 --- /dev/null +++ b/AutomatedTesting/Gem/Editor/Scripts/__init__.py @@ -0,0 +1,10 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" diff --git a/AutomatedTesting/Gem/Editor/Scripts/bootstrap.py b/AutomatedTesting/Gem/Editor/Scripts/bootstrap.py new file mode 100644 index 0000000000..e41f9c1767 --- /dev/null +++ b/AutomatedTesting/Gem/Editor/Scripts/bootstrap.py @@ -0,0 +1,13 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" +import sys, os +sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../../PythonTests') +from PythonAssetBuilder import bootstrap_tests diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py new file mode 100644 index 0000000000..e914182542 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py @@ -0,0 +1,57 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" +# +# This launches the AssetProcessor and Editor then attempts to find the expected +# assets created by a Python Asset Builder and the output of a scene pipeline script +# +import sys +import os +import pytest +import logging +pytest.importorskip('ly_test_tools') + +import ly_test_tools.environment.file_system as file_system +import ly_test_tools.log.log_monitor +import ly_test_tools.environment.waiter as waiter + +@pytest.mark.SUITE_sandbox +@pytest.mark.parametrize('launcher_platform', ['windows_editor']) +@pytest.mark.parametrize('project', ['AutomatedTesting']) +@pytest.mark.parametrize('level', ['auto_test']) +class TestPythonAssetProcessing(object): + def test_DetectPythonCreatedAsset(self, request, editor, level, launcher_platform): + unexpected_lines = [] + expected_lines = [ + 'Mock asset exists', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_negative.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_positive.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found' + ] + timeout = 180 + halt_on_unexpected = False + test_directory = os.path.join(os.path.dirname(__file__)) + testFile = os.path.join(test_directory, 'AssetBuilder_test_case.py') + editor.args.extend(['-NullRenderer', "--skipWelcomeScreenDialog", "--autotest_mode", "--runpythontest", testFile]) + + with editor.start(): + editorlog_file = os.path.join(editor.workspace.paths.project_log(), 'Editor.log') + log_monitor = ly_test_tools.log.log_monitor.LogMonitor(editor, editorlog_file) + waiter.wait_for( + lambda: editor.is_alive(), + timeout, + exc=("Log file '{}' was never opened by another process.".format(editorlog_file)), + interval=1) + log_monitor.monitor_log_for_lines(expected_lines, unexpected_lines, halt_on_unexpected, timeout) diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py new file mode 100644 index 0000000000..608c2d224d --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py @@ -0,0 +1,52 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" +import azlmbr.bus +import azlmbr.asset +import azlmbr.editor +import azlmbr.math +import azlmbr.legacy.general + +def raise_and_stop(msg): + print (msg) + azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt') + +# These tests are meant to check that the test_asset.mock source asset turned into +# a test_asset.mock_asset product asset via the Python asset builder system +mockAssetType = azlmbr.math.Uuid_CreateString('{9274AD17-3212-4651-9F3B-7DCCB080E467}', 0) +mockAssetPath = 'gem/pythontests/pythonassetbuilder/test_asset.mock_asset' +assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', mockAssetPath, mockAssetType, False) +if (assetId.is_valid() is False): + raise_and_stop(f'Mock AssetId is not valid!') + +if (assetId.to_string().endswith(':54c06b89') is False): + raise_and_stop(f'Mock AssetId has unexpected sub-id for {mockAssetPath}!') + +print ('Mock asset exists') + +# These tests detect if the geom_group.fbx file turns into a number of azmodel product assets +def test_azmodel_product(generatedModelAssetPath, expectedSubId): + azModelAssetType = azlmbr.math.Uuid_CreateString('{2C7477B6-69C5-45BE-8163-BCD6A275B6D8}', 0) + assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', generatedModelAssetPath, azModelAssetType, False) + assetIdString = assetId.to_string() + if (assetIdString.endswith(':' + expectedSubId) is False): + raise_and_stop(f'Asset has unexpected asset ID ({assetIdString}) for ({generatedModelAssetPath})!') + else: + print(f'Expected subId for asset ({generatedModelAssetPath}) found') + +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel', '10412075') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_positive.azmodel', '10d16e68') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_X_negative.azmodel', '10a71973') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Y_positive.azmodel', '10130556') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Y_negative.azmodel', '1065724d') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Z_positive.azmodel', '1024be55') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_Z_negative.azmodel', '1052c94e') + +azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt') diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/__init__.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/__init__.py new file mode 100644 index 0000000000..6ed3dc4bda --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/__init__.py @@ -0,0 +1,10 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/bootstrap_tests.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/bootstrap_tests.py new file mode 100644 index 0000000000..9e7b738a4d --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/bootstrap_tests.py @@ -0,0 +1,17 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" +import os +import sys +try: + sys.path.append(os.path.dirname(os.path.abspath(__file__))) + import mock_asset_builder +except: + print ('skipping asset builder testing via mock_asset_builder') diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/export_chunks_builder.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/export_chunks_builder.py new file mode 100644 index 0000000000..ad68a486b1 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/export_chunks_builder.py @@ -0,0 +1,88 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" +import uuid, os +import azlmbr.scene as sceneApi +import azlmbr.scene.graph +from scene_api import scene_data as sceneData + +def get_mesh_node_names(sceneGraph): + meshDataList = [] + node = sceneGraph.get_root() + children = [] + + while node.IsValid(): + # store children to process after siblings + if sceneGraph.has_node_child(node): + children.append(sceneGraph.get_node_child(node)) + + # store any node that has mesh data content + nodeContent = sceneGraph.get_node_content(node) + if nodeContent is not None and nodeContent.CastWithTypeName('MeshData'): + if sceneGraph.is_node_end_point(node) is False: + meshDataList.append(sceneData.SceneGraphName(sceneGraph.get_node_name(node))) + + # advance to next node + if sceneGraph.has_node_sibling(node): + node = sceneGraph.get_node_sibling(node) + elif children: + node = children.pop() + else: + node = azlmbr.scene.graph.NodeIndex() + + return meshDataList + +def update_manifest(scene): + graph = sceneData.SceneGraph(scene.graph) + meshNameList = get_mesh_node_names(graph) + sceneManifest = sceneData.SceneManifest() + sourceFilenameOnly = os.path.basename(scene.sourceFilename) + sourceFilenameOnly = sourceFilenameOnly.replace('.','_') + + for activeMeshIndex in range(len(meshNameList)): + chunkName = meshNameList[activeMeshIndex] + chunkPath = chunkName.get_path() + meshGroupName = '{}_{}'.format(sourceFilenameOnly, chunkName.get_name()) + meshGroup = sceneManifest.add_mesh_group(meshGroupName) + meshGroup['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, sourceFilenameOnly + chunkPath)) + '}' + sceneManifest.mesh_group_add_comment(meshGroup, 'auto generated by scene manifest') + sceneManifest.mesh_group_add_advanced_coordinate_system(meshGroup, None, None, None, 1.0) + + # create selection node list + pathSet = set() + for meshIndex in range(len(meshNameList)): + targetPath = meshNameList[meshIndex].get_path() + if (activeMeshIndex == meshIndex): + sceneManifest.mesh_group_select_node(meshGroup, targetPath) + else: + if targetPath not in pathSet: + pathSet.update(targetPath) + sceneManifest.mesh_group_unselect_node(meshGroup, targetPath) + + return sceneManifest.export() + +mySceneJobHandler = None + +def on_update_manifest(args): + scene = args[0] + result = update_manifest(scene) + global mySceneJobHandler + mySceneJobHandler.disconnect() + mySceneJobHandler = None + return result + +def main(): + global mySceneJobHandler + mySceneJobHandler = sceneApi.ScriptBuildingNotificationBusHandler() + mySceneJobHandler.connect() + mySceneJobHandler.add_callback('OnUpdateManifest', on_update_manifest) + +if __name__ == "__main__": + main() diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/geom_group.fbx b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/geom_group.fbx new file mode 100644 index 0000000000..8945a5505a --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/geom_group.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66d38948309ef273adf74b63eaa38f8fc2e2bdfbab3933d2ee082ce6a8cb108e +size 30496 diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/geom_group.fbx.assetinfo b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/geom_group.fbx.assetinfo new file mode 100644 index 0000000000..707c6f3705 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/geom_group.fbx.assetinfo @@ -0,0 +1,9 @@ +{ + "values": + [ + { + "$type": "ScriptProcessorRule", + "scriptFilename": "Gem/PythonTests/PythonAssetBuilder/export_chunks_builder.py" + } + ] +} diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/mock_asset_builder.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/mock_asset_builder.py new file mode 100644 index 0000000000..00a656abd0 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/mock_asset_builder.py @@ -0,0 +1,121 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" +import azlmbr.asset +import azlmbr.asset.builder +import azlmbr.bus +import azlmbr.math +import os, traceback, binascii, sys + +jobKeyName = 'Mock Asset' + +def log_exception_traceback(): + exc_type, exc_value, exc_tb = sys.exc_info() + data = traceback.format_exception(exc_type, exc_value, exc_tb) + print(str(data)) + +# creates a single job to compile for each platform +def create_jobs(request): + # create job descriptor for each platform + jobDescriptorList = [] + for platformInfo in request.enabledPlatforms: + jobDesc = azlmbr.asset.builder.JobDescriptor() + jobDesc.jobKey = jobKeyName + jobDesc.set_platform_identifier(platformInfo.identifier) + jobDescriptorList.append(jobDesc) + + response = azlmbr.asset.builder.CreateJobsResponse() + response.result = azlmbr.asset.builder.CreateJobsResponse_ResultSuccess + response.createJobOutputs = jobDescriptorList + return response + +def on_create_jobs(args): + try: + request = args[0] + return create_jobs(request) + except: + log_exception_traceback() + # returing back a default CreateJobsResponse() records an asset error + return azlmbr.asset.builder.CreateJobsResponse() + +def process_file(request): + # prepare output folder + basePath, _ = os.path.split(request.sourceFile) + outputPath = os.path.join(request.tempDirPath, basePath) + os.makedirs(outputPath, exist_ok=True) + + # write out a mock file + basePath, sourceFile = os.path.split(request.sourceFile) + mockFilename = os.path.splitext(sourceFile)[0] + '.mock_asset' + mockFilename = os.path.join(basePath, mockFilename) + mockFilename = mockFilename.replace('\\', '/').lower() + tempFilename = os.path.join(request.tempDirPath, mockFilename) + + # write out a tempFilename like a JSON or something? + fileOutput = open(tempFilename, "w") + fileOutput.write('{}') + fileOutput.close() + + # generate a product asset file entry + subId = binascii.crc32(mockFilename.encode()) + mockAssetType = azlmbr.math.Uuid_CreateString('{9274AD17-3212-4651-9F3B-7DCCB080E467}', 0) + product = azlmbr.asset.builder.JobProduct(mockFilename, mockAssetType, subId) + product.dependenciesHandled = True + productOutputs = [] + productOutputs.append(product) + + # fill out response object + response = azlmbr.asset.builder.ProcessJobResponse() + response.outputProducts = productOutputs + response.resultCode = azlmbr.asset.builder.ProcessJobResponse_Success + response.dependenciesHandled = True + return response + +# using the incoming 'request' find the type of job via 'jobKey' to determine what to do +def on_process_job(args): + try: + request = args[0] + if (request.jobDescription.jobKey.startswith(jobKeyName)): + return process_file(request) + except: + log_exception_traceback() + # returning back an empty ProcessJobResponse() will record an error + return azlmbr.asset.builder.ProcessJobResponse() + +# register asset builder +def register_asset_builder(busId): + assetPattern = azlmbr.asset.builder.AssetBuilderPattern() + assetPattern.pattern = '*.mock' + assetPattern.type = azlmbr.asset.builder.AssetBuilderPattern_Wildcard + + builderDescriptor = azlmbr.asset.builder.AssetBuilderDesc() + builderDescriptor.name = "Mock Builder" + builderDescriptor.patterns = [assetPattern] + builderDescriptor.busId = busId + builderDescriptor.version = 1 + + outcome = azlmbr.asset.builder.PythonAssetBuilderRequestBus(azlmbr.bus.Broadcast, 'RegisterAssetBuilder', builderDescriptor) + if outcome.IsSuccess(): + # created the asset builder to hook into the notification bus + handler = azlmbr.asset.builder.PythonBuilderNotificationBusHandler() + handler.connect(busId) + handler.add_callback('OnCreateJobsRequest', on_create_jobs) + handler.add_callback('OnProcessJobRequest', on_process_job) + return handler + +# create the asset builder handler +busIdString = '{CF5C74C1-9ED4-5851-95B1-0B15090DBEC7}' +busId = azlmbr.math.Uuid_CreateString(busIdString, 0) +handler = None +try: + handler = register_asset_builder(busId) +except: + handler = None + log_exception_traceback() diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/test_asset.mock b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/test_asset.mock new file mode 100644 index 0000000000..6d6a52e643 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/test_asset.mock @@ -0,0 +1 @@ +mock data \ No newline at end of file diff --git a/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py b/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py index 7db3daa276..4583262b25 100755 --- a/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py +++ b/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py @@ -114,12 +114,17 @@ class SceneManifest(): def mesh_group_unselect_node(self, meshGroup, nodeName): meshGroup['nodeSelectionList']['unselectedNodes'].append(nodeName) - def mesh_group_set_origin(self, meshGroup, originNodeName, x, y, z, scale): + def mesh_group_add_advanced_coordinate_system(self, meshGroup, originNodeName, translation, rotation, scale): originRule = {} - originRule['$type'] = 'OriginRule' - originRule['originNodeName'] = 'World' if originNodeName is None else originNodeName - originRule['translation'] = [x, y, z] - originRule['scale'] = scale + originRule['$type'] = 'CoordinateSystemRule' + originRule['useAdvancedData'] = True + originRule['originNodeName'] = '' if originNodeName is None else originNodeName + if translation is not None: + originRule['translation'] = translation + if rotation is not None: + originRule['rotation'] = rotation + if scale != 1.0: + originRule['scale'] = scale meshGroup['rules']['rules'].append(originRule) def mesh_group_add_comment(self, meshGroup, comment): From 3299730899789aa4de285635bf922c0cc62992be Mon Sep 17 00:00:00 2001 From: jackalbe <23512001+jackalbe@users.noreply.github.com> Date: Fri, 16 Apr 2021 14:23:01 -0500 Subject: [PATCH 08/20] re-adding EPB tests --- .../Gem/PythonTests/CMakeLists.txt | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 056c7982a6..a8ea3f9837 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -117,22 +117,22 @@ endif() #endif() ## Editor Python Bindings ## -#if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) -# ly_add_pytest( -# NAME AutomatedTesting::EditorPythonBindings -# TEST_SUITE sandbox -# TEST_SERIAL -# PATH ${CMAKE_CURRENT_LIST_DIR}/EditorPythonBindings -# TIMEOUT 3600 -# RUNTIME_DEPENDENCIES -# Legacy::Editor -# Legacy::CryRenderNULL -# AZ::AssetProcessor -# AutomatedTesting.Assets -# Gem::EditorPythonBindings.Editor -# COMPONENT TestTools -# ) -#endif() +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::EditorPythonBindings + TEST_SUITE sandbox + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/EditorPythonBindings + TIMEOUT 3600 + RUNTIME_DEPENDENCIES + Legacy::Editor + Legacy::CryRenderNULL + AZ::AssetProcessor + AutomatedTesting.Assets + Gem::EditorPythonBindings.Editor + COMPONENT TestTools + ) +endif() ## Python Asset Builder ## if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) From 3d91b19c194c5736606a10d02846b4e2e5c74f8f Mon Sep 17 00:00:00 2001 From: jackalbe <23512001+jackalbe@users.noreply.github.com> Date: Fri, 16 Apr 2021 15:41:03 -0500 Subject: [PATCH 09/20] printing wrong asset ID in message cleaned up comment --- .../PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py | 2 +- .../Gem/PythonTests/PythonAssetBuilder/mock_asset_builder.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py index 608c2d224d..54857c2067 100644 --- a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py @@ -24,7 +24,7 @@ mockAssetType = azlmbr.math.Uuid_CreateString('{9274AD17-3212-4651-9F3B-7DCCB080 mockAssetPath = 'gem/pythontests/pythonassetbuilder/test_asset.mock_asset' assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', mockAssetPath, mockAssetType, False) if (assetId.is_valid() is False): - raise_and_stop(f'Mock AssetId is not valid!') + raise_and_stop(f'Mock AssetId is not valid! Got {assetId.to_string()} instead') if (assetId.to_string().endswith(':54c06b89') is False): raise_and_stop(f'Mock AssetId has unexpected sub-id for {mockAssetPath}!') diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/mock_asset_builder.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/mock_asset_builder.py index 00a656abd0..c60871ac46 100644 --- a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/mock_asset_builder.py +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/mock_asset_builder.py @@ -58,7 +58,7 @@ def process_file(request): mockFilename = mockFilename.replace('\\', '/').lower() tempFilename = os.path.join(request.tempDirPath, mockFilename) - # write out a tempFilename like a JSON or something? + # write out a tempFilename like a JSON fileOutput = open(tempFilename, "w") fileOutput.write('{}') fileOutput.close() From b3cc14dd5cfddb945584c6274c88614b7baade10 Mon Sep 17 00:00:00 2001 From: mnaumov Date: Fri, 16 Apr 2021 18:59:21 -0700 Subject: [PATCH 10/20] disabling source control thumbnails in material editor --- .../MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp index bd7e1d94ab..6272312b90 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp @@ -73,7 +73,7 @@ namespace MaterialEditor m_filterModel->SetFilter(CreateFilter()); m_ui->m_assetBrowserTreeViewWidget->setModel(m_filterModel); - m_ui->m_assetBrowserTreeViewWidget->SetShowSourceControlIcons(true); + m_ui->m_assetBrowserTreeViewWidget->SetShowSourceControlIcons(false); m_ui->m_assetBrowserTreeViewWidget->setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection); // Maintains the tree expansion state between runs From d614b357e5cc1fe20398eb4a0244c3120be1e10f Mon Sep 17 00:00:00 2001 From: guthadam Date: Fri, 16 Apr 2021 22:11:01 -0500 Subject: [PATCH 11/20] ATOM-5921 Material Editor: Select newly created materials in the asset browser The code was previously using asset browser notifications to listen for new files being added in order to select newly created materials. Attempting to change the selection within the notification failed because the new entry still had not been added. Now the material browser queues and processes the selection on tick. https://jira.agscollab.com/browse/ATOM-5921 --- .../Source/Window/MaterialBrowserWidget.cpp | 126 ++++++++---------- .../Source/Window/MaterialBrowserWidget.h | 26 ++-- 2 files changed, 69 insertions(+), 83 deletions(-) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp index bd7e1d94ab..408ee1a478 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.cpp @@ -10,36 +10,32 @@ * */ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include - #include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT -#include -#include -#include -#include #include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include AZ_POP_DISABLE_WARNING namespace MaterialEditor @@ -99,7 +95,6 @@ namespace MaterialEditor } }); - AssetBrowserModelNotificationBus::Handler::BusConnect(); MaterialDocumentNotificationBus::Handler::BusConnect(); } @@ -108,7 +103,7 @@ namespace MaterialEditor // Maintains the tree expansion state between runs m_ui->m_assetBrowserTreeViewWidget->SaveState(); MaterialDocumentNotificationBus::Handler::BusDisconnect(); - AssetBrowserModelNotificationBus::Handler::BusDisconnect(); + AZ::TickBus::Handler::BusDisconnect(); } AzToolsFramework::AssetBrowser::FilterConstType MaterialBrowserWidget::CreateFilter() const @@ -151,72 +146,65 @@ namespace MaterialEditor for (const AssetBrowserEntry* entry : entries) { - const SourceAssetBrowserEntry* sourceEntry = azrtti_cast(entry); - if (!sourceEntry) + if (entry) { - const ProductAssetBrowserEntry* productEntry = azrtti_cast(entry); - if (productEntry) + if (AzFramework::StringFunc::Path::IsExtension(entry->GetFullPath().c_str(), MaterialExtension)) { - sourceEntry = azrtti_cast(productEntry->GetParent()); + MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::OpenDocument, entry->GetFullPath()); } - } - - if (sourceEntry) - { - if (AzFramework::StringFunc::Path::IsExtension(sourceEntry->GetFullPath().c_str(), MaterialExtension)) - { - MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::OpenDocument, sourceEntry->GetFullPath()); - } - else if (AzFramework::StringFunc::Path::IsExtension(sourceEntry->GetFullPath().c_str(), MaterialTypeExtension)) + else if (AzFramework::StringFunc::Path::IsExtension(entry->GetFullPath().c_str(), MaterialTypeExtension)) { //ignore MaterialTypeExtension } else { - QDesktopServices::openUrl(QUrl::fromLocalFile(sourceEntry->GetFullPath().c_str())); + QDesktopServices::openUrl(QUrl::fromLocalFile(entry->GetFullPath().c_str())); } } } } - void MaterialBrowserWidget::EntryAdded(const AssetBrowserEntry* entry) - { - if (m_pathToSelect.empty()) - { - return; - } - - const SourceAssetBrowserEntry* sourceEntry = azrtti_cast(entry); - if (!sourceEntry) - { - const ProductAssetBrowserEntry* productEntry = azrtti_cast(entry); - if (productEntry) - { - sourceEntry = azrtti_cast(productEntry->GetParent()); - } - } - - if (sourceEntry) - { - AZStd::string sourcePath = sourceEntry->GetFullPath(); - AzFramework::StringFunc::Path::Normalize(sourcePath); - if (m_pathToSelect == sourcePath) - { - m_ui->m_assetBrowserTreeViewWidget->SelectFileAtPath(m_pathToSelect); - m_pathToSelect.clear(); - } - } - } - void MaterialBrowserWidget::OnDocumentOpened(const AZ::Uuid& documentId) { AZStd::string absolutePath; MaterialDocumentRequestBus::EventResult(absolutePath, documentId, &MaterialDocumentRequestBus::Events::GetAbsolutePath); if (!absolutePath.empty()) { + // Selecting a new asset in the browser is not guaranteed to happen immediately. + // The asset browser model notifications are sent before the model is updated. + // Instead of relying on the notifications, queue the selection and process it on tick until this change occurs. m_pathToSelect = absolutePath; AzFramework::StringFunc::Path::Normalize(m_pathToSelect); - m_ui->m_assetBrowserTreeViewWidget->SelectFileAtPath(m_pathToSelect); + AZ::TickBus::Handler::BusConnect(); + } + } + + void MaterialBrowserWidget::OnTick(float deltaTime, AZ::ScriptTimePoint time) + { + AZ_UNUSED(time); + AZ_UNUSED(deltaTime); + + if (!m_pathToSelect.empty()) + { + // Attempt to select the new path + AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Broadcast( + &AzToolsFramework::AssetBrowser::AssetBrowserViewRequestBus::Events::SelectFileAtPath, m_pathToSelect); + + // Iterate over the selected entries to verify if the selection was made + for (const AssetBrowserEntry* entry : m_ui->m_assetBrowserTreeViewWidget->GetSelectedAssets()) + { + if (entry) + { + AZStd::string sourcePath = entry->GetFullPath(); + AzFramework::StringFunc::Path::Normalize(sourcePath); + if (m_pathToSelect == sourcePath) + { + // Once the selection is confirmed, cancel the operation and disconnect + AZ::TickBus::Handler::BusDisconnect(); + m_pathToSelect.clear(); + } + } + } } } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.h index d33f568ba3..38ff894214 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Window/MaterialBrowserWidget.h @@ -13,11 +13,11 @@ #pragma once #if !defined(Q_MOC_RUN) +#include +#include #include -#include #include #include -#include AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include @@ -26,8 +26,6 @@ AZ_POP_DISABLE_WARNING #endif - - namespace AzToolsFramework { namespace AssetBrowser @@ -50,8 +48,8 @@ namespace MaterialEditor //! Provides a tree view of all available materials and other assets exposed by the MaterialEditor. class MaterialBrowserWidget : public QWidget - , public AzToolsFramework::AssetBrowser::AssetBrowserModelNotificationBus::Handler - , public MaterialDocumentNotificationBus::Handler + , protected AZ::TickBus::Handler + , protected MaterialDocumentNotificationBus::Handler { Q_OBJECT public: @@ -62,20 +60,20 @@ namespace MaterialEditor AzToolsFramework::AssetBrowser::FilterConstType CreateFilter() const; void OpenSelectedEntries(); + // MaterialDocumentNotificationBus::Handler implementation + void OnDocumentOpened(const AZ::Uuid& documentId) override; + + // AZ::TickBus::Handler + void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; + + void OpenOptionsMenu(); + QScopedPointer m_ui; AzToolsFramework::AssetBrowser::AssetBrowserFilterModel* m_filterModel = nullptr; //! if new asset is being created with this path it will automatically be selected AZStd::string m_pathToSelect; - // AssetBrowserModelNotificationBus::Handler implementation - void EntryAdded(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry) override; - - // MaterialDocumentNotificationBus::Handler implementation - void OnDocumentOpened(const AZ::Uuid& documentId) override; - - void OpenOptionsMenu(); - QByteArray m_materialBrowserState; }; } // namespace MaterialEditor From 8fead27c45395924ff5dfc3775810bbaa078058e Mon Sep 17 00:00:00 2001 From: guthadam Date: Sun, 18 Apr 2021 12:12:32 -0500 Subject: [PATCH 12/20] ATOM-13950 Material Editor: Removing auto select option from lighting and model presets Remove option from presets Updated code to select current default options Will data drive default options with editor settings or settings registry in upcoming tasks https://jira.agscollab.com/browse/ATOM-13950 --- .../greenwich_park_02.lightingconfig.json | 2 -- .../Include/Atom/Feature/Utils/LightingPreset.h | 1 - .../Code/Include/Atom/Feature/Utils/ModelPreset.h | 1 - .../Code/Source/Utils/EditorLightingPreset.cpp | 1 - .../Common/Code/Source/Utils/EditorModelPreset.cpp | 1 - .../Common/Code/Source/Utils/LightingPreset.cpp | 4 +--- .../Common/Code/Source/Utils/ModelPreset.cpp | 4 +--- .../urban_street_02.lightingpreset.azasset | 1 - .../_TEMPLATE_.lightingconfig.json.template | 2 -- .../neutral_urban.lightingpreset.azasset | 1 - .../ViewportModels/Shaderball.modelpreset.azasset | 1 - .../Source/Viewport/MaterialViewportComponent.cpp | 13 ++++++++++--- .../EnvHDRi/photo_studio_01.lightingconfig.json | 2 -- 13 files changed, 12 insertions(+), 22 deletions(-) diff --git a/AutomatedTesting/LightingPresets/greenwich_park_02.lightingconfig.json b/AutomatedTesting/LightingPresets/greenwich_park_02.lightingconfig.json index 1646dd18a2..bfb92bbb6f 100644 --- a/AutomatedTesting/LightingPresets/greenwich_park_02.lightingconfig.json +++ b/AutomatedTesting/LightingPresets/greenwich_park_02.lightingconfig.json @@ -1,7 +1,6 @@ { "configurations": [ { - "autoSelect": false, "displayName": "Greenwich Park 02", "skyboxImageAsset": { "assetId": { @@ -64,7 +63,6 @@ "shadowCatcherOpacity": 0.20000000298023225 }, { - "autoSelect": false, "displayName": "Greenwich Park 02 (Alt)", "skyboxImageAsset": { "assetId": { diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/LightingPreset.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/LightingPreset.h index 1c220e0d8d..f1d8337a35 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/LightingPreset.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/LightingPreset.h @@ -78,7 +78,6 @@ namespace AZ AZ_CLASS_ALLOCATOR(LightingPreset, AZ::SystemAllocator, 0); static void Reflect(AZ::ReflectContext* context); - bool m_autoSelect = false; AZStd::string m_displayName; AZ::Data::Asset m_iblDiffuseImageAsset; AZ::Data::Asset m_iblSpecularImageAsset; diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/ModelPreset.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/ModelPreset.h index 896d6fb78f..9ca8c13859 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/ModelPreset.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Utils/ModelPreset.h @@ -32,7 +32,6 @@ namespace AZ AZ_CLASS_ALLOCATOR(ModelPreset, AZ::SystemAllocator, 0); static void Reflect(AZ::ReflectContext* context); - bool m_autoSelect = false; AZStd::string m_displayName; AZ::Data::Asset m_modelAsset; AZ::Data::Asset m_previewImageAsset; diff --git a/Gems/Atom/Feature/Common/Code/Source/Utils/EditorLightingPreset.cpp b/Gems/Atom/Feature/Common/Code/Source/Utils/EditorLightingPreset.cpp index e7f9c8b09f..1da9463bd8 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Utils/EditorLightingPreset.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Utils/EditorLightingPreset.cpp @@ -112,7 +112,6 @@ namespace AZ ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_displayName, "Display Name", "Identifier used for display and selection") - ->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_autoSelect, "Auto Select", "When true, the configuration is automatically selected when loaded") ->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_iblDiffuseImageAsset, "IBL Diffuse Image Asset", "IBL diffuse image asset reference") ->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_iblSpecularImageAsset, "IBL Specular Image Asset", "IBL specular image asset reference") ->DataElement(AZ::Edit::UIHandlers::Default, &LightingPreset::m_skyboxImageAsset, "Skybox Image Asset", "Skybox image asset reference") diff --git a/Gems/Atom/Feature/Common/Code/Source/Utils/EditorModelPreset.cpp b/Gems/Atom/Feature/Common/Code/Source/Utils/EditorModelPreset.cpp index b8b0b610f3..bed320c45d 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Utils/EditorModelPreset.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Utils/EditorModelPreset.cpp @@ -32,7 +32,6 @@ namespace AZ ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_displayName, "Display Name", "Identifier used for display and selection") - ->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_autoSelect, "Auto Select", "When true, the configuration is automatically selected when loaded") ->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_modelAsset, "Model Asset", "Model asset reference") ->DataElement(AZ::Edit::UIHandlers::Default, &ModelPreset::m_previewImageAsset, "Preview Image Asset", "Preview image asset reference") ; diff --git a/Gems/Atom/Feature/Common/Code/Source/Utils/LightingPreset.cpp b/Gems/Atom/Feature/Common/Code/Source/Utils/LightingPreset.cpp index 837a725a9f..77924b87a3 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Utils/LightingPreset.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Utils/LightingPreset.cpp @@ -105,8 +105,7 @@ namespace AZ serializeContext->RegisterGenericType>(); serializeContext->Class() - ->Version(4) - ->Field("autoSelect", &LightingPreset::m_autoSelect) + ->Version(5) ->Field("displayName", &LightingPreset::m_displayName) ->Field("iblDiffuseImageAsset", &LightingPreset::m_iblDiffuseImageAsset) ->Field("iblSpecularImageAsset", &LightingPreset::m_iblSpecularImageAsset) @@ -128,7 +127,6 @@ namespace AZ ->Attribute(AZ::Script::Attributes::Module, "render") ->Constructor() ->Constructor() - ->Property("autoSelect", BehaviorValueProperty(&LightingPreset::m_autoSelect)) ->Property("displayName", BehaviorValueProperty(&LightingPreset::m_displayName)) ->Property("alternateSkyboxImageAsset", BehaviorValueProperty(&LightingPreset::m_alternateSkyboxImageAsset)) ->Property("skyboxImageAsset", BehaviorValueProperty(&LightingPreset::m_skyboxImageAsset)) diff --git a/Gems/Atom/Feature/Common/Code/Source/Utils/ModelPreset.cpp b/Gems/Atom/Feature/Common/Code/Source/Utils/ModelPreset.cpp index e93bfa527a..2795617c18 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Utils/ModelPreset.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Utils/ModelPreset.cpp @@ -25,8 +25,7 @@ namespace AZ if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(2) - ->Field("autoSelect", &ModelPreset::m_autoSelect) + ->Version(3) ->Field("displayName", &ModelPreset::m_displayName) ->Field("modelAsset", &ModelPreset::m_modelAsset) ->Field("previewImageAsset", &ModelPreset::m_previewImageAsset) @@ -41,7 +40,6 @@ namespace AZ ->Attribute(AZ::Script::Attributes::Module, "render") ->Constructor() ->Constructor() - ->Property("autoSelect", BehaviorValueProperty(&ModelPreset::m_autoSelect)) ->Property("displayName", BehaviorValueProperty(&ModelPreset::m_displayName)) ->Property("modelAsset", BehaviorValueProperty(&ModelPreset::m_modelAsset)) ->Property("previewImageAsset", BehaviorValueProperty(&ModelPreset::m_previewImageAsset)) diff --git a/Gems/Atom/TestData/TestData/LightingPresets/urban_street_02.lightingpreset.azasset b/Gems/Atom/TestData/TestData/LightingPresets/urban_street_02.lightingpreset.azasset index d0a290649b..a676d5fba6 100644 --- a/Gems/Atom/TestData/TestData/LightingPresets/urban_street_02.lightingpreset.azasset +++ b/Gems/Atom/TestData/TestData/LightingPresets/urban_street_02.lightingpreset.azasset @@ -3,7 +3,6 @@ "Version": 1, "ClassName": "AZ::Render::LightingPreset", "ClassData": { - "autoSelect": false, "displayName": "Urban Street 02", "skyboxImageAsset": { "assetId": { diff --git a/Gems/Atom/Tools/MaterialEditor/Assets/MaterialEditor/LightingPresets/_TEMPLATE_.lightingconfig.json.template b/Gems/Atom/Tools/MaterialEditor/Assets/MaterialEditor/LightingPresets/_TEMPLATE_.lightingconfig.json.template index 7cfa7edbc3..6d87c5eb7b 100644 --- a/Gems/Atom/Tools/MaterialEditor/Assets/MaterialEditor/LightingPresets/_TEMPLATE_.lightingconfig.json.template +++ b/Gems/Atom/Tools/MaterialEditor/Assets/MaterialEditor/LightingPresets/_TEMPLATE_.lightingconfig.json.template @@ -2,7 +2,6 @@ "configurations": [ { "displayName": "Substance: