Merge remote-tracking branch 'origin/WIP_onboarding' into WIP_onboarding_by_ip

This commit is contained in:
Remco Burema 2019-03-14 11:40:44 +01:00
commit 61821e6378
77 changed files with 2138 additions and 272 deletions

View file

@ -114,6 +114,8 @@ from cura.Settings.CuraFormulaFunctions import CuraFormulaFunctions
from cura.ObjectsModel import ObjectsModel
from cura.Machines.Models.DiscoveredPrintersModel import DiscoveredPrintersModel
from cura.PrinterOutputDevice import PrinterOutputDevice
from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage
@ -210,6 +212,8 @@ class CuraApplication(QtApplication):
self._cura_scene_controller = None
self._machine_error_checker = None
self._discovered_printer_model = DiscoveredPrintersModel(self)
self._welcome_pages_model = WelcomePagesModel(self)
self._quality_profile_drop_down_menu_model = None
@ -846,6 +850,10 @@ class CuraApplication(QtApplication):
# Hide the splash screen
self.closeSplash()
@pyqtSlot(result = QObject)
def getDiscoveredPrintersModel(self, *args) -> "DiscoveredPrintersModel":
return self._discovered_printer_model
@pyqtSlot(result = QObject)
def getSettingVisibilityPresetsModel(self, *args) -> SettingVisibilityPresetsModel:
return self._setting_visibility_presets_model
@ -1003,6 +1011,8 @@ class CuraApplication(QtApplication):
qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel")
qmlRegisterType(MachineManagementModel, "Cura", 1, 0, "MachineManagementModel")
qmlRegisterType(DiscoveredPrintersModel, "Cura", 1, 0, "DiscoveredPrintersModel")
qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0,
"QualityProfilesDropDownMenuModel", self.getQualityProfilesDropDownMenuModel)
qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0,

View file

@ -537,6 +537,16 @@ class MaterialManager(QObject):
return
nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list
# Sort all nodes with respect to the container ID lengths in the ascending order so the base material container
# will be the first one to be removed. We need to do this to ensure that all containers get loaded & deleted.
nodes_to_remove = sorted(nodes_to_remove, key = lambda x: len(x.getMetaDataEntry("id", "")))
# Try to load all containers first. If there is any faulty ones, they will be put into the faulty container
# list, so removeContainer() can ignore those ones.
for node in nodes_to_remove:
container_id = node.getMetaDataEntry("id", "")
results = self._container_registry.findContainers(id = container_id)
if not results:
self._container_registry.addWrongContainerId(container_id)
for node in nodes_to_remove:
self._container_registry.removeContainer(node.getMetaDataEntry("id", ""))

View file

@ -0,0 +1,128 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Callable, List, Optional, TYPE_CHECKING
from PyQt5.QtCore import pyqtSlot, pyqtProperty, pyqtSignal, QObject
from UM.i18n import i18nCatalog
from UM.Logger import Logger
if TYPE_CHECKING:
from PyQt5.QtCore import QObject
catalog = i18nCatalog("cura")
class DiscoveredPrinter(QObject):
def __init__(self, ip_address: str, key: str, name: str, create_callback: Callable[[str], None], machine_type: str,
device, parent = None) -> None:
super().__init__(parent)
self._ip_address = ip_address
self._key = key
self._name = name
self.create_callback = create_callback
self._machine_type = machine_type
self._device = device
nameChanged = pyqtSignal()
def getKey(self) -> str:
return self._key
@pyqtProperty(str, notify = nameChanged)
def name(self) -> str:
return self._name
def setName(self, name: str) -> None:
if self._name != name:
self._name = name
self.nameChanged.emit()
machineTypeChanged = pyqtSignal()
@pyqtProperty(str, notify = machineTypeChanged)
def machine_type(self) -> str:
return self._machine_type
def setMachineType(self, machine_type: str) -> None:
if self._machine_type != machine_type:
self._machine_type = machine_type
self.machineTypeChanged.emit()
# Human readable machine type string
@pyqtProperty(str, notify = machineTypeChanged)
def readable_machine_type(self) -> str:
from cura.CuraApplication import CuraApplication
readable_type = CuraApplication.getInstance().getMachineManager().getMachineTypeNameFromId(self._machine_type)
if not readable_type:
readable_type = catalog.i18nc("@label", "Unknown")
return readable_type
@pyqtProperty(bool, notify = machineTypeChanged)
def is_unknown_machine_type(self) -> bool:
return self.readable_machine_type.lower() == "unknown"
@pyqtProperty(QObject, constant = True)
def device(self):
return self._device
#
# Discovered printers are all the printers that were found on the network, which provide a more convenient way
# to add networked printers (Plugin finds a bunch of printers, user can select one from the list, plugin can then
# add that printer to Cura as the active one).
#
class DiscoveredPrintersModel(QObject):
def __init__(self, parent: Optional["QObject"]) -> None:
super().__init__(parent)
self._discovered_printer_dict = dict()
discoveredPrintersChanged = pyqtSignal()
@pyqtProperty(list, notify = discoveredPrintersChanged)
def discovered_printers(self) -> "List[DiscoveredPrinter]":
item_list = list(x for x in self._discovered_printer_dict.values())
item_list.sort(key = lambda x: x.name)
return item_list
def addDiscoveredPrinter(self, ip_address: str, key: str, name: str, create_callback: Callable[[str], None],
machine_type: str, device) -> None:
if ip_address in self._discovered_printer_dict:
Logger.log("e", "Printer with ip [%s] has already been added", ip_address)
return
discovered_printer = DiscoveredPrinter(ip_address, key, name, create_callback, machine_type, device, parent = self)
self._discovered_printer_dict[ip_address] = discovered_printer
self.discoveredPrintersChanged.emit()
def updateDiscoveredPrinter(self, ip_address: str,
name: Optional[str] = None,
machine_type: Optional[str] = None) -> None:
if ip_address not in self._discovered_printer_dict:
Logger.log("e", "Printer with ip [%s] is not known", ip_address)
return
item = self._discovered_printer_dict[ip_address]
if name is not None:
item.setName(name)
if machine_type is not None:
item.setMachineType(machine_type)
def removeDiscoveredPrinter(self, ip_address: str) -> None:
if ip_address not in self._discovered_printer_dict:
Logger.log("i", "Key [%s] does not exist in the discovered printers list.", ip_address)
return
del self._discovered_printer_dict[ip_address]
self.discoveredPrintersChanged.emit()
@pyqtSlot("QVariant")
def createMachineFromDiscoveredPrinter(self, discovered_printer: "DiscoveredPrinter") -> None:
discovered_printer.create_callback(discovered_printer.getKey())

View file

@ -338,7 +338,7 @@ class ExtruderManager(QObject):
extruder_train.setNextStack(global_stack)
extruders_changed = True
self._fixSingleExtrusionMachineExtruderDefinition(global_stack)
self.fixSingleExtrusionMachineExtruderDefinition(global_stack)
if extruders_changed:
self.extrudersChanged.emit(global_stack_id)
self.setActiveExtruderIndex(0)
@ -346,7 +346,7 @@ class ExtruderManager(QObject):
# After 3.4, all single-extrusion machines have their own extruder definition files instead of reusing
# "fdmextruder". We need to check a machine here so its extruder definition is correct according to this.
def _fixSingleExtrusionMachineExtruderDefinition(self, global_stack: "GlobalStack") -> None:
def fixSingleExtrusionMachineExtruderDefinition(self, global_stack: "GlobalStack") -> None:
container_registry = ContainerRegistry.getInstance()
expected_extruder_definition_0_id = global_stack.getMetaDataEntry("machine_extruder_trains")["0"]
extruder_stack_0 = global_stack.extruders.get("0")

View file

@ -4,7 +4,7 @@
import time
import re
import unicodedata
from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast, NamedTuple, Callable
from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
@ -49,8 +49,6 @@ if TYPE_CHECKING:
from cura.Machines.QualityChangesGroup import QualityChangesGroup
from cura.Machines.QualityGroup import QualityGroup
DiscoveredPrinter = NamedTuple("DiscoveredPrinter", [("key", str), ("name", str), ("create_callback", Callable[[str], None]), ("machine_type", "str")])
class MachineManager(QObject):
def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None:
@ -136,9 +134,6 @@ class MachineManager(QObject):
self.globalContainerChanged.connect(self.printerConnectedStatusChanged)
self.outputDevicesChanged.connect(self.printerConnectedStatusChanged)
# This will contain all discovered network printers
self._discovered_printers = {} # type: Dict[str, DiscoveredPrinter]
activeQualityGroupChanged = pyqtSignal()
activeQualityChangesGroupChanged = pyqtSignal()
@ -178,30 +173,6 @@ class MachineManager(QObject):
self.outputDevicesChanged.emit()
# Discovered printers are all the printers that were found on the network, which provide a more convenient way
# to add networked printers (Plugin finds a bunch of printers, user can select one from the list, plugin can then
# add that printer to Cura as the active one).
def addDiscoveredPrinter(self, key: str, name: str, create_callback: Callable[[str], None], machine_type: str) -> None:
if key not in self._discovered_printers:
self._discovered_printers[key] = DiscoveredPrinter(key, name, create_callback, machine_type)
self.discoveredPrintersChanged.emit()
else:
Logger.log("e", "Printer with the key %s was already in the discovered printer list", key)
def removeDiscoveredPrinter(self, key: str) -> None:
if key in self._discovered_printers:
del self._discovered_printers[key]
self.discoveredPrintersChanged.emit()
@pyqtProperty("QVariantList", notify = discoveredPrintersChanged)
def discoveredPrinters(self):
return list(self._discovered_printers.values())
@pyqtSlot(str)
def addMachineFromDiscoveredPrinter(self, key: str) -> None:
if key in self._discovered_printers:
self._discovered_printers[key].create_callback(key)
@pyqtProperty(QObject, notify = currentConfigurationChanged)
def currentConfiguration(self) -> ConfigurationModel:
return self._current_printer_configuration
@ -386,7 +357,7 @@ class MachineManager(QObject):
# Make sure that the default machine actions for this machine have been added
self._application.getMachineActionManager().addDefaultMachineActions(global_stack)
ExtruderManager.getInstance()._fixSingleExtrusionMachineExtruderDefinition(global_stack)
ExtruderManager.getInstance().fixSingleExtrusionMachineExtruderDefinition(global_stack)
if not global_stack.isValid():
# Mark global stack as invalid
ConfigurationErrorMessage.getInstance().addFaultyContainers(global_stack.getId())
@ -1686,3 +1657,47 @@ class MachineManager(QObject):
abbr_machine += stripped_word
return abbr_machine
def getMachineTypeNameFromId(self, machine_type_id: str) -> str:
machine_type_name = ""
results = self._container_registry.findDefinitionContainersMetadata(id = machine_type_id)
if results:
machine_type_name = results[0]["name"]
return machine_type_name
@pyqtSlot(QObject)
def associateActiveMachineWithPrinterDevice(self, printer_device: Optional["PrinterOutputDevice"]) -> None:
if not printer_device:
return
Logger.log("d", "Attempting to set the network key of the active machine to %s", printer_device.key)
global_stack = self._global_container_stack
if not global_stack:
return
meta_data = global_stack.getMetaData()
if "um_network_key" in meta_data: # Global stack already had a connection, but it's changed.
old_network_key = meta_data["um_network_key"]
# Since we might have a bunch of hidden stacks, we also need to change it there.
metadata_filter = {"um_network_key": old_network_key}
containers = self._container_registry.findContainerStacks(type = "machine", **metadata_filter)
for container in containers:
container.setMetaDataEntry("um_network_key", printer_device.key)
# Delete old authentication data.
Logger.log("d", "Removing old authentication id %s for device %s",
global_stack.getMetaDataEntry("network_authentication_id", None),
printer_device.key)
container.removeMetaDataEntry("network_authentication_id")
container.removeMetaDataEntry("network_authentication_key")
# Ensure that these containers do know that they are configured for network connection
container.addConfiguredConnectionType(printer_device.connectionType.value)
else: # Global stack didn't have a connection yet, configure it.
global_stack.setMetaDataEntry("um_network_key", printer_device.key)
global_stack.addConfiguredConnectionType(printer_device.connectionType.value)

