Skip to content

Releases: mkeeter/fidget

v0.4.0

07 Sep 18:04
eb501bf

Choose a tag to compare

v0.4.0 Pre-release
Pre-release

Splitting into multiple crates

The focus of this release is splitting fidget into a set of smaller crates, for improved compile times and modularity. This brings a clean build of fidget (time cargo build --release -pfidget) down from 60 to 45 seconds on my laptop, a significant improvement!

For the most part, this should be transparent: each smaller crate is re-exported by the fidget root crate. However, a few things got moved around to improve modularity:

  • Image (bitmap and heightmap) rendering is moved from fidget::render to a separate fidget::raster module. Anything which was used by both image and mesh rendering remains in fidget::render.
  • View2 and View3 have moved to fidget::gui

The helper crates can be enabled with fine-grained features on the root fidget crate, for use cases where a smaller fidget is helpful.

Other changes

  • Return DoubleEndedIterator from RegTape::iter() and SsaTape::iter(), making it easier to iterate in reverse order.
  • Tighter interval bounds on sin and cos (thanks @alexneufeld)

v0.3.9

01 Sep 19:31
cc68659

Choose a tag to compare

v0.3.9 Pre-release
Pre-release

This release fixes a bunch of small issues encountered while building a design tool on top of the Fidget kernel.

  • Fix panic in tape construction if a multi-output expression has a constant as an output.
  • Add Function::can_simplify to check whether a Function can ever be simplified (if not, then interval evaluation isn't as useful).
  • Fix invalid access when doing bulk evaluation on a Function with more than one output. This caused a panic using the VM evaluator, and a segfault (typically) using the JIT evaluator.
  • Make PartialEq for Tree objects do deep comparisons, instead of shallow (pointer) equality
    • This is more expensive, but matches typical data structures in Rust
    • Tree::ptr_eq can be used to perform shallow equality checks
  • Changed 3D image rendering to saturate when voxels are touching the camera. Saturated voxels snap to the image's depth and have a normal of [0, 0, 1].
  • Replaced view in ImageRenderConfig, VoxelRenderConfig, and mesh::Settings with a generic world_to_model matrix, for more flexibility when rendering.
  • Add mathematical constants for Rhai scripts (PI, E, TAU...)
  • Add std::ops::Neg implementation for Vec2,3,4 types, in both Rust and Rhai.
  • Remove Shape::apply_transform; there were too many ways to apply transforms to shapes, and having mutable operations on a handle passed by Clone opens up possibilities for confusion. Here's the new plan:
    • When using high-level algorithms (e.g. meshing and rendering), the world-to-model transform is now only set by the world_to_model matrix in the config or settings object (ImageRenderConfig, VoxelRenderConfig, mesh::Settings)
    • When using a Shape directly, a transform can be set with Shape::with_transform. This returns a new Shape<F, Transformed>, where Transformed is a marker type indicating that the transform field is Some(..). Shape::with_transform is a one-way operation: it's only available on Shape<F> (which is actually now Shape<F, ()>). Note that high-level operations require a Shape<F, ()>, because they set the transform themselves!
  • Add vec2([..]) and vec3([..]) functions to Rhai environment
  • Fix remap_affine composition; previously, it applied operations in the wrong order given multiple affine transformations.
  • New shapes: Rectangle, Box, Rotate(X|Y|Z), Blend, Plane, ScaleUniform, RevolveY, ExtrudeZ, LoftZ
  • Added ordered constructors to Rhai bindings, e.g. rectangle([0,0], [1,1]). These are only available if a previous constructor didn't use the same function prototype.
  • Added cancel: CancelToken to fidget::mesh::Settings
    • Octree::build now returns an Option<..>, which is None if it was cancelled
  • Removed Settings from Octree::walk_dual, because we aren't actually doing any multithreading
  • Switched various mesh functions to take Settings by reference instead of by value, because CancelToken is not Copy.
  • Make Rhai vec2(..) and vec3(..) functions idempotent, i.e. vec2(vec2(..)) now works.
  • Optimize atan2 interval evaluation

v0.3.8

25 Jun 22:11
0cd0af8

Choose a tag to compare

v0.3.8 Pre-release
Pre-release

This release focuses heavily on Rhai ergonomics, improving the standard library and making it easier to write scripts.

There are a bunch of other fixes and improvements as well; see the detailed log below or details!

  • Bug fix: Image::height() was returning width instead!
  • Add #[derive(PartialEq)] to View2 and View3
  • Improve rendering at small images sizes
    • Previously, we rendered at least one tile of size cfg.tile_sizes[0]
    • Now, we pick the smallest possible tile size for the root tiles; if we're rendering a 32×32 image with tile sizes of [128, 32, 8], then we'll render a single 32×32 tile (instead of 128×128)
    • As part of this change, a few functions were removed from the TileSizes public API; they're now attached to an internal struct TileSizesRef.
  • Add a new trait ShapeVisitor and pub fn visit_shapes(..) for introspection into shapes and transforms defined in the shapes module. This is expected to be useful for automatically generated scripted bindings (indeed, fidget::rhai now uses it).
  • Added more document to fidget::shapes
  • Made fidget::rhai::shapes::register_shape private
  • Significant changes to 2D rendering API:
    • Changed fidget::render::render2d to always return an Image<DistancePixel>, which encodes either a distance sample or details on fill at that point.
    • Removed the trait RenderMode, which was previously used to generate pixel samples from a distance field.
    • Added ImageRenderConfig::pixel_perfect, which forces sampling down to individual pixels.
    • Added fidget::render::effects::{to_rgba_bitmap, to_debug_bitmap, to_rgba_distance} to post-process an Image<DistancePixel>. These replace the previous RenderMode objects for generating specific flavors of image.
    • Note that approximate SDFs are entirely removed; they were not substantially faster, added complexity, and looked bad.
  • Add #[facet(default = ...)] annotations to relevant fields in
    fidget::shapes.
    • These annotations are used in the Rhai bindings to build shapes without specifying every field, e.g. circle(1) leaves the center as a default value.
  • Fix issue where Shape::eval_* functions would return an empty slice if there were no active variables in the shape; it now returns a slice that's the correct size (i.e. matching the input slices).
  • In Rhai bindings, FromDynamic now takes the field's default value as a hint, which may be used when promoting other types. For example, if you pass a vec2 (instead of a vec3) to both Move and Scale, the z component will be set to 0 for Move and 1 for Scale.
  • Add helper functions to destructure and rebuild Canvas2, Canvas3, View2, and View3 into their component values.
  • Rename fidget::{shapes, rhai}::vec to fidget::{shapes, rhai}::types
  • Add more common types used in shapes and Rhai bindings:
    • Axis is a unit Vec3
    • Plane is an Axis and offset
  • Add Reflect shape, as well as ReflectX/Y/Z
  • Removed fidget::rhai::Engine and fidget::rhai::Axes
    • Previously, fidget::rhai::Engine wrapped a Rhai engine and Fidget-specific functionality
    • The internals of Engine were tightly coupled to fidget-viewer, in ways that weren't useful for other GUIs.
    • Now, fidget::rhai::engine() returns a rhai::Engine object with Fidget types pre-installed, but without the wrapper type.
    • The Rhai draw(..) and draw_rgb(..) functions are moved into fidget-viewer, because they're specific to that one GUI (fidget-cli is also aware of draw, but now has its own simpler implementation).
  • Move Vec2/3/4, Axis, Plane into fidget::shapes::types instead of re-exporting them in fidget::shapes.
  • Make fidget::shapes::types::{Value, Type} public; these represent types which can be used in shapes (with ergonomic Rhai bindings).
  • Fix missing local optimizations in Context::import (e.g. x * 0 => 0)
  • Rename remap_xyz(..) to just remap(..) in Rhai bindings; add a two-argument version which leaves z unchanged

v0.3.7

17 May 23:02
ab77d8b

Choose a tag to compare

v0.3.7 Pre-release
Pre-release
  • Small release to fix an issue with 0.3.6 being published with invalid local changes (I thought cargo prevented this, dunno how it happened)
  • Mark functions on Interval and Grad as #[inline], to improve performance when those types are used outside of the Fidget crate itself.
  • Make fidget::rhai submodules visible (vec, shape, tree) for finer-grained usage outside of Fidget.
  • Update to Rust 2024 edition, set minimum rustc version to 1.87
  • Update dependencies; remove some that have become unused

v0.3.6

25 Apr 12:39
5c7cd4a

Choose a tag to compare

v0.3.6 Pre-release
Pre-release
  • Change Option<ThreadPool<'a>> to Option<&'a ThreadPool> throughout the codebase; moving the reference out of the ThreadPool eliminates the need for a separate rayon::ThreadPool object on the stack.
  • Significant rewrite of meshing! It now uses the same Option<&ThreadPool> type and is multithreaded using Rayon, meaning it can work in WebAssembly.
  • Changed 3D rendering and effects functions to use a new GeometryBuffer type, which combines depth and normal data into a single image.
  • Add fidget::gui module, which defines Canvas2 and Canvas3. The canvas types are stateful abstractions around a GUI canvas, with support for cursor interactions.
  • Change ImageSize::transform_point and VoxelSize::transform_point to take a point with i32 coordinates (instead of f32). This helps us distinguish between screen (pixel) and world (floating-point) coordinates at the type level.
  • Add Tree::remap_affine (and TreeOp::RemapAffine) to perform affine transformations on math expressions. These transformations are composable; two affine transforms will be combined into a single transform if stacked together.
  • Major updates to the Rhai standard library and default bindings:
    • Add vec2, vec3, vec4 types
    • Shapes are now constructed with object maps
    • Added documentation in fidget::rhai::docs module
  • Significant rewrite of meshing! It now uses the same Option<&ThreadPool> type and is multithreaded using Rayon, meaning it can work in WebAssembly.
  • Changed 3D rendering and effects functions to use a new GeometryBuffer type, which combines depth and normal data into a single image.
  • Add fidget::gui module, which defines Canvas2 and Canvas3. The canvas types are stateful abstractions around a GUI canvas, with support for cursor interactions.
  • Change ImageSize::transform_point and VoxelSize::transform_point to take a point with i32 coordinates (instead of f32). This helps us distinguish between screen (pixel) and world (floating-point) coordinates at the type level.
  • Add Tree::remap_affine (and TreeOp::RemapAffine) to perform affine transformations on math expressions. These transformations are composable; two affine transforms will be combined into a single transform if stacked together.
  • Major updates to the Rhai standard library and default bindings:
    • Add vec2, vec3, vec4 types
    • Shapes are now constructed with object maps
    • Added documentation in fidget::rhai::docs module

v0.3.5

06 Mar 21:15
5474b31

Choose a tag to compare

v0.3.5 Pre-release
Pre-release
  • Added #[derive(Serialize, Deserialize)] to View2 and View3
  • Make TranslateHandle take a const N: usize parameter
  • Use TranslateHandle in View2 (previously, it was only used in View3)
  • Make translate and rotate functions borrow their respective handle, instead of taking it by value.
  • Fix docstring for AndRegImm, AndRegReg, OrRegImm, and OrRegReg
  • Add cancel: CancelToken to 2D and 3D rendering configuration objects; this is a shared Arc<AtomicBool> which can be used to stop rendering. The returned type is now an Option<...>, where None indicates that rendering was cancelled.
  • Fix inconsistency between JIT and VM evaluator when performing interval evaluation of not([NAN, NAN]).
  • Propagate NAN values through and and or operations on intervals.
  • Add a new Image<P> generic image type (wrapping a Vec<P>, width, and height).
    • Define DepthImage, NormalImage, and ColorImage specializations
    • Use these types in 2D and 3D rendering
  • Remove Grad::to_rgb in favor of handling it at the image level
  • Add fidget::render::effects module for post-processing rendered images:
    • Combining depth and normal images into a shaded image
    • Denoising normals to fix back-facing samples
    • Computing and applying screen-space ambient occlusion
  • Optimize implementation of interval modulo for cases where the right-hand argument is a positive constant value (which is the most common when using it for domain repetition)
  • Update many dependencies to their latest versions

⚠️ Due to getrandom#504, crates which use Fidget as a library and compile to WebAssembly must select a getrandom backend.

This can be done either on the command line (RUSTFLAGS='--cfg getrandom_backend="wasm_js"') or in a .cargo/config.toml configuration file (e.g. this file in Fidget itself).

v0.3.4

26 Dec 15:34
e2d6698

Choose a tag to compare

v0.3.4 Pre-release
Pre-release
  • Add GenericVmFunction::simplify_with to simultaneously simplify a function and pick a new register count for the resulting tape
  • Add bidirectional conversions between JitFunction and GenericVmFunction (exposing the inner data member)
  • Add a new TileSizes(Vec<usize>) object representing tile sizes used during rendering. Unlike the previous Vec<usize>, this data type checks our tile size invariants at construction. It is used in the struct RenderConfig.
  • Rethink rendering and viewport configuration:
    • Add a new RegionSize<const N: usize> type (with ImageSize and VoxelSize aliases), representing a render region. This type is responsible for the screen-to-world transform
    • Add View2 and View3 types, which stores the world-to-model transform (scaling, panning, etc)
    • Image rendering uses both RegionSize and ViewX; this means that we can now render non-square images!
    • Meshing uses just a View3, to position the model within the ±1 bounds
    • The previous fidget::shape::Bounds type is removed
    • Remove fidget::render::render2d/3d from the public API, as they're equivalent to the functions on ImageRenderConfig / VoxelRenderConfig
  • Move RenderHints into fidget::render
  • Remove fine-grained features from fidget crate, because we aren't actually testing the power-set of feature combinations in CI (and some were breaking!). The only remaining features are rhai, jit and eval-tests.
  • Add new ShapeVars<T> type, representing a map from VarIndex -> T. This type is used for high-level rendering and meshing of Shape objects that include supplementary variables
  • Add Octree::build_with_vars and Image/VoxelRenderConfig::run_with_vars functions for shapes with supplementary variables
  • Change ShapeBulkEval::eval_v to take single variables (i.e. x, y, z vary but each variable has a constant value across the whole slice). Add ShapeBulkEval::eval_vs if x, y, z and variables are all changing through the slices.
  • Add a new GenericVmTape<N> type, and use it for VM evaluation. Previously, the GenericVmFunction<N> type implemented both Tape and Function.
  • Add vars() to Function trait, because there are cases where we want to get the variable map without building a tape (and it must always be the same).
  • Fix soundness bug in Mmap (probably not user-visible)
  • Add Send + Sync + Clone bounds to the trait Tape, to make them easily shared between threads. Previously, we used an Arc<Tape> to share tapes between threads, but tapes were already using an Arc<..> under the hood.
  • Changed Tape::recycle from returning a Storage to returning an Option<Storage>, as tapes may now be shared between threads.
  • Use Rayon for 2D and 3D rasterization
    • The threads member of VoxelRenderConfig and ImageRenderConfig is now a Option<ThreadPool>, which can be None (use a single thread), Some(ThreadPool::Global) (use the global Rayon pool), or Some(ThreadPool::Custom(..)) (use a user-provided pool)
    • This is a step towards WebAssembly multithreading, using wasm-bindgen-rayon.
    • ThreadCount is moved to fidget::mesh, because that's the only place it's now used
      • The plan is to switch to Rayon for meshing as well, eventually
  • Tweak View2 and View3 APIs to make them more useful as camera types

v0.3.3

01 Oct 12:49
68b8c79

Choose a tag to compare

v0.3.3 Pre-release
Pre-release

This release adds multiple outputs to the low-level math and function traits. The high-level Shape object has not changed, although internally it now checks that it's wrapping a single-output Function.

  • Function and evaluator types now produce multiple outputs
    • MathFunction::new now takes a slice of nodes, instead of a single node
    • All of the intermediate tape formats (SsaTape, etc) are aware of multiple output nodes
    • Evaluation now returns a slice of outputs, one for each root node (ordered based on order in the &[Node] slice passed to MathFunction::new)
  • RegisterAllocator no longer binds SSA register 0 to physical register 0 by default. If you don't know what this means, don't worry about it.

v0.3.2

24 Jul 13:30
8ac39f8

Choose a tag to compare

v0.3.2 Pre-release
Pre-release

This release adds symbolic differentiation, along with more ergonomic improvements.

  • Added impl IntoNode for Var, to make handling Var values in a context easier.
  • Added impl From<TreeOp> for Tree for convenience
  • Added Context::export(&self, n: Node) -> Tree to make a freestanding Tree given a context-specific Node.
  • Fix possible corruption of x24 during AArch64 float slice JIT evaluation, due to incorrect stack alignment.
  • Added Context::deriv and Tree::deriv to do symbolic differentiation of math expressions.

v0.3.1

04 Jun 12:09
7a5e389

Choose a tag to compare

v0.3.1 Pre-release
Pre-release

The highlight of this release is the fidget::solver module, which implements the Levenberg-Marquardt algorithm to minimize a system of equations (represented as fidget::eval::Function objects). It's our first official case of using Fidget's types and traits for things other than pure implicit surfaces!

Detailed changelog below:

  • Fixed a bug in the x86 JIT which could corrupt registers during gradient (grad_slice) evaluation
  • Renamed Context::const_value to Context::get_const and tweaked its return type to match Context::get_var.
  • Added impl From<i32> for Tree to make writing tree expressions easier
  • Removed Error::ReservedName and Error::DuplicateName, which were unused
  • Add the fidget::solver module, which contains a simple solver for systems of equations. The solver requires the equations to implement Fidget's Function trait. It uses both point-wise and gradient evaluation to solve for a set of Var values, using the Levenberg-Marquardt algorithm.
  • Add Tree::var() and impl TryFrom<Tree> for Var