Blender V4.5
DocumentExporter.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdio>
10#include <cstdlib>
11
12#include "COLLADASWAsset.h"
13#include "COLLADASWCamera.h"
14#include "COLLADASWException.h"
15#include "COLLADASWScene.h"
16
17#include "DNA_object_types.h"
18#include "DNA_scene_types.h"
19
20#include "BLI_fileops.h"
21#include "BLI_path_utils.hh"
22#include "BLI_string.h"
23
24#include "BKE_animsys.h"
25#include "BKE_appdir.hh"
26#include "BKE_blender_version.h"
27#include "BKE_customdata.hh"
28#include "BKE_fcurve.hh"
29
30#include "ED_keyframing.hh"
31#ifdef WITH_BUILDINFO
32extern "C" char build_commit_date[];
33extern "C" char build_commit_time[];
34extern "C" char build_hash[];
35#endif
36
37#include "RNA_access.hh"
38
39#include "DocumentExporter.h"
40#include "collada_internal.h"
41#include "collada_utils.h"
42
43/* can probably go after refactor is complete */
44
45#include "AnimationExporter.h"
46#include "ArmatureExporter.h"
47#include "CameraExporter.h"
48#include "ControllerExporter.h"
49#include "EffectExporter.h"
50#include "GeometryExporter.h"
51#include "ImageExporter.h"
52#include "LightExporter.h"
53#include "MaterialExporter.h"
54#include "SceneExporter.h"
55
56#include <cerrno>
57
58const char *bc_CustomData_get_layer_name(const CustomData *data, const eCustomDataType type, int n)
59{
60 int layer_index = CustomData_get_layer_index(data, type);
61 if (layer_index < 0) {
62 return nullptr;
63 }
64
65 return data->layers[layer_index + n].name;
66}
67
69{
70 /* get the layer index of the active layer of type */
71 int layer_index = CustomData_get_active_layer_index(data, type);
72 if (layer_index < 0) {
73 return nullptr;
74 }
75
76 return data->layers[layer_index].name;
77}
78
80 ExportSettings *export_settings)
81 : blender_context(blender_context),
82 export_settings(BCExportSettings(export_settings, blender_context))
83{
84}
85
86static COLLADABU::NativeString make_temp_filepath(const char *name, const char *extension)
87{
88 char tempfile[FILE_MAX];
89
90 if (name == nullptr) {
91 name = "untitled";
92 }
93
94 BLI_path_join(tempfile, sizeof(tempfile), BKE_tempdir_session(), name);
95
96 if (extension) {
97 BLI_path_extension_ensure(tempfile, FILE_MAX, extension);
98 }
99
100 COLLADABU::NativeString native_filename = COLLADABU::NativeString(
101 tempfile, COLLADABU::NativeString::ENCODING_UTF8);
102 return native_filename;
103}
104
105/* TODO: it would be better to instantiate animations rather than create a new one per object
106 * COLLADA allows this through multiple <channel>s in <animation>.
107 * For this to work, we need to know objects that use a certain action. */
108
110{
111 Scene *sce = blender_context.get_scene();
112 bContext *C = blender_context.get_context();
113
114 PointerRNA unit_settings;
115 PropertyRNA *system; /* unused, *scale; */
116
118
119 COLLADABU::NativeString native_filename = make_temp_filepath(nullptr, ".dae");
120 COLLADASW::StreamWriter *writer;
121 try {
122 writer = new COLLADASW::StreamWriter(native_filename);
123 }
124 catch (COLLADASW::StreamWriterException &e) {
125 e.printMessage();
126 fprintf(stderr, "Collada: No Objects will be exported.\n");
127 return 1;
128 }
129
130 /* open <collada> */
131 writer->startDocument();
132
133 /* <asset> */
134 COLLADASW::Asset asset(writer);
135
136 PointerRNA sceneptr = RNA_id_pointer_create(&sce->id);
137 unit_settings = RNA_pointer_get(&sceneptr, "unit_settings");
138 system = RNA_struct_find_property(&unit_settings, "system");
139 // scale = RNA_struct_find_property(&unit_settings, "scale_length");
140
141 std::string unitname = "meter";
142 float linearmeasure = RNA_float_get(&unit_settings, "scale_length");
143
144 switch (RNA_property_enum_get(&unit_settings, system)) {
145 case USER_UNIT_NONE:
146 case USER_UNIT_METRIC:
147 if (linearmeasure == 0.001f) {
148 unitname = "millimeter";
149 }
150 else if (linearmeasure == 0.01f) {
151 unitname = "centimeter";
152 }
153 else if (linearmeasure == 0.1f) {
154 unitname = "decimeter";
155 }
156 else if (linearmeasure == 1.0f) {
157 unitname = "meter";
158 }
159 else if (linearmeasure == 1000.0f) {
160 unitname = "kilometer";
161 }
162 break;
164 if (linearmeasure == 0.0254f) {
165 unitname = "inch";
166 }
167 else if (linearmeasure == 0.3048f) {
168 unitname = "foot";
169 }
170 else if (linearmeasure == 0.9144f) {
171 unitname = "yard";
172 }
173 break;
174 default:
175 break;
176 }
177
178 asset.setUnit(unitname, linearmeasure);
179 asset.setUpAxisType(COLLADASW::Asset::Z_UP);
180 asset.getContributor().mAuthor = "Blender User";
181 char version_buf[128];
182#ifdef WITH_BUILDINFO
183 SNPRINTF(version_buf,
184 "Blender %s commit date:%s, commit time:%s, hash:%s",
188 build_hash);
189#else
190 SNPRINTF(version_buf, "Blender %s", BKE_blender_version_string());
191#endif
192 asset.getContributor().mAuthoringTool = version_buf;
193 asset.add();
194
195 LinkNode *export_set = this->export_settings.get_export_set();
196 /* <library_cameras> */
197 if (bc_has_object_type(export_set, OB_CAMERA)) {
198 CamerasExporter ce(writer, this->export_settings);
199 ce.exportCameras(sce);
200 }
201
202 /* <library_lights> */
203 if (bc_has_object_type(export_set, OB_LAMP)) {
204 LightsExporter le(writer, this->export_settings);
205 le.exportLights(sce);
206 }
207
208 /* <library_effects> */
209 EffectsExporter ee(writer, this->export_settings, key_image_map);
210 ee.exportEffects(C, sce);
211
212 /* <library_images> */
213 ImagesExporter ie(writer, this->export_settings, key_image_map);
214 ie.exportImages(sce);
215
216 /* <library_materials> */
217 MaterialsExporter me(writer, this->export_settings);
218 me.exportMaterials(sce);
219
220 /* <library_geometries> */
221 if (bc_has_object_type(export_set, OB_MESH)) {
222 GeometryExporter ge(blender_context, writer, this->export_settings);
223 ge.exportGeom();
224 }
225
226 /* <library_controllers> */
227 ArmatureExporter arm_exporter(blender_context, writer, this->export_settings);
228 ControllerExporter controller_exporter(blender_context, writer, this->export_settings);
229 if (bc_has_object_type(export_set, OB_ARMATURE) || this->export_settings.get_include_shapekeys())
230 {
231 controller_exporter.export_controllers();
232 }
233
234 /* <library_visual_scenes> */
235
236 SceneExporter se(blender_context, writer, &arm_exporter, this->export_settings);
237
238 if (this->export_settings.get_include_animations()) {
239 /* <library_animations> */
240 AnimationExporter ae(writer, this->export_settings);
241 ae.exportAnimations();
242 }
243
244 se.exportScene();
245
246 /* <scene> */
247 std::string scene_name(translate_id(id_name(sce)));
248 COLLADASW::Scene scene(writer, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, scene_name));
249 scene.add();
250
251 /* close <Collada> */
252 writer->endDocument();
253 delete writer;
254
255 /* Finally move the created document into place */
256 fprintf(stdout, "Collada export to: %s\n", this->export_settings.get_filepath());
257 int status = BLI_rename_overwrite(native_filename.c_str(), this->export_settings.get_filepath());
258 if (status != 0) {
259 status = BLI_copy(native_filename.c_str(), this->export_settings.get_filepath());
260 BLI_delete(native_filename.c_str(), false, false);
261 }
262 return status;
263}
264
265/*
266 * NOTES:
267 *
268 * AnimationExporter::sample_animation enables all curves on armature, this is undesirable for a
269 * user
270 */
const char * BKE_blender_version_string(void)
Definition blender.cc:143
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type)
int CustomData_get_active_layer_index(const CustomData *data, eCustomDataType type)
File and directory operations.
int BLI_copy(const char *path_src, const char *path_dst) ATTR_NONNULL()
int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL()
int BLI_rename_overwrite(const char *from, const char *to) ATTR_NONNULL()
Definition fileops_c.cc:505
#define FILE_MAX
#define BLI_path_join(...)
bool BLI_path_extension_ensure(char *path, size_t path_maxncpy, const char *ext) ATTR_NONNULL(1
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
Object is a sort of wrapper for general info.
@ OB_CAMERA
@ OB_ARMATURE
@ OB_LAMP
@ OB_MESH
@ USER_UNIT_IMPERIAL
@ USER_UNIT_METRIC
@ USER_UNIT_NONE
static COLLADABU::NativeString make_temp_filepath(const char *name, const char *extension)
const char * bc_CustomData_get_layer_name(const CustomData *data, const eCustomDataType type, int n)
const char * bc_CustomData_get_active_layer_name(const CustomData *data, const eCustomDataType type)
#define C
Definition RandGen.cpp:29
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
char build_hash[]
Definition bpy_app.cc:67
char build_commit_date[]
Definition bpy_app.cc:65
char build_commit_time[]
Definition bpy_app.cc:66
void exportCameras(Scene *sce)
DocumentExporter(BlenderContext &blender_context, ExportSettings *export_settings)
void exportEffects(bContext *C, Scene *sce)
void exportImages(Scene *sce)
void exportLights(Scene *sce)
void exportMaterials(Scene *sce)
std::string translate_id(const char *idString)
void clear_global_id_map()
std::string id_name(void *id)
bool bc_has_object_type(LinkNode *export_set, short obtype)
#define this
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
float RNA_float_get(PointerRNA *ptr, const char *name)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
PointerRNA RNA_id_pointer_create(ID *id)
void * BKE_tempdir_session
Definition stubs.c:38