View file

@ -3,7 +3,7 @@
import os
from typing import TYPE_CHECKING, Optional
from PyQt5.QtCore import QUrl, Qt
from PyQt5.QtCore import QUrl, Qt, pyqtSlot
from UM.Qt.ListModel import ListModel
from UM.Resources import Resources
@ -12,6 +12,7 @@ from logging import Logger
if TYPE_CHECKING:
from PyQt5.QtCore import QObject
class WelcomePagesModel(ListModel):
IdRole = Qt.UserRole + 1 # Page ID
@ -52,6 +53,11 @@ class WelcomePagesModel(ListModel):
os.path.join("WelcomePages",
"DataCollectionsContent.qml"))),
})
self._pages.append({"id": "add_printer_by_selection",
"page_url": QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles,
os.path.join("WelcomePages",
"AddPrinterBySelectionContent.qml"))),
})
self._pages.append({"id": "add_printer_by_ip",
"page_url": QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles,
os.path.join("WelcomePages", "AddPrinterByIpContent.qml")))})

View file

@ -26,6 +26,7 @@ from UM.Preferences import Preferences
from cura.Machines.VariantType import VariantType
from cura.Settings.CuraStackBuilder import CuraStackBuilder
from cura.Settings.ExtruderManager import ExtruderManager
from cura.Settings.ExtruderStack import ExtruderStack
from cura.Settings.GlobalStack import GlobalStack
from cura.Settings.CuraContainerStack import _ContainerIndexes
@ -781,6 +782,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if not quality_changes_info.extruder_info_dict:
container_info = ContainerInfo(None, None, None)
quality_changes_info.extruder_info_dict["0"] = container_info
# If the global stack we're "targeting" has never been active, but was updated from Cura 3.4,
# it might not have it's extruders set properly.
if not global_stack.extruders:
ExtruderManager.getInstance().fixSingleExtrusionMachineExtruderDefinition(global_stack)
extruder_stack = global_stack.extruders["0"]
container = quality_manager._createQualityChanges(quality_changes_quality_type, quality_changes_name,

View file

@ -326,6 +326,7 @@ class StartSliceJob(Job):
result["print_bed_temperature"] = result["material_bed_temperature"] # Renamed settings.
result["print_temperature"] = result["material_print_temperature"]
result["travel_speed"] = result["speed_travel"]
result["time"] = time.strftime("%H:%M:%S") #Some extra settings.
result["date"] = time.strftime("%d-%m-%Y")
result["day"] = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][int(time.strftime("%w"))]

View file

@ -0,0 +1,49 @@
# Created by Wayne Porter
from ..Script import Script
class InsertAtLayerChange(Script):
def __init__(self):
super().__init__()
def getSettingDataString(self):
return """{
"name": "Insert at layer change",
"key": "InsertAtLayerChange",
"metadata": {},
"version": 2,
"settings":
{
"insert_location":
{
"label": "When to insert",
"description": "Whether to insert code before or after layer change.",
"type": "enum",
"options": {"before": "Before", "after": "After"},
"default_value": "before"
},
"gcode_to_add":
{
"label": "GCODE to insert.",
"description": "GCODE to add before or after layer change.",
"type": "str",
"default_value": ""
}
}
}"""
def execute(self, data):
gcode_to_add = self.getSettingValueByKey("gcode_to_add") + "\n"
for layer in data:
# Check that a layer is being printed
lines = layer.split("\n")
if ";LAYER:" in lines[0]:
index = data.index(layer)
if self.getSettingValueByKey("insert_location") == "before":
layer = gcode_to_add + layer
else:
layer = layer + gcode_to_add
data[index] = layer
return data

View file

@ -0,0 +1,94 @@
# Created by Wayne Porter
from ..Script import Script
class TimeLapse(Script):
def __init__(self):
super().__init__()
def getSettingDataString(self):
return """{
"name": "Time Lapse",
"key": "TimeLapse",
"metadata": {},
"version": 2,
"settings":
{
"trigger_command":
{
"label": "Trigger camera command",
"description": "Gcode command used to trigger camera.",
"type": "str",
"default_value": "M240"
},
"pause_length":
{
"label": "Pause length",
"description": "How long to wait (in ms) after camera was triggered.",
"type": "int",
"default_value": 700,
"minimum_value": 0,
"unit": "ms"
},
"park_print_head":
{
"label": "Park Print Head",
"description": "Park the print head out of the way. Assumes absolute positioning.",
"type": "bool",
"default_value": true
},
"head_park_x":
{
"label": "Park Print Head X",
"description": "What X location does the head move to for photo.",
"unit": "mm",
"type": "float",
"default_value": 0,
"enabled": "park_print_head"
},
"head_park_y":
{
"label": "Park Print Head Y",
"description": "What Y location does the head move to for photo.",
"unit": "mm",
"type": "float",
"default_value": 190,
"enabled": "park_print_head"
},
"park_feed_rate":
{
"label": "Park Feed Rate",
"description": "How fast does the head move to the park coordinates.",
"unit": "mm/s",
"type": "float",
"default_value": 9000,
"enabled": "park_print_head"
}
}
}"""
def execute(self, data):
feed_rate = self.getSettingValueByKey("park_feed_rate")
park_print_head = self.getSettingValueByKey("park_print_head")
x_park = self.getSettingValueByKey("head_park_x")
y_park = self.getSettingValueByKey("head_park_y")
trigger_command = self.getSettingValueByKey("trigger_command")
pause_length = self.getSettingValueByKey("pause_length")
gcode_to_append = ";TimeLapse Begin\n"
if park_print_head:
gcode_to_append += self.putValue(G = 1, F = feed_rate, X = x_park, Y = y_park) + ";Park print head\n"
gcode_to_append += self.putValue(M = 400) + ";Wait for moves to finish\n"
gcode_to_append += trigger_command + ";Snap Photo\n"
gcode_to_append += self.putValue(G = 4, P = pause_length) + ";Wait for camera\n"
gcode_to_append += ";TimeLapse End\n"
for layer in data:
# Check that a layer is being printed
lines = layer.split("\n")
if ";LAYER:" in lines[0]:
index = data.index(layer)
layer += gcode_to_append
data[index] = layer
return data

View file

@ -12,8 +12,10 @@ from UM.Backend.Backend import BackendState
from UM.FileHandler.FileHandler import FileHandler
from UM.Logger import Logger
from UM.Message import Message
from UM.PluginRegistry import PluginRegistry
from UM.Qt.Duration import Duration, DurationFormat
from UM.Scene.SceneNode import SceneNode
from cura.CuraApplication import CuraApplication
from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState, NetworkedPrinterOutputDevice
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
@ -82,8 +84,11 @@ class CloudOutputDevice(NetworkedPrinterOutputDevice):
self._account = api_client.account
# We use the Cura Connect monitor tab to get most functionality right away.
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
"../../resources/qml/MonitorStage.qml")
if PluginRegistry.getInstance() is not None:
self._monitor_view_qml_path = os.path.join(
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
"resources", "qml", "MonitorStage.qml"
)
# Trigger the printersChanged signal when the private signal is triggered.
self.printersChanged.connect(self._clusterPrintersChanged)

View file

@ -10,13 +10,13 @@ import os
from UM.FileHandler.FileHandler import FileHandler
from UM.FileHandler.WriteFileJob import WriteFileJob # To call the file writer asynchronously.
from UM.Logger import Logger
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.i18n import i18nCatalog
from UM.Qt.Duration import Duration, DurationFormat
from UM.Logger import Logger
from UM.Message import Message
from UM.PluginRegistry import PluginRegistry
from UM.Qt.Duration import Duration, DurationFormat
from UM.Scene.SceneNode import SceneNode # For typing.
from UM.Settings.ContainerRegistry import ContainerRegistry
from cura.CuraApplication import CuraApplication
from cura.PrinterOutput.ConfigurationModel import ConfigurationModel
@ -65,7 +65,11 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
self._print_jobs = [] # type: List[UM3PrintJobOutputModel]
self._received_print_jobs = False # type: bool
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorStage.qml")
if PluginRegistry.getInstance() is not None:
self._monitor_view_qml_path = os.path.join(
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
"resources", "qml", "MonitorStage.qml"
)
# Trigger the printersChanged signal when the private signal is triggered
self.printersChanged.connect(self._clusterPrintersChanged)
@ -126,7 +130,11 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
def _spawnPrinterSelectionDialog(self):
if self._printer_selection_dialog is None:
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/PrintWindow.qml")
if PluginRegistry.getInstance() is not None:
path = os.path.join(
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
"resources", "qml", "PrintWindow.qml"
)
self._printer_selection_dialog = self._application.createQmlComponent(path, {"OutputDevice": self})
if self._printer_selection_dialog is not None:
self._printer_selection_dialog.show()
@ -624,6 +632,9 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
printer.updateName(data["friendly_name"])
printer.updateKey(data["uuid"])
printer.updateType(data["machine_variant"])
self._application.getDiscoveredPrintersModel().updateDiscoveredPrinter(data["ip_address"],
name = data["friendly_name"],
machine_type = data["machine_variant"])
# Do not store the build plate information that comes from connect if the current printer has not build plate information
if "build_plate" in data and machine_definition.getMetaDataEntry("has_variant_buildplates", False):

