From 5366900acec5dccaafb1afe21a61679404ddcfff Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Sun, 29 May 2016 00:35:50 +0200 Subject: Added support for non numeric bone layer labels (could happen when importing from other tools) Differential Revision: https://developer.blender.org/D2037 --- source/blender/collada/ArmatureImporter.cpp | 19 +++++++------- source/blender/collada/ArmatureImporter.h | 4 +-- source/blender/collada/collada_utils.cpp | 39 +++++++++++++++++------------ source/blender/collada/collada_utils.h | 2 +- 4 files changed, 36 insertions(+), 28 deletions(-) (limited to 'source/blender/collada') diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index 496ca4efd06..fca9b9ffa55 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -97,7 +97,7 @@ JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node); #endif int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[4][4], bArmature *arm) + float parent_mat[4][4], bArmature *arm, std::vector &layer_labels) { float mat[4][4]; float joint_inv_bind_mat[4][4]; @@ -145,7 +145,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon float loc[3], size[3], rot[3][3]; - BoneExtended &be = add_bone_extended(bone, node); + BoneExtended &be = add_bone_extended(bone, node, layer_labels); int layer = be.get_bone_layers(); if (layer) bone->layer = layer; arm->layer |= layer; // ensure that all populated bone layers are visible after import @@ -162,14 +162,13 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon if (be.has_roll()) { bone->roll = be.get_roll(); - } + } else { float angle; mat4_to_loc_rot_size(loc, rot, size, mat); mat3_to_vec_roll(rot, NULL, &angle); } - copy_v3_v3(bone->head, mat[3]); add_v3_v3v3(bone->tail, bone->head, tail); //tail must be non zero @@ -190,7 +189,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon COLLADAFW::NodePointerArray& children = node->getChildNodes(); for (unsigned int i = 0; i < children.getCount(); i++) { - int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm); + int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm, layer_labels); if (cl > chain_length) chain_length = cl; } @@ -438,6 +437,7 @@ ArmatureJoints& ArmatureImporter::get_armature_joints(Object *ob_arm) void ArmatureImporter::create_armature_bones( ) { std::vector::iterator ri; + std::vector layer_labels; leaf_bone_length = FLT_MAX; //if there is an armature created for root_joint next root_joint @@ -464,7 +464,7 @@ void ArmatureImporter::create_armature_bones( ) ED_armature_to_edit(armature); armature->layer = 0; // layer is set according to imported bone set in create_bone() - create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature); + create_bone(NULL, *ri , NULL, (*ri)->getChildNodes().getCount(), NULL, armature, layer_labels); /* exit armature edit mode to populate the Armature object */ ED_armature_from_edit(armature); @@ -540,6 +540,7 @@ void ArmatureImporter::create_armature_bones(SkinInfo& skin) SkinInfo *a = &skin; Object *shared = NULL; std::vector skin_root_joints; + std::vector layer_labels; std::map::iterator it; for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { @@ -605,7 +606,7 @@ 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, armature); + create_bone(&skin, *ri, NULL, (*ri)->getChildNodes().getCount(), NULL, armature, layer_labels); if (joint_parent_map.find((*ri)->getUniqueId()) != joint_parent_map.end() && !skin.get_parent()) skin.set_parent(joint_parent_map[(*ri)->getUniqueId()]); @@ -921,7 +922,7 @@ bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint) return found; } -BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node) +BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Node *node, std::vector &layer_labels) { BoneExtended *be = new BoneExtended(bone); extended_bones[bone->name] = be; @@ -953,7 +954,7 @@ BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, COLLADAFW::Nod use_connect = 0; // got a bone tail definition but no connect info -> bone is not connected } - be->set_bone_layers(layers); + be->set_bone_layers(layers, layer_labels); if (has_tail) be->set_tail(tail); if (has_roll) be->set_roll(roll); be->set_use_connect(use_connect); diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index fba8c5bd5d6..f38bd1a6c66 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -106,9 +106,9 @@ private: #endif int create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[4][4], bArmature *arm); + float parent_mat[4][4], bArmature *arm, std::vector &layer_labels); - BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node); + BoneExtended &add_bone_extended(EditBone *bone, COLLADAFW::Node * node, std::vector &layer_labels); void clear_extended_boneset(); void fix_leaf_bones(bArmature *armature, Bone *bone); diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index c510eb6e0e8..5a84eedd6e0 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -505,34 +505,41 @@ inline bool isInteger(const std::string & s) return (*p == 0); } -void BoneExtended::set_bone_layers(std::string layerString) +void BoneExtended::set_bone_layers(std::string layerString, std::vector &layer_labels) { std::stringstream ss(layerString); - std::istream_iterator begin(ss); - std::istream_iterator end; - std::vector layers(begin, end); + std::string layer; + int pos; - for (std::vector::iterator it = layers.begin(); it != layers.end(); ++it) { - std::string layer = *it; - int index = -1; + while (ss >> layer) { + /* Blender uses numbers to specify layers*/ if (isInteger(layer)) { - index = std::stoi(layer); - if (index < 0 || index > 31) - index - 1; + pos = std::stoi(layer); + if (pos >= 0 || pos < 32) { + this->bone_layers = bc_set_layer(this->bone_layers, pos); + continue; + } } - if (index == -1) - { - //TODO - int x = index; + /* layer uses labels (not supported by blender). Map to layer numbers:*/ + pos = find(layer_labels.begin(), layer_labels.end(), layer) - layer_labels.begin(); + if (pos >= layer_labels.size()) { + layer_labels.push_back(layer); /* remember layer number for future usage*/ } - if (index != -1) + if (pos > 31) { - this->bone_layers = bc_set_layer(this->bone_layers, index); + fprintf(stderr, "Too many layers in Import. Layer %s mapped to Blender layer 31\n", layer.c_str()); + pos = 31; } + + /* If numeric layers and labeled layers are used in parallel (unlikely), + we get a potential mixup. Just leave as is for now. + */ + this->bone_layers = bc_set_layer(this->bone_layers, pos); + } } diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index e9f84afef61..c821a5dd267 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -136,7 +136,7 @@ public: void set_leaf_bone(bool state); bool is_leaf_bone(); - void set_bone_layers(std::string layers); + void set_bone_layers(std::string layers, std::vector &layer_labels); int get_bone_layers(); static std::string get_bone_layers(int bitfield); -- cgit v1.2.3