v1.40a - Undo/Redo, Path-Sweeps, Merge-Down Paths, Rectangle Select Paths/Nodes, UI Icons, Etcetera...





I've decided to start posting a screenshot of what PixelCNC looks like with a generic test-project open, so users can see the immediate differences in the interface that are not readily apparent when reading the changes.txt or following development via social media. At any rate, without fail, this update's change list ballooned to be twice as large as I had imagined it would end up being. Nonetheless, everything was necessary and was going to be done sooner or later. This update includes several new features, many changes, and even more fixes. Here's the changes.txt for v1.40a:

added undo/redo system to canvas layer system for undoing edits to layers' contents as well as undoing changes to a layer's properties and state

added path-sweep function to path-editing mode for extruding "profile" paths along either a single "rail" path or spanning between two paths (select "sweep paths" while in path-editing mode)

added path-breaking removal a selected node w/ right-click, hold SHIFT to remove node from path without breaking it into two separate paths

added merge-down functionality for combining path-layers

added path/node selection-rectangle when holding shift + left-click-drag

added show/hide grid-plane button

added automatic scaling of grid-plane with camera's Z origin

added UI value slider logic to confine mouse cursor to slider track

added rudimentary smoothing to camera manipulation

added clamping of project dimensions and pixel density to prevent enormous depthmaps from accidentally being created and leading to a crash. users are presented with a warning beforehand that that project's dimensions and pixel density will be defaulted to safe values.

added persistent rendering of layer position within the top/bottom planes of the canvas, to reduce visual confusion about the vertical position of layers

added more icons to user interface, primarily menus and dialogs

added "always draw" mode to existing show/hide occluded toolpath modes

added indication as to a project's measurement units beneath button bar

changed button bar grid buttons to remain visible when not in canvas mode

changed project file version to 17 (removed path/node selection bits)

changed raster-editing brush to not be shown when outside of layer boundary

changed scale of colored machine-origin axes to half their previous size

changed several UI fonts to improve their quality and readability

changed default font to Tahoma

changed "simple update" under "view settings" to be enabled by default

changed "canvas height" parameter to physical size measurement

changed pocketing operation to offset by cutter radius by default when contour offset is set to zero instead of centered on pocket contour's edge (auto-subtracts cutter radius from offset when loading pre-v17 projects)

changed color of selected raster/text layer's content render to red when the layer's visibility is disabled

changed simulation speed curve function to allow for finer control over simulation speed at lower values

changed simulation speed from an arbitrary range of values to a percentage

changed layer smoothing radius from increment/decrement button to slider

changed to newer version of SDL for needed bugfixes

fixed layer getting stuck with a size of zero when scaling via handles

fixed scaling layer to negative size causing origin to slide

fixed toolpath "moves overflow" error when generating long toolpaths

fixed bug leading to crashes after deletion of layer while in raster-edit mode

fixed bug with maintaining path/node selections in path-editing mode

fixed bug causing path to become deselected while adding nodes to extend it

fixed bug when closing a path causing duplicate node-handles to be created for the path's initial node

fixed raster-layer merging not scaling layer z-size to resulting depth image

fixed bug in lighting calculations for the parallax occlusion mapping "raymarched simulation" render mode

fixed grid-snap layer positioning not aligning layer origin with grid if canvas size/origin do not align front-left corner of canvas with the grid

fixed crash/error caused by race condition in text-layer font rendering when regenerating project canvas depthmap

fixed interruption of view camera motion input when mouse cursor overlaps the selected layer's grab-handles

fixed canvas mesh not updating when changes to "canvas height" have been made with meshed canvas rendering mode enabled

fixed knot-allocation error when trying to create a new path on a paths-layer that was created from the selected paths of another paths-layer

fixed freeze when quitting while simulation is still playing

fixed value clamping on raster-layers produced via shape-from-paths after applying brush-strokes in raster-edit mode

re-fixed enforcement of cutpath motion angles over min/max length which resulted in irregular chevrons; previously fixed pre-v1.33a but was broken again when cut path generation with many small colinear motions was fixed

fixed stability issues around text-layer systems that resulted from multithreading race-conditions

fixed incorrect z-sizing of resulting raster-layer after a merge-down

fixed internal timing and framerate calculation losing precision the longer that the program has been left running on the system





Undo/Redo System





A generalized "event" system has been added to enable queuing and de-queuing of various data for users to undo the previous series of actions - or re-do undone ones. It hasn't been completely fleshed out yet with tracking the entering or leaving of layer editing modes but it does undo raster-edits, path-edits, and text-edits, along with any changes to the canvas or a layer's parameters. Now users can edit their raster/paths layers without having to worry about making mistakes!





Single/Double Rail Path-Sweep

Paths are no longer limited to creating 3D shape raster-layers strictly from closed-paths (i.e. angled, fixed-radius fillet, rounded). Now users can use open paths (not connecting back to themselves in a loop) as "profiles" which are extruded along one, or between two, "rail" paths. Here's a simple single-rail path-sweep, using a single path as both the starting and ending profiles:









