Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clearing memory stack #950

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
5 changes: 4 additions & 1 deletion UM/Controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ def getToolsEnabled(self) -> bool:
def setToolsEnabled(self, enabled: bool) -> None:
self._tools_enabled = enabled

def deleteAllNodesWithMeshData(self, only_selectable:bool = True) -> None:
def deleteAllNodesWithMeshData(self, only_selectable:bool = True, clear_all:bool = False) -> None:
Logger.log("i", "Clearing scene")
if not self.getToolsEnabled():
return
Expand Down Expand Up @@ -492,9 +492,12 @@ def deleteAllNodesWithMeshData(self, only_selectable:bool = True) -> None:
self.getScene().sceneChanged.emit(node)

op.push()
if clear_all:
op.clear()
from UM.Scene.Selection import Selection
Selection.clear()


# Rotate camera view according defined angle
def setCameraRotation(self, coordinate: str = "x", angle: int = 0) -> None:
camera = self._scene.getActiveCamera()
Expand Down
5 changes: 5 additions & 0 deletions UM/Operations/AddSceneNodeOperation.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,8 @@ def redo(self) -> None:
self._node.setParent(self._parent)
if self._selected: # It was selected while the operation was undone. We should restore that selection.
Selection.add(self._node)

def delete(self) -> None:
wawanbreton marked this conversation as resolved.
Show resolved Hide resolved
self._node.reset()
if self._parent.getName() != "Root":
self._parent.reset()
4 changes: 4 additions & 0 deletions UM/Operations/GroupedOperation.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,7 @@ def __repr__(self):
for child in self._children:
output += "{0!r}\n".format(child)
return output

def delete(self) -> None:
for node in self._children:
node.delete()
8 changes: 8 additions & 0 deletions UM/Operations/Operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,11 @@ def push(self) -> None:
# Because of circular dependency
from UM.Application import Application
Application.getInstance().getOperationStack().push(self)

def clear(self) -> None:
# Because of circular dependency
from UM.Application import Application
Application.getInstance().getOperationStack().clearStack()
wawanbreton marked this conversation as resolved.
Show resolved Hide resolved

def delete(self) -> None:
pass
20 changes: 18 additions & 2 deletions UM/Operations/OperationStack.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Copyright (c) 2019 Ultimaker B.V.
# Uranium is released under the terms of the LGPLv3 or higher.

import threading
import time

Expand Down Expand Up @@ -34,6 +33,23 @@ def __init__(self, controller) -> None:
def _onToolOperationStarted(self, tool):
self._merge_operations = False

def clearStackMemory(self, indexStart, indexEnd):
for node in self._operations[indexStart:indexEnd]:
node.delete()
del self._operations[indexStart:indexEnd]


def clearStack(self):
try:
with self._lock:
self.clearStackMemory(0, len(self._operations))
self._current_index = -1
self._merge_operations = False
self.changed.emit()
except Exception as e:
print("Error in clearing memory", e)


def _onToolOperationStopped(self, tool):
self._merge_operations = False

Expand All @@ -56,7 +72,7 @@ def push(self, operation):

try:
if self._current_index < len(self._operations) - 1:
del self._operations[self._current_index + 1:len(self._operations)]
self.clearStackMemory(self._current_index + 1, len(self._operations))

self._operations.append(operation)
operation.redo()
Expand Down
5 changes: 5 additions & 0 deletions UM/Operations/RemoveSceneNodeOperation.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,8 @@ def redo(self) -> None:
pass
if Selection.isSelected(self._node): # Also remove the selection.
Selection.remove(self._node)

def delete(self) -> None:
self._node.reset()
if self._parent.getName() != "Root":
self._parent.reset()
6 changes: 3 additions & 3 deletions UM/Qt/QtApplication.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,18 +627,18 @@ def createQmlComponent(self, qml_file_path: str, context_properties: Dict[str, "
return result

@pyqtSlot()
def deleteAll(self, only_selectable = True) -> None:
def deleteAll(self, only_selectable = True, clear_all:bool = False) -> None:
"""Delete all nodes containing mesh data in the scene.
:param only_selectable:. Set this to False to delete objects from all build plates
"""

self.getController().deleteAllNodesWithMeshData(only_selectable)
self.getController().deleteAllNodesWithMeshData(only_selectable, clear_all = clear_all)

@pyqtSlot()
def resetWorkspace(self) -> None:
self._workspace_metadata_storage.clear()
self._current_workspace_information.clear()
self.deleteAll()
self.deleteAll(clear_all = True)
self.workspaceLoaded.emit("")
self.getController().getScene().clearMetaData()

Expand Down
28 changes: 26 additions & 2 deletions UM/Scene/SceneNode.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,31 @@ def __init__(self, parent: Optional["SceneNode"] = None, visible: bool = True, n
if parent:
parent.addChild(self)

def reset(self):
"""Reset this scene node instance"""
self._children = []
self._mesh_data = None
self.metadata = {}
self._transformation = Matrix()
self._position = Vector()
self._scale = Vector(1.0, 1.0, 1.0)
self._shear = Vector(0.0, 0.0, 0.0)
self._mirror = Vector(1.0, 1.0, 1.0)
self._orientation = Quaternion()
self._world_transformation = Matrix()
self._cached_normal_matrix = Matrix()
self._derived_position = Vector()
self._derived_orientation = Quaternion()
self._derived_scale = Vector()
self._enabled = False
self._selectable = False
self._resetAABB()
self._visible = False
self._name = ""
self._id = ""
self.removeDecorators()
self._settings = {}

def __deepcopy__(self, memo: Dict[int, object]) -> "SceneNode":
copy = self.__class__()
copy.setTransformation(self.getLocalTransformation())
Expand Down Expand Up @@ -262,9 +287,8 @@ def getDecorator(self, dec_type: type) -> Optional[SceneNodeDecorator]:

def removeDecorators(self):
"""Remove all decorators"""

for decorator in self._decorators:
decorator.clear()
decorator.clearDecoratorData()
self._decorators = []
self.decoratorsChanged.emit(self)

Expand Down
5 changes: 2 additions & 3 deletions UM/Scene/SceneNodeDecorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ def setNode(self, node: "SceneNode") -> None:
def getNode(self) -> Optional["SceneNode"]:
return self._node

def clear(self) -> None:
def clearDecoratorData(self) -> None:
"""Clear all data associated with this decorator. This will be called before the decorator is removed"""

pass
self._node = None

def __deepcopy__(self, memo: Dict[int, object]) -> "SceneNodeDecorator":
raise NotImplementedError("Subclass {0} of SceneNodeDecorator should implement their own __deepcopy__() method.".format(str(self)))
Loading