Browse Source

Merge pull request #18443 from Ultimaker/CURA-10542-Drop-to-buildplate-permodel

Cura 10542 drop to buildplate permodel
Remco Burema 1 year ago
parent
commit
1a0622acf2

+ 3 - 3
cura/CuraApplication.py

@@ -1085,9 +1085,9 @@ class CuraApplication(QtApplication):
     def getTextManager(self, *args) -> "TextManager":
         return self._text_manager
 
-    @pyqtSlot(bool)
-    def getWorkplaceDropToBuildplate(self, drop_to_build_plate: bool) ->None:
-        return self._physics.setAppPerModelDropDown(drop_to_build_plate)
+    @pyqtSlot()
+    def setWorkplaceDropToBuildplate(self):
+        return self._physics.setAppAllModelDropDown()
 
     def getCuraFormulaFunctions(self, *args) -> "CuraFormulaFunctions":
         if self._cura_formula_functions is None:

+ 8 - 14
cura/PlatformPhysics.py

@@ -38,14 +38,12 @@ class PlatformPhysics:
         self._minimum_gap = 2  # It is a minimum distance (in mm) between two models, applicable for small models
 
         Application.getInstance().getPreferences().addPreference("physics/automatic_push_free", False)
-        Application.getInstance().getPreferences().addPreference("physics/automatic_drop_down", False)
-        self._app_per_model_drop = Application.getInstance().getPreferences().getValue("physics/automatic_drop_down")
+        Application.getInstance().getPreferences().addPreference("physics/automatic_drop_down", True)
+        self._app_all_model_drop = False
 
-    def getAppPerModelDropDown(self):
-        return self._app_per_model_drop
-
-    def setAppPerModelDropDown(self, drop_to_buildplate):
-        self._app_per_model_drop = drop_to_buildplate
+    def setAppAllModelDropDown(self):
+        self._app_all_model_drop = True
+        self._onChangeTimerFinished()
 
     def _onSceneChanged(self, source):
         if not source.callDecoration("isSliceable"):
@@ -78,7 +76,6 @@ class PlatformPhysics:
         # We try to shuffle all the nodes to prevent "locked" situations, where iteration B inverts iteration A.
         # By shuffling the order of the nodes, this might happen a few times, but at some point it will resolve.
         random.shuffle(nodes)
-
         for node in nodes:
             if node is root or not isinstance(node, SceneNode) or node.getBoundingBox() is None:
                 continue
@@ -88,12 +85,9 @@ class PlatformPhysics:
             # Move it downwards if bottom is above platform
             move_vector = Vector()
 
-            # if per model drop is different then app_automatic_drop, in case of 3mf loading when user changes this setting for that model
-            if (self._app_per_model_drop != app_automatic_drop_down):
-                node.setSetting(SceneNodeSettings.AutoDropDown, self._app_per_model_drop)
-            if node.getSetting(SceneNodeSettings.AutoDropDown, self._app_per_model_drop) and not (node.getParent() and node.getParent().callDecoration("isGroup") or node.getParent() != root) and node.isEnabled(): #If an object is grouped, don't move it down
+            if (node.getSetting(SceneNodeSettings.AutoDropDown, app_automatic_drop_down) or self._app_all_model_drop) and not (node.getParent() and node.getParent().callDecoration("isGroup") or node.getParent() != root)  and node.isEnabled():
                 z_offset = node.callDecoration("getZOffset") if node.getDecorator(ZOffsetDecorator.ZOffsetDecorator) else 0
-                move_vector = move_vector.set(y = -bbox.bottom + z_offset)
+                move_vector = move_vector.set(y=-bbox.bottom + z_offset)
 
             # If there is no convex hull for the node, start calculating it and continue.
             if not node.getDecorator(ConvexHullDecorator) and not node.callDecoration("isNonPrintingMesh") and node.callDecoration("getLayerData") is None:
@@ -180,7 +174,7 @@ class PlatformPhysics:
                 op.push()
 
         # setting this drop to model same as app_automatic_drop_down
-        self._app_per_model_drop = app_automatic_drop_down
+        self._app_all_model_drop = False
         # After moving, we have to evaluate the boundary checks for nodes
         build_volume.updateNodeBoundaryCheck()
 

+ 5 - 0
cura/Scene/CuraSceneNode.py

@@ -11,6 +11,7 @@ from UM.Scene.SceneNode import SceneNode
 from UM.Scene.SceneNodeDecorator import SceneNodeDecorator  # To cast the deepcopy of every decorator back to SceneNodeDecorator.
 
 import cura.CuraApplication  # To get the build plate.
+from UM.Scene.SceneNodeSettings import SceneNodeSettings
 from cura.Settings.ExtruderStack import ExtruderStack  # For typing.
 from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator  # For per-object settings.
 
@@ -41,6 +42,10 @@ class CuraSceneNode(SceneNode):
     def isOutsideBuildArea(self) -> bool:
         return self._outside_buildarea or self.callDecoration("getBuildPlateNumber") < 0
 
+    @property
+    def isDropDownEnabled(self) ->bool:
+        return self.getSetting(SceneNodeSettings.AutoDropDown, Application.getInstance().getPreferences().getValue("physics/automatic_drop_down"))
+
     def isVisible(self) -> bool:
         return super().isVisible() and self.callDecoration("getBuildPlateNumber") == cura.CuraApplication.CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate
 

