Fix duplicating / multiplicating support blockers

CURA-7851
This commit is contained in:
Jaime van Kessel 2021-10-04 15:52:08 +02:00
parent f749bbef46
commit 44eb3201a9
2 changed files with 54 additions and 23 deletions

View file

@ -110,18 +110,11 @@ def findNodePlacement(nodes_to_arrange: List["SceneNode"], build_volume: "BuildV
return found_solution_for_all, node_items return found_solution_for_all, node_items
def arrange(nodes_to_arrange: List["SceneNode"], build_volume: "BuildVolume", fixed_nodes: Optional[List["SceneNode"]] = None, factor = 10000, add_new_nodes_in_scene: bool = False) -> bool: def createGroupOperationForArrange(nodes_to_arrange: List["SceneNode"],
""" build_volume: "BuildVolume",
Find placement for a set of scene nodes, and move them by using a single grouped operation. fixed_nodes: Optional[List["SceneNode"]] = None,
:param nodes_to_arrange: The list of nodes that need to be moved. factor = 10000,
:param build_volume: The build volume that we want to place the nodes in. It gets size & disallowed areas from this. add_new_nodes_in_scene: bool = False):
:param fixed_nodes: List of nods that should not be moved, but should be used when deciding where the others nodes
are placed.
:param factor: The library that we use is int based. This factor defines how accuracte we want it to be.
:param add_new_nodes_in_scene: Whether to create new scene nodes before applying the transformations and rotations
:return: found_solution_for_all: Whether the algorithm found a place on the buildplate for all the objects
"""
scene_root = Application.getInstance().getController().getScene().getRoot() scene_root = Application.getInstance().getController().getScene().getRoot()
found_solution_for_all, node_items = findNodePlacement(nodes_to_arrange, build_volume, fixed_nodes, factor) found_solution_for_all, node_items = findNodePlacement(nodes_to_arrange, build_volume, fixed_nodes, factor)
@ -141,8 +134,30 @@ def arrange(nodes_to_arrange: List["SceneNode"], build_volume: "BuildVolume", fi
else: else:
# We didn't find a spot # We didn't find a spot
grouped_operation.addOperation( grouped_operation.addOperation(
TranslateOperation(node, Vector(200, node.getWorldPosition().y, -not_fit_count * 20), set_position = True)) TranslateOperation(node, Vector(200, node.getWorldPosition().y, -not_fit_count * 20),
set_position=True))
not_fit_count += 1 not_fit_count += 1
grouped_operation.push()
return found_solution_for_all return grouped_operation, not_fit_count
def arrange(nodes_to_arrange: List["SceneNode"],
build_volume: "BuildVolume",
fixed_nodes: Optional[List["SceneNode"]] = None,
factor = 10000,
add_new_nodes_in_scene: bool = False) -> bool:
"""
Find placement for a set of scene nodes, and move them by using a single grouped operation.
:param nodes_to_arrange: The list of nodes that need to be moved.
:param build_volume: The build volume that we want to place the nodes in. It gets size & disallowed areas from this.
:param fixed_nodes: List of nods that should not be moved, but should be used when deciding where the others nodes
are placed.
:param factor: The library that we use is int based. This factor defines how accuracte we want it to be.
:param add_new_nodes_in_scene: Whether to create new scene nodes before applying the transformations and rotations
:return: found_solution_for_all: Whether the algorithm found a place on the buildplate for all the objects
"""
grouped_operation, not_fit_count = createGroupOperationForArrange(nodes_to_arrange, build_volume, fixed_nodes, factor, add_new_nodes_in_scene)
grouped_operation.redo()
return not_fit_count != 0

View file

@ -7,10 +7,12 @@ from typing import List
from UM.Application import Application from UM.Application import Application
from UM.Job import Job from UM.Job import Job
from UM.Message import Message from UM.Message import Message
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
from UM.Operations.GroupedOperation import GroupedOperation
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.SceneNode import SceneNode from UM.Scene.SceneNode import SceneNode
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from cura.Arranging.Nest2DArrange import arrange from cura.Arranging.Nest2DArrange import arrange, createGroupOperationForArrange
i18n_catalog = i18nCatalog("cura") i18n_catalog = i18nCatalog("cura")
@ -43,11 +45,11 @@ class MultiplyObjectsJob(Job):
# Only count sliceable objects # Only count sliceable objects
if node_.callDecoration("isSliceable"): if node_.callDecoration("isSliceable"):
fixed_nodes.append(node_) fixed_nodes.append(node_)
nodes_to_add_without_arrange = []
for node in self._objects: for node in self._objects:
# If object is part of a group, multiply group # If object is part of a group, multiply group
current_node = node current_node = node
while current_node.getParent() and (current_node.getParent().callDecoration("isGroup") or current_node.getParent().callDecoration("isSliceable")): while current_node.getParent() and current_node.getParent().callDecoration("isGroup"):
current_node = current_node.getParent() current_node = current_node.getParent()
if current_node in processed_nodes: if current_node in processed_nodes:
@ -56,19 +58,33 @@ class MultiplyObjectsJob(Job):
for _ in range(self._count): for _ in range(self._count):
new_node = copy.deepcopy(node) new_node = copy.deepcopy(node)
# Same build plate # Same build plate
build_plate_number = current_node.callDecoration("getBuildPlateNumber") build_plate_number = current_node.callDecoration("getBuildPlateNumber")
new_node.callDecoration("setBuildPlateNumber", build_plate_number) new_node.callDecoration("setBuildPlateNumber", build_plate_number)
for child in new_node.getChildren(): for child in new_node.getChildren():
child.callDecoration("setBuildPlateNumber", build_plate_number) child.callDecoration("setBuildPlateNumber", build_plate_number)
if not current_node.getParent().callDecoration("isSliceable"):
nodes.append(new_node) nodes.append(new_node)
else:
# The node we're trying to place has another node that is sliceable as a parent.
# As such, we shouldn't arrange it (but it should be added to the scene!)
nodes_to_add_without_arrange.append(new_node)
new_node.setParent(current_node.getParent())
found_solution_for_all = True found_solution_for_all = True
if nodes: if nodes:
found_solution_for_all = arrange(nodes, Application.getInstance().getBuildVolume(), fixed_nodes, group_operation, not_fit_count = createGroupOperationForArrange(nodes,
factor = 10000, add_new_nodes_in_scene = True) Application.getInstance().getBuildVolume(),
fixed_nodes,
factor=10000, add_new_nodes_in_scene=True)
else:
group_operation = GroupedOperation()
if nodes_to_add_without_arrange:
for nested_node in nodes_to_add_without_arrange:
group_operation.addOperation(AddSceneNodeOperation(nested_node, nested_node.getParent()))
group_operation.redo()
status_message.hide() status_message.hide()
if not found_solution_for_all: if not found_solution_for_all: