Files
2025-05-18 13:04:45 +08:00

434 lines
10 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "CADSceneGraph.h"
#include "Misc/FileHelper.h"
#include "Serialization/Archive.h"
#include "HAL/FileManager.h"
namespace CADLibrary
{
FArchive& operator<<(FArchive& Ar, FArchiveCADObject& Object)
{
Ar << Object.Id;
Ar << Object.Label;
Ar << Object.MetaData;
Ar << Object.TransformMatrix;
Ar << Object.Unit;
Ar << (FArchiveGraphicProperties&) Object;
return Ar;
}
bool FArchiveCADObject::SetNameWithAttributeValue(const TCHAR* Key)
{
FString* LabelPtr = MetaData.Find(Key);
if (LabelPtr != nullptr)
{
Label = *LabelPtr;
return true;
}
return false;
}
FArchive& operator<<(FArchive& Ar, FArchiveInstance& Instance)
{
Ar << (FArchiveWithOverridenChildren&) Instance;
Ar << Instance.ReferenceNodeId;
Ar << Instance.bIsExternalReference;
return Ar;
}
FArchive& operator<<(FArchive& Ar, FArchiveReference& Component)
{
Ar << (FArchiveCADObject&) Component;
Ar << Component.Children;
return Ar;
}
FArchive& operator<<(FArchive& Ar, FArchiveUnloadedReference& Unloaded)
{
Ar << (FArchiveCADObject&) Unloaded;
Ar << Unloaded.ExternalFile;
return Ar;
}
FArchive& operator<<(FArchive& Ar, FArchiveOverrideOccurrence& OverrideOccurrence)
{
Ar << (FArchiveWithOverridenChildren&) OverrideOccurrence;
return Ar;
}
FArchive& operator<<(FArchive& Ar, FArchiveWithOverridenChildren& WithOverridenChildren)
{
Ar << (FArchiveCADObject&) WithOverridenChildren;
Ar << WithOverridenChildren.OverridenChildren;
return Ar;
}
FArchive& operator<<(FArchive& Ar, FArchiveBody& Body)
{
Ar << (FArchiveCADObject&) Body;
Ar << Body.MaterialFaceSet;
Ar << Body.ColorFaceSet;
Ar << Body.Mesher;
Ar << Body.ParentId;
Ar << Body.MeshActorUId;
return Ar;
}
FArchive& operator<<(FArchive& Ar, FArchiveColor& Color)
{
Ar << Color.Id;
Ar << Color.Color;
Ar << Color.UEMaterialUId;
return Ar;
}
FArchive& operator<<(FArchive& Ar, FArchiveMaterial& Material)
{
Ar << Material.Id;
Ar << Material.Material;
Ar << Material.UEMaterialUId;
return Ar;
}
FArchive& operator<<(FArchive& Ar, FArchiveSceneGraph& SceneGraph)
{
Ar << SceneGraph.SceneGraphId;
Ar << SceneGraph.CADFileName;
Ar << SceneGraph.ArchiveFileName;
Ar << SceneGraph.FullPath;
Ar << SceneGraph.ExternalReferenceFiles;
Ar << SceneGraph.ColorHIdToColor;
Ar << SceneGraph.MaterialHIdToMaterial;
Ar << SceneGraph.Instances;
Ar << SceneGraph.References;
Ar << SceneGraph.UnloadedReferences;
Ar << SceneGraph.OverrideOccurrences;
Ar << SceneGraph.Bodies;
Ar << SceneGraph.CADIdToIndex;
return Ar;
}
void FArchiveSceneGraph::SerializeMockUp(const TCHAR* Filename)
{
TUniquePtr<FArchive> Archive(IFileManager::Get().CreateFileWriter(Filename));
if (Archive.IsValid())
{
*Archive << *this;
Archive->Close();
}
}
void FArchiveSceneGraph::DeserializeMockUpFile(const TCHAR* Filename)
{
TUniquePtr<FArchive> Archive(IFileManager::Get().CreateFileReader(Filename));
if (Archive.IsValid())
{
*Archive << *this;
Archive->Close();
}
}
FArchiveInstance& FArchiveSceneGraph::AddInstance(const FArchiveCADObject& Parent)
{
ensure(Instances.Num() < Instances.Max());
const int32 InstanceId = LastEntityId++;
int32 Index = Instances.Emplace(InstanceId, Parent);
CADIdToIndex.Add(Index);
return Instances[Index];
}
FArchiveInstance& FArchiveSceneGraph::GetInstance(const FCadId CadId)
{
ensure(CADIdToIndex.IsValidIndex(CadId));
const int32 Index = CADIdToIndex[CadId];
ensure(Instances.IsValidIndex(Index));
return Instances[Index];
}
void FArchiveSceneGraph::RemoveLastInstance()
{
ensure(!Instances.IsEmpty());
LastEntityId--;
ensure(Instances.Last().Id == LastEntityId);
Instances.SetNum(Instances.Num() - 1, EAllowShrinking::No);
CADIdToIndex.SetNum(CADIdToIndex.Num() - 1, EAllowShrinking::No);
}
bool FArchiveSceneGraph::IsAInstance(FCadId CadId) const
{
if(!CADIdToIndex.IsValidIndex(CadId))
{
return false;
}
const int32 Index = CADIdToIndex[CadId];
if(!Instances.IsValidIndex(Index))
{
return false;
}
return Instances[Index].Id == CadId;
}
FArchiveReference& FArchiveSceneGraph::AddReference(FArchiveUnloadedReference& Reference)
{
ensure(References.Num() < References.Max());
int32 Index = References.Emplace(Reference.Id, Reference);
FArchiveReference& NewReference = References[Index];
NewReference.MoveTemp(Reference);
// do not call here RemoveLastUnloadedReference otherwise the Reference.Id will be delete
UnloadedReferences.SetNum(UnloadedReferences.Num() - 1, EAllowShrinking::No);
CADIdToIndex[Reference.Id] = Index;
return NewReference;
}
FArchiveReference& FArchiveSceneGraph::AddReference(FArchiveInstance& Parent)
{
ensure(References.Num() < References.Max());
const int32 ReferenceId = LastEntityId++;
int32 Index = References.Emplace(ReferenceId, Parent);
CADIdToIndex.Add(Index);
Parent.bIsExternalReference = false;
Parent.ReferenceNodeId = ReferenceId;
return References[Index];
}
FArchiveReference& FArchiveSceneGraph::AddOccurrence(FArchiveReference& Parent)
{
FArchiveInstance& Instance = AddInstance(Parent);
Parent.AddChild(Instance.Id);
FArchiveReference& Reference = AddReference(Instance);
Instance.ReferenceNodeId = Reference.Id;
return Reference;
}
void FArchiveSceneGraph::RemoveLastOccurrence()
{
RemoveLastReference();
RemoveLastInstance();
}
FArchiveReference& FArchiveSceneGraph::GetReference(const FCadId CadId)
{
ensure(CADIdToIndex.IsValidIndex(CadId));
const int32 Index = CADIdToIndex[CadId];
ensure(References.IsValidIndex(Index));
return References[Index];
}
bool FArchiveSceneGraph::IsAReference(const FCadId CadId) const
{
if (!CADIdToIndex.IsValidIndex(CadId))
{
return false;
}
const int32 Index = CADIdToIndex[CadId];
if (!References.IsValidIndex(Index))
{
return false;
}
return References[Index].Id == CadId;
}
void FArchiveSceneGraph::RemoveLastReference()
{
ensure(!References.IsEmpty());
LastEntityId--;
ensure(References.Last().Id == LastEntityId);
References.SetNum(References.Num() - 1, EAllowShrinking::No);
CADIdToIndex.SetNum(CADIdToIndex.Num() - 1, EAllowShrinking::No);
}
void FArchiveWithOverridenChildren::AddOverridenChild(const FCadId ChildId)
{
OverridenChildren.Add(ChildId);
}
void FArchiveReference::AddChild(const FCadId ChildId)
{
Children.Add(ChildId);
}
void FArchiveReference::RemoveLastChild()
{
Children.Pop();
}
int32 FArchiveReference::ChildrenCount()
{
return Children.Num();
}
void FArchiveBody::Delete()
{
bIsRemoved = true;
MetaData.Empty();
ColorFaceSet.Empty();
MaterialFaceSet.Empty();
Label.Empty();
MeshActorUId = 0;
}
void FArchiveReference::MoveTemp(FArchiveUnloadedReference& Reference)
{
Id = Reference.Id;
Label = ::MoveTemp(Reference.Label);
MetaData = ::MoveTemp(Reference.MetaData);
TransformMatrix = ::MoveTemp(Reference.TransformMatrix);
ColorUId = Reference.ColorUId;
MaterialUId = Reference.MaterialUId;
Unit = Reference.Unit;
}
void FArchiveReference::CopyMetaData(FArchiveUnloadedReference& Reference)
{
Label = Reference.Label;
MetaData = Reference.MetaData;
ColorUId = Reference.ColorUId;
MaterialUId = Reference.MaterialUId;
Unit = Reference.Unit;
}
FArchiveUnloadedReference& FArchiveSceneGraph::AddUnloadedReference(FArchiveInstance& Parent)
{
ensure(UnloadedReferences.Num() < UnloadedReferences.Max());
const int32 ReferenceId = LastEntityId++;
int32 Index = UnloadedReferences.Emplace(ReferenceId, Parent);
CADIdToIndex.Add(Index);
Parent.bIsExternalReference = true;
Parent.ReferenceNodeId = ReferenceId;
return UnloadedReferences[Index];
}
FArchiveUnloadedReference& FArchiveSceneGraph::GetUnloadedReference(const FCadId CadId)
{
ensure(CADIdToIndex.IsValidIndex(CadId));
const int32 Index = CADIdToIndex[CadId];
ensure(UnloadedReferences.IsValidIndex(Index));
return UnloadedReferences[Index];
}
FArchiveOverrideOccurrence& FArchiveSceneGraph::AddOverrideOccurrence(FArchiveWithOverridenChildren& Parent)
{
ensure(OverrideOccurrences.Num() < OverrideOccurrences.Max());
const int32 ReferenceId = LastEntityId++;
int32 Index = OverrideOccurrences.Emplace(ReferenceId, Parent);
CADIdToIndex.Add(Index);
return OverrideOccurrences[Index];
}
FArchiveOverrideOccurrence& FArchiveSceneGraph::GetOverrideOccurrence(const FCadId CadId)
{
ensure(CADIdToIndex.IsValidIndex(CadId));
const int32 Index = CADIdToIndex[CadId];
ensure(OverrideOccurrences.IsValidIndex(Index));
return OverrideOccurrences[Index];
}
bool FArchiveSceneGraph::IsAUnloadedReference(const FCadId CadId) const
{
if (!CADIdToIndex.IsValidIndex(CadId))
{
return false;
}
const int32 Index = CADIdToIndex[CadId];
if (!UnloadedReferences.IsValidIndex(Index))
{
return false;
}
return UnloadedReferences[Index].Id == CadId;
}
void FArchiveSceneGraph::RemoveLastUnloadedReference()
{
ensure(!UnloadedReferences.IsEmpty());
LastEntityId--;
ensure(UnloadedReferences.Last().Id == LastEntityId);
UnloadedReferences.SetNum(UnloadedReferences.Num() - 1, EAllowShrinking::No);
CADIdToIndex.SetNum(CADIdToIndex.Num() - 1, EAllowShrinking::No);
}
FArchiveBody& FArchiveSceneGraph::AddBody(FArchiveReference& Parent, EMesher InMesher)
{
ensure(Bodies.Num() < Bodies.Max());
const int32 BodyId = LastEntityId++;
int32 Index = Bodies.Emplace(BodyId, Parent, InMesher);
CADIdToIndex.Add(Index);
return Bodies[Index];
}
FArchiveBody& FArchiveSceneGraph::GetBody(const FCadId CadId)
{
ensure(CADIdToIndex.IsValidIndex(CadId));
const int32 Index = CADIdToIndex[CadId];
ensure(Bodies.IsValidIndex(Index));
return Bodies[Index];
}
bool FArchiveSceneGraph::IsABody(const FCadId CadId) const
{
if (!CADIdToIndex.IsValidIndex(CadId))
{
return false;
}
const int32 Index = CADIdToIndex[CadId];
if (!Bodies.IsValidIndex(Index))
{
return false;
}
return Bodies[Index].Id == CadId;
}
void FArchiveSceneGraph::RemoveLastBody()
{
ensure(!Bodies.IsEmpty());
LastEntityId--;
ensure(Bodies.Last().Id == LastEntityId);
Bodies.SetNum(Bodies.Num() - 1, EAllowShrinking::No);
CADIdToIndex.SetNum(CADIdToIndex.Num() - 1, EAllowShrinking::No);
}
void FArchiveSceneGraph::AddExternalReferenceFile(const FArchiveUnloadedReference& Reference)
{
const int32 Index = CADIdToIndex[Reference.Id];
ensure(ExternalReferenceFiles.Add(Reference.ExternalFile) == Index);
}
}