From 1d92f76da2f5b3288dfc165c160d5c151740483f Mon Sep 17 00:00:00 2001 From: Chuck Walbourn Date: Mon, 12 Sep 2016 22:51:26 -0700 Subject: [PATCH] meshconvert: added wildcard support --- Meshconvert/Meshconvert.cpp | 96 ++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 1 deletion(-) diff --git a/Meshconvert/Meshconvert.cpp b/Meshconvert/Meshconvert.cpp index b0dd154d..db52c197 100644 --- a/Meshconvert/Meshconvert.cpp +++ b/Meshconvert/Meshconvert.cpp @@ -34,7 +34,8 @@ using namespace DirectX; enum OPTIONS { - OPT_NORMALS = 1, + OPT_RECURSIVE = 1, + OPT_NORMALS, OPT_WEIGHT_BY_AREA, OPT_WEIGHT_BY_EQUAL, OPT_TANGENTS, @@ -77,6 +78,7 @@ struct SValue SValue g_pOptions[] = { + { L"r", OPT_RECURSIVE }, { L"n", OPT_NORMALS }, { L"na", OPT_WEIGHT_BY_AREA }, { L"ne", OPT_WEIGHT_BY_EQUAL }, @@ -107,6 +109,12 @@ SValue g_pOptions[] = namespace { + inline HANDLE safe_handle(HANDLE h) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; } + + struct find_closer { void operator()(HANDLE h) { assert(h != INVALID_HANDLE_VALUE); if (h) FindClose(h); } }; + + typedef public std::unique_ptr ScopedFindHandle; + #pragma prefast(disable : 26018, "Only used with static internal arrays") DWORD LookupByName(const wchar_t *pName, const SValue *pArray) @@ -137,6 +145,81 @@ namespace } + void SearchForFiles(const wchar_t* path, std::list& files, bool recursive) + { + // Process files + WIN32_FIND_DATA findData = {}; + ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path, + FindExInfoBasic, &findData, + FindExSearchNameMatch, nullptr, + FIND_FIRST_EX_LARGE_FETCH))); + if (hFile) + { + for (;;) + { + if (!(findData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY))) + { + wchar_t drive[_MAX_DRIVE] = {}; + wchar_t dir[_MAX_DIR] = {}; + _wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0); + + SConversion conv; + _wmakepath_s(conv.szSrc, drive, dir, findData.cFileName, nullptr); + files.push_back(conv); + } + + if (!FindNextFile(hFile.get(), &findData)) + break; + } + } + + // Process directories + if (recursive) + { + wchar_t searchDir[MAX_PATH] = {}; + { + wchar_t drive[_MAX_DRIVE] = {}; + wchar_t dir[_MAX_DIR] = {}; + _wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0); + _wmakepath_s(searchDir, drive, dir, L"*", nullptr); + } + + hFile.reset(safe_handle(FindFirstFileExW(searchDir, + FindExInfoBasic, &findData, + FindExSearchLimitToDirectories, nullptr, + FIND_FIRST_EX_LARGE_FETCH))); + if (!hFile) + return; + + for (;;) + { + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + if (findData.cFileName[0] != L'.') + { + wchar_t subdir[MAX_PATH] = {}; + + { + wchar_t drive[_MAX_DRIVE] = {}; + wchar_t dir[_MAX_DIR] = {}; + wchar_t fname[_MAX_FNAME] = {}; + wchar_t ext[_MAX_FNAME] = {}; + _wsplitpath_s(path, drive, dir, fname, ext); + wcscat_s(dir, findData.cFileName); + _wmakepath_s(subdir, drive, dir, fname, ext); + } + + SearchForFiles(subdir, files, recursive); + } + } + + if (!FindNextFile(hFile.get(), &findData)) + break; + } + } + } + + void PrintLogo() { wprintf(L"Microsoft (R) MeshConvert Command-line Tool\n"); @@ -151,6 +234,7 @@ namespace wprintf(L"Usage: meshconvert \n"); wprintf(L"\n"); + wprintf(L" -r wildcard filename search is recursive\n"); wprintf(L" -n | -na | -ne generate normals weighted by angle/area/equal\n"); wprintf(L" -t generate tangents\n"); wprintf(L" -tb generate tangents & bi-tangents\n"); @@ -401,6 +485,16 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[]) break; } } + else if (wcspbrk(pArg, L"?*") != nullptr) + { + size_t count = conversion.size(); + SearchForFiles(pArg, conversion, (dwOptions & (1 << OPT_RECURSIVE)) != 0); + if (conversion.size() <= count) + { + wprintf(L"No matching files found for %ls\n", pArg); + return 1; + } + } else { SConversion conv;