mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-07 06:57:28 -06:00
Merge branch 'master' of https://github.com/Ultimaker/Cura
This commit is contained in:
commit
155408d77d
25 changed files with 751 additions and 170 deletions
|
@ -28,11 +28,12 @@ class CuraAPI(QObject):
|
||||||
# The main reason for this is that we want to prevent consumers of API to have a dependency on CuraApplication.
|
# The main reason for this is that we want to prevent consumers of API to have a dependency on CuraApplication.
|
||||||
# Since the API is intended to be used by plugins, the cura application should have already created this.
|
# Since the API is intended to be used by plugins, the cura application should have already created this.
|
||||||
def __new__(cls, application: Optional["CuraApplication"] = None):
|
def __new__(cls, application: Optional["CuraApplication"] = None):
|
||||||
if cls.__instance is None:
|
if cls.__instance is not None:
|
||||||
if application is None:
|
raise RuntimeError("Tried to create singleton '{class_name}' more than once.".format(class_name = CuraAPI.__name__))
|
||||||
raise Exception("Upon first time creation, the application must be set.")
|
if application is None:
|
||||||
cls.__instance = super(CuraAPI, cls).__new__(cls)
|
raise RuntimeError("Upon first time creation, the application must be set.")
|
||||||
cls._application = application
|
cls.__instance = super(CuraAPI, cls).__new__(cls)
|
||||||
|
cls._application = application
|
||||||
return cls.__instance
|
return cls.__instance
|
||||||
|
|
||||||
def __init__(self, application: Optional["CuraApplication"] = None) -> None:
|
def __init__(self, application: Optional["CuraApplication"] = None) -> None:
|
||||||
|
|
|
@ -747,6 +747,11 @@ class MachineManager(QObject):
|
||||||
result = [] # type: List[str]
|
result = [] # type: List[str]
|
||||||
for setting_instance in container.findInstances():
|
for setting_instance in container.findInstances():
|
||||||
setting_key = setting_instance.definition.key
|
setting_key = setting_instance.definition.key
|
||||||
|
if setting_key == "print_sequence":
|
||||||
|
old_value = container.getProperty(setting_key, "value")
|
||||||
|
Logger.log("d", "Reset setting [%s] in [%s] because its old value [%s] is no longer valid", setting_key, container, old_value)
|
||||||
|
result.append(setting_key)
|
||||||
|
continue
|
||||||
if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
|
if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,13 @@ parser.add_argument("--debug",
|
||||||
known_args = vars(parser.parse_known_args()[0])
|
known_args = vars(parser.parse_known_args()[0])
|
||||||
|
|
||||||
if with_sentry_sdk:
|
if with_sentry_sdk:
|
||||||
sentry_env = "production"
|
sentry_env = "unknown" # Start off with a "IDK"
|
||||||
if ApplicationMetadata.CuraVersion == "master":
|
if hasattr(sys, "frozen"):
|
||||||
|
sentry_env = "production" # A frozen build is a "real" distribution.
|
||||||
|
elif ApplicationMetadata.CuraVersion == "master":
|
||||||
sentry_env = "development"
|
sentry_env = "development"
|
||||||
|
elif "beta" in ApplicationMetadata.CuraVersion or "BETA" in ApplicationMetadata.CuraVersion:
|
||||||
|
sentry_env = "beta"
|
||||||
try:
|
try:
|
||||||
if ApplicationMetadata.CuraVersion.split(".")[2] == "99":
|
if ApplicationMetadata.CuraVersion.split(".")[2] == "99":
|
||||||
sentry_env = "nightly"
|
sentry_env = "nightly"
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
import zipfile
|
import zipfile
|
||||||
import os
|
import os
|
||||||
from typing import cast, Dict, List, Optional, Tuple
|
import json
|
||||||
|
from typing import cast, Dict, List, Optional, Tuple, Any
|
||||||
|
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
@ -732,7 +733,25 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
|
|
||||||
base_file_name = os.path.basename(file_name)
|
base_file_name = os.path.basename(file_name)
|
||||||
self.setWorkspaceName(base_file_name)
|
self.setWorkspaceName(base_file_name)
|
||||||
return nodes
|
|
||||||
|
return nodes, self._loadMetadata(file_name)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _loadMetadata(file_name: str) -> Dict[str, Dict[str, Any]]:
|
||||||
|
archive = zipfile.ZipFile(file_name, "r")
|
||||||
|
|
||||||
|
metadata_files = [name for name in archive.namelist() if name.endswith("plugin_metadata.json")]
|
||||||
|
|
||||||
|
result = dict()
|
||||||
|
|
||||||
|
for metadata_file in metadata_files:
|
||||||
|
try:
|
||||||
|
plugin_id = metadata_file.split("/")[0]
|
||||||
|
result[plugin_id] = json.loads(archive.open("%s/plugin_metadata.json" % plugin_id).read().decode("utf-8"))
|
||||||
|
except Exception:
|
||||||
|
Logger.logException("w", "Unable to retrieve metadata for %s", metadata_file)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def _processQualityChanges(self, global_stack):
|
def _processQualityChanges(self, global_stack):
|
||||||
if self._machine_info.quality_changes_info is None:
|
if self._machine_info.quality_changes_info is None:
|
||||||
|
|
|
@ -73,11 +73,25 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
||||||
version_config_parser.write(version_file_string)
|
version_config_parser.write(version_file_string)
|
||||||
archive.writestr(version_file, version_file_string.getvalue())
|
archive.writestr(version_file, version_file_string.getvalue())
|
||||||
|
|
||||||
|
self._writePluginMetadataToArchive(archive)
|
||||||
|
|
||||||
# Close the archive & reset states.
|
# Close the archive & reset states.
|
||||||
archive.close()
|
archive.close()
|
||||||
mesh_writer.setStoreArchive(False)
|
mesh_writer.setStoreArchive(False)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _writePluginMetadataToArchive(archive: zipfile.ZipFile) -> None:
|
||||||
|
file_name_template = "%s/plugin_metadata.json"
|
||||||
|
|
||||||
|
for plugin_id, metadata in Application.getInstance().getWorkspaceMetadataStorage().getAllData().items():
|
||||||
|
file_name = file_name_template % plugin_id
|
||||||
|
file_in_archive = zipfile.ZipInfo(file_name)
|
||||||
|
# We have to set the compress type of each file as well (it doesn't keep the type of the entire archive)
|
||||||
|
file_in_archive.compress_type = zipfile.ZIP_DEFLATED
|
||||||
|
import json
|
||||||
|
archive.writestr(file_in_archive, json.dumps(metadata, separators = (", ", ": "), indent = 4, skipkeys = True))
|
||||||
|
|
||||||
## Helper function that writes ContainerStacks, InstanceContainers and DefinitionContainers to the archive.
|
## Helper function that writes ContainerStacks, InstanceContainers and DefinitionContainers to the archive.
|
||||||
# \param container That follows the \type{ContainerInterface} to archive.
|
# \param container That follows the \type{ContainerInterface} to archive.
|
||||||
# \param archive The archive to write to.
|
# \param archive The archive to write to.
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# Copyright (c) 2015 Ultimaker B.V.
|
# Copyright (c) 2015 Ultimaker B.V.
|
||||||
# Uranium is released under the terms of the LGPLv3 or higher.
|
# Uranium is released under the terms of the LGPLv3 or higher.
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from UM.Mesh.MeshWriter import MeshWriter
|
from UM.Mesh.MeshWriter import MeshWriter
|
||||||
from UM.Math.Vector import Vector
|
from UM.Math.Vector import Vector
|
||||||
|
@ -40,7 +41,7 @@ class ThreeMFWriter(MeshWriter):
|
||||||
}
|
}
|
||||||
|
|
||||||
self._unit_matrix_string = self._convertMatrixToString(Matrix())
|
self._unit_matrix_string = self._convertMatrixToString(Matrix())
|
||||||
self._archive = None
|
self._archive = None # type: Optional[zipfile.ZipFile]
|
||||||
self._store_archive = False
|
self._store_archive = False
|
||||||
|
|
||||||
def _convertMatrixToString(self, matrix):
|
def _convertMatrixToString(self, matrix):
|
||||||
|
|
|
@ -72,18 +72,25 @@ class DisplayFilenameAndLayerOnLCD(Script):
|
||||||
lcd_text = "M117 Printing " + name + " - Layer "
|
lcd_text = "M117 Printing " + name + " - Layer "
|
||||||
i = self.getSettingValueByKey("startNum")
|
i = self.getSettingValueByKey("startNum")
|
||||||
for layer in data:
|
for layer in data:
|
||||||
display_text = lcd_text + str(i) + " " + name
|
display_text = lcd_text + str(i)
|
||||||
layer_index = data.index(layer)
|
layer_index = data.index(layer)
|
||||||
lines = layer.split("\n")
|
lines = layer.split("\n")
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if line.startswith(";LAYER_COUNT:"):
|
if line.startswith(";LAYER_COUNT:"):
|
||||||
max_layer = line
|
max_layer = line
|
||||||
max_layer = max_layer.split(":")[1]
|
max_layer = max_layer.split(":")[1]
|
||||||
|
if self.getSettingValueByKey("startNum") == 0:
|
||||||
|
max_layer = str(int(max_layer) - 1)
|
||||||
if line.startswith(";LAYER:"):
|
if line.startswith(";LAYER:"):
|
||||||
if self.getSettingValueByKey("maxlayer"):
|
if self.getSettingValueByKey("maxlayer"):
|
||||||
display_text = display_text + " of " + max_layer
|
display_text = display_text + " of " + max_layer
|
||||||
|
if not self.getSettingValueByKey("scroll"):
|
||||||
|
display_text = display_text + " " + name
|
||||||
else:
|
else:
|
||||||
display_text = display_text + "!"
|
if not self.getSettingValueByKey("scroll"):
|
||||||
|
display_text = display_text + " " + name + "!"
|
||||||
|
else:
|
||||||
|
display_text = display_text + "!"
|
||||||
line_index = lines.index(line)
|
line_index = lines.index(line)
|
||||||
lines.insert(line_index + 1, display_text)
|
lines.insert(line_index + 1, display_text)
|
||||||
i += 1
|
i += 1
|
||||||
|
|
|
@ -20,6 +20,8 @@ UM.Dialog{
|
||||||
maximumHeight: minimumHeight
|
maximumHeight: minimumHeight
|
||||||
margin: 0
|
margin: 0
|
||||||
|
|
||||||
|
property string actionButtonText: subscribedPackagesModel.hasIncompatiblePackages && !subscribedPackagesModel.hasCompatiblePackages ? catalog.i18nc("@button", "Dismiss") : catalog.i18nc("@button", "Next")
|
||||||
|
|
||||||
Rectangle
|
Rectangle
|
||||||
{
|
{
|
||||||
id: root
|
id: root
|
||||||
|
@ -125,26 +127,6 @@ UM.Dialog{
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
UM.TooltipArea
|
|
||||||
{
|
|
||||||
width: childrenRect.width;
|
|
||||||
height: childrenRect.height;
|
|
||||||
text: catalog.i18nc("@info:tooltip", "Dismisses the package and won't be shown in this dialog anymore")
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: packageIcon.verticalCenter
|
|
||||||
Label
|
|
||||||
{
|
|
||||||
text: "(Dismiss)"
|
|
||||||
font: UM.Theme.getFont("small")
|
|
||||||
color: UM.Theme.getColor("text")
|
|
||||||
MouseArea
|
|
||||||
{
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: handler.dismissIncompatiblePackage(subscribedPackagesModel, model.package_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,7 +140,7 @@ UM.Dialog{
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: UM.Theme.getSize("default_margin").height
|
anchors.margins: UM.Theme.getSize("default_margin").height
|
||||||
text: catalog.i18nc("@button", "Next")
|
text: actionButtonText
|
||||||
onClicked: accept()
|
onClicked: accept()
|
||||||
leftPadding: UM.Theme.getSize("dialog_primary_button_padding").width
|
leftPadding: UM.Theme.getSize("dialog_primary_button_padding").width
|
||||||
rightPadding: UM.Theme.getSize("dialog_primary_button_padding").width
|
rightPadding: UM.Theme.getSize("dialog_primary_button_padding").width
|
||||||
|
|
|
@ -5,6 +5,7 @@ import QtQuick 2.10
|
||||||
import QtQuick.Dialogs 1.1
|
import QtQuick.Dialogs 1.1
|
||||||
import QtQuick.Window 2.2
|
import QtQuick.Window 2.2
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
import QtQuick.Controls.Styles 1.4
|
import QtQuick.Controls.Styles 1.4
|
||||||
|
|
||||||
// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles
|
// TODO: Switch to QtQuick.Controls 2.x and remove QtQuick.Controls.Styles
|
||||||
|
@ -20,31 +21,63 @@ UM.Dialog
|
||||||
minimumHeight: UM.Theme.getSize("license_window_minimum").height
|
minimumHeight: UM.Theme.getSize("license_window_minimum").height
|
||||||
width: minimumWidth
|
width: minimumWidth
|
||||||
height: minimumHeight
|
height: minimumHeight
|
||||||
|
backgroundColor: UM.Theme.getColor("main_background")
|
||||||
|
margin: screenScaleFactor * 10
|
||||||
|
|
||||||
Item
|
ColumnLayout
|
||||||
{
|
{
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
spacing: UM.Theme.getSize("thick_margin").height
|
||||||
|
|
||||||
UM.I18nCatalog{id: catalog; name: "cura"}
|
UM.I18nCatalog{id: catalog; name: "cura"}
|
||||||
|
|
||||||
|
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
id: licenseHeader
|
id: licenseHeader
|
||||||
anchors.top: parent.top
|
Layout.fillWidth: true
|
||||||
anchors.left: parent.left
|
text: catalog.i18nc("@label", "You need to accept the license to install the package")
|
||||||
anchors.right: parent.right
|
|
||||||
text: licenseModel.headerText
|
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
renderType: Text.NativeRendering
|
renderType: Text.NativeRendering
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: packageRow
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
height: childrenRect.height
|
||||||
|
spacing: UM.Theme.getSize("default_margin").width
|
||||||
|
leftPadding: UM.Theme.getSize("narrow_margin").width
|
||||||
|
|
||||||
|
Image
|
||||||
|
{
|
||||||
|
id: icon
|
||||||
|
width: 30 * screenScaleFactor
|
||||||
|
height: width
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: licenseModel.iconUrl || "../../images/logobot.svg"
|
||||||
|
mipmap: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Label
|
||||||
|
{
|
||||||
|
id: packageName
|
||||||
|
text: licenseModel.packageName
|
||||||
|
font.bold: true
|
||||||
|
anchors.verticalCenter: icon.verticalCenter
|
||||||
|
height: contentHeight
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
TextArea
|
TextArea
|
||||||
{
|
{
|
||||||
id: licenseText
|
id: licenseText
|
||||||
anchors.top: licenseHeader.bottom
|
Layout.fillWidth: true
|
||||||
anchors.bottom: parent.bottom
|
Layout.fillHeight: true
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||||
readOnly: true
|
readOnly: true
|
||||||
text: licenseModel.licenseText
|
text: licenseModel.licenseText
|
||||||
|
@ -57,7 +90,7 @@ UM.Dialog
|
||||||
leftPadding: UM.Theme.getSize("dialog_primary_button_padding").width
|
leftPadding: UM.Theme.getSize("dialog_primary_button_padding").width
|
||||||
rightPadding: UM.Theme.getSize("dialog_primary_button_padding").width
|
rightPadding: UM.Theme.getSize("dialog_primary_button_padding").width
|
||||||
|
|
||||||
text: catalog.i18nc("@button", "Agree")
|
text: licenseModel.acceptButtonText
|
||||||
onClicked: { handler.onLicenseAccepted() }
|
onClicked: { handler.onLicenseAccepted() }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -67,7 +100,7 @@ UM.Dialog
|
||||||
Cura.SecondaryButton
|
Cura.SecondaryButton
|
||||||
{
|
{
|
||||||
id: declineButton
|
id: declineButton
|
||||||
text: catalog.i18nc("@button", "Decline and remove from account")
|
text: licenseModel.declineButtonText
|
||||||
onClicked: { handler.onLicenseDeclined() }
|
onClicked: { handler.onLicenseDeclined() }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,11 +8,12 @@ from UM import i18nCatalog
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Message import Message
|
from UM.Message import Message
|
||||||
from UM.Signal import Signal
|
from UM.Signal import Signal
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication, ApplicationMetadata
|
||||||
from ..CloudApiModel import CloudApiModel
|
from ..CloudApiModel import CloudApiModel
|
||||||
from .SubscribedPackagesModel import SubscribedPackagesModel
|
from .SubscribedPackagesModel import SubscribedPackagesModel
|
||||||
from ..UltimakerCloudScope import UltimakerCloudScope
|
from ..UltimakerCloudScope import UltimakerCloudScope
|
||||||
|
|
||||||
|
from typing import List, Dict, Any
|
||||||
|
|
||||||
class CloudPackageChecker(QObject):
|
class CloudPackageChecker(QObject):
|
||||||
def __init__(self, application: CuraApplication) -> None:
|
def __init__(self, application: CuraApplication) -> None:
|
||||||
|
@ -25,12 +26,12 @@ class CloudPackageChecker(QObject):
|
||||||
|
|
||||||
self._application.initializationFinished.connect(self._onAppInitialized)
|
self._application.initializationFinished.connect(self._onAppInitialized)
|
||||||
self._i18n_catalog = i18nCatalog("cura")
|
self._i18n_catalog = i18nCatalog("cura")
|
||||||
|
self._sdk_version = ApplicationMetadata.CuraSDKVersion
|
||||||
|
|
||||||
# This is a plugin, so most of the components required are not ready when
|
# This is a plugin, so most of the components required are not ready when
|
||||||
# this is initialized. Therefore, we wait until the application is ready.
|
# this is initialized. Therefore, we wait until the application is ready.
|
||||||
def _onAppInitialized(self) -> None:
|
def _onAppInitialized(self) -> None:
|
||||||
self._package_manager = self._application.getPackageManager()
|
self._package_manager = self._application.getPackageManager()
|
||||||
|
|
||||||
# initial check
|
# initial check
|
||||||
self._fetchUserSubscribedPackages()
|
self._fetchUserSubscribedPackages()
|
||||||
# check again whenever the login state changes
|
# check again whenever the login state changes
|
||||||
|
@ -38,25 +39,51 @@ class CloudPackageChecker(QObject):
|
||||||
|
|
||||||
def _fetchUserSubscribedPackages(self) -> None:
|
def _fetchUserSubscribedPackages(self) -> None:
|
||||||
if self._application.getCuraAPI().account.isLoggedIn:
|
if self._application.getCuraAPI().account.isLoggedIn:
|
||||||
self._getUserPackages()
|
self._getUserSubscribedPackages()
|
||||||
|
|
||||||
def _handleCompatibilityData(self, json_data) -> None:
|
def _getUserSubscribedPackages(self) -> None:
|
||||||
user_subscribed_packages = [plugin["package_id"] for plugin in json_data]
|
Logger.debug("Requesting subscribed packages metadata from server.")
|
||||||
|
url = CloudApiModel.api_url_user_packages
|
||||||
|
self._application.getHttpRequestManager().get(url,
|
||||||
|
callback = self._onUserPackagesRequestFinished,
|
||||||
|
error_callback = self._onUserPackagesRequestFinished,
|
||||||
|
scope = self._scope)
|
||||||
|
|
||||||
|
def _onUserPackagesRequestFinished(self, reply: "QNetworkReply", error: Optional["QNetworkReply.NetworkError"] = None) -> None:
|
||||||
|
if error is not None or reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
|
||||||
|
Logger.log("w",
|
||||||
|
"Requesting user packages failed, response code %s while trying to connect to %s",
|
||||||
|
reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url())
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
json_data = json.loads(bytes(reply.readAll()).decode("utf-8"))
|
||||||
|
# Check for errors:
|
||||||
|
if "errors" in json_data:
|
||||||
|
for error in json_data["errors"]:
|
||||||
|
Logger.log("e", "%s", error["title"])
|
||||||
|
return
|
||||||
|
self._handleCompatibilityData(json_data["data"])
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
|
Logger.log("w", "Received invalid JSON for user subscribed packages from the Web Marketplace")
|
||||||
|
|
||||||
|
def _handleCompatibilityData(self, subscribed_packages_payload: List[Dict[str, Any]]) -> None:
|
||||||
|
user_subscribed_packages = [plugin["package_id"] for plugin in subscribed_packages_payload]
|
||||||
user_installed_packages = self._package_manager.getUserInstalledPackages()
|
user_installed_packages = self._package_manager.getUserInstalledPackages()
|
||||||
|
|
||||||
|
# We need to re-evaluate the dismissed packages
|
||||||
|
# (i.e. some package might got updated to the correct SDK version in the meantime,
|
||||||
|
# hence remove them from the Dismissed Incompatible list)
|
||||||
|
self._package_manager.reEvaluateDismissedPackages(subscribed_packages_payload, self._sdk_version)
|
||||||
user_dismissed_packages = self._package_manager.getDismissedPackages()
|
user_dismissed_packages = self._package_manager.getDismissedPackages()
|
||||||
if user_dismissed_packages:
|
if user_dismissed_packages:
|
||||||
user_installed_packages += user_dismissed_packages
|
user_installed_packages += user_dismissed_packages
|
||||||
# We check if there are packages installed in Cloud Marketplace but not in Cura marketplace
|
|
||||||
|
# We check if there are packages installed in Web Marketplace but not in Cura marketplace
|
||||||
package_discrepancy = list(set(user_subscribed_packages).difference(user_installed_packages))
|
package_discrepancy = list(set(user_subscribed_packages).difference(user_installed_packages))
|
||||||
|
|
||||||
self._model.setMetadata(json_data)
|
|
||||||
self._model.addDiscrepancies(package_discrepancy)
|
|
||||||
self._model.initialize()
|
|
||||||
|
|
||||||
if not self._model.hasCompatiblePackages:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if package_discrepancy:
|
if package_discrepancy:
|
||||||
|
self._model.addDiscrepancies(package_discrepancy)
|
||||||
|
self._model.initialize(subscribed_packages_payload)
|
||||||
self._handlePackageDiscrepancies()
|
self._handlePackageDiscrepancies()
|
||||||
|
|
||||||
def _handlePackageDiscrepancies(self) -> None:
|
def _handlePackageDiscrepancies(self) -> None:
|
||||||
|
@ -76,35 +103,4 @@ class CloudPackageChecker(QObject):
|
||||||
|
|
||||||
def _onSyncButtonClicked(self, sync_message: Message, sync_message_action: str) -> None:
|
def _onSyncButtonClicked(self, sync_message: Message, sync_message_action: str) -> None:
|
||||||
sync_message.hide()
|
sync_message.hide()
|
||||||
self.discrepancies.emit(self._model)
|
self.discrepancies.emit(self._model)
|
||||||
|
|
||||||
def _getUserPackages(self) -> None:
|
|
||||||
Logger.log("d", "Requesting subscribed packages metadata from server.")
|
|
||||||
url = CloudApiModel.api_url_user_packages
|
|
||||||
|
|
||||||
self._application.getHttpRequestManager().get(url,
|
|
||||||
callback = self._onUserPackagesRequestFinished,
|
|
||||||
error_callback = self._onUserPackagesRequestFinished,
|
|
||||||
scope = self._scope)
|
|
||||||
|
|
||||||
def _onUserPackagesRequestFinished(self,
|
|
||||||
reply: "QNetworkReply",
|
|
||||||
error: Optional["QNetworkReply.NetworkError"] = None) -> None:
|
|
||||||
if error is not None or reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
|
|
||||||
Logger.log("w",
|
|
||||||
"Requesting user packages failed, response code %s while trying to connect to %s",
|
|
||||||
reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url())
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
json_data = json.loads(bytes(reply.readAll()).decode("utf-8"))
|
|
||||||
|
|
||||||
# Check for errors:
|
|
||||||
if "errors" in json_data:
|
|
||||||
for error in json_data["errors"]:
|
|
||||||
Logger.log("e", "%s", error["title"])
|
|
||||||
return
|
|
||||||
|
|
||||||
self._handleCompatibilityData(json_data["data"])
|
|
||||||
except json.decoder.JSONDecodeError:
|
|
||||||
Logger.log("w", "Received invalid JSON for user packages")
|
|
|
@ -28,13 +28,12 @@ class DiscrepanciesPresenter(QObject):
|
||||||
assert self._dialog
|
assert self._dialog
|
||||||
self._dialog.accepted.connect(lambda: self._onConfirmClicked(model))
|
self._dialog.accepted.connect(lambda: self._onConfirmClicked(model))
|
||||||
|
|
||||||
@pyqtSlot("QVariant", str)
|
|
||||||
def dismissIncompatiblePackage(self, model: SubscribedPackagesModel, package_id: str) -> None:
|
|
||||||
model.dismissPackage(package_id) # update the model to update the view
|
|
||||||
self._package_manager.dismissPackage(package_id) # adds this package_id as dismissed in the user config file
|
|
||||||
|
|
||||||
def _onConfirmClicked(self, model: SubscribedPackagesModel) -> None:
|
def _onConfirmClicked(self, model: SubscribedPackagesModel) -> None:
|
||||||
|
# If there are incompatible packages - automatically dismiss them
|
||||||
|
if model.getIncompatiblePackages():
|
||||||
|
self._package_manager.dismissAllIncompatiblePackages(model.getIncompatiblePackages())
|
||||||
# For now, all compatible packages presented to the user should be installed.
|
# For now, all compatible packages presented to the user should be installed.
|
||||||
# Later, we might remove items for which the user unselected the package
|
# Later, we might remove items for which the user unselected the package
|
||||||
model.setItems(model.getCompatiblePackages())
|
if model.getCompatiblePackages():
|
||||||
self.packageMutations.emit(model)
|
model.setItems(model.getCompatiblePackages())
|
||||||
|
self.packageMutations.emit(model)
|
||||||
|
|
|
@ -62,7 +62,8 @@ class DownloadPresenter:
|
||||||
"received": 0,
|
"received": 0,
|
||||||
"total": 1, # make sure this is not considered done yet. Also divByZero-safe
|
"total": 1, # make sure this is not considered done yet. Also divByZero-safe
|
||||||
"file_written": None,
|
"file_written": None,
|
||||||
"request_data": request_data
|
"request_data": request_data,
|
||||||
|
"package_model": item
|
||||||
}
|
}
|
||||||
|
|
||||||
self._started = True
|
self._started = True
|
||||||
|
@ -128,7 +129,14 @@ class DownloadPresenter:
|
||||||
if not item["file_written"]:
|
if not item["file_written"]:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
success_items = {package_id : value["file_written"] for package_id, value in self._progress.items()}
|
success_items = {
|
||||||
|
package_id:
|
||||||
|
{
|
||||||
|
"package_path": value["file_written"],
|
||||||
|
"icon_url": value["package_model"]["icon_url"]
|
||||||
|
}
|
||||||
|
for package_id, value in self._progress.items()
|
||||||
|
}
|
||||||
error_items = [package_id for package_id in self._error]
|
error_items = [package_id for package_id in self._error]
|
||||||
|
|
||||||
self._progress_message.hide()
|
self._progress_message.hide()
|
||||||
|
|
|
@ -6,31 +6,52 @@ catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
# Model for the ToolboxLicenseDialog
|
# Model for the ToolboxLicenseDialog
|
||||||
class LicenseModel(QObject):
|
class LicenseModel(QObject):
|
||||||
dialogTitleChanged = pyqtSignal()
|
DEFAULT_DECLINE_BUTTON_TEXT = catalog.i18nc("@button", "Decline")
|
||||||
headerChanged = pyqtSignal()
|
ACCEPT_BUTTON_TEXT = catalog.i18nc("@button", "Agree")
|
||||||
licenseTextChanged = pyqtSignal()
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
dialogTitleChanged = pyqtSignal()
|
||||||
|
packageNameChanged = pyqtSignal()
|
||||||
|
licenseTextChanged = pyqtSignal()
|
||||||
|
iconChanged = pyqtSignal()
|
||||||
|
|
||||||
|
def __init__(self, decline_button_text: str = DEFAULT_DECLINE_BUTTON_TEXT) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self._current_page_idx = 0
|
self._current_page_idx = 0
|
||||||
self._page_count = 1
|
self._page_count = 1
|
||||||
self._dialogTitle = ""
|
self._dialogTitle = ""
|
||||||
self._header_text = ""
|
|
||||||
self._license_text = ""
|
self._license_text = ""
|
||||||
self._package_name = ""
|
self._package_name = ""
|
||||||
|
self._icon_url = ""
|
||||||
|
self._decline_button_text = decline_button_text
|
||||||
|
|
||||||
|
@pyqtProperty(str, constant = True)
|
||||||
|
def acceptButtonText(self):
|
||||||
|
return self.ACCEPT_BUTTON_TEXT
|
||||||
|
|
||||||
|
@pyqtProperty(str, constant = True)
|
||||||
|
def declineButtonText(self):
|
||||||
|
return self._decline_button_text
|
||||||
|
|
||||||
@pyqtProperty(str, notify=dialogTitleChanged)
|
@pyqtProperty(str, notify=dialogTitleChanged)
|
||||||
def dialogTitle(self) -> str:
|
def dialogTitle(self) -> str:
|
||||||
return self._dialogTitle
|
return self._dialogTitle
|
||||||
|
|
||||||
@pyqtProperty(str, notify=headerChanged)
|
@pyqtProperty(str, notify=packageNameChanged)
|
||||||
def headerText(self) -> str:
|
def packageName(self) -> str:
|
||||||
return self._header_text
|
return self._package_name
|
||||||
|
|
||||||
def setPackageName(self, name: str) -> None:
|
def setPackageName(self, name: str) -> None:
|
||||||
self._header_text = name + ": " + catalog.i18nc("@label", "This plugin contains a license.\nYou need to accept this license to install this plugin.\nDo you agree with the terms below?")
|
self._package_name = name
|
||||||
self.headerChanged.emit()
|
self.packageNameChanged.emit()
|
||||||
|
|
||||||
|
@pyqtProperty(str, notify=iconChanged)
|
||||||
|
def iconUrl(self) -> str:
|
||||||
|
return self._icon_url
|
||||||
|
|
||||||
|
def setIconUrl(self, url: str):
|
||||||
|
self._icon_url = url
|
||||||
|
self.iconChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(str, notify=licenseTextChanged)
|
@pyqtProperty(str, notify=licenseTextChanged)
|
||||||
def licenseText(self) -> str:
|
def licenseText(self) -> str:
|
||||||
|
|
|
@ -17,6 +17,7 @@ class LicensePresenter(QObject):
|
||||||
|
|
||||||
def __init__(self, app: CuraApplication) -> None:
|
def __init__(self, app: CuraApplication) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
self._catalog = i18nCatalog("cura")
|
||||||
self._dialog = None # type: Optional[QObject]
|
self._dialog = None # type: Optional[QObject]
|
||||||
self._package_manager = app.getPackageManager() # type: PackageManager
|
self._package_manager = app.getPackageManager() # type: PackageManager
|
||||||
# Emits List[Dict[str, [Any]] containing for example
|
# Emits List[Dict[str, [Any]] containing for example
|
||||||
|
@ -25,7 +26,8 @@ class LicensePresenter(QObject):
|
||||||
|
|
||||||
self._current_package_idx = 0
|
self._current_package_idx = 0
|
||||||
self._package_models = [] # type: List[Dict]
|
self._package_models = [] # type: List[Dict]
|
||||||
self._license_model = LicenseModel() # type: LicenseModel
|
decline_button_text = self._catalog.i18nc("@button", "Decline and remove from account")
|
||||||
|
self._license_model = LicenseModel(decline_button_text=decline_button_text) # type: LicenseModel
|
||||||
|
|
||||||
self._app = app
|
self._app = app
|
||||||
|
|
||||||
|
@ -34,7 +36,7 @@ class LicensePresenter(QObject):
|
||||||
## Show a license dialog for multiple packages where users can read a license and accept or decline them
|
## Show a license dialog for multiple packages where users can read a license and accept or decline them
|
||||||
# \param plugin_path: Root directory of the Toolbox plugin
|
# \param plugin_path: Root directory of the Toolbox plugin
|
||||||
# \param packages: Dict[package id, file path]
|
# \param packages: Dict[package id, file path]
|
||||||
def present(self, plugin_path: str, packages: Dict[str, str]) -> None:
|
def present(self, plugin_path: str, packages: Dict[str, Dict[str, str]]) -> None:
|
||||||
path = os.path.join(plugin_path, self._compatibility_dialog_path)
|
path = os.path.join(plugin_path, self._compatibility_dialog_path)
|
||||||
|
|
||||||
self._initState(packages)
|
self._initState(packages)
|
||||||
|
@ -42,7 +44,7 @@ class LicensePresenter(QObject):
|
||||||
if self._dialog is None:
|
if self._dialog is None:
|
||||||
|
|
||||||
context_properties = {
|
context_properties = {
|
||||||
"catalog": i18nCatalog("cura"),
|
"catalog": self._catalog,
|
||||||
"licenseModel": self._license_model,
|
"licenseModel": self._license_model,
|
||||||
"handler": self
|
"handler": self
|
||||||
}
|
}
|
||||||
|
@ -60,18 +62,20 @@ class LicensePresenter(QObject):
|
||||||
self._package_models[self._current_package_idx]["accepted"] = False
|
self._package_models[self._current_package_idx]["accepted"] = False
|
||||||
self._checkNextPage()
|
self._checkNextPage()
|
||||||
|
|
||||||
def _initState(self, packages: Dict[str, str]) -> None:
|
def _initState(self, packages: Dict[str, Dict[str, str]]) -> None:
|
||||||
self._package_models = [
|
self._package_models = [
|
||||||
{
|
{
|
||||||
"package_id" : package_id,
|
"package_id" : package_id,
|
||||||
"package_path" : package_path,
|
"package_path" : item["package_path"],
|
||||||
|
"icon_url" : item["icon_url"],
|
||||||
"accepted" : None #: None: no answer yet
|
"accepted" : None #: None: no answer yet
|
||||||
}
|
}
|
||||||
for package_id, package_path in packages.items()
|
for package_id, item in packages.items()
|
||||||
]
|
]
|
||||||
|
|
||||||
def _presentCurrentPackage(self) -> None:
|
def _presentCurrentPackage(self) -> None:
|
||||||
package_model = self._package_models[self._current_package_idx]
|
package_model = self._package_models[self._current_package_idx]
|
||||||
|
package_info = self._package_manager.getPackageInfo(package_model["package_path"])
|
||||||
license_content = self._package_manager.getPackageLicense(package_model["package_path"])
|
license_content = self._package_manager.getPackageLicense(package_model["package_path"])
|
||||||
if license_content is None:
|
if license_content is None:
|
||||||
# Implicitly accept when there is no license
|
# Implicitly accept when there is no license
|
||||||
|
@ -79,7 +83,8 @@ class LicensePresenter(QObject):
|
||||||
return
|
return
|
||||||
|
|
||||||
self._license_model.setCurrentPageIdx(self._current_package_idx)
|
self._license_model.setCurrentPageIdx(self._current_package_idx)
|
||||||
self._license_model.setPackageName(package_model["package_id"])
|
self._license_model.setPackageName(package_info["display_name"])
|
||||||
|
self._license_model.setIconUrl(package_model["icon_url"])
|
||||||
self._license_model.setLicenseText(license_content)
|
self._license_model.setLicenseText(license_content)
|
||||||
if self._dialog:
|
if self._dialog:
|
||||||
self._dialog.open() # Does nothing if already open
|
self._dialog.open() # Does nothing if already open
|
||||||
|
|
|
@ -37,27 +37,18 @@ class SubscribedPackagesModel(ListModel):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Sets the "is_compatible" to True for the given package, in memory
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def dismissPackage(self, package_id: str) -> None:
|
|
||||||
package = self.find(key="package_id", value=package_id)
|
|
||||||
if package != -1:
|
|
||||||
self.setProperty(package, property="is_dismissed", value=True)
|
|
||||||
Logger.debug("Package {} has been dismissed".format(package_id))
|
|
||||||
|
|
||||||
def setMetadata(self, data: List[Dict[str, List[Any]]]) -> None:
|
|
||||||
self._metadata = data
|
|
||||||
|
|
||||||
def addDiscrepancies(self, discrepancy: List[str]) -> None:
|
def addDiscrepancies(self, discrepancy: List[str]) -> None:
|
||||||
self._discrepancies = discrepancy
|
self._discrepancies = discrepancy
|
||||||
|
|
||||||
def getCompatiblePackages(self):
|
def getCompatiblePackages(self) -> List[Dict[str, Any]]:
|
||||||
return [x for x in self._items if x["is_compatible"]]
|
return [package for package in self._items if package["is_compatible"]]
|
||||||
|
|
||||||
def initialize(self) -> None:
|
def getIncompatiblePackages(self) -> List[str]:
|
||||||
|
return [package["package_id"] for package in self._items if not package["is_compatible"]]
|
||||||
|
|
||||||
|
def initialize(self, subscribed_packages_payload: List[Dict[str, Any]]) -> None:
|
||||||
self._items.clear()
|
self._items.clear()
|
||||||
for item in self._metadata:
|
for item in subscribed_packages_payload:
|
||||||
if item["package_id"] not in self._discrepancies:
|
if item["package_id"] not in self._discrepancies:
|
||||||
continue
|
continue
|
||||||
package = {
|
package = {
|
||||||
|
|
|
@ -63,9 +63,9 @@ class SyncOrchestrator(Extension):
|
||||||
self._download_presenter.download(mutations)
|
self._download_presenter.download(mutations)
|
||||||
|
|
||||||
## Called when a set of packages have finished downloading
|
## Called when a set of packages have finished downloading
|
||||||
# \param success_items: Dict[package_id, file_path]
|
# \param success_items: Dict[package_id, Dict[str, str]]
|
||||||
# \param error_items: List[package_id]
|
# \param error_items: List[package_id]
|
||||||
def _onDownloadFinished(self, success_items: Dict[str, str], error_items: List[str]) -> None:
|
def _onDownloadFinished(self, success_items: Dict[str, Dict[str, str]], error_items: List[str]) -> None:
|
||||||
if error_items:
|
if error_items:
|
||||||
message = i18n_catalog.i18nc("@info:generic", "{} plugins failed to download".format(len(error_items)))
|
message = i18n_catalog.i18nc("@info:generic", "{} plugins failed to download".format(len(error_items)))
|
||||||
self._showErrorMessage(message)
|
self._showErrorMessage(message)
|
||||||
|
|
|
@ -154,10 +154,11 @@ class Toolbox(QObject, Extension):
|
||||||
def getLicenseDialogPluginFileLocation(self) -> str:
|
def getLicenseDialogPluginFileLocation(self) -> str:
|
||||||
return self._license_dialog_plugin_file_location
|
return self._license_dialog_plugin_file_location
|
||||||
|
|
||||||
def openLicenseDialog(self, plugin_name: str, license_content: str, plugin_file_location: str) -> None:
|
def openLicenseDialog(self, plugin_name: str, license_content: str, plugin_file_location: str, icon_url: str) -> None:
|
||||||
# Set page 1/1 when opening the dialog for a single package
|
# Set page 1/1 when opening the dialog for a single package
|
||||||
self._license_model.setCurrentPageIdx(0)
|
self._license_model.setCurrentPageIdx(0)
|
||||||
self._license_model.setPageCount(1)
|
self._license_model.setPageCount(1)
|
||||||
|
self._license_model.setIconUrl(icon_url)
|
||||||
|
|
||||||
self._license_model.setPackageName(plugin_name)
|
self._license_model.setPackageName(plugin_name)
|
||||||
self._license_model.setLicenseText(license_content)
|
self._license_model.setLicenseText(license_content)
|
||||||
|
@ -670,14 +671,17 @@ class Toolbox(QObject, Extension):
|
||||||
return
|
return
|
||||||
|
|
||||||
license_content = self._package_manager.getPackageLicense(file_path)
|
license_content = self._package_manager.getPackageLicense(file_path)
|
||||||
|
package_id = package_info["package_id"]
|
||||||
if license_content is not None:
|
if license_content is not None:
|
||||||
self.openLicenseDialog(package_info["package_id"], license_content, file_path)
|
# get the icon url for package_id, make sure the result is a string, never None
|
||||||
|
icon_url = next((x["icon_url"] for x in self.packagesModel.items if x["id"] == package_id), None) or ""
|
||||||
|
self.openLicenseDialog(package_info["display_name"], license_content, file_path, icon_url)
|
||||||
return
|
return
|
||||||
|
|
||||||
package_id = self.install(file_path)
|
installed_id = self.install(file_path)
|
||||||
if package_id != package_info["package_id"]:
|
if installed_id != package_id:
|
||||||
Logger.error("Installed package {} does not match {}".format(package_id, package_info["package_id"]))
|
Logger.error("Installed package {} does not match {}".format(installed_id, package_id))
|
||||||
self.subscribe(package_id)
|
self.subscribe(installed_id)
|
||||||
|
|
||||||
# Getter & Setters for Properties:
|
# Getter & Setters for Properties:
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
@ -699,14 +703,14 @@ class Toolbox(QObject, Extension):
|
||||||
def isDownloading(self) -> bool:
|
def isDownloading(self) -> bool:
|
||||||
return self._is_downloading
|
return self._is_downloading
|
||||||
|
|
||||||
def setActivePackage(self, package: Dict[str, Any]) -> None:
|
def setActivePackage(self, package: QObject) -> None:
|
||||||
if self._active_package != package:
|
if self._active_package != package:
|
||||||
self._active_package = package
|
self._active_package = package
|
||||||
self.activePackageChanged.emit()
|
self.activePackageChanged.emit()
|
||||||
|
|
||||||
## The active package is the package that is currently being downloaded
|
## The active package is the package that is currently being downloaded
|
||||||
@pyqtProperty(QObject, fset = setActivePackage, notify = activePackageChanged)
|
@pyqtProperty(QObject, fset = setActivePackage, notify = activePackageChanged)
|
||||||
def activePackage(self) -> Optional[Dict[str, Any]]:
|
def activePackage(self) -> Optional[QObject]:
|
||||||
return self._active_package
|
return self._active_package
|
||||||
|
|
||||||
def setViewCategory(self, category: str = "plugin") -> None:
|
def setViewCategory(self, category: str = "plugin") -> None:
|
||||||
|
|
|
@ -5984,7 +5984,7 @@
|
||||||
"print_sequence":
|
"print_sequence":
|
||||||
{
|
{
|
||||||
"label": "Print Sequence",
|
"label": "Print Sequence",
|
||||||
"description": "Whether to print all models one layer at a time or to wait for one model to finish, before moving on to the next. One at a time mode is only possible if all models are separated in such a way that the whole print head can move in between and all models are lower than the distance between the nozzle and the X/Y axes.",
|
"description": "Whether to print all models one layer at a time or to wait for one model to finish, before moving on to the next. One at a time mode is possible if a) only one extruder is enabled and b) all models are separated in such a way that the whole print head can move in between and all models are lower than the distance between the nozzle and the X/Y axes. ",
|
||||||
"type": "enum",
|
"type": "enum",
|
||||||
"options":
|
"options":
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
"default_value": "skirt"
|
"default_value": "skirt"
|
||||||
},
|
},
|
||||||
"bottom_thickness": {
|
"bottom_thickness": {
|
||||||
"value": "0.5"
|
"value": "0.6"
|
||||||
},
|
},
|
||||||
"brim_width": {
|
"brim_width": {
|
||||||
"value": "2.0"
|
"value": "3.0"
|
||||||
},
|
},
|
||||||
"cool_fan_enabled": {
|
"cool_fan_enabled": {
|
||||||
"value": "True"
|
"value": "True"
|
||||||
|
@ -39,19 +39,28 @@
|
||||||
"value": "True"
|
"value": "True"
|
||||||
},
|
},
|
||||||
"cool_min_layer_time": {
|
"cool_min_layer_time": {
|
||||||
"value": "5.0"
|
"value": "1.0"
|
||||||
},
|
},
|
||||||
"cool_min_speed": {
|
"cool_min_speed": {
|
||||||
"value": "10.0"
|
"value": "5.0"
|
||||||
},
|
},
|
||||||
"infill_before_walls": {
|
"infill_before_walls": {
|
||||||
"value": "True"
|
"value": "True"
|
||||||
},
|
},
|
||||||
|
"infill_line_width": {
|
||||||
|
"value": "0.6"
|
||||||
|
},
|
||||||
"infill_overlap": {
|
"infill_overlap": {
|
||||||
"value": "15.0"
|
"value": "15.0"
|
||||||
},
|
},
|
||||||
|
"infill_sparse_density": {
|
||||||
|
"value": "26.0"
|
||||||
|
},
|
||||||
|
"ironing_enabled": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
"layer_0_z_overlap": {
|
"layer_0_z_overlap": {
|
||||||
"value": "0.22"
|
"value": "0.11"
|
||||||
},
|
},
|
||||||
"layer_height_0": {
|
"layer_height_0": {
|
||||||
"value": "0.3"
|
"value": "0.3"
|
||||||
|
@ -60,11 +69,23 @@
|
||||||
"value": "100"
|
"value": "100"
|
||||||
},
|
},
|
||||||
"machine_end_gcode": {
|
"machine_end_gcode": {
|
||||||
"default_value": ";End GCode\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 E-5 X-20 Y-20 ;retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nG0 Z{machine_height} ;move the platform all the way down\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nM84 ;steppers off\nG90 ;absolute positioning\nM117 Done"
|
"default_value": ";End GCode\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-4 F300 ;move Z up a bit and retract filament even more\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG0 Z{machine_height} F1800 ;move the platform all the way down\nG28 X0 Y0 F1800 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning\nM117 Done"
|
||||||
},
|
},
|
||||||
"machine_gcode_flavor": {
|
"machine_gcode_flavor": {
|
||||||
"default_value": "RepRap (Marlin/Sprinter)"
|
"default_value": "RepRap (Marlin/Sprinter)"
|
||||||
},
|
},
|
||||||
|
"machine_head_with_fans_polygon":
|
||||||
|
{
|
||||||
|
"default_value": [
|
||||||
|
[-26, -27],
|
||||||
|
[38, -27],
|
||||||
|
[38, 55],
|
||||||
|
[-26, 55]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"gantry_height": {
|
||||||
|
"value": "8"
|
||||||
|
},
|
||||||
"machine_height": {
|
"machine_height": {
|
||||||
"value": "100"
|
"value": "100"
|
||||||
},
|
},
|
||||||
|
@ -72,7 +93,7 @@
|
||||||
"default_value": "Renkforce RF100"
|
"default_value": "Renkforce RF100"
|
||||||
},
|
},
|
||||||
"machine_start_gcode": {
|
"machine_start_gcode": {
|
||||||
"default_value": ";Start GCode\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\n;Put printing message on LCD screen\nM117 Printing..."
|
"default_value": ";Sliced at: {day} {date} {time}\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG1 Z5.0 F1800 ;move Z to 5mm\nG28 X0 Y0 F1800 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstop\nG92 E0 ;zero the extruded length\nG1 F200 E6.0 ;extrude 6.0mm of feed stock to build pressure\nG1 Z5.0 F300 ;move the platform down 5mm\nG92 E0 ;zero the extruded length again\nG1 F1800\n;Put printing message on LCD screen\nM117 Printing..."
|
||||||
},
|
},
|
||||||
"machine_width": {
|
"machine_width": {
|
||||||
"value": "100"
|
"value": "100"
|
||||||
|
@ -90,7 +111,7 @@
|
||||||
"value": "True"
|
"value": "True"
|
||||||
},
|
},
|
||||||
"raft_airgap": {
|
"raft_airgap": {
|
||||||
"value": "0.22"
|
"value": "0.33"
|
||||||
},
|
},
|
||||||
"raft_base_line_spacing": {
|
"raft_base_line_spacing": {
|
||||||
"value": "3.0"
|
"value": "3.0"
|
||||||
|
@ -111,22 +132,25 @@
|
||||||
"value": "0.27"
|
"value": "0.27"
|
||||||
},
|
},
|
||||||
"raft_margin": {
|
"raft_margin": {
|
||||||
"value": "5.0"
|
"value": "6.0"
|
||||||
|
},
|
||||||
|
"raft_speed": {
|
||||||
|
"value": "20.0"
|
||||||
},
|
},
|
||||||
"raft_surface_layers": {
|
"raft_surface_layers": {
|
||||||
"value": "2.0"
|
"value": "2"
|
||||||
},
|
},
|
||||||
"raft_surface_line_spacing": {
|
"raft_surface_line_spacing": {
|
||||||
"value": "3.0"
|
"value": "0.4"
|
||||||
},
|
},
|
||||||
"raft_surface_line_width": {
|
"raft_surface_line_width": {
|
||||||
"value": "0.4"
|
"value": "0.4"
|
||||||
},
|
},
|
||||||
"raft_surface_thickness": {
|
"raft_surface_thickness": {
|
||||||
"value": "0.27"
|
"value": "0.1"
|
||||||
},
|
},
|
||||||
"retraction_amount": {
|
"retraction_amount": {
|
||||||
"value": "2.0"
|
"value": "5.0"
|
||||||
},
|
},
|
||||||
"retraction_combing": {
|
"retraction_combing": {
|
||||||
"default_value": "all"
|
"default_value": "all"
|
||||||
|
@ -134,15 +158,12 @@
|
||||||
"retraction_enable": {
|
"retraction_enable": {
|
||||||
"value": "True"
|
"value": "True"
|
||||||
},
|
},
|
||||||
"retraction_hop_enabled": {
|
"retraction_hop": {
|
||||||
"value": "1.0"
|
"value": "1.0"
|
||||||
},
|
},
|
||||||
"retraction_min_travel": {
|
"retraction_min_travel": {
|
||||||
"value": "1.5"
|
"value": "1.5"
|
||||||
},
|
},
|
||||||
"retraction_speed": {
|
|
||||||
"value": "40.0"
|
|
||||||
},
|
|
||||||
"skin_overlap": {
|
"skin_overlap": {
|
||||||
"value": "15.0"
|
"value": "15.0"
|
||||||
},
|
},
|
||||||
|
@ -185,6 +206,9 @@
|
||||||
"support_infill_rate": {
|
"support_infill_rate": {
|
||||||
"value": "15 if support_enable else 0 if support_tree_enable else 15"
|
"value": "15 if support_enable else 0 if support_tree_enable else 15"
|
||||||
},
|
},
|
||||||
|
"support_line_width": {
|
||||||
|
"value": "0.6"
|
||||||
|
},
|
||||||
"support_pattern": {
|
"support_pattern": {
|
||||||
"default_value": "lines"
|
"default_value": "lines"
|
||||||
},
|
},
|
||||||
|
@ -192,13 +216,13 @@
|
||||||
"default_value": "everywhere"
|
"default_value": "everywhere"
|
||||||
},
|
},
|
||||||
"support_xy_distance": {
|
"support_xy_distance": {
|
||||||
"value": "0.5"
|
"value": "0.7"
|
||||||
},
|
},
|
||||||
"support_z_distance": {
|
"support_z_distance": {
|
||||||
"value": "0.1"
|
"value": "0.35"
|
||||||
},
|
},
|
||||||
"top_thickness": {
|
"top_bottom_thickness": {
|
||||||
"value": "0.5"
|
"value": "0.8"
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"value": "0.8"
|
"value": "0.8"
|
||||||
|
|
231
resources/definitions/renkforce_rf100_v2.def.json
Normal file
231
resources/definitions/renkforce_rf100_v2.def.json
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"name": "Renkforce RF100 V2",
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"author": "Simon Peter (based on RF100.ini by Conrad Electronic SE)",
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"manufacturer": "Renkforce",
|
||||||
|
"visible": true,
|
||||||
|
"machine_extruder_trains":
|
||||||
|
{
|
||||||
|
"0": "renkforce_rf100_extruder_0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"overrides": {
|
||||||
|
"adhesion_type": {
|
||||||
|
"default_value": "skirt"
|
||||||
|
},
|
||||||
|
"bottom_thickness": {
|
||||||
|
"value": "0.6"
|
||||||
|
},
|
||||||
|
"brim_width": {
|
||||||
|
"value": "3.0"
|
||||||
|
},
|
||||||
|
"cool_fan_enabled": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"cool_fan_full_at_height": {
|
||||||
|
"value": "0.5"
|
||||||
|
},
|
||||||
|
"cool_fan_speed_max": {
|
||||||
|
"value": "100.0"
|
||||||
|
},
|
||||||
|
"cool_fan_speed_min": {
|
||||||
|
"value": "100.0"
|
||||||
|
},
|
||||||
|
"cool_lift_head": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"cool_min_layer_time": {
|
||||||
|
"value": "1.0"
|
||||||
|
},
|
||||||
|
"cool_min_speed": {
|
||||||
|
"value": "5.0"
|
||||||
|
},
|
||||||
|
"infill_before_walls": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"infill_line_width": {
|
||||||
|
"value": "0.6"
|
||||||
|
},
|
||||||
|
"infill_overlap": {
|
||||||
|
"value": "15.0"
|
||||||
|
},
|
||||||
|
"infill_sparse_density": {
|
||||||
|
"value": "26.0"
|
||||||
|
},
|
||||||
|
"ironing_enabled": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"layer_0_z_overlap": {
|
||||||
|
"value": "0.11"
|
||||||
|
},
|
||||||
|
"layer_height_0": {
|
||||||
|
"value": "0.3"
|
||||||
|
},
|
||||||
|
"machine_depth": {
|
||||||
|
"value": "120"
|
||||||
|
},
|
||||||
|
"machine_end_gcode": {
|
||||||
|
"default_value": ";End GCode\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-4 F300 ;move Z up a bit and retract filament even more\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG0 Z{machine_height} F1800 ;move the platform all the way down\nG28 X0 Y0 F1800 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning\nM117 Done"
|
||||||
|
},
|
||||||
|
"machine_gcode_flavor": {
|
||||||
|
"default_value": "RepRap (Marlin/Sprinter)"
|
||||||
|
},
|
||||||
|
"machine_head_with_fans_polygon":
|
||||||
|
{
|
||||||
|
"default_value": [
|
||||||
|
[-26, -27],
|
||||||
|
[38, -27],
|
||||||
|
[38, 55],
|
||||||
|
[-26, 55]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"gantry_height": {
|
||||||
|
"value": "8"
|
||||||
|
},
|
||||||
|
"machine_height": {
|
||||||
|
"value": "120"
|
||||||
|
},
|
||||||
|
"machine_name": {
|
||||||
|
"default_value": "Renkforce RF100 V2"
|
||||||
|
},
|
||||||
|
"machine_start_gcode": {
|
||||||
|
"default_value": ";Sliced at: {day} {date} {time}\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG1 Z5.0 F1800 ;move Z to 5mm\nG28 X0 Y0 F1800 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstop\nG92 E0 ;zero the extruded length\nG1 F200 E6.0 ;extrude 6.0mm of feed stock to build pressure\nG1 Z5.0 F300 ;move the platform down 5mm\nG92 E0 ;zero the extruded length again\nG1 F1800\n;Put printing message on LCD screen\nM117 Printing..."
|
||||||
|
},
|
||||||
|
"machine_width": {
|
||||||
|
"value": "120"
|
||||||
|
},
|
||||||
|
"material_bed_temperature": {
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"material_flow": {
|
||||||
|
"value": "110"
|
||||||
|
},
|
||||||
|
"material_print_temperature": {
|
||||||
|
"value": "210.0"
|
||||||
|
},
|
||||||
|
"ooze_shield_enabled": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"raft_airgap": {
|
||||||
|
"value": "0.33"
|
||||||
|
},
|
||||||
|
"raft_base_line_spacing": {
|
||||||
|
"value": "3.0"
|
||||||
|
},
|
||||||
|
"raft_base_line_width": {
|
||||||
|
"value": "1.0"
|
||||||
|
},
|
||||||
|
"raft_base_thickness": {
|
||||||
|
"value": "0.3"
|
||||||
|
},
|
||||||
|
"raft_interface_line_spacing": {
|
||||||
|
"value": "3.0"
|
||||||
|
},
|
||||||
|
"raft_interface_line_width": {
|
||||||
|
"value": "0.4"
|
||||||
|
},
|
||||||
|
"raft_interface_thickness": {
|
||||||
|
"value": "0.27"
|
||||||
|
},
|
||||||
|
"raft_margin": {
|
||||||
|
"value": "6.0"
|
||||||
|
},
|
||||||
|
"raft_speed": {
|
||||||
|
"value": "20.0"
|
||||||
|
},
|
||||||
|
"raft_surface_layers": {
|
||||||
|
"value": "2"
|
||||||
|
},
|
||||||
|
"raft_surface_line_spacing": {
|
||||||
|
"value": "0.4"
|
||||||
|
},
|
||||||
|
"raft_surface_line_width": {
|
||||||
|
"value": "0.4"
|
||||||
|
},
|
||||||
|
"raft_surface_thickness": {
|
||||||
|
"value": "0.1"
|
||||||
|
},
|
||||||
|
"retraction_amount": {
|
||||||
|
"value": "5.0"
|
||||||
|
},
|
||||||
|
"retraction_combing": {
|
||||||
|
"default_value": "all"
|
||||||
|
},
|
||||||
|
"retraction_enable": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"retraction_hop": {
|
||||||
|
"value": "1.0"
|
||||||
|
},
|
||||||
|
"retraction_min_travel": {
|
||||||
|
"value": "1.5"
|
||||||
|
},
|
||||||
|
"skin_overlap": {
|
||||||
|
"value": "15.0"
|
||||||
|
},
|
||||||
|
"skirt_brim_minimal_length": {
|
||||||
|
"value": "150.0"
|
||||||
|
},
|
||||||
|
"skirt_gap": {
|
||||||
|
"value": "3.0"
|
||||||
|
},
|
||||||
|
"skirt_line_count": {
|
||||||
|
"value": "3"
|
||||||
|
},
|
||||||
|
"speed_infill": {
|
||||||
|
"value": "50.0"
|
||||||
|
},
|
||||||
|
"speed_layer_0": {
|
||||||
|
"value": "15.0"
|
||||||
|
},
|
||||||
|
"speed_print": {
|
||||||
|
"value": "50.0"
|
||||||
|
},
|
||||||
|
"speed_topbottom": {
|
||||||
|
"value": "30.0"
|
||||||
|
},
|
||||||
|
"speed_travel": {
|
||||||
|
"value": "50.0"
|
||||||
|
},
|
||||||
|
"speed_wall_0": {
|
||||||
|
"value": "25.0"
|
||||||
|
},
|
||||||
|
"speed_wall_x": {
|
||||||
|
"value": "35.0"
|
||||||
|
},
|
||||||
|
"support_angle": {
|
||||||
|
"value": "60.0"
|
||||||
|
},
|
||||||
|
"support_enable": {
|
||||||
|
"value": "False"
|
||||||
|
},
|
||||||
|
"support_infill_rate": {
|
||||||
|
"value": "15 if support_enable else 0 if support_tree_enable else 15"
|
||||||
|
},
|
||||||
|
"support_line_width": {
|
||||||
|
"value": "0.6"
|
||||||
|
},
|
||||||
|
"support_pattern": {
|
||||||
|
"default_value": "lines"
|
||||||
|
},
|
||||||
|
"support_type": {
|
||||||
|
"default_value": "everywhere"
|
||||||
|
},
|
||||||
|
"support_xy_distance": {
|
||||||
|
"value": "0.7"
|
||||||
|
},
|
||||||
|
"support_z_distance": {
|
||||||
|
"value": "0.35"
|
||||||
|
},
|
||||||
|
"top_bottom_thickness": {
|
||||||
|
"value": "0.8"
|
||||||
|
},
|
||||||
|
"wall_thickness": {
|
||||||
|
"value": "0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
219
resources/definitions/renkforce_rf100_xl.def.json
Normal file
219
resources/definitions/renkforce_rf100_xl.def.json
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"name": "Renkforce RF100 XL",
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"author": "Simon Peter (based on RF100.ini by Conrad Electronic SE)",
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"manufacturer": "Renkforce",
|
||||||
|
"visible": true,
|
||||||
|
"machine_extruder_trains":
|
||||||
|
{
|
||||||
|
"0": "renkforce_rf100_xl_extruder_0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"overrides": {
|
||||||
|
"adhesion_type": {
|
||||||
|
"default_value": "skirt"
|
||||||
|
},
|
||||||
|
"bottom_thickness": {
|
||||||
|
"value": "0.6"
|
||||||
|
},
|
||||||
|
"brim_width": {
|
||||||
|
"value": "3.0"
|
||||||
|
},
|
||||||
|
"cool_fan_enabled": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"cool_fan_full_at_height": {
|
||||||
|
"value": "0.5"
|
||||||
|
},
|
||||||
|
"cool_fan_speed_max": {
|
||||||
|
"value": "100.0"
|
||||||
|
},
|
||||||
|
"cool_fan_speed_min": {
|
||||||
|
"value": "100.0"
|
||||||
|
},
|
||||||
|
"cool_lift_head": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"cool_min_layer_time": {
|
||||||
|
"value": "1.0"
|
||||||
|
},
|
||||||
|
"cool_min_speed": {
|
||||||
|
"value": "5.0"
|
||||||
|
},
|
||||||
|
"infill_before_walls": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"infill_line_width": {
|
||||||
|
"value": "0.6"
|
||||||
|
},
|
||||||
|
"infill_overlap": {
|
||||||
|
"value": "15.0"
|
||||||
|
},
|
||||||
|
"infill_sparse_density": {
|
||||||
|
"value": "26.0"
|
||||||
|
},
|
||||||
|
"ironing_enabled": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"layer_0_z_overlap": {
|
||||||
|
"value": "0.11"
|
||||||
|
},
|
||||||
|
"layer_height_0": {
|
||||||
|
"value": "0.3"
|
||||||
|
},
|
||||||
|
"machine_depth": {
|
||||||
|
"value": "200"
|
||||||
|
},
|
||||||
|
"machine_end_gcode": {
|
||||||
|
"default_value": ";End GCode\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-4 F300 ;move Z up a bit and retract filament even more\nM104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG0 Z{machine_height} F1800 ;move the platform all the way down\nG28 X0 Y0 F1800 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning\nM117 Done"
|
||||||
|
},
|
||||||
|
"machine_gcode_flavor": {
|
||||||
|
"default_value": "RepRap (Marlin/Sprinter)"
|
||||||
|
},
|
||||||
|
"machine_heated_bed": {
|
||||||
|
"default_value": "true"
|
||||||
|
},
|
||||||
|
"machine_height": {
|
||||||
|
"value": "200"
|
||||||
|
},
|
||||||
|
"machine_name": {
|
||||||
|
"default_value": "Renkforce RF100 XL"
|
||||||
|
},
|
||||||
|
"machine_start_gcode": {
|
||||||
|
"default_value": ";Sliced at: {day} {date} {time}\nG21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG1 Z5.0 F1800 ;move Z to 5mm\nG28 X0 Y0 F1800 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstop\nG92 E0 ;zero the extruded length\nG1 F200 E6.0 ;extrude 6.0mm of feed stock to build pressure\nG1 Z5.0 F300 ;move the platform down 5mm\nG92 E0 ;zero the extruded length again\nG1 F1800\n;Put printing message on LCD screen\nM117 Printing..."
|
||||||
|
},
|
||||||
|
"machine_width": {
|
||||||
|
"value": "200"
|
||||||
|
},
|
||||||
|
"material_bed_temperature": {
|
||||||
|
"value": "70"
|
||||||
|
},
|
||||||
|
"material_print_temperature": {
|
||||||
|
"value": "210.0"
|
||||||
|
},
|
||||||
|
"ooze_shield_enabled": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"raft_airgap": {
|
||||||
|
"value": "0.33"
|
||||||
|
},
|
||||||
|
"raft_base_line_spacing": {
|
||||||
|
"value": "3.0"
|
||||||
|
},
|
||||||
|
"raft_base_line_width": {
|
||||||
|
"value": "1.0"
|
||||||
|
},
|
||||||
|
"raft_base_thickness": {
|
||||||
|
"value": "0.3"
|
||||||
|
},
|
||||||
|
"raft_interface_line_spacing": {
|
||||||
|
"value": "3.0"
|
||||||
|
},
|
||||||
|
"raft_interface_line_width": {
|
||||||
|
"value": "0.4"
|
||||||
|
},
|
||||||
|
"raft_interface_thickness": {
|
||||||
|
"value": "0.27"
|
||||||
|
},
|
||||||
|
"raft_margin": {
|
||||||
|
"value": "6.0"
|
||||||
|
},
|
||||||
|
"raft_speed": {
|
||||||
|
"value": "20.0"
|
||||||
|
},
|
||||||
|
"raft_surface_layers": {
|
||||||
|
"value": "2"
|
||||||
|
},
|
||||||
|
"raft_surface_line_spacing": {
|
||||||
|
"value": "0.4"
|
||||||
|
},
|
||||||
|
"raft_surface_line_width": {
|
||||||
|
"value": "0.4"
|
||||||
|
},
|
||||||
|
"raft_surface_thickness": {
|
||||||
|
"value": "0.1"
|
||||||
|
},
|
||||||
|
"retraction_amount": {
|
||||||
|
"value": "5.0"
|
||||||
|
},
|
||||||
|
"retraction_combing": {
|
||||||
|
"default_value": "all"
|
||||||
|
},
|
||||||
|
"retraction_enable": {
|
||||||
|
"value": "True"
|
||||||
|
},
|
||||||
|
"retraction_hop": {
|
||||||
|
"value": "1.0"
|
||||||
|
},
|
||||||
|
"retraction_min_travel": {
|
||||||
|
"value": "1.5"
|
||||||
|
},
|
||||||
|
"skin_overlap": {
|
||||||
|
"value": "15.0"
|
||||||
|
},
|
||||||
|
"skirt_brim_minimal_length": {
|
||||||
|
"value": "150.0"
|
||||||
|
},
|
||||||
|
"skirt_gap": {
|
||||||
|
"value": "3.0"
|
||||||
|
},
|
||||||
|
"skirt_line_count": {
|
||||||
|
"value": "3"
|
||||||
|
},
|
||||||
|
"speed_infill": {
|
||||||
|
"value": "50.0"
|
||||||
|
},
|
||||||
|
"speed_layer_0": {
|
||||||
|
"value": "15.0"
|
||||||
|
},
|
||||||
|
"speed_print": {
|
||||||
|
"value": "50.0"
|
||||||
|
},
|
||||||
|
"speed_topbottom": {
|
||||||
|
"value": "30.0"
|
||||||
|
},
|
||||||
|
"speed_travel": {
|
||||||
|
"value": "50.0"
|
||||||
|
},
|
||||||
|
"speed_wall_0": {
|
||||||
|
"value": "25.0"
|
||||||
|
},
|
||||||
|
"speed_wall_x": {
|
||||||
|
"value": "35.0"
|
||||||
|
},
|
||||||
|
"support_angle": {
|
||||||
|
"value": "60.0"
|
||||||
|
},
|
||||||
|
"support_enable": {
|
||||||
|
"value": "False"
|
||||||
|
},
|
||||||
|
"support_infill_rate": {
|
||||||
|
"value": "15 if support_enable else 0 if support_tree_enable else 15"
|
||||||
|
},
|
||||||
|
"support_line_width": {
|
||||||
|
"value": "0.6"
|
||||||
|
},
|
||||||
|
"support_pattern": {
|
||||||
|
"default_value": "lines"
|
||||||
|
},
|
||||||
|
"support_type": {
|
||||||
|
"default_value": "everywhere"
|
||||||
|
},
|
||||||
|
"support_xy_distance": {
|
||||||
|
"value": "0.7"
|
||||||
|
},
|
||||||
|
"support_z_distance": {
|
||||||
|
"value": "0.35"
|
||||||
|
},
|
||||||
|
"top_bottom_thickness": {
|
||||||
|
"value": "0.8"
|
||||||
|
},
|
||||||
|
"wall_thickness": {
|
||||||
|
"value": "0.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
resources/extruders/renkforce_rf100_xl_extruder_0.def.json
Normal file
15
resources/extruders/renkforce_rf100_xl_extruder_0.def.json
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"name": "Extruder 1",
|
||||||
|
"inherits": "fdmextruder",
|
||||||
|
"metadata": {
|
||||||
|
"machine": "renkforce_rf100_xl",
|
||||||
|
"position": "0"
|
||||||
|
},
|
||||||
|
|
||||||
|
"overrides": {
|
||||||
|
"extruder_nr": { "default_value": 0 },
|
||||||
|
"machine_nozzle_size": { "default_value": 0.4 },
|
||||||
|
"material_diameter": { "default_value": 1.75 }
|
||||||
|
}
|
||||||
|
}
|
|
@ -127,8 +127,8 @@ Item
|
||||||
icon: StandardIcon.Question
|
icon: StandardIcon.Question
|
||||||
onYes:
|
onYes:
|
||||||
{
|
{
|
||||||
CuraApplication.deleteAll();
|
CuraApplication.resetWorkspace()
|
||||||
Cura.Actions.resetProfile.trigger();
|
Cura.Actions.resetProfile.trigger()
|
||||||
UM.Controller.setActiveStage("PrepareStage")
|
UM.Controller.setActiveStage("PrepareStage")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,7 @@ Item
|
||||||
id: createMenuButton
|
id: createMenuButton
|
||||||
text: catalog.i18nc("@action:button", "Create")
|
text: catalog.i18nc("@action:button", "Create")
|
||||||
iconName: "list-add"
|
iconName: "list-add"
|
||||||
|
enabled: Cura.MachineManager.activeMachine.hasMaterials
|
||||||
onClicked:
|
onClicked:
|
||||||
{
|
{
|
||||||
forceActiveFocus();
|
forceActiveFocus();
|
||||||
|
@ -174,7 +175,7 @@ Item
|
||||||
forceActiveFocus();
|
forceActiveFocus();
|
||||||
importMaterialDialog.open();
|
importMaterialDialog.open();
|
||||||
}
|
}
|
||||||
visible: true
|
enabled: Cura.MachineManager.activeMachine.hasMaterials
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export button
|
// Export button
|
||||||
|
|
|
@ -202,8 +202,9 @@ Item
|
||||||
// dragging a tool handle.
|
// dragging a tool handle.
|
||||||
Rectangle
|
Rectangle
|
||||||
{
|
{
|
||||||
x: -base.x + base.mouseX + UM.Theme.getSize("default_margin").width
|
id: toolInfo
|
||||||
y: -base.y + base.mouseY + UM.Theme.getSize("default_margin").height
|
x: visible ? -base.x + base.mouseX + UM.Theme.getSize("default_margin").width: 0
|
||||||
|
y: visible ? -base.y + base.mouseY + UM.Theme.getSize("default_margin").height: 0
|
||||||
|
|
||||||
width: toolHint.width + UM.Theme.getSize("default_margin").width
|
width: toolHint.width + UM.Theme.getSize("default_margin").width
|
||||||
height: toolHint.height;
|
height: toolHint.height;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue