wfc_image 0.12.1

Create patterns for wfc using image files
Documentation
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
use std::num::NonZeroU32;
use wfc_image::*;

fn app() -> Result<(), ()> {
    let (
        seed_opt,
        input_path,
        output_path,
        all_orientations,
        pattern_size,
        width,
        height,
        parallel,
    ) = meap::all! {
        opt_opt("INT", 's').name("seed").desc("rng seed"),
        opt_req::<String, _>("PATH", 'i').name("input").desc("input path"),
        opt_req::<String, _>("PATH", 'o').name("output").desc("output path"),
        flag('a').name("all-orientations").desc("all orientations"),
        opt_opt::<u32, _>("INT", 'p').name("pattern-size").desc("size of patterns in pixels").with_default(3),
        opt_opt::<u32, _>("INT", 'x').name("width").desc("width").with_default(48),
        opt_opt::<u32, _>("INT", 'y').name("height").desc("height").with_default(48),
        flag("parallel").desc("run multiple attempts in parallel"),
    }
    .with_help_default()
    .parse_env_or_exit();
    let seed = seed_opt.unwrap_or_else(|| rand::thread_rng().gen());
    println!("seed: {}", seed);
    let orientation: &[Orientation] = if all_orientations {
        &orientation::ALL
    } else {
        &[Orientation::Original]
    };
    let input_image = image::open(input_path).unwrap();
    let output_size = Size::new(width, height);
    let mut rng = StdRng::seed_from_u64(seed);
    let start_time = ::std::time::Instant::now();
    let pattern_size =
        NonZeroU32::new(pattern_size).expect("pattern size may not be zero");
    let result = if parallel {
        #[cfg(feature = "parallel")]
        {
            generate_image_with_rng(
                &input_image,
                pattern_size,
                output_size,
                orientation,
                WrapXY,
                ForbidNothing,
                retry::ParNumTimes(10),
                &mut rng,
            )
        }
        #[cfg(not(feature = "parallel"))]
        panic!("Recompile with `--features=parallel` to enable parallel retry")
    } else {
        generate_image_with_rng(
            &input_image,
            pattern_size,
            output_size,
            orientation,
            WrapXY,
            ForbidNothing,
            retry::NumTimes(10),
            &mut rng,
        )
    };
    match result {
        Err(_) => {
            eprintln!("Too many contradictions");
            Err(())
        }
        Ok(output_image) => {
            let end_time = ::std::time::Instant::now();
            println!("{:?}", end_time - start_time);
            output_image.save(output_path).unwrap();
            Ok(())
        }
    }
}

fn main() {
    ::std::process::exit(match app() {
        Ok(()) => 0,
        Err(()) => 1,
    })
}