diff options
Diffstat (limited to 'source/blender/collada')
25 files changed, 572 insertions, 268 deletions
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index 9582da4fe5c..57829f777c5 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -1114,7 +1114,7 @@ bool AnimationExporter::hasAnimations(Scene *sce) { LinkNode *node; - for(node=this->export_settings->export_set; node; node=node->next) { + for (node=this->export_settings->export_set; node; node=node->next) { Object *ob = (Object *)node->link; FCurve *fcu = 0; diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp index 625804e4ecd..4182a9c4c93 100644 --- a/source/blender/collada/AnimationImporter.cpp +++ b/source/blender/collada/AnimationImporter.cpp @@ -473,10 +473,10 @@ void AnimationImporter:: Assign_transform_animations(COLLADAFW::Transformation * { COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType(); bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX; - bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; + bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; //to check if the no of curves are valid - bool xyz = ((tm_type == COLLADAFW::Transformation::TRANSLATE || tm_type == COLLADAFW::Transformation::SCALE) && binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ); + bool xyz = ((tm_type == COLLADAFW::Transformation::TRANSLATE || tm_type == COLLADAFW::Transformation::SCALE) && binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ); if (!((!xyz && curves->size() == 1) || (xyz && curves->size() == 3) || is_matrix)) { diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 98047df8aa4..c5feb62fd80 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -80,6 +80,18 @@ bool ArmatureExporter::is_skinned_mesh(Object *ob) return bc_get_assigned_armature(ob) != NULL; } + +void ArmatureExporter::write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone) +{ + if (bc_is_root_bone(bone, this->export_settings->deform_bones_only)) + ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm))); + else { + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + write_bone_URLs(ins, ob_arm, child); + } + } +} + bool ArmatureExporter::add_instance_controller(Object *ob) { Object *ob_arm = bc_get_assigned_armature(ob); @@ -96,11 +108,10 @@ bool ArmatureExporter::add_instance_controller(Object *ob) // write root bone URLs Bone *bone; for (bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) { - if (!bone->parent) - ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_joint_id(bone, ob_arm))); + write_bone_URLs(ins, ob_arm, bone); } - InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob); + InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob, this->export_settings->active_uv_only); ins.add(); return true; @@ -164,67 +175,76 @@ void ArmatureExporter::add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se, std::list<Object *>& child_objects) { - std::string node_id = get_joint_id(bone, ob_arm); - std::string node_name = std::string(bone->name); - std::string node_sid = get_joint_sid(bone, ob_arm); + if (!(this->export_settings->deform_bones_only && bone->flag & BONE_NO_DEFORM)) { + std::string node_id = get_joint_id(bone, ob_arm); + std::string node_name = std::string(bone->name); + std::string node_sid = get_joint_sid(bone, ob_arm); - COLLADASW::Node node(mSW); + COLLADASW::Node node(mSW); - node.setType(COLLADASW::Node::JOINT); - node.setNodeId(node_id); - node.setNodeName(node_name); - node.setNodeSid(node_sid); + node.setType(COLLADASW::Node::JOINT); + node.setNodeId(node_id); + node.setNodeName(node_name); + node.setNodeSid(node_sid); - /*if ( bone->childbase.first == NULL || BLI_countlist(&(bone->childbase))>=2) - add_blender_leaf_bone( bone, ob_arm , node ); - else{*/ - node.start(); +#if 0 + if (bone->childbase.first == NULL || BLI_countlist(&(bone->childbase)) >= 2) { + add_blender_leaf_bone( bone, ob_arm , node ); + } + else { +#endif + node.start(); - add_bone_transform(ob_arm, bone, node); + add_bone_transform(ob_arm, bone, node); - // Write nodes of childobjects, remove written objects from list - std::list<Object *>::iterator i = child_objects.begin(); + // Write nodes of childobjects, remove written objects from list + std::list<Object *>::iterator i = child_objects.begin(); - while (i != child_objects.end()) { - if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) { - float backup_parinv[4][4]; - copy_m4_m4(backup_parinv, (*i)->parentinv); + while (i != child_objects.end()) { + if ((*i)->partype == PARBONE && (0 == strcmp((*i)->parsubstr, bone->name))) { + float backup_parinv[4][4]; + copy_m4_m4(backup_parinv, (*i)->parentinv); - // crude, temporary change to parentinv - // so transform gets exported correctly. + // crude, temporary change to parentinv + // so transform gets exported correctly. - // Add bone tail- translation... don't know why - // bone parenting is against the tail of a bone - // and not it's head, seems arbitrary. - (*i)->parentinv[3][1] += bone->length; + // Add bone tail- translation... don't know why + // bone parenting is against the tail of a bone + // and not it's head, seems arbitrary. + (*i)->parentinv[3][1] += bone->length; - // SECOND_LIFE_COMPATIBILITY - // TODO: when such objects are animated as - // single matrix the tweak must be applied - // to the result. - if (export_settings->second_life) { - // tweak objects parentinverse to match compatibility - float temp[4][4]; + // SECOND_LIFE_COMPATIBILITY + // TODO: when such objects are animated as + // single matrix the tweak must be applied + // to the result. + if (export_settings->second_life) { + // tweak objects parentinverse to match compatibility + float temp[4][4]; - copy_m4_m4(temp, bone->arm_mat); - temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; + copy_m4_m4(temp, bone->arm_mat); + temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; - mult_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv); - } + mult_m4_m4m4((*i)->parentinv, temp, (*i)->parentinv); + } - se->writeNodes(*i, sce); + se->writeNodes(*i, sce); - copy_m4_m4((*i)->parentinv, backup_parinv); - child_objects.erase(i++); + copy_m4_m4((*i)->parentinv, backup_parinv); + child_objects.erase(i++); + } + else i++; } - else i++; - } - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - add_bone_node(child, ob_arm, sce, se, child_objects); + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + add_bone_node(child, ob_arm, sce, se, child_objects); + } + node.end(); + } + else { + for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { + add_bone_node(child, ob_arm, sce, se, child_objects); + } } - node.end(); - //} } #if 0 @@ -325,7 +345,7 @@ void ArmatureExporter::export_controller(Object *ob, Object *ob_arm) Mesh *me; if (this->export_settings->apply_modifiers) { - me = bc_to_mesh_apply_modifiers(scene, ob); + me = bc_to_mesh_apply_modifiers(scene, ob, this->export_settings->export_mesh_type); } else { me = (Mesh *)ob->data; diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h index beef77af767..086c16f0cd5 100644 --- a/source/blender/collada/ArmatureExporter.h +++ b/source/blender/collada/ArmatureExporter.h @@ -53,14 +53,14 @@ class SceneExporter; // XXX exporter writes wrong data for shared armatures. A separate // controller should be written for each armature-mesh binding how do // we make controller ids then? -class ArmatureExporter: public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter +class ArmatureExporter : public COLLADASW::LibraryControllers, protected TransformWriter, protected InstanceWriter { public: ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings); // write bone nodes - void add_armature_bones(Object *ob_arm, Scene* sce, SceneExporter* se, - std::list<Object*>& child_objects); + void add_armature_bones(Object *ob_arm, Scene *sce, SceneExporter *se, + std::list<Object *>& child_objects); bool is_skinned_mesh(Object *ob); @@ -76,7 +76,7 @@ private: const ExportSettings *export_settings; #if 0 - std::vector<Object*> written_armatures; + std::vector<Object *> written_armatures; bool already_written(Object *ob_arm); @@ -89,8 +89,8 @@ private: // Scene, SceneExporter and the list of child_objects // are required for writing bone parented objects - void add_bone_node(Bone *bone, Object *ob_arm, Scene* sce, SceneExporter* se, - std::list<Object*>& child_objects); + void add_bone_node(Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se, + std::list<Object *>& child_objects); void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node); @@ -100,10 +100,10 @@ private: // ob should be of type OB_MESH // both args are required - void export_controller(Object* ob, Object *ob_arm); + void export_controller(Object *ob, Object *ob_arm); void add_joints_element(ListBase *defbase, - const std::string& joints_source_id, const std::string& inv_bind_mat_source_id); + const std::string& joints_source_id, const std::string& inv_bind_mat_source_id); void add_bind_shape_mat(Object *ob); @@ -111,15 +111,17 @@ private: std::string add_inv_bind_mats_source(Object *ob_arm, ListBase *defbase, const std::string& controller_id); - Bone *get_bone_from_defgroup(Object *ob_arm, bDeformGroup* def); + Bone *get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def); - bool is_bone_defgroup(Object *ob_arm, bDeformGroup* def); + bool is_bone_defgroup(Object *ob_arm, bDeformGroup *def); std::string add_weights_source(Mesh *me, const std::string& controller_id, - const std::list<float>& weights); + const std::list<float>& weights); void add_vertex_weights_element(const std::string& weights_source_id, const std::string& joints_source_id, - const std::list<int>& vcount, const std::list<int>& joints); + const std::list<int>& vcount, const std::list<int>& joints); + + void write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone); }; #endif diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp index 115f129cb88..cd2574d055e 100644 --- a/source/blender/collada/ArmatureImporter.cpp +++ b/source/blender/collada/ArmatureImporter.cpp @@ -279,7 +279,7 @@ void ArmatureImporter::add_leaf_bone(float mat[][4], EditBone *bone, COLLADAFW: TagsMap::iterator etit; ExtraTags *et = 0; etit = uid_tags_map.find(node->getUniqueId().toAscii()); - if (etit != uid_tags_map.end()) { + if (etit != uid_tags_map.end()) { et = etit->second; //else return; diff --git a/source/blender/collada/CMakeLists.txt b/source/blender/collada/CMakeLists.txt index 58a65db0489..3b7a38eb950 100644 --- a/source/blender/collada/CMakeLists.txt +++ b/source/blender/collada/CMakeLists.txt @@ -34,6 +34,7 @@ set(INC ../makesdna ../makesrna ../windowmanager + ../imbuf ../../../intern/guardedalloc ) diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 6c9d277de54..ca07512f439 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -386,7 +386,7 @@ Object *DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Nod Object *new_child = NULL; if (inodes.getCount()) { // \todo loop through instance nodes const COLLADAFW::UniqueId& id = inodes[0]->getInstanciatedObjectId(); - fprintf(stderr, "Doing %d child nodes\n", node_map.count(id)); + fprintf(stderr, "Doing %d child nodes\n", (int)node_map.count(id)); new_child = create_instance_node(object_map.find(id)->second, node_map[id], child_node, sce, is_library_node); } else { diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp index 3ed689628f7..f11ecc7f16d 100644 --- a/source/blender/collada/EffectExporter.cpp +++ b/source/blender/collada/EffectExporter.cpp @@ -27,6 +27,7 @@ #include <map> +#include <set> #include "COLLADASWEffectProfile.h" @@ -39,6 +40,8 @@ #include "DNA_world_types.h" #include "BKE_customdata.h" +#include "BKE_mesh.h" +#include "BKE_material.h" #include "collada_internal.h" #include "collada_utils.h" @@ -118,11 +121,60 @@ void EffectsExporter::writePhong(COLLADASW::EffectProfile &ep, Material *ma) ep.setSpecular(cot, false, "specular"); } +void EffectsExporter::writeTextures(COLLADASW::EffectProfile &ep, + std::string &key, + COLLADASW::Sampler *sampler, + MTex *t, Image *ima, + std::string &uvname ) { + + // Image not set for texture + if (!ima) return; + + // color + if (t->mapto & (MAP_COL | MAP_COLSPEC)) { + ep.setDiffuse(createTexture(ima, uvname, sampler), false, "diffuse"); + } + // ambient + if (t->mapto & MAP_AMB) { + ep.setAmbient(createTexture(ima, uvname, sampler), false, "ambient"); + } + // specular + if (t->mapto & MAP_SPEC) { + ep.setSpecular(createTexture(ima, uvname, sampler), false, "specular"); + } + // emission + if (t->mapto & MAP_EMIT) { + ep.setEmission(createTexture(ima, uvname, sampler), false, "emission"); + } + // reflective + if (t->mapto & MAP_REF) { + ep.setReflective(createTexture(ima, uvname, sampler)); + } + // alpha + if (t->mapto & MAP_ALPHA) { + ep.setTransparent(createTexture(ima, uvname, sampler)); + } + // extension: + // Normal map --> Must be stored with <extra> tag as different technique, + // since COLLADA doesn't support normal maps, even in current COLLADA 1.5. + if (t->mapto & MAP_NORM) { + COLLADASW::Texture texture(key); + texture.setTexcoord(uvname); + texture.setSampler(*sampler); + // technique FCOLLADA, with the <bump> tag, is most likely the best understood, + // most widespread de-facto standard. + texture.setProfileName("FCOLLADA"); + texture.setChildElementName("bump"); + ep.addExtraTechniqueColorOrTexture(COLLADASW::ColorOrTexture(texture)); + } +} + void EffectsExporter::operator()(Material *ma, Object *ob) { // create a list of indices to textures of type TEX_IMAGE std::vector<int> tex_indices; - createTextureIndices(ma, tex_indices); + if(this->export_settings->include_material_textures) + createTextureIndices(ma, tex_indices); openEffect(translate_id(id_name(ma)) + "-effect"); @@ -256,6 +308,52 @@ void EffectsExporter::operator()(Material *ma, Object *ob) } } + + std::set<Image *> uv_textures; + if (ob->type == OB_MESH && ob->totcol && this->export_settings->include_uv_textures) { + Mesh *me = (Mesh *) ob->data; + BKE_mesh_tessface_ensure(me); + for (int i = 0; i < me->pdata.totlayer; i++) { + if (me->pdata.layers[i].type == CD_MTEXPOLY) { + MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; + MFace *mface = me->mface; + for (int j = 0; j < me->totpoly; j++, mface++, txface++) { + + Material *mat = give_current_material(ob, mface->mat_nr + 1); + if (mat != ma) + continue; + + Image *ima = txface->tpage; + if (ima == NULL) + continue; + + + bool not_in_list = uv_textures.find(ima)==uv_textures.end(); + if (not_in_list) { + std::string name = id_name(ima); + std::string key(name); + key = translate_id(key); + + // create only one <sampler>/<surface> pair for each unique image + if (im_samp_map.find(key) == im_samp_map.end()) { + //<newparam> <sampler> <source> + COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, + key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, + key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); + sampler.setImageId(key); + samplers[a] = sampler; + samp_surf[b][0] = &samplers[a]; + im_samp_map[key] = b; + b++; + a++; + uv_textures.insert(ima); + } + } + } + } + } + } + // used as fallback when MTex->uvname is "" (this is pretty common) // it is indeed the correct value to use in that case std::string active_uv(getActiveUVLayerName(ob)); @@ -265,58 +363,25 @@ void EffectsExporter::operator()(Material *ma, Object *ob) for (a = 0; a < tex_indices.size(); a++) { MTex *t = ma->mtex[tex_indices[a]]; Image *ima = t->tex->ima; - - // Image not set for texture - if (!ima) continue; - - // we assume map input is always TEXCO_UV std::string key(id_name(ima)); key = translate_id(key); int i = im_samp_map[key]; - COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0]; - //COLLADASW::Surface *surface = (COLLADASW::Surface*)samp_surf[i][1]; - std::string uvname = strlen(t->uvname) ? t->uvname : active_uv; + COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0]; + writeTextures(ep, key, sampler, t, ima, uvname); + } - // color - if (t->mapto & (MAP_COL | MAP_COLSPEC)) { - ep.setDiffuse(createTexture(ima, uvname, sampler), false, "diffuse"); - } - // ambient - if (t->mapto & MAP_AMB) { - ep.setAmbient(createTexture(ima, uvname, sampler), false, "ambient"); - } - // specular - if (t->mapto & MAP_SPEC) { - ep.setSpecular(createTexture(ima, uvname, sampler), false, "specular"); - } - // emission - if (t->mapto & MAP_EMIT) { - ep.setEmission(createTexture(ima, uvname, sampler), false, "emission"); - } - // reflective - if (t->mapto & MAP_REF) { - ep.setReflective(createTexture(ima, uvname, sampler)); - } - // alpha - if (t->mapto & MAP_ALPHA) { - ep.setTransparent(createTexture(ima, uvname, sampler)); - } - // extension: - // Normal map --> Must be stored with <extra> tag as different technique, - // since COLLADA doesn't support normal maps, even in current COLLADA 1.5. - if (t->mapto & MAP_NORM) { - COLLADASW::Texture texture(key); - texture.setTexcoord(uvname); - texture.setSampler(*sampler); - // technique FCOLLADA, with the <bump> tag, is most likely the best understood, - // most widespread de-facto standard. - texture.setProfileName("FCOLLADA"); - texture.setChildElementName("bump"); - ep.addExtraTechniqueColorOrTexture(COLLADASW::ColorOrTexture(texture)); - } + std::set<Image *>::iterator uv_t_iter; + for(uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++ ) { + Image *ima = *uv_t_iter; + std::string key(id_name(ima)); + key = translate_id(key); + int i = im_samp_map[key]; + COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0]; + ep.setDiffuse(createTexture(ima, active_uv, sampler), false, "diffuse"); } + // performs the actual writing ep.addProfileElements(); bool twoSided = false; diff --git a/source/blender/collada/EffectExporter.h b/source/blender/collada/EffectExporter.h index 6b7caf439b7..d20cbfdfe0b 100644 --- a/source/blender/collada/EffectExporter.h +++ b/source/blender/collada/EffectExporter.h @@ -64,7 +64,12 @@ private: void writeBlinn(COLLADASW::EffectProfile &ep, Material *ma); void writeLambert(COLLADASW::EffectProfile &ep, Material *ma); void writePhong(COLLADASW::EffectProfile &ep, Material *ma); - + void writeTextures(COLLADASW::EffectProfile &ep, + std::string &key, + COLLADASW::Sampler *sampler, + MTex *t, Image *ima, + std::string &uvname ); + bool hasEffects(Scene *sce); const ExportSettings *export_settings; diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h index e856eefab99..2504c276036 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -24,25 +24,32 @@ * \ingroup collada */ -extern "C" { -#include "BLI_linklist.h" -} - #ifndef __EXPORTSETTINGS_H__ #define __EXPORTSETTINGS_H__ -struct ExportSettings -{ - public: - bool selected; - bool apply_modifiers; - bool include_armatures; - bool include_children; - bool use_object_instantiation; - bool sort_by_name; - bool second_life; - char *filepath; - LinkNode *export_set; +#include "collada.h" + +struct ExportSettings { +public: + bool apply_modifiers; + BC_export_mesh_type export_mesh_type; + + bool selected; + bool include_children; + bool include_armatures; + bool deform_bones_only; + + bool active_uv_only; + bool include_uv_textures; + bool include_material_textures; + bool use_texture_copies; + + bool use_object_instantiation; + bool sort_by_name; + bool second_life; + + char *filepath; + LinkNode *export_set; }; #endif diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 94b977ca01c..c3d1106b288 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -78,7 +78,7 @@ void GeometryExporter::operator()(Object *ob) bool use_instantiation = this->export_settings->use_object_instantiation; Mesh *me; if (this->export_settings->apply_modifiers) { - me = bc_to_mesh_apply_modifiers(mScene, ob); + me = bc_to_mesh_apply_modifiers(mScene, ob, this->export_settings->export_mesh_type); } else { me = (Mesh *)ob->data; @@ -261,8 +261,9 @@ void GeometryExporter::createPolylist(short material_index, // sets material name if (ma) { + std::string material_id = get_material_id(ma); std::ostringstream ostr; - ostr << translate_id(id_name(ma)); + ostr << translate_id(material_id); polylist.setMaterial(ostr.str()); } @@ -436,33 +437,38 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) // write <source> for each layer // each <source> will get id like meshName + "map-channel-1" + int map_index = 0; + int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1; for (int a = 0; a < num_layers; a++) { - MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); - // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a); - - COLLADASW::FloatSourceF source(mSW); - std::string layer_id = makeTexcoordSourceId(geom_id, a); - source.setId(layer_id); - source.setArrayId(layer_id + ARRAY_ID_SUFFIX); - - source.setAccessorCount(totuv); - source.setAccessorStride(2); - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("S"); - param.push_back("T"); - - source.prepareToAppendValues(); - - for (i = 0; i < totfaces; i++) { - MFace *f = &mfaces[i]; + + if (!this->export_settings->active_uv_only || a == active_uv_index) { + MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); + // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a); - for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { - source.appendValues(tface[i].uv[j][0], - tface[i].uv[j][1]); + COLLADASW::FloatSourceF source(mSW); + std::string layer_id = makeTexcoordSourceId(geom_id, map_index++); + source.setId(layer_id); + source.setArrayId(layer_id + ARRAY_ID_SUFFIX); + + source.setAccessorCount(totuv); + source.setAccessorStride(2); + COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); + param.push_back("S"); + param.push_back("T"); + + source.prepareToAppendValues(); + + for (i = 0; i < totfaces; i++) { + MFace *f = &mfaces[i]; + + for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) { + source.appendValues(tface[i].uv[j][0], + tface[i].uv[j][1]); + } } + + source.finish(); } - - source.finish(); } } diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp index c777a7d1fab..f789cfe3660 100644 --- a/source/blender/collada/ImageExporter.cpp +++ b/source/blender/collada/ImageExporter.cpp @@ -29,22 +29,150 @@ #include "COLLADABUURI.h" #include "COLLADASWImage.h" -#include "ImageExporter.h" -#include "MaterialExporter.h" - +extern "C" { #include "DNA_texture_types.h" +#include "DNA_image_types.h" +#include "DNA_meshdata_types.h" +#include "BKE_customdata.h" #include "BKE_global.h" +#include "BKE_image.h" #include "BKE_main.h" +#include "BKE_mesh.h" #include "BKE_utildefines.h" #include "BLI_fileops.h" #include "BLI_path_util.h" #include "BLI_string.h" +#include "IMB_imbuf_types.h" +} + +#include "ImageExporter.h" +#include "MaterialExporter.h" + ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryImages(sw), export_settings(export_settings) { } +void ImagesExporter::export_UV_Image(Image *image, bool use_copies) +{ + std::string name(id_name(image)); + std::string translated_name(translate_id(name)); + bool not_yet_exported = find(mImages.begin(), mImages.end(), translated_name) == mImages.end(); + + if (not_yet_exported) { + + ImBuf *imbuf = BKE_image_get_ibuf(image, NULL); + bool is_dirty = imbuf->userflags & IB_BITMAPDIRTY; + + ImageFormatData imageFormat; + BKE_imbuf_to_image_format(&imageFormat, imbuf); + + short image_source = image->source; + bool is_generated = image_source == IMA_SRC_GENERATED; + + char export_path[FILE_MAX]; + char source_path[FILE_MAX]; + char export_dir[FILE_MAX]; + char export_file[FILE_MAX]; + + // Destination folder for exported assets + BLI_split_dir_part(this->export_settings->filepath, export_dir, sizeof(export_dir)); + + if (is_generated || is_dirty || use_copies) { + + // make absolute destination path + + BLI_strncpy(export_file, name.c_str(), sizeof(export_file)); + BKE_add_image_extension(export_file, imageFormat.imtype); + + BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file); + + // make dest directory if it doesn't exist + BLI_make_existing_file(export_path); + } + + if (is_generated || is_dirty) { + + // This image in its current state only exists in Blender memory. + // So we have to export it. The export will keep the image state intact, + // so the exported file will not be associated with the image. + + if (BKE_imbuf_write_as(imbuf, export_path, &imageFormat, true) == 0) { + fprintf(stderr, "Collada export: Cannot export image to:\n%s\n", export_path); + } + BLI_strncpy(export_path, export_file, sizeof(export_path)); + } + else { + + // make absolute source path + BLI_strncpy(source_path, image->name, sizeof(source_path)); + BLI_path_abs(source_path, G.main->name); + BLI_cleanup_path(NULL, source_path); + + if (use_copies) { + + // This image is already located on the file system. + // But we want to create copies here. + // To avoid overwroting images with same file name but + // differenet source locations + + if (BLI_copy(source_path, export_path) != 0) { + fprintf(stderr, "Collada export: Cannot copy image:\n source:%s\ndest :%s\n", source_path, export_path); + } + + BLI_strncpy(export_path, export_file, sizeof(export_path)); + + } + else { + + // Do not make any vopies, but use the source path directly as reference + // to the original image + + BLI_strncpy(export_path, source_path, sizeof(export_path)); + } + } + + COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(export_path)), translated_name, translated_name); /* set name also to mNameNC. This helps other viewers import files exported from Blender better */ + img.add(mSW); + fprintf(stdout, "Collada export: Added image: %s\n",export_file); + mImages.push_back(translated_name); + } +} + +void ImagesExporter::export_UV_Images() +{ + std::set<Image *> uv_textures; + LinkNode *node; + bool use_copies = this->export_settings->use_texture_copies; + for (node=this->export_settings->export_set; node; node=node->next) { + Object *ob = (Object *)node->link; + if (ob->type == OB_MESH && ob->totcol) { + Mesh *me = (Mesh *) ob->data; + BKE_mesh_tessface_ensure(me); + for (int i = 0; i < me->pdata.totlayer; i++) { + if (me->pdata.layers[i].type == CD_MTEXPOLY) { + MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; + MFace *mface = me->mface; + for (int j = 0; j < me->totpoly; j++, mface++, txface++) { + + Image *ima = txface->tpage; + if (ima == NULL) + continue; + + bool not_in_list = uv_textures.find(ima)==uv_textures.end(); + if (not_in_list) { + uv_textures.insert(ima); + export_UV_Image(ima, use_copies); + } + } + } + } + } + } +} + + bool ImagesExporter::hasImages(Scene *sce) { LinkNode *node; @@ -64,60 +192,51 @@ bool ImagesExporter::hasImages(Scene *sce) } } + if (ob->type == OB_MESH) { + Mesh *me = (Mesh *) ob->data; + BKE_mesh_tessface_ensure(me); + bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE); + if (has_uvs) { + int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + for (int a = 0; a < num_layers; a++) { + MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a); + Image *img = tface->tpage; + if (img) return true; + } + } + } + } return false; } void ImagesExporter::exportImages(Scene *sce) { - if (hasImages(sce)) { - openLibrary(); - MaterialFunctor mf; + openLibrary(); + + MaterialFunctor mf; + if (this->export_settings->include_material_textures) { mf.forEachMaterialInExportSet<ImagesExporter>(sce, *this, this->export_settings->export_set); + } - closeLibrary(); + if (this->export_settings->include_uv_textures) { + export_UV_Images(); } + + closeLibrary(); } + + void ImagesExporter::operator()(Material *ma, Object *ob) { int a; + bool use_texture_copies = this->export_settings->use_texture_copies; for (a = 0; a < MAX_MTEX; a++) { MTex *mtex = ma->mtex[a]; if (mtex && mtex->tex && mtex->tex->ima) { - Image *image = mtex->tex->ima; - std::string name(id_name(image)); - name = translate_id(name); - char rel[FILE_MAX]; - char abs[FILE_MAX]; - char src[FILE_MAX]; - char dir[FILE_MAX]; - - BLI_split_dir_part(this->export_settings->filepath, dir, sizeof(dir)); - - BKE_rebase_path(abs, sizeof(abs), rel, sizeof(rel), G.main->name, image->name, dir); - - if (abs[0] != '\0') { - - // make absolute source path - BLI_strncpy(src, image->name, sizeof(src)); - BLI_path_abs(src, G.main->name); - - // make dest directory if it doesn't exist - BLI_make_existing_file(abs); - - if (BLI_copy(src, abs) != 0) { - fprintf(stderr, "Cannot copy image to file's directory.\n"); - } - } - - if (find(mImages.begin(), mImages.end(), name) == mImages.end()) { - COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(rel)), name, name); /* set name also to mNameNC. This helps other viewers import files exported from Blender better */ - img.add(mSW); - - mImages.push_back(name); - } + export_UV_Image(image, use_texture_copies); } } } diff --git a/source/blender/collada/ImageExporter.h b/source/blender/collada/ImageExporter.h index a2abc893a56..0eaebdd5cdd 100644 --- a/source/blender/collada/ImageExporter.h +++ b/source/blender/collada/ImageExporter.h @@ -35,6 +35,7 @@ #include "COLLADASWLibraryImages.h" #include "DNA_material_types.h" +#include "DNA_image_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -49,6 +50,9 @@ public: void operator()(Material *ma, Object *ob); private: std::vector<std::string> mImages; // contains list of written images, to avoid duplicates + + void export_UV_Images(); + void export_UV_Image(Image *image, bool use_texture_copies); bool hasImages(Scene *sce); const ExportSettings *export_settings; }; diff --git a/source/blender/collada/InstanceWriter.cpp b/source/blender/collada/InstanceWriter.cpp index 788bd2a98b7..5908037d782 100644 --- a/source/blender/collada/InstanceWriter.cpp +++ b/source/blender/collada/InstanceWriter.cpp @@ -41,7 +41,7 @@ #include "collada_internal.h" #include "collada_utils.h" -void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob) +void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only) { for (int a = 0; a < ob->totcol; a++) { Material *ma = give_current_material(ob, a + 1); @@ -52,16 +52,20 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_materia std::string matid(get_material_id(ma)); matid = translate_id(matid); std::ostringstream ostr; - ostr << translate_id(id_name(ma)); + ostr << matid; COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); // create <bind_vertex_input> for each uv map Mesh *me = (Mesh *)ob->data; int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + int map_index = 0; + int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) -1; for (int b = 0; b < totlayer; b++) { - char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b); - im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", b)); + if (!active_uv_only || b == active_uv_index) { + char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, map_index); + im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++)); + } } iml.push_back(im); diff --git a/source/blender/collada/InstanceWriter.h b/source/blender/collada/InstanceWriter.h index 87ddc7fb1f7..49ddf091b1c 100644 --- a/source/blender/collada/InstanceWriter.h +++ b/source/blender/collada/InstanceWriter.h @@ -35,7 +35,7 @@ class InstanceWriter { protected: - void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob); + void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only); }; #endif diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp index ef22a76d28e..5a1d8b7602a 100644 --- a/source/blender/collada/MaterialExporter.cpp +++ b/source/blender/collada/MaterialExporter.cpp @@ -31,7 +31,9 @@ #include "COLLADABUUtils.h" #include "collada_internal.h" -MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryMaterials(sw), export_settings(export_settings) { +MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryMaterials(sw), export_settings(export_settings) +{ + /* pass */ } void MaterialsExporter::exportMaterials(Scene *sce) @@ -49,7 +51,7 @@ void MaterialsExporter::exportMaterials(Scene *sce) bool MaterialsExporter::hasMaterials(Scene *sce) { LinkNode *node; - for(node=this->export_settings->export_set; node; node = node->next) { + for (node=this->export_settings->export_set; node; node = node->next) { Object *ob = (Object *)node->link; int a; for (a = 0; a < ob->totcol; a++) { diff --git a/source/blender/collada/SConscript b/source/blender/collada/SConscript index 90d0d83d793..5d921681aea 100644 --- a/source/blender/collada/SConscript +++ b/source/blender/collada/SConscript @@ -32,9 +32,9 @@ defs = [] # TODO sanitize inc path building # relative paths to include dirs, space-separated, string if env['OURPLATFORM']=='darwin': - incs = '../blenlib ../blenkernel ../windowmanager ../blenloader ../makesdna ../makesrna ../editors/include ../../../intern/guardedalloc [OPENCOLLADA]/COLLADAStreamWriter [OPENCOLLADA]/COLLADABaseUtils [OPENCOLLADA]/COLLADAFramework [OPENCOLLADA]/COLLADASaxFrameworkLoader [OPENCOLLADA]/GeneratedSaxParser '.replace('[OPENCOLLADA]', env['BF_OPENCOLLADA_INC']) + incs = '../blenlib ../blenkernel ../windowmanager ../blenloader ../makesdna ../makesrna ../editors/include ../imbuf ../../../intern/guardedalloc [OPENCOLLADA]/COLLADAStreamWriter [OPENCOLLADA]/COLLADABaseUtils [OPENCOLLADA]/COLLADAFramework [OPENCOLLADA]/COLLADASaxFrameworkLoader [OPENCOLLADA]/GeneratedSaxParser '.replace('[OPENCOLLADA]', env['BF_OPENCOLLADA_INC']) else: - incs = '../blenlib ../blenkernel ../windowmanager ../makesdna ../blenloader ../makesrna ../editors/include ../../../intern/guardedalloc [OPENCOLLADA]/COLLADAStreamWriter/include [OPENCOLLADA]/COLLADABaseUtils/include [OPENCOLLADA]/COLLADAFramework/include [OPENCOLLADA]/COLLADASaxFrameworkLoader/include [OPENCOLLADA]/GeneratedSaxParser/include '.replace('[OPENCOLLADA]', env['BF_OPENCOLLADA_INC']) + incs = '../blenlib ../blenkernel ../windowmanager ../makesdna ../blenloader ../makesrna ../editors/include ../imbuf ../../../intern/guardedalloc [OPENCOLLADA]/COLLADAStreamWriter/include [OPENCOLLADA]/COLLADABaseUtils/include [OPENCOLLADA]/COLLADAFramework/include [OPENCOLLADA]/COLLADASaxFrameworkLoader/include [OPENCOLLADA]/GeneratedSaxParser/include '.replace('[OPENCOLLADA]', env['BF_OPENCOLLADA_INC']) if env['BF_BUILDINFO']: defs.append('WITH_BUILDINFO') diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index bd746e241ca..65f552d5d0c 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -141,7 +141,7 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce) COLLADASW::InstanceGeometry instGeom(mSW); instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation))); - InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob); + InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob, this->export_settings->active_uv_only); instGeom.add(); } diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp index 0116f89361b..9b0d59d66ea 100644 --- a/source/blender/collada/SkinInfo.cpp +++ b/source/blender/collada/SkinInfo.cpp @@ -57,7 +57,9 @@ static const char *bc_get_joint_name(T *node) // This is used to store data passed in write_controller_data. // Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members // so that arrays don't get freed until we free them explicitly. -SkinInfo::SkinInfo() { +SkinInfo::SkinInfo() +{ + /* pass */ } SkinInfo::SkinInfo(const SkinInfo& skin) : weights(skin.weights), diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp index be615f83787..d10cd7378e9 100644 --- a/source/blender/collada/TransformReader.cpp +++ b/source/blender/collada/TransformReader.cpp @@ -29,7 +29,9 @@ #include "TransformReader.h" -TransformReader::TransformReader(UnitConverter *conv) : unit_converter(conv) { +TransformReader::TransformReader(UnitConverter *conv) : unit_converter(conv) +{ + /* pass */ } void TransformReader::get_node_mat(float mat[][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob) diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp index 9a4fd44b9e9..f7e0f75ec5c 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -28,9 +28,9 @@ /* COLLADABU_ASSERT, may be able to remove later */ #include "COLLADABUPlatform.h" -#include "ExportSettings.h" #include "DocumentExporter.h" #include "DocumentImporter.h" +#include "ExportSettings.h" extern "C" { @@ -40,6 +40,7 @@ extern "C" /* make dummy file */ #include "BLI_fileops.h" #include "BLI_path_util.h" +#include "BLI_linklist.h" int collada_import(bContext *C, const char *filepath) { @@ -49,18 +50,25 @@ int collada_import(bContext *C, const char *filepath) return 0; } -int collada_export( - Scene *sce, - const char *filepath, - int selected, - int apply_modifiers, +int collada_export(Scene *sce, + const char *filepath, + + int apply_modifiers, + BC_export_mesh_type export_mesh_type, - int include_armatures, - int include_children, + int selected, + int include_children, + int include_armatures, + int deform_bones_only, - int use_object_instantiation, - int sort_by_name, - int second_life) + int active_uv_only, + int include_uv_textures, + int include_material_textures, + int use_texture_copies, + + int use_object_instantiation, + int sort_by_name, + int second_life) { ExportSettings export_settings; @@ -73,15 +81,24 @@ int collada_export( } /* end! */ + export_settings.filepath = (char *)filepath; - export_settings.selected = selected != 0; export_settings.apply_modifiers = apply_modifiers != 0; + export_settings.export_mesh_type = export_mesh_type; + export_settings.selected = selected != 0; + export_settings.include_children = include_children != 0; export_settings.include_armatures = include_armatures != 0; - export_settings.include_children = include_children != 0; - export_settings.second_life = second_life != 0; + export_settings.deform_bones_only = deform_bones_only != 0; + + export_settings.active_uv_only = active_uv_only != 0; + export_settings.include_uv_textures = include_uv_textures != 0; + export_settings.include_material_textures= include_material_textures != 0; + export_settings.use_texture_copies = use_texture_copies != 0; + export_settings.use_object_instantiation = use_object_instantiation != 0; export_settings.sort_by_name = sort_by_name != 0; - export_settings.filepath = (char *)filepath; + export_settings.second_life = second_life != 0; + int includeFilter = OB_REL_NONE; if (export_settings.include_armatures) includeFilter |= OB_REL_MOD_ARMATURE; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 8daf2b65fe2..13f8151da3d 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -27,28 +27,44 @@ #ifndef __COLLADA_H__ #define __COLLADA_H__ -struct bContext; -struct Scene; - +#include <stdlib.h> #ifdef __cplusplus extern "C" { #endif - /* - * both return 1 on success, 0 on error - */ - int collada_import(bContext *C, const char *filepath); - int collada_export( - Scene *sce, - const char *filepath, - int selected, - int apply_modifiers, - - int include_armatures, - int include_children, - - int use_object_instantiation, - int sort_by_name, - int second_life); + +#include "BLI_linklist.h" +#include "RNA_types.h" + +typedef enum BC_export_mesh_type { + BC_MESH_TYPE_VIEW, + BC_MESH_TYPE_RENDER +} BC_export_mesh_type; + +struct bContext; +struct Scene; + +/* + * both return 1 on success, 0 on error + */ +int collada_import(bContext *C, const char *filepath); +int collada_export(Scene *sce, + const char *filepath, + int apply_modifiers, + BC_export_mesh_type export_mesh_type, + + int selected, + int include_children, + int include_armatures, + int deform_bones_only, + + int active_uv_only, + int include_uv_textures, + int include_material_textures, + int use_texture_copies, + + int use_object_instantiation, + int sort_by_name, + int second_life); diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index 0ee8419eda7..a4969735757 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -31,7 +31,9 @@ #include "BLI_linklist.h" -UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) { +UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) +{ + /* pass */ } void UnitConverter::read_asset(const COLLADAFW::FileInfo *asset) diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index aa6f0b3c515..cb9da9918be 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -34,11 +34,14 @@ #include "collada_utils.h" +extern "C" { + #include "DNA_modifier_types.h" #include "DNA_customdata_types.h" #include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_scene_types.h" +#include "DNA_armature_types.h" #include "BLI_math.h" @@ -49,13 +52,13 @@ #include "BKE_mesh.h" #include "BKE_scene.h" -extern "C" { #include "BKE_DerivedMesh.h" #include "BLI_linklist.h" -} + #include "WM_api.h" // XXX hrm, see if we can do without this #include "WM_types.h" +} float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index) { @@ -135,11 +138,22 @@ Object *bc_add_object(Scene *scene, int type, const char *name) return ob; } -Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob) +Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type) { Mesh *tmpmesh; CustomDataMask mask = CD_MASK_MESH; - DerivedMesh *dm = mesh_create_derived_view(scene, ob, mask); + DerivedMesh *dm; + switch (export_mesh_type) { + case BC_MESH_TYPE_VIEW: { + dm = mesh_create_derived_view(scene, ob, mask); + break; + } + case BC_MESH_TYPE_RENDER: { + dm = mesh_create_derived_render(scene, ob, mask); + break; + } + } + tmpmesh = BKE_mesh_add("ColladaMesh"); // name is not important here DM_to_mesh(dm, tmpmesh, ob); dm->release(dm); @@ -181,6 +195,7 @@ Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *o return ancestor; } + bool bc_is_base_node(LinkNode *export_set, Object *ob) { Object *root = bc_get_highest_selected_ancestor_or_self(export_set, ob); @@ -189,30 +204,19 @@ bool bc_is_base_node(LinkNode *export_set, Object *ob) bool bc_is_in_Export_set(LinkNode *export_set, Object *ob) { - LinkNode *node = export_set; - - while (node) { - Object *element = (Object *)node->link; - - if (element == ob) - return true; - - node= node->next; - } - return false; + return (BLI_linklist_index(export_set, ob) != -1); } bool bc_has_object_type(LinkNode *export_set, short obtype) { - LinkNode *node = export_set; + LinkNode *node; - while (node) { + for (node = export_set; node; node = node->next) { Object *ob = (Object *)node->link; - + /* XXX - why is this checking for ob->data? - we could be looking for empties */ if (ob->type == obtype && ob->data) { return true; } - node= node->next; } return false; } @@ -232,19 +236,16 @@ void bc_bubble_sort_by_Object_name(LinkNode *export_set) { bool sorted = false; LinkNode *node; - for(node=export_set; node->next && !sorted; node=node->next) { + for (node = export_set; node->next && !sorted; node = node->next) { sorted = true; LinkNode *current; - for (current=export_set; current->next; current = current->next) { + for (current = export_set; current->next; current = current->next) { Object *a = (Object *)current->link; Object *b = (Object *)current->next->link; - std::string str_a (a->id.name); - std::string str_b (b->id.name); - - if (str_a.compare(str_b) > 0) { + if (strcmp(a->id.name, b->id.name) > 0) { current->link = b; current->next->link = a; sorted = false; @@ -253,3 +254,30 @@ void bc_bubble_sort_by_Object_name(LinkNode *export_set) } } } + +/* Check if a bone is the top most exportable bone in the bone hierarchy. + * When deform_bones_only == false, then only bones with NO parent + * can be root bones. Otherwise the top most deform bones in the hierarchy + * are root bones. + */ +bool bc_is_root_bone(Bone *aBone, bool deform_bones_only) +{ + if (deform_bones_only) { + Bone *root = NULL; + Bone *bone = aBone; + while (bone) { + if (!(bone->flag & BONE_NO_DEFORM)) + root = bone; + bone = bone->parent; + } + return (aBone == root); + } + else + return !(aBone->parent); +} + +int bc_get_active_UVLayer(Object *ob) +{ + Mesh *me = (Mesh *)ob->data; + return CustomData_get_active_layer_index(&me->fdata, CD_MTFACE); +} diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index 139a2cb93bd..5f72581f584 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -51,13 +51,13 @@ extern "C" { #include "ExportSettings.h" -typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex*> > TexIndexTextureArrayMap; +typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex *> > TexIndexTextureArrayMap; extern float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index); extern int bc_test_parent_loop(Object *par, Object *ob); -extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space=true); +extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space = true); extern Object *bc_add_object(Scene *scene, int type, const char *name); -extern Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob); +extern Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type); extern Object *bc_get_assigned_armature(Object *ob); extern Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob); @@ -72,5 +72,7 @@ extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); extern void bc_bubble_sort_by_Object_name(LinkNode *export_set); +extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only); +extern int bc_get_active_UVLayer(Object *ob); #endif |