Browse Source

Merge remote-tracking branch 'origin/master' into CURA-5059_reset_icon_visibility

Lipu Fei 7 years ago
parent
commit
40d3e09d90

+ 26 - 31
cura/BuildVolume.py

@@ -111,6 +111,9 @@ class BuildVolume(SceneNode):
         # but it does not update the disallowed areas after material change
         Application.getInstance().getMachineManager().activeStackChanged.connect(self._onStackChanged)
 
+        # Enable and disable extruder
+        Application.getInstance().getMachineManager().extruderChanged.connect(self.updateNodeBoundaryCheck)
+
         # list of settings which were updated
         self._changed_settings_since_last_rebuild = []
 
@@ -217,30 +220,26 @@ class BuildVolume(SceneNode):
                 group_nodes.append(node)  # Keep list of affected group_nodes
 
             if node.callDecoration("isSliceable") or node.callDecoration("isGroup"):
-                node._outside_buildarea = False
-                bbox = node.getBoundingBox()
+                if node.collidesWithBbox(build_volume_bounding_box):
+                    node.setOutsideBuildArea(True)
+                    continue
+
+                if node.collidesWithArea(self.getDisallowedAreas()):
+                    node.setOutsideBuildArea(True)
+                    continue
 
-                # Mark the node as outside the build volume if the bounding box test fails.
-                if build_volume_bounding_box.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection:
-                    node._outside_buildarea = True
+                # Mark the node as outside build volume if the set extruder is disabled
+                extruder_position = node.callDecoration("getActiveExtruderPosition")
+                if not self._global_container_stack.extruders[extruder_position].isEnabled:
+                    node.setOutsideBuildArea(True)
                     continue
 
-                convex_hull = node.callDecoration("getConvexHull")
-                if convex_hull:
-                    if not convex_hull.isValid():
-                        return
-                    # Check for collisions between disallowed areas and the object
-                    for area in self.getDisallowedAreas():
-                        overlap = convex_hull.intersectsPolygon(area)
-                        if overlap is None:
-                            continue
-                        node._outside_buildarea = True
-                        continue
+                node.setOutsideBuildArea(False)
 
         # Group nodes should override the _outside_buildarea property of their children.
         for group_node in group_nodes:
             for child_node in group_node.getAllChildren():
-                child_node._outside_buildarea = group_node._outside_buildarea
+                child_node.setOutsideBuildArea(group_node.isOutsideBuildArea)
 
     ##  Update the outsideBuildArea of a single node, given bounds or current build volume
     def checkBoundsAndUpdate(self, node: CuraSceneNode, bounds: Optional[AxisAlignedBox] = None):
@@ -260,24 +259,20 @@ class BuildVolume(SceneNode):
             build_volume_bounding_box = bounds
 
         if node.callDecoration("isSliceable") or node.callDecoration("isGroup"):
-            bbox = node.getBoundingBox()
+            if node.collidesWithBbox(build_volume_bounding_box):
+                node.setOutsideBuildArea(True)
+                return
 
-            # Mark the node as outside the build volume if the bounding box test fails.
-            if build_volume_bounding_box.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection:
+            if node.collidesWithArea(self.getDisallowedAreas()):
+                node.setOutsideBuildArea(True)
+                return
+
+            # Mark the node as outside build volume if the set extruder is disabled
+            extruder_position = node.callDecoration("getActiveExtruderPosition")
+            if not self._global_container_stack.extruders[extruder_position].isEnabled:
                 node.setOutsideBuildArea(True)
                 return
 
-            convex_hull = self.callDecoration("getConvexHull")
-            if convex_hull:
-                if not convex_hull.isValid():
-                    return
-                # Check for collisions between disallowed areas and the object
-                for area in self.getDisallowedAreas():
-                    overlap = convex_hull.intersectsPolygon(area)
-                    if overlap is None:
-                        continue
-                    node.setOutsideBuildArea(True)
-                    return
             node.setOutsideBuildArea(False)
 
     ##  Recalculates the build volume & disallowed areas.

+ 4 - 0
cura/CuraApplication.py

