Merge branch 'master'

This commit is contained in:
Lipu Fei 2017-09-13 17:25:47 +02:00
commit 2e1c6abe0e
390 changed files with 1361 additions and 4887 deletions

4
.gitignore vendored
View File

@ -5,8 +5,8 @@ __pycache__
*.mo *.mo
docs/html docs/html
*.log *.log
resources/i18n/en resources/i18n/en_US
resources/i18n/7s resources/i18n/en_7S
resources/i18n/x-test resources/i18n/x-test
resources/firmware resources/firmware
resources/materials resources/materials

View File

@ -27,7 +27,11 @@ class ArrangeObjectsJob(Job):
self._min_offset = min_offset self._min_offset = min_offset
def run(self): def run(self):
status_message = Message(i18n_catalog.i18nc("@info:status", "Finding new location for objects"), lifetime = 0, dismissable=False, progress = 0) status_message = Message(i18n_catalog.i18nc("@info:status", "Finding new location for objects"),
lifetime = 0,
dismissable=False,
progress = 0,
title = i18n_catalog.i18nc("@info:title", "Finding Location"))
status_message.show() status_message.show()
arranger = Arrange.create(fixed_nodes = self._fixed_nodes) arranger = Arrange.create(fixed_nodes = self._fixed_nodes)
@ -82,5 +86,6 @@ class ArrangeObjectsJob(Job):
status_message.hide() status_message.hide()
if not found_solution_for_all: if not found_solution_for_all:
no_full_solution_message = Message(i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects")) no_full_solution_message = Message(i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects"),
title = i18n_catalog.i18nc("@info:title", "Can't Find Location"))
no_full_solution_message.show() no_full_solution_message.show()

View File

@ -27,9 +27,8 @@ import math
from typing import List from typing import List
PRIME_CLEARANCE = 6.5 #Setting for clearance around the prime. # Setting for clearance around the prime
MAJOR_GRID_SIZE = 10 #Size of the grid cells. PRIME_CLEARANCE = 6.5
MINOR_GRID_SIZE = 1
## Build volume is a special kind of node that is responsible for rendering the printable area & disallowed areas. ## Build volume is a special kind of node that is responsible for rendering the printable area & disallowed areas.
@ -45,8 +44,6 @@ class BuildVolume(SceneNode):
self._z_axis_color = None self._z_axis_color = None
self._disallowed_area_color = None self._disallowed_area_color = None
self._error_area_color = None self._error_area_color = None
self._grid_color = None
self._grid_minor_color = None
self._width = 0 self._width = 0
self._height = 0 self._height = 0
@ -59,9 +56,8 @@ class BuildVolume(SceneNode):
self._origin_line_length = 20 self._origin_line_length = 20
self._origin_line_width = 0.5 self._origin_line_width = 0.5
self._plate_mesh = None
self._grid_mesh = None self._grid_mesh = None
self._plate_shader = None self._grid_shader = None
self._disallowed_areas = [] self._disallowed_areas = []
self._disallowed_area_mesh = None self._disallowed_area_mesh = None
@ -96,14 +92,14 @@ class BuildVolume(SceneNode):
self._scene_change_timer.timeout.connect(self._onSceneChangeTimerFinished) self._scene_change_timer.timeout.connect(self._onSceneChangeTimerFinished)
self._setting_change_timer = QTimer() self._setting_change_timer = QTimer()
self._setting_change_timer.setInterval(100) self._setting_change_timer.setInterval(150)
self._setting_change_timer.setSingleShot(True) self._setting_change_timer.setSingleShot(True)
self._setting_change_timer.timeout.connect(self._onSettingChangeTimerFinished) self._setting_change_timer.timeout.connect(self._onSettingChangeTimerFinished)
self._build_volume_message = Message(catalog.i18nc("@info:status", self._build_volume_message = Message(catalog.i18nc("@info:status",
"The build volume height has been reduced due to the value of the" "The build volume height has been reduced due to the value of the"
" \"Print Sequence\" setting to prevent the gantry from colliding" " \"Print Sequence\" setting to prevent the gantry from colliding"
" with printed models.")) " with printed models."), title = catalog.i18nc("@info:title","Build Volume"))
# Must be after setting _build_volume_message, apparently that is used in getMachineManager. # Must be after setting _build_volume_message, apparently that is used in getMachineManager.
# activeQualityChanged is always emitted after setActiveVariant, setActiveMaterial and setActiveQuality. # activeQualityChanged is always emitted after setActiveVariant, setActiveMaterial and setActiveQuality.
@ -180,15 +176,15 @@ class BuildVolume(SceneNode):
if not self._shader: if not self._shader:
self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader")) self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "default.shader"))
self._plate_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader")) self._grid_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "grid.shader"))
theme = Application.getInstance().getTheme() theme = Application.getInstance().getTheme()
self._plate_shader.setUniformValue("u_color", Color(*theme.getColor("buildplate").getRgb())) self._grid_shader.setUniformValue("u_plateColor", Color(*theme.getColor("buildplate").getRgb()))
self._plate_shader.setUniformValue("u_z_bias", 0.000001) self._grid_shader.setUniformValue("u_gridColor0", Color(*theme.getColor("buildplate_grid").getRgb()))
self._grid_shader.setUniformValue("u_gridColor1", Color(*theme.getColor("buildplate_grid_minor").getRgb()))
renderer.queueNode(self, mode = RenderBatch.RenderMode.Lines) renderer.queueNode(self, mode = RenderBatch.RenderMode.Lines)
renderer.queueNode(self, mesh = self._origin_mesh) renderer.queueNode(self, mesh = self._origin_mesh)
renderer.queueNode(self, mesh = self._plate_mesh, shader = self._plate_shader, backface_cull = True) renderer.queueNode(self, mesh = self._grid_mesh, shader = self._grid_shader, backface_cull = True)
renderer.queueNode(self, mesh = self._grid_mesh, mode = RenderBatch.RenderMode.Lines, transparent = True)
if self._disallowed_area_mesh: if self._disallowed_area_mesh:
renderer.queueNode(self, mesh = self._disallowed_area_mesh, shader = self._shader, transparent = True, backface_cull = True, sort = -9) renderer.queueNode(self, mesh = self._disallowed_area_mesh, shader = self._shader, transparent = True, backface_cull = True, sort = -9)
@ -261,8 +257,6 @@ class BuildVolume(SceneNode):
self._z_axis_color = Color(*theme.getColor("z_axis").getRgb()) self._z_axis_color = Color(*theme.getColor("z_axis").getRgb())
self._disallowed_area_color = Color(*theme.getColor("disallowed_area").getRgb()) self._disallowed_area_color = Color(*theme.getColor("disallowed_area").getRgb())
self._error_area_color = Color(*theme.getColor("error_area").getRgb()) self._error_area_color = Color(*theme.getColor("error_area").getRgb())
self._grid_color = Color(*theme.getColor("buildplate_grid").getRgb())
self._grid_minor_color = Color(*theme.getColor("buildplate_grid_minor").getRgb())
min_w = -self._width / 2 min_w = -self._width / 2
max_w = self._width / 2 max_w = self._width / 2
@ -293,7 +287,7 @@ class BuildVolume(SceneNode):
self.setMeshData(mb.build()) self.setMeshData(mb.build())
# Build plate surface. # Build plate grid mesh
mb = MeshBuilder() mb = MeshBuilder()
mb.addQuad( mb.addQuad(
Vector(min_w, min_h - z_fight_distance, min_d), Vector(min_w, min_h - z_fight_distance, min_d),
@ -305,30 +299,6 @@ class BuildVolume(SceneNode):
for n in range(0, 6): for n in range(0, 6):
v = mb.getVertex(n) v = mb.getVertex(n)
mb.setVertexUVCoordinates(n, v[0], v[2]) mb.setVertexUVCoordinates(n, v[0], v[2])
self._plate_mesh = mb.build()
#Build plate grid mesh.
mb = MeshBuilder()
for x in range(0, int(math.ceil(max_w)), MAJOR_GRID_SIZE):
mb.addLine(Vector(x, min_h, min_d), Vector(x, min_h, max_d), color = self._grid_color)
#Start from 0 in both cases, so you need to do this in two for loops.
mb.addLine(Vector(-x, min_h, min_d), Vector(-x, min_h, max_d), color = self._grid_color)
for y in range(0, int(math.ceil(max_d)), MAJOR_GRID_SIZE):
mb.addLine(Vector(min_w, min_h, y), Vector(max_w, min_h, y), color = self._grid_color)
mb.addLine(Vector(min_w, min_h, -y), Vector(max_w, min_h, -y), color = self._grid_color)
#More fine grained grid.
for x in range(0, int(math.ceil(max_w)), MINOR_GRID_SIZE):
if x % MAJOR_GRID_SIZE == 0: #Don't overlap with the major grid.
pass
mb.addLine(Vector(x, min_h, min_d), Vector(x, min_h, max_d), color = self._grid_minor_color)
mb.addLine(Vector(-x, min_h, min_d), Vector(-x, min_h, max_d), color = self._grid_minor_color)
for y in range(0, int(math.ceil(max_d)), MINOR_GRID_SIZE):
if y % MAJOR_GRID_SIZE == 0:
pass
mb.addLine(Vector(min_w, min_h, y), Vector(max_w, min_h, y), color = self._grid_minor_color)
mb.addLine(Vector(min_w, min_h, -y), Vector(max_w, min_h, -y), color = self._grid_minor_color)
self._grid_mesh = mb.build() self._grid_mesh = mb.build()
else: else:
@ -344,7 +314,7 @@ class BuildVolume(SceneNode):
mb.addArc(max_w, Vector.Unit_Y, center = (0, max_h, 0), color = self._volume_outline_color) mb.addArc(max_w, Vector.Unit_Y, center = (0, max_h, 0), color = self._volume_outline_color)
self.setMeshData(mb.build().getTransformed(scale_matrix)) self.setMeshData(mb.build().getTransformed(scale_matrix))
# Build plate surface. # Build plate grid mesh
mb = MeshBuilder() mb = MeshBuilder()
mb.addVertex(0, min_h - z_fight_distance, 0) mb.addVertex(0, min_h - z_fight_distance, 0)
mb.addArc(max_w, Vector.Unit_Y, center = Vector(0, min_h - z_fight_distance, 0)) mb.addArc(max_w, Vector.Unit_Y, center = Vector(0, min_h - z_fight_distance, 0))
@ -358,40 +328,7 @@ class BuildVolume(SceneNode):
for n in range(0, mb.getVertexCount()): for n in range(0, mb.getVertexCount()):
v = mb.getVertex(n) v = mb.getVertex(n)
mb.setVertexUVCoordinates(n, v[0], v[2] * aspect) mb.setVertexUVCoordinates(n, v[0], v[2] * aspect)
self._plate_mesh = mb.build().getTransformed(scale_matrix) self._grid_mesh = mb.build().getTransformed(scale_matrix)
#Build plate grid mesh.
#We need to constrain the length of the lines to the build plate ellipsis. Time to get out the calculator!
mb = MeshBuilder()
for x in range(0, int(math.ceil(max_w)), MAJOR_GRID_SIZE):
#x / max_w is the fraction along the build plate we have progressed, counting from the centre.
#So x / max_w is sin(a), where a is the angle towards an endpoint of the grid line from the centre.
#So math.asin(x / max_w) is a.
#So math.cos(math.asin(x / max_w)) is half of the length of the grid line on a unit circle, which scales between 0 and 1.
length_factor = math.cos(math.asin(x / max_w))
mb.addLine(Vector(x, min_h, min_d * length_factor), Vector(x, min_h, max_d * length_factor), color = self._grid_color)
#Start from 0 in both cases, so you need to do this in two for loops.
mb.addLine(Vector(-x, min_h, min_d * length_factor), Vector(-x, min_h, max_d * length_factor), color = self._grid_color)
for y in range(0, int(math.ceil(max_d)), MAJOR_GRID_SIZE):
length_factor = math.sin(math.acos(y / max_d))
mb.addLine(Vector(min_w * length_factor, min_h, y), Vector(max_w * length_factor, min_h, y), color = self._grid_color)
mb.addLine(Vector(min_w * length_factor, min_h, -y), Vector(max_w * length_factor, min_h, -y), color = self._grid_color)
#More fine grained grid.
for x in range(0, int(math.ceil(max_w)), MINOR_GRID_SIZE):
if x % MAJOR_GRID_SIZE == 0: #Don't overlap with the major grid.
pass
length_factor = math.cos(math.asin(x / max_w))
mb.addLine(Vector(x, min_h, min_d * length_factor), Vector(x, min_h, max_d * length_factor), color = self._grid_minor_color)
mb.addLine(Vector(-x, min_h, min_d * length_factor), Vector(-x, min_h, max_d * length_factor), color = self._grid_minor_color)
for y in range(0, int(math.ceil(max_d)), MINOR_GRID_SIZE):
if y % MAJOR_GRID_SIZE == 0:
pass
length_factor = math.sin(math.acos(y / max_d))
mb.addLine(Vector(min_w * length_factor, min_h, y), Vector(max_w * length_factor, min_h, y), color = self._grid_minor_color)
mb.addLine(Vector(min_w * length_factor, min_h, -y), Vector(max_w * length_factor, min_h, -y), color = self._grid_minor_color)
self._grid_mesh = mb.build()
# Indication of the machine origin # Indication of the machine origin
if self._global_container_stack.getProperty("machine_center_is_zero", "value"): if self._global_container_stack.getProperty("machine_center_is_zero", "value"):

View File

@ -104,7 +104,7 @@ class CuraApplication(QtApplication):
# SettingVersion represents the set of settings available in the machine/extruder definitions. # SettingVersion represents the set of settings available in the machine/extruder definitions.
# You need to make sure that this version number needs to be increased if there is any non-backwards-compatible # You need to make sure that this version number needs to be increased if there is any non-backwards-compatible
# changes of the settings. # changes of the settings.
SettingVersion = 2 SettingVersion = 3
class ResourceTypes: class ResourceTypes:
QmlFiles = Resources.UserType + 1 QmlFiles = Resources.UserType + 1
@ -488,7 +488,7 @@ class CuraApplication(QtApplication):
f.write(data) f.write(data)
@pyqtSlot(str, result=QUrl) @pyqtSlot(str, result = QUrl)
def getDefaultPath(self, key): def getDefaultPath(self, key):
default_path = Preferences.getInstance().getValue("local_file/%s" % key) default_path = Preferences.getInstance().getValue("local_file/%s" % key)
return QUrl.fromLocalFile(default_path) return QUrl.fromLocalFile(default_path)
@ -1128,7 +1128,7 @@ class CuraApplication(QtApplication):
expandedCategoriesChanged = pyqtSignal() expandedCategoriesChanged = pyqtSignal()
@pyqtProperty("QStringList", notify=expandedCategoriesChanged) @pyqtProperty("QStringList", notify = expandedCategoriesChanged)
def expandedCategories(self): def expandedCategories(self):
return Preferences.getInstance().getValue("cura/categories_expanded").split(";") return Preferences.getInstance().getValue("cura/categories_expanded").split(";")
@ -1182,6 +1182,7 @@ class CuraApplication(QtApplication):
group_node = SceneNode() group_node = SceneNode()
group_decorator = GroupDecorator() group_decorator = GroupDecorator()
group_node.addDecorator(group_decorator) group_node.addDecorator(group_decorator)
group_node.addDecorator(ConvexHullDecorator())
group_node.setParent(self.getController().getScene().getRoot()) group_node.setParent(self.getController().getScene().getRoot())
group_node.setSelectable(True) group_node.setSelectable(True)
center = Selection.getSelectionCenter() center = Selection.getSelectionCenter()
@ -1292,7 +1293,7 @@ class CuraApplication(QtApplication):
message = Message( message = Message(
self._i18n_catalog.i18nc("@info:status", self._i18n_catalog.i18nc("@info:status",
"Only one G-code file can be loaded at a time. Skipped importing {0}", "Only one G-code file can be loaded at a time. Skipped importing {0}",
filename)) filename), title = self._i18n_catalog.i18nc("@info:title", "Warning"))
message.show() message.show()
return return
# If file being loaded is non-slicable file, then prevent loading of any other files # If file being loaded is non-slicable file, then prevent loading of any other files
@ -1301,7 +1302,7 @@ class CuraApplication(QtApplication):
message = Message( message = Message(
self._i18n_catalog.i18nc("@info:status", self._i18n_catalog.i18nc("@info:status",
"Can't open any other file if G-code is loading. Skipped importing {0}", "Can't open any other file if G-code is loading. Skipped importing {0}",
filename)) filename), title = self._i18n_catalog.i18nc("@info:title", "Error"))
message.show() message.show()
return return

View File

@ -1,38 +1,117 @@
# Copyright (c) 2015 Ultimaker B.V. # Copyright (c) 2017 Ultimaker B.V.
# Uranium is released under the terms of the AGPLv3 or higher. # Uranium is released under the terms of the AGPLv3 or higher.
from threading import Thread, Event
import time
from PyQt5.QtCore import Qt, QCoreApplication from PyQt5.QtCore import Qt, QCoreApplication
from PyQt5.QtGui import QPixmap, QColor, QFont, QFontMetrics from PyQt5.QtGui import QPixmap, QColor, QFont, QFontMetrics, QImage, QPen
from PyQt5.QtWidgets import QSplashScreen from PyQt5.QtWidgets import QSplashScreen
from UM.Resources import Resources from UM.Resources import Resources
from UM.Application import Application from UM.Application import Application
class CuraSplashScreen(QSplashScreen): class CuraSplashScreen(QSplashScreen):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._scale = round(QFontMetrics(QCoreApplication.instance().font()).ascent() / 12) self._scale = 0.7
splash_image = QPixmap(Resources.getPath(Resources.Images, "cura.png")) splash_image = QPixmap(Resources.getPath(Resources.Images, "cura.png"))
self.setPixmap(splash_image.scaled(splash_image.size() * self._scale)) self.setPixmap(splash_image)
self._current_message = ""
self._loading_image = QImage(Resources.getPath(Resources.Images, "loading.png"))
self._loading_image = self._loading_image.scaled(30, 30, Qt.KeepAspectRatio)
self._loading_image_rotation_angle = 0
self._to_stop = False
self._loading_tick_thread = LoadingTickThread(self)
def show(self):
super().show()
self._loading_tick_thread.start()
def updateLoadingImage(self):
if self._to_stop:
return
self._loading_image_rotation_angle -= 10
self.repaint()
def drawContents(self, painter): def drawContents(self, painter):
if self._to_stop:
return
painter.save() painter.save()
painter.setPen(QColor(0, 0, 0, 255)) painter.setPen(QColor(255, 255, 255, 255))
version = Application.getInstance().getVersion().split("-") version = Application.getInstance().getVersion().split("-")
buildtype = Application.getInstance().getBuildType() buildtype = Application.getInstance().getBuildType()
if buildtype: if buildtype:
version[0] += " (%s)" %(buildtype) version[0] += " (%s)" % buildtype
font = QFont() # Using system-default font here # draw version text
font.setPointSize(20) font = QFont() # Using system-default font here
font.setPointSize(34)
painter.setFont(font) painter.setFont(font)
painter.drawText(0, 0, 330 * self._scale, 230 * self._scale, Qt.AlignHCenter | Qt.AlignBottom, version[0]) painter.drawText(275, 87, 330 * self._scale, 230 * self._scale, Qt.AlignLeft | Qt.AlignBottom, version[0])
if len(version) > 1: if len(version) > 1:
font.setPointSize(12) font.setPointSize(12)
painter.setFont(font) painter.setFont(font)
painter.drawText(0, 0, 330 * self._scale, 255 * self._scale, Qt.AlignHCenter | Qt.AlignBottom, version[1]) painter.drawText(320, 82, 330 * self._scale, 255 * self._scale, Qt.AlignLeft | Qt.AlignBottom, version[1])
# draw the loading image
pen = QPen()
pen.setWidth(4 * self._scale)
pen.setColor(QColor(255, 255, 255, 255))
painter.setPen(pen)
painter.drawArc(130, 380, 32 * self._scale, 32 * self._scale, self._loading_image_rotation_angle * 16, 300 * 16)
# draw message text
if self._current_message:
font = QFont() # Using system-default font here
font.setPointSize(16)
painter.setFont(font)
painter.drawText(180, 243, 330 * self._scale, 230 * self._scale, Qt.AlignLeft | Qt.AlignBottom,
self._current_message)
painter.restore() painter.restore()
super().drawContents(painter) super().drawContents(painter)
def showMessage(self, message, *args, **kwargs):
if self._to_stop:
return
self._current_message = message
self.messageChanged.emit(message)
self.repaint()
def close(self):
# set stop flags
self._to_stop = True
self._loading_tick_thread.setToStop()
super().close()
class LoadingTickThread(Thread):
def __init__(self, splash):
super().__init__(daemon = True)
self._splash = splash
self._to_stop = False
self._time_interval = 0.05
self._event = Event()
def setToStop(self):
self._to_stop = True
self._event.set()
def run(self):
while not self._to_stop:
self._event.wait(self._time_interval)
if self._event.is_set():
break
self._splash.updateLoadingImage()

View File

@ -32,7 +32,7 @@ class MultiplyObjectsJob(Job):
def run(self): def run(self):
status_message = Message(i18n_catalog.i18nc("@info:status", "Multiplying and placing objects"), lifetime=0, status_message = Message(i18n_catalog.i18nc("@info:status", "Multiplying and placing objects"), lifetime=0,
dismissable=False, progress=0) dismissable=False, progress=0, title = i18n_catalog.i18nc("@info:title", "Placing Object"))
status_message.show() status_message.show()
scene = Application.getInstance().getController().getScene() scene = Application.getInstance().getController().getScene()
@ -80,5 +80,5 @@ class MultiplyObjectsJob(Job):
status_message.hide() status_message.hide()
if not found_solution_for_all: if not found_solution_for_all:
no_full_solution_message = Message(i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects")) no_full_solution_message = Message(i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects"), title = i18n_catalog.i18nc("@info:title", "Placing Object"))
no_full_solution_message.show() no_full_solution_message.show()

View File

@ -80,7 +80,7 @@ class PrintInformation(QObject):
self._abbr_machine = "" self._abbr_machine = ""
self._job_name = "" self._job_name = ""
Application.getInstance().globalContainerStackChanged.connect(self._setAbbreviatedMachineName) Application.getInstance().globalContainerStackChanged.connect(self._updateJobName)
Application.getInstance().fileLoaded.connect(self.setBaseName) Application.getInstance().fileLoaded.connect(self.setBaseName)
Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged) Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged)

