2016-03-03



alvinashcraft
shared this story
from Engineering @ Microsoft.

Maker.js is an easy-to-use open source library that brings NPM-style dependency management to the world of 2D drawings. Small and fast, Maker.js can run in anything from a web browser to a Node.js server application.

Like most software projects, Maker.js was created by a person who had a specific problem to solve. That person was Dan Marshall, a developer on Microsoft Research’s FUSE Labs team. Outside of work, he needed to make a clamp to fit on a pipe. After figuring out how to write some code to solve that problem, Dan realized he could turn it a more generalized library that he and other “makers” could use to create and manage parametric models. This led to the release of Maker.js as an open source project from the Microsoft Garage.

In early 2016, we caught up with Dan and talked to him about the creation of Maker.js, the decision to open source it, and how the project has grown and evolved.

Birth of a Project

In late 2014, Dan was working on a personal project: building a scooter. He needed a pair of clamps to connect the handlebars to the tubes that would serve as the struts, and decided to design those clamps in Adobe Illustrator so that he could export his design as DXF (a modeling form first used in AutoCAD). He would then be able to send that DXF file to a machining service such as www.bigbluesaw.com, and they could carve his clamps out of a block of aluminum.

After designing his clamp in Adobe Illustrator, it occurred to him that it would be great to have a simple “parametric” drawing of a clamp that he could re-use for other tube diameters. He had worked with OpenSCAD, a 3D modeling tool that uses its own functional programming language for specifying the details of each model. But why learn a special language just for creating models? And what about sharing that parametric code – does everyone need to install a plugin into desktop software just to take a look? Wouldn’t it be great if a CAD model could be created in a popular standardized language like JavaScript? What about letting somebody just download a customized drawing straight form a web page without installing anything at all? From those simple questions, Maker.js was born.

At its core, Maker.js provides JavaScript functions for generating a few types of primitive paths (lines, circles, arcs) and common transformations such as mirroring, rotating, and scaling. These simple building blocks can be combined into a model, and models and paths can be assembled recursively to create rich structures built from standardized components.

Once you’ve defined a model in JavaScript code, you can re-use that code in another model, or you can download a JSON representation of your model and re-use that. Here’s a very simple example of a rectangle, showing the Maker.js JavaScript code that created it and the corresponding JSON representation:

Maker.js example

You can easily traverse this JavaScript object and change, add or delete values as needed. It is just an ordinary object composed of schematized data – there are no methods or function calls. This makes it portable and easy to use in any other process. It also makes it easy to convert to other data types.

Dan also added options to download Maker.js models in other common formats used in modeling and CNC applications: DXF, SVG, OpenJSCAD, and STL. To create his clamps, Dan started from a 2D model in Maker.js, then exported as DXF. Then sent the resulting final DXF file to a CNC service to create his clamps.

Designing the clamp with Maker.js

There is a rich community around 3D CAD modeling, but the tools and techniques can become very complex. By working in 2D for the design phase, Maker.js keeps the design process very simple, especially for programmers who are already familiar with JavaScript. As Dan notes, “I love 3D, but in 2D it’s economical to make things out of materials such as textiles, wood and metal that have amazing tactile strength properties.”

The finished clamps, mounted on Dan’s scooter

Generalizing the solution

In designing the Maker.js library, there were several design decisions that helped focus the project and make it a flexible platform for a variety of applications.

From the beginning, Dan had no ambition to “re-invent CAD” with Maker.js. There are many popular tools for CAD and 3D modeling, and the scope of Maker.js is limited to just creating 2D models in code and making them easy to re-use and combine in creative ways. The library can be viewed as a DSL (domain-specific language) for representing 2D elements such as lines, circles, and arcs in JavaScript code. These elements can be combined into a model, and models can be further combined into complex shapes. Add a thickness to one of those shapes, and you have a 3D representation that can be sent to a 3D printer to create a prototype, or sent to a CNC (computerized numerical control) machine for manufacturing items made from steel, plastic, and other materials.

Within its simple 2D scope, Maker.js provides a great deal of flexibility because of two key design decisions: all models are parameterized, and dependency management is handled in an automated manner. Let’s look at how each of those works in practice.

A parameterized model simply means that there are numeric values which can be provided to a model to specify its size and shape. As a trivial example, a circle can be represented as a parameterized model with a single input: the radius of the circle. As a more complex real-world example, consider the design of a band clamp as shown here:

Band clamp, designed in Maker.js

This model’s size and shape is determined by many parameters: the radius of the hole in the middle, the width and height of the tabs extending to the right, the angle of the opening, and so on. A band clamp is provided as one of the demo models in Maker.js, and it has 8 total parameters as you can see from the function signature in the JavaScript code for makerjs-band-clamp:

