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:
-rw-r--r--source/blender/alembic/ABC_alembic.h6
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc30
-rw-r--r--source/blender/alembic/intern/abc_mesh.h2
-rw-r--r--source/blender/alembic/intern/abc_object.cc8
-rw-r--r--source/blender/alembic/intern/abc_object.h2
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc41
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c10
7 files changed, 88 insertions, 11 deletions
diff --git a/source/blender/alembic/ABC_alembic.h b/source/blender/alembic/ABC_alembic.h
index 653382017d6..696e0ff1810 100644
--- a/source/blender/alembic/ABC_alembic.h
+++ b/source/blender/alembic/ABC_alembic.h
@@ -117,6 +117,12 @@ struct Mesh *ABC_read_mesh(struct CacheReader *reader,
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);
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 6647ca83bd6..be2793e38f7 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -1131,6 +1131,31 @@ bool AbcMeshReader::accepts_object_type(
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,
@@ -1162,10 +1187,7 @@ Mesh *AbcMeshReader::read_mesh(Mesh *existing_mesh,
ImportSettings settings;
settings.read_flag |= read_flag;
- bool topology_changed = positions->size() != existing_mesh->totvert ||
- face_counts->size() != existing_mesh->totpoly ||
- face_indices->size() != existing_mesh->totloop;
- if (topology_changed) {
+ 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());
diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h
index 859ab121eb6..77686a0204e 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -110,6 +110,8 @@ class AbcMeshReader : public AbcObjectReader {
const Alembic::Abc::ISampleSelector &sample_sel,
int read_flag,
const char **err_str);
+ bool topology_changed(Mesh *existing_mesh,
+ const Alembic::Abc::ISampleSelector &sample_sel) override;
private:
void readFaceSetsSample(Main *bmain,
diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index f863fe4fee7..ebebbc0da1e 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -246,6 +246,14 @@ struct Mesh *AbcObjectReader::read_mesh(struct Mesh *existing_mesh,
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;
diff --git a/source/blender/alembic/intern/abc_object.h b/source/blender/alembic/intern/abc_object.h
index 537f24ab7d6..efe78b9017c 100644
--- a/source/blender/alembic/intern/abc_object.h
+++ b/source/blender/alembic/intern/abc_object.h
@@ -190,6 +190,8 @@ class AbcObjectReader {
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);
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index d63b310fef7..f7ba925530b 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -937,12 +937,7 @@ void ABC_get_transform(CacheReader *reader, float r_mat[4][4], float time, float
/* ************************************************************************** */
-Mesh *ABC_read_mesh(CacheReader *reader,
- Object *ob,
- Mesh *existing_mesh,
- const float time,
- const char **err_str,
- int read_flag)
+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();
@@ -958,12 +953,44 @@ Mesh *ABC_read_mesh(CacheReader *reader,
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. */
- ISampleSelector sample_sel(time, ISampleSelector::kFloorIndex);
+ 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 NULL;
+ }
+
+ ISampleSelector sample_sel = sample_selector_for_time(time);
+ return abc_reader->topology_changed(existing_mesh, sample_sel);
+}
+
/* ************************************************************************** */
void CacheReader_free(CacheReader *reader)
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index 760830ffb24..0f57b759e38 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -114,10 +114,20 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
}
}
+ /* If this invocation is for the ORCO mesh, and the mesh in Alembic hasn't changed topology, we
+ * must return the mesh as-is instead of deforming it. */
+ if (ctx->flag & MOD_APPLY_ORCO &&
+ !ABC_mesh_topology_changed(mcmd->reader, ctx->object, mesh, time, &err_str)) {
+ return mesh;
+ }
+
if (me != NULL) {
MVert *mvert = mesh->mvert;
MEdge *medge = mesh->medge;
MPoly *mpoly = mesh->mpoly;
+
+ /* TODO(sybren+bastien): possibly check relevant custom data layers (UV/color depending on
+ * flags) and duplicate those too. */
if ((me->mvert == mvert) || (me->medge == medge) || (me->mpoly == mpoly)) {
/* We need to duplicate data here, otherwise we'll modify org mesh, see T51701. */
BKE_id_copy_ex(NULL,