Browse Source

Merge branch 'feature_intent' of github.com:Ultimaker/Cura into feature_intent_container_tree

Jaime van Kessel 5 years ago
parent
commit
f7d61e1e24

+ 1 - 0
cura/BuildVolume.py

@@ -65,6 +65,7 @@ class BuildVolume(SceneNode):
         self._origin_mesh = None  # type: Optional[MeshData]
         self._origin_line_length = 20
         self._origin_line_width = 1.5
+        self._enabled = False
 
         self._grid_mesh = None   # type: Optional[MeshData]
         self._grid_shader = None

+ 4 - 0
cura/OAuth2/AuthorizationRequestHandler.py

@@ -25,6 +25,10 @@ class AuthorizationRequestHandler(BaseHTTPRequestHandler):
         self.authorization_callback = None  # type: Optional[Callable[[AuthenticationResponse], None]]
         self.verification_code = None  # type: Optional[str]
 
+    # CURA-6609: Some browser seems to issue a HEAD instead of GET request as the callback.
+    def do_HEAD(self) -> None:
+        self.do_GET()
+
     def do_GET(self) -> None:
         # Extract values from the query string.
         parsed_url = urlparse(self.path)

+ 2 - 1
plugins/MachineSettingsAction/MachineSettingsAction.py

@@ -9,6 +9,7 @@ import UM.i18n
 from UM.FlameProfiler import pyqtSlot
 from UM.Settings.ContainerRegistry import ContainerRegistry
 from UM.Settings.DefinitionContainer import DefinitionContainer
+from UM.Util import parseBool
 
 from cura.MachineAction import MachineAction
 from cura.Settings.CuraStackBuilder import CuraStackBuilder
@@ -92,7 +93,7 @@ class MachineSettingsAction(MachineAction):
             return
 
         definition = global_stack.getDefinition()
-        if definition.getProperty("machine_gcode_flavor", "value") != "UltiGCode" or definition.getMetaDataEntry("has_materials", False):
+        if definition.getProperty("machine_gcode_flavor", "value") != "UltiGCode" or parseBool(definition.getMetaDataEntry("has_materials", False)):
             # In other words: only continue for the UM2 (extended), but not for the UM2+
             return
 

+ 1 - 1
plugins/UM3NetworkPrinting/plugin.json

@@ -2,7 +2,7 @@
     "name": "Ultimaker Network Connection",
     "author": "Ultimaker B.V.",
     "description": "Manages network connections to Ultimaker networked printers.",
-    "version": "1.0.1",
+    "version": "2.0.0",
     "api": "6.0",
     "i18n-catalog": "cura"
 }

BIN
plugins/UM3NetworkPrinting/resources/png/Ultimaker S3.png


+ 39 - 0
plugins/UM3NetworkPrinting/src/Messages/MaterialSyncMessage.py

@@ -0,0 +1,39 @@
+# Copyright (c) 2019 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from typing import TYPE_CHECKING
+
+from UM import i18nCatalog
+from UM.Message import Message
+
+
+if TYPE_CHECKING:
+    from ..UltimakerNetworkedPrinterOutputDevice import UltimakerNetworkedPrinterOutputDevice
+
+
+I18N_CATALOG = i18nCatalog("cura")
+
+
+## Message shown when sending material files to cluster host.
+class MaterialSyncMessage(Message):
+
+    # Singleton used to prevent duplicate messages of this type at the same time.
+    __is_visible = False
+
+    def __init__(self, device: "UltimakerNetworkedPrinterOutputDevice") -> None:
+        super().__init__(
+            text = I18N_CATALOG.i18nc("@info:status", "Cura has detected material profiles that were not yet installed "
+                                                      "on the host printer of group {0}.", device.name),
+            title = I18N_CATALOG.i18nc("@info:title", "Sending materials to printer"),
+            lifetime = 10,
+            dismissable = True
+        )
+
+    def show(self) -> None:
+        if MaterialSyncMessage.__is_visible:
+            return
+        super().show()
+        MaterialSyncMessage.__is_visible = True
+
+    def hide(self, send_signal = True) -> None:
+        super().hide(send_signal)
+        MaterialSyncMessage.__is_visible = False

+ 1 - 1
plugins/UM3NetworkPrinting/src/Models/ClusterMaterial.py → plugins/UM3NetworkPrinting/src/Models/Http/ClusterMaterial.py

@@ -1,6 +1,6 @@
 # Copyright (c) 2019 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
-from .BaseModel import BaseModel
+from ..BaseModel import BaseModel
 
 
 class ClusterMaterial(BaseModel):

+ 2 - 2
plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterMaterialStation.py

@@ -8,13 +8,13 @@ from .ClusterPrinterMaterialStationSlot import ClusterPrinterMaterialStationSlot
 
 ## Class representing the data of a Material Station in the cluster.
 class ClusterPrinterMaterialStation(BaseModel):
