[Bf-blender-cvs] [d875c5a] alembic_basic_io: Refactor mesh reading code to de-duplicate logic with data streaming code.
Kévin Dietrich
noreply at git.blender.org
Wed Jul 13 15:01:32 CEST 2016
Commit: d875c5adfbe088aa537890e726dd172925804018
Author: Kévin Dietrich
Date: Wed Jul 13 11:04:20 2016 +0200
Branches: alembic_basic_io
https://developer.blender.org/rBd875c5adfbe088aa537890e726dd172925804018
Refactor mesh reading code to de-duplicate logic with data streaming
code.
===================================================================
M source/blender/alembic/intern/abc_customdata.h
M source/blender/alembic/intern/abc_mesh.cc
M source/blender/alembic/intern/abc_mesh.h
M source/blender/alembic/intern/alembic_capi.cc
===================================================================
diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h
index a5eba88..b6aa7b6 100644
--- a/source/blender/alembic/intern/abc_customdata.h
+++ b/source/blender/alembic/intern/abc_customdata.h
@@ -28,7 +28,9 @@
struct CustomData;
struct MLoop;
+struct MLoopUV;
struct MPoly;
+struct MVert;
using Alembic::Abc::ICompoundProperty;
using Alembic::Abc::OCompoundProperty;
@@ -45,8 +47,13 @@ struct CDStreamConfig {
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
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 016cc31..e813f7f 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -781,270 +781,291 @@ static void assign_materials(Main *bmain, Object *ob, const std::map<std::string
/* ************************************************************************** */
-template <typename Schema>
-static bool has_animations(Schema &schema, ImportSettings *settings)
-{
- if (settings->is_sequence) {
- return true;
- }
+using Alembic::AbcGeom::UInt32ArraySamplePtr;
+using Alembic::AbcGeom::V2fArraySamplePtr;
- if (!schema.isConstant()) {
- return true;
- }
+struct AbcMeshData {
+ Int32ArraySamplePtr face_indices;
+ Int32ArraySamplePtr face_counts;
- const ICompoundProperty &arb_geom_params = schema.getArbGeomParams();
+ P3fArraySamplePtr positions;
- if (!arb_geom_params.valid()) {
- return false;
- }
+ N3fArraySamplePtr vertex_normals;
+ N3fArraySamplePtr face_normals;
- const size_t num_props = arb_geom_params.getNumProperties();
+ V2fArraySamplePtr uvs;
+ UInt32ArraySamplePtr uvs_indices;
+};
- for (size_t i = 0; i < num_props; ++i) {
- const Alembic::Abc::PropertyHeader &propHeader = arb_geom_params.getPropertyHeader(i);
+static void *add_customdata_cb(void *user_data, const char *name, int data_type)
+{
+ Mesh *mesh = static_cast<Mesh *>(user_data);
+ CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
+ void *cd_ptr = NULL;
- /* Check for animated UVs. */
- if (IV2fGeomParam::matches(propHeader) && Alembic::AbcGeom::isUV(propHeader)) {
- IV2fGeomParam uv_geom_param(arb_geom_params, propHeader.getName());
+ int index = -1;
+ if (cd_data_type == CD_MLOOPUV) {
+ index = ED_mesh_uv_texture_add(mesh, name, true);
+ cd_ptr = CustomData_get_layer(&mesh->ldata, cd_data_type);
+ }
+ else if (cd_data_type == CD_MLOOPCOL) {
+ index = ED_mesh_color_add(mesh, name, true);
+ cd_ptr = CustomData_get_layer(&mesh->ldata, cd_data_type);
+ }
- if (!uv_geom_param.isConstant()) {
- return true;
- }
- }
+ if (index == -1) {
+ return NULL;
}
- return false;
+ return cd_ptr;
}
-AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings, bool is_subd)
- : AbcObjectReader(object, settings)
+ABC_INLINE CDStreamConfig create_config(Mesh *mesh)
{
- if (is_subd) {
- ISubD isubd_mesh(m_iobject, kWrapExisting);
- m_subd_schema = isubd_mesh.getSchema();
- get_min_max_time(m_subd_schema, m_min_time, m_max_time);
- }
- else {
- IPolyMesh ipoly_mesh(m_iobject, kWrapExisting);
- m_schema = ipoly_mesh.getSchema();
- get_min_max_time(m_schema, m_min_time, m_max_time);
- }
+ CDStreamConfig config;
+
+ config.mvert = mesh->mvert;
+ config.mpoly = mesh->mpoly;
+ config.mloop = mesh->mloop;
+ config.totpoly = mesh->totpoly;
+ config.totloop = mesh->totloop;
+ config.user_data = mesh;
+ config.add_customdata_cb = add_customdata_cb;
+
+ return config;
}
-bool AbcMeshReader::valid() const
+static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data)
{
- return m_schema.valid() || m_subd_schema.valid();
+ MVert *mverts = config.mvert;
+ const P3fArraySamplePtr &positions = mesh_data.positions;
+ const N3fArraySamplePtr &normals = mesh_data.vertex_normals;
+
+ read_mverts(mverts, positions, normals);
}
-static MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2)
+void read_mverts(MVert *mverts, const P3fArraySamplePtr &positions, const N3fArraySamplePtr &normals)
{
- for (int i = 0, e = totedge; i < e; ++i) {
- MEdge &edge = edges[i];
+ for (int i = 0; i < positions->size(); ++i) {
+ MVert &mvert = mverts[i];
+ Imath::V3f pos_in = (*positions)[i];
- if (edge.v1 == v1 && edge.v2 == v2) {
- return &edge;
+ copy_yup_zup(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_yup_zup(mvert.no, no);
}
}
-
- return NULL;
}
-void AbcMeshReader::readObjectData(Main *bmain, Scene *scene, float time)
+static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
{
- Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
+ MPoly *mpolys = config.mpoly;
+ MLoop *mloops = config.mloop;
+ MLoopUV *mloopuvs = config.mloopuv;
+ CustomData *ldata = config.loopdata;
- const ISampleSelector sample_sel(time);
- const size_t poly_start = mesh->totpoly;
+ const Int32ArraySamplePtr &face_indices = mesh_data.face_indices;
+ const Int32ArraySamplePtr &face_counts = mesh_data.face_counts;
+ const V2fArraySamplePtr &uvs = mesh_data.uvs;
+ const UInt32ArraySamplePtr &uvs_indices = mesh_data.uvs_indices;
+ const N3fArraySamplePtr &normals = mesh_data.face_normals;
- bool is_constant = true;
+ float (*pnors)[3] = NULL;
- if (m_subd_schema.valid()) {
- is_constant = !has_animations(m_subd_schema, m_settings);
+ if (normals) {
+ void *vptr = CustomData_get_layer(ldata, CD_NORMAL);
- const ISubDSchema::Sample sample = m_subd_schema.getValue(sample_sel);
+ if (!vptr) {
+ vptr = CustomData_add_layer(ldata, CD_NORMAL, CD_CALLOC, NULL, normals->size());
+ }
- readVertexDataSample(mesh, sample.getPositions(), N3fArraySamplePtr());
- readPolyDataSample(mesh, sample.getFaceIndices(), sample.getFaceCounts(), N3fArraySamplePtr());
+ pnors = static_cast<float (*)[3]>(vptr);
}
- else {
- is_constant = !has_animations(m_schema, m_settings);
- const IPolyMeshSchema::Sample sample = m_schema.getValue(sample_sel);
+ const bool do_normals = (normals && pnors);
+ 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;
+ Imath::V3f nor;
- N3fArraySamplePtr vertex_normals, poly_normals;
- const IN3fGeomParam normals = m_schema.getNormalsParam();
+ for (int i = 0; i < face_counts->size(); ++i) {
+ const int face_size = (*face_counts)[i];
- if (normals.valid()) {
- IN3fGeomParam::Sample normsamp = normals.getExpandedValue(sample_sel);
+ MPoly &poly = mpolys[i];
+ poly.loopstart = loop_index;
+ poly.totloop = face_size;
- if (normals.getScope() == Alembic::AbcGeom::kFacevaryingScope) {
- poly_normals = normsamp.getVals();
- }
- else if ((normals.getScope() == Alembic::AbcGeom::kVertexScope) ||
- (normals.getScope() == Alembic::AbcGeom::kVaryingScope))
- {
- vertex_normals = normsamp.getVals();
+ /* 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_normals) {
+ nor = (*normals)[loop_index];
+ copy_yup_zup(pnors[rev_loop_index], nor.getValue());
}
- }
- readVertexDataSample(mesh, sample.getPositions(), vertex_normals);
- readPolyDataSample(mesh, sample.getFaceIndices(), sample.getFaceCounts(), poly_normals);
+ if (do_uvs) {
+ MLoopUV &loopuv = mloopuvs[rev_loop_index];
- if (!vertex_normals && !poly_normals) {
- BKE_mesh_calc_normals(mesh);
+ uv_index = (*uvs_indices)[loop_index];
+ loopuv.uv[0] = (*uvs)[uv_index][0];
+ loopuv.uv[1] = (*uvs)[uv_index][1];
+ }
}
}
+}
- BKE_mesh_validate(mesh, false, false);
-
- m_object = BKE_object_add(bmain, scene, OB_MESH, m_object_name.c_str());
- m_object->data = mesh;
-
- readFaceSetsSample(bmain, mesh, poly_start, sample_sel);
-
- if (m_subd_schema.valid()) {
- const ISubDSchema::Sample sample = m_subd_schema.getValue(sample_sel);
-
- Int32ArraySamplePtr indices = sample.getCreaseIndices();
- Alembic::Abc::FloatArraySamplePtr sharpnesses = sample.getCreaseSharpnesses();
+ABC_INLINE void read_uvs_params(CDStreamConfig &config,
+ AbcMeshData &abc_data,
+ const IV2fGeomParam &uv,
+ const ISampleSelector &selector)
+{
+ if (!uv.valid()) {
+ return;
+ }
- MEdge *edges = mesh->medge;
+ IV2fGeomParam::Sample uvsamp;
+ uv.getIndexed(uvsamp, selector);
- if (indices && sharpnesses) {
- for (int i = 0, s = 0, e = indices->size(); i < e; i += 2, ++s) {
- MEdge *edge = find_edge(edges, mesh->totedge, (*indices)[i], (*indices)[i + 1]);
+ abc_data.uvs = uvsamp.getVals();
+ abc_data.uvs_indices = uvsamp.getIndices();
- if (edge) {
- edge->crease = FTOCHAR((*sharpnesses)[s]);
- }
- }
+ if (abc_data.uvs_indices->size() == config.totloop) {
+ std::string name = Alembic::Abc::GetSourceName(uv.getMetaData());
- mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ /* 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();
}
- }
- if (!is_constant) {
- addDefaultModifier();
+ void *cd_ptr = config.add_customdata_cb(config.user_data, name.c_str(), CD_MLOOPUV);
+ config.mloopuv = static_cast<MLoopUV *>(cd_ptr);
}
}
-void AbcMeshReader::readVertexDataSample(Mesh *mesh,
- const P3fArraySamplePtr &positions,
- const N3fArraySamplePtr &normals)
+ABC_INLINE void read_normals_params(AbcMeshData &abc_data,
+ const IN3fGeomParam normals,
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list