[Bf-blender-cvs] [1ac9a06a589] soc-2019-fast-io: [Fast import/export] Added option to disable deduplicating UVs and normals and small refactoring

Hugo Sales noreply at git.blender.org
Mon Jun 3 10:52:19 CEST 2019


Commit: 1ac9a06a58971efa8d40f8a6ce597c6fdc260613
Author: Hugo Sales
Date:   Thu May 23 17:42:06 2019 +0100
Branches: soc-2019-fast-io
https://developer.blender.org/rB1ac9a06a58971efa8d40f8a6ce597c6fdc260613

[Fast import/export] Added option to disable deduplicating UVs and normals and small refactoring

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

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

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

diff --git a/source/blender/editors/io/intern/common.cpp b/source/blender/editors/io/intern/common.cpp
index a72dcfbee63..a1be9c54687 100644
--- a/source/blender/editors/io/intern/common.cpp
+++ b/source/blender/editors/io/intern/common.cpp
@@ -21,6 +21,7 @@ extern "C" {
 }
 
 #include <iostream>
+#include <chrono>
 
 #include "common.hpp"
 
@@ -183,7 +184,7 @@ namespace common {
 		return name;
 	}
 
-	void export_start(bContext *UNUSED(C), const ExportSettings * const settings) {
+	void export_start(bContext *UNUSED(C), ExportSettings * const settings) {
 		/* From alembic_capi.cc
 		 * XXX annoying hack: needed to prevent data corruption when changing
 		 * scene frame in separate threads
@@ -205,4 +206,12 @@ namespace common {
 		return true;
 	}
 
+	bool time_export(bContext *C, ExportSettings * const settings,
+	                 typeof(export_start) start, typeof(export_end) end) {
+		auto f = std::chrono::steady_clock::now();
+		start(C, settings);
+		auto ret = end(C, settings);
+		std::cout << "Took " << (std::chrono::steady_clock::now() - f).count() << "ns\n";
+		return ret;
+	}
 }
diff --git a/source/blender/editors/io/intern/common.hpp b/source/blender/editors/io/intern/common.hpp
index 4bf73339516..5c492b40687 100644
--- a/source/blender/editors/io/intern/common.hpp
+++ b/source/blender/editors/io/intern/common.hpp
@@ -43,15 +43,19 @@ extern "C" {
 #include "../io_common.h"
 
 }
+
 #include <utility>
 #include <string>
 #include <vector>
 #include <set>
 #include <array>
+#include <typeinfo>
 
 namespace common {
 	using ulong = unsigned long;
 
+	// --- PROTOTYPES ---
+
 	bool object_is_smoke_sim(const Object * const ob);
 
 	bool should_export_object(const ExportSettings * const settings, const Object * const eob);
@@ -65,9 +69,16 @@ namespace common {
 
 	std::string get_object_name(const Object * const eob, const Mesh * const mesh);
 
-	void export_start(bContext *C, const ExportSettings * const settings);
+	void export_start(bContext *C, ExportSettings * const settings);
 	bool export_end(bContext *C, ExportSettings * const settings);
 
+	// Execute `start` and `end` and time it. Those functions should be specific to each exportter,
+	// but have the same signature as the two above
+	bool time_export(bContext *C, ExportSettings * const settings,
+	                 typeof(export_start) start, typeof(export_end) end);
+
+	// --- TEMPLATES ---
+
 	template<typename func>
 	void for_each_modifier(const Object * const ob, func f) {
 		for (ModifierData *md = (ModifierData *) ob->modifiers.first;
@@ -79,8 +90,8 @@ namespace common {
 	void for_each_base(ViewLayer * const view_layer, func f) {
 		for (Base *base = static_cast<Base *>(view_layer->object_bases.first);
 		     base; base = base->next)
-			if (!G.is_break)
-				f(base);
+			if (!G.is_break && !f(base)) // If we should break, or f return false (error)
+				break;
 		G.is_break = false;
 	}
 
@@ -172,7 +183,7 @@ namespace common {
 	template<typename key_t>
 	using dedup_pair_t = std::pair<set_t<key_t>, set_mapping_t<key_t> >;
 
-	using uv_key_t = std::pair<std::array<float, 2>, ulong>;
+	using uv_key_t = std::pair<std::array<float, 2>, ulong>; // ulong is the original index
 	using no_key_t = std::pair<std::array<float, 3>, ulong>;
 
 	// TODO someone Benchmark the performance wth iterators and normal deduplication
@@ -184,7 +195,7 @@ namespace common {
 		auto &set = p.first;
 		auto &set_mapping = p.second;
 
-		// Reserve approximate space to reduce allocations inside loop
+		// Reserve space to reduce allocations inside loop
 		set_mapping.reserve(reserve);
 
 		// C++14/17 would help here...
@@ -194,6 +205,11 @@ namespace common {
 			               auto p = set.insert(std::make_pair(v, total));
 			               set_mapping.push_back(p.first);
 			               if (p.second) {
+				               // "Unfortunately" normals need the actual iterator, but everything
+				               // else just needs the value. Therefore on_insert must always
+				               // recieve an iterator, but caller to this function should wrap
+				               // it's caller's function on a function, to get the first
+				               // field of the iterator
 				               on_insert(i, p.first);
 				               ++total;
 			               }
@@ -216,7 +232,11 @@ namespace common {
 		            mesh,
 		            /* modifies  */ p,
 		            /* for_each */  for_each_uv_t{},
-		            /* on_insert */ f);
+		            /* on_insert */
+		            [&f](ulong i, typename set_t<uv_key_t>::iterator it) {
+			            // As said in the deduplicate function, unwrap the iterator
+			            f(i, it->first);
+		            });
 	}
 
 	template<typename func>
