Merge branch 'main' into Issue-4835-allow-to-set-print-sequence-manually

This commit is contained in:
Saumya Jain 2024-02-09 09:52:06 +01:00 committed by GitHub
commit 355f24e29f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
468 changed files with 6280 additions and 711 deletions

View file

@ -5,6 +5,13 @@ body:
- type: markdown - type: markdown
attributes: attributes:
value: | value: |
### 💥 Slicing Crash Analysis Tool 💥
We are taking steps to analyze an increase in reported crashes more systematically. We'll need some help with that. 😇
Before filling out the report below, we want you to try a special Cura 5.7 Alpha.
This version of Cura has an updated slicing engine that will automatically send a report to the Cura Team for analysis.
#### [You can find the downloads here](https://github.com/Ultimaker/Cura/discussions/18080) ####
If you still encounter a crash you are still welcome to report the issue so we can use your model as a test case, you can find instructions on how to do that below.
### Project File ### Project File
**⚠️ Before you continue, we need your project file to troubleshoot a slicing crash.** **⚠️ Before you continue, we need your project file to troubleshoot a slicing crash.**
It contains the printer and settings we need for troubleshooting. It contains the printer and settings we need for troubleshooting.
@ -68,4 +75,3 @@ body:
description: You can add the zip file and additional information that is relevant to the issue in the comments below. description: You can add the zip file and additional information that is relevant to the issue in the comments below.
validations: validations:
required: true required: true

View file

@ -58,7 +58,7 @@ jobs:
enterprise: ${{ github.event.inputs.enterprise == 'true' }} enterprise: ${{ github.event.inputs.enterprise == 'true' }}
staging: ${{ github.event.inputs.staging == 'true' }} staging: ${{ github.event.inputs.staging == 'true' }}
architecture: X64 architecture: X64
operating_system: windows-2022 operating_system: self-hosted-Windows-X64
secrets: inherit secrets: inherit
linux-installer: linux-installer:

View file

@ -34,9 +34,10 @@ on:
operating_system: operating_system:
description: 'OS' description: 'OS'
required: true required: true
default: 'windows-2022' default: 'self-hosted-Windows-X64'
type: choice type: choice
options: options:
- self-hosted-Windows-X64
- windows-2022 - windows-2022
jobs: jobs:

View file

@ -55,7 +55,8 @@ exe = EXE(
target_arch={{ target_arch }}, target_arch={{ target_arch }},
codesign_identity=os.getenv('CODESIGN_IDENTITY', None), codesign_identity=os.getenv('CODESIGN_IDENTITY', None),
entitlements_file={{ entitlements_file }}, entitlements_file={{ entitlements_file }},
icon={{ icon }} icon={{ icon }},
contents_directory='.'
) )
coll = COLLECT( coll = COLLECT(
@ -70,188 +71,7 @@ coll = COLLECT(
) )
{% if macos == true %} {% if macos == true %}
# PyInstaller seems to copy everything in the resource folder for the MacOS, this causes issues with codesigning and notarizing app = BUNDLE(
# The folder structure should adhere to the one specified in Table 2-5
# https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW1
# The class below is basically ducktyping the BUNDLE class of PyInstaller and using our own `assemble` method for more fine-grain and specific
# control. Some code of the method below is copied from:
# https://github.com/pyinstaller/pyinstaller/blob/22d1d2a5378228744cc95f14904dae1664df32c4/PyInstaller/building/osx.py#L115
#-----------------------------------------------------------------------------
# Copyright (c) 2005-2022, PyInstaller Development Team.
#
# Distributed under the terms of the GNU General Public License (version 2
# or later) with exception for distributing the bootloader.
#
# The full license is in the file COPYING.txt, distributed with this software.
#
# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
#-----------------------------------------------------------------------------
import plistlib
import shutil
import PyInstaller.utils.osx as osxutils
from pathlib import Path
from PyInstaller.building.osx import BUNDLE
from PyInstaller.building.utils import (_check_path_overlap, _rmtree, add_suffix_to_extension, checkCache)
from PyInstaller.building.datastruct import logger
from PyInstaller.building.icon import normalize_icon_type
class UMBUNDLE(BUNDLE):
def assemble(self):
from PyInstaller.config import CONF
if _check_path_overlap(self.name) and os.path.isdir(self.name):
_rmtree(self.name)
logger.info("Building BUNDLE %s", self.tocbasename)
# Create a minimal Mac bundle structure.
macos_path = Path(self.name, "Contents", "MacOS")
resources_path = Path(self.name, "Contents", "Resources")
frameworks_path = Path(self.name, "Contents", "Frameworks")
os.makedirs(macos_path)
os.makedirs(resources_path)
os.makedirs(frameworks_path)
# Makes sure the icon exists and attempts to convert to the proper format if applicable
self.icon = normalize_icon_type(self.icon, ("icns",), "icns", CONF["workpath"])
# Ensure icon path is absolute
self.icon = os.path.abspath(self.icon)
# Copy icns icon to Resources directory.
shutil.copy(self.icon, os.path.join(self.name, 'Contents', 'Resources'))
# Key/values for a minimal Info.plist file
info_plist_dict = {
"CFBundleDisplayName": self.appname,
"CFBundleName": self.appname,
# Required by 'codesign' utility.
# The value for CFBundleIdentifier is used as the default unique name of your program for Code Signing
# purposes. It even identifies the APP for access to restricted OS X areas like Keychain.
#
# The identifier used for signing must be globally unique. The usual form for this identifier is a
# hierarchical name in reverse DNS notation, starting with the toplevel domain, followed by the company
# name, followed by the department within the company, and ending with the product name. Usually in the
# form: com.mycompany.department.appname
# CLI option --osx-bundle-identifier sets this value.
"CFBundleIdentifier": self.bundle_identifier,
"CFBundleExecutable": os.path.basename(self.exename),
"CFBundleIconFile": os.path.basename(self.icon),
"CFBundleInfoDictionaryVersion": "6.0",
"CFBundlePackageType": "APPL",
"CFBundleVersionString": self.version,
"CFBundleShortVersionString": self.version,
}
# Set some default values. But they still can be overwritten by the user.
if self.console:
# Setting EXE console=True implies LSBackgroundOnly=True.
info_plist_dict['LSBackgroundOnly'] = True
else:
# Let's use high resolution by default.
info_plist_dict['NSHighResolutionCapable'] = True
# Merge info_plist settings from spec file
if isinstance(self.info_plist, dict) and self.info_plist:
info_plist_dict.update(self.info_plist)
plist_filename = os.path.join(self.name, "Contents", "Info.plist")
with open(plist_filename, "wb") as plist_fh:
plistlib.dump(info_plist_dict, plist_fh)
links = []
_QT_BASE_PATH = {'PySide2', 'PySide6', 'PyQt5', 'PyQt6', 'PySide6'}
for inm, fnm, typ in self.toc:
# Adjust name for extensions, if applicable
inm, fnm, typ = add_suffix_to_extension(inm, fnm, typ)
inm = Path(inm)
fnm = Path(fnm)
# Copy files from cache. This ensures that are used files with relative paths to dynamic library
# dependencies (@executable_path)
if typ in ('EXTENSION', 'BINARY') or (typ == 'DATA' and inm.suffix == '.so'):
if any(['.' in p for p in inm.parent.parts]):
inm = Path(inm.name)
fnm = Path(checkCache(
str(fnm),
strip = self.strip,
upx = self.upx,
upx_exclude = self.upx_exclude,
dist_nm = str(inm),
target_arch = self.target_arch,
codesign_identity = self.codesign_identity,
entitlements_file = self.entitlements_file,
strict_arch_validation = (typ == 'EXTENSION'),
))
frame_dst = frameworks_path.joinpath(inm)
if not frame_dst.exists():
if frame_dst.is_dir():
os.makedirs(frame_dst, exist_ok = True)
else:
os.makedirs(frame_dst.parent, exist_ok = True)
shutil.copy(fnm, frame_dst, follow_symlinks = True)
macos_dst = macos_path.joinpath(inm)
if not macos_dst.exists():
if macos_dst.is_dir():
os.makedirs(macos_dst, exist_ok = True)
else:
os.makedirs(macos_dst.parent, exist_ok = True)
# Create relative symlink to the framework
symlink_to = Path(*[".." for p in macos_dst.relative_to(macos_path).parts], "Frameworks").joinpath(
frame_dst.relative_to(frameworks_path))
try:
macos_dst.symlink_to(symlink_to)
except FileExistsError:
pass
else:
if typ == 'DATA':
if any(['.' in p for p in inm.parent.parts]) or inm.suffix == '.so':
# Skip info dist egg and some not needed folders in tcl and tk, since they all contain dots in their files
logger.warning(f"Skipping DATA file {inm}")
continue
res_dst = resources_path.joinpath(inm)
if not res_dst.exists():
if res_dst.is_dir():
os.makedirs(res_dst, exist_ok = True)
else:
os.makedirs(res_dst.parent, exist_ok = True)
shutil.copy(fnm, res_dst, follow_symlinks = True)
macos_dst = macos_path.joinpath(inm)
if not macos_dst.exists():
if macos_dst.is_dir():
os.makedirs(macos_dst, exist_ok = True)
else:
os.makedirs(macos_dst.parent, exist_ok = True)
# Create relative symlink to the resource
symlink_to = Path(*[".." for p in macos_dst.relative_to(macos_path).parts], "Resources").joinpath(
res_dst.relative_to(resources_path))
try:
macos_dst.symlink_to(symlink_to)
except FileExistsError:
pass
else:
macos_dst = macos_path.joinpath(inm)
if not macos_dst.exists():
if macos_dst.is_dir():
os.makedirs(macos_dst, exist_ok = True)
else:
os.makedirs(macos_dst.parent, exist_ok = True)
shutil.copy(fnm, macos_dst, follow_symlinks = True)
# Sign the bundle
logger.info('Signing the BUNDLE...')
try:
osxutils.sign_binary(self.name, self.codesign_identity, self.entitlements_file, deep = True)
except Exception as e:
logger.warning(f"Error while signing the bundle: {e}")
logger.warning("You will need to sign the bundle manually!")
logger.info(f"Building BUNDLE {self.tocbasename} completed successfully.")
app = UMBUNDLE(
coll, coll,
name='{{ display_name }}.app', name='{{ display_name }}.app',
icon={{ icon }}, icon={{ icon }},
@ -271,9 +91,10 @@ app = UMBUNDLE(
'CFBundleURLSchemes': ['cura', 'slicer'], 'CFBundleURLSchemes': ['cura', 'slicer'],
}], }],
'CFBundleDocumentTypes': [{ 'CFBundleDocumentTypes': [{
'CFBundleTypeRole': 'Viewer', 'CFBundleTypeRole': 'Viewer',
'CFBundleTypeExtensions': ['*'], 'CFBundleTypeExtensions': ['stl', 'obj', '3mf', 'gcode', 'ufp'],
'CFBundleTypeName': 'Model Files', 'CFBundleTypeName': 'Model Files',
}] }]
}, },
){% endif %} )
{% endif %}

View file

@ -1,12 +1,11 @@
version: "5.7.0-alpha.0" version: "5.7.0-alpha.1"
requirements: requirements:
- "uranium/(latest)@ultimaker/testing" - "uranium/(latest)@ultimaker/testing"
- "curaengine/(latest)@ultimaker/testing" - "curaengine/(latest)@ultimaker/testing"
- "cura_binary_data/(latest)@ultimaker/testing" - "cura_binary_data/(latest)@ultimaker/testing"
- "fdm_materials/(latest)@ultimaker/testing" - "fdm_materials/(latest)@ultimaker/testing"
- "curaengine_plugin_gradual_flow/(latest)@ultimaker/stable" - "curaengine_plugin_gradual_flow/0.1.0-beta.2"
- "dulcificum/latest@ultimaker/testing" - "dulcificum/latest@ultimaker/testing"
- "pyarcus/5.3.0"
- "pysavitar/5.3.0" - "pysavitar/5.3.0"
- "pynest2d/5.3.0" - "pynest2d/5.3.0"
- "curaengine_grpc_definitions/(latest)@ultimaker/testing" - "curaengine_grpc_definitions/(latest)@ultimaker/testing"
@ -119,7 +118,6 @@ pyinstaller:
- "sqlite3" - "sqlite3"
- "trimesh" - "trimesh"
- "win32ctypes" - "win32ctypes"
- "PyQt6"
- "PyQt6.QtNetwork" - "PyQt6.QtNetwork"
- "PyQt6.sip" - "PyQt6.sip"
- "stl" - "stl"

View file

@ -1,4 +1,5 @@
import os import os
from io import StringIO
from pathlib import Path from pathlib import Path
from jinja2 import Template from jinja2 import Template
@ -150,6 +151,7 @@ class CuraConan(ConanFile):
return "None" return "None"
def _conan_installs(self): def _conan_installs(self):
self.output.info("Collecting conan installs")
conan_installs = {} conan_installs = {}
# list of conan installs # list of conan installs
@ -161,13 +163,22 @@ class CuraConan(ConanFile):
return conan_installs return conan_installs
def _python_installs(self): def _python_installs(self):
self.output.info("Collecting python installs")
python_installs = {} python_installs = {}
# list of python installs # list of python installs
python_ins_cmd = f"python -c \"import pkg_resources; print(';'.join([(s.key+','+ s.version) for s in pkg_resources.working_set]))\"" run_env = VirtualRunEnv(self)
from six import StringIO env = run_env.environment()
env.prepend_path("PYTHONPATH", str(self._site_packages.as_posix()))
venv_vars = env.vars(self, scope = "run")
outer = '"' if self.settings.os == "Windows" else "'"
inner = "'" if self.settings.os == "Windows" else '"'
buffer = StringIO() buffer = StringIO()
self.run(python_ins_cmd, run_environment= True, env = "conanrun", output=buffer) with venv_vars.apply():
self.run(f"""python -c {outer}import pkg_resources; print({inner};{inner}.join([(s.key+{inner},{inner}+ s.version) for s in pkg_resources.working_set])){outer}""",
env = "conanrun",
output = buffer)
packages = str(buffer.getvalue()).split("-----------------\n") packages = str(buffer.getvalue()).split("-----------------\n")
packages = packages[1].strip('\r\n').split(";") packages = packages[1].strip('\r\n').split(";")
@ -242,7 +253,7 @@ class CuraConan(ConanFile):
self.output.warning(f"Source path for binary {binary['binary']} does not exist") self.output.warning(f"Source path for binary {binary['binary']} does not exist")
continue continue
for bin in Path(src_path).glob(binary["binary"] + "*[.exe|.dll|.so|.dylib|.so.|.pdb]*"): for bin in Path(src_path).glob(binary["binary"] + "*[.exe|.dll|.so|.dylib|.so.]*"):
binaries.append((str(bin), binary["dst"])) binaries.append((str(bin), binary["dst"]))
for bin in Path(src_path).glob(binary["binary"]): for bin in Path(src_path).glob(binary["binary"]):
binaries.append((str(bin), binary["dst"])) binaries.append((str(bin), binary["dst"]))
@ -320,6 +331,8 @@ class CuraConan(ConanFile):
self.options["openssl"].shared = True self.options["openssl"].shared = True
if self.conf.get("user.curaengine:sentry_url", "", check_type=str) != "": if self.conf.get("user.curaengine:sentry_url", "", check_type=str) != "":
self.options["curaengine"].enable_sentry = True self.options["curaengine"].enable_sentry = True
self.options["arcus"].enable_sentry = True
self.options["clipper"].enable_sentry = True
def validate(self): def validate(self):
version = self.conf.get("user.cura:version", default = self.version, check_type = str) version = self.conf.get("user.cura:version", default = self.version, check_type = str)
@ -335,6 +348,7 @@ class CuraConan(ConanFile):
for req in self.conan_data["requirements_internal"]: for req in self.conan_data["requirements_internal"]:
self.requires(req) self.requires(req)
self.requires("cpython/3.10.4@ultimaker/stable") self.requires("cpython/3.10.4@ultimaker/stable")
self.requires("clipper/6.4.2@ultimaker/stable")
self.requires("openssl/3.2.0") self.requires("openssl/3.2.0")
self.requires("boost/1.82.0") self.requires("boost/1.82.0")
self.requires("spdlog/1.12.0") self.requires("spdlog/1.12.0")
@ -417,7 +431,6 @@ class CuraConan(ConanFile):
) )
if self.options.get_safe("enable_i18n", False) and self._i18n_options["extract"]: if self.options.get_safe("enable_i18n", False) and self._i18n_options["extract"]:
# Update the po and pot files
vb = VirtualBuildEnv(self) vb = VirtualBuildEnv(self)
vb.generate() vb.generate()
@ -502,10 +515,14 @@ echo "CURA_APP_NAME={{ cura_app_name }}" >> ${{ env_prefix }}GITHUB_ENV
if self.in_local_cache: if self.in_local_cache:
self.runenv_info.append_path("PYTHONPATH", os.path.join(self.package_folder, "site-packages")) self.runenv_info.append_path("PYTHONPATH", os.path.join(self.package_folder, "site-packages"))
self.env_info.PYTHONPATH.append(os.path.join(self.package_folder, "site-packages"))
self.runenv_info.append_path("PYTHONPATH", os.path.join(self.package_folder, "plugins")) self.runenv_info.append_path("PYTHONPATH", os.path.join(self.package_folder, "plugins"))
self.env_info.PYTHONPATH.append(os.path.join(self.package_folder, "plugins"))
else: else:
self.runenv_info.append_path("PYTHONPATH", self.source_folder) self.runenv_info.append_path("PYTHONPATH", self.source_folder)
self.env_info.PYTHONPATH.append(self.source_folder)
self.runenv_info.append_path("PYTHONPATH", os.path.join(self.source_folder, "plugins")) self.runenv_info.append_path("PYTHONPATH", os.path.join(self.source_folder, "plugins"))
self.env_info.PYTHONPATH.append(os.path.join(self.source_folder, "plugins"))
def package_id(self): def package_id(self):
self.info.clear() self.info.clear()
@ -518,7 +535,8 @@ echo "CURA_APP_NAME={{ cura_app_name }}" >> ${{ env_prefix }}GITHUB_ENV
del self.info.options.cloud_api_version del self.info.options.cloud_api_version
del self.info.options.display_name del self.info.options.display_name
del self.info.options.cura_debug_mode del self.info.options.cura_debug_mode
self.options.rm_safe("enable_i18n") if self.options.get_safe("enable_i18n", False):
del self.info.options.enable_i18n
# TODO: Use the hash of requirements.txt and requirements-ultimaker.txt, Because changing these will actually result in a different # TODO: Use the hash of requirements.txt and requirements-ultimaker.txt, Because changing these will actually result in a different
# Cura. This is needed because the requirements.txt aren't managed by Conan and therefor not resolved in the package_id. This isn't # Cura. This is needed because the requirements.txt aren't managed by Conan and therefor not resolved in the package_id. This isn't