View file

@ -118,7 +118,7 @@ class DiscoverUM3Action(MachineAction):
if self._network_plugin:
# Ensure that the connection states are refreshed.
self._network_plugin.reCheckConnections()
self._network_plugin.refreshConnections()
# Associates the currently active machine with the given printer device. The network connection information will be
# stored into the metadata of the currently active machine.
@ -160,7 +160,7 @@ class DiscoverUM3Action(MachineAction):
if self._network_plugin:
# Ensure that the connection states are refreshed.
self._network_plugin.reCheckConnections()
self._network_plugin.refreshConnections()
@pyqtSlot(result = str)
def getStoredKey(self) -> str:

View file

@ -1,7 +1,5 @@
from typing import List, Optional
from UM.FileHandler.FileHandler import FileHandler
from UM.Scene.SceneNode import SceneNode
from cura.CuraApplication import CuraApplication
from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice, AuthState
from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
@ -12,10 +10,13 @@ from cura.PrinterOutputDevice import ConnectionType
from cura.Settings.ContainerManager import ContainerManager
from cura.Settings.ExtruderManager import ExtruderManager
from UM.Logger import Logger
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.FileHandler.FileHandler import FileHandler
from UM.i18n import i18nCatalog
from UM.Logger import Logger
from UM.Message import Message
from UM.PluginRegistry import PluginRegistry
from UM.Scene.SceneNode import SceneNode
from UM.Settings.ContainerRegistry import ContainerRegistry
from PyQt5.QtNetwork import QNetworkRequest
from PyQt5.QtCore import QTimer, QUrl
@ -76,7 +77,11 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
self.setIconName("print")
self._monitor_view_qml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../resources/qml/MonitorItem.qml")
if PluginRegistry.getInstance() is not None:
self._monitor_view_qml_path = os.path.join(
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
"resources", "qml", "MonitorStage.qml"
)
self._output_controller = LegacyUM3PrinterOutputController(self)

View file

@ -16,11 +16,14 @@ from cura.PrinterOutputDevice import ConnectionType
from cura.Settings.GlobalStack import GlobalStack # typing
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
from UM.OutputDevice.OutputDeviceManager import ManualDeviceAdditionAttempt
from UM.i18n import i18nCatalog
from UM.Logger import Logger
from UM.Message import Message
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
from UM.PluginRegistry import PluginRegistry
from UM.Signal import Signal, signalemitter
from UM.Version import Version
from UM.Message import Message
from UM.i18n import i18nCatalog
from . import ClusterUM3OutputDevice, LegacyUM3OutputDevice
from .Cloud.CloudOutputDeviceManager import CloudOutputDeviceManager
@ -54,7 +57,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
self.addDeviceSignal.connect(self._onAddDevice)
self.removeDeviceSignal.connect(self._onRemoveDevice)
self._application.globalContainerStackChanged.connect(self.reCheckConnections)
self._application.globalContainerStackChanged.connect(self.refreshConnections)
self._discovered_devices = {}
@ -141,7 +144,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
self.addManualDevice(address)
self.resetLastManualDevice()
def reCheckConnections(self):
def refreshConnections(self):
active_machine = CuraApplication.getInstance().getGlobalContainerStack()
if not active_machine:
return
@ -225,7 +228,22 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
def _createMachineFromDiscoveredPrinter(self, key: str) -> None:
# TODO: This needs to be implemented. It's supposed to create a machine given a unique key as already discovered
# by this plugin.
pass
discovered_device = self._discovered_devices.get(key)
if discovered_device is None:
Logger.log("e", "Could not find discovered device with key [%s]", key)
return
group_name = discovered_device.getProperty("name")
machine_type_id = discovered_device.getProperty("printer_type")
Logger.log("i", "Creating machine from network device with key = [%s], group name = [%s], printer type = [%s]",
key, group_name, machine_type_id)
self._application.getMachineManager().addMachine(machine_type_id, group_name)
# connect the new machine to that network printer
self._application.getMachineManager().associateActiveMachineWithPrinterDevice(discovered_device)
# ensure that the connection states are refreshed.
self.refreshConnections()
def _checkManualDevice(self, address):
# Check if a UM3 family device exists at this address.
@ -315,7 +333,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
except TypeError:
# Disconnect already happened.
pass
self._application.getMachineManager().removeDiscoveredPrinter(device.getId())
self._application.getDiscoveredPrintersModel().removeDiscoveredPrinter(device.address)
self.discoveredDevicesChanged.emit()
def _onAddDevice(self, name, address, properties):
@ -340,7 +358,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
device = ClusterUM3OutputDevice.ClusterUM3OutputDevice(name, address, properties)
else:
device = LegacyUM3OutputDevice.LegacyUM3OutputDevice(name, address, properties)
self._application.getMachineManager().addDiscoveredPrinter(device.getId(), name, self._createMachineFromDiscoveredPrinter, properties[b"printer_type"].decode("utf-8"))
self._application.getDiscoveredPrintersModel().addDiscoveredPrinter(address, device.getId(), name, self._createMachineFromDiscoveredPrinter, properties[b"printer_type"].decode("utf-8"), device)
self._discovered_devices[device.getId()] = device
self.discoveredDevicesChanged.emit()
@ -477,8 +495,10 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
self._start_cloud_flow_message = Message(
text = i18n_catalog.i18nc("@info:status", "Send and monitor print jobs from anywhere using your Ultimaker account."),
lifetime = 0,
image_source = QUrl.fromLocalFile(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..",
"resources", "svg", "cloud-flow-start.svg")),
image_source = QUrl.fromLocalFile(os.path.join(
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
"resources", "svg", "cloud-flow-start.svg"
)),
image_caption = i18n_catalog.i18nc("@info:status", "Connect to Ultimaker Cloud"),
option_text = i18n_catalog.i18nc("@action", "Don't ask me again for this printer."),
option_state = False
@ -499,8 +519,10 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
self._cloud_flow_complete_message = Message(
text = i18n_catalog.i18nc("@info:status", "You can now send and monitor print jobs from anywhere using your Ultimaker account."),
lifetime = 30,
image_source = QUrl.fromLocalFile(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..",
"resources", "svg", "cloud-flow-completed.svg")),
image_source = QUrl.fromLocalFile(os.path.join(
PluginRegistry.getInstance().getPluginPath("UM3NetworkPrinting"),
"resources", "svg", "cloud-flow-completed.svg"
)),
image_caption = i18n_catalog.i18nc("@info:status", "Connected!")
)
# Don't show the review connection link if we're not on the local network

View file

@ -243,7 +243,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._last_temperature_request = time()
if re.search(b"[B|T\d*]: ?\d+\.?\d*", line): # Temperature message. 'T:' for extruder and 'B:' for bed
extruder_temperature_matches = re.findall(b"T(\d*): ?(\d+\.?\d*) ?\/?(\d+\.?\d*)?", line)
extruder_temperature_matches = re.findall(b"T(\d*): ?(\d+\.?\d*)\s*\/?(\d+\.?\d*)?", line)
# Update all temperature values
matched_extruder_nrs = []
for match in extruder_temperature_matches:
@ -265,7 +265,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
if match[2]:
extruder.updateTargetHotendTemperature(float(match[2]))
bed_temperature_matches = re.findall(b"B: ?(\d+\.?\d*) ?\/?(\d+\.?\d*) ?", line)
bed_temperature_matches = re.findall(b"B: ?(\d+\.?\d*)\s*\/?(\d+\.?\d*)?", line)
if bed_temperature_matches:
match = bed_temperature_matches[0]
if match[0]:

View file

