Merge branch 'master' into CURA-6856_signed_plugins_and_packages

This commit is contained in:
Remco Burema 2019-11-01 16:45:42 +01:00
commit 3dabd6023b
No known key found for this signature in database
GPG Key ID: 215C49431D43F98C
148 changed files with 1704 additions and 696 deletions

View File

@ -11,23 +11,24 @@ Information about how to find the log file can be found at https://github.com/Ul
Thank you for using Cura! Thank you for using Cura!
--> -->
**Application Version** **Application version**
<!-- The version of the application this issue occurs with --> (The version of the application this issue occurs with.)
**Platform** **Platform**
<!-- Information about the operating system the issue occurs on --> (Information about the operating system the issue occurs on. Include at least the operating system. In the case of visual glitches/issues, also include information about your graphics drivers and GPU.)
**Printer** **Printer**
<!-- Which printer was selected in Cura. Please attach project file as .curaproject.3mf.zip --> (Which printer was selected in Cura? If possible, please attach project file as .curaproject.3mf.zip.)
**Steps to Reproduce** **Reproduction steps**
<!-- Add the steps needed that lead up to the issue --> 1. Something you did.
2. Something you did next.
**Actual Results** **Actual results**
<!-- What happens after the above steps have been followed --> (What happens after the above steps have been followed.)
**Expected results** **Expected results**
<!-- What should happen after the above steps have been followed --> (What should happen after the above steps have been followed.)
**Additional Information** **Additional information**
<!-- Extra information relevant to the issue, like screenshots --> (Extra information relevant to the issue, like screenshots. Don't forget to attach the log files with this issue report.)

View File

@ -22,22 +22,23 @@ Thank you for using Cura!
--> -->
**Application version** **Application version**
<!-- The version of the application this issue occurs with --> (The version of the application this issue occurs with.)
**Platform** **Platform**
<!-- Information about the operating system the issue occurs on. Include at least the operating system. In the case of visual glitches/issues, also include information about your graphics drivers and GPU. --> (Information about the operating system the issue occurs on. Include at least the operating system. In the case of visual glitches/issues, also include information about your graphics drivers and GPU.)
**Printer** **Printer**
<!-- Which printer was selected in Cura? If possible, please attach project file as .curaproject.3mf.zip --> (Which printer was selected in Cura? If possible, please attach project file as .curaproject.3mf.zip.)
**Reproduction steps** **Reproduction steps**
<!-- How did you encounter the bug? --> 1. Something you did.
2. Something you did next.
**Actual results** **Actual results**
<!-- What happens after the above steps have been followed --> (What happens after the above steps have been followed.)
**Expected results** **Expected results**
<!-- What should happen after the above steps have been followed --> (What should happen after the above steps have been followed.)
**Additional information** **Additional information**
<!-- Extra information relevant to the issue, like screenshots. Don't forget to attach the log files with this issue report. --> (Extra information relevant to the issue, like screenshots. Don't forget to attach the log files with this issue report.)

View File

@ -8,15 +8,16 @@ assignees: ''
--- ---
**Is your feature request related to a problem? Please describe.** **Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] --> (A clear and concise description of what the problem is. Ex. I'm always frustrated when [...])
**Describe the solution you'd like** **Describe the solution you'd like**
<!--A clear and concise description of what you want to happen. If possible, describe why you think this is a good solution.--> (A clear and concise description of what you want to happen. If possible, describe why you think this is a good solution.)
**Describe alternatives you've considered** **Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. Again, if possible, think about why these alternatives are not working out. --> (A clear and concise description of any alternative solutions or features you've considered. Again, if possible, think about why these alternatives are not working out.)
**Affected users and/or printers** **Affected users and/or printers**
<!-- Who do you think will benefit from this? Is everyone going to benefit from these changes? Only a few people? --> (Who do you think will benefit from this? Is everyone going to benefit from these changes? Or specific kinds of users?)
**Additional context** **Additional context**
<!-- Add any other context or screenshots about the feature request here. --> (Add any other context or screenshots about the feature request here.)

View File

