diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index f993cfcb01..9b8b019b8b 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -604,8 +604,6 @@ class CuraApplication(QtApplication): op.addOperation(RemoveSceneNodeOperation(group_node)) op.push() - pass - ## Remove an object from the scene. # Note that this only removes an object if it is selected. @pyqtSlot("quint64") @@ -619,17 +617,17 @@ class CuraApplication(QtApplication): node = Selection.getSelectedObject(0) if node: - group_node = None - if node.getParent(): - group_node = node.getParent() - op = RemoveSceneNodeOperation(node) + op = GroupedOperation() + op.addOperation(RemoveSceneNodeOperation(node)) + + group_node = node.getParent() + if group_node: + # Note that at this point the node has not yet been deleted + if len(group_node.getChildren()) <= 2 and group_node.callDecoration("isGroup"): + op.addOperation(SetParentOperation(group_node.getChildren()[0], group_node.getParent())) + op.addOperation(RemoveSceneNodeOperation(group_node)) op.push() - if group_node: - if len(group_node.getChildren()) == 1 and group_node.callDecoration("isGroup"): - op.addOperation(SetParentOperation(group_node.getChildren()[0], group_node.getParent())) - op = RemoveSceneNodeOperation(group_node) - op.push() ## Create a number of copies of existing object. @pyqtSlot("quint64", int) diff --git a/cura/PrinterOutputDevice.py b/cura/PrinterOutputDevice.py index 12335e940b..bbf35da6f8 100644 --- a/cura/PrinterOutputDevice.py +++ b/cura/PrinterOutputDevice.py @@ -49,7 +49,7 @@ class PrinterOutputDevice(QObject, OutputDevice): self._printer_state = "" self._printer_type = "unknown" - def requestWrite(self, node, file_name = None, filter_by_machine = False): + def requestWrite(self, nodes, file_name = None, filter_by_machine = False): raise NotImplementedError("requestWrite needs to be implemented") ## Signals diff --git a/cura/QualityManager.py b/cura/QualityManager.py index a304eb1db3..09e9d283ed 100644 --- a/cura/QualityManager.py +++ b/cura/QualityManager.py @@ -20,9 +20,6 @@ class QualityManager: __instance = None - def __init__(self): - self._empty_quality_container = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality")[0] - ## Find a quality by name for a specific machine definition and materials. # # \param quality_name @@ -96,7 +93,7 @@ class QualityManager: basic_materials = self._getBasicMaterials(material_containers[0]) result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria) - return result[0] if result else self._empty_quality_container + return result[0] if result else None ## Find all suitable qualities for a combination of machine and material. # @@ -110,9 +107,6 @@ class QualityManager: basic_materials = self._getBasicMaterials(material_container) result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria) - if not result: - result = [ self._empty_quality_container ] - return result ## Find all quality changes for a machine. @@ -137,7 +131,8 @@ class QualityManager: # # \param global_container_stack \type{ContainerStack} the global machine definition # \param extruder_stacks \type{List[ContainerStack]} the list of extruder stacks - # \return \type{List[InstanceContainer]} the list of the matching qualities + # \return \type{List[InstanceContainer]} the list of the matching qualities. The quality profiles + # return come from the first extruder in the given list of extruders. def findAllUsableQualitiesForMachineAndExtruders(self, global_container_stack, extruder_stacks): global_machine_definition = global_container_stack.getBottom() diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index fd3f529351..86fc5335be 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -142,6 +142,7 @@ class CuraContainerRegistry(ContainerRegistry): # \return \type{Dict} dict with a 'status' key containing the string 'ok' or 'error', and a 'message' key # containing a message for the user def importProfile(self, file_name): + Logger.log("d", "Attempting to import profile %s", file_name) if not file_name: return { "status": "error", "message": catalog.i18nc("@info:status", "Failed to import profile from {0}: {1}", file_name, "Invalid path")} @@ -181,7 +182,7 @@ class CuraContainerRegistry(ContainerRegistry): for profile in profile_or_list: if profile_index >= 0: if len(machine_extruders) > profile_index: - extruder_id = machine_extruders[profile_index].getBottom().getId() + extruder_id = Application.getInstance().getMachineManager().getQualityDefinitionId(machine_extruders[profile_index].getBottom()) # Ensure the extruder profiles get non-conflicting names # NB: these are not user-facing if "extruder" in profile.getMetaData(): diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 8f7f311f47..0028ace4cd 100644 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -3,6 +3,7 @@ from PyQt5.QtCore import QObject, pyqtSlot, pyqtProperty, pyqtSignal from PyQt5.QtWidgets import QMessageBox +from UM import Util from UM.Application import Application from UM.Preferences import Preferences @@ -73,7 +74,7 @@ class MachineManager(QObject): self._auto_hotends_changed = {} self._material_incompatible_message = Message(catalog.i18nc("@info:status", - "The selected material is imcompatible with the selected machine or configuration.")) + "The selected material is incompatible with the selected machine or configuration.")) globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value) activeMaterialChanged = pyqtSignal() @@ -134,7 +135,7 @@ class MachineManager(QObject): definition_id = "fdmprinter" if self._global_container_stack.getMetaDataEntry("has_machine_materials", False): - definition_id = self._global_container_stack.getBottom().getId() + definition_id = self.activeQualityDefinitionId extruder_manager = ExtruderManager.getInstance() containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(type = "material", definition = definition_id, GUID = material_id) if containers: # New material ID is known @@ -145,9 +146,18 @@ class MachineManager(QObject): matching_extruder = extruder break - if matching_extruder and matching_extruder.findContainer({"type":"material"}).getMetaDataEntry("GUID") != material_id: + if matching_extruder and matching_extruder.findContainer({"type": "material"}).getMetaDataEntry("GUID") != material_id: # Save the material that needs to be changed. Multiple changes will be handled by the callback. - self._auto_materials_changed[str(index)] = containers[0].getId() + variant_container = matching_extruder.findContainer({"type": "variant"}) + if self._global_container_stack.getBottom().getMetaDataEntry("has_variants") and variant_container: + variant_id = self.getQualityVariantId(self._global_container_stack.getBottom(), variant_container) + for container in containers: + if container.getMetaDataEntry("variant") == variant_id: + self._auto_materials_changed[str(index)] = container.getId() + break + else: + # Just use the first result we found. + self._auto_materials_changed[str(index)] = containers[0].getId() self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback) else: Logger.log("w", "No material definition found for printer definition %s and GUID %s" % (definition_id, material_id)) @@ -223,6 +233,9 @@ class MachineManager(QObject): def _onActiveExtruderStackChanged(self): self.blurSettings.emit() # Ensure no-one has focus. + + old_active_container_stack = self._active_container_stack + if self._active_container_stack and self._active_container_stack != self._global_container_stack: self._active_container_stack.containersChanged.disconnect(self._onInstanceContainersChanged) self._active_container_stack.propertyChanged.disconnect(self._onPropertyChanged) @@ -232,8 +245,16 @@ class MachineManager(QObject): self._active_container_stack.propertyChanged.connect(self._onPropertyChanged) else: self._active_container_stack = self._global_container_stack + + old_active_stack_valid = self._active_stack_valid self._active_stack_valid = not self._checkStackForErrors(self._active_container_stack) - self.activeStackValidationChanged.emit() + if old_active_stack_valid != self._active_stack_valid: + self.activeStackValidationChanged.emit() + + if old_active_container_stack != self._active_container_stack: + # Many methods and properties related to the active quality actually depend + # on _active_container_stack. If it changes, then the properties change. + self.activeQualityChanged.emit() def _onInstanceContainersChanged(self, container): container_type = container.getMetaDataEntry("type") @@ -366,10 +387,20 @@ class MachineManager(QObject): top_container.removeInstance(key, postpone_emit=True) send_emits_containers.append(top_container) - for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()): - container = stack.getTop() - container.removeInstance(key, postpone_emit=True) - send_emits_containers.append(container) + linked = not self._global_container_stack.getProperty(key, "settable_per_extruder") or \ + self._global_container_stack.getProperty(key, "limit_to_extruder") != "-1" + + if not linked: + stack = ExtruderManager.getInstance().getActiveExtruderStack() + stacks = [stack] + else: + stacks = ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()) + + for stack in stacks: + if stack is not None: + container = stack.getTop() + container.removeInstance(key, postpone_emit=True) + send_emits_containers.append(container) for container in send_emits_containers: container.sendPostponedEmits() @@ -475,6 +506,17 @@ class MachineManager(QObject): @pyqtProperty(str, notify=activeQualityChanged) def activeQualityId(self): + if self._active_container_stack: + quality = self._active_container_stack.findContainer({"type": "quality_changes"}) + if quality and quality != self._empty_quality_changes_container: + return quality.getId() + quality = self._active_container_stack.findContainer({"type": "quality"}) + if quality: + return quality.getId() + return "" + + @pyqtProperty(str, notify=activeQualityChanged) + def globalQualityId(self): if self._global_container_stack: quality = self._global_container_stack.findContainer({"type": "quality_changes"}) if quality and quality != self._empty_quality_changes_container: @@ -486,16 +528,39 @@ class MachineManager(QObject): @pyqtProperty(str, notify = activeQualityChanged) def activeQualityType(self): - if self._global_container_stack: - quality = self._global_container_stack.findContainer(type = "quality") + if self._active_container_stack: + quality = self._active_container_stack.findContainer(type = "quality") if quality: return quality.getMetaDataEntry("quality_type") return "" + @pyqtProperty(bool, notify = activeQualityChanged) + def isActiveQualitySupported(self): + if self._active_container_stack: + quality = self._active_container_stack.findContainer(type = "quality") + if quality: + return Util.parseBool(quality.getMetaDataEntry("supported", True)) + return "" + + ## Get the Quality ID associated with the currently active extruder + # Note that this only returns the "quality", not the "quality_changes" + # \returns QualityID (string) if found, empty string otherwise + # \sa activeQualityId() + # \todo Ideally, this method would be named activeQualityId(), and the other one + # would be named something like activeQualityOrQualityChanges() for consistency + @pyqtProperty(str, notify = activeQualityChanged) + def activeQualityContainerId(self): + # We're using the active stack instead of the global stack in case the list of qualities differs per extruder + if self._global_container_stack: + quality = self._active_container_stack.findContainer(type = "quality") + if quality: + return quality.getId() + return "" + @pyqtProperty(str, notify = activeQualityChanged) def activeQualityChangesId(self): - if self._global_container_stack: - changes = self._global_container_stack.findContainer(type = "quality_changes") + if self._active_container_stack: + changes = self._active_container_stack.findContainer(type = "quality_changes") if changes: return changes.getId() return "" @@ -568,7 +633,7 @@ class MachineManager(QObject): candidate_quality = quality_manager.findQualityByQualityType(quality_type, quality_manager.getWholeMachineDefinition(machine_definition), [material_container]) - if not candidate_quality: + if not candidate_quality or candidate_quality.getId() == "empty_quality": # Fall back to a quality new_quality = quality_manager.findQualityByQualityType(None, quality_manager.getWholeMachineDefinition(machine_definition), diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py index 5b82ce9221..0f7c8c1ae7 100644 --- a/cura/Settings/ProfilesModel.py +++ b/cura/Settings/ProfilesModel.py @@ -28,5 +28,15 @@ class ProfilesModel(InstanceContainersModel): if global_container_stack is None: return [] + # Get the list of extruders and place the selected extruder at the front of the list. + extruder_manager = ExtruderManager.getInstance() + active_extruder = extruder_manager.getActiveExtruderStack() + extruder_stacks = extruder_manager.getActiveExtruderStacks() + if active_extruder in extruder_stacks: + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks + + # Fetch the list of useable qualities across all extruders. + # The actual list of quality profiles come from the first extruder in the extruder list. return QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, - ExtruderManager.getInstance().getActiveExtruderStacks()) + extruder_stacks) diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py index dcb6c698cf..db093126cc 100644 --- a/cura/Settings/QualityAndUserProfilesModel.py +++ b/cura/Settings/QualityAndUserProfilesModel.py @@ -25,9 +25,18 @@ class QualityAndUserProfilesModel(ProfilesModel): machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom()) quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition) - # Fetch the list of qualities + # Get the list of extruders and place the selected extruder at the front of the list. + extruder_manager = ExtruderManager.getInstance() + active_extruder = extruder_manager.getActiveExtruderStack() + extruder_stacks = extruder_manager.getActiveExtruderStacks() + if active_extruder in extruder_stacks: + extruder_stacks.remove(active_extruder) + extruder_stacks = [active_extruder] + extruder_stacks + + # Fetch the list of useable qualities across all extruders. + # The actual list of quality profiles come from the first extruder in the extruder list. quality_list = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, - ExtruderManager.getInstance().getActiveExtruderStacks()) + extruder_stacks) # Filter the quality_change by the list of available quality_types quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list]) diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py index 638a53e4b8..07191cd49d 100644 --- a/cura/Settings/QualitySettingsModel.py +++ b/cura/Settings/QualitySettingsModel.py @@ -110,9 +110,6 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): "definition": quality_changes_container.getDefinition().getId() } - if self._material_id and self._material_id != "empty_material": - criteria["material"] = self._material_id - quality_container = self._container_registry.findInstanceContainers(**criteria) if not quality_container: UM.Logger.log("w", "Could not find a quality container matching quality changes %s", quality_changes_container.getId()) @@ -120,7 +117,7 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): quality_container = quality_container[0] quality_type = quality_container.getMetaDataEntry("quality_type") - definition_id = quality_container.getDefinition().getId() + definition_id = UM.Application.getInstance().getMachineManager().getQualityDefinitionId(quality_container.getDefinition()) criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id} @@ -136,9 +133,9 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): new_criteria.pop("extruder") containers = self._container_registry.findInstanceContainers(**new_criteria) - if not containers: + if not containers and "material" in criteria: # Try again, this time without material - criteria.pop("material") + criteria.pop("material", None) containers = self._container_registry.findInstanceContainers(**criteria) if not containers: @@ -147,14 +144,16 @@ class QualitySettingsModel(UM.Qt.ListModel.ListModel): containers = self._container_registry.findInstanceContainers(**criteria) if not containers: - UM.Logger.log("Could not find any quality containers matching the search criteria %s" % str(criteria)) + UM.Logger.log("w", "Could not find any quality containers matching the search criteria %s" % str(criteria)) return if quality_changes_container: criteria = {"type": "quality_changes", "quality_type": quality_type, "definition": definition_id, "name": quality_changes_container.getName()} if self._extruder_definition_id != "": - criteria["extruder"] = self._extruder_definition_id - criteria["name"] = quality_changes_container.getName() + extruder_definitions = self._container_registry.findDefinitionContainers(id = self._extruder_definition_id) + if extruder_definitions: + criteria["extruder"] = UM.Application.getInstance().getMachineManager().getQualityDefinitionId(extruder_definitions[0]) + criteria["name"] = quality_changes_container.getName() else: criteria["extruder"] = None diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py index 8c10542069..a8cfcd8d80 100644 --- a/cura/Settings/SettingOverrideDecorator.py +++ b/cura/Settings/SettingOverrideDecorator.py @@ -61,6 +61,15 @@ class SettingOverrideDecorator(SceneNodeDecorator): def getActiveExtruder(self): return self._extruder_stack + ## Gets the currently active extruders position + # + # \return An extruder's position, or None if no position info is available. + def getActiveExtruderPosition(self): + containers = ContainerRegistry.getInstance().findContainers(id = self.getActiveExtruder()) + if containers: + container_stack = containers[0] + return container_stack.getMetaDataEntry("position", default=None) + def _onSettingChanged(self, instance, property_name): # Reminder: 'property' is a built-in function if property_name == "value": # Only reslice if the value has changed. Application.getInstance().getBackend().forceSlice() diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt index b5f7b35457..8452399346 100644 --- a/plugins/ChangeLogPlugin/ChangeLog.txt +++ b/plugins/ChangeLogPlugin/ChangeLog.txt @@ -7,7 +7,7 @@ The first thing you will notice is the speed. STL loading is now 10 to 20 times Machines with multiple extruders are now supported. If you’ve got the Ultimaker Original with the dual extrusion upgrade kit, we’ve got you covered. *Custom Machine Support -The new custom machine plug-in allows you to change machine settings with ease. That means it’s now much easier to use Cura with custom machines. +It’s now much easier to use Cura with custom machines. You can edit the machine settings when you load a new custom machine. *Improved Position Tool Place objects precisely where you want them by manually entering the values for the position. @@ -35,14 +35,17 @@ Cura now estimates print weight as well as length. Configurations from older installations of Cura 2.1 are automatically imported into the newest installation. *Slicing features -*Infill Improvements -We've introduced two new infill types: Tetrahedral and Cubic. They change along with the Z-axis for more uniform strength in all directions. Also, now you can change the density of the infill based on the distance from the top layers. Your objects print faster, use less material, and maintain the same strength. +*Infill Types +We've introduced two new infill types: Tetrahedral and Cubic. They change along with the Z-axis for more uniform strength in all directions. There are now 7 infill types to choose from. + +*Gradual Infill +Now you can change the density of the infill based on the distance from the top layers. Your objects print faster, use less material, while top surfaces have the same quality. *Set Acceleration and Jerk by Feature You can now set Jerk and Acceleration by feature-type (infill, walls, top/bottom, etc), for more precision. *Outer Wall Offset -Apply an offset to where the outer wall is printed for better surface quality when the outer wall line width is smaller than the nozzle size. +If your outer wall line width is smaller than your nozzle size, move the nozzle a bit inward when printing the outer wall, to improve surface quality. *Enhanced Combing The “No Skin” option allows you to comb over infill only to avoid scars on top surfaces. @@ -57,42 +60,45 @@ The Skin Overlap setting allows you to overlap the skin lines with the walls for Set the travel speed of the initial layer(s) to reduce risk of extruder pulling the print from the bed. *Support Interface -It is now possible to print a support bottom as well as a support roof. Support bottoms are placed where the support rests on the model. +It is now possible to print a support bottom as well as a support roof. Support bottoms are placed where the support rests on the model. Printing the support interface with PVA leads to improved surface quality. -*Bug fixes & minor changes -Deleting grouped objects works as intended again. -Duplicating groups works as intended again. -Bridging works as intended again. +*Bug fixes +Deleting grouped objects +Duplicating groups +Bridging +Drag and drop on the first run on Windows +Unretraction speeds +Bottom layer in Spiralize mode +Overlap Compensation +Retractions on Raft +Retractions now occur after each object printed in one-at-a-time mode. Rafts are no longer printed outside of build area. -Messages are now displayed 30 seconds instead of 10, making it less likely that certain messages are missed. -Drag and drop on the first run on windows works again. -You are now notified if you try to save to a locked SD card. -Combing is applied in more cases and results in better paths. -Infill thickness now supports Grid infill also for even multiples of the layer height. -Unretraction speeds are correct again. -Spiralize mode doesn’t spiralize the bottom layer any more. -Spiralize now spiralizes each part in a layer. -Support is no longer removed by unprintable thin parts of the model. -Support is now generated on each layer it’s supposed to. -Support doesn't go outside overhang areas any more. +Spiralize no longer only spiralizes the first printed segment only. Line distance is now the actual line distance. Enabling raft doesn’t influence at which height the model is sliced any more. Brim is now always printed just once. -Overlap Compensation works as intended again. -A raft now produces a reasonable amount of retractions. -No more string plume on top of one-at-a-time printed objects. -Engine log is now included in the application log. Support roofs now only occur just below overhang. -Brim is now also generated under the support. -Compensate overlapping wall parts now also works for inner walls. -Bed Level and Checkup procedures for UMO+ can now be done without re-adding machine. + +*Minor changes +Messages are now displayed 30 seconds instead of 10, making it less likely that certain messages are missed. +You are now notified if you try to save to a locked SD card. +Engine log is now included in the application log. Undo and Redo now work correctly with multiple operations. -The last used folder is now remembered (instead of defaulting to home folder) -You can now adjust the speed at which the bed is lowered each layer. -Settings shared between skirt and brim now also activate when brim is selected. +The last used folder is now remembered (instead of defaulting to home folder). +Import X3D files. Made it possible to add multiple Per Model Settings at once. +Bed Level and Checkup procedures for UMO+ can now be done without re-adding machine. +Combing is applied in more cases and results in better paths. +Infill thickness now supports Grid infill also for even multiples of the layer height. +Support is no longer removed by unprintable thin parts of the model. +Support is now generated on each layer it’s supposed to. +Support doesn't go outside overhang areas any more. Support doesn't remove brim around the object any more. +Brim is now also generated under the support. Draft shield and Ooze shield get their own brim or raft. +Settings shared between skirt and brim now also activate when brim is selected. +Compensate overlapping wall parts now also works for inner walls. +You can now adjust the speed at which the bed is lowered each layer. [2.1.3] diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index c24ea1cf76..f82e210524 100644 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -230,7 +230,7 @@ class CuraEngineBackend(Backend): if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible: if Application.getInstance().getPlatformActivity: self._error_message = Message(catalog.i18nc("@info:status", - "The selected material is imcompatible with the selected machine or configuration.")) + "The selected material is incompatible with the selected machine or configuration.")) self._error_message.show() self.backendStateChange.emit(BackendState.Error) else: diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index 210652720a..18c7fb1f5c 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -204,6 +204,9 @@ class StartSliceJob(Job): material_instance_container = stack.findContainer({"type": "material"}) for key in stack.getAllKeys(): + # Do not send settings that are not settable_per_extruder. + if stack.getProperty(key, "settable_per_extruder") == False: + continue setting = message.getMessage("settings").addRepeatedMessage("settings") setting.name = key if key == "material_guid" and material_instance_container: diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py index 695e90dbf8..3784d9d13e 100644 --- a/plugins/GCodeWriter/GCodeWriter.py +++ b/plugins/GCodeWriter/GCodeWriter.py @@ -46,7 +46,17 @@ class GCodeWriter(MeshWriter): def __init__(self): super().__init__() - def write(self, stream, node, mode = MeshWriter.OutputMode.TextMode): + ## Writes the g-code for the entire scene to a stream. + # + # Note that even though the function accepts a collection of nodes, the + # entire scene is always written to the file since it is not possible to + # separate the g-code for just specific nodes. + # + # \param stream The stream to write the g-code to. + # \param nodes This is ignored. + # \param mode Additional information on how to format the g-code in the + # file. This must always be text mode. + def write(self, stream, nodes, mode = MeshWriter.OutputMode.TextMode): if mode != MeshWriter.OutputMode.TextMode: Logger.log("e", "GCode Writer does not support non-text mode.") return False @@ -106,7 +116,7 @@ class GCodeWriter(MeshWriter): serialized = flat_global_container.serialize() data = {"global_quality": serialized} - for extruder in ExtruderManager.getInstance().getMachineExtruders(stack.getId()): + for extruder in sorted(ExtruderManager.getInstance().getMachineExtruders(stack.getId()), key = lambda k: k.getMetaDataEntry("position")): extruder_quality = extruder.findContainer({"type": "quality_changes"}) if not extruder_quality: Logger.log("w", "No extruder quality profile found, not writing quality for extruder %s to file!", extruder.getId()) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py index a90bb4b6d0..5834a5c606 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsTool.py @@ -84,11 +84,20 @@ class PerObjectSettingsTool(Tool): default_stack = ExtruderManager.getInstance().getExtruderStack(0) if default_stack: default_stack_id = default_stack.getId() - else: default_stack_id = global_container_stack.getId() + else: + default_stack_id = global_container_stack.getId() root_node = Application.getInstance().getController().getScene().getRoot() for node in DepthFirstIterator(root_node): - node.callDecoration("setActiveExtruder", default_stack_id) + new_stack_id = default_stack_id + # Get position of old extruder stack for this node + old_extruder_pos = node.callDecoration("getActiveExtruderPosition") + if old_extruder_pos is not None: + # Fetch current (new) extruder stack at position + new_stack = ExtruderManager.getInstance().getExtruderStack(old_extruder_pos) + if new_stack: + new_stack_id = new_stack.getId() + node.callDecoration("setActiveExtruder", new_stack_id) self._updateEnabled() diff --git a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py index efb7929327..8de1720107 100644 --- a/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py +++ b/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py @@ -1,3 +1,6 @@ +# Copyright (c) 2016 Ultimaker B.V. +# Cura is released under the terms of the AGPLv3 or higher. + import os.path from UM.Application import Application @@ -23,8 +26,18 @@ class RemovableDriveOutputDevice(OutputDevice): self.setPriority(1) self._writing = False + self._stream = None - def requestWrite(self, node, file_name = None, filter_by_machine = False): + ## Request the specified nodes to be written to the removable drive. + # + # \param nodes A collection of scene nodes that should be written to the + # removable drive. + # \param file_name \type{string} A suggestion for the file name to write + # to. If none is provided, a file name will be made from the names of the + # meshes. + # \param limit_mimetypes Should we limit the available MIME types to the + # MIME types available to the currently active machine? + def requestWrite(self, nodes, file_name = None, filter_by_machine = False): filter_by_machine = True # This plugin is indended to be used by machine (regardless of what it was told to do) if self._writing: raise OutputDeviceError.DeviceBusyError() @@ -49,15 +62,7 @@ class RemovableDriveOutputDevice(OutputDevice): extension = file_formats[0]["extension"] if file_name is None: - for n in BreadthFirstIterator(node): - if n.getMeshData(): - file_name = n.getName() - if file_name: - break - - if not file_name: - Logger.log("e", "Could not determine a proper file name when trying to write to %s, aborting", self.getName()) - raise OutputDeviceError.WriteRequestFailedError() + file_name = self._automaticFileName(nodes) if extension: # Not empty string. extension = "." + extension @@ -65,8 +70,9 @@ class RemovableDriveOutputDevice(OutputDevice): try: Logger.log("d", "Writing to %s", file_name) - stream = open(file_name, "wt") - job = WriteMeshJob(writer, stream, node, MeshWriter.OutputMode.TextMode) + # Using buffering greatly reduces the write time for many lines of gcode + self._stream = open(file_name, "wt", buffering = 1) + job = WriteMeshJob(writer, self._stream, nodes, MeshWriter.OutputMode.TextMode) job.setFileName(file_name) job.progress.connect(self._onProgress) job.finished.connect(self._onFinished) @@ -86,12 +92,33 @@ class RemovableDriveOutputDevice(OutputDevice): Logger.log("e", "Operating system would not let us write to %s: %s", file_name, str(e)) raise OutputDeviceError.WriteRequestFailedError(catalog.i18nc("@info:status", "Could not save to {0}: {1}").format(file_name, str(e))) from e + ## Generate a file name automatically for the specified nodes to be saved + # in. + # + # The name generated will be the name of one of the nodes. Which node that + # is can not be guaranteed. + # + # \param nodes A collection of nodes for which to generate a file name. + def _automaticFileName(self, nodes): + for root in nodes: + for child in BreadthFirstIterator(root): + if child.getMeshData(): + name = child.getName() + if name: + return name + raise OutputDeviceError.WriteRequestFailedError("Could not find a file name when trying to write to {device}.".format(device = self.getName())) + def _onProgress(self, job, progress): if hasattr(job, "_message"): job._message.setProgress(progress) self.writeProgress.emit(self, progress) def _onFinished(self, job): + if self._stream: + # Explicitly closing the stream flushes the write-buffer + self._stream.close() + self._stream = None + if hasattr(job, "_message"): job._message.hide() job._message = None diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py index 4838fe9b96..d98f631a2e 100644 --- a/plugins/USBPrinting/USBPrinterOutputDevice.py +++ b/plugins/USBPrinting/USBPrinterOutputDevice.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015 Ultimaker B.V. +# Copyright (c) 2016 Ultimaker B.V. # Cura is released under the terms of the AGPLv3 or higher. from .avr_isp import stk500v2, ispBase, intelHex @@ -426,7 +426,14 @@ class USBPrinterOutputDevice(PrinterOutputDevice): self._error_state = error self.onError.emit() - def requestWrite(self, node, file_name = None, filter_by_machine = False): + ## Request the current scene to be sent to a USB-connected printer. + # + # \param nodes A collection of scene nodes to send. This is ignored. + # \param file_name \type{string} A suggestion for a file name to write. + # This is ignored. + # \param filter_by_machine Whether to filter MIME types by machine. This + # is ignored. + def requestWrite(self, nodes, file_name = None, filter_by_machine = False): Application.getInstance().showPrintMonitor.emit(True) self.startPrint() diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 094735e50e..420113c4cb 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -276,7 +276,9 @@ "label": "Disallowed areas", "description": "A list of polygons with areas the print head is not allowed to enter.", "type": "polygons", - "default_value": [], + "default_value": + [ + ], "settable_per_mesh": false, "settable_per_extruder": false, "settable_per_meshgroup": false @@ -390,7 +392,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "machine_max_feedrate_x": { + "machine_max_feedrate_x": + { "label": "Maximum Speed X", "description": "The maximum speed for the motor of the X-direction.", "unit": "mm/s", @@ -400,7 +403,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_feedrate_y": { + "machine_max_feedrate_y": + { "label": "Maximum Speed Y", "description": "The maximum speed for the motor of the Y-direction.", "unit": "mm/s", @@ -410,7 +414,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_feedrate_z": { + "machine_max_feedrate_z": + { "label": "Maximum Speed Z", "description": "The maximum speed for the motor of the Z-direction.", "unit": "mm/s", @@ -420,7 +425,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_feedrate_e": { + "machine_max_feedrate_e": + { "label": "Maximum Feedrate", "description": "The maximum speed of the filament.", "unit": "mm/s", @@ -430,7 +436,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_x": { + "machine_max_acceleration_x": + { "label": "Maximum Acceleration X", "description": "Maximum acceleration for the motor of the X-direction", "unit": "mm/s²", @@ -440,7 +447,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_y": { + "machine_max_acceleration_y": + { "label": "Maximum Acceleration Y", "description": "Maximum acceleration for the motor of the Y-direction.", "unit": "mm/s²", @@ -450,7 +458,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_z": { + "machine_max_acceleration_z": + { "label": "Maximum Acceleration Z", "description": "Maximum acceleration for the motor of the Z-direction.", "unit": "mm/s²", @@ -460,7 +469,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_acceleration_e": { + "machine_max_acceleration_e": + { "label": "Maximum Filament Acceleration", "description": "Maximum acceleration for the motor of the filament.", "unit": "mm/s²", @@ -470,7 +480,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_acceleration": { + "machine_acceleration": + { "label": "Default Acceleration", "description": "The default acceleration of print head movement.", "unit": "mm/s²", @@ -480,7 +491,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_jerk_xy": { + "machine_max_jerk_xy": + { "label": "Default X-Y Jerk", "description": "Default jerk for movement in the horizontal plane.", "unit": "mm/s", @@ -490,7 +502,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_jerk_z": { + "machine_max_jerk_z": + { "label": "Default Z Jerk", "description": "Default jerk for the motor of the Z-direction.", "unit": "mm/s", @@ -500,7 +513,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_max_jerk_e": { + "machine_max_jerk_e": + { "label": "Default Filament Jerk", "description": "Default jerk for the motor of the filament.", "unit": "mm/s", @@ -510,7 +524,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "machine_minimum_feedrate": { + "machine_minimum_feedrate": + { "label": "Minimum Feedrate", "description": "The minimal movement speed of the print head.", "unit": "mm/s", @@ -579,7 +594,7 @@ "minimum_value": "0.0001", "minimum_value_warning": "0.75 * machine_nozzle_size", "maximum_value_warning": "2 * machine_nozzle_size", - "value":"line_width", + "value": "line_width", "default_value": 0.4, "type": "float", "settable_per_mesh": true, @@ -594,7 +609,7 @@ "minimum_value_warning": "0.75 * machine_nozzle_size if outer_inset_first else 0.1 * machine_nozzle_size", "maximum_value_warning": "2 * machine_nozzle_size", "default_value": 0.4, - "value":"wall_line_width", + "value": "wall_line_width", "type": "float", "settable_per_mesh": true }, @@ -607,7 +622,7 @@ "minimum_value_warning": "0.5 * machine_nozzle_size", "maximum_value_warning": "2 * machine_nozzle_size", "default_value": 0.4, - "value":"wall_line_width", + "value": "wall_line_width", "type": "float", "settable_per_mesh": true } @@ -761,7 +776,7 @@ "unit": "mm", "default_value": 0.8, "minimum_value": "0", - "minimum_value_warning": "3 * layer_height", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", "maximum_value": "machine_height", "type": "float", "value": "top_bottom_thickness", @@ -777,7 +792,7 @@ "maximum_value_warning": "100", "type": "int", "minimum_value_warning": "4", - "value": "0 if infill_sparse_density == 100 else math.ceil(round(top_thickness / layer_height, 4))", + "value": "0 if infill_sparse_density == 100 else math.ceil(round(top_thickness / resolveOrValue('layer_height'), 4))", "settable_per_mesh": true } } @@ -789,7 +804,7 @@ "unit": "mm", "default_value": 0.6, "minimum_value": "0", - "minimum_value_warning": "3 * layer_height", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", "type": "float", "value": "top_bottom_thickness", "maximum_value": "machine_height", @@ -804,7 +819,7 @@ "minimum_value_warning": "4", "default_value": 6, "type": "int", - "value": "999999 if infill_sparse_density == 100 else math.ceil(round(bottom_thickness / layer_height, 4))", + "value": "999999 if infill_sparse_density == 100 else math.ceil(round(bottom_thickness / resolveOrValue('layer_height'), 4))", "settable_per_mesh": true } } @@ -837,7 +852,7 @@ "maximum_value_warning": "machine_nozzle_size", "settable_per_mesh": true }, - "outer_inset_first": + "outer_inset_first": { "label": "Outer Before Inner Walls", "description": "Prints walls in order of outside to inside when enabled. This can help improve dimensional accuracy in X and Y when using a high viscosity plastic like ABS; however it can decrease outer surface print quality, especially on overhangs.", @@ -862,7 +877,8 @@ "settable_per_mesh": true, "children": { - "travel_compensate_overlapping_walls_0_enabled": { + "travel_compensate_overlapping_walls_0_enabled": + { "label": "Compensate Outer Wall Overlaps", "description": "Compensate the flow for parts of an outer wall being printed where there is already a wall in place.", "type": "bool", @@ -870,7 +886,8 @@ "value": "travel_compensate_overlapping_walls_enabled", "settable_per_mesh": true }, - "travel_compensate_overlapping_walls_x_enabled": { + "travel_compensate_overlapping_walls_x_enabled": + { "label": "Compensate Inner Wall Overlaps", "description": "Compensate the flow for parts of an inner wall being printed where there is already a wall in place.", "type": "bool", @@ -998,7 +1015,8 @@ } } }, - "skin_overlap": { + "skin_overlap": + { "label": "Skin Overlap Percentage", "description": "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin.", "unit": "%", @@ -1009,8 +1027,10 @@ "value": "5 if top_bottom_pattern != 'concentric' else 0", "enabled": "top_bottom_pattern != 'concentric'", "settable_per_mesh": true, - "children": { - "skin_overlap_mm": { + "children": + { + "skin_overlap_mm": + { "label": "Skin Overlap", "description": "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin.", "unit": "mm", @@ -1021,9 +1041,9 @@ "value": "skin_line_width * skin_overlap / 100 if top_bottom_pattern != 'concentric' else 0", "enabled": "top_bottom_pattern != 'concentric'", "settable_per_mesh": true - } - } - }, + } + } + }, "infill_wipe_dist": { "label": "Infill Wipe Distance", @@ -1044,10 +1064,10 @@ "unit": "mm", "type": "float", "default_value": 0.1, - "minimum_value": "layer_height", + "minimum_value": "resolveOrValue('layer_height')", "maximum_value_warning": "0.75 * machine_nozzle_size", - "maximum_value": "layer_height * 8", - "value": "layer_height", + "maximum_value": "resolveOrValue('layer_height') * 8", + "value": "resolveOrValue('layer_height')", "enabled": "infill_sparse_density > 0", "settable_per_mesh": true }, @@ -1071,7 +1091,7 @@ "type": "float", "default_value": 5.0, "minimum_value": "0.0001", - "minimum_value_warning": "3 * layer_height", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", "maximum_value_warning": "100", "enabled": "infill_sparse_density > 0 and gradual_infill_steps > 0", "settable_per_mesh": true @@ -1131,7 +1151,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "material_extrusion_cool_down_speed": { + "material_extrusion_cool_down_speed": + { "label": "Extrusion Cool Down Speed Modifier", "description": "The extra speed by which the nozzle cools while extruding. The same value is used to signify the heat up speed lost when heating up while extruding.", "unit": "°C/s", @@ -1144,12 +1165,13 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "material_bed_temperature": { + "material_bed_temperature": + { "label": "Build Plate Temperature", "description": "The temperature used for the heated build plate. Set at 0 to pre-heat the printer manually.", "unit": "°C", "type": "float", - "resolve": "sum(extruderValues('material_bed_temperature')) / len(extruderValues('material_bed_temperature'))", + "resolve": "max(extruderValues('material_bed_temperature'))", "default_value": 60, "minimum_value": "-273.15", "minimum_value_warning": "0", @@ -1159,7 +1181,8 @@ "settable_per_extruder": false, "settable_per_meshgroup": false }, - "material_diameter": { + "material_diameter": + { "label": "Diameter", "description": "Adjusts the diameter of the filament used. Match this value with the diameter of the used filament.", "unit": "mm", @@ -1171,7 +1194,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "material_flow": { + "material_flow": + { "label": "Flow", "description": "Flow compensation: the amount of material extruded is multiplied by this value.", "unit": "%", @@ -1182,7 +1206,8 @@ "maximum_value_warning": "150", "settable_per_mesh": true }, - "retraction_enable": { + "retraction_enable": + { "label": "Enable Retraction", "description": "Retract the filament when the nozzle is moving over a non-printed area. ", "type": "bool", @@ -1190,7 +1215,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_amount": { + "retraction_amount": + { "label": "Retraction Distance", "description": "The length of material retracted during a retraction move.", "unit": "mm", @@ -1202,7 +1228,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_speed": { + "retraction_speed": + { "label": "Retraction Speed", "description": "The speed at which the filament is retracted and primed during a retraction move.", "unit": "mm/s", @@ -1215,8 +1242,10 @@ "enabled": "retraction_enable", "settable_per_mesh": false, "settable_per_extruder": true, - "children": { - "retraction_retract_speed": { + "children": + { + "retraction_retract_speed": + { "label": "Retraction Retract Speed", "description": "The speed at which the filament is retracted during a retraction move.", "unit": "mm/s", @@ -1231,7 +1260,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_prime_speed": { + "retraction_prime_speed": + { "label": "Retraction Prime Speed", "description": "The speed at which the filament is primed during a retraction move.", "unit": "mm/s", @@ -1248,7 +1278,8 @@ } } }, - "retraction_extra_prime_amount": { + "retraction_extra_prime_amount": + { "label": "Retraction Extra Prime Amount", "description": "Some material can ooze away during a travel move, which can be compensated for here.", "unit": "mm³", @@ -1260,7 +1291,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_min_travel": { + "retraction_min_travel": + { "label": "Retraction Minimum Travel", "description": "The minimum distance of travel needed for a retraction to happen at all. This helps to get fewer retractions in a small area.", "unit": "mm", @@ -1273,7 +1305,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_count_max": { + "retraction_count_max": + { "label": "Maximum Retraction Count", "description": "This setting limits the number of retractions occurring within the minimum extrusion distance window. Further retractions within this window will be ignored. This avoids retracting repeatedly on the same piece of filament, as that can flatten the filament and cause grinding issues.", "default_value": 90, @@ -1284,7 +1317,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_extrusion_window": { + "retraction_extrusion_window": + { "label": "Minimum Extrusion Distance Window", "description": "The window in which the maximum retraction count is enforced. This value should be approximately the same as the retraction distance, so that effectively the number of times a retraction passes the same patch of material is limited.", "unit": "mm", @@ -1297,7 +1331,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_hop_enabled": { + "retraction_hop_enabled": + { "label": "Z Hop when Retracted", "description": "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate.", "type": "bool", @@ -1306,7 +1341,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_hop_only_when_collides": { + "retraction_hop_only_when_collides": + { "label": "Z Hop Only Over Printed Parts", "description": "Only perform a Z Hop when moving over printed parts which cannot be avoided by horizontal motion by Avoid Printed Parts when Traveling.", "type": "bool", @@ -1315,7 +1351,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "retraction_hop": { + "retraction_hop": + { "label": "Z Hop Height", "description": "The height difference when performing a Z Hop.", "unit": "mm", @@ -1404,7 +1441,8 @@ } } }, - "retraction_hop_after_extruder_switch": { + "retraction_hop_after_extruder_switch": + { "label": "Z Hop After Extruder Switch", "description": "After the machine switched from one extruder to the other, the build plate is lowered to create clearance between the nozzle and the print. This prevents the nozzle from leaving oozed material on the outside of a print.", "type": "bool", @@ -1587,7 +1625,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "speed_layer_0": { + "speed_layer_0": + { "label": "Initial Layer Speed", "description": "The speed for the initial layer. A lower value is advised to improve adhesion to the build plate.", "unit": "mm/s", @@ -1628,7 +1667,8 @@ } } }, - "skirt_brim_speed": { + "skirt_brim_speed": + { "label": "Skirt/Brim Speed", "description": "The speed at which the skirt and brim are printed. Normally this is done at the initial layer speed, but sometimes you might want to print the skirt or brim at a different speed.", "unit": "mm/s", @@ -1664,7 +1704,7 @@ "default_value": 2, "resolve": "sum(extruderValues('speed_slowdown_layers')) / len(extruderValues('speed_slowdown_layers'))", "minimum_value": "0", - "maximum_value_warning": "1.0 / layer_height", + "maximum_value_warning": "1.0 / resolveOrValue('layer_height')", "settable_per_mesh": false, "settable_per_extruder": false }, @@ -1691,9 +1731,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - - - "acceleration_enabled": { + "acceleration_enabled": + { "label": "Enable Acceleration Control", "description": "Enables adjusting the print head acceleration. Increasing the accelerations can reduce printing time at the cost of print quality.", "type": "bool", @@ -1702,7 +1741,8 @@ "settable_per_mesh": false, "settable_per_extruder": false }, - "acceleration_print": { + "acceleration_print": + { "label": "Print Acceleration", "description": "The acceleration with which printing happens.", "unit": "mm/s²", @@ -1713,8 +1753,10 @@ "default_value": 3000, "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true, - "children": { - "acceleration_infill": { + "children": + { + "acceleration_infill": + { "label": "Infill Acceleration", "description": "The acceleration with which infill is printed.", "unit": "mm/s²", @@ -1727,7 +1769,8 @@ "enabled": "resolveOrValue('acceleration_enabled') and infill_sparse_density > 0", "settable_per_mesh": true }, - "acceleration_wall": { + "acceleration_wall": + { "label": "Wall Acceleration", "description": "The acceleration with which the walls are printed.", "unit": "mm/s²", @@ -1739,8 +1782,10 @@ "value": "acceleration_print", "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true, - "children": { - "acceleration_wall_0": { + "children": + { + "acceleration_wall_0": + { "label": "Outer Wall Acceleration", "description": "The acceleration with which the outermost walls are printed.", "unit": "mm/s²", @@ -1753,7 +1798,8 @@ "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true }, - "acceleration_wall_x": { + "acceleration_wall_x": + { "label": "Inner Wall Acceleration", "description": "The acceleration with which all inner walls are printed.", "unit": "mm/s²", @@ -1768,7 +1814,8 @@ } } }, - "acceleration_topbottom": { + "acceleration_topbottom": + { "label": "Top/Bottom Acceleration", "description": "The acceleration with which top/bottom layers are printed.", "unit": "mm/s²", @@ -1781,7 +1828,8 @@ "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true }, - "acceleration_support": { + "acceleration_support": + { "label": "Support Acceleration", "description": "The acceleration with which the support structure is printed.", "unit": "mm/s²", @@ -1795,8 +1843,10 @@ "settable_per_mesh": false, "limit_to_extruder": "support_extruder_nr", "settable_per_extruder": true, - "children": { - "acceleration_support_infill": { + "children": + { + "acceleration_support_infill": + { "label": "Support Infill Acceleration", "description": "The acceleration with which the infill of support is printed.", "unit": "mm/s²", @@ -1811,7 +1861,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "acceleration_support_interface": { + "acceleration_support_interface": + { "label": "Support Interface Acceleration", "description": "The acceleration with which the roofs and bottoms of support are printed. Printing them at lower accelerations can improve overhang quality.", "unit": "mm/s²", @@ -1828,7 +1879,8 @@ } } }, - "acceleration_prime_tower": { + "acceleration_prime_tower": + { "label": "Prime Tower Acceleration", "description": "The acceleration with which the prime tower is printed.", "unit": "mm/s²", @@ -1843,7 +1895,8 @@ } } }, - "acceleration_travel": { + "acceleration_travel": + { "label": "Travel Acceleration", "description": "The acceleration with which travel moves are made.", "unit": "mm/s²", @@ -1856,7 +1909,8 @@ "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": false }, - "acceleration_layer_0": { + "acceleration_layer_0": + { "label": "Initial Layer Acceleration", "description": "The acceleration for the initial layer.", "unit": "mm/s²", @@ -1868,7 +1922,8 @@ "maximum_value_warning": "10000", "enabled": "resolveOrValue('acceleration_enabled')", "settable_per_mesh": true, - "children": { + "children": + { "acceleration_print_layer_0": { "label": "Initial Layer Print Acceleration", @@ -1900,7 +1955,8 @@ } } }, - "acceleration_skirt_brim": { + "acceleration_skirt_brim": + { "label": "Skirt/Brim Acceleration", "description": "The acceleration with which the skirt and brim are printed. Normally this is done with the initial layer acceleration, but sometimes you might want to print the skirt or brim at a different acceleration.", "unit": "mm/s²", @@ -1914,8 +1970,8 @@ "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, - - "jerk_enabled": { + "jerk_enabled": + { "label": "Enable Jerk Control", "description": "Enables adjusting the jerk of print head when the velocity in the X or Y axis changes. Increasing the jerk can reduce printing time at the cost of print quality.", "type": "bool", @@ -1924,7 +1980,8 @@ "settable_per_mesh": false, "settable_per_extruder": false }, - "jerk_print": { + "jerk_print": + { "label": "Print Jerk", "description": "The maximum instantaneous velocity change of the print head.", "unit": "mm/s", @@ -1935,8 +1992,10 @@ "default_value": 20, "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true, - "children": { - "jerk_infill": { + "children": + { + "jerk_infill": + { "label": "Infill Jerk", "description": "The maximum instantaneous velocity change with which infill is printed.", "unit": "mm/s", @@ -1949,7 +2008,8 @@ "enabled": "resolveOrValue('jerk_enabled') and infill_sparse_density > 0", "settable_per_mesh": true }, - "jerk_wall": { + "jerk_wall": + { "label": "Wall Jerk", "description": "The maximum instantaneous velocity change with which the walls are printed.", "unit": "mm/s", @@ -1961,8 +2021,10 @@ "value": "jerk_print", "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true, - "children": { - "jerk_wall_0": { + "children": + { + "jerk_wall_0": + { "label": "Outer Wall Jerk", "description": "The maximum instantaneous velocity change with which the outermost walls are printed.", "unit": "mm/s", @@ -1975,7 +2037,8 @@ "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true }, - "jerk_wall_x": { + "jerk_wall_x": + { "label": "Inner Wall Jerk", "description": "The maximum instantaneous velocity change with which all inner walls are printed.", "unit": "mm/s", @@ -1990,7 +2053,8 @@ } } }, - "jerk_topbottom": { + "jerk_topbottom": + { "label": "Top/Bottom Jerk", "description": "The maximum instantaneous velocity change with which top/bottom layers are printed.", "unit": "mm/s", @@ -2003,7 +2067,8 @@ "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true }, - "jerk_support": { + "jerk_support": + { "label": "Support Jerk", "description": "The maximum instantaneous velocity change with which the support structure is printed.", "unit": "mm/s", @@ -2017,8 +2082,10 @@ "settable_per_mesh": false, "settable_per_extruder": true, "limit_to_extruder": "support_extruder_nr", - "children": { - "jerk_support_infill": { + "children": + { + "jerk_support_infill": + { "label": "Support Infill Jerk", "description": "The maximum instantaneous velocity change with which the infill of support is printed.", "unit": "mm/s", @@ -2033,7 +2100,8 @@ "settable_per_mesh": false, "settable_per_extruder": true }, - "jerk_support_interface": { + "jerk_support_interface": + { "label": "Support Interface Jerk", "description": "The maximum instantaneous velocity change with which the roofs and bottoms of support are printed.", "unit": "mm/s", @@ -2050,7 +2118,8 @@ } } }, - "jerk_prime_tower": { + "jerk_prime_tower": + { "label": "Prime Tower Jerk", "description": "The maximum instantaneous velocity change with which the prime tower is printed.", "unit": "mm/s", @@ -2065,7 +2134,8 @@ } } }, - "jerk_travel": { + "jerk_travel": + { "label": "Travel Jerk", "description": "The maximum instantaneous velocity change with which travel moves are made.", "unit": "mm/s", @@ -2078,7 +2148,8 @@ "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": false }, - "jerk_layer_0": { + "jerk_layer_0": + { "label": "Initial Layer Jerk", "description": "The print maximum instantaneous velocity change for the initial layer.", "unit": "mm/s", @@ -2090,7 +2161,8 @@ "maximum_value_warning": "50", "enabled": "resolveOrValue('jerk_enabled')", "settable_per_mesh": true, - "children": { + "children": + { "jerk_print_layer_0": { "label": "Initial Layer Print Jerk", @@ -2122,7 +2194,8 @@ } } }, - "jerk_skirt_brim": { + "jerk_skirt_brim": + { "label": "Skirt/Brim Jerk", "description": "The maximum instantaneous velocity change with which the skirt and brim are printed.", "unit": "mm/s", @@ -2159,7 +2232,8 @@ }, "default_value": "all", "resolve": "'noskin' if 'noskin' in extruderValues('retraction_combing') else ('all' if 'all' in extruderValues('retraction_combing') else 'off')", - "settable_per_mesh": true + "settable_per_mesh": true, + "settable_per_extruder": false }, "travel_avoid_other_parts": { @@ -2283,8 +2357,8 @@ "type": "int", "default_value": 2, "minimum_value": "1", - "maximum_value_warning": "10 / layer_height", - "value": "max(1, int(math.floor((cool_fan_full_at_height - resolveOrValue('layer_height_0')) / layer_height) + 2))", + "maximum_value_warning": "10 / resolveOrValue('layer_height')", + "value": "max(1, int(math.floor((cool_fan_full_at_height - resolveOrValue('layer_height_0')) / resolveOrValue('layer_height')) + 2))", "settable_per_mesh": false, "settable_per_extruder": true } @@ -2353,7 +2427,7 @@ "everywhere": "Everywhere" }, "default_value": "everywhere", - "resolve": "'everywhere' if 'everywhere' in extruderValues('support_type') else buildplate", + "resolve": "'everywhere' if 'everywhere' in extruderValues('support_type') else 'buildplate'", "enabled": "support_enable", "settable_per_mesh": false, "settable_per_extruder": false @@ -2415,7 +2489,8 @@ "limit_to_extruder": "support_infill_extruder_nr", "settable_per_mesh": false, "settable_per_extruder": true, - "children": { + "children": + { "support_line_distance": { "label": "Support Line Distance", @@ -2490,11 +2565,13 @@ "enabled": "support_enable", "settable_per_mesh": true }, - "support_xy_overrides_z": { + "support_xy_overrides_z": + { "label": "Support Distance Priority", "description": "Whether the Support X/Y Distance overrides the Support Z Distance or vice versa. When X/Y overrides Z the X/Y distance can push away the support from the model, influencing the actual Z distance to the overhang. We can disable this by not applying the X/Y distance around overhangs.", "type": "enum", - "options": { + "options": + { "xy_overrides_z": "X/Y overrides Z", "z_overrides_xy": "Z overrides X/Y" }, @@ -2503,7 +2580,8 @@ "enabled": "support_enable", "settable_per_mesh": true }, - "support_xy_distance_overhang": { + "support_xy_distance_overhang": + { "label": "Minimum Support X/Y Distance", "description": "Distance of the support structure from the overhang in the X/Y directions. ", "unit": "mm", @@ -2573,7 +2651,7 @@ "type": "float", "default_value": 1, "minimum_value": "0", - "minimum_value_warning": "3 * layer_height", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", "maximum_value_warning": "10", "limit_to_extruder": "support_interface_extruder_nr", "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", @@ -2588,7 +2666,7 @@ "type": "float", "default_value": 1, "minimum_value": "0", - "minimum_value_warning": "3 * layer_height", + "minimum_value_warning": "3 * resolveOrValue('layer_height')", "maximum_value_warning": "10", "value": "extruderValue(support_interface_extruder_nr, 'support_interface_height')", "limit_to_extruder": "support_interface_extruder_nr", @@ -2604,7 +2682,7 @@ "default_value": 1, "value": "extruderValue(support_interface_extruder_nr, 'support_interface_height')", "minimum_value": "0", - "minimum_value_warning": "min(3 * layer_height, extruderValue(support_interface_extruder_nr, 'support_bottom_stair_step_height'))", + "minimum_value_warning": "min(3 * resolveOrValue('layer_height'), extruderValue(support_interface_extruder_nr, 'support_bottom_stair_step_height'))", "maximum_value_warning": "10", "limit_to_extruder": "support_interface_extruder_nr", "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable", @@ -2891,7 +2969,8 @@ "settable_per_extruder": true, "limit_to_extruder": "adhesion_extruder_nr" }, - "layer_0_z_overlap": { + "layer_0_z_overlap": + { "label": "Initial Layer Z Overlap", "description": "Make the first and second layer of the model overlap in the Z direction to compensate for the filament lost in the airgap. All models above the first model layer will be shifted down by this amount.", "unit": "mm", @@ -2925,7 +3004,7 @@ "unit": "mm", "type": "float", "default_value": 0.1, - "value": "layer_height", + "value": "resolveOrValue('layer_height')", "minimum_value": "0.001", "minimum_value_warning": "0.04", "maximum_value_warning": "0.75 * extruderValue(adhesion_extruder_nr, 'machine_nozzle_size')", @@ -2973,7 +3052,7 @@ "unit": "mm", "type": "float", "default_value": 0.15, - "value": "layer_height * 1.5", + "value": "resolveOrValue('layer_height') * 1.5", "minimum_value": "0.001", "minimum_value_warning": "0.04", "maximum_value_warning": "0.75 * extruderValue(adhesion_extruder_nr, 'raft_interface_line_width')", @@ -3129,7 +3208,8 @@ } } }, - "raft_acceleration": { + "raft_acceleration": + { "label": "Raft Print Acceleration", "description": "The acceleration with which the raft is printed.", "unit": "mm/s²", @@ -3142,8 +3222,10 @@ "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('acceleration_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr", - "children": { - "raft_surface_acceleration": { + "children": + { + "raft_surface_acceleration": + { "label": "Raft Top Print Acceleration", "description": "The acceleration with which the top raft layers are printed.", "unit": "mm/s²", @@ -3157,7 +3239,8 @@ "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, - "raft_interface_acceleration": { + "raft_interface_acceleration": + { "label": "Raft Middle Print Acceleration", "description": "The acceleration with which the middle raft layer is printed.", "unit": "mm/s²", @@ -3171,7 +3254,8 @@ "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, - "raft_base_acceleration": { + "raft_base_acceleration": + { "label": "Raft Base Print Acceleration", "description": "The acceleration with which the base raft layer is printed.", "unit": "mm/s²", @@ -3187,7 +3271,8 @@ } } }, - "raft_jerk": { + "raft_jerk": + { "label": "Raft Print Jerk", "description": "The jerk with which the raft is printed.", "unit": "mm/s", @@ -3200,8 +3285,10 @@ "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')", "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr", - "children": { - "raft_surface_jerk": { + "children": + { + "raft_surface_jerk": + { "label": "Raft Top Print Jerk", "description": "The jerk with which the top raft layers are printed.", "unit": "mm/s", @@ -3215,7 +3302,8 @@ "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, - "raft_interface_jerk": { + "raft_interface_jerk": + { "label": "Raft Middle Print Jerk", "description": "The jerk with which the middle raft layer is printed.", "unit": "mm/s", @@ -3229,7 +3317,8 @@ "settable_per_mesh": false, "limit_to_extruder": "adhesion_extruder_nr" }, - "raft_base_jerk": { + "raft_base_jerk": + { "label": "Raft Base Print Jerk", "description": "The jerk with which the base raft layer is printed.", "unit": "mm/s", @@ -3245,7 +3334,8 @@ } } }, - "raft_fan_speed": { + "raft_fan_speed": + { "label": "Raft Fan Speed", "description": "The fan speed for the raft.", "unit": "%", @@ -3336,7 +3426,8 @@ "enabled": "support_enable and machine_extruder_count > 1", "settable_per_mesh": false, "settable_per_extruder": false, - "children": { + "children": + { "support_infill_extruder_nr": { "label": "Support Infill Extruder", @@ -3681,13 +3772,15 @@ "settable_per_mesh": false, "settable_per_extruder": false }, - "conical_overhang_enabled": { + "conical_overhang_enabled": + { "label": "Make Overhang Printable", "description": "Change the geometry of the printed model such that minimal support is required. Steep overhangs will become shallow overhangs. Overhanging areas will drop down to become more vertical.", "type": "bool", "default_value": false }, - "conical_overhang_angle": { + "conical_overhang_angle": + { "label": "Maximum Model Angle", "description": "The maximum angle of overhangs after the they have been made printable. At a value of 0° all overhangs are replaced by a piece of model connected to the build plate, 90° will not change the model in any way.", "unit": "°", diff --git a/resources/i18n/de/cura.po b/resources/i18n/de/cura.po index 5865f8ebed..7dd480bf81 100644 --- a/resources/i18n/de/cura.po +++ b/resources/i18n/de/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Einige Einstellungswerte unterscheiden sich von den im Profil gespeicherten Werten.\n\nKlicken Sie, um den Profilmanager zu öffnen." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "G-Code ändern" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Nachbearbeitung" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Erweiterung, die eine Nachbearbeitung von Skripten ermöglicht, die von Benutzern erstellt wurden." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Plugin Nachbearbeitung" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Skripts Nachbearbeitung" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Ein Skript hinzufügen" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Einstellungen" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Aktive Skripts Nachbearbeitung ändern" diff --git a/resources/i18n/es/cura.po b/resources/i18n/es/cura.po index 8bee1f3c52..ef82e6be05 100644 --- a/resources/i18n/es/cura.po +++ b/resources/i18n/es/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Algunos valores son distintos de los valores almacenados en el perfil.\n\nHaga clic para abrir el administrador de perfiles." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "Modificar GCode" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Posprocesamiento" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Extensión que permite el posprocesamiento de las secuencias de comandos creadas por los usuarios." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Complemento de posprocesamiento" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Secuencias de comandos de posprocesamiento" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Añadir secuencia de comando" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Ajustes" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Cambia las secuencias de comandos de posprocesamiento." diff --git a/resources/i18n/fi/cura.po b/resources/i18n/fi/cura.po index 04b196c6ce..c96b976be0 100644 --- a/resources/i18n/fi/cura.po +++ b/resources/i18n/fi/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Jotkut asetusten arvot eroavat profiiliin tallennetuista arvoista.\n\nAvaa profiilin hallinta napsauttamalla." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "Muokkaa GCode-arvoa" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Jälkikäsittely" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Lisäosa, jonka avulla käyttäjät voivat luoda komentosarjoja jälkikäsittelyä varten" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Jälkikäsittelylisäosa" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Jälkikäsittelykomentosarjat" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Lisää komentosarja" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Asetukset" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Muuta aktiivisia jälkikäsittelykomentosarjoja" diff --git a/resources/i18n/fr/cura.po b/resources/i18n/fr/cura.po index c895cd41f5..ea3ed63c31 100644 --- a/resources/i18n/fr/cura.po +++ b/resources/i18n/fr/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Certaines valeurs de paramètre sont différentes des valeurs enregistrées dans le profil.\n\nCliquez pour ouvrir le gestionnaire de profils." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "Modifier le G-Code" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Post-traitement" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Extension qui permet le post-traitement des scripts créés par l'utilisateur" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Plug-in de post-traitement" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Scripts de post-traitement" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Ajouter un script" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Paramètres" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Modifier les scripts de post-traitement actifs" diff --git a/resources/i18n/it/cura.po b/resources/i18n/it/cura.po index 2483c09260..92ecd581cd 100644 --- a/resources/i18n/it/cura.po +++ b/resources/i18n/it/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Alcuni valori di impostazione sono diversi dai valori memorizzati nel profilo.\n\nFare clic per aprire la gestione profili." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "Modifica il codice G" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Post-elaborazione" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Estensione che consente la post-elaborazione degli script creati da utente" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Plug-in di post-elaborazione" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Script di post-elaborazione" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Aggiungi uno script" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Impostazioni" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Modifica script di post-elaborazione attivi" diff --git a/resources/i18n/nl/cura.po b/resources/i18n/nl/cura.po index 3dd69d0a0d..ee566a61ad 100644 --- a/resources/i18n/nl/cura.po +++ b/resources/i18n/nl/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Sommige instellingswaarden zijn anders dan de waarden die in het profiel zijn opgeslagen.\n\nKlik om het profielbeheer te openen." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "G-code wijzigen" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Nabewerken" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Uitbreiding waarmee door de gebruiker gemaakte scripts voor nabewerking kunnen worden gebruikt" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Invoegtoepassing voor nabewerking" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Scripts voor nabewerking" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Een script toevoegen" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Instellingen" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Actieve scripts voor nabewerking wijzigen" diff --git a/resources/i18n/tr/cura.po b/resources/i18n/tr/cura.po index 940ffb3e5e..511ed43c47 100644 --- a/resources/i18n/tr/cura.po +++ b/resources/i18n/tr/cura.po @@ -2294,3 +2294,42 @@ msgid "" "\n" "Click to open the profile manager." msgstr "Bazı ayar değerleri profilinizde saklanan değerlerden farklıdır.\n\nProfil yöneticisini açmak için tıklayın." + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.py:24 +msgid "Modify G-Code" +msgstr "GCode Değiştir" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:12 +msgctxt "@label" +msgid "Post Processing" +msgstr "Son İşleme" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/__init__.py:16 +msgctxt "Description of plugin" +msgid "Extension that allows for user created scripts for post processing" +msgstr "Kullanıcının oluşturduğu komut dosyalarına son işleme için izin veren uzantı" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18 +msgctxt "@title:window" +msgid "Post Processing Plugin" +msgstr "Son İşleme Uzantısı" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:49 +msgctxt "@label" +msgid "Post Processing Scripts" +msgstr "Son İşleme Dosyaları" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:218 +msgctxt "@action" +msgid "Add a script" +msgstr "Dosya ekle" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:264 +msgctxt "@label" +msgid "Settings" +msgstr "Ayarlar" + +#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:456 +msgctxt "@info:tooltip" +msgid "Change active post-processing scripts" +msgstr "Etkin son işleme dosyalarını değiştir" diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml index 6556f7e56a..59e4848851 100644 --- a/resources/qml/Cura.qml +++ b/resources/qml/Cura.qml @@ -666,10 +666,13 @@ UM.MainWindow for(var i in fileUrls) { UM.MeshFileHandler.readLocalFile(fileUrls[i]) - } - var meshName = backgroundItem.getMeshName(fileUrl.toString()) - backgroundItem.hasMesh(decodeURIComponent(meshName)) + if (i == fileUrls.length - 1) + { + var meshName = backgroundItem.getMeshName(fileUrls.toString()) + backgroundItem.hasMesh(decodeURIComponent(meshName)) + } + } } } diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml index 1cb97153dd..0b2c7a5ae2 100644 --- a/resources/qml/Menus/ProfileMenu.qml +++ b/resources/qml/Menus/ProfileMenu.qml @@ -42,7 +42,7 @@ Menu { text: model.name checkable: true - checked: Cura.MachineManager.activeQualityId == model.id + checked: Cura.MachineManager.globalQualityId == model.id exclusiveGroup: group onTriggered: Cura.MachineManager.setActiveQuality(model.id) } diff --git a/resources/qml/MonitorButton.qml b/resources/qml/MonitorButton.qml index 607d0a24ca..4a68e532d1 100644 --- a/resources/qml/MonitorButton.qml +++ b/resources/qml/MonitorButton.qml @@ -161,6 +161,10 @@ Rectangle visible: showProgress; indeterminate: { + if(!printerConnected) + { + return false; + } switch(Cura.MachineManager.printerOutputDevices[0].jobState) { case "pausing": diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index f727af5a10..adbad802ef 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2015 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Copyright (c) 2016 Ultimaker B.V. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml index f2937c04e6..78553bb37f 100644 --- a/resources/qml/Preferences/MachinesPage.qml +++ b/resources/qml/Preferences/MachinesPage.qml @@ -1,5 +1,5 @@ // Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 @@ -229,7 +229,7 @@ UM.ManagementPage } } - UM.I18nCatalog { id: catalog; name: "uranium"; } + UM.I18nCatalog { id: catalog; name: "cura"; } UM.ConfirmRemoveDialog { diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml index 3fd4ca6a5a..2c3bb0a2eb 100644 --- a/resources/qml/Preferences/ProfileTab.qml +++ b/resources/qml/Preferences/ProfileTab.qml @@ -38,8 +38,8 @@ Tab anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.right: parent.right text: styleData.value - font.strikeout: styleData.column == 1 && quality == Cura.MachineManager.activeQualityId && setting.user_value != "" - font.italic: setting.profile_value_source == "quality_changes" || (quality == Cura.MachineManager.activeQualityId && setting.user_value != "") + font.strikeout: styleData.column == 1 && quality == Cura.MachineManager.globalQualityId && setting.user_value != "" + font.italic: setting.profile_value_source == "quality_changes" || (quality == Cura.MachineManager.globalQualityId && setting.user_value != "") opacity: font.strikeout ? 0.5 : 1 color: styleData.textColor elide: Text.ElideRight @@ -65,7 +65,7 @@ Tab { role: "user_value" title: catalog.i18nc("@title:column", "Current"); - visible: quality == Cura.MachineManager.activeQualityId + visible: quality == Cura.MachineManager.globalQualityId width: parent.width * 0.18 delegate: itemDelegate } diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 42c055486a..621ecb3184 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -1,5 +1,5 @@ -// Copyright (c) 2015 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Copyright (c) 2016 Ultimaker B.V. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 @@ -208,7 +208,7 @@ UM.ManagementPage anchors.right: parent.right anchors.bottom: parent.bottom - currentIndex: ExtruderManager.activeExtruderIndex + 1; + currentIndex: ExtruderManager.extruderCount > 0 ? ExtruderManager.activeExtruderIndex + 1 : 0 ProfileTab { @@ -235,7 +235,7 @@ UM.ManagementPage Item { - UM.I18nCatalog { id: catalog; name: "uranium"; } + UM.I18nCatalog { id: catalog; name: "cura"; } UM.ConfirmRemoveDialog { diff --git a/resources/qml/Preferences/ReadOnlySpinBox.qml b/resources/qml/Preferences/ReadOnlySpinBox.qml index 8692f55708..90314ac323 100644 --- a/resources/qml/Preferences/ReadOnlySpinBox.qml +++ b/resources/qml/Preferences/ReadOnlySpinBox.qml @@ -1,5 +1,5 @@ // Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 diff --git a/resources/qml/Preferences/ReadOnlyTextArea.qml b/resources/qml/Preferences/ReadOnlyTextArea.qml index 080aec5f53..1c457eb5d2 100644 --- a/resources/qml/Preferences/ReadOnlyTextArea.qml +++ b/resources/qml/Preferences/ReadOnlyTextArea.qml @@ -1,5 +1,5 @@ // Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 diff --git a/resources/qml/Preferences/ReadOnlyTextField.qml b/resources/qml/Preferences/ReadOnlyTextField.qml index 2ff0357020..a34c39cde3 100644 --- a/resources/qml/Preferences/ReadOnlyTextField.qml +++ b/resources/qml/Preferences/ReadOnlyTextField.qml @@ -1,5 +1,5 @@ // Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Cura is released under the terms of the AGPLv3 or higher. // Different than the name suggests, it is not always read-only. import QtQuick 2.1 diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index e68df94122..cada8adfda 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -1,5 +1,5 @@ // Copyright (c) 2016 Ultimaker B.V. -// Uranium is released under the terms of the AGPLv3 or higher. +// Cura is released under the terms of the AGPLv3 or higher. import QtQuick 2.1 import QtQuick.Controls 1.1 diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml index 036f1283cc..22815c8b66 100644 --- a/resources/qml/Sidebar.qml +++ b/resources/qml/Sidebar.qml @@ -186,20 +186,21 @@ Rectangle Label { id: settingsModeLabel - text: catalog.i18nc("@label:listbox","Print Setup"); + text: catalog.i18nc("@label:listbox", "Print Setup"); anchors.left: parent.left anchors.leftMargin: UM.Theme.getSize("default_margin").width; anchors.top: headerSeparator.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width/100*45 + width: parent.width * 0.45 - 2 * UM.Theme.getSize("default_margin").width font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") visible: !monitoringPrint + elide: Text.ElideRight } Rectangle { id: settingsModeSelection - width: parent.width/100*55 + width: parent.width * 0.55 height: UM.Theme.getSize("sidebar_header_mode_toggle").height anchors.right: parent.right anchors.rightMargin: UM.Theme.getSize("default_margin").width @@ -262,7 +263,7 @@ Rectangle anchors.leftMargin: UM.Theme.getSize("default_margin").width; anchors.top: headerSeparator.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height - width: parent.width/100*45 + width: parent.width * 0.45 font: UM.Theme.getFont("large") color: UM.Theme.getColor("text") visible: monitoringPrint diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index 3e36cfbaa0..20ee5f66cd 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -244,7 +244,7 @@ Column } } - property var valueWarning: Cura.MachineManager.activeQualityId == "empty_quality" + property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported enabled: !extrudersList.visible || base.currentExtruderIndex > -1 @@ -292,7 +292,7 @@ Column height: UM.Theme.getSize("setting_control").height tooltip: Cura.MachineManager.activeQualityName style: UM.Theme.styles.sidebar_header_button - property var valueWarning: Cura.MachineManager.activeQualityId == "empty_quality" + property var valueWarning: ! Cura.MachineManager.isActiveQualitySupported menu: ProfileMenu { } UM.SimpleButton