Browse Source

Merge branch '2.1-max_message_size_fix' of https://github.com/Ultimaker/Cura into 2.1

Jaime van Kessel 9 years ago
parent
commit
e2e25ea3e8

+ 1 - 24
plugins/CuraEngineBackend/Cura.proto

@@ -2,14 +2,12 @@ syntax = "proto3";
 
 package cura.proto;
 
-
 message ObjectList
 {
     repeated Object objects = 1;
     repeated Setting settings = 2;
 }
 
-// typeid 1
 message Slice
 {
     repeated ObjectList object_lists = 1;
@@ -24,28 +22,13 @@ message Object
     repeated Setting settings = 5; // Setting override per object, overruling the global settings.
 }
 
-// typeid 3
 message Progress
 {
     float amount = 1;
 }
 
-// typeid 2
-message SlicedObjectList
-{
-    repeated SlicedObject objects = 1;
-}
-
-message SlicedObject
-{
-    int64 id = 1;
-
-    repeated Layer layers = 2;
-}
-
 message Layer {
     int32 id = 1;
-
     float height = 2;
     float thickness = 3;
 
@@ -70,20 +53,16 @@ message Polygon {
     float line_width = 3;
 }
 
-// typeid 4
 message GCodeLayer {
-    int64 id = 1;
     bytes data = 2;
 }
 
-// typeid 5
 message ObjectPrintTime {
     int64 id = 1;
     float time = 2;
     float material_amount = 3;
 }
 
-// typeid 6
 message SettingList {
     repeated Setting settings = 1;
 }
@@ -94,11 +73,9 @@ message Setting {
     bytes value = 2;
 }
 
-// typeid 7
 message GCodePrefix {
     bytes data = 2;
 }
 
-// typeid 8
 message SlicingFinished {
-}
+}

+ 14 - 11
plugins/CuraEngineBackend/CuraEngineBackend.py

@@ -16,7 +16,7 @@ from UM.Message import Message
 from UM.PluginRegistry import PluginRegistry
 
 from cura.OneAtATimeIterator import OneAtATimeIterator
-from . import ProcessSlicedObjectListJob
+from . import ProcessSlicedLayersJob
 from . import ProcessGCodeJob
 from . import StartSliceJob
 
@@ -51,7 +51,7 @@ class CuraEngineBackend(Backend):
         self._layer_view_active = False
         Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged)
         self._onActiveViewChanged()
-        self._stored_layer_data = None
+        self._stored_layer_data = []
 
         # When there are current settings and machine instance is changed, there is no profile changed event. We should
         # pretend there is though.
@@ -66,7 +66,7 @@ class CuraEngineBackend(Backend):
         self._change_timer.setSingleShot(True)
         self._change_timer.timeout.connect(self.slice)
 
-        self._message_handlers["cura.proto.SlicedObjectList"] = self._onSlicedObjectListMessage
+        self._message_handlers["cura.proto.Layer"] = self._onLayerMessage
         self._message_handlers["cura.proto.Progress"] = self._onProgressMessage
         self._message_handlers["cura.proto.GCodeLayer"] = self._onGCodeLayerMessage
         self._message_handlers["cura.proto.GCodePrefix"] = self._onGCodePrefixMessage
@@ -157,6 +157,7 @@ class CuraEngineBackend(Backend):
     def _terminate(self):
         self._slicing = False
         self._restart = True
+        self._stored_layer_data = []
         self.slicingCancelled.emit()
         self.processingProgress.emit(0)
         Logger.log("d", "Attempting to kill the engine process")
@@ -213,12 +214,9 @@ class CuraEngineBackend(Backend):
     def _onSettingChanged(self, setting):
         self._onChanged()
 
-    def _onSlicedObjectListMessage(self, message):
-        if self._layer_view_active:
-            self._process_layers_job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(message)
-            self._process_layers_job.start()
-        else :
-            self._stored_layer_data = message
+    def _onLayerMessage(self, message):
+        self._stored_layer_data.append(message)
+
 
     def _onProgressMessage(self, message):
         if self._message:
@@ -238,6 +236,11 @@ class CuraEngineBackend(Backend):
             self._message.hide()
             self._message = None
 
+        if self._layer_view_active and (self._process_layers_job is None or not self._process_layers_job.isRunning()):
+            self._process_layers_job = ProcessSlicedLayersJob.ProcessSlicedLayersJob(self._stored_layer_data)
+            self._process_layers_job.start()
+            self._stored_layer_data = []
+
     def _onGCodeLayerMessage(self, message):
         self._scene.gcode_list.append(message.data.decode("utf-8", "replace"))
 
@@ -280,9 +283,9 @@ class CuraEngineBackend(Backend):
                 # There is data and we're not slicing at the moment
                 # if we are slicing, there is no need to re-calculate the data as it will be invalid in a moment.
                 if self._stored_layer_data and not self._slicing:
-                    self._process_layers_job = ProcessSlicedObjectListJob.ProcessSlicedObjectListJob(self._stored_layer_data)
+                    self._process_layers_job = ProcessSlicedLayersJob.ProcessSlicedLayersJob(self._stored_layer_data)
                     self._process_layers_job.start()
