Skip to content

feurer98/PIXEstL

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

192 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Note: This is a personal project ported with Claude. Neither the documentation nor the code has been fully checked. WIP

PIXEstL - Rust Edition

Color Lithophane Generator for 3D Printing with Multi-Filament Support

Rust port of the original PIXEstL Java application by gaugo87. Generate stunning color lithophanes for 3D printing using CMYK-based additive color mixing with automatic material system (AMS) support.

Tests Rust License

Features

  • 🎨 CMYK Additive Color Mixing - Realistic color reproduction with transparent filaments
  • πŸ”¬ CIELab Color Matching - Perceptually uniform color distance for accurate matching
  • πŸš€ Parallel Processing - Multi-threaded mesh generation using Rayon
  • 🎯 Bambu Lab AMS Support - Automatic multi-group filament swapping
  • πŸ“ Physical Dimensions - Direct millimeter-based sizing for accurate prints
  • πŸ—οΈ Dual Layer Support - Separate color and texture (brightness) layers
  • πŸ’Ύ STL Export - ASCII and binary STL formats with ZIP packaging
  • ⚑ Run-Length Encoding - Optimized mesh generation

Quick Start

Prerequisites

  • Rust 1.75 or later β€” Install via rustup:
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  • Modern CPU (multi-core recommended)
  • ~100 MB RAM for typical images

Installation

# Clone the repository
git clone https://github.com/feurer98/PIXEstL.git
cd PIXEstL/rust

# Build release binary
cargo build --release

# Binary will be at: target/release/pixestl

Basic Usage

pixestl \
  --input image.png \
  --palette palette.json \
  --output lithophane.zip \
  --width 100

This will:

  1. Load image.png and resize to 100mm width
  2. Load color palette from palette.json
  3. Generate color lithophane layers
  4. Export STL files to lithophane.zip

A ready-to-use palette file is provided in the palette/ directory of the repository.

Usage

Command-Line Options

Required Arguments:

  • -i, --input <FILE> - Input image file (PNG, JPG, etc.)
  • -p, --palette <FILE> - Palette JSON file
  • -o, --output <FILE> - Output ZIP file

Image Dimensions:

  • -w, --width <MM> - Destination width in millimeters (0 = auto)
  • -H, --height <MM> - Destination height in millimeters (0 = auto)

Color Layer Settings:

  • --color-pixel-width <MM> - Size of each color pixel (default: 0.8)
  • --color-layer-thickness <MM> - Thickness per layer (default: 0.1)
  • --color-layers <N> - Number of layers (default: 5)
  • --no-color - Disable color layers