@ -0,0 +1,80 @@
{
"version": 2,
"name": "Anycubic Chiron",
"inherits": "fdmprinter",
"metadata":
{
"visible": true,
"author": "Patrick Glatt",
"manufacturer": "Anycubic",
"category": "Other",
"file_formats": "text/x-gcode",
"icon": "icon_ultimaker2",
"platform": "anycubic_chiron_platform.obj",
"platform_texture": "anycubic-chiron.png",
"has_materials": true,
"preferred_material": "generic_pla",
"has_machine_quality": true,
"quality_definition": "anycubic_chiron",
"preferred_quality_type": "normal",
"machine_extruder_trains":
{
"0": "anycubic_chiron_extruder_0"
},
"firmware_file": "MarlinChiron.hex"
},
"overrides":
{
"machine_name":
{
"default_value": "Anycubic Chiron"
},
"machine_heated_bed":
{
"default_value": true
},
"machine_width":
{
"default_value": 400
},
"machine_height":
{
"default_value": 450
},
"machine_depth":
{
"default_value": 400
},
"machine_center_is_zero":
{
"default_value": false
},
"gantry_height":
{
"default_value": 35
},
"machine_head_with_fans_polygon":
{
"default_value":
[
[-45, 50],
[-45, -45],
[45, 50],
[45, -45]
]
},
"machine_gcode_flavor":
{
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode":
{
"default_value": "M107 ;Start with the fan off\nG21 ;Set units to millimeters\nG91 ;Change to relative positioning mode for retract filament and nozzle lifting\nG1 F200 E-3 ;Retract 3mm filament for a clean start\nG92 E0 ;Zero the extruded length\nG1 F1000 Z5 ;Lift the nozzle 5mm before homing axes\nG90 ;Absolute positioning\nM82 ;Set extruder to absolute mode too\nG28 X0 Y0 ;First move X/Y to min endstops\nG28 Z0 ;Then move Z to min endstops\nG1 F1000 Z15 ;After homing lift the nozzle 15mm before start printing\n"
},
"machine_end_gcode":
{
"default_value": "G91 ;Change to relative positioning mode for filament retraction and nozzle lifting\nG1 F200 E-4;Retract the filament a bit before lifting the nozzle\nG1 F1000 Z5;Lift nozzle 5mm\nG90 ;Change to absolute positioning mode to prepare for part rermoval\nG1 X0 Y400 ;Move the print to max y pos for part rermoval\nM104 S0 ; Turn off hotend\nM106 S0 ; Turn off cooling fan\nM140 S0 ; Turn off bed\nM84 ; Disable motors\n"
}
}
}

View file

@ -2,60 +2,67 @@
"version": 2,
"name": "Deltacomb 3D",
"inherits": "fdmprinter",
"metadata": {
"author": "Gabriele Rossetti",
"visible": true,
"manufacturer": "Deltacomb 3D",
"category": "Other",
"file_formats": "text/x-gcode",
"icon": "icon_ultimaker2",
"platform": "deltacomb.stl",
"has_machine_quality": true,
"machine_extruder_trains":
{
"0": "deltacomb_extruder_0"
}
"has_materials": true,
"has_machine_materials": false,
"has_variants": true,
"variants_name": "Head",
"preferred_variant_name": "E3D 0.40mm",
"preferred_material": "generic_pla",
"preferred_quality_type": "normal",
"machine_extruder_trains": { "0": "deltacomb_extruder_0", "1": "deltacomb_extruder_1" }
},
"overrides": {
"machine_extruder_count": { "default_value": 1 },
"machine_heated_bed": { "default_value": true },
"machine_width": { "default_value": 190 },
"machine_height": { "default_value": 250 },
"machine_depth": { "default_value": 190 },
"machine_center_is_zero": { "default_value": true },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home all axes (max endstops)\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."},
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home all axes (max endstops)\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."},
"machine_end_gcode": { "default_value": "M104 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\nG28 ;Home all axes (max endstops)\nM84 ;steppers off\nG90 ;absolute positioning" },
"machine_shape": { "default_value": "elliptic" },
"retraction_hop_enabled": { "default_value": true },
"retraction_hop": { "default_value": 1 },
"retraction_amount" : { "default_value": 3.5 },
"retraction_speed" : { "default_value": 50 },
"material_final_print_temperature": { "value": "material_print_temperature - 5" },
"material_initial_print_temperature": { "value": "material_print_temperature" },
"material_print_temperature_layer_0": { "value": "material_print_temperature + 5" },
"material_diameter": { "default_value": 1.75 },
"retraction_speed" : { "default_value": 30 },
"retraction_combing" : { "default_value": "noskin" },
"travel_avoid_distance": { "default_value": 1, "value": "1" },
"speed_print" : { "default_value": 70 },
"speed_travel": { "value": "150.0" },
"speed_print" : { "default_value": 80 },
"speed_infill": { "value": "round(speed_print * 1.05, 0)" },
"speed_topbottom": { "value": "round(speed_print * 0.95, 0)" },
"speed_wall": { "value": "speed_print" },
"speed_wall_0": { "value": "20" },
"speed_wall_0": { "value": "30" },
"speed_wall_x": { "value": "speed_wall" },
"speed_layer_0": { "value": "min(round(speed_print * 0.75, 0), 45.0)" },
"speed_travel": { "default_value": 150, "value": 150 },
"speed_travel_layer_0": { "value": "round(speed_travel * 0.7, 0)" },
"skirt_brim_speed": { "value": "speed_layer_0" },
"skirt_line_count": { "default_value": 3 },
"skirt_brim_minimal_length": { "default_value": 150 },
"infill_sparse_density": { "default_value": 90 },
"gradual_infill_steps": { "default_value": 2 },
"infill_sparse_density": { "default_value": 30 },
"infill_pattern": { "value": "'cubic'" },
"infill_before_walls" : { "default_value": false },
"top_bottom_thickness": { "default_value": 0.6 },
"top_bottom_thickness": { "default_value": 0.8 },
"support_z_distance": { "value": "layer_height * 2" },
"support_bottom_distance": { "value": "layer_height" },
"support_use_towers" : { "default_value": false },
"jerk_wall_0" : { "value": "30" },
"jerk_travel" : { "default_value": 20 },
"acceleration_travel" : { "value": 10000 },
"machine_max_feedrate_z" : { "default_value": 150 }
"jerk_enabled": { "default_value": 1, "value": "1" },
"jerk_infill" : { "default_value": 5, "value": "5" },
"jerk_support" : { "default_value": 5, "value": "5" },
"acceleration_enabled": { "default_value": 1, "value": "1" },
"acceleration_travel" : { "value": 5000 },
"machine_max_feedrate_z" : { "default_value": 300 }
}
}

View file

@ -4579,7 +4579,7 @@
"description": "Whether to prime the filament with a blob before printing. Turning this setting on will ensure that the extruder will have material ready at the nozzle before printing. Printing Brim or Skirt can act like priming too, in which case turning this setting off saves some time.",
"type": "bool",
"resolve": "any(extruderValues('prime_blob_enable'))",
"default_value": true,
"default_value": false,
"settable_per_mesh": false,
"settable_per_extruder": true,
"enabled": false

View file

@ -0,0 +1,119 @@
{
"version": 2,
"name": "Discov3ry Complete (Ultimaker 2+)",
"inherits": "fdmprinter",
"metadata": {
"author": "Andrew Finkle, CTO",
"manufacturer": "Structur3d.io",
"visible": true,
"weight": 1,
"file_formats": "text/x-gcode",
"platform": "ultimaker2_platform.obj",
"platform_texture": "Ultimaker2Plusbackplate.png",
"platform_offset": [0, 0, 0],
"has_materials": true,
"has_variants": true,
"variants_name": "Print core",
"preferred_variant_name": "0.84mm (Green)",
"has_machine_materials": true,
"preferred_material": "structur3d_dap100silicone",
"has_variant_materials": false,
"has_machine_quality": false,
"preferred_quality_type": "extra_fast",
"first_start_actions": [],
"supported_actions": [],
"machine_extruder_trains":
{
"0": "structur3d_discov3ry1_complete_um2plus_extruder_0"
},
"firmware_file": "MarlinUltimaker2plus.hex"
},
"overrides": {
"machine_name": { "default_value": "Discov3ry Complete (Ultimaker 2+)" },
"speed_infill": {
"value": "speed_print"
},
"infill_sparse_density": {
"value": 100
},
"retraction_hop_enabled": {
"value": true
},
"adhesion_type": {
"default_value": "skirt"
},
"skirt_brim_minimal_length": {
"value": 1500
},
"speed_print": {
"value": 15
},
"speed_wall_x": {
"value": "speed_wall"
},
"layer_height_0": {
"value": "round(machine_nozzle_size / 1.5, 2)"
},
"line_width": {
"value": "round(machine_nozzle_size * 0.875, 2)"
},
"speed_layer_0": {
"default_value": 10
},
"speed_support": {
"value": "speed_wall_0"
},
"machine_height": {
"default_value": 205
},
"machine_width": {
"default_value": 205
},
"machine_depth": {
"default_value": 205
},
"machine_show_variants": {
"default_value": true
},
"gantry_height": {
"default_value": 52
},
"machine_nozzle_head_distance": {
"default_value": 5
},
"machine_nozzle_expansion_angle": {
"default_value": 45
},
"machine_heat_zone_length": {
"default_value": 20
},
"machine_head_with_fans_polygon":
{
"default_value": [
[ -44, 14 ],
[ -44, -34 ],
[ 64, 14 ],
[ 64, -34 ]
]
},
"machine_disallowed_areas": {
"default_value": [
[[-115, 112.5], [ -78, 112.5], [ -80, 102.5], [-115, 102.5]],
[[ 115, 112.5], [ 115, 102.5], [ 105, 102.5], [ 103, 112.5]],
[[-115, -112.5], [-115, -104.5], [ -84, -104.5], [ -82, -112.5]],
[[ 115, -112.5], [ 108, -112.5], [ 110, -104.5], [ 115, -104.5]]
]
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
"default_value": "\n;Updated Firmware (.hex and Marlin .ino) for \n;Ultimaker 2+ with Discov3ry Extruder available at: \n;https://github.com/Structur3d/UM2.1Discov3ry-Firmware-beta \n;**Learn more at https://www.structur3d.io** \n \nM104 S{material_print_temperature} ;Start heating extruder \nM140 S{material_bed_temperature} ;Start heating bed \nG21 ;metric values \nG90 ;absolute positioning \nM82 ;set extruder to absolute mode \nM107 ;start with the fan off \nM302 ;allow cold extrusion \nM92 E2589 ;set extruder EEPROM steps/mm for paste \nG28 Z0 ;move Z to bottom endstops \nG28 X0 Y0 ;move X/Y to endstops \nG1 X15 Y0 F4000 ;move X/Y to front of printer \nG1 Z15.0 F9000 ;move the platform to 15mm \nG92 E0 ;zero the extruded length \nG1 F200 E10 ;extrude 10 mm of feed stock \nG92 E0 ;zero the extruded length again \nG1 F9000 \n;Put printing message on LCD screen \nM117 Printing..."
},
"machine_end_gcode": {
"default_value": "M104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off (if you have it) \nM92 E282 ;reset extruder EEPROM steps/mm for plastic filament \nG91 ;relative positioning \nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure \nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;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 \nM84 ;steppers off\nG90 ;absolute positioning"
}
}
}

View file

