Ue4 Layer names as Mesh Objects named

Hi Jedd,

it is crucial to name the fetched objects somehow understoodable. Reference ids are not human understood. The Layer name as commited from Rhino whould be nice.

However , layer names are not in SpeckleObject but in ParentObject which I have found that contains all parents.

void ASpeckleUnrealManager::ImportObjectFromCache(AActor* AOwner, const TSharedPtr<FJsonObject> SpeckleObject,
                                                  const TSharedPtr<FJsonObject> ParentObject)
{
	
	// If it doesn't have type then ignore
	if (!SpeckleObject->HasField("speckle_type"))
	{
		UE_LOG(LogTemp, Warning, TEXT("No Speckle Type"));
		return;
	}

	// Check if it is a reference
	if (SpeckleObject->GetStringField("speckle_type") == "reference" && SpeckleObject->HasField("referencedId")) {
		TSharedPtr<FJsonObject> ReferencedObj;
		if (SpeckleObjects.Contains(SpeckleObject->GetStringField("referencedId")))
		{
			ImportObjectFromCache(AOwner, SpeckleObjects[SpeckleObject->GetStringField("referencedId")], ParentObject);
			UE_LOG(LogTemp, Warning, TEXT("It is a reference"));
		}
		return;
	}

	// If it does not have id, then return
	if (!SpeckleObject->HasField("id"))
	{
		UE_LOG(LogTemp, Warning, TEXT("No id"));
		return;
	}
	
	const FString ObjectId = SpeckleObject->GetStringField("id");
	const FString SpeckleType = SpeckleObject->GetStringField("speckle_type");
	
	AActor* Native = nullptr;

	
	if(SpeckleType == "Objects.Geometry.Mesh")
	{
		Native = CreateMesh(SpeckleObject, ParentObject);
	}
	else if(SpeckleType == "Objects.Geometry.Pointcloud")
	{
	    Native = CreatePointCloud(SpeckleObject);
	}
	else if(SpeckleType == "Objects.Other.BlockInstance")
	{
		Native = CreateBlockInstance(SpeckleObject);
	}
	else if(SpeckleType == "Objects.Other.BlockDefinition")
	{
		return; //Ignore block definitions, Block instances will create geometry instead.
	}

	
	if(IsValid(Native))
	{

		// // --  Print as String --
		 FString OutputString;
		 TSharedRef< TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&OutputString);
		 FJsonSerializer::Serialize(SpeckleObject.ToSharedRef(), Writer);
		 UE_LOG(LogTemp, Warning, TEXT("resulting jsonString -> %s"), *OutputString);
		// -- -------------------- --
		
		//--------------
		FString LayerName = "";
		
		// Iterate over Json Values
		if (ParentObject.IsValid())
		{
			for (auto currJsonValue = ParentObject->Values.CreateConstIterator(); currJsonValue; ++currJsonValue)
			{
				// Get the key name
				FString KeyName = (*currJsonValue).Key;
		
				if (KeyName.Contains("::"))
				{
					LayerName = FString::Printf(TEXT("%s"), *KeyName ) ;
					UE_LOG(LogTemp, Warning, TEXT("Key Name -> %s"), *KeyName);
				}
				// Get the value as a FJsonValue object
				//TSharedPtr< FJsonValue > Value = (*currJsonValue).Value;
			}
		}
		UE_LOG(LogTemp, Warning, TEXT("LayerName Name -> %s"), *LayerName);
		//----------------------

#if WITH_EDITOR
		UE_LOG(LogTemp, Warning, TEXT("%s - %s - %s"), *LayerName, *SpeckleType, *ObjectId);
		Native->SetActorLabel(FString::Printf(TEXT("%s - %s - %s"), *LayerName, *SpeckleType, *ObjectId));
#endif
		
        Native->AttachToActor(AOwner, FAttachmentTransformRules::KeepRelativeTransform);
        Native->SetOwner(AOwner);

        InProgressObjectsCache.Add(Native);
	}
	else
	{
		Native = AOwner;
	}
	
	
	//Convert Children
	for (const auto& Kv : SpeckleObject->Values)
	{

		const TSharedPtr<FJsonObject>* SubObjectPtr;
		if (Kv.Value->TryGetObject(SubObjectPtr))
		{
			ImportObjectFromCache(Native, *SubObjectPtr, SpeckleObject);
			continue;
		}

		const TArray<TSharedPtr<FJsonValue>>* SubArrayPtr;
		if (Kv.Value->TryGetArray(SubArrayPtr))
		{
			for (const auto& ArrayElement : *SubArrayPtr)
			{
				const TSharedPtr<FJsonObject>* ArraySubObjPtr;
				if (!ArrayElement->TryGetObject(ArraySubObjPtr))
					continue;
				ImportObjectFromCache(Native, *ArraySubObjPtr, SpeckleObject);
			}
		}
	}
}

So only the last one is got as the LayerName: