[Bf-blender-cvs] [d85c2620b81] soc-2020-io-performance: Export smooth groups for smooth shaded meshes.

Ankit Meel noreply at git.blender.org
Thu Jul 2 15:59:21 CEST 2020


Commit: d85c2620b81845eef48d8b89b48b3a0c758959d5
Author: Ankit Meel
Date:   Thu Jul 2 19:28:54 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rBd85c2620b81845eef48d8b89b48b3a0c758959d5

Export smooth groups for smooth shaded meshes.

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

M	source/blender/editors/io/io_obj.c
M	source/blender/io/wavefront_obj/IO_wavefront_obj.h
M	source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.cc
M	source/blender/io/wavefront_obj/intern/wavefront_obj_exporter_mesh.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 c167e2ae633..2e93d6e4673 100644
--- a/source/blender/editors/io/io_obj.c
+++ b/source/blender/editors/io/io_obj.c
@@ -117,6 +117,7 @@ static int wm_obj_export_exec(bContext *C, wmOperator *op)
   export_params.export_object_groups = RNA_boolean_get(op->ptr, "export_object_groups");
   export_params.export_material_groups = RNA_boolean_get(op->ptr, "export_material_groups");
   export_params.export_vertex_groups = RNA_boolean_get(op->ptr, "export_vertex_groups");
+  export_params.export_smooth_group = RNA_boolean_get(op->ptr, "export_smooth_group");
 
   OBJ_export(C, &export_params);
 
@@ -194,6 +195,9 @@ static void ui_obj_export_settings(uiLayout *layout, PointerRNA *imfptr)
 
   row = uiLayoutRow(box, false);
   uiItemR(row, imfptr, "export_vertex_groups", 0, NULL, ICON_NONE);
+
+  row = uiLayoutRow(box, false);
+  uiItemR(row, imfptr, "export_smooth_group", 0, NULL, ICON_NONE);
 }
 
 static void wm_obj_export_draw(bContext *UNUSED(C), wmOperator *op)
@@ -347,6 +351,12 @@ void WM_OT_obj_export(struct wmOperatorType *ot)
       "Export vertex groups",
       "If checked, writes the name of the vertex group of a face. It is approximated "
       "by choosing the vertex group with the most members among the vertices of a face");
+  RNA_def_boolean(ot->srna,
+                  "export_smooth_group",
+                  false,
+                  "Export smooth groups",
+                  "If checked, writes per-vertex normal instead of per-face normal if the mesh "
+                  "is shaded smooth");
 }
 
 static int wm_obj_import_invoke(bContext *C, wmOperator *op, const wmEvent *event)
diff --git a/source/blender/io/wavefront_obj/IO_wavefront_obj.h b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
index 5619f4c10bc..956f3c2806a 100644
--- a/source/blender/io/wavefront_obj/IO_wavefront_obj.h
+++ b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
@@ -77,6 +77,11 @@ struct OBJExportParams {
   bool export_object_groups;
   bool export_material_groups;
   bool export_vertex_groups;
+  /**
+   * Export vertex normals instead of face normals if mesh is shaded smooth and this option is
+   * true.
+   */
+  bool export_smooth_group;
 };
 
 struct OBJImportParams {
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 f4e9493725a..c747e81e6fd 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
@@ -244,14 +244,32 @@ void OBJMesh::calc_poly_normal(float r_poly_normal[3], uint poly_index)
   mul_mat3_m4_v3(_world_and_axes_transform, r_poly_normal);
 }
 
