WIP Solved stash apply. CURA-3610

This commit is contained in:
Jack Ha 2017-03-30 16:26:39 +02:00
parent 3135dc7d77
commit 1164805a68
2 changed files with 60 additions and 41 deletions

View file

@ -23,7 +23,6 @@ from UM.View.GL.OpenGL import OpenGL
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
import numpy import numpy
import copy
import math import math
# Setting for clearance around the prime # Setting for clearance around the prime
@ -113,8 +112,8 @@ class BuildVolume(SceneNode):
new_scene_objects = set(node for node in BreadthFirstIterator(root) if node.callDecoration("isSliceable")) new_scene_objects = set(node for node in BreadthFirstIterator(root) if node.callDecoration("isSliceable"))
if new_scene_objects != self._scene_objects: if new_scene_objects != self._scene_objects:
for node in new_scene_objects - self._scene_objects: #Nodes that were added to the scene. for node in new_scene_objects - self._scene_objects: #Nodes that were added to the scene.
self._onNodeDecoratorChanged(node) self._updateNodeListeners(node)
node.decoratorsChanged.connect(self._onNodeDecoratorChanged) # Make sure that decoration changes afterwards also receive the same treatment node.decoratorsChanged.connect(self._updateNodeListeners) # Make sure that decoration changes afterwards also receive the same treatment
for node in self._scene_objects - new_scene_objects: #Nodes that were removed from the scene. for node in self._scene_objects - new_scene_objects: #Nodes that were removed from the scene.
per_mesh_stack = node.callDecoration("getStack") per_mesh_stack = node.callDecoration("getStack")
if per_mesh_stack: if per_mesh_stack:
@ -122,7 +121,7 @@ class BuildVolume(SceneNode):
active_extruder_changed = node.callDecoration("getActiveExtruderChangedSignal") active_extruder_changed = node.callDecoration("getActiveExtruderChangedSignal")
if active_extruder_changed is not None: if active_extruder_changed is not None:
node.callDecoration("getActiveExtruderChangedSignal").disconnect(self._updateDisallowedAreasAndRebuild) node.callDecoration("getActiveExtruderChangedSignal").disconnect(self._updateDisallowedAreasAndRebuild)
node.decoratorsChanged.disconnect(self._onNodeDecoratorChanged) node.decoratorsChanged.disconnect(self._updateNodeListeners)
self._scene_objects = new_scene_objects self._scene_objects = new_scene_objects
self._onSettingPropertyChanged("print_sequence", "value") # Create fake event, so right settings are triggered. self._onSettingPropertyChanged("print_sequence", "value") # Create fake event, so right settings are triggered.
@ -130,7 +129,7 @@ class BuildVolume(SceneNode):
## Updates the listeners that listen for changes in per-mesh stacks. ## Updates the listeners that listen for changes in per-mesh stacks.
# #
# \param node The node for which the decorators changed. # \param node The node for which the decorators changed.
def _onNodeDecoratorChanged(self, node): def _updateNodeListeners(self, node):
per_mesh_stack = node.callDecoration("getStack") per_mesh_stack = node.callDecoration("getStack")
if per_mesh_stack: if per_mesh_stack:
per_mesh_stack.propertyChanged.connect(self._onSettingPropertyChanged) per_mesh_stack.propertyChanged.connect(self._onSettingPropertyChanged)
@ -180,6 +179,56 @@ class BuildVolume(SceneNode):
return True return True
## For every sliceable node, update node._outside_buildarea
#
def updateNodeBoundaryCheck(self):
root = Application.getInstance().getController().getScene().getRoot()
nodes = list(BreadthFirstIterator(root))
group_nodes = []
build_volume_bounding_box = self.getBoundingBox()
if build_volume_bounding_box:
# It's over 9000!
build_volume_bounding_box = build_volume_bounding_box.set(bottom=-9001)
else:
# No bounding box. This is triggered when running Cura from command line with a model for the first time
# In that situation there is a model, but no machine (and therefore no build volume.
return
for node in nodes:
# Need to check group nodes later
if node.callDecoration("isGroup"):
group_nodes.append(node) # Keep list of affected group_nodes
if node.callDecoration("isSliceable"):
node._outside_buildarea = False
bbox = node.getBoundingBox()
# 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
break
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
# from UM.Logger import Logger
# Logger.log("d", " # A node is outside build area")
break
# 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
## Recalculates the build volume & disallowed areas. ## Recalculates the build volume & disallowed areas.
def rebuild(self): def rebuild(self):
if not self._width or not self._height or not self._depth: if not self._width or not self._height or not self._depth:
@ -363,6 +412,8 @@ class BuildVolume(SceneNode):
Application.getInstance().getController().getScene()._maximum_bounds = scale_to_max_bounds Application.getInstance().getController().getScene()._maximum_bounds = scale_to_max_bounds
self.updateNodeBoundaryCheck()
def getBoundingBox(self): def getBoundingBox(self):
return self._volume_aabb return self._volume_aabb

