diff --git a/Cargo.lock b/Cargo.lock index 662f474ac..36ede137e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2157,6 +2157,13 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "model-template" +version = "0.1.0" +dependencies = [ + "fj", +] + [[package]] name = "naga" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 1ac0c10ac..82bd418a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "2" members = [ "crates/fj", "crates/fj-app", + "crates/fj-app/model-template", "crates/fj-export", "crates/fj-host", "crates/fj-interop", diff --git a/crates/fj-app/build.rs b/crates/fj-app/build.rs index deb34d250..7821a1972 100644 --- a/crates/fj-app/build.rs +++ b/crates/fj-app/build.rs @@ -1,8 +1,7 @@ use ignore::WalkBuilder; use std::{collections::HashSet, env, ffi::OsStr, fs::File, path::Path}; -static NEW_MODEL_TEMPLATE: &str = "star"; -static EXTRA_IGNORED_FILES: &[&str] = &["star.png", "README.md"]; +static EXTRA_IGNORED_FILES: &[&str] = &["README.md"]; fn main() { create_new_model_tar(); @@ -14,13 +13,7 @@ fn create_new_model_tar() { let mut tar_builder = tar::Builder::new(file); let manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap(); - let fornjot_root_path = Path::new(&manifest_dir) - .ancestors() - .nth(2) - .expect("Failed to get 'fornjot_root_path' path"); - - let new_model_path = - fornjot_root_path.join("models").join(NEW_MODEL_TEMPLATE); + let new_model_path = Path::new(&manifest_dir).join("model-template"); let extra_ignored_files = EXTRA_IGNORED_FILES .iter() diff --git a/crates/fj-app/model-template/Cargo.toml b/crates/fj-app/model-template/Cargo.toml new file mode 100644 index 000000000..17cde8373 --- /dev/null +++ b/crates/fj-app/model-template/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "model-template" +version = "0.1.0" +edition = "2021" + +[dependencies.fj] +path = "../../fj" diff --git a/crates/fj-app/model-template/README.md b/crates/fj-app/model-template/README.md new file mode 100644 index 000000000..29281129f --- /dev/null +++ b/crates/fj-app/model-template/README.md @@ -0,0 +1,3 @@ +# Fornjot - Model Template + +This template is compiled into the `fj-app` binary, where it is used to generate new models. diff --git a/crates/fj-app/model-template/src/lib.rs b/crates/fj-app/model-template/src/lib.rs new file mode 100644 index 000000000..3d1775680 --- /dev/null +++ b/crates/fj-app/model-template/src/lib.rs @@ -0,0 +1,40 @@ +use std::f64::consts::PI; + +#[fj::model] +pub fn model( + #[param(default = 5, min = 3)] num_points: u64, + #[param(default = 1.0, min = 1.0)] r1: f64, + #[param(default = 2.0, min = 2.0)] r2: f64, + #[param(default = 1.0)] h: f64, +) -> fj::Shape { + let num_vertices = num_points * 2; + let vertex_iter = (0..num_vertices).map(|i| { + let angle = + fj::Angle::from_rad(2. * PI / num_vertices as f64 * i as f64); + let radius = if i % 2 == 0 { r1 } else { r2 }; + (angle, radius) + }); + + // Now that we got that iterator prepared, generating the vertices is just a + // bit of trigonometry. + let mut outer = Vec::new(); + let mut inner = Vec::new(); + for (angle, radius) in vertex_iter { + let (sin, cos) = angle.rad().sin_cos(); + + let x = cos * radius; + let y = sin * radius; + + outer.push([x, y]); + inner.push([x / 2., y / 2.]); + } + + let outer = fj::Sketch::from_points(outer); + let inner = fj::Sketch::from_points(inner); + + let footprint = fj::Difference2d::from_shapes([outer.into(), inner.into()]); + + let star = fj::Sweep::from_path(footprint.into(), [0., 0., h]); + + star.into() +} diff --git a/crates/fj-app/src/model_crate.rs b/crates/fj-app/src/model_crate.rs index bbfbc9797..95b6de17e 100644 --- a/crates/fj-app/src/model_crate.rs +++ b/crates/fj-app/src/model_crate.rs @@ -1,8 +1,6 @@ use std::{fs, path::Path}; use tar::Archive; -static NEW_MODEL_TEMPLATE: &str = "star"; - static NEW_MODEL_TAR: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/new_model.tar")); @@ -22,11 +20,11 @@ fn postprocess_model_files( &path.join("Cargo.toml"), [ ( - format!("name = \"{NEW_MODEL_TEMPLATE}\""), + "name = \"model-template\"".to_string(), format!("name = \"{model_name}\""), ), ( - r#"path = "../../crates/fj""#.to_owned(), + r#"path = "../../fj""#.to_owned(), ["version = \"", &fj::version::VERSION_PKG.to_string(), "\""] .concat(), ),