CARLA
MoveAssetsCommandlet.cpp
Go to the documentation of this file.
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 #include "SSTags.h"
10 
12 {
13  IsClient = false;
14  IsEditor = true;
15  IsServer = false;
16  LogToConsole = true;
17 }
18 #if WITH_EDITORONLY_DATA
19 
20 FMovePackageParams UMoveAssetsCommandlet::ParseParams(const FString &InParams) const
21 {
22  TArray<FString> Tokens;
23  TArray<FString> Params;
24 
25  ParseCommandLine(*InParams, Tokens, Params);
26 
27  // Parse and store package name
28  FMovePackageParams PackageParams;
29  FParse::Value(*InParams, TEXT("PackageName="), PackageParams.Name);
30 
31  // Parse and store maps name in an array
32  FString Maps;
33  FParse::Value(*InParams, TEXT("Maps="), Maps);
34 
35  TArray<FString> MapNames;
36  Maps.ParseIntoArray(MapNames, TEXT(" "), true);
37 
38  PackageParams.MapNames = MapNames;
39 
40  return PackageParams;
41 }
42 
43 void UMoveAssetsCommandlet::MoveAssets(const FMovePackageParams &PackageParams)
44 {
45  // Create a library instance for loading all the assets
46  AssetsObjectLibrary = UObjectLibrary::CreateLibrary(UStaticMesh::StaticClass(), false, GIsEditor);
47  AssetsObjectLibrary->AddToRoot();
48 
49  // Start loading all the assets in the library and classify them for semantic
50  // segmentation
51  for (const auto &Map : PackageParams.MapNames)
52  {
53  MoveAssetsFromMapForSemanticSegmentation(PackageParams.Name, Map);
54  }
55 }
56 
57 void MoveFiles(const TArray<UObject *> &Assets, const FString &DestPath)
58 {
59  check(DestPath.Len() > 0);
60 
61  FAssetToolsModule &AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
62  TArray<FAssetRenameData> AssetsAndNames;
63  for (auto AssetIt = Assets.CreateConstIterator(); AssetIt; ++AssetIt)
64  {
65  UObject *Asset = *AssetIt;
66 
67  if (!ensure(Asset))
68  {
69  continue;
70  }
71  AssetsAndNames.Emplace(Asset, DestPath, Asset->GetName());
72  }
73 
74  if (AssetsAndNames.Num() > 0)
75  {
76  AssetToolsModule.Get().RenameAssets(AssetsAndNames);
77  }
78 }
79 
80 void UMoveAssetsCommandlet::MoveAssetsFromMapForSemanticSegmentation(
81  const FString &PackageName,
82  const FString &MapName)
83 {
84  // Prepare a UObjectLibrary for moving assets
85  const FString SrcPath = TEXT("/Game/") + PackageName + TEXT("/Maps/") + MapName;
86  AssetsObjectLibrary->LoadAssetDataFromPath(*SrcPath);
87  AssetsObjectLibrary->LoadAssetsFromAssetData();
88 
89  // Load Assets to move
90  MapContents.Empty();
91  AssetsObjectLibrary->GetAssetDataList(MapContents);
92  AssetsObjectLibrary->ClearLoaded();
93 
94  TArray<FString> DestinationPaths = {SSTags::ROAD, SSTags::ROADLINE, SSTags::TERRAIN, SSTags::GRASS, SSTags::SIDEWALK, SSTags::CURB, SSTags::GUTTER};
95 
96  // Init Map with keys
97  TMap<FString, TArray<UObject *>> AssetDataMap;
98  for (const auto &Paths : DestinationPaths)
99  {
100  AssetDataMap.Add(Paths, {});
101  }
102 
103  for (const auto &MapAsset : MapContents)
104  {
105  // Get AssetName
106  FString AssetName;
107  UStaticMesh *MeshAsset = CastChecked<UStaticMesh>(MapAsset.GetAsset());
108  MapAsset.AssetName.ToString(AssetName);
109 
110  if (SrcPath.Len())
111  {
112 
113  const FString CurrentPackageName = MeshAsset->GetOutermost()->GetName();
114 
115  if (!ensure(CurrentPackageName.StartsWith(SrcPath)))
116  {
117  continue;
118  }
119 
120  // Bind between tags and classify assets according to semantic
121  // segmentation
122  if (AssetName.Contains(SSTags::R_ROAD1) || AssetName.Contains(SSTags::R_ROAD2))
123  {
124  AssetDataMap[SSTags::ROAD].Add(MeshAsset);
125  }
126  else if (AssetName.Contains(SSTags::R_MARKING1) || AssetName.Contains(SSTags::R_MARKING2))
127  {
128  AssetDataMap[SSTags::ROADLINE].Add(MeshAsset);
129  }
130  else if (AssetName.Contains(SSTags::R_TERRAIN))
131  {
132  AssetDataMap[SSTags::TERRAIN].Add(MeshAsset);
133  }
134  else if (AssetName.Contains(SSTags::R_SIDEWALK1) || AssetName.Contains(SSTags::R_SIDEWALK2))
135  {
136  AssetDataMap[SSTags::SIDEWALK].Add(MeshAsset);
137  }
138  else if (AssetName.Contains(SSTags::R_CURB1) || AssetName.Contains(SSTags::R_CURB2))
139  {
140  AssetDataMap[SSTags::CURB].Add(MeshAsset);
141  }
142  else if (AssetName.Contains(SSTags::R_GUTTER1) || AssetName.Contains(SSTags::R_GUTTER2))
143  {
144  AssetDataMap[SSTags::GUTTER].Add(MeshAsset);
145  }
146  else
147  {
148  AssetDataMap[SSTags::TERRAIN].Add(MeshAsset);
149  }
150  }
151  }
152 
153  // Move assets to correspoding semantic segmentation folders
154  for (const auto &Elem : AssetDataMap)
155  {
156  FString DestPath = TEXT("/Game/") + PackageName + TEXT("/Static/") + Elem.Key + "/" + MapName;
157 
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
TArray< FString > MapNames
UMoveAssetsCommandlet()
Default constructor.
Struct containing Package Params, used for storing the parsed arguments when invoking this commandlet...
UObjectLibrary * AssetsObjectLibrary
Used for loading assets in object library.
TArray< FAssetData > MapContents
Loaded maps from any object library.