Skip to content

Releases: voron69-bit/Stepifi

v2.0.0 - Output Format Selection & Enhanced 3MF Support

31 Dec 19:00

Choose a tag to compare

Stepifi v2.0.0 Release Notes

πŸŽ‰ Major New Features

Choose Your Output Format

Select between STL or STEP output when converting:

  • STL: Fast mesh export (5-10x faster), perfect for re-slicing
  • STEP: CAD solid format for engineering/design work

BambuStudio 3MF Compatibility

Now supports modern 3MF files from BambuLab Studio, PrusaSlicer, and other slicers that use external object storage.

What's Changed

  • ✨ New output format selection UI with radio buttons
  • ✨ Dynamic download buttons show correct format (STL/STEP)
  • πŸ”§ Fixed 3MF parser to load external object files
  • πŸ”§ Enhanced mesh extraction for split-storage 3MF files
  • ⚑ Massive speed improvement for STL exports (80-90% faster)

Why These Features?

Just got my first BambuLabs printer, an H2D and found MakerWorld frustrating. I hate 3MF files. Most users do not include STL's, and the old faithful Windows 3D viewer fails to open 3MF for extraction of STLs. Well, now Stepifi does it!

Output Format Choice: Different workflows need different formats. 3D printing users often just need mesh data (STL is faster), while CAD users need solid geometry (STEP).

BambuStudio Support: Modern slicers optimize file size by splitting mesh data into separate files. Previous versions couldn't read these, causing "No mesh data found" errors.

Installation

git clone https://github.com/voron69-bit/Stepifi.git
cd Stepifi
docker compose up -d

Upgrading from v1.x

git pull origin main
docker compose down
docker compose build --no-cache app
docker compose up -d

Fully backward compatible - no breaking changes!

Full Documentation


Feedback? Open an issue or buy me a coffee! β˜•

v1.0.1

12 Dec 14:50

Choose a tag to compare

Stepifi Changelog - Complete Feature & Improvement History

Last Updated: December 12, 2025
Project: Stepifi - Self-Hosted STL/3MF to STEP Converter


Major Features Added

1. βœ… 3MF File Format Support

Status: Completed
Impact: High - Expands supported file formats significantly

Implementation:

  • Added full 3MF file parsing and extraction
  • Supports both single-object and multi-object 3MF files
  • Handles 3MF archives with multiple 3D model files
  • Parses 3MF XML structure to extract build items and components
  • Processes vertex colors from 3MF color groups (though colors are not preserved in STEP output)

Technical Details:

  • Backend: Created load_3mf_file() function in convert.py
    • Extracts .3mf zip archive to temporary directory
    • Parses 3dmodel.model XML file
    • Loads each .model file as separate mesh
    • Handles vertex attributes including colors
  • Frontend: Updated file input to accept .3mf extension
  • Conversion: Each 3MF object converted to individual solid, then combined into compound

2. βœ… 3D Preview with Multi-Format Support

Status: Completed
Impact: High - Significantly improves user experience

Features:

  • Real-time 3D preview using Three.js
  • Support for both STL and 3MF file formats
  • Automatic format detection and appropriate loader selection
  • Vertex color support for 3MF files
  • Interactive controls (rotate, zoom, pan)
  • Wireframe toggle mode
  • Reset view button
  • Displays mesh statistics (vertices, faces, file size)
  • Format distiguished by model color ( blue for STLS, green for 3MF )

Technical Implementation:

  • STL Files: Uses STLLoader from Three.js
  • 3MF Files: Custom loader using fflate library for zip extraction
    • Parses 3MF XML structure
    • Extracts vertex positions and colors
    • Builds Three.js BufferGeometry with color attributes
    • Handles multiple objects in single 3MF file
  • Storage: Preview data cached in IndexedDB for persistence
  • Sync: Preview availability tracked across devices via server sync

Preview Persistence Features:

  • Preview data stored in browser's IndexedDB
  • Survives page refreshes
  • "Preview" button only shown when data exists
  • Preview availability synced across devices every 10 seconds
  • Automatic cleanup of expired job previews

3. βœ… Shared Job List Across Devices

Status: Completed
Impact: High - Enables multi-device access

Features:

  • Jobs stored on server (Redis) instead of just localStorage
  • All devices see the same job list
  • Real-time job status updates
  • Periodic sync every 10 seconds
  • Jobs persist across sessions and browsers/computers
  • Automatic removal of completed jobs from other devices

Technical Implementation:

  • Added /api/jobs GET endpoint to fetch all jobs from Redis
  • Frontend polls server every 10 seconds
  • Jobs synced from server on page load
  • LocalStorage used as cache, server as authoritative source
  • Preview availability tracked per-device via IndexedDB

4. βœ… Job Cancellation Feature

Status: Completed
Impact: High - Essential for user control

Features:

  • Cancel button on each job card
  • Kills running FreeCAD process immediately
  • Removes job from queue
  • Deletes job files and Redis entry
  • Unblocks queue for next job
  • Detailed logging for debugging

Technical Implementation:

  • Process Tracking:
    • queue.service.js maintains Map of active FreeCAD PIDs
    • Process stored when conversion starts
    • Process retrieved and killed on cancel
  • Multi-Level Kill Strategy:
    1. Kill tracked process via Node.js process.kill(SIGKILL)
    2. Fallback: Kill all FreeCAD processes via shell command
    3. Remove job from BullMQ queue
    4. Delete files and Redis entry
  • BullMQ Integration:
    • Migrated from bull to bullmq v5.1.0
    • Separate Worker class for job processing
    • Proper job removal handling

