diff --git a/Plugin/abci/Importer/aiContext.cpp b/Plugin/abci/Importer/aiContext.cpp index 19fdc3cb9..2ffb0b049 100644 --- a/Plugin/abci/Importer/aiContext.cpp +++ b/Plugin/abci/Importer/aiContext.cpp @@ -5,6 +5,42 @@ #include "aiAsync.h" +static std::wstring L(const std::string& s) +{ + return std::wstring_convert>().from_bytes(s); +} + +static std::string S(const std::wstring& w) +{ + return std::wstring_convert>().to_bytes(w); +} + +static std::string NormalizePath(const char *in_path) +{ + std::wstring path; + + if (in_path != nullptr) { + path = L(in_path); + +#ifdef _WIN32 + size_t n = path.length(); + for (size_t i = 0; i < n; ++i) { + auto c = path[i]; + if (c == L'\\') { + path[i] = L'/'; + } + else if (c >= L'A' && c <= L'Z') { + path[i] = L'a' + (c - L'A'); + } + } +#endif + } + + return S(path); +} + + + aiContextManager aiContextManager::s_instance; aiContext* aiContextManager::getContext(int uid) @@ -32,7 +68,7 @@ void aiContextManager::destroyContext(int uid) void aiContextManager::destroyContextsWithPath(const char* asset_path) { - auto path = aiContext::normalizePath(asset_path); + auto path = NormalizePath(asset_path); for (auto it = s_instance.m_contexts.begin(); it != s_instance.m_contexts.end();) { if (it->second->getPath() == path) { DebugLog("Unregister context for gameObject with ID %s", it->second->getPath().c_str()); @@ -53,31 +89,6 @@ aiContextManager::~aiContextManager() } -std::string aiContext::normalizePath(const char *in_path) -{ - std::string path; - - if (in_path != nullptr) { - path = in_path; - -#ifdef _WIN32 - size_t n = path.length(); - for (size_t i = 0; i < n; ++i) { - char c = path[i]; - if (c == '\\') { - path[i] = '/'; - } - else if (c >= 'A' && c <= 'Z') { - path[i] = 'a' + (c - 'A'); - } - } -#endif - } - - return path; -} - - aiContext::aiContext(int uid) : m_uid(uid) { @@ -176,13 +187,17 @@ void aiContext::reset() m_top_node.reset(); m_timesamplings.clear(); m_archive.reset(); - m_path = ""; + + m_path.clear(); + for (auto s : m_streams) { delete s; } + m_streams.clear(); + // m_config is not reset intentionally } bool aiContext::load(const char *in_path) { - std::string path = normalizePath(in_path); + auto path = NormalizePath(in_path); DebugLog("aiContext::load: '%s'", path.c_str()); if (path == m_path && m_archive) { @@ -205,10 +220,23 @@ bool aiContext::load(const char *in_path) try { DebugLog("Trying to open AbcCoreOgawa::ReadArchive..."); - m_archive = Abc::IArchive(AbcCoreOgawa::ReadArchive(std::thread::hardware_concurrency()), path); + + // open archive with wstring path and pass it to Abc::IArchive (Abc::IArchive can not use wstring path...) + auto wpath = L(path); + auto ifs = new std::ifstream(wpath.c_str(), std::ios::in | std::ios::binary); + m_streams.push_back(ifs); + + Alembic::AbcCoreOgawa::ReadArchive archive_reader(m_streams); + m_archive = Abc::IArchive(archive_reader(m_path), Abc::kWrapExisting, Abc::ErrorHandler::kThrowPolicy); } catch (Alembic::Util::Exception e) { DebugLog("Failed (%s)", e.what()); + + // hdf5 archive can not use external stream + // (that means if path contains wide characters, we can't open it. I couldn't find solution..) + for (auto s : m_streams) { delete s; } + m_streams.clear(); + try { DebugLog("Trying to open AbcCoreHDF5::ReadArchive..."); m_archive = Abc::IArchive(AbcCoreHDF5::ReadArchive(), path); diff --git a/Plugin/abci/Importer/aiContext.h b/Plugin/abci/Importer/aiContext.h index 12b862623..523d6d68e 100644 --- a/Plugin/abci/Importer/aiContext.h +++ b/Plugin/abci/Importer/aiContext.h @@ -48,9 +48,6 @@ class aiContextManager class aiContext { -public: - static std::string normalizePath(const char *path); - public: explicit aiContext(int uid=-1); ~aiContext(); @@ -85,6 +82,8 @@ class aiContext void reset(); std::string m_path; + std::vector m_streams; + Abc::IArchive m_archive; std::unique_ptr m_top_node; std::vector m_timesamplings; diff --git a/Plugin/abci/pch.h b/Plugin/abci/pch.h index 8c0a17cba..691000def 100644 --- a/Plugin/abci/pch.h +++ b/Plugin/abci/pch.h @@ -12,7 +12,10 @@ #include #include #include +#include #include +#include +#include #include #include #include