[Bf-blender-cvs] [6d55dcf4dd2] master: Alembic: addition of a simple logging class.

Kévin Dietrich noreply at git.blender.org
Wed Apr 5 05:00:15 CEST 2017


Commit: 6d55dcf4dd2f2793ff433c31d4be30d7eaf35fba
Author: Kévin Dietrich
Date:   Wed Apr 5 04:56:38 2017 +0200
Branches: master
https://developer.blender.org/rB6d55dcf4dd2f2793ff433c31d4be30d7eaf35fba

Alembic: addition of a simple logging class.

The idea is to have a system where we properly log error messages and
let the users know that errors occured redirecting them to the console
for explanations. This is only implemented for the exporter since the
importer already has similar functionalities; however they shall
ultimately be unified in some way.

Reviewers: sybren, dfelinto

Differential Revision: https://developer.blender.org/D2541

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

M	source/blender/alembic/intern/abc_exporter.cc
M	source/blender/alembic/intern/abc_exporter.h
M	source/blender/alembic/intern/abc_object.cc
M	source/blender/alembic/intern/abc_util.cc
M	source/blender/alembic/intern/abc_util.h
M	source/blender/alembic/intern/alembic_capi.cc

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

diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index 564157fbc97..20ca40c3570 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -66,6 +66,7 @@ using Alembic::Abc::OBox3dProperty;
 
 ExportSettings::ExportSettings()
     : scene(NULL)
+	, logger()
     , selected_only(false)
     , visible_layers_only(false)
     , renderable_only(false)
@@ -419,7 +420,7 @@ void AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupl
 
 	/* check if we have already created a transform writer for this object */
 	if (getXForm(name) != NULL) {
-		std::cerr << "xform " << name << " already exists\n";
+		ABC_LOG(m_settings.logger) << "xform " << name << " already exists!\n";
 		return;
 	}
 
@@ -513,7 +514,7 @@ void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
 	AbcTransformWriter *xform = getXForm(name);
 
 	if (!xform) {
-		std::cerr << __func__ << ": xform " << name << " is NULL\n";
+		ABC_LOG(m_settings.logger) << __func__ << ": xform " << name << " is NULL\n";
 		return;
 	}
 
diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h
index b0eb8e185d6..f9fde99acd4 100644
--- a/source/blender/alembic/intern/abc_exporter.h
+++ b/source/blender/alembic/intern/abc_exporter.h
@@ -28,6 +28,8 @@
 #include <set>
 #include <vector>
 
+#include "abc_util.h"
+
 class AbcObjectWriter;
 class AbcTransformWriter;
 class ArchiveWriter;
