feature- Add variant of process_model that accepts Args rather than parsing them #2307

This commit is contained in:
rajgandhi1 2025-05-21 15:09:15 +05:30
parent 9683e65193
commit 4bea90d9d8
10 changed files with 215 additions and 27 deletions

9
Cargo.lock generated
View File

@ -686,6 +686,8 @@ checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
name = "cuboid"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"fj",
]
@ -1362,7 +1364,8 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
name = "holes"
version = "0.1.0"
dependencies = [
"cuboid",
"anyhow",
"clap",
"fj",
]
@ -3426,6 +3429,8 @@ dependencies = [
name = "spacer"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"fj",
]
@ -3468,6 +3473,8 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
name = "star"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"fj",
]

View File

@ -94,6 +94,59 @@ impl Instance {
Ok(())
}
/// Process a model with pre-parsed arguments
///
/// This function is similar to [`process_model`], but accepts pre-parsed arguments
/// instead of parsing them from the command line. This is useful when you want to
/// extend the standard arguments with your own parameters.
pub fn process_model_args<M>(&mut self, model: &M, args: Args) -> Result
where
for<'r> (&'r M, Tolerance): Triangulate,
for<'r> &'r M: BoundingVolume<3>,
{
tracing_subscriber::registry()
.with(tracing_subscriber::fmt::layer())
.with(tracing_subscriber::EnvFilter::from_default_env())
.init();
if !args.ignore_validation {
self.core.layers.validation.take_errors()?;
}
let aabb = model.aabb(&self.core.layers.geometry).unwrap_or(Aabb {
min: Point::origin(),
max: Point::origin(),
});
let tolerance = match args.tolerance {
None => {
let mut min_extent = Scalar::MAX;
for extent in aabb.size().components {
if extent > Scalar::ZERO && extent < min_extent {
min_extent = extent;
}
}
let tolerance = min_extent / Scalar::from_f64(1000.);
Tolerance::from_scalar(tolerance)?
}
Some(user_defined_tolerance) => user_defined_tolerance,
};
let tri_mesh = (model, tolerance).triangulate(&mut self.core);
if let Some(path) = args.export {
export::export(tri_mesh.all_triangles(), &path)?;
return Ok(());
}
make_viewer_and_spawn_thread(|viewer| {
viewer.display_model(tri_mesh);
})?;
Ok(())
}
}
/// Return value of [`Instance::process_model`]

View File

@ -3,5 +3,11 @@ name = "cuboid"
version = "0.1.0"
edition = "2021"
[dependencies.fj]
path = "../../crates/fj"
[[bin]]
name = "cuboid"
path = "src/main.rs"
[dependencies]
fj = { path = "../../crates/fj" }
clap = { version = "4.5", features = ["derive"] }
anyhow = "1.0"

View File

@ -1,6 +1,31 @@
fn main() -> fj::Result {
let mut fj = fj::Instance::new();
let model = cuboid::model([3., 2., 1.], &mut fj.core);
fj.process_model(&model)?;
use clap::Parser;
use fj::{Args, Instance};
#[derive(Parser)]
struct Parameters {
/// Size of the cuboid, as a comma-separated vector `x,y,z`
#[arg(long, value_parser = parse_vector_3)]
size: [f64; 3],
#[command(flatten)]
fj: Args,
}
fn parse_vector_3(arg: &str) -> anyhow::Result<[f64; 3]> {
Ok(arg
.split(',')
.map(str::parse)
.collect::<Result<Vec<f64>, _>>()?
.as_slice()
.try_into()?)
}
fn main() -> anyhow::Result<()> {
let mut fj = Instance::new();
let params = Parameters::parse();
let model = cuboid::model(params.size, &mut fj.core);
fj.process_model_args(&model, params.fj)?;
Ok(())
}

View File

@ -3,8 +3,11 @@ name = "holes"
version = "0.1.0"
edition = "2021"
[dependencies.fj]
path = "../../crates/fj"
[[bin]]
name = "holes"
path = "src/main.rs"
[dependencies.cuboid]
path = "../cuboid"
[dependencies]
fj = { path = "../../crates/fj" }
clap = { version = "4.5", features = ["derive"] }
anyhow = "1.0"

View File

@ -1,6 +1,23 @@
fn main() -> fj::Result {
let mut fj = fj::Instance::new();
let model = holes::model(0.25, &mut fj.core);
fj.process_model(&model)?;
use anyhow::Result;
use clap::Parser;
use fj::{Args, Instance};
#[derive(Parser)]
struct Parameters {
/// Radius of the holes
#[arg(long, default_value = "0.25")]
radius: f64,
#[command(flatten)]
fj: Args,
}
fn main() -> Result<()> {
let mut fj = Instance::new();
let params = Parameters::parse();
let model = holes::model(params.radius, &mut fj.core);
fj.process_model_args(&model, params.fj)?;
Ok(())
}

View File

@ -3,5 +3,11 @@ name = "spacer"
version = "0.1.0"
edition = "2021"
[dependencies.fj]
path = "../../crates/fj"
[[bin]]
name = "spacer"
path = "src/main.rs"
[dependencies]
fj = { path = "../../crates/fj" }
clap = { version = "4.5", features = ["derive"] }
anyhow = "1.0"

View File

@ -1,6 +1,36 @@
fn main() -> fj::Result {
let mut fj = fj::Instance::new();
let model = spacer::model(1., 0.5, 1., &mut fj.core);
fj.process_model(&model)?;
use anyhow::Result;
use clap::Parser;
use fj::{Args, Instance};
#[derive(Parser)]
struct Parameters {
/// Outer radius of the spacer
#[arg(long, default_value = "1.0")]
outer_radius: f64,
/// Inner radius of the spacer
#[arg(long, default_value = "0.5")]
inner_radius: f64,
/// Height of the spacer
#[arg(long, default_value = "1.0")]
height: f64,
#[command(flatten)]
fj: Args,
}
fn main() -> Result<()> {
let mut fj = Instance::new();
let params = Parameters::parse();
let model = spacer::model(
params.outer_radius,
params.inner_radius,
params.height,
&mut fj.core,
);
fj.process_model_args(&model, params.fj)?;
Ok(())
}

View File

@ -3,5 +3,11 @@ name = "star"
version = "0.1.0"
edition = "2021"
[dependencies.fj]
path = "../../crates/fj"
[[bin]]
name = "star"
path = "src/main.rs"
[dependencies]
fj = { path = "../../crates/fj" }
clap = { version = "4.5", features = ["derive"] }
anyhow = "1.0"

View File

@ -1,6 +1,41 @@
fn main() -> fj::Result {
let mut fj = fj::Instance::new();
let model = star::model(5, 1., 2., 1., &mut fj.core);
fj.process_model(&model)?;
use anyhow::Result;
use clap::Parser;
use fj::{Args, Instance};
#[derive(Parser)]
struct Parameters {
/// Number of points in the star
#[arg(long, default_value = "5")]
points: u64,
/// Inner radius of the star
#[arg(long, default_value = "1.0")]
inner_radius: f64,
/// Outer radius of the star
#[arg(long, default_value = "2.0")]
outer_radius: f64,
/// Height of the star
#[arg(long, default_value = "1.0")]
height: f64,
#[command(flatten)]
fj: Args,
}
fn main() -> Result<()> {
let mut fj = Instance::new();
let params = Parameters::parse();
let model = star::model(
params.points,
params.inner_radius,
params.outer_radius,
params.height,
&mut fj.core,
);
fj.process_model_args(&model, params.fj)?;
Ok(())
}