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
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ansi_term = "0.12"
|
|
||||||
bincode = "1.3.1"
|
bincode = "1.3.1"
|
||||||
|
crossterm = "0.18"
|
||||||
decorum = "0.3"
|
decorum = "0.3"
|
||||||
dyn-clone = "1.0"
|
dyn-clone = "1.0"
|
||||||
enum_dispatch = "0.3"
|
enum_dispatch = "0.3"
|
||||||
@@ -22,10 +22,11 @@ ndarray = { version = "0.13", features = ["rayon", "serde"] }
|
|||||||
piecewise-linear = "0.1"
|
piecewise-linear = "0.1"
|
||||||
plotly = { version = "0.6", features = ["kaleido", "plotly_ndarray"], path = "../plotly/plotly" }
|
plotly = { version = "0.6", features = ["kaleido", "plotly_ndarray"], path = "../plotly/plotly" }
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_cbor = "0.11"
|
|
||||||
structopt = "0.3"
|
structopt = "0.3"
|
||||||
threadpool = "1.8"
|
threadpool = "1.8"
|
||||||
y4m = "0.7"
|
y4m = "0.7"
|
||||||
|
# ansi_term = "0.12"
|
||||||
|
# serde_cbor = "0.11"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.3"
|
criterion = "0.3"
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
use coremem::StaticSim;
|
use coremem::{GenericSim as _, StaticSim};
|
||||||
use coremem::render::{ColorTermRenderer, Renderer as _};
|
use coremem::render::{ColorTermRenderer, Renderer as _};
|
||||||
|
|
||||||
use std::fs::{File, read_dir};
|
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 std::path::{Path, PathBuf};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
use crossterm::event::{Event, KeyCode};
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(Debug, StructOpt)]
|
||||||
struct Opt {
|
struct Opt {
|
||||||
@@ -16,6 +18,14 @@ struct Frame {
|
|||||||
data: StaticSim,
|
data: StaticSim,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Deref for Frame {
|
||||||
|
type Target = StaticSim;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
struct Loader {
|
struct Loader {
|
||||||
dir: PathBuf,
|
dir: PathBuf,
|
||||||
}
|
}
|
||||||
@@ -51,12 +61,46 @@ impl Loader {
|
|||||||
struct Viewer {
|
struct Viewer {
|
||||||
viewing: Option<Frame>,
|
viewing: Option<Frame>,
|
||||||
z: u32,
|
z: u32,
|
||||||
|
loader: Loader,
|
||||||
renderer: ColorTermRenderer,
|
renderer: ColorTermRenderer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Viewer {
|
impl Viewer {
|
||||||
fn switch_frame(&mut self, frame: Frame) {
|
fn prev_frame(&mut self) {
|
||||||
self.viewing = Some(frame);
|
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, &[]);
|
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 opt = Opt::from_args();
|
||||||
let loader = Loader::new(opt.directory);
|
let loader = Loader::new(opt.directory);
|
||||||
let mut viewer = Viewer::default();
|
let mut viewer = Viewer::default();
|
||||||
let frame = loader.load_next(None);
|
viewer.loader = loader;
|
||||||
viewer.switch_frame(frame.unwrap());
|
//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::geom::{Index, Meters, Vec2, Vec3, Vec3u};
|
||||||
use crate::{flt::{Flt, Real}, Material as _};
|
use crate::{flt::{Flt, Real}, Material as _};
|
||||||
use crate::mat;
|
use crate::mat;
|
||||||
use crate::sim::{Cell, GenericSim};
|
use crate::sim::{Cell, GenericSim};
|
||||||
use crate::meas::AbstractMeasurement;
|
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 font8x8::{BASIC_FONTS, GREEK_FONTS, UnicodeFonts as _};
|
||||||
use log::{trace, info};
|
use log::{trace, info};
|
||||||
use plotly;
|
use plotly;
|
||||||
use image::{RgbImage, Rgb};
|
use image::{RgbImage, Rgb};
|
||||||
use imageproc::{pixelops, drawing};
|
use imageproc::{pixelops, drawing};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::BufWriter;
|
use std::io::{BufWriter, Write as _};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::{Mutex, RwLock};
|
use std::sync::{Mutex, RwLock};
|
||||||
use y4m;
|
use y4m;
|
||||||
@@ -274,17 +275,25 @@ pub struct ColorTermRenderer;
|
|||||||
|
|
||||||
impl Renderer for ColorTermRenderer {
|
impl Renderer for ColorTermRenderer {
|
||||||
fn render_with_image(&self, _state: &dyn GenericSim, im: &RgbImage) {
|
fn render_with_image(&self, _state: &dyn GenericSim, im: &RgbImage) {
|
||||||
let square = "█";
|
// TODO: should scale the image to the size of the terminal!
|
||||||
let buf: String = im
|
let mut stdout = std::io::stdout();
|
||||||
.enumerate_rows()
|
let (w, h) = crossterm::terminal::size().unwrap();
|
||||||
.map(|(_y, row)| {
|
stdout.queue(cursor::MoveTo(0, 0));
|
||||||
format!("{}\n", row.map(|(_x, _y, p)| {
|
for (y, row) in im.enumerate_rows() {
|
||||||
format!("{}", RGB(p.0[0], p.0[1], p.0[2]).paint(square))
|
if y >= h.into() {
|
||||||
}).collect::<String>())
|
break;
|
||||||
})
|
}
|
||||||
.collect();
|
stdout.queue(cursor::MoveDown(1));
|
||||||
|
stdout.queue(cursor::MoveToColumn(0));
|
||||||
println!("{}", buf);
|
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