Files
integration/Plugins/UEWingman/Deprecated/UMCPHandler_DeleteMaterialExpression.h

127 lines
3.8 KiB
C
Raw Normal View History

2026-03-08 22:17:14 -04:00
#pragma once
#include "CoreMinimal.h"
#include "MCPHandler.h"
2026-03-13 14:26:04 -04:00
#include "MCPAssets.h"
2026-03-08 22:17:14 -04:00
#include "MCPUtils.h"
#include "Materials/Material.h"
#include "Materials/MaterialExpression.h"
2026-03-10 07:17:42 -04:00
#include "Materials/MaterialFunction.h"
2026-03-08 22:17:14 -04:00
#include "MaterialGraph/MaterialGraph.h"
#include "MaterialGraph/MaterialGraphNode.h"
#include "UMCPHandler_DeleteMaterialExpression.generated.h"
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
2026-03-11 22:03:32 -04:00
UCLASS(meta=(Group="Unclassified"))
2026-03-08 22:17:14 -04:00
class UMCPHandler_DeleteMaterialExpression : public UObject, public IMCPHandler
{
GENERATED_BODY()
public:
UPROPERTY(meta=(Optional, Description="Material name or package path (specify this or materialFunction)"))
FString Material;
UPROPERTY(meta=(Optional, Description="Material function name or package path (specify this or material)"))
FString MaterialFunction;
2026-03-10 07:17:42 -04:00
UPROPERTY(meta=(Description="Expression name (use FormatName from DumpMaterial output)"))
2026-03-08 22:17:14 -04:00
FString Node;
UPROPERTY(meta=(Optional, Description="If true, preview the change without applying it"))
bool DryRun = false;
virtual FString GetDescription() const override
{
return TEXT("Remove an expression node from a material or material function graph.");
}
2026-03-10 07:17:42 -04:00
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
2026-03-08 22:17:14 -04:00
{
if (Material.IsEmpty() && MaterialFunction.IsEmpty())
{
2026-03-10 07:17:42 -04:00
MCPErrorCallback(Result).SetError(TEXT("Specify 'material' or 'materialFunction'."));
return;
2026-03-08 22:17:14 -04:00
}
// Load material or material function
UMaterial* MaterialObj = nullptr;
UMaterialFunction* MatFunc = nullptr;
if (!MaterialFunction.IsEmpty())
{
MCPAssets<UMaterialFunction> MFAssets;
if (!MFAssets.Exact(MaterialFunction).Errors(Result).ENone().ETwo().Load()) return;
MatFunc = MFAssets.Object();
}
else
{
MCPAssets<UMaterial> MatAssets;
if (!MatAssets.Exact(Material).Errors(Result).ENone().ETwo().Load()) return;
MaterialObj = MatAssets.Object();
}
if (MaterialObj) MCPUtils::EnsureMaterialGraph(MaterialObj);
UEdGraph* Graph = MaterialObj ? (UEdGraph*)MaterialObj->MaterialGraph : (MatFunc ? MatFunc->MaterialGraph : nullptr);
if (!Graph)
{
2026-03-10 07:17:42 -04:00
MCPErrorCallback(Result).SetError(TEXT("Asset has no material graph."));
return;
2026-03-08 22:17:14 -04:00
}
2026-03-10 07:17:42 -04:00
// Find node by name
2026-03-08 22:17:14 -04:00
UMaterialGraphNode* TargetMatNode = nullptr;
for (UEdGraphNode* GraphNode : Graph->Nodes)
{
if (!GraphNode) continue;
2026-03-10 07:17:42 -04:00
UMaterialGraphNode* MatNode = Cast<UMaterialGraphNode>(GraphNode);
if (!MatNode || !MatNode->MaterialExpression) continue;
if (MCPUtils::Identifies(Node, MatNode->MaterialExpression))
2026-03-08 22:17:14 -04:00
{
2026-03-10 07:17:42 -04:00
TargetMatNode = MatNode;
2026-03-08 22:17:14 -04:00
break;
}
}
if (!TargetMatNode)
{
2026-03-10 07:17:42 -04:00
MCPErrorCallback(Result).SetError(FString::Printf(TEXT("Expression '%s' not found."), *Node));
return;
2026-03-08 22:17:14 -04:00
}
2026-03-10 07:17:42 -04:00
FString ExprName = MCPUtils::FormatName(TargetMatNode->MaterialExpression);
2026-03-08 22:17:14 -04:00
if (DryRun)
{
2026-03-10 07:17:42 -04:00
Result.Appendf(TEXT("DryRun: would delete %s\n"), *ExprName);
2026-03-08 22:17:14 -04:00
return;
}
// Remove the expression
UMaterialExpression* ExprToRemove = TargetMatNode->MaterialExpression;
if (MaterialObj)
MaterialObj->GetExpressionCollection().RemoveExpression(ExprToRemove);
else
MatFunc->GetExpressionCollection().RemoveExpression(ExprToRemove);
ExprToRemove->MarkAsGarbage();
// Rebuild graph
Graph->NotifyGraphChanged();
UObject* Asset = MaterialObj ? (UObject*)MaterialObj : (UObject*)MatFunc;
Asset->PreEditChange(nullptr);
Asset->PostEditChange();
Asset->MarkPackageDirty();
// Save
bool bSaved = MaterialObj ? MCPUtils::SaveMaterialPackage(MaterialObj) : MCPUtils::SaveGenericPackage(MatFunc);
2026-03-10 07:17:42 -04:00
Result.Appendf(TEXT("Deleted %s"), *ExprName);
if (!bSaved) Result.Append(TEXT(" (save failed)"));
Result.Append(TEXT("\n"));
2026-03-08 22:17:14 -04:00
}
};