Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 096e840098 |
@@ -1,4 +0,0 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "API/SpeckleTypeConverter.h"
|
||||
@@ -1,14 +0,0 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Components/SpeckleOperationsComponent.h"
|
||||
|
||||
|
||||
// Sets default values for this component's properties
|
||||
USpeckleOperationsComponent::USpeckleOperationsComponent()
|
||||
{
|
||||
PrimaryComponentTick.bCanEverTick = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Conversion/ConversionUtils.h"
|
||||
|
||||
FMatrix UConversionUtils::TransformToNative(const TArray<float>& TransformData)
|
||||
{
|
||||
if(TransformData.Num() != 16) return FMatrix::Identity;
|
||||
|
||||
FMatrix TransformMatrix;
|
||||
|
||||
for(int32 Row = 0; Row < 4; Row++)
|
||||
for(int32 Col = 0; Col < 4; Col++)
|
||||
{
|
||||
TransformMatrix.M[Row][Col] = TransformData[Row * 4 + Col];
|
||||
}
|
||||
|
||||
TransformMatrix = TransformMatrix.GetTransposed();
|
||||
|
||||
return TransformMatrix;
|
||||
}
|
||||
|
||||
float UConversionUtils::GetUnitsScaleFactorF(const FString& Units, const float WorldToCentimeters)
|
||||
{
|
||||
static const auto ParseUnits = [](const FString& LUnits) -> float
|
||||
{
|
||||
if (LUnits == "millimeters" || LUnits == "millimeter" || LUnits == "millimetres" || LUnits == "millimetre" || LUnits == "mm")
|
||||
return 0.1;
|
||||
if (LUnits == "centimeters" || LUnits == "centimeter" ||LUnits == "centimetres" || LUnits == "centimetre" || LUnits == "cm")
|
||||
return 1;
|
||||
if (LUnits == "meters" || LUnits == "meter" || LUnits == "metres" || LUnits == "metre" || LUnits == "m")
|
||||
return 100;
|
||||
if (LUnits == "kilometers" || LUnits == "kilometres" || LUnits == "km")
|
||||
return 100000;
|
||||
|
||||
if (LUnits == "inches" || LUnits == "inch" || LUnits == "in")
|
||||
return 2.54;
|
||||
if (LUnits == "feet" || LUnits == "foot" || LUnits == "ft")
|
||||
return 30.48;
|
||||
if (LUnits == "yards" || LUnits == "yard"|| LUnits == "yd")
|
||||
return 91.44;
|
||||
if (LUnits == "miles" || LUnits == "mile" || LUnits == "mi")
|
||||
return 160934.4;
|
||||
|
||||
return 100;
|
||||
};
|
||||
|
||||
return ParseUnits(Units.ToLower()) * WorldToCentimeters;
|
||||
}
|
||||
|
||||
float UConversionUtils::GetUnitsScaleFactor(const FString& Units, const UWorld* World)
|
||||
{
|
||||
int32 WorldToCentimeters;
|
||||
ensureAlways(TryGetWorldUnits(World, WorldToCentimeters));
|
||||
|
||||
return GetUnitsScaleFactorF(Units, WorldToCentimeters);
|
||||
}
|
||||
|
||||
bool UConversionUtils::TryGetWorldUnits(const UWorld* World, int32& OutWorldToCentimeters)
|
||||
{
|
||||
OutWorldToCentimeters = 1;
|
||||
if(!IsValid(World)) return false;
|
||||
|
||||
const AWorldSettings* Settings = World->GetWorldSettings();
|
||||
if(!IsValid(Settings)) return false;
|
||||
|
||||
OutWorldToCentimeters = Settings->WorldToMeters / 10.0;
|
||||
return true;
|
||||
}
|
||||
@@ -12,6 +12,7 @@ UProceduralMeshConverter::UProceduralMeshConverter()
|
||||
{
|
||||
SpeckleTypes.Add(UMesh::StaticClass());
|
||||
MeshActorType = AActor::StaticClass();
|
||||
bCreateCollisions = true;
|
||||
}
|
||||
|
||||
AActor* UProceduralMeshConverter::ConvertToNative_Implementation(const UBase* SpeckleBase, ASpeckleUnrealManager* Manager)
|
||||
@@ -19,13 +20,18 @@ AActor* UProceduralMeshConverter::ConvertToNative_Implementation(const UBase* Sp
|
||||
const UMesh* P = Cast<UMesh>(SpeckleBase);
|
||||
|
||||
if(P == nullptr) return nullptr;
|
||||
|
||||
return MeshToNative(P, Manager);
|
||||
|
||||
//No existing mesh was found, try and convert SpeckleMesh
|
||||
UMesh* ScaledMesh = DuplicateObject(P, P->GetOuter(), P->GetFName());
|
||||
ScaledMesh->ApplyUnits(Manager->GetWorld());
|
||||
ScaledMesh->AlignVerticesWithTexCoordsByIndex();
|
||||
|
||||
return MeshToNative(ScaledMesh, Manager);
|
||||
}
|
||||
|
||||
AActor* UProceduralMeshConverter::MeshToNative(const UMesh* SpeckleMesh, ASpeckleUnrealManager* Manager)
|
||||
{
|
||||
AActor* MeshActor = CreateActor(Manager, FTransform(SpeckleMesh->Transform));
|
||||
AActor* MeshActor = CreateActor(Manager, FTransform(SpeckleMesh->GetTransform()));
|
||||
UProceduralMeshComponent* MeshComponent = NewObject<UProceduralMeshComponent>(MeshActor, FName("SpeckleMeshComponent"));
|
||||
MeshComponent->SetupAttachment(MeshActor->GetRootComponent());
|
||||
MeshComponent->RegisterComponent();
|
||||
@@ -61,19 +67,23 @@ AActor* UProceduralMeshConverter::MeshToNative(const UMesh* SpeckleMesh, ASpeckl
|
||||
|
||||
i += n + 1;
|
||||
}
|
||||
|
||||
TArray<FColor> VertexColors;
|
||||
VertexColors.Reserve(SpeckleMesh->Colors.Num());
|
||||
for(const int32& c : SpeckleMesh->Colors) VertexColors.Add(FColor(c));
|
||||
|
||||
const TArray<FVector> Normals;
|
||||
const TArray<FProcMeshTangent> Tangents;
|
||||
|
||||
MeshComponent->CreateMeshSection(
|
||||
0,
|
||||
SpeckleMesh->Vertices,
|
||||
SpeckleMesh->GetVerts(),
|
||||
Faces,
|
||||
Normals,
|
||||
SpeckleMesh->TextureCoordinates,
|
||||
SpeckleMesh->VertexColors,
|
||||
SpeckleMesh->GetTextureCoordinates(),
|
||||
VertexColors,
|
||||
Tangents,
|
||||
true);
|
||||
bCreateCollisions);
|
||||
|
||||
MeshComponent->SetMaterial(0, GetMaterial(SpeckleMesh->RenderMaterial, Manager));
|
||||
|
||||
@@ -107,8 +117,8 @@ UMaterialInterface* UProceduralMeshConverter::GetMaterial(const URenderMaterial*
|
||||
DynMaterial->SetScalarParameterValue("Opacity", SpeckleMaterial->Opacity);
|
||||
DynMaterial->SetScalarParameterValue("Metallic", SpeckleMaterial->Metalness);
|
||||
DynMaterial->SetScalarParameterValue("Roughness", SpeckleMaterial->Roughness);
|
||||
DynMaterial->SetVectorParameterValue("BaseColor", SpeckleMaterial->Diffuse);
|
||||
DynMaterial->SetVectorParameterValue("EmissiveColor", SpeckleMaterial->Emissive);
|
||||
DynMaterial->SetVectorParameterValue("BaseColor", FColor(SpeckleMaterial->Diffuse));
|
||||
DynMaterial->SetVectorParameterValue("EmissiveColor", FColor(SpeckleMaterial->Emissive));
|
||||
|
||||
Manager->ConvertedMaterials.Add(SpeckleMaterial->Id, DynMaterial);
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "Objects/RenderMaterial.h"
|
||||
|
||||
|
||||
|
||||
UStaticMeshConverter::UStaticMeshConverter()
|
||||
{
|
||||
Transient = false;
|
||||
@@ -41,14 +40,20 @@ AActor* UStaticMeshConverter::ConvertToNative_Implementation(const UBase* Speckl
|
||||
|
||||
//Find existing mesh
|
||||
UStaticMesh* Mesh = Cast<UStaticMesh>(Package->FindAssetInPackage());
|
||||
|
||||
|
||||
FMatrix ActorTransform = FMatrix::Identity;
|
||||
if(!IsValid(Mesh))
|
||||
{
|
||||
//No existing mesh was found, try and convert SpeckleMesh
|
||||
Mesh = MeshToNative(Package, SpeckleMesh, Manager);
|
||||
UMesh* ScaledMesh = DuplicateObject(SpeckleMesh, SpeckleMesh->GetOuter(), SpeckleMesh->GetFName());
|
||||
ScaledMesh->ApplyUnits(Manager->GetWorld());
|
||||
ScaledMesh->AlignVerticesWithTexCoordsByIndex();
|
||||
|
||||
Mesh = MeshToNative(Package, ScaledMesh, Manager);
|
||||
ActorTransform = ScaledMesh->GetTransform();
|
||||
}
|
||||
AActor* Actor = CreateActor(Manager, FTransform(ActorTransform));
|
||||
|
||||
AActor* Actor = CreateActor(Manager, FTransform(SpeckleMesh->Transform));
|
||||
TInlineComponentArray<UStaticMeshComponent*> Components;
|
||||
Actor->GetComponents<UStaticMeshComponent>(Components);
|
||||
|
||||
@@ -71,7 +76,6 @@ AActor* UStaticMeshConverter::ConvertToNative_Implementation(const UBase* Speckl
|
||||
UStaticMesh* UStaticMeshConverter::MeshToNative(UObject* Outer, const UMesh* SpeckleMesh,
|
||||
ASpeckleUnrealManager* Manager)
|
||||
{
|
||||
|
||||
const EObjectFlags ObjectFags = Transient? RF_Transient | RF_Public : RF_Public;
|
||||
UStaticMesh* Mesh = NewObject<UStaticMesh>(Outer, FName(SpeckleMesh->Id), ObjectFags);
|
||||
|
||||
@@ -108,13 +112,13 @@ UStaticMesh* UStaticMeshConverter::MeshToNative(UObject* Outer, const UMesh* Spe
|
||||
const FName MaterialSlotName = Mesh->AddMaterial(Material);;
|
||||
BaseMeshDescription.PolygonGroupAttributes().RegisterAttribute<FName>(MeshAttribute::PolygonGroup::ImportedMaterialSlotName, 1, MaterialSlotName, EMeshAttributeFlags::None);
|
||||
{
|
||||
const size_t NumberOfVertices = SpeckleMesh->Vertices.Num();
|
||||
const size_t NumberOfVertices = SpeckleMesh->GetVertexCount();
|
||||
StaticMeshDescription->ReserveNewVertices(NumberOfVertices);
|
||||
|
||||
TArray<FVertexID> Vertices;
|
||||
Vertices.Reserve(NumberOfVertices);
|
||||
|
||||
for(const FVector VertexPosition : SpeckleMesh->Vertices)
|
||||
for(const FVector VertexPosition : SpeckleMesh->GetVerts())
|
||||
{
|
||||
const FVertexID VertID = StaticMeshDescription->CreateVertex();
|
||||
StaticMeshDescription->SetVertexPosition(VertID, VertexPosition);
|
||||
@@ -159,8 +163,8 @@ UStaticMesh* UStaticMeshConverter::MeshToNative(UObject* Outer, const UMesh* Spe
|
||||
|
||||
VertexInstances.Add(VertexInstance);
|
||||
|
||||
if(SpeckleMesh->TextureCoordinates.Num() > VertIndex)
|
||||
StaticMeshDescription->SetVertexInstanceUV(VertexInstance, SpeckleMesh->TextureCoordinates[VertIndex]);
|
||||
if(SpeckleMesh->GetTexCoordCount() > VertIndex)
|
||||
StaticMeshDescription->SetVertexInstanceUV(VertexInstance, SpeckleMesh->GetTextureCoordinate(VertIndex));
|
||||
|
||||
//if(SpeckleMesh->VertexColors.Num() > VertIndex)
|
||||
// //TODO set vertex colors
|
||||
@@ -257,8 +261,8 @@ UMaterialInterface* UStaticMeshConverter::GetMaterial(const URenderMaterial* Spe
|
||||
ConstMaterial->SetScalarParameterValueEditorOnly(FMaterialParameterInfo("Opacity"), SpeckleMaterial->Opacity);
|
||||
ConstMaterial->SetScalarParameterValueEditorOnly(FMaterialParameterInfo("Metallic"), SpeckleMaterial->Metalness);
|
||||
ConstMaterial->SetScalarParameterValueEditorOnly(FMaterialParameterInfo("Roughness"), SpeckleMaterial->Roughness);
|
||||
ConstMaterial->SetVectorParameterValueEditorOnly(FMaterialParameterInfo("BaseColor"), SpeckleMaterial->Diffuse);
|
||||
ConstMaterial->SetVectorParameterValueEditorOnly(FMaterialParameterInfo("EmissiveColor"), SpeckleMaterial->Emissive);
|
||||
ConstMaterial->SetVectorParameterValueEditorOnly(FMaterialParameterInfo("BaseColor"), FColor(SpeckleMaterial->Diffuse));
|
||||
ConstMaterial->SetVectorParameterValueEditorOnly(FMaterialParameterInfo("EmissiveColor"), FColor(SpeckleMaterial->Emissive));
|
||||
|
||||
//ConstMaterial->InitStaticPermutation();
|
||||
|
||||
@@ -275,8 +279,8 @@ UMaterialInterface* UStaticMeshConverter::GetMaterial(const URenderMaterial* Spe
|
||||
DynMaterial->SetScalarParameterValue("Opacity", SpeckleMaterial->Opacity);
|
||||
DynMaterial->SetScalarParameterValue("Metallic", SpeckleMaterial->Metalness);
|
||||
DynMaterial->SetScalarParameterValue("Roughness", SpeckleMaterial->Roughness);
|
||||
DynMaterial->SetVectorParameterValue("BaseColor", SpeckleMaterial->Diffuse);
|
||||
DynMaterial->SetVectorParameterValue("EmissiveColor", SpeckleMaterial->Emissive);
|
||||
DynMaterial->SetVectorParameterValue("BaseColor", FColor(SpeckleMaterial->Diffuse));
|
||||
DynMaterial->SetVectorParameterValue("EmissiveColor", FColor(SpeckleMaterial->Emissive));
|
||||
|
||||
DynMaterial->SetFlags(RF_Public);
|
||||
}
|
||||
|
||||
@@ -6,21 +6,16 @@
|
||||
#include "SpeckleUnrealManager.h"
|
||||
#include "Conversion/Converters/PointCloudConverter.h"
|
||||
#include "Conversion/Converters/StaticMeshConverter.h"
|
||||
#include "Objects/Mesh.h"
|
||||
#include "Objects/PointCloud.h"
|
||||
|
||||
|
||||
// Sets default values for this component's properties
|
||||
USpeckleConverterComponent::USpeckleConverterComponent()
|
||||
{
|
||||
PrimaryComponentTick.bCanEverTick = false;
|
||||
|
||||
//TODO consider using an object library for default converters
|
||||
static ConstructorHelpers::FObjectFinder<UStaticMeshConverter> MeshConverter(TEXT("StaticMeshConverter'/SpeckleUnreal/Converters/DefaultStaticMeshConverter.DefaultStaticMeshConverter'"));
|
||||
static ConstructorHelpers::FObjectFinder<UPointCloudConverter> PointCloudConverter(TEXT("PointCloudConverter'/SpeckleUnreal/Converters/DefaultPointCloudConverter.DefaultPointCloudConverter'"));
|
||||
|
||||
PrimaryComponentTick.bCanEverTick = false;
|
||||
|
||||
|
||||
|
||||
|
||||
//Mesh
|
||||
//Point
|
||||
@@ -42,9 +37,9 @@ void USpeckleConverterComponent::OnConvertersChangeHandler()
|
||||
for(int i = 0; i < SpeckleConverters.Num(); i++)
|
||||
{
|
||||
const UObject* Converter = SpeckleConverters[i];
|
||||
if(Converter != nullptr && !Converter->GetClass()->ImplementsInterface(USpeckleConverter::StaticClass()))
|
||||
if(Converter != nullptr && !Converter->GetClass()->ImplementsInterface(USpeckleTypeConverter::StaticClass()))
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("Converter {%s} is not a valid converter, Expected to implement interface %s"), *Converter->GetClass()->GetName(), *USpeckleConverter::StaticClass()->GetName())
|
||||
UE_LOG(LogTemp, Warning, TEXT("Converter {%s} is not a valid converter, Expected to implement interface %s"), *Converter->GetClass()->GetName(), *USpeckleTypeConverter::StaticClass()->GetName())
|
||||
SpeckleConverters.RemoveAt(i);
|
||||
i--;
|
||||
}
|
||||
@@ -80,15 +75,16 @@ AActor* USpeckleConverterComponent::ConvertToNative(const UBase* Object, ASpeckl
|
||||
UE_LOG(LogTemp, Warning, TEXT("Skipping Object %s - No conversion functions exist for %s"), *Object->Id, *Type->GetName());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("Converting object of type: %s id: %s "), *Object->Id, *Type->GetName());
|
||||
|
||||
FEditorScriptExecutionGuard ScriptGuard;
|
||||
return ISpeckleConverter::Execute_ConvertToNative(Converter, Object, Manager);
|
||||
|
||||
AActor* ReturnObject = ISpeckleTypeConverter::Execute_ConvertToNative(Converter, Object, Manager);
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("Converted object of type: %s id: %s "), *Object->Id, *Type->GetName());
|
||||
|
||||
return ReturnObject;
|
||||
}
|
||||
|
||||
TScriptInterface<ISpeckleConverter> USpeckleConverterComponent::GetConverter(const TSubclassOf<UBase> BaseType)
|
||||
TScriptInterface<ISpeckleTypeConverter> USpeckleConverterComponent::GetConverter(const TSubclassOf<UBase> BaseType)
|
||||
{
|
||||
// Check if this SpeckleType has a known converter.
|
||||
if(SpeckleTypeMap.Contains(BaseType))
|
||||
@@ -102,13 +98,13 @@ TScriptInterface<ISpeckleConverter> USpeckleConverterComponent::GetConverter(con
|
||||
{
|
||||
if(Converter == nullptr) continue;
|
||||
|
||||
if(!Converter->GetClass()->ImplementsInterface(USpeckleConverter::StaticClass()))
|
||||
if(!Converter->GetClass()->ImplementsInterface(USpeckleTypeConverter::StaticClass()))
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("Converter {%s} is not a valid converter, Expected to implement interface {%s}"), *Converter->GetClass()->GetName(), *USpeckleConverter::StaticClass()->GetName())
|
||||
UE_LOG(LogTemp, Warning, TEXT("Converter {%s} is not a valid converter, Expected to implement interface {%s}"), *Converter->GetClass()->GetName(), *USpeckleTypeConverter::StaticClass()->GetName())
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ISpeckleConverter::Execute_CanConvertToNative(Converter, BaseType))
|
||||
if(ISpeckleTypeConverter::Execute_CanConvertToNative(Converter, BaseType))
|
||||
{
|
||||
//Found a Converter! Save this mapping for next time.
|
||||
SpeckleTypeMap.Add(BaseType, Converter);
|
||||
|
||||
@@ -4,104 +4,114 @@
|
||||
#include "Objects/Mesh.h"
|
||||
|
||||
#include "SpeckleUnrealManager.h"
|
||||
#include "Objects/RenderMaterial.h"
|
||||
#include "Conversion/ConversionUtils.h"
|
||||
|
||||
void UMesh::Parse(const TSharedPtr<FJsonObject> Obj, const ASpeckleUnrealManager* Manager)
|
||||
FMatrix UMesh::GetTransform() const
|
||||
{
|
||||
Super::Parse(Obj, Manager);
|
||||
|
||||
const float ScaleFactor = Manager->ParseScaleFactor(Units);
|
||||
|
||||
//Parse optional Transform
|
||||
{
|
||||
Transform = FMatrix::Identity;
|
||||
|
||||
const TArray<TSharedPtr<FJsonValue>>* TransformData = nullptr;
|
||||
if(Obj->HasField("properties") && Obj->GetObjectField("properties")->TryGetArrayField("transform", TransformData))
|
||||
{
|
||||
for(int32 Row = 0; Row < 4; Row++)
|
||||
for(int32 Col = 0; Col < 4; Col++)
|
||||
{
|
||||
Transform.M[Row][Col] = TransformData->operator[](Row * 4 + Col)->AsNumber();
|
||||
}
|
||||
Transform = Transform.GetTransposed();
|
||||
Transform.ScaleTranslation(FVector(ScaleFactor));
|
||||
}
|
||||
}
|
||||
|
||||
//Parse Vertices
|
||||
{
|
||||
TArray<TSharedPtr<FJsonValue>> ObjectVertices = Manager->CombineChunks(Obj->GetArrayField("vertices"));
|
||||
const int32 NumberOfVertices = ObjectVertices.Num() / 3;
|
||||
|
||||
Vertices.Reserve(NumberOfVertices);
|
||||
|
||||
for (size_t i = 0, j = 0; i < NumberOfVertices; i++, j += 3)
|
||||
{
|
||||
Vertices.Add(Transform.InverseTransformPosition(FVector
|
||||
(
|
||||
ObjectVertices[j].Get()->AsNumber(),
|
||||
ObjectVertices[j + 1].Get()->AsNumber(),
|
||||
ObjectVertices[j + 2].Get()->AsNumber()
|
||||
) * ScaleFactor ));
|
||||
}
|
||||
}
|
||||
|
||||
//Parse Faces
|
||||
{
|
||||
const TArray<TSharedPtr<FJsonValue>> FaceVertices = Manager->CombineChunks(Obj->GetArrayField("faces"));
|
||||
Faces.Reserve(FaceVertices.Num());
|
||||
for(const auto VertIndex : FaceVertices)
|
||||
{
|
||||
Faces.Add(VertIndex->AsNumber());
|
||||
}
|
||||
}
|
||||
|
||||
//Parse TextureCoords
|
||||
{
|
||||
const TArray<TSharedPtr<FJsonValue>>* TextCoordArray;
|
||||
if(Obj->TryGetArrayField("textureCoordinates", TextCoordArray))
|
||||
{
|
||||
TArray<TSharedPtr<FJsonValue>> TexCoords = Manager->CombineChunks(*TextCoordArray);
|
||||
if(Transform.Num() != 16) return FMatrix::Identity;
|
||||
|
||||
TextureCoordinates.Reserve(TexCoords.Num() / 2);
|
||||
|
||||
for (int32 i = 0; i + 1 < TexCoords.Num(); i += 2)
|
||||
{
|
||||
TextureCoordinates.Add(FVector2D
|
||||
(
|
||||
TexCoords[i].Get()->AsNumber(),
|
||||
TexCoords[i + 1].Get()->AsNumber()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Parse VertexColors
|
||||
{
|
||||
const TArray<TSharedPtr<FJsonValue>>* ColorArray;
|
||||
if(Obj->TryGetArrayField("colors", ColorArray))
|
||||
FMatrix TransformMatrix;
|
||||
|
||||
for(int32 Row = 0; Row < 4; Row++)
|
||||
for(int32 Col = 0; Col < 4; Col++)
|
||||
{
|
||||
TArray<TSharedPtr<FJsonValue>> Colors = Manager->CombineChunks(*ColorArray);
|
||||
|
||||
VertexColors.Reserve(Colors.Num());
|
||||
|
||||
for (int32 i = 0; i + 1 < Colors.Num(); i ++)
|
||||
{
|
||||
VertexColors.Add(FColor(Colors[i].Get()->AsNumber()));
|
||||
}
|
||||
TransformMatrix.M[Row][Col] = Transform[Row * 4 + Col];
|
||||
}
|
||||
}
|
||||
|
||||
//Parse Optional RenderMaterial
|
||||
if (Obj->HasField("renderMaterial"))
|
||||
{
|
||||
RenderMaterial = NewObject<URenderMaterial>();
|
||||
RenderMaterial->Parse(Obj->GetObjectField("renderMaterial"), Manager);
|
||||
}
|
||||
|
||||
|
||||
AlignVerticesWithTexCoordsByIndex();
|
||||
TransformMatrix = TransformMatrix.GetTransposed();
|
||||
|
||||
return TransformMatrix;
|
||||
}
|
||||
|
||||
void UMesh::SetTransform(const FMatrix& T)
|
||||
{
|
||||
const FMatrix TransformMatrix = T.GetTransposed();
|
||||
|
||||
for(int32 Row = 0; Row < 4; Row++)
|
||||
for(int32 Col = 0; Col < 4; Col++)
|
||||
{
|
||||
Transform[Row * 4 + Col] = TransformMatrix.M[Row][Col];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
FVector UMesh::GetVert(int32 Index) const
|
||||
{
|
||||
Index *= 3;
|
||||
return FVector(
|
||||
Vertices[Index],
|
||||
Vertices[Index + 1],
|
||||
Vertices[Index + 2]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
TArray<FVector> UMesh::GetVerts() const
|
||||
{
|
||||
check(Vertices.Num() % 3 == 0);
|
||||
|
||||
//TODO - Maybe could just use a blit copy assuming 3 floats -> FVector
|
||||
TArray<FVector> VertexVectors;
|
||||
|
||||
const int32 NumberOfVertices = Vertices.Num() / 3;
|
||||
|
||||
VertexVectors.Reserve(NumberOfVertices);
|
||||
|
||||
for (size_t i = 0, j = 0; i < NumberOfVertices; i++, j += 3)
|
||||
{
|
||||
VertexVectors.Add(FVector
|
||||
(
|
||||
Vertices[j],
|
||||
Vertices[j + 1],
|
||||
Vertices[j + 2]
|
||||
));
|
||||
}
|
||||
return VertexVectors;
|
||||
}
|
||||
|
||||
|
||||
FVector2D UMesh::GetTextureCoordinate(int32 Index) const
|
||||
{
|
||||
Index *= 2;
|
||||
return FVector2D(TextureCoordinates[Index], TextureCoordinates[Index + 1]);
|
||||
}
|
||||
|
||||
TArray<FVector2D> UMesh::GetTextureCoordinates() const
|
||||
{
|
||||
//TODO - Maybe could just use a blit copy assuming 2 floats -> FVector2D
|
||||
TArray<FVector2D> TexCoords;
|
||||
|
||||
TexCoords.Reserve(TextureCoordinates.Num() / 2);
|
||||
|
||||
for (int32 i = 0; i + 1 < TexCoords.Num(); i += 2)
|
||||
{
|
||||
TexCoords.Add(FVector2D
|
||||
(
|
||||
TextureCoordinates[i],
|
||||
TextureCoordinates[i + 1]
|
||||
));
|
||||
}
|
||||
return TexCoords;
|
||||
}
|
||||
|
||||
FColor UMesh::GetVertexColor(int32 Index) const
|
||||
{
|
||||
return FColor(Colors[Index]);
|
||||
}
|
||||
|
||||
TArray<FColor> UMesh::GetVertexColors() const
|
||||
{
|
||||
TArray<FColor> VertexColors;
|
||||
|
||||
VertexColors.Reserve(Colors.Num());
|
||||
|
||||
for (int32 i = 0; i + 1 < Colors.Num(); i ++)
|
||||
{
|
||||
VertexColors.Add(FColor(Colors[i]));
|
||||
}
|
||||
|
||||
return VertexColors;
|
||||
}
|
||||
|
||||
|
||||
@@ -115,12 +125,12 @@ void UMesh::AlignVerticesWithTexCoordsByIndex()
|
||||
if(TextureCoordinates.Num() == 0) return;
|
||||
if(TextureCoordinates.Num() == Vertices.Num()) return; //Tex-coords already aligned as expected
|
||||
|
||||
TArray<int> FacesUnique;
|
||||
TArray<int32> FacesUnique;
|
||||
FacesUnique.Reserve(Faces.Num());
|
||||
TArray<FVector> VerticesUnique;
|
||||
VerticesUnique.Reserve(TextureCoordinates.Num());
|
||||
const bool HasColor = VertexColors.Num() > 0;
|
||||
TArray<FColor> ColorsUnique;
|
||||
TArray<float> VerticesUnique;
|
||||
VerticesUnique.Reserve(TextureCoordinates.Num() * 3);
|
||||
const bool HasColor = Colors.Num() > 0;
|
||||
TArray<int32> ColorsUnique;
|
||||
if(HasColor) ColorsUnique.Reserve(TextureCoordinates.Num());
|
||||
|
||||
int32 NIndex = 0;
|
||||
@@ -140,14 +150,35 @@ void UMesh::AlignVerticesWithTexCoordsByIndex()
|
||||
|
||||
VerticesUnique.Add(Vertices[VertIndex]);
|
||||
|
||||
if(HasColor) ColorsUnique.Add(VertexColors[NewVertIndex]);
|
||||
if(HasColor) ColorsUnique.Add(Colors[NewVertIndex]);
|
||||
FacesUnique.Add(NewVertIndex);
|
||||
}
|
||||
NIndex += n + 1;
|
||||
}
|
||||
|
||||
Vertices = VerticesUnique;
|
||||
VertexColors = ColorsUnique;
|
||||
Colors = ColorsUnique;
|
||||
Faces = FacesUnique;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void UMesh::ApplyScaleFactor(const float ScaleFactor)
|
||||
{
|
||||
for (size_t i = 0; i < Vertices.Num(); i++)
|
||||
{
|
||||
Vertices[i] *= ScaleFactor;
|
||||
}
|
||||
|
||||
FMatrix Transform = GetTransform();
|
||||
Transform.ScaleTranslation(FVector(ScaleFactor));
|
||||
|
||||
}
|
||||
|
||||
void UMesh::ApplyUnits(const UWorld* World)
|
||||
{
|
||||
const UWorld* CheckedWorld = IsValid(World)? World : GetWorld();
|
||||
const float ScaleFactor = UConversionUtils::GetUnitsScaleFactor(Units, CheckedWorld);
|
||||
ApplyScaleFactor(ScaleFactor);
|
||||
|
||||
Units = "cm";
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "JsonObjectConverter.h"
|
||||
#include "SpeckleUnrealActor.h"
|
||||
#include "SpeckleUnrealManager.h"
|
||||
#include "Objects/Mesh.h"
|
||||
@@ -98,7 +99,7 @@ bool ASpeckleUnrealManager::TryGetMaterial(const URenderMaterial* SpeckleMateria
|
||||
}
|
||||
|
||||
UBase* ASpeckleUnrealManager::DeserializeBase(const TSharedPtr<FJsonObject> Obj) const
|
||||
{
|
||||
{
|
||||
{ // Handle Detached Objects
|
||||
TSharedPtr<FJsonObject> DetachedObject;
|
||||
if(ResolveReference(Obj, DetachedObject))
|
||||
@@ -111,22 +112,192 @@ UBase* ASpeckleUnrealManager::DeserializeBase(const TSharedPtr<FJsonObject> Obj)
|
||||
if (!Obj->TryGetStringField("speckle_type", SpeckleType)) return nullptr;
|
||||
FString ObjectId = "";
|
||||
Obj->TryGetStringField("id", ObjectId);
|
||||
|
||||
const TSubclassOf<UBase> BaseType = UBase::FindClosestType(SpeckleType);
|
||||
|
||||
// Get the registered type from Base register
|
||||
const TSubclassOf<UBase> ObjectType = UBase::FindClosestType(SpeckleType);
|
||||
|
||||
if(BaseType == nullptr)
|
||||
if(ObjectType == nullptr)
|
||||
{
|
||||
UE_LOG(LogTemp, Verbose, TEXT("SpeckleType: %s is unknown,%t object: %s will be ignored"), *SpeckleType, *ObjectId );
|
||||
return nullptr; //BaseType = UBase::StaticClass();
|
||||
}
|
||||
|
||||
|
||||
UBase* Base = NewObject<UBase>(GetTransientPackage(), BaseType);
|
||||
Base->Parse(Obj, this);
|
||||
|
||||
//TODO before we create and deserialised a new object, first check if we have already deserialised this object
|
||||
|
||||
//Create instance of the ObjectType
|
||||
UBase* Base = NewObject<UBase>(GetTransientPackage(), ObjectType);
|
||||
|
||||
//Map of all properties with no explicit UProperty to set.
|
||||
//For now we add all values to this map, then remove the ones we find explicit UProperties for.
|
||||
auto DynamicProperties = TMap<FString, TSharedPtr<FJsonValue>>(Obj->Values);
|
||||
|
||||
//Loop through each UProperty in the UBase and try and set its value from the JSON obj
|
||||
for (TFieldIterator<UProperty> It(ObjectType); It; ++It)
|
||||
{
|
||||
FProperty* Property = *It;
|
||||
void* PropertyValueAddress = Property->ContainerPtrToValuePtr<uint8>(Base);
|
||||
|
||||
// Find a json value matching this property name
|
||||
const FString Key = Property->GetName();
|
||||
const TSharedPtr<FJsonValue>* JsonValuePtr = Obj->Values.Find(Key);
|
||||
|
||||
|
||||
//Ensure value is valid
|
||||
if (!JsonValuePtr) continue;
|
||||
TSharedPtr<FJsonValue> JsonValue = *JsonValuePtr;
|
||||
if ( (!JsonValue.IsValid()) || JsonValue->IsNull() ) continue;
|
||||
|
||||
//Handle chunked values!!!!!
|
||||
if (const FArrayProperty* ArrayProperty = CastField<FArrayProperty>(Property))
|
||||
{
|
||||
const TSharedPtr<FJsonObject>* ChunkedObject;
|
||||
FString ChunkedType;
|
||||
if(JsonValue->TryGetObject(ChunkedObject)
|
||||
&& ChunkedObject->operator->()->TryGetStringField("", ChunkedType)
|
||||
&& ChunkedType == "Speckle.Core.Models.DataChunk")
|
||||
{
|
||||
const TArray<TSharedPtr<FJsonValue>>* ChunkedArray;
|
||||
if(JsonValue->TryGetArray(ChunkedArray))
|
||||
{
|
||||
auto Arr = CombineChunks(*ChunkedArray);
|
||||
if()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Check if property is a Speckle Object
|
||||
if (const FObjectProperty* ObjectProperty = CastField<FObjectProperty>(Property))
|
||||
{
|
||||
UBase* SpeckleObject;
|
||||
if(TryParseSpeckleObjectFromJsonProperty(JsonValue, SpeckleObject))
|
||||
{
|
||||
ObjectProperty->SetObjectPropertyValue(PropertyValueAddress, SpeckleObject);
|
||||
DynamicProperties.Remove(Key);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//Handle primitive types
|
||||
if(FJsonObjectConverter::JsonValueToUProperty(JsonValue, Property, PropertyValueAddress, 0, 0))
|
||||
{
|
||||
DynamicProperties.Remove(Key);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("Failed to deserialise a value, object id: %s, property key: %s"), *ObjectId, *Key)
|
||||
}
|
||||
}
|
||||
|
||||
//Find any remaining Speckle objects and add them as children
|
||||
TMap<FString, UBase*> ChildBases;
|
||||
{
|
||||
const auto DynamicPropertiesCopy = TMap<FString, TSharedPtr<FJsonValue>>(DynamicProperties);
|
||||
for(const auto& Kvp : DynamicPropertiesCopy)
|
||||
{
|
||||
UBase* ChildObject;
|
||||
if(TryParseSpeckleObjectFromJsonProperty(Kvp.Value, ChildObject))
|
||||
{
|
||||
DynamicProperties.Remove(Kvp.Key);
|
||||
ChildBases.Add(ChildObject->Id, ChildObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Base->DynamicProperties = DynamicProperties;
|
||||
Base->Children = ChildBases;
|
||||
return Base;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool ASpeckleUnrealManager::TryParseSpeckleObjectFromJsonProperty(const TSharedPtr<FJsonValue> JsonValue, UBase*& OutBase) const
|
||||
{
|
||||
const TSharedPtr<FJsonObject>* JsonObjectPtr;
|
||||
if(JsonValue->TryGetObject(JsonObjectPtr))
|
||||
{
|
||||
TSharedPtr<FJsonObject> JsonObject;
|
||||
if(!ResolveReference(*JsonObjectPtr, JsonObject))
|
||||
JsonObject = *JsonObjectPtr;
|
||||
|
||||
if(JsonObject.IsValid())
|
||||
{
|
||||
//Handle Speckle object types
|
||||
OutBase = DeserializeBase(JsonObject);
|
||||
return IsValid(OutBase);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Test(const TSharedPtr<FJsonValue> JsonValue, const FProperty* Property, UObject* Base)
|
||||
{
|
||||
if (const FNumericProperty* NumericProperty = CastField<FNumericProperty>(Property))
|
||||
{
|
||||
if (NumericProperty->IsFloatingPoint())
|
||||
{
|
||||
NumericProperty->SetFloatingPointPropertyValue(Base, JsonValue->AsNumber());
|
||||
}
|
||||
else if (NumericProperty->IsInteger())
|
||||
{
|
||||
NumericProperty->SetIntPropertyValue(Base, (int64)JsonValue->AsNumber());
|
||||
}
|
||||
}
|
||||
else if (const FBoolProperty* BoolProperty = CastField<FBoolProperty>(Property))
|
||||
{
|
||||
// Export bools as bools
|
||||
BoolProperty->SetPropertyValue(Base, JsonValue->AsBool());
|
||||
}
|
||||
else if (const FStrProperty* StringProperty = CastField<FStrProperty>(Property))
|
||||
{
|
||||
StringProperty->SetPropertyValue(Base, JsonValue->AsString());
|
||||
}
|
||||
else if (const FMapProperty* MapProperty = CastField<FMapProperty>(Property))
|
||||
{
|
||||
|
||||
}
|
||||
else if (const FSetProperty* SetProperty = CastField<FSetProperty>(Property))
|
||||
{
|
||||
|
||||
}
|
||||
else if (const FArrayProperty* ArrayProperty = CastField<FArrayProperty>(Property))
|
||||
{
|
||||
if (JsonValue->Type != EJson::Array) return;
|
||||
|
||||
const TArray< TSharedPtr<FJsonValue> > ArrayValue = JsonValue->AsArray();
|
||||
int32 ArrLen = ArrayValue.Num();
|
||||
|
||||
// make the output array size match
|
||||
|
||||
}
|
||||
else if (const FStructProperty *StructProperty = CastField<FStructProperty>(Property))
|
||||
{
|
||||
|
||||
}
|
||||
else if (const FObjectProperty *ObjectProperty = CastField<FObjectProperty>(Property))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool ASpeckleUnrealManager::HasObject(const FString& Id) const
|
||||
{
|
||||
return SpeckleObjects.Contains(Id);
|
||||
@@ -139,7 +310,7 @@ TSharedPtr<FJsonObject, ESPMode::Fast> ASpeckleUnrealManager::GetSpeckleObject(c
|
||||
|
||||
bool ASpeckleUnrealManager::ResolveReference(const TSharedPtr<FJsonObject> Object, TSharedPtr<FJsonObject>& OutObject) const
|
||||
{
|
||||
FString SpeckleType;
|
||||
FString SpeckleType;
|
||||
FString ReferenceID;
|
||||
|
||||
if (Object->TryGetStringField("speckle_type", SpeckleType)
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
//#pragma once
|
||||
|
||||
|
||||
//#include "CoreMinimal.h"
|
||||
|
||||
//#include "Client.generated.h"
|
||||
//
|
||||
// /**
|
||||
// *
|
||||
// */
|
||||
// UCLASS()
|
||||
// class SPECKLEUNREAL_API UClient : public UClass
|
||||
// {
|
||||
// GENERATED_BODY()
|
||||
//
|
||||
// public:
|
||||
//
|
||||
// static int DefaultBranchLimit = 10;
|
||||
//
|
||||
// //UFUNCTION(BlueprintPure, Category="Speckle")
|
||||
// //void GetAccounts();
|
||||
//
|
||||
// //UFUNCTION(BlueprintPure, Category="Speckle")
|
||||
// //Branch StreamGetBranches(FString StreamID, int BranchesLimit = DefaultBranchLimit, int CommitLimit = DefaultBranchLimit);
|
||||
//
|
||||
//
|
||||
// };
|
||||
@@ -1,13 +0,0 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class FSpeckleTypeConverter
|
||||
{
|
||||
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "SpeckleOperationsComponent.generated.h"
|
||||
|
||||
|
||||
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
||||
class SPECKLEUNREAL_API USpeckleOperationsComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this component's properties
|
||||
USpeckleOperationsComponent();
|
||||
|
||||
|
||||
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "ConversionUtils.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class SPECKLEUNREAL_API UConversionUtils : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Speckle|Conversion Utilities")
|
||||
static FMatrix TransformToNative(const TArray<float>& TransformData);
|
||||
|
||||
//Parses units string into
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure)
|
||||
static float GetUnitsScaleFactorF(const FString& Units, const float WorldToCentimeters = 1);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure)
|
||||
static float GetUnitsScaleFactor(const FString& Units, const UWorld* World = nullptr);
|
||||
|
||||
//Safely try and get the WorldToCentimeters unit scale factor from the given world.
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure)
|
||||
static bool TryGetWorldUnits(const UWorld* World, int32& OutWorldToCentimeters);
|
||||
};
|
||||
@@ -3,7 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Conversion/SpeckleConverter.h"
|
||||
#include "Conversion/SpeckleTypeConverter.h"
|
||||
|
||||
#include "PointCloudConverter.generated.h"
|
||||
|
||||
@@ -13,7 +13,7 @@ class ULidarPointCloud;
|
||||
class UPointCloud;
|
||||
|
||||
UCLASS()
|
||||
class SPECKLEUNREAL_API UPointCloudConverter : public UObject, public ISpeckleConverter
|
||||
class SPECKLEUNREAL_API UPointCloudConverter : public UObject, public ISpeckleTypeConverter
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Conversion/SpeckleConverter.h"
|
||||
#include "Conversion/SpeckleTypeConverter.h"
|
||||
|
||||
#include "ProceduralMeshConverter.generated.h"
|
||||
|
||||
@@ -12,7 +12,7 @@ class UMesh;
|
||||
class URenderMaterial;
|
||||
|
||||
UCLASS()
|
||||
class SPECKLEUNREAL_API UProceduralMeshConverter : public UObject, public ISpeckleConverter
|
||||
class SPECKLEUNREAL_API UProceduralMeshConverter : public UObject, public ISpeckleTypeConverter
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -27,6 +27,9 @@ public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
TSubclassOf<AActor> MeshActorType;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool bCreateCollisions;
|
||||
|
||||
// Sets default values for this actor's properties
|
||||
UProceduralMeshConverter();
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Conversion/SpeckleConverter.h"
|
||||
#include "Conversion/SpeckleTypeConverter.h"
|
||||
|
||||
#include "StaticMeshConverter.generated.h"
|
||||
|
||||
@@ -12,7 +12,7 @@ class UMesh;
|
||||
class URenderMaterial;
|
||||
|
||||
UCLASS()
|
||||
class SPECKLEUNREAL_API UStaticMeshConverter : public UObject, public ISpeckleConverter
|
||||
class SPECKLEUNREAL_API UStaticMeshConverter : public UObject, public ISpeckleTypeConverter
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "SpeckleConverterComponent.generated.h"
|
||||
|
||||
class USpeckleConverter;
|
||||
class USpeckleTypeConverter;
|
||||
class ASpeckleUnrealManager;
|
||||
class UBase;
|
||||
class ISpeckleConverter;
|
||||
class ISpeckleTypeConverter;
|
||||
|
||||
/**
|
||||
* This component contains modular conversion functions for converting Speckle Objects <--> Native Unreal Objects.
|
||||
*/
|
||||
UCLASS(ClassGroup=(Speckle), meta=(BlueprintSpawnableComponent))
|
||||
class SPECKLEUNREAL_API USpeckleConverterComponent : public UActorComponent
|
||||
{
|
||||
@@ -19,7 +22,7 @@ class SPECKLEUNREAL_API USpeckleConverterComponent : public UActorComponent
|
||||
protected:
|
||||
|
||||
// A lazily initialised mapping of SpeckleType -> converters.
|
||||
TMap<TSubclassOf<UBase>, TScriptInterface<ISpeckleConverter>> SpeckleTypeMap;
|
||||
TMap<TSubclassOf<UBase>, TScriptInterface<ISpeckleTypeConverter>> SpeckleTypeMap;
|
||||
|
||||
public:
|
||||
|
||||
@@ -45,7 +48,7 @@ public:
|
||||
AActor* ConvertToNative(const UBase* Object, ASpeckleUnrealManager* Manager);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Speckle|Conversion")
|
||||
TScriptInterface<ISpeckleConverter> GetConverter(const TSubclassOf<UBase> BaseType);
|
||||
TScriptInterface<ISpeckleTypeConverter> GetConverter(const TSubclassOf<UBase> BaseType);
|
||||
};
|
||||
|
||||
|
||||
|
||||
+11
-4
@@ -6,22 +6,29 @@
|
||||
#include "Objects/Base.h"
|
||||
#include "UObject/Interface.h"
|
||||
|
||||
#include "SpeckleConverter.generated.h"
|
||||
#include "SpeckleTypeConverter.generated.h"
|
||||
|
||||
class UBase;
|
||||
class ASpeckleUnrealManager;
|
||||
|
||||
// This class does not need to be modified.
|
||||
UINTERFACE()
|
||||
class USpeckleConverter : public UInterface
|
||||
class USpeckleTypeConverter : public UInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
/**
|
||||
* Interfaces for conversion functions (ToSpeckle and ToNative) of a specific native type.
|
||||
* Interfaces for object conversion functions (ToSpeckle and ToNative) of a specific (most likely single) native type.
|
||||
*
|
||||
* Classes implementing this function are responsible for converting one or more UBase types
|
||||
* to a native AActor. (ToNative)
|
||||
* And/Or
|
||||
* Converting one or more AActor types to a UBase type.
|
||||
*
|
||||
* Note: This interface is not equivalent to ISpeckleConverter in the .NET SDK.
|
||||
*/
|
||||
class SPECKLEUNREAL_API ISpeckleConverter
|
||||
class SPECKLEUNREAL_API ISpeckleTypeConverter
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -43,11 +43,16 @@ public:
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Speckle|Objects")
|
||||
FString SpeckleType;
|
||||
|
||||
//TODO this won't be serialised
|
||||
TMap<FString, TSharedPtr<FJsonValue>> DynamicProperties;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="Speckle|Objects")
|
||||
TMap<FString, UBase*> Children;
|
||||
|
||||
virtual void Parse(const TSharedPtr<FJsonObject> Obj, const ASpeckleUnrealManager* Manager)
|
||||
{
|
||||
Obj->TryGetStringField("id", Id);
|
||||
Obj->TryGetStringField("units", Units);
|
||||
}
|
||||
/// Callback called right before serialization of this object
|
||||
virtual void OnBeforeSerialize();
|
||||
/// Callback called right after deserialization of this object
|
||||
virtual void OnAfterDeserialize();
|
||||
};
|
||||
|
||||
|
||||
@@ -22,25 +22,56 @@ public:
|
||||
UMesh() : UBase(TEXT("Objects.Geometry.Mesh")) {}
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Speckle|Objects")
|
||||
TArray<FVector> Vertices;
|
||||
TArray<float> Vertices;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Speckle|Objects")
|
||||
TArray<int32> Faces;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Speckle|Objects")
|
||||
TArray<FVector2D> TextureCoordinates;
|
||||
TArray<float> TextureCoordinates;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Speckle|Objects")
|
||||
TArray<FColor> VertexColors;
|
||||
TArray<int32> Colors;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Speckle|Objects")
|
||||
FMatrix Transform;
|
||||
|
||||
TArray<float> Transform;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Speckle|Objects")
|
||||
URenderMaterial* RenderMaterial;
|
||||
|
||||
virtual void Parse(const TSharedPtr<FJsonObject> Obj, const ASpeckleUnrealManager* Manager) override;
|
||||
|
||||
protected:
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
FVector GetVert(int32 Index) const;
|
||||
UFUNCTION(BlueprintPure)
|
||||
TArray<FVector> GetVerts() const;
|
||||
UFUNCTION(BlueprintPure)
|
||||
int32 GetVertexCount() const { return Vertices.Num() / 3; }
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
FVector2D GetTextureCoordinate(int32 Index) const;
|
||||
UFUNCTION(BlueprintPure)
|
||||
TArray<FVector2D> GetTextureCoordinates() const;
|
||||
UFUNCTION(BlueprintPure)
|
||||
int32 GetTexCoordCount() const { return TextureCoordinates.Num() / 2; }
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
FORCEINLINE FColor GetVertexColor(int32 Index) const;
|
||||
UFUNCTION(BlueprintPure)
|
||||
TArray<FColor> GetVertexColors() const;
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
FMatrix GetTransform() const;
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void SetTransform(const FMatrix& T);
|
||||
|
||||
UFUNCTION()
|
||||
virtual void AlignVerticesWithTexCoordsByIndex();
|
||||
|
||||
UFUNCTION()
|
||||
virtual void ApplyScaleFactor(const float ScaleFactor);
|
||||
|
||||
UFUNCTION()
|
||||
virtual void ApplyUnits(const UWorld* World);
|
||||
|
||||
};
|
||||
|
||||
@@ -19,10 +19,10 @@ public:
|
||||
UPointCloud() : UBase(TEXT("Objects.Other.Pointcloud")) {}
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Speckle|Objects")
|
||||
TArray<FVector> Points;
|
||||
TArray<float> Points;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Speckle|Objects")
|
||||
TArray<FColor> Colors;
|
||||
TArray<int32> Colors;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Speckle|Objects")
|
||||
TArray<float> Sizes;
|
||||
|
||||
@@ -32,10 +32,12 @@ public:
|
||||
double Roughness = 1;
|
||||
|
||||
UPROPERTY()
|
||||
FLinearColor Diffuse = FColor{221,221,221};
|
||||
int32 Diffuse = FColor{221,221,221};
|
||||
|
||||
|
||||
|
||||
UPROPERTY()
|
||||
FLinearColor Emissive = FLinearColor::Black;
|
||||
int32 Emissive = FLinearColor::Black;
|
||||
|
||||
virtual void Parse(const TSharedPtr<FJsonObject> Obj, const ASpeckleUnrealManager* Manager) override
|
||||
{
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Object.h"
|
||||
#include "BaseObjectSerializer.generated.h"
|
||||
|
||||
class UBase;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class SPECKLEUNREAL_API UBaseObjectSerializer : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
//UFUNCTION()
|
||||
//UBase* DeserialiseBase();
|
||||
|
||||
};
|
||||
@@ -119,6 +119,8 @@ protected:
|
||||
float WorldToCentimeters;
|
||||
|
||||
|
||||
bool TryParseSpeckleObjectFromJsonProperty(const TSharedPtr<FJsonValue> JsonValue, UBase*& OutBase) const;
|
||||
|
||||
TMap<FString, TSharedPtr<FJsonObject>> SpeckleObjects;
|
||||
|
||||
UPROPERTY()
|
||||
|
||||
Reference in New Issue
Block a user