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