@@ -41,6 +43,7 @@ struct ExportSettings {
 	ExportSettings();
 
 	Scene *scene;
+	SimpleLogger logger;
 
 	bool selected_only;
 	bool visible_layers_only;
diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index a5b8af542fc..a0cd378ff95 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -91,7 +91,7 @@ Imath::Box3d AbcObjectWriter::bounds()
 
 	if (!bb) {
 		if (this->m_object->type != OB_CAMERA) {
-			std::cerr << "Boundbox is null!\n";
+			ABC_LOG(m_settings.logger) << "Bounding box is null!\n";
 		}
 
 		return Imath::Box3d();
diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc
index 50fa43a3491..f82b07e91fb 100644
--- a/source/blender/alembic/intern/abc_util.cc
+++ b/source/blender/alembic/intern/abc_util.cc
@@ -537,3 +537,32 @@ ScopeTimer::~ScopeTimer()
 {
 	fprintf(stderr, "%s: %fs\n", m_message, PIL_check_seconds_timer() - m_start);
 }
+
+/* ********************** */
+
+bool SimpleLogger::empty()
+{
+	return m_stream.tellp() == 0ul;
+}
+
+std::string SimpleLogger::str() const
+{
+	return m_stream.str();
+}
+
+void SimpleLogger::clear()
+{
+	m_stream.clear();
+	m_stream.str("");
+}
+
+std::ostringstream &SimpleLogger::stream()
+{
+	return m_stream;
+}
+
+std::ostream &operator<<(std::ostream &os, const SimpleLogger &logger)
+{
+	os << logger.str();
+	return os;
+}
diff --git a/source/blender/alembic/intern/abc_util.h b/source/blender/alembic/intern/abc_util.h
index 85ba4d5c9c7..5aa74d232f7 100644
--- a/source/blender/alembic/intern/abc_util.h
+++ b/source/blender/alembic/intern/abc_util.h
@@ -165,4 +165,48 @@ public:
 #	define SCOPE_TIMER(message)
 #endif
 
+/* *************************** */
+
+/**
+ * Utility class whose purpose is to more easily log related informations. An
+ * instance of the SimpleLogger can be created in any context, and will hold a
+ * copy of all the strings passed to its output stream.
+ *
+ * Different instances of the class may be accessed from different threads,
+ * although accessing the same instance from different threads will lead to race
+ * conditions.
+ */
+class SimpleLogger {
+	std::ostringstream m_stream;
+
+public:
+	/**
+	 * Check whether or not the SimpleLogger's stream is empty.
+	 */
+	bool empty();
+
+	/**
+	 * Return a copy of the string contained in the SimpleLogger's stream.
+	 */
+	std::string str() const;
+
+	/**
+	 * Remove the bits set on the SimpleLogger's stream and clear its string.
+	 */
+	void clear();
+
+	/**
+	 * Return a reference to the SimpleLogger's stream, in order to e.g. push
+	 * content into it.
+	 */
+	std::ostringstream &stream();
+};
+
+#define ABC_LOG(logger) logger.stream()
+
+/**
+ * Pass the content of the logger's stream to the specified std::ostream.
+ */
+std::ostream &operator<<(std::ostream &os, const SimpleLogger &logger);
+
 #endif  /* __ABC_UTIL_H__ */
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index dc5146a26e0..6c6f64e1669 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -301,10 +301,10 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo
 		}
 	}
 	catch (const std::exception &e) {
-		std::cerr << "Abc Export error: " << e.what() << '\n';
+		ABC_LOG(data->settings.logger) << "Abc Export error: " << e.what() << '\n';
 	}
 	catch (...) {
-		std::cerr << "Abc Export error\n";
+		ABC_LOG(data->settings.logger) << "Abc Export: unknown error...\n";
 	}
 }
 
@@ -316,6 +316,11 @@ static void export_endjob(void *customdata)
 		BLI_delete(data->filename, false, false);
 	}
 
+	if (!data->settings.logger.empty()) {
+		std::cerr << data->settings.logger;
+		WM_report(RPT_ERROR, "Errors occured during the export, look in the console to know more...");
+	}
+
 	G.is_rendering = false;
 	BKE_spacedata_draw_locks(false);
 }
@@ -331,6 +336,22 @@ void ABC_export(
 	job->bmain = CTX_data_main(C);
 	BLI_strncpy(job->filename, filepath, 1024);
 
+	/* Alright, alright, alright....
+	 *
+	 * ExportJobData contains an ExportSettings containing a SimpleLogger.
+	 *
+	 * Since ExportJobData is a C-style struct dynamically allocated with
+	 * MEM_mallocN (see above), its construtor is never called, therefore the
+	 * ExportSettings constructor is not called which implies that the
+	 * SimpleLogger one is not called either. SimpleLogger in turn does not call
+	 * the constructor of its data members which ultimately means that its
+	 * std::ostringstream member has a NULL pointer. To be able to properly use
+	 * the stream's operator<<, the pointer needs to be set, therefore we have
+	 * to properly construct everything. And this is done using the placement
+	 * new operator as here below. It seems hackish, but I'm too lazy to
+	 * do bigger refactor and maybe there is a better way which does not involve
+	 * hardcore refactoring. */
+	new (&job->settings) ExportSettings();
 	job->settings.scene = job->scene;
 	job->settings.frame_start = params->frame_start;
 	job->settings.frame_end = params->frame_end;




More information about the Bf-blender-cvs mailing list