Skip to content

Releases: jgphilpott/polyslice

v26.4.0

19 Apr 18:02
ee0c2df

Choose a tag to compare

First release of April 2026, covering PR #189 merged since v26.3.1.

Version

package.json: 26.3.126.4.0

CHANGELOG highlights

Added

  • Configurable supportGap (PR #189) — shared by normal and tree support; replaces the previously hardcoded nozzleDiameter / 2 lateral gap. Default 0.2 mm preserves existing behaviour.
  • Configurable supportDensity (PR #189) — normal support grid density as a percentage (0–100). Default 50 matches the previously hardcoded spacing equivalent; 0 short-circuits to no support lines.
  • Configurable supportRootsEnabled (PR #189) — boolean toggle for tree-support root structures. Default true.
  • Configurable supportRootCount (PR #189) — number of radial roots at the trunk base (1–8). Default 4.
  • Configurable supportBranchAngle (PR #189) — angle (degrees, (0°, 90°)) of branches rising from the trunk. Default 45.
  • Configurable supportTwigAngle (PR #189) — angle (degrees, (0°, 90°)) of twigs rising from branch nodes to contact tips. Default 45.

All six options default to the values previously hardcoded, so no existing behaviour is affected.

v26.3.1

14 Mar 04:05
7b332a5

Choose a tag to compare

Second release of March 2026, covering 4 PRs (#184#187) merged since v26.3.0.

Version

package.json: 26.3.026.3.1

CHANGELOG highlights

Added

  • Visualizer: Persist folder states (#184) — saveFolderStates/loadFolderStates in state.js; trackFolder helper avoids private lil-gui internals; cleared on full reset
  • Visualizer: Reset icon UX (#184) — confirm prompt + one-shot @keyframes spin-once with animationend cleanup
  • Visualizer: Build-plate-centered model positioning (#185) — positionMeshOnBuildPlate() called on load, rotation drag-end, and printer change; getBuildPlateDimensions() with localStorage + preset table fallback; updateBuildVolume() rebuilds axes/grid in-place preserving event listeners

Fixed

  • G-code metadata version always "Unknown" (#186) — require('../../package.json')require('../../../package.json') in coders.coffee; metadata test now asserts actual pkg.version
  • Dome zenith skin infill suppressed (#187) — even-odd nesting-parity check in findCoveredRegions (cavity.coffee) skips candidates whose bbox centre has odd containment count (i.e. hole paths); preserves lego-stud detection from #182

v26.3.0

09 Mar 06:31
16de9f0

Choose a tag to compare

First release of March 2026, covering 19 PRs (#164#182) merged since v26.2.2.

Version

  • package.json: 26.2.226.3.0

CHANGELOG highlights

Added

  • Tree support roots (#178) — 45° root structures for base stability; broadened ray-cast (ROOT_RAY_SAMPLE_FRACTIONS) for curved surfaces; hanging roots suppressed in everywhere mode
  • Sequential wall printing for nested objects (#170) — outer-to-inner level ordering with nearest-neighbour within each level

Changed

  • Lightning infill (#169) — asymmetric fork positions (35–45% / 55–65%) + zig-zag kinks via addKinkedLine
  • Tree support cross-sections (#172) — circular O+X shape, size varies by type, single shared trunk segment, translation-independent clustering
  • Raft per-region separation (#176) — independent raft per contact region; default margin 5mm → 3mm; edgeEpsilon = 0.001 for boundary float imprecision

Fixed

  • Gizmo visibility on first model click (#164)
  • Smart wipe never activating (_meshBounds vs meshBounds) (#165)
  • Inverted pyramid covered-region detection (below-case in findCoveredRegions) (#166)
  • Concentric infill bleeding into holes (edge-by-edge clipLineWithHoles) (#167)
  • String setters silently ignoring valid mixed-case input (setSupportPlacement, setSpeedUnit, etc.) (#168)
  • Nested object middle layers spuriously getting skin (#171)
  • Oversized covered-area skin wall exclusion gap (should be infillGap, not nozzleDiameter) (#173)
  • Test suite broken by three-mesh-bvh@0.9.9 circular reference; replaced three-bvh-csg with ExtrudeGeometry (#174)
  • Sphere poles generating full-circle skin (raised candidateRatio 0.9→0.97, filter threshold 0.9→0.99) (#175)
  • Orphaned tree twig segments; weak twig/branch joint (TWIG_OVERLAP_LAYERS = 1) (#177)
  • Lego brick non-parallel skin lines — removed separate Phase 1 skin wall section; explicit G0 correction after combing (#179)
  • Tree support trunk relocation false-negative on upright arch/dome (maxZ-aware isTrunkAccessible) (#180)
  • Sibling nested structures not printing sequentially (precomputed directChildHolesOf/directChildStructuresOf) (#181)
  • Small covered regions (~2% area, e.g. lego studs) failing detection — removed 10% lower bound from findCoveredRegions (#182)

v26.2.2

27 Feb 11:12
1dcd4ea

Choose a tag to compare

Release v26.2.2 — 2026-02-27

Second release of February's second half. This release is heavy on correctness fixes — particularly for complex geometry (sideways dome, flipped arch) — plus a full tree support implementation and a significantly expanded visualizer.


New Features

Tree Support Type (#151)

A fully functional tree support algorithm is now available as an alternative to the normal grid supports:

  • Convergence algorithm: dense contact points near the overhang naturally thin into sparse trunk columns toward the build plate
  • Two zones determined per-point via barycentric interpolation of the overhang face Z:
    • Branch zone (within 8mm of overhang): fine 1.5× nozzle spacing
    • Trunk zone (>8mm from overhang): coarse 4× nozzle spacing with convergence snapping
  • Uses less material and produces smaller contact footprints for easier post-print removal
  • Enable with supportType: 'tree'

Visualizer: Extended Slicer Settings (#159)

The Slicer panel in the visualizer now exposes the full set of slicing options:

  • Adhesion: type selector + all skirt / brim / raft settings
  • Support: type, placement, and threshold
  • Temperatures: nozzle and bed temperature sliders
  • Fan speed slider
  • Shell: wall and skin thickness controls (moved to top of the section)
  • All 7 infill patterns now selectable in the GUI

Visualizer: Model Rotation Controls (#162)

A new Model Rotation folder in the Slicer panel:

  • X / Y / Z sliders (−180° to +180°, 1° steps), persisted to localStorage
  • Three.js TransformControls gizmo: click a mesh to attach arc handles, drag to rotate, click off to dismiss
  • OrbitControls paused automatically during gizmo drag to prevent conflicts
  • Bidirectional sync between sliders and gizmo

Improvements

  • Adhesion examples expandedslice-adhesion.js now demonstrates all 4 adhesion types against cube, cylinder, torus, and arch geometries (#150)
  • Visualizer camera — camera no longer refocuses on every file upload; only on the first upload per type (model or G-code), and resets when Slice is clicked (#159)
  • Visualizer sliders — numeric sliders use onFinishChange to avoid excessive localStorage writes while dragging (#159)
  • Visualizer layoutAdhesion and Support folders collapsed by default (#162)

Bug Fixes

Support Generation

PR Fix
#148 Support no longer generated on layer 0 when solid geometry blocks the position (<= blocking check)
#148 everywhere mode: for i in [1..0] CoffeeScript pitfall guarded when layersToCheck = 0
#148 Spurious ; TYPE: SUPPORT comments no longer emitted when all candidate points are blocked
#149 Barycentric isPointInSupportWedge check restricts fill to the actual overhang wedge, preventing support on the wrong side of slanted surfaces

Wall / Infill / Skin Geometry

PR Fix
#152 WALL-INNER and FILL/SKIN now generated on all layers with C-shaped cross-sections (sideways dome was missing both on 41 + 33 layers respectively)
#153 clipLineToPolygon epsilon reduced 0.3 → 0.001; skin and infill lines no longer cross the inner wall boundary on circular cross-sections
#153 Redundant G0 travel commands removed when nozzle is already at the infill start point
#154 Cavity detection no longer mistakes arch structural columns for interior cavity features, eliminating spurious skin walls on flipped arch layers 22–25
#155 Regression tests tightened (±0.5mm → ±0.05mm) confirming regular infill also stays within wall boundary
#156 numLinesUp now computed from boundary corner extents relative to pattern center; fixes missing infill with infillPatternCentering: 'global' in grid, triangles, and spiral patterns
#158 createInsetPath backtracking-vertex removal replaced with O(n) index-scan loop handling cascading near-reversal vertices (fixes jagged inner wall spikes at arc-rectangle junctions)
#160 createInsetPath now applies removeBacktrackingVertices as a post-processing pass on its output, fixing wall endpoints extending past expected positions at concave arc junctions
#161 generateSkinGCode pre-checks infill boundary feasibility before emitting ; TYPE: SKIN, eliminating degenerate skin-wall-only blocks on narrow ribbon polygon layers (sideways dome layers 14–18 and 108–112)

PRs in This Release

#148 · #149 · #150 · #151 · #152 · #153 · #154 · #155 · #156 · #158 · #159 · #160 · #161 · #162

v26.2.1

19 Feb 11:23
374282c

Choose a tag to compare

Release v26.2.1

Release Date: February 19, 2026

Second release of February 2026, addressing critical support generation improvements.


Highlights

🏗️ Complete Support Generation Overhaul - Revamped support generation with face-based grouping and modular architecture for better coverage, density, and maintainability.

🔧 Fixed Over-Extrusion - Support structures now use correct line width, making them 25% easier to remove.

🎨 Improved Visualizer Support - TYPE comments now added on every layer for proper color coding in G-code visualizers.


Support Generation Architecture

Sub-Module Organization

The support generation system has been reorganized into a clean, maintainable architecture:

src/slicer/support/
├── support.coffee          # Main dispatcher + shared utilities
├── support.test.coffee     # 19 integration tests
├── normal/
│   ├── normal.coffee       # Grid-based support implementation (499 lines)
│   └── normal.test.coffee  # 5 focused tests
└── tree/
    ├── tree.coffee         # Tree support template (future)
    └── tree.test.coffee    # 2 placeholder tests

Benefits:

  • Clean separation - Main module delegates all operations to specialized sub-modules
  • No duplication - 640 lines of duplicate code removed
  • Extensible - Easy to add new support types (tree, organic, etc.)
  • Maintainable - Focused modules with single responsibility
  • Well-tested - 26 total tests (19 main + 5 normal + 2 tree)

Dispatcher Pattern

The main support.coffee module acts as a dispatcher:

# Import specialized sub-modules
normalSupportModule = require('./normal/normal.coffee')

# Delegate based on support type
generateSupport: (slicer, ...) ->
    switch slicer.getSupportType()
        when 'normal'
            normalSupportModule.generateSupport(slicer, ...)
        when 'tree'
            # Future: tree support implementation
        else
            # Validation error

Only shared utilities remain in the main module:

  • buildLayerSolidRegions() - Caches solid geometry for collision detection
  • Cache management for _overhangFaces, _supportRegions, _layerSolidRegions

Support Algorithm Improvements

Face-Based Grouping

Old Approach (Point-Based):

  • Detected overhang face centers as isolated points
  • Generated separate support column for each point
  • Ignored face area (only center mattered)
  • Result: Arch had 50 separate structures, dome had 376 overlapping pillars

New Approach (Face-Based):

  • Stores complete face data (all 3 vertices)
  • Groups adjacent faces that share edges (union-find algorithm)
  • Calculates collective bounding box from all vertices
  • Generates coordinated grid pattern covering entire grouped area
  • Result: Arch has 1-2 unified regions, dome has coordinated structure

Edge Matching Algorithm

edgesMatch: (v1a, v1b, v2a, v2b, tolerance = 0.001) ->
    # Check if two edges share the same vertices
    # Works in both directions (forward and reverse)
    # 0.001mm tolerance for floating-point precision

Union-Find Grouping

# Initialize each face in its own group
parent = {}
for i in [0...faces.length]
    parent[i] = i

# Find all adjacent pairs and union them
for i in [0...faces.length]
    for j in [i+1...faces.length]
        if facesAreAdjacent(faces[i], faces[j])
            union(i, j)

# Group faces by root parent
groups = {}
for i in [0...faces.length]
    root = find(i)
    groups[root].push(faces[i])

Coordinated Grid Patterns

For each grouped region:

  1. Calculate collective bounding box (minX, maxX, minY, maxY)
  2. Apply support gap (nozzleDiameter / 2) to prevent overlap
  3. Generate grid points at supportSpacing intervals (2× nozzle diameter)
  4. Alternate X/Y direction per layer (even layers: horizontal, odd: vertical)
  5. Check collision for each point (even-odd winding rule)
  6. Group valid points into continuous lines
  7. Generate G-code with proper extrusion

Critical Fixes

1. Support Extrusion Calculation

Problem:

# Old code - used full nozzle diameter
extrusionDelta = slicer.calculateExtrusion(distance, nozzleDiameter)
# Result: 25% over-extrusion, difficult to remove

Fix:

# New code - uses support line width
supportLineWidth = nozzleDiameter * 0.8  # Thinner for easier removal
extrusionDelta = slicer.calculateExtrusion(distance, supportLineWidth)
# Result: Correct material flow, easy removal

Impact:

  • Eliminates 25% over-extrusion in all support structures
  • Supports are easier to remove as designed
  • Better surface quality on supported areas

2. Support Coverage

Arch Geometry (Upright):

  • Old: 50 overhang face centers → 50 isolated pillars
  • New: Adjacent bottom faces grouped → 1-2 unified regions → complete coverage

Dome Geometry (Upright):

  • Old: 376 face centers → 376 overlapping pillars
  • New: Connected faces pooled → fewer coordinated regions → no redundancy

3. Support Visualization

Problem: TYPE comments only added on first layer

G1 X10 Y10 E0.5 F1200  ; Layer 0 - has TYPE comment
G1 X10 Y10 E0.5 F1200  ; Layer 1 - no TYPE comment (wrong)

Fix: TYPE comments added on every layer

; TYPE: SUPPORT         ; Layer 0
G1 X10 Y10 E0.5 F1200

; TYPE: SUPPORT         ; Layer 1
G1 X10 Y10 E0.5 F1200

Impact:

  • G-code visualizers can properly color-code support structures
  • Consistent with other feature type annotations (WALL-OUTER, SKIN, FILL)

4. Support Gap

Problem: Supports generated too close to printed part

# Old code - no gap, used full bounds
grid covers: [minX, maxX] × [minY, maxY]

Fix: Added proper clearance gap

supportGap = nozzleDiameter / 2  # e.g., 0.2mm with 0.4mm nozzle
minX = region.minX + supportGap  # Shrink inward
maxX = region.maxX - supportGap  # Shrink inward
# Grid covers smaller area with gap

Impact:

  • Prevents support from adhering to printed part
  • Easier support removal
  • Better surface quality
  • Follows same gap convention as infill

Code Quality Improvements

Dead Code Removal

Removed:

  • 640 lines of duplicate code from main support.coffee
  • Never-called clusterOverhangRegions() method
  • Old point-based clustering implementation
  • Outdated region merging logic

Result:

  • Main module: 151 lines (down from ~800 lines)
  • Clear single responsibility per module
  • Easier to understand and maintain

Test Coverage

All 26 support tests passing:

  • 19 main tests - Integration testing of support generation
  • 5 normal tests - Face grouping, edge matching, grid patterns
  • 2 tree tests - Template placeholders for future implementation

Full test suite: 747 tests passing across 38 test suites


Breaking Changes

None. This release is fully backward compatible with v26.2.0.


Upgrade Guide

From v26.2.0

No code changes required. Simply update your package:

npm install @jgphilpott/polyslice@26.2.1

Support generation will automatically benefit from:

  • Better coverage (face-based grouping)
  • Easier removal (correct extrusion)
  • Improved visualization (TYPE comments)

Configuration

All existing support configuration options remain unchanged:

const slicer = new Polyslice({
    supportEnabled: true,
    supportType: 'normal',           // Only 'normal' implemented
    supportPlacement: 'buildPlate',  // or 'everywhere'
    supportThreshold: 45             // degrees
});

Performance Impact

Memory:

  • Similar memory usage (face data vs point data)
  • Additional caching for grouped regions (minimal overhead)

Speed:

  • Face grouping: O(n²) edge comparisons, but n is typically small (< 1000 faces)
  • Grid generation: Same complexity, more efficient paths
  • Overall: Negligible impact on slicing time

G-code Size:

  • Similar or slightly smaller (coordinated patterns vs isolated pillars)
  • Better travel paths reduce total G-code size

Known Limitations

Tree Support

Tree support type is defined but not yet implemented:

// Will be implemented in future release
const slicer = new Polyslice({
    supportType: 'tree'  // NOT YET IMPLEMENTED
});

Current status:

  • Template module created (tree/tree.coffee)
  • Placeholder tests added (tree.test.coffee)
  • Will be implemented in future release

Support Types

Currently supported types:

  • normal - Grid-based support with face grouping
  • tree - Tree-like branching (planned)
  • organic - Smooth organic supports (future consideration)

Migration from Older Versions

From v26.1.x

Update package.json:

{
  "dependencies": {
    "@jgphilpott/polyslice": "^26.2.1"
  }
}

Run:

npm update @jgphilpott/polyslice

Review the CHANGELOG for all changes between v26.1.x and v26.2.1.


Documentation Updates

Updated Files

  • CHANGELOG.md - Added v26.2.1 release notes
  • .github/instructions/slicer/support/overview.instructions.md - Updated architecture docs
  • docs/slicer/support/SUPPORT.md - Updated support generation guide

New Documentation

All documentation now reflects the sub-module architecture and face-based grouping algorithm.


Testing

Pre-Release Validation

All checks passed:

  • npm run compile - CoffeeScript compilation successful
  • npm test - All 747 tests passing (38 suites)
  • npm run build - All distributions built successfully
  • npm run lint - Code s...
Read more

v26.2.0

14 Feb 05:05
55c669a

Choose a tag to compare

Release v26.2.0 - February 2026

Release Date: February 14, 2026
Previous Release: v26.1.2 (January 28, 2026)

🎉 Highlights

This release brings major infill pattern improvements to Polyslice! We've added four new infill patterns, fixed critical issues with existing patterns, and introduced a new pattern centering system for better control over infill placement.

Key Improvements

  • 4 New Infill Patterns: Concentric, Gyroid, Spiral, and Lightning
  • Gyroid Pattern Completely Revised: Single rotating direction for better performance and layer adhesion
  • Concentric Pattern Fixed: Proper wall gaps and hole detection
  • Pattern Centering Control: Choose between object-centered or globally-centered patterns

✨ New Features

New Infill Patterns

Polyslice now supports 7 total infill patterns (previously 3):

1. Concentric Pattern 🎯

Inward-spiraling contours that follow the natural boundary shape.

Best for:

  • Curved shapes and organic forms
  • Cylindrical cross-sections
  • Parts where following the boundary is beneficial

Characteristics:

  • Continuous paths minimize travel moves
  • Natural fit for circular geometries
  • Each layer independently follows the boundary shape

2. Gyroid Pattern 🌊

Triply periodic minimal surface (TPMS) with wavy interlocking structure.

Best for:

  • Parts requiring maximum strength-to-weight ratio
  • Isotropic strength requirements
  • Aesthetic wavy patterns

Characteristics:

  • Single rotating direction per layer (0° to 90° over 8 layers)
  • 3D interlocking structure across layers
  • Excellent strength comparable to hexagons
  • Smooth gradual transitions between layers

3. Spiral Pattern 🌀

Archimedean spiral from center outward in one continuous path.

Best for:

  • Circular or cylindrical parts
  • Smooth continuous motion printing
  • Parts where radial structure is beneficial

Characteristics:

  • Single continuous spiral from center
  • No direction changes within a layer
  • Natural fit for cylindrical geometries
  • Efficient for circular cross-sections

4. Lightning Pattern

Tree-like branching structure for fast printing with minimal material.

Best for:

  • Draft prints and prototypes
  • Parts where speed is prioritized
  • Internal support structure
  • Low-density infill requirements

Characteristics:

  • Tree-like branching from boundary inward
  • 45° fork angles for natural appearance
  • Minimal material usage
  • Fast printing speed
  • Adequate support for top surfaces

Infill Pattern Centering

New configuration option infillPatternCentering gives you control over pattern alignment:

// Object-centered (default) - centers on each object's boundaries
slicer.setInfillPatternCentering('object');

// Global-centered - centers on build plate center (0,0)
slicer.setInfillPatternCentering('global');

Affected patterns: Grid, Triangles, Hexagons, Gyroid, Spiral, Lightning
Not affected: Concentric (inherently follows boundary)

Use cases:

  • Object mode: Best for most prints, centers patterns naturally on each object
  • Global mode: Consistent pattern alignment across multiple prints, easier visual comparison

🔧 Major Changes

Gyroid Pattern Algorithm Revision

The gyroid pattern has been completely rewritten for better performance and quality:

Before:

  • Generated two sets of wavy lines per layer (X and Y directions)
  • ~170 lines per layer
  • Abrupt direction changes between layers

After:

  • Single set of wavy lines per layer
  • Gradual rotation from 0° to 90° over 8-layer cycle
  • Consistent ~85-100 lines per layer
  • Smooth transitions for better layer adhesion
  • Better performance and material usage

Example layer sequence:

  • Layer 0: 0° (horizontal wavy lines) - ~92 lines
  • Layer 4: 45° (diagonal) - ~98 lines
  • Layer 7: ~79° (near vertical) - ~88 lines
  • Layer 8: Cycle repeats

This change results in:

  • ✅ Better layer-to-layer adhesion
  • ✅ More consistent material usage
  • ✅ Improved performance (fewer lines to generate)
  • ✅ Smoother interlocking 3D structure

🐛 Bug Fixes

Concentric Infill Issues Fixed

Problem: Concentric infill had multiple issues:

  1. First loop too close to walls (no gap)
  2. Infill generated inside holes (torus example showed 33% points in holes)

Solution:

  • Added proper lineSpacing gap before first infill loop
  • Implemented hole detection using majority voting on 8 sample points per loop
  • Loop skipped only if more than half the sample points are inside holes

Impact: Torus example now shows 0% erroneous points (down from 33%)

Cylinder Bottom Layer Fixed

Problem: Cylinders had incomplete walls on the bottom layer

Solution: Increased SLICE_EPSILON from 0.001mm to layerHeight/2 to avoid geometric boundary issues

Impact: All cylinder slicing now produces complete walls on every layer

Spiral Pattern LastEndPoint Tracking

Problem: Spiral pattern updated lastEndPoint unconditionally, causing incorrect combing calculations

Solution: Only update lastEndPoint when actual movement is generated (distance > 0.001mm)

Impact: More accurate travel path optimization in spiral infill

Skin Generation for Nested Structures

Problem: Travel moves between skin areas in nested structures were incorrect

Solution: Proper handling of travel moves when generating skin for complex nested geometries

Impact: Cleaner G-code with better travel optimization

CI Pipeline Dependency Conflicts

Problem: CI pipeline failed due to eslint-plugin-jest conflicts with eslint 10.x

Solution: Removed unused eslint-plugin-jest from devDependencies

Impact: CI pipeline now runs successfully with latest eslint 10.0.0

📊 Pattern Comparison

Pattern Directions Speed Strength Use Case
Grid 2 (±45°) Medium Good General purpose
Triangles 3 (45°, 105°, -15°) Medium Better Structural parts
Hexagons Honeycomb Slower Best Maximum strength
Concentric Spiraling Fast Good Curved/circular parts
Gyroid Wavy TPMS Medium Excellent Isotropic strength
Spiral Radial Fast Good Circular parts
Lightning Branching Fastest Adequate Draft/prototype

📚 Documentation Updates

  • Updated all instruction files for new infill patterns
  • Added comprehensive API documentation for new patterns
  • Updated README with pattern comparison table
  • Added example scripts demonstrating all patterns
  • Documented infill pattern centering feature

🔬 Testing

All new features include comprehensive test coverage:

  • Concentric pattern: 11 tests
  • Gyroid pattern: 13 tests
  • Spiral pattern: 11 tests
  • Lightning pattern: 11 tests
  • Pattern centering: Integration tests

🙏 Acknowledgments

Special thanks to the GitHub Copilot team for assisting with:

  • Complex gyroid algorithm implementation
  • Concentric infill hole detection logic
  • Lightning pattern tree structure
  • Comprehensive documentation updates

🔗 Links

📦 Installation

npm install @jgphilpott/polyslice

Or via CDN (browser):

<script src="https://unpkg.com/@jgphilpott/polyslice@26.2.0/dist/index.browser.min.js"></script>

🚀 Upgrade Guide

Upgrading from v26.1.2 is straightforward - all changes are additive:

npm update @jgphilpott/polyslice

New API Methods:

// Use new infill patterns
slicer.setInfillPattern('concentric');
slicer.setInfillPattern('gyroid');
slicer.setInfillPattern('spiral');
slicer.setInfillPattern('lightning');

// Configure pattern centering
slicer.setInfillPatternCentering('object'); // Default
slicer.setInfillPatternCentering('global');

Breaking Changes: None - all existing code continues to work

Behavior Changes:

  • Gyroid pattern now generates different output (single rotating direction)
  • Concentric pattern now properly respects holes
  • Cylinder slicing may produce slightly different output due to SLICE_EPSILON fix

📈 Statistics

Since v26.1.2:

  • 80+ commits merged
  • 7 major pull requests (4 for new patterns, 3 for fixes)
  • 4 new infill patterns added
  • 25 new tests added
  • 200+ documentation updates
  • 15+ bug fixes and improvements

Full Changelog: https://github.com/jgphilpott/polyslice/blob/main/CHANGELOG.md

v26.1.2

28 Jan 13:36
8f9a88a

Choose a tag to compare

Release v26.1.2

Release Date

January 28, 2026

Highlights

This release adds comprehensive metadata and progress tracking capabilities to Polyslice, including G-code metadata extraction, configurable metadata headers, progress callbacks, and print time calculation.

New Features

1. G-code Metadata Extraction (getGcodeMetadata())

Extract metadata from G-code files with automatic multi-slicer support:

// Extract from slicer's internal G-code
const metadata = slicer.getGcodeMetadata();

// Or extract from any G-code string
const customGcode = fs.readFileSync('print.gcode', 'utf8');
const metadata = slicer.getGcodeMetadata(customGcode);

console.log(metadata.printer);              // "Ender3"
console.log(metadata.nozzleTemp.value);     // 200
console.log(metadata.nozzleTemp.unit);      // "°C"
console.log(metadata.totalLayers);          // 50
console.log(metadata.filamentLength.value); // 1234.5
console.log(metadata.filamentLength.unit);  // "mm"

Supported Slicers:

  • ✅ Polyslice (native)
  • ✅ Cura / Ultimaker Cura
  • ✅ PrusaSlicer
  • ✅ Generic G-code (fallback parser)

Extracted Metadata Fields:

Common Fields (all slicers):

  • generatedBy - Slicer name
  • version - Slicer version
  • printer - Printer model
  • layerHeight - Layer height with units
  • totalLayers - Layer count
  • filamentLength - Filament used with units
  • estimatedPrintTime - Print time estimate

Polyslice-specific Fields:

  • timestamp - ISO 8601 timestamp
  • repository - Repository URL
  • filament - Filament name and type
  • nozzleTemp - Nozzle temperature with units
  • bedTemp - Bed temperature with units
  • materialVolume - Material volume with units
  • materialWeight - Material weight with units
  • flavor - G-code flavor (e.g., "Marlin")
  • infillDensity - Infill percentage
  • infillPattern - Infill pattern type
  • wallCount - Number of perimeters
  • boundingBox - Print bounding box coordinates

2. Configurable Metadata Fields

Fine-grained control over metadata output with 20+ configurable fields:

const slicer = new Polyslice({
  metadataVersion: true,      // Include version number
  metadataTimestamp: true,    // Include timestamp
  metadataRepository: true,   // Include repository URL
  metadataPrinter: true,      // Include printer info
  metadataFilament: true,     // Include filament info
  metadataNozzleTemp: true,   // Include nozzle temperature
  metadataBedTemp: true,      // Include bed temperature
  metadataLayerHeight: true,  // Include layer height
  metadataTotalLayers: true,  // Include total layers
  metadataFilamentLength: true, // Include filament length
  metadataMaterialVolume: true, // Include material volume
  metadataMaterialWeight: true, // Include material weight
  metadataPrintTime: true,    // Include estimated print time
  metadataFlavor: true,       // Include G-code flavor
  metadataInfillDensity: true, // Include infill density
  metadataInfillPattern: true, // Include infill pattern
  metadataWallCount: true,    // Include wall count
  metadataSupport: true,      // Include support status
  metadataAdhesion: true,     // Include adhesion type
  metadataSpeeds: true,       // Include print speeds
  metadataBoundingBox: true   // Include bounding box
});

All metadata fields output with proper units (°C for temperature, mm for length, etc.).

3. Progress Callback System

Real-time feedback during slicing with customizable progress callbacks:

const slicer = new Polyslice({
  progressCallback: (progressInfo) => {
    console.log(`Stage: ${progressInfo.stage}`);
    console.log(`Progress: ${progressInfo.percent}%`);
    if (progressInfo.currentLayer) {
      console.log(`Layer: ${progressInfo.currentLayer}/${progressInfo.totalLayers}`);
    }
    console.log(`Message: ${progressInfo.message}`);
  }
});

const gcode = slicer.slice(mesh);

Progress Stages:

  • initializing - Mesh preparation
  • pre-print - Pre-print G-code generation
  • adhesion - Adhesion structure generation
  • slicing - Layer-by-layer slicing (0-100%)
  • post-print - Post-print G-code generation
  • complete - Slicing finished

Default Progress Bar:

If no custom callback is provided, Polyslice includes a default lightweight progress bar:

  • Node.js: In-place updating progress bar using process.stdout.write
  • Browser: Console.log updates for each stage

4. Print Time Calculation

Accurate print time estimation from G-code analysis:

// Automatically calculated during slicing
const gcode = slicer.slice(mesh);
const metadata = slicer.getGcodeMetadata();
console.log(metadata.estimatedPrintTime); // "2h 34m 15s"

Features:

  • Analyzes all G-code movement commands (G0, G1, G2, G3)
  • Accounts for feedrates and positioning modes (absolute/relative)
  • Supports arc movements and Bézier curves
  • Parses actual G-code for accurate estimates

5. Enhanced Metadata Headers

G-code files now include comprehensive metadata headers:

; Generated by Polyslice
; Version: 26.1.2
; Timestamp: 2026-01-28T12:00:00.000Z
; Repository: https://github.com/jgphilpott/polyslice
; Printer: Ender3
; Filament: Generic PLA (pla)
; Nozzle Temp: 200°C
; Bed Temp: 60°C
; Layer Height: 0.2mm
; Total Layers: 50
; Filament Length: 1234.5mm
; Material Volume: 3.2cm³
; Material Weight: 4.0g
; Estimated Print Time: 2h 34m 15s
; Flavor: Marlin
; Infill Density: 20%
; Infill Pattern: grid
; Wall Count: 2
; Support: false
; Adhesion: skirt
; Perimeter Speed: 50mm/s
; Infill Speed: 60mm/s
; Travel Speed: 120mm/s
; Bounding Box: X[0.0,100.0] Y[0.0,100.0] Z[0.0,10.0]

Improvements

  • Improved Metadata Parsing - Better handling of multiple G-code flavors
  • Enhanced G-code Headers - Comprehensive metadata in G-code comments
  • Better Metadata Organization - Structured data with proper units
  • Improved Code Documentation - Better inline documentation for metadata features

Use Cases

  1. G-code Analysis Tools - Build tools to analyze and compare print settings
  2. Print Management - Track and categorize prints by settings
  3. Quality Control - Verify print parameters before sending to printer
  4. Cross-Slicer Compatibility - Read metadata from any slicer
  5. Print Statistics - Collect statistics on material usage and print times
  6. Progress Monitoring - Track slicing progress in real-time
  7. Custom Metadata Headers - Generate G-code with specific metadata fields

API Changes

New Configuration Options

// Metadata field options (all default to true)
metadataVersion
metadataTimestamp
metadataRepository
metadataPrinter
metadataFilament
metadataNozzleTemp
metadataBedTemp
metadataLayerHeight
metadataTotalLayers
metadataFilamentLength
metadataMaterialVolume
metadataMaterialWeight
metadataPrintTime
metadataFlavor
metadataInfillDensity
metadataInfillPattern
metadataWallCount
metadataSupport
metadataAdhesion
metadataSpeeds
metadataBoundingBox

// Progress callback option
progressCallback: Function

New Methods

// Extract metadata from G-code
slicer.getGcodeMetadata(gcode?: string): Object

Installation

npm install @jgphilpott/polyslice@26.1.2

Or update your existing installation:

npm update @jgphilpott/polyslice

CDN (Browser)

<script type="module">
  import Polyslice from 'https://unpkg.com/@jgphilpott/polyslice@26.1.2/dist/index.browser.esm.js';
</script>

Documentation

Full API documentation: https://github.com/jgphilpott/polyslice/blob/main/docs/api/API.md#getgcodemetadatagcode--null

Breaking Changes

None - This is a backward-compatible feature addition.

Dependencies

No dependency changes in this release.

Testing

  • All 695 tests passed ✅
  • Linting passed with no issues ✅
  • All distributions built successfully ✅

Thanks

This feature was developed to improve G-code interoperability and enable better tooling around 3D printing workflows.

Full Changelog

See CHANGELOG.md for complete version history.


Previous Release: v26.1.1
Next Release: TBD

v26.1.1

23 Jan 09:09
8a41528

Choose a tag to compare

Release v26.1.1

Release Date: January 23, 2026
Version: 26.1.1 (Second release of January 2026)

Highlights

This release introduces several major enhancements to Polyslice, focusing on improving print quality, adding comprehensive adhesion support, and optimizing travel paths for more efficient printing.

New Features

Smart Wipe Nozzle

A new intelligent wipe nozzle feature that prevents marks and filament threads on finished parts:

  • Intelligent Path Calculation: Analyzes the mesh bounding box to find the shortest path away from the print boundaries
  • Built-in Retraction: Includes retraction during the wipe move to prevent oozing
  • Configurable: Control via the smartWipeNozzle option (enabled by default when wipeNozzle is true)
  • Automatic Backoff: Adds 3mm safety backoff beyond mesh boundaries

Traditional wipe implementations simply move X+5, Y+5 in relative coordinates, which can cause the nozzle to land on the print itself. The smart wipe calculates the optimal direction to move perpendicular to the nearest boundary.

Complete Adhesion Module

A comprehensive adhesion system with three distinct adhesion types:

Skirt

  • Circular Mode: Perfect circles around the model for simple nozzle priming
  • Shape Mode: Follows the actual first layer outline for precise boundary visualization
  • Configurable Distance: Set distance from model edge (default: 5mm)
  • Line Count: Control number of loops (default: 3)

Brim

  • Attached Support: Directly attaches to model edge for maximum warping prevention
  • Minimal Gap: Configurable gap from model (default: 0mm for full attachment)
  • Wide Support: 8 lines by default for strong hold

Raft

  • Three-Layer System: Base layer, interface layers, and air gap
  • Configurable Thickness: Independent control of base and interface layer heights
  • Air Gap: Adjustable gap between raft and model for easy removal
  • Line Spacing: Control raft density for optimal bed adhesion

All adhesion types include:

  • Modular architecture with separate sub-modules
  • Boundary checking to warn if extending beyond build plate
  • Integration with verbose mode for detailed G-code annotations
  • Example scripts demonstrating usage

Travel Path Optimization

Significant improvements to travel move efficiency:

  • Nearest-Neighbor Algorithm: Objects are processed in order of proximity to minimize travel distance
  • Sequential Completion: For independent objects, each is fully completed (walls → skin → infill) before moving to the next
  • Home Position Start: First layer sorting starts from printer home position (0,0)
  • Intelligent Application: Optimization applies when exposure detection is disabled for simple multi-object prints

This can dramatically reduce print time for prints with multiple independent objects by eliminating zigzag patterns across the build plate.

Development Tools

  • Release Agent: New specialized agent for managing calendar-based version releases
  • CHANGELOG.md: Formal changelog following Keep a Changelog conventions
  • Example Scripts: New slice-pillars example generating pillar arrays from 1x1 to 5x5

Improvements

Module Organization

  • Reorganized adhesion module into clean subdirectories (skirt/, brim/, raft/, helpers/)
  • Each adhesion type now has its own dedicated module with clear separation of concerns
  • Improved code maintainability and testability

Travel Efficiency

  • Travel paths now use nearest-neighbor sorting throughout the slicing process
  • Better handling of independent objects vs complex geometries with holes
  • Reduced unnecessary travel moves between features

Bug Fixes

  • Test Output: Cleaned up test output to suppress expected console warnings
  • Travel Optimization: Fixed incorrect application when exposure detection was enabled
  • Home Position: Proper handling of printer home position (0,0) as starting point for first layer sorting

Breaking Changes

Removed

  • Deprecated outline Setting: The outline configuration option has been removed. This feature was deprecated and unused in the codebase.

Dependencies

No dependency updates in this release. Current major dependencies:

  • three.js: ^0.182.0
  • @jgphilpott/polytree: ^0.1.6
  • @jgphilpott/polyconvert: ^1.0.5
  • polygon-clipping: ^0.15.7
  • three-subdivide: ^1.1.5

Documentation

  • Added comprehensive CHANGELOG.md
  • Updated adhesion module documentation
  • Added smart wipe implementation guide
  • Documented travel optimization strategies

Testing

All tests pass (651 tests):

  • Unit tests for all new features
  • Integration tests for adhesion types
  • Smart wipe calculation tests
  • Travel optimization validation

Migration Guide

From v26.1.0 to v26.1.1

No breaking API changes. All existing code will continue to work.

If you were using the outline setting (unlikely as it was deprecated), simply remove it from your configuration:

// Before
const slicer = new Polyslice({
  outline: true,  // Remove this
  // ... other settings
});

// After
const slicer = new Polyslice({
  // ... other settings
});

New Optional Features

To use the new features, simply enable them in your configuration:

const slicer = new Polyslice({
  // Smart wipe nozzle (enabled by default when wipeNozzle is true)
  wipeNozzle: true,
  smartWipeNozzle: true,
  
  // Adhesion
  adhesionEnabled: true,
  adhesionType: 'skirt',  // or 'brim' or 'raft'
  skirtDistance: 5,
  skirtLineCount: 3,
  
  // Travel optimization (automatic for independent objects)
  exposureDetection: false,  // Enable optimization
});

Known Issues

None reported for this release.

Installation

npm

npm install @jgphilpott/polyslice

Browser CDN

<script src="https://unpkg.com/@jgphilpott/polyslice@26.1.1/dist/index.browser.min.js"></script>

Verification

To verify the installation:

const Polyslice = require('@jgphilpott/polyslice');
console.log(Polyslice.version); // Should output "26.1.1"

Next Steps

After merging this PR:

  1. Push Tags: git push origin main --tags to push the v26.1.1 tag
  2. GitHub Release: Create a GitHub release using these notes
  3. npm Publish: Run npm publish to publish to npm registry
  4. Verification:
    • Check npm view @jgphilpott/polyslice version
    • Test installation in a clean directory
    • Verify unpkg CDN updates

Thanks

Thanks to all contributors and users who have provided feedback and helped improve Polyslice!


Full Changelog: v26.1.0...v26.1.1