Texture Layer Settings:

  • --texture-pixel-width <MM> - Size of each texture pixel (default: 0.25)
  • --texture-min <MM> - Minimum texture thickness (default: 0.3)
  • --texture-max <MM> - Maximum texture thickness (default: 1.8)
  • --texture-color <HEX> - Filament color for texture layer (default: #FFFFFF)
  • --no-texture - Disable texture layer

Export Options:

  • --format <ascii|binary> - STL format (default: ascii)
  • --plate-thickness <MM> - Base plate thickness (default: 0.2)

Advanced Options:

  • --color-distance <rgb|cie-lab> - Color matching method (default: cie-lab)
  • --pixel-method <additive|full> - Color creation method (default: additive)
  • --color-number <N> - Limit colors per AMS group (0 = all)
  • -C, --curve <DEG> - Curve angle in degrees for cylindrical lithophanes (default: 0)
  • --debug - Enable debug output

Special Modes:

  • --palette-info - Show palette information and exit (no input/output required)
  • --calibrate - Generate a calibration pattern instead of processing an image

Examples

100mm wide lithophane with 5 color layers:

pixestl -i photo.jpg -p palette.json -o output.zip -w 100

80x120mm with texture layer only:

pixestl -i landscape.png -p palette.json -o output.zip \
  -w 80 -H 120 --no-color

High-resolution color lithophane:

pixestl -i portrait.png -p palette.json -o output.zip \
  -w 150 --color-pixel-width 0.4 --color-layers 7

Binary STL format (smaller files):

pixestl -i image.png -p palette.json -o output.zip \
  -w 100 --format binary

Palette Format

Palettes are defined in JSON with HSL or hex color definitions:

{
  "#FF0000": {
    "name": "Red",
    "active": true,
    "layers": {
      "5": { "H": 0, "S": 100, "L": 50 }
    }
  },
  "#00FF00": {
    "name": "Green", 
    "active": true,
    "layers": {
      "5": { "H": 120, "S": 100, "L": 50 }
    }
  },
  "#FFFFFF": {
    "name": "White",
    "active": true,
    "layers": {
      "1": "#FFFFFF"
    }
  }
}

Note: White (#FFFFFF) is required for proper color mixing.

Library Usage

use pixestl::{
    LithophaneConfig, LithophaneGenerator,
    PaletteLoader, PaletteLoaderConfig,
    export_to_zip, StlFormat,
};
use std::path::Path;

fn main() -> pixestl::Result<()> {
    // Load image
    let image = pixestl::image::load_image(Path::new("input.png"))?;
    
    // Load palette
    let palette_config = PaletteLoaderConfig {
        nb_layers: 5,
        creation_method: pixestl::PixelCreationMethod::Additive,
        color_number: 0,
        distance_method: pixestl::color::ColorDistanceMethod::CieLab,
    };
    let palette = PaletteLoader::load(Path::new("palette.json"), palette_config)?;
    
    // Generate lithophane
    let config = LithophaneConfig {
        dest_width_mm: 100.0,
        dest_height_mm: 0.0,
        ..Default::default()
    };
    let generator = LithophaneGenerator::new(config)?;
    let layers = generator.generate(&image, &palette)?;
    
    // Export to ZIP
    export_to_zip(&layers, "output.zip", StlFormat::Binary)?;
    
    Ok(())
}

Architecture

Module Structure

pixestl/
β”œβ”€β”€ color/          # Color space conversions (RGB, HSL, CIELab, CMYK)
β”œβ”€β”€ palette/        # Palette loading, color combinations, quantization
β”œβ”€β”€ image/          # Image loading, resizing, processing
β”œβ”€β”€ lithophane/     # Core mesh generation algorithms
β”‚   β”œβ”€β”€ config      # Configuration and validation
β”‚   β”œβ”€β”€ geometry    # 3D primitives (Vector3, Triangle, Mesh)
β”‚   β”œβ”€β”€ color_layer # Color layer mesh generation
β”‚   β”œβ”€β”€ texture_layer # Texture layer mesh generation
β”‚   └── support_plate # Base plate generation
β”œβ”€β”€ stl/            # STL export (ASCII/binary) and ZIP packaging
└── cli/            # Command-line interface

Key Algorithms

Color Matching:

  • Converts image to CIELab color space
  • Computes Delta E distance to palette colors
  • Parallel processing with Rayon

Color Layer Generation:

  • Stacks transparent CMYK layers
  • Run-length encoding for consecutive identical pixels
  • Parallel row-based processing

Texture Layer Generation:

  • Converts to grayscale using standard luminance formula
  • Maps brightness to thickness: thickness = min + K * (max - min)
  • Triangulated surface mesh with edge handling

Performance

  • Multi-threaded: Uses all CPU cores via Rayon
  • Optimized: Run-length encoding reduces mesh complexity
  • Memory efficient: Streaming STL generation
  • Fast builds: LTO and optimization level 3 in release mode

Typical generation time for 100x100mm lithophane: ~5-15 seconds

Testing

# Run all tests (233 tests)
cargo test

# Run with output
cargo test -- --nocapture

# Run specific module
cargo test color::

# Release mode tests (faster)
cargo test --release

Requirements

  • Rust 1.75 or later β€” Install via rustup
  • Modern CPU (multi-core recommended)
  • ~100 MB RAM for typical images

Comparison with Java Version

Feature Java Rust
Performance ⚑ ⚑⚑⚑ (2-3x faster)
Memory Usage 🐘 🐁 (50% less)
Binary Size 30+ MB 8 MB
Startup Time ~2s (JVM) <100ms
Dependencies JRE required Self-contained
Type Safety Runtime Compile-time

Contributing

Contributions welcome! This is a faithful port of the Java implementation with Rust idioms.

License

MIT License - See LICENSE file

Credits

  • Original PIXEstL Java application: gaugo87 β€” gaugo87/PIXEstL
  • Rust Port: feurer98
  • Based on CMYK additive color mixing research
  • Bambu Lab AMS integration

Links

About

A program for creating color lithophanies and pixel images. (Originally a ported version from Java.)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors

Languages