Cleanup: remove redundant doxygen \file argument
[blender.git] / source / blender / editors / io / io_alembic.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software  Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2016 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file \ingroup editor/io
21  */
22
23 #ifdef WITH_ALEMBIC
24
25 /* needed for directory lookup */
26 #ifndef WIN32
27 #  include <dirent.h>
28 #else
29 #  include "BLI_winstuff.h"
30 #endif
31
32 #include <string.h>
33 #include <errno.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_mesh_types.h"
38 #include "DNA_modifier_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_space_types.h"
42
43 #include "BKE_context.h"
44 #include "BKE_global.h"
45 #include "BKE_main.h"
46 #include "BKE_report.h"
47
48 #include "BLI_listbase.h"
49 #include "BLI_math_vector.h"
50 #include "BLI_path_util.h"
51 #include "BLI_string.h"
52 #include "BLI_utildefines.h"
53
54 #include "BLT_translation.h"
55
56 #include "RNA_access.h"
57 #include "RNA_define.h"
58 #include "RNA_enum_types.h"
59
60 #include "ED_object.h"
61
62 #include "UI_interface.h"
63 #include "UI_resources.h"
64
65 #include "WM_api.h"
66 #include "WM_types.h"
67
68 #include "io_alembic.h"
69
70 #include "ABC_alembic.h"
71
72 static int wm_alembic_export_invoke(bContext *C, wmOperator *op, const wmEvent *event)
73 {
74         if (!RNA_struct_property_is_set(op->ptr, "as_background_job")) {
75                 RNA_boolean_set(op->ptr, "as_background_job", true);
76         }
77
78         RNA_boolean_set(op->ptr, "init_scene_frame_range", true);
79
80         if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
81                 Main *bmain = CTX_data_main(C);
82                 char filepath[FILE_MAX];
83
84                 if (BKE_main_blendfile_path(bmain)[0] == '\0') {
85                         BLI_strncpy(filepath, "untitled", sizeof(filepath));
86                 }
87                 else {
88                         BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
89                 }
90
91                 BLI_path_extension_replace(filepath, sizeof(filepath), ".abc");
92                 RNA_string_set(op->ptr, "filepath", filepath);
93         }
94
95         WM_event_add_fileselect(C, op);
96
97         return OPERATOR_RUNNING_MODAL;
98
99         UNUSED_VARS(event);
100 }
101
102 static int wm_alembic_export_exec(bContext *C, wmOperator *op)
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         char filename[FILE_MAX];
110         RNA_string_get(op->ptr, "filepath", filename);
111
112         struct AlembicExportParams params = {
113             .frame_start = RNA_int_get(op->ptr, "start"),
114             .frame_end = RNA_int_get(op->ptr, "end"),
115
116             .frame_samples_xform = RNA_int_get(op->ptr, "xsamples"),
117             .frame_samples_shape = RNA_int_get(op->ptr, "gsamples"),
118
119             .shutter_open = RNA_float_get(op->ptr, "sh_open"),
120             .shutter_close = RNA_float_get(op->ptr, "sh_close"),
121
122             .selected_only = RNA_boolean_get(op->ptr, "selected"),
123             .uvs = RNA_boolean_get(op->ptr, "uvs"),
124             .normals = RNA_boolean_get(op->ptr, "normals"),
125             .vcolors = RNA_boolean_get(op->ptr, "vcolors"),
126             .apply_subdiv = RNA_boolean_get(op->ptr, "apply_subdiv"),
127             .curves_as_mesh = RNA_boolean_get(op->ptr, "curves_as_mesh"),
128             .flatten_hierarchy = RNA_boolean_get(op->ptr, "flatten"),
129             .visible_layers_only = RNA_boolean_get(op->ptr, "visible_layers_only"),
130             .renderable_only = RNA_boolean_get(op->ptr, "renderable_only"),
131             .face_sets = RNA_boolean_get(op->ptr, "face_sets"),
132             .use_subdiv_schema = RNA_boolean_get(op->ptr, "subdiv_schema"),
133             .export_hair = RNA_boolean_get(op->ptr, "export_hair"),
134             .export_particles = RNA_boolean_get(op->ptr, "export_particles"),
135             .compression_type = RNA_enum_get(op->ptr, "compression_type"),
136             .packuv = RNA_boolean_get(op->ptr, "packuv"),
137             .triangulate = RNA_boolean_get(op->ptr, "triangulate"),
138             .quad_method = RNA_enum_get(op->ptr, "quad_method"),
139             .ngon_method = RNA_enum_get(op->ptr, "ngon_method"),
140
141             .global_scale = RNA_float_get(op->ptr, "global_scale"),
142         };
143
144         /* Take some defaults from the scene, if not specified explicitly. */
145         Scene *scene = CTX_data_scene(C);
146         if (params.frame_start == INT_MIN) {
147                 params.frame_start = SFRA;
148         }
149         if (params.frame_end == INT_MIN) {
150                 params.frame_end = EFRA;
151         }
152
153         const bool as_background_job = RNA_boolean_get(op->ptr, "as_background_job");
154         bool ok = ABC_export(scene, C, filename, &params, as_background_job);
155
156         return as_background_job || ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
157 }
158
159 static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr)
160 {
161         uiLayout *box;
162         uiLayout *row;
163         uiLayout *col;
164
165 #ifdef WITH_ALEMBIC_HDF5
166         box = uiLayoutBox(layout);
167         row = uiLayoutRow(box, false);
168         uiItemL(row, IFACE_("Archive Options:"), ICON_NONE);
169
170         row = uiLayoutRow(box, false);
171         uiItemR(row, imfptr, "compression_type", 0, NULL, ICON_NONE);
172 #endif
173
174         box = uiLayoutBox(layout);
175         row = uiLayoutRow(box, false);
176         uiItemL(row, IFACE_("Manual Transform:"), ICON_NONE);
177
178         row = uiLayoutRow(box, false);
179         uiItemR(row, imfptr, "global_scale", 0, NULL, ICON_NONE);
180
181         /* Scene Options */
182         box = uiLayoutBox(layout);
183         row = uiLayoutRow(box, false);
184         uiItemL(row, IFACE_("Scene Options:"), ICON_SCENE_DATA);
185
186         row = uiLayoutRow(box, false);
187         uiItemR(row, imfptr, "start", 0, NULL, ICON_NONE);
188
189         row = uiLayoutRow(box, false);
190         uiItemR(row, imfptr, "end", 0, NULL, ICON_NONE);
191
192         row = uiLayoutRow(box, false);
193         uiItemR(row, imfptr, "xsamples", 0, NULL, ICON_NONE);
194
195         row = uiLayoutRow(box, false);
196         uiItemR(row, imfptr, "gsamples", 0, NULL, ICON_NONE);
197
198         row = uiLayoutRow(box, false);
199         uiItemR(row, imfptr, "sh_open", 0, NULL, ICON_NONE);
200
201         row = uiLayoutRow(box, false);
202         uiItemR(row, imfptr, "sh_close", 0, NULL, ICON_NONE);
203
204         row = uiLayoutRow(box, false);
205         uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE);
206
207         row = uiLayoutRow(box, false);
208         uiItemR(row, imfptr, "renderable_only", 0, NULL, ICON_NONE);
209
210         row = uiLayoutRow(box, false);
211         uiItemR(row, imfptr, "visible_layers_only", 0, NULL, ICON_NONE);
212
213         row = uiLayoutRow(box, false);
214         uiItemR(row, imfptr, "flatten", 0, NULL, ICON_NONE);
215
216         /* Object Data */
217         box = uiLayoutBox(layout);
218         row = uiLayoutRow(box, false);
219         uiItemL(row, IFACE_("Object Options:"), ICON_OBJECT_DATA);
220
221         row = uiLayoutRow(box, false);
222         uiItemR(row, imfptr, "uvs", 0, NULL, ICON_NONE);
223
224         row = uiLayoutRow(box, false);
225         uiItemR(row, imfptr, "packuv", 0, NULL, ICON_NONE);
226         uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "uvs"));
227
228         row = uiLayoutRow(box, false);
229         uiItemR(row, imfptr, "normals", 0, NULL, ICON_NONE);
230
231         row = uiLayoutRow(box, false);
232         uiItemR(row, imfptr, "vcolors", 0, NULL, ICON_NONE);
233
234         row = uiLayoutRow(box, false);
235         uiItemR(row, imfptr, "face_sets", 0, NULL, ICON_NONE);
236
237         row = uiLayoutRow(box, false);
238         uiItemR(row, imfptr, "subdiv_schema", 0, NULL, ICON_NONE);
239
240         row = uiLayoutRow(box, false);
241         uiItemR(row, imfptr, "apply_subdiv", 0, NULL, ICON_NONE);
242
243         row = uiLayoutRow(box, false);
244         uiItemR(row, imfptr, "curves_as_mesh", 0, NULL, ICON_NONE);
245
246         row = uiLayoutRow(box, false);
247         uiItemR(row, imfptr, "triangulate", 0, NULL, ICON_NONE);
248
249         const bool triangulate = RNA_boolean_get(imfptr, "triangulate");
250
251         row = uiLayoutRow(box, false);
252         uiLayoutSetEnabled(row, triangulate);
253         uiItemR(row, imfptr, "quad_method", 0, NULL, ICON_NONE);
254
255         row = uiLayoutRow(box, false);
256         uiLayoutSetEnabled(row, triangulate);
257         uiItemR(row, imfptr, "ngon_method", 0, NULL, ICON_NONE);
258
259         /* Object Data */
260         box = uiLayoutBox(layout);
261         row = uiLayoutRow(box, false);
262         uiItemL(row, IFACE_("Particle Systems:"), ICON_PARTICLE_DATA);
263
264         col = uiLayoutColumn(box, true);
265         uiItemR(col, imfptr, "export_hair", 0, NULL, ICON_NONE);
266         uiItemR(col, imfptr, "export_particles", 0, NULL, ICON_NONE);
267 }
268
269 static void wm_alembic_export_draw(bContext *C, wmOperator *op)
270 {
271         PointerRNA ptr;
272
273         RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
274
275         /* Conveniently set start and end frame to match the scene's frame range. */
276         Scene *scene = CTX_data_scene(C);
277
278         if (scene != NULL && RNA_boolean_get(&ptr, "init_scene_frame_range")) {
279                 RNA_int_set(&ptr, "start", SFRA);
280                 RNA_int_set(&ptr, "end", EFRA);
281
282                 RNA_boolean_set(&ptr, "init_scene_frame_range", false);
283         }
284
285         ui_alembic_export_settings(op->layout, &ptr);
286 }
287
288 static bool wm_alembic_export_check(bContext *UNUSED(C), wmOperator *op)
289 {
290         char filepath[FILE_MAX];
291         RNA_string_get(op->ptr, "filepath", filepath);
292
293         if (!BLI_path_extension_check(filepath, ".abc")) {
294                 BLI_path_extension_ensure(filepath, FILE_MAX, ".abc");
295                 RNA_string_set(op->ptr, "filepath", filepath);
296                 return true;
297         }
298
299         return false;
300 }
301
302 void WM_OT_alembic_export(wmOperatorType *ot)
303 {
304         ot->name = "Export Alembic";
305         ot->description = "Export current scene in an Alembic archive";
306         ot->idname = "WM_OT_alembic_export";
307
308         ot->invoke = wm_alembic_export_invoke;
309         ot->exec = wm_alembic_export_exec;
310         ot->poll = WM_operator_winactive;
311         ot->ui = wm_alembic_export_draw;
312         ot->check = wm_alembic_export_check;
313
314         WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_ALEMBIC,
315                                        FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH,
316                                        FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
317
318         RNA_def_int(ot->srna, "start", INT_MIN, INT_MIN, INT_MAX,
319                     "Start Frame",
320                     "Start frame of the export, use the default value to "
321                     "take the start frame of the current scene",
322                     INT_MIN, INT_MAX);
323
324         RNA_def_int(ot->srna, "end", INT_MIN, INT_MIN, INT_MAX,
325                     "End Frame",
326                     "End frame of the export, use the default value to "
327                     "take the end frame of the current scene",
328                     INT_MIN, INT_MAX);
329
330         RNA_def_int(ot->srna, "xsamples", 1, 1, 128,
331                     "Transform Samples", "Number of times per frame transformations are sampled", 1, 128);
332
333         RNA_def_int(ot->srna, "gsamples", 1, 1, 128,
334                     "Geometry Samples", "Number of times per frame object data are sampled", 1, 128);
335
336         RNA_def_float(ot->srna, "sh_open", 0.0f, -1.0f, 1.0f,
337                       "Shutter Open", "Time at which the shutter is open", -1.0f, 1.0f);
338
339         RNA_def_float(ot->srna, "sh_close", 1.0f, -1.0f, 1.0f,
340                       "Shutter Close", "Time at which the shutter is closed", -1.0f, 1.0f);
341
342         RNA_def_boolean(ot->srna, "selected", 0,
343                         "Selected Objects Only", "Export only selected objects");
344
345         RNA_def_boolean(ot->srna, "renderable_only", 1,
346                         "Renderable Objects Only",
347                         "Export only objects marked renderable in the outliner");
348
349         RNA_def_boolean(ot->srna, "visible_layers_only", 0,
350                         "Visible Layers Only", "Export only objects in visible layers");
351
352         RNA_def_boolean(ot->srna, "flatten", 0,
353                         "Flatten Hierarchy",
354                         "Do not preserve objects' parent/children relationship");
355
356         RNA_def_boolean(ot->srna, "uvs", 1, "UVs", "Export UVs");
357
358         RNA_def_boolean(ot->srna, "packuv", 1, "Pack UV Islands",
359                         "Export UVs with packed island");
360
361         RNA_def_boolean(ot->srna, "normals", 1, "Normals", "Export normals");
362
363         RNA_def_boolean(ot->srna, "vcolors", 0, "Vertex Colors", "Export vertex colors");
364
365         RNA_def_boolean(ot->srna, "face_sets", 0, "Face Sets", "Export per face shading group assignments");
366
367         RNA_def_boolean(ot->srna, "subdiv_schema", 0,
368                         "Use Subdivision Schema",
369                         "Export meshes using Alembic's subdivision schema");
370
371         RNA_def_boolean(ot->srna, "apply_subdiv", 0,
372                         "Apply Subsurf", "Export subdivision surfaces as meshes");
373
374         RNA_def_boolean(ot->srna, "curves_as_mesh", false,
375                         "Curves as Mesh", "Export curves and NURBS surfaces as meshes");
376
377         RNA_def_enum(ot->srna, "compression_type", rna_enum_abc_compression_items,
378                      ABC_ARCHIVE_OGAWA, "Compression", "");
379
380         RNA_def_float(ot->srna, "global_scale", 1.0f, 0.0001f, 1000.0f, "Scale",
381                       "Value by which to enlarge or shrink the objects with respect to the world's origin",
382                       0.0001f, 1000.0f);
383
384         RNA_def_boolean(ot->srna, "triangulate", false, "Triangulate",
385                         "Export Polygons (Quads & NGons) as Triangles");
386
387         RNA_def_enum(ot->srna, "quad_method", rna_enum_modifier_triangulate_quad_method_items,
388                      MOD_TRIANGULATE_QUAD_SHORTEDGE, "Quad Method", "Method for splitting the quads into triangles");
389
390         RNA_def_enum(ot->srna, "ngon_method", rna_enum_modifier_triangulate_quad_method_items,
391                      MOD_TRIANGULATE_NGON_BEAUTY, "Polygon Method", "Method for splitting the polygons into triangles");
392
393         RNA_def_boolean(ot->srna, "export_hair", 1, "Export Hair", "Exports hair particle systems as animated curves");
394         RNA_def_boolean(ot->srna, "export_particles", 1, "Export Particles", "Exports non-hair particle systems");
395
396         RNA_def_boolean(ot->srna, "as_background_job", false, "Run as Background Job",
397                         "Enable this to run the import in the background, disable to block Blender while importing. "
398                         "This option is deprecated; EXECUTE this operator to run in the foreground, and INVOKE it "
399                         "to run as a background job");
400
401         /* This dummy prop is used to check whether we need to init the start and
402          * end frame values to that of the scene's, otherwise they are reset at
403          * every change, draw update. */
404         RNA_def_boolean(ot->srna, "init_scene_frame_range", false, "", "");
405 }
406
407 /* ************************************************************************** */
408
409 /* TODO(kevin): check on de-duplicating all this with code in image_ops.c */
410
411 typedef struct CacheFrame {
412         struct CacheFrame *next, *prev;
413         int framenr;
414 } CacheFrame;
415
416 static int cmp_frame(const void *a, const void *b)
417 {
418         const CacheFrame *frame_a = a;
419         const CacheFrame *frame_b = b;
420
421         if (frame_a->framenr < frame_b->framenr) return -1;
422         if (frame_a->framenr > frame_b->framenr) return 1;
423         return 0;
424 }
425
426 static int get_sequence_len(char *filename, int *ofs)
427 {
428         int frame;
429         int numdigit;
430
431         if (!BLI_path_frame_get(filename, &frame, &numdigit)) {
432                 return 1;
433         }
434
435         char path[FILE_MAX];
436         BLI_path_abs(filename, BKE_main_blendfile_path_from_global());
437         BLI_split_dir_part(filename, path, FILE_MAX);
438
439         if (path[0] == '\0') {
440                 /* The filename had no path, so just use the blend file path. */
441                 BLI_split_dir_part(BKE_main_blendfile_path_from_global(), path, FILE_MAX);
442         }
443
444         DIR *dir = opendir(path);
445         if (dir == NULL) {
446                 fprintf(stderr, "Error opening directory '%s': %s\n",
447                         path, errno ? strerror(errno) : "unknown error");
448                 return -1;
449         }
450
451         const char *ext = ".abc";
452         const char *basename = BLI_path_basename(filename);
453         const int len = strlen(basename) - (numdigit + strlen(ext));
454
455         ListBase frames;
456         BLI_listbase_clear(&frames);
457
458         struct dirent *fname;
459         while ((fname = readdir(dir)) != NULL) {
460                 /* do we have the right extension? */
461                 if (!strstr(fname->d_name, ext)) {
462                         continue;
463                 }
464
465                 if (!STREQLEN(basename, fname->d_name, len)) {
466                         continue;
467                 }
468
469                 CacheFrame *cache_frame = MEM_callocN(sizeof(CacheFrame), "abc_frame");
470
471                 BLI_path_frame_get(fname->d_name, &cache_frame->framenr, &numdigit);
472
473                 BLI_addtail(&frames, cache_frame);
474         }
475
476         closedir(dir);
477
478         BLI_listbase_sort(&frames, cmp_frame);
479
480         CacheFrame *cache_frame = frames.first;
481
482         if (cache_frame) {
483                 int frame_curr = cache_frame->framenr;
484                 (*ofs) = frame_curr;
485
486                 while (cache_frame && (cache_frame->framenr == frame_curr)) {
487                         ++frame_curr;
488                         cache_frame = cache_frame->next;
489                 }
490
491                 BLI_freelistN(&frames);
492
493                 return frame_curr - (*ofs);
494         }
495
496         return 1;
497 }
498
499 /* ************************************************************************** */
500
501 static void ui_alembic_import_settings(uiLayout *layout, PointerRNA *imfptr)
502 {
503         uiLayout *box = uiLayoutBox(layout);
504         uiLayout *row = uiLayoutRow(box, false);
505         uiItemL(row, IFACE_("Manual Transform:"), ICON_NONE);
506
507         row = uiLayoutRow(box, false);
508         uiItemR(row, imfptr, "scale", 0, NULL, ICON_NONE);
509
510         box = uiLayoutBox(layout);
511         row = uiLayoutRow(box, false);
512         uiItemL(row, IFACE_("Options:"), ICON_NONE);
513
514         row = uiLayoutRow(box, false);
515         uiItemR(row, imfptr, "set_frame_range", 0, NULL, ICON_NONE);
516
517         row = uiLayoutRow(box, false);
518         uiItemR(row, imfptr, "is_sequence", 0, NULL, ICON_NONE);
519
520         row = uiLayoutRow(box, false);
521         uiItemR(row, imfptr, "validate_meshes", 0, NULL, ICON_NONE);
522 }
523
524 static void wm_alembic_import_draw(bContext *UNUSED(C), wmOperator *op)
525 {
526         PointerRNA ptr;
527
528         RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
529         ui_alembic_import_settings(op->layout, &ptr);
530 }
531
532
533 /* op->invoke, opens fileselect if path property not set, otherwise executes */
534 static int wm_alembic_import_invoke(bContext *C, wmOperator *op, const wmEvent *event)
535 {
536         if (!RNA_struct_property_is_set(op->ptr, "as_background_job")) {
537                 RNA_boolean_set(op->ptr, "as_background_job", true);
538         }
539         return WM_operator_filesel(C, op, event);
540 }
541
542
543 static int wm_alembic_import_exec(bContext *C, wmOperator *op)
544 {
545         if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
546                 BKE_report(op->reports, RPT_ERROR, "No filename given");
547                 return OPERATOR_CANCELLED;
548         }
549
550         char filename[FILE_MAX];
551         RNA_string_get(op->ptr, "filepath", filename);
552
553         const float scale = RNA_float_get(op->ptr, "scale");
554         const bool is_sequence = RNA_boolean_get(op->ptr, "is_sequence");
555         const bool set_frame_range = RNA_boolean_get(op->ptr, "set_frame_range");
556         const bool validate_meshes = RNA_boolean_get(op->ptr, "validate_meshes");
557         const bool as_background_job = RNA_boolean_get(op->ptr, "as_background_job");
558
559         int offset = 0;
560         int sequence_len = 1;
561
562         if (is_sequence) {
563                 sequence_len = get_sequence_len(filename, &offset);
564                 if (sequence_len < 0) {
565                         BKE_report(op->reports, RPT_ERROR, "Unable to determine ABC sequence length");
566                         return OPERATOR_CANCELLED;
567                 }
568         }
569
570         /* Switch out of edit mode to avoid being stuck in it (T54326). */
571         Object *obedit = CTX_data_edit_object(C);
572         if (obedit) {
573                 ED_object_mode_toggle(C, OB_MODE_EDIT);
574         }
575
576         bool ok = ABC_import(C, filename, scale, is_sequence, set_frame_range,
577                              sequence_len, offset, validate_meshes,
578                              as_background_job);
579
580         return as_background_job || ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
581 }
582
583 void WM_OT_alembic_import(wmOperatorType *ot)
584 {
585         ot->name = "Import Alembic";
586         ot->description = "Load an Alembic archive";
587         ot->idname = "WM_OT_alembic_import";
588
589         ot->invoke = wm_alembic_import_invoke;
590         ot->exec = wm_alembic_import_exec;
591         ot->poll = WM_operator_winactive;
592         ot->ui = wm_alembic_import_draw;
593
594         WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_ALEMBIC,
595                                        FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH,
596                                        FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
597
598         RNA_def_float(ot->srna, "scale", 1.0f, 0.0001f, 1000.0f, "Scale",
599                       "Value by which to enlarge or shrink the objects with respect to the world's origin",
600                       0.0001f, 1000.0f);
601
602         RNA_def_boolean(ot->srna, "set_frame_range", true,
603                         "Set Frame Range",
604                         "If checked, update scene's start and end frame to match those of the Alembic archive");
605
606         RNA_def_boolean(ot->srna, "validate_meshes", 0,
607                         "Validate Meshes", "Check imported mesh objects for invalid data (slow)");
608
609         RNA_def_boolean(ot->srna, "is_sequence", false, "Is Sequence",
610                         "Set to true if the cache is split into separate files");
611
612         RNA_def_boolean(ot->srna, "as_background_job", false, "Run as Background Job",
613                         "Enable this to run the export in the background, disable to block Blender while exporting. "
614                         "This option is deprecated; EXECUTE this operator to run in the foreground, and INVOKE it "
615                         "to run as a background job");
616 }
617
618 #endif