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:
authorGaia Clary <gaia.clary@machinimatrix.org>2014-11-29 15:24:26 +0300
committerGaia Clary <gaia.clary@machinimatrix.org>2014-12-01 14:08:26 +0300
commit8d42c2f3ea4b37c6a538b2b01e4d00f98ca96100 (patch)
tree9bc903c5cd605b22892256cb33167f6c2e24a7f8
parente240bd39320101e44b6b7e714d46c9272f0f9613 (diff)
Improved Collada Armature Import
Collada does not support Bone length. It has only Joints. This patch tries to improve the necessary "guesswork" for importing Rigs. Differential Revision: https://developer.blender.org/D920
-rw-r--r--source/blender/collada/ArmatureImporter.cpp331
-rw-r--r--source/blender/collada/ArmatureImporter.h44
-rw-r--r--source/blender/collada/DocumentImporter.cpp2
-rw-r--r--source/blender/collada/ImportSettings.h3
-rw-r--r--source/blender/collada/collada.cpp6
-rw-r--r--source/blender/collada/collada.h4
-rw-r--r--source/blender/editors/io/io_collada.c42
7 files changed, 328 insertions, 104 deletions
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index 033145b33d1..db24bf6d0cf 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -37,6 +37,7 @@
#include "BKE_object.h"
#include "BKE_armature.h"
#include "BLI_string.h"
+#include "BLI_listbase.h"
#include "ED_armature.h"
#include "ArmatureImporter.h"
@@ -49,7 +50,23 @@ static const char *bc_get_joint_name(T *node)
return id.size() ? id.c_str() : node->getOriginalId().c_str();
}
-ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce) :
+static EditBone *get_edit_bone(bArmature * armature, char *name) {
+ EditBone *eBone;
+
+ eBone = (EditBone *)armature->edbo->first;
+ for (eBone; eBone; eBone = eBone->next) {
+ if (!strcmp(name, eBone->name))
+ return eBone;
+ }
+
+ return NULL;
+
+}
+
+
+
+ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce, const ImportSettings *import_settings) :
+ import_settings(import_settings),
unit_converter(conv),
TransformReader(conv),
scene(sce),
@@ -57,6 +74,15 @@ ArmatureImporter::ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh,
mesh_importer(mesh) {
}
+void ArmatureImporter::clear_extended_boneset()
+{
+ for (std::map<std::string, BoneExtended *>::iterator it = extended_bones.begin(); it != extended_bones.end(); ++it) {
+ if (it->second != NULL)
+ delete it->second;
+ }
+ extended_bones.clear();
+}
+
ArmatureImporter::~ArmatureImporter()
{
// free skin controller data if we forget to do this earlier
@@ -64,6 +90,7 @@ ArmatureImporter::~ArmatureImporter()
for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) {
it->second.free();
}
+ clear_extended_boneset();
}
#if 0
@@ -83,16 +110,17 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node);
}
#endif
-void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
+int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[4][4], bArmature *arm)
{
float mat[4][4];
float joint_inv_bind_mat[4][4];
+ int chain_length = 0;
//Checking if bone is already made.
std::vector<COLLADAFW::Node *>::iterator it;
it = std::find(finished_joints.begin(), finished_joints.end(), node);
- if (it != finished_joints.end()) return;
+ if (it != finished_joints.end()) return chain_length;
// JointData* jd = get_joint_data(node);
@@ -143,96 +171,150 @@ void ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBo
// set tail, don't set it to head because 0-length bones are not allowed
add_v3_v3v3(bone->tail, bone->head, vec);
- // set parent tail
+ /* find smallest bone length in armature (used later for leaf bone length) */
if (parent) {
- // XXX increase this to prevent "very" small bones?
- const float epsilon = 0.000001f;
-
- // derive leaf bone length
+ /* guess reasonable leaf bone length */
float length = len_v3v3(parent->head, bone->head);
- if ((length < leaf_bone_length || totbone == 0) && length > epsilon) {
+ if ((length < leaf_bone_length || totbone == 0) && length > MINIMUM_BONE_LENGTH) {
leaf_bone_length = length;
}
-
- if (totchild == 1) {
- copy_v3_v3(parent->tail, bone->head);
-
- // not setting BONE_CONNECTED because this would lock child bone location with respect to parent
- bone->flag |= BONE_CONNECTED;
-
-
- // treat zero-sized bone like a leaf bone
- if (length <= epsilon) {
- add_leaf_bone(parent_mat, parent, node);
- }
- }
-
}
COLLADAFW::NodePointerArray& children = node->getChildNodes();
+
+ BoneExtended &be = add_bone_extended(bone, node);
+ be.set_leaf_bone(true);
+
for (unsigned int i = 0; i < children.getCount(); i++) {
- create_bone(skin, children[i], bone, children.getCount(), mat, arm);
+ int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm);
+ if (cl > chain_length)
+ chain_length = cl;
}
- // in second case it's not a leaf bone, but we handle it the same way
- if (!children.getCount() || children.getCount() > 1) {
- add_leaf_bone(mat, bone, node);
- }
bone->length = len_v3v3(bone->head, bone->tail);
joint_by_uid[node->getUniqueId()] = node;
finished_joints.push_back(node);
+
+ be.set_chain_length(chain_length + 1);
+
+ return chain_length + 1;
}
-void ArmatureImporter::add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node *node)
+/**
+ * Collada only knows Joints, hence bones at the end of a bone chain
+ * don't have a defined length. This function guesses reasonable
+ * tail locations for the affected bones (nodes which don't have any connected child)
+ * Hint: The extended_bones set gets populated in ArmatureImporter::create_bone
+**/
+void ArmatureImporter::fix_bone_orientation(bArmature *armature, Bone *bone)
{
- LeafBone leaf;
+ /* armature has no bones */
+ if (bone == NULL)
+ return;
- leaf.bone = bone;
- copy_m4_m4(leaf.mat, mat);
- BLI_strncpy(leaf.name, bone->name, sizeof(leaf.name));
-
- TagsMap::iterator etit;
- ExtraTags *et = 0;
- etit = uid_tags_map.find(node->getUniqueId().toAscii());
- if (etit != uid_tags_map.end()) {
- et = etit->second;
- //else return;
+ BoneExtended *be = extended_bones[bone->name];
+ if (be != NULL && be->is_leaf_bone() ) {
+ /* Collada only knows Joints, Here we guess a reasonable leaf bone length */
+ float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0 : leaf_bone_length;
- float x, y, z;
- et->setData("tip_x", &x);
- et->setData("tip_y", &y);
- et->setData("tip_z", &z);
- float vec[3] = {x, y, z};
- copy_v3_v3(leaf.bone->tail, leaf.bone->head);
- add_v3_v3v3(leaf.bone->tail, leaf.bone->head, vec);
- }
- else {
- leaf_bones.push_back(leaf);
+ EditBone *ebone = get_edit_bone(armature, bone->name);
+
+ float vec[3];
+ if (ebone->parent != NULL) {
+ EditBone *parent = ebone->parent;
+ sub_v3_v3v3(vec, ebone->head, parent->tail);
+ if (len_squared_v3(vec) < MINIMUM_BONE_LENGTH)
+ {
+ sub_v3_v3v3(vec, parent->tail, parent->head);
+ }
+ }
+ else {
+ vec[2] = 0.1f;
+ sub_v3_v3v3(vec, ebone->tail, ebone->head);
+ }
+ normalize_v3_v3(vec, vec);
+ mul_v3_fl(vec, leaf_length);
+ add_v3_v3v3(ebone->tail, ebone->head, vec);
}
-}
-void ArmatureImporter::fix_leaf_bones( )
-{
- // Collada only knows Joints, Here we guess a reasonable
- // leaf bone length
- float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0:leaf_bone_length;
+ for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
+ fix_bone_orientation(armature, child);
+ }
- // just setting tail for leaf bones here
- std::vector<LeafBone>::iterator it;
- for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) {
+}
- LeafBone& leaf = *it;
- // pointing up
- float vec[3] = {0.0f, 0.0f, 0.1f};
-
- sub_v3_v3v3(vec, leaf.bone->tail , leaf.bone->head);
- mul_v3_fl(vec, leaf_length);
- add_v3_v3v3(leaf.bone->tail, leaf.bone->head , vec);
+void ArmatureImporter::connect_bone_chains(bArmature *armature, Bone *parentbone, int clip)
+{
+ BoneExtended *dominant_child = NULL;
+ int maxlen = 0;
+ Bone *child = (Bone *)parentbone->childbase.first;
+ if (child && (import_settings->find_chains || child->next==NULL) )
+ {
+ for (child; child; child = child->next) {
+ BoneExtended *be = extended_bones[child->name];
+ if (be != NULL) {
+ if (be->get_chain_length() <= clip) {
+ if (be->get_chain_length() > maxlen) {
+ dominant_child = be;
+ maxlen = be->get_chain_length();
+ }
+ else if (be->get_chain_length() == maxlen) {
+ dominant_child = NULL;
+ }
+ }
+ }
+ }
+ }
+ BoneExtended *pbe = extended_bones[parentbone->name];
+ if (dominant_child != NULL) {
+ /* Found a valid chain. Now connect current bone with that chain.*/
+ EditBone *pebone = get_edit_bone(armature, parentbone->name);
+ EditBone *cebone = get_edit_bone(armature, dominant_child->get_name());
+ if (pebone && !(cebone->flag & BONE_CONNECTED)) {
+
+ float vec[3];
+ sub_v3_v3v3(vec, cebone->head, pebone->head);
+
+ /*
+ * It is possible that the child's head is located on the parents head.
+ * When this happens, then moving the parent's tail to the child's head
+ * would result in a zero sized bone and Blender would silently remove the bone.
+ * So we move the tail only when the resulting bone has a minimum length:
+ */
+
+ if (len_squared_v3(vec) > MINIMUM_BONE_LENGTH)
+ {
+ pebone->tail[0] = cebone->head[0];
+ pebone->tail[1] = cebone->head[1];
+ pebone->tail[2] = cebone->head[2];
+
+ if (pbe && pbe->get_chain_length() >= this->import_settings->min_chain_length) {
+ cebone->flag |= BONE_CONNECTED;
+ printf("Connecting chain: parent %s --> %s (child)\n", pebone->name, cebone->name);
+ pbe->set_leaf_bone(false);
+ }
+ }
+ }
+ for (Bone *child = (Bone *)parentbone->childbase.first; child; child = child->next) {
+ ArmatureImporter::connect_bone_chains(armature, child, UNLIMITED_CHAIN_MAX);
+ }
+ }
+ else if (maxlen>1 && maxlen > this->import_settings->min_chain_length) {
+ /* Try again with smaller chain length */
+ ArmatureImporter::connect_bone_chains(armature, parentbone, maxlen - 1);
+ }
+ else {
+ /* can't connect this Bone. Proceed with children ... */
+ if (pbe) pbe->set_leaf_bone(true);
+ for (Bone *child = (Bone *)parentbone->childbase.first; child; child = child->next) {
+ ArmatureImporter::connect_bone_chains(armature, child, UNLIMITED_CHAIN_MAX);
+ }
}
+
}
#if 0
@@ -351,21 +433,26 @@ void ArmatureImporter::create_armature_bones( )
continue;
}
+ clear_extended_boneset();
+
ED_armature_to_edit(armature);
create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature);
- //leaf bone tails are derived from the matrix, so no need of this.
- fix_leaf_bones();
+ /* exit armature edit mode to populate the Armature object */
+ ED_armature_from_edit(armature);
+ ED_armature_edit_free(armature);
+
+ /* and step back to edit mode to fix the leaf nodes */
+ ED_armature_to_edit(armature);
+
+ connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
+ fix_bone_orientation(armature, (Bone *)armature->bonebase.first);
// exit armature edit mode
unskinned_armature_map[(*ri)->getUniqueId()] = ob_arm;
ED_armature_from_edit(armature);
-
- //This serves no purpose, as pose is automatically reset later, in BKE_where_is_bone()
- //set_pose(ob_arm, *ri, NULL, NULL);
-
ED_armature_edit_free(armature);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
}
@@ -459,9 +546,11 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
}
// enter armature edit mode
- ED_armature_to_edit((bArmature *)ob_arm->data);
+ bArmature * armature = (bArmature *)ob_arm->data;
+ ED_armature_to_edit(armature);
+
+ clear_extended_boneset();
- leaf_bones.clear();
totbone = 0;
// bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on default row
leaf_bone_length = FLT_MAX;
@@ -480,20 +569,27 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin)
// since root_joints may contain joints for multiple controllers, we need to filter
if (skin.uses_joint_or_descendant(*ri)) {
- create_bone(&skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, (bArmature *)ob_arm->data);
+ create_bone(&skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, armature);
if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent())
skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]);
}
}
- fix_leaf_bones();
+ /* exit armature edit mode to populate the Armature object */
+ ED_armature_from_edit(armature);
+ ED_armature_edit_free(armature);
+
+ /* and step back to edit mode to fix the leaf nodes */
+ ED_armature_to_edit(armature);
+
+ connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX);
+ fix_bone_orientation(armature, (Bone *)armature->bonebase.first);
// exit armature edit mode
- ED_armature_from_edit((bArmature *)ob_arm->data);
- ED_armature_edit_free((bArmature *)ob_arm->data);
+ ED_armature_from_edit(armature);
+ ED_armature_edit_free(armature);
DAG_id_tag_update(&ob_arm->id, OB_RECALC_OB | OB_RECALC_DATA);
-
}
void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4])
@@ -538,10 +634,11 @@ void ArmatureImporter::set_pose(Object *ob_arm, COLLADAFW::Node *root_node, con
}
-
-// root - if this joint is the top joint in hierarchy, if a joint
-// is a child of a node (not joint), root should be true since
-// this is where we build armature bones from
+/**
+ * root - if this joint is the top joint in hierarchy, if a joint
+ * is a child of a node (not joint), root should be true since
+ * this is where we build armature bones from
+ **/
void ArmatureImporter::add_root_joint(COLLADAFW::Node *node, Object *parent)
{
root_joints.push_back(node);
@@ -785,3 +882,71 @@ bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint)
return found;
}
+
+
+/**
+ * BoneExtended is a helper class needed for the Bone chain finder
+ * See ArmatureImporter::fix_bone_orientation()
+ * and ArmatureImporter::connect_bone_chains()
+ **/
+
+BoneExtended::BoneExtended(EditBone *aBone)
+{
+ this->set_name(aBone->name);
+ this->chain_length = 0;
+ this->is_leaf = false;
+}
+
+char *BoneExtended::get_name()
+{
+ return name;
+}
+
+void BoneExtended::set_name(char *aName)
+{
+ BLI_strncpy(name, aName, MAXBONENAME);
+}
+
+int BoneExtended::get_chain_length()
+{
+ return chain_length;
+}
+
+void BoneExtended::set_chain_length(const int aLength)
+{
+ chain_length = aLength;
+}
+
+
+void BoneExtended::set_leaf_bone(bool state)
+{
+ is_leaf = state;
+}
+
+bool BoneExtended::is_leaf_bone()
+{
+ return is_leaf;
+}
+
+BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node)
+{
+
+ TagsMap::iterator etit;
+ ExtraTags *et = 0;
+ etit = uid_tags_map.find(node->getUniqueId().toAscii());
+ if (etit != uid_tags_map.end()) {
+ float x, y, z;
+
+ et = etit->second;
+ et->setData("tip_x", &x);
+ et->setData("tip_y", &y);
+ et->setData("tip_z", &z);
+ float vec[3] = { x, y, z };
+ copy_v3_v3(bone->tail, bone->head);
+ add_v3_v3v3(bone->tail, bone->head, vec);
+ }
+
+ BoneExtended *be = new BoneExtended(bone);
+ extended_bones[bone->name] = be;
+ return *be;
+}
diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h
index beeac85cc4d..e09906e6c92 100644
--- a/source/blender/collada/ArmatureImporter.h
+++ b/source/blender/collada/ArmatureImporter.h
@@ -54,23 +54,41 @@ extern "C" {
#include "collada_internal.h"
#include "collada_utils.h"
+#include "ImportSettings.h"
+
+#define UNLIMITED_CHAIN_MAX INT_MAX
+#define MINIMUM_BONE_LENGTH 0.000001f
+
+class BoneExtended {
+
+private:
+ char name[MAXBONENAME];
+ int chain_length;
+ bool is_leaf;
+
+public:
+
+ BoneExtended(EditBone *aBone);
+ char *get_name();
+ int get_chain_length();
+
+ void set_name(char *aName);
+ void set_chain_length(const int aLength);
+ void set_leaf_bone(bool state);
+ bool is_leaf_bone();
+};
class ArmatureImporter : private TransformReader
{
private:
Scene *scene;
UnitConverter *unit_converter;
+ const ImportSettings *import_settings;
// std::map<int, JointData> joint_index_to_joint_info_map;
// std::map<COLLADAFW::UniqueId, int> joint_id_to_joint_index_map;
- struct LeafBone {
- // COLLADAFW::Node *node;
- EditBone *bone;
- char name[32];
- float mat[4][4]; // bone matrix, derived from inv_bind_mat
- };
- std::vector<LeafBone> leaf_bones;
+ std::map<std::string, BoneExtended *> extended_bones;
// int bone_direction_row; // XXX not used
float leaf_bone_length;
int totbone;
@@ -106,13 +124,15 @@ private:
JointData *get_joint_data(COLLADAFW::Node *node);
#endif
- void create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
+ int create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild,
float parent_mat[4][4], bArmature *arm);
- void add_leaf_bone(float mat[4][4], EditBone *bone, COLLADAFW::Node * node);
+ BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node);
+ void clear_extended_boneset();
+
+ void fix_bone_orientation(bArmature *armature, Bone *bone);
+ void connect_bone_chains(bArmature *armature, Bone *bone, const int max_chain_length);
- void fix_leaf_bones();
-
void set_pose( Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]);
@@ -137,7 +157,7 @@ private:
TagsMap uid_tags_map;
public:
- ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce);
+ ArmatureImporter(UnitConverter *conv, MeshImporterBase *mesh, Scene *sce, const ImportSettings *import_settings);
~ArmatureImporter();
void add_root_joint(COLLADAFW::Node *node, Object *parent);
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 8101e579098..20ef45b6b71 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -104,7 +104,7 @@ DocumentImporter::DocumentImporter(bContext *C, const ImportSettings *import_set
import_settings(import_settings),
mImportStage(General),
mContext(C),
- armature_importer(&unit_converter, &mesh_importer, CTX_data_scene(C)),
+ armature_importer(&unit_converter, &mesh_importer, CTX_data_scene(C), import_settings),
mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)),
anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C))
{
diff --git a/source/blender/collada/ImportSettings.h b/source/blender/collada/ImportSettings.h
index 3f3a9fb354e..f2185b13c50 100644
--- a/source/blender/collada/ImportSettings.h
+++ b/source/blender/collada/ImportSettings.h
@@ -32,7 +32,8 @@
struct ImportSettings {
public:
bool import_units;
-
+ bool find_chains;
+ int min_chain_length;
char *filepath;
};
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index ffbbb8623ac..826d634b8f1 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -44,13 +44,17 @@ extern "C"
int collada_import(bContext *C,
const char *filepath,
- int import_units)
+ int import_units,
+ int find_chains,
+ int min_chain_length)
{
ImportSettings import_settings;
import_settings.filepath = (char *)filepath;
import_settings.import_units = import_units != 0;
+ import_settings.find_chains = find_chains != 0;
+ import_settings.min_chain_length = min_chain_length;
DocumentImporter imp(C, &import_settings);
if (imp.import()) return 1;
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index 524c704cdee..0a2713b1db5 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -55,7 +55,9 @@ struct Scene;
*/
int collada_import(struct bContext *C,
const char *filepath,
- int import_units);
+ int import_units,
+ int find_chains,
+ int min_chain_length);
int collada_export(struct Scene *sce,
const char *filepath,
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index bbf4447dd72..b45f3ccde2a 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -365,6 +365,8 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
{
char filename[FILE_MAX];
int import_units;
+ int find_chains;
+ int min_chain_length;
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
BKE_report(op->reports, RPT_ERROR, "No filename given");
@@ -372,10 +374,15 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op)
}
/* Options panel */
- import_units = RNA_boolean_get(op->ptr, "import_units");
+ import_units = RNA_boolean_get(op->ptr, "import_units");
+ find_chains = RNA_boolean_get(op->ptr, "find_chains");
+ min_chain_length = RNA_int_get(op->ptr, "min_chain_length");
RNA_string_get(op->ptr, "filepath", filename);
- if (collada_import(C, filename, import_units)) {
+ if (collada_import(C, filename,
+ import_units,
+ find_chains,
+ min_chain_length)) {
return OPERATOR_FINISHED;
}
else {
@@ -395,6 +402,17 @@ static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr)
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "import_units", 0, NULL, ICON_NONE);
+
+ box = uiLayoutBox(layout);
+ row = uiLayoutRow(box, false);
+ uiItemL(row, IFACE_("Armature Options:"), ICON_MESH_DATA);
+
+ row = uiLayoutRow(box, false);
+ uiItemR(row, imfptr, "find_chains", 0, NULL, ICON_NONE);
+
+ row = uiLayoutRow(box, false);
+ uiItemR(row, imfptr, "min_chain_length", 0, NULL, ICON_NONE);
+
}
static void wm_collada_import_draw(bContext *UNUSED(C), wmOperator *op)
@@ -423,9 +441,23 @@ void WM_OT_collada_import(wmOperatorType *ot)
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
RNA_def_boolean(ot->srna,
- "import_units", 0, "Import Units",
- "If disabled match import to Blender's current Unit settings, "
- "otherwise use the settings from the Imported scene");
+ "import_units", 0, "Import Units",
+ "If disabled match import to Blender's current Unit settings, "
+ "otherwise use the settings from the Imported scene");
+
+ RNA_def_boolean(ot->srna,
+ "find_chains", 0, "Find Bone Chains",
+ "Find best matching Bone Chains and ensure bones in chain are connected");
+
+ RNA_def_int(ot->srna,
+ "min_chain_length",
+ 0,
+ 0,
+ INT_MAX,
+ "Minimum Chain Length",
+ "When searching Bone Chains disregard chains of length below this value",
+ 0,
+ INT_MAX);
}
#endif