Commit: 722a793b74875a8f8a6df558bfa10628042817d5
Author: Ankit Meel
Date: Tue Aug 4 18:53:17 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rB722a793b74875a8f8a6df558bfa10628042817d5
MTL: use mtllib for importing MTL files.
Create a utility function for splitting lines into the first words
& the rest of it.
===================================================================
M source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
M source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.hh
M source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.cc
M source/blender/io/wavefront_obj/intern/wavefront_obj_im_objects.hh
M source/blender/io/wavefront_obj/intern/wavefront_obj_importer.cc
===================================================================
diff --git
a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
index c39218cfa2b..3b3e45f5ba9 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.cc
@@ -55,13 +55,22 @@ static void split_by_char(const string &in_string, char
delimiter, Vector<string
}
/**
- * Return substring of the given string from the start upto the first ` ` if
encountered.
- * If no space is found in the string, return the first character.
+ * Split a line string into the first word (key) and the rest of the line with
the
+ * first space in the latter removed.
*/
-static string first_word_of_string(const string &in_string)
+static void split_line_key_rest(std::string_view line, string &r_line_key,
string &r_rest_line)
{
- size_t pos = in_string.find_first_of(' ');
- return pos == string::npos ? in_string.substr(0, 1) : in_string.substr(0,
pos);
+ if (line.empty()) {
+ return;
+ }
+ size_t pos = line.find_first_of(' ');
+ r_line_key = pos == string::npos ? line.substr(0, 1) : line.substr(0, pos);
+ r_rest_line = line.substr(r_line_key.size(), string::npos);
+ if (r_rest_line.empty()) {
+ return;
+ }
+ /* Remove the initial space. */
+ r_rest_line.erase(0, 1);
}
/**
@@ -200,10 +209,16 @@ void
OBJParser::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of_o
string object_group{};
while (std::getline(obj_file_, line)) {
- string line_key{first_word_of_string(line)};
- string rest_line{line.substr(line_key.size())};
+ string line_key{}, rest_line{};
+ split_line_key_rest(line, line_key, rest_line);
+ if (line.empty() || rest_line.empty()) {
+ continue;
+ }
- if (line_key == "o") {
+ if (line_key == "mtllib") {
+ mtl_libraries_.append(rest_line);
+ }
+ else if (line_key == "o") {
/* Update index offsets to keep track of objects which have claimed
their vertices. */
update_index_offsets(curr_ob);
shaded_smooth = false;
@@ -386,6 +401,14 @@ void
OBJParser::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of_o
}
}
+/**
+ * Return a list of all material library filepaths referenced by in the OBJ
file.
+ */
+Span<std::string> OBJParser::mtl_libraries() const
+{
+ return mtl_libraries_;
+}
+
/**
* Get the texture map from the MTLMaterial struct corresponding to the given
string.
*/
@@ -415,12 +438,11 @@ static tex_map_XX *get_tex_map_of_type(MTLMaterial
*mtl_mat, StringRef tex_map_s
return nullptr;
}
-MTLParser::MTLParser(const OBJImportParams &import_params) :
import_params_(import_params)
+MTLParser::MTLParser(StringRef mtl_library, StringRef obj_filepath) :
mtl_library_(mtl_library)
{
- /* Try to open an MTL file with the same name as the OBJ. */
- // TODO ankitm change it to get filename/path from OBJ file.
- BLI_strncpy(mtl_file_path_, import_params_.filepath, FILE_MAX);
- BLI_path_extension_replace(mtl_file_path_, FILE_MAX, ".mtl");
+ char obj_file_dir[FILE_MAXDIR];
+ BLI_split_dir_part(obj_filepath.data(), obj_file_dir, FILE_MAXDIR);
+ BLI_path_join(mtl_file_path_, FILE_MAX, obj_file_dir, mtl_library_.data(),
NULL);
mtl_file_.open(mtl_file_path_);
}
@@ -433,11 +455,11 @@ void MTLParser::parse_and_store(Map<string, MTLMaterial>
&mtl_materials)
string line;
MTLMaterial *curr_mtlmat = nullptr;
while (std::getline(mtl_file_, line)) {
- if (line.empty()) {
+ string line_key{}, rest_line{};
+ split_line_key_rest(line, line_key, rest_line);
+ if (line.empty() || rest_line.empty()) {
continue;
}
- string line_key{first_word_of_string(line)};
- string rest_line{line.substr(line_key.size())};
if (line_key == "newmtl") {
MTLMaterial new_mtl;
diff --git
a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.hh
b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.hh
index 481ea81b896..983dec3b0cf 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.hh
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_file_reader.hh
@@ -33,6 +33,7 @@ class OBJParser {
private:
const OBJImportParams &import_params_;
std::ifstream obj_file_;
+ Vector<std::string> mtl_libraries_{};
/**
* These two numbers VERTEX_OFF and UV_VERTEX_OFF respectively keep track of
how many vertices
* have been occupied by other objects. It is used when an index must stay
local to an object,
@@ -45,6 +46,7 @@ class OBJParser {
void parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of_objects,
GlobalVertices &global_vertices);
+ Span<std::string> mtl_libraries() const;
void print_obj_data(Span<std::unique_ptr<OBJRawObject>> list_of_objects,
const GlobalVertices &global_vertices);
@@ -54,12 +56,12 @@ class OBJParser {
class MTLParser {
private:
- const OBJImportParams &import_params_;
+ StringRef mtl_library_;
char mtl_file_path_[FILE_MAX]{};
std::ifstream mtl_file_;
public:
- MTLParser(const OBJImportParams &import_params);
+ MTLParser(StringRef mtl_library_, StringRef obj_filepath);
void parse_and_store(Map<std::string, MTLMaterial> &mtl_materials);
};
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.cc
b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.cc
index 32375f99913..4a3faf5b0a9 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.cc
@@ -101,6 +101,10 @@ ShaderNodetreeWrap::~ShaderNodetreeWrap()
shader_output_.release();
}
+/**
+ * Release nodetree for materials to own it. nodetree has its unique deleter
+ * if destructor is not reached for some reason.
+ */
bNodeTree *ShaderNodetreeWrap::get_nodetree()
{
return nodetree_.release();
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_objects.hh
b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_objects.hh
index e27c540625e..9a69cb94a87 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_objects.hh
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_objects.hh
@@ -177,6 +177,7 @@ struct MTLMaterial {
tex_map_XX map_Bump;
/** Only used for Normal Map node: map_Bump. */
float map_Bump_value = 0.0f;
+
Span<eTextureMapType> all_tex_map_types() const;
const tex_map_XX &tex_map_of_type(eTextureMapType type) const;
};
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_importer.cc
b/source/blender/io/wavefront_obj/intern/wavefront_obj_importer.cc
index d9a00c93367..455635bf522 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_importer.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_importer.cc
@@ -117,11 +117,14 @@ void importer_main(bContext *C, const OBJImportParams
&import_params)
Vector<std::unique_ptr<OBJRawObject>> list_of_objects;
GlobalVertices global_vertices;
Map<std::string, MTLMaterial> materials;
- OBJParser obj_parser{import_params};
- MTLParser mtl_parser{import_params};
+ OBJParser obj_parser{import_params};
obj_parser.parse_and_store(list_of_objects, global_vertices);
- mtl_parser.parse_and_store(materials);
+
+ for (StringRef mtl_library : obj_parser.mtl_libraries()) {
+ MTLParser mtl_parser{mtl_library, import_params.filepath};
+ mtl_parser.parse_and_store(materials);
+ }
obj_parser.print_obj_data(list_of_objects, global_vertices);
raw_to_blender_objects(bmain, scene, list_of_objects, global_vertices,
materials);
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs