[Bf-blender-cvs] [72712e99853] soc-2019-fast-io: [Fast import/export] Added NURBS export. Previous commit added path mode

Hugo Sales noreply at git.blender.org
Mon Jun 24 00:20:48 CEST 2019


Commit: 72712e9985334363b50b06620a9a6162b0f680fc
Author: Hugo Sales
Date:   Sun Jun 23 23:20:41 2019 +0100
Branches: soc-2019-fast-io
https://developer.blender.org/rB72712e9985334363b50b06620a9a6162b0f680fc

[Fast import/export] Added NURBS export. Previous commit added path mode

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

M	source/blender/editors/io/intern/common.cpp
M	source/blender/editors/io/intern/common.hpp
M	source/blender/editors/io/intern/iterators.hpp
M	source/blender/editors/io/intern/obj.cpp
M	source/blender/editors/io/io_common.c
M	source/blender/editors/io/io_common.h
M	source/blender/editors/io/io_obj.c

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

diff --git a/source/blender/editors/io/intern/common.cpp b/source/blender/editors/io/intern/common.cpp
index a5085a303f2..d6c6ba59a85 100644
--- a/source/blender/editors/io/intern/common.cpp
+++ b/source/blender/editors/io/intern/common.cpp
@@ -29,15 +29,6 @@ extern "C" {
 
 // Anonymous namespace for internal functions
 namespace {
-inline void name_compat(std::string &ob_name, const std::string &mesh_name)
-{
-  if (ob_name.compare(mesh_name) != 0) {
-    ob_name += "_" + mesh_name;
-  }
-  size_t start_pos;
-  while ((start_pos = ob_name.find(" ")) != std::string::npos)
-    ob_name.replace(start_pos, 1, "_");
-}
 
 inline void change_single_axis_orientation(float (&mat)[4][4], int axis_from, int axis_to)
 {
@@ -64,6 +55,16 @@ inline void change_single_axis_orientation(float (&mat)[4][4], int axis_from, in
 
 namespace common {
 
+void name_compat(std::string &ob_name, const std::string &mesh_name)
+{
+  if (ob_name.compare(mesh_name) != 0) {
+    ob_name += "_" + mesh_name;
+  }
+  size_t start_pos;
+  while ((start_pos = ob_name.find(" ")) != std::string::npos)
+    ob_name.replace(start_pos, 1, "_");
+}
+
 bool object_is_smoke_sim(const Object *const ob)
 {
   ModifierData *md = modifiers_findByType((Object *)ob, eModifierType_Smoke);
@@ -196,14 +197,6 @@ void free_mesh(Mesh *mesh, bool needs_free)
     BKE_id_free(NULL, mesh);  // TODO someoene null? (alembic)
 }
 
-std::string get_object_name(const Object *const eob, const Mesh *const mesh)
-{
-  std::string name{eob->id.name + 2};
-  std::string mesh_name{mesh->id.name + 2};
-  name_compat(name /* modifies */, mesh_name);
-  return name;
-}
-
 std::string get_version_string()
 {
   return "";  // TODO someone implement
diff --git a/source/blender/editors/io/intern/common.hpp b/source/blender/editors/io/intern/common.hpp
index 0d8a9e17dfc..275136c43e2 100644
--- a/source/blender/editors/io/intern/common.hpp
+++ b/source/blender/editors/io/intern/common.hpp
@@ -74,7 +74,7 @@ bool get_final_mesh(const ExportSettings *const settings,
 
 void free_mesh(Mesh *mesh, bool needs_free);
 
-std::string get_object_name(const Object *const ob, const Mesh *const mesh);
+void name_compat(std::string &ob_name, const std::string &mesh_name);
 std::string get_version_string();
 
 void export_start(bContext *C, ExportSettings *const settings);
@@ -94,6 +94,16 @@ std::vector<std::array<float, 2>> get_uv(const Mesh *const mesh);
 std::vector<std::array<float, 3>> get_vertices(const Mesh *const mesh);
 
 // --- TEMPLATES ---
+
+// T should be something with an ID, like Mesh or Curve
+template<typename T> std::string get_object_name(const Object *const ob, const T *const data)
+{
+  std::string name{ob->id.name + 2};
+  std::string data_name{data->id.name + 2};
+  name_compat(name /* modifies */, data_name);
+  return name;
+}
+
 // --- Deduplication ---
 // TODO someone How to properly compare similarity of vectors?
 struct threshold_comparator {
diff --git a/source/blender/editors/io/intern/iterators.hpp b/source/blender/editors/io/intern/iterators.hpp
index 422c658d2f9..60ec3752f23 100644
--- a/source/blender/editors/io/intern/iterators.hpp
+++ b/source/blender/editors/io/intern/iterators.hpp
@@ -3,15 +3,16 @@
 
 extern "C" {
 /* clang-format off */
+#include "BKE_customdata.h"
 #include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_runtime.h"
 #include "BKE_modifier.h"
-#include "BKE_library.h"
-#include "BKE_customdata.h"
 #include "BKE_scene.h"
-#include "BKE_material.h"
 
+#include "DNA_curve_types.h"
 #include "DNA_layer_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_mesh_types.h"
@@ -190,7 +191,7 @@ struct modifier_iter : list_iterator<ModifierData> {
 // Iterator over the `MLoop` of a `MPoly` of a mesh
 struct loop_of_poly_iter : pointer_iterator<MLoop> {
   loop_of_poly_iter(const Mesh *const mesh, const poly_iter &poly)
-    : pointer_iterator(mesh->mloop + (*poly).loopstart, (*poly).totloop) {} // XXX DEBUG THIS HERE
+    : pointer_iterator(mesh->mloop + (*poly).loopstart, (*poly).totloop) {}
   loop_of_poly_iter(const Mesh *const mesh, const MPoly &poly)
       : pointer_iterator(mesh->mloop + poly.loopstart, poly.totloop) {}
   loop_of_poly_iter(MLoop * const loop, size_t size)
@@ -220,6 +221,21 @@ struct material_iter : offset_iterator<Material *> {
   const Material * const * const mdata;
 };
 
+struct nurbs_of_curve_iter : list_iterator<Nurb> {
+  nurbs_of_curve_iter(const Curve * const curve) : list_iterator((Nurb *) curve->nurb.first) {}
+};
+
+struct points_of_nurbs_iter : pointer_iterator_base<BPoint> {
+  points_of_nurbs_iter(const Nurb * const nu)
+    : pointer_iterator_base(nu->bp, (nu->pntsv > 0 ? nu->pntsu * nu->pntsv : nu->pntsu)) {}
+  points_of_nurbs_iter(BPoint *bp, size_t size) : pointer_iterator_base(bp, size) {}
+  points_of_nurbs_iter begin() const { return {this->first, this->size}; }
+  points_of_nurbs_iter end()   const { return {this->first + this->size, this->size}; }
+  inline const std::array<float, 3> operator*() const {
+    return {curr->vec[0], curr->vec[1], curr->vec[2]};
+  }
+};
+
 // Iterator over the UVs of a mesh (as `const std::array<float, 2>`)
 struct uv_iter : pointer_iterator_base<MLoopUV> {
   uv_iter(const Mesh *const m) : pointer_iterator_base(m->mloopuv, m->totloop) {}
diff --git a/source/blender/editors/io/intern/obj.cpp b/source/blender/editors/io/intern/obj.cpp
index 40a3b7f8dfd..be1e6fe9bc8 100644
--- a/source/blender/editors/io/intern/obj.cpp
+++ b/source/blender/editors/io/intern/obj.cpp
@@ -18,6 +18,7 @@ extern "C" {
 #include "DNA_mesh_types.h"
 #include "DNA_object_types.h"
 #include "DNA_space_types.h"
+#include "DNA_curve_types.h"
 
 #include "DEG_depsgraph.h"
 
@@ -123,12 +124,12 @@ std::FILE *get_file(const char *const original_path,
 
 bool OBJ_export_materials(bContext *C,
                           ExportSettings *settings,
-                          std::set<const Material *> materials,
-                          size_t frame)
+                          std::string mtl_path,
+                          std::set<const Material *> materials)
 {
 #ifdef WITH_PYTHON
   const char *imports[] = {"obj_export", NULL};
-  std::string mtl_path = get_path(settings->filepath, ".mtl", settings->export_animations, frame);
+
   std::stringstream ss;
   ss << "obj_export.write_mtl(\"" << mtl_path << "\", [";
   bool first = true;
@@ -150,6 +151,85 @@ bool OBJ_export_materials(bContext *C,
 #endif
 }
 
+bool OBJ_export_curve(bContext *UNUSED(C),
+                      ExportSettings *UNUSED(settings),
+                      std::FILE *file,
+                      const Object *eob,
+                      const Curve *cu)
+{
+  size_t totvert = 0;
+  for (const Nurb &nurb : nurbs_of_curve_iter(cu)) {
+    size_t deg_order_u = 0;
+    if (nurb.type == CU_POLY) {
+      deg_order_u = 1;
+    }
+    else {
+      // Original OBJ exporter says this is tested to be correct...
+      deg_order_u = nurb.orderu - 1;
+    }
+
+    if (nurb.type == CU_BEZIER) {
+      std::cerr << "Warning: BEZIER curve '" << eob->id.name
+                << "' skipped. Only Poly and NURBS curves supported\n";
+      return true;  // Don't abort all exports, just skip
+    }
+
+    if (nurb.pntsv > 1) {
+      std::cerr << "Warning: Surface curve '" << eob->id.name
+                << "' skipped. Only Poly and NURBS curves supported\n";
+      return true;  // Don't abort all exports, just skip
+    }
+
+    // If the length of the nurb.bp array is smaller than the degree, we'remissing points
+    if ((nurb.pntsv > 0 ? nurb.pntsu * nurb.pntsv : nurb.pntsu) <= deg_order_u) {
+      std::cerr << "Warning: Number of points in object '" << eob->id.name
+                << "' is lower than it's degree. Skipped. \n";
+      return true;  // Don't abort all exports, just skip
+    }
+
+    const bool closed = nurb.flagu & CU_NURB_CYCLIC;
+    const bool endpoints = !closed && (nurb.flagu & CU_NURB_ENDPOINT);
+    size_t num_points = 0;
+    // TODO someone Transform, scale and such
+    for (const std::array<float, 3> &point : points_of_nurbs_iter(&nurb)) {
+      fprintf(file, "v %.6g %.6g %.6g\n", point[0], point[1], point[2]);
+      ++num_points;
+    }
+    totvert += num_points;
+
+    fprintf(file, "g %s\n", common::get_object_name(eob, cu).c_str());
+    fprintf(file, "cstype bspline\ndeg %lu\n", deg_order_u);
+
+    size_t real_num_points = num_points;
+    if (closed) {
+      num_points += deg_order_u;
+    }
+
+    fputs("curv 0.0 1.0", file);
+    for (int i = 0; i < num_points; ++i) {
+      // Relative indexes, reuse vertices if closed
+      fprintf(file, " %ld", (long)(i < real_num_points ? -(i + 1) : -(i - real_num_points + 1)));
+    }
+    fputc('\n', file);
+
+    fputs("parm u", file);
+    size_t tot_parm = deg_order_u + 1 + num_points;
+    float tot_norm_div = 1.0f / (tot_parm - 1);
+    for (int i = 0; i < tot_parm; ++i) {
+      float parm = i * tot_norm_div;
+      if (endpoints) {
+        if (i <= deg_order_u)
+          parm = 0;
+        else if (i >= num_points)
+          parm = 1;
+      }
+      fprintf(file, " %g", parm);
+    }
+    fputs("\nend\n", file);
+  }
+  return true;
+}
+
 bool OBJ_export_mesh(bContext *UNUSED(C),
                      ExportSettings *settings,
                      std::FILE *file,
@@ -294,11 +374,17 @@ bool OBJ_export_object(bContext *C,
 
       common::free_mesh(mesh, needs_free);
       return true;
+    case OB_CURVE:
+    case OB_SURF:
+      if (settings->export_curves)
+        return OBJ_export_curve(C, settings, file, ob, (const Curve *)ob->data);
+      else
+        return true;  // Continue
     default:
       // TODO someone Probably abort, it shouldn't be possible to get here (once finished)
       std::cerr << "OBJ Export for the object \"" << ob->id.name << "\" is not implemented\n";
       // BLI_assert(false);
-      return false;
+      return true;
   }
 }
 
@@ -322,9 +408,12 @@ void OBJ_export_start(bContext *C, ExportSettings *const settings)
     /* clang-format off */
     auto uv_mapping_pair = common::make_deduplicate_set<uv_key_t>(settings->dedup_uvs_threshold);
     auto no_mapping_pair = common::make_deduplicate_s

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list