Skip to content

Commit

Permalink
very simple clap implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
coillteoir committed Oct 29, 2024
1 parent ad9f211 commit 6578f08
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 112 deletions.
2 changes: 2 additions & 0 deletions annoying.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ cargo clippy -- \
-Wclippy::nursery \
-Wclippy::cargo \
-Wclippy::suspicious \
-Wclippy::complexity \
-Wclippy::style \
-Wclippy::perf
26 changes: 26 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
description = "A very basic flake";

inputs = {
nixpkgs.url = "github:nixos/nixpkgs";
};

outputs = {
self,
nixpkgs,
}: let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.${system}.default = pkgs.mkShell {
buildInputs = [
pkgs.vim
pkgs.cargo
pkgs.clippy
pkgs.rustfmt
pkgs.f3d
pkgs.git
];
};
packages.x86_64-linux.default = pkgs.rustPlatform.buildRustPackage rec {
name = "kodama";
src = ./.;

cargoHash = "sha256-U9Un9x9EfIrJ2Zmem935SIes3KF2Aq8eip5u4PkBWFI=";
};
};
}
7 changes: 0 additions & 7 deletions shell.nix

This file was deleted.

34 changes: 0 additions & 34 deletions src/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,8 @@
use crate::shape::{cone, cube, cuboid, sphere, Point};

#[derive(Debug, Clone)]
struct Token {}

fn validate_braces(source: &str) -> Result<(), String> {
let braces = String::from(source)
.chars()
.filter(|c| (*c == '{' || *c == '}'))
.collect::<Vec<char>>();

if braces.len() % 2 != 0 {
return Err(String::from("invalid amount of braces"));
}
let mut stack = Vec::<char>::new();
for brace in braces.into_iter() {
if brace == '{' {
stack.push(brace);
}

if brace == '}' {
stack.pop();
}
}
if !stack.is_empty() {
return Err(String::from("mismatched braces"));
}
Ok(())
}

fn parser(data: &str) -> Result<String, String> {
let _ = validate_braces(data);
Ok(String::from("yay"))
}

