mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-12 19:29:02 +08:00
Merge branch 'Ultimaker:main' into master
This commit is contained in:
commit
9437de8266
4
.github/ISSUE_TEMPLATE/bugreport.yaml
vendored
4
.github/ISSUE_TEMPLATE/bugreport.yaml
vendored
@ -1,6 +1,6 @@
|
||||
name: Bug Report
|
||||
description: Create a report to help us fix issues.
|
||||
labels: "Type: Bug"
|
||||
labels: ["Type: Bug", "Status: Triage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@ -14,7 +14,7 @@ body:
|
||||
attributes:
|
||||
label: Application Version
|
||||
description: The version of Cura this issue occurs with.
|
||||
placeholder: 4.9.0
|
||||
placeholder: 5.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -65,6 +65,7 @@ plugins/CuraRemoteSupport
|
||||
plugins/ModelCutter
|
||||
plugins/PrintProfileCreator
|
||||
plugins/MultiPrintPlugin
|
||||
plugins/CuraOrientationPlugin
|
||||
|
||||
#Build stuff
|
||||
CMakeCache.txt
|
||||
|
@ -25,9 +25,10 @@
|
||||
</description>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>https://raw.githubusercontent.com/Ultimaker/Cura/master/screenshot.png</image>
|
||||
<image>https://raw.githubusercontent.com/Ultimaker/Cura/main/cura-logo.PNG</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<url type="homepage">https://ultimaker.com/software/ultimaker-cura?utm_source=cura&utm_medium=software&utm_campaign=cura-update-linux</url>
|
||||
<translation type="gettext">Cura</translation>
|
||||
<content_rating type="oars-1.1" />
|
||||
</component>
|
||||
|
@ -261,7 +261,7 @@ class CrashHandler:
|
||||
opengl_instance = OpenGL.getInstance()
|
||||
if not opengl_instance:
|
||||
self.data["opengl"] = {"version": "n/a", "vendor": "n/a", "type": "n/a"}
|
||||
return catalog.i18nc("@label", "Not yet initialized<br/>")
|
||||
return catalog.i18nc("@label", "Not yet initialized") + "<br />"
|
||||
|
||||
info = "<ul>"
|
||||
info += catalog.i18nc("@label OpenGL version", "<li>OpenGL Version: {version}</li>").format(version = opengl_instance.getOpenGLVersion())
|
||||
@ -291,6 +291,7 @@ class CrashHandler:
|
||||
if with_sentry_sdk:
|
||||
with configure_scope() as scope:
|
||||
scope.set_tag("opengl_version", opengl_instance.getOpenGLVersion())
|
||||
scope.set_tag("opengl_version_short", opengl_instance.getOpenGLVersionShort())
|
||||
scope.set_tag("gpu_vendor", opengl_instance.getGPUVendorName())
|
||||
scope.set_tag("gpu_type", opengl_instance.getGPUType())
|
||||
scope.set_tag("active_machine", active_machine_definition_id)
|
||||
|
@ -257,6 +257,7 @@ class CuraApplication(QtApplication):
|
||||
|
||||
from UM.CentralFileStorage import CentralFileStorage
|
||||
CentralFileStorage.setIsEnterprise(ApplicationMetadata.IsEnterpriseVersion)
|
||||
Resources.setIsEnterprise(ApplicationMetadata.IsEnterpriseVersion)
|
||||
|
||||
@pyqtProperty(str, constant=True)
|
||||
def ultimakerCloudApiRootUrl(self) -> str:
|
||||
@ -315,7 +316,7 @@ class CuraApplication(QtApplication):
|
||||
def initialize(self) -> None:
|
||||
self.__addExpectedResourceDirsAndSearchPaths() # Must be added before init of super
|
||||
|
||||
super().initialize()
|
||||
super().initialize(ApplicationMetadata.IsEnterpriseVersion)
|
||||
|
||||
self._preferences.addPreference("cura/single_instance", False)
|
||||
self._use_single_instance = self._preferences.getValue("cura/single_instance") or self._cli_args.single_instance
|
||||
@ -348,12 +349,12 @@ class CuraApplication(QtApplication):
|
||||
Resources.addExpectedDirNameInData(dir_name)
|
||||
|
||||
app_root = os.path.abspath(os.path.join(os.path.dirname(sys.executable)))
|
||||
Resources.addSearchPath(os.path.join(app_root, "share", "cura", "resources"))
|
||||
Resources.addSecureSearchPath(os.path.join(app_root, "share", "cura", "resources"))
|
||||
|
||||
Resources.addSearchPath(os.path.join(self._app_install_dir, "share", "cura", "resources"))
|
||||
Resources.addSecureSearchPath(os.path.join(self._app_install_dir, "share", "cura", "resources"))
|
||||
if not hasattr(sys, "frozen"):
|
||||
resource_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "resources")
|
||||
Resources.addSearchPath(resource_path)
|
||||
Resources.addSecureSearchPath(resource_path)
|
||||
|
||||
@classmethod
|
||||
def _initializeSettingDefinitions(cls):
|
||||
@ -942,6 +943,7 @@ class CuraApplication(QtApplication):
|
||||
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
||||
self._setLoadingHint(self._i18n_catalog.i18nc("@info:progress", "Initializing engine..."))
|
||||
self.initializeEngine()
|
||||
self.getTheme().setCheckIfTrusted(ApplicationMetadata.IsEnterpriseVersion)
|
||||
|
||||
# Initialize UI state
|
||||
controller.setActiveStage("PrepareStage")
|
||||
|
@ -1,14 +1,18 @@
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import os
|
||||
|
||||
from typing import Any, cast, Dict, List, Set, Tuple, TYPE_CHECKING, Optional
|
||||
|
||||
from UM.Logger import Logger
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from cura.CuraApplication import CuraApplication # To find some resource types.
|
||||
from cura.Settings.GlobalStack import GlobalStack
|
||||
|
||||
from UM.PackageManager import PackageManager # The class we're extending.
|
||||
from UM.Resources import Resources # To find storage paths for some resource types.
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -51,6 +55,27 @@ class CuraPackageManager(PackageManager):
|
||||
|
||||
super().initialize()
|
||||
|
||||
def getMaterialFilePackageId(self, file_name: str, guid: str) -> str:
|
||||
"""Get the id of the installed material package that contains file_name"""
|
||||
for material_package in [f for f in os.scandir(self._installation_dirs_dict["materials"]) if f.is_dir()]:
|
||||
package_id = material_package.name
|
||||
|
||||
for root, _, file_names in os.walk(material_package.path):
|
||||
if file_name not in file_names:
|
||||
# File with the name we are looking for is not in this directory
|
||||
continue
|
||||
|
||||
with open(root + "/" + file_name, encoding="utf-8") as f:
|
||||
# Make sure the file we found has the same guid as our material
|
||||
# Parsing this xml would be better but the namespace is needed to search it.
|
||||
parsed_guid = PluginRegistry.getInstance().getPluginObject("XmlMaterialProfile").getMetadataFromSerialized(
|
||||
f.read(), "GUID")
|
||||
if guid == parsed_guid:
|
||||
return package_id
|
||||
|
||||
Logger.error("Could not find package_id for file: {} with GUID: {} ".format(file_name, guid))
|
||||
return ""
|
||||
|
||||
def getMachinesUsingPackage(self, package_id: str) -> Tuple[List[Tuple[GlobalStack, str, str]], List[Tuple[GlobalStack, str, str]]]:
|
||||
"""Returns a list of where the package is used
|
||||
|
||||
|
@ -111,7 +111,7 @@ class IntentCategoryModel(ListModel):
|
||||
except ValueError:
|
||||
weight = 99
|
||||
result.append({
|
||||
"name": IntentCategoryModel.translation(category, "name", category),
|
||||
"name": IntentCategoryModel.translation(category, "name", category.title()),
|
||||
"description": IntentCategoryModel.translation(category, "description", None),
|
||||
"intent_category": category,
|
||||
"weight": weight,
|
||||
|
@ -45,8 +45,7 @@ class MaterialManagementModel(QObject):
|
||||
for package_id, package_data in application.getPackageManager().getPackagesInstalledOnStartup().items():
|
||||
if package_data["package_info"]["package_type"] == "material":
|
||||
# At least one new material was installed
|
||||
# TODO: This should be enabled again once CURA-8609 is merged
|
||||
#self._showSyncNewMaterialsMessage()
|
||||
self._showSyncNewMaterialsMessage()
|
||||
break
|
||||
|
||||
def _showSyncNewMaterialsMessage(self) -> None:
|
||||
|
@ -358,8 +358,9 @@ class QualityManagementModel(ListModel):
|
||||
"quality_type": quality_type,
|
||||
"quality_changes_group": None,
|
||||
"intent_category": intent_category,
|
||||
"section_name": catalog.i18nc("@label", intent_translations.get(intent_category, {}).get("name", catalog.i18nc("@label", "Unknown"))),
|
||||
"section_name": catalog.i18nc("@label", intent_translations.get(intent_category, {}).get("name", catalog.i18nc("@label", intent_category.title()))),
|
||||
})
|
||||
|
||||
# Sort by quality_type for each intent category
|
||||
intent_translations_list = list(intent_translations)
|
||||
|
||||
|
@ -114,7 +114,7 @@ class ContainerManager(QObject):
|
||||
for _ in range(len(entries)):
|
||||
item = item.get(entries.pop(0), {})
|
||||
|
||||
if item[entry_name] != entry_value:
|
||||
if entry_name not in item or item[entry_name] != entry_value:
|
||||
sub_item_changed = True
|
||||
item[entry_name] = entry_value
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2020 Ultimaker B.V.
|
||||
# Copyright (c) 2022 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt6.QtCore import pyqtSignal, pyqtProperty, QObject, QVariant # For communicating data and events to Qt.
|
||||
@ -382,7 +382,10 @@ class ExtruderManager(QObject):
|
||||
# "fdmextruder". We need to check a machine here so its extruder definition is correct according to this.
|
||||
def fixSingleExtrusionMachineExtruderDefinition(self, global_stack: "GlobalStack") -> None:
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
expected_extruder_definition_0_id = global_stack.getMetaDataEntry("machine_extruder_trains")["0"]
|
||||
expected_extruder_stack = global_stack.getMetaDataEntry("machine_extruder_trains")
|
||||
if expected_extruder_stack is None:
|
||||
return
|
||||
expected_extruder_definition_0_id = expected_extruder_stack["0"]
|
||||
try:
|
||||
extruder_stack_0 = global_stack.extruderList[0]
|
||||
except IndexError:
|
||||
|
@ -1611,7 +1611,7 @@ class MachineManager(QObject):
|
||||
if intent_category != "default":
|
||||
intent_display_name = IntentCategoryModel.translation(intent_category,
|
||||
"name",
|
||||
catalog.i18nc("@label", "Unknown"))
|
||||
intent_category.title())
|
||||
display_name = "{intent_name} - {the_rest}".format(intent_name = intent_display_name,
|
||||
the_rest = display_name)
|
||||
|
||||
|
@ -23,6 +23,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType
|
||||
from UM.Job import Job
|
||||
from UM.Preferences import Preferences
|
||||
from cura.CuraPackageManager import CuraPackageManager
|
||||
|
||||
from cura.Machines.ContainerTree import ContainerTree
|
||||
from cura.Settings.CuraStackBuilder import CuraStackBuilder
|
||||
@ -579,6 +580,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
is_printer_group = True
|
||||
machine_name = group_name
|
||||
|
||||
# Getting missing required package ids
|
||||
package_metadata = self._parse_packages_metadata(archive)
|
||||
missing_package_metadata = self._filter_missing_package_metadata(package_metadata)
|
||||
|
||||
# Show the dialog, informing the user what is about to happen.
|
||||
self._dialog.setMachineConflict(machine_conflict)
|
||||
self._dialog.setIsPrinterGroup(is_printer_group)
|
||||
@ -599,6 +604,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
self._dialog.setExtruders(extruders)
|
||||
self._dialog.setVariantType(variant_type_name)
|
||||
self._dialog.setHasObjectsOnPlate(Application.getInstance().platformActivity)
|
||||
self._dialog.setMissingPackagesMetadata(missing_package_metadata)
|
||||
self._dialog.show()
|
||||
|
||||
# Block until the dialog is closed.
|
||||
@ -1243,3 +1249,29 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
metadata = data.iterfind("./um:metadata/um:name/um:label", {"um": "http://www.ultimaker.com/material"})
|
||||
for entry in metadata:
|
||||
return entry.text
|
||||
|
||||
@staticmethod
|
||||
def _parse_packages_metadata(archive: zipfile.ZipFile) -> List[Dict[str, str]]:
|
||||
try:
|
||||
package_metadata = json.loads(archive.open("Metadata/packages.json").read().decode("utf-8"))
|
||||
return package_metadata["packages"]
|
||||
except KeyError:
|
||||
Logger.warning("No package metadata was found in .3mf file.")
|
||||
except Exception:
|
||||
Logger.error("Failed to load packes metadata from .3mf file")
|
||||
|
||||
return []
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _filter_missing_package_metadata(package_metadata: List[Dict[str, str]]) -> List[Dict[str, str]]:
|
||||
"""Filters out installed packages from package_metadata"""
|
||||
missing_packages = []
|
||||
package_manager = cast(CuraPackageManager, CuraApplication.getInstance().getPackageManager())
|
||||
|
||||
for package in package_metadata:
|
||||
package_id = package["id"]
|
||||
if not package_manager.isPackageInstalled(package_id):
|
||||
missing_packages.append(package)
|
||||
|
||||
return missing_packages
|
||||
|
@ -1,14 +1,19 @@
|
||||
# Copyright (c) 2020 Ultimaker B.V.
|
||||
# Copyright (c) 2022 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt6.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication, QUrl
|
||||
from PyQt6.QtGui import QDesktopServices
|
||||
from typing import List, Optional, Dict, cast
|
||||
|
||||
from PyQt6.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Application import Application
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from cura.Settings.GlobalStack import GlobalStack
|
||||
from UM.Application import Application
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
|
||||
from .UpdatableMachinesModel import UpdatableMachinesModel
|
||||
|
||||
import os
|
||||
@ -23,7 +28,7 @@ i18n_catalog = i18nCatalog("cura")
|
||||
class WorkspaceDialog(QObject):
|
||||
showDialogSignal = pyqtSignal()
|
||||
|
||||
def __init__(self, parent = None):
|
||||
def __init__(self, parent = None) -> None:
|
||||
super().__init__(parent)
|
||||
self._component = None
|
||||
self._context = None
|
||||
@ -59,6 +64,9 @@ class WorkspaceDialog(QObject):
|
||||
self._objects_on_plate = False
|
||||
self._is_printer_group = False
|
||||
self._updatable_machines_model = UpdatableMachinesModel(self)
|
||||
self._missing_package_metadata: List[Dict[str, str]] = []
|
||||
self._plugin_registry: PluginRegistry = CuraApplication.getInstance().getPluginRegistry()
|
||||
self._install_missing_package_dialog: Optional[QObject] = None
|
||||
|
||||
machineConflictChanged = pyqtSignal()
|
||||
qualityChangesConflictChanged = pyqtSignal()
|
||||
@ -79,6 +87,7 @@ class WorkspaceDialog(QObject):
|
||||
variantTypeChanged = pyqtSignal()
|
||||
extrudersChanged = pyqtSignal()
|
||||
isPrinterGroupChanged = pyqtSignal()
|
||||
missingPackagesChanged = pyqtSignal()
|
||||
|
||||
@pyqtProperty(bool, notify = isPrinterGroupChanged)
|
||||
def isPrinterGroup(self) -> bool:
|
||||
@ -274,6 +283,21 @@ class WorkspaceDialog(QObject):
|
||||
self._has_quality_changes_conflict = quality_changes_conflict
|
||||
self.qualityChangesConflictChanged.emit()
|
||||
|
||||
def setMissingPackagesMetadata(self, missing_package_metadata: List[Dict[str, str]]) -> None:
|
||||
self._missing_package_metadata = missing_package_metadata
|
||||
self.missingPackagesChanged.emit()
|
||||
|
||||
@pyqtProperty("QVariantList", notify=missingPackagesChanged)
|
||||
def missingPackages(self) -> List[Dict[str, str]]:
|
||||
return self._missing_package_metadata
|
||||
|
||||
@pyqtSlot()
|
||||
def installMissingPackages(self) -> None:
|
||||
marketplace_plugin = PluginRegistry.getInstance().getPluginObject("Marketplace")
|
||||
if not marketplace_plugin:
|
||||
Logger.warning("Could not show dialog to install missing plug-ins. Is Marketplace plug-in not available?")
|
||||
marketplace_plugin.showInstallMissingPackageDialog(self._missing_package_metadata, self.showMissingMaterialsWarning) # type: ignore
|
||||
|
||||
def getResult(self) -> Dict[str, Optional[str]]:
|
||||
if "machine" in self._result and self.updatableMachinesModel.count <= 1:
|
||||
self._result["machine"] = None
|
||||
@ -360,6 +384,41 @@ class WorkspaceDialog(QObject):
|
||||
time.sleep(1 / 50)
|
||||
QCoreApplication.processEvents() # Ensure that the GUI does not freeze.
|
||||
|
||||
@pyqtSlot()
|
||||
def showMissingMaterialsWarning(self) -> None:
|
||||
result_message = Message(
|
||||
i18n_catalog.i18nc("@info:status", "The material used in this project relies on some material definitions not available in Cura, this might produce undesirable print results. We highly recommend installing the full material package from the Marketplace."),
|
||||
lifetime=0,
|
||||
title=i18n_catalog.i18nc("@info:title", "Material profiles not installed"),
|
||||
message_type=Message.MessageType.WARNING
|
||||
)
|
||||
result_message.addAction(
|
||||
"learn_more",
|
||||
name=i18n_catalog.i18nc("@action:button", "Learn more"),
|
||||
icon="",
|
||||
description="Learn more about project materials.",
|
||||
button_align=Message.ActionButtonAlignment.ALIGN_LEFT,
|
||||
button_style=Message.ActionButtonStyle.LINK
|
||||
)
|
||||
result_message.addAction(
|
||||
"install_materials",
|
||||
name=i18n_catalog.i18nc("@action:button", "Install Materials"),
|
||||
icon="",
|
||||
description="Install missing materials from project file.",
|
||||
button_align=Message.ActionButtonAlignment.ALIGN_RIGHT,
|
||||
button_style=Message.ActionButtonStyle.DEFAULT
|
||||
)
|
||||
result_message.actionTriggered.connect(self._onMessageActionTriggered)
|
||||
result_message.show()
|
||||
|
||||
def _onMessageActionTriggered(self, message: Message, sync_message_action: str) -> None:
|
||||
if sync_message_action == "install_materials":
|
||||
self.installMissingPackages()
|
||||
message.hide()
|
||||
elif sync_message_action == "learn_more":
|
||||
QDesktopServices.openUrl(QUrl("https://support.ultimaker.com/hc/en-us/articles/360011968360-Using-the-Ultimaker-Marketplace"))
|
||||
|
||||
|
||||
def __show(self) -> None:
|
||||
if self._view is None:
|
||||
self._createViewFromQML()
|
||||
|
@ -17,7 +17,7 @@ UM.Dialog
|
||||
minimumWidth: UM.Theme.getSize("popup_dialog").width
|
||||
minimumHeight: UM.Theme.getSize("popup_dialog").height
|
||||
width: minimumWidth
|
||||
|
||||
margin: UM.Theme.getSize("default_margin").width
|
||||
property int comboboxHeight: UM.Theme.getSize("default_margin").height
|
||||
|
||||
onClosing: manager.notifyClosed()
|
||||
@ -31,337 +31,220 @@ UM.Dialog
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
Flickable
|
||||
{
|
||||
id: dialogSummaryItem
|
||||
clip: true
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
anchors.margins: 10 * screenScaleFactor
|
||||
height: parent.height
|
||||
contentHeight: dialogSummaryItem.height
|
||||
ScrollBar.vertical: UM.ScrollBar { id: verticalScrollBar }
|
||||
|
||||
UM.I18nCatalog
|
||||
Item
|
||||
{
|
||||
id: catalog
|
||||
name: "cura"
|
||||
}
|
||||
|
||||
ListModel
|
||||
{
|
||||
id: resolveStrategiesModel
|
||||
// Instead of directly adding the list elements, we add them afterwards.
|
||||
// This is because it's impossible to use setting function results to be bound to listElement properties directly.
|
||||
// See http://stackoverflow.com/questions/7659442/listelement-fields-as-properties
|
||||
Component.onCompleted:
|
||||
{
|
||||
append({"key": "override", "label": catalog.i18nc("@action:ComboBox Update/override existing profile", "Update existing")});
|
||||
append({"key": "new", "label": catalog.i18nc("@action:ComboBox Save settings in a new profile", "Create new")});
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width
|
||||
id: dialogSummaryItem
|
||||
width: verticalScrollBar.visible ? parent.width - verticalScrollBar.width - UM.Theme.getSize("default_margin").width : parent.width
|
||||
height: childrenRect.height
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
anchors.margins: 10 * screenScaleFactor
|
||||
|
||||
UM.I18nCatalog
|
||||
{
|
||||
id: catalog
|
||||
name: "cura"
|
||||
}
|
||||
|
||||
ListModel
|
||||
{
|
||||
id: resolveStrategiesModel
|
||||
// Instead of directly adding the list elements, we add them afterwards.
|
||||
// This is because it's impossible to use setting function results to be bound to listElement properties directly.
|
||||
// See http://stackoverflow.com/questions/7659442/listelement-fields-as-properties
|
||||
Component.onCompleted:
|
||||
{
|
||||
append({"key": "override", "label": catalog.i18nc("@action:ComboBox Update/override existing profile", "Update existing")});
|
||||
append({"key": "new", "label": catalog.i18nc("@action:ComboBox Save settings in a new profile", "Create new")});
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
|
||||
UM.Label
|
||||
Column
|
||||
{
|
||||
id: titleLabel
|
||||
text: catalog.i18nc("@action:title", "Summary - Cura Project")
|
||||
font: UM.Theme.getFont("large")
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: separator
|
||||
color: UM.Theme.getColor("text")
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("default_lining").height
|
||||
}
|
||||
}
|
||||
height: childrenRect.height
|
||||
|
||||
Item
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.TooltipArea
|
||||
{
|
||||
id: machineResolveStrategyTooltip
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
width: (parent.width / 3) | 0
|
||||
height: visible ? comboboxHeight : 0
|
||||
visible: base.visible && machineResolveComboBox.model.count > 1
|
||||
text: catalog.i18nc("@info:tooltip", "How should the conflict in the machine be resolved?")
|
||||
Cura.ComboBox
|
||||
UM.Label
|
||||
{
|
||||
id: machineResolveComboBox
|
||||
model: manager.updatableMachinesModel
|
||||
visible: machineResolveStrategyTooltip.visible
|
||||
textRole: "displayName"
|
||||
id: titleLabel
|
||||
text: catalog.i18nc("@action:title", "Summary - Cura Project")
|
||||
font: UM.Theme.getFont("large")
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: separator
|
||||
color: UM.Theme.getColor("text")
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("button").height
|
||||
onCurrentIndexChanged:
|
||||
{
|
||||
if (model.getItem(currentIndex).id == "new"
|
||||
&& model.getItem(currentIndex).type == "default_option")
|
||||
{
|
||||
manager.setResolveStrategy("machine", "new")
|
||||
}
|
||||
else
|
||||
{
|
||||
manager.setResolveStrategy("machine", "override")
|
||||
manager.setMachineToOverride(model.getItem(currentIndex).id)
|
||||
}
|
||||
}
|
||||
height: UM.Theme.getSize("default_lining").height
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged:
|
||||
{
|
||||
if (!visible) {return}
|
||||
Item
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
currentIndex = 0
|
||||
// If the project printer exists in Cura, set it as the default dropdown menu option.
|
||||
// No need to check object 0, which is the "Create new" option
|
||||
for (var i = 1; i < model.count; i++)
|
||||
UM.TooltipArea
|
||||
{
|
||||
id: machineResolveStrategyTooltip
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
width: (parent.width / 3) | 0
|
||||
height: visible ? comboboxHeight : 0
|
||||
visible: base.visible && machineResolveComboBox.model.count > 1
|
||||
text: catalog.i18nc("@info:tooltip", "How should the conflict in the machine be resolved?")
|
||||
Cura.ComboBox
|
||||
{
|
||||
id: machineResolveComboBox
|
||||
model: manager.updatableMachinesModel
|
||||
visible: machineResolveStrategyTooltip.visible
|
||||
textRole: "displayName"
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("button").height
|
||||
onCurrentIndexChanged:
|
||||
{
|
||||
if (model.getItem(i).name == manager.machineName)
|
||||
if (model.getItem(currentIndex).id == "new"
|
||||
&& model.getItem(currentIndex).type == "default_option")
|
||||
{
|
||||
currentIndex = i
|
||||
break
|
||||
manager.setResolveStrategy("machine", "new")
|
||||
}
|
||||
else
|
||||
{
|
||||
manager.setResolveStrategy("machine", "override")
|
||||
manager.setMachineToOverride(model.getItem(currentIndex).id)
|
||||
}
|
||||
}
|
||||
// The project printer does not exist in Cura. If there is at least one printer of the same
|
||||
// type, select the first one, else set the index to "Create new"
|
||||
if (currentIndex == 0 && model.count > 1)
|
||||
|
||||
onVisibleChanged:
|
||||
{
|
||||
currentIndex = 1
|
||||
if (!visible) {return}
|
||||
|
||||
currentIndex = 0
|
||||
// If the project printer exists in Cura, set it as the default dropdown menu option.
|
||||
// No need to check object 0, which is the "Create new" option
|
||||
for (var i = 1; i < model.count; i++)
|
||||
{
|
||||
if (model.getItem(i).name == manager.machineName)
|
||||
{
|
||||
currentIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
// The project printer does not exist in Cura. If there is at least one printer of the same
|
||||
// type, select the first one, else set the index to "Create new"
|
||||
if (currentIndex == 0 && model.count > 1)
|
||||
{
|
||||
currentIndex = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: printer_settings_label
|
||||
text: catalog.i18nc("@action:label", "Printer settings")
|
||||
font: UM.Theme.getFont("default_bold")
|
||||
}
|
||||
|
||||
Row
|
||||
Column
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Type")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: manager.machineType
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", manager.isPrinterGroup ? "Printer Group" : "Printer Name")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: manager.machineName
|
||||
width: (parent.width / 3) | 0
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.TooltipArea
|
||||
{
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
width: (parent.width / 3) | 0
|
||||
height: visible ? comboboxHeight : 0
|
||||
visible: manager.qualityChangesConflict
|
||||
text: catalog.i18nc("@info:tooltip", "How should the conflict in the profile be resolved?")
|
||||
Cura.ComboBox
|
||||
{
|
||||
model: resolveStrategiesModel
|
||||
textRole: "label"
|
||||
id: qualityChangesResolveComboBox
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("button").height
|
||||
onActivated:
|
||||
{
|
||||
manager.setResolveStrategy("quality_changes", resolveStrategiesModel.get(index).key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Profile settings")
|
||||
font: UM.Theme.getFont("default_bold")
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Name")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: manager.qualityName
|
||||
width: (parent.width / 3) | 0
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Intent")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: manager.intentName
|
||||
width: (parent.width / 3) | 0
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Not in profile")
|
||||
visible: manager.numUserSettings != 0
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18ncp("@action:label", "%1 override", "%1 overrides", manager.numUserSettings).arg(manager.numUserSettings)
|
||||
visible: manager.numUserSettings != 0
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Derivative from")
|
||||
visible: manager.numSettingsOverridenByQualityChanges != 0
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18ncp("@action:label", "%1, %2 override", "%1, %2 overrides", manager.numSettingsOverridenByQualityChanges).arg(manager.qualityType).arg(manager.numSettingsOverridenByQualityChanges)
|
||||
width: (parent.width / 3) | 0
|
||||
visible: manager.numSettingsOverridenByQualityChanges != 0
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.TooltipArea
|
||||
{
|
||||
id: materialResolveTooltip
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
width: (parent.width / 3) | 0
|
||||
height: visible ? comboboxHeight : 0
|
||||
visible: manager.materialConflict
|
||||
text: catalog.i18nc("@info:tooltip", "How should the conflict in the material be resolved?")
|
||||
Cura.ComboBox
|
||||
{
|
||||
model: resolveStrategiesModel
|
||||
textRole: "label"
|
||||
id: materialResolveComboBox
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("button").height
|
||||
onActivated:
|
||||
{
|
||||
manager.setResolveStrategy("material", resolveStrategiesModel.get(index).key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
Row
|
||||
{
|
||||
height: childrenRect.height
|
||||
width: parent.width
|
||||
spacing: UM.Theme.getSize("narrow_margin").width
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Material settings")
|
||||
id: printer_settings_label
|
||||
text: catalog.i18nc("@action:label", "Printer settings")
|
||||
font: UM.Theme.getFont("default_bold")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: manager.materialLabels
|
||||
delegate: Row
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Type")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: manager.machineType
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", manager.isPrinterGroup ? "Printer Group" : "Printer Name")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: manager.machineName
|
||||
width: (parent.width / 3) | 0
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.TooltipArea
|
||||
{
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
width: (parent.width / 3) | 0
|
||||
height: visible ? comboboxHeight : 0
|
||||
visible: manager.qualityChangesConflict
|
||||
text: catalog.i18nc("@info:tooltip", "How should the conflict in the profile be resolved?")
|
||||
Cura.ComboBox
|
||||
{
|
||||
model: resolveStrategiesModel
|
||||
textRole: "label"
|
||||
id: qualityChangesResolveComboBox
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("button").height
|
||||
onActivated:
|
||||
{
|
||||
manager.setResolveStrategy("quality_changes", resolveStrategiesModel.get(index).key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Profile settings")
|
||||
font: UM.Theme.getFont("default_bold")
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Name")
|
||||
@ -369,76 +252,250 @@ UM.Dialog
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: modelData
|
||||
text: manager.qualityName
|
||||
width: (parent.width / 3) | 0
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Intent")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: manager.intentName
|
||||
width: (parent.width / 3) | 0
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Not in profile")
|
||||
visible: manager.numUserSettings != 0
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18ncp("@action:label", "%1 override", "%1 overrides", manager.numUserSettings).arg(manager.numUserSettings)
|
||||
visible: manager.numUserSettings != 0
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Derivative from")
|
||||
visible: manager.numSettingsOverridenByQualityChanges != 0
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18ncp("@action:label", "%1, %2 override", "%1, %2 overrides", manager.numSettingsOverridenByQualityChanges).arg(manager.qualityType).arg(manager.numSettingsOverridenByQualityChanges)
|
||||
width: (parent.width / 3) | 0
|
||||
visible: manager.numSettingsOverridenByQualityChanges != 0
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
Item
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Setting visibility")
|
||||
font: UM.Theme.getFont("default_bold")
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.TooltipArea
|
||||
{
|
||||
id: materialResolveTooltip
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
width: (parent.width / 3) | 0
|
||||
height: visible ? comboboxHeight : 0
|
||||
visible: manager.materialConflict
|
||||
text: catalog.i18nc("@info:tooltip", "How should the conflict in the material be resolved?")
|
||||
Cura.ComboBox
|
||||
{
|
||||
model: resolveStrategiesModel
|
||||
textRole: "label"
|
||||
id: materialResolveComboBox
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("button").height
|
||||
onActivated:
|
||||
{
|
||||
manager.setResolveStrategy("material", resolveStrategiesModel.get(index).key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
Row
|
||||
{
|
||||
height: childrenRect.height
|
||||
width: parent.width
|
||||
spacing: UM.Theme.getSize("narrow_margin").width
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Material settings")
|
||||
font: UM.Theme.getFont("default_bold")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
}
|
||||
|
||||
Repeater
|
||||
{
|
||||
model: manager.materialLabels
|
||||
delegate: Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Name")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: modelData
|
||||
width: (parent.width / 3) | 0
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Setting visibility")
|
||||
font: UM.Theme.getFont("default_bold")
|
||||
}
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Mode")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: manager.activeMode
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
}
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
visible: manager.hasVisibleSettingsField
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Visible settings:")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "%1 out of %2" ).arg(manager.numVisibleSettings).arg(manager.totalNumberOfSettings)
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
UM.Label
|
||||
visible: manager.hasObjectsOnPlate
|
||||
UM.ColorImage
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Mode")
|
||||
width: (parent.width / 3) | 0
|
||||
width: warningLabel.height
|
||||
height: width
|
||||
source: UM.Theme.getIcon("Information")
|
||||
color: UM.Theme.getColor("text")
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: manager.activeMode
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
}
|
||||
Row
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
visible: manager.hasVisibleSettingsField
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "Visible settings:")
|
||||
width: (parent.width / 3) | 0
|
||||
}
|
||||
UM.Label
|
||||
{
|
||||
text: catalog.i18nc("@action:label", "%1 out of %2" ).arg(manager.numVisibleSettings).arg(manager.totalNumberOfSettings)
|
||||
width: (parent.width / 3) | 0
|
||||
id: warningLabel
|
||||
text: catalog.i18nc("@action:warning", "Loading a project will clear all models on the build plate.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row
|
||||
property bool warning: manager.missingPackages.length > 0
|
||||
|
||||
footerComponent: Rectangle
|
||||
{
|
||||
color: warning ? UM.Theme.getColor("warning") : "transparent"
|
||||
anchors.bottom: parent.bottom
|
||||
width: parent.width
|
||||
height: childrenRect.height + 2 * base.margin
|
||||
|
||||
Column
|
||||
{
|
||||
height: childrenRect.height
|
||||
spacing: base.margin
|
||||
|
||||
anchors.margins: base.margin
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
|
||||
RowLayout
|
||||
{
|
||||
width: parent.width
|
||||
id: warningRow
|
||||
height: childrenRect.height
|
||||
visible: manager.hasObjectsOnPlate
|
||||
visible: warning
|
||||
spacing: base.margin
|
||||
UM.ColorImage
|
||||
{
|
||||
width: warningLabel.height
|
||||
height: width
|
||||
source: UM.Theme.getIcon("Information")
|
||||
color: UM.Theme.getColor("text")
|
||||
width: UM.Theme.getSize("extruder_icon").width
|
||||
height: UM.Theme.getSize("extruder_icon").height
|
||||
source: UM.Theme.getIcon("Warning")
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
id: warningLabel
|
||||
text: catalog.i18nc("@action:warning", "Loading a project will clear all models on the build plate.")
|
||||
id: warningText
|
||||
text: "The material used in this project is currently not installed in Cura.<br/>Install the material profile and reopen the project."
|
||||
}
|
||||
}
|
||||
|
||||
Loader
|
||||
{
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
sourceComponent: buttonRow
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,13 +504,30 @@ UM.Dialog
|
||||
rightButtons: [
|
||||
Cura.TertiaryButton
|
||||
{
|
||||
visible: !warning
|
||||
text: catalog.i18nc("@action:button", "Cancel")
|
||||
onClicked: reject()
|
||||
},
|
||||
Cura.PrimaryButton
|
||||
{
|
||||
visible: !warning
|
||||
text: catalog.i18nc("@action:button", "Open")
|
||||
onClicked: accept()
|
||||
},
|
||||
Cura.TertiaryButton
|
||||
{
|
||||
visible: warning
|
||||
text: catalog.i18nc("@action:button", "Open project anyway")
|
||||
onClicked: {
|
||||
manager.showMissingMaterialsWarning();
|
||||
accept();
|
||||
}
|
||||
},
|
||||
Cura.PrimaryButton
|
||||
{
|
||||
visible: warning
|
||||
text: catalog.i18nc("@action:button", "Install missing material")
|
||||
onClicked: manager.installMissingPackages()
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -1,15 +1,19 @@
|
||||
# Copyright (c) 2015-2022 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import Optional
|
||||
import json
|
||||
|
||||
from typing import Optional, cast, List, Dict
|
||||
|
||||
from UM.Mesh.MeshWriter import MeshWriter
|
||||
from UM.Math.Vector import Vector
|
||||
from UM.Logger import Logger
|
||||
from UM.Math.Matrix import Matrix
|
||||
from UM.Application import Application
|
||||
from UM.Message import Message
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.CuraPackageManager import CuraPackageManager
|
||||
from cura.Utils.Threading import call_on_qt_thread
|
||||
from cura.Snapshot import Snapshot
|
||||
|
||||
@ -34,6 +38,9 @@ import UM.Application
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
THUMBNAIL_PATH = "Metadata/thumbnail.png"
|
||||
MODEL_PATH = "3D/3dmodel.model"
|
||||
PACKAGE_METADATA_PATH = "Metadata/packages.json"
|
||||
|
||||
class ThreeMFWriter(MeshWriter):
|
||||
def __init__(self):
|
||||
@ -46,7 +53,7 @@ class ThreeMFWriter(MeshWriter):
|
||||
}
|
||||
|
||||
self._unit_matrix_string = self._convertMatrixToString(Matrix())
|
||||
self._archive = None # type: Optional[zipfile.ZipFile]
|
||||
self._archive: Optional[zipfile.ZipFile] = None
|
||||
self._store_archive = False
|
||||
|
||||
def _convertMatrixToString(self, matrix):
|
||||
@ -132,11 +139,11 @@ class ThreeMFWriter(MeshWriter):
|
||||
def getArchive(self):
|
||||
return self._archive
|
||||
|
||||
def write(self, stream, nodes, mode = MeshWriter.OutputMode.BinaryMode):
|
||||
def write(self, stream, nodes, mode = MeshWriter.OutputMode.BinaryMode) -> bool:
|
||||
self._archive = None # Reset archive
|
||||
archive = zipfile.ZipFile(stream, "w", compression = zipfile.ZIP_DEFLATED)
|
||||
try:
|
||||
model_file = zipfile.ZipInfo("3D/3dmodel.model")
|
||||
model_file = zipfile.ZipInfo(MODEL_PATH)
|
||||
# Because zipfile is stupid and ignores archive-level compression settings when writing with ZipInfo.
|
||||
model_file.compress_type = zipfile.ZIP_DEFLATED
|
||||
|
||||
@ -151,7 +158,7 @@ class ThreeMFWriter(MeshWriter):
|
||||
relations_file = zipfile.ZipInfo("_rels/.rels")
|
||||
relations_file.compress_type = zipfile.ZIP_DEFLATED
|
||||
relations_element = ET.Element("Relationships", xmlns = self._namespaces["relationships"])
|
||||
model_relation_element = ET.SubElement(relations_element, "Relationship", Target = "/3D/3dmodel.model", Id = "rel0", Type = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel")
|
||||
model_relation_element = ET.SubElement(relations_element, "Relationship", Target = "/" + MODEL_PATH, Id = "rel0", Type = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel")
|
||||
|
||||
# Attempt to add a thumbnail
|
||||
snapshot = self._createSnapshot()
|
||||
@ -160,28 +167,32 @@ class ThreeMFWriter(MeshWriter):
|
||||
thumbnail_buffer.open(QBuffer.OpenModeFlag.ReadWrite)
|
||||
snapshot.save(thumbnail_buffer, "PNG")
|
||||
|
||||
thumbnail_file = zipfile.ZipInfo("Metadata/thumbnail.png")
|
||||
thumbnail_file = zipfile.ZipInfo(THUMBNAIL_PATH)
|
||||
# Don't try to compress snapshot file, because the PNG is pretty much as compact as it will get
|
||||
archive.writestr(thumbnail_file, thumbnail_buffer.data())
|
||||
|
||||
# Add PNG to content types file
|
||||
thumbnail_type = ET.SubElement(content_types, "Default", Extension = "png", ContentType = "image/png")
|
||||
# Add thumbnail relation to _rels/.rels file
|
||||
thumbnail_relation_element = ET.SubElement(relations_element, "Relationship", Target = "/Metadata/thumbnail.png", Id = "rel1", Type = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail")
|
||||
thumbnail_relation_element = ET.SubElement(relations_element, "Relationship", Target = "/" + THUMBNAIL_PATH, Id = "rel1", Type = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail")
|
||||
|
||||
# Write material metadata
|
||||
material_metadata = self._getMaterialPackageMetadata()
|
||||
self._storeMetadataJson({"packages": material_metadata}, archive, PACKAGE_METADATA_PATH)
|
||||
|
||||
savitar_scene = Savitar.Scene()
|
||||
|
||||
metadata_to_store = CuraApplication.getInstance().getController().getScene().getMetaData()
|
||||
scene_metadata = CuraApplication.getInstance().getController().getScene().getMetaData()
|
||||
|
||||
for key, value in metadata_to_store.items():
|
||||
for key, value in scene_metadata.items():
|
||||
savitar_scene.setMetaDataEntry(key, value)
|
||||
|
||||
current_time_string = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
if "Application" not in metadata_to_store:
|
||||
if "Application" not in scene_metadata:
|
||||
# This might sound a bit strange, but this field should store the original application that created
|
||||
# the 3mf. So if it was already set, leave it to whatever it was.
|
||||
savitar_scene.setMetaDataEntry("Application", CuraApplication.getInstance().getApplicationDisplayName())
|
||||
if "CreationDate" not in metadata_to_store:
|
||||
if "CreationDate" not in scene_metadata:
|
||||
savitar_scene.setMetaDataEntry("CreationDate", current_time_string)
|
||||
|
||||
savitar_scene.setMetaDataEntry("ModificationDate", current_time_string)
|
||||
@ -233,6 +244,53 @@ class ThreeMFWriter(MeshWriter):
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def _storeMetadataJson(metadata: Dict[str, List[Dict[str, str]]], archive: zipfile.ZipFile, path: str) -> None:
|
||||
"""Stores metadata inside archive path as json file"""
|
||||
metadata_file = zipfile.ZipInfo(path)
|
||||
# We have to set the compress type of each file as well (it doesn't keep the type of the entire archive)
|
||||
metadata_file.compress_type = zipfile.ZIP_DEFLATED
|
||||
archive.writestr(metadata_file, json.dumps(metadata, separators=(", ", ": "), indent=4, skipkeys=True, ensure_ascii=False))
|
||||
|
||||
@staticmethod
|
||||
def _getMaterialPackageMetadata() -> List[Dict[str, str]]:
|
||||
"""Get metadata for installed materials in active extruder stack, this does not include bundled materials.
|
||||
|
||||
:return: List of material metadata dictionaries.
|
||||
"""
|
||||
metadata = {}
|
||||
|
||||
package_manager = cast(CuraPackageManager, CuraApplication.getInstance().getPackageManager())
|
||||
|
||||
for extruder in CuraApplication.getInstance().getExtruderManager().getActiveExtruderStacks():
|
||||
if not extruder.isEnabled:
|
||||
# Don't export materials not in use
|
||||
continue
|
||||
|
||||
package_id = package_manager.getMaterialFilePackageId(extruder.material.getFileName(), extruder.material.getMetaDataEntry("GUID"))
|
||||
package_data = package_manager.getInstalledPackageInfo(package_id)
|
||||
|
||||
if not package_data:
|
||||
message = Message(catalog.i18nc("@error:material",
|
||||
"It was not possible to store material package information in project file: {material}. This project may not open correctly on other systems.".format(material=extruder.getName())),
|
||||
title=catalog.i18nc("@info:title", "Failed to save material package information"),
|
||||
message_type=Message.MessageType.WARNING)
|
||||
message.show()
|
||||
continue
|
||||
|
||||
if package_data.get("is_bundled"):
|
||||
continue
|
||||
|
||||
material_metadata = {"id": package_id,
|
||||
"display_name": package_data.get("display_name") if package_data.get("display_name") else "",
|
||||
"package_version": package_data.get("package_version") if package_data.get("package_version") else "",
|
||||
"sdk_version_semver": package_data.get("sdk_version_semver") if package_data.get("sdk_version_semver") else ""}
|
||||
|
||||
metadata[package_id] = material_metadata
|
||||
|
||||
# Storing in a dict and fetching values to avoid duplicates
|
||||
return list(metadata.values())
|
||||
|
||||
@call_on_qt_thread # must be called from the main thread because of OpenGL
|
||||
def _createSnapshot(self):
|
||||
Logger.log("d", "Creating thumbnail image...")
|
||||
|
@ -60,7 +60,7 @@ class CuraEngineBackend(QObject, Backend):
|
||||
executable_name = "CuraEngine"
|
||||
if Platform.isWindows():
|
||||
executable_name += ".exe"
|
||||
default_engine_location = executable_name
|
||||
self._default_engine_location = executable_name
|
||||
|
||||
search_path = [
|
||||
os.path.abspath(os.path.dirname(sys.executable)),
|
||||
@ -74,29 +74,29 @@ class CuraEngineBackend(QObject, Backend):
|
||||
for path in search_path:
|
||||
engine_path = os.path.join(path, executable_name)
|
||||
if os.path.isfile(engine_path):
|
||||
default_engine_location = engine_path
|
||||
self._default_engine_location = engine_path
|
||||
break
|
||||
|
||||
if Platform.isLinux() and not default_engine_location:
|
||||
if Platform.isLinux() and not self._default_engine_location:
|
||||
if not os.getenv("PATH"):
|
||||
raise OSError("There is something wrong with your Linux installation.")
|
||||
for pathdir in cast(str, os.getenv("PATH")).split(os.pathsep):
|
||||
execpath = os.path.join(pathdir, executable_name)
|
||||
if os.path.exists(execpath):
|
||||
default_engine_location = execpath
|
||||
self._default_engine_location = execpath
|
||||
break
|
||||
|
||||
application = CuraApplication.getInstance() #type: CuraApplication
|
||||
self._multi_build_plate_model = None #type: Optional[MultiBuildPlateModel]
|
||||
self._machine_error_checker = None #type: Optional[MachineErrorChecker]
|
||||
|
||||
if not default_engine_location:
|
||||
if not self._default_engine_location:
|
||||
raise EnvironmentError("Could not find CuraEngine")
|
||||
|
||||
Logger.log("i", "Found CuraEngine at: %s", default_engine_location)
|
||||
Logger.log("i", "Found CuraEngine at: %s", self._default_engine_location)
|
||||
|
||||
default_engine_location = os.path.abspath(default_engine_location)
|
||||
application.getPreferences().addPreference("backend/location", default_engine_location)
|
||||
self._default_engine_location = os.path.abspath(self._default_engine_location)
|
||||
application.getPreferences().addPreference("backend/location", self._default_engine_location)
|
||||
|
||||
# Workaround to disable layer view processing if layer view is not active.
|
||||
self._layer_view_active = False #type: bool
|
||||
@ -215,7 +215,12 @@ class CuraEngineBackend(QObject, Backend):
|
||||
This is useful for debugging and used to actually start the engine.
|
||||
:return: list of commands and args / parameters.
|
||||
"""
|
||||
command = [CuraApplication.getInstance().getPreferences().getValue("backend/location"), "connect", "127.0.0.1:{0}".format(self._port), ""]
|
||||
from cura import ApplicationMetadata
|
||||
if ApplicationMetadata.IsEnterpriseVersion:
|
||||
command = [self._default_engine_location]
|
||||
else:
|
||||
command = [CuraApplication.getInstance().getPreferences().getValue("backend/location")]
|
||||
command += ["connect", "127.0.0.1:{0}".format(self._port), ""]
|
||||
|
||||
parser = argparse.ArgumentParser(prog = "cura", add_help = False)
|
||||
parser.add_argument("--debug", action = "store_true", default = False, help = "Turn on the debug mode by setting this option.")
|
||||
|
67
plugins/Marketplace/InstallMissingPackagesDialog.py
Normal file
67
plugins/Marketplace/InstallMissingPackagesDialog.py
Normal file
@ -0,0 +1,67 @@
|
||||
# Copyright (c) 2022 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import os
|
||||
|
||||
from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty
|
||||
from typing import Optional, List, Dict, cast, Callable
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from cura.CuraPackageManager import CuraPackageManager
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
from .MissingPackageList import MissingPackageList
|
||||
|
||||
i18n_catalog = i18nCatalog("cura")
|
||||
|
||||
class InstallMissingPackageDialog(QObject):
|
||||
"""Dialog used to display packages that need to be installed to load 3mf file materials"""
|
||||
def __init__(self, packages_metadata: List[Dict[str, str]], show_missing_materials_warning: Callable[[], None]) -> None:
|
||||
"""Initialize
|
||||
|
||||
:param packages_metadata: List of dictionaries containing information about missing packages.
|
||||
"""
|
||||
super().__init__()
|
||||
|
||||
self._plugin_registry: PluginRegistry = CuraApplication.getInstance().getPluginRegistry()
|
||||
self._package_manager: CuraPackageManager = cast(CuraPackageManager, CuraApplication.getInstance().getPackageManager())
|
||||
self._package_manager.installedPackagesChanged.connect(self.checkIfRestartNeeded)
|
||||
|
||||
self._dialog: Optional[QObject] = None
|
||||
self._restart_needed = False
|
||||
self._package_metadata: List[Dict[str, str]] = packages_metadata
|
||||
|
||||
self._package_model: MissingPackageList = MissingPackageList(packages_metadata)
|
||||
self._show_missing_materials_warning = show_missing_materials_warning
|
||||
|
||||
def show(self) -> None:
|
||||
plugin_path = self._plugin_registry.getPluginPath("Marketplace")
|
||||
if plugin_path is None:
|
||||
plugin_path = os.path.dirname(__file__)
|
||||
|
||||
# create a QML component for the license dialog
|
||||
license_dialog_component_path = os.path.join(plugin_path, "resources", "qml", "InstallMissingPackagesDialog.qml")
|
||||
self._dialog = CuraApplication.getInstance().createQmlComponent(license_dialog_component_path, {"manager": self})
|
||||
self._dialog.show()
|
||||
|
||||
def checkIfRestartNeeded(self) -> None:
|
||||
if self._dialog is None:
|
||||
return
|
||||
|
||||
self._restart_needed = self._package_manager.hasPackagesToRemoveOrInstall
|
||||
self.showRestartChanged.emit()
|
||||
|
||||
showRestartChanged = pyqtSignal()
|
||||
|
||||
@pyqtProperty(bool, notify=showRestartChanged)
|
||||
def showRestartNotification(self) -> bool:
|
||||
return self._restart_needed
|
||||
|
||||
@pyqtProperty(QObject)
|
||||
def model(self) -> MissingPackageList:
|
||||
return self._package_model
|
||||
|
||||
@pyqtSlot()
|
||||
def showMissingMaterialsWarning(self) -> None:
|
||||
self._show_missing_materials_warning()
|
@ -3,15 +3,15 @@
|
||||
|
||||
import os.path
|
||||
from PyQt6.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
|
||||
from typing import Optional, cast
|
||||
from typing import Callable, cast, Dict, List, Optional
|
||||
|
||||
from cura.CuraApplication import CuraApplication # Creating QML objects and managing packages.
|
||||
|
||||
from UM.Extension import Extension # We are implementing the main object of an extension here.
|
||||
from UM.PluginRegistry import PluginRegistry # To find out where we are stored (the proper way).
|
||||
|
||||
from .RemotePackageList import RemotePackageList # To register this type with QML.
|
||||
from .InstallMissingPackagesDialog import InstallMissingPackageDialog # To allow creating this dialogue from outside of the plug-in.
|
||||
from .LocalPackageList import LocalPackageList # To register this type with QML.
|
||||
from .RemotePackageList import RemotePackageList # To register this type with QML.
|
||||
|
||||
|
||||
class Marketplace(Extension, QObject):
|
||||
@ -41,6 +41,7 @@ class Marketplace(Extension, QObject):
|
||||
|
||||
self._tab_shown: int = 0
|
||||
self._restart_needed = False
|
||||
self.missingPackageDialog = None
|
||||
|
||||
def getTabShown(self) -> int:
|
||||
return self._tab_shown
|
||||
@ -103,6 +104,9 @@ class Marketplace(Extension, QObject):
|
||||
self.setTabShown(1)
|
||||
|
||||
def checkIfRestartNeeded(self) -> None:
|
||||
if self._window is None:
|
||||
return
|
||||
|
||||
if self._package_manager.hasPackagesToRemoveOrInstall or \
|
||||
cast(PluginRegistry, self._plugin_registry).getCurrentSessionActivationChangedPlugins():
|
||||
self._restart_needed = True
|
||||
@ -115,3 +119,15 @@ class Marketplace(Extension, QObject):
|
||||
@pyqtProperty(bool, notify=showRestartNotificationChanged)
|
||||
def showRestartNotification(self) -> bool:
|
||||
return self._restart_needed
|
||||
|
||||
def showInstallMissingPackageDialog(self, packages_metadata: List[Dict[str, str]], ignore_warning_callback: Callable[[], None]) -> None:
|
||||
"""
|
||||
Show a dialog that prompts the user to install certain packages.
|
||||
|
||||
The dialog is worded for packages that are missing and required for a certain operation.
|
||||
:param packages_metadata: The metadata of the packages that are missing.
|
||||
:param ignore_warning_callback: A callback that gets executed when the user ignores the pop-up, to show them a
|
||||
warning.
|
||||
"""
|
||||
self.missingPackageDialog = InstallMissingPackageDialog(packages_metadata, ignore_warning_callback)
|
||||
self.missingPackageDialog.show()
|
||||
|
46
plugins/Marketplace/MissingPackageList.py
Normal file
46
plugins/Marketplace/MissingPackageList.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Copyright (c) 2022 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from typing import Optional, TYPE_CHECKING, Dict, List
|
||||
|
||||
from .Constants import PACKAGES_URL
|
||||
from .PackageModel import PackageModel
|
||||
from .RemotePackageList import RemotePackageList
|
||||
from PyQt6.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication
|
||||
|
||||
from UM.TaskManagement.HttpRequestManager import HttpRequestManager # To request the package list from the API.
|
||||
from UM.i18n import i18nCatalog
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from PyQt6.QtCore import QObject, pyqtProperty, pyqtSignal
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
class MissingPackageList(RemotePackageList):
|
||||
def __init__(self, packages_metadata: List[Dict[str, str]], parent: Optional["QObject"] = None) -> None:
|
||||
super().__init__(parent)
|
||||
self._packages_metadata: List[Dict[str, str]] = packages_metadata
|
||||
self._package_type_filter = "material"
|
||||
self._search_type = "package_ids"
|
||||
self._requested_search_string = ",".join(map(lambda package: package["id"], packages_metadata))
|
||||
|
||||
def _parseResponse(self, reply: "QNetworkReply") -> None:
|
||||
super()._parseResponse(reply)
|
||||
|
||||
# At the end of the list we want to show some information about packages the user is missing that can't be found
|
||||
# This will add cards with some information about the missing packages
|
||||
if not self.hasMore:
|
||||
self._addPackagesMissingFromRequest()
|
||||
|
||||
def _addPackagesMissingFromRequest(self) -> None:
|
||||
"""Create cards for packages the user needs to install that could not be found"""
|
||||
returned_packages_ids = [item["package"].packageId for item in self._items]
|
||||
|
||||
for package_metadata in self._packages_metadata:
|
||||
if package_metadata["id"] not in returned_packages_ids:
|
||||
package = PackageModel.fromIncompletePackageInformation(package_metadata["display_name"], package_metadata["package_version"], self._package_type_filter)
|
||||
self.appendItem({"package": package})
|
||||
|
||||
self.itemsChanged.emit()
|
||||
|
||||
|
@ -244,7 +244,10 @@ class PackageList(ListModel):
|
||||
|
||||
def _downloadError(self, package_id: str, update: bool = False, reply: Optional["QNetworkReply"] = None, error: Optional["QNetworkReply.NetworkError"] = None) -> None:
|
||||
if reply:
|
||||
reply_string = bytes(reply.readAll()).decode()
|
||||
try:
|
||||
reply_string = bytes(reply.readAll()).decode()
|
||||
except UnicodeDecodeError:
|
||||
reply_string = "<error message is corrupt too>"
|
||||
Logger.error(f"Failed to download package: {package_id} due to {reply_string}")
|
||||
self._package_manager.packageInstallingFailed.emit(package_id)
|
||||
|
||||
|
@ -84,6 +84,20 @@ class PackageModel(QObject):
|
||||
|
||||
self._is_busy = False
|
||||
|
||||
self._is_missing_package_information = False
|
||||
|
||||
@classmethod
|
||||
def fromIncompletePackageInformation(cls, display_name: str, package_version: str, package_type: str) -> "PackageModel":
|
||||
package_data = {
|
||||
"display_name": display_name,
|
||||
"package_version": package_version,
|
||||
"package_type": package_type,
|
||||
"description": "The material package associated with the Cura project could not be found on the Ultimaker marketplace. Use the partial material profile definition stored in the Cura project file at your own risk."
|
||||
}
|
||||
package_model = cls(package_data)
|
||||
package_model.setIsMissingPackageInformation(True)
|
||||
return package_model
|
||||
|
||||
@pyqtSlot()
|
||||
def _processUpdatedPackages(self):
|
||||
self.setCanUpdate(self._package_manager.checkIfPackageCanUpdate(self._package_id))
|
||||
@ -385,3 +399,14 @@ class PackageModel(QObject):
|
||||
def canUpdate(self) -> bool:
|
||||
"""Flag indicating if the package can be updated"""
|
||||
return self._can_update
|
||||
|
||||
isMissingPackageInformationChanged = pyqtSignal()
|
||||
|
||||
def setIsMissingPackageInformation(self, isMissingPackageInformation: bool) -> None:
|
||||
self._is_missing_package_information = isMissingPackageInformation
|
||||
self.isMissingPackageInformationChanged.emit()
|
||||
|
||||
@pyqtProperty(bool, notify=isMissingPackageInformationChanged)
|
||||
def isMissingPackageInformation(self) -> bool:
|
||||
"""Flag indicating if the package can be updated"""
|
||||
return self._is_missing_package_information
|
||||
|
@ -28,6 +28,7 @@ class RemotePackageList(PackageList):
|
||||
self._package_type_filter = ""
|
||||
self._requested_search_string = ""
|
||||
self._current_search_string = ""
|
||||
self._search_type = "search"
|
||||
self._request_url = self._initialRequestUrl()
|
||||
self._ongoing_requests["get_packages"] = None
|
||||
self.isLoadingChanged.connect(self._onLoadingChanged)
|
||||
@ -100,7 +101,7 @@ class RemotePackageList(PackageList):
|
||||
if self._package_type_filter != "":
|
||||
request_url += f"&package_type={self._package_type_filter}"
|
||||
if self._current_search_string != "":
|
||||
request_url += f"&search={self._current_search_string}"
|
||||
request_url += f"&{self._search_type}={self._current_search_string}"
|
||||
return request_url
|
||||
|
||||
def _parseResponse(self, reply: "QNetworkReply") -> None:
|
||||
|
@ -14,4 +14,4 @@ def register(app):
|
||||
"""
|
||||
Register the plug-in object with Uranium.
|
||||
"""
|
||||
return { "extension": [Marketplace(), SyncOrchestrator(app)] }
|
||||
return { "extension": [SyncOrchestrator(app), Marketplace()] }
|
||||
|
@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2021 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
import UM 1.5 as UM
|
||||
import Cura 1.6 as Cura
|
||||
|
||||
Marketplace
|
||||
{
|
||||
modality: Qt.ApplicationModal
|
||||
title: catalog.i18nc("@title", "Install missing Materials")
|
||||
pageContentsSource: "MissingPackages.qml"
|
||||
showSearchHeader: false
|
||||
showOnboadBanner: false
|
||||
|
||||
onClosing: manager.showMissingMaterialsWarning()
|
||||
}
|
@ -16,6 +16,10 @@ Window
|
||||
|
||||
signal searchStringChanged(string new_search)
|
||||
|
||||
property alias showOnboadBanner: onBoardBanner.visible
|
||||
property alias showSearchHeader: searchHeader.visible
|
||||
property alias pageContentsSource: content.source
|
||||
|
||||
minimumWidth: UM.Theme.getSize("modal_window_minimum").width
|
||||
minimumHeight: UM.Theme.getSize("modal_window_minimum").height
|
||||
width: minimumWidth
|
||||
@ -86,6 +90,7 @@ Window
|
||||
|
||||
OnboardBanner
|
||||
{
|
||||
id: onBoardBanner
|
||||
visible: content.item && content.item.bannerVisible
|
||||
text: content.item && content.item.bannerText
|
||||
icon: content.item && content.item.bannerIcon
|
||||
@ -100,6 +105,7 @@ Window
|
||||
// Search & Top-Level Tabs
|
||||
Item
|
||||
{
|
||||
id: searchHeader
|
||||
implicitHeight: childrenRect.height
|
||||
implicitWidth: parent.width - 2 * UM.Theme.getSize("default_margin").width
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
@ -186,7 +192,7 @@ Window
|
||||
{
|
||||
text: catalog.i18nc("@info", "Search in the browser")
|
||||
iconSource: UM.Theme.getIcon("LinkExternal")
|
||||
visible: pageSelectionTabBar.currentItem.hasSearch
|
||||
visible: pageSelectionTabBar.currentItem.hasSearch && searchHeader.visible
|
||||
isIconOnRightSide: true
|
||||
height: fontMetrics.height
|
||||
textFont: fontMetrics.font
|
||||
|
15
plugins/Marketplace/resources/qml/MissingPackages.qml
Normal file
15
plugins/Marketplace/resources/qml/MissingPackages.qml
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2021 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import UM 1.4 as UM
|
||||
|
||||
Packages
|
||||
{
|
||||
pageTitle: catalog.i18nc("@header", "Install Materials")
|
||||
|
||||
bannerVisible: false
|
||||
showUpdateButton: false
|
||||
showInstallButton: true
|
||||
|
||||
model: manager.model
|
||||
}
|
@ -18,6 +18,8 @@ Rectangle
|
||||
height: childrenRect.height
|
||||
color: UM.Theme.getColor("main_background")
|
||||
radius: UM.Theme.getSize("default_radius").width
|
||||
border.color: packageData.isMissingPackageInformation ? UM.Theme.getColor("warning") : "transparent"
|
||||
border.width: packageData.isMissingPackageInformation ? UM.Theme.getSize("default_lining").width : 0
|
||||
|
||||
PackageCardHeader
|
||||
{
|
||||
|
@ -19,6 +19,8 @@ Item
|
||||
property bool showInstallButton: false
|
||||
property bool showUpdateButton: false
|
||||
|
||||
property string missingPackageReadMoreUrl: "https://ultimaker.atlassian.net/wiki/spaces/SD/pages/1231916580/Campaign+links+from+Cura+to+the+Ultimaker+domain"
|
||||
|
||||
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("card").height
|
||||
@ -87,6 +89,14 @@ Item
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
|
||||
UM.StatusIcon
|
||||
{
|
||||
width: UM.Theme.getSize("section_icon").width + UM.Theme.getSize("narrow_margin").width
|
||||
height: UM.Theme.getSize("section_icon").height
|
||||
status: UM.StatusIcon.Status.WARNING
|
||||
visible: packageData.isMissingPackageInformation
|
||||
}
|
||||
|
||||
UM.Label
|
||||
{
|
||||
text: packageData.displayName
|
||||
@ -109,6 +119,7 @@ Item
|
||||
Button
|
||||
{
|
||||
id: externalLinkButton
|
||||
visible: !packageData.isMissingPackageInformation
|
||||
|
||||
// For some reason if i set padding, they don't match up. If i set all of them explicitly, it does work?
|
||||
leftPadding: UM.Theme.getSize("narrow_margin").width
|
||||
@ -155,6 +166,7 @@ Item
|
||||
UM.Label
|
||||
{
|
||||
id: authorBy
|
||||
visible: !packageData.isMissingPackageInformation
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
text: catalog.i18nc("@label Is followed by the name of an author", "By")
|
||||
@ -165,6 +177,7 @@ Item
|
||||
// clickable author name
|
||||
Item
|
||||
{
|
||||
visible: !packageData.isMissingPackageInformation
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: authorBy.height
|
||||
Layout.alignment: Qt.AlignTop
|
||||
@ -182,10 +195,29 @@ Item
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
visible: packageData.isMissingPackageInformation
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: readMoreButton.height
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Cura.TertiaryButton
|
||||
{
|
||||
id: readMoreButton
|
||||
text: catalog.i18nc("@button:label", "Learn More")
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
iconSource: UM.Theme.getIcon("LinkExternal")
|
||||
isIconOnRightSide: true
|
||||
|
||||
onClicked: Qt.openUrlExternally(missingPackageReadMoreUrl)
|
||||
}
|
||||
}
|
||||
|
||||
ManageButton
|
||||
{
|
||||
id: enableManageButton
|
||||
visible: showDisableButton && packageData.isInstalled && !packageData.isToBeInstalled && packageData.packageType != "material"
|
||||
visible: showDisableButton && packageData.isInstalled && !packageData.isToBeInstalled && packageData.packageType != "material" && !packageData.isMissingPackageInformation
|
||||
enabled: !packageData.busy
|
||||
|
||||
button_style: !packageData.isActive
|
||||
@ -199,7 +231,7 @@ Item
|
||||
ManageButton
|
||||
{
|
||||
id: installManageButton
|
||||
visible: showInstallButton && (packageData.canDowngrade || !packageData.isBundled)
|
||||
visible: showInstallButton && (packageData.canDowngrade || !packageData.isBundled) && !packageData.isMissingPackageInformation
|
||||
enabled: !packageData.busy
|
||||
busy: packageData.busy
|
||||
button_style: !(packageData.isInstalled || packageData.isToBeInstalled)
|
||||
@ -229,7 +261,7 @@ Item
|
||||
ManageButton
|
||||
{
|
||||
id: updateManageButton
|
||||
visible: showUpdateButton && packageData.canUpdate
|
||||
visible: showUpdateButton && packageData.canUpdate && !packageData.isMissingPackageInformation
|
||||
enabled: !packageData.busy
|
||||
busy: packageData.busy
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
@ -62,8 +62,11 @@ ListView
|
||||
hoverEnabled: true
|
||||
onClicked:
|
||||
{
|
||||
packages.selectedPackage = model.package;
|
||||
contextStack.push(packageDetailsComponent);
|
||||
if (!model.package.isMissingPackageInformation)
|
||||
{
|
||||
packages.selectedPackage = model.package;
|
||||
contextStack.push(packageDetailsComponent);
|
||||
}
|
||||
}
|
||||
|
||||
PackageCard
|
||||
|
@ -122,6 +122,7 @@ Rectangle
|
||||
}
|
||||
visible: !isNetworkConfigured && isNetworkConfigurable
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
|
||||
UM.ColorImage
|
||||
{
|
||||
|
@ -169,7 +169,10 @@ class ClusterApiClient:
|
||||
"""
|
||||
|
||||
def parse() -> None:
|
||||
self._anti_gc_callbacks.remove(parse)
|
||||
try:
|
||||
self._anti_gc_callbacks.remove(parse)
|
||||
except ValueError: # Already removed asynchronously.
|
||||
return # Then the rest of the function is also already executed.
|
||||
|
||||
# Don't try to parse the reply if we didn't get one
|
||||
if reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute) is None:
|
||||
|
@ -343,6 +343,9 @@ class XmlMaterialProfile(InstanceContainer):
|
||||
|
||||
return stream.getvalue().decode("utf-8")
|
||||
|
||||
def getFileName(self) -> str:
|
||||
return (self.getMetaDataEntry("base_file") + ".xml.fdm_material").replace(" ", "+")
|
||||
|
||||
# Recursively resolve loading inherited files
|
||||
def _resolveInheritance(self, file_name):
|
||||
xml = self._loadFile(file_name)
|
||||
@ -477,6 +480,15 @@ class XmlMaterialProfile(InstanceContainer):
|
||||
|
||||
return version * 1000000 + setting_version
|
||||
|
||||
@classmethod
|
||||
def getMetadataFromSerialized(cls, serialized: str, property_name: str) -> str:
|
||||
data = ET.fromstring(serialized)
|
||||
metadata = data.find("./um:metadata", cls.__namespaces)
|
||||
property = metadata.find("./um:" + property_name, cls.__namespaces)
|
||||
|
||||
# This is a necessary property != None check, xml library overrides __bool__ to return False in cases when Element is not None.
|
||||
return property.text if property != None else ""
|
||||
|
||||
def deserialize(self, serialized, file_name = None):
|
||||
"""Overridden from InstanceContainer"""
|
||||
|
||||
|
@ -44,7 +44,6 @@
|
||||
"machine_max_jerk_xy": { "value": 8 },
|
||||
"machine_max_jerk_z": { "value": 0.4 },
|
||||
"machine_max_jerk_e": { "value": 5 },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"infill_overlap": { "default_value": 15 },
|
||||
"acceleration_print": { "value": 500 },
|
||||
|
@ -2256,7 +2256,7 @@
|
||||
"maximum_value": "machine_height",
|
||||
"maximum_value_warning": "resolveOrValue('infill_sparse_thickness') * 10",
|
||||
"type": "float",
|
||||
"value": "0 if infill_sparse_density > 0 else 0",
|
||||
"value": "0",
|
||||
"limit_to_extruder": "infill_extruder_nr",
|
||||
"enabled": "infill_sparse_density > 0",
|
||||
"settable_per_mesh": true,
|
||||
|
@ -50,23 +50,29 @@
|
||||
"wall_thickness": {
|
||||
"value": "wall_line_width_0 + wall_line_width_x"
|
||||
},
|
||||
"infill_before_walls": {
|
||||
"value": "False"
|
||||
},
|
||||
"infill_material_flow": {
|
||||
"value": "(1.95-infill_sparse_density / 100 if infill_sparse_density > 95 else 1) * material_flow"
|
||||
},
|
||||
"retraction_combing": {
|
||||
"value": "'no_outer_surfaces'"
|
||||
},
|
||||
"retraction_count_max": {
|
||||
"value": 25
|
||||
},
|
||||
"retraction_extrusion_window": {
|
||||
"value": 1
|
||||
},
|
||||
"roofing_layer_count": {
|
||||
"value": "0"
|
||||
"value": "1"
|
||||
},
|
||||
"roofing_material_flow": {
|
||||
"value": "material_flow"
|
||||
},
|
||||
"skin_material_flow": {
|
||||
"value": "0.97 * material_flow"
|
||||
"value": "0.95 * material_flow"
|
||||
},
|
||||
"support_interface_material_flow": {
|
||||
"value": "skin_material_flow"
|
||||
},
|
||||
"skin_monotonic" : {
|
||||
"value": true
|
||||
@ -89,11 +95,124 @@
|
||||
"meshfix_maximum_deviation": {
|
||||
"value": "machine_nozzle_size / 10"
|
||||
},
|
||||
"jerk_travel": {
|
||||
"value": "jerk_print"
|
||||
"jerk_travel_enabled": {
|
||||
"value": false
|
||||
},
|
||||
"acceleration_travel_enabled": {
|
||||
"value": false
|
||||
},
|
||||
"acceleration_travel": {
|
||||
"value": "acceleration_wall"
|
||||
},
|
||||
"skin_edge_support_thickness": {
|
||||
"value": "4 * layer_height if infill_sparse_density < 30 else 0"
|
||||
},
|
||||
"bridge_settings_enabled": {
|
||||
"value": false
|
||||
},
|
||||
"bridge_wall_min_length": {
|
||||
"value": 0
|
||||
},
|
||||
"bridge_skin_support_threshold": {
|
||||
"value": 50
|
||||
},
|
||||
"bridge_sparse_infill_max_density": {
|
||||
"value": 0
|
||||
},
|
||||
"bridge_wall_coast": {
|
||||
"value": 0
|
||||
},
|
||||
"bridge_wall_speed": {
|
||||
"value": "speed_wall"
|
||||
},
|
||||
"bridge_wall_material_flow": {
|
||||
"value": "wall_material_flow"
|
||||
},
|
||||
"bridge_skin_speed": {
|
||||
"value": "speed_topbottom"
|
||||
},
|
||||
"bridge_skin_material_flow": {
|
||||
"value": "skin_material_flow"
|
||||
},
|
||||
"bridge_skin_density": {
|
||||
"value": "80"
|
||||
},
|
||||
"bridge_fan_speed": {
|
||||
"value": "cool_fan_speed_max"
|
||||
},
|
||||
"bridge_enable_more_layers": {
|
||||
"value": false
|
||||
},
|
||||
"bridge_skin_speed_2": {
|
||||
"value": "speed_topbottom"
|
||||
},
|
||||
"bridge_skin_material_flow_2": {
|
||||
"value": "skin_material_flow"
|
||||
},
|
||||
"bridge_skin_density_2": {
|
||||
"value": 100
|
||||
},
|
||||
"bridge_fan_speed_2": {
|
||||
"value": "cool_fan_speed_min"
|
||||
},
|
||||
"bridge_skin_speed_3": {
|
||||
"value": "speed_topbottom"
|
||||
},
|
||||
"bridge_skin_material_flow_3": {
|
||||
"value": "skin_material_flow"
|
||||
},
|
||||
"bridge_skin_density_3": {
|
||||
"value": 100
|
||||
},
|
||||
"bridge_fan_speed_3": {
|
||||
"value": "cool_fan_speed_min"
|
||||
},
|
||||
"jerk_print": {
|
||||
"value": "20",
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_infill": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_wall": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_wall_0": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_roofing": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_topbottom": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_support": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_support_infill": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_support_interface": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_prime_tower": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_layer_0": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_print_layer_0": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_travel": {
|
||||
"value": "jerk_print",
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_travel_layer_0": {
|
||||
"minimum_value_warning": 20
|
||||
},
|
||||
"jerk_skirt_brim": {
|
||||
"minimum_value_warning": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,20 +101,6 @@
|
||||
"infill_wipe_dist": { "value": "0" },
|
||||
"initial_layer_line_width_factor": { "value": "120" },
|
||||
"jerk_enabled": { "value": "True" },
|
||||
"jerk_print": { "value": "20", "minimum_value_warning": 20 },
|
||||
"jerk_infill": {"minimum_value_warning": 20 },
|
||||
"jerk_wall": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_wall_0": { "value": "jerk_wall", "minimum_value_warning": 20 },
|
||||
"jerk_roofing": {"minimum_value_warning": 20 },
|
||||
"jerk_topbottom": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_support": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_support_infill": {"minimum_value_warning": 20 },
|
||||
"jerk_support_interface": { "value": "math.ceil(jerk_print * 5 / 20)"},
|
||||
"jerk_prime_tower": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_layer_0": { "value": "jerk_topbottom", "minimum_value_warning": 20},
|
||||
"jerk_print_layer_0": {"minimum_value_warning": 20 },
|
||||
"jerk_travel_layer_0": {"minimum_value_warning": 20 },
|
||||
"jerk_skirt_brim": {"minimum_value_warning": 20 },
|
||||
"layer_height_0": { "value": "round(machine_nozzle_size / 1.5, 2)" },
|
||||
"layer_start_x": { "value": "sum(extruderValues('machine_extruder_start_pos_x')) / len(extruderValues('machine_extruder_start_pos_x'))" },
|
||||
"layer_start_y": { "value": "sum(extruderValues('machine_extruder_start_pos_y')) / len(extruderValues('machine_extruder_start_pos_y'))" },
|
||||
@ -136,8 +122,6 @@
|
||||
"raft_margin": { "value": "10" },
|
||||
"raft_surface_layers": { "value": "1" },
|
||||
"retraction_amount": { "value": "6.5" },
|
||||
"retraction_count_max": { "value": "10" },
|
||||
"retraction_extrusion_window": { "value": "1" },
|
||||
"retraction_hop": { "value": "2" },
|
||||
"retraction_hop_enabled": { "value": "extruders_enabled_count > 1" },
|
||||
"retraction_hop_only_when_collides": { "value": "True" },
|
||||
|
@ -93,20 +93,6 @@
|
||||
"infill_pattern": { "value": "'zigzag' if infill_sparse_density > 80 else 'triangles'" },
|
||||
"infill_wipe_dist": { "value": "0" },
|
||||
"jerk_enabled": { "value": "True" },
|
||||
"jerk_print": { "value": "20", "minimum_value_warning": 20 },
|
||||
"jerk_infill": {"minimum_value_warning": 20 },
|
||||
"jerk_wall": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_wall_0": { "value": "jerk_wall", "minimum_value_warning": 20 },
|
||||
"jerk_roofing": {"minimum_value_warning": 20 },
|
||||
"jerk_topbottom": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_support": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_support_infill": {"minimum_value_warning": 20 },
|
||||
"jerk_support_interface": { "value": "math.ceil(jerk_print * 5 / 20)"},
|
||||
"jerk_prime_tower": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_layer_0": { "value": "jerk_topbottom", "minimum_value_warning": 20},
|
||||
"jerk_print_layer_0": {"minimum_value_warning": 20 },
|
||||
"jerk_travel_layer_0": {"minimum_value_warning": 20 },
|
||||
"jerk_skirt_brim": {"minimum_value_warning": 20 },
|
||||
"layer_height_0": { "value": "round(machine_nozzle_size / 1.5, 2)" },
|
||||
"layer_start_x": { "value": "sum(extruderValues('machine_extruder_start_pos_x')) / len(extruderValues('machine_extruder_start_pos_x'))" },
|
||||
"layer_start_y": { "value": "sum(extruderValues('machine_extruder_start_pos_y')) / len(extruderValues('machine_extruder_start_pos_y'))" },
|
||||
@ -128,8 +114,6 @@
|
||||
"raft_speed": { "value": "25" },
|
||||
"raft_surface_layers": { "value": "1" },
|
||||
"retraction_amount": { "value": "6.5" },
|
||||
"retraction_count_max": { "value": "10" },
|
||||
"retraction_extrusion_window": { "value": "1" },
|
||||
"retraction_hop": { "value": "2" },
|
||||
"retraction_hop_enabled": { "value": "extruders_enabled_count > 1" },
|
||||
"retraction_hop_only_when_collides": { "value": "True" },
|
||||
@ -155,7 +139,6 @@
|
||||
"switch_extruder_prime_speed": { "value": "15" },
|
||||
"switch_extruder_retraction_amount": { "value": "8" },
|
||||
"top_bottom_thickness": { "value": "1" },
|
||||
"travel_avoid_supports": { "value": "True" },
|
||||
"travel_avoid_distance": { "value": "3 if extruders_enabled_count > 1 else machine_nozzle_tip_outer_diameter / 2 * 1.5" },
|
||||
"wall_0_inset": { "value": "0" },
|
||||
"initial_layer_line_width_factor": { "value": "120" },
|
||||
|
@ -95,20 +95,6 @@
|
||||
"infill_pattern": { "value": "'zigzag' if infill_sparse_density > 80 else 'triangles'" },
|
||||
"infill_wipe_dist": { "value": "0" },
|
||||
"jerk_enabled": { "value": "True" },
|
||||
"jerk_print": { "value": "20", "minimum_value_warning": 20 },
|
||||
"jerk_infill": {"minimum_value_warning": 20 },
|
||||
"jerk_wall": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_wall_0": { "value": "jerk_wall", "minimum_value_warning": 20 },
|
||||
"jerk_roofing": {"minimum_value_warning": 20 },
|
||||
"jerk_topbottom": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_support": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_support_infill": {"minimum_value_warning": 20 },
|
||||
"jerk_support_interface": { "value": "math.ceil(jerk_print * 5 / 20)"},
|
||||
"jerk_prime_tower": { "value": "jerk_print", "minimum_value_warning": 20 },
|
||||
"jerk_layer_0": { "value": "jerk_topbottom", "minimum_value_warning": 20},
|
||||
"jerk_print_layer_0": {"minimum_value_warning": 20 },
|
||||
"jerk_travel_layer_0": {"minimum_value_warning": 20 },
|
||||
"jerk_skirt_brim": {"minimum_value_warning": 20 },
|
||||
"layer_height_0": { "value": "round(machine_nozzle_size / 1.5, 2)" },
|
||||
"layer_start_x": { "value": "sum(extruderValues('machine_extruder_start_pos_x')) / len(extruderValues('machine_extruder_start_pos_x'))" },
|
||||
"layer_start_y": { "value": "sum(extruderValues('machine_extruder_start_pos_y')) / len(extruderValues('machine_extruder_start_pos_y'))" },
|
||||
@ -130,8 +116,6 @@
|
||||
"raft_surface_layers": { "value": "1" },
|
||||
"retraction_amount": { "value": "6.5" },
|
||||
"retraction_combing": { "value": "'no_outer_surfaces'"},
|
||||
"retraction_count_max": { "value": "10" },
|
||||
"retraction_extrusion_window": { "value": "1" },
|
||||
"retraction_hop": { "value": "2" },
|
||||
"retraction_hop_enabled": { "value": "extruders_enabled_count > 1" },
|
||||
"retraction_hop_only_when_collides": { "value": "True" },
|
||||
@ -157,7 +141,6 @@
|
||||
"switch_extruder_prime_speed": { "value": "15" },
|
||||
"switch_extruder_retraction_amount": { "value": "8" },
|
||||
"top_bottom_thickness": { "value": "1" },
|
||||
"travel_avoid_supports": { "value": "True" },
|
||||
"travel_avoid_distance": { "value": "3 if extruders_enabled_count > 1 else machine_nozzle_tip_outer_diameter / 2 * 1.5" },
|
||||
"wall_0_inset": { "value": "0" },
|
||||
"optimize_wall_printing_order": { "value": "True" },
|
||||
|
@ -138,7 +138,6 @@
|
||||
"machine_height": {"default_value": 250},
|
||||
"machine_extruder_count": {"value": 2},
|
||||
"machine_buildplate_type": {"value": "glass"},
|
||||
"machine_heated_bed": {"default_value": true},
|
||||
"machine_center_is_zero": {"default_value": false},
|
||||
"machine_gcode_flavor": {"default_value": "RepRap (Marlin/Sprinter)"},
|
||||
"machine_head_with_fans_polygon": {"default_value": [
|
||||
|
@ -98,8 +98,9 @@
|
||||
"machine_start_gcode": { "default_value": "print_start" },
|
||||
"machine_end_gcode": { "default_value": "print_end" },
|
||||
"adhesion_type": { "default_value": "skirt" },
|
||||
"retraction_amount": { "default_value": 0.75 },
|
||||
"skirt_brim_minimal_length": { "default_value": 550 },
|
||||
"retraction_speed": { "default_value": 80, "maximum_value_warning": 130 },
|
||||
"retraction_speed": { "default_value": 30, "maximum_value_warning": 130 },
|
||||
"retraction_retract_speed": { "maximum_value_warning": 130 },
|
||||
"retraction_prime_speed": { "value": "math.ceil(retraction_speed * 0.4)", "maximum_value_warning": 130 },
|
||||
"retraction_hop_enabled": { "default_value": true },
|
||||
|
@ -147,7 +147,6 @@
|
||||
"machine_height": {"default_value": 270},
|
||||
"machine_extruder_count": {"value": 1},
|
||||
"machine_buildplate_type": {"value": "glass"},
|
||||
"machine_heated_bed": {"default_value": true},
|
||||
"machine_center_is_zero": {"default_value": false},
|
||||
"machine_gcode_flavor": {"default_value": "RepRap (Marlin/Sprinter)"},
|
||||
"machine_head_with_fans_polygon": {"default_value": [
|
||||
|
@ -22,11 +22,6 @@ top_bottom_thickness = 0.8
|
||||
infill_sparse_density = 15
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
|
||||
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -16,12 +16,6 @@ is_experimental = True
|
||||
infill_sparse_density = 10
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
acceleration_print = 4000
|
||||
acceleration_wall = 2000
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -22,11 +22,6 @@ top_bottom_thickness = 0.8
|
||||
infill_sparse_density = 15
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
|
||||
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -22,11 +22,6 @@ top_bottom_thickness = 0.8
|
||||
infill_sparse_density = 15
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
|
||||
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -16,12 +16,6 @@ is_experimental = True
|
||||
infill_sparse_density = 10
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
acceleration_print = 4000
|
||||
acceleration_wall = 2000
|
||||
|
@ -22,11 +22,6 @@ top_bottom_thickness = 0.8
|
||||
infill_sparse_density = 15
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
|
||||
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -14,12 +14,6 @@ variant = AA 0.4
|
||||
[values]
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
speed_print = 30
|
||||
speed_infill = =speed_print
|
||||
|
@ -16,12 +16,6 @@ is_experimental = True
|
||||
infill_sparse_density = 10
|
||||
|
||||
jerk_print = 30
|
||||
jerk_infill = =jerk_print
|
||||
jerk_topbottom = =jerk_print
|
||||
jerk_wall = =jerk_print
|
||||
jerk_wall_0 = =jerk_wall
|
||||
jerk_wall_x = =jerk_wall
|
||||
jerk_layer_0 = 5
|
||||
|
||||
acceleration_print = 4000
|
||||
acceleration_wall = 2000
|
||||
|
@ -29,7 +29,7 @@ UM.Dialog
|
||||
// the size of the dialog ourselves.
|
||||
// Ugly workaround for windows having overlapping elements due to incorrect dialog width
|
||||
minimumWidth: content.width + (Qt.platform.os == "windows" ? 4 * margin : 2 * margin)
|
||||
minimumHeight: content.height + buttonArea.height + (Qt.platform.os == "windows" ? 5 * margin : 3 * margin)
|
||||
minimumHeight: content.height + footer.height + (Qt.platform.os == "windows" ? 5 * margin : 3 * margin)
|
||||
|
||||
property alias color: colorInput.text
|
||||
property var swatchColors: [
|
||||
|
@ -67,6 +67,8 @@ UM.TooltipArea
|
||||
font: UM.Theme.getFont("fixed")
|
||||
renderType: Text.NativeRendering
|
||||
color: UM.Theme.getColor("text")
|
||||
selectionColor: UM.Theme.getColor("text_selection")
|
||||
selectedTextColor: UM.Theme.getColor("text")
|
||||
wrapMode: TextEdit.NoWrap
|
||||
|
||||
onActiveFocusChanged:
|
||||
@ -91,7 +93,7 @@ UM.TooltipArea
|
||||
}
|
||||
if (gcodeTextArea.hovered || gcodeTextArea.activeFocus)
|
||||
{
|
||||
return UM.Theme.getColor("border_main")
|
||||
return UM.Theme.getColor("text_field_border_active")
|
||||
}
|
||||
return UM.Theme.getColor("border_field_light")
|
||||
}
|
||||
|
@ -39,8 +39,7 @@ jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -29,18 +29,8 @@ cool_min_speed = 20
|
||||
infill_overlap = 0
|
||||
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'cubic'
|
||||
infill_wipe_dist = 0
|
||||
jerk_enabled = True
|
||||
jerk_layer_0 = =jerk_topbottom
|
||||
jerk_prime_tower = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_print = 25
|
||||
jerk_support = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_support_interface = =jerk_topbottom
|
||||
jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -29,18 +29,8 @@ cool_min_speed = 20
|
||||
infill_overlap = 0
|
||||
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'cubic'
|
||||
infill_wipe_dist = 0
|
||||
jerk_enabled = True
|
||||
jerk_layer_0 = =jerk_topbottom
|
||||
jerk_prime_tower = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_print = 25
|
||||
jerk_support = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_support_interface = =jerk_topbottom
|
||||
jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -39,8 +39,7 @@ jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -29,18 +29,8 @@ cool_min_speed = 20
|
||||
infill_overlap = 0
|
||||
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'cubic'
|
||||
infill_wipe_dist = 0
|
||||
jerk_enabled = True
|
||||
jerk_layer_0 = =jerk_topbottom
|
||||
jerk_prime_tower = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_print = 25
|
||||
jerk_support = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_support_interface = =jerk_topbottom
|
||||
jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -39,8 +39,7 @@ jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -25,6 +25,7 @@ raft_base_line_spacing = 1
|
||||
raft_interface_line_spacing = 1
|
||||
raft_interface_line_width = 0.2
|
||||
raft_surface_line_width = 0.2
|
||||
retraction_count_max = 15
|
||||
retraction_hop_enabled = 0.2
|
||||
speed_layer_0 = =math.ceil(speed_print * 30 / 40)
|
||||
speed_print = 40
|
||||
|
@ -23,6 +23,7 @@ raft_base_line_spacing = 2
|
||||
raft_base_line_width = 0.8
|
||||
raft_interface_line_spacing = 1
|
||||
raft_margin = 12
|
||||
retraction_count_max = 15
|
||||
retraction_hop_enabled = 0.2
|
||||
speed_layer_0 = =math.ceil(speed_print * 30 / 40)
|
||||
speed_print = 40
|
||||
|
@ -26,6 +26,7 @@ raft_interface_line_spacing = 1.2
|
||||
raft_interface_line_width = 0.57
|
||||
raft_margin = 15
|
||||
raft_surface_line_width = 0.5
|
||||
retraction_count_max = 15
|
||||
retraction_hop_enabled = 0.2
|
||||
speed_layer_0 = =math.ceil(speed_print * 30 / 45)
|
||||
speed_print = 45
|
||||
|
@ -29,18 +29,8 @@ cool_min_speed = 20
|
||||
infill_overlap = 0
|
||||
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'tetrahedral'
|
||||
infill_wipe_dist = 0
|
||||
jerk_enabled = True
|
||||
jerk_layer_0 = =jerk_topbottom
|
||||
jerk_prime_tower = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_print = 25
|
||||
jerk_support = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_support_interface = =jerk_topbottom
|
||||
jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -29,18 +29,8 @@ cool_min_speed = 20
|
||||
infill_overlap = 0
|
||||
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'tetrahedral'
|
||||
infill_wipe_dist = 0
|
||||
jerk_enabled = True
|
||||
jerk_layer_0 = =jerk_topbottom
|
||||
jerk_prime_tower = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_print = 25
|
||||
jerk_support = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_support_interface = =jerk_topbottom
|
||||
jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -29,18 +29,8 @@ cool_min_speed = 20
|
||||
infill_overlap = 0
|
||||
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'tetrahedral'
|
||||
infill_wipe_dist = 0
|
||||
jerk_enabled = True
|
||||
jerk_layer_0 = =jerk_topbottom
|
||||
jerk_prime_tower = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_print = 25
|
||||
jerk_support = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_support_interface = =jerk_topbottom
|
||||
jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -29,18 +29,8 @@ cool_min_speed = 20
|
||||
infill_overlap = 0
|
||||
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'tetrahedral'
|
||||
infill_wipe_dist = 0
|
||||
jerk_enabled = True
|
||||
jerk_layer_0 = =jerk_topbottom
|
||||
jerk_prime_tower = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_print = 25
|
||||
jerk_support = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_support_interface = =jerk_topbottom
|
||||
jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -39,8 +39,7 @@ jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -29,18 +29,8 @@ cool_min_speed = 20
|
||||
infill_overlap = 0
|
||||
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'tetrahedral'
|
||||
infill_wipe_dist = 0
|
||||
jerk_enabled = True
|
||||
jerk_layer_0 = =jerk_topbottom
|
||||
jerk_prime_tower = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_print = 25
|
||||
jerk_support = =math.ceil(jerk_print * 15 / 25)
|
||||
jerk_support_interface = =jerk_topbottom
|
||||
jerk_topbottom = =math.ceil(jerk_print * 5 / 25)
|
||||
jerk_wall = =math.ceil(jerk_print * 10 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 5 / 10)
|
||||
multiple_mesh_overlap = 0
|
||||
retraction_count_max = 12
|
||||
retraction_extrusion_window = 1
|
||||
retraction_count_max = 15
|
||||
retraction_hop = 0.15
|
||||
retraction_hop_enabled = True
|
||||
retraction_hop_only_when_collides = True
|
||||
|
@ -25,6 +25,7 @@ raft_base_line_spacing = 1
|
||||
raft_interface_line_spacing = 1
|
||||
raft_interface_line_width = 0.2
|
||||
raft_surface_line_width = 0.2
|
||||
retraction_count_max = 15
|
||||
retraction_hop_enabled = 0.2
|
||||
speed_layer_0 = =math.ceil(speed_print * 30 / 40)
|
||||
speed_print = 40
|
||||
|
@ -23,6 +23,7 @@ raft_base_line_spacing = 2
|
||||
raft_base_line_width = 0.8
|
||||
raft_interface_line_spacing = 1
|
||||
raft_margin = 12
|
||||
retraction_count_max = 15
|
||||
retraction_hop_enabled = 0.2
|
||||
speed_layer_0 = =math.ceil(speed_print * 30 / 40)
|
||||
speed_print = 40
|
||||
|
@ -26,6 +26,7 @@ raft_interface_line_spacing = 1.2
|
||||
raft_interface_line_width = 0.57
|
||||
raft_margin = 15
|
||||
raft_surface_line_width = 0.5
|
||||
retraction_count_max = 15
|
||||
retraction_hop_enabled = 0.2
|
||||
speed_layer_0 = =math.ceil(speed_print * 30 / 45)
|
||||
speed_print = 45
|
||||
|
@ -12,7 +12,6 @@ material = generic_cpe
|
||||
variant = AA 0.25
|
||||
|
||||
[values]
|
||||
retraction_extrusion_window = 0.5
|
||||
speed_infill = =math.ceil(speed_print * 40 / 55)
|
||||
speed_topbottom = =math.ceil(speed_print * 30 / 55)
|
||||
top_bottom_thickness = 0.8
|
||||
|
@ -21,7 +21,6 @@ cool_min_layer_time_fan_speed_max = 5
|
||||
cool_min_speed = 5
|
||||
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
|
||||
infill_wipe_dist = 0.1
|
||||
jerk_enabled = True
|
||||
jerk_print = 25
|
||||
machine_min_cool_heat_time_window = 15
|
||||
multiple_mesh_overlap = 0
|
||||
@ -30,7 +29,6 @@ prime_tower_enable = True
|
||||
prime_tower_wipe_enabled = True
|
||||
raft_airgap = 0.25
|
||||
raft_interface_thickness = =max(layer_height * 1.5, 0.225)
|
||||
retraction_count_max = 80
|
||||
retraction_hop = 2
|
||||
retraction_hop_only_when_collides = True
|
||||
retraction_min_travel = 0.8
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user