View File

@ -140,15 +140,20 @@ class CuraContainerRegistry(ContainerRegistry):
success = profile_writer.write(file_name, found_containers) success = profile_writer.write(file_name, found_containers)
except Exception as e: except Exception as e:
Logger.log("e", "Failed to export profile to %s: %s", file_name, str(e)) Logger.log("e", "Failed to export profile to %s: %s", file_name, str(e))
m = Message(catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Failed to export profile to <filename>{0}</filename>: <message>{1}</message>", file_name, str(e)), lifetime = 0) m = Message(catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Failed to export profile to <filename>{0}</filename>: <message>{1}</message>", file_name, str(e)),
lifetime = 0,
title = catalog.i18nc("@info:title", "Error"))
m.show() m.show()
return return
if not success: if not success:
Logger.log("w", "Failed to export profile to %s: Writer plugin reported failure.", file_name) Logger.log("w", "Failed to export profile to %s: Writer plugin reported failure.", file_name)
m = Message(catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Failed to export profile to <filename>{0}</filename>: Writer plugin reported failure.", file_name), lifetime = 0) m = Message(catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Failed to export profile to <filename>{0}</filename>: Writer plugin reported failure.", file_name),
lifetime = 0,
title = catalog.i18nc("@info:title", "Error"))
m.show() m.show()
return return
m = Message(catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Exported profile to <filename>{0}</filename>", file_name)) m = Message(catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Exported profile to <filename>{0}</filename>", file_name),
title = catalog.i18nc("@info:title", "Export Details"))
m.show() m.show()
## Gets the plugin object matching the criteria ## Gets the plugin object matching the criteria

View File

@ -105,7 +105,8 @@ class MachineManager(QObject):
self._auto_hotends_changed = {} self._auto_hotends_changed = {}
self._material_incompatible_message = Message(catalog.i18nc("@info:status", self._material_incompatible_message = Message(catalog.i18nc("@info:status",
"The selected material is incompatible with the selected machine or configuration.")) "The selected material is incompatible with the selected machine or configuration."),
title = catalog.i18nc("@info:title", "Incompatible Material"))
globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value) globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value)
activeMaterialChanged = pyqtSignal() activeMaterialChanged = pyqtSignal()

View File

@ -21,7 +21,7 @@ class MaterialManager(QObject):
#Material diameter changed warning message. #Material diameter changed warning message.
self._material_diameter_warning_message = Message(catalog.i18nc("@info:status Has a cancel button next to it.", self._material_diameter_warning_message = Message(catalog.i18nc("@info:status Has a cancel button next to it.",
"The selected material diameter causes the material to become incompatible with the current printer.")) "The selected material diameter causes the material to become incompatible with the current printer."), title = catalog.i18nc("@info:title", "Incompatible Material"))
self._material_diameter_warning_message.addAction("Undo", catalog.i18nc("@action:button", "Undo"), None, catalog.i18nc("@action", "Undo changing the material diameter.")) self._material_diameter_warning_message.addAction("Undo", catalog.i18nc("@action:button", "Undo"), None, catalog.i18nc("@action", "Undo changing the material diameter."))
self._material_diameter_warning_message.actionTriggered.connect(self._materialWarningMessageAction) self._material_diameter_warning_message.actionTriggered.connect(self._materialWarningMessageAction)

View File

