diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index db5ab91daa..205968121f 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -199,7 +199,6 @@ class CuraApplication(QtApplication): self._platform_activity = False self._scene_bounding_box = AxisAlignedBox.Null - self._job_name = None self._center_after_select = False self._camera_animation = None self._cura_actions = None diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index e1da1a941d..1b8ba575db 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -299,7 +299,7 @@ class PrintInformation(QObject): def _updateJobName(self): if self._base_name == "": - self._job_name = "" + self._job_name = "unnamed" self._is_user_specified_job_name = False self.jobNameChanged.emit() return @@ -351,18 +351,17 @@ class PrintInformation(QObject): if is_gcode or is_project_file or (is_empty or (self._base_name == "" and self._base_name != check_name)): # Only take the file name part, Note : file name might have 'dot' in name as well - data = '' + data = "" try: mime_type = MimeTypeDatabase.getMimeTypeForFile(name) data = mime_type.stripExtension(name) except: - Logger.log("w", "Unsupported Mime Type Database file extension") - data = 'unnamed' + Logger.log("w", "Unsupported Mime Type Database file extension %s", name) if data is not None and check_name is not None: self._base_name = data else: - self._base_name = 'unnamed' + self._base_name = "" self._updateJobName() diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 6d8ed7c037..f5036078be 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -475,7 +475,7 @@ class CuraContainerRegistry(ContainerRegistry): extruder_definition = extruder_definitions[0] unique_name = self.uniqueName(machine.getName() + " " + new_extruder_id) if create_new_ids else machine.getName() + " " + new_extruder_id - extruder_stack = ExtruderStack.ExtruderStack(unique_name, parent = machine) + extruder_stack = ExtruderStack.ExtruderStack(unique_name) extruder_stack.setName(extruder_definition.getName()) extruder_stack.setDefinition(extruder_definition) extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position")) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index f174df2e21..20cc2b2eca 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -654,6 +654,15 @@ class MachineManager(QObject): return "" + @pyqtProperty(str, notify = activeVariantChanged) + def activeVariantId(self) -> str: + if self._active_container_stack: + variant = self._active_container_stack.variant + if variant: + return variant.getId() + + return "" + @pyqtProperty(str, notify = activeVariantChanged) def activeVariantBuildplateName(self) -> str: if self._global_container_stack: diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py index 5423ee0caa..a3a58b18ba 100755 --- a/plugins/3MFReader/ThreeMFReader.py +++ b/plugins/3MFReader/ThreeMFReader.py @@ -15,6 +15,7 @@ from UM.Math.Vector import Vector from UM.Mesh.MeshBuilder import MeshBuilder from UM.Mesh.MeshReader import MeshReader from UM.Scene.GroupDecorator import GroupDecorator +from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType from cura.Settings.ExtruderManager import ExtruderManager from cura.Scene.CuraSceneNode import CuraSceneNode @@ -25,6 +26,7 @@ from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch MYPY = False + try: if not MYPY: import xml.etree.cElementTree as ET @@ -32,10 +34,20 @@ except ImportError: Logger.log("w", "Unable to load cElementTree, switching to slower version") import xml.etree.ElementTree as ET + ## Base implementation for reading 3MF files. Has no support for textures. Only loads meshes! class ThreeMFReader(MeshReader): def __init__(self, application): super().__init__(application) + + MimeTypeDatabase.addMimeType( + MimeType( + name = "application/vnd.ms-package.3dmanufacturing-3dmodel+xml", + comment="3MF", + suffixes=["3mf"] + ) + ) + self._supported_extensions = [".3mf"] self._root = None self._base_name = "" diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 8eecc3b5d9..1f950f275c 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -4,7 +4,6 @@ from configparser import ConfigParser import zipfile import os -import threading from typing import List, Tuple @@ -21,7 +20,7 @@ from UM.Settings.ContainerStack import ContainerStack from UM.Settings.DefinitionContainer import DefinitionContainer from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.MimeTypeDatabase import MimeTypeDatabase +from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType from UM.Job import Job from UM.Preferences import Preferences @@ -84,6 +83,15 @@ class ExtruderInfo: class ThreeMFWorkspaceReader(WorkspaceReader): def __init__(self): super().__init__() + + MimeTypeDatabase.addMimeType( + MimeType( + name="application/x-cura-project-file", + comment="Cura Project File", + suffixes=["curaproject.3mf"] + ) + ) + self._supported_extensions = [".3mf"] self._dialog = WorkspaceDialog() self._3mf_mesh_reader = None diff --git a/plugins/3MFReader/__init__.py b/plugins/3MFReader/__init__.py index e545fb9f87..feabf19818 100644 --- a/plugins/3MFReader/__init__.py +++ b/plugins/3MFReader/__init__.py @@ -13,23 +13,9 @@ from . import ThreeMFWorkspaceReader from UM.i18n import i18nCatalog from UM.Platform import Platform -from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType + catalog = i18nCatalog("cura") -MimeTypeDatabase.addMimeType( - MimeType( - name = "application/x-cura-project-file", - comment = "Cura Project File", - suffixes = ["curaproject.3mf"] - ) -) -MimeTypeDatabase.addMimeType( - MimeType( - name = "application/x-cura-project-file", - comment = "Cura Project File", - suffixes = ["3mf"] - ) -) def getMetaData() -> Dict: # Workarround for osx not supporting double file extensions correctly. diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index 9cb9a60e79..8da415df05 100755 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -1,3 +1,127 @@ + + +[3.4.0] + +*Toolbox +The plugin browser has been remodeled into the Toolbox. Navigation now involves graphical elements such as tiles, which can be clicked for further details. + +*Upgradable bundled resources +It is now possible to have multiple versions of bundled resources installed: the bundled version and the downloaded upgrade. If an upgrade in the form of a package is present, the bundled version will not be loaded. If it's not present, Ultimaker Cura will revert to the bundled version. + +*Package manager recognizes bundled resources +Bundled packages are now made visible to the CuraPackageMangager. This means the resources are included by default, as well as the "wrapping" of a package, (e.g. package.json) so that the CuraPackageManger and Toolbox recognize them as being installed. + +*Retraction combing max distance +New setting for maximum combing travel distance. Combing travel moves longer than this value will use retraction. Contributed by smartavionics. + +*Infill support +When enabled, infill will be generated only where it is needed using a specialized support generation algorithm for the internal support structures of a part. Contributed by BagelOrb. + +*Print outside perimeter before holes +This prioritizes outside perimeters before printing holes. By printing holes as late as possible, there is a reduced risk of travel moves dislodging them from the build plate. This setting should only have an effect if printing outer before inner walls. Contributed by smartavionics. + +*Disable omitting retractions in support +Previous versions had no option to disable omitting retraction moves when printing supports, which could cause issues with third-party machines or materials. An option has been added to disable this. Contributed by BagelOrb. + +*Support wall line count +Added setting to configure how many walls to print around supports. Contributed by BagelOrb. + +*Maximum combing resolution +Combing travel moves are kept at least 1.5 mm long to prevent buffer underruns. + +*Avoid supports when traveling +Added setting to avoid supports when performing travel moves. This minimizes the risk of the print head hitting support material. + +*Rewrite cross infill +Experimental setting that allows you to input a path to an image to manipulate the cross infill density. This will overlay that image on your model. Contributed by BagelOrb. + +*Backup and restore +Added functionality to backup and restore settings and profiles to cloud using the Cura Backups plugin. + +*Auto-select model after import +User can now set preferences for the behavior of selecting a newly imported model or not. + +*Settings filter timeout +The settings filter is triggered on enter or after a 500ms timeout when typing a setting to filter. + +*Event measurements +Added time measurement to logs for occurrences, including startup time, file load time, number of items on the build plate when slicing, slicing time, and time and performance when moving items on the build plate, for benchmarking purposes. + +*Send anonymous data +Disable button on the ‘Send anonymous data’ popup has changed to a ‘more info’ button, with further options to enable/disable anonymous data messages. + +*Configuration error assistant +Detect and show potential configuration file errors to users, e.g. incorrect files and duplicate files in material or quality profiles, there are several places to check. Information is stored and communicated to the user to prevent crashing in future. + +*Disable ensure models are kept apart +Disable "Ensure models are kept apart" by default due to to a change in preference files. + +*Prepare and monitor QML files +Created two separate QML files for the Prepare and Monitor stages. + +*Hide bed temperature +Option to hide bed temperature when no heated bed is present. Contributed by ngraziano. + +*Reprap/Marlin GCODE flavor +RepRap firmware now lists values for all extruders in the "Filament used" GCODE comment. Contributed by smartavionics. + +*AutoDesk Inventor integration +Open AutoDesk inventor files (parts, assemblies, drawings) directly into Ultimaker Cura. Contributed by thopiekar. + +*Blender integration +Open Blender files directly into Ultimaker Cura. Contributed by thopiekar. + +*OpenSCAD integration +Open OpenSCAD files directly into Ultimaker Cura. Contributed by thopiekar. + +*FreeCAD integration +Open FreeCAD files directly into Ultimaker Cura. Contributed by thopiekar. + +*OctoPrint plugin +New version of the OctoPrint plugin for Ultimaker Cura. Contributed by fieldOfView. + +*Cura Backups +Backup and restore your configuration, including settings, materials and plugins, for use across different systems. + +*MakePrintable +New version of the MakePrintable plugin. + +*Compact Prepare sidebar +Plugin that replaces the sidebar with a more compact variation of the original sidebar. Nozzle and material dropdowns are combined into a single line, the “Check compatibility” link is removed, extruder selection buttons are downsized, recommended and custom mode selection buttons are moved to a combobox at the top, and margins are tweaked. Contributed by fieldOfView. + +*PauseAtHeight plugin +Bug fixes and improvements for PauseAtHeight plugin. Plugin now accounts for raft layers when choosing “Pause of layer no.” Now positions the nozzle at x and y values of the next layer when resuming. Contributed by JPFrancoia. + +*Bug fixes +- Prime tower purge fix. Prime tower purge now starts away from the center, minimizing the chance of overextrusion and nozzle obstructions. Contributed by BagelOrb. +- Extruder 2 temp via USB. Fixed a bug where temperatures can’t be read for a second extruder via USB. Contributed by kirilledelman. +- Move to next object position before bed heat. Print one at a time mode caused waiting for the bed temperature to reach the first layer temperature while the nozzle was still positioned on the top of the last part. This has been fixed so that the nozzle moves to the location of the next part before waiting for heat up. Contributed by smartavionics. +- Non-GCODE USB. Fixed a bug where the USB port doesn’t open if printer doesn't support GCODE. Contributed by ohrn. +- Improved wall overlap compensation. Minimizes unexpected behavior on overlap lines, providing smoother results. Contributed by BagelOrb. +- Configuration/sync. Fixes minor issues with the configuration/sync menu, such as text rendering on some OSX systems and untranslatable text. Contributed by fieldOfView. +- Print job name reslice. Fixed behavior where print job name changes back to origin when reslicing. +- Discard/keep. Customized settings don't give an 'discard or keep' dialog when changing material. +- Message box styling. Fixed bugs related to message box styling, such as the progress bar overlapping the button in the ‘Sending Data’ popup. +- Curaproject naming. Fixed bug related to two "curaprojects" in the file name when saving a project. +- No support on first layers. Fixed a bug related to no support generated causing failed prints when model is floating above build plate. +- False incompatible configuration. Fixed a bug where PrintCore and materials were flagged even though the configurations are compatible. +- Spiralize contour overlaps. Fixed a bug related to spiralize contour overlaps. +- Model saved outside build volume. Fixed a bug that would saved a model to file (GCODE) outside the build volume. +- Filament diameter line width. Adjust filament diameter to calculate line width in the GCODE parser. +- Holes in model surfaces. Fixed a bug where illogical travel moves leave holes in the model surface. +- Nozzle legacy file variant. Fixed crashes caused by loading legacy nozzle variant files. +- Brim wall order. Fixed a bug related to brim wall order. Contributed by smartavionics. +- GCODE reader gaps. Fixed a GCODE reader bug that can create a gap at the start of a spiralized layer. +- Korean translation. Fixed some typos in Korean translation. +- ARM/Mali systems. Graphics pipeline for ARM/Mali fixed. Contributed by jwalt. +- NGC Writer. Fixed missing author for NGC Writer plugin. +- Support blocker legacy GPU. Fixes depth picking on older GPUs that do not support the 4.1 shading model which caused the support blocker to put cubes in unexpected locations. Contributed by fieldOfView. + +*Third-party printers +- Felix Tec4 printer. Updated definitions for Felix Tec4. Contributed by kerog777. +- Deltacomb. Updated definitions for Deltacomb. Contributed by kaleidoscopeit. +- Rigid3D Mucit. Added definitions for Rigid3D Mucit. Contributed by Rigid3D. + [3.3.0] *Profile for the Ultimaker S5 @@ -66,7 +190,7 @@ Generate a cube mesh to prevent support material generation in specific areas of *Real bridging - smartavionics New experimental feature that detects bridges, adjusting the print speed, slow and fan speed to enhance print quality on bridging parts. -*Updated CuraEngine executable - thopiekar & Ultimaker B.V. ❤️ +*Updated CuraEngine executable - thopiekar & Ultimaker B.V. The CuraEngine executable contains a dedicated icon, author and license info on Windows now. The icon has been designed by Ultimaker B.V. *Use RapidJSON and ClipperLib from system libraries diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py index 4a75b23c2f..37b6989add 100644 --- a/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py +++ b/plugins/VersionUpgrade/VersionUpgrade21to22/MachineInstance.py @@ -107,7 +107,12 @@ class MachineInstance: user_profile["values"] = {} version_upgrade_manager = UM.VersionUpgradeManager.VersionUpgradeManager.getInstance() - user_storage = os.path.join(Resources.getDataStoragePath(), next(iter(version_upgrade_manager.getStoragePaths("user")))) + user_version_to_paths_dict = version_upgrade_manager.getStoragePaths("user") + paths_set = set() + for paths in user_version_to_paths_dict.values(): + paths_set |= paths + + user_storage = os.path.join(Resources.getDataStoragePath(), next(iter(paths_set))) user_profile_file = os.path.join(user_storage, urllib.parse.quote_plus(self._name) + "_current_settings.inst.cfg") if not os.path.exists(user_storage): os.makedirs(user_storage) @@ -135,4 +140,4 @@ class MachineInstance: output = io.StringIO() config.write(output) - return [self._filename], [output.getvalue()] \ No newline at end of file + return [self._filename], [output.getvalue()] diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json index 64948b4fe9..08fe01a76b 100644 --- a/resources/definitions/ultimaker3.def.json +++ b/resources/definitions/ultimaker3.def.json @@ -122,7 +122,7 @@ "raft_jerk": { "value": "jerk_layer_0" }, "raft_margin": { "value": "10" }, "raft_surface_layers": { "value": "1" }, - "retraction_amount": { "value": "2" }, + "retraction_amount": { "value": "6.5" }, "retraction_count_max": { "value": "10" }, "retraction_extrusion_window": { "value": "1" }, "retraction_hop": { "value": "2" }, diff --git a/resources/definitions/ultimaker_s5.def.json b/resources/definitions/ultimaker_s5.def.json index 8af77e22ac..f6971d0da3 100644 --- a/resources/definitions/ultimaker_s5.def.json +++ b/resources/definitions/ultimaker_s5.def.json @@ -119,7 +119,7 @@ "raft_margin": { "value": "10" }, "raft_speed": { "value": "25" }, "raft_surface_layers": { "value": "1" }, - "retraction_amount": { "value": "2" }, + "retraction_amount": { "value": "6.5" }, "retraction_count_max": { "value": "10" }, "retraction_extrusion_window": { "value": "1" }, "retraction_hop": { "value": "2" }, diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 6cd9999db7..3b10cf59d5 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -81,8 +81,8 @@ Item { text: PrintInformation.jobName horizontalAlignment: TextInput.AlignRight onEditingFinished: { - text = text == "" ? "unnamed" : text; - PrintInformation.setJobName(printJobTextfield.text, true); + var new_name = text == "" ? "unnamed" : text; + PrintInformation.setJobName(new_name, true); printJobTextfield.focus = false; } validator: RegExpValidator { diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml index ceb2ed12be..ad91f2ee9a 100644 --- a/resources/qml/Preferences/MaterialView.qml +++ b/resources/qml/Preferences/MaterialView.qml @@ -404,10 +404,17 @@ TabView id: spinBox anchors.left: label.right value: { + // In case the setting is not in the material... if (!isNaN(parseFloat(materialPropertyProvider.properties.value))) { return parseFloat(materialPropertyProvider.properties.value); } + // ... we search in the variant, and if it is not there... + if (!isNaN(parseFloat(variantPropertyProvider.properties.value))) + { + return parseFloat(variantPropertyProvider.properties.value); + } + // ... then look in the definition container. if (!isNaN(parseFloat(machinePropertyProvider.properties.value))) { return parseFloat(machinePropertyProvider.properties.value); @@ -431,6 +438,13 @@ TabView key: model.key } UM.ContainerPropertyProvider + { + id: variantPropertyProvider + containerId: Cura.MachineManager.activeVariantId + watchedProperties: [ "value" ] + key: model.key + } + UM.ContainerPropertyProvider { id: machinePropertyProvider containerId: Cura.MachineManager.activeDefinitionId