Repository navigation
Releases: sn4k3/UVtools
Releases · sn4k3/UVtools
Release list
v7.1.2
- (Improvement) Linux: Present better error messages when libcvextern fails to load, and add a check for missing dependencies
- (Fix) Linux: libcvextern no longer requires the system libtiff.so.5 and libsqlite3, fixing startup on Debian 13 and Ubuntu 24.04+ (#1161)
- (Fix) macOS: The missing dependencies window never listed the libcvextern dependencies
- (Fix) Repair layers: Attach islands could hang forever on files with cloned layers, such as from timelapse, clone
layers, double exposure, lithophane, stir resin and the calibration tests, as the clones shared the same lock - (Fix) Issues: Resin traps, suction cups and print height issues on a single layer had their area calculated as a
volume, multiplied by the layer height in pixels - (Fix) Issues: Ignoring an island also ignored the islands with the same pixels on other layers
v7.1.1
- PCB exposure:
- (Fix) Gerber X2 attributes (%TO, %TA, %TD) and other unsupported extended commands were parsed as
coordinates and D codes, a net or component name like TX0, Y1 or D12 drew phantom copper or changed the aperture,
dropping the next pads and tracks (#1159). - (Fix) Gerber arcs exact to the file resolution were rejected, mostly small arcs in inch files with few
decimals (Eagle 2.4), and the next track then started from the arc start. An arc that can't be resolved is now drawn
as a straight segment and still moves to its end point. - (Fix) Gerber aperture macro primitives were rotated clockwise instead of counterclockwise, and the
center line rotation was rounded to whole degrees. - (Fix) defining a Gerber aperture also selected it, the following tracks and pads used the new
aperture instead of the selected one. - (Fix) Gerber aperture macros flashed with clear polarity (%LPC) added copper instead of clearing it.
- (Fix) Gerber aperture holes and macro parts with the exposure off erased the copper under them, and
a clear flash with a hole added copper in the hole. They now show what is under them. - (Fix) Gerber rectangle pads were one pixel larger on each axis, and with "Size scale" they grew to the
right and down only instead of staying centered. - (Fix) Gerber coordinates with a + sign were ignored, and only the first command of an extended block
with several (%FSLAX24Y24MOIN%) was read, so such inch files were read as millimeters. - (Improvement) unsupported Gerber commands that change the image (step and repeat, block apertures,
aperture mirroring, rotation and scaling) are recorded inGerberFormat.UnsupportedCommands.
- (Fix) Gerber X2 attributes (%TO, %TA, %TD) and other unsupported extended commands were parsed as
- (Add) 3D preview: zoom level on the toolbar, relative to the whole model fitting the view (1x), click to fit the
model to the view. - (Add) 3D preview: "Auto zoom & center issues" setting (on by default), independent of the layer preview one. When
off, selecting an issue centers the camera on it keeping the zoom. Hold [ALT] while selecting the issue to invert
the behavior. - (Add) Issues: "Group each island with the floating parts resting on it" setting (off by default). The pixels of an
island no longer support the layer above, everything that rests only on an island is floating too and is shown with it
as a single island issue, from its lowest layer, the one to support, up to where it joins the supported model.
Islands that join each other are merged in the same issue, and removing the issue removes the whole floating part.
The repair tool still works on each island alone. Also available in the command line asprint-issues --group-islands(#1047). - (Fix) About window was showing available ram instead of used ram.
- (Fix) Typos in OSLA documentation by @hamidzr (#1160)
- (Upgrade) .NET from 10.0.12 to 10.0.13
v7.1.0
- (Change) Use NuGet mini runtimes for Windows, macOS, Ubuntu 24.04 x64 and Debian 13 (Trixie) ARM64, with custom
cvextern overrides from build/platforms when available. - (Fix) Anycubic PWSZ: saved files could be rejected by Photon Workshop because optional resin names
were added to legacy user resins; omit absent names and preserve existing values (#1155). - (Fix) Convert: thumbnails are now matched to the target format by size instead of by order, formats that list
the largest thumbnail first (CTB, Chitubox ZIP, PHZ, ...) swapped the small and large previews when converted to
formats that list the smallest first (GR1, GOO, CXDLP, ...), shrinking the large one and upscaling the small one
(#1121). - (Fix) Anycubic ZIP formats (PWSZ and PW0 layers): opening high resolution files could fail with "Failed to allocate"
because every decoded layer image was kept in memory until the garbage collector freed it. - (Fix) Image formats: saving leaked one layer image per save.
- (Fix) LGS: saving a file without a thumbnail leaked the generated preview image.
- (Improvement) Layer preview: rotate and mirror are now applied when drawing instead of rotating and flipping the full
resolution layer image on every change, which is faster on high resolutions. Rotating keeps the zoom and the view
centered on the same spot of the layer instead of zooming to fit, it still zooms to fit when the whole layer was in
view. - (Add) Layer preview: "Real aspect ratio" toggle on the toolbar, and its "Real aspect ratio on load" setting, to show
the layer with the physical proportions of the printer pixels, printers with non-square LCD pixels, for example the
Halot Mage S, looked stretched. It is enabled by default and view only, the layer image is never resized (#918). - (Improvement) Layer preview: the crosshairs, the print volume, layer and contour bounds, the enclosing circles, the
centroids and the triangles count are now drawn as vectors over the layer image instead of into it, they are crisp at
any zoom, their text stays upright when the preview is rotated, and toggling them or zooming across the crosshair fade
level no longer renders the layer image again. Their thickness and diameter settings are now in screen pixels, scaled
to half of the value (at least 1) which is the same as before at 50% zoom. - (Improvement) Layer preview: the layer bitmap is reused while the layer resolution doesn't change instead of
allocating a new one for every layer, which is faster and reduces the memory churn on high resolution layers. - (Improvement) Layer preview: layers with nothing to color (no issues, difference, outlines, masks or pixel editor
operations on the layer) are displayed as the 8-bit image they are, instead of being expanded to a 32-bit image
and bitmap. On a 13312x5120 layer it needs 142 MB instead of 598 MB, and changing the layer takes about 8 ms instead
of 29 ms. Layers with colored pixels still use the 32-bit image, and the pixel editor always does. - (Add) Layer preview: "Layer image sampling" setting (Auto, Nearest, Smooth), Auto is the default. Zoomed out, the
layer is now drawn averaged instead of skipping pixels, which removed the aliasing and the shimmering of high
resolution layers when panning or scrolling the layers. It is still sharp pixels when zoomed in. Choose Nearest to
get the previous look. - (Add) Layer preview: the layer difference (difference, similarity and onion skin) is drawn by the GPU ("GPU
rendering" in the Difference menu, and a setting, on by default). The previous and next layers are drawn over the
layer as tinted layers by the layer image box, which keeps the layer as the 8-bit image it is, instead of the CPU
mixing the layers into a 32-bit image. The difference is the same as the CPU version; in the similarity the
anti-aliased pixels of the other layers blend with the layer instead of replacing it; in the onion skin the ghosts
have the same colors and priority, but the current layer is always white: there is no yellow for pixels without a
layer below and no magenta for cavities. The exact CPU version is used whenever the layer has something else to
color, like issues, or when the setting is off. - (Add) Layer preview: onion skin with 7 layers (-3 to +3) [6 ghosts], the layer +3 is drawn in dark blue.
- (Add) Layer preview: compare mode ("Compare" on the toolbar), the current layer is shown on the left of a split line
that is dragged with the mouse, and on its right the layer below or above, 10 layers below or above, or the same
layer before the last operation, from the undo history, to see what the operation changed. - (Add) Layer preview: rulers (toolbar toggle and setting, off by default) and a scale bar (toolbar toggle and setting,
on by default) in millimeters, from the display size and the resolution of the file. The rulers are drawn over the
layer along the top and left edges, with round steps that adapt to the zoom, upright labels and a mark that follows
the pointer. They show the position of the layer pixels along the axes of the screen from the top-left pixel of the
layer, also when the preview is rotated or flipped. - (Add) Layer preview: minimap (toolbar toggle and setting, on by default) in the bottom right corner, a thumbnail of
the whole layer with the visible part marked, shown only while the layer is zoomed in. Click or drag on it to move
the view. Its size and corner, and the corner of the scale bar, are set in the settings. - (Change) Layer preview: the cross-section and peel curve HUD moved to the top right corner, so it doesn't cover the
minimap and the scale bar, and its shortcut is now [P] because [A] also pans the layer to the left. - (Fix) Cross-section and peel curve HUD: in the layer preview it showed "No slice area data available" until the 3D
preview was opened, the layer areas are now calculated when the HUD is shown and again when the layers change. - (Fix) Cross-section and peel curve HUD: files without lift speeds and heights per layer now use the global bottom
and normal values for the peel force, instead of empty layer values. The lift values are refreshed when the lift
settings or the layers change. - (Fix) Layer preview: the triangulate outline drew triangles over the empty areas of concave shapes and holes,
now only the triangles inside the lit pixels are drawn and counted. The triangle count is shown in a fixed label at
the top of the layer preview instead of on the layer image, so it is visible at any zoom, rotation and flip. - (Improvement) Layer preview: [Q] and [E] change the layer when the key is pressed instead of released, and repeat
while the key is held, like the arrow keys. - (Add) Layer preview: pinch to zoom around the fingers with a two finger pan, and the magnify gesture of touchpads (
"Touch and touchpad gestures" setting, on by default). The mouse is not affected. - AdvancedImageBox
- (Add)
PixelAspectRatioproperty to show images with non-square pixels, the image is stretched vertically when
drawing without being resampled, with theZoomFactorXandZoomFactorYproperties that are the zoom factor of
each axis. TheZoomFactoris the same asZoomFactorX(#918). - (Add)
ImageRotation,FlipHorizontalandFlipVerticalproperties to display the image rotated in steps of 90
degrees and mirrored, without modifying or processing it. The image is flipped first and then rotated. The
coordinates of the control (PointToImage,GetOffsetPoint,CenterAt,ZoomToRegion,SelectionRegion, ...)
stay in pixels of the source image,PixelAspectRatiodescribes the source pixels, and theTrackerImageis
transformed like the image.GetSelectedBitmap(true)returns the selection as it is displayed. - (Add)
Overlayscollection to draw vector items over the image:ImageBoxLineOverlay,ImageBoxRectangleOverlay,
ImageBoxEllipseOverlay,ImageBoxPolylineOverlay(polygon when closed),ImageBoxMarkerOverlayand
ImageBoxTextOverlay. The geometry is in pixels of the source image and follows the zoom, the scroll, the rotation,
the flips and thePixelAspectRatioexactly like the image, while the stroke thickness, the marker size and the
font size are in screen pixels and stay the same at any zoom, and the text is always upright. They have a stroke, an
optional fill,OpacityandIsVisible, changing them redraws the control,ReplaceAll()andAddRange()redraw
once, the items outside of the viewport are skipped, andShowOverlayshides them all. - (Add)
InvalidateImage()method to redraw the control after the pixels of the sameImagebitmap were modified in
place, which raises no change, without touching the zoom, the scroll position or the centering. - (Add)
BitmapSamplingModeproperty (Nearestby default,AutoandSmooth) to draw a zoomed out image averaged
instead of aliased. AWriteableBitmapis reduced by powers of two once for each content, about 15 ms for
13312x5120 BGRA, and the reduction is drawn, so panning and zooming cost the same as nearest sampling, while
Avalonia's high quality interpolation takes about 50 ms for every frame. CallInvalidateImage()after changing
the pixels. - (Add)
GrayscaleImageproperty andGrayscaleImageclass to display an 8-bit image without expanding it to 32-bit
(a quarter of the memory and of the copy), with an optional 256 entry color map (SetColorMap) applied when
drawing. All the features work with it,GetSelectedBitmap()returns the colored selection. It is drawn with
Skia, falling back to a 32-bit copy for other render backends. Needs the Avalonia.Skia package to be drawn with
Skia, it is referenced by the control only to build, so it is not a new dependency of the NuGet package. - (Add)
CompositeLayerscollection to draw more images over or under the main one with the same ...
- (Add)
v7.0.3
- File formats:
- (Add) CXDLPv4: Support for the Creality HALOT-X1 (#1016), its layers use a different codec of 3 bit gray pixel
pairs per row, which is detected when opening the file and used when the machine is a HALOT-X1 or the resolution
is 15120x6230. Files of the other printers keep using the classic codec - (Fix) CXDLPv4: Anti-aliasing reported as 0 when the file header has a level of 0
- (Add) VLR: Vlare file format of the Peopoly Phenom Forge (#513), it shares the OSF structure with a bigger header
and a different layer codec - (Fix) PWSZ (Anycubic zip formats): overlapping or touching contours were filled as holes, for example supports
inside the model, causing false islands and overhangs, the layers are now filled with the non-zero winding rule
(#970) - (Fix) CXDLP: Print parameters were truncated instead of rounded to the integers the format stores, lift and
retract speeds below 60 mm/min became 0 (#1116) - (Improvement) Edit print parameters: the values are limited to what the file format can store, for example the CXDLP
speeds step in 60 mm/min and its integer fields have no decimals, and the confirmation shows the value that will be
stored (#1116)
- (Add) CXDLPv4: Support for the Creality HALOT-X1 (#1016), its layers use a different codec of 3 bit gray pixel
- (Add) PrusaSlicer printer: Creality Halot X1
- (Fix) Layer tracker: the issues were drawn at wrong positions after maximize or restore the window
- (Fix) AdvancedImageBox: The pixel grid image border and the selection were drawn over the scroll bars area when the
image was clipped by the viewport, they are now clipped to the viewport (#959)
v7.0.2
- File formats:
- (Improvement) Encoding is up to 10x faster for GR1 and MDLP, 2x for PWS, and 25-35% faster for cbddlp, N4/N7, and
Photon S; decoding PWS, cbddlp, FDG, and PHZ is 25-45% faster. Runs are found with vectorized searches, and the
duplicated CTB, anti-aliasing plane, and column line codecs are now shared - (Improvement) CTB, PHZ, and FDG layer encryption is processed 4 bytes at a time, and the CTB encrypted encoder
writes layers in batches instead of keeping all of them in memory - (Improvement) Thumbnail encoding and decoding no longer compares strings or queries the channel count per pixel
- (Improvement) QDT and SVGX decoding parse without allocating a string per token, SVGX decoding no longer searches
the layer group linearly, and its encoding no longer creates a native wrapper per contour point - (Improvement) Truncated CTB RLE data now fails with a corrupted data error instead of an index out of range
- (Fix) Anet: the last pixel of the layer was lost when it differed from the previous one, making the file unreadable
- (Fix) OSF: encoding failed when the layer content touched the last row of the image,
Layer.LastPixelIndexpointed
one row below the last pixel - (Fix) cbddlp: layers with anti-aliasing 1 turned every gray pixel black, and identical layers did not copy the page
number - (Fix) OSLA: the preview table padding used the layer table size
- (Fix) Encoding layers to a zip with the cache enabled skipped the duplicated layers
- (Fix) The hash helpers shared non-thread safe instances, and the AES padding bytes were not zeroed
- (Fix) ZCode: wrong exception arguments for a too long G-code line; QDT: swapped resolution names on header errors
- (Improvement) Encoding is up to 10x faster for GR1 and MDLP, 2x for PWS, and 25-35% faster for cbddlp, N4/N7, and
- (Fix) Crash
Cannot access a disposed objectonImage.MeasureOverride(#1150): the thumbnail and tool preview
bitmaps are now disposed after the UI applied the new image, and the PCB exposure preview no longer leaks the previous
bitmap - Windows and controls:
- (Improvement) 3D layer preview: model volume, weight, cost and base contact are cached instead of recomputed from
the whole mesh on every plate change, clicking where the model is not hit skips the full mesh picking, and the
orientation cube, peel curve and measure overlay no longer allocate geometries, pens and brushes on every frame - (Improvement) PCB exposure and Lithophane previews are rendered off the UI thread, outdated renders are discarded
- (Improvement) Moving files and layers in the PCB exposure and Phased exposure tools no longer rebuilds the list
- (Improvement) Tool windows scripting inputs share one numeric input implementation, and icon only buttons have tooltips
- (Fix) Scripting: the save file dialog input was ignored when a file was picked, and the open file text was joined wrong
- (Fix) 3D layer preview: wrong center of mass vertex on the wireframe
- (Fix) Message window: custom button tags were lost
- (Fix) Settings: parallelism and decimal values were parsed with the current culture instead of the invariant one
- (Fix) Tool window: the layer count text, and Enter triggering the first button by default
- (Fix) Layer import: unreadable images crashed the preview, and the filter index was not validated
- (Fix) Pixel editor profiles: selection with no profile and out of range indexes
- (Fix) Suggestion settings: stale content kept when no suggestion was active
- (Fix) Benchmark: a zero duration produced a division by zero
- (Improvement) 3D layer preview: model volume, weight, cost and base contact are cached instead of recomputed from
- (Fix) Error when executing UVtooldCmd run with a script (#1138)
- (Fix)
LayerCachedisposed the wrongSkiaSurfacewhen the layer was changed, and did not release the framebuffer - (Fix) Zstd: the fastest compression level was not really the fastest
- (Improvement) Update
NativeCompressionsand use it LZ4 codec - (Update) Benchmark 13900K reference values
- (Drop)
K4os.Compression.LZ4library
v7.0.1
- (Improvement) Add a Windows renderer preference in 3D preview settings to prefer native OpenGL (WGL) after restarting
UVtools; ANGLE stays the default, with WGL tried before software rendering (#1152, #1153) - (Add) Pixel Arithmetic options to apply changes only to model top surfaces, with an optional margin from walls (#1151)
- (Improvement) Pixel editor: applying supports and drain holes is much faster, all of them are now drawn in a single
pass that decodes and encodes each layer only once, in parallel - (Fix) Pixel editor: multiple supports or drain holes on the same layer no longer share the drawn layers counter, which
made their radius grow faster than intended - (Improvement) Issues detection is up to 5x faster for islands/overhangs and about 2x faster for resin traps:
- Layers are decoded only for the area needed instead of the whole resolution
- Islands use a run-length component labeling, and layers whose pixels are all supported skip it
- Overhangs only erode and trace the area that differs from the previous layer
- Resin traps air map is updated in a single multi-threaded SIMD pass, with layers decoded ahead while processing
- Touching bounds only decodes the layer when it is actually close to a border
- (Fix) Issues detection: partially supported islands were always discarded when the overhang check was not computed for
the layer (overhang detection disabled or layer outside its white list), after the enhanced detection - (Fix) Issues detection: touching bounds skipped the first rows of the layer content beside the left/right borders
- (Fix) Issues detection: native contour vectors were not released when the detection was cancelled
- (Improvement) Repair layers: gap closing and noise removal only process the area around the layer content, empty
layers
are skipped and layers that the repair did not change are no longer rewritten - 3D layer preview:
- (Improvement) Building the model is up to 5x faster (detailed quality on a 4K file went from 9.3s to 1.7s), the
faces are found with vectorized row by row passes and only the area of the model is decoded from each layer - (Improvement) Building the issues overlay is up to 10x faster, the layers are rasterized in parallel
- (Improvement) Moving the clip slider decodes less per layer to rebuild the cut cross-section
- (Improvement) Exporting the mesh to STL/OBJ no longer freezes the window
- (Fix) Export clipped mesh to OBJ exported the whole mesh, and the clipped STL lost the walls crossing the clip and
was left open on the cut; it now meshes only the shown layers, closed, and respects the cutaway - (Fix) Model volume, weight and resin cost were overestimated on a coarse detail, they now come from the layer pixels
- (Fix) Base contact area was overestimated on a coarse detail, and a floating model was reported as touching the
plate - (Fix) Clicking the model while clipped could pick the hidden part of a tall wall instead of the visible surface
- (Fix) Parts of the model were cut or showed stripes depending on the camera angle: the framebuffer provided by
Avalonia only has a 16 bit depth buffer, too coarse for faces a fraction of a millimeter apart. The scene is now
drawn into a 24 bit depth framebuffer and copied to the control - (Fix) The camera near/far planes are now fitted to the model bounds from the camera point of view, they were
estimated from a bounding sphere around the orbit target, which clipped the model or made its faces fight each other
(cuts and stripes) when the camera was panned, focused on an issue, zoomed in or the model was rebuilt - (Fix) Snapshot bitmaps were never released
- (Improvement) Building the model is up to 5x faster (detailed quality on a 4K file went from 9.3s to 1.7s), the
- Operations:
- (Improvement) Most tools skip empty layers and no longer clone every layer when there is no mask to apply
- (Improvement) Morph, Box/Median blur, Solidify and Pixel dimming only process the area around the layer content,
Solidify and Repair layers also rewrite only the layers they changed - (Improvement) Infill: gyroid pattern is computed from per-axis tables instead of per pixel, the neighbor layers used
to find the floor and ceil are only decoded where needed and the search stops once nothing is left to infill - (Improvement) Raft relief traces the raft layers in parallel, Heat map and Skeleton exports accumulate in parallel,
Mesh export skips the empty pixels faster, HTML export traces only the layer area, Remove layers and Pattern are
faster, Change resolution only decodes the model area - (Improvement) Calibration tolerance shares the identical layers instead of allocating one per layer, which used to
take gigabytes of memory on every parameter change of the preview - (Improvement) Pixel arithmetic skips empty layers and only clones the layer when it has to restore pixels
- (Improvement) Layer import skips merging empty images, and fails with a clear message on unreadable images
- (Improvement) Progress notifications from parallel operations are throttled, to not flood the UI
- (Fix) Blur: stack blur gave random pixels when layers were blurred in parallel (the OpenCV implementation is not
thread safe) and misbehaved when using a ROI; pyramid blur had no effect at all - (Fix) Infill: using a mask without a ROI always failed, and the mask is now the area where the infill happens
- (Fix) Layer arithmetic and Heat map export failed or used a wrong mask when a ROI and a mask were used together
- (Fix) Operations mask application when the layer, ROI and mask have different sizes
- (Fix) Redraw model: checked the wrong layer to skip empty ones, never released the redraw file and did not complete
the progress - (Fix) Raft relief: tabs on the left and right sides were limited by the layer width instead of the height
- (Fix) Layer import, Lithophane and Edit parameters did not complete the progress when layers were skipped
- (Fix) Grayscale and Elephant foot calibrations hanged or threw with a step of 0, Elephant foot threw when the start
was higher than the end, Lift height, Stress tower and Exposure finder threw or looped forever with invalid
divisors/steps (decrease factor, layer height, spirals, layer height step) - (Fix) Dynamic layer height: repeated the same erosion up to the maximum number of times for nothing
- (Fix) Calibrate XYZ accuracy drain hole was centered using the object width instead of the height, and Blooming
effect text was added for objects that were not created
v7.0.0
- AdvancedImageBox
- (Add)
PanBoundsModeproperty to choose the pan bounds mode, ifPaddingis selected it will add that padding to
scroll content bounds (#959)
disabled - (Fix) Owned-image disposal, selection clamping, crop stride/alpha handling, zoom bounds, redraw invalidation,
panning cursor reuse, and selection start bounds - (Breaking)
ZoomLevelCollectionnow exposesICollection<int>rather than positional
IList<int>operations, because zoom levels are sorted and unique. - (Improvement) Rewrite the installer scripts, add windows install script and uninstall scripts
- (Improvement) Remove
e.Handled = true;from handlers to allow subscribers to handle the event in same conditions
- (Add)
- Packaging:
- (Add) Linux native packages for .deb, .rpm and .pkg.tar.zst and arm64 packages (maybe fix #1124)
- (Improvement) Rewrite the installers, use more keys on registry and registers the known file extensions to make
double click on files to prompt for open with UVtools, it also allow to select it as default program (maybe fix
#459)
- 3D layer preview: GPU-accelerated, rotatable 3D model generated from the layer stack (#38, #602)
- (Add) Solid, X-Ray and Wireframe render modes, with Camera/Studio/Flat lighting and configurable voxel/background
colors - (Add) Color modes: overhang heatmap, layer-height zones, peel force & area risk, and bed adhesion footprint
- (Add) Clip modes (top/bottom/slab, with adjustable slab thickness) and X/Y cutaway with an invertible slider, to
inspect the model's interior - (Add) Model dimensions, bounding box, volume/weight/resin cost, center of mass & first-layer contact stability,
and cross-section area/peel-force curve HUD overlays, each independently toggleable - (Add) Per-type issue highlighting in 3D, with next/prev navigation and in-place solidify/drill repair
- (Add) Measure tool: click two points on the model to get the distance between them
- (Add) Orbit cube navigation (faces/edges/corners, roll, turntable/auto-rotate, home, fit-to-view), full keyboard
shortcuts, and click-to-select-layer - (Add) Print simulation playback with adjustable speed
- (Add) Export: mesh to STL/OBJ (full or clipped), current cross-section to PNG, snapshot to clipboard or file,
and 360° turntable animation to GIF
- (Add) Solid, X-Ray and Wireframe render modes, with Camera/Studio/Flat lighting and configurable voxel/background
- 2D layer preview:
- (Add) Elapsed print time readout
- (Add) Measure tool: click two points on the model to get the distance between them
- (Add) Cross-section area/peel-force curve HUD overlay
- (Add) Setting to start layer number at 1 instead of 0 on layer slider and navigation panel (#948)
- (Add) Dynamic lifts: Configure separate bottom/normal retract speeds and two-stage retract distance percentages (#927)
- (Add) Configure bottom height and transition layers for wait time after cure (#1093)
- (Add) Panel Gamma setting to compensate Exposure Time calibration tool in Multiple Brightness / grayscale mode (#1104)
- (Fix) Align pixel editor line brush preview and applied position (#966)
- (Add) Diagnostics tab to About window
- (Add) Announcements manager and live messages
- (Improvement) UI safety: Guaranteed GUI re-enabling via
try / finallyacross file operations, exports, suggestions, and send-to actions - (Improvement) Optimize issues collection view caching and selection lookups in issues DataGrid
- (Fix) Prevent SkiaSurface and framebuffer leaks during pixel editor preview drawing in
LayerCache - (Fix) Dispose previous thumbnail bitmaps, native OpenCV Mat instances, and ensure explicit disposal of timers and cache on window close
- (Improvement) pixel editor drawing with smooth, interpolated strokes committed on pointer release by @jorgerobles
(#1139) - (Improvement) Avoid eager pixel lists during island detection by @apullin (#1142)
- (Improvement) UI: Add
RelayCommandattributes to various methods for improved command binding - (Improvement) Redetect issues when ran operations: Rotate, Flip, Lithophane, LayerImport (#879)
- (Fix) Terminal error when sending a command (#1138)
- (Fix) 'Edit Print Paramters' menu item not visible in Tools (#1106)
- (Fix) empty-layer classification in linear time by @apullin (#1145)
- (Fix) Object reference not set to an instance of an object after clicking File -> Reload (#1141)
- (Fix) Disposed generated tracker and ROI crop bitmaps
- (Fix) UVtoolsCmd: it always return 1 exit code
- (Fix) SL1 layer height round trips by @apullin (#1147)
- (Fix) Culture-invariant serialization and parsing for SL1, CWS, and JXS config files and reflection extensions
- (Fix) Clear stale detected issues after layer image changes, undo, and redo (#879)
- (Fix) Undo/redo failing to revert differential layer edits in ClipboardManager
- (Fix) MessageBox from bug report and update show repeated header icon
- (Fix) Prevent SkiaSurface and framebuffer leaks during pixel editor preview drawing in
LayerCache - (Fix) Dispose previous thumbnail bitmaps and ensure explicit disposal of timers and cache on window close
- (Upgrade) .NET from 10.0.10 to 10.0.12
- (Upgrade) AvaloniaUI from 12.1.1 to 12.1.2

v6.2.0
- Layer repair:
- Fixed single-pass island and suction-cup re-detection.
- Fixed the inclusive layer range so the final selected layer is processed.
- Restricted repairs and island detection to the selected range.
- Removed the early return that skipped morphology and empty-layer removal.
- Indexed issues by layer instead of repeatedly scanning all issues.
- Added deterministic Mat disposal and exception-safe attachment locking.
- Fixed attachment of early layers and prevented source-layer modification.
- Improved cancellation handling, validation, progress counts, and all-empty-file handling.
- Prevented repaired islands from being processed again by later stages.
- Operations:
- Audited all operation implementations for correctness, cancellation, native-resource ownership, and avoidable work.
- Invalidated cached validation after settings change, rejected reversed layer ranges, and disposed internally owned
progress state. - Made native matrix, ROI, cache, and imported-format cleanup deterministic across calibration, import, mesh export,
dynamic-height, arithmetic, dimming, raft, re-height, and redraw operations. - Reduced multi-layer removal from repeated full-layer shifts to one pass while handling duplicate and invalid indexes
safely. - Replaced quadratic pattern-image string construction with row builders and avoided oversized pattern tiling.
- Fixed re-height difference accumulation and pixel-corrosion indexing errors.
- Fixed clone, phased-exposure, double-exposure, and timelapse layer placement/counting while avoiding partial commits
on cancellation. - Made light-bleed compensation deterministic by reading immutable layer snapshots instead of concurrently modified
neighbors. - Fixed dynamic-lift zero-range calculations, resize fade endpoints, overlapping copy moves, transition progress, and
lift-time calculations. - Fixed infill wave stepping/Z accumulation, pattern cleanup, and exact pattern repeat sizing.
- Fixed GIF frame counts, zero FPS handling, rotated frame dimensions, save error reporting, and image/heat-map crop
transforms. - Improved mask ownership and ROI behavior, layer-arithmetic bounds/masking, lithophane sizing, and PCB render reuse.
- Gerber:
- Audited the complete Gerber parser, apertures, macros, and drawing primitives.
- Reworked command tokenization to support multiple commands per line and multiline extended commands without repeated
string concatenation. - Fixed signed and trailing-zero coordinates, modal D01/D02/D03 operations, relative positioning, duplicate
definitions, and combined G01/G02/G03 commands. - Added validated single- and multi-quadrant arc interpolation, optional I/J offsets, correctly stroked full circles,
and arc support inside regions. - Replaced the aperture regex parser with allocation-conscious validated parsing and fixed clipped rectangle flashes
near image boundaries. - Added ordered macro variable assignments, invariant-culture expression evaluation, malformed-input handling, outline
vertex validation, and rotation around the macro origin for every primitive. - Consolidated duplicated primitive expression logic and reduced temporary allocations throughout parsing and drawing.
- Capture the coordinate sign so negative plots are placed correctly. by @The-Bootloader (#1133)
- Auto-center the artwork, render it upright, and optionally by @The-Bootloader (#1133)
- Warn when a drill file would be silently ignored. by @The-Bootloader (#1133)
- Add anchors to PCB render
- Excellon:
- Reworked coordinate and tool parsing to handle declared formats, signed and decimal coordinates, zero suppression,
omitted axes, and malformed input without regex allocations or parser exceptions. - Added incremental coordinates, repeats, routed linear slots, G85 slots, M71/M72 units, and G90/G91 positioning.
- Fixed
FILE_FORMATfractional precision, asymmetric pixel scaling, duplicate tools, stale parser state, and
invariant-culture serialization. - Added slot rendering and deterministic sizing validation.
- Reworked coordinate and tool parsing to handle declared formats, signed and decimal coordinates, zero suppression,
- GCode:
- Audited the complete GCode builder, command, and layer-state implementations.
- Fixed invariant-culture output, command equality/hash consistency, line counting, compact command parsing, numeric
validation, LED-off detection, PWM scaling, sync-delay detection, and layer bounds/state resets. - Fixed relative retract acceleration, zero-valued retract suppression, event arguments, Klipper setup idempotence,
malformed thumbnail handling, and out-of-range layer detection. - Reduced rebuild work by reusing movement lists, replacing quadratic remaining-time sums with a running total, and
avoiding thumbnail chunk allocations.
- File formats:
- Reduced GCode thumbnail and FlashForge SVGX path-building allocations with bounded stack-backed and sparse DotNext
buffer writers. - Made FlashForge SVG coordinate serialization culture-invariant.
- Add
GetRleBufferInitialCapacityhelper toFileFormatfor consistent RLE buffer sizing - Add Goo V5.0, V5.1 and V5.2 support by @AlchMeow (#1129) fixes #1114
- Refactor RLE encode/decode across all file formats to use
BufferWriterSlim<byte>instead ofList<byte>, reducing
allocations - Replace
List<byte>layer line buffers withMemoryOwner<byte>usingArrayPoolfor pooled, zero-copy layer
encoding/decoding - Improve robustness: add bounds checks to RLE decoders, dispose Mat on error, validate ZIP entry sizes
- Fix
CTBEncryptedFile.CryptFileto use a shared backing buffer instead of copying - Fix
SL1FileswappedBottomLightPWM/LightPWMdefault values - Fix
NanoDLPFileincorrectDisplayControllercondition - Fix
KlipperFileregex group count checks and float parsing withInvariantCulture - Fix
ZCodexFiledivision-by-zero whenLayerCount == 0
- Reduced GCode thumbnail and FlashForge SVGX path-building allocations with bounded stack-backed and sparse DotNext
- Layer compression:
- Preserved sparse, incrementally growing compression streams for large matrices while reducing Zstandard
decompression overhead by decoding directly into the destination matrix. - Rejected truncated, oversized, and dimension-mismatched LZ4 and Zstandard decompressed data.
- Preserved sparse, incrementally growing compression streams for large matrices while reducing Zstandard
- Mesh export:
- Added shared stack-buffered, invariant UTF-8 record formatting across AMF, 3MF, OBJ, OFF, PLY, STL, and WRL exports.
- Replaced repeated dictionary lookups with single-probe vertex-cache access in all indexed mesh exporters.
- Combined binary PLY vertex/face records and STL triangles into one stream write per record without heap allocations.
- Removed per-candidate string allocations from mesh extension lookup and made matching case-insensitive.
- Fixed cropped rotation/flip exports, non-square pixel pitch after quarter-turn rotation, and layer Z placement.
- Made cancellation, temporary writer, and voxel subtraction-matrix cleanup deterministic while preserving the
selected output extension.
- Suggestions:
- Audited every suggestion for validation, cancellation, progress ownership, malformed profile handling, and avoidable
work. - Fixed bottom-layer target caps, transition-layer zero-step handling and reporting, and exact/stable model corner
placement. - Corrected bottom/normal limits, clamping, proportional inputs, and light-off-delay handling for wait-before-cure and
wait-after-cure suggestions. - Removed repeated transition-layer scans, made random anchors allocation-free, and replaced whole-file XML regex
matching with secure streaming profile discovery.
- Audited every suggestion for validation, cancellation, progress ownership, malformed profile handling, and avoidable
- Advanced image box:
- Fixed zoom-level navigation skipping adjacent levels and failing with an empty level collection
- Corrected centered zoom anchoring and tracker-image sizing when automatic tracker zoom is disabled
- Made pointer panning and selection end reliably when the pointer is released outside the control
- Rejected empty zoom regions and clipped selections safely to image bounds
- Optimize
FileStreamExtensionsread/write methods usingBinaryPrimitivesand stack-allocated spans - Fix .gitignore the NUKE temp directory by @The-Bootloader (#1132)
- Rename "010" solution folder to work around Nuke source generator bug by @The-Bootloader (#1133)
- (Upgrade) .NET from 10.0.9 to 10.0.10
- (Upgrade) AvaloniaUI from 12.0.5 to 12.1.1
v6.1.0
- (Add) Zstd/Zstandard layer compression
- (Add) UI Scaling setting to allow to scale the UI to your preference
- (Change) Default compressor from
BrotlitoDeflate - (Improvement) Move the
EmguCVextensions and classes to a separate libraryEmguExtensionsand rewrite most of it,
providing a boost in performance and fixing bugs: #1118, #1119 - (Improvement) Better memory management when compressing layers
- (Improvement) Use
OptimalMaxDegreeOfParallelismsetting forMaxDegreeOfParallelismby default at core, this
affectsUVtoolsCmdand libraries that might useUVtools.Core - (Improvement) Allow to set array of strings via reflection, this simplifies the use of
UVtoolsCmd(#1127) - (Improvement) Migrate
BindableBasetoObservableObjectfromCommunityToolkit.Mvvm - (Improvement) Migrate to
Nukebuilds and publish - (Breaking change) As
EmguCVextensions moved to a separate library, if you are using them in your own code/scripts
you need to adapt and use the new naming and reference the new library - (Fix) Anycubic zip format after save can not be loaded again in anycubic slicer (#1108)
- (Fix) Goo: Disallow open files with a version that is not known by decoder (#1114)
- (Fix) Calibrate - Exposure Finder: NullReferenceException when loading profiles (#1109)
- (Upgrade) .NET from 10.0.5 to 10.0.9
- (Upgrade) AvaloniaUI from 11.3.13 to 12.0.5
- (Upgrade) openCV from 4.12.0 to 4.13.0
Benchmark:
*** 64.goo ****
Layer count: 3144
Resolution: 11520 x 5120
Pixels: 58982400
Uncompressed size/layer: 56.25 MB
Total uncompressed size: 172.71 GB
- Compressed with Png @ Lowest level:
- Layers cache size: 932.12 MB
- Compression ratio: 189.73x (99.47% saved)
- Took: 00:00:58.0968780 (3044.05 MB/s)
- Efficiency score: 0.33
Opening file 64.goo: Done in 55.87s
- Compressed with Png @ Optimal level:
- Layers cache size: 891.05 MB
- Compression ratio: 198.47x (99.50% saved)
- Took: 00:00:55.8672170 (3165.54 MB/s)
- Efficiency score: 0.36
Opening file 64.goo: Done in 214.33s
- Compressed with Png @ Highest level:
- Layers cache size: 383.46 MB
- Compression ratio: 461.19x (99.78% saved)
- Took: 00:03:34.3342806 (825.11 MB/s)
- Efficiency score: 0.22
*** Compressing with GZip ***
Opening file 64.goo: Done in 21.25s
- Compressed with GZip @ Lowest level:
- Layers cache size: 1.56 GB
- Compression ratio: 111.01x (99.10% saved)
- Took: 00:00:21.2451546 (8324.25 MB/s)
- Efficiency score: 0.52
Opening file 64.goo: Done in 23.23s
- Compressed with GZip @ Optimal level:
- Layers cache size: 467.83 MB
- Compression ratio: 378.02x (99.74% saved)
- Took: 00:00:23.2257618 (7614.39 MB/s)
- Efficiency score: 1.63
Opening file 64.goo: Done in 86.36s
- Compressed with GZip @ Highest level:
- Layers cache size: 365.84 MB
- Compression ratio: 483.41x (99.79% saved)
- Took: 00:01:26.3654719 (2047.69 MB/s)
- Efficiency score: 0.56
*** Compressing with Deflate ***
Opening file 64.goo: Done in 20.66s
- Compressed with Deflate @ Lowest level:
- Layers cache size: 1.56 GB
- Compression ratio: 111.02x (99.10% saved)
- Took: 00:00:20.6646495 (8558.09 MB/s)
- Efficiency score: 0.54
Opening file 64.goo: Done in 22.15s
- Compressed with Deflate @ Optimal level:
- Layers cache size: 467.77 MB
- Compression ratio: 378.07x (99.74% saved)
- Took: 00:00:22.1466998 (7985.39 MB/s)
- Efficiency score: 1.71
Opening file 64.goo: Done in 82.43s
- Compressed with Deflate @ Highest level:
- Layers cache size: 365.79 MB
- Compression ratio: 483.48x (99.79% saved)
- Took: 00:01:22.4335569 (2145.36 MB/s)
- Efficiency score: 0.59
*** Compressing with Brotli ***
Opening file 64.goo: Done in 31.06s
- Compressed with Brotli @ Lowest level:
- Layers cache size: 944.61 MB
- Compression ratio: 187.22x (99.47% saved)
- Took: 00:00:31.0634355 (5693.19 MB/s)
- Efficiency score: 0.60
Opening file 64.goo: Done in 25.10s
- Compressed with Brotli @ Optimal level:
- Layers cache size: 449.87 MB
- Compression ratio: 393.11x (99.75% saved)
- Took: 00:00:25.1045734 (7044.53 MB/s)
- Efficiency score: 1.57
*** Compressing with Lz4 ***
Opening file 64.goo: Done in 20.53s
- Compressed with Lz4 @ Lowest level:
- Layers cache size: 1.55 GB
- Compression ratio: 111.29x (99.10% saved)
- Took: 00:00:20.5324849 (8613.18 MB/s)
- Efficiency score: 0.54
Opening file 64.goo: Done in 33.89s
- Compressed with Lz4 @ Optimal level:
- Layers cache size: 675.15 MB
- Compression ratio: 261.94x (99.62% saved)
- Took: 00:00:33.8888118 (5218.54 MB/s)
- Efficiency score: 0.77
Opening file 64.goo: Done in 330.08s
- Compressed with Lz4 @ Highest level:
- Layers cache size: 645.46 MB
- Compression ratio: 273.99x (99.64% saved)
- Took: 00:05:30.0777280 (535.78 MB/s)
- Efficiency score: 0.08
*** Compressing with Zstd ***
Opening file 64.goo: Done in 22.51s
- Compressed with Zstd @ Lowest level:
- Layers cache size: 608.55 MB
- Compression ratio: 290.61x (99.66% saved)
- Took: 00:00:22.5071716 (7857.50 MB/s)
- Efficiency score: 1.29
Opening file 64.goo: Done in 28.94s
- Compressed with Zstd @ Optimal level:
- Layers cache size: 413.11 MB
- Compression ratio: 428.09x (99.77% saved)
- Took: 00:00:28.9375050 (6111.45 MB/s)
- Efficiency score: 1.48
Opening file 64.goo: Done in 34.88s
- Compressed with Zstd @ Highest level:
- Layers cache size: 426.33 MB
- Compression ratio: 414.82x (99.76% saved)
- Took: 00:00:34.8796002 (5070.30 MB/s)
- Efficiency score: 1.19
*** Total benchmark time: 00:18:31.4016417 ***
*** Results: ***
Png @ Lowest | Size: 932.12 MB | Ratio: 189.73x | Saved: 99.47% | Time: 00:00:58.0968780 | Speed: 3044.05 MB/s | Efficiency: 0.33
Png @ Optimal | Size: 891.05 MB | Ratio: 198.47x | Saved: 99.50% | Time: 00:00:55.8672170 | Speed: 3165.54 MB/s | Efficiency: 0.36
Png @ Highest | Size: 383.46 MB | Ratio: 461.19x | Saved: 99.78% | Time: 00:03:34.3342806 | Speed: 825.11 MB/s | Efficiency: 0.22
GZip @ Lowest | Size: 1.56 GB | Ratio: 111.01x | Saved: 99.10% | Time: 00:00:21.2451546 | Speed: 8324.25 MB/s | Efficiency: 0.52
GZip @ Optimal | Size: 467.83 MB | Ratio: 378.02x | Saved: 99.74% | Time: 00:00:23.2257618 | Speed: 7614.39 MB/s | Efficiency: 1.63
GZip @ Highest | Size: 365.84 MB | Ratio: 483.41x | Saved: 99.79% | Time: 00:01:26.3654719 | Speed: 2047.69 MB/s | Efficiency: 0.56
Deflate @ Lowest | Size: 1.56 GB | Ratio: 111.02x | Saved: 99.10% | Time: 00:00:20.6646495 | Speed: 8558.09 MB/s | Efficiency: 0.54
Deflate @ Optimal | Size: 467.77 MB | Ratio: 378.07x | Saved: 99.74% | Time: 00:00:22.1466998 | Speed: 7985.39 MB/s | Efficiency: 1.71
Deflate @ Highest | Size: 365.79 MB | Ratio: 483.48x | Saved: 99.79% | Time: 00:01:22.4335569 | Speed: 2145.36 MB/s | Efficiency: 0.59
Brotli @ Lowest | Size: 944.61 MB | Ratio: 187.22x | Saved: 99.47% | Time: 00:00:31.0634355 | Speed: 5693.19 MB/s | Efficiency: 0.60
Brotli @ Optimal | Size: 449.87 MB | Ratio: 393.11x | Saved: 99.75% | Time: 00:00:25.1045734 | Speed: 7044.53 MB/s | Efficiency: 1.57
Lz4 @ Lowest | Size: 1.55 GB | Ratio: 111.29x | Saved: 99.10% | Time: 00:00:20.5324849 | Speed: 8613.18 MB/s | Efficiency: 0.54
Lz4 @ Optimal | Size: 675.15 MB | Ratio: 261.94x | Saved: 99.62% | Time: 00:00:33.8888118 | Speed: 5218.54 MB/s | Efficiency: 0.77
Lz4 @ Highest | Size: 645.46 MB | Ratio: 273.99x | Saved: 99.64% | Time: 00:05:30.0777280 | Speed: 535.78 MB/s | Efficiency: 0.08
Zstd @ Lowest | Size: 608.55 MB | Ratio: 290.61x | Saved: 99.66% | Time: 00:00:22.5071716 | Speed: 7857.50 MB/s | Efficiency: 1.29
Zstd @ Optimal | Size: 413.11 MB | Ratio: 428.09x | Saved: 99.77% | Time: 00:00:28.9375050 | Speed: 6111.45 MB/s | Efficiency: 1.48
Zstd @ Highest | Size: 426.33 MB | Ratio: 414.82x | Saved: 99.76% | Time: 00:00:34.8796002 | Speed: 5070.30 MB/s | Efficiency: 1.19
*** Sorted by best compression ratio: ***
Deflate @ Highest | Size: 365.79 MB | Ratio: 483.48x | Saved: 99.79% | Time: 00:01:22.4335569 | Speed: 2145.36 MB/s | Efficiency: 0.59
GZip @ Highest | Size: 365.84 MB | Ratio: 483.41x | Saved: 99.79% | Time: 00:01:26.3654719 | Speed: 2047.69 MB/s | Efficiency: 0.56
Png @ Highest | Size: 383.46 MB | Ratio: 461.19x | Saved: 99.78% | Time: 00:03:34.3342806 | Speed: 825.11 MB/s | Efficiency: 0.22
Zstd @ Optimal | Size: 413.11 MB | Ratio: 428.09x | Saved: 99.77% | Time: 00:00:28.9375050 | Speed: 6111.45 MB/s | Efficiency: 1.48
Zstd @ Highest | Size: 426.33 MB | Ratio: 414.82x | Saved: 99.76% | Time: 00:00:34.8796002 | Speed: 5070.30 MB/s | Efficiency: 1.19
Brotli @ Optimal | Size: 449.87 MB | Ratio: 393.11x | Saved: 99.75% | Time: 00:00:25.1045734 | Speed: 7044.53 MB/s | Efficiency: 1.57
Deflate @ Optimal | Size: 467.77 MB | Ratio: 378.07x | Saved: 99.74% | Time: 00:00:22.1466998 | Speed: 7985.39 MB/s | Efficiency: 1.71
GZip @ Optimal | Size: 467.83 MB | Ratio: 378.02x | Saved: 99.74% | Time: 00:00:23.2257618 | Speed: 7614.39 MB/s | Efficiency: 1.63
Zstd @ Lowest | Size: 608.55 MB | Ratio: 290.61x | Saved: 99.66% | Time: 00:00:22.5071716 | Speed: 7857.50 MB/s | Efficiency: 1.29
Lz4 @ Highest | Size: 645.46 MB | Ratio: 273.99x | Saved: 99.64% | Time: 00:05:30.0777280 | Speed: 535.78 MB/s | Efficiency: 0.08
Lz4 @ Optimal | Size: 675.15 MB | Ratio: 261.94x | Saved: 99.62% | Time: 00:00:33.8888118 | Speed: 5218.54 MB/s | Efficiency: 0.77
Png @ Optimal | Size: 891.05 MB | Ratio: 198.47x | Saved: 99.50% | Time: 00:00:55.8672170 | Speed: 3165.54 MB/s | Efficiency: 0.36
Png @ Lowest | Size: 932.12 MB | Ratio: 189.73x | Saved: 99.47% | Time: 00:00:58.0968780 | Speed: 3044.05 MB/s | Efficiency: 0.33
Brotli @ Lowest | Size: 944.61 MB | Ratio: 187.22x | Saved: 99.47% | Time: 00:00:31.0634355 | Speed: 5693.19 MB/s | Efficiency: 0.60
Lz4 @ Lowest | Size: 1.55 GB | Ratio: 111.29x | Saved: 99.10% | Time: 00:00:...