View file

@ -3,10 +3,11 @@
from typing import List, cast from typing import List, cast
from PyQt6.QtCore import QObject, QUrl, QMimeData from PyQt6.QtCore import QObject, QUrl, pyqtSignal, pyqtProperty
from PyQt6.QtGui import QDesktopServices from PyQt6.QtGui import QDesktopServices
from PyQt6.QtWidgets import QApplication from PyQt6.QtWidgets import QApplication
from UM.Application import Application
from UM.Event import CallFunctionEvent from UM.Event import CallFunctionEvent
from UM.FlameProfiler import pyqtSlot from UM.FlameProfiler import pyqtSlot
from UM.Math.Vector import Vector from UM.Math.Vector import Vector
@ -37,6 +38,10 @@ class CuraActions(QObject):
def __init__(self, parent: QObject = None) -> None: def __init__(self, parent: QObject = None) -> None:
super().__init__(parent) super().__init__(parent)
self._operation_stack = Application.getInstance().getOperationStack()
self._operation_stack.changed.connect(self._onUndoStackChanged)
undoStackChanged = pyqtSignal()
@pyqtSlot() @pyqtSlot()
def openDocumentation(self) -> None: def openDocumentation(self) -> None:
# Starting a web browser from a signal handler connected to a menu will crash on windows. # Starting a web browser from a signal handler connected to a menu will crash on windows.
@ -45,6 +50,25 @@ class CuraActions(QObject):
event = CallFunctionEvent(self._openUrl, [QUrl("https://ultimaker.com/en/resources/manuals/software?utm_source=cura&utm_medium=software&utm_campaign=dropdown-documentation")], {}) event = CallFunctionEvent(self._openUrl, [QUrl("https://ultimaker.com/en/resources/manuals/software?utm_source=cura&utm_medium=software&utm_campaign=dropdown-documentation")], {})
cura.CuraApplication.CuraApplication.getInstance().functionEvent(event) cura.CuraApplication.CuraApplication.getInstance().functionEvent(event)
@pyqtProperty(bool, notify=undoStackChanged)
def canUndo(self):
return self._operation_stack.canUndo()
@pyqtProperty(bool, notify=undoStackChanged)
def canRedo(self):
return self._operation_stack.canRedo()
@pyqtSlot()
def undo(self):
self._operation_stack.undo()
@pyqtSlot()
def redo(self):
self._operation_stack.redo()
def _onUndoStackChanged(self):
self.undoStackChanged.emit()
@pyqtSlot() @pyqtSlot()
def openBugReportPage(self) -> None: def openBugReportPage(self) -> None:
event = CallFunctionEvent(self._openUrl, [QUrl("https://github.com/Ultimaker/Cura/issues/new/choose")], {}) event = CallFunctionEvent(self._openUrl, [QUrl("https://github.com/Ultimaker/Cura/issues/new/choose")], {})

View file

@ -15,13 +15,13 @@ import numpy
from PyQt6.QtCore import QObject, QTimer, QUrl, QUrlQuery, pyqtSignal, pyqtProperty, QEvent, pyqtEnum, QCoreApplication, \ from PyQt6.QtCore import QObject, QTimer, QUrl, QUrlQuery, pyqtSignal, pyqtProperty, QEvent, pyqtEnum, QCoreApplication, \
QByteArray QByteArray
from PyQt6.QtGui import QColor, QIcon from PyQt6.QtGui import QColor, QIcon
from PyQt6.QtQml import qmlRegisterUncreatableType, qmlRegisterUncreatableMetaObject, qmlRegisterSingletonType, qmlRegisterType from PyQt6.QtQml import qmlRegisterUncreatableMetaObject, qmlRegisterSingletonType, qmlRegisterType
from PyQt6.QtWidgets import QMessageBox from PyQt6.QtWidgets import QMessageBox
import UM.Util import UM.Util
import cura.Settings.cura_empty_instance_containers import cura.Settings.cura_empty_instance_containers
from UM.Application import Application from UM.Application import Application
from UM.Decorators import override from UM.Decorators import override, deprecated
from UM.FlameProfiler import pyqtSlot from UM.FlameProfiler import pyqtSlot
from UM.Logger import Logger from UM.Logger import Logger
from UM.Math.AxisAlignedBox import AxisAlignedBox from UM.Math.AxisAlignedBox import AxisAlignedBox
@ -104,7 +104,8 @@ from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel
from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager
from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager
from cura.UI import CuraSplashScreen, MachineActionManager, PrintInformation from cura.UI import CuraSplashScreen, PrintInformation
from cura.UI.MachineActionManager import MachineActionManager
from cura.UI.AddPrinterPagesModel import AddPrinterPagesModel from cura.UI.AddPrinterPagesModel import AddPrinterPagesModel
from cura.UI.MachineSettingsManager import MachineSettingsManager from cura.UI.MachineSettingsManager import MachineSettingsManager
from cura.UI.ObjectsModel import ObjectsModel from cura.UI.ObjectsModel import ObjectsModel
@ -180,6 +181,7 @@ class CuraApplication(QtApplication):
# Variables set from CLI # Variables set from CLI
self._files_to_open = [] self._files_to_open = []
self._urls_to_open = []
self._use_single_instance = False self._use_single_instance = False
self._single_instance = None self._single_instance = None
@ -187,12 +189,12 @@ class CuraApplication(QtApplication):
self._cura_formula_functions = None # type: Optional[CuraFormulaFunctions] self._cura_formula_functions = None # type: Optional[CuraFormulaFunctions]
self._machine_action_manager = None # type: Optional[MachineActionManager.MachineActionManager] self._machine_action_manager: Optional[MachineActionManager] = None
self.empty_container = None # type: EmptyInstanceContainer self.empty_container = None # type: EmptyInstanceContainer
self.empty_definition_changes_container = None # type: EmptyInstanceContainer self.empty_definition_changes_container = None # type: EmptyInstanceContainer
self.empty_variant_container = None # type: EmptyInstanceContainer self.empty_variant_container = None # type: EmptyInstanceContainer
self.empty_intent_container = None # type: EmptyInstanceContainer self.empty_intent_container = None # type: EmptyInstanceContainer
self.empty_material_container = None # type: EmptyInstanceContainer self.empty_material_container = None # type: EmptyInstanceContainer
self.empty_quality_container = None # type: EmptyInstanceContainer self.empty_quality_container = None # type: EmptyInstanceContainer
self.empty_quality_changes_container = None # type: EmptyInstanceContainer self.empty_quality_changes_container = None # type: EmptyInstanceContainer
@ -335,7 +337,7 @@ class CuraApplication(QtApplication):
for filename in self._cli_args.file: for filename in self._cli_args.file:
url = QUrl(filename) url = QUrl(filename)
if url.scheme() in self._supported_url_schemes: if url.scheme() in self._supported_url_schemes:
self._open_url_queue.append(url) self._urls_to_open.append(url)
else: else:
self._files_to_open.append(os.path.abspath(filename)) self._files_to_open.append(os.path.abspath(filename))
@ -354,11 +356,11 @@ class CuraApplication(QtApplication):
self.__addAllEmptyContainers() self.__addAllEmptyContainers()
self.__setLatestResouceVersionsForVersionUpgrade() self.__setLatestResouceVersionsForVersionUpgrade()
self._machine_action_manager = MachineActionManager.MachineActionManager(self) self._machine_action_manager = MachineActionManager(self)
self._machine_action_manager.initialize() self._machine_action_manager.initialize()
def __sendCommandToSingleInstance(self): def __sendCommandToSingleInstance(self):
self._single_instance = SingleInstance(self, self._files_to_open) self._single_instance = SingleInstance(self, self._files_to_open, self._urls_to_open)
# If we use single instance, try to connect to the single instance server, send commands, and then exit. # If we use single instance, try to connect to the single instance server, send commands, and then exit.
# If we cannot find an existing single instance server, this is the only instance, so just keep going. # If we cannot find an existing single instance server, this is the only instance, so just keep going.
@ -375,9 +377,15 @@ class CuraApplication(QtApplication):
Resources.addExpectedDirNameInData(dir_name) Resources.addExpectedDirNameInData(dir_name)
app_root = os.path.abspath(os.path.join(os.path.dirname(sys.executable))) app_root = os.path.abspath(os.path.join(os.path.dirname(sys.executable)))
Resources.addSecureSearchPath(os.path.join(app_root, "share", "cura", "resources"))
Resources.addSecureSearchPath(os.path.join(self._app_install_dir, "share", "cura", "resources")) if platform.system() == "Darwin":
Resources.addSecureSearchPath(os.path.join(app_root, "Resources", "share", "cura", "resources"))
Resources.addSecureSearchPath(
os.path.join(self._app_install_dir, "Resources", "share", "cura", "resources"))
else:
Resources.addSecureSearchPath(os.path.join(app_root, "share", "cura", "resources"))
Resources.addSecureSearchPath(os.path.join(self._app_install_dir, "share", "cura", "resources"))
if not hasattr(sys, "frozen"): if not hasattr(sys, "frozen"):
cura_data_root = os.environ.get('CURA_DATA_ROOT', None) cura_data_root = os.environ.get('CURA_DATA_ROOT', None)
if cura_data_root: if cura_data_root:
@ -959,6 +967,8 @@ class CuraApplication(QtApplication):
self.callLater(self._openFile, file_name) self.callLater(self._openFile, file_name)
for file_name in self._open_file_queue: # Open all the files that were queued up while plug-ins were loading. for file_name in self._open_file_queue: # Open all the files that were queued up while plug-ins were loading.
self.callLater(self._openFile, file_name) self.callLater(self._openFile, file_name)
for url in self._urls_to_open:
self.callLater(self._openUrl, url)
for url in self._open_url_queue: for url in self._open_url_queue:
self.callLater(self._openUrl, url) self.callLater(self._openUrl, url)
@ -1098,6 +1108,10 @@ class CuraApplication(QtApplication):
self._object_manager = ObjectsModel(self) self._object_manager = ObjectsModel(self)
return self._object_manager return self._object_manager
@pyqtSlot(str, result = "QVariantList")
def getSupportedActionMachineList(self, definition_id: str) -> List["MachineAction"]:
return self._machine_action_manager.getSupportedActions(self._machine_manager.getDefinitionByMachineId(definition_id))
@pyqtSlot(result = QObject) @pyqtSlot(result = QObject)
def getExtrudersModel(self, *args) -> "ExtrudersModel": def getExtrudersModel(self, *args) -> "ExtrudersModel":
if self._extruders_model is None: if self._extruders_model is None:
@ -1133,14 +1147,16 @@ class CuraApplication(QtApplication):
self._setting_inheritance_manager = SettingInheritanceManager.createSettingInheritanceManager() self._setting_inheritance_manager = SettingInheritanceManager.createSettingInheritanceManager()
return self._setting_inheritance_manager return self._setting_inheritance_manager
def getMachineActionManager(self, *args: Any) -> MachineActionManager.MachineActionManager: @pyqtSlot(result = QObject)
def getMachineActionManager(self, *args: Any) -> MachineActionManager:
"""Get the machine action manager """Get the machine action manager
We ignore any *args given to this, as we also register the machine manager as qml singleton. We ignore any *args given to this, as we also register the machine manager as qml singleton.
It wants to give this function an engine and script engine, but we don't care about that. It wants to give this function an engine and script engine, but we don't care about that.
""" """
return cast(MachineActionManager.MachineActionManager, self._machine_action_manager) return self._machine_action_manager
@pyqtSlot(result = QObject) @pyqtSlot(result = QObject)
def getMaterialManagementModel(self) -> MaterialManagementModel: def getMaterialManagementModel(self) -> MaterialManagementModel:
@ -1154,7 +1170,8 @@ class CuraApplication(QtApplication):
self._quality_management_model = QualityManagementModel(parent = self) self._quality_management_model = QualityManagementModel(parent = self)
return self._quality_management_model return self._quality_management_model
def getSimpleModeSettingsManager(self, *args): @pyqtSlot(result=QObject)
def getSimpleModeSettingsManager(self)-> SimpleModeSettingsManager:
if self._simple_mode_settings_manager is None: if self._simple_mode_settings_manager is None:
self._simple_mode_settings_manager = SimpleModeSettingsManager() self._simple_mode_settings_manager = SimpleModeSettingsManager()
return self._simple_mode_settings_manager return self._simple_mode_settings_manager
@ -1197,16 +1214,43 @@ class CuraApplication(QtApplication):
return self._print_information return self._print_information
def getQualityProfilesDropDownMenuModel(self, *args, **kwargs): @pyqtSlot(result=QObject)
def getQualityProfilesDropDownMenuModel(self, *args, **kwargs)-> QualityProfilesDropDownMenuModel:
if self._quality_profile_drop_down_menu_model is None: if self._quality_profile_drop_down_menu_model is None:
self._quality_profile_drop_down_menu_model = QualityProfilesDropDownMenuModel(self) self._quality_profile_drop_down_menu_model = QualityProfilesDropDownMenuModel(self)
return self._quality_profile_drop_down_menu_model return self._quality_profile_drop_down_menu_model
def getCustomQualityProfilesDropDownMenuModel(self, *args, **kwargs): @pyqtSlot(result=QObject)
def getCustomQualityProfilesDropDownMenuModel(self, *args, **kwargs)->CustomQualityProfilesDropDownMenuModel:
if self._custom_quality_profile_drop_down_menu_model is None: if self._custom_quality_profile_drop_down_menu_model is None:
self._custom_quality_profile_drop_down_menu_model = CustomQualityProfilesDropDownMenuModel(self) self._custom_quality_profile_drop_down_menu_model = CustomQualityProfilesDropDownMenuModel(self)
return self._custom_quality_profile_drop_down_menu_model return self._custom_quality_profile_drop_down_menu_model
@deprecated("SimpleModeSettingsManager is deprecated and will be removed in major SDK release, Use getSimpleModeSettingsManager() instead", since = "5.7.0")
def getSimpleModeSettingsManagerWrapper(self, *args, **kwargs):
return self.getSimpleModeSettingsManager()
@deprecated("MachineActionManager is deprecated and will be removed in major SDK release, Use getMachineActionManager() instead", since="5.7.0")
def getMachineActionManagerWrapper(self, *args, **kwargs):
return self.getMachineActionManager()
@deprecated("QualityManagementModel is deprecated and will be removed in major SDK release, Use getQualityManagementModel() instead", since="5.7.0")
def getQualityManagementModelWrapper(self, *args, **kwargs):
return self.getQualityManagementModel()
@deprecated("MaterialManagementModel is deprecated and will be removed in major SDK release, Use getMaterialManagementModel() instead", since = "5.7.0")
def getMaterialManagementModelWrapper(self, *args, **kwargs):
return self.getMaterialManagementModel()
@deprecated("QualityProfilesDropDownMenuModel is deprecated and will be removed in major SDK release, Use getQualityProfilesDropDownMenuModel() instead", since = "5.7.0")
def getQualityProfilesDropDownMenuModelWrapper(self, *args, **kwargs):
return self.getQualityProfilesDropDownMenuModel()
@deprecated("CustomQualityProfilesDropDownMenuModel is deprecated and will be removed in major SDK release, Use getCustomQualityProfilesDropDownMenuModel() instead", since = "5.7.0")
def getCustomQualityProfilesDropDownMenuModelWrapper(self, *args, **kwargs):
return self.getCustomQualityProfilesDropDownMenuModel()
def getCuraAPI(self, *args, **kwargs) -> "CuraAPI": def getCuraAPI(self, *args, **kwargs) -> "CuraAPI":
return self._cura_API return self._cura_API
@ -1236,8 +1280,8 @@ class CuraApplication(QtApplication):
qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, self.getMachineManager, "MachineManager") qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, self.getMachineManager, "MachineManager")
qmlRegisterSingletonType(IntentManager, "Cura", 1, 6, self.getIntentManager, "IntentManager") qmlRegisterSingletonType(IntentManager, "Cura", 1, 6, self.getIntentManager, "IntentManager")
qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, self.getSettingInheritanceManager, "SettingInheritanceManager") qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, self.getSettingInheritanceManager, "SettingInheritanceManager")
qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, self.getSimpleModeSettingsManager, "SimpleModeSettingsManager") qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, self.getSimpleModeSettingsManagerWrapper, "SimpleModeSettingsManager")
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, self.getMachineActionManager, "MachineActionManager") qmlRegisterSingletonType(MachineActionManager, "Cura", 1, 0, self.getMachineActionManagerWrapper, "MachineActionManager")
self.processEvents() self.processEvents()
qmlRegisterType(NetworkingUtil, "Cura", 1, 5, "NetworkingUtil") qmlRegisterType(NetworkingUtil, "Cura", 1, 5, "NetworkingUtil")
@ -1262,16 +1306,14 @@ class CuraApplication(QtApplication):
qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel") qmlRegisterType(FavoriteMaterialsModel, "Cura", 1, 0, "FavoriteMaterialsModel")
qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel") qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel")
qmlRegisterType(MaterialBrandsModel, "Cura", 1, 0, "MaterialBrandsModel") qmlRegisterType(MaterialBrandsModel, "Cura", 1, 0, "MaterialBrandsModel")
qmlRegisterSingletonType(QualityManagementModel, "Cura", 1, 0, self.getQualityManagementModel, "QualityManagementModel") qmlRegisterSingletonType(QualityManagementModel, "Cura", 1, 0, self.getQualityManagementModelWrapper,"QualityManagementModel")
qmlRegisterSingletonType(MaterialManagementModel, "Cura", 1, 5, self.getMaterialManagementModel, "MaterialManagementModel") qmlRegisterSingletonType(MaterialManagementModel, "Cura", 1, 5, self.getMaterialManagementModelWrapper,"MaterialManagementModel")
self.processEvents() self.processEvents()
qmlRegisterType(DiscoveredPrintersModel, "Cura", 1, 0, "DiscoveredPrintersModel") qmlRegisterType(DiscoveredPrintersModel, "Cura", 1, 0, "DiscoveredPrintersModel")
qmlRegisterType(DiscoveredCloudPrintersModel, "Cura", 1, 7, "DiscoveredCloudPrintersModel") qmlRegisterType(DiscoveredCloudPrintersModel, "Cura", 1, 7, "DiscoveredCloudPrintersModel")
qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0, qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0, self.getQualityProfilesDropDownMenuModelWrapper, "QualityProfilesDropDownMenuModel")
self.getQualityProfilesDropDownMenuModel, "QualityProfilesDropDownMenuModel") qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0, self.getCustomQualityProfilesDropDownMenuModelWrapper, "CustomQualityProfilesDropDownMenuModel")
qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0,
self.getCustomQualityProfilesDropDownMenuModel, "CustomQualityProfilesDropDownMenuModel")
qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel") qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
qmlRegisterType(IntentModel, "Cura", 1, 6, "IntentModel") qmlRegisterType(IntentModel, "Cura", 1, 6, "IntentModel")
qmlRegisterType(IntentCategoryModel, "Cura", 1, 6, "IntentCategoryModel") qmlRegisterType(IntentCategoryModel, "Cura", 1, 6, "IntentCategoryModel")

