Browse Source

Merge branch 'master' into CURA-4451_not_support_container

ChrisTerBeke 7 years ago
parent
commit
c679f4aa6b

+ 2 - 2
cura/CameraAnimation.py

@@ -12,8 +12,8 @@ class CameraAnimation(QVariantAnimation):
     def __init__(self, parent = None):
         super().__init__(parent)
         self._camera_tool = None
-        self.setDuration(500)
-        self.setEasingCurve(QEasingCurve.InOutQuad)
+        self.setDuration(300)
+        self.setEasingCurve(QEasingCurve.OutQuad)
 
     def setCameraTool(self, camera_tool):
         self._camera_tool = camera_tool

+ 21 - 2
cura/CuraApplication.py

@@ -393,6 +393,7 @@ class CuraApplication(QtApplication):
     showDiscardOrKeepProfileChanges = pyqtSignal()
 
     def discardOrKeepProfileChanges(self):
+        has_user_interaction = False
         choice = Preferences.getInstance().getValue("cura/choice_on_profile_override")
         if choice == "always_discard":
             # don't show dialog and DISCARD the profile
@@ -403,8 +404,10 @@ class CuraApplication(QtApplication):
         else:
             # ALWAYS ask whether to keep or discard the profile
             self.showDiscardOrKeepProfileChanges.emit()
+            has_user_interaction = True
+        return has_user_interaction
 
-    #sidebarSimpleDiscardOrKeepProfileChanges = pyqtSignal()
+    onDiscardOrKeepProfileChangesClosed = pyqtSignal()  # Used to notify other managers that the dialog was closed
 
     @pyqtSlot(str)
     def discardOrKeepProfileChangesClosed(self, option):
@@ -412,9 +415,25 @@ class CuraApplication(QtApplication):
             global_stack = self.getGlobalContainerStack()
             for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
                 extruder.getTop().clear()
-
             global_stack.getTop().clear()
 
+        # if the user decided to keep settings then the user settings should be re-calculated and validated for errors
+        # before slicing. To ensure that slicer uses right settings values
+        elif option == "keep":
+            global_stack = self.getGlobalContainerStack()
+            for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
+                user_extruder_container = extruder.getTop()
+                if user_extruder_container:
+                    user_extruder_container.update()
+
+            user_global_container = global_stack.getTop()
+            if user_global_container:
+                user_global_container.update()
+
+        # notify listeners that quality has changed (after user selected discard or keep)
+        self.onDiscardOrKeepProfileChangesClosed.emit()
+        self.getMachineManager().activeQualityChanged.emit()
+
     @pyqtSlot(int)
     def messageBoxClosed(self, button):
         if self._message_box_callback:

+ 49 - 16
cura/Settings/MachineManager.py

@@ -47,6 +47,10 @@ class MachineManager(QObject):
         self._active_container_stack = None     # type: CuraContainerStack
         self._global_container_stack = None     # type: GlobalStack
 
+        # Used to store the new containers until after confirming the dialog
+        self._new_variant_container = None
+        self._new_material_container = None
+
         self._error_check_timer = QTimer()
         self._error_check_timer.setInterval(250)
         self._error_check_timer.setSingleShot(True)
@@ -58,6 +62,7 @@ class MachineManager(QObject):
         self._instance_container_timer.timeout.connect(self.__onInstanceContainersChanged)
 
         Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
+
         ##  When the global container is changed, active material probably needs to be updated.
         self.globalContainerChanged.connect(self.activeMaterialChanged)
         self.globalContainerChanged.connect(self.activeVariantChanged)
@@ -84,6 +89,9 @@ class MachineManager(QObject):
         ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeStackChanged)
         self.activeStackChanged.connect(self.activeStackValueChanged)
 
+        # when a user closed dialog check if any delayed material or variant changes need to be applied
+        Application.getInstance().onDiscardOrKeepProfileChangesClosed.connect(self._executeDelayedActiveContainerStackChanges)
+
         Preferences.getInstance().addPreference("cura/active_machine", "")
 
         self._global_event_keys = set()
@@ -109,7 +117,7 @@ class MachineManager(QObject):
                                               "The selected material is incompatible with the selected machine or configuration."),
                                                 title = catalog.i18nc("@info:title", "Incompatible Material"))
 
-    globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value)
+    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()
     activeVariantChanged = pyqtSignal()
     activeQualityChanged = pyqtSignal()
@@ -333,6 +341,7 @@ class MachineManager(QObject):
         self.activeQualityChanged.emit()
         self.activeVariantChanged.emit()
         self.activeMaterialChanged.emit()
+        self._updateStacksHaveErrors()  # Prevents unwanted re-slices after changing machine
         self._error_check_timer.start()
 
     def _onInstanceContainersChanged(self, container):
@@ -349,6 +358,8 @@ class MachineManager(QObject):
     @pyqtSlot(str)
     def setActiveMachine(self, stack_id: str) -> None:
         self.blurSettings.emit()  # Ensure no-one has focus.
+        self._cancelDelayedActiveContainerStackChanges()
+
         containers = ContainerRegistry.getInstance().findContainerStacks(id = stack_id)
         if containers:
             Application.getInstance().setGlobalContainerStack(containers[0])
