Skip to content
This repository was archived by the owner on May 20, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion native/src/bin/meldtool/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub fn parse_args() -> WorkOrder {
.short("q")
.long("quiet")
.takes_value(false)
.help("output nothing"),
.help("suppress all informational output"),
)
.get_matches();

Expand Down
25 changes: 25 additions & 0 deletions native/src/bin/meldtool/error_handling.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
//

use std::{fmt, result};

/// A custom error type for the MeldTool.
///
// (until NoneOption stabilises, we have to use this rather silly type-ersing
// trick to be able to use ? on Option.)
pub struct ToolError(Box<dyn fmt::Debug>);

impl<T: fmt::Debug + 'static> From<T> for ToolError {
fn from(error: T) -> Self {
Self(Box::new(error))
}
}

impl fmt::Display for ToolError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.0)
}
}

/// Convenience type for a Result using our Error.
pub type Result<T> = result::Result<T, ToolError>;
72 changes: 53 additions & 19 deletions native/src/bin/meldtool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ extern crate gltf_variant_meld;

use std::fs;

use gltf_variant_meld::{Result, VariationalAsset};
use gltf_variant_meld::VariationalAsset;

mod args;
use args::parse_args;
pub use args::{SourceAsset, SourceAssets, WorkOrder};

mod error_handling;
use error_handling::Result;

fn main() {
let work_order = parse_args();

Expand All @@ -22,30 +25,53 @@ fn main() {
}

fn process(work_order: WorkOrder) -> Result<()> {
let base = read_asset(&work_order.source_assets.base)?;
let base = &work_order.source_assets.base;
let base_asset = read_asset(base)?;
if work_order.verbose() {
println!("Base asset:");
describe_asset(&base);
println!(
"Parsed base asset [{}]: {:?}",
size(base_asset.glb().len()),
base.path.file_name()?
);
}

let mut result = base;
let mut result = base_asset;
for meld in &work_order.source_assets.melds {
let meld = read_asset(meld)?;
result = VariationalAsset::meld(&result, &meld)?;
let meld_asset = read_asset(meld)?;
if work_order.verbose() {
println!("New melded result:");
describe_asset(&result);
println!();
println!(
"Melding in asset [{}]: {:?}",
size(meld_asset.glb().len()),
meld.path.file_name()?
);
}
let old_size = result.glb().len();
result = VariationalAsset::meld(&result, &meld_asset)?;
if work_order.verbose() {
let new_size = result.glb().len();
println!(
"Total post-meld size increase: {}",
size(new_size - old_size)
);
}
}

if work_order.verbose() {
println!();
println!("Final asset size: {}", size(result.glb().len()));
describe_textures(&result)?;
println!();
}

fs::write(&work_order.output_path, result.glb())
.map_err(|e| format!("Couldn't write output file: {}", e))?;

if !work_order.quiet() {
println!(
"Success! {} bytes written to '{}'.",
"{} bytes written to '{}'.",
result.glb().len(),
work_order.output_path.to_str().unwrap_or("<error>"),
work_order.output_path.to_str()?,
);
}
Ok(())
Expand All @@ -58,18 +84,26 @@ fn read_asset(asset: &SourceAsset) -> Result<VariationalAsset> {
)?)
}

fn describe_asset(asset: &VariationalAsset) {
println!(" Total file size: {}", size(asset.glb().len()));
let total = asset.metadata().total_sizes().texture_bytes;
let variational = asset.metadata().variational_sizes().texture_bytes;
println!(" Total texture data: {}", size(total));
println!(" Of which is depends on tag: {}", size(variational));
fn describe_textures(asset: &VariationalAsset) -> Result<()> {
let metadata = asset.metadata();
let shared_textures =
metadata.total_sizes().texture_bytes() - metadata.variational_sizes().texture_bytes();

println!("Active variational texture, by tag:");
let mut tags: Vec<_> = metadata.tags().iter().collect();
tags.sort();
for &tag in &tags {
let textures_for_tag = metadata.tag_sizes(tag)?.texture_bytes() - shared_textures;
println!("{:>30}: {}", format!("[{}]", tag), size(textures_for_tag));
}
println!("Textures shared by all variants: {}", size(shared_textures));
Ok(())
}

fn size(byte_count: usize) -> String {
if byte_count < 1000000 {
format!("{:.01} kB", byte_count / 1000)
format!("{:.01} kB", (byte_count as f64) / 1000.0)
} else {
format!("{:.01} MB", byte_count / 1000000)
format!("{:.01} MB", (byte_count as f64) / 1000000.0)
}
}