package org.reprap.machines;
import java.io.IOException;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.vecmath.Color3f;
import javax.media.j3d.*;
import org.reprap.Attributes;
import org.reprap.CartesianPrinter;
import org.reprap.Preferences;
import org.reprap.ReprapException;
import org.reprap.comms.Communicator;
import org.reprap.comms.snap.SNAPAddress;
import org.reprap.comms.snap.SNAPCommunicator;
import org.reprap.devices.GenericExtruder;
import org.reprap.devices.GenericStepperMotor;
import org.reprap.devices.pseudo.LinePrinter;
import org.reprap.gui.CalibrateZAxis;
import org.reprap.gui.Previewer;
import org.reprap.Extruder;
import org.reprap.utilities.Debug;
import org.reprap.utilities.Timer;
import org.reprap.gui.*;
/**
*
* A Reprap printer is a 3-D cartesian printer with one or more
* extruders
*
*/
public class Reprap implements CartesianPrinter {
/**
*
*/
private StatusMessage statusWindow;
/**
*
*/
private JCheckBoxMenuItem layerPauseCheckbox = null, segmentPauseCheckbox = null;
/**
*
*/
private final int localNodeNumber = 0;
/**
* comms speed
*/
/**
*
*/
private Communicator communicator = org.reprap.Main.getCommunicator();
/**
*
*/
private Previewer previewer = null;
/**
* Stepper motors for the 3 axis
*/
private GenericStepperMotor motorX;
private GenericStepperMotor motorY;
private GenericStepperMotor motorZ;
/**
* Total distance the carriage has moved in mm
*/
double totalDistanceMoved = 0.0;
/**
* Total distance the extruder has printed in mm
*/
double totalDistanceExtruded = 0.0;
/**
* Rezero X and y every...
*/
double xYReZeroInterval = -1;
/**
* Distance since last zero
*/
double distanceFromLastZero = 0;
/**
* Distance at last call of maybeZero
*/
double distanceAtLastCall = 0;
/**
*
*/
private LinePrinter layerPrinter;
/**
*
*/
double scaleX, scaleY, scaleZ;
/**
* Current X, Y and Z position of the extruder (?)
*/
double currentX, currentY, currentZ;
/**
* Initial default speed
*/
private int currentSpeedXY = 200;
/**
*
*/
private int fastSpeedXY = 230;
/**
* Initial default speed
*/
private int speedZ = 230;
/**
* Number of extruders on the 3D printer
*/
private int extruderCount;
/**
* Array containing the extruders on the 3D printer
*/
private Extruder extruders[];
/**
* Current extruder?
*/
private int extruder;
/**
* Don't perform Z operations.
* FIXME: Should be removed later.
*/
private boolean excludeZ = false;
/**
*
*/
private long startTime;
/**
*
*/
private double startCooling;
/**
*
*/
private boolean idleZ;
/**
* @param prefs
* @throws Exception
*/
public Reprap(Preferences prefs) throws Exception {
statusWindow = new StatusMessage(new JFrame());
startTime = System.currentTimeMillis();
int axes = prefs.loadInt("AxisCount");
if (axes != 3)
throw new Exception("A Reprap printer must contain 3 axes");
String commPortName = prefs.loadString("Port(name)");
// SNAPAddress myAddress = new SNAPAddress(localNodeNumber);
// communicator = new SNAPCommunicator(commPortName, myAddress);
motorX = new GenericStepperMotor(communicator,
new SNAPAddress(prefs.loadInt("XAxisAddress")), prefs, 1);
motorY = new GenericStepperMotor(communicator,
new SNAPAddress(prefs.loadInt("YAxisAddress")), prefs, 2);
motorZ = new GenericStepperMotor(communicator,
new SNAPAddress(prefs.loadInt("ZAxisAddress")), prefs, 3);
extruderCount = prefs.loadInt("NumberOfExtruders");
extruders = new GenericExtruder[extruderCount];
if (extruderCount < 1)
throw new Exception("A Reprap printer must contain at least one extruder");
for(int i = 0; i < extruderCount; i++)
{
String prefix = "Extruder" + i + "_";
extruders[i] = new GenericExtruder(communicator,
new SNAPAddress(prefs.loadInt(prefix + "Address")), prefs, i);
}
extruder=0;
xYReZeroInterval = prefs.loadDouble("XYReZeroInterval(mm)");
layerPrinter = new LinePrinter(motorX, motorY, extruders[extruder]);
// TODO This should be from calibration
scaleX = prefs.loadDouble("XAxisScale(steps/mm)");
scaleY = prefs.loadDouble("YAxisScale(steps/mm)");
scaleZ = prefs.loadDouble("ZAxisScale(steps/mm)");
idleZ = prefs.loadBool("IdleZAxis");
fastSpeedXY = prefs.loadInt("FastSpeed(0..255)");
try {
currentX = convertToPositionZ(motorX.getPosition());
currentY = convertToPositionZ(motorY.getPosition());
} catch (Exception ex) {
throw new Exception("Warning: X and/or Y controller not responding, cannot continue");
}
try {
currentZ = convertToPositionZ(motorZ.getPosition());
} catch (Exception ex) {
System.err.println("Z axis not responding and will be ignored");
excludeZ = true;
}
}
/* (non-Javadoc)
* @see org.reprap.Printer#calibrate()
*/
public void calibrate() {
}
/* (non-Javadoc)
* @see org.reprap.Printer#moveTo(double, double, double, boolean, boolean)
*/
public void moveTo(double x, double y, double z, boolean startUp, boolean endUp) throws ReprapException, IOException {
if (isCancelled()) return;
int stepperX = convertToStepX(x);
int stepperY = convertToStepY(y);
int stepperZ = convertToStepZ(z);
int currentStepperX = convertToStepX(currentX);
int currentStepperY = convertToStepY(currentY);
int currentStepperZ = convertToStepZ(currentZ);
if (currentStepperX == stepperX &&
currentStepperY ==stepperY &&
currentStepperZ == stepperZ &&
!startUp)
return;
// We don't need to lift a whole layer up. Half a layer should do
// and will dribble less. Remember the Z axis is kinda slow...
double liftedZ = z + (extruders[extruder].getMinLiftedZ());
int stepperLiftedZ = convertToStepZ(liftedZ);
int targetZ;
// Raise head slightly before move?
if(startUp)
{
targetZ = stepperLiftedZ;
currentZ = liftedZ;
} else
{
targetZ = stepperZ;
currentZ = z;
}
if (targetZ != currentStepperZ) {
totalDistanceMoved += Math.abs(currentZ - liftedZ);
if (!excludeZ) motorZ.seekBlocking(speedZ, targetZ);
if (idleZ) motorZ.setIdle();
currentStepperZ = targetZ;
}
layerPrinter.moveTo(stepperX, stepperY, currentSpeedXY);
totalDistanceMoved += segmentLength(x - currentX, y - currentY);
currentX = x;
currentY = y;
if(endUp)
{
targetZ = stepperLiftedZ;
currentZ = liftedZ;
} else
{
targetZ = stepperZ;
currentZ = z;
}
// Move head back down to surface?
if(targetZ != currentStepperZ)
{
totalDistanceMoved += Math.abs(currentZ - z);
if (!excludeZ) motorZ.seekBlocking(speedZ, targetZ);
if (idleZ) motorZ.setIdle();
currentStepperZ = targetZ;
}
}
// double totalDistanceMoved = 0.0;
// double totalDistanceExtruded = 0.0;
// double xYReZeroInterval = -1;
// double distanceFromLastZero = 0;
// double distanceAtLastCall = 0;
private void maybeReZero() throws ReprapException, IOException
{
if(xYReZeroInterval <= 0)
return;
distanceFromLastZero += totalDistanceMoved - distanceAtLastCall;
distanceAtLastCall = totalDistanceMoved;
if(distanceFromLastZero < xYReZeroInterval)
return;
distanceFromLastZero = 0;
double liftedZ = currentZ + (extruders[extruder].getMinLiftedZ());
int stepperZ = convertToStepZ(liftedZ);
extruders[extruder].setValve(false);
extruders[extruder].setExtrusion(0);
if (!excludeZ) motorZ.seekBlocking(speedZ, stepperZ);
double x = currentX;
double y = currentY;
int stepperX = convertToStepX(x);
int stepperY = convertToStepY(y);
homeToZeroX();
totalDistanceMoved += segmentLength(currentX, 0);
homeToZeroY();
totalDistanceMoved += segmentLength(0, currentY);
layerPrinter.moveTo(stepperX, stepperY, fastSpeedXY);
totalDistanceMoved += segmentLength(x, y);
currentX = x;
currentY = y;
stepperZ = convertToStepZ(currentZ);
if (!excludeZ) motorZ.seekBlocking(speedZ, stepperZ);
printStartDelay(false);
}
/* (non-Javadoc)
* @see org.reprap.Printer#printTo(double, double, double, boolean)
*/
public void printTo(double x, double y, double z, boolean turnOff)
throws ReprapException, IOException {
if (isCancelled()) return;
EnsureNotEmpty();
if (isCancelled()) return;
EnsureHot();
if (isCancelled()) return;
maybeReZero();
int stepperX = convertToStepX(x);
int stepperY = convertToStepY(y);
int stepperZ = convertToStepZ(z);
if ((stepperX != layerPrinter.getCurrentX() || stepperY != layerPrinter.getCurrentY()) && z != currentZ)
throw new ReprapException("Reprap cannot print a line across 3 axes simultaneously");
if (previewer != null)
previewer.addSegment(convertToPositionX(layerPrinter.getCurrentX()),
convertToPositionY(layerPrinter.getCurrentY()), currentZ,
x, y, z);
if (isCancelled()) return;
if (z != currentZ)
{
System.out.println("Printing a vertical extrusion. Should we do that?");
// Print a simple vertical extrusion
double distance = Math.abs(currentZ - z);
totalDistanceExtruded += distance;
totalDistanceMoved += distance;
extruders[extruder].setExtrusion(extruders[extruder].getExtruderSpeed());
if (!excludeZ) motorZ.seekBlocking(speedZ, stepperZ);
extruders[extruder].setExtrusion(0);
currentZ = z;
return;
}
// Otherwise printing only in X/Y plane
double deltaX = x - currentX;
double deltaY = y - currentY;
double distance = segmentLength(deltaX, deltaY);
totalDistanceExtruded += distance;
totalDistanceMoved += distance;
if (segmentPauseCheckbox != null && distance > 0)
if(segmentPauseCheckbox.isSelected())
segmentPause();
layerPrinter.printTo(stepperX, stepperY, currentSpeedXY, extruders[extruder].getExtruderSpeed(), turnOff);
currentX = x;
currentY = y;
}
public void stopExtruding() throws IOException
{
layerPrinter.stopExtruding();
}
public void stopValve() throws IOException
{
layerPrinter.stopValve();
}
/* Move to zero stop on X axis.
* (non-Javadoc)
* @see org.reprap.Printer#homeToZeroX()
*/
public void homeToZeroX() throws ReprapException, IOException {
motorX.homeReset(fastSpeedXY);
currentX=0;
layerPrinter.zeroX();
}
/* Move to zero stop on Y axis.
* (non-Javadoc)
* @see org.reprap.Printer#homeToZeroY()
*/
public void homeToZeroY() throws ReprapException, IOException {
motorY.homeReset(fastSpeedXY);
currentY=0;
layerPrinter.zeroY();
}
/* (non-Javadoc)
* @see org.reprap.Printer#selectMaterial(int)
*/
public void selectExtruder(int materialIndex) {
if (isCancelled()) return;
if(materialIndex < 0 || materialIndex >= extruderCount)
System.err.println("Selected material (" + materialIndex + ") is out of range.");
else
extruder = materialIndex;
layerPrinter.changeExtruder(extruders[extruder]);
// if (previewer != null)
// previewer.setExtruder(extruders[extruder]);
if (isCancelled()) return;
// TODO Select new material
// TODO Load new x/y/z offsets for the new extruder
}
/* (non-Javadoc)
* @see org.reprap.Printer#selectMaterial(int)
*/
public void selectExtruder(Attributes att) {
for(int i = 0; i < extruderCount; i++)
{
if(att.getMaterial().equals(extruders[i].toString()))
{
selectExtruder(i);
return;
}
}
System.err.println("selectExtruder() - extruder not found for: " + att.getMaterial());
}
/**
* FIXME: Why don't these use round()? - AB.
* @param n
* @return
*/
protected int convertToStepX(double n) {
return (int)((n + extruders[extruder].getOffsetX()) * scaleX);
}
/**
* @param n
* @return
*/
protected int convertToStepY(double n) {
return (int)((n + extruders[extruder].getOffsetY()) * scaleY);
}
/**
* @param n
* @return
*/
protected int convertToStepZ(double n) {
return (int)((n + extruders[extruder].getOffsetZ()) * scaleZ);
}
/**
* @param n
* @return
*/
protected double convertToPositionX(int n) {
return n / scaleX - extruders[extruder].getOffsetX();
}
/**
* @param n
* @return
*/
protected double convertToPositionY(int n) {
return n / scaleY - extruders[extruder].getOffsetY();
}
/**
* @param n
* @return
*/
protected double convertToPositionZ(int n) {
return n / scaleZ - extruders[extruder].getOffsetZ();
}
/* (non-Javadoc)
* @see org.reprap.Printer#terminate()
*/
public void terminate() throws Exception {
motorX.setIdle();
motorY.setIdle();
if (!excludeZ) motorZ.setIdle();
extruders[extruder].setExtrusion(0);
extruders[extruder].setTemperature(0);
}
/* (non-Javadoc)
* @see org.reprap.Printer#dispose()
*/
public void dispose() {
motorX.dispose();
motorY.dispose();
motorZ.dispose();
for(int i = 0; i < extruderCount; i++)
extruders[i].dispose();
// communicator.close();
// communicator.dispose();
}
/**
* @return Returns the speed for the X & Y axes.
*/
// public int getSpeed() {
// return currentSpeedXY;
// }
/**
* @return Returns the maximum speed for the X & Y axes in air movement.
*/
public int getFastSpeed() {
return fastSpeedXY;
}
/**
* @param speed The speed to set for the X and Y axes.
*/
public void setSpeed(int speed) {
currentSpeedXY = speed;
}
/**
* @param speed The speed to set for the X and Y axes moving in air.
*/
public void setFastSpeed(int speed) {
this.fastSpeedXY = speed;
}
/**
* @return Returns the speed for the Z axis.
*/
public int getSpeedZ() {
return speedZ;
}
/**
* @param speed The speed to set for the Z axis.
*/
public void setSpeedZ(int speed) {
this.speedZ = speed;
}
/**
* Returns the speedExtruder.
*/
// public int getExtruderSpeed() {
// return speedExtruder;
// }
/**
* The speedExtruder to set.
*/
// public void setExtruderSpeed(int speedExtruder) {
// this.speedExtruder = speedExtruder;
// }
/* (non-Javadoc)
* @see org.reprap.Printer#setPreviewer(org.reprap.gui.Previewer)
*/
public void setPreviewer(Previewer previewer) {
this.previewer = previewer;
}
// public void setTemperature(int temperature) throws Exception {
// extruder.setTemperature(temperature);
// }
/**
* outline speed and the infill speed
*/
// public double getOutlineSpeed()
// {
// return extruder.getOutlineSpeed();
// }
// public double getInfillSpeed()
// {
// return extruder.getInfillSpeed();
// }
/**
* The length in mm to speed up when going round corners
*/
// public double getAngleSpeedUpLength()
// {
// return extruder.getAngleSpeedUpLength();
// }
/**
* The factor by which to speed up when going round a corner.
* The formula is speed = baseSpeed*[1 + 0.5*(1 - ca)*getAngleSpeedFactor()]
* where ca is the cos of the angle between the lines. So it goes fastest when
* the line doubles back on itself, and slowest when it continues straight.
*/
// public double getAngleSpeedFactor()
// {
// return extruder.getAngleSpeedFactor();
// }
/**
*
*/
private void EnsureNotEmpty() {
if (!extruders[extruder].isEmpty()) return;
while (extruders[extruder].isEmpty() && !isCancelled()) {
//if (previewer != null)
//previewer.
setMessage("Extruder is out of feedstock. Waiting for refill.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
//if (previewer != null) previewer.
setMessage(null);
}
/**
* @throws ReprapException
* @throws IOException
*/
private void EnsureHot() throws ReprapException, IOException {
if(extruders[extruder].getTemperatureTarget() <= Preferences.absoluteZero() + 1)
return;
double threshold = extruders[extruder].getTemperatureTarget() * 0.90; // Changed from 0.95 by Vik.
if (extruders[extruder].getTemperature() >= threshold)
return;
double x = currentX;
double y = currentY;
int tempReminder=0;
temperatureReminder();
Debug.d("Moving to heating zone");
int oldSpeed = currentSpeedXY;
// Ensure the extruder is off
extruders[extruder].setExtrusion(0);
moveToHeatingZone();
while(extruders[extruder].getTemperature() < threshold && !isCancelled()) {
//if (previewer != null) previewer.
setMessage("Waiting for extruder to reach working temperature (" +
Math.round(extruders[extruder].getTemperature()) + ")");
try {
Thread.sleep(1000);
// If it stays cold for 10s, remind it of its purpose.
if (tempReminder++ >10) {
tempReminder=0;
temperatureReminder();
}
} catch (InterruptedException e) {
}
}
Debug.d("Returning to previous position");
moveTo(x, y, currentZ, true, false);
setSpeed(oldSpeed);
//if (previewer != null) previewer.
setMessage(null);
}
/** A bodge to fix the extruder's current tendency to forget what temperature
* it is supposed to be reaching.
*
* Vik
*/
private void temperatureReminder() {
if(extruders[extruder].getTemperatureTarget() < Preferences.absoluteZero())
return;
Debug.d("Reminding it of the temperature");
try {
extruders[extruder].setTemperature(extruders[extruder].getTemperatureTarget());
//setTemperature(Preferences.loadGlobalInt("ExtrusionTemp"));
} catch (Exception e) {
System.err.println("Error resetting temperature.");
}
}
/**
* Moves the head to the predefined heating area
* @throws IOException
* @throws ReprapException
*/
private void moveToHeatingZone() throws ReprapException, IOException {
setSpeed(fastSpeedXY);
moveTo(1, 1, currentZ, true, false);
}
/* (non-Javadoc)
* @see org.reprap.Printer#isCancelled()
*/
// public boolean isCancelled() {
// if (previewer == null)
// return false;
// return previewer.isCancelled();
// }
/* (non-Javadoc)
* @see org.reprap.Printer#initialise()
*/
public void initialise() throws Exception {
if (previewer != null)
previewer.reset();
motorX.homeReset(fastSpeedXY);
motorY.homeReset(fastSpeedXY);
if (!excludeZ) motorZ.homeReset(speedZ);
currentX = currentY = currentZ = 0.0;
}
/* (non-Javadoc)
* @see org.reprap.Printer#getX()
*/
public double getX() {
return currentX;
}
/* (non-Javadoc)
* @see org.reprap.Printer#getY()
*/
public double getY() {
return currentY;
}
/* (non-Javadoc)
* @see org.reprap.Printer#getZ()
*/
public double getZ() {
return currentZ;
}
/* (non-Javadoc)
* @see org.reprap.Printer#getTotalDistanceMoved()
*/
public double getTotalDistanceMoved() {
return totalDistanceMoved;
}
/* (non-Javadoc)
* @see org.reprap.Printer#getTotalDistanceExtruded()
*/
public double getTotalDistanceExtruded() {
return totalDistanceExtruded;
}
/**
* @param x
* @param y
* @return segment length in millimeters
*/
public double segmentLength(double x, double y) {
return Math.sqrt(x*x + y*y);
}
// public double getExtrusionSize() {
// return extrusionSize;
// }
// public double getExtrusionHeight() {
// return extrusionHeight;
// }
// public double getInfillWidth() {
// return infillWidth;
// }
/**
* @param enable
* @throws IOException
*/
public void setCooling(boolean enable) throws IOException {
extruders[extruder].setCooler(enable);
}
/**
* Get the length before the end of a track to turn the extruder off
* to allow for the delay in the stream stopping.
*/
// public double getOverRun() { return overRun; }
/**
* Get the number of milliseconds to wait between turning an
* extruder on and starting to move it.
*/
// public long getDelay() { return delay; }
/* (non-Javadoc)
* @see org.reprap.Printer#getTotalElapsedTime()
*/
public double getTotalElapsedTime() {
long now = System.currentTimeMillis();
return (now - startTime) / 1000.0;
}
/**
* Extrude for the given time in milliseconds, so that polymer is flowing
* before we try to move the extruder.
*/
public void printStartDelay(boolean firstOneInLayer)
{
// Extrude motor and valve delays (ms)
long eDelay, vDelay;
if(firstOneInLayer)
{
eDelay = (long)extruders[extruder].getExtrusionDelayForLayer();
vDelay = (long)extruders[extruder].getValveDelayForLayer();
} else
{
eDelay = (long)extruders[extruder].getExtrusionDelayForPolygon();
vDelay = (long)extruders[extruder].getValveDelayForPolygon();
}
try
{
if(eDelay >= vDelay)
{
extruders[extruder].setExtrusion(extruders[extruder].getExtruderSpeed());
Thread.sleep(eDelay - vDelay);
extruders[extruder].setValve(true);
Thread.sleep(vDelay);
} else
{
extruders[extruder].setValve(true);
Thread.sleep(vDelay - eDelay);
extruders[extruder].setExtrusion(extruders[extruder].getExtruderSpeed());
Thread.sleep(eDelay);
}
extruders[extruder].setExtrusion(0); // What's this for? - AB
} catch(Exception e)
{
// If anything goes wrong, we'll let someone else catch it.
}
}
/* (non-Javadoc)
* @see org.reprap.Printer#setLowerShell(javax.media.j3d.Shape3D)
*/
public void setLowerShell(BranchGroup ls)
{
if(previewer != null)
previewer.setLowerShell(ls);
}
/* (non-Javadoc)
* @see org.reprap.Printer#setZManual()
*/
public void setZManual() throws IOException {
setZManual(0.0);
}
/* (non-Javadoc)
* @see org.reprap.Printer#setZManual(double)
*/
public void setZManual(double zeroPoint) throws IOException {
CalibrateZAxis msg =
new CalibrateZAxis(null, motorZ, scaleZ, speedZ);
msg.setVisible(true);
try {
synchronized(msg) {
msg.wait();
}
} catch (Exception ex) {
}
msg.dispose();
motorZ.setPosition(convertToStepZ(zeroPoint));
}
/* (non-Javadoc)
* @see org.reprap.Printer#getExtruder()
*/
public Extruder getExtruder()
{
return extruders[extruder];
}
/* (non-Javadoc)
* @see org.reprap.Printer#getExtruder()
*/
public Extruder[] getExtruders()
{
return extruders;
}
/* (non-Javadoc)
* @see org.reprap.Printer#getExtruder(String)
*/
public Extruder getExtruder(String name)
{
for(int i = 0; i < extruderCount; i++)
if(name.equals(extruders[i].toString()))
return extruders[i];
return null;
}
// /**
// * Moves nozzle back and forth over wiper
// */
// public void wipeNozzle() throws ReprapException, IOException {
//
// if (getExtruder().getNozzleWipeEnabled() == false) return;
//
// else {
//
// int freq = getExtruder().getNozzleWipeFreq();
// double datumX = getExtruder().getNozzleWipeDatumX();
// double datumY = getExtruder().getNozzleWipeDatumY();
// double strokeX = getExtruder().getNozzleWipeStrokeX();
// double strokeY = getExtruder().getNozzleWipeStrokeY();
//
// setSpeed(fastSpeedXY);
// //moveTo(datumX, datumY + strokeY, currentZ, false, false);
// moveTo(datumX, datumY, currentZ, false, false);
// double clearTime = getExtruder().getNozzleClearTime();
// if(clearTime > 0)
// {
// extruders[extruder].setExtrusion(extruders[extruder].getExtruderSpeed());
// try
// {
// Thread.sleep((long)(1000*clearTime));
// } catch (Exception ex)
// {
// }
// extruders[extruder].setExtrusion(0);
// }
//
// try
// {
// Thread.sleep((long)(10000));
// } catch (Exception ex)
// {
// }
//
// moveTo(datumX, datumY + strokeY, currentZ, false, false);
//
//// double step = 0.5*strokeX/freq;
//// double xInc = 0;
////
//// // Moves nozzle over wiper
////
//// for (int w=0; w < freq; w++)
//// {
//// moveTo(datumX + xInc, datumY, currentZ, false, false);
//// xInc += step;
//// moveTo(datumX + xInc, datumY, currentZ, false, false);
//// moveTo(datumX + xInc, datumY + strokeY, currentZ, false, false);
//// xInc += step;
//// moveTo(datumX + xInc, datumY + strokeY, currentZ, false, false);
//// }
//
//
// }
// }
/**
* Just finished a layer
* @param layerNumber
*/
public void finishedLayer(int layerNumber) throws Exception
{
double datumX = getExtruder().getNozzleWipeDatumX();
double datumY = getExtruder().getNozzleWipeDatumY();
double strokeX = getExtruder().getNozzleWipeStrokeX();
double strokeY = getExtruder().getNozzleWipeStrokeY();
double coolTime = getExtruder().getCoolingPeriod();
startCooling = -1;
if(coolTime > 0 && (layerNumber != 0)) {
getExtruder().setCooler(true);
Debug.d("Start of cooling period");
setSpeed(getFastSpeed());
// Go home. Seek (0,0) then callibrate X first
homeToZeroX();
homeToZeroY();
startCooling = Timer.elapsed();
}
// If wiping, nudge the clearer blade
if (getExtruder().getNozzleWipeEnabled())
{
// Now hunt down the wiper.
moveTo(datumX, datumY, currentZ, false, false);
setSpeed(getExtruder().getXYSpeed());
moveTo(datumX + strokeX, datumY+strokeY, currentZ, false, false);
moveTo(datumX, datumY, currentZ, false, false);
}
}
/**
* Deals with all the actions that need to be done between one layer
* and the next.
*/
public void betweenLayers(int layerNumber) throws Exception
{
double clearTime = getExtruder().getNozzleClearTime();
// Do half the extrusion between layers now
if (getExtruder().getNozzleWipeEnabled())
{
if(clearTime > 0)
{
getExtruder().setExtrusion(extruders[extruder].getExtruderSpeed());
Thread.sleep((long)(500*clearTime));
getExtruder().setExtrusion(0);
}
}
// Now is a good time to garbage collect
System.gc();
}
/**
* Just about to start the next layer
* @param layerNumber
*/
public void startingLayer(int layerNumber) throws Exception
{
double datumX = getExtruder().getNozzleWipeDatumX();
double datumY = getExtruder().getNozzleWipeDatumY();
double strokeY = getExtruder().getNozzleWipeStrokeY();
double clearTime = getExtruder().getNozzleClearTime();
double waitTime = getExtruder().getNozzleWaitTime();
double coolTime = getExtruder().getCoolingPeriod();
if (layerPauseCheckbox != null && layerPauseCheckbox.isSelected())
layerPause();
if(isCancelled())
{
getExtruder().setCooler(false);
return;
}
// Cooling period
// How long has the fan been on?
double cool = Timer.elapsed();
if(startCooling >= 0)
cool = cool - startCooling;
else
cool = 0;
// Wait the remainder of the cooling period
if(coolTime > cool && (layerNumber != 0))
{
cool = coolTime - cool;
Thread.sleep((long)(1000*cool));
}
// Fan off
getExtruder().setCooler(false);
// If we were cooling, wait for warm-up
if(coolTime > 0 && (layerNumber != 0))
{
Thread.sleep((long)(200 * coolTime));
Debug.d("End of cooling period");
}
// Do the other half of the clearing extrude then
// Wipe the nozzle on the doctor blade
if (getExtruder().getNozzleWipeEnabled())
{
if(clearTime > 0)
{
getExtruder().setExtrusion(extruders[extruder].getExtruderSpeed());
Thread.sleep((long)(500*clearTime));
getExtruder().setExtrusion(0);
Thread.sleep((long)(1000*waitTime));
}
setSpeed(LinePrinter.speedFix(getExtruder().getXYSpeed(),
getExtruder().getOutlineSpeed()));
moveTo(datumX, datumY + strokeY, currentZ, false, false);
}
setSpeed(getFastSpeed());
}
/**
* Display a message indicating a segment is about to be
* printed and wait for the user to acknowledge
*/
private void segmentPause() {
ContinuationMesage msg =
new ContinuationMesage(null, "A new segment is about to be produced");
//,segmentPauseCheckbox, layerPauseCheckbox);
msg.setVisible(true);
try {
synchronized(msg) {
msg.wait();
}
} catch (Exception ex) {
}
if (msg.getResult() == false)
setCancelled(true);
msg.dispose();
}
/**
* Display a message indicating a layer is about to be
* printed and wait for the user to acknowledge
*/
private void layerPause() {
ContinuationMesage msg =
new ContinuationMesage(null, "A new layer is about to be produced");
//,segmentPauseCheckbox, layerPauseCheckbox);
msg.setVisible(true);
try {
synchronized(msg) {
msg.wait();
}
} catch (Exception ex) {
}
if (msg.getResult() == false)
setCancelled(true);
msg.dispose();
}
/**
* Set the source checkbox used to determine if there should
* be a pause between segments.
*
* @param segmentPause The source checkbox used to determine
* if there should be a pause. This is a checkbox rather than
* a boolean so it can be changed on the fly.
*/
public void setSegmentPause(JCheckBoxMenuItem segmentPause) {
segmentPauseCheckbox = segmentPause;
}
/**
* Set the source checkbox used to determine if there should
* be a pause between layers.
*
* @param layerPause The source checkbox used to determine
* if there should be a pause. This is a checkbox rather than
* a boolean so it can be changed on the fly.
*/
public void setLayerPause(JCheckBoxMenuItem layerPause) {
layerPauseCheckbox = layerPause;
}
public void setMessage(String message) {
if (message == null)
statusWindow.setVisible(false);
else {
statusWindow.setMessage(message);
statusWindow.setVisible(true);
}
}
public boolean isCancelled() {
return statusWindow.isCancelled();
}
public void setCancelled(boolean isCancelled) {
statusWindow.setCancelled(isCancelled);
}
}