# Working with chains

### Chain theory

When 2 or more paths connect end to end, we call this a chain. Here are 3 lines that connect end to end, forming a chain with 3 links; each line path is considered a link in the chain:

When the links do not have any loose ends and connect to each other, we call this an endless chain. Frequently, endless chains are used to represent a closed geometry. Here is an endless chain made up of 2 lines and an arc:

A circle is a closed geometry by nature. In Maker.js, a single circle comprises an endless chain with only one link.

A chain may contain other chains, recursively. A chain may only contain others if it is an endless chain itself. Here are some examples of one chain containing another:

Here is a model which does not have any chains. Although the lines overlap, they do not connect end to end.

#### Chains are implicit

You do not explicitly define chains in your drawing, chains are something that Maker.js finds in your model(s).

#### Finding

Call one of these two functions to find chains, which will return one or more Chain objects:

### Find a single chain

Let's start with a drawing of a rectangle. A rectangle is a model, but we also implicitly know that a rectangle comprises a chain of 4 paths which connect end to end. Let's find this chain now using makerjs.model.findSingleChain(model): Now, let's combine two rectangle models in a union. Notice that a chain will continue unconstrained by the fact that the two rectangle models are independent:

Each path in the chain is represented by a ChainLink wrapper object in the links array. This ChainLink wrapper tells us how the path relates to the rest of the chain. Each ChainLink array element is connected to the next and previous element. If the chain is endless, then the last array element is connected to the first, and vice-versa.

The path itself can be found in the walkedPath property which is a WalkPath object, the same type of object used in walking a model tree.

#### Natural path flow

The three types of paths in Maker.js are line, arc and circle. A circle has no end points, and therefore cannot connect to other paths to form a chain. Lines and arcs however, may connect to other lines or arcs at their end points to form chains. In context of a chain, lines and arcs each have a concept of a directional flow:
• line - a line flows from its origin to its end.
• arc - an arc flows from its startAngle to its endAngle, in the polar (counter-clockwise) direction.
The reversed property of a ChainLink denotes that the link's path flows in the opposite direction of its natural flow to connect to its neighboring links.

You may have already noticed that we have not specified the order of the links array. For example, given a chain with 3 links A, B, C - the order may also be C, B, A. So, what is the order of the links in a chain? The answer is: it is quite arbitrary. There is no guarantee that the order will be the same each time across JavaScript runtime environments.

#### Reverse a chain

If you have deduced that your chain needs to be reversed, you can call makerjs.chain.reverse(chain).

#### Beginning of a chain

Another issue with endless chains is, which link is at the beginning of the links array? The answer once again, is that it is unpredictable. If you need to specify which link is at the beginning of an endless chain, you have 2 functions at your disposal:

#### Clockwise

If you have an endless chain, you also have the option to see if your links flow in a clockwise direction. Call makerjs.measure.isChainClockwise(chain) which returns a boolean, unless your chain has one link which is a circle - in which case it will return null.

### Find multiple chains

You can find multiple chains by calling makerjs.model.findChains(model), which will return an array of chains, sorted by largest to smallest on the pathLength property. We can find 2 chains in this drawing with 2 rectangles:

#### Containment

Instead of a "flat" array, we can see the containment of chains by also passing an `{ contain: true }` object to makerjs.model.findChains(model, options):

#### Alternating flow directions

There are scenarios where you may need contained chains to flow in the opposite direction of their containing chain. This will require extra computation on each chain to test its direction. If you need this, use `{ contain: { alternateDirection: true } }` in your options. In the returned chains array, the outmost chains will flow clockwise:

#### Isolating within layers

You can find chains within layers by passing `{ byLayers: true }` in your options. This will not return an array, but it will return an object map with keys being the layer names, and values being the array of chains for that layer:

### Finding loose paths

You may also wish to find paths that are not part of a chain. This will require you to pass a callback function which will be passed these three parameters:
• chains: an array of chains that were found. (both endless and non-endless)
• loose: an array of paths that did not connect in a chain.
• layer: the layer name containing the above.
This function will get called once for each logical layer. Since our example has no layers (logically it's all one "null" layer), our function will only get called once.

### Chain to key points

If you want a "low poly" representation of a chain, call makerjs.model.toKeyPoints(chain, [optional] maxArcFacet) passing your chain, and the maximum length of facets on arcs & circles:

### Chain to points

To get points consistently spaced along a chains, call makerjs.model.toPoints(chain, distance) passing your chain, and the distance between points: Hint: you can use the pathLength property of the chain to make sure your distance divides equally on the entire chain:

### Chain fillet

A fillet can be added between all paths in a chain by calling makerjs.chain.fillet with these parameters:
• chainToFillet: the chain containing paths which will be modified to have fillets at their joints.
This will modify all of the chain's paths to accomodate an arc between each other, and it will return a new model containing all of the fillets which fit. This new model should be added into your tree.
##### Basic example
Let's draw a few lines that we know will form a chain: Next we will find all of the chains in our model. We are expecting that there will only be one chain, so we will just take `chains[0]`. Then we will add fillets to that chain:
We can improve upon the design of the truss example by adding fillets to the interior shapes. Let's review the truss design: We know that there are 5 chains in this drawing. When we find chains, the array of found chains will be sorted by pathLength (the total length of all paths in each chain), so we know that the first chain represents the outermost perimeter of the drawing. Therefore we will ignore `chains[0]` and create a for...loop beginning at `chains[1]`:

### Chain dogbone

A dogbone fillet can be added between all line paths in a chain by calling makerjs.chain.dogbone with these parameters:
• chainToFillet: the chain containing paths which will be modified to have dogbone fillets at their joints.
• a number, specifying the radius of the dogbone fillets at every link junction.
• an object, with these optional properties:
• left: radius of the dogbone fillets at every left-turning link junction.
• right: radius of the dogbone fillets at every right-turning link junction.
This will modify all of the chain's line paths to accomodate an arc between each other, and it will return a new model containing all of the dogbone fillets which fit. This new model should be added into your tree.
##### Left turn and right turn example
The direction of turns are in context of which direction the chain is "flowing". An endless chain might flow either clockwise or counter-clockwise. Let's decide to make our chain clockwise. Now when we follow the chain's links in a clockwise direction, right turns will be on the "outside" corners of the shape, and left turns will be on the "inside" corners of the shape. Let's make a shape that is a cutout to represent both the inside and outside of a cut: Next, lets find the chains for each plus, and ensure they are clockwise. Then we can add dogbones to the "outside" corners of the plus that is contained within the square, and to the "inside" corners of the plus that is apart:

### Chain to new model

Once you have a chain, you can also convert it to a model, so that you can return to using the familiar model API with your shapes. Call makerjs.chain.toNewModel(chain, detachFromOldModel: boolean).

### Layout on a chain

Similar to layout on a path, you can use a chain as a layout guide for a row of child models within a model. Call makerjs.layout.childrenOnChain(parentModel: Model, onChain: chain), the x-axis will be projected onto your onChain: There are additional optional parameters to this makerjs.layout.childrenOnChain:
• baseline: number [default: 0]
• reversed: boolean [default: false]
• contain: boolean [default: false]
• rotate: boolean [default: true]
These behave the same as when laying out on a path. See layout on a path for explanation.

#### Laying out text

Layout on a chain works well with fonts and text. See an example here.