Merge branch 'master' into python_type_hinting

This commit is contained in:
Simon Edwards 2017-01-27 15:37:30 +01:00
commit eb43806d7a
51 changed files with 9425 additions and 219 deletions

View file

@ -32,16 +32,18 @@ PRIME_CLEARANCE = 6.5
## 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.
class BuildVolume(SceneNode): class BuildVolume(SceneNode):
VolumeOutlineColor = Color(12, 169, 227, 255)
XAxisColor = Color(255, 0, 0, 255)
YAxisColor = Color(0, 0, 255, 255)
ZAxisColor = Color(0, 255, 0, 255)
raftThicknessChanged = Signal() raftThicknessChanged = Signal()
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)
self._volume_outline_color = None
self._x_axis_color = None
self._y_axis_color = None
self._z_axis_color = None
self._disallowed_area_color = None
self._error_area_color = None
self._width = 0 self._width = 0
self._height = 0 self._height = 0
self._depth = 0 self._depth = 0
@ -73,6 +75,9 @@ class BuildVolume(SceneNode):
Application.getInstance().globalContainerStackChanged.connect(self._onStackChanged) Application.getInstance().globalContainerStackChanged.connect(self._onStackChanged)
self._onStackChanged() self._onStackChanged()
self._engine_ready = False
Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated)
self._has_errors = False self._has_errors = False
Application.getInstance().getController().getScene().sceneChanged.connect(self._onSceneChanged) Application.getInstance().getController().getScene().sceneChanged.connect(self._onSceneChanged)
@ -97,6 +102,7 @@ class BuildVolume(SceneNode):
# but it does not update the disallowed areas after material change # but it does not update the disallowed areas after material change
Application.getInstance().getMachineManager().activeStackChanged.connect(self._onStackChanged) Application.getInstance().getMachineManager().activeStackChanged.connect(self._onStackChanged)
def _onSceneChanged(self, source): def _onSceneChanged(self, source):
if self._global_container_stack: if self._global_container_stack:
self._change_timer.start() self._change_timer.start()
@ -156,6 +162,9 @@ 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._grid_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "grid.shader")) self._grid_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "grid.shader"))
theme = Application.getInstance().getTheme()
self._grid_shader.setUniformValue("u_gridColor0", Color(*theme.getColor("buildplate").getRgb()))
self._grid_shader.setUniformValue("u_gridColor1", Color(*theme.getColor("buildplate_alt").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)
@ -174,6 +183,18 @@ class BuildVolume(SceneNode):
if not self._width or not self._height or not self._depth: if not self._width or not self._height or not self._depth:
return return
if not Application.getInstance()._engine:
return
if not self._volume_outline_color:
theme = Application.getInstance().getTheme()
self._volume_outline_color = Color(*theme.getColor("volume_outline").getRgb())
self._x_axis_color = Color(*theme.getColor("x_axis").getRgb())
self._y_axis_color = Color(*theme.getColor("y_axis").getRgb())
self._z_axis_color = Color(*theme.getColor("z_axis").getRgb())
self._disallowed_area_color = Color(*theme.getColor("disallowed_area").getRgb())
self._error_area_color = Color(*theme.getColor("error_area").getRgb())
min_w = -self._width / 2 min_w = -self._width / 2
max_w = self._width / 2 max_w = self._width / 2
min_h = 0.0 min_h = 0.0
@ -186,20 +207,20 @@ class BuildVolume(SceneNode):
if self._shape != "elliptic": if self._shape != "elliptic":
# Outline 'cube' of the build volume # Outline 'cube' of the build volume
mb = MeshBuilder() mb = MeshBuilder()
mb.addLine(Vector(min_w, min_h, min_d), Vector(max_w, min_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(max_w, min_h, min_d), color = self._volume_outline_color)
mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, max_h, min_d), color = self._volume_outline_color)
mb.addLine(Vector(min_w, max_h, min_d), Vector(max_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(max_w, max_h, min_d), color = self._volume_outline_color)
mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, max_h, min_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, max_h, min_d), color = self._volume_outline_color)
mb.addLine(Vector(min_w, min_h, max_d), Vector(max_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(max_w, min_h, max_d), color = self._volume_outline_color)
mb.addLine(Vector(min_w, min_h, max_d), Vector(min_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, max_d), Vector(min_w, max_h, max_d), color = self._volume_outline_color)
mb.addLine(Vector(min_w, max_h, max_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, max_d), Vector(max_w, max_h, max_d), color = self._volume_outline_color)
mb.addLine(Vector(max_w, min_h, max_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, max_d), Vector(max_w, max_h, max_d), color = self._volume_outline_color)
mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, min_h, min_d), Vector(min_w, min_h, max_d), color = self._volume_outline_color)
mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, min_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, min_h, min_d), Vector(max_w, min_h, max_d), color = self._volume_outline_color)
mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(min_w, max_h, min_d), Vector(min_w, max_h, max_d), color = self._volume_outline_color)
mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color = self.VolumeOutlineColor) mb.addLine(Vector(max_w, max_h, min_d), Vector(max_w, max_h, max_d), color = self._volume_outline_color)
self.setMeshData(mb.build()) self.setMeshData(mb.build())
@ -226,8 +247,8 @@ class BuildVolume(SceneNode):
aspect = self._depth / self._width aspect = self._depth / self._width
scale_matrix.compose(scale = Vector(1, 1, aspect)) scale_matrix.compose(scale = Vector(1, 1, aspect))
mb = MeshBuilder() mb = MeshBuilder()
mb.addArc(max_w, Vector.Unit_Y, center = (0, min_h - z_fight_distance, 0), color = self.VolumeOutlineColor) mb.addArc(max_w, Vector.Unit_Y, center = (0, min_h - z_fight_distance, 0), color = self._volume_outline_color)
mb.addArc(max_w, Vector.Unit_Y, center = (0, max_h, 0), color = self.VolumeOutlineColor) 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 grid mesh # Build plate grid mesh
@ -258,21 +279,21 @@ class BuildVolume(SceneNode):
height = self._origin_line_width, height = self._origin_line_width,
depth = self._origin_line_width, depth = self._origin_line_width,
center = origin + Vector(self._origin_line_length / 2, 0, 0), center = origin + Vector(self._origin_line_length / 2, 0, 0),
color = self.XAxisColor color = self._x_axis_color
) )
mb.addCube( mb.addCube(
width = self._origin_line_width, width = self._origin_line_width,
height = self._origin_line_length, height = self._origin_line_length,
depth = self._origin_line_width, depth = self._origin_line_width,
center = origin + Vector(0, self._origin_line_length / 2, 0), center = origin + Vector(0, self._origin_line_length / 2, 0),
color = self.YAxisColor color = self._y_axis_color
) )
mb.addCube( mb.addCube(
width = self._origin_line_width, width = self._origin_line_width,
height = self._origin_line_width, height = self._origin_line_width,
depth = self._origin_line_length, depth = self._origin_line_length,
center = origin - Vector(0, 0, self._origin_line_length / 2), center = origin - Vector(0, 0, self._origin_line_length / 2),
color = self.ZAxisColor color = self._z_axis_color
) )
self._origin_mesh = mb.build() self._origin_mesh = mb.build()
@ -280,7 +301,7 @@ class BuildVolume(SceneNode):
disallowed_area_size = 0 disallowed_area_size = 0
if self._disallowed_areas: if self._disallowed_areas:
mb = MeshBuilder() mb = MeshBuilder()
color = Color(0.0, 0.0, 0.0, 0.15) color = self._disallowed_area_color
for polygon in self._disallowed_areas: for polygon in self._disallowed_areas:
points = polygon.getPoints() points = polygon.getPoints()
if len(points) == 0: if len(points) == 0:
@ -309,7 +330,7 @@ class BuildVolume(SceneNode):
if self._error_areas: if self._error_areas:
mb = MeshBuilder() mb = MeshBuilder()
for error_area in self._error_areas: for error_area in self._error_areas:
color = Color(1.0, 0.0, 0.0, 0.5) color = self._error_area_color
points = error_area.getPoints() points = error_area.getPoints()
first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height, first = Vector(self._clamp(points[0][0], min_w, max_w), disallowed_area_height,
self._clamp(points[0][1], min_d, max_d)) self._clamp(points[0][1], min_d, max_d))
@ -396,7 +417,12 @@ class BuildVolume(SceneNode):
self._updateDisallowedAreas() self._updateDisallowedAreas()
self._updateRaftThickness() self._updateRaftThickness()
self.rebuild() if self._engine_ready:
self.rebuild()
def _onEngineCreated(self):
self._engine_ready = True
self.rebuild()
def _onSettingPropertyChanged(self, setting_key, property_name): def _onSettingPropertyChanged(self, setting_key, property_name):
if property_name != "value": if property_name != "value":

View file

@ -1,6 +1,7 @@
# Copyright (c) 2015 Ultimaker B.V. # Copyright (c) 2015 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.
from UM.Application import Application
from UM.Scene.SceneNode import SceneNode from UM.Scene.SceneNode import SceneNode
from UM.Resources import Resources from UM.Resources import Resources
from UM.Math.Color import Color from UM.Math.Color import Color
@ -23,7 +24,7 @@ class ConvexHullNode(SceneNode):
self._original_parent = parent self._original_parent = parent
# Color of the drawn convex hull # Color of the drawn convex hull
self._color = Color(0.4, 0.4, 0.4, 1.0) self._color = None
# The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting. # The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting.
self._mesh_height = 0.1 self._mesh_height = 0.1
@ -72,7 +73,7 @@ class ConvexHullNode(SceneNode):
return True return True
def _onNodeDecoratorsChanged(self, node): def _onNodeDecoratorsChanged(self, node):
self._color = Color(35, 35, 35, 0.5) self._color = Color(*Application.getInstance().getTheme().getColor("convex_hull").getRgb())
convex_hull_head = self._node.callDecoration("getConvexHullHead") convex_hull_head = self._node.callDecoration("getConvexHullHead")
if convex_hull_head: if convex_hull_head:

View file