@ -278,7 +278,7 @@ class CuraEngineBackend(QObject, Backend):
if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible: if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible:
if Application.getInstance().platformActivity: if Application.getInstance().platformActivity:
self._error_message = Message(catalog.i18nc("@info:status", self._error_message = Message(catalog.i18nc("@info:status",
"The selected material is incompatible with the selected machine or configuration.")) "The selected material is incompatible with the selected machine or configuration."), title = catalog.i18nc("@info:title", "Material Details"))
self._error_message.show() self._error_message.show()
self.backendStateChange.emit(BackendState.Error) self.backendStateChange.emit(BackendState.Error)
else: else:
@ -305,7 +305,8 @@ class CuraEngineBackend(QObject, Backend):
error_labels.add(definitions[0].label) error_labels.add(definitions[0].label)
error_labels = ", ".join(error_labels) error_labels = ", ".join(error_labels)
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. The following settings have errors: {0}".format(error_labels))) self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. The following settings have errors: {0}".format(error_labels)),
title = catalog.i18nc("@info:title", "Setting Details"))
self._error_message.show() self._error_message.show()
self.backendStateChange.emit(BackendState.Error) self.backendStateChange.emit(BackendState.Error)
else: else:
@ -314,7 +315,8 @@ class CuraEngineBackend(QObject, Backend):
if job.getResult() == StartSliceJob.StartJobResult.BuildPlateError: if job.getResult() == StartSliceJob.StartJobResult.BuildPlateError:
if Application.getInstance().platformActivity: if Application.getInstance().platformActivity:
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice because the prime tower or prime position(s) are invalid.")) self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice because the prime tower or prime position(s) are invalid."),
title = catalog.i18nc("@info:title", "Invalid position"))
self._error_message.show() self._error_message.show()
self.backendStateChange.emit(BackendState.Error) self.backendStateChange.emit(BackendState.Error)
else: else:
@ -322,7 +324,8 @@ class CuraEngineBackend(QObject, Backend):
if job.getResult() == StartSliceJob.StartJobResult.NothingToSlice: if job.getResult() == StartSliceJob.StartJobResult.NothingToSlice:
if Application.getInstance().platformActivity: if Application.getInstance().platformActivity:
self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit.")) self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."),
title = catalog.i18nc("@info:title", "Warning"))
self._error_message.show() self._error_message.show()
self.backendStateChange.emit(BackendState.Error) self.backendStateChange.emit(BackendState.Error)
else: else:

View File

@ -235,7 +235,7 @@ class ProcessSlicedLayersJob(Job):
if self.isRunning(): if self.isRunning():
if Application.getInstance().getController().getActiveView().getPluginId() == "LayerView": if Application.getInstance().getController().getActiveView().getPluginId() == "LayerView":
if not self._progress: if not self._progress:
self._progress = Message(catalog.i18nc("@info:status", "Processing Layers"), 0, False, 0) self._progress = Message(catalog.i18nc("@info:status", "Processing Layers"), 0, False, 0, catalog.i18nc("@info:title", "Information"))
if self._progress.getProgress() != 100: if self._progress.getProgress() != 100:
self._progress.show() self._progress.show()
else: else:

View File

@ -319,18 +319,22 @@ class StartSliceJob(Job):
# \param message object_lists message to put the per object settings in # \param message object_lists message to put the per object settings in
def _handlePerObjectSettings(self, node, message): def _handlePerObjectSettings(self, node, message):
stack = node.callDecoration("getStack") stack = node.callDecoration("getStack")
if not stack: # Check if the node has a stack attached to it and the stack has any settings in the top container.
# Check if the node has a stack attached to it and the stack has any settings in the top container.
if not stack:
return return
# Check all settings for relations, so we can also calculate the correct values for dependent settings. # Check all settings for relations, so we can also calculate the correct values for dependent settings.
top_of_stack = stack.getTop() #Cache for efficiency. top_of_stack = stack.getTop() # Cache for efficiency.
changed_setting_keys = set(top_of_stack.getAllKeys()) changed_setting_keys = set(top_of_stack.getAllKeys())
# Add all relations to changed settings as well.
for key in top_of_stack.getAllKeys(): for key in top_of_stack.getAllKeys():
instance = top_of_stack.getInstance(key) instance = top_of_stack.getInstance(key)
self._addRelations(changed_setting_keys, instance.definition.relations) self._addRelations(changed_setting_keys, instance.definition.relations)
Job.yieldThread() Job.yieldThread()
# Ensure that the engine is aware what the build extruder is # Ensure that the engine is aware what the build extruder is.
if stack.getProperty("machine_extruder_count", "value") > 1: if stack.getProperty("machine_extruder_count", "value") > 1:
changed_setting_keys.add("extruder_nr") changed_setting_keys.add("extruder_nr")
@ -339,14 +343,18 @@ class StartSliceJob(Job):
setting = message.addRepeatedMessage("settings") setting = message.addRepeatedMessage("settings")
setting.name = key setting.name = key
extruder = int(round(float(stack.getProperty(key, "limit_to_extruder")))) extruder = int(round(float(stack.getProperty(key, "limit_to_extruder"))))
if extruder >= 0 and key not in top_of_stack.getAllKeys(): #Limited to a specific extruder, but not overridden by per-object settings.
# Check if limited to a specific extruder, but not overridden by per-object settings.
if extruder >= 0 and key not in changed_setting_keys:
limited_stack = ExtruderManager.getInstance().getActiveExtruderStacks()[extruder] limited_stack = ExtruderManager.getInstance().getActiveExtruderStacks()[extruder]
else: else:
limited_stack = stack #Just take from the per-object settings itself. limited_stack = stack
setting.value = str(limited_stack.getProperty(key, "value")).encode("utf-8") setting.value = str(limited_stack.getProperty(key, "value")).encode("utf-8")
Job.yieldThread() Job.yieldThread()
## Recursive function to put all settings that require eachother for value changes in a list ## Recursive function to put all settings that require each other for value changes in a list
# \param relations_set \type{set} Set of keys (strings) of settings that are influenced # \param relations_set \type{set} Set of keys (strings) of settings that are influenced
# \param relations list of relation objects that need to be checked. # \param relations list of relation objects that need to be checked.
def _addRelations(self, relations_set, relations): def _addRelations(self, relations_set, relations):

View File

@ -251,7 +251,10 @@ class GCodeReader(MeshReader):
self._clearValues() self._clearValues()
self._message = Message(catalog.i18nc("@info:status", "Parsing G-code"), lifetime=0) self._message = Message(catalog.i18nc("@info:status", "Parsing G-code"),
lifetime=0,
title = catalog.i18nc("@info:title", "G-code Details"))
self._message.setProgress(0) self._message.setProgress(0)
self._message.show() self._message.show()
@ -362,7 +365,9 @@ class GCodeReader(MeshReader):
if Preferences.getInstance().getValue("gcodereader/show_caution"): if Preferences.getInstance().getValue("gcodereader/show_caution"):
caution_message = Message(catalog.i18nc( caution_message = Message(catalog.i18nc(
"@info:generic", "@info:generic",
"Make sure the g-code is suitable for your printer and printer configuration before sending the file to it. The g-code representation may not be accurate."), lifetime=0) "Make sure the g-code is suitable for your printer and printer configuration before sending the file to it. The g-code representation may not be accurate."),
lifetime=0,
title = catalog.i18nc("@info:title", "G-code Details"))
caution_message.show() caution_message.show()
# The "save/print" button's state is bound to the backend state. # The "save/print" button's state is bound to the backend state.

View File

@ -90,7 +90,8 @@ class LayerView(View):
self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers")) self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers"))
self._compatibility_mode = True # for safety self._compatibility_mode = True # for safety
self._wireprint_warning_message = Message(catalog.i18nc("@info:status", "Cura does not accurately display layers when Wire Printing is enabled")) self._wireprint_warning_message = Message(catalog.i18nc("@info:status", "Cura does not accurately display layers when Wire Printing is enabled"),
title = catalog.i18nc("@info:title", "Layer View"))
def _resetSettings(self): def _resetSettings(self):
self._layer_view_type = 0 # 0 is material color, 1 is color by linetype, 2 is speed self._layer_view_type = 0 # 0 is material color, 1 is color by linetype, 2 is speed

View File

