[Bf-blender-cvs] [58d67e0402a] collada: Feature: Collada: Added new classes for The Animation exporter

Gaia Clary noreply at git.blender.org
Wed Mar 28 21:30:45 CEST 2018


Commit: 58d67e0402af2bd60c98cf6d148ebce276897078
Author: Gaia Clary
Date:   Sat Mar 17 13:40:46 2018 +0100
Branches: collada
https://developer.blender.org/rB58d67e0402af2bd60c98cf6d148ebce276897078

Feature: Collada: Added new classes for The Animation exporter

Actually the new classes are not depending on Collada itself.
They coul dbe reused for other purposes as well, for example
as a general helper tool for Animation export.

===================================================================

M	source/blender/collada/BCAnimationCurve.cpp
M	source/blender/collada/BCAnimationCurve.h
M	source/blender/collada/BCAnimationCurveContainer.cpp
M	source/blender/collada/BCAnimationCurveContainer.h
M	source/blender/collada/CMakeLists.txt

===================================================================

diff --git a/source/blender/collada/BCAnimationCurve.cpp b/source/blender/collada/BCAnimationCurve.cpp
index cfca9a532f2..cffec4c7743 100644
--- a/source/blender/collada/BCAnimationCurve.cpp
+++ b/source/blender/collada/BCAnimationCurve.cpp
@@ -50,18 +50,35 @@ void BCAnimationCurve::create_bezt(float frame, float output)
 	calchandles_fcurve(fcu);
 }
 
-BCAnimationCurve::BCAnimationCurve(FCurve *fcu, Object *ob, BC_animation_curve_type type) // = BC_ANIMATION_CURVE_TYPE_OBJECT )
+BCAnimationCurve::BCAnimationCurve()
 {
-	this->ob = ob;
+	this->fcurve = nullptr;
+	this->type = BC_ANIMATION_CURVE_TYPE_UNKNOWN;
+	bool curve_is_local_copy = false;
+}
+
+void BCAnimationCurve::init(Object *ob, BC_animation_curve_type type, std::string path, int index)
+{
+	this->curve_key.init(path, index);
+	this->fcurve = nullptr; // create_fcurve(index, path.c_str());
+	this->type = type;
+	curve_is_local_copy = false;
+}
+
+void BCAnimationCurve::init(Object *ob, BC_animation_curve_type type, FCurve *fcu)
+{
+	this->curve_key.init(std::string(fcu->rna_path), fcu->array_index);
 	this->fcurve = fcu;
 	this->type = type;
+	curve_is_local_copy = false; // make sure the curve is destroyed later;
 }
 
 BCAnimationCurve::~BCAnimationCurve()
 {
 	if (curve_is_local_copy && fcurve) {
-		fprintf(stderr, "removed fcurve %s\n", fcurve->rna_path);
+		//fprintf(stderr, "removed fcurve %s\n", fcurve->rna_path);
 		delete_fcurve(fcurve);
+		this->fcurve = nullptr;
 	}
 }
 
@@ -72,13 +89,11 @@ const BC_animation_curve_type BCAnimationCurve::get_channel_type() const
 
 const std::string BCAnimationCurve::get_channel_target() const
 {
-	if (!fcurve || !fcurve->rna_path)
-		return "";
-
-	return bc_string_after(fcurve->rna_path, '.');
+	const std::string path = curve_key.path();
+	return bc_string_after(path, '.');
 }
 
