public static bool T1OrGreaterUsed(PrinterConfig printer) { var scene = printer.Bed.Scene; var extrudersUsed = new List <bool>(); Slicer.GetExtrudersUsed(extrudersUsed, printer.PrintableItems(scene), printer.Settings, false); for (int i = 1; i < extrudersUsed.Count; i++) { if (extrudersUsed[i]) { return(true); } } return(false); }
public static GuiWidget CreateStartPrintButton(string buttonText, PrinterConfig printer, ThemeConfig theme, out bool printEnabled) { // Enable print option when no validation Errors exists var printingOrPause = printer.Connection.Printing || printer.Connection.Paused; var errors = printer.Validate(); printEnabled = !printingOrPause && !errors.Any(err => err.ErrorLevel == ValidationErrorLevel.Error); var startPrintButton = new TextButton(buttonText, theme) { Name = "Start Print Button", Enabled = printEnabled }; startPrintButton.Click += (s, e) => { // Exit if the bed is not GCode and the bed has no printable items if (!printer.Bed.EditContext.IsGGCodeSource && !printer.PrintableItems(printer.Bed.Scene).Any()) { return; } UiThread.RunOnIdle(async() => { // Save any pending changes before starting print operation await ApplicationController.Instance.Tasks.Execute("Saving Changes".Localize(), printer, printer.Bed.SaveChanges); await ApplicationController.Instance.PrintPart( printer.Bed.EditContext, printer, null, CancellationToken.None, true); }); }; return(startPrintButton); }
public static Task <bool> SliceItem(IObject3D object3D, string gcodeFilePath, PrinterConfig printer, IProgress <ProgressStatus> progressReporter, CancellationToken cancellationToken) { return(printer.Settings.Slicer.Slice(printer.PrintableItems(object3D), printer.Settings, gcodeFilePath, progressReporter, cancellationToken)); }
public PrintPopupMenu(PrinterConfig printer, ThemeConfig theme) : base(theme) { this.printer = printer; this.DrawArrow = true; this.BackgroundColor = theme.ToolbarButtonBackground; this.HoverColor = theme.ToolbarButtonHover; this.MouseDownColor = theme.ToolbarButtonDown; this.Name = "PrintPopupMenu"; this.HAnchor = HAnchor.Fit; this.VAnchor = VAnchor.Fit; settingsContext = new SettingsContext(printer, null, NamedSettingsLayers.All); this.PopupHAnchor = HAnchor.Fit; this.PopupVAnchor = VAnchor.Fit; this.MakeScrollable = false; this.DynamicPopupContent = () => { var menuTheme = ApplicationController.Instance.MenuTheme; int tabIndex = 0; allUiFields.Clear(); var printPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { Padding = theme.DefaultContainerPadding, BackgroundColor = menuTheme.BackgroundColor }; printPanel.AddChild(new TextWidget("Options".Localize(), textColor: menuTheme.TextColor, pointSize: theme.DefaultFontSize) { HAnchor = HAnchor.Left }); var optionsPanel = new IgnoredFlowLayout() { Name = "PrintPopupMenu Panel", HAnchor = HAnchor.Fit | HAnchor.Left, VAnchor = VAnchor.Fit, Padding = 5, MinimumSize = new Vector2(400, 65), }; printPanel.AddChild(optionsPanel); foreach (var key in new[] { SettingsKey.layer_height, SettingsKey.fill_density, SettingsKey.create_raft }) { var settingsData = PrinterSettings.SettingsData[key]; var row = SliceSettingsTabView.CreateItemRow(settingsData, settingsContext, printer, menuTheme, ref tabIndex, allUiFields); if (row is SliceSettingsRow settingsRow) { settingsRow.ArrowDirection = ArrowDirection.Left; } optionsPanel.AddChild(row); } var subPanel = new FlowLayoutWidget(FlowDirection.TopToBottom) { Margin = new BorderDouble(2, 0) }; bool anySettingOverridden = false; anySettingOverridden |= printer.Settings.GetValue <bool>(SettingsKey.spiral_vase); anySettingOverridden |= !string.IsNullOrWhiteSpace(printer.Settings.GetValue(SettingsKey.layer_to_pause)); var sectionWidget = new SectionWidget("Advanced".Localize(), subPanel, menuTheme, expanded: anySettingOverridden) { Name = "Advanced Section", HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Margin = 0 }; printPanel.AddChild(sectionWidget); foreach (var key in new[] { SettingsKey.spiral_vase, SettingsKey.layer_to_pause }) { var advancedRow = SliceSettingsTabView.CreateItemRow( PrinterSettings.SettingsData[key], settingsContext, printer, menuTheme, ref tabIndex, allUiFields); if (advancedRow is SliceSettingsRow settingsRow) { settingsRow.ArrowDirection = ArrowDirection.Left; } subPanel.AddChild(advancedRow); } menuTheme.ApplyBoxStyle(sectionWidget); sectionWidget.Margin = new BorderDouble(0, 10); sectionWidget.ContentPanel.Children <SettingsRow>().First().Border = new BorderDouble(0, 1); sectionWidget.ContentPanel.Children <SettingsRow>().Last().Border = 0; var printerReadyToTakeCommands = printer.Connection.CommunicationState == PrinterCommunication.CommunicationStates.FinishedPrint || printer.Connection.CommunicationState == PrinterCommunication.CommunicationStates.Connected; // add the start print button var setupRow = new FlowLayoutWidget() { HAnchor = HAnchor.Stretch }; // Perform validation before popup var errors = printer.Validate(); // Enable print option when no validation Errors exists var printEnabled = !errors.Any(err => err.ErrorLevel == ValidationErrorLevel.Error); var startPrintButton = new TextButton("Start Print".Localize(), menuTheme) { Name = "Start Print Button", Enabled = printEnabled }; startPrintButton.Click += (s, e) => { // Exit if the bed is not GCode and the bed has no printable items if (!printer.Bed.EditContext.IsGGCodeSource && !printer.PrintableItems(printer.Bed.Scene).Any()) { return; } UiThread.RunOnIdle(async() => { // Save any pending changes before starting print operation await ApplicationController.Instance.Tasks.Execute("Saving Changes".Localize(), printer, printer.Bed.SaveChanges); await ApplicationController.Instance.PrintPart( printer.Bed.EditContext, printer, null, CancellationToken.None); }); this.CloseMenu(); }; var hasErrors = errors.Any(e => e.ErrorLevel == ValidationErrorLevel.Error); var hasWarnings = errors.Any(e => e.ErrorLevel == ValidationErrorLevel.Warning && UserSettings.Instance.get($"Ignore_{e.ID}") != "true"); var hasErrorsOrWarnings = hasErrors || hasWarnings; if (hasErrorsOrWarnings) { string label = hasErrors ? "Action Required".Localize() : "Action Recommended".Localize(); setupRow.AddChild(new TextWidget(label, textColor: hasErrors ? Color.Red : theme.PrimaryAccentColor, pointSize: theme.DefaultFontSize) { VAnchor = VAnchor.Bottom, AutoExpandBoundsToText = true, }); } setupRow.AddChild(new HorizontalSpacer()); // Export button {{ bool isSailfish = printer.Settings.GetValue <bool>("enable_sailfish_communication"); var exportPlugins = PluginFinder.CreateInstancesOf <IExportPlugin>(); var targetPluginType = isSailfish ? typeof(X3GExport) : typeof(GCodeExport); // Find the first export plugin with the target type if (exportPlugins.FirstOrDefault(p => p.GetType() == targetPluginType) is IExportPlugin exportPlugin) { string exportType = isSailfish ? "Export X3G".Localize() : "Export G-Code".Localize(); exportPlugin.Initialize(printer); var exportGCodeButton = menuTheme.CreateDialogButton("Export".Localize()); exportGCodeButton.Name = "Export Gcode Button"; exportGCodeButton.Enabled = exportPlugin.Enabled; exportGCodeButton.ToolTipText = exportPlugin.Enabled ? exportType : exportPlugin.DisabledReason; exportGCodeButton.Click += (s, e) => { ExportPrintItemPage.DoExport( new[] { new InMemoryLibraryItem(printer.Bed.Scene) }, printer, exportPlugin); }; setupRow.AddChild(exportGCodeButton); } // Export button }} setupRow.AddChild(startPrintButton); printPanel.AddChild(setupRow); if (printEnabled) { theme.ApplyPrimaryActionStyle(startPrintButton); } else { startPrintButton.BackgroundColor = theme.MinimalShade; } if (hasErrorsOrWarnings) { var errorsPanel = new ValidationErrorsPanel(errors, menuTheme); // Conditional layout for right or bottom errors panel alignment var layoutStyle = FlowDirection.TopToBottom; if (layoutStyle == FlowDirection.LeftToRight) { errorsPanel.HAnchor = HAnchor.Absolute; errorsPanel.VAnchor = VAnchor.Fit | VAnchor.Top; errorsPanel.BackgroundColor = theme.ResolveColor(menuTheme.BackgroundColor, theme.PrimaryAccentColor.WithAlpha(30)); errorsPanel.Width = 350; errorsPanel.Load += (s, e) => { errorsPanel.Parent.BackgroundColor = Color.Transparent; }; } else { errorsPanel.HAnchor = HAnchor.Stretch; errorsPanel.VAnchor = VAnchor.Fit; errorsPanel.Margin = 3; } // Instead of the typical case where the print panel is returned, wrap and append validation errors panel var errorsContainer = new FlowLayoutWidget(layoutStyle) { HAnchor = HAnchor.Fit, VAnchor = VAnchor.Fit, BackgroundColor = layoutStyle == FlowDirection.TopToBottom ? printPanel.BackgroundColor : Color.Transparent }; // Clear bottom padding printPanel.Padding = printPanel.Padding.Clone(bottom: 2); errorsContainer.AddChild(printPanel); errorsContainer.AddChild(errorsPanel); return(errorsContainer); } return(printPanel); }; this.AddChild(new TextButton("Print".Localize(), theme) { Selectable = false, Padding = theme.TextButtonPadding.Clone(right: 5) }); // Register listeners printer.Settings.SettingChanged += Printer_SettingChanged; }
public static List <(Matrix4X4 matrix, string fileName)> GetStlFileLocations(IObject3D object3D, ref string mergeRules, PrinterConfig printer, IProgress <ProgressStatus> progressReporter, CancellationToken cancellationToken) { var progressStatus = new ProgressStatus(); extrudersUsed.Clear(); int extruderCount = printer.Settings.GetValue <int>(SettingsKey.extruder_count); for (int extruderIndex = 0; extruderIndex < extruderCount; extruderIndex++) { extrudersUsed.Add(false); } // If we have support enabled and are using an extruder other than 0 for it if (printer.Settings.GetValue <bool>("support_material")) { if (printer.Settings.GetValue <int>("support_material_extruder") != 0) { int supportExtruder = Math.Max(0, Math.Min(printer.Settings.GetValue <int>(SettingsKey.extruder_count) - 1, printer.Settings.GetValue <int>("support_material_extruder") - 1)); extrudersUsed[supportExtruder] = true; } } // If we have raft enabled and are using an extruder other than 0 for it if (printer.Settings.GetValue <bool>("create_raft")) { if (printer.Settings.GetValue <int>("raft_extruder") != 0) { int raftExtruder = Math.Max(0, Math.Min(printer.Settings.GetValue <int>(SettingsKey.extruder_count) - 1, printer.Settings.GetValue <int>("raft_extruder") - 1)); extrudersUsed[raftExtruder] = true; } } { // TODO: Once graph parsing is added to MatterSlice we can remove and avoid this flattening meshPrintOutputSettings.Clear(); // Flatten the scene, filtering out items outside of the build volume var meshItemsOnBuildPlate = printer.PrintableItems(object3D); if (meshItemsOnBuildPlate.Any()) { int maxExtruderIndex = 0; var itemsByExtruder = new List <IEnumerable <IObject3D> >(); for (int extruderIndexIn = 0; extruderIndexIn < extruderCount; extruderIndexIn++) { var extruderIndex = extruderIndexIn; var itemsThisExtruder = meshItemsOnBuildPlate.Where((item) => (File.Exists(item.MeshPath) || // Drop missing files File.Exists(Path.Combine(Object3D.AssetsPath, item.MeshPath))) && (item.WorldMaterialIndex() == extruderIndex || (extruderIndex == 0 && (item.WorldMaterialIndex() >= extruderCount || item.WorldMaterialIndex() == -1))) && (item.WorldOutputType() == PrintOutputTypes.Solid || item.WorldOutputType() == PrintOutputTypes.Default)); itemsByExtruder.Add(itemsThisExtruder); extrudersUsed[extruderIndex] |= itemsThisExtruder.Any(); if (extrudersUsed[extruderIndex]) { maxExtruderIndex = extruderIndex; } } var outputOptions = new List <(Matrix4X4 matrix, string fileName)>(); int savedStlCount = 0; bool first = true; for (int extruderIndex = 0; extruderIndex < itemsByExtruder.Count; extruderIndex++) { if (!first) { mergeRules += ","; first = false; } mergeRules += AddObjectsForExtruder(itemsByExtruder[extruderIndex], outputOptions, ref savedStlCount); } var supportObjects = meshItemsOnBuildPlate.Where((item) => item.WorldOutputType() == PrintOutputTypes.Support); // if we added user generated support if (supportObjects.Any()) { // add a flag to the merge rules to let us know there was support mergeRules += "," + AddObjectsForExtruder(supportObjects, outputOptions, ref savedStlCount) + "S"; } mergeRules += " "; return(outputOptions); } } return(new List <(Matrix4X4 matrix, string fileName)>()); }
public PrintPopupMenu(PrinterConfig printer, ThemeConfig theme) : base(theme) { this.printer = printer; this.DrawArrow = true; this.BackgroundColor = theme.ToolbarButtonBackground; this.HoverColor = theme.ToolbarButtonHover; this.MouseDownColor = theme.ToolbarButtonDown; this.Name = "PrintPopupMenu"; this.HAnchor = HAnchor.Fit; this.VAnchor = VAnchor.Fit; settingsContext = new SettingsContext(printer, null, NamedSettingsLayers.All); this.DynamicPopupContent = () => { var menuTheme = ApplicationController.Instance.MenuTheme; int tabIndex = 0; allUiFields.Clear(); var column = new FlowLayoutWidget(FlowDirection.TopToBottom) { Padding = 10, BackgroundColor = menuTheme.Colors.PrimaryBackgroundColor }; column.AddChild(new TextWidget("Options".Localize(), textColor: menuTheme.Colors.PrimaryTextColor) { HAnchor = HAnchor.Left }); var optionsPanel = new IgnoredFlowLayout() { Name = "PrintPopupMenu Panel", HAnchor = HAnchor.Fit | HAnchor.Left, VAnchor = VAnchor.Fit, Padding = 5, MinimumSize = new Vector2(400, 65), Margin = new BorderDouble(top: 10), }; column.AddChild(optionsPanel); foreach (var key in new[] { "layer_height", "fill_density", "support_material", "create_raft" }) { var settingsData = SettingsOrganizer.Instance.GetSettingsData(key); var row = SliceSettingsTabView.CreateItemRow(settingsData, settingsContext, printer, menuTheme, ref tabIndex, allUiFields); SliceSettingsRow.AddBordersToEditFields(row); optionsPanel.AddChild(row); } var subPanel = new FlowLayoutWidget(FlowDirection.TopToBottom); var sectionWidget = new SectionWidget("Advanced", subPanel, menuTheme, expanded: true) { Name = "Advanced Section", HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Margin = 0 }; column.AddChild(sectionWidget); bool anySettingOverridden = false; anySettingOverridden |= printer.Settings.GetValue <bool>(SettingsKey.spiral_vase); anySettingOverridden |= !string.IsNullOrWhiteSpace(printer.Settings.GetValue(SettingsKey.layer_to_pause)); sectionWidget.Load += (s, e) => { sectionWidget.Checkbox.Checked = anySettingOverridden; }; foreach (var key in new[] { SettingsKey.spiral_vase, SettingsKey.layer_to_pause }) { var settingsData = SettingsOrganizer.Instance.GetSettingsData(key); var row = SliceSettingsTabView.CreateItemRow(settingsData, settingsContext, printer, menuTheme, ref tabIndex, allUiFields); SliceSettingsRow.AddBordersToEditFields(row); subPanel.AddChild(row); } theme.ApplyBoxStyle(sectionWidget); sectionWidget.Margin = new BorderDouble(0, 10); sectionWidget.ContentPanel.Children <SettingsRow>().First().Border = new BorderDouble(0, 1); sectionWidget.ContentPanel.Children <SettingsRow>().Last().Border = 0; var button = new TextButton("Start Print".Localize(), menuTheme) { Name = "Start Print Button", HAnchor = HAnchor.Right, VAnchor = VAnchor.Absolute, }; button.Click += (s, e) => { // Exit if the bed is not GCode and the bed has no printable items if ((printer.Bed.EditContext.SourceItem as ILibraryAsset)?.ContentType != "gcode" && !printer.PrintableItems(printer.Bed.EditContext.Content).Any()) { return; } UiThread.RunOnIdle(async() => { // Save any pending changes before starting print operation await ApplicationController.Instance.Tasks.Execute("Saving Changes".Localize(), printer.Bed.SaveChanges); await ApplicationController.Instance.PrintPart( printer.Bed.EditContext, printer, null, CancellationToken.None); }); }; column.AddChild(button); theme.ApplyPrimaryActionStyle(button); return(column); }; this.AddChild(new TextButton("Print".Localize(), theme) { Selectable = false, Padding = theme.TextButtonPadding.Clone(right: 5) }); PrinterSettings.SettingChanged.RegisterEvent((s, e) => { if (e is StringEventArgs stringEvent) { string settingsKey = stringEvent.Data; if (allUiFields.TryGetValue(settingsKey, out UIField uifield)) { string currentValue = settingsContext.GetValue(settingsKey); if (uifield.Value != currentValue || settingsKey == "com_port") { uifield.SetValue( currentValue, userInitiated: false); } } } }, ref unregisterEvents); }