View file

@ -227,7 +227,7 @@ class ExtrudersModel(ListModel):
"material_brand": "", "material_brand": "",
"color_name": "", "color_name": "",
"material_type": "", "material_type": "",
"material_label": "" "material_name": ""
} }
items.append(item) items.append(item)
if self._items != items: if self._items != items:

View file

@ -40,6 +40,7 @@ class AuthorizationHelpers:
""" """
data = { data = {
"client_id": self._settings.CLIENT_ID if self._settings.CLIENT_ID is not None else "", "client_id": self._settings.CLIENT_ID if self._settings.CLIENT_ID is not None else "",
"client_secret": self._settings.CLIENT_SECRET if self._settings.CLIENT_SECRET is not None else "",
"redirect_uri": self._settings.CALLBACK_URL if self._settings.CALLBACK_URL is not None else "", "redirect_uri": self._settings.CALLBACK_URL if self._settings.CALLBACK_URL is not None else "",
"grant_type": "authorization_code", "grant_type": "authorization_code",
"code": authorization_code, "code": authorization_code,
@ -64,6 +65,7 @@ class AuthorizationHelpers:
Logger.log("d", "Refreshing the access token for [%s]", self._settings.OAUTH_SERVER_URL) Logger.log("d", "Refreshing the access token for [%s]", self._settings.OAUTH_SERVER_URL)
data = { data = {
"client_id": self._settings.CLIENT_ID if self._settings.CLIENT_ID is not None else "", "client_id": self._settings.CLIENT_ID if self._settings.CLIENT_ID is not None else "",
"client_secret": self._settings.CLIENT_SECRET if self._settings.CLIENT_SECRET is not None else "",
"redirect_uri": self._settings.CALLBACK_URL if self._settings.CALLBACK_URL is not None else "", "redirect_uri": self._settings.CALLBACK_URL if self._settings.CALLBACK_URL is not None else "",
"grant_type": "refresh_token", "grant_type": "refresh_token",
"refresh_token": refresh_token, "refresh_token": refresh_token,

View file

@ -31,20 +31,24 @@ class AuthorizationService:
account information. account information.
""" """
# Emit signal when authentication is completed. def __init__(self,
onAuthStateChanged = Signal() settings: "OAuth2Settings",
preferences: Optional["Preferences"] = None,
get_user_profile: bool = True) -> None:
# Emit signal when authentication is completed.
self.onAuthStateChanged = Signal()
# Emit signal when authentication failed. # Emit signal when authentication failed.
onAuthenticationError = Signal() self.onAuthenticationError = Signal()
accessTokenChanged = Signal() self.accessTokenChanged = Signal()
def __init__(self, settings: "OAuth2Settings", preferences: Optional["Preferences"] = None) -> None:
self._settings = settings self._settings = settings
self._auth_helpers = AuthorizationHelpers(settings) self._auth_helpers = AuthorizationHelpers(settings)
self._auth_url = "{}/authorize".format(self._settings.OAUTH_SERVER_URL) self._auth_url = "{}/authorize".format(self._settings.OAUTH_SERVER_URL)
self._auth_data: Optional[AuthenticationResponse] = None self._auth_data: Optional[AuthenticationResponse] = None
self._user_profile: Optional["UserProfile"] = None self._user_profile: Optional["UserProfile"] = None
self._get_user_profile: bool = get_user_profile
self._preferences = preferences self._preferences = preferences
self._server = LocalAuthorizationServer(self._auth_helpers, self._onAuthStateChanged, daemon=True) self._server = LocalAuthorizationServer(self._auth_helpers, self._onAuthStateChanged, daemon=True)
self._currently_refreshing_token = False # Whether we are currently in the process of refreshing auth. Don't make new requests while busy. self._currently_refreshing_token = False # Whether we are currently in the process of refreshing auth. Don't make new requests while busy.
@ -294,7 +298,8 @@ class AuthorizationService:
self._auth_data = auth_data self._auth_data = auth_data
self._currently_refreshing_token = False self._currently_refreshing_token = False
if auth_data: if auth_data:
self.getUserProfile() if self._get_user_profile:
self.getUserProfile()
self._preferences.setValue(self._settings.AUTH_DATA_PREFERENCE_KEY, json.dumps(auth_data.dump())) self._preferences.setValue(self._settings.AUTH_DATA_PREFERENCE_KEY, json.dumps(auth_data.dump()))
else: else:
Logger.log("d", "Clearing the user profile") Logger.log("d", "Clearing the user profile")

View file

@ -16,6 +16,7 @@ class OAuth2Settings(BaseModel):
CALLBACK_PORT = None # type: Optional[int] CALLBACK_PORT = None # type: Optional[int]
OAUTH_SERVER_URL = None # type: Optional[str] OAUTH_SERVER_URL = None # type: Optional[str]
CLIENT_ID = None # type: Optional[str] CLIENT_ID = None # type: Optional[str]
CLIENT_SECRET = None # type: Optional[str]
CLIENT_SCOPES = None # type: Optional[str] CLIENT_SCOPES = None # type: Optional[str]
CALLBACK_URL = None # type: Optional[str] CALLBACK_URL = None # type: Optional[str]
AUTH_DATA_PREFERENCE_KEY = "" # type: str AUTH_DATA_PREFERENCE_KEY = "" # type: str

View file

@ -316,7 +316,13 @@ class ExtruderManager(QObject):
# Starts with the adhesion extruder. # Starts with the adhesion extruder.
adhesion_type = global_stack.getProperty("adhesion_type", "value") adhesion_type = global_stack.getProperty("adhesion_type", "value")
if adhesion_type in {"skirt", "brim"}: if adhesion_type in {"skirt", "brim"}:
return max(0, int(global_stack.getProperty("skirt_brim_extruder_nr", "value"))) # optional skirt/brim extruder defaults to zero skirt_brim_extruder_nr = global_stack.getProperty("skirt_brim_extruder_nr", "value")
# if the skirt_brim_extruder_nr is -1, then we use the first used extruder
if skirt_brim_extruder_nr == -1:
used_extruders = self.getUsedExtruderStacks()
return used_extruders[0].position
else:
return skirt_brim_extruder_nr
if adhesion_type == "raft": if adhesion_type == "raft":
return global_stack.getProperty("raft_base_extruder_nr", "value") return global_stack.getProperty("raft_base_extruder_nr", "value")

View file

@ -5,16 +5,18 @@ import json
import os import os
from typing import List, Optional from typing import List, Optional
from PyQt6.QtCore import QUrl
from PyQt6.QtNetwork import QLocalServer, QLocalSocket from PyQt6.QtNetwork import QLocalServer, QLocalSocket
from UM.Qt.QtApplication import QtApplication #For typing. from UM.Qt.QtApplication import QtApplication # For typing.
from UM.Logger import Logger from UM.Logger import Logger
class SingleInstance: class SingleInstance:
def __init__(self, application: QtApplication, files_to_open: Optional[List[str]]) -> None: def __init__(self, application: QtApplication, files_to_open: Optional[List[str]], url_to_open: Optional[List[str]]) -> None:
self._application = application self._application = application
self._files_to_open = files_to_open self._files_to_open = files_to_open
self._url_to_open = url_to_open
self._single_instance_server = None self._single_instance_server = None
@ -33,7 +35,7 @@ class SingleInstance:
return False return False
# We only send the files that need to be opened. # We only send the files that need to be opened.
if not self._files_to_open: if not self._files_to_open and not self._url_to_open:
Logger.log("i", "No file need to be opened, do nothing.") Logger.log("i", "No file need to be opened, do nothing.")
return True return True
@ -55,8 +57,12 @@ class SingleInstance:
payload = {"command": "open", "filePath": os.path.abspath(filename)} payload = {"command": "open", "filePath": os.path.abspath(filename)}
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding = "ascii")) single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding = "ascii"))
for url in self._url_to_open:
payload = {"command": "open-url", "urlPath": url.toString()}
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ascii"))
payload = {"command": "close-connection"} payload = {"command": "close-connection"}
single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding = "ascii")) single_instance_socket.write(bytes(json.dumps(payload) + "\n", encoding="ascii"))
single_instance_socket.flush() single_instance_socket.flush()
single_instance_socket.waitForDisconnected() single_instance_socket.waitForDisconnected()
@ -72,7 +78,7 @@ class SingleInstance:
def _onClientConnected(self) -> None: def _onClientConnected(self) -> None:
Logger.log("i", "New connection received on our single-instance server") Logger.log("i", "New connection received on our single-instance server")
connection = None #type: Optional[QLocalSocket] connection = None # type: Optional[QLocalSocket]
if self._single_instance_server: if self._single_instance_server:
connection = self._single_instance_server.nextPendingConnection() connection = self._single_instance_server.nextPendingConnection()
@ -81,7 +87,7 @@ class SingleInstance:
def __readCommands(self, connection: QLocalSocket) -> None: def __readCommands(self, connection: QLocalSocket) -> None:
line = connection.readLine() line = connection.readLine()
while len(line) != 0: # There is also a .canReadLine() while len(line) != 0: # There is also a .canReadLine()
try: try:
payload = json.loads(str(line, encoding = "ascii").strip()) payload = json.loads(str(line, encoding = "ascii").strip())
command = payload["command"] command = payload["command"]
@ -94,13 +100,19 @@ class SingleInstance:
elif command == "open": elif command == "open":
self._application.callLater(lambda f = payload["filePath"]: self._application._openFile(f)) self._application.callLater(lambda f = payload["filePath"]: self._application._openFile(f))
#command: Load a url link in Cura
elif command == "open-url":
url = QUrl(payload["urlPath"])
self._application.callLater(lambda: self._application._openUrl(url))
# Command: Activate the window and bring it to the top. # Command: Activate the window and bring it to the top.
elif command == "focus": elif command == "focus":
# Operating systems these days prevent windows from moving around by themselves. # Operating systems these days prevent windows from moving around by themselves.
# 'alert' or flashing the icon in the taskbar is the best thing we do now. # 'alert' or flashing the icon in the taskbar is the best thing we do now.
main_window = self._application.getMainWindow() main_window = self._application.getMainWindow()
if main_window is not None: if main_window is not None:
self._application.callLater(lambda: main_window.alert(0)) # type: ignore # I don't know why MyPy complains here self._application.callLater(lambda: main_window.alert(0)) # type: ignore # I don't know why MyPy complains here
# Command: Close the socket connection. We're done. # Command: Close the socket connection. We're done.
elif command == "close-connection": elif command == "close-connection":

View file

@ -15,6 +15,10 @@ if "" in sys.path:
import argparse import argparse
import faulthandler import faulthandler
import os import os
# set the environment variable QT_QUICK_FLICKABLE_WHEEL_DECELERATION to 5000 as mentioned in qt6.6 update log to overcome scroll related issues
os.environ["QT_QUICK_FLICKABLE_WHEEL_DECELERATION"] = str(int(os.environ.get("QT_QUICK_FLICKABLE_WHEEL_DECELERATION", "5000")))
if sys.platform != "linux": # Turns out the Linux build _does_ use this, but we're not making an Enterprise release for that system anyway. if sys.platform != "linux": # Turns out the Linux build _does_ use this, but we're not making an Enterprise release for that system anyway.
os.environ["QT_PLUGIN_PATH"] = "" # Security workaround: Don't need it, and introduces an attack vector, so set to nul. os.environ["QT_PLUGIN_PATH"] = "" # Security workaround: Don't need it, and introduces an attack vector, so set to nul.
os.environ["QML2_IMPORT_PATH"] = "" # Security workaround: Don't need it, and introduces an attack vector, so set to nul. os.environ["QML2_IMPORT_PATH"] = "" # Security workaround: Don't need it, and introduces an attack vector, so set to nul.

View file