@@ -1605,6 +1605,8 @@ class CuraApplication(QtApplication):
                 fixed_nodes.append(node_)
         arranger = Arrange.create(fixed_nodes = fixed_nodes)
         min_offset = 8
+        default_extruder_position = self.getMachineManager().defaultExtruderPosition
+        default_extruder_id = self._global_container_stack.extruders[default_extruder_position].getId()
 
         for original_node in nodes:
 
@@ -1670,6 +1672,8 @@ class CuraApplication(QtApplication):
 
             op = AddSceneNodeOperation(node, scene.getRoot())
             op.push()
+
+            node.callDecoration("setActiveExtruder", default_extruder_id)
             scene.sceneChanged.emit(node)
 
         self.fileCompleted.emit(filename)

+ 6 - 5
cura/Machines/MaterialGroup.py

@@ -1,9 +1,10 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 
+from typing import List
+from cura.Machines.MaterialNode import MaterialNode #For type checking.
 
-#
-# A MaterialGroup represents a group of material InstanceContainers that are derived from a single material profile.
+## A MaterialGroup represents a group of material InstanceContainers that are derived from a single material profile.
 # The main InstanceContainer which has the ID of the material profile file name is called the "root_material". For
 # example: "generic_abs" is the root material (ID) of "generic_abs_ultimaker3" and "generic_abs_ultimaker3_AA_0.4",
 # and "generic_abs_ultimaker3" and "generic_abs_ultimaker3_AA_0.4" are derived materials of "generic_abs".
@@ -17,10 +18,10 @@
 class MaterialGroup:
     __slots__ = ("name", "root_material_node", "derived_material_node_list")
 
-    def __init__(self, name: str):
+    def __init__(self, name: str, root_material_node: MaterialNode):
         self.name = name
-        self.root_material_node = None
-        self.derived_material_node_list = []
+        self.root_material_node = root_material_node
+        self.derived_material_node_list = [] #type: List[MaterialNode]
 
     def __str__(self) -> str:
         return "%s[%s]" % (self.__class__.__name__, self.name)

+ 7 - 9
cura/Machines/MaterialManager.py

@@ -72,29 +72,27 @@ class MaterialManager(QObject):
 
     def initialize(self):
         # Find all materials and put them in a matrix for quick search.
-        material_metadata_list = self._container_registry.findContainersMetadata(type = "material")
+        material_metadatas = {metadata["id"]: metadata for metadata in self._container_registry.findContainersMetadata(type = "material")}
 
         self._material_group_map = dict()
 
         # Map #1
         #    root_material_id -> MaterialGroup
-        for material_metadata in material_metadata_list:
-            material_id = material_metadata["id"]
+        for material_id, material_metadata in material_metadatas.items():
             # We don't store empty material in the lookup tables
             if material_id == "empty_material":
                 continue
 
             root_material_id = material_metadata.get("base_file")
             if root_material_id not in self._material_group_map:
-                self._material_group_map[root_material_id] = MaterialGroup(root_material_id)
+                self._material_group_map[root_material_id] = MaterialGroup(root_material_id, MaterialNode(material_metadatas[root_material_id]))
             group = self._material_group_map[root_material_id]
 
-            # We only add root materials here
-            if material_id == root_material_id:
-                group.root_material_node = MaterialNode(material_metadata)
-            else:
+            #Store this material in the group of the appropriate root material.
+            if material_id != root_material_id:
                 new_node = MaterialNode(material_metadata)
                 group.derived_material_node_list.append(new_node)
+
         # Order this map alphabetically so it's easier to navigate in a debugger
         self._material_group_map = OrderedDict(sorted(self._material_group_map.items(), key = lambda x: x[0]))
 
@@ -179,7 +177,7 @@ class MaterialManager(QObject):
         #    "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer
         # Construct the "machine" -> "variant" -> "root material ID" -> specific material InstanceContainer
         self._diameter_machine_variant_material_map = dict()
-        for material_metadata in material_metadata_list:
+        for material_metadata in material_metadatas.values():
             # We don't store empty material in the lookup tables
             if material_metadata["id"] == "empty_material":
                 continue

