From 71bbe1ef7eb42027f36baa8bdf733dadfc7157fb Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 17 Nov 2014 16:43:22 +0100 Subject: [PATCH 01/76] Added CuraEngineBackend plugin --- CuraEngineBackend.py | 5 +++++ __init__.py | 8 ++++++++ 2 files changed, 13 insertions(+) create mode 100644 CuraEngineBackend.py create mode 100644 __init__.py diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py new file mode 100644 index 0000000000..d9681fc788 --- /dev/null +++ b/CuraEngineBackend.py @@ -0,0 +1,5 @@ +from Cura.Backend.Backend import Backend + +class CuraEngineBackend(Backend): + def __init__(self): + super(CuraEngineBackend,self).__init__() \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000000..2097947a55 --- /dev/null +++ b/__init__.py @@ -0,0 +1,8 @@ +#Shoopdawoop +from plugins.CuraEngineBackend import CuraEngineBackend + +def getMetaData(): + return { "name": "CuraBackend", "type": "Backend" } + +def register(app): + app.setBackend(CuraEngineBackend()) \ No newline at end of file From f8dd19460b311a3cd001c80910a51c13dcbef9ff Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 17 Nov 2014 16:56:25 +0100 Subject: [PATCH 02/76] Added transferMeshCommand --- TransferMeshCommand.py | 6 ++++++ __init__.py | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 TransferMeshCommand.py diff --git a/TransferMeshCommand.py b/TransferMeshCommand.py new file mode 100644 index 0000000000..83c93cb329 --- /dev/null +++ b/TransferMeshCommand.py @@ -0,0 +1,6 @@ +from Cura.Backend.Command import Command + +class TransferMeshCommand(Command): + def __init__(self): + super(TransferMeshCommand,self).__init__() + \ No newline at end of file diff --git a/__init__.py b/__init__.py index 2097947a55..7cd38610e4 100644 --- a/__init__.py +++ b/__init__.py @@ -5,4 +5,6 @@ def getMetaData(): return { "name": "CuraBackend", "type": "Backend" } def register(app): - app.setBackend(CuraEngineBackend()) \ No newline at end of file + engine = CuraEngineBackend() + app.setBackend(engine) + engine.addCommand(TransferMeshCommand()) \ No newline at end of file From 11ac8e85e8c0e8a9912390c9fc67ad5452b416b5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 18 Nov 2014 10:52:49 +0100 Subject: [PATCH 03/76] More work on CuraEngineBackend (and backend in general) --- Commands/TransferMeshCommand.py | 9 +++++++++ Commands/TransferMeshesCommand.py | 12 ++++++++++++ Commands/TransferVertCommand.py | 8 ++++++++ TransferMeshCommand.py | 6 ------ 4 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 Commands/TransferMeshCommand.py create mode 100644 Commands/TransferMeshesCommand.py create mode 100644 Commands/TransferVertCommand.py delete mode 100644 TransferMeshCommand.py diff --git a/Commands/TransferMeshCommand.py b/Commands/TransferMeshCommand.py new file mode 100644 index 0000000000..4e93113640 --- /dev/null +++ b/Commands/TransferMeshCommand.py @@ -0,0 +1,9 @@ +from Cura.Backend.Command import Command +from Cura.plugins.CuraBackendEngine.Commands.TransferVertCommand import TransferVertCommand + +class TransferMeshCommand(Command): + def __init__(self): + super(TransferMeshCommand,self).__init__() + + def send(self, mesh_data): + vertices = mesh_data.getVerticesList() \ No newline at end of file diff --git a/Commands/TransferMeshesCommand.py b/Commands/TransferMeshesCommand.py new file mode 100644 index 0000000000..b6ad579818 --- /dev/null +++ b/Commands/TransferMeshesCommand.py @@ -0,0 +1,12 @@ +from Cura.Backend.Command import Command +from Cura.plugins.CuraBackendEngine.Commands.TransferMeshCommand import TransferMeshCommand + +class TransferMeshesCommand(Command): + def __init__(self): + super(TransferMeshesCommand,self).__init__() + + def send(self, meshes): + command = TransferMeshCommand(self._socket) + for mesh in meshes: + command.send(mesh) + \ No newline at end of file diff --git a/Commands/TransferVertCommand.py b/Commands/TransferVertCommand.py new file mode 100644 index 0000000000..9d58191cd6 --- /dev/null +++ b/Commands/TransferVertCommand.py @@ -0,0 +1,8 @@ +from Cura.Backend.Command import Command + +class TransferVertCommand(Command): + def __init__(self): + super(TransferVertCommand,self).__init__() + + def send(self): + self._socket.sendData(self._id, self._data) \ No newline at end of file diff --git a/TransferMeshCommand.py b/TransferMeshCommand.py deleted file mode 100644 index 83c93cb329..0000000000 --- a/TransferMeshCommand.py +++ /dev/null @@ -1,6 +0,0 @@ -from Cura.Backend.Command import Command - -class TransferMeshCommand(Command): - def __init__(self): - super(TransferMeshCommand,self).__init__() - \ No newline at end of file From 2edd4da8616ccef887f9f7349ee1c032807bc607 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 18 Nov 2014 11:35:07 +0100 Subject: [PATCH 04/76] Fixed pluginRegistry bug --- Commands/TransferMeshCommand.py | 5 ++++- Commands/TransferVertCommand.py | 4 ++-- __init__.py | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Commands/TransferMeshCommand.py b/Commands/TransferMeshCommand.py index 4e93113640..93349d853d 100644 --- a/Commands/TransferMeshCommand.py +++ b/Commands/TransferMeshCommand.py @@ -6,4 +6,7 @@ class TransferMeshCommand(Command): super(TransferMeshCommand,self).__init__() def send(self, mesh_data): - vertices = mesh_data.getVerticesList() \ No newline at end of file + vertices = mesh_data.getVertices() + command = TransferVertCommand(self._socket) + for vertex in vertices: + command.send(vertex) \ No newline at end of file diff --git a/Commands/TransferVertCommand.py b/Commands/TransferVertCommand.py index 9d58191cd6..ec2fb52bf6 100644 --- a/Commands/TransferVertCommand.py +++ b/Commands/TransferVertCommand.py @@ -4,5 +4,5 @@ class TransferVertCommand(Command): def __init__(self): super(TransferVertCommand,self).__init__() - def send(self): - self._socket.sendData(self._id, self._data) \ No newline at end of file + def send(self, vertex): + self._socket.sendData(self._id, vertex.toString()) \ No newline at end of file diff --git a/__init__.py b/__init__.py index 7cd38610e4..c050072ecb 100644 --- a/__init__.py +++ b/__init__.py @@ -5,6 +5,7 @@ def getMetaData(): return { "name": "CuraBackend", "type": "Backend" } def register(app): + engine = CuraEngineBackend() app.setBackend(engine) - engine.addCommand(TransferMeshCommand()) \ No newline at end of file + #engine.addCommand(TransferMeshCommand()) \ No newline at end of file From ad33effbbe8231326c8e4f3bb22428d69b64ff35 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 18 Nov 2014 14:07:17 +0100 Subject: [PATCH 05/76] Changes to CuraEngineBackend plugin. The plugin does not work correctly, will visit later --- Commands/TransferMeshCommand.py | 15 ++++++++++++--- Commands/TransferMeshesCommand.py | 9 ++++++++- Commands/TransferVertCommand.py | 8 -------- Commands/TransferVerticeListCommand.py | 8 ++++++++ 4 files changed, 28 insertions(+), 12 deletions(-) delete mode 100644 Commands/TransferVertCommand.py create mode 100644 Commands/TransferVerticeListCommand.py diff --git a/Commands/TransferMeshCommand.py b/Commands/TransferMeshCommand.py index 93349d853d..11791986f8 100644 --- a/Commands/TransferMeshCommand.py +++ b/Commands/TransferMeshCommand.py @@ -6,7 +6,16 @@ class TransferMeshCommand(Command): super(TransferMeshCommand,self).__init__() def send(self, mesh_data): - vertices = mesh_data.getVertices() + vertices = mesh_data.getVerticesList() + self._socket.sendCommand(0x00200001, len(vertices)) # Tell other side that mesh with num vertices is going to be sent. + command = TransferVertCommand(self._socket) - for vertex in vertices: - command.send(vertex) \ No newline at end of file + command.send(vertices) + + + def recieve(self): + command_id, data = self._socket.getNextCommand() + if(command_id is not 0x00200001): + print("Wrong command!") + return None + unpacked_data = struct(' \ No newline at end of file diff --git a/Commands/TransferMeshesCommand.py b/Commands/TransferMeshesCommand.py index b6ad579818..23ec09f9af 100644 --- a/Commands/TransferMeshesCommand.py +++ b/Commands/TransferMeshesCommand.py @@ -6,7 +6,14 @@ class TransferMeshesCommand(Command): super(TransferMeshesCommand,self).__init__() def send(self, meshes): + self._socket.sendCommand(0x00200000,len(meshes)) # Tell other side that n meshes are going to be sent. command = TransferMeshCommand(self._socket) for mesh in meshes: command.send(mesh) - \ No newline at end of file + + def recieve(self, num_meshes): + meshes = [] + command = TransferMeshCommand(self._socket) + for x in range(0,num_meshes): + meshes.append(command.recieve()) + return meshes \ No newline at end of file diff --git a/Commands/TransferVertCommand.py b/Commands/TransferVertCommand.py deleted file mode 100644 index ec2fb52bf6..0000000000 --- a/Commands/TransferVertCommand.py +++ /dev/null @@ -1,8 +0,0 @@ -from Cura.Backend.Command import Command - -class TransferVertCommand(Command): - def __init__(self): - super(TransferVertCommand,self).__init__() - - def send(self, vertex): - self._socket.sendData(self._id, vertex.toString()) \ No newline at end of file diff --git a/Commands/TransferVerticeListCommand.py b/Commands/TransferVerticeListCommand.py new file mode 100644 index 0000000000..20b1bf3dc0 --- /dev/null +++ b/Commands/TransferVerticeListCommand.py @@ -0,0 +1,8 @@ +from Cura.Backend.Command import Command + +class TransferVerticeListCommand(Command): + def __init__(self): + super(TransferVertCommand,self).__init__() + + def send(self, vertices): + self._socet.sendCommandPacked(0x00200002, vertices.toString()) # Send vertex list \ No newline at end of file From 59767ec5603934f45b5db0e90c50c87893e36612 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Dec 2014 10:44:23 +0100 Subject: [PATCH 06/76] Refactoring of namespace --- Commands/TransferMeshCommand.py | 4 ++-- Commands/TransferMeshesCommand.py | 4 ++-- Commands/TransferVerticeListCommand.py | 2 +- CuraEngineBackend.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Commands/TransferMeshCommand.py b/Commands/TransferMeshCommand.py index 11791986f8..6f145deb0d 100644 --- a/Commands/TransferMeshCommand.py +++ b/Commands/TransferMeshCommand.py @@ -1,5 +1,5 @@ -from Cura.Backend.Command import Command -from Cura.plugins.CuraBackendEngine.Commands.TransferVertCommand import TransferVertCommand +from UM.Backend.Command import Command +from UM.plugins.CuraBackendEngine.Commands.TransferVertCommand import TransferVertCommand class TransferMeshCommand(Command): def __init__(self): diff --git a/Commands/TransferMeshesCommand.py b/Commands/TransferMeshesCommand.py index 23ec09f9af..b25225de8a 100644 --- a/Commands/TransferMeshesCommand.py +++ b/Commands/TransferMeshesCommand.py @@ -1,5 +1,5 @@ -from Cura.Backend.Command import Command -from Cura.plugins.CuraBackendEngine.Commands.TransferMeshCommand import TransferMeshCommand +from UM.Backend.Command import Command +from UM.plugins.CuraBackendEngine.Commands.TransferMeshCommand import TransferMeshCommand class TransferMeshesCommand(Command): def __init__(self): diff --git a/Commands/TransferVerticeListCommand.py b/Commands/TransferVerticeListCommand.py index 20b1bf3dc0..3390a9eb03 100644 --- a/Commands/TransferVerticeListCommand.py +++ b/Commands/TransferVerticeListCommand.py @@ -1,4 +1,4 @@ -from Cura.Backend.Command import Command +from UM.Backend.Command import Command class TransferVerticeListCommand(Command): def __init__(self): diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index d9681fc788..fa4aa4a2dc 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -1,4 +1,4 @@ -from Cura.Backend.Backend import Backend +from UM.Backend.Backend import Backend class CuraEngineBackend(Backend): def __init__(self): From 8b3f1bacb2f4e4657dafebbca9c17b334385ecae Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Dec 2014 11:24:43 +0100 Subject: [PATCH 07/76] Fixed broken renames in qml --- Commands/TransferMeshCommand.py | 2 +- Commands/TransferMeshesCommand.py | 2 +- CuraEngineBackend.py | 4 ++-- __init__.py | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Commands/TransferMeshCommand.py b/Commands/TransferMeshCommand.py index 6f145deb0d..038b0fc03f 100644 --- a/Commands/TransferMeshCommand.py +++ b/Commands/TransferMeshCommand.py @@ -1,5 +1,5 @@ from UM.Backend.Command import Command -from UM.plugins.CuraBackendEngine.Commands.TransferVertCommand import TransferVertCommand +from UM.plugins.UMBackendEngine.Commands.TransferVertCommand import TransferVertCommand class TransferMeshCommand(Command): def __init__(self): diff --git a/Commands/TransferMeshesCommand.py b/Commands/TransferMeshesCommand.py index b25225de8a..706452c640 100644 --- a/Commands/TransferMeshesCommand.py +++ b/Commands/TransferMeshesCommand.py @@ -1,5 +1,5 @@ from UM.Backend.Command import Command -from UM.plugins.CuraBackendEngine.Commands.TransferMeshCommand import TransferMeshCommand +from UM.plugins.UMBackendEngine.Commands.TransferMeshCommand import TransferMeshCommand class TransferMeshesCommand(Command): def __init__(self): diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index fa4aa4a2dc..970ab39354 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -1,5 +1,5 @@ from UM.Backend.Backend import Backend -class CuraEngineBackend(Backend): +class UMEngineBackend(Backend): def __init__(self): - super(CuraEngineBackend,self).__init__() \ No newline at end of file + super(UMEngineBackend,self).__init__() \ No newline at end of file diff --git a/__init__.py b/__init__.py index c050072ecb..63de68948a 100644 --- a/__init__.py +++ b/__init__.py @@ -1,11 +1,11 @@ #Shoopdawoop -from plugins.CuraEngineBackend import CuraEngineBackend +from plugins.UMEngineBackend import UMEngineBackend def getMetaData(): - return { "name": "CuraBackend", "type": "Backend" } + return { "name": "UMBackend", "type": "Backend" } def register(app): - engine = CuraEngineBackend() + engine = UMEngineBackend() app.setBackend(engine) #engine.addCommand(TransferMeshCommand()) \ No newline at end of file From 6cc079874477858caebcef87c64abe5b3703707a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 15 Dec 2014 11:34:39 +0100 Subject: [PATCH 08/76] Fixed wrong rename of CuraEngineBackend --- CuraEngineBackend.py | 4 ++-- __init__.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 970ab39354..fa4aa4a2dc 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -1,5 +1,5 @@ from UM.Backend.Backend import Backend -class UMEngineBackend(Backend): +class CuraEngineBackend(Backend): def __init__(self): - super(UMEngineBackend,self).__init__() \ No newline at end of file + super(CuraEngineBackend,self).__init__() \ No newline at end of file diff --git a/__init__.py b/__init__.py index 63de68948a..c050072ecb 100644 --- a/__init__.py +++ b/__init__.py @@ -1,11 +1,11 @@ #Shoopdawoop -from plugins.UMEngineBackend import UMEngineBackend +from plugins.CuraEngineBackend import CuraEngineBackend def getMetaData(): - return { "name": "UMBackend", "type": "Backend" } + return { "name": "CuraBackend", "type": "Backend" } def register(app): - engine = UMEngineBackend() + engine = CuraEngineBackend() app.setBackend(engine) #engine.addCommand(TransferMeshCommand()) \ No newline at end of file From 84ede6954099ff2bb8621a311eda9d8e9a44db27 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 9 Jan 2015 17:30:33 +0100 Subject: [PATCH 09/76] Start implementing the CuraEngineBackend --- CuraEngineBackend.py | 68 +++++++++++++++++++++++++++++++++++++++++++- __init__.py | 10 ++++--- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index fa4aa4a2dc..eabfbe7538 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -1,5 +1,71 @@ from UM.Backend.Backend import Backend +from UM.Application import Application +from UM.Scene.SceneNode import SceneNode +from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator +from UM.Preferences import Preferences +import threading + +import subprocess + +CMD_REQUEST_IDENTIFIER = 0x00100000; +CMD_IDENTIFIER_REPLY = 0x00100001; +CMD_REQUEST_VERSION = 0x00100002; +CMD_VERSION_REPLY = 0x00100003; + +CMD_SETTING = 0x00100004; +CMD_MATRIX = 0x00300002; +CMD_OBJECT_COUNT = 0x00300003; +CMD_OBJECT_LIST = 0x00200000; +CMD_MESH_LIST = 0x00200001; +CMD_VERTEX_LIST = 0x00200002; +CMD_NORMAL_LIST = 0x00200003; +CMD_PROCESS_MESH = 0x00300000; + +CMD_PROGRESS_REPORT = 0x00300001; +CMD_OBJECT_PRINT_TIME = 0x00300004; +CMD_OBJECT_PRINT_MATERIAL = 0x00300005; +CMD_LAYER_INFO = 0x00300007; +CMD_POLYGON = 0x00300006; class CuraEngineBackend(Backend): def __init__(self): - super(CuraEngineBackend,self).__init__() \ No newline at end of file + super().__init__() + + self._scene = Application.getInstance().getController().getScene() + self._scene.sceneChanged.connect(self._onSceneChanged) + + self._command_handlers[CMD_IDENTIFIER_REPLY] = self._identifierReply + self._command_handlers[CMD_OBJECT_PRINT_TIME] = self._printTimeReply + + def startEngine(self): + super().startEngine() + + def getEngineCommand(self): + return [Preferences.getPreference("BackendLocation"), '--socket', str(self._socket_thread.getPort()), '--command-socket'] + + def _onSceneChanged(self, source): + if (type(source) is not SceneNode) or (source is self._scene.getRoot()): + return + + objects = [] + for node in DepthFirstIterator(self._scene.getRoot()): + if type(node) is SceneNode and node.getMeshData(): + objects.append(node) + + self._socket_thread.sendCommand(CMD_OBJECT_COUNT, len(objects)) + + for object in objects: + print('sending object', object) + self._socket_thread.sendCommand(CMD_OBJECT_LIST, 1) + + meshData = object.getMeshData() + self._socket_thread.sendCommand(CMD_MESH_LIST, 1) + self._socket_thread.sendCommand(CMD_VERTEX_LIST, meshData.getVerticesAsByteArray()) + + self._socket_thread.sendCommand(CMD_PROCESS_MESH) + + def _identifierReply(self, data): + print(data) + + def _printTimeReply(self, data): + print(data) diff --git a/__init__.py b/__init__.py index c050072ecb..7caa8dafa1 100644 --- a/__init__.py +++ b/__init__.py @@ -1,11 +1,13 @@ #Shoopdawoop -from plugins.CuraEngineBackend import CuraEngineBackend +from . import CuraEngineBackend + +from UM.Preferences import Preferences def getMetaData(): return { "name": "CuraBackend", "type": "Backend" } def register(app): - - engine = CuraEngineBackend() + Preferences.addPreference("BackendLocation","../PinkUnicornEngine/CuraEngine") + engine = CuraEngineBackend.CuraEngineBackend() app.setBackend(engine) - #engine.addCommand(TransferMeshCommand()) \ No newline at end of file + #engine.addCommand(TransferMeshCommand()) From cdf3b06c8c5d64151045281c4b9654285f9f93a0 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 23 Jan 2015 11:19:07 +0100 Subject: [PATCH 10/76] Use libArcus for backend communication --- CuraEngineBackend.py | 76 ++++--- Cura_pb2.py | 465 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 502 insertions(+), 39 deletions(-) create mode 100644 Cura_pb2.py diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index eabfbe7538..c4d8c404be 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -3,29 +3,8 @@ from UM.Application import Application from UM.Scene.SceneNode import SceneNode from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Preferences import Preferences -import threading -import subprocess - -CMD_REQUEST_IDENTIFIER = 0x00100000; -CMD_IDENTIFIER_REPLY = 0x00100001; -CMD_REQUEST_VERSION = 0x00100002; -CMD_VERSION_REPLY = 0x00100003; - -CMD_SETTING = 0x00100004; -CMD_MATRIX = 0x00300002; -CMD_OBJECT_COUNT = 0x00300003; -CMD_OBJECT_LIST = 0x00200000; -CMD_MESH_LIST = 0x00200001; -CMD_VERTEX_LIST = 0x00200002; -CMD_NORMAL_LIST = 0x00200003; -CMD_PROCESS_MESH = 0x00300000; - -CMD_PROGRESS_REPORT = 0x00300001; -CMD_OBJECT_PRINT_TIME = 0x00300004; -CMD_OBJECT_PRINT_MATERIAL = 0x00300005; -CMD_LAYER_INFO = 0x00300007; -CMD_POLYGON = 0x00300006; +from . import Cura_pb2 class CuraEngineBackend(Backend): def __init__(self): @@ -34,14 +13,19 @@ class CuraEngineBackend(Backend): self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) - self._command_handlers[CMD_IDENTIFIER_REPLY] = self._identifierReply - self._command_handlers[CMD_OBJECT_PRINT_TIME] = self._printTimeReply + self._socket.registerMessageType(1, Cura_pb2.ObjectList) + self._socket.registerMessageType(2, Cura_pb2.SlicedObjectList) + self._socket.registerMessageType(3, Cura_pb2.Progress) + self._socket.registerMessageType(4, Cura_pb2.GCode) + self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) - def startEngine(self): - super().startEngine() + self._message_handlers[Cura_pb2.SlicedObjectList] = self._onSlicedObjectListMessage + self._message_handlers[Cura_pb2.Progress] = self._onProgressMessage + self._message_handlers[Cura_pb2.GCode] = self._onGCodeMessage + self._message_handlers[Cura_pb2.ObjectPrintTime] = self._onObjectPrintTimeMessage def getEngineCommand(self): - return [Preferences.getPreference("BackendLocation"), '--socket', str(self._socket_thread.getPort()), '--command-socket'] + return [Preferences.getPreference("BackendLocation"), '--connect', "127.0.0.1:49674"] def _onSceneChanged(self, source): if (type(source) is not SceneNode) or (source is self._scene.getRoot()): @@ -52,20 +36,34 @@ class CuraEngineBackend(Backend): if type(node) is SceneNode and node.getMeshData(): objects.append(node) - self._socket_thread.sendCommand(CMD_OBJECT_COUNT, len(objects)) - + msg = Cura_pb2.ObjectList() for object in objects: - print('sending object', object) - self._socket_thread.sendCommand(CMD_OBJECT_LIST, 1) - meshData = object.getMeshData() - self._socket_thread.sendCommand(CMD_MESH_LIST, 1) - self._socket_thread.sendCommand(CMD_VERTEX_LIST, meshData.getVerticesAsByteArray()) - self._socket_thread.sendCommand(CMD_PROCESS_MESH) + obj = msg.objects.add() + obj.vertices = meshData.getVerticesAsByteArray() - def _identifierReply(self, data): - print(data) + if meshData.hasNormals(): + obj.normals = meshData.getNormalsAsByteArray() - def _printTimeReply(self, data): - print(data) + if meshData.hasIndices(): + obj.indices = meshData.getIndicesAsByteArray() + + self._socket.sendMessage(msg) + + def _onSlicedObjectListMessage(self, message): + print('Received Sliced Objects') + + for object in message.objects: + print('Object:', object.id) + for layer in object.layers: + print(' Layer:', layer.id) + + def _onProgressMessage(self, message): + self.processingProgress.emit(message.amount) + + def _onGCodeMessage(self, message): + pass + + def _onObjectPrintTimeMessage(self, message): + pass diff --git a/Cura_pb2.py b/Cura_pb2.py new file mode 100644 index 0000000000..781aa8801e --- /dev/null +++ b/Cura_pb2.py @@ -0,0 +1,465 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: Cura.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='Cura.proto', + package='Cura', + serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x05\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"\x15\n\x05GCode\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x0c\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0c\n\x04time\x18\x02 \x01(\x02\x62\x06proto3') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + +_POLYGON_TYPE = _descriptor.EnumDescriptor( + name='Type', + full_name='Cura.Polygon.Type', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='NoneType', index=0, number=0, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='Inset0Type', index=1, number=1, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='InsetXType', index=2, number=2, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='SkinType', index=3, number=3, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='SupportType', index=4, number=4, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='SkirtType', index=5, number=5, + options=None, + type=None), + ], + containing_type=None, + options=None, + serialized_start=397, + serialized_end=495, +) +_sym_db.RegisterEnumDescriptor(_POLYGON_TYPE) + + +_OBJECTLIST = _descriptor.Descriptor( + name='ObjectList', + full_name='Cura.ObjectList', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='objects', full_name='Cura.ObjectList.objects', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=20, + serialized_end=63, +) + + +_OBJECT = _descriptor.Descriptor( + name='Object', + full_name='Cura.Object', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='Cura.Object.id', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='vertices', full_name='Cura.Object.vertices', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='normals', full_name='Cura.Object.normals', index=2, + number=3, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='indices', full_name='Cura.Object.indices', index=3, + number=4, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=65, + serialized_end=137, +) + + +_PROGRESS = _descriptor.Descriptor( + name='Progress', + full_name='Cura.Progress', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='amount', full_name='Cura.Progress.amount', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=139, + serialized_end=165, +) + + +_SLICEDOBJECTLIST = _descriptor.Descriptor( + name='SlicedObjectList', + full_name='Cura.SlicedObjectList', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='objects', full_name='Cura.SlicedObjectList.objects', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=167, + serialized_end=222, +) + + +_SLICEDOBJECT = _descriptor.Descriptor( + name='SlicedObject', + full_name='Cura.SlicedObject', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='Cura.SlicedObject.id', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='layers', full_name='Cura.SlicedObject.layers', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=224, + serialized_end=279, +) + + +_LAYER = _descriptor.Descriptor( + name='Layer', + full_name='Cura.Layer', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='Cura.Layer.id', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='polygons', full_name='Cura.Layer.polygons', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=281, + serialized_end=333, +) + + +_POLYGON = _descriptor.Descriptor( + name='Polygon', + full_name='Cura.Polygon', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='type', full_name='Cura.Polygon.type', index=0, + number=1, type=14, cpp_type=8, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='points', full_name='Cura.Polygon.points', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _POLYGON_TYPE, + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=336, + serialized_end=495, +) + + +_GCODE = _descriptor.Descriptor( + name='GCode', + full_name='Cura.GCode', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='code', full_name='Cura.GCode.code', index=0, + number=1, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=497, + serialized_end=518, +) + + +_OBJECTPRINTTIME = _descriptor.Descriptor( + name='ObjectPrintTime', + full_name='Cura.ObjectPrintTime', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='id', full_name='Cura.ObjectPrintTime.id', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='time', full_name='Cura.ObjectPrintTime.time', index=1, + number=2, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=520, + serialized_end=563, +) + +_OBJECTLIST.fields_by_name['objects'].message_type = _OBJECT +_SLICEDOBJECTLIST.fields_by_name['objects'].message_type = _SLICEDOBJECT +_SLICEDOBJECT.fields_by_name['layers'].message_type = _LAYER +_LAYER.fields_by_name['polygons'].message_type = _POLYGON +_POLYGON.fields_by_name['type'].enum_type = _POLYGON_TYPE +_POLYGON_TYPE.containing_type = _POLYGON +DESCRIPTOR.message_types_by_name['ObjectList'] = _OBJECTLIST +DESCRIPTOR.message_types_by_name['Object'] = _OBJECT +DESCRIPTOR.message_types_by_name['Progress'] = _PROGRESS +DESCRIPTOR.message_types_by_name['SlicedObjectList'] = _SLICEDOBJECTLIST +DESCRIPTOR.message_types_by_name['SlicedObject'] = _SLICEDOBJECT +DESCRIPTOR.message_types_by_name['Layer'] = _LAYER +DESCRIPTOR.message_types_by_name['Polygon'] = _POLYGON +DESCRIPTOR.message_types_by_name['GCode'] = _GCODE +DESCRIPTOR.message_types_by_name['ObjectPrintTime'] = _OBJECTPRINTTIME + +ObjectList = _reflection.GeneratedProtocolMessageType('ObjectList', (_message.Message,), dict( + DESCRIPTOR = _OBJECTLIST, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.ObjectList) + )) +_sym_db.RegisterMessage(ObjectList) + +Object = _reflection.GeneratedProtocolMessageType('Object', (_message.Message,), dict( + DESCRIPTOR = _OBJECT, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.Object) + )) +_sym_db.RegisterMessage(Object) + +Progress = _reflection.GeneratedProtocolMessageType('Progress', (_message.Message,), dict( + DESCRIPTOR = _PROGRESS, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.Progress) + )) +_sym_db.RegisterMessage(Progress) + +SlicedObjectList = _reflection.GeneratedProtocolMessageType('SlicedObjectList', (_message.Message,), dict( + DESCRIPTOR = _SLICEDOBJECTLIST, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.SlicedObjectList) + )) +_sym_db.RegisterMessage(SlicedObjectList) + +SlicedObject = _reflection.GeneratedProtocolMessageType('SlicedObject', (_message.Message,), dict( + DESCRIPTOR = _SLICEDOBJECT, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.SlicedObject) + )) +_sym_db.RegisterMessage(SlicedObject) + +Layer = _reflection.GeneratedProtocolMessageType('Layer', (_message.Message,), dict( + DESCRIPTOR = _LAYER, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.Layer) + )) +_sym_db.RegisterMessage(Layer) + +Polygon = _reflection.GeneratedProtocolMessageType('Polygon', (_message.Message,), dict( + DESCRIPTOR = _POLYGON, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.Polygon) + )) +_sym_db.RegisterMessage(Polygon) + +GCode = _reflection.GeneratedProtocolMessageType('GCode', (_message.Message,), dict( + DESCRIPTOR = _GCODE, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.GCode) + )) +_sym_db.RegisterMessage(GCode) + +ObjectPrintTime = _reflection.GeneratedProtocolMessageType('ObjectPrintTime', (_message.Message,), dict( + DESCRIPTOR = _OBJECTPRINTTIME, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.ObjectPrintTime) + )) +_sym_db.RegisterMessage(ObjectPrintTime) + + +# @@protoc_insertion_point(module_scope) From 0580dbb84cd185f3b2e083fa7918b1a8171db6e8 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 28 Jan 2015 11:56:33 +0100 Subject: [PATCH 11/76] Always register message types after socket creation --- CuraEngineBackend.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index c4d8c404be..4928ed1eca 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -13,19 +13,13 @@ class CuraEngineBackend(Backend): self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) - self._socket.registerMessageType(1, Cura_pb2.ObjectList) - self._socket.registerMessageType(2, Cura_pb2.SlicedObjectList) - self._socket.registerMessageType(3, Cura_pb2.Progress) - self._socket.registerMessageType(4, Cura_pb2.GCode) - self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) - self._message_handlers[Cura_pb2.SlicedObjectList] = self._onSlicedObjectListMessage self._message_handlers[Cura_pb2.Progress] = self._onProgressMessage self._message_handlers[Cura_pb2.GCode] = self._onGCodeMessage self._message_handlers[Cura_pb2.ObjectPrintTime] = self._onObjectPrintTimeMessage def getEngineCommand(self): - return [Preferences.getPreference("BackendLocation"), '--connect', "127.0.0.1:49674"] + return [Preferences.getPreference("BackendLocation"), '--connect', "127.0.0.1:{0}".format(self._port)] def _onSceneChanged(self, source): if (type(source) is not SceneNode) or (source is self._scene.getRoot()): @@ -67,3 +61,12 @@ class CuraEngineBackend(Backend): def _onObjectPrintTimeMessage(self, message): pass + + def _createSocket(self): + super()._createSocket() + + self._socket.registerMessageType(1, Cura_pb2.ObjectList) + self._socket.registerMessageType(2, Cura_pb2.SlicedObjectList) + self._socket.registerMessageType(3, Cura_pb2.Progress) + self._socket.registerMessageType(4, Cura_pb2.GCode) + self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) From 4b3e2a3f8c5ab53c4f3343f528c1eef56020d50b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 28 Jan 2015 11:56:49 +0100 Subject: [PATCH 12/76] Update Cura protocol file to latest version --- Cura_pb2.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cura_pb2.py b/Cura_pb2.py index 781aa8801e..906e64e12a 100644 --- a/Cura_pb2.py +++ b/Cura_pb2.py @@ -18,7 +18,7 @@ _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='Cura.proto', package='Cura', - serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x05\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"\x15\n\x05GCode\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x0c\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0c\n\x04time\x18\x02 \x01(\x02\x62\x06proto3') + serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x05\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"\x15\n\x05GCode\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x0c\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\x62\x06proto3') ) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -102,7 +102,7 @@ _OBJECT = _descriptor.Descriptor( fields=[ _descriptor.FieldDescriptor( name='id', full_name='Cura.Object.id', index=0, - number=1, type=5, cpp_type=1, label=1, + number=1, type=3, cpp_type=2, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -213,7 +213,7 @@ _SLICEDOBJECT = _descriptor.Descriptor( fields=[ _descriptor.FieldDescriptor( name='id', full_name='Cura.SlicedObject.id', index=0, - number=1, type=5, cpp_type=1, label=1, + number=1, type=3, cpp_type=2, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -355,7 +355,7 @@ _OBJECTPRINTTIME = _descriptor.Descriptor( fields=[ _descriptor.FieldDescriptor( name='id', full_name='Cura.ObjectPrintTime.id', index=0, - number=1, type=5, cpp_type=1, label=1, + number=1, type=3, cpp_type=2, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, From ecd8a8d2a355f93b6c116d6c7e911c10c7ba27c2 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 28 Jan 2015 11:57:47 +0100 Subject: [PATCH 13/76] Add a LayerData class and a Job class to create it from a Protobuf message --- LayerData.py | 45 +++++++++++++++++++++++++++++++++++ ProcessSlicedObjectListJob.py | 37 ++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 LayerData.py create mode 100644 ProcessSlicedObjectListJob.py diff --git a/LayerData.py b/LayerData.py new file mode 100644 index 0000000000..692ef97f91 --- /dev/null +++ b/LayerData.py @@ -0,0 +1,45 @@ +from UM.Mesh.MeshData import MeshData + +import numpy +import math + +class LayerData(MeshData): + def __init__(self): + super().__init__() + self._layers = {} + + def addPolygon(self, layer, type, data): + if layer not in self._layers: + self._layers[layer] = [] + + self._layers[layer].append(Polygon(self, type, data)) + + def getLayers(self): + return self._layers + +class Polygon(): + NoneType = 0 + Inset0Type = 1 + InsetXType = 2 + SkinType = 3 + SupportType = 4 + SkirtType = 5 + + def __init__(self, mesh, type, data): + super().__init__() + self._type = type + self._begin = mesh._vertex_count + mesh.addVertices(data) + + indices = [self._begin + i for i in range(len(data))] + + mesh.addIndices(numpy.array(indices, dtype=numpy.int32)) + self._end = mesh._vertex_count + + @property + def type(self): + return self._type + + @property + def data(self): + return self._data diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py new file mode 100644 index 0000000000..1080a9d4e8 --- /dev/null +++ b/ProcessSlicedObjectListJob.py @@ -0,0 +1,37 @@ +from UM.Job import Job +from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator +from UM.Scene.SceneNode import SceneNode +from UM.Application import Application +from UM.Mesh.MeshData import MeshData + +from . import LayerData + +import numpy +import struct + +class ProcessSlicedObjectListJob(Job): + def __init__(self, message): + super().__init__(description = 'Processing sliced object', visible = True) + self._message = message + self._scene = Application.getInstance().getController().getScene() + + def run(self): + objectIdMap = {} + for node in DepthFirstIterator(self._scene.getRoot()): + if type(node) is SceneNode and node.getMeshData(): + objectIdMap[id(node)] = node + + for object in self._message.objects: + mesh = objectIdMap[object.id].getMeshData() + + layerData = LayerData.LayerData() + for layer in object.layers: + for polygon in layer.polygons: + points = numpy.fromstring(polygon.points, dtype='i8') # Convert bytearray to numpy array + points = points.reshape((-1,2)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly. + points = numpy.asarray(points, dtype=numpy.float32) + points /= 1000 + points = numpy.insert(points, 1, layer.id / 10, axis = 1) + layerData.addPolygon(layer.id, polygon.type, points) + + mesh.layerData = layerData From ae63fdf58c1bc32e12abedda3d37138daef1cbcb Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 28 Jan 2015 11:59:41 +0100 Subject: [PATCH 14/76] Use the new Job class to process the sliced polygons received from backend --- CuraEngineBackend.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 4928ed1eca..c39a140986 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -5,6 +5,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Preferences import Preferences from . import Cura_pb2 +from . import ProcessSlicedObjectListJob class CuraEngineBackend(Backend): def __init__(self): @@ -35,23 +36,23 @@ class CuraEngineBackend(Backend): meshData = object.getMeshData() obj = msg.objects.add() - obj.vertices = meshData.getVerticesAsByteArray() + obj.id = id(object) - if meshData.hasNormals(): - obj.normals = meshData.getNormalsAsByteArray() + verts = meshData.getVertices() + verts[:,[1,2]] = verts[:,[2,1]] + obj.vertices = verts.tostring() - if meshData.hasIndices(): - obj.indices = meshData.getIndicesAsByteArray() + #if meshData.hasNormals(): + #obj.normals = meshData.getNormalsAsByteArray() + + #if meshData.hasIndices(): + #obj.indices = meshData.getIndicesAsByteArray() self._socket.sendMessage(msg) def _onSlicedObjectListMessage(self, message): - print('Received Sliced Objects') - - for object in message.objects: - print('Object:', object.id) - for layer in object.layers: - print(' Layer:', layer.id) + job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message) + job.start() def _onProgressMessage(self, message): self.processingProgress.emit(message.amount) From 143bdf38807edba64295c45ef9319ed3f3904bc7 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 28 Jan 2015 17:56:43 +0100 Subject: [PATCH 15/76] Send progress as floating point from 0 to 1 --- Cura_pb2.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cura_pb2.py b/Cura_pb2.py index 906e64e12a..3455a59c89 100644 --- a/Cura_pb2.py +++ b/Cura_pb2.py @@ -18,7 +18,7 @@ _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='Cura.proto', package='Cura', - serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x05\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"\x15\n\x05GCode\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x0c\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\x62\x06proto3') + serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"\x19\n\x05GCode\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\x62\x06proto3') ) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -153,7 +153,7 @@ _PROGRESS = _descriptor.Descriptor( fields=[ _descriptor.FieldDescriptor( name='amount', full_name='Cura.Progress.amount', index=0, - number=1, type=5, cpp_type=1, label=1, + number=1, type=2, cpp_type=6, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -324,9 +324,9 @@ _GCODE = _descriptor.Descriptor( containing_type=None, fields=[ _descriptor.FieldDescriptor( - name='code', full_name='Cura.GCode.code', index=0, - number=1, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=_b(""), + name='filename', full_name='Cura.GCode.filename', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -342,7 +342,7 @@ _GCODE = _descriptor.Descriptor( oneofs=[ ], serialized_start=497, - serialized_end=518, + serialized_end=522, ) @@ -378,8 +378,8 @@ _OBJECTPRINTTIME = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=520, - serialized_end=563, + serialized_start=524, + serialized_end=567, ) _OBJECTLIST.fields_by_name['objects'].message_type = _OBJECT From 78fa145bca4416726acb7c279754589ba0b2d1c0 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 28 Jan 2015 17:57:14 +0100 Subject: [PATCH 16/76] Add a job to handle processing of GCode from the backend --- ProcessGCodeJob.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 ProcessGCodeJob.py diff --git a/ProcessGCodeJob.py b/ProcessGCodeJob.py new file mode 100644 index 0000000000..3fbacd67a9 --- /dev/null +++ b/ProcessGCodeJob.py @@ -0,0 +1,17 @@ +from UM.Job import Job +from UM.Application import Application + +import os + +class ProcessGCodeJob(Job): + def __init__(self, message): + super().__init__() + + self._message = message + + def run(self): + with open(self._message.filename) as f: + data = f.read(None) + Application.getInstance().getController().getScene().gcode = data + + os.remove(self._message.filename) From 1f365d3467dc935086b7f61150efe10e6b3a32f4 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 28 Jan 2015 17:59:43 +0100 Subject: [PATCH 17/76] Handle GCode messages and delay sending object updates until a timer is expired --- CuraEngineBackend.py | 56 +++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index c39a140986..f0d18c079e 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -6,6 +6,9 @@ from UM.Preferences import Preferences from . import Cura_pb2 from . import ProcessSlicedObjectListJob +from . import ProcessGCodeJob + +import threading class CuraEngineBackend(Backend): def __init__(self): @@ -13,6 +16,7 @@ class CuraEngineBackend(Backend): self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) + self._sceneChangeTimer = None self._message_handlers[Cura_pb2.SlicedObjectList] = self._onSlicedObjectListMessage self._message_handlers[Cura_pb2.Progress] = self._onProgressMessage @@ -26,6 +30,36 @@ class CuraEngineBackend(Backend): if (type(source) is not SceneNode) or (source is self._scene.getRoot()): return + if self._sceneChangeTimer: + return + + self._sceneChangeTimer = threading.Timer(1, self._sceneChangeTimerFinished) + self._sceneChangeTimer.start() + + def _onSlicedObjectListMessage(self, message): + job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message) + job.start() + + def _onProgressMessage(self, message): + self.processingProgress.emit(message.amount) + + def _onGCodeMessage(self, message): + job = ProcessGCodeJob.ProcessGCodeJob(message) + job.start() + + def _onObjectPrintTimeMessage(self, message): + pass + + def _createSocket(self): + super()._createSocket() + + self._socket.registerMessageType(1, Cura_pb2.ObjectList) + self._socket.registerMessageType(2, Cura_pb2.SlicedObjectList) + self._socket.registerMessageType(3, Cura_pb2.Progress) + self._socket.registerMessageType(4, Cura_pb2.GCode) + self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) + + def _sceneChangeTimerFinished(self): objects = [] for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is SceneNode and node.getMeshData(): @@ -50,24 +84,4 @@ class CuraEngineBackend(Backend): self._socket.sendMessage(msg) - def _onSlicedObjectListMessage(self, message): - job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message) - job.start() - - def _onProgressMessage(self, message): - self.processingProgress.emit(message.amount) - - def _onGCodeMessage(self, message): - pass - - def _onObjectPrintTimeMessage(self, message): - pass - - def _createSocket(self): - super()._createSocket() - - self._socket.registerMessageType(1, Cura_pb2.ObjectList) - self._socket.registerMessageType(2, Cura_pb2.SlicedObjectList) - self._socket.registerMessageType(3, Cura_pb2.Progress) - self._socket.registerMessageType(4, Cura_pb2.GCode) - self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) + self._sceneChangeTimer = None From a77a95eec8c133aeec0058f0d14555a0d6092cbe Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 29 Jan 2015 16:47:51 +0100 Subject: [PATCH 18/76] Send settings to the slicer on change --- CuraEngineBackend.py | 44 +++++++++++++++++++---- Cura_pb2.py | 86 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 8 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index f0d18c079e..de1fc273ea 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -9,6 +9,7 @@ from . import ProcessSlicedObjectListJob from . import ProcessGCodeJob import threading +import struct class CuraEngineBackend(Backend): def __init__(self): @@ -16,7 +17,11 @@ class CuraEngineBackend(Backend): self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) - self._sceneChangeTimer = None + + self._settings = Application.getInstance().getMachineSettings() + self._settings.settingChanged.connect(self._onSettingChanged) + + self._changeTimer = None self._message_handlers[Cura_pb2.SlicedObjectList] = self._onSlicedObjectListMessage self._message_handlers[Cura_pb2.Progress] = self._onProgressMessage @@ -30,11 +35,10 @@ class CuraEngineBackend(Backend): if (type(source) is not SceneNode) or (source is self._scene.getRoot()): return - if self._sceneChangeTimer: - return + self._onChanged() - self._sceneChangeTimer = threading.Timer(1, self._sceneChangeTimerFinished) - self._sceneChangeTimer.start() + def _onSettingChanged(self, setting): + self._onChanged() def _onSlicedObjectListMessage(self, message): job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message) @@ -59,12 +63,36 @@ class CuraEngineBackend(Backend): self._socket.registerMessageType(4, Cura_pb2.GCode) self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) - def _sceneChangeTimerFinished(self): + def _onChanged(self): + if self._changeTimer: + return + + self._changeTimer = threading.Timer(1, self._onChangeTimerFinished) + self._changeTimer.start() + + def _onChangeTimerFinished(self): objects = [] for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is SceneNode and node.getMeshData(): objects.append(node) + if not objects: + return #No point in slicing an empty build plate + + msg = Cura_pb2.SettingList() + for setting in self._settings.getAllSettings(): + s = msg.settings.add() + s.name = setting.getKey() + + if setting.getType() == 'float': + s.value = struct.pack('!f', setting.getValue()) + elif setting.getType() == 'int' or setting.getType() == 'enum': + s.value = struct.pack('!i', setting.getValue()) + + self._socket.sendMessage(msg) + + self._scene.acquireLock() + msg = Cura_pb2.ObjectList() for object in objects: meshData = object.getMeshData() @@ -82,6 +110,8 @@ class CuraEngineBackend(Backend): #if meshData.hasIndices(): #obj.indices = meshData.getIndicesAsByteArray() + self._scene.releaseLock() + self._socket.sendMessage(msg) - self._sceneChangeTimer = None + self._changeTimer = None diff --git a/Cura_pb2.py b/Cura_pb2.py index 3455a59c89..37d677bd76 100644 --- a/Cura_pb2.py +++ b/Cura_pb2.py @@ -18,7 +18,7 @@ _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='Cura.proto', package='Cura', - serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"\x19\n\x05GCode\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\x62\x06proto3') + serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"\x19\n\x05GCode\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x62\x06proto3') ) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -382,12 +382,80 @@ _OBJECTPRINTTIME = _descriptor.Descriptor( serialized_end=567, ) + +_SETTINGLIST = _descriptor.Descriptor( + name='SettingList', + full_name='Cura.SettingList', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='settings', full_name='Cura.SettingList.settings', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=569, + serialized_end=615, +) + + +_SETTING = _descriptor.Descriptor( + name='Setting', + full_name='Cura.Setting', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='Cura.Setting.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='value', full_name='Cura.Setting.value', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=617, + serialized_end=655, +) + _OBJECTLIST.fields_by_name['objects'].message_type = _OBJECT _SLICEDOBJECTLIST.fields_by_name['objects'].message_type = _SLICEDOBJECT _SLICEDOBJECT.fields_by_name['layers'].message_type = _LAYER _LAYER.fields_by_name['polygons'].message_type = _POLYGON _POLYGON.fields_by_name['type'].enum_type = _POLYGON_TYPE _POLYGON_TYPE.containing_type = _POLYGON +_SETTINGLIST.fields_by_name['settings'].message_type = _SETTING DESCRIPTOR.message_types_by_name['ObjectList'] = _OBJECTLIST DESCRIPTOR.message_types_by_name['Object'] = _OBJECT DESCRIPTOR.message_types_by_name['Progress'] = _PROGRESS @@ -397,6 +465,8 @@ DESCRIPTOR.message_types_by_name['Layer'] = _LAYER DESCRIPTOR.message_types_by_name['Polygon'] = _POLYGON DESCRIPTOR.message_types_by_name['GCode'] = _GCODE DESCRIPTOR.message_types_by_name['ObjectPrintTime'] = _OBJECTPRINTTIME +DESCRIPTOR.message_types_by_name['SettingList'] = _SETTINGLIST +DESCRIPTOR.message_types_by_name['Setting'] = _SETTING ObjectList = _reflection.GeneratedProtocolMessageType('ObjectList', (_message.Message,), dict( DESCRIPTOR = _OBJECTLIST, @@ -461,5 +531,19 @@ ObjectPrintTime = _reflection.GeneratedProtocolMessageType('ObjectPrintTime', (_ )) _sym_db.RegisterMessage(ObjectPrintTime) +SettingList = _reflection.GeneratedProtocolMessageType('SettingList', (_message.Message,), dict( + DESCRIPTOR = _SETTINGLIST, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.SettingList) + )) +_sym_db.RegisterMessage(SettingList) + +Setting = _reflection.GeneratedProtocolMessageType('Setting', (_message.Message,), dict( + DESCRIPTOR = _SETTING, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.Setting) + )) +_sym_db.RegisterMessage(Setting) + # @@protoc_insertion_point(module_scope) From e5e621e511493a147f8ed3a7bae401874b5e5ef1 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 6 Feb 2015 17:48:56 +0100 Subject: [PATCH 19/76] Update name and displayName for a bunch of plugins --- __init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index 7caa8dafa1..40fd5200af 100644 --- a/__init__.py +++ b/__init__.py @@ -4,7 +4,7 @@ from . import CuraEngineBackend from UM.Preferences import Preferences def getMetaData(): - return { "name": "CuraBackend", "type": "Backend" } + return { "name": "CuraEngine Backend", "type": "Backend" } def register(app): Preferences.addPreference("BackendLocation","../PinkUnicornEngine/CuraEngine") From b02e98696febdac215813d40db2b6465da2da1a2 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 Feb 2015 13:53:15 +0100 Subject: [PATCH 20/76] Do not make the "processing list of sliced objects" job visible --- ProcessSlicedObjectListJob.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index 1080a9d4e8..f92832e234 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -11,7 +11,7 @@ import struct class ProcessSlicedObjectListJob(Job): def __init__(self, message): - super().__init__(description = 'Processing sliced object', visible = True) + super().__init__(description = 'Processing sliced object') self._message = message self._scene = Application.getInstance().getController().getScene() From 6f825598c1f3da626b5fac3978032f3907f5b017 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 Feb 2015 15:10:11 +0100 Subject: [PATCH 21/76] Correctl send settings over to the Cura engine --- CuraEngineBackend.py | 182 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 170 insertions(+), 12 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index de1fc273ea..5583a3270e 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -3,6 +3,7 @@ from UM.Application import Application from UM.Scene.SceneNode import SceneNode from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Preferences import Preferences +from UM.Math.Vector import Vector from . import Cura_pb2 from . import ProcessSlicedObjectListJob @@ -10,6 +11,7 @@ from . import ProcessGCodeJob import threading import struct +import numpy class CuraEngineBackend(Backend): def __init__(self): @@ -62,6 +64,7 @@ class CuraEngineBackend(Backend): self._socket.registerMessageType(3, Cura_pb2.Progress) self._socket.registerMessageType(4, Cura_pb2.GCode) self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) + self._socket.registerMessageType(6, Cura_pb2.SettingList) def _onChanged(self): if self._changeTimer: @@ -77,30 +80,26 @@ class CuraEngineBackend(Backend): objects.append(node) if not objects: + self._changeTimer = None return #No point in slicing an empty build plate - msg = Cura_pb2.SettingList() - for setting in self._settings.getAllSettings(): - s = msg.settings.add() - s.name = setting.getKey() - - if setting.getType() == 'float': - s.value = struct.pack('!f', setting.getValue()) - elif setting.getType() == 'int' or setting.getType() == 'enum': - s.value = struct.pack('!i', setting.getValue()) - - self._socket.sendMessage(msg) + self._sendSettings() self._scene.acquireLock() msg = Cura_pb2.ObjectList() + + #TODO: All at once/one at a time mode + center = Vector() for object in objects: + center += object.getPosition() + meshData = object.getMeshData() obj = msg.objects.add() obj.id = id(object) - verts = meshData.getVertices() + verts = numpy.array(meshData.getVertices(), copy=True) verts[:,[1,2]] = verts[:,[2,1]] obj.vertices = verts.tostring() @@ -112,6 +111,165 @@ class CuraEngineBackend(Backend): self._scene.releaseLock() + center /= float(len(objects)) + if not self._settings.getSettingValueByKey('machine_center_is_zero'): + center.setX(center.x + self._settings.getSettingValueByKey('machine_width') / 2) + center.setZ(center.z + self._settings.getSettingValueByKey('machine_depth') / 2) + + posmsg = Cura_pb2.SettingList() + posX = posmsg.settings.add() + posX.name = 'position.X' + posX.value = str(int(center.x * 1000)).encode('utf-8') + posY = posmsg.settings.add() + posY.name = 'position.Y' + posY.value = str(int(center.z * 1000)).encode('utf-8') + posZ = posmsg.settings.add() + posZ.name = 'position.Z' + posZ.value = str(int(0)).encode('utf-8') + self._socket.sendMessage(posmsg) + self._socket.sendMessage(msg) self._changeTimer = None + + def _sendSettings(self): + extruder = 0 + + settings = { + 'extruderNr': extruder, + 'layerThickness': int(self._settings.getSettingValueByKey('layer_height') * 1000), + 'initialLayerThickness': int(self._settings.getSettingValueByKey('layer_height_0') * 1000), + 'printTemperature': int(self._settings.getSettingValueByKey('material_print_temperature')), + 'filamentDiameter': int(self._settings.getSettingValueByKey('material_diameter') * 1000), + 'filamentFlow': int(self._settings.getSettingValueByKey('material_flow')), + 'layer0extrusionWidth': int(self._settings.getSettingValueByKey('wall_line_width_0') * 1000), + 'extrusionWidth': int(self._settings.getSettingValueByKey('wall_line_width_x') * 1000), + 'insetCount': int(self._settings.getSettingValueByKey('wall_line_count')), + 'downSkinCount': int(self._settings.getSettingValueByKey('bottom_layers')), + 'upSkinCount': int(self._settings.getSettingValueByKey('top_layers')), + #'skirtDistance': int(self._settings.getSettingValueByKey('skirt_gap') * 1000), + #'skirtLineCount': int(fbk('skirt_line_count')), + #'skirtMinLength': int(fbk('skirt_minimal_length') * 1000), + + 'retractionAmount': int(self._settings.getSettingValueByKey('retraction_amount') * 1000), + 'retractionAmountPrime': int(0 * 1000), + # 'retractionAmountExtruderSwitch': int(fbk('') * 1000), + 'retractionSpeed': int(self._settings.getSettingValueByKey('retraction_speed')), + 'retractionPrimeSpeed': int(self._settings.getSettingValueByKey('retraction_speed')), + 'retractionMinimalDistance': int(self._settings.getSettingValueByKey('retraction_min_travel') * 1000), + 'minimalExtrusionBeforeRetraction': int(self._settings.getSettingValueByKey('retraction_minimal_extrusion') * 1000), + 'retractionZHop': int(self._settings.getSettingValueByKey('retraction_hop') * 1000), + + 'enableCombing': 1 if self._settings.getSettingValueByKey('retraction_combing') else 0, + # 'enableOozeShield': int(fbk('') * 1000), + # 'wipeTowerSize': int(fbk('') * 1000), + # 'multiVolumeOverlap': int(fbk('') * 1000), + + 'initialSpeedupLayers': int(self._settings.getSettingValueByKey('speed_slowdown_layers')), + 'initialLayerSpeed': int(self._settings.getSettingValueByKey('speed_layer_0')), + 'skirtSpeed': int(self._settings.getSettingValueByKey('skirt_speed')), + 'inset0Speed': int(self._settings.getSettingValueByKey('speed_wall_0')), + 'insetXSpeed': int(self._settings.getSettingValueByKey('speed_wall_x')), + 'supportSpeed': int(self._settings.getSettingValueByKey('speed_support')), + 'moveSpeed': int(self._settings.getSettingValueByKey('speed_travel')), + #'fanFullOnLayerNr': int(fbk('cool_fan_full_layer')), + + 'infillOverlap': int(self._settings.getSettingValueByKey('fill_overlap')), + 'infillSpeed': int(self._settings.getSettingValueByKey('speed_infill')), + + 'minimalLayerTime': int(self._settings.getSettingValueByKey('cool_min_layer_time')), + 'minimalFeedrate': int(self._settings.getSettingValueByKey('cool_min_speed')), + 'coolHeadLift': 1 if self._settings.getSettingValueByKey('cool_lift_head') else 0, + 'fanSpeedMin': int(self._settings.getSettingValueByKey('cool_fan_speed_min')), + 'fanSpeedMax': int(self._settings.getSettingValueByKey('cool_fan_speed_max')), + + #'spiralizeMode': 1 if vbk('magic_spiralize') == 'True' else 0, + + } + + if self._settings.getSettingValueByKey('top_bottom_pattern') == 'lines': + settings['skinPattern'] = 'SKIN_LINES' + elif self._settings.getSettingValueByKey('top_bottom_pattern') == 'concentric': + settings['skinPattern'] = 'SKIN_CONCENTRIC' + + if self._settings.getSettingValueByKey('fill_pattern') == 'Grid': + settings['infillPattern'] = 'INFILL_GRID' + elif self._settings.getSettingValueByKey('fill_pattern') == 'Lines': + settings['infillPattern'] = 'INFILL_LINES' + elif self._settings.getSettingValueByKey('fill_pattern') == 'concentric': + settings['infillPattern'] = 'INFILL_CONCENTRIC' + + #if vbk('adhesion_type') == 'raft': + #settings['raftMargin'] = int(fbk('raft_margin') * 1000) + #settings['raftLineSpacing'] = int(fbk('raft_line_spacing') * 1000) + #settings['raftBaseThickness'] = int(fbk('raft_base_thickness') * 1000) + #settings['raftBaseLinewidth'] = int(fbk('raft_base_linewidth') * 1000) + #settings['raftBaseSpeed'] = int(fbk('raft_base_speed') * 1000) + #settings['raftInterfaceThickness'] = int(fbk('raft_interface_thickness') * 1000) + #settings['raftInterfaceLinewidth'] = int(fbk('raft_interface_linewidth') * 1000) + #settings['raftInterfaceLineSpacing'] = int(fbk('raft_line_spacing') * 1000) + #settings['raftFanSpeed'] = 0 + #settings['raftSurfaceThickness'] = int(fbk('layer_height_0') * 1000) + #settings['raftSurfaceLinewidth'] = int(fbk('wall_line_width_x') * 1000) + #settings['raftSurfaceLineSpacing'] = int(fbk('wall_line_width_x') * 1000) + #settings['raftSurfaceLayers'] = int(fbk('raft_surface_layers')) + #settings['raftSurfaceSpeed'] = int(fbk('speed_layer_0') * 1000) + #settings['raftAirGap'] = int(fbk('raft_airgap') * 1000) + #settings['skirtLineCount'] = 0 + #if vbk('adhesion_type') == 'brim': + #settings['skirtDistance'] = 0 + #settings['skirtLineCount'] = int(fbk('brim_line_count')) + #if vbk('support_type') == '': + #settings['supportType'] = '' + #settings['supportAngle'] = -1 + #else: + #settings['supportType'] = 'GRID' + #settings['supportAngle'] = int(fbk('support_angle')) + #settings['supportEverywhere'] = 1 if vbk('support_type') == 'everywhere' else 0 + #settings['supportLineDistance'] = int(100 * fbk('wall_line_width_x') * 1000 / fbk('support_fill_rate')) + #settings['supportXYDistance'] = int(fbk('support_xy_distance') * 1000) + #settings['supportZDistance'] = int(fbk('support_z_distance') * 1000) + #settings['supportExtruder'] = -1 + #if vbk('support_pattern') == 'grid': + #settings['supportType'] = 'GRID' + #elif vbk('support_pattern') == 'lines': + #settings['supportType'] = 'LINES' + + settings['sparseInfillLineDistance'] = -1 + if self._settings.getSettingValueByKey('fill_sparse_density') >= 100: + settings['sparseInfillLineDistance'] = self._settings.getSettingValueByKey('wall_line_width_x') + settings['downSkinCount'] = 10000 + settings['upSkinCount'] = 10000 + elif self._settings.getSettingValueByKey('fill_sparse_density') > 0: + settings['sparseInfillLineDistance'] = int(100 * self._settings.getSettingValueByKey('wall_line_width_x') * 1000 / self._settings.getSettingValueByKey('fill_sparse_density')) + settings['sparseInfillCombineCount'] = int(round(self._settings.getSettingValueByKey('fill_sparse_combine'))) + + gcodeFlavor = self._settings.getSettingValueByKey('machine_gcode_flavor') + if gcodeFlavor == 'UltiGCode': + settings['gcodeFlavor'] = 1 + elif gcodeFlavor == 'Makerbot': + settings['gcodeFlavor'] = 2 + elif gcodeFlavor == 'BFB': + settings['gcodeFlavor'] = 3 + elif gcodeFlavor == 'Mach3': + settings['gcodeFlavor'] = 4 + elif gcodeFlavor == 'Volumetric': + settings['gcodeFlavor'] = 5 + else: + settings['gcodeFlavor'] = 0 + + settings['startCode'] = self._settings.getSettingValueByKey('machine_start_gcode') + settings['endCode'] = self._settings.getSettingValueByKey('machine_end_gcode') + + #for n in range(1, self._machine.getMaxNozzles()): + n = 1 + settings['extruderOffset1.X'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_x_1') * 1000) + settings['extruderOffset1.Y'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_y_1') * 1000) + + msg = Cura_pb2.SettingList() + for key, value in settings.items(): + s = msg.settings.add() + s.name = key + s.value = str(value).encode('utf-8') + + self._socket.sendMessage(msg) From 645a179bc317933c18c47bed4b32103668376f50 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 12 Feb 2015 17:55:56 +0100 Subject: [PATCH 22/76] Account for center and proper layer height when displaying the sliced layers --- CuraEngineBackend.py | 6 +++++- ProcessSlicedObjectListJob.py | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 5583a3270e..06d61c62dd 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -30,6 +30,8 @@ class CuraEngineBackend(Backend): self._message_handlers[Cura_pb2.GCode] = self._onGCodeMessage self._message_handlers[Cura_pb2.ObjectPrintTime] = self._onObjectPrintTimeMessage + self._center = None + def getEngineCommand(self): return [Preferences.getPreference("BackendLocation"), '--connect', "127.0.0.1:{0}".format(self._port)] @@ -43,7 +45,7 @@ class CuraEngineBackend(Backend): self._onChanged() def _onSlicedObjectListMessage(self, message): - job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message) + job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message, self._center) job.start() def _onProgressMessage(self, message): @@ -128,6 +130,8 @@ class CuraEngineBackend(Backend): posZ.value = str(int(0)).encode('utf-8') self._socket.sendMessage(posmsg) + self._center = center + self._socket.sendMessage(msg) self._changeTimer = None diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index f92832e234..2819153758 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -10,10 +10,11 @@ import numpy import struct class ProcessSlicedObjectListJob(Job): - def __init__(self, message): + def __init__(self, message, center): super().__init__(description = 'Processing sliced object') self._message = message self._scene = Application.getInstance().getController().getScene() + self._center = center def run(self): objectIdMap = {} @@ -21,6 +22,8 @@ class ProcessSlicedObjectListJob(Job): if type(node) is SceneNode and node.getMeshData(): objectIdMap[id(node)] = node + layerHeight = Application.getInstance().getMachineSettings().getSettingValueByKey('layer_height') + for object in self._message.objects: mesh = objectIdMap[object.id].getMeshData() @@ -31,7 +34,9 @@ class ProcessSlicedObjectListJob(Job): points = points.reshape((-1,2)) # We get a linear list of pairs that make up the points, so make numpy interpret them correctly. points = numpy.asarray(points, dtype=numpy.float32) points /= 1000 - points = numpy.insert(points, 1, layer.id / 10, axis = 1) + points = numpy.insert(points, 1, layer.id * layerHeight, axis = 1) + points[:,0] -= self._center.x + points[:,2] -= self._center.z layerData.addPolygon(layer.id, polygon.type, points) mesh.layerData = layerData From 201ea272b0af216b5fefe18a640e8c57fab2b52b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 12 Feb 2015 17:56:22 +0100 Subject: [PATCH 23/76] Send some more settings to the backend --- CuraEngineBackend.py | 53 +++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 06d61c62dd..244536e7c6 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -151,9 +151,9 @@ class CuraEngineBackend(Backend): 'insetCount': int(self._settings.getSettingValueByKey('wall_line_count')), 'downSkinCount': int(self._settings.getSettingValueByKey('bottom_layers')), 'upSkinCount': int(self._settings.getSettingValueByKey('top_layers')), - #'skirtDistance': int(self._settings.getSettingValueByKey('skirt_gap') * 1000), - #'skirtLineCount': int(fbk('skirt_line_count')), - #'skirtMinLength': int(fbk('skirt_minimal_length') * 1000), + 'skirtDistance': int(self._settings.getSettingValueByKey('skirt_gap') * 1000), + 'skirtLineCount': int(self._settings.getSettingValueByKey('skirt_line_count')), + 'skirtMinLength': int(self._settings.getSettingValueByKey('skirt_minimal_length') * 1000), 'retractionAmount': int(self._settings.getSettingValueByKey('retraction_amount') * 1000), 'retractionAmountPrime': int(0 * 1000), @@ -184,8 +184,8 @@ class CuraEngineBackend(Backend): 'minimalLayerTime': int(self._settings.getSettingValueByKey('cool_min_layer_time')), 'minimalFeedrate': int(self._settings.getSettingValueByKey('cool_min_speed')), 'coolHeadLift': 1 if self._settings.getSettingValueByKey('cool_lift_head') else 0, - 'fanSpeedMin': int(self._settings.getSettingValueByKey('cool_fan_speed_min')), - 'fanSpeedMax': int(self._settings.getSettingValueByKey('cool_fan_speed_max')), + 'fanSpeedMin': self._settings.getSettingValueByKey('cool_fan_speed_min'), + 'fanSpeedMax': self._settings.getSettingValueByKey('cool_fan_speed_max'), #'spiralizeMode': 1 if vbk('magic_spiralize') == 'True' else 0, @@ -203,26 +203,29 @@ class CuraEngineBackend(Backend): elif self._settings.getSettingValueByKey('fill_pattern') == 'concentric': settings['infillPattern'] = 'INFILL_CONCENTRIC' - #if vbk('adhesion_type') == 'raft': - #settings['raftMargin'] = int(fbk('raft_margin') * 1000) - #settings['raftLineSpacing'] = int(fbk('raft_line_spacing') * 1000) - #settings['raftBaseThickness'] = int(fbk('raft_base_thickness') * 1000) - #settings['raftBaseLinewidth'] = int(fbk('raft_base_linewidth') * 1000) - #settings['raftBaseSpeed'] = int(fbk('raft_base_speed') * 1000) - #settings['raftInterfaceThickness'] = int(fbk('raft_interface_thickness') * 1000) - #settings['raftInterfaceLinewidth'] = int(fbk('raft_interface_linewidth') * 1000) - #settings['raftInterfaceLineSpacing'] = int(fbk('raft_line_spacing') * 1000) - #settings['raftFanSpeed'] = 0 - #settings['raftSurfaceThickness'] = int(fbk('layer_height_0') * 1000) - #settings['raftSurfaceLinewidth'] = int(fbk('wall_line_width_x') * 1000) - #settings['raftSurfaceLineSpacing'] = int(fbk('wall_line_width_x') * 1000) - #settings['raftSurfaceLayers'] = int(fbk('raft_surface_layers')) - #settings['raftSurfaceSpeed'] = int(fbk('speed_layer_0') * 1000) - #settings['raftAirGap'] = int(fbk('raft_airgap') * 1000) - #settings['skirtLineCount'] = 0 - #if vbk('adhesion_type') == 'brim': - #settings['skirtDistance'] = 0 - #settings['skirtLineCount'] = int(fbk('brim_line_count')) + adhesion_type = self._settings.getSettingValueByKey('adhesion_type') + if adhesion_type == 'Raft': + settings['raftMargin'] = int(self._settings.getSettingValueByKey('raft_margin') * 1000) + settings['raftLineSpacing'] = int(self._settings.getSettingValueByKey('raft_line_spacing') * 1000) + settings['raftBaseThickness'] = int(self._settings.getSettingValueByKey('raft_base_thickness') * 1000) + settings['raftBaseLinewidth'] = int(self._settings.getSettingValueByKey('raft_base_linewidth') * 1000) + settings['raftBaseSpeed'] = int(self._settings.getSettingValueByKey('raft_base_speed') * 1000) + settings['raftInterfaceThickness'] = int(self._settings.getSettingValueByKey('raft_interface_thickness') * 1000) + settings['raftInterfaceLinewidth'] = int(self._settings.getSettingValueByKey('raft_interface_linewidth') * 1000) + settings['raftInterfaceLineSpacing'] = int(self._settings.getSettingValueByKey('raft_line_spacing') * 1000) + settings['raftFanSpeed'] = 0 + settings['raftSurfaceThickness'] = int(self._settings.getSettingValueByKey('layer_height_0') * 1000) + settings['raftSurfaceLinewidth'] = int(self._settings.getSettingValueByKey('wall_line_width_x') * 1000) + settings['raftSurfaceLineSpacing'] = int(self._settings.getSettingValueByKey('wall_line_width_x') * 1000) + settings['raftSurfaceLayers'] = int(self._settings.getSettingValueByKey('raft_surface_layers')) + settings['raftSurfaceSpeed'] = int(self._settings.getSettingValueByKey('speed_layer_0') * 1000) + settings['raftAirGap'] = int(self._settings.getSettingValueByKey('raft_airgap') * 1000) + settings['skirtLineCount'] = 0 + pass + elif adhesion_type == 'Brim': + settings['skirtDistance'] = 0 + settings['skirtLineCount'] = self._settings.getSettingValueByKey('brim_line_count') + #if vbk('support_type') == '': #settings['supportType'] = '' #settings['supportAngle'] = -1 From 227d9600dc4db7d750f7565983ed2b0e1ab19d9e Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 13 Feb 2015 18:04:32 +0100 Subject: [PATCH 24/76] Make the available machines a list and do not assume we have an active machine everywhere in the code --- CuraEngineBackend.py | 17 +++++++++++++++-- ProcessSlicedObjectListJob.py | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 244536e7c6..11c4ac85e4 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -20,8 +20,9 @@ class CuraEngineBackend(Backend): self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) - self._settings = Application.getInstance().getMachineSettings() - self._settings.settingChanged.connect(self._onSettingChanged) + self._settings = None + Application.getInstance().activeMachineChanged.connect(self._onActiveMachineChanged) + self._onActiveMachineChanged() self._changeTimer = None @@ -41,6 +42,15 @@ class CuraEngineBackend(Backend): self._onChanged() + def _onActiveMachineChanged(self): + if self._settings: + self._settings.settingChanged.disconnect(self._onSettingChanged) + + self._settings = Application.getInstance().getActiveMachine() + if self._settings: + self._settings.settingChanged.connect(self._onSettingChanged) + self._onChanged() + def _onSettingChanged(self, setting): self._onChanged() @@ -69,6 +79,9 @@ class CuraEngineBackend(Backend): self._socket.registerMessageType(6, Cura_pb2.SettingList) def _onChanged(self): + if not self._settings: + return + if self._changeTimer: return diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index 2819153758..7cb5fa6760 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -22,7 +22,7 @@ class ProcessSlicedObjectListJob(Job): if type(node) is SceneNode and node.getMeshData(): objectIdMap[id(node)] = node - layerHeight = Application.getInstance().getMachineSettings().getSettingValueByKey('layer_height') + layerHeight = Application.getInstance().getActiveMachine().getSettingValueByKey('layer_height') for object in self._message.objects: mesh = objectIdMap[object.id].getMeshData() From 2f1f2dbb13d8f442eefc3c2e8923ba34a08accc2 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 19 Feb 2015 17:34:04 +0100 Subject: [PATCH 25/76] Enable the missing settings to be sent to the backend --- CuraEngineBackend.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 11c4ac85e4..489ecc79ae 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -200,7 +200,7 @@ class CuraEngineBackend(Backend): 'fanSpeedMin': self._settings.getSettingValueByKey('cool_fan_speed_min'), 'fanSpeedMax': self._settings.getSettingValueByKey('cool_fan_speed_max'), - #'spiralizeMode': 1 if vbk('magic_spiralize') == 'True' else 0, + 'spiralizeMode': 1 if self._settings.getSettingValueByKey('magic_spiralize') == 'True' else 0, } @@ -239,21 +239,21 @@ class CuraEngineBackend(Backend): settings['skirtDistance'] = 0 settings['skirtLineCount'] = self._settings.getSettingValueByKey('brim_line_count') - #if vbk('support_type') == '': - #settings['supportType'] = '' - #settings['supportAngle'] = -1 - #else: - #settings['supportType'] = 'GRID' - #settings['supportAngle'] = int(fbk('support_angle')) - #settings['supportEverywhere'] = 1 if vbk('support_type') == 'everywhere' else 0 - #settings['supportLineDistance'] = int(100 * fbk('wall_line_width_x') * 1000 / fbk('support_fill_rate')) - #settings['supportXYDistance'] = int(fbk('support_xy_distance') * 1000) - #settings['supportZDistance'] = int(fbk('support_z_distance') * 1000) - #settings['supportExtruder'] = -1 - #if vbk('support_pattern') == 'grid': - #settings['supportType'] = 'GRID' - #elif vbk('support_pattern') == 'lines': - #settings['supportType'] = 'LINES' + if self._settings.getSettingValueByKey('support_type') == 'None': + settings['supportType'] = '' + settings['supportAngle'] = -1 + else: + settings['supportType'] = 'GRID' + settings['supportAngle'] = self._settings.getSettingValueByKey('support_angle') + settings['supportEverywhere'] = 1 if self._settings.getSettingValueByKey('support_type') == 'Everywhere' else 0 + settings['supportLineDistance'] = int(100 * self._settings.getSettingValueByKey('wall_line_width_x') * 1000 / self._settings.getSettingValueByKey('support_fill_rate')) + settings['supportXYDistance'] = int(self._settings.getSettingValueByKey('support_xy_distance') * 1000) + settings['supportZDistance'] = int(self._settings.getSettingValueByKey('support_z_distance') * 1000) + settings['supportExtruder'] = -1 + if self._settings.getSettingValueByKey('support_pattern') == 'Grid': + settings['supportType'] = 'GRID' + elif self._settings.getSettingValueByKey('support_pattern') == 'Lines': + settings['supportType'] = 'LINES' settings['sparseInfillLineDistance'] = -1 if self._settings.getSettingValueByKey('fill_sparse_density') >= 100: From 71514cf3ff2cb998bb419a9d172469bb7d34ab49 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 24 Feb 2015 15:05:38 +0100 Subject: [PATCH 26/76] added erea support generation options --- CuraEngineBackend.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 489ecc79ae..72ad3efcea 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -243,12 +243,17 @@ class CuraEngineBackend(Backend): settings['supportType'] = '' settings['supportAngle'] = -1 else: - settings['supportType'] = 'GRID' + settings['areaSupportPolyGenerator'] = 1 + settings['supportType'] = 'LINES' settings['supportAngle'] = self._settings.getSettingValueByKey('support_angle') settings['supportEverywhere'] = 1 if self._settings.getSettingValueByKey('support_type') == 'Everywhere' else 0 settings['supportLineDistance'] = int(100 * self._settings.getSettingValueByKey('wall_line_width_x') * 1000 / self._settings.getSettingValueByKey('support_fill_rate')) settings['supportXYDistance'] = int(self._settings.getSettingValueByKey('support_xy_distance') * 1000) settings['supportZDistance'] = int(self._settings.getSettingValueByKey('support_z_distance') * 1000) + settings['supportZDistanceBottom'] = int(self._settings.getSettingValueByKey('support_top_distance') * 1000) + settings['supportZDistanceTop'] = int(self._settings.getSettingValueByKey('support_bottom_distance') * 1000) + settings['supportJoinDistance'] = int(self._settings.getSettingValueByKey('support_join_distance') * 1000) + settings['supportBridgeBack'] = int(self._settings.getSettingValueByKey('support_bridge_back')) settings['supportExtruder'] = -1 if self._settings.getSettingValueByKey('support_pattern') == 'Grid': settings['supportType'] = 'GRID' From b158e65839b9b662d56bd43dfd362ad26da70184 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 3 Mar 2015 14:51:47 +0100 Subject: [PATCH 27/76] Update plugin's register functions to return the object instance instead of performing the registration themselves --- __init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/__init__.py b/__init__.py index 40fd5200af..780df89f1f 100644 --- a/__init__.py +++ b/__init__.py @@ -8,6 +8,5 @@ def getMetaData(): def register(app): Preferences.addPreference("BackendLocation","../PinkUnicornEngine/CuraEngine") - engine = CuraEngineBackend.CuraEngineBackend() - app.setBackend(engine) - #engine.addCommand(TransferMeshCommand()) + return CuraEngineBackend.CuraEngineBackend() + From a7ed3ae2aedcb74a351b850dfa035adda08ea05b Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 3 Mar 2015 14:55:00 +0100 Subject: [PATCH 28/76] Update plugin metadata to the new format --- __init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index 780df89f1f..706676c030 100644 --- a/__init__.py +++ b/__init__.py @@ -4,7 +4,12 @@ from . import CuraEngineBackend from UM.Preferences import Preferences def getMetaData(): - return { "name": "CuraEngine Backend", "type": "Backend" } + return { + 'type': 'backend', + 'plugin': { + 'name': "CuraEngine Backend" + } + } def register(app): Preferences.addPreference("BackendLocation","../PinkUnicornEngine/CuraEngine") From 27f475dc794d59cda3bf7516ebf5b4a4d330c85c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 3 Mar 2015 18:00:49 +0100 Subject: [PATCH 29/76] Assign processed GCode to a mesh instead of the scene --- Cura_pb2.py | 27 +++++++++++++++++---------- ProcessGCodeJob.py | 18 ++++++++++++++---- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/Cura_pb2.py b/Cura_pb2.py index 37d677bd76..855c92b4c4 100644 --- a/Cura_pb2.py +++ b/Cura_pb2.py @@ -18,7 +18,7 @@ _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='Cura.proto', package='Cura', - serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"\x19\n\x05GCode\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x62\x06proto3') + serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"%\n\x05GCode\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08\x66ilename\x18\x02 \x01(\t\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x62\x06proto3') ) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -324,8 +324,15 @@ _GCODE = _descriptor.Descriptor( containing_type=None, fields=[ _descriptor.FieldDescriptor( - name='filename', full_name='Cura.GCode.filename', index=0, - number=1, type=9, cpp_type=9, label=1, + name='id', full_name='Cura.GCode.id', index=0, + number=1, type=3, cpp_type=2, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='filename', full_name='Cura.GCode.filename', index=1, + number=2, type=9, cpp_type=9, label=1, has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -342,7 +349,7 @@ _GCODE = _descriptor.Descriptor( oneofs=[ ], serialized_start=497, - serialized_end=522, + serialized_end=534, ) @@ -378,8 +385,8 @@ _OBJECTPRINTTIME = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=524, - serialized_end=567, + serialized_start=536, + serialized_end=579, ) @@ -408,8 +415,8 @@ _SETTINGLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=569, - serialized_end=615, + serialized_start=581, + serialized_end=627, ) @@ -445,8 +452,8 @@ _SETTING = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=617, - serialized_end=655, + serialized_start=629, + serialized_end=667, ) _OBJECTLIST.fields_by_name['objects'].message_type = _OBJECT diff --git a/ProcessGCodeJob.py b/ProcessGCodeJob.py index 3fbacd67a9..712fb76e28 100644 --- a/ProcessGCodeJob.py +++ b/ProcessGCodeJob.py @@ -1,5 +1,7 @@ from UM.Job import Job from UM.Application import Application +from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator +from UM.Scene.SceneNode import SceneNode import os @@ -7,11 +9,19 @@ class ProcessGCodeJob(Job): def __init__(self, message): super().__init__() + self._scene = Application.getInstance().getController().getScene() self._message = message def run(self): - with open(self._message.filename) as f: - data = f.read(None) - Application.getInstance().getController().getScene().gcode = data + objectIdMap = {} + for node in DepthFirstIterator(self._scene.getRoot()): + if type(node) is SceneNode and node.getMeshData(): + objectIdMap[id(node)] = node - os.remove(self._message.filename) + node = objectIdMap[self._message.id] + if node: + with open(self._message.filename) as f: + data = f.read(None) + setattr(node.getMeshData(), 'gcode', data) + + os.remove(self._message.filename) From 4e6322d94e88b7a1c9c9cb2e91e3908309a9f46c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 11 Mar 2015 18:10:44 +0100 Subject: [PATCH 30/76] Move backend location preference into the backend class and use the new api --- CuraEngineBackend.py | 4 +++- __init__.py | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 72ad3efcea..70595c69dc 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -17,6 +17,8 @@ class CuraEngineBackend(Backend): def __init__(self): super().__init__() + Preferences.getInstance().addPreference('backend/location', '../PinkUnicornEngine/CuraEngine') + self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) @@ -34,7 +36,7 @@ class CuraEngineBackend(Backend): self._center = None def getEngineCommand(self): - return [Preferences.getPreference("BackendLocation"), '--connect', "127.0.0.1:{0}".format(self._port)] + return [Preferences.getInstance().getValue("backend/location"), '--connect', "127.0.0.1:{0}".format(self._port)] def _onSceneChanged(self, source): if (type(source) is not SceneNode) or (source is self._scene.getRoot()): diff --git a/__init__.py b/__init__.py index 706676c030..7bea4d0113 100644 --- a/__init__.py +++ b/__init__.py @@ -1,8 +1,6 @@ #Shoopdawoop from . import CuraEngineBackend -from UM.Preferences import Preferences - def getMetaData(): return { 'type': 'backend', @@ -12,6 +10,5 @@ def getMetaData(): } def register(app): - Preferences.addPreference("BackendLocation","../PinkUnicornEngine/CuraEngine") return CuraEngineBackend.CuraEngineBackend() From 800faf6bcf862e1bddfc7776bbf8c375523c1ce3 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 12 Mar 2015 13:31:14 +0100 Subject: [PATCH 31/76] Support colours for rendering the layer view --- LayerData.py | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/LayerData.py b/LayerData.py index 692ef97f91..84f9c613a4 100644 --- a/LayerData.py +++ b/LayerData.py @@ -1,4 +1,5 @@ from UM.Mesh.MeshData import MeshData +from UM.Math.Color import Color import numpy import math @@ -7,16 +8,22 @@ class LayerData(MeshData): def __init__(self): super().__init__() self._layers = {} + self._element_counts = [] def addPolygon(self, layer, type, data): if layer not in self._layers: self._layers[layer] = [] - self._layers[layer].append(Polygon(self, type, data)) + p = Polygon(self, type, data) + self._layers[layer].append(p) + self._element_counts.append(p.count) def getLayers(self): return self._layers + def getElementCounts(self): + return self._element_counts + class Polygon(): NoneType = 0 Inset0Type = 1 @@ -30,11 +37,30 @@ class Polygon(): self._type = type self._begin = mesh._vertex_count mesh.addVertices(data) + self._end = self._begin + len(data) - indices = [self._begin + i for i in range(len(data))] + color = None + if type == self.Inset0Type: + color = [1, 0, 0, 1] + elif type == self.InsetXType: + color = [0, 1, 0, 1] + elif type == self.SkinType: + color = [1, 1, 0, 1] + elif type == self.SupportType: + color = [0, 1, 1, 1] + elif type == self.SkirtType: + color = [0, 1, 1, 1] + else: + color = [1, 1, 1, 1] + colors = [color for i in range(len(data))] + mesh.addColors(numpy.array(colors, dtype=numpy.float32)) + + indices = [] + for i in range(self._begin, self._end): + indices.append(i) + indices.append(i + 1) mesh.addIndices(numpy.array(indices, dtype=numpy.int32)) - self._end = mesh._vertex_count @property def type(self): @@ -43,3 +69,7 @@ class Polygon(): @property def data(self): return self._data + + @property + def count(self): + return self._end - self._begin From c03a368a0d7691a35cb3c5fd13a251a8c5cf0cfb Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 13 Mar 2015 12:16:59 +0100 Subject: [PATCH 32/76] Cancel the running timer when receiving another change notification in CuraEngineBackend --- CuraEngineBackend.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 70595c69dc..18e86aba9d 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -35,6 +35,8 @@ class CuraEngineBackend(Backend): self._center = None + self._slice_interval = 0.5 + def getEngineCommand(self): return [Preferences.getInstance().getValue("backend/location"), '--connect', "127.0.0.1:{0}".format(self._port)] @@ -85,9 +87,9 @@ class CuraEngineBackend(Backend): return if self._changeTimer: - return + self._changeTimer.cancel() - self._changeTimer = threading.Timer(1, self._onChangeTimerFinished) + self._changeTimer = threading.Timer(self._slice_interval, self._onChangeTimerFinished) self._changeTimer.start() def _onChangeTimerFinished(self): From 17316edfeff5d00fe3e4adf7f872e7d229e1351f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 13 Mar 2015 13:50:01 +0100 Subject: [PATCH 33/76] Ensure we update the view when the layer data has changed --- ProcessSlicedObjectListJob.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index 7cb5fa6760..c0b98f4482 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -40,3 +40,4 @@ class ProcessSlicedObjectListJob(Job): layerData.addPolygon(layer.id, polygon.type, points) mesh.layerData = layerData + objectIdMap[object.id].meshDataChanged.emit() From 25d347691dca2c5d30dd5bdab709dcd11f6e1194 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 13 Mar 2015 13:51:42 +0100 Subject: [PATCH 34/76] Enable killing and restarting the engine when we get a change and are busy slicing --- CuraEngineBackend.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 18e86aba9d..491b4fbd67 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -4,6 +4,7 @@ from UM.Scene.SceneNode import SceneNode from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Preferences import Preferences from UM.Math.Vector import Vector +from UM.Signal import Signal from . import Cura_pb2 from . import ProcessSlicedObjectListJob @@ -37,9 +38,17 @@ class CuraEngineBackend(Backend): self._slice_interval = 0.5 + self._slicing = False + self._restart = False + + self.changeTimerFinished.connect(self._onChangeTimerFinished) + self.backendConnected.connect(self._onBackendConnected) + def getEngineCommand(self): return [Preferences.getInstance().getValue("backend/location"), '--connect', "127.0.0.1:{0}".format(self._port)] + changeTimerFinished = Signal() + def _onSceneChanged(self, source): if (type(source) is not SceneNode) or (source is self._scene.getRoot()): return @@ -63,6 +72,8 @@ class CuraEngineBackend(Backend): job.start() def _onProgressMessage(self, message): + if message.amount >= 0.99: + self._slicing = False self.processingProgress.emit(message.amount) def _onGCodeMessage(self, message): @@ -89,10 +100,16 @@ class CuraEngineBackend(Backend): if self._changeTimer: self._changeTimer.cancel() - self._changeTimer = threading.Timer(self._slice_interval, self._onChangeTimerFinished) + self._changeTimer = threading.Timer(self._slice_interval, lambda: self.changeTimerFinished.emit()) self._changeTimer.start() def _onChangeTimerFinished(self): + if self._slicing: + self._slicing = False + self._restart = True + self._process.terminate() + return + objects = [] for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is SceneNode and node.getMeshData(): @@ -102,6 +119,8 @@ class CuraEngineBackend(Backend): self._changeTimer = None return #No point in slicing an empty build plate + self._slicing = True + self._sendSettings() self._scene.acquireLock() @@ -302,3 +321,8 @@ class CuraEngineBackend(Backend): s.value = str(value).encode('utf-8') self._socket.sendMessage(msg) + + def _onBackendConnected(self): + if self._restart: + self._onChanged() + self._restart = False From 05dcd90b7854cc591c589c5be4b31a9a5f9cf2ca Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 13 Mar 2015 13:53:31 +0100 Subject: [PATCH 35/76] Emit a progress message when we start processing to improve user feedback --- CuraEngineBackend.py | 1 + 1 file changed, 1 insertion(+) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 491b4fbd67..f9bb46ce9c 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -120,6 +120,7 @@ class CuraEngineBackend(Backend): return #No point in slicing an empty build plate self._slicing = True + self.processingProgress.emit(0.0) self._sendSettings() From b751c90813bef12c377e5cafb50b71327394670f Mon Sep 17 00:00:00 2001 From: daid Date: Fri, 13 Mar 2015 18:20:10 +0100 Subject: [PATCH 36/76] Small for for when we get engine data for an object which is already removed from the scene. --- ProcessGCodeJob.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ProcessGCodeJob.py b/ProcessGCodeJob.py index 712fb76e28..195fc87747 100644 --- a/ProcessGCodeJob.py +++ b/ProcessGCodeJob.py @@ -18,10 +18,10 @@ class ProcessGCodeJob(Job): if type(node) is SceneNode and node.getMeshData(): objectIdMap[id(node)] = node - node = objectIdMap[self._message.id] - if node: + if self._message.id in objectIdMap: + node = objectIdMap[self._message.id] with open(self._message.filename) as f: data = f.read(None) setattr(node.getMeshData(), 'gcode', data) - os.remove(self._message.filename) + os.remove(self._message.filename) From 924cbaaac52c8d6ef40b3daf4dcdd3deb29497d5 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 13 Mar 2015 17:22:11 +0100 Subject: [PATCH 37/76] Fix LayerData to use the right indices for polygons --- LayerData.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/LayerData.py b/LayerData.py index 84f9c613a4..cfa2249d40 100644 --- a/LayerData.py +++ b/LayerData.py @@ -37,7 +37,7 @@ class Polygon(): self._type = type self._begin = mesh._vertex_count mesh.addVertices(data) - self._end = self._begin + len(data) + self._end = self._begin + len(data) - 1 color = None if type == self.Inset0Type: @@ -60,6 +60,9 @@ class Polygon(): for i in range(self._begin, self._end): indices.append(i) indices.append(i + 1) + + indices.append(self._end) + indices.append(self._begin) mesh.addIndices(numpy.array(indices, dtype=numpy.int32)) @property From 1f340beef1770227dffa0f3e4082bb0cc36e5f09 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 16 Mar 2015 12:03:51 +0100 Subject: [PATCH 38/76] included lots of support options and the bed temp option, massive rewrite of the support options structure --- CuraEngineBackend.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 72ad3efcea..97df6e0052 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -157,6 +157,7 @@ class CuraEngineBackend(Backend): 'layerThickness': int(self._settings.getSettingValueByKey('layer_height') * 1000), 'initialLayerThickness': int(self._settings.getSettingValueByKey('layer_height_0') * 1000), 'printTemperature': int(self._settings.getSettingValueByKey('material_print_temperature')), + 'bedTemperature': int(self._settings.getSettingValueByKey('material_bed_temperature') * 100), 'filamentDiameter': int(self._settings.getSettingValueByKey('material_diameter') * 1000), 'filamentFlow': int(self._settings.getSettingValueByKey('material_flow')), 'layer0extrusionWidth': int(self._settings.getSettingValueByKey('wall_line_width_0') * 1000), @@ -204,17 +205,19 @@ class CuraEngineBackend(Backend): } - if self._settings.getSettingValueByKey('top_bottom_pattern') == 'lines': + if self._settings.getSettingValueByKey('top_bottom_pattern') == 'Lines': settings['skinPattern'] = 'SKIN_LINES' - elif self._settings.getSettingValueByKey('top_bottom_pattern') == 'concentric': + elif self._settings.getSettingValueByKey('top_bottom_pattern') == 'Concentric': settings['skinPattern'] = 'SKIN_CONCENTRIC' if self._settings.getSettingValueByKey('fill_pattern') == 'Grid': settings['infillPattern'] = 'INFILL_GRID' elif self._settings.getSettingValueByKey('fill_pattern') == 'Lines': settings['infillPattern'] = 'INFILL_LINES' - elif self._settings.getSettingValueByKey('fill_pattern') == 'concentric': + elif self._settings.getSettingValueByKey('fill_pattern') == 'Concentric': settings['infillPattern'] = 'INFILL_CONCENTRIC' + elif self._settings.getSettingValueByKey('fill_pattern') == 'ZigZag': + settings['infillPattern'] = 'INFILL_ZIGZAG' adhesion_type = self._settings.getSettingValueByKey('adhesion_type') if adhesion_type == 'Raft': @@ -243,22 +246,27 @@ class CuraEngineBackend(Backend): settings['supportType'] = '' settings['supportAngle'] = -1 else: - settings['areaSupportPolyGenerator'] = 1 settings['supportType'] = 'LINES' settings['supportAngle'] = self._settings.getSettingValueByKey('support_angle') - settings['supportEverywhere'] = 1 if self._settings.getSettingValueByKey('support_type') == 'Everywhere' else 0 + settings['supportOnBuildplateOnly'] = 1 if self._settings.getSettingValueByKey('support_type') == 'Touching Buildplate' else 0 settings['supportLineDistance'] = int(100 * self._settings.getSettingValueByKey('wall_line_width_x') * 1000 / self._settings.getSettingValueByKey('support_fill_rate')) settings['supportXYDistance'] = int(self._settings.getSettingValueByKey('support_xy_distance') * 1000) settings['supportZDistance'] = int(self._settings.getSettingValueByKey('support_z_distance') * 1000) settings['supportZDistanceBottom'] = int(self._settings.getSettingValueByKey('support_top_distance') * 1000) settings['supportZDistanceTop'] = int(self._settings.getSettingValueByKey('support_bottom_distance') * 1000) settings['supportJoinDistance'] = int(self._settings.getSettingValueByKey('support_join_distance') * 1000) - settings['supportBridgeBack'] = int(self._settings.getSettingValueByKey('support_bridge_back')) + settings['supportAreaSmoothing'] = int(self._settings.getSettingValueByKey('support_area_smoothing') * 1000) + settings['supportMinimalAreaSqrt'] = int(self._settings.getSettingValueByKey('support_minimal_diameter') * 1000) if self._settings.getSettingValueByKey('support_use_towers') else 0 + settings['supportTowerDiameter'] = int(self._settings.getSettingValueByKey('support_tower_diameter') * 1000) + settings['supportTowerRoofAngle'] = int(self._settings.getSettingValueByKey('support_tower_roof_angle')) + settings['supportConnectZigZags'] = 1 if self._settings.getSettingValueByKey('support_connect_zigzags') else 0 settings['supportExtruder'] = -1 if self._settings.getSettingValueByKey('support_pattern') == 'Grid': settings['supportType'] = 'GRID' elif self._settings.getSettingValueByKey('support_pattern') == 'Lines': settings['supportType'] = 'LINES' + elif self._settings.getSettingValueByKey('support_pattern') == 'ZigZag': + settings['supportType'] = 'ZIGZAG' settings['sparseInfillLineDistance'] = -1 if self._settings.getSettingValueByKey('fill_sparse_density') >= 100: From 4ad75bd43c7b8cfec783598cec62ffddb4f2eb14 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 19 Mar 2015 14:24:45 +0100 Subject: [PATCH 39/76] Don't emit meshDataChanged when ProcessSlicedObjectListJob is done --- ProcessSlicedObjectListJob.py | 1 - 1 file changed, 1 deletion(-) diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index c0b98f4482..7cb5fa6760 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -40,4 +40,3 @@ class ProcessSlicedObjectListJob(Job): layerData.addPolygon(layer.id, polygon.type, points) mesh.layerData = layerData - objectIdMap[object.id].meshDataChanged.emit() From 2f9ddaf8997c939b916ac05df1f0a3a8957119fb Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 23 Mar 2015 11:43:10 +0100 Subject: [PATCH 40/76] fix of one wrong setting description (and some more stuff) --- CuraEngineBackend.py | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 6950cb1e9d..8fbe7ff839 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -174,6 +174,68 @@ class CuraEngineBackend(Backend): self._changeTimer = None def _sendSettings(self): + self._sendSettings_neith() if self._settings.getSettingValueByKey('wireframe') else self._sendSettings_normal() + + def _sendSettings_neith(self): + extruder = 0 + + settings = { + 'neith': 1, + 'extruderNr': extruder, + 'printTemperature': int(self._settings.getSettingValueByKey('material_print_temperature')), + 'bedTemperature': int(self._settings.getSettingValueByKey('material_bed_temperature') * 100), + 'filamentDiameter': int(self._settings.getSettingValueByKey('material_diameter') * 1000), + 'retractionAmount': int(self._settings.getSettingValueByKey('retraction_amount') * 1000), + 'retractionAmountPrime': int(0 * 1000), + # 'retractionAmountExtruderSwitch': int(fbk('') * 1000), + 'retractionSpeed': int(self._settings.getSettingValueByKey('retraction_speed')), + 'retractionPrimeSpeed': int(self._settings.getSettingValueByKey('retraction_speed')), + 'retractionMinimalDistance': int(self._settings.getSettingValueByKey('retraction_min_travel') * 1000), + 'retractionZHop': int(self._settings.getSettingValueByKey('retraction_hop') * 1000), + + 'moveSpeed': int(self._settings.getSettingValueByKey('speed_travel')), + + 'fanSpeedMin': self._settings.getSettingValueByKey('cool_fan_speed_min'), + 'fanSpeedMax': self._settings.getSettingValueByKey('cool_fan_speed_max'), + + # ================================ + # wireframe printing options + # ================================ + + } + + + gcodeFlavor = self._settings.getSettingValueByKey('machine_gcode_flavor') + if gcodeFlavor == 'UltiGCode': + settings['gcodeFlavor'] = 1 + elif gcodeFlavor == 'Makerbot': + settings['gcodeFlavor'] = 2 + elif gcodeFlavor == 'BFB': + settings['gcodeFlavor'] = 3 + elif gcodeFlavor == 'Mach3': + settings['gcodeFlavor'] = 4 + elif gcodeFlavor == 'Volumetric': + settings['gcodeFlavor'] = 5 + else: + settings['gcodeFlavor'] = 0 + + settings['startCode'] = self._settings.getSettingValueByKey('machine_start_gcode') + settings['endCode'] = self._settings.getSettingValueByKey('machine_end_gcode') + + #for n in range(1, self._machine.getMaxNozzles()): + n = 1 + settings['extruderOffset1.X'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_x_1') * 1000) + settings['extruderOffset1.Y'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_y_1') * 1000) + + msg = Cura_pb2.SettingList() + for key, value in settings.items(): + s = msg.settings.add() + s.name = key + s.value = str(value).encode('utf-8') + + self._socket.sendMessage(msg) + + def _sendSettings_normal(self): extruder = 0 settings = { From cefa69592a7049b192f2428d11cb64b76bc82740 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 23 Mar 2015 11:43:31 +0100 Subject: [PATCH 41/76] fix of one wrong setting description (and some more stuff) --- CuraEngineBackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 8fbe7ff839..76c107d79a 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -201,7 +201,7 @@ class CuraEngineBackend(Backend): # ================================ # wireframe printing options # ================================ - + 'wireframePrintspeed': self._settings.getSettingValueByKey('wireframe_printspeed') } From 700d2d6f6ce32923dfffa50d9d7898dbec8e6b87 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 23 Mar 2015 14:58:37 +0100 Subject: [PATCH 42/76] fixed options type and default value and backend communication (not yet structure and ordering) --- CuraEngineBackend.py | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 76c107d79a..1064abd65e 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -201,9 +201,49 @@ class CuraEngineBackend(Backend): # ================================ # wireframe printing options # ================================ - 'wireframePrintspeed': self._settings.getSettingValueByKey('wireframe_printspeed') + 'wireframeConnectionHeight': int(self._settings.getSettingValueByKey('wireframe_height')*1000), + 'wireframeNozzleClearance': int(self._settings.getSettingValueByKey('wireframe_nozzle_clearance')*1000), + + 'machineNozzleTipOuterDiameter': int(self._settings.getSettingValueByKey('machine_nozzle_tip_outer_diameter')*1000), + 'machineNozzleHeadDistance': int(self._settings.getSettingValueByKey('machine_nozzle_head_distance')*1000), + 'machineNozzleExpansionAngle': int(self._settings.getSettingValueByKey('machine_nozzle_expansion_angle')), + + 'wireframePrintspeedBottom': self._settings.getSettingValueByKey('wireframe_printspeed_bottom'), + 'wireframePrintspeedUp': self._settings.getSettingValueByKey('wireframe_printspeed_up'), + 'wireframePrintspeedDown': self._settings.getSettingValueByKey('wireframe_printspeed_down'), + 'wireframePrintspeedFlat': self._settings.getSettingValueByKey('wireframe_printspeed_flat'), + + 'wireframeFlowConnection': int(self._settings.getSettingValueByKey('wireframe_flow_connection')), + 'wireframeFlowFlat': int(self._settings.getSettingValueByKey('wireframe_flow_flat')), + + 'wireframeTopDelay': int(self._settings.getSettingValueByKey('wireframe_top_delay')*100), + 'wireframeBottomDelay': int(self._settings.getSettingValueByKey('wireframe_bottom_delay')*100), + 'wireframeFlatDelay': int(self._settings.getSettingValueByKey('wireframe_flat_delay')*100), + + 'wireframeUpDistHalfSpeed': int(self._settings.getSettingValueByKey('wireframe_up_half_speed')*1000), + 'wireframeTopJump': int(self._settings.getSettingValueByKey('wireframe_top_jump')*1000), + + 'wireframeFallDown': int(self._settings.getSettingValueByKey('wireframe_fall_down')*1000), + 'wireframeDragAlong': int(self._settings.getSettingValueByKey('wireframe_drag_along')*1000), + + 'wireframeStraightBeforeDown': int(self._settings.getSettingValueByKey('wireframe_straight_before_down')), + + + 'wireframeRoofFallDown': int(self._settings.getSettingValueByKey('wireframe_roof_fall_down')*1000), + 'wireframeRoofDragAlong': int(self._settings.getSettingValueByKey('wireframe_roof_drag_along')*1000), + 'wireframeRoofOuterDelay': int(self._settings.getSettingValueByKey('wireframe_roof_outer_delay')*100), + 'wireframeRoofInset': int(self._settings.getSettingValueByKey('wireframe_roof_inset')*1000), + + } + wireFrameStrategy = self._settings.getSettingValueByKey('wireframe_strategy') + if wireFrameStrategy == 'Compensate': + settings['wireframeStrategy' = 0 + if wireFrameStrategy == 'Knot': + settings['wireframeStrategy' = 1 + if wireFrameStrategy == 'Retract': + settings['wireframeStrategy' = 2 gcodeFlavor = self._settings.getSettingValueByKey('machine_gcode_flavor') if gcodeFlavor == 'UltiGCode': From e5ee19037ede804d55938a033e7476669283136e Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Mon, 23 Mar 2015 15:02:12 +0100 Subject: [PATCH 43/76] syntax bugfix --- CuraEngineBackend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 1064abd65e..2fb5b0ade3 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -239,11 +239,11 @@ class CuraEngineBackend(Backend): wireFrameStrategy = self._settings.getSettingValueByKey('wireframe_strategy') if wireFrameStrategy == 'Compensate': - settings['wireframeStrategy' = 0 + settings['wireframeStrategy'] = 0 if wireFrameStrategy == 'Knot': - settings['wireframeStrategy' = 1 + settings['wireframeStrategy'] = 1 if wireFrameStrategy == 'Retract': - settings['wireframeStrategy' = 2 + settings['wireframeStrategy'] = 2 gcodeFlavor = self._settings.getSettingValueByKey('machine_gcode_flavor') if gcodeFlavor == 'UltiGCode': From b614b47ed271bdf609c6e3edd64bf7ea5922a1ce Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 Mar 2015 14:56:43 +0100 Subject: [PATCH 44/76] Catch errors when objects no longer exist in backend processing jobs --- ProcessGCodeJob.py | 6 +++++- ProcessSlicedObjectListJob.py | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ProcessGCodeJob.py b/ProcessGCodeJob.py index 195fc87747..b9f9a9f2be 100644 --- a/ProcessGCodeJob.py +++ b/ProcessGCodeJob.py @@ -19,7 +19,11 @@ class ProcessGCodeJob(Job): objectIdMap[id(node)] = node if self._message.id in objectIdMap: - node = objectIdMap[self._message.id] + try: + node = objectIdMap[self._message.id] + except KeyError: + return + with open(self._message.filename) as f: data = f.read(None) setattr(node.getMeshData(), 'gcode', data) diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index 7cb5fa6760..8ca7b0fde4 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -25,7 +25,12 @@ class ProcessSlicedObjectListJob(Job): layerHeight = Application.getInstance().getActiveMachine().getSettingValueByKey('layer_height') for object in self._message.objects: - mesh = objectIdMap[object.id].getMeshData() + try: + node = objectIdMap[object.id] + except KeyError: + continue + + mesh = node.getMeshData() layerData = LayerData.LayerData() for layer in object.layers: From ad2f839dc186250655d00e2a267f3a1ad0da1c8c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 23 Mar 2015 17:57:45 +0100 Subject: [PATCH 45/76] Send the transformed mesh data to the backend --- CuraEngineBackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 2fb5b0ade3..d5e323746f 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -133,7 +133,7 @@ class CuraEngineBackend(Backend): for object in objects: center += object.getPosition() - meshData = object.getMeshData() + meshData = object.getMeshData().getTransformed(object.getGlobalTransformation()) obj = msg.objects.add() obj.id = id(object) From d85cc0f0bf85d4e2621da59e06576285e0614812 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 24 Mar 2015 12:30:23 +0100 Subject: [PATCH 46/76] Do not make center dependant on object position and correct for object position in ProcessSlicedObjectListJob --- CuraEngineBackend.py | 39 ++++++++++++++++++----------------- ProcessSlicedObjectListJob.py | 7 +++++++ 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index d5e323746f..e79f7ab3c8 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -150,25 +150,6 @@ class CuraEngineBackend(Backend): self._scene.releaseLock() - center /= float(len(objects)) - if not self._settings.getSettingValueByKey('machine_center_is_zero'): - center.setX(center.x + self._settings.getSettingValueByKey('machine_width') / 2) - center.setZ(center.z + self._settings.getSettingValueByKey('machine_depth') / 2) - - posmsg = Cura_pb2.SettingList() - posX = posmsg.settings.add() - posX.name = 'position.X' - posX.value = str(int(center.x * 1000)).encode('utf-8') - posY = posmsg.settings.add() - posY.name = 'position.Y' - posY.value = str(int(center.z * 1000)).encode('utf-8') - posZ = posmsg.settings.add() - posZ.name = 'position.Z' - posZ.value = str(int(0)).encode('utf-8') - self._socket.sendMessage(posmsg) - - self._center = center - self._socket.sendMessage(msg) self._changeTimer = None @@ -267,6 +248,16 @@ class CuraEngineBackend(Backend): settings['extruderOffset1.X'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_x_1') * 1000) settings['extruderOffset1.Y'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_y_1') * 1000) + if not self._settings.getSettingValueByKey('machine_center_is_zero'): + settings['position.X'] = int((self._settings.getSettingValueByKey('machine_width') / 2.0) * 1000) + settings['position.Y'] = int((self._settings.getSettingValueByKey('machine_depth') / 2.0) * 1000) + self._center = Vector(self._settings.getSettingValueByKey('machine_width') / 2.0, 0.0, self._settings.getSettingValueByKey('machine_depth') / 2.0) + else: + settings['position.X'] = 0 + settings['position.Y'] = 0 + self._center = Vector(0.0, 0.0, 0.0) + settings['position.Z'] = 0 + msg = Cura_pb2.SettingList() for key, value in settings.items(): s = msg.settings.add() @@ -425,6 +416,16 @@ class CuraEngineBackend(Backend): settings['extruderOffset1.X'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_x_1') * 1000) settings['extruderOffset1.Y'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_y_1') * 1000) + if not self._settings.getSettingValueByKey('machine_center_is_zero'): + settings['position.X'] = int((self._settings.getSettingValueByKey('machine_width') / 2.0) * 1000) + settings['position.Y'] = int((self._settings.getSettingValueByKey('machine_depth') / 2.0) * 1000) + self._center = Vector(self._settings.getSettingValueByKey('machine_width') / 2.0, 0.0, self._settings.getSettingValueByKey('machine_depth') / 2.0) + else: + settings['position.X'] = 0 + settings['position.Y'] = 0 + self._center = Vector(0.0, 0.0, 0.0) + settings['position.Z'] = 0 + msg = Cura_pb2.SettingList() for key, value in settings.items(): s = msg.settings.add() diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index 8ca7b0fde4..ae99e777f0 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -40,8 +40,15 @@ class ProcessSlicedObjectListJob(Job): points = numpy.asarray(points, dtype=numpy.float32) points /= 1000 points = numpy.insert(points, 1, layer.id * layerHeight, axis = 1) + points[:,0] -= self._center.x points[:,2] -= self._center.z + + points = numpy.pad(points, ((0,0), (0,1)), 'constant', constant_values=(0.0, 1.0)) + inverse = node.getGlobalTransformation().getInverse().getData() + points = points.dot(inverse) + points = points[:,0:3] + layerData.addPolygon(layer.id, polygon.type, points) mesh.layerData = layerData From e679c0a2b07a7ca0575dd4027dd61592c5000032 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 24 Mar 2015 17:25:40 +0100 Subject: [PATCH 47/76] Replace python timer with QTimer since python timer is unreliable Python's timer::cancel() method will sometimes not actually cancel the timer. So instead, use a QTimer since those are more reliable. --- CuraEngineBackend.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index e79f7ab3c8..c84f68bde7 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -14,6 +14,8 @@ import threading import struct import numpy +from PyQt5.QtCore import QTimer + class CuraEngineBackend(Backend): def __init__(self): super().__init__() @@ -27,7 +29,10 @@ class CuraEngineBackend(Backend): Application.getInstance().activeMachineChanged.connect(self._onActiveMachineChanged) self._onActiveMachineChanged() - self._changeTimer = None + self._changeTimer = QTimer() + self._changeTimer.setInterval(500) + self._changeTimer.setSingleShot(True) + self._changeTimer.timeout.connect(self._onChangeTimerFinished) self._message_handlers[Cura_pb2.SlicedObjectList] = self._onSlicedObjectListMessage self._message_handlers[Cura_pb2.Progress] = self._onProgressMessage @@ -36,12 +41,9 @@ class CuraEngineBackend(Backend): self._center = None - self._slice_interval = 0.5 - self._slicing = False self._restart = False - self.changeTimerFinished.connect(self._onChangeTimerFinished) self.backendConnected.connect(self._onBackendConnected) def getEngineCommand(self): @@ -97,10 +99,6 @@ class CuraEngineBackend(Backend): if not self._settings: return - if self._changeTimer: - self._changeTimer.cancel() - - self._changeTimer = threading.Timer(self._slice_interval, lambda: self.changeTimerFinished.emit()) self._changeTimer.start() def _onChangeTimerFinished(self): @@ -116,7 +114,6 @@ class CuraEngineBackend(Backend): objects.append(node) if not objects: - self._changeTimer = None return #No point in slicing an empty build plate self._slicing = True @@ -152,8 +149,6 @@ class CuraEngineBackend(Backend): self._socket.sendMessage(msg) - self._changeTimer = None - def _sendSettings(self): self._sendSettings_neith() if self._settings.getSettingValueByKey('wireframe') else self._sendSettings_normal() From 7aa2062fe1ef6e1488df863180cc57f72569365d Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Tue, 31 Mar 2015 13:48:31 +0200 Subject: [PATCH 48/76] added Triangles infill option, but not yet in fdmPrinter.json, so not present in hte GUI --- CuraEngineBackend.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index c84f68bde7..ee7b8a1bda 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -324,6 +324,8 @@ class CuraEngineBackend(Backend): if self._settings.getSettingValueByKey('fill_pattern') == 'Grid': settings['infillPattern'] = 'INFILL_GRID' + elif self._settings.getSettingValueByKey('fill_pattern') == 'Triangles': # TODO add option to fdmPrinter.json once it has been translated(?) + settings['infillPattern'] = 'INFILL_TRIANGLES' elif self._settings.getSettingValueByKey('fill_pattern') == 'Lines': settings['infillPattern'] = 'INFILL_LINES' elif self._settings.getSettingValueByKey('fill_pattern') == 'Concentric': From a97c241a5dc8c3e2dd3533727ca9f56e6e7759b9 Mon Sep 17 00:00:00 2001 From: daid Date: Wed, 8 Apr 2015 13:57:53 +0200 Subject: [PATCH 49/76] Use the new CuraEngine GCode protocol instead of temp files. --- CuraEngineBackend.py | 14 +++++++++----- Cura_pb2.py | 40 ++++++++++++++++++++-------------------- ProcessGCodeJob.py | 22 ++-------------------- 3 files changed, 31 insertions(+), 45 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index ee7b8a1bda..7809736988 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -20,7 +20,7 @@ class CuraEngineBackend(Backend): def __init__(self): super().__init__() - Preferences.getInstance().addPreference('backend/location', '../PinkUnicornEngine/CuraEngine') + Preferences.getInstance().addPreference('backend/location', 'C:/Software/Cura_PinkUnicornEngine/_bin/Debug/Cura_SteamEngine.exe') self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) @@ -36,7 +36,7 @@ class CuraEngineBackend(Backend): self._message_handlers[Cura_pb2.SlicedObjectList] = self._onSlicedObjectListMessage self._message_handlers[Cura_pb2.Progress] = self._onProgressMessage - self._message_handlers[Cura_pb2.GCode] = self._onGCodeMessage + self._message_handlers[Cura_pb2.GCodeLayer] = self._onGCodeLayerMessage self._message_handlers[Cura_pb2.ObjectPrintTime] = self._onObjectPrintTimeMessage self._center = None @@ -78,8 +78,8 @@ class CuraEngineBackend(Backend): self._slicing = False self.processingProgress.emit(message.amount) - def _onGCodeMessage(self, message): - job = ProcessGCodeJob.ProcessGCodeJob(message) + def _onGCodeLayerMessage(self, message): + job = ProcessGCodeJob.ProcessGCodeLayerJob(message) job.start() def _onObjectPrintTimeMessage(self, message): @@ -91,7 +91,7 @@ class CuraEngineBackend(Backend): self._socket.registerMessageType(1, Cura_pb2.ObjectList) self._socket.registerMessageType(2, Cura_pb2.SlicedObjectList) self._socket.registerMessageType(3, Cura_pb2.Progress) - self._socket.registerMessageType(4, Cura_pb2.GCode) + self._socket.registerMessageType(4, Cura_pb2.GCodeLayer) self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) self._socket.registerMessageType(6, Cura_pb2.SettingList) @@ -122,6 +122,10 @@ class CuraEngineBackend(Backend): self._sendSettings() self._scene.acquireLock() + # Set the gcode as an empty list. This will be filled with strings by GCodeLayer messages. + # This is done so the gcode can be fragmented in memory and does not need a continues memory space. + # (AKA. This prevents MemoryErrors) + setattr(self._scene, 'gcode_list', []) msg = Cura_pb2.ObjectList() diff --git a/Cura_pb2.py b/Cura_pb2.py index 855c92b4c4..090bea1089 100644 --- a/Cura_pb2.py +++ b/Cura_pb2.py @@ -18,7 +18,7 @@ _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='Cura.proto', package='Cura', - serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"%\n\x05GCode\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08\x66ilename\x18\x02 \x01(\t\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x62\x06proto3') + serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"&\n\nGCodeLayer\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x62\x06proto3') ) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -316,24 +316,24 @@ _POLYGON = _descriptor.Descriptor( ) -_GCODE = _descriptor.Descriptor( - name='GCode', - full_name='Cura.GCode', +_GCODELAYER = _descriptor.Descriptor( + name='GCodeLayer', + full_name='Cura.GCodeLayer', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ _descriptor.FieldDescriptor( - name='id', full_name='Cura.GCode.id', index=0, + name='id', full_name='Cura.GCodeLayer.id', index=0, number=1, type=3, cpp_type=2, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), _descriptor.FieldDescriptor( - name='filename', full_name='Cura.GCode.filename', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=_b("").decode('utf-8'), + name='data', full_name='Cura.GCodeLayer.data', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -349,7 +349,7 @@ _GCODE = _descriptor.Descriptor( oneofs=[ ], serialized_start=497, - serialized_end=534, + serialized_end=535, ) @@ -385,8 +385,8 @@ _OBJECTPRINTTIME = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=536, - serialized_end=579, + serialized_start=537, + serialized_end=580, ) @@ -415,8 +415,8 @@ _SETTINGLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=581, - serialized_end=627, + serialized_start=582, + serialized_end=628, ) @@ -452,8 +452,8 @@ _SETTING = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=629, - serialized_end=667, + serialized_start=630, + serialized_end=668, ) _OBJECTLIST.fields_by_name['objects'].message_type = _OBJECT @@ -470,7 +470,7 @@ DESCRIPTOR.message_types_by_name['SlicedObjectList'] = _SLICEDOBJECTLIST DESCRIPTOR.message_types_by_name['SlicedObject'] = _SLICEDOBJECT DESCRIPTOR.message_types_by_name['Layer'] = _LAYER DESCRIPTOR.message_types_by_name['Polygon'] = _POLYGON -DESCRIPTOR.message_types_by_name['GCode'] = _GCODE +DESCRIPTOR.message_types_by_name['GCodeLayer'] = _GCODELAYER DESCRIPTOR.message_types_by_name['ObjectPrintTime'] = _OBJECTPRINTTIME DESCRIPTOR.message_types_by_name['SettingList'] = _SETTINGLIST DESCRIPTOR.message_types_by_name['Setting'] = _SETTING @@ -524,12 +524,12 @@ Polygon = _reflection.GeneratedProtocolMessageType('Polygon', (_message.Message, )) _sym_db.RegisterMessage(Polygon) -GCode = _reflection.GeneratedProtocolMessageType('GCode', (_message.Message,), dict( - DESCRIPTOR = _GCODE, +GCodeLayer = _reflection.GeneratedProtocolMessageType('GCodeLayer', (_message.Message,), dict( + DESCRIPTOR = _GCODELAYER, __module__ = 'Cura_pb2' - # @@protoc_insertion_point(class_scope:Cura.GCode) + # @@protoc_insertion_point(class_scope:Cura.GCodeLayer) )) -_sym_db.RegisterMessage(GCode) +_sym_db.RegisterMessage(GCodeLayer) ObjectPrintTime = _reflection.GeneratedProtocolMessageType('ObjectPrintTime', (_message.Message,), dict( DESCRIPTOR = _OBJECTPRINTTIME, diff --git a/ProcessGCodeJob.py b/ProcessGCodeJob.py index b9f9a9f2be..4da385a58d 100644 --- a/ProcessGCodeJob.py +++ b/ProcessGCodeJob.py @@ -1,11 +1,8 @@ from UM.Job import Job from UM.Application import Application -from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator -from UM.Scene.SceneNode import SceneNode -import os -class ProcessGCodeJob(Job): +class ProcessGCodeLayerJob(Job): def __init__(self, message): super().__init__() @@ -13,19 +10,4 @@ class ProcessGCodeJob(Job): self._message = message def run(self): - objectIdMap = {} - for node in DepthFirstIterator(self._scene.getRoot()): - if type(node) is SceneNode and node.getMeshData(): - objectIdMap[id(node)] = node - - if self._message.id in objectIdMap: - try: - node = objectIdMap[self._message.id] - except KeyError: - return - - with open(self._message.filename) as f: - data = f.read(None) - setattr(node.getMeshData(), 'gcode', data) - - os.remove(self._message.filename) + self._scene.gcode_list.append(self._message.data.decode('utf-8', 'replace')) From c53bed8450e8f456d81664dc50874217368ac38e Mon Sep 17 00:00:00 2001 From: daid Date: Wed, 8 Apr 2015 14:05:33 +0200 Subject: [PATCH 50/76] Slightly improve process kill handling. --- CuraEngineBackend.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 7809736988..8154620f91 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -105,7 +105,11 @@ class CuraEngineBackend(Backend): if self._slicing: self._slicing = False self._restart = True - self._process.terminate() + if self._process is not None: + try: + self._process.terminate() + except: # terminating a process that is already terminating causes an exception, silently ignore this. + pass return objects = [] From 115c2b006e4e3557b5824d9b1779a2110830ea49 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 8 Apr 2015 17:22:30 +0200 Subject: [PATCH 51/76] Update more things to the changed SceneNode API --- CuraEngineBackend.py | 2 +- ProcessSlicedObjectListJob.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 8154620f91..d812c2c8e3 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -138,7 +138,7 @@ class CuraEngineBackend(Backend): for object in objects: center += object.getPosition() - meshData = object.getMeshData().getTransformed(object.getGlobalTransformation()) + meshData = object.getMeshData().getTransformed(object.getWorldTransformation()) obj = msg.objects.add() obj.id = id(object) diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index ae99e777f0..a324e260bc 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -45,7 +45,7 @@ class ProcessSlicedObjectListJob(Job): points[:,2] -= self._center.z points = numpy.pad(points, ((0,0), (0,1)), 'constant', constant_values=(0.0, 1.0)) - inverse = node.getGlobalTransformation().getInverse().getData() + inverse = node.getWorldTransformation().getInverse().getData() points = points.dot(inverse) points = points[:,0:3] From 04fce487ac77a6eb14ec93ecd1ff21d40115fb05 Mon Sep 17 00:00:00 2001 From: daid Date: Thu, 9 Apr 2015 09:52:38 +0200 Subject: [PATCH 52/76] Add QT5 plugin search path when on windows and build with py2exe. --- CuraEngineBackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index d812c2c8e3..c62c27a889 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -20,7 +20,7 @@ class CuraEngineBackend(Backend): def __init__(self): super().__init__() - Preferences.getInstance().addPreference('backend/location', 'C:/Software/Cura_PinkUnicornEngine/_bin/Debug/Cura_SteamEngine.exe') + Preferences.getInstance().addPreference('backend/location', '../PinkUnicornEngine/CuraEngine') self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) From 8cbf2456acde9fe3cd1f712eac63b1006d849145 Mon Sep 17 00:00:00 2001 From: daid Date: Thu, 9 Apr 2015 11:02:22 +0200 Subject: [PATCH 53/76] Look for the proper location for the engine when running in py2exe. --- CuraEngineBackend.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index c62c27a889..6220215975 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -10,8 +10,8 @@ from . import Cura_pb2 from . import ProcessSlicedObjectListJob from . import ProcessGCodeJob -import threading -import struct +import os +import sys import numpy from PyQt5.QtCore import QTimer @@ -20,7 +20,14 @@ class CuraEngineBackend(Backend): def __init__(self): super().__init__() - Preferences.getInstance().addPreference('backend/location', '../PinkUnicornEngine/CuraEngine') + # Find out where the engine is located, and how it is called. This depends on how Cura is packaged and which OS we are running on. + default_engine_location = '../PinkUnicornEngine/CuraEngine' + if hasattr(sys, 'frozen'): + default_engine_location = os.path.join(os.path.dirname(os.path.abspath(sys.executable)), 'CuraEngine') + if sys.platform == 'win32': + default_engine_location += '.exe' + default_engine_location = os.path.abspath(default_engine_location) + Preferences.getInstance().addPreference('backend/location', default_engine_location) self._scene = Application.getInstance().getController().getScene() self._scene.sceneChanged.connect(self._onSceneChanged) From ceb6f43b11eefe99dd309c81a26dabb4ef9846c1 Mon Sep 17 00:00:00 2001 From: daid Date: Mon, 13 Apr 2015 11:15:29 +0200 Subject: [PATCH 54/76] That is not how we do an if. --- CuraEngineBackend.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 6220215975..cc2dce1e6c 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -165,8 +165,11 @@ class CuraEngineBackend(Backend): self._socket.sendMessage(msg) def _sendSettings(self): - self._sendSettings_neith() if self._settings.getSettingValueByKey('wireframe') else self._sendSettings_normal() - + if self._settings.getSettingValueByKey('wireframe'): + self._sendSettings_neith() + else: + self._sendSettings_normal() + def _sendSettings_neith(self): extruder = 0 From 231ca38fdee76b5df01d615799c77e825cd54355 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 13 Apr 2015 13:06:33 +0200 Subject: [PATCH 55/76] Tooltips now show when hovering the text area --- CuraEngineBackend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 6220215975..d789a8c55c 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -164,6 +164,7 @@ class CuraEngineBackend(Backend): self._socket.sendMessage(msg) + ## TODO: Neith settings need to be moved to their own backend. def _sendSettings(self): self._sendSettings_neith() if self._settings.getSettingValueByKey('wireframe') else self._sendSettings_normal() @@ -375,7 +376,6 @@ class CuraEngineBackend(Backend): settings['supportType'] = '' settings['supportAngle'] = -1 else: - settings['supportType'] = 'LINES' settings['supportAngle'] = self._settings.getSettingValueByKey('support_angle') settings['supportOnBuildplateOnly'] = 1 if self._settings.getSettingValueByKey('support_type') == 'Touching Buildplate' else 0 settings['supportLineDistance'] = int(100 * self._settings.getSettingValueByKey('wall_line_width_x') * 1000 / self._settings.getSettingValueByKey('support_fill_rate')) @@ -389,7 +389,7 @@ class CuraEngineBackend(Backend): settings['supportTowerDiameter'] = int(self._settings.getSettingValueByKey('support_tower_diameter') * 1000) settings['supportTowerRoofAngle'] = int(self._settings.getSettingValueByKey('support_tower_roof_angle')) settings['supportConnectZigZags'] = 1 if self._settings.getSettingValueByKey('support_connect_zigzags') else 0 - settings['supportExtruder'] = -1 + settings['supportExtruder'] = -1 #Not yet implemented if self._settings.getSettingValueByKey('support_pattern') == 'Grid': settings['supportType'] = 'GRID' elif self._settings.getSettingValueByKey('support_pattern') == 'Lines': From 0af0a4dafeef6e7918f2abd593abed7e6db1171a Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 16 Apr 2015 11:47:56 +0200 Subject: [PATCH 56/76] Do not multiply bed temperature by 100 It is rather silly to set a bed temperature of 6000C --- CuraEngineBackend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index c37907de47..ed6657031e 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -178,7 +178,7 @@ class CuraEngineBackend(Backend): 'neith': 1, 'extruderNr': extruder, 'printTemperature': int(self._settings.getSettingValueByKey('material_print_temperature')), - 'bedTemperature': int(self._settings.getSettingValueByKey('material_bed_temperature') * 100), + 'bedTemperature': int(self._settings.getSettingValueByKey('material_bed_temperature')), 'filamentDiameter': int(self._settings.getSettingValueByKey('material_diameter') * 1000), 'retractionAmount': int(self._settings.getSettingValueByKey('retraction_amount') * 1000), 'retractionAmountPrime': int(0 * 1000), @@ -288,7 +288,7 @@ class CuraEngineBackend(Backend): 'layerThickness': int(self._settings.getSettingValueByKey('layer_height') * 1000), 'initialLayerThickness': int(self._settings.getSettingValueByKey('layer_height_0') * 1000), 'printTemperature': int(self._settings.getSettingValueByKey('material_print_temperature')), - 'bedTemperature': int(self._settings.getSettingValueByKey('material_bed_temperature') * 100), + 'bedTemperature': int(self._settings.getSettingValueByKey('material_bed_temperature')), 'filamentDiameter': int(self._settings.getSettingValueByKey('material_diameter') * 1000), 'filamentFlow': int(self._settings.getSettingValueByKey('material_flow')), 'layer0extrusionWidth': int(self._settings.getSettingValueByKey('wall_line_width_0') * 1000), From 7448011166a01f85ea30b3b24c867add14593252 Mon Sep 17 00:00:00 2001 From: daid Date: Fri, 17 Apr 2015 08:52:36 +0200 Subject: [PATCH 57/76] Add gcode prefix message handling. Fix gcode flavor issue. --- CuraEngineBackend.py | 31 ++++++++------- Cura_pb2.py | 90 +++++++++++++++++++++++++++++++++----------- 2 files changed, 86 insertions(+), 35 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index ed6657031e..209a03ee34 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -44,6 +44,7 @@ class CuraEngineBackend(Backend): self._message_handlers[Cura_pb2.SlicedObjectList] = self._onSlicedObjectListMessage self._message_handlers[Cura_pb2.Progress] = self._onProgressMessage self._message_handlers[Cura_pb2.GCodeLayer] = self._onGCodeLayerMessage + self._message_handlers[Cura_pb2.GCodePrefix] = self._onGCodePrefixMessage self._message_handlers[Cura_pb2.ObjectPrintTime] = self._onObjectPrintTimeMessage self._center = None @@ -54,7 +55,7 @@ class CuraEngineBackend(Backend): self.backendConnected.connect(self._onBackendConnected) def getEngineCommand(self): - return [Preferences.getInstance().getValue("backend/location"), '--connect', "127.0.0.1:{0}".format(self._port)] + return [Preferences.getInstance().getValue("backend/location"), '-vv', '--connect', "127.0.0.1:{0}".format(self._port)] changeTimerFinished = Signal() @@ -89,6 +90,9 @@ class CuraEngineBackend(Backend): job = ProcessGCodeJob.ProcessGCodeLayerJob(message) job.start() + def _onGCodePrefixMessage(self, message): + self._scene.gcode_list.insert(0, message.data.decode('utf-8', 'replace')) + def _onObjectPrintTimeMessage(self, message): pass @@ -101,6 +105,7 @@ class CuraEngineBackend(Backend): self._socket.registerMessageType(4, Cura_pb2.GCodeLayer) self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) self._socket.registerMessageType(6, Cura_pb2.SettingList) + self._socket.registerMessageType(7, Cura_pb2.GCodePrefix) def _onChanged(self): if not self._settings: @@ -242,17 +247,17 @@ class CuraEngineBackend(Backend): gcodeFlavor = self._settings.getSettingValueByKey('machine_gcode_flavor') if gcodeFlavor == 'UltiGCode': - settings['gcodeFlavor'] = 1 + settings['gcodeFlavor'] = "GCODE_FLAVOR_ULTIGCODE" elif gcodeFlavor == 'Makerbot': - settings['gcodeFlavor'] = 2 + settings['gcodeFlavor'] = "GCODE_FLAVOR_MAKERBOT" elif gcodeFlavor == 'BFB': - settings['gcodeFlavor'] = 3 + settings['gcodeFlavor'] = "GCODE_FLAVOR_BFB" elif gcodeFlavor == 'Mach3': - settings['gcodeFlavor'] = 4 + settings['gcodeFlavor'] = "GCODE_FLAVOR_MACH3" elif gcodeFlavor == 'Volumetric': - settings['gcodeFlavor'] = 5 + settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP_VOLUMATRIC" else: - settings['gcodeFlavor'] = 0 + settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP" settings['startCode'] = self._settings.getSettingValueByKey('machine_start_gcode') settings['endCode'] = self._settings.getSettingValueByKey('machine_end_gcode') @@ -411,17 +416,17 @@ class CuraEngineBackend(Backend): gcodeFlavor = self._settings.getSettingValueByKey('machine_gcode_flavor') if gcodeFlavor == 'UltiGCode': - settings['gcodeFlavor'] = 1 + settings['gcodeFlavor'] = "GCODE_FLAVOR_ULTIGCODE" elif gcodeFlavor == 'Makerbot': - settings['gcodeFlavor'] = 2 + settings['gcodeFlavor'] = "GCODE_FLAVOR_MAKERBOT" elif gcodeFlavor == 'BFB': - settings['gcodeFlavor'] = 3 + settings['gcodeFlavor'] = "GCODE_FLAVOR_BFB" elif gcodeFlavor == 'Mach3': - settings['gcodeFlavor'] = 4 + settings['gcodeFlavor'] = "GCODE_FLAVOR_MACH3" elif gcodeFlavor == 'Volumetric': - settings['gcodeFlavor'] = 5 + settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP_VOLUMATRIC" else: - settings['gcodeFlavor'] = 0 + settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP" settings['startCode'] = self._settings.getSettingValueByKey('machine_start_gcode') settings['endCode'] = self._settings.getSettingValueByKey('machine_end_gcode') diff --git a/Cura_pb2.py b/Cura_pb2.py index 090bea1089..1f794225b1 100644 --- a/Cura_pb2.py +++ b/Cura_pb2.py @@ -18,7 +18,7 @@ _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='Cura.proto', package='Cura', - serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"H\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"&\n\nGCodeLayer\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x62\x06proto3') + serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"i\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\x12\x1f\n\x08settings\x18\x05 \x03(\x0b\x32\r.Cura.Setting\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"&\n\nGCodeLayer\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\"\x1b\n\x0bGCodePrefix\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x62\x06proto3') ) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -57,8 +57,8 @@ _POLYGON_TYPE = _descriptor.EnumDescriptor( ], containing_type=None, options=None, - serialized_start=397, - serialized_end=495, + serialized_start=430, + serialized_end=528, ) _sym_db.RegisterEnumDescriptor(_POLYGON_TYPE) @@ -128,6 +128,13 @@ _OBJECT = _descriptor.Descriptor( message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), + _descriptor.FieldDescriptor( + name='settings', full_name='Cura.Object.settings', index=4, + number=5, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), ], extensions=[ ], @@ -140,7 +147,7 @@ _OBJECT = _descriptor.Descriptor( oneofs=[ ], serialized_start=65, - serialized_end=137, + serialized_end=170, ) @@ -169,8 +176,8 @@ _PROGRESS = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=139, - serialized_end=165, + serialized_start=172, + serialized_end=198, ) @@ -199,8 +206,8 @@ _SLICEDOBJECTLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=167, - serialized_end=222, + serialized_start=200, + serialized_end=255, ) @@ -236,8 +243,8 @@ _SLICEDOBJECT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=224, - serialized_end=279, + serialized_start=257, + serialized_end=312, ) @@ -273,8 +280,8 @@ _LAYER = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=281, - serialized_end=333, + serialized_start=314, + serialized_end=366, ) @@ -311,8 +318,8 @@ _POLYGON = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=336, - serialized_end=495, + serialized_start=369, + serialized_end=528, ) @@ -348,8 +355,8 @@ _GCODELAYER = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=497, - serialized_end=535, + serialized_start=530, + serialized_end=568, ) @@ -385,8 +392,8 @@ _OBJECTPRINTTIME = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=537, - serialized_end=580, + serialized_start=570, + serialized_end=613, ) @@ -415,8 +422,8 @@ _SETTINGLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=582, - serialized_end=628, + serialized_start=615, + serialized_end=661, ) @@ -452,11 +459,42 @@ _SETTING = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=630, - serialized_end=668, + serialized_start=663, + serialized_end=701, +) + + +_GCODEPREFIX = _descriptor.Descriptor( + name='GCodePrefix', + full_name='Cura.GCodePrefix', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='data', full_name='Cura.GCodePrefix.data', index=0, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value=_b(""), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + oneofs=[ + ], + serialized_start=703, + serialized_end=730, ) _OBJECTLIST.fields_by_name['objects'].message_type = _OBJECT +_OBJECT.fields_by_name['settings'].message_type = _SETTING _SLICEDOBJECTLIST.fields_by_name['objects'].message_type = _SLICEDOBJECT _SLICEDOBJECT.fields_by_name['layers'].message_type = _LAYER _LAYER.fields_by_name['polygons'].message_type = _POLYGON @@ -474,6 +512,7 @@ DESCRIPTOR.message_types_by_name['GCodeLayer'] = _GCODELAYER DESCRIPTOR.message_types_by_name['ObjectPrintTime'] = _OBJECTPRINTTIME DESCRIPTOR.message_types_by_name['SettingList'] = _SETTINGLIST DESCRIPTOR.message_types_by_name['Setting'] = _SETTING +DESCRIPTOR.message_types_by_name['GCodePrefix'] = _GCODEPREFIX ObjectList = _reflection.GeneratedProtocolMessageType('ObjectList', (_message.Message,), dict( DESCRIPTOR = _OBJECTLIST, @@ -552,5 +591,12 @@ Setting = _reflection.GeneratedProtocolMessageType('Setting', (_message.Message, )) _sym_db.RegisterMessage(Setting) +GCodePrefix = _reflection.GeneratedProtocolMessageType('GCodePrefix', (_message.Message,), dict( + DESCRIPTOR = _GCODEPREFIX, + __module__ = 'Cura_pb2' + # @@protoc_insertion_point(class_scope:Cura.GCodePrefix) + )) +_sym_db.RegisterMessage(GCodePrefix) + # @@protoc_insertion_point(module_scope) From e4c6fff6b8a8ccbbcd6c420416b2d1d75ef8bf68 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 17 Apr 2015 11:21:58 +0200 Subject: [PATCH 58/76] Send "fanFullOnLayer" setting to the engine --- CuraEngineBackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 209a03ee34..0d4e53a2ba 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -326,7 +326,6 @@ class CuraEngineBackend(Backend): 'insetXSpeed': int(self._settings.getSettingValueByKey('speed_wall_x')), 'supportSpeed': int(self._settings.getSettingValueByKey('speed_support')), 'moveSpeed': int(self._settings.getSettingValueByKey('speed_travel')), - #'fanFullOnLayerNr': int(fbk('cool_fan_full_layer')), 'infillOverlap': int(self._settings.getSettingValueByKey('fill_overlap')), 'infillSpeed': int(self._settings.getSettingValueByKey('speed_infill')), @@ -336,6 +335,7 @@ class CuraEngineBackend(Backend): 'coolHeadLift': 1 if self._settings.getSettingValueByKey('cool_lift_head') else 0, 'fanSpeedMin': self._settings.getSettingValueByKey('cool_fan_speed_min'), 'fanSpeedMax': self._settings.getSettingValueByKey('cool_fan_speed_max'), + 'fanFullOnLayerNr': self._settings.getSettingValueByKey('cool_fan_full_layer'), 'spiralizeMode': 1 if self._settings.getSettingValueByKey('magic_spiralize') == 'True' else 0, From 4ae82632389d5d52725af937adc263e7fb4365b5 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Fri, 17 Apr 2015 13:52:06 +0200 Subject: [PATCH 59/76] Add missing top/bottom speed --- CuraEngineBackend.py | 1 + 1 file changed, 1 insertion(+) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 0d4e53a2ba..7c0acbc8e6 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -326,6 +326,7 @@ class CuraEngineBackend(Backend): 'insetXSpeed': int(self._settings.getSettingValueByKey('speed_wall_x')), 'supportSpeed': int(self._settings.getSettingValueByKey('speed_support')), 'moveSpeed': int(self._settings.getSettingValueByKey('speed_travel')), + 'skinSpeed': int(self._settings.getSettingValueByKey('speed_topbottom')), 'infillOverlap': int(self._settings.getSettingValueByKey('fill_overlap')), 'infillSpeed': int(self._settings.getSettingValueByKey('speed_infill')), From daa6e04d8c5dd382e30c0e7cfe601be6a03e6ee9 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 20 Apr 2015 16:42:19 +0200 Subject: [PATCH 60/76] Ignore nodes that are outside the build volume for slicing --- CuraEngineBackend.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 7c0acbc8e6..527f9c0683 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -127,7 +127,8 @@ class CuraEngineBackend(Backend): objects = [] for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is SceneNode and node.getMeshData(): - objects.append(node) + if not getattr(node, '_outside_buildarea', False): + objects.append(node) if not objects: return #No point in slicing an empty build plate From 1bda4ee23ab73f91558f8133bc0fe5e070c18e1f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Mon, 20 Apr 2015 17:55:25 +0200 Subject: [PATCH 61/76] Add support for displaying print time and print material amount --- CuraEngineBackend.py | 4 ++-- Cura_pb2.py | 23 +++++++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 527f9c0683..506fc1fd09 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -57,7 +57,7 @@ class CuraEngineBackend(Backend): def getEngineCommand(self): return [Preferences.getInstance().getValue("backend/location"), '-vv', '--connect', "127.0.0.1:{0}".format(self._port)] - changeTimerFinished = Signal() + printDurationMessage = Signal() def _onSceneChanged(self, source): if (type(source) is not SceneNode) or (source is self._scene.getRoot()): @@ -94,7 +94,7 @@ class CuraEngineBackend(Backend): self._scene.gcode_list.insert(0, message.data.decode('utf-8', 'replace')) def _onObjectPrintTimeMessage(self, message): - pass + self.printDurationMessage.emit(message.time, message.material_amount) def _createSocket(self): super()._createSocket() diff --git a/Cura_pb2.py b/Cura_pb2.py index 1f794225b1..c577ef0f71 100644 --- a/Cura_pb2.py +++ b/Cura_pb2.py @@ -18,7 +18,7 @@ _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor.FileDescriptor( name='Cura.proto', package='Cura', - serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"i\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\x12\x1f\n\x08settings\x18\x05 \x03(\x0b\x32\r.Cura.Setting\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"&\n\nGCodeLayer\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"+\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\"\x1b\n\x0bGCodePrefix\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x62\x06proto3') + serialized_pb=_b('\n\nCura.proto\x12\x04\x43ura\"+\n\nObjectList\x12\x1d\n\x07objects\x18\x01 \x03(\x0b\x32\x0c.Cura.Object\"i\n\x06Object\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x10\n\x08vertices\x18\x02 \x01(\x0c\x12\x0f\n\x07normals\x18\x03 \x01(\x0c\x12\x0f\n\x07indices\x18\x04 \x01(\x0c\x12\x1f\n\x08settings\x18\x05 \x03(\x0b\x32\r.Cura.Setting\"\x1a\n\x08Progress\x12\x0e\n\x06\x61mount\x18\x01 \x01(\x02\"7\n\x10SlicedObjectList\x12#\n\x07objects\x18\x01 \x03(\x0b\x32\x12.Cura.SlicedObject\"7\n\x0cSlicedObject\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x1b\n\x06layers\x18\x02 \x03(\x0b\x32\x0b.Cura.Layer\"4\n\x05Layer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1f\n\x08polygons\x18\x02 \x03(\x0b\x32\r.Cura.Polygon\"\x9f\x01\n\x07Polygon\x12 \n\x04type\x18\x01 \x01(\x0e\x32\x12.Cura.Polygon.Type\x12\x0e\n\x06points\x18\x02 \x01(\x0c\"b\n\x04Type\x12\x0c\n\x08NoneType\x10\x00\x12\x0e\n\nInset0Type\x10\x01\x12\x0e\n\nInsetXType\x10\x02\x12\x0c\n\x08SkinType\x10\x03\x12\x0f\n\x0bSupportType\x10\x04\x12\r\n\tSkirtType\x10\x05\"&\n\nGCodeLayer\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"D\n\x0fObjectPrintTime\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x02\x12\x17\n\x0fmaterial_amount\x18\x03 \x01(\x02\".\n\x0bSettingList\x12\x1f\n\x08settings\x18\x01 \x03(\x0b\x32\r.Cura.Setting\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\"\x1b\n\x0bGCodePrefix\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\x62\x06proto3') ) _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -381,6 +381,13 @@ _OBJECTPRINTTIME = _descriptor.Descriptor( message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), + _descriptor.FieldDescriptor( + name='material_amount', full_name='Cura.ObjectPrintTime.material_amount', index=2, + number=3, type=2, cpp_type=6, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), ], extensions=[ ], @@ -393,7 +400,7 @@ _OBJECTPRINTTIME = _descriptor.Descriptor( oneofs=[ ], serialized_start=570, - serialized_end=613, + serialized_end=638, ) @@ -422,8 +429,8 @@ _SETTINGLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=615, - serialized_end=661, + serialized_start=640, + serialized_end=686, ) @@ -459,8 +466,8 @@ _SETTING = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=663, - serialized_end=701, + serialized_start=688, + serialized_end=726, ) @@ -489,8 +496,8 @@ _GCODEPREFIX = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=703, - serialized_end=730, + serialized_start=728, + serialized_end=755, ) _OBJECTLIST.fields_by_name['objects'].message_type = _OBJECT From d2129d27394990e6925b99d54ab6657286fc4db1 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 21 Apr 2015 14:56:58 +0200 Subject: [PATCH 62/76] LayerData is now added in a new node --- CuraEngineBackend.py | 9 +++++---- ProcessSlicedObjectListJob.py | 24 ++++++++++++++++-------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 506fc1fd09..3dcc876b4c 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -60,9 +60,10 @@ class CuraEngineBackend(Backend): printDurationMessage = Signal() def _onSceneChanged(self, source): - if (type(source) is not SceneNode) or (source is self._scene.getRoot()): + if (type(source) is not SceneNode) or (source is self._scene.getRoot()) or (source.getMeshData() is None): + return + if(source.getMeshData().getVertices() is None): return - self._onChanged() def _onActiveMachineChanged(self): @@ -126,7 +127,7 @@ class CuraEngineBackend(Backend): objects = [] for node in DepthFirstIterator(self._scene.getRoot()): - if type(node) is SceneNode and node.getMeshData(): + if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None: if not getattr(node, '_outside_buildarea', False): objects.append(node) @@ -155,7 +156,7 @@ class CuraEngineBackend(Backend): obj = msg.objects.add() obj.id = id(object) - + verts = numpy.array(meshData.getVertices(), copy=True) verts[:,[1,2]] = verts[:,[2,1]] obj.vertices = verts.tostring() diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index a324e260bc..e9a7adebd9 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -18,19 +18,24 @@ class ProcessSlicedObjectListJob(Job): def run(self): objectIdMap = {} + new_node = SceneNode() + ## Put all nodes in a dict identified by ID for node in DepthFirstIterator(self._scene.getRoot()): if type(node) is SceneNode and node.getMeshData(): - objectIdMap[id(node)] = node + if hasattr(node.getMeshData(), "layerData"): + self._scene.getRoot().removeChild(node) + else: + objectIdMap[id(node)] = node layerHeight = Application.getInstance().getActiveMachine().getSettingValueByKey('layer_height') for object in self._message.objects: - try: + try: node = objectIdMap[object.id] except KeyError: continue - - mesh = node.getMeshData() + + mesh = MeshData() layerData = LayerData.LayerData() for layer in object.layers: @@ -44,11 +49,14 @@ class ProcessSlicedObjectListJob(Job): points[:,0] -= self._center.x points[:,2] -= self._center.z - points = numpy.pad(points, ((0,0), (0,1)), 'constant', constant_values=(0.0, 1.0)) - inverse = node.getWorldTransformation().getInverse().getData() - points = points.dot(inverse) - points = points[:,0:3] + #points = numpy.pad(points, ((0,0), (0,1)), 'constant', constant_values=(0.0, 1.0)) + #inverse = node.getWorldTransformation().getInverse().getData() + #points = points.dot(inverse) + #points = points[:,0:3] layerData.addPolygon(layer.id, polygon.type, points) mesh.layerData = layerData + + new_node.setMeshData(mesh) + new_node.setParent(self._scene.getRoot()) From 5d8b84e1a2981c9872f9386e3ed8dd0b51fdcd1c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 21 Apr 2015 14:58:47 +0200 Subject: [PATCH 63/76] Changed changeTimer to correct naming --- CuraEngineBackend.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 3dcc876b4c..52308c7c4f 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -36,10 +36,10 @@ class CuraEngineBackend(Backend): Application.getInstance().activeMachineChanged.connect(self._onActiveMachineChanged) self._onActiveMachineChanged() - self._changeTimer = QTimer() - self._changeTimer.setInterval(500) - self._changeTimer.setSingleShot(True) - self._changeTimer.timeout.connect(self._onChangeTimerFinished) + self._change_timer = QTimer() + self._change_timer.setInterval(500) + self._change_timer.setSingleShot(True) + self._change_timer.timeout.connect(self._onChangeTimerFinished) self._message_handlers[Cura_pb2.SlicedObjectList] = self._onSlicedObjectListMessage self._message_handlers[Cura_pb2.Progress] = self._onProgressMessage @@ -112,7 +112,7 @@ class CuraEngineBackend(Backend): if not self._settings: return - self._changeTimer.start() + self._change_timer.start() def _onChangeTimerFinished(self): if self._slicing: From 2bdc85c8eaa93bd5d95e225a1ff95219ec76a67f Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 21 Apr 2015 15:20:22 +0200 Subject: [PATCH 64/76] Data is now correctly sent to engine (in right reference frame) --- CuraEngineBackend.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 52308c7c4f..56939780a5 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -96,7 +96,8 @@ class CuraEngineBackend(Backend): def _onObjectPrintTimeMessage(self, message): self.printDurationMessage.emit(message.time, message.material_amount) - + + ## Create socket and register the used message types. Note that these must be the same on engine side! def _createSocket(self): super()._createSocket() @@ -152,13 +153,14 @@ class CuraEngineBackend(Backend): for object in objects: center += object.getPosition() - meshData = object.getMeshData().getTransformed(object.getWorldTransformation()) + mesh_data = object.getMeshData().getTransformed(object.getWorldTransformation()) obj = msg.objects.add() obj.id = id(object) - verts = numpy.array(meshData.getVertices(), copy=True) + verts = numpy.array(mesh_data.getVertices(), copy=True) verts[:,[1,2]] = verts[:,[2,1]] + verts[:,[2]] *= -1 obj.vertices = verts.tostring() #if meshData.hasNormals(): From 089aad324175fd9a0f5c6cdb8a66077db41575c1 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 21 Apr 2015 16:30:12 +0200 Subject: [PATCH 65/76] CuraEngineBackend: Move the slicing code into a slice method with optional keyword arguments --- CuraEngineBackend.py | 576 +++++++++++++++++++++++-------------------- 1 file changed, 308 insertions(+), 268 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 3dcc876b4c..e33879b5c6 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -39,7 +39,7 @@ class CuraEngineBackend(Backend): self._changeTimer = QTimer() self._changeTimer.setInterval(500) self._changeTimer.setSingleShot(True) - self._changeTimer.timeout.connect(self._onChangeTimerFinished) + self._changeTimer.timeout.connect(self.slice) self._message_handlers[Cura_pb2.SlicedObjectList] = self._onSlicedObjectListMessage self._message_handlers[Cura_pb2.Progress] = self._onProgressMessage @@ -52,70 +52,41 @@ class CuraEngineBackend(Backend): self._slicing = False self._restart = False + self._save_gcode = True + self._save_polygons = True + self._report_progress = True + self.backendConnected.connect(self._onBackendConnected) def getEngineCommand(self): return [Preferences.getInstance().getValue("backend/location"), '-vv', '--connect', "127.0.0.1:{0}".format(self._port)] + ## Emitted when we get a message containing print duration and material amount. This also implies the slicing has finished. + # \param time The amount of time the print will take. + # \param material_amount The amount of material the print will use. printDurationMessage = Signal() - def _onSceneChanged(self, source): - if (type(source) is not SceneNode) or (source is self._scene.getRoot()) or (source.getMeshData() is None): - return - if(source.getMeshData().getVertices() is None): - return - self._onChanged() + ## Emitted when the slicing process starts. + slicingStarted = Signal() - def _onActiveMachineChanged(self): - if self._settings: - self._settings.settingChanged.disconnect(self._onSettingChanged) + ## Emitted whne the slicing process is aborted forcefully. + slicingCancelled = Signal() - self._settings = Application.getInstance().getActiveMachine() - if self._settings: - self._settings.settingChanged.connect(self._onSettingChanged) - self._onChanged() - - def _onSettingChanged(self, setting): - self._onChanged() - - def _onSlicedObjectListMessage(self, message): - job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message, self._center) - job.start() - - def _onProgressMessage(self, message): - if message.amount >= 0.99: - self._slicing = False - self.processingProgress.emit(message.amount) - - def _onGCodeLayerMessage(self, message): - job = ProcessGCodeJob.ProcessGCodeLayerJob(message) - job.start() - - def _onGCodePrefixMessage(self, message): - self._scene.gcode_list.insert(0, message.data.decode('utf-8', 'replace')) - - def _onObjectPrintTimeMessage(self, message): - self.printDurationMessage.emit(message.time, message.material_amount) - - def _createSocket(self): - super()._createSocket() - - self._socket.registerMessageType(1, Cura_pb2.ObjectList) - self._socket.registerMessageType(2, Cura_pb2.SlicedObjectList) - self._socket.registerMessageType(3, Cura_pb2.Progress) - self._socket.registerMessageType(4, Cura_pb2.GCodeLayer) - self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) - self._socket.registerMessageType(6, Cura_pb2.SettingList) - self._socket.registerMessageType(7, Cura_pb2.GCodePrefix) - - def _onChanged(self): - if not self._settings: - return - - self._changeTimer.start() - - def _onChangeTimerFinished(self): + ## Perform a slice of the scene with the given set of settings. + # + # \param kwargs Keyword arguments. + # Valid values are: + # - settings: The settings to use for the slice. The default is the active machine. + # - save_gcode: True if the generated gcode should be saved, False if not. True by default. + # - save_polygons: True if the generated polygon data should be saved, False if not. True by default. + # - force_restart: True if the slicing process should be forcefully restarted if it is already slicing. + # If False, this method do nothing. True by default. + # - report_progress: True if the slicing progress should be reported, False if not. Default is True. + def slice(self, **kwargs): if self._slicing: + if not kwargs.get('force_restart', True): + return + self._slicing = False self._restart = True if self._process is not None: @@ -123,6 +94,7 @@ class CuraEngineBackend(Backend): self._process.terminate() except: # terminating a process that is already terminating causes an exception, silently ignore this. pass + self.slicingCancelled.emit() return objects = [] @@ -135,15 +107,21 @@ class CuraEngineBackend(Backend): return #No point in slicing an empty build plate self._slicing = True + self.slicingStarted.emit() self.processingProgress.emit(0.0) - self._sendSettings() + self._sendSettings(kwargs.get('settings', self._settings)) self._scene.acquireLock() + # Set the gcode as an empty list. This will be filled with strings by GCodeLayer messages. # This is done so the gcode can be fragmented in memory and does not need a continues memory space. # (AKA. This prevents MemoryErrors) - setattr(self._scene, 'gcode_list', []) + self._save_gcode = kwargs.get('save_gcode', True) + if self._save_gcode: + setattr(self._scene, 'gcode_list', []) + + self._save_polygons = kwargs.get('save_polygons', True) msg = Cura_pb2.ObjectList() @@ -171,286 +149,348 @@ class CuraEngineBackend(Backend): self._socket.sendMessage(msg) - ## TODO: Neith settings need to be moved to their own backend. - def _sendSettings(self): - if self._settings.getSettingValueByKey('wireframe'): - self._sendSettings_neith() - else: - self._sendSettings_normal() + def _onSceneChanged(self, source): + if (type(source) is not SceneNode) or (source is self._scene.getRoot()) or (source.getMeshData() is None): + return - def _sendSettings_neith(self): + if(source.getMeshData().getVertices() is None): + return + + self._onChanged() + + def _onActiveMachineChanged(self): + if self._settings: + self._settings.settingChanged.disconnect(self._onSettingChanged) + + self._settings = Application.getInstance().getActiveMachine() + if self._settings: + self._settings.settingChanged.connect(self._onSettingChanged) + self._onChanged() + + def _onSettingChanged(self, setting): + self._onChanged() + + def _onSlicedObjectListMessage(self, message): + if self._save_polygons: + job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message, self._center) + job.start() + + def _onProgressMessage(self, message): + if message.amount >= 0.99: + self._slicing = False + + if self._report_progress: + self.processingProgress.emit(message.amount) + + def _onGCodeLayerMessage(self, message): + if self._save_gcode: + job = ProcessGCodeJob.ProcessGCodeLayerJob(message) + job.start() + + def _onGCodePrefixMessage(self, message): + if self._save_gcode: + self._scene.gcode_list.insert(0, message.data.decode('utf-8', 'replace')) + + def _onObjectPrintTimeMessage(self, message): + self.printDurationMessage.emit(message.time, message.material_amount) + + def _createSocket(self): + super()._createSocket() + + self._socket.registerMessageType(1, Cura_pb2.ObjectList) + self._socket.registerMessageType(2, Cura_pb2.SlicedObjectList) + self._socket.registerMessageType(3, Cura_pb2.Progress) + self._socket.registerMessageType(4, Cura_pb2.GCodeLayer) + self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) + self._socket.registerMessageType(6, Cura_pb2.SettingList) + self._socket.registerMessageType(7, Cura_pb2.GCodePrefix) + + def _onChanged(self): + if not self._settings: + return + + self._changeTimer.start() + + ## TODO: Neith settings need to be moved to their own backend. + def _sendSettings(self, settings): + if settings.getSettingValueByKey('wireframe'): + self._sendSettings_neith(settings) + else: + self._sendSettings_normal(settings) + + def _sendSettings_neith(self, settings): extruder = 0 - settings = { + # AKA The Dictionary of Doom (tm) + engine_settings = { 'neith': 1, 'extruderNr': extruder, - 'printTemperature': int(self._settings.getSettingValueByKey('material_print_temperature')), - 'bedTemperature': int(self._settings.getSettingValueByKey('material_bed_temperature')), - 'filamentDiameter': int(self._settings.getSettingValueByKey('material_diameter') * 1000), - 'retractionAmount': int(self._settings.getSettingValueByKey('retraction_amount') * 1000), + 'printTemperature': int(settings.getSettingValueByKey('material_print_temperature')), + 'bedTemperature': int(settings.getSettingValueByKey('material_bed_temperature')), + 'filamentDiameter': int(settings.getSettingValueByKey('material_diameter') * 1000), + 'retractionAmount': int(settings.getSettingValueByKey('retraction_amount') * 1000), 'retractionAmountPrime': int(0 * 1000), # 'retractionAmountExtruderSwitch': int(fbk('') * 1000), - 'retractionSpeed': int(self._settings.getSettingValueByKey('retraction_speed')), - 'retractionPrimeSpeed': int(self._settings.getSettingValueByKey('retraction_speed')), - 'retractionMinimalDistance': int(self._settings.getSettingValueByKey('retraction_min_travel') * 1000), - 'retractionZHop': int(self._settings.getSettingValueByKey('retraction_hop') * 1000), + 'retractionSpeed': int(settings.getSettingValueByKey('retraction_speed')), + 'retractionPrimeSpeed': int(settings.getSettingValueByKey('retraction_speed')), + 'retractionMinimalDistance': int(settings.getSettingValueByKey('retraction_min_travel') * 1000), + 'retractionZHop': int(settings.getSettingValueByKey('retraction_hop') * 1000), - 'moveSpeed': int(self._settings.getSettingValueByKey('speed_travel')), + 'moveSpeed': int(settings.getSettingValueByKey('speed_travel')), - 'fanSpeedMin': self._settings.getSettingValueByKey('cool_fan_speed_min'), - 'fanSpeedMax': self._settings.getSettingValueByKey('cool_fan_speed_max'), + 'fanSpeedMin': settings.getSettingValueByKey('cool_fan_speed_min'), + 'fanSpeedMax': settings.getSettingValueByKey('cool_fan_speed_max'), # ================================ # wireframe printing options # ================================ - 'wireframeConnectionHeight': int(self._settings.getSettingValueByKey('wireframe_height')*1000), - 'wireframeNozzleClearance': int(self._settings.getSettingValueByKey('wireframe_nozzle_clearance')*1000), - - 'machineNozzleTipOuterDiameter': int(self._settings.getSettingValueByKey('machine_nozzle_tip_outer_diameter')*1000), - 'machineNozzleHeadDistance': int(self._settings.getSettingValueByKey('machine_nozzle_head_distance')*1000), - 'machineNozzleExpansionAngle': int(self._settings.getSettingValueByKey('machine_nozzle_expansion_angle')), - - 'wireframePrintspeedBottom': self._settings.getSettingValueByKey('wireframe_printspeed_bottom'), - 'wireframePrintspeedUp': self._settings.getSettingValueByKey('wireframe_printspeed_up'), - 'wireframePrintspeedDown': self._settings.getSettingValueByKey('wireframe_printspeed_down'), - 'wireframePrintspeedFlat': self._settings.getSettingValueByKey('wireframe_printspeed_flat'), - - 'wireframeFlowConnection': int(self._settings.getSettingValueByKey('wireframe_flow_connection')), - 'wireframeFlowFlat': int(self._settings.getSettingValueByKey('wireframe_flow_flat')), - - 'wireframeTopDelay': int(self._settings.getSettingValueByKey('wireframe_top_delay')*100), - 'wireframeBottomDelay': int(self._settings.getSettingValueByKey('wireframe_bottom_delay')*100), - 'wireframeFlatDelay': int(self._settings.getSettingValueByKey('wireframe_flat_delay')*100), - - 'wireframeUpDistHalfSpeed': int(self._settings.getSettingValueByKey('wireframe_up_half_speed')*1000), - 'wireframeTopJump': int(self._settings.getSettingValueByKey('wireframe_top_jump')*1000), - - 'wireframeFallDown': int(self._settings.getSettingValueByKey('wireframe_fall_down')*1000), - 'wireframeDragAlong': int(self._settings.getSettingValueByKey('wireframe_drag_along')*1000), - - 'wireframeStraightBeforeDown': int(self._settings.getSettingValueByKey('wireframe_straight_before_down')), - - - 'wireframeRoofFallDown': int(self._settings.getSettingValueByKey('wireframe_roof_fall_down')*1000), - 'wireframeRoofDragAlong': int(self._settings.getSettingValueByKey('wireframe_roof_drag_along')*1000), - 'wireframeRoofOuterDelay': int(self._settings.getSettingValueByKey('wireframe_roof_outer_delay')*100), - 'wireframeRoofInset': int(self._settings.getSettingValueByKey('wireframe_roof_inset')*1000), - - - } - - wireFrameStrategy = self._settings.getSettingValueByKey('wireframe_strategy') - if wireFrameStrategy == 'Compensate': - settings['wireframeStrategy'] = 0 - if wireFrameStrategy == 'Knot': - settings['wireframeStrategy'] = 1 - if wireFrameStrategy == 'Retract': - settings['wireframeStrategy'] = 2 - - gcodeFlavor = self._settings.getSettingValueByKey('machine_gcode_flavor') - if gcodeFlavor == 'UltiGCode': - settings['gcodeFlavor'] = "GCODE_FLAVOR_ULTIGCODE" - elif gcodeFlavor == 'Makerbot': - settings['gcodeFlavor'] = "GCODE_FLAVOR_MAKERBOT" - elif gcodeFlavor == 'BFB': - settings['gcodeFlavor'] = "GCODE_FLAVOR_BFB" - elif gcodeFlavor == 'Mach3': - settings['gcodeFlavor'] = "GCODE_FLAVOR_MACH3" - elif gcodeFlavor == 'Volumetric': - settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP_VOLUMATRIC" - else: - settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP" + 'wireframeConnectionHeight': int(settings.getSettingValueByKey('wireframe_height')*1000), + 'wireframeNozzleClearance': int(settings.getSettingValueByKey('wireframe_nozzle_clearance')*1000), - settings['startCode'] = self._settings.getSettingValueByKey('machine_start_gcode') - settings['endCode'] = self._settings.getSettingValueByKey('machine_end_gcode') + 'machineNozzleTipOuterDiameter': int(settings.getSettingValueByKey('machine_nozzle_tip_outer_diameter')*1000), + 'machineNozzleHeadDistance': int(settings.getSettingValueByKey('machine_nozzle_head_distance')*1000), + 'machineNozzleExpansionAngle': int(settings.getSettingValueByKey('machine_nozzle_expansion_angle')), + + 'wireframePrintspeedBottom': settings.getSettingValueByKey('wireframe_printspeed_bottom'), + 'wireframePrintspeedUp': settings.getSettingValueByKey('wireframe_printspeed_up'), + 'wireframePrintspeedDown': settings.getSettingValueByKey('wireframe_printspeed_down'), + 'wireframePrintspeedFlat': settings.getSettingValueByKey('wireframe_printspeed_flat'), + + 'wireframeFlowConnection': int(settings.getSettingValueByKey('wireframe_flow_connection')), + 'wireframeFlowFlat': int(settings.getSettingValueByKey('wireframe_flow_flat')), + + 'wireframeTopDelay': int(settings.getSettingValueByKey('wireframe_top_delay')*100), + 'wireframeBottomDelay': int(settings.getSettingValueByKey('wireframe_bottom_delay')*100), + 'wireframeFlatDelay': int(settings.getSettingValueByKey('wireframe_flat_delay')*100), + + 'wireframeUpDistHalfSpeed': int(settings.getSettingValueByKey('wireframe_up_half_speed')*1000), + 'wireframeTopJump': int(settings.getSettingValueByKey('wireframe_top_jump')*1000), + + 'wireframeFallDown': int(settings.getSettingValueByKey('wireframe_fall_down')*1000), + 'wireframeDragAlong': int(settings.getSettingValueByKey('wireframe_drag_along')*1000), + + 'wireframeStraightBeforeDown': int(settings.getSettingValueByKey('wireframe_straight_before_down')), + + + 'wireframeRoofFallDown': int(settings.getSettingValueByKey('wireframe_roof_fall_down')*1000), + 'wireframeRoofDragAlong': int(settings.getSettingValueByKey('wireframe_roof_drag_along')*1000), + 'wireframeRoofOuterDelay': int(settings.getSettingValueByKey('wireframe_roof_outer_delay')*100), + 'wireframeRoofInset': int(settings.getSettingValueByKey('wireframe_roof_inset')*1000), + } + + wireFrameStrategy = settings.getSettingValueByKey('wireframe_strategy') + if wireFrameStrategy == 'Compensate': + engine_settings['wireframeStrategy'] = 0 + if wireFrameStrategy == 'Knot': + engine_settings['wireframeStrategy'] = 1 + if wireFrameStrategy == 'Retract': + engine_settings['wireframeStrategy'] = 2 + + gcodeFlavor = settings.getSettingValueByKey('machine_gcode_flavor') + if gcodeFlavor == 'UltiGCode': + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_ULTIGCODE" + elif gcodeFlavor == 'Makerbot': + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_MAKERBOT" + elif gcodeFlavor == 'BFB': + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_BFB" + elif gcodeFlavor == 'Mach3': + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_MACH3" + elif gcodeFlavor == 'Volumetric': + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP_VOLUMATRIC" + else: + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP" + + engine_settings['startCode'] = settings.getSettingValueByKey('machine_start_gcode') + engine_settings['endCode'] = settings.getSettingValueByKey('machine_end_gcode') #for n in range(1, self._machine.getMaxNozzles()): n = 1 - settings['extruderOffset1.X'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_x_1') * 1000) - settings['extruderOffset1.Y'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_y_1') * 1000) + engine_settings['extruderOffset1.X'] = int(settings.getSettingValueByKey('machine_nozzle_offset_x_1') * 1000) + engine_settings['extruderOffset1.Y'] = int(settings.getSettingValueByKey('machine_nozzle_offset_y_1') * 1000) - if not self._settings.getSettingValueByKey('machine_center_is_zero'): - settings['position.X'] = int((self._settings.getSettingValueByKey('machine_width') / 2.0) * 1000) - settings['position.Y'] = int((self._settings.getSettingValueByKey('machine_depth') / 2.0) * 1000) - self._center = Vector(self._settings.getSettingValueByKey('machine_width') / 2.0, 0.0, self._settings.getSettingValueByKey('machine_depth') / 2.0) + if not settings.getSettingValueByKey('machine_center_is_zero'): + engine_settings['position.X'] = int((settings.getSettingValueByKey('machine_width') / 2.0) * 1000) + engine_settings['position.Y'] = int((settings.getSettingValueByKey('machine_depth') / 2.0) * 1000) + self._center = Vector(settings.getSettingValueByKey('machine_width') / 2.0, 0.0, settings.getSettingValueByKey('machine_depth') / 2.0) else: - settings['position.X'] = 0 - settings['position.Y'] = 0 + engine_settings['position.X'] = 0 + engine_settings['position.Y'] = 0 self._center = Vector(0.0, 0.0, 0.0) - settings['position.Z'] = 0 + engine_settings['position.Z'] = 0 msg = Cura_pb2.SettingList() - for key, value in settings.items(): + for key, value in engine_settings.items(): s = msg.settings.add() s.name = key s.value = str(value).encode('utf-8') self._socket.sendMessage(msg) - def _sendSettings_normal(self): + def _sendSettings_normal(self, settings): extruder = 0 - settings = { + # AKA The Dictionary of Doom (tm) + engine_settings = { 'extruderNr': extruder, - 'layerThickness': int(self._settings.getSettingValueByKey('layer_height') * 1000), - 'initialLayerThickness': int(self._settings.getSettingValueByKey('layer_height_0') * 1000), - 'printTemperature': int(self._settings.getSettingValueByKey('material_print_temperature')), - 'bedTemperature': int(self._settings.getSettingValueByKey('material_bed_temperature')), - 'filamentDiameter': int(self._settings.getSettingValueByKey('material_diameter') * 1000), - 'filamentFlow': int(self._settings.getSettingValueByKey('material_flow')), - 'layer0extrusionWidth': int(self._settings.getSettingValueByKey('wall_line_width_0') * 1000), - 'extrusionWidth': int(self._settings.getSettingValueByKey('wall_line_width_x') * 1000), - 'insetCount': int(self._settings.getSettingValueByKey('wall_line_count')), - 'downSkinCount': int(self._settings.getSettingValueByKey('bottom_layers')), - 'upSkinCount': int(self._settings.getSettingValueByKey('top_layers')), - 'skirtDistance': int(self._settings.getSettingValueByKey('skirt_gap') * 1000), - 'skirtLineCount': int(self._settings.getSettingValueByKey('skirt_line_count')), - 'skirtMinLength': int(self._settings.getSettingValueByKey('skirt_minimal_length') * 1000), + 'layerThickness': int(settings.getSettingValueByKey('layer_height') * 1000), + 'initialLayerThickness': int(settings.getSettingValueByKey('layer_height_0') * 1000), + 'printTemperature': int(settings.getSettingValueByKey('material_print_temperature')), + 'bedTemperature': int(settings.getSettingValueByKey('material_bed_temperature')), + 'filamentDiameter': int(settings.getSettingValueByKey('material_diameter') * 1000), + 'filamentFlow': int(settings.getSettingValueByKey('material_flow')), + 'layer0extrusionWidth': int(settings.getSettingValueByKey('wall_line_width_0') * 1000), + 'extrusionWidth': int(settings.getSettingValueByKey('wall_line_width_x') * 1000), + 'insetCount': int(settings.getSettingValueByKey('wall_line_count')), + 'downSkinCount': int(settings.getSettingValueByKey('bottom_layers')), + 'upSkinCount': int(settings.getSettingValueByKey('top_layers')), + 'skirtDistance': int(settings.getSettingValueByKey('skirt_gap') * 1000), + 'skirtLineCount': int(settings.getSettingValueByKey('skirt_line_count')), + 'skirtMinLength': int(settings.getSettingValueByKey('skirt_minimal_length') * 1000), - 'retractionAmount': int(self._settings.getSettingValueByKey('retraction_amount') * 1000), + 'retractionAmount': int(settings.getSettingValueByKey('retraction_amount') * 1000), 'retractionAmountPrime': int(0 * 1000), # 'retractionAmountExtruderSwitch': int(fbk('') * 1000), - 'retractionSpeed': int(self._settings.getSettingValueByKey('retraction_speed')), - 'retractionPrimeSpeed': int(self._settings.getSettingValueByKey('retraction_speed')), - 'retractionMinimalDistance': int(self._settings.getSettingValueByKey('retraction_min_travel') * 1000), - 'minimalExtrusionBeforeRetraction': int(self._settings.getSettingValueByKey('retraction_minimal_extrusion') * 1000), - 'retractionZHop': int(self._settings.getSettingValueByKey('retraction_hop') * 1000), + 'retractionSpeed': int(settings.getSettingValueByKey('retraction_speed')), + 'retractionPrimeSpeed': int(settings.getSettingValueByKey('retraction_speed')), + 'retractionMinimalDistance': int(settings.getSettingValueByKey('retraction_min_travel') * 1000), + 'minimalExtrusionBeforeRetraction': int(settings.getSettingValueByKey('retraction_minimal_extrusion') * 1000), + 'retractionZHop': int(settings.getSettingValueByKey('retraction_hop') * 1000), - 'enableCombing': 1 if self._settings.getSettingValueByKey('retraction_combing') else 0, + 'enableCombing': 1 if settings.getSettingValueByKey('retraction_combing') else 0, # 'enableOozeShield': int(fbk('') * 1000), # 'wipeTowerSize': int(fbk('') * 1000), # 'multiVolumeOverlap': int(fbk('') * 1000), - 'initialSpeedupLayers': int(self._settings.getSettingValueByKey('speed_slowdown_layers')), - 'initialLayerSpeed': int(self._settings.getSettingValueByKey('speed_layer_0')), - 'skirtSpeed': int(self._settings.getSettingValueByKey('skirt_speed')), - 'inset0Speed': int(self._settings.getSettingValueByKey('speed_wall_0')), - 'insetXSpeed': int(self._settings.getSettingValueByKey('speed_wall_x')), - 'supportSpeed': int(self._settings.getSettingValueByKey('speed_support')), - 'moveSpeed': int(self._settings.getSettingValueByKey('speed_travel')), - 'skinSpeed': int(self._settings.getSettingValueByKey('speed_topbottom')), + 'initialSpeedupLayers': int(settings.getSettingValueByKey('speed_slowdown_layers')), + 'initialLayerSpeed': int(settings.getSettingValueByKey('speed_layer_0')), + 'skirtSpeed': int(settings.getSettingValueByKey('skirt_speed')), + 'inset0Speed': int(settings.getSettingValueByKey('speed_wall_0')), + 'insetXSpeed': int(settings.getSettingValueByKey('speed_wall_x')), + 'supportSpeed': int(settings.getSettingValueByKey('speed_support')), + 'moveSpeed': int(settings.getSettingValueByKey('speed_travel')), + 'skinSpeed': int(settings.getSettingValueByKey('speed_topbottom')), - 'infillOverlap': int(self._settings.getSettingValueByKey('fill_overlap')), - 'infillSpeed': int(self._settings.getSettingValueByKey('speed_infill')), + 'infillOverlap': int(settings.getSettingValueByKey('fill_overlap')), + 'infillSpeed': int(settings.getSettingValueByKey('speed_infill')), - 'minimalLayerTime': int(self._settings.getSettingValueByKey('cool_min_layer_time')), - 'minimalFeedrate': int(self._settings.getSettingValueByKey('cool_min_speed')), - 'coolHeadLift': 1 if self._settings.getSettingValueByKey('cool_lift_head') else 0, - 'fanSpeedMin': self._settings.getSettingValueByKey('cool_fan_speed_min'), - 'fanSpeedMax': self._settings.getSettingValueByKey('cool_fan_speed_max'), - 'fanFullOnLayerNr': self._settings.getSettingValueByKey('cool_fan_full_layer'), + 'minimalLayerTime': int(settings.getSettingValueByKey('cool_min_layer_time')), + 'minimalFeedrate': int(settings.getSettingValueByKey('cool_min_speed')), + 'coolHeadLift': 1 if settings.getSettingValueByKey('cool_lift_head') else 0, + 'fanSpeedMin': settings.getSettingValueByKey('cool_fan_speed_min'), + 'fanSpeedMax': settings.getSettingValueByKey('cool_fan_speed_max'), + 'fanFullOnLayerNr': settings.getSettingValueByKey('cool_fan_full_layer'), - 'spiralizeMode': 1 if self._settings.getSettingValueByKey('magic_spiralize') == 'True' else 0, + 'spiralizeMode': 1 if settings.getSettingValueByKey('magic_spiralize') == 'True' else 0, } - if self._settings.getSettingValueByKey('top_bottom_pattern') == 'Lines': - settings['skinPattern'] = 'SKIN_LINES' - elif self._settings.getSettingValueByKey('top_bottom_pattern') == 'Concentric': - settings['skinPattern'] = 'SKIN_CONCENTRIC' + if settings.getSettingValueByKey('top_bottom_pattern') == 'Lines': + engine_settings['skinPattern'] = 'SKIN_LINES' + elif settings.getSettingValueByKey('top_bottom_pattern') == 'Concentric': + engine_settings['skinPattern'] = 'SKIN_CONCENTRIC' - if self._settings.getSettingValueByKey('fill_pattern') == 'Grid': - settings['infillPattern'] = 'INFILL_GRID' - elif self._settings.getSettingValueByKey('fill_pattern') == 'Triangles': # TODO add option to fdmPrinter.json once it has been translated(?) - settings['infillPattern'] = 'INFILL_TRIANGLES' - elif self._settings.getSettingValueByKey('fill_pattern') == 'Lines': - settings['infillPattern'] = 'INFILL_LINES' - elif self._settings.getSettingValueByKey('fill_pattern') == 'Concentric': - settings['infillPattern'] = 'INFILL_CONCENTRIC' - elif self._settings.getSettingValueByKey('fill_pattern') == 'ZigZag': - settings['infillPattern'] = 'INFILL_ZIGZAG' + if settings.getSettingValueByKey('fill_pattern') == 'Grid': + engine_settings['infillPattern'] = 'INFILL_GRID' + elif settings.getSettingValueByKey('fill_pattern') == 'Triangles': # TODO add option to fdmPrinter.json once it has been translated(?) + engine_settings['infillPattern'] = 'INFILL_TRIANGLES' + elif settings.getSettingValueByKey('fill_pattern') == 'Lines': + engine_settings['infillPattern'] = 'INFILL_LINES' + elif settings.getSettingValueByKey('fill_pattern') == 'Concentric': + engine_settings['infillPattern'] = 'INFILL_CONCENTRIC' + elif settings.getSettingValueByKey('fill_pattern') == 'ZigZag': + engine_settings['infillPattern'] = 'INFILL_ZIGZAG' - adhesion_type = self._settings.getSettingValueByKey('adhesion_type') + adhesion_type = settings.getSettingValueByKey('adhesion_type') if adhesion_type == 'Raft': - settings['raftMargin'] = int(self._settings.getSettingValueByKey('raft_margin') * 1000) - settings['raftLineSpacing'] = int(self._settings.getSettingValueByKey('raft_line_spacing') * 1000) - settings['raftBaseThickness'] = int(self._settings.getSettingValueByKey('raft_base_thickness') * 1000) - settings['raftBaseLinewidth'] = int(self._settings.getSettingValueByKey('raft_base_linewidth') * 1000) - settings['raftBaseSpeed'] = int(self._settings.getSettingValueByKey('raft_base_speed') * 1000) - settings['raftInterfaceThickness'] = int(self._settings.getSettingValueByKey('raft_interface_thickness') * 1000) - settings['raftInterfaceLinewidth'] = int(self._settings.getSettingValueByKey('raft_interface_linewidth') * 1000) - settings['raftInterfaceLineSpacing'] = int(self._settings.getSettingValueByKey('raft_line_spacing') * 1000) - settings['raftFanSpeed'] = 0 - settings['raftSurfaceThickness'] = int(self._settings.getSettingValueByKey('layer_height_0') * 1000) - settings['raftSurfaceLinewidth'] = int(self._settings.getSettingValueByKey('wall_line_width_x') * 1000) - settings['raftSurfaceLineSpacing'] = int(self._settings.getSettingValueByKey('wall_line_width_x') * 1000) - settings['raftSurfaceLayers'] = int(self._settings.getSettingValueByKey('raft_surface_layers')) - settings['raftSurfaceSpeed'] = int(self._settings.getSettingValueByKey('speed_layer_0') * 1000) - settings['raftAirGap'] = int(self._settings.getSettingValueByKey('raft_airgap') * 1000) - settings['skirtLineCount'] = 0 + engine_settings['raftMargin'] = int(settings.getSettingValueByKey('raft_margin') * 1000) + engine_settings['raftLineSpacing'] = int(settings.getSettingValueByKey('raft_line_spacing') * 1000) + engine_settings['raftBaseThickness'] = int(settings.getSettingValueByKey('raft_base_thickness') * 1000) + engine_settings['raftBaseLinewidth'] = int(settings.getSettingValueByKey('raft_base_linewidth') * 1000) + engine_settings['raftBaseSpeed'] = int(settings.getSettingValueByKey('raft_base_speed') * 1000) + engine_settings['raftInterfaceThickness'] = int(settings.getSettingValueByKey('raft_interface_thickness') * 1000) + engine_settings['raftInterfaceLinewidth'] = int(settings.getSettingValueByKey('raft_interface_linewidth') * 1000) + engine_settings['raftInterfaceLineSpacing'] = int(settings.getSettingValueByKey('raft_line_spacing') * 1000) + engine_settings['raftFanSpeed'] = 0 + engine_settings['raftSurfaceThickness'] = int(settings.getSettingValueByKey('layer_height_0') * 1000) + engine_settings['raftSurfaceLinewidth'] = int(settings.getSettingValueByKey('wall_line_width_x') * 1000) + engine_settings['raftSurfaceLineSpacing'] = int(settings.getSettingValueByKey('wall_line_width_x') * 1000) + engine_settings['raftSurfaceLayers'] = int(settings.getSettingValueByKey('raft_surface_layers')) + engine_settings['raftSurfaceSpeed'] = int(settings.getSettingValueByKey('speed_layer_0') * 1000) + engine_settings['raftAirGap'] = int(settings.getSettingValueByKey('raft_airgap') * 1000) + engine_settings['skirtLineCount'] = 0 pass elif adhesion_type == 'Brim': - settings['skirtDistance'] = 0 - settings['skirtLineCount'] = self._settings.getSettingValueByKey('brim_line_count') + engine_settings['skirtDistance'] = 0 + engine_settings['skirtLineCount'] = settings.getSettingValueByKey('brim_line_count') - if self._settings.getSettingValueByKey('support_type') == 'None': - settings['supportType'] = '' - settings['supportAngle'] = -1 + if settings.getSettingValueByKey('support_type') == 'None': + engine_settings['supportType'] = '' + engine_settings['supportAngle'] = -1 else: - settings['supportAngle'] = self._settings.getSettingValueByKey('support_angle') - settings['supportOnBuildplateOnly'] = 1 if self._settings.getSettingValueByKey('support_type') == 'Touching Buildplate' else 0 - settings['supportLineDistance'] = int(100 * self._settings.getSettingValueByKey('wall_line_width_x') * 1000 / self._settings.getSettingValueByKey('support_fill_rate')) - settings['supportXYDistance'] = int(self._settings.getSettingValueByKey('support_xy_distance') * 1000) - settings['supportZDistance'] = int(self._settings.getSettingValueByKey('support_z_distance') * 1000) - settings['supportZDistanceBottom'] = int(self._settings.getSettingValueByKey('support_top_distance') * 1000) - settings['supportZDistanceTop'] = int(self._settings.getSettingValueByKey('support_bottom_distance') * 1000) - settings['supportJoinDistance'] = int(self._settings.getSettingValueByKey('support_join_distance') * 1000) - settings['supportAreaSmoothing'] = int(self._settings.getSettingValueByKey('support_area_smoothing') * 1000) - settings['supportMinimalAreaSqrt'] = int(self._settings.getSettingValueByKey('support_minimal_diameter') * 1000) if self._settings.getSettingValueByKey('support_use_towers') else 0 - settings['supportTowerDiameter'] = int(self._settings.getSettingValueByKey('support_tower_diameter') * 1000) - settings['supportTowerRoofAngle'] = int(self._settings.getSettingValueByKey('support_tower_roof_angle')) - settings['supportConnectZigZags'] = 1 if self._settings.getSettingValueByKey('support_connect_zigzags') else 0 - settings['supportExtruder'] = -1 #Not yet implemented - if self._settings.getSettingValueByKey('support_pattern') == 'Grid': - settings['supportType'] = 'GRID' - elif self._settings.getSettingValueByKey('support_pattern') == 'Lines': - settings['supportType'] = 'LINES' - elif self._settings.getSettingValueByKey('support_pattern') == 'ZigZag': - settings['supportType'] = 'ZIGZAG' + engine_settings['supportAngle'] = settings.getSettingValueByKey('support_angle') + engine_settings['supportOnBuildplateOnly'] = 1 if settings.getSettingValueByKey('support_type') == 'Touching Buildplate' else 0 + engine_settings['supportLineDistance'] = int(100 * settings.getSettingValueByKey('wall_line_width_x') * 1000 / settings.getSettingValueByKey('support_fill_rate')) + engine_settings['supportXYDistance'] = int(settings.getSettingValueByKey('support_xy_distance') * 1000) + engine_settings['supportZDistance'] = int(settings.getSettingValueByKey('support_z_distance') * 1000) + engine_settings['supportZDistanceBottom'] = int(settings.getSettingValueByKey('support_top_distance') * 1000) + engine_settings['supportZDistanceTop'] = int(settings.getSettingValueByKey('support_bottom_distance') * 1000) + engine_settings['supportJoinDistance'] = int(settings.getSettingValueByKey('support_join_distance') * 1000) + engine_settings['supportAreaSmoothing'] = int(settings.getSettingValueByKey('support_area_smoothing') * 1000) + engine_settings['supportMinimalAreaSqrt'] = int(settings.getSettingValueByKey('support_minimal_diameter') * 1000) if settings.getSettingValueByKey('support_use_towers') else 0 + engine_settings['supportTowerDiameter'] = int(settings.getSettingValueByKey('support_tower_diameter') * 1000) + engine_settings['supportTowerRoofAngle'] = int(settings.getSettingValueByKey('support_tower_roof_angle')) + engine_settings['supportConnectZigZags'] = 1 if settings.getSettingValueByKey('support_connect_zigzags') else 0 + engine_settings['supportExtruder'] = -1 #Not yet implemented + if settings.getSettingValueByKey('support_pattern') == 'Grid': + engine_settings['supportType'] = 'GRID' + elif settings.getSettingValueByKey('support_pattern') == 'Lines': + engine_settings['supportType'] = 'LINES' + elif settings.getSettingValueByKey('support_pattern') == 'ZigZag': + engine_settings['supportType'] = 'ZIGZAG' - settings['sparseInfillLineDistance'] = -1 - if self._settings.getSettingValueByKey('fill_sparse_density') >= 100: - settings['sparseInfillLineDistance'] = self._settings.getSettingValueByKey('wall_line_width_x') - settings['downSkinCount'] = 10000 - settings['upSkinCount'] = 10000 - elif self._settings.getSettingValueByKey('fill_sparse_density') > 0: - settings['sparseInfillLineDistance'] = int(100 * self._settings.getSettingValueByKey('wall_line_width_x') * 1000 / self._settings.getSettingValueByKey('fill_sparse_density')) - settings['sparseInfillCombineCount'] = int(round(self._settings.getSettingValueByKey('fill_sparse_combine'))) + engine_settings['sparseInfillLineDistance'] = -1 + if settings.getSettingValueByKey('fill_sparse_density') >= 100: + engine_settings['sparseInfillLineDistance'] = settings.getSettingValueByKey('wall_line_width_x') + engine_settings['downSkinCount'] = 10000 + engine_settings['upSkinCount'] = 10000 + elif settings.getSettingValueByKey('fill_sparse_density') > 0: + engine_settings['sparseInfillLineDistance'] = int(100 * settings.getSettingValueByKey('wall_line_width_x') * 1000 / settings.getSettingValueByKey('fill_sparse_density')) + engine_settings['sparseInfillCombineCount'] = int(round(settings.getSettingValueByKey('fill_sparse_combine'))) - gcodeFlavor = self._settings.getSettingValueByKey('machine_gcode_flavor') + gcodeFlavor = settings.getSettingValueByKey('machine_gcode_flavor') if gcodeFlavor == 'UltiGCode': - settings['gcodeFlavor'] = "GCODE_FLAVOR_ULTIGCODE" + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_ULTIGCODE" elif gcodeFlavor == 'Makerbot': - settings['gcodeFlavor'] = "GCODE_FLAVOR_MAKERBOT" + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_MAKERBOT" elif gcodeFlavor == 'BFB': - settings['gcodeFlavor'] = "GCODE_FLAVOR_BFB" + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_BFB" elif gcodeFlavor == 'Mach3': - settings['gcodeFlavor'] = "GCODE_FLAVOR_MACH3" + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_MACH3" elif gcodeFlavor == 'Volumetric': - settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP_VOLUMATRIC" + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP_VOLUMATRIC" else: - settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP" + engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP" - settings['startCode'] = self._settings.getSettingValueByKey('machine_start_gcode') - settings['endCode'] = self._settings.getSettingValueByKey('machine_end_gcode') + engine_settings['startCode'] = settings.getSettingValueByKey('machine_start_gcode') + engine_settings['endCode'] = settings.getSettingValueByKey('machine_end_gcode') #for n in range(1, self._machine.getMaxNozzles()): n = 1 - settings['extruderOffset1.X'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_x_1') * 1000) - settings['extruderOffset1.Y'] = int(self._settings.getSettingValueByKey('machine_nozzle_offset_y_1') * 1000) + engine_settings['extruderOffset1.X'] = int(settings.getSettingValueByKey('machine_nozzle_offset_x_1') * 1000) + engine_settings['extruderOffset1.Y'] = int(settings.getSettingValueByKey('machine_nozzle_offset_y_1') * 1000) - if not self._settings.getSettingValueByKey('machine_center_is_zero'): - settings['position.X'] = int((self._settings.getSettingValueByKey('machine_width') / 2.0) * 1000) - settings['position.Y'] = int((self._settings.getSettingValueByKey('machine_depth') / 2.0) * 1000) - self._center = Vector(self._settings.getSettingValueByKey('machine_width') / 2.0, 0.0, self._settings.getSettingValueByKey('machine_depth') / 2.0) + if not settings.getSettingValueByKey('machine_center_is_zero'): + engine_settings['position.X'] = int((settings.getSettingValueByKey('machine_width') / 2.0) * 1000) + engine_settings['position.Y'] = int((settings.getSettingValueByKey('machine_depth') / 2.0) * 1000) + self._center = Vector(settings.getSettingValueByKey('machine_width') / 2.0, 0.0, settings.getSettingValueByKey('machine_depth') / 2.0) else: - settings['position.X'] = 0 - settings['position.Y'] = 0 + engine_settings['position.X'] = 0 + engine_settings['position.Y'] = 0 self._center = Vector(0.0, 0.0, 0.0) - settings['position.Z'] = 0 + engine_settings['position.Z'] = 0 msg = Cura_pb2.SettingList() - for key, value in settings.items(): + for key, value in engine_settings.items(): s = msg.settings.add() s.name = key s.value = str(value).encode('utf-8') From a27cb80531ec6da2a47b8cd615d062f641c604f9 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 21 Apr 2015 17:21:32 +0200 Subject: [PATCH 66/76] Do not report progress if the option is not set --- CuraEngineBackend.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index e33879b5c6..8f5d8733cb 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -108,7 +108,10 @@ class CuraEngineBackend(Backend): self._slicing = True self.slicingStarted.emit() - self.processingProgress.emit(0.0) + + self._report_progress = kwargs.get('report_progress', True) + if self._report_progress: + self.processingProgress.emit(0.0) self._sendSettings(kwargs.get('settings', self._settings)) From abc28cc766d4ef6fd340f14eff8267a58add8ac9 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 22 Apr 2015 11:00:12 +0200 Subject: [PATCH 67/76] Plugin registering is now done by dict instead of single object or list --- __init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index 7bea4d0113..675cde091c 100644 --- a/__init__.py +++ b/__init__.py @@ -10,5 +10,5 @@ def getMetaData(): } def register(app): - return CuraEngineBackend.CuraEngineBackend() + return {"backend":CuraEngineBackend.CuraEngineBackend()} From 49a510b03cd18fe3a5e6f65e44cb5c38e6b2eaf4 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 22 Apr 2015 13:42:02 +0200 Subject: [PATCH 68/76] Clarify documentation a bit --- CuraEngineBackend.py | 70 ++++++++++---------------------------------- 1 file changed, 15 insertions(+), 55 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 4c5fcd231e..801940f1d6 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -66,63 +66,23 @@ class CuraEngineBackend(Backend): # \param material_amount The amount of material the print will use. printDurationMessage = Signal() - def _onSceneChanged(self, source): - if (type(source) is not SceneNode) or (source is self._scene.getRoot()) or (source.getMeshData() is None): - return - if(source.getMeshData().getVertices() is None): - return - self._onChanged() + ## Emitted when the slicing process starts. + slicingStarted = Signal() - def _onActiveMachineChanged(self): - if self._settings: - self._settings.settingChanged.disconnect(self._onSettingChanged) + ## Emitted whne the slicing process is aborted forcefully. + slicingCancelled = Signal() - self._settings = Application.getInstance().getActiveMachine() - if self._settings: - self._settings.settingChanged.connect(self._onSettingChanged) - self._onChanged() - - def _onSettingChanged(self, setting): - self._onChanged() - - def _onSlicedObjectListMessage(self, message): - job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message, self._center) - job.start() - - def _onProgressMessage(self, message): - if message.amount >= 0.99: - self._slicing = False - self.processingProgress.emit(message.amount) - - def _onGCodeLayerMessage(self, message): - job = ProcessGCodeJob.ProcessGCodeLayerJob(message) - job.start() - - def _onGCodePrefixMessage(self, message): - self._scene.gcode_list.insert(0, message.data.decode('utf-8', 'replace')) - - def _onObjectPrintTimeMessage(self, message): - self.printDurationMessage.emit(message.time, message.material_amount) - - ## Create socket and register the used message types. Note that these must be the same on engine side! - def _createSocket(self): - super()._createSocket() - - self._socket.registerMessageType(1, Cura_pb2.ObjectList) - self._socket.registerMessageType(2, Cura_pb2.SlicedObjectList) - self._socket.registerMessageType(3, Cura_pb2.Progress) - self._socket.registerMessageType(4, Cura_pb2.GCodeLayer) - self._socket.registerMessageType(5, Cura_pb2.ObjectPrintTime) - self._socket.registerMessageType(6, Cura_pb2.SettingList) - self._socket.registerMessageType(7, Cura_pb2.GCodePrefix) - - def _onChanged(self): - if not self._settings: - return - - self._change_timer.start() - - def _onChangeTimerFinished(self): + ## Perform a slice of the scene with the given set of settings. + # + # \param kwargs Keyword arguments. + # Valid values are: + # - settings: The settings to use for the slice. The default is the active machine. + # - save_gcode: True if the generated gcode should be saved, False if not. True by default. + # - save_polygons: True if the generated polygon data should be saved, False if not. True by default. + # - force_restart: True if the slicing process should be forcefully restarted if it is already slicing. + # If False, this method will do nothing when already slicing. True by default. + # - report_progress: True if the slicing progress should be reported, False if not. Default is True. + def slice(self, **kwargs): if self._slicing: if not kwargs.get('force_restart', True): return From 462b68f389239f00dfb01f2bb083a0a795def72e Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 22 Apr 2015 14:24:01 +0200 Subject: [PATCH 69/76] Fix issues caused by merge --- CuraEngineBackend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 801940f1d6..68a2914d6a 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -39,7 +39,7 @@ class CuraEngineBackend(Backend): self._change_timer = QTimer() self._change_timer.setInterval(500) self._change_timer.setSingleShot(True) - self._change_timer.timeout.connect(self._onChangeTimerFinished) + self._change_timer.timeout.connect(self.slice) self._message_handlers[Cura_pb2.SlicedObjectList] = self._onSlicedObjectListMessage self._message_handlers[Cura_pb2.Progress] = self._onProgressMessage @@ -213,7 +213,7 @@ class CuraEngineBackend(Backend): if not self._settings: return - self._changeTimer.start() + self._change_timer.start() ## TODO: Neith settings need to be moved to their own backend. def _sendSettings(self, settings): From be168bace093c15df7bd0a7c0f2f196ddb12f270 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 23 Apr 2015 13:49:03 +0200 Subject: [PATCH 70/76] Correct for inverted Z in ProcessSlicedObjectListJob --- ProcessSlicedObjectListJob.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index e9a7adebd9..23a4c44ff2 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -49,6 +49,8 @@ class ProcessSlicedObjectListJob(Job): points[:,0] -= self._center.x points[:,2] -= self._center.z + points[:,2] *= -1 + #points = numpy.pad(points, ((0,0), (0,1)), 'constant', constant_values=(0.0, 1.0)) #inverse = node.getWorldTransformation().getInverse().getData() #points = points.dot(inverse) From dcb33be89ffc4e7d4073b818c321acc4d29f2b1f Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 23 Apr 2015 14:03:39 +0200 Subject: [PATCH 71/76] Invert the Y axis when sending data to the engine, not Z Since we just swapped Y and Z it is Y that needs to be inverted, not Z --- CuraEngineBackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 68a2914d6a..1f637568c0 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -140,7 +140,7 @@ class CuraEngineBackend(Backend): verts = numpy.array(mesh_data.getVertices(), copy=True) verts[:,[1,2]] = verts[:,[2,1]] - verts[:,[2]] *= -1 + verts[:,1] *= -1 obj.vertices = verts.tostring() #if meshData.hasNormals(): From 1726254bd7250b68afb259bd4f32ac6c127e3062 Mon Sep 17 00:00:00 2001 From: daid Date: Thu, 23 Apr 2015 14:41:58 +0200 Subject: [PATCH 72/76] Update to remove dict of doom. --- CuraEngineBackend.py | 292 +--------------------------------- ProcessSlicedObjectListJob.py | 6 +- 2 files changed, 9 insertions(+), 289 deletions(-) diff --git a/CuraEngineBackend.py b/CuraEngineBackend.py index 68a2914d6a..dfa106a9c3 100644 --- a/CuraEngineBackend.py +++ b/CuraEngineBackend.py @@ -5,6 +5,8 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Preferences import Preferences from UM.Math.Vector import Vector from UM.Signal import Signal +from UM.Logger import Logger +from UM.Resources import Resources from . import Cura_pb2 from . import ProcessSlicedObjectListJob @@ -47,8 +49,6 @@ class CuraEngineBackend(Backend): self._message_handlers[Cura_pb2.GCodePrefix] = self._onGCodePrefixMessage self._message_handlers[Cura_pb2.ObjectPrintTime] = self._onObjectPrintTimeMessage - self._center = None - self._slicing = False self._restart = False @@ -59,7 +59,7 @@ class CuraEngineBackend(Backend): self.backendConnected.connect(self._onBackendConnected) def getEngineCommand(self): - return [Preferences.getInstance().getValue("backend/location"), '-vv', '--connect', "127.0.0.1:{0}".format(self._port)] + return [Preferences.getInstance().getValue("backend/location"), '-j', Resources.getPath(Resources.SettingsLocation, 'fdmprinter.json'), '-vv', '--connect', "127.0.0.1:{0}".format(self._port)] ## Emitted when we get a message containing print duration and material amount. This also implies the slicing has finished. # \param time The amount of time the print will take. @@ -90,6 +90,7 @@ class CuraEngineBackend(Backend): self._slicing = False self._restart = True if self._process is not None: + Logger.log('d', "Killing engine process") try: self._process.terminate() except: # terminating a process that is already terminating causes an exception, silently ignore this. @@ -176,7 +177,7 @@ class CuraEngineBackend(Backend): def _onSlicedObjectListMessage(self, message): if self._save_polygons: - job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message, self._center) + job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message) job.start() def _onProgressMessage(self, message): @@ -215,289 +216,12 @@ class CuraEngineBackend(Backend): self._change_timer.start() - ## TODO: Neith settings need to be moved to their own backend. def _sendSettings(self, settings): - if settings.getSettingValueByKey('wireframe'): - self._sendSettings_neith(settings) - else: - self._sendSettings_normal(settings) - - def _sendSettings_neith(self, settings): - extruder = 0 - - # AKA The Dictionary of Doom (tm) - engine_settings = { - 'neith': 1, - 'extruderNr': extruder, - 'printTemperature': int(settings.getSettingValueByKey('material_print_temperature')), - 'bedTemperature': int(settings.getSettingValueByKey('material_bed_temperature')), - 'filamentDiameter': int(settings.getSettingValueByKey('material_diameter') * 1000), - 'retractionAmount': int(settings.getSettingValueByKey('retraction_amount') * 1000), - 'retractionAmountPrime': int(0 * 1000), - # 'retractionAmountExtruderSwitch': int(fbk('') * 1000), - 'retractionSpeed': int(settings.getSettingValueByKey('retraction_speed')), - 'retractionPrimeSpeed': int(settings.getSettingValueByKey('retraction_speed')), - 'retractionMinimalDistance': int(settings.getSettingValueByKey('retraction_min_travel') * 1000), - 'retractionZHop': int(settings.getSettingValueByKey('retraction_hop') * 1000), - - 'moveSpeed': int(settings.getSettingValueByKey('speed_travel')), - - 'fanSpeedMin': settings.getSettingValueByKey('cool_fan_speed_min'), - 'fanSpeedMax': settings.getSettingValueByKey('cool_fan_speed_max'), - - # ================================ - # wireframe printing options - # ================================ - 'wireframeConnectionHeight': int(settings.getSettingValueByKey('wireframe_height')*1000), - 'wireframeNozzleClearance': int(settings.getSettingValueByKey('wireframe_nozzle_clearance')*1000), - - 'machineNozzleTipOuterDiameter': int(settings.getSettingValueByKey('machine_nozzle_tip_outer_diameter')*1000), - 'machineNozzleHeadDistance': int(settings.getSettingValueByKey('machine_nozzle_head_distance')*1000), - 'machineNozzleExpansionAngle': int(settings.getSettingValueByKey('machine_nozzle_expansion_angle')), - - 'wireframePrintspeedBottom': settings.getSettingValueByKey('wireframe_printspeed_bottom'), - 'wireframePrintspeedUp': settings.getSettingValueByKey('wireframe_printspeed_up'), - 'wireframePrintspeedDown': settings.getSettingValueByKey('wireframe_printspeed_down'), - 'wireframePrintspeedFlat': settings.getSettingValueByKey('wireframe_printspeed_flat'), - - 'wireframeFlowConnection': int(settings.getSettingValueByKey('wireframe_flow_connection')), - 'wireframeFlowFlat': int(settings.getSettingValueByKey('wireframe_flow_flat')), - - 'wireframeTopDelay': int(settings.getSettingValueByKey('wireframe_top_delay')*100), - 'wireframeBottomDelay': int(settings.getSettingValueByKey('wireframe_bottom_delay')*100), - 'wireframeFlatDelay': int(settings.getSettingValueByKey('wireframe_flat_delay')*100), - - 'wireframeUpDistHalfSpeed': int(settings.getSettingValueByKey('wireframe_up_half_speed')*1000), - 'wireframeTopJump': int(settings.getSettingValueByKey('wireframe_top_jump')*1000), - - 'wireframeFallDown': int(settings.getSettingValueByKey('wireframe_fall_down')*1000), - 'wireframeDragAlong': int(settings.getSettingValueByKey('wireframe_drag_along')*1000), - - 'wireframeStraightBeforeDown': int(settings.getSettingValueByKey('wireframe_straight_before_down')), - - - 'wireframeRoofFallDown': int(settings.getSettingValueByKey('wireframe_roof_fall_down')*1000), - 'wireframeRoofDragAlong': int(settings.getSettingValueByKey('wireframe_roof_drag_along')*1000), - 'wireframeRoofOuterDelay': int(settings.getSettingValueByKey('wireframe_roof_outer_delay')*100), - 'wireframeRoofInset': int(settings.getSettingValueByKey('wireframe_roof_inset')*1000), - } - - wireFrameStrategy = settings.getSettingValueByKey('wireframe_strategy') - if wireFrameStrategy == 'Compensate': - engine_settings['wireframeStrategy'] = 0 - if wireFrameStrategy == 'Knot': - engine_settings['wireframeStrategy'] = 1 - if wireFrameStrategy == 'Retract': - engine_settings['wireframeStrategy'] = 2 - - gcodeFlavor = settings.getSettingValueByKey('machine_gcode_flavor') - if gcodeFlavor == 'UltiGCode': - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_ULTIGCODE" - elif gcodeFlavor == 'Makerbot': - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_MAKERBOT" - elif gcodeFlavor == 'BFB': - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_BFB" - elif gcodeFlavor == 'Mach3': - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_MACH3" - elif gcodeFlavor == 'Volumetric': - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP_VOLUMATRIC" - else: - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP" - - engine_settings['startCode'] = settings.getSettingValueByKey('machine_start_gcode') - engine_settings['endCode'] = settings.getSettingValueByKey('machine_end_gcode') - - #for n in range(1, self._machine.getMaxNozzles()): - n = 1 - engine_settings['extruderOffset1.X'] = int(settings.getSettingValueByKey('machine_nozzle_offset_x_1') * 1000) - engine_settings['extruderOffset1.Y'] = int(settings.getSettingValueByKey('machine_nozzle_offset_y_1') * 1000) - - if not settings.getSettingValueByKey('machine_center_is_zero'): - engine_settings['position.X'] = int((settings.getSettingValueByKey('machine_width') / 2.0) * 1000) - engine_settings['position.Y'] = int((settings.getSettingValueByKey('machine_depth') / 2.0) * 1000) - self._center = Vector(settings.getSettingValueByKey('machine_width') / 2.0, 0.0, settings.getSettingValueByKey('machine_depth') / 2.0) - else: - engine_settings['position.X'] = 0 - engine_settings['position.Y'] = 0 - self._center = Vector(0.0, 0.0, 0.0) - engine_settings['position.Z'] = 0 - msg = Cura_pb2.SettingList() - for key, value in engine_settings.items(): + for setting in settings.getAllSettings(include_machine=True): s = msg.settings.add() - s.name = key - s.value = str(value).encode('utf-8') - - self._socket.sendMessage(msg) - - def _sendSettings_normal(self, settings): - extruder = 0 - - # AKA The Dictionary of Doom (tm) - engine_settings = { - 'extruderNr': extruder, - 'layerThickness': int(settings.getSettingValueByKey('layer_height') * 1000), - 'initialLayerThickness': int(settings.getSettingValueByKey('layer_height_0') * 1000), - 'printTemperature': int(settings.getSettingValueByKey('material_print_temperature')), - 'bedTemperature': int(settings.getSettingValueByKey('material_bed_temperature')), - 'filamentDiameter': int(settings.getSettingValueByKey('material_diameter') * 1000), - 'filamentFlow': int(settings.getSettingValueByKey('material_flow')), - 'layer0extrusionWidth': int(settings.getSettingValueByKey('wall_line_width_0') * 1000), - 'extrusionWidth': int(settings.getSettingValueByKey('wall_line_width_x') * 1000), - 'insetCount': int(settings.getSettingValueByKey('wall_line_count')), - 'downSkinCount': int(settings.getSettingValueByKey('bottom_layers')), - 'upSkinCount': int(settings.getSettingValueByKey('top_layers')), - 'skirtDistance': int(settings.getSettingValueByKey('skirt_gap') * 1000), - 'skirtLineCount': int(settings.getSettingValueByKey('skirt_line_count')), - 'skirtMinLength': int(settings.getSettingValueByKey('skirt_minimal_length') * 1000), - - 'retractionAmount': int(settings.getSettingValueByKey('retraction_amount') * 1000), - 'retractionAmountPrime': int(0 * 1000), - # 'retractionAmountExtruderSwitch': int(fbk('') * 1000), - 'retractionSpeed': int(settings.getSettingValueByKey('retraction_speed')), - 'retractionPrimeSpeed': int(settings.getSettingValueByKey('retraction_speed')), - 'retractionMinimalDistance': int(settings.getSettingValueByKey('retraction_min_travel') * 1000), - 'minimalExtrusionBeforeRetraction': int(settings.getSettingValueByKey('retraction_minimal_extrusion') * 1000), - 'retractionZHop': int(settings.getSettingValueByKey('retraction_hop') * 1000), - - 'enableCombing': 1 if settings.getSettingValueByKey('retraction_combing') else 0, - # 'enableOozeShield': int(fbk('') * 1000), - # 'wipeTowerSize': int(fbk('') * 1000), - # 'multiVolumeOverlap': int(fbk('') * 1000), - - 'initialSpeedupLayers': int(settings.getSettingValueByKey('speed_slowdown_layers')), - 'initialLayerSpeed': int(settings.getSettingValueByKey('speed_layer_0')), - 'skirtSpeed': int(settings.getSettingValueByKey('skirt_speed')), - 'inset0Speed': int(settings.getSettingValueByKey('speed_wall_0')), - 'insetXSpeed': int(settings.getSettingValueByKey('speed_wall_x')), - 'supportSpeed': int(settings.getSettingValueByKey('speed_support')), - 'moveSpeed': int(settings.getSettingValueByKey('speed_travel')), - 'skinSpeed': int(settings.getSettingValueByKey('speed_topbottom')), - - 'infillOverlap': int(settings.getSettingValueByKey('fill_overlap')), - 'infillSpeed': int(settings.getSettingValueByKey('speed_infill')), - - 'minimalLayerTime': int(settings.getSettingValueByKey('cool_min_layer_time')), - 'minimalFeedrate': int(settings.getSettingValueByKey('cool_min_speed')), - 'coolHeadLift': 1 if settings.getSettingValueByKey('cool_lift_head') else 0, - 'fanSpeedMin': settings.getSettingValueByKey('cool_fan_speed_min'), - 'fanSpeedMax': settings.getSettingValueByKey('cool_fan_speed_max'), - 'fanFullOnLayerNr': settings.getSettingValueByKey('cool_fan_full_layer'), - - 'spiralizeMode': 1 if settings.getSettingValueByKey('magic_spiralize') == 'True' else 0, - - } - - if settings.getSettingValueByKey('top_bottom_pattern') == 'Lines': - engine_settings['skinPattern'] = 'SKIN_LINES' - elif settings.getSettingValueByKey('top_bottom_pattern') == 'Concentric': - engine_settings['skinPattern'] = 'SKIN_CONCENTRIC' - - if settings.getSettingValueByKey('fill_pattern') == 'Grid': - engine_settings['infillPattern'] = 'INFILL_GRID' - elif settings.getSettingValueByKey('fill_pattern') == 'Triangles': # TODO add option to fdmPrinter.json once it has been translated(?) - engine_settings['infillPattern'] = 'INFILL_TRIANGLES' - elif settings.getSettingValueByKey('fill_pattern') == 'Lines': - engine_settings['infillPattern'] = 'INFILL_LINES' - elif settings.getSettingValueByKey('fill_pattern') == 'Concentric': - engine_settings['infillPattern'] = 'INFILL_CONCENTRIC' - elif settings.getSettingValueByKey('fill_pattern') == 'ZigZag': - engine_settings['infillPattern'] = 'INFILL_ZIGZAG' - - adhesion_type = settings.getSettingValueByKey('adhesion_type') - if adhesion_type == 'Raft': - engine_settings['raftMargin'] = int(settings.getSettingValueByKey('raft_margin') * 1000) - engine_settings['raftLineSpacing'] = int(settings.getSettingValueByKey('raft_line_spacing') * 1000) - engine_settings['raftBaseThickness'] = int(settings.getSettingValueByKey('raft_base_thickness') * 1000) - engine_settings['raftBaseLinewidth'] = int(settings.getSettingValueByKey('raft_base_linewidth') * 1000) - engine_settings['raftBaseSpeed'] = int(settings.getSettingValueByKey('raft_base_speed') * 1000) - engine_settings['raftInterfaceThickness'] = int(settings.getSettingValueByKey('raft_interface_thickness') * 1000) - engine_settings['raftInterfaceLinewidth'] = int(settings.getSettingValueByKey('raft_interface_linewidth') * 1000) - engine_settings['raftInterfaceLineSpacing'] = int(settings.getSettingValueByKey('raft_line_spacing') * 1000) - engine_settings['raftFanSpeed'] = 0 - engine_settings['raftSurfaceThickness'] = int(settings.getSettingValueByKey('layer_height_0') * 1000) - engine_settings['raftSurfaceLinewidth'] = int(settings.getSettingValueByKey('wall_line_width_x') * 1000) - engine_settings['raftSurfaceLineSpacing'] = int(settings.getSettingValueByKey('wall_line_width_x') * 1000) - engine_settings['raftSurfaceLayers'] = int(settings.getSettingValueByKey('raft_surface_layers')) - engine_settings['raftSurfaceSpeed'] = int(settings.getSettingValueByKey('speed_layer_0') * 1000) - engine_settings['raftAirGap'] = int(settings.getSettingValueByKey('raft_airgap') * 1000) - engine_settings['skirtLineCount'] = 0 - pass - elif adhesion_type == 'Brim': - engine_settings['skirtDistance'] = 0 - engine_settings['skirtLineCount'] = settings.getSettingValueByKey('brim_line_count') - - if settings.getSettingValueByKey('support_type') == 'None': - engine_settings['supportType'] = '' - engine_settings['supportAngle'] = -1 - else: - engine_settings['supportAngle'] = settings.getSettingValueByKey('support_angle') - engine_settings['supportOnBuildplateOnly'] = 1 if settings.getSettingValueByKey('support_type') == 'Touching Buildplate' else 0 - engine_settings['supportLineDistance'] = int(100 * settings.getSettingValueByKey('wall_line_width_x') * 1000 / settings.getSettingValueByKey('support_fill_rate')) - engine_settings['supportXYDistance'] = int(settings.getSettingValueByKey('support_xy_distance') * 1000) - engine_settings['supportZDistance'] = int(settings.getSettingValueByKey('support_z_distance') * 1000) - engine_settings['supportZDistanceBottom'] = int(settings.getSettingValueByKey('support_top_distance') * 1000) - engine_settings['supportZDistanceTop'] = int(settings.getSettingValueByKey('support_bottom_distance') * 1000) - engine_settings['supportJoinDistance'] = int(settings.getSettingValueByKey('support_join_distance') * 1000) - engine_settings['supportAreaSmoothing'] = int(settings.getSettingValueByKey('support_area_smoothing') * 1000) - engine_settings['supportMinimalAreaSqrt'] = int(settings.getSettingValueByKey('support_minimal_diameter') * 1000) if settings.getSettingValueByKey('support_use_towers') else 0 - engine_settings['supportTowerDiameter'] = int(settings.getSettingValueByKey('support_tower_diameter') * 1000) - engine_settings['supportTowerRoofAngle'] = int(settings.getSettingValueByKey('support_tower_roof_angle')) - engine_settings['supportConnectZigZags'] = 1 if settings.getSettingValueByKey('support_connect_zigzags') else 0 - engine_settings['supportExtruder'] = -1 #Not yet implemented - if settings.getSettingValueByKey('support_pattern') == 'Grid': - engine_settings['supportType'] = 'GRID' - elif settings.getSettingValueByKey('support_pattern') == 'Lines': - engine_settings['supportType'] = 'LINES' - elif settings.getSettingValueByKey('support_pattern') == 'ZigZag': - engine_settings['supportType'] = 'ZIGZAG' - - engine_settings['sparseInfillLineDistance'] = -1 - if settings.getSettingValueByKey('fill_sparse_density') >= 100: - engine_settings['sparseInfillLineDistance'] = settings.getSettingValueByKey('wall_line_width_x') - engine_settings['downSkinCount'] = 10000 - engine_settings['upSkinCount'] = 10000 - elif settings.getSettingValueByKey('fill_sparse_density') > 0: - engine_settings['sparseInfillLineDistance'] = int(100 * settings.getSettingValueByKey('wall_line_width_x') * 1000 / settings.getSettingValueByKey('fill_sparse_density')) - engine_settings['sparseInfillCombineCount'] = int(round(settings.getSettingValueByKey('fill_sparse_combine'))) - - gcodeFlavor = settings.getSettingValueByKey('machine_gcode_flavor') - if gcodeFlavor == 'UltiGCode': - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_ULTIGCODE" - elif gcodeFlavor == 'Makerbot': - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_MAKERBOT" - elif gcodeFlavor == 'BFB': - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_BFB" - elif gcodeFlavor == 'Mach3': - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_MACH3" - elif gcodeFlavor == 'Volumetric': - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP_VOLUMATRIC" - else: - engine_settings['gcodeFlavor'] = "GCODE_FLAVOR_REPRAP" - - engine_settings['startCode'] = settings.getSettingValueByKey('machine_start_gcode') - engine_settings['endCode'] = settings.getSettingValueByKey('machine_end_gcode') - - #for n in range(1, self._machine.getMaxNozzles()): - n = 1 - engine_settings['extruderOffset1.X'] = int(settings.getSettingValueByKey('machine_nozzle_offset_x_1') * 1000) - engine_settings['extruderOffset1.Y'] = int(settings.getSettingValueByKey('machine_nozzle_offset_y_1') * 1000) - - if not settings.getSettingValueByKey('machine_center_is_zero'): - engine_settings['position.X'] = int((settings.getSettingValueByKey('machine_width') / 2.0) * 1000) - engine_settings['position.Y'] = int((settings.getSettingValueByKey('machine_depth') / 2.0) * 1000) - self._center = Vector(settings.getSettingValueByKey('machine_width') / 2.0, 0.0, settings.getSettingValueByKey('machine_depth') / 2.0) - else: - engine_settings['position.X'] = 0 - engine_settings['position.Y'] = 0 - self._center = Vector(0.0, 0.0, 0.0) - engine_settings['position.Z'] = 0 - - msg = Cura_pb2.SettingList() - for key, value in engine_settings.items(): - s = msg.settings.add() - s.name = key - s.value = str(value).encode('utf-8') + s.name = setting.getKey() + s.value = str(setting.getValue()).encode('utf-8') self._socket.sendMessage(msg) diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index e9a7adebd9..5f9192a776 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -10,11 +10,10 @@ import numpy import struct class ProcessSlicedObjectListJob(Job): - def __init__(self, message, center): + def __init__(self, message): super().__init__(description = 'Processing sliced object') self._message = message self._scene = Application.getInstance().getController().getScene() - self._center = center def run(self): objectIdMap = {} @@ -46,9 +45,6 @@ class ProcessSlicedObjectListJob(Job): points /= 1000 points = numpy.insert(points, 1, layer.id * layerHeight, axis = 1) - points[:,0] -= self._center.x - points[:,2] -= self._center.z - #points = numpy.pad(points, ((0,0), (0,1)), 'constant', constant_values=(0.0, 1.0)) #inverse = node.getWorldTransformation().getInverse().getData() #points = points.dot(inverse) From 9dbff5a109e0e5fc00476e4fdbe426c9ef5f2575 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 28 Apr 2015 11:30:52 +0200 Subject: [PATCH 73/76] Only build the layer data mesh after we have received all the polygons Certain polygons might be added to a layer later, so to prevent issues when using range drawing, we need to wait until we have all layer data then process that in the right order. --- LayerData.py | 38 +++++++++++++++++++++++------------ ProcessSlicedObjectListJob.py | 2 ++ 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/LayerData.py b/LayerData.py index cfa2249d40..b9a3e2e31c 100644 --- a/LayerData.py +++ b/LayerData.py @@ -8,7 +8,7 @@ class LayerData(MeshData): def __init__(self): super().__init__() self._layers = {} - self._element_counts = [] + self._element_counts = {} def addPolygon(self, layer, type, data): if layer not in self._layers: @@ -16,7 +16,6 @@ class LayerData(MeshData): p = Polygon(self, type, data) self._layers[layer].append(p) - self._element_counts.append(p.count) def getLayers(self): return self._layers @@ -24,6 +23,15 @@ class LayerData(MeshData): def getElementCounts(self): return self._element_counts + def build(self): + for layer, data in self._layers.items(): + if layer not in self._element_counts: + self._element_counts[layer] = [] + + for polygon in data: + polygon.build() + self._element_counts[layer].append(polygon.count) + class Polygon(): NoneType = 0 Inset0Type = 1 @@ -34,27 +42,31 @@ class Polygon(): def __init__(self, mesh, type, data): super().__init__() + self._mesh = mesh self._type = type - self._begin = mesh._vertex_count - mesh.addVertices(data) - self._end = self._begin + len(data) - 1 + self._data = data + + def build(self): + self._begin = self._mesh._vertex_count + self._mesh.addVertices(self._data) + self._end = self._begin + len(self._data) - 1 color = None - if type == self.Inset0Type: + if self._type == self.Inset0Type: color = [1, 0, 0, 1] - elif type == self.InsetXType: + elif self._type == self.InsetXType: color = [0, 1, 0, 1] - elif type == self.SkinType: + elif self._type == self.SkinType: color = [1, 1, 0, 1] - elif type == self.SupportType: + elif self._type == self.SupportType: color = [0, 1, 1, 1] - elif type == self.SkirtType: + elif self._type == self.SkirtType: color = [0, 1, 1, 1] else: color = [1, 1, 1, 1] - colors = [color for i in range(len(data))] - mesh.addColors(numpy.array(colors, dtype=numpy.float32)) + colors = [color for i in range(len(self._data))] + self._mesh.addColors(numpy.array(colors, dtype=numpy.float32)) indices = [] for i in range(self._begin, self._end): @@ -63,7 +75,7 @@ class Polygon(): indices.append(self._end) indices.append(self._begin) - mesh.addIndices(numpy.array(indices, dtype=numpy.int32)) + self._mesh.addIndices(numpy.array(indices, dtype=numpy.int32)) @property def type(self): diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index 6cd823ba2d..92f26b1fc5 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -54,6 +54,8 @@ class ProcessSlicedObjectListJob(Job): layerData.addPolygon(layer.id, polygon.type, points) + # We are done processing all the layers we got from the engine, now create a mesh out of the data + layerData.build() mesh.layerData = layerData new_node.setMeshData(mesh) From 52868ec01e009c78884e45abfb7aed12f1f5a10c Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Tue, 28 Apr 2015 11:50:54 +0200 Subject: [PATCH 74/76] Rename Polygon.count to Polygon.elementCount and return the proper element count --- LayerData.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LayerData.py b/LayerData.py index b9a3e2e31c..33ec83cd81 100644 --- a/LayerData.py +++ b/LayerData.py @@ -30,7 +30,7 @@ class LayerData(MeshData): for polygon in data: polygon.build() - self._element_counts[layer].append(polygon.count) + self._element_counts[layer].append(polygon.elementCount) class Polygon(): NoneType = 0 @@ -86,5 +86,5 @@ class Polygon(): return self._data @property - def count(self): - return self._end - self._begin + def elementCount(self): + return (self._end - self._begin) * 2 #The range of vertices multiplied by 2 since each vertex is used twice From b9f99a3c56d505be7977fdce5ea9fbeb7e381018 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Wed, 29 Apr 2015 17:46:53 +0200 Subject: [PATCH 75/76] Translate the received polygons from the engine to use 0,0 as center --- ProcessSlicedObjectListJob.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ProcessSlicedObjectListJob.py b/ProcessSlicedObjectListJob.py index 92f26b1fc5..2938dde0a9 100644 --- a/ProcessSlicedObjectListJob.py +++ b/ProcessSlicedObjectListJob.py @@ -26,7 +26,8 @@ class ProcessSlicedObjectListJob(Job): else: objectIdMap[id(node)] = node - layerHeight = Application.getInstance().getActiveMachine().getSettingValueByKey('layer_height') + settings = Application.getInstance().getActiveMachine() + layerHeight = settings.getSettingValueByKey('layer_height') for object in self._message.objects: try: @@ -47,6 +48,10 @@ class ProcessSlicedObjectListJob(Job): points[:,2] *= -1 + if not settings.getSettingValueByKey('machine_center_is_zero'): + center = [settings.getSettingValueByKey('machine_width') / 2, 0.0, -settings.getSettingValueByKey('machine_depth') / 2] + points -= numpy.array(center) + #points = numpy.pad(points, ((0,0), (0,1)), 'constant', constant_values=(0.0, 1.0)) #inverse = node.getWorldTransformation().getInverse().getData() #points = points.dot(inverse) From 918d4b41c802f5e8acd0e271a261b73df0441346 Mon Sep 17 00:00:00 2001 From: Arjen Hiemstra Date: Thu, 30 Apr 2015 12:23:48 +0200 Subject: [PATCH 76/76] Remove obsolete "Commands" directory --- Commands/TransferMeshCommand.py | 21 --------------------- Commands/TransferMeshesCommand.py | 19 ------------------- Commands/TransferVerticeListCommand.py | 8 -------- 3 files changed, 48 deletions(-) delete mode 100644 Commands/TransferMeshCommand.py delete mode 100644 Commands/TransferMeshesCommand.py delete mode 100644 Commands/TransferVerticeListCommand.py diff --git a/Commands/TransferMeshCommand.py b/Commands/TransferMeshCommand.py deleted file mode 100644 index 038b0fc03f..0000000000 --- a/Commands/TransferMeshCommand.py +++ /dev/null @@ -1,21 +0,0 @@ -from UM.Backend.Command import Command -from UM.plugins.UMBackendEngine.Commands.TransferVertCommand import TransferVertCommand - -class TransferMeshCommand(Command): - def __init__(self): - super(TransferMeshCommand,self).__init__() - - def send(self, mesh_data): - vertices = mesh_data.getVerticesList() - self._socket.sendCommand(0x00200001, len(vertices)) # Tell other side that mesh with num vertices is going to be sent. - - command = TransferVertCommand(self._socket) - command.send(vertices) - - - def recieve(self): - command_id, data = self._socket.getNextCommand() - if(command_id is not 0x00200001): - print("Wrong command!") - return None - unpacked_data = struct(' \ No newline at end of file diff --git a/Commands/TransferMeshesCommand.py b/Commands/TransferMeshesCommand.py deleted file mode 100644 index 706452c640..0000000000 --- a/Commands/TransferMeshesCommand.py +++ /dev/null @@ -1,19 +0,0 @@ -from UM.Backend.Command import Command -from UM.plugins.UMBackendEngine.Commands.TransferMeshCommand import TransferMeshCommand - -class TransferMeshesCommand(Command): - def __init__(self): - super(TransferMeshesCommand,self).__init__() - - def send(self, meshes): - self._socket.sendCommand(0x00200000,len(meshes)) # Tell other side that n meshes are going to be sent. - command = TransferMeshCommand(self._socket) - for mesh in meshes: - command.send(mesh) - - def recieve(self, num_meshes): - meshes = [] - command = TransferMeshCommand(self._socket) - for x in range(0,num_meshes): - meshes.append(command.recieve()) - return meshes \ No newline at end of file diff --git a/Commands/TransferVerticeListCommand.py b/Commands/TransferVerticeListCommand.py deleted file mode 100644 index 3390a9eb03..0000000000 --- a/Commands/TransferVerticeListCommand.py +++ /dev/null @@ -1,8 +0,0 @@ -from UM.Backend.Command import Command - -class TransferVerticeListCommand(Command): - def __init__(self): - super(TransferVertCommand,self).__init__() - - def send(self, vertices): - self._socet.sendCommandPacked(0x00200002, vertices.toString()) # Send vertex list \ No newline at end of file