-const std::string BCAnimationCurve::get_animation_name() const
+const std::string BCAnimationCurve::get_animation_name(Object *ob) const
 {
 	std::string name;
 
@@ -116,12 +131,17 @@ const std::string BCAnimationCurve::get_animation_name() const
 
 const int BCAnimationCurve::get_array_index() const
 {
-	return fcurve->array_index;
+	return curve_key.index();
+}
+
+const std::string BCAnimationCurve::get_rna_path() const
+{
+	return curve_key.path();
 }
 
 const int BCAnimationCurve::size() const
 {
-	return export_values.size();
+	return sample_frames.size();
 }
 
 const int BCAnimationCurve::closest_index_above(float sample_frame, int start_at) const
@@ -184,38 +204,60 @@ FCurve *BCAnimationCurve::get_edit_fcurve()
 {
 	if (!curve_is_local_copy) {
 
-		fcurve = copy_fcurve(fcurve);
+		if (fcurve) {
+			fcurve = copy_fcurve(fcurve);
+			//fprintf(stderr, "Copy to temporary fcurve %s (for editing)\n", fcurve->rna_path);
+		}
+		else {
+			int index = curve_key.index();
+			const std::string &path = curve_key.path();
+			fcurve = create_fcurve(index, path.c_str());
+			//fprintf(stderr, "Create temporary fcurve %s (for editing)\n", fcurve->rna_path);
+		}
 
 		/* Replacing the pointer here is OK because the original value
 		of FCurve was a const pointer into Blender territory. We do not
 		touch that! We use the local copy to prepare for export.
 		*/
 		curve_is_local_copy = true;
-		fprintf(stderr, "Copy fcurve %s (for editing)\n", fcurve->rna_path);
 	}
 	return fcurve;
 }
 
-Object *BCAnimationCurve::get_object() const
+Bone *BCAnimationCurve::get_bone(Object *ob) const
 {
-	return ob;
+	if (ob->type != OB_ARMATURE ||
+		type != BC_ANIMATION_CURVE_TYPE_BONE ||
+		!fcurve ||
+		!fcurve->rna_path)
+		return nullptr;
+
+	char *boneName = BLI_str_quoted_substrN(fcurve->rna_path, "pose.bones[");
+
+	if (!boneName)
+		return nullptr;
+
+	Bone *bone = BKE_armature_find_bone_name((bArmature *)ob->data, boneName);
+	return bone;
+
 }
 
 void BCAnimationCurve::add_value(const float val, const int frame)
 {
 	FCurve *fcu = get_edit_fcurve();
 	insert_vert_fcurve(fcu, frame, val, BEZT_IPO_BEZ, INSERTKEY_NO_USERPREF);
-	export_values[frame] = val;
+
+	sample_frames.push_back(frame);
 }
 
 /*
-Pick the value from the matrix accoridng to the definition of the FCurve
+Pick the value from the matrix according to the definition of the FCurve
 Note: This works only for "scale", "rotation", "rotation_euler" and "location"
 */
 void BCAnimationCurve::add_value(BCMatrix mat, int frame)
 {
 	std::string target = get_channel_target();
-	int array_index = fcurve->array_index;
+	const int array_index = curve_key.index();
 	float val;
 
 	if (target == "location") {
@@ -226,7 +268,9 @@ void BCAnimationCurve::add_value(BCMatrix mat, int frame)
 		const float(&size)[3] = mat.scale();
 		val = size[array_index];
 	}
-	else if (target == "rotation_euler") {
+	else if (
+		target == "rotation" ||
+		target == "rotation_euler") {
 		const float(&rot)[3] = mat.rotation();
 		val = rot[array_index];
 	}
@@ -246,18 +290,18 @@ returned vector is empty
 */
 void BCAnimationCurve::get_frames(std::vector<float> &frames) const
 {
-	std::map<int, float>::const_iterator it;
-	for (it = export_values.begin(); it != export_values.end(); ++it) {
-		frames.push_back(it->first);
+	std::vector<int>::const_iterator it;
+	for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
+		frames.push_back(*it);
 	}
 }
 
 void BCAnimationCurve::get_frames(std::set<float> &frames) const
 {
-	std::map<int, float>::const_iterator it;
-	for (it = export_values.begin(); it != export_values.end(); ++it) {
-		frames.insert(it->first);
-	}
+	std::vector<int>::const_iterator it;
+		for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
+			frames.insert(*it);
+		}
 }
 
 /*
@@ -267,11 +311,11 @@ returned vector is empty
 */
 void BCAnimationCurve::get_times(std::vector<float> &times, Scene *scene) const
 {
-	std::map<int, float>::const_iterator it;
-	for (it = export_values.begin(); it != export_values.end(); ++it) {
-		float time = FRA2TIME(it->first); // implicit use of scene
-		times.push_back(it->first);
-	}
+	std::vector<int>::const_iterator it;
+		for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
+			float time = FRA2TIME(*it); // implicit use of scene
+			times.push_back(*it);
+		}
 }
 
 /*
@@ -281,10 +325,28 @@ returned vector is empty
 */
 void BCAnimationCurve::get_values(std::vector<float> &values) const
 {
-	std::map<int, float>::const_iterator it;
-	for (it = export_values.begin(); it != export_values.end(); ++it) {
-		values.push_back(it->second);
+	std::vector<int>::const_iterator it;
+		for (it = sample_frames.begin(); it != sample_frames.end(); ++it) {
+			float val = evaluate_fcurve(fcurve, *it);
+			values.push_back(val);
+		}
+}
+
+bool BCAnimationCurve::is_flat_line(std::vector<float> &values)
+{
+	static float MIN_DISTANCE = 0.00001;
+
+	if (values.size() < 2)
+		return true; // need at least 2 entries to be not flat
+
+	float ref = values[0];
+	for (int index = 1; index < values.size(); index++) {
+		float val = values[index];
+		if (fabs(val - ref) > MIN_DISTANCE) {
+			return false;
+		}
 	}
+	return true;
 }
 
 
diff --git a/source/blender/collada/BCAnimationCurve.h b/source/blender/collada/BCAnimationCurve.h
index f3e27b03444..ec09217b77d 100644
--- a/source/blender/collada/BCAnimationCurve.h
+++ b/source/blender/collada/BCAnimationCurve.h
@@ -30,6 +30,7 @@ extern "C"
 {
 #include "MEM_guardedalloc.h"
 #include "BKE_fcurve.h"
+#include "BKE_armature.h"
 #include "ED_keyframing.h"
 }
 
@@ -44,36 +45,82 @@ typedef enum BC_animation_curve_type {
 
 } BC_animation_curve_type;
 
+class CurveKey {
+private:
+	std::string rna_path;
+	int array_index;
+
+public:
+
+	CurveKey()
+	{
+		rna_path = "";
+		array_index = -1;
+	}
+
+	CurveKey(std::string rna_path, int array_index)
+	{
+		this->init(rna_path, array_index);
+	}
+
+	void init(std::string rna_path, int array_index)
+	{
+		this->rna_path = rna_path;
+		this->array_index = array_index;
+	}
+
+	const std::string path() const
+	{
+		return this->rna_path;
+	}
+
+	const int index() const
+	{
+		return this->array_index;
+	}
+
+	bool operator< (const CurveKey& key) const
+	{
+		if (rna_path == key.rna_path) {
+			return key.array_index < this->array_index;
+		}
+		return ((rna_path < key.rna_path));
+	}
+};
 
 class BCAnimationCurve {
 private:
-	
 	BC_animation_curve_type type = BC_ANIMATION_CURVE_TYPE_UNKNOWN;
+	std::vector<int> sample_frames;
+	CurveKey curve_key;
 	bool curve_is_local_copy = false;
-	FCurve * fcurve;
-	Object *ob;
-	std::map<int, float> export_values;
+	FCurve *fcurve;
 
 	void delete_fcurve(FCurve *fcu);
 	FCurve *create_fcurve(int array_index, const char *rna_path);
 	void create_bezt(float frame, float output);
 
 public:
-	BCAnimationCurve(FCurve *fcu, Object *ob, BC_animation_curve_type type);
+	BCAnimationCurve();
 	~BCAnimationCurve();
 
 	const BC_animation_curve_type get_channel_type() const;
 	const std::string get_channel_target() const;
-	const std::string get_animation_name() const;
+	const std::string get_animation_name(Object *ob) const;
 	const int get_array_index() const;
+	const std::string get_rna_path() const;
+
 	const int size() const;
 	const int closest_index_above(float sample_frame, int start_at) const;
 	const int closest_index_below(float sample_frame) const;
 	const int get_ipo(float sample_frame) const;
-	const FCurve *get_fcurve() const;
-	FCurve *get_edit_fcurve();
-	Object *get_object() const;
+	Bone *get_bone(Object *ob) const;
+
 	void add_value(const float val, const int frame);
+	void init(Object *ob, BC_animation_curve_type type, std::string rna_path, int index);
+	void init(Object *ob, BC_animation_curve_type type, FCurve *fcu);
+	FCurve *get_edit_fcurve();
+	const FCurve *get_fcurve() const;
 
 	/*
 	Pick the value from the matrix accoridng to the definition of the FCurve
@@ -87,7 +134,6 @@ public:
 	returned vector is empty
 	*/
 	void get_frames(std::vector<float> &frames) const;
-
 	void get_frames(std::set<float> &frames) const;
 
 	/*
@@ -103,6 +149,7 @@ public:
 	returned vector is empty
 	*/
 	void get_values(std::vector<float> &values) const;
+	static bool is_flat_line(std::vector<float> &values);
 };
 
 
diff --git a/source/blender/collada/BCAnimationCurveContainer.cpp b/source/blender/collada/BCAnimationCurveContainer.cpp
index d83796acc0f..7522133

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list