@ -10,11 +10,8 @@ from UM.Math.Vector import Vector
from UM.Logger import Logger from UM.Logger import Logger
from UM.Math.Matrix import Matrix from UM.Math.Matrix import Matrix
from UM.Application import Application from UM.Application import Application
from UM.Message import Message
from UM.Resources import Resources
from UM.Scene.SceneNode import SceneNode from UM.Scene.SceneNode import SceneNode
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.EmptyInstanceContainer import EmptyInstanceContainer
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
from cura.CuraPackageManager import CuraPackageManager from cura.CuraPackageManager import CuraPackageManager

View file

@ -35,6 +35,8 @@ message Slice
repeated EnginePlugin engine_plugins = 5; repeated EnginePlugin engine_plugins = 5;
string sentry_id = 6; // The anonymized Sentry user id that requested the slice string sentry_id = 6; // The anonymized Sentry user id that requested the slice
string cura_version = 7; // The version of Cura that requested the slice string cura_version = 7; // The version of Cura that requested the slice
optional string project_name = 8; // The name of the project that requested the slice
optional string user_name = 9; // The Digital Factory account name of the user that requested the slice
} }
message Extruder message Extruder

View file

@ -76,6 +76,7 @@ class CuraEngineBackend(QObject, Backend):
self._default_engine_location = executable_name self._default_engine_location = executable_name
search_path = [ search_path = [
os.path.abspath(os.path.join(os.path.dirname(sys.executable), "..", "Resources")),
os.path.abspath(os.path.dirname(sys.executable)), os.path.abspath(os.path.dirname(sys.executable)),
os.path.abspath(os.path.join(os.path.dirname(sys.executable), "bin")), os.path.abspath(os.path.join(os.path.dirname(sys.executable), "bin")),
os.path.abspath(os.path.join(os.path.dirname(sys.executable), "..")), os.path.abspath(os.path.join(os.path.dirname(sys.executable), "..")),
@ -164,6 +165,7 @@ class CuraEngineBackend(QObject, Backend):
application.getPreferences().addPreference("general/auto_slice", False) application.getPreferences().addPreference("general/auto_slice", False)
application.getPreferences().addPreference("info/send_engine_crash", True) application.getPreferences().addPreference("info/send_engine_crash", True)
application.getPreferences().addPreference("info/anonymous_engine_crash_report", True)
self._use_timer: bool = False self._use_timer: bool = False
@ -1094,14 +1096,14 @@ class CuraEngineBackend(QObject, Backend):
self._change_timer.timeout.disconnect(self.slice) self._change_timer.timeout.disconnect(self.slice)
def _onPreferencesChanged(self, preference: str) -> None: def _onPreferencesChanged(self, preference: str) -> None:
if preference != "general/auto_slice" and preference != "info/send_engine_crash": if preference != "general/auto_slice" and preference != "info/send_engine_crash" and preference != "info/anonymous_engine_crash_report":
return return
if preference == "general/auto_slice": if preference == "general/auto_slice":
auto_slice = self.determineAutoSlicing() auto_slice = self.determineAutoSlicing()
if auto_slice: if auto_slice:
self._change_timer.start() self._change_timer.start()
elif preference == "info/send_engine_crash": elif preference == "info/send_engine_crash":
os.environ["use_sentry"] = "1" if CuraApplication.getInstance().getPreferences().getValue("info/send_engine_crash") else "0" os.environ["USE_SENTRY"] = "1" if CuraApplication.getInstance().getPreferences().getValue("info/send_engine_crash") else "0"
def tickle(self) -> None: def tickle(self) -> None:
"""Tickle the backend so in case of auto slicing, it starts the timer.""" """Tickle the backend so in case of auto slicing, it starts the timer."""

View file

@ -1,4 +1,4 @@
# Copyright (c) 2023 UltiMaker # Copyright (c) 2024 UltiMaker
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import uuid import uuid
@ -63,13 +63,12 @@ class GcodeStartEndFormatter(Formatter):
# will be used. Alternatively, if the expression is formatted as "{[expression], [extruder_nr]}", # will be used. Alternatively, if the expression is formatted as "{[expression], [extruder_nr]}",
# then the expression will be evaluated with the extruder stack of the specified extruder_nr. # then the expression will be evaluated with the extruder stack of the specified extruder_nr.
_extruder_regex = re.compile(r"^\s*(?P<expression>.*)\s*,\s*(?P<extruder_nr>\d+)\s*$") _extruder_regex = re.compile(r"^\s*(?P<expression>.*)\s*,\s*(?P<extruder_nr_expr>.*)\s*$")
def __init__(self, default_extruder_nr: int = -1, *, def __init__(self, all_extruder_settings: Dict[str, Any], default_extruder_nr: int = -1) -> None:
additional_per_extruder_settings: Optional[Dict[str, Dict[str, any]]] = None) -> None:
super().__init__() super().__init__()
self._all_extruder_settings: Dict[str, Any] = all_extruder_settings
self._default_extruder_nr: int = default_extruder_nr self._default_extruder_nr: int = default_extruder_nr
self._additional_per_extruder_settings: Optional[Dict[str, Dict[str, any]]] = additional_per_extruder_settings
def get_field(self, field_name, args: [str], kwargs: dict) -> Tuple[str, str]: def get_field(self, field_name, args: [str], kwargs: dict) -> Tuple[str, str]:
# get_field method parses all fields in the format-string and parses them individually to the get_value method. # get_field method parses all fields in the format-string and parses them individually to the get_value method.
@ -88,22 +87,32 @@ class GcodeStartEndFormatter(Formatter):
if expression in post_slice_data_variables: if expression in post_slice_data_variables:
return f"{{{expression}}}" return f"{{{expression}}}"
extruder_nr = self._default_extruder_nr extruder_nr = str(self._default_extruder_nr)
# The settings may specify a specific extruder to use. This is done by # The settings may specify a specific extruder to use. This is done by
# formatting the expression as "{expression}, {extruder_nr}". If the # formatting the expression as "{expression}, {extruder_nr_expr}". If the
# expression is formatted like this, we extract the extruder_nr and use # expression is formatted like this, we extract the extruder_nr and use
# it to get the value from the correct extruder stack. # it to get the value from the correct extruder stack.
match = self._extruder_regex.match(expression) match = self._extruder_regex.match(expression)
if match: if match:
expression = match.group("expression") expression = match.group("expression")
extruder_nr = int(match.group("extruder_nr")) extruder_nr_expr = match.group("extruder_nr_expr")
if self._additional_per_extruder_settings is not None and str( if extruder_nr_expr.isdigit():
extruder_nr) in self._additional_per_extruder_settings: extruder_nr = extruder_nr_expr
additional_variables = self._additional_per_extruder_settings[str(extruder_nr)] else:
# We get the value of the extruder_nr_expr from `_all_extruder_settings` dictionary
# rather than the global container stack. The `_all_extruder_settings["-1"]` is a
# dict-representation of the global container stack, with additional properties such
# as `initial_extruder_nr`. As users may enter such expressions we can't use the
# global container stack.
extruder_nr = str(self._all_extruder_settings["-1"].get(extruder_nr_expr, "-1"))
if extruder_nr in self._all_extruder_settings:
additional_variables = self._all_extruder_settings[extruder_nr].copy()
else: else:
additional_variables = dict() Logger.warning(f"Extruder {extruder_nr} does not exist, using global settings")
additional_variables = self._all_extruder_settings["-1"].copy()
# Add the arguments and keyword arguments to the additional settings. These # Add the arguments and keyword arguments to the additional settings. These
# are currently _not_ used, but they are added for consistency with the # are currently _not_ used, but they are added for consistency with the
@ -113,15 +122,17 @@ class GcodeStartEndFormatter(Formatter):
for key, value in kwargs.items(): for key, value in kwargs.items():
additional_variables[key] = value additional_variables[key] = value
if extruder_nr == -1: if extruder_nr == "-1":
container_stack = CuraApplication.getInstance().getGlobalContainerStack() container_stack = CuraApplication.getInstance().getGlobalContainerStack()
else: else:
container_stack = ExtruderManager.getInstance().getExtruderStack(extruder_nr) container_stack = ExtruderManager.getInstance().getExtruderStack(extruder_nr)
if not container_stack:
Logger.warning(f"Extruder {extruder_nr} does not exist, using global settings")
container_stack = CuraApplication.getInstance().getGlobalContainerStack()
setting_function = SettingFunction(expression) setting_function = SettingFunction(expression)
value = setting_function(container_stack, additional_variables=additional_variables) value = setting_function(container_stack, additional_variables=additional_variables)
return value return value
@ -131,12 +142,13 @@ class StartSliceJob(Job):
def __init__(self, slice_message: Arcus.PythonMessage) -> None: def __init__(self, slice_message: Arcus.PythonMessage) -> None:
super().__init__() super().__init__()
self._scene = CuraApplication.getInstance().getController().getScene() #type: Scene self._scene: Scene = CuraApplication.getInstance().getController().getScene()
self._slice_message: Arcus.PythonMessage = slice_message self._slice_message: Arcus.PythonMessage = slice_message
self._is_cancelled = False #type: bool self._is_cancelled: bool = False
self._build_plate_number = None #type: Optional[int] self._build_plate_number: Optional[int] = None
self._all_extruders_settings = None #type: Optional[Dict[str, Any]] # cache for all setting values from all stacks (global & extruder) for the current machine # cache for all setting values from all stacks (global & extruder) for the current machine
self._all_extruders_settings: Optional[Dict[str, Any]] = None
def getSliceMessage(self) -> Arcus.PythonMessage: def getSliceMessage(self) -> Arcus.PythonMessage:
return self._slice_message return self._slice_message
@ -340,6 +352,12 @@ class StartSliceJob(Job):
self._slice_message.sentry_id = f"{user_id}" self._slice_message.sentry_id = f"{user_id}"
self._slice_message.cura_version = CuraVersion self._slice_message.cura_version = CuraVersion
# Add the project name to the message if the user allows for non-anonymous crash data collection.
account = CuraApplication.getInstance().getCuraAPI().account
if account and account.isLoggedIn and not CuraApplication.getInstance().getPreferences().getValue("info/anonymous_engine_crash_report"):
self._slice_message.project_name = CuraApplication.getInstance().getPrintInformation().baseName
self._slice_message.user_name = account.userName
# Build messages for extruder stacks # Build messages for extruder stacks
for extruder_stack in global_stack.extruderList: for extruder_stack in global_stack.extruderList:
self._buildExtruderMessage(extruder_stack) self._buildExtruderMessage(extruder_stack)
@ -471,10 +489,7 @@ class StartSliceJob(Job):
# Get "replacement-keys" for the extruders. In the formatter the settings stack is used to get the # Get "replacement-keys" for the extruders. In the formatter the settings stack is used to get the
# replacement values for the setting-keys. However, the values for `material_id`, `material_type`, # replacement values for the setting-keys. However, the values for `material_id`, `material_type`,
# etc are not in the settings stack. # etc are not in the settings stack.
additional_per_extruder_settings = self._all_extruders_settings.copy() fmt = GcodeStartEndFormatter(self._all_extruders_settings, default_extruder_nr=default_extruder_nr)
additional_per_extruder_settings["default_extruder_nr"] = default_extruder_nr
fmt = GcodeStartEndFormatter(default_extruder_nr=default_extruder_nr,
additional_per_extruder_settings=additional_per_extruder_settings)
return str(fmt.format(value)) return str(fmt.format(value))
except: except:
Logger.logException("w", "Unable to do token replacement on start/end g-code") Logger.logException("w", "Unable to do token replacement on start/end g-code")

View file

@ -1,7 +1,6 @@
# Copyright (c) 2021 Ultimaker B.V. # Copyright (c) 2021 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
from .src import DigitalFactoryFileProvider, DigitalFactoryOutputDevicePlugin, DigitalFactoryController from .src import DigitalFactoryFileProvider, DigitalFactoryOutputDevicePlugin, DigitalFactoryController

View file

@ -3,7 +3,6 @@
import json import json
from json import JSONDecodeError from json import JSONDecodeError
import re
from time import time from time import time
from typing import List, Any, Optional, Union, Type, Tuple, Dict, cast, TypeVar, Callable from typing import List, Any, Optional, Union, Type, Tuple, Dict, cast, TypeVar, Callable

View file

@ -4,7 +4,6 @@ from typing import List, Optional
from PyQt6.QtCore import Qt, pyqtSignal from PyQt6.QtCore import Qt, pyqtSignal
from UM.Logger import Logger
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
from .DigitalFactoryProjectResponse import DigitalFactoryProjectResponse from .DigitalFactoryProjectResponse import DigitalFactoryProjectResponse

View file

@ -2,7 +2,6 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Platform import Platform
from . import GCodeGzWriter from . import GCodeGzWriter

View file

@ -11,7 +11,6 @@ from UM.Settings.InstanceContainer import InstanceContainer
from cura.Machines.ContainerTree import ContainerTree from cura.Machines.ContainerTree import ContainerTree
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from cura.Settings.CuraStackBuilder import CuraStackBuilder
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")

View file

@ -3,12 +3,10 @@
from typing import Optional, TYPE_CHECKING, Dict, List from typing import Optional, TYPE_CHECKING, Dict, List
from .Constants import PACKAGES_URL
from .PackageModel import PackageModel from .PackageModel import PackageModel
from .RemotePackageList import RemotePackageList from .RemotePackageList import RemotePackageList
from PyQt6.QtCore import pyqtSignal, QObject, pyqtProperty, QCoreApplication 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 from UM.i18n import i18nCatalog
if TYPE_CHECKING: if TYPE_CHECKING:

View file

@ -2,7 +2,6 @@
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import re import re
from enum import Enum
from typing import Any, cast, Dict, List, Optional from typing import Any, cast, Dict, List, Optional
from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal, pyqtSlot from PyQt6.QtCore import pyqtProperty, QObject, pyqtSignal, pyqtSlot
@ -12,7 +11,6 @@ from cura.CuraApplication import CuraApplication
from cura.CuraPackageManager import CuraPackageManager from cura.CuraPackageManager import CuraPackageManager
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry # To get names of materials we're compatible with. from cura.Settings.CuraContainerRegistry import CuraContainerRegistry # To get names of materials we're compatible with.
from UM.i18n import i18nCatalog # To translate placeholder names if data is not present. from UM.i18n import i18nCatalog # To translate placeholder names if data is not present.
from UM.Logger import Logger
from UM.PluginRegistry import PluginRegistry from UM.PluginRegistry import PluginRegistry
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")

View file

@ -25,7 +25,7 @@ UM.TooltipArea
onClicked: onClicked:
{ {
addedSettingsModel.setVisible(model.key, checked); addedSettingsModel.setVisible(model.key, checked);
UM.ActiveTool.forceUpdate(); UM.Controller.forceUpdate();
} }
} }

View file

@ -11,7 +11,7 @@ from UM.Settings.SettingInstance import SettingInstance
from UM.Logger import Logger from UM.Logger import Logger
import UM.Settings.Models.SettingVisibilityHandler import UM.Settings.Models.SettingVisibilityHandler
from cura.Settings.ExtruderManager import ExtruderManager #To get global-inherits-stack setting values from different extruders. from cura.Settings.ExtruderManager import ExtruderManager # To get global-inherits-stack setting values from different extruders.
from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator

View file

