[Bf-blender-cvs] [6d088bdde46] soc-2020-io-performance: Export multiple frames to separate files.

Ankit Meel noreply at git.blender.org
Mon Jun 15 10:13:34 CEST 2020


Commit: 6d088bdde46ade408a0d122e4bff786b99995bbd
Author: Ankit Meel
Date:   Mon Jun 15 13:34:44 2020 +0530
Branches: soc-2020-io-performance
https://developer.blender.org/rB6d088bdde46ade408a0d122e4bff786b99995bbd

Export multiple frames to separate files.

Frame 20 with mentioned filename `name` is exported to `name020.obj`
It should be modified to exclude cases when a single frame is being
exported to avoid overwriting what the user intended to name it.

Also a filter is added to include only OB_MESH type objects for export.

The limits on frames can be changed, the current limits are like this:
Let's say unknowingly, the user selects the maximum 1000 frames & every
file is 1 MB in size. That will quickly fill up 1 GB on the disk.
More frames add to this risk.

===================================================================

M	source/blender/editors/io/io_obj.c
M	source/blender/io/wavefront_obj/IO_wavefront_obj.h
M	source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc

===================================================================

diff --git a/source/blender/editors/io/io_obj.c b/source/blender/editors/io/io_obj.c
index 57569ca7e87..7fcc78161c6 100644
--- a/source/blender/editors/io/io_obj.c
+++ b/source/blender/editors/io/io_obj.c
@@ -72,6 +72,26 @@ static int wm_obj_export_invoke(bContext *C, wmOperator *op, const wmEvent *even
 
   UNUSED_VARS(event);
 }
+
+static bool wm_obj_export_check(bContext *UNUSED(C), wmOperator *op)
+{
+  char filepath[FILE_MAX];
+  RNA_string_get(op->ptr, "filepath", filepath);
+
+  if (!BLI_path_extension_check(filepath, ".obj")) {
+    BLI_path_extension_ensure(filepath, FILE_MAX, ".obj");
+    RNA_string_set(op->ptr, "filepath", filepath);
+    return true;
+  }
+
+  /* End frame should be greater than or equal to start frame. */
+  if (RNA_int_get(op->ptr, "start_frame") > RNA_int_get(op->ptr, "end_frame")) {
+    RNA_int_set(op->ptr, "end_frame", RNA_int_get(op->ptr, "start_frame"));
+    return true;
+  }
+  return false;
+}
+
 static int wm_obj_export_exec(bContext *C, wmOperator *op)
 {
   if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
@@ -80,6 +100,8 @@ static int wm_obj_export_exec(bContext *C, wmOperator *op)
   }
   struct OBJExportParams export_params;
   RNA_string_get(op->ptr, "filepath", export_params.filepath);
+  export_params.start_frame = RNA_int_get(op->ptr, "start_frame");
+  export_params.end_frame = RNA_int_get(op->ptr, "end_frame");
   OBJ_export(C, &export_params);
 
   return OPERATOR_FINISHED;
@@ -92,13 +114,13 @@ static void ui_obj_export_settings(uiLayout *layout, PointerRNA *imfptr)
 
   box = uiLayoutBox(layout);
   row = uiLayoutRow(box, false);
-  uiItemL(row, IFACE_("Some Options"), ICON_NONE);
+  uiItemL(row, IFACE_("Animation "), ICON_NONE);
 
   row = uiLayoutRow(box, false);
-  uiItemR(row, imfptr, "dummy_checkbox", 0, NULL, ICON_NONE);
+  uiItemR(row, imfptr, "start_frame", 0, NULL, ICON_NONE);
 
   row = uiLayoutRow(box, false);
-  uiItemR(row, imfptr, "dummy_slider", 0, NULL, ICON_NONE);
+  uiItemR(row, imfptr, "end_frame", 0, NULL, ICON_NONE);
 }
 
 static void wm_obj_export_draw(bContext *UNUSED(C), wmOperator *op)
@@ -118,6 +140,7 @@ void WM_OT_obj_export(struct wmOperatorType *ot)
   ot->exec = wm_obj_export_exec;
   ot->poll = WM_operator_winactive;
   ot->ui = wm_obj_export_draw;
+  ot->check = wm_obj_export_check;
 
   WM_operator_properties_filesel(ot,
                                  FILE_TYPE_FOLDER | FILE_TYPE_OBJECT_IO,
@@ -127,8 +150,17 @@ void WM_OT_obj_export(struct wmOperatorType *ot)
                                  FILE_DEFAULTDISPLAY,
                                  FILE_SORT_ALPHA);
 
-  RNA_def_boolean(ot->srna, "dummy_checkbox", 0, "Dummy Checkbox", "");
-  RNA_def_float(ot->srna, "dummy_slider", 4.56, 0.0f, 10.0f, "Dummy Slider", "", 1.0f, 9.0f);
+  RNA_def_int(ot->srna,
+              "start_frame",
+              1,
+              0,
+              1000,
+              "Start Frame",
+              "The first frame to be exported",
+              0,
+              250);
+  RNA_def_int(
+      ot->srna, "end_frame", 1, 0, 1000, "End Frame", "The last frame to be exported", 0, 250);
 }
 
 static int wm_obj_import_invoke(bContext *C, wmOperator *op, const wmEvent *event)
