// Portage UE 5.5 - voir LPCheckMeshesCommandlet.h #include "LPCheckMeshesCommandlet.h" #include "AssetRegistry/AssetData.h" #include "AssetRegistry/AssetRegistryModule.h" #include "Engine/StaticMesh.h" #include "MeshDescription.h" #include "Misc/FileHelper.h" DEFINE_LOG_CATEGORY_STATIC(LogLPCheckMeshes, Log, All); ULPCheckMeshesCommandlet::ULPCheckMeshesCommandlet() { IsClient = false; IsServer = false; IsEditor = true; LogToConsole = true; } int32 ULPCheckMeshesCommandlet::Main(const FString& Params) { TArray Tokens, Switches; TMap ParamsMap; ParseCommandLine(*Params, Tokens, Switches, ParamsMap); const FString PathFilter = ParamsMap.FindRef(TEXT("Path")); const FString CsvPath = ParamsMap.FindRef(TEXT("CSV")); if (PathFilter.IsEmpty() || CsvPath.IsEmpty()) { UE_LOG(LogLPCheckMeshes, Error, TEXT("Usage : -Path=/Game/Dossier -CSV=")); return 1; } FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked(TEXT("AssetRegistry")); AssetRegistryModule.Get().SearchAllAssets(true); TArray Assets; AssetRegistryModule.Get().GetAssetsByClass(UStaticMesh::StaticClass()->GetClassPathName(), Assets, true); Assets.RemoveAll([&PathFilter](const FAssetData& A) { return !A.PackageName.ToString().StartsWith(PathFilter); }); Assets.Sort([](const FAssetData& A, const FAssetData& B) { return A.AssetName.LexicalLess(B.AssetName); }); TArray Lines; Lines.Add(TEXT("Mesh;LODs;SommetsSource;TrianglesSource;SommetsRendu;TrianglesRendu;Sections;Materiaux;TailleX;TailleY;TailleZ;MinZ;MaxZ")); int32 Failures = 0; for (const FAssetData& AssetData : Assets) { UStaticMesh* Mesh = Cast(AssetData.GetAsset()); if (!Mesh) { ++Failures; Lines.Add(FString::Printf(TEXT("%s;ECHEC"), *AssetData.AssetName.ToString())); continue; } // Donnees sources (MeshDescription) : independantes du format des donnees de rendu. int32 SrcVerts = -1, SrcTris = -1; if (const FMeshDescription* Desc = Mesh->GetMeshDescription(0)) { SrcVerts = Desc->Vertices().Num(); SrcTris = Desc->Triangles().Num(); } // Donnees de rendu (construites ou lues du DDC au chargement dans l'editeur). const int32 RenderVerts = Mesh->GetNumVertices(0); const int32 RenderTris = Mesh->GetNumTriangles(0); const int32 Sections = Mesh->GetNumSections(0); const FBox Box = Mesh->GetBoundingBox(); const FVector Size = Box.GetSize(); Lines.Add(FString::Printf(TEXT("%s;%d;%d;%d;%d;%d;%d;%d;%.0f;%.0f;%.0f;%.2f;%.2f"), *AssetData.AssetName.ToString(), Mesh->GetNumLODs(), SrcVerts, SrcTris, RenderVerts, RenderTris, Sections, Mesh->GetStaticMaterials().Num(), Size.X, Size.Y, Size.Z, Box.Min.Z, Box.Max.Z)); } if (!FFileHelper::SaveStringArrayToFile(Lines, *CsvPath, FFileHelper::EEncodingOptions::ForceUTF8WithoutBOM)) { UE_LOG(LogLPCheckMeshes, Error, TEXT("Ecriture impossible : %s"), *CsvPath); return 1; } UE_LOG(LogLPCheckMeshes, Warning, TEXT("=== %d mesh(es) sous %s, %d echec(s) -> %s ==="), Assets.Num(), *PathFilter, Failures, *CsvPath); return Failures > 0 ? 1 : 0; }