@ -234,10 +234,14 @@ class CuraApplication(QtApplication):
Preferences.getInstance().addPreference("cura/categories_expanded", "") Preferences.getInstance().addPreference("cura/categories_expanded", "")
Preferences.getInstance().addPreference("cura/jobname_prefix", True) Preferences.getInstance().addPreference("cura/jobname_prefix", True)
Preferences.getInstance().addPreference("view/center_on_select", False) Preferences.getInstance().addPreference("view/center_on_select", False)
Preferences.getInstance().addPreference("mesh/scale_to_fit", True) Preferences.getInstance().addPreference("mesh/scale_to_fit", False)
Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True) Preferences.getInstance().addPreference("mesh/scale_tiny_meshes", True)
Preferences.getInstance().addPreference("cura/dialog_on_project_save", True) Preferences.getInstance().addPreference("cura/dialog_on_project_save", True)
Preferences.getInstance().addPreference("cura/asked_dialog_on_project_save", False) Preferences.getInstance().addPreference("cura/asked_dialog_on_project_save", False)
Preferences.getInstance().addPreference("cura/currency", "")
Preferences.getInstance().addPreference("cura/material_settings", "{}")
for key in [ for key in [
"dialog_load_path", # dialog_save_path is in LocalFileOutputDevicePlugin "dialog_load_path", # dialog_save_path is in LocalFileOutputDevicePlugin
"dialog_profile_path", "dialog_profile_path",
@ -330,6 +334,11 @@ class CuraApplication(QtApplication):
showPrintMonitor = pyqtSignal(bool, arguments = ["show"]) showPrintMonitor = pyqtSignal(bool, arguments = ["show"])
def setViewLegendItems(self, items):
self.viewLegendItemsChanged.emit(items)
viewLegendItemsChanged = pyqtSignal("QVariantList", arguments = ["items"])
## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently. ## Cura has multiple locations where instance containers need to be saved, so we need to handle this differently.
# #
# Note that the AutoSave plugin also calls this method. # Note that the AutoSave plugin also calls this method.

View file

@ -1,4 +1,5 @@
from UM.Math.Color import Color from UM.Math.Color import Color
from UM.Application import Application
import numpy import numpy
@ -37,7 +38,7 @@ class LayerPolygon:
# Buffering the colors shouldn't be necessary as it is not # Buffering the colors shouldn't be necessary as it is not
# re-used and can save alot of memory usage. # re-used and can save alot of memory usage.
self._color_map = self.__color_map * [1, 1, 1, self._extruder] # The alpha component is used to store the extruder nr self._color_map = LayerPolygon.getColorMap() * [1, 1, 1, self._extruder] # The alpha component is used to store the extruder nr
self._colors = self._color_map[self._types] self._colors = self._color_map[self._types]
# When type is used as index returns true if type == LayerPolygon.InfillType or type == LayerPolygon.SkinType or type == LayerPolygon.SupportInfillType # When type is used as index returns true if type == LayerPolygon.InfillType or type == LayerPolygon.SkinType or type == LayerPolygon.SupportInfillType
@ -172,17 +173,25 @@ class LayerPolygon:
return normals return normals
# Should be generated in better way, not hardcoded. __color_map = None
__color_map = numpy.array([
[1.0, 1.0, 1.0, 1.0], # NoneType ## Gets the instance of the VersionUpgradeManager, or creates one.
[1.0, 0.0, 0.0, 1.0], # Inset0Type @classmethod
[0.0, 1.0, 0.0, 1.0], # InsetXType def getColorMap(cls):
[1.0, 1.0, 0.0, 1.0], # SkinType if cls.__color_map is None:
[0.0, 1.0, 1.0, 1.0], # SupportType theme = Application.getInstance().getTheme()
[0.0, 1.0, 1.0, 1.0], # SkirtType cls.__color_map = numpy.array([
[1.0, 0.75, 0.0, 1.0], # InfillType theme.getColor("layerview_none").getRgbF(), # NoneType
[0.0, 1.0, 1.0, 1.0], # SupportInfillType theme.getColor("layerview_inset_0").getRgbF(), # Inset0Type
[0.0, 0.0, 1.0, 1.0], # MoveCombingType theme.getColor("layerview_inset_x").getRgbF(), # InsetXType
[0.5, 0.5, 1.0, 1.0], # MoveRetractionType theme.getColor("layerview_skin").getRgbF(), # SkinType
[0.25, 0.75, 1.0, 1.0] # SupportInterfaceType theme.getColor("layerview_support").getRgbF(), # SupportType
]) theme.getColor("layerview_skirt").getRgbF(), # SkirtType
theme.getColor("layerview_infill").getRgbF(), # InfillType
theme.getColor("layerview_support_infill").getRgbF(), # SupportInfillType
theme.getColor("layerview_move_combing").getRgbF(), # MoveCombingType
theme.getColor("layerview_move_retraction").getRgbF(), # MoveRetractionType
theme.getColor("layerview_support_interface").getRgbF() # SupportInterfaceType
])
return cls.__color_map

View file

@ -7,12 +7,14 @@ from UM.FlameProfiler import pyqtSlot
from UM.Application import Application from UM.Application import Application
from UM.Qt.Duration import Duration from UM.Qt.Duration import Duration
from UM.Preferences import Preferences from UM.Preferences import Preferences
from UM.Settings import ContainerRegistry
from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderManager import ExtruderManager
import math import math
import os.path import os.path
import unicodedata import unicodedata
import json
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
@ -52,6 +54,7 @@ class PrintInformation(QObject):
self._material_lengths = [] self._material_lengths = []
self._material_weights = [] self._material_weights = []
self._material_costs = []
self._pre_sliced = False self._pre_sliced = False
@ -65,6 +68,12 @@ class PrintInformation(QObject):
Application.getInstance().globalContainerStackChanged.connect(self._setAbbreviatedMachineName) Application.getInstance().globalContainerStackChanged.connect(self._setAbbreviatedMachineName)
Application.getInstance().fileLoaded.connect(self.setJobName) Application.getInstance().fileLoaded.connect(self.setJobName)
Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged)
self._active_material_container = None
Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._onActiveMaterialChanged)
self._onActiveMaterialChanged()
currentPrintTimeChanged = pyqtSignal() currentPrintTimeChanged = pyqtSignal()
preSlicedChanged = pyqtSignal() preSlicedChanged = pyqtSignal()
@ -93,28 +102,83 @@ class PrintInformation(QObject):
def materialWeights(self): def materialWeights(self):
return self._material_weights return self._material_weights
materialCostsChanged = pyqtSignal()
@pyqtProperty("QVariantList", notify = materialCostsChanged)
def materialCosts(self):
return self._material_costs
def _onPrintDurationMessage(self, total_time, material_amounts): def _onPrintDurationMessage(self, total_time, material_amounts):
self._current_print_time.setDuration(total_time) self._current_print_time.setDuration(total_time)
self.currentPrintTimeChanged.emit() self.currentPrintTimeChanged.emit()
self._material_amounts = material_amounts
self._calculateInformation()
def _calculateInformation(self):
# Material amount is sent as an amount of mm^3, so calculate length from that # Material amount is sent as an amount of mm^3, so calculate length from that
r = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2 r = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2
self._material_lengths = [] self._material_lengths = []
self._material_weights = [] self._material_weights = []
self._material_costs = []
material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings"))
extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(Application.getInstance().getGlobalContainerStack().getId())) extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(Application.getInstance().getGlobalContainerStack().getId()))
for index, amount in enumerate(material_amounts): for index, amount in enumerate(self._material_amounts):
## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some ## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some
# list comprehension filtering to solve this for us. # list comprehension filtering to solve this for us.
material = None
if extruder_stacks: # Multi extrusion machine if extruder_stacks: # Multi extrusion machine
extruder_stack = [extruder for extruder in extruder_stacks if extruder.getMetaDataEntry("position") == str(index)][0] extruder_stack = [extruder for extruder in extruder_stacks if extruder.getMetaDataEntry("position") == str(index)][0]
density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0) density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0)
material = extruder_stack.findContainer({"type": "material"})
else: # Machine with no extruder stacks else: # Machine with no extruder stacks
density = Application.getInstance().getGlobalContainerStack().getMetaDataEntry("properties", {}).get("density", 0) density = Application.getInstance().getGlobalContainerStack().getMetaDataEntry("properties", {}).get("density", 0)
material = Application.getInstance().getGlobalContainerStack().findContainer({"type": "material"})
self._material_weights.append(float(amount) * float(density) / 1000) weight = float(amount) * float(density) / 1000
cost = 0
if material:
material_guid = material.getMetaDataEntry("GUID")
if material_guid in material_preference_values:
material_values = material_preference_values[material_guid]
weight_per_spool = float(material_values["spool_weight"] if material_values and "spool_weight" in material_values else 0)
cost_per_spool = float(material_values["spool_cost"] if material_values and "spool_cost" in material_values else 0)
if weight_per_spool != 0:
cost = cost_per_spool * weight / weight_per_spool
else:
cost = 0
self._material_weights.append(weight)
self._material_lengths.append(round((amount / (math.pi * r ** 2)) / 1000, 2)) self._material_lengths.append(round((amount / (math.pi * r ** 2)) / 1000, 2))
self._material_costs.append(cost)
self.materialLengthsChanged.emit() self.materialLengthsChanged.emit()
self.materialWeightsChanged.emit() self.materialWeightsChanged.emit()
self.materialCostsChanged.emit()
def _onPreferencesChanged(self, preference):
if preference != "cura/material_settings":
return
self._calculateInformation()
def _onActiveMaterialChanged(self):
if self._active_material_container:
self._active_material_container.metaDataChanged.disconnect(self._onMaterialMetaDataChanged)
active_material_id = Application.getInstance().getMachineManager().activeMaterialId
active_material_containers = ContainerRegistry.getInstance().findInstanceContainers(id=active_material_id)
if active_material_containers:
self._active_material_container = active_material_containers[0]
self._active_material_container.metaDataChanged.connect(self._onMaterialMetaDataChanged)
def _onMaterialMetaDataChanged(self):
self._calculateInformation()
@pyqtSlot(str) @pyqtSlot(str)
def setJobName(self, name): def setJobName(self, name):

View file

@ -22,6 +22,8 @@ To open the profiler go to the Extensions menu and select "Start BFG" from the "
The time scale is at the top of the window. The blocks should be read as meaning the blocks at the bottom call the blocks which are stacked on top of them. Hover the mouse to get more detailed information about a block such as the name of the code involved and its duration. Use the zoom buttons or mouse wheel to zoom in. The display can be panned by dragging with the left mouse button. The time scale is at the top of the window. The blocks should be read as meaning the blocks at the bottom call the blocks which are stacked on top of them. Hover the mouse to get more detailed information about a block such as the name of the code involved and its duration. Use the zoom buttons or mouse wheel to zoom in. The display can be panned by dragging with the left mouse button.
Note: The profiler front-end itself is quite "heavy" (ok, not optimised). It runs much better in Google Chrome or Chromium than Firefox. It is also a good idea to keep recording sessions short for the same reason.
What the Profiler Sees What the Profiler Sees
---------------------- ----------------------

View file

@ -119,7 +119,7 @@ class ThreeMFReader(MeshReader):
Job.yieldThread() Job.yieldThread()
# TODO: We currently do not check for normals and simply recalculate them. # TODO: We currently do not check for normals and simply recalculate them.
mesh_builder.calculateNormals() mesh_builder.calculateNormals(fast=True)
mesh_builder.setFileName(name) mesh_builder.setFileName(name)
mesh_data = mesh_builder.build() mesh_data = mesh_builder.build()

View file