@ -22,18 +22,23 @@ Item
height: { height: {
if (UM.LayerView.compatibilityMode) { if (UM.LayerView.compatibilityMode) {
return UM.Theme.getSize("layerview_menu_size_compatibility").height; return UM.Theme.getSize("layerview_menu_size_compatibility").height;
} else if (UM.Preferences.getValue("layerview/layer_view_type") == 0) {
return UM.Theme.getSize("layerview_menu_size_material_color_mode").height + UM.LayerView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height)
} else { } else {
return UM.Theme.getSize("layerview_menu_size").height + UM.LayerView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height) return UM.Theme.getSize("layerview_menu_size").height + UM.LayerView.extruderCount * (UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("layerview_row_spacing").height)
} }
} }
property var buttonTarget: { property var buttonTarget: {
var force_binding = parent.y; // ensure this gets reevaluated when the panel moves var force_binding = parent.y; // ensure this gets reevaluated when the panel moves
return base.mapFromItem(parent.parent, parent.buttonTarget.x, parent.buttonTarget.y); return base.mapFromItem(parent.parent, parent.buttonTarget.x, parent.buttonTarget.y);
} }
visible: !parent.parent.monitoringPrint
UM.PointingRectangle { UM.PointingRectangle {
id: layerViewMenu id: layerViewMenu
anchors.left: parent.left anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
width: parent.width width: parent.width
height: parent.height height: parent.height
@ -41,9 +46,7 @@ Item
color: UM.Theme.getColor("tool_panel_background") color: UM.Theme.getColor("tool_panel_background")
borderWidth: UM.Theme.getSize("default_lining").width borderWidth: UM.Theme.getSize("default_lining").width
borderColor: UM.Theme.getColor("lining") borderColor: UM.Theme.getColor("lining")
arrowSize: 0 // hide arrow until weird issue with first time rendering is fixed
target: parent.buttonTarget
arrowSize: UM.Theme.getSize("default_arrow").width
ColumnLayout { ColumnLayout {
id: view_settings id: view_settings
@ -64,26 +67,7 @@ Item
anchors.leftMargin: UM.Theme.getSize("default_margin").width anchors.leftMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("layerview_row_spacing").height spacing: UM.Theme.getSize("layerview_row_spacing").height
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2 anchors.rightMargin: UM.Theme.getSize("default_margin").width
Label
{
id: layersLabel
anchors.left: parent.left
text: catalog.i18nc("@label","View Mode: Layers")
font: UM.Theme.getFont("default_bold");
color: UM.Theme.getColor("setting_control_text")
Layout.fillWidth: true
elide: Text.ElideMiddle;
}
Label
{
id: spaceLabel
anchors.left: parent.left
text: " "
font.pointSize: 0.5
}
Label Label
{ {
@ -199,6 +183,7 @@ Item
width: UM.Theme.getSize("layerview_legend_size").width width: UM.Theme.getSize("layerview_legend_size").width
height: UM.Theme.getSize("layerview_legend_size").height height: UM.Theme.getSize("layerview_legend_size").height
color: model.color color: model.color
radius: width / 2
border.width: UM.Theme.getSize("default_lining").width border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining") border.color: UM.Theme.getColor("lining")
visible: !view_settings.show_legend visible: !view_settings.show_legend
@ -211,7 +196,7 @@ Item
{ {
text: model.name text: model.name
elide: Text.ElideRight elide: Text.ElideRight
color: UM.Theme.getColor("button_text") color: UM.Theme.getColor("setting_control_text")
font: UM.Theme.getFont("default") font: UM.Theme.getFont("default")
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.left: extrudersModelCheckBox.left; anchors.left: extrudersModelCheckBox.left;
@ -280,7 +265,7 @@ Item
text: label text: label
font: UM.Theme.getFont("default") font: UM.Theme.getFont("default")
elide: Text.ElideRight elide: Text.ElideRight
color: UM.Theme.getColor("button_text") color: UM.Theme.getColor("setting_control_text")
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.left: legendModelCheckBox.left; anchors.left: legendModelCheckBox.left;
anchors.right: legendModelCheckBox.right; anchors.right: legendModelCheckBox.right;
@ -343,7 +328,7 @@ Item
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height Layout.preferredHeight: UM.Theme.getSize("layerview_row").height + UM.Theme.getSize("default_lining").height
Layout.preferredWidth: UM.Theme.getSize("layerview_row").width Layout.preferredWidth: UM.Theme.getSize("layerview_row").width
color: UM.Theme.getColor("button_text") color: UM.Theme.getColor("setting_control_text")
font: UM.Theme.getFont("default") font: UM.Theme.getFont("default")
} }
} }
@ -354,7 +339,7 @@ Item
id: slider id: slider
width: handleSize width: handleSize
height: parent.height - 2*UM.Theme.getSize("slider_layerview_margin").height height: parent.height - 2*UM.Theme.getSize("slider_layerview_margin").height
anchors.top: parent.top anchors.top: parent.bottom
anchors.topMargin: UM.Theme.getSize("slider_layerview_margin").height anchors.topMargin: UM.Theme.getSize("slider_layerview_margin").height
anchors.right: layerViewMenu.right anchors.right: layerViewMenu.right
anchors.rightMargin: UM.Theme.getSize("slider_layerview_margin").width anchors.rightMargin: UM.Theme.getSize("slider_layerview_margin").width
@ -364,7 +349,7 @@ Item
property real minimumRangeHandleSize: UM.Theme.getSize("slider_handle").width / 2 property real minimumRangeHandleSize: UM.Theme.getSize("slider_handle").width / 2
property real trackThickness: UM.Theme.getSize("slider_groove").width property real trackThickness: UM.Theme.getSize("slider_groove").width
property real trackRadius: trackThickness / 2 property real trackRadius: trackThickness / 2
property real trackBorderWidth: UM.Theme.getSize("default_lining").width property real trackBorderWidth: UM.Theme.getSize("default_lining").width / 2
property color upperHandleColor: UM.Theme.getColor("slider_handle") property color upperHandleColor: UM.Theme.getColor("slider_handle")
property color lowerHandleColor: UM.Theme.getColor("slider_handle") property color lowerHandleColor: UM.Theme.getColor("slider_handle")
property color rangeHandleColor: UM.Theme.getColor("slider_groove_fill") property color rangeHandleColor: UM.Theme.getColor("slider_groove_fill")
@ -434,6 +419,7 @@ Item
color: parent.trackColor color: parent.trackColor
border.width: parent.trackBorderWidth; border.width: parent.trackBorderWidth;
border.color: parent.trackBorderColor; border.color: parent.trackBorderColor;
visible: slider.layersVisible
} }
Item { Item {
@ -492,8 +478,8 @@ Item
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
radius: parent.handleRadius radius: parent.handleRadius
color: parent.upperHandleColor color: parent.upperHandleColor
border.width: UM.Theme.getSize("default_lining").width //border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("slider_handle_border") //border.color: UM.Theme.getColor("slider_handle_border")
visible: slider.layersVisible visible: slider.layersVisible
@ -568,10 +554,10 @@ Item
UM.PointingRectangle UM.PointingRectangle
{ {
x: parent.width + UM.Theme.getSize("slider_layerview_background").width / 2; x: parent.width - UM.Theme.getSize("slider_layerview_background").width / 2 - width;
y: Math.floor(slider.activeHandle.y + slider.activeHandle.height / 2 - height / 2); y: Math.floor(slider.activeHandle.y + slider.activeHandle.height / 2 - height / 2);
target: Qt.point(0, slider.activeHandle.y + slider.activeHandle.height / 2) target: Qt.point(parent.width, slider.activeHandle.y + slider.activeHandle.height / 2)
arrowSize: UM.Theme.getSize("default_arrow").width arrowSize: UM.Theme.getSize("default_arrow").width
height: UM.Theme.getSize("slider_handle").height + UM.Theme.getSize("default_margin").height height: UM.Theme.getSize("slider_handle").height + UM.Theme.getSize("default_margin").height

View File

@ -10,7 +10,7 @@ catalog = i18nCatalog("cura")
def getMetaData(): def getMetaData():
return { return {
"view": { "view": {
"name": catalog.i18nc("@item:inlistbox", "Layers"), "name": catalog.i18nc("@item:inlistbox", "Layer view"),
"view_panel": "LayerView.qml", "view_panel": "LayerView.qml",
"weight": 2 "weight": 2
} }

View File

@ -161,7 +161,8 @@ class PluginBrowser(QObject, Extension):
if plugin_id is None: if plugin_id is None:
msg = i18n_catalog.i18nc("@info:status", "Failed to get plugin ID from <filename>{0}</filename>", file_path) msg = i18n_catalog.i18nc("@info:status", "Failed to get plugin ID from <filename>{0}</filename>", file_path)
self._progress_message = Message(msg, lifetime=0, dismissable=False) msg_title = i18n_catalog.i18nc("@info:tile", "Warning")
self._progress_message = Message(msg, lifetime=0, dismissable=False, title = msg_title)
return return
# find a potential license file # find a potential license file

View File

@ -86,7 +86,7 @@ class RemovableDriveOutputDevice(OutputDevice):
job.progress.connect(self._onProgress) job.progress.connect(self._onProgress)
job.finished.connect(self._onFinished) job.finished.connect(self._onFinished)
message = Message(catalog.i18nc("@info:progress Don't translate the XML tags <filename>!", "Saving to Removable Drive <filename>{0}</filename>").format(self.getName()), 0, False, -1) message = Message(catalog.i18nc("@info:progress Don't translate the XML tags <filename>!", "Saving to Removable Drive <filename>{0}</filename>").format(self.getName()), 0, False, -1, catalog.i18nc("@info:title", "Saving"))
message.show() message.show()
self.writeStarted.emit(self) self.writeStarted.emit(self)
@ -128,9 +128,8 @@ class RemovableDriveOutputDevice(OutputDevice):
self._stream = None self._stream = None
except: except:
Logger.logException("w", "An execption occured while trying to write to removable drive.") Logger.logException("w", "An execption occured while trying to write to removable drive.")
message = Message(catalog.i18nc("@info:status", "Could not save to removable drive {0}: {1}").format(self.getName(), message = Message(catalog.i18nc("@info:status", "Could not save to removable drive {0}: {1}").format(self.getName(),str(job.getError())),
str( title = catalog.i18nc("@info:title", "Error"))
job.getError())))
message.show() message.show()
self.writeError.emit(self) self.writeError.emit(self)
return return
@ -138,13 +137,13 @@ class RemovableDriveOutputDevice(OutputDevice):
self._writing = False self._writing = False
self.writeFinished.emit(self) self.writeFinished.emit(self)
if job.getResult(): if job.getResult():
message = Message(catalog.i18nc("@info:status", "Saved to Removable Drive {0} as {1}").format(self.getName(), os.path.basename(job.getFileName()))) message = Message(catalog.i18nc("@info:status", "Saved to Removable Drive {0} as {1}").format(self.getName(), os.path.basename(job.getFileName())), title = catalog.i18nc("@info:title", "File Saved"))
message.addAction("eject", catalog.i18nc("@action:button", "Eject"), "eject", catalog.i18nc("@action", "Eject removable device {0}").format(self.getName())) message.addAction("eject", catalog.i18nc("@action:button", "Eject"), "eject", catalog.i18nc("@action", "Eject removable device {0}").format(self.getName()))
message.actionTriggered.connect(self._onActionTriggered) message.actionTriggered.connect(self._onActionTriggered)
message.show() message.show()
self.writeSuccess.emit(self) self.writeSuccess.emit(self)
else: else:
message = Message(catalog.i18nc("@info:status", "Could not save to removable drive {0}: {1}").format(self.getName(), str(job.getError()))) message = Message(catalog.i18nc("@info:status", "Could not save to removable drive {0}: {1}").format(self.getName(), str(job.getError())), title = catalog.i18nc("@info:title", "Warning"))
message.show() message.show()
self.writeError.emit(self) self.writeError.emit(self)
job.getStream().close() job.getStream().close()
@ -154,7 +153,7 @@ class RemovableDriveOutputDevice(OutputDevice):
if Application.getInstance().getOutputDeviceManager().getOutputDevicePlugin("RemovableDriveOutputDevice").ejectDevice(self): if Application.getInstance().getOutputDeviceManager().getOutputDevicePlugin("RemovableDriveOutputDevice").ejectDevice(self):
message.hide() message.hide()
eject_message = Message(catalog.i18nc("@info:status", "Ejected {0}. You can now safely remove the drive.").format(self.getName())) eject_message = Message(catalog.i18nc("@info:status", "Ejected {0}. You can now safely remove the drive.").format(self.getName()), title = catalog.i18nc("@info:title", "Safely Remove Hardware"))
else: else:
eject_message = Message(catalog.i18nc("@info:status", "Failed to eject {0}. Another program may be using the drive.").format(self.getName())) eject_message = Message(catalog.i18nc("@info:status", "Failed to eject {0}. Another program may be using the drive.").format(self.getName()), title = catalog.i18nc("@info:title", "Warning"))
eject_message.show() eject_message.show()

View File

@ -40,7 +40,11 @@ class SliceInfo(Extension):
Preferences.getInstance().addPreference("info/asked_send_slice_info", False) Preferences.getInstance().addPreference("info/asked_send_slice_info", False)
if not Preferences.getInstance().getValue("info/asked_send_slice_info"): if not Preferences.getInstance().getValue("info/asked_send_slice_info"):
self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymised slicing statistics. You can disable this in the preferences."), lifetime = 0, dismissable = False) self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymised slicing statistics. You can disable this in the preferences."),
lifetime = 0,
dismissable = False,
title = catalog.i18nc("@info:title", "Collecting Data"))
self.send_slice_info_message.addAction("Dismiss", catalog.i18nc("@action:button", "Dismiss"), None, "") self.send_slice_info_message.addAction("Dismiss", catalog.i18nc("@action:button", "Dismiss"), None, "")
self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered) self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered)
self.send_slice_info_message.show() self.send_slice_info_message.show()

View File

@ -9,7 +9,7 @@ i18n_catalog = i18nCatalog("cura")
def getMetaData(): def getMetaData():
return { return {
"view": { "view": {
"name": i18n_catalog.i18nc("@item:inmenu", "Solid"), "name": i18n_catalog.i18nc("@item:inmenu", "Solid view"),
"weight": 0 "weight": 0
} }
} }

View File

@ -154,12 +154,12 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
self._authentication_id = None self._authentication_id = None
self._authentication_key = None self._authentication_key = None
self._authentication_requested_message = Message(i18n_catalog.i18nc("@info:status", "Access to the printer requested. Please approve the request on the printer"), lifetime = 0, dismissable = False, progress = 0) self._authentication_requested_message = Message(i18n_catalog.i18nc("@info:status", "Access to the printer requested. Please approve the request on the printer"), lifetime = 0, dismissable = False, progress = 0, title = i18n_catalog.i18nc("@info:title", "Connection status"))
self._authentication_failed_message = Message(i18n_catalog.i18nc("@info:status", "")) self._authentication_failed_message = Message(i18n_catalog.i18nc("@info:status", ""), title = i18n_catalog.i18nc("@info:title", "Connection Status"))
self._authentication_failed_message.addAction("Retry", i18n_catalog.i18nc("@action:button", "Retry"), None, i18n_catalog.i18nc("@info:tooltip", "Re-send the access request")) self._authentication_failed_message.addAction("Retry", i18n_catalog.i18nc("@action:button", "Retry"), None, i18n_catalog.i18nc("@info:tooltip", "Re-send the access request"))
self._authentication_failed_message.actionTriggered.connect(self.requestAuthentication) self._authentication_failed_message.actionTriggered.connect(self.requestAuthentication)
self._authentication_succeeded_message = Message(i18n_catalog.i18nc("@info:status", "Access to the printer accepted")) self._authentication_succeeded_message = Message(i18n_catalog.i18nc("@info:status", "Access to the printer accepted"), title = i18n_catalog.i18nc("@info:title", "Connection Status"))
self._not_authenticated_message = Message(i18n_catalog.i18nc("@info:status", "No access to print with this printer. Unable to send print job.")) self._not_authenticated_message = Message(i18n_catalog.i18nc("@info:status", "No access to print with this printer. Unable to send print job."), title = i18n_catalog.i18nc("@info:title", "Connection Status"))
self._not_authenticated_message.addAction("Request", i18n_catalog.i18nc("@action:button", "Request Access"), None, i18n_catalog.i18nc("@info:tooltip", "Send access request to the printer")) self._not_authenticated_message.addAction("Request", i18n_catalog.i18nc("@action:button", "Request Access"), None, i18n_catalog.i18nc("@info:tooltip", "Send access request to the printer"))
self._not_authenticated_message.actionTriggered.connect(self.requestAuthentication) self._not_authenticated_message.actionTriggered.connect(self.requestAuthentication)
@ -464,7 +464,8 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
self._connection_state_before_timeout = self._connection_state self._connection_state_before_timeout = self._connection_state
self.setConnectionState(ConnectionState.error) self.setConnectionState(ConnectionState.error)
self._connection_message = Message(i18n_catalog.i18nc("@info:status", self._connection_message = Message(i18n_catalog.i18nc("@info:status",
"The connection with the network was lost.")) "The connection with the network was lost."),
title = i18n_catalog.i18nc("@info:title", "Connection Status"))
self._connection_message.show() self._connection_message.show()
if self._progress_message: if self._progress_message:
@ -495,7 +496,8 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
# Go into timeout state. # Go into timeout state.
Logger.log("d", "We did not receive a response for %0.1f seconds, so it seems the printer is no longer accessible.", time_since_last_response) Logger.log("d", "We did not receive a response for %0.1f seconds, so it seems the printer is no longer accessible.", time_since_last_response)
self._connection_state_before_timeout = self._connection_state self._connection_state_before_timeout = self._connection_state
self._connection_message = Message(i18n_catalog.i18nc("@info:status", "The connection with the printer was lost. Check your printer to see if it is connected.")) self._connection_message = Message(i18n_catalog.i18nc("@info:status", "The connection with the printer was lost. Check your printer to see if it is connected."),
title = i18n_catalog.i18nc("@info:title", "Connection Status"))
self._connection_message.show() self._connection_message.show()
if self._progress_message: if self._progress_message:
@ -644,7 +646,8 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None, **kwargs): def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None, **kwargs):
if self._printer_state not in ["idle", ""]: if self._printer_state not in ["idle", ""]:
self._error_message = Message( self._error_message = Message(
i18n_catalog.i18nc("@info:status", "Unable to start a new print job, printer is busy. Current printer status is %s.") % self._printer_state) i18n_catalog.i18nc("@info:status", "Unable to start a new print job, printer is busy. Current printer status is %s.") % self._printer_state,
title = i18n_catalog.i18nc("@info:title", "Printer Status"))
self._error_message.show() self._error_message.show()
return return
elif self._authentication_state != AuthState.Authenticated: elif self._authentication_state != AuthState.Authenticated:
@ -668,14 +671,16 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
if self._json_printer_state["heads"][0]["extruders"][index]["hotend"]["id"] == "": if self._json_printer_state["heads"][0]["extruders"][index]["hotend"]["id"] == "":
Logger.log("e", "No cartridge loaded in slot %s, unable to start print", index + 1) Logger.log("e", "No cartridge loaded in slot %s, unable to start print", index + 1)
self._error_message = Message( self._error_message = Message(
i18n_catalog.i18nc("@info:status", "Unable to start a new print job. No Printcore loaded in slot {0}".format(index + 1))) i18n_catalog.i18nc("@info:status", "Unable to start a new print job. No Printcore loaded in slot {0}".format(index + 1)),
title = i18n_catalog.i18nc("@info:title", "Error"))
self._error_message.show() self._error_message.show()
return return
if self._json_printer_state["heads"][0]["extruders"][index]["active_material"]["guid"] == "": if self._json_printer_state["heads"][0]["extruders"][index]["active_material"]["guid"] == "":
Logger.log("e", "No material loaded in slot %s, unable to start print", index + 1) Logger.log("e", "No material loaded in slot %s, unable to start print", index + 1)
self._error_message = Message( self._error_message = Message(
i18n_catalog.i18nc("@info:status", i18n_catalog.i18nc("@info:status",
"Unable to start a new print job. No material loaded in slot {0}".format(index + 1))) "Unable to start a new print job. No material loaded in slot {0}".format(index + 1)),
title = i18n_catalog.i18nc("@info:title", "Error"))
self._error_message.show() self._error_message.show()
return return
@ -831,7 +836,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
def startPrint(self): def startPrint(self):
try: try:
self._send_gcode_start = time() self._send_gcode_start = time()
self._progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), 0, False, -1) self._progress_message = Message(i18n_catalog.i18nc("@info:status", "Sending data to printer"), 0, False, -1, i18n_catalog.i18nc("@info:title", "Sending Data"))
self._progress_message.addAction("Abort", i18n_catalog.i18nc("@action:button", "Cancel"), None, "") self._progress_message.addAction("Abort", i18n_catalog.i18nc("@action:button", "Cancel"), None, "")
self._progress_message.actionTriggered.connect(self._progressMessageActionTrigger) self._progress_message.actionTriggered.connect(self._progressMessageActionTrigger)
self._progress_message.show() self._progress_message.show()
@ -900,7 +905,8 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
except IOError: except IOError:
self._progress_message.hide() self._progress_message.hide()
self._error_message = Message(i18n_catalog.i18nc("@info:status", "Unable to send data to printer. Is another job still active?")) self._error_message = Message(i18n_catalog.i18nc("@info:status", "Unable to send data to printer. Is another job still active?"),
title = i18n_catalog.i18nc("@info:title", "Warning"))
self._error_message.show() self._error_message.show()
except Exception as e: except Exception as e:
self._progress_message.hide() self._progress_message.hide()