@ -7,7 +7,7 @@
"manufacturer": "Ultimaker B.V.",
"category": "Ultimaker",
"visible": false,
"exclude_materials": [ "generic_hips", "generic_petg" ]
"exclude_materials": [ "generic_hips", "generic_petg", "structur3d_dap100silicone" ]
},
"overrides": {
"machine_max_feedrate_e": {

View file

@ -78,7 +78,7 @@
"prime_tower_position_x": { "value": "machine_depth - max(extruderValue(adhesion_extruder_nr, 'brim_width') * extruderValue(adhesion_extruder_nr, 'initial_layer_line_width_factor') / 100 if adhesion_type == 'brim' else (extruderValue(adhesion_extruder_nr, 'raft_margin') if adhesion_type == 'raft' else (extruderValue(adhesion_extruder_nr, 'skirt_gap') if adhesion_type == 'skirt' else 0)), max(extruderValues('travel_avoid_distance'))) - max(extruderValues('support_offset')) - sum(extruderValues('skirt_brim_line_width')) - 30" },
"prime_tower_wipe_enabled": { "default_value": false },
"prime_blob_enable": { "enabled": true },
"prime_blob_enable": { "enabled": true, "default_value": true },
"acceleration_enabled": { "value": "True" },
"acceleration_layer_0": { "value": "acceleration_topbottom" },

View file

@ -0,0 +1,16 @@
{
"id": "anycubic_chiron_extruder_0",
"version": 2,
"name": "Extruder 1",
"inherits": "fdmextruder",
"metadata": {
"machine": "anycubic_chiron",
"position": "0"
},
"overrides": {
"extruder_nr": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.4 },
"material_diameter": { "default_value": 1.75 }
}
}

View file

@ -11,6 +11,8 @@
"overrides": {
"extruder_nr": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.4 },
"material_diameter": { "default_value": 1.75 }
"material_diameter": { "default_value": 1.75 },
"machine_nozzle_offset_x": { "default_value": 0.0 },
"machine_nozzle_offset_y": { "default_value": 0.0 }
}
}

View file

@ -0,0 +1,18 @@
{
"id": "deltacomb_extruder_1",
"version": 2,
"name": "Extruder 2",
"inherits": "fdmextruder",
"metadata": {
"machine": "deltacomb",
"position": "1"
},
"overrides": {
"extruder_nr": { "default_value": 1 },
"machine_nozzle_size": { "default_value": 0.4 },
"material_diameter": { "default_value": 1.75 },
"machine_nozzle_offset_x": { "default_value": 0.0 },
"machine_nozzle_offset_y": { "default_value": 0.0 }
}
}

View file

@ -0,0 +1,16 @@
{
"id": "structur3d_discov3ry1_complete_um2plus_extruder_0",
"version": 2,
"name": "Discov3ry Extruder",
"inherits": "fdmextruder",
"metadata": {
"machine": "structur3d_discov3ry1_complete_um2plus",
"position": "0"
},
"overrides": {
"extruder_nr": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.84 },
"material_diameter": { "default_value": 3.175 }
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View file

@ -0,0 +1,150 @@
# WaveFront *.obj file (generated by Autodesk ATF)
#Author: Patrick Glatt
mtllib ae48cbb4-79ca-43fd-95a7-5e2258fec6c5.mtl
o Anycubic Chiron Platform
#vertex 1
v 200.000000 200.000000 0.000000
#vertex 2
v 200.000000 -200.000000 0.000000
#vertex 3
v 200.000000 -200.000000 -4.000000
#vertex 4
v 200.000000 200.000000 -4.000000
#vertex 5
v -200.000000 200.000000 0.000000
#vertex 6
v -200.000000 200.000000 -4.000000
#vertex 7
v -200.000000 -200.000000 0.000000
#vertex 8
v -200.000000 -200.000000 -4.000000
#vt right
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
#vt front
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
#vt left
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
#vt back
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
#vt top (only the color of the (0.000000 1.000000 0.000000) corner in logo)
#vt 0.000000 1.000000 0.000000
#vt 0.000000 1.000000 0.000000
#vt 0.000000 1.000000 0.000000
#vt 0.000000 1.000000 0.000000
#vt top (full logo)
vt 0.00000 0.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 1.000000 1.000000 0.000000
#vt bottom
vt 0.000000 0.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 1.000000 1.000000 0.000000
#vn right
vn 0.000000 0.000000 0.000000
vn 0.100000 0.000000 0.000000
vn 0.100000 0.000000 0.000000
vn 0.100000 0.000000 0.000000
#vn front
vn 0.000000 0.100000 0.000000
vn 0.000000 0.100000 0.000000
vn 0.000000 0.100000 0.000000
vn 0.000000 0.100000 0.000000
#vn left
vn -0.100000 0.000000 0.000000
vn -0.100000 0.000000 0.000000
vn -0.100000 0.000000 0.000000
vn -0.100000 0.000000 0.000000
#vn back
vn 0.000000 -0.100000 0.000000
vn 0.000000 -0.100000 0.000000
vn 0.000000 -0.100000 0.000000
vn 0.000000 -0.100000 0.000000
#vn top
vn 0.000000 -0.000000 0.100000
vn 0.000000 -0.000000 0.100000
vn 0.000000 -0.000000 0.100000
vn 0.000000 -0.000000 0.100000
#vn bottom
vn 0.000000 0.000000 0.100000
vn 0.000000 0.000000 0.100000
vn 0.000000 0.000000 0.100000
vn 0.000000 0.000000 0.100000
#faces f v{index}/vt{index}/vn{index}..
#face right
f 1/1/1 2/2/1 4/3/1
f 4/3/1 2/2/1 3/4/1
#face front
f 5/5/5 1/6/5 6/7/5
f 6/7/5 1/6/5 4/8/5
#face left
f 7/9/9 5/10/9 8/11/9
f 8/11/9 5/10/9 6/12/9
#face back
f 2/13/13 7/14/13 3/15/13
f 3/15/13 7/14/13 8/16/13
#face top (uncomment this code if you want to see the logo on top too)
#f 7/17/17 2/18/17 1/20/17 5/19/17
#face bottom
f 6/21/23 4/22/23 3/24/23 8/23/23
o Small Logo Platform
#9 front left
v -50.000000 270.700000 70.700000
#10 front right
v 50.000000 270.700000 70.700000
#11 back right
v 50.000000 200.000000 0.000000
#12 back left
v -50.000000 200.000000 0.000000
#13 front left 2
v -50.000000 270.700000 66.700000
#14 front right2
v 50.000000 270.700000 66.700000
#15 back right 3
v 50.000000 200.000000 -4.000000
#16 back left2
v -50.000000 200.000000 -4.000000
#vt's
vt 0.000000 1.000000 0.000000
vt 0.000000 0.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 1.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
#vn's
vn 0.000000 0.000000 1.000000
#faces f v{index}/vt{index}/vn{index}...
#right
f 10/1/1 11/2/1 15/3/1 14/4/1
#front
f 9/4/5 10/8/5 14/7/5 13/8/5
#left
f 12/9/9 9/10/9 13/11/9 16/12/9
#back
f 11/13/13 12/14/13 16/15/13 15/16/13
#top
f 12/26/25 11/27/25 10/28/25 9/25/25
#bottom
f 13/13/23 14/14/23 15/15/23 16/16/23

View file

@ -14,7 +14,7 @@ UM.ManagementPage
id: base;
title: catalog.i18nc("@title:tab", "Printers");
model: Cura.MachineManagementModel { }
model: Cura.GlobalStacksModel { }
activeId: Cura.MachineManager.activeMachineId
activeIndex: activeMachineIndex()

View file

@ -19,12 +19,19 @@ Button
checkable: true
hoverEnabled: true
property bool selected: checked
property bool printerTypeLabelAutoFit: false
property var outputDevice: null
property var printerTypesList: []
property var updatePrinterTypesFunction: updatePrinterTypesList
// This function converts the printer type string to another string.
property var printerTypeLabelConversionFunction: Cura.MachineManager.getAbbreviatedMachineName
function updatePrinterTypesList()
{
printerTypesList = (checked && (outputDevice != null)) ? outputDevice.uniquePrinterTypes : []
printerTypesList = (outputDevice != null) ? outputDevice.uniquePrinterTypes : []
}
contentItem: Item
@ -67,7 +74,8 @@ Button
model: printerTypesList
delegate: Cura.PrinterTypeLabel
{
text: Cura.MachineManager.getAbbreviatedMachineName(modelData)
autoFit: printerTypeLabelAutoFit
text: printerTypeLabelConversionFunction(modelData)
}
}
}
@ -76,29 +84,30 @@ Button
background: Rectangle
{
id: backgroundRect
color: machineSelectorButton.hovered ? UM.Theme.getColor("action_button_hovered") : "transparent"
color:
{
if (!machineSelectorButton.enabled)
{
return UM.Theme.getColor("action_button_disabled")
}
return machineSelectorButton.hovered ? UM.Theme.getColor("action_button_hovered") : "transparent"
}
radius: UM.Theme.getSize("action_button_radius").width
border.width: UM.Theme.getSize("default_lining").width
border.color: machineSelectorButton.checked ? UM.Theme.getColor("primary") : "transparent"
}
onClicked:
{
toggleContent()
Cura.MachineManager.setActiveMachine(model.id)
border.color: machineSelectorButton.selected ? UM.Theme.getColor("primary") : "transparent"
}
Connections
{
target: outputDevice
onUniqueConfigurationsChanged: updatePrinterTypesList()
onUniqueConfigurationsChanged: updatePrinterTypesFunction()
}
Connections
{
target: Cura.MachineManager
onOutputDevicesChanged: updatePrinterTypesList()
onOutputDevicesChanged: updatePrinterTypesFunction()
}
Component.onCompleted: updatePrinterTypesList()
Component.onCompleted: updatePrinterTypesFunction()
}

View file

@ -42,5 +42,11 @@ ListView
}
return result
}
onClicked:
{
toggleContent()
Cura.MachineManager.setActiveMachine(model.id)
}
}
}

View file

