353 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			353 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 * ***** 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 <stdlib.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <math.h>
 | 
						|
#include <vector>
 | 
						|
#include <algorithm> // 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 <errno.h>
 | 
						|
 | 
						|
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 <channel>s in <animation>.
 | 
						|
// 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 <collada>
 | 
						|
	writer->startDocument();
 | 
						|
 | 
						|
	// <asset>
 | 
						|
	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;
 | 
						|
	// <library_cameras>
 | 
						|
	if (bc_has_object_type(export_set, OB_CAMERA)) {
 | 
						|
		CamerasExporter ce(writer, this->export_settings);
 | 
						|
		ce.exportCameras(sce);
 | 
						|
	}
 | 
						|
	
 | 
						|
	// <library_lights>
 | 
						|
	if (bc_has_object_type(export_set, OB_LAMP)) {
 | 
						|
		LightsExporter le(writer, this->export_settings);
 | 
						|
		le.exportLights(sce);
 | 
						|
	}
 | 
						|
 | 
						|
	// <library_images>
 | 
						|
	ImagesExporter ie(writer, this->export_settings);
 | 
						|
	ie.exportImages(sce);
 | 
						|
	
 | 
						|
	// <library_effects>
 | 
						|
	EffectsExporter ee(writer, this->export_settings);
 | 
						|
	ee.exportEffects(sce);
 | 
						|
	
 | 
						|
	// <library_materials>
 | 
						|
	MaterialsExporter me(writer, this->export_settings);
 | 
						|
	me.exportMaterials(sce);
 | 
						|
 | 
						|
	// <library_geometries>
 | 
						|
	if (bc_has_object_type(export_set, OB_MESH)) {
 | 
						|
		GeometryExporter ge(writer, this->export_settings);
 | 
						|
		ge.exportGeom(sce);
 | 
						|
	}
 | 
						|
 | 
						|
	// <library_animations>
 | 
						|
	AnimationExporter ae(writer, this->export_settings);
 | 
						|
	bool has_animations = ae.exportAnimations(sce);
 | 
						|
 | 
						|
	// <library_controllers>
 | 
						|
	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);
 | 
						|
	}
 | 
						|
 | 
						|
	// <library_visual_scenes>
 | 
						|
 | 
						|
	SceneExporter se(writer, &arm_exporter, this->export_settings);
 | 
						|
 | 
						|
	if (has_animations && this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX) {
 | 
						|
		// channels adressing <matrix> objects is not (yet) supported
 | 
						|
		// So we force usage of <location>, <translation> and <scale>
 | 
						|
		fprintf(stdout, 
 | 
						|
			"For animated Ojects we must use decomposed <matrix> 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);
 | 
						|
	
 | 
						|
	// <scene>
 | 
						|
	std::string scene_name(translate_id(id_name(sce)));
 | 
						|
	COLLADASW::Scene scene(writer, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING,
 | 
						|
	                                           scene_name));
 | 
						|
	scene.add();
 | 
						|
	
 | 
						|
	// close <Collada>
 | 
						|
	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
 | 
						|
 *
 | 
						|
 */
 |