Export equirectangular PNGs through paint renderer

This commit is contained in:
2026-06-05 20:31:35 +02:00
parent ebc84373e6
commit 77268a28fb
8 changed files with 378 additions and 19 deletions

View File

@@ -25,6 +25,19 @@ void show_export_success_dialog(
}
}
bool is_png_export_target(std::string_view path) noexcept
{
if (path.size() < 4U) {
return false;
}
const auto extension = path.substr(path.size() - 4U);
return extension[0] == '.'
&& (extension[1] == 'p' || extension[1] == 'P')
&& (extension[2] == 'n' || extension[2] == 'N')
&& (extension[3] == 'g' || extension[3] == 'G');
}
struct LegacyDocumentExportSnapshotReports {
pp::app::DocumentCanvasSnapshotResult snapshot;
pp::paint_renderer::DocumentFrameFacePngExportResult face_pngs;
@@ -174,6 +187,40 @@ pp::foundation::Status export_cube_faces_from_document_snapshot(
return pp::app::execute_document_cube_face_export_write(target.value(), payloads, services);
}
pp::foundation::Status export_equirectangular_png_from_document_snapshot(
App& app,
const pp::app::DocumentExportFileTarget& target,
const LegacyDocumentExportSnapshotReports& reports)
{
if (!is_png_export_target(target.path)) {
return pp::foundation::Status::invalid_argument(
"document snapshot equirectangular export currently supports PNG targets only");
}
auto exported = pp::paint_renderer::export_document_frame_equirectangular_png(reports.face_pngs.composite);
if (!exported) {
return exported.status();
}
auto exported_value = std::move(exported.value());
LOG(
"export-equirectangular document export PNG writer: %ux%u bytes=%llu facePayloads=%zu compositedLayerFaces=%zu",
exported_value.equirectangular_extent.width,
exported_value.equirectangular_extent.height,
static_cast<unsigned long long>(exported_value.encoded_bytes),
exported_value.face_payload_count,
exported_value.composited_layer_face_count);
const auto write_status = write_export_binary_file(
target.path,
std::span<const std::byte>(exported_value.png.data(), exported_value.png.size()));
if (!write_status.ok()) {
return write_status;
}
app.publish_exported_image(target.path);
return pp::foundation::Status::success();
}
class LegacyDocumentExportServices final : public pp::app::DocumentExportServices {
public:
explicit LegacyDocumentExportServices(App& app) noexcept
@@ -189,7 +236,34 @@ public:
void export_equirectangular(const pp::app::DocumentExportFileTarget& target) override
{
auto* app = &app_;
prepare_legacy_document_export_snapshot_or_continue(app_, "export-equirectangular");
#if !__WEB__
if (is_png_export_target(target.path)) {
const auto prepared = prepare_legacy_document_export_snapshot(app_, "export-equirectangular");
if (prepared) {
const auto exported = export_equirectangular_png_from_document_snapshot(app_, target, prepared.value());
if (exported.ok()) {
show_export_success_dialog(
app_,
pp::app::plan_document_export_success_dialog(
pp::app::DocumentExportSuccessKind::equirectangular,
pp::app::document_export_equirectangular_platform_destination(),
app_.work_path));
return;
}
LOG(
"export-equirectangular document export writer retained legacy export after failure: %s",
exported.message);
} else {
LOG(
"export-equirectangular document export snapshot bridge retained legacy export after failure: %s",
prepared.status().message);
}
} else
#endif
{
prepare_legacy_document_export_snapshot_or_continue(app_, "export-equirectangular");
}
app_.canvas->m_canvas->export_equirectangular(target.path, [app, target] {
#if __WEB__
app->ui_task([app, target] {