Merge remote-tracking branch 'origin/master' into add_42_43_version_upgrader

This commit is contained in:
Lipu Fei 2019-07-25 14:56:27 +02:00
commit 9f18ceda51
37 changed files with 380 additions and 249 deletions

View file

@ -47,7 +47,7 @@ function(cura_add_test)
if (NOT ${test_exists})
add_test(
NAME ${_NAME}
COMMAND ${Python3_EXECUTABLE} -m pytest --verbose --full-trace --capture=no --no-print-log --junitxml=${CMAKE_BINARY_DIR}/junit-${_NAME}.xml ${_DIRECTORY}
COMMAND ${Python3_EXECUTABLE} -m pytest --junitxml=${CMAKE_BINARY_DIR}/junit-${_NAME}.xml ${_DIRECTORY}
)
set_tests_properties(${_NAME} PROPERTIES ENVIRONMENT LANG=C)
set_tests_properties(${_NAME} PROPERTIES ENVIRONMENT "PYTHONPATH=${_PYTHONPATH}")

View file

@ -9,7 +9,7 @@ DEFAULT_CURA_DISPLAY_NAME = "Ultimaker Cura"
DEFAULT_CURA_VERSION = "master"
DEFAULT_CURA_BUILD_TYPE = ""
DEFAULT_CURA_DEBUG_MODE = False
DEFAULT_CURA_SDK_VERSION = "6.1.0"
DEFAULT_CURA_SDK_VERSION = "6.2.0"
try:
from cura.CuraVersion import CuraAppName # type: ignore
@ -45,4 +45,4 @@ except ImportError:
# Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for
# example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the
# CuraVersion.py.in template.
CuraSDKVersion = "6.1.0"
CuraSDKVersion = "6.2.0"

View file

@ -770,7 +770,7 @@ class BuildVolume(SceneNode):
self._has_errors = len(self._error_areas) > 0
self._disallowed_areas = [] # type: List[Polygon]
self._disallowed_areas = []
for extruder_id in result_areas:
self._disallowed_areas.extend(result_areas[extruder_id])
self._disallowed_areas_no_brim = []

View file

@ -421,7 +421,7 @@ class CuraApplication(QtApplication):
# Add empty variant, material and quality containers.
# Since they are empty, they should never be serialized and instead just programmatically created.
# We need them to simplify the switching between materials.
self.empty_container = cura.Settings.cura_empty_instance_containers.empty_container # type: EmptyInstanceContainer
self.empty_container = cura.Settings.cura_empty_instance_containers.empty_container
self._container_registry.addContainer(
cura.Settings.cura_empty_instance_containers.empty_definition_changes_container)
@ -1262,7 +1262,7 @@ class CuraApplication(QtApplication):
@pyqtSlot()
def arrangeObjectsToAllBuildPlates(self) -> None:
nodes_to_arrange = []
for node in DepthFirstIterator(self.getController().getScene().getRoot()): # type: ignore
for node in DepthFirstIterator(self.getController().getScene().getRoot()):
if not isinstance(node, SceneNode):
continue
@ -1289,7 +1289,7 @@ class CuraApplication(QtApplication):
def arrangeAll(self) -> None:
nodes_to_arrange = []
active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate
for node in DepthFirstIterator(self.getController().getScene().getRoot()): # type: ignore
for node in DepthFirstIterator(self.getController().getScene().getRoot()):
if not isinstance(node, SceneNode):
continue
@ -1327,7 +1327,7 @@ class CuraApplication(QtApplication):
Logger.log("i", "Reloading all loaded mesh data.")
nodes = []
has_merged_nodes = False
for node in DepthFirstIterator(self.getController().getScene().getRoot()): # type: ignore
for node in DepthFirstIterator(self.getController().getScene().getRoot()):
if not isinstance(node, CuraSceneNode) or not node.getMeshData():
if node.getName() == "MergedMesh":
has_merged_nodes = True
@ -1339,9 +1339,9 @@ class CuraApplication(QtApplication):
return
for node in nodes:
file_name = node.getMeshData().getFileName()
if file_name:
job = ReadMeshJob(file_name)
mesh_data = node.getMeshData()
if mesh_data and mesh_data.getFileName():
job = ReadMeshJob(mesh_data.getFileName())
job._node = node # type: ignore
job.finished.connect(self._reloadMeshFinished)
if has_merged_nodes:

View file

@ -93,7 +93,7 @@ class MaterialManager(QObject):
self._container_registry.findContainersMetadata(type = "material") if
metadata.get("GUID")} # type: Dict[str, Dict[str, Any]]
self._material_group_map = dict() # type: Dict[str, MaterialGroup]
self._material_group_map = dict()
# Map #1
# root_material_id -> MaterialGroup
@ -120,7 +120,7 @@ class MaterialManager(QObject):
# Map #1.5
# GUID -> material group list
self._guid_material_groups_map = defaultdict(list) # type: Dict[str, List[MaterialGroup]]
self._guid_material_groups_map = defaultdict(list)
for root_material_id, material_group in self._material_group_map.items():
guid = material_group.root_material_node.getMetaDataEntry("GUID", "")
self._guid_material_groups_map[guid].append(material_group)
@ -202,7 +202,7 @@ class MaterialManager(QObject):
# Map #4
# "machine" -> "nozzle name" -> "buildplate name" -> "root material ID" -> specific material InstanceContainer
self._diameter_machine_nozzle_buildplate_material_map = dict() # type: Dict[str, Dict[str, MaterialNode]]
self._diameter_machine_nozzle_buildplate_material_map = dict()
for material_metadata in material_metadatas.values():
self.__addMaterialMetadataIntoLookupTree(material_metadata)

View file