pub fn compile(data: &str) -> Result<String, String> {
let mut result = String::new();
let lines = data.split('\n');
let _ = parser(data);

for line in lines {
let tokens: Vec<&str> = line.split(' ').collect();
Expand Down
28 changes: 8 additions & 20 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,23 @@
use clap::Parser;
use kodama::compiler::compile;
use std::ffi::OsStr;
use kodama::compiler::*;
use std::fs;
use std::path::Path;

#[derive(Parser)]
#[command(author = "David Lynch", about = "3d modelling but epic")]
struct Args {
#[arg(help = "source file")]
#[arg(short, long, help = "source file")]
source: String,
#[arg(help = "output file")]
#[arg(short, long, help = "output file")]
output: String,
}

fn main() {
let args = Args::parse();

let source_path = Path::new(&args.source);
let output_path = Path::new(&args.output);

if source_path.extension().and_then(OsStr::to_str) != Some("kda") {
eprintln!("please specify a kodama source file");
return;
}

let source = fs::read_to_string(source_path).expect("couldn't load source file");

match output_path.extension().and_then(OsStr::to_str) {
Some("obj") => fs::write(output_path, compile(&source).expect("ehhe"))
.expect("could not write output file"),
Some(other) => eprintln!("file type {other} not supported"),
None => eprintln!("specify an output file type"),
let contents = fs::read_to_string(args.source).expect("File not found");
if let Ok(result) = compile(&contents) {
if let Err(e) = fs::write(args.output, result) {
panic!("{}", e)
}
}
}
101 changes: 50 additions & 51 deletions src/shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,31 @@ impl Point {
pub const fn new(x: f32, y: f32, z: f32) -> Self {
Self { x, y, z }
}
pub fn to_obj_string(self) -> String {
pub fn to_obj_string(&self) -> String {
format!("v {0} {1} {2}", self.x, self.y, self.z)
}
}

#[derive(Clone)]
struct Face<'lt> {
points: &'lt Vec<Point>,
indexes: Vec<u32>,
points: &'lt [Point],
indexes: &'lt [u32],
}

impl<'lt> Face<'lt> {
pub fn new(points: &'lt Vec<Point>, indexes: Vec<u32>) -> Self {
pub fn new(points: &'lt [Point], indexes: &'lt [u32]) -> Self {
Self { points, indexes }
}

pub fn to_obj_string(self) -> String {
pub fn to_obj_string(&self) -> String {
let mut result = String::from("f ");

result.push_str(
&self
.indexes
.clone()
.into_iter()
.map(|i: u32| -> String {
format!("-{0}", (self.points.len() as u64 - u64::from(i)))
.iter()
.map(|i: &u32| -> String {
format!("-{0}", (self.points.len() as u64 - u64::from(*i)))
})
.collect::<Vec<String>>()
.join(" "),
Expand All @@ -45,23 +44,23 @@ impl<'lt> Face<'lt> {
}
}

fn vertex_string(points: Vec<Point>) -> String {
fn vertex_string(points: &[Point]) -> String {
points
.into_iter()
.iter()
.map(Point::to_obj_string)
.collect::<Vec<String>>()
.join("\n")
}

fn render_obj(points: &[Point], faces: Vec<Face>) -> String {
fn render_obj(points: &[Point], faces: &[Face]) -> String {
format!(
r#"{0}
{1}
"#,
vertex_string(points.to_vec()),
vertex_string(points),
faces
.into_iter()
.map(Face::to_obj_string)
.iter()
.map(|f: &Face| Face::to_obj_string(f))
.collect::<Vec<String>>()
.join("\n")
)
Expand All @@ -74,71 +73,71 @@ pub fn sphere(origin: Point, radius: f32, _detail: u32) -> Result<String, String
// Create faces procedurally
// To start we'll create a simple octahedron

let top = Point::new(origin.x, origin.y + (radius * (PI / 2.0).sin()), origin.z);
let bottom = Point::new(origin.x, origin.y + (radius * (PI / -2.0).sin()), origin.z);
let north = Point::new(origin.x, origin.y, origin.z + (radius * (PI / 2.0).sin()));
let south = Point::new(origin.x, origin.y, origin.z + (radius * (PI / -2.0).sin()));
let top = Point::new(origin.x, origin.y + (radius * (PI / 2.).sin()), origin.z);
let bottom = Point::new(origin.x, origin.y + (radius * (PI / -2.).sin()), origin.z);
let north = Point::new(origin.x, origin.y, origin.z + (radius * (PI / 2.).sin()));
let south = Point::new(origin.x, origin.y, origin.z + (radius * (PI / -2.).sin()));
let east = Point::new(origin.x + (radius * (0.0_f32).cos()), origin.y, origin.z);
let west = Point::new(origin.x + (radius * (PI).cos()), origin.y, origin.z);

let points = vec![top, bottom, north, south, east, west];
let points = [top, bottom, north, south, east, west];

let faces = vec![
let faces = [
// top, north, east
Face::new(&points, vec![0, 2, 4]),
Face::new(&points, &[0, 2, 4]),
// top, north, west
Face::new(&points, vec![0, 2, 5]),
Face::new(&points, &[0, 2, 5]),
// top, south, east
Face::new(&points, vec![0, 3, 4]),
Face::new(&points, &[0, 3, 4]),
// top, south, west
Face::new(&points, vec![0, 3, 5]),
Face::new(&points, &[0, 3, 5]),
// bottom, north, east
Face::new(&points, vec![1, 2, 4]),
Face::new(&points, &[1, 2, 4]),
// bottom, north, west
Face::new(&points, vec![1, 2, 5]),
Face::new(&points, &[1, 2, 5]),
// bottom, south, east
Face::new(&points, vec![1, 3, 4]),
Face::new(&points, &[1, 3, 4]),
// bottom, south, west
Face::new(&points, vec![1, 3, 5]),
Face::new(&points, &[1, 3, 5]),
];

Ok(render_obj(&points, faces))
Ok(render_obj(&points, &faces))
}

pub fn cone(origin: Point, _detail: i32, _radius: f32) -> String {
let points = vec![
let points = [
Point::new(origin.x, origin.y + (PI / 3.0).sin(), origin.z),
Point::new(origin.x, origin.y, origin.z + 0.0_f32.cos()),
Point::new(
origin.x + (4.0 * PI / 3.0).sin(),
origin.x + (4. * PI / 3.).sin(),
origin.y,
(2.0 * -PI / 3.0).cos(),
(2. * -PI / 3.).cos(),
),
Point::new(
origin.x + (2.0 * PI / 3.0).sin(),
origin.x + (2. * PI / 3.).sin(),
origin.y,
(2.0 * -PI / 3.0).cos(),
(2. * -PI / 3.).cos(),
),
];

let faces = vec![
Face::new(&points, vec![1, 2, 3]),
Face::new(&points, vec![0, 2, 3]),
Face::new(&points, vec![0, 1, 3]),
Face::new(&points, vec![0, 2, 1]),
let faces = [
Face::new(&points, &[1, 2, 3]),
Face::new(&points, &[0, 2, 3]),
Face::new(&points, &[0, 1, 3]),
Face::new(&points, &[0, 2, 1]),
];

render_obj(&points, faces)
render_obj(&points, &faces)
}

pub fn cuboid(origin: Point, sx: f32, sy: f32, sz: f32) -> Result<String, String> {
if sx <= 0.0 || sy <= 0.0 || sz <= 0.0 {
if sx <= 0. || sy <= 0. || sz <= 0. {
return Err(String::from(
"could not generate cuboid, side length less than or equal to zero",
));
}

let points = vec![
let points = [
Point::new(origin.x, origin.y + sy, origin.z + sz),
Point::new(origin.x, origin.y, origin.z + sz),
Point::new(origin.x + sx, origin.y, origin.z + sz),
Expand All @@ -149,16 +148,16 @@ pub fn cuboid(origin: Point, sx: f32, sy: f32, sz: f32) -> Result<String, String
Point::new(origin.x + sx, origin.y + sy, origin.z),
];

let faces = vec![
Face::new(&points, vec![0, 1, 2, 3]),
Face::new(&points, vec![7, 6, 5, 4]),
Face::new(&points, vec![4, 5, 1, 0]),
Face::new(&points, vec![3, 7, 4, 0]),
Face::new(&points, vec![3, 2, 6, 7]),
Face::new(&points, vec![6, 2, 1, 5]),
let faces = [
Face::new(&points, &[0, 1, 2, 3]),
Face::new(&points, &[7, 6, 5, 4]),
Face::new(&points, &[4, 5, 1, 0]),
Face::new(&points, &[3, 7, 4, 0]),
Face::new(&points, &[3, 2, 6, 7]),
Face::new(&points, &[6, 2, 1, 5]),
];

Ok(render_obj(&points, faces))
Ok(render_obj(&points, &faces))
}

pub fn cube(origin: Point, size: f32) -> Result<String, String> {
Expand Down

0 comments on commit 6578f08

Please sign in to comment.