Releases: mkeeter/fidget
v0.3.4
- Add
GenericVmFunction::simplify_with
to simultaneously simplify a function and pick a new register count for the resulting tape - Add bidirectional conversions between
JitFunction
andGenericVmFunction
(exposing the inner data member) - Add a new
TileSizes(Vec<usize>)
object representing tile sizes used during rendering. Unlike the previousVec<usize>
, this data type checks our tile size invariants at construction. It is used in thestruct RenderConfig
. - Rethink rendering and viewport configuration:
- Add a new
RegionSize<const N: usize>
type (withImageSize
andVoxelSize
aliases), representing a render region. This type is responsible for the screen-to-world transform - Add
View2
andView3
types, which stores the world-to-model transform (scaling, panning, etc) - Image rendering uses both
RegionSize
andViewX
; 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 onImageRenderConfig
/VoxelRenderConfig
- Add a new
- Move
RenderHints
intofidget::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 arerhai
,jit
andeval-tests
. - Add new
ShapeVars<T>
type, representing a map fromVarIndex -> T
. This type is used for high-level rendering and meshing ofShape
objects that include supplementary variables - Add
Octree::build_with_vars
andImage/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). AddShapeBulkEval::eval_vs
ifx
,y
,z
and variables are all changing through the slices. - Add a new
GenericVmTape<N>
type, and use it for VM evaluation. Previously, theGenericVmFunction<N>
type implemented bothTape
andFunction
. - Add
vars()
toFunction
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 thetrait Tape
, to make them easily shared between threads. Previously, we used anArc<Tape>
to share tapes between threads, but tapes were already using anArc<..>
under the hood. - Changed
Tape::recycle
from returning aStorage
to returning anOption<Storage>
, as tapes may now be shared between threads. - Use Rayon for 2D and 3D rasterization
- The
threads
member ofVoxelRenderConfig
andImageRenderConfig
is now aOption<ThreadPool>
, which can beNone
(use a single thread),Some(ThreadPool::Global)
(use the global Rayon pool), orSome(ThreadPool::Custom(..))
(use a user-provided pool) - This is a step towards WebAssembly multithreading, using
wasm-bindgen-rayon
. ThreadCount
is moved tofidget::mesh
, because that's the only place it's now used- The plan is to switch to Rayon for meshing as well, eventually
- The
- Tweak
View2
andView3
APIs to make them more useful as camera types
v0.3.3
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 outputsMathFunction::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 toMathFunction::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
This release adds symbolic differentiation, along with more ergonomic improvements.
- Added
impl IntoNode for Var
, to make handlingVar
values in a context easier. - Added
impl From<TreeOp> for Tree
for convenience - Added
Context::export(&self, n: Node) -> Tree
to make a freestandingTree
given a context-specificNode
. - Fix possible corruption of
x24
during AArch64 float slice JIT evaluation, due to incorrect stack alignment. - Added
Context::deriv
andTree::deriv
to do symbolic differentiation of math expressions.
v0.3.1
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
toContext::get_const
and tweaked its return type to matchContext::get_var
. - Added
impl From<i32> for Tree
to make writing tree expressions easier - Removed
Error::ReservedName
andError::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'sFunction
trait. It uses both point-wise and gradient evaluation to solve for a set ofVar
values, using the Levenberg-Marquardt algorithm. - Add
Tree::var()
andimpl TryFrom<Tree> for Var
v0.3.0
- Major refactoring of core evaluation traits
- The lowest-level "thing that can be evaluated" trait has changed from
Shape
(taking(x, y, z)
inputs) toFunction
(taking an arbitrary number of variables). Shape
is now a wrapper around aF: Function
instead of a trait.- Shape evaluators are now wrappers around
E: BulkEvaluator
orE: TracingEvaluator
, which convert(x, y, z)
arguments into list-of-variables arguments. - Using the
VmShape
orJitShape
types should be mostly the same as before; changes are most noticeable if you're writing things that are generic acrossS: Shape
.
- The lowest-level "thing that can be evaluated" trait has changed from
- Major refactoring of how variables are handled
- Removed
VarNode
; the canonical variable type isVar
, which is its own unique index. - Removed named variables, to make
Var
triviallyCopy + Clone
. - Added
vars()
method toFunction
trait, allowing users to look up the mapping from variable to evaluation index. AVar
now represents a persistent identity fromTree
toContext
toFunction
evaluation. - Move
Var
andVarMap
intofidget::vars
module, because they're no longer specific to aContext
. Op::Input
now takes au32
argument, instead of au8
- Removed
- Fixed a bug in the AArch64 JIT would which could corrupt certain registers during interval evaluation.
v0.2.7
This release brings us to opcode parity with libfive
's operators, adding atan2
and various rounding operations. In addition, there are a few new APIs and rearrangements in preparation for larger refactoring to come.
- Changed to 2D rendering API to support render modes which use linear interpolation to process full / empty regions
- Specifically,
RenderMode::interval
now returns anIntervalAction
, which can beFill(..)
,Recurse
, orInterpolate
. - Modify
SdfRenderMode
use this interpolation; the previous pixel-perfect behavior is renamed toSdfPixelRenderModel
- Make
RenderMode
trait methods static, because they weren't using&self
- Change signature of
fidget::render::render2d
to pass the mode only as a generic parameter, instead of an argument
- Specifically,
- Add new operations:
floor
,ceil
,round
,atan2
- Changed
BulkEvaluator::eval
signature to take x, y, z arguments as&[T]
instead of&[f32]
. This is more flexible for gradient evaluation, because it allows the caller to specify up to three gradients, without pinning them to specific argument. - Moved
tile_sizes_2d
,tile_sizes_3d
, andsimplify_tree_during_meshing
into a newfidget::shape::RenderHits
trait. This is a building block for generic (n-variable) function evaluation.
v0.2.6
This is a relatively small release; there are a few features to improve the WebAssembly demo, bug fixes and improvements for very deep Tree
objects, and one more public API.
- Added
VmShape
serialization (usingserde
), specifically#[derive(Serialize, Deserialize)}
onVmData
impl From<VmData<255>> for VmShape { .. }
- Fixed stack overflows when handling very deep
Tree
objects- Added a non-recursive
Drop
implementation - Rewrote
Context::import
to use the heap instead of stack
- Added a non-recursive
- Updated
Context::import
to cache theTreeOp → Node
mapping, which is a minor optimization (probably only relevant for unreasonably largeTree
objects) - Made
fidget::render::RenderHandle
public and documented
v0.2.5
The highlight of this release is native Windows support (including JIT compilation). Everything should work out of the box; please open an issue if things are misbehaving.
There are a handful of API and feature changes as well:
- Removed
threads
parameter from variousSettings
objects when targetingwasm32
, so that it's harder to accidentally spawn threads (which would panic). - Removed
min_depth
/max_depth
distinction in meshing; this doesn't actually guarantee manifold models (see this scale-invariant adversarial model), so the extra complexity isn't worth it. - Added Windows support (including JIT)
- Removed
write-xor-execute
feature, which was extra cognitive load that no one had actually asked for; if you care about it, let me know!
v0.2.4
The highlight of this release is a refactoring of how shapes are handled in Rhai scripts: instead of being built from thunks (unevaluated closures) and evaluated in draw(..)
and draw_rgb(..)
, they are built directly using a new Tree
object. This makes writing scripts more ergonomic:
// Before
fn circle(cx, cy, r) {
|x, y| {
sqrt((x - cx) * (x - cx) +
(y - cy) * (y - cy)) - r
}
}
// After
fn circle(cx, cy, r) {
let ax = axes();
sqrt((ax.x - cx) * (ax.x - cx) +
(ax.y - cy) * (ax.y - cy)) - r
}
The change is even more noticeable on higher-level functions (functions which operate on shapes):
// Before
fn intersection(a, b) {
|x, y| {
max(a.call(x, y), b.call(x, y))
}
}
// After
fn intersection(a, b) {
a.max(b)
}
Detailed changelog
- Add helper function
Context::if_nonzero_else
to build conditionals (using the logical operators added in version 0.2.3) - Add
fidget::context::{Tree, TreeOp}
. These types allow construction of math trees without a parentContext
(and therefore without deduplication); the resulting trees can be loaded into aContext
usingContext::import
. This replaces theBoundNode
andBoundContext
types (previously only available for unit tests). - Remove
Context::remap_xyz
in favor of lazy remapping withTree::remap_xyz
. - Use
Tree
in Rhai scripts, removing the per-scriptContext
. This is an API change: previously, shapes in Rhai were thunks evaluated during calls todraw(..)
; now, shapes in Rhai areTree
objects, and there's much less function wrangling required. - Remove the distinction between variables and inputs (by removing all
Var
-related functions and opcodes). This was over-engineered; the plan going forward will be to support functions with N inputs (currently fixed to 3,x
/y
/z
). - Improved robustness of
viewer
application when editors move files instead of writing to them directly. - Add Rhai bindings for all new opcodes
- Tweak JIT calling convention to take an array of inputs instead of X, Y, Z arguments.
v0.2.3
- Fix a possible panic during multithreaded 3D rendering of very small images
- Add
compare
operator (equivalent to<=>
in C++ orpartial_cmp
in Rust, with the difference that unordered results are returned asNAN
) - Fix a bug in the x86 JIT evaluator's implementation of interval
abs
- Add generic
TransformedShape<S>
, representing a shape transformed by a 4x4 homogeneous matrix. This replacesRenderConfig::mat
as the flexible strategy for rotation / scale / translation / perspective transforms, e.g. for interactive visualization (where you don't want to remap the underlying shape) - Introduce a new
Bounds
type, representing an X/Y/Z region of interest for rendering or meshing. This overlaps somewhat withTransformedShape
, but it's ergonomic to specify render region instead of having to do the matrix
math every time.- Replaced
RenderConfig::mat
with a newbounds
member. - Added a new
bounds
member tomesh::Settings
, for octree construction
- Replaced
- Move
Interval
andGrad
tofidget::types
module, instead offidget::eval::types
. - Fix an edge case in meshing where nearly-planar surfaces could produce vertexes far from the desired position.
- Add the
modulo
(Euclidean remainder) operation - Add logical operations (
and
,or
,not
), which can be used to build pseudo-conditionals which are simplified by theTracingEvaluator
.