@ -12,7 +12,9 @@ Item
{
property alias text: printerTypeLabel.text
width: UM.Theme.getSize("printer_type_label").width
property bool autoFit: false
width: autoFit ? (printerTypeLabel.width + UM.Theme.getSize("default_margin").width) : UM.Theme.getSize("printer_type_label").width
height: UM.Theme.getSize("printer_type_label").height
Rectangle

View file

@ -47,7 +47,7 @@ Cura.ExpandablePopup
Label
{
id: title
text: catalog.i18nc("@label", "View types")
text: catalog.i18nc("@label", "View type")
verticalAlignment: Text.AlignVCenter
height: parent.height
elide: Text.ElideRight

View file

@ -0,0 +1,190 @@
// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.3 as UM
import Cura 1.0 as Cura
//
// This is the scroll view widget for adding a (local) printer. This scroll view shows a list view with printers
// categorized into 3 categories: "Ultimaker", "Custom", and "Other".
//
ScrollView
{
id: base
property var currentItem: (machineList.currentIndex >= 0)
? machineList.model.getItem(machineList.currentIndex)
: null
property string currentSection: preferredCategory
property string preferredCategory: "Ultimaker"
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
property int maxItemCountAtOnce: 10 // show at max 10 items at once, otherwise you need to scroll.
height: maxItemCountAtOnce * UM.Theme.getSize("action_button").height
clip: true
function updateCurrentItemUponSectionChange()
{
// Find the first machine from this section
for (var i = 0; i < machineList.count; i++)
{
var item = machineList.model.getItem(i)
if (item.section == base.currentSection)
{
machineList.currentIndex = i
break
}
}
}
Component.onCompleted:
{
updateCurrentItemUponSectionChange()
}
background: Rectangle
{
anchors.fill: parent
color: "white"
}
ListView
{
id: machineList
model: UM.DefinitionContainersModel
{
id: machineDefinitionsModel
filter: { "visible": true }
sectionProperty: "category"
preferredSectionValue: preferredCategory
}
section.property: "section"
section.delegate: sectionHeader
delegate: machineButton
}
Component
{
id: sectionHeader
Button
{
id: button
width: ListView.view.width
height: UM.Theme.getSize("action_button").height
text: section
property bool isActive: base.currentSection == section
background: Rectangle
{
anchors.fill: parent
color: isActive ? UM.Theme.getColor("setting_control_highlight") : "transparent"
}
contentItem: Item
{
width: childrenRect.width
height: UM.Theme.getSize("action_button").height
UM.RecolorImage
{
id: arrow
anchors.left: parent.left
//anchors.verticalCenter: label.verticalCenter
width: UM.Theme.getSize("standard_arrow").width
height: UM.Theme.getSize("standard_arrow").height
sourceSize.width: width
sourceSize.height: height
color: UM.Theme.getColor("text")
source: base.currentSection == section ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_right")
}
Label
{
id: label
anchors.left: arrow.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
verticalAlignment: Text.AlignVCenter
text: button.text
font.bold: true
renderType: Text.NativeRendering
}
}
onClicked:
{
base.currentSection = section
base.updateCurrentItemUponSectionChange()
}
}
}
Component
{
id: machineButton
RadioButton
{
id: radioButton
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("standard_list_lineheight").width
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
height: visible ? UM.Theme.getSize("standard_list_lineheight").height : 0
checked: ListView.view.currentIndex == index
text: name
font: UM.Theme.getFont("default")
visible: base.currentSection == section
background: Rectangle
{
anchors.fill: parent
color: "transparent"
}
indicator: Rectangle
{
implicitWidth: 16
implicitHeight: 16
anchors.verticalCenter: parent.verticalCenter
radius: width / 2
border.width: UM.Theme.getSize("default_lining").width
border.color: radioButton.hovered ? UM.Theme.getColor("small_button_text") : UM.Theme.getColor("small_button_text_hover")
Rectangle {
width: parent.width / 2
height: width
anchors.centerIn: parent
radius: width / 2
color: radioButton.hovered ? UM.Theme.getColor("primary_button_hover") : UM.Theme.getColor("primary_button")
visible: radioButton.checked
}
}
contentItem: Label
{
verticalAlignment: Text.AlignVCenter
leftPadding: radioButton.indicator.width + radioButton.spacing
text: radioButton.text
font: radioButton.font
renderType: Text.NativeRendering
}
onClicked:
{
ListView.view.currentIndex = index
}
}
}
}

View file

@ -0,0 +1,217 @@
// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.3 as UM
import Cura 1.1 as Cura
import "../PrinterSelector"
//
// This is the widget for adding a network printer. There are 2 parts in this widget. One is a scroll view of a list
// of discovered network printers. Beneath the scroll view is a container with 3 buttons: "Refresh", "Add by IP", and
// "Troubleshooting".
//
Item
{
id: base
height: networkPrinterInfo.height + controlsRectangle.height
property alias maxItemCountAtOnce: networkPrinterScrollView.maxItemCountAtOnce
property var currentItem: (networkPrinterListView.currentIndex >= 0)
? networkPrinterListView.model[networkPrinterListView.currentIndex]
: null
signal refreshButtonClicked()
signal addByIpButtonClicked()
Item
{
id: networkPrinterInfo
height: networkPrinterScrollView.visible ? networkPrinterScrollView.height : noPrinterLabel.height
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
Label
{
id: noPrinterLabel
height: UM.Theme.getSize("setting_control").height + UM.Theme.getSize("default_margin").height
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@label", "There is no printer found over your network.")
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
visible: !networkPrinterScrollView.visible
}
ScrollView
{
id: networkPrinterScrollView
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
property int maxItemCountAtOnce: 8 // show at max 8 items at once, otherwise you need to scroll.
height: maxItemCountAtOnce * UM.Theme.getSize("action_button").height
visible: networkPrinterListView.model.length > 0
clip: true
ListView
{
id: networkPrinterListView
anchors.fill: parent
model: CuraApplication.getDiscoveredPrintersModel().discovered_printers
Component.onCompleted:
{
// select the first one that's not "unknown" by default.
for (var i = 0; i < count; i++)
{
if (!model[i].is_unknown_machine_type)
{
currentIndex = i
break
}
}
}
delegate: MachineSelectorButton
{
text: modelData.device.name
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 10
outputDevice: modelData.device
enabled: !modelData.is_unknown_machine_type
printerTypeLabelAutoFit: true
updatePrinterTypesFunction: updateMachineTypes
// show printer type as it is
printerTypeLabelConversionFunction: function(value) { return value }
function updateMachineTypes()
{
printerTypesList = [ modelData.readable_machine_type ]
}
checkable: false
selected: ListView.view.currentIndex == model.index
onClicked:
{
ListView.view.currentIndex = index
}
}
}
}
}
Cura.RoundedRectangle
{
id: controlsRectangle
anchors.left: parent.left
anchors.right: parent.right
anchors.top: networkPrinterInfo.bottom
// Make sure that the left, right, and bottom borders do not show up, otherwise you see double
// borders.
anchors.bottomMargin: -border.width
anchors.leftMargin: -border.width
anchors.rightMargin: -border.width
height: UM.Theme.getSize("message_action_button").height + UM.Theme.getSize("default_margin").height
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
color: "white"
cornerSide: Cura.RoundedRectangle.Direction.Down
Cura.SecondaryButton
{
id: refreshButton
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: parent.verticalCenter
text: catalog.i18nc("@label", "Refresh")
height: UM.Theme.getSize("message_action_button").height
onClicked: base.refreshButtonClicked()
}
Cura.SecondaryButton
{
id: addPrinterByIpButton
anchors.left: refreshButton.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: parent.verticalCenter
text: catalog.i18nc("@label", "Add printer by IP")
height: UM.Theme.getSize("message_action_button").height
onClicked: base.addByIpButtonClicked()
}
Item
{
id: troubleshootingButton
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: parent.verticalCenter
height: troubleshoortingLinkIcon.height
width: troubleshoortingLinkIcon.width + troubleshoortingLabel.width + UM.Theme.getSize("default_margin").width
UM.RecolorImage
{
id: troubleshoortingLinkIcon
anchors.right: troubleshoortingLabel.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: parent.verticalCenter
height: troubleshoortingLabel.height
width: height
sourceSize.height: width
color: UM.Theme.getColor("text_link")
source: UM.Theme.getIcon("external_link")
}
Label
{
id: troubleshoortingLabel
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: catalog.i18nc("@label", "Troubleshooting")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_link")
linkColor: UM.Theme.getColor("text_link")
renderType: Text.NativeRendering
}
MouseArea
{
anchors.fill: parent
hoverEnabled: true
onClicked:
{
// open the throubleshooting URL with web browser
var url = "https://ultimaker.com/incoming-links/cura/material-compatibilty" // TODO
Qt.openUrlExternally(url)
}
onEntered:
{
troubleshoortingLabel.font.underline = true
}
onExited:
{
troubleshoortingLabel.font.underline = false
}
}
}
}
}

View file

@ -201,7 +201,7 @@ Item
text: catalog.i18nc("@button", "Cancel")
width: 140
fixedWidthMode: true
onClicked: base.showPreviousPage()
onClicked: base.gotoPage("add_printer_by_selection")
enabled: true
}

View file

@ -0,0 +1,154 @@
// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.3 as UM
import Cura 1.1 as Cura
//
// This component contains the content for the "Add a printer" (network) page of the welcome on-boarding process.
//
Item
{
UM.I18nCatalog { id: catalog; name: "cura" }
Label
{
id: titleLabel
anchors.top: parent.top
anchors.topMargin: 40
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
text: catalog.i18nc("@label", "Add a printer")
color: UM.Theme.getColor("primary_button")
font: UM.Theme.getFont("large_bold")
renderType: Text.NativeRendering
}
DropDownWidget
{
id: addNetworkPrinterDropDown
anchors.top: titleLabel.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 20
title: catalog.i18nc("@label", "Add a networked printer")
contentShown: true // by default expand the network printer list
onClicked:
{
if (contentShown)
{
addLocalPrinterDropDown.contentShown = false
}
}
contentComponent: networkPrinterListComponent
Component
{
id: networkPrinterListComponent
AddNetworkPrinterScrollView
{
id: networkPrinterScrollView
maxItemCountAtOnce: 6 // show at max 6 items at once, otherwise you need to scroll.
onRefreshButtonClicked:
{
UM.OutputDeviceManager.startDiscovery()
}
onAddByIpButtonClicked:
{
base.gotoPage("add_printer_by_ip")
}
}
}
}
DropDownWidget
{
id: addLocalPrinterDropDown
anchors.top: addNetworkPrinterDropDown.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 20
title: catalog.i18nc("@label", "Add a non-networked printer")
onClicked:
{
if (contentShown)
{
addNetworkPrinterDropDown.contentShown = false
}
}
contentComponent: localPrinterListComponent
Component
{
id: localPrinterListComponent
AddLocalPrinterScrollView
{
id: localPrinterView
maxItemCountAtOnce: 10 // show at max 10 items at once, otherwise you need to scroll.
}
}
}
Cura.PrimaryButton
{
id: nextButton
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: 40
enabled:
{
// If the network printer dropdown is expanded, make sure that there is a selected item
if (addNetworkPrinterDropDown.contentShown)
{
return addNetworkPrinterDropDown.contentItem.currentItem != null
}
else
{
return addLocalPrinterDropDown.contentItem.currentItem != null
}
}
text: catalog.i18nc("@button", "Next")
width: 140
fixedWidthMode: true
onClicked:
{
// Create a network printer or a local printer according to the selection
if (addNetworkPrinterDropDown.contentShown)
{
// Create a network printer
const networkPrinterItem = addNetworkPrinterDropDown.contentItem.currentItem
CuraApplication.getDiscoveredPrintersModel().createMachineFromDiscoveredPrinter(networkPrinterItem)
}
else
{
// Create a local printer
const localPrinterItem = addLocalPrinterDropDown.contentItem.currentItem
Cura.MachineManager.addMachine(localPrinterItem.id)
}
// TODO: implement machine actions
// If we have created a machine, go to the last page, which is the "cloud" page.
base.gotoPage("cloud")
}
}
}

View file

@ -1,106 +0,0 @@
// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.3 as UM
import Cura 1.1 as Cura
import "../PrinterSelector"
//
// This component contains the content for the "Add a printer" (network) page of the welcome on-boarding process.
//
Item
{
UM.I18nCatalog { id: catalog; name: "cura" }
Label
{
id: titleLabel
anchors.top: parent.top
anchors.topMargin: 40
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
text: catalog.i18nc("@label", "Add a printer")
color: UM.Theme.getColor("primary_button")
font: UM.Theme.getFont("large_bold")
renderType: Text.NativeRendering
}
DropDownWidget
{
id: addNetworkPrinterDropDown
anchors.top: titleLabel.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 20
title: catalog.i18nc("@label", "Add a network printer")
contentComponent: networkPrinterListComponent
Component
{
id: networkPrinterListComponent
ScrollView
{
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ScrollBar.vertical.policy: ScrollBar.AlwaysOn
property int maxItemCountAtOnce: 5 // show at max 10 items at once, otherwise you need to scroll.
height: maxItemCountAtOnce * (UM.Theme.getSize("action_button").height)
clip: true
ListView
{
id: listView
anchors.fill: parent
model: Cura.GlobalStacksModel {} // TODO: change this to the network printers
delegate: MachineSelectorButton
{
text: model.name
width: listView.width - UM.Theme.getSize("default_margin").width
outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
checked: ListView.view.currentIndex == index
onClicked:
{
ListView.view.currentIndex = index
}
}
}
}
}
}
DropDownWidget
{
id: addLocalPrinterDropDown
anchors.top: addNetworkPrinterDropDown.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: 20
title: catalog.i18nc("@label", "Add a non-network printer")
}
Cura.PrimaryButton
{
id: nextButton
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: 40
enabled: true // TODO
text: catalog.i18nc("@button", "Next")
width: 140
fixedWidthMode: true
onClicked: base.showNextPage()
}
}

View file

@ -99,14 +99,13 @@ Item
text: catalog.i18nc("@button", "Create an account")
width: 140
fixedWidthMode: true
onClicked: base.showNextPage() // TODO: create account
onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create")
}
Cura.SecondaryButton
{
id: signInButton
anchors.left: createAccountButton.right
//anchors.leftMargin: 10
anchors.verticalCenter: finishButton.verticalCenter
text: catalog.i18nc("@button", "Sign in")
width: 80
@ -115,6 +114,6 @@ Item
hoverColor: "transparent"
textHoverColor: UM.Theme.getColor("text_light_blue")
fixedWidthMode: true
onClicked: base.showNextPage() // TODO: sign in
onClicked: Cura.API.account.login()
}
}