@ -3,6 +3,8 @@
from typing import Optional, TYPE_CHECKING
from numpy import cast
from UM.Application import Application
from UM.Resources import Resources
@ -12,6 +14,7 @@ from UM.View.RenderBatch import RenderBatch
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from cura.Scene.CuraSceneNode import CuraSceneNode
if TYPE_CHECKING:
from UM.View.GL.ShaderProgram import ShaderProgram
@ -44,9 +47,9 @@ class PreviewPass(RenderPass):
self._renderer = Application.getInstance().getRenderer()
self._shader = None #type: Optional[ShaderProgram]
self._non_printing_shader = None #type: Optional[ShaderProgram]
self._support_mesh_shader = None #type: Optional[ShaderProgram]
self._shader = None # type: Optional[ShaderProgram]
self._non_printing_shader = None # type: Optional[ShaderProgram]
self._support_mesh_shader = None # type: Optional[ShaderProgram]
self._scene = Application.getInstance().getController().getScene()
# Set the camera to be used by this render pass
@ -83,8 +86,8 @@ class PreviewPass(RenderPass):
batch_support_mesh = RenderBatch(self._support_mesh_shader)
# Fill up the batch with objects that can be sliced.
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
if hasattr(node, "_outside_buildarea") and not node._outside_buildarea:
for node in DepthFirstIterator(self._scene.getRoot()):
if hasattr(node, "_outside_buildarea") and not getattr(node, "_outside_buildarea"):
if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible():
per_mesh_stack = node.callDecoration("getStack")
if node.callDecoration("isNonThumbnailVisibleMesh"):
@ -94,7 +97,7 @@ class PreviewPass(RenderPass):
# Support mesh
uniforms = {}
shade_factor = 0.6
diffuse_color = node.getDiffuseColor()
diffuse_color = cast(CuraSceneNode, node).getDiffuseColor()
diffuse_color2 = [
diffuse_color[0] * shade_factor,
diffuse_color[1] * shade_factor,
@ -106,7 +109,7 @@ class PreviewPass(RenderPass):
else:
# Normal scene node
uniforms = {}
uniforms["diffuse_color"] = prettier_color(node.getDiffuseColor())
uniforms["diffuse_color"] = prettier_color(cast(CuraSceneNode, node).getDiffuseColor())
batch.addItem(node.getWorldTransformation(), node.getMeshData(), uniforms = uniforms)
self.bind()

View file

@ -55,7 +55,7 @@ class GenericOutputController(PrinterOutputController):
self._preheat_hotends_timer.stop()
for extruder in self._preheat_hotends:
extruder.updateIsPreheating(False)
self._preheat_hotends = set() # type: Set[ExtruderOutputModel]
self._preheat_hotends = set()
def moveHead(self, printer: "PrinterOutputModel", x, y, z, speed) -> None:
self._output_device.sendCommand("G91")
@ -159,7 +159,7 @@ class GenericOutputController(PrinterOutputController):
def _onPreheatHotendsTimerFinished(self) -> None:
for extruder in self._preheat_hotends:
self.setTargetHotendTemperature(extruder.getPrinter(), extruder.getPosition(), 0)
self._preheat_hotends = set() #type: Set[ExtruderOutputModel]
self._preheat_hotends = set()
# Cancel any ongoing preheating timers, without setting back the temperature to 0
# This can be used eg at the start of a print
@ -167,7 +167,7 @@ class GenericOutputController(PrinterOutputController):
if self._preheat_hotends_timer.isActive():
for extruder in self._preheat_hotends:
extruder.updateIsPreheating(False)
self._preheat_hotends = set() #type: Set[ExtruderOutputModel]
self._preheat_hotends = set()
self._preheat_hotends_timer.stop()

View file

@ -115,7 +115,7 @@ class ExtruderManager(QObject):
selected_nodes = [] # type: List["SceneNode"]
for node in Selection.getAllSelectedObjects():
if node.callDecoration("isGroup"):
for grouped_node in BreadthFirstIterator(node): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
for grouped_node in BreadthFirstIterator(node):
if grouped_node.callDecoration("isGroup"):
continue
@ -132,7 +132,7 @@ class ExtruderManager(QObject):
elif current_extruder_trains:
object_extruders.add(current_extruder_trains[0].getId())
self._selected_object_extruders = list(object_extruders) # type: List[Union[str, "ExtruderStack"]]
self._selected_object_extruders = list(object_extruders)
return self._selected_object_extruders
@ -141,7 +141,7 @@ class ExtruderManager(QObject):
# This will trigger a recalculation of the extruders used for the
# selection.
def resetSelectedObjectExtruders(self) -> None:
self._selected_object_extruders = [] # type: List[Union[str, "ExtruderStack"]]
self._selected_object_extruders = []
self.selectedObjectExtrudersChanged.emit()
@pyqtSlot(result = QObject)

View file

@ -949,7 +949,7 @@ class MachineManager(QObject):
# Check to see if any objects are set to print with an extruder that will no longer exist
root_node = self._application.getController().getScene().getRoot()
for node in DepthFirstIterator(root_node): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
for node in DepthFirstIterator(root_node):
if node.getMeshData():
extruder_nr = node.callDecoration("getActiveExtruderPosition")

View file

@ -369,7 +369,7 @@ class CuraEngineBackend(QObject, Backend):
elif job.getResult() == StartJobResult.ObjectSettingError:
errors = {}
for node in DepthFirstIterator(self._application.getController().getScene().getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
for node in DepthFirstIterator(self._application.getController().getScene().getRoot()):
stack = node.callDecoration("getStack")
if not stack:
continue
@ -438,7 +438,7 @@ class CuraEngineBackend(QObject, Backend):
if not self._application.getPreferences().getValue("general/auto_slice"):
enable_timer = False
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
for node in DepthFirstIterator(self._scene.getRoot()):
if node.callDecoration("isBlockSlicing"):
enable_timer = False
self.setState(BackendState.Disabled)
@ -460,7 +460,7 @@ class CuraEngineBackend(QObject, Backend):
## Return a dict with number of objects per build plate
def _numObjectsPerBuildPlate(self) -> Dict[int, int]:
num_objects = defaultdict(int) #type: Dict[int, int]
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
for node in DepthFirstIterator(self._scene.getRoot()):
# Only count sliceable objects
if node.callDecoration("isSliceable"):
build_plate_number = node.callDecoration("getBuildPlateNumber")
@ -548,10 +548,11 @@ class CuraEngineBackend(QObject, Backend):
# Clear out any old gcode
self._scene.gcode_dict = {} # type: ignore
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
for node in DepthFirstIterator(self._scene.getRoot()):
if node.callDecoration("getLayerData"):
if not build_plate_numbers or node.callDecoration("getBuildPlateNumber") in build_plate_numbers:
node.getParent().removeChild(node)
# We can asume that all nodes have a parent as we're looping through the scene (and filter out root)
cast(SceneNode, node.getParent()).removeChild(node)
def markSliceAll(self) -> None:
for build_plate_number in range(self._application.getMultiBuildPlateModel().maxBuildPlate + 1):

View file

@ -11,6 +11,7 @@ import Arcus #For typing.
from UM.Job import Job
from UM.Logger import Logger
from UM.Scene.SceneNode import SceneNode
from UM.Settings.ContainerStack import ContainerStack #For typing.
from UM.Settings.SettingRelation import SettingRelation #For typing.
@ -150,7 +151,7 @@ class StartSliceJob(Job):
# Don't slice if there is a per object setting with an error value.
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
for node in DepthFirstIterator(self._scene.getRoot()):
if not isinstance(node, CuraSceneNode) or not node.isSelectable():
continue
@ -160,15 +161,16 @@ class StartSliceJob(Job):
with self._scene.getSceneLock():
# Remove old layer data.
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
for node in DepthFirstIterator(self._scene.getRoot()):
if node.callDecoration("getLayerData") and node.callDecoration("getBuildPlateNumber") == self._build_plate_number:
node.getParent().removeChild(node)
# Singe we walk through all nodes in the scene, they always have a parent.
cast(SceneNode, node.getParent()).removeChild(node)
break
# Get the objects in their groups to print.
object_groups = []
if stack.getProperty("print_sequence", "value") == "one_at_a_time":
for node in OneAtATimeIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
for node in OneAtATimeIterator(self._scene.getRoot()):
temp_list = []
# Node can't be printed, so don't bother sending it.
@ -183,7 +185,8 @@ class StartSliceJob(Job):
children = node.getAllChildren()
children.append(node)
for child_node in children:
if child_node.getMeshData() and child_node.getMeshData().getVertices() is not None:
mesh_data = child_node.getMeshData()
if mesh_data and mesh_data.getVertices() is not None:
temp_list.append(child_node)
if temp_list:
@ -194,8 +197,9 @@ class StartSliceJob(Job):
else:
temp_list = []
has_printing_mesh = False
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
if node.callDecoration("isSliceable") and node.getMeshData() and node.getMeshData().getVertices() is not None:
for node in DepthFirstIterator(self._scene.getRoot()):
mesh_data = node.getMeshData()
if node.callDecoration("isSliceable") and mesh_data and mesh_data.getVertices() is not None:
is_non_printing_mesh = bool(node.callDecoration("isNonPrintingMesh"))
# Find a reason not to add the node
@ -210,7 +214,7 @@ class StartSliceJob(Job):
Job.yieldThread()
#If the list doesn't have any model with suitable settings then clean the list
# If the list doesn't have any model with suitable settings then clean the list
# otherwise CuraEngine will crash
if not has_printing_mesh:
temp_list.clear()
@ -261,10 +265,14 @@ class StartSliceJob(Job):
for group in filtered_object_groups:
group_message = self._slice_message.addRepeatedMessage("object_lists")
if group[0].getParent() is not None and group[0].getParent().callDecoration("isGroup"):
self._handlePerObjectSettings(group[0].getParent(), group_message)
parent = group[0].getParent()
if parent is not None and parent.callDecoration("isGroup"):
self._handlePerObjectSettings(cast(CuraSceneNode, parent), group_message)
for object in group:
mesh_data = object.getMeshData()
if mesh_data is None:
continue
rot_scale = object.getWorldTransformation().getTransposed().getData()[0:3, 0:3]
translate = object.getWorldTransformation().getData()[:3, 3]
@ -288,7 +296,7 @@ class StartSliceJob(Job):
obj.vertices = flat_verts
self._handlePerObjectSettings(object, obj)
self._handlePerObjectSettings(cast(CuraSceneNode, object), obj)
Job.yieldThread()

View file

@ -85,7 +85,7 @@ class CuraProfileReader(ProfileReader):
profile = InstanceContainer(profile_id)
profile.setMetaDataEntry("type", "quality_changes")
try:
profile.deserialize(serialized)
profile.deserialize(serialized, file_name = profile_id)
except ContainerFormatError as e:
Logger.log("e", "Error in the format of a container: %s", str(e))
return None

View file

@ -1,10 +1,13 @@
# Cura PostProcessingPlugin
# Author: Amanda de Castilho
# Date: August 28, 2018
# Modified: November 16, 2018 by Joshua Pope-Lewis
# Description: This plugin inserts a line at the start of each layer,
# M117 - displays the filename and layer height to the LCD
# Alternatively, user can override the filename to display alt text + layer height
# Description: This plugin shows custom messages about your print on the Status bar...
# Please look at the 3 options
# - Scolling (SCROLL_LONG_FILENAMES) if enabled in Marlin and you arent printing a small item select this option.
# - Name: By default it will use the name generated by Cura (EG: TT_Test_Cube) - Type a custom name in here
# - Max Layer: Enabling this will show how many layers are in the entire print (EG: Layer 1 of 265!)
from ..Script import Script
from UM.Application import Application
@ -15,35 +18,72 @@ class DisplayFilenameAndLayerOnLCD(Script):
def getSettingDataString(self):
return """{
"name": "Display filename and layer on LCD",
"name": "Display Filename And Layer On LCD",
"key": "DisplayFilenameAndLayerOnLCD",
"metadata": {},
"version": 2,
"settings":
{
"scroll":
{
"label": "Scroll enabled/Small layers?",
"description": "If SCROLL_LONG_FILENAMES is enabled select this setting however, if the model is small disable this setting!",
"type": "bool",
"default_value": false
},
"name":
{
"label": "text to display:",
"label": "Text to display:",
"description": "By default the current filename will be displayed on the LCD. Enter text here to override the filename and display something else.",
"type": "str",
"default_value": ""
},
"startNum":
{
"label": "Initial layer number:",
"description": "Choose which number you prefer for the initial layer, 0 or 1",
"type": "int",
"default_value": 0,
"minimum_value": 0,
"maximum_value": 1
},
"maxlayer":
{
"label": "Display max layer?:",
"description": "Display how many layers are in the entire print on status bar?",
"type": "bool",
"default_value": true
}
}
}"""
def execute(self, data):
max_layer = 0
if self.getSettingValueByKey("name") != "":
name = self.getSettingValueByKey("name")
else:
name = Application.getInstance().getPrintInformation().jobName
lcd_text = "M117 " + name + " layer "
i = 0
name = Application.getInstance().getPrintInformation().jobName
if not self.getSettingValueByKey("scroll"):
if self.getSettingValueByKey("maxlayer"):
lcd_text = "M117 Layer "
else:
lcd_text = "M117 Printing Layer "
else:
lcd_text = "M117 Printing " + name + " - Layer "
i = self.getSettingValueByKey("startNum")
for layer in data:
display_text = lcd_text + str(i)
display_text = lcd_text + str(i) + " " + name
layer_index = data.index(layer)
lines = layer.split("\n")
for line in lines:
if line.startswith(";LAYER_COUNT:"):
max_layer = line
max_layer = max_layer.split(":")[1]
if line.startswith(";LAYER:"):
if self.getSettingValueByKey("maxlayer"):
display_text = display_text + " of " + max_layer
else:
display_text = display_text + "!"
line_index = lines.index(line)
lines.insert(line_index + 1, display_text)
i += 1

View file

@ -128,9 +128,26 @@ class Stretcher():
onestep = GCodeStep(0, in_relative_movement)
onestep.copyPosFrom(current)
elif _getValue(line, "G") == 1:
last_x = current.step_x
last_y = current.step_y
last_z = current.step_z
last_e = current.step_e
current.readStep(line)
onestep = GCodeStep(1, in_relative_movement)
onestep.copyPosFrom(current)
if (current.step_x == last_x and current.step_y == last_y and
current.step_z == last_z and current.step_e != last_e
):
# It's an extruder only move. Preserve it rather than process it as an
# extruded move. Otherwise, the stretched output might contain slight
# motion in X and Y in addition to E. This can cause problems with
# firmwares that implement pressure advance.
onestep = GCodeStep(-1, in_relative_movement)
onestep.copyPosFrom(current)
# Rather than copy the original line, write a new one with consistent
# extruder coordinates
onestep.comment = "G1 F{} E{}".format(onestep.step_f, onestep.step_e)
else:
onestep = GCodeStep(1, in_relative_movement)
onestep.copyPosFrom(current)
# end of relative movement
elif _getValue(line, "G") == 90:

View file

@ -218,10 +218,10 @@ class SimulationView(CuraView):
if theme is not None:
self._ghost_shader.setUniformValue("u_color", Color(*theme.getColor("layerview_ghost").getRgb()))
for node in DepthFirstIterator(scene.getRoot()): # type: ignore
for node in DepthFirstIterator(scene.getRoot()):
# We do not want to render ConvexHullNode as it conflicts with the bottom layers.
# However, it is somewhat relevant when the node is selected, so do render it then.
if type(node) is ConvexHullNode and not Selection.isSelected(node.getWatchedNode()):
if type(node) is ConvexHullNode and not Selection.isSelected(cast(ConvexHullNode, node).getWatchedNode()):
continue
if not node.render(renderer):
@ -572,14 +572,14 @@ class SimulationView(CuraView):
self._current_layer_jumps = job.getResult().get("jumps")
self._controller.getScene().sceneChanged.emit(self._controller.getScene().getRoot())
self._top_layers_job = None # type: Optional["_CreateTopLayersJob"]
self._top_layers_job = None
def _updateWithPreferences(self) -> None:
self._solid_layers = int(Application.getInstance().getPreferences().getValue("view/top_layer_count"))
self._only_show_top_layers = bool(Application.getInstance().getPreferences().getValue("view/only_show_top_layers"))
self._compatibility_mode = self._evaluateCompatibilityMode()
self.setSimulationViewType(int(float(Application.getInstance().getPreferences().getValue("layerview/layer_view_type"))));
self.setSimulationViewType(int(float(Application.getInstance().getPreferences().getValue("layerview/layer_view_type"))))
for extruder_nr, extruder_opacity in enumerate(Application.getInstance().getPreferences().getValue("layerview/extruder_opacities").split("|")):
try:

View file

@ -48,32 +48,32 @@ Window
ToolboxLoadingPage
{
id: viewLoading
visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "loading"
visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "loading"
}
ToolboxErrorPage
{
id: viewErrored
visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "errored"
visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "errored"
}
ToolboxDownloadsPage
{
id: viewDownloads
visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "overview"
visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "overview"
}
ToolboxDetailPage
{
id: viewDetail
visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "detail"
visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "detail"
}
ToolboxAuthorPage
{
id: viewAuthor
visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "author"
visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "author"
}
ToolboxInstalledPage
{
id: installedPluginList
visible: toolbox.viewCategory == "installed"
visible: toolbox.viewCategory === "installed"
}
}

View file

@ -1,9 +1,9 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2019 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.1 as UM
Item
@ -11,48 +11,17 @@ Item
id: base
property var packageData
property var technicalDataSheetUrl:
{
var link = undefined
if ("Technical Data Sheet" in packageData.links)
{
// HACK: This is the way the old API (used in 3.6-beta) used to do it. For safety it's still here,
// but it can be removed over time.
link = packageData.links["Technical Data Sheet"]
}
else if ("technicalDataSheet" in packageData.links)
{
link = packageData.links["technicalDataSheet"]
}
return link
}
property var safetyDataSheetUrl:
{
var sds_name = "safetyDataSheet"
return (sds_name in packageData.links) ? packageData.links[sds_name] : undefined
}
property var printingGuidelinesUrl:
{
var pg_name = "printingGuidelines"
return (pg_name in packageData.links) ? packageData.links[pg_name] : undefined
}
property var technicalDataSheetUrl: packageData.links.technicalDataSheet
property var safetyDataSheetUrl: packageData.links.safetyDataSheet
property var printingGuidelinesUrl: packageData.links.printingGuidelines
property var materialWebsiteUrl: packageData.links.website
property var materialWebsiteUrl:
{
var pg_name = "website"
return (pg_name in packageData.links) ? packageData.links[pg_name] : undefined
}
anchors.topMargin: UM.Theme.getSize("default_margin").height
height: visible ? childrenRect.height : 0
height: childrenRect.height
onVisibleChanged: packageData.type === "material" && (compatibilityItem.visible || dataSheetLinks.visible)
visible: packageData.type == "material" &&
(packageData.has_configs || technicalDataSheetUrl !== undefined ||
safetyDataSheetUrl !== undefined || printingGuidelinesUrl !== undefined ||
materialWebsiteUrl !== undefined)
Item
Column
{
id: combatibilityItem
id: compatibilityItem
visible: packageData.has_configs
width: parent.width
// This is a bit of a hack, but the whole QML is pretty messy right now. This needs a big overhaul.
@ -61,7 +30,6 @@ Item
Label
{
id: heading
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
text: catalog.i18nc("@label", "Compatibility")
wrapMode: Text.WordWrap
@ -73,8 +41,6 @@ Item
TableView
{
id: table
anchors.top: heading.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
frameVisible: false
@ -155,32 +121,32 @@ Item
TableViewColumn
{
role: "machine"
title: "Machine"
title: catalog.i18nc("@label:table_header", "Machine")
width: Math.floor(table.width * 0.25)
delegate: columnTextDelegate
}
TableViewColumn
{
role: "print_core"
title: "Print Core"
title: catalog.i18nc("@label:table_header", "Print Core")
width: Math.floor(table.width * 0.2)
}
TableViewColumn
{
role: "build_plate"
title: "Build Plate"
title: catalog.i18nc("@label:table_header", "Build Plate")
width: Math.floor(table.width * 0.225)
}
TableViewColumn
{
role: "support_material"
title: "Support"
title: catalog.i18nc("@label:table_header", "Support")
width: Math.floor(table.width * 0.225)
}
TableViewColumn
{
role: "quality"
title: "Quality"
title: catalog.i18nc("@label:table_header", "Quality")
width: Math.floor(table.width * 0.1)
}
}
@ -188,13 +154,14 @@ Item
Label
{
id: data_sheet_links
anchors.top: combatibilityItem.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height / 2
id: dataSheetLinks
anchors.top: compatibilityItem.bottom
anchors.topMargin: UM.Theme.getSize("narrow_margin").height
visible: base.technicalDataSheetUrl !== undefined ||
base.safetyDataSheetUrl !== undefined || base.printingGuidelinesUrl !== undefined ||
base.materialWebsiteUrl !== undefined
height: visible ? contentHeight : 0
base.safetyDataSheetUrl !== undefined ||
base.printingGuidelinesUrl !== undefined ||
base.materialWebsiteUrl !== undefined
text:
{
var result = ""

View file

@ -1,9 +1,8 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2019 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.1 as UM
Item
@ -11,10 +10,9 @@ Item
id: detailList
ScrollView
{
frameVisible: false
clip: true
anchors.fill: detailList
style: UM.Theme.styles.scrollview
flickableItem.flickableDirection: Flickable.VerticalFlick
Column
{
anchors

View file

@ -1,30 +1,30 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2019 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls 2.3
import UM 1.1 as UM
Item
{
id: tile
width: detailList.width - UM.Theme.getSize("wide_margin").width
height: normalData.height + compatibilityChart.height + 4 * UM.Theme.getSize("default_margin").height
Item
height: normalData.height + 2 * UM.Theme.getSize("wide_margin").height
Column
{
id: normalData
height: childrenRect.height
anchors
{
top: parent.top
left: parent.left
right: controls.left
rightMargin: UM.Theme.getSize("default_margin").width * 2 + UM.Theme.getSize("toolbox_loader").width
top: parent.top
rightMargin: UM.Theme.getSize("wide_margin").width
}
Label
{
id: packageName
width: parent.width
height: UM.Theme.getSize("toolbox_property_label").height
text: model.name
@ -33,9 +33,9 @@ Item
font: UM.Theme.getFont("medium_bold")
renderType: Text.NativeRendering
}
Label
{
anchors.top: packageName.bottom
width: parent.width
text: model.description
maximumLineCount: 25
@ -45,6 +45,12 @@ Item
font: UM.Theme.getFont("default")
renderType: Text.NativeRendering
}
ToolboxCompatibilityChart
{
width: parent.width
packageData: model
}
}
ToolboxDetailTileActions
@ -57,20 +63,12 @@ Item
packageData: model
}
ToolboxCompatibilityChart
{
id: compatibilityChart
anchors.top: normalData.bottom
width: normalData.width
packageData: model
}
Rectangle
{
color: UM.Theme.getColor("lining")
width: tile.width
height: UM.Theme.getSize("default_lining").height
anchors.top: compatibilityChart.bottom
anchors.top: normalData.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height + UM.Theme.getSize("wide_margin").height //Normal margin for spacing after chart, wide margin between items.
}
}

View file

@ -35,7 +35,7 @@ Column
// Don't allow installing while another download is running
enabled: installed || (!(toolbox.isDownloading && toolbox.activePackage != model) && !loginRequired)
opacity: enabled ? 1.0 : 0.5
visible: !updateButton.visible && !installed// Don't show when the update button is visible
visible: !updateButton.visible && !installed // Don't show when the update button is visible
}
Cura.SecondaryButton

View file

@ -2,9 +2,7 @@
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.3
import UM 1.1 as UM
Column

View file

@ -1,25 +1,20 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2019 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.1 as UM
ScrollView
{
frameVisible: false
clip: true
width: parent.width
height: parent.height
style: UM.Theme.styles.scrollview
flickableItem.flickableDirection: Flickable.VerticalFlick
Column
{
width: base.width
spacing: UM.Theme.getSize("default_margin").height
height: childrenRect.height
ToolboxDownloadsShowcase
{
@ -31,14 +26,14 @@ ScrollView
{
id: allPlugins
width: parent.width
heading: toolbox.viewCategory == "material" ? catalog.i18nc("@label", "Community Contributions") : catalog.i18nc("@label", "Community Plugins")
model: toolbox.viewCategory == "material" ? toolbox.materialsAvailableModel : toolbox.pluginsAvailableModel
heading: toolbox.viewCategory === "material" ? catalog.i18nc("@label", "Community Contributions") : catalog.i18nc("@label", "Community Plugins")
model: toolbox.viewCategory === "material" ? toolbox.materialsAvailableModel : toolbox.pluginsAvailableModel
}
ToolboxDownloadsGrid
{
id: genericMaterials
visible: toolbox.viewCategory == "material"
visible: toolbox.viewCategory === "material"
width: parent.width
heading: catalog.i18nc("@label", "Generic Materials")
model: toolbox.materialsGenericModel

View file

@ -1,50 +1,50 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2019 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Dialogs 1.1
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Controls 2.3
import UM 1.1 as UM
ScrollView
{
id: page
frameVisible: false
clip: true
width: parent.width
height: parent.height
style: UM.Theme.styles.scrollview
flickableItem.flickableDirection: Flickable.VerticalFlick
Column
{
width: page.width
spacing: UM.Theme.getSize("default_margin").height
padding: UM.Theme.getSize("wide_margin").width
visible: toolbox.pluginsInstalledModel.items.length > 0
height: childrenRect.height + 4 * UM.Theme.getSize("default_margin").height
anchors
{
right: parent.right
left: parent.left
margins: UM.Theme.getSize("default_margin").width
top: parent.top
}
height: childrenRect.height + 2 * UM.Theme.getSize("wide_margin").height
Label
{
width: page.width
anchors
{
left: parent.left
right: parent.right
margins: parent.padding
}
text: catalog.i18nc("@title:tab", "Plugins")
color: UM.Theme.getColor("text_medium")
font: UM.Theme.getFont("large")
renderType: Text.NativeRendering
}
Rectangle
{
anchors
{
left: parent.left
right: parent.right
margins: parent.padding
}
id: installedPlugins
color: "transparent"
width: parent.width
height: childrenRect.height + UM.Theme.getSize("default_margin").width
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width
@ -65,8 +65,15 @@ ScrollView
}
}
}
Label
{
anchors
{
left: parent.left
right: parent.right
margins: parent.padding
}
text: catalog.i18nc("@title:tab", "Materials")
color: UM.Theme.getColor("text_medium")
font: UM.Theme.getFont("medium")
@ -75,9 +82,14 @@ ScrollView
Rectangle
{
anchors
{
left: parent.left
right: parent.right
margins: parent.padding
}
id: installedMaterials
color: "transparent"
width: parent.width
height: childrenRect.height + UM.Theme.getSize("default_margin").width
border.color: UM.Theme.getColor("lining")
border.width: UM.Theme.getSize("default_lining").width

View file

@ -41,7 +41,7 @@ Item
Column
{
id: pluginInfo
topPadding: Math.floor(UM.Theme.getSize("default_margin").height / 2)
topPadding: UM.Theme.getSize("narrow_margin").height
property var color: model.type === "plugin" && !isEnabled ? UM.Theme.getColor("lining") : UM.Theme.getColor("text")
width: Math.floor(tileRow.width - (authorInfo.width + pluginActions.width + 2 * tileRow.spacing + ((disableButton.visible) ? disableButton.width + tileRow.spacing : 0)))
Label

View file

@ -1,16 +1,16 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2019 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.1 as UM
import Cura 1.0 as Cura
Item
Cura.PrimaryButton
{
id: base
id: button
property var active: false
property var complete: false
@ -25,43 +25,36 @@ Item
width: UM.Theme.getSize("toolbox_action_button").width
height: UM.Theme.getSize("toolbox_action_button").height
Cura.PrimaryButton
fixedWidthMode: true
text:
{
id: button
width: UM.Theme.getSize("toolbox_action_button").width
height: UM.Theme.getSize("toolbox_action_button").height
fixedWidthMode: true
text:
if (complete)
{
if (complete)
{
return completeLabel
}
else if (active)
{
return activeLabel
}
else
{
return readyLabel
}
return completeLabel
}
onClicked:
else if (active)
{
if (complete)
{
completeAction()
}
else if (active)
{
activeAction()
}
else
{
readyAction()
}
return activeLabel
}
else
{
return readyLabel
}
busy: active
}
onClicked:
{
if (complete)
{
completeAction()
}
else if (active)
{
activeAction()
}
else
{
readyAction()
}
}
busy: active
}

View file

@ -655,8 +655,12 @@ class Toolbox(QObject, Extension):
# Check if the download was sucessfull
if self._download_reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
Logger.log("w", "Failed to download package. The following error was returned: %s", json.loads(bytes(self._download_reply.readAll()).decode("utf-8")))
return
try:
Logger.log("w", "Failed to download package. The following error was returned: %s", json.loads(bytes(self._download_reply.readAll()).decode("utf-8")))
except json.decoder.JSONDecodeError:
Logger.logException("w", "Failed to download package and failed to parse a response from it")
finally:
return
# Must not delete the temporary file on Windows
self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curapackage", delete = False)
file_path = self._temp_plugin_file.name

View file

@ -243,10 +243,11 @@ Item
enabled: !contextMenuButton.enabled
}
MonitorInfoBlurb
{
id: contextMenuDisabledInfo
text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
target: contextMenuButton
}
// TODO: uncomment this tooltip as soon as the required firmware is released
// MonitorInfoBlurb
// {
// id: contextMenuDisabledInfo
// text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
// target: contextMenuButton
// }
}

View file

@ -81,7 +81,7 @@ Item
mipmap: true
}
}
Item
{
@ -99,7 +99,7 @@ Item
height: 18 * screenScaleFactor // TODO: Theme!
width: parent.width
radius: 2 * screenScaleFactor // TODO: Theme!
Label
{
text: printer && printer.name ? printer.name : ""
@ -202,12 +202,13 @@ Item
enabled: !contextMenuButton.enabled
}
MonitorInfoBlurb
{
id: contextMenuDisabledInfo
text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
target: contextMenuButton
}
// TODO: uncomment this tooltip as soon as the required firmware is released
// MonitorInfoBlurb
// {
// id: contextMenuDisabledInfo
// text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
// target: contextMenuButton
// }
CameraButton
{
@ -454,4 +455,4 @@ Item
id: overrideConfirmationDialog
printer: base.printer
}
}
}

View file

@ -174,9 +174,13 @@ class CloudApiClient:
model: Type[CloudApiClientModel],
) -> None:
def parse() -> None:
# Don't try to parse the reply if we didn't get one
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None:
return
status_code, response = self._parseReply(reply)
self._anti_gc_callbacks.remove(parse)
return self._parseModels(response, on_finished, model)
self._parseModels(response, on_finished, model)
return
self._anti_gc_callbacks.append(parse)
reply.finished.connect(parse)

View file

@ -969,7 +969,7 @@ class XmlMaterialProfile(InstanceContainer):
machine_compatibility = cls._parseCompatibleValue(entry.text)
for identifier in machine.iterfind("./um:machine_identifier", cls.__namespaces):
machine_id_list = product_id_map.get(identifier.get("product"), [])
machine_id_list = product_id_map.get(identifier.get("product", ""), [])
if not machine_id_list:
machine_id_list = cls.getPossibleDefinitionIDsFromName(identifier.get("product"))
@ -1001,7 +1001,7 @@ class XmlMaterialProfile(InstanceContainer):
result_metadata.append(new_material_metadata)
buildplates = machine.iterfind("./um:buildplate", cls.__namespaces)
buildplate_map = {} # type: Dict[str, Dict[str, bool]]
buildplate_map = {} # type: Dict[str, Dict[str, bool]]
buildplate_map["buildplate_compatible"] = {}
buildplate_map["buildplate_recommended"] = {}
for buildplate in buildplates:

View file

@ -162,6 +162,7 @@
"optimize_wall_printing_order": { "value": "True" },
"retraction_combing": { "default_value": "all" },
"initial_layer_line_width_factor": { "value": "120" },
"zig_zaggify_infill": { "value": "gradual_infill_steps == 0" }
"zig_zaggify_infill": { "value": "gradual_infill_steps == 0" },
"build_volume_temperature": { "maximum_value": 50 }
}
}

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="78px" height="53px" viewBox="0 0 78 53" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->
<title>Group-cloud Copy</title>
<desc>Created with Sketch.</desc>
<g id="Sign-in-/Message-restyle" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Artboard" transform="translate(-162.000000, -16.000000)">
<g id="Group-cloud-Copy" transform="translate(162.000000, 16.000000)">
<path d="M71.6139989,39.7264219 C71.5196898,37.5579439 70.9711289,35.5059663 70.0601048,33.6613194 L71.6937566,33.6613194 C72.8434847,33.6613194 73.787904,32.731337 73.787904,31.5991845 L73.8289659,31.5991845 L73.8289659,6.57052798 C73.8289659,6.1257538 73.4594104,5.80228166 73.0487931,5.80228166 L58.158788,5.80228166 L58.158788,25.1687374 C57.4862997,25.0807183 56.800231,25.0352941 56.103441,25.0352941 C55.374501,25.0352941 54.6572944,25.0850068 53.9550947,25.1811929 L53.9550947,5.80228166 L53.8935021,5.80228166 L53.8935021,4.68260671 C53.7612249,4.35507342 53.4329996,4.13943248 53.0774006,4.13943248 L24.4830482,4.13943248 C23.9749094,4.13943248 23.605354,4.54882691 23.605354,5.0037096 L23.605354,33.1609482 C23.605354,34.4346197 24.6678259,35.4808499 25.9612699,35.4808499 L41.3906551,35.4808499 C40.8638727,37.0247578 40.5782993,38.67857 40.5782993,40.3983852 C40.5782993,41.0436856 40.6185041,41.6796936 40.6965701,42.3040902 L25.2683535,42.3040902 C24.7602147,42.3495785 24.252076,42.5315316 23.8825205,42.8499495 L23.605354,43.122879 C23.3281874,43.5777618 22.7738542,43.6687383 22.219521,43.6687383 L19.7250218,43.6687383 C19.5864385,43.6687383 19.4478552,43.5322734 19.4478552,43.3958088 L19.4478552,39.7264219 L5.21483793,39.7264219 C4.76315904,39.7668558 4.31148018,39.928592 3.98298644,40.2116301 L3.73661615,40.4542343 C3.49024586,40.8585745 2.99750527,40.9394424 2.50476467,40.9394424 L0.287432013,40.9394424 C0.164246864,40.9394424 0.0410617159,40.8181403 0.0410617159,40.6968382 L0.0410617159,2.5675603 C0.0410617159,2.44625825 0.164246864,2.3249562 0.287432013,2.3249562 L19.4478552,2.3249562 L19.4478552,0.50037096 C19.4478552,0.363906153 19.5864385,0.227441345 19.7250218,0.227441345 L57.8816214,0.227441345 C58.0202046,0.227441345 58.158788,0.363906153 58.158788,0.50037096 L58.158788,2.3249562 L77.3192117,2.3249562 C77.4423969,2.3249562 77.565582,2.44625825 77.565582,2.5675603 L77.565582,40.6968382 C77.565582,40.8181403 77.4423969,40.9394424 77.3192117,40.9394424 L75.101879,40.9394424 C74.6502001,40.8990083 74.1985212,40.7372724 73.8700276,40.4542343 L73.6236573,40.2116301 C73.377287,39.8072899 72.8845464,39.7264219 72.3918058,39.7264219 L71.6139989,39.7264219 Z M19.4478552,5.80228166 L4.51678875,5.80228166 C4.06510989,5.80228166 3.73661615,6.16618781 3.73661615,6.57052798 L3.73661615,31.5991845 C3.73661615,32.731337 4.68103562,33.6613194 5.83076366,33.6613194 L19.4478552,33.6613194 L19.4478552,5.80228166 Z" id="Combined-Shape" fill="#E5E5E5" fill-rule="nonzero"></path>
<g id="Group" transform="translate(43.578299, 28.035294)" fill="#3282FF">
<path d="M12.5251415,24.7888094 C5.60769686,24.7888094 1.77635684e-14,19.2396454 1.77635684e-14,12.3944047 C1.77635684e-14,5.54916401 5.60769686,-4.26325641e-14 12.5251415,-4.26325641e-14 C19.4425861,-4.26325641e-14 25.050283,5.54916401 25.050283,12.3944047 C25.050283,19.2396454 19.4425861,24.7888094 12.5251415,24.7888094 Z M17.9438152,10.4266859 C17.7896596,9.07601357 16.6334927,8.04314651 15.2460924,8.04314651 C14.8607034,8.04314651 14.5523922,8.12259783 14.244081,8.28150044 C13.5503809,7.16918208 12.3171362,6.45412027 11.0068137,6.45412027 C8.84863548,6.45412027 7.15292402,8.20204914 7.15292402,10.4266859 C7.15292402,10.4266859 7.15292402,10.4266859 7.15292402,10.5061372 C5.84260152,10.6650398 4.8405902,11.8568095 4.8405902,13.2074818 C4.8405902,14.7170567 6.0738349,15.9882777 7.53831299,15.9882777 C8.69447989,15.9882777 16.1710259,15.9882777 17.5584262,15.9882777 C19.0229043,15.9882777 20.256149,14.7170567 20.256149,13.2074818 C20.256149,11.7773582 19.2541376,10.6650398 17.9438152,10.4266859 Z" id="Combined-Shape"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -0,0 +1,28 @@
{
"metadata": {
"name": "Colorblind Assist Dark",
"inherits": "cura-dark"
},
"colors": {
"x_axis": [212, 0, 0, 255],
"y_axis": [64, 64, 255, 255],
"model_default": [156, 201, 36, 255],
"model_overhang": [200, 0, 255, 255],
"xray": [26, 26, 62, 255],
"xray_error": [255, 0, 0, 255],
"layerview_inset_0": [255, 64, 0, 255],
"layerview_inset_x": [0, 156, 128, 255],
"layerview_skin": [255, 255, 86, 255],
"layerview_support": [255, 255, 0, 255],
"layerview_infill": [0, 255, 255, 255],
"layerview_support_infill": [0, 200, 200, 255],
"layerview_move_retraction": [0, 100, 255, 255]
}
}

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="78px" height="53px" viewBox="0 0 78 53" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->
<title>Group-cloud Copy</title>
<desc>Created with Sketch.</desc>
<g id="Sign-in-/Message-restyle" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Artboard" transform="translate(-162.000000, -16.000000)">
<g id="Group-cloud-Copy" transform="translate(162.000000, 16.000000)">
<path d="M71.6139989,39.7264219 C71.5196898,37.5579439 70.9711289,35.5059663 70.0601048,33.6613194 L71.6937566,33.6613194 C72.8434847,33.6613194 73.787904,32.731337 73.787904,31.5991845 L73.8289659,31.5991845 L73.8289659,6.57052798 C73.8289659,6.1257538 73.4594104,5.80228166 73.0487931,5.80228166 L58.158788,5.80228166 L58.158788,25.1687374 C57.4862997,25.0807183 56.800231,25.0352941 56.103441,25.0352941 C55.374501,25.0352941 54.6572944,25.0850068 53.9550947,25.1811929 L53.9550947,5.80228166 L53.8935021,5.80228166 L53.8935021,4.68260671 C53.7612249,4.35507342 53.4329996,4.13943248 53.0774006,4.13943248 L24.4830482,4.13943248 C23.9749094,4.13943248 23.605354,4.54882691 23.605354,5.0037096 L23.605354,33.1609482 C23.605354,34.4346197 24.6678259,35.4808499 25.9612699,35.4808499 L41.3906551,35.4808499 C40.8638727,37.0247578 40.5782993,38.67857 40.5782993,40.3983852 C40.5782993,41.0436856 40.6185041,41.6796936 40.6965701,42.3040902 L25.2683535,42.3040902 C24.7602147,42.3495785 24.252076,42.5315316 23.8825205,42.8499495 L23.605354,43.122879 C23.3281874,43.5777618 22.7738542,43.6687383 22.219521,43.6687383 L19.7250218,43.6687383 C19.5864385,43.6687383 19.4478552,43.5322734 19.4478552,43.3958088 L19.4478552,39.7264219 L5.21483793,39.7264219 C4.76315904,39.7668558 4.31148018,39.928592 3.98298644,40.2116301 L3.73661615,40.4542343 C3.49024586,40.8585745 2.99750527,40.9394424 2.50476467,40.9394424 L0.287432013,40.9394424 C0.164246864,40.9394424 0.0410617159,40.8181403 0.0410617159,40.6968382 L0.0410617159,2.5675603 C0.0410617159,2.44625825 0.164246864,2.3249562 0.287432013,2.3249562 L19.4478552,2.3249562 L19.4478552,0.50037096 C19.4478552,0.363906153 19.5864385,0.227441345 19.7250218,0.227441345 L57.8816214,0.227441345 C58.0202046,0.227441345 58.158788,0.363906153 58.158788,0.50037096 L58.158788,2.3249562 L77.3192117,2.3249562 C77.4423969,2.3249562 77.565582,2.44625825 77.565582,2.5675603 L77.565582,40.6968382 C77.565582,40.8181403 77.4423969,40.9394424 77.3192117,40.9394424 L75.101879,40.9394424 C74.6502001,40.8990083 74.1985212,40.7372724 73.8700276,40.4542343 L73.6236573,40.2116301 C73.377287,39.8072899 72.8845464,39.7264219 72.3918058,39.7264219 L71.6139989,39.7264219 Z M19.4478552,5.80228166 L4.51678875,5.80228166 C4.06510989,5.80228166 3.73661615,6.16618781 3.73661615,6.57052798 L3.73661615,31.5991845 C3.73661615,32.731337 4.68103562,33.6613194 5.83076366,33.6613194 L19.4478552,33.6613194 L19.4478552,5.80228166 Z" id="Combined-Shape" fill="#E5E5E5" fill-rule="nonzero"></path>
<g id="Group" transform="translate(43.578299, 28.035294)" fill="#3282FF">
<path d="M12.5251415,24.7888094 C5.60769686,24.7888094 1.77635684e-14,19.2396454 1.77635684e-14,12.3944047 C1.77635684e-14,5.54916401 5.60769686,-4.26325641e-14 12.5251415,-4.26325641e-14 C19.4425861,-4.26325641e-14 25.050283,5.54916401 25.050283,12.3944047 C25.050283,19.2396454 19.4425861,24.7888094 12.5251415,24.7888094 Z M17.9438152,10.4266859 C17.7896596,9.07601357 16.6334927,8.04314651 15.2460924,8.04314651 C14.8607034,8.04314651 14.5523922,8.12259783 14.244081,8.28150044 C13.5503809,7.16918208 12.3171362,6.45412027 11.0068137,6.45412027 C8.84863548,6.45412027 7.15292402,8.20204914 7.15292402,10.4266859 C7.15292402,10.4266859 7.15292402,10.4266859 7.15292402,10.5061372 C5.84260152,10.6650398 4.8405902,11.8568095 4.8405902,13.2074818 C4.8405902,14.7170567 6.0738349,15.9882777 7.53831299,15.9882777 C8.69447989,15.9882777 16.1710259,15.9882777 17.5584262,15.9882777 C19.0229043,15.9882777 20.256149,14.7170567 20.256149,13.2074818 C20.256149,11.7773582 19.2541376,10.6650398 17.9438152,10.4266859 Z" id="Combined-Shape"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -0,0 +1,29 @@
{
"metadata": {
"name": "Colorblind Assist Light",
"inherits": "cura-light"
},
"colors": {
"x_axis": [200, 0, 0, 255],
"y_axis": [64, 64, 255, 255],
"model_default": [156, 201, 36, 255],
"model_overhang": [200, 0, 255, 255],
"model_selection_outline": [12, 169, 227, 255],
"xray": [26, 26, 62, 255],
"xray_error": [255, 0, 0, 255],
"layerview_inset_0": [255, 64, 0, 255],
"layerview_inset_x": [0, 156, 128, 255],
"layerview_skin": [255, 255, 86, 255],
"layerview_support": [255, 255, 0, 255],
"layerview_infill": [0, 255, 255, 255],
"layerview_support_infill": [0, 200, 200, 255],
"layerview_move_retraction": [0, 100, 255, 255]
}
}

View file

@ -6,7 +6,7 @@ import pytest
from unittest.mock import patch
class TestConvexHullDecorator(SceneNodeDecorator):
class MockedConvexHullDecorator(SceneNodeDecorator):
def __init__(self):
super().__init__()
@ -14,7 +14,7 @@ class TestConvexHullDecorator(SceneNodeDecorator):
return Polygon([[5, 5], [-5, 5], [-5, -5], [5, -5]])
class TestInvalidConvexHullDecorator(SceneNodeDecorator):
class InvalidConvexHullDecorator(SceneNodeDecorator):
def __init__(self):
super().__init__()
@ -34,16 +34,16 @@ class TestCollidesWithAreas:
assert not cura_scene_node.collidesWithAreas([Polygon([[10, 10], [-10, 10], [-10, -10], [10, -10]])])
def test_convexHullIntersects(self, cura_scene_node):
cura_scene_node.addDecorator(TestConvexHullDecorator())
cura_scene_node.addDecorator(MockedConvexHullDecorator())
assert cura_scene_node.collidesWithAreas([Polygon([[10, 10], [-10, 10], [-10, -10], [10, -10]])])
def test_convexHullNoIntersection(self, cura_scene_node):
cura_scene_node.addDecorator(TestConvexHullDecorator())
cura_scene_node.addDecorator(MockedConvexHullDecorator())
assert not cura_scene_node.collidesWithAreas([Polygon([[60, 60], [40, 60], [40, 40], [60, 40]])])
def test_invalidConvexHull(self, cura_scene_node):
cura_scene_node.addDecorator(TestInvalidConvexHullDecorator())
cura_scene_node.addDecorator(InvalidConvexHullDecorator())
assert not cura_scene_node.collidesWithAreas([Polygon([[10, 10], [-10, 10], [-10, -10], [10, -10]])])

View file

@ -61,6 +61,7 @@ def test_getQualityChangesGroup(quality_mocked_application):
assert "herp" in manager.getQualityChangesGroups(mocked_stack)
@pytest.mark.skip("Doesn't work on remote")
def test_getDefaultQualityType(quality_mocked_application):
manager = QualityManager(quality_mocked_application)
manager.initialize()