Files
UnrealEngineUWP/Engine/Plugins/Experimental/MeshModelingToolsetExp/Source/MeshModelingToolsExp/Private/OffsetMeshTool.cpp
michael balzer b8a1c9b6cf GeometryCore: Remove ExplicitUseGeometryMathTypes.h
#ROBOMERGE-AUTHOR: michael.balzer
#ROBOMERGE-SOURCE: CL 18227685 in //UE5/Release-5.0/... via CL 18229350
#ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469)
#ROBOMERGE[STARSHIP]: UE5-Main

[CL 18231457 by michael balzer in ue5-release-engine-test branch]
2021-11-17 19:02:44 -05:00

134 lines
4.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "OffsetMeshTool.h"
#include "InteractiveToolManager.h"
#include "ToolBuilderUtil.h"
#include "DynamicMesh/DynamicMesh3.h"
#include "DynamicMesh/DynamicMeshAABBTree3.h"
#include "WeightMapTypes.h"
#include "DeformationOps/MeshOffsetOps.h"
using namespace UE::Geometry;
#define LOCTEXT_NAMESPACE "UOffsetMeshTool"
/*
* Tool
*/
UOffsetMeshTool::UOffsetMeshTool()
{
SetToolDisplayName(LOCTEXT("ToolName", "Offset"));
}
void UOffsetMeshTool::InitializeProperties()
{
OffsetProperties = NewObject<UOffsetMeshToolProperties>(this);
AddToolPropertySource(OffsetProperties);
OffsetProperties->RestoreProperties(this);
OffsetProperties->WatchProperty(OffsetProperties->OffsetType,
[&](EOffsetMeshToolOffsetType) { UpdateOptionalPropertyVisibility(); InvalidateResult(); });
OffsetProperties->WatchProperty(OffsetProperties->Distance,
[&](float) { InvalidateResult(); });
OffsetProperties->WatchProperty(OffsetProperties->bCreateShell,
[&](bool) { InvalidateResult(); });
IterativeProperties = AddOptionalPropertySet<UIterativeOffsetProperties>(
[&]() { return OffsetProperties->OffsetType == EOffsetMeshToolOffsetType::Iterative; });
ImplicitProperties = AddOptionalPropertySet<UImplicitOffsetProperties>(
[&]() { return OffsetProperties->OffsetType == EOffsetMeshToolOffsetType::Implicit; });
WeightMapProperties = AddWeightMapPropertySet<UOffsetWeightMapSetProperties>();
WeightMapProperties->WatchProperty(WeightMapProperties->MinDistance,
[&](float) { InvalidateResult(); });
}
void UOffsetMeshTool::OnShutdown(EToolShutdownType ShutdownType)
{
OffsetProperties->SaveProperties(this);
}
FText UOffsetMeshTool::GetToolMessageString() const
{
return LOCTEXT("StartOffsetToolMessage", "Offset the mesh vertex positions using various Offseting methods.");
}
FText UOffsetMeshTool::GetAcceptTransactionName() const
{
return LOCTEXT("OffsetMeshToolTransactionName", "Offset Mesh");
}
bool UOffsetMeshTool::HasMeshTopologyChanged() const
{
return OffsetProperties->bCreateShell;
}
TUniquePtr<FDynamicMeshOperator> UOffsetMeshTool::MakeNewOperator()
{
const FDynamicMesh3* Mesh = &GetInitialMesh();
TUniquePtr<FMeshOffsetBaseOp> MeshOp;
switch (OffsetProperties->OffsetType)
{
default:
case EOffsetMeshToolOffsetType::Iterative:
{
TUniquePtr<FIterativeOffsetMeshOp> IterOp = MakeUnique<FIterativeOffsetMeshOp>(Mesh);
IterOp->Steps = IterativeProperties->Steps;
IterOp->SmoothAlpha = IterativeProperties->SmoothingPerStep;
IterOp->bReprojectSmooth = IterativeProperties->bReprojectSmooth;
IterOp->bFixedBoundary = (!IterativeProperties->bOffsetBoundaries);
MeshOp = MoveTemp(IterOp);
}
break;
case EOffsetMeshToolOffsetType::Implicit:
{
TUniquePtr<FLaplacianOffsetMeshOp> ImplicitOp = MakeUnique<FLaplacianOffsetMeshOp>(Mesh);
double NonlinearT = FMathd::Pow(ImplicitProperties->Smoothness, 2.0);
// this is an empirically-determined hack that seems to work OK to normalize the result for variable vertex count...
double ScaledPower = (NonlinearT / 50.0) * Mesh->VertexCount();
ImplicitOp->Softness = ScaledPower;
ImplicitOp->bUniformWeights = (ImplicitProperties->bPreserveUVs == false);
ImplicitOp->bFixedBoundary = true;
MeshOp = MoveTemp(ImplicitOp);
}
break;
}
double MaxDist = FMathd::Abs(OffsetProperties->Distance);
double MinDist = FMathd::Abs(WeightMapProperties->MinDistance);
MinDist = FMathd::Min(MinDist, MaxDist);
MaxDist *= GetScaleNormalizationFactor();
MinDist *= GetScaleNormalizationFactor();
MeshOp->OffsetRange = FInterval1d(MinDist, MaxDist);
MeshOp->OffsetSign = (OffsetProperties->Distance < 0) ? -1.0 : 1.0;
MeshOp->BaseNormals = this->GetInitialVtxNormals();
MeshOp->bCreateShell = OffsetProperties->bCreateShell;
if (MeshOp->bCreateShell)
{
MeshOp->BoundaryLoops = GetInitialBoundaryLoops();
}
MeshOp->WeightMap = GetActiveWeightMap();
MeshOp->bUseWeightMap = true;
MeshOp->SetTransform( FTransform3d(GetPreviewTransform()) );
return MoveTemp(MeshOp);
}
#undef LOCTEXT_NAMESPACE