@ -23,7 +23,7 @@ Item
readonly property string infillMeshType: "infill_mesh" readonly property string infillMeshType: "infill_mesh"
readonly property string antiOverhangMeshType: "anti_overhang_mesh" readonly property string antiOverhangMeshType: "anti_overhang_mesh"
property var currentMeshType: UM.ActiveTool.properties.getValue("MeshType") property var currentMeshType: UM.Controller.properties.getValue("MeshType")
// Update the view every time the currentMeshType changes // Update the view every time the currentMeshType changes
onCurrentMeshTypeChanged: onCurrentMeshTypeChanged:
@ -56,7 +56,7 @@ Item
function setMeshType(type) function setMeshType(type)
{ {
UM.ActiveTool.setProperty("MeshType", type) UM.Controller.setProperty("MeshType", type)
updateMeshTypeCheckedState(type) updateMeshTypeCheckedState(type)
} }
@ -224,7 +224,7 @@ Item
visibilityHandler: Cura.PerObjectSettingVisibilityHandler visibilityHandler: Cura.PerObjectSettingVisibilityHandler
{ {
id: visibility_handler id: visibility_handler
selectedObjectId: UM.ActiveTool.properties.getValue("SelectedObjectId") selectedObjectId: UM.Controller.properties.getValue("SelectedObjectId")
} }
// For some reason the model object is updated after removing him from the memory and // For some reason the model object is updated after removing him from the memory and
@ -320,7 +320,7 @@ Item
{ {
id: provider id: provider
containerStackId: UM.ActiveTool.properties.getValue("ContainerID") containerStackId: UM.Controller.properties.getValue("ContainerID")
key: model.key key: model.key
watchedProperties: [ "value", "enabled", "validationState" ] watchedProperties: [ "value", "enabled", "validationState" ]
storeIndex: 0 storeIndex: 0
@ -330,7 +330,7 @@ Item
UM.SettingPropertyProvider UM.SettingPropertyProvider
{ {
id: inheritStackProvider id: inheritStackProvider
containerStackId: UM.ActiveTool.properties.getValue("ContainerID") containerStackId: UM.Controller.properties.getValue("ContainerID")
key: model.key key: model.key
watchedProperties: [ "limit_to_extruder" ] watchedProperties: [ "limit_to_extruder" ]
} }
@ -381,22 +381,22 @@ Item
Connections Connections
{ {
target: UM.ActiveTool target: UM.Controller
function onPropertiesChanged() function onPropertiesChanged()
{ {
// the values cannot be bound with UM.ActiveTool.properties.getValue() calls, // the values cannot be bound with UM.Controller.properties.getValue() calls,
// so here we connect to the signal and update the those values. // so here we connect to the signal and update the those values.
if (typeof UM.ActiveTool.properties.getValue("SelectedObjectId") !== "undefined") if (typeof UM.Controller.properties.getValue("SelectedObjectId") !== "undefined")
{ {
const selectedObjectId = UM.ActiveTool.properties.getValue("SelectedObjectId") const selectedObjectId = UM.Controller.properties.getValue("SelectedObjectId")
if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId) if (addedSettingsModel.visibilityHandler.selectedObjectId != selectedObjectId)
{ {
addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId addedSettingsModel.visibilityHandler.selectedObjectId = selectedObjectId
} }
} }
if (typeof UM.ActiveTool.properties.getValue("ContainerID") !== "undefined") if (typeof UM.Controller.properties.getValue("ContainerID") !== "undefined")
{ {
const containerId = UM.ActiveTool.properties.getValue("ContainerID") const containerId = UM.Controller.properties.getValue("ContainerID")
if (provider.containerStackId !== containerId) if (provider.containerStackId !== containerId)
{ {
provider.containerStackId = containerId provider.containerStackId = containerId

View file

@ -21,7 +21,7 @@
# M163 - Set Mix Factor # M163 - Set Mix Factor
# M164 - Save Mix - saves to T2 as a unique mix # M164 - Save Mix - saves to T2 as a unique mix
import re #To perform the search and replace. import re # To perform the search and replace.
from ..Script import Script from ..Script import Script
class ColorMix(Script): class ColorMix(Script):

View file

@ -6,7 +6,6 @@
# Description: This plugin is now an option in 'Display Info on LCD' # Description: This plugin is now an option in 'Display Info on LCD'
from ..Script import Script from ..Script import Script
from UM.Application import Application
from UM.Message import Message from UM.Message import Message
class DisplayFilenameAndLayerOnLCD(Script): class DisplayFilenameAndLayerOnLCD(Script):

View file

@ -30,9 +30,6 @@
from ..Script import Script from ..Script import Script
from UM.Application import Application from UM.Application import Application
from UM.Qt.Duration import DurationFormat from UM.Qt.Duration import DurationFormat
import UM.Util
import configparser
from UM.Preferences import Preferences
import time import time
import datetime import datetime
import math import math

View file

@ -7,8 +7,6 @@
from ..Script import Script from ..Script import Script
import re
import datetime
from UM.Message import Message from UM.Message import Message
class DisplayProgressOnLCD(Script): class DisplayProgressOnLCD(Script):

View file

@ -7,7 +7,7 @@
from typing import List from typing import List
from ..Script import Script from ..Script import Script
from UM.Application import Application #To get the current printer's settings. from UM.Application import Application # To get the current printer's settings.
class FilamentChange(Script): class FilamentChange(Script):

View file

@ -7,7 +7,7 @@
from ..Script import Script from ..Script import Script
import re import re
from UM.Application import Application #To get the current printer's settings. from UM.Application import Application # To get the current printer's settings.
from UM.Logger import Logger from UM.Logger import Logger
from typing import List, Tuple from typing import List, Tuple

View file

@ -1,7 +1,7 @@
# Copyright (c) 2017 Ghostkeeper # Copyright (c) 2017 Ghostkeeper
# The PostProcessingPlugin is released under the terms of the LGPLv3 or higher. # The PostProcessingPlugin is released under the terms of the LGPLv3 or higher.
import re #To perform the search and replace. import re # To perform the search and replace.
from ..Script import Script from ..Script import Script

View file

@ -8,7 +8,7 @@ from UM.Application import Application
from UM.Logger import Logger from UM.Logger import Logger
from UM.Message import Message from UM.Message import Message
from UM.FileHandler.WriteFileJob import WriteFileJob from UM.FileHandler.WriteFileJob import WriteFileJob
from UM.FileHandler.FileWriter import FileWriter #To check against the write modes (text vs. binary). from UM.FileHandler.FileWriter import FileWriter # To check against the write modes (text vs. binary).
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
from UM.OutputDevice.OutputDevice import OutputDevice from UM.OutputDevice.OutputDevice import OutputDevice
from UM.OutputDevice import OutputDeviceError from UM.OutputDevice import OutputDeviceError

View file

@ -372,7 +372,10 @@ class SimulationView(CuraView):
self._minimum_path_num = min(self._minimum_path_num, self._current_path_num) self._minimum_path_num = min(self._minimum_path_num, self._current_path_num)
# update _current time when the path is changed by user # update _current time when the path is changed by user
if self._current_path_num < self._max_paths and round(self._current_path_num)== self._current_path_num: if self._current_path_num < self._max_paths and round(self._current_path_num)== self._current_path_num:
self._current_time = self.cumulativeLineDuration()[int(self._current_path_num)] actual_path_num = int(self._current_path_num)
cumulative_line_duration = self.cumulativeLineDuration()
if actual_path_num < len(cumulative_line_duration):
self._current_time = cumulative_line_duration[actual_path_num]
self._startUpdateTopLayers() self._startUpdateTopLayers()
self.currentPathNumChanged.emit() self.currentPathNumChanged.emit()

View file

@ -5,7 +5,7 @@ import json
import os import os
import platform import platform
import time import time
from typing import cast, Optional, Set, TYPE_CHECKING from typing import Optional, Set, TYPE_CHECKING
from PyQt6.QtCore import pyqtSlot, QObject from PyQt6.QtCore import pyqtSlot, QObject
from PyQt6.QtNetwork import QNetworkRequest from PyQt6.QtNetwork import QNetworkRequest

View file

@ -16,8 +16,6 @@ from UM.Application import Application
from UM.Logger import Logger from UM.Logger import Logger
from UM.Message import Message from UM.Message import Message
from UM.Math.Color import Color from UM.Math.Color import Color
from UM.PluginRegistry import PluginRegistry
from UM.Platform import Platform
from UM.Event import Event from UM.Event import Event
from UM.View.RenderBatch import RenderBatch from UM.View.RenderBatch import RenderBatch

View file

@ -22,7 +22,6 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.SceneNode import SceneNode from UM.Scene.SceneNode import SceneNode
from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.InstanceContainer import InstanceContainer
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
from cura.Settings.CuraStackBuilder import CuraStackBuilder
from cura.Settings.GlobalStack import GlobalStack from cura.Settings.GlobalStack import GlobalStack
from cura.Utils.Threading import call_on_qt_thread from cura.Utils.Threading import call_on_qt_thread

View file

@ -9,8 +9,8 @@ try:
except ImportError: except ImportError:
Logger.log("w", "Could not import UFPWriter; libCharon may be missing") Logger.log("w", "Could not import UFPWriter; libCharon may be missing")
from UM.i18n import i18nCatalog #To translate the file format description. from UM.i18n import i18nCatalog # To translate the file format description.
from UM.Mesh.MeshWriter import MeshWriter #For the binary mode flag. from UM.Mesh.MeshWriter import MeshWriter # For the binary mode flag.
i18n_catalog = i18nCatalog("cura") i18n_catalog = i18nCatalog("cura")

View file

@ -4,9 +4,6 @@
from UM.Job import Job from UM.Job import Job
from UM.Logger import Logger from UM.Logger import Logger
from .avr_isp import ispBase
from .avr_isp.stk500v2 import Stk500v2
from time import time, sleep from time import time, sleep
from serial import Serial, SerialException from serial import Serial, SerialException

View file

@ -5,9 +5,9 @@ import os
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Logger import Logger from UM.Logger import Logger
from UM.Mesh.MeshWriter import MeshWriter #To get the g-code output. from UM.Mesh.MeshWriter import MeshWriter # To get the g-code output.
from UM.Message import Message #Show an error when already printing. from UM.Message import Message # Show an error when already printing.
from UM.PluginRegistry import PluginRegistry #To get the g-code output. from UM.PluginRegistry import PluginRegistry # To get the g-code output.
from UM.Qt.Duration import DurationFormat from UM.Qt.Duration import DurationFormat
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
@ -19,7 +19,7 @@ from cura.PrinterOutput.GenericOutputController import GenericOutputController
from .AutoDetectBaudJob import AutoDetectBaudJob from .AutoDetectBaudJob import AutoDetectBaudJob
from .AvrFirmwareUpdater import AvrFirmwareUpdater from .AvrFirmwareUpdater import AvrFirmwareUpdater
from io import StringIO #To write the g-code output. from io import StringIO # To write the g-code output.
from queue import Queue from queue import Queue
from serial import Serial, SerialException, SerialTimeoutException from serial import Serial, SerialException, SerialTimeoutException
from threading import Thread, Event from threading import Thread, Event

View file

@ -1,16 +1,16 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import configparser #To read config files. import configparser # To read config files.
import io #To write config files to strings as if they were files. import io # To write config files to strings as if they were files.
import os.path #To get the path to write new user profiles to. import os.path # To get the path to write new user profiles to.
from typing import Dict, List, Optional, Set, Tuple from typing import Dict, List, Optional, Set, Tuple
import urllib #To serialise the user container file name properly. import urllib # To serialise the user container file name properly.
import urllib.parse import urllib.parse
import UM.VersionUpgrade #To indicate that a file is of incorrect format. import UM.VersionUpgrade # To indicate that a file is of incorrect format.
import UM.VersionUpgradeManager #To schedule more files to be upgraded. import UM.VersionUpgradeManager # To schedule more files to be upgraded.
from UM.Resources import Resources #To get the config storage path. from UM.Resources import Resources # To get the config storage path.
## Creates a new machine instance instance by parsing a serialised machine ## Creates a new machine instance instance by parsing a serialised machine
# instance in version 1 of the file format. # instance in version 1 of the file format.

View file

@ -1,11 +1,11 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import configparser #To read config files. import configparser # To read config files.
import io #To output config files to string. import io # To output config files to string.
from typing import List, Optional, Tuple from typing import List, Optional, Tuple
import UM.VersionUpgrade #To indicate that a file is of the wrong format. import UM.VersionUpgrade # To indicate that a file is of the wrong format.
## Creates a new preferences instance by parsing a serialised preferences file ## Creates a new preferences instance by parsing a serialised preferences file
# in version 1 of the file format. # in version 1 of the file format.

View file

@ -1,8 +1,8 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import configparser #To read config files. import configparser # To read config files.
import io #To write config files to strings as if they were files. import io # To write config files to strings as if they were files.
from typing import Dict, List, Optional, Tuple from typing import Dict, List, Optional, Tuple
import UM.VersionUpgrade import UM.VersionUpgrade

View file

@ -0,0 +1,95 @@
# Copyright (c) 2024 UltiMaker
# Cura is released under the terms of the LGPLv3 or higher.
import configparser
from typing import Tuple, List
import io
from UM.VersionUpgrade import VersionUpgrade
_REMOVED_SETTINGS = {
"support_interface_skip_height",
}
_NEW_SETTING_VERSION = "23"
class VersionUpgrade56to57(VersionUpgrade):
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
"""
Upgrades preferences to remove from the visibility list the settings that were removed in this version.
It also changes the preferences to have the new version number.
This removes any settings that were removed in the new Cura version.
:param serialized: The original contents of the preferences file.
:param filename: The file name of the preferences file.
:return: A list of new file names, and a list of the new contents for
those files.
"""
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized)
# Update version number.
parser["metadata"]["setting_version"] = _NEW_SETTING_VERSION
# Remove deleted settings from the visible settings list.
if "general" in parser and "visible_settings" in parser["general"]:
visible_settings = set(parser["general"]["visible_settings"].split(";"))
for removed in _REMOVED_SETTINGS:
if removed in visible_settings:
visible_settings.remove(removed)
parser["general"]["visible_settings"] = ";".join(visible_settings)
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]
def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
"""
Upgrades instance containers to remove the settings that were removed in this version.
It also changes the instance containers to have the new version number.
This removes any settings that were removed in the new Cura version and updates settings that need to be updated
with a new value.
:param serialized: The original contents of the instance container.
:param filename: The original file name of the instance container.
:return: A list of new file names, and a list of the new contents for
those files.
"""
parser = configparser.ConfigParser(interpolation = None, comment_prefixes = ())
parser.read_string(serialized)
# Update version number.
parser["metadata"]["setting_version"] = _NEW_SETTING_VERSION
if "values" in parser:
# Remove deleted settings from the instance containers.
for removed in _REMOVED_SETTINGS:
if removed in parser["values"]:
del parser["values"][removed]
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]
def upgradeStack(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
"""
Upgrades stacks to have the new version number.
:param serialized: The original contents of the stack.
:param filename: The original file name of the stack.
:return: A list of new file names, and a list of the new contents for
those files.
"""
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized)
# Update version number.
if "metadata" not in parser:
parser["metadata"] = {}
parser["metadata"]["setting_version"] = _NEW_SETTING_VERSION
result = io.StringIO()
parser.write(result)
return [filename], [result.getvalue()]

View file

@ -0,0 +1,61 @@
# Copyright (c) 2024 UltiMaker
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Any, Dict, TYPE_CHECKING
from . import VersionUpgrade56to57
if TYPE_CHECKING:
from UM.Application import Application
upgrade = VersionUpgrade56to57.VersionUpgrade56to57()
def getMetaData() -> Dict[str, Any]:
return {
"version_upgrade": {
# From To Upgrade function
("preferences", 7000022): ("preferences", 7000023, upgrade.upgradePreferences),
("machine_stack", 6000022): ("machine_stack", 6000023, upgrade.upgradeStack),
("extruder_train", 6000022): ("extruder_train", 6000023, upgrade.upgradeStack),
("definition_changes", 4000022): ("definition_changes", 4000023, upgrade.upgradeInstanceContainer),
("quality_changes", 4000022): ("quality_changes", 4000023, upgrade.upgradeInstanceContainer),
("quality", 4000022): ("quality", 4000023, upgrade.upgradeInstanceContainer),
("user", 4000022): ("user", 4000023, upgrade.upgradeInstanceContainer),
("intent", 4000022): ("intent", 4000023, upgrade.upgradeInstanceContainer),
},
"sources": {
"preferences": {
"get_version": upgrade.getCfgVersion,
"location": {"."}
},
"machine_stack": {
"get_version": upgrade.getCfgVersion,
"location": {"./machine_instances"}
},
"extruder_train": {
"get_version": upgrade.getCfgVersion,
"location": {"./extruders"}
},
"definition_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./definition_changes"}
},
"quality_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./quality_changes"}
},
"quality": {
"get_version": upgrade.getCfgVersion,
"location": {"./quality"}
},
"user": {
"get_version": upgrade.getCfgVersion,
"location": {"./user"}
}
}
}
def register(app: "Application") -> Dict[str, Any]:
return {"version_upgrade": upgrade}

View file

@ -0,0 +1,8 @@
{
"name": "Version Upgrade 5.6 to 5.7",
"author": "UltiMaker",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 5.6 to Cura 5.7.",
"api": 8,
"i18n-catalog": "cura"
}

View file

@ -7,7 +7,6 @@ from PyQt6.QtGui import QOpenGLContext, QImage
from UM.Application import Application from UM.Application import Application
from UM.Logger import Logger from UM.Logger import Logger
from UM.Math.Color import Color from UM.Math.Color import Color
from UM.PluginRegistry import PluginRegistry
from UM.Resources import Resources from UM.Resources import Resources
from UM.Platform import Platform from UM.Platform import Platform
from UM.Event import Event from UM.Event import Event

View file

@ -3,9 +3,9 @@
import copy import copy
import io import io
import json #To parse the product-to-id mapping file. import json # To parse the product-to-id mapping file.
import os.path #To find the product-to-id mapping. import os.path # To find the product-to-id mapping.
from typing import Any, Dict, List, Optional, Tuple, cast, Set, Union from typing import Any, Dict, List, Optional, Tuple, cast, Set
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from UM.PluginRegistry import PluginRegistry from UM.PluginRegistry import PluginRegistry

View file

@ -1,5 +1,5 @@
pytest pytest
pyinstaller==5.8.0 pyinstaller==6.3.0
pyinstaller-hooks-contrib pyinstaller-hooks-contrib
pyyaml pyyaml
sip==6.5.1 sip==6.5.1

View file

@ -112,7 +112,6 @@
"support_interface_density": { "value": 33.333 }, "support_interface_density": { "value": 33.333 },
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_roof_enable": { "value": true }, "support_roof_enable": { "value": true },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },
"support_xy_distance_overhang": { "value": "wall_line_width_0" }, "support_xy_distance_overhang": { "value": "wall_line_width_0" },

View file

@ -114,7 +114,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },
"support_xy_distance_overhang": { "value": "wall_line_width_0" }, "support_xy_distance_overhang": { "value": "wall_line_width_0" },
"support_xy_overrides_z": { "value": "'xy_overrides_z'" }, "support_xy_overrides_z": { "value": "'xy_overrides_z'" },

View file

@ -154,7 +154,6 @@
"support_infill_rate": { "value": "20" }, "support_infill_rate": { "value": "20" },
"support_interface_enable": { "value": "True" }, "support_interface_enable": { "value": "True" },
"support_interface_height": { "value": "1" }, "support_interface_height": { "value": "1" },
"support_interface_skip_height": { "value": "layer_height" },
"support_join_distance": { "value": "1" }, "support_join_distance": { "value": "1" },
"support_offset": { "value": "1.5" }, "support_offset": { "value": "1.5" },
"support_pattern": { "default_value": "zigzag" }, "support_pattern": { "default_value": "zigzag" },

View file

@ -108,7 +108,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 1 }, "support_wall_count": { "value": 1 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -97,7 +97,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },
"support_xy_distance_overhang": { "value": "wall_line_width_0" }, "support_xy_distance_overhang": { "value": "wall_line_width_0" },