+ 0 - 2
cura/Machines/Models/BrandMaterialsModel.py

@@ -54,9 +54,7 @@ class BrandMaterialsModel(ListModel):
         self._material_manager = CuraApplication.getInstance().getMaterialManager()
 
         self._machine_manager.globalContainerChanged.connect(self._update)
-        self._extruder_manager.activeExtruderChanged.connect(self._update)
         self._material_manager.materialsUpdated.connect(self._update)
-
         self._update()
 
     def setExtruderPosition(self, position: int):

+ 0 - 2
cura/Machines/Models/GenericMaterialsModel.py

@@ -16,9 +16,7 @@ class GenericMaterialsModel(BaseMaterialsModel):
         self._material_manager = CuraApplication.getInstance().getMaterialManager()
 
         self._machine_manager.globalContainerChanged.connect(self._update)
-        self._extruder_manager.activeExtruderChanged.connect(self._update)
         self._material_manager.materialsUpdated.connect(self._update)
-
         self._update()
 
     def _update(self):

+ 11 - 9
cura/Machines/Models/NozzleModel.py

@@ -21,28 +21,30 @@ class NozzleModel(ListModel):
         self.addRoleName(self.HotendNameRole, "hotend_name")
         self.addRoleName(self.ContainerNodeRole, "container_node")
 
-        Application.getInstance().globalContainerStackChanged.connect(self._update)
-        Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update)
-        Application.getInstance().getMachineManager().activeStackChanged.connect(self._update)
-        Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update)
+        self._application = Application.getInstance()
+        self._machine_manager = self._application.getMachineManager()
+        self._variant_manager = self._application.getVariantManager()
+
+        self._machine_manager.globalContainerChanged.connect(self._update)
+        self._update()
 
     def _update(self):
         Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
 
         self.items.clear()
 
-        variant_manager = Application.getInstance()._variant_manager
-        active_global_stack = Application.getInstance().getMachineManager()._global_container_stack
-        if active_global_stack is None:
+        global_stack = self._machine_manager.activeMachine
+        if global_stack is None:
             self.setItems([])
             return
 
-        has_variants = parseBool(active_global_stack.getMetaDataEntry("has_variants", False))
+        has_variants = parseBool(global_stack.getMetaDataEntry("has_variants", False))
         if not has_variants:
             self.setItems([])
             return
 
-        variant_node_dict = variant_manager.getVariantNodes(active_global_stack)
+        from cura.Machines.VariantManager import VariantType
+        variant_node_dict = self._variant_manager.getVariantNodes(global_stack, VariantType.NOZZLE)
         if not variant_node_dict:
             self.setItems([])
             return

+ 2 - 1
cura/Machines/Models/QualityProfilesDropDownMenuModel.py

@@ -29,7 +29,7 @@ class QualityProfilesDropDownMenuModel(ListModel):
         self.addRoleName(self.QualityTypeRole, "quality_type")
         self.addRoleName(self.LayerHeightRole, "layer_height")
         self.addRoleName(self.LayerHeightUnitRole, "layer_height_unit")
-        self.addRoleName(self.AvailableRole, "available")
+        self.addRoleName(self.AvailableRole, "available") #Whether the quality profile is available in our current nozzle + material.
         self.addRoleName(self.QualityGroupRole, "quality_group")
         self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group")
 
@@ -39,6 +39,7 @@ class QualityProfilesDropDownMenuModel(ListModel):
 
         self._application.globalContainerStackChanged.connect(self._update)
         self._machine_manager.activeQualityGroupChanged.connect(self._update)
+        self._machine_manager.extruderChanged.connect(self._update)
         self._quality_manager.qualitiesUpdated.connect(self._update)
 
         self._layer_height_unit = ""  # This is cached

+ 10 - 9
cura/Machines/Models/QualitySettingsModel.py

@@ -21,6 +21,8 @@ class QualitySettingsModel(ListModel):
     UserValueRole = Qt.UserRole + 6
     CategoryRole = Qt.UserRole + 7
 
+    GLOBAL_STACK_POSITION = -1
+
     def __init__(self, parent = None):
         super().__init__(parent = parent)
 
