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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/io/alembic')
-rw-r--r--source/blender/io/alembic/ABC_alembic.h30
-rw-r--r--source/blender/io/alembic/exporter/abc_export_capi.cc18
-rw-r--r--source/blender/io/alembic/exporter/abc_subdiv_disabler.cc4
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_hair.cc14
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_mesh.cc52
-rw-r--r--source/blender/io/alembic/intern/abc_customdata.cc13
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.cc100
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.h9
-rw-r--r--source/blender/io/alembic/intern/abc_reader_object.cc6
-rw-r--r--source/blender/io/alembic/intern/abc_reader_points.cc2
-rw-r--r--source/blender/io/alembic/intern/alembic_capi.cc50
11 files changed, 164 insertions, 134 deletions
diff --git a/source/blender/io/alembic/ABC_alembic.h b/source/blender/io/alembic/ABC_alembic.h
index ded3258ff18..05025861857 100644
--- a/source/blender/io/alembic/ABC_alembic.h
+++ b/source/blender/io/alembic/ABC_alembic.h
@@ -60,6 +60,28 @@ struct AlembicExportParams {
float global_scale;
};
+struct AlembicImportParams {
+ /* Multiplier for the cached data scale. Mostly useful if the data is stored in a different unit
+ * as what Blender expects (e.g. centimeters instead of meters). */
+ float global_scale;
+
+ /* Number of consecutive files to expect if the cached animation is split in a sequence. */
+ int sequence_len;
+ /* Start frame of the sequence, offset from 0. */
+ int sequence_offset;
+ /* True if the cache is split in multiple files. */
+ bool is_sequence;
+
+ /* True if the importer should set the current scene's start and end frame based on the start and
+ * end frames of the cached animation. */
+ bool set_frame_range;
+ /* True if imported meshes should be validated. Error messages are sent to the console. */
+ bool validate_meshes;
+ /* True if a cache reader should be added regardless of whether there is animated data in the
+ * cached file. */
+ bool always_add_cache_reader;
+};
+
/* The ABC_export and ABC_import functions both take a as_background_job
* parameter, and return a boolean.
*
@@ -78,13 +100,7 @@ bool ABC_export(struct Scene *scene,
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 always_add_cache_reader,
+ const struct AlembicImportParams *params,
bool as_background_job);
struct CacheArchiveHandle *ABC_create_handle(struct Main *bmain,
diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc b/source/blender/io/alembic/exporter/abc_export_capi.cc
index edaf53b3efa..dfca89e2c6d 100644
--- a/source/blender/io/alembic/exporter/abc_export_capi.cc
+++ b/source/blender/io/alembic/exporter/abc_export_capi.cc
@@ -24,6 +24,7 @@
#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
+#include "BLI_timeit.hh"
#include "WM_api.h"
#include "WM_types.h"
@@ -44,6 +45,7 @@ struct ExportJobData {
bool was_canceled;
bool export_ok;
+ blender::timeit::TimePoint start_time;
};
namespace blender::io::alembic {
@@ -59,6 +61,14 @@ static void build_depsgraph(Depsgraph *depsgraph, const bool visible_objects_onl
}
}
+static void report_job_duration(const ExportJobData *data)
+{
+ blender::timeit::Nanoseconds duration = blender::timeit::Clock::now() - data->start_time;
+ std::cout << "Alembic export of '" << data->filename << "' took ";
+ blender::timeit::print_duration(duration);
+ std::cout << '\n';
+}
+
static void export_startjob(void *customdata,
/* Cannot be const, this function implements wm_jobs_start_callback.
* NOLINTNEXTLINE: readability-non-const-parameter. */
@@ -68,6 +78,7 @@ static void export_startjob(void *customdata,
{
ExportJobData *data = static_cast<ExportJobData *>(customdata);
data->was_canceled = false;
+ data->start_time = blender::timeit::Clock::now();
G.is_rendering = true;
WM_set_locked_interface(data->wm, true);
@@ -85,7 +96,7 @@ static void export_startjob(void *customdata,
/* For restoring the current frame after exporting animation is done. */
Scene *scene = DEG_get_input_scene(data->depsgraph);
- const int orig_frame = CFRA;
+ const int orig_frame = scene->r.cfra;
const bool export_animation = (data->params.frame_start != data->params.frame_end);
/* Create the Alembic archive. */
@@ -154,8 +165,8 @@ static void export_startjob(void *customdata,
iter.release_writers();
/* Finish up by going back to the keyframe that was current before we started. */
- if (CFRA != orig_frame) {
- CFRA = orig_frame;
+ if (scene->r.cfra != orig_frame) {
+ scene->r.cfra = orig_frame;
BKE_scene_graph_update_for_newframe(data->depsgraph);
}
@@ -177,6 +188,7 @@ static void export_endjob(void *customdata)
G.is_rendering = false;
WM_set_locked_interface(data->wm, false);
+ report_job_duration(data);
}
} // namespace blender::io::alembic
diff --git a/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc b/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
index 514ce389e36..712b04f3992 100644
--- a/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
+++ b/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc
@@ -14,6 +14,7 @@
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
+#include "BKE_layer.h"
#include "BKE_modifier.h"
namespace blender::io::alembic {
@@ -34,7 +35,8 @@ void SubdivModifierDisabler::disable_modifiers()
Scene *scene = DEG_get_input_scene(depsgraph_);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph_);
- LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
+ BKE_view_layer_synced_ensure(scene, view_layer);
+ LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
Object *object = base->object;
if (object->type != OB_MESH) {
diff --git a/source/blender/io/alembic/exporter/abc_writer_hair.cc b/source/blender/io/alembic/exporter/abc_writer_hair.cc
index d12eaf07e29..4f09aee3ea9 100644
--- a/source/blender/io/alembic/exporter/abc_writer_hair.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_hair.cc
@@ -18,6 +18,7 @@
#include "BKE_customdata.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_legacy_convert.h"
#include "BKE_mesh_runtime.h"
#include "BKE_particle.h"
@@ -119,9 +120,9 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context,
float inv_mat[4][4];
invert_m4_m4_safe(inv_mat, context.object->obmat);
- MTFace *mtface = mesh->mtface;
- MFace *mface = mesh->mface;
- MVert *mverts = mesh->mvert;
+ MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE);
+ MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ const MVert *mverts = BKE_mesh_verts(mesh);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
if ((!mtface || !mface) && !uv_warning_shown_) {
@@ -242,8 +243,9 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context,
float inv_mat[4][4];
invert_m4_m4_safe(inv_mat, context.object->obmat);
- MTFace *mtface = mesh->mtface;
- MVert *mverts = mesh->mvert;
+ MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE);
+ const MVert *mverts = BKE_mesh_verts(mesh);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
ParticleSystem *psys = context.particle_system;
@@ -268,7 +270,7 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context,
continue;
}
- MFace *face = &mesh->mface[num];
+ MFace *face = &mface[num];
MTFace *tface = mtface + num;
float r_uv[2], tmpnor[3], mapfw[4], vec[3];
diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
index 07b185ffd64..7d38cd1ec88 100644
--- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
@@ -12,6 +12,7 @@
#include "BLI_math_vector.h"
#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_lib_id.h"
#include "BKE_material.h"
@@ -175,8 +176,8 @@ void ABCGenericMeshWriter::do_write(HierarchyContext &context)
m_custom_data_config.pack_uvs = args_.export_params->packuv;
m_custom_data_config.mesh = mesh;
- m_custom_data_config.mpoly = mesh->mpoly;
- m_custom_data_config.mloop = mesh->mloop;
+ m_custom_data_config.mpoly = mesh->polys_for_write().data();
+ m_custom_data_config.mloop = mesh->loops_for_write().data();
m_custom_data_config.totpoly = mesh->totpoly;
m_custom_data_config.totloop = mesh->totloop;
m_custom_data_config.totvert = mesh->totvert;
@@ -366,7 +367,7 @@ bool ABCGenericMeshWriter::get_velocities(struct Mesh *mesh, std::vector<Imath::
{
/* Export velocity attribute output by fluid sim, sequence cache modifier
* and geometry nodes. */
- CustomDataLayer *velocity_layer = BKE_id_attribute_find(
+ const CustomDataLayer *velocity_layer = BKE_id_attribute_find(
&mesh->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT);
if (velocity_layer == nullptr) {
@@ -390,12 +391,12 @@ void ABCGenericMeshWriter::get_geo_groups(Object *object,
struct Mesh *mesh,
std::map<std::string, std::vector<int32_t>> &geo_groups)
{
- const int num_poly = mesh->totpoly;
- MPoly *polygons = mesh->mpoly;
+ const bke::AttributeAccessor attributes = mesh->attributes();
+ const VArraySpan<int> material_indices = attributes.lookup_or_default<int>(
+ "material_index", ATTR_DOMAIN_FACE, 0);
- for (int i = 0; i < num_poly; i++) {
- MPoly &current_poly = polygons[i];
- short mnr = current_poly.mat_nr;
+ for (const int i : material_indices.index_range()) {
+ short mnr = material_indices[i];
Material *mat = BKE_object_material_get(object, mnr + 1);
@@ -435,8 +436,7 @@ static void get_vertices(struct Mesh *mesh, std::vector<Imath::V3f> &points)
points.clear();
points.resize(mesh->totvert);
- MVert *verts = mesh->mvert;
-
+ const Span<MVert> verts = mesh->verts();
for (int i = 0, e = mesh->totvert; i < e; i++) {
copy_yup_from_zup(points[i].getValue(), verts[i].co);
}
@@ -447,25 +447,23 @@ static void get_topology(struct Mesh *mesh,
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;
+ const Span<MPoly> polys = mesh->polys();
+ const Span<MLoop> loops = mesh->loops();
r_has_flat_shaded_poly = false;
poly_verts.clear();
loop_counts.clear();
- poly_verts.reserve(num_loops);
- loop_counts.reserve(num_poly);
+ poly_verts.reserve(loops.size());
+ loop_counts.reserve(polys.size());
/* NOTE: data needs to be written in the reverse order. */
- for (int i = 0; i < num_poly; i++) {
- MPoly &poly = mpoly[i];
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[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);
+ const MLoop *loop = &loops[poly.loopstart + (poly.totloop - 1)];
for (int j = 0; j < poly.totloop; j++, loop--) {
poly_verts.push_back(loop->v);
@@ -484,14 +482,14 @@ static void get_edge_creases(struct Mesh *mesh,
lengths.clear();
sharpnesses.clear();
- MEdge *edge = mesh->medge;
+ const Span<MEdge> edges = mesh->edges();
- for (int i = 0, e = mesh->totedge; i < e; i++) {
- const float sharpness = static_cast<float>(edge[i].crease) * factor;
+ for (const int i : edges.index_range()) {
+ const float sharpness = static_cast<float>(edges[i].crease) * factor;
if (sharpness != 0.0f) {
- indices.push_back(edge[i].v1);
- indices.push_back(edge[i].v2);
+ indices.push_back(edges[i].v1);
+ indices.push_back(edges[i].v2);
sharpnesses.push_back(sharpness);
}
}
@@ -543,8 +541,10 @@ static void get_loop_normals(struct Mesh *mesh,
/* 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++) {
+ const Span<MPoly> polys = mesh->polys();
+
+ for (const int i : polys.index_range()) {
+ const MPoly *mp = &polys[i];
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]);
diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc
index 2820a128072..5494bfaa6e8 100644
--- a/source/blender/io/alembic/intern/abc_customdata.cc
+++ b/source/blender/io/alembic/intern/abc_customdata.cc
@@ -57,7 +57,7 @@ static void get_uvs(const CDStreamConfig &config,
}
const int num_poly = config.totpoly;
- MPoly *polygons = config.mpoly;
+ MPoly *mpoly = config.mpoly;
MLoop *mloop = config.mloop;
if (!config.pack_uvs) {
@@ -67,7 +67,7 @@ static void get_uvs(const CDStreamConfig &config,
/* Iterate in reverse order to match exported polygons. */
for (int i = 0; i < num_poly; i++) {
- MPoly &current_poly = polygons[i];
+ MPoly &current_poly = mpoly[i];
const MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
for (int j = 0; j < current_poly.totloop; j++, count++) {
@@ -85,7 +85,7 @@ static void get_uvs(const CDStreamConfig &config,
int idx_count = 0;
for (int i = 0; i < num_poly; i++) {
- MPoly &current_poly = polygons[i];
+ MPoly &current_poly = mpoly[i];
MLoop *looppoly = mloop + current_poly.loopstart + current_poly.totloop;
const MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
@@ -540,7 +540,7 @@ void read_generated_coordinates(const ICompoundProperty &prop,
cd_data = CustomData_get_layer(&mesh->vdata, CD_ORCO);
}
else {
- cd_data = CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_CALLOC, nullptr, totvert);
+ cd_data = CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_CONSTRUCT, nullptr, totvert);
}
float(*orcodata)[3] = static_cast<float(*)[3]>(cd_data);
@@ -564,7 +564,6 @@ void read_custom_data(const std::string &iobject_full_name,
}
int num_uvs = 0;
- int num_colors = 0;
const size_t num_props = prop.getNumProperties();
@@ -583,10 +582,6 @@ void read_custom_data(const std::string &iobject_full_name,
/* 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/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index d8c48357fc0..c07aaa37988 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -20,11 +20,13 @@
#include "DNA_object_types.h"
#include "BLI_compiler_compat.h"
+#include "BLI_edgehash.h"
#include "BLI_index_range.hh"
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
-#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
+#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
@@ -77,10 +79,8 @@ static void assign_materials(Main *bmain,
const std::map<std::string, int> &mat_index_map)
{
std::map<std::string, int>::const_iterator it;
- for (it = mat_index_map.begin(); it != mat_index_map.end(); ++it) {
- if (!BKE_object_material_slot_add(bmain, ob)) {
- return;
- }
+ if (mat_index_map.size() > MAXMAT) {
+ return;
}
std::map<std::string, Material *> matname_to_material = build_material_map(bmain);
@@ -94,13 +94,17 @@ static void assign_materials(Main *bmain,
mat_iter = matname_to_material.find(mat_name);
if (mat_iter == matname_to_material.end()) {
assigned_mat = BKE_material_add(bmain, mat_name.c_str());
+ id_us_min(&assigned_mat->id);
matname_to_material[mat_name] = assigned_mat;
}
else {
assigned_mat = mat_iter->second;
}
- BKE_object_material_assign(bmain, ob, assigned_mat, mat_index, BKE_MAT_ASSIGN_OBDATA);
+ BKE_object_material_assign_single_obdata(bmain, ob, assigned_mat, mat_index);
+ }
+ if (ob->totcol > 0) {
+ ob->actcol = 1;
}
}
@@ -131,8 +135,6 @@ static void read_mverts_interp(MVert *mverts,
interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), static_cast<float>(weight));
copy_zup_from_yup(mvert.co, tmp);
-
- mvert.bweight = 0;
}
}
@@ -153,13 +155,12 @@ static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data)
void read_mverts(Mesh &mesh, const P3fArraySamplePtr positions, const N3fArraySamplePtr normals)
{
+ MutableSpan<MVert> verts = mesh.verts_for_write();
for (int i = 0; i < positions->size(); i++) {
- MVert &mvert = mesh.mvert[i];
+ MVert &mvert = verts[i];
Imath::V3f pos_in = (*positions)[i];
copy_zup_from_yup(mvert.co, pos_in.getValue());
-
- mvert.bweight = 0;
}
if (normals) {
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(&mesh);
@@ -270,7 +271,7 @@ static void process_loop_normals(CDStreamConfig &config, const N3fArraySamplePtr
float(*lnors)[3] = static_cast<float(*)[3]>(
MEM_malloc_arrayN(loop_count, sizeof(float[3]), "ABC::FaceNormals"));
- MPoly *mpoly = mesh->mpoly;
+ MPoly *mpoly = mesh->polys_for_write().data();
const N3fArraySample &loop_normals = *loop_normals_ptr;
int abc_index = 0;
for (int i = 0, e = mesh->totpoly; i < e; i++, mpoly++) {
@@ -305,7 +306,7 @@ static void process_vertex_normals(CDStreamConfig &config,
}
config.mesh->flag |= ME_AUTOSMOOTH;
- BKE_mesh_set_custom_normals_from_vertices(config.mesh, vnors);
+ BKE_mesh_set_custom_normals_from_verts(config.mesh, vnors);
MEM_freeN(vnors);
}
@@ -392,7 +393,7 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type)
/* Create a new layer. */
int numloops = mesh->totloop;
cd_ptr = CustomData_add_layer_named(
- &mesh->ldata, cd_data_type, CD_DEFAULT, nullptr, numloops, name);
+ &mesh->ldata, cd_data_type, CD_SET_DEFAULT, nullptr, numloops, name);
return cd_ptr;
}
@@ -515,13 +516,10 @@ static void read_mesh_sample(const std::string &iobject_full_name,
CDStreamConfig get_config(Mesh *mesh, const bool use_vertex_interpolation)
{
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.mvert = mesh->verts_for_write().data();
+ config.mloop = mesh->loops_for_write().data();
+ config.mpoly = mesh->polys_for_write().data();
config.totvert = mesh->totvert;
config.totloop = mesh->totloop;
config.totpoly = mesh->totpoly;
@@ -617,11 +615,7 @@ void AbcMeshReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, "", 0.0f, nullptr);
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. */
- uint16_t autosmooth = (read_mesh->flag & ME_AUTOSMOOTH);
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_EVERYTHING, true);
- mesh->flag |= autosmooth;
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object);
}
if (m_settings->validate_meshes) {
@@ -767,7 +761,11 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
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);
+ bke::MutableAttributeAccessor attributes = new_mesh->attributes_for_write();
+ bke::SpanAttributeWriter<int> material_indices =
+ attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
+ assign_facesets_to_material_indices(sample_sel, material_indices.span, mat_map);
+ material_indices.finish();
}
return new_mesh;
@@ -776,10 +774,9 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_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)
+void AbcMeshReader::assign_facesets_to_material_indices(const ISampleSelector &sample_sel,
+ MutableSpan<int> material_indices,
+ std::map<std::string, int> &r_mat_map)
{
std::vector<std::string> face_sets;
m_schema.getFaceSetNames(face_sets);
@@ -812,13 +809,12 @@ void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
for (size_t l = 0; l < num_group_faces; l++) {
size_t pos = (*group_faces)[l];
- if (pos >= totpoly) {
+ if (pos >= material_indices.size()) {
std::cerr << "Faceset overflow on " << faceset.getName() << '\n';
break;
}
- MPoly &poly = mpoly[pos];
- poly.mat_nr = assigned_mat - 1;
+ material_indices[pos] = assigned_mat - 1;
}
}
}
@@ -826,25 +822,16 @@ void AbcMeshReader::assign_facesets_to_mpoly(const ISampleSelector &sample_sel,
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);
+ bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
+ bke::SpanAttributeWriter<int> material_indices =
+ attributes.lookup_or_add_for_write_only_span<int>("material_index", ATTR_DOMAIN_FACE);
+ assign_facesets_to_material_indices(sample_sel, material_indices.span, mat_map);
+ material_indices.finish();
utils::assign_materials(bmain, m_object, mat_map);
}
/* ************************************************************************** */
-BLI_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 nullptr;
-}
-
static void read_subd_sample(const std::string &iobject_full_name,
ImportSettings *settings,
const ISubDSchema &schema,
@@ -904,7 +891,7 @@ static void read_vertex_creases(Mesh *mesh,
}
float *vertex_crease_data = (float *)CustomData_add_layer(
- &mesh->vdata, CD_CREASE, CD_DEFAULT, nullptr, mesh->totvert);
+ &mesh->vdata, CD_CREASE, CD_SET_DEFAULT, nullptr, mesh->totvert);
const int totvert = mesh->totvert;
for (int i = 0, v = indices->size(); i < v; ++i) {
@@ -928,8 +915,13 @@ static void read_edge_creases(Mesh *mesh,
return;
}
- MEdge *edges = mesh->medge;
- int totedge = mesh->totedge;
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+ EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, edges.size());
+
+ for (const int i : edges.index_range()) {
+ MEdge *edge = &edges[i];
+ BLI_edgehash_insert(edge_hash, edge->v1, edge->v2, edge);
+ }
for (int i = 0, s = 0, e = indices->size(); i < e; i += 2, s++) {
int v1 = (*indices)[i];
@@ -941,9 +933,9 @@ static void read_edge_creases(Mesh *mesh,
std::swap(v1, v2);
}
- MEdge *edge = find_edge(edges, totedge, v1, v2);
+ MEdge *edge = static_cast<MEdge *>(BLI_edgehash_lookup(edge_hash, v1, v2));
if (edge == nullptr) {
- edge = find_edge(edges, totedge, v2, v1);
+ edge = static_cast<MEdge *>(BLI_edgehash_lookup(edge_hash, v2, v1));
}
if (edge) {
@@ -951,6 +943,8 @@ static void read_edge_creases(Mesh *mesh,
}
}
+ BLI_edgehash_free(edge_hash, nullptr);
+
mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
}
@@ -1001,7 +995,7 @@ void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
Mesh *read_mesh = this->read_mesh(mesh, sample_sel, MOD_MESHSEQ_READ_ALL, "", 0.0f, nullptr);
if (read_mesh != mesh) {
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_EVERYTHING, true);
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object);
}
ISubDSchema::Sample sample;
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.h b/source/blender/io/alembic/intern/abc_reader_mesh.h
index f97525297b7..151f4d82226 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.h
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.h
@@ -5,6 +5,8 @@
* \ingroup balembic
*/
+#include "BLI_span.hh"
+
#include "abc_customdata.h"
#include "abc_reader_object.h"
@@ -38,10 +40,9 @@ class AbcMeshReader final : public AbcObjectReader {
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);
+ void assign_facesets_to_material_indices(const Alembic::Abc::ISampleSelector &sample_sel,
+ MutableSpan<int> material_indices,
+ std::map<std::string, int> &r_mat_map);
};
class AbcSubDReader final : public AbcObjectReader {
diff --git a/source/blender/io/alembic/intern/abc_reader_object.cc b/source/blender/io/alembic/intern/abc_reader_object.cc
index a698eeca8f1..db056c0eef6 100644
--- a/source/blender/io/alembic/intern/abc_reader_object.cc
+++ b/source/blender/io/alembic/intern/abc_reader_object.cc
@@ -218,12 +218,12 @@ Alembic::AbcGeom::IXform AbcObjectReader::xform()
void AbcObjectReader::read_matrix(float r_mat[4][4] /* local matrix */,
const chrono_t time,
const float scale,
- bool &is_constant)
+ bool &r_is_constant)
{
IXform ixform = xform();
if (!ixform) {
unit_m4(r_mat);
- is_constant = true;
+ r_is_constant = true;
return;
}
@@ -254,7 +254,7 @@ void AbcObjectReader::read_matrix(float r_mat[4][4] /* local matrix */,
mul_m4_m4m4(r_mat, scale_mat, r_mat);
}
- is_constant = schema.isConstant();
+ r_is_constant = schema.isConstant();
}
void AbcObjectReader::addCacheModifier()
diff --git a/source/blender/io/alembic/intern/abc_reader_points.cc b/source/blender/io/alembic/intern/abc_reader_points.cc
index ff189bc92dc..54ae71ad7a6 100644
--- a/source/blender/io/alembic/intern/abc_reader_points.cc
+++ b/source/blender/io/alembic/intern/abc_reader_points.cc
@@ -69,7 +69,7 @@ void AbcPointsReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSel
Mesh *read_mesh = this->read_mesh(mesh, sample_sel, 0, "", 0.0f, nullptr);
if (read_mesh != mesh) {
- BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object, &CD_MASK_MESH, true);
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, m_object);
}
if (m_settings->validate_meshes) {
diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc
index 1fb535a57f2..11c26fd2f72 100644
--- a/source/blender/io/alembic/intern/alembic_capi.cc
+++ b/source/blender/io/alembic/intern/alembic_capi.cc
@@ -50,6 +50,7 @@
#include "BLI_math.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
+#include "BLI_timeit.hh"
#include "WM_api.h"
#include "WM_types.h"
@@ -434,8 +435,17 @@ struct ImportJobData {
bool was_cancelled;
bool import_ok;
bool is_background_job;
+ blender::timeit::TimePoint start_time;
};
+static void report_job_duration(const ImportJobData *data)
+{
+ blender::timeit::Nanoseconds duration = blender::timeit::Clock::now() - data->start_time;
+ std::cout << "Alembic import of '" << data->filename << "' took ";
+ blender::timeit::print_duration(duration);
+ std::cout << '\n';
+}
+
static void import_startjob(void *user_data, short *stop, short *do_update, float *progress)
{
SCOPE_TIMER("Alembic import, objects reading and creation");
@@ -445,6 +455,7 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
data->stop = stop;
data->do_update = do_update;
data->progress = progress;
+ data->start_time = blender::timeit::Clock::now();
WM_set_locked_interface(data->wm, true);
@@ -526,14 +537,14 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
Scene *scene = data->scene;
if (data->settings.is_sequence) {
- SFRA = data->settings.sequence_offset;
- EFRA = SFRA + (data->settings.sequence_len - 1);
- CFRA = SFRA;
+ scene->r.sfra = data->settings.sequence_offset;
+ scene->r.efra = scene->r.sfra + (data->settings.sequence_len - 1);
+ scene->r.cfra = scene->r.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;
+ scene->r.sfra = static_cast<int>(round(min_time * FPS));
+ scene->r.efra = static_cast<int>(round(max_time * FPS));
+ scene->r.cfra = scene->r.sfra;
}
}
@@ -590,9 +601,10 @@ static void import_endjob(void *user_data)
else {
Base *base;
LayerCollection *lc;
+ const Scene *scene = data->scene;
ViewLayer *view_layer = data->view_layer;
- BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_deselect_all(scene, view_layer);
lc = BKE_layer_collection_get_active(view_layer);
@@ -605,6 +617,7 @@ static void import_endjob(void *user_data)
/* Sync the collection, and do view layer operations. */
BKE_layer_collection_resync_allow();
BKE_main_collection_sync(data->bmain);
+ BKE_view_layer_synced_ensure(scene, view_layer);
for (AbcObjectReader *reader : data->readers) {
Object *ob = reader->object();
base = BKE_view_layer_base_find(view_layer, ob);
@@ -649,6 +662,7 @@ static void import_endjob(void *user_data)
}
WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);
+ report_job_duration(data);
}
static void import_freejob(void *user_data)
@@ -660,13 +674,7 @@ static void import_freejob(void *user_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 always_add_cache_reader,
+ const AlembicImportParams *params,
bool as_background_job)
{
/* Using new here since MEM_* functions do not call constructor to properly initialize data. */
@@ -679,13 +687,13 @@ bool ABC_import(bContext *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->settings.always_add_cache_reader = always_add_cache_reader;
+ job->settings.scale = params->global_scale;
+ job->settings.is_sequence = params->is_sequence;
+ job->settings.set_frame_range = params->set_frame_range;
+ job->settings.sequence_len = params->sequence_len;
+ job->settings.sequence_offset = params->sequence_offset;
+ job->settings.validate_meshes = params->validate_meshes;
+ job->settings.always_add_cache_reader = params->always_add_cache_reader;
job->error_code = ABC_NO_ERROR;
job->was_cancelled = false;
job->archive = nullptr;