diff options
Diffstat (limited to 'source/blender/alembic/intern')
22 files changed, 217 insertions, 102 deletions
diff --git a/source/blender/alembic/intern/abc_camera.cc b/source/blender/alembic/intern/abc_camera.cc index 16416205983..aa5d77ce4ec 100644 --- a/source/blender/alembic/intern/abc_camera.cc +++ b/source/blender/alembic/intern/abc_camera.cc @@ -49,12 +49,13 @@ using Alembic::AbcGeom::kWrapExisting; /* ************************************************************************** */ -AbcCameraWriter::AbcCameraWriter(Scene *scene, +AbcCameraWriter::AbcCameraWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) { OCamera camera(parent->alembicXform(), m_name, m_time_sampling); m_camera_schema = camera.getSchema(); diff --git a/source/blender/alembic/intern/abc_camera.h b/source/blender/alembic/intern/abc_camera.h index 16c5cccd5ea..772b7a6aec6 100644 --- a/source/blender/alembic/intern/abc_camera.h +++ b/source/blender/alembic/intern/abc_camera.h @@ -35,7 +35,8 @@ class AbcCameraWriter : public AbcObjectWriter { Alembic::AbcGeom::OFloatProperty m_eye_separation; public: - AbcCameraWriter(Scene *scene, + AbcCameraWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc index f73fe957fea..5328c471093 100644 --- a/source/blender/alembic/intern/abc_curves.cc +++ b/source/blender/alembic/intern/abc_curves.cc @@ -71,12 +71,13 @@ using Alembic::AbcGeom::OV2fGeomParam; /* ************************************************************************** */ -AbcCurveWriter::AbcCurveWriter(Scene *scene, +AbcCurveWriter::AbcCurveWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) { OCurves curves(parent->alembicXform(), m_name, m_time_sampling); m_schema = curves.getSchema(); diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h index a9231f947b2..73cc8b35e27 100644 --- a/source/blender/alembic/intern/abc_curves.h +++ b/source/blender/alembic/intern/abc_curves.h @@ -36,7 +36,8 @@ class AbcCurveWriter : public AbcObjectWriter { Alembic::AbcGeom::OCurvesSchema::Sample m_sample; public: - AbcCurveWriter(Scene *scene, + AbcCurveWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc index 1d2bc689027..d6e7a80d174 100644 --- a/source/blender/alembic/intern/abc_customdata.cc +++ b/source/blender/alembic/intern/abc_customdata.cc @@ -252,7 +252,31 @@ static void read_uvs(const CDStreamConfig &config, void *data, } } -static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, +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_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; + } + + 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) @@ -303,6 +327,8 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, size_t face_index = 0; size_t color_index; + bool bounds_warning_given = false; + for (int i = 0; i < config.totpoly; ++i) { MPoly *poly = &mpolys[i]; MCol *cface = &cfaces[poly->loopstart + poly->totloop]; @@ -311,9 +337,14 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, for (int j = 0; j < poly->totloop; ++j, ++face_index) { --cface; --mloop; - color_index = is_facevarying ? face_index : mloop->v; if (use_c3f_ptr) { + color_index = mcols_out_of_bounds_check( + is_facevarying ? face_index : mloop->v, + c3f_ptr->size(), + iobject_full_name, prop_header, + bounds_warning_given); + const Imath::C3f &color = (*c3f_ptr)[color_index]; cface->a = FTOCHAR(color[0]); cface->r = FTOCHAR(color[1]); @@ -321,6 +352,12 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams, cface->b = 255; } else { + color_index = mcols_out_of_bounds_check( + is_facevarying ? face_index : mloop->v, + c4f_ptr->size(), + iobject_full_name, prop_header, + bounds_warning_given); + const Imath::C4f &color = (*c4f_ptr)[color_index]; cface->a = FTOCHAR(color[0]); cface->r = FTOCHAR(color[1]); @@ -356,7 +393,10 @@ static void read_custom_data_uvs(const ICompoundProperty &prop, read_uvs(config, cd_data, sample.getVals(), sample.getIndices()); } -void read_custom_data(const ICompoundProperty &prop, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss) +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; @@ -386,7 +426,7 @@ void read_custom_data(const ICompoundProperty &prop, const CDStreamConfig &confi continue; } - read_custom_data_mcols(prop, prop_header, config, iss); + read_custom_data_mcols(iobject_full_name, prop, prop_header, config, iss); continue; } } diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h index 9e671fde386..b3072a2c9f7 100644 --- a/source/blender/alembic/intern/abc_customdata.h +++ b/source/blender/alembic/intern/abc_customdata.h @@ -96,7 +96,8 @@ void write_custom_data(const OCompoundProperty &prop, CustomData *data, int data_type); -void read_custom_data(const ICompoundProperty &prop, +void read_custom_data(const std::string & iobject_full_name, + const ICompoundProperty &prop, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss); diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 680913e45ea..df2bc52aa2c 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -163,11 +163,12 @@ static bool export_object(const ExportSettings * const settings, const Base * co /* ************************************************************************** */ -AbcExporter::AbcExporter(Scene *scene, const char *filename, ExportSettings &settings) +AbcExporter::AbcExporter(EvaluationContext *eval_ctx, Scene *scene, const char *filename, ExportSettings &settings) : m_settings(settings) , m_filename(filename) , m_trans_sampling_index(0) , m_shape_sampling_index(0) + , m_eval_ctx(eval_ctx) , m_scene(scene) , m_writer(NULL) {} @@ -383,7 +384,7 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Base *ob_base, O } if (object_type_is_exportable(ob)) { - createTransformWriter(ob, parent, dupliObParent); + createTransformWriter(eval_ctx, ob, parent, dupliObParent); } ListBase *lb = object_duplilist(eval_ctx, m_scene, ob); @@ -415,7 +416,7 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Base *ob_base, O free_object_duplilist(lb); } -AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupliObParent) +AbcTransformWriter * AbcExporter::createTransformWriter(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent) { /* An object should not be its own parent, or we'll get infinite loops. */ BLI_assert(ob != parent); @@ -450,29 +451,29 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare * return the parent's AbcTransformWriter pointer. */ if (parent->parent) { if (parent == dupliObParent) { - parent_writer = createTransformWriter(parent, parent->parent, NULL); + parent_writer = createTransformWriter(eval_ctx, parent, parent->parent, NULL); } else { - parent_writer = createTransformWriter(parent, parent->parent, dupliObParent); + parent_writer = createTransformWriter(eval_ctx, parent, parent->parent, dupliObParent); } } else if (parent == dupliObParent) { if (dupliObParent->parent == NULL) { - parent_writer = createTransformWriter(parent, NULL, NULL); + parent_writer = createTransformWriter(eval_ctx, parent, NULL, NULL); } else { - parent_writer = createTransformWriter(parent, dupliObParent->parent, dupliObParent->parent); + parent_writer = createTransformWriter(eval_ctx, parent, dupliObParent->parent, dupliObParent->parent); } } else { - parent_writer = createTransformWriter(parent, dupliObParent, dupliObParent); + parent_writer = createTransformWriter(eval_ctx, parent, dupliObParent, dupliObParent); } BLI_assert(parent_writer); alembic_parent = parent_writer->alembicXform(); } - my_writer = new AbcTransformWriter(ob, alembic_parent, parent_writer, + my_writer = new AbcTransformWriter(eval_ctx, ob, alembic_parent, parent_writer, m_trans_sampling_index, m_settings); /* When flattening, the matrix of the dupliobject has to be added. */ @@ -540,10 +541,10 @@ void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *x if (m_settings.export_hair && psys->part->type == PART_HAIR) { m_settings.export_child_hairs = true; - m_shapes.push_back(new AbcHairWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); + m_shapes.push_back(new AbcHairWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); } else if (m_settings.export_particles && psys->part->type == PART_EMITTER) { - m_shapes.push_back(new AbcPointsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); + m_shapes.push_back(new AbcPointsWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); } } } @@ -583,7 +584,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent) return; } - m_shapes.push_back(new AbcMeshWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings)); + m_shapes.push_back(new AbcMeshWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings)); break; } case OB_SURF: @@ -594,7 +595,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent) return; } - m_shapes.push_back(new AbcNurbsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings)); + m_shapes.push_back(new AbcNurbsWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings)); break; } case OB_CURVE: @@ -605,7 +606,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent) return; } - m_shapes.push_back(new AbcCurveWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings)); + m_shapes.push_back(new AbcCurveWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings)); break; } case OB_CAMERA: @@ -613,7 +614,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent) Camera *cam = static_cast<Camera *>(ob->data); if (cam->type == CAM_PERSP) { - m_shapes.push_back(new AbcCameraWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings)); + m_shapes.push_back(new AbcCameraWriter(m_eval_ctx, m_scene, ob, xform, m_shape_sampling_index, m_settings)); } break; diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h index 15158a9ef51..9c5fb69234c 100644 --- a/source/blender/alembic/intern/abc_exporter.h +++ b/source/blender/alembic/intern/abc_exporter.h @@ -90,6 +90,7 @@ class AbcExporter { unsigned int m_trans_sampling_index, m_shape_sampling_index; + EvaluationContext *m_eval_ctx; Scene *m_scene; ArchiveWriter *m_writer; @@ -101,7 +102,7 @@ class AbcExporter { std::vector<AbcObjectWriter *> m_shapes; public: - AbcExporter(Scene *scene, const char *filename, ExportSettings &settings); + AbcExporter(EvaluationContext *eval_ctx, Scene *scene, const char *filename, ExportSettings &settings); ~AbcExporter(); void operator()(Main *bmain, float &progress, bool &was_canceled); @@ -116,7 +117,7 @@ private: Alembic::Abc::TimeSamplingPtr createTimeSampling(double step); void createTransformWritersHierarchy(EvaluationContext *eval_ctx); - AbcTransformWriter * createTransformWriter(Object *ob, Object *parent, Object *dupliObParent); + AbcTransformWriter * createTransformWriter(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent); void exploreTransform(EvaluationContext *eval_ctx, Base *ob_base, Object *parent, Object *dupliObParent); void exploreObject(EvaluationContext *eval_ctx, Base *ob_base, Object *dupliObParent); void createShapeWriters(EvaluationContext *eval_ctx); diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc index 8f8ed2019d5..2579aa3cc36 100644 --- a/source/blender/alembic/intern/abc_hair.cc +++ b/source/blender/alembic/intern/abc_hair.cc @@ -49,13 +49,14 @@ using Alembic::AbcGeom::OV2fGeomParam; /* ************************************************************************** */ -AbcHairWriter::AbcHairWriter(Scene *scene, +AbcHairWriter::AbcHairWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings, ParticleSystem *psys) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) , m_uv_warning_shown(false) { m_psys = psys; @@ -76,7 +77,7 @@ void AbcHairWriter::do_write() return; } - DerivedMesh *dm = mesh_create_derived_render(m_scene, m_object, CD_MASK_MESH); + DerivedMesh *dm = mesh_create_derived_render(m_eval_ctx, m_scene, m_object, CD_MASK_MESH); DM_ensure_tessface(dm); std::vector<Imath::V3f> verts; diff --git a/source/blender/alembic/intern/abc_hair.h b/source/blender/alembic/intern/abc_hair.h index 61f5fe361f8..8190c449205 100644 --- a/source/blender/alembic/intern/abc_hair.h +++ b/source/blender/alembic/intern/abc_hair.h @@ -40,7 +40,8 @@ class AbcHairWriter : public AbcObjectWriter { bool m_uv_warning_shown; public: - AbcHairWriter(Scene *scene, + AbcHairWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc index bc62db5702c..de0ed421eb7 100644 --- a/source/blender/alembic/intern/abc_mesh.cc +++ b/source/blender/alembic/intern/abc_mesh.cc @@ -286,12 +286,13 @@ static ModifierData *get_liquid_sim_modifier(Scene *scene, Object *ob) /* ************************************************************************** */ -AbcMeshWriter::AbcMeshWriter(Scene *scene, +AbcMeshWriter::AbcMeshWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) { m_is_animated = isAnimated(); m_subsurf_mod = NULL; @@ -519,7 +520,7 @@ DerivedMesh *AbcMeshWriter::getFinalMesh() m_subsurf_mod->mode |= eModifierMode_DisableTemporary; } - DerivedMesh *dm = mesh_create_derived_render(m_scene, m_object, CD_MASK_MESH); + DerivedMesh *dm = mesh_create_derived_render(m_eval_ctx, m_scene, m_object, CD_MASK_MESH); if (m_subsurf_mod) { m_subsurf_mod->mode &= ~eModifierMode_DisableTemporary; @@ -680,17 +681,17 @@ static void assign_materials(Main *bmain, Object *ob, const std::map<std::string std::string mat_name = it->first; mat_iter = mat_map.find(mat_name.c_str()); - Material *assigned_name; + Material *assigned_mat; if (mat_iter == mat_map.end()) { - assigned_name = BKE_material_add(bmain, mat_name.c_str()); - mat_map[mat_name] = assigned_name; + assigned_mat = BKE_material_add(bmain, mat_name.c_str()); + mat_map[mat_name] = assigned_mat; } else { - assigned_name = mat_iter->second; + assigned_mat = mat_iter->second; } - assign_material(ob, assigned_name, it->second, BKE_MAT_ASSIGN_OBDATA); + assign_material(ob, assigned_mat, it->second, BKE_MAT_ASSIGN_OBDATA); } } } @@ -936,7 +937,8 @@ static void get_weight_and_index(CDStreamConfig &config, config.ceil_index = i1; } -static void read_mesh_sample(ImportSettings *settings, +static void read_mesh_sample(const std::string & iobject_full_name, + ImportSettings *settings, const IPolyMeshSchema &schema, const ISampleSelector &selector, CDStreamConfig &config, @@ -974,10 +976,9 @@ static void read_mesh_sample(ImportSettings *settings, } if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) { - read_custom_data(schema.getArbGeomParams(), config, selector); + read_custom_data(iobject_full_name, + schema.getArbGeomParams(), config, selector); } - - /* TODO: face sets */ } CDStreamConfig get_config(DerivedMesh *dm) @@ -1105,7 +1106,8 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, config.time = sample_sel.getRequestedTime(); bool do_normals = false; - read_mesh_sample(&settings, m_schema, sample_sel, config, do_normals); + read_mesh_sample(m_iobject.getFullName(), + &settings, m_schema, sample_sel, config, do_normals); if (new_dm) { /* Check if we had ME_SMOOTH flag set to restore it. */ @@ -1116,6 +1118,16 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, CDDM_calc_normals(new_dm); CDDM_calc_edges(new_dm); + /* 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_dm->getNumPolys(new_dm); + if (num_polys > 0) { + MPoly *dmpolies = new_dm->getPolyArray(new_dm); + std::map<std::string, int> mat_map; + assign_facesets_to_mpoly(sample_sel, 0, dmpolies, num_polys, mat_map); + } + return new_dm; } @@ -1126,8 +1138,11 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, return dm; } -void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start, - const ISampleSelector &sample_sel) +void AbcMeshReader::assign_facesets_to_mpoly( + const ISampleSelector &sample_sel, + size_t poly_start, + MPoly *mpoly, int totpoly, + std::map<std::string, int> & r_mat_map) { std::vector<std::string> face_sets; m_schema.getFaceSetNames(face_sets); @@ -1136,21 +1151,21 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_star return; } - std::map<std::string, int> mat_map; int current_mat = 0; for (int i = 0; i < face_sets.size(); ++i) { const std::string &grp_name = face_sets[i]; - if (mat_map.find(grp_name) == mat_map.end()) { - mat_map[grp_name] = 1 + current_mat++; + if (r_mat_map.find(grp_name) == r_mat_map.end()) { + r_mat_map[grp_name] = 1 + current_mat++; } - const int assigned_mat = mat_map[grp_name]; + 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; } @@ -1162,16 +1177,25 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_star for (size_t l = 0; l < num_group_faces; l++) { size_t pos = (*group_faces)[l] + poly_start; - if (pos >= mesh->totpoly) { + if (pos >= totpoly) { std::cerr << "Faceset overflow on " << faceset.getName() << '\n'; break; } - MPoly &poly = mesh->mpoly[pos]; + MPoly &poly = mpoly[pos]; poly.mat_nr = assigned_mat - 1; } } +} + +void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start, + const ISampleSelector &sample_sel) +{ + std::map<std::string, int> mat_map; + assign_facesets_to_mpoly(sample_sel, + poly_start, mesh->mpoly, mesh->totpoly, + mat_map); utils::assign_materials(bmain, m_object, mat_map); } @@ -1190,7 +1214,8 @@ ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2) return NULL; } -static void read_subd_sample(ImportSettings *settings, +static void read_subd_sample(const std::string & iobject_full_name, + ImportSettings *settings, const ISubDSchema &schema, const ISampleSelector &selector, CDStreamConfig &config) @@ -1225,10 +1250,9 @@ static void read_subd_sample(ImportSettings *settings, } if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) { - read_custom_data(schema.getArbGeomParams(), config, selector); + read_custom_data(iobject_full_name, + schema.getArbGeomParams(), config, selector); } - - /* TODO: face sets */ } /* ************************************************************************** */ @@ -1357,7 +1381,8 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, /* Only read point data when streaming meshes, unless we need to create new ones. */ CDStreamConfig config = get_config(new_dm ? new_dm : dm); config.time = sample_sel.getRequestedTime(); - read_subd_sample(&settings, m_schema, sample_sel, config); + read_subd_sample(m_iobject.getFullName(), + &settings, m_schema, sample_sel, config); if (new_dm) { /* Check if we had ME_SMOOTH flag set to restore it. */ diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h index 6bf1dde3d1d..e0b2365e134 100644 --- a/source/blender/alembic/intern/abc_mesh.h +++ b/source/blender/alembic/intern/abc_mesh.h @@ -50,7 +50,8 @@ class AbcMeshWriter : public AbcObjectWriter { bool m_is_subd; public: - AbcMeshWriter(Scene *scene, + AbcMeshWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, @@ -112,6 +113,11 @@ public: private: void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start, const Alembic::AbcGeom::ISampleSelector &sample_sel); + + void assign_facesets_to_mpoly(const Alembic::Abc::ISampleSelector &sample_sel, + size_t poly_start, + MPoly *mpoly, int totpoly, + std::map<std::string, int> & r_mat_map); }; /* ************************************************************************** */ diff --git a/source/blender/alembic/intern/abc_nurbs.cc b/source/blender/alembic/intern/abc_nurbs.cc index eaef06fd6d1..0532191a28d 100644 --- a/source/blender/alembic/intern/abc_nurbs.cc +++ b/source/blender/alembic/intern/abc_nurbs.cc @@ -60,12 +60,13 @@ using Alembic::AbcGeom::ONuPatchSchema; /* ************************************************************************** */ -AbcNurbsWriter::AbcNurbsWriter(Scene *scene, +AbcNurbsWriter::AbcNurbsWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) { m_is_animated = isAnimated(); diff --git a/source/blender/alembic/intern/abc_nurbs.h b/source/blender/alembic/intern/abc_nurbs.h index abe460a8988..3d20c5c60bb 100644 --- a/source/blender/alembic/intern/abc_nurbs.h +++ b/source/blender/alembic/intern/abc_nurbs.h @@ -32,7 +32,8 @@ class AbcNurbsWriter : public AbcObjectWriter { bool m_is_animated; public: - AbcNurbsWriter(Scene *scene, + AbcNurbsWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc index 8b169988096..98ebcf6debb 100644 --- a/source/blender/alembic/intern/abc_object.cc +++ b/source/blender/alembic/intern/abc_object.cc @@ -58,13 +58,15 @@ using Alembic::AbcGeom::OStringProperty; /* ************************************************************************** */ -AbcObjectWriter::AbcObjectWriter(Scene *scene, +AbcObjectWriter::AbcObjectWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, uint32_t time_sampling, ExportSettings &settings, AbcObjectWriter *parent) : m_object(ob) , m_settings(settings) + , m_eval_ctx(eval_ctx) , m_scene(scene) , m_time_sampling(time_sampling) , m_first_frame(true) @@ -139,6 +141,38 @@ AbcObjectReader::AbcObjectReader(const IObject &object, ImportSettings &settings 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() @@ -285,32 +319,10 @@ void AbcObjectReader::read_matrix(float r_mat[4][4], const float time, return; } - bool has_alembic_parent; - 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". */ - has_alembic_parent = false; - } - else { - has_alembic_parent = ixform_parent && schema.getInheritsXforms(); - - if (has_alembic_parent && m_object->parent == NULL) { - /* TODO Sybren: This happened in some files. I think I solved it, - * but I'll leave this check in here anyway until we've tested it - * more thoroughly. Better than crashing on a null parent anyway. */ - std::cerr << "Alembic object " << m_iobject.getFullName() - << " with transform " << ixform.getFullName() - << " has an Alembic parent but no parent Blender object." - << std::endl; - has_alembic_parent = false; - } - } - const Imath::M44d matrix = get_matrix(schema, time); convert_matrix(matrix, m_object, r_mat); - if (has_alembic_parent) { + if (m_inherits_xform) { /* In this case, the matrix in Alembic is in local coordinates, so * convert to world matrix. To prevent us from reading and accumulating * all parent matrices in the Alembic file, we assume that the Blender diff --git a/source/blender/alembic/intern/abc_object.h b/source/blender/alembic/intern/abc_object.h index 1462f93a422..6aa6224f8d5 100644 --- a/source/blender/alembic/intern/abc_object.h +++ b/source/blender/alembic/intern/abc_object.h @@ -44,6 +44,7 @@ protected: Object *m_object; ExportSettings &m_settings; + EvaluationContext *m_eval_ctx; Scene *m_scene; uint32_t m_time_sampling; @@ -56,7 +57,8 @@ protected: std::string m_name; public: - AbcObjectWriter(Scene *scene, + AbcObjectWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, uint32_t time_sampling, ExportSettings &settings, @@ -90,7 +92,7 @@ struct ImportSettings { /* Length and frame offset of file sequences. */ int sequence_len; - int offset; + int sequence_offset; /* From MeshSeqCacheModifierData.read_flag */ int read_flag; @@ -107,7 +109,7 @@ struct ImportSettings { , is_sequence(false) , set_frame_range(false) , sequence_len(1) - , offset(0) + , sequence_offset(0) , read_flag(0) , validate_meshes(false) , cache_file(NULL) @@ -143,6 +145,8 @@ protected: * modifiers and/or constraints. */ int m_refcount; + bool m_inherits_xform; + public: AbcObjectReader *parent_reader; @@ -167,6 +171,7 @@ public: 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, @@ -194,6 +199,9 @@ public: 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); diff --git a/source/blender/alembic/intern/abc_points.cc b/source/blender/alembic/intern/abc_points.cc index 80567cd6bf0..feb2eff5b9d 100644 --- a/source/blender/alembic/intern/abc_points.cc +++ b/source/blender/alembic/intern/abc_points.cc @@ -58,13 +58,14 @@ using Alembic::AbcGeom::OPointsSchema; /* ************************************************************************** */ -AbcPointsWriter::AbcPointsWriter(Scene *scene, +AbcPointsWriter::AbcPointsWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, ExportSettings &settings, ParticleSystem *psys) - : AbcObjectWriter(scene, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, scene, ob, time_sampling, settings, parent) { m_psys = psys; @@ -86,6 +87,7 @@ void AbcPointsWriter::do_write() ParticleKey state; ParticleSimulationData sim; + sim.eval_ctx = m_eval_ctx; sim.scene = m_scene; sim.ob = m_object; sim.psys = m_psys; diff --git a/source/blender/alembic/intern/abc_points.h b/source/blender/alembic/intern/abc_points.h index 369a802d763..b60f1997aa8 100644 --- a/source/blender/alembic/intern/abc_points.h +++ b/source/blender/alembic/intern/abc_points.h @@ -38,7 +38,8 @@ class AbcPointsWriter : public AbcObjectWriter { ParticleSystem *m_psys; public: - AbcPointsWriter(Scene *scene, + AbcPointsWriter(EvaluationContext *eval_ctx, + Scene *scene, Object *ob, AbcTransformWriter *parent, uint32_t time_sampling, diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc index 5392387663f..0a1480e62b0 100644 --- a/source/blender/alembic/intern/abc_transform.cc +++ b/source/blender/alembic/intern/abc_transform.cc @@ -57,12 +57,13 @@ static bool has_parent_camera(Object *ob) /* ************************************************************************** */ -AbcTransformWriter::AbcTransformWriter(Object *ob, +AbcTransformWriter::AbcTransformWriter(EvaluationContext *eval_ctx, + Object *ob, const OObject &abc_parent, AbcTransformWriter *parent, unsigned int time_sampling, ExportSettings &settings) - : AbcObjectWriter(NULL, ob, time_sampling, settings, parent) + : AbcObjectWriter(eval_ctx, NULL, ob, time_sampling, settings, parent) , m_proxy_from(NULL) { m_is_animated = hasAnimation(m_object); diff --git a/source/blender/alembic/intern/abc_transform.h b/source/blender/alembic/intern/abc_transform.h index 753a4247e9f..e82765cb169 100644 --- a/source/blender/alembic/intern/abc_transform.h +++ b/source/blender/alembic/intern/abc_transform.h @@ -44,7 +44,8 @@ public: Object *m_proxy_from; public: - AbcTransformWriter(Object *ob, + AbcTransformWriter(EvaluationContext *eval_ctx, + Object *ob, const Alembic::AbcGeom::OObject &abc_parent, AbcTransformWriter *parent, unsigned int time_sampling, diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc index 8601dff54ed..8bdc7ae3455 100644 --- a/source/blender/alembic/intern/abc_util.cc +++ b/source/blender/alembic/intern/abc_util.cc @@ -358,10 +358,10 @@ AbcObjectReader *create_reader(const Alembic::AbcGeom::IObject &object, ImportSe reader = new AbcCurveReader(object, settings); } else { - std::cerr << "Alembic: unknown how to handle objects of schema " + std::cerr << "Alembic: unknown how to handle objects of schema '" << md.get("schemaObjTitle") - << ", skipping object " - << object.getFullName() << std::endl; + << "', skipping object '" + << object.getFullName() << "'" << std::endl; } return reader; diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc index 54b49330355..e7c7213cecb 100644 --- a/source/blender/alembic/intern/alembic_capi.cc +++ b/source/blender/alembic/intern/alembic_capi.cc @@ -230,6 +230,7 @@ static void find_iobject(const IObject &object, IObject &ret, } struct ExportJobData { + EvaluationContext eval_ctx; Scene *scene; Main *bmain; @@ -262,7 +263,7 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo try { Scene *scene = data->scene; - AbcExporter exporter(scene, data->filename, data->settings); + AbcExporter exporter(&data->eval_ctx, scene, data->filename, data->settings); const int orig_frame = CFRA; @@ -310,6 +311,9 @@ bool ABC_export( bool as_background_job) { ExportJobData *job = static_cast<ExportJobData *>(MEM_mallocN(sizeof(ExportJobData), "ExportJobData")); + + CTX_data_eval_ctx(C, &job->eval_ctx); + job->scene = scene; job->bmain = CTX_data_main(C); job->export_ok = false; @@ -762,7 +766,7 @@ 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.offset; + SFRA = data->settings.sequence_offset; EFRA = SFRA + (data->settings.sequence_len - 1); CFRA = SFRA; } @@ -779,7 +783,7 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa const AbcObjectReader *parent_reader = reader->parent_reader; Object *ob = reader->object(); - if (parent_reader == NULL) { + if (parent_reader == NULL || !reader->inherits_xform()) { ob->parent = NULL; } else { @@ -902,7 +906,7 @@ bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence job->settings.is_sequence = is_sequence; job->settings.set_frame_range = set_frame_range; job->settings.sequence_len = sequence_len; - job->settings.offset = offset; + job->settings.sequence_offset = offset; job->settings.validate_meshes = validate_meshes; job->error_code = ABC_NO_ERROR; job->was_cancelled = false; @@ -1022,6 +1026,10 @@ CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle, CacheRead 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(); |