View File

@ -150,7 +150,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
def printGCode(self, gcode_list): def printGCode(self, gcode_list):
Logger.log("d", "Started printing g-code") Logger.log("d", "Started printing g-code")
if self._progress or self._connection_state != ConnectionState.connected: if self._progress or self._connection_state != ConnectionState.connected:
self._error_message = Message(catalog.i18nc("@info:status", "Unable to start a new job because the printer is busy or not connected.")) self._error_message = Message(catalog.i18nc("@info:status", "Unable to start a new job because the printer is busy or not connected."), title = catalog.i18nc("@info:title", "Print Details"))
self._error_message.show() self._error_message.show()
Logger.log("d", "Printer is busy or not connected, aborting print") Logger.log("d", "Printer is busy or not connected, aborting print")
self.writeError.emit(self) self.writeError.emit(self)
@ -453,11 +453,11 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
container_stack = Application.getInstance().getGlobalContainerStack() container_stack = Application.getInstance().getGlobalContainerStack()
if container_stack.getProperty("machine_gcode_flavor", "value") == "UltiGCode": if container_stack.getProperty("machine_gcode_flavor", "value") == "UltiGCode":
self._error_message = Message(catalog.i18nc("@info:status", "This printer does not support USB printing because it uses UltiGCode flavor.")) self._error_message = Message(catalog.i18nc("@info:status", "This printer does not support USB printing because it uses UltiGCode flavor."), title = catalog.i18nc("@info:title", "USB Printing"))
self._error_message.show() self._error_message.show()
return return
elif not container_stack.getMetaDataEntry("supports_usb_connection"): elif not container_stack.getMetaDataEntry("supports_usb_connection"):
self._error_message = Message(catalog.i18nc("@info:status", "Unable to start a new job because the printer does not support usb printing.")) self._error_message = Message(catalog.i18nc("@info:status", "Unable to start a new job because the printer does not support usb printing."), title = catalog.i18nc("@info:title", "Warning"))
self._error_message.show() self._error_message.show()
return return
@ -622,8 +622,9 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._sendCommand("M140 S0") self._sendCommand("M140 S0")
self._sendCommand("M104 S0") self._sendCommand("M104 S0")
self._sendCommand("M107") self._sendCommand("M107")
# Home XY to prevent nozzle resting on aborted print
# Don't home bed because it may crash the printhead into the print on printers that home on the bottom
self.homeHead() self.homeHead()
self.homeBed()
self._sendCommand("M84") self._sendCommand("M84")
self._is_printing = False self._is_printing = False
self._is_paused = False self._is_paused = False

View File

@ -105,7 +105,7 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
if file_name.startswith("file://"): if file_name.startswith("file://"):
file_name = QUrl(file_name).toLocalFile() # File dialogs prepend the path with file://, which we don't need / want file_name = QUrl(file_name).toLocalFile() # File dialogs prepend the path with file://, which we don't need / want
if not self._usb_output_devices: if not self._usb_output_devices:
Message(i18n_catalog.i18nc("@info", "Unable to update firmware because there are no printers connected.")).show() Message(i18n_catalog.i18nc("@info", "Unable to update firmware because there are no printers connected."), title = i18n_catalog.i18nc("@info:title", "Warning")).show()
return return
for printer_connection in self._usb_output_devices: for printer_connection in self._usb_output_devices:
@ -119,7 +119,7 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
self._usb_output_devices[printer_connection].setProgress(100, 100) self._usb_output_devices[printer_connection].setProgress(100, 100)
Logger.log("w", "No firmware found for printer %s called '%s'", printer_connection, file_name) Logger.log("w", "No firmware found for printer %s called '%s'", printer_connection, file_name)
Message(i18n_catalog.i18nc("@info", Message(i18n_catalog.i18nc("@info",
"Could not find firmware required for the printer at %s.") % printer_connection).show() "Could not find firmware required for the printer at %s.") % printer_connection, title = i18n_catalog.i18nc("@info:title", "Printer Firmware")).show()
self._firmware_view.close() self._firmware_view.close()
continue continue

View File

@ -9,6 +9,24 @@ from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this.
_renamed_themes = { _renamed_themes = {
"cura": "cura-light" "cura": "cura-light"
} }
_renamed_i18n = {
"7s": "en_7S",
"de": "de_DE",
"en": "en_US",
"es": "es_ES",
"fi": "fi_FI",
"fr": "fr_FR",
"hu": "hu_HU",
"it": "it_IT",
"jp": "ja_JP",
"ko": "ko_KR",
"nl": "nl_NL",
"pl": "pl_PL",
"ptbr": "pt_BR",
"ru": "ru_RU",
"tr": "tr_TR"
}
class VersionUpgrade27to30(VersionUpgrade): class VersionUpgrade27to30(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 2.7 format. ## Gets the version number from a CFG file in Uranium's 2.7 format.
@ -43,13 +61,88 @@ class VersionUpgrade27to30(VersionUpgrade):
parser["general"]["version"] = "5" parser["general"]["version"] = "5"
if "metadata" not in parser: if "metadata" not in parser:
parser["metadata"] = {} parser["metadata"] = {}
parser["metadata"]["setting_version"] = "2" parser["metadata"]["setting_version"] = "3"
#Renamed themes. #Renamed themes.
if "theme" in parser["general"]: if "theme" in parser["general"]:
if parser["general"]["theme"] in _renamed_themes: if parser["general"]["theme"] in _renamed_themes:
parser["general"]["theme"] = _renamed_themes[parser["general"]["theme"]] parser["general"]["theme"] = _renamed_themes[parser["general"]["theme"]]
#Renamed languages.
if "language" in parser["general"]:
if parser["general"]["language"] in _renamed_i18n:
parser["general"]["language"] = _renamed_i18n[parser["general"]["language"]]
# Renamed settings for skin pre-shrink settings
if parser.has_section("general") and "visible_settings" in parser["general"]:
visible_settings = parser["general"]["visible_settings"].split(";")
new_visible_settings = []
renamed_skin_preshrink_names = {"expand_upper_skins": "top_skin_expand_distance",
"expand_lower_skins": "bottom_skin_expand_distance"}
for setting in visible_settings:
if setting == "expand_skins_into_infill":
continue # this one is removed
if setting in renamed_skin_preshrink_names:
new_visible_settings.append(renamed_skin_preshrink_names[setting])
continue #Don't add the original.
new_visible_settings.append(setting) #No special handling, so just add the original visible setting back.
parser["general"]["visible_settings"] = ";".join(new_visible_settings)
# Re-serialise the file.
output = io.StringIO()
parser.write(output)
return [filename], [output.getvalue()]
## Upgrades the given instance container file from version 2.7 to 3.0.
#
# \param serialised The serialised form of the container file.
# \param filename The name of the file to upgrade.
def upgradeOtherContainer(self, serialised, filename):
parser = configparser.ConfigParser(interpolation=None)
parser.read_string(serialised)
# Update the skin pre-shrink settings:
# - Remove the old ones
# - Do not add the new ones. The default values will be used for them.
if parser.has_section("values"):
for remove_key in ["expand_skins_into_infill", "expand_upper_skins", "expand_lower_skins"]:
if remove_key in parser["values"]:
del parser["values"][remove_key]
for each_section in ("general", "metadata"):
if not parser.has_section(each_section):
parser.add_section(each_section)
# Update version numbers
parser["general"]["version"] = "2"
parser["metadata"]["setting_version"] = "3"
# Re-serialise the file.
output = io.StringIO()
parser.write(output)
return [filename], [output.getvalue()]
## Upgrades a container stack from version 2.7 to 3.0.
#
# \param serialised The serialised form of a container stack.
# \param filename The name of the file to upgrade.
def upgradeStack(self, serialised, filename):
parser = configparser.ConfigParser(interpolation=None)
parser.read_string(serialised)
for each_section in ("general", "metadata"):
if not parser.has_section(each_section):
parser.add_section(each_section)
# Update version numbers
if "general" not in parser:
parser["general"] = {}
parser["general"]["version"] = "3"
if "metadata" not in parser:
parser["metadata"] = {}
parser["metadata"]["setting_version"] = "3"
# Re-serialise the file. # Re-serialise the file.
output = io.StringIO() output = io.StringIO()
parser.write(output) parser.write(output)

View File

@ -9,13 +9,46 @@ def getMetaData():
return { return {
"version_upgrade": { "version_upgrade": {
# From To Upgrade function # From To Upgrade function
("preferences", 4000002): ("preferences", 5000002, upgrade.upgradePreferences), ("preferences", 4000002): ("preferences", 5000003, upgrade.upgradePreferences),
("machine_stack", 3000002): ("machine_stack", 3000003, upgrade.upgradeStack),
("extruder_train", 3000002): ("extruder_train", 3000003, upgrade.upgradeStack),
("quality_changes", 2000002): ("quality_changes", 2000003, upgrade.upgradeOtherContainer),
("user", 2000002): ("user", 2000003, upgrade.upgradeOtherContainer),
("quality", 2000002): ("quality", 2000003, upgrade.upgradeOtherContainer),
("definition_changes", 2000002): ("definition_changes", 2000003, upgrade.upgradeOtherContainer),
("variant", 2000002): ("variant", 2000003, upgrade.upgradeOtherContainer)
}, },
"sources": { "sources": {
"preferences": { "preferences": {
"get_version": upgrade.getCfgVersion, "get_version": upgrade.getCfgVersion,
"location": {"."} "location": {"."}
}, },
"machine_stack": {
"get_version": upgrade.getCfgVersion,
"location": {"./machine_instances"}
},
"extruder_train": {
"get_version": upgrade.getCfgVersion,
"location": {"./extruders"}
},
"quality_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./quality"}
},
"user": {
"get_version": upgrade.getCfgVersion,
"location": {"./user"}
},
"definition_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./definition_changes"}
},
"variant": {
"get_version": upgrade.getCfgVersion,
"location": {"./variants"}
}
} }
} }

View File

@ -9,7 +9,7 @@ catalog = i18nCatalog("cura")
def getMetaData(): def getMetaData():
return { return {
"view": { "view": {
"name": catalog.i18nc("@item:inlistbox", "X-Ray"), "name": catalog.i18nc("@item:inlistbox", "X-Ray view"),
"weight": 1 "weight": 1
} }
} }

View File

@ -35,7 +35,7 @@ class XmlMaterialProfile(InstanceContainer):
# \return The corresponding setting_version. # \return The corresponding setting_version.
def xmlVersionToSettingVersion(self, xml_version: str) -> int: def xmlVersionToSettingVersion(self, xml_version: str) -> int:
if xml_version == "1.3": if xml_version == "1.3":
return 2 return 3
return 0 #Older than 1.3. return 0 #Older than 1.3.
def getInheritedFiles(self): def getInheritedFiles(self):

View File