-                    self._stored_layer_data = None
+                    self._stored_layer_data = []
             else:
                 self._layer_view_active = False
 

+ 41 - 53
plugins/CuraEngineBackend/ProcessSlicedObjectListJob.py → plugins/CuraEngineBackend/ProcessSlicedLayersJob.py

@@ -1,4 +1,4 @@
-# Copyright (c) 2015 Ultimaker B.V.
+# Copyright (c) 2016 Ultimaker B.V.
 # Cura is released under the terms of the AGPLv3 or higher.
 
 from UM.Job import Job
@@ -20,10 +20,10 @@ import struct
 
 catalog = i18nCatalog("cura")
 
-class ProcessSlicedObjectListJob(Job):
-    def __init__(self, message):
+class ProcessSlicedLayersJob(Job):
+    def __init__(self, layers):
         super().__init__()
-        self._message = message
+        self._layers = layers
         self._scene = Application.getInstance().getController().getScene()
         self._progress = None
         self._abort_requested = False
@@ -51,13 +51,12 @@ class ProcessSlicedObjectListJob(Job):
 
         object_id_map = {}
         new_node = SceneNode()
-        ## Put all nodes in a dict identified by ID
+
+        ## Remove old layer data (if any)
         for node in DepthFirstIterator(self._scene.getRoot()):
             if type(node) is SceneNode and node.getMeshData():
                 if node.callDecoration("getLayerData"):
                     self._scene.getRoot().removeChild(node)
-                else:
-                    object_id_map[id(node)] = node
             Job.yieldThread()
             if self._abort_requested:
                 if self._progress:
@@ -68,56 +67,45 @@ class ProcessSlicedObjectListJob(Job):
 
         mesh = MeshData()
         layer_data = LayerData.LayerData()
-
-        layer_count = 0
-        for i in range(self._message.repeatedMessageCount("objects")):
-            layer_count += self._message.getRepeatedMessage("objects", i).repeatedMessageCount("layers")
+        layer_count = len(self._layers)
 
         current_layer = 0
-        for i in range(self._message.repeatedMessageCount("objects")):
-            object = self._message.getRepeatedMessage("objects", i)
-            try:
-                node = object_id_map[object.id]
-            except KeyError:
-                continue
-
-            for l in range(object.repeatedMessageCount("layers")):
-                layer = object.getRepeatedMessage("layers", l)
-
-                layer_data.addLayer(layer.id)
-                layer_data.setLayerHeight(layer.id, layer.height)
-                layer_data.setLayerThickness(layer.id, layer.thickness)
-
-                for p in range(layer.repeatedMessageCount("polygons")):
-                    polygon = layer.getRepeatedMessage("polygons", p)
-
-                    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.
-
-                    # Create a new 3D-array, copy the 2D points over and insert the right height.
-                    # This uses manual array creation + copy rather than numpy.insert since this is
-                    # faster.
-                    new_points = numpy.empty((len(points), 3), numpy.float32)
-                    new_points[:,0] = points[:,0]
-                    new_points[:,1] = layer.height
-                    new_points[:,2] = -points[:,1]
-
-                    new_points /= 1000
-
-                    layer_data.addPolygon(layer.id, polygon.type, new_points, polygon.line_width)
-                    Job.yieldThread()
+
+        for layer in self._layers:
+            layer_data.addLayer(layer.id)
+            layer_data.setLayerHeight(layer.id, layer.height)
+            layer_data.setLayerThickness(layer.id, layer.thickness)
+
+            for p in range(layer.repeatedMessageCount("polygons")):
+                polygon = layer.getRepeatedMessage("polygons", p)
+
+                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.
+
+                # Create a new 3D-array, copy the 2D points over and insert the right height.
+                # This uses manual array creation + copy rather than numpy.insert since this is
+                # faster.
+                new_points = numpy.empty((len(points), 3), numpy.float32)
+                new_points[:,0] = points[:,0]
+                new_points[:,1] = layer.height
+                new_points[:,2] = -points[:,1]
+
+                new_points /= 1000
+
+                layer_data.addPolygon(layer.id, polygon.type, new_points, polygon.line_width)
                 Job.yieldThread()
-                current_layer += 1
-                progress = (current_layer / layer_count) * 100
-                # TODO: Rebuild the layer data mesh once the layer has been processed.
-                # This needs some work in LayerData so we can add the new layers instead of recreating the entire mesh.
-
-                if self._abort_requested:
-                    if self._progress:
-                        self._progress.hide()
-                    return
+            Job.yieldThread()
+            current_layer += 1
+            progress = (current_layer / layer_count) * 100
+            # TODO: Rebuild the layer data mesh once the layer has been processed.
+            # This needs some work in LayerData so we can add the new layers instead of recreating the entire mesh.
+
+            if self._abort_requested:
                 if self._progress:
-                    self._progress.setProgress(progress)
+                    self._progress.hide()
+                return
+            if self._progress:
+                self._progress.setProgress(progress)
 
         # We are done processing all the layers we got from the engine, now create a mesh out of the data
         layer_data.build()