[Bf-blender-cvs] [827869a45bc] soc-2020-io-performance: Add support for exporting Material Library file

Ankit Meel noreply at git.blender.org
Sat Jun 27 15:23:51 CEST 2020


Commit: 827869a45bccbf1e016580b53426d70f065a4fe8
Author: Ankit Meel
Date:   Sat Jun 27 18:36:36 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rB827869a45bccbf1e016580b53426d70f065a4fe8

Add support for exporting Material Library file

**Why not reuse the `write_mtl` in `export_obj.py` ?**
Because there are no benefits except saving some time now, only to later
waste it in debugging or extending it.
Having it in C++ provides easy extensibility when we need to
add more nodes' support without having to modify node_utils.py, which
itself is a hardcoded wrapper for BSDF and normal map shader nodes.

Quick Summary:
If export_params->export_materials is true, we create an empty MTL file
with the same name (not extension, of course) in the same directory.
`frame_writer` writes its name (with extension) to the OBJ file, to
reference it, as per format specs.

MTLWriter class is added in the new files. It uses NodeTreeRef committed
recently in rBe1cc9aa7f281 for a faster way to find two linked sockets.

`frame_writer` instantiates an MTLWriter for an object which then
*appends* that object's material to the previously created MTL file.

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

M	source/blender/editors/io/io_obj.c
M	source/blender/io/wavefront_obj/CMakeLists.txt
M	source/blender/io/wavefront_obj/IO_wavefront_obj.h
M	source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
M	source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.cc
M	source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.hh
A	source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mtl.cc
A	source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mtl.hh
M	source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
M	source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.hh

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

diff --git a/source/blender/editors/io/io_obj.c b/source/blender/editors/io/io_obj.c
index e822eb92555..a09febfbfaa 100644
--- a/source/blender/editors/io/io_obj.c
+++ b/source/blender/editors/io/io_obj.c
@@ -109,6 +109,7 @@ static int wm_obj_export_exec(bContext *C, wmOperator *op)
 
   export_params.export_uv = RNA_boolean_get(op->ptr, "export_uv");
   export_params.export_normals = RNA_boolean_get(op->ptr, "export_normals");
+  export_params.export_materials = RNA_boolean_get(op->ptr, "export_materials");
   export_params.export_triangulated_mesh = RNA_boolean_get(op->ptr, "export_triangulated_mesh");
   export_params.export_curves_as_nurbs = RNA_boolean_get(op->ptr, "export_curves_as_nurbs");
 
@@ -164,6 +165,9 @@ static void ui_obj_export_settings(uiLayout *layout, PointerRNA *imfptr)
   row = uiLayoutRow(box, false);
   uiItemR(row, imfptr, "export_normals", 0, NULL, ICON_NONE);
 
+  row = uiLayoutRow(box, false);
+  uiItemR(row, imfptr, "export_materials", 0, NULL, ICON_NONE);
+
   row = uiLayoutRow(box, false);
   uiItemR(row, imfptr, "export_triangulated_mesh", 0, NULL, ICON_NONE);
 
@@ -276,6 +280,12 @@ void WM_OT_obj_export(struct wmOperatorType *ot)
   RNA_def_boolean(ot->srna, "export_uv", true, "Export UVs", "Export UV coordinates");
   RNA_def_boolean(
       ot->srna, "export_normals", true, "Export normals", "Export per face per vertex normals");
