Fastener Build Cycle

As stated in cqparts_fasteners Module, a Fastener is an Assemly, so it’s highly recommended you understand Assembly Build Cycle before reading this section.

A fastener still uses the assembly build cycle, but abstracts it further with the use of 3 utility classes:

Note

Using fasteners as a tool is not mandatory.

You can always achieve the same effects by picking a bolt, screw, or anything else as a part, and adding that to your assembly manually.

The Fastener class is intended to make building easier. If it’s more trouble than it’s worth for your assembly, don’t use one.

Evaluator

An Evaluator instance is an assessment of the workpieces affected by the fastener being applied.

The most common evaluator is the VectorEvaluator which evaluates which parts will be effected (by eliminating the white-list of parts passed to it), and how they will be effected.

An Evaluator instance is required to instantiate a Selector, and an Applicator.

There is very little gouverning the structure of an Evaluator, only that is is passed a list of Part instances, and that the overridden perform_evaluation() method is buffered in the eval attribute.

Selector

The Selector is what chooses, or tunes a part to fit the situation assessed by the Evaluator.

For example, a bolt that is the perfect length, or a screw that has enough thread to grip, but no so much as to stick out the other side.

A Selector also chooses where the screw fits in the fastener assembly.

Applicator

The Applicator makes alterations to existing parts to either:

  • cut solids to clear a path for the fastener, or
  • add to solids to create an anchor point for a fastener to hold on to.

Note

The typical assembly build cycle may perform alterations on components within that assembly, however a fastener assembly will make alterations on components in its parent assembly.

There’s no problem with this, it’s just noteworthy.

Why doesn’t the applicator place parts?

It may seem logical for the Applicator to choose where parts fit into the Fastener assembly.

Instead, the Selector sets the part placement for 2 reasons:

  • convenience: the placement of fasteners actually has a lot to do with which components were selected, so the Selector already has all the information when the selection is made.
  • clarity: a fastener component will always require placement, but the parent’s components will not always need to be altered. The presence of an Applicator means that parent components will be changed in the process of building a fastener.

Built Cycle

Putting all the above utilities together, a Fastener build cycle is outlined below. Please reference Assembly Build Cycle if needed.

In the fastener’s make_components() call:

  1. An evaluator is instantiated.
  2. A selector is instantiated, given the evaluator
  3. The Selector.get_components() call returns the components that will be part of this assembly

In the fastener’s make_constraints() call:

  1. The Selector.get_constraints() call returns the constraints that set each component’s placement.

Then as part of the assembly’s normal build cycle:

  1. solve() is run, setting component world coordinates.

And finally, in the fastener’s make_alterations() call:

  1. The applicator is instantiated. It is given both the evaluator and the selector.
  2. The applicator will make alterations to the geometry of the parts passed to the evaluator (if necessary).