These parameters are exposed in the Maker.js “playground” UI on the web site, so that you can interactively adjust settings and immediately see the effect of your changes:

Maker.js Playground UI

For example, here are three examples of values for the first parameter, the radius of the hole:

Examples of parameterized modeling

The other key design decision was to make dependency management a central aspect of the architecture of Maker.js. There is a fundamental dependency management challenge in the CAD industry, akin to the dependency management challenge that software developers face when building systems that re-use libraries, frameworks, and other components. Just as a customized web site can be viewed as a layer of custom code on top of a set of off-the-shelf re-usable software components – a CMS, a database, an ORM library, and so on – a complex CAD model can also be viewed as a set of customizations applied to a collection of re-usable models.

Once the problem is viewed in this manner, mature dependency management tools from the software development discipline can be used to manage dependencies between models. There is no need to invent and build dependency management tools for Maker.js models – they’re just JavaScript code, and NPM already provides a well-known, robust approach to managing dependencies between JavaScript/Node codebases.

You can see this approach at work in the source code for the band clamp model, which includes a dependency on another model published on NPM, the half band clamp. This dependency is specified in the first few lines of code for the band clamp model, in exactly the same way that a developer might specify a dependency on any other module or library:

Specifying model dependencies in Maker.js

As Dan explains, “working at Microsoft gave me the perspective to think about Maker.js in terms of a platform, including a focus on the developer experience and dependency management.”

This perspective is reflected in the fact that Maker.js re-uses existing dependency management techniques that the target developer audience – JavaScript and Node developers – is already familiar with. If you know how to manage your Node code’s dependencies, you know how to manage model dependencies in Maker.js. The dependencies between Maker.js models use the same require() syntax that is used by the Node.js packaging system, so a developer can simply say require(‘./mycomponent.js’) to indicate a dependency on a local model named mycomponent.js. The same syntax can be used for dependencies on Maker.js models that have been published in the NPM repository.

Releasing as open source

Once Maker.js was up and running, Dan wanted to release it as an open source project so that others could use it and contribute to it. In early 2015, he heard about the Microsoft Garage sponsoring a “pitch day” for projects to be released as open source, and decided to get involved.

The Garage is an outlet for experimental projects developed by Microsoft employees, and provides assistance in launching and promoting projects. “The Garage ship channel exists for Microsoft employees and teams to learn through public experiments,” explains Ed Essey (Senior Program Manager, Microsoft Garage).

Maker.js was a great fit for the Garage, because there is a vibrant maker community that has grown around the Maker Garage facility (launched in 2013). The Maker Garage provides a place for Microsoft employees and guests to collaborate and experiment with a variety of maker-related hardware and software.

The Playground

From the beginning, the Maker.js project included a simple UI for browsing models and interacting with them. You could zoom in and out via the mouse wheel, and there were slider controls for interactively adjusting parameter values.

Over the holiday break at the end of December 2015, Dan decided to take this functionality to the next level. He added a live JavaScript editor, which means you can type changes to the JavaScript source code behind a model and immediately see how that changes the rendering and behavior of the model. He also added full panning and zooming with both mouse and touch, making the Maker.js Playground even easier to work with on tablets and touchscreens. You can use the interactive UI to adjust your model, and then generate an OpenjsCad, .STL, JSON or DXF representation of the model that can be used by CNC or 3D printing devices to create a 3D object. Click on any of the demos on the Maker.js site to see the Playground in action.

The Playground is a great example of the creative possibilities for using Maker.js in the browser. And it’s very easy to embed this functionality. In the example below, we’ve embedded a JSFiddle that is an interactive smiley face – you can use the slider to adjust the width of the smile:

To see how it works, click the “Edit in JSFiddle” link and try changing the paths. For more information, see the Maker.js Getting Started page.

Going forward, the Maker.js project will evolve with feedback from the community. You can weigh in via GitHub issues if you’d like to see a new feature, and of course you can contribute expertise via pull requests if you would like to help grow the project. Developers can contribute code, and if you’re a designer you can contribute drawings or models that others can define in JavaScript. Dan is currently investigating a variety of new features including PDF export, SVG import, and the addition of Bezier curves to the Maker.js primitives. He’s also looking into how his colleagues in Microsoft Education can use Maker.js to help get more young people involved in computer science.

Maker.js is a great example of the type of small-scale, high-impact open source projects coming out of the Microsoft Garage. These projects are typically started by an individual or small informal team of Microsoft engineers who have a shared vision for a software project that may be far removed from their day to day work.

Dan Marshall and his scooter handlebars designed with Maker.js

For more information about Maker.js, see Dan Marshall’s interview with Jeremy Foster on Channel 9.

Would you like to work with Microsoft engineering teams tackling interesting challenges like those described above? You can find information about working at Microsoft or search for openings here. Come join the team!

Show more