@@ -747,7 +758,7 @@ class MachineManager(QObject):
             self.blurSettings.emit()
             old_material.nameChanged.disconnect(self._onMaterialNameChanged)
 
-            self._active_container_stack.material = material_container
+            self._new_material_container = material_container   # self._active_container_stack will be updated with a delay
             Logger.log("d", "Active material changed")
 
             material_container.nameChanged.connect(self._onMaterialNameChanged)
@@ -801,13 +812,13 @@ class MachineManager(QObject):
             old_material = self._active_container_stack.material
             if old_variant:
                 self.blurSettings.emit()
-                self._active_container_stack.variant = containers[0]
+                self._new_variant_container = containers[0]  # self._active_container_stack will be updated with a delay
                 Logger.log("d", "Active variant changed to {active_variant_id}".format(active_variant_id = containers[0].getId()))
                 preferred_material_name = None
                 if old_material:
                     preferred_material_name = old_material.getName()
-
-                self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), self._global_container_stack, containers[0], preferred_material_name).id)
+                preferred_material_id = self._updateMaterialContainer(self._global_container_stack.getBottom(), self._global_container_stack, containers[0], preferred_material_name).id
+                self.setActiveMaterial(preferred_material_id)
             else:
                 Logger.log("w", "While trying to set the active variant, no variant was found to replace.")
 
@@ -854,19 +865,44 @@ class MachineManager(QObject):
                 self._replaceQualityOrQualityChangesInStack(stack, stack_quality, postpone_emit=True)
                 self._replaceQualityOrQualityChangesInStack(stack, stack_quality_changes, postpone_emit=True)
 
-            # Send emits that are postponed in replaceContainer.
-            # Here the stacks are finished replacing and every value can be resolved based on the current state.
-            for setting_info in new_quality_settings_list:
-                setting_info["stack"].sendPostponedEmits()
-
             # Connect to onQualityNameChanged
             for stack in name_changed_connect_stacks:
                 stack.nameChanged.connect(self._onQualityNameChanged)
 
-            if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
-                self._askUserToKeepOrClearCurrentSettings()
+            has_user_interaction = False
 
-            self.activeQualityChanged.emit()
+            if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
+                # Show the keep/discard user settings dialog
+                has_user_interaction = Application.getInstance().discardOrKeepProfileChanges()
+            else:
+                # If the user doesn't have any of adjusted settings then slicing will be triggered by emit()
+                # Send emits that are postponed in replaceContainer.
+                # Here the stacks are finished replacing and every value can be resolved based on the current state.
+                for setting_info in new_quality_settings_list:
+                    setting_info["stack"].sendPostponedEmits()
+
+            if not has_user_interaction:
+                self._executeDelayedActiveContainerStackChanges()
+                self.activeQualityChanged.emit()
+
+    ##  Used to update material and variant in the active container stack with a delay.
+    #   This delay prevents the stack from triggering a lot of signals (eventually resulting in slicing)
+    #   before the user decided to keep or discard any of their changes using the dialog.
+    #   The Application.onDiscardOrKeepProfileChangesClosed signal triggers this method.
+    def _executeDelayedActiveContainerStackChanges(self):
+        if self._new_material_container is not None:
+            self._active_container_stack.material = self._new_material_container
+            self._new_material_container = None
+
+        if self._new_variant_container is not None:
+            self._active_container_stack.variant = self._new_variant_container
+            self._new_variant_container = None
+
+    ##  Cancel set changes for material and variant in the active container stack.
+    #   Used for ignoring any changes when switching between printers (setActiveMachine)
+    def _cancelDelayedActiveContainerStackChanges(self):
+        self._new_material_container = None
+        self._new_variant_container = None
 
     ##  Determine the quality and quality changes settings for the current machine for a quality name.
     #
@@ -985,9 +1021,6 @@ class MachineManager(QObject):
             stack.qualityChanges.nameChanged.connect(self._onQualityNameChanged)
         self._onQualityNameChanged()
 
-    def _askUserToKeepOrClearCurrentSettings(self):
-        Application.getInstance().discardOrKeepProfileChanges()
-
     @pyqtProperty(str, notify = activeVariantChanged)
     def activeVariantName(self) -> str:
         if self._active_container_stack:

+ 1 - 0
plugins/CuraEngineBackend/ProcessSlicedLayersJob.py

@@ -240,3 +240,4 @@ class ProcessSlicedLayersJob(Job):
             else:
                 if self._progress_message:
                     self._progress_message.hide()
+

+ 9 - 0
resources/definitions/fdmprinter.def.json

@@ -3956,6 +3956,15 @@
                     "limit_to_extruder": "support_infill_extruder_nr",
                     "enabled": "support_enable and support_use_towers",
                     "settable_per_mesh": true
+                },
+                "remove_empty_first_layers":
+                {
+                    "label": "Remove Empty First Layers",
+                    "description": "Remove empty layers beneath the first printed layer if they are present.",
+                    "type": "bool",
+                    "default_value": true,
+                    "settable_per_mesh": false,
+                    "settable_per_extruder": false
                 }
             }
         },