[Bf-blender-cvs] [9dadd5ff937] master: Fix T51292: Alembic import, show notification when trying to load HDF5

Sybren A. Stüvel noreply at git.blender.org
Tue Apr 25 14:38:14 CEST 2017


Commit: 9dadd5ff937f81cc1e5aa9136b8eafb5a5414bb1
Author: Sybren A. Stüvel
Date:   Tue Apr 25 14:30:01 2017 +0200
Branches: master
https://developer.blender.org/rB9dadd5ff937f81cc1e5aa9136b8eafb5a5414bb1

Fix T51292: Alembic import, show notification when trying to load HDF5

HDF5 Alembic files are not officially supported by Blender. With this
commit, the HDF5 format is detected even when Blender is compiled without
HDF5 support, and the user is given an explanatory error message (rather
than the generic "Could not open Alembic archive for reading".

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

M	source/blender/alembic/intern/abc_archive.cc
M	source/blender/alembic/intern/abc_archive.h
M	source/blender/alembic/intern/alembic_capi.cc

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

diff --git a/source/blender/alembic/intern/abc_archive.cc b/source/blender/alembic/intern/abc_archive.cc
index 5f8fc1a3739..cdbda0ace69 100644
--- a/source/blender/alembic/intern/abc_archive.cc
+++ b/source/blender/alembic/intern/abc_archive.cc
@@ -28,6 +28,8 @@
 #  include "utfconv.h"
 #endif
 
+#include <fstream>
+
 using Alembic::Abc::Exception;
 using Alembic::Abc::ErrorHandler;
 using Alembic::Abc::IArchive;
@@ -38,8 +40,9 @@ static IArchive open_archive(const std::string &filename,
                              const std::vector<std::istream *> &input_streams,
                              bool &is_hdf5)
 {
+	is_hdf5 = false;
+
 	try {
-		is_hdf5 = false;
 		Alembic::AbcCoreOgawa::ReadArchive archive_reader(input_streams);
 
 		return IArchive(archive_reader(filename),
@@ -63,6 +66,27 @@ static IArchive open_archive(const std::string &filename,
 			return IArchive();
 		}
 #else
+		/* Inspect the file to see whether it's really a HDF5 file. */
+		char header[4];  /* char(0x89) + "HDF" */
+		std::ifstream the_file(filename, std::ios::in | std::ios::binary);
+		if (!the_file) {
+			std::cerr << "Unable to open " << filename << std::endl;
+		}
+		else if (!the_file.read(header, sizeof(header))) {
+			std::cerr << "Unable to read from " << filename << std::endl;
+		}
+		else if (strncmp(header + 1, "HDF", 3)) {
+			std::cerr << filename << " has an unknown file format, unable to read." << std::endl;
+		}
+		else {
+			is_hdf5 = true;
+			std::cerr << filename << " is in the obsolete HDF5 format, unable to read." << std::endl;
+		}
+
+		if (the_file.is_open()) {
+			the_file.close();
+		}
+
 		return IArchive();
 #endif
 	}
@@ -83,16 +107,20 @@ ArchiveReader::ArchiveReader(const char *filename)
 
 	m_streams.push_back(&m_infile);
 
-	bool is_hdf5;
-	m_archive = open_archive(filename, m_streams, is_hdf5);
+	m_archive = open_archive(filename, m_streams, m_is_hdf5);
 
 	/* We can't open an HDF5 file from a stream, so close it. */
-	if (is_hdf5) {
+	if (m_is_hdf5) {
 		m_infile.close();
 		m_streams.clear();
 	}
 }
 
+bool ArchiveReader::is_hdf5() const
+{
+	return m_is_hdf5;
+}
+
 bool ArchiveReader::valid() const
 {
 	return m_archive.valid();
diff --git a/source/blender/alembic/intern/abc_archive.h b/source/blender/alembic/intern/abc_archive.h
index d412574b736..84309fbc9df 100644
--- a/source/blender/alembic/intern/abc_archive.h
+++ b/source/blender/alembic/intern/abc_archive.h
@@ -44,12 +44,21 @@ class ArchiveReader {
 	Alembic::Abc::IArchive m_archive;
 	std::ifstream m_infile;
 	std::vector<std::istream *> m_streams;
+	bool m_is_hdf5;
 
 public:
 	explicit ArchiveReader(const char *filename);
 
 	bool valid() const;
 
+	/**
+	 * Returns true when either Blender is compiled with HDF5 support and
+	 * the archive was succesfully opened (valid() will also return true),
+	 * or when Blender was built without HDF5 support but a HDF5 file was
+	 * detected (valid() will return false).
+	 */
+	bool is_hdf5() const;
+
 	Alembic::Abc::IObject getTop();
 };
 
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index e44f66b7e56..50e7626ad1e 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -595,6 +595,7 @@ static std::pair<bool, AbcObjectReader *> visit_object(
 enum {
 	ABC_NO_ERROR = 0,
 	ABC_ARCHIVE_FAIL,
+	ABC_UNSUPPORTED_HDF5,
 };
 
 struct ImportJobData {
@@ -659,8 +660,12 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
 	ArchiveReader *archive = new ArchiveReader(data->filename);
 
 	if (!archive->valid()) {
-		delete archive;
+#ifndef WITH_ALEMBIC_HDF5
+		data->error_code = archive->is_hdf5() ? ABC_UNSUPPORTED_HDF5 : ABC_ARCHIVE_FAIL;
+#else
 		data->error_code = ABC_ARCHIVE_FAIL;
+#endif
+		delete archive;
 		return;
 	}
 
@@ -829,6 +834,9 @@ static void import_endjob(void *user_data)
 		case ABC_ARCHIVE_FAIL:
 			WM_report(RPT_ERROR, "Could not open Alembic archive for reading! See console for detail.");
 			break;
+		case ABC_UNSUPPORTED_HDF5:
+			WM_report(RPT_ERROR, "Alembic archive in obsolete HDF5 format is not supported.");
+			break;
 	}
 
 	WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);




More information about the Bf-blender-cvs mailing list