diff --git a/MatterControl.Printing/Settings/SettingsKey.cs b/MatterControl.Printing/Settings/SettingsKey.cs index 4c10af4b8..03d95e52d 100644 --- a/MatterControl.Printing/Settings/SettingsKey.cs +++ b/MatterControl.Printing/Settings/SettingsKey.cs @@ -31,17 +31,13 @@ namespace MatterHackers.MatterControl.SlicerConfiguration { public static class SettingsKey { - public const string active_quality_key = nameof(active_quality_key); public const string active_material_key = nameof(active_material_key); + public const string active_quality_key = nameof(active_quality_key); + public const string air_gap_speed = nameof(air_gap_speed); public const string auto_connect = nameof(auto_connect); public const string auto_release_motors = nameof(auto_release_motors); - /// - /// The baby step offset for extruder index 0 - /// + public const string avoid_crossing_perimeters = nameof(avoid_crossing_perimeters); public const string baby_step_z_offset = nameof(baby_step_z_offset); - /// - /// The baby step offset for extruder index 1 - /// public const string baby_step_z_offset_1 = nameof(baby_step_z_offset_1); public const string backup_firmware_before_update = nameof(backup_firmware_before_update); public const string baud_rate = nameof(baud_rate); @@ -49,16 +45,34 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string bed_shape = nameof(bed_shape); public const string bed_size = nameof(bed_size); public const string bed_temperature = nameof(bed_temperature); + public const string before_toolchange_gcode = nameof(before_toolchange_gcode); + public const string before_toolchange_gcode_1 = nameof(before_toolchange_gcode_1); + public const string bottom_infill_speed = nameof(bottom_infill_speed); + public const string bottom_solid_layers = nameof(bottom_solid_layers); + public const string bridge_fan_speed = nameof(bridge_fan_speed); + public const string bridge_over_infill = nameof(bridge_over_infill); + public const string bridge_speed = nameof(bridge_speed); + public const string brims = nameof(brims); public const string build_height = nameof(build_height); public const string calibration_files = nameof(calibration_files); public const string cancel_gcode = nameof(cancel_gcode); + public const string coast_at_end_distance = nameof(coast_at_end_distance); public const string com_port = nameof(com_port); + public const string complete_objects = nameof(complete_objects); public const string connect_gcode = nameof(connect_gcode); + public const string cool_extruder_lift = nameof(cool_extruder_lift); + public const string cooling = nameof(cooling); + public const string create_brim = nameof(create_brim); + public const string create_raft = nameof(create_raft); + public const string create_skirt = nameof(create_skirt); public const string created_date = nameof(created_date); public const string default_material_presets = nameof(default_material_presets); public const string device_token = nameof(device_token); public const string device_type = nameof(device_type); + public const string disable_fan_first_layers = nameof(disable_fan_first_layers); + public const string driver_type = nameof(driver_type); public const string emulate_endstops = nameof(emulate_endstops); + public const string enable_fan = nameof(enable_fan); public const string enable_line_splitting = nameof(enable_line_splitting); public const string enable_network_printing = nameof(enable_network_printing); public const string enable_retractions = nameof(enable_retractions); @@ -66,21 +80,33 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string end_gcode = nameof(end_gcode); public const string expand_thin_walls = nameof(expand_thin_walls); public const string external_perimeter_extrusion_width = nameof(external_perimeter_extrusion_width); + public const string external_perimeter_speed = nameof(external_perimeter_speed); + public const string external_perimeters_first = nameof(external_perimeters_first); public const string extruder_count = nameof(extruder_count); public const string extruder_offset = nameof(extruder_offset); + public const string extruder_wipe_temperature = nameof(extruder_wipe_temperature); public const string extruders_share_temperature = nameof(extruders_share_temperature); + public const string extrusion_multiplier = nameof(extrusion_multiplier); public const string extrusion_ratio = nameof(extrusion_ratio); public const string feedrate_ratio = nameof(feedrate_ratio); + public const string filament_1_has_been_loaded = nameof(filament_1_has_been_loaded); public const string filament_cost = nameof(filament_cost); public const string filament_density = nameof(filament_density); public const string filament_diameter = nameof(filament_diameter); + public const string filament_has_been_loaded = nameof(filament_has_been_loaded); public const string filament_runout_sensor = nameof(filament_runout_sensor); + public const string fill_angle = nameof(fill_angle); public const string fill_density = nameof(fill_density); + public const string fill_pattern = nameof(fill_pattern); public const string fill_thin_gaps = nameof(fill_thin_gaps); + public const string first_layer_bed_temperature = nameof(first_layer_bed_temperature); public const string first_layer_extrusion_width = nameof(first_layer_extrusion_width); public const string first_layer_height = nameof(first_layer_height); public const string first_layer_speed = nameof(first_layer_speed); + public const string first_layer_temperature = nameof(first_layer_temperature); public const string g0 = nameof(g0); + public const string gcode_flavor = nameof(gcode_flavor); + public const string gcode_output_type = nameof(gcode_output_type); public const string has_fan = nameof(has_fan); public const string has_hardware_leveling = nameof(has_hardware_leveling); public const string has_heated_bed = nameof(has_heated_bed); @@ -92,73 +118,138 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string inactive_cool_down = nameof(inactive_cool_down); public const string include_firmware_updater = nameof(include_firmware_updater); public const string infill_overlap_perimeter = nameof(infill_overlap_perimeter); + public const string infill_speed = nameof(infill_speed); public const string infill_type = nameof(infill_type); - public const string insert_filament_markdown2 = nameof(insert_filament_markdown2); public const string insert_filament_1_markdown = nameof(insert_filament_1_markdown); + public const string insert_filament_markdown2 = nameof(insert_filament_markdown2); + public const string interface_layer_speed = nameof(interface_layer_speed); public const string ip_address = nameof(ip_address); public const string ip_port = nameof(ip_port); public const string jerk_velocity = nameof(jerk_velocity); - public const string print_time_estimate_multiplier = nameof(print_time_estimate_multiplier); public const string laser_speed_025 = nameof(laser_speed_025); public const string laser_speed_100 = nameof(laser_speed_100); public const string layer_gcode = nameof(layer_gcode); public const string layer_height = nameof(layer_height); public const string layer_name = nameof(layer_name); public const string layer_to_pause = nameof(layer_to_pause); + public const string leveling_sample_points = nameof(leveling_sample_points); public const string load_filament_length = nameof(load_filament_length); + public const string load_filament_speed = nameof(load_filament_speed); public const string make = nameof(make); public const string manual_movement_speeds = nameof(manual_movement_speeds); public const string max_acceleration = nameof(max_acceleration); + public const string max_fan_speed = nameof(max_fan_speed); + public const string max_fan_speed_layer_time = nameof(max_fan_speed_layer_time); public const string max_velocity = nameof(max_velocity); public const string merge_overlapping_lines = nameof(merge_overlapping_lines); + public const string min_extrusion_before_retract = nameof(min_extrusion_before_retract); public const string min_fan_speed = nameof(min_fan_speed); - public const string max_fan_speed = nameof(max_fan_speed); + public const string min_fan_speed_layer_time = nameof(min_fan_speed_layer_time); + public const string min_print_speed = nameof(min_print_speed); + public const string min_skirt_length = nameof(min_skirt_length); public const string model = nameof(model); public const string nozzle_diameter = nameof(nozzle_diameter); public const string number_of_first_layers = nameof(number_of_first_layers); public const string oem_profile_token = nameof(oem_profile_token); + public const string output_only_first_layer = nameof(output_only_first_layer); public const string pause_gcode = nameof(pause_gcode); + public const string perimeter_extrusion_width = nameof(perimeter_extrusion_width); + public const string perimeter_speed = nameof(perimeter_speed); public const string perimeter_start_end_overlap = nameof(perimeter_start_end_overlap); + public const string perimeters = nameof(perimeters); public const string print_center = nameof(print_center); public const string print_leveling_data = nameof(print_leveling_data); public const string print_leveling_enabled = nameof(print_leveling_enabled); public const string print_leveling_probe_start = nameof(print_leveling_probe_start); - public const string probe_has_been_calibrated = nameof(probe_has_been_calibrated); public const string print_leveling_required_to_print = nameof(print_leveling_required_to_print); public const string print_leveling_solution = nameof(print_leveling_solution); - public const string leveling_sample_points = nameof(leveling_sample_points); - public const string load_filament_speed = nameof(load_filament_speed); - public const string probe_offset_sample_point = nameof(probe_offset_sample_point); + public const string print_time_estimate_multiplier = nameof(print_time_estimate_multiplier); public const string printer_name = nameof(printer_name); + public const string probe_has_been_calibrated = nameof(probe_has_been_calibrated); + public const string probe_offset_sample_point = nameof(probe_offset_sample_point); public const string progress_reporting = nameof(progress_reporting); public const string publish_bed_image = nameof(publish_bed_image); + public const string raft_air_gap = nameof(raft_air_gap); + public const string raft_extra_distance_around_part = nameof(raft_extra_distance_around_part); + public const string raft_extruder = nameof(raft_extruder); + public const string raft_layers = nameof(raft_layers); + public const string raft_print_speed = nameof(raft_print_speed); + public const string randomize_start = nameof(randomize_start); public const string read_regex = nameof(read_regex); public const string recover_first_layer_speed = nameof(recover_first_layer_speed); public const string recover_is_enabled = nameof(recover_is_enabled); public const string recover_position_before_z_home = nameof(recover_position_before_z_home); + public const string repair_outlines_extensive_stitching = nameof(repair_outlines_extensive_stitching); + public const string repair_outlines_keep_open = nameof(repair_outlines_keep_open); + public const string reset_long_extrusion = nameof(reset_long_extrusion); + public const string resolution = nameof(resolution); public const string resume_gcode = nameof(resume_gcode); - public const string running_clean_markdown2 = nameof(running_clean_markdown2); + public const string retract_before_travel = nameof(retract_before_travel); + public const string retract_length = nameof(retract_length); + public const string retract_length_tool_change = nameof(retract_length_tool_change); + public const string retract_lift = nameof(retract_lift); + public const string retract_restart_extra = nameof(retract_restart_extra); + public const string retract_restart_extra_time_to_apply = nameof(retract_restart_extra_time_to_apply); + public const string retract_restart_extra_toolchange = nameof(retract_restart_extra_toolchange); + public const string retract_speed = nameof(retract_speed); + public const string retract_when_changing_islands = nameof(retract_when_changing_islands); public const string running_clean_1_markdown = nameof(running_clean_1_markdown); + public const string running_clean_markdown2 = nameof(running_clean_markdown2); public const string seconds_to_reheat = nameof(seconds_to_reheat); public const string selector_ip_address = nameof(selector_ip_address); public const string send_with_checksum = nameof(send_with_checksum); - public const string filament_has_been_loaded = nameof(filament_has_been_loaded); - public const string filament_1_has_been_loaded = nameof(filament_1_has_been_loaded); public const string show_reset_connection = nameof(show_reset_connection); + public const string skirt_distance = nameof(skirt_distance); + public const string skirt_height = nameof(skirt_height); + public const string skirts = nameof(skirts); public const string sla_printer = nameof(sla_printer); + public const string slowdown_below_layer_time = nameof(slowdown_below_layer_time); + public const string small_perimeter_speed = nameof(small_perimeter_speed); + public const string solid_fill_pattern = nameof(solid_fill_pattern); + public const string solid_infill_extrusion_width = nameof(solid_infill_extrusion_width); + public const string solid_infill_speed = nameof(solid_infill_speed); + public const string solid_shell = nameof(solid_shell); public const string spiral_vase = nameof(spiral_vase); + public const string standby_temperature_delta = nameof(standby_temperature_delta); public const string start_gcode = nameof(start_gcode); + public const string start_perimeters_at_concave_points = nameof(start_perimeters_at_concave_points); + public const string start_perimeters_at_non_overhang = nameof(start_perimeters_at_non_overhang); + public const string support_air_gap = nameof(support_air_gap); + public const string support_material_create_perimeter = nameof(support_material_create_perimeter); + public const string support_material_extruder = nameof(support_material_extruder); + public const string support_material_infill_angle = nameof(support_material_infill_angle); + public const string support_material_interface_extruder = nameof(support_material_interface_extruder); + public const string support_material_interface_layers = nameof(support_material_interface_layers); + public const string support_material_percent = nameof(support_material_percent); + public const string support_material_spacing = nameof(support_material_spacing); + public const string support_material_speed = nameof(support_material_speed); + public const string support_material_xy_distance = nameof(support_material_xy_distance); + public const string support_type = nameof(support_type); public const string temperature = nameof(temperature); public const string temperature1 = nameof(temperature1); public const string temperature2 = nameof(temperature2); public const string temperature3 = nameof(temperature3); + public const string thin_walls = nameof(thin_walls); + public const string threads = nameof(threads); + public const string toolchange_gcode = nameof(toolchange_gcode); + public const string toolchange_gcode_1 = nameof(toolchange_gcode_1); + public const string top_infill_extrusion_width = nameof(top_infill_extrusion_width); public const string top_solid_infill_speed = nameof(top_solid_infill_speed); + public const string top_solid_layers = nameof(top_solid_layers); + public const string travel_speed = nameof(travel_speed); public const string trim_filament_markdown = nameof(trim_filament_markdown); public const string unload_filament_length = nameof(unload_filament_length); + public const string unload_filament_time = nameof(unload_filament_time); + public const string use_firmware_retraction = nameof(use_firmware_retraction); + public const string use_relative_e_distances = nameof(use_relative_e_distances); public const string use_z_probe = nameof(use_z_probe); public const string validate_layer_height = nameof(validate_layer_height); + public const string vibration_limit = nameof(vibration_limit); public const string windows_driver = nameof(windows_driver); + public const string wipe_shield_distance = nameof(wipe_shield_distance); + public const string wipe_tower_size = nameof(wipe_tower_size); public const string write_regex = nameof(write_regex); + public const string xy_offsets_have_been_calibrated = nameof(xy_offsets_have_been_calibrated); public const string z_homes_to_max = nameof(z_homes_to_max); public const string z_offset = nameof(z_offset); public const string z_probe_samples = nameof(z_probe_samples); @@ -166,101 +257,5 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string z_probe_z_offset = nameof(z_probe_z_offset); public const string z_servo_depolyed_angle = nameof(z_servo_depolyed_angle); public const string z_servo_retracted_angle = nameof(z_servo_retracted_angle); - public const string small_perimeter_speed = nameof(small_perimeter_speed); - public const string bridge_speed = nameof(bridge_speed); - public const string air_gap_speed = nameof(air_gap_speed); - public const string external_perimeter_speed = nameof(external_perimeter_speed); - public const string infill_speed = nameof(infill_speed); - public const string perimeter_speed = nameof(perimeter_speed); - public const string solid_infill_speed = nameof(solid_infill_speed); - public const string support_material_speed = nameof(support_material_speed); - public const string interface_layer_speed = nameof(interface_layer_speed); - public const string travel_speed = nameof(travel_speed); - public const string retract_speed = nameof(retract_speed); - public const string create_raft = nameof(create_raft); - public const string bottom_solid_layers = nameof(bottom_solid_layers); - public const string perimeters = nameof(perimeters); - public const string raft_extra_distance_around_part = nameof(raft_extra_distance_around_part); - public const string support_material_interface_layers = nameof(support_material_interface_layers); - public const string top_solid_layers = nameof(top_solid_layers); - public const string raft_print_speed = nameof(raft_print_speed); - public const string before_toolchange_gcode = nameof(before_toolchange_gcode); - public const string toolchange_gcode = nameof(toolchange_gcode); - public const string before_toolchange_gcode_1 = nameof(before_toolchange_gcode_1); - public const string toolchange_gcode_1 = nameof(toolchange_gcode_1); - public const string retract_before_travel = nameof(retract_before_travel); - public const string retract_length = nameof(retract_length); - public const string retract_lift = nameof(retract_lift); - public const string retract_restart_extra = nameof(retract_restart_extra); - public const string retract_restart_extra_time_to_apply = nameof(retract_restart_extra_time_to_apply); - public const string bottom_infill_speed = nameof(bottom_infill_speed); - public const string bridge_over_infill = nameof(bridge_over_infill); - public const string extrusion_multiplier = nameof(extrusion_multiplier); - public const string fill_angle = nameof(fill_angle); - public const string min_extrusion_before_retract = nameof(min_extrusion_before_retract); - public const string min_print_speed = nameof(min_print_speed); - public const string raft_air_gap = nameof(raft_air_gap); - public const string avoid_crossing_perimeters = nameof(avoid_crossing_perimeters); - public const string unload_filament_time = nameof(unload_filament_time); - public const string complete_objects = nameof(complete_objects); - public const string cool_extruder_lift = nameof(cool_extruder_lift); - public const string cooling = nameof(cooling); - public const string enable_fan = nameof(enable_fan); - public const string min_fan_speed_layer_time = nameof(min_fan_speed_layer_time); - public const string max_fan_speed_layer_time = nameof(max_fan_speed_layer_time); - public const string bridge_fan_speed = nameof(bridge_fan_speed); - public const string disable_fan_first_layers = nameof(disable_fan_first_layers); - public const string external_perimeters_first = nameof(external_perimeters_first); - public const string fill_pattern = nameof(fill_pattern); - public const string first_layer_temperature = nameof(first_layer_temperature); - public const string gcode_flavor = nameof(gcode_flavor); - public const string gcode_output_type = nameof(gcode_output_type); - public const string solid_shell = nameof(solid_shell); - public const string min_skirt_length = nameof(min_skirt_length); - public const string output_only_first_layer = nameof(output_only_first_layer); - public const string perimeter_extrusion_width = nameof(perimeter_extrusion_width); - public const string raft_layers = nameof(raft_layers); - public const string randomize_start = nameof(randomize_start); - public const string coast_at_end_distance = nameof(coast_at_end_distance); - public const string retract_length_tool_change = nameof(retract_length_tool_change); - public const string retract_when_changing_islands = nameof(retract_when_changing_islands); - public const string retract_restart_extra_toolchange = nameof(retract_restart_extra_toolchange); - public const string reset_long_extrusion = nameof(reset_long_extrusion); - public const string repair_outlines_extensive_stitching = nameof(repair_outlines_extensive_stitching); - public const string repair_outlines_keep_open = nameof(repair_outlines_keep_open); - public const string resolution = nameof(resolution); - public const string skirt_distance = nameof(skirt_distance); - public const string skirt_height = nameof(skirt_height); - public const string skirts = nameof(skirts); - public const string brims = nameof(brims); - public const string slowdown_below_layer_time = nameof(slowdown_below_layer_time); - public const string solid_fill_pattern = nameof(solid_fill_pattern); - public const string solid_infill_extrusion_width = nameof(solid_infill_extrusion_width); - public const string standby_temperature_delta = nameof(standby_temperature_delta); - public const string start_perimeters_at_concave_points = nameof(start_perimeters_at_concave_points); - public const string start_perimeters_at_non_overhang = nameof(start_perimeters_at_non_overhang); - public const string support_air_gap = nameof(support_air_gap); - public const string support_material_percent = nameof(support_material_percent); - public const string support_material_infill_angle = nameof(support_material_infill_angle); - public const string support_material_create_perimeter = nameof(support_material_create_perimeter); - public const string support_material_extruder = nameof(support_material_extruder); - public const string raft_extruder = nameof(raft_extruder); - public const string support_material_interface_extruder = nameof(support_material_interface_extruder); - public const string support_material_spacing = nameof(support_material_spacing); - public const string support_material_xy_distance = nameof(support_material_xy_distance); - public const string support_type = nameof(support_type); - public const string extruder_wipe_temperature = nameof(extruder_wipe_temperature); - public const string thin_walls = nameof(thin_walls); - public const string threads = nameof(threads); - public const string top_infill_extrusion_width = nameof(top_infill_extrusion_width); - public const string use_firmware_retraction = nameof(use_firmware_retraction); - public const string use_relative_e_distances = nameof(use_relative_e_distances); - public const string vibration_limit = nameof(vibration_limit); - public const string wipe_shield_distance = nameof(wipe_shield_distance); - public const string wipe_tower_size = nameof(wipe_tower_size); - public const string driver_type = nameof(driver_type); - public const string create_brim = nameof(create_brim); - public const string create_skirt = nameof(create_skirt); - public const string first_layer_bed_temperature = nameof(first_layer_bed_temperature); } } diff --git a/MatterControl.Printing/Settings/SliceSettingsFields.cs b/MatterControl.Printing/Settings/SliceSettingsFields.cs index 21093379f..950a43b49 100644 --- a/MatterControl.Printing/Settings/SliceSettingsFields.cs +++ b/MatterControl.Printing/Settings/SliceSettingsFields.cs @@ -905,6 +905,16 @@ namespace MatterHackers.MatterControl.SlicerConfiguration RebuildGCodeOnChange = false }, new SliceSettingData() + { + SlicerConfigName = SettingsKey.xy_offsets_have_been_calibrated, + PresentationName = "X Y Nozzle Offsets Have Been Calibrated".Localize(), + HelpText = "Flag keeping track if xy calibration wizard has been run.".Localize(), + DataEditType = DataEditTypes.CHECK_BOX, + ShowIfSet = "!has_hardware_leveling", + DefaultValue = "0", + RebuildGCodeOnChange = false + }, + new SliceSettingData() { SlicerConfigName = SettingsKey.filament_has_been_loaded, PresentationName = "Filament Has Been Loaded".Localize(), diff --git a/MatterControlLib/ApplicationView/PrinterConfig.cs b/MatterControlLib/ApplicationView/PrinterConfig.cs index 86bc05dbc..eff3225ce 100644 --- a/MatterControlLib/ApplicationView/PrinterConfig.cs +++ b/MatterControlLib/ApplicationView/PrinterConfig.cs @@ -87,6 +87,7 @@ namespace MatterHackers.MatterControl this.Connection.ErrorReported += ApplicationController.Instance.Connection_ErrorReported; this.Connection.ConnectionSucceeded += Connection_ConnectionSucceeded; this.Connection.CommunicationStateChanged += Connection_CommunicationStateChanged; + this.Connection.DetailedPrintingStateChanged += Connection_CommunicationStateChanged; this.Connection.PrintFinished += Connection_PrintFinished; // Initialize bed settings @@ -480,6 +481,7 @@ namespace MatterHackers.MatterControl // Unregister listeners this.Settings.SettingChanged -= Printer_SettingChanged; this.Connection.CommunicationStateChanged -= Connection_CommunicationStateChanged; + this.Connection.DetailedPrintingStateChanged -= Connection_CommunicationStateChanged; this.Connection.ConnectionSucceeded -= Connection_ConnectionSucceeded; this.Connection.PrintFinished -= Connection_PrintFinished; this.Connection.TemporarilyHoldingTemp -= ApplicationController.Instance.Connection_TemporarilyHoldingTemp; diff --git a/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/XyCalibrationWizard.cs b/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/XyCalibrationWizard.cs index fd47b797b..dfc7b071c 100644 --- a/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/XyCalibrationWizard.cs +++ b/MatterControlLib/ConfigurationPage/PrintLeveling/SetupWizards/XyCalibrationWizard.cs @@ -38,9 +38,16 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling { public class XyCalibrationWizard : PrinterSetupWizard { - public XyCalibrationWizard(PrinterConfig printer) + private int extruderToCalibrateIndex; + XyCalibrationData xyCalibrationData; + private bool startPrint; + + public XyCalibrationWizard(PrinterConfig printer, int extruderToCalibrateIndex, XyCalibrationData xyCalibrationData = null, bool startPrint = false) : base(printer) { + this.extruderToCalibrateIndex = extruderToCalibrateIndex; + this.xyCalibrationData = xyCalibrationData; + this.startPrint = startPrint; this.WindowTitle = $"{ApplicationController.Instance.ProductName} - " + "Nozzle Calibration Wizard".Localize(); this.WindowSize = new Vector2(600 * GuiWidget.DeviceScale, 700 * GuiWidget.DeviceScale); @@ -51,7 +58,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling public static bool NeedsToBeRun(PrinterConfig printer) { // we have a probe that we are using and we have not done leveling yet - return UsingZProbe(printer) && !printer.Settings.GetValue(SettingsKey.probe_has_been_calibrated); + return UsingZProbe(printer) && !printer.Settings.GetValue(SettingsKey.xy_offsets_have_been_calibrated); } public override void Dispose() @@ -70,17 +77,40 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling private IEnumerator GetPages() { - var xyCalibrationData = new XyCalibrationData(); + if (xyCalibrationData == null) + { + xyCalibrationData = new XyCalibrationData(extruderToCalibrateIndex); - yield return new XyCalibrationSelectPage(this, printer, xyCalibrationData); - - yield return new XyCalibrationStartPrintPage(this, printer, xyCalibrationData); + yield return new XyCalibrationSelectPage(this, printer, xyCalibrationData); + yield return new XyCalibrationStartPrintPage(this, printer, xyCalibrationData); + } + else if(startPrint) + { + yield return new XyCalibrationStartPrintPage(this, printer, xyCalibrationData); + } + else // we are returing to the wizard and need to collect the data + { + yield return new XyCalibrationCollectDataPage(this, printer, xyCalibrationData); + yield return new XyCalibrationDataRecieved(this, printer, xyCalibrationData); + } } } public class XyCalibrationData { + public XyCalibrationData(int extruderToCalibrateIndex) + { + this.ExtruderToCalibrateIndex = extruderToCalibrateIndex; + } + + public int ExtruderToCalibrateIndex { get; private set; } public enum QualityType { Coarse, Normal, Fine } public QualityType Quality { get; set; } = QualityType.Normal; + /// + /// The index of the calibration print that was picked + /// + public int XPick { get; set; } = -1; + public int YPick { get; set; } = -1; + public double Offset { get; set; } = .1; } } \ No newline at end of file diff --git a/MatterControlLib/ConfigurationPage/PrintLeveling/WizardPages/HomePrinterPage.cs b/MatterControlLib/ConfigurationPage/PrintLeveling/WizardPages/HomePrinterPage.cs index b4ed0e02f..484e63670 100644 --- a/MatterControlLib/ConfigurationPage/PrintLeveling/WizardPages/HomePrinterPage.cs +++ b/MatterControlLib/ConfigurationPage/PrintLeveling/WizardPages/HomePrinterPage.cs @@ -47,14 +47,14 @@ namespace MatterHackers.MatterControl.ConfigurationPage.PrintLeveling public override void OnClosed(EventArgs e) { // Unregister listeners - printer.Connection.CommunicationStateChanged -= CheckHomeFinished; + printer.Connection.DetailedPrintingStateChanged -= CheckHomeFinished; base.OnClosed(e); } public override void OnLoad(EventArgs args) { - printer.Connection.CommunicationStateChanged += CheckHomeFinished; + printer.Connection.DetailedPrintingStateChanged += CheckHomeFinished; printer.Connection.HomeAxis(PrinterConnection.Axis.XYZ); diff --git a/MatterControlLib/CustomWidgets/NozzleOffsetCalibrationResultsPage.cs b/MatterControlLib/CustomWidgets/NozzleOffsetCalibrationResultsPage.cs index 70bf78a9b..14fcaf9a4 100644 --- a/MatterControlLib/CustomWidgets/NozzleOffsetCalibrationResultsPage.cs +++ b/MatterControlLib/CustomWidgets/NozzleOffsetCalibrationResultsPage.cs @@ -46,7 +46,7 @@ namespace MatterHackers.MatterControl this.CreateTextField("Congratulations, your nozzle offsets have been collected and are ready to be saved. Click next to save and finish the wizard".Localize()); - var row = new SettingsRow( + var row = new SettingsRow( "X Offset".Localize(), null, theme, @@ -71,6 +71,26 @@ namespace MatterHackers.MatterControl VAnchor = VAnchor.Center, Margin = new BorderDouble(right: 10) }); + + this.NextButton.Visible = false; + + var nextButton = theme.CreateDialogButton("Finish".Localize()); + nextButton.Name = "FinishCalibration"; + nextButton.Click += (s, e) => + { + // TODO: removed fixed index + var hotendOffset = printer.Settings.Helpers.ExtruderOffset(1); + hotendOffset.X += xOffset; + hotendOffset.Y += yOffset; + + printer.Settings.Helpers.SetExtruderOffset(1, hotendOffset); + + this.DialogWindow.CloseOnIdle(); + }; + + theme.ApplyPrimaryActionStyle(nextButton); + + this.AddPageAction(nextButton); } } } diff --git a/MatterControlLib/CustomWidgets/XyCalibrationCollectDataPage.cs b/MatterControlLib/CustomWidgets/XyCalibrationCollectDataPage.cs new file mode 100644 index 000000000..9f0995485 --- /dev/null +++ b/MatterControlLib/CustomWidgets/XyCalibrationCollectDataPage.cs @@ -0,0 +1,166 @@ +/* +Copyright (c) 2019, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System; +using System.Collections.Generic; +using MatterHackers.Agg.UI; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling; + +namespace MatterHackers.MatterControl +{ + public class XyCalibrationCollectDataPage : WizardPage + { + private List xButtons; + private XyCalibrationData xyCalibrationData; + private List yButtons; + private bool HaveWrittenData = false; + + public XyCalibrationCollectDataPage(ISetupWizard setupWizard, PrinterConfig printer, XyCalibrationData xyCalibrationData) + : base(setupWizard) + { + this.xyCalibrationData = xyCalibrationData; + this.WindowTitle = "Nozzle Offset Calibration Wizard".Localize(); + this.HeaderText = "Nozzle Offset Calibration".Localize() + ":"; + this.Name = "Nozzle Offset Calibration Wizard"; + + contentRow.Padding = theme.DefaultContainerPadding; + + contentRow.AddChild(new TextWidget("Choose the calibration you would like to perform.".Localize(), textColor: theme.TextColor, pointSize: theme.DefaultFontSize) + { + Margin = new Agg.BorderDouble(0, 15, 0, 0) + }); + + // disable the next button until we recieve data about both the x and y axis alignment + NextButton.Enabled = false; + + var xButtonsGroup = new FlowLayoutWidget(FlowDirection.TopToBottom) + { + HAnchor = HAnchor.Fit | HAnchor.Left + }; + contentRow.AddChild(xButtonsGroup); + xButtons = new List(); + xButtons.Add(new RadioButton("-2".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize)); + xButtons.Add(new RadioButton("-1".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize)); + xButtons.Add(new RadioButton(" 0".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize)); + xButtons.Add(new RadioButton("+1".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize)); + xButtons.Add(new RadioButton("+2".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize)); + foreach (var button in xButtons) + { + xButtonsGroup.AddChild(button); + button.CheckedStateChanged += XButton_CheckedStateChanged; + } + + var yButtonsGroup = new FlowLayoutWidget() + { + HAnchor = HAnchor.Fit | HAnchor.Left + }; + contentRow.AddChild(yButtonsGroup); + yButtonsGroup.AddChild(new GuiWidget(24 * GuiWidget.DeviceScale, 16)); + yButtons = new List(); + yButtons.Add(new RadioButton("-2".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize)); + yButtons.Add(new RadioButton("-1".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize)); + yButtons.Add(new RadioButton(" 0".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize)); + yButtons.Add(new RadioButton("+1".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize)); + yButtons.Add(new RadioButton("+2".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize)); + foreach (var button in yButtons) + { + var column = new FlowLayoutWidget(FlowDirection.TopToBottom); + yButtonsGroup.AddChild(column); + + button.HAnchor = HAnchor.Center; + column.AddChild(button); + column.AddChild(new TextWidget(button.Text, textColor: theme.TextColor, pointSize: theme.DefaultFontSize) + { + HAnchor = HAnchor.Left + }); + button.Text = ""; + + button.CheckedStateChanged += YButton_CheckedStateChanged; + } + } + + public override void OnClosed(EventArgs e) + { + // save the offsets to the extruder + if (!HaveWrittenData + && xyCalibrationData.XPick != -1 + && xyCalibrationData.YPick != -1) + { + var hotendOffset = printer.Settings.Helpers.ExtruderOffset(xyCalibrationData.ExtruderToCalibrateIndex); + hotendOffset.X -= xyCalibrationData.Offset * -2 + xyCalibrationData.Offset * xyCalibrationData.XPick; + hotendOffset.Y -= xyCalibrationData.Offset * -2 + xyCalibrationData.Offset * xyCalibrationData.YPick; + + printer.Settings.Helpers.SetExtruderOffset(xyCalibrationData.ExtruderToCalibrateIndex, hotendOffset); + HaveWrittenData = true; + } + + base.OnClosed(e); + } + + private void CheckIfCanAdvance() + { + if (xyCalibrationData.YPick != -1 + && xyCalibrationData.XPick != -1) + { + NextButton.Enabled = true; + } + } + + private void XButton_CheckedStateChanged(object sender, System.EventArgs e) + { + int i = 0; + foreach (var button in xButtons) + { + if (button == sender) + { + xyCalibrationData.XPick = i; + break; + } + i++; + } + CheckIfCanAdvance(); + } + + private void YButton_CheckedStateChanged(object sender, System.EventArgs e) + { + int i = 0; + foreach (var button in yButtons) + { + if (button == sender) + { + xyCalibrationData.YPick = i; + break; + } + i++; + } + CheckIfCanAdvance(); + } + } +} \ No newline at end of file diff --git a/MatterControlLib/CustomWidgets/XyCalibrationDataRecieved.cs b/MatterControlLib/CustomWidgets/XyCalibrationDataRecieved.cs new file mode 100644 index 000000000..ab3299eeb --- /dev/null +++ b/MatterControlLib/CustomWidgets/XyCalibrationDataRecieved.cs @@ -0,0 +1,140 @@ +/* +Copyright (c) 2019, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using MatterHackers.Agg.UI; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling; + +namespace MatterHackers.MatterControl +{ + public class XyCalibrationDataRecieved : WizardPage + { + public XyCalibrationDataRecieved(ISetupWizard setupWizard, PrinterConfig printer, XyCalibrationData xyCalibrationData) + : base(setupWizard) + { + this.WindowTitle = "Nozzle Offset Calibration Wizard".Localize(); + this.HeaderText = "Nozzle Offset Calibration".Localize() + ":"; + this.Name = "Nozzle Offset Calibration Wizard"; + + contentRow.Padding = theme.DefaultContainerPadding; + + var doneCalibratingButton = theme.CreateDialogButton("Done".Localize()); + bool printAgain = false; + + // check if we picked an outside of the calibration + if (xyCalibrationData.XPick == 0 + || xyCalibrationData.XPick == 4 + || xyCalibrationData.YPick == 0 + || xyCalibrationData.YPick == 4) + { + // offer to re-run the calibration with the same settings as last time + contentRow.AddChild(new TextWidget("Your printer has been ajusted but we need to run callibration again to improve accuracy.".Localize(), textColor: theme.TextColor, pointSize: theme.DefaultFontSize) + { + Margin = new Agg.BorderDouble(0, 15, 0, 0) + }); + doneCalibratingButton = theme.CreateDialogButton("Print Again".Localize()); + printAgain = true; + } + else + { + switch (xyCalibrationData.Quality) + { + case XyCalibrationData.QualityType.Coarse: + // if we are on coarse calibration offer to move down to normal + contentRow.AddChild(new TextWidget("Coarse calibration complete, we will now do a fine calibration to improve accuracy.".Localize(), textColor: theme.TextColor, pointSize: theme.DefaultFontSize) + { + Margin = new Agg.BorderDouble(0, 15, 0, 0) + }); + doneCalibratingButton = theme.CreateDialogButton("Print Next".Localize()); + // switch to normal calibration + xyCalibrationData.Quality = XyCalibrationData.QualityType.Normal; + printAgain = true; + break; + + case XyCalibrationData.QualityType.Normal: + // let the user know they are done with calibration, but if they would like they can print a fine calibration for even better results + // add a button to request fine calibration + var normalMessage = "Your nozzles should now be calibrated.".Localize(); + normalMessage += "\n\n" + "You can continue to ultra fine calibration, but for most uses this is not necessary.".Localize(); + contentRow.AddChild(new TextWidget(normalMessage, textColor: theme.TextColor, pointSize: theme.DefaultFontSize) + { + Margin = new Agg.BorderDouble(0, 15, 0, 0) + }); + var startFineCalibratingButton = theme.CreateDialogButton("Print Ultra Fine Calibration".Localize()); + startFineCalibratingButton.HAnchor = HAnchor.Fit | HAnchor.Right; + startFineCalibratingButton.VAnchor = VAnchor.Absolute; + startFineCalibratingButton.Name = "Fine Calibration Print"; + startFineCalibratingButton.Click += (s, e) => + { + // close this dialog + this.DialogWindow.CloseOnIdle(); + UiThread.RunOnIdle(() => + { + // switch to fine + xyCalibrationData.Quality = XyCalibrationData.QualityType.Fine; + // start up at the print window + DialogWindow.Show(new XyCalibrationWizard(printer, xyCalibrationData.ExtruderToCalibrateIndex, xyCalibrationData, true)); + }); + }; + contentRow.AddChild(startFineCalibratingButton); + break; + + case XyCalibrationData.QualityType.Fine: + // done! + contentRow.AddChild(new TextWidget("Offset Calibration complete.".Localize(), textColor: theme.TextColor, pointSize: theme.DefaultFontSize) + { + Margin = new Agg.BorderDouble(0, 15, 0, 0) + }); + break; + } + } + + // this is the last page of the wizard hide the next button + this.NextButton.Visible = false; + + doneCalibratingButton.Name = "Done Calibration Print"; + doneCalibratingButton.Click += (s, e) => + { + // close this window + this.DialogWindow.CloseOnIdle(); + if (printAgain) + { + UiThread.RunOnIdle(() => + { + DialogWindow.Show(new XyCalibrationWizard(printer, xyCalibrationData.ExtruderToCalibrateIndex, xyCalibrationData, true)); + }); + } + }; + + theme.ApplyPrimaryActionStyle(doneCalibratingButton); + + this.AddPageAction(doneCalibratingButton); + } + } +} diff --git a/MatterControlLib/CustomWidgets/XyCalibrationSelectPage.cs b/MatterControlLib/CustomWidgets/XyCalibrationSelectPage.cs index df6a19ead..ccab3abc8 100644 --- a/MatterControlLib/CustomWidgets/XyCalibrationSelectPage.cs +++ b/MatterControlLib/CustomWidgets/XyCalibrationSelectPage.cs @@ -27,14 +27,10 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ -using System; +using System.Collections.Generic; using MatterHackers.Agg.UI; -using MatterHackers.DataConverters3D; using MatterHackers.Localizations; using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling; -using MatterHackers.MatterControl.DesignTools; -using MatterHackers.MatterControl.SlicerConfiguration; -using MatterHackers.VectorMath; namespace MatterHackers.MatterControl { @@ -62,93 +58,29 @@ namespace MatterHackers.MatterControl { Checked = xyCalibrationData.Quality == XyCalibrationData.QualityType.Coarse }); - coarseCalibration.CheckedStateChanged += (s, e) => xyCalibrationData.Quality = XyCalibrationData.QualityType.Coarse; + coarseCalibration.CheckedStateChanged += (s, e) => + { + xyCalibrationData.Quality = XyCalibrationData.QualityType.Coarse; + xyCalibrationData.Offset = .5; + }; contentRow.AddChild(normalCalibration = new RadioButton("Normal Calibration: Start here".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize) { Checked = xyCalibrationData.Quality == XyCalibrationData.QualityType.Normal }); - normalCalibration.CheckedStateChanged += (s, e) => xyCalibrationData.Quality = XyCalibrationData.QualityType.Normal; + normalCalibration.CheckedStateChanged += (s, e) => + { + xyCalibrationData.Quality = XyCalibrationData.QualityType.Normal; + xyCalibrationData.Offset = .1; + }; contentRow.AddChild(fineCalibration = new RadioButton("Fine Calibration: When you want that extra precision".Localize(), textColor: theme.TextColor, fontSize: theme.DefaultFontSize) { Checked = xyCalibrationData.Quality == XyCalibrationData.QualityType.Fine }); - fineCalibration.CheckedStateChanged += (s, e) => xyCalibrationData.Quality = XyCalibrationData.QualityType.Fine; - } - } - - public class XyCalibrationStartPrintPage : WizardPage - { - public XyCalibrationStartPrintPage(ISetupWizard setupWizard, PrinterConfig printer, XyCalibrationData xyCalibrationData) - : base(setupWizard) - { - this.WindowTitle = "Nozzle Offset Calibration Wizard".Localize(); - this.HeaderText = "Nozzle Offset Calibration".Localize(); - this.Name = "Nozzle Offset Calibration Wizard"; - - var content = "Here is what we are going to do:".Localize(); - content += "\n\n • " + "Stash your current bed".Localize(); - content += "\n • " + "Print the calibration object".Localize(); - content += "\n • " + "Collect data".Localize(); - content += "\n • " + "Restore your current bed, after all calibration is complete".Localize(); - - contentRow.AddChild(this.CreateTextField(content)); - - contentRow.Padding = theme.DefaultContainerPadding; - - this.NextButton.Visible = false; - - var startCalibrationPrint = theme.CreateDialogButton("Start Print".Localize()); - startCalibrationPrint.Name = "Start Calibration Print"; - startCalibrationPrint.Click += (s, e) => + fineCalibration.CheckedStateChanged += (s, e) => { - this.DialogWindow.CloseOnIdle(); - // stash the current bed - var scene = printer.Bed.Scene; - scene.Children.Modify((list) => list.Clear()); - IObject3D item = null; - // add the calibration object to the bed - switch(xyCalibrationData.Quality) - { - case XyCalibrationData.QualityType.Coarse: - item = XyCalibrationTabObject3D.Create(1, - Math.Max(printer.Settings.GetValue(SettingsKey.first_layer_height) * 2, printer.Settings.GetValue(SettingsKey.layer_height) * 2), - .5, - printer.Settings.GetValue(SettingsKey.nozzle_diameter)).GetAwaiter().GetResult(); - break; - - case XyCalibrationData.QualityType.Fine: - item = XyCalibrationFaceObject3D.Create(1, - printer.Settings.GetValue(SettingsKey.first_layer_height) * 2, - printer.Settings.GetValue(SettingsKey.layer_height), - .05, - printer.Settings.GetValue(SettingsKey.nozzle_diameter), - printer.Settings.GetValue(SettingsKey.wipe_tower_size), - 8).GetAwaiter().GetResult(); - break; - - default: - item = XyCalibrationFaceObject3D.Create(1, - printer.Settings.GetValue(SettingsKey.first_layer_height) * 2, - printer.Settings.GetValue(SettingsKey.layer_height), - .1, - printer.Settings.GetValue(SettingsKey.nozzle_diameter), - printer.Settings.GetValue(SettingsKey.wipe_tower_size), - 8).GetAwaiter().GetResult(); - break; - } - - // move the part to the center of the bed - var bedBounds = printer.Bed.Bounds; - var aabb = item.GetAxisAlignedBoundingBox(); - item.Matrix *= Matrix4X4.CreateTranslation(bedBounds.Center.X - aabb.MinXYZ.X - aabb.XSize / 2, bedBounds.Center.Y - aabb.MinXYZ.Y - aabb.YSize / 2, -aabb.MinXYZ.Z); - scene.Children.Add(item); - // switch to 3D view - // start the calibration print + xyCalibrationData.Quality = XyCalibrationData.QualityType.Fine; + xyCalibrationData.Offset = .05; }; - - theme.ApplyPrimaryActionStyle(startCalibrationPrint); - - this.AddPageAction(startCalibrationPrint); } } } diff --git a/MatterControlLib/CustomWidgets/XyCalibrationStartPrintPage.cs b/MatterControlLib/CustomWidgets/XyCalibrationStartPrintPage.cs new file mode 100644 index 000000000..383b54ac8 --- /dev/null +++ b/MatterControlLib/CustomWidgets/XyCalibrationStartPrintPage.cs @@ -0,0 +1,195 @@ +/* +Copyright (c) 2019, Lars Brubaker, John Lewin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. +*/ + +using System; +using System.Threading; +using MatterHackers.Agg.UI; +using MatterHackers.DataConverters3D; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.ConfigurationPage.PrintLeveling; +using MatterHackers.MatterControl.DesignTools; +using MatterHackers.MatterControl.SlicerConfiguration; +using MatterHackers.VectorMath; + +namespace MatterHackers.MatterControl +{ + public class XyCalibrationStartPrintPage : WizardPage + { + private XyCalibrationData xyCalibrationData; + + public XyCalibrationStartPrintPage(ISetupWizard setupWizard, PrinterConfig printer, XyCalibrationData xyCalibrationData) + : base(setupWizard) + { + this.xyCalibrationData = xyCalibrationData; + this.WindowTitle = "Nozzle Offset Calibration Wizard".Localize(); + this.HeaderText = "Nozzle Offset Calibration".Localize(); + this.Name = "Nozzle Offset Calibration Wizard"; + + var content = "Here is what we are going to do:".Localize(); + content += "\n\n • " + "Stash your current bed".Localize(); + content += "\n • " + "Print the calibration object".Localize(); + content += "\n • " + "Collect data".Localize(); + content += "\n • " + "Restore your current bed, after all calibration is complete".Localize(); + + contentRow.AddChild(this.CreateTextField(content)); + + contentRow.Padding = theme.DefaultContainerPadding; + + this.NextButton.Visible = false; + + var startCalibrationPrint = theme.CreateDialogButton("Start Print".Localize()); + startCalibrationPrint.Name = "Start Calibration Print"; + startCalibrationPrint.Click += async (s, e) => + { + // stash the current bed + var scene = printer.Bed.Scene; + scene.Children.Modify((list) => list.Clear()); + + // create the item we are adding + IObject3D item = CreateCorectCalibrationObject(printer, xyCalibrationData); + + // add the calibration object to the bed + scene.Children.Add(item); + + // move the part to the center of the bed + var bedBounds = printer.Bed.Bounds; + var aabb = item.GetAxisAlignedBoundingBox(); + item.Matrix *= Matrix4X4.CreateTranslation(bedBounds.Center.X - aabb.MinXYZ.X - aabb.XSize / 2, bedBounds.Center.Y - aabb.MinXYZ.Y - aabb.YSize / 2, -aabb.MinXYZ.Z); + // switch to 3D view + // register callbacks for print compleation + printer.Connection.Disposed += Connection_Disposed; + printer.Connection.CommunicationStateChanged += Connection_CommunicationStateChanged; + + // close this window + this.DialogWindow.CloseOnIdle(); + + // Save the bed that we have created before starting print operation + await printer.Bed.SaveChanges(null, CancellationToken.None); + + // start the calibration print + await ApplicationController.Instance.PrintPart( + printer.Bed.EditContext, + printer, + null, + CancellationToken.None); + }; + + theme.ApplyPrimaryActionStyle(startCalibrationPrint); + + this.AddPageAction(startCalibrationPrint); + } + + private void RestoreBedAndClearPrinterCallbacks() + { + printer.Connection.Disposed -= Connection_Disposed; + printer.Connection.CommunicationStateChanged -= Connection_CommunicationStateChanged; + } + + private void Connection_CommunicationStateChanged(object sender, EventArgs e) + { + switch (printer.Connection.CommunicationState) + { + // We are no longer running this calibration, unwind anything that we have done + case PrinterCommunication.CommunicationStates.Disconnected: + case PrinterCommunication.CommunicationStates.AttemptingToConnect: + case PrinterCommunication.CommunicationStates.FailedToConnect: + case PrinterCommunication.CommunicationStates.ConnectionLost: + case PrinterCommunication.CommunicationStates.PrintingFromSd: + RestoreBedAndClearPrinterCallbacks(); + break; + + // The print hase finished, open the window to collect our calibration results + case PrinterCommunication.CommunicationStates.FinishedPrint: + // open up the next part of the wizard + UiThread.RunOnIdle(() => + { + DialogWindow.Show(new XyCalibrationWizard(printer, xyCalibrationData.ExtruderToCalibrateIndex, xyCalibrationData)); + }); + // close down our listening to the printer and restor the bed + RestoreBedAndClearPrinterCallbacks(); + break; + + // printing the calibration normaly + case PrinterCommunication.CommunicationStates.Connected: + case PrinterCommunication.CommunicationStates.PreparingToPrint: + case PrinterCommunication.CommunicationStates.Printing: + case PrinterCommunication.CommunicationStates.Paused: + case PrinterCommunication.CommunicationStates.Disconnecting: + break; + } + } + + private void Connection_Disposed(object sender, EventArgs e) + { + RestoreBedAndClearPrinterCallbacks(); + } + + private static IObject3D CreateCorectCalibrationObject(PrinterConfig printer, XyCalibrationData xyCalibrationData) + { + IObject3D item; + switch (xyCalibrationData.Quality) + { + case XyCalibrationData.QualityType.Coarse: + item = XyCalibrationTabObject3D.Create(1, + Math.Max(printer.Settings.GetValue(SettingsKey.first_layer_height) * 2, printer.Settings.GetValue(SettingsKey.layer_height) * 2), + .5, + printer.Settings.GetValue(SettingsKey.nozzle_diameter)).GetAwaiter().GetResult(); + break; + + case XyCalibrationData.QualityType.Fine: + item = XyCalibrationFaceObject3D.Create(1, + printer.Settings.GetValue(SettingsKey.first_layer_height) * 2, + printer.Settings.GetValue(SettingsKey.layer_height), + .05, + printer.Settings.GetValue(SettingsKey.nozzle_diameter), + printer.Settings.GetValue(SettingsKey.wipe_tower_size), + 6).GetAwaiter().GetResult(); + break; + + default: + item = XyCalibrationFaceObject3D.Create(1, + printer.Settings.GetValue(SettingsKey.first_layer_height) * 2, + printer.Settings.GetValue(SettingsKey.layer_height), + .1, + printer.Settings.GetValue(SettingsKey.nozzle_diameter), + printer.Settings.GetValue(SettingsKey.wipe_tower_size), + 6).GetAwaiter().GetResult(); + break; + } + + return item; + } + + void PrintHasCompleated() + { + // if we are done callibrating + printer.Settings.SetValue(SettingsKey.xy_offsets_have_been_calibrated, "1"); + } + } +} diff --git a/MatterControlLib/DesignTools/Primitives/XyCalibrationFaceObject3D.cs b/MatterControlLib/DesignTools/Primitives/XyCalibrationFaceObject3D.cs index 33646a5be..959f78551 100644 --- a/MatterControlLib/DesignTools/Primitives/XyCalibrationFaceObject3D.cs +++ b/MatterControlLib/DesignTools/Primitives/XyCalibrationFaceObject3D.cs @@ -176,19 +176,27 @@ namespace MatterHackers.MatterControl.DesignTools var step = new Vector2(spaceBetween + TabWidth, Offset); for (int i = 0; i < 5; i++) { + var offsetMultiple = i - 2; for (int j = 0; j < Layers; j++) { var calibrationMaterial = (j % 2 == 0); var cube = PlatonicSolids.CreateCube(); - var yOffset = calibrationMaterial ? position.Y : TabDepth / 2; - var offset = Matrix4X4.CreateTranslation(position.X, yOffset, BaseHeight + .5 * ChangingHeight + j * ChangingHeight); - content.Children.Add(new Object3D() + var item = new Object3D() { Mesh = cube, - Color = Color.Yellow, - Matrix = Matrix4X4.CreateScale(TabWidth, TabDepth, ChangingHeight) * offset, - MaterialIndex = calibrationMaterial ? CalibrationMaterialIndex : 0 - }); + }; + content.Children.Add(item); + if (calibrationMaterial) + { + item.MaterialIndex = CalibrationMaterialIndex; + item.Color = Color.Yellow; + item.Matrix = Matrix4X4.CreateScale(TabWidth, TabDepth, ChangingHeight) * Matrix4X4.CreateTranslation(position.X, position.Y + Offset * offsetMultiple, BaseHeight + .5 * ChangingHeight + j * ChangingHeight); + } + else + { + item.Color = Color.LightBlue; + item.Matrix = Matrix4X4.CreateScale(TabWidth + spaceBetween * 2, TabDepth, ChangingHeight) * Matrix4X4.CreateTranslation(position.X, position.Y, BaseHeight + .5 * ChangingHeight + j * ChangingHeight); + } } position += step; } diff --git a/MatterControlLib/PrinterCommunication/PrinterConnection.cs b/MatterControlLib/PrinterCommunication/PrinterConnection.cs index 1db36e4b9..47e3218cc 100644 --- a/MatterControlLib/PrinterCommunication/PrinterConnection.cs +++ b/MatterControlLib/PrinterCommunication/PrinterConnection.cs @@ -99,6 +99,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication public event EventHandler BedTemperatureRead; public event EventHandler CommunicationStateChanged; + public event EventHandler DetailedPrintingStateChanged; public event EventHandler ConnectionFailed; @@ -592,7 +593,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication } communicationState = value; - OnCommunicationStateChanged(null); + CommunicationStateChanged?.Invoke(this, null); } } } @@ -763,7 +764,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication if (_printingStatePrivate != value) { _printingStatePrivate = value; - OnCommunicationStateChanged(null); + DetailedPrintingStateChanged?.Invoke(this, null); } } } @@ -1324,29 +1325,6 @@ You will then need to logout and log back in to the computer for the changes to } } - public void OnCommunicationStateChanged(EventArgs e) - { - // Call instance event - CommunicationStateChanged?.Invoke(this, e); -#if __ANDROID__ - - //Path to the printer output file - string pathToPrintOutputFile = Path.Combine(ApplicationDataStorage.Instance.PublicDataStoragePath, "print_output.txt"); - - if (CommunicationState == CommunicationStates.FinishedPrint) - { - //Only write to the text file if file exists - if (File.Exists(pathToPrintOutputFile)) - { - Task.Run(() => - { - File.WriteAllLines(pathToPrintOutputFile, this.TerminalLog.PrinterLines); - }); - } - } -#endif - } - public void OnConnectionFailed(ConnectionFailure reason, string failureDetails = null) { communicationPossible = false; diff --git a/MatterControlLib/PrinterControls/ControlWidgets/CalibrationControls.cs b/MatterControlLib/PrinterControls/ControlWidgets/CalibrationControls.cs index eae110f74..bf1f9167f 100644 --- a/MatterControlLib/PrinterControls/ControlWidgets/CalibrationControls.cs +++ b/MatterControlLib/PrinterControls/ControlWidgets/CalibrationControls.cs @@ -163,7 +163,16 @@ namespace MatterHackers.MatterControl.PrinterControls xyCalibrateButton.Click += (s, e) => UiThread.RunOnIdle(() => { - DialogWindow.Show(new XyCalibrationWizard(printer)); + // TODO: check that we are able to print (no errors) + bool printerCanPrint = true; + if (printerCanPrint) + { + DialogWindow.Show(new XyCalibrationWizard(printer, 1)); + } + else + { + // show the error dialog for printer errors and warnings + } }); settingsRow.BorderColor = Color.Transparent; diff --git a/MatterControlLib/PrinterControls/ManualPrinterControls.cs b/MatterControlLib/PrinterControls/ManualPrinterControls.cs index 88cd14d60..bcb05645e 100644 --- a/MatterControlLib/PrinterControls/ManualPrinterControls.cs +++ b/MatterControlLib/PrinterControls/ManualPrinterControls.cs @@ -112,8 +112,9 @@ namespace MatterHackers.MatterControl UiThread.RunOnIdle(() => tuningAdjustmentControlsContainer.Width = tuningAdjustmentControlsContainer.Width + 1); // Register listeners - printer.Connection.CommunicationStateChanged += onPrinterStatusChanged; - printer.Connection.EnableChanged += onPrinterStatusChanged; + printer.Connection.CommunicationStateChanged += OnPrinterStatusChanged; + printer.Connection.DetailedPrintingStateChanged += OnPrinterStatusChanged; + printer.Connection.EnableChanged += OnPrinterStatusChanged; SetVisibleControls(); } @@ -163,13 +164,14 @@ namespace MatterHackers.MatterControl public override void OnClosed(EventArgs e) { // Unregister listeners - printer.Connection.CommunicationStateChanged -= onPrinterStatusChanged; - printer.Connection.EnableChanged -= onPrinterStatusChanged; + printer.Connection.CommunicationStateChanged -= OnPrinterStatusChanged; + printer.Connection.DetailedPrintingStateChanged -= OnPrinterStatusChanged; + printer.Connection.EnableChanged -= OnPrinterStatusChanged; base.OnClosed(e); } - private void onPrinterStatusChanged(object sender, EventArgs e) + private void OnPrinterStatusChanged(object sender, EventArgs e) { SetVisibleControls(); UiThread.RunOnIdle(this.Invalidate); diff --git a/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs b/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs index 0eac776e1..a21cbb7be 100644 --- a/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs +++ b/MatterControlLib/SlicerConfiguration/EngineMappingMatterSlice.cs @@ -136,6 +136,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration SettingsKey.use_z_probe, SettingsKey.validate_layer_height, SettingsKey.write_regex, + SettingsKey.xy_offsets_have_been_calibrated, SettingsKey.z_offset, SettingsKey.z_probe_samples, SettingsKey.z_probe_xy_offset, diff --git a/MatterControlLib/SlicerConfiguration/Settings/PrinterSettingsExtensions.cs b/MatterControlLib/SlicerConfiguration/Settings/PrinterSettingsExtensions.cs index 101e23e1a..851cc1053 100644 --- a/MatterControlLib/SlicerConfiguration/Settings/PrinterSettingsExtensions.cs +++ b/MatterControlLib/SlicerConfiguration/Settings/PrinterSettingsExtensions.cs @@ -42,6 +42,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration [SettingsKey.print_leveling_data] = "", [SettingsKey.print_leveling_enabled] = "0", [SettingsKey.probe_has_been_calibrated] = "0", + [SettingsKey.xy_offsets_have_been_calibrated] = "0", [SettingsKey.filament_has_been_loaded] = "0", [SettingsKey.filament_1_has_been_loaded] = "0" }; diff --git a/Tests/MatterControl.Tests/SceneTests.cs b/Tests/MatterControl.Tests/SceneTests.cs index 4f2738602..25a9b86e3 100644 --- a/Tests/MatterControl.Tests/SceneTests.cs +++ b/Tests/MatterControl.Tests/SceneTests.cs @@ -36,6 +36,7 @@ using MatterHackers.Agg.Platform; using MatterHackers.DataConverters3D; using MatterHackers.MatterControl; using MatterHackers.MatterControl.Library; +using MatterHackers.MatterControl.PartPreviewWindow; using MatterHackers.MatterControl.Tests.Automation; using MatterHackers.MeshVisualizer; using MatterHackers.VectorMath; @@ -67,6 +68,93 @@ namespace MatterHackers.PolygonMesh.UnitTests Assert.IsTrue(loadedItem.Children.Count == 1); } + [Test] + public async Task AutoArrangeChildrenTests() + { + // arange a single item around the origin + { + var scene = new InteractiveScene(); + Object3D cube1; + scene.Children.Add(cube1 = new Object3D() + { + Mesh = PlatonicSolids.CreateCube(20, 20, 20), + Matrix = Matrix4X4.CreateTranslation(34, 22, 10) + }); + + Assert.IsTrue(new AxisAlignedBoundingBox(24, 12, 0, 44, 32, 20).Equals(cube1.GetAxisAlignedBoundingBox(), .001)); + + await scene.AutoArrangeChildren(Vector3.Zero); + + Assert.IsTrue(new AxisAlignedBoundingBox(-10, -10, 0, 10, 10, 20).Equals(cube1.GetAxisAlignedBoundingBox(), .001)); + } + + // arange a single item around a typical bed center + { + var scene = new InteractiveScene(); + Object3D cube1; + scene.Children.Add(cube1 = new Object3D() + { + Mesh = PlatonicSolids.CreateCube(20, 20, 20), + Matrix = Matrix4X4.CreateTranslation(34, 22, 10) + }); + + Assert.IsTrue(new AxisAlignedBoundingBox(24, 12, 0, 44, 32, 20).Equals(cube1.GetAxisAlignedBoundingBox(), .001)); + + await scene.AutoArrangeChildren(new Vector3(100, 100, 0)); + + Assert.IsTrue(new AxisAlignedBoundingBox(90, 90, 0, 110, 110, 20).Equals(cube1.GetAxisAlignedBoundingBox(), .001)); + } + + // arange 4 items + { + var scene = new InteractiveScene(); + for (int i = 0; i < 4; i++) + { + scene.Children.Add(new Object3D() + { + Mesh = PlatonicSolids.CreateCube(20, 20, 20), + Matrix = Matrix4X4.CreateTranslation(i * 134, i * -122, 10) + }); + } + + var sceneAabb = scene.GetAxisAlignedBoundingBox(); + Assert.Greater(sceneAabb.XSize, 60); + Assert.Greater(sceneAabb.YSize, 60); + + await scene.AutoArrangeChildren(Vector3.Zero); + + sceneAabb = scene.GetAxisAlignedBoundingBox(); + Assert.Less(sceneAabb.XSize, 60); + Assert.Less(sceneAabb.YSize, 60); + } + + // arange 4 items, starting with 1 selected + { + var scene = new InteractiveScene(); + Object3D child = null; + for (int i = 0; i < 4; i++) + { + scene.Children.Add(child = new Object3D() + { + Mesh = PlatonicSolids.CreateCube(20, 20, 20), + Matrix = Matrix4X4.CreateTranslation(i * 134, i * -122, 10) + }); + } + + scene.SelectedItem = child; + + var sceneAabb = scene.GetAxisAlignedBoundingBox(); + Assert.Greater(sceneAabb.XSize, 60); + Assert.Greater(sceneAabb.YSize, 60); + + await scene.AutoArrangeChildren(Vector3.Zero); + + sceneAabb = scene.GetAxisAlignedBoundingBox(); + Assert.Less(sceneAabb.XSize, 60); + Assert.Less(sceneAabb.YSize, 60); + } + } + [Test] public void CreatesAndLinksAmfsForUnsavedMeshes() {