+  RNA_def_boolean(
+      ot->srna,
+      "export_materials",
+      true,
+      "Export Materials",
+      "Export Materials and texture images' names collected from Principled BSDF and linked nodes of the object");
   RNA_def_boolean(
       ot->srna,
       "export_triangulated_mesh",
diff --git a/source/blender/io/wavefront_obj/CMakeLists.txt b/source/blender/io/wavefront_obj/CMakeLists.txt
index 1774cadc140..70f7a552000 100644
--- a/source/blender/io/wavefront_obj/CMakeLists.txt
+++ b/source/blender/io/wavefront_obj/CMakeLists.txt
@@ -43,6 +43,7 @@ set(SRC
   intern/wavefront_obj.cc
   intern/wavefront_obj_exporter.cc
   intern/wavefront_obj_exporter_mesh.cc
+  intern/wavefront_obj_exporter_mtl.cc
   intern/wavefront_obj_exporter_nurbs.cc
   intern/wavefront_obj_file_handler.cc
   intern/wavefront_obj_importer.cc
@@ -51,6 +52,7 @@ set(SRC
   intern/wavefront_obj.hh
   intern/wavefront_obj_exporter.hh
   intern/wavefront_obj_exporter_mesh.hh
+  intern/wavefront_obj_exporter_mtl.hh
   intern/wavefront_obj_exporter_nurbs.hh
   intern/wavefront_obj_file_handler.hh
   intern/wavefront_obj_importer.hh
diff --git a/source/blender/io/wavefront_obj/IO_wavefront_obj.h b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
index 2e93427b3af..e217b09ea54 100644
--- a/source/blender/io/wavefront_obj/IO_wavefront_obj.h
+++ b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
@@ -65,6 +65,7 @@ struct OBJExportParams {
   /** File Write Options */
   bool export_uv;
   bool export_normals;
+  bool export_materials;
   bool export_triangulated_mesh;
   bool export_curves_as_nurbs;
 };
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
index 8d4db05095d..f1d1c8833f4 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
@@ -36,6 +36,7 @@
 
 #include "wavefront_obj_exporter.hh"
 #include "wavefront_obj_exporter_mesh.hh"
+#include "wavefront_obj_exporter_mtl.hh"
 #include "wavefront_obj_exporter_nurbs.hh"
 #include "wavefront_obj_file_handler.hh"
 
@@ -86,6 +87,11 @@ static void export_frame(bContext *C, const OBJExportParams *export_params, cons
     return;
   }
 
+  if (export_params->export_materials) {
+    /* Write MTL filename to the OBJ file. Also create an empty MTL file of the same name as the
+     * OBJ*/
+    frame_writer.write_mtllib(filepath);
+  }
   for (uint ob_iter = 0; ob_iter < exportable_meshes.size(); ob_iter++) {
     OBJMesh &mesh_to_export = exportable_meshes[ob_iter];
 
@@ -104,6 +110,12 @@ static void export_frame(bContext *C, const OBJExportParams *export_params, cons
       if (export_params->export_uv) {
         frame_writer.write_uv_coords(mesh_to_export, uv_indices);
       }
+      if (export_params->export_materials) {
+        /* Write material name just before face elements. */
+        frame_writer.write_usemtl(mesh_to_export);
+        MTLWriter mtl_writer(filepath);
+        mtl_writer.append_material(mesh_to_export);
+      }
       frame_writer.write_poly_indices(mesh_to_export, uv_indices);
     }
     frame_writer.update_index_offsets(mesh_to_export);
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.cc
index f8d95beac71..df40a56b486 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.cc
@@ -33,6 +33,7 @@
 #include "DEG_depsgraph_query.h"
 
 #include "DNA_layer_types.h"
+#include "DNA_material_types.h"
 #include "DNA_modifier_types.h"
 
 #include "wavefront_obj_exporter_mesh.hh"
@@ -222,6 +223,15 @@ void OBJMesh::calc_poly_normal(float r_poly_normal[3], uint poly_index)
   normalize_v3(r_poly_normal);
 }
 
+/**
+ * Set argument pointer to the name of an object's active material.
+ */
+void OBJMesh::get_material_name(const char **r_mat_name)
+{
+  Material *mat = BKE_object_material_get(_export_object_eval, _export_object_eval->actcol);
+  *r_mat_name = mat->id.name + 2;
+}
+
 /**
  * Calculate face normal indices of all polygons.
  */
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.hh b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.hh
index 069041eede0..aab14beca36 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.hh
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.hh
@@ -23,12 +23,14 @@
 #define __WAVEFRONT_OBJ_EXPORTER_MESH_HH__
 
 #include "BKE_lib_id.h"
+#include "BKE_material.h"
 #include "BKE_mesh.h"
 
 #include "BLI_vector.hh"
 
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
 
 #include "IO_wavefront_obj.h"
 
@@ -85,6 +87,15 @@ class OBJMesh {
     return _export_mesh_eval->mpoly[i];
   }
 
+  /** Return active material of the object. */
+  Material *export_object_material(){
+    return BKE_object_material_get(_export_object_eval, _export_object_eval->actcol);
+  }
+  /**
+   * Set argument pointer to the name of an object's active material.
+   */
+  void get_material_name(const char **r_mat_name);
+
   void get_object_name(const char **object_name);
   /**
    * Calculate coordinates of the vertex at given index.
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mtl.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mtl.cc
new file mode 100644
index 00000000000..c6894b07d49
--- /dev/null
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mtl.cc
@@ -0,0 +1,269 @@
+/*
+ * 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) 2008 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup obj
+ */
+
+#include "BKE_material.h"
+#include "BKE_node.h"
+#include "BKE_node_tree_ref.hh"
+
+#include "BLI_math.h"
+#include "BLI_map.hh"
+
+#include "DNA_material_types.h"
+#include "DNA_node_types.h"
+
+#include "wavefront_obj_exporter_mtl.hh"
+
+using namespace BKE;
+namespace io {
+namespace obj {
+
+/**
+ * Find and initialiase the Principled-BSDF from the object's material.
+ */
+void MTLWriter::init_bsdf_node()
+{
+  if (_export_mtl->use_nodes == false) {
+    fprintf(stderr, "No Principled-BSDF node found in the material Node tree.\n");
+    _bsdf_node = nullptr;
+    return;
+  }
+  ListBase *nodes = &_export_mtl->nodetree->nodes;
+  LISTBASE_FOREACH (bNode *, curr_node, nodes) {
+    if (curr_node->typeinfo->type == SH_NODE_BSDF_PRINCIPLED) {
+      _bsdf_node = curr_node;
+      return;
+    }
+  }
+  fprintf(stderr, "No Principled-BSDF node found in the material Node tree.\n");
+  _bsdf_node = nullptr;
+}
+
+/**
+ * Copy the float property from the bNode to given buffer.
+ */
+void MTLWriter::float_property_from_node(float *r_property,
+                                         const bNode *curr_node,
+                                         const char *identifier)
+{
+  if (!_bsdf_node) {
+    return;
+  }
+  bNodeSocket *socket = (bNodeSocket *)nodeFindSocket(_bsdf_node, SOCK_IN, identifier);
+  if (socket) {
+    bNodeSocketValueFloat *socket_def_value = (bNodeSocketValueFloat *)socket->default_value;
+    *r_property = socket_def_value->value;
+  }
+}
+
+/**
+ * Copy the float3 property from the bNode to given buffer.
+ * Mostly used for color, without alpha.
+ */
+void MTLWriter::float3_property_from_node(float *r_property,
+                                          const bNode *curr_node,
+                                          const char *identifier)
+{
+  if (!_bsdf_node) {
+    return;
+  }
+  bNodeSocket *socket = (bNodeSocket *)nodeFindSocket(_bsdf_node, SOCK_IN, identifier);
+  if (socket) {
+    bNodeSocketValueRGBA *socket_def_value = (bNodeSocketValueRGBA *)socket->default_value;
+    copy_v3_v3(r_property, socket_def_value->value);
+  }
+}
+
+/**
+ * Collect all the source sockets linked to the destination socket in a destination node.
+ */
+void MTLWriter::linked_sockets_to_dest_id(
+    blender::Vector<const OutputS

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list