Skip to content

Releases: sn4k3/UVtools

v7.1.2

Choose a tag to compare

@github-actions github-actions released this 26 Oct 22:47
  • (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

Choose a tag to compare

@github-actions github-actions released this 25 Oct 17:30
  • 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 in GerberFormat.UnsupportedCommands.
  • (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 as print-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

Choose a tag to compare

@github-actions github-actions released this 16 Oct 21:22
  • (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) PixelAspectRatio property to show images with non-square pixels, the image is stretched vertically when
      drawing without being resampled, with the ZoomFactorX and ZoomFactorY properties that are the zoom factor of
      each axis. The ZoomFactor is the same as ZoomFactorX (#918).
    • (Add) ImageRotation, FlipHorizontal and FlipVertical properties 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, PixelAspectRatio describes the source pixels, and the TrackerImage is
      transformed like the image. GetSelectedBitmap(true) returns the selection as it is displayed.
    • (Add) Overlays collection to draw vector items over the image: ImageBoxLineOverlay, ImageBoxRectangleOverlay,
      ImageBoxEllipseOverlay, ImageBoxPolylineOverlay (polygon when closed), ImageBoxMarkerOverlay and
      ImageBoxTextOverlay. The geometry is in pixels of the source image and follows the zoom, the scroll, the rotation,
      the flips and the PixelAspectRatio exactly 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, Opacity and IsVisible, changing them redraws the control, ReplaceAll() and AddRange() redraw
      once, the items outside of the viewport are skipped, and ShowOverlays hides them all.
    • (Add) InvalidateImage() method to redraw the control after the pixels of the same Image bitmap were modified in
      place, which raises no change, without touching the zoom, the scroll position or the centering.
    • (Add) BitmapSamplingMode property (Nearest by default, Auto and Smooth) to draw a zoomed out image averaged
      instead of aliased. A WriteableBitmap is 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. Call InvalidateImage() after changing
      the pixels.
    • (Add) GrayscaleImage property and GrayscaleImage class 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) CompositeLayers collection to draw more images over or under the main one with the same ...
Read more

v7.0.3

Choose a tag to compare

@github-actions github-actions released this 09 Oct 02:57
  • 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) 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

Choose a tag to compare

@github-actions github-actions released this 06 Oct 23:07
  • 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.LastPixelIndex pointed
      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
  • (Fix) Crash Cannot access a disposed object on Image.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
  • (Fix) Error when executing UVtooldCmd run with a script (#1138)
  • (Fix) LayerCache disposed the wrong SkiaSurface when the layer was changed, and did not release the framebuffer
  • (Fix) Zstd: the fastest compression level was not really the fastest
  • (Improvement) Update NativeCompressions and use it LZ4 codec
  • (Update) Benchmark 13900K reference values
  • (Drop) K4os.Compression.LZ4 library

v7.0.1

Choose a tag to compare

@github-actions github-actions released this 02 Oct 03:48
  • (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
  • 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

Choose a tag to compare

@github-actions github-actions released this 19 Sep 02:52
  • AdvancedImageBox
    • (Add) PanBoundsMode property to choose the pan bounds mode, if Padding is 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) ZoomLevelCollection now exposes ICollection<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
  • 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
  • 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 / finally across 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 RelayCommand attributes 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
UVtools_2026-09-19_04-43-54 UVtools_2026-09-18_23-13-08 UVtools_2026-09-18_23-16-02

v6.2.0

Choose a tag to compare

@sn4k3 sn4k3 released this 06 Aug 03:08
  • 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_FORMAT fractional precision, asymmetric pixel scaling, duplicate tools, stale parser state, and
      invariant-culture serialization.
    • Added slot rendering and deterministic sizing validation.
  • 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 GetRleBufferInitialCapacity helper to FileFormat for 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 of List<byte>, reducing
      allocations
    • Replace List<byte> layer line buffers with MemoryOwner<byte> using ArrayPool for pooled, zero-copy layer
      encoding/decoding
    • Improve robustness: add bounds checks to RLE decoders, dispose Mat on error, validate ZIP entry sizes
    • Fix CTBEncryptedFile.CryptFile to use a shared backing buffer instead of copying
    • Fix SL1File swapped BottomLightPWM/LightPWM default values
    • Fix NanoDLPFile incorrect DisplayController condition
    • Fix KlipperFile regex group count checks and float parsing with InvariantCulture
    • Fix ZCodexFile division-by-zero when LayerCount == 0
  • 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.
  • 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.
  • 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 FileStreamExtensions read/write methods using BinaryPrimitives and 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

Choose a tag to compare

@sn4k3 sn4k3 released this 27 Jun 23:52
  • (Add) Zstd/Zstandard layer compression
  • (Add) UI Scaling setting to allow to scale the UI to your preference
  • (Change) Default compressor from Brotli to Deflate
  • (Improvement) Move the EmguCV extensions and classes to a separate library EmguExtensions and rewrite most of it,
    providing a boost in performance and fixing bugs: #1118, #1119
  • (Improvement) Better memory management when compressing layers
  • (Improvement) Use OptimalMaxDegreeOfParallelism setting for MaxDegreeOfParallelism by default at core, this
    affects UVtoolsCmd and libraries that might use UVtools.Core
  • (Improvement) Allow to set array of strings via reflection, this simplifies the use of UVtoolsCmd (#1127)
  • (Improvement) Migrate BindableBase to ObservableObject from CommunityToolkit.Mvvm
  • (Improvement) Migrate to Nuke builds and publish
  • (Breaking change) As EmguCV extensions 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:...
Read more

v6.0.3

Choose a tag to compare

@sn4k3 sn4k3 released this 06 Apr 02:45
  • (Fix) Null reference exception on CMat