You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
216 lines
5.0 KiB
C++
216 lines
5.0 KiB
C++
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "SmoothMeshTool.h"
|
|
#include "InteractiveToolManager.h"
|
|
#include "ToolBuilderUtil.h"
|
|
|
|
#include "DynamicMesh3.h"
|
|
#include "DynamicMeshToMeshDescription.h"
|
|
#include "MeshDescriptionToDynamicMesh.h"
|
|
|
|
#include "SimpleDynamicMeshComponent.h"
|
|
|
|
#include "SceneManagement.h" // for FPrimitiveDrawInterface
|
|
#include "ToolSetupUtil.h"
|
|
|
|
// Smoothing operators
|
|
#include "SmoothingOps/IterativeSmoothingOp.h"
|
|
#include "SmoothingOps/CotanSmoothingOp.h"
|
|
//#include "SmoothingOps/MeanValueSmoothingOp.h"
|
|
|
|
|
|
#define LOCTEXT_NAMESPACE "USmoothMeshTool"
|
|
|
|
|
|
/*
|
|
* ToolBuilder
|
|
*/
|
|
|
|
|
|
bool USmoothMeshToolBuilder::CanBuildTool(const FToolBuilderState& SceneState) const
|
|
{
|
|
return ToolBuilderUtil::CountComponents(SceneState, CanMakeComponentTarget) == 1;
|
|
}
|
|
|
|
UInteractiveTool* USmoothMeshToolBuilder::BuildTool(const FToolBuilderState& SceneState) const
|
|
{
|
|
USmoothMeshTool* NewTool = NewObject<USmoothMeshTool>(SceneState.ToolManager);
|
|
|
|
UActorComponent* ActorComponent = ToolBuilderUtil::FindFirstComponent(SceneState, CanMakeComponentTarget);
|
|
auto* MeshComponent = Cast<UPrimitiveComponent>(ActorComponent);
|
|
check(MeshComponent != nullptr);
|
|
|
|
NewTool->SetSelection(MakeComponentTarget(MeshComponent));
|
|
NewTool->SetWorld(SceneState.World);
|
|
NewTool->SetAssetAPI(AssetAPI);
|
|
|
|
return NewTool;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Tool
|
|
*/
|
|
|
|
void USmoothMeshTool::SetWorld(UWorld* World)
|
|
{
|
|
this->TargetWorld = World;
|
|
}
|
|
|
|
void USmoothMeshTool::SetAssetAPI(IToolsContextAssetAPI* AssetAPIIn)
|
|
{
|
|
this->AssetAPI = AssetAPIIn;
|
|
}
|
|
|
|
|
|
void USmoothMeshTool::Setup()
|
|
{
|
|
UInteractiveTool::Setup();
|
|
|
|
// hide input StaticMeshComponent
|
|
ComponentTarget->SetOwnerVisibility(false);
|
|
|
|
// initialize our properties
|
|
ToolPropertyObjects.Add(this);
|
|
|
|
// populate the SrcDynamicMesh with a conversion of the input mesh.
|
|
FMeshDescriptionToDynamicMesh Converter;
|
|
Converter.bPrintDebugMessages = false;
|
|
Converter.Convert(ComponentTarget->GetMesh(), SrcDynamicMesh);
|
|
|
|
// Initialize the preview mesh with a copy of the source mesh.
|
|
{
|
|
// Construct the preview object and set the material on it.
|
|
Preview = NewObject<UMeshOpPreviewWithBackgroundCompute>(this, "Preview");
|
|
Preview->Setup(this->TargetWorld, this); // Adds the actual functional tool in the Preview object
|
|
|
|
Preview->PreviewMesh->UpdatePreview(&SrcDynamicMesh);
|
|
Preview->PreviewMesh->SetTransform(ComponentTarget->GetWorldTransform());
|
|
|
|
auto Material = ComponentTarget->GetMaterial(0);
|
|
|
|
Preview->ConfigureMaterials(
|
|
ToolSetupUtil::GetDefaultMaterial(GetToolManager(), Material),
|
|
ToolSetupUtil::GetDefaultWorkingMaterial(GetToolManager())
|
|
);
|
|
}
|
|
|
|
// show the preview mesh
|
|
Preview->SetVisibility(true);
|
|
|
|
// start the compute
|
|
Preview->InvalidateResult(); // start compute
|
|
|
|
bResultValid = false;
|
|
|
|
}
|
|
|
|
|
|
void USmoothMeshTool::Shutdown(EToolShutdownType ShutdownType)
|
|
{
|
|
// Restore (unhide) the source meshes
|
|
ComponentTarget->SetOwnerVisibility(true);
|
|
|
|
if (Preview != nullptr)
|
|
{
|
|
FDynamicMeshOpResult Result = Preview->Shutdown();
|
|
if (ShutdownType == EToolShutdownType::Accept)
|
|
{
|
|
|
|
GetToolManager()->BeginUndoTransaction(LOCTEXT("SmoothMeshToolTransactionName", "Smooth Mesh"));
|
|
|
|
FDynamicMesh3* DynamicMeshResult = Result.Mesh.Get();
|
|
check(DynamicMeshResult != nullptr);
|
|
|
|
ComponentTarget->CommitMesh([DynamicMeshResult](FMeshDescription* MeshDescription)
|
|
{
|
|
FDynamicMeshToMeshDescription Converter;
|
|
Converter.Convert(DynamicMeshResult, *MeshDescription);
|
|
});
|
|
|
|
|
|
GetToolManager()->EndUndoTransaction();
|
|
}
|
|
}
|
|
}
|
|
|
|
void USmoothMeshTool::Render(IToolsContextRenderAPI* RenderAPI)
|
|
{
|
|
UpdateResult();
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
void USmoothMeshTool::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
|
{
|
|
// one of the parameters changed. Dirty the result for force a recompute.
|
|
Preview->InvalidateResult();
|
|
bResultValid = false;
|
|
}
|
|
#endif
|
|
|
|
void USmoothMeshTool::OnPropertyModified(UObject* PropertySet, UProperty* Property)
|
|
{
|
|
Preview->InvalidateResult();
|
|
bResultValid = false;
|
|
}
|
|
|
|
|
|
void USmoothMeshTool::Tick(float DeltaTime)
|
|
{
|
|
Preview->Tick(DeltaTime);
|
|
}
|
|
|
|
void USmoothMeshTool::UpdateResult()
|
|
{
|
|
if (bResultValid)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bResultValid = Preview->HaveValidResult();
|
|
}
|
|
|
|
bool USmoothMeshTool::HasAccept() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool USmoothMeshTool::CanAccept() const
|
|
{
|
|
return bResultValid;
|
|
}
|
|
|
|
TSharedPtr<FDynamicMeshOperator> USmoothMeshTool::MakeNewOperator()
|
|
{
|
|
TSharedPtr<FSmoothingOpBase> MeshOp;
|
|
switch (SmoothType)
|
|
{
|
|
default:
|
|
case ESmoothMeshToolSmoothType::Iterative:
|
|
MeshOp = MakeShared<FIterativeSmoothingOp>(&SrcDynamicMesh, SmoothSpeed, SmoothIterations);
|
|
break;
|
|
|
|
case ESmoothMeshToolSmoothType::BiHarmonic_Cotan:
|
|
MeshOp = MakeShared<FCotanSmoothingOp>(&SrcDynamicMesh, SmoothSpeed, SmoothIterations);
|
|
break;
|
|
/**
|
|
case ESmoothMeshToolSmoothType::BiHarmonic_MVW:
|
|
MeshOp = MakeShared<FMeanValueSmoothingOp>(&SrcDynamicMesh, SmoothSpeed, SmoothIterations);
|
|
break;
|
|
*/
|
|
}
|
|
|
|
const FTransform XForm = ComponentTarget->GetWorldTransform();
|
|
FTransform3d XForm3d(XForm);
|
|
MeshOp->SetTransform(XForm3d);
|
|
|
|
return MeshOp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef LOCTEXT_NAMESPACE
|