Fixed merge issues & updated proto files

This commit is contained in:
Jaime van Kessel 2016-02-02 11:25:10 +01:00
commit 7c744044fd
5 changed files with 181 additions and 78 deletions

View file

@ -140,26 +140,7 @@ class Layer():
if polygon.type == Polygon.MoveCombingType or polygon.type == Polygon.MoveRetractionType:
points[:,1] += 0.01
# Calculate normals for the entire polygon using numpy.
normals = numpy.copy(points)
normals[:,1] = 0.0 # We are only interested in 2D normals
# Calculate the edges between points.
# The call to numpy.roll shifts the entire array by one so that
# we end up subtracting each next point from the current, wrapping
# around. This gives us the edges from the next point to the current
# point.
normals[:] = normals[:] - numpy.roll(normals, -1, axis = 0)
# Calculate the length of each edge using standard Pythagoras
lengths = numpy.sqrt(normals[:,0] ** 2 + normals[:,2] ** 2)
# The normal of a 2D vector is equal to its x and y coordinates swapped
# and then x inverted. This code does that.
normals[:,[0, 2]] = normals[:,[2, 0]]
normals[:,0] *= -1
# Normalize the normals.
normals[:,0] /= lengths
normals[:,2] /= lengths
normals = polygon.getNormals()
# Scale all by the line width of the polygon so we can easily offset.
normals *= (polygon.lineWidth / 2)
@ -199,16 +180,33 @@ class Polygon():
self._data = data
self._line_width = line_width / 1000
if type == self.Inset0Type:
self._color = Color(1.0, 0.0, 0.0, 1.0)
elif self._type == self.InsetXType:
self._color = Color(0.0, 1.0, 0.0, 1.0)
elif self._type == self.SkinType:
self._color = Color(1.0, 1.0, 0.0, 1.0)
elif self._type == self.SupportType:
self._color = Color(0.0, 1.0, 1.0, 1.0)
elif self._type == self.SkirtType:
self._color = Color(0.0, 1.0, 1.0, 1.0)
elif self._type == self.InfillType:
self._color = Color(1.0, 0.74, 0.0, 1.0)
elif self._type == self.SupportInfillType:
self._color = Color(0.0, 1.0, 1.0, 1.0)
elif self._type == self.MoveCombingType:
self._color = Color(0.0, 0.0, 1.0, 1.0)
elif self._type == self.MoveRetractionType:
self._color = Color(0.5, 0.5, 1.0, 1.0)
else:
self._color = Color(1.0, 1.0, 1.0, 1.0)
def build(self, offset, vertices, colors, indices):
self._begin = offset
self._end = self._begin + len(self._data) - 1
color = self.getColor()
color.setValues(color.r * 0.5, color.g * 0.5, color.b * 0.5, color.a)
color = numpy.array([color.r, color.g, color.b, color.a], numpy.float32)
vertices[self._begin:self._end + 1, :] = self._data[:, :]
colors[self._begin:self._end + 1, :] = color
colors[self._begin:self._end + 1, :] = numpy.array([self._color.r * 0.5, self._color.g * 0.5, self._color.b * 0.5, self._color.a], numpy.float32)
for i in range(self._begin, self._end):
indices[i, 0] = i
@ -218,26 +216,7 @@ class Polygon():
indices[self._end, 1] = self._begin
def getColor(self):
if self._type == self.Inset0Type:
return Color(1.0, 0.0, 0.0, 1.0)
elif self._type == self.InsetXType:
return Color(0.0, 1.0, 0.0, 1.0)
elif self._type == self.SkinType:
return Color(1.0, 1.0, 0.0, 1.0)
elif self._type == self.SupportType:
return Color(0.0, 1.0, 1.0, 1.0)
elif self._type == self.SkirtType:
return Color(0.0, 1.0, 1.0, 1.0)
elif self._type == self.InfillType:
return Color(1.0, 0.74, 0.0, 1.0)
elif self._type == self.SupportInfillType:
return Color(0.0, 1.0, 1.0, 1.0)
elif self._type == self.MoveCombingType:
return Color(0.0, 0.0, 1.0, 1.0)
elif self._type == self.MoveRetractionType:
return Color(0.5, 0.5, 1.0, 1.0)
else:
return Color(1.0, 1.0, 1.0, 1.0)
return self._color
def vertexCount(self):
return len(self._data)
@ -257,3 +236,27 @@ class Polygon():
@property
def lineWidth(self):
return self._line_width
# Calculate normals for the entire polygon using numpy.
def getNormals(self):
normals = numpy.copy(self._data)
normals[:,1] = 0.0 # We are only interested in 2D normals
# Calculate the edges between points.
# The call to numpy.roll shifts the entire array by one so that
# we end up subtracting each next point from the current, wrapping
# around. This gives us the edges from the next point to the current
# point.
normals[:] = normals[:] - numpy.roll(normals, -1, axis = 0)
# Calculate the length of each edge using standard Pythagoras
lengths = numpy.sqrt(normals[:,0] ** 2 + normals[:,2] ** 2)
# The normal of a 2D vector is equal to its x and y coordinates swapped
# and then x inverted. This code does that.
normals[:,[0, 2]] = normals[:,[2, 0]]
normals[:,0] *= -1
# Normalize the normals.
normals[:,0] /= lengths
normals[:,2] /= lengths
return normals

View file