5. βœ… Skip Face Merging Option

Status: Completed
Impact: Medium - Provides user control over conversion speed vs quality

Features:

  • New checkbox: "Skip face merging"
  • Tooltip explains what face merging does
  • Clarifies that curved surfaces stay triangulated regardless
  • Unchecked by default (normal behavior)
  • Results in faster conversions when enabled

Tooltip Text:

"Skips merging coplanar triangles into single faces. Results in faster conversion but more triangulated geometry. Face merging only works on flat surfaces - curved surfaces will remain triangulated regardless."

Technical Implementation:

  • Frontend: Checkbox in conversion options panel
  • Backend: Boolean parameter passed through entire pipeline
  • Python: Wraps face merging code with if not skip_face_merge checks
  • Logging: Debug output shows when face merging is skipped

Bug Fixes & Improvements

Preview System Fixes

βœ… Preview Button Persistence

Issue: Preview button disappeared on page refresh even when preview data existed
Root Cause: hasPreview property not persisted or checked against IndexedDB
Fix:

  • Check IndexedDB for preview data on job load
  • Set hasPreview property based on IndexedDB contents
  • Persist hasPreview in localStorage cache
  • Sync preview availability from server

Job Management Fixes

βœ… Job Display Shows Original Filename

Issue: Job cards showed UUID filename instead of uploaded filename
Root Cause: Original filename not stored in job data
Fix:

  • Store originalFilename in job data on upload
  • Display original filename in job cards
  • Show file format badge (STL/3MF)

βœ… Expired Job Cleanup

Issue: Old jobs lingered in localStorage indefinitely
Root Cause: No cleanup mechanism for expired jobs
Fix:

  • Added cleanupExpiredJobs() function
  • Runs on app initialization
  • Checks expiresAt timestamp against current time
  • Removes expired jobs from Map and IndexedDB

βœ… Job Status Synchronization

Issue: Job status out of sync between devices
Root Cause: Only stored in localStorage on one device
Fix:

  • Server becomes authoritative source (Redis)
  • Periodic sync every 10 seconds
  • Jobs added/removed based on server state
  • LocalStorage used only as cache

Conversion Process Fixes

βœ… Queue Not Processing After Cancel

Issue: New jobs stayed "Queued" after canceling previous job
Root Cause:

  • FreeCAD process not killed, blocking queue
  • Worker promise never resolved after SIGKILL
  • BullMQ job locked by worker

Fix:

  • Track FreeCAD process PID in activeProcesses Map
  • Kill process with SIGKILL on cancel
  • Fallback to killing all FreeCAD processes
  • Remove job from BullMQ queue
  • Worker unblocked when process killed

Technical Infrastructure Changes

Backend Architecture

βœ… BullMQ Queue System

Migration: Moved from bull to bullmq v5.1.0
Changes:

  • Created dedicated queue.service.js with Queue and Worker classes
  • Separate Worker for job processing
  • Process tracking via activeProcesses Map
  • Job cancellation support
  • Proper error handling and logging

Key Methods:

  • initialize() - Sets up Queue and Worker
  • addJob() - Adds job to queue
  • cancelJob() - Cancels running job and kills process

βœ… Redis Service Enhancements

New Methods:

  • getAllJobs() - Returns all jobs with TTL info
  • updateJobStatus() - Updates job status, progress, and error
  • healthCheck() - Verifies Redis connection

Improvements:

  • Better error handling
  • TTL management
  • Job expiration tracking

βœ… Converter Service Refactoring

New Methods:

  • convertWithProcess() - Returns both process and promise
  • convert() - Wrapper for backward compatibility

Benefits:

  • Process tracking for cancellation
  • Better error handling
  • Consistent return format

Frontend Architecture

βœ… IndexedDB Integration

Purpose: Client-side storage for preview data
Database: stepifiDB version 1
Object Store: stlFiles

Methods:

  • initIndexedDB() - Creates database and store
  • saveSTLToIndexedDB() - Saves preview data
  • loadSTLFromIndexedDB() - Loads preview data
  • deleteSTLFromIndexedDB() - Removes preview data
  • hasSTLInIndexedDB() - Checks if preview exists

βœ… Job Synchronization System

Features:

  • Periodic sync with server every 10 seconds
  • Server as authoritative source
  • LocalStorage as cache
  • Preview availability tracking
  • Expired job cleanup

Methods:

  • syncJobsFromServer() - Fetches and merges server jobs
  • loadJobsFromStorage() - Initial load from localStorage + server
  • saveJobsToStorage() - Updates localStorage cache

Python Conversion Script

βœ… Multi-Mesh Processing

Enhancement: Process multiple meshes from 3MF files
Implementation:

  • Loop through each mesh in list
  • Convert each to solid separately
  • Merge planar faces per solid
  • Create compound of all solids
  • Backward compatibility for single-mesh files

βœ… Enhanced Face Merging

Improvements:

  • Per-solid face merging before compound
  • Compound-level merge only for single objects
  • Configurable merge tolerance (10x base tolerance)
  • Skip merge option for large meshes (>100k facets)
  • User-controlled skip via checkbox

Performance & UX Enhancements

βœ… Rate Limiting Removed

Change: Removed artificial 1 file per 3 seconds throttle
Impact: Multiple files can upload simultaneously
Location: public/js/app.js - handleFiles() method

βœ… Detailed Progress Logging

Added: Comprehensive logging throughout conversion pipeline
Prefixes:

  • [DELETE] - Job deletion operations
  • [cancelJob] ...
Read more