diff --git a/cura/CrashHandler.py b/cura/CrashHandler.py index 24df54b74e..d74b48a53a 100644 --- a/cura/CrashHandler.py +++ b/cura/CrashHandler.py @@ -14,8 +14,9 @@ import urllib.request import urllib.error import shutil -from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QFile +from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, QUrl from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QTextEdit, QGroupBox, QCheckBox, QPushButton +from PyQt5.QtGui import QDesktopServices from UM.Application import Application from UM.Logger import Logger @@ -91,7 +92,7 @@ class CrashHandler: label = QLabel() label.setText(catalog.i18nc("@label crash message", """

A fatal error has occurred.

Unfortunately, Cura encountered an unrecoverable error during start up. It was possibly caused by some incorrect configuration files. We suggest to backup and reset your configuration.

-

Your backup can be found in your Configuration folder.

+

Backups can be found in the configuration folder.

Please send us this Crash Report to fix the problem.

""")) label.setWordWrap(True) @@ -105,8 +106,13 @@ class CrashHandler: show_details_button.setMaximumWidth(200) show_details_button.clicked.connect(self._showDetailedReport) + show_configuration_folder_button = QPushButton(catalog.i18nc("@action:button", "Show configuration folder"), dialog) + show_configuration_folder_button.setMaximumWidth(200) + show_configuration_folder_button.clicked.connect(self._showConfigurationFolder) + layout.addWidget(self._send_report_checkbox) layout.addWidget(show_details_button) + layout.addWidget(show_configuration_folder_button) # "backup and start clean" and "close" buttons buttons = QDialogButtonBox() @@ -182,6 +188,10 @@ class CrashHandler: self.early_crash_dialog.close() + def _showConfigurationFolder(self): + path = Resources.getConfigStoragePath(); + QDesktopServices.openUrl(QUrl.fromLocalFile( path )) + def _showDetailedReport(self): self.dialog.exec_() diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index b66bdcb6a8..464694dbcd 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1596,8 +1596,16 @@ class CuraApplication(QtApplication): for original_node in nodes: # Create a CuraSceneNode just if the original node is not that type - node = original_node if isinstance(original_node, CuraSceneNode) else CuraSceneNode() - node.setMeshData(original_node.getMeshData()) + if isinstance(original_node, CuraSceneNode): + node = original_node + else: + node = CuraSceneNode() + node.setMeshData(original_node.getMeshData()) + + #Setting meshdata does not apply scaling. + if(original_node.getScale() != Vector(1.0, 1.0, 1.0)): + node.scale(original_node.getScale()) + node.setSelectable(True) node.setName(os.path.basename(filename)) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 329fbe77b7..d6faf214dd 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -208,19 +208,12 @@ class CuraContainerRegistry(ContainerRegistry): Logger.log("e", "Incorrect profile [%s]. Could not find global profile", file_name) return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags or !", "This profile {0} contains incorrect data, could not import it.", file_name)} - - # In a profile we can have the quality_definition metadata, but if not, we get the definition - profile_definition = global_profile.getMetaDataEntry("quality_definition") - if not profile_definition: - profile_definition = global_profile.getMetaDataEntry("definition") - - # The expected machine definition may be the quality_definition if defined or the current definition id - expected_machine_definition = None + profile_definition = global_profile.getMetaDataEntry("definition") + expected_machine_definition = "fdmprinter" if parseBool(global_container_stack.getMetaDataEntry("has_machine_quality", "False")): expected_machine_definition = global_container_stack.getMetaDataEntry("quality_definition") - if not expected_machine_definition: - expected_machine_definition = global_container_stack.definition.getId() - + if not expected_machine_definition: + expected_machine_definition = global_container_stack.definition.getId() if expected_machine_definition is not None and profile_definition is not None and profile_definition != expected_machine_definition: Logger.log("e", "Profile [%s] is for machine [%s] but the current active machine is [%s]. Will not import the profile", file_name, profile_definition, expected_machine_definition) return { "status": "error", diff --git a/cura/Settings/MaterialSettingsVisibilityHandler.py b/cura/Settings/MaterialSettingsVisibilityHandler.py index bafe566293..ce545f4551 100644 --- a/cura/Settings/MaterialSettingsVisibilityHandler.py +++ b/cura/Settings/MaterialSettingsVisibilityHandler.py @@ -10,7 +10,7 @@ class MaterialSettingsVisibilityHandler(UM.Settings.Models.SettingVisibilityHand material_settings = { "default_material_print_temperature", - "material_bed_temperature", + "default_material_bed_temperature", "material_standby_temperature", #"material_flow_temp_graph", "cool_fan_speed", diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index ea3ac3c0f8..3982a0ad06 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -191,7 +191,7 @@ class CuraEngineBackend(QObject, Backend): ## Perform a slice of the scene. def slice(self): - Logger.log("d", "starting to slice!") + Logger.log("d", "Starting to slice...") self._slice_start_time = time() if not self._build_plates_to_be_sliced: self.processingProgress.emit(1.0) @@ -199,7 +199,7 @@ class CuraEngineBackend(QObject, Backend): return if self._process_layers_job: - Logger.log("d", " ## Process layers job still busy, trying later") + Logger.log("d", "Process layers job still busy, trying later.") return if not hasattr(self._scene, "gcode_dict"): diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index ede0e2c251..2be85384f5 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -121,9 +121,13 @@ class GCodeWriter(MeshWriter): if flat_global_container.getMetaDataEntry("quality_type", None) is None: flat_global_container.addMetaDataEntry("quality_type", stack.quality.getMetaDataEntry("quality_type", "normal")) - # Ensure that quality_definition is set. (Can happen if we have empty quality changes). + # Change the default defintion + default_machine_definition = "fdmprinter" if parseBool(stack.getMetaDataEntry("has_machine_quality", "False")): - flat_global_container.addMetaDataEntry("quality_definition", stack.getMetaDataEntry("quality_definition")) + default_machine_definition = stack.getMetaDataEntry("quality_definition") + if not default_machine_definition: + default_machine_definition = stack.definition.getId() + flat_global_container.setMetaDataEntry("definition", default_machine_definition) serialized = flat_global_container.serialize() data = {"global_quality": serialized} @@ -145,6 +149,15 @@ class GCodeWriter(MeshWriter): # Ensure that quality_type is set. (Can happen if we have empty quality changes). if flat_extruder_quality.getMetaDataEntry("quality_type", None) is None: flat_extruder_quality.addMetaDataEntry("quality_type", extruder.quality.getMetaDataEntry("quality_type", "normal")) + + # Change the default defintion + default_extruder_definition = "fdmextruder" + if parseBool(stack.getMetaDataEntry("has_machine_quality", "False")): + default_extruder_definition = extruder.getMetaDataEntry("quality_definition") + if not default_extruder_definition: + default_extruder_definition = extruder.definition.getId() + flat_extruder_quality.setMetaDataEntry("definition", default_extruder_definition) + extruder_serialized = flat_extruder_quality.serialize() data.setdefault("extruder_quality", []).append(extruder_serialized) diff --git a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py index 512671b3b3..42f00beceb 100644 --- a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py +++ b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py @@ -419,8 +419,6 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice): self._authentication_failed_message.show() elif status_code == 200: self.setAuthenticationState(AuthState.Authenticated) - # Now we know for sure that we are authenticated, send the material profiles to the machine. - self._sendMaterialProfiles() def _checkAuthentication(self): Logger.log("d", "Checking if authentication is correct for id %s and key %s", self._authentication_id, self._getSafeAuthKey()) diff --git a/resources/definitions/dagoma_discoeasy200.def.json b/resources/definitions/dagoma_discoeasy200.def.json index 9bcc2402f2..1674801b5e 100644 --- a/resources/definitions/dagoma_discoeasy200.def.json +++ b/resources/definitions/dagoma_discoeasy200.def.json @@ -7,7 +7,6 @@ "author": "Dagoma", "manufacturer": "Dagoma", "file_formats": "text/x-gcode", - "icon": "icon_discoeasy200.png", "platform": "discoeasy200.stl", "platform_offset": [ 105, -59, 280] }, @@ -39,13 +38,25 @@ "default_value": 10 }, "machine_start_gcode": { - "default_value": ";Gcode by Cura\nG90 ;absolute positioning\nM106 S250 ;fan on for the palpeur\nG28 X Y\nG1 X50\nM109 S180\nG28\nM104 S{material_print_temperature_layer_0}\n;Activation palpeur\n;bloc palpeur\nG29 ;Auto level\nM107 ;start with the fan off\nG1 X100 Y20 F3000\nG1 Z0.5\nM109 S{material_print_temperature_layer_0}\nM82 ;set extruder to absolute mode\nG92 E0 ;zero the extruded length\nG1 F200 E10 ;extrude 10mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 Z3\nG1 F6000" + "default_value": ";Gcode by Cura\nG90\nM106 S250\nG28 X Y\nG1 X50\nM109 S180\nG28\nM104 S{material_print_temperature_layer_0}\nG29\nM107\nG1 X100 Y20 F3000\nG1 Z0.5\nM109 S{material_print_temperature_layer_0}\nM82\nG92 E0\nG1 F200 E10\nG92 E0\nG1 Z3\nG1 F6000\n" }, "machine_end_gcode": { - "default_value": "M104 S0\nM106 S255 ;start fan full power\nM140 S0 ;heated bed heater off (if you have it)\n;Home machine\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+3 F3000 ;move Z up a bit and retract filament even more\nG90\nG28 X Y\n;Ventilation forcee\nM107 ;stop fan\n;Shut down motor\nM84 ;shut down motors" + "default_value": "\nM104 S0\nM106 S255\nM140 S0\nG91\nG1 E-1 F300\nG1 Z+3 F3000\nG90\nG28 X Y\nM107\nM84\n" }, "material_diameter": { "default_value": 1.75 + }, + "speed_print": { + "default_value": 60 + }, + "speed_travel": { + "default_value": 100 + }, + "retraction_amount": { + "default_value": 3.5 + }, + "retraction_speed": { + "default_value": 50 } } } diff --git a/resources/definitions/dagoma_neva.def.json b/resources/definitions/dagoma_neva.def.json new file mode 100644 index 0000000000..430d2f6ab1 --- /dev/null +++ b/resources/definitions/dagoma_neva.def.json @@ -0,0 +1,69 @@ +{ + "id": "Dagoma_neva", + "name": "Dagoma NEVA", + "version": 2, + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "Dagoma", + "manufacturer": "Dagoma", + "file_formats": "text/x-gcode", + "platform": "neva.stl", + "platform_offset": [ 0, 0, 0] + }, + "overrides": { + "machine_width": { + "default_value": 195.55 + }, + "machine_height": { + "default_value": 205 + }, + "machine_depth": { + "default_value": 195.55 + }, + "machine_center_is_zero": { + "default_value": true + }, + "machine_nozzle_size": { + "default_value": 0.4 + }, + "machine_head_with_fans_polygon": { + "default_value": [ + [17, 40], + [17, -70], + [-17, -70], + [17, 40] + ] + }, + "gantry_height": { + "default_value": 0 + }, + "machine_shape": { + "default_value": "elliptic" + }, + "machine_gcode_flavor": { + "default_value": "RepRap" + }, + "machine_start_gcode": { + "default_value": ";Gcode by Cura\nG90\nG28\nM109 S100\nG29\nM104 S{material_print_temperature_layer_0}\nG0 X0 Y-85\nG0 Z0.26\nM109 S{material_print_temperature_layer_0}\nM82\nG92 E0\nG1 F200 E6\nG92 E0\nG1 F200 E-3.5\nG0 Z0.15\nG0 X10\nG0 Z3\nG1 F6000\n" + }, + "machine_end_gcode": { + "default_value": "\nM104 S0\nM106 S255\nM140 S0\nG91\nG1 E-1 F300\nG1 Z+3 E-2 F9000\nG90\nG28\n" + }, + "material_diameter": { + "default_value": 1.75 + }, + "speed_print": { + "default_value": 40 + }, + "speed_travel": { + "default_value": 120 + }, + "retraction_amount": { + "default_value": 3.8 + }, + "retraction_speed": { + "default_value": 60 + } + } +} diff --git a/resources/definitions/ubuild-3d_mr_bot_280.def.json b/resources/definitions/ubuild-3d_mr_bot_280.def.json new file mode 100644 index 0000000000..7f9069370c --- /dev/null +++ b/resources/definitions/ubuild-3d_mr_bot_280.def.json @@ -0,0 +1,49 @@ +{ + "id": "ubuild-3d_mr_bot_280", + "version": 2, + "name": "uBuild-3D Mr Bot 280", + "inherits": "fdmprinter", + "metadata": { + "visible": true, + "author": "uBuild-3D", + "manufacturer": "uBuild-3D", + "category": "Other", + "file_formats": "text/x-gcode", + "icon": "icon_uBuild-3D", + "platform": "mr_bot_280_platform.stl", + "has_materials": true + }, + + "overrides": { + "machine_name": { "default_value": "Mr Bot 280" }, + "machine_heated_bed": { "default_value": true }, + "machine_width": { "default_value": 275 }, + "machine_height": { "default_value": 275 }, + "machine_depth": { "default_value": 275 }, + "machine_center_is_zero": { "default_value": false }, + "material_diameter": { "default_value": 1.75 }, + "material_bed_temperature": { "default_value": 70 }, + "machine_nozzle_size": { "default_value": 0.4 }, + "layer_height": { "default_value": 0.2 }, + "layer_height_0": { "default_value": 0.1 }, + "retraction_amount": { "default_value": 2 }, + "retraction_speed": { "default_value": 50 }, + "retraction_retract_speed": { "default_value": 50 }, + "retraction_prime_speed": { "default_value": 30 }, + "adhesion_type": { "default_value": "skirt" }, + "machine_nozzle_heat_up_speed": { "default_value": 2 }, + "machine_nozzle_cool_down_speed": { "default_value": 2 }, + "machine_head_with_fans_polygon": { "default_value": [[-20,20],[10,10],[10,10],[10,10]] }, + "gantry_height": { "default_value": 275 }, + "machine_max_feedrate_z": { "default_value": 15 }, + "machine_max_feedrate_e": { "default_value": 60 }, + "machine_max_acceleration_z": { "default_value": 1000 }, + "machine_acceleration": { "default_value": 2000 }, + "machine_max_jerk_xy": { "default_value": 20 }, + "machine_max_jerk_z": { "default_value": 0.4 }, + "machine_max_jerk_e": { "default_value": 5 }, + "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, + "machine_start_gcode": { "default_value": "G21 ; set units to millimeters\nG90 ; use absolute positioning\nM82 ; absolute extrusion mode\nM140 S{material_bed_temperature} ; set bed temp\nM104 S{material_print_temperature} ; set extruder temp\nG28 ; home X, Y and Z\nG29 ; probe sequence (for auto-leveling)\nG1 Z15 F600 ; go to Z15 position\nG1 X0 Y-20 F10000 ; go to X0 Y-20 position\nM190 S{material_bed_temperature} ; wait for bed temp\nM109 S{material_print_temperature} ; wait for extruder temp\nG92 E0 ; reset extruder distance position\nG1 E25 F100 ; extrude 25mm of material\nG92 E0 ; reset extruder distance position\nM117 Printing..." }, + "machine_end_gcode": { "default_value": "M400 ; wait for moves to finish\nG92 Z0 E0 ; reset Z position\nG1 E-2 F9000 ; retract material\nG1 Z2 ; get extruder out of the way\nM104 S0 ; turn off extruder\nG1 Y285 F3000 ; present finished print\nM140 S0 ; turn off bed\nM84 ; disable motors\nM117 Print complete" } + } +} diff --git a/resources/i18n/cura.pot b/resources/i18n/cura.pot index e8148997ce..1620e11d81 100644 --- a/resources/i18n/cura.pot +++ b/resources/i18n/cura.pot @@ -3598,6 +3598,11 @@ msgctxt "@label" msgid "SVG icons" msgstr "" +#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:139 +msgctxt "@label" +msgid "Linux cross-distribution application deployment" +msgstr "" + #: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:41 msgctxt "@label" msgid "Profile:" diff --git a/resources/i18n/de_DE/cura.po b/resources/i18n/de_DE/cura.po index 9af48a4d06..250e3e5e1b 100644 --- a/resources/i18n/de_DE/cura.po +++ b/resources/i18n/de_DE/cura.po @@ -3485,6 +3485,11 @@ msgctxt "@label" msgid "SVG icons" msgstr "SVG-Symbole" +#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:139 +msgctxt "@label" +msgid "Linux cross-distribution application deployment" +msgstr "Distributionsunabhängiges Format für Linux-Anwendungen" + #: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:41 msgctxt "@label" msgid "Profile:" diff --git a/resources/meshes/neva.stl b/resources/meshes/neva.stl new file mode 100644 index 0000000000..72ec185bd9 Binary files /dev/null and b/resources/meshes/neva.stl differ diff --git a/resources/qml/AboutDialog.qml b/resources/qml/AboutDialog.qml index 30e540e80a..5d3b1d1544 100644 --- a/resources/qml/AboutDialog.qml +++ b/resources/qml/AboutDialog.qml @@ -136,6 +136,7 @@ UM.Dialog projectsModel.append({ name:"Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" }); projectsModel.append({ name:"Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" }); + projectsModel.append({ name:"AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" }); } } } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index b7ab0000de..8c8e6d1c47 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -6,48 +6,53 @@ "fonts": { "large": { "size": 1.35, - "bold": true, + "weight": 63, "family": "Noto Sans" }, "large_nonbold": { "size": 1.35, + "weight": 50, "family": "Noto Sans" }, "default": { "size": 1.0, + "weight": 50, "family": "Noto Sans" }, "default_bold": { "size": 1.0, - "bold": true, + "weight": 63, "family": "Noto Sans" }, "default_italic": { "size": 1.15, + "weight": 50, "italic": true, "family": "Noto Sans" }, "small": { "size": 1.0, - "bold": true, + "weight": 63, "family": "Noto Sans" }, "very_small": { "size": 1.0, + "weight": 50, "family": "Noto Sans" }, "button_tooltip": { "size": 1.0, + "weight": 50, "family": "Noto Sans" }, "setting_category": { "size": 1.15, - "bold": true, + "weight": 63, "family": "Noto Sans" }, "action_button": { "size": 1.15, - "bold": true, + "weight": 50, "family": "Noto Sans" } },