use gemlab::mesh::{Draw, Mesh};
use gemlab::StrError;
use std::path::Path;
use std::path::PathBuf;
use structopt::StructOpt;
const OUT_DIR: &str = "/tmp/gemlab";
#[derive(Debug, StructOpt)]
#[structopt(name = "drawmsh", about = "Draw MSH file")]
struct Options {
#[structopt(parse(from_os_str))]
input: PathBuf,
#[structopt(short = "k", long)]
skip_check: bool,
#[structopt(short, long)]
dots: bool,
#[structopt(short, long)]
point_ids: bool,
#[structopt(short, long)]
cell_ids: bool,
#[structopt(short = "v", long)]
point_markers: bool,
#[structopt(short = "a", long)]
cell_markers: bool,
#[structopt(short, long)]
edge_markers: bool,
#[structopt(short, long)]
face_markers: bool,
#[structopt(short, long)]
normals: bool,
#[structopt(short = "i", long)]
hide_cells: bool,
#[structopt(short = "y", long)]
boundary_edges: bool,
#[structopt(short = "z", long)]
boundary_faces: bool,
#[structopt(short, long)]
width: Option<f64>,
#[structopt(short, long)]
height: Option<f64>,
#[structopt(short = "V", long)]
view: bool,
#[structopt(long)]
m_range: Option<f64>,
#[structopt(long)]
m_normal_vector: Option<f64>,
#[structopt(long)]
m_normal_vector_marker: Option<f64>,
#[structopt(long)]
elevation: Option<f64>,
#[structopt(long)]
azimuth: Option<f64>,
#[structopt(long = "glyph-enabled")]
glyph_enabled: Option<bool>,
#[structopt(
long,
value_names = &["x", "y", "z"],
number_of_values = 3,
allow_hyphen_values = true
)]
glyph_origin: Option<Vec<f64>>,
#[structopt(long)]
glyph_size: Option<f64>,
}
fn get_glyph_origin(values: &Option<Vec<f64>>) -> Result<[f64; 3], StrError> {
match values {
Some(v) if v.len() == 3 => Ok([v[0], v[1], v[2]]),
Some(_) => Err("glyph-origin expects exactly three values"),
None => Ok([0.0, 0.0, 0.0]),
}
}
fn main() -> Result<(), StrError> {
let options = Options::from_args();
let in_path = Path::new(&options.input);
let fn_stem = in_path
.file_stem()
.ok_or("cannot get file stem")?
.to_str()
.ok_or("cannot convert file stem to str")?;
let mesh = Mesh::read(in_path)?;
if !options.skip_check {
mesh.check_all()?;
}
let mut draw = Draw::new();
draw.show_cells(!options.hide_cells)
.show_point_dots(options.dots)
.show_point_ids(options.point_ids)
.show_cell_ids(options.cell_ids)
.show_point_marker(options.point_markers)
.show_cell_marker(options.cell_markers)
.show_edge_markers(options.edge_markers)
.show_face_markers(options.face_markers)
.show_normal_vectors(options.normals)
.show_boundary_edges_3d(options.boundary_edges)
.show_boundary_faces(options.boundary_faces)
.set_view_flag(options.view);
if options.width.is_some() || options.height.is_some() {
draw.set_size(options.width.unwrap_or(800.0), options.height.unwrap_or(800.0));
}
if let Some(m_range) = options.m_range {
draw.set_m_range(m_range);
}
if let Some(m_normal_vector) = options.m_normal_vector {
draw.set_m_normal_vector(m_normal_vector);
}
if let Some(m_normal_vector_marker) = options.m_normal_vector_marker {
draw.set_m_normal_vector_marker(m_normal_vector_marker);
}
if mesh.ndim == 3 {
let elevation = options.elevation.unwrap_or(30.0);
let azimuth = options.azimuth.unwrap_or(30.0);
draw.set_camera(elevation, azimuth);
if let Some(enabled) = options.glyph_enabled {
draw.show_glyph_3d(enabled);
}
if options.glyph_origin.is_some() || options.glyph_size.is_some() {
let origin = get_glyph_origin(&options.glyph_origin)?;
let size = options.glyph_size.unwrap_or(1.0);
draw.set_glyph_3d(origin[0], origin[1], origin[2], size);
}
}
draw.all(&mesh, &format!("{}/{}.svg", OUT_DIR, fn_stem))?;
println!("Generated SVG file: {}/{}.svg", OUT_DIR, fn_stem);
Ok(())
}