+ 4 - 0
plugins/3MFReader/ThreeMFReader.py

@@ -16,6 +16,7 @@ from UM.Mesh.MeshReader import MeshReader
 from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType
 from UM.Scene.GroupDecorator import GroupDecorator
 from UM.Scene.SceneNode import SceneNode  # For typing.
+from UM.Scene.SceneNodeSettings import SceneNodeSettings
 from cura.CuraApplication import CuraApplication
 from cura.Machines.ContainerTree import ContainerTree
 from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
@@ -180,6 +181,9 @@ class ThreeMFReader(MeshReader):
                 if key == "print_order":
                     um_node.printOrder = int(setting_value)
                     continue
+                if key =="drop_to_buildplate":
+                    um_node.setSetting(SceneNodeSettings.AutoDropDown, eval(setting_value))
+                    continue
                 if key in known_setting_keys:
                     setting_container.setProperty(key, "value", setting_value)
                 else:

+ 0 - 5
plugins/3MFReader/WorkspaceDialog.py

@@ -353,11 +353,6 @@ class WorkspaceDialog(QObject):
 
         Application.getInstance().getBackend().close()
 
-    @pyqtSlot(bool)
-    def setDropToBuildPlateForModel(self, drop_to_buildplate: bool) -> None:
-        CuraApplication.getInstance().getWorkplaceDropToBuildplate(drop_to_buildplate)
-
-
     def setMaterialConflict(self, material_conflict: bool) -> None:
         if self._has_material_conflict != material_conflict:
             self._has_material_conflict = material_conflict

+ 0 - 20
plugins/3MFReader/WorkspaceDialog.qml

@@ -351,25 +351,6 @@ UM.Dialog
                     }
                 }
 
-                Row
-                {
-                    id: dropToBuildPlate
-                    width: parent.width
-                    height: childrenRect.height
-                    spacing: UM.Theme.getSize("default_margin").width
-                    UM.CheckBox
-                    {
-                        id: checkDropModels
-                        text: catalog.i18nc("@text:window", "Drop models to buildplate")
-                        checked: UM.Preferences.getValue("physics/automatic_drop_down")
-                        onCheckedChanged: manager.setDropToBuildPlateForModel(checked)
-                    }
-                    function reloadValue()
-                    {
-                        checkDropModels.checked = UM.Preferences.getValue("physics/automatic_drop_down")
-                    }
-                }
-
                 Row
                 {
                     id: clearBuildPlateWarning
@@ -492,7 +473,6 @@ UM.Dialog
             materialSection.reloadValues()
             profileSection.reloadValues()
             printerSection.reloadValues()
-            dropToBuildPlate.reloadValue()
         }
     }
 }

+ 1 - 0
plugins/3MFWriter/ThreeMFWriter.py

@@ -155,6 +155,7 @@ class ThreeMFWriter(MeshWriter):
 
         if isinstance(um_node, CuraSceneNode):
             savitar_node.setSetting("cura:print_order", str(um_node.printOrder))
+            savitar_node.setSetting("cura:drop_to_buildplate", str(um_node.isDropDownEnabled))
 
         # Store the metadata.
         for key, value in um_node.metadata.items():

+ 9 - 1
resources/qml/Actions.qml

@@ -39,7 +39,7 @@ Item
     property alias printObjectAfterNext: printObjectAfterNextAction
 
     property alias multiplyObject: multiplyObjectAction
-
+    property alias dropAll: dropAllAction
     property alias selectAll: selectAllAction
     property alias deleteAll: deleteAllAction
     property alias reloadAll: reloadAllAction
@@ -490,6 +490,14 @@ Item
         shortcut: "Shift+Ctrl+R"
     }
 
+    Action
+    {
+        id: dropAllAction
+        text: catalog.i18nc("@action:inmenu menubar:edit","Drop All Models to buildplate")
+        shortcut: "Ctrl+B"
+        onTriggered: CuraApplication.setWorkplaceDropToBuildplate()
+    }
+
     Action
     {
         id: resetAllTranslationAction

+ 1 - 0
resources/qml/Menus/ContextMenu.qml

@@ -71,6 +71,7 @@ Cura.Menu
     Cura.MenuItem { action: Cura.Actions.reloadAll }
     Cura.MenuItem { action: Cura.Actions.resetAllTranslation }
     Cura.MenuItem { action: Cura.Actions.resetAll }
+    Cura.MenuItem { action: Cura.Actions.dropAll }
 
     // Group actions
     Cura.MenuSeparator {}

+ 1 - 0
resources/qml/Menus/EditMenu.qml

@@ -21,6 +21,7 @@ Cura.Menu
     Cura.MenuItem { action: Cura.Actions.deleteAll }
     Cura.MenuItem { action: Cura.Actions.resetAllTranslation }
     Cura.MenuItem { action: Cura.Actions.resetAll }
+    Cura.MenuItem { action: Cura.Actions.dropAll }
     Cura.MenuSeparator { }
     Cura.MenuItem { action: Cura.Actions.groupObjects }
     Cura.MenuItem { action: Cura.Actions.mergeObjects }

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