renderer can navigate forward in time (and also in the + or - z direction)
Can't navigate backward yet
This commit is contained in:
@@ -7,8 +7,8 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
ansi_term = "0.12"
|
||||
bincode = "1.3.1"
|
||||
crossterm = "0.18"
|
||||
decorum = "0.3"
|
||||
dyn-clone = "1.0"
|
||||
enum_dispatch = "0.3"
|
||||
@@ -22,10 +22,11 @@ ndarray = { version = "0.13", features = ["rayon", "serde"] }
|
||||
piecewise-linear = "0.1"
|
||||
plotly = { version = "0.6", features = ["kaleido", "plotly_ndarray"], path = "../plotly/plotly" }
|
||||
serde = "1.0"
|
||||
serde_cbor = "0.11"
|
||||
structopt = "0.3"
|
||||
threadpool = "1.8"
|
||||
y4m = "0.7"
|
||||
# ansi_term = "0.12"
|
||||
# serde_cbor = "0.11"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
|
@@ -1,10 +1,12 @@
|
||||
use coremem::StaticSim;
|
||||
use coremem::{GenericSim as _, StaticSim};
|
||||
use coremem::render::{ColorTermRenderer, Renderer as _};
|
||||
|
||||
use std::fs::{File, read_dir};
|
||||
use std::io::BufReader;
|
||||
use std::io::{BufReader, Read as _, stdin};
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use structopt::StructOpt;
|
||||
use crossterm::event::{Event, KeyCode};
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
struct Opt {
|
||||
@@ -16,6 +18,14 @@ struct Frame {
|
||||
data: StaticSim,
|
||||
}
|
||||
|
||||
impl Deref for Frame {
|
||||
type Target = StaticSim;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Loader {
|
||||
dir: PathBuf,
|
||||
}
|
||||
@@ -51,12 +61,46 @@ impl Loader {
|
||||
struct Viewer {
|
||||
viewing: Option<Frame>,
|
||||
z: u32,
|
||||
loader: Loader,
|
||||
renderer: ColorTermRenderer,
|
||||
}
|
||||
|
||||
impl Viewer {
|
||||
fn switch_frame(&mut self, frame: Frame) {
|
||||
self.viewing = Some(frame);
|
||||
fn prev_frame(&mut self) {
|
||||
println!("<unimplemented>");
|
||||
}
|
||||
fn next_frame(&mut self) {
|
||||
let next_frame = self.loader.load_next(self.viewing.as_ref());
|
||||
if next_frame.is_some() {
|
||||
self.viewing = next_frame;
|
||||
self.render();
|
||||
} else {
|
||||
println!("<end>");
|
||||
}
|
||||
}
|
||||
fn prev_depth(&mut self) {
|
||||
match self.z {
|
||||
0 => {
|
||||
println!("<end>");
|
||||
},
|
||||
_ => {
|
||||
self.z -= 1;
|
||||
self.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
fn next_depth(&mut self) {
|
||||
match self.z {
|
||||
z if z+1 < self.viewing.as_ref().map(|f| f.depth()).unwrap_or(0) => {
|
||||
self.z += 1;
|
||||
self.render();
|
||||
},
|
||||
_ => {
|
||||
println!("<end>");
|
||||
}
|
||||
}
|
||||
}
|
||||
fn render(&self) {
|
||||
self.renderer.render_z_slice(self.viewing.as_ref().map(|f| &f.data).unwrap(), self.z, &[]);
|
||||
}
|
||||
}
|
||||
@@ -65,6 +109,25 @@ fn main() {
|
||||
let opt = Opt::from_args();
|
||||
let loader = Loader::new(opt.directory);
|
||||
let mut viewer = Viewer::default();
|
||||
let frame = loader.load_next(None);
|
||||
viewer.switch_frame(frame.unwrap());
|
||||
viewer.loader = loader;
|
||||
//let frame = loader.load_next(None);
|
||||
//viewer.switch_frame(frame.unwrap());
|
||||
|
||||
// disable line buffering
|
||||
crossterm::terminal::enable_raw_mode().unwrap();
|
||||
loop {
|
||||
match crossterm::event::read().unwrap() {
|
||||
Event::Key(e) => match e.code {
|
||||
KeyCode::Left => viewer.prev_frame(),
|
||||
KeyCode::Right => viewer.next_frame(),
|
||||
KeyCode::Up => viewer.prev_depth(),
|
||||
KeyCode::Down => viewer.next_depth(),
|
||||
KeyCode::Char('q') => break,
|
||||
_ => {},
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
// otherwise terminal is left in a wacky state
|
||||
crossterm::terminal::disable_raw_mode().unwrap();
|
||||
}
|
||||
|
@@ -1,16 +1,17 @@
|
||||
use ansi_term::Color::RGB;
|
||||
use crate::geom::{Index, Meters, Vec2, Vec3, Vec3u};
|
||||
use crate::{flt::{Flt, Real}, Material as _};
|
||||
use crate::mat;
|
||||
use crate::sim::{Cell, GenericSim};
|
||||
use crate::meas::AbstractMeasurement;
|
||||
use crossterm::{cursor, ExecutableCommand as _, QueueableCommand as _};
|
||||
use crossterm::style::{style, Color, PrintStyledContent, StyledContent as _};
|
||||
use font8x8::{BASIC_FONTS, GREEK_FONTS, UnicodeFonts as _};
|
||||
use log::{trace, info};
|
||||
use plotly;
|
||||
use image::{RgbImage, Rgb};
|
||||
use imageproc::{pixelops, drawing};
|
||||
use std::fs::File;
|
||||
use std::io::BufWriter;
|
||||
use std::io::{BufWriter, Write as _};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Mutex, RwLock};
|
||||
use y4m;
|
||||
@@ -274,17 +275,25 @@ pub struct ColorTermRenderer;
|
||||
|
||||
impl Renderer for ColorTermRenderer {
|
||||
fn render_with_image(&self, _state: &dyn GenericSim, im: &RgbImage) {
|
||||
let square = "█";
|
||||
let buf: String = im
|
||||
.enumerate_rows()
|
||||
.map(|(_y, row)| {
|
||||
format!("{}\n", row.map(|(_x, _y, p)| {
|
||||
format!("{}", RGB(p.0[0], p.0[1], p.0[2]).paint(square))
|
||||
}).collect::<String>())
|
||||
})
|
||||
.collect();
|
||||
|
||||
println!("{}", buf);
|
||||
// TODO: should scale the image to the size of the terminal!
|
||||
let mut stdout = std::io::stdout();
|
||||
let (w, h) = crossterm::terminal::size().unwrap();
|
||||
stdout.queue(cursor::MoveTo(0, 0));
|
||||
for (y, row) in im.enumerate_rows() {
|
||||
if y >= h.into() {
|
||||
break;
|
||||
}
|
||||
stdout.queue(cursor::MoveDown(1));
|
||||
stdout.queue(cursor::MoveToColumn(0));
|
||||
for (_x, _y, p) in row {
|
||||
stdout.queue(PrintStyledContent(style(" ").on(Color::Rgb {
|
||||
r: p.0[0],
|
||||
g: p.0[1],
|
||||
b: p.0[2],
|
||||
})));
|
||||
}
|
||||
}
|
||||
stdout.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user