@ -19,7 +19,7 @@ def getMetaData():
"mimetype": "application/x-ultimaker-material-profile" "mimetype": "application/x-ultimaker-material-profile"
}, },
"version_upgrade": { "version_upgrade": {
("materials", 1000000): ("materials", 1000002, upgrader.upgradeMaterial), ("materials", 1000000): ("materials", 1000003, upgrader.upgradeMaterial),
}, },
"sources": { "sources": {
"materials": { "materials": {

View File

@ -566,6 +566,7 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 20.0, "default_value": 20.0,
"minimum_value": "0",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
@ -577,6 +578,7 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 0.4, "default_value": 0.4,
"minimum_value": "0",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
@ -588,6 +590,7 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 5.0, "default_value": 5.0,
"minimum_value": "0",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
@ -1231,7 +1234,7 @@
"random": "Random", "random": "Random",
"sharpest_corner": "Sharpest Corner" "sharpest_corner": "Sharpest Corner"
}, },
"default_value": "shortest", "default_value": "sharpest_corner",
"limit_to_extruder": "wall_0_extruder_nr", "limit_to_extruder": "wall_0_extruder_nr",
"settable_per_mesh": true "settable_per_mesh": true
}, },
@ -1295,6 +1298,17 @@
"default_value": true, "default_value": true,
"limit_to_extruder": "top_bottom_extruder_nr", "limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true "settable_per_mesh": true
},
"skin_outline_count":
{
"label": "Extra Skin Wall Count",
"description": "Replaces the outermost part of the top/bottom pattern with a number of concentric lines. Using one or two lines improves roofs that start on infill material.",
"default_value": 1,
"minimum_value": "0",
"maximum_value_warning": "10",
"type": "int",
"limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true
} }
} }
}, },
@ -1531,11 +1545,12 @@
}, },
"skin_preshrink": "skin_preshrink":
{ {
"label": "Skin Pre-Shrink Distance", "label": "Skin Removal Width",
"description": "The distance the skins are shrunk before considering them for skin expansion. Every skin area smaller than this value will disappear. This can help in limiting the amount of time and material spent on printing top/bottom skin at slanted surfaces in the model.", "description": "The largest width of skin areas which are to be removed. Every skin area smaller than this value will disappear. This can help in limiting the amount of time and material spent on printing top/bottom skin at slanted surfaces in the model.",
"unit": "mm", "unit": "mm",
"type": "float", "type": "float",
"default_value": 0, "default_value": 0,
"value": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
"minimum_value": "0", "minimum_value": "0",
"limit_to_extruder": "top_bottom_extruder_nr", "limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true, "settable_per_mesh": true,
@ -1543,8 +1558,8 @@
{ {
"top_skin_preshrink": "top_skin_preshrink":
{ {
"label": "Top Skin Pre-Shrink Distance", "label": "Top Skin Removal Width",
"description": "The distance the top skins are shrunk before considering them for skin expansion. Every skin area smaller than this value will disappear. This can help in limiting the amount of time and material spent on printing top skin at slanted surfaces in the model.", "description": "The largest width of top skin areas which are to be removed. Every skin area smaller than this value will disappear. This can help in limiting the amount of time and material spent on printing top skin at slanted surfaces in the model.",
"unit": "mm", "unit": "mm",
"type": "float", "type": "float",
"default_value": 0, "default_value": 0,
@ -1555,8 +1570,8 @@
}, },
"bottom_skin_preshrink": "bottom_skin_preshrink":
{ {
"label": "Bottom Skin Pre-Shrink Distance", "label": "Bottom Skin Removal Width",
"description": "The distance the bottom skins are shrunk before considering them for skin expansion. Every skin area smaller than this value will disappear. This can help in limiting the amount of time and material spent on printing bottom skin at slanted surfaces in the model.", "description": "The largest width of bottom skin areas which are to be removed. Every skin area smaller than this value will disappear. This can help in limiting the amount of time and material spent on printing bottom skin at slanted surfaces in the model.",
"unit": "mm", "unit": "mm",
"type": "float", "type": "float",
"default_value": 0, "default_value": 0,
@ -1567,51 +1582,45 @@
} }
} }
}, },
"expand_skins_into_infill": "expand_skins_expand_distance":
{ {
"label": "Expand Skins Into Infill", "label": "Skin Expand Distance",
"description": "Expand skin areas of top and/or bottom skin of flat surfaces. By default, skins stop under the wall lines that surround infill but this can lead to holes appearing when the infill density is low. This setting extends the skins beyond the wall lines so that the infill on the next layer rests on skin.", "description": "The distance the skins are expanded into the infill. Higher values makes the skin attach better to the infill pattern and makes the walls on neighboring layers adhere better to the skin. Lower values save amount of material used.",
"type": "bool", "unit": "mm",
"default_value": false, "type": "float",
"default_value": 2.8,
"value": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
"minimum_value": "-skin_preshrink",
"limit_to_extruder": "top_bottom_extruder_nr", "limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true, "settable_per_mesh": true,
"children": "children":
{ {
"expand_upper_skins": "top_skin_expand_distance":
{ {
"label": "Expand Top Skins Into Infill", "label": "Top Skin Expand Distance",
"description": "Expand the top skin areas (areas with air above) so that they support infill above.", "description": "The distance the top skins are expanded into the infill. Higher values makes the skin attach better to the infill pattern and makes the walls on the layer above adhere better to the skin. Lower values save amount of material used.",
"type": "bool", "unit": "mm",
"default_value": false, "type": "float",
"value": "expand_skins_into_infill", "default_value": 2.8,
"value": "expand_skins_expand_distance",
"minimum_value": "-top_skin_preshrink",
"limit_to_extruder": "top_bottom_extruder_nr", "limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true "settable_per_mesh": true
}, },
"expand_lower_skins": "bottom_skin_expand_distance":
{ {
"label": "Expand Bottom Skins Into Infill", "label": "Bottom Skin Expand Distance",
"description": "Expand the bottom skin areas (areas with air below) so that they are anchored by the infill layers above and below.", "description": "The distance the bottom skins are expanded into the infill. Higher values makes the skin attach better to the infill pattern and makes the skin adhere better to the walls on the layer below. Lower values save amount of material used.",
"type": "bool", "unit": "mm",
"default_value": false, "type": "float",
"default_value": 2.8,
"value": "expand_skins_expand_distance",
"minimum_value": "-bottom_skin_preshrink",
"limit_to_extruder": "top_bottom_extruder_nr", "limit_to_extruder": "top_bottom_extruder_nr",
"value": "expand_skins_into_infill",
"settable_per_mesh": true "settable_per_mesh": true
} }
} }
}, },
"expand_skins_expand_distance":
{
"label": "Skin Expand Distance",
"description": "The distance the skins are expanded into the infill. The default distance is enough to bridge the gap between the infill lines and will stop holes appearing in the skin where it meets the wall when the infill density is low. A smaller distance will often be sufficient.",
"unit": "mm",
"type": "float",
"default_value": 2.8,
"value": "infill_line_distance * 1.4",
"minimum_value": "0",
"enabled": "expand_upper_skins or expand_lower_skins",
"limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true
},
"max_skin_angle_for_expansion": "max_skin_angle_for_expansion":
{ {
"label": "Maximum Skin Angle for Expansion", "label": "Maximum Skin Angle for Expansion",
@ -1620,10 +1629,9 @@
"type": "float", "type": "float",
"minimum_value": "0", "minimum_value": "0",
"minimum_value_warning": "2", "minimum_value_warning": "2",
"maximum_value_warning": "45",
"maximum_value": "90", "maximum_value": "90",
"default_value": 20, "default_value": 90,
"enabled": "expand_upper_skins or expand_lower_skins", "enabled": "top_skin_expand_distance > 0 or bottom_skin_expand_distance > 0",
"limit_to_extruder": "top_bottom_extruder_nr", "limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true, "settable_per_mesh": true,
"children": "children":
@ -1637,7 +1645,7 @@
"default_value": 2.24, "default_value": 2.24,
"value": "top_layers * layer_height / math.tan(math.radians(max_skin_angle_for_expansion))", "value": "top_layers * layer_height / math.tan(math.radians(max_skin_angle_for_expansion))",
"minimum_value": "0", "minimum_value": "0",
"enabled": "expand_upper_skins or expand_lower_skins", "enabled": "top_skin_expand_distance > 0 or bottom_skin_expand_distance > 0",
"limit_to_extruder": "top_bottom_extruder_nr", "limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true "settable_per_mesh": true
} }
@ -2677,7 +2685,7 @@
"description": "The maximum instantaneous velocity change of the print head.", "description": "The maximum instantaneous velocity change of the print head.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"enabled": "resolveOrValue('jerk_enabled')", "enabled": "resolveOrValue('jerk_enabled')",
@ -2690,7 +2698,7 @@
"description": "The maximum instantaneous velocity change with which infill is printed.", "description": "The maximum instantaneous velocity change with which infill is printed.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"value": "jerk_print", "value": "jerk_print",
@ -2704,7 +2712,7 @@
"description": "The maximum instantaneous velocity change with which the walls are printed.", "description": "The maximum instantaneous velocity change with which the walls are printed.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"value": "jerk_print", "value": "jerk_print",
@ -2718,7 +2726,7 @@
"description": "The maximum instantaneous velocity change with which the outermost walls are printed.", "description": "The maximum instantaneous velocity change with which the outermost walls are printed.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"value": "jerk_wall", "value": "jerk_wall",
@ -2732,7 +2740,7 @@
"description": "The maximum instantaneous velocity change with which all inner walls are printed.", "description": "The maximum instantaneous velocity change with which all inner walls are printed.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"value": "jerk_wall", "value": "jerk_wall",
@ -2748,7 +2756,7 @@
"description": "The maximum instantaneous velocity change with which top surface skin layers are printed.", "description": "The maximum instantaneous velocity change with which top surface skin layers are printed.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"value": "jerk_topbottom", "value": "jerk_topbottom",
@ -2762,7 +2770,7 @@
"description": "The maximum instantaneous velocity change with which top/bottom layers are printed.", "description": "The maximum instantaneous velocity change with which top/bottom layers are printed.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"value": "jerk_print", "value": "jerk_print",
@ -2776,7 +2784,7 @@
"description": "The maximum instantaneous velocity change with which the support structure is printed.", "description": "The maximum instantaneous velocity change with which the support structure is printed.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"value": "jerk_print", "value": "jerk_print",
@ -2794,7 +2802,7 @@
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"value": "jerk_support", "value": "jerk_support",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled') and support_enable", "enabled": "resolveOrValue('jerk_enabled') and support_enable",
"limit_to_extruder": "support_infill_extruder_nr", "limit_to_extruder": "support_infill_extruder_nr",
@ -2809,7 +2817,7 @@
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"value": "jerk_support", "value": "jerk_support",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled') and support_interface_enable and support_enable", "enabled": "resolveOrValue('jerk_enabled') and support_interface_enable and support_enable",
"limit_to_extruder": "support_interface_extruder_nr", "limit_to_extruder": "support_interface_extruder_nr",
@ -2825,7 +2833,7 @@
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')", "value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled') and support_roof_enable and support_enable", "enabled": "resolveOrValue('jerk_enabled') and support_roof_enable and support_enable",
"limit_to_extruder": "support_roof_extruder_nr", "limit_to_extruder": "support_roof_extruder_nr",
@ -2840,7 +2848,7 @@
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')", "value": "extruderValue(support_roof_extruder_nr, 'jerk_support_interface')",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled') and support_bottom_enable and support_enable", "enabled": "resolveOrValue('jerk_enabled') and support_bottom_enable and support_enable",
"limit_to_extruder": "support_bottom_extruder_nr", "limit_to_extruder": "support_bottom_extruder_nr",
@ -2857,7 +2865,7 @@
"description": "The maximum instantaneous velocity change with which the prime tower is printed.", "description": "The maximum instantaneous velocity change with which the prime tower is printed.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"value": "jerk_print", "value": "jerk_print",
@ -2873,7 +2881,7 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 30, "default_value": 30,
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"value": "jerk_print if magic_spiralize else 30", "value": "jerk_print if magic_spiralize else 30",
"enabled": "resolveOrValue('jerk_enabled')", "enabled": "resolveOrValue('jerk_enabled')",
@ -2887,7 +2895,7 @@
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"value": "jerk_print", "value": "jerk_print",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled')", "enabled": "resolveOrValue('jerk_enabled')",
"settable_per_mesh": true, "settable_per_mesh": true,
@ -2901,7 +2909,7 @@
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"value": "jerk_layer_0", "value": "jerk_layer_0",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled')", "enabled": "resolveOrValue('jerk_enabled')",
"settable_per_mesh": true "settable_per_mesh": true
@ -2914,7 +2922,7 @@
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"value": "jerk_layer_0 * jerk_travel / jerk_print", "value": "jerk_layer_0 * jerk_travel / jerk_print",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('jerk_enabled')", "enabled": "resolveOrValue('jerk_enabled')",
"settable_per_extruder": true, "settable_per_extruder": true,
@ -2929,7 +2937,7 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"value": "jerk_layer_0", "value": "jerk_layer_0",
"enabled": "resolveOrValue('jerk_enabled')", "enabled": "resolveOrValue('jerk_enabled')",
@ -4448,7 +4456,7 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"minimum_value": "0.1", "minimum_value": "0",
"minimum_value_warning": "5", "minimum_value_warning": "5",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"value": "jerk_print", "value": "jerk_print",
@ -4465,7 +4473,7 @@
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"value": "raft_jerk", "value": "raft_jerk",
"minimum_value": "0.1", "minimum_value": "0",
"minimum_value_warning": "5", "minimum_value_warning": "5",
"maximum_value_warning": "100", "maximum_value_warning": "100",
"enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')", "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')",
@ -4480,7 +4488,7 @@
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"value": "raft_jerk", "value": "raft_jerk",
"minimum_value": "0.1", "minimum_value": "0",
"minimum_value_warning": "5", "minimum_value_warning": "5",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')", "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')",
@ -4495,7 +4503,7 @@
"type": "float", "type": "float",
"default_value": 20, "default_value": 20,
"value": "raft_jerk", "value": "raft_jerk",
"minimum_value": "0.1", "minimum_value": "0",
"minimum_value_warning": "5", "minimum_value_warning": "5",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')", "enabled": "resolveOrValue('adhesion_type') == 'raft' and resolveOrValue('jerk_enabled')",
@ -5000,6 +5008,17 @@
"enabled": "magic_spiralize", "enabled": "magic_spiralize",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false "settable_per_extruder": false
},
"relative_extrusion":
{
"label": "Relative Extrusion",
"description": "Use relative extrusion rather than absolute extrusion. Using relative E-steps makes for easier post-processing of the Gcode. However, it's not supported by all printers and it may produce very slight deviations in the amount of deposited material compared to absolute E-steps. Irrespective of this setting, the extrusion mode will always be set to absolute before any Gcode script is output.",
"type": "bool",
"default_value": false,
"value": "machine_gcode_flavor==\"RepRap (RepRap)\"",
"enabled": true,
"settable_per_mesh": false,
"settable_per_extruder": false
} }
} }
}, },
@ -5139,17 +5158,6 @@
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
}, },
"skin_outline_count":
{
"label": "Extra Skin Wall Count",
"description": "Replaces the outermost part of the top/bottom pattern with a number of concentric lines. Using one or two lines improves roofs that start on infill material.",
"default_value": 0,
"minimum_value": "0",
"maximum_value_warning": "10",
"type": "int",
"limit_to_extruder": "top_bottom_extruder_nr",
"settable_per_mesh": true
},
"skin_alternate_rotation": "skin_alternate_rotation":
{ {
"label": "Alternate Skin Rotation", "label": "Alternate Skin Rotation",
@ -5803,7 +5811,7 @@
"description": "The maximum instantaneous velocity change while performing ironing.", "description": "The maximum instantaneous velocity change while performing ironing.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"minimum_value": "0.1", "minimum_value": "0",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"default_value": 20, "default_value": 20,
"value": "jerk_topbottom", "value": "jerk_topbottom",

View File

@ -31,6 +31,11 @@
{ {
"minimum_value": "0", "minimum_value": "0",
"maximum_value": "machine_width" "maximum_value": "machine_width"
},
"relative_extrusion":
{
"value": false,
"enabled": false
} }
} }
} }

