Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
70e7e2a35a | |||
b6b6620105 | |||
18d15b0abe | |||
5c85efedde |
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -4491,6 +4491,7 @@ name = "slicer"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"common",
|
||||
"criterion",
|
||||
"goo_format",
|
||||
|
47
default.nix
Normal file
47
default.nix
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
libglvnd,
|
||||
libxkbcommon,
|
||||
rustPlatform,
|
||||
vulkan-loader,
|
||||
wayland,
|
||||
}:
|
||||
rustPlatform.buildRustPackage {
|
||||
name = "mslicer";
|
||||
src = ./.;
|
||||
|
||||
cargoHash = "sha256-mRbEwxR6bMkybxe7H1dX4Qa1elGiw/lSSz9sSTtp1zw=";
|
||||
useFetchCargoVendor = true;
|
||||
|
||||
buildInputs = [
|
||||
libglvnd
|
||||
libxkbcommon
|
||||
vulkan-loader
|
||||
wayland
|
||||
];
|
||||
|
||||
NIX_LDFLAGS = [
|
||||
"--push-state"
|
||||
"--no-as-needed"
|
||||
"-lEGL"
|
||||
"-lvulkan"
|
||||
"-lwayland-client"
|
||||
"-lxkbcommon"
|
||||
"--pop-state"
|
||||
];
|
||||
|
||||
doInstallCheck = true;
|
||||
installCheckPhase = ''
|
||||
runHook preInstallCheck
|
||||
|
||||
# spot-check the binaries
|
||||
$out/bin/goo_format --help
|
||||
# these other binaries can't be invoked w/ interactivity or real data:
|
||||
test -x $out/bin/mslicer
|
||||
test -x $out/bin/remote_send
|
||||
test -x $out/bin/slicer
|
||||
|
||||
runHook postInstallCheck
|
||||
'';
|
||||
|
||||
strictDeps = true;
|
||||
}
|
26
flake.lock
generated
Normal file
26
flake.lock
generated
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1743315132,
|
||||
"narHash": "sha256-6hl6L/tRnwubHcA4pfUUtk542wn2Om+D4UnDhlDW9BE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "52faf482a3889b7619003c0daec593a1912fddc1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-unstable",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
19
flake.nix
Normal file
19
flake.nix
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs }:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
};
|
||||
in
|
||||
{
|
||||
packages.${system}.default = pkgs.callPackage ./default.nix { };
|
||||
devShells.${system}.default = with pkgs; mkShell {
|
||||
inputsFrom = [ self.packages.${system}.default ];
|
||||
};
|
||||
};
|
||||
}
|
@@ -5,6 +5,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
clap.workspace = true
|
||||
image.workspace = true
|
||||
nalgebra.workspace = true
|
||||
obj-rs.workspace = true
|
||||
|
@@ -1,11 +1,13 @@
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::{stdout, BufReader, Write},
|
||||
path::PathBuf,
|
||||
thread,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use nalgebra::{Vector2, Vector3};
|
||||
|
||||
use common::{
|
||||
@@ -16,9 +18,26 @@ use common::{
|
||||
use goo_format::{File as GooFile, LayerEncoder};
|
||||
use slicer::{mesh::load_mesh, slicer::Slicer, Pos};
|
||||
|
||||
#[derive(Parser)]
|
||||
struct Args {
|
||||
/// Path to the .stl file
|
||||
input_file: PathBuf,
|
||||
/// Path to the .goo file
|
||||
output_file: PathBuf,
|
||||
|
||||
/// Rotate the model (in degrees, about the z axis) before slicing it
|
||||
#[clap(long)]
|
||||
rotate_xy: Option<f32>,
|
||||
/// Rotate the model (in degrees, about the y axis) before slicing it
|
||||
#[clap(long)]
|
||||
rotate_xz: Option<f32>,
|
||||
/// Rotate the model (in degrees, about the x axis) before slicing it
|
||||
#[clap(long)]
|
||||
rotate_yz: Option<f32>,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
const FILE_PATH: &str = "teapot.stl";
|
||||
const OUTPUT_PATH: &str = "output.goo";
|
||||
let args = Args::parse();
|
||||
|
||||
let slice_config = SliceConfig {
|
||||
format: Format::Goo,
|
||||
@@ -39,9 +58,22 @@ fn main() -> Result<()> {
|
||||
transition_layers: 10,
|
||||
};
|
||||
|
||||
let file = File::open(FILE_PATH)?;
|
||||
let file = File::open(args.input_file)?;
|
||||
let mut buf = BufReader::new(file);
|
||||
let mut mesh = load_mesh(&mut buf, "stl")?;
|
||||
|
||||
let mut rotate = mesh.rotation();
|
||||
if let Some(r) = args.rotate_xy {
|
||||
rotate.z += r.to_radians();
|
||||
}
|
||||
if let Some(r) = args.rotate_xz {
|
||||
rotate.y += r.to_radians();
|
||||
}
|
||||
if let Some(r) = args.rotate_yz {
|
||||
rotate.x += r.to_radians();
|
||||
}
|
||||
mesh.set_rotation(rotate);
|
||||
|
||||
let (min, max) = mesh.bounds();
|
||||
|
||||
// Scale the model into printer-space (mm => px)
|
||||
@@ -52,6 +84,11 @@ fn main() -> Result<()> {
|
||||
real_scale,
|
||||
));
|
||||
|
||||
let mesh_size = max - min;
|
||||
if mesh_size.x > slice_config.platform_size.x || mesh_size.y > slice_config.platform_size.y || mesh_size.z > slice_config.platform_size.z {
|
||||
eprintln!("WARNING: model bounds ({}) exceeds printer bounds ({}); print may be truncated", mesh_size, slice_config.platform_size);
|
||||
}
|
||||
|
||||
// Center the model
|
||||
let center = slice_config.platform_resolution / 2;
|
||||
let mesh_center = (min + max) / 2.0;
|
||||
@@ -90,7 +127,7 @@ fn main() -> Result<()> {
|
||||
// Once slicing is complete write to a .goo file
|
||||
let mut serializer = DynamicSerializer::new();
|
||||
goo.join().unwrap().serialize(&mut serializer);
|
||||
fs::write(OUTPUT_PATH, serializer.into_inner())?;
|
||||
fs::write(args.output_file, serializer.into_inner())?;
|
||||
|
||||
println!("\nDone. Elapsed: {:.1}s", now.elapsed().as_secs_f32());
|
||||
|
||||
|
Reference in New Issue
Block a user