@ -70,8 +70,9 @@ class WorkspaceDialog(QObject):
return self._variant_type return self._variant_type
def setVariantType(self, variant_type): def setVariantType(self, variant_type):
self._variant_type = variant_type if self._variant_type != variant_type:
self.variantTypeChanged.emit() self._variant_type = variant_type
self.variantTypeChanged.emit()
@pyqtProperty(str, notify=machineTypeChanged) @pyqtProperty(str, notify=machineTypeChanged)
def machineType(self): def machineType(self):
@ -82,8 +83,9 @@ class WorkspaceDialog(QObject):
self.machineTypeChanged.emit() self.machineTypeChanged.emit()
def setNumUserSettings(self, num_user_settings): def setNumUserSettings(self, num_user_settings):
self._num_user_settings = num_user_settings if self._num_user_settings != num_user_settings:
self.numVisibleSettingsChanged.emit() self._num_user_settings = num_user_settings
self.numVisibleSettingsChanged.emit()
@pyqtProperty(int, notify=numUserSettingsChanged) @pyqtProperty(int, notify=numUserSettingsChanged)
def numUserSettings(self): def numUserSettings(self):
@ -94,40 +96,45 @@ class WorkspaceDialog(QObject):
return self._objects_on_plate return self._objects_on_plate
def setHasObjectsOnPlate(self, objects_on_plate): def setHasObjectsOnPlate(self, objects_on_plate):
self._objects_on_plate = objects_on_plate if self._objects_on_plate != objects_on_plate:
self.objectsOnPlateChanged.emit() self._objects_on_plate = objects_on_plate
self.objectsOnPlateChanged.emit()
@pyqtProperty("QVariantList", notify = materialLabelsChanged) @pyqtProperty("QVariantList", notify = materialLabelsChanged)
def materialLabels(self): def materialLabels(self):
return self._material_labels return self._material_labels
def setMaterialLabels(self, material_labels): def setMaterialLabels(self, material_labels):
self._material_labels = material_labels if self._material_labels != material_labels:
self.materialLabelsChanged.emit() self._material_labels = material_labels
self.materialLabelsChanged.emit()
@pyqtProperty("QVariantList", notify=extrudersChanged) @pyqtProperty("QVariantList", notify=extrudersChanged)
def extruders(self): def extruders(self):
return self._extruders return self._extruders
def setExtruders(self, extruders): def setExtruders(self, extruders):
self._extruders = extruders if self._extruders != extruders:
self.extrudersChanged.emit() self._extruders = extruders
self.extrudersChanged.emit()
@pyqtProperty(str, notify = machineNameChanged) @pyqtProperty(str, notify = machineNameChanged)
def machineName(self): def machineName(self):
return self._machine_name return self._machine_name
def setMachineName(self, machine_name): def setMachineName(self, machine_name):
self._machine_name = machine_name if self._machine_name != machine_name:
self.machineNameChanged.emit() self._machine_name = machine_name
self.machineNameChanged.emit()
@pyqtProperty(str, notify=qualityTypeChanged) @pyqtProperty(str, notify=qualityTypeChanged)
def qualityType(self): def qualityType(self):
return self._quality_type return self._quality_type
def setQualityType(self, quality_type): def setQualityType(self, quality_type):
self._quality_type = quality_type if self._quality_type != quality_type:
self.qualityTypeChanged.emit() self._quality_type = quality_type
self.qualityTypeChanged.emit()
@pyqtProperty(int, notify=numSettingsOverridenByQualityChangesChanged) @pyqtProperty(int, notify=numSettingsOverridenByQualityChangesChanged)
def numSettingsOverridenByQualityChanges(self): def numSettingsOverridenByQualityChanges(self):
@ -142,8 +149,9 @@ class WorkspaceDialog(QObject):
return self._quality_name return self._quality_name
def setQualityName(self, quality_name): def setQualityName(self, quality_name):
self._quality_name = quality_name if self._quality_name != quality_name:
self.qualityNameChanged.emit() self._quality_name = quality_name
self.qualityNameChanged.emit()
@pyqtProperty(str, notify=activeModeChanged) @pyqtProperty(str, notify=activeModeChanged)
def activeMode(self): def activeMode(self):
@ -165,8 +173,9 @@ class WorkspaceDialog(QObject):
return self._num_visible_settings return self._num_visible_settings
def setNumVisibleSettings(self, num_visible_settings): def setNumVisibleSettings(self, num_visible_settings):
self._num_visible_settings = num_visible_settings if self._num_visible_settings != num_visible_settings:
self.numVisibleSettingsChanged.emit() self._num_visible_settings = num_visible_settings
self.numVisibleSettingsChanged.emit()
@pyqtProperty(bool, notify = machineConflictChanged) @pyqtProperty(bool, notify = machineConflictChanged)
def machineConflict(self): def machineConflict(self):
@ -191,16 +200,19 @@ class WorkspaceDialog(QObject):
Application.getInstance().getBackend().close() Application.getInstance().getBackend().close()
def setMaterialConflict(self, material_conflict): def setMaterialConflict(self, material_conflict):
self._has_material_conflict = material_conflict if self._has_material_conflict != material_conflict:
self.materialConflictChanged.emit() self._has_material_conflict = material_conflict
self.materialConflictChanged.emit()
def setMachineConflict(self, machine_conflict): def setMachineConflict(self, machine_conflict):
self._has_machine_conflict = machine_conflict if self._has_machine_conflict != machine_conflict:
self.machineConflictChanged.emit() self._has_machine_conflict = machine_conflict
self.machineConflictChanged.emit()
def setQualityChangesConflict(self, quality_changes_conflict): def setQualityChangesConflict(self, quality_changes_conflict):
self._has_quality_changes_conflict = quality_changes_conflict if self._has_quality_changes_conflict != quality_changes_conflict:
self.qualityChangesConflictChanged.emit() self._has_quality_changes_conflict = quality_changes_conflict
self.qualityChangesConflictChanged.emit()
def getResult(self): def getResult(self):
if "machine" in self._result and not self._has_machine_conflict: if "machine" in self._result and not self._has_machine_conflict:

View file

@ -46,7 +46,7 @@ class ThreeMFWriter(MeshWriter):
result += str(matrix._data[2,2]) + " " result += str(matrix._data[2,2]) + " "
result += str(matrix._data[0,3]) + " " result += str(matrix._data[0,3]) + " "
result += str(matrix._data[1,3]) + " " result += str(matrix._data[1,3]) + " "
result += str(matrix._data[2,3]) + " " result += str(matrix._data[2,3])
return result return result
## Should we store the archive ## Should we store the archive
@ -80,10 +80,11 @@ class ThreeMFWriter(MeshWriter):
model_relation_element = ET.SubElement(relations_element, "Relationship", Target = "/3D/3dmodel.model", Id = "rel0", Type = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel") model_relation_element = ET.SubElement(relations_element, "Relationship", Target = "/3D/3dmodel.model", Id = "rel0", Type = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel")
model = ET.Element("model", unit = "millimeter", xmlns = self._namespaces["3mf"]) model = ET.Element("model", unit = "millimeter", xmlns = self._namespaces["3mf"])
model.set("xmlns:cura", self._namespaces["cura"])
# Add the version of Cura this was created with. As "CuraVersion" is not a recognised metadata name # Add the version of Cura this was created with. Since there is no "version" or similar metadata name we need
# by 3mf itself, we place it in our own namespace. # to prefix it with the cura namespace, as specified by the 3MF specification.
version_metadata = ET.SubElement(model, "metadata", xmlns = self._namespaces["cura"], name = "CuraVersion") version_metadata = ET.SubElement(model, "metadata", name = "cura:version")
version_metadata.text = Application.getInstance().getVersion() version_metadata.text = Application.getInstance().getVersion()
resources = ET.SubElement(model, "resources") resources = ET.SubElement(model, "resources")

View file

@ -98,6 +98,9 @@ Use a mesh to specify a volume within which to classify nothing as overhang for
*Delta printer support *Delta printer support
This release adds support for printers with elliptic buildplates. This feature has not been extensively tested so please let us know if it works or get involved in improving it. This release adds support for printers with elliptic buildplates. This feature has not been extensively tested so please let us know if it works or get involved in improving it.
*AppImage for Linux
The Linux distribution is now in AppImage format, which makes Cura easier to install.
*bugfixes *bugfixes
The user is now notified when a new version of Cura is available. The user is now notified when a new version of Cura is available.
When searching in the setting visibility preferences, the category for each setting is always displayed. When searching in the setting visibility preferences, the category for each setting is always displayed.
@ -122,6 +125,8 @@ There are no more unnecessary retractions in support.
Each layer now has less extruder switches than the machine has extruders. Each layer now has less extruder switches than the machine has extruders.
Concentric infill doesnt generate the first infill perimeter next to the walls. Concentric infill doesnt generate the first infill perimeter next to the walls.
Extruder priming now always happens on the first layer. Extruder priming now always happens on the first layer.
Raising the build plate of the Ultimaker 2 now has the proper speed again.
Changing material while the Ultimaker 2 is paused works again.
[2.3.1] [2.3.1]
*Layer Height in Profile Selection *Layer Height in Profile Selection

View file

@ -12,11 +12,9 @@ UM.Dialog
{ {
width: 350 * Screen.devicePixelRatio; width: 350 * Screen.devicePixelRatio;
minimumWidth: 350 * Screen.devicePixelRatio; minimumWidth: 350 * Screen.devicePixelRatio;
maximumWidth: 350 * Screen.devicePixelRatio;
height: 250 * Screen.devicePixelRatio; height: 250 * Screen.devicePixelRatio;
minimumHeight: 250 * Screen.devicePixelRatio; minimumHeight: 250 * Screen.devicePixelRatio;
maximumHeight: 250 * Screen.devicePixelRatio;
title: catalog.i18nc("@title:window", "Convert Image...") title: catalog.i18nc("@title:window", "Convert Image...")
@ -158,11 +156,10 @@ UM.Dialog
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
Rectangle { Item {
width: 180 width: 180
height: 20 height: 20
Layout.fillWidth:true Layout.fillWidth: true
color: "transparent"
Slider { Slider {
id: smoothing id: smoothing

View file

@ -60,6 +60,8 @@ class LayerView(View):
self._proxy = LayerViewProxy.LayerViewProxy() self._proxy = LayerViewProxy.LayerViewProxy()
self._controller.getScene().getRoot().childrenChanged.connect(self._onSceneChanged) self._controller.getScene().getRoot().childrenChanged.connect(self._onSceneChanged)
self._legend_items = None
Preferences.getInstance().addPreference("view/top_layer_count", 5) Preferences.getInstance().addPreference("view/top_layer_count", 5)
Preferences.getInstance().addPreference("view/only_show_top_layers", False) Preferences.getInstance().addPreference("view/only_show_top_layers", False)
Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged) Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged)
@ -110,7 +112,7 @@ class LayerView(View):
if not self._ghost_shader: if not self._ghost_shader:
self._ghost_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader")) self._ghost_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader"))
self._ghost_shader.setUniformValue("u_color", Color(32, 32, 32, 96)) self._ghost_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("layerview_ghost").getRgb()))
for node in DepthFirstIterator(scene.getRoot()): for node in DepthFirstIterator(scene.getRoot()):
# We do not want to render ConvexHullNode as it conflicts with the bottom layers. # We do not want to render ConvexHullNode as it conflicts with the bottom layers.
@ -194,6 +196,9 @@ class LayerView(View):
if not self._layerview_composite_shader: if not self._layerview_composite_shader:
self._layerview_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("LayerView"), "layerview_composite.shader")) self._layerview_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("LayerView"), "layerview_composite.shader"))
theme = Application.getInstance().getTheme()
self._layerview_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb()))
self._layerview_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))
if not self._composite_pass: if not self._composite_pass:
self._composite_pass = self.getRenderer().getRenderPass("composite") self._composite_pass = self.getRenderer().getRenderPass("composite")
@ -203,6 +208,8 @@ class LayerView(View):
self._old_composite_shader = self._composite_pass.getCompositeShader() self._old_composite_shader = self._composite_pass.getCompositeShader()
self._composite_pass.setCompositeShader(self._layerview_composite_shader) self._composite_pass.setCompositeShader(self._layerview_composite_shader)
Application.getInstance().setViewLegendItems(self._getLegendItems())
elif event.type == Event.ViewDeactivateEvent: elif event.type == Event.ViewDeactivateEvent:
self._wireprint_warning_message.hide() self._wireprint_warning_message.hide()
Application.getInstance().globalContainerStackChanged.disconnect(self._onGlobalStackChanged) Application.getInstance().globalContainerStackChanged.disconnect(self._onGlobalStackChanged)
@ -212,6 +219,8 @@ class LayerView(View):
self._composite_pass.setLayerBindings(self._old_layer_bindings) self._composite_pass.setLayerBindings(self._old_layer_bindings)
self._composite_pass.setCompositeShader(self._old_composite_shader) self._composite_pass.setCompositeShader(self._old_composite_shader)
Application.getInstance().setViewLegendItems([])
def _onGlobalStackChanged(self): def _onGlobalStackChanged(self):
if self._global_container_stack: if self._global_container_stack:
self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged) self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged)
@ -261,6 +270,24 @@ class LayerView(View):
self._startUpdateTopLayers() self._startUpdateTopLayers()
def _getLegendItems(self):
if self._legend_items is None:
theme = Application.getInstance().getTheme()
self._legend_items = [
{"color": theme.getColor("layerview_inset_0").name(), "title": catalog.i18nc("@label:layerview polygon type", "Outer Wall")}, # Inset0Type
{"color": theme.getColor("layerview_inset_x").name(), "title": catalog.i18nc("@label:layerview polygon type", "Inner Wall")}, # InsetXType
{"color": theme.getColor("layerview_skin").name(), "title": catalog.i18nc("@label:layerview polygon type", "Top / Bottom")}, # SkinType
{"color": theme.getColor("layerview_infill").name(), "title": catalog.i18nc("@label:layerview polygon type", "Infill")}, # InfillType
{"color": theme.getColor("layerview_support").name(), "title": catalog.i18nc("@label:layerview polygon type", "Support Skin")}, # SupportType
{"color": theme.getColor("layerview_support_infill").name(), "title": catalog.i18nc("@label:layerview polygon type", "Support Infill")}, # SupportInfillType
{"color": theme.getColor("layerview_support_interface").name(), "title": catalog.i18nc("@label:layerview polygon type", "Support Interface")}, # SupportInterfaceType
{"color": theme.getColor("layerview_skirt").name(), "title": catalog.i18nc("@label:layerview polygon type", "Build Plate Adhesion")}, # SkirtType
{"color": theme.getColor("layerview_move_combing").name(), "title": catalog.i18nc("@label:layerview polygon type", "Travel Move")}, # MoveCombingType
{"color": theme.getColor("layerview_move_retraction").name(), "title": catalog.i18nc("@label:layerview polygon type", "Retraction Move")}, # MoveRetractionType
#{"color": theme.getColor("layerview_none").name(), "title": catalog.i18nc("@label:layerview polygon type", "Unknown")} # NoneType
]
return self._legend_items
class _CreateTopLayersJob(Job): class _CreateTopLayersJob(Job):
def __init__(self, scene, layer_number, solid_layers): def __init__(self, scene, layer_number, solid_layers):

