diff --git a/cura/Arranging/ArrangeObjectsJob.py b/cura/Arranging/ArrangeObjectsJob.py
index d122098565..4bb55bf660 100644
--- a/cura/Arranging/ArrangeObjectsJob.py
+++ b/cura/Arranging/ArrangeObjectsJob.py
@@ -15,7 +15,7 @@ i18n_catalog = i18nCatalog("cura")
class ArrangeObjectsJob(Job):
- def __init__(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode], min_offset=8,
+ def __init__(self, nodes: List[SceneNode], fixed_nodes: List[SceneNode], min_offset = 8,
grid_arrange: bool = False) -> None:
super().__init__()
self._nodes = nodes
diff --git a/cura/Arranging/GridArrange.py b/cura/Arranging/GridArrange.py
index 6d4db360f7..5280843bd3 100644
--- a/cura/Arranging/GridArrange.py
+++ b/cura/Arranging/GridArrange.py
@@ -18,10 +18,12 @@ class GridArrange:
_nodes_to_arrange: List["SceneNode"]
_fixed_nodes: List["SceneNode"]
- _build_volume_bounding_box = AxisAlignedBox
+ _build_volume: "BuildVolume"
+ _build_volume_bounding_box: AxisAlignedBox
def __init__(self, nodes_to_arrange: List["SceneNode"], build_volume: "BuildVolume", fixed_nodes: List["SceneNode"] = []):
self._nodes_to_arrange = nodes_to_arrange
+ self._build_volume = build_volume
self._build_volume_bounding_box = build_volume.getBoundingBox()
self._fixed_nodes = fixed_nodes
@@ -39,7 +41,6 @@ class GridArrange:
self._initial_leftover_grid_y = math.floor(self._initial_leftover_grid_y)
def arrange(self)-> bool:
-
grouped_operation, not_fit_count = self.createGroupOperationForArrange()
grouped_operation.push()
return not_fit_count == 0
@@ -51,6 +52,11 @@ class GridArrange:
fixed_nodes_grid_ids = fixed_nodes_grid_ids.union(self.intersectingGridIdxInclusive(node.getBoundingBox()))
build_plate_grid_ids = self.intersectingGridIdxExclusive(self._build_volume_bounding_box)
+
+ # Filter out the corner grid squares if the build plate shape is elliptic
+ if self._build_volume.getShape() == "elliptic":
+ build_plate_grid_ids = set(filter(lambda grid_id: self.checkGridUnderDiscSpace(grid_id[0], grid_id[1]), build_plate_grid_ids))
+
allowed_grid_idx = build_plate_grid_ids.difference(fixed_nodes_grid_ids)
# Find the sequence in which items are placed
@@ -86,7 +92,6 @@ class GridArrange:
operation = self.moveNodeOnGrid(node, self._initial_leftover_grid_x, left_over_grid_y)
grouped_operation.addOperation(operation)
left_over_grid_y = left_over_grid_y - 1
-
return grouped_operation, len(leftover_nodes)
def moveNodeOnGrid(self, node: "SceneNode", grid_x: int, grid_y: int) -> "Operation.Operation":
@@ -138,6 +143,35 @@ class GridArrange:
coord_y = (grid_y - self._build_volume_bounding_box.back) / (self._grid_height + self.offset_y)
return coord_x, coord_y
+ def checkGridUnderDiscSpace(self, grid_x: int, grid_y: int) -> bool:
+ left, back = self.gridSpaceToCoordSpace(grid_x, grid_y)
+ right, front = self.gridSpaceToCoordSpace(grid_x + 1, grid_y + 1)
+ corners = [(left, back), (right, back), (right, front), (left, front)]
+ return all([self.checkPointUnderDiscSpace(x, y) for x, y in corners])
+
+ def checkPointUnderDiscSpace(self, x: float, y: float) -> bool:
+ disc_x, disc_y = self.coordSpaceToDiscSpace(x, y)
+ distance_to_center_squared = disc_x ** 2 + disc_y ** 2
+ return distance_to_center_squared <= 1.0
+
+ def coordSpaceToDiscSpace(self, x: float, y: float) -> Tuple[float, float]:
+ # Transform coordinate system to
+ #
+ # coord_build_plate_left = -1
+ # | coord_build_plate_right = 1
+ # v (0,1) v
+ # ┌───────┬───────┐ < coord_build_plate_back = -1
+ # │ │ │
+ # │ │(0,0) │
+ # (-1,0)│───────o───────┤(1,0)
+ # │ │ │
+ # │ │ │
+ # └───────┴───────┘ < coord_build_plate_front = +1
+ # (0,-1)
+ disc_x = ((x - self._build_volume_bounding_box.left) / self._build_volume_bounding_box.width) * 2.0 - 1.0
+ disc_y = ((y - self._build_volume_bounding_box.back) / self._build_volume_bounding_box.depth) * 2.0 - 1.0
+ return disc_x, disc_y
+
def drawDebugSvg(self):
with open("Builvolume_test.svg", "w") as f:
build_volume_bounding_box = self._build_volume_bounding_box
@@ -145,25 +179,39 @@ class GridArrange:
f.write(
f"")
+
+ for x in range(math.floor(self._build_volume_bounding_box.left), math.floor(self._build_volume_bounding_box.right), 50):
+ for y in range(math.floor(self._build_volume_bounding_box.back), math.floor(self._build_volume_bounding_box.front), 50):
+ color = "green" if self.checkPointUnderDiscSpace(x, y) else "red"
+ f.write(f"""
+
+ """)
+ f.write(f"")
\ No newline at end of file
diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py
index 0d6ecf5810..045156dcce 100755
--- a/cura/BuildVolume.py
+++ b/cura/BuildVolume.py
@@ -203,6 +203,9 @@ class BuildVolume(SceneNode):
if shape:
self._shape = shape
+ def getShape(self) -> str:
+ return self._shape
+
def getDiagonalSize(self) -> float:
"""Get the length of the 3D diagonal through the build volume.
diff --git a/cura/CuraActions.py b/cura/CuraActions.py
index bd5787de42..6e6e93e3ad 100644
--- a/cura/CuraActions.py
+++ b/cura/CuraActions.py
@@ -80,7 +80,7 @@ class CuraActions(QObject):
center_y = 0
# Move the object so that it's bottom is on to of the buildplate
- center_operation = TranslateOperation(current_node, Vector(0, center_y, 0), set_position=True)
+ center_operation = TranslateOperation(current_node, Vector(0, center_y, 0), set_position = True)
operation.addOperation(center_operation)
operation.push()
@pyqtSlot(int)
diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml
index 0701ba48ce..65888b3493 100644
--- a/resources/qml/Actions.qml
+++ b/resources/qml/Actions.qml
@@ -42,8 +42,6 @@ Item
property alias reloadAll: reloadAllAction
property alias arrangeAll: arrangeAllAction
property alias arrangeAllGrid: arrangeAllGridAction
- property alias arrangeSelection: arrangeSelectionAction
- property alias arrangeSelectionLock: arrangeSelectionLockAction
property alias resetAllTranslation: resetAllTranslationAction
property alias resetAll: resetAllAction
@@ -470,20 +468,6 @@ Item
shortcut: "Shift+Ctrl+R"
}
- Action
- {
- id: arrangeSelectionAction
- text: catalog.i18nc("@action:inmenu menubar:edit","Arrange Selection")
- onTriggered: Printer.arrangeSelection(false)
- }
-
- Action
- {
- id: arrangeSelectionLockAction
- text: catalog.i18nc("@action:inmenu menubar:edit","Arrange Selection Without Rotation")
- onTriggered: Printer.arrangeSelection(true)
- }
-
Action
{
id: resetAllTranslationAction