2019-12-27 09:26:59 -05:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
2019-10-01 20:41:42 -04:00
|
|
|
|
|
|
|
|
#include "Changes/MeshVertexChange.h"
|
2021-06-13 00:35:22 -04:00
|
|
|
#include "DynamicMesh/DynamicMesh3.h"
|
2019-10-01 20:41:42 -04:00
|
|
|
|
2021-06-12 14:28:52 -04:00
|
|
|
#include "Components/BaseDynamicMeshComponent.h"
|
2019-10-01 20:41:42 -04:00
|
|
|
|
2021-03-09 19:33:56 -04:00
|
|
|
using namespace UE::Geometry;
|
2019-10-01 20:41:42 -04:00
|
|
|
|
|
|
|
|
void FMeshVertexChange::Apply(UObject* Object)
|
|
|
|
|
{
|
|
|
|
|
IMeshVertexCommandChangeTarget* ChangeTarget = CastChecked<IMeshVertexCommandChangeTarget>(Object);
|
|
|
|
|
ChangeTarget->ApplyChange(this, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMeshVertexChange::Revert(UObject* Object)
|
|
|
|
|
{
|
|
|
|
|
IMeshVertexCommandChangeTarget* ChangeTarget = CastChecked<IMeshVertexCommandChangeTarget>(Object);
|
|
|
|
|
ChangeTarget->ApplyChange(this, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FString FMeshVertexChange::ToString() const
|
|
|
|
|
{
|
|
|
|
|
return FString(TEXT("Mesh Vertex Change"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-04-18 18:42:59 -04:00
|
|
|
FMeshVertexChangeBuilder::FMeshVertexChangeBuilder()
|
|
|
|
|
{
|
|
|
|
|
Change = MakeUnique<FMeshVertexChange>();
|
|
|
|
|
}
|
2019-10-01 20:41:42 -04:00
|
|
|
|
|
|
|
|
|
2020-04-18 18:42:59 -04:00
|
|
|
FMeshVertexChangeBuilder::FMeshVertexChangeBuilder(EMeshVertexChangeComponents Components)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
|
|
|
|
Change = MakeUnique<FMeshVertexChange>();
|
2020-03-05 18:07:34 -05:00
|
|
|
|
2020-04-18 18:42:59 -04:00
|
|
|
bSavePositions = ((Components & EMeshVertexChangeComponents::VertexPositions) != EMeshVertexChangeComponents::None);
|
|
|
|
|
Change->bHaveVertexPositions = bSavePositions;
|
|
|
|
|
|
|
|
|
|
bSaveColors = ((Components & EMeshVertexChangeComponents::VertexColors) != EMeshVertexChangeComponents::None);
|
|
|
|
|
Change->bHaveVertexColors = bSaveColors;
|
|
|
|
|
|
|
|
|
|
bSaveOverlayNormals = ((Components & EMeshVertexChangeComponents::OverlayNormals) != EMeshVertexChangeComponents::None);
|
|
|
|
|
Change->bHaveOverlayNormals = bSaveOverlayNormals;
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMeshVertexChangeBuilder::UpdateVertex(int VertexID, const FVector3d& OldPosition, const FVector3d& NewPosition)
|
|
|
|
|
{
|
|
|
|
|
const int* FoundIndex = SavedVertices.Find(VertexID);
|
|
|
|
|
if (FoundIndex == nullptr)
|
|
|
|
|
{
|
|
|
|
|
int NewIndex = Change->Vertices.Num();
|
|
|
|
|
SavedVertices.Add(VertexID, NewIndex);
|
|
|
|
|
Change->Vertices.Add(VertexID);
|
|
|
|
|
Change->OldPositions.Add(OldPosition);
|
|
|
|
|
Change->NewPositions.Add(NewPosition);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Change->NewPositions[*FoundIndex] = NewPosition;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-31 20:16:41 -04:00
|
|
|
|
|
|
|
|
void FMeshVertexChangeBuilder::UpdateVertexColor(int32 VertexID, const FVector3f& OldColor, const FVector3f& NewColor)
|
|
|
|
|
{
|
|
|
|
|
const int* FoundIndex = SavedVertices.Find(VertexID);
|
|
|
|
|
if (FoundIndex == nullptr)
|
|
|
|
|
{
|
|
|
|
|
int NewIndex = Change->Vertices.Num();
|
|
|
|
|
SavedVertices.Add(VertexID, NewIndex);
|
|
|
|
|
Change->Vertices.Add(VertexID);
|
|
|
|
|
Change->OldColors.Add(OldColor);
|
|
|
|
|
Change->NewColors.Add(NewColor);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Change->NewColors[*FoundIndex] = NewColor;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-10-01 20:41:42 -04:00
|
|
|
void FMeshVertexChangeBuilder::UpdateVertexFinal(int VertexID, const FVector3d& NewPosition)
|
|
|
|
|
{
|
|
|
|
|
check(SavedVertices.Contains(VertexID));
|
|
|
|
|
|
|
|
|
|
const int* Index = SavedVertices.Find(VertexID);
|
|
|
|
|
if ( Index != nullptr )
|
|
|
|
|
{
|
|
|
|
|
Change->NewPositions[*Index] = NewPosition;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-03-05 18:07:34 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-18 18:42:59 -04:00
|
|
|
void FMeshVertexChangeBuilder::SaveVertexInitial(const FDynamicMesh3* Mesh, int32 VertexID)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2020-04-18 18:42:59 -04:00
|
|
|
const int32* FoundIndex = SavedVertices.Find(VertexID);
|
|
|
|
|
if (FoundIndex == nullptr)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2020-04-18 18:42:59 -04:00
|
|
|
int32 Index = Change->Vertices.Num();
|
|
|
|
|
SavedVertices.Add(VertexID, Index);
|
|
|
|
|
Change->Vertices.Add(VertexID);
|
|
|
|
|
if (bSavePositions)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2020-04-18 18:42:59 -04:00
|
|
|
FVector3d Pos = Mesh->GetVertex(VertexID);
|
|
|
|
|
Change->OldPositions.Add(Pos);
|
|
|
|
|
Change->NewPositions.Add(Pos);
|
|
|
|
|
}
|
|
|
|
|
if (bSaveColors)
|
|
|
|
|
{
|
|
|
|
|
FVector3f Color = Mesh->GetVertexColor(VertexID);
|
|
|
|
|
Change->OldColors.Add(Color);
|
|
|
|
|
Change->NewColors.Add(Color);
|
|
|
|
|
}
|
|
|
|
|
if (OnNewVertexSaved)
|
|
|
|
|
{
|
|
|
|
|
OnNewVertexSaved(VertexID, Index);
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-04-18 18:42:59 -04:00
|
|
|
int32 Index = *FoundIndex;
|
|
|
|
|
if (bSavePositions)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2020-04-18 18:42:59 -04:00
|
|
|
Change->NewPositions[Index] = Mesh->GetVertex(VertexID);
|
|
|
|
|
}
|
|
|
|
|
if (bSaveColors)
|
|
|
|
|
{
|
|
|
|
|
Change->NewColors[Index] = Mesh->GetVertexColor(VertexID);
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-04-18 18:42:59 -04:00
|
|
|
void FMeshVertexChangeBuilder::SaveVertexFinal(const FDynamicMesh3* Mesh, int32 VertexID)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2020-04-18 18:42:59 -04:00
|
|
|
const int32* FoundIndex = SavedVertices.Find(VertexID);
|
|
|
|
|
if (FoundIndex != nullptr)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2020-04-18 18:42:59 -04:00
|
|
|
int32 Index = *FoundIndex;
|
|
|
|
|
if (bSavePositions)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2020-04-18 18:42:59 -04:00
|
|
|
Change->NewPositions[Index] = Mesh->GetVertex(VertexID);
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|
2020-04-18 18:42:59 -04:00
|
|
|
if (bSaveColors)
|
2019-10-01 20:41:42 -04:00
|
|
|
{
|
2020-04-18 18:42:59 -04:00
|
|
|
Change->NewColors[Index] = Mesh->GetVertexColor(VertexID);
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
2020-03-05 18:07:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-04-18 18:42:59 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-05 18:07:34 -05:00
|
|
|
void FMeshVertexChangeBuilder::UpdateOverlayNormal(int ElementID, const FVector3f& OldNormal, const FVector3f& NewNormal)
|
|
|
|
|
{
|
|
|
|
|
const int* FoundIndex = SavedNormalElements.Find(ElementID);
|
|
|
|
|
if (FoundIndex == nullptr)
|
|
|
|
|
{
|
|
|
|
|
int NewIndex = Change->Normals.Num();
|
|
|
|
|
SavedNormalElements.Add(ElementID, NewIndex);
|
|
|
|
|
Change->Normals.Add(ElementID);
|
|
|
|
|
Change->OldNormals.Add(OldNormal);
|
|
|
|
|
Change->NewNormals.Add(NewNormal);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Change->NewNormals[*FoundIndex] = NewNormal;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMeshVertexChangeBuilder::UpdateOverlayNormalFinal(int ElementID, const FVector3f& NewNormal)
|
|
|
|
|
{
|
|
|
|
|
check(SavedNormalElements.Contains(ElementID));
|
|
|
|
|
const int* Index = SavedNormalElements.Find(ElementID);
|
|
|
|
|
if (Index != nullptr)
|
|
|
|
|
{
|
|
|
|
|
Change->NewNormals[*Index] = NewNormal;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FMeshVertexChangeBuilder::SaveOverlayNormals(const FDynamicMesh3* Mesh, const TArray<int>& ElementIDs, bool bInitial)
|
|
|
|
|
{
|
|
|
|
|
if (Mesh->HasAttributes() == false || Mesh->Attributes()->PrimaryNormals() == nullptr)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const FDynamicMeshNormalOverlay* Overlay = Mesh->Attributes()->PrimaryNormals();
|
|
|
|
|
|
|
|
|
|
int Num = ElementIDs.Num();
|
|
|
|
|
if (bInitial)
|
|
|
|
|
{
|
|
|
|
|
for (int k = 0; k < Num; ++k)
|
|
|
|
|
{
|
|
|
|
|
FVector3f Normal = Overlay->GetElement(ElementIDs[k]);
|
|
|
|
|
UpdateOverlayNormal(ElementIDs[k], Normal, Normal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int k = 0; k < Num; ++k)
|
|
|
|
|
{
|
|
|
|
|
FVector3f Normal = Overlay->GetElement(ElementIDs[k]);
|
|
|
|
|
UpdateOverlayNormalFinal(ElementIDs[k], Normal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FMeshVertexChangeBuilder::SaveOverlayNormals(const FDynamicMesh3* Mesh, const TSet<int>& ElementIDs, bool bInitial)
|
|
|
|
|
{
|
|
|
|
|
if (Mesh->HasAttributes() == false || Mesh->Attributes()->PrimaryNormals() == nullptr)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const FDynamicMeshNormalOverlay* Overlay = Mesh->Attributes()->PrimaryNormals();
|
|
|
|
|
|
|
|
|
|
if (bInitial)
|
|
|
|
|
{
|
|
|
|
|
for (int ElementID : ElementIDs)
|
|
|
|
|
{
|
|
|
|
|
FVector3f Normal = Overlay->GetElement(ElementID);
|
|
|
|
|
UpdateOverlayNormal(ElementID, Normal, Normal);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int ElementID : ElementIDs)
|
|
|
|
|
{
|
|
|
|
|
FVector3f Normal = Overlay->GetElement(ElementID);
|
|
|
|
|
UpdateOverlayNormalFinal(ElementID, Normal);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-10-01 20:41:42 -04:00
|
|
|
}
|