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".
This commit is contained in:
parent
ab4f6f01a6
commit
9dadd5ff93
@ -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)
|
||||
{
|
||||
try {
|
||||
is_hdf5 = false;
|
||||
|
||||
try {
|
||||
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();
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user