View file

@ -9,16 +9,20 @@
}, },
"overrides": "overrides":
{ {
"acceleration_layer_0": { "value": 3000 }, "acceleration_print":
"acceleration_print": { "value": 3000 }, {
"acceleration_travel": { "value": 5000 }, "maximum_value_warning": "20000",
"value": 10000
},
"acceleration_wall": { "value": "acceleration_print/2" },
"cool_fan_full_layer": { "value": 2 }, "cool_fan_full_layer": { "value": 2 },
"infill_line_width": { "value": "line_width + 0.05" }, "infill_line_width": { "value": "line_width + 0.05" },
"infill_overlap": { "value": "0 if infill_sparse_density < 40.01 and infill_pattern != 'concentric' else -5" }, "infill_overlap": { "value": "0 if infill_sparse_density < 40.01 and infill_pattern != 'concentric' else -5" },
"infill_pattern": { "value": "'lines' if infill_sparse_density > 35 else 'grid'" },
"initial_layer_line_width_factor": { "value": "100.0 if resolveOrValue('adhesion_type') == 'raft' else 125 if line_width < 0.5 else 110" }, "initial_layer_line_width_factor": { "value": "100.0 if resolveOrValue('adhesion_type') == 'raft' else 125 if line_width < 0.5 else 110" },
"machine_acceleration": { "value": 3000 }, "machine_acceleration": { "value": 5000 },
"machine_depth": { "default_value": 230 }, "machine_depth": { "default_value": 230 },
"machine_end_gcode": { "default_value": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z2 ;Raise Z more\nG90 ;Absolute positionning\nG1 X0 Y{machine_depth} ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\nM84 X Y E ;Disable all steppers but Z" }, "machine_end_gcode": { "default_value": "G91 ;Relative positionning\nG1 E-2 F2700 ;Retract a bit\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z2 ;Raise Z more\nG90 ;Absolute positionning\nG1 X0 Y{machine_depth - 5} ;Present print\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\nM84 X Y E ;Disable all steppers but Z" },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" }, "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_head_with_fans_polygon": "machine_head_with_fans_polygon":
{ {
@ -32,12 +36,12 @@
"machine_heated_bed": { "default_value": true }, "machine_heated_bed": { "default_value": true },
"machine_height": { "default_value": 270 }, "machine_height": { "default_value": 270 },
"machine_max_acceleration_e": { "value": 5000 }, "machine_max_acceleration_e": { "value": 5000 },
"machine_max_acceleration_x": { "value": 5000 }, "machine_max_acceleration_x": { "value": 20000 },
"machine_max_acceleration_y": { "value": 5000 }, "machine_max_acceleration_y": { "value": 20000 },
"machine_name": { "default_value": "ELEGOO NEPTUNE 4" }, "machine_name": { "default_value": "ELEGOO NEPTUNE 4" },
"machine_nozzle_cool_down_speed": { "value": 0.75 }, "machine_nozzle_cool_down_speed": { "value": 0.75 },
"machine_nozzle_heat_up_speed": { "value": 1.6 }, "machine_nozzle_heat_up_speed": { "value": 1.6 },
"machine_start_gcode": { "default_value": "G28 ;home\nG92 E0 ;Reset Extruder\nG1 Z4.0 F3000 ;Move Z Axis up\nG92 E0 ;Reset Extruder\nG1 X1.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X1.1 Y80.0 Z0.28 F1500.0 E10 ;Draw the first line\nG1 X1.4 Y80.0 Z0.28 F5000.0 ;Move to side a little\nG1 X1.4 Y20 Z0.28 F1500.0 E20 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up" }, "machine_start_gcode": { "default_value": ";ELEGOO NEPTUNE 4 / 4 PRO\nM220 S100 ;Set the feed speed to 100%\nM221 S100 ;Set the flow rate to 100%\nM104 S140 ;Start heating extruder\nM190 S{material_bed_temperature_layer_0} ;Wait for the bed to reach print temp\nG90\nG28 ;home\nG1 Z10 F300\nG1 X67.5 Y0 F6000\nG1 Z0 F300\nM109 S{material_print_temperature_layer_0} ;Wait for extruder to reach print temp\nG92 E0 ;Reset Extruder\nG1 X67.5 Y0 Z0.4 F300 ;Move to start position\nG1 X167.5 E30 F400 ;Draw the first line\nG1 Z0.6 F120.0 ;Move to side a little\nG1 X162.5 F3000\nG92 E0 ;Reset Extruder" },
"machine_width": { "default_value": 235 }, "machine_width": { "default_value": 235 },
"retraction_amount": { "default_value": 0.5 }, "retraction_amount": { "default_value": 0.5 },
"retraction_count_max": { "value": 80 }, "retraction_count_max": { "value": 80 },

View file

@ -0,0 +1,62 @@
{
"version": 2,
"name": "ELEGOO NEPTUNE 4 Max",
"inherits": "elegoo_neptune_4",
"metadata":
{
"visible": true,
"author": "mastercaution",
"platform": "elegoo_platform_max.3mf",
"platform_offset": [
-2.1,
-0.2,
0
],
"quality_definition": "elegoo_neptune_4"
},
"overrides":
{
"acceleration_print":
{
"maximum_value_warning": "15000",
"value": 2500
},
"machine_depth": { "default_value": 430 },
"machine_height": { "default_value": 482 },
"machine_max_acceleration_e": { "value": 5000 },
"machine_max_acceleration_x": { "value": 15000 },
"machine_max_acceleration_y": { "value": 15000 },
"machine_name": { "default_value": "ELEGOO NEPTUNE 4 Max" },
"machine_start_gcode": { "default_value": ";ELEGOO NEPTUNE 4 MAX\nM220 S100 ;Set the feed speed to 100%\nM221 S100 ;Set the flow rate to 100%\nM104 S140 ;Start heating extruder\nM190 S{material_bed_temperature_layer_0} ;Wait for the bed to reach print temp\nG90\nG28 ;home\nG1 Z10 F300\nG1 X165 Y0 F6000\nG1 Z0 F300\nM109 S{material_print_temperature_layer_0} ;Wait for extruder to reach print temp\nG92 E0 ;Reset Extruder\nG1 X165 Y0 Z0.4 F300 ;Move to start position\nG1 X265 E30 F400 ;Draw the first line\nG1 Z0.6 F120.0 ;Move to side a little\nG1 X260 F3000\nG92 E0 ;Reset Extruder" },
"machine_width": { "default_value": 430 },
"nozzle_disallowed_areas":
{
"default_value": [
[
[-215, -215],
[-215, 215],
[-211, 215],
[-211, -215]
],
[
[215, 215],
[215, -215],
[211, -215],
[211, 215]
],
[
[-215, -215],
[215, -215],
[-215, -211],
[215, -211]
],
[
[-215, 215],
[215, 215],
[-215, 211],
[215, 211]
]
]
}
}
}

View file

@ -0,0 +1,59 @@
{
"version": 2,
"name": "ELEGOO NEPTUNE 4 Plus",
"inherits": "elegoo_neptune_4",
"metadata":
{
"visible": true,
"author": "mastercaution",
"platform": "elegoo_platform_max.3mf",
"platform_offset": [
-2.1,
-0.2,
0
],
"quality_definition": "elegoo_neptune_4"
},
"overrides":
{
"acceleration_print": { "value": 4000 },
"machine_acceleration": { "value": 4000 },
"machine_depth": { "default_value": 330 },
"machine_height": { "default_value": 387 },
"machine_max_acceleration_e": { "value": 5000 },
"machine_max_acceleration_x": { "value": 20000 },
"machine_max_acceleration_y": { "value": 20000 },
"machine_name": { "default_value": "ELEGOO NEPTUNE 4 Plus" },
"machine_start_gcode": { "default_value": ";ELEGOO NEPTUNE 4 PLUS\nM220 S100 ;Set the feed speed to 100%\nM221 S100 ;Set the flow rate to 100%\nM104 S140 ;Start heating extruder\nM190 S{material_bed_temperature_layer_0} ;Wait for the bed to reach print temp\nG90\nG28 ;home\nG1 Z10 F300\nG1 X115 Y0 F6000\nG1 Z0 F300\nM109 S{material_print_temperature_layer_0} ;Wait for extruder to reach print temp\nG92 E0 ;Reset Extruder\nG1 X115 Y0 Z0.4 F300 ;Move to start position\nG1 X215 E30 F400 ;Draw the first line\nG1 Z0.6 F120.0 ;Move to side a little\nG1 X210 F3000\nG92 E0 ;Reset Extruder" },
"machine_width": { "default_value": 330 },
"nozzle_disallowed_areas":
{
"default_value": [
[
[-165, -165],
[-165, 165],
[-161, 165],
[-161, -165]
],
[
[165, 165],
[165, -165],
[161, -165],
[161, 165]
],
[
[-165, -165],
[165, -165],
[-165, -161],
[165, -161]
],
[
[-165, 165],
[165, 165],
[-165, 161],
[165, 161]
]
]
}
}
}

View file

@ -1668,7 +1668,7 @@
"value": "skin_line_width * 2", "value": "skin_line_width * 2",
"default_value": 1, "default_value": 1,
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "skin_line_width * 3", "maximum_value_warning": "skin_line_width * 10",
"type": "float", "type": "float",
"enabled": "(top_layers > 0 or bottom_layers > 0) and top_bottom_pattern != 'concentric'", "enabled": "(top_layers > 0 or bottom_layers > 0) and top_bottom_pattern != 'concentric'",
"limit_to_extruder": "top_bottom_extruder_nr", "limit_to_extruder": "top_bottom_extruder_nr",
@ -5423,20 +5423,6 @@
} }
} }
}, },
"support_interface_skip_height":
{
"label": "Support Interface Resolution",
"description": "When checking where there's model above and below the support, take steps of the given height. Lower values will slice slower, while higher values may cause normal support to be printed in some places where there should have been support interface.",
"unit": "mm",
"type": "float",
"default_value": 0.2,
"value": "layer_height",
"minimum_value": "0",
"maximum_value_warning": "support_interface_height",
"limit_to_extruder": "support_interface_extruder_nr",
"enabled": "support_interface_enable and (support_enable or support_meshes_present)",
"settable_per_mesh": true
},
"support_interface_density": "support_interface_density":
{ {
"label": "Support Interface Density", "label": "Support Interface Density",
@ -6467,6 +6453,18 @@
"settable_per_extruder": true, "settable_per_extruder": true,
"limit_to_extruder": "raft_surface_extruder_nr" "limit_to_extruder": "raft_surface_extruder_nr"
}, },
"raft_surface_monotonic":
{
"label": "Monotonic Raft Top Surface Order",
"description": "Print raft top surface lines in an ordering that causes them to always overlap with adjacent lines in a single direction. This takes slightly more time to print, but makes the surface look more consistent, which is also visible on the model bottom surface.",
"type": "bool",
"default_value": false,
"value": "skin_monotonic",
"enabled": "resolveOrValue('adhesion_type') == 'raft' and raft_surface_layers > 0",
"settable_per_mesh": false,
"settable_per_extruder": true,
"limit_to_extruder": "raft_surface_extruder_nr"
},
"raft_wall_count": "raft_wall_count":
{ {
"label": "Raft Wall Count", "label": "Raft Wall Count",

View file

@ -0,0 +1,15 @@
{
"version": 2,
"name": "Adventurer 3",
"inherits": "flashforge_adventurer3c",
"metadata":
{
"visible": true,
"author": "Jeremie-C",
"supports_network_connection": true
},
"overrides":
{
"machine_name": { "default_value": "Adventurer 3" }
}
}

View file

@ -0,0 +1,33 @@
{
"version": 2,
"name": "Adventurer 3C",
"inherits": "flashforge_adventurer_base",
"metadata":
{
"visible": true,
"author": "Jeremie-C",
"quality_definition": "flashforge_adventurer3"
},
"overrides":
{
"default_material_bed_temperature": { "maximum_value_warning": "100" },
"gantry_height": { "value": "150" },
"machine_center_is_zero": { "default_value": true },
"machine_depth": { "default_value": 150 },
"machine_end_gcode": { "default_value": ";end gcode\nM104 S0 T0\nM140 S0 T0\nG162 Z F1800\nG28 X Y\nM132 X Y A B\nM652\nG91\nM18" },
"machine_head_with_fans_polygon":
{
"default_value": [
[-20, 10],
[-20, -10],
[10, 10],
[10, -10]
]
},
"machine_height": { "default_value": 150 },
"machine_name": { "default_value": "Adventurer 3C" },
"machine_start_gcode": { "default_value": ";Start Gcode\nG28\nM132 X Y Z A B\nG1 Z50.000 F420\nG161 X Y F3300\nM7 T0\nM6 T0\nM651 S255\n;End Start" },
"machine_width": { "default_value": 150 },
"speed_print": { "maximum_value_warning": 100 }
}
}

View file

@ -0,0 +1,33 @@
{
"version": 2,
"name": "Adventurer 4",
"inherits": "flashforge_adventurer_base",
"metadata":
{
"visible": true,
"author": "Jeremie-C",
"quality_definition": "flashforge_adventurer4",
"supports_network_connection": true
},
"overrides":
{
"default_material_bed_temperature": { "maximum_value_warning": "110" },
"gantry_height": { "value": "250" },
"machine_depth": { "default_value": 200 },
"machine_end_gcode": { "default_value": ";End Gcode\nM104 S0 T0\nM140 S0 T0\nG162 Z F1800\nG28 X Y\nM132 X Y A B\nM652\nG91\nM18" },
"machine_head_with_fans_polygon":
{
"default_value": [
[-20, 10],
[-20, -10],
[10, 10],
[10, -10]
]
},
"machine_height": { "default_value": 250 },
"machine_name": { "default_value": "Adventurer 4" },
"machine_start_gcode": { "default_value": ";Start Gcode\nG28\nM132 X Y Z A B\nG1 Z50.000 F420\nG161 X Y F3300\nM7 T0\nM6 T0\nM651 S255\n;End Start" },
"machine_use_extruder_offset_to_offset_coords": { "default_value": false },
"machine_width": { "default_value": 220 }
}
}

View file

@ -0,0 +1,14 @@
{
"version": 2,
"name": "Adventurer 4 Lite",
"inherits": "flashforge_adventurer4",
"metadata":
{
"visible": true,
"author": "Jeremie-C"
},
"overrides":
{
"machine_name": { "default_value": "Adventurer 4 Lite" }
}
}

View file

@ -0,0 +1,34 @@
{
"version": 2,
"name": "Flashforge Adventurer Base",
"inherits": "fdmprinter",
"metadata":
{
"visible": false,
"author": "Jeremie-C",
"manufacturer": "Flashforge",
"file_formats": "application/gx;text/x-gcode",
"first_start_actions": [ "MachineSettingsAction" ],
"has_machine_quality": true,
"has_materials": true,
"has_variants": true,
"machine_extruder_trains": { "0": "flashforge_adventurer_extruder_0" },
"preferred_material": "generic_pla",
"preferred_quality_type": "normal",
"preferred_variant_name": "0.4mm Nozzle",
"variants_name": "Nozzle Size"
},
"overrides":
{
"adhesion_type": { "default_value": "skirt" },
"default_material_print_temperature": { "maximum_value_warning": "265" },
"layer_height":
{
"maximum_value_warning": "0.4",
"minimum_value_warning": "0.1"
},
"machine_center_is_zero": { "default_value": true },
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_heated_bed": { "default_value": true }
}
}

View file

@ -92,7 +92,6 @@
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_line_width": { "value": "line_width - 0.1" }, "support_interface_line_width": { "value": "line_width - 0.1" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 1 }, "support_wall_count": { "value": 1 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -112,7 +112,6 @@
"support_interface_density": { "value": 33.333 }, "support_interface_density": { "value": 33.333 },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 0 }, "support_wall_count": { "value": 0 },
"support_xy_distance": { "value": "wall_line_width_0 * 3" }, "support_xy_distance": { "value": "wall_line_width_0 * 3" },

View file

@ -133,7 +133,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 1 }, "support_wall_count": { "value": 1 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -70,7 +70,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 1 }, "support_wall_count": { "value": 1 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -88,7 +88,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 1 }, "support_wall_count": { "value": 1 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -88,7 +88,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 1 }, "support_wall_count": { "value": 1 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -109,7 +109,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 1 }, "support_wall_count": { "value": 1 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -119,7 +119,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 1 }, "support_wall_count": { "value": 1 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -0,0 +1,20 @@
{
"version": 2,
"name": "RatRig Printer",
"inherits": "fdmprinter",
"metadata":
{
"visible": false,
"author": "nu-hin",
"manufacturer": "RatRig",
"file_formats": "text/x-gcode",
"exclude_materials": [],
"first_start_actions": [ "MachineSettingsAction" ],
"has_materials": true,
"machine_extruder_trains": { "0": "ratrig_base_extruder_0" },
"preferred_material": "generic_pla",
"preferred_quality_type": "standard",
"quality_definition": "ratrig_base",
"supported_actions": [ "MachineSettingsAction" ]
}
}

View file

@ -0,0 +1,23 @@
{
"version": 2,
"name": "RatRig V-Core 3 200mm",
"inherits": "ratrig_vcore3_base",
"metadata":
{
"visible": true,
"platform": "ratrig_vcore3_200.stl",
"platform_offset": [
0,
5,
0
],
"weight": 16
},
"overrides":
{
"machine_depth": { "default_value": 200 },
"machine_height": { "default_value": 200 },
"machine_name": { "default_value": "RatRig V-Core 3 200mm" },
"machine_width": { "default_value": 200 }
}
}

View file

@ -0,0 +1,23 @@
{
"version": 2,
"name": "RatRig V-Core 3 300mm",
"inherits": "ratrig_vcore3_base",
"metadata":
{
"visible": true,
"platform": "ratrig_vcore3_300.stl",
"platform_offset": [
0,
5,
0
],
"weight": 16
},
"overrides":
{
"machine_depth": { "default_value": 300 },
"machine_height": { "default_value": 300 },
"machine_name": { "default_value": "RatRig V-Core 3 300mm" },
"machine_width": { "default_value": 300 }
}
}

View file

@ -0,0 +1,23 @@
{
"version": 2,
"name": "RatRig V-Core 3 400mm",
"inherits": "ratrig_vcore3_base",
"metadata":
{
"visible": true,
"platform": "ratrig_vcore3_400.stl",
"platform_offset": [
0,
3,
0
],
"weight": 16
},
"overrides":
{
"machine_depth": { "default_value": 400 },
"machine_height": { "default_value": 400 },
"machine_name": { "default_value": "RatRig V-Core 3 400mm" },
"machine_width": { "default_value": 400 }
}
}

View file

@ -0,0 +1,23 @@
{
"version": 2,
"name": "RatRig V-Core 3 500mm",
"inherits": "ratrig_vcore3_base",
"metadata":
{
"visible": true,
"platform": "ratrig_vcore3_500.stl",
"platform_offset": [
0,
0,
0
],
"weight": 16
},
"overrides":
{
"machine_depth": { "default_value": 500 },
"machine_height": { "default_value": 500 },
"machine_name": { "default_value": "RatRig V-Core 3 500mm" },
"machine_width": { "default_value": 500 }
}
}

View file

@ -0,0 +1,116 @@
{
"version": 2,
"name": "RatRig V-Core 3",
"inherits": "ratrig_base",
"metadata":
{
"visible": false,
"has_machine_quality": true,
"has_variants": true,
"machine_extruder_trains": { "0": "ratrig_base_extruder_0" },
"preferred_variant_name": "0.4mm Nozzle",
"variants_name": "Nozzle Size"
},
"overrides":
{
"acceleration_enabled": { "value": true },
"acceleration_layer_0": { "value": "acceleration_topbottom" },
"acceleration_roofing": { "enabled": "acceleration_enabled and roofing_layer_count > 0 and top_layers > 0" },
"acceleration_topbottom": { "value": "acceleration_print / 3" },
"acceleration_travel": { "value": 3000 },
"acceleration_travel_layer_0": { "value": "acceleration_travel / 3" },
"adaptive_layer_height_variation": { "value": 0.04 },
"adaptive_layer_height_variation_step": { "value": 0.04 },
"adhesion_type": { "value": "'skirt'" },
"brim_replaces_support": { "value": false },
"brim_width": { "value": "3" },
"cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" },
"cool_min_layer_time": { "value": 2 },
"fill_outline_gaps": { "value": false },
"gantry_height": { "value": 30 },
"infill_before_walls": { "value": false },
"infill_overlap": { "value": 30 },
"infill_pattern": { "value": "'lines' if infill_sparse_density > 50 else 'cubic'" },
"infill_wipe_dist": { "value": 0 },
"layer_height": { "default_value": 0.2 },
"layer_height_0": { "default_value": 0.2 },
"machine_acceleration": { "value": 3000 },
"machine_end_gcode": { "default_value": "END_PRINT" },
"machine_extruder_count": { "default_value": 1 },
"machine_head_with_fans_polygon":
{
"default_value": [
[-40, 90],
[-40, -30],
[40, -30],
[40, 90]
]
},
"machine_heated_bed": { "default_value": true },
"machine_max_acceleration_e": { "value": 5000 },
"machine_max_acceleration_x": { "value": 9000 },
"machine_max_acceleration_y": { "value": 9000 },
"machine_max_acceleration_z": { "value": 100 },
"machine_max_feedrate_e": { "value": 60 },
"machine_max_feedrate_x": { "value": 500 },
"machine_max_feedrate_y": { "value": 500 },
"machine_max_feedrate_z": { "value": 10 },
"machine_max_jerk_e": { "value": 5 },
"machine_max_jerk_xy": { "value": 5 },
"machine_max_jerk_z": { "value": 0.4 },
"machine_name": { "default_value": "RatRig V-Core 3" },
"machine_shape": { "default_value": "rectangular" },
"machine_show_variants": { "default_value": true },
"machine_start_gcode": { "default_value": "START_PRINT EXTRUDER_TEMP={material_print_temperature_layer_0} BED_TEMP={material_bed_temperature_layer_0}" },
"material_diameter": { "default_value": 1.75 },
"material_final_print_temperature": { "value": "material_print_temperature" },
"material_initial_print_temperature": { "value": "material_print_temperature" },
"meshfix_maximum_resolution": { "value": "0.25" },
"meshfix_maximum_travel_resolution": { "value": "meshfix_maximum_resolution" },
"minimum_interface_area": { "value": 10 },
"minimum_support_area": { "value": 2 },
"optimize_wall_printing_order": { "value": true },
"retraction_amount": { "value": "machine_nozzle_size * 2" },
"retraction_combing": { "value": "'off' if retraction_hop_enabled else 'noskin'" },
"retraction_combing_max_distance": { "value": 30 },
"retraction_count_max": { "value": 100 },
"retraction_extrusion_window": { "value": 10 },
"retraction_speed": { "value": 40 },
"roofing_layer_count": { "value": 1 },
"skin_overlap": { "value": 18 },
"skirt_brim_minimal_length": { "default_value": 30 },
"skirt_gap": { "value": 10 },
"skirt_line_count": { "value": 3 },
"speed_layer_0": { "value": "math.floor(speed_print * 3 / 10)" },
"speed_print": { "value": 100 },
"speed_roofing": { "value": "math.floor(speed_print * 3 / 10)" },
"speed_support": { "value": "math.floor(speed_print * 3 / 10)" },
"speed_support_interface": { "value": "speed_topbottom" },
"speed_topbottom": { "value": "math.floor(speed_print / 2)" },
"speed_travel": { "value": 250 },
"speed_travel_layer_0": { "value": "100 if speed_layer_0 < 20 else 150 if speed_layer_0 > 30 else speed_layer_0 * 5" },
"speed_wall_x": { "value": "speed_wall" },
"speed_z_hop": { "value": 5 },
"support_angle": { "value": "math.floor(math.degrees(math.atan(line_width/2.0/layer_height)))" },
"support_brim_width": { "value": 4 },
"support_infill_rate": { "value": "0 if support_enable and support_structure == 'tree' else 20" },
"support_interface_density": { "value": 33.333 },
"support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" },
"support_pattern": { "value": "'zigzag'" },
"support_use_towers": { "value": false },
"support_xy_distance": { "value": "wall_line_width_0 * 2" },
"support_xy_distance_overhang": { "value": "wall_line_width_0" },
"support_xy_overrides_z": { "value": "'xy_overrides_z'" },
"support_z_distance": { "value": "layer_height if layer_height >= 0.16 else layer_height * 2" },
"top_bottom_pattern": { "value": "'lines'" },
"top_bottom_thickness": { "value": "layer_height_0 + layer_height * 3" },
"travel_avoid_supports": { "value": true },
"travel_retract_before_outer_wall": { "value": true },
"wall_0_wipe_dist": { "value": 0 },
"wall_thickness": { "value": "line_width * 2" },
"z_seam_corner": { "value": "'z_seam_corner_weighted'" },
"z_seam_type": { "value": "'back'" }
}
}

