[Bf-blender-cvs] [19145856ba7] soc-2020-io-performance: Add MTL parser.

Ankit Meel noreply at git.blender.org
Thu Jul 30 15:02:01 CEST 2020


Commit: 19145856ba7a7cfa0668b3864ef4b37cd7a2f436
Author: Ankit Meel
Date:   Thu Jul 30 18:24:52 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rB19145856ba7a7cfa0668b3864ef4b37cd7a2f436

Add MTL parser.

===================================================================

M	source/blender/io/wavefront_obj/CMakeLists.txt
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
A	source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.cc
A	source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.hh
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/CMakeLists.txt b/source/blender/io/wavefront_obj/CMakeLists.txt
index 51103536817..15d0c3b4d13 100644
--- a/source/blender/io/wavefront_obj/CMakeLists.txt
+++ b/source/blender/io/wavefront_obj/CMakeLists.txt
@@ -45,6 +45,7 @@ set(SRC
   intern/wavefront_obj_im_file_reader.cc
   intern/wavefront_obj_importer.cc
   intern/wavefront_obj_im_mesh.cc
+  intern/wavefront_obj_im_mtl.cc
   intern/wavefront_obj_im_nurbs.cc
   intern/wavefront_obj_im_objects.cc
 
@@ -58,6 +59,7 @@ set(SRC
   intern/wavefront_obj_im_file_reader.hh
   intern/wavefront_obj_importer.hh
   intern/wavefront_obj_im_mesh.hh
+  intern/wavefront_obj_im_mtl.hh
   intern/wavefront_obj_im_nurbs.hh
   intern/wavefront_obj_im_objects.hh
 )
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 f2dfdc919a1..c39218cfa2b 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
@@ -26,6 +26,7 @@
 
 #include "BKE_context.h"
 
+#include "BLI_map.hh"
 #include "BLI_string_ref.hh"
 #include "BLI_vector.hh"
 
@@ -384,4 +385,131 @@ void OBJParser::parse_and_store(Vector<std::unique_ptr<OBJRawObject>> &list_of_o
     }
   }
 }
+
+/**
+ * Get the texture map from the MTLMaterial struct corresponding to the given string.
+ */
+static tex_map_XX *get_tex_map_of_type(MTLMaterial *mtl_mat, StringRef tex_map_str)
+{
+  if (tex_map_str == "map_Kd") {
+    return &mtl_mat->map_Kd;
+  }
+  else if (tex_map_str == "map_Ks") {
+    return &mtl_mat->map_Ks;
+  }
+  else if (tex_map_str == "map_Ns") {
+    return &mtl_mat->map_Ns;
+  }
+  else if (tex_map_str == "map_d") {
+    return &mtl_mat->map_d;
+  }
+  else if (tex_map_str == "map_refl") {
+    return &mtl_mat->map_refl;
+  }
+  else if (tex_map_str == "map_Ke") {
+    return &mtl_mat->map_Ke;
+  }
+  else if (tex_map_str == "map_Bump") {
+    return &mtl_mat->map_Bump;
+  }
+  return nullptr;
+}
+
+MTLParser::MTLParser(const OBJImportParams &import_params) : import_params_(import_params)
+{
+  /* 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");
+  mtl_file_.open(mtl_file_path_);
+}
+
+void MTLParser::parse_and_store(Map<string, MTLMaterial> &mtl_materials)
+{
+  if (!mtl_file_.good()) {
+    fprintf(stderr, "Cannot read from file:%s\n", mtl_file_path_);
+  }
+
+  string line;
+  MTLMaterial *curr_mtlmat = nullptr;
+  while (std::getline(mtl_file_, line)) {
+    if (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;
+      curr_mtlmat = &new_mtl;
+      mtl_materials.add(rest_line, new_mtl);
+    }
+    else if (line_key == "Ns") {
+      copy_string_to_float(line.substr(line_key.size()), 324.0f, curr_mtlmat->Ns);
+    }
+    else if (line_key == "Ka") {
+      Vector<string> str_ka_split{};
+      split_by_char(rest_line, ' ', str_ka_split);
+      copy_string_to_float(str_ka_split, 0.0f, {curr_mtlmat->Ka, 3});
+    }
+    else if (line_key == "Kd") {
+      Vector<string> str_kd_split{};
+      split_by_char(rest_line, ' ', str_kd_split);
+      copy_string_to_float(str_kd_split, 0.8f, {curr_mtlmat->Kd, 3});
+    }
+    else if (line_key == "Ks") {
+      Vector<string> str_ks_split{};
+      split_by_char(rest_line, ' ', str_ks_split);
+      copy_string_to_float(str_ks_split, 0.5f, {curr_mtlmat->Ks, 3});
+    }
+    else if (line_key == "Ke") {
+      Vector<string> str_ke_split{};
+      split_by_char(rest_line, ' ', str_ke_split);
+      copy_string_to_float(str_ke_split, 0.0f, {curr_mtlmat->Ke, 3});
+    }
+    else if (line_key == "Ni") {
+      copy_string_to_float(rest_line, 1.45f, curr_mtlmat->Ni);
+    }
+    else if (line_key == "d") {
+      copy_string_to_float(rest_line, 1.0f, curr_mtlmat->d);
+    }
+    else if (line_key == "illum") {
+      copy_string_to_int(rest_line, 2, curr_mtlmat->illum);
+    }
+    /* Image Textures. */
+    else if (line_key.find("map_") != string::npos) {
+      tex_map_XX *tex_map = get_tex_map_of_type(curr_mtlmat, line_key);
+      if (!tex_map) {
+        /* No supported map_xx found. */
+        continue;
+      }
+      Vector<string> str_map_xx_split{};
+      split_by_char(rest_line, ' ', str_map_xx_split);
+
+      int64_t pos_o{str_map_xx_split.first_index_of_try("-o")};
+      if (pos_o != string::npos && pos_o + 3 < str_map_xx_split.size()) {
+        copy_string_to_float({str_map_xx_split[pos_o + 1],
+                              str_map_xx_split[pos_o + 2],
+                              str_map_xx_split[pos_o + 3]},
+                             0.0f,
+                             {tex_map->translation, 3});
+      }
+      int64_t pos_s{str_map_xx_split.first_index_of_try("-s")};
+      if (pos_s != string::npos && pos_s + 3 < str_map_xx_split.size()) {
+        copy_string_to_float({str_map_xx_split[pos_s + 1],
+                              str_map_xx_split[pos_s + 2],
+                              str_map_xx_split[pos_s + 3]},
+                             1.0f,
+                             {tex_map->scale, 3});
+      }
+      /* Only specific to Normal Map node. */
+      int64_t pos_bm{str_map_xx_split.first_index_of_try("-bm")};
+      if (pos_bm != string::npos && pos_bm + 1 < str_map_xx_split.size()) {
+        copy_string_to_float(str_map_xx_split[pos_bm + 1], 0.0f, curr_mtlmat->map_Bump_value);
+      }
+
+      tex_map->image_path = str_map_xx_split.last();
+    }
+  }
+}
 }  // namespace blender::io::obj
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 f144cba223c..481ea81b896 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
@@ -52,5 +52,16 @@ class OBJParser {
   void update_index_offsets(std::unique_ptr<OBJRawObject> *curr_ob);
 };
 