@ -0,0 +1,104 @@
syntax = "proto3";
package cura.proto;
message ObjectList
{
repeated Object objects = 1;
repeated Setting settings = 2;
}
// typeid 1
message Slice
{
repeated ObjectList object_lists = 1;
}
message Object
{
int64 id = 1;
bytes vertices = 2; //An array of 3 floats.
bytes normals = 3; //An array of 3 floats.
bytes indices = 4; //An array of ints.
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;
repeated Polygon polygons = 4;
}
message Polygon {
enum Type {
NoneType = 0;
Inset0Type = 1;
InsetXType = 2;
SkinType = 3;
SupportType = 4;
SkirtType = 5;
InfillType = 6;
SupportInfillType = 7;
MoveCombingType = 8;
MoveRetractionType = 9;
}
Type type = 1;
bytes points = 2;
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;
}
message Setting {
string name = 1;
bytes value = 2;
}
// typeid 7
message GCodePrefix {
bytes data = 2;
}
// typeid 8
message SlicingFinished {
}

View file

@ -13,6 +13,7 @@ from UM.Qt.Bindings.BackendProxy import BackendState #To determine the state of
from UM.Resources import Resources
from UM.Settings.SettingOverrideDecorator import SettingOverrideDecorator
from UM.Message import Message
from UM.PluginRegistry import PluginRegistry
from cura.OneAtATimeIterator import OneAtATimeIterator
from . import Cura_pb2
@ -62,12 +63,12 @@ class CuraEngineBackend(Backend):
self._change_timer.setSingleShot(True)
self._change_timer.timeout.connect(self.slice)
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._message_handlers[Cura_pb2.SlicingFinished] = self._onSlicingFinishedMessage
self._message_handlers["cura.proto.SlicedObjectList"] = self._onSlicedObjectListMessage
self._message_handlers["cura.proto.Progress"] = self._onProgressMessage
self._message_handlers["cura.proto.GCodeLayer"] = self._onGCodeLayerMessage
self._message_handlers["cura.proto.GCodePrefix"] = self._onGCodePrefixMessage
self._message_handlers["cura.proto.ObjectPrintTime"] = self._onObjectPrintTimeMessage
self._message_handlers["cura.proto.SlicingFinished"] = self._onSlicingFinishedMessage
self._slicing = False
self._restart = False
@ -230,16 +231,7 @@ class CuraEngineBackend(Backend):
self.printDurationMessage.emit(message.time, message.material_amount)
def _createSocket(self):
super()._createSocket()
self._socket.registerMessageType(1, Cura_pb2.Slice)
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)
self._socket.registerMessageType(8, Cura_pb2.SlicingFinished)
super()._createSocket(os.path.abspath(os.path.join(PluginRegistry.getInstance().getPluginPath(self.getPluginId()), "Cura.proto")))
## Manually triggers a reslice
def forceSlice(self):
@ -278,7 +270,6 @@ class CuraEngineBackend(Backend):
else:
self._layer_view_active = False
def _onInstanceChanged(self):
self._terminate()
self.slicingCancelled.emit()

View file

@ -56,21 +56,27 @@ class ProcessSlicedObjectListJob(Job):
layer_data = LayerData.LayerData()
layer_count = 0
for object in self._message.objects:
layer_count += len(object.layers)
for i in range(self._message.repeatedMessageCount("objects")):
layer_count += self._message.getRepeatedMessage("objects", i).repeatedMessageCount("layers")
current_layer = 0
for object in self._message.objects:
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 layer in object.layers:
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 polygon in layer.polygons:
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.
points = numpy.asarray(points, dtype=numpy.float32)
@ -83,8 +89,6 @@ class ProcessSlicedObjectListJob(Job):
layer_data.addPolygon(layer.id, polygon.type, 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.

View file

@ -81,20 +81,21 @@ class StartSliceJob(Job):
self._sendSettings(self._profile)
slice_message = Cura_pb2.Slice()
slice_message = self._socket.createMessage("cura.proto.Slice");
for group in object_groups:
group_message = slice_message.object_lists.add()
group_message = slice_message.addRepeatedMessage("object_lists");
for object in group:
mesh_data = object.getMeshData().getTransformed(object.getWorldTransformation())
obj = group_message.objects.add()
obj = group_message.addRepeatedMessage("objects");
obj.id = id(object)
verts = numpy.array(mesh_data.getVertices())
verts[:,[1,2]] = verts[:,[2,1]]
verts[:,1] *= -1
obj.vertices = verts.tostring()
obj.vertices = verts
self._handlePerObjectSettings(object, obj)
@ -115,13 +116,13 @@ class StartSliceJob(Job):
return str(value).encode("utf-8")
def _sendSettings(self, profile):
msg = Cura_pb2.SettingList()
msg = self._socket.createMessage("cura.proto.SettingList");
settings = profile.getAllSettingValues(include_machine = True)
start_gcode = settings["machine_start_gcode"]
settings["material_bed_temp_prepend"] = "{material_bed_temperature}" not in start_gcode
settings["material_print_temp_prepend"] = "{material_print_temperature}" not in start_gcode
for key, value in settings.items():
s = msg.settings.add()
s = msg.addRepeatedMessage("settings")
s.name = key
if key == "machine_start_gcode" or key == "machine_end_gcode":
s.value = self._expandGcodeTokens(key, value, settings)
@ -134,7 +135,7 @@ class StartSliceJob(Job):
profile = node.callDecoration("getProfile")
if profile:
for key, value in profile.getAllSettingValues().items():
setting = message.settings.add()
setting = message.addRepeatedMessage("settings")
setting.name = key
setting.value = str(value).encode()
@ -145,7 +146,7 @@ class StartSliceJob(Job):
return
for key, value in object_settings.items():
setting = message.settings.add()
setting = message.addRepeatedMessage("settings")
setting.name = key
setting.value = str(value).encode()