+/**
+ * Calculate vertex normal indices of all vertices.
+ */
+void OBJMesh::calc_vertex_normal(float r_vertex_normal[3], uint vert_index)
+{
+  normal_short_to_float_v3(r_vertex_normal, _export_mesh_eval->mvert[vert_index].no);
+  mul_mat3_m4_v3(_world_and_axes_transform, r_vertex_normal);
+}
+
 /**
  * Calculate face normal indices of all polygons.
  */
 void OBJMesh::calc_poly_normal_indices(Vector<uint> &r_normal_indices, uint poly_index)
 {
   r_normal_indices.resize(_export_mesh_eval->mpoly[poly_index].totloop);
-  for (uint i = 0; i < r_normal_indices.size(); i++) {
-    r_normal_indices[i] = poly_index + 1;
+  if (_export_params->export_smooth_group && this->is_shaded_smooth()) {
+    const MPoly &mpoly = _export_mesh_eval->mpoly[poly_index];
+    const MLoop *mloop = &_export_mesh_eval->mloop[mpoly.loopstart];
+    for (uint i = 0; i < r_normal_indices.size(); i++) {
+      r_normal_indices[i] = (mloop + i)->v + 1;
+    }
+  }
+  else {
+    for (uint i = 0; i < r_normal_indices.size(); i++) {
+      r_normal_indices[i] = poly_index + 1;
+    }
   }
 }
 
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 468724eeabe..47bd479df81 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
@@ -87,6 +87,11 @@ class OBJMesh : NonMovable, NonCopyable {
     return _export_mesh_eval->mpoly[i];
   }
 
+  bool is_shaded_smooth()
+  {
+    return ((_export_mesh_eval->flag & ME_SMOOTH) == 0);
+  }
+
   void ensure_normals();
   /** Return mat_nr-th material of the object. */
   Material *get_object_material(short mat_nr);
@@ -113,6 +118,10 @@ class OBJMesh : NonMovable, NonCopyable {
    * Calculate face normal of the polygon at given index.
    */
   void calc_poly_normal(float r_poly_normal[3], uint poly_index);
+  /**
+   * Calculate vertex normal of a vertex at the given index.
+   */
+  void calc_vertex_normal(float r_vertex_normal[3], uint vertex_index);
   /**
    * Calculate face normal indices of all polygons.
    */
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
index 11b12201eed..e37c9d99e2a 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.cc
@@ -167,14 +167,40 @@ void OBJWriter::write_uv_coords(OBJMesh &obj_mesh_data, Vector<Vector<uint>> &uv
   }
 }
 
-/** Write face normals for all polygons as vn x y z . */
+/**
+ * Write all face normals or all vertex normals as vn x y z .
+ */
 void OBJWriter::write_poly_normals(OBJMesh &obj_mesh_data)
 {
-  float poly_normal[3];
   obj_mesh_data.ensure_normals();
-  for (uint i = 0; i < obj_mesh_data.tot_poly_normals(); i++) {
-    obj_mesh_data.calc_poly_normal(poly_normal, i);
-    fprintf(_outfile, "vn %f %f %f\n", poly_normal[0], poly_normal[1], poly_normal[2]);
+  if (_export_params->export_smooth_group && obj_mesh_data.is_shaded_smooth()) {
+    float vertex_normal[3];
+    for (uint i = 0; i < obj_mesh_data.tot_vertices(); i++) {
+      obj_mesh_data.calc_vertex_normal(vertex_normal, i);
+      fprintf(_outfile, "vn %f %f %f\n", vertex_normal[0], vertex_normal[1], vertex_normal[2]);
+    }
+  }
+  else {
+    float poly_normal[3];
+    for (uint i = 0; i < obj_mesh_data.tot_poly_normals(); i++) {
+      obj_mesh_data.calc_poly_normal(poly_normal, i);
+      fprintf(_outfile, "vn %f %f %f\n", poly_normal[0], poly_normal[1], poly_normal[2]);
+    }
+  }
+}
+
+/**
+ * Write smooth group if mesh is shaded smooth and export settings specify so.
+ */
+void OBJWriter::write_smooth_group(OBJMesh &obj_mesh_data)
+{
+  if (_export_params->export_smooth_group) {
+    if (obj_mesh_data.is_shaded_smooth()) {
+      fprintf(_outfile, "s 1\n");
+    }
+    else {
+      fprintf(_outfile, "s off\n");
+    }
   }
 }
 
@@ -242,6 +268,7 @@ void OBJWriter::write_poly_indices(OBJMesh &obj_mesh_data, Span<Vector<uint>> uv
   short last_face_vertex_group = -2;
 
   if (_export_params->export_normals) {
+    write_smooth_group(obj_mesh_data);
     if (_export_params->export_uv && (obj_mesh_data.tot_uv_vertices() > 0)) {
       /* Write both normals and UV indices. */
       for (uint i = 0; i < obj_mesh_data.tot_poly_normals(); i++) {
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.hh b/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.hh
index f2c6c084e4c..974fecefd90 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.hh
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_file_handler.hh
@@ -71,6 +71,10 @@ class OBJWriter {
   void write_uv_coords(OBJMesh &obj_mesh_data, Vector<Vector<uint>> &uv_indices);
   /** Write face normals for all polygons as vn x y z . */
   void write_poly_normals(OBJMesh &obj_mesh_data);
+  /**
+   * Write smooth group if mesh is shaded smooth and export settings specify so.
+   */
+  void write_smooth_group(OBJMesh &obj_mesh_data);
   /** Write material name and material group of a face in the OBJ file.
    * \note It doesn't write to the material library, MTL file.
    */



More information about the Bf-blender-cvs mailing list