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:
authorSybren A. Stüvel <sybren@blender.org>2020-03-06 18:19:35 +0300
committerSybren A. Stüvel <sybren@blender.org>2020-03-06 18:19:45 +0300
commiteb522af4fec58876ac1b0a73ad9bcdae2d82d33f (patch)
tree485c6a1fb23b5be256757375e2157378d3a5c61b /source/blender/alembic
parentff60dd8b18ed00902e5bdfd36882072db7af8735 (diff)
Cleanup: move Alembic, AVI, Collada, and USD to `source/blender/io`
This moves the `alembic`, `avi`, `collada`, and `usd` modules into a common `io` directory. This also cleans up some `#include "../../{somedir}/{somefile}.h"` by adding `../../io/{somedir}` to `CMakeLists.txt` and then just using `#include "{somefile}.h"`. No functional changes.
Diffstat (limited to 'source/blender/alembic')
-rw-r--r--source/blender/alembic/ABC_alembic.h141
-rw-r--r--source/blender/alembic/CMakeLists.txt110
-rw-r--r--source/blender/alembic/intern/abc_customdata.cc484
-rw-r--r--source/blender/alembic/intern/abc_customdata.h104
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc677
-rw-r--r--source/blender/alembic/intern/abc_exporter.h128
-rw-r--r--source/blender/alembic/intern/abc_reader_archive.cc140
-rw-r--r--source/blender/alembic/intern/abc_reader_archive.h67
-rw-r--r--source/blender/alembic/intern/abc_reader_camera.cc113
-rw-r--r--source/blender/alembic/intern/abc_reader_camera.h40
-rw-r--r--source/blender/alembic/intern/abc_reader_curves.cc354
-rw-r--r--source/blender/alembic/intern/abc_reader_curves.h56
-rw-r--r--source/blender/alembic/intern/abc_reader_mesh.cc889
-rw-r--r--source/blender/alembic/intern/abc_reader_mesh.h86
-rw-r--r--source/blender/alembic/intern/abc_reader_nurbs.cc225
-rw-r--r--source/blender/alembic/intern/abc_reader_nurbs.h40
-rw-r--r--source/blender/alembic/intern/abc_reader_object.cc333
-rw-r--r--source/blender/alembic/intern/abc_reader_object.h171
-rw-r--r--source/blender/alembic/intern/abc_reader_points.cc157
-rw-r--r--source/blender/alembic/intern/abc_reader_points.h54
-rw-r--r--source/blender/alembic/intern/abc_reader_transform.cc76
-rw-r--r--source/blender/alembic/intern/abc_reader_transform.h42
-rw-r--r--source/blender/alembic/intern/abc_util.cc393
-rw-r--r--source/blender/alembic/intern/abc_util.h236
-rw-r--r--source/blender/alembic/intern/abc_writer_archive.cc114
-rw-r--r--source/blender/alembic/intern/abc_writer_archive.h58
-rw-r--r--source/blender/alembic/intern/abc_writer_camera.cc81
-rw-r--r--source/blender/alembic/intern/abc_writer_camera.h45
-rw-r--r--source/blender/alembic/intern/abc_writer_curves.cc189
-rw-r--r--source/blender/alembic/intern/abc_writer_curves.h55
-rw-r--r--source/blender/alembic/intern/abc_writer_hair.cc292
-rw-r--r--source/blender/alembic/intern/abc_writer_hair.h62
-rw-r--r--source/blender/alembic/intern/abc_writer_mball.cc97
-rw-r--r--source/blender/alembic/intern/abc_writer_mball.h56
-rw-r--r--source/blender/alembic/intern/abc_writer_mesh.cc592
-rw-r--r--source/blender/alembic/intern/abc_writer_mesh.h91
-rw-r--r--source/blender/alembic/intern/abc_writer_nurbs.cc172
-rw-r--r--source/blender/alembic/intern/abc_writer_nurbs.h42
-rw-r--r--source/blender/alembic/intern/abc_writer_object.cc79
-rw-r--r--source/blender/alembic/intern/abc_writer_object.h71
-rw-r--r--source/blender/alembic/intern/abc_writer_points.cc123
-rw-r--r--source/blender/alembic/intern/abc_writer_points.h49
-rw-r--r--source/blender/alembic/intern/abc_writer_transform.cc121
-rw-r--r--source/blender/alembic/intern/abc_writer_transform.h60
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc1052
45 files changed, 0 insertions, 8617 deletions
diff --git a/source/blender/alembic/ABC_alembic.h b/source/blender/alembic/ABC_alembic.h
deleted file mode 100644
index 878dbfc2a53..00000000000
--- a/source/blender/alembic/ABC_alembic.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_ALEMBIC_H__
-#define __ABC_ALEMBIC_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct CacheReader;
-struct ListBase;
-struct Main;
-struct Mesh;
-struct Object;
-struct Scene;
-struct bContext;
-
-typedef struct AbcArchiveHandle AbcArchiveHandle;
-
-enum {
- ABC_ARCHIVE_OGAWA = 0,
- ABC_ARCHIVE_HDF5 = 1,
-};
-
-int ABC_get_version(void);
-
-struct AlembicExportParams {
- double frame_start;
- double frame_end;
-
- unsigned int frame_samples_xform;
- unsigned int frame_samples_shape;
-
- double shutter_open;
- double shutter_close;
-
- bool selected_only;
- bool uvs;
- bool normals;
- bool vcolors;
- bool apply_subdiv;
- bool curves_as_mesh;
- bool flatten_hierarchy;
- bool visible_objects_only;
- bool renderable_only;
- bool face_sets;
- bool use_subdiv_schema;
- bool packuv;
- bool triangulate;
- bool export_hair;
- bool export_particles;
-
- unsigned int compression_type : 1;
-
- /* See MOD_TRIANGULATE_NGON_xxx and MOD_TRIANGULATE_QUAD_xxx
- * in DNA_modifier_types.h */
- int quad_method;
- int ngon_method;
-
- float global_scale;
-};
-
-/* The ABC_export and ABC_import functions both take a as_background_job
- * parameter, and return a boolean.
- *
- * When as_background_job=true, returns false immediately after scheduling
- * a background job.
- *
- * When as_background_job=false, performs the export synchronously, and returns
- * true when the export was ok, and false if there were any errors.
- */
-
-bool ABC_export(struct Scene *scene,
- struct bContext *C,
- const char *filepath,
- const struct AlembicExportParams *params,
- bool as_background_job);
-
-bool ABC_import(struct 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);
-
-AbcArchiveHandle *ABC_create_handle(struct Main *bmain,
- const char *filename,
- struct ListBase *object_paths);
-
-void ABC_free_handle(AbcArchiveHandle *handle);
-
-void ABC_get_transform(struct CacheReader *reader, float r_mat[4][4], float time, float scale);
-
-/* Either modifies current_mesh in-place or constructs a new mesh. */
-struct Mesh *ABC_read_mesh(struct CacheReader *reader,
- struct Object *ob,
- struct Mesh *current_mesh,
- const float time,
- const char **err_str,
- int flags);
-
-bool ABC_mesh_topology_changed(struct CacheReader *reader,
- struct Object *ob,
- struct Mesh *existing_mesh,
- const float time,
- const char **err_str);
-
-void CacheReader_incref(struct CacheReader *reader);
-void CacheReader_free(struct CacheReader *reader);
-
-struct CacheReader *CacheReader_open_alembic_object(struct AbcArchiveHandle *handle,
- struct CacheReader *reader,
- struct Object *object,
- const char *object_path);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __ABC_ALEMBIC_H__ */
diff --git a/source/blender/alembic/CMakeLists.txt b/source/blender/alembic/CMakeLists.txt
deleted file mode 100644
index 8bb7051982a..00000000000
--- a/source/blender/alembic/CMakeLists.txt
+++ /dev/null
@@ -1,110 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# The Original Code is Copyright (C) 2006, Blender Foundation
-# All rights reserved.
-# ***** END GPL LICENSE BLOCK *****
-
-set(INC
- .
- ../blenkernel
- ../blenlib
- ../blenloader
- ../bmesh
- ../depsgraph
- ../editors/include
- ../makesdna
- ../makesrna
- ../windowmanager
- ../../../intern/guardedalloc
- ../../../intern/utfconv
-)
-
-set(INC_SYS
- ${ALEMBIC_INCLUDE_DIRS}
- ${BOOST_INCLUDE_DIR}
- ${HDF5_INCLUDE_DIRS}
- ${OPENEXR_INCLUDE_DIRS}
-)
-
-set(SRC
- intern/abc_customdata.cc
- intern/abc_exporter.cc
- intern/abc_reader_archive.cc
- intern/abc_reader_camera.cc
- intern/abc_reader_curves.cc
- intern/abc_reader_mesh.cc
- intern/abc_reader_nurbs.cc
- intern/abc_reader_object.cc
- intern/abc_reader_points.cc
- intern/abc_reader_transform.cc
- intern/abc_util.cc
- intern/abc_writer_archive.cc
- intern/abc_writer_camera.cc
- intern/abc_writer_curves.cc
- intern/abc_writer_hair.cc
- intern/abc_writer_mball.cc
- intern/abc_writer_mesh.cc
- intern/abc_writer_nurbs.cc
- intern/abc_writer_object.cc
- intern/abc_writer_points.cc
- intern/abc_writer_transform.cc
- intern/alembic_capi.cc
-
- ABC_alembic.h
- intern/abc_customdata.h
- intern/abc_exporter.h
- intern/abc_reader_archive.h
- intern/abc_reader_camera.h
- intern/abc_reader_curves.h
- intern/abc_reader_mesh.h
- intern/abc_reader_nurbs.h
- intern/abc_reader_object.h
- intern/abc_reader_points.h
- intern/abc_reader_transform.h
- intern/abc_util.h
- intern/abc_writer_archive.h
- intern/abc_writer_camera.h
- intern/abc_writer_curves.h
- intern/abc_writer_hair.h
- intern/abc_writer_mball.h
- intern/abc_writer_mesh.h
- intern/abc_writer_nurbs.h
- intern/abc_writer_object.h
- intern/abc_writer_points.h
- intern/abc_writer_transform.h
-)
-
-set(LIB
- bf_blenkernel
- bf_blenlib
-
- ${ALEMBIC_LIBRARIES}
- ${OPENEXR_LIBRARIES}
-)
-
-if(WITH_ALEMBIC_HDF5)
- add_definitions(-DWITH_ALEMBIC_HDF5)
- list(APPEND LIB
- ${HDF5_LIBRARIES}
- )
-endif()
-
-list(APPEND LIB
- ${BOOST_LIBRARIES}
-)
-
-blender_add_lib(bf_alembic "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc
deleted file mode 100644
index c5f60ac3e29..00000000000
--- a/source/blender/alembic/intern/abc_customdata.cc
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_customdata.h"
-
-#include <Alembic/AbcGeom/All.h>
-#include <algorithm>
-#include <unordered_map>
-
-extern "C" {
-#include "DNA_customdata_types.h"
-#include "DNA_meshdata_types.h"
-
-#include "BLI_math_base.h"
-#include "BLI_utildefines.h"
-
-#include "BKE_customdata.h"
-}
-
-/* NOTE: for now only UVs and Vertex Colors are supported for streaming.
- * Although Alembic only allows for a single UV layer per {I|O}Schema, and does
- * not have a vertex color concept, there is a convention between DCCs to write
- * 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::kFacevaryingScope;
-using Alembic::AbcGeom::kVertexScope;
-
-using Alembic::Abc::C4fArraySample;
-using Alembic::Abc::UInt32ArraySample;
-using Alembic::Abc::V2fArraySample;
-
-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);
- }
- }
- }
- }
-}
-
-const char *get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data)
-{
- const int active_uvlayer = CustomData_get_active_layer(data, CD_MLOOPUV);
-
- if (active_uvlayer < 0) {
- return "";
- }
-
- void *cd_data = CustomData_get_layer_n(data, CD_MLOOPUV, active_uvlayer);
-
- get_uvs(config, sample.uvs, sample.indices, cd_data);
-
- return CustomData_get_layer_name(data, CD_MLOOPUV, active_uvlayer);
-}
-
-/* Convention to write UVs:
- * - V2fGeomParam on the arbGeomParam
- * - 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)
-{
- std::vector<uint32_t> indices;
- std::vector<Imath::V2f> uvs;
-
- get_uvs(config, uvs, indices, data);
-
- if (indices.empty() || uvs.empty()) {
- return;
- }
-
- OV2fGeomParam param(prop, name, true, kFacevaryingScope, 1);
-
- OV2fGeomParam::Sample sample(V2fArraySample(&uvs.front(), uvs.size()),
- UInt32ArraySample(&indices.front(), indices.size()),
- kFacevaryingScope);
-
- 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)
-{
- 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;
-
- buffer.reserve(config.totvert);
- indices.reserve(config.totvert);
-
- 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 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;
-
- buffer.push_back(col);
- indices.push_back(buffer.size() - 1);
- }
- }
-
- OC4fGeomParam param(prop, name, true, kFacevaryingScope, 1);
-
- OC4fGeomParam::Sample sample(C4fArraySample(&buffer.front(), buffer.size()),
- UInt32ArraySample(&indices.front(), indices.size()),
- kVertexScope);
-
- param.set(sample);
-}
-
-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);
- }
- }
-}
-
-/* ************************************************************************** */
-
-using Alembic::Abc::C3fArraySamplePtr;
-using Alembic::Abc::C4fArraySamplePtr;
-using Alembic::Abc::PropertyHeader;
-
-using Alembic::AbcGeom::IC3fGeomParam;
-using Alembic::AbcGeom::IC4fGeomParam;
-using Alembic::AbcGeom::IV2fGeomParam;
-
-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];
- }
- }
-}
-
-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;
-}
-
-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.mesh, 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,
- const PropertyHeader &prop_header,
- const CDStreamConfig &config,
- const Alembic::Abc::ISampleSelector &iss)
-{
- IV2fGeomParam uv_param(prop, prop_header.getName());
-
- if (!uv_param.isIndexed()) {
- return;
- }
-
- IV2fGeomParam::Sample sample;
- uv_param.getIndexed(sample, iss);
-
- if (uv_param.getScope() != kFacevaryingScope) {
- return;
- }
-
- void *cd_data = config.add_customdata_cb(config.mesh, prop_header.getName().c_str(), CD_MLOOPUV);
-
- read_uvs(config, cd_data, sample.getVals(), sample.getIndices());
-}
-
-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;
- }
- }
-}
diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h
deleted file mode 100644
index 6107e230627..00000000000
--- a/source/blender/alembic/intern/abc_customdata.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_CUSTOMDATA_H__
-#define __ABC_CUSTOMDATA_H__
-
-#include <Alembic/Abc/All.h>
-#include <Alembic/AbcGeom/All.h>
-
-struct CustomData;
-struct MLoop;
-struct MLoopUV;
-struct MPoly;
-struct MVert;
-struct Mesh;
-
-using Alembic::Abc::ICompoundProperty;
-using Alembic::Abc::OCompoundProperty;
-
-struct UVSample {
- 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 data such that it updates the custom data holder and its pointers properly. */
- Mesh *mesh;
- void *(*add_customdata_cb)(Mesh *mesh, 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),
- mesh(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.
- * Returns the name of the UV layer.
- *
- * For now the active layer is used, maybe needs a better way to choose this. */
-const char *get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data);
-
-void write_custom_data(const OCompoundProperty &prop,
- const CDStreamConfig &config,
- CustomData *data,
- int data_type);
-
-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__ */
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
deleted file mode 100644
index a58b0a29e5e..00000000000
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_exporter.h"
-
-#include <cmath>
-
-#include "abc_writer_archive.h"
-#include "abc_writer_camera.h"
-#include "abc_writer_curves.h"
-#include "abc_writer_hair.h"
-#include "abc_writer_mball.h"
-#include "abc_writer_mesh.h"
-#include "abc_writer_nurbs.h"
-#include "abc_writer_points.h"
-#include "abc_writer_transform.h"
-#include "abc_util.h"
-
-extern "C" {
-#include "DNA_camera_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_meta_types.h"
-#include "DNA_mesh_types.h"
-#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_fluid_types.h"
-
-#include "BLI_string.h"
-
-#ifdef WIN32
-/* needed for MSCV because of snprintf from BLI_string */
-# include "BLI_winstuff.h"
-#endif
-
-#include "BKE_anim.h"
-#include "BKE_global.h"
-#include "BKE_idprop.h"
-#include "BKE_layer.h"
-#include "BKE_main.h"
-#include "BKE_mball.h"
-#include "BKE_modifier.h"
-#include "BKE_particle.h"
-#include "BKE_scene.h"
-
-#include "DEG_depsgraph_query.h"
-}
-
-using Alembic::Abc::OBox3dProperty;
-using Alembic::Abc::TimeSamplingPtr;
-
-/* ************************************************************************** */
-
-ExportSettings::ExportSettings()
- : scene(NULL),
- view_layer(NULL),
- depsgraph(NULL),
- logger(),
- selected_only(false),
- visible_objects_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)
-{
-}
-
-static bool object_is_smoke_sim(Object *ob)
-{
- ModifierData *md = modifiers_findByType(ob, eModifierType_Fluid);
-
- if (md) {
- FluidModifierData *smd = reinterpret_cast<FluidModifierData *>(md);
- return (smd->type == MOD_FLUID_TYPE_DOMAIN && smd->domain &&
- smd->domain->type == FLUID_DOMAIN_TYPE_GAS);
- }
-
- 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;
- }
-}
-
-/**
- * Returns whether this object should be exported into the Alembic file.
- *
- * \param settings: export settings, used for options like 'selected only'.
- * \param ob: the object's base in question.
- * \param is_duplicated: Normally false; true when the object is instanced
- * into the scene by a dupli-object (e.g. part of a dupligroup).
- * 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,
- 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_objects_only && !BASE_VISIBLE(v3d, base)) {
- return false;
- }
- }
-
- Object *ob_eval = DEG_get_evaluated_object(settings->depsgraph, base->object);
- if ((ob_eval->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0) {
- /* XXX fix after 2.80: the object was not part of the depsgraph, and thus we cannot get the
- * evaluated copy to export. This will be handled more elegantly in the new
- * AbstractHierarchyIterator that Sybren is working on. This condition is temporary, and avoids
- * a BLI_assert() failure getting the evaluated mesh of this object. */
- 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)
-{
-}
-
-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;
-}
-
-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);
- }
-}
-
-Alembic::Abc::TimeSamplingPtr AbcExporter::createTimeSampling(double step)
-{
- std::vector<double> samples;
-
- if (m_settings.frame_start == m_settings.frame_end) {
- return TimeSamplingPtr(new Alembic::Abc::TimeSampling());
- }
-
- getShutterSamples(step, true, samples);
-
- /* 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);
-
- return TimeSamplingPtr(new Alembic::Abc::TimeSampling(ts, samples));
-}
-
-void AbcExporter::getFrameSet(unsigned int nr_of_samples, std::set<double> &frames)
-{
- frames.clear();
-
- std::vector<double> 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]);
- }
- }
-}
-
-void AbcExporter::operator()(short *do_update, float *progress, bool *was_canceled)
-{
- std::string abc_scene_name;
-
- if (m_bmain->name[0] != '\0') {
- char scene_file_name[FILE_MAX];
- BLI_strncpy(scene_file_name, m_bmain->name, FILE_MAX);
- abc_scene_name = scene_file_name;
- }
- else {
- abc_scene_name = "untitled";
- }
-
- m_writer = new ArchiveWriter(
- m_filename, abc_scene_name, m_settings.scene, m_settings.export_ogawa);
-
- /* Create time samplings for transforms and shapes. */
-
- TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_samples_xform);
-
- m_trans_sampling_index = m_writer->archive().addTimeSampling(*trans_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);
- }
-
- OBox3dProperty archive_bounds_prop = Alembic::AbcGeom::CreateOArchiveBounds(
- m_writer->archive(), m_trans_sampling_index);
-
- createTransformWritersHierarchy();
- createShapeWriters();
-
- /* Make a list of frames to export. */
-
- 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);
-
- /* Merge all frames needed. */
- std::set<double> frames(xform_frames);
- frames.insert(shape_frames.begin(), shape_frames.end());
-
- /* Export all frames. */
-
- 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;
-
- for (; begin != end; ++begin) {
- *progress = (++i / size);
- *do_update = 1;
-
- if (G.is_break) {
- *was_canceled = true;
- break;
- }
-
- const double frame = *begin;
-
- /* '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 (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();
- }
-
- /* 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);
- }
-
- 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);
- }
- }
- }
-}
-
-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);
- }
-}
-
-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;
-}
-
-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);
- }
-}
-
-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);
- }
-}
-
-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 || psys->part->type == PART_FLUID_FLIP ||
- psys->part->type == PART_FLUID_SPRAY || psys->part->type == PART_FLUID_BUBBLE ||
- psys->part->type == PART_FLUID_FOAM || psys->part->type == PART_FLUID_TRACER ||
- psys->part->type == PART_FLUID_SPRAYFOAM ||
- psys->part->type == PART_FLUID_SPRAYBUBBLE ||
- psys->part->type == PART_FLUID_FOAMBUBBLE ||
- psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE)) {
- 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;
- }
- }
-}
-
-AbcTransformWriter *AbcExporter::getXForm(const std::string &name)
-{
- std::map<std::string, AbcTransformWriter *>::iterator it = m_xforms.find(name);
-
- if (it == m_xforms.end()) {
- return NULL;
- }
-
- 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);
-}
diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h
deleted file mode 100644
index 398004d2ec5..00000000000
--- a/source/blender/alembic/intern/abc_exporter.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_EXPORTER_H__
-#define __ABC_EXPORTER_H__
-
-#include <Alembic/Abc/All.h>
-#include <map>
-#include <set>
-#include <vector>
-
-#include "abc_util.h"
-
-class AbcObjectWriter;
-class AbcTransformWriter;
-class ArchiveWriter;
-
-struct Base;
-struct Depsgraph;
-struct Main;
-struct Object;
-struct Scene;
-struct ViewLayer;
-
-struct ExportSettings {
- ExportSettings();
-
- Scene *scene;
- /** Scene layer to export; all its objects will be exported, unless selected_only=true. */
- ViewLayer *view_layer;
- Depsgraph *depsgraph;
- SimpleLogger logger;
-
- bool selected_only;
- bool visible_objects_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;
-};
-
-class AbcExporter {
- Main *m_bmain;
- ExportSettings &m_settings;
-
- const char *m_filename;
-
- unsigned int m_trans_sampling_index, m_shape_sampling_index;
-
- ArchiveWriter *m_writer;
-
- /* 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;
-
- public:
- AbcExporter(Main *bmain, const char *filename, ExportSettings &settings);
- ~AbcExporter();
-
- void operator()(short *do_update, 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);
-
- 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);
-
- AbcTransformWriter *getXForm(const std::string &name);
-
- void setCurrentFrame(Main *bmain, double t);
-};
-
-#endif /* __ABC_EXPORTER_H__ */
diff --git a/source/blender/alembic/intern/abc_reader_archive.cc b/source/blender/alembic/intern/abc_reader_archive.cc
deleted file mode 100644
index 6ad44553701..00000000000
--- a/source/blender/alembic/intern/abc_reader_archive.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_reader_archive.h"
-
-extern "C" {
-#include "BKE_main.h"
-
-#include "BLI_path_util.h"
-#include "BLI_string.h"
-}
-
-#ifdef WIN32
-# include "utfconv.h"
-#endif
-
-#include <fstream>
-
-using Alembic::Abc::ErrorHandler;
-using Alembic::Abc::Exception;
-using Alembic::Abc::IArchive;
-using Alembic::Abc::kWrapExisting;
-
-static IArchive open_archive(const std::string &filename,
- const std::vector<std::istream *> &input_streams,
- bool &is_hdf5)
-{
- is_hdf5 = false;
-
- 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';
-
-#ifdef WITH_ALEMBIC_HDF5
- try {
- is_hdf5 = true;
- Alembic::AbcCoreAbstract::ReadArraySampleCachePtr cache_ptr;
-
- return IArchive(Alembic::AbcCoreHDF5::ReadArchive(),
- filename.c_str(),
- ErrorHandler::kThrowPolicy,
- cache_ptr);
- }
- catch (const Exception &) {
- std::cerr << e.what() << '\n';
- return IArchive();
- }
-#else
- /* 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();
-}
-
-ArchiveReader::ArchiveReader(struct Main *bmain, const char *filename)
-{
- char abs_filename[FILE_MAX];
- BLI_strncpy(abs_filename, filename, FILE_MAX);
- BLI_path_abs(abs_filename, BKE_main_blendfile_path(bmain));
-
-#ifdef WIN32
- UTF16_ENCODE(abs_filename);
- std::wstring wstr(abs_filename_16);
- m_infile.open(wstr.c_str(), std::ios::in | std::ios::binary);
- UTF16_UN_ENCODE(abs_filename);
-#else
- m_infile.open(abs_filename, std::ios::in | std::ios::binary);
-#endif
-
- m_streams.push_back(&m_infile);
-
- m_archive = open_archive(abs_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();
- }
-}
-
-bool ArchiveReader::is_hdf5() const
-{
- return m_is_hdf5;
-}
-
-bool ArchiveReader::valid() const
-{
- return m_archive.valid();
-}
-
-Alembic::Abc::IObject ArchiveReader::getTop()
-{
- return m_archive.getTop();
-}
diff --git a/source/blender/alembic/intern/abc_reader_archive.h b/source/blender/alembic/intern/abc_reader_archive.h
deleted file mode 100644
index bdb53bd0b8c..00000000000
--- a/source/blender/alembic/intern/abc_reader_archive.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_READER_ARCHIVE_H__
-#define __ABC_READER_ARCHIVE_H__
-
-#include <Alembic/Abc/All.h>
-
-#ifdef WITH_ALEMBIC_HDF5
-# include <Alembic/AbcCoreHDF5/All.h>
-#endif
-
-#include <Alembic/AbcCoreOgawa/All.h>
-
-#include <fstream>
-
-struct Main;
-struct Scene;
-
-/* Wrappers around input and output archives. The goal is to be able to use
- * streams so that unicode paths work on Windows (T49112), and to make sure that
- * the stream objects remain valid as long as the archives are open.
- */
-
-class ArchiveReader {
- Alembic::Abc::IArchive m_archive;
- std::ifstream m_infile;
- std::vector<std::istream *> m_streams;
- bool m_is_hdf5;
-
- public:
- ArchiveReader(struct Main *bmain, const char *filename);
-
- 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;
-
- Alembic::Abc::IObject getTop();
-};
-
-#endif /* __ABC_READER_ARCHIVE_H__ */
diff --git a/source/blender/alembic/intern/abc_reader_camera.cc b/source/blender/alembic/intern/abc_reader_camera.cc
deleted file mode 100644
index ab506f32cbe..00000000000
--- a/source/blender/alembic/intern/abc_reader_camera.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_reader_camera.h"
-#include "abc_reader_transform.h"
-#include "abc_util.h"
-
-extern "C" {
-#include "DNA_camera_types.h"
-#include "DNA_object_types.h"
-
-#include "BKE_camera.h"
-#include "BKE_object.h"
-
-#include "BLI_math.h"
-}
-
-using Alembic::AbcGeom::CameraSample;
-using Alembic::AbcGeom::ICamera;
-using Alembic::AbcGeom::ICompoundProperty;
-using Alembic::AbcGeom::IFloatProperty;
-using Alembic::AbcGeom::ISampleSelector;
-using Alembic::AbcGeom::kWrapExisting;
-
-AbcCameraReader::AbcCameraReader(const Alembic::Abc::IObject &object, ImportSettings &settings)
- : AbcObjectReader(object, settings)
-{
- 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);
-}
-
-bool AbcCameraReader::valid() const
-{
- return m_schema.valid();
-}
-
-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;
-}
-
-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->dof.focus_distance = static_cast<float>(cam_sample.getFocusDistance());
- bcam->dof.aperture_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_reader_camera.h b/source/blender/alembic/intern/abc_reader_camera.h
deleted file mode 100644
index 1d9763b0454..00000000000
--- a/source/blender/alembic/intern/abc_reader_camera.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_READER_CAMERA_H__
-#define __ABC_READER_CAMERA_H__
-
-#include "abc_reader_object.h"
-
-class AbcCameraReader : public AbcObjectReader {
- Alembic::AbcGeom::ICameraSchema m_schema;
-
- 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;
-
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
-};
-
-#endif /* __ABC_READER_CAMERA_H__ */
diff --git a/source/blender/alembic/intern/abc_reader_curves.cc b/source/blender/alembic/intern/abc_reader_curves.cc
deleted file mode 100644
index 1be164c7c94..00000000000
--- a/source/blender/alembic/intern/abc_reader_curves.cc
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_reader_curves.h"
-#include "abc_reader_transform.h"
-#include "abc_util.h"
-
-#include <cstdio>
-
-#include "MEM_guardedalloc.h"
-
-extern "C" {
-#include "DNA_curve_types.h"
-#include "DNA_object_types.h"
-
-#include "BLI_listbase.h"
-
-#include "BKE_curve.h"
-#include "BKE_mesh.h"
-#include "BKE_object.h"
-}
-
-using Alembic::Abc::FloatArraySamplePtr;
-using Alembic::Abc::Int32ArraySamplePtr;
-using Alembic::Abc::P3fArraySamplePtr;
-using Alembic::Abc::PropertyHeader;
-using Alembic::Abc::UcharArraySamplePtr;
-
-using Alembic::AbcGeom::CurvePeriodicity;
-using Alembic::AbcGeom::ICompoundProperty;
-using Alembic::AbcGeom::ICurves;
-using Alembic::AbcGeom::ICurvesSchema;
-using Alembic::AbcGeom::IFloatGeomParam;
-using Alembic::AbcGeom::IInt16Property;
-using Alembic::AbcGeom::ISampleSelector;
-using Alembic::AbcGeom::kWrapExisting;
-
-AbcCurveReader::AbcCurveReader(const Alembic::Abc::IObject &object, ImportSettings &settings)
- : AbcObjectReader(object, settings)
-{
- 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);
-}
-
-bool AbcCurveReader::valid() const
-{
- 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
-{
- 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);
-
- 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);
- }
- }
-
- 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);
-
- if (has_animations(m_curves_schema, m_settings)) {
- addCacheModifier();
- }
-}
-
-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);
- }
-}
-
-/* NOTE: Alembic only stores data about control points, but the Mesh
- * passed from the cache modifier contains the displist, which has more data
- * than the control points, so to avoid corrupting the displist we modify the
- * object directly and create a new Mesh from that. Also we might need to
- * create new or delete existing NURBS in the curve.
- */
-Mesh *AbcCurveReader::read_mesh(Mesh *existing_mesh,
- const ISampleSelector &sample_sel,
- 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);
-}
diff --git a/source/blender/alembic/intern/abc_reader_curves.h b/source/blender/alembic/intern/abc_reader_curves.h
deleted file mode 100644
index 1e4f28edc51..00000000000
--- a/source/blender/alembic/intern/abc_reader_curves.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_READER_CURVES_H__
-#define __ABC_READER_CURVES_H__
-
-#include "abc_reader_object.h"
-#include "abc_reader_mesh.h"
-
-struct Curve;
-
-#define ABC_CURVE_RESOLUTION_U_PROPNAME "blender:resolution"
-
-class AbcCurveReader : public AbcObjectReader {
- Alembic::AbcGeom::ICurvesSchema m_curves_schema;
-
- 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;
-
- 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_READER_CURVES_H__ */
diff --git a/source/blender/alembic/intern/abc_reader_mesh.cc b/source/blender/alembic/intern/abc_reader_mesh.cc
deleted file mode 100644
index a4e412695c3..00000000000
--- a/source/blender/alembic/intern/abc_reader_mesh.cc
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_reader_mesh.h"
-#include "abc_reader_transform.h"
-#include "abc_util.h"
-
-#include <algorithm>
-
-#include "MEM_guardedalloc.h"
-
-extern "C" {
-#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_object_types.h"
-
-#include "BLI_math_geom.h"
-
-#include "BKE_main.h"
-#include "BKE_material.h"
-#include "BKE_mesh.h"
-#include "BKE_modifier.h"
-#include "BKE_object.h"
-}
-
-using Alembic::Abc::Int32ArraySamplePtr;
-using Alembic::Abc::P3fArraySamplePtr;
-
-using Alembic::AbcGeom::IFaceSet;
-using Alembic::AbcGeom::IFaceSetSchema;
-using Alembic::AbcGeom::IN3fGeomParam;
-using Alembic::AbcGeom::IObject;
-using Alembic::AbcGeom::IPolyMesh;
-using Alembic::AbcGeom::IPolyMeshSchema;
-using Alembic::AbcGeom::ISampleSelector;
-using Alembic::AbcGeom::ISubD;
-using Alembic::AbcGeom::ISubDSchema;
-using Alembic::AbcGeom::IV2fGeomParam;
-using Alembic::AbcGeom::kWrapExisting;
-using Alembic::AbcGeom::N3fArraySample;
-using Alembic::AbcGeom::N3fArraySamplePtr;
-using Alembic::AbcGeom::UInt32ArraySamplePtr;
-using Alembic::AbcGeom::V2fArraySamplePtr;
-
-/* NOTE: Alembic's polygon winding order is clockwise, to match with Renderman. */
-
-/* Some helpers for mesh generation */
-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);
-
- 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)
-{
- 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;
- }
-
- BKE_object_material_assign(bmain, ob, assigned_mat, it->second, BKE_MAT_ASSIGN_OBDATA);
- }
- }
-}
-
-} /* namespace utils */
-
-struct AbcMeshData {
- Int32ArraySamplePtr face_indices;
- Int32ArraySamplePtr face_counts;
-
- P3fArraySamplePtr positions;
- P3fArraySamplePtr ceil_positions;
-
- V2fArraySamplePtr uvs;
- UInt32ArraySamplePtr uvs_indices;
-};
-
-static void read_mverts_interp(MVert *mverts,
- const P3fArraySamplePtr &positions,
- const P3fArraySamplePtr &ceil_positions,
- const float weight)
-{
- float tmp[3];
- for (int i = 0; i < positions->size(); i++) {
- MVert &mvert = mverts[i];
- const Imath::V3f &floor_pos = (*positions)[i];
- const Imath::V3f &ceil_pos = (*ceil_positions)[i];
-
- interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), weight);
- copy_zup_from_yup(mvert.co, tmp);
-
- mvert.bweight = 0;
- }
-}
-
-static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data)
-{
- MVert *mverts = config.mvert;
- const P3fArraySamplePtr &positions = mesh_data.positions;
-
- 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, nullptr);
-}
-
-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];
-
- copy_zup_from_yup(mvert.co, pos_in.getValue());
-
- mvert.bweight = 0;
-
- if (normals) {
- Imath::V3f nor_in = (*normals)[i];
-
- short no[3];
- normal_float_to_short_v3(no, nor_in.getValue());
-
- 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 size_t uvs_size = uvs == nullptr ? 0 : uvs->size();
-
- const UInt32ArraySamplePtr &uvs_indices = mesh_data.uvs_indices;
-
- 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;
-
- /* Polygons are always assumed to be smooth-shaded. If the Alembic mesh should be flat-shaded,
- * this is encoded in custom loop normals. See T71246. */
- 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];
-
- /* Some Alembic files are broken (or at least export UVs in a way we don't expect). */
- if (uv_index >= uvs_size) {
- continue;
- }
-
- loopuv.uv[0] = (*uvs)[uv_index][0];
- loopuv.uv[1] = (*uvs)[uv_index][1];
- }
- }
- }
-
- BKE_mesh_calc_edges(config.mesh, false, false);
-}
-
-static void process_no_normals(CDStreamConfig &config)
-{
- /* Absense of normals in the Alembic mesh is interpreted as 'smooth'. */
- BKE_mesh_calc_normals(config.mesh);
-}
-
-static void process_loop_normals(CDStreamConfig &config, const N3fArraySamplePtr loop_normals_ptr)
-{
- size_t loop_count = loop_normals_ptr->size();
-
- if (loop_count == 0) {
- process_no_normals(config);
- return;
- }
-
- float(*lnors)[3] = static_cast<float(*)[3]>(
- MEM_malloc_arrayN(loop_count, sizeof(float[3]), "ABC::FaceNormals"));
-
- Mesh *mesh = config.mesh;
- MPoly *mpoly = mesh->mpoly;
- const N3fArraySample &loop_normals = *loop_normals_ptr;
- int abc_index = 0;
- for (int i = 0, e = mesh->totpoly; i < e; i++, mpoly++) {
- /* As usual, ABC orders the loops in reverse. */
- for (int j = mpoly->totloop - 1; j >= 0; j--, abc_index++) {
- int blender_index = mpoly->loopstart + j;
- copy_zup_from_yup(lnors[blender_index], loop_normals[abc_index].getValue());
- }
- }
-
- mesh->flag |= ME_AUTOSMOOTH;
- BKE_mesh_set_custom_normals(mesh, lnors);
-
- MEM_freeN(lnors);
-}
-
-static void process_vertex_normals(CDStreamConfig &config,
- const N3fArraySamplePtr vertex_normals_ptr)
-{
- size_t normals_count = vertex_normals_ptr->size();
- if (normals_count == 0) {
- process_no_normals(config);
- return;
- }
-
- float(*vnors)[3] = static_cast<float(*)[3]>(
- MEM_malloc_arrayN(normals_count, sizeof(float[3]), "ABC::VertexNormals"));
-
- const N3fArraySample &vertex_normals = *vertex_normals_ptr;
- for (int index = 0; index < normals_count; index++) {
- copy_zup_from_yup(vnors[index], vertex_normals[index].getValue());
- }
-
- config.mesh->flag |= ME_AUTOSMOOTH;
- BKE_mesh_set_custom_normals_from_vertices(config.mesh, vnors);
- MEM_freeN(vnors);
-}
-
-static void process_normals(CDStreamConfig &config,
- const IN3fGeomParam &normals,
- const ISampleSelector &selector)
-{
- if (!normals.valid()) {
- process_no_normals(config);
- return;
- }
-
- IN3fGeomParam::Sample normsamp = normals.getExpandedValue(selector);
- Alembic::AbcGeom::GeometryScope scope = normals.getScope();
-
- switch (scope) {
- case Alembic::AbcGeom::kFacevaryingScope: // 'Vertex Normals' in Houdini.
- process_loop_normals(config, normsamp.getVals());
- break;
- case Alembic::AbcGeom::kVertexScope:
- case Alembic::AbcGeom::kVaryingScope: // 'Point Normals' in Houdini.
- process_vertex_normals(config, normsamp.getVals());
- break;
- case Alembic::AbcGeom::kConstantScope:
- case Alembic::AbcGeom::kUniformScope:
- case Alembic::AbcGeom::kUnknownScope:
- process_no_normals(config);
- break;
- }
-}
-
-ABC_INLINE void read_uvs_params(CDStreamConfig &config,
- AbcMeshData &abc_data,
- const IV2fGeomParam &uv,
- const ISampleSelector &selector)
-{
- if (!uv.valid()) {
- return;
- }
-
- IV2fGeomParam::Sample uvsamp;
- uv.getIndexed(uvsamp, selector);
-
- 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());
-
- /* 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.mesh, name.c_str(), CD_MLOOPUV);
- config.mloopuv = static_cast<MLoopUV *>(cd_ptr);
- }
-}
-
-static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type)
-{
- 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. */
- 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;
-
- config.weight = get_weight_and_index(config.time, time_sampling, samples_number, i0, i1);
-
- config.index = i0;
- config.ceil_index = i1;
-}
-
-static void read_mesh_sample(const std::string &iobject_full_name,
- ImportSettings *settings,
- const IPolyMeshSchema &schema,
- const ISampleSelector &selector,
- CDStreamConfig &config)
-{
- 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();
-
- 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 ((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);
- process_normals(config, schema.getNormalsParam(), 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;
-
- BLI_assert(mesh->mvert || mesh->totvert == 0);
-
- config.mesh = 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;
-}
-
-/* ************************************************************************** */
-
-AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings)
- : AbcObjectReader(object, settings)
-{
- m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
-
- 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);
-}
-
-bool AbcMeshReader::valid() const
-{
- 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());
-
- 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) {
- /* XXX fixme after 2.80; mesh->flag isn't copied by BKE_mesh_nomain_to_mesh() */
- /* read_mesh can be freed by BKE_mesh_nomain_to_mesh(), so get the flag before that happens. */
- short autosmooth = (read_mesh->flag & ME_AUTOSMOOTH);
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_MESH, true);
- mesh->flag |= autosmooth;
- }
-
- if (m_settings->validate_meshes) {
- BKE_mesh_validate(mesh, false, false);
- }
-
- readFaceSetsSample(bmain, mesh, sample_sel);
-
- 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
-{
- 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;
-}
-
-bool AbcMeshReader::topology_changed(Mesh *existing_mesh, const ISampleSelector &sample_sel)
-{
- IPolyMeshSchema::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());
- // A similar error in read_mesh() would just return existing_mesh.
- return false;
- }
-
- const P3fArraySamplePtr &positions = sample.getPositions();
- const Alembic::Abc::Int32ArraySamplePtr &face_indices = sample.getFaceIndices();
- const Alembic::Abc::Int32ArraySamplePtr &face_counts = sample.getFaceCounts();
-
- return positions->size() != existing_mesh->totvert ||
- face_counts->size() != existing_mesh->totpoly ||
- face_indices->size() != existing_mesh->totloop;
-}
-
-Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
- const ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str)
-{
- IPolyMeshSchema::Sample sample;
- try {
- sample = m_schema.getValue(sample_sel);
- }
- catch (Alembic::Util::Exception &ex) {
- if (err_str != nullptr) {
- *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;
-
- if (topology_changed(existing_mesh, sample_sel)) {
- 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();
-
- read_mesh_sample(m_iobject.getFullName(), &settings, m_schema, sample_sel, config);
-
- if (new_mesh) {
- /* 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, new_mesh->mpoly, num_polys, mat_map);
- }
-
- return new_mesh;
- }
-
- return existing_mesh;
-}
-
-void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
- 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;
- }
-
- int current_mat = 0;
-
- for (int i = 0; i < face_sets.size(); i++) {
- const std::string &grp_name = face_sets[i];
-
- if (r_mat_map.find(grp_name) == r_mat_map.end()) {
- r_mat_map[grp_name] = 1 + current_mat++;
- }
-
- const int assigned_mat = r_mat_map[grp_name];
-
- const IFaceSet faceset = m_schema.getFaceSet(grp_name);
-
- if (!faceset.valid()) {
- std::cerr << " Face set " << grp_name << " invalid for " << m_object_name << "\n";
- continue;
- }
-
- 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();
-
- for (size_t l = 0; l < num_group_faces; l++) {
- size_t pos = (*group_faces)[l];
-
- 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, const ISampleSelector &sample_sel)
-{
- std::map<std::string, int> mat_map;
- assign_facesets_to_mpoly(sample_sel, 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];
-
- if (edge.v1 == v1 && edge.v2 == v2) {
- return &edge;
- }
- }
-
- return NULL;
-}
-
-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.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) {
- /* Alembic's 'SubD' scheme is used to store subdivision surfaces, i.e. the pre-subdivision
- * mesh. Currently we don't add a subdivision modifier when we load such data. This code is
- * assuming that the subdivided surface should be smooth. */
- read_mpolys(config, abc_mesh_data);
- process_no_normals(config);
- }
-
- if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
- read_custom_data(iobject_full_name, schema.getArbGeomParams(), config, selector);
- }
-}
-
-/* ************************************************************************** */
-
-AbcSubDReader::AbcSubDReader(const IObject &object, ImportSettings &settings)
- : AbcObjectReader(object, settings)
-{
- m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
-
- 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);
-}
-
-bool AbcSubDReader::valid() const
-{
- return m_schema.valid();
-}
-
-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;
-}
-
-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();
-
- if (indices && sharpnesses) {
- MEdge *edges = mesh->medge;
- int totedge = mesh->totedge;
-
- for (int i = 0, s = 0, e = indices->size(); i < e; i += 2, s++) {
- int v1 = (*indices)[i];
- int v2 = (*indices)[i + 1];
-
- if (v2 < v1) {
- /* It appears to be common to store edges with the smallest index first, in which case this
- * prevents us from doing the second search below. */
- std::swap(v1, v2);
- }
-
- MEdge *edge = find_edge(edges, totedge, v1, v2);
- if (edge == NULL) {
- edge = find_edge(edges, totedge, v2, v1);
- }
-
- if (edge) {
- edge->crease = unit_float_to_uchar_clamp((*sharpnesses)[s]);
- }
- }
-
- mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
- }
-
- 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,
- const ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str)
-{
- ISubDSchema::Sample sample;
- try {
- sample = m_schema.getValue(sample_sel);
- }
- catch (Alembic::Util::Exception &ex) {
- if (err_str != nullptr) {
- *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->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!";
- }
- }
- }
-
- /* 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);
-
- return config.mesh;
-}
diff --git a/source/blender/alembic/intern/abc_reader_mesh.h b/source/blender/alembic/intern/abc_reader_mesh.h
deleted file mode 100644
index bc95c7ec134..00000000000
--- a/source/blender/alembic/intern/abc_reader_mesh.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_READER_MESH_H__
-#define __ABC_READER_MESH_H__
-
-#include "abc_customdata.h"
-#include "abc_reader_object.h"
-
-struct Mesh;
-
-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 override;
- bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
- const Object *const ob,
- const char **err_str) const override;
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) override;
-
- struct Mesh *read_mesh(struct Mesh *existing_mesh,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str) override;
- bool topology_changed(Mesh *existing_mesh,
- const Alembic::Abc::ISampleSelector &sample_sel) override;
-
- private:
- void readFaceSetsSample(Main *bmain,
- Mesh *mesh,
- const Alembic::AbcGeom::ISampleSelector &sample_sel);
-
- void assign_facesets_to_mpoly(const Alembic::Abc::ISampleSelector &sample_sel,
- 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);
-};
-
-void read_mverts(MVert *mverts,
- const Alembic::AbcGeom::P3fArraySamplePtr positions,
- const Alembic::AbcGeom::N3fArraySamplePtr normals);
-
-CDStreamConfig get_config(struct Mesh *mesh);
-
-#endif /* __ABC_READER_MESH_H__ */
diff --git a/source/blender/alembic/intern/abc_reader_nurbs.cc b/source/blender/alembic/intern/abc_reader_nurbs.cc
deleted file mode 100644
index 0ada10baba5..00000000000
--- a/source/blender/alembic/intern/abc_reader_nurbs.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_reader_nurbs.h"
-#include "abc_reader_transform.h"
-#include "abc_util.h"
-
-#include "MEM_guardedalloc.h"
-
-extern "C" {
-#include "DNA_curve_types.h"
-#include "DNA_object_types.h"
-
-#include "BLI_listbase.h"
-#include "BLI_string.h"
-
-#include "BKE_curve.h"
-#include "BKE_object.h"
-}
-
-using Alembic::AbcGeom::FloatArraySamplePtr;
-using Alembic::AbcGeom::kWrapExisting;
-using Alembic::AbcGeom::MetaData;
-using Alembic::AbcGeom::P3fArraySamplePtr;
-
-using Alembic::AbcGeom::ICompoundProperty;
-using Alembic::AbcGeom::INuPatch;
-using Alembic::AbcGeom::INuPatchSchema;
-using Alembic::AbcGeom::IObject;
-
-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);
-}
-
-bool AbcNurbsReader::valid() const
-{
- 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;
-
- if (!schema.valid()) {
- return false;
- }
- }
-
- return true;
-}
-
-static bool set_knots(const FloatArraySamplePtr &knots, float *&nu_knots)
-{
- 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"));
-
- for (size_t i = 0; i < num_knots; i++) {
- nu_knots[i] = (*knots)[i + 1];
- }
-
- 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;
-
- 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();
-
- /* Read positions and weights. */
-
- const P3fArraySamplePtr positions = smp.getPositions();
- const FloatArraySamplePtr weights = smp.getPositionWeights();
-
- const size_t num_points = positions->size();
-
- nu->bp = static_cast<BPoint *>(MEM_callocN(num_points * sizeof(BPoint), "abc_setsplinetype"));
-
- 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];
-
- 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;
- }
-
- /* Read knots. */
-
- 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);
- }
-
- /* Read flags. */
-
- ICompoundProperty user_props = schema.getUserProperties();
-
- 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, "cyclic_u")) {
- nu->flagu |= CU_NURB_CYCLIC;
- }
-
- if (has_property(user_props, "cyclic_v")) {
- nu->flagv |= CU_NURB_CYCLIC;
- }
-
- BLI_addtail(BKE_curve_nurbs_get(cu), nu);
- }
-
- 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;
-}
-
-void AbcNurbsReader::getNurbsPatches(const IObject &obj)
-{
- if (!obj.valid()) {
- return;
- }
-
- 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;
- }
-
- 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 (!child.valid()) {
- continue;
- }
-
- 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));
- }
-
- getNurbsPatches(child);
- }
-}
diff --git a/source/blender/alembic/intern/abc_reader_nurbs.h b/source/blender/alembic/intern/abc_reader_nurbs.h
deleted file mode 100644
index f4284c136fb..00000000000
--- a/source/blender/alembic/intern/abc_reader_nurbs.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_READER_NURBS_H__
-#define __ABC_READER_NURBS_H__
-
-#include "abc_reader_object.h"
-
-class AbcNurbsReader : public AbcObjectReader {
- std::vector<std::pair<Alembic::AbcGeom::INuPatchSchema, Alembic::Abc::IObject>> m_schemas;
-
- public:
- AbcNurbsReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
-
- bool valid() const;
-
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
-
- private:
- void getNurbsPatches(const Alembic::Abc::IObject &obj);
-};
-
-#endif /* __ABC_READER_NURBS_H__ */
diff --git a/source/blender/alembic/intern/abc_reader_object.cc b/source/blender/alembic/intern/abc_reader_object.cc
deleted file mode 100644
index 3e7f87d78cc..00000000000
--- a/source/blender/alembic/intern/abc_reader_object.cc
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_reader_object.h"
-#include "abc_util.h"
-
-extern "C" {
-#include "DNA_cachefile_types.h"
-#include "DNA_constraint_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_space_types.h" /* for FILE_MAX */
-
-#include "BKE_constraint.h"
-#include "BKE_lib_id.h"
-#include "BKE_modifier.h"
-#include "BKE_object.h"
-
-#include "BLI_utildefines.h"
-#include "BLI_listbase.h"
-#include "BLI_math_geom.h"
-#include "BLI_string.h"
-}
-
-using Alembic::AbcGeom::IObject;
-using Alembic::AbcGeom::IXform;
-using Alembic::AbcGeom::IXformSchema;
-
-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 = 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;
- }
-}
-
-AbcObjectReader::~AbcObjectReader()
-{
-}
-
-const IObject &AbcObjectReader::iobject() const
-{
- return m_iobject;
-}
-
-Object *AbcObjectReader::object() const
-{
- return m_object;
-}
-
-void AbcObjectReader::object(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];
-
- /* 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++) {
- mat1[i][j] = static_cast<float>(m1[i][j]);
- }
- }
-
- interp_m4_m4m4(ret, mat0, mat1, weight);
-
- Imath::M44d m;
-
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- m[i][j] = ret[i][j];
- }
- }
-
- return m;
-}
-
-Imath::M44d get_matrix(const IXformSchema &schema, const float time)
-{
- 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);
-
- 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);
- }
-
- return s0.getMatrix();
-}
-
-struct Mesh *AbcObjectReader::read_mesh(struct Mesh *existing_mesh,
- const Alembic::Abc::ISampleSelector &UNUSED(sample_sel),
- int UNUSED(read_flag),
- const char **UNUSED(err_str))
-{
- return existing_mesh;
-}
-
-bool AbcObjectReader::topology_changed(Mesh * /*existing_mesh*/,
- const Alembic::Abc::ISampleSelector & /*sample_sel*/)
-{
- /* The default implementation of read_mesh() just returns the original mesh, so never changes the
- * topology. */
- return false;
-}
-
-void AbcObjectReader::setupObjectTransform(const float time)
-{
- bool is_constant = false;
- float transform_from_alembic[4][4];
-
- /* If the parent is a camera, apply the inverse rotation to make up for the from-Maya rotation.
- * This assumes that the parent object also was imported from Alembic. */
- if (m_object->parent != nullptr && m_object->parent->type == OB_CAMERA) {
- axis_angle_to_mat4_single(m_object->parentinv, 'X', -M_PI_2);
- }
-
- this->read_matrix(transform_from_alembic, time, m_settings->scale, is_constant);
-
- /* Apply the matrix to the object. */
- BKE_object_apply_mat4(m_object, transform_from_alembic, true, false);
- BKE_object_to_mat4(m_object, m_object->obmat);
-
- 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);
- }
-}
-
-Alembic::AbcGeom::IXform AbcObjectReader::xform()
-{
- /* Check that we have an empty object (locator, bone head/tail...). */
- if (IXform::matches(m_iobject.getMetaData())) {
- try {
- return IXform(m_iobject, Alembic::AbcGeom::kWrapExisting);
- }
- catch (Alembic::Util::Exception &ex) {
- printf("Alembic: error reading object transform for '%s': %s\n",
- m_iobject.getFullName().c_str(),
- ex.what());
- return IXform();
- }
- }
-
- /* 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())) {
- try {
- return IXform(abc_parent, Alembic::AbcGeom::kWrapExisting);
- }
- catch (Alembic::Util::Exception &ex) {
- printf("Alembic: error reading object transform for '%s': %s\n",
- abc_parent.getFullName().c_str(),
- ex.what());
- return IXform();
- }
- }
-
- /* 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] /* local matrix */,
- 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_datatype(matrix, r_mat);
- copy_m44_axis_swap(r_mat, r_mat, ABC_ZUP_FROM_YUP);
-
- /* Convert from Maya to Blender camera orientation. Children of this camera
- * will have the opposite transform as their Parent Inverse matrix.
- * See AbcObjectReader::setupObjectTransform(). */
- if (m_object->type == OB_CAMERA) {
- float camera_rotation[4][4];
- axis_angle_to_mat4_single(camera_rotation, 'X', M_PI_2);
- mul_m4_m4m4(r_mat, r_mat, camera_rotation);
- }
-
- if (!m_inherits_xform) {
- /* Only apply scaling to root objects, parenting will propagate it. */
- float scale_mat[4][4];
- scale_m4_fl(scale_mat, scale);
- mul_m4_m4m4(r_mat, scale_mat, r_mat);
- }
-
- is_constant = schema.isConstant();
-}
-
-void AbcObjectReader::addCacheModifier()
-{
- ModifierData *md = modifier_new(eModifierType_MeshSequenceCache);
- BLI_addtail(&m_object->modifiers, md);
-
- MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md);
-
- 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);
-}
-
-chrono_t AbcObjectReader::minTime() const
-{
- return m_min_time;
-}
-
-chrono_t AbcObjectReader::maxTime() const
-{
- return m_max_time;
-}
-
-int AbcObjectReader::refcount() const
-{
- return m_refcount;
-}
-
-void AbcObjectReader::incref()
-{
- m_refcount++;
-}
-
-void AbcObjectReader::decref()
-{
- m_refcount--;
- BLI_assert(m_refcount >= 0);
-}
diff --git a/source/blender/alembic/intern/abc_reader_object.h b/source/blender/alembic/intern/abc_reader_object.h
deleted file mode 100644
index 94923df2df9..00000000000
--- a/source/blender/alembic/intern/abc_reader_object.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_READER_OBJECT_H__
-#define __ABC_READER_OBJECT_H__
-
-#include <Alembic/Abc/All.h>
-#include <Alembic/AbcGeom/All.h>
-
-extern "C" {
-#include "DNA_ID.h"
-}
-
-struct CacheFile;
-struct Main;
-struct Mesh;
-struct Object;
-
-using Alembic::AbcCoreAbstract::chrono_t;
-
-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)
- {
- }
-};
-
-template<typename Schema> static bool has_animations(Schema &schema, ImportSettings *settings)
-{
- return settings->is_sequence || !schema.isConstant();
-}
-
-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;
-
- ImportSettings *m_settings;
-
- 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;
-
- bool m_inherits_xform;
-
- public:
- AbcObjectReader *parent_reader;
-
- public:
- explicit AbcObjectReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
-
- virtual ~AbcObjectReader();
-
- const Alembic::Abc::IObject &iobject() const;
-
- 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();
-
- 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;
- }
-
- 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 struct Mesh *read_mesh(struct Mesh *mesh,
- const Alembic::Abc::ISampleSelector &sample_sel,
- int read_flag,
- const char **err_str);
- virtual bool topology_changed(Mesh *existing_mesh,
- const Alembic::Abc::ISampleSelector &sample_sel);
-
- /** Reads the object matrix and sets up an object transform if animated. */
- void setupObjectTransform(const float time);
-
- void addCacheModifier();
-
- chrono_t minTime() const;
- chrono_t maxTime() const;
-
- int refcount() const;
- void incref();
- void decref();
-
- void read_matrix(float r_mat[4][4], const float time, const float scale, bool &is_constant);
-
- protected:
- void determine_inherits_xform();
-};
-
-Imath::M44d get_matrix(const Alembic::AbcGeom::IXformSchema &schema, const float time);
-
-#endif /* __ABC_READER_OBJECT_H__ */
diff --git a/source/blender/alembic/intern/abc_reader_points.cc b/source/blender/alembic/intern/abc_reader_points.cc
deleted file mode 100644
index e4dc345f868..00000000000
--- a/source/blender/alembic/intern/abc_reader_points.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_reader_points.h"
-#include "abc_reader_mesh.h"
-#include "abc_reader_transform.h"
-#include "abc_util.h"
-
-extern "C" {
-#include "DNA_mesh_types.h"
-#include "DNA_object_types.h"
-
-#include "BKE_customdata.h"
-#include "BKE_mesh.h"
-#include "BKE_object.h"
-}
-
-using Alembic::AbcGeom::kWrapExisting;
-using Alembic::AbcGeom::N3fArraySamplePtr;
-using Alembic::AbcGeom::P3fArraySamplePtr;
-
-using Alembic::AbcGeom::ICompoundProperty;
-using Alembic::AbcGeom::IN3fArrayProperty;
-using Alembic::AbcGeom::IPoints;
-using Alembic::AbcGeom::IPointsSchema;
-using Alembic::AbcGeom::ISampleSelector;
-
-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);
-}
-
-bool AbcPointsReader::valid() const
-{
- return m_schema.valid();
-}
-
-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;
-}
-
-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);
-
- 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);
- }
-
- 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();
- }
-}
-
-void read_points_sample(const IPointsSchema &schema,
- const ISampleSelector &selector,
- CDStreamConfig &config)
-{
- Alembic::AbcGeom::IPointsSchema::Sample sample = schema.getValue(selector);
-
- const P3fArraySamplePtr &positions = sample.getPositions();
-
- 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 (normals_prop) {
- vnormals = normals_prop.getValue(selector);
- }
- }
-
- read_mverts(config.mvert, positions, vnormals);
-}
-
-struct Mesh *AbcPointsReader::read_mesh(struct Mesh *existing_mesh,
- const ISampleSelector &sample_sel,
- 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;
-}
diff --git a/source/blender/alembic/intern/abc_reader_points.h b/source/blender/alembic/intern/abc_reader_points.h
deleted file mode 100644
index 31ad6c4589b..00000000000
--- a/source/blender/alembic/intern/abc_reader_points.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_READER_POINTS_H__
-#define __ABC_READER_POINTS_H__
-
-#include "abc_reader_object.h"
-#include "abc_customdata.h"
-
-class AbcPointsReader : public AbcObjectReader {
- Alembic::AbcGeom::IPointsSchema m_schema;
- Alembic::AbcGeom::IPointsSchema::Sample m_sample;
-
- 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;
-
- 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_points_sample(const Alembic::AbcGeom::IPointsSchema &schema,
- const Alembic::AbcGeom::ISampleSelector &selector,
- CDStreamConfig &config);
-
-#endif /* __ABC_READER_POINTS_H__ */
diff --git a/source/blender/alembic/intern/abc_reader_transform.cc b/source/blender/alembic/intern/abc_reader_transform.cc
deleted file mode 100644
index ce569a9ccb5..00000000000
--- a/source/blender/alembic/intern/abc_reader_transform.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_reader_transform.h"
-#include "abc_util.h"
-
-extern "C" {
-#include "DNA_object_types.h"
-
-#include "BLI_utildefines.h"
-
-#include "BKE_object.h"
-}
-
-using Alembic::Abc::ISampleSelector;
-
-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();
-
- 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);
-}
-
-bool AbcEmptyReader::valid() const
-{
- return m_schema.valid();
-}
-
-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;
-}
-
-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;
-}
diff --git a/source/blender/alembic/intern/abc_reader_transform.h b/source/blender/alembic/intern/abc_reader_transform.h
deleted file mode 100644
index 6b4d23c1884..00000000000
--- a/source/blender/alembic/intern/abc_reader_transform.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_READER_TRANSFORM_H__
-#define __ABC_READER_TRANSFORM_H__
-
-#include "abc_reader_object.h"
-
-#include <Alembic/AbcGeom/All.h>
-
-class AbcEmptyReader : public AbcObjectReader {
- Alembic::AbcGeom::IXformSchema m_schema;
-
- 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;
-
- void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
-};
-
-#endif /* __ABC_READER_TRANSFORM_H__ */
diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc
deleted file mode 100644
index b26ef8b3b76..00000000000
--- a/source/blender/alembic/intern/abc_util.cc
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_util.h"
-
-#include "abc_reader_camera.h"
-#include "abc_reader_curves.h"
-#include "abc_reader_mesh.h"
-#include "abc_reader_nurbs.h"
-#include "abc_reader_points.h"
-#include "abc_reader_transform.h"
-
-#include <Alembic/AbcMaterial/IMaterial.h>
-
-#include <algorithm>
-
-extern "C" {
-#include "DNA_object_types.h"
-
-#include "BLI_math_geom.h"
-
-#include "PIL_time.h"
-}
-
-std::string get_id_name(const Object *const ob)
-{
- if (!ob) {
- return "";
- }
-
- return get_id_name(&ob->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(), ':', '_');
-
- return name;
-}
-
-/**
- * \brief get_object_dag_path_name returns the name under which the object
- * will be exported in the Alembic file. It is of the form
- * "[../grandparent/]parent/object" if dupli_parent is NULL, or
- * "dupli_parent/[../grandparent/]parent/object" otherwise.
- * \param ob:
- * \param dupli_parent:
- * \return
- */
-std::string get_object_dag_path_name(const Object *const ob, Object *dupli_parent)
-{
- std::string name = get_id_name(ob);
-
- Object *p = ob->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;
- }
-
- return name;
-}
-
-Imath::M44d convert_matrix_datatype(float mat[4][4])
-{
- Imath::M44d m;
-
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- m[i][j] = mat[i][j];
- }
- }
-
- return m;
-}
-
-void convert_matrix_datatype(const Imath::M44d &xform, 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]);
- }
- }
-}
-
-void split(const std::string &s, const char delim, std::vector<std::string> &tokens)
-{
- tokens.clear();
-
- std::stringstream ss(s);
- std::string 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)
-{
- 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);
-}
-
-/* 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,
- 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);
-}
-
-bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name)
-{
- if (!prop.valid()) {
- return false;
- }
-
- return prop.getPropertyHeader(name) != NULL;
-}
-
-typedef std::pair<Alembic::AbcCoreAbstract::index_t, float> index_time_pair_t;
-
-float get_weight_and_index(float time,
- const Alembic::AbcCoreAbstract::TimeSamplingPtr &time_sampling,
- int samples_number,
- Alembic::AbcGeom::index_t &i0,
- Alembic::AbcGeom::index_t &i1)
-{
- samples_number = std::max(samples_number, 1);
-
- 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;
- }
-
- index_time_pair_t t1 = time_sampling->getCeilIndex(time, samples_number);
- i1 = t1.first;
-
- if (i0 == i1) {
- return 0.0f;
- }
-
- const float bias = (time - t0.second) / (t1.second - t0.second);
-
- if (fabs(1.0f - bias) < 0.0001f) {
- i0 = i1;
- return 0.0f;
- }
-
- 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)) {
-#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);
-#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;
-}
-
-/* ********************** */
-
-ScopeTimer::ScopeTimer(const char *message)
- : m_message(message), m_start(PIL_check_seconds_timer())
-{
-}
-
-ScopeTimer::~ScopeTimer()
-{
- fprintf(stderr, "%s: %fs\n", m_message, PIL_check_seconds_timer() - m_start);
-}
-
-/* ********************** */
-
-std::string SimpleLogger::str() const
-{
- return m_stream.str();
-}
-
-void SimpleLogger::clear()
-{
- m_stream.clear();
- m_stream.str("");
-}
-
-std::ostringstream &SimpleLogger::stream()
-{
- return m_stream;
-}
-
-std::ostream &operator<<(std::ostream &os, const SimpleLogger &logger)
-{
- os << logger.str();
- return os;
-}
diff --git a/source/blender/alembic/intern/abc_util.h b/source/blender/alembic/intern/abc_util.h
deleted file mode 100644
index 0b3462c2132..00000000000
--- a/source/blender/alembic/intern/abc_util.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_UTIL_H__
-#define __ABC_UTIL_H__
-
-#include <Alembic/Abc/All.h>
-#include <Alembic/AbcGeom/All.h>
-
-#ifdef _MSC_VER
-# define ABC_INLINE static __forceinline
-#else
-# define ABC_INLINE static inline
-#endif
-
-/**
- * \brief The CacheReader struct is only used for anonymous pointers,
- * to interface between C and C++ code. This library only creates
- * pointers to AbcObjectReader (or subclasses thereof).
- */
-struct CacheReader {
- int unused;
-};
-
-using Alembic::Abc::chrono_t;
-
-class AbcObjectReader;
-struct ImportSettings;
-
-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);
-
-/* Convert from float to Alembic matrix representations. Does NOT convert from Z-up to Y-up. */
-Imath::M44d convert_matrix_datatype(float mat[4][4]);
-/* Convert from Alembic to float matrix representations. Does NOT convert from Y-up to Z-up. */
-void convert_matrix_datatype(const Imath::M44d &xform, float r_mat[4][4]);
-
-typedef enum {
- 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 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)
-{
- return input.size() >= match.size() && std::equal(match.begin(), match.end(), input.begin());
-}
-
-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();
-
- 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);
-
- 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)
-{
- 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);
- }
-}
-
-bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name);
-
-float get_weight_and_index(float time,
- const Alembic::AbcCoreAbstract::TimeSamplingPtr &time_sampling,
- int samples_number,
- Alembic::AbcGeom::index_t &i0,
- Alembic::AbcGeom::index_t &i1);
-
-AbcObjectReader *create_reader(const Alembic::AbcGeom::IObject &object, ImportSettings &settings);
-
-/* ************************** */
-
-/* TODO(kevin): for now keeping these transformations hardcoded to make sure
- * everything works properly, and also because Alembic is almost exclusively
- * used in Y-up software, but eventually they'll be set by the user in the UI
- * like other importers/exporters do, to support other axis. */
-
-/* Copy from Y-up to Z-up. */
-
-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;
-}
-
-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;
-}
-
-/* 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;
-}
-
-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;
-}
-
-/* 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,
-} 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 copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode);
-
-/* *************************** */
-
-#undef ABC_DEBUG_TIME
-
-class ScopeTimer {
- const char *m_message;
- double m_start;
-
- public:
- ScopeTimer(const char *message);
- ~ScopeTimer();
-};
-
-#ifdef ABC_DEBUG_TIME
-# define SCOPE_TIMER(message) ScopeTimer prof(message)
-#else
-# define SCOPE_TIMER(message)
-#endif
-
-/* *************************** */
-
-/**
- * Utility class whose purpose is to more easily log related information. An
- * instance of the SimpleLogger can be created in any context, and will hold a
- * copy of all the strings passed to its output stream.
- *
- * Different instances of the class may be accessed from different threads,
- * although accessing the same instance from different threads will lead to race
- * conditions.
- */
-class SimpleLogger {
- std::ostringstream m_stream;
-
- public:
- /**
- * 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()
-
-/**
- * Pass the content of the logger's stream to the specified std::ostream.
- */
-std::ostream &operator<<(std::ostream &os, const SimpleLogger &logger);
-
-#endif /* __ABC_UTIL_H__ */
diff --git a/source/blender/alembic/intern/abc_writer_archive.cc b/source/blender/alembic/intern/abc_writer_archive.cc
deleted file mode 100644
index af18d480a18..00000000000
--- a/source/blender/alembic/intern/abc_writer_archive.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_writer_archive.h"
-extern "C" {
-#include "BKE_blender_version.h"
-
-#include "BLI_path_util.h"
-#include "BLI_string.h"
-
-#include "DNA_scene_types.h"
-}
-
-#ifdef WIN32
-# include "utfconv.h"
-#endif
-
-#include <fstream>
-
-using Alembic::Abc::ErrorHandler;
-using Alembic::Abc::kWrapExisting;
-using Alembic::Abc::OArchive;
-
-/* This kinda duplicates CreateArchiveWithInfo, but Alembic does not seem to
- * have a version supporting streams. */
-static OArchive create_archive(std::ostream *ostream,
- const std::string &filename,
- const std::string &scene_name,
- double scene_fps,
- bool ogawa)
-{
- Alembic::Abc::MetaData abc_metadata;
-
- abc_metadata.set(Alembic::Abc::kApplicationNameKey, "Blender");
- abc_metadata.set(Alembic::Abc::kUserDescriptionKey, scene_name);
- abc_metadata.set("blender_version", versionstr);
- abc_metadata.set("FramesPerTimeUnit", std::to_string(scene_fps));
-
- time_t raw_time;
- time(&raw_time);
- char buffer[128];
-
-#if defined _WIN32 || defined _WIN64
- ctime_s(buffer, 128, &raw_time);
-#else
- ctime_r(&raw_time, buffer);
-#endif
-
- const std::size_t buffer_len = strlen(buffer);
- if (buffer_len > 0 && buffer[buffer_len - 1] == '\n') {
- buffer[buffer_len - 1] = '\0';
- }
-
- abc_metadata.set(Alembic::Abc::kDateWrittenKey, buffer);
-
- ErrorHandler::Policy policy = ErrorHandler::kThrowPolicy;
-
-#ifdef WITH_ALEMBIC_HDF5
- if (!ogawa) {
- return OArchive(Alembic::AbcCoreHDF5::WriteArchive(), filename, abc_metadata, policy);
- }
-#else
- static_cast<void>(filename);
- static_cast<void>(ogawa);
-#endif
-
- Alembic::AbcCoreOgawa::WriteArchive archive_writer;
- return OArchive(archive_writer(ostream, abc_metadata), kWrapExisting, policy);
-}
-
-ArchiveWriter::ArchiveWriter(const char *filename,
- const std::string &abc_scene_name,
- const Scene *scene,
- bool 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);
-#else
- m_outfile.open(filename, std::ios::out | std::ios::binary);
-#endif
- }
-
- m_archive = create_archive(&m_outfile, filename, abc_scene_name, FPS, do_ogawa);
-}
-
-OArchive &ArchiveWriter::archive()
-{
- return m_archive;
-}
diff --git a/source/blender/alembic/intern/abc_writer_archive.h b/source/blender/alembic/intern/abc_writer_archive.h
deleted file mode 100644
index e261e60990a..00000000000
--- a/source/blender/alembic/intern/abc_writer_archive.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_WRITER_ARCHIVE_H__
-#define __ABC_WRITER_ARCHIVE_H__
-
-#include <Alembic/Abc/All.h>
-
-#ifdef WITH_ALEMBIC_HDF5
-# include <Alembic/AbcCoreHDF5/All.h>
-#endif
-
-#include <Alembic/AbcCoreOgawa/All.h>
-
-#include <fstream>
-
-struct Main;
-struct Scene;
-
-/* Wrappers around input and output archives. The goal is to be able to use
- * streams so that unicode paths work on Windows (T49112), and to make sure that
- * the stream objects remain valid as long as the archives are open.
- */
-
-class ArchiveWriter {
- std::ofstream m_outfile;
- Alembic::Abc::OArchive m_archive;
-
- public:
- ArchiveWriter(const char *filename,
- const std::string &abc_scene_name,
- const Scene *scene,
- bool do_ogawa);
-
- Alembic::Abc::OArchive &archive();
-};
-
-#endif /* __ABC_WRITER_ARCHIVE_H__ */
diff --git a/source/blender/alembic/intern/abc_writer_camera.cc b/source/blender/alembic/intern/abc_writer_camera.cc
deleted file mode 100644
index e705e5ba911..00000000000
--- a/source/blender/alembic/intern/abc_writer_camera.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_writer_camera.h"
-#include "abc_writer_transform.h"
-
-extern "C" {
-#include "DNA_camera_types.h"
-#include "DNA_object_types.h"
-}
-
-using Alembic::AbcGeom::OCamera;
-using Alembic::AbcGeom::OFloatProperty;
-
-AbcCameraWriter::AbcCameraWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings)
- : AbcObjectWriter(ob, time_sampling, settings, parent)
-{
- 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);
-}
-
-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.focus_object) {
- Imath::V3f v(m_object->loc[0] - cam->dof.focus_object->loc[0],
- m_object->loc[1] - cam->dof.focus_object->loc[1],
- m_object->loc[2] - cam->dof.focus_object->loc[2]);
- m_camera_sample.setFocusDistance(v.length());
- }
- else {
- m_camera_sample.setFocusDistance(cam->dof.focus_distance);
- }
-
- /* Blender camera does not have an fstop param, so try to find a custom prop
- * instead. */
- m_camera_sample.setFStop(cam->dof.aperture_fstop);
-
- m_camera_sample.setLensSqueezeRatio(1.0);
- m_camera_schema.set(m_camera_sample);
-}
diff --git a/source/blender/alembic/intern/abc_writer_camera.h b/source/blender/alembic/intern/abc_writer_camera.h
deleted file mode 100644
index 3b515911a48..00000000000
--- a/source/blender/alembic/intern/abc_writer_camera.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_WRITER_CAMERA_H__
-#define __ABC_WRITER_CAMERA_H__
-
-#include "abc_writer_object.h"
-
-/* ************************************************************************** */
-
-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();
-};
-
-#endif /* __ABC_WRITER_CAMERA_H__ */
diff --git a/source/blender/alembic/intern/abc_writer_curves.cc b/source/blender/alembic/intern/abc_writer_curves.cc
deleted file mode 100644
index 3ab9b365a72..00000000000
--- a/source/blender/alembic/intern/abc_writer_curves.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_writer_curves.h"
-#include "abc_reader_curves.h"
-#include "abc_writer_transform.h"
-
-extern "C" {
-#include "DNA_curve_types.h"
-#include "DNA_object_types.h"
-
-#include "BKE_curve.h"
-#include "BKE_mesh.h"
-#include "BKE_object.h"
-}
-
-using Alembic::AbcGeom::OCompoundProperty;
-using Alembic::AbcGeom::OCurves;
-using Alembic::AbcGeom::OCurvesSchema;
-using Alembic::AbcGeom::OInt16Property;
-using Alembic::AbcGeom::ON3fGeomParam;
-using Alembic::AbcGeom::OV2fGeomParam;
-
-AbcCurveWriter::AbcCurveWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings)
- : AbcObjectWriter(ob, time_sampling, settings, parent)
-{
- 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);
-}
-
-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);
-}
-
-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)
-{
- Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
- if (mesh_eval != NULL) {
- /* Mesh_eval only exists when generative modifiers are in use. */
- r_needsfree = false;
- return mesh_eval;
- }
-
- r_needsfree = true;
- return BKE_mesh_new_nomain_from_curve(ob_eval);
-}
diff --git a/source/blender/alembic/intern/abc_writer_curves.h b/source/blender/alembic/intern/abc_writer_curves.h
deleted file mode 100644
index d6d8c0a7f11..00000000000
--- a/source/blender/alembic/intern/abc_writer_curves.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_WRITER_CURVES_H__
-#define __ABC_WRITER_CURVES_H__
-
-#include "abc_writer_object.h"
-#include "abc_writer_mesh.h"
-
-class AbcCurveWriter : public AbcObjectWriter {
- Alembic::AbcGeom::OCurvesSchema m_schema;
- Alembic::AbcGeom::OCurvesSchema::Sample m_sample;
-
- public:
- AbcCurveWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings);
-
- 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);
-};
-
-#endif /* __ABC_WRITER_CURVES_H__ */
diff --git a/source/blender/alembic/intern/abc_writer_hair.cc b/source/blender/alembic/intern/abc_writer_hair.cc
deleted file mode 100644
index bbba03ed7f4..00000000000
--- a/source/blender/alembic/intern/abc_writer_hair.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_writer_hair.h"
-#include "abc_writer_transform.h"
-#include "abc_util.h"
-
-#include <cstdio>
-
-extern "C" {
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
-
-#include "BLI_math_geom.h"
-
-#include "BKE_mesh.h"
-#include "BKE_mesh_runtime.h"
-#include "BKE_particle.h"
-}
-
-using Alembic::Abc::P3fArraySamplePtr;
-
-using Alembic::AbcGeom::OCurves;
-using Alembic::AbcGeom::OCurvesSchema;
-using Alembic::AbcGeom::ON3fGeomParam;
-using Alembic::AbcGeom::OV2fGeomParam;
-
-/* ************************************************************************** */
-
-AbcHairWriter::AbcHairWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings,
- ParticleSystem *psys)
- : AbcObjectWriter(ob, time_sampling, settings, parent), m_uv_warning_shown(false)
-{
- m_psys = psys;
-
- 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;
- bool export_children = m_settings.export_child_hairs && m_psys->childcache &&
- part->childtype != 0;
-
- if (!export_children || part->draw & PART_DRAW_PARENT) {
- write_hair_sample(mesh, part, verts, norm_values, uv_values, hvertices);
- }
-
- if (export_children) {
- 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,
- ParticleSettings *part,
- std::vector<Imath::V3f> &verts,
- std::vector<Imath::V3f> &norm_values,
- 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]));
- }
- }
-}
-
-void AbcHairWriter::write_hair_child_sample(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)
-{
- /* 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_writer_hair.h b/source/blender/alembic/intern/abc_writer_hair.h
deleted file mode 100644
index 67d1b7b3d23..00000000000
--- a/source/blender/alembic/intern/abc_writer_hair.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_WRITER_HAIR_H__
-#define __ABC_WRITER_HAIR_H__
-
-#include "abc_writer_object.h"
-
-struct ParticleSettings;
-struct ParticleSystem;
-
-class AbcHairWriter : public AbcObjectWriter {
- ParticleSystem *m_psys;
-
- Alembic::AbcGeom::OCurvesSchema m_schema;
- Alembic::AbcGeom::OCurvesSchema::Sample m_sample;
-
- bool m_uv_warning_shown;
-
- public:
- AbcHairWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings,
- ParticleSystem *psys);
-
- 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_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_WRITER_HAIR_H__ */
diff --git a/source/blender/alembic/intern/abc_writer_mball.cc b/source/blender/alembic/intern/abc_writer_mball.cc
deleted file mode 100644
index cc0775bd537..00000000000
--- a/source/blender/alembic/intern/abc_writer_mball.cc
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_writer_mball.h"
-#include "abc_writer_mesh.h"
-
-extern "C" {
-#include "DNA_meta_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_object_types.h"
-
-#include "BKE_displist.h"
-#include "BKE_lib_id.h"
-#include "BKE_mball.h"
-#include "BKE_mesh.h"
-#include "BKE_object.h"
-
-#include "BLI_utildefines.h"
-}
-
-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();
-}
-
-AbcMBallWriter::~AbcMBallWriter()
-{
-}
-
-bool AbcMBallWriter::isAnimated() const
-{
- return true;
-}
-
-Mesh *AbcMBallWriter::getEvaluatedMesh(Scene * /*scene_eval*/, Object *ob_eval, bool &r_needsfree)
-{
- Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
- if (mesh_eval != NULL) {
- /* Mesh_eval only exists when generative modifiers are in use. */
- r_needsfree = false;
- return 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 rethought.
- */
- 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);
-}
-
-bool AbcMBallWriter::isBasisBall(Scene *scene, Object *ob)
-{
- Object *basis_ob = BKE_mball_basis_find(scene, ob);
- return ob == basis_ob;
-}
diff --git a/source/blender/alembic/intern/abc_writer_mball.h b/source/blender/alembic/intern/abc_writer_mball.h
deleted file mode 100644
index c752472c86d..00000000000
--- a/source/blender/alembic/intern/abc_writer_mball.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_WRITER_MBALL_H__
-#define __ABC_WRITER_MBALL_H__
-
-#include "abc_writer_object.h"
-#include "abc_writer_mesh.h"
-
-struct Main;
-struct Object;
-
-/* AbcMBallWriter converts the metaballs to meshes at every frame,
- * and defers to AbcGenericMeshWriter to perform the writing
- * 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);
-
- ~AbcMBallWriter();
-
- static bool isBasisBall(Scene *scene, Object *ob);
-
- 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_WRITER_MBALL_H__ */
diff --git a/source/blender/alembic/intern/abc_writer_mesh.cc b/source/blender/alembic/intern/abc_writer_mesh.cc
deleted file mode 100644
index b55d2473f99..00000000000
--- a/source/blender/alembic/intern/abc_writer_mesh.cc
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_writer_mesh.h"
-#include "abc_writer_transform.h"
-#include "abc_util.h"
-
-extern "C" {
-#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_object_fluidsim_types.h"
-
-#include "BKE_animsys.h"
-#include "BKE_key.h"
-#include "BKE_lib_id.h"
-#include "BKE_material.h"
-#include "BKE_mesh.h"
-#include "BKE_mesh_runtime.h"
-#include "BKE_modifier.h"
-
-#include "bmesh.h"
-#include "bmesh_tools.h"
-
-#include "DEG_depsgraph_query.h"
-}
-
-using Alembic::Abc::FloatArraySample;
-using Alembic::Abc::Int32ArraySample;
-using Alembic::Abc::V2fArraySample;
-using Alembic::Abc::V3fArraySample;
-
-using Alembic::AbcGeom::kFacevaryingScope;
-using Alembic::AbcGeom::OBoolProperty;
-using Alembic::AbcGeom::OCompoundProperty;
-using Alembic::AbcGeom::OFaceSet;
-using Alembic::AbcGeom::OFaceSetSchema;
-using Alembic::AbcGeom::ON3fGeomParam;
-using Alembic::AbcGeom::OPolyMesh;
-using Alembic::AbcGeom::OPolyMeshSchema;
-using Alembic::AbcGeom::OSubD;
-using Alembic::AbcGeom::OSubDSchema;
-using Alembic::AbcGeom::OV2fGeomParam;
-using Alembic::AbcGeom::UInt32ArraySample;
-
-/* NOTE: Alembic's polygon winding order is clockwise, to match with Renderman. */
-
-static void get_vertices(struct Mesh *mesh, std::vector<Imath::V3f> &points)
-{
- points.clear();
- points.resize(mesh->totvert);
-
- MVert *verts = mesh->mvert;
-
- 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,
- std::vector<int32_t> &poly_verts,
- std::vector<int32_t> &loop_counts,
- bool &r_has_flat_shaded_poly)
-{
- const int num_poly = mesh->totpoly;
- const int num_loops = mesh->totloop;
- MLoop *mloop = mesh->mloop;
- MPoly *mpoly = mesh->mpoly;
- r_has_flat_shaded_poly = false;
-
- 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);
-
- r_has_flat_shaded_poly |= (poly.flag & ME_SMOOTH) == 0;
-
- MLoop *loop = mloop + poly.loopstart + (poly.totloop - 1);
-
- for (int j = 0; j < poly.totloop; j++, loop--) {
- poly_verts.push_back(loop->v);
- }
- }
-}
-
-static void get_creases(struct Mesh *mesh,
- std::vector<int32_t> &indices,
- std::vector<int32_t> &lengths,
- std::vector<float> &sharpnesses)
-{
- const float factor = 1.0f / 255.0f;
-
- indices.clear();
- lengths.clear();
- sharpnesses.clear();
-
- MEdge *edge = mesh->medge;
-
- 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);
- }
- }
-
- lengths.resize(sharpnesses.size(), 2);
-}
-
-static void get_loop_normals(struct Mesh *mesh,
- std::vector<Imath::V3f> &normals,
- bool has_flat_shaded_poly)
-{
- normals.clear();
-
- /* If all polygons are smooth shaded, and there are no custom normals, we don't need to export
- * normals at all. This is also done by other software, see T71246. */
- if (!has_flat_shaded_poly && !CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL)) {
- return;
- }
-
- BKE_mesh_calc_normals_split(mesh);
- const float(*lnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL));
- BLI_assert(lnors != NULL || !"BKE_mesh_calc_normals_split() should have computed CD_NORMAL");
-
- normals.resize(mesh->totloop);
-
- /* NOTE: data needs to be written in the reverse order. */
- int abc_index = 0;
- MPoly *mp = mesh->mpoly;
- for (int i = 0, e = mesh->totpoly; i < e; i++, mp++) {
- for (int j = mp->totloop - 1; j >= 0; j--, abc_index++) {
- int blender_index = mp->loopstart + j;
- copy_yup_from_zup(normals[abc_index].getValue(), lnors[blender_index]);
- }
- }
-}
-
-/* *************** Modifiers *************** */
-
-/* check if the mesh is a subsurf, ignoring disabled modifiers and
- * displace if it's after subsurf. */
-static ModifierData *get_subsurf_modifier(Scene *scene, Object *ob)
-{
- ModifierData *md = static_cast<ModifierData *>(ob->modifiers.last);
-
- 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 (smd->subdivType == ME_CC_SUBSURF) {
- return md;
- }
- }
-
- /* mesh is not a subsurf. break */
- if ((md->type != eModifierType_Displace) && (md->type != eModifierType_ParticleSystem)) {
- return NULL;
- }
- }
-
- return NULL;
-}
-
-static ModifierData *get_liquid_sim_modifier(Scene *scene, Object *ob)
-{
- ModifierData *md = modifiers_findByType(ob, eModifierType_Fluidsim);
-
- 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;
- }
- }
-
- return NULL;
-}
-
-/* ************************************************************************** */
-
-AbcGenericMeshWriter::AbcGenericMeshWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- 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);
- }
-}
-
-AbcGenericMeshWriter::~AbcGenericMeshWriter()
-{
- if (m_subsurf_mod) {
- m_subsurf_mod->mode &= ~eModifierMode_DisableTemporary;
- }
-}
-
-bool AbcGenericMeshWriter::isAnimated() const
-{
- if (BKE_animdata_id_is_animated(static_cast<ID *>(m_object->data))) {
- 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;
-}
-
-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;
- }
-}
-
-void AbcGenericMeshWriter::freeEvaluatedMesh(struct Mesh *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> velocities;
- bool has_flat_shaded_poly = false;
-
- get_vertices(mesh, points);
- get_topology(mesh, poly_verts, loop_counts, has_flat_shaded_poly);
-
- 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));
-
- 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);
-
- 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);
- }
-
- if (m_settings.export_normals) {
- get_loop_normals(mesh, normals, has_flat_shaded_poly);
-
- ON3fGeomParam::Sample normals_sample;
- if (!normals.empty()) {
- normals_sample.setScope(kFacevaryingScope);
- normals_sample.setVals(V3fArraySample(normals));
- }
-
- m_mesh_sample.setNormals(normals_sample);
- }
-
- if (m_is_liquid) {
- getVelocities(mesh, velocities);
- m_mesh_sample.setVelocities(V3fArraySample(velocities));
- }
-
- m_mesh_sample.setSelfBounds(bounds());
-
- m_mesh_schema.set(m_mesh_sample);
-
- 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;
- bool has_flat_poly = false;
-
- get_vertices(mesh, points);
- get_topology(mesh, poly_verts, loop_counts, has_flat_poly);
- get_creases(mesh, crease_indices, crease_lengths, crease_sharpness);
-
- 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));
-
- 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);
-
- 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);
- }
-
- 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);
-
- writeArbGeoParams(mesh);
-}
-
-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);
- }
-}
-
-Mesh *AbcGenericMeshWriter::getFinalMesh(bool &r_needsfree)
-{
- /* We don't want subdivided mesh data */
- if (m_subsurf_mod) {
- m_subsurf_mod->mode |= eModifierMode_DisableTemporary;
- }
-
- 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);
-
- 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;
-
- 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);
-
- Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh);
- BM_mesh_free(bm);
-
- if (r_needsfree) {
- BKE_id_free(NULL, mesh);
- }
-
- 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;
-
- 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);
- }
- }
-}
-
-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));
- }
-}
-
-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;
-
- for (int i = 0; i < num_poly; i++) {
- MPoly &current_poly = polygons[i];
- short mnr = current_poly.mat_nr;
-
- Material *mat = BKE_object_material_get(m_object, mnr + 1);
-
- if (!mat) {
- continue;
- }
-
- 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;
- }
-
- geo_groups[name].push_back(i);
- }
-
- if (geo_groups.size() == 0) {
- Material *mat = BKE_object_material_get(m_object, 1);
-
- std::string name = (mat) ? get_id_name(&mat->id) : "default";
-
- std::vector<int32_t> faceArray;
-
- for (int i = 0, e = mesh->totface; i < e; i++) {
- faceArray.push_back(i);
- }
-
- 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);
-}
diff --git a/source/blender/alembic/intern/abc_writer_mesh.h b/source/blender/alembic/intern/abc_writer_mesh.h
deleted file mode 100644
index 9152a370e4f..00000000000
--- a/source/blender/alembic/intern/abc_writer_mesh.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_WRITER_MESH_H__
-#define __ABC_WRITER_MESH_H__
-
-#include "abc_customdata.h"
-#include "abc_writer_object.h"
-
-struct Mesh;
-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;
-
- Alembic::AbcGeom::OSubDSchema m_subdiv_schema;
- Alembic::AbcGeom::OSubDSchema::Sample m_subdiv_sample;
-
- Alembic::Abc::OArrayProperty m_mat_indices;
-
- bool m_is_animated;
- ModifierData *m_subsurf_mod;
-
- CDStreamConfig m_custom_data_config;
-
- bool m_is_liquid;
- bool m_is_subd;
-
- public:
- AbcGenericMeshWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings);
-
- ~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);
-
- Mesh *getFinalMesh(bool &r_needsfree);
-
- 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);
-
- /* fluid surfaces support */
- void getVelocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels);
-
- 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;
-};
-
-#endif /* __ABC_WRITER_MESH_H__ */
diff --git a/source/blender/alembic/intern/abc_writer_nurbs.cc b/source/blender/alembic/intern/abc_writer_nurbs.cc
deleted file mode 100644
index 9796eaf54c3..00000000000
--- a/source/blender/alembic/intern/abc_writer_nurbs.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_writer_nurbs.h"
-#include "abc_writer_transform.h"
-#include "abc_util.h"
-
-extern "C" {
-#include "DNA_curve_types.h"
-#include "DNA_object_types.h"
-
-#include "BLI_listbase.h"
-
-#include "BKE_curve.h"
-}
-
-using Alembic::AbcGeom::FloatArraySample;
-using Alembic::AbcGeom::OBoolProperty;
-using Alembic::AbcGeom::OCompoundProperty;
-using Alembic::AbcGeom::ONuPatch;
-using Alembic::AbcGeom::ONuPatchSchema;
-
-AbcNurbsWriter::AbcNurbsWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings)
- : AbcObjectWriter(ob, time_sampling, settings, parent)
-{
- m_is_animated = isAnimated();
-
- /* 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);
-
- for (size_t i = 0; i < numNurbs; i++) {
- std::stringstream str;
- str << m_name << '_' << i;
-
- 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());
- }
-}
-
-bool AbcNurbsWriter::isAnimated() const
-{
- /* 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;
- }
-
- /* 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);
-
- 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]);
-}
-
-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);
- }
-}
diff --git a/source/blender/alembic/intern/abc_writer_nurbs.h b/source/blender/alembic/intern/abc_writer_nurbs.h
deleted file mode 100644
index c6a3c399b66..00000000000
--- a/source/blender/alembic/intern/abc_writer_nurbs.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_WRITER_NURBS_H__
-#define __ABC_WRITER_NURBS_H__
-
-#include "abc_writer_object.h"
-
-class AbcNurbsWriter : public AbcObjectWriter {
- std::vector<Alembic::AbcGeom::ONuPatchSchema> m_nurbs_schema;
- bool m_is_animated;
-
- public:
- AbcNurbsWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings);
-
- private:
- virtual void do_write();
-
- bool isAnimated() const;
-};
-
-#endif /* __ABC_WRITER_NURBS_H__ */
diff --git a/source/blender/alembic/intern/abc_writer_object.cc b/source/blender/alembic/intern/abc_writer_object.cc
deleted file mode 100644
index 75dc93bd08e..00000000000
--- a/source/blender/alembic/intern/abc_writer_object.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_writer_object.h"
-
-extern "C" {
-#include "DNA_object_types.h"
-
-#include "BKE_object.h"
-}
-
-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_name = get_id_name(m_object) + "Shape";
-
- if (parent) {
- parent->addChild(this);
- }
-}
-
-AbcObjectWriter::~AbcObjectWriter()
-{
-}
-
-void AbcObjectWriter::addChild(AbcObjectWriter *child)
-{
- m_children.push_back(child);
-}
-
-Imath::Box3d AbcObjectWriter::bounds()
-{
- 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";
- }
-
- 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];
-
- 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;
-}
-
-void AbcObjectWriter::write()
-{
- do_write();
- m_first_frame = false;
-}
diff --git a/source/blender/alembic/intern/abc_writer_object.h b/source/blender/alembic/intern/abc_writer_object.h
deleted file mode 100644
index c3511566372..00000000000
--- a/source/blender/alembic/intern/abc_writer_object.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_WRITER_OBJECT_H__
-#define __ABC_WRITER_OBJECT_H__
-
-#include <Alembic/Abc/All.h>
-#include <Alembic/AbcGeom/All.h>
-
-#include "abc_exporter.h"
-
-extern "C" {
-#include "DNA_ID.h"
-}
-
-class AbcTransformWriter;
-
-struct Main;
-struct Object;
-
-class AbcObjectWriter {
- protected:
- Object *m_object;
- ExportSettings &m_settings;
-
- uint32_t m_time_sampling;
-
- Imath::Box3d m_bounds;
- std::vector<AbcObjectWriter *> m_children;
-
- std::vector<std::pair<std::string, IDProperty *>> m_props;
-
- bool m_first_frame;
- std::string m_name;
-
- public:
- AbcObjectWriter(Object *ob,
- uint32_t time_sampling,
- ExportSettings &settings,
- AbcObjectWriter *parent = NULL);
-
- virtual ~AbcObjectWriter();
-
- void addChild(AbcObjectWriter *child);
-
- virtual Imath::Box3d bounds();
-
- void write();
-
- private:
- virtual void do_write() = 0;
-};
-
-#endif /* __ABC_WRITER_OBJECT_H__ */
diff --git a/source/blender/alembic/intern/abc_writer_points.cc b/source/blender/alembic/intern/abc_writer_points.cc
deleted file mode 100644
index cc4abe8ec4b..00000000000
--- a/source/blender/alembic/intern/abc_writer_points.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_writer_points.h"
-#include "abc_writer_mesh.h"
-#include "abc_writer_transform.h"
-#include "abc_util.h"
-
-extern "C" {
-#include "DNA_object_types.h"
-#include "DNA_particle_types.h"
-
-#include "BKE_lattice.h"
-#include "BKE_particle.h"
-
-#include "BLI_math.h"
-
-#include "DEG_depsgraph_query.h"
-}
-
-using Alembic::AbcGeom::kVertexScope;
-using Alembic::AbcGeom::OPoints;
-using Alembic::AbcGeom::OPointsSchema;
-
-/* ************************************************************************** */
-
-AbcPointsWriter::AbcPointsWriter(Object *ob,
- AbcTransformWriter *parent,
- uint32_t time_sampling,
- ExportSettings &settings,
- ParticleSystem *psys)
- : AbcObjectWriter(ob, time_sampling, settings, parent)
-{
- m_psys = psys;
-
- OPoints points(parent->alembicXform(), psys->name, m_time_sampling);
- m_schema = points.getSchema();
-}
-
-void AbcPointsWriter::do_write()
-{
- if (!m_psys) {
- return;
- }
-
- std::vector<Imath::V3f> points;
- std::vector<Imath::V3f> velocities;
- std::vector<float> widths;
- std::vector<uint64_t> ids;
-
- ParticleKey state;
-
- 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);
-
- 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;
- }
-
- state.time = DEG_get_ctime(m_settings.depsgraph);
-
- if (psys_get_particle_state(&sim, p, &state, 0) == 0) {
- continue;
- }
-
- /* location */
- mul_v3_m4v3(pos, m_object->imat, 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++);
- }
-
- 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);
-
- m_sample = OPointsSchema::Sample(psample, idsample, vsample, wsample);
- m_sample.setSelfBounds(bounds());
-
- m_schema.set(m_sample);
-}
diff --git a/source/blender/alembic/intern/abc_writer_points.h b/source/blender/alembic/intern/abc_writer_points.h
deleted file mode 100644
index 77dd10c4b26..00000000000
--- a/source/blender/alembic/intern/abc_writer_points.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2016 Kévin Dietrich.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_WRITER_POINTS_H__
-#define __ABC_WRITER_POINTS_H__
-
-#include "abc_writer_object.h"
-#include "abc_customdata.h"
-
-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();
-};
-
-#endif /* __ABC_WRITER_POINTS_H__ */
diff --git a/source/blender/alembic/intern/abc_writer_transform.cc b/source/blender/alembic/intern/abc_writer_transform.cc
deleted file mode 100644
index d7bcc46d96f..00000000000
--- a/source/blender/alembic/intern/abc_writer_transform.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "abc_writer_transform.h"
-#include "abc_util.h"
-
-#include <OpenEXR/ImathBoxAlgo.h>
-
-extern "C" {
-#include "DNA_object_types.h"
-
-#include "BLI_math.h"
-
-#include "DEG_depsgraph_query.h"
-}
-
-using Alembic::AbcGeom::OObject;
-using Alembic::AbcGeom::OXform;
-
-AbcTransformWriter::AbcTransformWriter(Object *ob,
- const OObject &abc_parent,
- AbcTransformWriter *parent,
- unsigned int time_sampling,
- ExportSettings &settings)
- : AbcObjectWriter(ob, time_sampling, settings, parent), m_proxy_from(NULL)
-{
- m_is_animated = hasAnimation(m_object);
-
- if (!m_is_animated) {
- time_sampling = 0;
- }
-
- 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;
-}
-
-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_VIEWPORT));
-
- 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);
-
- /* If the parent is a camera, undo its to-Maya rotation (see below). */
- bool is_root_object = !m_inherits_xform || ob_eval->parent == nullptr;
- if (!is_root_object && ob_eval->parent->type == OB_CAMERA) {
- float rot_mat[4][4];
- axis_angle_to_mat4_single(rot_mat, 'X', M_PI_2);
- mul_m4_m4m4(yup_mat, rot_mat, yup_mat);
- }
-
- /* If the object is a camera, apply an extra rotation to Maya camera orientation. */
- if (ob_eval->type == OB_CAMERA) {
- 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 (is_root_object) {
- /* 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_datatype(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;
-
- 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);
-}
-
-bool AbcTransformWriter::hasAnimation(Object * /*ob*/) const
-{
- return true;
-}
diff --git a/source/blender/alembic/intern/abc_writer_transform.h b/source/blender/alembic/intern/abc_writer_transform.h
deleted file mode 100644
index 4397b220761..00000000000
--- a/source/blender/alembic/intern/abc_writer_transform.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#ifndef __ABC_WRITER_TRANSFORM_H__
-#define __ABC_WRITER_TRANSFORM_H__
-
-#include "abc_writer_object.h"
-
-#include <Alembic/AbcGeom/All.h>
-
-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;
-};
-
-#endif /* __ABC_WRITER_TRANSFORM_H__ */
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
deleted file mode 100644
index c6f9e284d53..00000000000
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ /dev/null
@@ -1,1052 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/** \file
- * \ingroup balembic
- */
-
-#include "../ABC_alembic.h"
-
-#include <Alembic/AbcMaterial/IMaterial.h>
-
-#include "abc_reader_archive.h"
-#include "abc_reader_camera.h"
-#include "abc_reader_curves.h"
-#include "abc_reader_mesh.h"
-#include "abc_reader_nurbs.h"
-#include "abc_reader_points.h"
-#include "abc_reader_transform.h"
-#include "abc_util.h"
-#include "abc_writer_camera.h"
-#include "abc_writer_curves.h"
-#include "abc_writer_hair.h"
-#include "abc_writer_mesh.h"
-#include "abc_writer_nurbs.h"
-#include "abc_writer_points.h"
-#include "abc_writer_transform.h"
-
-#include "MEM_guardedalloc.h"
-
-extern "C" {
-#include "DNA_cachefile_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-
-#include "BKE_cachefile.h"
-#include "BKE_context.h"
-#include "BKE_curve.h"
-#include "BKE_global.h"
-#include "BKE_layer.h"
-#include "BKE_lib_id.h"
-#include "BKE_scene.h"
-
-#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_build.h"
-
-/* SpaceType struct has a member called 'new' which obviously conflicts with C++
- * so temporarily redefining the new keyword to make it compile. */
-#define new extern_new
-#include "BKE_screen.h"
-#undef new
-
-#include "BLI_fileops.h"
-#include "BLI_ghash.h"
-#include "BLI_listbase.h"
-#include "BLI_math.h"
-#include "BLI_path_util.h"
-#include "BLI_string.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-}
-
-using Alembic::Abc::Int32ArraySamplePtr;
-using Alembic::Abc::ObjectHeader;
-
-using Alembic::AbcGeom::kWrapExisting;
-using Alembic::AbcGeom::MetaData;
-using Alembic::AbcGeom::P3fArraySamplePtr;
-
-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;
-using Alembic::AbcGeom::IPointsSchema;
-using Alembic::AbcGeom::IPolyMesh;
-using Alembic::AbcGeom::IPolyMeshSchema;
-using Alembic::AbcGeom::ISampleSelector;
-using Alembic::AbcGeom::ISubD;
-using Alembic::AbcGeom::IV2fGeomParam;
-using Alembic::AbcGeom::IXform;
-using Alembic::AbcGeom::IXformSchema;
-using Alembic::AbcGeom::N3fArraySamplePtr;
-using Alembic::AbcGeom::V3fArraySamplePtr;
-using Alembic::AbcGeom::XformSample;
-
-using Alembic::AbcMaterial::IMaterial;
-
-struct AbcArchiveHandle {
- int unused;
-};
-
-ABC_INLINE ArchiveReader *archive_from_handle(AbcArchiveHandle *handle)
-{
- return reinterpret_cast<ArchiveReader *>(handle);
-}
-
-ABC_INLINE AbcArchiveHandle *handle_from_archive(ArchiveReader *archive)
-{
- return reinterpret_cast<AbcArchiveHandle *>(archive);
-}
-
-//#define USE_NURBS
-
-/* NOTE: this function is similar to visit_objects below, need to keep them in
- * 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) ||
-#ifdef USE_NURBS
- INuPatch::matches(md) ||
-#endif
- 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);
-
- 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;
-}
-
-AbcArchiveHandle *ABC_create_handle(struct Main *bmain,
- const char *filename,
- ListBase *object_paths)
-{
- ArchiveReader *archive = new ArchiveReader(bmain, filename);
-
- if (!archive->valid()) {
- delete archive;
- return NULL;
- }
-
- if (object_paths) {
- gather_objects_paths(archive->getTop(), object_paths);
- }
-
- return handle_from_archive(archive);
-}
-
-void ABC_free_handle(AbcArchiveHandle *handle)
-{
- delete archive_from_handle(handle);
-}
-
-int ABC_get_version()
-{
- return ALEMBIC_LIBRARY_VERSION;
-}
-
-static void find_iobject(const IObject &object, IObject &ret, const std::string &path)
-{
- if (!object.valid()) {
- return;
- }
-
- std::vector<std::string> tokens;
- split(path, '/', tokens);
-
- IObject tmp = object;
-
- std::vector<std::string>::iterator iter;
- for (iter = tokens.begin(); iter != tokens.end(); ++iter) {
- IObject child = tmp.getChild(*iter);
- tmp = child;
- }
-
- ret = tmp;
-}
-
-struct ExportJobData {
- ViewLayer *view_layer;
- Main *bmain;
- wmWindowManager *wm;
-
- char filename[1024];
- ExportSettings settings;
-
- short *stop;
- short *do_update;
- float *progress;
-
- 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);
-
- 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;
- WM_set_locked_interface(data->wm, true);
- 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);
-
- try {
- AbcExporter exporter(data->bmain, data->filename, data->settings);
-
- Scene *scene = data->settings.scene; /* for the CFRA macro */
- const int orig_frame = CFRA;
-
- data->was_canceled = false;
- exporter(do_update, progress, &data->was_canceled);
-
- if (CFRA != orig_frame) {
- CFRA = orig_frame;
-
- 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";
- }
-}
-
-static void export_endjob(void *customdata)
-{
- ExportJobData *data = static_cast<ExportJobData *>(customdata);
-
- DEG_graph_free(data->settings.depsgraph);
-
- if (data->was_canceled && BLI_exists(data->filename)) {
- BLI_delete(data->filename, false, false);
- }
-
- std::string log = data->settings.logger.str();
- if (!log.empty()) {
- std::cerr << log;
- WM_report(RPT_ERROR, "Errors occurred during the export, look in the console to know more...");
- }
-
- G.is_rendering = false;
- WM_set_locked_interface(data->wm, false);
-}
-
-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->wm = CTX_wm_manager(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(job->bmain, 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_objects_only = params->visible_objects_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 ********************** */
-
-/**
- * Generates an AbcObjectReader for this Alembic object and its children.
- *
- * \param object: The Alembic IObject to visit.
- * \param readers: The created AbcObjectReader * will be appended to this vector.
- * \param settings: Import settings, not used directly but passed to the
- * AbcObjectReader subclass constructors.
- * \param r_assign_as_parent: Return parameter, contains a list of reader
- * pointers, whose parent pointer should still be set.
- * This is filled when this call to visit_object() didn't create
- * a reader that should be the parent.
- * \return A pair of boolean and reader pointer. The boolean indicates whether
- * this IObject claims its parent as part of the same object
- * (for example an IPolyMesh object would claim its parent, as the mesh
- * is interpreted as the object's data, and the parent IXform as its
- * Blender object). The pointer is the AbcObjectReader that represents
- * the IObject parameter.
- *
- * 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 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;
-#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) {
- for (AbcObjectReader *child_reader : nonclaiming_child_readers) {
- child_reader->parent_reader = reader;
- }
- for (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];
- for (AbcObjectReader *child_reader : nonclaiming_child_readers) {
- child_reader->parent_reader = claiming_child;
- }
- for (AbcObjectReader *child_reader : assign_as_parent) {
- child_reader->parent_reader = claiming_child;
- }
- /* Claiming children should have our parent set as their parent. */
- for (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. */
- for (AbcObjectReader *child_reader : claiming_child_readers) {
- r_assign_as_parent.push_back(child_reader);
- }
- for (AbcObjectReader *child_reader : nonclaiming_child_readers) {
- r_assign_as_parent.push_back(child_reader);
- }
- for (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,
-};
-
-struct ImportJobData {
- Main *bmain;
- Scene *scene;
- ViewLayer *view_layer;
- wmWindowManager *wm;
-
- char filename[1024];
- ImportSettings settings;
-
- ArchiveReader *archive;
- std::vector<AbcObjectReader *> readers;
-
- short *stop;
- short *do_update;
- float *progress;
-
- 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");
-
- ImportJobData *data = static_cast<ImportJobData *>(user_data);
-
- data->stop = stop;
- data->do_update = do_update;
- data->progress = progress;
-
- WM_set_locked_interface(data->wm, true);
-
- ArchiveReader *archive = new ArchiveReader(data->bmain, data->filename);
-
- if (!archive->valid()) {
-#ifndef WITH_ALEMBIC_HDF5
- data->error_code = archive->is_hdf5() ? ABC_UNSUPPORTED_HDF5 : ABC_ARCHIVE_FAIL;
-#else
- 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;
- STRNCPY(cache_file->filepath, data->filename);
-
- data->archive = archive;
- 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 cancellation. */
- 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->archive;
- 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)
-{
- /* 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;
- job->archive = NULL;
-
- 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;
- }
-
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
-
- bool is_constant = false;
- abc_reader->read_matrix(r_mat, time, scale, is_constant);
-}
-
-/* ************************************************************************** */
-
-static AbcObjectReader *get_abc_reader(CacheReader *reader, Object *ob, const char **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;
- }
-
- return abc_reader;
-}
-
-static ISampleSelector sample_selector_for_time(float time)
-{
- /* kFloorIndex is used to be compatible with non-interpolating
- * properties; they use the floor. */
- return ISampleSelector(time, ISampleSelector::kFloorIndex);
-}
-
-Mesh *ABC_read_mesh(CacheReader *reader,
- Object *ob,
- Mesh *existing_mesh,
- const float time,
- const char **err_str,
- int read_flag)
-{
- AbcObjectReader *abc_reader = get_abc_reader(reader, ob, err_str);
- if (abc_reader == NULL) {
- return NULL;
- }
-
- ISampleSelector sample_sel = sample_selector_for_time(time);
- return abc_reader->read_mesh(existing_mesh, sample_sel, read_flag, err_str);
-}
-
-bool ABC_mesh_topology_changed(
- CacheReader *reader, Object *ob, Mesh *existing_mesh, const float time, const char **err_str)
-{
- AbcObjectReader *abc_reader = get_abc_reader(reader, ob, err_str);
- if (abc_reader == NULL) {
- return false;
- }
-
- ISampleSelector sample_sel = sample_selector_for_time(time);
- return abc_reader->topology_changed(existing_mesh, sample_sel);
-}
-
-/* ************************************************************************** */
-
-void CacheReader_free(CacheReader *reader)
-{
- AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
- abc_reader->decref();
-
- if (abc_reader->refcount() == 0) {
- delete abc_reader;
- }
-}
-
-void CacheReader_incref(CacheReader *reader)
-{
- 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)
-{
- if (object_path[0] == '\0') {
- return reader;
- }
-
- ArchiveReader *archive = archive_from_handle(handle);
-
- if (!archive || !archive->valid()) {
- return reader;
- }
-
- IObject iobject;
- find_iobject(archive->getTop(), iobject, object_path);
-
- 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();
-
- return reinterpret_cast<CacheReader *>(abc_reader);
-}