View file

@ -41,8 +41,9 @@ Item
width: valueLabel.width + UM.Theme.getSize("default_margin").width width: valueLabel.width + UM.Theme.getSize("default_margin").width
Behavior on height { NumberAnimation { duration: 50; } } Behavior on height { NumberAnimation { duration: 50; } }
border.width: UM.Theme.getSize("default_lining").width; border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("slider_groove_border"); border.color: UM.Theme.getColor("slider_groove_border")
color: UM.Theme.getColor("tool_panel_background")
visible: UM.LayerView.getLayerActivity && Printer.getPlatformActivity ? true : false visible: UM.LayerView.getLayerActivity && Printer.getPlatformActivity ? true : false

View file

@ -9,7 +9,7 @@ from UM.Application import Application
from UM.Preferences import Preferences from UM.Preferences import Preferences
from UM.View.Renderer import Renderer from UM.View.Renderer import Renderer
from UM.Settings.Validator import ValidatorState from UM.Settings.Validator import ValidatorState
from UM.Math.Color import Color
from UM.View.GL.OpenGL import OpenGL from UM.View.GL.OpenGL import OpenGL
from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderManager import ExtruderManager
@ -36,11 +36,14 @@ class SolidView(View):
if not self._enabled_shader: if not self._enabled_shader:
self._enabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader")) self._enabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader"))
theme = Application.getInstance().getTheme()
self._enabled_shader.setUniformValue("u_overhangColor", Color(*theme.getColor("model_overhang").getRgb()))
if not self._disabled_shader: if not self._disabled_shader:
self._disabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "striped.shader")) self._disabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "striped.shader"))
self._disabled_shader.setUniformValue("u_diffuseColor1", [0.48, 0.48, 0.48, 1.0]) theme = Application.getInstance().getTheme()
self._disabled_shader.setUniformValue("u_diffuseColor2", [0.68, 0.68, 0.68, 1.0]) self._disabled_shader.setUniformValue("u_diffuseColor1", Color(*theme.getColor("model_unslicable").getRgb()))
self._disabled_shader.setUniformValue("u_diffuseColor2", Color(*theme.getColor("model_unslicable_alt").getRgb()))
self._disabled_shader.setUniformValue("u_width", 50.0) self._disabled_shader.setUniformValue("u_width", 50.0)
multi_extrusion = False multi_extrusion = False
@ -89,7 +92,7 @@ class SolidView(View):
extruder_index = max(0, self._extruders_model.find("id", extruder_id)) extruder_index = max(0, self._extruders_model.find("id", extruder_id))
try: try:
material_color = self._extruders_model.getItem(extruder_index)["color"] material_color = self._extruders_model.getItem(extruder_index)["color"]
except KeyError: except KeyError:
material_color = self._extruders_model.defaultColors[0] material_color = self._extruders_model.defaultColors[0]
if extruder_index != ExtruderManager.getInstance().activeExtruderIndex: if extruder_index != ExtruderManager.getInstance().activeExtruderIndex:

View file

@ -3,6 +3,8 @@
import os.path import os.path
from UM.Application import Application
from UM.Math.Color import Color
from UM.PluginRegistry import PluginRegistry from UM.PluginRegistry import PluginRegistry
from UM.Event import Event from UM.Event import Event
from UM.View.View import View from UM.View.View import View
@ -31,7 +33,7 @@ class XRayView(View):
if not self._xray_shader: if not self._xray_shader:
self._xray_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray.shader")) self._xray_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray.shader"))
self._xray_shader.setUniformValue("u_color", [0.1, 0.1, 0.2, 1.0]) self._xray_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("xray").getRgb()))
for node in BreadthFirstIterator(scene.getRoot()): for node in BreadthFirstIterator(scene.getRoot()):
if not node.render(renderer): if not node.render(renderer):
@ -58,6 +60,10 @@ class XRayView(View):
if not self._xray_composite_shader: if not self._xray_composite_shader:
self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray_composite.shader")) self._xray_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("XRayView"), "xray_composite.shader"))
theme = Application.getInstance().getTheme()
self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb()))
self._xray_composite_shader.setUniformValue("u_error_color", Color(*theme.getColor("xray_error").getRgb()))
self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))
if not self._composite_pass: if not self._composite_pass:
self._composite_pass = self.getRenderer().getRenderPass("composite") self._composite_pass = self.getRenderer().getRenderPass("composite")

View file

@ -22,6 +22,7 @@ fragment =
uniform float u_outline_strength; uniform float u_outline_strength;
uniform vec4 u_outline_color; uniform vec4 u_outline_color;
uniform vec4 u_error_color; uniform vec4 u_error_color;
uniform vec4 u_background_color;
const vec3 x_axis = vec3(1.0, 0.0, 0.0); const vec3 x_axis = vec3(1.0, 0.0, 0.0);
const vec3 y_axis = vec3(0.0, 1.0, 0.0); const vec3 y_axis = vec3(0.0, 1.0, 0.0);
@ -37,7 +38,7 @@ fragment =
kernel[3] = 1.0; kernel[4] = -4.0; kernel[5] = 1.0; kernel[3] = 1.0; kernel[4] = -4.0; kernel[5] = 1.0;
kernel[6] = 0.0; kernel[7] = 1.0; kernel[8] = 0.0; kernel[6] = 0.0; kernel[7] = 1.0; kernel[8] = 0.0;
vec4 result = vec4(0.965, 0.965, 0.965, 1.0); vec4 result = u_background_color;
vec4 layer0 = texture2D(u_layer0, v_uvs); vec4 layer0 = texture2D(u_layer0, v_uvs);
result = layer0 * layer0.a + result * (1.0 - layer0.a); result = layer0 * layer0.a + result * (1.0 - layer0.a);
@ -70,6 +71,7 @@ fragment =
u_layer0 = 0 u_layer0 = 0
u_layer1 = 1 u_layer1 = 1
u_layer2 = 2 u_layer2 = 2
u_background_color = [0.965, 0.965, 0.965, 1.0]
u_outline_strength = 1.0 u_outline_strength = 1.0
u_outline_color = [0.05, 0.66, 0.89, 1.0] u_outline_color = [0.05, 0.66, 0.89, 1.0]
u_error_color = [1.0, 0.0, 0.0, 1.0] u_error_color = [1.0, 0.0, 0.0, 1.0]

View file

@ -1230,6 +1230,16 @@
"default_value": true, "default_value": true,
"enabled": "infill_sparse_density > 0", "enabled": "infill_sparse_density > 0",
"settable_per_mesh": true "settable_per_mesh": true
},
"min_infill_area":
{
"label": "Minimum Infill Area",
"description": "Don't generate areas of infill smaller than this (use skin instead).",
"unit": "mm²",
"type": "float",
"minimum_value": "0",
"default_value": 0,
"settable_per_mesh": true
} }
} }
}, },
@ -1373,9 +1383,9 @@
"type": "float", "type": "float",
"resolve": "max(extruderValues('material_bed_temperature_layer_0'))", "resolve": "max(extruderValues('material_bed_temperature_layer_0'))",
"default_value": 60, "default_value": 60,
"value": "material_bed_temperature", "value": "resolveOrValue('material_bed_temperature')",
"minimum_value": "-273.15", "minimum_value": "-273.15",
"minimum_value_warning": "0", "minimum_value_warning": "max(extruderValues('material_bed_temperature'))",
"maximum_value_warning": "260", "maximum_value_warning": "260",
"enabled": "machine_heated_bed and machine_gcode_flavor != \"UltiGCode\"", "enabled": "machine_heated_bed and machine_gcode_flavor != \"UltiGCode\"",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -3854,6 +3864,7 @@
"description": "Enable exterior ooze shield. This will create a shell around the model which is likely to wipe a second nozzle if it's at the same height as the first nozzle.", "description": "Enable exterior ooze shield. This will create a shell around the model which is likely to wipe a second nozzle if it's at the same height as the first nozzle.",
"type": "bool", "type": "bool",
"resolve": "any(extruderValues('ooze_shield_enabled'))", "resolve": "any(extruderValues('ooze_shield_enabled'))",
"enabled": "machine_extruder_count > 1",
"default_value": false, "default_value": false,
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false "settable_per_extruder": false

View file

@ -45,7 +45,7 @@
"default_value": "RepRap (Marlin/Sprinter)" "default_value": "RepRap (Marlin/Sprinter)"
}, },
"machine_start_gcode": { "machine_start_gcode": {
"default_value": "; info: M303 E0 S200 C8 ; Pid auto-tune \n\nM140 S{{material_bed_temperature}}; Start heating up the base\nG28 ; Home to top 3 endstops\n; Autolevel and adjust first layer\n; Adjust this value to fit your own printer! (positive is thicker)\n; This default value is intentionally very high to accommodate the\n; variety of print heads used with this printer. Many of you will\n; need tiny values like Z0 or Z0.1. Use feeler gauges to dial this\n; in as accurately as possible.\nG29 Z10\n\n; Squirt and wipe ;\nM109 S220 ; Wait for the temp to hit 220\nG00 X125 Y-60 Z0.1 ;\nG92 E0 ;\nG01 E25 F100 ; Extrude a little bit to replace oozage from auto levelling\nG01 X90 Y-50 F6000 ;\nG01 Z5 ;\n\n; Set the extruder to the requested print temperature\nM104 S{{material_print_temperature}}\n" "default_value": "; info: M303 E0 S200 C8 ; Pid auto-tune \n\nM140 S{material_bed_temperature}; Start heating up the base\nG28 ; Home to top 3 endstops\n; Autolevel and adjust first layer\n; Adjust this value to fit your own printer! (positive is thicker)\n; This default value is intentionally very high to accommodate the\n; variety of print heads used with this printer. Many of you will\n; need tiny values like Z0 or Z0.1. Use feeler gauges to dial this\n; in as accurately as possible.\nG29 Z10\n\n; Squirt and wipe ;\nM109 S220 ; Wait for the temp to hit 220\nG00 X125 Y-60 Z0.1 ;\nG92 E0 ;\nG01 E25 F100 ; Extrude a little bit to replace oozage from auto levelling\nG01 X90 Y-50 F6000 ;\nG01 Z5 ;\n\n; Set the extruder to the requested print temperature\nM104 S{material_print_temperature}\n"
}, },
"machine_end_gcode": { "machine_end_gcode": {
"default_value": "M104 S0 ; turn off temperature\nM140 S0 ; turn off bed\nG28 ; home all axes\nM84 ; disable motors\n" "default_value": "M104 S0 ; turn off temperature\nM140 S0 ; turn off bed\nG28 ; home all axes\nM84 ; disable motors\n"
@ -54,4 +54,4 @@
"default_value": "elliptic" "default_value": "elliptic"
} }
} }
} }

View file

