Commit: e8483f9bd721f93ec8c21fb339a518096042537d
Author: Sybren A. Stüvel
Date:   Tue Aug 4 15:23:36 2020 +0200
Branches: blender-v2.90-release
https://developer.blender.org/rBe8483f9bd721f93ec8c21fb339a518096042537d

Fix T78758 Alembic export: crash when file is in use by another application

In cases when the output file cannot be opened, an exception is thrown that
was not caught.

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

M       source/blender/io/alembic/exporter/abc_export_capi.cc

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

diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc 
b/source/blender/io/alembic/exporter/abc_export_capi.cc
index 98c551c635c..8c5f3d89870 100644
--- a/source/blender/io/alembic/exporter/abc_export_capi.cc
+++ b/source/blender/io/alembic/exporter/abc_export_capi.cc
@@ -48,6 +48,7 @@
 static CLG_LogRef LOG = {"io.alembic"};
 
 #include <algorithm>
+#include <memory>
 
 struct ExportJobData {
   Main *bmain;
@@ -103,17 +104,41 @@ static void export_startjob(void *customdata,
   const bool export_animation = (data->params.frame_start != 
data->params.frame_end);
 
   // Create the Alembic archive.
-  ABCArchive abc_archive(data->bmain, scene, data->params, 
std::string(data->filename));
+  std::unique_ptr<ABCArchive> abc_archive;
+  try {
+    abc_archive = std::make_unique<ABCArchive>(
+        data->bmain, scene, data->params, std::string(data->filename));
+  }
+  catch (const std::exception &ex) {
+    std::stringstream error_message_stream;
+    error_message_stream << "Error writing to " << data->filename;
+    const std::string &error_message = error_message_stream.str();
+
+    // The exception message can be very cryptic (just "iostream error" on 
Linux, for example), so
+    // better not to include it in the report.
+    CLOG_ERROR(&LOG, "%s: %s", error_message.c_str(), ex.what());
+    WM_report(RPT_ERROR, error_message.c_str());
+    data->export_ok = false;
+    return;
+  }
+  catch (...) {
+    // Unknown exception class, so we cannot include its message.
+    std::stringstream error_message_stream;
+    error_message_stream << "Unknown error writing to " << data->filename;
+    WM_report(RPT_ERROR, error_message_stream.str().c_str());
+    data->export_ok = false;
+    return;
+  }
 
-  ABCHierarchyIterator iter(data->depsgraph, &abc_archive, data->params);
+  ABCHierarchyIterator iter(data->depsgraph, abc_archive.get(), data->params);
 
   if (export_animation) {
     CLOG_INFO(&LOG, 2, "Exporting animation");
 
     // Writing the animated frames is not 100% of the work, but it's our best 
guess.
-    const float progress_per_frame = 1.0f / std::max(size_t(1), 
abc_archive.total_frame_count());
-    ABCArchive::Frames::const_iterator frame_it = abc_archive.frames_begin();
-    const ABCArchive::Frames::const_iterator frames_end = 
abc_archive.frames_end();
+    const float progress_per_frame = 1.0f / std::max(size_t(1), 
abc_archive->total_frame_count());
+    ABCArchive::Frames::const_iterator frame_it = abc_archive->frames_begin();
+    const ABCArchive::Frames::const_iterator frames_end = 
abc_archive->frames_end();
 
     for (; frame_it != frames_end; frame_it++) {
       double frame = *frame_it;
@@ -128,7 +153,7 @@ static void export_startjob(void *customdata,
       BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain);
 
       CLOG_INFO(&LOG, 2, "Exporting frame %.2f", frame);
-      ExportSubset export_subset = abc_archive.export_subset_for_frame(frame);
+      ExportSubset export_subset = abc_archive->export_subset_for_frame(frame);
       iter.set_export_subset(export_subset);
       iter.iterate_and_write();

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to