Different sized/shaped profile paths are blended between too:









Double-rail path-sweeps allow profiles to be positioned per-rail. Although this allows for crossing profiles the result will not be exactly what one would predict as a profile's "point of maximum influence" on each rail is only for each rail, and not along the length of the profile when they are crossing. Instead, each output pixel's depth value is calculated from the four surrounding points on rails, and treated as a sort of quadrilateral interpolation:









Rail-paths have their start and end points indicated with green and red dots, respectively. For double-rail path-sweeps it's important that both rails start and end in the same direction. If a rail's path has its nodes in the wrong order users can simply toggle the 'flip' option shown next to the "remove rail" trashcan icon button:









Selection Rectangle

Selecting paths no longer requires that users manually select individual paths or nodes one-by-one with individual left-clicks while holding SHIFT. Users can now draw a selection rectangle using a left-click-drag while holding down the SHIFT key when in path editing mode. When no paths are selected this will initially select only all of the paths which the selection rectangle happens to overlap - not requiring that the paths lie entirely within the rectangle (this may be be changed, or opened up to users to choose per their preference). If there is already a selection of paths then the selection rectangle will instead select all of the selected paths' nodes that lie within the rectangle.





The path/node selection behavior of the selection rectangle stands to be further refined, particularly to allow multiple groups of paths to be selected using separate rectangle selections - instead of only allowing the user to make a single selection of paths before they're limited to only selected nodes after the initial path selection has been made. Perhaps holding the CTRL and SHIFT keys will signify that more paths are being added to the existing selection of paths? More thought needs to be put into what the best course of action will be here.

All other means of selecting and editing paths/nodes are still in place and much of the conventions involved follow those of other popular software, path-editing or otherwise. Once users actually start playing with path-editing in PixelCNC it's really rather intuitive and quick to get the hang of. It will be especially pleasant once the undo system is capable of maintaining a user's previous selections and editing-state while in path-editing mode, and not booting them out of editing mode if they undo an edit. At any rate a built-in guide to assist users in knowing what their immediate options are while editing a paths-layer is planned for integration in a near-future release. In the meantime path-editing information is included within the User Guide and there's also a quick reference that can be accessed via the "Edit Paths Help" question-mark-icon button on the right UI panel for users to quickly determine what key presses and mouse clicks or drags they can use.





Layer Vertical Position Indication





Previously it could be difficult to discern the vertical positioning of a layer just by its outlines. Now PixelCNC draws a set of lines extending from the bottom corners of the selected layer to the bottom-plane of the canvas, and from the top of the selected layer to the top-plane of the canvas. The coloration of the layer's top/bottom extents also will change from green, when within the top/bottom of the canvas, to red, when above or below the the canvas. This should help users quickly understand the positioning and scaling of their layers relative to the canvas more so than was the case prior to v1.40a.







Fixed Layer-Scaling Issues





Above is a GIF demonstrating how pre-v1.40a layer sizing behavior allowed the layer origin to shift away once the layer's size had been reduced to zero, if the user continued dragging the sizing handle of the layer "into the negative". If the user happened to release the layer handle when its size was reduced to zero like this it would result in the layer getting "stuck" with a dimension of zero. This could be manually rectified via the layer's properties on the UI's right-panel by just typing in a new non-zero value for the stuck dimension. v1.40a now simply prevents users from both sliding a layer's origin around when they drag the layer to a size of zero, and also pops the layer back out upon release to the current grid subdivision as a minimum value.





Fixed Timing

PixelCNC's timing code, which is used for both clamping framerate and keeping track of logfile timestamps, would gradually lose precision the longer that it was left running on the system. This would begin to cause some erratic behavior, including causing the framerate to slowly dwindle down. Within just a few hours the framerate (when clamp-framerate is enabled via the View Settings dialog - as it should be if users wish to maximize performance of computation-intensive functionality!) would drop into the upper 50s and continue dropping by a few frames per-second every several hours. PixelCNC should now be able to run for months and months, if not years, without any of these issues causing problems.





Numerous Fixes and UI Changes

This update comes with a number of other fixes - issues which caused crashes, errors, and several which were just a nuisance or inconvenience insofar as usability of the interface itself is concerned. Most of these were a bit spur-of-the-moment, as many of the fixes across all PixelCNC versions have been. There are always some planned fixes with each update but many of these fixes are the result of bugs which are stumbled upon by accident.

There have also been quite a number of UI changes, many which aren't even listed in the changes.txt simply because they were decidedly unplanned and occurred purely as the result of taking some time to experiment with things. I hope that the end result is more appealing to everyone than previous versions' were. Anyone who has any suggestions/feedback please do not hesitate to share with us either in a comment on a devlog post, or on the PixelCNC community forums. Every little bit helps!





...What's Next?

There are a lot of things left on the todo list, and not all of them will necessarily find their way into v1.41a, if any version at all. It's a question of time budgeting. The goal for now is to get PixelCNC into its beta phase of development before summer 2020, which means implementing all of the major features and leaving most of the polishing work for afterward. In the meantime, there are the things that I feel are important for the immediate future: