Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2016-09-04 17:41:06 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-09-04 17:41:06 +0300
commit3c29aad787f636167319950636f1497442075df8 (patch)
tree3a993cc25296ce987893b9f58b7c794b51e77f85 /source/blender/alembic
parent498583844fb7d0adbbc91d512f98885800cdf46e (diff)
parente76e8fcdcc53455a52a6a73495881eddd346472c (diff)
Merge branch 'master' into blender2.8
Conflicts: intern/cycles/blender/blender_particles.cpp source/blender/blenkernel/intern/particle.c source/blender/gpu/intern/gpu_shader.c
Diffstat (limited to 'source/blender/alembic')
-rw-r--r--source/blender/alembic/CMakeLists.txt1
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc85
-rw-r--r--source/blender/alembic/intern/abc_exporter.h2
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc125
4 files changed, 160 insertions, 53 deletions
diff --git a/source/blender/alembic/CMakeLists.txt b/source/blender/alembic/CMakeLists.txt
index 42bd6a9c340..0b6b2433bd0 100644
--- a/source/blender/alembic/CMakeLists.txt
+++ b/source/blender/alembic/CMakeLists.txt
@@ -33,6 +33,7 @@ set(INC
../makesrna
../windowmanager
../../../intern/guardedalloc
+ ../../../intern/utfconv
)
set(INC_SYS
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index 132c59c0cfb..57a2bdd274f 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -30,6 +30,10 @@
#include <Alembic/AbcCoreOgawa/All.h>
+#ifdef WIN32
+# include "utfconv.h"
+#endif
+
#include "abc_camera.h"
#include "abc_curves.h"
#include "abc_hair.h"
@@ -66,6 +70,54 @@ extern "C" {
using Alembic::Abc::TimeSamplingPtr;
using Alembic::Abc::OBox3dProperty;
+
+/* ************************************************************************** */
+
+/* This kinda duplicates CreateArchiveWithInfo, but Alembic does not seem to
+ * have a version supporting streams. */
+static Alembic::Abc::OArchive create_archive(std::ostream *ostream,
+ const std::string &filename,
+ const std::string &scene_name,
+ const Alembic::Abc::Argument &arg0,
+ const Alembic::Abc::Argument &arg1,
+ bool ogawa)
+{
+ Alembic::Abc::MetaData md = GetMetaData(arg0, arg1);
+ 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);
+
+ Alembic::Abc::ErrorHandler::Policy policy = GetErrorHandlerPolicyFromArgs(arg0, arg1);
+
+#ifdef WITH_ALEMBIC_HDF5
+ if (!ogawa) {
+ return Alembic::Abc::OArchive(Alembic::AbcCoreHDF5::WriteArchive(), filename, md, policy);
+ }
+#else
+ static_cast<void>(filename);
+ static_cast<void>(ogawa);
+#endif
+
+ Alembic::AbcCoreOgawa::WriteArchive archive_writer;
+ return Alembic::Abc::OArchive(archive_writer(ostream, md), Alembic::Abc::kWrapExisting, policy);
+}
+
/* ************************************************************************** */
ExportSettings::ExportSettings()
@@ -246,26 +298,25 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
Alembic::Abc::Argument arg(md);
-#ifdef WITH_ALEMBIC_HDF5
- if (!m_settings.export_ogawa) {
- m_archive = Alembic::Abc::CreateArchiveWithInfo(Alembic::AbcCoreHDF5::WriteArchive(),
- m_filename,
- "Blender",
- scene_name,
- Alembic::Abc::ErrorHandler::kThrowPolicy,
- arg);
- }
- else
+ /* Use stream to support unicode character paths on Windows. */
+ if (m_settings.export_ogawa) {
+#ifdef WIN32
+ UTF16_ENCODE(m_filename);
+ std::wstring wstr(m_filename_16);
+ m_out_file.open(wstr.c_str(), std::ios::out | std::ios::binary);
+ UTF16_UN_ENCODE(m_filename);
+#else
+ m_out_file.open(m_filename, std::ios::out | std::ios::binary);
#endif
- {
- m_archive = Alembic::Abc::CreateArchiveWithInfo(Alembic::AbcCoreOgawa::WriteArchive(),
- m_filename,
- "Blender",
- scene_name,
- Alembic::Abc::ErrorHandler::kThrowPolicy,
- arg);
}
+ m_archive = create_archive(&m_out_file,
+ m_filename,
+ scene_name,
+ Alembic::Abc::ErrorHandler::kThrowPolicy,
+ arg,
+ m_settings.export_ogawa);
+
/* Create time samplings for transforms and shapes. */
TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_step_xform);
diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h
index 070eb9ea81a..6c242f973c4 100644
--- a/source/blender/alembic/intern/abc_exporter.h
+++ b/source/blender/alembic/intern/abc_exporter.h
@@ -24,6 +24,7 @@
#define __ABC_EXPORTER_H__
#include <Alembic/Abc/All.h>
+#include <fstream>
#include <map>
#include <set>
#include <vector>
@@ -75,6 +76,7 @@ class AbcExporter {
const char *m_filename;
+ std::ofstream m_out_file;
Alembic::Abc::OArchive m_archive;
unsigned int m_trans_sampling_index, m_shape_sampling_index;
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index f42c708b4c2..d057cc341f6 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -29,6 +29,12 @@
#include <Alembic/AbcCoreOgawa/All.h>
#include <Alembic/AbcMaterial/IMaterial.h>
+#include <fstream>
+
+#ifdef WIN32
+# include "utfconv.h"
+#endif
+
#include "abc_camera.h"
#include "abc_curves.h"
#include "abc_hair.h"
@@ -109,49 +115,97 @@ using Alembic::AbcGeom::V3fArraySamplePtr;
using Alembic::AbcMaterial::IMaterial;
-struct AbcArchiveHandle {
- int unused;
-};
-
-ABC_INLINE IArchive *archive_from_handle(AbcArchiveHandle *handle)
-{
- return reinterpret_cast<IArchive *>(handle);
-}
-
-ABC_INLINE AbcArchiveHandle *handle_from_archive(IArchive *archive)
+static IArchive open_archive(const std::string &filename,
+ const std::vector<std::istream *> &input_streams,
+ bool &is_hdf5)
{
- return reinterpret_cast<AbcArchiveHandle *>(archive);
-}
-
-static IArchive *open_archive(const std::string &filename)
-{
- Alembic::AbcCoreAbstract::ReadArraySampleCachePtr cache_ptr;
- IArchive *archive;
-
try {
- archive = new IArchive(Alembic::AbcCoreOgawa::ReadArchive(),
- filename.c_str(), ErrorHandler::kThrowPolicy,
- cache_ptr);
+ 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 {
- archive = new IArchive(Alembic::AbcCoreHDF5::ReadArchive(),
- filename.c_str(), ErrorHandler::kThrowPolicy,
- cache_ptr);
+ 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 NULL;
+ return IArchive();
}
#else
- return NULL;
+ return IArchive();
#endif
}
- return archive;
+ return IArchive();
+}
+
+/* Wrapper around an archive to be able to use streams so that unicode paths
+ * work on Windows (T49112), and to make sure the input stream remains valid as
+ * long as the archive is open. */
+class ArchiveWrapper {
+ IArchive m_archive;
+ std::ifstream m_infile;
+ std::vector<std::istream *> m_streams;
+
+public:
+ explicit ArchiveWrapper(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 valid() const
+ {
+ return m_archive.valid();
+ }
+
+ IObject getTop()
+ {
+ return m_archive.getTop();
+ }
+};
+
+struct AbcArchiveHandle {
+ int unused;
+};
+
+ABC_INLINE ArchiveWrapper *archive_from_handle(AbcArchiveHandle *handle)
+{
+ return reinterpret_cast<ArchiveWrapper *>(handle);
+}
+
+ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveWrapper *archive)
+{
+ return reinterpret_cast<AbcArchiveHandle *>(archive);
}
//#define USE_NURBS
@@ -247,9 +301,10 @@ static void gather_objects_paths(const IObject &object, ListBase *object_paths)
AbcArchiveHandle *ABC_create_handle(const char *filename, ListBase *object_paths)
{
- IArchive *archive = open_archive(filename);
+ ArchiveWrapper *archive = new ArchiveWrapper(filename);
- if (!archive) {
+ if (!archive->valid()) {
+ delete archive;
return NULL;
}
@@ -582,12 +637,10 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
data->do_update = do_update;
data->progress = progress;
- IArchive *archive = open_archive(data->filename);
+ ArchiveWrapper *archive = new ArchiveWrapper(data->filename);
- if (!archive || !archive->valid()) {
- if (archive) {
- delete archive;
- }
+ if (!archive->valid()) {
+ delete archive;
data->error_code = ABC_ARCHIVE_FAIL;
return;
}
@@ -812,7 +865,7 @@ void ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence
void ABC_get_transform(AbcArchiveHandle *handle, Object *ob, const char *object_path, float r_mat[4][4], float time, float scale)
{
- IArchive *archive = archive_from_handle(handle);
+ ArchiveWrapper *archive = archive_from_handle(handle);
if (!archive || !archive->valid()) {
return;
@@ -1088,7 +1141,7 @@ DerivedMesh *ABC_read_mesh(AbcArchiveHandle *handle,
const char **err_str,
int read_flag)
{
- IArchive *archive = archive_from_handle(handle);
+ ArchiveWrapper *archive = archive_from_handle(handle);
if (!archive || !archive->valid()) {
*err_str = "Invalid archive!";