Source:
CONTRIBUTING.md— this page is rendered directly from the file in the repository. Edit it there.
Contributing to Slicer Engine
Thank you for your interest in contributing to Slicer Engine! This guide will help you get started with the codebase and development workflow.
Quick Start
- Fork the repository on GitHub
- Clone your fork:bash
git clone https://github.com/YOUR-USERNAME/slicer-engine.git cd slicer-engine - Build and test:bash
cargo build cargo test - Read the architecture: See ARCHITECTURE.md for a comprehensive overview
Before You Start
Essential Reading
- ARCHITECTURE.md — Complete system architecture with Mermaid diagrams
- README.md — Usage and quick start guide
- src/SLICING.md — Slicing algorithm deep-dive
Understanding the Codebase
The slicer is organized into focused modules:
src/
├── core.rs → Main slicing pipeline (start here!)
├── arachne/ → Variable-width wall generation
├── mesh/ → STL loading and transformations
├── gcode/ → G-code emission (multi-flavor)
├── settings/ → Configuration and validation
├── cli/ → Command-line interface
└── server/ → WebSocket API for web UIStart by reading: src/core.rs → process_mesh() function
Development Workflow
1. Set Up Your Environment
Install Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shInstall development tools:
rustup component add clippy rustfmtFor WebAssembly builds:
cargo install wasm-pack2. Create a Feature Branch
git checkout -b feature/your-feature-nameUse descriptive names:
feature/gyroid-infill-patternfix/arachne-thin-wall-crashdocs/explain-surface-detection
3. Make Your Changes
Code Style:
- Follow Rust idioms and conventions
- Use
cargo fmtto format code (enforced by CI) - Run
cargo clippyto catch common issues - Add doc comments (
///) for public APIs
Testing:
- Write tests for new functionality
- Use inline tests with
#[cfg(test)]modules - Run
cargo testfrequently during development - Ensure
cargo test --releasepasses before committing
Example test:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_collapse_depth_square() {
let paths = square_paths(10.0);
let d = find_collapse_depth(&paths);
assert!((d - 5.0).abs() < 0.02, "Expected ~5mm, got {}", d);
}
}4. Commit Your Changes
Commit message format:
type(scope): short description
Longer explanation if needed, wrapping at 72 characters.
Include motivation, context, and implementation notes.
Fixes #123Types:
feat:— New featurefix:— Bug fixdocs:— Documentation changesrefactor:— Code restructuring (no behavior change)test:— Adding or fixing testschore:— Build config, dependencies, etc.
Examples:
feat(arachne): add wall_distribution_count parameter
Allows distributing residual width across multiple innermost beads
instead of just the last one. Improves finish on tapered walls.
Fixes #45
---
fix(gcode): correct extrusion calculation for variable widths
Was using nozzle_diameter_mm for all paths; now uses per-path
width from Arachne. Fixes under-extrusion on thin-wall beads.
Fixes #675. Push and Create a Pull Request
git push origin feature/your-feature-nameThen open a PR on GitHub with:
- Clear title describing the change
- Description explaining what and why
- Link to issue if fixing a bug or implementing a feature request
- Screenshots/videos if changing UI or output quality
Code Quality Standards
Must Pass Before Merge
# Format check
cargo fmt --check
# Linting (zero warnings)
cargo clippy --all-targets --all-features -- -D warnings
# All tests passing
cargo test --release
# No compiler warnings
cargo build --release 2>&1 | grep warningOptional But Recommended
# Check for unused dependencies
cargo install cargo-udeps
cargo +nightly udeps
# Security audit
cargo install cargo-audit
cargo audit
# Check for outdated dependencies
cargo install cargo-outdated
cargo outdatedWhat to Contribute
Good First Issues
Look for issues labeled good first issue on GitHub. These are typically:
- Documentation improvements
- Adding tests for existing code
- Small bug fixes with clear reproduction steps
- Parameter validation rules
Ideas for Contributions
Features:
- New infill patterns (cubic, hilbert curve, lightning)
- Support structure generation
- Adaptive layer heights
- Ironing (smooth top surfaces)
- Sequential printing (object-by-object)
- Custom G-code insertion at layer changes
Improvements:
- Performance optimizations (profiling with
cargo flamegraph) - Better error messages
- More comprehensive tests
- Additional G-code flavors (RepRap, Prusa, etc.)
- UI enhancements
Documentation:
- Tutorial blog posts
- Video walkthroughs
- API documentation examples
- Translation to other languages
Areas That Need Help
Check the GitHub issues for:
help wanted— Community input desiredenhancement— Feature requestsbug— Known issues
Development Tips
Debugging
Add trace logging:
use crate::logging::ProcessLogger;
logger.log_debug(&format!("Collapse depth: {:.4}mm", depth));Visualize intermediate results:
// Export Clipper2 paths as SVG for inspection
use clipper2::*;
let svg = paths.to_svg(1000, 1000);
std::fs::write("debug.svg", svg)?;Profile performance:
cargo install flamegraph
cargo flamegraph --bin slicer-engine -- slice --input large.stl
# Opens flamegraph.svg in browserTesting Strategy
Unit tests: Test individual functions in isolation
#[test]
fn test_edge_intersect() {
let a = Vertex { x: 0.0, y: 0.0, z: 1.0 };
let b = Vertex { x: 10.0, y: 10.0, z: 3.0 };
let (x, y) = edge_intersect(a, b, 2.5);
assert_eq!(x, 7.5);
assert_eq!(y, 7.5);
}Integration tests: Test module interactions
#[test]
fn test_process_mesh_pipeline() {
let mesh = create_test_cube(10.0);
let params = SlicingParams::default();
let layers = process_mesh(&mesh, ¶ms, &NullLogger);
assert!(!layers.is_empty());
}Property-based tests: Use proptest or quickcheck for fuzzing
use proptest::prelude::*;
proptest! {
#[test]
fn test_collapse_depth_positive(side in 1.0..100.0f64) {
let paths = square_paths(side);
let d = find_collapse_depth(&paths);
assert!(d > 0.0 && d <= side / 2.0);
}
}Common Pitfalls
1. Clipper2 coordinate precision:
- Uses integer-based
Centi(centimeter precision) - Be careful with floating-point conversions
- Use simplify() after inflate() to remove duplicate points
2. Winding order:
- Outer contours = counter-clockwise
- Holes = clockwise
- Use
FillRule::EvenOddwhen winding isn't guaranteed
3. Path roles:
- Always set
path_roleswhen adding paths to a layer - Length must match
paths.len()or defaults toPerimeter
4. Settings defaults:
- Use
#[serde(default)]for new fields to maintain backward compatibility - Add default value functions:
fn default_my_param() -> T
5. Memory in loops:
- Avoid cloning large structures in hot paths
- Use
&references when possible - Profile with
cargo flamegraphif performance degrades
Documentation Standards
Code Comments
Doc comments (///) for public APIs:
/// Compute the collapse depth of a polygon.
///
/// The collapse depth D is the largest inward offset at which the polygon
/// is still non-empty. It equals the polygon's inradius (half the minimum
/// local wall thickness).
///
/// # Arguments
/// * `input` - The polygon paths to analyze
///
/// # Returns
/// The collapse depth in millimeters, or 0.0 if the polygon is degenerate.
///
/// # Example
/// ```
/// let square = square_paths(10.0);
/// let depth = find_collapse_depth(&square);
/// assert_eq!(depth, 5.0); // Half the side length
/// ```
pub fn find_collapse_depth(input: &Paths) -> f64 {
// ...
}Inline comments for complex logic:
// Strategy: binary search the collapse depth using Clipper2 inflate().
// 24 iterations give sub-nanometer precision on a 500mm bbox.
for _ in 0..COLLAPSE_DEPTH_ITERATIONS {
let mid = (lo + hi) / 2.0;
// ...
}Markdown Documentation
Update existing docs when adding features:
ARCHITECTURE.md— High-level architecture changesREADME.md— User-facing feature descriptions- Module READMEs — Implementation details
Add Mermaid diagrams for visual clarity:
## Data Flow
\`\`\`mermaid
graph LR
A[Input] --> B[Process]
B --> C[Output]
\`\`\`Pull Request Checklist
Before submitting your PR, ensure:
- [ ] Code builds:
cargo build --release - [ ] All tests pass:
cargo test --release - [ ] Linting passes:
cargo clippy --all-targets --all-features -- -D warnings - [ ] Code is formatted:
cargo fmt - [ ] New code has tests
- [ ] Public APIs have doc comments
- [ ] ARCHITECTURE.md updated if architecture changed
- [ ] README.md updated if user-facing features added
- [ ] Commit messages follow the format
- [ ] PR description explains what/why/how
Getting Help
- Questions: Open a GitHub Discussion
- Bugs: Open an Issue
- Architecture: Read ARCHITECTURE.md
- Chat: (Add Discord/Matrix/IRC if available)
Code of Conduct
Be respectful, constructive, and inclusive. We're all here to learn and build something awesome together.
Expected behavior:
- Be welcoming to newcomers
- Provide constructive feedback on PRs
- Assume good intentions
- Focus on the code, not the person
Unacceptable:
- Harassment, trolling, or personal attacks
- Discriminatory language or behavior
- Spam or off-topic discussions
Violations will result in comment deletion, temporary bans, or permanent bans depending on severity.
License
By contributing, you agree that your contributions will be licensed under the same license as the project (see LICENSE file).
Thank you for contributing! Every contribution, no matter how small, helps make this project better. 🚀