mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-11-23 02:41:01 -07:00
Merge branch '15.06'
* 15.06: Update changelog Correct the bottom offset we add when setting the volume for scale to max Display progress information during processing of layer data If findObject returns none but object_id != 0 use the selected object Offset the displayed rotation angle so it does not overlap the mouse cursor Abort attempts to connect if an error is thrown when connecting to the serial port Fix recent files on Windows Defer opening the webbrowser until the next run of the event loop Disable slicing and platform physics when an operation is being performed Rework LayerData mesh generation for improved performance Performance: Only calculate the platform center once, not for every poly Add application icons for all three platforms
This commit is contained in:
commit
a429e362ad
16 changed files with 190 additions and 51 deletions
|
|
@ -59,6 +59,8 @@ class CuraEngineBackend(Backend):
|
|||
self._save_polygons = True
|
||||
self._report_progress = True
|
||||
|
||||
self._enabled = True
|
||||
|
||||
self.backendConnected.connect(self._onBackendConnected)
|
||||
|
||||
def getEngineCommand(self):
|
||||
|
|
@ -86,6 +88,9 @@ class CuraEngineBackend(Backend):
|
|||
# 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 not self._enabled:
|
||||
return
|
||||
|
||||
if self._slicing:
|
||||
if not kwargs.get("force_restart", True):
|
||||
return
|
||||
|
|
@ -235,3 +240,10 @@ class CuraEngineBackend(Backend):
|
|||
if self._restart:
|
||||
self._onChanged()
|
||||
self._restart = False
|
||||
|
||||
def _onToolOperationStarted(self, tool):
|
||||
self._enabled = False
|
||||
|
||||
def _onToolOperationStopped(self, tool):
|
||||
self._enabled = True
|
||||
self._onChanged()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ from UM.Math.Vector import Vector
|
|||
|
||||
import numpy
|
||||
import math
|
||||
import copy
|
||||
|
||||
class LayerData(MeshData):
|
||||
def __init__(self):
|
||||
|
|
@ -48,11 +49,23 @@ class LayerData(MeshData):
|
|||
self._layers[layer].setThickness(thickness)
|
||||
|
||||
def build(self):
|
||||
vertex_count = 0
|
||||
for layer, data in self._layers.items():
|
||||
data.build()
|
||||
vertex_count += data.vertexCount()
|
||||
|
||||
vertices = numpy.empty((vertex_count, 3), numpy.float32)
|
||||
colors = numpy.empty((vertex_count, 4), numpy.float32)
|
||||
indices = numpy.empty((vertex_count, 2), numpy.int32)
|
||||
|
||||
offset = 0
|
||||
for layer, data in self._layers.items():
|
||||
offset = data.build(offset, vertices, colors, indices)
|
||||
self._element_counts[layer] = data.elementCount
|
||||
|
||||
self.addVertices(vertices)
|
||||
self.addColors(colors)
|
||||
self.addIndices(indices.flatten())
|
||||
|
||||
class Layer():
|
||||
def __init__(self, id):
|
||||
self._id = id
|
||||
|
|
@ -83,20 +96,30 @@ class Layer():
|
|||
def setThickness(self, thickness):
|
||||
self._thickness = thickness
|
||||
|
||||
def build(self):
|
||||
def vertexCount(self):
|
||||
result = 0
|
||||
for polygon in self._polygons:
|
||||
result += polygon.vertexCount()
|
||||
|
||||
return result
|
||||
|
||||
def build(self, offset, vertices, colors, indices):
|
||||
result = offset
|
||||
for polygon in self._polygons:
|
||||
if polygon._type == Polygon.InfillType or polygon._type == Polygon.SupportInfillType:
|
||||
continue
|
||||
|
||||
polygon.build()
|
||||
polygon.build(result, vertices, colors, indices)
|
||||
result += polygon.vertexCount()
|
||||
self._element_count += polygon.elementCount
|
||||
|
||||
return result
|
||||
|
||||
def createMesh(self):
|
||||
builder = MeshBuilder()
|
||||
|
||||
for polygon in self._polygons:
|
||||
poly_color = polygon.getColor()
|
||||
poly_color = Color(poly_color[0], poly_color[1], poly_color[2], poly_color[3])
|
||||
|
||||
points = numpy.copy(polygon.data)
|
||||
if polygon.type == Polygon.InfillType or polygon.type == Polygon.SkinType or polygon.type == Polygon.SupportInfillType:
|
||||
|
|
@ -159,43 +182,48 @@ class Polygon():
|
|||
self._data = data
|
||||
self._line_width = line_width / 1000
|
||||
|
||||
def build(self):
|
||||
self._begin = self._mesh._vertex_count
|
||||
self._mesh.addVertices(self._data)
|
||||
self._end = self._begin + len(self._data) - 1
|
||||
def build(self, offset, vertices, colors, indices):
|
||||
self._begin = offset
|
||||
|
||||
color = self.getColor()
|
||||
color[3] = 2.0
|
||||
color.setValues(color.r * 0.5, color.g * 0.5, color.b * 0.5, color.a)
|
||||
|
||||
colors = [color for i in range(len(self._data))]
|
||||
self._mesh.addColors(numpy.array(colors, dtype=numpy.float32) * 0.5)
|
||||
for i in range(len(self._data)):
|
||||
vertices[offset + i, :] = self._data[i, :]
|
||||
colors[offset + i, 0] = color.r
|
||||
colors[offset + i, 1] = color.g
|
||||
colors[offset + i, 2] = color.b
|
||||
colors[offset + i, 3] = color.a
|
||||
|
||||
self._end = self._begin + len(self._data) - 1
|
||||
|
||||
indices = []
|
||||
for i in range(self._begin, self._end):
|
||||
indices.append(i)
|
||||
indices.append(i + 1)
|
||||
indices[i, 0] = i
|
||||
indices[i, 1] = i + 1
|
||||
|
||||
indices.append(self._end)
|
||||
indices.append(self._begin)
|
||||
self._mesh.addIndices(numpy.array(indices, dtype=numpy.int32))
|
||||
indices[self._end, 0] = self._end
|
||||
indices[self._end, 1] = self._begin
|
||||
|
||||
def getColor(self):
|
||||
if self._type == self.Inset0Type:
|
||||
return [1.0, 0.0, 0.0, 1.0]
|
||||
return Color(1.0, 0.0, 0.0, 1.0)
|
||||
elif self._type == self.InsetXType:
|
||||
return [0.0, 1.0, 0.0, 1.0]
|
||||
return Color(0.0, 1.0, 0.0, 1.0)
|
||||
elif self._type == self.SkinType:
|
||||
return [1.0, 1.0, 0.0, 1.0]
|
||||
return Color(1.0, 1.0, 0.0, 1.0)
|
||||
elif self._type == self.SupportType:
|
||||
return [0.0, 1.0, 1.0, 1.0]
|
||||
return Color(0.0, 1.0, 1.0, 1.0)
|
||||
elif self._type == self.SkirtType:
|
||||
return [0.0, 1.0, 1.0, 1.0]
|
||||
return Color(0.0, 1.0, 1.0, 1.0)
|
||||
elif self._type == self.InfillType:
|
||||
return [1.0, 1.0, 0.0, 1.0]
|
||||
return Color(1.0, 1.0, 0.0, 1.0)
|
||||
elif self._type == self.SupportInfillType:
|
||||
return [0.0, 1.0, 1.0, 1.0]
|
||||
return Color(0.0, 1.0, 1.0, 1.0)
|
||||
else:
|
||||
return [1.0, 1.0, 1.0, 1.0]
|
||||
return Color(1.0, 1.0, 1.0, 1.0)
|
||||
|
||||
def vertexCount(self):
|
||||
return len(self._data)
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
|
|
|
|||
|
|
@ -7,18 +7,30 @@ from UM.Scene.SceneNode import SceneNode
|
|||
from UM.Application import Application
|
||||
from UM.Mesh.MeshData import MeshData
|
||||
|
||||
from UM.Message import Message
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
from . import LayerData
|
||||
|
||||
import numpy
|
||||
import struct
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
class ProcessSlicedObjectListJob(Job):
|
||||
def __init__(self, message):
|
||||
super().__init__()
|
||||
self._message = message
|
||||
self._scene = Application.getInstance().getController().getScene()
|
||||
|
||||
self._progress = None
|
||||
Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged)
|
||||
|
||||
def run(self):
|
||||
if Application.getInstance().getController().getActiveView().getPluginId() == "LayerView":
|
||||
self._progress = Message(catalog.i18nc("Layers View mode", "Layers"), 0, False, 0)
|
||||
self._progress.show()
|
||||
|
||||
objectIdMap = {}
|
||||
new_node = SceneNode()
|
||||
## Put all nodes in a dict identified by ID
|
||||
|
|
@ -32,6 +44,15 @@ class ProcessSlicedObjectListJob(Job):
|
|||
settings = Application.getInstance().getActiveMachine()
|
||||
layerHeight = settings.getSettingValueByKey("layer_height")
|
||||
|
||||
center = None
|
||||
if not settings.getSettingValueByKey("machine_center_is_zero"):
|
||||
center = numpy.array([settings.getSettingValueByKey("machine_width") / 2, 0.0, -settings.getSettingValueByKey("machine_depth") / 2])
|
||||
else:
|
||||
center = numpy.array([0.0, 0.0, 0.0])
|
||||
|
||||
if self._progress:
|
||||
self._progress.setProgress(2)
|
||||
|
||||
mesh = MeshData()
|
||||
for object in self._message.objects:
|
||||
try:
|
||||
|
|
@ -53,15 +74,37 @@ 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.array(center)
|
||||
|
||||
layerData.addPolygon(layer.id, polygon.type, points, polygon.line_width)
|
||||
|
||||
if self._progress:
|
||||
self._progress.setProgress(50)
|
||||
|
||||
# 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
|
||||
|
||||
if self._progress:
|
||||
self._progress.setProgress(100)
|
||||
|
||||
new_node.setMeshData(mesh)
|
||||
new_node.setParent(self._scene.getRoot())
|
||||
|
||||
view = Application.getInstance().getController().getActiveView()
|
||||
if view.getPluginId() == "LayerView":
|
||||
view.resetLayerData()
|
||||
|
||||
if self._progress:
|
||||
self._progress.hide()
|
||||
|
||||
def _onActiveViewChanged(self):
|
||||
if self.isRunning():
|
||||
if Application.getInstance().getController().getActiveView().getPluginId() == "LayerView":
|
||||
if not self._progress:
|
||||
self._progress = Message(catalog.i18nc("Layers View mode", "Layers"), 0, False, 0)
|
||||
self._progress.show()
|
||||
else:
|
||||
if self._progress:
|
||||
self._progress.hide()
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ class LayerView(View):
|
|||
def getMaxLayers(self):
|
||||
return self._max_layers
|
||||
|
||||
def resetLayerData(self):
|
||||
self._current_layer_mesh = None
|
||||
|
||||
def beginRendering(self):
|
||||
scene = self.getController().getScene()
|
||||
renderer = self.getRenderer()
|
||||
|
|
|
|||
|
|
@ -173,6 +173,10 @@ class PrinterConnection(SignalEmitter):
|
|||
Logger.log("i", "Could not establish connection on %s: %s. Device is not arduino based." %(self._serial_port,str(e)))
|
||||
except Exception as e:
|
||||
Logger.log("i", "Could not establish connection on %s, unknown reasons. Device is not arduino based." % self._serial_port)
|
||||
|
||||
if not self._serial or not programmer.serial:
|
||||
self._is_connecting = False
|
||||
return
|
||||
|
||||
# If the programmer connected, we know its an atmega based version. Not all that usefull, but it does give some debugging information.
|
||||
for baud_rate in self._getBaudrateList(): # Cycle all baud rates (auto detect)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue