diff options
-rw-r--r-- | intern/cycles/blender/blender_python.cpp | 32 | ||||
-rw-r--r-- | intern/cycles/render/osl.cpp | 17 | ||||
-rw-r--r-- | intern/cycles/util/util_path.cpp | 12 | ||||
-rw-r--r-- | intern/cycles/util/util_string.cpp | 44 | ||||
-rw-r--r-- | intern/cycles/util/util_string.h | 5 |
5 files changed, 92 insertions, 18 deletions
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 27eab0c7f68..b2294c8b68e 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -138,19 +138,29 @@ void python_thread_state_restore(void **python_thread_state) static const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce) { -#ifdef WIN32 - /* bug [#31856] oddly enough, Python3.2 --> 3.3 on Windows will throw an - * exception here this needs to be fixed in python: - * see: bugs.python.org/issue15859 */ - if(!PyUnicode_Check(py_str)) { - PyErr_BadArgument(); - return ""; + const char *result = _PyUnicode_AsString(py_str); + if(result) { + /* 99% of the time this is enough but we better support non unicode + * chars since blender doesnt limit this. + */ + return result; } -#endif - if((*coerce = PyUnicode_EncodeFSDefault(py_str))) { - return PyBytes_AS_STRING(*coerce); + else { + PyErr_Clear(); + if(PyBytes_Check(py_str)) { + return PyBytes_AS_STRING(py_str); + } + else if((*coerce = PyUnicode_EncodeFSDefault(py_str))) { + return PyBytes_AS_STRING(*coerce); + } + else { + /* Clear the error, so Cycles can be at leadt used without + * GPU and OSL support, + */ + PyErr_Clear(); + return ""; + } } - return ""; } static PyObject *init_func(PyObject * /*self*/, PyObject *args) diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 78b06a8e6d6..e1c5416b024 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -202,13 +202,26 @@ void OSLShaderManager::shading_system_init() if(ss_shared_users == 0) { services_shared = new OSLRenderServices(); + string shader_path = path_get("shader"); +#ifdef _WIN32 + /* Annoying thing, Cycles stores paths in UTF-8 codepage, so it can + * operate with file paths with any character. This requires to use wide + * char functions, but OSL uses old fashioned ANSI functions which means: + * + * - We have to convert our paths to ANSI before passing to OSL + * - OSL can't be used when there's a multi-byte character in the path + * to the shaders folder. + */ + shader_path = string_to_ansi(shader_path); +#endif + ss_shared = new OSL::ShadingSystem(services_shared, ts_shared, &errhandler); ss_shared->attribute("lockgeom", 1); ss_shared->attribute("commonspace", "world"); - ss_shared->attribute("searchpath:shader", path_get("shader")); + ss_shared->attribute("searchpath:shader", shader_path); ss_shared->attribute("greedyjit", 1); - VLOG(1) << "Using shader search path: " << path_get("shader"); + VLOG(1) << "Using shader search path: " << shader_path; /* our own ray types */ static const char *raytypes[] = { diff --git a/intern/cycles/util/util_path.cpp b/intern/cycles/util/util_path.cpp index b7aa24a831f..468d5c20ee1 100644 --- a/intern/cycles/util/util_path.cpp +++ b/intern/cycles/util/util_path.cpp @@ -56,7 +56,6 @@ typedef struct _stat path_stat_t; # ifndef S_ISDIR # define S_ISDIR(x) (((x) & _S_IFDIR) == _S_IFDIR) # endif -# define mkdir(path, mode) _mkdir(path) #else typedef struct stat path_stat_t; #endif @@ -626,7 +625,12 @@ static bool create_directories_recursivey(const string& path) } } +#ifdef _WIN32 + wstring path_wc = string_to_wstring(path); + return _wmkdir(path_wc.c_str()) == 0; +#else return mkdir(path.c_str(), 0777) == 0; +#endif } void path_create_directories(const string& filepath) @@ -745,7 +749,13 @@ string path_source_replace_includes(const string& source_, const string& path) FILE *path_fopen(const string& path, const string& mode) { +#ifdef _WIN32 + wstring path_wc = string_to_wstring(path); + wstring mode_wc = string_to_wstring(mode); + return _wfopen(path_wc.c_str(), mode_wc.c_str()); +#else return fopen(path.c_str(), mode.c_str()); +#endif } void path_cache_clear_except(const string& name, const set<string>& except) diff --git a/intern/cycles/util/util_string.cpp b/intern/cycles/util/util_string.cpp index 51306a249cd..b3a8c6d7c2e 100644 --- a/intern/cycles/util/util_string.cpp +++ b/intern/cycles/util/util_string.cpp @@ -165,14 +165,14 @@ string string_from_bool(bool var) wstring string_to_wstring(const string& str) { - const int length_wc = MultiByteToWideChar(CP_ACP, + const int length_wc = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0); wstring str_wc(length_wc, 0); - MultiByteToWideChar(CP_ACP, + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), @@ -183,7 +183,7 @@ wstring string_to_wstring(const string& str) string string_from_wstring(const wstring& str) { - int length_mb = WideCharToMultiByte(CP_ACP, + int length_mb = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.size(), @@ -191,7 +191,7 @@ string string_from_wstring(const wstring& str) 0, NULL, NULL); string str_mb(length_mb, 0); - WideCharToMultiByte(CP_ACP, + WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.size(), @@ -201,6 +201,42 @@ string string_from_wstring(const wstring& str) return str_mb; } +string string_to_ansi(const string& str) +{ + const int length_wc = MultiByteToWideChar(CP_UTF8, + 0, + str.c_str(), + str.length(), + NULL, + 0); + wstring str_wc(length_wc, 0); + MultiByteToWideChar(CP_UTF8, + 0, + str.c_str(), + str.length(), + &str_wc[0], + length_wc); + + int length_mb = WideCharToMultiByte(CP_ACP, + 0, + str_wc.c_str(), + str_wc.size(), + NULL, + 0, + NULL, NULL); + + string str_mb(length_mb, 0); + WideCharToMultiByte(CP_ACP, + 0, + str_wc.c_str(), + str_wc.size(), + &str_mb[0], + length_mb, + NULL, NULL); + + return str_mb; +} + #endif /* _WIN32 */ CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_string.h b/intern/cycles/util/util_string.h index d73ab15d784..c4b51bda432 100644 --- a/intern/cycles/util/util_string.h +++ b/intern/cycles/util/util_string.h @@ -50,11 +50,16 @@ string string_from_bool(const bool var); /* Wide char strings are only used on Windows to deal with non-ascii * characters in file names and such. No reason to use such strings * for something else at this moment. + * + * Please note that strings are expected to be in UTF-8 codepage, and + * if ANSI is needed then explicit conversion required. + * */ #ifdef _WIN32 using std::wstring; wstring string_to_wstring(const string& path); string string_from_wstring(const wstring& path); +string string_to_ansi(const string& str); #endif CCL_NAMESPACE_END |