@@ -229,8 +249,8 @@ namespace common {
 		            /* for_each  */ for_each_normal_t{},
 		            /* on_insert */
 		            [&p, &f, &mesh](ulong i, typename set_t<no_key_t>::iterator it){
-			            // Call callee function
-			            f(i, it);
+			            // Call caller's function
+			            f(i, it->first);
 
 			            // If the face is flat shaded, f is only invoked once, but we need to
 			            // add the value to the map an additional totloop - 1 times
diff --git a/source/blender/editors/io/intern/obj.cpp b/source/blender/editors/io/intern/obj.cpp
index 3a5a255685e..580bd48a4ee 100644
--- a/source/blender/editors/io/intern/obj.cpp
+++ b/source/blender/editors/io/intern/obj.cpp
@@ -69,21 +69,11 @@ extern "C" {
   -?vertex order
   --scale
   # units?
-
+  # removing duplicates with a threshold and as an option
   TODO someone filter_glob : StringProp weird Python syntax
 
  */
 
-extern "C" {
-bool OBJ_export(bContext *C, ExportSettings *settings) {
-	auto f = std::chrono::steady_clock::now();
-	OBJ_export_start(C, settings);
-	auto ret = OBJ_export_end(C, settings);
-	std::cout << "Took " << (std::chrono::steady_clock::now() - f).count() << "ns\n";
-	return ret;
-}
-} // extern
-
 namespace {
 
 	using namespace common;
@@ -143,28 +133,31 @@ namespace {
 		                              });
 
 		if (settings->export_uvs) {
+			auto uv_writer = [&fs](ulong UNUSED(i), const std::array<float, 2> &v) {
+				                 fs << "vt " << v[0] << ' ' << v[1] << '\n';
+			                 };
+
 			// TODO someone Is T47010 still relevant?
-			common::for_each_deduplicated_uv(mesh, /* modifies */ uv_total,
-			                                 /* modifies */ uv_mapping_pair,
-			                                 [&fs](ulong UNUSED(i),
-			                                       const typename set_t<uv_key_t>::
-			                                       iterator &v) {
-				                                 fs << "vt " << v->first[0]
-				                                    << ' '   << v->first[1] << '\n';
-			                                 });
+			if (settings->dedup_uvs)
+				common::for_each_deduplicated_uv(mesh, /* modifies */ uv_total,
+				                                 /* modifies */ uv_mapping_pair,
+				                                 uv_writer);
+			else
+				common::for_each_uv(mesh, uv_writer);
 		}
 
 		if (settings->export_normals) {
+			auto normal_writer = [&fs](ulong UNUSED(i), const std::array<float, 3> &v) {
+				                     fs << "vn " << v[0] << ' ' << v[1] << ' ' << v[2] << '\n';
+			                     };
+
 			fs << std::fixed << std::setprecision(4);
-			common::for_each_deduplicated_normal(mesh, /* modifies */ no_total,
-			                                     /* modifies */ no_mapping_pair,
-			                                     [&fs](ulong UNUSED(i),
-			                                           const typename set_t<no_key_t>::
-			                                           iterator &v) {
-				                                     fs << "vn " << v->first[0]
-				                                        << ' '   << v->first[1]
-				                                        << ' '   << v->first[2] << '\n';
-			                                     });
+			if (settings->dedup_normals)
+				common::for_each_deduplicated_normal(mesh, /* modifies */ no_total,
+				                                     /* modifies */ no_mapping_pair,
+				                                     normal_writer);
+			else
+				common::for_each_normal(mesh, normal_writer);
 		}
 
 		if (settings->export_edges) {
@@ -242,40 +235,44 @@ namespace {
 			return false;
 		}
 	}
-}
 
-bool OBJ_export_start(bContext *C, ExportSettings *settings) {
-	common::export_start(C, settings);
 
-	std::fstream fs;
-	fs.open(settings->filepath, std::ios::out);
-	fs << "# Blender v2.8\n# www.blender.org\n"; // TODO someone add proper version
-	// TODO someone add material export
+	void OBJ_export_start(bContext *C, ExportSettings * const settings) {
+		common::export_start(C, settings);
+
+		std::fstream fs;
+		fs.open(settings->filepath, std::ios::out);
+		fs << "# Blender v2.8\n# www.blender.org\n"; // TODO someone add proper version
+		// TODO someone add material export
 
-	// If not exporting animattions, the start and end are the same
-	for (int frame = settings->frame_start; frame <= settings->frame_end; ++frame) {
-		BKE_scene_frame_set(settings->scene, frame);
-		BKE_scene_graph_update_for_newframe(settings->depsgraph, settings->main);
-		Scene *escene  = DEG_get_evaluated_scene(settings->depsgraph);
-		ulong vertex_total = 0, uv_total = 0, no_total = 0;
+		// If not exporting animattions, the start and end are the same
+		for (int frame = settings->frame_start; frame <= settings->frame_end; ++frame) {
+			BKE_scene_frame_set(settings->scene, frame);
+			BKE_scene_graph_update_for_newframe(settings->depsgraph, settings->main);
+			Scene *escene  = DEG_get_evaluated_scene(settings->depsgraph);
+			ulong vertex_total = 0, uv_total = 0, no_total = 0;
 
-		auto uv_mapping_pair = common::make_deduplicate_set<uv_key_t>();
-		auto no_mapping_pair = common::make_deduplicate_set<no_key_t>();
+			auto uv_mapping_pair = common::make_deduplicate_set<uv_key_t>();
+			auto no_mapping_pair = common::make_deduplicate_set<no_key_t>();
 
-		// TODO someone if not exporting as objects, do they need to all be merged?
-		common::for_each_base(settings->view_layer,
-		                   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list