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/intern/abc_reader_mesh.cc')
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.cc130
1 files changed, 88 insertions, 42 deletions
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index eab94139f55..43581ad48d9 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -34,6 +34,7 @@
#include "DNA_object_types.h"
#include "BLI_compiler_compat.h"
+#include "BLI_index_range.hh"
#include "BLI_listbase.h"
#include "BLI_math_geom.h"
@@ -44,6 +45,7 @@
#include "BKE_modifier.h"
#include "BKE_object.h"
+using Alembic::Abc::FloatArraySamplePtr;
using Alembic::Abc::Int32ArraySamplePtr;
using Alembic::Abc::IV3fArrayProperty;
using Alembic::Abc::P3fArraySamplePtr;
@@ -160,27 +162,26 @@ static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data)
return;
}
- read_mverts(mverts, positions, nullptr);
+ read_mverts(*config.mesh, positions, nullptr);
}
-void read_mverts(MVert *mverts, const P3fArraySamplePtr positions, const N3fArraySamplePtr normals)
+void read_mverts(Mesh &mesh, const P3fArraySamplePtr positions, const N3fArraySamplePtr normals)
{
for (int i = 0; i < positions->size(); i++) {
- MVert &mvert = mverts[i];
+ MVert &mvert = mesh.mvert[i];
Imath::V3f pos_in = (*positions)[i];
copy_zup_from_yup(mvert.co, pos_in.getValue());
mvert.bweight = 0;
-
- if (normals) {
+ }
+ if (normals) {
+ float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(&mesh);
+ for (const int i : IndexRange(normals->size())) {
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);
+ copy_zup_from_yup(vert_normals[i], nor_in.getValue());
}
+ BKE_mesh_vertex_normals_clear_dirty(&mesh);
}
}
@@ -435,6 +436,13 @@ static V3fArraySamplePtr get_velocity_prop(const ICompoundProperty &schema,
const ICompoundProperty &prop = ICompoundProperty(schema, header.getName());
if (has_property(prop, name)) {
+ /* Header cannot be null here, as its presence is checked via has_property, so it is safe
+ * to dereference. */
+ const PropertyHeader *header = prop.getPropertyHeader(name);
+ if (!IV3fArrayProperty::matches(*header)) {
+ continue;
+ }
+
const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(prop, name, 0);
if (velocity_prop) {
return velocity_prop.getValue(selector);
@@ -442,7 +450,7 @@ static V3fArraySamplePtr get_velocity_prop(const ICompoundProperty &schema,
}
}
else if (header.isArray()) {
- if (header.getName() == name) {
+ if (header.getName() == name && IV3fArrayProperty::matches(header)) {
const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(schema, name, 0);
return velocity_prop.getValue(selector);
}
@@ -456,13 +464,17 @@ static void read_velocity(const V3fArraySamplePtr &velocities,
const CDStreamConfig &config,
const float velocity_scale)
{
+ const int num_velocity_vectors = static_cast<int>(velocities->size());
+ if (num_velocity_vectors != config.mesh->totvert) {
+ /* Files containing videogrammetry data may be malformed and export velocity data on missing
+ * frames (most likely by copying the last valid data). */
+ return;
+ }
+
CustomDataLayer *velocity_layer = BKE_id_attribute_new(
&config.mesh->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT, nullptr);
float(*velocity)[3] = (float(*)[3])velocity_layer->data;
- const int num_velocity_vectors = static_cast<int>(velocities->size());
- BLI_assert(num_velocity_vectors == config.mesh->totvert);
-
for (int i = 0; i < num_velocity_vectors; i++) {
const Imath::V3f &vel_in = (*velocities)[i];
copy_zup_from_yup(velocity[i], vel_in.getValue());
@@ -899,6 +911,66 @@ static void read_subd_sample(const std::string &iobject_full_name,
}
}
+static void read_vertex_creases(Mesh *mesh,
+ const Int32ArraySamplePtr &indices,
+ const FloatArraySamplePtr &sharpnesses)
+{
+ if (!(indices && sharpnesses && indices->size() == sharpnesses->size() &&
+ indices->size() != 0)) {
+ return;
+ }
+
+ float *vertex_crease_data = (float *)CustomData_add_layer(
+ &mesh->vdata, CD_CREASE, CD_DEFAULT, nullptr, mesh->totvert);
+ const int totvert = mesh->totvert;
+
+ for (int i = 0, v = indices->size(); i < v; ++i) {
+ const int idx = (*indices)[i];
+
+ if (idx >= totvert) {
+ continue;
+ }
+
+ vertex_crease_data[idx] = (*sharpnesses)[i];
+ }
+
+ mesh->cd_flag |= ME_CDFLAG_VERT_CREASE;
+}
+
+static void read_edge_creases(Mesh *mesh,
+ const Int32ArraySamplePtr &indices,
+ const FloatArraySamplePtr &sharpnesses)
+{
+ if (!(indices && sharpnesses)) {
+ return;
+ }
+
+ 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 == nullptr) {
+ 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;
+}
+
/* ************************************************************************** */
AbcSubDReader::AbcSubDReader(const IObject &object, ImportSettings &settings)
@@ -962,35 +1034,9 @@ void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelec
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);
- }
+ read_edge_creases(mesh, sample.getCreaseIndices(), sample.getCreaseSharpnesses());
- MEdge *edge = find_edge(edges, totedge, v1, v2);
- if (edge == nullptr) {
- 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;
- }
+ read_vertex_creases(mesh, sample.getCornerIndices(), sample.getCornerSharpnesses());
if (m_settings->validate_meshes) {
BKE_mesh_validate(mesh, false, false);