+class MTLParser {
+ private:
+  const OBJImportParams &import_params_;
+  char mtl_file_path_[FILE_MAX]{};
+  std::ifstream mtl_file_;
+
+ public:
+  MTLParser(const OBJImportParams &import_params);
+
+  void parse_and_store(Map<std::string, MTLMaterial> &mtl_materials);
+};
 }  // namespace blender::io::obj
 #endif
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
new file mode 100644
index 00000000000..148b173c259
--- /dev/null
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.cc
@@ -0,0 +1,27 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup obj
+ */
+
+
+#include "wavefront_obj_im_mtl.hh"
+
+
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.hh b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.hh
new file mode 100644
index 00000000000..cb5b8a79530
--- /dev/null
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_im_mtl.hh
@@ -0,0 +1,22 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup obj
+ */
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 12c67405e6b..9ca2a813279 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
@@ -136,6 +136,40 @@ class OBJRawObject {
   friend class OBJParser;
 };
 
+/**
+ * Used for storing parameters for all kinds of texture maps from MTL file.
+ */
+struct tex_map_XX {
+  // TODO ankitm add map type enum.
+  float3 translation = {0.0f, 0.0f, 0.0f};
+  float3 scale = {1.0f, 1.0f, 1.0f};
+  std::string image_path{};
+};
+
+/**
+ * Store material data parsed from MTL file.
+ */
+struct MTLMaterial {
+  std::string name{};
+  float Ns{1.0f};
+  float3 Ka;
+  float3 Kd;
+  float3 Ks;
+  float3 Ke;
+  float Ni{1.0f};
+  float d{1.0f};
+  int illum{0};
+  tex_map_XX map_Kd;
+  tex_map_XX map_Ks;
+  tex_map_XX map_Ke;
+  tex_map_XX map_d;
+  tex_map_XX map_refl;
+  tex_map_XX map_Ns;
+  tex_map_XX map_Bump;
+  /** Only used for Normal Map node: map_Bump. */
+  float map_Bump_value = 0.0f;
+};
+
 struct UniqueObjectDeleter {
   void operator()(Object *obje

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list