///|
/// Backend-neutral export manifest for reproducible media renders.
pub enum ExportFormat2 {
ImageSequenceExport
VideoExport
DataExport
AudioExport
} derive(Debug)
///|
pub fn export_formats2() -> Array[ExportFormat2] {
[ImageSequenceExport, VideoExport, DataExport, AudioExport]
}
///|
pub struct ExportSettings2 {
format : ExportFormat2
width : Int
height : Int
frame_rate : Double
quality : RenderQuality2
premultiplied : Bool
} derive(Debug)
///|
pub fn export_settings2(
format : ExportFormat2,
width : Int,
height : Int,
frame_rate : Double,
) -> ExportSettings2 {
{
format,
width: width.max(1),
height: height.max(1),
frame_rate: frame_rate.max(0.001),
quality: FinalQuality,
premultiplied: true,
}
}
///|
pub fn ExportSettings2::format(self : ExportSettings2) -> ExportFormat2 {
self.format
}
///|
pub fn ExportSettings2::width(self : ExportSettings2) -> Int {
self.width
}
///|
pub fn ExportSettings2::height(self : ExportSettings2) -> Int {
self.height
}
///|
pub fn ExportSettings2::frame_rate(self : ExportSettings2) -> Double {
self.frame_rate
}
///|
pub fn ExportSettings2::quality(self : ExportSettings2) -> RenderQuality2 {
self.quality
}
///|
pub fn ExportSettings2::with_quality(
self : ExportSettings2,
quality : RenderQuality2,
) -> ExportSettings2 {
{
format: self.format,
width: self.width,
height: self.height,
frame_rate: self.frame_rate,
quality,
premultiplied: self.premultiplied,
}
}
///|
pub fn ExportSettings2::with_premultiplied(
self : ExportSettings2,
value : Bool,
) -> ExportSettings2 {
{
format: self.format,
width: self.width,
height: self.height,
frame_rate: self.frame_rate,
quality: self.quality,
premultiplied: value,
}
}
///|
pub fn ExportSettings2::viewport(self : ExportSettings2) -> Viewport {
viewport(self.width.to_double(), self.height.to_double())
}
///|
pub struct ExportManifestEntry2 {
id : Int
name : String
start : Double
end : Double
checksum : Int
frame_count : Int
} derive(Debug)
///|
pub fn export_manifest_entry2(
id : Int,
name : String,
start : Double,
end : Double,
frame_count : Int,
) -> ExportManifestEntry2 {
{ id, name, start, end, checksum: 0, frame_count: frame_count.max(0) }
}
///|
pub fn ExportManifestEntry2::id(self : ExportManifestEntry2) -> Int {
self.id
}
///|
pub fn ExportManifestEntry2::name(self : ExportManifestEntry2) -> String {
self.name
}
///|
pub fn ExportManifestEntry2::start(self : ExportManifestEntry2) -> Double {
self.start
}
///|
pub fn ExportManifestEntry2::end(self : ExportManifestEntry2) -> Double {
self.end
}
///|
pub fn ExportManifestEntry2::checksum(self : ExportManifestEntry2) -> Int {
self.checksum
}
///|
pub fn ExportManifestEntry2::frame_count(self : ExportManifestEntry2) -> Int {
self.frame_count
}
///|
pub fn ExportManifestEntry2::with_checksum(
self : ExportManifestEntry2,
checksum : Int,
) -> ExportManifestEntry2 {
{
id: self.id,
name: self.name,
start: self.start,
end: self.end,
checksum,
frame_count: self.frame_count,
}
}
///|
pub fn export_entry_checksum(values : Array[Double]) -> Int {
let mut hash = 17
for value in values {
let bits = @math.floor(value * 1000000.0).to_int()
hash = (hash * 31 + bits) % 2147483647
}
hash
}
///|
pub struct ExportManifest2 {
settings : ExportSettings2
entries : Array[ExportManifestEntry2]
version : Int
} derive(Debug)
///|
pub fn export_manifest2(settings : ExportSettings2) -> ExportManifest2 {
{ settings, entries: [], version: 1 }
}
///|
pub fn ExportManifest2::settings(self : ExportManifest2) -> ExportSettings2 {
self.settings
}
///|
pub fn ExportManifest2::entries(
self : ExportManifest2,
) -> Array[ExportManifestEntry2] {
self.entries.copy()
}
///|
pub fn ExportManifest2::version(self : ExportManifest2) -> Int {
self.version
}
///|
pub fn ExportManifest2::add(
self : ExportManifest2,
entry : ExportManifestEntry2,
) -> Bool {
for existing in self.entries {
if existing.id == entry.id {
return false
}
}
self.entries.push(entry)
true
}
///|
pub fn ExportManifest2::find(
self : ExportManifest2,
id : Int,
) -> ExportManifestEntry2? {
for entry in self.entries {
if entry.id == id {
return Some(entry)
}
}
None
}
///|
pub fn ExportManifest2::total_frames(self : ExportManifest2) -> Int {
let mut result = 0
for entry in self.entries {
result = result + entry.frame_count
}
result
}
///|
pub fn ExportManifest2::time_range(self : ExportManifest2) -> (Double, Double) {
if self.entries.length() == 0 {
return (0.0, 0.0)
}
let mut start = self.entries[0].start
let mut end = self.entries[0].end
for entry in self.entries {
start = start.min(entry.start)
end = end.max(entry.end)
}
(start, end)
}
///|
pub fn ExportManifest2::validate(self : ExportManifest2) -> DiagnosticReport2 {
let report = diagnostic_report2("export-manifest").with_measurements(
self.total_frames(),
self.time_range().1 - self.time_range().0,
)
if self.entries.length() == 0 {
report.add(
diagnostic_issue(
WarningDiagnostic,
EmptyInputDiagnostic,
"manifest contains no entries",
0,
0.0,
0.0,
),
)
}
for index in 0..