diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp index 9ac943f369c..c5feb62fd80 100644 --- a/source/blender/collada/ArmatureExporter.cpp +++ b/source/blender/collada/ArmatureExporter.cpp @@ -111,7 +111,7 @@ bool ArmatureExporter::add_instance_controller(Object *ob) 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; 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/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp index 3ed689628f7..aee4f00b31c 100644 --- a/source/blender/collada/EffectExporter.cpp +++ b/source/blender/collada/EffectExporter.cpp @@ -27,6 +27,7 @@ #include +#include #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,6 +121,54 @@ 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 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 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 @@ -256,6 +307,52 @@ void EffectsExporter::operator()(Material *ma, Object *ob) } } + + std::set uv_textures; + 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++) { + + 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 / pair for each unique image + if (im_samp_map.find(key) == im_samp_map.end()) { + // + 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 +362,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; - - // 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 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 tag, is most likely the best understood, - // most widespread de-facto standard. - texture.setProfileName("FCOLLADA"); - texture.setChildElementName("bump"); - ep.addExtraTechniqueColorOrTexture(COLLADASW::ColorOrTexture(texture)); - } + COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i][0]; + writeTextures(ep, key, sampler, t, ima, uvname); } + + std::set::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..e20d6b7cd4b 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 EffectsExporter::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 1b2dfde641b..73f78ebd040 100644 --- a/source/blender/collada/ExportSettings.h +++ b/source/blender/collada/ExportSettings.h @@ -33,13 +33,20 @@ 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 use_texture_copies; + bool use_object_instantiation; bool sort_by_name; bool second_life; + char *filepath; LinkNode *export_set; }; diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index baa20ab07b7..c3d1106b288 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -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 for each layer // each 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..d7bcfa8eed1 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 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,49 @@ 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; - mf.forEachMaterialInExportSet(sce, *this, this->export_settings->export_set); + openLibrary(); - closeLibrary(); + MaterialFunctor mf; + mf.forEachMaterialInExportSet(sce, *this, this->export_settings->export_set); + + 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..c617676cf20 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 mImages; // contains list of written images, to avoid duplicates + + void ImagesExporter::export_UV_Images(); + void ImagesExporter::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 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/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/collada.cpp b/source/blender/collada/collada.cpp index da1ca6c30c8..17be0c46cd3 100644 --- a/source/blender/collada/collada.cpp +++ b/source/blender/collada/collada.cpp @@ -61,6 +61,10 @@ int collada_export(Scene *sce, int include_armatures, int deform_bones_only, + int active_uv_only, + int include_uv_textures, + int use_texture_copies, + int use_object_instantiation, int sort_by_name, int second_life) @@ -79,12 +83,16 @@ int collada_export(Scene *sce, export_settings.filepath = (char *)filepath; export_settings.apply_modifiers = apply_modifiers != 0; - export_settings.export_mesh_type = export_mesh_type; + 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.deform_bones_only = deform_bones_only != 0; + export_settings.active_uv_only = active_uv_only != 0; + export_settings.include_uv_textures = include_uv_textures; + export_settings.use_texture_copies = use_texture_copies; + export_settings.use_object_instantiation = use_object_instantiation != 0; export_settings.sort_by_name = sort_by_name != 0; export_settings.second_life = second_life != 0; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 63f791ba80e..d136914e484 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -57,6 +57,10 @@ int collada_export(Scene *sce, int include_armatures, int deform_bones_only, + int active_uv, + int include_textures, + int use_texture_copies, + int use_object_instantiation, int sort_by_name, int second_life); diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 62ae5d38727..cb9da9918be 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -275,3 +275,9 @@ bool bc_is_root_bone(Bone *aBone, bool deform_bones_only) 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 ab0b7421aa1..5f72581f584 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -73,5 +73,6 @@ extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int typ 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 diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index cf649207ff3..0ceffe19ad8 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -83,6 +83,11 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) int include_children; int include_armatures; int deform_bones_only; + + int include_uv_textures; + int use_texture_copies; + int active_uv_only; + int use_object_instantiation; int sort_by_name; int second_life; @@ -97,11 +102,16 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) /* Options panel */ apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers"); - export_mesh_type = RNA_enum_get(op->ptr, "export_mesh_type_selection"); + export_mesh_type = RNA_enum_get(op->ptr, "export_mesh_type_selection"); selected = RNA_boolean_get(op->ptr, "selected"); include_children = RNA_boolean_get(op->ptr, "include_children"); include_armatures = RNA_boolean_get(op->ptr, "include_armatures"); deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only"); + + include_uv_textures = RNA_boolean_get(op->ptr, "include_uv_textures"); + use_texture_copies = RNA_boolean_get(op->ptr, "use_texture_copies"); + active_uv_only = RNA_boolean_get(op->ptr, "active_uv_only"); + use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation"); sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name"); second_life = RNA_boolean_get(op->ptr, "second_life"); @@ -118,6 +128,11 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) include_children, include_armatures, deform_bones_only, + + include_uv_textures, + active_uv_only, + use_texture_copies, + use_object_instantiation, sort_by_name, second_life)) { @@ -130,7 +145,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr) { - uiLayout *box, *row, *col, *sub, *split; + uiLayout *box, *row, *col, *split; /* Export Options: */ box = uiLayoutBox(layout); @@ -138,30 +153,38 @@ void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr) uiItemL(row, IFACE_("Export Data Options:"), ICON_MESH_DATA); row = uiLayoutRow(box, 0); - col = uiLayoutColumn(row, 0); - split = uiLayoutSplit(col, 0.5f, 0); - uiItemR(split, imfptr, "apply_modifiers", 0, NULL, ICON_NONE); - sub = uiLayoutRow(split, 0); - uiItemR(sub, imfptr, "export_mesh_type_selection", UI_ITEM_R_EXPAND, IFACE_("Color"), ICON_NONE); - uiLayoutSetEnabled(sub, RNA_boolean_get(imfptr, "apply_modifiers")); + split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT); + col = uiLayoutColumn(split,0); + uiItemR(col, imfptr, "apply_modifiers", 0, NULL, ICON_NONE); + col = uiLayoutColumn(split,0); + uiItemR(col, imfptr, "export_mesh_type_selection", 0, "", ICON_NONE); + uiLayoutSetEnabled(col, RNA_boolean_get(imfptr, "apply_modifiers")); row = uiLayoutRow(box, 0); uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE); row = uiLayoutRow(box, 0); - col = uiLayoutColumn(row, 0); - split = uiLayoutSplit(col, 0.1f, 0); - sub = uiLayoutRow(split, 0); - uiItemR(split, imfptr, "include_children", 0, NULL, ICON_NONE); + uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE); uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected")); row = uiLayoutRow(box, 0); - col = uiLayoutColumn(row, 0); - split = uiLayoutSplit(col, 0.1f, 0); - sub = uiLayoutRow(split, 0); - uiItemR(split, imfptr, "include_armatures", 0, NULL, ICON_NONE); + uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE); uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected")); + // Texture options + box = uiLayoutBox(layout); + row = uiLayoutRow(box, 0); + uiItemL(row, IFACE_("Texture Options:"), ICON_TEXTURE_DATA); + + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE); + + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "include_uv_textures", 0, NULL, ICON_NONE); + + row = uiLayoutRow(box, 0); + uiItemR(row, imfptr, "use_texture_copies", 1, NULL, ICON_NONE); + // Armature options box = uiLayoutBox(layout); @@ -215,8 +238,9 @@ void WM_OT_collada_export(wmOperatorType *ot) WM_operator_properties_filesel(ot, FOLDERFILE | COLLADAFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY); - RNA_def_boolean(ot->srna, "apply_modifiers", 0, "Apply Modifiers", - "Apply modifiers"); + RNA_def_boolean(ot->srna, + "apply_modifiers", 0, "Apply Modifiers", + "Apply modifiers to exported mesh (non destructive))"); RNA_def_int(ot->srna, "export_mesh_type", 0, INT_MIN, INT_MAX, "Resolution", "Modifier resolution for export", INT_MIN, INT_MAX); @@ -237,6 +261,16 @@ void WM_OT_collada_export(wmOperatorType *ot) "Only export deforming bones with armatures"); + RNA_def_boolean(ot->srna, "active_uv_only", 0, "Only Active UV layer", + "Export textures assigned to the object UV maps"); + + RNA_def_boolean(ot->srna, "include_uv_textures", 0, "Include UV Textures", + "Export textures assigned to the object UV maps"); + + RNA_def_boolean(ot->srna, "use_texture_copies", 1, "copy", + "Copy textures to same folder where the .dae file is exported"); + + RNA_def_boolean(ot->srna, "use_object_instantiation", 1, "Use Object Instances", "Instantiate multiple Objects from same Data"); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index d4611f4a268..7fec46b4837 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -91,16 +91,23 @@ static void rna_Scene_collada_export( const char *filepath, int apply_modifiers, int export_mesh_type, - int selected, + + int selected, int include_children, int include_armatures, int deform_bones_only, + + int active_uv_only, + int include_textures, + int use_texture_copies, + int use_object_instantiation, int sort_by_name, int second_life) { collada_export(scene, filepath, apply_modifiers, export_mesh_type, selected, - include_children, include_armatures, deform_bones_only, + include_children, include_armatures, deform_bones_only, + active_uv_only, include_textures, use_texture_copies, use_object_instantiation, sort_by_name, second_life); } @@ -136,6 +143,11 @@ void RNA_api_scene(StructRNA *srna) parm = RNA_def_boolean(func, "include_children", 0, "Include Children", "Export all children of selected objects (even if not selected)"); parm = RNA_def_boolean(func, "include_armatures", 0, "Include Armatures", "Export related armatures (even if not selected)"); parm = RNA_def_boolean(func, "deform_bones_only", 0, "Deform Bones only", "Only export deforming bones with armatures"); + + parm = RNA_def_boolean(func, "active_uv_only", 0, "Active UV Layer only", "Export only the active UV Layer"); + parm = RNA_def_boolean(func, "include_textures", 0, "Include Textures", "Export related textures"); + parm = RNA_def_boolean(func, "use_texture_copies", 0, "copy", "Copy textures to same folder where the .dae file is exported"); + parm = RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instances", "Instantiate multiple Objects from same Data"); parm = RNA_def_boolean(func, "sort_by_name", 0, "Sort by Object name", "Sort exported data by Object name"); parm = RNA_def_boolean(func, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life");