rtiow: add support to send rendering output to https://github.com/Tom94/tev

This commit is contained in:
Bill Thiede 2023-10-29 10:44:59 -07:00
parent 593632a9e3
commit f93d215fc2
5 changed files with 53 additions and 8 deletions

7
rtiow/Cargo.lock generated
View File

@ -2591,6 +2591,7 @@ dependencies = [
"structopt 0.2.18", "structopt 0.2.18",
"strum", "strum",
"strum_macros", "strum_macros",
"tev_client",
"thiserror", "thiserror",
"vec3", "vec3",
] ]
@ -3083,6 +3084,12 @@ dependencies = [
"redox_termios", "redox_termios",
] ]
[[package]]
name = "tev_client"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c845c2d56d4f732d09a32c9ea2cd3f01923be7a5f98d9f7f0a347205c3141036"
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.11.0" version = "0.11.0"

View File

@ -30,6 +30,7 @@ stl = {path = "../../../stl"}
strum = { version = "0.24.1", features = ["derive"] } strum = { version = "0.24.1", features = ["derive"] }
strum_macros = "0.24.3" strum_macros = "0.24.3"
thiserror = "1.0.38" thiserror = "1.0.38"
tev_client = "0.5.2"
#stl = {git = "https://git-private.z.xinu.tv/wathiede/stl"} #stl = {git = "https://git-private.z.xinu.tv/wathiede/stl"}
[dev-dependencies] [dev-dependencies]

View File

@ -2,6 +2,7 @@ use std::{
collections::HashMap, collections::HashMap,
fs::File, fs::File,
io::BufWriter, io::BufWriter,
net::TcpStream,
path::Path, path::Path,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time, time,
@ -9,9 +10,9 @@ use std::{
use chrono::Local; use chrono::Local;
use image; use image;
use lazy_static::lazy_static;
use log::info; use log::info;
use serde_derive::Serialize; use serde_derive::Serialize;
use tev_client::{PacketCreateImage, PacketUpdateImage, TevClient};
use crate::{renderer::Scene, vec3::Vec3}; use crate::{renderer::Scene, vec3::Vec3};
@ -72,18 +73,36 @@ impl Image {
pub struct OutputManager { pub struct OutputManager {
images: Arc<Mutex<HashMap<String, (ImageType, Image)>>>, images: Arc<Mutex<HashMap<String, (ImageType, Image)>>>,
tev_client: Option<Arc<Mutex<TevClient>>>,
} }
impl OutputManager { impl OutputManager {
pub fn new() -> OutputManager { pub fn new(tev_addr: &Option<String>) -> std::io::Result<OutputManager> {
OutputManager { let tev_client = if let Some(addr) = tev_addr {
Some(Arc::new(Mutex::new(TevClient::wrap(TcpStream::connect(
addr,
)?))))
} else {
None
};
Ok(OutputManager {
images: Arc::new(Mutex::new(HashMap::new())), images: Arc::new(Mutex::new(HashMap::new())),
} tev_client,
})
} }
pub fn register_image(&self, name: String, dimensions: (usize, usize), it: ImageType) { pub fn register_image(&self, name: String, dimensions: (usize, usize), it: ImageType) {
let mut images = self.images.lock().unwrap(); let mut images = self.images.lock().unwrap();
images.insert(name, (it, Image::new(dimensions.0, dimensions.1))); images.insert(name.clone(), (it, Image::new(dimensions.0, dimensions.1)));
self.tev_client.clone().map(|c| {
c.lock().unwrap().send(PacketCreateImage {
image_name: &name,
grab_focus: false,
width: dimensions.0 as u32,
height: dimensions.1 as u32,
channel_names: &["R", "G", "B"],
})
});
} }
pub fn set_pixel(&self, name: &str, x: usize, y: usize, pixel: Vec3) { pub fn set_pixel(&self, name: &str, x: usize, y: usize, pixel: Vec3) {
@ -93,6 +112,20 @@ impl OutputManager {
.unwrap_or_else(|| panic!("couldn't find image named '{}'", name)); .unwrap_or_else(|| panic!("couldn't find image named '{}'", name));
let y_inv = img.h - y - 1; let y_inv = img.h - y - 1;
img.put_pixel(x, y_inv, pixel); img.put_pixel(x, y_inv, pixel);
self.tev_client.clone().map(|c| {
c.lock().unwrap().send(PacketUpdateImage {
image_name: &name,
grab_focus: false,
channel_names: &["R", "G", "B"],
channel_offsets: &[0, 1, 2],
channel_strides: &[0, 0, 0],
x: x as u32,
y: y_inv as u32,
width: 1,
height: 1,
data: &[pixel.x, pixel.y, pixel.z],
})
});
} }
pub fn set_pixel_grey(&self, name: &str, x: usize, y: usize, grey: f32) { pub fn set_pixel_grey(&self, name: &str, x: usize, y: usize, grey: f32) {

View File

@ -529,7 +529,11 @@ lazy_static! {
} }
*/ */
pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::io::Error> { pub fn render(
scene: Scene,
output_dir: &Path,
tev_addr: &Option<String>,
) -> std::result::Result<(), std::io::Error> {
// Default to half the cores to disable hyperthreading. // Default to half the cores to disable hyperthreading.
let num_threads = scene.num_threads.unwrap_or_else(|| num_cpus::get() / 2); let num_threads = scene.num_threads.unwrap_or_else(|| num_cpus::get() / 2);
let (pixel_req_tx, pixel_req_rx) = sync_channel(2 * num_threads); let (pixel_req_tx, pixel_req_rx) = sync_channel(2 * num_threads);
@ -545,7 +549,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
} else { } else {
core_ids core_ids
}; };
let output = output::OutputManager::new(); let output = output::OutputManager::new(tev_addr)?;
let output = Arc::new(output); let output = Arc::new(output);
info!("Creating {} render threads", core_ids.len()); info!("Creating {} render threads", core_ids.len());

View File

@ -80,7 +80,7 @@ fn main() -> Result<()> {
.start(pprof_path.to_str().unwrap().as_bytes()) .start(pprof_path.to_str().unwrap().as_bytes())
.unwrap(); .unwrap();
} }
let res = render(scene, &opt.output); let res = render(scene, &opt.output, &opt.tev_addr);
if let Some(pprof_path) = &opt.pprof { if let Some(pprof_path) = &opt.pprof {
info!("Saving pprof to {}", pprof_path.to_string_lossy()); info!("Saving pprof to {}", pprof_path.to_string_lossy());
PROFILER.lock().unwrap().stop().unwrap(); PROFILER.lock().unwrap().stop().unwrap();