Fix #145259: Grease Pencil: Bail when no frame is selected for SVG export
Previously `SVGExporter::export_scene` can work on a empty `frames` index mask, causing crash. Now it will exit early when no frames are selected, and it will show a warning to the user. Pull Request: https://projects.blender.org/blender/blender/pulls/145286
This commit is contained in:
@@ -295,6 +295,7 @@ static wmOperatorStatus grease_pencil_export_svg_invoke(bContext *C,
|
||||
static wmOperatorStatus grease_pencil_export_svg_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
using blender::io::grease_pencil::ExportParams;
|
||||
using blender::io::grease_pencil::ExportStatus;
|
||||
using blender::io::grease_pencil::IOContext;
|
||||
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
@@ -337,11 +338,25 @@ static wmOperatorStatus grease_pencil_export_svg_exec(bContext *C, wmOperator *o
|
||||
stroke_sample};
|
||||
|
||||
WM_cursor_wait(true);
|
||||
const bool done = blender::io::grease_pencil::export_svg(io_context, params, *scene, filepath);
|
||||
ExportStatus status = blender::io::grease_pencil::export_svg(
|
||||
io_context, params, *scene, filepath);
|
||||
WM_cursor_wait(false);
|
||||
|
||||
if (!done) {
|
||||
BKE_report(op->reports, RPT_WARNING, "Unable to export SVG");
|
||||
switch (status) {
|
||||
case ExportStatus::Ok:
|
||||
break;
|
||||
case ExportStatus::InvalidActiveObjectType:
|
||||
BKE_report(op->reports, RPT_WARNING, "Active object is not a Grease Pencil object");
|
||||
break;
|
||||
case ExportStatus::NoFramesSelected:
|
||||
BKE_report(op->reports, RPT_WARNING, "No frames selected in the Grease Pencil object");
|
||||
break;
|
||||
case ExportStatus::FileWriteError:
|
||||
BKE_reportf(op->reports, RPT_WARNING, "Error during file write for \"%s\"", filepath);
|
||||
break;
|
||||
case ExportStatus::UnknownError:
|
||||
BLI_assert_unreachable();
|
||||
break;
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
@@ -45,6 +45,14 @@ struct ImportParams {
|
||||
bool recenter_bounds = false;
|
||||
};
|
||||
|
||||
enum class ExportStatus : int8_t {
|
||||
Ok = 0,
|
||||
NoFramesSelected,
|
||||
InvalidActiveObjectType,
|
||||
FileWriteError,
|
||||
UnknownError,
|
||||
};
|
||||
|
||||
struct ExportParams {
|
||||
/* Object to be exported. */
|
||||
enum class SelectMode {
|
||||
@@ -74,10 +82,10 @@ struct ExportParams {
|
||||
};
|
||||
|
||||
bool import_svg(const IOContext &context, const ImportParams ¶ms, StringRefNull filepath);
|
||||
bool export_svg(const IOContext &context,
|
||||
const ExportParams ¶ms,
|
||||
Scene &scene,
|
||||
StringRefNull filepath);
|
||||
ExportStatus export_svg(const IOContext &context,
|
||||
const ExportParams ¶ms,
|
||||
Scene &scene,
|
||||
StringRefNull filepath);
|
||||
bool export_pdf(const IOContext &context,
|
||||
const ExportParams ¶ms,
|
||||
Scene &scene,
|
||||
|
||||
@@ -106,7 +106,7 @@ class SVGExporter : public GreasePencilExporter {
|
||||
|
||||
pugi::xml_document main_doc_;
|
||||
|
||||
bool export_scene(Scene &scene, StringRefNull filepath);
|
||||
ExportStatus export_scene(Scene &scene, StringRefNull filepath);
|
||||
void export_grease_pencil_objects(pugi::xml_node node, int frame_number);
|
||||
void export_grease_pencil_layer(pugi::xml_node node,
|
||||
const Object &object,
|
||||
@@ -146,7 +146,7 @@ std::string SVGExporter::get_node_uuid_string()
|
||||
return id;
|
||||
}
|
||||
|
||||
bool SVGExporter::export_scene(Scene &scene, StringRefNull filepath)
|
||||
ExportStatus SVGExporter::export_scene(Scene &scene, StringRefNull filepath)
|
||||
{
|
||||
this->_node_uuid = 0;
|
||||
|
||||
@@ -160,7 +160,8 @@ bool SVGExporter::export_scene(Scene &scene, StringRefNull filepath)
|
||||
|
||||
this->export_grease_pencil_objects(main_node, frame_number);
|
||||
|
||||
return this->write_to_file(filepath);
|
||||
const bool write_success = this->write_to_file(filepath);
|
||||
return write_success ? ExportStatus::Ok : ExportStatus::FileWriteError;
|
||||
}
|
||||
case ExportParams::FrameMode::Selected:
|
||||
case ExportParams::FrameMode::Scene: {
|
||||
@@ -172,6 +173,9 @@ bool SVGExporter::export_scene(Scene &scene, StringRefNull filepath)
|
||||
IndexMaskMemory memory;
|
||||
if (selection_only) {
|
||||
const Object &ob_eval = *DEG_get_evaluated(context_.depsgraph, params_.object);
|
||||
if (ob_eval.type != OB_GREASE_PENCIL) {
|
||||
return ExportStatus::InvalidActiveObjectType;
|
||||
}
|
||||
const GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob_eval.data);
|
||||
frames = IndexMask::from_predicate(
|
||||
frames, GrainSize(1024), memory, [&](const int frame_number) {
|
||||
@@ -179,6 +183,10 @@ bool SVGExporter::export_scene(Scene &scene, StringRefNull filepath)
|
||||
});
|
||||
}
|
||||
|
||||
if (frames.is_empty()) {
|
||||
return ExportStatus::NoFramesSelected;
|
||||
}
|
||||
|
||||
this->prepare_render_params(scene, frames.first());
|
||||
|
||||
this->write_document_header();
|
||||
@@ -209,11 +217,12 @@ bool SVGExporter::export_scene(Scene &scene, StringRefNull filepath)
|
||||
|
||||
this->write_animation_node(main_node, frames, duration);
|
||||
|
||||
return this->write_to_file(filepath);
|
||||
const bool write_success = this->write_to_file(filepath);
|
||||
return write_success ? ExportStatus::Ok : ExportStatus::FileWriteError;
|
||||
}
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
return false;
|
||||
return ExportStatus::UnknownError;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,10 +581,10 @@ bool SVGExporter::write_to_file(StringRefNull filepath)
|
||||
return result;
|
||||
}
|
||||
|
||||
bool export_svg(const IOContext &context,
|
||||
const ExportParams ¶ms,
|
||||
Scene &scene,
|
||||
StringRefNull filepath)
|
||||
ExportStatus export_svg(const IOContext &context,
|
||||
const ExportParams ¶ms,
|
||||
Scene &scene,
|
||||
StringRefNull filepath)
|
||||
{
|
||||
SVGExporter exporter(context, params);
|
||||
return exporter.export_scene(scene, filepath);
|
||||
|
||||
Reference in New Issue
Block a user