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:
Diffstat (limited to 'source/blender/alembic/intern')
-rw-r--r--source/blender/alembic/intern/abc_archive.cc175
-rw-r--r--source/blender/alembic/intern/abc_archive.h66
-rw-r--r--source/blender/alembic/intern/abc_customdata.h9
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc96
-rw-r--r--source/blender/alembic/intern/abc_exporter.h10
-rw-r--r--source/blender/alembic/intern/abc_hair.cc2
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc99
-rw-r--r--source/blender/alembic/intern/abc_points.cc2
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc120
9 files changed, 386 insertions, 193 deletions
diff --git a/source/blender/alembic/intern/abc_archive.cc b/source/blender/alembic/intern/abc_archive.cc
new file mode 100644
index 00000000000..0985a06d732
--- /dev/null
+++ b/source/blender/alembic/intern/abc_archive.cc
@@ -0,0 +1,175 @@
+/*
+ * ***** 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;
+}
diff --git a/source/blender/alembic/intern/abc_archive.h b/source/blender/alembic/intern/abc_archive.h
new file mode 100644
index 00000000000..d412574b736
--- /dev/null
+++ b/source/blender/alembic/intern/abc_archive.h
@@ -0,0 +1,66 @@
+/*
+ * ***** 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 *****
+ *
+ */
+
+#ifndef __ABC_ARCHIVE_H__
+#define __ABC_ARCHIVE_H__
+
+#include <Alembic/Abc/All.h>
+
+#ifdef WITH_ALEMBIC_HDF5
+# include <Alembic/AbcCoreHDF5/All.h>
+#endif
+
+#include <Alembic/AbcCoreOgawa/All.h>
+
+#include <fstream>
+
+/* Wrappers around input and output archives. The goal is to be able to use
+ * streams so that unicode paths work on Windows (T49112), and to make sure that
+ * the stream objects remain valid as long as the archives are open.
+ */
+
+class ArchiveReader {
+ Alembic::Abc::IArchive m_archive;
+ std::ifstream m_infile;
+ std::vector<std::istream *> m_streams;
+
+public:
+ explicit ArchiveReader(const char *filename);
+
+ bool valid() const;
+
+ Alembic::Abc::IObject getTop();
+};
+
+class ArchiveWriter {
+ std::ofstream m_outfile;
+ Alembic::Abc::OArchive m_archive;
+
+public:
+ explicit ArchiveWriter(const char *filename, const char *scene, bool do_ogawa, Alembic::Abc::MetaData &md);
+
+ Alembic::Abc::OArchive &archive();
+};
+
+#endif /* __ABC_ARCHIVE_H__ */
diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h
index 3b16c0d9796..bc42e24eba1 100644
--- a/source/blender/alembic/intern/abc_customdata.h
+++ b/source/blender/alembic/intern/abc_customdata.h
@@ -63,6 +63,11 @@ struct CDStreamConfig {
void *user_data;
void *(*add_customdata_cb)(void *user_data, const char *name, int data_type);
+ float weight;
+ float time;
+ int index;
+ int ceil_index;
+
CDStreamConfig()
: mloop(NULL)
, totloop(0)
@@ -72,6 +77,10 @@ struct CDStreamConfig {
, pack_uvs(false)
, user_data(NULL)
, add_customdata_cb(NULL)
+ , weight(0.0f)
+ , time(0.0f)
+ , index(0)
+ , ceil_index(0)
{}
};
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index 764b1533309..a31122b7cd0 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -24,16 +24,7 @@
#include <cmath>
-#ifdef WITH_ALEMBIC_HDF5
-# include <Alembic/AbcCoreHDF5/All.h>
-#endif
-
-#include <Alembic/AbcCoreOgawa/All.h>
-
-#ifdef WIN32
-# include "utfconv.h"
-#endif
-
+#include "abc_archive.h"
#include "abc_camera.h"
#include "abc_curves.h"
#include "abc_hair.h"
@@ -71,54 +62,6 @@ 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()
@@ -145,6 +88,9 @@ ExportSettings::ExportSettings()
, export_ogawa(true)
, pack_uv(false)
, do_convert_axis(false)
+ , triangulate(false)
+ , quad_method(0)
+ , ngon_method(0)
{}
static bool object_is_smoke_sim(Object *ob)
@@ -202,6 +148,7 @@ AbcExporter::AbcExporter(Scene *scene, const char *filename, ExportSettings &set
, m_trans_sampling_index(0)
, m_shape_sampling_index(0)
, m_scene(scene)
+ , m_writer(NULL)
{}
AbcExporter::~AbcExporter()
@@ -214,6 +161,8 @@ AbcExporter::~AbcExporter()
for (int i = 0, e = m_shapes.size(); i != e; ++i) {
delete m_shapes[i];
}
+
+ delete m_writer;
}
void AbcExporter::getShutterSamples(double step, bool time_relative,
@@ -297,32 +246,13 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
Alembic::AbcCoreAbstract::MetaData md;
md.set("FramesPerTimeUnit", str_fps);
- Alembic::Abc::Argument arg(md);
-
- /* 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 = create_archive(&m_out_file,
- m_filename,
- scene_name,
- Alembic::Abc::ErrorHandler::kThrowPolicy,
- arg,
- m_settings.export_ogawa);
+ m_writer = new ArchiveWriter(m_filename, scene_name.c_str(), m_settings.export_ogawa, md);
/* Create time samplings for transforms and shapes. */
TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_step_xform);
- m_trans_sampling_index = m_archive.addTimeSampling(*trans_time);
+ m_trans_sampling_index = m_writer->archive().addTimeSampling(*trans_time);
TimeSamplingPtr shape_time;
@@ -334,10 +264,10 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
}
else {
shape_time = createTimeSampling(m_settings.frame_step_shape);
- m_shape_sampling_index = m_archive.addTimeSampling(*shape_time);
+ m_shape_sampling_index = m_writer->archive().addTimeSampling(*shape_time);
}
- OBox3dProperty archive_bounds_prop = Alembic::AbcGeom::CreateOArchiveBounds(m_archive, m_trans_sampling_index);
+ OBox3dProperty archive_bounds_prop = Alembic::AbcGeom::CreateOArchiveBounds(m_writer->archive(), m_trans_sampling_index);
if (m_settings.flatten_hierarchy) {
createTransformWritersFlat();
@@ -443,7 +373,7 @@ void AbcExporter::createTransformWritersFlat()
if (export_object(&m_settings, ob) && object_is_shape(ob)) {
std::string name = get_id_name(ob);
- m_xforms[name] = new AbcTransformWriter(ob, m_archive.getTop(), 0, m_trans_sampling_index, m_settings);
+ m_xforms[name] = new AbcTransformWriter(ob, m_writer->archive().getTop(), 0, m_trans_sampling_index, m_settings);
}
base = base->next;
@@ -509,7 +439,7 @@ void AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupl
m_xforms[name]->setParent(parent);
}
else {
- m_xforms[name] = new AbcTransformWriter(ob, m_archive.getTop(), NULL, m_trans_sampling_index, m_settings);
+ m_xforms[name] = new AbcTransformWriter(ob, m_writer->archive().getTop(), NULL, m_trans_sampling_index, m_settings);
}
}
diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h
index 6c242f973c4..b0eb8e185d6 100644
--- a/source/blender/alembic/intern/abc_exporter.h
+++ b/source/blender/alembic/intern/abc_exporter.h
@@ -24,13 +24,13 @@
#define __ABC_EXPORTER_H__
#include <Alembic/Abc/All.h>
-#include <fstream>
#include <map>
#include <set>
#include <vector>
class AbcObjectWriter;
class AbcTransformWriter;
+class ArchiveWriter;
struct EvaluationContext;
struct Main;
@@ -66,6 +66,10 @@ struct ExportSettings {
bool export_child_hairs;
bool export_ogawa;
bool pack_uv;
+ bool triangulate;
+
+ int quad_method;
+ int ngon_method;
bool do_convert_axis;
float convert_matrix[3][3];
@@ -76,12 +80,12 @@ 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;
Scene *m_scene;
+ ArchiveWriter *m_writer;
+
std::map<std::string, AbcTransformWriter *> m_xforms;
std::vector<AbcObjectWriter *> m_shapes;
diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc
index 45bf9b7ab8a..14bcf6731ea 100644
--- a/source/blender/alembic/intern/abc_hair.cc
+++ b/source/blender/alembic/intern/abc_hair.cc
@@ -59,7 +59,7 @@ AbcHairWriter::AbcHairWriter(Scene *scene,
{
m_psys = psys;
- OCurves curves(parent->alembicXform(), m_name, m_time_sampling);
+ OCurves curves(parent->alembicXform(), psys->name, m_time_sampling);
m_schema = curves.getSchema();
}
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index b80b7c0c4c8..18b5dd9d1e0 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -37,8 +37,8 @@ extern "C" {
#include "BLI_math_geom.h"
#include "BLI_string.h"
+#include "BKE_cdderivedmesh.h"
#include "BKE_depsgraph.h"
-#include "BKE_DerivedMesh.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
@@ -49,6 +49,9 @@ extern "C" {
#include "WM_types.h"
#include "ED_mesh.h"
+
+#include "bmesh.h"
+#include "bmesh_tools.h"
}
using Alembic::Abc::FloatArraySample;
@@ -538,6 +541,23 @@ DerivedMesh *AbcMeshWriter::getFinalMesh()
m_subsurf_mod->mode &= ~eModifierMode_DisableTemporary;
}
+ if (m_settings.triangulate) {
+ const bool tag_only = false;
+ const int quad_method = m_settings.quad_method;
+ const int ngon_method = m_settings.ngon_method;
+
+ BMesh *bm = DM_to_bmesh(dm, true);
+
+ BM_mesh_triangulate(bm, quad_method, ngon_method, tag_only, NULL, NULL, NULL);
+
+ DerivedMesh *result = CDDM_from_bmesh(bm, false);
+ BM_mesh_free(bm);
+
+ freeMesh(dm);
+
+ dm = result;
+ }
+
m_custom_data_config.pack_uvs = m_settings.pack_uv;
m_custom_data_config.mpoly = dm->getPolyArray(dm);
m_custom_data_config.mloop = dm->getLoopArray(dm);
@@ -784,6 +804,7 @@ struct AbcMeshData {
Int32ArraySamplePtr face_counts;
P3fArraySamplePtr positions;
+ P3fArraySamplePtr ceil_positions;
N3fArraySamplePtr vertex_normals;
N3fArraySamplePtr face_normals;
@@ -831,12 +852,32 @@ CDStreamConfig create_config(Mesh *mesh)
return config;
}
+static void read_mverts_interp(MVert *mverts, const P3fArraySamplePtr &positions, const P3fArraySamplePtr &ceil_positions, const float weight)
+{
+ float tmp[3];
+ for (int i = 0; i < positions->size(); ++i) {
+ MVert &mvert = mverts[i];
+ const Imath::V3f &floor_pos = (*positions)[i];
+ const Imath::V3f &ceil_pos = (*ceil_positions)[i];
+
+ interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), weight);
+ copy_yup_zup(mvert.co, tmp);
+
+ mvert.bweight = 0;
+ }
+}
+
static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data)
{
MVert *mverts = config.mvert;
const P3fArraySamplePtr &positions = mesh_data.positions;
const N3fArraySamplePtr &normals = mesh_data.vertex_normals;
+ if (config.weight != 0.0f && mesh_data.ceil_positions) {
+ read_mverts_interp(mverts, positions, mesh_data.ceil_positions, config.weight);
+ return;
+ }
+
read_mverts(mverts, positions, normals);
}
@@ -1063,6 +1104,46 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_star
utils::assign_materials(bmain, m_object, mat_map);
}
+typedef std::pair<Alembic::AbcCoreAbstract::index_t, float> index_time_pair_t;
+
+static void get_weight_and_index(CDStreamConfig &config,
+ Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling,
+ size_t samples_number)
+{
+ if (samples_number == 0) {
+ samples_number = 1;
+ }
+
+ index_time_pair_t floor_index = time_sampling->getFloorIndex(config.time, samples_number);
+
+ config.index = floor_index.first;
+ config.ceil_index = config.index;
+
+ if (fabs(config.time - floor_index.second) < 0.0001f) {
+ config.weight = 0.0f;
+ return;
+ }
+
+ index_time_pair_t ceil_index = time_sampling->getCeilIndex(config.time, samples_number);
+
+ if (config.index == ceil_index.first) {
+ config.weight = 0.0f;
+ return;
+ }
+
+ config.ceil_index = ceil_index.first;
+
+ float alpha = (config.time - floor_index.second) / (ceil_index.second - floor_index.second);
+
+ /* Since we so closely match the ceiling, we'll just use it. */
+ if (fabs(1.0f - alpha) < 0.0001f) {
+ config.index = config.ceil_index;
+ alpha = 0.0f;
+ }
+
+ config.weight = alpha;
+}
+
void read_mesh_sample(ImportSettings *settings,
const IPolyMeshSchema &schema,
const ISampleSelector &selector,
@@ -1080,6 +1161,14 @@ void read_mesh_sample(ImportSettings *settings,
do_normals = (abc_mesh_data.face_normals != NULL);
+ get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
+
+ if (config.weight != 0.0f) {
+ Alembic::AbcGeom::IPolyMeshSchema::Sample ceil_sample;
+ schema.get(ceil_sample, Alembic::Abc::ISampleSelector(static_cast<Alembic::AbcCoreAbstract::index_t>(config.ceil_index)));
+ abc_mesh_data.ceil_positions = ceil_sample.getPositions();
+ }
+
if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector);
}
@@ -1195,6 +1284,14 @@ void read_subd_sample(ImportSettings *settings,
abc_mesh_data.face_normals = N3fArraySamplePtr();
abc_mesh_data.positions = sample.getPositions();
+ get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
+
+ if (config.weight != 0.0f) {
+ Alembic::AbcGeom::ISubDSchema::Sample ceil_sample;
+ schema.get(ceil_sample, Alembic::Abc::ISampleSelector(static_cast<Alembic::AbcCoreAbstract::index_t>(config.ceil_index)));
+ abc_mesh_data.ceil_positions = ceil_sample.getPositions();
+ }
+
if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector);
}
diff --git a/source/blender/alembic/intern/abc_points.cc b/source/blender/alembic/intern/abc_points.cc
index 322bb906bf5..03014547416 100644
--- a/source/blender/alembic/intern/abc_points.cc
+++ b/source/blender/alembic/intern/abc_points.cc
@@ -67,7 +67,7 @@ AbcPointsWriter::AbcPointsWriter(Scene *scene,
{
m_psys = psys;
- OPoints points(parent->alembicXform(), m_name, m_time_sampling);
+ OPoints points(parent->alembicXform(), psys->name, m_time_sampling);
m_schema = points.getSchema();
}
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index d057cc341f6..3cc549350ea 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -22,19 +22,9 @@
#include "../ABC_alembic.h"
-#ifdef WITH_ALEMBIC_HDF5
-# include <Alembic/AbcCoreHDF5/All.h>
-#endif
-
-#include <Alembic/AbcCoreOgawa/All.h>
#include <Alembic/AbcMaterial/IMaterial.h>
-#include <fstream>
-
-#ifdef WIN32
-# include "utfconv.h"
-#endif
-
+#include "abc_archive.h"
#include "abc_camera.h"
#include "abc_curves.h"
#include "abc_hair.h"
@@ -83,13 +73,10 @@ extern "C" {
using Alembic::Abc::Int32ArraySamplePtr;
using Alembic::Abc::ObjectHeader;
-using Alembic::AbcGeom::ErrorHandler;
-using Alembic::AbcGeom::Exception;
using Alembic::AbcGeom::MetaData;
using Alembic::AbcGeom::P3fArraySamplePtr;
using Alembic::AbcGeom::kWrapExisting;
-using Alembic::AbcGeom::IArchive;
using Alembic::AbcGeom::ICamera;
using Alembic::AbcGeom::ICurves;
using Alembic::AbcGeom::ICurvesSchema;
@@ -115,95 +102,16 @@ using Alembic::AbcGeom::V3fArraySamplePtr;
using Alembic::AbcMaterial::IMaterial;
-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();
-}
-
-/* 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)
+ABC_INLINE ArchiveReader *archive_from_handle(AbcArchiveHandle *handle)
{
- return reinterpret_cast<ArchiveWrapper *>(handle);
+ return reinterpret_cast<ArchiveReader *>(handle);
}
-ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveWrapper *archive)
+ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveReader *archive)
{
return reinterpret_cast<AbcArchiveHandle *>(archive);
}
@@ -301,7 +209,7 @@ static void gather_objects_paths(const IObject &object, ListBase *object_paths)
AbcArchiveHandle *ABC_create_handle(const char *filename, ListBase *object_paths)
{
- ArchiveWrapper *archive = new ArchiveWrapper(filename);
+ ArchiveReader *archive = new ArchiveReader(filename);
if (!archive->valid()) {
delete archive;
@@ -443,6 +351,9 @@ void ABC_export(
job->settings.export_ogawa = (params->compression_type == ABC_ARCHIVE_OGAWA);
job->settings.pack_uv = params->packuv;
job->settings.global_scale = params->global_scale;
+ job->settings.triangulate = params->triangulate;
+ job->settings.quad_method = params->quad_method;
+ job->settings.ngon_method = params->ngon_method;
if (job->settings.frame_start > job->settings.frame_end) {
std::swap(job->settings.frame_start, job->settings.frame_end);
@@ -599,10 +510,6 @@ struct ImportJobData {
ABC_INLINE bool is_mesh_and_strands(const IObject &object)
{
- if (object.getNumChildren() != 2) {
- return false;
- }
-
bool has_mesh = false;
bool has_curve = false;
@@ -624,6 +531,9 @@ ABC_INLINE bool is_mesh_and_strands(const IObject &object)
else if (ICurves::matches(md)) {
has_curve = true;
}
+ else if (IPoints::matches(md)) {
+ has_curve = true;
+ }
}
return has_mesh && has_curve;
@@ -637,7 +547,7 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
data->do_update = do_update;
data->progress = progress;
- ArchiveWrapper *archive = new ArchiveWrapper(data->filename);
+ ArchiveReader *archive = new ArchiveReader(data->filename);
if (!archive->valid()) {
delete archive;
@@ -865,7 +775,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)
{
- ArchiveWrapper *archive = archive_from_handle(handle);
+ ArchiveReader *archive = archive_from_handle(handle);
if (!archive || !archive->valid()) {
return;
@@ -988,6 +898,7 @@ static DerivedMesh *read_mesh_sample(DerivedMesh *dm, const IObject &iobject, co
}
CDStreamConfig config = get_config(new_dm ? new_dm : dm);
+ config.time = time;
bool do_normals = false;
read_mesh_sample(&settings, schema, sample_sel, config, do_normals);
@@ -1042,6 +953,7 @@ static DerivedMesh *read_subd_sample(DerivedMesh *dm, const IObject &iobject, co
/* Only read point data when streaming meshes, unless we need to create new ones. */
CDStreamConfig config = get_config(new_dm ? new_dm : dm);
+ config.time = time;
read_subd_sample(&settings, schema, sample_sel, config);
if (new_dm) {
@@ -1141,7 +1053,7 @@ DerivedMesh *ABC_read_mesh(AbcArchiveHandle *handle,
const char **err_str,
int read_flag)
{
- ArchiveWrapper *archive = archive_from_handle(handle);
+ ArchiveReader *archive = archive_from_handle(handle);
if (!archive || !archive->valid()) {
*err_str = "Invalid archive!";