Add support for slicing persisted but in memory IObject3D items

- Issue MatterHackers/MCCentral#2785
Exception in AddObjectsForExtruder
This commit is contained in:
John Lewin 2018-02-09 18:11:55 -08:00
parent 56d5ccf241
commit 30cf0c0f60
9 changed files with 63 additions and 56 deletions

View file

@ -1308,8 +1308,13 @@ namespace MatterHackers.MatterControl
private string doNotAskAgainMessage = "Don't remind me again".Localize();
public async Task PrintPart(string partFilePath, string gcodeFilePath, string printItemName, PrinterConfig printer, IProgress<ProgressStatus> reporter, CancellationToken cancellationToken, bool overrideAllowGCode = false)
public async Task PrintPart(EditContext editContext, PrinterConfig printer, IProgress<ProgressStatus> reporter, CancellationToken cancellationToken, bool overrideAllowGCode = false)
{
var object3D = editContext.Content;
var partFilePath = editContext.SourceFilePath;
var gcodeFilePath = editContext.GCodeFilePath;
var printItemName = editContext.SourceItem.Name;
// Exit if called in a non-applicable state
if (this.ActivePrinter.Connection.CommunicationState != CommunicationStates.Connected
&& this.ActivePrinter.Connection.CommunicationState != CommunicationStates.FinishedPrint)
@ -1331,8 +1336,7 @@ namespace MatterHackers.MatterControl
}
}
if (!string.IsNullOrEmpty(partFilePath)
&& File.Exists(partFilePath))
//if (!string.IsNullOrEmpty(partFilePath) && File.Exists(partFilePath))
{
this.PrintingItemName = printItemName;
@ -1374,7 +1378,7 @@ namespace MatterHackers.MatterControl
if (messageBoxResponse)
{
this.ActivePrinter.Connection.CommunicationState = CommunicationStates.PreparingToPrint;
partToPrint_SliceDone(partFilePath, gcodeFilePath);
this.ArchiveAndStartPrint(partFilePath, gcodeFilePath);
}
},
"The file you are attempting to print is a GCode file.\n\nIt is recommended that you only print Gcode files known to match your printer's configuration.\n\nAre you sure you want to print this GCode file?".Localize(),
@ -1392,12 +1396,12 @@ namespace MatterHackers.MatterControl
{
this.ActivePrinter.Connection.CommunicationState = CommunicationStates.PreparingToPrint;
await ApplicationController.Instance.SliceFileLoadOutput(
await ApplicationController.Instance.SliceItemLoadOutput(
printer,
partFilePath,
printer.Bed.Scene,
gcodeFilePath);
partToPrint_SliceDone(partFilePath, gcodeFilePath);
this.ArchiveAndStartPrint(partFilePath, gcodeFilePath);
}
await ApplicationController.Instance.Tasks.Execute(
@ -1457,18 +1461,23 @@ namespace MatterHackers.MatterControl
}
}
private void partToPrint_SliceDone(string partFilePath, string gcodeFilePath)
/// <summary>
/// Archives MCX and validates GCode results before starting a print operation
/// </summary>
/// <param name="sourcePath">The source file which originally caused the slice->print operation</param>
/// <param name="gcodeFilePath">The resulting GCode to print</param>
private void ArchiveAndStartPrint(string sourcePath, string gcodeFilePath)
{
if (!string.IsNullOrEmpty(partFilePath)
&& File.Exists(partFilePath))
if (File.Exists(sourcePath)
&& File.Exists(gcodeFilePath))
{
if (gcodeFilePath != "")
//if (gcodeFilePath != "")
{
bool originalIsGCode = Path.GetExtension(partFilePath).ToUpper() == ".GCODE";
bool originalIsGCode = Path.GetExtension(sourcePath).ToUpper() == ".GCODE";
if (File.Exists(gcodeFilePath))
{
// Create archive point for printing attempt
if (Path.GetExtension(partFilePath).ToUpper() == ".MCX")
if (Path.GetExtension(sourcePath).ToUpper() == ".MCX")
{
// TODO: We should zip mcx and settings when starting a print
string platingDirectory = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, "PrintHistory");
@ -1480,13 +1489,12 @@ namespace MatterHackers.MatterControl
using (var file = File.OpenWrite(archivePath))
using (var zip = new ZipArchive(file, ZipArchiveMode.Create))
{
zip.CreateEntryFromFile(partFilePath, "PrinterPlate.mcx");
zip.CreateEntryFromFile(sourcePath, "PrinterPlate.mcx");
zip.CreateEntryFromFile(ActiveSliceSettings.Instance.DocumentPath, ActiveSliceSettings.Instance.GetValue(SettingsKey.printer_name) + ".printer");
zip.CreateEntryFromFile(gcodeFilePath, "sliced.gcode");
}
}
// read the last few k of the file and see if it says "filament used". We use this marker to tell if the file finished writing
if (originalIsGCode)
{
this.ActivePrinter.Connection.StartPrint(gcodeFilePath);
@ -1494,6 +1502,7 @@ namespace MatterHackers.MatterControl
}
else
{
// read the last few k of the file and see if it says "filament used". We use this marker to tell if the file finished writing
int bufferSize = 32000;
using (Stream fileStream = new FileStream(gcodeFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
@ -1517,7 +1526,7 @@ namespace MatterHackers.MatterControl
}
}
public async Task SliceFileLoadOutput(PrinterConfig printer, string partFilePath, string gcodeFilePath)
public async Task SliceItemLoadOutput(PrinterConfig printer, IObject3D object3D, string gcodeFilePath)
{
// Slice
bool slicingSucceeded = false;
@ -1526,8 +1535,8 @@ namespace MatterHackers.MatterControl
{
reporter.Report(new ProgressStatus() { Status = "Slicing".Localize() });
slicingSucceeded = await Slicer.SliceFile(
partFilePath,
slicingSucceeded = await Slicer.SliceItem(
object3D,
gcodeFilePath,
printer,
new SliceProgressReporter(reporter, printer),

View file

@ -186,11 +186,8 @@ namespace MatterHackers.MatterControl
this.Save();
// Slice and print
var context = this.EditContext;
await ApplicationController.Instance.PrintPart(
context.PartFilePath,
context.GCodeFilePath,
context.SourceItem.Name,
this.EditContext,
this.Printer,
null,
CancellationToken.None);
@ -527,7 +524,7 @@ namespace MatterHackers.MatterControl
public string GCodeFilePath => printItem?.GetGCodePathAndFileName();
public string PartFilePath => printItem?.FileLocation;
public string SourceFilePath => printItem?.FileLocation;
/// <summary>
/// Short term stop gap that should only be used until GCode path helpers, hash code and print recovery components can be extracted

View file

@ -129,12 +129,17 @@ namespace MatterHackers.MatterControl.Library.Export
// - If bedplate, save any pending changes before starting the print
await ApplicationController.Instance.Tasks.Execute(ApplicationController.Instance.ActiveView3DWidget.SaveChanges);
var context = ApplicationController.Instance.ActivePrinter.Bed.EditContext;
// Create a context to hold a temporary scene used during slicing to complete the export
var context = new EditContext()
{
ContentStore = ApplicationController.Instance.Library.PlatingHistory,
SourceItem = libraryContent
};
// - Slice
await ApplicationController.Instance.Tasks.Execute((reporter, cancellationToken) =>
{
return Slicer.SliceFile(context.PartFilePath, context.GCodeFilePath, printer, reporter, cancellationToken);
return Slicer.SliceItem(context.Content, context.GCodeFilePath, printer, reporter, cancellationToken);
});
// - Return

View file

@ -64,11 +64,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
UiThread.RunOnIdle(async () =>
{
var context = printer.Bed.EditContext;
await ApplicationController.Instance.PrintPart(
context.PartFilePath,
context.GCodeFilePath,
context.SourceItem.Name,
printer.Bed.EditContext,
printer,
null,
CancellationToken.None);

View file

@ -156,11 +156,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// Save any pending changes before starting print operation
await ApplicationController.Instance.Tasks.Execute(printerTabPage.view3DWidget.SaveChanges);
var context = printer.Bed.EditContext;
await ApplicationController.Instance.PrintPart(
context.PartFilePath,
context.GCodeFilePath,
context.SourceItem.Name,
printer.Bed.EditContext,
printer,
null,
CancellationToken.None);

View file

@ -64,7 +64,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public override async void OnClick(MouseEventArgs mouseEvent)
{
base.OnClick(mouseEvent);
await this.SliceFileTask();
await this.SliceBedplate();
}
public override void OnClosed(ClosedEventArgs e)
@ -90,7 +90,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
}
private async Task SliceFileTask()
private async Task SliceBedplate()
{
if (printer.Settings.PrinterSelected)
{
@ -111,9 +111,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
await ApplicationController.Instance.Tasks.Execute(printerTabPage.view3DWidget.SaveChanges);
await ApplicationController.Instance.SliceFileLoadOutput(
await ApplicationController.Instance.SliceItemLoadOutput(
printer,
printer.Bed.EditContext.PartFilePath,
printer.Bed.Scene,
printer.Bed.EditContext.GCodeFilePath);
}
catch (Exception ex)

View file

@ -559,7 +559,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
DialogWindow.Show(
new ExportPrintItemPage(new[]
{
new FileSystemFileItem(sceneContext.EditContext.PartFilePath)
new FileSystemFileItem(sceneContext.EditContext.SourceFilePath)
}));
});
},

View file

@ -53,7 +53,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public static List<bool> extrudersUsed = new List<bool>();
public static bool runInProcess = true;
public static List<(Matrix4X4 matrix, string fileName)> GetStlFileLocations(string fileToSlice, ref string mergeRules, PrinterConfig printer, IProgress<ProgressStatus> progressReporter, CancellationToken cancellationToken)
public static List<(Matrix4X4 matrix, string fileName)> GetStlFileLocations(IObject3D reloadedItem, ref string mergeRules, PrinterConfig printer, IProgress<ProgressStatus> progressReporter, CancellationToken cancellationToken)
{
var progressStatus = new ProgressStatus();
@ -85,21 +85,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
}
}
switch (Path.GetExtension(fileToSlice).ToUpper())
{
case ".MCX":
// TODO: Once graph parsing is added to MatterSlice we can remove and avoid this flattening
meshPrintOutputSettings.Clear();
progressStatus.Status = "Loading";
progressReporter.Report(progressStatus);
var reloadedItem = Object3D.Load(fileToSlice, cancellationToken, null, (ratio, status) =>
{
progressStatus.Progress0To1 = ratio;
progressStatus.Status = status;
});
// Flatten the scene, filtering out items outside of the build volume
var meshItemsOnBuildPlate = reloadedItem.VisibleMeshes().Where((item) => item.InsideBuildVolume(printer));
@ -153,10 +142,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
return outputOptions;
}
break;
default:
break;
}
return new List<(Matrix4X4 matrix, string fileName)>();
@ -209,12 +194,29 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
}
public static Task<bool> SliceFile(string sourceFile, string gcodeFilePath, PrinterConfig printer, IProgress<ProgressStatus> progressReporter, CancellationToken cancellationToken)
{
var progressStatus = new ProgressStatus()
{
Status = "Loading"
};
progressReporter.Report(progressStatus);
var loadedItem = Object3D.Load(sourceFile, cancellationToken, null, (ratio, status) =>
{
progressStatus.Progress0To1 = ratio;
progressStatus.Status = status;
});
return SliceItem(loadedItem, gcodeFilePath, printer, progressReporter, cancellationToken);
}
public static Task<bool> SliceItem(IObject3D object3D, string gcodeFilePath, PrinterConfig printer, IProgress<ProgressStatus> progressReporter, CancellationToken cancellationToken)
{
bool slicingSucceeded = true;
string mergeRules = "";
var stlFileLocations = GetStlFileLocations(sourceFile, ref mergeRules, printer, progressReporter, cancellationToken);
var stlFileLocations = GetStlFileLocations(object3D, ref mergeRules, printer, progressReporter, cancellationToken);
if(stlFileLocations.Count > 0)
{

@ -1 +1 @@
Subproject commit 8016bf08c887be9f149299ab13458b7a1da674f2
Subproject commit 475340af7062eb5ee3130d077230fdca434bd50e