You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
6.6 KiB
Rust
208 lines
6.6 KiB
Rust
#![warn(
|
|
clippy::all,
|
|
clippy::pedantic,
|
|
//clippy::cargo,
|
|
//rust_2024_compatibility,
|
|
)]
|
|
//#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
|
|
|
extern crate dxf;
|
|
extern crate simple_xml_builder;
|
|
extern crate unicode_segmentation;
|
|
|
|
use anyhow::{Context, Ok, Result};
|
|
use clap::Parser;
|
|
use dxf::entities::EntityType;
|
|
use dxf::Drawing;
|
|
use qelmt::Definition;
|
|
//use rayon::prelude::*;
|
|
use simple_xml_builder::XMLElement;
|
|
use std::time::Instant;
|
|
use std::{io, path::PathBuf};
|
|
use tracing::{span, trace, warn, Level};
|
|
use tracing_subscriber::prelude::*;
|
|
|
|
#[cfg(feature = "venator")]
|
|
use venator::Venator;
|
|
|
|
mod qelmt;
|
|
|
|
#[derive(Parser, Debug)]
|
|
#[command(name = "dxf2elmt")]
|
|
#[command(author, version, about = "A CLI program to convert .dxf files into .elmt files", long_about = None)]
|
|
struct Args {
|
|
/// The .dxf file to convert
|
|
//#[clap(short, long, value_parser)]
|
|
file_names: Vec<PathBuf>,
|
|
|
|
/// Activates verbose output, eliminates .elmt file writing
|
|
#[clap(short, long, value_parser, default_value_t = false)]
|
|
verbose: bool,
|
|
|
|
/// Converts text entities into dynamic text instead of the default text box
|
|
#[clap(short, long, value_parser, default_value_t = false)]
|
|
dtext: bool,
|
|
|
|
/// Determine the number of lines you want each spline to have (more lines = greater resolution)
|
|
#[clap(short, long, value_parser, default_value_t = 20)]
|
|
spline_step: u32,
|
|
|
|
/// Toggles information output... defaults to off
|
|
#[clap(short, long, value_parser, default_value_t = false)]
|
|
info: bool,
|
|
}
|
|
|
|
pub mod file_writer;
|
|
|
|
#[allow(clippy::too_many_lines)]
|
|
fn main() -> Result<()> {
|
|
#[cfg(feature = "venator")]
|
|
let tr_reg = tracing_subscriber::registry()
|
|
.with(Venator::default())
|
|
.with(tracing_subscriber::fmt::Layer::default());
|
|
|
|
#[cfg(not(feature = "venator"))]
|
|
let tr_reg = {
|
|
let file_layer =
|
|
if let std::result::Result::Ok(file) = std::fs::File::create("dxf2elmt.log") {
|
|
//if we can create a log file use it
|
|
Some(tracing_subscriber::fmt::layer().with_writer(std::sync::Arc::new(file)))
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let stde_layer = tracing_subscriber::fmt::layer()
|
|
.pretty()
|
|
.with_writer(io::stderr);
|
|
tracing_subscriber::registry()
|
|
.with(file_layer.map(|fl| {
|
|
fl.with_file(true)
|
|
.with_line_number(true)
|
|
.with_thread_ids(true)
|
|
.with_ansi(false)
|
|
.with_filter(tracing_subscriber::EnvFilter::from_env("DXF2E_LOG"))
|
|
}))
|
|
.with(
|
|
stde_layer
|
|
.with_file(true)
|
|
.with_line_number(true)
|
|
.with_thread_ids(true)
|
|
.with_filter(tracing_subscriber::EnvFilter::from_env("DXF2E_LOG")),
|
|
)
|
|
};
|
|
tr_reg.init();
|
|
|
|
trace!("Starting dxf2elmt");
|
|
|
|
// Start recording time
|
|
let now: Instant = Instant::now();
|
|
|
|
// Collect arguments
|
|
let args: Args = Args::parse_from(wild::args());
|
|
|
|
// Load dxf file
|
|
let dxf_loop_span = span!(Level::TRACE, "Looping over dxf files");
|
|
let dxf_loop_guard = dxf_loop_span.enter();
|
|
for file_name in args.file_names {
|
|
let friendly_file_name = file_name
|
|
.file_stem()
|
|
.unwrap_or_else(|| file_name.as_os_str())
|
|
.to_string_lossy();
|
|
let drawing: Drawing = Drawing::load_file(&file_name).context(format!(
|
|
"Failed to load {friendly_file_name}...\n\tMake sure the file is a valid .dxf file.",
|
|
))?;
|
|
let q_elmt = Definition::new(friendly_file_name.clone(), args.spline_step, &drawing);
|
|
if !args.verbose && args.info {
|
|
println!("{friendly_file_name} loaded...");
|
|
}
|
|
|
|
// Initialize counts
|
|
let mut circle_count: u32 = 0;
|
|
let mut line_count: u32 = 0;
|
|
let mut arc_count: u32 = 0;
|
|
let mut spline_count: u32 = 0;
|
|
let mut text_count: u32 = 0;
|
|
let mut ellipse_count: u32 = 0;
|
|
let mut polyline_count: u32 = 0;
|
|
let mut lwpolyline_count: u32 = 0;
|
|
let mut solid_count: u32 = 0;
|
|
let mut block_count: u32 = 0;
|
|
let mut other_count: u32 = 0;
|
|
|
|
// Loop through all entities, counting the element types
|
|
//drawing.entities().for_each(|e| match e.specific {
|
|
drawing.entities().for_each(|e| match e.specific {
|
|
EntityType::Circle(ref _circle) => {
|
|
circle_count += 1;
|
|
}
|
|
EntityType::Line(ref _line) => {
|
|
line_count += 1;
|
|
}
|
|
EntityType::Arc(ref _arc) => {
|
|
arc_count += 1;
|
|
}
|
|
EntityType::Spline(ref _spline) => {
|
|
spline_count += 1;
|
|
}
|
|
EntityType::Text(ref _text) => {
|
|
text_count += 1;
|
|
}
|
|
EntityType::Ellipse(ref _ellipse) => {
|
|
ellipse_count += 1;
|
|
}
|
|
EntityType::Polyline(ref _polyline) => {
|
|
polyline_count += 1;
|
|
}
|
|
EntityType::LwPolyline(ref _lwpolyline) => {
|
|
lwpolyline_count += 1;
|
|
}
|
|
EntityType::Solid(ref _solid) => {
|
|
solid_count += 1;
|
|
}
|
|
EntityType::Insert(ref _insert) => {
|
|
block_count += 1;
|
|
}
|
|
_ => {
|
|
other_count += 1;
|
|
}
|
|
});
|
|
|
|
// Create output file for .elmt
|
|
let out_file = file_writer::create_file(args.verbose, args.info, &file_name)?;
|
|
|
|
// Write to output file
|
|
let out_xml = XMLElement::from(&q_elmt);
|
|
out_xml
|
|
.write(&out_file)
|
|
.context("Failed to write output file.")?;
|
|
|
|
if args.info {
|
|
println!("Conversion complete!\n");
|
|
|
|
// Print stats
|
|
println!("STATS");
|
|
println!("~~~~~~~~~~~~~~~");
|
|
println!("Circles: {circle_count}");
|
|
println!("Lines: {line_count}");
|
|
println!("Arcs: {arc_count}");
|
|
println!("Splines: {spline_count}");
|
|
println!("Texts: {text_count}");
|
|
println!("Ellipses: {ellipse_count}");
|
|
println!("Polylines: {polyline_count}");
|
|
println!("LwPolylines: {lwpolyline_count}");
|
|
println!("Solids: {solid_count}");
|
|
println!("Blocks: {block_count}");
|
|
println!("Currently Unsupported: {other_count}");
|
|
|
|
println!("\nTime Elapsed: {} ms", now.elapsed().as_millis());
|
|
}
|
|
|
|
if args.verbose {
|
|
print!("{out_xml}");
|
|
}
|
|
}
|
|
drop(dxf_loop_guard);
|
|
|
|
Ok(())
|
|
}
|