Blender V5.0
abc_reader_archive.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 Kévin Dietrich. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10
11#include "Alembic/Abc/ArchiveInfo.h"
12#include "Alembic/AbcCoreAbstract/MetaData.h"
13#include "Alembic/AbcCoreLayer/Read.h"
14#include "Alembic/AbcCoreOgawa/ReadWrite.h"
15
16#include "BKE_main.hh"
17
18#include "BLI_path_utils.hh"
19#include "BLI_string.h"
20
21#ifdef WIN32
22# include "utfconv.hh"
23#endif
24
25#include <fstream>
26#include <vector>
27
28using Alembic::Abc::ErrorHandler;
29using Alembic::Abc::Exception;
30using Alembic::Abc::IArchive;
31using Alembic::Abc::kWrapExisting;
32using Alembic::Abc::MetaData;
33
34namespace blender::io::alembic {
35
36static IArchive open_archive(const std::string &filename,
37 const std::vector<std::istream *> &input_streams)
38{
39 try {
40 Alembic::AbcCoreOgawa::ReadArchive archive_reader(input_streams);
41
42 return IArchive(archive_reader(filename), kWrapExisting, ErrorHandler::kThrowPolicy);
43 }
44 catch (const Exception &e) {
45 std::cerr << e.what() << '\n';
46
47 /* Inspect the file to see whether it's actually a HDF5 file. */
48 char header[4]; /* char(0x89) + "HDF" */
49 std::ifstream the_file(filename.c_str(), std::ios::in | std::ios::binary);
50 if (!the_file) {
51 std::cerr << "Unable to open " << filename << std::endl;
52 }
53 else if (!the_file.read(header, sizeof(header))) {
54 std::cerr << "Unable to read from " << filename << std::endl;
55 }
56 else if (strncmp(header + 1, "HDF", 3) != 0) {
57 std::cerr << filename << " has an unknown file format, unable to read." << std::endl;
58 }
59 else {
60 std::cerr << filename << " is in the obsolete HDF5 format, unable to read." << std::endl;
61 }
62
63 if (the_file.is_open()) {
64 the_file.close();
65 }
66 }
67
68 return IArchive();
69}
70
71ArchiveReader *ArchiveReader::get(const Main *bmain, const std::vector<const char *> &filenames)
72{
73 std::vector<ArchiveReader *> readers;
74
75 for (const char *filename : filenames) {
76 ArchiveReader *reader = new ArchiveReader(bmain, filename);
77
78 if (!reader->valid()) {
79 delete reader;
80 continue;
81 }
82
83 readers.push_back(reader);
84 }
85
86 if (readers.empty()) {
87 return nullptr;
88 }
89
90 if (readers.size() == 1) {
91 return readers[0];
92 }
93
94 return new ArchiveReader(readers);
95}
96
97ArchiveReader::ArchiveReader(const std::vector<ArchiveReader *> &readers) : m_readers(readers)
98{
99 Alembic::AbcCoreLayer::ArchiveReaderPtrs archives;
100
101 for (ArchiveReader *reader : readers) {
102 archives.push_back(reader->m_archive.getPtr());
103 }
104
105 Alembic::AbcCoreLayer::ReadArchive layer;
106 Alembic::AbcCoreAbstract::ArchiveReaderPtr arPtr = layer(archives);
107
108 m_archive = IArchive(arPtr, kWrapExisting, ErrorHandler::kThrowPolicy);
109}
110
111ArchiveReader::ArchiveReader(const Main *bmain, const char *filename)
112{
113 char abs_filepath[FILE_MAX];
114 STRNCPY(abs_filepath, filename);
115 BLI_path_abs(abs_filepath, BKE_main_blendfile_path(bmain));
116
117#ifdef WIN32
118 UTF16_ENCODE(abs_filepath);
119 std::wstring wstr(abs_filepath_16);
120 m_infile.open(wstr.c_str(), std::ios::in | std::ios::binary);
121 UTF16_UN_ENCODE(abs_filepath);
122#else
123 m_infile.open(abs_filepath, std::ios::in | std::ios::binary);
124#endif
125
126 m_streams.push_back(&m_infile);
127
128 m_archive = open_archive(abs_filepath, m_streams);
129}
130
132{
133 for (ArchiveReader *reader : m_readers) {
134 delete reader;
135 }
136}
137
139{
140 return m_archive.valid();
141}
142
143Alembic::Abc::IObject ArchiveReader::getTop()
144{
145 return m_archive.getTop();
146}
147
149{
150 const MetaData &abc_metadata = m_archive.getPtr()->getMetaData();
151
152 /* Was the incoming Archive written by Blender? If so, make the version check. */
153 if (abc_metadata.get(Alembic::Abc::kApplicationNameKey) == "Blender") {
154 return abc_metadata.get("blender_version") < "v4.4";
155 }
156
157 return false;
158}
159
160} // namespace blender::io::alembic
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
Definition main.cc:887
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
#define FILE_MAX
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
static ArchiveReader * get(const struct Main *bmain, const std::vector< const char * > &filenames)
static IArchive open_archive(const std::string &filename, const std::vector< std::istream * > &input_streams)
#define UTF16_ENCODE(in8str)
Definition utfconv.hh:80
#define UTF16_UN_ENCODE(in8str)
Definition utfconv.hh:84