Alembic export: don't assume transform is always animated
authorSybren A. Stüvel <sybren@blender.org>
Tue, 26 Nov 2019 13:35:47 +0000 (14:35 +0100)
committerSybren A. Stüvel <sybren@blender.org>
Tue, 26 Nov 2019 15:26:52 +0000 (16:26 +0100)
Instead of always writing the transform on every frame, it's now checked
whether the object is animated at all. This could be made stricter to
reduce false positives, for example by checking FCurves and drivers to
see whether translation/rotation/scale is animated. However, this
approach is already better than the `return true` we had before.

This commit adds the BKE_animdata_id_is_animated(id) function, which
returns true if the ID datablock has non-empty animation data. This is
determined by checking the the active action's fcurves, the drivers, and
NLA tracks.

source/blender/alembic/intern/abc_mesh.cc
source/blender/alembic/intern/abc_transform.cc
source/blender/blenkernel/BKE_animsys.h
source/blender/blenkernel/intern/anim_sys.c

index 89fafc65e5d56288c1f47a05df66df71b021db89..edcb6263da3f85aacbc14069e05fe12711d968d7 100644 (file)
@@ -304,14 +304,8 @@ AbcGenericMeshWriter::~AbcGenericMeshWriter()
 
 bool AbcGenericMeshWriter::isAnimated() const
 {
-  if (m_object->data != NULL) {
-    AnimData *adt = BKE_animdata_from_id(static_cast<ID *>(m_object->data));
-    /* TODO(Sybren): make this check more strict, as the AnimationData may
-     * actually be empty (no fcurves, drivers, etc.) and thus effectively
-     * have no animation at all. */
-    if (adt != NULL) {
-      return true;
-    }
+  if (BKE_animdata_id_is_animated(static_cast<ID *>(m_object->data))) {
+    return true;
   }
   if (BKE_key_from_object(m_object) != NULL) {
     return true;
index 505acfc164a42a0ba70a756de028489400455b5b..9b12fe86d590b31cf8b4f6fc1dabdd2339334bae 100644 (file)
@@ -29,6 +29,7 @@ extern "C" {
 
 #include "BLI_math.h"
 
+#include "BKE_animsys.h"
 #include "BKE_object.h"
 
 #include "DEG_depsgraph_query.h"
@@ -130,10 +131,9 @@ Imath::Box3d AbcTransformWriter::bounds()
   return Imath::transform(bounds, m_matrix);
 }
 
-bool AbcTransformWriter::hasAnimation(Object * /*ob*/) const
+bool AbcTransformWriter::hasAnimation(Object *ob) const
 {
-  /* TODO(kevin): implement this. */
-  return true;
+  return BKE_animdata_id_is_animated(&ob->id);
 }
 
 /* ************************************************************************** */
index 4e4528ff92bb2d303d5f429a1a7ab8a4e3c937f8..985dce70bdcb3a4bde274da9677f88904022f01f 100644 (file)
@@ -60,6 +60,9 @@ bool BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct b
 /* Free AnimData */
 void BKE_animdata_free(struct ID *id, const bool do_id_user);
 
+/* Return true if the ID-block has non-empty AnimData. */
+bool BKE_animdata_id_is_animated(struct ID *id);
+
 /* Copy AnimData */
 struct AnimData *BKE_animdata_copy(struct Main *bmain, struct AnimData *adt, const int flag);
 
index 88a8463b99404688f5d2726a4118d667f59da7ac..6ecfeaffdba06fa87c60cecde8ab6b079b9e4692 100644 (file)
@@ -283,6 +283,24 @@ void BKE_animdata_free(ID *id, const bool do_id_user)
   }
 }
 
+bool BKE_animdata_id_is_animated(struct ID *id)
+{
+  if (id == NULL) {
+    return false;
+  }
+
+  AnimData *adt = BKE_animdata_from_id(id);
+  if (adt == NULL) {
+    return false;
+  }
+
+  if (adt->action != NULL && !BLI_listbase_is_empty(&adt->action->curves)) {
+    return true;
+  }
+
+  return !BLI_listbase_is_empty(&adt->drivers) || !BLI_listbase_is_empty(&adt->nla_tracks);
+}
+
 /* Copying -------------------------------------------- */
 
 /**