View File

@ -0,0 +1,62 @@
{
"id": "K8800",
"name": "Vertex Delta K8800",
"version": 2,
"inherits": "fdmprinter",
"metadata": {
"manufacturer": "Velleman nv",
"file_formats": "text/x-gcode",
"visible": true,
"author": "Velleman"
},
"overrides": {
"machine_width": {
"default_value": 200
},
"machine_height": {
"default_value": 225
},
"machine_depth": {
"default_value": 200
},
"machine_center_is_zero": {
"default_value": true
},
"machine_shape": {
"default_value": "elliptic"
},
"machine_nozzle_size": {
"default_value": 0.35
},
"machine_head_shape_min_x": {
"default_value": 0
},
"machine_head_shape_min_y": {
"default_value": 0
},
"machine_head_shape_max_x": {
"default_value": 0
},
"machine_head_shape_max_y": {
"default_value": 0
},
"machine_nozzle_gantry_distance": {
"default_value": 0
},
"machine_nozzle_offset_x_1": {
"default_value": 0
},
"machine_nozzle_offset_y_1": {
"default_value": 0
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
"default_value": "; Vertex Delta Start Gcode\nM0 Is my nozzle clean?\nM400\nG28 ; Home extruder\nM106 S128 ; Start fan\nM104 T0 R130 ; Set cold nozzle\nM109 T0 R130 ; Wait for cold nozzle\nM117 Leveling bed...\nG29 ; Level Bed\nG1 X0 Y100 Z1 F2000\nG92 Z0.9 ; Set Z position (SET Z OFFSET HERE -> 1 - OFFSET)\nM107 ; Stop fan\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\nM104 T0 S{material_print_temperature}\nG92 E0 ; Reset extruder position\nM109 T0 S{material_print_temperature}\nM117 Priming nozzle...\nM83\nG1 E20 F100 ; purge/prime nozzle\nM82\nG92 E0 ; Reset extruder position\nG4 S3 ; Wait 3 seconds\nG1 Z5 F2000\nM117 Vertex Delta printing"
},
"machine_end_gcode": {
"default_value": "; Vertex Delta end code\nM107 ; Turn off fan\nG91 ; Relative positioning\nT0\nG1 E-1 F1500; Reduce filament pressure\nM104 T0 S0\nG90 ; Absolute positioning\nG92 E0 ; Reset extruder position\nM300 S4000 P500\nM300 S3000 P500\nM300 S2000 P800\nG28\nM84 ; Turn steppers off"
}
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -319,24 +319,6 @@ UM.MainWindow
} }
} }
Loader
{
id: view_panel
property bool hugBottom: parent.height < viewModeButton.y + viewModeButton.height + height + UM.Theme.getSize("default_margin").height
anchors.bottom: parent.bottom // panel is always anchored to the bottom only, because dynamically switching between bottom and top results in stretching the height
anchors.bottomMargin: hugBottom ? 0 : parent.height - (viewModeButton.y + viewModeButton.height + height + UM.Theme.getSize("default_margin").height)
anchors.left: viewModeButton.left;
anchors.leftMargin: hugBottom ? viewModeButton.width + UM.Theme.getSize("default_margin").width : 0
property var buttonTarget: Qt.point(viewModeButton.x + viewModeButton.width / 2, viewModeButton.y + viewModeButton.height / 2)
height: childrenRect.height;
source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "";
}
Button Button
{ {
id: openFileButton; id: openFileButton;
@ -393,25 +375,6 @@ UM.MainWindow
monitoringPrint: base.showPrintMonitor monitoringPrint: base.showPrintMonitor
} }
Button
{
id: viewModeButton
anchors
{
top: toolbar.bottom;
topMargin: UM.Theme.getSize("window_margin").height;
left: parent.left;
}
text: catalog.i18nc("@action:button","View Mode");
iconSource: UM.Theme.getIcon("viewmode");
style: UM.Theme.styles.tool_button;
tooltip: "";
enabled: !PrintInformation.preSliced
menu: ViewMenu { }
}
Rectangle Rectangle
{ {
id: viewportOverlay id: viewportOverlay

View File

@ -1,4 +1,4 @@
// Copyright (c) 2016 Ultimaker B.V. // Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the AGPLv3 or higher. // Cura is released under the terms of the AGPLv3 or higher.
import QtQuick 2.1 import QtQuick 2.1
@ -148,25 +148,25 @@ UM.PreferencesPage
id: languageList id: languageList
Component.onCompleted: { Component.onCompleted: {
append({ text: "English", code: "en" }) append({ text: "English", code: "en_US" })
append({ text: "Deutsch", code: "de" }) append({ text: "Deutsch", code: "de_DE" })
append({ text: "Español", code: "es" }) append({ text: "Español", code: "es_ES" })
append({ text: "Suomi", code: "fi" }) append({ text: "Suomi", code: "fi_FI" })
append({ text: "Français", code: "fr" }) append({ text: "Français", code: "fr_FR" })
append({ text: "Italiano", code: "it" }) append({ text: "Italiano", code: "it_IT" })
append({ text: "日本語", code: "jp" }) append({ text: "日本語", code: "ja_JP" })
append({ text: "한국어", code: "ko" }) append({ text: "한국어", code: "ko_KR" })
append({ text: "Nederlands", code: "nl" }) append({ text: "Nederlands", code: "nl_NL" })
append({ text: "Polski", code: "pl" }) append({ text: "Polski", code: "pl_PL" })
append({ text: "Português do Brasil", code: "ptbr" }) append({ text: "Português do Brasil", code: "pt_BR" })
append({ text: "Русский", code: "ru" }) append({ text: "Русский", code: "ru_RU" })
append({ text: "Türkçe", code: "tr" }) append({ text: "Türkçe", code: "tr_TR" })
append({ text: "简体中文", code: "zh_CN" }) append({ text: "简体中文", code: "zh_CN" })
var date_object = new Date(); var date_object = new Date();
if (date_object.getUTCMonth() == 8 && date_object.getUTCDate() == 19) //Only add Pirate on the 19th of September. if (date_object.getUTCMonth() == 8 && date_object.getUTCDate() == 19) //Only add Pirate on the 19th of September.
{ {
append({ text: "Pirate", code: "7s" }) append({ text: "Pirate", code: "en_7S" })
} }
} }
} }

View File

@ -181,7 +181,7 @@ Rectangle
color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") : color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") :
control.hovered ? UM.Theme.getColor("action_button_hovered_text") : control.hovered ? UM.Theme.getColor("action_button_hovered_text") :
UM.Theme.getColor("action_button_text") UM.Theme.getColor("action_button_text")
font: (control.checked || control.pressed) ? UM.Theme.getFont("default_bold") : UM.Theme.getFont("default") font: UM.Theme.getFont("default")
text: control.text; text: control.text;
} }
} }

View File