-    
+
     ## Creates a new Material Station status.
     #  \param status: The status of the material station.
     #  \param: supported: Whether the material station is supported on this machine or not.
     #  \param material_slots: The active slots configurations of this material station.
     def __init__(self, status: str, supported: bool = False,
-                 material_slots: Union[None, Dict[str, Any], ClusterPrinterMaterialStationSlot] = None,
+                 material_slots: List[Union[ClusterPrinterMaterialStationSlot, Dict[str, Any]]] = None,
                  **kwargs) -> None:
         self.status = status
         self.supported = supported

+ 23 - 17
plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrinterStatus.py

@@ -13,6 +13,7 @@ from .ClusterBuildPlate import ClusterBuildPlate
 from .ClusterPrintCoreConfiguration import ClusterPrintCoreConfiguration
 from .ClusterPrinterMaterialStation import ClusterPrinterMaterialStation
 from .ClusterPrinterMaterialStationSlot import ClusterPrinterMaterialStationSlot
+from .ClusterPrinterConfigurationMaterial import ClusterPrinterConfigurationMaterial
 from ..BaseModel import BaseModel
 
 
@@ -80,9 +81,9 @@ class ClusterPrinterStatus(BaseModel):
         model.setCameraUrl(QUrl("http://{}:8080/?action=stream".format(self.ip_address)))
 
         # Set the possible configurations based on whether a Material Station is present or not.
-        if self.material_station is not None and len(self.material_station.material_slots):
+        if self.material_station and self.material_station.material_slots:
             self._updateAvailableConfigurations(model)
-        if self.configuration is not None:
+        if self.configuration:
             self._updateActiveConfiguration(model)
 
     def _updateActiveConfiguration(self, model: PrinterOutputModel) -> None:
@@ -92,31 +93,36 @@ class ClusterPrinterStatus(BaseModel):
             configuration.updateConfigurationModel(extruder_config)
 
     def _updateAvailableConfigurations(self, model: PrinterOutputModel) -> None:
-        # Generate a list of configurations for the left extruder.
-        left_configurations = [slot for slot in self.material_station.material_slots if self._isSupportedConfiguration(
-            slot = slot,
-            extruder_index = 0
-        )]
-        # Generate a list of configurations for the right extruder.
-        right_configurations = [slot for slot in self.material_station.material_slots if self._isSupportedConfiguration(
-            slot = slot,
-            extruder_index = 1
-        )]
-        # Create a list of all available combinations between both print cores.
         available_configurations = [self._createAvailableConfigurationFromPrinterConfiguration(
             left_slot = left_slot,
             right_slot = right_slot,
             printer_configuration = model.printerConfiguration
-        ) for left_slot, right_slot in product(left_configurations, right_configurations)]
-        # Let Cura know which available configurations there are.
+        ) for left_slot, right_slot in product(self._getSlotsForExtruder(0), self._getSlotsForExtruder(1))]
         model.setAvailableConfigurations(available_configurations)
 
+    ## Create a list of Material Station slots for the given extruder index.
+    #  Returns a list with a single empty material slot if none are found to ensure we don't miss configurations.
+    def _getSlotsForExtruder(self, extruder_index: int) -> List[ClusterPrinterMaterialStationSlot]:
+        if not self.material_station:  # typing guard
+            return []
+        slots = [slot for slot in self.material_station.material_slots if self._isSupportedConfiguration(
+            slot = slot,
+            extruder_index = extruder_index
+        )]
+        return slots or [self._createEmptyMaterialSlot(extruder_index)]
+
     ## Check if a configuration is supported in order to make it selectable by the user.
     #  We filter out any slot that is not supported by the extruder index, print core type or if the material is empty.
     @staticmethod
     def _isSupportedConfiguration(slot: ClusterPrinterMaterialStationSlot, extruder_index: int) -> bool:
-        return slot.extruder_index == extruder_index and slot.compatible and slot.material and \
-               slot.material_remaining != 0
+        return slot.extruder_index == extruder_index and slot.compatible
+
+    ## Create an empty material slot with a fake empty material.
+    @staticmethod
+    def _createEmptyMaterialSlot(extruder_index: int) -> ClusterPrinterMaterialStationSlot:
+        empty_material = ClusterPrinterConfigurationMaterial(guid = "", material = "empty", brand = "", color = "")
+        return ClusterPrinterMaterialStationSlot(slot_index = 0, extruder_index = extruder_index,
+                                                 compatible = True, material_remaining = 0, material = empty_material)
 
     @staticmethod
     def _createAvailableConfigurationFromPrinterConfiguration(left_slot: ClusterPrinterMaterialStationSlot,

+ 0 - 0
plugins/UM3NetworkPrinting/src/Models/Http/__init__.py


Some files were not shown because too many files changed in this diff