[HN Gopher] Fidget
       ___________________________________________________________________
        
       Fidget
        
       Author : todsacerdoti
       Score  : 525 points
       Date   : 2025-01-08 14:30 UTC (1 days ago)
        
 (HTM) web link (www.mattkeeter.com)
 (TXT) w3m dump (www.mattkeeter.com)
        
       | turnsout wrote:
       | Phenomenal to have a new open source CAD kernel out there! I
       | couldn't tell from the article if this supports export to common
       | formats like STEP. But if so (or once that's possible) it should
       | be a great foundation for some of the open source CAD libraries
       | out there.
        
         | mkeeter wrote:
         | It does not support STEP export, unfortunately, because STEP
         | files use a completely different underlying representation.
         | 
         | Most STEP files represent shapes as a set of surfaces (e.g.
         | trimmed NURBS). These surfaces have to form a watertight
         | manifold, which can be treated as a solid volume.
         | 
         | To make this actually work, you need a kernel for boundary
         | representations (b-reps), rather than Fidget's functional
         | representations (f-reps). Writing such a kernel is a _much
         | harder problem_ - as one example, the intersection of two NURBS
         | surfaces doesn 't always have a closed-form representation! In
         | conversations with someone in the industry, they estimated it
         | would take 6 engineers about a year to write a decent b-rep
         | kernel, _if_ they had done it before.
         | 
         | If you'd like to learn more, I've coincidentally _also_ written
         | a STEP file viewer, which includes a far-from-industrial-
         | strength b-rep kernel:
         | https://www.mattkeeter.com/projects/foxtrot/
        
           | actionfromafar wrote:
           | Could this or the other "Studio" be used to avoid using
           | OpenSCAD when creating models for 3D printing?
        
             | bhaney wrote:
             | I've been using Studio as my primary way of generating
             | models for 3D printing for years now, no OpenSCAD involved.
             | Write some scheme, get an STL.
             | 
             | I do wish Matt would cool it with his constant brilliant
             | endeavors and go back and give Studio some love though. At
             | this point I can't get it to build and can only launch an
             | old version I compiled years ago that breaks if I'm not in
             | some specific working directory in my Downloads folder.
        
               | actionfromafar wrote:
               | Thanks!
        
               | emmelaich wrote:
               | Does anyone know if Zoo/KittyCad uses the similar
               | principles under the hood?
               | 
               | https://zoo.dev/geometry-engine
        
               | fallat wrote:
               | uses brep
        
               | emmelaich wrote:
               | Thanks
               | 
               | https://en.wikipedia.org/wiki/Boundary_representation
        
       | red_trumpet wrote:
       | > Here's the intersection of two exactly-coincident cylinders
       | 
       | The picture looks like the union of two cylinders?
        
         | mkeeter wrote:
         | You're correct, fixed!
        
       | agentultra wrote:
       | Oh neat. I've been meaning to explore SDF/implicit surfaces.
       | 
       | Optimizing for enjoyment/time and writing from scratch are useful
       | exercises!
        
       | jacobparker wrote:
       | Coincidentally I was just reading this other wonderful post from
       | the author https://www.mattkeeter.com/projects/constraints/
        
         | mkeeter wrote:
         | Hah, I actually wrote a similar constrain solver that uses
         | Fidget's evaluation + differentiation! This blog post was
         | getting too long, so I'm going to write it up separately, but
         | in the meantime:
         | 
         | demo: https://mattkeeter.com/projects/fidget/constraints
         | 
         | source:
         | https://github.com/mkeeter/fidget/blob/main/demos/constraint...
         | 
         | docs on the solver:
         | https://docs.rs/fidget/latest/fidget/solver/
        
         | jy14898 wrote:
         | You might be interested in http://omrelli.ug/g9/gallery/ too
        
       | syedrezaali wrote:
       | Matt is a constant source of inspiration. Congrats on the new
       | project Matt!
        
         | mkeeter wrote:
         | Thanks Reza!
        
       | miniBill wrote:
       | Oh wow. This would have been incredibly useful to have found when
       | I was writing my own implicit-surface drawer. My approach is
       | similar in some ways (interval arithmetic), and different in
       | others (not as optimized, I directly produce GLSL for a fragment
       | shader).
       | 
       | Honestly I'm tempted to just toss everything away and replace it
       | with (a reimplementation of) this. Dunno if I should be happy or
       | sad about that.
        
         | dleink wrote:
         | Happy! You work in a field where you can both make your own
         | tools and use tools others have created. Maybe you can steal
         | some of his ideas and use them, or use his stuff and contribute
         | to the project. either way, rad.
        
       | adius wrote:
       | Related: Fornjot - b-rep CAD kernel in Rust
       | https://github.com/hannobraun/fornjot
        
       | mkeeter wrote:
       | Hi, this is my project :)
       | 
       | I particularly love this corner of CS because there's something
       | for everyone - data structures and algorithms, low-level
       | performance work, compilers, rendering / computer graphics, UI/UX
       | for design tools, GPGPU programming, and more!
       | 
       | I'll be answering questions in the threads as I see them, but
       | feel free to connect on social media
       | (https://mattkeeter.com/links/) or follow my blog's RSS feed for
       | further updates (https://mattkeeter.com/atom.xml)
        
         | a_e_k wrote:
         | Neat! I remember contributing the expression parser code for
         | the Knoll et. al 2009 work that you cited in your SIGGRAPH
         | paper. That just rewrote a single user-friendly expression into
         | nested function calls to our IA library in GLSL, without any
         | sort of optimization.
         | 
         | You've clearly taken things waaay farther. Nicely done.
        
         | jerome-jh wrote:
         | Hi Matt, Since you're here I have a quick question. I did not
         | do my homework so please excuse if that's too general or
         | stupid.
         | 
         | How does Fidget differ from libfive and Ao, functionality wise?
         | 
         | Thanks in advance.
        
           | mkeeter wrote:
           | Here's a quick list, off the top of my head:
           | 
           | "Ao" was an early codename for libfive, so those are the same
           | thing (at different stages of development).
           | 
           | Fidget is written in Rust, versus C/C++ for libfive. This
           | makes it easier to use as a dependency (in Rust projects) and
           | cross-compile to WebAssembly. Also, I don't have to debug
           | segfaults anymore, except when touching the raw assembly in
           | the JIT.
           | 
           | They both implement a similar set of algorithms (meshing, 2D
           | and 3D rasterization).
           | 
           | Fidget has the potential to be faster due to its JIT, and
           | _is_ faster for 2D  / 3D rasterization. (I suspect that the
           | non-JIT interpreter is also faster at rasterization, for
           | architectural reasons)
           | 
           | libfive has more effort put into its meshing algorithms, so
           | it does a better job of handling edge cases (heh). I've heard
           | reports that libfive is faster than Fidget at meshing, but
           | haven't done much investigation.
           | 
           | Fidget is not limited to 2D and 3D functions: it can be used
           | wherever you want to quickly evaluation graphs of math, with
           | arbitrary numbers of inputs and outputs. libfive, on the
           | other hand, is specialized to functions of the form f(x, y,
           | z, *vars) -> v.
           | 
           | Extremely in the weeds: if you know what libfive's
           | "feature"-flavored evaluator is, Fidget doesn't have it.
        
         | ynrfin wrote:
         | Hi Matt, Thank you for publishing this. I have a fear creating
         | article on my blog because I thought that what I know is not
         | interesting enough. Your last section is a moodboster and
         | reminder for me, that I should not take myself too seriously
         | and enjoy programming as fun activities
         | 
         | Cheers
        
         | jcgrillo wrote:
         | This is really great, thank you for doing this.
         | 
         | Tangentially, while browsing through your blog I found this:
         | https://www.mattkeeter.com/projects/machined-pen/the_plan.jp...
         | 
         | This illustrates beautifully an idea that's been rattling
         | around in my head for a while: _what if the process you went
         | through to design this manufacturing plan was the user facing
         | cad api?_ When I approach a  "making" problem--whether it's
         | carpentry, plumbing, metal fabrication, machining--I naturally
         | think about it in much the same way you did here. What raw
         | materials am I starting with? What tools do I have? What
         | sequence of operations do I need to perform to achieve the
         | desired end result? The "cad api" (literally an api in the case
         | of code cad tools or the visual representation thereof in
         | traditional mouse driven interfaces) does not work this way,
         | and forces me to think about how to represent the finished
         | shape not about how I'll actually make it. All I care about in
         | the end is making a thing, the modeling is just a tool to
         | assist in that process but it makes itself way too visible.
         | 
         | Naively it seems like there would be so many benefits to having
         | a more "reality based" modeling workflow. As someone who
         | clearly has a lot more experience in the cad space than I do,
         | do you think this concept could go anywhere or is it a dead
         | end?
         | 
         | EDIT: also, a bit of feedback on the pen: you can maintain
         | concentricity if you do something like this:
         | 
         | 1. grab the bar stock in a 3 jaw chuck and turn it to a
         | dimension suitable for a collet
         | 
         | 2. cut off three blanks from the dimensioned rod, one for your
         | cap and two for the body
         | 
         | 3. do the rest of the work using a collet for work holding
         | 
         | The tradeoff is you'll waste a bit this way if you want a
         | different final dimension than you have for your collet.
        
       | peppertree wrote:
       | Here is a thought experiment. What if 3D printers support
       | implicit representation natively. Resin printers are basically
       | physical marching cube machines. FSM would need an algorithm for
       | following contours but should be doable.
        
         | daeken wrote:
         | I kinda tried doing this with a custom FDM slicer for SDFs a
         | long while back. I hit some roadblocks, but the concept was
         | pretty simple: slicers by definition need to know what exists
         | in a 2d slice of a 3d object. So why not render an SDF directly
         | as slices and then act on that? You're basically then just
         | trying to turn a raster into a vector (a toolpath).
         | 
         | The code is simple and hacky as hell -- very much an experiment
         | -- but I still think that it is a plausible route forward.
         | https://github.com/daeken/AjaPrint
        
         | UniverseHacker wrote:
         | Ultimately you'll still need to further process it into a set
         | of physical step by step instructions for the instrument. I'd
         | still rather have the slicer be separate software step so you
         | can tweak the physical properties of the process -wall
         | thickness, infill, temperature and speed, etc. But yeah, it
         | should be possible to input an implicit representation into a
         | slicer.
        
         | Jarmsy wrote:
         | You might be interested in this recent work in the 3mf format
         | 
         | https://cdfam.com/3mf-consortium-volumetric-and-implicit-ext...
        
         | pidge wrote:
         | Relatedly, here's a slicer built around Fidget
         | https://github.com/Wulfsta/WeekendSlicer/tree/main
        
       | dleink wrote:
       | I've been yearning for updated winamp/eggdrop style music
       | visualizations... this is very far outside my domain knowledge
       | but feels like it could be used somehow..
        
       | retzkek wrote:
       | Years ago in college I did a bit of work on a nuclear physics
       | simulator (think: reactor modeling) that based its geometrical
       | model on implicit surfaces, specifically R-functions (of which
       | min(x,y) is an example), which have some neat properties such as
       | being differentiable everywhere. This is a good introduction (and
       | probably the only one in English):
       | https://ecommons.cornell.edu/items/35ae0f68-1af5-4f28-8b8b-7...
       | 
       | I've been away from the nuclear field for a while, but I imagine
       | it's still using a lot of legacy Fortran codes to do modeling.
       | Fidget has some interesting possibilities as a kernel for a new
       | simulation package.
        
       | rendaw wrote:
       | Sorry, tangential but is that rust in the web editor? Do you have
       | a wasm compiler or something? It seems super fast!
       | 
       | I was looking for a live-coding editor (or live preview? hot
       | reloading with visualizer?) for doing creative coding with
       | something like Nannou and after a bunch of searching I came up
       | dry.
        
         | bhaney wrote:
         | > is that rust in the web editor?
         | 
         | From the post:
         | 
         | > Fidget includes bindings for Rhai, an embedded scripting
         | language for Rust
         | 
         | https://rhai.rs/
        
           | rendaw wrote:
           | Ah, since it said it was a library I thought the bindings
           | were something extra. That makes sense though.
        
       | lilyball wrote:
       | Speaking as someone who's never done any sort of graphics work,
       | this is really cool! I wish there were more demos though. The web
       | editor has a single program, the repo itself only appears to have
       | one Rhai program too (the one used for the web editor) so I can't
       | just copy from that. It would be great if the web editor had a
       | dropdown of programs to try, such as the one I see in the first
       | image of the post.
        
       | matthewfcarlson wrote:
       | I've been meaning to do something like this (work on an abstract
       | tree for surface generation) but using SDFs. The idea being that
       | you have a target mesh/point cloud and then use hill
       | climbing/annealing to reach a good tree that fits the desired
       | shape.
        
         | mkeeter wrote:
         | You would probably find "A Unified Differentiable Boolean
         | Operator with Fuzzy Logic" interesting!
         | 
         | https://arxiv.org/abs/2407.10954
         | 
         | They build up CSG trees with differentiable leafs (quadrics)
         | combined with differentiable boolean-ish operations, so you can
         | hill-climb over the entire shape.
        
       | sans_souse wrote:
       | let scale = 27.9;
       | 
       | let x = x * scale; let y = y * scale; let z = z * scale;
       | 
       | let sphere = sin(x) _cos(y) + sin(y)_ cos(z) + sin(z) _cos(x);
       | let fill = abs(sphere) - 0.2; let gradient = sin(sphere)_ cos(y)
       | + cos(z)*sqrt(sphere);
       | 
       | let sphere = sqrt(square(x) + square(y) + square(z)) - 23.77;
       | max(sphere, gradient)
       | 
       | No idea what I'm doing but it's fun
        
       | emmelaich wrote:
       | Reminds me a lot of Ian Henry's https://bauble.studio/
        
       | marcosscriven wrote:
       | This is fascinating. I've seen papers and demos on such implicit
       | surfaces before (quite possibly yours), and while it's impressive
       | what models one can build up with some imagination, I'd love to
       | see something more than toy examples.
       | 
       | Would it be possible, for instance, to do the things possible in
       | b-rep kernels like extruding a surface, or importing an
       | SVG/typeface and creating a solid out of it?
       | 
       | I'd really love to see a fast, open source, kernel that can
       | support such things and also parallelise well.
        
       | wmacaluso wrote:
       | i've always wondered about closed form brep approaches, and i'm
       | glad to see that someone much smarter than I has made it their
       | passion and made it a reality
        
       | rtpg wrote:
       | > libfive is 40K lines of mostly C++, and is extremely
       | challenging to hack on, even as the original author. It's also
       | frustrating to touch: if it's been a few months since I last
       | compiled it, it's inevitable that the build will have broken, and
       | I'll have to mess with CMake for 10 minutes to unbreak it.
       | 
       | I'm a bit shocked at this. Is build breakage that much of an
       | issue? Is this "we are merging in patches and then fixing them up
       | later"? Why would something not being touched break?
        
         | mkeeter wrote:
         | This wouldn't be an issue if I locked my computer in a safe,
         | but the rest of the system is changing underneath me: I may
         | have a new laptop, a new CMake version, a new Qt install
         | location, etc. Having everything managed through Cargo does a
         | great job of isolating me from those kind of changes.
        
           | mehackernewsacc wrote:
           | Just in case you are unaware, these build issues are entirely
           | solvable by defining a Nix flake for your project, resulting
           | in a repeatable, reproducible build every time:
           | 
           | https://nixos.org/ https://wiki.nixos.org/wiki/Flakes
        
       | i_am_a_squirrel wrote:
       | A bit of a tangent, but I've been shopping around for the best
       | code based CAD software. I gave cad query a shot and had a few
       | issues. Any recommendations? My use case is 3D printing.
        
         | zokier wrote:
         | There is build123d too
         | 
         | https://github.com/gumyr/build123d
        
         | fallat wrote:
         | replicad
        
         | bschwindHN wrote:
         | I gave a talk on code-based CAD and covered quite a few
         | options:
         | 
         | https://youtu.be/0wn7vUmWQgg?si=9Rc1tvbiQgQDgQzd&t=2766
         | 
         | I'm also developing one in Rust but I wouldn't say it's ready
         | yet.
        
       | ssfrr wrote:
       | > Doing brute force evaluation on 10242 pixels, the bytecode
       | interpreter takes 5.8 seconds, while the JIT backend takes 182
       | milliseconds - a 31x speedup!
       | 
       | > Note that the speedup is less dramatic with smarter algorithms;
       | brute force doesn't take advantage of interval arithmetic or tape
       | simplification! The optimized rendering implementation in Fidget
       | draws this image in 6 ms using the bytecode interpreter, or 4.6
       | ms using the JIT backend, so the improvement is only about 25%.
       | 
       | I love how this is focused on how the JIT backend is less
       | important with the algorithmic optimizations, and not on how the
       | algorithmic optimizations give a _1000x_ improvement with
       | bytecode and 40x with JIT.
        
       ___________________________________________________________________
       (page generated 2025-01-09 23:01 UTC)