merge from master
[blender.git] / source / blender / editors / io / io_collada.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/io/io_collada.c
28  *  \ingroup collada
29  */
30 #ifdef WITH_COLLADA
31 #include "DNA_space_types.h"
32
33 #include "BLT_translation.h"
34
35 #include "BLI_blenlib.h"
36 #include "BLI_utildefines.h"
37
38 #include "BKE_context.h"
39 #include "BKE_global.h"
40 #include "BKE_main.h"
41 #include "BKE_report.h"
42
43 #include "DEG_depsgraph.h"
44
45 #include "ED_screen.h"
46 #include "ED_object.h"
47
48 #include "RNA_access.h"
49 #include "RNA_define.h"
50
51 #include "UI_interface.h"
52 #include "UI_resources.h"
53
54 #include "WM_api.h"
55 #include "WM_types.h"
56
57 #include "../../collada/collada.h"
58
59 #include "io_collada.h"
60
61 #include "DEG_depsgraph.h"
62
63 static int wm_collada_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
64 {       
65         if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
66                 char filepath[FILE_MAX];
67
68                 if (G.main->name[0] == 0)
69                         BLI_strncpy(filepath, "untitled", sizeof(filepath));
70                 else
71                         BLI_strncpy(filepath, G.main->name, sizeof(filepath));
72
73                 BLI_replace_extension(filepath, sizeof(filepath), ".dae");
74                 RNA_string_set(op->ptr, "filepath", filepath);
75         }
76
77         WM_event_add_fileselect(C, op);
78
79         return OPERATOR_RUNNING_MODAL;
80 }
81
82 /* function used for WM_OT_save_mainfile too */
83 static int wm_collada_export_exec(bContext *C, wmOperator *op)
84 {
85         EvaluationContext eval_ctx;
86         char filepath[FILE_MAX];
87         int apply_modifiers;
88         int export_mesh_type;
89         int selected;
90         int include_children;
91         int include_armatures;
92         int include_shapekeys;
93         int deform_bones_only;
94
95         int include_animations;
96         int sample_animations;
97         int sampling_rate;
98
99         int include_material_textures;
100         int use_texture_copies;
101         int active_uv_only;
102
103         int triangulate;
104         int use_object_instantiation;
105         int use_blender_profile;
106         int sort_by_name;
107         int export_transformation_type;
108
109         int open_sim;
110         int limit_precision;
111         int keep_bind_info;
112
113         int export_count;
114
115         CTX_data_eval_ctx(C, &eval_ctx);
116
117         if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
118                 BKE_report(op->reports, RPT_ERROR, "No filename given");
119                 return OPERATOR_CANCELLED;
120         }
121
122         RNA_string_get(op->ptr, "filepath", filepath);
123         BLI_ensure_extension(filepath, sizeof(filepath), ".dae");
124
125
126         /* Avoid File write exceptions in Collada */
127         if (!BLI_exists(filepath)) {
128                 BLI_make_existing_file(filepath);
129                 if (!BLI_file_touch(filepath)) {
130                         BKE_report(op->reports, RPT_ERROR, "Can't create export file");
131                         fprintf(stdout, "Collada export: Can not create: %s\n", filepath);
132                         return OPERATOR_CANCELLED;
133                 }
134         }
135         else if (!BLI_file_is_writable(filepath)) {
136                 BKE_report(op->reports, RPT_ERROR, "Can't overwrite export file");
137                 fprintf(stdout, "Collada export: Can not modify: %s\n", filepath);
138                 return OPERATOR_CANCELLED;
139         }
140
141         /* Now the exporter can create and write the export file */
142
143         /* Options panel */
144         apply_modifiers          = RNA_boolean_get(op->ptr, "apply_modifiers");
145         export_mesh_type         = RNA_enum_get(op->ptr,    "export_mesh_type_selection");
146         selected                 = RNA_boolean_get(op->ptr, "selected");
147         include_children         = RNA_boolean_get(op->ptr, "include_children");
148         include_armatures        = RNA_boolean_get(op->ptr, "include_armatures");
149         include_shapekeys        = RNA_boolean_get(op->ptr, "include_shapekeys");
150
151         include_animations       = RNA_boolean_get(op->ptr, "include_animations");
152         sample_animations        = RNA_boolean_get(op->ptr, "sample_animations");
153         sampling_rate            = (sample_animations)? RNA_int_get(op->ptr, "sampling_rate") : 0;
154
155         deform_bones_only        = RNA_boolean_get(op->ptr, "deform_bones_only");
156
157         include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures");
158         use_texture_copies       = RNA_boolean_get(op->ptr, "use_texture_copies");
159         active_uv_only           = RNA_boolean_get(op->ptr, "active_uv_only");
160
161         triangulate                = RNA_boolean_get(op->ptr, "triangulate");
162         use_object_instantiation   = RNA_boolean_get(op->ptr, "use_object_instantiation");
163         use_blender_profile        = RNA_boolean_get(op->ptr, "use_blender_profile");
164         sort_by_name               = RNA_boolean_get(op->ptr, "sort_by_name");
165         export_transformation_type = RNA_enum_get(op->ptr,    "export_transformation_type_selection");
166         open_sim                   = RNA_boolean_get(op->ptr, "open_sim");
167
168         limit_precision = RNA_boolean_get(op->ptr, "limit_precision");
169         keep_bind_info = RNA_boolean_get(op->ptr, "keep_bind_info");
170
171         /* get editmode results */
172         ED_object_editmode_load(CTX_data_edit_object(C));
173
174         Scene *scene = CTX_data_scene(C);
175         CTX_data_eval_ctx(C, &eval_ctx);
176
177         export_count = collada_export(&eval_ctx,
178                 scene,
179                 filepath,
180                 apply_modifiers,
181                 export_mesh_type,
182                 selected,
183                 include_children,
184                 include_armatures,
185                 include_shapekeys,
186                 deform_bones_only,
187                 include_animations,
188                 sampling_rate,
189
190                 active_uv_only,
191                 include_material_textures,
192                 use_texture_copies,
193
194                 triangulate,
195                 use_object_instantiation,
196                 use_blender_profile,
197                 sort_by_name,
198                 export_transformation_type,
199
200                 open_sim,
201                 limit_precision,
202                 keep_bind_info
203         );
204
205         if (export_count == 0) {
206                 BKE_report(op->reports, RPT_WARNING, "No objects selected -- Created empty export file");
207                 return OPERATOR_CANCELLED;
208         }
209         else if (export_count < 0) {
210                 BKE_report(op->reports, RPT_WARNING, "Error during export (see Console)");
211                 return OPERATOR_CANCELLED;
212         }
213         else {
214                 char buff[100];
215                 sprintf(buff, "Exported %d Objects", export_count);
216                 BKE_report(op->reports, RPT_INFO, buff);
217                 return OPERATOR_FINISHED;
218         }
219 }
220
221 static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
222 {
223         uiLayout *box, *row, *col, *split;
224         bool include_animations = RNA_boolean_get(imfptr, "include_animations");
225
226         /* Export Options: */
227         box = uiLayoutBox(layout);
228         row = uiLayoutRow(box, false);
229         uiItemL(row, IFACE_("Export Data Options:"), ICON_MESH_DATA);
230
231         row = uiLayoutRow(box, false);
232         split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
233         col   = uiLayoutColumn(split, false);
234         uiItemR(col, imfptr, "apply_modifiers", 0, NULL, ICON_NONE);
235         col   = uiLayoutColumn(split, false);
236         uiItemR(col, imfptr, "export_mesh_type_selection", 0, "", ICON_NONE);
237         uiLayoutSetEnabled(col, RNA_boolean_get(imfptr, "apply_modifiers"));
238
239         row = uiLayoutRow(box, false);
240         uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE);
241
242         row = uiLayoutRow(box, false);
243         uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE);
244         uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
245
246         row = uiLayoutRow(box, false);
247         uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE);
248         uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
249
250         row = uiLayoutRow(box, false);
251         uiItemR(row, imfptr, "include_shapekeys", 0, NULL, ICON_NONE);
252         uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
253
254         row = uiLayoutRow(box, false);
255         uiItemR(row, imfptr, "include_animations", 0, NULL, ICON_NONE);
256         row = uiLayoutRow(box, false);
257         if (include_animations) {
258                 uiItemR(row, imfptr, "sample_animations", 0, NULL, ICON_NONE);
259                 row = uiLayoutColumn(box, false);
260                 uiItemR(row, imfptr, "sampling_rate", 0, NULL, ICON_NONE);
261                 uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "sample_animations"));
262         }
263
264         /* Texture options */
265         box = uiLayoutBox(layout);
266         row = uiLayoutRow(box, false);
267         uiItemL(row, IFACE_("Texture Options:"), ICON_TEXTURE_DATA);
268
269         row = uiLayoutRow(box, false);
270         uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE);
271
272         row = uiLayoutRow(box, false);
273         uiItemR(row, imfptr, "include_material_textures", 0, NULL, ICON_NONE);
274
275         row = uiLayoutRow(box, false);
276         uiItemR(row, imfptr, "use_texture_copies", 1, NULL, ICON_NONE);
277
278
279         /* Armature options */
280         box = uiLayoutBox(layout);
281         row = uiLayoutRow(box, false);
282         uiItemL(row, IFACE_("Armature Options:"), ICON_ARMATURE_DATA);
283
284         row = uiLayoutRow(box, false);
285         uiItemR(row, imfptr, "deform_bones_only", 0, NULL, ICON_NONE);
286
287         row = uiLayoutRow(box, false);
288         uiItemR(row, imfptr, "open_sim", 0, NULL, ICON_NONE);
289
290         /* Collada options: */
291         box = uiLayoutBox(layout);
292         row = uiLayoutRow(box, false);
293         uiItemL(row, IFACE_("Collada Options:"), ICON_MODIFIER);
294
295         row = uiLayoutRow(box, false);
296         uiItemR(row, imfptr, "triangulate", 1, NULL, ICON_NONE);
297         row = uiLayoutRow(box, false);
298         uiItemR(row, imfptr, "use_object_instantiation", 1, NULL, ICON_NONE);
299         row = uiLayoutRow(box, false);
300         uiItemR(row, imfptr, "use_blender_profile", 1, NULL, ICON_NONE);
301
302         row = uiLayoutRow(box, false);
303         split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
304         uiItemL(split, IFACE_("Transformation Type"), ICON_NONE);
305         uiItemR(split, imfptr, "export_transformation_type_selection", 0, "", ICON_NONE);
306         row = uiLayoutRow(box, false);
307         uiItemR(row, imfptr, "sort_by_name", 0, NULL, ICON_NONE);
308
309         row = uiLayoutRow(box, false);
310         uiItemR(row, imfptr, "keep_bind_info", 0, NULL, ICON_NONE);
311
312         row = uiLayoutRow(box, false);
313         uiItemR(row, imfptr, "limit_precision", 0, NULL, ICON_NONE);
314
315 }
316
317 static void wm_collada_export_draw(bContext *UNUSED(C), wmOperator *op)
318 {
319         PointerRNA ptr;
320
321         RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
322         uiCollada_exportSettings(op->layout, &ptr);
323 }
324
325 static bool wm_collada_export_check(bContext *UNUSED(C), wmOperator *op)
326 {
327         char filepath[FILE_MAX];
328         RNA_string_get(op->ptr, "filepath", filepath);
329
330         if (!BLI_testextensie(filepath, ".dae")) {
331                 BLI_ensure_extension(filepath, FILE_MAX, ".dae");
332                 RNA_string_set(op->ptr, "filepath", filepath);
333                 return true;
334         }
335
336         return false;
337 }
338
339 void WM_OT_collada_export(wmOperatorType *ot)
340 {
341         struct StructRNA *func = ot->srna;
342
343         static const EnumPropertyItem prop_bc_export_mesh_type[] = {
344                 {BC_MESH_TYPE_VIEW, "view", 0, "View", "Apply modifier's view settings"},
345                 {BC_MESH_TYPE_RENDER, "render", 0, "Render", "Apply modifier's render settings"},
346                 {0, NULL, 0, NULL, NULL}
347         };
348
349         static const EnumPropertyItem prop_bc_export_transformation_type[] = {
350                 {BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations"},
351                 {BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations"},
352                 {0, NULL, 0, NULL, NULL}
353         };
354
355         ot->name = "Export COLLADA";
356         ot->description = "Save a Collada file";
357         ot->idname = "WM_OT_collada_export";
358
359         ot->invoke = wm_collada_export_invoke;
360         ot->exec = wm_collada_export_exec;
361         ot->poll = WM_operator_winactive;
362         ot->check = wm_collada_export_check;
363
364         ot->flag |= OPTYPE_PRESET;
365
366         ot->ui = wm_collada_export_draw;
367
368         WM_operator_properties_filesel(
369                 ot, FILE_TYPE_FOLDER | FILE_TYPE_COLLADA, FILE_BLENDER, FILE_SAVE,
370                 WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
371
372         RNA_def_boolean(func,
373                         "apply_modifiers", 0, "Apply Modifiers",
374                         "Apply modifiers to exported mesh (non destructive))");
375
376         RNA_def_int(func, "export_mesh_type", 0, INT_MIN, INT_MAX,
377                     "Resolution", "Modifier resolution for export", INT_MIN, INT_MAX);
378
379         RNA_def_enum(func, "export_mesh_type_selection", prop_bc_export_mesh_type, 0,
380                      "Resolution", "Modifier resolution for export");
381
382         RNA_def_boolean(func, "selected", 0, "Selection Only",
383                         "Export only selected elements");
384
385         RNA_def_boolean(func, "include_children", 0, "Include Children",
386                         "Export all children of selected objects (even if not selected)");
387
388         RNA_def_boolean(func, "include_armatures", 0, "Include Armatures",
389                         "Export related armatures (even if not selected)");
390
391         RNA_def_boolean(func, "include_shapekeys", 1, "Include Shape Keys",
392                         "Export all Shape Keys from Mesh Objects");
393
394         RNA_def_boolean(func, "deform_bones_only", 0, "Deform Bones only",
395                         "Only export deforming bones with armatures");
396
397         RNA_def_boolean(func, "include_animations", false,
398                 "Include Animations", "Export Animations if available.\nExporting Animations will enforce the decomposition of node transforms\ninto  <translation> <rotation> and <scale> components");
399
400         RNA_def_boolean(func, "sample_animations", 0,
401                 "Sample Animations", "Auto-generate keyframes with a frame distance set by 'Sampling Rate'.\nWhen disabled, export only the keyframes defined in the animation f-curves (may be less accurate)");
402
403         RNA_def_int(func, "sampling_rate", 1, 1, INT_MAX,
404                 "Sampling Rate", "The distance between 2 keyframes. 1 means: Every frame is keyed", 1, INT_MAX);
405
406
407         RNA_def_boolean(func, "active_uv_only", 0, "Only Selected UV Map",
408                         "Export only the selected UV Map");
409
410         RNA_def_boolean(func, "include_material_textures", 0, "Include Material Textures",
411                         "Export textures assigned to the object Materials");
412
413         RNA_def_boolean(func, "use_texture_copies", 1, "Copy",
414                         "Copy textures to same folder where the .dae file is exported");
415
416
417         RNA_def_boolean(func, "triangulate", 1, "Triangulate",
418                         "Export Polygons (Quads & NGons) as Triangles");
419
420         RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instances",
421                 "Instantiate multiple Objects from same Data");
422
423         RNA_def_boolean(func, "use_blender_profile", 1, "Use Blender Profile",
424                 "Export additional Blender specific information (for material, shaders, bones, etc.)");
425
426         RNA_def_boolean(func, "sort_by_name", 0, "Sort by Object name",
427                         "Sort exported data by Object name");
428
429         RNA_def_int(func, "export_transformation_type", 0, INT_MIN, INT_MAX,
430                     "Transform", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
431
432         RNA_def_enum(func, "export_transformation_type_selection", prop_bc_export_transformation_type, 0,
433                      "Transform", "Transformation type for translation, scale and rotation");
434
435         RNA_def_boolean(func, "open_sim", 0, "Export to SL/OpenSim",
436                         "Compatibility mode for SL, OpenSim and other compatible online worlds");
437
438         RNA_def_boolean(func, "limit_precision", 0,
439                 "Limit Precision", "Reduce the precision of the exported data to 6 digits");
440
441         RNA_def_boolean(func, "keep_bind_info", 0,
442                 "Keep Bind Info", "Store Bindpose information in custom bone properties for later use during Collada export");
443
444 }
445
446
447 /* function used for WM_OT_save_mainfile too */
448 static int wm_collada_import_exec(bContext *C, wmOperator *op)
449 {
450         char filename[FILE_MAX];
451         int import_units;
452         int find_chains;
453         int auto_connect;
454         int fix_orientation;
455         int min_chain_length;
456
457         int keep_bind_info;
458
459         if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
460                 BKE_report(op->reports, RPT_ERROR, "No filename given");
461                 return OPERATOR_CANCELLED;
462         }
463
464         /* Options panel */
465         import_units     = RNA_boolean_get(op->ptr, "import_units");
466         find_chains      = RNA_boolean_get(op->ptr, "find_chains");
467         auto_connect     = RNA_boolean_get(op->ptr, "auto_connect");
468         fix_orientation  = RNA_boolean_get(op->ptr, "fix_orientation");
469
470         keep_bind_info = RNA_boolean_get(op->ptr, "keep_bind_info");
471
472         min_chain_length = RNA_int_get(op->ptr, "min_chain_length");
473
474         RNA_string_get(op->ptr, "filepath", filename);
475         if (collada_import(
476                 C, filename,
477                 import_units,
478                 find_chains,
479                 auto_connect,
480                 fix_orientation,
481                 min_chain_length,
482                 keep_bind_info) )
483         {
484                 DEG_id_tag_update(&CTX_data_scene(C)->id, DEG_TAG_BASE_FLAGS_UPDATE);
485                 return OPERATOR_FINISHED;
486         }
487         else {
488                 BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document (see console for details)");
489                 return OPERATOR_CANCELLED;
490         }
491 }
492
493 static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr)
494 {
495         uiLayout *box, *row;
496
497         /* Import Options: */
498         box = uiLayoutBox(layout);
499         row = uiLayoutRow(box, false);
500         uiItemL(row, IFACE_("Import Data Options:"), ICON_MESH_DATA);
501
502         row = uiLayoutRow(box, false);
503         uiItemR(row, imfptr, "import_units", 0, NULL, ICON_NONE);
504
505         box = uiLayoutBox(layout);
506         row = uiLayoutRow(box, false);
507         uiItemL(row, IFACE_("Armature Options:"), ICON_MESH_DATA);
508
509         row = uiLayoutRow(box, false);
510         uiItemR(row, imfptr, "fix_orientation", 0, NULL, ICON_NONE);
511
512         row = uiLayoutRow(box, false);
513         uiItemR(row, imfptr, "find_chains", 0, NULL, ICON_NONE);
514
515         row = uiLayoutRow(box, false);
516         uiItemR(row, imfptr, "auto_connect", 0, NULL, ICON_NONE);
517
518         row = uiLayoutRow(box, false);
519         uiItemR(row, imfptr, "min_chain_length", 0, NULL, ICON_NONE);
520
521         box = uiLayoutBox(layout);
522         row = uiLayoutRow(box, false);
523
524         row = uiLayoutRow(box, false);
525         uiItemR(row, imfptr, "keep_bind_info", 0, NULL, ICON_NONE);
526
527 }
528
529 static void wm_collada_import_draw(bContext *UNUSED(C), wmOperator *op)
530 {
531         PointerRNA ptr;
532
533         RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
534         uiCollada_importSettings(op->layout, &ptr);
535 }
536
537 void WM_OT_collada_import(wmOperatorType *ot)
538 {
539         ot->name = "Import COLLADA";
540         ot->description = "Load a Collada file";
541         ot->idname = "WM_OT_collada_import";
542
543         ot->invoke = WM_operator_filesel;
544         ot->exec = wm_collada_import_exec;
545         ot->poll = WM_operator_winactive;
546
547         //ot->flag |= OPTYPE_PRESET;
548
549         ot->ui = wm_collada_import_draw;
550
551         WM_operator_properties_filesel(
552                 ot, FILE_TYPE_FOLDER | FILE_TYPE_COLLADA, FILE_BLENDER, FILE_OPENFILE,
553                 WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
554
555         RNA_def_boolean(ot->srna,
556                 "import_units", 0, "Import Units",
557                 "If disabled match import to Blender's current Unit settings, "
558                 "otherwise use the settings from the Imported scene");
559
560         RNA_def_boolean(ot->srna,
561                 "fix_orientation", 0, "Fix Leaf Bones",
562                 "Fix Orientation of Leaf Bones (Collada does only support Joints)");
563
564         RNA_def_boolean(ot->srna,
565                 "find_chains", 0, "Find Bone Chains",
566                 "Find best matching Bone Chains and ensure bones in chain are connected");
567
568         RNA_def_boolean(ot->srna,
569                 "auto_connect", 0, "Auto Connect",
570                 "Set use_connect for parent bones which have exactly one child bone");
571
572         RNA_def_int(ot->srna,
573                 "min_chain_length",
574                 0,
575                 0,
576                 INT_MAX,
577                 "Minimum Chain Length",
578                 "When searching Bone Chains disregard chains of length below this value",
579                 0,
580                 INT_MAX);
581
582         RNA_def_boolean(ot->srna, 
583                 "keep_bind_info", 0, "Keep Bind Info", 
584                 "Store Bindpose information in custom bone properties for later use during Collada export");
585
586 }
587 #endif