@ -153,7 +153,7 @@ Column
control.hovered ? UM.Theme.getColor("action_button_hovered_text") : control.hovered ? UM.Theme.getColor("action_button_hovered_text") :
UM.Theme.getColor("action_button_text") UM.Theme.getColor("action_button_text")
font: control.checked ? UM.Theme.getFont("default_bold") : UM.Theme.getFont("default") font: UM.Theme.getFont("large_nonbold")
text: catalog.i18nc("@label", "Extruder") text: catalog.i18nc("@label", "Extruder")
visible: width < (control.width - extruderIconItem.width - UM.Theme.getSize("default_margin").width) visible: width < (control.width - extruderIconItem.width - UM.Theme.getSize("default_margin").width)
elide: Text.ElideRight elide: Text.ElideRight
@ -351,14 +351,12 @@ Column
rightMargin: UM.Theme.getSize("sidebar_margin").width rightMargin: UM.Theme.getSize("sidebar_margin").width
} }
Item Item {
{
height: UM.Theme.getSize("sidebar_setup").height height: UM.Theme.getSize("sidebar_setup").height
anchors.right: parent.right anchors.right: parent.right
width: parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width width: parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width
UM.RecolorImage UM.RecolorImage {
{
id: warningImage id: warningImage
anchors.right: materialInfoLabel.left anchors.right: materialInfoLabel.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.rightMargin: UM.Theme.getSize("default_margin").width
@ -366,41 +364,33 @@ Column
source: UM.Theme.getIcon("warning") source: UM.Theme.getIcon("warning")
width: UM.Theme.getSize("section_icon").width width: UM.Theme.getSize("section_icon").width
height: UM.Theme.getSize("section_icon").height height: UM.Theme.getSize("section_icon").height
//sourceSize.width: width + 5
//sourceSize.height: width + 5
color: UM.Theme.getColor("material_compatibility_warning") color: UM.Theme.getColor("material_compatibility_warning")
visible: !Cura.MachineManager.isCurrentSetupSupported visible: !Cura.MachineManager.isCurrentSetupSupported
} }
Text Text {
{
id: materialInfoLabel id: materialInfoLabel
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "Check material compatibility") text: catalog.i18nc("@label", "<a href='%1'>Check material compatibility</a>")
font: UM.Theme.getFont("default"); font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
linkColor: UM.Theme.getColor("text_link")
verticalAlignment: Text.AlignTop verticalAlignment: Text.AlignTop
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
color: UM.Theme.getColor("text")
MouseArea MouseArea {
{
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onClicked: onClicked: {
{
// open the material URL with web browser // open the material URL with web browser
var version = UM.Application.version; var version = UM.Application.version;
var machineName = Cura.MachineManager.activeMachine.definition.id; var machineName = Cura.MachineManager.activeMachine.definition.id;
var url = "https://ultimaker.com/materialcompatibility/" + version + "/" + machineName; var url = "https://ultimaker.com/materialcompatibility/" + version + "/" + machineName;
Qt.openUrlExternally(url); Qt.openUrlExternally(url);
} }
onEntered: onEntered: {
{
var content = catalog.i18nc("@tooltip", "Click to check the material compatibility on Ultimaker.com."); var content = catalog.i18nc("@tooltip", "Click to check the material compatibility on Ultimaker.com.");
base.showTooltip( base.showTooltip(
materialInfoRow, materialInfoRow,

View File

@ -261,6 +261,7 @@ Item
Text Text
{ {
id: enableSupportLabel id: enableSupportLabel
visible: enableSupportCheckBox.visible
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.verticalCenter: enableSupportCheckBox.verticalCenter anchors.verticalCenter: enableSupportCheckBox.verticalCenter
@ -281,6 +282,7 @@ Item
style: UM.Theme.styles.checkbox; style: UM.Theme.styles.checkbox;
enabled: base.settingsEnabled enabled: base.settingsEnabled
visible: supportEnabled.properties.enabled == "True"
checked: supportEnabled.properties.value == "True"; checked: supportEnabled.properties.value == "True";
MouseArea MouseArea
@ -309,7 +311,7 @@ Item
Text Text
{ {
id: supportExtruderLabel id: supportExtruderLabel
visible: (supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1) visible: supportExtruderCombobox.visible
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.verticalCenter: supportExtruderCombobox.verticalCenter anchors.verticalCenter: supportExtruderCombobox.verticalCenter
@ -321,7 +323,7 @@ Item
ComboBox ComboBox
{ {
id: supportExtruderCombobox id: supportExtruderCombobox
visible: (supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1) visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)
model: extruderModel model: extruderModel
property string color_override: "" // for manually setting values property string color_override: "" // for manually setting values
@ -329,41 +331,19 @@ Item
{ {
var current_extruder = extruderModel.get(currentIndex); var current_extruder = extruderModel.get(currentIndex);
color_override = ""; color_override = "";
if (current_extruder === undefined) { if (current_extruder === undefined) return ""
return ""; return (current_extruder.color) ? current_extruder.color : "";
}
var model_color = current_extruder.color;
return (model_color) ? model_color : "";
} }
textRole: 'text' // this solves that the combobox isn't populated in the first time Cura is started textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started
anchors.top: enableSupportCheckBox.bottom anchors.top: enableSupportCheckBox.bottom
anchors.topMargin: anchors.topMargin: ((supportEnabled.properties.value === "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("sidebar_margin").height : 0
{
if ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1))
{
return UM.Theme.getSize("sidebar_margin").height;
}
else
{
return 0;
}
}
anchors.left: infillCellRight.left anchors.left: infillCellRight.left
width: UM.Theme.getSize("sidebar").width * .55 width: UM.Theme.getSize("sidebar").width * .55
height: height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0
{
if ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1))
{
// default height when control is enabled
return UM.Theme.getSize("setting_control").height;
}
else
{
return 0;
}
}
Behavior on height { NumberAnimation { duration: 100 } } Behavior on height { NumberAnimation { duration: 100 } }
style: UM.Theme.styles.combobox_color style: UM.Theme.styles.combobox_color
@ -407,6 +387,7 @@ Item
Text Text
{ {
id: adhesionHelperLabel id: adhesionHelperLabel
visible: adhesionCheckBox.visible
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.verticalCenter: adhesionCheckBox.verticalCenter anchors.verticalCenter: adhesionCheckBox.verticalCenter
@ -421,7 +402,7 @@ Item
id: adhesionCheckBox id: adhesionCheckBox
property alias _hovered: adhesionMouseArea.containsMouse property alias _hovered: adhesionMouseArea.containsMouse
anchors.top: supportExtruderCombobox.bottom anchors.top: enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
anchors.left: infillCellRight.left anchors.left: infillCellRight.left
@ -429,6 +410,7 @@ Item
style: UM.Theme.styles.checkbox; style: UM.Theme.styles.checkbox;
enabled: base.settingsEnabled enabled: base.settingsEnabled
visible: platformAdhesionType.properties.enabled == "True"
checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none" checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none"
MouseArea MouseArea
@ -445,7 +427,7 @@ Item
// Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft // Remove the "user" setting to see if the rest of the stack prescribes a brim or a raft
platformAdhesionType.removeFromContainer(0); platformAdhesionType.removeFromContainer(0);
adhesionType = platformAdhesionType.properties.value; adhesionType = platformAdhesionType.properties.value;
if(adhesionType == "skirt") if(adhesionType == "skirt" || adhesionType == "none")
{ {
// If the rest of the stack doesn't prescribe an adhesion-type, default to a brim // If the rest of the stack doesn't prescribe an adhesion-type, default to a brim
adhesionType = "brim"; adhesionType = "brim";
@ -481,7 +463,7 @@ Item
Item Item
{ {
id: tipsCell id: tipsCell
anchors.top: adhesionCheckBox.bottom anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom)
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2 anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2
anchors.left: parent.left anchors.left: parent.left
width: parent.width width: parent.width
@ -566,7 +548,7 @@ Item
containerStackId: Cura.MachineManager.activeMachineId containerStackId: Cura.MachineManager.activeMachineId
key: "adhesion_type" key: "adhesion_type"
watchedProperties: [ "value" ] watchedProperties: [ "value", "enabled" ]
storeIndex: 0 storeIndex: 0
} }
@ -576,7 +558,7 @@ Item
containerStackId: Cura.MachineManager.activeMachineId containerStackId: Cura.MachineManager.activeMachineId
key: "support_enable" key: "support_enable"
watchedProperties: [ "value", "description" ] watchedProperties: [ "value", "enabled", "description" ]
storeIndex: 0 storeIndex: 0
} }

View File

@ -16,13 +16,16 @@ Rectangle
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
height: UM.Theme.getSize("sidebar_header").height height: UM.Theme.getSize("sidebar_header").height
color: "transparent" color: base.monitoringPrint ? UM.Theme.getColor("topbar_background_color_monitoring") : UM.Theme.getColor("topbar_background_color")
Behavior on color { ColorAnimation { duration: 100; } }
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
property bool monitoringPrint: false property bool monitoringPrint: false
signal startMonitoringPrint() signal startMonitoringPrint()
signal stopMonitoringPrint() signal stopMonitoringPrint()
UM.I18nCatalog UM.I18nCatalog
{ {
id: catalog id: catalog
@ -76,21 +79,21 @@ Rectangle
text: catalog.i18nc("@title:tab", "Monitor") text: catalog.i18nc("@title:tab", "Monitor")
property string iconSource: property string iconSource:
{ {
if(!printerConnected) if (!printerConnected)
{ {
return UM.Theme.getIcon("tab_status_unknown"); return UM.Theme.getIcon("tab_status_unknown");
} }
else if(!printerAcceptsCommands) else if (!printerAcceptsCommands)
{ {
return UM.Theme.getIcon("tab_status_unknown"); return UM.Theme.getIcon("tab_status_unknown");
} }
if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance") if (Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance")
{ {
return UM.Theme.getIcon("tab_status_busy"); return UM.Theme.getIcon("tab_status_busy");
} }
switch(Cura.MachineManager.printerOutputDevices[0].jobState) switch (Cura.MachineManager.printerOutputDevices[0].jobState)
{ {
case "printing": case "printing":
case "pre_print": case "pre_print":
@ -121,7 +124,6 @@ Rectangle
ExclusiveGroup { id: sidebarHeaderBarGroup } ExclusiveGroup { id: sidebarHeaderBarGroup }
} }
ToolButton ToolButton
{ {
id: machineSelection id: machineSelection
@ -142,28 +144,18 @@ Rectangle
if(control.pressed) if(control.pressed)
{ {
return UM.Theme.getColor("sidebar_header_active"); return UM.Theme.getColor("sidebar_header_active");
} else if(control.hovered) }
else if(control.hovered)
{ {
return UM.Theme.getColor("sidebar_header_hover"); return UM.Theme.getColor("sidebar_header_hover");
} else }
else
{ {
return UM.Theme.getColor("sidebar_header_bar"); return UM.Theme.getColor("sidebar_header_bar");
} }
} }
Behavior on color { ColorAnimation { duration: 50; } } Behavior on color { ColorAnimation { duration: 50; } }
Rectangle
{
id: underline;
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: UM.Theme.getSize("sidebar_header_highlight").height
color: UM.Theme.getColor("sidebar_header_highlight_hover")
visible: control.hovered || control.pressed
}
UM.RecolorImage UM.RecolorImage
{ {
id: downArrow id: downArrow
@ -196,4 +188,60 @@ Rectangle
menu: PrinterMenu { } menu: PrinterMenu { }
} }
ComboBox
{
id: viewModeButton
anchors
{
verticalCenter: parent.verticalCenter
right: parent.right
rightMargin: UM.Theme.getSize("sidebar").width + UM.Theme.getSize("default_margin").width
}
style: UM.Theme.styles.combobox
visible: !base.monitoringPrint
model: UM.ViewModel { }
textRole: "name"
onCurrentIndexChanged:
{
UM.Controller.setActiveView(model.getItem(currentIndex).id);
// Update the active flag
for (var i = 0; i < model.rowCount; ++i)
{
const is_active = i == currentIndex;
model.getItem(i).active = is_active;
}
}
currentIndex:
{
for (var i = 0; i < model.rowCount; ++i)
{
if (model.getItem(i).active)
{
return i;
}
}
return 0;
}
}
Loader
{
id: view_panel
anchors.top: viewModeButton.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.right: viewModeButton.right
property var buttonTarget: Qt.point(viewModeButton.x + viewModeButton.width / 2, viewModeButton.y + viewModeButton.height / 2)
height: childrenRect.height;
source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "";
}
} }

View File

@ -8,7 +8,7 @@ type = quality
material = generic_pla material = generic_pla
weight = 0 weight = 0
quality_type = normal quality_type = normal
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.2 layer_height = 0.2

View File

@ -8,7 +8,7 @@ type = quality
material = generic_pla material = generic_pla
weight = 1 weight = 1
quality_type = high quality_type = high
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.1 layer_height = 0.1

View File

@ -8,7 +8,7 @@ type = quality
material = generic_pla material = generic_pla
weight = 0 weight = 0
quality_type = normal quality_type = normal
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.2 layer_height = 0.2

View File

@ -8,7 +8,7 @@ type = quality
material = generic_pla material = generic_pla
weight = 0 weight = 0
quality_type = normal quality_type = normal
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.2 layer_height = 0.2

View File

@ -8,7 +8,7 @@ type = quality
material = generic_pla material = generic_pla
weight = 1 weight = 1
quality_type = high quality_type = high
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.1 layer_height = 0.1

View File

@ -8,7 +8,7 @@ type = quality
material = generic_pla material = generic_pla
weight = 0 weight = 0
quality_type = normal quality_type = normal
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.2 layer_height = 0.2

View File

@ -8,7 +8,7 @@ type = quality
material = generic_pla material = generic_pla
weight = 0 weight = 0
quality_type = normal quality_type = normal
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.2 layer_height = 0.2

View File

@ -7,7 +7,7 @@ type = quality
material = generic_pla material = generic_pla
weight = 1 weight = 1
quality_type = high quality_type = high
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.1 layer_height = 0.1

View File

@ -8,7 +8,7 @@ type = quality
material = generic_pla material = generic_pla
weight = 0 weight = 0
quality_type = normal quality_type = normal
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.2 layer_height = 0.2

View File

@ -8,7 +8,7 @@ type = quality
quality_type = high quality_type = high
material = generic_abs_175_cartesio_0.25_mm material = generic_abs_175_cartesio_0.25_mm
weight = 1 weight = 1
setting_version = 2 setting_version = 3
[values] [values]
infill_line_width = 0.3 infill_line_width = 0.3

View File

@ -8,7 +8,7 @@ type = quality
quality_type = normal quality_type = normal
material = generic_abs_175_cartesio_0.25_mm material = generic_abs_175_cartesio_0.25_mm
weight = 2 weight = 2
setting_version = 2 setting_version = 3
[values] [values]
infill_line_width = 0.3 infill_line_width = 0.3

View File

@ -8,7 +8,7 @@ type = quality
quality_type = high quality_type = high
material = generic_abs_175_cartesio_0.4_mm material = generic_abs_175_cartesio_0.4_mm
weight = 1 weight = 1
setting_version = 2 setting_version = 3
[values] [values]
infill_line_width = 0.5 infill_line_width = 0.5

View File

@ -8,7 +8,7 @@ type = quality
quality_type = normal quality_type = normal
material = generic_abs_175_cartesio_0.4_mm material = generic_abs_175_cartesio_0.4_mm
weight = 2 weight = 2
setting_version = 2 setting_version = 3
[values] [values]
infill_line_width = 0.5 infill_line_width = 0.5

View File

@ -8,7 +8,7 @@ type = quality
quality_type = coarse quality_type = coarse
material = generic_abs_175_cartesio_0.8_mm material = generic_abs_175_cartesio_0.8_mm
weight = 3 weight = 3
setting_version = 2 setting_version = 3
[values] [values]
infill_line_width = 0.9 infill_line_width = 0.9

View File

@ -8,7 +8,7 @@ type = quality
quality_type = extra coarse quality_type = extra coarse
material = generic_abs_175_cartesio_0.8_mm material = generic_abs_175_cartesio_0.8_mm
weight = 4 weight = 4
setting_version = 2 setting_version = 3
[values] [values]
infill_line_width = 0.9 infill_line_width = 0.9

View File

@ -8,7 +8,7 @@ type = quality
quality_type = high quality_type = high
material = generic_abs_175_cartesio_0.8_mm material = generic_abs_175_cartesio_0.8_mm
weight = 1 weight = 1
setting_version = 2 setting_version = 3
[values] [values]
infill_line_width = 0.9 infill_line_width = 0.9

View File

@ -8,7 +8,7 @@ type = quality
quality_type = normal quality_type = normal
material = generic_abs_175_cartesio_0.8_mm material = generic_abs_175_cartesio_0.8_mm
weight = 2 weight = 2
setting_version = 2 setting_version = 3
[values] [values]
infill_line_width = 0.9 infill_line_width = 0.9

View File

@ -8,7 +8,7 @@ type = quality
quality_type = high quality_type = high
material = dsm_arnitel2045_175_cartesio_0.4_mm material = dsm_arnitel2045_175_cartesio_0.4_mm
weight = 1 weight = 1
setting_version = 2 setting_version = 3
[values] [values]
infill_line_width = 0.5 infill_line_width = 0.5

View File

@ -8,7 +8,7 @@ type = quality
quality_type = normal quality_type = normal
material = dsm_arnitel2045_175_cartesio_0.4_mm material = dsm_arnitel2045_175_cartesio_0.4_mm
weight = 2 weight = 2
setting_version = 2 setting_version = 3
[values] [values]
infill_line_width = 0.5 infill_line_width = 0.5

View File

@ -8,7 +8,7 @@ type = quality
quality_type = coarse quality_type = coarse
global_quality = True global_quality = True
weight = 0 weight = 0
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.4 layer_height = 0.4

View File

@ -8,7 +8,7 @@ type = quality
quality_type = extra coarse quality_type = extra coarse
global_quality = True global_quality = True
weight = 0 weight = 0
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.6 layer_height = 0.6

View File

@ -8,7 +8,7 @@ type = quality
quality_type = high quality_type = high
global_quality = True global_quality = True
weight = 0 weight = 0
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.1 layer_height = 0.1

View File

@ -8,7 +8,7 @@ type = quality
quality_type = normal quality_type = normal
global_quality = True global_quality = True
weight = 0 weight = 0
setting_version = 2 setting_version = 3
[values] [values]
layer_height = 0.2 layer_height = 0.2

Some files were not shown because too many files have changed in this diff Show More