commit
eab11f60ab
6 changed files with 126 additions and 71 deletions
|
|
@ -27,6 +27,7 @@ of the authors and should not be interpreted as representing official policies,
|
|||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MatterHackers.Agg.Image;
|
||||
|
|
@ -84,5 +85,14 @@ namespace MatterHackers.MatterControl
|
|||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static IEnumerable<GCodeStream> InternalStreams(this GCodeStream context)
|
||||
{
|
||||
while (context is GCodeStream gCodeStream)
|
||||
{
|
||||
context = gCodeStream.InternalStream;
|
||||
yield return context;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,10 +45,19 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
[DllImport("609_Boolean_bin.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int DeleteInt(ref IntPtr handle);
|
||||
|
||||
public static Mesh Do(Mesh inMeshA, Matrix4X4 matrixA,
|
||||
Mesh inMeshB, Matrix4X4 matrixB,
|
||||
int operation,
|
||||
IProgress<ProgressStatus> reporter, double amountPerOperation, double percentCompleted, ProgressStatus progressStatus, CancellationToken cancellationToken)
|
||||
public static Mesh Do(Mesh inMeshA,
|
||||
Matrix4X4 matrixA,
|
||||
// mesh B
|
||||
Mesh inMeshB,
|
||||
Matrix4X4 matrixB,
|
||||
// operation
|
||||
int operation,
|
||||
// reporting
|
||||
IProgress<ProgressStatus> reporter,
|
||||
double amountPerOperation,
|
||||
double percentCompleted,
|
||||
ProgressStatus progressStatus,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var libiglExe = "libigl_boolean.exe";
|
||||
if (File.Exists(libiglExe)
|
||||
|
|
@ -67,12 +76,22 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
vb = inMeshB.Vertices.ToDoubleArray(matrixB);
|
||||
fb = inMeshB.Faces.ToIntArray();
|
||||
|
||||
int vcCount;
|
||||
int fcCount;
|
||||
DoBooleanOperation(va, va.Length, fa, fa.Length,
|
||||
vb, vb.Length, fb, fb.Length,
|
||||
DoBooleanOperation(va,
|
||||
va.Length,
|
||||
fa,
|
||||
fa.Length,
|
||||
// object B
|
||||
vb,
|
||||
vb.Length,
|
||||
fb,
|
||||
fb.Length,
|
||||
// operation
|
||||
operation,
|
||||
out pVc, out vcCount, out pFc, out fcCount);
|
||||
// results
|
||||
out pVc,
|
||||
out int vcCount,
|
||||
out pFc,
|
||||
out int fcCount);
|
||||
|
||||
var vcArray = new double[vcCount];
|
||||
Marshal.Copy(pVc, vcArray, 0, vcCount);
|
||||
|
|
@ -88,6 +107,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
{
|
||||
DeleteDouble(ref pVc);
|
||||
}
|
||||
|
||||
if (pFc != IntPtr.Zero)
|
||||
{
|
||||
DeleteInt(ref pFc);
|
||||
|
|
@ -107,44 +127,53 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
switch (operation)
|
||||
{
|
||||
case 0:
|
||||
return PolygonMesh.Csg.CsgOperations.Union(meshA, meshB, (status, progress0To1) =>
|
||||
{
|
||||
// Abort if flagged
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return PolygonMesh.Csg.CsgOperations.Union(meshA,
|
||||
meshB,
|
||||
(status, progress0To1) =>
|
||||
{
|
||||
// Abort if flagged
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
progressStatus.Status = status;
|
||||
progressStatus.Progress0To1 = percentCompleted + (amountPerOperation * progress0To1);
|
||||
reporter?.Report(progressStatus);
|
||||
}, cancellationToken);
|
||||
progressStatus.Status = status;
|
||||
progressStatus.Progress0To1 = percentCompleted + (amountPerOperation * progress0To1);
|
||||
reporter?.Report(progressStatus);
|
||||
},
|
||||
cancellationToken);
|
||||
|
||||
case 1:
|
||||
return PolygonMesh.Csg.CsgOperations.Subtract(meshA, meshB, (status, progress0To1) =>
|
||||
{
|
||||
// Abort if flagged
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return PolygonMesh.Csg.CsgOperations.Subtract(meshA,
|
||||
meshB,
|
||||
(status, progress0To1) =>
|
||||
{
|
||||
// Abort if flagged
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
progressStatus.Status = status;
|
||||
progressStatus.Progress0To1 = percentCompleted + (amountPerOperation * progress0To1);
|
||||
reporter?.Report(progressStatus);
|
||||
}, cancellationToken);
|
||||
progressStatus.Status = status;
|
||||
progressStatus.Progress0To1 = percentCompleted + (amountPerOperation * progress0To1);
|
||||
reporter?.Report(progressStatus);
|
||||
},
|
||||
cancellationToken);
|
||||
|
||||
case 2:
|
||||
return PolygonMesh.Csg.CsgOperations.Intersect(meshA, meshB, (status, progress0To1) =>
|
||||
{
|
||||
// Abort if flagged
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return PolygonMesh.Csg.CsgOperations.Intersect(meshA,
|
||||
meshB,
|
||||
(status, progress0To1) =>
|
||||
{
|
||||
// Abort if flagged
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
progressStatus.Status = status;
|
||||
progressStatus.Progress0To1 = percentCompleted + (amountPerOperation * progress0To1);
|
||||
reporter.Report(progressStatus);
|
||||
}, cancellationToken);
|
||||
progressStatus.Status = status;
|
||||
progressStatus.Progress0To1 = percentCompleted + (amountPerOperation * progress0To1);
|
||||
reporter.Report(progressStatus);
|
||||
},
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[DllImport("609_Boolean_bin.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void DoBooleanOperation(
|
||||
public static extern void DoBooleanOperation(
|
||||
double[] va, int vaCount, int[] fa, int faCount,
|
||||
double[] vb, int vbCount, int[] fb, int fbCount,
|
||||
int opperation,
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
this.Children.Add(SourceContainer.Clone());
|
||||
SourceContainer.Visible = false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -197,8 +198,10 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
double amountPerOperation = 1.0 / totalOperations;
|
||||
double percentCompleted = 0;
|
||||
|
||||
ProgressStatus progressStatus = new ProgressStatus();
|
||||
progressStatus.Status = "Do CSG";
|
||||
var progressStatus = new ProgressStatus
|
||||
{
|
||||
Status = "Do CSG"
|
||||
};
|
||||
foreach (var keep in keepVisibleItems)
|
||||
{
|
||||
var resultsMesh = keep.Mesh;
|
||||
|
|
@ -206,9 +209,19 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
|
|||
|
||||
foreach (var remove in removeVisibleItems)
|
||||
{
|
||||
resultsMesh = BooleanProcessing.Do(resultsMesh, keepWorldMatrix,
|
||||
remove.Mesh, remove.WorldMatrix(SourceContainer),
|
||||
1, reporter, amountPerOperation, percentCompleted, progressStatus, cancellationToken);
|
||||
resultsMesh = BooleanProcessing.Do(resultsMesh,
|
||||
keepWorldMatrix,
|
||||
// other mesh
|
||||
remove.Mesh,
|
||||
remove.WorldMatrix(SourceContainer),
|
||||
// operation type
|
||||
1,
|
||||
// reporting
|
||||
reporter,
|
||||
amountPerOperation,
|
||||
percentCompleted,
|
||||
progressStatus,
|
||||
cancellationToken);
|
||||
|
||||
// after the first time we get a result the results mesh is in the right coordinate space
|
||||
keepWorldMatrix = Matrix4X4.Identity;
|
||||
|
|
|
|||
|
|
@ -40,15 +40,16 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
{
|
||||
private readonly string completedBeforeGCodeString = "; COMPLETED_BEFORE_GCODE";
|
||||
private int activeTool;
|
||||
private int extruderCount = 0;
|
||||
private readonly int extruderCount = 0;
|
||||
private PrinterMove lastDestination = PrinterMove.Unknown;
|
||||
private string postSwitchLine;
|
||||
private double preSwitchFeedRate;
|
||||
private Vector3 preSwitchPosition;
|
||||
private IGCodeLineReader gcodeLineReader;
|
||||
private GCodeMemoryFile gCodeMemoryFile;
|
||||
private QueuedCommandsStream queuedCommandsStream;
|
||||
private int requestedTool;
|
||||
private readonly IGCodeLineReader gcodeLineReader;
|
||||
private readonly GCodeMemoryFile gCodeMemoryFile;
|
||||
private readonly QueuedCommandsStream queuedCommandsStream;
|
||||
|
||||
public int RequestedTool { get; set; }
|
||||
|
||||
private enum SendStates
|
||||
{
|
||||
|
|
@ -58,8 +59,8 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
}
|
||||
|
||||
private SendStates sendState = SendStates.Normal;
|
||||
private double[] targetTemps = new double[4];
|
||||
private Queue<string> queuedCommands = new Queue<string>();
|
||||
private readonly double[] targetTemps = new double[4];
|
||||
private readonly Queue<string> queuedCommands = new Queue<string>();
|
||||
|
||||
public ToolChangeStream(PrinterConfig printer, GCodeStream internalStream, QueuedCommandsStream queuedCommandsStream, IGCodeLineReader gcodeLineReader)
|
||||
: base(printer, internalStream)
|
||||
|
|
@ -69,6 +70,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
{
|
||||
this.gCodeMemoryFile = gcodeLineReader.GCodeFile as GCodeMemoryFile;
|
||||
}
|
||||
|
||||
this.queuedCommandsStream = queuedCommandsStream;
|
||||
extruderCount = printer.Settings.GetValue<int>(SettingsKey.extruder_count);
|
||||
activeTool = printer.Connection.ActiveExtruderIndex;
|
||||
|
|
@ -103,7 +105,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
// get the temp we are setting
|
||||
GCodeFile.GetFirstNumberAfter("S", lineToSend, ref toolTemp);
|
||||
// set it to the tool we will be changing to
|
||||
requestedToolForTempChange = requestedTool;
|
||||
requestedToolForTempChange = RequestedTool;
|
||||
// check if this command contains a tool specification
|
||||
GCodeFile.GetFirstNumberAfter("T", lineToSend, ref requestedToolForTempChange);
|
||||
|
||||
|
|
@ -121,7 +123,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
|
||||
if (lineToSend == completedBeforeGCodeString)
|
||||
{
|
||||
activeTool = requestedTool;
|
||||
activeTool = RequestedTool;
|
||||
sendState = SendStates.Normal;
|
||||
QueueAfterGCode();
|
||||
}
|
||||
|
|
@ -139,12 +141,12 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
}
|
||||
|
||||
// if we are waiting to switch to the next tool
|
||||
else if (activeTool != requestedTool)
|
||||
else if (activeTool != RequestedTool)
|
||||
{
|
||||
// if this command does not include the extruder to switch to, than we need to switch before sending it
|
||||
if (!lineNoComment.Contains("T"))
|
||||
{
|
||||
queuedCommands.Enqueue($"T{requestedTool}");
|
||||
queuedCommands.Enqueue($"T{RequestedTool}");
|
||||
}
|
||||
|
||||
// For smoothie, switch back to the extrude we were using before the temp change (smoothie switches to the specified extruder, marlin repetier do not)
|
||||
|
|
@ -167,9 +169,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
// we have switch back to our starting tool without a move
|
||||
// change back to normal processing and don't change tools
|
||||
sendState = SendStates.Normal;
|
||||
var lastRequestedTool = requestedTool;
|
||||
var lastRequestedTool = RequestedTool;
|
||||
// set the requested tool
|
||||
requestedTool = changeCommandTool;
|
||||
RequestedTool = changeCommandTool;
|
||||
// don't send the change are we are on the right tool now
|
||||
return $"; switch back without move from T{lastRequestedTool} to T{activeTool}";
|
||||
}
|
||||
|
|
@ -180,9 +182,9 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
{
|
||||
sendState = SendStates.WaitingForMove;
|
||||
// set the requested tool
|
||||
requestedTool = changeCommandTool;
|
||||
RequestedTool = changeCommandTool;
|
||||
// don't queue the tool change until after the before gcode has been sent
|
||||
return $"; waiting for move on T{requestedTool}";
|
||||
return $"; waiting for move on T{RequestedTool}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -190,7 +192,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
|
||||
// if it is only an extrusion move
|
||||
if (sendState == SendStates.WaitingForMove
|
||||
&& activeTool != requestedTool // is different than the last extruder set
|
||||
&& activeTool != RequestedTool // is different than the last extruder set
|
||||
&& (lineNoComment.StartsWith("G0 ") || lineNoComment.StartsWith("G1 ")) // is a G1 or G0
|
||||
&& lineNoComment.Contains("E") // it is an extrusion move
|
||||
// and have no other position information
|
||||
|
|
@ -203,7 +205,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
if (GCodeFile.GetFirstNumberAfter("E", lineNoComment, ref ePosition))
|
||||
{
|
||||
// switch extruders
|
||||
queuedCommands.Enqueue($"T{requestedTool}");
|
||||
queuedCommands.Enqueue($"T{RequestedTool}");
|
||||
|
||||
// if we know the current E position before the switch
|
||||
// set the E value to the previous E value.
|
||||
|
|
@ -270,7 +272,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
// we do not switch tools again, turn off any that are not currently printing
|
||||
for (int i = 0; i < extruderCount; i++)
|
||||
{
|
||||
if (i != requestedTool
|
||||
if (i != RequestedTool
|
||||
&& i != activeTool)
|
||||
{
|
||||
gcode.AppendLine($"M104 T{i} S0");
|
||||
|
|
@ -310,16 +312,16 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
// check if any extruders need to start heating back up
|
||||
for (int i = 0; i < extruderCount; i++)
|
||||
{
|
||||
var nextToolChange = NextToolChange(i);
|
||||
var (toolIndex, time) = NextToolChange(i);
|
||||
var targetTemp = targetTemps[i];
|
||||
var setTempLine = $"M104 T{i} S{targetTemp}";
|
||||
if (nextToolChange.toolIndex >= 0
|
||||
&& nextToolChange.time < timeToReheat
|
||||
if (toolIndex >= 0
|
||||
&& time < timeToReheat
|
||||
&& printer.Connection.GetTargetHotendTemperature(i) != targetTemp
|
||||
&& line != setTempLine)
|
||||
{
|
||||
printer.Connection.SetTargetHotendTemperature(i, targetTemp);
|
||||
//queuedCommands.Enqueue(setTempLine);
|
||||
// queuedCommands.Enqueue(setTempLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -327,7 +329,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
private void QueueAfterGCode()
|
||||
{
|
||||
string afterGcodeToQueue = "";
|
||||
switch (requestedTool)
|
||||
switch (RequestedTool)
|
||||
{
|
||||
case 0:
|
||||
afterGcodeToQueue = printer.Settings.GetValue(SettingsKey.toolchange_gcode).Replace("\\n", "\n");
|
||||
|
|
@ -357,13 +359,13 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
var gcode = new StringBuilder();
|
||||
|
||||
// If the printer is heating, make sure we are at temp before switching extruders
|
||||
var nextToolTargetTemp = targetTemps[requestedTool];
|
||||
var currentPrinterTargeTemp = printer.Connection.GetTargetHotendTemperature(requestedTool);
|
||||
var nextToolTargetTemp = targetTemps[RequestedTool];
|
||||
var currentPrinterTargeTemp = printer.Connection.GetTargetHotendTemperature(RequestedTool);
|
||||
if (currentPrinterTargeTemp > 0
|
||||
&& printer.Connection.GetActualHotendTemperature(requestedTool) < nextToolTargetTemp - 3)
|
||||
&& printer.Connection.GetActualHotendTemperature(RequestedTool) < nextToolTargetTemp - 3)
|
||||
{
|
||||
// ensure our next tool is at temp (the one we are switching to)
|
||||
gcode.AppendLine($"M109 T{requestedTool} S{nextToolTargetTemp}");
|
||||
gcode.AppendLine($"M109 T{RequestedTool} S{nextToolTargetTemp}");
|
||||
}
|
||||
|
||||
if (afterGcodeToQueue.Trim().Length > 0)
|
||||
|
|
@ -400,14 +402,14 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
{
|
||||
// check if there is a travel
|
||||
if (sendState == SendStates.WaitingForMove
|
||||
&& activeTool != requestedTool // is different than the last extruder set
|
||||
&& activeTool != RequestedTool // is different than the last extruder set
|
||||
&& (lineNoComment.StartsWith("G0 ") || lineNoComment.StartsWith("G1 ")) // is a G1 or G0
|
||||
&& (lineNoComment.Contains("X") || lineNoComment.Contains("Y") || lineNoComment.Contains("Z"))) // has a move axis in it
|
||||
{
|
||||
postSwitchLine = lineIn;
|
||||
|
||||
string beforeGcodeToQueue = "";
|
||||
switch (requestedTool)
|
||||
switch (RequestedTool)
|
||||
{
|
||||
case 0:
|
||||
beforeGcodeToQueue = printer.Settings.GetValue(SettingsKey.before_toolchange_gcode).Replace("\\n", "\n");
|
||||
|
|
@ -433,7 +435,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io
|
|||
ManageCoolDownAndOffTemps(gcode);
|
||||
|
||||
// send the actual tool change
|
||||
gcode.AppendLine($"T{requestedTool}");
|
||||
gcode.AppendLine($"T{RequestedTool}");
|
||||
|
||||
// send the marker to let us know we have sent the before gcode
|
||||
gcode.AppendLine(completedBeforeGCodeString);
|
||||
|
|
|
|||
|
|
@ -1327,7 +1327,8 @@ You will then need to logout and log back in to the computer for the changes to
|
|||
if (moveAmountMm != 0)
|
||||
{
|
||||
// TODO: Long term we need to track the active extruder and make requiresToolChange be driven by the extruder you're actually on
|
||||
bool requiresToolChange = extruderNumber != ActiveExtruderIndex;
|
||||
bool requiresToolChange = extruderNumber != ActiveExtruderIndex
|
||||
|| TotalGCodeStream.InternalStreams().OfType<ToolChangeStream>().FirstOrDefault().RequestedTool != ActiveExtruderIndex;
|
||||
|
||||
SetMovementToRelative();
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit a52e2a218a7d3efb1546a2edfe1b37488d26100d
|
||||
Subproject commit 22750d5a2afc91c4eea323c364ef05200211560b
|
||||
Loading…
Add table
Add a link
Reference in a new issue