View file

@ -0,0 +1,127 @@
{
"version": 2,
"name": "RatRig V-Minion",
"inherits": "ratrig_base",
"metadata":
{
"visible": true,
"platform": "ratrig_vminion.stl",
"has_machine_quality": true,
"has_variants": true,
"machine_extruder_trains": { "0": "ratrig_base_extruder_0" },
"platform_offset": [
0,
5,
0
],
"preferred_variant_name": "0.4mm Nozzle",
"variants_name": "Nozzle Size",
"weight": 8
},
"overrides":
{
"acceleration_enabled": { "value": true },
"acceleration_layer_0": { "value": "acceleration_topbottom" },
"acceleration_roofing": { "enabled": "acceleration_enabled and roofing_layer_count > 0 and top_layers > 0" },
"acceleration_topbottom": { "value": "acceleration_print / 3" },
"acceleration_travel": { "value": 3000 },
"acceleration_travel_layer_0": { "value": "acceleration_travel / 3" },
"adaptive_layer_height_variation": { "value": 0.04 },
"adaptive_layer_height_variation_step": { "value": 0.04 },
"adhesion_type": { "value": "'skirt'" },
"brim_replaces_support": { "value": false },
"brim_width": { "value": "3" },
"cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" },
"cool_min_layer_time": { "value": 2 },
"fill_outline_gaps": { "value": false },
"gantry_height": { "value": 30 },
"infill_before_walls": { "value": false },
"infill_overlap": { "value": 30 },
"infill_pattern": { "value": "'lines' if infill_sparse_density > 50 else 'cubic'" },
"infill_wipe_dist": { "value": 0 },
"layer_height": { "default_value": 0.2 },
"layer_height_0": { "default_value": 0.2 },
"machine_acceleration": { "value": 3000 },
"machine_depth": { "default_value": 180 },
"machine_end_gcode": { "default_value": "END_PRINT" },
"machine_extruder_count": { "default_value": 1 },
"machine_head_with_fans_polygon":
{
"default_value": [
[-40, 90],
[-40, -30],
[40, -30],
[40, 90]
]
},
"machine_heated_bed": { "default_value": true },
"machine_height": { "default_value": 180 },
"machine_max_acceleration_e": { "value": 5000 },
"machine_max_acceleration_x": { "value": 9000 },
"machine_max_acceleration_y": { "value": 9000 },
"machine_max_acceleration_z": { "value": 100 },
"machine_max_feedrate_e": { "value": 60 },
"machine_max_feedrate_x": { "value": 500 },
"machine_max_feedrate_y": { "value": 500 },
"machine_max_feedrate_z": { "value": 10 },
"machine_max_jerk_e": { "value": 5 },
"machine_max_jerk_xy": { "value": 5 },
"machine_max_jerk_z": { "value": 0.4 },
"machine_name": { "default_value": "RatRig V-Minion" },
"machine_shape": { "default_value": "rectangular" },
"machine_show_variants": { "default_value": true },
"machine_start_gcode": { "default_value": "START_PRINT EXTRUDER_TEMP={material_print_temperature_layer_0} BED_TEMP={material_bed_temperature_layer_0}" },
"machine_width": { "default_value": 180 },
"material_diameter": { "default_value": 1.75 },
"material_final_print_temperature": { "value": "material_print_temperature" },
"material_initial_print_temperature": { "value": "material_print_temperature" },
"meshfix_maximum_resolution": { "value": "0.25" },
"meshfix_maximum_travel_resolution": { "value": "meshfix_maximum_resolution" },
"minimum_interface_area": { "value": 10 },
"minimum_support_area": { "value": 2 },
"optimize_wall_printing_order": { "value": true },
"retraction_amount": { "value": "machine_nozzle_size * 2" },
"retraction_combing": { "value": "'off' if retraction_hop_enabled else 'noskin'" },
"retraction_combing_max_distance": { "value": 30 },
"retraction_count_max": { "value": 100 },
"retraction_extrusion_window": { "value": 10 },
"retraction_speed": { "value": 40 },
"roofing_layer_count": { "value": 1 },
"skin_overlap": { "value": 18 },
"skirt_brim_minimal_length": { "default_value": 30 },
"skirt_gap": { "value": 10 },
"skirt_line_count": { "value": 3 },
"speed_layer_0": { "value": "math.floor(speed_print * 3 / 10)" },
"speed_print": { "value": 100 },
"speed_roofing": { "value": "math.floor(speed_print * 3 / 10)" },
"speed_support": { "value": "math.floor(speed_print * 3 / 10)" },
"speed_support_interface": { "value": "speed_topbottom" },
"speed_topbottom": { "value": "math.floor(speed_print / 2)" },
"speed_travel": { "value": 250 },
"speed_travel_layer_0": { "value": "100 if speed_layer_0 < 20 else 150 if speed_layer_0 > 30 else speed_layer_0 * 5" },
"speed_wall": { "value": "math.floor(speed_print / 2)" },
"speed_wall_x": { "value": "speed_wall" },
"speed_z_hop": { "value": 5 },
"support_angle": { "value": "math.floor(math.degrees(math.atan(line_width/2.0/layer_height)))" },
"support_brim_width": { "value": 4 },
"support_infill_rate": { "value": "0 if support_enable and support_structure == 'tree' else 20" },
"support_interface_density": { "value": 33.333 },
"support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" },
"support_pattern": { "value": "'zigzag'" },
"support_use_towers": { "value": false },
"support_xy_distance": { "value": "wall_line_width_0 * 2" },
"support_xy_distance_overhang": { "value": "wall_line_width_0" },
"support_xy_overrides_z": { "value": "'xy_overrides_z'" },
"support_z_distance": { "value": "layer_height if layer_height >= 0.16 else layer_height * 2" },
"top_bottom_pattern": { "value": "'lines'" },
"top_bottom_thickness": { "value": "layer_height_0 + layer_height * 3" },
"travel_avoid_supports": { "value": true },
"travel_retract_before_outer_wall": { "value": true },
"wall_0_wipe_dist": { "value": 0 },
"wall_thickness": { "value": "line_width * 2" },
"z_seam_corner": { "value": "'z_seam_corner_weighted'" },
"z_seam_type": { "value": "'back'" }
}
}

View file

