@@ -26,6 +26,7 @@ THE SOFTWARE.
26
26
// version 2.0.0 : Add new object oriented API. 1.x API is still provided.
27
27
// * Support line primitive.
28
28
// * Support points primitive.
29
+ // * Support multiple search path for .mtl(v1 API).
29
30
// version 1.4.0 : Modifed ParseTextureNameAndOption API
30
31
// version 1.3.1 : Make ParseTextureNameAndOption API public
31
32
// version 1.3.0 : Separate warning and error message(breaking API of LoadObj)
@@ -436,6 +437,7 @@ class MaterialReader {
436
437
// /
437
438
class MaterialFileReader : public MaterialReader {
438
439
public:
440
+ // Path could contain separator(';' in Windows, ':' in Posix)
439
441
explicit MaterialFileReader (const std::string &mtl_basedir)
440
442
: m_mtlBaseDir(mtl_basedir) {}
441
443
virtual ~MaterialFileReader () {}
@@ -1634,6 +1636,21 @@ static void SplitString(const std::string &s, char delim,
1634
1636
}
1635
1637
}
1636
1638
1639
+ static std::string JoinPath (const std::string &dir,
1640
+ const std::string &filename) {
1641
+ if (dir.empty ()) {
1642
+ return filename;
1643
+ } else {
1644
+ // check '/'
1645
+ char lastChar = *dir.rbegin ();
1646
+ if (lastChar != ' /' ) {
1647
+ return dir + std::string (" /" ) + filename;
1648
+ } else {
1649
+ return dir + filename;
1650
+ }
1651
+ }
1652
+ }
1653
+
1637
1654
void LoadMtl (std::map<std::string, int > *material_map,
1638
1655
std::vector<material_t > *materials, std::istream *inStream,
1639
1656
std::string *warning, std::string *err) {
@@ -2015,27 +2032,59 @@ bool MaterialFileReader::operator()(const std::string &matId,
2015
2032
std::vector<material_t > *materials,
2016
2033
std::map<std::string, int > *matMap,
2017
2034
std::string *warn, std::string *err) {
2018
- std::string filepath;
2019
-
2020
2035
if (!m_mtlBaseDir.empty ()) {
2021
- filepath = std::string (m_mtlBaseDir) + matId;
2022
- } else {
2023
- filepath = matId;
2024
- }
2036
+ #if _WIN32
2037
+ char sep = ' ;' ;
2038
+ #else
2039
+ char sep = ' :' ;
2040
+ #endif
2041
+
2042
+ // https://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g
2043
+ std::vector<std::string> paths;
2044
+ std::istringstream f (m_mtlBaseDir);
2045
+
2046
+ std::string s;
2047
+ while (getline (f, s, sep)) {
2048
+ paths.push_back (s);
2049
+ }
2050
+
2051
+ for (size_t i = 0 ; i < paths.size (); i++) {
2052
+ std::string filepath = JoinPath (paths[i], matId);
2053
+
2054
+ std::ifstream matIStream (filepath.c_str ());
2055
+ if (matIStream) {
2056
+ LoadMtl (matMap, materials, &matIStream, warn, err);
2057
+
2058
+ return true ;
2059
+ }
2060
+ }
2025
2061
2026
- std::ifstream matIStream (filepath.c_str ());
2027
- if (!matIStream) {
2028
2062
std::stringstream ss;
2029
- ss << " Material file [ " << filepath << " ] not found." << std::endl;
2063
+ ss << " Material file [ " << matId
2064
+ << " ] not found in a path : " << m_mtlBaseDir << std::endl;
2030
2065
if (warn) {
2031
2066
(*warn) += ss.str ();
2032
2067
}
2033
2068
return false ;
2034
- }
2035
2069
2036
- LoadMtl (matMap, materials, &matIStream, warn, err);
2070
+ } else {
2071
+ std::string filepath = matId;
2072
+ std::ifstream matIStream (filepath.c_str ());
2073
+ if (matIStream) {
2074
+ LoadMtl (matMap, materials, &matIStream, warn, err);
2037
2075
2038
- return true ;
2076
+ return true ;
2077
+ }
2078
+
2079
+ std::stringstream ss;
2080
+ ss << " Material file [ " << filepath
2081
+ << " ] not found in a path : " << m_mtlBaseDir << std::endl;
2082
+ if (warn) {
2083
+ (*warn) += ss.str ();
2084
+ }
2085
+
2086
+ return false ;
2087
+ }
2039
2088
}
2040
2089
2041
2090
bool MaterialStreamReader::operator ()(const std::string &matId,
0 commit comments