Alembic export: made hair/particle export optional.
[blender.git] / source / blender / editors / io / io_alembic.c
index 7a7c42e501bba7207c74547a3adab62aa5668242..8651d89c403d2b0d0453afcecb52a38182daff52 100644 (file)
@@ -34,6 +34,7 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_mesh_types.h"
+#include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_space_types.h"
 
 static int wm_alembic_export_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
+       RNA_boolean_set(op->ptr, "init_scene_frame_range", true);
+
        if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
+               Main *bmain = CTX_data_main(C);
                char filepath[FILE_MAX];
-               BLI_strncpy(filepath, G.main->name, sizeof(filepath));
+
+               if (bmain->name[0] == '\0') {
+                       BLI_strncpy(filepath, "untitled", sizeof(filepath));
+               }
+               else {
+                       BLI_strncpy(filepath, bmain->name, sizeof(filepath));
+               }
+
                BLI_replace_extension(filepath, sizeof(filepath), ".abc");
                RNA_string_set(op->ptr, "filepath", filepath);
        }
@@ -111,8 +122,13 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
            .renderable_only = RNA_boolean_get(op->ptr, "renderable_only"),
            .face_sets = RNA_boolean_get(op->ptr, "face_sets"),
            .use_subdiv_schema = RNA_boolean_get(op->ptr, "subdiv_schema"),
+           .export_hair = RNA_boolean_get(op->ptr, "export_hair"),
+           .export_particles = RNA_boolean_get(op->ptr, "export_particles"),
            .compression_type = RNA_enum_get(op->ptr, "compression_type"),
            .packuv = RNA_boolean_get(op->ptr, "packuv"),
+           .triangulate = RNA_boolean_get(op->ptr, "triangulate"),
+           .quad_method = RNA_enum_get(op->ptr, "quad_method"),
+           .ngon_method = RNA_enum_get(op->ptr, "ngon_method"),
 
            .global_scale = RNA_float_get(op->ptr, "global_scale"),
        };
@@ -124,10 +140,12 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
 
 static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr)
 {
-       uiLayout *box = uiLayoutBox(layout);
+       uiLayout *box;
        uiLayout *row;
+       uiLayout *col;
 
 #ifdef WITH_ALEMBIC_HDF5
+       box = uiLayoutBox(layout);
        row = uiLayoutRow(box, false);
        uiItemL(row, IFACE_("Archive Options:"), ICON_NONE);
 
@@ -203,25 +221,74 @@ static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr)
 
        row = uiLayoutRow(box, false);
        uiItemR(row, imfptr, "apply_subdiv", 0, NULL, ICON_NONE);
+
+       row = uiLayoutRow(box, false);
+       uiItemR(row, imfptr, "triangulate", 0, NULL, ICON_NONE);
+
+       const bool triangulate = RNA_boolean_get(imfptr, "triangulate");
+
+       row = uiLayoutRow(box, false);
+       uiLayoutSetEnabled(row, triangulate);
+       uiItemR(row, imfptr, "quad_method", 0, NULL, ICON_NONE);
+
+       row = uiLayoutRow(box, false);
+       uiLayoutSetEnabled(row, triangulate);
+       uiItemR(row, imfptr, "ngon_method", 0, NULL, ICON_NONE);
+
+       /* Object Data */
+       box = uiLayoutBox(layout);
+       row = uiLayoutRow(box, false);
+       uiItemL(row, IFACE_("Particle Systems:"), ICON_PARTICLE_DATA);
+
+       col = uiLayoutColumn(box, true);
+       uiItemR(col, imfptr, "export_hair", 0, NULL, ICON_NONE);
+       uiItemR(col, imfptr, "export_particles", 0, NULL, ICON_NONE);
 }
 
-static void wm_alembic_export_draw(bContext *UNUSED(C), wmOperator *op)
+static void wm_alembic_export_draw(bContext *C, wmOperator *op)
 {
        PointerRNA ptr;
 
        RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
+
+       /* Conveniently set start and end frame to match the scene's frame range. */
+       Scene *scene = CTX_data_scene(C);
+
+       if (scene != NULL && RNA_boolean_get(&ptr, "init_scene_frame_range")) {
+               RNA_int_set(&ptr, "start", SFRA);
+               RNA_int_set(&ptr, "end", EFRA);
+
+               RNA_boolean_set(&ptr, "init_scene_frame_range", false);
+       }
+
        ui_alembic_export_settings(op->layout, &ptr);
 }
 
