This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/alembic/intern/abc_archive.cc
Kévin Dietrich 04bfea0d67 Fix T49369: Blender crashes/closes down application at alembic export of
any object

There were a couple of crashes caused by stupid typos in
rB631af9f930d2fd2c76751204ff22239aa95f761d and
rB78ea06fea4a74181c25254ed72d50d8a743b6954, as well as a shamefull lack
of 'testing before committing' which only affect exporting.

One crash was due to using RNA_boolean_get instead of RNA_enum_get, the
other one was a tricky case of order of deletion happening in the
destructors of AbcExporter and ArchiveWriter.

Should not affect RC or release.
2016-09-16 09:27:44 +02:00

176 lines
4.6 KiB
C++

/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2016 Kévin Dietrich.
* All rights reserved.
*
* ***** END GPL LICENSE BLOCK *****
*
*/
#include "abc_archive.h"
#ifdef WIN32
# include "utfconv.h"
#endif
using Alembic::Abc::Exception;
using Alembic::Abc::ErrorHandler;
using Alembic::Abc::IArchive;
using Alembic::Abc::kWrapExisting;
using Alembic::Abc::OArchive;
static IArchive open_archive(const std::string &filename,
const std::vector<std::istream *> &input_streams,
bool &is_hdf5)
{
try {
is_hdf5 = false;
Alembic::AbcCoreOgawa::ReadArchive archive_reader(input_streams);
return IArchive(archive_reader(filename),
kWrapExisting,
ErrorHandler::kThrowPolicy);
}
catch (const Exception &e) {
std::cerr << e.what() << '\n';
#ifdef WITH_ALEMBIC_HDF5
try {
is_hdf5 = true;
Alembic::AbcCoreAbstract::ReadArraySampleCachePtr cache_ptr;
return IArchive(Alembic::AbcCoreHDF5::ReadArchive(),
filename.c_str(), ErrorHandler::kThrowPolicy,
cache_ptr);
}
catch (const Exception &) {
std::cerr << e.what() << '\n';
return IArchive();
}
#else
return IArchive();
#endif
}
return IArchive();
}
ArchiveReader::ArchiveReader(const char *filename)
{
#ifdef WIN32
UTF16_ENCODE(filename);
std::wstring wstr(filename_16);
m_infile.open(wstr.c_str(), std::ios::in | std::ios::binary);
UTF16_UN_ENCODE(filename);
#else
m_infile.open(filename, std::ios::in | std::ios::binary);
#endif
m_streams.push_back(&m_infile);
bool is_hdf5;
m_archive = open_archive(filename, m_streams, is_hdf5);
/* We can't open an HDF5 file from a stream, so close it. */
if (is_hdf5) {
m_infile.close();
m_streams.clear();
}
}
bool ArchiveReader::valid() const
{
return m_archive.valid();
}
Alembic::Abc::IObject ArchiveReader::getTop()
{
return m_archive.getTop();
}
/* ************************************************************************** */
/* This kinda duplicates CreateArchiveWithInfo, but Alembic does not seem to
* have a version supporting streams. */
static OArchive create_archive(std::ostream *ostream,
const std::string &filename,
const std::string &scene_name,
Alembic::Abc::MetaData &md,
bool ogawa)
{
md.set(Alembic::Abc::kApplicationNameKey, "Blender");
md.set(Alembic::Abc::kUserDescriptionKey, scene_name);
time_t raw_time;
time(&raw_time);
char buffer[128];
#if defined _WIN32 || defined _WIN64
ctime_s(buffer, 128, &raw_time);
#else
ctime_r(&raw_time, buffer);
#endif
const std::size_t buffer_len = strlen(buffer);
if (buffer_len > 0 && buffer[buffer_len - 1] == '\n') {
buffer[buffer_len - 1] = '\0';
}
md.set(Alembic::Abc::kDateWrittenKey, buffer);
ErrorHandler::Policy policy = ErrorHandler::kThrowPolicy;
#ifdef WITH_ALEMBIC_HDF5
if (!ogawa) {
return OArchive(Alembic::AbcCoreHDF5::WriteArchive(), filename, md, policy);
}
#else
static_cast<void>(filename);
static_cast<void>(ogawa);
#endif
Alembic::AbcCoreOgawa::WriteArchive archive_writer;
return OArchive(archive_writer(ostream, md), kWrapExisting, policy);
}
ArchiveWriter::ArchiveWriter(const char *filename, const char *scene, bool do_ogawa, Alembic::Abc::MetaData &md)
{
/* Use stream to support unicode character paths on Windows. */
if (do_ogawa) {
#ifdef WIN32
UTF16_ENCODE(filename);
std::wstring wstr(filename_16);
m_outfile.open(wstr.c_str(), std::ios::out | std::ios::binary);
UTF16_UN_ENCODE(filename);
#else
m_outfile.open(filename, std::ios::out | std::ios::binary);
#endif
}
m_archive = create_archive(&m_outfile,
filename,
scene,
md,
do_ogawa);
}
OArchive &ArchiveWriter::archive()
{
return m_archive;
}