Releases: hannobraun/fornjot
v0.9.0
This release announcement is also available on the Fornjot website
Last week wasn't one of those super-focused work weeks that I like most. I spent Monday dealing with the new weekly release procedure; Tuesday I was out sick; Wednesday and much of Thursday, I accidentally distracted myself into doing some cleanup work that was useful, but not immediately important.
Thursday and Friday I finally managed to get back on track with boolean operations. Or rather, the latest detour from boolean operations. I mentioned last week that I could really use a low-level shape updating API for use in unit test, and I've been looking into that.
No definite results so far, but I've come up with some changes to the kernel APIs that would be required to make it happen. And since I very much liked those changes on their own terms, I've just ended up making them, as I look into the topic of the update API more deeply.
Meanwhile, I've had some awesome help from contributors again this week! @hendrikmaus has fixed some issues with the release automation; @Michael-F-Bryan has started improving the API we expose to models, as well as aspects of the host/model interface; and @willhansen has contributed a test case for an open bug, which should make that bug much easier to fix.
Sponsors
Fornjot is supported by @webtrax-oz, @lthiery, @Yatekii, @martindederer, @hobofan, @ahdinosaur, @thawkins, @bollian, @rozgo, and my other awesome sponsors. Thank you!
If you want Fornjot to be stable and sustainable long-term, please consider supporting me too.
End-user improvements
Improvements to Fornjot and its documentation that are visible to end-users.
- Determine model's
target/
directory from Cargo metadata (#828, #841, #853; special thanks go to first-time contributor @Michael-F-Bryan!) - Derive
PartialEq
for types infj
crate (#832; thank you, @Michael-F-Bryan!) - Type-check model functions (#867; thank you, @Michael-F-Bryan!)
Ecosystem improvements
Improvements to the Fornjot ecosystem that are relevant to developers who are building on top of Fornjot components.
fj-interop
- Convert
Color
into a struct (#862)
fj-kernel
- Clean up and expand APIs of
Edge
,Face
, andCycle
(#854, #855, #863, #865) - Return references to objects, where appropriate (#858)
- Make names of
Local
methods more explicit (#860) - Revamp builder API (#864, #866)
Internal Improvements
Improvements that are relevant to developers working on Fornjot itself.
- Fix release automation issues (#814, #843; thank you, @hendrikmaus!)
- Update dependencies (#836, #840)
- Update release procedure (#838, #839, #857)
- Add unit test for triangulation bug (#842; special thanks go to first-time contributor @willhansen!)
- Upgrade to Rust 1.62.1 (#852)
- Clean up
fj-kernel
'siter
module (#859) - Expand implementation note (#861)
Issue of the Week
Fornjot is still in its infancy, and an area where that really shows is usability. One especially annoying issue, is that errors or status messages are not shown anywhere in the UI, being relegated to the command-line instead.
If you're interested in GUI, especially egui
, then #856 - Add UI element that displays status updates might be an interesting issue for you.
Outlook
I'm still looking into the potential low-level shape update API, as that would be very useful for my further work on boolean operations, and pretty much any other kernel work down the line.
I'm currently experimenting with what the syntax could be, and how it would work. I expect that very soon, I'll come to a decision between either going on with the implementation, deferring it, or abandoning the effort.
v0.8.0
This release announcement is also available on the Fornjot website
As previously announced, Fornjot is changing to a weekly release schedule. The previous Weekly Dev Log is being repurposed into this weekly release announcement. Otherwise not much is going to change, for now.
I've finally restarted my work on the union operation (#42). This has been going well so far, and I've finished a few more building blocks that are going to be needed in the finished algorithm. That work has also inspired some cleanups in fj-kernel
and fj-operations
, which you can see below.
Meanwhile @jeevcat has worked on improving the API of the fj-viewer
crate.
Sponsors
Fornjot is supported by @webtrax-oz, @lthiery, @Yatekii, @martindederer, @hobofan, @ahdinosaur, @thawkins, @bollian, @rozgo, and my other awesome sponsors. Thank you!
If you want Fornjot to be stable and sustainable long-term, please consider supporting me too.
End-user improvements
Improvements to Fornjot and its documentation that are visible to end-users.
- Make moving the model work, even if mouse is not hovering over it (#806)
- Make group and transform operations work on all shapes (#825)
Ecosystem improvements
Improvements to the Fornjot ecosystem that are relevant to developers who are building on top of Fornjot components.
fj-interop
fj-kernel
- Implement curve/face intersection algorithm (#802, #812, #813, #817, #826)
- Return local curves from surface/surface intersection (#811)
- Derive
Copy
forVerticesOfEdge
(#818) - Add
Sketch
/Solid
to distinguish between 2D/3D shapes (#819, #823, #827) - Provide more complete and convenient transform API (#822)
fj-math
- Fix edge case in
Vector::scalar_projection_onto
(#810)
fj-operations
fj-viewer
Internal Improvements
Improvements that are relevant to developers working on Fornjot itself.
Issue of the Week
One of Fornjot's goals is support for the web. It should be possible to embed a configurable Fornjot model in a website, where users can look at it, change the parameters, and even export it to external file formats.
We're not quite there yet. The next step would be to make sure that Fornjot can be compiled to WebAssembly. If that's something that sounds interesting to you, check out #815 - Compile Fornjot to WebAssembly.
Outlook
My main priority remains implementing the union operation (#42), but I might have encountered the next detour: creating a low-level shape manipulation API for use in test suites. This is something I could use immediately, for the next step of the union algorithm implementation.
I'm currently looking into that. If I can come up with something good, it would be a huge asset for in-kernel test code, but it also has wider applications. It could even be exposed to users, as a low-level API for defining models. If it turns into too much work, I might decide to table it though, and find some workaround for my current need in the meantime.
v0.7.0
This release announcement is also available on the Fornjot website.
Fornjot 0.7
Fornjot is an early-stage project with the goal to create a next-generation, code-first CAD application. This is the announcement for Fornjot's new release, version 0.7.0.
Fornjot is still at an early stage and far from being useful as a general-purpose CAD tool. This release should be seen as a preview for anyone who's interested in following Fornjot's development.
This release features improvements to how models are defined, how they can be viewed and exported, massive cleanups of the CAD kernel, and some improvements to the ecosystem libraries.
This release announcement provides a high-level summary of those changes. For more details, please refer to the changelog. For pre-compiled binaries, check out the release on GitHub. Please report bugs to any of the usual community channels.
Sponsors
Fornjot is supported by @webtrax-oz, @lthiery, @Yatekii, @martindederer, @hobofan, @ahdinosaur, @thawkins, @bollian, @rozgo, and my other awesome sponsors. Thank you!
To help make the project stable and sustainable long-term, please consider supporting me too.
Modeling Improvements
Fornjot is a code-first CAD application, meaning CAD models are defined using a programming language. Right now, only Rust is supported, but in the future I hope that support for more languages will be available.
This release brings with it some great improvements for defining CAD models! Here's how a model with three parameters (including default values for each) looked in version 0.6:
#[no_mangle]
pub extern "C" fn model(args: &HashMap<String, String>) -> fj::Shape {
let x: f64 = args.get("x").map(|arg| arg.parse().unwrap()).unwrap_or(3.0);
let y: f64 = args.get("y").map(|arg| arg.parse().unwrap()).unwrap_or(2.0);
let z: f64 = args.get("z").map(|arg| arg.parse().unwrap()).unwrap_or(1.0);
// model code goes here
}
The same model can now be defined like this:
#[fj::model]
pub fn model(
#[value(default = 3.0)] x: f64,
#[value(default = 2.0)] y: f64,
#[value(default = 1.0)] z: f64,
) -> fj::Shape {
// model code goes here
}
Much better, isn't it?
Models can also specify minimum and maximum values for each parameter:
#[fj::model]
pub fn model(
#[value(default = 3.0, min = 2.5)] x: f64,
#[value(default = 2.0, max = 2.5)] y: f64,
#[value(default = 1.0, min = 0.5, max = 1.5)] z: f64,
) -> fj::Shape {
// model code goes here
}
And these min
/max
values can even refer to other parameters:
#[fj::model]
pub fn model(
#[value(default = 3.0, min = y)] x: f64,
#[value(default = 2.0, max = x)] y: f64,
#[value(default = 1.0, min = y / 2.0, max = x / 2.0)] z: f64,
) -> fj::Shape {
// model code goes here
}
One thing that always seems to be error-prone are angles. Previously, Fornjot would let you write this:
// Rotate 180 degrees around the z-axis
let rotated = my_shape.rotate([0., 0., 1.], 180.);
But would this have been correct? No, actually not. Fornjot internally handles its angles in radians, not degrees.
This is no longer a problem. Now you would write the same code like this:
// Rotate 180 degrees around the z-axis
let rotated = my_shape.rotate([0., 0., 1.], fj::Angle::from_deg(180.));
Or you can specify your angle in radians:
// Rotate 180 degrees around the z-axis
let rotated = my_shape.rotate([0., 0., 1.], fj::Angle::from_rad(2. * PI));
Or even revolutions:
// Rotate 180 degrees around the z-axis
let rotated = my_shape.rotate([0., 0., 1.], fj::Angle::from_rev(0.5));
All of these features were implemented by contributor @gabsi26, with improvements by @T0mstone. Thank you!
Camera Improvements
Some time ago, I implemented an advanced system for controlling the camera in the 3D view, meant to solve some problems I had encountered in other CAD programs.
The most annoying one, to me, is when you're zoomed in to look at a detail of your model, and need to adjust your viewpoint a tiny bit. But when you try to do that, the detail you were looking at is gone from your view, because the model rotates around some far-away point.
A related issue appears when you're moving the model, but because you're zoomed in too closely, it moves way too fast. Or you are zoomed way out, and it moves really slowly.
In Fornjot, there is the concept of the focus point, which is the point on the model that the mouse cursor is currently hovering over. If you rotate the model, it will rotate around the focus point. And if you move it, the focus point will stay under the cursor.
Unfortunately, that was a case where my ambition outpaced my ability to put time into that specific area, and the system didn't work very well. Until very recently, I was contemplating to rip out all that code and replace it with a simpler solution that didn't try to fix those problems.
No more! The camera system works much, much better now.
Sorry, this video is not available here on GitHub! Please check out the release announcement on the Fornjot website.
(Sorry for those weird green artifacts at the beginning of the video. They appeared when I encoded the edited video. When it comes to video editing, I barely know what I'm doing.)
This work was also completely driven by contributors. Thank you, @chrisprice and @jeevcat!
STL Export
Fornjot was already capable of exporting models to 3MF, the up-and-coming file format for 3D printing. For the traditionalists, we now also support exporting to STL.
Just specify the file extension when calling fj-app
on the command line:
fj-app --model=cuboid --export cuboid.stl # export to STL
fj-app --model=cuboid --export cuboid.3mf # export to 3MF
This has been implemented by contributor @chrisprice. Thank you!
Kernel
A lot of effort went into cleaning up Fornjot's CAD kernel! As Fornjot is slowly edging closer towards support for boolean operations, architectural problems show themselves that need to be fixed.
Some of those fixes have been overly complex, as it turned out, and provided ample opportunity for simplifications. Many of those opportunities have been identified and taken advantage of, and the kernel now does similar things as it did before, but with much less code.
This work is very important, as it paves the way for all the CAD feature work going forward, but this release, it didn't lead to any outwardly visible changes. I figured I'd still call it out, as that's basically all I've been doing in recent weeks (besides pressing the "Merge" button for the awesome contributors that did the real work 😁).
Ecosystem
Fornjot is not just a CAD application. The components that make up this application are released separately, and can be used by other projects that would like to augment Fornjot, or use parts of it for something completely different.
This release, there have been some additions and cleanups of fj-math
, Fornjot's math library, and fj-operations
, which is the glue that binds fj-kernel
to the operations that Fornjot models have access to. These improvements have largely been driven by the changes in fj-kernel
.
There is also a new library in the Fornjot ecosystem, fj-window
, which has been extracted from fj-viewer
. This leaves fj-viewer
without a dependency on any windowing library, meaning alternative applications that want to use something else than winit (the library that Fornjot uses for this), can still use fj-viewer
to display models.
Smaller Improvements
In addition to all this, there ...
v0.6.0
Fornjot 0.6
Also see release announcement on the Fornjot website.
Fornjot is an early-stage project to create a next-generation Code-CAD application. This is the announcement for Fornjot's new release, version 0.6.0.
Fornjot is still at an early stage and far from being useful as a general-purpose CAD application. This release should be seen as a preview for anyone who's interested in following Fornjot's development.
The project is steadily inching forward, however, and this new version comes with some new and refined modeling features, lots of small improvements, lots of bug fixes, and a huge amount of internal cleanup.
This release announcement provides a high-level summary of those changes. For more details, please refer to the changelog. For pre-compiled binaries, check out the release on GitHub. Please report bugs in any of the usual community channels.
Sponsors
Fornjot is supported by @webtrax-oz, @lthiery, @Yatekii, @martindederer, @hobofan, @ahdinosaur, @thawkins, and my other awesome sponsors. Thank you!
If you're interested in helping to make the project sustainable long-term, please consider supporting me too.
Modeling Improvements
The ways that models can be defined have been improved in various ways. For example, it's now possible to sweep 2D shapes in arbitrary directions, not just along the z-axis.
And if you don't like the classic "Fornjot red", you have options now:
There's more: fj::Union
has been renamed to fj::Group
(with support for actual unions still being a work-in-progress), new convenient syntax for fj::Difference2d
was added, documentation of the fj
crate has been improved, and other small tweaks have been made.
Bug Fixes
You can define abstract geometry all day, but at some point (namely to render it, or to export it for 3D printing), you need to approximate it using a triangle mesh. This process is non-trivial and provides lots of opportunity for exciting bugs.
Here's what happened, if you tried to sweep a non-symmetric sketch:
It's much better now, although this model still does not work perfectly (missing triangles in the long, narrow part of the upper face):
Here's another model with triangles in the wrong places:
And here's how that looks in the new version:
These are just some examples. Many more bugs have been fixed. And of course, more bugs are still lurking. But Fornjot has become much more robust in this release, and will continue to do so.
Small Improvements
There have been lots of smaller feature additions and bug fixes!
If you display a model, or export it for 3D printing, the model needs to be approximated. You can now specify the tolerance value, i.e. the maximum allowed deviation of the approximation from the actual model, as a command-line argument.
For example, running this from the Fornjot repository:
cargo run -- --model=spacer --tolerance=0.1
While this:
cargo run -- --model=spacer --tolerance=0.001
This is just one example of many small features that were added.
The Fornjot Ecosystem
Some people I've talked to have expressed interest in building their own applications on top of Fornjot, once it's ready. It might still take a while before Fornjot has matured enough for that to make sense, but in principle this is possible starting with this version.
While the previous version of Fornjot consisted mostly of one monolithic application, parts of that application have been extracted into libraries that can be used on their own.
Check out my blog post on the Fornjot ecosystem, if you're interested in this.
Cleanup
Maybe the most important aspect of this release is the huge amount of cleanup work that has gone into it. Fornjot's code base is now much more capable, and much more ready to support the features we'll want to add.
While this has enabled some improvements in this release, this is mostly invisible. But it will pay dividends as more features are being added over the next releases.
Contributors
Fornjot is an ambitious project, and it wouldn't be possible without contributors! Thanks you @gzsombor, @mxdamien, @hendrikmaus, @ObiWanRohan, @therealprof, @danieleades, @anwentec, @ozghimire, @homersimpsons, @liubog2008, @freylint, and @connor-lennox for your help with this release!
v0.5.0
Read the release announcement on the Fornjot website.
fj
Library
- Replace
fj::Rectangle
with the more powerfulfj::Sketch
. - Add
fj::Union
to express unions. This is subject to limitations (see API Reference). - Add
fj::Transform
to support transforming shapes. - Add traits to provide simplified syntax for various operations. These traits can be accessed through a
use fj::prelude::*;
. - Rename
fj::Difference
tofj::Difference2d
to make room for a 3D difference operation. - Add
fj::Difference
to express difference operation in 3D. This is not supported by the host application yet. - Improve documentation (#86)
Host Application
-
Fix shapes that are very near or very far not being shown on camera.
-
Add support for Windows and macOS (#22, #23, #28; special thanks to Fornjot's first contributor, @Bandsberg!).
-
Add support for concave 2D sketches.
-
Add debug info visualization mechanism to help debug internal algorithms. So far, it just outputs lines to visualize the triangulation algorithm.
-
Fix bug in 2D difference operation, that would create an internal pseudo-face within the model, if the 2D difference was swept into a 3D model.
-
Add blacklist to avoid multiple rebuilds on model changes (#39; special thanks to first-time contributor, @mxdamien)
-
Fix triangulation bugs that would cause errors in some models (#61, #74, #81)
-
Add star model to repository (#50)
-
Lots of internal clean-ups, to enable more features in the future.