40
cura/PlatformPhysics.py Normal file → Executable file
View file

@ -3,10 +3,10 @@
from PyQt5.QtCore import QTimer from PyQt5.QtCore import QTimer
from UM.Application import Application
from UM.Scene.SceneNode import SceneNode from UM.Scene.SceneNode import SceneNode
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
from UM.Math.Vector import Vector from UM.Math.Vector import Vector
from UM.Math.AxisAlignedBox import AxisAlignedBox
from UM.Scene.Selection import Selection from UM.Scene.Selection import Selection
from UM.Preferences import Preferences from UM.Preferences import Preferences
@ -51,7 +51,6 @@ class PlatformPhysics:
# same direction. # same direction.
transformed_nodes = [] transformed_nodes = []
group_nodes = []
# We try to shuffle all the nodes to prevent "locked" situations, where iteration B inverts iteration A. # 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. # By shuffling the order of the nodes, this might happen a few times, but at some point it will resolve.
nodes = list(BreadthFirstIterator(root)) nodes = list(BreadthFirstIterator(root))
@ -62,24 +61,6 @@ class PlatformPhysics:
bbox = node.getBoundingBox() bbox = node.getBoundingBox()
# Ignore intersections with the bottom
build_volume_bounding_box = self._build_volume.getBoundingBox()
if build_volume_bounding_box:
# It's over 9000!
build_volume_bounding_box = build_volume_bounding_box.set(bottom=-9001)
else:
# No bounding box. This is triggered when running Cura from command line with a model for the first time
# In that situation there is a model, but no machine (and therefore no build volume.
return
node._outside_buildarea = False
# 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
if node.callDecoration("isGroup"):
group_nodes.append(node) # Keep list of affected group_nodes
# Move it downwards if bottom is above platform # Move it downwards if bottom is above platform
move_vector = Vector() move_vector = Vector()
if Preferences.getInstance().getValue("physics/automatic_drop_down") and not (node.getParent() and node.getParent().callDecoration("isGroup")) and node.isEnabled(): #If an object is grouped, don't move it down if Preferences.getInstance().getValue("physics/automatic_drop_down") and not (node.getParent() and node.getParent().callDecoration("isGroup")) and node.isEnabled(): #If an object is grouped, don't move it down
@ -145,27 +126,14 @@ class PlatformPhysics:
# Simply waiting for the next tick seems to resolve this correctly. # Simply waiting for the next tick seems to resolve this correctly.
overlap = None overlap = None
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._build_volume.getDisallowedAreas():
overlap = convex_hull.intersectsPolygon(area)
if overlap is None:
continue
node._outside_buildarea = True
if not Vector.Null.equals(move_vector, epsilon=1e-5): if not Vector.Null.equals(move_vector, epsilon=1e-5):
transformed_nodes.append(node) transformed_nodes.append(node)
op = PlatformPhysicsOperation.PlatformPhysicsOperation(node, move_vector) op = PlatformPhysicsOperation.PlatformPhysicsOperation(node, move_vector)
op.push() op.push()
# Group nodes should override the _outside_buildarea property of their children. # After moving, we have to evaluate the boundary checks for nodes
for group_node in group_nodes: build_volume = Application.getInstance().getBuildVolume()
for child_node in group_node.getAllChildren(): build_volume.updateNodeBoundaryCheck()
child_node._outside_buildarea = group_node._outside_buildarea
def _onToolOperationStarted(self, tool): def _onToolOperationStarted(self, tool):
self._enabled = False self._enabled = False