mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-06 21:44:01 -06:00
Merge branch 'master' into fix_version_upgrade_returning_none
This commit is contained in:
commit
c765615f1a
104 changed files with 13958 additions and 52759 deletions
|
@ -17,6 +17,7 @@ if(CURA_DEBUGMODE)
|
|||
set(_cura_debugmode "ON")
|
||||
endif()
|
||||
|
||||
set(CURA_APP_DISPLAY_NAME "Ultimaker Cura" CACHE STRING "Display name of Cura")
|
||||
set(CURA_VERSION "master" CACHE STRING "Version name of Cura")
|
||||
set(CURA_BUILDTYPE "" CACHE STRING "Build type of Cura, eg. 'PPA'")
|
||||
set(CURA_SDK_VERSION "" CACHE STRING "SDK version of Cura")
|
||||
|
|
43
Jenkinsfile
vendored
43
Jenkinsfile
vendored
|
@ -38,20 +38,9 @@ parallel_nodes(['linux && cura', 'windows && cura'])
|
|||
{
|
||||
if (isUnix())
|
||||
{
|
||||
// For Linux to show everything
|
||||
def branch = env.BRANCH_NAME
|
||||
if(!fileExists("${env.CURA_ENVIRONMENT_PATH}/${branch}"))
|
||||
{
|
||||
branch = "master"
|
||||
}
|
||||
def uranium_dir = get_workspace_dir("Ultimaker/Uranium/${branch}")
|
||||
|
||||
// For Linux
|
||||
try {
|
||||
sh """
|
||||
cd ..
|
||||
export PYTHONPATH=.:"${uranium_dir}"
|
||||
${env.CURA_ENVIRONMENT_PATH}/${branch}/bin/pytest -x --verbose --full-trace --capture=no ./tests
|
||||
"""
|
||||
sh 'make CTEST_OUTPUT_ON_FAILURE=TRUE test'
|
||||
} catch(e)
|
||||
{
|
||||
currentBuild.result = "UNSTABLE"
|
||||
|
@ -70,34 +59,6 @@ parallel_nodes(['linux && cura', 'windows && cura'])
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Code Style')
|
||||
{
|
||||
if (isUnix())
|
||||
{
|
||||
// For Linux to show everything.
|
||||
// CMake also runs this test, but if it fails then the test just shows "failed" without details of what exactly failed.
|
||||
def branch = env.BRANCH_NAME
|
||||
if(!fileExists("${env.CURA_ENVIRONMENT_PATH}/${branch}"))
|
||||
{
|
||||
branch = "master"
|
||||
}
|
||||
def uranium_dir = get_workspace_dir("Ultimaker/Uranium/${branch}")
|
||||
|
||||
try
|
||||
{
|
||||
sh """
|
||||
cd ..
|
||||
export PYTHONPATH=.:"${uranium_dir}"
|
||||
${env.CURA_ENVIRONMENT_PATH}/${branch}/bin/python3 run_mypy.py
|
||||
"""
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
currentBuild.result = "UNSTABLE"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ include(CMakeParseArguments)
|
|||
|
||||
find_package(PythonInterp 3.5.0 REQUIRED)
|
||||
|
||||
add_custom_target(test-verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose)
|
||||
|
||||
function(cura_add_test)
|
||||
set(_single_args NAME DIRECTORY PYTHONPATH)
|
||||
cmake_parse_arguments("" "" "${_single_args}" "" ${ARGN})
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from cura.API.Interface.Settings import Settings
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -23,9 +22,6 @@ if TYPE_CHECKING:
|
|||
|
||||
class Interface:
|
||||
|
||||
# For now we use the same API version to be consistent.
|
||||
VERSION = PluginRegistry.APIVersion
|
||||
|
||||
def __init__(self, application: "CuraApplication") -> None:
|
||||
# API methods specific to the settings portion of the UI
|
||||
self.settings = Settings(application)
|
||||
|
|
|
@ -4,7 +4,6 @@ from typing import Optional, TYPE_CHECKING
|
|||
|
||||
from PyQt5.QtCore import QObject, pyqtProperty
|
||||
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from cura.API.Backups import Backups
|
||||
from cura.API.Interface import Interface
|
||||
from cura.API.Account import Account
|
||||
|
@ -22,7 +21,6 @@ if TYPE_CHECKING:
|
|||
class CuraAPI(QObject):
|
||||
|
||||
# For now we use the same API version to be consistent.
|
||||
VERSION = PluginRegistry.APIVersion
|
||||
__instance = None # type: "CuraAPI"
|
||||
_application = None # type: CuraApplication
|
||||
|
||||
|
@ -62,4 +60,4 @@ class CuraAPI(QObject):
|
|||
|
||||
@property
|
||||
def interface(self) -> "Interface":
|
||||
return self._interface
|
||||
return self._interface
|
||||
|
|
|
@ -489,7 +489,9 @@ class BuildVolume(SceneNode):
|
|||
|
||||
def _updateRaftThickness(self):
|
||||
old_raft_thickness = self._raft_thickness
|
||||
self._adhesion_type = self._global_container_stack.getProperty("adhesion_type", "value")
|
||||
if self._global_container_stack.extruders:
|
||||
# This might be called before the extruder stacks have initialised, in which case getting the adhesion_type fails
|
||||
self._adhesion_type = self._global_container_stack.getProperty("adhesion_type", "value")
|
||||
self._raft_thickness = 0.0
|
||||
if self._adhesion_type == "raft":
|
||||
self._raft_thickness = (
|
||||
|
|
|
@ -128,12 +128,13 @@ if TYPE_CHECKING:
|
|||
numpy.seterr(all = "ignore")
|
||||
|
||||
try:
|
||||
from cura.CuraVersion import CuraVersion, CuraBuildType, CuraDebugMode, CuraSDKVersion # type: ignore
|
||||
from cura.CuraVersion import CuraAppDisplayName, CuraVersion, CuraBuildType, CuraDebugMode, CuraSDKVersion # type: ignore
|
||||
except ImportError:
|
||||
CuraAppDisplayName = "Ultimaker Cura"
|
||||
CuraVersion = "master" # [CodeStyle: Reflecting imported value]
|
||||
CuraBuildType = ""
|
||||
CuraDebugMode = False
|
||||
CuraSDKVersion = ""
|
||||
CuraSDKVersion = "5.0.0"
|
||||
|
||||
|
||||
class CuraApplication(QtApplication):
|
||||
|
@ -161,7 +162,9 @@ class CuraApplication(QtApplication):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(name = "cura",
|
||||
app_display_name = CuraAppDisplayName,
|
||||
version = CuraVersion,
|
||||
api_version = CuraSDKVersion,
|
||||
buildtype = CuraBuildType,
|
||||
is_debug_mode = CuraDebugMode,
|
||||
tray_icon_name = "cura-icon-32.png",
|
||||
|
@ -429,34 +432,30 @@ class CuraApplication(QtApplication):
|
|||
|
||||
self.setRequiredPlugins([
|
||||
# Misc.:
|
||||
"ConsoleLogger",
|
||||
"CuraEngineBackend",
|
||||
"UserAgreement",
|
||||
"FileLogger",
|
||||
"XmlMaterialProfile",
|
||||
"Toolbox",
|
||||
"PrepareStage",
|
||||
"MonitorStage",
|
||||
"LocalFileOutputDevice",
|
||||
"LocalContainerProvider",
|
||||
"ConsoleLogger", #You want to be able to read the log if something goes wrong.
|
||||
"CuraEngineBackend", #Cura is useless without this one since you can't slice.
|
||||
"UserAgreement", #Our lawyers want every user to see this at least once.
|
||||
"FileLogger", #You want to be able to read the log if something goes wrong.
|
||||
"XmlMaterialProfile", #Cura crashes without this one.
|
||||
"Toolbox", #This contains the interface to enable/disable plug-ins, so if you disable it you can't enable it back.
|
||||
"PrepareStage", #Cura is useless without this one since you can't load models.
|
||||
"MonitorStage", #Major part of Cura's functionality.
|
||||
"LocalFileOutputDevice", #Major part of Cura's functionality.
|
||||
"LocalContainerProvider", #Cura is useless without any profiles or setting definitions.
|
||||
|
||||
# Views:
|
||||
"SimpleView",
|
||||
"SimulationView",
|
||||
"SolidView",
|
||||
"SimpleView", #Dependency of SolidView.
|
||||
"SolidView", #Displays models. Cura is useless without it.
|
||||
|
||||
# Readers & Writers:
|
||||
"GCodeWriter",
|
||||
"STLReader",
|
||||
"3MFWriter",
|
||||
"GCodeWriter", #Cura is useless if it can't write its output.
|
||||
"STLReader", #Most common model format, so disabling this makes Cura 90% useless.
|
||||
"3MFWriter", #Required for writing project files.
|
||||
|
||||
# Tools:
|
||||
"CameraTool",
|
||||
"MirrorTool",
|
||||
"RotateTool",
|
||||
"ScaleTool",
|
||||
"SelectionTool",
|
||||
"TranslateTool",
|
||||
"CameraTool", #Needed to see the scene. Cura is useless without it.
|
||||
"SelectionTool", #Dependency of the rest of the tools.
|
||||
"TranslateTool", #You'll need this for almost every print.
|
||||
])
|
||||
self._i18n_catalog = i18nCatalog("cura")
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright (c) 2015 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
CuraAppDisplayName = "@CURA_APP_DISPLAY_NAME@"
|
||||
CuraVersion = "@CURA_VERSION@"
|
||||
CuraBuildType = "@CURA_BUILDTYPE@"
|
||||
CuraDebugMode = True if "@_cura_debugmode@" == "ON" else False
|
||||
|
|
|
@ -644,8 +644,11 @@ class MaterialManager(QObject):
|
|||
machine_manager = self._application.getMachineManager()
|
||||
extruder_stack = machine_manager.activeStack
|
||||
|
||||
machine_definition = self._application.getGlobalContainerStack().definition
|
||||
preferred_material = machine_definition.getMetaDataEntry("preferred_material")
|
||||
|
||||
approximate_diameter = str(extruder_stack.approximateMaterialDiameter)
|
||||
root_material_id = "generic_pla"
|
||||
root_material_id = preferred_material if preferred_material else "generic_pla"
|
||||
root_material_id = self.getRootMaterialIDForDiameter(root_material_id, approximate_diameter)
|
||||
material_group = self.getMaterialGroup(root_material_id)
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ from .QualityGroup import QualityGroup
|
|||
from .QualityNode import QualityNode
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||
from UM.Settings.Interfaces import DefinitionContainerInterface
|
||||
from cura.Settings.GlobalStack import GlobalStack
|
||||
from .QualityChangesGroup import QualityChangesGroup
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
@ -538,7 +538,7 @@ class QualityManager(QObject):
|
|||
# Example: for an Ultimaker 3 Extended, it has "quality_definition = ultimaker3". This means Ultimaker 3 Extended
|
||||
# shares the same set of qualities profiles as Ultimaker 3.
|
||||
#
|
||||
def getMachineDefinitionIDForQualitySearch(machine_definition: "DefinitionContainer",
|
||||
def getMachineDefinitionIDForQualitySearch(machine_definition: "DefinitionContainerInterface",
|
||||
default_definition_id: str = "fdmprinter") -> str:
|
||||
machine_definition_id = default_definition_id
|
||||
if parseBool(machine_definition.getMetaDataEntry("has_machine_quality", False)):
|
||||
|
|
|
@ -120,7 +120,7 @@ class AuthorizationService:
|
|||
"redirect_uri": self._settings.CALLBACK_URL,
|
||||
"scope": self._settings.CLIENT_SCOPES,
|
||||
"response_type": "code",
|
||||
"state": "CuraDriveIsAwesome",
|
||||
"state": "(.Y.)",
|
||||
"code_challenge": challenge_code,
|
||||
"code_challenge_method": "S512"
|
||||
})
|
||||
|
|
|
@ -272,7 +272,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
|||
head_and_fans = self._getHeadAndFans().intersectionConvexHulls(mirrored)
|
||||
|
||||
# Min head hull is used for the push free
|
||||
convex_hull = self._compute2DConvexHeadFull()
|
||||
convex_hull = self._compute2DConvexHull()
|
||||
if convex_hull:
|
||||
return convex_hull.getMinkowskiHull(head_and_fans)
|
||||
return None
|
||||
|
|
|
@ -419,13 +419,13 @@ class ContainerManager(QObject):
|
|||
self._container_name_filters[name_filter] = entry
|
||||
|
||||
## Import single profile, file_url does not have to end with curaprofile
|
||||
@pyqtSlot(QUrl, result="QVariantMap")
|
||||
def importProfile(self, file_url: QUrl):
|
||||
@pyqtSlot(QUrl, result = "QVariantMap")
|
||||
def importProfile(self, file_url: QUrl) -> Dict[str, str]:
|
||||
if not file_url.isValid():
|
||||
return
|
||||
return {"status": "error", "message": catalog.i18nc("@info:status", "Invalid file URL:") + " " + str(file_url)}
|
||||
path = file_url.toLocalFile()
|
||||
if not path:
|
||||
return
|
||||
return {"status": "error", "message": catalog.i18nc("@info:status", "Invalid file URL:") + " " + str(file_url)}
|
||||
return self._container_registry.importProfile(path)
|
||||
|
||||
@pyqtSlot(QObject, QUrl, str)
|
||||
|
|
|
@ -5,12 +5,12 @@ import os
|
|||
import re
|
||||
import configparser
|
||||
|
||||
from typing import cast, Optional
|
||||
|
||||
from typing import cast, Dict, Optional
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
|
||||
from UM.Decorators import override
|
||||
from UM.Settings.ContainerFormatError import ContainerFormatError
|
||||
from UM.Settings.Interfaces import ContainerInterface
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.ContainerStack import ContainerStack
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
|
@ -28,7 +28,7 @@ from . import GlobalStack
|
|||
|
||||
import cura.CuraApplication
|
||||
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
|
||||
from cura.ReaderWriters.ProfileReader import NoProfileException
|
||||
from cura.ReaderWriters.ProfileReader import NoProfileException, ProfileReader
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
@ -161,20 +161,20 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
|
||||
## Imports a profile from a file
|
||||
#
|
||||
# \param file_name \type{str} the full path and filename of the profile to import
|
||||
# \return \type{Dict} dict with a 'status' key containing the string 'ok' or 'error', and a 'message' key
|
||||
# containing a message for the user
|
||||
def importProfile(self, file_name):
|
||||
# \param file_name The full path and filename of the profile to import.
|
||||
# \return Dict with a 'status' key containing the string 'ok' or 'error',
|
||||
# and a 'message' key containing a message for the user.
|
||||
def importProfile(self, file_name: str) -> Dict[str, str]:
|
||||
Logger.log("d", "Attempting to import profile %s", file_name)
|
||||
if not file_name:
|
||||
return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", file_name, "Invalid path")}
|
||||
return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename>!", "Failed to import profile from <filename>{0}</filename>: {1}", file_name, "Invalid path")}
|
||||
|
||||
plugin_registry = PluginRegistry.getInstance()
|
||||
extension = file_name.split(".")[-1]
|
||||
|
||||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if not global_stack:
|
||||
return
|
||||
return {"status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename>!", "Can't import profile from <filename>{0}</filename> before a printer is added.", file_name)}
|
||||
|
||||
machine_extruders = []
|
||||
for position in sorted(global_stack.extruders):
|
||||
|
@ -183,7 +183,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
for plugin_id, meta_data in self._getIOPlugins("profile_reader"):
|
||||
if meta_data["profile_reader"][0]["extension"] != extension:
|
||||
continue
|
||||
profile_reader = plugin_registry.getPluginObject(plugin_id)
|
||||
profile_reader = cast(ProfileReader, plugin_registry.getPluginObject(plugin_id))
|
||||
try:
|
||||
profile_or_list = profile_reader.read(file_name) # Try to open the file with the profile reader.
|
||||
except NoProfileException:
|
||||
|
@ -221,13 +221,13 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
# Make sure we have a profile_definition in the file:
|
||||
if profile_definition is None:
|
||||
break
|
||||
machine_definition = self.findDefinitionContainers(id = profile_definition)
|
||||
if not machine_definition:
|
||||
machine_definitions = self.findDefinitionContainers(id = profile_definition)
|
||||
if not machine_definitions:
|
||||
Logger.log("e", "Incorrect profile [%s]. Unknown machine type [%s]", file_name, profile_definition)
|
||||
return {"status": "error",
|
||||
"message": catalog.i18nc("@info:status Don't translate the XML tags <filename>!", "This profile <filename>{0}</filename> contains incorrect data, could not import it.", file_name)
|
||||
}
|
||||
machine_definition = machine_definition[0]
|
||||
machine_definition = machine_definitions[0]
|
||||
|
||||
# Get the expected machine definition.
|
||||
# i.e.: We expect gcode for a UM2 Extended to be defined as normal UM2 gcode...
|
||||
|
@ -274,11 +274,12 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
setting_value = global_profile.getProperty(qc_setting_key, "value")
|
||||
|
||||
setting_definition = global_stack.getSettingDefinition(qc_setting_key)
|
||||
new_instance = SettingInstance(setting_definition, profile)
|
||||
new_instance.setProperty("value", setting_value)
|
||||
new_instance.resetState() # Ensure that the state is not seen as a user state.
|
||||
profile.addInstance(new_instance)
|
||||
profile.setDirty(True)
|
||||
if setting_definition is not None:
|
||||
new_instance = SettingInstance(setting_definition, profile)
|
||||
new_instance.setProperty("value", setting_value)
|
||||
new_instance.resetState() # Ensure that the state is not seen as a user state.
|
||||
profile.addInstance(new_instance)
|
||||
profile.setDirty(True)
|
||||
|
||||
global_profile.removeInstance(qc_setting_key, postpone_emit=True)
|
||||
extruder_profiles.append(profile)
|
||||
|
@ -290,7 +291,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
for profile_index, profile in enumerate(profile_or_list):
|
||||
if profile_index == 0:
|
||||
# This is assumed to be the global profile
|
||||
profile_id = (global_stack.getBottom().getId() + "_" + name_seed).lower().replace(" ", "_")
|
||||
profile_id = (cast(ContainerInterface, global_stack.getBottom()).getId() + "_" + name_seed).lower().replace(" ", "_")
|
||||
|
||||
elif profile_index < len(machine_extruders) + 1:
|
||||
# This is assumed to be an extruder profile
|
||||
|
|
|
@ -5,6 +5,7 @@ from typing import Any, List, Optional, TYPE_CHECKING
|
|||
|
||||
from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
|
||||
from UM.Settings.SettingFunction import SettingFunction
|
||||
from UM.Logger import Logger
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
@ -38,7 +39,11 @@ class CuraFormulaFunctions:
|
|||
extruder_position = int(machine_manager.defaultExtruderPosition)
|
||||
|
||||
global_stack = machine_manager.activeMachine
|
||||
extruder_stack = global_stack.extruders[str(extruder_position)]
|
||||
try:
|
||||
extruder_stack = global_stack.extruders[str(extruder_position)]
|
||||
except KeyError:
|
||||
Logger.log("w", "Value for %s of extruder %s was requested, but that extruder is not available" % (property_key, extruder_position))
|
||||
return None
|
||||
|
||||
value = extruder_stack.getRawProperty(property_key, "value", context = context)
|
||||
if isinstance(value, SettingFunction):
|
||||
|
|
156
installer.nsi
156
installer.nsi
|
@ -1,156 +0,0 @@
|
|||
!ifndef VERSION
|
||||
!define VERSION '15.09.80'
|
||||
!endif
|
||||
|
||||
; The name of the installer
|
||||
Name "Cura ${VERSION}"
|
||||
|
||||
; The file to write
|
||||
OutFile "Cura_${VERSION}.exe"
|
||||
|
||||
; The default installation directory
|
||||
InstallDir $PROGRAMFILES\Cura_${VERSION}
|
||||
|
||||
; Registry key to check for directory (so if you install again, it will
|
||||
; overwrite the old one automatically)
|
||||
InstallDirRegKey HKLM "Software\Cura_${VERSION}" "Install_Dir"
|
||||
|
||||
; Request application privileges for Windows Vista
|
||||
RequestExecutionLevel admin
|
||||
|
||||
; Set the LZMA compressor to reduce size.
|
||||
SetCompressor /SOLID lzma
|
||||
;--------------------------------
|
||||
|
||||
!include "MUI2.nsh"
|
||||
!include "Library.nsh"
|
||||
|
||||
; !define MUI_ICON "dist/resources/cura.ico"
|
||||
!define MUI_BGCOLOR FFFFFF
|
||||
|
||||
; Directory page defines
|
||||
!define MUI_DIRECTORYPAGE_VERIFYONLEAVE
|
||||
|
||||
; Header
|
||||
; Don't show the component description box
|
||||
!define MUI_COMPONENTSPAGE_NODESC
|
||||
|
||||
;Do not leave (Un)Installer page automaticly
|
||||
!define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
|
||||
|
||||
;Run Cura after installing
|
||||
!define MUI_FINISHPAGE_RUN
|
||||
!define MUI_FINISHPAGE_RUN_TEXT "Start Cura ${VERSION}"
|
||||
!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink"
|
||||
|
||||
;Add an option to show release notes
|
||||
!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\plugins\ChangeLogPlugin\changelog.txt"
|
||||
|
||||
; Pages
|
||||
;!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_COMPONENTS
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
!insertmacro MUI_UNPAGE_FINISH
|
||||
|
||||
; Languages
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
; Reserve Files
|
||||
!insertmacro MUI_RESERVEFILE_LANGDLL
|
||||
ReserveFile '${NSISDIR}\Plugins\InstallOptions.dll'
|
||||
|
||||
;--------------------------------
|
||||
|
||||
; The stuff to install
|
||||
Section "Cura ${VERSION}"
|
||||
|
||||
SectionIn RO
|
||||
|
||||
; Set output path to the installation directory.
|
||||
SetOutPath $INSTDIR
|
||||
|
||||
; Put file there
|
||||
File /r "dist\"
|
||||
|
||||
; Write the installation path into the registry
|
||||
WriteRegStr HKLM "SOFTWARE\Cura_${VERSION}" "Install_Dir" "$INSTDIR"
|
||||
|
||||
; Write the uninstall keys for Windows
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}" "DisplayName" "Cura ${VERSION}"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}" "UninstallString" '"$INSTDIR\uninstall.exe"'
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}" "NoModify" 1
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}" "NoRepair" 1
|
||||
WriteUninstaller "uninstall.exe"
|
||||
|
||||
; Write start menu entries for all users
|
||||
SetShellVarContext all
|
||||
|
||||
CreateDirectory "$SMPROGRAMS\Cura ${VERSION}"
|
||||
CreateShortCut "$SMPROGRAMS\Cura ${VERSION}\Uninstall Cura ${VERSION}.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
|
||||
CreateShortCut "$SMPROGRAMS\Cura ${VERSION}\Cura ${VERSION}.lnk" "$INSTDIR\Cura.exe" '' "$INSTDIR\Cura.exe" 0
|
||||
|
||||
SectionEnd
|
||||
|
||||
Function LaunchLink
|
||||
; Write start menu entries for all users
|
||||
SetShellVarContext all
|
||||
Exec '"$WINDIR\explorer.exe" "$SMPROGRAMS\Cura ${VERSION}\Cura ${VERSION}.lnk"'
|
||||
FunctionEnd
|
||||
|
||||
Section "Install Visual Studio 2010 Redistributable"
|
||||
SetOutPath "$INSTDIR"
|
||||
File "vcredist_2010_20110908_x86.exe"
|
||||
|
||||
IfSilent +2
|
||||
ExecWait '"$INSTDIR\vcredist_2010_20110908_x86.exe" /q /norestart'
|
||||
|
||||
SectionEnd
|
||||
|
||||
Section "Install Arduino Drivers"
|
||||
; Set output path to the driver directory.
|
||||
SetOutPath "$INSTDIR\drivers\"
|
||||
File /r "drivers\"
|
||||
|
||||
${If} ${RunningX64}
|
||||
IfSilent +2
|
||||
ExecWait '"$INSTDIR\drivers\dpinst64.exe" /lm'
|
||||
${Else}
|
||||
IfSilent +2
|
||||
ExecWait '"$INSTDIR\drivers\dpinst32.exe" /lm'
|
||||
${EndIf}
|
||||
SectionEnd
|
||||
|
||||
Section "Open STL files with Cura"
|
||||
${registerExtension} "$INSTDIR\Cura.exe" ".stl" "STL_File"
|
||||
SectionEnd
|
||||
|
||||
Section /o "Open OBJ files with Cura"
|
||||
WriteRegStr HKCR .obj "" "Cura OBJ model file"
|
||||
DeleteRegValue HKCR .obj "Content Type"
|
||||
WriteRegStr HKCR "Cura OBJ model file\DefaultIcon" "" "$INSTDIR\Cura.exe,0"
|
||||
WriteRegStr HKCR "Cura OBJ model file\shell" "" "open"
|
||||
WriteRegStr HKCR "Cura OBJ model file\shell\open\command" "" '"$INSTDIR\Cura.exe" "%1"'
|
||||
SectionEnd
|
||||
|
||||
;--------------------------------
|
||||
|
||||
; Uninstaller
|
||||
|
||||
Section "Uninstall"
|
||||
|
||||
; Remove registry keys
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Cura_${VERSION}"
|
||||
DeleteRegKey HKLM "SOFTWARE\Cura_${VERSION}"
|
||||
|
||||
; Write start menu entries for all users
|
||||
SetShellVarContext all
|
||||
; Remove directories used
|
||||
RMDir /r "$SMPROGRAMS\Cura ${VERSION}"
|
||||
RMDir /r "$INSTDIR"
|
||||
|
||||
SectionEnd
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2015 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
|
@ -29,6 +29,7 @@ class ChangeLog(Extension, QObject,):
|
|||
self._change_logs = None
|
||||
Application.getInstance().engineCreatedSignal.connect(self._onEngineCreated)
|
||||
Application.getInstance().getPreferences().addPreference("general/latest_version_changelog_shown", "2.0.0") #First version of CURA with uranium
|
||||
self.setMenuName(catalog.i18nc("@item:inmenu", "Changelog"))
|
||||
self.addMenuItem(catalog.i18nc("@item:inmenu", "Show Changelog"), self.showChangelog)
|
||||
|
||||
def getChangeLogs(self):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"source_version": "15.04",
|
||||
"target_version": 3,
|
||||
"target_version": "4.5",
|
||||
|
||||
"translation": {
|
||||
"machine_nozzle_size": "nozzle_size",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import configparser # For reading the legacy profile INI files.
|
||||
|
@ -6,6 +6,7 @@ import io
|
|||
import json # For reading the Dictionary of Doom.
|
||||
import math # For mathematical operations included in the Dictionary of Doom.
|
||||
import os.path # For concatenating the path to the plugin and the relative path to the Dictionary of Doom.
|
||||
from typing import Dict
|
||||
|
||||
from UM.Application import Application # To get the machine manager to create the new profile in.
|
||||
from UM.Logger import Logger # Logging errors.
|
||||
|
@ -33,10 +34,11 @@ class LegacyProfileReader(ProfileReader):
|
|||
# \param json The JSON file to load the default setting values from. This
|
||||
# should not be a URL but a pre-loaded JSON handle.
|
||||
# \return A dictionary of the default values of the legacy Cura version.
|
||||
def prepareDefaults(self, json):
|
||||
def prepareDefaults(self, json: Dict[str, Dict[str, str]]) -> Dict[str, str]:
|
||||
defaults = {}
|
||||
for key in json["defaults"]: # We have to copy over all defaults from the JSON handle to a normal dict.
|
||||
defaults[key] = json["defaults"][key]
|
||||
if "defaults" in json:
|
||||
for key in json["defaults"]: # We have to copy over all defaults from the JSON handle to a normal dict.
|
||||
defaults[key] = json["defaults"][key]
|
||||
return defaults
|
||||
|
||||
## Prepares the local variables that can be used in evaluation of computing
|
||||
|
@ -80,11 +82,10 @@ class LegacyProfileReader(ProfileReader):
|
|||
Logger.log("i", "Importing legacy profile from file " + file_name + ".")
|
||||
container_registry = ContainerRegistry.getInstance()
|
||||
profile_id = container_registry.uniqueName("Imported Legacy Profile")
|
||||
profile = InstanceContainer(profile_id) # Create an empty profile.
|
||||
|
||||
parser = configparser.ConfigParser(interpolation = None)
|
||||
input_parser = configparser.ConfigParser(interpolation = None)
|
||||
try:
|
||||
parser.read([file_name]) # Parse the INI file.
|
||||
input_parser.read([file_name]) # Parse the INI file.
|
||||
except Exception as e:
|
||||
Logger.log("e", "Unable to open legacy profile %s: %s", file_name, str(e))
|
||||
return None
|
||||
|
@ -92,7 +93,7 @@ class LegacyProfileReader(ProfileReader):
|
|||
# Legacy Cura saved the profile under the section "profile_N" where N is the ID of a machine, except when you export in which case it saves it in the section "profile".
|
||||
# Since importing multiple machine profiles is out of scope, just import the first section we find.
|
||||
section = ""
|
||||
for found_section in parser.sections():
|
||||
for found_section in input_parser.sections():
|
||||
if found_section.startswith("profile"):
|
||||
section = found_section
|
||||
break
|
||||
|
@ -110,15 +111,13 @@ class LegacyProfileReader(ProfileReader):
|
|||
return None
|
||||
|
||||
defaults = self.prepareDefaults(dict_of_doom)
|
||||
legacy_settings = self.prepareLocals(parser, section, defaults) #Gets the settings from the legacy profile.
|
||||
legacy_settings = self.prepareLocals(input_parser, section, defaults) #Gets the settings from the legacy profile.
|
||||
|
||||
#Check the target version in the Dictionary of Doom with this application version.
|
||||
if "target_version" not in dict_of_doom:
|
||||
Logger.log("e", "Dictionary of Doom has no target version. Is it the correct JSON file?")
|
||||
return None
|
||||
if InstanceContainer.Version != dict_of_doom["target_version"]:
|
||||
Logger.log("e", "Dictionary of Doom of legacy profile reader (version %s) is not in sync with the current instance container version (version %s)!", dict_of_doom["target_version"], str(InstanceContainer.Version))
|
||||
return None
|
||||
# Serialised format into version 4.5. Do NOT upgrade this, let the version upgrader handle it.
|
||||
output_parser = configparser.ConfigParser(interpolation = None)
|
||||
output_parser.add_section("general")
|
||||
output_parser.add_section("metadata")
|
||||
output_parser.add_section("values")
|
||||
|
||||
if "translation" not in dict_of_doom:
|
||||
Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?")
|
||||
|
@ -127,7 +126,7 @@ class LegacyProfileReader(ProfileReader):
|
|||
quality_definition = current_printer_definition.getMetaDataEntry("quality_definition")
|
||||
if not quality_definition:
|
||||
quality_definition = current_printer_definition.getId()
|
||||
profile.setDefinition(quality_definition)
|
||||
output_parser["general"]["definition"] = quality_definition
|
||||
for new_setting in dict_of_doom["translation"]: # Evaluate all new settings that would get a value from the translations.
|
||||
old_setting_expression = dict_of_doom["translation"][new_setting]
|
||||
compiled = compile(old_setting_expression, new_setting, "eval")
|
||||
|
@ -140,37 +139,34 @@ class LegacyProfileReader(ProfileReader):
|
|||
definitions = current_printer_definition.findDefinitions(key = new_setting)
|
||||
if definitions:
|
||||
if new_value != value_using_defaults and definitions[0].default_value != new_value: # Not equal to the default in the new Cura OR the default in the legacy Cura.
|
||||
profile.setProperty(new_setting, "value", new_value) # Store the setting in the profile!
|
||||
output_parser["values"][new_setting] = str(new_value) # Store the setting in the profile!
|
||||
|
||||
if len(profile.getAllKeys()) == 0:
|
||||
if len(output_parser["values"]) == 0:
|
||||
Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.")
|
||||
|
||||
profile.setMetaDataEntry("type", "profile")
|
||||
# don't know what quality_type it is based on, so use "normal" by default
|
||||
profile.setMetaDataEntry("quality_type", "normal")
|
||||
profile.setName(profile_id)
|
||||
profile.setDirty(True)
|
||||
output_parser["general"]["version"] = "4"
|
||||
output_parser["general"]["name"] = profile_id
|
||||
output_parser["metadata"]["type"] = "quality_changes"
|
||||
output_parser["metadata"]["quality_type"] = "normal" # Don't know what quality_type it is based on, so use "normal" by default.
|
||||
output_parser["metadata"]["position"] = "0" # We only support single extrusion.
|
||||
output_parser["metadata"]["setting_version"] = "5" # What the dictionary of doom is made for.
|
||||
|
||||
#Serialise and deserialise in order to perform the version upgrade.
|
||||
parser = configparser.ConfigParser(interpolation = None)
|
||||
data = profile.serialize()
|
||||
parser.read_string(data)
|
||||
parser["general"]["version"] = "1"
|
||||
if parser.has_section("values"):
|
||||
parser["settings"] = parser["values"]
|
||||
del parser["values"]
|
||||
# Serialise in order to perform the version upgrade.
|
||||
stream = io.StringIO()
|
||||
parser.write(stream)
|
||||
output_parser.write(stream)
|
||||
data = stream.getvalue()
|
||||
profile.deserialize(data)
|
||||
|
||||
# The definition can get reset to fdmprinter during the deserialization's upgrade. Here we set the definition
|
||||
# again.
|
||||
profile.setDefinition(quality_definition)
|
||||
profile = InstanceContainer(profile_id)
|
||||
profile.deserialize(data) # Also performs the version upgrade.
|
||||
profile.setDirty(True)
|
||||
|
||||
#We need to return one extruder stack and one global stack.
|
||||
global_container_id = container_registry.uniqueName("Global Imported Legacy Profile")
|
||||
# We duplicate the extruder profile into the global stack.
|
||||
# This may introduce some settings that are global in the extruder stack and some settings that are per-extruder in the global stack.
|
||||
# We don't care about that. The engine will ignore them anyway.
|
||||
global_profile = profile.duplicate(new_id = global_container_id, new_name = profile_id) #Needs to have the same name as the extruder profile.
|
||||
del global_profile.getMetaData()["position"] # Has no position because it's global.
|
||||
global_profile.setDirty(True)
|
||||
|
||||
profile_definition = "fdmprinter"
|
||||
|
|
190
plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py
Normal file
190
plugins/LegacyProfileReader/tests/TestLegacyProfileReader.py
Normal file
|
@ -0,0 +1,190 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import configparser # An input for some functions we're testing.
|
||||
import os.path # To find the integration test .ini files.
|
||||
import pytest # To register tests with.
|
||||
import unittest.mock # To mock the application, plug-in and container registry out.
|
||||
|
||||
import UM.Application # To mock the application out.
|
||||
import UM.PluginRegistry # To mock the plug-in registry out.
|
||||
import UM.Settings.ContainerRegistry # To mock the container registry out.
|
||||
import UM.Settings.InstanceContainer # To intercept the serialised data from the read() function.
|
||||
|
||||
import LegacyProfileReader as LegacyProfileReaderModule # To get the directory of the module.
|
||||
from LegacyProfileReader import LegacyProfileReader # The module we're testing.
|
||||
|
||||
@pytest.fixture
|
||||
def legacy_profile_reader():
|
||||
return LegacyProfileReader()
|
||||
|
||||
test_prepareDefaultsData = [
|
||||
{
|
||||
"defaults":
|
||||
{
|
||||
"foo": "bar"
|
||||
},
|
||||
"cheese": "delicious"
|
||||
},
|
||||
{
|
||||
"cat": "fluffy",
|
||||
"dog": "floofy"
|
||||
}
|
||||
]
|
||||
|
||||
@pytest.mark.parametrize("input", test_prepareDefaultsData)
|
||||
def test_prepareDefaults(legacy_profile_reader, input):
|
||||
output = legacy_profile_reader.prepareDefaults(input)
|
||||
if "defaults" in input:
|
||||
assert input["defaults"] == output
|
||||
else:
|
||||
assert output == {}
|
||||
|
||||
test_prepareLocalsData = [
|
||||
( # Ordinary case.
|
||||
{ # Parser data.
|
||||
"profile":
|
||||
{
|
||||
"layer_height": "0.2",
|
||||
"infill_density": "30"
|
||||
}
|
||||
},
|
||||
{ # Defaults.
|
||||
"layer_height": "0.1",
|
||||
"infill_density": "20",
|
||||
"line_width": "0.4"
|
||||
}
|
||||
),
|
||||
( # Empty data.
|
||||
{ # Parser data.
|
||||
"profile":
|
||||
{
|
||||
}
|
||||
},
|
||||
{ # Defaults.
|
||||
}
|
||||
),
|
||||
( # All defaults.
|
||||
{ # Parser data.
|
||||
"profile":
|
||||
{
|
||||
}
|
||||
},
|
||||
{ # Defaults.
|
||||
"foo": "bar",
|
||||
"boo": "far"
|
||||
}
|
||||
),
|
||||
( # Multiple config sections.
|
||||
{ # Parser data.
|
||||
"some_other_name":
|
||||
{
|
||||
"foo": "bar"
|
||||
},
|
||||
"profile":
|
||||
{
|
||||
"foo": "baz" #Not the same as in some_other_name
|
||||
}
|
||||
},
|
||||
{ # Defaults.
|
||||
"foo": "bla"
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
@pytest.mark.parametrize("parser_data, defaults", test_prepareLocalsData)
|
||||
def test_prepareLocals(legacy_profile_reader, parser_data, defaults):
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read_dict(parser_data)
|
||||
|
||||
output = legacy_profile_reader.prepareLocals(parser, "profile", defaults)
|
||||
|
||||
assert set(defaults.keys()) <= set(output.keys()) # All defaults must be in there.
|
||||
assert set(parser_data["profile"]) <= set(output.keys()) # All overwritten values must be in there.
|
||||
for key in output:
|
||||
if key in parser_data["profile"]:
|
||||
assert output[key] == parser_data["profile"][key] # If overwritten, must be the overwritten value.
|
||||
else:
|
||||
assert output[key] == defaults[key] # Otherwise must be equal to the default.
|
||||
|
||||
test_prepareLocalsNoSectionErrorData = [
|
||||
( # Section does not exist.
|
||||
{ # Parser data.
|
||||
"some_other_name":
|
||||
{
|
||||
"foo": "bar"
|
||||
},
|
||||
},
|
||||
{ # Defaults.
|
||||
"foo": "baz"
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
## Test cases where a key error is expected.
|
||||
@pytest.mark.parametrize("parser_data, defaults", test_prepareLocalsNoSectionErrorData)
|
||||
def test_prepareLocalsNoSectionError(legacy_profile_reader, parser_data, defaults):
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read_dict(parser_data)
|
||||
|
||||
with pytest.raises(configparser.NoSectionError):
|
||||
legacy_profile_reader.prepareLocals(parser, "profile", defaults)
|
||||
|
||||
intercepted_data = ""
|
||||
|
||||
@pytest.mark.parametrize("file_name", ["normal_case.ini"])
|
||||
def test_read(legacy_profile_reader, file_name):
|
||||
# Mock out all dependencies. Quite a lot!
|
||||
global_stack = unittest.mock.MagicMock()
|
||||
global_stack.getProperty = unittest.mock.MagicMock(return_value = 1) # For machine_extruder_count setting.
|
||||
def getMetaDataEntry(key, default_value = ""):
|
||||
if key == "quality_definition":
|
||||
return "mocked_quality_definition"
|
||||
if key == "has_machine_quality":
|
||||
return "True"
|
||||
global_stack.definition.getMetaDataEntry = getMetaDataEntry
|
||||
global_stack.definition.getId = unittest.mock.MagicMock(return_value = "mocked_global_definition")
|
||||
application = unittest.mock.MagicMock()
|
||||
application.getGlobalContainerStack = unittest.mock.MagicMock(return_value = global_stack)
|
||||
application_getInstance = unittest.mock.MagicMock(return_value = application)
|
||||
container_registry = unittest.mock.MagicMock()
|
||||
container_registry_getInstance = unittest.mock.MagicMock(return_value = container_registry)
|
||||
container_registry.uniqueName = unittest.mock.MagicMock(return_value = "Imported Legacy Profile")
|
||||
container_registry.findDefinitionContainers = unittest.mock.MagicMock(return_value = [global_stack.definition])
|
||||
UM.Settings.InstanceContainer.setContainerRegistry(container_registry)
|
||||
plugin_registry = unittest.mock.MagicMock()
|
||||
plugin_registry_getInstance = unittest.mock.MagicMock(return_value = plugin_registry)
|
||||
plugin_registry.getPluginPath = unittest.mock.MagicMock(return_value = os.path.dirname(LegacyProfileReaderModule.__file__))
|
||||
|
||||
# Mock out the resulting InstanceContainer so that we can intercept the data before it's passed through the version upgrader.
|
||||
def deserialize(self, data): # Intercepts the serialised data that we'd perform the version upgrade from when deserializing.
|
||||
global intercepted_data
|
||||
intercepted_data = data
|
||||
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read_string(data)
|
||||
self._metadata["position"] = parser["metadata"]["position"]
|
||||
def duplicate(self, new_id, new_name):
|
||||
self._metadata["id"] = new_id
|
||||
self._metadata["name"] = new_name
|
||||
return self
|
||||
|
||||
with unittest.mock.patch.object(UM.Application.Application, "getInstance", application_getInstance):
|
||||
with unittest.mock.patch.object(UM.Settings.ContainerRegistry.ContainerRegistry, "getInstance", container_registry_getInstance):
|
||||
with unittest.mock.patch.object(UM.PluginRegistry.PluginRegistry, "getInstance", plugin_registry_getInstance):
|
||||
with unittest.mock.patch.object(UM.Settings.InstanceContainer.InstanceContainer, "deserialize", deserialize):
|
||||
with unittest.mock.patch.object(UM.Settings.InstanceContainer.InstanceContainer, "duplicate", duplicate):
|
||||
result = legacy_profile_reader.read(os.path.join(os.path.dirname(__file__), file_name))
|
||||
|
||||
assert len(result) == 1
|
||||
|
||||
# Let's see what's inside the actual output file that we generated.
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read_string(intercepted_data)
|
||||
assert parser["general"]["definition"] == "mocked_quality_definition"
|
||||
assert parser["general"]["version"] == "4" # Yes, before we upgraded.
|
||||
assert parser["general"]["name"] == "Imported Legacy Profile" # Because we overwrote uniqueName.
|
||||
assert parser["metadata"]["type"] == "quality_changes"
|
||||
assert parser["metadata"]["quality_type"] == "normal"
|
||||
assert parser["metadata"]["position"] == "0"
|
||||
assert parser["metadata"]["setting_version"] == "5" # Yes, before we upgraded.
|
7
plugins/LegacyProfileReader/tests/normal_case.ini
Normal file
7
plugins/LegacyProfileReader/tests/normal_case.ini
Normal file
|
@ -0,0 +1,7 @@
|
|||
[profile]
|
||||
foo = bar
|
||||
boo = far
|
||||
fill_overlap = 3
|
||||
|
||||
[alterations]
|
||||
some = values
|
|
@ -32,7 +32,8 @@ class PostProcessingPlugin(QObject, Extension):
|
|||
def __init__(self, parent = None) -> None:
|
||||
QObject.__init__(self, parent)
|
||||
Extension.__init__(self)
|
||||
self.addMenuItem(i18n_catalog.i18n("Modify G-Code"), self.showPopup)
|
||||
self.setMenuName(i18n_catalog.i18nc("@item:inmenu", "Post Processing"))
|
||||
self.addMenuItem(i18n_catalog.i18nc("@item:inmenu", "Modify G-Code"), self.showPopup)
|
||||
self._view = None
|
||||
|
||||
# Loaded scripts are all scripts that can be used
|
||||
|
|
|
@ -187,7 +187,8 @@ Item
|
|||
var result = ""
|
||||
if (base.technicalDataSheetUrl !== undefined)
|
||||
{
|
||||
result += "<a href='%1'>%2</a>".arg(base.technicalDataSheetUrl).arg("Technical Data Sheet")
|
||||
var tds_name = catalog.i18nc("@action:label", "Technical Data Sheet")
|
||||
result += "<a href='%1'>%2</a>".arg(base.technicalDataSheetUrl).arg(tds_name)
|
||||
}
|
||||
if (base.safetyDataSheetUrl !== undefined)
|
||||
{
|
||||
|
@ -195,7 +196,8 @@ Item
|
|||
{
|
||||
result += "<br/>"
|
||||
}
|
||||
result += "<a href='%1'>%2</a>".arg(base.safetyDataSheetUrl).arg("Safety Data Sheet")
|
||||
var sds_name = catalog.i18nc("@action:label", "Safety Data Sheet")
|
||||
result += "<a href='%1'>%2</a>".arg(base.safetyDataSheetUrl).arg(sds_name)
|
||||
}
|
||||
if (base.printingGuidelinesUrl !== undefined)
|
||||
{
|
||||
|
@ -203,7 +205,8 @@ Item
|
|||
{
|
||||
result += "<br/>"
|
||||
}
|
||||
result += "<a href='%1'>%2</a>".arg(base.printingGuidelinesUrl).arg("Printing Guidelines")
|
||||
var pg_name = catalog.i18nc("@action:label", "Printing Guidelines")
|
||||
result += "<a href='%1'>%2</a>".arg(base.printingGuidelinesUrl).arg(pg_name)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ from UM.Qt.ListModel import ListModel
|
|||
from .ConfigsModel import ConfigsModel
|
||||
|
||||
|
||||
## Model that holds cura packages. By setting the filter property the instances held by this model can be changed.
|
||||
## Model that holds Cura packages. By setting the filter property the instances held by this model can be changed.
|
||||
class PackagesModel(ListModel):
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
|
@ -70,7 +70,7 @@ class PackagesModel(ListModel):
|
|||
|
||||
# Links is a list of dictionaries with "title" and "url". Convert this list into a dict so it's easier
|
||||
# to process.
|
||||
link_list = package['data']['links'] if 'links' in package['data'] else []
|
||||
link_list = package["data"]["links"] if "links" in package["data"] else []
|
||||
links_dict = {d["title"]: d["url"] for d in link_list}
|
||||
|
||||
if "author_id" not in package["author"] or "display_name" not in package["author"]:
|
||||
|
|
|
@ -172,18 +172,18 @@ class Toolbox(QObject, Extension):
|
|||
self._cloud_api_version = self._getCloudAPIVersion()
|
||||
self._cloud_api_root = self._getCloudAPIRoot()
|
||||
self._api_url = "{cloud_api_root}/cura-packages/v{cloud_api_version}/cura/v{sdk_version}".format(
|
||||
cloud_api_root=self._cloud_api_root,
|
||||
cloud_api_version=self._cloud_api_version,
|
||||
sdk_version=self._sdk_version
|
||||
cloud_api_root = self._cloud_api_root,
|
||||
cloud_api_version = self._cloud_api_version,
|
||||
sdk_version = self._sdk_version
|
||||
)
|
||||
self._request_urls = {
|
||||
"authors": QUrl("{base_url}/authors".format(base_url=self._api_url)),
|
||||
"packages": QUrl("{base_url}/packages".format(base_url=self._api_url)),
|
||||
"plugins_showcase": QUrl("{base_url}/showcase".format(base_url=self._api_url)),
|
||||
"plugins_available": QUrl("{base_url}/packages?package_type=plugin".format(base_url=self._api_url)),
|
||||
"materials_showcase": QUrl("{base_url}/showcase".format(base_url=self._api_url)),
|
||||
"materials_available": QUrl("{base_url}/packages?package_type=material".format(base_url=self._api_url)),
|
||||
"materials_generic": QUrl("{base_url}/packages?package_type=material&tags=generic".format(base_url=self._api_url))
|
||||
"authors": QUrl("{base_url}/authors".format(base_url = self._api_url)),
|
||||
"packages": QUrl("{base_url}/packages".format(base_url = self._api_url)),
|
||||
"plugins_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)),
|
||||
"plugins_available": QUrl("{base_url}/packages?package_type=plugin".format(base_url = self._api_url)),
|
||||
"materials_showcase": QUrl("{base_url}/showcase".format(base_url = self._api_url)),
|
||||
"materials_available": QUrl("{base_url}/packages?package_type=material".format(base_url = self._api_url)),
|
||||
"materials_generic": QUrl("{base_url}/packages?package_type=material&tags=generic".format(base_url = self._api_url))
|
||||
}
|
||||
|
||||
# Get the API root for the packages API depending on Cura version settings.
|
||||
|
@ -209,11 +209,11 @@ class Toolbox(QObject, Extension):
|
|||
# Get the packages version depending on Cura version settings.
|
||||
def _getSDKVersion(self) -> Union[int, str]:
|
||||
if not hasattr(cura, "CuraVersion"):
|
||||
return self._plugin_registry.APIVersion
|
||||
return self._application.getAPIVersion().getMajor()
|
||||
if not hasattr(cura.CuraVersion, "CuraSDKVersion"): # type: ignore
|
||||
return self._plugin_registry.APIVersion
|
||||
return self._application.getAPIVersion().getMajor()
|
||||
if not cura.CuraVersion.CuraSDKVersion: # type: ignore
|
||||
return self._plugin_registry.APIVersion
|
||||
return self._application.getAPIVersion().getMajor()
|
||||
return cura.CuraVersion.CuraSDKVersion # type: ignore
|
||||
|
||||
@pyqtSlot()
|
||||
|
@ -299,7 +299,7 @@ class Toolbox(QObject, Extension):
|
|||
for plugin_id in old_plugin_ids:
|
||||
# Neither the installed packages nor the packages that are scheduled to remove are old plugins
|
||||
if plugin_id not in installed_package_ids and plugin_id not in scheduled_to_remove_package_ids:
|
||||
Logger.log('i', 'Found a plugin that was installed with the old plugin browser: %s', plugin_id)
|
||||
Logger.log("i", "Found a plugin that was installed with the old plugin browser: %s", plugin_id)
|
||||
|
||||
old_metadata = self._plugin_registry.getMetaData(plugin_id)
|
||||
new_metadata = self._convertPluginMetadata(old_metadata)
|
||||
|
@ -511,7 +511,10 @@ class Toolbox(QObject, Extension):
|
|||
# version, we also need to check if the current one has a lower SDK version. If so, this package should also
|
||||
# be upgradable.
|
||||
elif remote_version == local_version:
|
||||
can_upgrade = local_package.get("sdk_version", 0) < remote_package.get("sdk_version", 0)
|
||||
# First read sdk_version_semver. If that doesn't exist, read just sdk_version (old version system).
|
||||
remote_sdk_version = Version(remote_package.get("sdk_version_semver", remote_package.get("sdk_version", 0)))
|
||||
local_sdk_version = Version(local_package.get("sdk_version_semver", local_package.get("sdk_version", 0)))
|
||||
can_upgrade = local_sdk_version < remote_sdk_version
|
||||
|
||||
return can_upgrade
|
||||
|
||||
|
|
|
@ -590,13 +590,27 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||
origin_name=change["origin_name"]))
|
||||
return result
|
||||
|
||||
def _createMaterialOutputModel(self, material_data) -> MaterialOutputModel:
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(type="material", GUID=material_data["guid"])
|
||||
if containers:
|
||||
color = containers[0].getMetaDataEntry("color_code")
|
||||
brand = containers[0].getMetaDataEntry("brand")
|
||||
material_type = containers[0].getMetaDataEntry("material")
|
||||
name = containers[0].getName()
|
||||
def _createMaterialOutputModel(self, material_data: Dict[str, Any]) -> "MaterialOutputModel":
|
||||
material_manager = CuraApplication.getInstance().getMaterialManager()
|
||||
material_group_list = material_manager.getMaterialGroupListByGUID(material_data["guid"])
|
||||
|
||||
# Sort the material groups by "is_read_only = True" first, and then the name alphabetically.
|
||||
read_only_material_group_list = list(filter(lambda x: x.is_read_only, material_group_list))
|
||||
non_read_only_material_group_list = list(filter(lambda x: not x.is_read_only, material_group_list))
|
||||
material_group = None
|
||||
if read_only_material_group_list:
|
||||
read_only_material_group_list = sorted(read_only_material_group_list, key = lambda x: x.name)
|
||||
material_group = read_only_material_group_list[0]
|
||||
elif non_read_only_material_group_list:
|
||||
non_read_only_material_group_list = sorted(non_read_only_material_group_list, key = lambda x: x.name)
|
||||
material_group = non_read_only_material_group_list[0]
|
||||
|
||||
if material_group:
|
||||
container = material_group.root_material_node.getContainer()
|
||||
color = container.getMetaDataEntry("color_code")
|
||||
brand = container.getMetaDataEntry("brand")
|
||||
material_type = container.getMetaDataEntry("material")
|
||||
name = container.getName()
|
||||
else:
|
||||
Logger.log("w",
|
||||
"Unable to find material with guid {guid}. Using data as provided by cluster".format(
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "3Dator GmbH",
|
||||
"manufacturer": "3Dator GmbH",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"supports_usb_connection": true,
|
||||
"platform": "3dator_platform.stl",
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"author": "TheTobby",
|
||||
"manufacturer": "Anycubic",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "anycubic_i3_mega_platform.stl",
|
||||
"has_materials": false,
|
||||
"has_machine_quality": true,
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"manufacturer": "Deltacomb 3D",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "deltacomb.stl",
|
||||
"has_machine_quality": true,
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform": "fabtotum_platform.stl",
|
||||
"icon": "fabtotum_platform.png",
|
||||
"has_machine_quality": true,
|
||||
"has_variants": true,
|
||||
"variants_name": "Head",
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
"machine_extruder_start_code":
|
||||
{
|
||||
"label": "Extruder Start G-Code",
|
||||
"description": "Start g-code to execute whenever turning the extruder on.",
|
||||
"description": "Start g-code to execute when switching to this extruder.",
|
||||
"type": "str",
|
||||
"default_value": "",
|
||||
"settable_per_mesh": false,
|
||||
|
@ -124,7 +124,7 @@
|
|||
"machine_extruder_end_code":
|
||||
{
|
||||
"label": "Extruder End G-Code",
|
||||
"description": "End g-code to execute whenever turning the extruder off.",
|
||||
"description": "End g-code to execute when switching away from this extruder.",
|
||||
"type": "str",
|
||||
"default_value": "",
|
||||
"settable_per_mesh": false,
|
||||
|
|
|
@ -2406,7 +2406,7 @@
|
|||
"switch_extruder_retraction_amount":
|
||||
{
|
||||
"label": "Nozzle Switch Retraction Distance",
|
||||
"description": "The amount of retraction: Set at 0 for no retraction at all. This should generally be the same as the length of the heat zone.",
|
||||
"description": "The amount of retraction when switching extruders. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone.",
|
||||
"type": "float",
|
||||
"unit": "mm",
|
||||
"enabled": "retraction_enable",
|
||||
|
@ -4139,6 +4139,20 @@
|
|||
"limit_to_extruder": "support_infill_extruder_nr",
|
||||
"settable_per_mesh": false
|
||||
},
|
||||
"minimum_support_area":
|
||||
{
|
||||
"label": "Minimum Support Area",
|
||||
"description": "Minimum area size for support polygons. Polygons which have an area smaller than this value will not be generated.",
|
||||
"unit": "mm²",
|
||||
"type": "float",
|
||||
"default_value": 0.0,
|
||||
"minimum_value": "0",
|
||||
"enabled": "support_enable",
|
||||
"limit_to_extruder": "support_infill_extruder_nr",
|
||||
"settable_per_mesh": true,
|
||||
"fabricate_enabled": true,
|
||||
"intermediate_enabled": true
|
||||
},
|
||||
"support_interface_enable":
|
||||
{
|
||||
"label": "Enable Support Interface",
|
||||
|
@ -4378,6 +4392,94 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"minimum_interface_area":
|
||||
{
|
||||
"label": "Minimum Support Interface Area",
|
||||
"description": "Minimum area size for support interface polygons. Polygons which have an area smaller than this value will not be generated.",
|
||||
"unit": "mm²",
|
||||
"type": "float",
|
||||
"default_value": 1.0,
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "minimum_support_area",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"enabled": "support_interface_enable and support_enable",
|
||||
"settable_per_mesh": true,
|
||||
"children":
|
||||
{
|
||||
"minimum_roof_area":
|
||||
{
|
||||
"label": "Minimum Support Roof Area",
|
||||
"description": "Minimum area size for the roofs of the support. Polygons which have an area smaller than this value will not be generated.",
|
||||
"unit": "mm²",
|
||||
"type": "float",
|
||||
"default_value": 1.0,
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'minimum_interface_area')",
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "minimum_support_area",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"enabled": "support_roof_enable and support_enable",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"minimum_bottom_area":
|
||||
{
|
||||
"label": "Minimum Support Floor Area",
|
||||
"description": "Minimum area size for the floors of the support. Polygons which have an area smaller than this value will not be generated.",
|
||||
"unit": "mm²",
|
||||
"type": "float",
|
||||
"default_value": 1.0,
|
||||
"value": "extruderValue(support_bottom_extruder_nr, 'minimum_interface_area')",
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "minimum_support_area",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"enabled": "support_bottom_enable and support_enable",
|
||||
"settable_per_mesh": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"support_interface_offset":
|
||||
{
|
||||
"label": "Support Interface Horizontal Expansion",
|
||||
"description": "Amount of offset applied to the support interface polygons.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0.0,
|
||||
"maximum_value": "extruderValue(support_extruder_nr, 'support_offset')",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"enabled": "support_interface_enable and (support_enable or support_tree_enable)",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
"children":
|
||||
{
|
||||
"support_roof_offset":
|
||||
{
|
||||
"label": "Support Roof Horizontal Expansion",
|
||||
"description": "Amount of offset applied to the roofs of the support.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0.0,
|
||||
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_offset')",
|
||||
"maximum_value": "extruderValue(support_extruder_nr, 'support_offset')",
|
||||
"limit_to_extruder": "support_roof_extruder_nr",
|
||||
"enabled": "support_roof_enable and (support_enable or support_tree_enable)",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"support_bottom_offset":
|
||||
{
|
||||
"label": "Support Floor Horizontal Expansion",
|
||||
"description": "Amount of offset applied to the floors of the support.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0.0,
|
||||
"value": "extruderValue(support_bottom_extruder_nr, 'support_interface_offset')",
|
||||
"maximum_value": "extruderValue(support_extruder_nr, 'support_offset')",
|
||||
"limit_to_extruder": "support_bottom_extruder_nr",
|
||||
"enabled": "support_bottom_enable and (support_enable or support_tree_enable)",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"support_fan_enable":
|
||||
{
|
||||
"label": "Fan Speed Override",
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Simon Cor",
|
||||
"manufacturer": "German RepRap",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker.png",
|
||||
"platform": "grr_neo_platform.stl",
|
||||
"machine_extruder_trains":
|
||||
{
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Claudio Sampaio (Patola)",
|
||||
"manufacturer": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "kossel_platform.stl",
|
||||
"platform_offset": [0, -0.25, 0],
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Chris Petersen",
|
||||
"manufacturer": "OpenBeam",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "kossel_pro_build_platform.stl",
|
||||
"platform_offset": [0, -0.25, 0],
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "makeR",
|
||||
"manufacturer": "makeR",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "makeR_pegasus_platform.stl",
|
||||
"platform_offset": [-200, -10, 200],
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "makeR",
|
||||
"manufacturer": "makeR",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "makeR_prusa_tairona_i3_platform.stl",
|
||||
"platform_offset": [-2, 0, 0],
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "tvlgiao",
|
||||
"manufacturer": "3DMaker",
|
||||
"file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj",
|
||||
"icon": "icon_ultimaker2.png",
|
||||
"platform": "makerstarter_platform.stl",
|
||||
"preferred_quality_type": "draft",
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Quillford",
|
||||
"manufacturer": "Prusajr",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "prusai3_platform.stl",
|
||||
"machine_extruder_trains":
|
||||
{
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Apsu, Nounours2099",
|
||||
"manufacturer": "Prusa Research",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "prusai3_platform.stl",
|
||||
"has_materials": true,
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "guigashm",
|
||||
"manufacturer": "Prusajr",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2.png",
|
||||
"platform": "prusai3_xl_platform.stl",
|
||||
"machine_extruder_trains":
|
||||
{
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "PouncingIguana, JJ",
|
||||
"manufacturer": "SeeMeCNC",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "artemis_platform.stl",
|
||||
"has_materials": true,
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "PouncingIguana, JJ",
|
||||
"manufacturer": "SeeMeCNC",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "rostock_platform.stl",
|
||||
"has_materials": true,
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "TheTobby",
|
||||
"manufacturer": "Tevo",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"has_materials": false,
|
||||
"has_machine_quality": true,
|
||||
"platform": "tevo_blackwidow.stl",
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"author": "TheAssassin",
|
||||
"manufacturer": "Tevo",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "prusai3_platform.stl",
|
||||
"machine_extruder_trains":
|
||||
{
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "nean",
|
||||
"manufacturer": "Tevo",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2.png",
|
||||
"has_materials": true,
|
||||
"machine_extruder_trains": {
|
||||
"0": "tevo_tornado_extruder_0"
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
"manufacturer": "uBuild-3D",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_uBuild-3D",
|
||||
"platform": "mr_bot_280_platform.stl",
|
||||
"has_materials": true,
|
||||
"preferred_quality_type": "draft",
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"manufacturer": "Ultimaker B.V.",
|
||||
"weight": 3,
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2.png",
|
||||
"platform": "ultimaker2_platform.obj",
|
||||
"platform_texture": "Ultimaker2backplate.png",
|
||||
"platform_offset": [9, 0, 0],
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"quality_definition": "ultimaker2",
|
||||
"weight": 3,
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2.png",
|
||||
"platform": "ultimaker2_platform.obj",
|
||||
"platform_texture": "Ultimaker2Extendedbackplate.png",
|
||||
"machine_extruder_trains":
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"quality_definition": "ultimaker2",
|
||||
"weight": 3,
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2.png",
|
||||
"platform": "ultimaker2go_platform.obj",
|
||||
"platform_texture": "Ultimaker2Gobackplate.png",
|
||||
"platform_offset": [0, 0, 0],
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"manufacturer": "Ultimaker B.V.",
|
||||
"weight": 4,
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker.png",
|
||||
"platform": "ultimaker_platform.stl",
|
||||
"has_materials": true,
|
||||
"has_machine_quality": true,
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
"manufacturer": "Ultimaker B.V.",
|
||||
"weight": 4,
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker.png",
|
||||
"platform": "ultimaker_platform.stl",
|
||||
"has_materials": true,
|
||||
"has_machine_quality": true,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"manufacturer": "Ultimaker B.V.",
|
||||
"weight": 4,
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker.png",
|
||||
"platform": "ultimaker2_platform.obj",
|
||||
"platform_texture": "UltimakerPlusbackplate.png",
|
||||
"quality_definition": "ultimaker_original",
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
"author": "Unimatech",
|
||||
"manufacturer": "Unimatech",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2.png",
|
||||
"machine_extruder_trains":
|
||||
{
|
||||
"0": "uniqbot_one_extruder_0"
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
"visible": true,
|
||||
"manufacturer": "Velleman",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "Vertex_build_panel.stl",
|
||||
"platform_offset": [0, -3, 0],
|
||||
"supports_usb_connection": true,
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
"visible": true,
|
||||
"manufacturer": "Velleman",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "icon_ultimaker2",
|
||||
"platform": "Vertex_build_panel.stl",
|
||||
"platform_offset": [0, -3, 0],
|
||||
"machine_extruder_trains": {
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Ricardo Snoek",
|
||||
"manufacturer": "Wanhao",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "wanhao-icon.png",
|
||||
"has_materials": true,
|
||||
"platform": "wanhao_225_145_platform.obj",
|
||||
"platform_texture": "Wanhaobackplate.png",
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Ricardo Snoek",
|
||||
"manufacturer": "Wanhao",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "wanhao-icon.png",
|
||||
"has_materials": true,
|
||||
"platform": "wanhao_200_200_platform.obj",
|
||||
"platform_texture": "Wanhaobackplate.png",
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Ricardo Snoek",
|
||||
"manufacturer": "Wanhao",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "wanhao-icon.png",
|
||||
"has_materials": true,
|
||||
"platform": "wanhao_200_200_platform.obj",
|
||||
"platform_texture": "Wanhaobackplate.png",
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Ricardo Snoek",
|
||||
"manufacturer": "Wanhao",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "wanhao-icon.png",
|
||||
"has_materials": true,
|
||||
"platform": "wanhao_300_200_platform.obj",
|
||||
"platform_texture": "Wanhaobackplate.png",
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Ricardo Snoek",
|
||||
"manufacturer": "Wanhao",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "wanhao-icon.png",
|
||||
"has_materials": true,
|
||||
"platform": "wanhao_300_200_platform.obj",
|
||||
"platform_texture": "Wanhaobackplate.png",
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Ricardo Snoek",
|
||||
"manufacturer": "Wanhao",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "wanhao-icon.png",
|
||||
"has_materials": true,
|
||||
"platform": "wanhao_200_200_platform.obj",
|
||||
"platform_texture": "Wanhaobackplate.png",
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Ricardo Snoek",
|
||||
"manufacturer": "Wanhao",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "wanhao-icon.png",
|
||||
"has_materials": true,
|
||||
"platform": "wanhao_110_110_platform.obj",
|
||||
"platform_texture": "Wanhaobackplate.png",
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
"author": "Ricardo Snoek",
|
||||
"manufacturer": "Wanhao",
|
||||
"file_formats": "text/x-gcode",
|
||||
"icon": "wanhao-icon.png",
|
||||
"has_materials": true,
|
||||
"platform": "wanhao_200_200_platform.obj",
|
||||
"platform_texture": "Wanhaobackplate.png",
|
||||
|
|
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load diff
Binary file not shown.
Binary file not shown.
|
@ -168,6 +168,7 @@ Item
|
|||
id: manageMaterialsAction
|
||||
text: catalog.i18nc("@action:inmenu", "Manage Materials...")
|
||||
iconName: "configure"
|
||||
shortcut: "Ctrl+K"
|
||||
}
|
||||
|
||||
Action
|
||||
|
@ -182,7 +183,7 @@ Item
|
|||
{
|
||||
id: resetProfileAction;
|
||||
enabled: Cura.MachineManager.hasUserSettings
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","&Discard current changes");
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile", "&Discard current changes");
|
||||
onTriggered:
|
||||
{
|
||||
forceActiveFocus();
|
||||
|
@ -194,20 +195,21 @@ Item
|
|||
{
|
||||
id: addProfileAction;
|
||||
enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","&Create profile from current settings/overrides...");
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile", "&Create profile from current settings/overrides...");
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: manageProfilesAction;
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile","Manage Profiles...");
|
||||
iconName: "configure";
|
||||
id: manageProfilesAction
|
||||
text: catalog.i18nc("@action:inmenu menubar:profile", "Manage Profiles...")
|
||||
iconName: "configure"
|
||||
shortcut: "Ctrl+J"
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: documentationAction;
|
||||
text: catalog.i18nc("@action:inmenu menubar:help","Show Online &Documentation");
|
||||
text: catalog.i18nc("@action:inmenu menubar:help", "Show Online &Documentation");
|
||||
iconName: "help-contents";
|
||||
shortcut: StandardKey.Help;
|
||||
onTriggered: CuraActions.openDocumentation();
|
||||
|
@ -215,7 +217,7 @@ Item
|
|||
|
||||
Action {
|
||||
id: reportBugAction;
|
||||
text: catalog.i18nc("@action:inmenu menubar:help","Report a &Bug");
|
||||
text: catalog.i18nc("@action:inmenu menubar:help", "Report a &Bug");
|
||||
iconName: "tools-report-bug";
|
||||
onTriggered: CuraActions.openBugReportPage();
|
||||
}
|
||||
|
@ -223,7 +225,7 @@ Item
|
|||
Action
|
||||
{
|
||||
id: aboutAction;
|
||||
text: catalog.i18nc("@action:inmenu menubar:help","About...");
|
||||
text: catalog.i18nc("@action:inmenu menubar:help", "About...");
|
||||
iconName: "help-about";
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ UM.Dialog
|
|||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
|
||||
flags: {
|
||||
flags:
|
||||
{
|
||||
var window_flags = Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint;
|
||||
if (Cura.MachineManager.activeDefinitionId !== "") //Disallow closing the window if we have no active printer yet. You MUST add a printer.
|
||||
{
|
||||
|
@ -45,10 +46,52 @@ UM.Dialog
|
|||
}
|
||||
|
||||
signal machineAdded(string id)
|
||||
|
||||
function getMachineName()
|
||||
{
|
||||
var name = machineList.model.getItem(machineList.currentIndex) != undefined ? machineList.model.getItem(machineList.currentIndex).name : ""
|
||||
return name
|
||||
if (machineList.model.getItem(machineList.currentIndex) != undefined)
|
||||
{
|
||||
return machineList.model.getItem(machineList.currentIndex).name;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function getMachineMetaDataEntry(key)
|
||||
{
|
||||
if (machineList.model.getItem(machineList.currentIndex) != undefined)
|
||||
{
|
||||
return machineList.model.getItem(machineList.currentIndex).metadata[key];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: titleLabel
|
||||
|
||||
anchors
|
||||
{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
topMargin: UM.Theme.getSize("default_margin").height
|
||||
}
|
||||
text: catalog.i18nc("@title:tab", "Add a printer to Cura")
|
||||
|
||||
font.pointSize: 18
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: captionLabel
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
top: titleLabel.bottom
|
||||
topMargin: UM.Theme.getSize("default_margin").height
|
||||
}
|
||||
text: catalog.i18nc("@title:tab", "Select the printer you want to use from the list below.\n\nIf your printer is not in the list, use the \"Custom FFF Printer\" from the \"Custom\" category and adjust the settings to match your printer in the next dialog.")
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
ScrollView
|
||||
|
@ -57,13 +100,22 @@ UM.Dialog
|
|||
|
||||
anchors
|
||||
{
|
||||
left: parent.left;
|
||||
top: parent.top;
|
||||
right: parent.right;
|
||||
bottom: machineNameRow.top;
|
||||
top: captionLabel.visible ? captionLabel.bottom : parent.top;
|
||||
topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0;
|
||||
bottom: addPrinterButton.top;
|
||||
bottomMargin: UM.Theme.getSize("default_margin").height
|
||||
}
|
||||
|
||||
width: Math.round(parent.width * 0.45)
|
||||
|
||||
frameVisible: true;
|
||||
Rectangle
|
||||
{
|
||||
parent: viewport
|
||||
anchors.fill: parent
|
||||
color: palette.light
|
||||
}
|
||||
|
||||
ListView
|
||||
{
|
||||
id: machineList
|
||||
|
@ -115,11 +167,14 @@ UM.Dialog
|
|||
onClicked:
|
||||
{
|
||||
base.activeCategory = section;
|
||||
if (machineList.model.getItem(machineList.currentIndex).section != section) {
|
||||
if (machineList.model.getItem(machineList.currentIndex).section != section)
|
||||
{
|
||||
// Find the first machine from this section
|
||||
for(var i = 0; i < machineList.model.rowCount(); i++) {
|
||||
for(var i = 0; i < machineList.model.rowCount(); i++)
|
||||
{
|
||||
var item = machineList.model.getItem(i);
|
||||
if (item.section == section) {
|
||||
if (item.section == section)
|
||||
{
|
||||
machineList.currentIndex = i;
|
||||
break;
|
||||
}
|
||||
|
@ -184,32 +239,76 @@ UM.Dialog
|
|||
}
|
||||
}
|
||||
|
||||
Row
|
||||
Column
|
||||
{
|
||||
id: machineNameRow
|
||||
anchors.bottom:parent.bottom
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
|
||||
Label
|
||||
anchors
|
||||
{
|
||||
text: catalog.i18nc("@label", "Printer Name:")
|
||||
anchors.verticalCenter: machineName.verticalCenter
|
||||
top: machinesHolder.top
|
||||
left: machinesHolder.right
|
||||
right: parent.right
|
||||
leftMargin: UM.Theme.getSize("default_margin").width
|
||||
}
|
||||
|
||||
TextField
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
Label
|
||||
{
|
||||
id: machineName
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: getMachineName()
|
||||
implicitWidth: UM.Theme.getSize("standard_list_input").width
|
||||
maximumLength: 40
|
||||
//validator: Cura.MachineNameValidator { } //TODO: Gives a segfault in PyQt5.6. For now, we must use a signal on text changed.
|
||||
validator: RegExpValidator
|
||||
font.pointSize: 16
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Grid
|
||||
{
|
||||
width: parent.width
|
||||
columns: 2
|
||||
rowSpacing: UM.Theme.getSize("default_lining").height
|
||||
columnSpacing: UM.Theme.getSize("default_margin").width
|
||||
verticalItemAlignment: Grid.AlignVCenter
|
||||
|
||||
Label
|
||||
{
|
||||
regExp: {
|
||||
machineName.machine_name_validator.machineNameRegex
|
||||
}
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "Manufacturer")
|
||||
}
|
||||
Label
|
||||
{
|
||||
width: Math.floor(parent.width * 0.65)
|
||||
wrapMode: Text.WordWrap
|
||||
text: getMachineMetaDataEntry("manufacturer")
|
||||
}
|
||||
Label
|
||||
{
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "Author")
|
||||
}
|
||||
Label
|
||||
{
|
||||
width: Math.floor(parent.width * 0.75)
|
||||
wrapMode: Text.WordWrap
|
||||
text: getMachineMetaDataEntry("author")
|
||||
}
|
||||
Label
|
||||
{
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "Printer Name")
|
||||
}
|
||||
TextField
|
||||
{
|
||||
id: machineName
|
||||
text: getMachineName()
|
||||
width: Math.floor(parent.width * 0.75)
|
||||
implicitWidth: UM.Theme.getSize("standard_list_input").width
|
||||
maximumLength: 40
|
||||
//validator: Cura.MachineNameValidator { } //TODO: Gives a segfault in PyQt5.6. For now, we must use a signal on text changed.
|
||||
validator: RegExpValidator
|
||||
{
|
||||
regExp: {
|
||||
machineName.machine_name_validator.machineNameRegex
|
||||
}
|
||||
}
|
||||
property var machine_name_validator: Cura.MachineNameValidator { }
|
||||
}
|
||||
property var machine_name_validator: Cura.MachineNameValidator { }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ SettingItem
|
|||
maximumLength: (definition.type == "str" || definition.type == "[int]") ? -1 : 10;
|
||||
clip: true; //Hide any text that exceeds the width of the text box.
|
||||
|
||||
validator: RegExpValidator { regExp: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,9}\s*,)*(\s*-?[0-9]{0,9})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,10}$/ : (definition.type == "float") ? /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry
|
||||
validator: RegExpValidator { regExp: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,9}\s*,)*(\s*-?[0-9]{0,9})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,10}$/ : (definition.type == "float") ? /^-?[0-9]{0,9}[.,]?[0-9]{0,3}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry
|
||||
|
||||
Binding
|
||||
{
|
||||
|
|
|
@ -489,7 +489,7 @@ Column
|
|||
|
||||
Label
|
||||
{
|
||||
id: bulidplateLabel
|
||||
id: buildplateLabel
|
||||
text: catalog.i18nc("@label", "Build plate");
|
||||
width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
|
||||
height: parent.height
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = fast
|
||||
weight = -1
|
||||
material = fabtotum_abs
|
||||
material = generic_abs
|
||||
|
||||
[values]
|
||||
adhesion_type = raft
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = high
|
||||
weight = 1
|
||||
material = fabtotum_abs
|
||||
material = generic_abs
|
||||
|
||||
[values]
|
||||
adhesion_type = raft
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = normal
|
||||
weight = 0
|
||||
material = fabtotum_abs
|
||||
material = generic_abs
|
||||
|
||||
[values]
|
||||
adhesion_type = raft
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = fast
|
||||
weight = -1
|
||||
material = fabtotum_nylon
|
||||
material = generic_nylon
|
||||
|
||||
[values]
|
||||
adhesion_type = raft
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = high
|
||||
weight = 1
|
||||
material = fabtotum_nylon
|
||||
material = generic_nylon
|
||||
|
||||
[values]
|
||||
adhesion_type = raft
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = normal
|
||||
weight = 0
|
||||
material = fabtotum_nylon
|
||||
material = generic_nylon
|
||||
|
||||
[values]
|
||||
adhesion_type = raft
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = fast
|
||||
weight = -1
|
||||
material = fabtotum_pla
|
||||
material = generic_pla
|
||||
|
||||
[values]
|
||||
adhesion_type = skirt
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = high
|
||||
weight = 1
|
||||
material = fabtotum_pla
|
||||
material = generic_pla
|
||||
|
||||
[values]
|
||||
adhesion_type = skirt
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = normal
|
||||
weight = 0
|
||||
material = fabtotum_pla
|
||||
material = generic_pla
|
||||
|
||||
[values]
|
||||
adhesion_type = skirt
|
||||
|
|
|
@ -6,7 +6,7 @@ name = Fast Quality
|
|||
[metadata]
|
||||
type = quality
|
||||
setting_version = 5
|
||||
material = fabtotum_tpu
|
||||
material = generic_tpu
|
||||
quality_type = fast
|
||||
weight = -1
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ name = High Quality
|
|||
[metadata]
|
||||
type = quality
|
||||
setting_version = 5
|
||||
material = fabtotum_tpu
|
||||
material = generic_tpu
|
||||
quality_type = high
|
||||
weight = 1
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ name = Normal Quality
|
|||
[metadata]
|
||||
type = quality
|
||||
setting_version = 5
|
||||
material = fabtotum_TPU
|
||||
material = generic_tpu
|
||||
quality_type = normal
|
||||
weight = 0
|
||||
|
||||
|
|
|
@ -31,11 +31,11 @@ line_width = =machine_nozzle_size * 0.95
|
|||
machine_min_cool_heat_time_window = 15
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 106
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 15
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0
|
||||
prime_tower_wipe_enabled = True
|
||||
|
|
|
@ -31,11 +31,11 @@ line_width = =machine_nozzle_size * 0.95
|
|||
machine_min_cool_heat_time_window = 15
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 106
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 15
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0
|
||||
prime_tower_wipe_enabled = True
|
||||
|
|
|
@ -30,10 +30,10 @@ line_width = =machine_nozzle_size * 0.95
|
|||
machine_min_cool_heat_time_window = 15
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 106
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_print_temperature_layer_0 = =default_material_print_temperature
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 17
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0
|
||||
prime_tower_wipe_enabled = True
|
||||
|
|
|
@ -25,11 +25,11 @@ jerk_support = =math.ceil(jerk_print * 25 / 25)
|
|||
jerk_wall_0 = =math.ceil(jerk_wall * 15 / 25)
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 105
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature = =default_material_print_temperature - 2
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 4
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 19
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0.2
|
||||
prime_tower_enable = True
|
||||
|
|
|
@ -26,11 +26,11 @@ jerk_wall_0 = =math.ceil(jerk_wall * 15 / 25)
|
|||
layer_height = 0.4
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 105
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =material_print_temperature
|
||||
material_print_temperature_layer_0 = =material_print_temperature +15
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0.2
|
||||
prime_tower_enable = True
|
||||
|
|
|
@ -26,10 +26,10 @@ jerk_wall_0 = =math.ceil(jerk_wall * 15 / 25)
|
|||
layer_height = 0.3
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 105
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 2
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 17
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0.2
|
||||
prime_tower_enable = True
|
||||
|
|
|
@ -30,11 +30,11 @@ line_width = =machine_nozzle_size * 0.95
|
|||
machine_min_cool_heat_time_window = 15
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 106
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 15
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0
|
||||
prime_tower_wipe_enabled = True
|
||||
|
|
|
@ -30,11 +30,11 @@ line_width = =machine_nozzle_size * 0.95
|
|||
machine_min_cool_heat_time_window = 15
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 106
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 15
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0
|
||||
prime_tower_wipe_enabled = True
|
||||
|
|
|
@ -30,10 +30,10 @@ line_width = =machine_nozzle_size * 0.95
|
|||
machine_min_cool_heat_time_window = 15
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 106
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_print_temperature_layer_0 = =default_material_print_temperature
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 17
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0
|
||||
prime_tower_wipe_enabled = True
|
||||
|
|
|
@ -23,11 +23,11 @@ jerk_support = =math.ceil(jerk_print * 25 / 25)
|
|||
jerk_wall_0 = =math.ceil(jerk_wall * 15 / 25)
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 105
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature = =default_material_print_temperature - 2
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 4
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 19
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0.2
|
||||
prime_tower_enable = True
|
||||
|
|
|
@ -24,11 +24,11 @@ jerk_support = =math.ceil(jerk_print * 25 / 25)
|
|||
jerk_wall_0 = =math.ceil(jerk_wall * 15 / 25)
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 105
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =material_print_temperature
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 15
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0.2
|
||||
prime_tower_enable = True
|
||||
|
|
|
@ -24,10 +24,10 @@ jerk_support = =math.ceil(jerk_print * 25 / 25)
|
|||
jerk_wall_0 = =math.ceil(jerk_wall * 15 / 25)
|
||||
machine_nozzle_cool_down_speed = 0.5
|
||||
machine_nozzle_heat_up_speed = 2.5
|
||||
material_final_print_temperature = =material_print_temperature - 21
|
||||
material_final_print_temperature = =material_print_temperature
|
||||
material_flow = 105
|
||||
material_initial_print_temperature = =material_print_temperature - 16
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 2
|
||||
material_initial_print_temperature = =material_print_temperature
|
||||
material_print_temperature_layer_0 = =material_print_temperature + 17
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0.2
|
||||
prime_tower_enable = True
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = fast
|
||||
weight = 1
|
||||
material = zyyx_pro_flex
|
||||
material = generic_tpu
|
||||
|
||||
[values]
|
||||
layer_height = 0.3
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = fine
|
||||
weight = 3
|
||||
material = zyyx_pro_flex
|
||||
material = generic_tpu
|
||||
|
||||
[values]
|
||||
layer_height = 0.12
|
||||
|
|
|
@ -8,7 +8,7 @@ setting_version = 5
|
|||
type = quality
|
||||
quality_type = normal
|
||||
weight = 2
|
||||
material = zyyx_pro_flex
|
||||
material = generic_tpu
|
||||
|
||||
[values]
|
||||
layer_height = 0.2
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue