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:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/alembic/intern
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/alembic/intern')
-rw-r--r--source/blender/alembic/intern/abc_archive.cc197
-rw-r--r--source/blender/alembic/intern/abc_archive.h43
-rw-r--r--source/blender/alembic/intern/abc_camera.cc187
-rw-r--r--source/blender/alembic/intern/abc_camera.h46
-rw-r--r--source/blender/alembic/intern/abc_curves.cc766
-rw-r--r--source/blender/alembic/intern/abc_curves.h67
-rw-r--r--source/blender/alembic/intern/abc_customdata.cc680
-rw-r--r--source/blender/alembic/intern/abc_customdata.h89
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc951
-rw-r--r--source/blender/alembic/intern/abc_exporter.h143
-rw-r--r--source/blender/alembic/intern/abc_hair.cc423
-rw-r--r--source/blender/alembic/intern/abc_hair.h50
-rw-r--r--source/blender/alembic/intern/abc_mball.cc80
-rw-r--r--source/blender/alembic/intern/abc_mball.h33
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc1962
-rw-r--r--source/blender/alembic/intern/abc_mesh.h173
-rw-r--r--source/blender/alembic/intern/abc_nurbs.cc453
-rw-r--r--source/blender/alembic/intern/abc_nurbs.h36
-rw-r--r--source/blender/alembic/intern/abc_object.cc407
-rw-r--r--source/blender/alembic/intern/abc_object.h229
-rw-r--r--source/blender/alembic/intern/abc_points.cc242
-rw-r--r--source/blender/alembic/intern/abc_points.h52
-rw-r--r--source/blender/alembic/intern/abc_transform.cc177
-rw-r--r--source/blender/alembic/intern/abc_transform.h73
-rw-r--r--source/blender/alembic/intern/abc_util.cc501
-rw-r--r--source/blender/alembic/intern/abc_util.h172
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc1475
27 files changed, 4869 insertions, 4838 deletions
diff --git a/source/blender/alembic/intern/abc_archive.cc b/source/blender/alembic/intern/abc_archive.cc
index 7bd3e5af66a..c4252d20d48 100644
--- a/source/blender/alembic/intern/abc_archive.cc
+++ b/source/blender/alembic/intern/abc_archive.cc
@@ -22,9 +22,8 @@
*/
#include "abc_archive.h"
-extern "C"
-{
- #include "BKE_blender_version.h"
+extern "C" {
+#include "BKE_blender_version.h"
}
#ifdef WIN32
@@ -33,8 +32,8 @@ extern "C"
#include <fstream>
-using Alembic::Abc::Exception;
using Alembic::Abc::ErrorHandler;
+using Alembic::Abc::Exception;
using Alembic::Abc::IArchive;
using Alembic::Abc::kWrapExisting;
using Alembic::Abc::OArchive;
@@ -43,95 +42,94 @@ static IArchive open_archive(const std::string &filename,
const std::vector<std::istream *> &input_streams,
bool &is_hdf5)
{
- is_hdf5 = false;
+ is_hdf5 = false;
- try {
- Alembic::AbcCoreOgawa::ReadArchive archive_reader(input_streams);
+ try {
+ Alembic::AbcCoreOgawa::ReadArchive archive_reader(input_streams);
- return IArchive(archive_reader(filename),
- kWrapExisting,
- ErrorHandler::kThrowPolicy);
- }
- catch (const Exception &e) {
- std::cerr << e.what() << '\n';
+ 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();
- }
+ 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
- /* Inspect the file to see whether it's really a HDF5 file. */
- char header[4]; /* char(0x89) + "HDF" */
- std::ifstream the_file(filename.c_str(), std::ios::in | std::ios::binary);
- if (!the_file) {
- std::cerr << "Unable to open " << filename << std::endl;
- }
- else if (!the_file.read(header, sizeof(header))) {
- std::cerr << "Unable to read from " << filename << std::endl;
- }
- else if (strncmp(header + 1, "HDF", 3)) {
- std::cerr << filename << " has an unknown file format, unable to read." << std::endl;
- }
- else {
- is_hdf5 = true;
- std::cerr << filename << " is in the obsolete HDF5 format, unable to read." << std::endl;
- }
-
- if (the_file.is_open()) {
- the_file.close();
- }
-
- return IArchive();
+ /* Inspect the file to see whether it's really a HDF5 file. */
+ char header[4]; /* char(0x89) + "HDF" */
+ std::ifstream the_file(filename.c_str(), std::ios::in | std::ios::binary);
+ if (!the_file) {
+ std::cerr << "Unable to open " << filename << std::endl;
+ }
+ else if (!the_file.read(header, sizeof(header))) {
+ std::cerr << "Unable to read from " << filename << std::endl;
+ }
+ else if (strncmp(header + 1, "HDF", 3)) {
+ std::cerr << filename << " has an unknown file format, unable to read." << std::endl;
+ }
+ else {
+ is_hdf5 = true;
+ std::cerr << filename << " is in the obsolete HDF5 format, unable to read." << std::endl;
+ }
+
+ if (the_file.is_open()) {
+ the_file.close();
+ }
+
+ return IArchive();
#endif
- }
+ }
- return IArchive();
+ 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);
+ 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);
+ m_infile.open(filename, std::ios::in | std::ios::binary);
#endif
- m_streams.push_back(&m_infile);
+ m_streams.push_back(&m_infile);
- m_archive = open_archive(filename, m_streams, m_is_hdf5);
+ m_archive = open_archive(filename, m_streams, m_is_hdf5);
- /* We can't open an HDF5 file from a stream, so close it. */
- if (m_is_hdf5) {
- m_infile.close();
- m_streams.clear();
- }
+ /* We can't open an HDF5 file from a stream, so close it. */
+ if (m_is_hdf5) {
+ m_infile.close();
+ m_streams.clear();
+ }
}
bool ArchiveReader::is_hdf5() const
{
- return m_is_hdf5;
+ return m_is_hdf5;
}
bool ArchiveReader::valid() const
{
- return m_archive.valid();
+ return m_archive.valid();
}
Alembic::Abc::IObject ArchiveReader::getTop()
{
- return m_archive.getTop();
+ return m_archive.getTop();
}
/* ************************************************************************** */
@@ -144,64 +142,63 @@ static OArchive create_archive(std::ostream *ostream,
Alembic::Abc::MetaData &md,
bool ogawa)
{
- md.set(Alembic::Abc::kApplicationNameKey, "Blender");
- md.set(Alembic::Abc::kUserDescriptionKey, scene_name);
- md.set("blender_version", versionstr);
+ md.set(Alembic::Abc::kApplicationNameKey, "Blender");
+ md.set(Alembic::Abc::kUserDescriptionKey, scene_name);
+ md.set("blender_version", versionstr);
- time_t raw_time;
- time(&raw_time);
- char buffer[128];
+ time_t raw_time;
+ time(&raw_time);
+ char buffer[128];
#if defined _WIN32 || defined _WIN64
- ctime_s(buffer, 128, &raw_time);
+ ctime_s(buffer, 128, &raw_time);
#else
- ctime_r(&raw_time, buffer);
+ 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';
- }
+ 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);
+ md.set(Alembic::Abc::kDateWrittenKey, buffer);
- ErrorHandler::Policy policy = ErrorHandler::kThrowPolicy;
+ ErrorHandler::Policy policy = ErrorHandler::kThrowPolicy;
#ifdef WITH_ALEMBIC_HDF5
- if (!ogawa) {
- return OArchive(Alembic::AbcCoreHDF5::WriteArchive(), filename, md, policy);
- }
+ if (!ogawa) {
+ return OArchive(Alembic::AbcCoreHDF5::WriteArchive(), filename, md, policy);
+ }
#else
- static_cast<void>(filename);
- static_cast<void>(ogawa);
+ static_cast<void>(filename);
+ static_cast<void>(ogawa);
#endif
- Alembic::AbcCoreOgawa::WriteArchive archive_writer;
- return OArchive(archive_writer(ostream, md), kWrapExisting, policy);
+ 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)
+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) {
+ /* 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);
+ 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);
+ m_outfile.open(filename, std::ios::out | std::ios::binary);
#endif
- }
+ }
- m_archive = create_archive(&m_outfile,
- filename,
- scene,
- md,
- do_ogawa);
+ m_archive = create_archive(&m_outfile, filename, scene, md, do_ogawa);
}
OArchive &ArchiveWriter::archive()
{
- return m_archive;
+ return m_archive;
}
diff --git a/source/blender/alembic/intern/abc_archive.h b/source/blender/alembic/intern/abc_archive.h
index ced55f56eac..343a8112aa2 100644
--- a/source/blender/alembic/intern/abc_archive.h
+++ b/source/blender/alembic/intern/abc_archive.h
@@ -40,35 +40,38 @@
*/
class ArchiveReader {
- Alembic::Abc::IArchive m_archive;
- std::ifstream m_infile;
- std::vector<std::istream *> m_streams;
- bool m_is_hdf5;
+ Alembic::Abc::IArchive m_archive;
+ std::ifstream m_infile;
+ std::vector<std::istream *> m_streams;
+ bool m_is_hdf5;
-public:
- explicit ArchiveReader(const char *filename);
+ public:
+ explicit ArchiveReader(const char *filename);
- bool valid() const;
+ bool valid() const;
- /**
- * Returns true when either Blender is compiled with HDF5 support and
- * the archive was successfully opened (valid() will also return true),
- * or when Blender was built without HDF5 support but a HDF5 file was
- * detected (valid() will return false).
- */
- bool is_hdf5() const;
+ /**
+ * Returns true when either Blender is compiled with HDF5 support and
+ * the archive was successfully opened (valid() will also return true),
+ * or when Blender was built without HDF5 support but a HDF5 file was
+ * detected (valid() will return false).
+ */
+ bool is_hdf5() const;
- Alembic::Abc::IObject getTop();
+ Alembic::Abc::IObject getTop();
};
class ArchiveWriter {
- std::ofstream m_outfile;
- Alembic::Abc::OArchive m_archive;
+ 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);
+ public:
+ explicit ArchiveWriter(const char *filename,
+ const char *scene,
+ bool do_ogawa,
+ Alembic::Abc::MetaData &md);
- Alembic::Abc::OArchive &archive();
+ Alembic::Abc::OArchive &archive();
};
#endif /* __ABC_ARCHIVE_H__ */
diff --git a/source/blender/alembic/intern/abc_camera.cc b/source/blender/alembic/intern/abc_camera.cc
index 572e825299b..b15608703de 100644
--- a/source/blender/alembic/intern/abc_camera.cc
+++ b/source/blender/alembic/intern/abc_camera.cc
@@ -53,49 +53,49 @@ AbcCameraWriter::AbcCameraWriter(Object *ob,
ExportSettings &settings)
: AbcObjectWriter(ob, time_sampling, settings, parent)
{
- OCamera camera(parent->alembicXform(), m_name, m_time_sampling);
- m_camera_schema = camera.getSchema();
+ OCamera camera(parent->alembicXform(), m_name, m_time_sampling);
+ m_camera_schema = camera.getSchema();
- m_custom_data_container = m_camera_schema.getUserProperties();
- m_stereo_distance = OFloatProperty(m_custom_data_container, "stereoDistance", m_time_sampling);
- m_eye_separation = OFloatProperty(m_custom_data_container, "eyeSeparation", m_time_sampling);
+ m_custom_data_container = m_camera_schema.getUserProperties();
+ m_stereo_distance = OFloatProperty(m_custom_data_container, "stereoDistance", m_time_sampling);
+ m_eye_separation = OFloatProperty(m_custom_data_container, "eyeSeparation", m_time_sampling);
}
void AbcCameraWriter::do_write()
{
- Camera *cam = static_cast<Camera *>(m_object->data);
-
- m_stereo_distance.set(cam->stereo.convergence_distance);
- m_eye_separation.set(cam->stereo.interocular_distance);
-
- const double apperture_x = cam->sensor_x / 10.0;
- const double apperture_y = cam->sensor_y / 10.0;
- const double film_aspect = apperture_x / apperture_y;
-
- m_camera_sample.setFocalLength(cam->lens);
- m_camera_sample.setHorizontalAperture(apperture_x);
- m_camera_sample.setVerticalAperture(apperture_y);
- m_camera_sample.setHorizontalFilmOffset(apperture_x * cam->shiftx);
- m_camera_sample.setVerticalFilmOffset(apperture_y * cam->shifty * film_aspect);
- m_camera_sample.setNearClippingPlane(cam->clip_start);
- m_camera_sample.setFarClippingPlane(cam->clip_end);
-
- if (cam->dof_ob) {
- Imath::V3f v(m_object->loc[0] - cam->dof_ob->loc[0],
- m_object->loc[1] - cam->dof_ob->loc[1],
- m_object->loc[2] - cam->dof_ob->loc[2]);
- m_camera_sample.setFocusDistance(v.length());
- }
- else {
- m_camera_sample.setFocusDistance(cam->gpu_dof.focus_distance);
- }
-
- /* Blender camera does not have an fstop param, so try to find a custom prop
- * instead. */
- m_camera_sample.setFStop(cam->gpu_dof.fstop);
-
- m_camera_sample.setLensSqueezeRatio(1.0);
- m_camera_schema.set(m_camera_sample);
+ Camera *cam = static_cast<Camera *>(m_object->data);
+
+ m_stereo_distance.set(cam->stereo.convergence_distance);
+ m_eye_separation.set(cam->stereo.interocular_distance);
+
+ const double apperture_x = cam->sensor_x / 10.0;
+ const double apperture_y = cam->sensor_y / 10.0;
+ const double film_aspect = apperture_x / apperture_y;
+
+ m_camera_sample.setFocalLength(cam->lens);
+ m_camera_sample.setHorizontalAperture(apperture_x);
+ m_camera_sample.setVerticalAperture(apperture_y);
+ m_camera_sample.setHorizontalFilmOffset(apperture_x * cam->shiftx);
+ m_camera_sample.setVerticalFilmOffset(apperture_y * cam->shifty * film_aspect);
+ m_camera_sample.setNearClippingPlane(cam->clip_start);
+ m_camera_sample.setFarClippingPlane(cam->clip_end);
+
+ if (cam->dof_ob) {
+ Imath::V3f v(m_object->loc[0] - cam->dof_ob->loc[0],
+ m_object->loc[1] - cam->dof_ob->loc[1],
+ m_object->loc[2] - cam->dof_ob->loc[2]);
+ m_camera_sample.setFocusDistance(v.length());
+ }
+ else {
+ m_camera_sample.setFocusDistance(cam->gpu_dof.focus_distance);
+ }
+
+ /* Blender camera does not have an fstop param, so try to find a custom prop
+ * instead. */
+ m_camera_sample.setFStop(cam->gpu_dof.fstop);
+
+ m_camera_sample.setLensSqueezeRatio(1.0);
+ m_camera_schema.set(m_camera_sample);
}
/* ************************************************************************** */
@@ -103,71 +103,72 @@ void AbcCameraWriter::do_write()
AbcCameraReader::AbcCameraReader(const Alembic::Abc::IObject &object, ImportSettings &settings)
: AbcObjectReader(object, settings)
{
- ICamera abc_cam(m_iobject, kWrapExisting);
- m_schema = abc_cam.getSchema();
+ ICamera abc_cam(m_iobject, kWrapExisting);
+ m_schema = abc_cam.getSchema();
- get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
+ get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
}
bool AbcCameraReader::valid() const
{
- return m_schema.valid();
+ return m_schema.valid();
}
-bool AbcCameraReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const
+bool AbcCameraReader::accepts_object_type(
+ const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
{
- if (!Alembic::AbcGeom::ICamera::matches(alembic_header)) {
- *err_str = "Object type mismatch, Alembic object path pointed to Camera when importing, but not any more.";
- return false;
- }
-
- if (ob->type != OB_CAMERA) {
- *err_str = "Object type mismatch, Alembic object path points to Camera.";
- return false;
- }
-
- return true;
+ if (!Alembic::AbcGeom::ICamera::matches(alembic_header)) {
+ *err_str =
+ "Object type mismatch, Alembic object path pointed to Camera when importing, but not any "
+ "more.";
+ return false;
+ }
+
+ if (ob->type != OB_CAMERA) {
+ *err_str = "Object type mismatch, Alembic object path points to Camera.";
+ return false;
+ }
+
+ return true;
}
void AbcCameraReader::readObjectData(Main *bmain, const ISampleSelector &sample_sel)
{
- Camera *bcam = static_cast<Camera *>(BKE_camera_add(bmain, m_data_name.c_str()));
-
- CameraSample cam_sample;
- m_schema.get(cam_sample, sample_sel);
-
- ICompoundProperty customDataContainer = m_schema.getUserProperties();
-
- if (customDataContainer.valid() &&
- customDataContainer.getPropertyHeader("stereoDistance") &&
- customDataContainer.getPropertyHeader("eyeSeparation"))
- {
- IFloatProperty convergence_plane(customDataContainer, "stereoDistance");
- IFloatProperty eye_separation(customDataContainer, "eyeSeparation");
-
- bcam->stereo.interocular_distance = eye_separation.getValue(sample_sel);
- bcam->stereo.convergence_distance = convergence_plane.getValue(sample_sel);
- }
-
- const float lens = static_cast<float>(cam_sample.getFocalLength());
- const float apperture_x = static_cast<float>(cam_sample.getHorizontalAperture());
- const float apperture_y = static_cast<float>(cam_sample.getVerticalAperture());
- const float h_film_offset = static_cast<float>(cam_sample.getHorizontalFilmOffset());
- const float v_film_offset = static_cast<float>(cam_sample.getVerticalFilmOffset());
- const float film_aspect = apperture_x / apperture_y;
-
- bcam->lens = lens;
- bcam->sensor_x = apperture_x * 10;
- bcam->sensor_y = apperture_y * 10;
- bcam->shiftx = h_film_offset / apperture_x;
- bcam->shifty = v_film_offset / apperture_y / film_aspect;
- bcam->clip_start = max_ff(0.1f, static_cast<float>(cam_sample.getNearClippingPlane()));
- bcam->clip_end = static_cast<float>(cam_sample.getFarClippingPlane());
- bcam->gpu_dof.focus_distance = static_cast<float>(cam_sample.getFocusDistance());
- bcam->gpu_dof.fstop = static_cast<float>(cam_sample.getFStop());
-
- m_object = BKE_object_add_only_object(bmain, OB_CAMERA, m_object_name.c_str());
- m_object->data = bcam;
+ Camera *bcam = static_cast<Camera *>(BKE_camera_add(bmain, m_data_name.c_str()));
+
+ CameraSample cam_sample;
+ m_schema.get(cam_sample, sample_sel);
+
+ ICompoundProperty customDataContainer = m_schema.getUserProperties();
+
+ if (customDataContainer.valid() && customDataContainer.getPropertyHeader("stereoDistance") &&
+ customDataContainer.getPropertyHeader("eyeSeparation")) {
+ IFloatProperty convergence_plane(customDataContainer, "stereoDistance");
+ IFloatProperty eye_separation(customDataContainer, "eyeSeparation");
+
+ bcam->stereo.interocular_distance = eye_separation.getValue(sample_sel);
+ bcam->stereo.convergence_distance = convergence_plane.getValue(sample_sel);
+ }
+
+ const float lens = static_cast<float>(cam_sample.getFocalLength());
+ const float apperture_x = static_cast<float>(cam_sample.getHorizontalAperture());
+ const float apperture_y = static_cast<float>(cam_sample.getVerticalAperture());
+ const float h_film_offset = static_cast<float>(cam_sample.getHorizontalFilmOffset());
+ const float v_film_offset = static_cast<float>(cam_sample.getVerticalFilmOffset());
+ const float film_aspect = apperture_x / apperture_y;
+
+ bcam->lens = lens;
+ bcam->sensor_x = apperture_x * 10;
+ bcam->sensor_y = apperture_y * 10;
+ bcam->shiftx = h_film_offset / apperture_x;
+ bcam->shifty = v_film_offset / apperture_y / film_aspect;
+ bcam->clip_start = max_ff(0.1f, static_cast<float>(cam_sample.getNearClippingPlane()));
+ bcam->clip_end = static_cast<float>(cam_sample.getFarClippingPlane());
+ bcam->gpu_dof.focus_distance = static_cast<float>(cam_sample.getFocusDistance());
+ bcam->gpu_dof.fstop = static_cast<float>(cam_sample.getFStop());
+
+ m_object = BKE_object_add_only_object(bmain, OB_CAMERA, m_object_name.c_str());
+ m_object->data = bcam;
}
diff --git a/source/blender/alembic/intern/abc_camera.h b/source/blender/alembic/intern/abc_camera.h
index a5cd8373dc0..28169cb7d85 100644
--- a/source/blender/alembic/intern/abc_camera.h
+++ b/source/blender/alembic/intern/abc_camera.h
@@ -26,36 +26,36 @@
/* ************************************************************************** */
class AbcCameraWriter : public AbcObjectWriter {
- Alembic::AbcGeom::OCameraSchema m_camera_schema;
- Alembic::AbcGeom::CameraSample m_camera_sample;
- Alembic::AbcGeom::OCompoundProperty m_custom_data_container;
- Alembic::AbcGeom::OFloatProperty m_stereo_distance;
- Alembic::AbcGeom::OFloatProperty m_eye_separation;
-
-public:
- AbcCameraWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings);
-
-private:
- virtual void do_write();
+ Alembic::AbcGeom::OCameraSchema m_camera_schema;
+ Alembic::AbcGeom::CameraSample m_camera_sample;
+ Alembic::AbcGeom::OCompoundProperty m_custom_data_container;
+ Alembic::AbcGeom::OFloatProperty m_stereo_distance;
+ Alembic::AbcGeom::OFloatProperty m_eye_separation;
+
+ public:
+ AbcCameraWriter(Object *ob,
+ AbcTransformWriter *parent,
+ uint32_t time_sampling,
+ ExportSettings &settings);
+
+ private:
+ virtual void do_write();
};
/* ************************************************************************** */
class AbcCameraReader : public AbcObjectReader {
- Alembic::AbcGeom::ICameraSchema m_schema;
+ Alembic::AbcGeom::ICameraSchema m_schema;
-public:
- AbcCameraReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
+ public:
+ AbcCameraReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
- bool valid() const;
- bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const;
+ bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
};
-#endif /* __ABC_CAMERA_H__ */
+#endif /* __ABC_CAMERA_H__ */
diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc
index c78f31b671f..13872618d74 100644
--- a/source/blender/alembic/intern/abc_curves.cc
+++ b/source/blender/alembic/intern/abc_curves.cc
@@ -43,13 +43,14 @@ extern "C" {
#include "ED_curve.h"
}
+using Alembic::Abc::FloatArraySamplePtr;
using Alembic::Abc::IInt32ArrayProperty;
using Alembic::Abc::Int32ArraySamplePtr;
-using Alembic::Abc::FloatArraySamplePtr;
using Alembic::Abc::P3fArraySamplePtr;
-using Alembic::Abc::UcharArraySamplePtr;
using Alembic::Abc::PropertyHeader;
+using Alembic::Abc::UcharArraySamplePtr;
+using Alembic::AbcGeom::CurvePeriodicity;
using Alembic::AbcGeom::ICompoundProperty;
using Alembic::AbcGeom::ICurves;
using Alembic::AbcGeom::ICurvesSchema;
@@ -57,7 +58,6 @@ using Alembic::AbcGeom::IFloatGeomParam;
using Alembic::AbcGeom::IInt16Property;
using Alembic::AbcGeom::ISampleSelector;
using Alembic::AbcGeom::kWrapExisting;
-using Alembic::AbcGeom::CurvePeriodicity;
using Alembic::AbcGeom::OCompoundProperty;
using Alembic::AbcGeom::OCurves;
@@ -76,358 +76,366 @@ AbcCurveWriter::AbcCurveWriter(Object *ob,
ExportSettings &settings)
: AbcObjectWriter(ob, time_sampling, settings, parent)
{
- OCurves curves(parent->alembicXform(), m_name, m_time_sampling);
- m_schema = curves.getSchema();
+ OCurves curves(parent->alembicXform(), m_name, m_time_sampling);
+ m_schema = curves.getSchema();
- Curve *cu = static_cast<Curve *>(m_object->data);
- OCompoundProperty user_props = m_schema.getUserProperties();
- OInt16Property user_prop_resolu(user_props, ABC_CURVE_RESOLUTION_U_PROPNAME);
- user_prop_resolu.set(cu->resolu);
+ Curve *cu = static_cast<Curve *>(m_object->data);
+ OCompoundProperty user_props = m_schema.getUserProperties();
+ OInt16Property user_prop_resolu(user_props, ABC_CURVE_RESOLUTION_U_PROPNAME);
+ user_prop_resolu.set(cu->resolu);
}
void AbcCurveWriter::do_write()
{
- Curve *curve = static_cast<Curve *>(m_object->data);
-
- std::vector<Imath::V3f> verts;
- std::vector<int32_t> vert_counts;
- std::vector<float> widths;
- std::vector<float> weights;
- std::vector<float> knots;
- std::vector<uint8_t> orders;
- Imath::V3f temp_vert;
-
- Alembic::AbcGeom::BasisType curve_basis;
- Alembic::AbcGeom::CurveType curve_type;
- Alembic::AbcGeom::CurvePeriodicity periodicity;
-
- Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
- for (; nurbs; nurbs = nurbs->next) {
- if (nurbs->bp) {
- curve_basis = Alembic::AbcGeom::kNoBasis;
- curve_type = Alembic::AbcGeom::kVariableOrder;
-
- const int totpoint = nurbs->pntsu * nurbs->pntsv;
-
- const BPoint *point = nurbs->bp;
-
- for (int i = 0; i < totpoint; ++i, ++point) {
- copy_yup_from_zup(temp_vert.getValue(), point->vec);
- verts.push_back(temp_vert);
- weights.push_back(point->vec[3]);
- widths.push_back(point->radius);
- }
- }
- else if (nurbs->bezt) {
- curve_basis = Alembic::AbcGeom::kBezierBasis;
- curve_type = Alembic::AbcGeom::kCubic;
-
- const int totpoint = nurbs->pntsu;
-
- const BezTriple *bezier = nurbs->bezt;
-
- /* TODO(kevin): store info about handles, Alembic doesn't have this. */
- for (int i = 0; i < totpoint; ++i, ++bezier) {
- copy_yup_from_zup(temp_vert.getValue(), bezier->vec[1]);
- verts.push_back(temp_vert);
- widths.push_back(bezier->radius);
- }
- }
-
- if ((nurbs->flagu & CU_NURB_ENDPOINT) != 0) {
- periodicity = Alembic::AbcGeom::kNonPeriodic;
- }
- else if ((nurbs->flagu & CU_NURB_CYCLIC) != 0) {
- periodicity = Alembic::AbcGeom::kPeriodic;
-
- /* Duplicate the start points to indicate that the curve is actually
- * cyclic since other software need those.
- */
-
- for (int i = 0; i < nurbs->orderu; ++i) {
- verts.push_back(verts[i]);
- }
- }
-
- if (nurbs->knotsu != NULL) {
- const size_t num_knots = KNOTSU(nurbs);
-
- /* Add an extra knot at the beginning and end of the array since most apps
- * require/expect them. */
- knots.resize(num_knots + 2);
-
- for (int i = 0; i < num_knots; ++i) {
- knots[i + 1] = nurbs->knotsu[i];
- }
-
- if ((nurbs->flagu & CU_NURB_CYCLIC) != 0) {
- knots[0] = nurbs->knotsu[0];
- knots[num_knots - 1] = nurbs->knotsu[num_knots - 1];
- }
- else {
- knots[0] = (2.0f * nurbs->knotsu[0] - nurbs->knotsu[1]);
- knots[num_knots - 1] = (2.0f * nurbs->knotsu[num_knots - 1] - nurbs->knotsu[num_knots - 2]);
- }
- }
-
- orders.push_back(nurbs->orderu);
- vert_counts.push_back(verts.size());
- }
-
- Alembic::AbcGeom::OFloatGeomParam::Sample width_sample;
- width_sample.setVals(widths);
-
- m_sample = OCurvesSchema::Sample(verts,
- vert_counts,
- curve_type,
- periodicity,
- width_sample,
- OV2fGeomParam::Sample(), /* UVs */
- ON3fGeomParam::Sample(), /* normals */
- curve_basis,
- weights,
- orders,
- knots);
-
- m_sample.setSelfBounds(bounds());
- m_schema.set(m_sample);
+ Curve *curve = static_cast<Curve *>(m_object->data);
+
+ std::vector<Imath::V3f> verts;
+ std::vector<int32_t> vert_counts;
+ std::vector<float> widths;
+ std::vector<float> weights;
+ std::vector<float> knots;
+ std::vector<uint8_t> orders;
+ Imath::V3f temp_vert;
+
+ Alembic::AbcGeom::BasisType curve_basis;
+ Alembic::AbcGeom::CurveType curve_type;
+ Alembic::AbcGeom::CurvePeriodicity periodicity;
+
+ Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
+ for (; nurbs; nurbs = nurbs->next) {
+ if (nurbs->bp) {
+ curve_basis = Alembic::AbcGeom::kNoBasis;
+ curve_type = Alembic::AbcGeom::kVariableOrder;
+
+ const int totpoint = nurbs->pntsu * nurbs->pntsv;
+
+ const BPoint *point = nurbs->bp;
+
+ for (int i = 0; i < totpoint; ++i, ++point) {
+ copy_yup_from_zup(temp_vert.getValue(), point->vec);
+ verts.push_back(temp_vert);
+ weights.push_back(point->vec[3]);
+ widths.push_back(point->radius);
+ }
+ }
+ else if (nurbs->bezt) {
+ curve_basis = Alembic::AbcGeom::kBezierBasis;
+ curve_type = Alembic::AbcGeom::kCubic;
+
+ const int totpoint = nurbs->pntsu;
+
+ const BezTriple *bezier = nurbs->bezt;
+
+ /* TODO(kevin): store info about handles, Alembic doesn't have this. */
+ for (int i = 0; i < totpoint; ++i, ++bezier) {
+ copy_yup_from_zup(temp_vert.getValue(), bezier->vec[1]);
+ verts.push_back(temp_vert);
+ widths.push_back(bezier->radius);
+ }
+ }
+
+ if ((nurbs->flagu & CU_NURB_ENDPOINT) != 0) {
+ periodicity = Alembic::AbcGeom::kNonPeriodic;
+ }
+ else if ((nurbs->flagu & CU_NURB_CYCLIC) != 0) {
+ periodicity = Alembic::AbcGeom::kPeriodic;
+
+ /* Duplicate the start points to indicate that the curve is actually
+ * cyclic since other software need those.
+ */
+
+ for (int i = 0; i < nurbs->orderu; ++i) {
+ verts.push_back(verts[i]);
+ }
+ }
+
+ if (nurbs->knotsu != NULL) {
+ const size_t num_knots = KNOTSU(nurbs);
+
+ /* Add an extra knot at the beginning and end of the array since most apps
+ * require/expect them. */
+ knots.resize(num_knots + 2);
+
+ for (int i = 0; i < num_knots; ++i) {
+ knots[i + 1] = nurbs->knotsu[i];
+ }
+
+ if ((nurbs->flagu & CU_NURB_CYCLIC) != 0) {
+ knots[0] = nurbs->knotsu[0];
+ knots[num_knots - 1] = nurbs->knotsu[num_knots - 1];
+ }
+ else {
+ knots[0] = (2.0f * nurbs->knotsu[0] - nurbs->knotsu[1]);
+ knots[num_knots - 1] = (2.0f * nurbs->knotsu[num_knots - 1] -
+ nurbs->knotsu[num_knots - 2]);
+ }
+ }
+
+ orders.push_back(nurbs->orderu);
+ vert_counts.push_back(verts.size());
+ }
+
+ Alembic::AbcGeom::OFloatGeomParam::Sample width_sample;
+ width_sample.setVals(widths);
+
+ m_sample = OCurvesSchema::Sample(verts,
+ vert_counts,
+ curve_type,
+ periodicity,
+ width_sample,
+ OV2fGeomParam::Sample(), /* UVs */
+ ON3fGeomParam::Sample(), /* normals */
+ curve_basis,
+ weights,
+ orders,
+ knots);
+
+ m_sample.setSelfBounds(bounds());
+ m_schema.set(m_sample);
}
-
AbcCurveMeshWriter::AbcCurveMeshWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings)
: AbcGenericMeshWriter(ob, parent, time_sampling, settings)
-{}
-
-Mesh *AbcCurveMeshWriter::getEvaluatedMesh(Scene * /*scene_eval*/, Object *ob_eval, bool &r_needsfree)
{
- if (ob_eval->runtime.mesh_eval != NULL) {
- /* Mesh_eval only exists when generative modifiers are in use. */
- r_needsfree = false;
- return ob_eval->runtime.mesh_eval;
- }
-
- r_needsfree = true;
- return BKE_mesh_new_nomain_from_curve(ob_eval);
}
+Mesh *AbcCurveMeshWriter::getEvaluatedMesh(Scene * /*scene_eval*/,
+ Object *ob_eval,
+ bool &r_needsfree)
+{
+ if (ob_eval->runtime.mesh_eval != NULL) {
+ /* Mesh_eval only exists when generative modifiers are in use. */
+ r_needsfree = false;
+ return ob_eval->runtime.mesh_eval;
+ }
+
+ r_needsfree = true;
+ return BKE_mesh_new_nomain_from_curve(ob_eval);
+}
/* ************************************************************************** */
AbcCurveReader::AbcCurveReader(const Alembic::Abc::IObject &object, ImportSettings &settings)
: AbcObjectReader(object, settings)
{
- ICurves abc_curves(object, kWrapExisting);
- m_curves_schema = abc_curves.getSchema();
+ ICurves abc_curves(object, kWrapExisting);
+ m_curves_schema = abc_curves.getSchema();
- get_min_max_time(m_iobject, m_curves_schema, m_min_time, m_max_time);
+ get_min_max_time(m_iobject, m_curves_schema, m_min_time, m_max_time);
}
bool AbcCurveReader::valid() const
{
- return m_curves_schema.valid();
+ return m_curves_schema.valid();
}
-bool AbcCurveReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const
+bool AbcCurveReader::accepts_object_type(
+ const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
{
- if (!Alembic::AbcGeom::ICurves::matches(alembic_header)) {
- *err_str = "Object type mismatch, Alembic object path pointed to Curves when importing, but not any more.";
- return false;
- }
-
- if (ob->type != OB_CURVE) {
- *err_str = "Object type mismatch, Alembic object path points to Curves.";
- return false;
- }
-
- return true;
+ if (!Alembic::AbcGeom::ICurves::matches(alembic_header)) {
+ *err_str =
+ "Object type mismatch, Alembic object path pointed to Curves when importing, but not any "
+ "more.";
+ return false;
+ }
+
+ if (ob->type != OB_CURVE) {
+ *err_str = "Object type mismatch, Alembic object path points to Curves.";
+ return false;
+ }
+
+ return true;
}
void AbcCurveReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
- Curve *cu = BKE_curve_add(bmain, m_data_name.c_str(), OB_CURVE);
+ Curve *cu = BKE_curve_add(bmain, m_data_name.c_str(), OB_CURVE);
- cu->flag |= CU_DEFORM_FILL | CU_3D;
- cu->actvert = CU_ACT_NONE;
- cu->resolu = 1;
+ cu->flag |= CU_DEFORM_FILL | CU_3D;
+ cu->actvert = CU_ACT_NONE;
+ cu->resolu = 1;
- ICompoundProperty user_props = m_curves_schema.getUserProperties();
- if (user_props) {
- const PropertyHeader *header = user_props.getPropertyHeader(ABC_CURVE_RESOLUTION_U_PROPNAME);
- if (header != NULL && header->isScalar() && IInt16Property::matches(*header)) {
- IInt16Property resolu(user_props, header->getName());
- cu->resolu = resolu.getValue(sample_sel);
- }
- }
+ ICompoundProperty user_props = m_curves_schema.getUserProperties();
+ if (user_props) {
+ const PropertyHeader *header = user_props.getPropertyHeader(ABC_CURVE_RESOLUTION_U_PROPNAME);
+ if (header != NULL && header->isScalar() && IInt16Property::matches(*header)) {
+ IInt16Property resolu(user_props, header->getName());
+ cu->resolu = resolu.getValue(sample_sel);
+ }
+ }
- m_object = BKE_object_add_only_object(bmain, OB_CURVE, m_object_name.c_str());
- m_object->data = cu;
+ m_object = BKE_object_add_only_object(bmain, OB_CURVE, m_object_name.c_str());
+ m_object->data = cu;
- read_curve_sample(cu, m_curves_schema, sample_sel);
+ read_curve_sample(cu, m_curves_schema, sample_sel);
- if (has_animations(m_curves_schema, m_settings)) {
- addCacheModifier();
- }
+ if (has_animations(m_curves_schema, m_settings)) {
+ addCacheModifier();
+ }
}
/* ************************************************************************** */
-void AbcCurveReader::read_curve_sample(Curve *cu, const ICurvesSchema &schema, const ISampleSelector &sample_sel)
+void AbcCurveReader::read_curve_sample(Curve *cu,
+ const ICurvesSchema &schema,
+ const ISampleSelector &sample_sel)
{
- ICurvesSchema::Sample smp;
- try {
- smp = schema.getValue(sample_sel);
- }
- catch(Alembic::Util::Exception &ex) {
- printf("Alembic: error reading curve sample for '%s/%s' at time %f: %s\n",
- m_iobject.getFullName().c_str(),
- schema.getName().c_str(),
- sample_sel.getRequestedTime(),
- ex.what());
- return;
- }
-
- const Int32ArraySamplePtr num_vertices = smp.getCurvesNumVertices();
- const P3fArraySamplePtr positions = smp.getPositions();
- const FloatArraySamplePtr weights = smp.getPositionWeights();
- const FloatArraySamplePtr knots = smp.getKnots();
- const CurvePeriodicity periodicity = smp.getWrap();
- const UcharArraySamplePtr orders = smp.getOrders();
-
- const IFloatGeomParam widths_param = schema.getWidthsParam();
- FloatArraySamplePtr radiuses;
-
- if (widths_param.valid()) {
- IFloatGeomParam::Sample wsample = widths_param.getExpandedValue(sample_sel);
- radiuses = wsample.getVals();
- }
-
- int knot_offset = 0;
-
- size_t idx = 0;
- for (size_t i = 0; i < num_vertices->size(); ++i) {
- const int num_verts = (*num_vertices)[i];
-
- Nurb *nu = static_cast<Nurb *>(MEM_callocN(sizeof(Nurb), "abc_getnurb"));
- nu->resolu = cu->resolu;
- nu->resolv = cu->resolv;
- nu->pntsu = num_verts;
- nu->pntsv = 1;
- nu->flag |= CU_SMOOTH;
-
- switch (smp.getType()) {
- case Alembic::AbcGeom::kCubic:
- nu->orderu = 4;
- break;
- case Alembic::AbcGeom::kVariableOrder:
- if (orders && orders->size() > i) {
- nu->orderu = static_cast<short>((*orders)[i]);
- break;
- }
- ATTR_FALLTHROUGH;
- case Alembic::AbcGeom::kLinear:
- default:
- nu->orderu = 2;
- }
-
- if (periodicity == Alembic::AbcGeom::kNonPeriodic) {
- nu->flagu |= CU_NURB_ENDPOINT;
- }
- else if (periodicity == Alembic::AbcGeom::kPeriodic) {
- nu->flagu |= CU_NURB_CYCLIC;
-
- /* Check the number of points which overlap, we don't have
- * overlapping points in Blender, but other software do use them to
- * indicate that a curve is actually cyclic. Usually the number of
- * overlapping points is equal to the order/degree of the curve.
- */
-
- const int start = idx;
- const int end = idx + num_verts;
- int overlap = 0;
-
- for (int j = start, k = end - nu->orderu; j < nu->orderu; ++j, ++k) {
- const Imath::V3f &p1 = (*positions)[j];
- const Imath::V3f &p2 = (*positions)[k];
-
- if (p1 != p2) {
- break;
- }
-
- ++overlap;
- }
-
- /* TODO: Special case, need to figure out how it coincides with knots. */
- if (overlap == 0 && num_verts > 2 && (*positions)[start] == (*positions)[end - 1]) {
- overlap = 1;
- }
-
- /* There is no real cycles. */
- if (overlap == 0) {
- nu->flagu &= ~CU_NURB_CYCLIC;
- nu->flagu |= CU_NURB_ENDPOINT;
- }
-
- nu->pntsu -= overlap;
- }
-
- const bool do_weights = (weights != NULL) && (weights->size() > 1);
- float weight = 1.0f;
-
- const bool do_radius = (radiuses != NULL) && (radiuses->size() > 1);
- float radius = (radiuses && radiuses->size() == 1) ? (*radiuses)[0] : 1.0f;
-
- nu->type = CU_NURBS;
-
- nu->bp = static_cast<BPoint *>(MEM_callocN(sizeof(BPoint) * nu->pntsu, "abc_getnurb"));
- BPoint *bp = nu->bp;
-
- for (int j = 0; j < nu->pntsu; ++j, ++bp, ++idx) {
- const Imath::V3f &pos = (*positions)[idx];
-
- if (do_radius) {
- radius = (*radiuses)[idx];
- }
-
- if (do_weights) {
- weight = (*weights)[idx];
- }
-
- copy_zup_from_yup(bp->vec, pos.getValue());
- bp->vec[3] = weight;
- bp->f1 = SELECT;
- bp->radius = radius;
- bp->weight = 1.0f;
- }
-
- if (knots && knots->size() != 0) {
- nu->knotsu = static_cast<float *>(MEM_callocN(KNOTSU(nu) * sizeof(float), "abc_setsplineknotsu"));
-
- /* TODO: second check is temporary, for until the check for cycles is rock solid. */
- if (periodicity == Alembic::AbcGeom::kPeriodic && (KNOTSU(nu) == knots->size() - 2)) {
- /* Skip first and last knots. */
- for (size_t i = 1; i < knots->size() - 1; ++i) {
- nu->knotsu[i - 1] = (*knots)[knot_offset + i];
- }
- }
- else {
- /* TODO: figure out how to use the knots array from other
- * software in this case. */
- BKE_nurb_knot_calc_u(nu);
- }
-
- knot_offset += knots->size();
- }
- else {
- BKE_nurb_knot_calc_u(nu);
- }
-
- BLI_addtail(BKE_curve_nurbs_get(cu), nu);
- }
+ ICurvesSchema::Sample smp;
+ try {
+ smp = schema.getValue(sample_sel);
+ }
+ catch (Alembic::Util::Exception &ex) {
+ printf("Alembic: error reading curve sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return;
+ }
+
+ const Int32ArraySamplePtr num_vertices = smp.getCurvesNumVertices();
+ const P3fArraySamplePtr positions = smp.getPositions();
+ const FloatArraySamplePtr weights = smp.getPositionWeights();
+ const FloatArraySamplePtr knots = smp.getKnots();
+ const CurvePeriodicity periodicity = smp.getWrap();
+ const UcharArraySamplePtr orders = smp.getOrders();
+
+ const IFloatGeomParam widths_param = schema.getWidthsParam();
+ FloatArraySamplePtr radiuses;
+
+ if (widths_param.valid()) {
+ IFloatGeomParam::Sample wsample = widths_param.getExpandedValue(sample_sel);
+ radiuses = wsample.getVals();
+ }
+
+ int knot_offset = 0;
+
+ size_t idx = 0;
+ for (size_t i = 0; i < num_vertices->size(); ++i) {
+ const int num_verts = (*num_vertices)[i];
+
+ Nurb *nu = static_cast<Nurb *>(MEM_callocN(sizeof(Nurb), "abc_getnurb"));
+ nu->resolu = cu->resolu;
+ nu->resolv = cu->resolv;
+ nu->pntsu = num_verts;
+ nu->pntsv = 1;
+ nu->flag |= CU_SMOOTH;
+
+ switch (smp.getType()) {
+ case Alembic::AbcGeom::kCubic:
+ nu->orderu = 4;
+ break;
+ case Alembic::AbcGeom::kVariableOrder:
+ if (orders && orders->size() > i) {
+ nu->orderu = static_cast<short>((*orders)[i]);
+ break;
+ }
+ ATTR_FALLTHROUGH;
+ case Alembic::AbcGeom::kLinear:
+ default:
+ nu->orderu = 2;
+ }
+
+ if (periodicity == Alembic::AbcGeom::kNonPeriodic) {
+ nu->flagu |= CU_NURB_ENDPOINT;
+ }
+ else if (periodicity == Alembic::AbcGeom::kPeriodic) {
+ nu->flagu |= CU_NURB_CYCLIC;
+
+ /* Check the number of points which overlap, we don't have
+ * overlapping points in Blender, but other software do use them to
+ * indicate that a curve is actually cyclic. Usually the number of
+ * overlapping points is equal to the order/degree of the curve.
+ */
+
+ const int start = idx;
+ const int end = idx + num_verts;
+ int overlap = 0;
+
+ for (int j = start, k = end - nu->orderu; j < nu->orderu; ++j, ++k) {
+ const Imath::V3f &p1 = (*positions)[j];
+ const Imath::V3f &p2 = (*positions)[k];
+
+ if (p1 != p2) {
+ break;
+ }
+
+ ++overlap;
+ }
+
+ /* TODO: Special case, need to figure out how it coincides with knots. */
+ if (overlap == 0 && num_verts > 2 && (*positions)[start] == (*positions)[end - 1]) {
+ overlap = 1;
+ }
+
+ /* There is no real cycles. */
+ if (overlap == 0) {
+ nu->flagu &= ~CU_NURB_CYCLIC;
+ nu->flagu |= CU_NURB_ENDPOINT;
+ }
+
+ nu->pntsu -= overlap;
+ }
+
+ const bool do_weights = (weights != NULL) && (weights->size() > 1);
+ float weight = 1.0f;
+
+ const bool do_radius = (radiuses != NULL) && (radiuses->size() > 1);
+ float radius = (radiuses && radiuses->size() == 1) ? (*radiuses)[0] : 1.0f;
+
+ nu->type = CU_NURBS;
+
+ nu->bp = static_cast<BPoint *>(MEM_callocN(sizeof(BPoint) * nu->pntsu, "abc_getnurb"));
+ BPoint *bp = nu->bp;
+
+ for (int j = 0; j < nu->pntsu; ++j, ++bp, ++idx) {
+ const Imath::V3f &pos = (*positions)[idx];
+
+ if (do_radius) {
+ radius = (*radiuses)[idx];
+ }
+
+ if (do_weights) {
+ weight = (*weights)[idx];
+ }
+
+ copy_zup_from_yup(bp->vec, pos.getValue());
+ bp->vec[3] = weight;
+ bp->f1 = SELECT;
+ bp->radius = radius;
+ bp->weight = 1.0f;
+ }
+
+ if (knots && knots->size() != 0) {
+ nu->knotsu = static_cast<float *>(
+ MEM_callocN(KNOTSU(nu) * sizeof(float), "abc_setsplineknotsu"));
+
+ /* TODO: second check is temporary, for until the check for cycles is rock solid. */
+ if (periodicity == Alembic::AbcGeom::kPeriodic && (KNOTSU(nu) == knots->size() - 2)) {
+ /* Skip first and last knots. */
+ for (size_t i = 1; i < knots->size() - 1; ++i) {
+ nu->knotsu[i - 1] = (*knots)[knot_offset + i];
+ }
+ }
+ else {
+ /* TODO: figure out how to use the knots array from other
+ * software in this case. */
+ BKE_nurb_knot_calc_u(nu);
+ }
+
+ knot_offset += knots->size();
+ }
+ else {
+ BKE_nurb_knot_calc_u(nu);
+ }
+
+ BLI_addtail(BKE_curve_nurbs_get(cu), nu);
+ }
}
/* NOTE: Alembic only stores data about control points, but the Mesh
@@ -441,71 +449,71 @@ Mesh *AbcCurveReader::read_mesh(Mesh *existing_mesh,
int /*read_flag*/,
const char **err_str)
{
- ICurvesSchema::Sample sample;
-
- try {
- sample = m_curves_schema.getValue(sample_sel);
- }
- catch(Alembic::Util::Exception &ex) {
- *err_str = "Error reading curve sample; more detail on the console";
- printf("Alembic: error reading curve sample for '%s/%s' at time %f: %s\n",
- m_iobject.getFullName().c_str(),
- m_curves_schema.getName().c_str(),
- sample_sel.getRequestedTime(),
- ex.what());
- return existing_mesh;
- }
-
- const P3fArraySamplePtr &positions = sample.getPositions();
- const Int32ArraySamplePtr num_vertices = sample.getCurvesNumVertices();
-
- int vertex_idx = 0;
- int curve_idx;
- Curve *curve = static_cast<Curve *>(m_object->data);
-
- const int curve_count = BLI_listbase_count(&curve->nurb);
- bool same_topology = curve_count == num_vertices->size();
-
- if (same_topology) {
- Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
- for (curve_idx = 0; nurbs; nurbs = nurbs->next, ++curve_idx) {
- const int num_in_alembic = (*num_vertices)[curve_idx];
- const int num_in_blender = nurbs->pntsu;
-
- if (num_in_alembic != num_in_blender) {
- same_topology = false;
- break;
- }
- }
- }
-
- if (!same_topology) {
- BKE_nurbList_free(&curve->nurb);
- read_curve_sample(curve, m_curves_schema, sample_sel);
- }
- else {
- Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
- for (curve_idx = 0; nurbs; nurbs = nurbs->next, ++curve_idx) {
- const int totpoint = (*num_vertices)[curve_idx];
-
- if (nurbs->bp) {
- BPoint *point = nurbs->bp;
-
- for (int i = 0; i < totpoint; ++i, ++point, ++vertex_idx) {
- const Imath::V3f &pos = (*positions)[vertex_idx];
- copy_zup_from_yup(point->vec, pos.getValue());
- }
- }
- else if (nurbs->bezt) {
- BezTriple *bezier = nurbs->bezt;
-
- for (int i = 0; i < totpoint; ++i, ++bezier, ++vertex_idx) {
- const Imath::V3f &pos = (*positions)[vertex_idx];
- copy_zup_from_yup(bezier->vec[1], pos.getValue());
- }
- }
- }
- }
-
- return BKE_mesh_new_nomain_from_curve(m_object);
+ ICurvesSchema::Sample sample;
+
+ try {
+ sample = m_curves_schema.getValue(sample_sel);
+ }
+ catch (Alembic::Util::Exception &ex) {
+ *err_str = "Error reading curve sample; more detail on the console";
+ printf("Alembic: error reading curve sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ m_curves_schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return existing_mesh;
+ }
+
+ const P3fArraySamplePtr &positions = sample.getPositions();
+ const Int32ArraySamplePtr num_vertices = sample.getCurvesNumVertices();
+
+ int vertex_idx = 0;
+ int curve_idx;
+ Curve *curve = static_cast<Curve *>(m_object->data);
+
+ const int curve_count = BLI_listbase_count(&curve->nurb);
+ bool same_topology = curve_count == num_vertices->size();
+
+ if (same_topology) {
+ Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
+ for (curve_idx = 0; nurbs; nurbs = nurbs->next, ++curve_idx) {
+ const int num_in_alembic = (*num_vertices)[curve_idx];
+ const int num_in_blender = nurbs->pntsu;
+
+ if (num_in_alembic != num_in_blender) {
+ same_topology = false;
+ break;
+ }
+ }
+ }
+
+ if (!same_topology) {
+ BKE_nurbList_free(&curve->nurb);
+ read_curve_sample(curve, m_curves_schema, sample_sel);
+ }
+ else {
+ Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
+ for (curve_idx = 0; nurbs; nurbs = nurbs->next, ++curve_idx) {
+ const int totpoint = (*num_vertices)[curve_idx];
+
+ if (nurbs->bp) {
+ BPoint *point = nurbs->bp;
+
+ for (int i = 0; i < totpoint; ++i, ++point, ++vertex_idx) {
+ const Imath::V3f &pos = (*positions)[vertex_idx];
+ copy_zup_from_yup(point->vec, pos.getValue());
+ }
+ }
+ else if (nurbs->bezt) {
+ BezTriple *bezier = nurbs->bezt;
+
+ for (int i = 0; i < totpoint; ++i, ++bezier, ++vertex_idx) {
+ const Imath::V3f &pos = (*positions)[vertex_idx];
+ copy_zup_from_yup(bezier->vec[1], pos.getValue());
+ }
+ }
+ }
+ }
+
+ return BKE_mesh_new_nomain_from_curve(m_object);
}
diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h
index e03feceed64..6636558356f 100644
--- a/source/blender/alembic/intern/abc_curves.h
+++ b/source/blender/alembic/intern/abc_curves.h
@@ -32,55 +32,54 @@ struct Curve;
/* ************************************************************************** */
class AbcCurveWriter : public AbcObjectWriter {
- Alembic::AbcGeom::OCurvesSchema m_schema;
- Alembic::AbcGeom::OCurvesSchema::Sample m_sample;
+ Alembic::AbcGeom::OCurvesSchema m_schema;
+ Alembic::AbcGeom::OCurvesSchema::Sample m_sample;
-public:
- AbcCurveWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings);
+ public:
+ AbcCurveWriter(Object *ob,
+ AbcTransformWriter *parent,
+ uint32_t time_sampling,
+ ExportSettings &settings);
-protected:
- void do_write();
+ protected:
+ void do_write();
};
class AbcCurveMeshWriter : public AbcGenericMeshWriter {
-public:
- AbcCurveMeshWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings);
-
-protected:
- Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree);
+ public:
+ AbcCurveMeshWriter(Object *ob,
+ AbcTransformWriter *parent,
+ uint32_t time_sampling,
+ ExportSettings &settings);
+
+ protected:
+ Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree);
};
/* ************************************************************************** */
class AbcCurveReader : public AbcObjectReader {
- Alembic::AbcGeom::ICurvesSchema m_curves_schema;
+ Alembic::AbcGeom::ICurvesSchema m_curves_schema;
-public:
- AbcCurveReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
+ public:
+ AbcCurveReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
- bool valid() const;
- bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const;
+ bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
- struct Mesh *read_mesh(struct Mesh *existing_mesh,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
-
- void read_curve_sample(Curve *cu,
- const Alembic::AbcGeom::ICurvesSchema &schema,
- const Alembic::Abc::ISampleSelector &sample_selector);
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
+ struct Mesh *read_mesh(struct Mesh *existing_mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
+ void read_curve_sample(Curve *cu,
+ const Alembic::AbcGeom::ICurvesSchema &schema,
+ const Alembic::Abc::ISampleSelector &sample_selector);
};
/* ************************************************************************** */
-#endif /* __ABC_CURVES_H__ */
+#endif /* __ABC_CURVES_H__ */
diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc
index 1587f333e3d..20ca659d32f 100644
--- a/source/blender/alembic/intern/abc_customdata.cc
+++ b/source/blender/alembic/intern/abc_customdata.cc
@@ -41,101 +41,101 @@ extern "C" {
* such data in a way that lets other DCC know what they are for. See comments
* in the write code for the conventions. */
-using Alembic::AbcGeom::kVertexScope;
using Alembic::AbcGeom::kFacevaryingScope;
+using Alembic::AbcGeom::kVertexScope;
using Alembic::Abc::C4fArraySample;
using Alembic::Abc::UInt32ArraySample;
using Alembic::Abc::V2fArraySample;
-using Alembic::AbcGeom::OV2fGeomParam;
using Alembic::AbcGeom::OC4fGeomParam;
+using Alembic::AbcGeom::OV2fGeomParam;
static void get_uvs(const CDStreamConfig &config,
std::vector<Imath::V2f> &uvs,
std::vector<uint32_t> &uvidx,
void *cd_data)
{
- MLoopUV *mloopuv_array = static_cast<MLoopUV *>(cd_data);
-
- if (!mloopuv_array) {
- return;
- }
-
- const int num_poly = config.totpoly;
- MPoly *polygons = config.mpoly;
- MLoop *mloop = config.mloop;
-
- if (!config.pack_uvs) {
- int cnt = 0;
- uvidx.resize(config.totloop);
- uvs.resize(config.totloop);
-
- /* Iterate in reverse order to match exported polygons. */
- for (int i = 0; i < num_poly; ++i) {
- MPoly &current_poly = polygons[i];
- MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
-
- for (int j = 0; j < current_poly.totloop; ++j, ++cnt) {
- --loopuv;
-
- uvidx[cnt] = cnt;
- uvs[cnt][0] = loopuv->uv[0];
- uvs[cnt][1] = loopuv->uv[1];
- }
- }
- }
- else {
- /* Mapping for indexed UVs, deduplicating UV coordinates at vertices. */
- std::vector<std::vector<uint32_t>> idx_map(config.totvert);
- int idx_count = 0;
-
- for (int i = 0; i < num_poly; ++i) {
- MPoly &current_poly = polygons[i];
- MLoop *looppoly = mloop + current_poly.loopstart + current_poly.totloop;
- MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
-
- for (int j = 0; j < current_poly.totloop; ++j) {
- --looppoly;
- --loopuv;
-
- Imath::V2f uv(loopuv->uv[0], loopuv->uv[1]);
- bool found_same = false;
-
- /* Find UV already in uvs array. */
- for (uint32_t uv_idx : idx_map[looppoly->v]) {
- if (uvs[uv_idx] == uv) {
- found_same = true;
- uvidx.push_back(uv_idx);
- break;
- }
- }
-
- /* UV doesn't exists for this vertex, add it. */
- if (!found_same) {
- uint32_t uv_idx = idx_count++;
- idx_map[looppoly->v].push_back(uv_idx);
- uvidx.push_back(uv_idx);
- uvs.push_back(uv);
- }
- }
- }
- }
+ MLoopUV *mloopuv_array = static_cast<MLoopUV *>(cd_data);
+
+ if (!mloopuv_array) {
+ return;
+ }
+
+ const int num_poly = config.totpoly;
+ MPoly *polygons = config.mpoly;
+ MLoop *mloop = config.mloop;
+
+ if (!config.pack_uvs) {
+ int cnt = 0;
+ uvidx.resize(config.totloop);
+ uvs.resize(config.totloop);
+
+ /* Iterate in reverse order to match exported polygons. */
+ for (int i = 0; i < num_poly; ++i) {
+ MPoly &current_poly = polygons[i];
+ MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
+
+ for (int j = 0; j < current_poly.totloop; ++j, ++cnt) {
+ --loopuv;
+
+ uvidx[cnt] = cnt;
+ uvs[cnt][0] = loopuv->uv[0];
+ uvs[cnt][1] = loopuv->uv[1];
+ }
+ }
+ }
+ else {
+ /* Mapping for indexed UVs, deduplicating UV coordinates at vertices. */
+ std::vector<std::vector<uint32_t>> idx_map(config.totvert);
+ int idx_count = 0;
+
+ for (int i = 0; i < num_poly; ++i) {
+ MPoly &current_poly = polygons[i];
+ MLoop *looppoly = mloop + current_poly.loopstart + current_poly.totloop;
+ MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
+
+ for (int j = 0; j < current_poly.totloop; ++j) {
+ --looppoly;
+ --loopuv;
+
+ Imath::V2f uv(loopuv->uv[0], loopuv->uv[1]);
+ bool found_same = false;
+
+ /* Find UV already in uvs array. */
+ for (uint32_t uv_idx : idx_map[looppoly->v]) {
+ if (uvs[uv_idx] == uv) {
+ found_same = true;
+ uvidx.push_back(uv_idx);
+ break;
+ }
+ }
+
+ /* UV doesn't exists for this vertex, add it. */
+ if (!found_same) {
+ uint32_t uv_idx = idx_count++;
+ idx_map[looppoly->v].push_back(uv_idx);
+ uvidx.push_back(uv_idx);
+ uvs.push_back(uv);
+ }
+ }
+ }
+ }
}
const char *get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data)
{
- const int active_uvlayer = CustomData_get_active_layer(data, CD_MLOOPUV);
+ const int active_uvlayer = CustomData_get_active_layer(data, CD_MLOOPUV);
- if (active_uvlayer < 0) {
- return "";
- }
+ if (active_uvlayer < 0) {
+ return "";
+ }
- void *cd_data = CustomData_get_layer_n(data, CD_MLOOPUV, active_uvlayer);
+ void *cd_data = CustomData_get_layer_n(data, CD_MLOOPUV, active_uvlayer);
- get_uvs(config, sample.uvs, sample.indices, cd_data);
+ get_uvs(config, sample.uvs, sample.indices, cd_data);
- return CustomData_get_layer_name(data, CD_MLOOPUV, active_uvlayer);
+ return CustomData_get_layer_name(data, CD_MLOOPUV, active_uvlayer);
}
/* Convention to write UVs:
@@ -143,102 +143,109 @@ const char *get_uv_sample(UVSample &sample, const CDStreamConfig &config, Custom
* - set scope as face varying
* - (optional due to its behavior) tag as UV using Alembic::AbcGeom::SetIsUV
*/
-static void write_uv(const OCompoundProperty &prop, const CDStreamConfig &config, void *data, const char *name)
+static void write_uv(const OCompoundProperty &prop,
+ const CDStreamConfig &config,
+ void *data,
+ const char *name)
{
- std::vector<uint32_t> indices;
- std::vector<Imath::V2f> uvs;
+ std::vector<uint32_t> indices;
+ std::vector<Imath::V2f> uvs;
- get_uvs(config, uvs, indices, data);
+ get_uvs(config, uvs, indices, data);
- if (indices.empty() || uvs.empty()) {
- return;
- }
+ if (indices.empty() || uvs.empty()) {
+ return;
+ }
- OV2fGeomParam param(prop, name, true, kFacevaryingScope, 1);
+ OV2fGeomParam param(prop, name, true, kFacevaryingScope, 1);
- OV2fGeomParam::Sample sample(
- V2fArraySample(&uvs.front(), uvs.size()),
- UInt32ArraySample(&indices.front(), indices.size()),
- kFacevaryingScope);
+ OV2fGeomParam::Sample sample(V2fArraySample(&uvs.front(), uvs.size()),
+ UInt32ArraySample(&indices.front(), indices.size()),
+ kFacevaryingScope);
- param.set(sample);
+ param.set(sample);
}
/* Convention to write Vertex Colors:
* - C3fGeomParam/C4fGeomParam on the arbGeomParam
* - set scope as vertex varying
*/
-static void write_mcol(const OCompoundProperty &prop, const CDStreamConfig &config, void *data, const char *name)
+static void write_mcol(const OCompoundProperty &prop,
+ const CDStreamConfig &config,
+ void *data,
+ const char *name)
{
- const float cscale = 1.0f / 255.0f;
- MPoly *polys = config.mpoly;
- MLoop *mloops = config.mloop;
- MCol *cfaces = static_cast<MCol *>(data);
+ const float cscale = 1.0f / 255.0f;
+ MPoly *polys = config.mpoly;
+ MLoop *mloops = config.mloop;
+ MCol *cfaces = static_cast<MCol *>(data);
- std::vector<Imath::C4f> buffer;
- std::vector<uint32_t> indices;
+ std::vector<Imath::C4f> buffer;
+ std::vector<uint32_t> indices;
- buffer.reserve(config.totvert);
- indices.reserve(config.totvert);
+ buffer.reserve(config.totvert);
+ indices.reserve(config.totvert);
- Imath::C4f col;
+ Imath::C4f col;
- for (int i = 0; i < config.totpoly; ++i) {
- MPoly *p = &polys[i];
- MCol *cface = &cfaces[p->loopstart + p->totloop];
- MLoop *mloop = &mloops[p->loopstart + p->totloop];
+ for (int i = 0; i < config.totpoly; ++i) {
+ MPoly *p = &polys[i];
+ MCol *cface = &cfaces[p->loopstart + p->totloop];
+ MLoop *mloop = &mloops[p->loopstart + p->totloop];
- for (int j = 0; j < p->totloop; ++j) {
- cface--;
- mloop--;
+ for (int j = 0; j < p->totloop; ++j) {
+ cface--;
+ mloop--;
- col[0] = cface->a * cscale;
- col[1] = cface->r * cscale;
- col[2] = cface->g * cscale;
- col[3] = cface->b * cscale;
+ col[0] = cface->a * cscale;
+ col[1] = cface->r * cscale;
+ col[2] = cface->g * cscale;
+ col[3] = cface->b * cscale;
- buffer.push_back(col);
- indices.push_back(buffer.size() - 1);
- }
- }
+ buffer.push_back(col);
+ indices.push_back(buffer.size() - 1);
+ }
+ }
- OC4fGeomParam param(prop, name, true, kFacevaryingScope, 1);
+ OC4fGeomParam param(prop, name, true, kFacevaryingScope, 1);
- OC4fGeomParam::Sample sample(
- C4fArraySample(&buffer.front(), buffer.size()),
- UInt32ArraySample(&indices.front(), indices.size()),
- kVertexScope);
+ OC4fGeomParam::Sample sample(C4fArraySample(&buffer.front(), buffer.size()),
+ UInt32ArraySample(&indices.front(), indices.size()),
+ kVertexScope);
- param.set(sample);
+ param.set(sample);
}
-void write_custom_data(const OCompoundProperty &prop, const CDStreamConfig &config, CustomData *data, int data_type)
+void write_custom_data(const OCompoundProperty &prop,
+ const CDStreamConfig &config,
+ CustomData *data,
+ int data_type)
{
- CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
-
- if (!CustomData_has_layer(data, cd_data_type)) {
- return;
- }
-
- const int active_layer = CustomData_get_active_layer(data, cd_data_type);
- const int tot_layers = CustomData_number_of_layers(data, cd_data_type);
-
- for (int i = 0; i < tot_layers; ++i) {
- void *cd_data = CustomData_get_layer_n(data, cd_data_type, i);
- const char *name = CustomData_get_layer_name(data, cd_data_type, i);
-
- if (cd_data_type == CD_MLOOPUV) {
- /* Already exported. */
- if (i == active_layer) {
- continue;
- }
-
- write_uv(prop, config, cd_data, name);
- }
- else if (cd_data_type == CD_MLOOPCOL) {
- write_mcol(prop, config, cd_data, name);
- }
- }
+ CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
+
+ if (!CustomData_has_layer(data, cd_data_type)) {
+ return;
+ }
+
+ const int active_layer = CustomData_get_active_layer(data, cd_data_type);
+ const int tot_layers = CustomData_number_of_layers(data, cd_data_type);
+
+ for (int i = 0; i < tot_layers; ++i) {
+ void *cd_data = CustomData_get_layer_n(data, cd_data_type, i);
+ const char *name = CustomData_get_layer_name(data, cd_data_type, i);
+
+ if (cd_data_type == CD_MLOOPUV) {
+ /* Already exported. */
+ if (i == active_layer) {
+ continue;
+ }
+
+ write_uv(prop, config, cd_data, name);
+ }
+ else if (cd_data_type == CD_MLOOPCOL) {
+ write_mcol(prop, config, cd_data, name);
+ }
+ }
}
/* ************************************************************************** */
@@ -251,167 +258,165 @@ using Alembic::AbcGeom::IC3fGeomParam;
using Alembic::AbcGeom::IC4fGeomParam;
using Alembic::AbcGeom::IV2fGeomParam;
-
-static void read_uvs(const CDStreamConfig &config, void *data,
+static void read_uvs(const CDStreamConfig &config,
+ void *data,
const Alembic::AbcGeom::V2fArraySamplePtr &uvs,
const Alembic::AbcGeom::UInt32ArraySamplePtr &indices)
{
- MPoly *mpolys = config.mpoly;
- MLoopUV *mloopuvs = static_cast<MLoopUV *>(data);
-
- unsigned int uv_index, loop_index, rev_loop_index;
-
- for (int i = 0; i < config.totpoly; ++i) {
- MPoly &poly = mpolys[i];
- unsigned int rev_loop_offset = poly.loopstart + poly.totloop - 1;
-
- for (int f = 0; f < poly.totloop; ++f) {
- loop_index = poly.loopstart + f;
- rev_loop_index = rev_loop_offset - f;
- uv_index = (*indices)[loop_index];
- const Imath::V2f &uv = (*uvs)[uv_index];
-
- MLoopUV &loopuv = mloopuvs[rev_loop_index];
- loopuv.uv[0] = uv[0];
- loopuv.uv[1] = uv[1];
- }
- }
+ MPoly *mpolys = config.mpoly;
+ MLoopUV *mloopuvs = static_cast<MLoopUV *>(data);
+
+ unsigned int uv_index, loop_index, rev_loop_index;
+
+ for (int i = 0; i < config.totpoly; ++i) {
+ MPoly &poly = mpolys[i];
+ unsigned int rev_loop_offset = poly.loopstart + poly.totloop - 1;
+
+ for (int f = 0; f < poly.totloop; ++f) {
+ loop_index = poly.loopstart + f;
+ rev_loop_index = rev_loop_offset - f;
+ uv_index = (*indices)[loop_index];
+ const Imath::V2f &uv = (*uvs)[uv_index];
+
+ MLoopUV &loopuv = mloopuvs[rev_loop_index];
+ loopuv.uv[0] = uv[0];
+ loopuv.uv[1] = uv[1];
+ }
+ }
}
-static size_t mcols_out_of_bounds_check(
- const size_t color_index,
- const size_t array_size,
- const std::string & iobject_full_name,
- const PropertyHeader &prop_header,
- bool &r_is_out_of_bounds,
- bool &r_bounds_warning_given)
+static size_t mcols_out_of_bounds_check(const size_t color_index,
+ const size_t array_size,
+ const std::string &iobject_full_name,
+ const PropertyHeader &prop_header,
+ bool &r_is_out_of_bounds,
+ bool &r_bounds_warning_given)
{
- if (color_index < array_size) {
- return color_index;
- }
-
- if (!r_bounds_warning_given) {
- std::cerr << "Alembic: color index out of bounds "
- "reading face colors for object "
- << iobject_full_name
- << ", property "
- << prop_header.getName() << std::endl;
- r_bounds_warning_given = true;
- }
- r_is_out_of_bounds = true;
- return 0;
+ if (color_index < array_size) {
+ return color_index;
+ }
+
+ if (!r_bounds_warning_given) {
+ std::cerr << "Alembic: color index out of bounds "
+ "reading face colors for object "
+ << iobject_full_name << ", property " << prop_header.getName() << std::endl;
+ r_bounds_warning_given = true;
+ }
+ r_is_out_of_bounds = true;
+ return 0;
}
-static void read_custom_data_mcols(const std::string & iobject_full_name,
+static void read_custom_data_mcols(const std::string &iobject_full_name,
const ICompoundProperty &arbGeomParams,
const PropertyHeader &prop_header,
const CDStreamConfig &config,
const Alembic::Abc::ISampleSelector &iss)
{
- C3fArraySamplePtr c3f_ptr = C3fArraySamplePtr();
- C4fArraySamplePtr c4f_ptr = C4fArraySamplePtr();
- Alembic::Abc::UInt32ArraySamplePtr indices;
- bool use_c3f_ptr;
- bool is_facevarying;
-
- /* Find the correct interpretation of the data */
- if (IC3fGeomParam::matches(prop_header)) {
- IC3fGeomParam color_param(arbGeomParams, prop_header.getName());
- IC3fGeomParam::Sample sample;
- BLI_assert(!strcmp("rgb", color_param.getInterpretation()));
-
- color_param.getIndexed(sample, iss);
- is_facevarying = sample.getScope() == kFacevaryingScope &&
- config.totloop == sample.getIndices()->size();
-
- c3f_ptr = sample.getVals();
- indices = sample.getIndices();
- use_c3f_ptr = true;
- }
- else if (IC4fGeomParam::matches(prop_header)) {
- IC4fGeomParam color_param(arbGeomParams, prop_header.getName());
- IC4fGeomParam::Sample sample;
- BLI_assert(!strcmp("rgba", color_param.getInterpretation()));
-
- color_param.getIndexed(sample, iss);
- is_facevarying = sample.getScope() == kFacevaryingScope &&
- config.totloop == sample.getIndices()->size();
-
- c4f_ptr = sample.getVals();
- indices = sample.getIndices();
- use_c3f_ptr = false;
- }
- else {
- /* this won't happen due to the checks in read_custom_data() */
- return;
- }
- BLI_assert(c3f_ptr || c4f_ptr);
-
- /* Read the vertex colors */
- void *cd_data = config.add_customdata_cb(config.user_data,
- prop_header.getName().c_str(),
- CD_MLOOPCOL);
- MCol *cfaces = static_cast<MCol *>(cd_data);
- MPoly *mpolys = config.mpoly;
- MLoop *mloops = config.mloop;
-
- size_t face_index = 0;
- size_t color_index;
- bool bounds_warning_given = false;
-
- /* The colors can go through two layers of indexing. Often the 'indices'
- * array doesn't do anything (i.e. indices[n] = n), but when it does, it's
- * important. Blender 2.79 writes indices incorrectly (see T53745), which
- * is why we have to check for indices->size() > 0 */
- bool use_dual_indexing = is_facevarying && indices->size() > 0;
-
- for (int i = 0; i < config.totpoly; ++i) {
- MPoly *poly = &mpolys[i];
- MCol *cface = &cfaces[poly->loopstart + poly->totloop];
- MLoop *mloop = &mloops[poly->loopstart + poly->totloop];
-
- for (int j = 0; j < poly->totloop; ++j, ++face_index) {
- --cface;
- --mloop;
-
- color_index = is_facevarying ? face_index : mloop->v;
- if (use_dual_indexing) {
- color_index = (*indices)[color_index];
- }
- if (use_c3f_ptr) {
- bool is_mcols_out_of_bounds = false;
- color_index = mcols_out_of_bounds_check(
- color_index,
- c3f_ptr->size(),
- iobject_full_name, prop_header,
- is_mcols_out_of_bounds, bounds_warning_given);
- if (is_mcols_out_of_bounds) {
- continue;
- }
- const Imath::C3f &color = (*c3f_ptr)[color_index];
- cface->a = unit_float_to_uchar_clamp(color[0]);
- cface->r = unit_float_to_uchar_clamp(color[1]);
- cface->g = unit_float_to_uchar_clamp(color[2]);
- cface->b = 255;
- }
- else {
- bool is_mcols_out_of_bounds = false;
- color_index = mcols_out_of_bounds_check(
- color_index,
- c4f_ptr->size(),
- iobject_full_name, prop_header,
- is_mcols_out_of_bounds, bounds_warning_given);
- if (is_mcols_out_of_bounds) {
- continue;
- }
- const Imath::C4f &color = (*c4f_ptr)[color_index];
- cface->a = unit_float_to_uchar_clamp(color[0]);
- cface->r = unit_float_to_uchar_clamp(color[1]);
- cface->g = unit_float_to_uchar_clamp(color[2]);
- cface->b = unit_float_to_uchar_clamp(color[3]);
- }
- }
- }
+ C3fArraySamplePtr c3f_ptr = C3fArraySamplePtr();
+ C4fArraySamplePtr c4f_ptr = C4fArraySamplePtr();
+ Alembic::Abc::UInt32ArraySamplePtr indices;
+ bool use_c3f_ptr;
+ bool is_facevarying;
+
+ /* Find the correct interpretation of the data */
+ if (IC3fGeomParam::matches(prop_header)) {
+ IC3fGeomParam color_param(arbGeomParams, prop_header.getName());
+ IC3fGeomParam::Sample sample;
+ BLI_assert(!strcmp("rgb", color_param.getInterpretation()));
+
+ color_param.getIndexed(sample, iss);
+ is_facevarying = sample.getScope() == kFacevaryingScope &&
+ config.totloop == sample.getIndices()->size();
+
+ c3f_ptr = sample.getVals();
+ indices = sample.getIndices();
+ use_c3f_ptr = true;
+ }
+ else if (IC4fGeomParam::matches(prop_header)) {
+ IC4fGeomParam color_param(arbGeomParams, prop_header.getName());
+ IC4fGeomParam::Sample sample;
+ BLI_assert(!strcmp("rgba", color_param.getInterpretation()));
+
+ color_param.getIndexed(sample, iss);
+ is_facevarying = sample.getScope() == kFacevaryingScope &&
+ config.totloop == sample.getIndices()->size();
+
+ c4f_ptr = sample.getVals();
+ indices = sample.getIndices();
+ use_c3f_ptr = false;
+ }
+ else {
+ /* this won't happen due to the checks in read_custom_data() */
+ return;
+ }
+ BLI_assert(c3f_ptr || c4f_ptr);
+
+ /* Read the vertex colors */
+ void *cd_data = config.add_customdata_cb(
+ config.user_data, prop_header.getName().c_str(), CD_MLOOPCOL);
+ MCol *cfaces = static_cast<MCol *>(cd_data);
+ MPoly *mpolys = config.mpoly;
+ MLoop *mloops = config.mloop;
+
+ size_t face_index = 0;
+ size_t color_index;
+ bool bounds_warning_given = false;
+
+ /* The colors can go through two layers of indexing. Often the 'indices'
+ * array doesn't do anything (i.e. indices[n] = n), but when it does, it's
+ * important. Blender 2.79 writes indices incorrectly (see T53745), which
+ * is why we have to check for indices->size() > 0 */
+ bool use_dual_indexing = is_facevarying && indices->size() > 0;
+
+ for (int i = 0; i < config.totpoly; ++i) {
+ MPoly *poly = &mpolys[i];
+ MCol *cface = &cfaces[poly->loopstart + poly->totloop];
+ MLoop *mloop = &mloops[poly->loopstart + poly->totloop];
+
+ for (int j = 0; j < poly->totloop; ++j, ++face_index) {
+ --cface;
+ --mloop;
+
+ color_index = is_facevarying ? face_index : mloop->v;
+ if (use_dual_indexing) {
+ color_index = (*indices)[color_index];
+ }
+ if (use_c3f_ptr) {
+ bool is_mcols_out_of_bounds = false;
+ color_index = mcols_out_of_bounds_check(color_index,
+ c3f_ptr->size(),
+ iobject_full_name,
+ prop_header,
+ is_mcols_out_of_bounds,
+ bounds_warning_given);
+ if (is_mcols_out_of_bounds) {
+ continue;
+ }
+ const Imath::C3f &color = (*c3f_ptr)[color_index];
+ cface->a = unit_float_to_uchar_clamp(color[0]);
+ cface->r = unit_float_to_uchar_clamp(color[1]);
+ cface->g = unit_float_to_uchar_clamp(color[2]);
+ cface->b = 255;
+ }
+ else {
+ bool is_mcols_out_of_bounds = false;
+ color_index = mcols_out_of_bounds_check(color_index,
+ c4f_ptr->size(),
+ iobject_full_name,
+ prop_header,
+ is_mcols_out_of_bounds,
+ bounds_warning_given);
+ if (is_mcols_out_of_bounds) {
+ continue;
+ }
+ const Imath::C4f &color = (*c4f_ptr)[color_index];
+ cface->a = unit_float_to_uchar_clamp(color[0]);
+ cface->r = unit_float_to_uchar_clamp(color[1]);
+ cface->g = unit_float_to_uchar_clamp(color[2]);
+ cface->b = unit_float_to_uchar_clamp(color[3]);
+ }
+ }
+ }
}
static void read_custom_data_uvs(const ICompoundProperty &prop,
@@ -419,61 +424,60 @@ static void read_custom_data_uvs(const ICompoundProperty &prop,
const CDStreamConfig &config,
const Alembic::Abc::ISampleSelector &iss)
{
- IV2fGeomParam uv_param(prop, prop_header.getName());
+ IV2fGeomParam uv_param(prop, prop_header.getName());
- if (!uv_param.isIndexed()) {
- return;
- }
+ if (!uv_param.isIndexed()) {
+ return;
+ }
- IV2fGeomParam::Sample sample;
- uv_param.getIndexed(sample, iss);
+ IV2fGeomParam::Sample sample;
+ uv_param.getIndexed(sample, iss);
- if (uv_param.getScope() != kFacevaryingScope) {
- return;
- }
+ if (uv_param.getScope() != kFacevaryingScope) {
+ return;
+ }
- void *cd_data = config.add_customdata_cb(config.user_data,
- prop_header.getName().c_str(),
- CD_MLOOPUV);
+ void *cd_data = config.add_customdata_cb(
+ config.user_data, prop_header.getName().c_str(), CD_MLOOPUV);
- read_uvs(config, cd_data, sample.getVals(), sample.getIndices());
+ read_uvs(config, cd_data, sample.getVals(), sample.getIndices());
}
-void read_custom_data(const std::string & iobject_full_name,
+void read_custom_data(const std::string &iobject_full_name,
const ICompoundProperty &prop,
const CDStreamConfig &config,
const Alembic::Abc::ISampleSelector &iss)
{
- if (!prop.valid()) {
- return;
- }
-
- int num_uvs = 0;
- int num_colors = 0;
-
- const size_t num_props = prop.getNumProperties();
-
- for (size_t i = 0; i < num_props; ++i) {
- const Alembic::Abc::PropertyHeader &prop_header = prop.getPropertyHeader(i);
-
- /* Read UVs according to convention. */
- if (IV2fGeomParam::matches(prop_header) && Alembic::AbcGeom::isUV(prop_header)) {
- if (++num_uvs > MAX_MTFACE) {
- continue;
- }
-
- read_custom_data_uvs(prop, prop_header, config, iss);
- continue;
- }
-
- /* Read vertex colors according to convention. */
- if (IC3fGeomParam::matches(prop_header) || IC4fGeomParam::matches(prop_header)) {
- if (++num_colors > MAX_MCOL) {
- continue;
- }
-
- read_custom_data_mcols(iobject_full_name, prop, prop_header, config, iss);
- continue;
- }
- }
+ if (!prop.valid()) {
+ return;
+ }
+
+ int num_uvs = 0;
+ int num_colors = 0;
+
+ const size_t num_props = prop.getNumProperties();
+
+ for (size_t i = 0; i < num_props; ++i) {
+ const Alembic::Abc::PropertyHeader &prop_header = prop.getPropertyHeader(i);
+
+ /* Read UVs according to convention. */
+ if (IV2fGeomParam::matches(prop_header) && Alembic::AbcGeom::isUV(prop_header)) {
+ if (++num_uvs > MAX_MTFACE) {
+ continue;
+ }
+
+ read_custom_data_uvs(prop, prop_header, config, iss);
+ continue;
+ }
+
+ /* Read vertex colors according to convention. */
+ if (IC3fGeomParam::matches(prop_header) || IC4fGeomParam::matches(prop_header)) {
+ if (++num_colors > MAX_MCOL) {
+ continue;
+ }
+
+ read_custom_data_mcols(iobject_full_name, prop, prop_header, config, iss);
+ continue;
+ }
+ }
}
diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h
index 88520b47a55..c36029d5116 100644
--- a/source/blender/alembic/intern/abc_customdata.h
+++ b/source/blender/alembic/intern/abc_customdata.h
@@ -37,51 +37,52 @@ using Alembic::Abc::ICompoundProperty;
using Alembic::Abc::OCompoundProperty;
struct UVSample {
- std::vector<Imath::V2f> uvs;
- std::vector<uint32_t> indices;
+ std::vector<Imath::V2f> uvs;
+ std::vector<uint32_t> indices;
};
struct CDStreamConfig {
- MLoop *mloop;
- int totloop;
-
- MPoly *mpoly;
- int totpoly;
-
- MVert *mvert;
- int totvert;
-
- MLoopUV *mloopuv;
-
- CustomData *loopdata;
-
- bool pack_uvs;
-
- /* TODO(kevin): might need a better way to handle adding and/or updating
- * custom datas such that it updates the custom data holder and its pointers
- * properly. */
- void *user_data;
- void *(*add_customdata_cb)(void *user_data, const char *name, int data_type);
-
- float weight;
- float time;
- Alembic::AbcGeom::index_t index;
- Alembic::AbcGeom::index_t ceil_index;
-
- CDStreamConfig()
- : mloop(NULL)
- , totloop(0)
- , mpoly(NULL)
- , totpoly(0)
- , totvert(0)
- , pack_uvs(false)
- , user_data(NULL)
- , add_customdata_cb(NULL)
- , weight(0.0f)
- , time(0.0f)
- , index(0)
- , ceil_index(0)
- {}
+ MLoop *mloop;
+ int totloop;
+
+ MPoly *mpoly;
+ int totpoly;
+
+ MVert *mvert;
+ int totvert;
+
+ MLoopUV *mloopuv;
+
+ CustomData *loopdata;
+
+ bool pack_uvs;
+
+ /* TODO(kevin): might need a better way to handle adding and/or updating
+ * custom datas such that it updates the custom data holder and its pointers
+ * properly. */
+ void *user_data;
+ void *(*add_customdata_cb)(void *user_data, const char *name, int data_type);
+
+ float weight;
+ float time;
+ Alembic::AbcGeom::index_t index;
+ Alembic::AbcGeom::index_t ceil_index;
+
+ CDStreamConfig()
+ : mloop(NULL),
+ totloop(0),
+ mpoly(NULL),
+ totpoly(0),
+ totvert(0),
+ pack_uvs(false),
+ user_data(NULL),
+ add_customdata_cb(NULL),
+ weight(0.0f),
+ time(0.0f),
+ index(0),
+ ceil_index(0)
+ {
+ }
};
/* Get the UVs for the main UV property on a OSchema.
@@ -95,9 +96,9 @@ void write_custom_data(const OCompoundProperty &prop,
CustomData *data,
int data_type);
-void read_custom_data(const std::string & iobject_full_name,
+void read_custom_data(const std::string &iobject_full_name,
const ICompoundProperty &prop,
const CDStreamConfig &config,
const Alembic::Abc::ISampleSelector &iss);
-#endif /* __ABC_CUSTOMDATA_H__ */
+#endif /* __ABC_CUSTOMDATA_H__ */
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index f37dbab3b57..4a7f26d2e18 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -41,7 +41,7 @@ extern "C" {
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "DNA_space_types.h" /* for FILE_MAX */
+#include "DNA_space_types.h" /* for FILE_MAX */
#include "BLI_string.h"
@@ -62,79 +62,79 @@ extern "C" {
#include "DEG_depsgraph_query.h"
}
-using Alembic::Abc::TimeSamplingPtr;
using Alembic::Abc::OBox3dProperty;
+using Alembic::Abc::TimeSamplingPtr;
/* ************************************************************************** */
ExportSettings::ExportSettings()
- : scene(NULL)
- , view_layer(NULL)
- , depsgraph(NULL)
- , logger()
- , selected_only(false)
- , visible_layers_only(false)
- , renderable_only(false)
- , frame_start(1)
- , frame_end(1)
- , frame_samples_xform(1)
- , frame_samples_shape(1)
- , shutter_open(0.0)
- , shutter_close(1.0)
- , global_scale(1.0f)
- , flatten_hierarchy(false)
- , export_normals(false)
- , export_uvs(false)
- , export_vcols(false)
- , export_face_sets(false)
- , export_vweigths(false)
- , export_hair(true)
- , export_particles(true)
- , apply_subdiv(false)
- , use_subdiv_schema(false)
- , export_child_hairs(true)
- , export_ogawa(true)
- , pack_uv(false)
- , triangulate(false)
- , quad_method(0)
- , ngon_method(0)
- , do_convert_axis(false)
-{}
+ : scene(NULL),
+ view_layer(NULL),
+ depsgraph(NULL),
+ logger(),
+ selected_only(false),
+ visible_layers_only(false),
+ renderable_only(false),
+ frame_start(1),
+ frame_end(1),
+ frame_samples_xform(1),
+ frame_samples_shape(1),
+ shutter_open(0.0),
+ shutter_close(1.0),
+ global_scale(1.0f),
+ flatten_hierarchy(false),
+ export_normals(false),
+ export_uvs(false),
+ export_vcols(false),
+ export_face_sets(false),
+ export_vweigths(false),
+ export_hair(true),
+ export_particles(true),
+ apply_subdiv(false),
+ use_subdiv_schema(false),
+ export_child_hairs(true),
+ export_ogawa(true),
+ pack_uv(false),
+ triangulate(false),
+ quad_method(0),
+ ngon_method(0),
+ do_convert_axis(false)
+{
+}
static bool object_is_smoke_sim(Object *ob)
{
- ModifierData *md = modifiers_findByType(ob, eModifierType_Smoke);
+ ModifierData *md = modifiers_findByType(ob, eModifierType_Smoke);
- if (md) {
- SmokeModifierData *smd = reinterpret_cast<SmokeModifierData *>(md);
- return (smd->type == MOD_SMOKE_TYPE_DOMAIN);
- }
+ if (md) {
+ SmokeModifierData *smd = reinterpret_cast<SmokeModifierData *>(md);
+ return (smd->type == MOD_SMOKE_TYPE_DOMAIN);
+ }
- return false;
+ return false;
}
static bool object_type_is_exportable(Scene *scene, Object *ob)
{
- switch (ob->type) {
- case OB_MESH:
- if (object_is_smoke_sim(ob)) {
- return false;
- }
-
- return true;
- case OB_EMPTY:
- case OB_CURVE:
- case OB_SURF:
- case OB_CAMERA:
- return true;
- case OB_MBALL:
- return AbcMBallWriter::isBasisBall(scene, ob);
- default:
- return false;
- }
+ switch (ob->type) {
+ case OB_MESH:
+ if (object_is_smoke_sim(ob)) {
+ return false;
+ }
+
+ return true;
+ case OB_EMPTY:
+ case OB_CURVE:
+ case OB_SURF:
+ case OB_CAMERA:
+ return true;
+ case OB_MBALL:
+ return AbcMBallWriter::isBasisBall(scene, ob);
+ default:
+ return false;
+ }
}
-
/**
* Returns whether this object should be exported into the Alembic file.
*
@@ -145,518 +145,521 @@ static bool object_type_is_exportable(Scene *scene, Object *ob)
* This ignores selection and layer visibility,
* and assumes that the dupli-object itself (e.g. the group-instantiating empty) is exported.
*/
-static bool export_object(const ExportSettings * const settings, const Base * const base,
+static bool export_object(const ExportSettings *const settings,
+ const Base *const base,
bool is_duplicated)
{
- if (!is_duplicated) {
- View3D *v3d = NULL;
-
- /* These two tests only make sense when the object isn't being instanced
- * into the scene. When it is, its exportability is determined by
- * its dupli-object and the DupliObject::no_draw property. */
- if (settings->selected_only && !BASE_SELECTED(v3d, base)) {
- return false;
- }
- // FIXME Sybren: handle these cleanly (maybe just remove code), now using active scene layer instead.
- if (settings->visible_layers_only && !BASE_VISIBLE(v3d, base)) {
- return false;
- }
- }
-
- // if (settings->renderable_only && (ob->restrictflag & OB_RESTRICT_RENDER)) {
- // return false;
- // }
-
- return true;
+ if (!is_duplicated) {
+ View3D *v3d = NULL;
+
+ /* These two tests only make sense when the object isn't being instanced
+ * into the scene. When it is, its exportability is determined by
+ * its dupli-object and the DupliObject::no_draw property. */
+ if (settings->selected_only && !BASE_SELECTED(v3d, base)) {
+ return false;
+ }
+ // FIXME Sybren: handle these cleanly (maybe just remove code), now using active scene layer instead.
+ if (settings->visible_layers_only && !BASE_VISIBLE(v3d, base)) {
+ return false;
+ }
+ }
+
+ // if (settings->renderable_only && (ob->restrictflag & OB_RESTRICT_RENDER)) {
+ // return false;
+ // }
+
+ return true;
}
/* ************************************************************************** */
AbcExporter::AbcExporter(Main *bmain, const char *filename, ExportSettings &settings)
- : m_bmain(bmain)
- , m_settings(settings)
- , m_filename(filename)
- , m_trans_sampling_index(0)
- , m_shape_sampling_index(0)
- , m_writer(NULL)
-{}
+ : m_bmain(bmain),
+ m_settings(settings),
+ m_filename(filename),
+ m_trans_sampling_index(0),
+ m_shape_sampling_index(0),
+ m_writer(NULL)
+{
+}
AbcExporter::~AbcExporter()
{
- /* Free xforms map */
- m_xforms_type::iterator it_x, e_x;
- for (it_x = m_xforms.begin(), e_x = m_xforms.end(); it_x != e_x; ++it_x) {
- delete it_x->second;
- }
-
- /* Free shapes vector */
- for (int i = 0, e = m_shapes.size(); i != e; ++i) {
- delete m_shapes[i];
- }
-
- delete m_writer;
+ /* Free xforms map */
+ m_xforms_type::iterator it_x, e_x;
+ for (it_x = m_xforms.begin(), e_x = m_xforms.end(); it_x != e_x; ++it_x) {
+ delete it_x->second;
+ }
+
+ /* Free shapes vector */
+ for (int i = 0, e = m_shapes.size(); i != e; ++i) {
+ delete m_shapes[i];
+ }
+
+ delete m_writer;
}
void AbcExporter::getShutterSamples(unsigned int nr_of_samples,
bool time_relative,
std::vector<double> &samples)
{
- Scene *scene = m_settings.scene; /* for use in the FPS macro */
- samples.clear();
-
- unsigned int frame_offset = time_relative ? m_settings.frame_start : 0;
- double time_factor = time_relative ? FPS : 1.0;
- double shutter_open = m_settings.shutter_open;
- double shutter_close = m_settings.shutter_close;
- double time_inc = (shutter_close - shutter_open) / nr_of_samples;
-
- /* sample between shutter open & close */
- for (int sample=0; sample < nr_of_samples; ++sample) {
- double sample_time = shutter_open + time_inc * sample;
- double time = (frame_offset + sample_time) / time_factor;
-
- samples.push_back(time);
- }
+ Scene *scene = m_settings.scene; /* for use in the FPS macro */
+ samples.clear();
+
+ unsigned int frame_offset = time_relative ? m_settings.frame_start : 0;
+ double time_factor = time_relative ? FPS : 1.0;
+ double shutter_open = m_settings.shutter_open;
+ double shutter_close = m_settings.shutter_close;
+ double time_inc = (shutter_close - shutter_open) / nr_of_samples;
+
+ /* sample between shutter open & close */
+ for (int sample = 0; sample < nr_of_samples; ++sample) {
+ double sample_time = shutter_open + time_inc * sample;
+ double time = (frame_offset + sample_time) / time_factor;
+
+ samples.push_back(time);
+ }
}
Alembic::Abc::TimeSamplingPtr AbcExporter::createTimeSampling(double step)
{
- std::vector<double> samples;
+ std::vector<double> samples;
- if (m_settings.frame_start == m_settings.frame_end) {
- return TimeSamplingPtr(new Alembic::Abc::TimeSampling());
- }
+ if (m_settings.frame_start == m_settings.frame_end) {
+ return TimeSamplingPtr(new Alembic::Abc::TimeSampling());
+ }
- getShutterSamples(step, true, samples);
+ getShutterSamples(step, true, samples);
- Alembic::Abc::TimeSamplingType ts(
- static_cast<uint32_t>(samples.size()),
- 1.0 / m_settings.scene->r.frs_sec); /* TODO(Sybren): shouldn't we use the FPS macro here? */
+ Alembic::Abc::TimeSamplingType ts(
+ static_cast<uint32_t>(samples.size()),
+ 1.0 / m_settings.scene->r.frs_sec); /* TODO(Sybren): shouldn't we use the FPS macro here? */
- return TimeSamplingPtr(new Alembic::Abc::TimeSampling(ts, samples));
+ return TimeSamplingPtr(new Alembic::Abc::TimeSampling(ts, samples));
}
-void AbcExporter::getFrameSet(unsigned int nr_of_samples,
- std::set<double> &frames)
+void AbcExporter::getFrameSet(unsigned int nr_of_samples, std::set<double> &frames)
{
- frames.clear();
+ frames.clear();
- std::vector<double> shutter_samples;
+ std::vector<double> shutter_samples;
- getShutterSamples(nr_of_samples, false, shutter_samples);
+ getShutterSamples(nr_of_samples, false, shutter_samples);
- for (double frame = m_settings.frame_start; frame <= m_settings.frame_end; frame += 1.0) {
- for (size_t j = 0; j < nr_of_samples; ++j) {
- frames.insert(frame + shutter_samples[j]);
- }
- }
+ for (double frame = m_settings.frame_start; frame <= m_settings.frame_end; frame += 1.0) {
+ for (size_t j = 0; j < nr_of_samples; ++j) {
+ frames.insert(frame + shutter_samples[j]);
+ }
+ }
}
void AbcExporter::operator()(float &progress, bool &was_canceled)
{
- std::string scene_name;
+ std::string scene_name;
- if (m_bmain->name[0] != '\0') {
- char scene_file_name[FILE_MAX];
- BLI_strncpy(scene_file_name, m_bmain->name, FILE_MAX);
- scene_name = scene_file_name;
- }
- else {
- scene_name = "untitled";
- }
+ if (m_bmain->name[0] != '\0') {
+ char scene_file_name[FILE_MAX];
+ BLI_strncpy(scene_file_name, m_bmain->name, FILE_MAX);
+ scene_name = scene_file_name;
+ }
+ else {
+ scene_name = "untitled";
+ }
- Scene *scene = m_settings.scene;
- const double fps = FPS;
- char buf[16];
- snprintf(buf, 15, "%f", fps);
- const std::string str_fps = buf;
+ Scene *scene = m_settings.scene;
+ const double fps = FPS;
+ char buf[16];
+ snprintf(buf, 15, "%f", fps);
+ const std::string str_fps = buf;
- Alembic::AbcCoreAbstract::MetaData md;
- md.set("FramesPerTimeUnit", str_fps);
+ Alembic::AbcCoreAbstract::MetaData md;
+ md.set("FramesPerTimeUnit", str_fps);
- m_writer = new ArchiveWriter(m_filename, scene_name.c_str(), m_settings.export_ogawa, md);
+ m_writer = new ArchiveWriter(m_filename, scene_name.c_str(), m_settings.export_ogawa, md);
- /* Create time samplings for transforms and shapes. */
+ /* Create time samplings for transforms and shapes. */
- TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_samples_xform);
+ TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_samples_xform);
- m_trans_sampling_index = m_writer->archive().addTimeSampling(*trans_time);
+ m_trans_sampling_index = m_writer->archive().addTimeSampling(*trans_time);
- TimeSamplingPtr shape_time;
+ TimeSamplingPtr shape_time;
- if ((m_settings.frame_samples_shape == m_settings.frame_samples_xform) ||
- (m_settings.frame_start == m_settings.frame_end))
- {
- shape_time = trans_time;
- m_shape_sampling_index = m_trans_sampling_index;
- }
- else {
- shape_time = createTimeSampling(m_settings.frame_samples_shape);
- m_shape_sampling_index = m_writer->archive().addTimeSampling(*shape_time);
- }
+ if ((m_settings.frame_samples_shape == m_settings.frame_samples_xform) ||
+ (m_settings.frame_start == m_settings.frame_end)) {
+ shape_time = trans_time;
+ m_shape_sampling_index = m_trans_sampling_index;
+ }
+ else {
+ shape_time = createTimeSampling(m_settings.frame_samples_shape);
+ m_shape_sampling_index = m_writer->archive().addTimeSampling(*shape_time);
+ }
- OBox3dProperty archive_bounds_prop = Alembic::AbcGeom::CreateOArchiveBounds(m_writer->archive(), m_trans_sampling_index);
+ OBox3dProperty archive_bounds_prop = Alembic::AbcGeom::CreateOArchiveBounds(
+ m_writer->archive(), m_trans_sampling_index);
- createTransformWritersHierarchy();
- createShapeWriters();
+ createTransformWritersHierarchy();
+ createShapeWriters();
- /* Make a list of frames to export. */
+ /* Make a list of frames to export. */
- std::set<double> xform_frames;
- getFrameSet(m_settings.frame_samples_xform, xform_frames);
+ std::set<double> xform_frames;
+ getFrameSet(m_settings.frame_samples_xform, xform_frames);
- std::set<double> shape_frames;
- getFrameSet(m_settings.frame_samples_shape, shape_frames);
+ std::set<double> shape_frames;
+ getFrameSet(m_settings.frame_samples_shape, shape_frames);
- /* Merge all frames needed. */
- std::set<double> frames(xform_frames);
- frames.insert(shape_frames.begin(), shape_frames.end());
+ /* Merge all frames needed. */
+ std::set<double> frames(xform_frames);
+ frames.insert(shape_frames.begin(), shape_frames.end());
- /* Export all frames. */
+ /* Export all frames. */
- std::set<double>::const_iterator begin = frames.begin();
- std::set<double>::const_iterator end = frames.end();
+ std::set<double>::const_iterator begin = frames.begin();
+ std::set<double>::const_iterator end = frames.end();
- const float size = static_cast<float>(frames.size());
- size_t i = 0;
+ const float size = static_cast<float>(frames.size());
+ size_t i = 0;
- for (; begin != end; ++begin) {
- progress = (++i / size);
+ for (; begin != end; ++begin) {
+ progress = (++i / size);
- if (G.is_break) {
- was_canceled = true;
- break;
- }
+ if (G.is_break) {
+ was_canceled = true;
+ break;
+ }
- const double frame = *begin;
+ const double frame = *begin;
- /* 'frame' is offset by start frame, so need to cancel the offset. */
- setCurrentFrame(m_bmain, frame);
+ /* 'frame' is offset by start frame, so need to cancel the offset. */
+ setCurrentFrame(m_bmain, frame);
- if (shape_frames.count(frame) != 0) {
- for (int i = 0, e = m_shapes.size(); i != e; ++i) {
- m_shapes[i]->write();
- }
- }
+ if (shape_frames.count(frame) != 0) {
+ for (int i = 0, e = m_shapes.size(); i != e; ++i) {
+ m_shapes[i]->write();
+ }
+ }
- if (xform_frames.count(frame) == 0) {
- continue;
- }
+ if (xform_frames.count(frame) == 0) {
+ continue;
+ }
- m_xforms_type::iterator xit, xe;
- for (xit = m_xforms.begin(), xe = m_xforms.end(); xit != xe; ++xit) {
- xit->second->write();
- }
+ m_xforms_type::iterator xit, xe;
+ for (xit = m_xforms.begin(), xe = m_xforms.end(); xit != xe; ++xit) {
+ xit->second->write();
+ }
- /* Save the archive 's bounding box. */
- Imath::Box3d bounds;
+ /* Save the archive 's bounding box. */
+ Imath::Box3d bounds;
- for (xit = m_xforms.begin(), xe = m_xforms.end(); xit != xe; ++xit) {
- Imath::Box3d box = xit->second->bounds();
- bounds.extendBy(box);
- }
+ for (xit = m_xforms.begin(), xe = m_xforms.end(); xit != xe; ++xit) {
+ Imath::Box3d box = xit->second->bounds();
+ bounds.extendBy(box);
+ }
- archive_bounds_prop.set(bounds);
- }
+ archive_bounds_prop.set(bounds);
+ }
}
void AbcExporter::createTransformWritersHierarchy()
{
- for (Base *base = static_cast<Base *>(m_settings.view_layer->object_bases.first); base; base = base->next) {
- Object *ob = base->object;
-
- if (export_object(&m_settings, base, false)) {
- switch (ob->type) {
- case OB_LAMP:
- case OB_LATTICE:
- case OB_SPEAKER:
- /* We do not export transforms for objects of these classes. */
- break;
- default:
- exploreTransform(base, ob, ob->parent, NULL);
- }
- }
- }
+ for (Base *base = static_cast<Base *>(m_settings.view_layer->object_bases.first); base;
+ base = base->next) {
+ Object *ob = base->object;
+
+ if (export_object(&m_settings, base, false)) {
+ switch (ob->type) {
+ case OB_LAMP:
+ case OB_LATTICE:
+ case OB_SPEAKER:
+ /* We do not export transforms for objects of these classes. */
+ break;
+ default:
+ exploreTransform(base, ob, ob->parent, NULL);
+ }
+ }
+ }
}
-void AbcExporter::exploreTransform(Base *base, Object *object, Object *parent, Object *dupliObParent)
+void AbcExporter::exploreTransform(Base *base,
+ Object *object,
+ Object *parent,
+ Object *dupliObParent)
{
- /* If an object isn't exported itself, its duplilist shouldn't be
- * exported either. */
- if (!export_object(&m_settings, base, dupliObParent != NULL)) {
- return;
- }
-
- Object *ob = DEG_get_evaluated_object(m_settings.depsgraph, object);
- if (object_type_is_exportable(m_settings.scene, ob)) {
- createTransformWriter(ob, parent, dupliObParent);
- }
-
- ListBase *lb = object_duplilist(m_settings.depsgraph, m_settings.scene, ob);
-
- if (lb) {
- DupliObject *link = static_cast<DupliObject *>(lb->first);
- Object *dupli_ob = NULL;
- Object *dupli_parent = NULL;
-
- for (; link; link = link->next) {
- /* This skips things like custom bone shapes. */
- if (m_settings.renderable_only && link->no_draw) {
- continue;
- }
-
- if (link->type == OB_DUPLICOLLECTION) {
- dupli_ob = link->ob;
- dupli_parent = (dupli_ob->parent) ? dupli_ob->parent : ob;
-
- exploreTransform(base, dupli_ob, dupli_parent, ob);
- }
- }
-
- free_object_duplilist(lb);
- }
+ /* If an object isn't exported itself, its duplilist shouldn't be
+ * exported either. */
+ if (!export_object(&m_settings, base, dupliObParent != NULL)) {
+ return;
+ }
+
+ Object *ob = DEG_get_evaluated_object(m_settings.depsgraph, object);
+ if (object_type_is_exportable(m_settings.scene, ob)) {
+ createTransformWriter(ob, parent, dupliObParent);
+ }
+
+ ListBase *lb = object_duplilist(m_settings.depsgraph, m_settings.scene, ob);
+
+ if (lb) {
+ DupliObject *link = static_cast<DupliObject *>(lb->first);
+ Object *dupli_ob = NULL;
+ Object *dupli_parent = NULL;
+
+ for (; link; link = link->next) {
+ /* This skips things like custom bone shapes. */
+ if (m_settings.renderable_only && link->no_draw) {
+ continue;
+ }
+
+ if (link->type == OB_DUPLICOLLECTION) {
+ dupli_ob = link->ob;
+ dupli_parent = (dupli_ob->parent) ? dupli_ob->parent : ob;
+
+ exploreTransform(base, dupli_ob, dupli_parent, ob);
+ }
+ }
+
+ free_object_duplilist(lb);
+ }
}
-AbcTransformWriter *AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupliObParent)
+AbcTransformWriter *AbcExporter::createTransformWriter(Object *ob,
+ Object *parent,
+ Object *dupliObParent)
{
- /* An object should not be its own parent, or we'll get infinite loops. */
- BLI_assert(ob != parent);
- BLI_assert(ob != dupliObParent);
-
- std::string name;
- if (m_settings.flatten_hierarchy) {
- name = get_id_name(ob);
- }
- else {
- name = get_object_dag_path_name(ob, dupliObParent);
- }
-
- /* check if we have already created a transform writer for this object */
- AbcTransformWriter *my_writer = getXForm(name);
- if (my_writer != NULL) {
- return my_writer;
- }
-
- AbcTransformWriter *parent_writer = NULL;
- Alembic::Abc::OObject alembic_parent;
-
- if (m_settings.flatten_hierarchy || parent == NULL) {
- /* Parentless objects still have the "top object" as parent
- * in Alembic. */
- alembic_parent = m_writer->archive().getTop();
- }
- else {
- /* Since there are so many different ways to find parents (as evident
- * in the number of conditions below), we can't really look up the
- * parent by name. We'll just call createTransformWriter(), which will
- * return the parent's AbcTransformWriter pointer. */
- if (parent->parent) {
- if (parent == dupliObParent) {
- parent_writer = createTransformWriter(parent, parent->parent, NULL);
- }
- else {
- parent_writer = createTransformWriter(parent, parent->parent, dupliObParent);
- }
- }
- else if (parent == dupliObParent) {
- if (dupliObParent->parent == NULL) {
- parent_writer = createTransformWriter(parent, NULL, NULL);
- }
- else {
- parent_writer = createTransformWriter(parent, dupliObParent->parent, dupliObParent->parent);
- }
- }
- else {
- parent_writer = createTransformWriter(parent, dupliObParent, dupliObParent);
- }
-
- BLI_assert(parent_writer);
- alembic_parent = parent_writer->alembicXform();
- }
-
- my_writer = new AbcTransformWriter(ob, alembic_parent, parent_writer,
- m_trans_sampling_index, m_settings);
-
- /* When flattening, the matrix of the dupliobject has to be added. */
- if (m_settings.flatten_hierarchy && dupliObParent) {
- my_writer->m_proxy_from = dupliObParent;
- }
-
- m_xforms[name] = my_writer;
- return my_writer;
+ /* An object should not be its own parent, or we'll get infinite loops. */
+ BLI_assert(ob != parent);
+ BLI_assert(ob != dupliObParent);
+
+ std::string name;
+ if (m_settings.flatten_hierarchy) {
+ name = get_id_name(ob);
+ }
+ else {
+ name = get_object_dag_path_name(ob, dupliObParent);
+ }
+
+ /* check if we have already created a transform writer for this object */
+ AbcTransformWriter *my_writer = getXForm(name);
+ if (my_writer != NULL) {
+ return my_writer;
+ }
+
+ AbcTransformWriter *parent_writer = NULL;
+ Alembic::Abc::OObject alembic_parent;
+
+ if (m_settings.flatten_hierarchy || parent == NULL) {
+ /* Parentless objects still have the "top object" as parent
+ * in Alembic. */
+ alembic_parent = m_writer->archive().getTop();
+ }
+ else {
+ /* Since there are so many different ways to find parents (as evident
+ * in the number of conditions below), we can't really look up the
+ * parent by name. We'll just call createTransformWriter(), which will
+ * return the parent's AbcTransformWriter pointer. */
+ if (parent->parent) {
+ if (parent == dupliObParent) {
+ parent_writer = createTransformWriter(parent, parent->parent, NULL);
+ }
+ else {
+ parent_writer = createTransformWriter(parent, parent->parent, dupliObParent);
+ }
+ }
+ else if (parent == dupliObParent) {
+ if (dupliObParent->parent == NULL) {
+ parent_writer = createTransformWriter(parent, NULL, NULL);
+ }
+ else {
+ parent_writer = createTransformWriter(
+ parent, dupliObParent->parent, dupliObParent->parent);
+ }
+ }
+ else {
+ parent_writer = createTransformWriter(parent, dupliObParent, dupliObParent);
+ }
+
+ BLI_assert(parent_writer);
+ alembic_parent = parent_writer->alembicXform();
+ }
+
+ my_writer = new AbcTransformWriter(
+ ob, alembic_parent, parent_writer, m_trans_sampling_index, m_settings);
+
+ /* When flattening, the matrix of the dupliobject has to be added. */
+ if (m_settings.flatten_hierarchy && dupliObParent) {
+ my_writer->m_proxy_from = dupliObParent;
+ }
+
+ m_xforms[name] = my_writer;
+ return my_writer;
}
void AbcExporter::createShapeWriters()
{
- for (Base *base = static_cast<Base *>(m_settings.view_layer->object_bases.first); base; base = base->next) {
- exploreObject(base, base->object, NULL);
- }
+ for (Base *base = static_cast<Base *>(m_settings.view_layer->object_bases.first); base;
+ base = base->next) {
+ exploreObject(base, base->object, NULL);
+ }
}
void AbcExporter::exploreObject(Base *base, Object *object, Object *dupliObParent)
{
- /* If an object isn't exported itself, its duplilist shouldn't be
- * exported either. */
- if (!export_object(&m_settings, base, dupliObParent != NULL)) {
- return;
- }
-
- Object *ob = DEG_get_evaluated_object(m_settings.depsgraph, object);
- createShapeWriter(ob, dupliObParent);
-
- ListBase *lb = object_duplilist(m_settings.depsgraph, m_settings.scene, ob);
-
- if (lb) {
- DupliObject *link = static_cast<DupliObject *>(lb->first);
-
- for (; link; link = link->next) {
- /* This skips things like custom bone shapes. */
- if (m_settings.renderable_only && link->no_draw) {
- continue;
- }
- if (link->type == OB_DUPLICOLLECTION) {
- exploreObject(base, link->ob, ob);
- }
- }
-
- free_object_duplilist(lb);
- }
+ /* If an object isn't exported itself, its duplilist shouldn't be
+ * exported either. */
+ if (!export_object(&m_settings, base, dupliObParent != NULL)) {
+ return;
+ }
+
+ Object *ob = DEG_get_evaluated_object(m_settings.depsgraph, object);
+ createShapeWriter(ob, dupliObParent);
+
+ ListBase *lb = object_duplilist(m_settings.depsgraph, m_settings.scene, ob);
+
+ if (lb) {
+ DupliObject *link = static_cast<DupliObject *>(lb->first);
+
+ for (; link; link = link->next) {
+ /* This skips things like custom bone shapes. */
+ if (m_settings.renderable_only && link->no_draw) {
+ continue;
+ }
+ if (link->type == OB_DUPLICOLLECTION) {
+ exploreObject(base, link->ob, ob);
+ }
+ }
+
+ free_object_duplilist(lb);
+ }
}
void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *xform)
{
- if (!m_settings.export_hair && !m_settings.export_particles) {
- return;
- }
-
- ParticleSystem *psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
-
- for (; psys; psys = psys->next) {
- if (!psys_check_enabled(ob, psys, G.is_rendering) || !psys->part) {
- continue;
- }
-
- if (m_settings.export_hair && psys->part->type == PART_HAIR) {
- m_settings.export_child_hairs = true;
- m_shapes.push_back(new AbcHairWriter(ob, xform, m_shape_sampling_index, m_settings, psys));
- }
- else if (m_settings.export_particles && psys->part->type == PART_EMITTER) {
- m_shapes.push_back(new AbcPointsWriter(ob, xform, m_shape_sampling_index, m_settings, psys));
- }
- }
+ if (!m_settings.export_hair && !m_settings.export_particles) {
+ return;
+ }
+
+ ParticleSystem *psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
+
+ for (; psys; psys = psys->next) {
+ if (!psys_check_enabled(ob, psys, G.is_rendering) || !psys->part) {
+ continue;
+ }
+
+ if (m_settings.export_hair && psys->part->type == PART_HAIR) {
+ m_settings.export_child_hairs = true;
+ m_shapes.push_back(new AbcHairWriter(ob, xform, m_shape_sampling_index, m_settings, psys));
+ }
+ else if (m_settings.export_particles && psys->part->type == PART_EMITTER) {
+ m_shapes.push_back(new AbcPointsWriter(ob, xform, m_shape_sampling_index, m_settings, psys));
+ }
+ }
}
void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
{
- if (!object_type_is_exportable(m_settings.scene, ob)) {
- return;
- }
-
- std::string name;
-
- if (m_settings.flatten_hierarchy) {
- name = get_id_name(ob);
- }
- else {
- name = get_object_dag_path_name(ob, dupliObParent);
- }
-
- AbcTransformWriter *xform = getXForm(name);
-
- if (!xform) {
- ABC_LOG(m_settings.logger) << __func__ << ": xform " << name << " is NULL\n";
- return;
- }
-
- createParticleSystemsWriters(ob, xform);
-
- switch (ob->type) {
- case OB_MESH:
- {
- Mesh *me = static_cast<Mesh *>(ob->data);
-
- if (!me) {
- return;
- }
-
- m_shapes.push_back(new AbcMeshWriter(ob, xform, m_shape_sampling_index, m_settings));
- break;
- }
- case OB_SURF:
- {
- Curve *cu = static_cast<Curve *>(ob->data);
-
- if (!cu) {
- return;
- }
-
- AbcObjectWriter *writer;
- if (m_settings.curves_as_mesh) {
- writer = new AbcCurveMeshWriter(ob, xform, m_shape_sampling_index, m_settings);
- }
- else {
- writer = new AbcNurbsWriter(ob, xform, m_shape_sampling_index, m_settings);
- }
- m_shapes.push_back(writer);
- break;
- }
- case OB_CURVE:
- {
- Curve *cu = static_cast<Curve *>(ob->data);
-
- if (!cu) {
- return;
- }
-
- AbcObjectWriter *writer;
- if (m_settings.curves_as_mesh) {
- writer = new AbcCurveMeshWriter(ob, xform, m_shape_sampling_index, m_settings);
- }
- else {
- writer = new AbcCurveWriter(ob, xform, m_shape_sampling_index, m_settings);
- }
- m_shapes.push_back(writer);
- break;
- }
- case OB_CAMERA:
- {
- Camera *cam = static_cast<Camera *>(ob->data);
-
- if (cam->type == CAM_PERSP) {
- m_shapes.push_back(new AbcCameraWriter(ob, xform, m_shape_sampling_index, m_settings));
- }
-
- break;
- }
- case OB_MBALL:
- {
- MetaBall *mball = static_cast<MetaBall *>(ob->data);
- if (!mball) {
- return;
- }
-
- m_shapes.push_back(new AbcMBallWriter(
- m_bmain, ob, xform,
- m_shape_sampling_index, m_settings));
- break;
- }
- }
+ if (!object_type_is_exportable(m_settings.scene, ob)) {
+ return;
+ }
+
+ std::string name;
+
+ if (m_settings.flatten_hierarchy) {
+ name = get_id_name(ob);
+ }
+ else {
+ name = get_object_dag_path_name(ob, dupliObParent);
+ }
+
+ AbcTransformWriter *xform = getXForm(name);
+
+ if (!xform) {
+ ABC_LOG(m_settings.logger) << __func__ << ": xform " << name << " is NULL\n";
+ return;
+ }
+
+ createParticleSystemsWriters(ob, xform);
+
+ switch (ob->type) {
+ case OB_MESH: {
+ Mesh *me = static_cast<Mesh *>(ob->data);
+
+ if (!me) {
+ return;
+ }
+
+ m_shapes.push_back(new AbcMeshWriter(ob, xform, m_shape_sampling_index, m_settings));
+ break;
+ }
+ case OB_SURF: {
+ Curve *cu = static_cast<Curve *>(ob->data);
+
+ if (!cu) {
+ return;
+ }
+
+ AbcObjectWriter *writer;
+ if (m_settings.curves_as_mesh) {
+ writer = new AbcCurveMeshWriter(ob, xform, m_shape_sampling_index, m_settings);
+ }
+ else {
+ writer = new AbcNurbsWriter(ob, xform, m_shape_sampling_index, m_settings);
+ }
+ m_shapes.push_back(writer);
+ break;
+ }
+ case OB_CURVE: {
+ Curve *cu = static_cast<Curve *>(ob->data);
+
+ if (!cu) {
+ return;
+ }
+
+ AbcObjectWriter *writer;
+ if (m_settings.curves_as_mesh) {
+ writer = new AbcCurveMeshWriter(ob, xform, m_shape_sampling_index, m_settings);
+ }
+ else {
+ writer = new AbcCurveWriter(ob, xform, m_shape_sampling_index, m_settings);
+ }
+ m_shapes.push_back(writer);
+ break;
+ }
+ case OB_CAMERA: {
+ Camera *cam = static_cast<Camera *>(ob->data);
+
+ if (cam->type == CAM_PERSP) {
+ m_shapes.push_back(new AbcCameraWriter(ob, xform, m_shape_sampling_index, m_settings));
+ }
+
+ break;
+ }
+ case OB_MBALL: {
+ MetaBall *mball = static_cast<MetaBall *>(ob->data);
+ if (!mball) {
+ return;
+ }
+
+ m_shapes.push_back(
+ new AbcMBallWriter(m_bmain, ob, xform, m_shape_sampling_index, m_settings));
+ break;
+ }
+ }
}
AbcTransformWriter *AbcExporter::getXForm(const std::string &name)
{
- std::map<std::string, AbcTransformWriter *>::iterator it = m_xforms.find(name);
+ std::map<std::string, AbcTransformWriter *>::iterator it = m_xforms.find(name);
- if (it == m_xforms.end()) {
- return NULL;
- }
+ if (it == m_xforms.end()) {
+ return NULL;
+ }
- return it->second;
+ return it->second;
}
void AbcExporter::setCurrentFrame(Main *bmain, double t)
{
- m_settings.scene->r.cfra = static_cast<int>(t);
- m_settings.scene->r.subframe = static_cast<float>(t) - m_settings.scene->r.cfra;
- BKE_scene_graph_update_for_newframe(m_settings.depsgraph, bmain);
+ m_settings.scene->r.cfra = static_cast<int>(t);
+ m_settings.scene->r.subframe = static_cast<float>(t) - m_settings.scene->r.cfra;
+ BKE_scene_graph_update_for_newframe(m_settings.depsgraph, bmain);
}
diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h
index 5e00ccdff07..6ed6a97f935 100644
--- a/source/blender/alembic/intern/abc_exporter.h
+++ b/source/blender/alembic/intern/abc_exporter.h
@@ -40,91 +40,92 @@ struct Scene;
struct ViewLayer;
struct ExportSettings {
- ExportSettings();
-
- Scene *scene;
- ViewLayer *view_layer; // Scene layer to export; all its objects will be exported, unless selected_only=true
- Depsgraph *depsgraph;
- SimpleLogger logger;
-
- bool selected_only;
- bool visible_layers_only;
- bool renderable_only;
-
- double frame_start, frame_end;
- double frame_samples_xform;
- double frame_samples_shape;
- double shutter_open;
- double shutter_close;
- float global_scale;
-
- bool flatten_hierarchy;
-
- bool export_normals;
- bool export_uvs;
- bool export_vcols;
- bool export_face_sets;
- bool export_vweigths;
- bool export_hair;
- bool export_particles;
-
- bool apply_subdiv;
- bool curves_as_mesh;
- bool use_subdiv_schema;
- 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];
+ ExportSettings();
+
+ Scene *scene;
+ ViewLayer *
+ view_layer; // Scene layer to export; all its objects will be exported, unless selected_only=true
+ Depsgraph *depsgraph;
+ SimpleLogger logger;
+
+ bool selected_only;
+ bool visible_layers_only;
+ bool renderable_only;
+
+ double frame_start, frame_end;
+ double frame_samples_xform;
+ double frame_samples_shape;
+ double shutter_open;
+ double shutter_close;
+ float global_scale;
+
+ bool flatten_hierarchy;
+
+ bool export_normals;
+ bool export_uvs;
+ bool export_vcols;
+ bool export_face_sets;
+ bool export_vweigths;
+ bool export_hair;
+ bool export_particles;
+
+ bool apply_subdiv;
+ bool curves_as_mesh;
+ bool use_subdiv_schema;
+ 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];
};
class AbcExporter {
- Main *m_bmain;
- ExportSettings &m_settings;
+ Main *m_bmain;
+ ExportSettings &m_settings;
- const char *m_filename;
+ const char *m_filename;
- unsigned int m_trans_sampling_index, m_shape_sampling_index;
+ unsigned int m_trans_sampling_index, m_shape_sampling_index;
- ArchiveWriter *m_writer;
+ ArchiveWriter *m_writer;
- /* mapping from name to transform writer */
- typedef std::map<std::string, AbcTransformWriter *> m_xforms_type;
- m_xforms_type m_xforms;
+ /* mapping from name to transform writer */
+ typedef std::map<std::string, AbcTransformWriter *> m_xforms_type;
+ m_xforms_type m_xforms;
- std::vector<AbcObjectWriter *> m_shapes;
+ std::vector<AbcObjectWriter *> m_shapes;
-public:
- AbcExporter(Main *bmain, const char *filename, ExportSettings &settings);
- ~AbcExporter();
+ public:
+ AbcExporter(Main *bmain, const char *filename, ExportSettings &settings);
+ ~AbcExporter();
- void operator()(float &progress, bool &was_canceled);
+ void operator()(float &progress, bool &was_canceled);
-protected:
- void getShutterSamples(unsigned int nr_of_samples,
- bool time_relative,
- std::vector<double> &samples);
- void getFrameSet(unsigned int nr_of_samples, std::set<double> &frames);
+ protected:
+ void getShutterSamples(unsigned int nr_of_samples,
+ bool time_relative,
+ std::vector<double> &samples);
+ void getFrameSet(unsigned int nr_of_samples, std::set<double> &frames);
-private:
- Alembic::Abc::TimeSamplingPtr createTimeSampling(double step);
+ private:
+ Alembic::Abc::TimeSamplingPtr createTimeSampling(double step);
- void createTransformWritersHierarchy();
- AbcTransformWriter *createTransformWriter(Object *ob, Object *parent, Object *dupliObParent);
- void exploreTransform(Base *base, Object *object, Object *parent, Object *dupliObParent);
- void exploreObject(Base *base, Object *object, Object *dupliObParent);
- void createShapeWriters();
- void createShapeWriter(Object *ob, Object *dupliObParent);
- void createParticleSystemsWriters(Object *ob, AbcTransformWriter *xform);
+ void createTransformWritersHierarchy();
+ AbcTransformWriter *createTransformWriter(Object *ob, Object *parent, Object *dupliObParent);
+ void exploreTransform(Base *base, Object *object, Object *parent, Object *dupliObParent);
+ void exploreObject(Base *base, Object *object, Object *dupliObParent);
+ void createShapeWriters();
+ void createShapeWriter(Object *ob, Object *dupliObParent);
+ void createParticleSystemsWriters(Object *ob, AbcTransformWriter *xform);
- AbcTransformWriter *getXForm(const std::string &name);
+ AbcTransformWriter *getXForm(const std::string &name);
- void setCurrentFrame(Main *bmain, double t);
+ void setCurrentFrame(Main *bmain, double t);
};
-#endif /* __ABC_EXPORTER_H__ */
+#endif /* __ABC_EXPORTER_H__ */
diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc
index a587e2a2cd1..b2489169856 100644
--- a/source/blender/alembic/intern/abc_hair.cc
+++ b/source/blender/alembic/intern/abc_hair.cc
@@ -55,58 +55,58 @@ AbcHairWriter::AbcHairWriter(Object *ob,
uint32_t time_sampling,
ExportSettings &settings,
ParticleSystem *psys)
- : AbcObjectWriter(ob, time_sampling, settings, parent)
- , m_uv_warning_shown(false)
+ : AbcObjectWriter(ob, time_sampling, settings, parent), m_uv_warning_shown(false)
{
- m_psys = psys;
+ m_psys = psys;
- OCurves curves(parent->alembicXform(), psys->name, m_time_sampling);
- m_schema = curves.getSchema();
+ OCurves curves(parent->alembicXform(), psys->name, m_time_sampling);
+ m_schema = curves.getSchema();
}
void AbcHairWriter::do_write()
{
- if (!m_psys) {
- return;
- }
- Mesh *mesh = mesh_get_eval_final(m_settings.depsgraph, m_settings.scene, m_object, &CD_MASK_MESH);
- BKE_mesh_tessface_ensure(mesh);
-
- std::vector<Imath::V3f> verts;
- std::vector<int32_t> hvertices;
- std::vector<Imath::V2f> uv_values;
- std::vector<Imath::V3f> norm_values;
-
- if (m_psys->pathcache) {
- ParticleSettings *part = m_psys->part;
-
- write_hair_sample(mesh, part, verts, norm_values, uv_values, hvertices);
-
- if (m_settings.export_child_hairs && m_psys->childcache) {
- write_hair_child_sample(mesh, part, verts, norm_values, uv_values, hvertices);
- }
- }
-
- Alembic::Abc::P3fArraySample iPos(verts);
- m_sample = OCurvesSchema::Sample(iPos, hvertices);
- m_sample.setBasis(Alembic::AbcGeom::kNoBasis);
- m_sample.setType(Alembic::AbcGeom::kLinear);
- m_sample.setWrap(Alembic::AbcGeom::kNonPeriodic);
-
- if (!uv_values.empty()) {
- OV2fGeomParam::Sample uv_smp;
- uv_smp.setVals(uv_values);
- m_sample.setUVs(uv_smp);
- }
-
- if (!norm_values.empty()) {
- ON3fGeomParam::Sample norm_smp;
- norm_smp.setVals(norm_values);
- m_sample.setNormals(norm_smp);
- }
-
- m_sample.setSelfBounds(bounds());
- m_schema.set(m_sample);
+ if (!m_psys) {
+ return;
+ }
+ Mesh *mesh = mesh_get_eval_final(
+ m_settings.depsgraph, m_settings.scene, m_object, &CD_MASK_MESH);
+ BKE_mesh_tessface_ensure(mesh);
+
+ std::vector<Imath::V3f> verts;
+ std::vector<int32_t> hvertices;
+ std::vector<Imath::V2f> uv_values;
+ std::vector<Imath::V3f> norm_values;
+
+ if (m_psys->pathcache) {
+ ParticleSettings *part = m_psys->part;
+
+ write_hair_sample(mesh, part, verts, norm_values, uv_values, hvertices);
+
+ if (m_settings.export_child_hairs && m_psys->childcache) {
+ write_hair_child_sample(mesh, part, verts, norm_values, uv_values, hvertices);
+ }
+ }
+
+ Alembic::Abc::P3fArraySample iPos(verts);
+ m_sample = OCurvesSchema::Sample(iPos, hvertices);
+ m_sample.setBasis(Alembic::AbcGeom::kNoBasis);
+ m_sample.setType(Alembic::AbcGeom::kLinear);
+ m_sample.setWrap(Alembic::AbcGeom::kNonPeriodic);
+
+ if (!uv_values.empty()) {
+ OV2fGeomParam::Sample uv_smp;
+ uv_smp.setVals(uv_values);
+ m_sample.setUVs(uv_smp);
+ }
+
+ if (!norm_values.empty()) {
+ ON3fGeomParam::Sample norm_smp;
+ norm_smp.setVals(norm_values);
+ m_sample.setNormals(norm_smp);
+ }
+
+ m_sample.setSelfBounds(bounds());
+ m_schema.set(m_sample);
}
void AbcHairWriter::write_hair_sample(Mesh *mesh,
@@ -116,109 +116,109 @@ void AbcHairWriter::write_hair_sample(Mesh *mesh,
std::vector<Imath::V2f> &uv_values,
std::vector<int32_t> &hvertices)
{
- /* Get untransformed vertices, there's a xform under the hair. */
- float inv_mat[4][4];
- invert_m4_m4_safe(inv_mat, m_object->obmat);
-
- MTFace *mtface = mesh->mtface;
- MFace *mface = mesh->mface;
- MVert *mverts = mesh->mvert;
-
- if ((!mtface || !mface) && !m_uv_warning_shown) {
- std::fprintf(stderr, "Warning, no UV set found for underlying geometry of %s.\n",
- m_object->id.name + 2);
- m_uv_warning_shown = true;
- }
-
- ParticleData *pa = m_psys->particles;
- int k;
-
- ParticleCacheKey **cache = m_psys->pathcache;
- ParticleCacheKey *path;
- float normal[3];
- Imath::V3f tmp_nor;
-
- for (int p = 0; p < m_psys->totpart; ++p, ++pa) {
- /* underlying info for faces-only emission */
- path = cache[p];
-
- /* Write UV and normal vectors */
- if (part->from == PART_FROM_FACE && mtface) {
- const int num = pa->num_dmcache >= 0 ? pa->num_dmcache : pa->num;
-
- if (num < mesh->totface) {
- /* TODO(Sybren): check whether the NULL check here and if(mface) are actually required */
- MFace *face = mface == NULL ? NULL : &mface[num];
- MTFace *tface = mtface + num;
-
- if (mface) {
- float r_uv[2], mapfw[4], vec[3];
-
- psys_interpolate_uvs(tface, face->v4, pa->fuv, r_uv);
- uv_values.push_back(Imath::V2f(r_uv[0], r_uv[1]));
-
- psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, normal, NULL, NULL, NULL);
-
- copy_yup_from_zup(tmp_nor.getValue(), normal);
- norm_values.push_back(tmp_nor);
- }
- }
- else {
- std::fprintf(stderr, "Particle to faces overflow (%d/%d)\n", num, mesh->totface);
- }
- }
- else if (part->from == PART_FROM_VERT && mtface) {
- /* vertex id */
- const int num = (pa->num_dmcache >= 0) ? pa->num_dmcache : pa->num;
-
- /* iterate over all faces to find a corresponding underlying UV */
- for (int n = 0; n < mesh->totface; ++n) {
- MFace *face = &mface[n];
- MTFace *tface = mtface + n;
- unsigned int vtx[4];
- vtx[0] = face->v1;
- vtx[1] = face->v2;
- vtx[2] = face->v3;
- vtx[3] = face->v4;
- bool found = false;
-
- for (int o = 0; o < 4; ++o) {
- if (o > 2 && vtx[o] == 0) {
- break;
- }
-
- if (vtx[o] == num) {
- uv_values.push_back(Imath::V2f(tface->uv[o][0], tface->uv[o][1]));
-
- MVert *mv = mverts + vtx[o];
-
- normal_short_to_float_v3(normal, mv->no);
- copy_yup_from_zup(tmp_nor.getValue(), normal);
- norm_values.push_back(tmp_nor);
- found = true;
- break;
- }
- }
-
- if (found) {
- break;
- }
- }
- }
-
- int steps = path->segments + 1;
- hvertices.push_back(steps);
-
- for (k = 0; k < steps; ++k, ++path) {
- float vert[3];
- copy_v3_v3(vert, path->co);
- mul_m4_v3(inv_mat, vert);
-
- /* Convert Z-up to Y-up. */
- verts.push_back(Imath::V3f(vert[0], vert[2], -vert[1]));
-
- }
- }
+ /* Get untransformed vertices, there's a xform under the hair. */
+ float inv_mat[4][4];
+ invert_m4_m4_safe(inv_mat, m_object->obmat);
+
+ MTFace *mtface = mesh->mtface;
+ MFace *mface = mesh->mface;
+ MVert *mverts = mesh->mvert;
+
+ if ((!mtface || !mface) && !m_uv_warning_shown) {
+ std::fprintf(stderr,
+ "Warning, no UV set found for underlying geometry of %s.\n",
+ m_object->id.name + 2);
+ m_uv_warning_shown = true;
+ }
+
+ ParticleData *pa = m_psys->particles;
+ int k;
+
+ ParticleCacheKey **cache = m_psys->pathcache;
+ ParticleCacheKey *path;
+ float normal[3];
+ Imath::V3f tmp_nor;
+
+ for (int p = 0; p < m_psys->totpart; ++p, ++pa) {
+ /* underlying info for faces-only emission */
+ path = cache[p];
+
+ /* Write UV and normal vectors */
+ if (part->from == PART_FROM_FACE && mtface) {
+ const int num = pa->num_dmcache >= 0 ? pa->num_dmcache : pa->num;
+
+ if (num < mesh->totface) {
+ /* TODO(Sybren): check whether the NULL check here and if(mface) are actually required */
+ MFace *face = mface == NULL ? NULL : &mface[num];
+ MTFace *tface = mtface + num;
+
+ if (mface) {
+ float r_uv[2], mapfw[4], vec[3];
+
+ psys_interpolate_uvs(tface, face->v4, pa->fuv, r_uv);
+ uv_values.push_back(Imath::V2f(r_uv[0], r_uv[1]));
+
+ psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, normal, NULL, NULL, NULL);
+
+ copy_yup_from_zup(tmp_nor.getValue(), normal);
+ norm_values.push_back(tmp_nor);
+ }
+ }
+ else {
+ std::fprintf(stderr, "Particle to faces overflow (%d/%d)\n", num, mesh->totface);
+ }
+ }
+ else if (part->from == PART_FROM_VERT && mtface) {
+ /* vertex id */
+ const int num = (pa->num_dmcache >= 0) ? pa->num_dmcache : pa->num;
+
+ /* iterate over all faces to find a corresponding underlying UV */
+ for (int n = 0; n < mesh->totface; ++n) {
+ MFace *face = &mface[n];
+ MTFace *tface = mtface + n;
+ unsigned int vtx[4];
+ vtx[0] = face->v1;
+ vtx[1] = face->v2;
+ vtx[2] = face->v3;
+ vtx[3] = face->v4;
+ bool found = false;
+
+ for (int o = 0; o < 4; ++o) {
+ if (o > 2 && vtx[o] == 0) {
+ break;
+ }
+
+ if (vtx[o] == num) {
+ uv_values.push_back(Imath::V2f(tface->uv[o][0], tface->uv[o][1]));
+
+ MVert *mv = mverts + vtx[o];
+
+ normal_short_to_float_v3(normal, mv->no);
+ copy_yup_from_zup(tmp_nor.getValue(), normal);
+ norm_values.push_back(tmp_nor);
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ break;
+ }
+ }
+ }
+
+ int steps = path->segments + 1;
+ hvertices.push_back(steps);
+
+ for (k = 0; k < steps; ++k, ++path) {
+ float vert[3];
+ copy_v3_v3(vert, path->co);
+ mul_m4_v3(inv_mat, vert);
+
+ /* Convert Z-up to Y-up. */
+ verts.push_back(Imath::V3f(vert[0], vert[2], -vert[1]));
+ }
+ }
}
void AbcHairWriter::write_hair_child_sample(Mesh *mesh,
@@ -228,68 +228,65 @@ void AbcHairWriter::write_hair_child_sample(Mesh *mesh,
std::vector<Imath::V2f> &uv_values,
std::vector<int32_t> &hvertices)
{
- /* Get untransformed vertices, there's a xform under the hair. */
- float inv_mat[4][4];
- invert_m4_m4_safe(inv_mat, m_object->obmat);
-
- MTFace *mtface = mesh->mtface;
- MVert *mverts = mesh->mvert;
-
- ParticleCacheKey **cache = m_psys->childcache;
- ParticleCacheKey *path;
-
- ChildParticle *pc = m_psys->child;
-
- for (int p = 0; p < m_psys->totchild; ++p, ++pc) {
- path = cache[p];
-
- if (part->from == PART_FROM_FACE &&
- part->childtype != PART_CHILD_PARTICLES &&
- mtface)
- {
- const int num = pc->num;
- if (num < 0) {
- ABC_LOG(m_settings.logger)
- << "Warning, child particle of hair system " << m_psys->name
- << " has unknown face index of geometry of "<< (m_object->id.name + 2)
- << ", skipping child hair." << std::endl;
- continue;
- }
-
- MFace *face = &mesh->mface[num];
- MTFace *tface = mtface + num;
-
- float r_uv[2], tmpnor[3], mapfw[4], vec[3];
-
- psys_interpolate_uvs(tface, face->v4, pc->fuv, r_uv);
- uv_values.push_back(Imath::V2f(r_uv[0], r_uv[1]));
-
- psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, tmpnor, NULL, NULL, NULL);
-
- /* Convert Z-up to Y-up. */
- norm_values.push_back(Imath::V3f(tmpnor[0], tmpnor[2], -tmpnor[1]));
- }
- else {
- if (uv_values.size()) {
- uv_values.push_back(uv_values[pc->parent]);
- }
- if (norm_values.size()) {
- norm_values.push_back(norm_values[pc->parent]);
- }
- }
-
- int steps = path->segments + 1;
- hvertices.push_back(steps);
-
- for (int k = 0; k < steps; ++k) {
- float vert[3];
- copy_v3_v3(vert, path->co);
- mul_m4_v3(inv_mat, vert);
-
- /* Convert Z-up to Y-up. */
- verts.push_back(Imath::V3f(vert[0], vert[2], -vert[1]));
-
- ++path;
- }
- }
+ /* Get untransformed vertices, there's a xform under the hair. */
+ float inv_mat[4][4];
+ invert_m4_m4_safe(inv_mat, m_object->obmat);
+
+ MTFace *mtface = mesh->mtface;
+ MVert *mverts = mesh->mvert;
+
+ ParticleCacheKey **cache = m_psys->childcache;
+ ParticleCacheKey *path;
+
+ ChildParticle *pc = m_psys->child;
+
+ for (int p = 0; p < m_psys->totchild; ++p, ++pc) {
+ path = cache[p];
+
+ if (part->from == PART_FROM_FACE && part->childtype != PART_CHILD_PARTICLES && mtface) {
+ const int num = pc->num;
+ if (num < 0) {
+ ABC_LOG(m_settings.logger)
+ << "Warning, child particle of hair system " << m_psys->name
+ << " has unknown face index of geometry of " << (m_object->id.name + 2)
+ << ", skipping child hair." << std::endl;
+ continue;
+ }
+
+ MFace *face = &mesh->mface[num];
+ MTFace *tface = mtface + num;
+
+ float r_uv[2], tmpnor[3], mapfw[4], vec[3];
+
+ psys_interpolate_uvs(tface, face->v4, pc->fuv, r_uv);
+ uv_values.push_back(Imath::V2f(r_uv[0], r_uv[1]));
+
+ psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, tmpnor, NULL, NULL, NULL);
+
+ /* Convert Z-up to Y-up. */
+ norm_values.push_back(Imath::V3f(tmpnor[0], tmpnor[2], -tmpnor[1]));
+ }
+ else {
+ if (uv_values.size()) {
+ uv_values.push_back(uv_values[pc->parent]);
+ }
+ if (norm_values.size()) {
+ norm_values.push_back(norm_values[pc->parent]);
+ }
+ }
+
+ int steps = path->segments + 1;
+ hvertices.push_back(steps);
+
+ for (int k = 0; k < steps; ++k) {
+ float vert[3];
+ copy_v3_v3(vert, path->co);
+ mul_m4_v3(inv_mat, vert);
+
+ /* Convert Z-up to Y-up. */
+ verts.push_back(Imath::V3f(vert[0], vert[2], -vert[1]));
+
+ ++path;
+ }
+ }
}
diff --git a/source/blender/alembic/intern/abc_hair.h b/source/blender/alembic/intern/abc_hair.h
index 7b6500196a3..21f665a4795 100644
--- a/source/blender/alembic/intern/abc_hair.h
+++ b/source/blender/alembic/intern/abc_hair.h
@@ -29,36 +29,36 @@ struct ParticleSystem;
/* ************************************************************************** */
class AbcHairWriter : public AbcObjectWriter {
- ParticleSystem *m_psys;
+ ParticleSystem *m_psys;
- Alembic::AbcGeom::OCurvesSchema m_schema;
- Alembic::AbcGeom::OCurvesSchema::Sample m_sample;
+ Alembic::AbcGeom::OCurvesSchema m_schema;
+ Alembic::AbcGeom::OCurvesSchema::Sample m_sample;
- bool m_uv_warning_shown;
+ bool m_uv_warning_shown;
-public:
- AbcHairWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings,
- ParticleSystem *psys);
+ public:
+ AbcHairWriter(Object *ob,
+ AbcTransformWriter *parent,
+ uint32_t time_sampling,
+ ExportSettings &settings,
+ ParticleSystem *psys);
-private:
- virtual void do_write();
+ private:
+ virtual void do_write();
- void write_hair_sample(struct Mesh *mesh,
- ParticleSettings *part,
- std::vector<Imath::V3f> &verts,
- std::vector<Imath::V3f> &norm_values,
- std::vector<Imath::V2f> &uv_values,
- std::vector<int32_t> &hvertices);
+ void write_hair_sample(struct Mesh *mesh,
+ ParticleSettings *part,
+ std::vector<Imath::V3f> &verts,
+ std::vector<Imath::V3f> &norm_values,
+ std::vector<Imath::V2f> &uv_values,
+ std::vector<int32_t> &hvertices);
- void write_hair_child_sample(struct Mesh *mesh,
- ParticleSettings *part,
- std::vector<Imath::V3f> &verts,
- std::vector<Imath::V3f> &norm_values,
- std::vector<Imath::V2f> &uv_values,
- std::vector<int32_t> &hvertices);
+ void write_hair_child_sample(struct Mesh *mesh,
+ ParticleSettings *part,
+ std::vector<Imath::V3f> &verts,
+ std::vector<Imath::V3f> &norm_values,
+ std::vector<Imath::V2f> &uv_values,
+ std::vector<int32_t> &hvertices);
};
-#endif /* __ABC_HAIR_H__ */
+#endif /* __ABC_HAIR_H__ */
diff --git a/source/blender/alembic/intern/abc_mball.cc b/source/blender/alembic/intern/abc_mball.cc
index bb6ab57643f..3ee26a5081a 100644
--- a/source/blender/alembic/intern/abc_mball.cc
+++ b/source/blender/alembic/intern/abc_mball.cc
@@ -38,64 +38,62 @@ extern "C" {
#include "MEM_guardedalloc.h"
}
-AbcMBallWriter::AbcMBallWriter(
- Main *bmain,
- Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings)
- : AbcGenericMeshWriter(ob, parent, time_sampling, settings)
- , m_bmain(bmain)
+AbcMBallWriter::AbcMBallWriter(Main *bmain,
+ Object *ob,
+ AbcTransformWriter *parent,
+ uint32_t time_sampling,
+ ExportSettings &settings)
+ : AbcGenericMeshWriter(ob, parent, time_sampling, settings), m_bmain(bmain)
{
- m_is_animated = isAnimated();
+ m_is_animated = isAnimated();
}
-
AbcMBallWriter::~AbcMBallWriter()
-{}
+{
+}
bool AbcMBallWriter::isAnimated() const
{
- return true;
+ return true;
}
Mesh *AbcMBallWriter::getEvaluatedMesh(Scene * /*scene_eval*/, Object *ob_eval, bool &r_needsfree)
{
- if (ob_eval->runtime.mesh_eval != NULL) {
- /* Mesh_eval only exists when generative modifiers are in use. */
- r_needsfree = false;
- return ob_eval->runtime.mesh_eval;
- }
- r_needsfree = true;
-
- /* The approach below is copied from BKE_mesh_new_from_object() */
- Mesh *tmpmesh = BKE_mesh_add(m_bmain, ((ID *)m_object->data)->name + 2);
- BLI_assert(tmpmesh != NULL);
-
- /* BKE_mesh_add gives us a user count we don't need */
- id_us_min(&tmpmesh->id);
-
- ListBase disp = {NULL, NULL};
- /* TODO(sergey): This is gonna to work for until Depsgraph
- * only contains for_render flag. As soon as CoW is
- * implemented, this is to be rethinked.
- */
- BKE_displist_make_mball_forRender(m_settings.depsgraph, m_settings.scene, m_object, &disp);
- BKE_mesh_from_metaball(&disp, tmpmesh);
- BKE_displist_free(&disp);
-
- BKE_mesh_texspace_copy_from_object(tmpmesh, m_object);
-
- return tmpmesh;
+ if (ob_eval->runtime.mesh_eval != NULL) {
+ /* Mesh_eval only exists when generative modifiers are in use. */
+ r_needsfree = false;
+ return ob_eval->runtime.mesh_eval;
+ }
+ r_needsfree = true;
+
+ /* The approach below is copied from BKE_mesh_new_from_object() */
+ Mesh *tmpmesh = BKE_mesh_add(m_bmain, ((ID *)m_object->data)->name + 2);
+ BLI_assert(tmpmesh != NULL);
+
+ /* BKE_mesh_add gives us a user count we don't need */
+ id_us_min(&tmpmesh->id);
+
+ ListBase disp = {NULL, NULL};
+ /* TODO(sergey): This is gonna to work for until Depsgraph
+ * only contains for_render flag. As soon as CoW is
+ * implemented, this is to be rethinked.
+ */
+ BKE_displist_make_mball_forRender(m_settings.depsgraph, m_settings.scene, m_object, &disp);
+ BKE_mesh_from_metaball(&disp, tmpmesh);
+ BKE_displist_free(&disp);
+
+ BKE_mesh_texspace_copy_from_object(tmpmesh, m_object);
+
+ return tmpmesh;
}
void AbcMBallWriter::freeEvaluatedMesh(struct Mesh *mesh)
{
- BKE_id_free(m_bmain, mesh);
+ BKE_id_free(m_bmain, mesh);
}
bool AbcMBallWriter::isBasisBall(Scene *scene, Object *ob)
{
- Object *basis_ob = BKE_mball_basis_find(scene, ob);
- return ob == basis_ob;
+ Object *basis_ob = BKE_mball_basis_find(scene, ob);
+ return ob == basis_ob;
}
diff --git a/source/blender/alembic/intern/abc_mball.h b/source/blender/alembic/intern/abc_mball.h
index d2bdb8f297a..770fa6fdf8c 100644
--- a/source/blender/alembic/intern/abc_mball.h
+++ b/source/blender/alembic/intern/abc_mball.h
@@ -34,26 +34,25 @@ struct Object;
* to the Alembic file. Only the basis balls are exported, as this
* results in the entire shape as one mesh. */
class AbcMBallWriter : public AbcGenericMeshWriter {
- Main *m_bmain;
-public:
- explicit AbcMBallWriter(
- Main *bmain,
- Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings);
+ Main *m_bmain;
- ~AbcMBallWriter();
+ public:
+ explicit AbcMBallWriter(Main *bmain,
+ Object *ob,
+ AbcTransformWriter *parent,
+ uint32_t time_sampling,
+ ExportSettings &settings);
- static bool isBasisBall(Scene *scene, Object *ob);
+ ~AbcMBallWriter();
-protected:
- Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree) override;
- void freeEvaluatedMesh(struct Mesh *mesh) override;
+ static bool isBasisBall(Scene *scene, Object *ob);
-private:
- bool isAnimated() const override;
-};
+ protected:
+ Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree) override;
+ void freeEvaluatedMesh(struct Mesh *mesh) override;
+ private:
+ bool isAnimated() const override;
+};
-#endif /* __ABC_MBALL_H__ */
+#endif /* __ABC_MBALL_H__ */
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 97cd6ffc0e3..5ccb9be02a3 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -57,6 +57,7 @@ extern "C" {
#include "DEG_depsgraph_query.h"
}
+using Alembic::Abc::C4fArraySample;
using Alembic::Abc::FloatArraySample;
using Alembic::Abc::ICompoundProperty;
using Alembic::Abc::Int32ArraySample;
@@ -64,7 +65,6 @@ using Alembic::Abc::Int32ArraySamplePtr;
using Alembic::Abc::P3fArraySamplePtr;
using Alembic::Abc::V2fArraySample;
using Alembic::Abc::V3fArraySample;
-using Alembic::Abc::C4fArraySample;
using Alembic::AbcGeom::IFaceSet;
using Alembic::AbcGeom::IFaceSetSchema;
@@ -95,13 +95,13 @@ using Alembic::AbcGeom::OSubDSchema;
using Alembic::AbcGeom::OV2fGeomParam;
using Alembic::AbcGeom::OV3fGeomParam;
+using Alembic::AbcGeom::IN3fGeomParam;
using Alembic::AbcGeom::kFacevaryingScope;
using Alembic::AbcGeom::kVaryingScope;
using Alembic::AbcGeom::kVertexScope;
using Alembic::AbcGeom::kWrapExisting;
-using Alembic::AbcGeom::UInt32ArraySample;
using Alembic::AbcGeom::N3fArraySamplePtr;
-using Alembic::AbcGeom::IN3fGeomParam;
+using Alembic::AbcGeom::UInt32ArraySample;
/* ************************************************************************** */
@@ -109,14 +109,14 @@ using Alembic::AbcGeom::IN3fGeomParam;
static void get_vertices(struct Mesh *mesh, std::vector<Imath::V3f> &points)
{
- points.clear();
- points.resize(mesh->totvert);
+ points.clear();
+ points.resize(mesh->totvert);
- MVert *verts = mesh->mvert;
+ MVert *verts = mesh->mvert;
- for (int i = 0, e = mesh->totvert; i < e; ++i) {
- copy_yup_from_zup(points[i].getValue(), verts[i].co);
- }
+ for (int i = 0, e = mesh->totvert; i < e; ++i) {
+ copy_yup_from_zup(points[i].getValue(), verts[i].co);
+ }
}
static void get_topology(struct Mesh *mesh,
@@ -124,29 +124,29 @@ static void get_topology(struct Mesh *mesh,
std::vector<int32_t> &loop_counts,
bool &smooth_normal)
{
- const int num_poly = mesh->totpoly;
- const int num_loops = mesh->totloop;
- MLoop *mloop = mesh->mloop;
- MPoly *mpoly = mesh->mpoly;
+ const int num_poly = mesh->totpoly;
+ const int num_loops = mesh->totloop;
+ MLoop *mloop = mesh->mloop;
+ MPoly *mpoly = mesh->mpoly;
- poly_verts.clear();
- loop_counts.clear();
- poly_verts.reserve(num_loops);
- loop_counts.reserve(num_poly);
+ poly_verts.clear();
+ loop_counts.clear();
+ poly_verts.reserve(num_loops);
+ loop_counts.reserve(num_poly);
- /* NOTE: data needs to be written in the reverse order. */
- for (int i = 0; i < num_poly; ++i) {
- MPoly &poly = mpoly[i];
- loop_counts.push_back(poly.totloop);
+ /* NOTE: data needs to be written in the reverse order. */
+ for (int i = 0; i < num_poly; ++i) {
+ MPoly &poly = mpoly[i];
+ loop_counts.push_back(poly.totloop);
- smooth_normal |= ((poly.flag & ME_SMOOTH) != 0);
+ smooth_normal |= ((poly.flag & ME_SMOOTH) != 0);
- MLoop *loop = mloop + poly.loopstart + (poly.totloop - 1);
+ MLoop *loop = mloop + poly.loopstart + (poly.totloop - 1);
- for (int j = 0; j < poly.totloop; ++j, --loop) {
- poly_verts.push_back(loop->v);
- }
- }
+ for (int j = 0; j < poly.totloop; ++j, --loop) {
+ poly_verts.push_back(loop->v);
+ }
+ }
}
static void get_creases(struct Mesh *mesh,
@@ -154,92 +154,92 @@ static void get_creases(struct Mesh *mesh,
std::vector<int32_t> &lengths,
std::vector<float> &sharpnesses)
{
- const float factor = 1.0f / 255.0f;
+ const float factor = 1.0f / 255.0f;
- indices.clear();
- lengths.clear();
- sharpnesses.clear();
+ indices.clear();
+ lengths.clear();
+ sharpnesses.clear();
- MEdge *edge = mesh->medge;
+ MEdge *edge = mesh->medge;
- for (int i = 0, e = mesh->totedge; i < e; ++i) {
- const float sharpness = static_cast<float>(edge[i].crease) * factor;
+ for (int i = 0, e = mesh->totedge; i < e; ++i) {
+ const float sharpness = static_cast<float>(edge[i].crease) * factor;
- if (sharpness != 0.0f) {
- indices.push_back(edge[i].v1);
- indices.push_back(edge[i].v2);
- sharpnesses.push_back(sharpness);
- }
- }
+ if (sharpness != 0.0f) {
+ indices.push_back(edge[i].v1);
+ indices.push_back(edge[i].v2);
+ sharpnesses.push_back(sharpness);
+ }
+ }
- lengths.resize(sharpnesses.size(), 2);
+ lengths.resize(sharpnesses.size(), 2);
}
static void get_vertex_normals(struct Mesh *mesh, std::vector<Imath::V3f> &normals)
{
- normals.clear();
- normals.resize(mesh->totvert);
+ normals.clear();
+ normals.resize(mesh->totvert);
- MVert *verts = mesh->mvert;
- float no[3];
+ MVert *verts = mesh->mvert;
+ float no[3];
- for (int i = 0, e = mesh->totvert; i < e; ++i) {
- normal_short_to_float_v3(no, verts[i].no);
- copy_yup_from_zup(normals[i].getValue(), no);
- }
+ for (int i = 0, e = mesh->totvert; i < e; ++i) {
+ normal_short_to_float_v3(no, verts[i].no);
+ copy_yup_from_zup(normals[i].getValue(), no);
+ }
}
static void get_loop_normals(struct Mesh *mesh, std::vector<Imath::V3f> &normals)
{
- MPoly *mp = mesh->mpoly;
-
- MLoop *mloop = mesh->mloop;
- MLoop *ml = mloop;
-
- MVert *verts = mesh->mvert;
-
- const float (*lnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
-
- normals.clear();
- normals.resize(mesh->totloop);
-
- unsigned loop_index = 0;
-
- /* NOTE: data needs to be written in the reverse order. */
-
- if (lnors) {
- for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mp) {
- ml = mloop + mp->loopstart + (mp->totloop - 1);
-
- for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
- const int index = ml->v;
- copy_yup_from_zup(normals[loop_index].getValue(), lnors[index]);
- }
- }
- }
- else {
- float no[3];
-
- for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mp) {
- ml = mloop + mp->loopstart + (mp->totloop - 1);
-
- /* Flat shaded, use common normal for all verts. */
- if ((mp->flag & ME_SMOOTH) == 0) {
- BKE_mesh_calc_poly_normal(mp, ml - (mp->totloop - 1), verts, no);
-
- for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
- copy_yup_from_zup(normals[loop_index].getValue(), no);
- }
- }
- else {
- /* Smooth shaded, use individual vert normals. */
- for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
- normal_short_to_float_v3(no, verts[ml->v].no);
- copy_yup_from_zup(normals[loop_index].getValue(), no);
- }
- }
- }
- }
+ MPoly *mp = mesh->mpoly;
+
+ MLoop *mloop = mesh->mloop;
+ MLoop *ml = mloop;
+
+ MVert *verts = mesh->mvert;
+
+ const float(*lnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
+
+ normals.clear();
+ normals.resize(mesh->totloop);
+
+ unsigned loop_index = 0;
+
+ /* NOTE: data needs to be written in the reverse order. */
+
+ if (lnors) {
+ for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mp) {
+ ml = mloop + mp->loopstart + (mp->totloop - 1);
+
+ for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
+ const int index = ml->v;
+ copy_yup_from_zup(normals[loop_index].getValue(), lnors[index]);
+ }
+ }
+ }
+ else {
+ float no[3];
+
+ for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mp) {
+ ml = mloop + mp->loopstart + (mp->totloop - 1);
+
+ /* Flat shaded, use common normal for all verts. */
+ if ((mp->flag & ME_SMOOTH) == 0) {
+ BKE_mesh_calc_poly_normal(mp, ml - (mp->totloop - 1), verts, no);
+
+ for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
+ copy_yup_from_zup(normals[loop_index].getValue(), no);
+ }
+ }
+ else {
+ /* Smooth shaded, use individual vert normals. */
+ for (int j = 0; j < mp->totloop; --ml, ++j, ++loop_index) {
+ normal_short_to_float_v3(no, verts[ml->v].no);
+ copy_yup_from_zup(normals[loop_index].getValue(), no);
+ }
+ }
+ }
+ }
}
/* *************** Modifiers *************** */
@@ -248,43 +248,43 @@ static void get_loop_normals(struct Mesh *mesh, std::vector<Imath::V3f> &normals
* displace if it's after subsurf. */
static ModifierData *get_subsurf_modifier(Scene *scene, Object *ob)
{
- ModifierData *md = static_cast<ModifierData *>(ob->modifiers.last);
+ ModifierData *md = static_cast<ModifierData *>(ob->modifiers.last);
- for (; md; md = md->prev) {
- if (!modifier_isEnabled(scene, md, eModifierMode_Render)) {
- continue;
- }
+ for (; md; md = md->prev) {
+ if (!modifier_isEnabled(scene, md, eModifierMode_Render)) {
+ continue;
+ }
- if (md->type == eModifierType_Subsurf) {
- SubsurfModifierData *smd = reinterpret_cast<SubsurfModifierData*>(md);
+ if (md->type == eModifierType_Subsurf) {
+ SubsurfModifierData *smd = reinterpret_cast<SubsurfModifierData *>(md);
- if (smd->subdivType == ME_CC_SUBSURF) {
- return md;
- }
- }
+ if (smd->subdivType == ME_CC_SUBSURF) {
+ return md;
+ }
+ }
- /* mesh is not a subsurf. break */
- if ((md->type != eModifierType_Displace) && (md->type != eModifierType_ParticleSystem)) {
- return NULL;
- }
- }
+ /* mesh is not a subsurf. break */
+ if ((md->type != eModifierType_Displace) && (md->type != eModifierType_ParticleSystem)) {
+ return NULL;
+ }
+ }
- return NULL;
+ return NULL;
}
static ModifierData *get_liquid_sim_modifier(Scene *scene, Object *ob)
{
- ModifierData *md = modifiers_findByType(ob, eModifierType_Fluidsim);
+ ModifierData *md = modifiers_findByType(ob, eModifierType_Fluidsim);
- if (md && (modifier_isEnabled(scene, md, eModifierMode_Render))) {
- FluidsimModifierData *fsmd = reinterpret_cast<FluidsimModifierData *>(md);
+ if (md && (modifier_isEnabled(scene, md, eModifierMode_Render))) {
+ FluidsimModifierData *fsmd = reinterpret_cast<FluidsimModifierData *>(md);
- if (fsmd->fss && fsmd->fss->type == OB_FLUIDSIM_DOMAIN) {
- return md;
- }
- }
+ if (fsmd->fss && fsmd->fss->type == OB_FLUIDSIM_DOMAIN) {
+ return md;
+ }
+ }
- return NULL;
+ return NULL;
}
/* ************************************************************************** */
@@ -295,390 +295,394 @@ AbcGenericMeshWriter::AbcGenericMeshWriter(Object *ob,
ExportSettings &settings)
: AbcObjectWriter(ob, time_sampling, settings, parent)
{
- m_is_animated = isAnimated();
- m_subsurf_mod = NULL;
- m_is_subd = false;
-
- /* If the object is static, use the default static time sampling. */
- if (!m_is_animated) {
- time_sampling = 0;
- }
-
- if (!m_settings.apply_subdiv) {
- m_subsurf_mod = get_subsurf_modifier(m_settings.scene, m_object);
- m_is_subd = (m_subsurf_mod != NULL);
- }
-
- m_is_liquid = (get_liquid_sim_modifier(m_settings.scene, m_object) != NULL);
-
- while (parent->alembicXform().getChildHeader(m_name)) {
- m_name.append("_");
- }
-
- if (m_settings.use_subdiv_schema && m_is_subd) {
- OSubD subd(parent->alembicXform(), m_name, m_time_sampling);
- m_subdiv_schema = subd.getSchema();
- }
- else {
- OPolyMesh mesh(parent->alembicXform(), m_name, m_time_sampling);
- m_mesh_schema = mesh.getSchema();
-
- OCompoundProperty typeContainer = m_mesh_schema.getUserProperties();
- OBoolProperty type(typeContainer, "meshtype");
- type.set(m_is_subd);
- }
+ m_is_animated = isAnimated();
+ m_subsurf_mod = NULL;
+ m_is_subd = false;
+
+ /* If the object is static, use the default static time sampling. */
+ if (!m_is_animated) {
+ time_sampling = 0;
+ }
+
+ if (!m_settings.apply_subdiv) {
+ m_subsurf_mod = get_subsurf_modifier(m_settings.scene, m_object);
+ m_is_subd = (m_subsurf_mod != NULL);
+ }
+
+ m_is_liquid = (get_liquid_sim_modifier(m_settings.scene, m_object) != NULL);
+
+ while (parent->alembicXform().getChildHeader(m_name)) {
+ m_name.append("_");
+ }
+
+ if (m_settings.use_subdiv_schema && m_is_subd) {
+ OSubD subd(parent->alembicXform(), m_name, m_time_sampling);
+ m_subdiv_schema = subd.getSchema();
+ }
+ else {
+ OPolyMesh mesh(parent->alembicXform(), m_name, m_time_sampling);
+ m_mesh_schema = mesh.getSchema();
+
+ OCompoundProperty typeContainer = m_mesh_schema.getUserProperties();
+ OBoolProperty type(typeContainer, "meshtype");
+ type.set(m_is_subd);
+ }
}
AbcGenericMeshWriter::~AbcGenericMeshWriter()
{
- if (m_subsurf_mod) {
- m_subsurf_mod->mode &= ~eModifierMode_DisableTemporary;
- }
+ if (m_subsurf_mod) {
+ m_subsurf_mod->mode &= ~eModifierMode_DisableTemporary;
+ }
}
bool AbcGenericMeshWriter::isAnimated() const
{
- if (m_object->data != NULL) {
- AnimData *adt = BKE_animdata_from_id(static_cast<ID*>(m_object->data));
- /* TODO(Sybren): make this check more strict, as the AnimationData may
- * actually be empty (no fcurves, drivers, etc.) and thus effectively
- * have no animation at all. */
- if (adt != NULL) {
- return true;
- }
- }
- if (BKE_key_from_object(m_object) != NULL) {
- return true;
- }
-
- /* Test modifiers. */
- ModifierData *md = static_cast<ModifierData *>(m_object->modifiers.first);
- while (md) {
-
- if (md->type != eModifierType_Subsurf) {
- return true;
- }
-
- md = md->next;
- }
-
- return false;
+ if (m_object->data != NULL) {
+ AnimData *adt = BKE_animdata_from_id(static_cast<ID *>(m_object->data));
+ /* TODO(Sybren): make this check more strict, as the AnimationData may
+ * actually be empty (no fcurves, drivers, etc.) and thus effectively
+ * have no animation at all. */
+ if (adt != NULL) {
+ return true;
+ }
+ }
+ if (BKE_key_from_object(m_object) != NULL) {
+ return true;
+ }
+
+ /* Test modifiers. */
+ ModifierData *md = static_cast<ModifierData *>(m_object->modifiers.first);
+ while (md) {
+
+ if (md->type != eModifierType_Subsurf) {
+ return true;
+ }
+
+ md = md->next;
+ }
+
+ return false;
}
void AbcGenericMeshWriter::setIsAnimated(bool is_animated)
{
- m_is_animated = is_animated;
+ m_is_animated = is_animated;
}
void AbcGenericMeshWriter::do_write()
{
- /* We have already stored a sample for this object. */
- if (!m_first_frame && !m_is_animated)
- return;
-
- bool needsfree;
- struct Mesh *mesh = getFinalMesh(needsfree);
-
- try {
- if (m_settings.use_subdiv_schema && m_subdiv_schema.valid()) {
- writeSubD(mesh);
- }
- else {
- writeMesh(mesh);
- }
-
- if (needsfree) freeEvaluatedMesh(mesh);
- }
- catch (...) {
- if (needsfree) freeEvaluatedMesh(mesh);
- throw;
- }
+ /* We have already stored a sample for this object. */
+ if (!m_first_frame && !m_is_animated)
+ return;
+
+ bool needsfree;
+ struct Mesh *mesh = getFinalMesh(needsfree);
+
+ try {
+ if (m_settings.use_subdiv_schema && m_subdiv_schema.valid()) {
+ writeSubD(mesh);
+ }
+ else {
+ writeMesh(mesh);
+ }
+
+ if (needsfree)
+ freeEvaluatedMesh(mesh);
+ }
+ catch (...) {
+ if (needsfree)
+ freeEvaluatedMesh(mesh);
+ throw;
+ }
}
void AbcGenericMeshWriter::freeEvaluatedMesh(struct Mesh *mesh)
{
- BKE_id_free(NULL, mesh);
+ BKE_id_free(NULL, mesh);
}
void AbcGenericMeshWriter::writeMesh(struct Mesh *mesh)
{
- std::vector<Imath::V3f> points, normals;
- std::vector<int32_t> poly_verts, loop_counts;
+ std::vector<Imath::V3f> points, normals;
+ std::vector<int32_t> poly_verts, loop_counts;
- bool smooth_normal = false;
+ bool smooth_normal = false;
- get_vertices(mesh, points);
- get_topology(mesh, poly_verts, loop_counts, smooth_normal);
+ get_vertices(mesh, points);
+ get_topology(mesh, poly_verts, loop_counts, smooth_normal);
- if (m_first_frame && m_settings.export_face_sets) {
- writeFaceSets(mesh, m_mesh_schema);
- }
+ if (m_first_frame && m_settings.export_face_sets) {
+ writeFaceSets(mesh, m_mesh_schema);
+ }
- m_mesh_sample = OPolyMeshSchema::Sample(V3fArraySample(points),
- Int32ArraySample(poly_verts),
- Int32ArraySample(loop_counts));
+ m_mesh_sample = OPolyMeshSchema::Sample(
+ V3fArraySample(points), Int32ArraySample(poly_verts), Int32ArraySample(loop_counts));
- UVSample sample;
- if (m_first_frame && m_settings.export_uvs) {
- const char *name = get_uv_sample(sample, m_custom_data_config, &mesh->ldata);
+ UVSample sample;
+ if (m_first_frame && m_settings.export_uvs) {
+ const char *name = get_uv_sample(sample, m_custom_data_config, &mesh->ldata);
- if (!sample.indices.empty() && !sample.uvs.empty()) {
- OV2fGeomParam::Sample uv_sample;
- uv_sample.setVals(V2fArraySample(sample.uvs));
- uv_sample.setIndices(UInt32ArraySample(sample.indices));
- uv_sample.setScope(kFacevaryingScope);
+ if (!sample.indices.empty() && !sample.uvs.empty()) {
+ OV2fGeomParam::Sample uv_sample;
+ uv_sample.setVals(V2fArraySample(sample.uvs));
+ uv_sample.setIndices(UInt32ArraySample(sample.indices));
+ uv_sample.setScope(kFacevaryingScope);
- m_mesh_schema.setUVSourceName(name);
- m_mesh_sample.setUVs(uv_sample);
- }
+ m_mesh_schema.setUVSourceName(name);
+ m_mesh_sample.setUVs(uv_sample);
+ }
- write_custom_data(m_mesh_schema.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
- }
+ write_custom_data(
+ m_mesh_schema.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
+ }
- if (m_settings.export_normals) {
- if (smooth_normal) {
- get_loop_normals(mesh, normals);
- }
- else {
- get_vertex_normals(mesh, normals);
- }
+ if (m_settings.export_normals) {
+ if (smooth_normal) {
+ get_loop_normals(mesh, normals);
+ }
+ else {
+ get_vertex_normals(mesh, normals);
+ }
- ON3fGeomParam::Sample normals_sample;
- if (!normals.empty()) {
- normals_sample.setScope((smooth_normal) ? kFacevaryingScope : kVertexScope);
- normals_sample.setVals(V3fArraySample(normals));
- }
+ ON3fGeomParam::Sample normals_sample;
+ if (!normals.empty()) {
+ normals_sample.setScope((smooth_normal) ? kFacevaryingScope : kVertexScope);
+ normals_sample.setVals(V3fArraySample(normals));
+ }
- m_mesh_sample.setNormals(normals_sample);
- }
+ m_mesh_sample.setNormals(normals_sample);
+ }
- if (m_is_liquid) {
- std::vector<Imath::V3f> velocities;
- getVelocities(mesh, velocities);
+ if (m_is_liquid) {
+ std::vector<Imath::V3f> velocities;
+ getVelocities(mesh, velocities);
- m_mesh_sample.setVelocities(V3fArraySample(velocities));
- }
+ m_mesh_sample.setVelocities(V3fArraySample(velocities));
+ }
- m_mesh_sample.setSelfBounds(bounds());
+ m_mesh_sample.setSelfBounds(bounds());
- m_mesh_schema.set(m_mesh_sample);
+ m_mesh_schema.set(m_mesh_sample);
- writeArbGeoParams(mesh);
+ writeArbGeoParams(mesh);
}
void AbcGenericMeshWriter::writeSubD(struct Mesh *mesh)
{
- std::vector<float> crease_sharpness;
- std::vector<Imath::V3f> points;
- std::vector<int32_t> poly_verts, loop_counts;
- std::vector<int32_t> crease_indices, crease_lengths;
+ std::vector<float> crease_sharpness;
+ std::vector<Imath::V3f> points;
+ std::vector<int32_t> poly_verts, loop_counts;
+ std::vector<int32_t> crease_indices, crease_lengths;
- bool smooth_normal = false;
+ bool smooth_normal = false;
- get_vertices(mesh, points);
- get_topology(mesh, poly_verts, loop_counts, smooth_normal);
- get_creases(mesh, crease_indices, crease_lengths, crease_sharpness);
+ get_vertices(mesh, points);
+ get_topology(mesh, poly_verts, loop_counts, smooth_normal);
+ get_creases(mesh, crease_indices, crease_lengths, crease_sharpness);
- if (m_first_frame && m_settings.export_face_sets) {
- writeFaceSets(mesh, m_subdiv_schema);
- }
+ if (m_first_frame && m_settings.export_face_sets) {
+ writeFaceSets(mesh, m_subdiv_schema);
+ }
- m_subdiv_sample = OSubDSchema::Sample(V3fArraySample(points),
- Int32ArraySample(poly_verts),
- Int32ArraySample(loop_counts));
+ m_subdiv_sample = OSubDSchema::Sample(
+ V3fArraySample(points), Int32ArraySample(poly_verts), Int32ArraySample(loop_counts));
- UVSample sample;
- if (m_first_frame && m_settings.export_uvs) {
- const char *name = get_uv_sample(sample, m_custom_data_config, &mesh->ldata);
+ UVSample sample;
+ if (m_first_frame && m_settings.export_uvs) {
+ const char *name = get_uv_sample(sample, m_custom_data_config, &mesh->ldata);
- if (!sample.indices.empty() && !sample.uvs.empty()) {
- OV2fGeomParam::Sample uv_sample;
- uv_sample.setVals(V2fArraySample(sample.uvs));
- uv_sample.setIndices(UInt32ArraySample(sample.indices));
- uv_sample.setScope(kFacevaryingScope);
+ if (!sample.indices.empty() && !sample.uvs.empty()) {
+ OV2fGeomParam::Sample uv_sample;
+ uv_sample.setVals(V2fArraySample(sample.uvs));
+ uv_sample.setIndices(UInt32ArraySample(sample.indices));
+ uv_sample.setScope(kFacevaryingScope);
- m_subdiv_schema.setUVSourceName(name);
- m_subdiv_sample.setUVs(uv_sample);
- }
+ m_subdiv_schema.setUVSourceName(name);
+ m_subdiv_sample.setUVs(uv_sample);
+ }
- write_custom_data(m_subdiv_schema.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
- }
+ write_custom_data(
+ m_subdiv_schema.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
+ }
- if (!crease_indices.empty()) {
- m_subdiv_sample.setCreaseIndices(Int32ArraySample(crease_indices));
- m_subdiv_sample.setCreaseLengths(Int32ArraySample(crease_lengths));
- m_subdiv_sample.setCreaseSharpnesses(FloatArraySample(crease_sharpness));
- }
+ if (!crease_indices.empty()) {
+ m_subdiv_sample.setCreaseIndices(Int32ArraySample(crease_indices));
+ m_subdiv_sample.setCreaseLengths(Int32ArraySample(crease_lengths));
+ m_subdiv_sample.setCreaseSharpnesses(FloatArraySample(crease_sharpness));
+ }
- m_subdiv_sample.setSelfBounds(bounds());
- m_subdiv_schema.set(m_subdiv_sample);
+ m_subdiv_sample.setSelfBounds(bounds());
+ m_subdiv_schema.set(m_subdiv_sample);
- writeArbGeoParams(mesh);
+ writeArbGeoParams(mesh);
}
-template <typename Schema>
-void AbcGenericMeshWriter::writeFaceSets(struct Mesh *me, Schema &schema)
+template<typename Schema> void AbcGenericMeshWriter::writeFaceSets(struct Mesh *me, Schema &schema)
{
- std::map< std::string, std::vector<int32_t>> geo_groups;
- getGeoGroups(me, geo_groups);
-
- std::map< std::string, std::vector<int32_t>>::iterator it;
- for (it = geo_groups.begin(); it != geo_groups.end(); ++it) {
- OFaceSet face_set = schema.createFaceSet(it->first);
- OFaceSetSchema::Sample samp;
- samp.setFaces(Int32ArraySample(it->second));
- face_set.getSchema().set(samp);
- }
+ std::map<std::string, std::vector<int32_t>> geo_groups;
+ getGeoGroups(me, geo_groups);
+
+ std::map<std::string, std::vector<int32_t>>::iterator it;
+ for (it = geo_groups.begin(); it != geo_groups.end(); ++it) {
+ OFaceSet face_set = schema.createFaceSet(it->first);
+ OFaceSetSchema::Sample samp;
+ samp.setFaces(Int32ArraySample(it->second));
+ face_set.getSchema().set(samp);
+ }
}
Mesh *AbcGenericMeshWriter::getFinalMesh(bool &r_needsfree)
{
- /* We don't want subdivided mesh data */
- if (m_subsurf_mod) {
- m_subsurf_mod->mode |= eModifierMode_DisableTemporary;
- }
+ /* We don't want subdivided mesh data */
+ if (m_subsurf_mod) {
+ m_subsurf_mod->mode |= eModifierMode_DisableTemporary;
+ }
- r_needsfree = false;
+ r_needsfree = false;
- Scene *scene = DEG_get_evaluated_scene(m_settings.depsgraph);
- Object *ob_eval = DEG_get_evaluated_object(m_settings.depsgraph, m_object);
- struct Mesh *mesh = getEvaluatedMesh(scene, ob_eval, r_needsfree);
+ Scene *scene = DEG_get_evaluated_scene(m_settings.depsgraph);
+ Object *ob_eval = DEG_get_evaluated_object(m_settings.depsgraph, m_object);
+ struct Mesh *mesh = getEvaluatedMesh(scene, ob_eval, r_needsfree);
- if (m_subsurf_mod) {
- m_subsurf_mod->mode &= ~eModifierMode_DisableTemporary;
- }
+ if (m_subsurf_mod) {
+ 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;
+ 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;
- struct BMeshCreateParams bmcp = {false};
- struct BMeshFromMeshParams bmfmp = {true, false, false, 0};
- BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmcp, &bmfmp);
+ struct BMeshCreateParams bmcp = {false};
+ struct BMeshFromMeshParams bmfmp = {true, false, false, 0};
+ BMesh *bm = BKE_mesh_to_bmesh_ex(mesh, &bmcp, &bmfmp);
- BM_mesh_triangulate(bm, quad_method, ngon_method, 4, tag_only, NULL, NULL, NULL);
+ BM_mesh_triangulate(bm, quad_method, ngon_method, 4, tag_only, NULL, NULL, NULL);
- Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
- BM_mesh_free(bm);
+ Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL);
+ BM_mesh_free(bm);
- if (r_needsfree) {
- BKE_id_free(NULL, mesh);
- }
+ if (r_needsfree) {
+ BKE_id_free(NULL, mesh);
+ }
- mesh = result;
- r_needsfree = true;
- }
+ mesh = result;
+ r_needsfree = true;
+ }
- m_custom_data_config.pack_uvs = m_settings.pack_uv;
- m_custom_data_config.mpoly = mesh->mpoly;
- m_custom_data_config.mloop = mesh->mloop;
- m_custom_data_config.totpoly = mesh->totpoly;
- m_custom_data_config.totloop = mesh->totloop;
- m_custom_data_config.totvert = mesh->totvert;
+ m_custom_data_config.pack_uvs = m_settings.pack_uv;
+ m_custom_data_config.mpoly = mesh->mpoly;
+ m_custom_data_config.mloop = mesh->mloop;
+ m_custom_data_config.totpoly = mesh->totpoly;
+ m_custom_data_config.totloop = mesh->totloop;
+ m_custom_data_config.totvert = mesh->totvert;
- return mesh;
+ return mesh;
}
void AbcGenericMeshWriter::writeArbGeoParams(struct Mesh *me)
{
- if (m_is_liquid) {
- /* We don't need anything more for liquid meshes. */
- return;
- }
-
- if (m_first_frame && m_settings.export_vcols) {
- if (m_subdiv_schema.valid()) {
- write_custom_data(m_subdiv_schema.getArbGeomParams(), m_custom_data_config, &me->ldata, CD_MLOOPCOL);
- }
- else {
- write_custom_data(m_mesh_schema.getArbGeomParams(), m_custom_data_config, &me->ldata, CD_MLOOPCOL);
- }
- }
+ if (m_is_liquid) {
+ /* We don't need anything more for liquid meshes. */
+ return;
+ }
+
+ if (m_first_frame && m_settings.export_vcols) {
+ if (m_subdiv_schema.valid()) {
+ write_custom_data(
+ m_subdiv_schema.getArbGeomParams(), m_custom_data_config, &me->ldata, CD_MLOOPCOL);
+ }
+ else {
+ write_custom_data(
+ m_mesh_schema.getArbGeomParams(), m_custom_data_config, &me->ldata, CD_MLOOPCOL);
+ }
+ }
}
void AbcGenericMeshWriter::getVelocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels)
{
- const int totverts = mesh->totvert;
-
- vels.clear();
- vels.resize(totverts);
-
- ModifierData *md = get_liquid_sim_modifier(m_settings.scene, m_object);
- FluidsimModifierData *fmd = reinterpret_cast<FluidsimModifierData *>(md);
- FluidsimSettings *fss = fmd->fss;
-
- if (fss->meshVelocities) {
- float *mesh_vels = reinterpret_cast<float *>(fss->meshVelocities);
-
- for (int i = 0; i < totverts; ++i) {
- copy_yup_from_zup(vels[i].getValue(), mesh_vels);
- mesh_vels += 3;
- }
- }
- else {
- std::fill(vels.begin(), vels.end(), Imath::V3f(0.0f));
- }
+ const int totverts = mesh->totvert;
+
+ vels.clear();
+ vels.resize(totverts);
+
+ ModifierData *md = get_liquid_sim_modifier(m_settings.scene, m_object);
+ FluidsimModifierData *fmd = reinterpret_cast<FluidsimModifierData *>(md);
+ FluidsimSettings *fss = fmd->fss;
+
+ if (fss->meshVelocities) {
+ float *mesh_vels = reinterpret_cast<float *>(fss->meshVelocities);
+
+ for (int i = 0; i < totverts; ++i) {
+ copy_yup_from_zup(vels[i].getValue(), mesh_vels);
+ mesh_vels += 3;
+ }
+ }
+ else {
+ std::fill(vels.begin(), vels.end(), Imath::V3f(0.0f));
+ }
}
-void AbcGenericMeshWriter::getGeoGroups(
- struct Mesh *mesh,
- std::map<std::string, std::vector<int32_t>> &geo_groups)
+void AbcGenericMeshWriter::getGeoGroups(struct Mesh *mesh,
+ std::map<std::string, std::vector<int32_t>> &geo_groups)
{
- const int num_poly = mesh->totpoly;
- MPoly *polygons = mesh->mpoly;
+ const int num_poly = mesh->totpoly;
+ MPoly *polygons = mesh->mpoly;
- for (int i = 0; i < num_poly; ++i) {
- MPoly &current_poly = polygons[i];
- short mnr = current_poly.mat_nr;
+ for (int i = 0; i < num_poly; ++i) {
+ MPoly &current_poly = polygons[i];
+ short mnr = current_poly.mat_nr;
- Material *mat = give_current_material(m_object, mnr + 1);
+ Material *mat = give_current_material(m_object, mnr + 1);
- if (!mat) {
- continue;
- }
+ if (!mat) {
+ continue;
+ }
- std::string name = get_id_name(&mat->id);
+ std::string name = get_id_name(&mat->id);
- if (geo_groups.find(name) == geo_groups.end()) {
- std::vector<int32_t> faceArray;
- geo_groups[name] = faceArray;
- }
+ if (geo_groups.find(name) == geo_groups.end()) {
+ std::vector<int32_t> faceArray;
+ geo_groups[name] = faceArray;
+ }
- geo_groups[name].push_back(i);
- }
+ geo_groups[name].push_back(i);
+ }
- if (geo_groups.size() == 0) {
- Material *mat = give_current_material(m_object, 1);
+ if (geo_groups.size() == 0) {
+ Material *mat = give_current_material(m_object, 1);
- std::string name = (mat) ? get_id_name(&mat->id) : "default";
+ std::string name = (mat) ? get_id_name(&mat->id) : "default";
- std::vector<int32_t> faceArray;
+ std::vector<int32_t> faceArray;
- for (int i = 0, e = mesh->totface; i < e; ++i) {
- faceArray.push_back(i);
- }
+ for (int i = 0, e = mesh->totface; i < e; ++i) {
+ faceArray.push_back(i);
+ }
- geo_groups[name] = faceArray;
- }
+ geo_groups[name] = faceArray;
+ }
}
-
AbcMeshWriter::AbcMeshWriter(Object *ob,
AbcTransformWriter *parent,
uint32_t time_sampling,
ExportSettings &settings)
: AbcGenericMeshWriter(ob, parent, time_sampling, settings)
-{}
+{
+}
AbcMeshWriter::~AbcMeshWriter()
-{}
-
-Mesh *AbcMeshWriter::getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &UNUSED(r_needsfree))
{
- return mesh_get_eval_final(m_settings.depsgraph, scene_eval, ob_eval, &CD_MASK_MESH);
}
+Mesh *AbcMeshWriter::getEvaluatedMesh(Scene *scene_eval,
+ Object *ob_eval,
+ bool &UNUSED(r_needsfree))
+{
+ return mesh_get_eval_final(m_settings.depsgraph, scene_eval, ob_eval, &CD_MASK_MESH);
+}
/* ************************************************************************** */
@@ -687,55 +691,57 @@ namespace utils {
static void build_mat_map(const Main *bmain, std::map<std::string, Material *> &mat_map)
{
- Material *material = static_cast<Material *>(bmain->materials.first);
+ Material *material = static_cast<Material *>(bmain->materials.first);
- for (; material; material = static_cast<Material *>(material->id.next)) {
- mat_map[material->id.name + 2] = material;
- }
+ for (; material; material = static_cast<Material *>(material->id.next)) {
+ mat_map[material->id.name + 2] = material;
+ }
}
-static void assign_materials(Main *bmain, Object *ob, const std::map<std::string, int> &mat_index_map)
+static void assign_materials(Main *bmain,
+ Object *ob,
+ const std::map<std::string, int> &mat_index_map)
{
- bool can_assign = true;
- std::map<std::string, int>::const_iterator it = mat_index_map.begin();
-
- int matcount = 0;
- for (; it != mat_index_map.end(); ++it, ++matcount) {
- if (!BKE_object_material_slot_add(bmain, ob)) {
- can_assign = false;
- break;
- }
- }
-
- /* TODO(kevin): use global map? */
- std::map<std::string, Material *> mat_map;
- build_mat_map(bmain, mat_map);
-
- std::map<std::string, Material *>::iterator mat_iter;
-
- if (can_assign) {
- it = mat_index_map.begin();
-
- for (; it != mat_index_map.end(); ++it) {
- std::string mat_name = it->first;
- mat_iter = mat_map.find(mat_name.c_str());
-
- Material *assigned_mat;
-
- if (mat_iter == mat_map.end()) {
- assigned_mat = BKE_material_add(bmain, mat_name.c_str());
- mat_map[mat_name] = assigned_mat;
- }
- else {
- assigned_mat = mat_iter->second;
- }
-
- assign_material(bmain, ob, assigned_mat, it->second, BKE_MAT_ASSIGN_OBDATA);
- }
- }
+ bool can_assign = true;
+ std::map<std::string, int>::const_iterator it = mat_index_map.begin();
+
+ int matcount = 0;
+ for (; it != mat_index_map.end(); ++it, ++matcount) {
+ if (!BKE_object_material_slot_add(bmain, ob)) {
+ can_assign = false;
+ break;
+ }
+ }
+
+ /* TODO(kevin): use global map? */
+ std::map<std::string, Material *> mat_map;
+ build_mat_map(bmain, mat_map);
+
+ std::map<std::string, Material *>::iterator mat_iter;
+
+ if (can_assign) {
+ it = mat_index_map.begin();
+
+ for (; it != mat_index_map.end(); ++it) {
+ std::string mat_name = it->first;
+ mat_iter = mat_map.find(mat_name.c_str());
+
+ Material *assigned_mat;
+
+ if (mat_iter == mat_map.end()) {
+ assigned_mat = BKE_material_add(bmain, mat_name.c_str());
+ mat_map[mat_name] = assigned_mat;
+ }
+ else {
+ assigned_mat = mat_iter->second;
+ }
+
+ assign_material(bmain, ob, assigned_mat, it->second, BKE_MAT_ASSIGN_OBDATA);
+ }
+ }
}
-} /* namespace utils */
+} /* namespace utils */
/* ************************************************************************** */
@@ -743,116 +749,120 @@ using Alembic::AbcGeom::UInt32ArraySamplePtr;
using Alembic::AbcGeom::V2fArraySamplePtr;
struct AbcMeshData {
- Int32ArraySamplePtr face_indices;
- Int32ArraySamplePtr face_counts;
+ Int32ArraySamplePtr face_indices;
+ Int32ArraySamplePtr face_counts;
- P3fArraySamplePtr positions;
- P3fArraySamplePtr ceil_positions;
+ P3fArraySamplePtr positions;
+ P3fArraySamplePtr ceil_positions;
- N3fArraySamplePtr vertex_normals;
- N3fArraySamplePtr face_normals;
+ N3fArraySamplePtr vertex_normals;
+ N3fArraySamplePtr face_normals;
- V2fArraySamplePtr uvs;
- UInt32ArraySamplePtr uvs_indices;
+ V2fArraySamplePtr uvs;
+ UInt32ArraySamplePtr uvs_indices;
};
-static void read_mverts_interp(MVert *mverts, const P3fArraySamplePtr &positions, const P3fArraySamplePtr &ceil_positions, const float weight)
+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];
+ 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_zup_from_yup(mvert.co, tmp);
+ interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), weight);
+ copy_zup_from_yup(mvert.co, tmp);
- mvert.bweight = 0;
- }
+ 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 != NULL
- && mesh_data.ceil_positions->size() == positions->size())
- {
- read_mverts_interp(mverts, positions, mesh_data.ceil_positions, config.weight);
- return;
- }
-
- read_mverts(mverts, positions, normals);
+ 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 != NULL &&
+ mesh_data.ceil_positions->size() == positions->size()) {
+ read_mverts_interp(mverts, positions, mesh_data.ceil_positions, config.weight);
+ return;
+ }
+
+ read_mverts(mverts, positions, normals);
}
-void read_mverts(MVert *mverts, const P3fArraySamplePtr &positions, const N3fArraySamplePtr &normals)
+void read_mverts(MVert *mverts,
+ const P3fArraySamplePtr &positions,
+ const N3fArraySamplePtr &normals)
{
- for (int i = 0; i < positions->size(); ++i) {
- MVert &mvert = mverts[i];
- Imath::V3f pos_in = (*positions)[i];
+ for (int i = 0; i < positions->size(); ++i) {
+ MVert &mvert = mverts[i];
+ Imath::V3f pos_in = (*positions)[i];
- copy_zup_from_yup(mvert.co, pos_in.getValue());
+ copy_zup_from_yup(mvert.co, pos_in.getValue());
- mvert.bweight = 0;
+ mvert.bweight = 0;
- if (normals) {
- Imath::V3f nor_in = (*normals)[i];
+ if (normals) {
+ Imath::V3f nor_in = (*normals)[i];
- short no[3];
- normal_float_to_short_v3(no, nor_in.getValue());
+ short no[3];
+ normal_float_to_short_v3(no, nor_in.getValue());
- copy_zup_from_yup(mvert.no, no);
- }
- }
+ copy_zup_from_yup(mvert.no, no);
+ }
+ }
}
static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
{
- MPoly *mpolys = config.mpoly;
- MLoop *mloops = config.mloop;
- MLoopUV *mloopuvs = config.mloopuv;
-
- const Int32ArraySamplePtr &face_indices = mesh_data.face_indices;
- const Int32ArraySamplePtr &face_counts = mesh_data.face_counts;
- const V2fArraySamplePtr &uvs = mesh_data.uvs;
- const UInt32ArraySamplePtr &uvs_indices = mesh_data.uvs_indices;
- const N3fArraySamplePtr &normals = mesh_data.face_normals;
-
- const bool do_uvs = (mloopuvs && uvs && uvs_indices) && (uvs_indices->size() == face_indices->size());
- unsigned int loop_index = 0;
- unsigned int rev_loop_index = 0;
- unsigned int uv_index = 0;
-
- for (int i = 0; i < face_counts->size(); ++i) {
- const int face_size = (*face_counts)[i];
-
- MPoly &poly = mpolys[i];
- poly.loopstart = loop_index;
- poly.totloop = face_size;
-
- if (normals != NULL) {
- poly.flag |= ME_SMOOTH;
- }
-
- /* NOTE: Alembic data is stored in the reverse order. */
- rev_loop_index = loop_index + (face_size - 1);
-
- for (int f = 0; f < face_size; ++f, ++loop_index, --rev_loop_index) {
- MLoop &loop = mloops[rev_loop_index];
- loop.v = (*face_indices)[loop_index];
-
- if (do_uvs) {
- MLoopUV &loopuv = mloopuvs[rev_loop_index];
-
- uv_index = (*uvs_indices)[loop_index];
- loopuv.uv[0] = (*uvs)[uv_index][0];
- loopuv.uv[1] = (*uvs)[uv_index][1];
- }
- }
- }
+ MPoly *mpolys = config.mpoly;
+ MLoop *mloops = config.mloop;
+ MLoopUV *mloopuvs = config.mloopuv;
+
+ const Int32ArraySamplePtr &face_indices = mesh_data.face_indices;
+ const Int32ArraySamplePtr &face_counts = mesh_data.face_counts;
+ const V2fArraySamplePtr &uvs = mesh_data.uvs;
+ const UInt32ArraySamplePtr &uvs_indices = mesh_data.uvs_indices;
+ const N3fArraySamplePtr &normals = mesh_data.face_normals;
+
+ const bool do_uvs = (mloopuvs && uvs && uvs_indices) &&
+ (uvs_indices->size() == face_indices->size());
+ unsigned int loop_index = 0;
+ unsigned int rev_loop_index = 0;
+ unsigned int uv_index = 0;
+
+ for (int i = 0; i < face_counts->size(); ++i) {
+ const int face_size = (*face_counts)[i];
+
+ MPoly &poly = mpolys[i];
+ poly.loopstart = loop_index;
+ poly.totloop = face_size;
+
+ if (normals != NULL) {
+ poly.flag |= ME_SMOOTH;
+ }
+
+ /* NOTE: Alembic data is stored in the reverse order. */
+ rev_loop_index = loop_index + (face_size - 1);
+
+ for (int f = 0; f < face_size; ++f, ++loop_index, --rev_loop_index) {
+ MLoop &loop = mloops[rev_loop_index];
+ loop.v = (*face_indices)[loop_index];
+
+ if (do_uvs) {
+ MLoopUV &loopuv = mloopuvs[rev_loop_index];
+
+ uv_index = (*uvs_indices)[loop_index];
+ loopuv.uv[0] = (*uvs)[uv_index][0];
+ loopuv.uv[1] = (*uvs)[uv_index][1];
+ }
+ }
+ }
}
ABC_INLINE void read_uvs_params(CDStreamConfig &config,
@@ -860,29 +870,29 @@ ABC_INLINE void read_uvs_params(CDStreamConfig &config,
const IV2fGeomParam &uv,
const ISampleSelector &selector)
{
- if (!uv.valid()) {
- return;
- }
+ if (!uv.valid()) {
+ return;
+ }
- IV2fGeomParam::Sample uvsamp;
- uv.getIndexed(uvsamp, selector);
+ IV2fGeomParam::Sample uvsamp;
+ uv.getIndexed(uvsamp, selector);
- abc_data.uvs = uvsamp.getVals();
- abc_data.uvs_indices = uvsamp.getIndices();
+ abc_data.uvs = uvsamp.getVals();
+ abc_data.uvs_indices = uvsamp.getIndices();
- if (abc_data.uvs_indices->size() == config.totloop) {
- std::string name = Alembic::Abc::GetSourceName(uv.getMetaData());
+ if (abc_data.uvs_indices->size() == config.totloop) {
+ std::string name = Alembic::Abc::GetSourceName(uv.getMetaData());
- /* According to the convention, primary UVs should have had their name
- * set using Alembic::Abc::SetSourceName, but you can't expect everyone
- * to follow it! :) */
- if (name.empty()) {
- name = uv.getName();
- }
+ /* According to the convention, primary UVs should have had their name
+ * set using Alembic::Abc::SetSourceName, but you can't expect everyone
+ * to follow it! :) */
+ if (name.empty()) {
+ name = uv.getName();
+ }
- void *cd_ptr = config.add_customdata_cb(config.user_data, name.c_str(), CD_MLOOPUV);
- config.mloopuv = static_cast<MLoopUV *>(cd_ptr);
- }
+ void *cd_ptr = config.add_customdata_cb(config.user_data, name.c_str(), CD_MLOOPUV);
+ config.mloopuv = static_cast<MLoopUV *>(cd_ptr);
+ }
}
/* TODO(kevin): normals from Alembic files are not read in anymore, this is due
@@ -893,149 +903,143 @@ ABC_INLINE void read_normals_params(AbcMeshData &abc_data,
const IN3fGeomParam &normals,
const ISampleSelector &selector)
{
- if (!normals.valid()) {
- return;
- }
-
- IN3fGeomParam::Sample normsamp = normals.getExpandedValue(selector);
-
- if (normals.getScope() == kFacevaryingScope) {
- abc_data.face_normals = normsamp.getVals();
- }
- else if ((normals.getScope() == kVertexScope) || (normals.getScope() == kVaryingScope)) {
- abc_data.vertex_normals = N3fArraySamplePtr();
- }
+ if (!normals.valid()) {
+ return;
+ }
+
+ IN3fGeomParam::Sample normsamp = normals.getExpandedValue(selector);
+
+ if (normals.getScope() == kFacevaryingScope) {
+ abc_data.face_normals = normsamp.getVals();
+ }
+ else if ((normals.getScope() == kVertexScope) || (normals.getScope() == kVaryingScope)) {
+ abc_data.vertex_normals = N3fArraySamplePtr();
+ }
}
static bool check_smooth_poly_flag(Mesh *mesh)
{
- MPoly *mpolys = mesh->mpoly;
+ MPoly *mpolys = mesh->mpoly;
- for (int i = 0, e = mesh->totpoly; i < e; ++i) {
- MPoly &poly = mpolys[i];
+ for (int i = 0, e = mesh->totpoly; i < e; ++i) {
+ MPoly &poly = mpolys[i];
- if ((poly.flag & ME_SMOOTH) != 0) {
- return true;
- }
- }
+ if ((poly.flag & ME_SMOOTH) != 0) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
static void set_smooth_poly_flag(Mesh *mesh)
{
- MPoly *mpolys = mesh->mpoly;
+ MPoly *mpolys = mesh->mpoly;
- for (int i = 0, e = mesh->totpoly; i < e; ++i) {
- MPoly &poly = mpolys[i];
- poly.flag |= ME_SMOOTH;
- }
+ for (int i = 0, e = mesh->totpoly; i < e; ++i) {
+ MPoly &poly = mpolys[i];
+ poly.flag |= ME_SMOOTH;
+ }
}
static void *add_customdata_cb(void *user_data, const char *name, int data_type)
{
- Mesh *mesh = static_cast<Mesh *>(user_data);
- CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
- void *cd_ptr;
- CustomData *loopdata;
- int numloops;
-
- /* unsupported custom data type -- don't do anything. */
- if (!ELEM(cd_data_type, CD_MLOOPUV, CD_MLOOPCOL)) {
- return NULL;
- }
-
- loopdata = &mesh->ldata;
- cd_ptr = CustomData_get_layer_named(loopdata, cd_data_type, name);
- if (cd_ptr != NULL) {
- /* layer already exists, so just return it. */
- return cd_ptr;
- }
-
- /* create a new layer, taking care to construct the hopefully-soon-to-be-removed
- * CD_MTEXPOLY layer too, with the same name. */
- numloops = mesh->totloop;
- cd_ptr = CustomData_add_layer_named(loopdata, cd_data_type, CD_DEFAULT,
- NULL, numloops, name);
- return cd_ptr;
+ Mesh *mesh = static_cast<Mesh *>(user_data);
+ CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
+ void *cd_ptr;
+ CustomData *loopdata;
+ int numloops;
+
+ /* unsupported custom data type -- don't do anything. */
+ if (!ELEM(cd_data_type, CD_MLOOPUV, CD_MLOOPCOL)) {
+ return NULL;
+ }
+
+ loopdata = &mesh->ldata;
+ cd_ptr = CustomData_get_layer_named(loopdata, cd_data_type, name);
+ if (cd_ptr != NULL) {
+ /* layer already exists, so just return it. */
+ return cd_ptr;
+ }
+
+ /* create a new layer, taking care to construct the hopefully-soon-to-be-removed
+ * CD_MTEXPOLY layer too, with the same name. */
+ numloops = mesh->totloop;
+ cd_ptr = CustomData_add_layer_named(loopdata, cd_data_type, CD_DEFAULT, NULL, numloops, name);
+ return cd_ptr;
}
static void get_weight_and_index(CDStreamConfig &config,
Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling,
size_t samples_number)
{
- Alembic::AbcGeom::index_t i0, i1;
+ Alembic::AbcGeom::index_t i0, i1;
- config.weight = get_weight_and_index(config.time,
- time_sampling,
- samples_number,
- i0,
- i1);
+ config.weight = get_weight_and_index(config.time, time_sampling, samples_number, i0, i1);
- config.index = i0;
- config.ceil_index = i1;
+ config.index = i0;
+ config.ceil_index = i1;
}
-static void read_mesh_sample(const std::string & iobject_full_name,
+static void read_mesh_sample(const std::string &iobject_full_name,
ImportSettings *settings,
const IPolyMeshSchema &schema,
const ISampleSelector &selector,
CDStreamConfig &config,
bool &do_normals)
{
- const IPolyMeshSchema::Sample sample = schema.getValue(selector);
+ const IPolyMeshSchema::Sample sample = schema.getValue(selector);
- AbcMeshData abc_mesh_data;
- abc_mesh_data.face_counts = sample.getFaceCounts();
- abc_mesh_data.face_indices = sample.getFaceIndices();
- abc_mesh_data.positions = sample.getPositions();
+ AbcMeshData abc_mesh_data;
+ abc_mesh_data.face_counts = sample.getFaceCounts();
+ abc_mesh_data.face_indices = sample.getFaceIndices();
+ abc_mesh_data.positions = sample.getPositions();
- read_normals_params(abc_mesh_data, schema.getNormalsParam(), selector);
+ read_normals_params(abc_mesh_data, schema.getNormalsParam(), selector);
- do_normals = (abc_mesh_data.face_normals != NULL);
+ do_normals = (abc_mesh_data.face_normals != NULL);
- get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
+ 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(config.ceil_index));
- abc_mesh_data.ceil_positions = ceil_sample.getPositions();
- }
+ if (config.weight != 0.0f) {
+ Alembic::AbcGeom::IPolyMeshSchema::Sample ceil_sample;
+ schema.get(ceil_sample, Alembic::Abc::ISampleSelector(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);
- }
+ if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
+ read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector);
+ }
- if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
- read_mverts(config, abc_mesh_data);
- }
+ if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
+ read_mverts(config, abc_mesh_data);
+ }
- if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
- read_mpolys(config, abc_mesh_data);
- }
+ if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
+ read_mpolys(config, abc_mesh_data);
+ }
- if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
- read_custom_data(iobject_full_name,
- schema.getArbGeomParams(), config, selector);
- }
+ if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
+ read_custom_data(iobject_full_name, schema.getArbGeomParams(), config, selector);
+ }
}
CDStreamConfig get_config(Mesh *mesh)
{
- CDStreamConfig config;
+ CDStreamConfig config;
- BLI_assert(mesh->mvert || mesh->totvert == 0);
+ BLI_assert(mesh->mvert || mesh->totvert == 0);
- config.user_data = mesh;
- config.mvert = mesh->mvert;
- config.mloop = mesh->mloop;
- config.mpoly = mesh->mpoly;
- config.totloop = mesh->totloop;
- config.totpoly = mesh->totpoly;
- config.loopdata = &mesh->ldata;
- config.add_customdata_cb = add_customdata_cb;
+ config.user_data = mesh;
+ config.mvert = mesh->mvert;
+ config.mloop = mesh->mloop;
+ config.mpoly = mesh->mpoly;
+ config.totloop = mesh->totloop;
+ config.totpoly = mesh->totpoly;
+ config.loopdata = &mesh->ldata;
+ config.add_customdata_cb = add_customdata_cb;
- return config;
+ return config;
}
/* ************************************************************************** */
@@ -1043,57 +1047,60 @@ CDStreamConfig get_config(Mesh *mesh)
AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings)
: AbcObjectReader(object, settings)
{
- m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
+ m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
- IPolyMesh ipoly_mesh(m_iobject, kWrapExisting);
- m_schema = ipoly_mesh.getSchema();
+ IPolyMesh ipoly_mesh(m_iobject, kWrapExisting);
+ m_schema = ipoly_mesh.getSchema();
- get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
+ get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
}
bool AbcMeshReader::valid() const
{
- return m_schema.valid();
+ return m_schema.valid();
}
void AbcMeshReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
- Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
+ Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
- m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
- m_object->data = mesh;
+ m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
+ m_object->data = mesh;
- Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
- if (read_mesh != mesh) {
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_MESH, true);
- }
+ Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
+ if (read_mesh != mesh) {
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_MESH, true);
+ }
- if (m_settings->validate_meshes) {
- BKE_mesh_validate(mesh, false, false);
- }
+ if (m_settings->validate_meshes) {
+ BKE_mesh_validate(mesh, false, false);
+ }
- readFaceSetsSample(bmain, mesh, 0, sample_sel);
+ readFaceSetsSample(bmain, mesh, 0, sample_sel);
- if (has_animations(m_schema, m_settings)) {
- addCacheModifier();
- }
+ if (has_animations(m_schema, m_settings)) {
+ addCacheModifier();
+ }
}
-bool AbcMeshReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const
+bool AbcMeshReader::accepts_object_type(
+ const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
{
- if (!Alembic::AbcGeom::IPolyMesh::matches(alembic_header)) {
- *err_str = "Object type mismatch, Alembic object path pointed to PolyMesh when importing, but not any more.";
- return false;
- }
-
- if (ob->type != OB_MESH) {
- *err_str = "Object type mismatch, Alembic object path points to PolyMesh.";
- return false;
- }
-
- return true;
+ if (!Alembic::AbcGeom::IPolyMesh::matches(alembic_header)) {
+ *err_str =
+ "Object type mismatch, Alembic object path pointed to PolyMesh when importing, but not "
+ "any more.";
+ return false;
+ }
+
+ if (ob->type != OB_MESH) {
+ *err_str = "Object type mismatch, Alembic object path points to PolyMesh.";
+ return false;
+ }
+
+ return true;
}
Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
@@ -1101,209 +1108,202 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
int read_flag,
const char **err_str)
{
- IPolyMeshSchema::Sample sample;
- try {
- sample = m_schema.getValue(sample_sel);
- }
- catch(Alembic::Util::Exception &ex) {
- *err_str = "Error reading mesh sample; more detail on the console";
- printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
- m_iobject.getFullName().c_str(),
- m_schema.getName().c_str(),
- sample_sel.getRequestedTime(),
- ex.what());
- return existing_mesh;
- }
-
- const P3fArraySamplePtr &positions = sample.getPositions();
- const Alembic::Abc::Int32ArraySamplePtr &face_indices = sample.getFaceIndices();
- const Alembic::Abc::Int32ArraySamplePtr &face_counts = sample.getFaceCounts();
-
- Mesh *new_mesh = NULL;
-
- /* Only read point data when streaming meshes, unless we need to create new ones. */
- ImportSettings settings;
- settings.read_flag |= read_flag;
-
- bool topology_changed = positions->size() != existing_mesh->totvert ||
- face_counts->size() != existing_mesh->totpoly ||
- face_indices->size() != existing_mesh->totloop;
- if (topology_changed) {
- new_mesh = BKE_mesh_new_nomain_from_template(existing_mesh,
- positions->size(),
- 0,
- 0,
- face_indices->size(),
- face_counts->size());
-
- settings.read_flag |= MOD_MESHSEQ_READ_ALL;
- }
- else {
- /* If the face count changed (e.g. by triangulation), only read points.
- * This prevents crash from T49813.
- * TODO(kevin): perhaps find a better way to do this? */
- if (face_counts->size() != existing_mesh->totpoly ||
- face_indices->size() != existing_mesh->totloop)
- {
- settings.read_flag = MOD_MESHSEQ_READ_VERT;
-
- if (err_str) {
- *err_str = "Topology has changed, perhaps by triangulating the"
- " mesh. Only vertices will be read!";
- }
- }
- }
-
- CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
- config.time = sample_sel.getRequestedTime();
-
- bool do_normals = false;
- read_mesh_sample(m_iobject.getFullName(),
- &settings, m_schema, sample_sel, config, do_normals);
-
- if (new_mesh) {
- /* Check if we had ME_SMOOTH flag set to restore it. */
- if (!do_normals && check_smooth_poly_flag(existing_mesh)) {
- set_smooth_poly_flag(new_mesh);
- }
-
- BKE_mesh_calc_normals(new_mesh);
- BKE_mesh_calc_edges(new_mesh, false, false);
-
- /* Here we assume that the number of materials doesn't change, i.e. that
- * the material slots that were created when the object was loaded from
- * Alembic are still valid now. */
- size_t num_polys = new_mesh->totpoly;
- if (num_polys > 0) {
- std::map<std::string, int> mat_map;
- assign_facesets_to_mpoly(sample_sel, 0, new_mesh->mpoly, num_polys, mat_map);
- }
-
- return new_mesh;
- }
-
- if (do_normals) {
- BKE_mesh_calc_normals(existing_mesh);
- }
-
- return existing_mesh;
+ IPolyMeshSchema::Sample sample;
+ try {
+ sample = m_schema.getValue(sample_sel);
+ }
+ catch (Alembic::Util::Exception &ex) {
+ *err_str = "Error reading mesh sample; more detail on the console";
+ printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ m_schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return existing_mesh;
+ }
+
+ const P3fArraySamplePtr &positions = sample.getPositions();
+ const Alembic::Abc::Int32ArraySamplePtr &face_indices = sample.getFaceIndices();
+ const Alembic::Abc::Int32ArraySamplePtr &face_counts = sample.getFaceCounts();
+
+ Mesh *new_mesh = NULL;
+
+ /* Only read point data when streaming meshes, unless we need to create new ones. */
+ ImportSettings settings;
+ settings.read_flag |= read_flag;
+
+ bool topology_changed = positions->size() != existing_mesh->totvert ||
+ face_counts->size() != existing_mesh->totpoly ||
+ face_indices->size() != existing_mesh->totloop;
+ if (topology_changed) {
+ new_mesh = BKE_mesh_new_nomain_from_template(
+ existing_mesh, positions->size(), 0, 0, face_indices->size(), face_counts->size());
+
+ settings.read_flag |= MOD_MESHSEQ_READ_ALL;
+ }
+ else {
+ /* If the face count changed (e.g. by triangulation), only read points.
+ * This prevents crash from T49813.
+ * TODO(kevin): perhaps find a better way to do this? */
+ if (face_counts->size() != existing_mesh->totpoly ||
+ face_indices->size() != existing_mesh->totloop) {
+ settings.read_flag = MOD_MESHSEQ_READ_VERT;
+
+ if (err_str) {
+ *err_str =
+ "Topology has changed, perhaps by triangulating the"
+ " mesh. Only vertices will be read!";
+ }
+ }
+ }
+
+ CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
+ config.time = sample_sel.getRequestedTime();
+
+ bool do_normals = false;
+ read_mesh_sample(m_iobject.getFullName(), &settings, m_schema, sample_sel, config, do_normals);
+
+ if (new_mesh) {
+ /* Check if we had ME_SMOOTH flag set to restore it. */
+ if (!do_normals && check_smooth_poly_flag(existing_mesh)) {
+ set_smooth_poly_flag(new_mesh);
+ }
+
+ BKE_mesh_calc_normals(new_mesh);
+ BKE_mesh_calc_edges(new_mesh, false, false);
+
+ /* Here we assume that the number of materials doesn't change, i.e. that
+ * the material slots that were created when the object was loaded from
+ * Alembic are still valid now. */
+ size_t num_polys = new_mesh->totpoly;
+ if (num_polys > 0) {
+ std::map<std::string, int> mat_map;
+ assign_facesets_to_mpoly(sample_sel, 0, new_mesh->mpoly, num_polys, mat_map);
+ }
+
+ return new_mesh;
+ }
+
+ if (do_normals) {
+ BKE_mesh_calc_normals(existing_mesh);
+ }
+
+ return existing_mesh;
}
-void AbcMeshReader::assign_facesets_to_mpoly(
- const ISampleSelector &sample_sel,
- size_t poly_start,
- MPoly *mpoly, int totpoly,
- std::map<std::string, int> & r_mat_map)
+void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
+ size_t poly_start,
+ MPoly *mpoly,
+ int totpoly,
+ std::map<std::string, int> &r_mat_map)
{
- std::vector<std::string> face_sets;
- m_schema.getFaceSetNames(face_sets);
-
- if (face_sets.empty()) {
- return;
- }
+ std::vector<std::string> face_sets;
+ m_schema.getFaceSetNames(face_sets);
- int current_mat = 0;
+ if (face_sets.empty()) {
+ return;
+ }
- for (int i = 0; i < face_sets.size(); ++i) {
- const std::string &grp_name = face_sets[i];
+ int current_mat = 0;
- if (r_mat_map.find(grp_name) == r_mat_map.end()) {
- r_mat_map[grp_name] = 1 + current_mat++;
- }
+ for (int i = 0; i < face_sets.size(); ++i) {
+ const std::string &grp_name = face_sets[i];
- const int assigned_mat = r_mat_map[grp_name];
+ if (r_mat_map.find(grp_name) == r_mat_map.end()) {
+ r_mat_map[grp_name] = 1 + current_mat++;
+ }
- const IFaceSet faceset = m_schema.getFaceSet(grp_name);
+ const int assigned_mat = r_mat_map[grp_name];
- if (!faceset.valid()) {
- std::cerr << " Face set " << grp_name << " invalid for " << m_object_name << "\n";
- continue;
- }
+ const IFaceSet faceset = m_schema.getFaceSet(grp_name);
- const IFaceSetSchema face_schem = faceset.getSchema();
- const IFaceSetSchema::Sample face_sample = face_schem.getValue(sample_sel);
- const Int32ArraySamplePtr group_faces = face_sample.getFaces();
- const size_t num_group_faces = group_faces->size();
+ if (!faceset.valid()) {
+ std::cerr << " Face set " << grp_name << " invalid for " << m_object_name << "\n";
+ continue;
+ }
- for (size_t l = 0; l < num_group_faces; l++) {
- size_t pos = (*group_faces)[l] + poly_start;
+ const IFaceSetSchema face_schem = faceset.getSchema();
+ const IFaceSetSchema::Sample face_sample = face_schem.getValue(sample_sel);
+ const Int32ArraySamplePtr group_faces = face_sample.getFaces();
+ const size_t num_group_faces = group_faces->size();
- if (pos >= totpoly) {
- std::cerr << "Faceset overflow on " << faceset.getName() << '\n';
- break;
- }
+ for (size_t l = 0; l < num_group_faces; l++) {
+ size_t pos = (*group_faces)[l] + poly_start;
- MPoly &poly = mpoly[pos];
- poly.mat_nr = assigned_mat - 1;
- }
- }
+ if (pos >= totpoly) {
+ std::cerr << "Faceset overflow on " << faceset.getName() << '\n';
+ break;
+ }
+ MPoly &poly = mpoly[pos];
+ poly.mat_nr = assigned_mat - 1;
+ }
+ }
}
-void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
+void AbcMeshReader::readFaceSetsSample(Main *bmain,
+ Mesh *mesh,
+ size_t poly_start,
const ISampleSelector &sample_sel)
{
- std::map<std::string, int> mat_map;
- assign_facesets_to_mpoly(sample_sel,
- poly_start, mesh->mpoly, mesh->totpoly,
- mat_map);
- utils::assign_materials(bmain, m_object, mat_map);
+ std::map<std::string, int> mat_map;
+ assign_facesets_to_mpoly(sample_sel, poly_start, mesh->mpoly, mesh->totpoly, mat_map);
+ utils::assign_materials(bmain, m_object, mat_map);
}
/* ************************************************************************** */
ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2)
{
- for (int i = 0, e = totedge; i < e; ++i) {
- MEdge &edge = edges[i];
+ for (int i = 0, e = totedge; i < e; ++i) {
+ MEdge &edge = edges[i];
- if (edge.v1 == v1 && edge.v2 == v2) {
- return &edge;
- }
- }
+ if (edge.v1 == v1 && edge.v2 == v2) {
+ return &edge;
+ }
+ }
- return NULL;
+ return NULL;
}
-static void read_subd_sample(const std::string & iobject_full_name,
+static void read_subd_sample(const std::string &iobject_full_name,
ImportSettings *settings,
const ISubDSchema &schema,
const ISampleSelector &selector,
CDStreamConfig &config)
{
- const ISubDSchema::Sample sample = schema.getValue(selector);
-
- AbcMeshData abc_mesh_data;
- abc_mesh_data.face_counts = sample.getFaceCounts();
- abc_mesh_data.face_indices = sample.getFaceIndices();
- abc_mesh_data.vertex_normals = N3fArraySamplePtr();
- 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(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);
- }
-
- if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
- read_mverts(config, abc_mesh_data);
- }
-
- if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
- read_mpolys(config, abc_mesh_data);
- }
-
- if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
- read_custom_data(iobject_full_name,
- schema.getArbGeomParams(), config, selector);
- }
+ const ISubDSchema::Sample sample = schema.getValue(selector);
+
+ AbcMeshData abc_mesh_data;
+ abc_mesh_data.face_counts = sample.getFaceCounts();
+ abc_mesh_data.face_indices = sample.getFaceIndices();
+ abc_mesh_data.vertex_normals = N3fArraySamplePtr();
+ 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(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);
+ }
+
+ if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
+ read_mverts(config, abc_mesh_data);
+ }
+
+ if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
+ read_mpolys(config, abc_mesh_data);
+ }
+
+ if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
+ read_custom_data(iobject_full_name, schema.getArbGeomParams(), config, selector);
+ }
}
/* ************************************************************************** */
@@ -1311,88 +1311,91 @@ static void read_subd_sample(const std::string & iobject_full_name,
AbcSubDReader::AbcSubDReader(const IObject &object, ImportSettings &settings)
: AbcObjectReader(object, settings)
{
- m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
+ m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
- ISubD isubd_mesh(m_iobject, kWrapExisting);
- m_schema = isubd_mesh.getSchema();
+ ISubD isubd_mesh(m_iobject, kWrapExisting);
+ m_schema = isubd_mesh.getSchema();
- get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
+ get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
}
bool AbcSubDReader::valid() const
{
- return m_schema.valid();
+ return m_schema.valid();
}
-bool AbcSubDReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const
+bool AbcSubDReader::accepts_object_type(
+ const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
{
- if (!Alembic::AbcGeom::ISubD::matches(alembic_header)) {
- *err_str = "Object type mismatch, Alembic object path pointed to SubD when importing, but not any more.";
- return false;
- }
-
- if (ob->type != OB_MESH) {
- *err_str = "Object type mismatch, Alembic object path points to SubD.";
- return false;
- }
-
- return true;
+ if (!Alembic::AbcGeom::ISubD::matches(alembic_header)) {
+ *err_str =
+ "Object type mismatch, Alembic object path pointed to SubD when importing, but not any "
+ "more.";
+ return false;
+ }
+
+ if (ob->type != OB_MESH) {
+ *err_str = "Object type mismatch, Alembic object path points to SubD.";
+ return false;
+ }
+
+ return true;
}
void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
- Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
-
- m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
- m_object->data = mesh;
-
- Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
- if (read_mesh != mesh) {
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_MESH, true);
- }
-
- ISubDSchema::Sample sample;
- try {
- sample = m_schema.getValue(sample_sel);
- }
- catch(Alembic::Util::Exception &ex) {
- printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
- m_iobject.getFullName().c_str(),
- m_schema.getName().c_str(),
- sample_sel.getRequestedTime(),
- ex.what());
- return;
- }
-
- Int32ArraySamplePtr indices = sample.getCreaseIndices();
- Alembic::Abc::FloatArraySamplePtr sharpnesses = sample.getCreaseSharpnesses();
-
- MEdge *edges = mesh->medge;
-
- if (indices && sharpnesses) {
- for (int i = 0, s = 0, e = indices->size(); i < e; i += 2, ++s) {
- MEdge *edge = find_edge(edges, mesh->totedge, (*indices)[i], (*indices)[i + 1]);
-
- if (edge) {
- edge->crease = unit_float_to_uchar_clamp((*sharpnesses)[s]);
- }
- }
-
- mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
- }
-
- BKE_mesh_calc_normals(mesh);
- BKE_mesh_calc_edges(mesh, false, false);
-
- if (m_settings->validate_meshes) {
- BKE_mesh_validate(mesh, false, false);
- }
-
- if (has_animations(m_schema, m_settings)) {
- addCacheModifier();
- }
+ Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
+
+ m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
+ m_object->data = mesh;
+
+ Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
+ if (read_mesh != mesh) {
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_MESH, true);
+ }
+
+ ISubDSchema::Sample sample;
+ try {
+ sample = m_schema.getValue(sample_sel);
+ }
+ catch (Alembic::Util::Exception &ex) {
+ printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ m_schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return;
+ }
+
+ Int32ArraySamplePtr indices = sample.getCreaseIndices();
+ Alembic::Abc::FloatArraySamplePtr sharpnesses = sample.getCreaseSharpnesses();
+
+ MEdge *edges = mesh->medge;
+
+ if (indices && sharpnesses) {
+ for (int i = 0, s = 0, e = indices->size(); i < e; i += 2, ++s) {
+ MEdge *edge = find_edge(edges, mesh->totedge, (*indices)[i], (*indices)[i + 1]);
+
+ if (edge) {
+ edge->crease = unit_float_to_uchar_clamp((*sharpnesses)[s]);
+ }
+ }
+
+ mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ }
+
+ BKE_mesh_calc_normals(mesh);
+ BKE_mesh_calc_edges(mesh, false, false);
+
+ if (m_settings->validate_meshes) {
+ BKE_mesh_validate(mesh, false, false);
+ }
+
+ if (has_animations(m_schema, m_settings)) {
+ addCacheModifier();
+ }
}
Mesh *AbcSubDReader::read_mesh(Mesh *existing_mesh,
@@ -1400,72 +1403,67 @@ Mesh *AbcSubDReader::read_mesh(Mesh *existing_mesh,
int read_flag,
const char **err_str)
{
- ISubDSchema::Sample sample;
- try {
- sample = m_schema.getValue(sample_sel);
- }
- catch(Alembic::Util::Exception &ex) {
- *err_str = "Error reading mesh sample; more detail on the console";
- printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
- m_iobject.getFullName().c_str(),
- m_schema.getName().c_str(),
- sample_sel.getRequestedTime(),
- ex.what());
- return existing_mesh;
- }
-
- const P3fArraySamplePtr &positions = sample.getPositions();
- const Alembic::Abc::Int32ArraySamplePtr &face_indices = sample.getFaceIndices();
- const Alembic::Abc::Int32ArraySamplePtr &face_counts = sample.getFaceCounts();
-
- Mesh *new_mesh = NULL;
-
- ImportSettings settings;
- settings.read_flag |= read_flag;
-
- if (existing_mesh->totvert != positions->size()) {
- new_mesh = BKE_mesh_new_nomain_from_template(existing_mesh,
- positions->size(),
- 0,
- 0,
- face_indices->size(),
- face_counts->size());
-
- settings.read_flag |= MOD_MESHSEQ_READ_ALL;
- }
- else {
- /* If the face count changed (e.g. by triangulation), only read points.
- * This prevents crash from T49813.
- * TODO(kevin): perhaps find a better way to do this? */
- if (face_counts->size() != existing_mesh->totpoly ||
- face_indices->size() != existing_mesh->totpoly)
- {
- settings.read_flag = MOD_MESHSEQ_READ_VERT;
-
- if (err_str) {
- *err_str = "Topology has changed, perhaps by triangulating the"
- " mesh. Only vertices will be read!";
- }
- }
- }
-
- /* Only read point data when streaming meshes, unless we need to create new ones. */
- CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
- config.time = sample_sel.getRequestedTime();
- read_subd_sample(m_iobject.getFullName(),
- &settings, m_schema, sample_sel, config);
-
- if (new_mesh) {
- /* Check if we had ME_SMOOTH flag set to restore it. */
- if (check_smooth_poly_flag(existing_mesh)) {
- set_smooth_poly_flag(new_mesh);
- }
-
- BKE_mesh_calc_normals(new_mesh);
- BKE_mesh_calc_edges(new_mesh, false, false);
-
- return new_mesh;
- }
-
- return existing_mesh;
+ ISubDSchema::Sample sample;
+ try {
+ sample = m_schema.getValue(sample_sel);
+ }
+ catch (Alembic::Util::Exception &ex) {
+ *err_str = "Error reading mesh sample; more detail on the console";
+ printf("Alembic: error reading mesh sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ m_schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return existing_mesh;
+ }
+
+ const P3fArraySamplePtr &positions = sample.getPositions();
+ const Alembic::Abc::Int32ArraySamplePtr &face_indices = sample.getFaceIndices();
+ const Alembic::Abc::Int32ArraySamplePtr &face_counts = sample.getFaceCounts();
+
+ Mesh *new_mesh = NULL;
+
+ ImportSettings settings;
+ settings.read_flag |= read_flag;
+
+ if (existing_mesh->totvert != positions->size()) {
+ new_mesh = BKE_mesh_new_nomain_from_template(
+ existing_mesh, positions->size(), 0, 0, face_indices->size(), face_counts->size());
+
+ settings.read_flag |= MOD_MESHSEQ_READ_ALL;
+ }
+ else {
+ /* If the face count changed (e.g. by triangulation), only read points.
+ * This prevents crash from T49813.
+ * TODO(kevin): perhaps find a better way to do this? */
+ if (face_counts->size() != existing_mesh->totpoly ||
+ face_indices->size() != existing_mesh->totpoly) {
+ settings.read_flag = MOD_MESHSEQ_READ_VERT;
+
+ if (err_str) {
+ *err_str =
+ "Topology has changed, perhaps by triangulating the"
+ " mesh. Only vertices will be read!";
+ }
+ }
+ }
+
+ /* Only read point data when streaming meshes, unless we need to create new ones. */
+ CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
+ config.time = sample_sel.getRequestedTime();
+ read_subd_sample(m_iobject.getFullName(), &settings, m_schema, sample_sel, config);
+
+ if (new_mesh) {
+ /* Check if we had ME_SMOOTH flag set to restore it. */
+ if (check_smooth_poly_flag(existing_mesh)) {
+ set_smooth_poly_flag(new_mesh);
+ }
+
+ BKE_mesh_calc_normals(new_mesh);
+ BKE_mesh_calc_edges(new_mesh, false, false);
+
+ return new_mesh;
+ }
+
+ return existing_mesh;
}
diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h
index 35ad0f8b297..6cbaeea6536 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -31,117 +31,118 @@ struct ModifierData;
/* Writer for Alembic meshes. Does not assume the object is a mesh object. */
class AbcGenericMeshWriter : public AbcObjectWriter {
-protected:
- Alembic::AbcGeom::OPolyMeshSchema m_mesh_schema;
- Alembic::AbcGeom::OPolyMeshSchema::Sample m_mesh_sample;
+ protected:
+ Alembic::AbcGeom::OPolyMeshSchema m_mesh_schema;
+ Alembic::AbcGeom::OPolyMeshSchema::Sample m_mesh_sample;
- Alembic::AbcGeom::OSubDSchema m_subdiv_schema;
- Alembic::AbcGeom::OSubDSchema::Sample m_subdiv_sample;
+ Alembic::AbcGeom::OSubDSchema m_subdiv_schema;
+ Alembic::AbcGeom::OSubDSchema::Sample m_subdiv_sample;
- Alembic::Abc::OArrayProperty m_mat_indices;
+ Alembic::Abc::OArrayProperty m_mat_indices;
- bool m_is_animated;
- ModifierData *m_subsurf_mod;
+ bool m_is_animated;
+ ModifierData *m_subsurf_mod;
- CDStreamConfig m_custom_data_config;
+ CDStreamConfig m_custom_data_config;
- bool m_is_liquid;
- bool m_is_subd;
+ bool m_is_liquid;
+ bool m_is_subd;
-public:
- AbcGenericMeshWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings);
+ public:
+ AbcGenericMeshWriter(Object *ob,
+ AbcTransformWriter *parent,
+ uint32_t time_sampling,
+ ExportSettings &settings);
- ~AbcGenericMeshWriter();
- void setIsAnimated(bool is_animated);
+ ~AbcGenericMeshWriter();
+ void setIsAnimated(bool is_animated);
-protected:
- virtual void do_write();
- virtual bool isAnimated() const;
- virtual Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree) = 0;
- virtual void freeEvaluatedMesh(struct Mesh *mesh);
+ protected:
+ virtual void do_write();
+ virtual bool isAnimated() const;
+ virtual Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree) = 0;
+ virtual void freeEvaluatedMesh(struct Mesh *mesh);
- Mesh *getFinalMesh(bool &r_needsfree);
+ Mesh *getFinalMesh(bool &r_needsfree);
- void writeMesh(struct Mesh *mesh);
- void writeSubD(struct Mesh *mesh);
+ void writeMesh(struct Mesh *mesh);
+ void writeSubD(struct Mesh *mesh);
- void writeArbGeoParams(struct Mesh *mesh);
- void getGeoGroups(struct Mesh *mesh, std::map<std::string, std::vector<int32_t>> &geoGroups);
+ void writeArbGeoParams(struct Mesh *mesh);
+ void getGeoGroups(struct Mesh *mesh, std::map<std::string, std::vector<int32_t>> &geoGroups);
- /* fluid surfaces support */
- void getVelocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels);
+ /* fluid surfaces support */
+ void getVelocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels);
- template <typename Schema>
- void writeFaceSets(struct Mesh *mesh, Schema &schema);
+ template<typename Schema> void writeFaceSets(struct Mesh *mesh, Schema &schema);
};
-
class AbcMeshWriter : public AbcGenericMeshWriter {
-public:
- AbcMeshWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings);
-
- ~AbcMeshWriter();
-protected:
- virtual Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree) override;
-};
+ public:
+ AbcMeshWriter(Object *ob,
+ AbcTransformWriter *parent,
+ uint32_t time_sampling,
+ ExportSettings &settings);
+ ~AbcMeshWriter();
+
+ protected:
+ virtual Mesh *getEvaluatedMesh(Scene *scene_eval, Object *ob_eval, bool &r_needsfree) override;
+};
/* ************************************************************************** */
class AbcMeshReader : public AbcObjectReader {
- Alembic::AbcGeom::IPolyMeshSchema m_schema;
-
- CDStreamConfig m_mesh_data;
-
-public:
- AbcMeshReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
-
- bool valid() const;
- bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const;
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
-
- struct Mesh *read_mesh(struct Mesh *existing_mesh,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
-
-private:
- void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
- const Alembic::AbcGeom::ISampleSelector &sample_sel);
-
- void assign_facesets_to_mpoly(const Alembic::Abc::ISampleSelector &sample_sel,
- size_t poly_start,
- MPoly *mpoly, int totpoly,
- std::map<std::string, int> & r_mat_map);
+ Alembic::AbcGeom::IPolyMeshSchema m_schema;
+
+ CDStreamConfig m_mesh_data;
+
+ public:
+ AbcMeshReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
+
+ bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
+
+ struct Mesh *read_mesh(struct Mesh *existing_mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
+
+ private:
+ void readFaceSetsSample(Main *bmain,
+ Mesh *mesh,
+ size_t poly_start,
+ const Alembic::AbcGeom::ISampleSelector &sample_sel);
+
+ void assign_facesets_to_mpoly(const Alembic::Abc::ISampleSelector &sample_sel,
+ size_t poly_start,
+ MPoly *mpoly,
+ int totpoly,
+ std::map<std::string, int> &r_mat_map);
};
/* ************************************************************************** */
class AbcSubDReader : public AbcObjectReader {
- Alembic::AbcGeom::ISubDSchema m_schema;
-
- CDStreamConfig m_mesh_data;
-
-public:
- AbcSubDReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
-
- bool valid() const;
- bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const;
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
- struct Mesh *read_mesh(struct Mesh *existing_mesh,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
+ Alembic::AbcGeom::ISubDSchema m_schema;
+
+ CDStreamConfig m_mesh_data;
+
+ public:
+ AbcSubDReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
+
+ bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
+ struct Mesh *read_mesh(struct Mesh *existing_mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
};
/* ************************************************************************** */
@@ -152,4 +153,4 @@ void read_mverts(MVert *mverts,
CDStreamConfig get_config(struct Mesh *mesh);
-#endif /* __ABC_MESH_H__ */
+#endif /* __ABC_MESH_H__ */
diff --git a/source/blender/alembic/intern/abc_nurbs.cc b/source/blender/alembic/intern/abc_nurbs.cc
index 463396c0b65..c78cc4570c9 100644
--- a/source/blender/alembic/intern/abc_nurbs.cc
+++ b/source/blender/alembic/intern/abc_nurbs.cc
@@ -40,9 +40,9 @@ extern "C" {
using Alembic::AbcGeom::bool_t;
using Alembic::AbcGeom::FloatArraySample;
using Alembic::AbcGeom::FloatArraySamplePtr;
+using Alembic::AbcGeom::kWrapExisting;
using Alembic::AbcGeom::MetaData;
using Alembic::AbcGeom::P3fArraySamplePtr;
-using Alembic::AbcGeom::kWrapExisting;
using Alembic::AbcGeom::IBoolProperty;
using Alembic::AbcGeom::ICompoundProperty;
@@ -64,132 +64,132 @@ AbcNurbsWriter::AbcNurbsWriter(Object *ob,
ExportSettings &settings)
: AbcObjectWriter(ob, time_sampling, settings, parent)
{
- m_is_animated = isAnimated();
+ m_is_animated = isAnimated();
- /* if the object is static, use the default static time sampling */
- if (!m_is_animated) {
- m_time_sampling = 0;
- }
+ /* if the object is static, use the default static time sampling */
+ if (!m_is_animated) {
+ m_time_sampling = 0;
+ }
- Curve *curve = static_cast<Curve *>(m_object->data);
- size_t numNurbs = BLI_listbase_count(&curve->nurb);
+ Curve *curve = static_cast<Curve *>(m_object->data);
+ size_t numNurbs = BLI_listbase_count(&curve->nurb);
- for (size_t i = 0; i < numNurbs; ++i) {
- std::stringstream str;
- str << m_name << '_' << i;
+ for (size_t i = 0; i < numNurbs; ++i) {
+ std::stringstream str;
+ str << m_name << '_' << i;
- while (parent->alembicXform().getChildHeader(str.str())) {
- str << "_";
- }
+ while (parent->alembicXform().getChildHeader(str.str())) {
+ str << "_";
+ }
- ONuPatch nurbs(parent->alembicXform(), str.str().c_str(), m_time_sampling);
- m_nurbs_schema.push_back(nurbs.getSchema());
- }
+ ONuPatch nurbs(parent->alembicXform(), str.str().c_str(), m_time_sampling);
+ m_nurbs_schema.push_back(nurbs.getSchema());
+ }
}
bool AbcNurbsWriter::isAnimated() const
{
- /* check if object has shape keys */
- Curve *cu = static_cast<Curve *>(m_object->data);
- return (cu->key != NULL);
+ /* check if object has shape keys */
+ Curve *cu = static_cast<Curve *>(m_object->data);
+ return (cu->key != NULL);
}
static void get_knots(std::vector<float> &knots, const int num_knots, float *nu_knots)
{
- if (num_knots <= 1) {
- return;
- }
+ if (num_knots <= 1) {
+ return;
+ }
- /* Add an extra knot at the beginning and end of the array since most apps
- * require/expect them. */
- knots.reserve(num_knots + 2);
+ /* Add an extra knot at the beginning and end of the array since most apps
+ * require/expect them. */
+ knots.reserve(num_knots + 2);
- knots.push_back(0.0f);
+ knots.push_back(0.0f);
- for (int i = 0; i < num_knots; ++i) {
- knots.push_back(nu_knots[i]);
- }
+ for (int i = 0; i < num_knots; ++i) {
+ knots.push_back(nu_knots[i]);
+ }
- knots[0] = 2.0f * knots[1] - knots[2];
- knots.push_back(2.0f * knots[num_knots] - knots[num_knots - 1]);
+ knots[0] = 2.0f * knots[1] - knots[2];
+ knots.push_back(2.0f * knots[num_knots] - knots[num_knots - 1]);
}
void AbcNurbsWriter::do_write()
{
- /* we have already stored a sample for this object. */
- if (!m_first_frame && !m_is_animated) {
- return;
- }
-
- if (!ELEM(m_object->type, OB_SURF, OB_CURVE)) {
- return;
- }
-
- Curve *curve = static_cast<Curve *>(m_object->data);
- ListBase *nulb;
-
- if (m_object->runtime.curve_cache->deformed_nurbs.first != NULL) {
- nulb = &m_object->runtime.curve_cache->deformed_nurbs;
- }
- else {
- nulb = BKE_curve_nurbs_get(curve);
- }
-
- size_t count = 0;
- for (Nurb *nu = static_cast<Nurb *>(nulb->first); nu; nu = nu->next, ++count) {
- std::vector<float> knotsU;
- get_knots(knotsU, KNOTSU(nu), nu->knotsu);
-
- std::vector<float> knotsV;
- get_knots(knotsV, KNOTSV(nu), nu->knotsv);
-
- const int size = nu->pntsu * nu->pntsv;
- std::vector<Imath::V3f> positions(size);
- std::vector<float> weights(size);
-
- const BPoint *bp = nu->bp;
-
- for (int i = 0; i < size; ++i, ++bp) {
- copy_yup_from_zup(positions[i].getValue(), bp->vec);
- weights[i] = bp->vec[3];
- }
-
- ONuPatchSchema::Sample sample;
- sample.setUOrder(nu->orderu + 1);
- sample.setVOrder(nu->orderv + 1);
- sample.setPositions(positions);
- sample.setPositionWeights(weights);
- sample.setUKnot(FloatArraySample(knotsU));
- sample.setVKnot(FloatArraySample(knotsV));
- sample.setNu(nu->pntsu);
- sample.setNv(nu->pntsv);
-
- /* TODO(kevin): to accommodate other software we should duplicate control
- * points to indicate that a NURBS is cyclic. */
- OCompoundProperty user_props = m_nurbs_schema[count].getUserProperties();
-
- if ((nu->flagu & CU_NURB_ENDPOINT) != 0) {
- OBoolProperty prop(user_props, "endpoint_u");
- prop.set(true);
- }
-
- if ((nu->flagv & CU_NURB_ENDPOINT) != 0) {
- OBoolProperty prop(user_props, "endpoint_v");
- prop.set(true);
- }
-
- if ((nu->flagu & CU_NURB_CYCLIC) != 0) {
- OBoolProperty prop(user_props, "cyclic_u");
- prop.set(true);
- }
-
- if ((nu->flagv & CU_NURB_CYCLIC) != 0) {
- OBoolProperty prop(user_props, "cyclic_v");
- prop.set(true);
- }
-
- m_nurbs_schema[count].set(sample);
- }
+ /* we have already stored a sample for this object. */
+ if (!m_first_frame && !m_is_animated) {
+ return;
+ }
+
+ if (!ELEM(m_object->type, OB_SURF, OB_CURVE)) {
+ return;
+ }
+
+ Curve *curve = static_cast<Curve *>(m_object->data);
+ ListBase *nulb;
+
+ if (m_object->runtime.curve_cache->deformed_nurbs.first != NULL) {
+ nulb = &m_object->runtime.curve_cache->deformed_nurbs;
+ }
+ else {
+ nulb = BKE_curve_nurbs_get(curve);
+ }
+
+ size_t count = 0;
+ for (Nurb *nu = static_cast<Nurb *>(nulb->first); nu; nu = nu->next, ++count) {
+ std::vector<float> knotsU;
+ get_knots(knotsU, KNOTSU(nu), nu->knotsu);
+
+ std::vector<float> knotsV;
+ get_knots(knotsV, KNOTSV(nu), nu->knotsv);
+
+ const int size = nu->pntsu * nu->pntsv;
+ std::vector<Imath::V3f> positions(size);
+ std::vector<float> weights(size);
+
+ const BPoint *bp = nu->bp;
+
+ for (int i = 0; i < size; ++i, ++bp) {
+ copy_yup_from_zup(positions[i].getValue(), bp->vec);
+ weights[i] = bp->vec[3];
+ }
+
+ ONuPatchSchema::Sample sample;
+ sample.setUOrder(nu->orderu + 1);
+ sample.setVOrder(nu->orderv + 1);
+ sample.setPositions(positions);
+ sample.setPositionWeights(weights);
+ sample.setUKnot(FloatArraySample(knotsU));
+ sample.setVKnot(FloatArraySample(knotsV));
+ sample.setNu(nu->pntsu);
+ sample.setNv(nu->pntsv);
+
+ /* TODO(kevin): to accommodate other software we should duplicate control
+ * points to indicate that a NURBS is cyclic. */
+ OCompoundProperty user_props = m_nurbs_schema[count].getUserProperties();
+
+ if ((nu->flagu & CU_NURB_ENDPOINT) != 0) {
+ OBoolProperty prop(user_props, "endpoint_u");
+ prop.set(true);
+ }
+
+ if ((nu->flagv & CU_NURB_ENDPOINT) != 0) {
+ OBoolProperty prop(user_props, "endpoint_v");
+ prop.set(true);
+ }
+
+ if ((nu->flagu & CU_NURB_CYCLIC) != 0) {
+ OBoolProperty prop(user_props, "cyclic_u");
+ prop.set(true);
+ }
+
+ if ((nu->flagv & CU_NURB_CYCLIC) != 0) {
+ OBoolProperty prop(user_props, "cyclic_v");
+ prop.set(true);
+ }
+
+ m_nurbs_schema[count].set(sample);
+ }
}
/* ************************************************************************** */
@@ -197,179 +197,178 @@ void AbcNurbsWriter::do_write()
AbcNurbsReader::AbcNurbsReader(const IObject &object, ImportSettings &settings)
: AbcObjectReader(object, settings)
{
- getNurbsPatches(m_iobject);
- get_min_max_time(m_iobject, m_schemas[0].first, m_min_time, m_max_time);
+ getNurbsPatches(m_iobject);
+ get_min_max_time(m_iobject, m_schemas[0].first, m_min_time, m_max_time);
}
bool AbcNurbsReader::valid() const
{
- if (m_schemas.empty()) {
- return false;
- }
+ if (m_schemas.empty()) {
+ return false;
+ }
- std::vector<std::pair<INuPatchSchema, IObject>>::const_iterator it;
- for (it = m_schemas.begin(); it != m_schemas.end(); ++it) {
- const INuPatchSchema &schema = it->first;
+ std::vector<std::pair<INuPatchSchema, IObject>>::const_iterator it;
+ for (it = m_schemas.begin(); it != m_schemas.end(); ++it) {
+ const INuPatchSchema &schema = it->first;
- if (!schema.valid()) {
- return false;
- }
- }
+ if (!schema.valid()) {
+ return false;
+ }
+ }
- return true;
+ return true;
}
static bool set_knots(const FloatArraySamplePtr &knots, float *&nu_knots)
{
- if (!knots || knots->size() == 0) {
- return false;
- }
+ if (!knots || knots->size() == 0) {
+ return false;
+ }
- /* Skip first and last knots, as they are used for padding. */
- const size_t num_knots = knots->size() - 2;
- nu_knots = static_cast<float *>(MEM_callocN(num_knots * sizeof(float), "abc_setsplineknotsu"));
+ /* Skip first and last knots, as they are used for padding. */
+ const size_t num_knots = knots->size() - 2;
+ nu_knots = static_cast<float *>(MEM_callocN(num_knots * sizeof(float), "abc_setsplineknotsu"));
- for (size_t i = 0; i < num_knots; ++i) {
- nu_knots[i] = (*knots)[i + 1];
- }
+ for (size_t i = 0; i < num_knots; ++i) {
+ nu_knots[i] = (*knots)[i + 1];
+ }
- return true;
+ return true;
}
void AbcNurbsReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
- Curve *cu = static_cast<Curve *>(BKE_curve_add(bmain, "abc_curve", OB_SURF));
- cu->actvert = CU_ACT_NONE;
-
- std::vector<std::pair<INuPatchSchema, IObject>>::iterator it;
+ Curve *cu = static_cast<Curve *>(BKE_curve_add(bmain, "abc_curve", OB_SURF));
+ cu->actvert = CU_ACT_NONE;
- for (it = m_schemas.begin(); it != m_schemas.end(); ++it) {
- Nurb *nu = static_cast<Nurb *>(MEM_callocN(sizeof(Nurb), "abc_getnurb"));
- nu->flag = CU_SMOOTH;
- nu->type = CU_NURBS;
- nu->resolu = cu->resolu;
- nu->resolv = cu->resolv;
+ std::vector<std::pair<INuPatchSchema, IObject>>::iterator it;
- const INuPatchSchema &schema = it->first;
- INuPatchSchema::Sample smp;
- try {
- smp = schema.getValue(sample_sel);
- }
- catch(Alembic::Util::Exception &ex) {
- printf("Alembic: error reading nurbs sample for '%s/%s' at time %f: %s\n",
- m_iobject.getFullName().c_str(),
- schema.getName().c_str(),
- sample_sel.getRequestedTime(),
- ex.what());
- return;
- }
+ for (it = m_schemas.begin(); it != m_schemas.end(); ++it) {
+ Nurb *nu = static_cast<Nurb *>(MEM_callocN(sizeof(Nurb), "abc_getnurb"));
+ nu->flag = CU_SMOOTH;
+ nu->type = CU_NURBS;
+ nu->resolu = cu->resolu;
+ nu->resolv = cu->resolv;
+ const INuPatchSchema &schema = it->first;
+ INuPatchSchema::Sample smp;
+ try {
+ smp = schema.getValue(sample_sel);
+ }
+ catch (Alembic::Util::Exception &ex) {
+ printf("Alembic: error reading nurbs sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return;
+ }
- nu->orderu = smp.getUOrder() - 1;
- nu->orderv = smp.getVOrder() - 1;
- nu->pntsu = smp.getNumU();
- nu->pntsv = smp.getNumV();
+ nu->orderu = smp.getUOrder() - 1;
+ nu->orderv = smp.getVOrder() - 1;
+ nu->pntsu = smp.getNumU();
+ nu->pntsv = smp.getNumV();
- /* Read positions and weights. */
+ /* Read positions and weights. */
- const P3fArraySamplePtr positions = smp.getPositions();
- const FloatArraySamplePtr weights = smp.getPositionWeights();
+ const P3fArraySamplePtr positions = smp.getPositions();
+ const FloatArraySamplePtr weights = smp.getPositionWeights();
- const size_t num_points = positions->size();
+ const size_t num_points = positions->size();
- nu->bp = static_cast<BPoint *>(MEM_callocN(num_points * sizeof(BPoint), "abc_setsplinetype"));
+ nu->bp = static_cast<BPoint *>(MEM_callocN(num_points * sizeof(BPoint), "abc_setsplinetype"));
- BPoint *bp = nu->bp;
- float posw_in = 1.0f;
+ BPoint *bp = nu->bp;
+ float posw_in = 1.0f;
- for (int i = 0; i < num_points; ++i, ++bp) {
- const Imath::V3f &pos_in = (*positions)[i];
+ for (int i = 0; i < num_points; ++i, ++bp) {
+ const Imath::V3f &pos_in = (*positions)[i];
- if (weights) {
- posw_in = (*weights)[i];
- }
+ if (weights) {
+ posw_in = (*weights)[i];
+ }
- copy_zup_from_yup(bp->vec, pos_in.getValue());
- bp->vec[3] = posw_in;
- bp->f1 = SELECT;
- bp->radius = 1.0f;
- bp->weight = 1.0f;
- }
+ copy_zup_from_yup(bp->vec, pos_in.getValue());
+ bp->vec[3] = posw_in;
+ bp->f1 = SELECT;
+ bp->radius = 1.0f;
+ bp->weight = 1.0f;
+ }
- /* Read knots. */
+ /* Read knots. */
- if (!set_knots(smp.getUKnot(), nu->knotsu)) {
- BKE_nurb_knot_calc_u(nu);
- }
+ if (!set_knots(smp.getUKnot(), nu->knotsu)) {
+ BKE_nurb_knot_calc_u(nu);
+ }
- if (!set_knots(smp.getVKnot(), nu->knotsv)) {
- BKE_nurb_knot_calc_v(nu);
- }
+ if (!set_knots(smp.getVKnot(), nu->knotsv)) {
+ BKE_nurb_knot_calc_v(nu);
+ }
- /* Read flags. */
+ /* Read flags. */
- ICompoundProperty user_props = schema.getUserProperties();
+ ICompoundProperty user_props = schema.getUserProperties();
- if (has_property(user_props, "enpoint_u")) {
- nu->flagu |= CU_NURB_ENDPOINT;
- }
+ if (has_property(user_props, "enpoint_u")) {
+ nu->flagu |= CU_NURB_ENDPOINT;
+ }
- if (has_property(user_props, "enpoint_v")) {
- nu->flagv |= CU_NURB_ENDPOINT;
- }
+ if (has_property(user_props, "enpoint_v")) {
+ nu->flagv |= CU_NURB_ENDPOINT;
+ }
- if (has_property(user_props, "cyclic_u")) {
- nu->flagu |= CU_NURB_CYCLIC;
- }
+ if (has_property(user_props, "cyclic_u")) {
+ nu->flagu |= CU_NURB_CYCLIC;
+ }
- if (has_property(user_props, "cyclic_v")) {
- nu->flagv |= CU_NURB_CYCLIC;
- }
+ if (has_property(user_props, "cyclic_v")) {
+ nu->flagv |= CU_NURB_CYCLIC;
+ }
- BLI_addtail(BKE_curve_nurbs_get(cu), nu);
- }
+ BLI_addtail(BKE_curve_nurbs_get(cu), nu);
+ }
- BLI_strncpy(cu->id.name + 2, m_data_name.c_str(), m_data_name.size() + 1);
+ BLI_strncpy(cu->id.name + 2, m_data_name.c_str(), m_data_name.size() + 1);
- m_object = BKE_object_add_only_object(bmain, OB_SURF, m_object_name.c_str());
- m_object->data = cu;
+ m_object = BKE_object_add_only_object(bmain, OB_SURF, m_object_name.c_str());
+ m_object->data = cu;
}
void AbcNurbsReader::getNurbsPatches(const IObject &obj)
{
- if (!obj.valid()) {
- return;
- }
+ if (!obj.valid()) {
+ return;
+ }
- const int num_children = obj.getNumChildren();
+ const int num_children = obj.getNumChildren();
- if (num_children == 0) {
- INuPatch abc_nurb(obj, kWrapExisting);
- INuPatchSchema schem = abc_nurb.getSchema();
- m_schemas.push_back(std::pair<INuPatchSchema, IObject>(schem, obj));
- return;
- }
+ if (num_children == 0) {
+ INuPatch abc_nurb(obj, kWrapExisting);
+ INuPatchSchema schem = abc_nurb.getSchema();
+ m_schemas.push_back(std::pair<INuPatchSchema, IObject>(schem, obj));
+ return;
+ }
- for (int i = 0; i < num_children; ++i) {
- bool ok = true;
- IObject child(obj, obj.getChildHeader(i).getName());
+ for (int i = 0; i < num_children; ++i) {
+ bool ok = true;
+ IObject child(obj, obj.getChildHeader(i).getName());
- if (!m_name.empty() && child.valid() && !begins_with(child.getFullName(), m_name)) {
- ok = false;
- }
+ if (!m_name.empty() && child.valid() && !begins_with(child.getFullName(), m_name)) {
+ ok = false;
+ }
- if (!child.valid()) {
- continue;
- }
+ if (!child.valid()) {
+ continue;
+ }
- const MetaData &md = child.getMetaData();
+ const MetaData &md = child.getMetaData();
- if (INuPatch::matches(md) && ok) {
- INuPatch abc_nurb(child, kWrapExisting);
- INuPatchSchema schem = abc_nurb.getSchema();
- m_schemas.push_back(std::pair<INuPatchSchema, IObject>(schem, child));
- }
+ if (INuPatch::matches(md) && ok) {
+ INuPatch abc_nurb(child, kWrapExisting);
+ INuPatchSchema schem = abc_nurb.getSchema();
+ m_schemas.push_back(std::pair<INuPatchSchema, IObject>(schem, child));
+ }
- getNurbsPatches(child);
- }
+ getNurbsPatches(child);
+ }
}
diff --git a/source/blender/alembic/intern/abc_nurbs.h b/source/blender/alembic/intern/abc_nurbs.h
index 89c54ba9c16..3e12c9a3b62 100644
--- a/source/blender/alembic/intern/abc_nurbs.h
+++ b/source/blender/alembic/intern/abc_nurbs.h
@@ -26,35 +26,35 @@
/* ************************************************************************** */
class AbcNurbsWriter : public AbcObjectWriter {
- std::vector<Alembic::AbcGeom::ONuPatchSchema> m_nurbs_schema;
- bool m_is_animated;
+ std::vector<Alembic::AbcGeom::ONuPatchSchema> m_nurbs_schema;
+ bool m_is_animated;
-public:
- AbcNurbsWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings);
+ public:
+ AbcNurbsWriter(Object *ob,
+ AbcTransformWriter *parent,
+ uint32_t time_sampling,
+ ExportSettings &settings);
-private:
- virtual void do_write();
+ private:
+ virtual void do_write();
- bool isAnimated() const;
+ bool isAnimated() const;
};
/* ************************************************************************** */
class AbcNurbsReader : public AbcObjectReader {
- std::vector<std::pair<Alembic::AbcGeom::INuPatchSchema, Alembic::Abc::IObject>> m_schemas;
+ std::vector<std::pair<Alembic::AbcGeom::INuPatchSchema, Alembic::Abc::IObject>> m_schemas;
-public:
- AbcNurbsReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
+ public:
+ AbcNurbsReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
- bool valid() const;
+ bool valid() const;
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
-private:
- void getNurbsPatches(const Alembic::Abc::IObject &obj);
+ private:
+ void getNurbsPatches(const Alembic::Abc::IObject &obj);
};
-#endif /* __ABC_NURBS_H__ */
+#endif /* __ABC_NURBS_H__ */
diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index d8bd92121aa..dddd985d796 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -27,7 +27,7 @@ extern "C" {
#include "DNA_constraint_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
-#include "DNA_space_types.h" /* for FILE_MAX */
+#include "DNA_space_types.h" /* for FILE_MAX */
#include "BKE_constraint.h"
#include "BKE_idprop.h"
@@ -60,186 +60,182 @@ AbcObjectWriter::AbcObjectWriter(Object *ob,
uint32_t time_sampling,
ExportSettings &settings,
AbcObjectWriter *parent)
- : m_object(ob)
- , m_settings(settings)
- , m_time_sampling(time_sampling)
- , m_first_frame(true)
+ : m_object(ob), m_settings(settings), m_time_sampling(time_sampling), m_first_frame(true)
{
- m_name = get_id_name(m_object) + "Shape";
+ m_name = get_id_name(m_object) + "Shape";
- if (parent) {
- parent->addChild(this);
- }
+ if (parent) {
+ parent->addChild(this);
+ }
}
AbcObjectWriter::~AbcObjectWriter()
-{}
+{
+}
void AbcObjectWriter::addChild(AbcObjectWriter *child)
{
- m_children.push_back(child);
+ m_children.push_back(child);
}
Imath::Box3d AbcObjectWriter::bounds()
{
- BoundBox *bb = BKE_object_boundbox_get(this->m_object);
+ BoundBox *bb = BKE_object_boundbox_get(this->m_object);
- if (!bb) {
- if (this->m_object->type != OB_CAMERA) {
- ABC_LOG(m_settings.logger) << "Bounding box is null!\n";
- }
+ if (!bb) {
+ if (this->m_object->type != OB_CAMERA) {
+ ABC_LOG(m_settings.logger) << "Bounding box is null!\n";
+ }
- return Imath::Box3d();
- }
+ return Imath::Box3d();
+ }
- /* Convert Z-up to Y-up. This also changes which vector goes into which min/max property. */
- this->m_bounds.min.x = bb->vec[0][0];
- this->m_bounds.min.y = bb->vec[0][2];
- this->m_bounds.min.z = -bb->vec[6][1];
+ /* Convert Z-up to Y-up. This also changes which vector goes into which min/max property. */
+ this->m_bounds.min.x = bb->vec[0][0];
+ this->m_bounds.min.y = bb->vec[0][2];
+ this->m_bounds.min.z = -bb->vec[6][1];
- this->m_bounds.max.x = bb->vec[6][0];
- this->m_bounds.max.y = bb->vec[6][2];
- this->m_bounds.max.z = -bb->vec[0][1];
+ this->m_bounds.max.x = bb->vec[6][0];
+ this->m_bounds.max.y = bb->vec[6][2];
+ this->m_bounds.max.z = -bb->vec[0][1];
- return this->m_bounds;
+ return this->m_bounds;
}
void AbcObjectWriter::write()
{
- do_write();
- m_first_frame = false;
+ do_write();
+ m_first_frame = false;
}
/* ************************************************************************** */
AbcObjectReader::AbcObjectReader(const IObject &object, ImportSettings &settings)
- : m_name("")
- , m_object_name("")
- , m_data_name("")
- , m_object(NULL)
- , m_iobject(object)
- , m_settings(&settings)
- , m_min_time(std::numeric_limits<chrono_t>::max())
- , m_max_time(std::numeric_limits<chrono_t>::min())
- , m_refcount(0)
- , parent_reader(NULL)
+ : m_name(""),
+ m_object_name(""),
+ m_data_name(""),
+ m_object(NULL),
+ m_iobject(object),
+ m_settings(&settings),
+ m_min_time(std::numeric_limits<chrono_t>::max()),
+ m_max_time(std::numeric_limits<chrono_t>::min()),
+ m_refcount(0),
+ parent_reader(NULL)
{
- m_name = object.getFullName();
- std::vector<std::string> parts;
- split(m_name, '/', parts);
-
- if (parts.size() >= 2) {
- m_object_name = parts[parts.size() - 2];
- m_data_name = parts[parts.size() - 1];
- }
- else {
- m_object_name = m_data_name = parts[parts.size() - 1];
- }
-
- determine_inherits_xform();
+ m_name = object.getFullName();
+ std::vector<std::string> parts;
+ split(m_name, '/', parts);
+
+ if (parts.size() >= 2) {
+ m_object_name = parts[parts.size() - 2];
+ m_data_name = parts[parts.size() - 1];
+ }
+ else {
+ m_object_name = m_data_name = parts[parts.size() - 1];
+ }
+
+ determine_inherits_xform();
}
/* Determine whether we can inherit our parent's XForm */
void AbcObjectReader::determine_inherits_xform()
{
- m_inherits_xform = false;
-
- IXform ixform = xform();
- if (!ixform) {
- return;
- }
-
- const IXformSchema & schema(ixform.getSchema());
- if (!schema.valid()) {
- std::cerr << "Alembic object " << ixform.getFullName()
- << " has an invalid schema." << std::endl;
- return;
- }
-
- m_inherits_xform = schema.getInheritsXforms();
-
- IObject ixform_parent = ixform.getParent();
- if (!ixform_parent.getParent()) {
- /* The archive top object certainly is not a transform itself, so handle
- * it as "no parent". */
- m_inherits_xform = false;
- }
- else {
- m_inherits_xform = ixform_parent && m_inherits_xform;
- }
+ m_inherits_xform = false;
+
+ IXform ixform = xform();
+ if (!ixform) {
+ return;
+ }
+
+ const IXformSchema &schema(ixform.getSchema());
+ if (!schema.valid()) {
+ std::cerr << "Alembic object " << ixform.getFullName() << " has an invalid schema."
+ << std::endl;
+ return;
+ }
+
+ m_inherits_xform = schema.getInheritsXforms();
+
+ IObject ixform_parent = ixform.getParent();
+ if (!ixform_parent.getParent()) {
+ /* The archive top object certainly is not a transform itself, so handle
+ * it as "no parent". */
+ m_inherits_xform = false;
+ }
+ else {
+ m_inherits_xform = ixform_parent && m_inherits_xform;
+ }
}
AbcObjectReader::~AbcObjectReader()
-{}
+{
+}
const IObject &AbcObjectReader::iobject() const
{
- return m_iobject;
+ return m_iobject;
}
Object *AbcObjectReader::object() const
{
- return m_object;
+ return m_object;
}
void AbcObjectReader::object(Object *ob)
{
- m_object = ob;
+ m_object = ob;
}
static Imath::M44d blend_matrices(const Imath::M44d &m0, const Imath::M44d &m1, const float weight)
{
- float mat0[4][4], mat1[4][4], ret[4][4];
+ float mat0[4][4], mat1[4][4], ret[4][4];
- /* Cannot use Imath::M44d::getValue() since this returns a pointer to
- * doubles and interp_m4_m4m4 expects pointers to floats. So need to convert
- * the matrices manually.
- */
+ /* Cannot use Imath::M44d::getValue() since this returns a pointer to
+ * doubles and interp_m4_m4m4 expects pointers to floats. So need to convert
+ * the matrices manually.
+ */
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 4; ++j) {
- mat0[i][j] = static_cast<float>(m0[i][j]);
- }
- }
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ mat0[i][j] = static_cast<float>(m0[i][j]);
+ }
+ }
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 4; ++j) {
- mat1[i][j] = static_cast<float>(m1[i][j]);
- }
- }
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ mat1[i][j] = static_cast<float>(m1[i][j]);
+ }
+ }
- interp_m4_m4m4(ret, mat0, mat1, weight);
+ interp_m4_m4m4(ret, mat0, mat1, weight);
- Imath::M44d m;
+ Imath::M44d m;
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 4; ++j) {
- m[i][j] = ret[i][j];
- }
- }
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ m[i][j] = ret[i][j];
+ }
+ }
- return m;
+ return m;
}
Imath::M44d get_matrix(const IXformSchema &schema, const float time)
{
- Alembic::AbcGeom::index_t i0, i1;
- Alembic::AbcGeom::XformSample s0, s1;
+ Alembic::AbcGeom::index_t i0, i1;
+ Alembic::AbcGeom::XformSample s0, s1;
- const float weight = get_weight_and_index(time,
- schema.getTimeSampling(),
- schema.getNumSamples(),
- i0,
- i1);
+ const float weight = get_weight_and_index(
+ time, schema.getTimeSampling(), schema.getNumSamples(), i0, i1);
- schema.get(s0, Alembic::AbcGeom::ISampleSelector(i0));
+ schema.get(s0, Alembic::AbcGeom::ISampleSelector(i0));
- if (i0 != i1) {
- schema.get(s1, Alembic::AbcGeom::ISampleSelector(i1));
- return blend_matrices(s0.getMatrix(), s1.getMatrix(), weight);
- }
+ if (i0 != i1) {
+ schema.get(s1, Alembic::AbcGeom::ISampleSelector(i1));
+ return blend_matrices(s0.getMatrix(), s1.getMatrix(), weight);
+ }
- return s0.getMatrix();
+ return s0.getMatrix();
}
struct Mesh *AbcObjectReader::read_mesh(struct Mesh *existing_mesh,
@@ -247,137 +243,138 @@ struct Mesh *AbcObjectReader::read_mesh(struct Mesh *existing_mesh,
int UNUSED(read_flag),
const char **UNUSED(err_str))
{
- return existing_mesh;
+ return existing_mesh;
}
void AbcObjectReader::setupObjectTransform(const float time)
{
- bool is_constant = false;
+ bool is_constant = false;
- this->read_matrix(m_object->obmat, time, m_settings->scale, is_constant);
- invert_m4_m4(m_object->imat, m_object->obmat);
+ this->read_matrix(m_object->obmat, time, m_settings->scale, is_constant);
+ invert_m4_m4(m_object->imat, m_object->obmat);
- BKE_object_apply_mat4(m_object, m_object->obmat, false, false);
+ BKE_object_apply_mat4(m_object, m_object->obmat, false, false);
- if (!is_constant) {
- bConstraint *con = BKE_constraint_add_for_object(m_object, NULL, CONSTRAINT_TYPE_TRANSFORM_CACHE);
- bTransformCacheConstraint *data = static_cast<bTransformCacheConstraint *>(con->data);
- BLI_strncpy(data->object_path, m_iobject.getFullName().c_str(), FILE_MAX);
+ if (!is_constant) {
+ bConstraint *con = BKE_constraint_add_for_object(
+ m_object, NULL, CONSTRAINT_TYPE_TRANSFORM_CACHE);
+ bTransformCacheConstraint *data = static_cast<bTransformCacheConstraint *>(con->data);
+ BLI_strncpy(data->object_path, m_iobject.getFullName().c_str(), FILE_MAX);
- data->cache_file = m_settings->cache_file;
- id_us_plus(&data->cache_file->id);
+ data->cache_file = m_settings->cache_file;
+ id_us_plus(&data->cache_file->id);
- data->reader = reinterpret_cast<CacheReader *>(this);
- this->incref();
- }
+ data->reader = reinterpret_cast<CacheReader *>(this);
+ this->incref();
+ }
}
Alembic::AbcGeom::IXform AbcObjectReader::xform()
{
- /* Check that we have an empty object (locator, bone head/tail...). */
- if (IXform::matches(m_iobject.getMetaData())) {
- return IXform(m_iobject, Alembic::AbcGeom::kWrapExisting);
- }
-
- /* Check that we have an object with actual data, in which case the
- * parent Alembic object should contain the transform. */
- IObject abc_parent = m_iobject.getParent();
-
- /* The archive's top object can be recognised by not having a parent. */
- if (abc_parent.getParent()
- && IXform::matches(abc_parent.getMetaData()))
- {
- return IXform(abc_parent, Alembic::AbcGeom::kWrapExisting);
- }
-
- /* This can happen in certain cases. For example, MeshLab exports
- * point clouds without parent XForm. */
- return IXform();
+ /* Check that we have an empty object (locator, bone head/tail...). */
+ if (IXform::matches(m_iobject.getMetaData())) {
+ return IXform(m_iobject, Alembic::AbcGeom::kWrapExisting);
+ }
+
+ /* Check that we have an object with actual data, in which case the
+ * parent Alembic object should contain the transform. */
+ IObject abc_parent = m_iobject.getParent();
+
+ /* The archive's top object can be recognised by not having a parent. */
+ if (abc_parent.getParent() && IXform::matches(abc_parent.getMetaData())) {
+ return IXform(abc_parent, Alembic::AbcGeom::kWrapExisting);
+ }
+
+ /* This can happen in certain cases. For example, MeshLab exports
+ * point clouds without parent XForm. */
+ return IXform();
}
-void AbcObjectReader::read_matrix(float r_mat[4][4], const float time,
- const float scale, bool &is_constant)
+void AbcObjectReader::read_matrix(float r_mat[4][4],
+ const float time,
+ const float scale,
+ bool &is_constant)
{
- IXform ixform = xform();
- if (!ixform) {
- unit_m4(r_mat);
- is_constant = true;
- return;
- }
-
- const IXformSchema & schema(ixform.getSchema());
- if (!schema.valid()) {
- std::cerr << "Alembic object " << ixform.getFullName()
- << " has an invalid schema." << std::endl;
- return;
- }
-
- const Imath::M44d matrix = get_matrix(schema, time);
- convert_matrix(matrix, m_object, r_mat);
-
- if (m_inherits_xform) {
- /* In this case, the matrix in Alembic is in local coordinates, so
- * convert to world matrix. To prevent us from reading and accumulating
- * all parent matrices in the Alembic file, we assume that the Blender
- * parent object is already updated for the current timekey, and use its
- * world matrix. */
- if (m_object->parent) {
- mul_m4_m4m4(r_mat, m_object->parent->obmat, r_mat);
- }
- else {
- /* This can happen if the user deleted the parent object. */
- unit_m4(r_mat);
- }
- }
- else {
- /* Only apply scaling to root objects, parenting will propagate it. */
- float scale_mat[4][4];
- scale_m4_fl(scale_mat, scale);
- scale_mat[3][3] = scale; /* scale translations too */
- mul_m4_m4m4(r_mat, r_mat, scale_mat);
- }
-
- is_constant = schema.isConstant();
+ IXform ixform = xform();
+ if (!ixform) {
+ unit_m4(r_mat);
+ is_constant = true;
+ return;
+ }
+
+ const IXformSchema &schema(ixform.getSchema());
+ if (!schema.valid()) {
+ std::cerr << "Alembic object " << ixform.getFullName() << " has an invalid schema."
+ << std::endl;
+ return;
+ }
+
+ const Imath::M44d matrix = get_matrix(schema, time);
+ convert_matrix(matrix, m_object, r_mat);
+
+ if (m_inherits_xform) {
+ /* In this case, the matrix in Alembic is in local coordinates, so
+ * convert to world matrix. To prevent us from reading and accumulating
+ * all parent matrices in the Alembic file, we assume that the Blender
+ * parent object is already updated for the current timekey, and use its
+ * world matrix. */
+ if (m_object->parent) {
+ mul_m4_m4m4(r_mat, m_object->parent->obmat, r_mat);
+ }
+ else {
+ /* This can happen if the user deleted the parent object. */
+ unit_m4(r_mat);
+ }
+ }
+ else {
+ /* Only apply scaling to root objects, parenting will propagate it. */
+ float scale_mat[4][4];
+ scale_m4_fl(scale_mat, scale);
+ scale_mat[3][3] = scale; /* scale translations too */
+ mul_m4_m4m4(r_mat, r_mat, scale_mat);
+ }
+
+ is_constant = schema.isConstant();
}
void AbcObjectReader::addCacheModifier()
{
- ModifierData *md = modifier_new(eModifierType_MeshSequenceCache);
- BLI_addtail(&m_object->modifiers, md);
+ ModifierData *md = modifier_new(eModifierType_MeshSequenceCache);
+ BLI_addtail(&m_object->modifiers, md);
- MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
+ MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
- mcmd->cache_file = m_settings->cache_file;
- id_us_plus(&mcmd->cache_file->id);
+ mcmd->cache_file = m_settings->cache_file;
+ id_us_plus(&mcmd->cache_file->id);
- BLI_strncpy(mcmd->object_path, m_iobject.getFullName().c_str(), FILE_MAX);
+ BLI_strncpy(mcmd->object_path, m_iobject.getFullName().c_str(), FILE_MAX);
- mcmd->reader = reinterpret_cast<CacheReader *>(this);
- this->incref();
+ mcmd->reader = reinterpret_cast<CacheReader *>(this);
+ this->incref();
}
chrono_t AbcObjectReader::minTime() const
{
- return m_min_time;
+ return m_min_time;
}
chrono_t AbcObjectReader::maxTime() const
{
- return m_max_time;
+ return m_max_time;
}
int AbcObjectReader::refcount() const
{
- return m_refcount;
+ return m_refcount;
}
void AbcObjectReader::incref()
{
- ++m_refcount;
+ ++m_refcount;
}
void AbcObjectReader::decref()
{
- --m_refcount;
- BLI_assert(m_refcount >= 0);
+ --m_refcount;
+ BLI_assert(m_refcount >= 0);
}
diff --git a/source/blender/alembic/intern/abc_object.h b/source/blender/alembic/intern/abc_object.h
index d87bfb315d9..537f24ab7d6 100644
--- a/source/blender/alembic/intern/abc_object.h
+++ b/source/blender/alembic/intern/abc_object.h
@@ -38,36 +38,36 @@ struct Object;
/* ************************************************************************** */
class AbcObjectWriter {
-protected:
- Object *m_object;
- ExportSettings &m_settings;
+ protected:
+ Object *m_object;
+ ExportSettings &m_settings;
- uint32_t m_time_sampling;
+ uint32_t m_time_sampling;
- Imath::Box3d m_bounds;
- std::vector<AbcObjectWriter *> m_children;
+ Imath::Box3d m_bounds;
+ std::vector<AbcObjectWriter *> m_children;
- std::vector<std::pair<std::string, IDProperty *>> m_props;
+ std::vector<std::pair<std::string, IDProperty *>> m_props;
- bool m_first_frame;
- std::string m_name;
+ bool m_first_frame;
+ std::string m_name;
-public:
- AbcObjectWriter(Object *ob,
- uint32_t time_sampling,
- ExportSettings &settings,
- AbcObjectWriter *parent = NULL);
+ public:
+ AbcObjectWriter(Object *ob,
+ uint32_t time_sampling,
+ ExportSettings &settings,
+ AbcObjectWriter *parent = NULL);
- virtual ~AbcObjectWriter();
+ virtual ~AbcObjectWriter();
- void addChild(AbcObjectWriter *child);
+ void addChild(AbcObjectWriter *child);
- virtual Imath::Box3d bounds();
+ virtual Imath::Box3d bounds();
- void write();
+ void write();
-private:
- virtual void do_write() = 0;
+ private:
+ virtual void do_write() = 0;
};
/* ************************************************************************** */
@@ -75,45 +75,45 @@ private:
struct CacheFile;
struct ImportSettings {
- bool do_convert_mat;
- float conversion_mat[4][4];
-
- int from_up;
- int from_forward;
- float scale;
- bool is_sequence;
- bool set_frame_range;
-
- /* Length and frame offset of file sequences. */
- int sequence_len;
- int sequence_offset;
-
- /* From MeshSeqCacheModifierData.read_flag */
- int read_flag;
-
- bool validate_meshes;
-
- CacheFile *cache_file;
-
- ImportSettings()
- : do_convert_mat(false)
- , from_up(0)
- , from_forward(0)
- , scale(1.0f)
- , is_sequence(false)
- , set_frame_range(false)
- , sequence_len(1)
- , sequence_offset(0)
- , read_flag(0)
- , validate_meshes(false)
- , cache_file(NULL)
- {}
+ bool do_convert_mat;
+ float conversion_mat[4][4];
+
+ int from_up;
+ int from_forward;
+ float scale;
+ bool is_sequence;
+ bool set_frame_range;
+
+ /* Length and frame offset of file sequences. */
+ int sequence_len;
+ int sequence_offset;
+
+ /* From MeshSeqCacheModifierData.read_flag */
+ int read_flag;
+
+ bool validate_meshes;
+
+ CacheFile *cache_file;
+
+ ImportSettings()
+ : do_convert_mat(false),
+ from_up(0),
+ from_forward(0),
+ scale(1.0f),
+ is_sequence(false),
+ set_frame_range(false),
+ sequence_len(1),
+ sequence_offset(0),
+ read_flag(0),
+ validate_meshes(false),
+ cache_file(NULL)
+ {
+ }
};
-template <typename Schema>
-static bool has_animations(Schema &schema, ImportSettings *settings)
+template<typename Schema> static bool has_animations(Schema &schema, ImportSettings *settings)
{
- return settings->is_sequence || !schema.isConstant();
+ return settings->is_sequence || !schema.isConstant();
}
/* ************************************************************************** */
@@ -123,81 +123,92 @@ struct Mesh;
using Alembic::AbcCoreAbstract::chrono_t;
class AbcObjectReader {
-protected:
- std::string m_name;
- std::string m_object_name;
- std::string m_data_name;
- Object *m_object;
- Alembic::Abc::IObject m_iobject;
+ protected:
+ std::string m_name;
+ std::string m_object_name;
+ std::string m_data_name;
+ Object *m_object;
+ Alembic::Abc::IObject m_iobject;
- ImportSettings *m_settings;
+ ImportSettings *m_settings;
- chrono_t m_min_time;
- chrono_t m_max_time;
+ chrono_t m_min_time;
+ chrono_t m_max_time;
- /* Use reference counting since the same reader may be used by multiple
- * modifiers and/or constraints. */
- int m_refcount;
+ /* Use reference counting since the same reader may be used by multiple
+ * modifiers and/or constraints. */
+ int m_refcount;
- bool m_inherits_xform;
+ bool m_inherits_xform;
-public:
- AbcObjectReader *parent_reader;
+ public:
+ AbcObjectReader *parent_reader;
-public:
- explicit AbcObjectReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
+ public:
+ explicit AbcObjectReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
- virtual ~AbcObjectReader();
+ virtual ~AbcObjectReader();
- const Alembic::Abc::IObject &iobject() const;
+ const Alembic::Abc::IObject &iobject() const;
- typedef std::vector<AbcObjectReader *> ptr_vector;
+ typedef std::vector<AbcObjectReader *> ptr_vector;
- /**
- * Returns the transform of this object. This can be the Alembic object
- * itself (in case of an Empty) or it can be the parent Alembic object.
- */
- virtual Alembic::AbcGeom::IXform xform();
+ /**
+ * Returns the transform of this object. This can be the Alembic object
+ * itself (in case of an Empty) or it can be the parent Alembic object.
+ */
+ virtual Alembic::AbcGeom::IXform xform();
- Object *object() const;
- void object(Object *ob);
+ Object *object() const;
+ void object(Object *ob);
- const std::string & name() const { return m_name; }
- const std::string & object_name() const { return m_object_name; }
- const std::string & data_name() const { return m_data_name; }
- bool inherits_xform() const { return m_inherits_xform; }
+ const std::string &name() const
+ {
+ return m_name;
+ }
+ const std::string &object_name() const
+ {
+ return m_object_name;
+ }
+ const std::string &data_name() const
+ {
+ return m_data_name;
+ }
+ bool inherits_xform() const
+ {
+ return m_inherits_xform;
+ }
- virtual bool valid() const = 0;
- virtual bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const = 0;
+ virtual bool valid() const = 0;
+ virtual bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const = 0;
- virtual void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) = 0;
+ virtual void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) = 0;
- virtual struct Mesh *read_mesh(struct Mesh *mesh,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
+ virtual struct Mesh *read_mesh(struct Mesh *mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
- /** Reads the object matrix and sets up an object transform if animated. */
- void setupObjectTransform(const float time);
+ /** Reads the object matrix and sets up an object transform if animated. */
+ void setupObjectTransform(const float time);
- void addCacheModifier();
+ void addCacheModifier();
- chrono_t minTime() const;
- chrono_t maxTime() const;
+ chrono_t minTime() const;
+ chrono_t maxTime() const;
- int refcount() const;
- void incref();
- void decref();
+ int refcount() const;
+ void incref();
+ void decref();
- void read_matrix(float r_mat[4][4], const float time,
- const float scale, bool &is_constant);
+ void read_matrix(float r_mat[4][4], const float time, const float scale, bool &is_constant);
-protected:
- void determine_inherits_xform();
+ protected:
+ void determine_inherits_xform();
};
Imath::M44d get_matrix(const Alembic::AbcGeom::IXformSchema &schema, const float time);
-#endif /* __ABC_OBJECT_H__ */
+#endif /* __ABC_OBJECT_H__ */
diff --git a/source/blender/alembic/intern/abc_points.cc b/source/blender/alembic/intern/abc_points.cc
index bc8c1e2debb..d691087ca21 100644
--- a/source/blender/alembic/intern/abc_points.cc
+++ b/source/blender/alembic/intern/abc_points.cc
@@ -45,8 +45,8 @@ extern "C" {
using Alembic::AbcGeom::kVertexScope;
using Alembic::AbcGeom::kWrapExisting;
-using Alembic::AbcGeom::P3fArraySamplePtr;
using Alembic::AbcGeom::N3fArraySamplePtr;
+using Alembic::AbcGeom::P3fArraySamplePtr;
using Alembic::AbcGeom::ICompoundProperty;
using Alembic::AbcGeom::IN3fArrayProperty;
@@ -66,75 +66,75 @@ AbcPointsWriter::AbcPointsWriter(Object *ob,
ParticleSystem *psys)
: AbcObjectWriter(ob, time_sampling, settings, parent)
{
- m_psys = psys;
+ m_psys = psys;
- OPoints points(parent->alembicXform(), psys->name, m_time_sampling);
- m_schema = points.getSchema();
+ OPoints points(parent->alembicXform(), psys->name, m_time_sampling);
+ m_schema = points.getSchema();
}
void AbcPointsWriter::do_write()
{
- if (!m_psys) {
- return;
- }
+ if (!m_psys) {
+ return;
+ }
- std::vector<Imath::V3f> points;
- std::vector<Imath::V3f> velocities;
- std::vector<float> widths;
- std::vector<uint64_t> ids;
+ std::vector<Imath::V3f> points;
+ std::vector<Imath::V3f> velocities;
+ std::vector<float> widths;
+ std::vector<uint64_t> ids;
- ParticleKey state;
+ ParticleKey state;
- ParticleSimulationData sim;
- sim.depsgraph = m_settings.depsgraph;
- sim.scene = m_settings.scene;
- sim.ob = m_object;
- sim.psys = m_psys;
+ ParticleSimulationData sim;
+ sim.depsgraph = m_settings.depsgraph;
+ sim.scene = m_settings.scene;
+ sim.ob = m_object;
+ sim.psys = m_psys;
- m_psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
+ m_psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);
- uint64_t index = 0;
- for (int p = 0; p < m_psys->totpart; p++) {
- float pos[3], vel[3];
+ uint64_t index = 0;
+ for (int p = 0; p < m_psys->totpart; p++) {
+ float pos[3], vel[3];
- if (m_psys->particles[p].flag & (PARS_NO_DISP | PARS_UNEXIST)) {
- continue;
- }
+ if (m_psys->particles[p].flag & (PARS_NO_DISP | PARS_UNEXIST)) {
+ continue;
+ }
- state.time = DEG_get_ctime(m_settings.depsgraph);
+ state.time = DEG_get_ctime(m_settings.depsgraph);
- if (psys_get_particle_state(&sim, p, &state, 0) == 0) {
- continue;
- }
+ if (psys_get_particle_state(&sim, p, &state, 0) == 0) {
+ continue;
+ }
- /* location */
- mul_v3_m4v3(pos, m_object->imat, state.co);
+ /* location */
+ mul_v3_m4v3(pos, m_object->imat, state.co);
- /* velocity */
- sub_v3_v3v3(vel, state.co, m_psys->particles[p].prev_state.co);
+ /* velocity */
+ sub_v3_v3v3(vel, state.co, m_psys->particles[p].prev_state.co);
- /* Convert Z-up to Y-up. */
- points.push_back(Imath::V3f(pos[0], pos[2], -pos[1]));
- velocities.push_back(Imath::V3f(vel[0], vel[2], -vel[1]));
- widths.push_back(m_psys->particles[p].size);
- ids.push_back(index++);
- }
+ /* Convert Z-up to Y-up. */
+ points.push_back(Imath::V3f(pos[0], pos[2], -pos[1]));
+ velocities.push_back(Imath::V3f(vel[0], vel[2], -vel[1]));
+ widths.push_back(m_psys->particles[p].size);
+ ids.push_back(index++);
+ }
- if (m_psys->lattice_deform_data) {
- end_latt_deform(m_psys->lattice_deform_data);
- m_psys->lattice_deform_data = NULL;
- }
+ if (m_psys->lattice_deform_data) {
+ end_latt_deform(m_psys->lattice_deform_data);
+ m_psys->lattice_deform_data = NULL;
+ }
- Alembic::Abc::P3fArraySample psample(points);
- Alembic::Abc::UInt64ArraySample idsample(ids);
- Alembic::Abc::V3fArraySample vsample(velocities);
- Alembic::Abc::FloatArraySample wsample_array(widths);
- Alembic::AbcGeom::OFloatGeomParam::Sample wsample(wsample_array, kVertexScope);
+ Alembic::Abc::P3fArraySample psample(points);
+ Alembic::Abc::UInt64ArraySample idsample(ids);
+ Alembic::Abc::V3fArraySample vsample(velocities);
+ Alembic::Abc::FloatArraySample wsample_array(widths);
+ Alembic::AbcGeom::OFloatGeomParam::Sample wsample(wsample_array, kVertexScope);
- m_sample = OPointsSchema::Sample(psample, idsample, vsample, wsample);
- m_sample.setSelfBounds(bounds());
+ m_sample = OPointsSchema::Sample(psample, idsample, vsample, wsample);
+ m_sample.setSelfBounds(bounds());
- m_schema.set(m_sample);
+ m_schema.set(m_sample);
}
/* ************************************************************************** */
@@ -142,75 +142,79 @@ void AbcPointsWriter::do_write()
AbcPointsReader::AbcPointsReader(const Alembic::Abc::IObject &object, ImportSettings &settings)
: AbcObjectReader(object, settings)
{
- IPoints ipoints(m_iobject, kWrapExisting);
- m_schema = ipoints.getSchema();
- get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
+ IPoints ipoints(m_iobject, kWrapExisting);
+ m_schema = ipoints.getSchema();
+ get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
}
bool AbcPointsReader::valid() const
{
- return m_schema.valid();
+ return m_schema.valid();
}
-bool AbcPointsReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const
+bool AbcPointsReader::accepts_object_type(
+ const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
{
- if (!Alembic::AbcGeom::IPoints::matches(alembic_header)) {
- *err_str = "Object type mismatch, Alembic object path pointed to Points when importing, but not any more.";
- return false;
- }
-
- if (ob->type != OB_MESH) {
- *err_str = "Object type mismatch, Alembic object path points to Points.";
- return false;
- }
-
- return true;
+ if (!Alembic::AbcGeom::IPoints::matches(alembic_header)) {
+ *err_str =
+ "Object type mismatch, Alembic object path pointed to Points when importing, but not any "
+ "more.";
+ return false;
+ }
+
+ if (ob->type != OB_MESH) {
+ *err_str = "Object type mismatch, Alembic object path points to Points.";
+ return false;
+ }
+
+ return true;
}
void AbcPointsReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
- Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
- Mesh *read_mesh = this->read_mesh(mesh, sample_sel, 0, NULL);
+ Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
+ Mesh *read_mesh = this->read_mesh(mesh, sample_sel, 0, NULL);
- if (read_mesh != mesh) {
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_MESH, true);
- }
+ if (read_mesh != mesh) {
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_MESH, true);
+ }
- if (m_settings->validate_meshes) {
- BKE_mesh_validate(mesh, false, false);
- }
+ if (m_settings->validate_meshes) {
+ BKE_mesh_validate(mesh, false, false);
+ }
- m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
- m_object->data = mesh;
+ m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
+ m_object->data = mesh;
- if (has_animations(m_schema, m_settings)) {
- addCacheModifier();
- }
+ if (has_animations(m_schema, m_settings)) {
+ addCacheModifier();
+ }
}
void read_points_sample(const IPointsSchema &schema,
const ISampleSelector &selector,
CDStreamConfig &config)
{
- Alembic::AbcGeom::IPointsSchema::Sample sample = schema.getValue(selector);
+ Alembic::AbcGeom::IPointsSchema::Sample sample = schema.getValue(selector);
- const P3fArraySamplePtr &positions = sample.getPositions();
+ const P3fArraySamplePtr &positions = sample.getPositions();
- ICompoundProperty prop = schema.getArbGeomParams();
- N3fArraySamplePtr vnormals;
+ ICompoundProperty prop = schema.getArbGeomParams();
+ N3fArraySamplePtr vnormals;
- if (has_property(prop, "N")) {
- const Alembic::Util::uint32_t itime = static_cast<Alembic::Util::uint32_t>(selector.getRequestedTime());
- const IN3fArrayProperty &normals_prop = IN3fArrayProperty(prop, "N", itime);
+ if (has_property(prop, "N")) {
+ const Alembic::Util::uint32_t itime = static_cast<Alembic::Util::uint32_t>(
+ selector.getRequestedTime());
+ const IN3fArrayProperty &normals_prop = IN3fArrayProperty(prop, "N", itime);
- if (normals_prop) {
- vnormals = normals_prop.getValue(selector);
- }
- }
+ if (normals_prop) {
+ vnormals = normals_prop.getValue(selector);
+ }
+ }
- read_mverts(config.mvert, positions, vnormals);
+ read_mverts(config.mvert, positions, vnormals);
}
struct Mesh *AbcPointsReader::read_mesh(struct Mesh *existing_mesh,
@@ -218,30 +222,30 @@ struct Mesh *AbcPointsReader::read_mesh(struct Mesh *existing_mesh,
int /*read_flag*/,
const char **err_str)
{
- IPointsSchema::Sample sample;
- try {
- sample = m_schema.getValue(sample_sel);
- }
- catch(Alembic::Util::Exception &ex) {
- *err_str = "Error reading points sample; more detail on the console";
- printf("Alembic: error reading points sample for '%s/%s' at time %f: %s\n",
- m_iobject.getFullName().c_str(),
- m_schema.getName().c_str(),
- sample_sel.getRequestedTime(),
- ex.what());
- return existing_mesh;
- }
-
- const P3fArraySamplePtr &positions = sample.getPositions();
-
- Mesh *new_mesh = NULL;
-
- if (existing_mesh->totvert != positions->size()) {
- new_mesh = BKE_mesh_new_nomain(positions->size(), 0, 0, 0, 0);
- }
-
- CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
- read_points_sample(m_schema, sample_sel, config);
-
- return new_mesh ? new_mesh : existing_mesh;
+ IPointsSchema::Sample sample;
+ try {
+ sample = m_schema.getValue(sample_sel);
+ }
+ catch (Alembic::Util::Exception &ex) {
+ *err_str = "Error reading points sample; more detail on the console";
+ printf("Alembic: error reading points sample for '%s/%s' at time %f: %s\n",
+ m_iobject.getFullName().c_str(),
+ m_schema.getName().c_str(),
+ sample_sel.getRequestedTime(),
+ ex.what());
+ return existing_mesh;
+ }
+
+ const P3fArraySamplePtr &positions = sample.getPositions();
+
+ Mesh *new_mesh = NULL;
+
+ if (existing_mesh->totvert != positions->size()) {
+ new_mesh = BKE_mesh_new_nomain(positions->size(), 0, 0, 0, 0);
+ }
+
+ CDStreamConfig config = get_config(new_mesh ? new_mesh : existing_mesh);
+ read_points_sample(m_schema, sample_sel, config);
+
+ return new_mesh ? new_mesh : existing_mesh;
}
diff --git a/source/blender/alembic/intern/abc_points.h b/source/blender/alembic/intern/abc_points.h
index 64c032d6c2f..5eb448f0f66 100644
--- a/source/blender/alembic/intern/abc_points.h
+++ b/source/blender/alembic/intern/abc_points.h
@@ -32,44 +32,44 @@ struct ParticleSystem;
/* ************************************************************************** */
class AbcPointsWriter : public AbcObjectWriter {
- Alembic::AbcGeom::OPointsSchema m_schema;
- Alembic::AbcGeom::OPointsSchema::Sample m_sample;
- ParticleSystem *m_psys;
-
-public:
- AbcPointsWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings,
- ParticleSystem *psys);
-
- void do_write();
+ Alembic::AbcGeom::OPointsSchema m_schema;
+ Alembic::AbcGeom::OPointsSchema::Sample m_sample;
+ ParticleSystem *m_psys;
+
+ public:
+ AbcPointsWriter(Object *ob,
+ AbcTransformWriter *parent,
+ uint32_t time_sampling,
+ ExportSettings &settings,
+ ParticleSystem *psys);
+
+ void do_write();
};
/* ************************************************************************** */
class AbcPointsReader : public AbcObjectReader {
- Alembic::AbcGeom::IPointsSchema m_schema;
- Alembic::AbcGeom::IPointsSchema::Sample m_sample;
+ Alembic::AbcGeom::IPointsSchema m_schema;
+ Alembic::AbcGeom::IPointsSchema::Sample m_sample;
-public:
- AbcPointsReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
+ public:
+ AbcPointsReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
- bool valid() const;
- bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const;
+ bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
- struct Mesh *read_mesh(struct Mesh *existing_mesh,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
+ struct Mesh *read_mesh(struct Mesh *existing_mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
};
void read_points_sample(const Alembic::AbcGeom::IPointsSchema &schema,
const Alembic::AbcGeom::ISampleSelector &selector,
CDStreamConfig &config);
-#endif /* __ABC_POINTS_H__ */
+#endif /* __ABC_POINTS_H__ */
diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc
index 83473bd0fe6..8b8ed6c5c4b 100644
--- a/source/blender/alembic/intern/abc_transform.cc
+++ b/source/blender/alembic/intern/abc_transform.cc
@@ -34,25 +34,25 @@ extern "C" {
#include "DEG_depsgraph_query.h"
}
+using Alembic::Abc::ISampleSelector;
using Alembic::AbcGeom::OObject;
using Alembic::AbcGeom::OXform;
-using Alembic::Abc::ISampleSelector;
/* ************************************************************************** */
static bool has_parent_camera(Object *ob)
{
- if (!ob->parent) {
- return false;
- }
+ if (!ob->parent) {
+ return false;
+ }
- Object *parent = ob->parent;
+ Object *parent = ob->parent;
- if (parent->type == OB_CAMERA) {
- return true;
- }
+ if (parent->type == OB_CAMERA) {
+ return true;
+ }
- return has_parent_camera(parent);
+ return has_parent_camera(parent);
}
/* ************************************************************************** */
@@ -62,79 +62,78 @@ AbcTransformWriter::AbcTransformWriter(Object *ob,
AbcTransformWriter *parent,
unsigned int time_sampling,
ExportSettings &settings)
- : AbcObjectWriter(ob, time_sampling, settings, parent)
- , m_proxy_from(NULL)
+ : AbcObjectWriter(ob, time_sampling, settings, parent), m_proxy_from(NULL)
{
- m_is_animated = hasAnimation(m_object);
+ m_is_animated = hasAnimation(m_object);
- if (!m_is_animated) {
- time_sampling = 0;
- }
+ if (!m_is_animated) {
+ time_sampling = 0;
+ }
- m_xform = OXform(abc_parent, get_id_name(m_object), time_sampling);
- m_schema = m_xform.getSchema();
+ m_xform = OXform(abc_parent, get_id_name(m_object), time_sampling);
+ m_schema = m_xform.getSchema();
- /* Blender objects can't have a parent without inheriting the transform. */
- m_inherits_xform = parent != NULL;
+ /* Blender objects can't have a parent without inheriting the transform. */
+ m_inherits_xform = parent != NULL;
}
void AbcTransformWriter::do_write()
{
- Object *ob_eval = DEG_get_evaluated_object(m_settings.depsgraph, m_object);
-
- if (m_first_frame) {
- m_visibility = Alembic::AbcGeom::CreateVisibilityProperty(m_xform, m_xform.getSchema().getTimeSampling());
- }
-
- m_visibility.set(!(ob_eval->restrictflag & OB_RESTRICT_VIEW));
-
- if (!m_first_frame && !m_is_animated) {
- return;
- }
-
- float yup_mat[4][4];
- create_transform_matrix(ob_eval, yup_mat,
- m_inherits_xform ? ABC_MATRIX_LOCAL : ABC_MATRIX_WORLD,
- m_proxy_from);
-
- /* Only apply rotation to root camera, parenting will propagate it. */
- if (ob_eval->type == OB_CAMERA && (!m_inherits_xform || !has_parent_camera(ob_eval))) {
- float rot_mat[4][4];
- axis_angle_to_mat4_single(rot_mat, 'X', -M_PI_2);
- mul_m4_m4m4(yup_mat, yup_mat, rot_mat);
- }
-
- if (!ob_eval->parent || !m_inherits_xform) {
- /* Only apply scaling to root objects, parenting will propagate it. */
- float scale_mat[4][4];
- scale_m4_fl(scale_mat, m_settings.global_scale);
- scale_mat[3][3] = m_settings.global_scale; /* also scale translation */
- mul_m4_m4m4(yup_mat, yup_mat, scale_mat);
- yup_mat[3][3] /= m_settings.global_scale; /* normalise the homogeneous component */
- }
-
- m_matrix = convert_matrix(yup_mat);
- m_sample.setMatrix(m_matrix);
- m_sample.setInheritsXforms(m_inherits_xform);
- m_schema.set(m_sample);
+ Object *ob_eval = DEG_get_evaluated_object(m_settings.depsgraph, m_object);
+
+ if (m_first_frame) {
+ m_visibility = Alembic::AbcGeom::CreateVisibilityProperty(
+ m_xform, m_xform.getSchema().getTimeSampling());
+ }
+
+ m_visibility.set(!(ob_eval->restrictflag & OB_RESTRICT_VIEW));
+
+ if (!m_first_frame && !m_is_animated) {
+ return;
+ }
+
+ float yup_mat[4][4];
+ create_transform_matrix(
+ ob_eval, yup_mat, m_inherits_xform ? ABC_MATRIX_LOCAL : ABC_MATRIX_WORLD, m_proxy_from);
+
+ /* Only apply rotation to root camera, parenting will propagate it. */
+ if (ob_eval->type == OB_CAMERA && (!m_inherits_xform || !has_parent_camera(ob_eval))) {
+ float rot_mat[4][4];
+ axis_angle_to_mat4_single(rot_mat, 'X', -M_PI_2);
+ mul_m4_m4m4(yup_mat, yup_mat, rot_mat);
+ }
+
+ if (!ob_eval->parent || !m_inherits_xform) {
+ /* Only apply scaling to root objects, parenting will propagate it. */
+ float scale_mat[4][4];
+ scale_m4_fl(scale_mat, m_settings.global_scale);
+ scale_mat[3][3] = m_settings.global_scale; /* also scale translation */
+ mul_m4_m4m4(yup_mat, yup_mat, scale_mat);
+ yup_mat[3][3] /= m_settings.global_scale; /* normalise the homogeneous component */
+ }
+
+ m_matrix = convert_matrix(yup_mat);
+ m_sample.setMatrix(m_matrix);
+ m_sample.setInheritsXforms(m_inherits_xform);
+ m_schema.set(m_sample);
}
Imath::Box3d AbcTransformWriter::bounds()
{
- Imath::Box3d bounds;
+ Imath::Box3d bounds;
- for (int i = 0; i < m_children.size(); ++i) {
- Imath::Box3d box(m_children[i]->bounds());
- bounds.extendBy(box);
- }
+ for (int i = 0; i < m_children.size(); ++i) {
+ Imath::Box3d box(m_children[i]->bounds());
+ bounds.extendBy(box);
+ }
- return Imath::transform(bounds, m_matrix);
+ return Imath::transform(bounds, m_matrix);
}
bool AbcTransformWriter::hasAnimation(Object * /*ob*/) const
{
- /* TODO(kevin): implement this. */
- return true;
+ /* TODO(kevin): implement this. */
+ return true;
}
/* ************************************************************************** */
@@ -142,41 +141,43 @@ bool AbcTransformWriter::hasAnimation(Object * /*ob*/) const
AbcEmptyReader::AbcEmptyReader(const Alembic::Abc::IObject &object, ImportSettings &settings)
: AbcObjectReader(object, settings)
{
- /* Empties have no data. It makes the import of Alembic files easier to
- * understand when we name the empty after its name in Alembic. */
- m_object_name = object.getName();
+ /* Empties have no data. It makes the import of Alembic files easier to
+ * understand when we name the empty after its name in Alembic. */
+ m_object_name = object.getName();
- Alembic::AbcGeom::IXform xform(object, Alembic::AbcGeom::kWrapExisting);
- m_schema = xform.getSchema();
+ Alembic::AbcGeom::IXform xform(object, Alembic::AbcGeom::kWrapExisting);
+ m_schema = xform.getSchema();
- get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
+ get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
}
bool AbcEmptyReader::valid() const
{
- return m_schema.valid();
+ return m_schema.valid();
}
-bool AbcEmptyReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const
+bool AbcEmptyReader::accepts_object_type(
+ const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
{
- if (!Alembic::AbcGeom::IXform::matches(alembic_header)) {
- *err_str = "Object type mismatch, Alembic object path pointed to XForm when importing, but not any more.";
- return false;
- }
-
- if (ob->type != OB_EMPTY) {
- *err_str = "Object type mismatch, Alembic object path points to XForm.";
- return false;
- }
-
- return true;
+ if (!Alembic::AbcGeom::IXform::matches(alembic_header)) {
+ *err_str =
+ "Object type mismatch, Alembic object path pointed to XForm when importing, but not any "
+ "more.";
+ return false;
+ }
+
+ if (ob->type != OB_EMPTY) {
+ *err_str = "Object type mismatch, Alembic object path points to XForm.";
+ return false;
+ }
+
+ return true;
}
void AbcEmptyReader::readObjectData(Main *bmain, const ISampleSelector &UNUSED(sample_sel))
{
- m_object = BKE_object_add_only_object(bmain, OB_EMPTY,
- m_object_name.c_str());
- m_object->data = NULL;
+ m_object = BKE_object_add_only_object(bmain, OB_EMPTY, m_object_name.c_str());
+ m_object->data = NULL;
}
diff --git a/source/blender/alembic/intern/abc_transform.h b/source/blender/alembic/intern/abc_transform.h
index 79d278ce587..7fa42cf0299 100644
--- a/source/blender/alembic/intern/abc_transform.h
+++ b/source/blender/alembic/intern/abc_transform.h
@@ -28,48 +28,51 @@
/* ************************************************************************** */
class AbcTransformWriter : public AbcObjectWriter {
- Alembic::AbcGeom::OXform m_xform;
- Alembic::AbcGeom::OXformSchema m_schema;
- Alembic::AbcGeom::XformSample m_sample;
- Alembic::AbcGeom::OVisibilityProperty m_visibility;
- Alembic::Abc::M44d m_matrix;
-
- bool m_is_animated;
- bool m_inherits_xform;
-
-public:
- Object *m_proxy_from;
-
-public:
- AbcTransformWriter(Object *ob,
- const Alembic::AbcGeom::OObject &abc_parent,
- AbcTransformWriter *parent,
- unsigned int time_sampling,
- ExportSettings &settings);
-
- Alembic::AbcGeom::OXform &alembicXform() { return m_xform;}
- virtual Imath::Box3d bounds();
-
-private:
- virtual void do_write();
-
- bool hasAnimation(Object *ob) const;
+ Alembic::AbcGeom::OXform m_xform;
+ Alembic::AbcGeom::OXformSchema m_schema;
+ Alembic::AbcGeom::XformSample m_sample;
+ Alembic::AbcGeom::OVisibilityProperty m_visibility;
+ Alembic::Abc::M44d m_matrix;
+
+ bool m_is_animated;
+ bool m_inherits_xform;
+
+ public:
+ Object *m_proxy_from;
+
+ public:
+ AbcTransformWriter(Object *ob,
+ const Alembic::AbcGeom::OObject &abc_parent,
+ AbcTransformWriter *parent,
+ unsigned int time_sampling,
+ ExportSettings &settings);
+
+ Alembic::AbcGeom::OXform &alembicXform()
+ {
+ return m_xform;
+ }
+ virtual Imath::Box3d bounds();
+
+ private:
+ virtual void do_write();
+
+ bool hasAnimation(Object *ob) const;
};
/* ************************************************************************** */
class AbcEmptyReader : public AbcObjectReader {
- Alembic::AbcGeom::IXformSchema m_schema;
+ Alembic::AbcGeom::IXformSchema m_schema;
-public:
- AbcEmptyReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
+ public:
+ AbcEmptyReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
- bool valid() const;
- bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const;
+ bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
};
-#endif /* __ABC_TRANSFORM_H__ */
+#endif /* __ABC_TRANSFORM_H__ */
diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc
index a4a7256b783..380ceff80cf 100644
--- a/source/blender/alembic/intern/abc_util.cc
+++ b/source/blender/alembic/intern/abc_util.cc
@@ -40,23 +40,23 @@ extern "C" {
#include "PIL_time.h"
}
-std::string get_id_name(const Object * const ob)
+std::string get_id_name(const Object *const ob)
{
- if (!ob) {
- return "";
- }
+ if (!ob) {
+ return "";
+ }
- return get_id_name(&ob->id);
+ return get_id_name(&ob->id);
}
-std::string get_id_name(const ID * const id)
+std::string get_id_name(const ID *const id)
{
- std::string name(id->name + 2);
- std::replace(name.begin(), name.end(), ' ', '_');
- std::replace(name.begin(), name.end(), '.', '_');
- std::replace(name.begin(), name.end(), ':', '_');
+ std::string name(id->name + 2);
+ std::replace(name.begin(), name.end(), ' ', '_');
+ std::replace(name.begin(), name.end(), '.', '_');
+ std::replace(name.begin(), name.end(), ':', '_');
- return name;
+ return name;
}
/**
@@ -68,209 +68,212 @@ std::string get_id_name(const ID * const id)
* \param dupli_parent:
* \return
*/
-std::string get_object_dag_path_name(const Object * const ob, Object *dupli_parent)
+std::string get_object_dag_path_name(const Object *const ob, Object *dupli_parent)
{
- std::string name = get_id_name(ob);
+ std::string name = get_id_name(ob);
- Object *p = ob->parent;
+ Object *p = ob->parent;
- while (p) {
- name = get_id_name(p) + "/" + name;
- p = p->parent;
- }
+ while (p) {
+ name = get_id_name(p) + "/" + name;
+ p = p->parent;
+ }
- if (dupli_parent && (ob != dupli_parent)) {
- name = get_id_name(dupli_parent) + "/" + name;
- }
+ if (dupli_parent && (ob != dupli_parent)) {
+ name = get_id_name(dupli_parent) + "/" + name;
+ }
- return name;
+ return name;
}
Imath::M44d convert_matrix(float mat[4][4])
{
- Imath::M44d m;
+ Imath::M44d m;
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 4; ++j) {
- m[i][j] = mat[i][j];
- }
- }
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ m[i][j] = mat[i][j];
+ }
+ }
- return m;
+ return m;
}
void split(const std::string &s, const char delim, std::vector<std::string> &tokens)
{
- tokens.clear();
+ tokens.clear();
- std::stringstream ss(s);
- std::string item;
+ std::stringstream ss(s);
+ std::string item;
- while (std::getline(ss, item, delim)) {
- if (!item.empty()) {
- tokens.push_back(item);
- }
- }
+ while (std::getline(ss, item, delim)) {
+ if (!item.empty()) {
+ tokens.push_back(item);
+ }
+ }
}
-void create_swapped_rotation_matrix(
- float rot_x_mat[3][3], float rot_y_mat[3][3],
- float rot_z_mat[3][3], const float euler[3],
- AbcAxisSwapMode mode)
+void create_swapped_rotation_matrix(float rot_x_mat[3][3],
+ float rot_y_mat[3][3],
+ float rot_z_mat[3][3],
+ const float euler[3],
+ AbcAxisSwapMode mode)
{
- const float rx = euler[0];
- float ry;
- float rz;
-
- /* Apply transformation */
- switch (mode) {
- case ABC_ZUP_FROM_YUP:
- ry = -euler[2];
- rz = euler[1];
- break;
- case ABC_YUP_FROM_ZUP:
- ry = euler[2];
- rz = -euler[1];
- break;
- default:
- ry = 0.0f;
- rz = 0.0f;
- BLI_assert(false);
- break;
- }
-
- unit_m3(rot_x_mat);
- unit_m3(rot_y_mat);
- unit_m3(rot_z_mat);
-
- rot_x_mat[1][1] = cos(rx);
- rot_x_mat[2][1] = -sin(rx);
- rot_x_mat[1][2] = sin(rx);
- rot_x_mat[2][2] = cos(rx);
-
- rot_y_mat[2][2] = cos(ry);
- rot_y_mat[0][2] = -sin(ry);
- rot_y_mat[2][0] = sin(ry);
- rot_y_mat[0][0] = cos(ry);
-
- rot_z_mat[0][0] = cos(rz);
- rot_z_mat[1][0] = -sin(rz);
- rot_z_mat[0][1] = sin(rz);
- rot_z_mat[1][1] = cos(rz);
+ const float rx = euler[0];
+ float ry;
+ float rz;
+
+ /* Apply transformation */
+ switch (mode) {
+ case ABC_ZUP_FROM_YUP:
+ ry = -euler[2];
+ rz = euler[1];
+ break;
+ case ABC_YUP_FROM_ZUP:
+ ry = euler[2];
+ rz = -euler[1];
+ break;
+ default:
+ ry = 0.0f;
+ rz = 0.0f;
+ BLI_assert(false);
+ break;
+ }
+
+ unit_m3(rot_x_mat);
+ unit_m3(rot_y_mat);
+ unit_m3(rot_z_mat);
+
+ rot_x_mat[1][1] = cos(rx);
+ rot_x_mat[2][1] = -sin(rx);
+ rot_x_mat[1][2] = sin(rx);
+ rot_x_mat[2][2] = cos(rx);
+
+ rot_y_mat[2][2] = cos(ry);
+ rot_y_mat[0][2] = -sin(ry);
+ rot_y_mat[2][0] = sin(ry);
+ rot_y_mat[0][0] = cos(ry);
+
+ rot_z_mat[0][0] = cos(rz);
+ rot_z_mat[1][0] = -sin(rz);
+ rot_z_mat[0][1] = sin(rz);
+ rot_z_mat[1][1] = cos(rz);
}
/* Convert matrix from Z=up to Y=up or vice versa. Use yup_mat = zup_mat for in-place conversion. */
void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode)
{
- float dst_rot[3][3], src_rot[3][3], dst_scale_mat[4][4];
- float rot_x_mat[3][3], rot_y_mat[3][3], rot_z_mat[3][3];
- float src_trans[3], dst_scale[3], src_scale[3], euler[3];
-
- zero_v3(src_trans);
- zero_v3(dst_scale);
- zero_v3(src_scale);
- zero_v3(euler);
- unit_m3(src_rot);
- unit_m3(dst_rot);
- unit_m4(dst_scale_mat);
-
- /* TODO(Sybren): This code assumes there is no sheer component and no
- * homogeneous scaling component, which is not always true when writing
- * non-hierarchical (e.g. flat) objects (e.g. when parent has non-uniform
- * scale and the child rotates). This is currently not taken into account
- * when axis-swapping. */
-
- /* Extract translation, rotation, and scale form matrix. */
- mat4_to_loc_rot_size(src_trans, src_rot, src_scale, src_mat);
-
- /* Get euler angles from rotation matrix. */
- mat3_to_eulO(euler, ROT_MODE_XZY, src_rot);
-
- /* Create X, Y, Z rotation matrices from euler angles. */
- create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, mode);
-
- /* Concatenate rotation matrices. */
- mul_m3_m3m3(dst_rot, dst_rot, rot_z_mat);
- mul_m3_m3m3(dst_rot, dst_rot, rot_y_mat);
- mul_m3_m3m3(dst_rot, dst_rot, rot_x_mat);
-
- mat3_to_eulO(euler, ROT_MODE_XZY, dst_rot);
-
- /* Start construction of dst_mat from rotation matrix */
- unit_m4(dst_mat);
- copy_m4_m3(dst_mat, dst_rot);
-
- /* Apply translation */
- switch (mode) {
- case ABC_ZUP_FROM_YUP:
- copy_zup_from_yup(dst_mat[3], src_trans);
- break;
- case ABC_YUP_FROM_ZUP:
- copy_yup_from_zup(dst_mat[3], src_trans);
- break;
- default:
- BLI_assert(false);
- }
-
- /* Apply scale matrix. Swaps y and z, but does not
- * negate like translation does. */
- dst_scale[0] = src_scale[0];
- dst_scale[1] = src_scale[2];
- dst_scale[2] = src_scale[1];
-
- size_to_mat4(dst_scale_mat, dst_scale);
- mul_m4_m4m4(dst_mat, dst_mat, dst_scale_mat);
+ float dst_rot[3][3], src_rot[3][3], dst_scale_mat[4][4];
+ float rot_x_mat[3][3], rot_y_mat[3][3], rot_z_mat[3][3];
+ float src_trans[3], dst_scale[3], src_scale[3], euler[3];
+
+ zero_v3(src_trans);
+ zero_v3(dst_scale);
+ zero_v3(src_scale);
+ zero_v3(euler);
+ unit_m3(src_rot);
+ unit_m3(dst_rot);
+ unit_m4(dst_scale_mat);
+
+ /* TODO(Sybren): This code assumes there is no sheer component and no
+ * homogeneous scaling component, which is not always true when writing
+ * non-hierarchical (e.g. flat) objects (e.g. when parent has non-uniform
+ * scale and the child rotates). This is currently not taken into account
+ * when axis-swapping. */
+
+ /* Extract translation, rotation, and scale form matrix. */
+ mat4_to_loc_rot_size(src_trans, src_rot, src_scale, src_mat);
+
+ /* Get euler angles from rotation matrix. */
+ mat3_to_eulO(euler, ROT_MODE_XZY, src_rot);
+
+ /* Create X, Y, Z rotation matrices from euler angles. */
+ create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, mode);
+
+ /* Concatenate rotation matrices. */
+ mul_m3_m3m3(dst_rot, dst_rot, rot_z_mat);
+ mul_m3_m3m3(dst_rot, dst_rot, rot_y_mat);
+ mul_m3_m3m3(dst_rot, dst_rot, rot_x_mat);
+
+ mat3_to_eulO(euler, ROT_MODE_XZY, dst_rot);
+
+ /* Start construction of dst_mat from rotation matrix */
+ unit_m4(dst_mat);
+ copy_m4_m3(dst_mat, dst_rot);
+
+ /* Apply translation */
+ switch (mode) {
+ case ABC_ZUP_FROM_YUP:
+ copy_zup_from_yup(dst_mat[3], src_trans);
+ break;
+ case ABC_YUP_FROM_ZUP:
+ copy_yup_from_zup(dst_mat[3], src_trans);
+ break;
+ default:
+ BLI_assert(false);
+ }
+
+ /* Apply scale matrix. Swaps y and z, but does not
+ * negate like translation does. */
+ dst_scale[0] = src_scale[0];
+ dst_scale[1] = src_scale[2];
+ dst_scale[2] = src_scale[1];
+
+ size_to_mat4(dst_scale_mat, dst_scale);
+ mul_m4_m4m4(dst_mat, dst_mat, dst_scale_mat);
}
void convert_matrix(const Imath::M44d &xform, Object *ob, float r_mat[4][4])
{
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 4; ++j) {
- r_mat[i][j] = static_cast<float>(xform[i][j]);
- }
- }
-
- if (ob->type == OB_CAMERA) {
- float cam_to_yup[4][4];
- axis_angle_to_mat4_single(cam_to_yup, 'X', M_PI_2);
- mul_m4_m4m4(r_mat, r_mat, cam_to_yup);
- }
-
- copy_m44_axis_swap(r_mat, r_mat, ABC_ZUP_FROM_YUP);
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j) {
+ r_mat[i][j] = static_cast<float>(xform[i][j]);
+ }
+ }
+
+ if (ob->type == OB_CAMERA) {
+ float cam_to_yup[4][4];
+ axis_angle_to_mat4_single(cam_to_yup, 'X', M_PI_2);
+ mul_m4_m4m4(r_mat, r_mat, cam_to_yup);
+ }
+
+ copy_m44_axis_swap(r_mat, r_mat, ABC_ZUP_FROM_YUP);
}
/* Recompute transform matrix of object in new coordinate system
* (from Z-Up to Y-Up). */
-void create_transform_matrix(Object *obj, float r_yup_mat[4][4], AbcMatrixMode mode,
+void create_transform_matrix(Object *obj,
+ float r_yup_mat[4][4],
+ AbcMatrixMode mode,
Object *proxy_from)
{
- float zup_mat[4][4];
-
- /* get local or world matrix. */
- if (mode == ABC_MATRIX_LOCAL && obj->parent) {
- /* Note that this produces another matrix than the local matrix, due to
- * constraints and modifiers as well as the obj->parentinv matrix. */
- invert_m4_m4(obj->parent->imat, obj->parent->obmat);
- mul_m4_m4m4(zup_mat, obj->parent->imat, obj->obmat);
- }
- else {
- copy_m4_m4(zup_mat, obj->obmat);
- }
-
- if (proxy_from) {
- mul_m4_m4m4(zup_mat, proxy_from->obmat, zup_mat);
- }
-
- copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
+ float zup_mat[4][4];
+
+ /* get local or world matrix. */
+ if (mode == ABC_MATRIX_LOCAL && obj->parent) {
+ /* Note that this produces another matrix than the local matrix, due to
+ * constraints and modifiers as well as the obj->parentinv matrix. */
+ invert_m4_m4(obj->parent->imat, obj->parent->obmat);
+ mul_m4_m4m4(zup_mat, obj->parent->imat, obj->obmat);
+ }
+ else {
+ copy_m4_m4(zup_mat, obj->obmat);
+ }
+
+ if (proxy_from) {
+ mul_m4_m4m4(zup_mat, proxy_from->obmat, zup_mat);
+ }
+
+ copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
}
bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name)
{
- if (!prop.valid()) {
- return false;
- }
+ if (!prop.valid()) {
+ return false;
+ }
- return prop.getPropertyHeader(name) != NULL;
+ return prop.getPropertyHeader(name) != NULL;
}
typedef std::pair<Alembic::AbcCoreAbstract::index_t, float> index_time_pair_t;
@@ -281,125 +284,123 @@ float get_weight_and_index(float time,
Alembic::AbcGeom::index_t &i0,
Alembic::AbcGeom::index_t &i1)
{
- samples_number = std::max(samples_number, 1);
+ samples_number = std::max(samples_number, 1);
- index_time_pair_t t0 = time_sampling->getFloorIndex(time, samples_number);
- i0 = i1 = t0.first;
+ index_time_pair_t t0 = time_sampling->getFloorIndex(time, samples_number);
+ i0 = i1 = t0.first;
- if (samples_number == 1 || (fabs(time - t0.second) < 0.0001f)) {
- return 0.0f;
- }
+ if (samples_number == 1 || (fabs(time - t0.second) < 0.0001f)) {
+ return 0.0f;
+ }
- index_time_pair_t t1 = time_sampling->getCeilIndex(time, samples_number);
- i1 = t1.first;
+ index_time_pair_t t1 = time_sampling->getCeilIndex(time, samples_number);
+ i1 = t1.first;
- if (i0 == i1) {
- return 0.0f;
- }
+ if (i0 == i1) {
+ return 0.0f;
+ }
- const float bias = (time - t0.second) / (t1.second - t0.second);
+ const float bias = (time - t0.second) / (t1.second - t0.second);
- if (fabs(1.0f - bias) < 0.0001f) {
- i0 = i1;
- return 0.0f;
- }
+ if (fabs(1.0f - bias) < 0.0001f) {
+ i0 = i1;
+ return 0.0f;
+ }
- return bias;
+ return bias;
}
//#define USE_NURBS
AbcObjectReader *create_reader(const Alembic::AbcGeom::IObject &object, ImportSettings &settings)
{
- AbcObjectReader *reader = NULL;
-
- const Alembic::AbcGeom::MetaData &md = object.getMetaData();
-
- if (Alembic::AbcGeom::IXform::matches(md)) {
- reader = new AbcEmptyReader(object, settings);
- }
- else if (Alembic::AbcGeom::IPolyMesh::matches(md)) {
- reader = new AbcMeshReader(object, settings);
- }
- else if (Alembic::AbcGeom::ISubD::matches(md)) {
- reader = new AbcSubDReader(object, settings);
- }
- else if (Alembic::AbcGeom::INuPatch::matches(md)) {
+ AbcObjectReader *reader = NULL;
+
+ const Alembic::AbcGeom::MetaData &md = object.getMetaData();
+
+ if (Alembic::AbcGeom::IXform::matches(md)) {
+ reader = new AbcEmptyReader(object, settings);
+ }
+ else if (Alembic::AbcGeom::IPolyMesh::matches(md)) {
+ reader = new AbcMeshReader(object, settings);
+ }
+ else if (Alembic::AbcGeom::ISubD::matches(md)) {
+ reader = new AbcSubDReader(object, settings);
+ }
+ else if (Alembic::AbcGeom::INuPatch::matches(md)) {
#ifdef USE_NURBS
- /* TODO(kevin): importing cyclic NURBS from other software crashes
- * at the moment. This is due to the fact that NURBS in other
- * software have duplicated points which causes buffer overflows in
- * Blender. Need to figure out exactly how these points are
- * duplicated, in all cases (cyclic U, cyclic V, and cyclic UV).
- * Until this is fixed, disabling NURBS reading. */
- reader = new AbcNurbsReader(child, settings);
+ /* TODO(kevin): importing cyclic NURBS from other software crashes
+ * at the moment. This is due to the fact that NURBS in other
+ * software have duplicated points which causes buffer overflows in
+ * Blender. Need to figure out exactly how these points are
+ * duplicated, in all cases (cyclic U, cyclic V, and cyclic UV).
+ * Until this is fixed, disabling NURBS reading. */
+ reader = new AbcNurbsReader(child, settings);
#endif
- }
- else if (Alembic::AbcGeom::ICamera::matches(md)) {
- reader = new AbcCameraReader(object, settings);
- }
- else if (Alembic::AbcGeom::IPoints::matches(md)) {
- reader = new AbcPointsReader(object, settings);
- }
- else if (Alembic::AbcMaterial::IMaterial::matches(md)) {
- /* Pass for now. */
- }
- else if (Alembic::AbcGeom::ILight::matches(md)) {
- /* Pass for now. */
- }
- else if (Alembic::AbcGeom::IFaceSet::matches(md)) {
- /* Pass, those are handled in the mesh reader. */
- }
- else if (Alembic::AbcGeom::ICurves::matches(md)) {
- reader = new AbcCurveReader(object, settings);
- }
- else {
- std::cerr << "Alembic: unknown how to handle objects of schema '"
- << md.get("schemaObjTitle")
- << "', skipping object '"
- << object.getFullName() << "'" << std::endl;
- }
-
- return reader;
+ }
+ else if (Alembic::AbcGeom::ICamera::matches(md)) {
+ reader = new AbcCameraReader(object, settings);
+ }
+ else if (Alembic::AbcGeom::IPoints::matches(md)) {
+ reader = new AbcPointsReader(object, settings);
+ }
+ else if (Alembic::AbcMaterial::IMaterial::matches(md)) {
+ /* Pass for now. */
+ }
+ else if (Alembic::AbcGeom::ILight::matches(md)) {
+ /* Pass for now. */
+ }
+ else if (Alembic::AbcGeom::IFaceSet::matches(md)) {
+ /* Pass, those are handled in the mesh reader. */
+ }
+ else if (Alembic::AbcGeom::ICurves::matches(md)) {
+ reader = new AbcCurveReader(object, settings);
+ }
+ else {
+ std::cerr << "Alembic: unknown how to handle objects of schema '" << md.get("schemaObjTitle")
+ << "', skipping object '" << object.getFullName() << "'" << std::endl;
+ }
+
+ return reader;
}
/* ********************** */
ScopeTimer::ScopeTimer(const char *message)
- : m_message(message)
- , m_start(PIL_check_seconds_timer())
-{}
+ : m_message(message), m_start(PIL_check_seconds_timer())
+{
+}
ScopeTimer::~ScopeTimer()
{
- fprintf(stderr, "%s: %fs\n", m_message, PIL_check_seconds_timer() - m_start);
+ fprintf(stderr, "%s: %fs\n", m_message, PIL_check_seconds_timer() - m_start);
}
/* ********************** */
bool SimpleLogger::empty()
{
- return ((size_t)m_stream.tellp()) == 0ul;
+ return ((size_t)m_stream.tellp()) == 0ul;
}
std::string SimpleLogger::str() const
{
- return m_stream.str();
+ return m_stream.str();
}
void SimpleLogger::clear()
{
- m_stream.clear();
- m_stream.str("");
+ m_stream.clear();
+ m_stream.str("");
}
std::ostringstream &SimpleLogger::stream()
{
- return m_stream;
+ return m_stream;
}
std::ostream &operator<<(std::ostream &os, const SimpleLogger &logger)
{
- os << logger.str();
- return os;
+ os << logger.str();
+ return os;
}
diff --git a/source/blender/alembic/intern/abc_util.h b/source/blender/alembic/intern/abc_util.h
index d21fe7a78ce..44ad4bca2f7 100644
--- a/source/blender/alembic/intern/abc_util.h
+++ b/source/blender/alembic/intern/abc_util.h
@@ -36,7 +36,7 @@
* pointers to AbcObjectReader (or subclasses thereof).
*/
struct CacheReader {
- int unused;
+ int unused;
};
using Alembic::Abc::chrono_t;
@@ -48,58 +48,61 @@ struct Base;
struct ID;
struct Object;
-std::string get_id_name(const ID * const id);
-std::string get_id_name(const Object * const ob);
-std::string get_object_dag_path_name(const Object * const ob, Object *dupli_parent);
+std::string get_id_name(const ID *const id);
+std::string get_id_name(const Object *const ob);
+std::string get_object_dag_path_name(const Object *const ob, Object *dupli_parent);
Imath::M44d convert_matrix(float mat[4][4]);
typedef enum {
- ABC_MATRIX_WORLD = 1,
- ABC_MATRIX_LOCAL = 2,
+ ABC_MATRIX_WORLD = 1,
+ ABC_MATRIX_LOCAL = 2,
} AbcMatrixMode;
-void create_transform_matrix(Object *obj, float r_transform_mat[4][4],
- AbcMatrixMode mode, Object *proxy_from);
+void create_transform_matrix(Object *obj,
+ float r_transform_mat[4][4],
+ AbcMatrixMode mode,
+ Object *proxy_from);
void split(const std::string &s, const char delim, std::vector<std::string> &tokens);
-template<class TContainer>
-bool begins_with(const TContainer &input, const TContainer &match)
+template<class TContainer> bool begins_with(const TContainer &input, const TContainer &match)
{
- return input.size() >= match.size()
- && std::equal(match.begin(), match.end(), input.begin());
+ return input.size() >= match.size() && std::equal(match.begin(), match.end(), input.begin());
}
void convert_matrix(const Imath::M44d &xform, Object *ob, float r_mat[4][4]);
-template <typename Schema>
+template<typename Schema>
void get_min_max_time_ex(const Schema &schema, chrono_t &min, chrono_t &max)
{
- const Alembic::Abc::TimeSamplingPtr &time_samp = schema.getTimeSampling();
+ const Alembic::Abc::TimeSamplingPtr &time_samp = schema.getTimeSampling();
- if (!schema.isConstant()) {
- const size_t num_samps = schema.getNumSamples();
+ if (!schema.isConstant()) {
+ const size_t num_samps = schema.getNumSamples();
- if (num_samps > 0) {
- const chrono_t min_time = time_samp->getSampleTime(0);
- min = std::min(min, min_time);
+ if (num_samps > 0) {
+ const chrono_t min_time = time_samp->getSampleTime(0);
+ min = std::min(min, min_time);
- const chrono_t max_time = time_samp->getSampleTime(num_samps - 1);
- max = std::max(max, max_time);
- }
- }
+ const chrono_t max_time = time_samp->getSampleTime(num_samps - 1);
+ max = std::max(max, max_time);
+ }
+ }
}
-template <typename Schema>
-void get_min_max_time(const Alembic::AbcGeom::IObject &object, const Schema &schema, chrono_t &min, chrono_t &max)
+template<typename Schema>
+void get_min_max_time(const Alembic::AbcGeom::IObject &object,
+ const Schema &schema,
+ chrono_t &min,
+ chrono_t &max)
{
- get_min_max_time_ex(schema, min, max);
+ get_min_max_time_ex(schema, min, max);
- const Alembic::AbcGeom::IObject &parent = object.getParent();
- if (parent.valid() && Alembic::AbcGeom::IXform::matches(parent.getMetaData())) {
- Alembic::AbcGeom::IXform xform(parent, Alembic::AbcGeom::kWrapExisting);
- get_min_max_time_ex(xform.getSchema(), min, max);
- }
+ const Alembic::AbcGeom::IObject &parent = object.getParent();
+ if (parent.valid() && Alembic::AbcGeom::IXform::matches(parent.getMetaData())) {
+ Alembic::AbcGeom::IXform xform(parent, Alembic::AbcGeom::kWrapExisting);
+ get_min_max_time_ex(xform.getSchema(), min, max);
+ }
}
bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name);
@@ -123,51 +126,52 @@ AbcObjectReader *create_reader(const Alembic::AbcGeom::IObject &object, ImportSe
ABC_INLINE void copy_zup_from_yup(float zup[3], const float yup[3])
{
- const float old_yup1 = yup[1]; /* in case zup == yup */
- zup[0] = yup[0];
- zup[1] = -yup[2];
- zup[2] = old_yup1;
+ const float old_yup1 = yup[1]; /* in case zup == yup */
+ zup[0] = yup[0];
+ zup[1] = -yup[2];
+ zup[2] = old_yup1;
}
ABC_INLINE void copy_zup_from_yup(short zup[3], const short yup[3])
{
- const short old_yup1 = yup[1]; /* in case zup == yup */
- zup[0] = yup[0];
- zup[1] = -yup[2];
- zup[2] = old_yup1;
+ const short old_yup1 = yup[1]; /* in case zup == yup */
+ zup[0] = yup[0];
+ zup[1] = -yup[2];
+ zup[2] = old_yup1;
}
/* Copy from Z-up to Y-up. */
ABC_INLINE void copy_yup_from_zup(float yup[3], const float zup[3])
{
- const float old_zup1 = zup[1]; /* in case yup == zup */
- yup[0] = zup[0];
- yup[1] = zup[2];
- yup[2] = -old_zup1;
+ const float old_zup1 = zup[1]; /* in case yup == zup */
+ yup[0] = zup[0];
+ yup[1] = zup[2];
+ yup[2] = -old_zup1;
}
ABC_INLINE void copy_yup_from_zup(short yup[3], const short zup[3])
{
- const short old_zup1 = zup[1]; /* in case yup == zup */
- yup[0] = zup[0];
- yup[1] = zup[2];
- yup[2] = -old_zup1;
+ const short old_zup1 = zup[1]; /* in case yup == zup */
+ yup[0] = zup[0];
+ yup[1] = zup[2];
+ yup[2] = -old_zup1;
}
/* Names are given in (dst, src) order, just like
* the parameters of copy_m44_axis_swap() */
typedef enum {
- ABC_ZUP_FROM_YUP = 1,
- ABC_YUP_FROM_ZUP = 2,
+ ABC_ZUP_FROM_YUP = 1,
+ ABC_YUP_FROM_ZUP = 2,
} AbcAxisSwapMode;
/* Create a rotation matrix for each axis from euler angles.
* Euler angles are swapped to change coordinate system. */
-void create_swapped_rotation_matrix(
- float rot_x_mat[3][3], float rot_y_mat[3][3],
- float rot_z_mat[3][3], const float euler[3],
- AbcAxisSwapMode mode);
+void create_swapped_rotation_matrix(float rot_x_mat[3][3],
+ float rot_y_mat[3][3],
+ float rot_z_mat[3][3],
+ const float euler[3],
+ AbcAxisSwapMode mode);
void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode);
@@ -176,18 +180,18 @@ void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMod
#undef ABC_DEBUG_TIME
class ScopeTimer {
- const char *m_message;
- double m_start;
+ const char *m_message;
+ double m_start;
-public:
- ScopeTimer(const char *message);
- ~ScopeTimer();
+ public:
+ ScopeTimer(const char *message);
+ ~ScopeTimer();
};
#ifdef ABC_DEBUG_TIME
-# define SCOPE_TIMER(message) ScopeTimer prof(message)
+# define SCOPE_TIMER(message) ScopeTimer prof(message)
#else
-# define SCOPE_TIMER(message)
+# define SCOPE_TIMER(message)
#endif
/* *************************** */
@@ -202,29 +206,29 @@ public:
* conditions.
*/
class SimpleLogger {
- std::ostringstream m_stream;
-
-public:
- /**
- * Check whether or not the SimpleLogger's stream is empty.
- */
- bool empty();
-
- /**
- * Return a copy of the string contained in the SimpleLogger's stream.
- */
- std::string str() const;
-
- /**
- * Remove the bits set on the SimpleLogger's stream and clear its string.
- */
- void clear();
-
- /**
- * Return a reference to the SimpleLogger's stream, in order to e.g. push
- * content into it.
- */
- std::ostringstream &stream();
+ std::ostringstream m_stream;
+
+ public:
+ /**
+ * Check whether or not the SimpleLogger's stream is empty.
+ */
+ bool empty();
+
+ /**
+ * Return a copy of the string contained in the SimpleLogger's stream.
+ */
+ std::string str() const;
+
+ /**
+ * Remove the bits set on the SimpleLogger's stream and clear its string.
+ */
+ void clear();
+
+ /**
+ * Return a reference to the SimpleLogger's stream, in order to e.g. push
+ * content into it.
+ */
+ std::ostringstream &stream();
};
#define ABC_LOG(logger) logger.stream()
@@ -234,4 +238,4 @@ public:
*/
std::ostream &operator<<(std::ostream &os, const SimpleLogger &logger);
-#endif /* __ABC_UTIL_H__ */
+#endif /* __ABC_UTIL_H__ */
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index 541db514bb0..0bc4eb2385b 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -74,15 +74,18 @@ extern "C" {
using Alembic::Abc::Int32ArraySamplePtr;
using Alembic::Abc::ObjectHeader;
+using Alembic::AbcGeom::kWrapExisting;
using Alembic::AbcGeom::MetaData;
using Alembic::AbcGeom::P3fArraySamplePtr;
-using Alembic::AbcGeom::kWrapExisting;
using Alembic::AbcGeom::ICamera;
+using Alembic::AbcGeom::ICompoundProperty;
using Alembic::AbcGeom::ICurves;
using Alembic::AbcGeom::ICurvesSchema;
using Alembic::AbcGeom::IFaceSet;
using Alembic::AbcGeom::ILight;
+using Alembic::AbcGeom::IN3fArrayProperty;
+using Alembic::AbcGeom::IN3fGeomParam;
using Alembic::AbcGeom::INuPatch;
using Alembic::AbcGeom::IObject;
using Alembic::AbcGeom::IPoints;
@@ -95,26 +98,23 @@ using Alembic::AbcGeom::IV2fGeomParam;
using Alembic::AbcGeom::IXform;
using Alembic::AbcGeom::IXformSchema;
using Alembic::AbcGeom::N3fArraySamplePtr;
-using Alembic::AbcGeom::XformSample;
-using Alembic::AbcGeom::ICompoundProperty;
-using Alembic::AbcGeom::IN3fArrayProperty;
-using Alembic::AbcGeom::IN3fGeomParam;
using Alembic::AbcGeom::V3fArraySamplePtr;
+using Alembic::AbcGeom::XformSample;
using Alembic::AbcMaterial::IMaterial;
struct AbcArchiveHandle {
- int unused;
+ int unused;
};
ABC_INLINE ArchiveReader *archive_from_handle(AbcArchiveHandle *handle)
{
- return reinterpret_cast<ArchiveReader *>(handle);
+ return reinterpret_cast<ArchiveReader *>(handle);
}
ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveReader *archive)
{
- return reinterpret_cast<AbcArchiveHandle *>(archive);
+ return reinterpret_cast<AbcArchiveHandle *>(archive);
}
//#define USE_NURBS
@@ -123,297 +123,289 @@ ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveReader *archive)
* sync. */
static bool gather_objects_paths(const IObject &object, ListBase *object_paths)
{
- if (!object.valid()) {
- return false;
- }
-
-
- size_t children_claiming_this_object = 0;
- size_t num_children = object.getNumChildren();
-
- for (size_t i = 0; i < num_children; ++i) {
- bool child_claims_this_object = gather_objects_paths(object.getChild(i), object_paths);
- children_claiming_this_object += child_claims_this_object ? 1 : 0;
- }
-
- const MetaData &md = object.getMetaData();
- bool get_path = false;
- bool parent_is_part_of_this_object = false;
-
- if (!object.getParent()) {
- /* The root itself is not an object we should import. */
- }
- else if (IXform::matches(md)) {
- if (has_property(object.getProperties(), "locator")) {
- get_path = true;
- }
- else {
- get_path = children_claiming_this_object == 0;
- }
-
- /* Transforms are never "data" for their parent. */
- parent_is_part_of_this_object = false;
- }
- else {
- /* These types are "data" for their parent. */
- get_path =
- IPolyMesh::matches(md) ||
- ISubD::matches(md) ||
+ if (!object.valid()) {
+ return false;
+ }
+
+ size_t children_claiming_this_object = 0;
+ size_t num_children = object.getNumChildren();
+
+ for (size_t i = 0; i < num_children; ++i) {
+ bool child_claims_this_object = gather_objects_paths(object.getChild(i), object_paths);
+ children_claiming_this_object += child_claims_this_object ? 1 : 0;
+ }
+
+ const MetaData &md = object.getMetaData();
+ bool get_path = false;
+ bool parent_is_part_of_this_object = false;
+
+ if (!object.getParent()) {
+ /* The root itself is not an object we should import. */
+ }
+ else if (IXform::matches(md)) {
+ if (has_property(object.getProperties(), "locator")) {
+ get_path = true;
+ }
+ else {
+ get_path = children_claiming_this_object == 0;
+ }
+
+ /* Transforms are never "data" for their parent. */
+ parent_is_part_of_this_object = false;
+ }
+ else {
+ /* These types are "data" for their parent. */
+ get_path = IPolyMesh::matches(md) || ISubD::matches(md) ||
#ifdef USE_NURBS
- INuPatch::matches(md) ||
+ INuPatch::matches(md) ||
#endif
- ICamera::matches(md) ||
- IPoints::matches(md) ||
- ICurves::matches(md);
- parent_is_part_of_this_object = get_path;
- }
+ ICamera::matches(md) || IPoints::matches(md) || ICurves::matches(md);
+ parent_is_part_of_this_object = get_path;
+ }
- if (get_path) {
- void *abc_path_void = MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath");
- AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(abc_path_void);
+ if (get_path) {
+ void *abc_path_void = MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath");
+ AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(abc_path_void);
- BLI_strncpy(abc_path->path, object.getFullName().c_str(), sizeof(abc_path->path));
- BLI_addtail(object_paths, abc_path);
- }
+ BLI_strncpy(abc_path->path, object.getFullName().c_str(), sizeof(abc_path->path));
+ BLI_addtail(object_paths, abc_path);
+ }
- return parent_is_part_of_this_object;
+ return parent_is_part_of_this_object;
}
AbcArchiveHandle *ABC_create_handle(const char *filename, ListBase *object_paths)
{
- ArchiveReader *archive = new ArchiveReader(filename);
+ ArchiveReader *archive = new ArchiveReader(filename);
- if (!archive->valid()) {
- delete archive;
- return NULL;
- }
+ if (!archive->valid()) {
+ delete archive;
+ return NULL;
+ }
- if (object_paths) {
- gather_objects_paths(archive->getTop(), object_paths);
- }
+ if (object_paths) {
+ gather_objects_paths(archive->getTop(), object_paths);
+ }
- return handle_from_archive(archive);
+ return handle_from_archive(archive);
}
void ABC_free_handle(AbcArchiveHandle *handle)
{
- delete archive_from_handle(handle);
+ delete archive_from_handle(handle);
}
int ABC_get_version()
{
- return ALEMBIC_LIBRARY_VERSION;
+ return ALEMBIC_LIBRARY_VERSION;
}
-static void find_iobject(const IObject &object, IObject &ret,
- const std::string &path)
+static void find_iobject(const IObject &object, IObject &ret, const std::string &path)
{
- if (!object.valid()) {
- return;
- }
+ if (!object.valid()) {
+ return;
+ }
- std::vector<std::string> tokens;
- split(path, '/', tokens);
+ std::vector<std::string> tokens;
+ split(path, '/', tokens);
- IObject tmp = object;
+ IObject tmp = object;
- std::vector<std::string>::iterator iter;
- for (iter = tokens.begin(); iter != tokens.end(); ++iter) {
- IObject child = tmp.getChild(*iter);
- tmp = child;
- }
+ std::vector<std::string>::iterator iter;
+ for (iter = tokens.begin(); iter != tokens.end(); ++iter) {
+ IObject child = tmp.getChild(*iter);
+ tmp = child;
+ }
- ret = tmp;
+ ret = tmp;
}
struct ExportJobData {
- ViewLayer *view_layer;
- Main *bmain;
+ ViewLayer *view_layer;
+ Main *bmain;
- char filename[1024];
- ExportSettings settings;
+ char filename[1024];
+ ExportSettings settings;
- short *stop;
- short *do_update;
- float *progress;
+ short *stop;
+ short *do_update;
+ float *progress;
- bool was_canceled;
- bool export_ok;
+ bool was_canceled;
+ bool export_ok;
};
static void export_startjob(void *customdata, short *stop, short *do_update, float *progress)
{
- ExportJobData *data = static_cast<ExportJobData *>(customdata);
+ ExportJobData *data = static_cast<ExportJobData *>(customdata);
- data->stop = stop;
- data->do_update = do_update;
- data->progress = progress;
+ data->stop = stop;
+ data->do_update = do_update;
+ data->progress = progress;
- /* XXX annoying hack: needed to prevent data corruption when changing
- * scene frame in separate threads
- */
- G.is_rendering = true;
- BKE_spacedata_draw_locks(true);
+ /* XXX annoying hack: needed to prevent data corruption when changing
+ * scene frame in separate threads
+ */
+ G.is_rendering = true;
+ BKE_spacedata_draw_locks(true);
- G.is_break = false;
+ G.is_break = false;
- DEG_graph_build_from_view_layer(data->settings.depsgraph,
- data->bmain,
- data->settings.scene,
- data->view_layer);
- BKE_scene_graph_update_tagged(data->settings.depsgraph, data->bmain);
+ DEG_graph_build_from_view_layer(
+ data->settings.depsgraph, data->bmain, data->settings.scene, data->view_layer);
+ BKE_scene_graph_update_tagged(data->settings.depsgraph, data->bmain);
- try {
- AbcExporter exporter(data->bmain, data->filename, data->settings);
+ try {
+ AbcExporter exporter(data->bmain, data->filename, data->settings);
- Scene *scene = data->settings.scene; /* for the CFRA macro */
- const int orig_frame = CFRA;
+ Scene *scene = data->settings.scene; /* for the CFRA macro */
+ const int orig_frame = CFRA;
- data->was_canceled = false;
- exporter(*data->progress, data->was_canceled);
+ data->was_canceled = false;
+ exporter(*data->progress, data->was_canceled);
- if (CFRA != orig_frame) {
- CFRA = orig_frame;
+ if (CFRA != orig_frame) {
+ CFRA = orig_frame;
- BKE_scene_graph_update_for_newframe(data->settings.depsgraph, data->bmain);
- }
+ BKE_scene_graph_update_for_newframe(data->settings.depsgraph, data->bmain);
+ }
- data->export_ok = !data->was_canceled;
- }
- catch (const std::exception &e) {
- ABC_LOG(data->settings.logger) << "Abc Export error: " << e.what() << '\n';
- }
- catch (...) {
- ABC_LOG(data->settings.logger) << "Abc Export: unknown error...\n";
- }
+ data->export_ok = !data->was_canceled;
+ }
+ catch (const std::exception &e) {
+ ABC_LOG(data->settings.logger) << "Abc Export error: " << e.what() << '\n';
+ }
+ catch (...) {
+ ABC_LOG(data->settings.logger) << "Abc Export: unknown error...\n";
+ }
}
static void export_endjob(void *customdata)
{
- ExportJobData *data = static_cast<ExportJobData *>(customdata);
+ ExportJobData *data = static_cast<ExportJobData *>(customdata);
- DEG_graph_free(data->settings.depsgraph);
+ DEG_graph_free(data->settings.depsgraph);
- if (data->was_canceled && BLI_exists(data->filename)) {
- BLI_delete(data->filename, false, false);
- }
+ if (data->was_canceled && BLI_exists(data->filename)) {
+ BLI_delete(data->filename, false, false);
+ }
- if (!data->settings.logger.empty()) {
- std::cerr << data->settings.logger;
- WM_report(RPT_ERROR, "Errors occurred during the export, look in the console to know more...");
- }
+ if (!data->settings.logger.empty()) {
+ std::cerr << data->settings.logger;
+ WM_report(RPT_ERROR, "Errors occurred during the export, look in the console to know more...");
+ }
- G.is_rendering = false;
- BKE_spacedata_draw_locks(false);
+ G.is_rendering = false;
+ BKE_spacedata_draw_locks(false);
}
-bool ABC_export(
- Scene *scene,
- bContext *C,
- const char *filepath,
- const struct AlembicExportParams *params,
- bool as_background_job)
+bool ABC_export(Scene *scene,
+ bContext *C,
+ const char *filepath,
+ const struct AlembicExportParams *params,
+ bool as_background_job)
{
- ExportJobData *job = static_cast<ExportJobData *>(MEM_mallocN(sizeof(ExportJobData), "ExportJobData"));
-
- job->view_layer = CTX_data_view_layer(C);
- job->bmain = CTX_data_main(C);
- job->export_ok = false;
- BLI_strncpy(job->filename, filepath, 1024);
-
- /* Alright, alright, alright....
- *
- * ExportJobData contains an ExportSettings containing a SimpleLogger.
- *
- * Since ExportJobData is a C-style struct dynamically allocated with
- * MEM_mallocN (see above), its constructor is never called, therefore the
- * ExportSettings constructor is not called which implies that the
- * SimpleLogger one is not called either. SimpleLogger in turn does not call
- * the constructor of its data members which ultimately means that its
- * std::ostringstream member has a NULL pointer. To be able to properly use
- * the stream's operator<<, the pointer needs to be set, therefore we have
- * to properly construct everything. And this is done using the placement
- * new operator as here below. It seems hackish, but I'm too lazy to
- * do bigger refactor and maybe there is a better way which does not involve
- * hardcore refactoring. */
- new (&job->settings) ExportSettings();
- job->settings.scene = scene;
- job->settings.depsgraph = DEG_graph_new(scene, job->view_layer, DAG_EVAL_RENDER);
-
- /* TODO(Sybren): for now we only export the active scene layer.
- * Later in the 2.8 development process this may be replaced by using
- * a specific collection for Alembic I/O, which can then be toggled
- * between "real" objects and cached Alembic files. */
- job->settings.view_layer = job->view_layer;
-
- job->settings.frame_start = params->frame_start;
- job->settings.frame_end = params->frame_end;
- job->settings.frame_samples_xform = params->frame_samples_xform;
- job->settings.frame_samples_shape = params->frame_samples_shape;
- job->settings.shutter_open = params->shutter_open;
- job->settings.shutter_close = params->shutter_close;
-
- /* TODO(Sybren): For now this is ignored, until we can get selection
- * detection working through Base pointers (instead of ob->flags). */
- job->settings.selected_only = params->selected_only;
-
- job->settings.export_face_sets = params->face_sets;
- job->settings.export_normals = params->normals;
- job->settings.export_uvs = params->uvs;
- job->settings.export_vcols = params->vcolors;
- job->settings.export_hair = params->export_hair;
- job->settings.export_particles = params->export_particles;
- job->settings.apply_subdiv = params->apply_subdiv;
- job->settings.curves_as_mesh = params->curves_as_mesh;
- job->settings.flatten_hierarchy = params->flatten_hierarchy;
-
- /* TODO(Sybren): visible_layer & renderable only is ignored for now,
- * to be replaced with collections later in the 2.8 dev process
- * (also see note above). */
- job->settings.visible_layers_only = params->visible_layers_only;
- job->settings.renderable_only = params->renderable_only;
-
- job->settings.use_subdiv_schema = params->use_subdiv_schema;
- 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);
- }
-
- bool export_ok = false;
- if (as_background_job) {
- wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
- CTX_wm_window(C),
- job->settings.scene,
- "Alembic Export",
- WM_JOB_PROGRESS,
- WM_JOB_TYPE_ALEMBIC);
-
- /* setup job */
- WM_jobs_customdata_set(wm_job, job, MEM_freeN);
- WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
- WM_jobs_callbacks(wm_job, export_startjob, NULL, NULL, export_endjob);
-
- WM_jobs_start(CTX_wm_manager(C), wm_job);
- }
- else {
- /* Fake a job context, so that we don't need NULL pointer checks while exporting. */
- short stop = 0, do_update = 0;
- float progress = 0.f;
-
- export_startjob(job, &stop, &do_update, &progress);
- export_endjob(job);
- export_ok = job->export_ok;
-
- MEM_freeN(job);
- }
-
- return export_ok;
+ ExportJobData *job = static_cast<ExportJobData *>(
+ MEM_mallocN(sizeof(ExportJobData), "ExportJobData"));
+
+ job->view_layer = CTX_data_view_layer(C);
+ job->bmain = CTX_data_main(C);
+ job->export_ok = false;
+ BLI_strncpy(job->filename, filepath, 1024);
+
+ /* Alright, alright, alright....
+ *
+ * ExportJobData contains an ExportSettings containing a SimpleLogger.
+ *
+ * Since ExportJobData is a C-style struct dynamically allocated with
+ * MEM_mallocN (see above), its constructor is never called, therefore the
+ * ExportSettings constructor is not called which implies that the
+ * SimpleLogger one is not called either. SimpleLogger in turn does not call
+ * the constructor of its data members which ultimately means that its
+ * std::ostringstream member has a NULL pointer. To be able to properly use
+ * the stream's operator<<, the pointer needs to be set, therefore we have
+ * to properly construct everything. And this is done using the placement
+ * new operator as here below. It seems hackish, but I'm too lazy to
+ * do bigger refactor and maybe there is a better way which does not involve
+ * hardcore refactoring. */
+ new (&job->settings) ExportSettings();
+ job->settings.scene = scene;
+ job->settings.depsgraph = DEG_graph_new(scene, job->view_layer, DAG_EVAL_RENDER);
+
+ /* TODO(Sybren): for now we only export the active scene layer.
+ * Later in the 2.8 development process this may be replaced by using
+ * a specific collection for Alembic I/O, which can then be toggled
+ * between "real" objects and cached Alembic files. */
+ job->settings.view_layer = job->view_layer;
+
+ job->settings.frame_start = params->frame_start;
+ job->settings.frame_end = params->frame_end;
+ job->settings.frame_samples_xform = params->frame_samples_xform;
+ job->settings.frame_samples_shape = params->frame_samples_shape;
+ job->settings.shutter_open = params->shutter_open;
+ job->settings.shutter_close = params->shutter_close;
+
+ /* TODO(Sybren): For now this is ignored, until we can get selection
+ * detection working through Base pointers (instead of ob->flags). */
+ job->settings.selected_only = params->selected_only;
+
+ job->settings.export_face_sets = params->face_sets;
+ job->settings.export_normals = params->normals;
+ job->settings.export_uvs = params->uvs;
+ job->settings.export_vcols = params->vcolors;
+ job->settings.export_hair = params->export_hair;
+ job->settings.export_particles = params->export_particles;
+ job->settings.apply_subdiv = params->apply_subdiv;
+ job->settings.curves_as_mesh = params->curves_as_mesh;
+ job->settings.flatten_hierarchy = params->flatten_hierarchy;
+
+ /* TODO(Sybren): visible_layer & renderable only is ignored for now,
+ * to be replaced with collections later in the 2.8 dev process
+ * (also see note above). */
+ job->settings.visible_layers_only = params->visible_layers_only;
+ job->settings.renderable_only = params->renderable_only;
+
+ job->settings.use_subdiv_schema = params->use_subdiv_schema;
+ 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);
+ }
+
+ bool export_ok = false;
+ if (as_background_job) {
+ wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
+ CTX_wm_window(C),
+ job->settings.scene,
+ "Alembic Export",
+ WM_JOB_PROGRESS,
+ WM_JOB_TYPE_ALEMBIC);
+
+ /* setup job */
+ WM_jobs_customdata_set(wm_job, job, MEM_freeN);
+ WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
+ WM_jobs_callbacks(wm_job, export_startjob, NULL, NULL, export_endjob);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+ }
+ else {
+ /* Fake a job context, so that we don't need NULL pointer checks while exporting. */
+ short stop = 0, do_update = 0;
+ float progress = 0.f;
+
+ export_startjob(job, &stop, &do_update, &progress);
+ export_endjob(job);
+ export_ok = job->export_ok;
+
+ MEM_freeN(job);
+ }
+
+ return export_ok;
}
/* ********************** Import file ********************** */
@@ -439,499 +431,505 @@ bool ABC_export(
* NOTE: this function is similar to gather_object_paths above, need to keep
* them in sync. */
static std::pair<bool, AbcObjectReader *> visit_object(
- const IObject &object,
- AbcObjectReader::ptr_vector &readers,
- ImportSettings &settings,
- AbcObjectReader::ptr_vector &r_assign_as_parent)
+ const IObject &object,
+ AbcObjectReader::ptr_vector &readers,
+ ImportSettings &settings,
+ AbcObjectReader::ptr_vector &r_assign_as_parent)
{
- const std::string & full_name = object.getFullName();
-
- if (!object.valid()) {
- std::cerr << " - "
- << full_name
- << ": object is invalid, skipping it and all its children.\n";
- return std::make_pair(false, static_cast<AbcObjectReader *>(NULL));
- }
-
- /* The interpretation of data by the children determine the role of this
- * object. This is especially important for Xform objects, as they can be
- * either part of a Blender object or a Blender object (Empty) themselves.
- */
- size_t children_claiming_this_object = 0;
- size_t num_children = object.getNumChildren();
- AbcObjectReader::ptr_vector claiming_child_readers;
- AbcObjectReader::ptr_vector nonclaiming_child_readers;
- AbcObjectReader::ptr_vector assign_as_parent;
- for (size_t i = 0; i < num_children; ++i) {
- const IObject ichild = object.getChild(i);
-
- /* TODO: When we only support C++11, use std::tie() instead. */
- std::pair<bool, AbcObjectReader *> child_result;
- child_result = visit_object(ichild, readers, settings, assign_as_parent);
-
- bool child_claims_this_object = child_result.first;
- AbcObjectReader *child_reader = child_result.second;
-
- if (child_reader == NULL) {
- BLI_assert(!child_claims_this_object);
- }
- else {
- if (child_claims_this_object) {
- claiming_child_readers.push_back(child_reader);
- }
- else {
- nonclaiming_child_readers.push_back(child_reader);
- }
- }
-
- children_claiming_this_object += child_claims_this_object ? 1 : 0;
- }
- BLI_assert(children_claiming_this_object == claiming_child_readers.size());
-
- AbcObjectReader *reader = NULL;
- const MetaData &md = object.getMetaData();
- bool parent_is_part_of_this_object = false;
-
- if (!object.getParent()) {
- /* The root itself is not an object we should import. */
- }
- else if (IXform::matches(md)) {
- bool create_empty;
-
- /* An xform can either be a Blender Object (if it contains a mesh, for
- * example), but it can also be an Empty. Its correct translation to
- * Blender's data model depends on its children. */
-
- /* Check whether or not this object is a Maya locator, which is
- * similar to empties used as parent object in Blender. */
- if (has_property(object.getProperties(), "locator")) {
- create_empty = true;
- }
- else {
- create_empty = claiming_child_readers.empty();
- }
-
- if (create_empty) {
- reader = new AbcEmptyReader(object, settings);
- }
- }
- else if (IPolyMesh::matches(md)) {
- reader = new AbcMeshReader(object, settings);
- parent_is_part_of_this_object = true;
- }
- else if (ISubD::matches(md)) {
- reader = new AbcSubDReader(object, settings);
- parent_is_part_of_this_object = true;
- }
- else if (INuPatch::matches(md)) {
+ const std::string &full_name = object.getFullName();
+
+ if (!object.valid()) {
+ std::cerr << " - " << full_name << ": object is invalid, skipping it and all its children.\n";
+ return std::make_pair(false, static_cast<AbcObjectReader *>(NULL));
+ }
+
+ /* The interpretation of data by the children determine the role of this
+ * object. This is especially important for Xform objects, as they can be
+ * either part of a Blender object or a Blender object (Empty) themselves.
+ */
+ size_t children_claiming_this_object = 0;
+ size_t num_children = object.getNumChildren();
+ AbcObjectReader::ptr_vector claiming_child_readers;
+ AbcObjectReader::ptr_vector nonclaiming_child_readers;
+ AbcObjectReader::ptr_vector assign_as_parent;
+ for (size_t i = 0; i < num_children; ++i) {
+ const IObject ichild = object.getChild(i);
+
+ /* TODO: When we only support C++11, use std::tie() instead. */
+ std::pair<bool, AbcObjectReader *> child_result;
+ child_result = visit_object(ichild, readers, settings, assign_as_parent);
+
+ bool child_claims_this_object = child_result.first;
+ AbcObjectReader *child_reader = child_result.second;
+
+ if (child_reader == NULL) {
+ BLI_assert(!child_claims_this_object);
+ }
+ else {
+ if (child_claims_this_object) {
+ claiming_child_readers.push_back(child_reader);
+ }
+ else {
+ nonclaiming_child_readers.push_back(child_reader);
+ }
+ }
+
+ children_claiming_this_object += child_claims_this_object ? 1 : 0;
+ }
+ BLI_assert(children_claiming_this_object == claiming_child_readers.size());
+
+ AbcObjectReader *reader = NULL;
+ const MetaData &md = object.getMetaData();
+ bool parent_is_part_of_this_object = false;
+
+ if (!object.getParent()) {
+ /* The root itself is not an object we should import. */
+ }
+ else if (IXform::matches(md)) {
+ bool create_empty;
+
+ /* An xform can either be a Blender Object (if it contains a mesh, for
+ * example), but it can also be an Empty. Its correct translation to
+ * Blender's data model depends on its children. */
+
+ /* Check whether or not this object is a Maya locator, which is
+ * similar to empties used as parent object in Blender. */
+ if (has_property(object.getProperties(), "locator")) {
+ create_empty = true;
+ }
+ else {
+ create_empty = claiming_child_readers.empty();
+ }
+
+ if (create_empty) {
+ reader = new AbcEmptyReader(object, settings);
+ }
+ }
+ else if (IPolyMesh::matches(md)) {
+ reader = new AbcMeshReader(object, settings);
+ parent_is_part_of_this_object = true;
+ }
+ else if (ISubD::matches(md)) {
+ reader = new AbcSubDReader(object, settings);
+ parent_is_part_of_this_object = true;
+ }
+ else if (INuPatch::matches(md)) {
#ifdef USE_NURBS
- /* TODO(kevin): importing cyclic NURBS from other software crashes
- * at the moment. This is due to the fact that NURBS in other
- * software have duplicated points which causes buffer overflows in
- * Blender. Need to figure out exactly how these points are
- * duplicated, in all cases (cyclic U, cyclic V, and cyclic UV).
- * Until this is fixed, disabling NURBS reading. */
- reader = new AbcNurbsReader(object, settings);
- parent_is_part_of_this_object = true;
+ /* TODO(kevin): importing cyclic NURBS from other software crashes
+ * at the moment. This is due to the fact that NURBS in other
+ * software have duplicated points which causes buffer overflows in
+ * Blender. Need to figure out exactly how these points are
+ * duplicated, in all cases (cyclic U, cyclic V, and cyclic UV).
+ * Until this is fixed, disabling NURBS reading. */
+ reader = new AbcNurbsReader(object, settings);
+ parent_is_part_of_this_object = true;
#endif
- }
- else if (ICamera::matches(md)) {
- reader = new AbcCameraReader(object, settings);
- parent_is_part_of_this_object = true;
- }
- else if (IPoints::matches(md)) {
- reader = new AbcPointsReader(object, settings);
- parent_is_part_of_this_object = true;
- }
- else if (IMaterial::matches(md)) {
- /* Pass for now. */
- }
- else if (ILight::matches(md)) {
- /* Pass for now. */
- }
- else if (IFaceSet::matches(md)) {
- /* Pass, those are handled in the mesh reader. */
- }
- else if (ICurves::matches(md)) {
- reader = new AbcCurveReader(object, settings);
- parent_is_part_of_this_object = true;
- }
- else {
- std::cerr << "Alembic object " << full_name
- << " is of unsupported schema type '"
- << object.getMetaData().get("schemaObjTitle") << "'"
- << std::endl;
- }
-
- if (reader) {
- /* We have created a reader, which should imply that this object is
- * not claimed as part of any child Alembic object. */
- BLI_assert(claiming_child_readers.empty());
-
- readers.push_back(reader);
- reader->incref();
-
- AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(
- MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath"));
- BLI_strncpy(abc_path->path, full_name.c_str(), sizeof(abc_path->path));
- BLI_addtail(&settings.cache_file->object_paths, abc_path);
-
- /* We can now assign this reader as parent for our children. */
- if (nonclaiming_child_readers.size() + assign_as_parent.size() > 0) {
- /* TODO: When we only support C++11, use for (a: b) instead. */
- BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
- child_reader->parent_reader = reader;
- }
- BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
- child_reader->parent_reader = reader;
- }
- }
- }
- else if (object.getParent()) {
- if (claiming_child_readers.size() > 0) {
- /* The first claiming child will serve just fine as parent to
- * our non-claiming children. Since all claiming children share
- * the same XForm, it doesn't really matter which one we pick. */
- AbcObjectReader *claiming_child = claiming_child_readers[0];
- BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
- child_reader->parent_reader = claiming_child;
- }
- BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
- child_reader->parent_reader = claiming_child;
- }
- /* Claiming children should have our parent set as their parent. */
- BOOST_FOREACH(AbcObjectReader *child_reader, claiming_child_readers) {
- r_assign_as_parent.push_back(child_reader);
- }
- }
- else {
- /* This object isn't claimed by any child, and didn't produce
- * a reader. Odd situation, could be the top Alembic object, or
- * an unsupported Alembic schema. Delegate to our parent. */
- BOOST_FOREACH(AbcObjectReader *child_reader, claiming_child_readers) {
- r_assign_as_parent.push_back(child_reader);
- }
- BOOST_FOREACH(AbcObjectReader *child_reader, nonclaiming_child_readers) {
- r_assign_as_parent.push_back(child_reader);
- }
- BOOST_FOREACH(AbcObjectReader *child_reader, assign_as_parent) {
- r_assign_as_parent.push_back(child_reader);
- }
- }
- }
-
- return std::make_pair(parent_is_part_of_this_object, reader);
+ }
+ else if (ICamera::matches(md)) {
+ reader = new AbcCameraReader(object, settings);
+ parent_is_part_of_this_object = true;
+ }
+ else if (IPoints::matches(md)) {
+ reader = new AbcPointsReader(object, settings);
+ parent_is_part_of_this_object = true;
+ }
+ else if (IMaterial::matches(md)) {
+ /* Pass for now. */
+ }
+ else if (ILight::matches(md)) {
+ /* Pass for now. */
+ }
+ else if (IFaceSet::matches(md)) {
+ /* Pass, those are handled in the mesh reader. */
+ }
+ else if (ICurves::matches(md)) {
+ reader = new AbcCurveReader(object, settings);
+ parent_is_part_of_this_object = true;
+ }
+ else {
+ std::cerr << "Alembic object " << full_name << " is of unsupported schema type '"
+ << object.getMetaData().get("schemaObjTitle") << "'" << std::endl;
+ }
+
+ if (reader) {
+ /* We have created a reader, which should imply that this object is
+ * not claimed as part of any child Alembic object. */
+ BLI_assert(claiming_child_readers.empty());
+
+ readers.push_back(reader);
+ reader->incref();
+
+ AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(
+ MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath"));
+ BLI_strncpy(abc_path->path, full_name.c_str(), sizeof(abc_path->path));
+ BLI_addtail(&settings.cache_file->object_paths, abc_path);
+
+ /* We can now assign this reader as parent for our children. */
+ if (nonclaiming_child_readers.size() + assign_as_parent.size() > 0) {
+ /* TODO: When we only support C++11, use for (a: b) instead. */
+ BOOST_FOREACH (AbcObjectReader *child_reader, nonclaiming_child_readers) {
+ child_reader->parent_reader = reader;
+ }
+ BOOST_FOREACH (AbcObjectReader *child_reader, assign_as_parent) {
+ child_reader->parent_reader = reader;
+ }
+ }
+ }
+ else if (object.getParent()) {
+ if (claiming_child_readers.size() > 0) {
+ /* The first claiming child will serve just fine as parent to
+ * our non-claiming children. Since all claiming children share
+ * the same XForm, it doesn't really matter which one we pick. */
+ AbcObjectReader *claiming_child = claiming_child_readers[0];
+ BOOST_FOREACH (AbcObjectReader *child_reader, nonclaiming_child_readers) {
+ child_reader->parent_reader = claiming_child;
+ }
+ BOOST_FOREACH (AbcObjectReader *child_reader, assign_as_parent) {
+ child_reader->parent_reader = claiming_child;
+ }
+ /* Claiming children should have our parent set as their parent. */
+ BOOST_FOREACH (AbcObjectReader *child_reader, claiming_child_readers) {
+ r_assign_as_parent.push_back(child_reader);
+ }
+ }
+ else {
+ /* This object isn't claimed by any child, and didn't produce
+ * a reader. Odd situation, could be the top Alembic object, or
+ * an unsupported Alembic schema. Delegate to our parent. */
+ BOOST_FOREACH (AbcObjectReader *child_reader, claiming_child_readers) {
+ r_assign_as_parent.push_back(child_reader);
+ }
+ BOOST_FOREACH (AbcObjectReader *child_reader, nonclaiming_child_readers) {
+ r_assign_as_parent.push_back(child_reader);
+ }
+ BOOST_FOREACH (AbcObjectReader *child_reader, assign_as_parent) {
+ r_assign_as_parent.push_back(child_reader);
+ }
+ }
+ }
+
+ return std::make_pair(parent_is_part_of_this_object, reader);
}
enum {
- ABC_NO_ERROR = 0,
- ABC_ARCHIVE_FAIL,
- ABC_UNSUPPORTED_HDF5,
+ ABC_NO_ERROR = 0,
+ ABC_ARCHIVE_FAIL,
+ ABC_UNSUPPORTED_HDF5,
};
struct ImportJobData {
- Main *bmain;
- Scene *scene;
- ViewLayer *view_layer;
- wmWindowManager *wm;
+ Main *bmain;
+ Scene *scene;
+ ViewLayer *view_layer;
+ wmWindowManager *wm;
- char filename[1024];
- ImportSettings settings;
+ char filename[1024];
+ ImportSettings settings;
- std::vector<AbcObjectReader *> readers;
+ std::vector<AbcObjectReader *> readers;
- short *stop;
- short *do_update;
- float *progress;
+ short *stop;
+ short *do_update;
+ float *progress;
- char error_code;
- bool was_cancelled;
- bool import_ok;
+ char error_code;
+ bool was_cancelled;
+ bool import_ok;
};
static void import_startjob(void *user_data, short *stop, short *do_update, float *progress)
{
- SCOPE_TIMER("Alembic import, objects reading and creation");
+ SCOPE_TIMER("Alembic import, objects reading and creation");
- ImportJobData *data = static_cast<ImportJobData *>(user_data);
+ ImportJobData *data = static_cast<ImportJobData *>(user_data);
- data->stop = stop;
- data->do_update = do_update;
- data->progress = progress;
+ data->stop = stop;
+ data->do_update = do_update;
+ data->progress = progress;
- WM_set_locked_interface(data->wm, true);
+ WM_set_locked_interface(data->wm, true);
- ArchiveReader *archive = new ArchiveReader(data->filename);
+ ArchiveReader *archive = new ArchiveReader(data->filename);
- if (!archive->valid()) {
+ if (!archive->valid()) {
#ifndef WITH_ALEMBIC_HDF5
- data->error_code = archive->is_hdf5() ? ABC_UNSUPPORTED_HDF5 : ABC_ARCHIVE_FAIL;
+ data->error_code = archive->is_hdf5() ? ABC_UNSUPPORTED_HDF5 : ABC_ARCHIVE_FAIL;
#else
- data->error_code = ABC_ARCHIVE_FAIL;
+ data->error_code = ABC_ARCHIVE_FAIL;
#endif
- delete archive;
- return;
- }
-
- CacheFile *cache_file = static_cast<CacheFile *>(BKE_cachefile_add(data->bmain, BLI_path_basename(data->filename)));
-
- /* Decrement the ID ref-count because it is going to be incremented for each
- * modifier and constraint that it will be attached to, so since currently
- * it is not used by anyone, its use count will off by one. */
- id_us_min(&cache_file->id);
-
- cache_file->is_sequence = data->settings.is_sequence;
- cache_file->scale = data->settings.scale;
- cache_file->handle = handle_from_archive(archive);
- BLI_strncpy(cache_file->filepath, data->filename, 1024);
-
- data->settings.cache_file = cache_file;
-
- *data->do_update = true;
- *data->progress = 0.05f;
-
- /* Parse Alembic Archive. */
- AbcObjectReader::ptr_vector assign_as_parent;
- visit_object(archive->getTop(), data->readers, data->settings, assign_as_parent);
-
- /* There shouldn't be any orphans. */
- BLI_assert(assign_as_parent.size() == 0);
-
- if (G.is_break) {
- data->was_cancelled = true;
- return;
- }
-
- *data->do_update = true;
- *data->progress = 0.1f;
-
- /* Create objects and set scene frame range. */
-
- const float size = static_cast<float>(data->readers.size());
- size_t i = 0;
-
- chrono_t min_time = std::numeric_limits<chrono_t>::max();
- chrono_t max_time = std::numeric_limits<chrono_t>::min();
-
- ISampleSelector sample_sel(0.0f);
- std::vector<AbcObjectReader *>::iterator iter;
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- AbcObjectReader *reader = *iter;
-
- if (reader->valid()) {
- reader->readObjectData(data->bmain, sample_sel);
-
- min_time = std::min(min_time, reader->minTime());
- max_time = std::max(max_time, reader->maxTime());
- }
- else {
- std::cerr << "Object " << reader->name() << " in Alembic file "
- << data->filename << " is invalid.\n";
- }
-
- *data->progress = 0.1f + 0.3f * (++i / size);
- *data->do_update = true;
-
- if (G.is_break) {
- data->was_cancelled = true;
- return;
- }
- }
-
- if (data->settings.set_frame_range) {
- Scene *scene = data->scene;
-
- if (data->settings.is_sequence) {
- SFRA = data->settings.sequence_offset;
- EFRA = SFRA + (data->settings.sequence_len - 1);
- CFRA = SFRA;
- }
- else if (min_time < max_time) {
- SFRA = static_cast<int>(round(min_time * FPS));
- EFRA = static_cast<int>(round(max_time * FPS));
- CFRA = SFRA;
- }
- }
-
- /* Setup parenthood. */
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- const AbcObjectReader *reader = *iter;
- const AbcObjectReader *parent_reader = reader->parent_reader;
- Object *ob = reader->object();
-
- if (parent_reader == NULL || !reader->inherits_xform()) {
- ob->parent = NULL;
- }
- else {
- ob->parent = parent_reader->object();
- }
- }
-
- /* Setup transformations and constraints. */
- i = 0;
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- AbcObjectReader *reader = *iter;
- reader->setupObjectTransform(0.0f);
-
- *data->progress = 0.7f + 0.3f * (++i / size);
- *data->do_update = true;
-
- if (G.is_break) {
- data->was_cancelled = true;
- return;
- }
- }
+ delete archive;
+ return;
+ }
+
+ CacheFile *cache_file = static_cast<CacheFile *>(
+ BKE_cachefile_add(data->bmain, BLI_path_basename(data->filename)));
+
+ /* Decrement the ID ref-count because it is going to be incremented for each
+ * modifier and constraint that it will be attached to, so since currently
+ * it is not used by anyone, its use count will off by one. */
+ id_us_min(&cache_file->id);
+
+ cache_file->is_sequence = data->settings.is_sequence;
+ cache_file->scale = data->settings.scale;
+ cache_file->handle = handle_from_archive(archive);
+ BLI_strncpy(cache_file->filepath, data->filename, 1024);
+
+ data->settings.cache_file = cache_file;
+
+ *data->do_update = true;
+ *data->progress = 0.05f;
+
+ /* Parse Alembic Archive. */
+ AbcObjectReader::ptr_vector assign_as_parent;
+ visit_object(archive->getTop(), data->readers, data->settings, assign_as_parent);
+
+ /* There shouldn't be any orphans. */
+ BLI_assert(assign_as_parent.size() == 0);
+
+ if (G.is_break) {
+ data->was_cancelled = true;
+ return;
+ }
+
+ *data->do_update = true;
+ *data->progress = 0.1f;
+
+ /* Create objects and set scene frame range. */
+
+ const float size = static_cast<float>(data->readers.size());
+ size_t i = 0;
+
+ chrono_t min_time = std::numeric_limits<chrono_t>::max();
+ chrono_t max_time = std::numeric_limits<chrono_t>::min();
+
+ ISampleSelector sample_sel(0.0f);
+ std::vector<AbcObjectReader *>::iterator iter;
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ AbcObjectReader *reader = *iter;
+
+ if (reader->valid()) {
+ reader->readObjectData(data->bmain, sample_sel);
+
+ min_time = std::min(min_time, reader->minTime());
+ max_time = std::max(max_time, reader->maxTime());
+ }
+ else {
+ std::cerr << "Object " << reader->name() << " in Alembic file " << data->filename
+ << " is invalid.\n";
+ }
+
+ *data->progress = 0.1f + 0.3f * (++i / size);
+ *data->do_update = true;
+
+ if (G.is_break) {
+ data->was_cancelled = true;
+ return;
+ }
+ }
+
+ if (data->settings.set_frame_range) {
+ Scene *scene = data->scene;
+
+ if (data->settings.is_sequence) {
+ SFRA = data->settings.sequence_offset;
+ EFRA = SFRA + (data->settings.sequence_len - 1);
+ CFRA = SFRA;
+ }
+ else if (min_time < max_time) {
+ SFRA = static_cast<int>(round(min_time * FPS));
+ EFRA = static_cast<int>(round(max_time * FPS));
+ CFRA = SFRA;
+ }
+ }
+
+ /* Setup parenthood. */
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ const AbcObjectReader *reader = *iter;
+ const AbcObjectReader *parent_reader = reader->parent_reader;
+ Object *ob = reader->object();
+
+ if (parent_reader == NULL || !reader->inherits_xform()) {
+ ob->parent = NULL;
+ }
+ else {
+ ob->parent = parent_reader->object();
+ }
+ }
+
+ /* Setup transformations and constraints. */
+ i = 0;
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ AbcObjectReader *reader = *iter;
+ reader->setupObjectTransform(0.0f);
+
+ *data->progress = 0.7f + 0.3f * (++i / size);
+ *data->do_update = true;
+
+ if (G.is_break) {
+ data->was_cancelled = true;
+ return;
+ }
+ }
}
static void import_endjob(void *user_data)
{
- SCOPE_TIMER("Alembic import, cleanup");
-
- ImportJobData *data = static_cast<ImportJobData *>(user_data);
-
- std::vector<AbcObjectReader *>::iterator iter;
-
- /* Delete objects on cancelation. */
- if (data->was_cancelled) {
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- Object *ob = (*iter)->object();
-
- /* It's possible that cancellation occurred between the creation of
- * the reader and the creation of the Blender object. */
- if (ob == NULL) continue;
-
- BKE_id_free_us(data->bmain, ob);
- }
- }
- else {
- /* Add object to scene. */
- Base *base;
- LayerCollection *lc;
- ViewLayer *view_layer = data->view_layer;
-
- BKE_view_layer_base_deselect_all(view_layer);
-
- lc = BKE_layer_collection_get_active(view_layer);
-
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- Object *ob = (*iter)->object();
-
- BKE_collection_object_add(data->bmain, lc->collection, ob);
-
- base = BKE_view_layer_base_find(view_layer, ob);
- /* TODO: is setting active needed? */
- BKE_view_layer_base_select_and_set_active(view_layer, base);
-
- DEG_id_tag_update(&lc->collection->id, ID_RECALC_COPY_ON_WRITE);
- DEG_id_tag_update_ex(data->bmain, &ob->id,
- ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION | ID_RECALC_BASE_FLAGS);
- }
-
- DEG_id_tag_update(&data->scene->id, ID_RECALC_BASE_FLAGS);
- DEG_relations_tag_update(data->bmain);
- }
-
- for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
- AbcObjectReader *reader = *iter;
- reader->decref();
-
- if (reader->refcount() == 0) {
- delete reader;
- }
- }
-
- WM_set_locked_interface(data->wm, false);
-
- switch (data->error_code) {
- default:
- case ABC_NO_ERROR:
- data->import_ok = !data->was_cancelled;
- break;
- case ABC_ARCHIVE_FAIL:
- WM_report(RPT_ERROR, "Could not open Alembic archive for reading! See console for detail.");
- break;
- case ABC_UNSUPPORTED_HDF5:
- WM_report(RPT_ERROR, "Alembic archive in obsolete HDF5 format is not supported.");
- break;
- }
-
- WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);
+ SCOPE_TIMER("Alembic import, cleanup");
+
+ ImportJobData *data = static_cast<ImportJobData *>(user_data);
+
+ std::vector<AbcObjectReader *>::iterator iter;
+
+ /* Delete objects on cancelation. */
+ if (data->was_cancelled) {
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ Object *ob = (*iter)->object();
+
+ /* It's possible that cancellation occurred between the creation of
+ * the reader and the creation of the Blender object. */
+ if (ob == NULL)
+ continue;
+
+ BKE_id_free_us(data->bmain, ob);
+ }
+ }
+ else {
+ /* Add object to scene. */
+ Base *base;
+ LayerCollection *lc;
+ ViewLayer *view_layer = data->view_layer;
+
+ BKE_view_layer_base_deselect_all(view_layer);
+
+ lc = BKE_layer_collection_get_active(view_layer);
+
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ Object *ob = (*iter)->object();
+
+ BKE_collection_object_add(data->bmain, lc->collection, ob);
+
+ base = BKE_view_layer_base_find(view_layer, ob);
+ /* TODO: is setting active needed? */
+ BKE_view_layer_base_select_and_set_active(view_layer, base);
+
+ DEG_id_tag_update(&lc->collection->id, ID_RECALC_COPY_ON_WRITE);
+ DEG_id_tag_update_ex(data->bmain,
+ &ob->id,
+ ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION |
+ ID_RECALC_BASE_FLAGS);
+ }
+
+ DEG_id_tag_update(&data->scene->id, ID_RECALC_BASE_FLAGS);
+ DEG_relations_tag_update(data->bmain);
+ }
+
+ for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
+ AbcObjectReader *reader = *iter;
+ reader->decref();
+
+ if (reader->refcount() == 0) {
+ delete reader;
+ }
+ }
+
+ WM_set_locked_interface(data->wm, false);
+
+ switch (data->error_code) {
+ default:
+ case ABC_NO_ERROR:
+ data->import_ok = !data->was_cancelled;
+ break;
+ case ABC_ARCHIVE_FAIL:
+ WM_report(RPT_ERROR, "Could not open Alembic archive for reading! See console for detail.");
+ break;
+ case ABC_UNSUPPORTED_HDF5:
+ WM_report(RPT_ERROR, "Alembic archive in obsolete HDF5 format is not supported.");
+ break;
+ }
+
+ WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);
}
static void import_freejob(void *user_data)
{
- ImportJobData *data = static_cast<ImportJobData *>(user_data);
- delete data;
+ ImportJobData *data = static_cast<ImportJobData *>(user_data);
+ delete data;
}
-bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence,
- bool set_frame_range, int sequence_len, int offset,
- bool validate_meshes, bool as_background_job)
+bool ABC_import(bContext *C,
+ const char *filepath,
+ float scale,
+ bool is_sequence,
+ bool set_frame_range,
+ int sequence_len,
+ int offset,
+ bool validate_meshes,
+ bool as_background_job)
{
- /* Using new here since MEM_* funcs do not call ctor to properly initialize
- * data. */
- ImportJobData *job = new ImportJobData();
- job->bmain = CTX_data_main(C);
- job->scene = CTX_data_scene(C);
- job->view_layer = CTX_data_view_layer(C);
- job->wm = CTX_wm_manager(C);
- job->import_ok = false;
- BLI_strncpy(job->filename, filepath, 1024);
-
- job->settings.scale = scale;
- job->settings.is_sequence = is_sequence;
- job->settings.set_frame_range = set_frame_range;
- job->settings.sequence_len = sequence_len;
- job->settings.sequence_offset = offset;
- job->settings.validate_meshes = validate_meshes;
- job->error_code = ABC_NO_ERROR;
- job->was_cancelled = false;
-
- G.is_break = false;
-
- bool import_ok = false;
- if (as_background_job) {
- wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
- CTX_wm_window(C),
- job->scene,
- "Alembic Import",
- WM_JOB_PROGRESS,
- WM_JOB_TYPE_ALEMBIC);
-
- /* setup job */
- WM_jobs_customdata_set(wm_job, job, import_freejob);
- WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
- WM_jobs_callbacks(wm_job, import_startjob, NULL, NULL, import_endjob);
-
- WM_jobs_start(CTX_wm_manager(C), wm_job);
- }
- else {
- /* Fake a job context, so that we don't need NULL pointer checks while importing. */
- short stop = 0, do_update = 0;
- float progress = 0.f;
-
- import_startjob(job, &stop, &do_update, &progress);
- import_endjob(job);
- import_ok = job->import_ok;
-
- import_freejob(job);
- }
-
- return import_ok;
+ /* Using new here since MEM_* funcs do not call ctor to properly initialize
+ * data. */
+ ImportJobData *job = new ImportJobData();
+ job->bmain = CTX_data_main(C);
+ job->scene = CTX_data_scene(C);
+ job->view_layer = CTX_data_view_layer(C);
+ job->wm = CTX_wm_manager(C);
+ job->import_ok = false;
+ BLI_strncpy(job->filename, filepath, 1024);
+
+ job->settings.scale = scale;
+ job->settings.is_sequence = is_sequence;
+ job->settings.set_frame_range = set_frame_range;
+ job->settings.sequence_len = sequence_len;
+ job->settings.sequence_offset = offset;
+ job->settings.validate_meshes = validate_meshes;
+ job->error_code = ABC_NO_ERROR;
+ job->was_cancelled = false;
+
+ G.is_break = false;
+
+ bool import_ok = false;
+ if (as_background_job) {
+ wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
+ CTX_wm_window(C),
+ job->scene,
+ "Alembic Import",
+ WM_JOB_PROGRESS,
+ WM_JOB_TYPE_ALEMBIC);
+
+ /* setup job */
+ WM_jobs_customdata_set(wm_job, job, import_freejob);
+ WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
+ WM_jobs_callbacks(wm_job, import_startjob, NULL, NULL, import_endjob);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+ }
+ else {
+ /* Fake a job context, so that we don't need NULL pointer checks while importing. */
+ short stop = 0, do_update = 0;
+ float progress = 0.f;
+
+ import_startjob(job, &stop, &do_update, &progress);
+ import_endjob(job);
+ import_ok = job->import_ok;
+
+ import_freejob(job);
+ }
+
+ return import_ok;
}
/* ************************************************************************** */
void ABC_get_transform(CacheReader *reader, float r_mat[4][4], float time, float scale)
{
- if (!reader) {
- return;
- }
+ if (!reader) {
+ return;
+ }
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
- bool is_constant = false;
- abc_reader->read_matrix(r_mat, time, scale, is_constant);
+ bool is_constant = false;
+ abc_reader->read_matrix(r_mat, time, scale, is_constant);
}
/* ************************************************************************** */
@@ -943,71 +941,74 @@ Mesh *ABC_read_mesh(CacheReader *reader,
const char **err_str,
int read_flag)
{
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
- IObject iobject = abc_reader->iobject();
-
- if (!iobject.valid()) {
- *err_str = "Invalid object: verify object path";
- return NULL;
- }
-
- const ObjectHeader &header = iobject.getHeader();
- if (!abc_reader->accepts_object_type(header, ob, err_str)) {
- /* err_str is set by acceptsObjectType() */
- return NULL;
- }
-
- /* kFloorIndex is used to be compatible with non-interpolating
- * properties; they use the floor. */
- ISampleSelector sample_sel(time, ISampleSelector::kFloorIndex);
- return abc_reader->read_mesh(existing_mesh, sample_sel, read_flag, err_str);
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+ IObject iobject = abc_reader->iobject();
+
+ if (!iobject.valid()) {
+ *err_str = "Invalid object: verify object path";
+ return NULL;
+ }
+
+ const ObjectHeader &header = iobject.getHeader();
+ if (!abc_reader->accepts_object_type(header, ob, err_str)) {
+ /* err_str is set by acceptsObjectType() */
+ return NULL;
+ }
+
+ /* kFloorIndex is used to be compatible with non-interpolating
+ * properties; they use the floor. */
+ ISampleSelector sample_sel(time, ISampleSelector::kFloorIndex);
+ return abc_reader->read_mesh(existing_mesh, sample_sel, read_flag, err_str);
}
/* ************************************************************************** */
void CacheReader_free(CacheReader *reader)
{
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
- abc_reader->decref();
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+ abc_reader->decref();
- if (abc_reader->refcount() == 0) {
- delete abc_reader;
- }
+ if (abc_reader->refcount() == 0) {
+ delete abc_reader;
+ }
}
void CacheReader_incref(CacheReader *reader)
{
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
- abc_reader->incref();
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+ abc_reader->incref();
}
-CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle, CacheReader *reader, Object *object, const char *object_path)
+CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle,
+ CacheReader *reader,
+ Object *object,
+ const char *object_path)
{
- if (object_path[0] == '\0') {
- return reader;
- }
+ if (object_path[0] == '\0') {
+ return reader;
+ }
- ArchiveReader *archive = archive_from_handle(handle);
+ ArchiveReader *archive = archive_from_handle(handle);
- if (!archive || !archive->valid()) {
- return reader;
- }
+ if (!archive || !archive->valid()) {
+ return reader;
+ }
- IObject iobject;
- find_iobject(archive->getTop(), iobject, object_path);
+ IObject iobject;
+ find_iobject(archive->getTop(), iobject, object_path);
- if (reader) {
- CacheReader_free(reader);
- }
+ if (reader) {
+ CacheReader_free(reader);
+ }
- ImportSettings settings;
- AbcObjectReader *abc_reader = create_reader(iobject, settings);
- if (abc_reader == NULL) {
- /* This object is not supported */
- return NULL;
- }
- abc_reader->object(object);
- abc_reader->incref();
+ ImportSettings settings;
+ AbcObjectReader *abc_reader = create_reader(iobject, settings);
+ if (abc_reader == NULL) {
+ /* This object is not supported */
+ return NULL;
+ }
+ abc_reader->object(object);
+ abc_reader->incref();
- return reinterpret_cast<CacheReader *>(abc_reader);
+ return reinterpret_cast<CacheReader *>(abc_reader);
}