@ -49,7 +49,7 @@ endif()
if(NOT ${URANIUM_DIR} STREQUAL "") if(NOT ${URANIUM_DIR} STREQUAL "")
set(CMAKE_MODULE_PATH "${URANIUM_DIR}/cmake") set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${URANIUM_DIR}/cmake")
endif() endif()
if(NOT ${URANIUM_SCRIPTS_DIR} STREQUAL "") if(NOT ${URANIUM_SCRIPTS_DIR} STREQUAL "")
list(APPEND CMAKE_MODULE_PATH ${URANIUM_DIR}/cmake) list(APPEND CMAKE_MODULE_PATH ${URANIUM_DIR}/cmake)
@ -63,8 +63,8 @@ endif()
install(DIRECTORY resources install(DIRECTORY resources
DESTINATION ${CMAKE_INSTALL_DATADIR}/cura) DESTINATION ${CMAKE_INSTALL_DATADIR}/cura)
install(DIRECTORY plugins
DESTINATION lib${LIB_SUFFIX}/cura) include(CuraPluginInstall)
if(NOT APPLE AND NOT WIN32) if(NOT APPLE AND NOT WIN32)
install(FILES cura_app.py install(FILES cura_app.py

View File

@ -0,0 +1,99 @@
# Copyright (c) 2019 Ultimaker B.V.
# CuraPluginInstall.cmake is released under the terms of the LGPLv3 or higher.
#
# This module detects all plugins that need to be installed and adds them using the CMake install() command.
# It detects all plugin folder in the path "plugins/*" where there's a "plugin.json" in it.
#
# Plugins can be configured to NOT BE INSTALLED via the variable "CURA_NO_INSTALL_PLUGINS" as a list of string in the
# form of "a;b;c" or "a,b,c". By default all plugins will be installed.
#
# FIXME: Remove the code for CMake <3.12 once we have switched over completely.
# FindPython3 is a new module since CMake 3.12. It deprecates FindPythonInterp and FindPythonLibs. The FindPython3
# module is copied from the CMake repository here so in CMake <3.12 we can still use it.
if(${CMAKE_VERSION} VERSION_LESS 3.12)
# Use FindPythonInterp and FindPythonLibs for CMake <3.12
find_package(PythonInterp 3 REQUIRED)
set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
else()
# Use FindPython3 for CMake >=3.12
find_package(Python3 REQUIRED COMPONENTS Interpreter)
endif()
# Options or configuration variables
set(CURA_NO_INSTALL_PLUGINS "" CACHE STRING "A list of plugins that should not be installed, separated with ';' or ','.")
file(GLOB_RECURSE _plugin_json_list ${CMAKE_SOURCE_DIR}/plugins/*/plugin.json)
list(LENGTH _plugin_json_list _plugin_json_list_len)
# Sort the lists alphabetically so we can handle cases like this:
# - plugins/my_plugin/plugin.json
# - plugins/my_plugin/my_module/plugin.json
# In this case, only "plugins/my_plugin" should be added via install().
set(_no_install_plugin_list ${CURA_NO_INSTALL_PLUGINS})
# Sanitize the string so the comparison will be case-insensitive.
string(STRIP "${_no_install_plugin_list}" _no_install_plugin_list)
string(TOLOWER "${_no_install_plugin_list}" _no_install_plugin_list)
# WORKAROUND counterpart of what's in cura-build.
string(REPLACE "," ";" _no_install_plugin_list "${_no_install_plugin_list}")
list(LENGTH _no_install_plugin_list _no_install_plugin_list_len)
if(_no_install_plugin_list_len GREATER 0)
list(SORT _no_install_plugin_list)
endif()
if(_plugin_json_list_len GREATER 0)
list(SORT _plugin_json_list)
endif()
# Check all plugin directories and add them via install() if needed.
set(_install_plugin_list "")
foreach(_plugin_json_path ${_plugin_json_list})
get_filename_component(_plugin_dir ${_plugin_json_path} DIRECTORY)
file(RELATIVE_PATH _rel_plugin_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_plugin_dir})
get_filename_component(_plugin_dir_name ${_plugin_dir} NAME)
# Make plugin name comparison case-insensitive
string(TOLOWER "${_plugin_dir_name}" _plugin_dir_name_lowercase)
# Check if this plugin needs to be skipped for installation
set(_add_plugin ON) # Indicates if this plugin should be added to the build or not.
set(_is_no_install_plugin OFF) # If this plugin will not be added, this indicates if it's because the plugin is
# specified in the NO_INSTALL_PLUGINS list.
if(_no_install_plugin_list)
if("${_plugin_dir_name_lowercase}" IN_LIST _no_install_plugin_list)
set(_add_plugin OFF)
set(_is_no_install_plugin ON)
endif()
endif()
# Make sure this is not a subdirectory in a plugin that's already in the install list
if(_add_plugin)
foreach(_known_install_plugin_dir ${_install_plugin_list})
if(_plugin_dir MATCHES "${_known_install_plugin_dir}.+")
set(_add_plugin OFF)
break()
endif()
endforeach()
endif()
if(_add_plugin)
message(STATUS "[+] PLUGIN TO INSTALL: ${_rel_plugin_dir}")
get_filename_component(_rel_plugin_parent_dir ${_rel_plugin_dir} DIRECTORY)
install(DIRECTORY ${_rel_plugin_dir}
DESTINATION lib${LIB_SUFFIX}/cura/${_rel_plugin_parent_dir}
PATTERN "__pycache__" EXCLUDE
PATTERN "*.qmlc" EXCLUDE
)
list(APPEND _install_plugin_list ${_plugin_dir})
elseif(_is_no_install_plugin)
message(STATUS "[-] PLUGIN TO REMOVE : ${_rel_plugin_dir}")
execute_process(COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mod_bundled_packages_json.py
-d ${CMAKE_CURRENT_SOURCE_DIR}/resources/bundled_packages
${_plugin_dir_name}
RESULT_VARIABLE _mod_json_result)
endif()
endforeach()

View File

@ -0,0 +1,69 @@
#!/usr/bin/env python3
#
# This script removes the given package entries in the bundled_packages JSON files. This is used by the PluginInstall
# CMake module.
#
import argparse
import collections
import json
import os
import sys
## Finds all JSON files in the given directory recursively and returns a list of those files in absolute paths.
#
# \param work_dir The directory to look for JSON files recursively.
# \return A list of JSON files in absolute paths that are found in the given directory.
def find_json_files(work_dir: str) -> list:
json_file_list = []
for root, dir_names, file_names in os.walk(work_dir):
for file_name in file_names:
abs_path = os.path.abspath(os.path.join(root, file_name))
json_file_list.append(abs_path)
return json_file_list
## Removes the given entries from the given JSON file. The file will modified in-place.
#
# \param file_path The JSON file to modify.
# \param entries A list of strings as entries to remove.
# \return None
def remove_entries_from_json_file(file_path: str, entries: list) -> None:
try:
with open(file_path, "r", encoding = "utf-8") as f:
package_dict = json.load(f, object_hook = collections.OrderedDict)
except Exception as e:
msg = "Failed to load '{file_path}' as a JSON file. This file will be ignored Exception: {e}"\
.format(file_path = file_path, e = e)
sys.stderr.write(msg + os.linesep)
return
for entry in entries:
if entry in package_dict:
del package_dict[entry]
print("[INFO] Remove entry [{entry}] from [{file_path}]".format(file_path = file_path, entry = entry))
try:
with open(file_path, "w", encoding = "utf-8", newline = "\n") as f:
json.dump(package_dict, f, indent = 4)
except Exception as e:
msg = "Failed to write '{file_path}' as a JSON file. Exception: {e}".format(file_path = file_path, e = e)
raise IOError(msg)
def main() -> None:
parser = argparse.ArgumentParser("mod_bundled_packages_json")
parser.add_argument("-d", "--dir", dest = "work_dir",
help = "The directory to look for bundled packages JSON files, recursively.")
parser.add_argument("entries", metavar = "ENTRIES", type = str, nargs = "+")
args = parser.parse_args()
json_file_list = find_json_files(args.work_dir)
for json_file_path in json_file_list:
remove_entries_from_json_file(json_file_path, args.entries)
if __name__ == "__main__":
main()

View File

@ -224,7 +224,7 @@ class CuraApplication(QtApplication):
self._quality_management_model = None self._quality_management_model = None
self._discovered_printer_model = DiscoveredPrintersModel(self, parent = self) self._discovered_printer_model = DiscoveredPrintersModel(self, parent = self)
self._first_start_machine_actions_model = FirstStartMachineActionsModel(self, parent = self) self._first_start_machine_actions_model = None
self._welcome_pages_model = WelcomePagesModel(self, parent = self) self._welcome_pages_model = WelcomePagesModel(self, parent = self)
self._add_printer_pages_model = AddPrinterPagesModel(self, parent = self) self._add_printer_pages_model = AddPrinterPagesModel(self, parent = self)
self._whats_new_pages_model = WhatsNewPagesModel(self, parent = self) self._whats_new_pages_model = WhatsNewPagesModel(self, parent = self)
@ -517,7 +517,8 @@ class CuraApplication(QtApplication):
with self._container_registry.lockFile(): with self._container_registry.lockFile():
self._container_registry.loadAllMetadata() self._container_registry.loadAllMetadata()
# set the setting version for Preferences self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up preferences..."))
# Set the setting version for Preferences
preferences = self.getPreferences() preferences = self.getPreferences()
preferences.addPreference("metadata/setting_version", 0) preferences.addPreference("metadata/setting_version", 0)
preferences.setValue("metadata/setting_version", self.SettingVersion) #Don't make it equal to the default so that the setting version always gets written to the file. preferences.setValue("metadata/setting_version", self.SettingVersion) #Don't make it equal to the default so that the setting version always gets written to the file.
@ -879,6 +880,10 @@ class CuraApplication(QtApplication):
@pyqtSlot(result = QObject) @pyqtSlot(result = QObject)
def getFirstStartMachineActionsModel(self, *args) -> "FirstStartMachineActionsModel": def getFirstStartMachineActionsModel(self, *args) -> "FirstStartMachineActionsModel":
if self._first_start_machine_actions_model is None:
self._first_start_machine_actions_model = FirstStartMachineActionsModel(self, parent = self)
if self.started:
self._first_start_machine_actions_model.initialize()
return self._first_start_machine_actions_model return self._first_start_machine_actions_model
@pyqtSlot(result = QObject) @pyqtSlot(result = QObject)

View File

@ -33,11 +33,11 @@ class FirstStartMachineActionsModel(ListModel):
self._current_action_index = 0 self._current_action_index = 0
self._application = application self._application = application
self._application.initializationFinished.connect(self._initialize) self._application.initializationFinished.connect(self.initialize)
self._previous_global_stack = None self._previous_global_stack = None
def _initialize(self) -> None: def initialize(self) -> None:
self._application.getMachineManager().globalContainerChanged.connect(self._update) self._application.getMachineManager().globalContainerChanged.connect(self._update)
self._update() self._update()

View File

@ -1,7 +1,7 @@
#Copyright (c) 2019 Ultimaker B.V. #Copyright (c) 2019 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 PyQt5.QtCore import Qt from PyQt5.QtCore import Qt, QTimer
import collections import collections
from typing import TYPE_CHECKING, Optional, Dict from typing import TYPE_CHECKING, Optional, Dict
@ -35,15 +35,19 @@ class IntentCategoryModel(ListModel):
_translations["default"] = { _translations["default"] = {
"name": catalog.i18nc("@label", "Default") "name": catalog.i18nc("@label", "Default")
} }
_translations["visual"] = {
"name": catalog.i18nc("@label", "Visual"),
"description": catalog.i18nc("@text", "Optimized for appearance")
}
_translations["engineering"] = { _translations["engineering"] = {
"name": catalog.i18nc("@label", "Engineering"), "name": catalog.i18nc("@label", "Engineering"),
"description": catalog.i18nc("@text", "Suitable for engineering work") "description": catalog.i18nc("@text", "Optimized for higher accuracy")
}
_translations["quick"] = {
"name": catalog.i18nc("@label", "Draft"),
"description": catalog.i18nc("@text", "Optimized for fast results")
}
}
_translations["smooth"] = {
"name": catalog.i18nc("@label", "Smooth"),
"description": catalog.i18nc("@text", "Optimized for a smooth surfaces")
}
## Creates a new model for a certain intent category. ## Creates a new model for a certain intent category.
# \param The category to list the intent profiles for. # \param The category to list the intent profiles for.
@ -69,6 +73,11 @@ class IntentCategoryModel(ListModel):
extruder_manager = application.getExtruderManager() extruder_manager = application.getExtruderManager()
extruder_manager.extrudersChanged.connect(self.update) extruder_manager.extrudersChanged.connect(self.update)
self._update_timer = QTimer()
self._update_timer.setInterval(500)
self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._update)
self.update() self.update()
## Updates the list of intents if an intent profile was added or removed. ## Updates the list of intents if an intent profile was added or removed.
@ -76,8 +85,11 @@ class IntentCategoryModel(ListModel):
if container.getMetaDataEntry("type") == "intent": if container.getMetaDataEntry("type") == "intent":
self.update() self.update()
def update(self):
self._update_timer.start()
## Updates the list of intents. ## Updates the list of intents.
def update(self) -> None: def _update(self) -> None:
available_categories = IntentManager.getInstance().currentAvailableIntentCategories() available_categories = IntentManager.getInstance().currentAvailableIntentCategories()
result = [] result = []
for category in available_categories: for category in available_categories:

View File

@ -83,7 +83,7 @@ class VariantNode(ContainerNode):
# if there is no match. # if there is no match.
def preferredMaterial(self, approximate_diameter: int) -> MaterialNode: def preferredMaterial(self, approximate_diameter: int) -> MaterialNode:
for base_material, material_node in self.materials.items(): for base_material, material_node in self.materials.items():
if self.machine.preferred_material in base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")): if self.machine.preferred_material == base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
return material_node return material_node
# First fallback: Choose any material with matching diameter. # First fallback: Choose any material with matching diameter.
for material_node in self.materials.values(): for material_node in self.materials.values():

View File

@ -20,7 +20,7 @@ class FirmwareUpdater(QObject):
self._output_device = output_device self._output_device = output_device
self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True) self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True, name = "FirmwareUpdateThread")
self._firmware_file = "" self._firmware_file = ""
self._firmware_progress = 0 self._firmware_progress = 0
@ -43,7 +43,7 @@ class FirmwareUpdater(QObject):
## Cleanup after a succesful update ## Cleanup after a succesful update
def _cleanupAfterUpdate(self) -> None: def _cleanupAfterUpdate(self) -> None:
# Clean up for next attempt. # Clean up for next attempt.
self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True) self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True, name = "FirmwareUpdateThread")
self._firmware_file = "" self._firmware_file = ""
self._onFirmwareProgress(100) self._onFirmwareProgress(100)
self._setFirmwareUpdateState(FirmwareUpdateState.completed) self._setFirmwareUpdateState(FirmwareUpdateState.completed)

View File

@ -35,6 +35,7 @@ class PrinterOutputModel(QObject):
self._target_bed_temperature = 0 # type: float self._target_bed_temperature = 0 # type: float
self._name = "" self._name = ""
self._key = "" # Unique identifier self._key = "" # Unique identifier
self._unique_name = "" # Unique name (used in Connect)
self._controller = output_controller self._controller = output_controller
self._controller.canUpdateFirmwareChanged.connect(self._onControllerCanUpdateFirmwareChanged) self._controller.canUpdateFirmwareChanged.connect(self._onControllerCanUpdateFirmwareChanged)
self._extruders = [ExtruderOutputModel(printer = self, position = i) for i in range(number_of_extruders)] self._extruders = [ExtruderOutputModel(printer = self, position = i) for i in range(number_of_extruders)]
@ -190,6 +191,15 @@ class PrinterOutputModel(QObject):
self._name = name self._name = name
self.nameChanged.emit() self.nameChanged.emit()
@pyqtProperty(str, notify = nameChanged)
def uniqueName(self) -> str:
return self._unique_name
def updateUniqueName(self, unique_name: str) -> None:
if self._unique_name != unique_name:
self._unique_name = unique_name
self.nameChanged.emit()
## Update the bed temperature. This only changes it locally. ## Update the bed temperature. This only changes it locally.
def updateBedTemperature(self, temperature: float) -> None: def updateBedTemperature(self, temperature: float) -> None:
if self._bed_temperature != temperature: if self._bed_temperature != temperature:

View File

@ -220,6 +220,9 @@ class PrinterOutputDevice(QObject, OutputDevice):
if printer.printerConfiguration is not None and printer.printerConfiguration.hasAnyMaterialLoaded(): if printer.printerConfiguration is not None and printer.printerConfiguration.hasAnyMaterialLoaded():
all_configurations.add(printer.printerConfiguration) all_configurations.add(printer.printerConfiguration)
all_configurations.update(printer.availableConfigurations) all_configurations.update(printer.availableConfigurations)
if None in all_configurations: # Shouldn't happen, but it does. I don't see how it could ever happen. Skip adding that configuration. List could end up empty!
Logger.log("e", "Found a broken configuration in the synced list!")
all_configurations.remove(None)
new_configurations = sorted(all_configurations, key = lambda config: config.printerType or "") new_configurations = sorted(all_configurations, key = lambda config: config.printerType or "")
if new_configurations != self._unique_configurations: if new_configurations != self._unique_configurations:
self._unique_configurations = new_configurations self._unique_configurations = new_configurations

View File

@ -872,7 +872,10 @@ class MachineManager(QObject):
def numberExtrudersEnabled(self) -> int: def numberExtrudersEnabled(self) -> int:
if self._global_container_stack is None: if self._global_container_stack is None:
return 1 return 1
return self._global_container_stack.definitionChanges.getProperty("extruders_enabled_count", "value") extruders_enabled_count = self._global_container_stack.definitionChanges.getProperty("extruders_enabled_count", "value")
if extruders_enabled_count is None:
extruders_enabled_count = len(self._global_container_stack.extruderList)
return extruders_enabled_count
@pyqtProperty(str, notify = extruderChanged) @pyqtProperty(str, notify = extruderChanged)
def defaultExtruderPosition(self) -> str: def defaultExtruderPosition(self) -> str:

View File

@ -28,20 +28,21 @@ if TYPE_CHECKING:
class SettingInheritanceManager(QObject): class SettingInheritanceManager(QObject):
def __init__(self, parent = None) -> None: def __init__(self, parent = None) -> None:
super().__init__(parent) super().__init__(parent)
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
self._global_container_stack = None # type: Optional[ContainerStack] self._global_container_stack = None # type: Optional[ContainerStack]
self._settings_with_inheritance_warning = [] # type: List[str] self._settings_with_inheritance_warning = [] # type: List[str]
self._active_container_stack = None # type: Optional[ExtruderStack] self._active_container_stack = None # type: Optional[ExtruderStack]
self._onGlobalContainerChanged()
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged)
self._onActiveExtruderChanged()
self._update_timer = QTimer() self._update_timer = QTimer()
self._update_timer.setInterval(500) self._update_timer.setInterval(500)
self._update_timer.setSingleShot(True) self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._update) self._update_timer.timeout.connect(self._update)
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged)
self._onGlobalContainerChanged()
self._onActiveExtruderChanged()
settingsWithIntheritanceChanged = pyqtSignal() settingsWithIntheritanceChanged = pyqtSignal()
## Get the keys of all children settings with an override. ## Get the keys of all children settings with an override.
@ -88,8 +89,8 @@ class SettingInheritanceManager(QObject):
self.settingsWithIntheritanceChanged.emit() self.settingsWithIntheritanceChanged.emit()
@pyqtSlot() @pyqtSlot()
def forceUpdate(self) -> None: def scheduleUpdate(self) -> None:
self._update() self._update_timer.start()
def _onActiveExtruderChanged(self) -> None: def _onActiveExtruderChanged(self) -> None:
new_active_stack = ExtruderManager.getInstance().getActiveExtruderStack() new_active_stack = ExtruderManager.getInstance().getActiveExtruderStack()
@ -106,7 +107,7 @@ class SettingInheritanceManager(QObject):
if self._active_container_stack is not None: if self._active_container_stack is not None:
self._active_container_stack.propertyChanged.connect(self._onPropertyChanged) self._active_container_stack.propertyChanged.connect(self._onPropertyChanged)
self._active_container_stack.containersChanged.connect(self._onContainersChanged) self._active_container_stack.containersChanged.connect(self._onContainersChanged)
self._update() # Ensure that the settings_with_inheritance_warning list is populated. self._update_timer.start() # Ensure that the settings_with_inheritance_warning list is populated.
def _onPropertyChanged(self, key: str, property_name: str) -> None: def _onPropertyChanged(self, key: str, property_name: str) -> None:
if (property_name == "value" or property_name == "enabled") and self._global_container_stack: if (property_name == "value" or property_name == "enabled") and self._global_container_stack:

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2019 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 argparse import argparse
@ -131,7 +131,10 @@ def exceptHook(hook_type, value, traceback):
# Set exception hook to use the crash dialog handler # Set exception hook to use the crash dialog handler
sys.excepthook = exceptHook sys.excepthook = exceptHook
# Enable dumping traceback for all threads # Enable dumping traceback for all threads
faulthandler.enable(all_threads = True) if sys.stderr:
faulthandler.enable(file = sys.stderr, all_threads = True)
else:
faulthandler.enable(file = sys.stdout, all_threads = True)
# Workaround for a race condition on certain systems where there # Workaround for a race condition on certain systems where there
# is a race condition between Arcus and PyQt. Importing Arcus # is a race condition between Arcus and PyQt. Importing Arcus

View File

@ -1,4 +1,4 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2019 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 numpy import numpy
@ -72,7 +72,7 @@ class GcodeStartEndFormatter(Formatter):
value = default_value_str value = default_value_str
# "-1" is global stack, and if the setting value exists in the global stack, use it as the fallback value. # "-1" is global stack, and if the setting value exists in the global stack, use it as the fallback value.
if key in kwargs["-1"]: if key in kwargs["-1"]:
value = kwargs["-1"] value = kwargs["-1"][key]
if str(extruder_nr) in kwargs and key in kwargs[str(extruder_nr)]: if str(extruder_nr) in kwargs and key in kwargs[str(extruder_nr)]:
value = kwargs[str(extruder_nr)][key] value = kwargs[str(extruder_nr)][key]

View File

@ -143,6 +143,52 @@ UM.Dialog
} }
} }
UM.TooltipArea {
Layout.fillWidth:true
height: childrenRect.height
text: catalog.i18nc("@info:tooltip","For lithophanes a simple logarithmic model for translucency is available. For height maps the pixel values correspond to heights linearly.")
Row {
width: parent.width
Label {
text: "Color Model"
width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter
}
ComboBox {
id: color_model
objectName: "ColorModel"
model: [ catalog.i18nc("@item:inlistbox","Linear"), catalog.i18nc("@item:inlistbox","Translucency") ]
width: 180 * screenScaleFactor
onCurrentIndexChanged: { manager.onColorModelChanged(currentIndex) }
}
}
}
UM.TooltipArea {
Layout.fillWidth:true
height: childrenRect.height
text: catalog.i18nc("@info:tooltip","The percentage of light penetrating a print with a thickness of 1 millimeter. Lowering this value increases the contrast in dark regions and decreases the contrast in light regions of the image.")
visible: color_model.currentText == catalog.i18nc("@item:inlistbox","Translucency")
Row {
width: parent.width
Label {
text: catalog.i18nc("@action:label", "1mm Transmittance (%)")
width: 150 * screenScaleFactor
anchors.verticalCenter: parent.verticalCenter
}
TextField {
id: transmittance
objectName: "Transmittance"
focus: true
validator: RegExpValidator {regExp: /^[1-9]\d{0,2}([\,|\.]\d*)?$/}
width: 180 * screenScaleFactor
onTextChanged: { manager.onTransmittanceChanged(text) }
}
}
}
UM.TooltipArea { UM.TooltipArea {
Layout.fillWidth:true Layout.fillWidth:true
height: childrenRect.height height: childrenRect.height

View File

@ -3,6 +3,8 @@
import numpy import numpy
import math
from PyQt5.QtGui import QImage, qRed, qGreen, qBlue from PyQt5.QtGui import QImage, qRed, qGreen, qBlue
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
@ -46,9 +48,9 @@ class ImageReader(MeshReader):
def _read(self, file_name): def _read(self, file_name):
size = max(self._ui.getWidth(), self._ui.getDepth()) size = max(self._ui.getWidth(), self._ui.getDepth())
return self._generateSceneNode(file_name, size, self._ui.peak_height, self._ui.base_height, self._ui.smoothing, 512, self._ui.lighter_is_higher) return self._generateSceneNode(file_name, size, self._ui.peak_height, self._ui.base_height, self._ui.smoothing, 512, self._ui.lighter_is_higher, self._ui.use_transparency_model, self._ui.transmittance_1mm)
def _generateSceneNode(self, file_name, xz_size, peak_height, base_height, blur_iterations, max_size, lighter_is_higher): def _generateSceneNode(self, file_name, xz_size, peak_height, base_height, blur_iterations, max_size, lighter_is_higher, use_transparency_model, transmittance_1mm):
scene_node = SceneNode() scene_node = SceneNode()
mesh = MeshBuilder() mesh = MeshBuilder()
@ -99,12 +101,14 @@ class ImageReader(MeshReader):
for x in range(0, width): for x in range(0, width):
for y in range(0, height): for y in range(0, height):
qrgb = img.pixel(x, y) qrgb = img.pixel(x, y)
avg = float(qRed(qrgb) + qGreen(qrgb) + qBlue(qrgb)) / (3 * 255) if use_transparency_model:
height_data[y, x] = avg height_data[y, x] = (0.299 * math.pow(qRed(qrgb) / 255.0, 2.2) + 0.587 * math.pow(qGreen(qrgb) / 255.0, 2.2) + 0.114 * math.pow(qBlue(qrgb) / 255.0, 2.2))
else:
height_data[y, x] = (0.212655 * qRed(qrgb) + 0.715158 * qGreen(qrgb) + 0.072187 * qBlue(qrgb)) / 255 # fast computation ignoring gamma and degamma
Job.yieldThread() Job.yieldThread()
if not lighter_is_higher: if lighter_is_higher == use_transparency_model:
height_data = 1 - height_data height_data = 1 - height_data
for _ in range(0, blur_iterations): for _ in range(0, blur_iterations):
@ -124,8 +128,15 @@ class ImageReader(MeshReader):
Job.yieldThread() Job.yieldThread()
height_data *= scale_vector.y if use_transparency_model:
height_data += base_height divisor = 1.0 / math.log(transmittance_1mm / 100.0) # log-base doesn't matter here. Precompute this value for faster computation of each pixel.
min_luminance = (transmittance_1mm / 100.0) ** (peak_height - base_height)
for (y, x) in numpy.ndindex(height_data.shape):
mapped_luminance = min_luminance + (1.0 - min_luminance) * height_data[y, x]
height_data[y, x] = base_height + divisor * math.log(mapped_luminance) # use same base as a couple lines above this
else:
height_data *= scale_vector.y
height_data += base_height
heightmap_face_count = 2 * height_minus_one * width_minus_one heightmap_face_count = 2 * height_minus_one * width_minus_one
total_face_count = heightmap_face_count + (width_minus_one * 2) * (height_minus_one * 2) + 2 total_face_count = heightmap_face_count + (width_minus_one * 2) * (height_minus_one * 2) + 2

View File

@ -34,6 +34,8 @@ class ImageReaderUI(QObject):
self.peak_height = 2.5 self.peak_height = 2.5
self.smoothing = 1 self.smoothing = 1
self.lighter_is_higher = False; self.lighter_is_higher = False;
self.use_transparency_model = True;
self.transmittance_1mm = 50.0; # based on pearl PLA
self._ui_lock = threading.Lock() self._ui_lock = threading.Lock()
self._cancelled = False self._cancelled = False
@ -75,6 +77,7 @@ class ImageReaderUI(QObject):
self._ui_view.findChild(QObject, "Base_Height").setProperty("text", str(self.base_height)) self._ui_view.findChild(QObject, "Base_Height").setProperty("text", str(self.base_height))
self._ui_view.findChild(QObject, "Peak_Height").setProperty("text", str(self.peak_height)) self._ui_view.findChild(QObject, "Peak_Height").setProperty("text", str(self.peak_height))
self._ui_view.findChild(QObject, "Transmittance").setProperty("text", str(self.transmittance_1mm))
self._ui_view.findChild(QObject, "Smoothing").setProperty("value", self.smoothing) self._ui_view.findChild(QObject, "Smoothing").setProperty("value", self.smoothing)
def _createConfigUI(self): def _createConfigUI(self):
@ -144,3 +147,11 @@ class ImageReaderUI(QObject):
@pyqtSlot(int) @pyqtSlot(int)
def onImageColorInvertChanged(self, value): def onImageColorInvertChanged(self, value):
self.lighter_is_higher = (value == 1) self.lighter_is_higher = (value == 1)
@pyqtSlot(int)
def onColorModelChanged(self, value):
self.use_transparency_model = (value == 0)
@pyqtSlot(int)
def onTransmittanceChanged(self, value):
self.transmittance_1mm = value

View File

@ -0,0 +1,94 @@
# Cura PostProcessingPlugin
# Author: Mathias Lyngklip Kjeldgaard
# Date: July 31, 2019
# Modified: ---
# Description: This plugin displayes the remaining time on the LCD of the printer
# using the estimated print-time generated by Cura.
from ..Script import Script
import re
import datetime
class DisplayRemainingTimeOnLCD(Script):
def __init__(self):
super().__init__()
def getSettingDataString(self):
return """{
"name":"Disaplay Remaining Time on LCD",
"key":"DisplayRemainingTimeOnLCD",
"metadata": {},
"version": 2,
"settings":
{
"TurnOn":
{
"label": "Enable",
"description": "When enabled, It will write Time Left: HHMMSS on the display",
"type": "bool",
"default_value": false
}
}
}"""
def execute(self, data):
if self.getSettingValueByKey("TurnOn"):
total_time = 0
total_time_string = ""
for layer in data:
layer_index = data.index(layer)
lines = layer.split("\n")
for line in lines:
if line.startswith(";TIME:"):
# At this point, we have found a line in the GCODE with ";TIME:"
# which is the indication of total_time. Looks like: ";TIME:1337", where
# 1337 is the total print time in seconds.
line_index = lines.index(line) # We take a hold of that line
split_string = re.split(":", line) # Then we split it, so we can get the number
string_with_numbers = "{}".format(split_string[1]) # Here we insert that number from the
# list into a string.
total_time = int(string_with_numbers) # Only to contert it to a int.
m, s = divmod(total_time, 60) # Math to calculate
h, m = divmod(m, 60) # hours, minutes and seconds.
total_time_string = "{:d}h{:02d}m{:02d}s".format(h, m, s) # Now we put it into the string
lines[line_index] = "M117 Time Left {}".format(total_time_string) # And print that string instead of the original one
elif line.startswith(";TIME_ELAPSED:"):
# As we didnt find the total time (";TIME:"), we have found a elapsed time mark
# This time represents the time the printer have printed. So with some math;
# totalTime - printTime = RemainingTime.
line_index = lines.index(line) # We get a hold of the line
list_split = re.split(":", line) # Again, we split at ":" so we can get the number
string_with_numbers = "{}".format(list_split[1]) # Then we put that number from the list, into a string
current_time = float(string_with_numbers) # This time we convert to a float, as the line looks something like:
# ;TIME_ELAPSED:1234.6789
# which is total time in seconds
time_left = total_time - current_time # Here we calculate remaining time
m1, s1 = divmod(time_left, 60) # And some math to get the total time in seconds into
h1, m1 = divmod(m1, 60) # the right format. (HH,MM,SS)
current_time_string = "{:d}h{:2d}m{:2d}s".format(int(h1), int(m1), int(s1)) # Here we create the string holding our time
lines[line_index] = "M117 Time Left {}".format(current_time_string) # And now insert that into the GCODE
# Here we are OUT of the second for-loop
# Which means we have found and replaces all the occurences.
# Which also means we are ready to join the lines for that section of the GCODE file.
final_lines = "\n".join(lines)
data[layer_index] = final_lines
return data

View File

@ -12,14 +12,18 @@ import Cura 1.0 as Cura
Item Item
{ {
// An Item whose bounds are guaranteed to be safe for overlays to be placed.
// Defaults to parent, ie. the entire available area
property var safeArea: parent
// Subtract the actionPanel from the safe area. This way the view won't draw interface elements under/over it // Subtract the actionPanel from the safe area. This way the view won't draw interface elements under/over it
Item { Item
id: safeArea {
visible: false id: childSafeArea
anchors.left: parent.left x: safeArea.x - parent.x
anchors.right: actionPanelWidget.left y: safeArea.y - parent.y
anchors.top: parent.top width: actionPanelWidget.x - x
anchors.bottom: actionPanelWidget.top height: actionPanelWidget.y - y
} }
Loader Loader
@ -29,11 +33,11 @@ Item
source: UM.Controller.activeView != null && UM.Controller.activeView.mainComponent != null ? UM.Controller.activeView.mainComponent : "" source: UM.Controller.activeView != null && UM.Controller.activeView.mainComponent != null ? UM.Controller.activeView.mainComponent : ""
Binding onLoaded:
{ {
target: previewMain.item if (previewMain.item.safeArea !== undefined){
property: "safeArea" previewMain.item.safeArea = Qt.binding(function() { return childSafeArea });
value:safeArea }
} }
} }

View File

@ -56,6 +56,11 @@ Item
return Math.min(Math.max(value, sliderRoot.minimumValue), sliderRoot.maximumValue) return Math.min(Math.max(value, sliderRoot.minimumValue), sliderRoot.maximumValue)
} }
onWidthChanged : {
// After a width change, the pixel-position of the handle is out of sync with the property value
setHandleValue(handleValue)
}
// slider track // slider track
Rectangle Rectangle
{ {

View File

@ -18,7 +18,10 @@ Item
property bool isSimulationPlaying: false property bool isSimulationPlaying: false
readonly property var layerSliderSafeYMax: safeArea.y + safeArea.height readonly property real layerSliderSafeYMin: safeArea.y
readonly property real layerSliderSafeYMax: safeArea.y + safeArea.height
readonly property real pathSliderSafeXMin: safeArea.x + playButton.width
readonly property real pathSliderSafeXMax: safeArea.x + safeArea.width
visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity
@ -26,13 +29,21 @@ Item
PathSlider PathSlider
{ {
id: pathSlider id: pathSlider
readonly property real preferredWidth: UM.Theme.getSize("slider_layerview_size").height // not a typo, should be as long as layerview slider
readonly property real margin: UM.Theme.getSize("default_margin").width
readonly property real pathSliderSafeWidth: pathSliderSafeXMax - pathSliderSafeXMin
height: UM.Theme.getSize("slider_handle").width height: UM.Theme.getSize("slider_handle").width
width: UM.Theme.getSize("slider_layerview_size").height width: preferredWidth + margin * 2 < pathSliderSafeWidth ? preferredWidth : pathSliderSafeWidth - margin * 2
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: UM.Theme.getSize("default_margin").height anchors.bottomMargin: margin
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: -(parent.width - pathSliderSafeXMax - pathSliderSafeXMin) / 2 // center between parent top and layerSliderSafeYMax
visible: !UM.SimulationView.compatibilityMode visible: !UM.SimulationView.compatibilityMode
@ -184,16 +195,19 @@ Item
{ {
property var preferredHeight: UM.Theme.getSize("slider_layerview_size").height property var preferredHeight: UM.Theme.getSize("slider_layerview_size").height
property double heightMargin: UM.Theme.getSize("default_margin").height property double heightMargin: UM.Theme.getSize("default_margin").height
property double layerSliderSafeHeight: layerSliderSafeYMax - layerSliderSafeYMin
//todo incorporate margins in safeHeight?
id: layerSlider id: layerSlider
width: UM.Theme.getSize("slider_handle").width width: UM.Theme.getSize("slider_handle").width
height: preferredHeight + heightMargin * 2 < layerSliderSafeYMax ? preferredHeight : layerSliderSafeYMax - heightMargin * 2 height: preferredHeight + heightMargin * 2 < layerSliderSafeHeight ? preferredHeight : layerSliderSafeHeight - heightMargin * 2
anchors anchors
{ {
right: parent.right right: parent.right
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
verticalCenterOffset: -(parent.height - layerSliderSafeYMax) / 2 // center between parent top and layerSliderSafeYMax verticalCenterOffset: -(parent.height - layerSliderSafeYMax - layerSliderSafeYMin) / 2 // center between parent top and layerSliderSafeYMax
rightMargin: UM.Theme.getSize("default_margin").width rightMargin: UM.Theme.getSize("default_margin").width
bottomMargin: heightMargin bottomMargin: heightMargin
topMargin: heightMargin topMargin: heightMargin

View File

@ -63,41 +63,41 @@ Item
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
color: UM.Theme.getColor("monitor_text_primary") color: UM.Theme.getColor("monitor_text_primary")
font: UM.Theme.getFont("default") // 12pt, regular font: UM.Theme.getFont("default")
text: text:
{ {
if (!printJob) if (!printJob)
{ {
return "" return "";
} }
switch (printJob.state) switch (printJob.state)
{ {
case "wait_cleanup": case "wait_cleanup":
if (printJob.timeTotal > printJob.timeElapsed) if (printJob.timeTotal > printJob.timeElapsed)
{ {
return catalog.i18nc("@label:status", "Aborted") return catalog.i18nc("@label:status", "Aborted");
} }
return catalog.i18nc("@label:status", "Finished") return catalog.i18nc("@label:status", "Finished");
case "finished": case "finished":
return catalog.i18nc("@label:status", "Finished") return catalog.i18nc("@label:status", "Finished");
case "sent_to_printer": case "sent_to_printer":
return catalog.i18nc("@label:status", "Preparing...") return catalog.i18nc("@label:status", "Preparing...");
case "pre_print": case "pre_print":
return catalog.i18nc("@label:status", "Preparing...") return catalog.i18nc("@label:status", "Preparing...");
case "aborting": // NOTE: Doesn't exist but maybe should someday case "aborting": // NOTE: Doesn't exist but maybe should someday
return catalog.i18nc("@label:status", "Aborting...") return catalog.i18nc("@label:status", "Aborting...");
case "aborted": // NOTE: Unused, see above case "aborted": // NOTE: Unused, see above
return catalog.i18nc("@label:status", "Aborted") return catalog.i18nc("@label:status", "Aborted");
case "pausing": case "pausing":
return catalog.i18nc("@label:status", "Pausing...") return catalog.i18nc("@label:status", "Pausing...");
case "paused": case "paused":
return catalog.i18nc("@label:status", "Paused") return catalog.i18nc("@label:status", "Paused");
case "resuming": case "resuming":
return catalog.i18nc("@label:status", "Resuming...") return catalog.i18nc("@label:status", "Resuming...");
case "queued": case "queued":
return catalog.i18nc("@label:status", "Action required") return catalog.i18nc("@label:status", "Action required");
default: default:
return catalog.i18nc("@label:status", "Finishes %1 at %2".arg(OutputDevice.getDateCompleted( printJob.timeRemaining )).arg(OutputDevice.getTimeCompleted( printJob.timeRemaining ))) return catalog.i18nc("@label:status", "Finishes %1 at %2".arg(OutputDevice.getDateCompleted(printJob.timeRemaining)).arg(OutputDevice.getTimeCompleted(printJob.timeRemaining)));
} }
} }
width: contentWidth width: contentWidth

View File

@ -1,52 +1,57 @@
// Copyright (c) 2019 Ultimaker B.V. // Copyright (c) 2019 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 QtQuick 2.2 import QtQuick 2.2
import QtQuick.Window 2.2 import QtQuick.Window 2.2
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import UM 1.1 as UM import UM 1.1 as UM
UM.Dialog { UM.Dialog {
id: base; id: base;
title: catalog.i18nc("@title:window", "Print over network");
width: minimumWidth;
height: minimumHeight; height: minimumHeight;
leftButtons: [
Button {
enabled: true;
onClicked: {
base.visible = false;
printerSelectionCombobox.currentIndex = 0;
OutputDevice.cancelPrintSelection();
}
text: catalog.i18nc("@action:button","Cancel");
}
]
maximumHeight: minimumHeight; maximumHeight: minimumHeight;
maximumWidth: minimumWidth; maximumWidth: minimumWidth;
minimumHeight: 140 * screenScaleFactor; minimumHeight: 140 * screenScaleFactor;
minimumWidth: 500 * screenScaleFactor; minimumWidth: 500 * screenScaleFactor;
modality: Qt.ApplicationModal; modality: Qt.ApplicationModal;
onVisibleChanged: {
if (visible) { Component.onCompleted: {
resetPrintersModel(); populateComboBox()
} else { }
OutputDevice.cancelPrintSelection();
// populates the combo box with the correct printer values
function populateComboBox() {
comboBoxPrintersModel.clear();
comboBoxPrintersModel.append({ name: "Automatic", key: "" }); // Connect will just do it's thing
for (var i in OutputDevice.printers) {
comboBoxPrintersModel.append({
name: OutputDevice.printers[i].name,
key: OutputDevice.printers[i].uniqueName
});
} }
} }
leftButtons: [
Button {
enabled: true;
onClicked: {
base.close();
}
text: catalog.i18nc("@action:button","Cancel");
}
]
rightButtons: [ rightButtons: [
Button { Button {
enabled: true; enabled: true;
onClicked: { onClicked: {
base.visible = false; OutputDevice.selectTargetPrinter(printerComboBox.model.get(printerComboBox.currentIndex).key);
OutputDevice.selectPrinter(printerSelectionCombobox.model.get(printerSelectionCombobox.currentIndex).key); base.close();
// reset to defaults
printerSelectionCombobox.currentIndex = 0;
} }
text: catalog.i18nc("@action:button","Print"); text: catalog.i18nc("@action:button","Print");
} }
] ]
title: catalog.i18nc("@title:window", "Print over network");
visible: true;
width: minimumWidth;
Column { Column {
id: printerSelection; id: printerSelection;
@ -59,10 +64,6 @@ UM.Dialog {
} }
height: 50 * screenScaleFactor; height: 50 * screenScaleFactor;
SystemPalette {
id: palette;
}
UM.I18nCatalog { UM.I18nCatalog {
id: catalog; id: catalog;
name: "cura"; name: "cura";
@ -82,23 +83,14 @@ UM.Dialog {
} }
ComboBox { ComboBox {
id: printerSelectionCombobox; id: printerComboBox;
Behavior on height { NumberAnimation { duration: 100 } } Behavior on height { NumberAnimation { duration: 100 } }
height: 40 * screenScaleFactor; height: 40 * screenScaleFactor;
model: ListModel { model: ListModel {
id: printersModel; id: comboBoxPrintersModel;
} }
textRole: "name"; textRole: "name";
width: parent.width; width: parent.width;
} }
} }
// Utils
function resetPrintersModel() {
printersModel.clear();
printersModel.append({ name: "Automatic", key: ""});
for (var index in OutputDevice.printers) {
printersModel.append({name: OutputDevice.printers[index].name, key: OutputDevice.printers[index].key});
}
}
} }

View File

@ -79,6 +79,7 @@ class ClusterPrinterStatus(BaseModel):
def updateOutputModel(self, model: PrinterOutputModel) -> None: def updateOutputModel(self, model: PrinterOutputModel) -> None:
model.updateKey(self.uuid) model.updateKey(self.uuid)
model.updateName(self.friendly_name) model.updateName(self.friendly_name)
model.updateUniqueName(self.unique_name)
model.updateType(self.machine_variant) model.updateType(self.machine_variant)
model.updateState(self.status if self.enabled else "disabled") model.updateState(self.status if self.enabled else "disabled")
model.updateBuildplate(self.build_plate.type if self.build_plate else "glass") model.updateBuildplate(self.build_plate.type if self.build_plate else "glass")

View File

@ -135,7 +135,7 @@ class ClusterApiClient:
result = model_class(**response) # type: ClusterApiClientModel result = model_class(**response) # type: ClusterApiClientModel
on_finished_item = cast(Callable[[ClusterApiClientModel], Any], on_finished) on_finished_item = cast(Callable[[ClusterApiClientModel], Any], on_finished)
on_finished_item(result) on_finished_item(result)
except (JSONDecodeError, TypeError): except (JSONDecodeError, TypeError, ValueError):
Logger.log("e", "Could not parse response from network: %s", str(response)) Logger.log("e", "Could not parse response from network: %s", str(response))
## Creates a callback function so that it includes the parsing of the response into the correct model. ## Creates a callback function so that it includes the parsing of the response into the correct model.

View File

@ -1,16 +1,17 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2019 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 os
from typing import Optional, Dict, List, Callable, Any from typing import Optional, Dict, List, Callable, Any
from PyQt5.QtGui import QDesktopServices from PyQt5.QtGui import QDesktopServices
from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty from PyQt5.QtCore import pyqtSlot, QUrl, pyqtSignal, pyqtProperty, QObject
from PyQt5.QtNetwork import QNetworkReply from PyQt5.QtNetwork import QNetworkReply
from UM.FileHandler.FileHandler import FileHandler from UM.FileHandler.FileHandler import FileHandler
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Logger import Logger from UM.Logger import Logger
from UM.Scene.SceneNode import SceneNode from UM.Scene.SceneNode import SceneNode
from cura.CuraApplication import CuraApplication
from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState from cura.PrinterOutput.NetworkedPrinterOutputDevice import AuthState
from cura.PrinterOutput.PrinterOutputDevice import ConnectionType from cura.PrinterOutput.PrinterOutputDevice import ConnectionType
@ -42,6 +43,8 @@ class LocalClusterOutputDevice(UltimakerNetworkedPrinterOutputDevice):
) )
self._cluster_api = None # type: Optional[ClusterApiClient] self._cluster_api = None # type: Optional[ClusterApiClient]
self._active_exported_job = None # type: Optional[ExportFileJob]
self._printer_select_dialog = None # type: Optional[QObject]
# We don't have authentication over local networking, so we're always authenticated. # We don't have authentication over local networking, so we're always authenticated.
self.setAuthenticationState(AuthState.Authenticated) self.setAuthenticationState(AuthState.Authenticated)
@ -129,17 +132,50 @@ class LocalClusterOutputDevice(UltimakerNetworkedPrinterOutputDevice):
job.finished.connect(self._onPrintJobCreated) job.finished.connect(self._onPrintJobCreated)
job.start() job.start()
## Allows the user to choose a printer to print with from the printer selection dialogue.
# \param unique_name: The unique name of the printer to target.
@pyqtSlot(str, name="selectTargetPrinter")
def selectTargetPrinter(self, unique_name: str = "") -> None:
self._startPrintJobUpload(unique_name if unique_name != "" else None)
## Handler for when the print job was created locally. ## Handler for when the print job was created locally.
# It can now be sent over the network. # It can now be sent over the network.
def _onPrintJobCreated(self, job: ExportFileJob) -> None: def _onPrintJobCreated(self, job: ExportFileJob) -> None:
self._active_exported_job = job
# TODO: add preference to enable/disable this feature?
if self.clusterSize > 1:
self._showPrinterSelectionDialog() # self._startPrintJobUpload will be triggered from this dialog
return
self._startPrintJobUpload()
## Shows a dialog allowing the user to select which printer in a group to send a job to.
def _showPrinterSelectionDialog(self) -> None:
if not self._printer_select_dialog:
plugin_path = CuraApplication.getInstance().getPluginRegistry().getPluginPath("UM3NetworkPrinting") or ""
path = os.path.join(plugin_path, "resources", "qml", "PrintWindow.qml")
self._printer_select_dialog = CuraApplication.getInstance().createQmlComponent(path, {"OutputDevice": self})
if self._printer_select_dialog is not None:
self._printer_select_dialog.show()
## Upload the print job to the group.
def _startPrintJobUpload(self, unique_name: str = None) -> None:
if not self._active_exported_job:
Logger.log("e", "No active exported job to upload!")
return
self._progress.show() self._progress.show()
parts = [ parts = [
self._createFormPart("name=owner", bytes(self._getUserName(), "utf-8"), "text/plain"), self._createFormPart("name=owner", bytes(self._getUserName(), "utf-8"), "text/plain"),
self._createFormPart("name=\"file\"; filename=\"%s\"" % job.getFileName(), job.getOutput()) self._createFormPart("name=\"file\"; filename=\"%s\"" % self._active_exported_job.getFileName(),
self._active_exported_job.getOutput())
] ]
# If a specific printer was selected we include the name in the request.
# FIXME: Connect should allow the printer UUID here instead of the 'unique_name'.
if unique_name is not None:
parts.append(self._createFormPart("name=require_printer_name", bytes(unique_name, "utf-8"), "text/plain"))
# FIXME: move form posting to API client # FIXME: move form posting to API client
self.postFormWithParts("/cluster-api/v1/print_jobs/", parts, on_finished=self._onPrintUploadCompleted, self.postFormWithParts("/cluster-api/v1/print_jobs/", parts, on_finished=self._onPrintUploadCompleted,
on_progress=self._onPrintJobUploadProgress) on_progress=self._onPrintJobUploadProgress)
self._active_exported_job = None
## Handler for print job upload progress. ## Handler for print job upload progress.
def _onPrintJobUploadProgress(self, bytes_sent: int, bytes_total: int) -> None: def _onPrintJobUploadProgress(self, bytes_sent: int, bytes_total: int) -> None:

View File

@ -43,7 +43,7 @@ class ZeroConfClient:
Logger.logException("e", "Failed to create zeroconf instance.") Logger.logException("e", "Failed to create zeroconf instance.")
return return
self._service_changed_request_thread = Thread(target = self._handleOnServiceChangedRequests, daemon = True) self._service_changed_request_thread = Thread(target = self._handleOnServiceChangedRequests, daemon = True, name = "ZeroConfServiceChangedThread")
self._service_changed_request_thread.start() self._service_changed_request_thread.start()
self._zero_conf_browser = ServiceBrowser(self._zero_conf, self.ZERO_CONF_NAME, [self._queueService]) self._zero_conf_browser = ServiceBrowser(self._zero_conf, self.ZERO_CONF_NAME, [self._queueService])

View File

@ -61,7 +61,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._all_baud_rates = [115200, 250000, 500000, 230400, 57600, 38400, 19200, 9600] self._all_baud_rates = [115200, 250000, 500000, 230400, 57600, 38400, 19200, 9600]
# Instead of using a timer, we really need the update to be as a thread, as reading from serial can block. # Instead of using a timer, we really need the update to be as a thread, as reading from serial can block.
self._update_thread = Thread(target = self._update, daemon = True) self._update_thread = Thread(target = self._update, daemon = True, name = "USBPrinterUpdate")
self._last_temperature_request = None # type: Optional[int] self._last_temperature_request = None # type: Optional[int]
self._firmware_idle_count = 0 self._firmware_idle_count = 0
@ -212,7 +212,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
self._serial.close() self._serial.close()
# Re-create the thread so it can be started again later. # Re-create the thread so it can be started again later.
self._update_thread = Thread(target=self._update, daemon=True) self._update_thread = Thread(target=self._update, daemon=True, name = "USBPrinterUpdate")
self._serial = None self._serial = None
## Send a command to printer. ## Send a command to printer.

View File

@ -66,6 +66,13 @@ class VersionUpgrade43to44(VersionUpgrade):
# Alternate skin rotation should be translated to top/bottom line directions. # Alternate skin rotation should be translated to top/bottom line directions.
if "skin_alternate_rotation" in parser["values"] and parseBool(parser["values"]["skin_alternate_rotation"]): if "skin_alternate_rotation" in parser["values"] and parseBool(parser["values"]["skin_alternate_rotation"]):
parser["values"]["skin_angles"] = "[45, 135, 0, 90]" parser["values"]["skin_angles"] = "[45, 135, 0, 90]"
# Unit of adaptive layers topography size changed.
if "adaptive_layer_height_threshold" in parser["values"]:
val = parser["values"]["adaptive_layer_height_threshold"]
if val.startswith("="):
val = val[1:]
val = "=({val}) / 1000".format(val = val) # Convert microns to millimetres. Works even if the profile contained a formula.
parser["values"]["adaptive_layer_height_threshold"] = val
result = io.StringIO() result = io.StringIO()
parser.write(result) parser.write(result)

View File

@ -6658,30 +6658,26 @@
}, },
"flow_rate_max_extrusion_offset": "flow_rate_max_extrusion_offset":
{ {
"label": "Flow rate compensation max extrusion offset", "label": "Flow Rate Compensation Max Extrusion Offset",
"description": "The maximum distance in mm to compensate.", "description": "The maximum distance in mm to move the filament to compensate for changes in flow rate.",
"unit": "mm", "unit": "mm",
"type": "float", "type": "float",
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "10", "maximum_value_warning": "10",
"default_value": 0, "default_value": 0,
"value": "0",
"enabled": true,
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
}, },
"flow_rate_extrusion_offset_factor": "flow_rate_extrusion_offset_factor":
{ {
"label": "Flow rate compensation factor", "label": "Flow Rate Compensation Factor",
"description": "The multiplication factor for the flow rate -> distance translation.", "description": "How far to move the filament in order to compensate for changes in flow rate, as a percentage of how far the filament would move in one second of extrusion.",
"unit": "%", "unit": "%",
"type": "float", "type": "float",
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "100", "maximum_value_warning": "100",
"default_value": 100, "default_value": 100,
"value": "100",
"enabled": true,
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
@ -6704,7 +6700,7 @@
"unit": "mm", "unit": "mm",
"default_value": 3, "default_value": 3,
"value": "machine_nozzle_head_distance", "value": "machine_nozzle_head_distance",
"minimum_value": "0.0001", "minimum_value": "0.001",
"maximum_value_warning": "20", "maximum_value_warning": "20",
"enabled": "wireframe_enabled", "enabled": "wireframe_enabled",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -6734,7 +6730,7 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 5, "default_value": 5,
"minimum_value": "0.1", "minimum_value": "0.05",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + machine_max_feedrate_z ** 2)", "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + machine_max_feedrate_z ** 2)",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "wireframe_enabled", "enabled": "wireframe_enabled",
@ -6750,11 +6746,11 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 5, "default_value": 5,
"minimum_value": "0.1", "minimum_value": "0.05",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)", "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "wireframe_enabled", "enabled": "wireframe_enabled",
"value": "wireframe_printspeed", "value": "wireframe_printspeed_flat",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
@ -6766,7 +6762,7 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 5, "default_value": 5,
"minimum_value": "0.1", "minimum_value": "0.05",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + machine_max_feedrate_z ** 2)", "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + machine_max_feedrate_z ** 2)",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "wireframe_enabled", "enabled": "wireframe_enabled",
@ -6782,7 +6778,7 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 5, "default_value": 5,
"minimum_value": "0.1", "minimum_value": "0.05",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + machine_max_feedrate_z ** 2)", "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2 + machine_max_feedrate_z ** 2)",
"maximum_value_warning": "50", "maximum_value_warning": "50",
"enabled": "wireframe_enabled", "enabled": "wireframe_enabled",
@ -6798,7 +6794,7 @@
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 5, "default_value": 5,
"minimum_value": "0.1", "minimum_value": "0.05",
"maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)", "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
"maximum_value_warning": "100", "maximum_value_warning": "100",
"value": "wireframe_printspeed", "value": "wireframe_printspeed",
@ -6921,7 +6917,7 @@
"default_value": 0.6, "default_value": 0.6,
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "2.0", "maximum_value_warning": "2.0",
"enabled": "wireframe_enabled", "enabled": "wireframe_enabled and wireframe_strategy == 'knot'",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
@ -6935,7 +6931,7 @@
"default_value": 0.5, "default_value": 0.5,
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "wireframe_height", "maximum_value_warning": "wireframe_height",
"enabled": "wireframe_enabled", "enabled": "wireframe_enabled and wireframe_strategy == 'compensate'",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
@ -6949,7 +6945,7 @@
"default_value": 0.6, "default_value": 0.6,
"minimum_value": "0", "minimum_value": "0",
"maximum_value_warning": "wireframe_height", "maximum_value_warning": "wireframe_height",
"enabled": "wireframe_enabled", "enabled": "wireframe_enabled and wireframe_strategy == 'compensate'",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
@ -7072,17 +7068,18 @@
"default_value": 0.01, "default_value": 0.01,
"unit": "mm", "unit": "mm",
"settable_per_mesh": false, "settable_per_mesh": false,
"minimum_value": "0.0001", "minimum_value": "0.001",
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
}, },
"adaptive_layer_height_threshold": "adaptive_layer_height_threshold":
{ {
"label": "Adaptive Layers Threshold", "label": "Adaptive Layers Topography Size",
"description": "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer.", "description": "Target horizontal distance between two adjacent layers. Reducing this setting causes thinner layers to be used to bring the edges of the layers closer together.",
"type": "float", "type": "float",
"enabled": "adaptive_layer_height_enabled", "enabled": "adaptive_layer_height_enabled",
"default_value": 200.0, "default_value": 0.2,
"unit": "mm",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false

View File

@ -18,12 +18,12 @@
"supports_usb_connection": false, "supports_usb_connection": false,
"machine_extruder_trains": "machine_extruder_trains":
{ {
"0": "alya3dp_extruder_0" "0": "kupido_extruder_0"
} }
}, },
"overrides": { "overrides": {
"machine_name": { "default_value": "ALYA 3DP" }, "machine_name": { "default_value": "KUPIDO" },
"machine_heated_bed": { "default_value": true }, "machine_heated_bed": { "default_value": true },
"machine_width": { "default_value": 195 }, "machine_width": { "default_value": 195 },
"machine_height": { "default_value": 190 }, "machine_height": { "default_value": 190 },

View File

@ -14,7 +14,7 @@
"has_variants": true, "has_variants": true,
"preferred_variant_name": "Standard 0.6", "preferred_variant_name": "Standard 0.6",
"preferred_material": "emotiontech_pla", "preferred_material": "emotiontech_pla",
"preferred_quality_type": "e", "preferred_quality_type": "c",
"variants_name": "Print Head", "variants_name": "Print Head",
"machine_extruder_trains": "machine_extruder_trains":
{ {
@ -30,13 +30,14 @@
"machine_depth": { "default_value": 420 }, "machine_depth": { "default_value": 420 },
"machine_height": { "default_value": 495 }, "machine_height": { "default_value": 495 },
"machine_heated_bed": { "default_value": true }, "machine_heated_bed": { "default_value": true },
"machine_heated_build_volume": { "default_value": true },
"machine_center_is_zero": { "default_value": false }, "machine_center_is_zero": { "default_value": false },
"machine_head_with_fans_polygon": { "default_value": [ [ -76, -51.8 ] , [ 25, -51.8 ] , [ 25, 38.2 ] , [ -76, 38.2 ] ] }, "machine_head_with_fans_polygon": { "default_value": [ [ -76, -51.8 ] , [ 25, -51.8 ] , [ 25, 38.2 ] , [ -76, 38.2 ] ] },
"gantry_height": { "value": "40" }, "gantry_height": { "value": "40" },
"machine_extruder_count": { "default_value": 2 }, "machine_extruder_count": { "default_value": 2 },
"machine_gcode_flavor": { "default_value": "Marlin" }, "machine_gcode_flavor": { "default_value": "Marlin" },
"machine_start_gcode": { "default_value": "G28 \nG90 G1 X300 Y210 Z15 F6000 \nG92 E0" }, "machine_start_gcode": { "default_value": "G28 \nG90 G1 X300 Y210 Z15 F6000 \nG92 E0" },
"machine_end_gcode": { "default_value": "T1 \nM104 S0 \nT0 \nM104 S0 \nM140 S0 \nM141 S0 \nG91 \nG0 E-1 F1500 \nG0 z1 \nG90 \nG28 \nM801.2 \nM801.0 \nM84" }, "machine_end_gcode": { "default_value": "T1 \nM104 S0 \nT0 \nM104 S0 \nM140 S0 \nM141 S0 \nG91 \nG0 z1 \nG90 \nG28 \nM801.0 \nM84 \nM192" },
"extruder_prime_pos_y": {"minimum_value": "0", "maximum_value": "machine_depth"}, "extruder_prime_pos_y": {"minimum_value": "0", "maximum_value": "machine_depth"},
"extruder_prime_pos_x": {"minimum_value": "0", "maximum_value": "machine_width"}, "extruder_prime_pos_x": {"minimum_value": "0", "maximum_value": "machine_width"},
"machine_heat_zone_length": { "default_value": 7 }, "machine_heat_zone_length": { "default_value": 7 },
@ -46,17 +47,17 @@
"material_bed_temperature": { "maximum_value": "130" }, "material_bed_temperature": { "maximum_value": "130" },
"material_bed_temperature_layer_0": { "maximum_value": "130" }, "material_bed_temperature_layer_0": { "maximum_value": "130" },
"extruder_prime_pos_abs": { "default_value": true }, "extruder_prime_pos_abs": { "default_value": true },
"machine_acceleration": { "default_value": 2000 }, "machine_acceleration": { "default_value": 1500 },
"acceleration_enabled": { "value": false }, "acceleration_enabled": { "value": false },
"acceleration_layer_0": { "value": "acceleration_topbottom" }, "acceleration_print": { "value": "machine_acceleration" },
"acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 1000 / 2000)" }, "acceleration_wall": { "value": "math.ceil(acceleration_print * 1250 / acceleration_print)" },
"acceleration_print": { "value": "2000" }, "acceleration_wall_0": { "value": "math.ceil(acceleration_print * 1000 / acceleration_print)" },
"acceleration_topbottom": { "value": "math.ceil(acceleration_print * 1250 / acceleration_print)" },
"acceleration_support": { "value": "acceleration_print" }, "acceleration_support": { "value": "acceleration_print" },
"acceleration_support_interface": { "value": "acceleration_topbottom" }, "acceleration_support_interface": { "value": "acceleration_topbottom" },
"acceleration_topbottom": { "value": "math.ceil(acceleration_print * 1000 / 2000)" }, "acceleration_travel": { "value": "acceleration_print" },
"acceleration_wall": { "value": "math.ceil(acceleration_print * 1500 / 2000)" }, "acceleration_layer_0": { "value": "acceleration_topbottom" },
"acceleration_wall_0": { "value": "math.ceil(acceleration_wall * 1000 / 1500)" },
"adaptive_layer_height_variation": { "default_value": 0.1 }, "adaptive_layer_height_variation": { "default_value": 0.1 },
"adaptive_layer_height_variation_step": { "default_value": 0.05 }, "adaptive_layer_height_variation_step": { "default_value": 0.05 },
"adhesion_type": { "default_value": "skirt" }, "adhesion_type": { "default_value": "skirt" },

View File

@ -67,8 +67,6 @@
"extruder_prime_pos_abs": { "default_value": true }, "extruder_prime_pos_abs": { "default_value": true },
"machine_start_gcode": { "default_value": "" }, "machine_start_gcode": { "default_value": "" },
"machine_end_gcode": { "default_value": "" }, "machine_end_gcode": { "default_value": "" },
"prime_tower_position_x": { "value": "345" },
"prime_tower_position_y": { "value": "222.5" },
"prime_blob_enable": { "enabled": true, "default_value": false }, "prime_blob_enable": { "enabled": true, "default_value": false },
"speed_travel": "speed_travel":

View File

@ -1,45 +1,45 @@
{ {
"version": 2, "version": 2,
"name": "Extruder 1", "name": "Extruder 1",
"inherits": "fdmextruder", "inherits": "fdmextruder",
"metadata": { "metadata": {
"machine": "BIBO2 dual", "machine": "bibo2_dual",
"position": "0" "position": "0"
}, },
"overrides": { "overrides": {
"extruder_nr": { "extruder_nr": {
"default_value": 0, "default_value": 0,
"maximum_value": "1" "maximum_value": "1"
}, },
"material_diameter": { "material_diameter": {
"default_value": 1.75 "default_value": 1.75
}, },
"machine_nozzle_size": { "machine_nozzle_size": {
"default_value": 0.4 "default_value": 0.4
}, },
"machine_nozzle_offset_x": { "machine_nozzle_offset_x": {
"default_value": 0.0 "default_value": 0.0
}, },
"machine_nozzle_offset_y": { "machine_nozzle_offset_y": {
"default_value": 0.0 "default_value": 0.0
}, },
"machine_extruder_start_pos_abs": { "machine_extruder_start_pos_abs": {
"default_value": true "default_value": true
}, },
"machine_extruder_start_pos_x": { "machine_extruder_start_pos_x": {
"value": "prime_tower_position_x" "value": "prime_tower_position_x"
}, },
"machine_extruder_start_pos_y": { "machine_extruder_start_pos_y": {
"value": "prime_tower_position_y" "value": "prime_tower_position_y"
}, },
"machine_extruder_end_pos_abs": { "machine_extruder_end_pos_abs": {
"default_value": true "default_value": true
}, },
"machine_extruder_end_pos_x": { "machine_extruder_end_pos_x": {
"value": "prime_tower_position_x" "value": "prime_tower_position_x"
}, },
"machine_extruder_end_pos_y": { "machine_extruder_end_pos_y": {
"value": "prime_tower_position_y" "value": "prime_tower_position_y"
} }
} }
} }

View File

@ -1,45 +1,45 @@
{ {
"version": 2, "version": 2,
"name": "Extruder 2", "name": "Extruder 2",
"inherits": "fdmextruder", "inherits": "fdmextruder",
"metadata": { "metadata": {
"machine": "BIBO2 dual", "machine": "bibo2_dual",
"position": "1" "position": "1"
}, },
"overrides": { "overrides": {
"extruder_nr": { "extruder_nr": {
"default_value": 1, "default_value": 1,
"maximum_value": "1" "maximum_value": "1"
}, },
"material_diameter": { "material_diameter": {
"default_value": 1.75 "default_value": 1.75
}, },
"machine_nozzle_size": { "machine_nozzle_size": {
"default_value": 0.4 "default_value": 0.4
}, },
"machine_nozzle_offset_x": { "machine_nozzle_offset_x": {
"default_value": 0.0 "default_value": 0.0
}, },
"machine_nozzle_offset_y": { "machine_nozzle_offset_y": {
"default_value": 0.0 "default_value": 0.0
}, },
"machine_extruder_start_pos_abs": { "machine_extruder_start_pos_abs": {
"default_value": true "default_value": true
}, },
"machine_extruder_start_pos_x": { "machine_extruder_start_pos_x": {
"value": "prime_tower_position_x" "value": "prime_tower_position_x"
}, },
"machine_extruder_start_pos_y": { "machine_extruder_start_pos_y": {
"value": "prime_tower_position_y" "value": "prime_tower_position_y"
}, },
"machine_extruder_end_pos_abs": { "machine_extruder_end_pos_abs": {
"default_value": true "default_value": true
}, },
"machine_extruder_end_pos_x": { "machine_extruder_end_pos_x": {
"value": "prime_tower_position_x" "value": "prime_tower_position_x"
}, },
"machine_extruder_end_pos_y": { "machine_extruder_end_pos_y": {
"value": "prime_tower_position_y" "value": "prime_tower_position_y"
} }
} }
} }

View File

@ -3,7 +3,7 @@
"name": "Left Extruder", "name": "Left Extruder",
"inherits": "fdmextruder", "inherits": "fdmextruder",
"metadata": { "metadata": {
"machine": "Creality CR-X", "machine": "creality_cr-x",
"position": "0" "position": "0"
}, },

View File

@ -3,7 +3,7 @@
"name": "Right Extruder", "name": "Right Extruder",
"inherits": "fdmextruder", "inherits": "fdmextruder",
"metadata": { "metadata": {
"machine": "Creality CR-X", "machine": "creality_cr-x",
"position": "1" "position": "1"
}, },

View File

@ -3,7 +3,7 @@
"name": "Extruder 1", "name": "Extruder 1",
"inherits": "fdmextruder", "inherits": "fdmextruder",
"metadata": { "metadata": {
"machine": "Creatable_D3", "machine": "creatable_d3",
"position": "0" "position": "0"
}, },

View File

@ -3,7 +3,7 @@
"name": "Extruder 1", "name": "Extruder 1",
"inherits": "fdmextruder", "inherits": "fdmextruder",
"metadata": { "metadata": {
"machine": "hellbot_magna_i", "machine": "hellbot_magna_I",
"position": "0" "position": "0"
}, },

View File

@ -3,7 +3,7 @@
"name": "0.4mm Nozzle", "name": "0.4mm Nozzle",
"inherits": "fdmextruder", "inherits": "fdmextruder",
"metadata": { "metadata": {
"machine": "Tyro", "machine": "key3d_tyro",
"position": "0" "position": "0"
}, },

View File

@ -22,7 +22,7 @@
"machine_extruder_end_pos_x": { "default_value": 180 }, "machine_extruder_end_pos_x": { "default_value": 180 },
"machine_extruder_end_pos_y": { "default_value": 180 }, "machine_extruder_end_pos_y": { "default_value": 180 },
"machine_nozzle_head_distance": { "default_value": 4.2 }, "machine_nozzle_head_distance": { "default_value": 4.2 },
"extruder_prime_pos_x": { "default_value": 180 }, "extruder_prime_pos_x": { "value": "machine_width + 3" },
"extruder_prime_pos_y": { "default_value": 6 }, "extruder_prime_pos_y": { "default_value": 6 },
"extruder_prime_pos_z": { "default_value": 2 } "extruder_prime_pos_z": { "default_value": 2 }
} }

View File

@ -2795,7 +2795,7 @@ msgstr "Selecteer eventuele upgrades die op deze Ultimaker Original zijn uitgevo
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:41 #: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOUpgradeSelectionMachineAction.qml:41
msgctxt "@label" msgctxt "@label"
msgid "Heated Build Plate (official kit or self-built)" msgid "Heated Build Plate (official kit or self-built)"
msgstr "Verwarmd Platform (officiële kit of eigenbouw)" msgstr "Verwarmd Platform (officiële kit of zelf gebouwd)"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:119 #: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:119
msgctxt "@label:MonitorStatus" msgctxt "@label:MonitorStatus"

View File

@ -0,0 +1,34 @@
[general]
version = 4
name = Quick
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
intent_category = quick
quality_type = draft
material = generic_abs
variant = AA 0.4
[values]
speed_infill = =speed_print
speed_topbottom = =speed_print
speed_wall = =speed_print
speed_wall_0 = =speed_wall
speed_wall_x = =speed_wall
speed_layer_0 = 20
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 2
fill_perimeter_gaps = nowhere
infill_sparse_density = 15
infill_line_width = =line_width
jerk_print = 30
jerk_infill = =jerk_print
jerk_topbottom = =jerk_print
jerk_wall = =jerk_print
jerk_wall_0 = =jerk_wall
jerk_wall_x = =jerk_wall
jerk_layer_0 = 5
line_width = =machine_nozzle_size
wall_line_width_x = =line_width

View File

@ -0,0 +1,34 @@
[general]
version = 4
name = Accurate
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
intent_category = engineering
quality_type = fast
material = generic_abs
variant = AA 0.4
[values]
infill_line_width = =line_width
jerk_print = 30
jerk_infill = =jerk_print
jerk_topbottom = =jerk_print
jerk_wall = =jerk_print
jerk_wall_0 = =jerk_wall
jerk_wall_x = =jerk_wall
jerk_layer_0 = 5
line_width = =machine_nozzle_size
speed_print = 30
speed_infill = =speed_print
speed_layer_0 = 20
speed_topbottom = =speed_print
speed_wall = =speed_print
speed_wall_0 = =speed_wall
speed_wall_x = =speed_wall
top_bottom_thickness = =wall_thickness
wall_line_width_x = =line_width
wall_thickness = =line_width * 3
xy_offset = =- layer_height * 0.2

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
quality_type = fast
intent_category = visual
material = generic_abs
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
quality_type = high
intent_category = visual
material = generic_abs
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,34 @@
[general]
version = 4
name = Accurate
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
intent_category = engineering
quality_type = normal
material = generic_abs
variant = AA 0.4
[values]
infill_line_width = =line_width
jerk_print = 30
jerk_infill = =jerk_print
jerk_topbottom = =jerk_print
jerk_wall = =jerk_print
jerk_wall_0 = =jerk_wall
jerk_wall_x = =jerk_wall
jerk_layer_0 = 5
line_width = =machine_nozzle_size
speed_print = 30
speed_infill = =speed_print
speed_layer_0 = 20
speed_topbottom = =speed_print
speed_wall = =speed_print
speed_wall_0 = =speed_wall
speed_wall_x = =speed_wall
top_bottom_thickness = =wall_thickness
wall_line_width_x = =line_width
wall_thickness = =line_width * 3
xy_offset = =- layer_height * 0.2

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
quality_type = normal
intent_category = visual
material = generic_abs
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,34 @@
[general]
version = 4
name = Quick
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
intent_category = quick
quality_type = draft
material = generic_pla
variant = AA 0.4
[values]
speed_infill = =speed_print
speed_topbottom = =speed_print
speed_wall = =speed_print
speed_wall_0 = =speed_wall
speed_wall_x = =speed_wall
speed_layer_0 = 20
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 2
fill_perimeter_gaps = nowhere
infill_sparse_density = 15
infill_line_width = =line_width
jerk_print = 30
jerk_infill = =jerk_print
jerk_topbottom = =jerk_print
jerk_wall = =jerk_print
jerk_wall_0 = =jerk_wall
jerk_wall_x = =jerk_wall
jerk_layer_0 = 5
line_width = =machine_nozzle_size
wall_line_width_x = =line_width

View File

@ -0,0 +1,34 @@
[general]
version = 4
name = Accurate
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
intent_category = engineering
quality_type = fast
material = generic_pla
variant = AA 0.4
[values]
infill_line_width = =line_width
jerk_print = 30
jerk_infill = =jerk_print
jerk_topbottom = =jerk_print
jerk_wall = =jerk_print
jerk_wall_0 = =jerk_wall
jerk_wall_x = =jerk_wall
jerk_layer_0 = 5
line_width = =machine_nozzle_size
speed_print = 30
speed_infill = =speed_print
speed_layer_0 = 20
speed_topbottom = =speed_print
speed_wall = =speed_print
speed_wall_0 = =speed_wall
speed_wall_x = =speed_wall
top_bottom_thickness = =wall_thickness
wall_line_width_x = =line_width
wall_thickness = =line_width * 3
xy_offset = =- layer_height * 0.2

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
quality_type = fast
intent_category = visual
material = generic_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
quality_type = high
intent_category = visual
material = generic_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,34 @@
[general]
version = 4
name = Accurate
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
intent_category = engineering
quality_type = normal
material = generic_pla
variant = AA 0.4
[values]
infill_line_width = =line_width
jerk_print = 30
jerk_infill = =jerk_print
jerk_topbottom = =jerk_print
jerk_wall = =jerk_print
jerk_wall_0 = =jerk_wall
jerk_wall_x = =jerk_wall
jerk_layer_0 = 5
line_width = =machine_nozzle_size
speed_print = 30
speed_infill = =speed_print
speed_layer_0 = 20
speed_topbottom = =speed_print
speed_wall = =speed_print
speed_wall_0 = =speed_wall
speed_wall_x = =speed_wall
top_bottom_thickness = =wall_thickness
wall_line_width_x = =line_width
wall_thickness = =line_width * 3
xy_offset = =- layer_height * 0.2

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
quality_type = normal
intent_category = visual
material = generic_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,34 @@
[general]
version = 4
name = Quick
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
intent_category = quick
quality_type = draft
material = generic_tough_pla
variant = AA 0.4
[values]
speed_infill = =speed_print
speed_topbottom = =speed_print
speed_wall = =speed_print
speed_wall_0 = =speed_wall
speed_wall_x = =speed_wall
speed_layer_0 = 20
top_bottom_thickness = =wall_thickness
wall_thickness = =line_width * 2
fill_perimeter_gaps = nowhere
infill_sparse_density = 15
infill_line_width = =line_width
jerk_print = 30
jerk_infill = =jerk_print
jerk_topbottom = =jerk_print
jerk_wall = =jerk_print
jerk_wall_0 = =jerk_wall
jerk_wall_x = =jerk_wall
jerk_layer_0 = 5
line_width = =machine_nozzle_size
wall_line_width_x = =line_width

View File

@ -0,0 +1,34 @@
[general]
version = 4
name = Accurate
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
intent_category = engineering
quality_type = fast
material = generic_tough_pla
variant = AA 0.4
[values]
infill_line_width = =line_width
jerk_print = 30
jerk_infill = =jerk_print
jerk_topbottom = =jerk_print
jerk_wall = =jerk_print
jerk_wall_0 = =jerk_wall
jerk_wall_x = =jerk_wall
jerk_layer_0 = 5
line_width = =machine_nozzle_size
speed_print = 30
speed_infill = =speed_print
speed_layer_0 = 20
speed_topbottom = =speed_print
speed_wall = =speed_print
speed_wall_0 = =speed_wall
speed_wall_x = =speed_wall
top_bottom_thickness = =wall_thickness
wall_line_width_x = =line_width
wall_thickness = =line_width * 3
xy_offset = =- layer_height * 0.2

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
quality_type = fast
intent_category = visual
material = generic_tough_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
quality_type = high
intent_category = visual
material = generic_tough_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,34 @@
[general]
version = 4
name = Accurate
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
intent_category = engineering
quality_type = normal
material = generic_tough_pla
variant = AA 0.4
[values]
infill_line_width = =line_width
jerk_print = 30
jerk_infill = =jerk_print
jerk_topbottom = =jerk_print
jerk_wall = =jerk_print
jerk_wall_0 = =jerk_wall
jerk_wall_x = =jerk_wall
jerk_layer_0 = 5
line_width = =machine_nozzle_size
speed_print = 30
speed_infill = =speed_print
speed_layer_0 = 20
speed_topbottom = =speed_print
speed_wall = =speed_print
speed_wall_0 = =speed_wall
speed_wall_x = =speed_wall
top_bottom_thickness = =wall_thickness
wall_line_width_x = =line_width
wall_thickness = =line_width * 3
xy_offset = =- layer_height * 0.2

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s3
[metadata]
setting_version = 10
type = intent
quality_type = normal
intent_category = visual
material = generic_tough_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -6,7 +6,7 @@ definition = ultimaker_s5
[metadata] [metadata]
setting_version = 10 setting_version = 10
type = intent type = intent
intent_category = smooth intent_category = quick
quality_type = draft quality_type = draft
material = generic_abs material = generic_abs
variant = AA 0.4 variant = AA 0.4

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s5
[metadata]
setting_version = 10
type = intent
quality_type = fast
intent_category = visual
material = generic_abs
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s5
[metadata]
setting_version = 10
type = intent
quality_type = high
intent_category = visual
material = generic_abs
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s5
[metadata]
setting_version = 10
type = intent
quality_type = normal
intent_category = visual
material = generic_abs
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -6,7 +6,7 @@ definition = ultimaker_s5
[metadata] [metadata]
setting_version = 10 setting_version = 10
type = intent type = intent
intent_category = smooth intent_category = quick
quality_type = draft quality_type = draft
material = generic_pla material = generic_pla
variant = AA 0.4 variant = AA 0.4

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s5
[metadata]
setting_version = 10
type = intent
quality_type = fast
intent_category = visual
material = generic_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s5
[metadata]
setting_version = 10
type = intent
quality_type = high
intent_category = visual
material = generic_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s5
[metadata]
setting_version = 10
type = intent
quality_type = normal
intent_category = visual
material = generic_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -6,7 +6,7 @@ definition = ultimaker_s5
[metadata] [metadata]
setting_version = 10 setting_version = 10
type = intent type = intent
intent_category = smooth intent_category = quick
quality_type = draft quality_type = draft
material = generic_tough_pla material = generic_tough_pla
variant = AA 0.4 variant = AA 0.4

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s5
[metadata]
setting_version = 10
type = intent
quality_type = fast
intent_category = visual
material = generic_tough_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s5
[metadata]
setting_version = 10
type = intent
quality_type = high
intent_category = visual
material = generic_tough_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -0,0 +1,17 @@
[general]
version = 4
name = Visual
definition = ultimaker_s5
[metadata]
setting_version = 10
type = intent
quality_type = normal
intent_category = visual
material = generic_tough_pla
variant = AA 0.4
[values]
speed_infill = 50
wall_thickness = =wall_line_width * 3
top_bottom_thickness = =wall_thickness

View File

@ -301,6 +301,15 @@ UM.MainWindow
} }
} }
// A hint for the loaded content view. Overlay items / controls can safely be placed in this area
Item {
id: mainSafeArea
anchors.left: viewOrientationControls.right
anchors.right: main.right
anchors.top: main.top
anchors.bottom: main.bottom
}
Loader Loader
{ {
// A stage can control this area. If nothing is set, it will therefore show the 3D view. // A stage can control this area. If nothing is set, it will therefore show the 3D view.
@ -316,6 +325,12 @@ UM.MainWindow
} }
source: UM.Controller.activeStage != null ? UM.Controller.activeStage.mainComponent : "" source: UM.Controller.activeStage != null ? UM.Controller.activeStage.mainComponent : ""
onLoaded: {
if (main.item.safeArea !== undefined){
main.item.safeArea = Qt.binding(function() { return mainSafeArea });
}
}
} }
Loader Loader

View File

@ -53,7 +53,11 @@ Item
} }
// When loaded, try to select the active material in the tree // When loaded, try to select the active material in the tree
Component.onCompleted: resetExpandedActiveMaterial() Component.onCompleted:
{
resetExpandedActiveMaterial()
base.newRootMaterialIdToSwitchTo = active_root_material_id
}
// Every time the selected item has changed, notify to the details panel // Every time the selected item has changed, notify to the details panel
onCurrentItemChanged: onCurrentItemChanged:

View File

@ -19,12 +19,6 @@ Item
property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1 property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1
property real padding: UM.Theme.getSize("thick_margin").width property real padding: UM.Theme.getSize("thick_margin").width
UM.I18nCatalog
{
id: catalog
name: "cura"
}
Column Column
{ {
spacing: UM.Theme.getSize("wide_margin").height spacing: UM.Theme.getSize("wide_margin").height

View File

@ -124,18 +124,6 @@ Item
elide: Text.ElideRight elide: Text.ElideRight
} }
NoIntentIcon
{
affected_extruders: Cura.MachineManager.extruderPositionsWithNonActiveIntent
intent_type: model.name
anchors.right: intentCategoryLabel.right
anchors.rightMargin: UM.Theme.getSize("narrow_margin").width
width: intentCategoryLabel.height * 0.75
anchors.verticalCenter: parent.verticalCenter
height: width
visible: Cura.MachineManager.activeIntentCategory == model.intent_category && affected_extruders.length
}
Cura.RadioCheckbar Cura.RadioCheckbar
{ {
anchors anchors
@ -164,8 +152,9 @@ Item
isCheckedFunction: checkedFunction isCheckedFunction: checkedFunction
} }
MouseArea // tooltip hover area MouseArea // Intent description tooltip hover area
{ {
id: intentDescriptionHoverArea
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
enabled: model.description !== undefined enabled: model.description !== undefined
@ -181,6 +170,20 @@ Item
} }
onExited: base.hideTooltip() onExited: base.hideTooltip()
} }
NoIntentIcon // This icon has hover priority over intentDescriptionHoverArea, so draw it above it.
{
affected_extruders: Cura.MachineManager.extruderPositionsWithNonActiveIntent
intent_type: model.name
anchors.right: intentCategoryLabel.right
anchors.rightMargin: UM.Theme.getSize("narrow_margin").width
width: intentCategoryLabel.height * 0.75
anchors.verticalCenter: parent.verticalCenter
height: width
visible: Cura.MachineManager.activeIntentCategory == model.intent_category && affected_extruders.length
}
} }
} }

View File

@ -75,7 +75,7 @@ SettingItem
base.setActiveFocusToNextSetting(false) base.setActiveFocusToNextSetting(false)
} }
currentIndex: propertyProvider.properties.value currentIndex: propertyProvider.properties.value !== undefined ? propertyProvider.properties.value : 0
property string color: "#fff" property string color: "#fff"

View File

@ -23,17 +23,16 @@ Item
property alias contents: controlContainer.children property alias contents: controlContainer.children
property alias hovered: mouse.containsMouse property alias hovered: mouse.containsMouse
property var showRevertButton: true property bool showRevertButton: true
property var showInheritButton: true property bool showInheritButton: true
property var showLinkedSettingIcon: true property bool showLinkedSettingIcon: true
property var doDepthIndentation: true property bool doDepthIndentation: true
property var doQualityUserSettingEmphasis: true property bool doQualityUserSettingEmphasis: true
property var settingKey: definition.key //Used to detect each individual setting more easily in Squish GUI tests. property var settingKey: definition.key //Used to detect each individual setting more easily in Squish GUI tests.
// Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise) // Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise)
property var state: propertyProvider.properties.state property var state: propertyProvider.properties.state
// There is no resolve property if there is only one stack. property var resolve: propertyProvider.properties.resolve
property var resolve: Cura.MachineManager.activeStackId !== Cura.MachineManager.activeMachine.id ? propertyProvider.properties.resolve : "None"
property var stackLevels: propertyProvider.stackLevels property var stackLevels: propertyProvider.stackLevels
property var stackLevel: stackLevels[0] property var stackLevel: stackLevels[0]
// A list of stack levels that will trigger to show the revert button // A list of stack levels that will trigger to show the revert button
@ -57,7 +56,8 @@ Item
signal showTooltip(string text) signal showTooltip(string text)
signal hideTooltip() signal hideTooltip()
signal showAllHiddenInheritedSettings(string category_id) signal showAllHiddenInheritedSettings(string category_id)
property string tooltipText:
function createTooltipText()
{ {
var affects = settingDefinitionsModel.getRequiredBy(definition.key, "value") var affects = settingDefinitionsModel.getRequiredBy(definition.key, "value")
var affected_by = settingDefinitionsModel.getRequires(definition.key, "value") var affected_by = settingDefinitionsModel.getRequires(definition.key, "value")
@ -128,7 +128,7 @@ Item
onTriggered: onTriggered:
{ {
base.showTooltip(base.tooltipText) base.showTooltip(base.createTooltipText())
} }
} }
@ -149,7 +149,7 @@ Item
color: UM.Theme.getColor("setting_control_text") color: UM.Theme.getColor("setting_control_text")
opacity: (definition.visible) ? 1 : 0.5 opacity: (definition.visible) ? 1 : 0.5
// emphasize the setting if it has a value in the user or quality profile // emphasize the setting if it has a value in the user or quality profile
font: base.doQualityUserSettingEmphasis && base.stackLevel != undefined && base.stackLevel <= 1 ? UM.Theme.getFont("default_italic") : UM.Theme.getFont("default") font: base.doQualityUserSettingEmphasis && base.stackLevel !== undefined && base.stackLevel <= 1 ? UM.Theme.getFont("default_italic") : UM.Theme.getFont("default")
} }
Row Row
@ -170,10 +170,11 @@ Item
{ {
id: linkedSettingIcon; id: linkedSettingIcon;
visible: Cura.MachineManager.activeStack != Cura.MachineManager.activeMachine && (!definition.settable_per_extruder || String(globalPropertyProvider.properties.limit_to_extruder) != "-1") && base.showLinkedSettingIcon visible: (!definition.settable_per_extruder || String(globalPropertyProvider.properties.limit_to_extruder) != "-1") && base.showLinkedSettingIcon
height: parent.height; anchors.top: parent.top
width: height; anchors.bottom: parent.bottom
width: height
color: UM.Theme.getColor("setting_control_button") color: UM.Theme.getColor("setting_control_button")
hoverColor: UM.Theme.getColor("setting_control_button") hoverColor: UM.Theme.getColor("setting_control_button")
@ -184,14 +185,14 @@ Item
{ {
hoverTimer.stop() hoverTimer.stop()
var tooltipText = catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders.") var tooltipText = catalog.i18nc("@label", "This setting is always shared between all extruders. Changing it here will change the value for all extruders.")
if ((resolve != "None") && (stackLevel != 0)) if ((resolve !== "None") && (stackLevel !== 0))
{ {
// We come here if a setting has a resolve and the setting is not manually edited. // We come here if a setting has a resolve and the setting is not manually edited.
tooltipText += " " + catalog.i18nc("@label", "The value is resolved from per-extruder values ") + "[" + Cura.ExtruderManager.getInstanceExtruderValues(definition.key) + "]." tooltipText += " " + catalog.i18nc("@label", "The value is resolved from per-extruder values ") + "[" + Cura.ExtruderManager.getInstanceExtruderValues(definition.key) + "]."
} }
base.showTooltip(tooltipText) base.showTooltip(tooltipText)
} }
onExited: base.showTooltip(base.tooltipText) onExited: base.showTooltip(base.createTooltipText())
} }
UM.SimpleButton UM.SimpleButton
@ -200,7 +201,8 @@ Item
visible: base.resetButtonVisible visible: base.resetButtonVisible
height: parent.height anchors.top: parent.top
anchors.bottom: parent.bottom
width: height width: height
color: UM.Theme.getColor("setting_control_button") color: UM.Theme.getColor("setting_control_button")
@ -227,7 +229,7 @@ Item
hoverTimer.stop() hoverTimer.stop()
base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile.")) base.showTooltip(catalog.i18nc("@label", "This setting has a value that is different from the profile.\n\nClick to restore the value of the profile."))
} }
onExited: base.showTooltip(base.tooltipText) onExited: base.showTooltip(base.createTooltipText())
} }
UM.SimpleButton UM.SimpleButton
@ -275,10 +277,15 @@ Item
// Observed when loading workspace, probably when SettingItems are removed. // Observed when loading workspace, probably when SettingItems are removed.
return false return false
} }
if(globalPropertyProvider.properties.limit_to_extruder === undefined)
{
return false
}
return Cura.SettingInheritanceManager.getOverridesForExtruder(definition.key, String(globalPropertyProvider.properties.limit_to_extruder)).indexOf(definition.key) >= 0 return Cura.SettingInheritanceManager.getOverridesForExtruder(definition.key, String(globalPropertyProvider.properties.limit_to_extruder)).indexOf(definition.key) >= 0
} }
height: parent.height anchors.top: parent.top
anchors.bottom: parent.bottom
width: height width: height
onClicked: onClicked:
@ -296,7 +303,7 @@ Item
break break
} }
} }
if ((last_entry == 4 || last_entry == 11) && base.stackLevel == 0 && base.stackLevels.length == 2) if ((last_entry === 4 || last_entry === 11) && base.stackLevel === 0 && base.stackLevels.length === 2)
{ {
// Special case of the inherit reset. If only the definition (4th or 11th) container) and the first // Special case of the inherit reset. If only the definition (4th or 11th) container) and the first
// entry (user container) are set, we can simply remove the container. // entry (user container) are set, we can simply remove the container.
@ -320,7 +327,7 @@ Item
iconSource: UM.Theme.getIcon("formula") iconSource: UM.Theme.getIcon("formula")
onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) } onEntered: { hoverTimer.stop(); base.showTooltip(catalog.i18nc("@label", "This setting is normally calculated, but it currently has an absolute value set.\n\nClick to restore the calculated value.")) }
onExited: base.showTooltip(base.tooltipText) onExited: base.showTooltip(base.createTooltipText())
} }
} }

View File

@ -228,7 +228,7 @@ Item
model: UM.SettingDefinitionsModel model: UM.SettingDefinitionsModel
{ {
id: definitionsModel id: definitionsModel
containerId: Cura.MachineManager.activeMachine != null ? Cura.MachineManager.activeMachine.definition.id: "" containerId: Cura.MachineManager.activeMachine !== null ? Cura.MachineManager.activeMachine.definition.id: ""
visibilityHandler: UM.SettingPreferenceVisibilityHandler { } visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
exclude: ["machine_settings", "command_line_settings", "infill_mesh", "infill_mesh_order", "cutting_mesh", "support_mesh", "anti_overhang_mesh"] // TODO: infill_mesh settigns are excluded hardcoded, but should be based on the fact that settable_globally, settable_per_meshgroup and settable_per_extruder are false. exclude: ["machine_settings", "command_line_settings", "infill_mesh", "infill_mesh_order", "cutting_mesh", "support_mesh", "anti_overhang_mesh"] // TODO: infill_mesh settigns are excluded hardcoded, but should be based on the fact that settable_globally, settable_per_meshgroup and settable_per_extruder are false.
expanded: CuraApplication.expandedCategories expanded: CuraApplication.expandedCategories
@ -241,43 +241,41 @@ Item
CuraApplication.setExpandedCategories(expanded) CuraApplication.setExpandedCategories(expanded)
} }
} }
onVisibilityChanged: Cura.SettingInheritanceManager.forceUpdate() onVisibilityChanged: Cura.SettingInheritanceManager.scheduleUpdate()
} }
property var indexWithFocus: -1 property int indexWithFocus: -1
property string activeMachineId: Cura.MachineManager.activeMachine !== null ? Cura.MachineManager.activeMachine.id : ""
delegate: Loader delegate: Loader
{ {
id: delegate id: delegate
width: scrollView.width width: scrollView.width
height: provider.properties.enabled == "True" ? UM.Theme.getSize("section").height : - contents.spacing height: provider.properties.enabled === "True" ? UM.Theme.getSize("section").height : - contents.spacing
Behavior on height { NumberAnimation { duration: 100 } } Behavior on height { NumberAnimation { duration: 100 } }
opacity: provider.properties.enabled == "True" ? 1 : 0 opacity: provider.properties.enabled === "True" ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } } Behavior on opacity { NumberAnimation { duration: 100 } }
enabled: enabled:
{ {
if (!Cura.ExtruderManager.activeExtruderStackId && machineExtruderCount.properties.value > 1) if (!Cura.ExtruderManager.activeExtruderStackId && machineExtruderCount.properties.value > 1)
{ {
// disable all controls on the global tab, except categories // disable all controls on the global tab, except categories
return model.type == "category" return model.type === "category"
} }
return provider.properties.enabled == "True" return provider.properties.enabled === "True"
} }
property var definition: model property var definition: model
property var settingDefinitionsModel: definitionsModel property var settingDefinitionsModel: definitionsModel
property var propertyProvider: provider property var propertyProvider: provider
property var globalPropertyProvider: inheritStackProvider property var globalPropertyProvider: inheritStackProvider
property var externalResetHandler: false property bool externalResetHandler: false
property string activeMachineId: Cura.MachineManager.activeMachine !== null ? Cura.MachineManager.activeMachine.id : ""
//Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989 //Qt5.4.2 and earlier has a bug where this causes a crash: https://bugreports.qt.io/browse/QTBUG-35989
//In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes, //In addition, while it works for 5.5 and higher, the ordering of the actual combo box drop down changes,
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely. //causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
asynchronous: model.type != "enum" && model.type != "extruder" && model.type != "optional_extruder" asynchronous: model.type !== "enum" && model.type !== "extruder" && model.type !== "optional_extruder"
active: model.type != undefined active: model.type !== undefined
source: source:
{ {
@ -313,7 +311,7 @@ Item
{ {
target: provider target: provider
property: "containerStackId" property: "containerStackId"
when: model.settable_per_extruder || (inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0); when: model.settable_per_extruder || (inheritStackProvider.properties.limit_to_extruder !== null && inheritStackProvider.properties.limit_to_extruder >= 0);
value: value:
{ {
// Associate this binding with Cura.MachineManager.activeMachine.id in the beginning so this // Associate this binding with Cura.MachineManager.activeMachine.id in the beginning so this
@ -324,9 +322,9 @@ Item
if (!model.settable_per_extruder) if (!model.settable_per_extruder)
{ {
//Not settable per extruder or there only is global, so we must pick global. //Not settable per extruder or there only is global, so we must pick global.
return delegate.activeMachineId return contents.activeMachineId
} }
if (inheritStackProvider.properties.limit_to_extruder != null && inheritStackProvider.properties.limit_to_extruder >= 0) if (inheritStackProvider.properties.limit_to_extruder !== null && inheritStackProvider.properties.limit_to_extruder >= 0)
{ {
//We have limit_to_extruder, so pick that stack. //We have limit_to_extruder, so pick that stack.
return Cura.ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)]; return Cura.ExtruderManager.extruderIds[String(inheritStackProvider.properties.limit_to_extruder)];
@ -337,7 +335,7 @@ Item
return Cura.ExtruderManager.activeExtruderStackId; return Cura.ExtruderManager.activeExtruderStackId;
} }
//No extruder tab is selected. Pick the global stack. Shouldn't happen any more since we removed the global tab. //No extruder tab is selected. Pick the global stack. Shouldn't happen any more since we removed the global tab.
return delegate.activeMachineId return contents.activeMachineId
} }
} }
@ -346,7 +344,7 @@ Item
UM.SettingPropertyProvider UM.SettingPropertyProvider
{ {
id: inheritStackProvider id: inheritStackProvider
containerStackId: Cura.MachineManager.activeMachine !== null ? Cura.MachineManager.activeMachine.id: "" containerStackId: contents.activeMachineId
key: model.key key: model.key
watchedProperties: [ "limit_to_extruder" ] watchedProperties: [ "limit_to_extruder" ]
} }
@ -355,11 +353,11 @@ Item
{ {
id: provider id: provider
containerStackId: delegate.activeMachineId containerStackId: contents.activeMachineId
key: model.key ? model.key : "" key: model.key ? model.key : ""
watchedProperties: [ "value", "enabled", "state", "validationState", "settable_per_extruder", "resolve" ] watchedProperties: [ "value", "enabled", "state", "validationState", "settable_per_extruder", "resolve" ]
storeIndex: 0 storeIndex: 0
removeUnusedValue: model.resolve == undefined removeUnusedValue: model.resolve === undefined
} }
Connections Connections
@ -421,8 +419,6 @@ Item
} }
} }
UM.I18nCatalog { id: catalog; name: "cura"; }
NumberAnimation { NumberAnimation {
id: animateContentY id: animateContentY
target: contents target: contents
@ -465,7 +461,7 @@ Item
//: Settings context menu action //: Settings context menu action
text: catalog.i18nc("@action:menu", "Copy value to all extruders") text: catalog.i18nc("@action:menu", "Copy value to all extruders")
visible: machineExtruderCount.properties.value > 1 visible: machineExtruderCount.properties.value > 1
enabled: contextMenu.provider != undefined && contextMenu.provider.properties.settable_per_extruder != "False" enabled: contextMenu.provider !== undefined && contextMenu.provider.properties.settable_per_extruder !== "False"
onTriggered: Cura.MachineManager.copyValueToExtruders(contextMenu.key) onTriggered: Cura.MachineManager.copyValueToExtruders(contextMenu.key)
} }
@ -474,7 +470,7 @@ Item
//: Settings context menu action //: Settings context menu action
text: catalog.i18nc("@action:menu", "Copy all changed values to all extruders") text: catalog.i18nc("@action:menu", "Copy all changed values to all extruders")
visible: machineExtruderCount.properties.value > 1 visible: machineExtruderCount.properties.value > 1
enabled: contextMenu.provider != undefined enabled: contextMenu.provider !== undefined
onTriggered: Cura.MachineManager.copyAllValuesToExtruders() onTriggered: Cura.MachineManager.copyAllValuesToExtruders()
} }

View File

@ -8,21 +8,20 @@ setting_version = 10
type = quality type = quality
quality_type = a quality_type = a
weight = 1 weight = 1
material = generic_abs material = emotiontech_abs
variant = Standard 0.4 variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.5*machine_nozzle_size, 2) layer_height_0 = =round(0.5*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.5
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 55 speed_print = 50
speed_wall = =math.ceil(speed_print * 40/55) speed_wall = =math.ceil(speed_print * 35/50)
speed_wall_0 = =math.ceil(speed_wall * 30/40) speed_wall_0 = =math.ceil(speed_wall * 30/35)
speed_topbottom = =math.ceil(speed_print * 35/55) speed_topbottom = =math.ceil(speed_print * 35/50)
speed_layer_0 = =math.ceil(speed_print * 20/55) speed_layer_0 = =math.ceil(speed_print * 20/50)
speed_slowdown_layers = 2 speed_slowdown_layers = 2
cool_fan_enabled = True cool_fan_enabled = True
cool_fan_speed = 35 cool_fan_speed = 35

View File

@ -8,21 +8,20 @@ setting_version = 10
type = quality type = quality
quality_type = b quality_type = b
weight = 0 weight = 0
material = generic_abs material = emotiontech_abs
variant = Standard 0.4 variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.67*machine_nozzle_size, 2) layer_height_0 = =round(0.67*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.5
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 60 speed_print = 55
speed_wall = =math.ceil(speed_print * 43/60) speed_wall = =math.ceil(speed_print * 37/55)
speed_wall_0 = =math.ceil(speed_wall * 33/43) speed_wall_0 = =math.ceil(speed_wall * 33/37)
speed_topbottom = =math.ceil(speed_print * 37/60) speed_topbottom = =math.ceil(speed_print * 37/55)
speed_layer_0 = =math.ceil(speed_print * 25/60) speed_layer_0 = =math.ceil(speed_print * 25/55)
speed_slowdown_layers = 2 speed_slowdown_layers = 2
cool_fan_enabled = True cool_fan_enabled = True
cool_fan_speed = 35 cool_fan_speed = 35

View File

@ -8,21 +8,20 @@ setting_version = 10
type = quality type = quality
quality_type = c quality_type = c
weight = -1 weight = -1
material = generic_abs material = emotiontech_abs
variant = Standard 0.4 variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.75*machine_nozzle_size, 2) layer_height_0 = =round(0.75*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.5
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 65 speed_print = 60
speed_wall = =math.ceil(speed_print * 45/65) speed_wall = =math.ceil(speed_print * 40/60)
speed_wall_0 = =math.ceil(speed_wall * 35/45) speed_wall_0 = =math.ceil(speed_wall * 35/40)
speed_topbottom = =math.ceil(speed_print * 40/65) speed_topbottom = =math.ceil(speed_print * 40/60)
speed_layer_0 = =math.ceil(speed_print * 30/65) speed_layer_0 = =math.ceil(speed_print * 30/60)
speed_slowdown_layers = 2 speed_slowdown_layers = 2
cool_fan_enabled = True cool_fan_enabled = True
cool_fan_speed = 35 cool_fan_speed = 35

View File

@ -8,21 +8,20 @@ setting_version = 10
type = quality type = quality
quality_type = a quality_type = a
weight = 1 weight = 1
material = generic_petg material = emotiontech_petg
variant = Standard 0.4 variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.5*machine_nozzle_size, 2) layer_height_0 = =round(0.5*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.4
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 55 speed_print = 50
speed_wall = =math.ceil(speed_print * 40/55) speed_wall = =math.ceil(speed_print * 35/50)
speed_wall_0 = =math.ceil(speed_wall * 25/40) speed_wall_0 = =math.ceil(speed_wall * 30/35)
speed_topbottom = =math.ceil(speed_print * 35/55) speed_topbottom = =math.ceil(speed_print * 35/50)
speed_layer_0 = =math.ceil(speed_print * 20/55) speed_layer_0 = =math.ceil(speed_print * 20/50)
speed_slowdown_layers = 2 speed_slowdown_layers = 2
cool_fan_enabled = True cool_fan_enabled = True
cool_fan_speed = 50 cool_fan_speed = 50

View File

@ -8,21 +8,20 @@ setting_version = 10
type = quality type = quality
quality_type = b quality_type = b
weight = 0 weight = 0
material = generic_petg material = emotiontech_petg
variant = Standard 0.4 variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.67*machine_nozzle_size, 2) layer_height_0 = =round(0.67*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.4
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 60 speed_print = 55
speed_wall = =math.ceil(speed_print * 43/60) speed_wall = =math.ceil(speed_print * 37/55)
speed_wall_0 = =math.ceil(speed_wall * 27/43) speed_wall_0 = =math.ceil(speed_wall * 33/37)
speed_topbottom = =math.ceil(speed_print * 37/60) speed_topbottom = =math.ceil(speed_print * 37/55)
speed_layer_0 = =math.ceil(speed_print * 25/60) speed_layer_0 = =math.ceil(speed_print * 25/55)
speed_slowdown_layers = 2 speed_slowdown_layers = 2
cool_fan_enabled = True cool_fan_enabled = True
cool_fan_speed = 50 cool_fan_speed = 50

View File

@ -8,21 +8,20 @@ setting_version = 10
type = quality type = quality
quality_type = c quality_type = c
weight = -1 weight = -1
material = generic_petg material = emotiontech_petg
variant = Standard 0.4 variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.75*machine_nozzle_size, 2) layer_height_0 = =round(0.75*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.4
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 65 speed_print = 60
speed_wall = =math.ceil(speed_print * 45/65) speed_wall = =math.ceil(speed_print * 40/60)
speed_wall_0 = =math.ceil(speed_wall * 30/45) speed_wall_0 = =math.ceil(speed_wall * 35/40)
speed_topbottom = =math.ceil(speed_print * 40/65) speed_topbottom = =math.ceil(speed_print * 40/60)
speed_layer_0 = =math.ceil(speed_print * 30/65) speed_layer_0 = =math.ceil(speed_print * 30/60)
speed_slowdown_layers = 2 speed_slowdown_layers = 2
cool_fan_enabled = True cool_fan_enabled = True
cool_fan_speed = 50 cool_fan_speed = 50

View File

@ -8,21 +8,20 @@ setting_version = 10
type = quality type = quality
quality_type = a quality_type = a
weight = 1 weight = 1
material = generic_pla material = emotiontech_pla
variant = Standard 0.4 variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.5*machine_nozzle_size, 2) layer_height_0 = =round(0.5*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.43
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 55 speed_print = 50
speed_wall = =math.ceil(speed_print * 40/55) speed_wall = =math.ceil(speed_print * 35/50)
speed_wall_0 = =math.ceil(speed_wall * 30/40) speed_wall_0 = =math.ceil(speed_wall * 30/35)
speed_topbottom = =math.ceil(speed_print * 35/55) speed_topbottom = =math.ceil(speed_print * 35/50)
speed_layer_0 = =math.ceil(speed_print * 20/55) speed_layer_0 = =math.ceil(speed_print * 20/50)
speed_slowdown_layers = 2 speed_slowdown_layers = 2
cool_fan_enabled = True cool_fan_enabled = True
cool_fan_speed = 100 cool_fan_speed = 100

View File

@ -8,21 +8,20 @@ setting_version = 10
type = quality type = quality
quality_type = b quality_type = b
weight = 0 weight = 0
material = generic_pla material = emotiontech_pla
variant = Standard 0.4 variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.67*machine_nozzle_size, 2) layer_height_0 = =round(0.67*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.43
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 60 speed_print = 55
speed_wall = =math.ceil(speed_print * 43/60) speed_wall = =math.ceil(speed_print * 37/55)
speed_wall_0 = =math.ceil(speed_wall * 33/43) speed_wall_0 = =math.ceil(speed_wall * 33/37)
speed_topbottom = =math.ceil(speed_print * 37/60) speed_topbottom = =math.ceil(speed_print * 37/55)
speed_layer_0 = =math.ceil(speed_print * 25/60) speed_layer_0 = =math.ceil(speed_print * 25/55)
speed_slowdown_layers = 2 speed_slowdown_layers = 2
cool_fan_enabled = True cool_fan_enabled = True
cool_fan_speed = 100 cool_fan_speed = 100

View File

@ -8,21 +8,20 @@ setting_version = 10
type = quality type = quality
quality_type = c quality_type = c
weight = -1 weight = -1
material = generic_pla material = emotiontech_pla
variant = Standard 0.4 variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.75*machine_nozzle_size, 2) layer_height_0 = =round(0.75*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.43
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.35
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 65 speed_print = 60
speed_wall = =math.ceil(speed_print * 45/65) speed_wall = =math.ceil(speed_print * 40/60)
speed_wall_0 = =math.ceil(speed_wall * 35/45) speed_wall_0 = =math.ceil(speed_wall * 35/40)
speed_topbottom = =math.ceil(speed_print * 40/65) speed_topbottom = =math.ceil(speed_print * 40/60)
speed_layer_0 = =math.ceil(speed_print * 30/65) speed_layer_0 = =math.ceil(speed_print * 30/60)
speed_slowdown_layers = 2 speed_slowdown_layers = 2
cool_fan_enabled = True cool_fan_enabled = True
cool_fan_speed = 100 cool_fan_speed = 100

View File

@ -13,10 +13,9 @@ variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.5*machine_nozzle_size, 2) layer_height_0 = =round(0.5*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.4
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.4 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.4
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 40 speed_print = 40
speed_wall = =math.ceil(speed_print * 30/40) speed_wall = =math.ceil(speed_print * 30/40)

View File

@ -13,10 +13,9 @@ variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.67*machine_nozzle_size, 2) layer_height_0 = =round(0.67*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.4
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.4 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.4
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 40 speed_print = 40
speed_wall = =math.ceil(speed_print * 30/40) speed_wall = =math.ceil(speed_print * 30/40)
@ -42,7 +41,7 @@ skin_overlap = 15
support_z_distance = =layer_height-layer_height support_z_distance = =layer_height-layer_height
support_bottom_distance = =support_z_distance support_bottom_distance = =support_z_distance
support_xy_distance = =line_width*3/4 support_xy_distance = =line_width*3/4
support_xy_distance_overhang = ==line_width*0.175/line_width support_xy_distance_overhang = =line_width*0.175/line_width
support_offset = 3 support_offset = 3
support_pattern = grid support_pattern = grid
support_interface_density = 100 support_interface_density = 100

View File

@ -13,10 +13,9 @@ variant = Standard 0.4
[values] [values]
layer_height_0 = =round(0.75*machine_nozzle_size, 2) layer_height_0 = =round(0.75*machine_nozzle_size, 2)
line_width = =machine_nozzle_size/machine_nozzle_size*0.35 line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.3 wall_line_width = =machine_nozzle_size/machine_nozzle_size*0.4
infill_line_width = =machine_nozzle_size/machine_nozzle_size*0.4 wall_line_width_x = =machine_nozzle_size/machine_nozzle_size*0.4
support_line_width = =machine_nozzle_size/machine_nozzle_size*0.4
wall_0_wipe_dist = =machine_nozzle_size/2 wall_0_wipe_dist = =machine_nozzle_size/2
speed_print = 40 speed_print = 40
speed_wall = =math.ceil(speed_print * 30/40) speed_wall = =math.ceil(speed_print * 30/40)

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