View file

@ -11,7 +11,7 @@ import ".."
//
// This is DropDown Header bar of the expandable drop down list.
// This is DropDown Header bar of the expandable drop down list. See comments in DropDownWidget for details.
//
Cura.RoundedRectangle
{
@ -34,6 +34,8 @@ Cura.RoundedRectangle
// If the content is shown
property bool contentShown: false
signal clicked()
MouseArea
{
anchors.fill: parent
@ -41,7 +43,7 @@ Cura.RoundedRectangle
onEntered: base.hovered = true
onExited: base.hovered = false
onClicked: base.contentShown = !base.contentShown
onClicked: base.clicked()
}
Label

View file

@ -8,6 +8,13 @@ import UM 1.3 as UM
import Cura 1.1 as Cura
//
// This is the dropdown list widget in the welcome wizard. The dropdown list has a header bar which is always present,
// and its content whose visibility can be toggled by clicking on the header bar. The content is displayed as an
// expandable dropdown box that will appear below the header bar.
//
// The content is configurable via the property "contentComponent", which will be loaded by a Loader when set.
//
Item
{
UM.I18nCatalog { id: catalog; name: "cura" }
@ -15,12 +22,25 @@ Item
id: base
implicitWidth: 200
height: header.contentShown ? childrenRect.height : header.height
height: header.contentShown ? (header.height + contentRectangle.height + 30) : header.height
property var contentComponent: null
property alias contentItem: contentLoader.item
property alias title: header.title
property alias contentShown: header.contentShown
property bool contentShown: false
signal clicked()
Connections
{
target: header
onClicked:
{
base.contentShown = !base.contentShown
clicked()
}
}
DropDownHeader
{
@ -30,15 +50,16 @@ Item
anchors.right: parent.right
height: UM.Theme.getSize("expandable_component_content_header").height
rightIconSource: contentShown ? UM.Theme.getIcon("arrow_bottom") : UM.Theme.getIcon("arrow_right")
contentShown: base.contentShown
}
Cura.RoundedRectangle
{
id: contentRectangle
anchors.top: header.bottom
anchors.horizontalCenter: header.horizontalCenter
width: header.width
height: childrenRect.height
anchors.left: header.left
anchors.right: header.right
height: contentLoader.height + 2
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
@ -53,7 +74,6 @@ Item
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: childrenRect.height
anchors.margins: 1
sourceComponent: base.contentComponent != null ? base.contentComponent : emptyComponent
}

View file

@ -33,6 +33,7 @@ Item
signal showNextPage()
signal showPreviousPage()
signal passLastPage() // Emitted when there is no more page to show
signal gotoPage(string page_id) // Go to a specific page by the given page_id.
onShowNextPage:
{
@ -53,6 +54,29 @@ Item
}
}
onGotoPage:
{
// find the page index
var page_index = -1
for (var i = 0; i < base.model.count; i++)
{
const item = base.model.getItem(i)
if (item.id == page_id)
{
page_index = i
break
}
}
if (page_index > 0)
{
currentStep = page_index
}
else
{
console.log("Error: cannot find page with page_id = [", page_id, "]")
}
}
onVisibleChanged:
{
if (visible)

View file

@ -0,0 +1,61 @@
[general]
version = 4
name = Draft
definition = anycubic_chiron
[metadata]
setting_version = 7
type = quality
quality_type = draft
weight = -2
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = skirt
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.3
layer_height_0 = 0.3
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 60
speed_support = 60
speed_topbottom = =math.ceil(speed_print * 30 / 60)
speed_travel = 100
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View file

@ -0,0 +1,61 @@
[general]
version = 4
name = High
definition = anycubic_chiron
[metadata]
setting_version = 7
type = quality
quality_type = high
weight = 1
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = skirt
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.1
layer_height_0 = 0.1
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 50
speed_support = 30
speed_topbottom = =math.ceil(speed_print * 20 / 50)
speed_travel = 50
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View file

@ -0,0 +1,61 @@
[general]
version = 4
name = Normal
definition = anycubic_chiron
[metadata]
setting_version = 7
type = quality
quality_type = normal
weight = 0
global_quality = True
[values]
acceleration_enabled = True
acceleration_print = 1800
acceleration_travel = 3000
adhesion_type = skirt
brim_width = 4.0
cool_fan_full_at_height = 0.5
cool_fan_speed = 100
cool_fan_speed_0 = 100
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 25
initial_layer_line_width_factor = 140
jerk_enabled = True
jerk_print = 8
jerk_travel = 10
layer_height = 0.2
layer_height_0 = 0.2
material_bed_temperature = 60
material_diameter = 1.75
material_print_temperature = 200
material_print_temperature_layer_0 = 0
retract_at_layer_change = False
retraction_amount = 6
retraction_hop = 0.075
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
retraction_min_travel = 1.5
retraction_speed = 40
skirt_brim_speed = 40
skirt_gap = 5
skirt_line_count = 3
speed_infill = =speed_print
speed_print = 50
speed_support = 30
speed_topbottom = =math.ceil(speed_print * 20 / 50)
speed_travel = 100
speed_wall = =speed_print
speed_wall_x = =speed_print
support_angle = 60
support_enable = True
support_interface_enable = True
support_pattern = triangles
support_roof_enable = True
support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
wall_thickness = 1.2

View file

@ -13,7 +13,7 @@ material = generic_abs
[values]
adhesion_type = raft
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 2
cool_fan_full_at_height = =layer_height * 6
cool_fan_speed = 50
cool_fan_speed_max = 50
cool_fan_speed_min = 50

View file

@ -13,7 +13,7 @@ material = generic_abs
[values]
adhesion_type = raft
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 2
cool_fan_full_at_height = =layer_height * 6
cool_fan_speed = 50
cool_fan_speed_max = 50
cool_fan_speed_min = 50

View file

@ -7,13 +7,13 @@ definition = deltacomb
setting_version = 7
type = quality
quality_type = high
weight = 1
weight = 0
material = generic_abs
[values]
adhesion_type = raft
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 2
cool_fan_full_at_height = =layer_height * 6
cool_fan_speed = 50
cool_fan_speed_max = 50
cool_fan_speed_min = 50

View file

@ -13,7 +13,7 @@ material = generic_abs
[values]
adhesion_type = raft
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 2
cool_fan_full_at_height = =layer_height * 6
cool_fan_speed = 50
cool_fan_speed_max = 50
cool_fan_speed_min = 50

View file

@ -13,7 +13,7 @@ material = generic_abs
[values]
adhesion_type = raft
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 2
cool_fan_full_at_height = =layer_height * 6
cool_fan_speed = 50
cool_fan_speed_max = 50
cool_fan_speed_min = 50

View file

@ -7,7 +7,7 @@ definition = deltacomb
setting_version = 7
type = quality
quality_type = high
weight = 1
weight = 0
global_quality = True
[values]

View file

@ -0,0 +1,25 @@
[general]
version = 4
name = Fast
definition = deltacomb
[metadata]
setting_version = 7
type = quality
quality_type = draft
weight = -2
material = generic_petg
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 4
cool_fan_speed = 60
cool_fan_speed_max = 100
cool_fan_speed_min = 60
cool_min_layer_time = 5
cool_min_speed = 20
speed_print = 50
default_material_print_temperature = 235
material_standby_temperature = 215
material_print_temperature_layer_0 = =default_material_print_temperature + 5

View file

@ -0,0 +1,25 @@
[general]
version = 4
name = Normal
definition = deltacomb
[metadata]
setting_version = 7
type = quality
quality_type = fast
weight = -1
material = generic_petg
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 4
cool_fan_speed = 60
cool_fan_speed_max = 100
cool_fan_speed_min = 60
cool_min_layer_time = 5
cool_min_speed = 20
speed_print = 50
default_material_print_temperature = 235
material_standby_temperature = 215
material_print_temperature_layer_0 = =default_material_print_temperature + 5

View file

@ -0,0 +1,25 @@
[general]
version = 4
name = Extra Fine
definition = deltacomb
[metadata]
setting_version = 7
type = quality
quality_type = high
weight = 0
material = generic_petg
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 4
cool_fan_speed = 60
cool_fan_speed_max = 100
cool_fan_speed_min = 60
cool_min_layer_time = 5
cool_min_speed = 20
speed_print = 50
default_material_print_temperature = 235
material_standby_temperature = 215
material_print_temperature_layer_0 = =default_material_print_temperature + 5

View file

@ -0,0 +1,25 @@
[general]
version = 4
name = Fine
definition = deltacomb
[metadata]
setting_version = 7
type = quality
quality_type = normal
weight = 0
material = generic_petg
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 4
cool_fan_speed = 60
cool_fan_speed_max = 100
cool_fan_speed_min = 60
cool_min_layer_time = 5
cool_min_speed = 20
speed_print = 50
default_material_print_temperature = 235
material_standby_temperature = 215
material_print_temperature_layer_0 = =default_material_print_temperature + 5

View file

@ -0,0 +1,25 @@
[general]
version = 4
name = Extra Fast
definition = deltacomb
[metadata]
setting_version = 7
type = quality
quality_type = verydraft
weight = -3
material = generic_petg
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 4
cool_fan_speed = 60
cool_fan_speed_max = 100
cool_fan_speed_min = 60
cool_min_layer_time = 5
cool_min_speed = 20
speed_print = 50
default_material_print_temperature = 235
material_standby_temperature = 215
material_print_temperature_layer_0 = =default_material_print_temperature + 5

View file

@ -13,7 +13,7 @@ material = generic_pla
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height
cool_fan_full_at_height = =layer_height * 4
cool_fan_speed = 100
cool_fan_speed_max = 100
cool_fan_speed_min = 100

View file

@ -13,7 +13,7 @@ material = generic_pla
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height
cool_fan_full_at_height = =layer_height * 4
cool_fan_speed = 100
cool_fan_speed_max = 100
cool_fan_speed_min = 100

View file

@ -7,13 +7,13 @@ definition = deltacomb
setting_version = 7
type = quality
quality_type = high
weight = 1
weight = 0
material = generic_pla
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height
cool_fan_full_at_height = =layer_height * 4
cool_fan_speed = 100
cool_fan_speed_max = 100
cool_fan_speed_min = 100

View file

@ -13,7 +13,7 @@ material = generic_pla
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height
cool_fan_full_at_height = =layer_height * 4
cool_fan_speed = 100
cool_fan_speed_max = 100
cool_fan_speed_min = 100

View file

@ -13,7 +13,7 @@ material = generic_pla
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height
cool_fan_full_at_height = =layer_height * 4
cool_fan_speed = 100
cool_fan_speed_max = 100
cool_fan_speed_min = 100

View file

@ -0,0 +1,27 @@
[general]
version = 4
name = Fast
definition = deltacomb
[metadata]
setting_version = 7
type = quality
quality_type = draft
weight = -2
material = generic_tpu
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 6
cool_fan_speed = 100
cool_fan_speed_max = 100
cool_fan_speed_min = 70
cool_min_layer_time = 5
cool_min_speed = 20
material_print_temperature_layer_0 = =default_material_print_temperature + 5
speed_print = 25
speed_travel = 300
acceleration_travel = 10000
retraction_amount = 5
retraction_hop_enabled = False

View file

@ -0,0 +1,27 @@
[general]
version = 4
name = Normal
definition = deltacomb
[metadata]
setting_version = 7
type = quality
quality_type = fast
weight = -1
material = generic_tpu
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 6
cool_fan_speed = 100
cool_fan_speed_max = 100
cool_fan_speed_min = 70
cool_min_layer_time = 5
cool_min_speed = 20
material_print_temperature_layer_0 = =default_material_print_temperature + 5
speed_print = 25
speed_travel = 300
acceleration_travel = 10000
retraction_amount = 5
retraction_hop_enabled = False

View file

@ -0,0 +1,27 @@
[general]
version = 4
name = Extra Fine
definition = deltacomb
[metadata]
setting_version = 7
type = quality
quality_type = high
weight = 0
material = generic_tpu
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 6
cool_fan_speed = 100
cool_fan_speed_max = 100
cool_fan_speed_min = 70
cool_min_layer_time = 5
cool_min_speed = 20
material_print_temperature_layer_0 = =default_material_print_temperature + 5
speed_print = 25
speed_travel = 300
acceleration_travel = 10000
retraction_amount = 5
retraction_hop_enabled = False

View file

@ -0,0 +1,27 @@
[general]
version = 4
name = Fine
definition = deltacomb
[metadata]
setting_version = 7
type = quality
quality_type = normal
weight = 0
material = generic_tpu
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 6
cool_fan_speed = 100
cool_fan_speed_max = 100
cool_fan_speed_min = 70
cool_min_layer_time = 5
cool_min_speed = 20
material_print_temperature_layer_0 = =default_material_print_temperature + 5
speed_print = 25
speed_travel = 300
acceleration_travel = 10000
retraction_amount = 5
retraction_hop_enabled = False

View file

@ -0,0 +1,27 @@
[general]
version = 4
name = Extra Fast
definition = deltacomb
[metadata]
setting_version = 7
type = quality
quality_type = verydraft
weight = -3
material = generic_tpu
[values]
adhesion_type = skirt
cool_fan_enabled = True
cool_fan_full_at_height = =layer_height * 6
cool_fan_speed = 100
cool_fan_speed_max = 100
cool_fan_speed_min = 70
cool_min_layer_time = 5
cool_min_speed = 20
material_print_temperature_layer_0 = =default_material_print_temperature + 5
speed_print = 25
speed_travel = 300
acceleration_travel = 10000
retraction_amount = 5
retraction_hop_enabled = False

View file

@ -0,0 +1,13 @@
[general]
name = E3D 0.25mm
version = 4
definition = deltacomb
[metadata]
author = Deltacomb 3D
setting_version = 5
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.25

View file

@ -0,0 +1,13 @@
[general]
name = E3D 0.40mm
version = 4
definition = deltacomb
[metadata]
author = Deltacomb 3D
setting_version = 5
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.4

View file

@ -0,0 +1,13 @@
[general]
name = E3D 0.80mm
version = 4
definition = deltacomb
[metadata]
author = Deltacomb 3D
setting_version = 5
type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.8

View file

@ -0,0 +1,14 @@
[general]
name = 0.20mm (Clear)
version = 4
definition = structur3d_discov3ry1_complete_um2plus
[metadata]
setting_version = 7
type = variant
hardware_type = nozzle
[values]
machine_nozzle_id = 0.20mm (Clear)
machine_nozzle_size = 0.20
machine_nozzle_tip_outer_diameter = 0.30

View file

@ -0,0 +1,14 @@
[general]
name = 0.25mm (Red)
version = 4
definition = structur3d_discov3ry1_complete_um2plus
[metadata]
setting_version = 7
type = variant
hardware_type = nozzle
[values]
machine_nozzle_id = 0.25mm (Red)
machine_nozzle_size = 0.25
machine_nozzle_tip_outer_diameter = 0.35

View file

@ -0,0 +1,14 @@
[general]
name = 0.41mm (Blue)
version = 4
definition = structur3d_discov3ry1_complete_um2plus
[metadata]
setting_version = 7
type = variant
hardware_type = nozzle
[values]
machine_nozzle_id = 0.41mm (Blue)
machine_nozzle_size = 0.41
machine_nozzle_tip_outer_diameter = 0.51

View file

@ -0,0 +1,14 @@
[general]
name = 0.58mm (Pink)
version = 4
definition = structur3d_discov3ry1_complete_um2plus
[metadata]
setting_version = 7
type = variant
hardware_type = nozzle
[values]
machine_nozzle_id = 0.58mm (Pink)
machine_nozzle_size = 0.58
machine_nozzle_tip_outer_diameter = 0.68

View file

@ -0,0 +1,14 @@
[general]
name = 0.84mm (Green)
version = 4
definition = structur3d_discov3ry1_complete_um2plus
[metadata]
setting_version = 7
type = variant
hardware_type = nozzle
[values]
machine_nozzle_id = 0.84mm (Green)
machine_nozzle_size = 0.84
machine_nozzle_tip_outer_diameter = 0.94

View file

@ -0,0 +1,14 @@
[general]
name = 1.19mm (Grey)
version = 4
definition = structur3d_discov3ry1_complete_um2plus
[metadata]
setting_version = 7
type = variant
hardware_type = nozzle
[values]
machine_nozzle_id = 1.19mm (Grey)
machine_nozzle_size = 1.19
machine_nozzle_tip_outer_diameter = 1.29

View file

@ -0,0 +1,14 @@
[general]
name = 1.60mm (Olive)
version = 4
definition = structur3d_discov3ry1_complete_um2plus
[metadata]
setting_version = 7
type = variant
hardware_type = nozzle
[values]
machine_nozzle_id = 1.60mm (Olive)
machine_nozzle_size = 1.60
machine_nozzle_tip_outer_diameter = 1.70