[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