blazing fast implicit surface evaluation
MPL-2.0 License
This release adds symbolic differentiation, along with more ergonomic improvements.
impl IntoNode for Var
, to make handling Var
values in a context easier.impl From<TreeOp> for Tree
for convenienceContext::export(&self, n: Node) -> Tree
to make a freestanding Tree
given a context-specific Node
.x24
during AArch64 float slice JIT evaluation, due to incorrect stack alignment.Context::deriv
and Tree::deriv
to do symbolic differentiation of math expressions.Published by mkeeter 5 months ago
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:
grad_slice
) evaluationContext::const_value
to Context::get_const
and tweaked its return type to match Context::get_var
.impl From<i32> for Tree
to make writing tree expressions easierError::ReservedName
and Error::DuplicateName
, which were unusedfidget::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.Tree::var()
and impl TryFrom<Tree> for Var
Published by mkeeter 5 months ago
Shape
(taking (x, y, z)
inputs) to Function
(taking an arbitrary number of variables).Shape
is now a wrapper around a F: Function
instead of a trait.E: BulkEvaluator
or E: TracingEvaluator
, which convert (x, y, z)
arguments into list-of-variables arguments.VmShape
or JitShape
types should be mostly the same as before; changes are most noticeable if you're writing things that are generic across S: Shape
.VarNode
; the canonical variable type is Var
, which is its own unique index.Var
trivially Copy + Clone
.vars()
method to Function
trait, allowing users to look up the mapping from variable to evaluation index. A Var
now represents a persistent identity from Tree
to Context
to Function
evaluation.Var
and VarMap
into fidget::vars
module, because they're no longer specific to a Context
.Op::Input
now takes a u32
argument, instead of a u8
Published by mkeeter 5 months ago
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.
RenderMode::interval
now returns an IntervalAction
, which can be Fill(..)
, Recurse
, or Interpolate
.SdfRenderMode
use this interpolation; the previous pixel-perfect behavior is renamed to SdfPixelRenderModel
RenderMode
trait methods static, because they weren't using &self
fidget::render::render2d
to pass the mode only as a generic parameter, instead of an argumentfloor
, ceil
, round
, atan2
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.tile_sizes_2d
, tile_sizes_3d
, and simplify_tree_during_meshing
into a new fidget::shape::RenderHits
trait. This is a building block for generic (n-variable) function evaluation.Published by mkeeter 5 months ago
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.
VmShape
serialization (using serde
), specifically
#[derive(Serialize, Deserialize)}
on VmData
impl From<VmData<255>> for VmShape { .. }
Tree
objects
Drop
implementationContext::import
to use the heap instead of stackContext::import
to cache the TreeOp → Node
mapping, which is a minor optimization (probably only relevant for unreasonably large Tree
objects)fidget::render::RenderHandle
public and documentedPublished by mkeeter 6 months ago
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:
threads
parameter from various Settings
objects when targeting wasm32
, so that it's harder to accidentally spawn threads (which would panic).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.write-xor-execute
feature, which was extra cognitive load that no one had actually asked for; if you care about it, let me know!Published by mkeeter 7 months ago
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)
}
Context::if_nonzero_else
to build conditionals (using the logical operators added in version 0.2.3)fidget::context::{Tree, TreeOp}
. These types allow construction of math trees without a parent Context
(and therefore without deduplication); the resulting trees can be loaded into a Context
using Context::import
. This replaces the BoundNode
and BoundContext
types (previously only available for unit tests).Context::remap_xyz
in favor of lazy remapping with Tree::remap_xyz
.Tree
in Rhai scripts, removing the per-script Context
. This is an API change: previously, shapes in Rhai were thunks evaluated during calls to draw(..)
; now, shapes in Rhai are Tree
objects, and there's much less function wrangling required.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
).viewer
application when editors move files instead of writing to them directly.Published by mkeeter 7 months ago
compare
operator (equivalent to <=>
in C++ or partial_cmp
in Rust, with the difference that unordered results are returned as NAN
)abs
TransformedShape<S>
, representing a shape transformed by a 4x4 homogeneous matrix. This replaces RenderConfig::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)Bounds
type, representing an X/Y/Z region of interest for rendering or meshing. This overlaps somewhat with TransformedShape
, but it's ergonomic to specify render region instead of having to do the matrixRenderConfig::mat
with a new bounds
member.bounds
member to mesh::Settings
, for octree constructionInterval
and Grad
to fidget::types
module, instead of fidget::eval::types
.modulo
(Euclidean remainder) operationand
, or
, not
), which can be used to build pseudo-conditionals which are simplified by the TracingEvaluator
.Published by mkeeter 7 months ago
sin
, cos
, tan
, asin
, acos
, atan
, exp
, ln
NAN
handling between platforms)Published by mkeeter 8 months ago
This release is mostly small tweaks, but enough performance improvements have piled up that it seems worthwhile!
fidget::eval::Vars
to borrow instead of use an Arc
mmap
regions based on estimated sizeatty
being unmaintainedwasm32-unknown-unknown
target to CI checksPublished by mkeeter 8 months ago
This release includes a significant amount of reorganization and refactoring. There are two main sets of changes, along with some minor tweaks.
Previously, evaluation was tightly coupled to the Tape
type, and individual evaluators were tightly bound to a specific tape. Upon reflection, both of these decisions were reconsidered:
These changes can be seen in the new fidget::eval::Shape
trait, which replaces (but is not equivalent to) the previous fidget::eval::Family
trait.
Compiler modules are reorganized to live under fidget::compiler
instead of being split between fidget::ssa
and fidget::vm
.
fidget::mesh::Settings
.fidget::mesh
modulesPublished by mkeeter 8 months ago
fidget::mesh
module, gated by the mesh
feature (enabled by default).aarch64-unknown-linux-*
to the JIT compiler; previously, aarch64
was only supported on macOS.Published by mkeeter 8 months ago
This release adds an x86_64
backend to the JIT compiler
Published by mkeeter 8 months ago
Point release which attempted to fix documentation rendering (and failed)
Published by mkeeter 8 months ago
Initial release to crates.io