@ -70,7 +70,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 1 }, "support_wall_count": { "value": 1 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -111,7 +111,6 @@
"support_interface_density": { "value": 33.333 }, "support_interface_density": { "value": 33.333 },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": "1 if (support_structure == 'tree') else 0" }, "support_wall_count": { "value": "1 if (support_structure == 'tree') else 0" },
"support_xy_distance": { "value": "wall_line_width_0 * 3" }, "support_xy_distance": { "value": "wall_line_width_0 * 3" },

View file

@ -68,7 +68,6 @@
"support_interface_density": { "value": 33.333 }, "support_interface_density": { "value": 33.333 },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": "1 if (support_structure == 'tree') else 0" }, "support_wall_count": { "value": "1 if (support_structure == 'tree') else 0" },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -99,7 +99,7 @@
"acceleration_print": "acceleration_print":
{ {
"enabled": false, "enabled": false,
"value": 300 "value": 800
}, },
"acceleration_print_layer_0": "acceleration_print_layer_0":
{ {
@ -234,7 +234,7 @@
"jerk_print": "jerk_print":
{ {
"enabled": false, "enabled": false,
"value": 12.5 "value": 6.25
}, },
"jerk_print_layer_0": "jerk_print_layer_0":
{ {
@ -279,7 +279,7 @@
"jerk_travel": "jerk_travel":
{ {
"enabled": false, "enabled": false,
"value": 12.5 "value": "jerk_print"
}, },
"jerk_travel_enabled": "jerk_travel_enabled":
{ {
@ -361,8 +361,10 @@
"raft_interface_line_width": { "value": 0.7 }, "raft_interface_line_width": { "value": 0.7 },
"raft_interface_speed": { "value": 90 }, "raft_interface_speed": { "value": 90 },
"raft_interface_thickness": { "value": 0.3 }, "raft_interface_thickness": { "value": 0.3 },
"raft_margin": { "value": 3 }, "raft_interface_wall_count": { "value": "raft_wall_count" },
"raft_margin": { "value": 1.2 },
"raft_surface_extruder_nr": { "value": "int(anyExtruderWithMaterial('material_is_support_material')) if support_enable and extruderValue(support_extruder_nr,'material_is_support_material') else raft_base_extruder_nr" }, "raft_surface_extruder_nr": { "value": "int(anyExtruderWithMaterial('material_is_support_material')) if support_enable and extruderValue(support_extruder_nr,'material_is_support_material') else raft_base_extruder_nr" },
"raft_surface_wall_count": { "value": "raft_wall_count" },
"retraction_amount": { "value": 0.75 }, "retraction_amount": { "value": 0.75 },
"retraction_combing": { "value": "'off'" }, "retraction_combing": { "value": "'off'" },
"retraction_combing_max_distance": { "value": "speed_travel / 10" }, "retraction_combing_max_distance": { "value": "speed_travel / 10" },
@ -384,6 +386,7 @@
"skin_preshrink": { "value": 0 }, "skin_preshrink": { "value": 0 },
"skirt_brim_material_flow": { "value": "material_flow" }, "skirt_brim_material_flow": { "value": "material_flow" },
"skirt_brim_minimal_length": { "value": 500 }, "skirt_brim_minimal_length": { "value": 500 },
"small_skin_width": { "value": 4 },
"speed_equalize_flow_width_factor": { "value": 0 }, "speed_equalize_flow_width_factor": { "value": 0 },
"speed_prime_tower": { "value": "speed_topbottom" }, "speed_prime_tower": { "value": "speed_topbottom" },
"speed_print": { "value": 50 }, "speed_print": { "value": 50 },
@ -424,7 +427,7 @@
"travel_avoid_other_parts": { "value": false }, "travel_avoid_other_parts": { "value": false },
"wall_0_inset": { "value": 0 }, "wall_0_inset": { "value": 0 },
"wall_0_material_flow": { "value": "material_flow" }, "wall_0_material_flow": { "value": "material_flow" },
"wall_0_wipe_dist": { "value": 0 }, "wall_0_wipe_dist": { "value": 0.8 },
"wall_material_flow": { "value": "material_flow" }, "wall_material_flow": { "value": "material_flow" },
"wall_x_material_flow": { "value": "material_flow" }, "wall_x_material_flow": { "value": "material_flow" },
"xy_offset": { "value": 0 }, "xy_offset": { "value": 0 },

View file

@ -99,7 +99,6 @@
"support_interface_enable": { "value": true }, "support_interface_enable": { "value": true },
"support_interface_height": { "value": "layer_height * 4" }, "support_interface_height": { "value": "layer_height * 4" },
"support_interface_pattern": { "value": "'grid'" }, "support_interface_pattern": { "value": "'grid'" },
"support_interface_skip_height": { "value": 0.2 },
"support_pattern": { "value": "'zigzag'" }, "support_pattern": { "value": "'zigzag'" },
"support_wall_count": { "value": 1 }, "support_wall_count": { "value": 1 },
"support_xy_distance": { "value": "wall_line_width_0 * 2" }, "support_xy_distance": { "value": "wall_line_width_0 * 2" },

View file

@ -55,7 +55,7 @@
"machine_endstop_positive_direction_y": { "default_value": true }, "machine_endstop_positive_direction_y": { "default_value": true },
"machine_endstop_positive_direction_z": { "default_value": false }, "machine_endstop_positive_direction_z": { "default_value": false },
"machine_feeder_wheel_diameter": { "default_value": 7.5 }, "machine_feeder_wheel_diameter": { "default_value": 7.5 },
"machine_gcode_flavor": { "default_value": "RepRap (RepRap)" }, "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"machine_head_with_fans_polygon": "machine_head_with_fans_polygon":
{ {
"default_value": [ "default_value": [
@ -76,7 +76,7 @@
"machine_max_jerk_xy": { "default_value": 20 }, "machine_max_jerk_xy": { "default_value": 20 },
"machine_max_jerk_z": { "default_value": 1 }, "machine_max_jerk_z": { "default_value": 1 },
"machine_name": { "default_value": "VORON2" }, "machine_name": { "default_value": "VORON2" },
"machine_start_gcode": { "default_value": "print_start" }, "machine_start_gcode": { "default_value": ";Nozzle diameter = {machine_nozzle_size}\n;Filament type = {material_type}\n;Filament name = {material_name}\n;Filament weight = {filament_weight}\n; M190 S{material_bed_temperature_layer_0}\n; M109 S{material_print_temperature_layer_0}\nprint_start EXTRUDER={material_print_temperature_layer_0} BED={material_bed_temperature_layer_0} CHAMBER={build_volume_temperature}" },
"machine_steps_per_mm_x": { "default_value": 80 }, "machine_steps_per_mm_x": { "default_value": 80 },
"machine_steps_per_mm_y": { "default_value": 80 }, "machine_steps_per_mm_y": { "default_value": 80 },
"machine_steps_per_mm_z": { "default_value": 400 }, "machine_steps_per_mm_z": { "default_value": 400 },

View file

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

View file

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

View file

@ -14,8 +14,9 @@
"default_value": 0, "default_value": 0,
"maximum_value": "1" "maximum_value": "1"
}, },
"machine_extruder_end_code": { "default_value": "M106 P{extruder_nr} S255\nG91\nG0 Z0.4 F600\nG90\nG0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000" }, "machine_extruder_end_code": { "default_value": "M106 P{extruder_nr} S1.0\nG91\nG0 Z0.4 F600\nG90\nG0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000" },
"machine_extruder_start_code": { "default_value": "G0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000\nM109 S{material_final_print_temperature}\nG4 S5\nG91\nG0 Z-0.4 F600\nG90\nM107 P{(extruder_nr+1)%2}\nM106 P{extruder_nr} S{cool_fan_speed*255/100}" }, "machine_extruder_start_code": { "default_value": "G0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000\nM104 S{material_print_temperature}\nG4 S5\nG91\nG0 Z-0.4 F600\nG90\nM107 P{(extruder_nr+1)%2}\nM106 P{extruder_nr} S{cool_fan_speed/100}" },
"machine_extruder_start_code_duration": { "default_value": 8 },
"machine_nozzle_offset_x": { "default_value": 0 }, "machine_nozzle_offset_x": { "default_value": 0 },
"machine_nozzle_offset_y": { "default_value": 0 }, "machine_nozzle_offset_y": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.4 }, "machine_nozzle_size": { "default_value": 0.4 },

View file

@ -14,8 +14,9 @@
"default_value": 1, "default_value": 1,
"maximum_value": "1" "maximum_value": "1"
}, },
"machine_extruder_end_code": { "default_value": "M106 P{extruder_nr} S255\nG91\nG0 Z0.4 F600\nG90\nG0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000" }, "machine_extruder_end_code": { "default_value": "M106 P{extruder_nr} S1.0\nG91\nG0 Z0.4 F600\nG90\nG0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000" },
"machine_extruder_start_code": { "default_value": "G0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000\nM109 S{material_final_print_temperature}\nG4 S5\nG91\nG0 Z-0.4 F600\nG90\nM107 P{(extruder_nr+1)%2}\nM106 P{extruder_nr} S{cool_fan_speed*255/100}" }, "machine_extruder_start_code": { "default_value": "G0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000\nM104 S{material_print_temperature}\nG4 S5\nG91\nG0 Z-0.4 F600\nG90\nM107 P{(extruder_nr+1)%2}\nM106 P{extruder_nr} S{cool_fan_speed/100}" },
"machine_extruder_start_code_duration": { "default_value": 8 },
"machine_nozzle_offset_x": { "default_value": 0 }, "machine_nozzle_offset_x": { "default_value": 0 },
"machine_nozzle_offset_y": { "default_value": 0 }, "machine_nozzle_offset_y": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.4 }, "machine_nozzle_size": { "default_value": 0.4 },

View file

@ -14,8 +14,9 @@
"default_value": 0, "default_value": 0,
"maximum_value": "1" "maximum_value": "1"
}, },
"machine_extruder_end_code": { "default_value": "M106 P{extruder_nr} S255\nG91\nG0 Z0.4 F600\nG90\nG0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000" }, "machine_extruder_end_code": { "default_value": "M106 P{extruder_nr} S1.0\nG91\nG0 Z0.4 F600\nG90\nG0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000" },
"machine_extruder_start_code": { "default_value": "G0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000\nM109 S{material_final_print_temperature}\nG4 S5\nG91\nG0 Z-0.4 F600\nG90\nM107 P{(extruder_nr+1)%2}\nM106 P{extruder_nr} S{cool_fan_speed*255/100}" }, "machine_extruder_start_code": { "default_value": "G0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000\nM104 S{material_print_temperature}\nG4 S5\nG91\nG0 Z-0.4 F600\nG90\nM107 P{(extruder_nr+1)%2}\nM106 P{extruder_nr} S{cool_fan_speed/100}" },
"machine_extruder_start_code_duration": { "default_value": 10 },
"machine_nozzle_offset_x": { "default_value": 0 }, "machine_nozzle_offset_x": { "default_value": 0 },
"machine_nozzle_offset_y": { "default_value": 0 }, "machine_nozzle_offset_y": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.4 }, "machine_nozzle_size": { "default_value": 0.4 },

View file

@ -14,8 +14,9 @@
"default_value": 1, "default_value": 1,
"maximum_value": "1" "maximum_value": "1"
}, },
"machine_extruder_end_code": { "default_value": "M106 P{extruder_nr} S255\nG91\nG0 Z0.4 F600\nG90\nG0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000" }, "machine_extruder_end_code": { "default_value": "M106 P{extruder_nr} S1.0\nG91\nG0 Z0.4 F600\nG90\nG0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000" },
"machine_extruder_start_code": { "default_value": "G0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000\nM109 S{material_final_print_temperature}\nG4 S5\nG91\nG0 Z-0.4 F600\nG90\nM107 P{(extruder_nr+1)%2}\nM106 P{extruder_nr} S{cool_fan_speed*255/100}" }, "machine_extruder_start_code": { "default_value": "G0 X{prime_tower_position_x - prime_tower_size/2} Y{prime_tower_position_y + prime_tower_size/2} F6000\nM104 S{material_print_temperature}\nG4 S5\nG91\nG0 Z-0.4 F600\nG90\nM107 P{(extruder_nr+1)%2}\nM106 P{extruder_nr} S{cool_fan_speed/100}" },
"machine_extruder_start_code_duration": { "default_value": 10 },
"machine_nozzle_offset_x": { "default_value": 0 }, "machine_nozzle_offset_x": { "default_value": 0 },
"machine_nozzle_offset_y": { "default_value": 0 }, "machine_nozzle_offset_y": { "default_value": 0 },
"machine_nozzle_size": { "default_value": 0.4 }, "machine_nozzle_size": { "default_value": 0.4 },

View file

@ -3548,14 +3548,6 @@ msgctxt "support_bottom_height description"
msgid "The thickness of the support floors. This controls the number of dense layers that are printed on top of places of a model on which support rests." msgid "The thickness of the support floors. This controls the number of dense layers that are printed on top of places of a model on which support rests."
msgstr "" msgstr ""
msgctxt "support_interface_skip_height label"
msgid "Support Interface Resolution"
msgstr ""
msgctxt "support_interface_skip_height description"
msgid "When checking where there's model above and below the support, take steps of the given height. Lower values will slice slower, while higher values may cause normal support to be printed in some places where there should have been support interface."
msgstr ""
msgctxt "support_interface_density label" msgctxt "support_interface_density label"
msgid "Support Interface Density" msgid "Support Interface Density"
msgstr "" msgstr ""

View file

@ -0,0 +1,25 @@
[general]
definition = elegoo_neptune_4
name = Accurate
version = 4
[metadata]
intent_category = engineering
is_experimental = True
material = generic_pla
quality_type = Elegoo_layer_020
setting_version = 22
type = intent
variant = 0.40mm_Elegoo_Nozzle
[values]
speed_infill = =speed_print
speed_print = 150
speed_topbottom = =speed_print * 2 / 3
speed_travel = =min(speed_print * 4 / 3, 250) if speed_print <= 250 else speed_print
speed_wall = =speed_print * 2 / 3
speed_wall_0 = =speed_wall
speed_wall_x = =speed_wall
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 3

View file

@ -12,6 +12,14 @@ type = intent
variant = AA 0.4 variant = AA 0.4
[values] [values]
speed_infill = 50 _plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 0.5
top_bottom_thickness = 1.05 acceleration_print = 2500
acceleration_wall_0 = 1000
inset_direction = inside_out
jerk_wall_0 = 20
speed_print = 50
speed_roofing = =math.ceil(speed_wall*(35/50))
speed_wall_0 = =math.ceil(speed_wall*(20/50))
speed_wall_x = =math.ceil(speed_wall*(35/50))
top_bottom_thickness = =max(1.2 , layer_height * 6)

View file

@ -12,9 +12,13 @@ type = intent
variant = AA 0.4 variant = AA 0.4
[values] [values]
_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
infill_sparse_density = 20
jerk_print = 30 jerk_print = 30
speed_infill = =speed_print speed_infill = =speed_print
speed_print = 30 speed_print = 35
speed_roofing = =speed_topbottom
speed_topbottom = =speed_print speed_topbottom = =speed_print
speed_wall = =speed_print speed_wall = =speed_print
speed_wall_0 = =speed_wall speed_wall_0 = =speed_wall

View file

@ -12,6 +12,14 @@ type = intent
variant = AA 0.4 variant = AA 0.4
[values] [values]
speed_infill = 50 _plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 0.5
top_bottom_thickness = 1.05 acceleration_print = 2500
acceleration_wall_0 = 1000
inset_direction = inside_out
jerk_wall_0 = 20
speed_print = 50
speed_roofing = =math.ceil(speed_wall*(35/50))
speed_wall_0 = =math.ceil(speed_wall*(20/50))
speed_wall_x = =math.ceil(speed_wall*(35/50))
top_bottom_thickness = =max(1.2 , layer_height * 6)

View file

@ -12,9 +12,13 @@ type = intent
variant = AA 0.4 variant = AA 0.4
[values] [values]
_plugin__curaenginegradualflow__0_1_0__max_flow_acceleration = 1
infill_pattern = ='zigzag' if infill_sparse_density > 80 else 'triangles'
infill_sparse_density = 20
jerk_print = 30 jerk_print = 30
speed_infill = =speed_print speed_infill = =speed_print
speed_print = 30 speed_print = 35
speed_roofing = =speed_topbottom
speed_topbottom = =speed_print speed_topbottom = =speed_print
speed_wall = =speed_print speed_wall = =speed_print
speed_wall_0 = =speed_wall speed_wall_0 = =speed_wall

Some files were not shown because too many files have changed in this diff Show more