/* * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed. * * ***** END GPL LICENSE BLOCK ***** */ /** \file blender/collada/DocumentExporter.cpp * \ingroup collada */ #include #include #include #include #include // std::find #include "COLLADASWCamera.h" #include "COLLADASWAsset.h" #include "COLLADASWLibraryVisualScenes.h" #include "COLLADASWNode.h" #include "COLLADASWSource.h" #include "COLLADASWInstanceGeometry.h" #include "COLLADASWInputList.h" #include "COLLADASWPrimitves.h" #include "COLLADASWVertices.h" #include "COLLADASWLibraryAnimations.h" #include "COLLADASWLibraryImages.h" #include "COLLADASWLibraryEffects.h" #include "COLLADASWImage.h" #include "COLLADASWEffectProfile.h" #include "COLLADASWColorOrTexture.h" #include "COLLADASWParamTemplate.h" #include "COLLADASWParamBase.h" #include "COLLADASWSurfaceInitOption.h" #include "COLLADASWSampler.h" #include "COLLADASWScene.h" #include "COLLADASWTechnique.h" #include "COLLADASWTexture.h" #include "COLLADASWLibraryMaterials.h" #include "COLLADASWBindMaterial.h" #include "COLLADASWInstanceCamera.h" #include "COLLADASWInstanceLight.h" #include "COLLADASWConstants.h" #include "COLLADASWLibraryControllers.h" #include "COLLADASWInstanceController.h" #include "COLLADASWInstanceNode.h" #include "COLLADASWBaseInputElement.h" extern "C" { #include "DNA_scene_types.h" #include "DNA_object_types.h" #include "DNA_group_types.h" #include "DNA_meshdata_types.h" #include "DNA_mesh_types.h" #include "DNA_image_types.h" #include "DNA_material_types.h" #include "DNA_texture_types.h" #include "DNA_anim_types.h" #include "DNA_action_types.h" #include "DNA_curve_types.h" #include "DNA_armature_types.h" #include "DNA_modifier_types.h" #include "DNA_userdef_types.h" #include "BLI_path_util.h" #include "BLI_fileops.h" #include "BLI_math.h" #include "BLI_string.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" #include "BKE_DerivedMesh.h" #include "BKE_action.h" // pose functions #include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_blender_version.h" #include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_object.h" #include "BKE_scene.h" #include "BKE_appdir.h" #include "ED_keyframing.h" #ifdef WITH_BUILDINFO extern char build_commit_date[]; extern char build_commit_time[]; extern char build_hash[]; #endif #include "MEM_guardedalloc.h" #include "RNA_access.h" } #include "collada_internal.h" #include "collada_utils.h" #include "DocumentExporter.h" extern bool bc_has_object_type(LinkNode *export_set, short obtype); // can probably go after refactor is complete #include "InstanceWriter.h" #include "TransformWriter.h" #include "SceneExporter.h" #include "ArmatureExporter.h" #include "AnimationExporter.h" #include "CameraExporter.h" #include "ControllerExporter.h" #include "EffectExporter.h" #include "GeometryExporter.h" #include "ImageExporter.h" #include "LightExporter.h" #include "MaterialExporter.h" #include char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n) { int layer_index = CustomData_get_layer_index(data, type); if (layer_index < 0) return NULL; return data->layers[layer_index + n].name; } char *bc_CustomData_get_active_layer_name(const CustomData *data, int type) { /* get the layer index of the active layer of type */ int layer_index = CustomData_get_active_layer_index(data, type); if (layer_index < 1) return NULL; return bc_CustomData_get_layer_name(data, type, layer_index-1); } DocumentExporter::DocumentExporter(const ExportSettings *export_settings) : export_settings(export_settings) { } static COLLADABU::NativeString make_temp_filepath(const char *name, const char *extension) { char tempfile[FILE_MAX]; const char *tempdir = BKE_tempdir_session(); if (name == NULL) { name = "untitled"; } BLI_make_file_string(NULL, tempfile, tempdir, name); if (extension) { BLI_ensure_extension(tempfile, FILE_MAX, extension); } COLLADABU::NativeString native_filename = COLLADABU::NativeString(tempfile, COLLADABU::NativeString::ENCODING_UTF8); return native_filename; } // TODO: it would be better to instantiate animations rather than create a new one per object // COLLADA allows this through multiple s in . // For this to work, we need to know objects that use a certain action. int DocumentExporter::exportCurrentScene(Scene *sce) { PointerRNA sceneptr, unit_settings; PropertyRNA *system; /* unused , *scale; */ clear_global_id_map(); COLLADABU::NativeString native_filename = make_temp_filepath(NULL, ".dae"); COLLADASW::StreamWriter *writer = new COLLADASW::StreamWriter(native_filename); // open writer->startDocument(); // COLLADASW::Asset asset(writer); RNA_id_pointer_create(&(sce->id), &sceneptr); unit_settings = RNA_pointer_get(&sceneptr, "unit_settings"); system = RNA_struct_find_property(&unit_settings, "system"); //scale = RNA_struct_find_property(&unit_settings, "scale_length"); std::string unitname = "meter"; float linearmeasure = RNA_float_get(&unit_settings, "scale_length"); switch (RNA_property_enum_get(&unit_settings, system)) { case USER_UNIT_NONE: case USER_UNIT_METRIC: if (linearmeasure == 0.001f) { unitname = "millimeter"; } else if (linearmeasure == 0.01f) { unitname = "centimeter"; } else if (linearmeasure == 0.1f) { unitname = "decimeter"; } else if (linearmeasure == 1.0f) { unitname = "meter"; } else if (linearmeasure == 1000.0f) { unitname = "kilometer"; } break; case USER_UNIT_IMPERIAL: if (linearmeasure == 0.0254f) { unitname = "inch"; } else if (linearmeasure == 0.3048f) { unitname = "foot"; } else if (linearmeasure == 0.9144f) { unitname = "yard"; } break; default: break; } asset.setUnit(unitname, linearmeasure); asset.setUpAxisType(COLLADASW::Asset::Z_UP); if (U.author[0] != '\0') { asset.getContributor().mAuthor = U.author; } else { asset.getContributor().mAuthor = "Blender User"; } char version_buf[128]; #ifdef WITH_BUILDINFO BLI_snprintf(version_buf, sizeof(version_buf), "Blender %d.%02d.%d commit date:%s, commit time:%s, hash:%s", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION, build_commit_date, build_commit_time, build_hash); #else BLI_snprintf(version_buf, sizeof(version_buf), "Blender %d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION); #endif asset.getContributor().mAuthoringTool = version_buf; asset.add(); LinkNode *export_set = this->export_settings->export_set; // if (bc_has_object_type(export_set, OB_CAMERA)) { CamerasExporter ce(writer, this->export_settings); ce.exportCameras(sce); } // if (bc_has_object_type(export_set, OB_LAMP)) { LightsExporter le(writer, this->export_settings); le.exportLights(sce); } // ImagesExporter ie(writer, this->export_settings); ie.exportImages(sce); // EffectsExporter ee(writer, this->export_settings); ee.exportEffects(sce); // MaterialsExporter me(writer, this->export_settings); me.exportMaterials(sce); // if (bc_has_object_type(export_set, OB_MESH)) { GeometryExporter ge(writer, this->export_settings); ge.exportGeom(sce); } // AnimationExporter ae(writer, this->export_settings); bool has_animations = ae.exportAnimations(sce); // ArmatureExporter arm_exporter(writer, this->export_settings); ControllerExporter controller_exporter(writer, this->export_settings); if (bc_has_object_type(export_set, OB_ARMATURE) || this->export_settings->include_shapekeys) { controller_exporter.export_controllers(sce); } // SceneExporter se(writer, &arm_exporter, this->export_settings); if (has_animations && this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX) { // channels adressing objects is not (yet) supported // So we force usage of , and fprintf(stdout, "For animated Ojects we must use decomposed elements,\n" \ "Forcing usage of TransLocRot transformation type."); se.setExportTransformationType(BC_TRANSFORMATION_TYPE_TRANSROTLOC); } else { se.setExportTransformationType(this->export_settings->export_transformation_type); } se.exportScene(sce); // std::string scene_name(translate_id(id_name(sce))); COLLADASW::Scene scene(writer, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, scene_name)); scene.add(); // close writer->endDocument(); delete writer; // Finally move the created document into place fprintf(stdout, "Collada export to: %s\n", this->export_settings->filepath); int status = BLI_rename(native_filename.c_str(), this->export_settings->filepath); if (status != 0) { status = BLI_copy(native_filename.c_str(), this->export_settings->filepath); BLI_delete(native_filename.c_str(), false, false); } return status; } void DocumentExporter::exportScenes(const char *filename) { } /* * NOTES: * * AnimationExporter::sample_animation enables all curves on armature, this is undesirable for a user * */