+static bool wm_alembic_export_check(bContext *UNUSED(C), wmOperator *op)
+{
+       char filepath[FILE_MAX];
+       RNA_string_get(op->ptr, "filepath", filepath);
+
+       if (!BLI_testextensie(filepath, ".abc")) {
+               BLI_ensure_extension(filepath, FILE_MAX, ".abc");
+               RNA_string_set(op->ptr, "filepath", filepath);
+               return true;
+       }
+
+       return false;
+}
+
 void WM_OT_alembic_export(wmOperatorType *ot)
 {
-       ot->name = "Export Alembic Archive";
+       ot->name = "Export Alembic";
+       ot->description = "Export current scene in an Alembic archive";
        ot->idname = "WM_OT_alembic_export";
 
        ot->invoke = wm_alembic_export_invoke;
        ot->exec = wm_alembic_export_exec;
        ot->poll = WM_operator_winactive;
        ot->ui = wm_alembic_export_draw;
+       ot->check = wm_alembic_export_check;
 
        WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_ALEMBIC,
                                       FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH,
@@ -237,7 +304,7 @@ void WM_OT_alembic_export(wmOperatorType *ot)
                    "Transform Samples", "Number of times per frame transformations are sampled", 1, 128);
 
        RNA_def_int(ot->srna, "gsamples", 1, 1, 128,
-                   "Geometry Samples", "Number of times per frame object datas are sampled", 1, 128);
+                   "Geometry Samples", "Number of times per frame object data are sampled", 1, 128);
 
        RNA_def_float(ot->srna, "sh_open", 0.0f, -1.0f, 1.0f,
                      "Shutter Open", "Time at which the shutter is open", -1.0f, 1.0f);
@@ -266,7 +333,7 @@ void WM_OT_alembic_export(wmOperatorType *ot)
 
        RNA_def_boolean(ot->srna, "normals", 1, "Normals", "Export normals");
 
-       RNA_def_boolean(ot->srna, "vcolors", 0, "Vertex colors", "Export vertex colors");
+       RNA_def_boolean(ot->srna, "vcolors", 0, "Vertex Colors", "Export vertex colors");
 
        RNA_def_boolean(ot->srna, "face_sets", 0, "Face Sets", "Export per face shading group assignments");
 
@@ -283,6 +350,23 @@ void WM_OT_alembic_export(wmOperatorType *ot)
        RNA_def_float(ot->srna, "global_scale", 1.0f, 0.0001f, 1000.0f, "Scale",
                      "Value by which to enlarge or shrink the objects with respect to the world's origin",
                      0.0001f, 1000.0f);
+
+       RNA_def_boolean(ot->srna, "triangulate", false, "Triangulate",
+                       "Export Polygons (Quads & NGons) as Triangles");
+
+       RNA_def_enum(ot->srna, "quad_method", rna_enum_modifier_triangulate_quad_method_items,
+                    MOD_TRIANGULATE_QUAD_SHORTEDGE, "Quad Method", "Method for splitting the quads into triangles");
+
+       RNA_def_enum(ot->srna, "ngon_method", rna_enum_modifier_triangulate_quad_method_items,
+                    MOD_TRIANGULATE_NGON_BEAUTY, "Polygon Method", "Method for splitting the polygons into triangles");
+
+       RNA_def_boolean(ot->srna, "export_hair", 1, "Export Hair", "Exports hair particle systems as animated curves");
+       RNA_def_boolean(ot->srna, "export_particles", 1, "Export Particles", "Exports non-hair particle systems");
+
+       /* This dummy prop is used to check whether we need to init the start and
+     * end frame values to that of the scene's, otherwise they are reset at
+     * every change, draw update. */
+       RNA_def_boolean(ot->srna, "init_scene_frame_range", false, "", "");
 }
 
 /* ************************************************************************** */
@@ -428,7 +512,8 @@ static int wm_alembic_import_exec(bContext *C, wmOperator *op)
 
 void WM_OT_alembic_import(wmOperatorType *ot)
 {
-       ot->name = "Import Alembic Archive";
+       ot->name = "Import Alembic";
+       ot->description = "Load an Alembic archive";
        ot->idname = "WM_OT_alembic_import";
 
        ot->invoke = WM_operator_filesel;