@@ -36,8 +38,7 @@ class QualitySettingsModel(ListModel):
         self._application = Application.getInstance()
         self._quality_manager = self._application.getQualityManager()
 
-        self._selected_position = ""  # empty string means GlobalStack
-                                      # strings such as "0", "1", etc. mean extruder positions
+        self._selected_position = self.GLOBAL_STACK_POSITION #Must be either GLOBAL_STACK_POSITION or an extruder position (0, 1, etc.)
         self._selected_quality_item = None  # The selected quality in the quality management page
         self._i18n_catalog = None
 
@@ -54,7 +55,7 @@ class QualitySettingsModel(ListModel):
             self.selectedPositionChanged.emit()
             self._update()
 
-    @pyqtProperty(str, fset = setSelectedPosition, notify = selectedPositionChanged)
+    @pyqtProperty(int, fset = setSelectedPosition, notify = selectedPositionChanged)
     def selectedPosition(self):
         return self._selected_position
 
@@ -83,7 +84,7 @@ class QualitySettingsModel(ListModel):
         quality_group = self._selected_quality_item["quality_group"]
         quality_changes_group = self._selected_quality_item["quality_changes_group"]
 
-        if self._selected_position == "":
+        if self._selected_position == self.GLOBAL_STACK_POSITION:
             quality_node = quality_group.node_for_global
         else:
             quality_node = quality_group.nodes_for_extruders.get(self._selected_position)
@@ -93,14 +94,14 @@ class QualitySettingsModel(ListModel):
         # Here, if the user has selected a quality changes, then "quality_changes_group" will not be None, and we fetch
         # the settings in that quality_changes_group.
         if quality_changes_group is not None:
-            if self._selected_position == "":
+            if self._selected_position == self.GLOBAL_STACK_POSITION:
                 quality_changes_node = quality_changes_group.node_for_global
             else:
                 quality_changes_node = quality_changes_group.nodes_for_extruders.get(self._selected_position)
             if quality_changes_node is not None:  # it can be None if number of extruders are changed during runtime
                 try:
                     quality_containers.insert(0, quality_changes_node.getContainer())
-                except:
+                except RuntimeError:
                     # FIXME: This is to prevent incomplete update of QualityManager
                     Logger.logException("d", "Failed to get container for quality changes node %s", quality_changes_node)
                     return
@@ -127,7 +128,7 @@ class QualitySettingsModel(ListModel):
                     profile_value = new_value
 
                 # Global tab should use resolve (if there is one)
-                if self._selected_position == "":
+                if self._selected_position == self.GLOBAL_STACK_POSITION:
                     resolve_value = global_container_stack.getProperty(definition.key, "resolve")
                     if resolve_value is not None and definition.key in settings_keys:
                         profile_value = resolve_value
@@ -135,10 +136,10 @@ class QualitySettingsModel(ListModel):
                 if profile_value is not None:
                     break
 
-            if not self._selected_position:
+            if self._selected_position == self.GLOBAL_STACK_POSITION:
                 user_value = global_container_stack.userChanges.getProperty(definition.key, "value")
             else:
-                extruder_stack = global_container_stack.extruders[self._selected_position]
+                extruder_stack = global_container_stack.extruders[str(self._selected_position)]
                 user_value = extruder_stack.userChanges.getProperty(definition.key, "value")
 
             if profile_value is None and user_value is None:

+ 2 - 2
cura/Machines/QualityGroup.py

@@ -1,7 +1,7 @@
 # Copyright (c) 2018 Ultimaker B.V.
 # Cura is released under the terms of the LGPLv3 or higher.
 
-from typing import Optional, List
+from typing import Dict, Optional, List
 
 from PyQt5.QtCore import QObject, pyqtSlot
 
@@ -25,7 +25,7 @@ class QualityGroup(QObject):
         super().__init__(parent)
         self.name = name
         self.node_for_global = None  # type: Optional["QualityGroup"]
-        self.nodes_for_extruders = dict()  # position str -> QualityGroup
+        self.nodes_for_extruders = {}  # type: Dict[int, "QualityGroup"]
         self.quality_type = quality_type
         self.is_available = False
 

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