From a5a42e3268dd3888327630615cf4c8f3cf82e3d8 Mon Sep 17 00:00:00 2001
From: carlitosan <82187351+carlitosan@users.noreply.github.com>
Date: Tue, 30 Nov 2021 14:05:31 -0800
Subject: [PATCH 01/12] Add dialog window for messaging when SC assets fail to
save
Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com>
---
.../Code/Editor/View/Windows/MainWindow.cpp | 60 ++++++++++++++++++-
.../Code/Editor/View/Windows/MainWindow.h | 10 +++-
2 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
index e61b015aae..778ad9d5b7 100644
--- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
@@ -914,6 +914,12 @@ namespace ScriptCanvasEditor
void MainWindow::closeEvent(QCloseEvent* event)
{
+ if (m_forceCloseInProgress)
+ {
+ event->accept();
+ return;
+ }
+
// If we are in the middle of saving a graph. We don't want to close ourselves down and potentially retrigger the saving logic.
if (m_queueCloseRequest)
{
@@ -1981,6 +1987,7 @@ namespace ScriptCanvasEditor
EnableAssetView(memoryAsset);
+ ClearSaveAttempt();
UnblockCloseRequests();
}
@@ -1992,6 +1999,7 @@ namespace ScriptCanvasEditor
void MainWindow::SaveAsset(AZ::Data::AssetId assetId, const Callbacks::OnSave& onSave)
{
+ MarkSaveAttempt();
PrepareAssetForSave(assetId);
auto onSaveCallback = [this, onSave](bool saveSuccess, AZ::Data::AssetPtr asset, AZ::Data::AssetId previousAssetId)
@@ -2020,6 +2028,7 @@ namespace ScriptCanvasEditor
void MainWindow::SaveNewAsset(AZStd::string_view path, AZ::Data::AssetId inMemoryAssetId, const Callbacks::OnSave& onSave)
{
+ MarkSaveAttempt();
PrepareAssetForSave(inMemoryAssetId);
auto onSaveCallback = [this, onSave](bool saveSuccess, AZ::Data::AssetPtr asset, AZ::Data::AssetId previousAssetId)
@@ -4213,6 +4222,11 @@ namespace ScriptCanvasEditor
void MainWindow::OnSystemTick()
{
+ if (m_saveAttemptInProgress)
+ {
+ EvaluateSaveAttempt();
+ }
+
if (HasSystemTickAction(SystemTickActionFlag::RefreshPropertyGrid))
{
RemoveSystemTickAction(SystemTickActionFlag::RefreshPropertyGrid);
@@ -4246,13 +4260,56 @@ namespace ScriptCanvasEditor
RemoveSystemTickAction(SystemTickActionFlag::CloseNextTabAction);
CloseNextTab();
}
+ }
- if (m_systemTickActions == 0)
+ void MainWindow::ClearSaveAttempt()
+ {
+ m_saveAttemptInProgress = false;
+
+ if (!m_systemTickActions)
{
AZ::SystemTickBus::Handler::BusDisconnect();
}
}
+ bool MainWindow::EvaluateSaveAttempt()
+ {
+ const AZ::s64 k_saveAttemptSeconds = 20;
+
+ if (m_saveAttemptInProgress)
+ {
+ auto saveDuration = AZStd::chrono::seconds(AZStd::chrono::system_clock::now() - m_saveAttemptTime).count();
+
+ if (saveDuration > k_saveAttemptSeconds)
+ {
+ WarnOnFailedSaveAttempt();
+ }
+ }
+
+ return m_forceCloseInProgress;
+ }
+
+ void MainWindow::MarkSaveAttempt()
+ {
+ m_saveAttemptInProgress = true;
+ m_saveAttemptTime = AZStd::chrono::system_clock::now();
+
+ if (!AZ::SystemTickBus::Handler::BusIsConnected())
+ {
+ AZ::SystemTickBus::Handler::BusConnect();
+ }
+ }
+
+ void MainWindow::WarnOnFailedSaveAttempt()
+ {
+ m_forceCloseInProgress = true;
+ QMessageBox::critical(this, QString(), QObject::tr
+ ("The ScriptCanvas Editor has encountered an external bug which prevents it from tracking the file state.
"
+ "Likely the Asset Processor has crashed. ScriptCanvas files may have saved successfully, but the O3DE Engine and Asset Processor should be restarted before continuing work."));
+ AZ::SystemTickBus::Handler::BusDisconnect();
+ qobject_cast(parent())->close();
+ }
+
void MainWindow::OnCommandStarted(AZ::Crc32)
{
PushPreventUndoStateUpdate();
@@ -4486,7 +4543,6 @@ namespace ScriptCanvasEditor
{
AZ::SystemTickBus::Handler::BusConnect();
}
-
m_systemTickActions |= action;
}
diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h
index 7672f0a199..d73da41219 100644
--- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h
+++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h
@@ -51,7 +51,7 @@
#include
#include
-
+//#include
#include
#if SCRIPTCANVAS_EDITOR
@@ -798,5 +798,13 @@ namespace ScriptCanvasEditor
Workspace* m_workspace;
void OnSaveCallback(bool saveSuccess, AZ::Data::AssetPtr, AZ::Data::AssetId previousFileAssetId);
+
+ bool m_saveAttemptInProgress = false;
+ bool m_forceCloseInProgress = false;
+ AZStd::chrono::system_clock::time_point m_saveAttemptTime;
+ void ClearSaveAttempt();
+ bool EvaluateSaveAttempt();
+ void MarkSaveAttempt();
+ void WarnOnFailedSaveAttempt();
};
}
From 850d36130efb5571a63c14255554927333af971b Mon Sep 17 00:00:00 2001
From: carlitosan <82187351+carlitosan@users.noreply.github.com>
Date: Tue, 30 Nov 2021 15:02:06 -0800
Subject: [PATCH 02/12] update error window message and add AP launch request
Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com>
---
.../Code/Editor/View/Windows/MainWindow.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
index 778ad9d5b7..ee36fc4212 100644
--- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
@@ -154,6 +154,7 @@
#include
#include
+#include
namespace ScriptCanvasEditor
{
@@ -4305,9 +4306,14 @@ namespace ScriptCanvasEditor
m_forceCloseInProgress = true;
QMessageBox::critical(this, QString(), QObject::tr
("The ScriptCanvas Editor has encountered an external bug which prevents it from tracking the file state.
"
- "Likely the Asset Processor has crashed. ScriptCanvas files may have saved successfully, but the O3DE Engine and Asset Processor should be restarted before continuing work."));
+ "The ScriptCanvas files in the process of being saved may have saved successfully.
Closing this window will close "
+ "the ScriptCanvas Editor, and request a launch of the Asset Processor.
"
+ "Verify that the Asset Processor or is running before launching the ScriptCanvas Editor again.
"
+ "The status of the Asset Processor can be monitored from the O3DE Editor in the bottom-right corner of the status bar."));
+
+ AzFramework::AssetSystem::LaunchAssetProcessor();
AZ::SystemTickBus::Handler::BusDisconnect();
- qobject_cast(parent())->close();
+ AzToolsFramework::CloseViewPane(LyViewPane::ScriptCanvas);
}
void MainWindow::OnCommandStarted(AZ::Crc32)
From 9e725da597c5a1681d1da73f7d10d2455bed8c7c Mon Sep 17 00:00:00 2001
From: carlitosan <82187351+carlitosan@users.noreply.github.com>
Date: Tue, 30 Nov 2021 15:30:42 -0800
Subject: [PATCH 03/12] removed commented out include
Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com>
---
Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h
index d73da41219..8d84ece968 100644
--- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h
+++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h
@@ -51,7 +51,6 @@
#include
#include
-//#include
#include
#if SCRIPTCANVAS_EDITOR
From a359244c51f85d6d8894b3874cd15c08838388bd Mon Sep 17 00:00:00 2001
From: carlitosan <82187351+carlitosan@users.noreply.github.com>
Date: Tue, 30 Nov 2021 17:18:27 -0800
Subject: [PATCH 04/12] add pane close to system tick bus
Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com>
---
.../ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
index ee36fc4212..4a20c6bc0d 100644
--- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
@@ -4275,13 +4275,13 @@ namespace ScriptCanvasEditor
bool MainWindow::EvaluateSaveAttempt()
{
- const AZ::s64 k_saveAttemptSeconds = 20;
+ const AZ::s64 SaveAttemptSeconds = 20;
if (m_saveAttemptInProgress)
{
auto saveDuration = AZStd::chrono::seconds(AZStd::chrono::system_clock::now() - m_saveAttemptTime).count();
- if (saveDuration > k_saveAttemptSeconds)
+ if (saveDuration > SaveAttemptSeconds)
{
WarnOnFailedSaveAttempt();
}
@@ -4313,7 +4313,10 @@ namespace ScriptCanvasEditor
AzFramework::AssetSystem::LaunchAssetProcessor();
AZ::SystemTickBus::Handler::BusDisconnect();
- AzToolsFramework::CloseViewPane(LyViewPane::ScriptCanvas);
+ AZ::SystemTickBus::QueueFunction([]()
+ {
+ AzToolsFramework::CloseViewPane(LyViewPane::ScriptCanvas);
+ });
}
void MainWindow::OnCommandStarted(AZ::Crc32)
From b70545ad94e35203170985dc8e2d864ecfb993e6 Mon Sep 17 00:00:00 2001
From: carlitosan <82187351+carlitosan@users.noreply.github.com>
Date: Thu, 2 Dec 2021 16:07:50 -0800
Subject: [PATCH 05/12] ScriptCanvas --> Script Canvas in comments
Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com>
---
Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
index 4a20c6bc0d..999afd7a9d 100644
--- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp
@@ -4305,10 +4305,10 @@ namespace ScriptCanvasEditor
{
m_forceCloseInProgress = true;
QMessageBox::critical(this, QString(), QObject::tr
- ("The ScriptCanvas Editor has encountered an external bug which prevents it from tracking the file state.
"
- "The ScriptCanvas files in the process of being saved may have saved successfully.
Closing this window will close "
- "the ScriptCanvas Editor, and request a launch of the Asset Processor.
"
- "Verify that the Asset Processor or is running before launching the ScriptCanvas Editor again.
"
+ ("The Script Canvas Editor has encountered an external bug which prevents it from tracking the file state.
"
+ "The Script Canvas files in the process of being saved may have saved successfully.
Closing this window will close "
+ "the Script Canvas Editor, and request a launch of the Asset Processor.
"
+ "Verify that the Asset Processor is running before launching the Script Canvas Editor again.
"
"The status of the Asset Processor can be monitored from the O3DE Editor in the bottom-right corner of the status bar."));
AzFramework::AssetSystem::LaunchAssetProcessor();
From 08cf53a3f663476307fb59f9d0d1c91353672017 Mon Sep 17 00:00:00 2001
From: mrieggeramzn
Date: Tue, 7 Dec 2021 16:37:53 -0800
Subject: [PATCH 06/12] Fix warnings, add branch notifier
Signed-off-by: mrieggeramzn
---
.../Assets/ShaderLib/Atom/Features/LightCulling/NVLC.azsli | 4 ++--
.../Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/NVLC.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/NVLC.azsli
index f6dfc0aab4..7878d946b8 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/NVLC.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/LightCulling/NVLC.azsli
@@ -74,7 +74,7 @@ struct TileLightData
bool Light_IsInsideBin(uint package, uint bin)
{
- return (package & (1 << bin)) != 0;
+ return (package & (1u << bin)) != 0;
}
uint PackLightIndexWithBinMask(uint ind, uint bins)
@@ -130,7 +130,7 @@ uint NVLC_GetBin(const float viewZ, const TileLightData data)
const float zFarCoordSystemAdjusted = data.zFar * RH_COORD_SYSTEM_REVERSE;
float f = saturate( (abs(viewZCoordSystemAdjusted) - zNearCoordSystemAdjusted) / (zFarCoordSystemAdjusted - zNearCoordSystemAdjusted) );
- float bin = min(f, 0.999999) * float(1 << data.logMaxBins);
+ float bin = min(f, 0.999999) * float(1u << data.logMaxBins);
return uint(bin);
}
diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli
index aecb89eb92..1863c749b0 100644
--- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli
+++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/PBR/Decals.azsli
@@ -54,6 +54,8 @@ void ApplyDecal(uint currDecalIndex, inout Surface surface)
localPos = mul(decalRot, localPos);
float3 decalUVW = localPos * rcp(decal.m_halfSize);
+
+ [branch]
if(decalUVW.x >= -1.0f && decalUVW.x <= 1.0f &&
decalUVW.y >= -1.0f && decalUVW.y <= 1.0f &&
decalUVW.z >= -1.0f && decalUVW.z <= 1.0f)
@@ -72,6 +74,7 @@ void ApplyDecal(uint currDecalIndex, inout Surface surface)
float2 normalMap = 0;
// Each texture array handles a size permutation.
// e.g. it could be that tex array 0 handles 256x256 and tex array 1 handles 512x64, etc.
+ [branch]
switch(textureArrayIndex)
{
case 0:
From 766de68199203ad3095a711a6e1f6b180ac0aca4 Mon Sep 17 00:00:00 2001
From: carlitosan <82187351+carlitosan@users.noreply.github.com>
Date: Wed, 8 Dec 2021 22:54:21 -0800
Subject: [PATCH 07/12] small fixes for SC play in editor and warnings
Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com>
---
.../Components/EditorScriptCanvasComponent.cpp | 10 ----------
.../Components/EditorScriptCanvasComponent.h | 4 +---
Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp | 13 ++++++++++++-
Gems/ScriptCanvas/Code/Editor/SystemComponent.h | 10 +++++++++-
.../Code/Include/ScriptCanvas/Core/Graph.cpp | 15 ++++++++++++++-
5 files changed, 36 insertions(+), 16 deletions(-)
diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp
index 043e034062..a0e0868422 100644
--- a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp
@@ -475,16 +475,6 @@ namespace ScriptCanvasEditor
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
}
- void EditorScriptCanvasComponent::OnStartPlayInEditor()
- {
- ScriptCanvas::Execution::PerformanceStatisticsEBus::Broadcast(&ScriptCanvas::Execution::PerformanceStatisticsBus::ClearSnaphotStatistics);
- }
-
- void EditorScriptCanvasComponent::OnStopPlayInEditor()
- {
- AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::GarbageCollect);
- }
-
void EditorScriptCanvasComponent::SetAssetId(const AZ::Data::AssetId& assetId)
{
if (m_scriptCanvasAssetHolder.GetAssetId() != assetId)
diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h
index 5dbe718eca..8fd4ce4f14 100644
--- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h
+++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h
@@ -96,9 +96,7 @@ namespace ScriptCanvasEditor
//=====================================================================
// EditorEntityContextNotificationBus
- void OnStartPlayInEditor() override;
-
- void OnStopPlayInEditor() override;
+
protected:
static void Reflect(AZ::ReflectContext* context);
diff --git a/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp
index f901915fdb..d976e2c0b9 100644
--- a/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
@@ -328,10 +329,20 @@ namespace ScriptCanvasEditor
}
};
- openers.push_back({ "O3DE_ScriptCanvasEditor", "Open In Script Canvas Editor...", QIcon(), scriptCanvasEditorCallback });
+ openers.push_back({ "O3DE_ScriptCanvasEditor", "Open In Script Canvas Editor...", QIcon(ScriptCanvasAssetDescription().GetIconPathImpl()), scriptCanvasEditorCallback });
}
}
+ void SystemComponent::OnStartPlayInEditor()
+ {
+ ScriptCanvas::Execution::PerformanceStatisticsEBus::Broadcast(&ScriptCanvas::Execution::PerformanceStatisticsBus::ClearSnaphotStatistics);
+ }
+
+ void SystemComponent::OnStopPlayInEditor()
+ {
+ AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::GarbageCollect);
+ }
+
void SystemComponent::OnUserSettingsActivated()
{
PopulateEditorCreatableTypes();
diff --git a/Gems/ScriptCanvas/Code/Editor/SystemComponent.h b/Gems/ScriptCanvas/Code/Editor/SystemComponent.h
index 6f85b3c5a6..c2c42c5b9d 100644
--- a/Gems/ScriptCanvas/Code/Editor/SystemComponent.h
+++ b/Gems/ScriptCanvas/Code/Editor/SystemComponent.h
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
namespace ScriptCanvasEditor
{
@@ -36,6 +37,8 @@ namespace ScriptCanvasEditor
, private AZ::Data::AssetBus::MultiHandler
, private AzToolsFramework::AssetSeedManagerRequests::Bus::Handler
, private AzToolsFramework::EditorContextMenuBus::Handler
+ , private AzToolsFramework::EditorEntityContextNotificationBus::Handler
+
{
public:
AZ_COMPONENT(SystemComponent, "{1DE7A120-4371-4009-82B5-8140CB1D7B31}");
@@ -97,7 +100,12 @@ namespace ScriptCanvasEditor
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
-
+
+ protected:
+ void OnStartPlayInEditor() override;
+
+ void OnStopPlayInEditor() override;
+
private:
SystemComponent(const SystemComponent&) = delete;
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp
index 9d848ff998..2b567aab0d 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp
@@ -52,6 +52,7 @@ namespace GraphCpp
VariablePanelSymantics,
AddVersionData,
RemoveFunctionGraphMarker,
+ FixupVersionDataTypeId,
// label your version above
Current
};
@@ -71,11 +72,23 @@ namespace ScriptCanvas
componentElementNode.AddElementWithData(context, "m_assetType", azrtti_typeid());
}
- if (componentElementNode.GetVersion() < GraphCpp::GraphVersion::RemoveFunctionGraphMarker)
+ if (componentElementNode.GetVersion() <= GraphCpp::GraphVersion::RemoveFunctionGraphMarker)
{
componentElementNode.RemoveElementByName(AZ_CRC_CE("isFunctionGraph"));
}
+ if (componentElementNode.GetVersion() < GraphCpp::GraphVersion::FixupVersionDataTypeId)
+ {
+ if (auto subElement = componentElementNode.FindSubElement(AZ_CRC_CE("versionData")))
+ {
+ if (subElement->GetId() == azrtti_typeid())
+ {
+ componentElementNode.RemoveElementByName(AZ_CRC_CE("versionData"));
+ componentElementNode.AddElementWithData(context, "versionData", VersionData());
+ }
+ }
+ }
+
return true;
}
From 70875651491842cf80d46371d1d1dcae5776dd23 Mon Sep 17 00:00:00 2001
From: carlitosan <82187351+carlitosan@users.noreply.github.com>
Date: Wed, 8 Dec 2021 23:23:03 -0800
Subject: [PATCH 08/12] fix interpreted statics
Signed-off-by: carlitosan <82187351+carlitosan@users.noreply.github.com>
---
.../Execution/Interpreted/ExecutionInterpretedAPI.cpp | 9 +++++----
.../Execution/Interpreted/ExecutionStateInterpreted.cpp | 5 ++++-
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp
index 1855b348f2..561708dea1 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp
@@ -503,20 +503,21 @@ namespace ScriptCanvas
void InitializeInterpretedStatics(RuntimeData& runtimeData)
{
- if (!runtimeData.m_areStaticsInitialized)
+ AZ_Error("ScriptCanvas", !runtimeData.m_areStaticsInitialized, "ScriptCanvas runtime data already initalized");
{
runtimeData.m_areStaticsInitialized = true;
for (auto& dependency : runtimeData.m_requiredAssets)
{
- InitializeInterpretedStatics(dependency.Get()->GetData());
+ if (!dependency.Get()->GetData().m_areStaticsInitialized)
+ {
+ InitializeInterpretedStatics(dependency.Get()->GetData());
+ }
}
#if defined(AZ_PROFILE_BUILD) || defined(AZ_DEBUG_BUILD)
Execution::InitializeFromLuaStackFunctions(const_cast(runtimeData.m_debugMap));
#endif
- AZ_WarningOnce("ScriptCanvas", !runtimeData.m_areStaticsInitialized, "ScriptCanvas runtime data already initalized");
-
if (runtimeData.RequiresStaticInitialization())
{
AZ::ScriptLoadResult result{};
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp
index 3ae52846cd..3b963317ec 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp
@@ -49,7 +49,10 @@ namespace ScriptCanvas
, config.asset.GetId().ToString().data());
#endif
- Execution::InitializeInterpretedStatics(runtimeAsset->GetData());
+ if (!runtimeAsset->GetData().m_areStaticsInitialized)
+ {
+ Execution::InitializeInterpretedStatics(runtimeAsset->GetData());
+ }
}
void ExecutionStateInterpreted::ClearLuaRegistryIndex()
From 0bccecaa15ea756b840985ba562a1302e419b322 Mon Sep 17 00:00:00 2001
From: Chris Galvan
Date: Thu, 9 Dec 2021 11:36:39 -0600
Subject: [PATCH 09/12] Fixed logic for when to cull entities from having their
viewport manipulators regenerated.
Signed-off-by: Chris Galvan
---
.../EditorTransformComponentSelection.cpp | 46 +++++++++----------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp
index 336198c183..f430d3a61e 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp
@@ -2504,6 +2504,29 @@ namespace AzToolsFramework
{
AZ_PROFILE_FUNCTION(AzToolsFramework);
+ // Do not create manipulators for the container entity of the focused prefab.
+ if (auto prefabFocusPublicInterface = AZ::Interface::Get())
+ {
+ AzFramework::EntityContextId editorEntityContextId = GetEntityContextId();
+ if (AZ::EntityId focusRoot = prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);
+ focusRoot.IsValid())
+ {
+ m_selectedEntityIds.erase(focusRoot);
+ }
+ }
+
+ // Do not create manipulators for any entities marked as read only
+ if (auto readOnlyEntityPublicInterface = AZ::Interface::Get())
+ {
+ AZStd::erase_if(
+ m_selectedEntityIds,
+ [readOnlyEntityPublicInterface](auto entityId)
+ {
+ return readOnlyEntityPublicInterface->IsReadOnly(entityId);
+ }
+ );
+ }
+
// note: create/destroy pattern to be addressed
DestroyManipulators(m_entityIdManipulators);
CreateEntityIdManipulators();
@@ -3635,29 +3658,6 @@ namespace AzToolsFramework
m_selectedEntityIds.clear();
m_selectedEntityIds.reserve(selectedEntityIds.size());
AZStd::copy(selectedEntityIds.begin(), selectedEntityIds.end(), AZStd::inserter(m_selectedEntityIds, m_selectedEntityIds.end()));
-
- // Do not create manipulators for the container entity of the focused prefab.
- if (auto prefabFocusPublicInterface = AZ::Interface::Get())
- {
- AzFramework::EntityContextId editorEntityContextId = GetEntityContextId();
- if (AZ::EntityId focusRoot = prefabFocusPublicInterface->GetFocusedPrefabContainerEntityId(editorEntityContextId);
- focusRoot.IsValid())
- {
- m_selectedEntityIds.erase(focusRoot);
- }
- }
-
- // Do not create manipulators for any entities marked as read only
- if (auto readOnlyEntityPublicInterface = AZ::Interface::Get())
- {
- AZStd::erase_if(
- m_selectedEntityIds,
- [readOnlyEntityPublicInterface](auto entityId)
- {
- return readOnlyEntityPublicInterface->IsReadOnly(entityId);
- }
- );
- }
}
void EditorTransformComponentSelection::OnTransformChanged(
From e636ea39e3123fa576b45e21c6750aeb2cf1e17e Mon Sep 17 00:00:00 2001
From: Chris Galvan
Date: Thu, 9 Dec 2021 13:15:20 -0600
Subject: [PATCH 10/12] Fixed comment casing to match rest of file.
Signed-off-by: Chris Galvan
---
.../ViewportSelection/EditorTransformComponentSelection.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp
index f430d3a61e..bd9292db32 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp
@@ -2504,7 +2504,7 @@ namespace AzToolsFramework
{
AZ_PROFILE_FUNCTION(AzToolsFramework);
- // Do not create manipulators for the container entity of the focused prefab.
+ // do not create manipulators for the container entity of the focused prefab.
if (auto prefabFocusPublicInterface = AZ::Interface::Get())
{
AzFramework::EntityContextId editorEntityContextId = GetEntityContextId();
@@ -2515,7 +2515,7 @@ namespace AzToolsFramework
}
}
- // Do not create manipulators for any entities marked as read only
+ // do not create manipulators for any entities marked as read only
if (auto readOnlyEntityPublicInterface = AZ::Interface::Get())
{
AZStd::erase_if(
From c63b4eb905eb396c530cddbfcfcc194b19a5b0ba Mon Sep 17 00:00:00 2001
From: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
Date: Thu, 9 Dec 2021 14:53:25 -0600
Subject: [PATCH 11/12] Removing unused variable and fix typo (#6265)
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
---
.../AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp | 2 +-
.../AzToolsFramework/Tests/Prefab/PrefabAssetFixupTests.cpp | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp
index 83e8d2e4be..50c61e6877 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp
@@ -150,7 +150,7 @@ namespace AzToolsFramework
return result.GetOutcome() == AZ::JsonSerializationResult::Outcomes::Success;
}
- // some assets may come in from the JSON serialzier with no AssetID, but have an asset hint
+ // some assets may come in from the JSON serializer with no AssetID, but have an asset hint
// this attempts to fix up the assets using the assetHint field
void FixUpInvalidAssets(AZ::Data::Asset& asset)
{
diff --git a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabAssetFixupTests.cpp b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabAssetFixupTests.cpp
index 379392553e..4f2a19faec 100644
--- a/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabAssetFixupTests.cpp
+++ b/Code/Framework/AzToolsFramework/Tests/Prefab/PrefabAssetFixupTests.cpp
@@ -176,7 +176,6 @@ namespace UnitTest
TEST_F(PrefabFixupTest, Test_LoadInstanceFromPrefabDom_Overload3)
{
Instance instance;
- AZStd::vector> referencedAssets;
Instance::EntityList entityList;
(PrefabDomUtils::LoadInstanceFromPrefabDom(instance, entityList, m_prefabDom));
From 5e5bb272192043c18612942d660c1c98c18af583 Mon Sep 17 00:00:00 2001
From: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
Date: Thu, 9 Dec 2021 14:53:35 -0600
Subject: [PATCH 12/12] Procedural Prefabs: Python documentation cleanup
(#6136)
* Auto LOD script setup
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Working auto LODs
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Correctly selected LODs and added default prefab
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Cleanup code
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Cleanup code
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Add missing legal header, move name cleanup to scene_helpers, add documentation
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Add PhysX mesh group support.
Updated example script to show usage
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Add a physics collider component
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Update DefaultOrValue call
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Document remaining methods in scene_data.py
Add enums where appropriate
Add type hints and default values
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Remove unused import
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Convert docstring to numpy style
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Fix return types
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Remove empty returns
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
* Add docs on enums
Signed-off-by: amzn-mike <80125227+amzn-mike@users.noreply.github.com>
---
.../Editor/Scripts/scene_helpers.py | 38 +-
.../Editor/Scripts/scene_mesh_to_prefab.py | 8 +-
.../Editor/Scripts/scene_api/scene_data.py | 628 ++++++++++++------
3 files changed, 474 insertions(+), 200 deletions(-)
diff --git a/AutomatedTesting/Editor/Scripts/scene_helpers.py b/AutomatedTesting/Editor/Scripts/scene_helpers.py
index 761068e796..cae4488abc 100644
--- a/AutomatedTesting/Editor/Scripts/scene_helpers.py
+++ b/AutomatedTesting/Editor/Scripts/scene_helpers.py
@@ -14,30 +14,44 @@ from scene_api.scene_data import SceneGraphName
def log_exception_traceback():
- """
- Outputs an exception stacktrace.
- """
+ """Outputs an exception stacktrace."""
data = traceback.format_exc()
logger = logging.getLogger('python')
logger.error(data)
-def sanitize_name_for_disk(name: str):
- """
- Removes illegal filename characters from a string.
+def sanitize_name_for_disk(name: str) -> str:
+ """Removes illegal filename characters from a string.
+
+ Parameters
+ ----------
+ name :
+ String to clean.
+
+
+ Returns
+ -------
+ str
+ Name with illegal characters removed.
- :param name: String to clean.
- :return: Name with illegal characters removed.
"""
return "".join(char for char in name if char not in "|<>:\"/?*\\")
def get_mesh_node_names(scene_graph: sceneData.SceneGraph) -> Tuple[List[SceneGraphName], List[str]]:
- """
- Returns a tuple of all the mesh nodes as well as all the node paths
+ """Returns a tuple of all the mesh nodes as well as all the node paths
+
+ Parameters
+ ----------
+ scene_graph :
+ Scene graph to search
+
+
+ Returns
+ -------
+ Tuple[List[SceneGraphName], List[str]]
+ Tuple of [Mesh Nodes, All Node Paths]
- :param scene_graph: Scene graph to search
- :return: Tuple of [Mesh Nodes, All Node Paths]
"""
import azlmbr.scene as sceneApi
import azlmbr.scene.graph
diff --git a/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py
index db8df09091..f9c1e08558 100644
--- a/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py
+++ b/AutomatedTesting/Editor/Scripts/scene_mesh_to_prefab.py
@@ -8,7 +8,7 @@
import azlmbr.bus
import azlmbr.math
-from scene_api.scene_data import PrimitiveShape, DecompositionMode
+from scene_api.scene_data import PrimitiveShape, DecompositionMode, ColorChannel, TangentSpaceSource, TangentSpaceMethod
from scene_helpers import *
@@ -71,6 +71,7 @@ def add_physx_meshes(scene_manifest: sceneData.SceneManifest, source_file_name:
triangle = scene_manifest.add_physx_triangle_mesh_group(source_file_name + "_triangle", False, True, True, True, True, True)
scene_manifest.physx_mesh_group_add_selected_unselected_nodes(triangle, [first_mesh], all_except_first_mesh)
+
def update_manifest(scene):
import uuid, os
import azlmbr.scene.graph
@@ -114,10 +115,11 @@ def update_manifest(scene):
if node != mesh_path:
scene_manifest.mesh_group_unselect_node(mesh_group, node)
- scene_manifest.mesh_group_add_cloth_rule(mesh_group, mesh_path, "Col0", 1, "Col0", 2, "Col0", 2, 3)
+ scene_manifest.mesh_group_add_cloth_rule(mesh_group, mesh_path, "Col0", ColorChannel.GREEN, "Col0",
+ ColorChannel.BLUE, "Col0", ColorChannel.BLUE, ColorChannel.ALPHA)
scene_manifest.mesh_group_add_advanced_mesh_rule(mesh_group, True, False, True, "Col0")
scene_manifest.mesh_group_add_skin_rule(mesh_group, 3, 0.002)
- scene_manifest.mesh_group_add_tangent_rule(mesh_group, 1, 0)
+ scene_manifest.mesh_group_add_tangent_rule(mesh_group, TangentSpaceSource.MIKKT_GENERATION, TangentSpaceMethod.TSPACE_BASIC)
# Create an editor entity
entity_id = azlmbr.entity.EntityUtilityBus(azlmbr.bus.Broadcast, "CreateEditorReadyEntity", mesh_group_name)
diff --git a/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py b/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py
index 173558d784..66b836f171 100755
--- a/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py
+++ b/Gems/PythonAssetBuilder/Editor/Scripts/scene_api/scene_data.py
@@ -7,13 +7,13 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
import typing
import json
import azlmbr.scene as sceneApi
-from enum import Enum, IntEnum
+from enum import IntEnum
# Wraps the AZ.SceneAPI.Containers.SceneGraph.NodeIndex internal class
class SceneGraphNodeIndex:
- def __init__(self, sceneGraphNodeIndex) -> None:
- self.nodeIndex = sceneGraphNodeIndex
+ def __init__(self, scene_graph_node_index) -> None:
+ self.nodeIndex = scene_graph_node_index
def as_number(self):
return self.nodeIndex.AsNumber()
@@ -29,9 +29,9 @@ class SceneGraphNodeIndex:
# Wraps AZ.SceneAPI.Containers.SceneGraph.Name internal class
-class SceneGraphName():
- def __init__(self, sceneGraphName) -> None:
- self.name = sceneGraphName
+class SceneGraphName:
+ def __init__(self, scene_graph_name) -> None:
+ self.name = scene_graph_name
def get_path(self) -> str:
return self.name.GetPath()
@@ -41,9 +41,9 @@ class SceneGraphName():
# Wraps AZ.SceneAPI.Containers.SceneGraph class
-class SceneGraph():
- def __init__(self, sceneGraphInstance) -> None:
- self.sceneGraph = sceneGraphInstance
+class SceneGraph:
+ def __init__(self, scene_graph_instance) -> None:
+ self.sceneGraph = scene_graph_instance
@classmethod
def is_valid_name(cls, name):
@@ -96,53 +96,161 @@ class SceneGraph():
return self.sceneGraph.GetNodeContent(node)
+class ColorChannel(IntEnum):
+ RED = 0
+ """ Red color channel """
+ GREEN = 1
+ """ Green color channel """
+ BLUE = 2
+ """ Blue color channel """
+ ALPHA = 3
+ """ Alpha color channel """
+
+
+class TangentSpaceSource(IntEnum):
+ SCENE = 0
+ """ Extract the tangents and bitangents directly from the source scene file. """
+ MIKKT_GENERATION = 1
+ """ Use MikkT algorithm to generate tangents """
+
+
+class TangentSpaceMethod(IntEnum):
+ TSPACE = 0
+ """ Generates the tangents and bitangents with their true magnitudes which can be used for relief mapping effects.
+ It calculates the 'real' bitangent which may not be perpendicular to the tangent.
+ However, both, the tangent and bitangent are perpendicular to the vertex normal.
+ """
+ TSPACE_BASIC = 1
+ """ Calculates unit vector tangents and bitangents at pixel/vertex level which are sufficient for basic normal mapping. """
+
+
class PrimitiveShape(IntEnum):
BEST_FIT = 0
+ """ The algorithm will determine which of the shapes fits best. """
SPHERE = 1
+ """ Sphere shape """
BOX = 2
+ """ Box shape """
CAPSULE = 3
+ """ Capsule shape """
class DecompositionMode(IntEnum):
VOXEL = 0
+ """ Voxel-based approximate convex decomposition """
TETRAHEDRON = 1
+ """ Tetrahedron-based approximate convex decomposition """
# Contains a dictionary to contain and export AZ.SceneAPI.Containers.SceneManifest
-class SceneManifest():
+class SceneManifest:
def __init__(self):
self.manifest = {'values': []}
def add_mesh_group(self, name: str) -> dict:
- meshGroup = {}
- meshGroup['$type'] = '{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup'
- meshGroup['name'] = name
- meshGroup['nodeSelectionList'] = {'selectedNodes': [], 'unselectedNodes': []}
- meshGroup['rules'] = {'rules': [{'$type': 'MaterialRule'}]}
- self.manifest['values'].append(meshGroup)
- return meshGroup
+ """Adds a Mesh Group to the scene manifest.
+
+ Parameters
+ ----------
+ name :
+ Name of the mesh group. This will become a file on disk and be usable as a Mesh in the editor.
+
+
+ Returns
+ -------
+ dict
+ Newly created mesh group.
+
+ """
+ mesh_group = {
+ '$type': '{07B356B7-3635-40B5-878A-FAC4EFD5AD86} MeshGroup',
+ 'name': name,
+ 'nodeSelectionList': {'selectedNodes': [], 'unselectedNodes': []},
+ 'rules': {'rules': [{'$type': 'MaterialRule'}]}
+ }
+ self.manifest['values'].append(mesh_group)
+ return mesh_group
def add_prefab_group(self, name: str, id: str, json: dict) -> dict:
- prefabGroup = {}
- prefabGroup['$type'] = '{99FE3C6F-5B55-4D8B-8013-2708010EC715} PrefabGroup'
- prefabGroup['name'] = name
- prefabGroup['id'] = id
- prefabGroup['prefabDomData'] = json
- self.manifest['values'].append(prefabGroup)
- return prefabGroup
+ """Adds a Prefab Group to the scene manifest. This will become a file on disk and be usable as a ProceduralPrefab in the editor.
+
+ Parameters
+ ----------
+ name :
+ Name of the prefab.
+ id :
+ Unique ID for this prefab group.
+ json :
+ The prefab template data.
+
+
+ Returns
+ -------
+ dict
+ The newly created Prefab group
+
+ """
+ prefab_group = {
+ '$type': '{99FE3C6F-5B55-4D8B-8013-2708010EC715} PrefabGroup',
+ 'name': name,
+ 'id': id,
+ 'prefabDomData': json
+ }
+ self.manifest['values'].append(prefab_group)
+ return prefab_group
def mesh_group_select_node(self, mesh_group: dict, node_name: str) -> None:
+ """Adds a node as a selected node.
+
+ Parameters
+ ----------
+ mesh_group :
+ Mesh group to apply the selection to.
+ node_name :
+ Path of the node.
+
+ """
mesh_group['nodeSelectionList']['selectedNodes'].append(node_name)
def mesh_group_unselect_node(self, mesh_group: dict, node_name: str) -> None:
+ """Adds a node as an unselected node.
+
+ Parameters
+ ----------
+ mesh_group :
+ Mesh group to apply the selection to.
+ node_name :
+ Path of the node.
+
+ """
mesh_group['nodeSelectionList']['unselectedNodes'].append(node_name)
- def mesh_group_add_advanced_coordinate_system(self, mesh_group: dict, origin_node_name: str, translation: object,
- rotation: object, scale: float) -> None:
+ def mesh_group_add_advanced_coordinate_system(self, mesh_group: dict,
+ origin_node_name: str = '',
+ translation: typing.Optional[object] = None,
+ rotation: typing.Optional[object] = None,
+ scale: float = 1.0) -> None:
+ """Adds an Advanced Coordinate System rule which modifies the target coordinate system,
+ applying a transformation to all data (transforms and vertex data if it exists).
+
+ Parameters
+ ----------
+ mesh_group :
+ Mesh group to add the Advanced Coordinate System rule to.
+ origin_node_name :
+ Path of the node to use as the origin.
+ translation :
+ Moves the group along the given vector.
+ rotation :
+ Sets the orientation offset of the processed mesh in degrees. Rotates the group after translation.
+ scale :
+ Sets the scale offset of the processed mesh.
+
+ """
origin_rule = {
'$type': 'CoordinateSystemRule',
'useAdvancedData': True,
- 'originNodeName': '' if origin_node_name is None else origin_node_name
+ 'originNodeName': self.__default_or_value(origin_node_name, '')
}
if translation is not None:
origin_rule['translation'] = translation
@@ -153,31 +261,57 @@ class SceneManifest():
mesh_group['rules']['rules'].append(origin_rule)
def mesh_group_add_comment(self, mesh_group: dict, comment: str) -> None:
- commentRule = {
+ """Adds a Comment rule.
+
+ Parameters
+ ----------
+ mesh_group :
+ Mesh group to add the comment rule to.
+ comment :
+ Text for the comment rule.
+
+ """
+ comment_rule = {
'$type': 'CommentRule',
'comment': comment
}
- mesh_group['rules']['rules'].append(commentRule)
+ mesh_group['rules']['rules'].append(comment_rule)
def __default_or_value(self, val, default):
return default if val is None else val
- def mesh_group_add_cloth_rule(self, mesh_group: dict, cloth_node_name: str,
- inverse_masses_stream_name: str, inverse_masses_channel: int,
- motion_constraints_stream_name: str, motion_constraints_channel: int,
- backstop_stream_name: str, backstop_offset_channel: int,
- backstop_radius_channel: int) -> None:
- """
- Adds a Cloth rule. 0 = Red, 1 = Green, 2 = Blue, 3 = Alpha
- :param mesh_group: Mesh Group to add the cloth rule to
- :param cloth_node_name: Name of the node that the rule applies to
- :param inverse_masses_stream_name: Name of the color stream to use for inverse masses
- :param inverse_masses_channel: Color channel (index) for inverse masses
- :param motion_constraints_stream_name: Name of the color stream to use for motion constraints
- :param motion_constraints_channel: Color channel (index) for motion constraints
- :param backstop_stream_name: Name of the color stream to use for backstop
- :param backstop_offset_channel: Color channel (index) for backstop offset value
- :param backstop_radius_channel: Color chnanel (index) for backstop radius value
+ def mesh_group_add_cloth_rule(self, mesh_group: dict,
+ cloth_node_name: str,
+ inverse_masses_stream_name: typing.Optional[str],
+ inverse_masses_channel: typing.Optional[ColorChannel],
+ motion_constraints_stream_name: typing.Optional[str],
+ motion_constraints_channel: typing.Optional[ColorChannel],
+ backstop_stream_name: typing.Optional[str],
+ backstop_offset_channel: typing.Optional[ColorChannel],
+ backstop_radius_channel: typing.Optional[ColorChannel]) -> None:
+ """Adds a Cloth rule.
+
+ Parameters
+ ----------
+ mesh_group :
+ Mesh Group to add the cloth rule to
+ cloth_node_name :
+ Name of the node that the rule applies to
+ inverse_masses_stream_name :
+ Name of the color stream to use for inverse masses
+ inverse_masses_channel :
+ Color channel (index) for inverse masses
+ motion_constraints_stream_name :
+ Name of the color stream to use for motion constraints
+ motion_constraints_channel :
+ Color channel (index) for motion constraints
+ backstop_stream_name :
+ Name of the color stream to use for backstop
+ backstop_offset_channel :
+ Color channel (index) for backstop offset value
+ backstop_radius_channel :
+ Color channel (index) for backstop radius value
+
"""
cloth_rule = {
'$type': 'ClothRule',
@@ -186,22 +320,31 @@ class SceneManifest():
}
if inverse_masses_channel is not None:
- cloth_rule['inverseMassesChannel'] = inverse_masses_channel
+ cloth_rule['inverseMassesChannel'] = int(inverse_masses_channel)
cloth_rule['motionConstraintsStreamName'] = self.__default_or_value(motion_constraints_stream_name, 'Default: 1.0')
if motion_constraints_channel is not None:
- cloth_rule['motionConstraintsChannel'] = motion_constraints_channel
+ cloth_rule['motionConstraintsChannel'] = int(motion_constraints_channel)
cloth_rule['backstopStreamName'] = self.__default_or_value(backstop_stream_name, 'None')
if backstop_offset_channel is not None:
- cloth_rule['backstopOffsetChannel'] = backstop_offset_channel
+ cloth_rule['backstopOffsetChannel'] = int(backstop_offset_channel)
if backstop_radius_channel is not None:
- cloth_rule['backstopRadiusChannel'] = backstop_radius_channel
+ cloth_rule['backstopRadiusChannel'] = int(backstop_radius_channel)
mesh_group['rules']['rules'].append(cloth_rule)
def mesh_group_add_lod_rule(self, mesh_group: dict) -> dict:
- """
- Adds an LOD rule
- :param mesh_group: Mesh Group to add the rule to
- :return: LOD rule
+ """Adds an LOD rule.
+
+ Parameters
+ ----------
+ mesh_group :
+ Mesh Group to add the rule to.
+
+
+ Returns
+ -------
+ dict
+ LOD rule.
+
"""
lod_rule = {
'$type': '{6E796AC8-1484-4909-860A-6D3F22A7346F} LodRule',
@@ -212,47 +355,76 @@ class SceneManifest():
return lod_rule
def lod_rule_add_lod(self, lod_rule: dict) -> dict:
- """
- Adds an LOD level to the LOD rule. Nodes are added in order. The first node added represents LOD1, 2nd LOD2, etc
- :param lod_rule: LOD rule to add the LOD level to
- :return: LOD level
+ """Adds an LOD level to the LOD rule. Nodes are added in order. The first node added represents LOD1, 2nd LOD2, etc.
+
+ Parameters
+ ----------
+ lod_rule :
+ LOD rule to add the LOD level to.
+
+
+ Returns
+ -------
+ dict
+ LOD level.
+
"""
lod = {'selectedNodes': [], 'unselectedNodes': []}
lod_rule['nodeSelectionList'].append(lod)
return lod
def lod_select_node(self, lod: dict, selected_node: str) -> None:
- """
- Adds a node as a selected node
- :param lod: LOD level to add the node to
- :param selected_node: Path of the node
+ """Adds a node as a selected node.
+
+ Parameters
+ ----------
+ lod :
+ LOD level to add the node to.
+ selected_node :
+ Path of the node.
+
"""
lod['selectedNodes'].append(selected_node)
def lod_unselect_node(self, lod: dict, unselected_node: str) -> None:
- """
- Adds a node as an unselected node
- :param lod: LOD rule to add the node to
- :param unselected_node: Path of the node
+ """Adds a node as an unselected node.
+
+ Parameters
+ ----------
+ lod :
+ LOD rule to add the node to.
+ unselected_node :
+ Path of the node.
+
"""
lod['unselectedNodes'].append(unselected_node)
- def mesh_group_add_advanced_mesh_rule(self, mesh_group: dict, use_32bit_vertices: bool, merge_meshes: bool,
- use_custom_normals: bool,
- vertex_color_stream: str) -> None:
- """
- Adds an Advanced Mesh rule
- :param mesh_group: Mesh Group to add the rule to
- :param use_32bit_vertices: False = 16bit vertex position precision. True = 32bit vertex position precision
- :param merge_meshes: Merge all meshes into a single mesh
- :param use_custom_normals: True = use normals from DCC tool. False = average normals
- :param vertex_color_stream: Color stream name to use for Vertex Coloring
+ def mesh_group_add_advanced_mesh_rule(self, mesh_group: dict,
+ use_32bit_vertices: bool = False,
+ merge_meshes: bool = True,
+ use_custom_normals: bool = True,
+ vertex_color_stream: typing.Optional[str] = None) -> None:
+ """Adds an Advanced Mesh rule.
+
+ Parameters
+ ----------
+ mesh_group :
+ Mesh Group to add the rule to.
+ use_32bit_vertices :
+ False = 16bit vertex position precision. True = 32bit vertex position precision.
+ merge_meshes :
+ Merge all meshes into a single mesh.
+ use_custom_normals :
+ True = use normals from DCC tool. False = average normals.
+ vertex_color_stream :
+ Color stream name to use for Vertex Coloring.
+
"""
rule = {
'$type': 'StaticMeshAdvancedRule',
- 'use32bitVertices': self.__default_or_value(use_32bit_vertices, False),
- 'mergeMeshes': self.__default_or_value(merge_meshes, True),
- 'useCustomNormals': self.__default_or_value(use_custom_normals, True)
+ 'use32bitVertices': use_32bit_vertices,
+ 'mergeMeshes': merge_meshes,
+ 'useCustomNormals': use_custom_normals
}
if vertex_color_stream is not None:
@@ -260,37 +432,51 @@ class SceneManifest():
mesh_group['rules']['rules'].append(rule)
- def mesh_group_add_skin_rule(self, mesh_group: dict, max_weights_per_vertex: int, weight_threshold: float) -> None:
- """
- Adds a Skin rule
- :param mesh_group: Mesh Group to add the rule to
- :param max_weights_per_vertex: Max number of joints that can influence a vertex
- :param weight_threshold: Weight values below this value will be treated as 0
+ def mesh_group_add_skin_rule(self, mesh_group: dict, max_weights_per_vertex: int = 4, weight_threshold: float = 0.001) -> None:
+ """Adds a Skin rule.
+
+ Parameters
+ ----------
+ mesh_group :
+ Mesh Group to add the rule to.
+ max_weights_per_vertex :
+ Max number of joints that can influence a vertex.
+ weight_threshold :
+ Weight values below this value will be treated as 0.
+
"""
rule = {
'$type': 'SkinRule',
- 'maxWeightsPerVertex': self.__default_or_value(max_weights_per_vertex, 4),
- 'weightThreshold': self.__default_or_value(weight_threshold, 0.001)
+ 'maxWeightsPerVertex': max_weights_per_vertex,
+ 'weightThreshold': weight_threshold
}
mesh_group['rules']['rules'].append(rule)
- def mesh_group_add_tangent_rule(self, mesh_group: dict, tangent_space: int, tspace_method: int) -> None:
- """
- Adds a Tangent rule to control tangent space generation
- :param mesh_group: Mesh Group to add the rule to
- :param tangent_space: Tangent space source. 0 = Scene, 1 = MikkT Tangent Generation
- :param tspace_method: MikkT Generation method. 0 = TSpace, 1 = TSpaceBasic
+ def mesh_group_add_tangent_rule(self, mesh_group: dict,
+ tangent_space: TangentSpaceSource = TangentSpaceSource.SCENE,
+ tspace_method: TangentSpaceMethod = TangentSpaceMethod.TSPACE) -> None:
+ """Adds a Tangent rule to control tangent space generation.
+
+ Parameters
+ ----------
+ mesh_group :
+ Mesh Group to add the rule to.
+ tangent_space :
+ Tangent space source. 0 = Scene, 1 = MikkT Tangent Generation.
+ tspace_method :
+ MikkT Generation method. 0 = TSpace, 1 = TSpaceBasic.
+
"""
rule = {
'$type': 'TangentsRule',
- 'tangentSpace': self.__default_or_value(tangent_space, 1),
- 'tSpaceMethod': self.__default_or_value(tspace_method, 0)
+ 'tangentSpace': int(tangent_space),
+ 'tSpaceMethod': int(tspace_method)
}
mesh_group['rules']['rules'].append(rule)
- def __add_physx_base_mesh_group(self, name: str, physics_material: typing.Optional[str]) -> dict:
+ def __add_physx_base_mesh_group(self, name: str, physics_material: typing.Optional[str] = None) -> dict:
import azlmbr.math
group = {
'$type': '{5B03C8E6-8CEE-4DA0-A7FA-CD88689DD45B} MeshGroup',
@@ -314,7 +500,9 @@ class SceneManifest():
return group
- def add_physx_triangle_mesh_group(self, name: str, merge_meshes: bool = True, weld_vertices: bool = False,
+ def add_physx_triangle_mesh_group(self, name: str,
+ merge_meshes: bool = True,
+ weld_vertices: bool = False,
disable_clean_mesh: bool = False,
force_32bit_indices: bool = False,
suppress_triangle_mesh_remap_table: bool = False,
@@ -322,26 +510,42 @@ class SceneManifest():
mesh_weld_tolerance: float = 0.0,
num_tris_per_leaf: int = 4,
physics_material: typing.Optional[str] = None) -> dict:
- """
- Adds a Triangle type PhysX Mesh Group to the scene.
+ """Adds a Triangle type PhysX Mesh Group to the scene.
+
+ Parameters
+ ----------
+ name :
+ Name of the mesh group.
+ merge_meshes :
+ When true, all selected nodes will be merged into a single collision mesh.
+ weld_vertices :
+ When true, mesh welding is performed. Clean mesh must be enabled.
+ disable_clean_mesh :
+ When true, mesh cleaning is disabled. This makes cooking faster.
+ force_32bit_indices :
+ When true, 32-bit indices will always be created regardless of triangle count.
+ suppress_triangle_mesh_remap_table :
+ When true, the face remap table is not created.
+ This saves a significant amount of memory, but the SDK will not be able to provide the remap
+ information for internal mesh triangles returned by collisions, sweeps or raycasts hits.
+ build_triangle_adjacencies :
+ When true, the triangle adjacency information is created.
+ mesh_weld_tolerance :
+ If mesh welding is enabled, this controls the distance at
+ which vertices are welded. If mesh welding is not enabled, this value defines the
+ acceptance distance for mesh validation. Provided no two vertices are within this
+ distance, the mesh is considered to be clean. If not, a warning will be emitted.
+ num_tris_per_leaf :
+ Mesh cooking hint for max triangles per leaf limit. Fewer triangles per leaf
+ produces larger meshes with better runtime performance and worse cooking performance.
+ physics_material :
+ Configure which physics material to use.
+
+ Returns
+ -------
+ dict
+ The newly created mesh group.
- :param name: Name of the mesh group.
- :param merge_meshes: When true, all selected nodes will be merged into a single collision mesh.
- :param weld_vertices: When true, mesh welding is performed. Clean mesh must be enabled.
- :param disable_clean_mesh: When true, mesh cleaning is disabled. This makes cooking faster.
- :param force_32bit_indices: When true, 32-bit indices will always be created regardless of triangle count.
- :param suppress_triangle_mesh_remap_table: When true, the face remap table is not created.
- This saves a significant amount of memory, but the SDK will not be able to provide the remap
- information for internal mesh triangles returned by collisions, sweeps or raycasts hits.
- :param build_triangle_adjacencies: When true, the triangle adjacency information is created.
- :param mesh_weld_tolerance: If mesh welding is enabled, this controls the distance at
- which vertices are welded. If mesh welding is not enabled, this value defines the
- acceptance distance for mesh validation. Provided no two vertices are within this
- distance, the mesh is considered to be clean. If not, a warning will be emitted.
- :param num_tris_per_leaf: Mesh cooking hint for max triangles per leaf limit. Fewer triangles per leaf
- produces larger meshes with better runtime performance and worse cooking performance.
- :param physics_material: Configure which physics material to use.
- :return: The newly created mesh group.
"""
group = self.__add_physx_base_mesh_group(name, physics_material)
group["export method"] = 0
@@ -367,32 +571,49 @@ class SceneManifest():
gauss_map_limit: int = 32,
build_gpu_data: bool = False,
physics_material: typing.Optional[str] = None) -> dict:
- """
- Adds a Convex type PhysX Mesh Group to the scene.
+ """Adds a Convex type PhysX Mesh Group to the scene.
+
+ Parameters
+ ----------
+ name :
+ Name of the mesh group.
+ area_test_epsilon :
+ If the area of a triangle of the hull is below this value, the triangle will be
+ rejected. This test is done only if Check Zero Area Triangles is used.
+ plane_tolerance :
+ The value is used during hull construction. When a new point is about to be added
+ to the hull it gets dropped when the point is closer to the hull than the planeTolerance.
+ use_16bit_indices :
+ Denotes the use of 16-bit vertex indices in Convex triangles or polygons.
+ check_zero_area_triangles :
+ Checks and removes almost zero-area triangles during convex hull computation.
+ The rejected area size is specified in Area Test Epsilon.
+ quantize_input :
+ Quantizes the input vertices using the k-means clustering.
+ use_plane_shifting :
+ Enables plane shifting vertex limit algorithm. Plane shifting is an alternative
+ algorithm for the case when the computed hull has more vertices than the specified vertex
+ limit.
+ shift_vertices :
+ Convex hull input vertices are shifted to be around origin to provide better
+ computation stability
+ gauss_map_limit :
+ Vertex limit beyond which additional acceleration structures are computed for each
+ convex mesh. Increase that limit to reduce memory usage. Computing the extra structures
+ all the time does not guarantee optimal performance.
+ build_gpu_data :
+ When true, additional information required for GPU-accelerated rigid body
+ simulation is created. This can increase memory usage and cooking times for convex meshes
+ and triangle meshes. Convex hulls are created with respect to GPU simulation limitations.
+ Vertex limit is set to 64 and vertex limit per face is internally set to 32.
+ physics_material :
+ Configure which physics material to use.
+
+ Returns
+ -------
+ dict
+ The newly created mesh group.
- :param name: Name of the mesh group.
- :param area_test_epsilon: If the area of a triangle of the hull is below this value, the triangle will be
- rejected. This test is done only if Check Zero Area Triangles is used.
- :param plane_tolerance: The value is used during hull construction. When a new point is about to be added
- to the hull it gets dropped when the point is closer to the hull than the planeTolerance.
- :param use_16bit_indices: Denotes the use of 16-bit vertex indices in Convex triangles or polygons.
- :param check_zero_area_triangles: Checks and removes almost zero-area triangles during convex hull computation.
- The rejected area size is specified in Area Test Epsilon.
- :param quantize_input: Quantizes the input vertices using the k-means clustering.
- :param use_plane_shifting: Enables plane shifting vertex limit algorithm. Plane shifting is an alternative
- algorithm for the case when the computed hull has more vertices than the specified vertex
- limit.
- :param shift_vertices: Convex hull input vertices are shifted to be around origin to provide better
- computation stability
- :param gauss_map_limit: Vertex limit beyond which additional acceleration structures are computed for each
- convex mesh. Increase that limit to reduce memory usage. Computing the extra structures
- all the time does not guarantee optimal performance.
- :param build_gpu_data: When true, additional information required for GPU-accelerated rigid body
- simulation is created. This can increase memory usage and cooking times for convex meshes
- and triangle meshes. Convex hulls are created with respect to GPU simulation limitations.
- Vertex limit is set to 64 and vertex limit per face is internally set to 32.
- :param physics_material: Configure which physics material to use.
- :return: The newly created mesh group.
"""
group = self.__add_physx_base_mesh_group(name, physics_material)
group["export method"] = 1
@@ -414,17 +635,27 @@ class SceneManifest():
primitive_shape_target: PrimitiveShape = PrimitiveShape.BEST_FIT,
volume_term_coefficient: float = 0.0,
physics_material: typing.Optional[str] = None) -> dict:
- """
- Adds a Primitive Shape type PhysX Mesh Group to the scene
+ """Adds a Primitive Shape type PhysX Mesh Group to the scene
+
+ Parameters
+ ----------
+ name :
+ Name of the mesh group.
+ primitive_shape_target :
+ The shape that should be fitted to this mesh. If BEST_FIT is selected, the
+ algorithm will determine which of the shapes fits best.
+ volume_term_coefficient :
+ This parameter controls how aggressively the primitive fitting algorithm will try
+ to minimize the volume of the fitted primitive. A value of 0 (no volume minimization) is
+ recommended for most meshes, especially those with moderate to high vertex counts.
+ physics_material :
+ Configure which physics material to use.
+
+ Returns
+ -------
+ dict
+ The newly created mesh group.
- :param name: Name of the mesh group.
- :param primitive_shape_target: The shape that should be fitted to this mesh. If BEST_FIT is selected, the
- algorithm will determine which of the shapes fits best.
- :param volume_term_coefficient: This parameter controls how aggressively the primitive fitting algorithm will try
- to minimize the volume of the fitted primitive. A value of 0 (no volume minimization) is
- recommended for most meshes, especially those with moderate to high vertex counts.
- :param physics_material: Configure which physics material to use.
- :return: The newly created mesh group.
"""
group = self.__add_physx_base_mesh_group(name, physics_material)
group["export method"] = 2
@@ -447,26 +678,40 @@ class SceneManifest():
convex_hull_downsampling: int = 4,
pca: bool = False,
project_hull_vertices: bool = True) -> None:
- """
- Enables and configures mesh decomposition for a PhysX Mesh Group.
+ """Enables and configures mesh decomposition for a PhysX Mesh Group.
Only valid for convex or primitive mesh types.
- :param mesh_group: Mesh group to configure decomposition for.
- :param max_convex_hulls: Controls the maximum number of hulls to generate.
- :param max_num_vertices_per_convex_hull: Controls the maximum number of triangles per convex hull.
- :param concavity: Maximum concavity of each approximate convex hull.
- :param resolution: Maximum number of voxels generated during the voxelization stage.
- :param mode: Select voxel-based approximate convex decomposition or tetrahedron-based
- approximate convex decomposition.
- :param alpha: Controls the bias toward clipping along symmetry planes.
- :param beta: Controls the bias toward clipping along revolution axes.
- :param min_volume_per_convex_hull: Controls the adaptive sampling of the generated convex hulls.
- :param plane_downsampling: Controls the granularity of the search for the best clipping plane.
- :param convex_hull_downsampling: Controls the precision of the convex hull generation process
- during the clipping plane selection stage.
- :param pca: Enable or disable normalizing the mesh before applying the convex decomposition.
- :param project_hull_vertices: Project the output convex hull vertices onto the original source mesh to increase
- the floating point accuracy of the results.
+ Parameters
+ ----------
+ mesh_group :
+ Mesh group to configure decomposition for.
+ max_convex_hulls :
+ Controls the maximum number of hulls to generate.
+ max_num_vertices_per_convex_hull :
+ Controls the maximum number of triangles per convex hull.
+ concavity :
+ Maximum concavity of each approximate convex hull.
+ resolution :
+ Maximum number of voxels generated during the voxelization stage.
+ mode :
+ Select voxel-based approximate convex decomposition or tetrahedron-based
+ approximate convex decomposition.
+ alpha :
+ Controls the bias toward clipping along symmetry planes.
+ beta :
+ Controls the bias toward clipping along revolution axes.
+ min_volume_per_convex_hull :
+ Controls the adaptive sampling of the generated convex hulls.
+ plane_downsampling :
+ Controls the granularity of the search for the best clipping plane.
+ convex_hull_downsampling :
+ Controls the precision of the convex hull generation process
+ during the clipping plane selection stage.
+ pca :
+ Enable or disable normalizing the mesh before applying the convex decomposition.
+ project_hull_vertices :
+ Project the output convex hull vertices onto the original source mesh to increase
+ the floating point accuracy of the results.
"""
mesh_group['DecomposeMeshes'] = True
mesh_group['ConvexDecompositionParams'] = {
@@ -485,41 +730,54 @@ class SceneManifest():
}
def physx_mesh_group_add_selected_node(self, mesh_group: dict, node: str) -> None:
- """
- Adds a node to the selected nodes list
+ """Adds a node to the selected nodes list
- :param mesh_group: Mesh group to add to.
- :param node: Node path to add.
+ Parameters
+ ----------
+ mesh_group :
+ Mesh group to add to.
+ node :
+ Node path to add.
"""
mesh_group['NodeSelectionList']['selectedNodes'].append(node)
def physx_mesh_group_add_unselected_node(self, mesh_group: dict, node: str) -> None:
- """
- Adds a node to the unselected nodes list
+ """Adds a node to the unselected nodes list
- :param mesh_group: Mesh group to add to.
- :param node: Node path to add.
+ Parameters
+ ----------
+ mesh_group :
+ Mesh group to add to.
+ node :
+ Node path to add.
"""
mesh_group['NodeSelectionList']['unselectedNodes'].append(node)
def physx_mesh_group_add_selected_unselected_nodes(self, mesh_group: dict, selected: typing.List[str],
unselected: typing.List[str]) -> None:
- """
- Adds a set of nodes to the selected/unselected node lists
+ """Adds a set of nodes to the selected/unselected node lists
- :param mesh_group: Mesh group to add to.
- :param selected: List of node paths to add to the selected list.
- :param unselected: List of node paths to add to the unselected list.
+ Parameters
+ ----------
+ mesh_group :
+ Mesh group to add to.
+ selected :
+ List of node paths to add to the selected list.
+ unselected :
+ List of node paths to add to the unselected list.
"""
mesh_group['NodeSelectionList']['selectedNodes'].extend(selected)
mesh_group['NodeSelectionList']['unselectedNodes'].extend(unselected)
def physx_mesh_group_add_comment(self, mesh_group: dict, comment: str) -> None:
- """
- Adds a comment rule
+ """Adds a comment rule
- :param mesh_group: Mesh group to add the rule to.
- :param comment: Comment string.
+ Parameters
+ ----------
+ mesh_group :
+ Mesh group to add the rule to.
+ comment :
+ Comment string.
"""
rule = {
"$type": "CommentRule",