@ -39,7 +39,7 @@
"default_value": "RepRap (Marlin/Sprinter)" "default_value": "RepRap (Marlin/Sprinter)"
}, },
"machine_start_gcode": { "machine_start_gcode": {
"default_value": ";Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;M190 S{material_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{material_print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{travel_speed} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{speed_travel}\n;Put printing message on LCD screen\nM117 Rigibot Printing..." "default_value": ";Basic settings: Layer height: {layer_height} Walls: {wall_thickness} Fill: {infill_sparse_density}\n;M190 S{material_bed_temperature} ;Uncomment to add your own bed temperature line\n;M109 S{material_print_temperature} ;Uncomment to add your own temperature line\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM205 X8 ;X/Y Jerk settings\nG1 Z15.0 F{speed_travel} ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E7 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F{speed_travel}\n;Put printing message on LCD screen\nM117 Rigibot Printing..."
}, },
"machine_end_gcode": { "machine_end_gcode": {
"default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning" "default_value": ";End GCode\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+10 E-1 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG1 Y230 F3000 ;move Y so the head is out of the way and Plate is moved forward\nM84 ;steppers off\nG90 ;absolute positioning"

3336
resources/i18n/ptbr/cura.po Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,191 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: Uranium json setting files\n"
"Report-Msgid-Bugs-To: http://github.com/ultimaker/uranium\n"
"POT-Creation-Date: 2016-12-28 10:51+0000\n"
"PO-Revision-Date: 2016-01-25 05:05-0300\n"
"Last-Translator: Cláudio Sampaio <patola@makerlinux.com.br>\n"
"Language-Team: LANGUAGE\n"
"Language: ptbr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: fdmextruder.def.json
msgctxt "machine_settings label"
msgid "Machine"
msgstr "Máquina"
#: fdmextruder.def.json
msgctxt "machine_settings description"
msgid "Machine specific settings"
msgstr "Ajustes específicos da máquina"
#: fdmextruder.def.json
msgctxt "extruder_nr label"
msgid "Extruder"
msgstr "Extrusor"
#: fdmextruder.def.json
msgctxt "extruder_nr description"
msgid "The extruder train used for printing. This is used in multi-extrusion."
msgstr "O extrusor usado para impressão. Isto é usado em multi-extrusão."
#: fdmextruder.def.json
msgctxt "machine_nozzle_offset_x label"
msgid "Nozzle X Offset"
msgstr "Deslocamento X do Bico"
#: fdmextruder.def.json
msgctxt "machine_nozzle_offset_x description"
msgid "The x-coordinate of the offset of the nozzle."
msgstr "A coordenada X do deslocamento aplicado ao bico."
#: fdmextruder.def.json
msgctxt "machine_nozzle_offset_y label"
msgid "Nozzle Y Offset"
msgstr "Deslocamento Y do Bico"
#: fdmextruder.def.json
msgctxt "machine_nozzle_offset_y description"
msgid "The y-coordinate of the offset of the nozzle."
msgstr "A coordenada Y do deslocamento aplicado ao bico."
#: fdmextruder.def.json
msgctxt "machine_extruder_start_code label"
msgid "Extruder Start G-Code"
msgstr "G-Code Inicial do Extrusor"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_code description"
msgid "Start g-code to execute whenever turning the extruder on."
msgstr "G-Code Inicial a ser executado sempre que o extrusor for ligado."
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_abs label"
msgid "Extruder Start Position Absolute"
msgstr "Posição de Início do Extrusor Absoluta"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_abs description"
msgid ""
"Make the extruder starting position absolute rather than relative to the "
"last-known location of the head."
msgstr ""
"Faz a posição de início do extrusor ser absoluta ao invés de relativa à "
"última posição conhecida da cabeça de impressão."
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_x label"
msgid "Extruder Start Position X"
msgstr "Posição X de Início do Extrusor"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_x description"
msgid "The x-coordinate of the starting position when turning the extruder on."
msgstr "A coordenada X da posição de início quando se liga o extrusor."
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_y label"
msgid "Extruder Start Position Y"
msgstr "Posição Y de Início do Extrusor"
#: fdmextruder.def.json
msgctxt "machine_extruder_start_pos_y description"
msgid "The y-coordinate of the starting position when turning the extruder on."
msgstr "A coordenada Y da posição de início quando se liga o extrusor."
#: fdmextruder.def.json
msgctxt "machine_extruder_end_code label"
msgid "Extruder End G-Code"
msgstr "G-Code Final do Extrusor"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_code description"
msgid "End g-code to execute whenever turning the extruder off."
msgstr "G-Code a ser executado antes de desligar o extrusor."
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_abs label"
msgid "Extruder End Position Absolute"
msgstr "Posição Final do Extrusor Absoluta"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_abs description"
msgid ""
"Make the extruder ending position absolute rather than relative to the last-"
"known location of the head."
msgstr ""
"Faz a posição final do extrusor ser absoluta ao invés de relativa à última "
"posição conhecida da cabeça de impressão."
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_x label"
msgid "Extruder End Position X"
msgstr "Posição X Final do Extrusor"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_x description"
msgid "The x-coordinate of the ending position when turning the extruder off."
msgstr "A coordenada X da posição final do extrusor quando se o desliga."
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_y label"
msgid "Extruder End Position Y"
msgstr "Posição Y Final do Extrusor"
#: fdmextruder.def.json
msgctxt "machine_extruder_end_pos_y description"
msgid "The y-coordinate of the ending position when turning the extruder off."
msgstr "A coordenada Y da posição final do extrusor quando se o desliga."
#: fdmextruder.def.json
msgctxt "extruder_prime_pos_z label"
msgid "Extruder Prime Z Position"
msgstr "Posição Z de Purga do Extrusor"
#: fdmextruder.def.json
msgctxt "extruder_prime_pos_z description"
msgid ""
"The Z coordinate of the position where the nozzle primes at the start of "
"printing."
msgstr ""
"A coordenada Z da posição onde o bico faz a purga no início da impressão."
#: fdmextruder.def.json
msgctxt "platform_adhesion label"
msgid "Build Plate Adhesion"
msgstr "Aderência da Mesa de Impressão"
#: fdmextruder.def.json
msgctxt "platform_adhesion description"
msgid "Adhesion"
msgstr "Aderência"
#: fdmextruder.def.json
msgctxt "extruder_prime_pos_x label"
msgid "Extruder Prime X Position"
msgstr "Posição X de Purga do Extrusor"
#: fdmextruder.def.json
msgctxt "extruder_prime_pos_x description"
msgid ""
"The X coordinate of the position where the nozzle primes at the start of "
"printing."
msgstr ""
"A coordenada X da posição onde o bico faz a purga no início da impressão."
#: fdmextruder.def.json
msgctxt "extruder_prime_pos_y label"
msgid "Extruder Prime Y Position"
msgstr "Posição Y de Purga do Extrusor"
#: fdmextruder.def.json
msgctxt "extruder_prime_pos_y description"
msgid ""
"The Y coordinate of the position where the nozzle primes at the start of "
"printing."
msgstr ""
"A coordenada Y da posição onde o bico faz a purga no início da impressão."

File diff suppressed because it is too large Load diff

View file

@ -74,10 +74,8 @@ UM.Dialog
width: machineList.width width: machineList.width
style: ButtonStyle style: ButtonStyle
{ {
background: Rectangle background: Item
{ {
border.width: 0
color: "transparent";
height: UM.Theme.getSize("standard_list_lineheight").height height: UM.Theme.getSize("standard_list_lineheight").height
width: machineList.width width: machineList.width
} }

View file

@ -306,6 +306,18 @@ UM.MainWindow
} }
} }
Legend
{
id: legend
anchors
{
top: parent.top
topMargin: UM.Theme.getSize("default_margin").height
right: sidebar.left
rightMargin: UM.Theme.getSize("default_margin").width
}
}
JobSpecs JobSpecs
{ {
id: jobSpecs id: jobSpecs

View file

@ -9,7 +9,7 @@ import QtQuick.Layouts 1.1
import UM 1.1 as UM import UM 1.1 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
Rectangle { Item {
id: base id: base
property bool activity: Printer.getPlatformActivity property bool activity: Printer.getPlatformActivity
@ -26,9 +26,9 @@ Rectangle {
property variant printDuration: PrintInformation.currentPrintTime property variant printDuration: PrintInformation.currentPrintTime
property variant printMaterialLengths: PrintInformation.materialLengths property variant printMaterialLengths: PrintInformation.materialLengths
property variant printMaterialWeights: PrintInformation.materialWeights property variant printMaterialWeights: PrintInformation.materialWeights
property variant printMaterialCosts: PrintInformation.materialCosts
height: childrenRect.height height: childrenRect.height
color: "transparent"
Connections Connections
{ {
@ -83,9 +83,8 @@ Rectangle {
} }
style: ButtonStyle style: ButtonStyle
{ {
background: Rectangle background: Item
{ {
color: "transparent"
UM.RecolorImage UM.RecolorImage
{ {
width: UM.Theme.getSize("save_button_specs_icons").width; width: UM.Theme.getSize("save_button_specs_icons").width;
@ -133,7 +132,8 @@ Rectangle {
} }
} }
Label{ Label
{
id: boundingSpec id: boundingSpec
anchors.top: jobNameRow.bottom anchors.top: jobNameRow.bottom
anchors.right: parent.right anchors.right: parent.right
@ -144,17 +144,20 @@ Rectangle {
text: Printer.getSceneBoundingBoxString text: Printer.getSceneBoundingBoxString
} }
Rectangle { Rectangle
{
id: specsRow id: specsRow
anchors.top: boundingSpec.bottom anchors.top: boundingSpec.bottom
anchors.right: parent.right anchors.right: parent.right
height: UM.Theme.getSize("jobspecs_line").height height: UM.Theme.getSize("jobspecs_line").height
Item{ Item
{
width: parent.width width: parent.width
height: parent.height height: parent.height
UM.RecolorImage { UM.RecolorImage
{
id: timeIcon id: timeIcon
anchors.right: timeSpec.left anchors.right: timeSpec.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width/2 anchors.rightMargin: UM.Theme.getSize("default_margin").width/2
@ -166,7 +169,8 @@ Rectangle {
color: UM.Theme.getColor("text_subtext") color: UM.Theme.getColor("text_subtext")
source: UM.Theme.getIcon("print_time") source: UM.Theme.getIcon("print_time")
} }
Label{ Label
{
id: timeSpec id: timeSpec
anchors.right: lengthIcon.left anchors.right: lengthIcon.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.rightMargin: UM.Theme.getSize("default_margin").width
@ -175,7 +179,8 @@ Rectangle {
color: UM.Theme.getColor("text_subtext") color: UM.Theme.getColor("text_subtext")
text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short) text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
} }
UM.RecolorImage { UM.RecolorImage
{
id: lengthIcon id: lengthIcon
anchors.right: lengthSpec.left anchors.right: lengthSpec.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width/2 anchors.rightMargin: UM.Theme.getSize("default_margin").width/2
@ -187,7 +192,8 @@ Rectangle {
color: UM.Theme.getColor("text_subtext") color: UM.Theme.getColor("text_subtext")
source: UM.Theme.getIcon("category_material") source: UM.Theme.getIcon("category_material")
} }
Label{ Label
{
id: lengthSpec id: lengthSpec
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@ -197,19 +203,38 @@ Rectangle {
{ {
var lengths = []; var lengths = [];
var weights = []; var weights = [];
var costs = [];
var someCostsKnown = false;
if(base.printMaterialLengths) { if(base.printMaterialLengths) {
for(var index = 0; index < base.printMaterialLengths.length; index++) { for(var index = 0; index < base.printMaterialLengths.length; index++)
if(base.printMaterialLengths[index] > 0) { {
if(base.printMaterialLengths[index] > 0)
{
lengths.push(base.printMaterialLengths[index].toFixed(2)); lengths.push(base.printMaterialLengths[index].toFixed(2));
weights.push(String(Math.floor(base.printMaterialWeights[index]))); weights.push(String(Math.floor(base.printMaterialWeights[index])));
costs.push(base.printMaterialCosts[index].toFixed(2));
if(base.printMaterialCosts[index] > 0)
{
someCostsKnown = true;
}
} }
} }
} }
if(lengths.length == 0) { if(lengths.length == 0)
{
lengths = ["0.00"]; lengths = ["0.00"];
weights = ["0"]; weights = ["0"];
costs = ["0.00"];
}
if(someCostsKnown)
{
return catalog.i18nc("@label", "%1 m / ~ %2 g / ~ %4 %3").arg(lengths.join(" + "))
.arg(weights.join(" + ")).arg(costs.join(" + ")).arg(UM.Preferences.getValue("cura/currency"));
}
else
{
return catalog.i18nc("@label", "%1 m / ~ %2 g").arg(lengths.join(" + ")).arg(weights.join(" + "));
} }
return catalog.i18nc("@label", "%1 m / ~ %2 g").arg(lengths.join(" + ")).arg(weights.join(" + "));
} }
} }
} }

65
resources/qml/Legend.qml Normal file
View file

@ -0,0 +1,65 @@
// Copyright (c) 2015 Ultimaker B.V.
// Cura is released under the terms of the AGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import UM 1.1 as UM
import Cura 1.0 as Cura
Item {
id: base
UM.I18nCatalog { id: catalog; name:"cura"}
width: childrenRect.width
height: childrenRect.height
Connections
{
target: Printer
onViewLegendItemsChanged:
{
legendItemRepeater.model = items
}
}
Column
{
Repeater
{
id: legendItemRepeater
Item {
anchors.right: parent.right
height: childrenRect.height
width: childrenRect.width
Rectangle {
id: swatch
anchors.right: parent.right
anchors.verticalCenter: label.verticalCenter
height: UM.Theme.getSize("setting_control").height / 2
width: height
color: modelData.color
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("text_subtext")
}
Label {
id: label
text: modelData.title
font: UM.Theme.getFont("small")
color: UM.Theme.getColor("text_subtext")
anchors.right: swatch.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width / 2
}
}
}
}
}

View file

@ -10,7 +10,7 @@ import QtQuick.Layouts 1.1
import UM 1.1 as UM import UM 1.1 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
Rectangle Item
{ {
id: base; id: base;
UM.I18nCatalog { id: catalog; name:"cura"} UM.I18nCatalog { id: catalog; name:"cura"}
@ -20,7 +20,6 @@ Rectangle
property real progress: printerConnected ? Cura.MachineManager.printerOutputDevices[0].progress : 0 property real progress: printerConnected ? Cura.MachineManager.printerOutputDevices[0].progress : 0
property int backendState: UM.Backend.state property int backendState: UM.Backend.state
property bool showProgress: { property bool showProgress: {
// determine if we need to show the progress bar + percentage // determine if we need to show the progress bar + percentage
if(!printerConnected || !printerAcceptsCommands) { if(!printerConnected || !printerAcceptsCommands) {

View file

@ -97,6 +97,7 @@ UM.PreferencesPage
append({ text: "Français", code: "fr" }) append({ text: "Français", code: "fr" })
append({ text: "Italiano", code: "it" }) append({ text: "Italiano", code: "it" })
append({ text: "Nederlands", code: "nl" }) append({ text: "Nederlands", code: "nl" })
append({ text: "Português do Brasil", code: "ptbr" })
append({ text: "Русский", code: "ru" }) append({ text: "Русский", code: "ru" })
append({ text: "Türkçe", code: "tr" }) append({ text: "Türkçe", code: "tr" })
} }
@ -129,6 +130,19 @@ UM.PreferencesPage
currentIndex -= 1; currentIndex -= 1;
} }
} }
Label
{
id: currencyLabel
text: catalog.i18nc("@label","Currency:")
anchors.verticalCenter: languageComboBox.verticalCenter
}
TextField
{
id: currencyField
text: UM.Preferences.getValue("cura/currency")
onTextChanged: UM.Preferences.setValue("cura/currency", text)
}
} }
Label Label

View file

@ -15,14 +15,19 @@ TabView
property QtObject properties; property QtObject properties;
property bool editingEnabled: false; property bool editingEnabled: false;
property string currency: UM.Preferences.getValue("general/currency") ? UM.Preferences.getValue("general/currency") : "€" property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€"
property real firstColumnWidth: width * 0.45 property real firstColumnWidth: width * 0.45
property real secondColumnWidth: width * 0.45 property real secondColumnWidth: width * 0.45
property string containerId: "" property string containerId: ""
property var materialPreferenceValues: UM.Preferences.getValue("cura/material_settings") ? JSON.parse(UM.Preferences.getValue("cura/material_settings")) : {}
property double spoolLength: calculateSpoolLength()
property real costPerMeter: calculateCostPerMeter()
Tab Tab
{ {
title: catalog.i18nc("@title","Information") title: catalog.i18nc("@title","Information")
anchors anchors
{ {
leftMargin: UM.Theme.getSize("default_margin").width leftMargin: UM.Theme.getSize("default_margin").width
@ -35,6 +40,7 @@ TabView
{ {
anchors.fill: parent anchors.fill: parent
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
flickableItem.flickableDirection: Flickable.VerticalFlick
Flow Flow
{ {
@ -112,64 +118,78 @@ TabView
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") } Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
ReadOnlySpinBox ReadOnlySpinBox
{ {
width: base.secondColumnWidth; id: densitySpinBox
value: properties.density; width: base.secondColumnWidth
value: properties.density
decimals: 2 decimals: 2
suffix: "g/cm³" suffix: " g/cm³"
stepSize: 0.01 stepSize: 0.01
readOnly: !base.editingEnabled; readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value) onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value)
onValueChanged: updateCostPerMeter()
} }
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") } Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
ReadOnlySpinBox ReadOnlySpinBox
{ {
width: base.secondColumnWidth; id: diameterSpinBox
value: properties.diameter; width: base.secondColumnWidth
value: properties.diameter
decimals: 2 decimals: 2
suffix: "mm" suffix: " mm"
stepSize: 0.01 stepSize: 0.01
readOnly: !base.editingEnabled; readOnly: !base.editingEnabled
onEditingFinished: base.setMetaDataEntry("properties/diameter", properties.diameter, value) onEditingFinished: base.setMetaDataEntry("properties/diameter", properties.diameter, value)
onValueChanged: updateCostPerMeter()
} }
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") } Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
SpinBox SpinBox
{ {
width: base.secondColumnWidth; id: spoolCostSpinBox
value: properties.spool_cost; width: base.secondColumnWidth
prefix: base.currency value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
enabled: false prefix: base.currency + " "
decimals: 2
maximumValue: 1000
onEditingFinished: base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value))
onValueChanged: updateCostPerMeter()
} }
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") } Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
SpinBox SpinBox
{ {
width: base.secondColumnWidth; id: spoolWeightSpinBox
value: properties.spool_weight; width: base.secondColumnWidth
suffix: "g"; value: base.getMaterialPreferenceValue(properties.guid, "spool_weight")
stepSize: 10 suffix: " g"
enabled: false stepSize: 100
decimals: 0
maximumValue: 10000
onEditingFinished: base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value))
onValueChanged: updateCostPerMeter()
} }
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") } Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
SpinBox Label
{ {
width: base.secondColumnWidth; width: base.secondColumnWidth
value: parseFloat(properties.spool_length); text: "~ %1 m".arg(Math.round(base.spoolLength))
suffix: "m"; verticalAlignment: Qt.AlignVCenter
enabled: false height: parent.rowHeight
} }
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter (Approx.)") } Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") }
SpinBox Label
{ {
width: base.secondColumnWidth; width: base.secondColumnWidth
value: parseFloat(properties.cost_per_meter); text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
suffix: catalog.i18nc("@label", "%1/m".arg(base.currency)); verticalAlignment: Qt.AlignVCenter
enabled: false height: parent.rowHeight
} }
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height } Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
@ -200,6 +220,12 @@ TabView
onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text) onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
} }
} }
function updateCostPerMeter()
{
base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value);
base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value);
}
} }
} }
@ -259,6 +285,44 @@ TabView
} }
} }
function calculateSpoolLength(diameter, density, spoolWeight)
{
if(!diameter)
{
diameter = properties.diameter;
}
if(!density)
{
density = properties.density;
}
if(!spoolWeight)
{
spoolWeight = base.getMaterialPreferenceValue(properties.guid, "spool_weight");
}
if (diameter == 0 || density == 0 || spoolWeight == 0)
{
return 0;
}
var area = Math.PI * Math.pow(diameter / 2, 2); // in mm2
var volume = (spoolWeight / density); // in cm3
return volume / area; // in m
}
function calculateCostPerMeter(spoolCost)
{
if(!spoolCost)
{
spoolCost = base.getMaterialPreferenceValue(properties.guid, "spool_cost");
}
if (spoolLength == 0)
{
return 0;
}
return spoolCost / spoolLength;
}
// Tiny convenience function to check if a value really changed before trying to set it. // Tiny convenience function to check if a value really changed before trying to set it.
function setMetaDataEntry(entry_name, old_value, new_value) function setMetaDataEntry(entry_name, old_value, new_value)
{ {
@ -268,6 +332,32 @@ TabView
} }
} }
function setMaterialPreferenceValue(material_guid, entry_name, new_value)
{
if(!(material_guid in materialPreferenceValues))
{
materialPreferenceValues[material_guid] = {};
}
if(entry_name in materialPreferenceValues[material_guid] && materialPreferenceValues[material_guid][entry_name] == new_value)
{
// value has not changed
return
}
materialPreferenceValues[material_guid][entry_name] = new_value;
// store preference
UM.Preferences.setValue("cura/material_settings", JSON.stringify(materialPreferenceValues));
}
function getMaterialPreferenceValue(material_guid, entry_name)
{
if(material_guid in materialPreferenceValues && entry_name in materialPreferenceValues[material_guid])
{
return materialPreferenceValues[material_guid][entry_name];
}
return 0;
}
function setName(old_value, new_value) function setName(old_value, new_value)
{ {
if(old_value != new_value) if(old_value != new_value)

View file

@ -185,17 +185,6 @@ UM.ManagementPage
height: childrenRect.height height: childrenRect.height
Label { text: materialProperties.name; font: UM.Theme.getFont("large"); } Label { text: materialProperties.name; font: UM.Theme.getFont("large"); }
Button
{
id: editButton
anchors.right: parent.right;
text: catalog.i18nc("@action:button", "Edit");
iconName: "document-edit";
enabled: base.currentItem != null && !base.currentItem.readOnly
checkable: enabled
}
} }
MaterialView MaterialView
@ -209,7 +198,7 @@ UM.ManagementPage
bottom: parent.bottom bottom: parent.bottom
} }
editingEnabled: editButton.checkable && editButton.checked; editingEnabled: base.currentItem != null && !base.currentItem.readOnly
properties: materialProperties properties: materialProperties
containerId: base.currentItem != null ? base.currentItem.id : "" containerId: base.currentItem != null ? base.currentItem.id : ""
@ -219,6 +208,7 @@ UM.ManagementPage
{ {
id: materialProperties id: materialProperties
property string guid: "00000000-0000-0000-0000-000000000000"
property string name: "Unknown"; property string name: "Unknown";
property string profile_type: "Unknown"; property string profile_type: "Unknown";
property string supplier: "Unknown"; property string supplier: "Unknown";
@ -344,6 +334,7 @@ UM.ManagementPage
return return
} }
materialProperties.name = currentItem.name; materialProperties.name = currentItem.name;
materialProperties.guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID");
if(currentItem.metadata != undefined && currentItem.metadata != null) if(currentItem.metadata != undefined && currentItem.metadata != null)
{ {

View file

@ -8,7 +8,7 @@ import QtQuick.Layouts 1.1
import UM 1.1 as UM import UM 1.1 as UM
Rectangle { Item {
id: base; id: base;
UM.I18nCatalog { id: catalog; name:"cura"} UM.I18nCatalog { id: catalog; name:"cura"}
@ -53,7 +53,7 @@ Rectangle {
text: statusText; text: statusText;
} }
Rectangle{ Rectangle {
id: progressBar id: progressBar
width: parent.width - 2 * UM.Theme.getSize("default_margin").width width: parent.width - 2 * UM.Theme.getSize("default_margin").width
height: UM.Theme.getSize("progressbar").height height: UM.Theme.getSize("progressbar").height
@ -64,7 +64,7 @@ Rectangle {
radius: UM.Theme.getSize("progressbar_radius").width radius: UM.Theme.getSize("progressbar_radius").width
color: UM.Theme.getColor("progressbar_background") color: UM.Theme.getColor("progressbar_background")
Rectangle{ Rectangle {
width: Math.max(parent.width * base.progress) width: Math.max(parent.width * base.progress)
height: parent.height height: parent.height
color: UM.Theme.getColor("progressbar_control") color: UM.Theme.getColor("progressbar_control")
@ -73,7 +73,7 @@ Rectangle {
} }
} }
Rectangle{ Item {
id: saveRow id: saveRow
width: base.width width: base.width
height: saveToButton.height height: saveToButton.height

View file

@ -145,8 +145,6 @@ Item {
height: parent.height; height: parent.height;
width: height; width: height;
backgroundColor: UM.Theme.getColor("setting_control");
hoverBackgroundColor: UM.Theme.getColor("setting_control")
color: UM.Theme.getColor("setting_control_button") color: UM.Theme.getColor("setting_control_button")
hoverColor: UM.Theme.getColor("setting_control_button") hoverColor: UM.Theme.getColor("setting_control_button")
@ -173,8 +171,6 @@ Item {
height: parent.height; height: parent.height;
width: height; width: height;
backgroundColor: UM.Theme.getColor("setting_control");
hoverBackgroundColor: UM.Theme.getColor("setting_control_highlight")
color: UM.Theme.getColor("setting_control_button") color: UM.Theme.getColor("setting_control_button")
hoverColor: UM.Theme.getColor("setting_control_button_hover") hoverColor: UM.Theme.getColor("setting_control_button_hover")
@ -278,8 +274,6 @@ Item {
} }
} }
backgroundColor: UM.Theme.getColor("setting_control");
hoverBackgroundColor: UM.Theme.getColor("setting_control_highlight")
color: UM.Theme.getColor("setting_control_button") color: UM.Theme.getColor("setting_control_button")
hoverColor: UM.Theme.getColor("setting_control_button_hover") hoverColor: UM.Theme.getColor("setting_control_button_hover")

View file

@ -175,6 +175,9 @@ Rectangle
height: UM.Theme.getSize("sidebar_header").height height: UM.Theme.getSize("sidebar_header").height
onClicked: monitoringPrint = false onClicked: monitoringPrint = false
iconSource: UM.Theme.getIcon("tab_settings"); iconSource: UM.Theme.getIcon("tab_settings");
property color overlayColor: "transparent"
property string overlayIconSource: ""
checkable: true checkable: true
checked: !monitoringPrint checked: !monitoringPrint
exclusiveGroup: sidebarHeaderBarGroup exclusiveGroup: sidebarHeaderBarGroup
@ -203,15 +206,53 @@ Rectangle
width: height width: height
height: UM.Theme.getSize("sidebar_header").height height: UM.Theme.getSize("sidebar_header").height
onClicked: monitoringPrint = true onClicked: monitoringPrint = true
iconSource: { iconSource: printerConnected ? UM.Theme.getIcon("tab_monitor_with_status") : UM.Theme.getIcon("tab_monitor")
if(!printerConnected) property color overlayColor:
return UM.Theme.getIcon("tab_monitor"); {
else if(!printerAcceptsCommands) if(!printerAcceptsCommands)
return UM.Theme.getIcon("tab_monitor_unknown"); {
return UM.Theme.getColor("status_unknown");
}
if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance") if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance")
{ {
return UM.Theme.getIcon("tab_monitor_busy"); return UM.Theme.getColor("status_busy");
}
switch(Cura.MachineManager.printerOutputDevices[0].jobState)
{
case "printing":
case "pre_print":
case "wait_cleanup":
case "pausing":
case "resuming":
return UM.Theme.getColor("status_busy");
case "ready":
case "":
return UM.Theme.getColor("status_ready");
case "paused":
return UM.Theme.getColor("status_paused");
case "error":
return UM.Theme.getColor("status_stopped");
case "offline":
return UM.Theme.getColor("status_offline");
default:
return UM.Theme.getColor("text_reversed");
}
}
property string overlayIconSource:
{
if(!printerConnected)
{
return "";
}
else if(!printerAcceptsCommands)
{
return UM.Theme.getIcon("tab_status_unknown");
}
if(Cura.MachineManager.printerOutputDevices[0].printerState == "maintenance")
{
return UM.Theme.getIcon("tab_status_busy");
} }
switch(Cura.MachineManager.printerOutputDevices[0].jobState) switch(Cura.MachineManager.printerOutputDevices[0].jobState)
@ -219,20 +260,23 @@ Rectangle
case "printing": case "printing":
case "pre_print": case "pre_print":
case "wait_cleanup": case "wait_cleanup":
return UM.Theme.getIcon("tab_monitor_busy"); case "pausing":
case "resuming":
return UM.Theme.getIcon("tab_status_busy");
case "ready": case "ready":
case "": case "":
return UM.Theme.getIcon("tab_monitor_connected") return UM.Theme.getIcon("tab_status_connected")
case "paused": case "paused":
return UM.Theme.getIcon("tab_monitor_paused") return UM.Theme.getIcon("tab_status_paused")
case "error": case "error":
return UM.Theme.getIcon("tab_monitor_stopped") return UM.Theme.getIcon("tab_status_stopped")
case "offline": case "offline":
return UM.Theme.getIcon("tab_monitor_offline") return UM.Theme.getIcon("tab_status_offline")
default: default:
return UM.Theme.getIcon("tab_monitor") return ""
} }
} }
checkable: true checkable: true
checked: monitoringPrint checked: monitoringPrint
exclusiveGroup: sidebarHeaderBarGroup exclusiveGroup: sidebarHeaderBarGroup

View file

@ -201,7 +201,7 @@ Column
color: UM.Theme.getColor("text"); color: UM.Theme.getColor("text");
} }
Rectangle Item
{ {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter

View file

@ -25,7 +25,7 @@ Item
Component.onDestruction: PrintInformation.enabled = false Component.onDestruction: PrintInformation.enabled = false
UM.I18nCatalog { id: catalog; name:"cura"} UM.I18nCatalog { id: catalog; name:"cura"}
Rectangle Item
{ {
id: infillCellLeft id: infillCellLeft
anchors.top: parent.top anchors.top: parent.top
@ -216,7 +216,7 @@ Item
} }
} }
Rectangle Item
{ {
id: helpersCell id: helpersCell
anchors.top: infillCellRight.bottom anchors.top: infillCellRight.bottom
@ -461,7 +461,7 @@ Item
supportExtruderCombobox.updateCurrentColor(); supportExtruderCombobox.updateCurrentColor();
} }
Rectangle Item
{ {
id: tipsCell id: tipsCell
anchors.top: helpersCell.bottom anchors.top: helpersCell.bottom

View file

@ -15,11 +15,10 @@ UM.Dialog
width: 550 width: 550
minimumWidth: 550 minimumWidth: 550
maximumWidth: 550
height: 350 height: 350
minimumHeight: 350 minimumHeight: 350
maximumHeight: 350
property int spacerHeight: 10 property int spacerHeight: 10
property bool dontShowAgain: true property bool dontShowAgain: true

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path d="M2.5 2.5h25v1.19h-25V2.5zm0 23.81h2.287l2.272-1.19h15.966l2.234 1.19H27.5v1.19h-2.239l-2.236-1.19H7.057l-2.27 1.177L2.5 27.5v-1.19zM26.364 3.69H27.5v22.62h-1.136V3.69zM2.5 3.69h1.136v22.62H2.5V3.69zm3.41 2.381h18.18v16.667H5.91V6.071zm1.135 1.19h15.91v14.287H7.045V7.262zm5.682 0h4.546v3.572h-4.546V7.262zM9.318 20.358h11.364v1.19H9.318v-1.19zm4.546-9.524h2.272v1.19h-2.272v-1.19z" fill="#fff" fill-rule="evenodd"/> <path d="M2.5 2.5h25v1.19h-25V2.5zm0 23.81h2.287l2.272-1.19h15.966l2.234 1.19H27.5v1.19h-2.239l-2.236-1.19H7.057l-2.27 1.177L2.5 27.5v-1.19zM26.364 3.69H27.5v22.62h-1.136V3.69zM2.5 3.69h1.136v22.62H2.5V3.69zm3.41 2.381h18.18v16.667H5.91V6.071zm1.135 1.19h15.91v14.287H7.045V7.262zm5.682 0h4.546v3.572h-4.546V7.262zM9.318 20.358h11.364v1.19H9.318v-1.19zm4.546-9.524h2.272v1.19h-2.272v-1.19z" fill-rule="evenodd"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 485 B

Before After
Before After

View file

@ -1,7 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path d="M2.5 2.5h25v1.19h-25V2.5zm0 23.81h2.287l2.272-1.19h15.966l2.234 1.19H27.5v1.19h-2.239l-2.236-1.19H7.057l-2.27 1.177L2.5 27.5v-1.19zM26.364 3.69H27.5v22.62h-1.136V3.69zM2.5 3.69h1.136v22.62H2.5V3.69zm3.41 2.381h18.18v16.667H5.91V6.071zm1.135 1.19h15.91v14.287H7.045V7.262zm5.682 0h4.546v3.572h-4.546V7.262zM9.318 20.358h11.364v1.19H9.318v-1.19zm4.546-9.524h2.272v1.19h-2.272v-1.19z" fill="#fff" fill-rule="evenodd"/>
<circle cx="22.5" cy="7.5" r="7.5" fill="#0ca9e3"/>
<circle cx="22.5" cy="7.5" r="1.5" fill="#fff"/>
<circle r="1.5" cy="7.5" cx="18.5" fill="#fff"/>
<circle cx="26.5" cy="7.5" r="1.5" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 712 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path d="M2.5 2.5h25v1.19h-25V2.5zm0 23.81h2.287l2.272-1.19h15.966l2.234 1.19H27.5v1.19h-2.239l-2.236-1.19H7.057l-2.27 1.177L2.5 27.5v-1.19zM26.364 3.69H27.5v22.62h-1.136V3.69zM2.5 3.69h1.136v22.62H2.5V3.69zm3.41 2.381h18.18v16.667H5.91V6.071zm1.135 1.19h15.91v14.287H7.045V7.262zm5.682 0h4.546v3.572h-4.546V7.262zM9.318 20.358h11.364v1.19H9.318v-1.19zm4.546-9.524h2.272v1.19h-2.272v-1.19z" fill="#fff" fill-rule="evenodd"/>
<circle cx="22.5" cy="7.5" r="7.5" fill="#00cd00"/>
<path d="M25.547 4.302L21.994 7.92 19.86 5.84 18.5 7.218l3.572 3.48c1.66-1.68 3.447-3.513 4.903-4.996z" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 675 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path d="M2.5 2.5h25v1.19h-25V2.5zm0 23.81h2.287l2.272-1.19h15.966l2.234 1.19H27.5v1.19h-2.239l-2.236-1.19H7.057l-2.27 1.177L2.5 27.5v-1.19zM26.364 3.69H27.5v22.62h-1.136V3.69zM2.5 3.69h1.136v22.62H2.5V3.69zm3.41 2.381h18.18v16.667H5.91V6.071zm1.135 1.19h15.91v14.287H7.045V7.262zm5.682 0h4.546v3.572h-4.546V7.262zM9.318 20.358h11.364v1.19H9.318v-1.19zm4.546-9.524h2.272v1.19h-2.272v-1.19z" fill="#fff" fill-rule="evenodd"/>
<circle cx="22.5" cy="7.5" r="7.5"/>
<path d="M20.025 3.611l-1.414 1.414L21.086 7.5 18.61 9.975l1.414 1.414L22.5 8.914l2.475 2.475 1.414-1.414L23.914 7.5l2.475-2.475-1.414-1.414L22.5 6.086 20.025 3.61z" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 722 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path d="M2.5 2.5h25v1.19h-25V2.5zm0 23.81h2.287l2.272-1.19h15.966l2.234 1.19H27.5v1.19h-2.239l-2.236-1.19H7.057l-2.27 1.177L2.5 27.5v-1.19zM26.364 3.69H27.5v22.62h-1.136V3.69zM2.5 3.69h1.136v22.62H2.5V3.69zm3.41 2.381h18.18v16.667H5.91V6.071zm1.135 1.19h15.91v14.287H7.045V7.262zm5.682 0h4.546v3.572h-4.546V7.262zM9.318 20.358h11.364v1.19H9.318v-1.19zm4.546-9.524h2.272v1.19h-2.272v-1.19z" fill="#fff" fill-rule="evenodd"/>
<circle cx="22.5" cy="7.5" r="7.5" fill="#ec5250"/>
<path d="M20.025 3.611l-1.414 1.414L21.086 7.5 18.61 9.975l1.414 1.414L22.5 8.914l2.475 2.475 1.414-1.414L23.914 7.5l2.475-2.475-1.414-1.414L22.5 6.086 20.025 3.61z" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 737 B

View file

@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path d="M2.5 2.5h25v1.19h-25V2.5zm0 23.81h2.287l2.272-1.19h15.966l2.234 1.19H27.5v1.19h-2.239l-2.236-1.19H7.057l-2.27 1.177L2.5 27.5v-1.19zM26.364 3.69H27.5v22.62h-1.136V3.69zM2.5 3.69h1.136v22.62H2.5V3.69zm3.41 2.381h18.18v16.667H5.91V6.071zm1.135 1.19h15.91v14.287H7.045V7.262zm5.682 0h4.546v3.572h-4.546V7.262zM9.318 20.358h11.364v1.19H9.318v-1.19zm4.546-9.524h2.272v1.19h-2.272v-1.19z" fill="#fff" fill-rule="evenodd"/>
<circle cx="22.5" cy="7.5" r="7.5" fill="#7f7f7f"/>
<path d="M25.538 5.675q0 .532-.158.943-.153.405-.437.706-.285.3-.685.537-.395.237-.895.432v1.2h-1.854V7.718q.374-.1.674-.205.305-.105.637-.342.31-.21.485-.49.179-.28.179-.632 0-.527-.343-.748-.337-.226-.953-.226-.38 0-.858.163-.474.163-.87.421h-.21V4.053q.337-.142 1.038-.295.7-.158 1.422-.158 1.3 0 2.064.574t.764 1.501zM23.51 11.6h-2.128v-1.39h2.128v1.39z" style="-inkscape-font-specification:'Verdana Bold'" font-weight="700" font-family="Verdana" fill="#fff" font-size="10.786" letter-spacing="0" word-spacing="0"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,5 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path d="M2.5 2.5h25v1.19h-25V2.5zm0 23.81h2.287l2.272-1.19h15.966l2.234 1.19H27.5v1.19h-2.239l-2.236-1.19H7.057l-2.27 1.177L2.5 27.5v-1.19zM26.364 3.69H27.5v22.62h-1.136V3.69zM2.5 3.69h1.136v22.62H2.5V3.69zm3.41 2.381h18.18v16.667H5.91V6.071zm1.135 1.19h15.91v14.287H7.045V7.262zm5.682 0h4.546v3.572h-4.546V7.262zM9.318 20.358h11.364v1.19H9.318v-1.19zm4.546-9.524h2.272v1.19h-2.272v-1.19z" fill="#fff" fill-rule="evenodd"/> <path d="M2.5 2.5h25v1.19h-25V2.5zm0 23.81h2.287l2.272-1.19h15.966l2.234 1.19H27.5v1.19h-2.239l-2.236-1.19H7.057l-2.27 1.177L2.5 27.5v-1.19zM26.364 3.69H27.5v22.62h-1.136V3.69zM2.5 3.69h1.136v22.62H2.5V3.69zm3.41 2.381h18.18v16.667H5.91V6.071zm1.135 1.19h15.91v14.287H7.045V7.262zm5.682 0h4.546v3.572h-4.546V7.262zM9.318 20.358h11.364v1.19H9.318v-1.19zm4.546-9.524h2.272v1.19h-2.272v-1.19z" fill-rule="evenodd"/>
<circle cx="22.5" cy="7.5" r="7.5" fill="#ff8c00"/> <circle cx="22.5" cy="7.5" r="7.4" />
<path fill="#fff" d="M19.5 4h2v7h-2zm4 0h2v7h-2z"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 609 B

After

Width:  |  Height:  |  Size: 527 B

Before After
Before After

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path
d="M 22.5 0 A 7.5 7.5 0 0 0 15 7.5 A 7.5 7.5 0 0 0 22.5 15 A 7.5 7.5 0 0 0 30 7.5 A 7.5 7.5 0 0 0 22.5 0 z M 18.5 6 A 1.5 1.5 0 0 1 20 7.5 A 1.5 1.5 0 0 1 18.5 9 A 1.5 1.5 0 0 1 17 7.5 A 1.5 1.5 0 0 1 18.5 6 z M 22.5 6 A 1.5 1.5 0 0 1 24 7.5 A 1.5 1.5 0 0 1 22.5 9 A 1.5 1.5 0 0 1 21 7.5 A 1.5 1.5 0 0 1 22.5 6 z M 26.5 6 A 1.5 1.5 0 0 1 28 7.5 A 1.5 1.5 0 0 1 26.5 9 A 1.5 1.5 0 0 1 25 7.5 A 1.5 1.5 0 0 1 26.5 6 z " />
</svg>

After

Width:  |  Height:  |  Size: 502 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path
d="M 22.5 0 A 7.5 7.5 0 0 0 15 7.5 A 7.5 7.5 0 0 0 22.5 15 A 7.5 7.5 0 0 0 30 7.5 A 7.5 7.5 0 0 0 22.5 0 z M 25.546875 4.3027344 L 26.974609 5.7011719 C 25.518609 7.1841719 23.732266 9.0172656 22.072266 10.697266 L 18.5 7.21875 L 19.859375 5.8398438 L 21.994141 7.9199219 L 25.546875 4.3027344 z " />
</svg>

After

Width:  |  Height:  |  Size: 382 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path
d="M 22.5 0 A 7.5 7.5 0 0 0 15 7.5 A 7.5 7.5 0 0 0 22.5 15 A 7.5 7.5 0 0 0 30 7.5 A 7.5 7.5 0 0 0 22.5 0 z M 20.025391 3.6113281 L 22.5 6.0859375 L 24.974609 3.6113281 L 26.388672 5.0253906 L 23.914062 7.5 L 26.388672 9.9746094 L 24.974609 11.388672 L 22.5 8.9140625 L 20.023438 11.388672 L 18.609375 9.9746094 L 21.085938 7.5 L 18.611328 5.0253906 L 20.025391 3.6113281 z " />
</svg>

After

Width:  |  Height:  |  Size: 459 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path
d="M 22.5 0 A 7.5 7.5 0 0 0 15 7.5 A 7.5 7.5 0 0 0 22.5 15 A 7.5 7.5 0 0 0 30 7.5 A 7.5 7.5 0 0 0 22.5 0 z M 19.5 4 L 21.5 4 L 21.5 11 L 19.5 11 L 19.5 4 z M 23.5 4 L 25.5 4 L 25.5 11 L 23.5 11 L 23.5 4 z " />
</svg>

After

Width:  |  Height:  |  Size: 291 B

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 30 30"
version="1.1"
id="svg3753"
sodipodi:docname="tab_monitor_stopped.svg"
inkscape:version="0.92.0 r15299">
<metadata
id="metadata3759">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs3757" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="640"
inkscape:window-height="480"
id="namedview3755"
showgrid="false"
inkscape:zoom="7.8666667"
inkscape:cx="15"
inkscape:cy="15"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg3753" />
<path
d="M 22.5 0 A 7.5 7.5 0 0 0 15 7.5 A 7.5 7.5 0 0 0 22.5 15 A 7.5 7.5 0 0 0 30 7.5 A 7.5 7.5 0 0 0 22.5 0 z M 20.025391 3.6113281 L 22.5 6.0859375 L 24.974609 3.6113281 L 26.388672 5.0253906 L 23.914062 7.5 L 26.388672 9.9746094 L 24.974609 11.388672 L 22.5 8.9140625 L 20.023438 11.388672 L 18.609375 9.9746094 L 21.085938 7.5 L 18.611328 5.0253906 L 20.025391 3.6113281 z "
id="circle3749" />
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
<path
d="M 22.5 0 A 7.5 7.5 0 0 0 15 7.5 A 7.5 7.5 0 0 0 22.5 15 A 7.5 7.5 0 0 0 30 7.5 A 7.5 7.5 0 0 0 22.5 0 z M 22.710938 3.5996094 C 23.577604 3.5996094 24.264104 3.7911615 24.773438 4.1738281 C 25.282771 4.5564948 25.537109 5.0577813 25.537109 5.6757812 C 25.537109 6.0304479 25.486193 6.3431875 25.380859 6.6171875 C 25.278859 6.8871875 25.132693 7.1235521 24.943359 7.3242188 C 24.753359 7.5242188 24.524479 7.7033281 24.257812 7.8613281 C 23.994479 8.0193281 23.696615 8.1629687 23.363281 8.2929688 L 23.363281 9.4921875 L 21.509766 9.4921875 L 21.509766 7.71875 C 21.759099 7.6520833 21.983594 7.5836719 22.183594 7.5136719 C 22.386927 7.4436719 22.598979 7.329875 22.820312 7.171875 C 23.026979 7.031875 23.188021 6.8683073 23.304688 6.6816406 C 23.424021 6.494974 23.484375 6.2834948 23.484375 6.0488281 C 23.484375 5.6974948 23.369292 5.4481146 23.140625 5.3007812 C 22.915958 5.1501146 22.598167 5.0742187 22.1875 5.0742188 C 21.934167 5.0742188 21.648745 5.1296146 21.330078 5.2382812 C 21.014078 5.3469479 20.724937 5.4862031 20.460938 5.6582031 L 20.25 5.6582031 L 20.25 4.0527344 C 20.474667 3.9580677 20.819776 3.8598125 21.287109 3.7578125 C 21.753776 3.6524792 22.229604 3.5996094 22.710938 3.5996094 z M 21.382812 10.210938 L 23.509766 10.210938 L 23.509766 11.599609 L 21.382812 11.599609 L 21.382812 10.210938 z " />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -100,12 +100,24 @@ QtObject {
} }
label: Item { label: Item {
Image { UM.RecolorImage {
anchors.centerIn: parent; color: UM.Theme.getColor("text_reversed")
anchors.centerIn: parent
opacity: !control.enabled ? 0.2 : 1.0 opacity: !control.enabled ? 0.2 : 1.0
source: control.iconSource; source: control.iconSource
width: Theme.getSize("button_icon").width; width: Theme.getSize("button_icon").width
height: Theme.getSize("button_icon").height; height: Theme.getSize("button_icon").height
sourceSize: Theme.getSize("button_icon")
}
UM.RecolorImage {
visible: control.overlayIconSource != ""
color: control.overlayColor
anchors.centerIn: parent
opacity: !control.enabled ? 0.2 : 1.0
source: control.overlayIconSource
width: Theme.getSize("button_icon").width
height: Theme.getSize("button_icon").height
sourceSize: Theme.getSize("button_icon") sourceSize: Theme.getSize("button_icon")
} }

View file

@ -192,7 +192,45 @@
"status_ready": [0, 205, 0, 255], "status_ready": [0, 205, 0, 255],
"status_busy": [12, 169, 227, 255], "status_busy": [12, 169, 227, 255],
"status_paused": [255, 140, 0, 255], "status_paused": [255, 140, 0, 255],
"status_stopped": [236, 82, 80, 255] "status_stopped": [236, 82, 80, 255],
"status_unknown": [127, 127, 127, 255],
"disabled_axis": [127, 127, 127, 255],
"x_axis": [255, 0, 0, 255],
"y_axis": [0, 0, 255, 255],
"z_axis": [0, 255, 0, 255],
"all_axis": [255, 255, 255, 255],
"viewport_background": [245, 245, 245, 255],
"volume_outline": [12, 169, 227, 255],
"buildplate": [244, 244, 244, 255],
"buildplate_alt": [204, 204, 204, 255],
"convex_hull": [35, 35, 35, 127],
"disallowed_area": [0, 0, 0, 40],
"error_area": [255, 0, 0, 127],
"model_default": [255, 201, 36, 255],
"model_overhang": [255, 0, 0, 255],
"model_unslicable": [122, 122, 122, 255],
"model_unslicable_alt": [172, 172, 127, 255],
"model_selection_outline": [12, 169, 227, 255],
"xray": [26, 26, 62, 255],
"xray_error": [255, 0, 0, 255],
"layerview_ghost": [32, 32, 32, 96],
"layerview_none": [255, 255, 255, 255],
"layerview_inset_0": [255, 0, 0, 255],
"layerview_inset_x": [0, 255, 0, 255],
"layerview_skin": [255, 255, 0, 255],
"layerview_support": [0, 255, 255, 255],
"layerview_skirt": [0, 255, 255, 255],
"layerview_infill": [255, 192, 0, 255],
"layerview_support_infill": [0, 255, 255, 255],
"layerview_move_combing": [0, 0, 255, 255],
"layerview_move_retraction": [128, 128, 255, 255],
"layerview_support_interface": [64, 192, 255, 255]
}, },
"sizes": { "sizes": {