2019-12-27 09:26:59 -05:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
2019-10-01 20:41:42 -04:00
|
|
|
|
|
|
|
|
#include "ParameterizeMeshTool.h"
|
|
|
|
|
#include "InteractiveToolManager.h"
|
|
|
|
|
#include "ToolBuilderUtil.h"
|
|
|
|
|
#include "ToolSetupUtil.h"
|
2021-06-11 22:42:32 -04:00
|
|
|
#include "ModelingToolTargetUtil.h"
|
2021-06-20 17:01:49 -04:00
|
|
|
#include "DynamicMesh/DynamicMesh3.h"
|
|
|
|
|
#include "ParameterizationOps/ParameterizeMeshOp.h"
|
2021-09-08 19:51:00 -04:00
|
|
|
#include "Properties/ParameterizeMeshProperties.h"
|
2021-03-24 11:11:02 -04:00
|
|
|
|
2021-03-09 19:33:56 -04:00
|
|
|
using namespace UE::Geometry;
|
2019-10-01 20:41:42 -04:00
|
|
|
|
2021-03-09 19:33:56 -04:00
|
|
|
#define LOCTEXT_NAMESPACE "UParameterizeMeshTool"
|
2019-10-01 20:41:42 -04:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ToolBuilder
|
|
|
|
|
*/
|
|
|
|
|
|
2021-03-24 11:11:02 -04:00
|
|
|
USingleSelectionMeshEditingTool* UParameterizeMeshToolBuilder::CreateNewTool(const FToolBuilderState& SceneState) const
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
|
|
|
|
UParameterizeMeshTool* NewTool = NewObject<UParameterizeMeshTool>(SceneState.ToolManager);
|
|
|
|
|
return NewTool;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Tool
|
|
|
|
|
*/
|
2020-01-27 20:11:15 -05:00
|
|
|
|
|
|
|
|
|
2019-10-01 20:41:42 -04:00
|
|
|
void UParameterizeMeshTool::Setup()
|
|
|
|
|
{
|
|
|
|
|
UInteractiveTool::Setup();
|
|
|
|
|
|
2021-06-20 17:01:49 -04:00
|
|
|
InputMesh = MakeShared<FDynamicMesh3, ESPMode::ThreadSafe>();
|
|
|
|
|
*InputMesh = UE::ToolTarget::GetDynamicMeshCopy(Target);
|
2021-08-24 16:38:45 -04:00
|
|
|
FTransform InputTransform = (FTransform)UE::ToolTarget::GetLocalToWorldTransform(Target);
|
|
|
|
|
FComponentMaterialSet MaterialSet = UE::ToolTarget::GetMaterialSet(Target);
|
2019-10-01 20:41:42 -04:00
|
|
|
|
2021-06-20 17:01:49 -04:00
|
|
|
Preview = NewObject<UMeshOpPreviewWithBackgroundCompute>(this);
|
2022-01-28 10:18:10 -05:00
|
|
|
Preview->Setup(GetTargetWorld(), this);
|
2021-10-07 22:25:54 -04:00
|
|
|
ToolSetupUtil::ApplyRenderingConfigurationToPreview(Preview->PreviewMesh, nullptr);
|
2021-06-11 22:42:32 -04:00
|
|
|
Preview->PreviewMesh->SetTangentsMode(EDynamicMeshComponentTangentsMode::AutoCalculated);
|
2021-06-20 17:01:49 -04:00
|
|
|
Preview->PreviewMesh->ReplaceMesh(*InputMesh);
|
2021-08-24 16:38:45 -04:00
|
|
|
Preview->ConfigureMaterials(MaterialSet.Materials, ToolSetupUtil::GetDefaultWorkingMaterial(GetToolManager()));
|
|
|
|
|
Preview->PreviewMesh->SetTransform(InputTransform);
|
2020-09-24 00:43:27 -04:00
|
|
|
|
2021-02-02 13:26:23 -04:00
|
|
|
Preview->OnMeshUpdated.AddLambda([this](UMeshOpPreviewWithBackgroundCompute* Op)
|
|
|
|
|
{
|
2021-08-24 16:38:45 -04:00
|
|
|
OnPreviewMeshUpdated();
|
2021-02-02 13:26:23 -04:00
|
|
|
});
|
|
|
|
|
|
2021-06-20 17:01:49 -04:00
|
|
|
UE::ToolTarget::HideSourceObject(Target);
|
2020-01-27 20:11:15 -05:00
|
|
|
|
|
|
|
|
// initialize our properties
|
2021-02-02 13:26:23 -04:00
|
|
|
|
|
|
|
|
UVChannelProperties = NewObject<UMeshUVChannelProperties>(this);
|
|
|
|
|
UVChannelProperties->RestoreProperties(this);
|
2021-06-20 17:01:49 -04:00
|
|
|
UVChannelProperties->Initialize(InputMesh.Get(), false);
|
2021-02-02 13:26:23 -04:00
|
|
|
UVChannelProperties->ValidateSelection(true);
|
|
|
|
|
UVChannelProperties->WatchProperty(UVChannelProperties->UVChannel, [this](const FString& NewValue)
|
|
|
|
|
{
|
2021-11-18 20:41:17 -05:00
|
|
|
MaterialSettings->UpdateUVChannels(UVChannelProperties->UVChannelNamesList.IndexOfByKey(UVChannelProperties->UVChannel),
|
|
|
|
|
UVChannelProperties->UVChannelNamesList);
|
2021-02-02 13:26:23 -04:00
|
|
|
});
|
|
|
|
|
AddToolPropertySource(UVChannelProperties);
|
|
|
|
|
|
2020-01-27 20:11:15 -05:00
|
|
|
Settings = NewObject<UParameterizeMeshToolProperties>(this);
|
|
|
|
|
Settings->RestoreProperties(this);
|
|
|
|
|
AddToolPropertySource(Settings);
|
2021-06-20 17:01:49 -04:00
|
|
|
Settings->WatchProperty(Settings->Method, [&](EParameterizeMeshUVMethod) { OnMethodTypeChanged(); });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UVAtlasProperties = NewObject<UParameterizeMeshToolUVAtlasProperties>(this);
|
|
|
|
|
UVAtlasProperties->RestoreProperties(this);
|
|
|
|
|
AddToolPropertySource(UVAtlasProperties);
|
|
|
|
|
SetToolPropertySourceEnabled(UVAtlasProperties, false);
|
|
|
|
|
|
|
|
|
|
XAtlasProperties = NewObject<UParameterizeMeshToolXAtlasProperties>(this);
|
|
|
|
|
XAtlasProperties->RestoreProperties(this);
|
|
|
|
|
AddToolPropertySource(XAtlasProperties);
|
|
|
|
|
SetToolPropertySourceEnabled(XAtlasProperties, false);
|
2020-01-27 20:11:15 -05:00
|
|
|
|
2021-08-24 16:38:45 -04:00
|
|
|
PatchBuilderProperties = NewObject<UParameterizeMeshToolPatchBuilderProperties>(this);
|
|
|
|
|
PatchBuilderProperties->RestoreProperties(this);
|
|
|
|
|
AddToolPropertySource(PatchBuilderProperties);
|
|
|
|
|
SetToolPropertySourceEnabled(PatchBuilderProperties, false);
|
|
|
|
|
|
2021-09-15 22:44:16 -04:00
|
|
|
PolygroupLayerProperties = NewObject<UParameterizeMeshToolPatchBuilderGroupLayerProperties>(this);
|
|
|
|
|
PolygroupLayerProperties->RestoreProperties(this, TEXT("ModelingUVTools") );
|
|
|
|
|
PolygroupLayerProperties->InitializeGroupLayers(InputMesh.Get());
|
|
|
|
|
AddToolPropertySource(PolygroupLayerProperties);
|
|
|
|
|
SetToolPropertySourceEnabled(PolygroupLayerProperties, false);
|
|
|
|
|
|
2021-08-24 16:38:45 -04:00
|
|
|
|
2019-10-01 20:41:42 -04:00
|
|
|
MaterialSettings = NewObject<UExistingMeshMaterialProperties>(this);
|
2021-06-20 17:01:49 -04:00
|
|
|
MaterialSettings->MaterialMode = ESetMeshMaterialMode::Checkerboard;
|
|
|
|
|
MaterialSettings->RestoreProperties(this, TEXT("ModelingUVTools"));
|
2019-10-01 20:41:42 -04:00
|
|
|
AddToolPropertySource(MaterialSettings);
|
2019-12-19 18:07:47 -05:00
|
|
|
// force update
|
|
|
|
|
MaterialSettings->UpdateMaterials();
|
|
|
|
|
Preview->OverrideMaterial = MaterialSettings->GetActiveOverrideMaterial();
|
2019-10-01 20:41:42 -04:00
|
|
|
|
2021-08-24 16:38:45 -04:00
|
|
|
if (bCreateUVLayoutViewOnSetup)
|
|
|
|
|
{
|
|
|
|
|
UVLayoutView = NewObject<UUVLayoutPreview>(this);
|
2022-01-28 10:18:10 -05:00
|
|
|
UVLayoutView->CreateInWorld(GetTargetWorld());
|
2021-08-24 16:38:45 -04:00
|
|
|
UVLayoutView->SetSourceMaterials(MaterialSet);
|
|
|
|
|
UVLayoutView->SetSourceWorldPosition(InputTransform, UE::ToolTarget::GetTargetActor(Target)->GetComponentsBoundingBox());
|
2021-11-18 20:41:17 -05:00
|
|
|
UVLayoutView->Settings->bEnabled = false;
|
2021-08-24 16:38:45 -04:00
|
|
|
UVLayoutView->Settings->bShowWireframe = false;
|
|
|
|
|
UVLayoutView->Settings->RestoreProperties(this, TEXT("ParameterizeMeshTool"));
|
|
|
|
|
AddToolPropertySource(UVLayoutView->Settings);
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-01 20:41:42 -04:00
|
|
|
Preview->InvalidateResult(); // start compute
|
2020-09-24 00:43:27 -04:00
|
|
|
|
2021-06-20 17:01:49 -04:00
|
|
|
SetToolDisplayName(LOCTEXT("ToolNameGlobal", "AutoUV"));
|
|
|
|
|
GetToolManager()->DisplayMessage(
|
|
|
|
|
LOCTEXT("OnStartTool_Global", "Automatically partition the selected Mesh into UV islands, flatten, and pack into a single UV chart"),
|
|
|
|
|
EToolMessageLevel::UserNotification);
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|
|
|
|
|
|
2020-01-07 15:54:23 -05:00
|
|
|
void UParameterizeMeshTool::OnPropertyModified(UObject* PropertySet, FProperty* Property)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2021-08-24 16:38:45 -04:00
|
|
|
if (PropertySet == UVChannelProperties
|
|
|
|
|
|| PropertySet == Settings
|
|
|
|
|
|| PropertySet == UVAtlasProperties
|
|
|
|
|
|| PropertySet == XAtlasProperties
|
2021-09-15 22:44:16 -04:00
|
|
|
|| PropertySet == PatchBuilderProperties
|
|
|
|
|
|| PropertySet == PolygroupLayerProperties)
|
2019-12-19 18:07:47 -05:00
|
|
|
{
|
|
|
|
|
Preview->InvalidateResult();
|
2021-02-02 13:26:23 -04:00
|
|
|
}
|
|
|
|
|
|
2021-06-20 17:01:49 -04:00
|
|
|
MaterialSettings->UpdateMaterials();
|
|
|
|
|
Preview->OverrideMaterial = MaterialSettings->GetActiveOverrideMaterial();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void UParameterizeMeshTool::OnMethodTypeChanged()
|
|
|
|
|
{
|
|
|
|
|
SetToolPropertySourceEnabled(UVAtlasProperties, Settings->Method == EParameterizeMeshUVMethod::UVAtlas);
|
|
|
|
|
SetToolPropertySourceEnabled(XAtlasProperties, Settings->Method == EParameterizeMeshUVMethod::XAtlas);
|
2021-08-24 16:38:45 -04:00
|
|
|
SetToolPropertySourceEnabled(PatchBuilderProperties, Settings->Method == EParameterizeMeshUVMethod::PatchBuilder);
|
2021-09-15 22:44:16 -04:00
|
|
|
SetToolPropertySourceEnabled(PolygroupLayerProperties, Settings->Method == EParameterizeMeshUVMethod::PatchBuilder);
|
2021-06-20 17:01:49 -04:00
|
|
|
|
|
|
|
|
Preview->InvalidateResult();
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-01-28 18:40:54 -05:00
|
|
|
void UParameterizeMeshTool::OnShutdown(EToolShutdownType ShutdownType)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2021-08-24 16:38:45 -04:00
|
|
|
if (UVLayoutView)
|
|
|
|
|
{
|
2021-09-08 16:59:29 -04:00
|
|
|
UVLayoutView->Settings->SaveProperties(this, TEXT("ParameterizeMeshTool"));
|
2021-08-24 16:38:45 -04:00
|
|
|
UVLayoutView->Disconnect();
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-02 13:26:23 -04:00
|
|
|
UVChannelProperties->SaveProperties(this);
|
2019-12-19 18:07:47 -05:00
|
|
|
Settings->SaveProperties(this);
|
2021-06-20 17:01:49 -04:00
|
|
|
MaterialSettings->SaveProperties(this, TEXT("ModelingUVTools"));
|
2021-08-24 16:38:45 -04:00
|
|
|
UVAtlasProperties->SaveProperties(this);
|
|
|
|
|
XAtlasProperties->SaveProperties(this);
|
|
|
|
|
PatchBuilderProperties->SaveProperties(this);
|
2021-09-15 22:44:16 -04:00
|
|
|
PolygroupLayerProperties->SaveProperties(this, TEXT("ModelingUVTools"));
|
2021-02-02 13:26:23 -04:00
|
|
|
|
2019-10-02 12:05:44 -04:00
|
|
|
FDynamicMeshOpResult Result = Preview->Shutdown();
|
2021-03-11 21:27:23 -04:00
|
|
|
|
|
|
|
|
// Restore (unhide) the source meshes
|
2021-06-20 17:01:49 -04:00
|
|
|
UE::ToolTarget::ShowSourceObject(Target);
|
2021-03-11 21:27:23 -04:00
|
|
|
|
2019-10-01 20:41:42 -04:00
|
|
|
if (ShutdownType == EToolShutdownType::Accept)
|
|
|
|
|
{
|
2021-06-20 17:01:49 -04:00
|
|
|
GetToolManager()->BeginUndoTransaction(LOCTEXT("ParameterizeMesh", "Auto UVs"));
|
|
|
|
|
FDynamicMesh3* NewDynamicMesh = Result.Mesh.Get();
|
|
|
|
|
if (ensure(NewDynamicMesh))
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2021-06-20 17:01:49 -04:00
|
|
|
UE::ToolTarget::CommitDynamicMeshUVUpdate(Target, NewDynamicMesh);
|
|
|
|
|
}
|
2019-10-01 20:41:42 -04:00
|
|
|
GetToolManager()->EndUndoTransaction();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-24 16:38:45 -04:00
|
|
|
void UParameterizeMeshTool::Render(IToolsContextRenderAPI* RenderAPI)
|
|
|
|
|
{
|
|
|
|
|
if (UVLayoutView)
|
|
|
|
|
{
|
|
|
|
|
UVLayoutView->Render(RenderAPI);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-18 18:42:59 -04:00
|
|
|
void UParameterizeMeshTool::OnTick(float DeltaTime)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
|
|
|
|
Preview->Tick(DeltaTime);
|
2021-08-24 16:38:45 -04:00
|
|
|
|
|
|
|
|
if (UVLayoutView)
|
|
|
|
|
{
|
|
|
|
|
UVLayoutView->OnTick(DeltaTime);
|
|
|
|
|
}
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool UParameterizeMeshTool::CanAccept() const
|
|
|
|
|
{
|
2020-11-24 18:42:39 -04:00
|
|
|
return Super::CanAccept() && Preview->HaveValidResult();
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|
|
|
|
|
|
2019-10-04 14:13:21 -04:00
|
|
|
TUniquePtr<FDynamicMeshOperator> UParameterizeMeshTool::MakeNewOperator()
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2020-09-24 00:43:27 -04:00
|
|
|
TUniquePtr<FParameterizeMeshOp> ParameterizeMeshOp = MakeUnique<FParameterizeMeshOp>();
|
2021-06-20 17:01:49 -04:00
|
|
|
|
2020-09-24 00:43:27 -04:00
|
|
|
ParameterizeMeshOp->InputMesh = InputMesh;
|
2021-02-02 13:26:23 -04:00
|
|
|
ParameterizeMeshOp->UVLayer = UVChannelProperties->GetSelectedChannelIndex(true);
|
2021-03-04 14:35:19 -04:00
|
|
|
ParameterizeMeshOp->Method = (EParamOpBackend)(int)Settings->Method;
|
|
|
|
|
|
2021-06-20 17:01:49 -04:00
|
|
|
// uvatlas options
|
2022-01-07 00:14:44 -05:00
|
|
|
ParameterizeMeshOp->Stretch = UVAtlasProperties->IslandStretch;
|
|
|
|
|
ParameterizeMeshOp->NumCharts = UVAtlasProperties->NumIslands;
|
2022-01-13 17:25:17 -05:00
|
|
|
if (Settings->Method == EParameterizeMeshUVMethod::UVAtlas)
|
|
|
|
|
{
|
|
|
|
|
ParameterizeMeshOp->Width = ParameterizeMeshOp->Height = UVAtlasProperties->TextureResolution;
|
|
|
|
|
}
|
2021-06-20 17:01:49 -04:00
|
|
|
|
|
|
|
|
// xatlas options
|
|
|
|
|
ParameterizeMeshOp->XAtlasMaxIterations = XAtlasProperties->MaxIterations;
|
|
|
|
|
|
2021-08-24 16:38:45 -04:00
|
|
|
// patchbuilder options
|
|
|
|
|
ParameterizeMeshOp->InitialPatchCount = PatchBuilderProperties->InitialPatches;
|
2021-09-15 22:44:16 -04:00
|
|
|
ParameterizeMeshOp->bRespectInputGroups = PolygroupLayerProperties->bConstrainToPolygroups;
|
|
|
|
|
if (PolygroupLayerProperties->bConstrainToPolygroups)
|
|
|
|
|
{
|
|
|
|
|
ParameterizeMeshOp->InputGroupLayer = PolygroupLayerProperties->GetSelectedLayer(*InputMesh);
|
|
|
|
|
}
|
2021-08-24 16:38:45 -04:00
|
|
|
ParameterizeMeshOp->PatchCurvatureAlignmentWeight = PatchBuilderProperties->CurvatureAlignment;
|
2022-01-07 00:14:44 -05:00
|
|
|
ParameterizeMeshOp->PatchMergingMetricThresh = PatchBuilderProperties->MergingDistortionThreshold;
|
|
|
|
|
ParameterizeMeshOp->PatchMergingAngleThresh = PatchBuilderProperties->MergingAngleThreshold;
|
2021-08-24 16:38:45 -04:00
|
|
|
ParameterizeMeshOp->ExpMapNormalSmoothingSteps = PatchBuilderProperties->SmoothingSteps;
|
|
|
|
|
ParameterizeMeshOp->ExpMapNormalSmoothingAlpha = PatchBuilderProperties->SmoothingAlpha;
|
2022-01-07 00:14:44 -05:00
|
|
|
ParameterizeMeshOp->bEnablePacking = PatchBuilderProperties->bRepack;
|
2022-01-13 17:25:17 -05:00
|
|
|
if (Settings->Method == EParameterizeMeshUVMethod::PatchBuilder)
|
|
|
|
|
{
|
|
|
|
|
ParameterizeMeshOp->Width = ParameterizeMeshOp->Height = PatchBuilderProperties->TextureResolution;
|
|
|
|
|
}
|
2021-08-24 16:38:45 -04:00
|
|
|
|
2021-06-20 17:01:49 -04:00
|
|
|
ParameterizeMeshOp->SetTransform(UE::ToolTarget::GetLocalToWorldTransform(Target));
|
2019-10-01 20:41:42 -04:00
|
|
|
|
2020-09-24 00:43:27 -04:00
|
|
|
return ParameterizeMeshOp;
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-08-24 16:38:45 -04:00
|
|
|
void UParameterizeMeshTool::OnPreviewMeshUpdated()
|
|
|
|
|
{
|
|
|
|
|
if (UVLayoutView)
|
|
|
|
|
{
|
|
|
|
|
int32 UVChannel = UVChannelProperties ? UVChannelProperties->GetSelectedChannelIndex(true) : 0;
|
|
|
|
|
Preview->PreviewMesh->ProcessMesh([&](const FDynamicMesh3& NewMesh)
|
|
|
|
|
{
|
|
|
|
|
UVLayoutView->UpdateUVMesh(&NewMesh, UVChannel);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (MaterialSettings)
|
|
|
|
|
{
|
|
|
|
|
MaterialSettings->UpdateMaterials();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-10-01 20:41:42 -04:00
|
|
|
#undef LOCTEXT_NAMESPACE
|