while ((solutions = jobPlanner.getNextPlacementSolutions(head)) != null) {
LinkedHashMap<PlacementSolution, Location> placementSolutionLocations = new LinkedHashMap<PlacementSolution, Location>();
for (PlacementSolution solution : solutions) {
firePartProcessingStarted(solution.boardLocation, solution.placement);
BoardLocation bl = solution.boardLocation;
Part part = solution.placement.getPart();
Feeder feeder = solution.feeder;
Placement placement = solution.placement;
Nozzle nozzle = solution.nozzle;
NozzleTip nozzleTip = solution.nozzleTip;
// Determine where we will place the part
Location boardLocation = bl.getLocation();
Location placementLocation = placement.getLocation();
// We will work in the units of the placementLocation, so convert
// anything that isn't in those units to it.
boardLocation = boardLocation.convertToUnits(placementLocation.getUnits());
// If we are placing the bottom of the board we need to invert
// the placement location.
if (bl.getSide() == Side.Bottom) {
placementLocation = placementLocation.invert(true, false, false, false);
}
// Create the point that represents the final placement location
Point p = new Point(placementLocation.getX(),
placementLocation.getY());
// Rotate and translate the point into the same coordinate space
// as the board
p = Utils2D.rotateTranslateScalePoint(p, boardLocation
.getRotation(), boardLocation.getX(), boardLocation
.getY(), 1.0, 1.0);
// Update the placementLocation with the transformed point
placementLocation = placementLocation.derive(p.getX(), p.getY(), null, null);
// Update the placementLocation with the board's rotation and
// the placement's rotation
// This sets the rotation of the part itself when it will be
// placed
placementLocation = placementLocation.derive(
null,
null,
null,
(placementLocation.getRotation() + boardLocation.getRotation()) % 360.0);
// Update the placementLocation with the proper Z value. This is
// the distance to the top of the board minus the height of
// the part.
double partHeight = part.getHeight().convertToUnits(placementLocation.getUnits()).getValue();
placementLocation = placementLocation.derive(null, null, boardLocation.getZ() - partHeight, null);
// NozzleTip Changer
if (nozzle.getNozzleTip() != nozzleTip) {
fireDetailedStatusUpdated(String.format("Unload nozzle tip from nozzle %s.", nozzle.getId()));
if (!shouldJobProcessingContinue()) {
return;
}
try {
nozzle.unloadNozzleTip();
}
catch (Exception e) {
fireJobEncounteredError(JobError.PickError, e.getMessage());
return;
}
fireDetailedStatusUpdated(String.format("Load nozzle tip %s into nozzle %s.", nozzleTip.getId(), nozzle.getId()));
if (!shouldJobProcessingContinue()) {
return;
}
try {
nozzle.loadNozzleTip(nozzleTip);
}
catch (Exception e) {
fireJobEncounteredError(JobError.PickError, e.getMessage());
return;
}
if (nozzle.getNozzleTip() != nozzleTip) {
fireJobEncounteredError(JobError.PickError, "Failed to load correct nozzle tip");
return;
}
try {
((ZippyNozzleTip) nozzleTip).calibrate((ZippyNozzle) nozzle);
}
catch (Exception e) {
fireJobEncounteredError(JobError.PickError, e.getMessage());
return;
}
}
// End NozzleTip Changer
if (!nozzle.getNozzleTip().canHandle(part)) {
fireJobEncounteredError(JobError.PickError, "Selected nozzle tip is not compatible with part");
}
pick(nozzle, feeder, bl, placement);
placementSolutionLocations.put(solution, placementLocation);
}
// TODO: a lot of the event fires are broken
for (PlacementSolution solution : solutions) {
Nozzle nozzle = solution.nozzle;
BoardLocation bl = solution.boardLocation;
Placement placement = solution.placement;
Location placementLocation = placementSolutionLocations.get(solution);
place(nozzle, bl, placementLocation, placement);
}