Files
UnrealEngineUWP/Engine/Plugins/Experimental/MeshModelingToolsetExp/Source/MeshModelingToolsExp/Private/TransferMeshTool.cpp

191 lines
5.7 KiB
C++
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#include "TransferMeshTool.h"
#include "ComponentSourceInterfaces.h"
#include "InteractiveToolManager.h"
#include "ToolTargetManager.h"
#include "ToolBuilderUtil.h"
#include "ToolSetupUtil.h"
ModelingTools: Add support for reading and writing to a specific LOD via IMeshDescriptionProvider/Committer. Refactor various other aspects of MeshDescription access. Update MeshTransferTool to be able to transfer from and to specific LODs. Add new MeshTargetInterfaceTypes.h file, move EStaticMeshEditingLOD there and rename to EMeshLODIdentifier. Add FGetMeshParameters and FCommitMeshParameters types. IMeshDescriptionProvider::GetMeshDescription() now takes FGetMeshParameters to optionally specify LOD. Added IMeshDescriptionProvider::GetMeshDescriptionCopy() function, to handle copy-case. removed IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). This was only being used to force Tangents computation, which can now be done via GetMeshDescriptionCopy() and FGetMeshParameters.bWantMeshTangents option IMeshDescriptionCommitter commit functions now take a FCommitMeshParameters to optionally specify target LOD. StaticMeshComponentToolTarget::GetMeshDescriptionCopy() added, optionally computes auto-generated MeshDescription attributes on the copy StaticMesh(Component)ToolTarget updated to support FCommitMeshParameters target-LOD. SkeletalMesh, Volume, and DynamicMesh ToolTargets updated for new APIs but do not currently support any of the new LOD parameters. These should never be called w/ LOD parameters in the current codebase, ensures added to catch any errors (they would be non-fatal). UE::ToolTarget::GetMeshDescription() and GetMeshDescriptionCopy() in now take FGetMeshParameters argument. Removed bWantMeshTangents param to GetMeshDescriptionCopy(), now done via FGetMeshParameters. Updated call sites. TransferMeshesTool now supports specifying read and write LOD (numbered or HiRes) for StaticMeshComponent source/target, via above functions. TransferMeshesTool can now also target a new LOD in a StaticMeshComponent, index is 1 larger than current maximum source LOD. #rb lonnie.li, rinat.abdrashitov #rnx #jira none #preflight 61b8d56b2e65a1df046aa5e1 #ROBOMERGE-AUTHOR: ryan.schmidt #ROBOMERGE-SOURCE: CL 18461686 in //UE5/Release-5.0/... via CL 18461725 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v899-18417669) [CL 18461778 by ryan schmidt in ue5-release-engine-test branch]
2021-12-14 18:40:01 -05:00
#include "TargetInterfaces/StaticMeshBackedTarget.h"
#include "TargetInterfaces/MeshDescriptionProvider.h"
#include "TargetInterfaces/MeshDescriptionCommitter.h"
#include "ModelingToolTargetUtil.h"
ModelingTools: Add support for reading and writing to a specific LOD via IMeshDescriptionProvider/Committer. Refactor various other aspects of MeshDescription access. Update MeshTransferTool to be able to transfer from and to specific LODs. Add new MeshTargetInterfaceTypes.h file, move EStaticMeshEditingLOD there and rename to EMeshLODIdentifier. Add FGetMeshParameters and FCommitMeshParameters types. IMeshDescriptionProvider::GetMeshDescription() now takes FGetMeshParameters to optionally specify LOD. Added IMeshDescriptionProvider::GetMeshDescriptionCopy() function, to handle copy-case. removed IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). This was only being used to force Tangents computation, which can now be done via GetMeshDescriptionCopy() and FGetMeshParameters.bWantMeshTangents option IMeshDescriptionCommitter commit functions now take a FCommitMeshParameters to optionally specify target LOD. StaticMeshComponentToolTarget::GetMeshDescriptionCopy() added, optionally computes auto-generated MeshDescription attributes on the copy StaticMesh(Component)ToolTarget updated to support FCommitMeshParameters target-LOD. SkeletalMesh, Volume, and DynamicMesh ToolTargets updated for new APIs but do not currently support any of the new LOD parameters. These should never be called w/ LOD parameters in the current codebase, ensures added to catch any errors (they would be non-fatal). UE::ToolTarget::GetMeshDescription() and GetMeshDescriptionCopy() in now take FGetMeshParameters argument. Removed bWantMeshTangents param to GetMeshDescriptionCopy(), now done via FGetMeshParameters. Updated call sites. TransferMeshesTool now supports specifying read and write LOD (numbered or HiRes) for StaticMeshComponent source/target, via above functions. TransferMeshesTool can now also target a new LOD in a StaticMeshComponent, index is 1 larger than current maximum source LOD. #rb lonnie.li, rinat.abdrashitov #rnx #jira none #preflight 61b8d56b2e65a1df046aa5e1 #ROBOMERGE-AUTHOR: ryan.schmidt #ROBOMERGE-SOURCE: CL 18461686 in //UE5/Release-5.0/... via CL 18461725 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v899-18417669) [CL 18461778 by ryan schmidt in ue5-release-engine-test branch]
2021-12-14 18:40:01 -05:00
#include "Engine/StaticMesh.h"
using namespace UE::Geometry;
#define LOCTEXT_NAMESPACE "UTransferMeshTool"
/*
* ToolBuilder
*/
bool UTransferMeshToolBuilder::CanBuildTool(const FToolBuilderState& SceneState) const
{
return SceneState.TargetManager->CountSelectedAndTargetable(SceneState, GetTargetRequirements()) == 2;
}
UMultiSelectionMeshEditingTool* UTransferMeshToolBuilder::CreateNewTool(const FToolBuilderState& SceneState) const
{
return NewObject<UTransferMeshTool>(SceneState.ToolManager);
}
/*
* Tool
*/
void UTransferMeshTool::Setup()
{
UInteractiveTool::Setup();
BasicProperties = NewObject<UTransferMeshToolProperties>(this);
BasicProperties->RestoreProperties(this);
AddToolPropertySource(BasicProperties);
SetToolDisplayName(LOCTEXT("ToolName", "Transfer"));
GetToolManager()->DisplayMessage(
LOCTEXT("OnStartTool", "Copy Mesh from Source object to Target object"),
EToolMessageLevel::UserNotification);
ModelingTools: Add support for reading and writing to a specific LOD via IMeshDescriptionProvider/Committer. Refactor various other aspects of MeshDescription access. Update MeshTransferTool to be able to transfer from and to specific LODs. Add new MeshTargetInterfaceTypes.h file, move EStaticMeshEditingLOD there and rename to EMeshLODIdentifier. Add FGetMeshParameters and FCommitMeshParameters types. IMeshDescriptionProvider::GetMeshDescription() now takes FGetMeshParameters to optionally specify LOD. Added IMeshDescriptionProvider::GetMeshDescriptionCopy() function, to handle copy-case. removed IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). This was only being used to force Tangents computation, which can now be done via GetMeshDescriptionCopy() and FGetMeshParameters.bWantMeshTangents option IMeshDescriptionCommitter commit functions now take a FCommitMeshParameters to optionally specify target LOD. StaticMeshComponentToolTarget::GetMeshDescriptionCopy() added, optionally computes auto-generated MeshDescription attributes on the copy StaticMesh(Component)ToolTarget updated to support FCommitMeshParameters target-LOD. SkeletalMesh, Volume, and DynamicMesh ToolTargets updated for new APIs but do not currently support any of the new LOD parameters. These should never be called w/ LOD parameters in the current codebase, ensures added to catch any errors (they would be non-fatal). UE::ToolTarget::GetMeshDescription() and GetMeshDescriptionCopy() in now take FGetMeshParameters argument. Removed bWantMeshTangents param to GetMeshDescriptionCopy(), now done via FGetMeshParameters. Updated call sites. TransferMeshesTool now supports specifying read and write LOD (numbered or HiRes) for StaticMeshComponent source/target, via above functions. TransferMeshesTool can now also target a new LOD in a StaticMeshComponent, index is 1 larger than current maximum source LOD. #rb lonnie.li, rinat.abdrashitov #rnx #jira none #preflight 61b8d56b2e65a1df046aa5e1 #ROBOMERGE-AUTHOR: ryan.schmidt #ROBOMERGE-SOURCE: CL 18461686 in //UE5/Release-5.0/... via CL 18461725 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v899-18417669) [CL 18461778 by ryan schmidt in ue5-release-engine-test branch]
2021-12-14 18:40:01 -05:00
// currently we can only query available LODs via the UStaticMesh, improvements TBD
#if WITH_EDITOR
if (IStaticMeshBackedTarget* StaticMeshTarget = Cast<IStaticMeshBackedTarget>(Targets[0]))
{
if (UStaticMesh* StaticMesh = StaticMeshTarget->GetStaticMesh())
{
BasicProperties->bIsStaticMeshSource = true;
int32 NumSourceModels = StaticMesh->GetNumSourceModels();
for (int32 si = 0; si < NumSourceModels; ++si)
{
if (StaticMesh->IsMeshDescriptionValid(si))
{
BasicProperties->SourceLODNamesList.Add(FString::Printf(TEXT("LOD %d"), si));
BasicProperties->SourceLODEnums.Add(static_cast<EMeshLODIdentifier>(si));
}
}
// hires LOD slot
if (StaticMesh->IsHiResMeshDescriptionValid())
{
BasicProperties->SourceLODNamesList.Add(TEXT("HiRes"));
BasicProperties->SourceLODEnums.Add(EMeshLODIdentifier::HiResSource);
}
BasicProperties->SourceLOD = BasicProperties->SourceLODNamesList[0];
}
}
if (IStaticMeshBackedTarget* StaticMeshTarget = Cast<IStaticMeshBackedTarget>(Targets[1]))
{
if (UStaticMesh* StaticMesh = StaticMeshTarget->GetStaticMesh())
{
BasicProperties->bIsStaticMeshTarget = true;
int32 NumSourceModels = StaticMesh->GetNumSourceModels();
for (int32 si = 0; si < NumSourceModels; ++si)
{
BasicProperties->TargetLODNamesList.Add( FString::Printf(TEXT("LOD %d"), si) );
BasicProperties->TargetLODEnums.Add(static_cast<EMeshLODIdentifier>(si));
}
// option to add one additional lod
if (NumSourceModels <= 7)
{
BasicProperties->TargetLODNamesList.Add(FString::Printf(TEXT("LOD %d (New)"), NumSourceModels));
BasicProperties->TargetLODEnums.Add(static_cast<EMeshLODIdentifier>(NumSourceModels));
}
// hires LOD slot
BasicProperties->TargetLODNamesList.Add(TEXT("HiRes"));
BasicProperties->TargetLODEnums.Add(EMeshLODIdentifier::HiResSource);
BasicProperties->TargetLOD = BasicProperties->TargetLODNamesList[0];
}
}
#endif
}
bool UTransferMeshTool::CanAccept() const
{
return Super::CanAccept();
}
void UTransferMeshTool::OnShutdown(EToolShutdownType ShutdownType)
{
BasicProperties->SaveProperties(this);
if (ShutdownType == EToolShutdownType::Accept)
{
GetToolManager()->BeginUndoTransaction(LOCTEXT("TransferMeshToolTransactionName", "Transfer Mesh"));
FComponentMaterialSet Materials = UE::ToolTarget::GetMaterialSet(Targets[0]);
const FComponentMaterialSet* TransferMaterials = (BasicProperties->bTransferMaterials) ? &Materials : nullptr;
ModelingTools: Add support for reading and writing to a specific LOD via IMeshDescriptionProvider/Committer. Refactor various other aspects of MeshDescription access. Update MeshTransferTool to be able to transfer from and to specific LODs. Add new MeshTargetInterfaceTypes.h file, move EStaticMeshEditingLOD there and rename to EMeshLODIdentifier. Add FGetMeshParameters and FCommitMeshParameters types. IMeshDescriptionProvider::GetMeshDescription() now takes FGetMeshParameters to optionally specify LOD. Added IMeshDescriptionProvider::GetMeshDescriptionCopy() function, to handle copy-case. removed IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). This was only being used to force Tangents computation, which can now be done via GetMeshDescriptionCopy() and FGetMeshParameters.bWantMeshTangents option IMeshDescriptionCommitter commit functions now take a FCommitMeshParameters to optionally specify target LOD. StaticMeshComponentToolTarget::GetMeshDescriptionCopy() added, optionally computes auto-generated MeshDescription attributes on the copy StaticMesh(Component)ToolTarget updated to support FCommitMeshParameters target-LOD. SkeletalMesh, Volume, and DynamicMesh ToolTargets updated for new APIs but do not currently support any of the new LOD parameters. These should never be called w/ LOD parameters in the current codebase, ensures added to catch any errors (they would be non-fatal). UE::ToolTarget::GetMeshDescription() and GetMeshDescriptionCopy() in now take FGetMeshParameters argument. Removed bWantMeshTangents param to GetMeshDescriptionCopy(), now done via FGetMeshParameters. Updated call sites. TransferMeshesTool now supports specifying read and write LOD (numbered or HiRes) for StaticMeshComponent source/target, via above functions. TransferMeshesTool can now also target a new LOD in a StaticMeshComponent, index is 1 larger than current maximum source LOD. #rb lonnie.li, rinat.abdrashitov #rnx #jira none #preflight 61b8d56b2e65a1df046aa5e1 #ROBOMERGE-AUTHOR: ryan.schmidt #ROBOMERGE-SOURCE: CL 18461686 in //UE5/Release-5.0/... via CL 18461725 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v899-18417669) [CL 18461778 by ryan schmidt in ue5-release-engine-test branch]
2021-12-14 18:40:01 -05:00
FMeshDescription SourceMesh;
FGetMeshParameters GetMeshParams;
GetMeshParams.bWantMeshTangents = true;
if (IMeshDescriptionProvider* MeshDescriptionProvider = Cast<IMeshDescriptionProvider>(Targets[0]))
{
ModelingTools: Add support for reading and writing to a specific LOD via IMeshDescriptionProvider/Committer. Refactor various other aspects of MeshDescription access. Update MeshTransferTool to be able to transfer from and to specific LODs. Add new MeshTargetInterfaceTypes.h file, move EStaticMeshEditingLOD there and rename to EMeshLODIdentifier. Add FGetMeshParameters and FCommitMeshParameters types. IMeshDescriptionProvider::GetMeshDescription() now takes FGetMeshParameters to optionally specify LOD. Added IMeshDescriptionProvider::GetMeshDescriptionCopy() function, to handle copy-case. removed IMeshDescriptionProvider::CalculateAutoGeneratedAttributes(). This was only being used to force Tangents computation, which can now be done via GetMeshDescriptionCopy() and FGetMeshParameters.bWantMeshTangents option IMeshDescriptionCommitter commit functions now take a FCommitMeshParameters to optionally specify target LOD. StaticMeshComponentToolTarget::GetMeshDescriptionCopy() added, optionally computes auto-generated MeshDescription attributes on the copy StaticMesh(Component)ToolTarget updated to support FCommitMeshParameters target-LOD. SkeletalMesh, Volume, and DynamicMesh ToolTargets updated for new APIs but do not currently support any of the new LOD parameters. These should never be called w/ LOD parameters in the current codebase, ensures added to catch any errors (they would be non-fatal). UE::ToolTarget::GetMeshDescription() and GetMeshDescriptionCopy() in now take FGetMeshParameters argument. Removed bWantMeshTangents param to GetMeshDescriptionCopy(), now done via FGetMeshParameters. Updated call sites. TransferMeshesTool now supports specifying read and write LOD (numbered or HiRes) for StaticMeshComponent source/target, via above functions. TransferMeshesTool can now also target a new LOD in a StaticMeshComponent, index is 1 larger than current maximum source LOD. #rb lonnie.li, rinat.abdrashitov #rnx #jira none #preflight 61b8d56b2e65a1df046aa5e1 #ROBOMERGE-AUTHOR: ryan.schmidt #ROBOMERGE-SOURCE: CL 18461686 in //UE5/Release-5.0/... via CL 18461725 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v899-18417669) [CL 18461778 by ryan schmidt in ue5-release-engine-test branch]
2021-12-14 18:40:01 -05:00
FString SelectedLOD = BasicProperties->SourceLOD;
if (SelectedLOD.StartsWith(TEXT("HiRes")))
{
GetMeshParams.bHaveRequestLOD = true;
GetMeshParams.RequestLOD = EMeshLODIdentifier::HiResSource;
}
else
{
int32 FoundIndex = BasicProperties->SourceLODNamesList.IndexOfByKey(BasicProperties->SourceLOD);
if (FoundIndex != INDEX_NONE)
{
GetMeshParams.bHaveRequestLOD = true;
GetMeshParams.RequestLOD = BasicProperties->SourceLODEnums[FoundIndex];
}
}
}
SourceMesh = UE::ToolTarget::GetMeshDescriptionCopy(Targets[0], GetMeshParams);
IMeshDescriptionCommitter* MeshDescriptionCommitter = Cast<IMeshDescriptionCommitter>(Targets[1]);
if (BasicProperties->bIsStaticMeshTarget && MeshDescriptionCommitter)
{
FCommitMeshParameters CommitParams;
FString SelectedLOD = BasicProperties->TargetLOD;
if (SelectedLOD.StartsWith(TEXT("HiRes")))
{
CommitParams.bHaveTargetLOD = true;
CommitParams.TargetLOD = EMeshLODIdentifier::HiResSource;
}
else
{
int32 FoundIndex = BasicProperties->TargetLODNamesList.IndexOfByKey(BasicProperties->TargetLOD);
if (FoundIndex != INDEX_NONE)
{
CommitParams.bHaveTargetLOD = true;
CommitParams.TargetLOD = BasicProperties->TargetLODEnums[FoundIndex];
}
}
if (TransferMaterials)
{
UE::ToolTarget::CommitMaterialSetUpdate(Targets[1], *TransferMaterials, true);
}
MeshDescriptionCommitter->CommitMeshDescription(MoveTemp(SourceMesh), CommitParams);
}
else
{
UE::ToolTarget::CommitMeshDescriptionUpdate(Targets[1], &SourceMesh, TransferMaterials);
}
GetToolManager()->EndUndoTransaction();
}
}
#undef LOCTEXT_NAMESPACE