Model trees
Model tree structures
Routes
We know that we are able to refer to deep objects by using the dot notation:
The reference from plate
to BottomRight_bolt
is hard-coded. Suppose that we had a
model plate2
which was a duplicate of plate
- we would need to have to hard-code
the reference to its BottomRight_bolt
:
Instead of hard-coded dot notation, we can have an abstract way of referencing deep objects by using a route.
It is simply an array of strings that represent the segments names between the dots. We do not put the root object in a route.
A route that we can apply to both plate
and plate2
would be:
Travel a route
Use makerjs.travel(rootModel, route) to get to a child object in rootModel via a route. This function will return an object with these 2 properties:
- result: model or path - the object referenced by the route
- offset: point - the offset of the result object's origin from the rootModel's origin
Patterns in Routes
Notice that the schema for Maker.js models has a pattern of models.modelName
and paths.pathName
.
There are always 2 segments between model and/or path objects. So, in any given route to an object, you can always get to its parent
by subtracting the last 2 array elements of the route. We will use Array.slice(0, -2)
to make a copy of the route array without the last 2 elements:
Route Keys
Additionally, we can "flatten" a route array into a string, known as a route key, by calling makerjs.createRouteKey(route) and passing a route. Every route key is of course unique in the scope of the root object. It may used as a unique id of a child path or model.
Walking a model tree
You can traverse a model tree by calling makerjs.model.walk with your model and an object with these optional properties:
property name | property type | description |
---|---|---|
onPath | function(walkPath object) | called for every path (in every model) in your tree. |
beforeChildWalk | function(walkModel) | called for every model in your tree, prior to diving deeper down the tree. Return false if you wish to not dive deeper. |
afterChildWalk | function(walkModel) | called for every model in your tree, after returning from a deep dive down the tree. |
walkPath object
A walkPath object has these properties:
- layer: the layer name (if any) containing this path.
- modelContext: the model containing this path.
- offset: the absolute coordinates from [0, 0] where this path is located.
- pathContext: the path itself.
- pathId: the id of this path in its parent model.paths container.
- route: array of property names to locate this path from the root of the tree.
- routeKey: a string representation of the route which may safely be used as a unique key identifier for this path.
walkModel object
A walkModel object has these properties:
- childId: the id of this model in its parent model.models container.
- childModel: the model itself
- layer: the layer name (if any) containing this path.
- offset: the absolute coordinates from [0, 0] where this model is located.
- parentModel: the model containing this model.
- route: array of property names to locate this model from the root of the tree.
- routeKey: a string representation of the route which may safely be used as a unique key identifier for this model.
Example
In this example we will create a RoundRectangle and walk its tree. We have an onPath
function that will get called for every path in the model. If the path is an arc, we will invert it:
Next: Working with chains.
A model is a tree structure which may contain paths, and it may also contain other models in a heirachy. Let's look at an example:
If we represent this drawing as a conceptual tree structure, it would look like this:
(You may notice that this structure is reminiscent of a folder system on your computer.) We can easily traverse the tree when starting at the root. For example, let's change the radius of the BottomRight_bolt hole:
We can access the BottomRight_bolt circle from the
plate
object downward. Notice that in this tree structure, you cannot access upwardly. Theplate
object contains thebolt
model which contains theBottomRight_bolt
path, butBottomRight_bolt
does not have a reference to its container. There are no properties of thebottomRight_bolt
circle object which access anything up the tree. It also does not have any references to its sibling circles withinbolt.paths
.Downward-only access is the nature of a simple object tree structure. We can overcome this using routes.