-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17893 from alexandr-vladimirov/Issue-4835-allow-t…
…o-set-print-sequence-manually Allow to set print sequence manually
- Loading branch information
Showing
53 changed files
with
1,022 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
from typing import List, Dict | ||
from cura.Scene.CuraSceneNode import CuraSceneNode | ||
|
||
|
||
class HitChecker: | ||
"""Checks if nodes can be printed without causing any collisions and interference""" | ||
|
||
def __init__(self, nodes: List[CuraSceneNode]) -> None: | ||
self._hit_map = self._buildHitMap(nodes) | ||
|
||
def anyTwoNodesBlockEachOther(self, nodes: List[CuraSceneNode]) -> bool: | ||
"""Returns True if any 2 nodes block each other""" | ||
for a in nodes: | ||
for b in nodes: | ||
if self._hit_map[a][b] and self._hit_map[b][a]: | ||
return True | ||
return False | ||
|
||
def canPrintBefore(self, node: CuraSceneNode, other_nodes: List[CuraSceneNode]) -> bool: | ||
"""Returns True if node doesn't block other_nodes and can be printed before them""" | ||
no_hits = all(not self._hit_map[node][other_node] for other_node in other_nodes) | ||
return no_hits | ||
|
||
def canPrintAfter(self, node: CuraSceneNode, other_nodes: List[CuraSceneNode]) -> bool: | ||
"""Returns True if node doesn't hit other nodes and can be printed after them""" | ||
no_hits = all(not self._hit_map[other_node][node] for other_node in other_nodes) | ||
return no_hits | ||
|
||
def calculateScore(self, a: CuraSceneNode, b: CuraSceneNode) -> int: | ||
"""Calculate score simply sums the number of other objects it 'blocks' | ||
:param a: node | ||
:param b: node | ||
:return: sum of the number of other objects | ||
""" | ||
|
||
score_a = sum(self._hit_map[a].values()) | ||
score_b = sum(self._hit_map[b].values()) | ||
return score_a - score_b | ||
|
||
def canPrintNodesInProvidedOrder(self, ordered_nodes: List[CuraSceneNode]) -> bool: | ||
"""Returns True If nodes don't have any hits in provided order""" | ||
for node_index, node in enumerate(ordered_nodes): | ||
nodes_before = ordered_nodes[:node_index - 1] if node_index - 1 >= 0 else [] | ||
nodes_after = ordered_nodes[node_index + 1:] if node_index + 1 < len(ordered_nodes) else [] | ||
if not self.canPrintBefore(node, nodes_after) or not self.canPrintAfter(node, nodes_before): | ||
return False | ||
return True | ||
|
||
@staticmethod | ||
def _buildHitMap(nodes: List[CuraSceneNode]) -> Dict[CuraSceneNode, CuraSceneNode]: | ||
"""Pre-computes all hits between all objects | ||
:nodes: nodes that need to be checked for collisions | ||
:return: dictionary where hit_map[node1][node2] is False if there node1 can be printed before node2 | ||
""" | ||
hit_map = {j: {i: HitChecker._checkHit(j, i) for i in nodes} for j in nodes} | ||
return hit_map | ||
|
||
@staticmethod | ||
def _checkHit(a: CuraSceneNode, b: CuraSceneNode) -> bool: | ||
"""Checks if a can be printed before b | ||
:param a: node | ||
:param b: node | ||
:return: False if a can be printed before b | ||
""" | ||
|
||
if a == b: | ||
return False | ||
|
||
a_hit_hull = a.callDecoration("getConvexHullBoundary") | ||
b_hit_hull = b.callDecoration("getConvexHullHeadFull") | ||
overlap = a_hit_hull.intersectsPolygon(b_hit_hull) | ||
|
||
if overlap: | ||
return True | ||
|
||
# Adhesion areas must never overlap, regardless of printing order | ||
# This would cause over-extrusion | ||
a_hit_hull = a.callDecoration("getAdhesionArea") | ||
b_hit_hull = b.callDecoration("getAdhesionArea") | ||
overlap = a_hit_hull.intersectsPolygon(b_hit_hull) | ||
|
||
if overlap: | ||
return True | ||
else: | ||
return False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.