Accidentally while creating a lamp I ended up learning FreeCAD. FreeCAD is an amazing open source CAD program. It still amazes me that people created this for free in their spare time. The software is still in it’s alpha version and is far from perfect as you can tell by the current release version number 0.19 and the heated discussions around how soon a 1.0 release could be reached. Still it’s very usable and once you get the gist of it you can create powerful and complex designs. FreeCADs approach to CAD is a parametric design. That means that you specify shapes with parameters. E.g. you base the 3D shape on a 2D drawing. The geometric figures of the 2D drawing - circles, recatangles, lines - are all constrained with parameters. Then you create a 3D shape out of your 2D sketch, for example by extruding it. And every step is based on certain parameters that can reference previous parameters. It’s basically visual programming. Is FreeCAD NP-complete? Probably, but that’s a topic for another time. Anyways. The parametric approach allows you to easily modify your design at any time just by tuning these parameters. For example with my lamp design the number of aluminium bars is a parameter I can simply tweak at any point in time. All the relevant details depending on this number will be automatically recomputed by FreeCAD. This gives great flexibility and allows for fast customization.
Google Summer of Code (GSoC) is a program run by Google that gives stipends to students who over a period of three months implement an open source project with a mentor organization. Among the organizations are well known ones like Arduino, Ruby or Wikimedia. But there are also more niche organizations that are not so widely known. The great part about GSoC is that students apply for specific projects, so you yourself determine how exciting the thing you work on is if you get accepted. This and the work from home aspects are definitely something a lot of internships can’t offer. For me it started with seeing the potential of first designing a parametric lamp and then creating a custom web page where you could change the parameters to your liking and see a live 3D rendering of the changed lamp. Then you just download the 3D files and 3D-print the lamp. I was heavily inspired by the card1o cover generator created with OpenSCAD. After some research I realized that something comparable to rendering OpenSCAD in the web browser does not exist for FreeCAD yet. I already knew about GSoC and to my suprise FreeCAD was one of the open source organizations taking part in GSoC 2020.
I sent out two applications: A better IPython and Jupyter Notebook Integration for FreeCAD and Measurement tool for FreeCAD. In the end the first one was chosen. It was closer to my original idea that got me excited and on the path of applying. I definitely didn’t expect the application to succeed, but that might just be the classic imposter syndrome. I put in quite some thought researching the topic and contacted some of the previous students, I even managed to email the student who applied for the exact same idea a couple years before. He was so nice to send me a link to his old application so that I could make us of the feedback he got on his application from back then. After the acceptance the project started moving. The FreeCAD community is mainly organized in an old school internet forum. I haven’t used one since I was active on an RC car forum when I was 14 before I signed up on forum.freecadweb.org. Here is the project thread where I posted questions and updates on work progress: link. For the unlikely case that you haven’t read through my 8 page project application let me summarize it for you. Or actually the document is very well written so let me quote it instead:
Currently, FreeCAD’s IPython and Jupyter Notebook integration can only provide visualization by running the entire FreeCAD GUI alongside the notebook. Besides not being elegant it brings many problems with it, like not being able to save the visualizations inside the notebook for sharing or bringing visual complexity of the entire GUI into the view instead of just displaying the 3D model. It is therefore important to find a way to visualize FreeCAD’s 3D scene in the IPython display system as supported by Jupyter Notebook.
To make things a bit more clear, Juypter Notebook is an multi purpose computation evironment, which basically means you can run interactive code on the web. Since Juypter Notebook and FreeCAD both support Python this is a match made in heaven. With Jupyter you can quickly create interactive UIs and mix them with text into a great experience for learning, communicating and experimenting. Opening this space to FreeCAD users and developers brings potentially endless new possibilities. You get access to all the powerful Jupyter widgets that make it so popular. I certainly hope some of you reading this will take this idea further by writing that interactive Python scripting tutorial inside a notebook, by writing that new workbench which will have a widget for notebooks, by improving your workbenches Python API so you can easily access all GUI functions inside a notebook.
During this GSoC I successfully implemented a 3D viewer that can display FreeCAD objects inside a notebook. Currently it’s still limited to the Part Workbench, I still have to implement modifications to handle scene objects created by other workbenches. The current project is a good base to build upon. The basic features working right now are:
- displaying FreeCAD scene graph face sets
- displaying FreeCAD scene graph line sets
- setting view parameters according to FreeCAD scene graph
- emissive color
- highlighting FreeCAD object faces
- selecting FreeCAD object faces
- displaying FreeCAD object edges indices
- selecting FreeCAD object edges
- displaying FreeCAD object faces indices
- rotating the view
- zooming the view
There obviously are many more features that should be implemented over time to make this project maximally useful. For example moving the view, view controls matching the FreeCAD key combinations and having the standard FreeCAD view buttons (“top”, “bottom”, etc.) available would be great.
Here is an example Jupyter Notebook that uses the
freecadviewer Python module I created during the GSoC. Be aware that due to the missing Python kernel (this is just a static site) most of the interactivity is lost. For full interactivity you should run the notebook yourself. The link to the full static notebook is here. But still you can pan and zoom the 3D views inside the notebook. Also I recommend viewing this on a bigger screen than a smartphone, even though mobile works, it’s not ideal:
As you probably already have guessed, this enables you to embed interactive FreeCAD views on your web sites, e.g. like this:
But enough with the “Why” let’s get to the “How” aka technical details shall we? Since the goal is to have a very general 3D viewer solution that will be able to display any content that exists inside the desktop applications 3D view we need to work directly with it’s scene graph. So how does FreeCAD generate it’s 3D view? Internally FreeCAD relies on a C++ CAD library called Open Cascade that implements 2D and 3D geometric modelling. You could say Open Cascade is FreeCADs CAD kernel. Internally Open Cascade represents Geometries mathematically in potentially infinite resulution. The visualization on the other hand is realized with a probably not that widely know framework called Coin3D which itself is based on a format called Open Inventor:
Coin is an OpenGL-based, 3D graphics library that has its roots in the Open Inventor 2.1 API, which Coin still is compatible with.
If you are not familiar with Open Inventor, it is a scene-graph based, retain-mode, rendering and model manipulation, C++ class library, originally designed by SGI. It quickly became the de facto standard graphics library for 3D visualization and visual simulation software in the scientific and engineering community after its release. It also became the basis for the VRML1 file format standard. Several books exists on the subject of Open Inventor, most notably The Inventor Mentor, and The Inventor Toolmaker, both highly recommended for those who wants to learn how to use Open Inventor.
Thankfully someone started creating a Python binding for the Coin3D library as a topic for his masterthesis. It still lives on under the name pivy. This means that I possibly can implement the project entirely in Python. Which has been a very pleasent language to work with so far.
I will continue to improve the project in the future. You can find the repository here. If you use the module and encounter any issues or just find it useful, don’t hesitate to post to the forum thread or let me know with a tweet or an issue in the repository.
Thanks to my mentors: @ickby, @kkremitzki, @yorik. I’m grateful for them spending time on helping me with the project. Doing this entirely in their spare time is insanely great! Also thanks to the entire FreeCAD community who gave helpful input. I was especially impressed by how much effort @vocx-fc put into reviewing my second pull request to FreeCAD. So this GSoC, also by watching what my fellow students where doing, definitely taught me to appreciate free software and open source even more. ❤️