package org.reprap.devices;
import java.io.IOException;
import org.reprap.Preferences;
import org.reprap.Extruder;
import org.reprap.Printer;
import org.reprap.geometry.LayerRules;
import org.reprap.utilities.Debug;
import javax.media.j3d.Appearance;
import javax.vecmath.Color3f;
import javax.media.j3d.Material;
/**
* @author jwiel
*
*/
public abstract class GenericExtruder implements Extruder
{
/**
* Flag to decide extrude speed
*/
protected boolean separating;
/**
* How far we have extruded plus other things like temperature
*/
protected ExtruderState es;
/**
* Flag to decide if the machine implements 4D extruding
* (i.e. it processes extrude lengths along with X, Y, and Z
* lengths in a 4D Bressenham DDA)
*/
protected boolean fiveD;
/**
* Flag to record if we're going backwards
*/
//protected boolean reversing;
/**
* The current extrude speed
*/
//protected double currentSpeed = 0;
/**
* Offset of 0 degrees centigrade from absolute zero
*/
public static final double absZero = 273.15;
/**
* The temperature most recently read from the device
*/
//protected double currentTemperature = 0;
/**
* Maximum motor speed (value between 0-255)
*/
protected int maxExtruderSpeed;
/**
* The actual extrusion speed
*/
//protected double extrusionSpeed;
/**
* The time to run the extruder at the start
* -ve values supress
*/
protected double purgeTime;
/**
* The PWM into stepper extruders
*/
protected double extrusionPWM;
/**
* The extrusion temperature
*/
protected double extrusionTemp;
/**
* The extrusion width in XY
*/
protected double extrusionSize;
/**
* The extrusion height in Z
* TODO: Should this be a machine-wide constant? - AB
*/
protected double extrusionHeight;
/**
* The step between infill tracks
*/
protected double extrusionInfillWidth;
/**
* below this infill finely
*/
protected int lowerFineLayers;
/**
* Above this infill finely
*/
protected int upperFineLayers;
/**
* Use this for broad infill in the middle; if negative, always
* infill fine.
*/
protected double extrusionBroadWidth;
/**
* The number of seconds to cool between layers
*/
protected double coolingPeriod;
/**
* The fastest speed of movement in XY when depositing
*/
protected double fastXYFeedrate;
/**
* The fastest the extruder can extrude
*/
protected double fastEFeedrate;
/**
* The speed from which that machine can do a standing start with this extruder
*/
protected double slowXYFeedrate;
/**
* The fastest the machine can accelerate with this extruder
*/
protected double maxAcceleration;
/**
* Zero torque speed
*/
protected int t0;
/**
* Infill speed [0,1]*maxSpeed
*/
protected double iSpeed;
/**
* Outline speed [0,1]*maxSpeed
*/
protected double oSpeed;
/**
* Length (mm) to speed up round corners
*/
protected double asLength;
/**
* Factor by which to speed up round corners
*/
protected double asFactor;
/**
* Line length below which to plot faster
*/
protected double shortLength;
/**
*Factor for short line speeds
*/
protected double shortSpeed;
/**
* The name of this extruder's material
*/
protected String material;
/**
* Number of mm to overlap the hatching infill with the outline. 0 gives none; -ve will
* leave a gap between the two
*/
protected double infillOverlap = 0;
/**
* Where to put the nozzle
*/
//protected double offsetX, offsetY, offsetZ;
/**
* The diameter of the feedstock (if any)
*/
protected double feedDiameter = -1;
/**
*
*/
//protected long lastTemperatureUpdate = 0;
/**
* Identifier of the extruder
*/
protected int myExtruderID;
/**
* One physical extruder can have several of this class attached to it
* with different myExtruderIDs. physicalExtruder is a unique integer
* for each actual extruder, derived from the old SNAP address of the extruder,
* which is necessarily unique.
*/
//protected int physicalExtruder;
/**
* prefix for our preferences.
*/
protected String prefName;
/**
* Start polygons at random perimiter points
*/
protected boolean randSt = false;
/**
* Start polygons at incremented perimiter points
*/
protected boolean incrementedSt = false;
/**
* The colour black
*/
protected static final Color3f black = new Color3f(0, 0, 0);
/**
* The colour of the material to use in the simulation windows
*/
protected Appearance materialColour;
/**
* Enable wiping procedure for nozzle
*/
protected boolean nozzleWipeEnabled;
/**
* Co-ordinates for the nozzle wiper
*/
protected double nozzleWipeDatumX;
protected double nozzleWipeDatumY;
/**
* X Distance to move nozzle over wiper
*/
protected double nozzleWipeStrokeX;
/**
* Y Distance to move nozzle over wiper
*/
protected double nozzleWipeStrokeY;
/**
* Number of wipe cycles per method call
*/
protected int nozzleWipeFreq;
/**
* Number of seconds to run to re-start the nozzle before a wipe
*/
protected double nozzleClearTime;
/**
* Number of seconds to wait after restarting the nozzle
*/
protected double nozzleWaitTime;
/**
* The current coordinate to wipe at
*/
protected double wipeX;
/**
* The number of ms to pulse the valve to open or close it
* -ve to supress
*/
protected double valvePulseTime;
/**
* The number of milliseconds to wait before starting a border track
*/
protected double extrusionDelayForLayer = 0;
/**
* How high to move above the surface for non-extruding movements
*/
protected double lift = 0;
/**
* The number of milliseconds to wait before starting a hatch track
*/
protected double extrusionDelayForPolygon = 0;
/**
* The number of milliseconds to reverse at the end of a track
*/
protected double extrusionReverseDelay = -1;
/**
* The number of milliseconds to wait before starting a border track
*/
protected double valveDelayForLayer = 0;
/**
* The number of milliseconds to wait before starting a hatch track
*/
protected double valveDelayForPolygon = 0;
/**
* The number of mm to stop extruding before the end of a track
*/
protected double extrusionOverRun;
/**
* The number of mm to stop extruding before the end of a track
*/
protected double valveOverRun;
/**
* The smallest allowable free-movement height above the base
*/
protected double minLiftedZ = 1;
/**
* The number of outlines to plot
*/
protected int shells = 1;
/**
* Stop the extrude motor between segments?
*/
protected boolean pauseBetweenSegments = true;
/**
* This decides how many layers to fine-infill for areas that are upward-
* or downward-facing surfaces of the object.
* @return
*/
protected int surfaceLayers = 2;
/**
* Are we currently extruding?
*/
//protected boolean isExtruding = false;
private double extrusionFoundationWidth;
private double extrusionLastFoundationWidth;
private double separationFraction;
private double arcCompensationFactor;
private double arcShortSides;
private double evenHatchDirection;
private double oddHatchDirection;
private String supportMaterial;
private String inFillMaterial;
protected double extrudeRatio = 1;
protected boolean middleStart;
protected boolean singleLine = false;
/**
* Our printer object.
*/
protected Printer printer = null;
/**
* @param extruderId
*/
public GenericExtruder(int extruderId, Printer p)
{
printer = p;
try
{
fiveD = Preferences.loadGlobalBool("FiveD");
} catch (Exception e)
{
fiveD = false;
}
myExtruderID = extruderId;
separating = false;
es = new ExtruderState(refreshPreferences());
es.setReverse(false);
}
/**
* Allow others to set our extrude length so that all logical extruders
* talking to one physical extruder can use the same length instance.
* @param e
*/
public void setExtrudeState(ExtruderState e)
{
es = e;
}
/**
* Zero the extruded length
*
*/
public void zeroExtrudedLength(boolean really) throws Exception
{
es.zero();
}
public int refreshPreferences()
{
prefName = "Extruder" + myExtruderID + "_";
int result = -1;
try
{
result = Preferences.loadGlobalInt(prefName + "Address");
maxExtruderSpeed = 255; //Preferences.loadGlobalInt(prefName + "MaxSpeed(0..255)");
// extrusionSpeed = Preferences.loadGlobalDouble(prefName + "ExtrusionSpeed(mm/minute)");
purgeTime = Preferences.loadGlobalDouble(prefName + "Purge(ms)");
extrusionPWM = Preferences.loadGlobalDouble(prefName + "ExtrusionPWM(0..1)");
extrusionTemp = Preferences.loadGlobalDouble(prefName + "ExtrusionTemp(C)");
extrusionSize = Preferences.loadGlobalDouble(prefName + "ExtrusionSize(mm)");
extrusionHeight = Preferences.loadGlobalDouble(prefName + "ExtrusionHeight(mm)");
extrusionInfillWidth = Preferences.loadGlobalDouble(prefName + "ExtrusionInfillWidth(mm)");
lowerFineLayers = 2; //Preferences.loadGlobalInt(prefName + "LowerFineLayers(0...)");
upperFineLayers = 2; //Preferences.loadGlobalInt(prefName + "UpperFineLayers(0...)");
extrusionBroadWidth = Preferences.loadGlobalDouble(prefName + "ExtrusionBroadWidth(mm)");
coolingPeriod = Preferences.loadGlobalDouble(prefName + "CoolingPeriod(s)");
fastXYFeedrate = Preferences.loadGlobalDouble(prefName + "FastXYFeedrate(mm/minute)");
fastEFeedrate = Preferences.loadGlobalDouble(prefName + "FastEFeedrate(mm/minute)");
slowXYFeedrate = Preferences.loadGlobalDouble(prefName + "SlowXYFeedrate(mm/minute)");
maxAcceleration = Preferences.loadGlobalDouble(prefName + "MaxAcceleration(mm/minute/minute)");
middleStart = Preferences.loadGlobalBool(prefName + "MiddleStart");
t0 = 0; //Preferences.loadGlobalInt(prefName + "t0(0..255)");
iSpeed = Preferences.loadGlobalDouble(prefName + "InfillSpeed(0..1)");
oSpeed = Preferences.loadGlobalDouble(prefName + "OutlineSpeed(0..1)");
asLength = -1; //Preferences.loadGlobalDouble(prefName + "AngleSpeedLength(mm)");
asFactor = 0.5; //Preferences.loadGlobalDouble(prefName + "AngleSpeedFactor(0..1)");
material = Preferences.loadGlobalString(prefName + "MaterialType(name)");
supportMaterial = Preferences.loadGlobalString(prefName + "SupportMaterialType(name)");
inFillMaterial = Preferences.loadGlobalString(prefName + "InFillMaterialType(name)");
// offsetX = Preferences.loadGlobalDouble(prefName + "OffsetX(mm)");
// offsetY = Preferences.loadGlobalDouble(prefName + "OffsetY(mm)");
// offsetZ = Preferences.loadGlobalDouble(prefName + "OffsetZ(mm)");
nozzleWipeEnabled = false; //Preferences.loadGlobalBool(prefName + "NozzleWipeEnabled");
nozzleWipeDatumX = 22.4; //Preferences.loadGlobalDouble(prefName + "NozzleWipeDatumX(mm)");
nozzleWipeDatumY = 4; //Preferences.loadGlobalDouble(prefName + "NozzleWipeDatumY(mm)");
nozzleWipeStrokeX = 0; //Preferences.loadGlobalDouble(prefName + "NozzleWipeStrokeX(mm)");
nozzleWipeStrokeY = 10; //Preferences.loadGlobalDouble(prefName + "NozzleWipeStrokeY(mm)");
nozzleWipeFreq = 1; //Preferences.loadGlobalInt(prefName + "NozzleWipeFreq");
nozzleClearTime = 10; //Preferences.loadGlobalDouble(prefName + "NozzleClearTime(s)");
nozzleWaitTime = 0; //Preferences.loadGlobalDouble(prefName + "NozzleWaitTime(s)");
randSt = false; //Preferences.loadGlobalBool(prefName + "RandomStart");
incrementedSt = false; //Preferences.loadGlobalBool(prefName + "IncrementedStart");
shortLength = -1; //Preferences.loadGlobalDouble(prefName + "ShortLength(mm)");
shortSpeed = 1; //Preferences.loadGlobalDouble(prefName + "ShortSpeed(0..1)");
infillOverlap = Preferences.loadGlobalDouble(prefName + "InfillOverlap(mm)");
extrusionDelayForLayer = Preferences.loadGlobalDouble(prefName + "ExtrusionDelayForLayer(ms)");
extrusionDelayForPolygon = Preferences.loadGlobalDouble(prefName + "ExtrusionDelayForPolygon(ms)");
extrusionOverRun = Preferences.loadGlobalDouble(prefName + "ExtrusionOverRun(mm)");
valveDelayForLayer = Preferences.loadGlobalDouble(prefName + "ValveDelayForLayer(ms)");
valveDelayForPolygon = Preferences.loadGlobalDouble(prefName + "ValveDelayForPolygon(ms)");
extrusionReverseDelay = Preferences.loadGlobalDouble(prefName + "Reverse(ms)");
valveOverRun = Preferences.loadGlobalDouble(prefName + "ValveOverRun(mm)");
minLiftedZ = -1; //Preferences.loadGlobalDouble(prefName + "MinimumZClearance(mm)");
// NB - store as 2ms ticks to allow longer pulses
valvePulseTime = 0.5*Preferences.loadGlobalDouble(prefName + "ValvePulseTime(ms)");
shells = Preferences.loadGlobalInt(prefName + "NumberOfShells(0..N)");
pauseBetweenSegments = false; //Preferences.loadGlobalBool(prefName + "PauseBetweenSegments");
extrusionFoundationWidth = Preferences.loadGlobalDouble(prefName + "ExtrusionFoundationWidth(mm)");
extrusionLastFoundationWidth = Preferences.loadGlobalDouble(prefName + "ExtrusionLastFoundationWidth(mm)");
separationFraction = 0.8; //Preferences.loadGlobalDouble(prefName + "SeparationFraction(0..1)");
arcCompensationFactor = Preferences.loadGlobalDouble(prefName + "ArcCompensationFactor(0..)");
arcShortSides = Preferences.loadGlobalDouble(prefName + "ArcShortSides(0..)");
extrudeRatio = Preferences.loadGlobalDouble(prefName + "ExtrudeRatio(0..)");
lift = Preferences.loadGlobalDouble(prefName + "Lift(mm)");
evenHatchDirection = Preferences.loadGlobalDouble(prefName + "EvenHatchDirection(degrees)");
oddHatchDirection = Preferences.loadGlobalDouble(prefName + "OddHatchDirection(degrees)");
Color3f col = new Color3f((float)Preferences.loadGlobalDouble(prefName + "ColourR(0..1)"),
(float)Preferences.loadGlobalDouble(prefName + "ColourG(0..1)"),
(float)Preferences.loadGlobalDouble(prefName + "ColourB(0..1)"));
materialColour = new Appearance();
materialColour.setMaterial(new Material(col, black, col, black, 101f));
surfaceLayers = Preferences.loadGlobalInt(prefName + "SurfaceLayers(0..N)");
singleLine = Preferences.loadGlobalBool(prefName + "SingleLine");
feedDiameter = Preferences.loadGlobalDouble(prefName + "FeedDiameter(mm)");
} catch (Exception ex)
{
Debug.e("Refresh extruder preferences: " + ex.toString());
}
if(printer == null)
{
Debug.e("GenericExtruder(): printer is null!");
} else
{
fastXYFeedrate = Math.min(printer.getFastXYFeedrate(), fastXYFeedrate);
slowXYFeedrate = Math.min(printer.getSlowXYFeedrate(), slowXYFeedrate);
maxAcceleration = Math.min(printer.getMaxXYAcceleration(), maxAcceleration);
}
return result;
}
/* (non-Javadoc)
* @see org.reprap.Extruder#dispose()
*/
public void dispose() {
}
/**
* Wait while the motors move about
* @throws IOException
*/
public void waitTillNotBusy() throws IOException
{
if(printer == null)
return;
printer.waitTillNotBusy();
}
public void setPrinter(Printer p)
{
printer = p;
}
public Printer getPrinter()
{
return printer;
}
/**
* Start the extruder motor at a given speed. In the old scheme, this ranges from 0
* to 255 but is scaled by maxSpeed and t0, so that 255 corresponds to the
* highest permitted speed. It is also scaled so that 0 would correspond
* with the lowest extrusion speed.
*
* In the new scheme speed is simply mm/sec.
*
* @param speed The speed to drive the motor at (0-255)
* @throws IOException
* @throws Exception
*/
public void setExtrusion(double speed, boolean rev) throws IOException, Exception
{
if (speed > 0)
es.setExtruding(true);
else
es.setExtruding(false);
es.setSpeed(speed);
es.setReverse(rev);
}
public void setTemperature(double temperature, boolean wait) throws Exception
{
es.setTargetTemperature(temperature);
}
public void startExtruding()
{
if (!es.isExtruding())
{
try
{
setExtrusion(getExtruderSpeed(), false);
} catch (Exception e) {
//hmm.
}
es.setExtruding(true);
}
}
public void stopExtruding()
{
if (es.isExtruding())
{
try
{
setExtrusion(0, false);
} catch (Exception e) {
//hmm.
}
es.setExtruding(false);
}
}
public void setMotor(boolean motorOn) throws Exception
{
if(getExtruderSpeed() < 0)
return;
if(motorOn)
{
setExtrusion(getExtruderSpeed(), false);
es.setSpeed(getExtruderSpeed());
} else
{
setExtrusion(0, false);
es.setSpeed(0);
}
es.setReverse(false);
}
public void heatOn(boolean wait) throws Exception
{
setTemperature(extrusionTemp, wait);
}
public void heatOff() throws Exception
{
setTemperature(0, false);
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getTemperatureTarget()
*/
public double getTemperatureTarget() {
return es.targetTemperature();
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getDefaultTemperature()
*/
public double getDefaultTemperature() {
return extrusionTemp;
}
/**
* The the outline speed and the infill speed [0,1]
*/
public double getInfillSpeedFactor()
{
return iSpeed;
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getInfillFeedrate()
*/
public double getInfillFeedrate()
{
return getInfillSpeedFactor() * getFastXYFeedrate();
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getOutlineSpeedFactor()
*/
public double getOutlineSpeedFactor()
{
return oSpeed;
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getOutlineFeedrate()
*/
public double getOutlineFeedrate()
{
return getOutlineSpeedFactor() * getFastXYFeedrate();
}
/**
* The length in mm to speed up when going round corners
* (non-Javadoc)
* @see org.reprap.Extruder#getAngleSpeedUpLength()
*/
public double getAngleSpeedUpLength()
{
return asLength;
}
/**
* 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 (returning 1), and slowest when it
* continues straight (returning 1 - getAngleSpeedFactor()).
* (non-Javadoc)
* @see org.reprap.Extruder#getAngleSpeedFactor()
*/
public double getAngleSpeedFactor()
{
return asFactor;
}
public double getAngleFeedrate()
{
return getAngleSpeedFactor() * getFastXYFeedrate();
}
/* (non-Javadoc)
* @see org.reprap.Extruder#isAvailable()
*/
public boolean isAvailable()
{
return true;
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getXYSpeed()
*/
public double getFastXYFeedrate()
{
return fastXYFeedrate;
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getXYSpeed()
*/
public double getFastEFeedrate()
{
return fastEFeedrate;
}
/**
* @return slow XY movement feedrate in mm/minute
*/
public double getSlowXYFeedrate()
{
return slowXYFeedrate;
}
/**
* @return the fastest the machine can accelerate
*/
public double getMaxAcceleration()
{
return maxAcceleration;
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getExtruderSpeed()
*/
private double getRegularExtruderSpeed()
{
try
{
return Preferences.loadGlobalDouble(prefName + "ExtrusionSpeed(mm/minute)");
} catch (Exception e)
{
Debug.e(e.toString());
return 200; //Hack
}
}
private double getSeparationSpeed()
{
try
{
return 3000; //Preferences.loadGlobalDouble(prefName + "SeparationSpeed(mm/minute)");
} catch (Exception e)
{
Debug.e(e.toString());
return 200; //Hack
}
}
public void setSeparating(boolean s)
{
separating = s;
}
public double getExtruderSpeed()
{
if(separating)
return getSeparationSpeed();
else
return getRegularExtruderSpeed();
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getExtrusionSize()
*/
public double getExtrusionSize()
{
return extrusionSize;
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getExtrusionHeight()
*/
public double getExtrusionHeight()
{
return extrusionHeight;
}
/**
* At the top and bottom return the fine width; in between
* return the braod one. If the braod one is negative, just do fine.
*/
public double getExtrusionInfillWidth()
{
return extrusionInfillWidth;
}
public double getExtrusionBroadWidth()
{
return extrusionBroadWidth;
}
public int getLowerFineLayers()
{
return lowerFineLayers;
}
public int getUpperFineLayers()
{
return upperFineLayers;
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getCoolingPeriod()
*/
public double getCoolingPeriod()
{
return coolingPeriod;
}
// /* (non-Javadoc)
// * @see org.reprap.Extruder#getOffsetX()
// */
// public double getOffsetX()
// {
// return offsetX;
// }
//
// /* (non-Javadoc)
// * @see org.reprap.Extruder#getOffsetY()
// */
// public double getOffsetY()
// {
// return offsetY;
// }
//
// /* (non-Javadoc)
// * @see org.reprap.Extruder#getOffsetZ()
// */
// public double getOffsetZ()
// {
// return offsetZ;
// }
/* (non-Javadoc)
* @see org.reprap.Extruder#getColour()
*/
public Appearance getAppearance()
{
return materialColour;
}
/**
* @return the name of the material
* TODO: should this give more information?
*/
public String toString()
{
return material;
}
/**
* @return determine whether nozzle wipe method is enabled or not
*/
public boolean getNozzleWipeEnabled()
{
return nozzleWipeEnabled;
}
/**
* @return the X-cord for the nozzle wiper
*/
public double getNozzleWipeDatumX()
{
return nozzleWipeDatumX;
}
/**
* @return the Y-cord for the nozzle wiper
*/
public double getNozzleWipeDatumY()
{
return nozzleWipeDatumY;
}
/**
* @return the length of the nozzle movement over the wiper
*/
public double getNozzleWipeStrokeX()
{
return nozzleWipeStrokeX;
}
/**
* @return the length of the nozzle movement over the wiper
*/
public double getNozzleWipeStrokeY()
{
return nozzleWipeStrokeY;
}
/**
* @return the number of times the nozzle moves over the wiper
*/
public int getNozzleWipeFreq()
{
return nozzleWipeFreq;
}
/**
* @return the time to extrude before wiping the nozzle
*/
public double getNozzleClearTime()
{
return nozzleClearTime;
}
/**
* @return the time to wait after extruding before wiping the nozzle
*/
public double getNozzleWaitTime()
{
return nozzleWaitTime;
}
/**
* Start polygons at a random location round their perimiter
* @return
*/
public boolean randomStart()
{
return randSt;
}
/**
* Start polygons at an incremented location round their perimiter
* @return
*/
public boolean incrementedStart()
{
return incrementedSt;
}
/**
* get short lengths which need to be plotted faster
* set -ve to turn this off.
* @return
*/
public double getShortLength()
{
return shortLength;
}
/**
* Factor (between 0 and 1) to use to set the speed for
* short lines.
* @return
*/
public double getShortLineSpeedFactor()
{
return shortSpeed;
}
/**
* Feedrate for short lines in mm/minute
* @return
*/
public double getShortLineFeedrate()
{
return getShortLineSpeedFactor() * getFastXYFeedrate();
}
/**
* Number of mm to overlap the hatching infill with the outline. 0 gives none; -ve will
* leave a gap between the two
* @return
*/
public double getInfillOverlap()
{
return infillOverlap;
}
/**
* Gets the number of milliseconds to wait before starting a border track
* @return
*/
public double getExtrusionDelayForLayer()
{
return extrusionDelayForLayer;
}
/**
* Gets the number of milliseconds to wait before starting a hatch track
* @return
*/
public double getExtrusionDelayForPolygon()
{
return extrusionDelayForPolygon;
}
/**
* Gets the number of milliseconds to reverse the extrude motor
* at the end of a track
* @return
*/
public double getExtrusionReverseDelay()
{
return extrusionReverseDelay;
}
/**
* Gets the number of milliseconds to wait before opening the valve
* for the first track of a layer
* @return
*/
public double getValveDelayForLayer()
{
if(valvePulseTime < 0)
return 0;
return valveDelayForLayer;
}
/**
* Gets the number of milliseconds to wait before opening the valve
* for any other track
* @return
*/
public double getValveDelayForPolygon()
{
if(valvePulseTime < 0)
return 0;
return valveDelayForPolygon;
}
/* (non-Javadoc)
* @see org.reprap.Extruder#getExtrusionOverRun()
*/
public double getExtrusionOverRun()
{
return extrusionOverRun;
}
/**
* @return the valve overrun in millimeters (i.e. how many mm
* before the end of a track to turn off the extrude motor)
*/
public double getValveOverRun()
{
if(valvePulseTime < 0)
return 0;
return valveOverRun;
}
/**
* The smallest allowable free-movement height above the base
* @return
*/
public double getMinLiftedZ()
{
return minLiftedZ;
}
/**
* The number of times to go round the outline (0 to supress)
* @return
*/
public int getShells()
{
return shells;
}
/**
* Stop the extrude motor between segments?
* @return
*/
public boolean getPauseBetweenSegments()
{
return pauseBetweenSegments;
}
/**
* What stuff are we working with?
* @return
*/
public String getMaterial()
{
return material;
}
/**
* What stuff are we holding up with?
* @return
*/
public String getSupportMaterial()
{
return supportMaterial;
}
public int getSupportExtruderNumber()
{
return getNumberFromMaterial(supportMaterial);
}
public Extruder getSupportExtruder()
{
return org.reprap.Main.gui.getPrinter().getExtruder(supportMaterial);
}
/**
* What stuff are we infilling with?
* @return
*/
public String getInfillMaterial()
{
return inFillMaterial;
}
public int getInfillExtruderNumber()
{
return getNumberFromMaterial(inFillMaterial);
}
public Extruder getInfillExtruder()
{
return org.reprap.Main.gui.getPrinter().getExtruder(inFillMaterial);
}
/**
* What are the dimensions for infill?
* @return
*/
// public String getBroadInfillMaterial()
// {
// return inFillMaterial;
// }
public static int getNumberFromMaterial(String material)
{
if(material.equalsIgnoreCase("null"))
return -1;
String[] names;
try
{
names = Preferences.allMaterials();
for(int i = 0; i < names.length; i++)
{
if(names[i].equals(material))
return i;
}
throw new Exception("getNumberFromMaterial - can't find " + material);
} catch (Exception ex)
{
Debug.d(ex.toString());
}
return -1;
}
public static Appearance getAppearanceFromNumber(int n)
{
String prefName = "Extruder" + n + "_";
Color3f col = null;
try
{
col = new Color3f((float)Preferences.loadGlobalDouble(prefName + "ColourR(0..1)"),
(float)Preferences.loadGlobalDouble(prefName + "ColourG(0..1)"),
(float)Preferences.loadGlobalDouble(prefName + "ColourB(0..1)"));
} catch (Exception ex)
{
Debug.e(ex.toString());
}
Appearance a = new Appearance();
a.setMaterial(new Material(col, black, col, black, 101f));
return a;
}
public static Appearance getAppearanceFromMaterial(String material)
{
return(getAppearanceFromNumber(getNumberFromMaterial(material)));
}
public double getExtrusionFoundationWidth()
{
return extrusionFoundationWidth;
}
public double getLastFoundationWidth(LayerRules lc)
{
return extrusionLastFoundationWidth;
}
/**
* At the support layer before a layer is to be separated, how far up
* the normal Z movement do we go to make a bigger gap to form a weak join?
* @return
*/
public double getSeparationFraction()
{
return separationFraction;
}
/**
* The arc compensation factor.
* See org.reprap.geometry.polygons.RrPolygon.arcCompensate(...)
* @return
*/
public double getArcCompensationFactor()
{
return arcCompensationFactor;
}
/**
* The arc short sides.
* See org.reprap.geometry.polygons.RrPolygon.arcCompensate(...)
* @return
*/
public double getArcShortSides()
{
return arcShortSides;
}
/**
* The direction to hatch even-numbered layers in degrees anticlockwise
* from the X axis
* @return
*/
public double getEvenHatchDirection()
{
return evenHatchDirection;
}
/**
* The direction to hatch odd-numbered layers in degrees anticlockwise
* from the X axis
* @return
*/
public double getOddHatchDirection()
{
return oddHatchDirection;
}
/**
* Find out what our current speed is
* @return
*/
public double getCurrentSpeed()
{
return es.speed();
}
/**
* Find out if we are currently in reverse
* @return
*/
public boolean getReversing()
{
return es.reverse();
}
/**
* If we are working with feedstock lengths, compute that from the
* actual length we want to extrude from the nozzle, otherwise
* just return the extruded length.
* @param distance
* @return
*/
private double filamentDistance(double distance)
{
if(getFeedDiameter() < 0)
return distance;
return distance*getExtrusionHeight()*getExtrusionSize()/(getFeedDiameter()*getFeedDiameter()*Math.PI/4);
}
/**
* Get how much extrudate is deposited in a given time (in milliseconds)
* currentSpeed is in mm per minute. Valve extruders cannot know, so return 0.
* @param time (ms)
* @return
*/
public double getDistanceFromTime(double time)
{
if(!es.isExtruding() || valvePulseTime > 0)
return 0;
return filamentDistance(extrudeRatio*es.speed()*time/60000.0);
}
/**
* Get how much extrudate is deposited for a given xy movement
* currentSpeed is in mm per minute. Valve extruders cannot know, so return 0.
* @param xyDistance (mm)
* @param xyFeedrate (mm/minute)
* @return
*/
public double getDistance(double distance)
{
if(!es.isExtruding() || valvePulseTime > 0)
return 0;
return filamentDistance(extrudeRatio*distance);
}
/**
* Get the extrude ratio
* @return
*/
public double getExtrudeRatio()
{
return extrudeRatio;
}
/**
* Set the extrude ratio. Only to be used if you know what you
* are doing. It's a good idea to set it back when you've finished...
* @param er
*/
public void setExtrudeRatio(double er)
{
extrudeRatio = er;
}
/**
* Find out if we're working in 5D
* @return
*/
public boolean get5D()
{
return fiveD;
}
/**
* Find out how far we have extruded so far
* @return
*/
public ExtruderState getExtruderState()
{
return es;
}
/**
* Add some extruded length
* @param l
*/
public void addExtrudedLength(double l)
{
es.add(l);
}
/**
* Each logical extruder has a unique ID
* @return
*/
public int getID()
{
return myExtruderID;
}
/**
* Several logical extruders can share one physical extruder
* This number is unique to each physical extruder
* @return
*/
public int getPhysicalExtruderNumber()
{
return es.physicalExtruder();
}
/**
* Return the PWM for the motor. -ve values mean
* this feature is unavailable
*/
public double getPWM()
{
return extrusionPWM;
}
/**
* Time to purge the extruder
* -ve values supress
* @return
*/
public double getPurgeTime()
{
return purgeTime;
}
/**
* Purge the extruder
*/
public void purge(double liftZ) throws Exception
{
getPrinter().moveToPurge(liftZ);
try
{
//if(homeZ)
// getPrinter().homeToZeroZ();
//heatOn(true);
if(getPurgeTime() > 0)
{
setExtrusion(getFastXYFeedrate(), false);
getPrinter().machineWait(getPurgeTime(), false, true);
setExtrusion(0, false);
getPrinter().printEndReverse();
zeroExtrudedLength(true);
}
} catch (Exception e)
{}
}
/**
* If this is true, plot outlines from the middle of their infilling hatch to reduce dribble at
* their starts and ends. If false, plot the outline as the outline.
* @return
*/
public boolean getMiddleStart()
{
return middleStart;
}
public double getLift()
{
return lift;
}
/**
* This decides how many layers to fine-infill for areas that are upward-
* or downward-facing surfaces of the object.
* @return
*/
public int getSurfaceLayers()
{
return surfaceLayers;
}
/**
* Are the extruder's models ones that (may) include single-width vectors to be plotted?
* @return
*/
public boolean getSingleLine()
{
return singleLine;
}
/**
* The diameter of the input filament
* @return
*/
public double getFeedDiameter()
{
return feedDiameter;
}
}