Cleanup: style, whitespace, doxy filepaths
[blender-staging.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_scene_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 "ED_screen.h"
44 #include "ED_object.h"
45
46 #include "RNA_access.h"
47 #include "RNA_define.h"
48
49 #include "UI_interface.h"
50 #include "UI_resources.h"
51
52 #include "WM_api.h"
53 #include "WM_types.h"
54
55 #include "../../collada/collada.h"
56
57 #include "io_collada.h"
58
59 static int wm_collada_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
60 {       
61         if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
62                 char filepath[FILE_MAX];
63
64                 if (G.main->name[0] == 0)
65                         BLI_strncpy(filepath, "untitled", sizeof(filepath));
66                 else
67                         BLI_strncpy(filepath, G.main->name, sizeof(filepath));
68
69                 BLI_replace_extension(filepath, sizeof(filepath), ".dae");
70                 RNA_string_set(op->ptr, "filepath", filepath);
71         }
72
73         WM_event_add_fileselect(C, op);
74
75         return OPERATOR_RUNNING_MODAL;
76 }
77
78 /* function used for WM_OT_save_mainfile too */
79 static int wm_collada_export_exec(bContext *C, wmOperator *op)
80 {
81         char filepath[FILE_MAX];
82         int apply_modifiers;
83         int export_mesh_type;
84         int selected;
85         int include_children;
86         int include_armatures;
87         int include_shapekeys;
88         int deform_bones_only;
89
90         int include_uv_textures;
91         int include_material_textures;
92         int use_texture_copies;
93         int active_uv_only;
94
95         int triangulate;
96         int use_object_instantiation;
97         int use_blender_profile;
98         int sort_by_name;
99         int export_transformation_type;
100         int open_sim;
101
102         int export_count;
103
104         if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
105                 BKE_report(op->reports, RPT_ERROR, "No filename given");
106                 return OPERATOR_CANCELLED;
107         }
108
109         RNA_string_get(op->ptr, "filepath", filepath);
110         BLI_ensure_extension(filepath, sizeof(filepath), ".dae");
111
112
113         /* Avoid File write exceptions in Collada */
114         if (!BLI_exists(filepath)) {
115                 BLI_make_existing_file(filepath);
116                 if (!BLI_file_touch(filepath)) {
117                         BKE_report(op->reports, RPT_ERROR, "Can't create export file");
118                         fprintf(stdout, "Collada export: Can not create: %s\n", filepath);
119                         return OPERATOR_CANCELLED;
120                 }
121         }
122         else if (!BLI_file_is_writable(filepath)) {
123                 BKE_report(op->reports, RPT_ERROR, "Can't overwrite export file");
124                 fprintf(stdout, "Collada export: Can not modify: %s\n", filepath);
125                 return OPERATOR_CANCELLED;
126         }
127
128         /* Now the exporter can create and write the export file */
129
130         /* Options panel */
131         apply_modifiers          = RNA_boolean_get(op->ptr, "apply_modifiers");
132         export_mesh_type         = RNA_enum_get(op->ptr,    "export_mesh_type_selection");
133         selected                 = RNA_boolean_get(op->ptr, "selected");
134         include_children         = RNA_boolean_get(op->ptr, "include_children");
135         include_armatures        = RNA_boolean_get(op->ptr, "include_armatures");
136         include_shapekeys        = RNA_boolean_get(op->ptr, "include_shapekeys");
137         deform_bones_only        = RNA_boolean_get(op->ptr, "deform_bones_only");
138
139         include_uv_textures      = RNA_boolean_get(op->ptr, "include_uv_textures");
140         include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures");
141         use_texture_copies       = RNA_boolean_get(op->ptr, "use_texture_copies");
142         active_uv_only           = RNA_boolean_get(op->ptr, "active_uv_only");
143
144         triangulate                = RNA_boolean_get(op->ptr, "triangulate");
145         use_object_instantiation   = RNA_boolean_get(op->ptr, "use_object_instantiation");
146         use_blender_profile        = RNA_boolean_get(op->ptr, "use_blender_profile");
147         sort_by_name               = RNA_boolean_get(op->ptr, "sort_by_name");
148         export_transformation_type = RNA_enum_get(op->ptr,    "export_transformation_type_selection");
149         open_sim                   = RNA_boolean_get(op->ptr, "open_sim");
150
151         /* get editmode results */
152         ED_object_editmode_load(CTX_data_edit_object(C));
153
154
155         export_count = collada_export(CTX_data_scene(C),
156                 filepath,
157                 apply_modifiers,
158                 export_mesh_type,
159                 selected,
160                 include_children,
161                 include_armatures,
162                 include_shapekeys,
163                 deform_bones_only,
164
165                 active_uv_only,
166                 include_uv_textures,
167                 include_material_textures,
168                 use_texture_copies,
169
170                 triangulate,
171                 use_object_instantiation,
172                 use_blender_profile,
173                 sort_by_name,
174                 export_transformation_type,
175                 open_sim);
176
177         if (export_count == 0) {
178                 BKE_report(op->reports, RPT_WARNING, "Export file is empty");
179                 return OPERATOR_CANCELLED;
180         }
181         else if (export_count < 0) {
182                 BKE_report(op->reports, RPT_WARNING, "Error during export (see Console)");
183                 return OPERATOR_CANCELLED;
184         }
185         else {
186                 char buff[100];
187                 sprintf(buff, "Exported %d Objects", export_count);
188                 BKE_report(op->reports, RPT_INFO, buff);
189                 return OPERATOR_FINISHED;
190         }
191 }
192
193 static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
194 {
195         uiLayout *box, *row, *col, *split;
196
197         /* Export Options: */
198         box = uiLayoutBox(layout);
199         row = uiLayoutRow(box, false);
200         uiItemL(row, IFACE_("Export Data Options:"), ICON_MESH_DATA);
201
202         row = uiLayoutRow(box, false);
203         split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
204         col   = uiLayoutColumn(split, false);
205         uiItemR(col, imfptr, "apply_modifiers", 0, NULL, ICON_NONE);
206         col   = uiLayoutColumn(split, false);
207         uiItemR(col, imfptr, "export_mesh_type_selection", 0, "", ICON_NONE);
208         uiLayoutSetEnabled(col, RNA_boolean_get(imfptr, "apply_modifiers"));
209
210         row = uiLayoutRow(box, false);
211         uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE);
212
213         row = uiLayoutRow(box, false);
214         uiItemR(row, imfptr, "include_children", 0, NULL, ICON_NONE);
215         uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
216
217         row = uiLayoutRow(box, false);
218         uiItemR(row, imfptr, "include_armatures", 0, NULL, ICON_NONE);
219         uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
220
221         row = uiLayoutRow(box, false);
222         uiItemR(row, imfptr, "include_shapekeys", 0, NULL, ICON_NONE);
223         uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
224
225         /* Texture options */
226         box = uiLayoutBox(layout);
227         row = uiLayoutRow(box, false);
228         uiItemL(row, IFACE_("Texture Options:"), ICON_TEXTURE_DATA);
229
230         row = uiLayoutRow(box, false);
231         uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE);
232
233         row = uiLayoutRow(box, false);
234         uiItemR(row, imfptr, "include_uv_textures", 0, NULL, ICON_NONE);
235
236         row = uiLayoutRow(box, false);
237         uiItemR(row, imfptr, "include_material_textures", 0, NULL, ICON_NONE);
238
239         row = uiLayoutRow(box, false);
240         uiItemR(row, imfptr, "use_texture_copies", 1, NULL, ICON_NONE);
241
242
243         /* Armature options */
244         box = uiLayoutBox(layout);
245         row = uiLayoutRow(box, false);
246         uiItemL(row, IFACE_("Armature Options:"), ICON_ARMATURE_DATA);
247
248         row = uiLayoutRow(box, false);
249         uiItemR(row, imfptr, "deform_bones_only", 0, NULL, ICON_NONE);
250         row = uiLayoutRow(box, false);
251         uiItemR(row, imfptr, "open_sim", 0, NULL, ICON_NONE);
252
253         /* Collada options: */
254         box = uiLayoutBox(layout);
255         row = uiLayoutRow(box, false);
256         uiItemL(row, IFACE_("Collada Options:"), ICON_MODIFIER);
257
258         row = uiLayoutRow(box, false);
259         uiItemR(row, imfptr, "triangulate", 0, NULL, ICON_NONE);
260         row = uiLayoutRow(box, false);
261         uiItemR(row, imfptr, "use_object_instantiation", 0, NULL, ICON_NONE);
262         row = uiLayoutRow(box, false);
263         uiItemR(row, imfptr, "use_blender_profile", 0, NULL, ICON_NONE);
264
265         row = uiLayoutRow(box, false);
266         split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
267         uiItemL(split, IFACE_("Transformation Type"), ICON_NONE);
268         uiItemR(split, imfptr, "export_transformation_type_selection", 0, "", ICON_NONE);
269
270         row = uiLayoutRow(box, false);
271         uiItemR(row, imfptr, "sort_by_name", 0, NULL, ICON_NONE);
272
273 }
274
275 static void wm_collada_export_draw(bContext *UNUSED(C), wmOperator *op)
276 {
277         PointerRNA ptr;
278
279         RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
280         uiCollada_exportSettings(op->layout, &ptr);
281 }
282
283 void WM_OT_collada_export(wmOperatorType *ot)
284 {
285         static EnumPropertyItem prop_bc_export_mesh_type[] = {
286                 {BC_MESH_TYPE_VIEW, "view", 0, "View", "Apply modifier's view settings"},
287                 {BC_MESH_TYPE_RENDER, "render", 0, "Render", "Apply modifier's render settings"},
288                 {0, NULL, 0, NULL, NULL}
289         };
290
291         static EnumPropertyItem prop_bc_export_transformation_type[] = {
292                 {BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations"},
293                 {BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations"},
294                 {BC_TRANSFORMATION_TYPE_BOTH, "both", 0, "Both", "Use <matrix> AND <translate>, <rotate>, <scale> to specify transformations"},
295                 {0, NULL, 0, NULL, NULL}
296         };
297
298         ot->name = "Export COLLADA";
299         ot->description = "Save a Collada file";
300         ot->idname = "WM_OT_collada_export";
301
302         ot->invoke = wm_collada_export_invoke;
303         ot->exec = wm_collada_export_exec;
304         ot->poll = WM_operator_winactive;
305
306         ot->flag |= OPTYPE_PRESET;
307
308         ot->ui = wm_collada_export_draw;
309
310         WM_operator_properties_filesel(
311                 ot, FILE_TYPE_FOLDER | FILE_TYPE_COLLADA, FILE_BLENDER, FILE_SAVE,
312                 WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
313
314         RNA_def_boolean(ot->srna,
315                         "apply_modifiers", 0, "Apply Modifiers",
316                         "Apply modifiers to exported mesh (non destructive))");
317
318         RNA_def_int(ot->srna, "export_mesh_type", 0, INT_MIN, INT_MAX,
319                     "Resolution", "Modifier resolution for export", INT_MIN, INT_MAX);
320
321         RNA_def_enum(ot->srna, "export_mesh_type_selection", prop_bc_export_mesh_type, 0,
322                      "Resolution", "Modifier resolution for export");
323
324         RNA_def_boolean(ot->srna, "selected", 0, "Selection Only",
325                         "Export only selected elements");
326
327         RNA_def_boolean(ot->srna, "include_children", 0, "Include Children",
328                         "Export all children of selected objects (even if not selected)");
329
330         RNA_def_boolean(ot->srna, "include_armatures", 0, "Include Armatures",
331                         "Export related armatures (even if not selected)");
332
333         RNA_def_boolean(ot->srna, "include_shapekeys", 1, "Include Shape Keys",
334                         "Export all Shape Keys from Mesh Objects");
335
336         RNA_def_boolean(ot->srna, "deform_bones_only", 0, "Deform Bones only",
337                         "Only export deforming bones with armatures");
338
339
340         RNA_def_boolean(ot->srna, "active_uv_only", 0, "Only Selected UV Map",
341                         "Export only the selected UV Map");
342
343         RNA_def_boolean(ot->srna, "include_uv_textures", 0, "Include UV Textures",
344                         "Export textures assigned to the object UV Maps");
345
346         RNA_def_boolean(ot->srna, "include_material_textures", 0, "Include Material Textures",
347                         "Export textures assigned to the object Materials");
348
349         RNA_def_boolean(ot->srna, "use_texture_copies", 1, "Copy",
350                         "Copy textures to same folder where the .dae file is exported");
351
352
353         RNA_def_boolean(ot->srna, "triangulate", 1, "Triangulate",
354                         "Export Polygons (Quads & NGons) as Triangles");
355
356         RNA_def_boolean(ot->srna, "use_object_instantiation", 1, "Use Object Instances",
357                 "Instantiate multiple Objects from same Data");
358
359         RNA_def_boolean(ot->srna, "use_blender_profile", 1, "Use Blender Profile",
360                 "Export additional Blender specific information (for material, shaders, bones, etc.)");
361
362         RNA_def_boolean(ot->srna, "sort_by_name", 0, "Sort by Object name",
363                         "Sort exported data by Object name");
364
365         RNA_def_int(ot->srna, "export_transformation_type", 0, INT_MIN, INT_MAX,
366                     "Transform", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
367
368         RNA_def_enum(ot->srna, "export_transformation_type_selection", prop_bc_export_transformation_type, 0,
369                      "Transform", "Transformation type for translation, scale and rotation");
370
371         RNA_def_boolean(ot->srna, "open_sim", 0, "Export to SL/OpenSim",
372                         "Compatibility mode for SL, OpenSim and other compatible online worlds");
373 }
374
375
376 /* function used for WM_OT_save_mainfile too */
377 static int wm_collada_import_exec(bContext *C, wmOperator *op)
378 {
379         char filename[FILE_MAX];
380         int import_units;
381         int find_chains;
382         int auto_connect;
383         int fix_orientation;
384         int  min_chain_length;
385
386         if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
387                 BKE_report(op->reports, RPT_ERROR, "No filename given");
388                 return OPERATOR_CANCELLED;
389         }
390
391         /* Options panel */
392         import_units     = RNA_boolean_get(op->ptr, "import_units");
393         find_chains      = RNA_boolean_get(op->ptr, "find_chains");
394         auto_connect     = RNA_boolean_get(op->ptr, "auto_connect");
395         fix_orientation  = RNA_boolean_get(op->ptr, "fix_orientation");
396         min_chain_length = RNA_int_get(op->ptr, "min_chain_length");
397
398         RNA_string_get(op->ptr, "filepath", filename);
399         if (collada_import(
400                 C, filename,
401                 import_units,
402                 find_chains,
403                 auto_connect,
404                 fix_orientation,
405                 min_chain_length))
406         {
407                 return OPERATOR_FINISHED;
408         }
409         else {
410                 BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document (see console for details)");
411                 return OPERATOR_CANCELLED;
412         }
413 }
414
415 static void uiCollada_importSettings(uiLayout *layout, PointerRNA *imfptr)
416 {
417         uiLayout *box, *row;
418
419         /* Import Options: */
420         box = uiLayoutBox(layout);
421         row = uiLayoutRow(box, false);
422         uiItemL(row, IFACE_("Import Data Options:"), ICON_MESH_DATA);
423
424         row = uiLayoutRow(box, false);
425         uiItemR(row, imfptr, "import_units", 0, NULL, ICON_NONE);
426
427         box = uiLayoutBox(layout);
428         row = uiLayoutRow(box, false);
429         uiItemL(row, IFACE_("Armature Options:"), ICON_MESH_DATA);
430
431         row = uiLayoutRow(box, false);
432         uiItemR(row, imfptr, "fix_orientation", 0, NULL, ICON_NONE);
433
434         row = uiLayoutRow(box, false);
435         uiItemR(row, imfptr, "find_chains", 0, NULL, ICON_NONE);
436
437         row = uiLayoutRow(box, false);
438         uiItemR(row, imfptr, "auto_connect", 0, NULL, ICON_NONE);
439
440         row = uiLayoutRow(box, false);
441         uiItemR(row, imfptr, "min_chain_length", 0, NULL, ICON_NONE);
442 }
443
444 static void wm_collada_import_draw(bContext *UNUSED(C), wmOperator *op)
445 {
446         PointerRNA ptr;
447
448         RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
449         uiCollada_importSettings(op->layout, &ptr);
450 }
451
452 void WM_OT_collada_import(wmOperatorType *ot)
453 {
454         ot->name = "Import COLLADA";
455         ot->description = "Load a Collada file";
456         ot->idname = "WM_OT_collada_import";
457
458         ot->invoke = WM_operator_filesel;
459         ot->exec = wm_collada_import_exec;
460         ot->poll = WM_operator_winactive;
461
462         //ot->flag |= OPTYPE_PRESET;
463
464         ot->ui = wm_collada_import_draw;
465
466         WM_operator_properties_filesel(
467                 ot, FILE_TYPE_FOLDER | FILE_TYPE_COLLADA, FILE_BLENDER, FILE_OPENFILE,
468                 WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
469
470         RNA_def_boolean(ot->srna,
471                 "import_units", 0, "Import Units",
472                 "If disabled match import to Blender's current Unit settings, "
473                 "otherwise use the settings from the Imported scene");
474
475         RNA_def_boolean(ot->srna,
476                 "fix_orientation", 0, "Fix Leaf Bones",
477                 "Fix Orientation of Leaf Bones (Collada does only support Joints)");
478
479         RNA_def_boolean(ot->srna,
480                 "find_chains", 0, "Find Bone Chains",
481                 "Find best matching Bone Chains and ensure bones in chain are connected");
482
483         RNA_def_boolean(ot->srna,
484                 "auto_connect", 0, "Auto Connect",
485                 "Set use_connect for parent bones which have exactly one child bone");
486
487         RNA_def_int(ot->srna,
488                 "min_chain_length",
489                 0,
490                 0,
491                 INT_MAX,
492                 "Minimum Chain Length",
493                 "When searching Bone Chains disregard chains of length below this value",
494                 0,
495                 INT_MAX);
496
497 }
498 #endif