diff --git a/source/blender/io/wavefront_obj/IO_wavefront_obj.h b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
index 6af50635565..a31f2e73395 100644
--- a/source/blender/io/wavefront_obj/IO_wavefront_obj.h
+++ b/source/blender/io/wavefront_obj/IO_wavefront_obj.h
@@ -31,7 +31,10 @@ extern "C" {
 struct OBJExportParams {
   /** Full path to the destination OBJ file to export. */
   char filepath[FILENAME_MAX];
-  /* Preferences will be added here when there is an actual setting to use. */
+  /** The first frame to be exported. */
+  short start_frame;
+  /** The last frame to be exported. */
+  short end_frame;
 };
 
 struct OBJImportParams {
diff --git a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
index 56d7a060135..63b0d8d61b2 100644
--- a/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
+++ b/source/blender/io/wavefront_obj/intern/wavefront_obj_exporter.cc
@@ -32,12 +32,14 @@
 #include "BKE_scene.h"
 
 #include "BLI_math.h"
+#include "BLI_path_util.h"
 #include "BLI_vector.hh"
 
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_query.h"
 
 #include "DNA_layer_types.h"
+#include "DNA_scene_types.h"
 
 #include "IO_wavefront_obj.h"
 
@@ -48,22 +50,6 @@
 namespace io {
 namespace obj {
 
-/**
- * Check object type to filter only exportable types.
- */
-static void check_object_type(Object *object, std::vector<OBJ_object_to_export> &objects_to_export)
-{
-  switch (object->type) {
-    case OB_MESH:
-      objects_to_export.push_back(OBJ_object_to_export());
-      objects_to_export.back().object = object;
-      break;
-      /* Do nothing for all other cases for now. */
-    default:
-      break;
-  }
-}
-
 /**
  * Store the mesh vertex coordinates in object_to_export, in world coordinates.
  */
@@ -124,6 +110,7 @@ static void get_polygon_vert_indices(Mesh *me_eval, OBJ_object_to_export &object
     }
   }
 }
+
 /**
  * Store UV vertex coordinates in object_to_export.uv_coords as well as their indices, in
  * a polygon[i].uv_vertex_index.
@@ -196,11 +183,26 @@ static void get_geometry_per_object(const OBJExportParams *export_params,
 }
 
 /**
- * Central internal function to call geometry data preparation & writer functions.
+ * Check object type to filter only exportable objects.
  */
-void exporter_main(bContext *C, const OBJExportParams *export_params)
+static void check_object_type(Object *object, std::vector<OBJ_object_to_export> &objects_to_export)
+{
+  switch (object->type) {
+    case OB_MESH:
+      objects_to_export.push_back(OBJ_object_to_export());
+      objects_to_export.back().object = object;
+      break;
+      /* Do nothing for all other cases for now. */
+    default:
+      break;
+  }
+}
+
+/**
+ * Exports a single frame to a single file in an animation.
+ */
+static void export_frame(bContext *C, const OBJExportParams *export_params, const char *filepath)
 {
-  const char *filepath = export_params->filepath;
   std::vector<OBJ_object_to_export> exportable_objects;
 
   ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -225,5 +227,38 @@ void exporter_main(bContext *C, const OBJExportParams *export_params)
     MEM_freeN(exportable_objects[i].mvert);
   }
 }
+
+/**
+ * Central internal function to call Scene update & writer functions.
+ */
+void exporter_main(bContext *C, const OBJExportParams *export_params)
+{
+  Scene *scene = CTX_data_scene(C);
+  const char *filepath = export_params->filepath;
+  short start_frame = export_params->start_frame;
+  short end_frame = export_params->end_frame;
+  char filepath_with_frames[FILE_MAX];
+
+  /* To reset the Scene to its original state. */
+  int original_frame = CFRA;
+
+  for (short frame = start_frame; frame <= end_frame; frame++) {
+    BLI_strncpy(filepath_with_frames, filepath, FILE_MAX);
+    /* 0 + 4 digits for frame number + 4 for extension + 1 null. */
+    char frame_ext[10];
+    BLI_snprintf(frame_ext, 10, "0%hd.obj", frame);
+    bool filepath_ok = BLI_path_extension_replace(filepath_with_frames, FILE_MAX, frame_ext);
+    if (filepath_ok == false) {
+      printf("Error: File Path too long.");
+      return;
+    }
+
+    CFRA = frame;
+    BKE_scene_graph_update_for_newframe(CTX_data_ensure_evaluated_depsgraph(C), CTX_data_main(C));
+    printf("Writing %s\n", filepath_with_frames);
+    export_frame(C, export_params, filepath_with_frames);
+  }
+  CFRA = original_frame;
+}
 }  // namespace obj
 }  // namespace io



More information about the Bf-blender-cvs mailing list