Skip to content

Commit 89e329b

Browse files
authored
Fixed bugs of importing assets (carla-simulator#2068)
* Refactor Commandlet + made small fix * fixed scale of assets when importing them * Fixed bug of adding assets automatically, but semantic segmentation to be fixed * small fix + hiding movemeshes call until its stable * Meshes are moved to semantic segmentation folders * Retagging semantic segmentation * Redefined tags, refactor and added comments * Updated Changelog * created a move assets commandlet * Removing RoadRunnerFiles folder * readded flag of only prepare maps in import script * Removing ContentBrowser module * Added Import folder * updated readme * Apply zero rotation * updated doc link * updated readme * refactoring * Adding more comments and refactoring * Removed unnecesary include header files * Remove unnecessary includes in source files
1 parent 2b120e3 commit 89e329b

File tree

9 files changed

+454
-186
lines changed

9 files changed

+454
-186
lines changed

.gitignore

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ Util/Build
66
Install
77

88
/ExportedMaps
9-
/Import
10-
/RoadRunnerFiles/*/
9+
/Import/*/
1110

1211
*.VC.db
1312
*.VC.opendb

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Added Doxygen documentation online with automatic updates through Jenkins pipeline
44
* Fixed client_bounding_boxes.py example script
55
* Exposed in the API: camera, exposure, depth of field, tone mapper and color attributes for the RGB sensor
6+
* Fixed materials and semantic segmentation issues regarding importing assets
67

78
## CARLA 0.9.6
89

Import/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CARLA Simulator
2+
===============
3+
4+
Please, place all the packages containing props and maps tom import in this folder. For more information, see topic [Creating standalone asset packages for distribution](https://carla.readthedocs.io/en/latest/asset_packages_for_dist/)

RoadRunnerFiles/README.txt

-34
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
2+
// de Barcelona (UAB).
3+
//
4+
// This work is licensed under the terms of the MIT license.
5+
// For a copy, see <https://opensource.org/licenses/MIT>.
6+
7+
#include "MoveAssetsCommandlet.h"
8+
9+
UMoveAssetsCommandlet::UMoveAssetsCommandlet()
10+
{
11+
IsClient = false;
12+
IsEditor = true;
13+
IsServer = false;
14+
LogToConsole = true;
15+
}
16+
#if WITH_EDITORONLY_DATA
17+
18+
// NOTE: Assets imported from a map FBX will be classified for semantic
19+
// segmentation as ROAD, ROADLINES AND TERRAIN based on the asset name
20+
// defined in RoadRunner. These tags will be used for moving the meshes
21+
// and for specifying the path to these meshes when spawning them in a world.
22+
namespace SSTags {
23+
// Carla Semantic Segmentation Folder Tags
24+
static const FString ROAD = TEXT("Roads");
25+
static const FString ROADLINES = TEXT("RoadLines");
26+
static const FString TERRAIN = TEXT("Terrain");
27+
28+
// RoadRunner Tags
29+
static const FString R_ROAD = TEXT("RoadNode");
30+
static const FString R_TERRAIN = TEXT("Terrain");
31+
static const FString R_MARKING = TEXT("MarkingNode");
32+
}
33+
34+
FMovePackageParams UMoveAssetsCommandlet::ParseParams(const FString &InParams) const
35+
{
36+
TArray<FString> Tokens;
37+
TArray<FString> Params;
38+
39+
ParseCommandLine(*InParams, Tokens, Params);
40+
41+
// Parse and store package name
42+
FMovePackageParams PackageParams;
43+
FParse::Value(*InParams, TEXT("PackageName="), PackageParams.Name);
44+
45+
// Parse and store maps name in an array
46+
FString Maps;
47+
FParse::Value(*InParams, TEXT("Maps="), Maps);
48+
49+
TArray<FString> MapNames;
50+
Maps.ParseIntoArray(MapNames, TEXT(" "), true);
51+
52+
PackageParams.MapNames = MapNames;
53+
54+
return PackageParams;
55+
}
56+
57+
void UMoveAssetsCommandlet::MoveAssets(const FMovePackageParams &PackageParams)
58+
{
59+
// Create a library instance for loading all the assets
60+
AssetsObjectLibrary = UObjectLibrary::CreateLibrary(UStaticMesh::StaticClass(), false, GIsEditor);
61+
AssetsObjectLibrary->AddToRoot();
62+
63+
// Start loading all the assets in the library and classify them for semantic
64+
// segmentation
65+
for (const auto &Map : PackageParams.MapNames)
66+
{
67+
MoveAssetsFromMapForSemanticSegmentation(PackageParams.Name, Map);
68+
}
69+
}
70+
71+
void MoveFiles(const TArray<UObject *> &Assets, const FString &DestPath)
72+
{
73+
check(DestPath.Len() > 0);
74+
75+
FAssetToolsModule &AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
76+
TArray<FAssetRenameData> AssetsAndNames;
77+
for (auto AssetIt = Assets.CreateConstIterator(); AssetIt; ++AssetIt)
78+
{
79+
UObject *Asset = *AssetIt;
80+
81+
if (!ensure(Asset))
82+
{
83+
continue;
84+
}
85+
86+
new(AssetsAndNames) FAssetRenameData(Asset, DestPath, Asset->GetName());
87+
}
88+
89+
if (AssetsAndNames.Num() > 0)
90+
{
91+
AssetToolsModule.Get().RenameAssetsWithDialog(AssetsAndNames);
92+
}
93+
}
94+
95+
void UMoveAssetsCommandlet::MoveAssetsFromMapForSemanticSegmentation(
96+
const FString &PackageName,
97+
const FString &MapName)
98+
{
99+
// Prepare a UObjectLibrary for moving assets
100+
const FString SrcPath = TEXT("/Game/") + PackageName + TEXT("/Maps/") + MapName;
101+
AssetsObjectLibrary->LoadAssetDataFromPath(*SrcPath);
102+
AssetsObjectLibrary->LoadAssetsFromAssetData();
103+
104+
// Load Assets to move
105+
MapContents.Empty();
106+
AssetsObjectLibrary->GetAssetDataList(MapContents);
107+
AssetsObjectLibrary->ClearLoaded();
108+
109+
TArray<FString> DestinationPaths = {SSTags::ROAD, SSTags::ROADLINES, SSTags::TERRAIN};
110+
111+
// Init Map with keys
112+
TMap<FString, TArray<UObject *>> AssetDataMap;
113+
for (const auto &Paths : DestinationPaths)
114+
{
115+
AssetDataMap.Add(Paths, {});
116+
}
117+
118+
for (const auto &MapAsset : MapContents)
119+
{
120+
// Get AssetName
121+
UStaticMesh *MeshAsset = CastChecked<UStaticMesh>(MapAsset.GetAsset());
122+
FString ObjectName = MeshAsset->GetName();
123+
124+
FString AssetName;
125+
MapAsset.AssetName.ToString(AssetName);
126+
127+
if (SrcPath.Len())
128+
{
129+
130+
const FString CurrentPackageName = MeshAsset->GetOutermost()->GetName();
131+
132+
if (!ensure(CurrentPackageName.StartsWith(SrcPath)))
133+
{
134+
continue;
135+
}
136+
137+
// Bind between tags and classify assets according to semantic
138+
// segmentation
139+
if (AssetName.Contains(SSTags::R_ROAD))
140+
{
141+
AssetDataMap[SSTags::ROAD].Add(MeshAsset);
142+
}
143+
else if (AssetName.Contains(SSTags::R_MARKING))
144+
{
145+
AssetDataMap[SSTags::ROADLINES].Add(MeshAsset);
146+
}
147+
else if (AssetName.Contains(SSTags::R_TERRAIN))
148+
{
149+
AssetDataMap[SSTags::TERRAIN].Add(MeshAsset);
150+
}
151+
}
152+
}
153+
154+
// Move assets to correspoding semantic segmentation folders
155+
for (const auto &Elem : AssetDataMap)
156+
{
157+
FString DestPath = TEXT("/Game/") + PackageName + TEXT("/Static/") + Elem.Key + "/" + MapName;
158+
MoveFiles(Elem.Value, DestPath);
159+
}
160+
}
161+
162+
int32 UMoveAssetsCommandlet::Main(const FString &Params)
163+
{
164+
FMovePackageParams PackageParams = ParseParams(Params);
165+
166+
MoveAssets(PackageParams);
167+
168+
return 0;
169+
}
170+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
2+
// de Barcelona (UAB).
3+
//
4+
// This work is licensed under the terms of the MIT license.
5+
// For a copy, see <https://opensource.org/licenses/MIT>.
6+
7+
#pragma once
8+
9+
#include "Carla/OpenDrive/OpenDriveActor.h"
10+
#include "Commandlets/Commandlet.h"
11+
#include "Runtime/Engine/Classes/Engine/ObjectLibrary.h"
12+
13+
#if WITH_EDITORONLY_DATA
14+
#include "AssetRegistry/Public/AssetRegistryModule.h"
15+
#include "Developer/AssetTools/Public/AssetToolsModule.h"
16+
#endif // WITH_EDITORONLY_DATA
17+
#include "MoveAssetsCommandlet.generated.h"
18+
19+
/// Struct containing Package Params, used for storing the parsed arguments when
20+
/// invoking this commandlet
21+
USTRUCT()
22+
struct CARLA_API FMovePackageParams
23+
{
24+
GENERATED_USTRUCT_BODY()
25+
26+
FString Name;
27+
28+
TArray<FString> MapNames;
29+
};
30+
31+
UCLASS()
32+
class UMoveAssetsCommandlet : public UCommandlet
33+
{
34+
GENERATED_BODY()
35+
36+
public:
37+
38+
/// Default constructor.
39+
UMoveAssetsCommandlet();
40+
#if WITH_EDITORONLY_DATA
41+
42+
/// Parses the command line parameters provided through @a InParams The
43+
/// arguments to parse are the package name and a list of map names
44+
/// concatenated in a string.
45+
FMovePackageParams ParseParams(const FString &InParams) const;
46+
47+
/// Moves all the assets contained in a map from @a SrcPath to @a DestPath
48+
void MoveAssetsFromMapForSemanticSegmentation(const FString &PackageName, const FString &MapName);
49+
50+
/// Moves the meshes of all maps listed in a @PackageParams
51+
void MoveAssets(const FMovePackageParams &PackageParams);
52+
53+
public:
54+
55+
/// Main method and entry of the commandlet, taking as input parameters @a
56+
/// Params.
57+
virtual int32 Main(const FString &Params) override;
58+
59+
#endif // WITH_EDITORONLY_DATA
60+
61+
private:
62+
63+
/// The following data structures are declared as class members and with
64+
/// UPROPERTY macro to avoid UE4 to garbage collect them.
65+
66+
/// Loaded assets from any object library
67+
UPROPERTY()
68+
TArray<FAssetData> AssetDatas;
69+
70+
/// Loaded maps from any object library
71+
UPROPERTY()
72+
TArray<FAssetData> MapContents;
73+
74+
/// Used for loading assets in object library. Loaded Data is stored in
75+
/// AssetDatas.
76+
UPROPERTY()
77+
UObjectLibrary *AssetsObjectLibrary;
78+
};

0 commit comments

Comments
 (0)