mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-16 13:25:53 +08:00
Merge branch 'master' into feature_preheat_extruder
# Conflicts: # plugins/USBPrinting/USBPrinterOutputController.py # plugins/USBPrinting/USBPrinterOutputDevice.py
This commit is contained in:
commit
ed9943c732
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -1,5 +1,5 @@
|
|||||||
timeout(time: 2, unit: "HOURS") {
|
|
||||||
parallel_nodes(['linux && cura', 'windows && cura']) {
|
parallel_nodes(['linux && cura', 'windows && cura']) {
|
||||||
|
timeout(time: 2, unit: "HOURS") {
|
||||||
// Prepare building
|
// Prepare building
|
||||||
stage('Prepare') {
|
stage('Prepare') {
|
||||||
// Ensure we start with a clean build directory.
|
// Ensure we start with a clean build directory.
|
||||||
|
20
README.md
20
README.md
@ -41,25 +41,7 @@ Please check out [Wiki page](https://github.com/Ultimaker/Cura/wiki/Cura-Setting
|
|||||||
|
|
||||||
Translating Cura
|
Translating Cura
|
||||||
----------------
|
----------------
|
||||||
If you'd like to contribute a translation of Cura, please first look for [any existing translation](https://github.com/Ultimaker/Cura/tree/master/resources/i18n). If your language is already there in the source code but not in Cura's interface, it may be partially translated.
|
Please check out [Wiki page](https://github.com/Ultimaker/Cura/wiki/Translating-Cura) about how to translate Cura into other languages.
|
||||||
|
|
||||||
There are four files that need to be translated for Cura:
|
|
||||||
1. https://github.com/Ultimaker/Cura/blob/master/resources/i18n/cura.pot
|
|
||||||
2. https://github.com/Ultimaker/Cura/blob/master/resources/i18n/fdmextruder.def.json.pot
|
|
||||||
3. https://github.com/Ultimaker/Cura/blob/master/resources/i18n/fdmprinter.def.json.pot (This one is the most work.)
|
|
||||||
4. https://github.com/Ultimaker/Uranium/blob/master/resources/i18n/uranium.pot
|
|
||||||
|
|
||||||
Copy these files and rename them to `*.po` (remove the `t`). Then create the actual translations by filling in the empty `msgstr` entries. These are gettext files, which are plain text so you can open them with any text editor such as Notepad or GEdit, but it is probably easier with a specialised tool such as [POEdit](https://poedit.net/) or [Virtaal](http://virtaal.translatehouse.org/).
|
|
||||||
|
|
||||||
Do not hestiate to ask us about a translation or the meaning of some text via Github Issues.
|
|
||||||
|
|
||||||
Once the translation is complete, it's probably best to test them in Cura. Use your favourite software to convert the .po file to a .mo file (such as [GetText](https://www.gnu.org/software/gettext/)). Then put the .mo files in the `.../resources/i18n/<language code>/LC_MESSAGES` folder in your Cura installation. Then find your Cura configuration file (next to the log as described above, except on Linux where it is located in `~/.config/cura`) and change the language preference to the name of the folder you just created. Then start Cura. If working correctly, your Cura should now be translated.
|
|
||||||
|
|
||||||
To submit your translation, ideally you would make two pull requests where all `*.po` files are located in that same `<language code>` folder in the resources of both the Cura and Uranium repositories. Put `cura.po`, `fdmprinter.def.json.po` and `fdmextruder.def.json.po` in the Cura repository, and put `uranium.po` in the Uranium repository. Then submit the pull requests to Github. For people with less experience with Git, you can also e-mail the translations to the e-mail address listed at the top of the [cura.pot](https://github.com/Ultimaker/Cura/blob/master/resources/i18n/cura.pot) file as the `Report-Msgid-Bugs-To` entry and we'll make sure it gets checked and included.
|
|
||||||
|
|
||||||
After the translation is submitted, the Cura maintainers will check for its completeness and check whether it is consistent. We will take special care to look for common mistakes, such as translating mark-up `<message>` code and such. We are often not fluent in every language, so we expect the translator and the international users to make corrections where necessary. Of course, there will always be some mistakes in every translation.
|
|
||||||
|
|
||||||
When the next Cura release comes around, some of the texts will have changed and some new texts will have been added. Around the time when the beta is released we will invoke a string freeze, meaning that no developer is allowed to make changes to the texts. Then we will update the translation template `.pot` files and ask all our translators to update their translations. If you are unable to update the translation in time for the actual release, we will remove the language from the drop-down menu in the Preferences window. The translation stays in Cura however, so that someone might pick it up again later and update it with the newest texts. Also, users who had previously selected the language can still continue Cura in their language but English text will appear among the original text.
|
|
||||||
|
|
||||||
License
|
License
|
||||||
----------------
|
----------------
|
||||||
|
@ -88,3 +88,5 @@ class ArrangeObjectsJob(Job):
|
|||||||
no_full_solution_message = Message(i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects"),
|
no_full_solution_message = Message(i18n_catalog.i18nc("@info:status", "Unable to find a location within the build volume for all objects"),
|
||||||
title = i18n_catalog.i18nc("@info:title", "Can't Find Location"))
|
title = i18n_catalog.i18nc("@info:title", "Can't Find Location"))
|
||||||
no_full_solution_message.show()
|
no_full_solution_message.show()
|
||||||
|
|
||||||
|
self.finished.emit(self)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 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 cura.Scene.CuraSceneNode import CuraSceneNode
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
@ -25,7 +26,7 @@ catalog = i18nCatalog("cura")
|
|||||||
import numpy
|
import numpy
|
||||||
import math
|
import math
|
||||||
|
|
||||||
from typing import List
|
from typing import List, Optional
|
||||||
|
|
||||||
# Setting for clearance around the prime
|
# Setting for clearance around the prime
|
||||||
PRIME_CLEARANCE = 6.5
|
PRIME_CLEARANCE = 6.5
|
||||||
@ -241,6 +242,44 @@ class BuildVolume(SceneNode):
|
|||||||
for child_node in group_node.getAllChildren():
|
for child_node in group_node.getAllChildren():
|
||||||
child_node._outside_buildarea = group_node._outside_buildarea
|
child_node._outside_buildarea = group_node._outside_buildarea
|
||||||
|
|
||||||
|
## Update the outsideBuildArea of a single node, given bounds or current build volume
|
||||||
|
def checkBoundsAndUpdate(self, node: CuraSceneNode, bounds: Optional[AxisAlignedBox] = None):
|
||||||
|
if not isinstance(node, CuraSceneNode):
|
||||||
|
return
|
||||||
|
|
||||||
|
if bounds is None:
|
||||||
|
build_volume_bounding_box = self.getBoundingBox()
|
||||||
|
if build_volume_bounding_box:
|
||||||
|
# It's over 9000!
|
||||||
|
build_volume_bounding_box = build_volume_bounding_box.set(bottom=-9001)
|
||||||
|
else:
|
||||||
|
# No bounding box. This is triggered when running Cura from command line with a model for the first time
|
||||||
|
# In that situation there is a model, but no machine (and therefore no build volume.
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
build_volume_bounding_box = bounds
|
||||||
|
|
||||||
|
if node.callDecoration("isSliceable") or node.callDecoration("isGroup"):
|
||||||
|
bbox = node.getBoundingBox()
|
||||||
|
|
||||||
|
# Mark the node as outside the build volume if the bounding box test fails.
|
||||||
|
if build_volume_bounding_box.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection:
|
||||||
|
node.setOutsideBuildArea(True)
|
||||||
|
return
|
||||||
|
|
||||||
|
convex_hull = self.callDecoration("getConvexHull")
|
||||||
|
if convex_hull:
|
||||||
|
if not convex_hull.isValid():
|
||||||
|
return
|
||||||
|
# Check for collisions between disallowed areas and the object
|
||||||
|
for area in self.getDisallowedAreas():
|
||||||
|
overlap = convex_hull.intersectsPolygon(area)
|
||||||
|
if overlap is None:
|
||||||
|
continue
|
||||||
|
node.setOutsideBuildArea(True)
|
||||||
|
return
|
||||||
|
node.setOutsideBuildArea(False)
|
||||||
|
|
||||||
## Recalculates the build volume & disallowed areas.
|
## Recalculates the build volume & disallowed areas.
|
||||||
def rebuild(self):
|
def rebuild(self):
|
||||||
if not self._width or not self._height or not self._depth:
|
if not self._width or not self._height or not self._depth:
|
||||||
|
@ -94,6 +94,10 @@ class CuraActions(QObject):
|
|||||||
removed_group_nodes.append(group_node)
|
removed_group_nodes.append(group_node)
|
||||||
op.addOperation(SetParentOperation(remaining_nodes_in_group[0], group_node.getParent()))
|
op.addOperation(SetParentOperation(remaining_nodes_in_group[0], group_node.getParent()))
|
||||||
op.addOperation(RemoveSceneNodeOperation(group_node))
|
op.addOperation(RemoveSceneNodeOperation(group_node))
|
||||||
|
|
||||||
|
# Reset the print information
|
||||||
|
Application.getInstance().getController().getScene().sceneChanged.emit(node)
|
||||||
|
|
||||||
op.push()
|
op.push()
|
||||||
|
|
||||||
## Set the extruder that should be used to print the selection.
|
## Set the extruder that should be used to print the selection.
|
||||||
|
@ -142,6 +142,7 @@ class CuraApplication(QtApplication):
|
|||||||
if not hasattr(sys, "frozen"):
|
if not hasattr(sys, "frozen"):
|
||||||
Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "resources"))
|
Resources.addSearchPath(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "resources"))
|
||||||
|
|
||||||
|
self._use_gui = True
|
||||||
self._open_file_queue = [] # Files to open when plug-ins are loaded.
|
self._open_file_queue = [] # Files to open when plug-ins are loaded.
|
||||||
|
|
||||||
# Need to do this before ContainerRegistry tries to load the machines
|
# Need to do this before ContainerRegistry tries to load the machines
|
||||||
@ -278,6 +279,11 @@ class CuraApplication(QtApplication):
|
|||||||
# We need them to simplify the switching between materials.
|
# We need them to simplify the switching between materials.
|
||||||
empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
|
empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
|
||||||
|
|
||||||
|
empty_definition_changes_container = copy.deepcopy(empty_container)
|
||||||
|
empty_definition_changes_container.setMetaDataEntry("id", "empty_definition_changes")
|
||||||
|
empty_definition_changes_container.addMetaDataEntry("type", "definition_changes")
|
||||||
|
ContainerRegistry.getInstance().addContainer(empty_definition_changes_container)
|
||||||
|
|
||||||
empty_variant_container = copy.deepcopy(empty_container)
|
empty_variant_container = copy.deepcopy(empty_container)
|
||||||
empty_variant_container.setMetaDataEntry("id", "empty_variant")
|
empty_variant_container.setMetaDataEntry("id", "empty_variant")
|
||||||
empty_variant_container.addMetaDataEntry("type", "variant")
|
empty_variant_container.addMetaDataEntry("type", "variant")
|
||||||
@ -452,7 +458,7 @@ class CuraApplication(QtApplication):
|
|||||||
elif choice == "always_keep":
|
elif choice == "always_keep":
|
||||||
# don't show dialog and KEEP the profile
|
# don't show dialog and KEEP the profile
|
||||||
self.discardOrKeepProfileChangesClosed("keep")
|
self.discardOrKeepProfileChangesClosed("keep")
|
||||||
else:
|
elif self._use_gui:
|
||||||
# ALWAYS ask whether to keep or discard the profile
|
# ALWAYS ask whether to keep or discard the profile
|
||||||
self.showDiscardOrKeepProfileChanges.emit()
|
self.showDiscardOrKeepProfileChanges.emit()
|
||||||
has_user_interaction = True
|
has_user_interaction = True
|
||||||
@ -652,12 +658,47 @@ class CuraApplication(QtApplication):
|
|||||||
def run(self):
|
def run(self):
|
||||||
self.preRun()
|
self.preRun()
|
||||||
|
|
||||||
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up scene..."))
|
# Check if we should run as single instance or not
|
||||||
|
|
||||||
self._setUpSingleInstanceServer()
|
self._setUpSingleInstanceServer()
|
||||||
|
|
||||||
|
# Setup scene and build volume
|
||||||
|
root = self.getController().getScene().getRoot()
|
||||||
|
self._volume = BuildVolume.BuildVolume(self.getController().getScene().getRoot())
|
||||||
|
Arrange.build_volume = self._volume
|
||||||
|
|
||||||
|
# initialize info objects
|
||||||
|
self._print_information = PrintInformation.PrintInformation()
|
||||||
|
self._cura_actions = CuraActions.CuraActions(self)
|
||||||
|
|
||||||
|
# Detect in which mode to run and execute that mode
|
||||||
|
if self.getCommandLineOption("headless", False):
|
||||||
|
self.runWithoutGUI()
|
||||||
|
else:
|
||||||
|
self.runWithGUI()
|
||||||
|
|
||||||
|
# Pre-load files if requested
|
||||||
|
for file_name in self.getCommandLineOption("file", []):
|
||||||
|
self._openFile(file_name)
|
||||||
|
for file_name in self._open_file_queue: # Open all the files that were queued up while plug-ins were loading.
|
||||||
|
self._openFile(file_name)
|
||||||
|
|
||||||
|
self._started = True
|
||||||
|
self.exec_()
|
||||||
|
|
||||||
|
## Run Cura without GUI elements and interaction (server mode).
|
||||||
|
def runWithoutGUI(self):
|
||||||
|
self._use_gui = False
|
||||||
|
self.closeSplash()
|
||||||
|
|
||||||
|
## Run Cura with GUI (desktop mode).
|
||||||
|
def runWithGUI(self):
|
||||||
|
self._use_gui = True
|
||||||
|
|
||||||
|
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Setting up scene..."))
|
||||||
|
|
||||||
controller = self.getController()
|
controller = self.getController()
|
||||||
|
|
||||||
|
# Initialize UI state
|
||||||
controller.setActiveStage("PrepareStage")
|
controller.setActiveStage("PrepareStage")
|
||||||
controller.setActiveView("SolidView")
|
controller.setActiveView("SolidView")
|
||||||
controller.setCameraTool("CameraTool")
|
controller.setCameraTool("CameraTool")
|
||||||
@ -669,67 +710,44 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
Selection.selectionChanged.connect(self.onSelectionChanged)
|
Selection.selectionChanged.connect(self.onSelectionChanged)
|
||||||
|
|
||||||
root = controller.getScene().getRoot()
|
# Set default background color for scene
|
||||||
|
|
||||||
# The platform is a child of BuildVolume
|
|
||||||
self._volume = BuildVolume.BuildVolume(root)
|
|
||||||
|
|
||||||
# Set the build volume of the arranger to the used build volume
|
|
||||||
Arrange.build_volume = self._volume
|
|
||||||
|
|
||||||
self.getRenderer().setBackgroundColor(QColor(245, 245, 245))
|
self.getRenderer().setBackgroundColor(QColor(245, 245, 245))
|
||||||
|
|
||||||
|
# Initialize platform physics
|
||||||
self._physics = PlatformPhysics.PlatformPhysics(controller, self._volume)
|
self._physics = PlatformPhysics.PlatformPhysics(controller, self._volume)
|
||||||
|
|
||||||
|
# Initialize camera
|
||||||
|
root = controller.getScene().getRoot()
|
||||||
camera = Camera("3d", root)
|
camera = Camera("3d", root)
|
||||||
camera.setPosition(Vector(-80, 250, 700))
|
camera.setPosition(Vector(-80, 250, 700))
|
||||||
camera.setPerspective(True)
|
camera.setPerspective(True)
|
||||||
camera.lookAt(Vector(0, 0, 0))
|
camera.lookAt(Vector(0, 0, 0))
|
||||||
controller.getScene().setActiveCamera("3d")
|
controller.getScene().setActiveCamera("3d")
|
||||||
|
|
||||||
camera_tool = self.getController().getTool("CameraTool")
|
# Initialize camera tool
|
||||||
|
camera_tool = controller.getTool("CameraTool")
|
||||||
camera_tool.setOrigin(Vector(0, 100, 0))
|
camera_tool.setOrigin(Vector(0, 100, 0))
|
||||||
camera_tool.setZoomRange(0.1, 200000)
|
camera_tool.setZoomRange(0.1, 200000)
|
||||||
|
|
||||||
|
# Initialize camera animations
|
||||||
self._camera_animation = CameraAnimation.CameraAnimation()
|
self._camera_animation = CameraAnimation.CameraAnimation()
|
||||||
self._camera_animation.setCameraTool(self.getController().getTool("CameraTool"))
|
self._camera_animation.setCameraTool(self.getController().getTool("CameraTool"))
|
||||||
|
|
||||||
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface..."))
|
self.showSplashMessage(self._i18n_catalog.i18nc("@info:progress", "Loading interface..."))
|
||||||
|
|
||||||
qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, "ExtruderManager", self.getExtruderManager)
|
# Initialize QML engine
|
||||||
qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager)
|
|
||||||
qmlRegisterSingletonType(MaterialManager, "Cura", 1, 0, "MaterialManager", self.getMaterialManager)
|
|
||||||
|
|
||||||
qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager",
|
|
||||||
self.getSettingInheritanceManager)
|
|
||||||
qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 2, "SimpleModeSettingsManager",
|
|
||||||
self.getSimpleModeSettingsManager)
|
|
||||||
|
|
||||||
qmlRegisterSingletonType(ObjectsModel, "Cura", 1, 2, "ObjectsModel", self.getObjectsModel)
|
|
||||||
qmlRegisterSingletonType(BuildPlateModel, "Cura", 1, 2, "BuildPlateModel", self.getBuildPlateModel)
|
|
||||||
qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 2, "SceneController", self.getCuraSceneController)
|
|
||||||
|
|
||||||
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
|
|
||||||
|
|
||||||
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
|
self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml"))
|
||||||
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles))
|
||||||
|
|
||||||
run_without_gui = self.getCommandLineOption("headless", False)
|
|
||||||
if not run_without_gui:
|
|
||||||
self.initializeEngine()
|
self.initializeEngine()
|
||||||
|
|
||||||
|
# Make sure the correct stage is activated after QML is loaded
|
||||||
controller.setActiveStage("PrepareStage")
|
controller.setActiveStage("PrepareStage")
|
||||||
|
|
||||||
if run_without_gui or self._engine.rootObjects:
|
# Hide the splash screen
|
||||||
self.closeSplash()
|
self.closeSplash()
|
||||||
|
|
||||||
for file_name in self.getCommandLineOption("file", []):
|
def hasGui(self):
|
||||||
self._openFile(file_name)
|
return self._use_gui
|
||||||
for file_name in self._open_file_queue: #Open all the files that were queued up while plug-ins were loading.
|
|
||||||
self._openFile(file_name)
|
|
||||||
|
|
||||||
self._started = True
|
|
||||||
|
|
||||||
self.exec_()
|
|
||||||
|
|
||||||
def getMachineManager(self, *args) -> MachineManager:
|
def getMachineManager(self, *args) -> MachineManager:
|
||||||
if self._machine_manager is None:
|
if self._machine_manager is None:
|
||||||
@ -797,15 +815,25 @@ class CuraApplication(QtApplication):
|
|||||||
# \param engine The QML engine.
|
# \param engine The QML engine.
|
||||||
def registerObjects(self, engine):
|
def registerObjects(self, engine):
|
||||||
super().registerObjects(engine)
|
super().registerObjects(engine)
|
||||||
|
|
||||||
|
# global contexts
|
||||||
engine.rootContext().setContextProperty("Printer", self)
|
engine.rootContext().setContextProperty("Printer", self)
|
||||||
engine.rootContext().setContextProperty("CuraApplication", self)
|
engine.rootContext().setContextProperty("CuraApplication", self)
|
||||||
self._print_information = PrintInformation.PrintInformation()
|
|
||||||
engine.rootContext().setContextProperty("PrintInformation", self._print_information)
|
engine.rootContext().setContextProperty("PrintInformation", self._print_information)
|
||||||
self._cura_actions = CuraActions.CuraActions(self)
|
|
||||||
engine.rootContext().setContextProperty("CuraActions", self._cura_actions)
|
engine.rootContext().setContextProperty("CuraActions", self._cura_actions)
|
||||||
|
|
||||||
qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type")
|
qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type")
|
||||||
|
|
||||||
|
qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 2, "SceneController", self.getCuraSceneController)
|
||||||
|
qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, "ExtruderManager", self.getExtruderManager)
|
||||||
|
qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager)
|
||||||
|
qmlRegisterSingletonType(MaterialManager, "Cura", 1, 0, "MaterialManager", self.getMaterialManager)
|
||||||
|
qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager", self.getSettingInheritanceManager)
|
||||||
|
qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 2, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager)
|
||||||
|
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
|
||||||
|
|
||||||
|
qmlRegisterSingletonType(ObjectsModel, "Cura", 1, 2, "ObjectsModel", self.getObjectsModel)
|
||||||
|
qmlRegisterSingletonType(BuildPlateModel, "Cura", 1, 2, "BuildPlateModel", self.getBuildPlateModel)
|
||||||
qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer")
|
qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer")
|
||||||
qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
|
qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
|
||||||
qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel")
|
qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel")
|
||||||
@ -1035,8 +1063,9 @@ class CuraApplication(QtApplication):
|
|||||||
Selection.add(node)
|
Selection.add(node)
|
||||||
|
|
||||||
## Delete all nodes containing mesh data in the scene.
|
## Delete all nodes containing mesh data in the scene.
|
||||||
|
# \param only_selectable. Set this to False to delete objects from all build plates
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def deleteAll(self):
|
def deleteAll(self, only_selectable = True):
|
||||||
Logger.log("i", "Clearing scene")
|
Logger.log("i", "Clearing scene")
|
||||||
if not self.getController().getToolsEnabled():
|
if not self.getController().getToolsEnabled():
|
||||||
return
|
return
|
||||||
@ -1047,7 +1076,9 @@ class CuraApplication(QtApplication):
|
|||||||
continue
|
continue
|
||||||
if (not node.getMeshData() and not node.callDecoration("getLayerData")) and not node.callDecoration("isGroup"):
|
if (not node.getMeshData() and not node.callDecoration("getLayerData")) and not node.callDecoration("isGroup"):
|
||||||
continue # Node that doesnt have a mesh and is not a group.
|
continue # Node that doesnt have a mesh and is not a group.
|
||||||
if not node.isSelectable():
|
if only_selectable and not node.isSelectable():
|
||||||
|
continue
|
||||||
|
if not node.callDecoration("isSliceable") and not node.callDecoration("getLayerData") and not node.callDecoration("isGroup"):
|
||||||
continue # Only remove nodes that are selectable.
|
continue # Only remove nodes that are selectable.
|
||||||
if node.getParent() and node.getParent().callDecoration("isGroup"):
|
if node.getParent() and node.getParent().callDecoration("isGroup"):
|
||||||
continue # Grouped nodes don't need resetting as their parent (the group) is resetted)
|
continue # Grouped nodes don't need resetting as their parent (the group) is resetted)
|
||||||
@ -1058,16 +1089,12 @@ class CuraApplication(QtApplication):
|
|||||||
for node in nodes:
|
for node in nodes:
|
||||||
op.addOperation(RemoveSceneNodeOperation(node))
|
op.addOperation(RemoveSceneNodeOperation(node))
|
||||||
|
|
||||||
|
# Reset the print information
|
||||||
|
self.getController().getScene().sceneChanged.emit(node)
|
||||||
|
|
||||||
op.push()
|
op.push()
|
||||||
Selection.clear()
|
Selection.clear()
|
||||||
|
|
||||||
# Reset the print information:
|
|
||||||
self.getController().getScene().sceneChanged.emit(node)
|
|
||||||
# self._print_information.setToZeroPrintInformation(self.getBuildPlateModel().activeBuildPlate)
|
|
||||||
|
|
||||||
# stay on the same build plate
|
|
||||||
#self.getCuraSceneController().setActiveBuildPlate(0) # Select first build plate
|
|
||||||
|
|
||||||
## Reset all translation on nodes with mesh data.
|
## Reset all translation on nodes with mesh data.
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def resetAllTranslation(self):
|
def resetAllTranslation(self):
|
||||||
@ -1342,6 +1369,7 @@ class CuraApplication(QtApplication):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
fileLoaded = pyqtSignal(str)
|
fileLoaded = pyqtSignal(str)
|
||||||
|
fileCompleted = pyqtSignal(str)
|
||||||
|
|
||||||
def _reloadMeshFinished(self, job):
|
def _reloadMeshFinished(self, job):
|
||||||
# TODO; This needs to be fixed properly. We now make the assumption that we only load a single mesh!
|
# TODO; This needs to be fixed properly. We now make the assumption that we only load a single mesh!
|
||||||
@ -1426,7 +1454,7 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
self._currently_loading_files.append(f)
|
self._currently_loading_files.append(f)
|
||||||
if extension in self._non_sliceable_extensions:
|
if extension in self._non_sliceable_extensions:
|
||||||
self.deleteAll()
|
self.deleteAll(only_selectable = False)
|
||||||
|
|
||||||
job = ReadMeshJob(f)
|
job = ReadMeshJob(f)
|
||||||
job.finished.connect(self._readMeshFinished)
|
job.finished.connect(self._readMeshFinished)
|
||||||
@ -1459,6 +1487,7 @@ class CuraApplication(QtApplication):
|
|||||||
|
|
||||||
node.setSelectable(True)
|
node.setSelectable(True)
|
||||||
node.setName(os.path.basename(filename))
|
node.setName(os.path.basename(filename))
|
||||||
|
self.getBuildVolume().checkBoundsAndUpdate(node)
|
||||||
|
|
||||||
extension = os.path.splitext(filename)[1]
|
extension = os.path.splitext(filename)[1]
|
||||||
if extension.lower() in self._non_sliceable_extensions:
|
if extension.lower() in self._non_sliceable_extensions:
|
||||||
@ -1496,7 +1525,7 @@ class CuraApplication(QtApplication):
|
|||||||
node, _ = arranger.findNodePlacement(node, offset_shape_arr, hull_shape_arr, step = 10)
|
node, _ = arranger.findNodePlacement(node, offset_shape_arr, hull_shape_arr, step = 10)
|
||||||
|
|
||||||
# This node is deep copied from some other node which already has a BuildPlateDecorator, but the deepcopy
|
# This node is deep copied from some other node which already has a BuildPlateDecorator, but the deepcopy
|
||||||
# of BuildPlateDecorator produces one that's assoicated with build plate -1. So, here we need to check if
|
# of BuildPlateDecorator produces one that's associated with build plate -1. So, here we need to check if
|
||||||
# the BuildPlateDecorator exists or not and always set the correct build plate number.
|
# the BuildPlateDecorator exists or not and always set the correct build plate number.
|
||||||
build_plate_decorator = node.getDecorator(BuildPlateDecorator)
|
build_plate_decorator = node.getDecorator(BuildPlateDecorator)
|
||||||
if build_plate_decorator is None:
|
if build_plate_decorator is None:
|
||||||
@ -1508,6 +1537,8 @@ class CuraApplication(QtApplication):
|
|||||||
op.push()
|
op.push()
|
||||||
scene.sceneChanged.emit(node)
|
scene.sceneChanged.emit(node)
|
||||||
|
|
||||||
|
self.fileCompleted.emit(filename)
|
||||||
|
|
||||||
def addNonSliceableExtension(self, extension):
|
def addNonSliceableExtension(self, extension):
|
||||||
self._non_sliceable_extensions.append(extension)
|
self._non_sliceable_extensions.append(extension)
|
||||||
|
|
||||||
|
@ -18,12 +18,13 @@ class OneAtATimeIterator(Iterator.Iterator):
|
|||||||
def _fillStack(self):
|
def _fillStack(self):
|
||||||
node_list = []
|
node_list = []
|
||||||
for node in self._scene_node.getChildren():
|
for node in self._scene_node.getChildren():
|
||||||
if not isinstance(node, SceneNode):
|
if not issubclass(type(node), SceneNode):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if node.callDecoration("getConvexHull"):
|
if node.callDecoration("getConvexHull"):
|
||||||
node_list.append(node)
|
node_list.append(node)
|
||||||
|
|
||||||
|
|
||||||
if len(node_list) < 2:
|
if len(node_list) < 2:
|
||||||
self._node_stack = node_list[:]
|
self._node_stack = node_list[:]
|
||||||
return
|
return
|
||||||
|
@ -8,7 +8,9 @@ from UM.Application import Application
|
|||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Qt.Duration import Duration
|
from UM.Qt.Duration import Duration
|
||||||
from UM.Preferences import Preferences
|
from UM.Preferences import Preferences
|
||||||
|
from UM.Scene.SceneNode import SceneNode
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
|
from cura.Scene.CuraSceneNode import CuraSceneNode
|
||||||
|
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
@ -65,7 +67,7 @@ class PrintInformation(QObject):
|
|||||||
self._backend = Application.getInstance().getBackend()
|
self._backend = Application.getInstance().getBackend()
|
||||||
if self._backend:
|
if self._backend:
|
||||||
self._backend.printDurationMessage.connect(self._onPrintDurationMessage)
|
self._backend.printDurationMessage.connect(self._onPrintDurationMessage)
|
||||||
Application.getInstance().getController().getScene().sceneChanged.connect(self.setToZeroPrintInformation)
|
Application.getInstance().getController().getScene().sceneChanged.connect(self._onSceneChanged)
|
||||||
|
|
||||||
self._base_name = ""
|
self._base_name = ""
|
||||||
self._abbr_machine = ""
|
self._abbr_machine = ""
|
||||||
@ -395,12 +397,25 @@ class PrintInformation(QObject):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
# Simulate message with zero time duration
|
# Simulate message with zero time duration
|
||||||
def setToZeroPrintInformation(self, build_plate_number):
|
def setToZeroPrintInformation(self, build_plate):
|
||||||
temp_message = {}
|
|
||||||
if build_plate_number not in self._print_time_message_values:
|
|
||||||
self._print_time_message_values[build_plate_number] = {}
|
|
||||||
for key in self._print_time_message_values[build_plate_number].keys():
|
|
||||||
temp_message[key] = 0
|
|
||||||
|
|
||||||
|
# Construct the 0-time message
|
||||||
|
temp_message = {}
|
||||||
|
if build_plate not in self._print_time_message_values:
|
||||||
|
self._print_time_message_values[build_plate] = {}
|
||||||
|
for key in self._print_time_message_values[build_plate].keys():
|
||||||
|
temp_message[key] = 0
|
||||||
temp_material_amounts = [0]
|
temp_material_amounts = [0]
|
||||||
self._onPrintDurationMessage(build_plate_number, temp_message, temp_material_amounts)
|
|
||||||
|
self._onPrintDurationMessage(build_plate, temp_message, temp_material_amounts)
|
||||||
|
|
||||||
|
## Listen to scene changes to check if we need to reset the print information
|
||||||
|
def _onSceneChanged(self, scene_node):
|
||||||
|
|
||||||
|
# Ignore any changes that are not related to sliceable objects
|
||||||
|
if not isinstance(scene_node, SceneNode)\
|
||||||
|
or not scene_node.callDecoration("isSliceable")\
|
||||||
|
or not scene_node.callDecoration("getBuildPlateNumber") == self._active_build_plate:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.setToZeroPrintInformation(self._active_build_plate)
|
||||||
|
@ -100,7 +100,7 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
|
|||||||
if batched_lines_count >= max_chars_per_line:
|
if batched_lines_count >= max_chars_per_line:
|
||||||
file_data_bytes_list.append(self._compressDataAndNotifyQt("".join(batched_lines)))
|
file_data_bytes_list.append(self._compressDataAndNotifyQt("".join(batched_lines)))
|
||||||
batched_lines = []
|
batched_lines = []
|
||||||
batched_lines_count
|
batched_lines_count = 0
|
||||||
|
|
||||||
# Don't miss the last batch (If any)
|
# Don't miss the last batch (If any)
|
||||||
if len(batched_lines) != 0:
|
if len(batched_lines) != 0:
|
||||||
|
@ -24,7 +24,10 @@ class ConvexHullNode(SceneNode):
|
|||||||
self._original_parent = parent
|
self._original_parent = parent
|
||||||
|
|
||||||
# Color of the drawn convex hull
|
# Color of the drawn convex hull
|
||||||
|
if Application.getInstance().hasGui():
|
||||||
self._color = Color(*Application.getInstance().getTheme().getColor("convex_hull").getRgb())
|
self._color = Color(*Application.getInstance().getTheme().getColor("convex_hull").getRgb())
|
||||||
|
else:
|
||||||
|
self._color = Color(0, 0, 0)
|
||||||
|
|
||||||
# The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting.
|
# The y-coordinate of the convex hull mesh. Must not be 0, to prevent z-fighting.
|
||||||
self._mesh_height = 0.1
|
self._mesh_height = 0.1
|
||||||
|
@ -9,7 +9,7 @@ from copy import deepcopy
|
|||||||
class CuraSceneNode(SceneNode):
|
class CuraSceneNode(SceneNode):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self._outside_buildarea = True
|
self._outside_buildarea = False
|
||||||
|
|
||||||
def setOutsideBuildArea(self, new_value):
|
def setOutsideBuildArea(self, new_value):
|
||||||
self._outside_buildarea = new_value
|
self._outside_buildarea = new_value
|
||||||
|
@ -211,6 +211,34 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", file_name, str(e))}
|
return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", file_name, str(e))}
|
||||||
|
|
||||||
if profile_or_list:
|
if profile_or_list:
|
||||||
|
# Ensure it is always a list of profiles
|
||||||
|
if not isinstance(profile_or_list, list):
|
||||||
|
profile_or_list = [profile_or_list]
|
||||||
|
|
||||||
|
# First check if this profile is suitable for this machine
|
||||||
|
global_profile = None
|
||||||
|
if len(profile_or_list) == 1:
|
||||||
|
global_profile = profile_or_list[0]
|
||||||
|
else:
|
||||||
|
for profile in profile_or_list:
|
||||||
|
if not profile.getMetaDataEntry("extruder"):
|
||||||
|
global_profile = profile
|
||||||
|
break
|
||||||
|
if not global_profile:
|
||||||
|
Logger.log("e", "Incorrect profile [%s]. Could not find global profile", file_name)
|
||||||
|
return { "status": "error",
|
||||||
|
"message": catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "This profile <filename>{0}</filename> contains incorrect data, could not import it.", file_name)}
|
||||||
|
profile_definition = global_profile.getMetaDataEntry("definition")
|
||||||
|
expected_machine_definition = "fdmprinter"
|
||||||
|
if parseBool(global_container_stack.getMetaDataEntry("has_machine_quality", "False")):
|
||||||
|
expected_machine_definition = global_container_stack.getMetaDataEntry("quality_definition")
|
||||||
|
if not expected_machine_definition:
|
||||||
|
expected_machine_definition = global_container_stack.definition.getId()
|
||||||
|
if expected_machine_definition is not None and profile_definition is not None and profile_definition != expected_machine_definition:
|
||||||
|
Logger.log("e", "Profile [%s] is for machine [%s] but the current active machine is [%s]. Will not import the profile", file_name)
|
||||||
|
return { "status": "error",
|
||||||
|
"message": catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "The machine defined in profile <filename>{0}</filename> doesn't match with your current machine, could not import it.", file_name)}
|
||||||
|
|
||||||
name_seed = os.path.splitext(os.path.basename(file_name))[0]
|
name_seed = os.path.splitext(os.path.basename(file_name))[0]
|
||||||
new_name = self.uniqueName(name_seed)
|
new_name = self.uniqueName(name_seed)
|
||||||
|
|
||||||
@ -245,6 +273,9 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
|
|
||||||
return {"status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile_or_list[0].getName())}
|
return {"status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile_or_list[0].getName())}
|
||||||
|
|
||||||
|
# This message is throw when the profile reader doesn't find any profile in the file
|
||||||
|
return {"status": "error", "message": catalog.i18nc("@info:status", "File {0} does not contain any valid profile.", file_name)}
|
||||||
|
|
||||||
# If it hasn't returned by now, none of the plugins loaded the profile successfully.
|
# If it hasn't returned by now, none of the plugins loaded the profile successfully.
|
||||||
return {"status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type or is corrupted.", file_name)}
|
return {"status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type or is corrupted.", file_name)}
|
||||||
|
|
||||||
@ -418,7 +449,14 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
if not extruder_stacks:
|
if not extruder_stacks:
|
||||||
self.addExtruderStackForSingleExtrusionMachine(container, "fdmextruder")
|
self.addExtruderStackForSingleExtrusionMachine(container, "fdmextruder")
|
||||||
|
|
||||||
def addExtruderStackForSingleExtrusionMachine(self, machine, extruder_id):
|
#
|
||||||
|
# new_global_quality_changes is optional. It is only used in project loading for a scenario like this:
|
||||||
|
# - override the current machine
|
||||||
|
# - create new for custom quality profile
|
||||||
|
# new_global_quality_changes is the new global quality changes container in this scenario.
|
||||||
|
# create_new_ids indicates if new unique ids must be created
|
||||||
|
#
|
||||||
|
def addExtruderStackForSingleExtrusionMachine(self, machine, extruder_id, new_global_quality_changes = None, create_new_ids = True):
|
||||||
new_extruder_id = extruder_id
|
new_extruder_id = extruder_id
|
||||||
|
|
||||||
extruder_definitions = self.findDefinitionContainers(id = new_extruder_id)
|
extruder_definitions = self.findDefinitionContainers(id = new_extruder_id)
|
||||||
@ -427,7 +465,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
return
|
return
|
||||||
|
|
||||||
extruder_definition = extruder_definitions[0]
|
extruder_definition = extruder_definitions[0]
|
||||||
unique_name = self.uniqueName(machine.getName() + " " + new_extruder_id)
|
unique_name = self.uniqueName(machine.getName() + " " + new_extruder_id) if create_new_ids else machine.getName() + " " + new_extruder_id
|
||||||
|
|
||||||
extruder_stack = ExtruderStack.ExtruderStack(unique_name)
|
extruder_stack = ExtruderStack.ExtruderStack(unique_name)
|
||||||
extruder_stack.setName(extruder_definition.getName())
|
extruder_stack.setName(extruder_definition.getName())
|
||||||
@ -437,7 +475,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
# create a new definition_changes container for the extruder stack
|
# create a new definition_changes container for the extruder stack
|
||||||
definition_changes_id = self.uniqueName(extruder_stack.getId() + "_settings")
|
definition_changes_id = self.uniqueName(extruder_stack.getId() + "_settings") if create_new_ids else extruder_stack.getId() + "_settings"
|
||||||
definition_changes_name = definition_changes_id
|
definition_changes_name = definition_changes_id
|
||||||
definition_changes = InstanceContainer(definition_changes_id)
|
definition_changes = InstanceContainer(definition_changes_id)
|
||||||
definition_changes.setName(definition_changes_name)
|
definition_changes.setName(definition_changes_name)
|
||||||
@ -464,7 +502,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
extruder_stack.setDefinitionChanges(definition_changes)
|
extruder_stack.setDefinitionChanges(definition_changes)
|
||||||
|
|
||||||
# create empty user changes container otherwise
|
# create empty user changes container otherwise
|
||||||
user_container_id = self.uniqueName(extruder_stack.getId() + "_user")
|
user_container_id = self.uniqueName(extruder_stack.getId() + "_user") if create_new_ids else extruder_stack.getId() + "_user"
|
||||||
user_container_name = user_container_id
|
user_container_name = user_container_id
|
||||||
user_container = InstanceContainer(user_container_id)
|
user_container = InstanceContainer(user_container_id)
|
||||||
user_container.setName(user_container_name)
|
user_container.setName(user_container_name)
|
||||||
@ -514,8 +552,12 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
quality_id = "empty_quality"
|
quality_id = "empty_quality"
|
||||||
extruder_stack.setQualityById(quality_id)
|
extruder_stack.setQualityById(quality_id)
|
||||||
|
|
||||||
if machine.qualityChanges.getId() not in ("empty", "empty_quality_changes"):
|
machine_quality_changes = machine.qualityChanges
|
||||||
extruder_quality_changes_container = self.findInstanceContainers(name = machine.qualityChanges.getName(), extruder = extruder_id)
|
if new_global_quality_changes is not None:
|
||||||
|
machine_quality_changes = new_global_quality_changes
|
||||||
|
|
||||||
|
if machine_quality_changes.getId() not in ("empty", "empty_quality_changes"):
|
||||||
|
extruder_quality_changes_container = self.findInstanceContainers(name = machine_quality_changes.getName(), extruder = extruder_id)
|
||||||
if extruder_quality_changes_container:
|
if extruder_quality_changes_container:
|
||||||
extruder_quality_changes_container = extruder_quality_changes_container[0]
|
extruder_quality_changes_container = extruder_quality_changes_container[0]
|
||||||
|
|
||||||
@ -525,31 +567,34 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
# Some extruder quality_changes containers can be created at runtime as files in the qualities
|
# Some extruder quality_changes containers can be created at runtime as files in the qualities
|
||||||
# folder. Those files won't be loaded in the registry immediately. So we also need to search
|
# folder. Those files won't be loaded in the registry immediately. So we also need to search
|
||||||
# the folder to see if the quality_changes exists.
|
# the folder to see if the quality_changes exists.
|
||||||
extruder_quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine.qualityChanges.getName())
|
extruder_quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine_quality_changes.getName())
|
||||||
if extruder_quality_changes_container:
|
if extruder_quality_changes_container:
|
||||||
quality_changes_id = extruder_quality_changes_container.getId()
|
quality_changes_id = extruder_quality_changes_container.getId()
|
||||||
extruder_stack.setQualityChangesById(quality_changes_id)
|
extruder_stack.setQualityChangesById(quality_changes_id)
|
||||||
else:
|
else:
|
||||||
# if we still cannot find a quality changes container for the extruder, create a new one
|
# if we still cannot find a quality changes container for the extruder, create a new one
|
||||||
container_id = self.uniqueName(extruder_stack.getId() + "_user")
|
container_name = machine_quality_changes.getName()
|
||||||
container_name = machine.qualityChanges.getName()
|
container_id = self.uniqueName(extruder_stack.getId() + "_qc_" + container_name)
|
||||||
extruder_quality_changes_container = InstanceContainer(container_id)
|
extruder_quality_changes_container = InstanceContainer(container_id)
|
||||||
extruder_quality_changes_container.setName(container_name)
|
extruder_quality_changes_container.setName(container_name)
|
||||||
extruder_quality_changes_container.addMetaDataEntry("type", "quality_changes")
|
extruder_quality_changes_container.addMetaDataEntry("type", "quality_changes")
|
||||||
extruder_quality_changes_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
extruder_quality_changes_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
|
||||||
extruder_quality_changes_container.addMetaDataEntry("extruder", extruder_stack.definition.getId())
|
extruder_quality_changes_container.addMetaDataEntry("extruder", extruder_stack.definition.getId())
|
||||||
extruder_quality_changes_container.addMetaDataEntry("quality_type", machine.qualityChanges.getMetaDataEntry("quality_type"))
|
extruder_quality_changes_container.addMetaDataEntry("quality_type", machine_quality_changes.getMetaDataEntry("quality_type"))
|
||||||
extruder_quality_changes_container.setDefinition(machine.qualityChanges.getDefinition().getId())
|
extruder_quality_changes_container.setDefinition(machine_quality_changes.getDefinition().getId())
|
||||||
|
|
||||||
|
self.addContainer(extruder_quality_changes_container)
|
||||||
|
extruder_stack.qualityChanges = extruder_quality_changes_container
|
||||||
|
|
||||||
if not extruder_quality_changes_container:
|
if not extruder_quality_changes_container:
|
||||||
Logger.log("w", "Could not find quality_changes named [%s] for extruder [%s]",
|
Logger.log("w", "Could not find quality_changes named [%s] for extruder [%s]",
|
||||||
machine.qualityChanges.getName(), extruder_stack.getId())
|
machine_quality_changes.getName(), extruder_stack.getId())
|
||||||
else:
|
else:
|
||||||
# move all per-extruder settings to the extruder's quality changes
|
# move all per-extruder settings to the extruder's quality changes
|
||||||
for qc_setting_key in machine.qualityChanges.getAllKeys():
|
for qc_setting_key in machine_quality_changes.getAllKeys():
|
||||||
settable_per_extruder = machine.getProperty(qc_setting_key, "settable_per_extruder")
|
settable_per_extruder = machine.getProperty(qc_setting_key, "settable_per_extruder")
|
||||||
if settable_per_extruder:
|
if settable_per_extruder:
|
||||||
setting_value = machine.qualityChanges.getProperty(qc_setting_key, "value")
|
setting_value = machine_quality_changes.getProperty(qc_setting_key, "value")
|
||||||
|
|
||||||
setting_definition = machine.getSettingDefinition(qc_setting_key)
|
setting_definition = machine.getSettingDefinition(qc_setting_key)
|
||||||
new_instance = SettingInstance(setting_definition, definition_changes)
|
new_instance = SettingInstance(setting_definition, definition_changes)
|
||||||
@ -558,7 +603,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
extruder_quality_changes_container.addInstance(new_instance)
|
extruder_quality_changes_container.addInstance(new_instance)
|
||||||
extruder_quality_changes_container.setDirty(True)
|
extruder_quality_changes_container.setDirty(True)
|
||||||
|
|
||||||
machine.qualityChanges.removeInstance(qc_setting_key, postpone_emit=True)
|
machine_quality_changes.removeInstance(qc_setting_key, postpone_emit=True)
|
||||||
else:
|
else:
|
||||||
extruder_stack.setQualityChangesById("empty_quality_changes")
|
extruder_stack.setQualityChangesById("empty_quality_changes")
|
||||||
|
|
||||||
@ -566,8 +611,8 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
|
|
||||||
# Also need to fix the other qualities that are suitable for this machine. Those quality changes may still have
|
# Also need to fix the other qualities that are suitable for this machine. Those quality changes may still have
|
||||||
# per-extruder settings in the container for the machine instead of the extruder.
|
# per-extruder settings in the container for the machine instead of the extruder.
|
||||||
if machine.qualityChanges.getId() not in ("empty", "empty_quality_changes"):
|
if machine_quality_changes.getId() not in ("empty", "empty_quality_changes"):
|
||||||
quality_changes_machine_definition_id = machine.qualityChanges.getDefinition().getId()
|
quality_changes_machine_definition_id = machine_quality_changes.getDefinition().getId()
|
||||||
else:
|
else:
|
||||||
whole_machine_definition = machine.definition
|
whole_machine_definition = machine.definition
|
||||||
machine_entry = machine.definition.getMetaDataEntry("machine")
|
machine_entry = machine.definition.getMetaDataEntry("machine")
|
||||||
@ -587,7 +632,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||||||
qc_groups[qc_name] = []
|
qc_groups[qc_name] = []
|
||||||
qc_groups[qc_name].append(qc)
|
qc_groups[qc_name].append(qc)
|
||||||
# try to find from the quality changes cura directory too
|
# try to find from the quality changes cura directory too
|
||||||
quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine.qualityChanges.getName())
|
quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine_quality_changes.getName())
|
||||||
if quality_changes_container:
|
if quality_changes_container:
|
||||||
qc_groups[qc_name].append(quality_changes_container)
|
qc_groups[qc_name].append(quality_changes_container)
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ class CuraStackBuilder:
|
|||||||
next_stack = new_global_stack
|
next_stack = new_global_stack
|
||||||
)
|
)
|
||||||
new_global_stack.addExtruder(new_extruder)
|
new_global_stack.addExtruder(new_extruder)
|
||||||
|
registry.addContainer(new_extruder)
|
||||||
else:
|
else:
|
||||||
# create extruder stack for each found extruder definition
|
# create extruder stack for each found extruder definition
|
||||||
for extruder_definition in registry.findDefinitionContainers(machine = machine_definition.id):
|
for extruder_definition in registry.findDefinitionContainers(machine = machine_definition.id):
|
||||||
@ -81,6 +82,11 @@ class CuraStackBuilder:
|
|||||||
next_stack = new_global_stack
|
next_stack = new_global_stack
|
||||||
)
|
)
|
||||||
new_global_stack.addExtruder(new_extruder)
|
new_global_stack.addExtruder(new_extruder)
|
||||||
|
registry.addContainer(new_extruder)
|
||||||
|
|
||||||
|
# Register the global stack after the extruder stacks are created. This prevents the registry from adding another
|
||||||
|
# extruder stack because the global stack didn't have one yet (which is enforced since Cura 3.1).
|
||||||
|
registry.addContainer(new_global_stack)
|
||||||
|
|
||||||
return new_global_stack
|
return new_global_stack
|
||||||
|
|
||||||
@ -135,9 +141,7 @@ class CuraStackBuilder:
|
|||||||
# Only add the created containers to the registry after we have set all the other
|
# Only add the created containers to the registry after we have set all the other
|
||||||
# properties. This makes the create operation more transactional, since any problems
|
# properties. This makes the create operation more transactional, since any problems
|
||||||
# setting properties will not result in incomplete containers being added.
|
# setting properties will not result in incomplete containers being added.
|
||||||
registry = ContainerRegistry.getInstance()
|
ContainerRegistry.getInstance().addContainer(user_container)
|
||||||
registry.addContainer(stack)
|
|
||||||
registry.addContainer(user_container)
|
|
||||||
|
|
||||||
return stack
|
return stack
|
||||||
|
|
||||||
@ -181,9 +185,7 @@ class CuraStackBuilder:
|
|||||||
if "quality_changes" in kwargs:
|
if "quality_changes" in kwargs:
|
||||||
stack.setQualityChangesById(kwargs["quality_changes"])
|
stack.setQualityChangesById(kwargs["quality_changes"])
|
||||||
|
|
||||||
registry = ContainerRegistry.getInstance()
|
ContainerRegistry.getInstance().addContainer(user_container)
|
||||||
registry.addContainer(stack)
|
|
||||||
registry.addContainer(user_container)
|
|
||||||
|
|
||||||
return stack
|
return stack
|
||||||
|
|
||||||
|
@ -407,6 +407,12 @@ class ExtruderManager(QObject):
|
|||||||
extruder_train.setNextStack(global_stack)
|
extruder_train.setNextStack(global_stack)
|
||||||
extruders_changed = True
|
extruders_changed = True
|
||||||
|
|
||||||
|
# FIX: We have to remove those settings here because we know that those values have been copied to all
|
||||||
|
# the extruders at this point.
|
||||||
|
for key in ("material_diameter", "machine_nozzle_size"):
|
||||||
|
if global_stack.definitionChanges.hasProperty(key, "value"):
|
||||||
|
global_stack.definitionChanges.removeInstance(key, postpone_emit = True)
|
||||||
|
|
||||||
if extruders_changed:
|
if extruders_changed:
|
||||||
self.extrudersChanged.emit(global_stack_id)
|
self.extrudersChanged.emit(global_stack_id)
|
||||||
self.extrudersAdded.emit()
|
self.extrudersAdded.emit()
|
||||||
@ -496,6 +502,89 @@ class ExtruderManager(QObject):
|
|||||||
def getInstanceExtruderValues(self, key):
|
def getInstanceExtruderValues(self, key):
|
||||||
return ExtruderManager.getExtruderValues(key)
|
return ExtruderManager.getExtruderValues(key)
|
||||||
|
|
||||||
|
## Updates the material container to a material that matches the material diameter set for the printer
|
||||||
|
def updateMaterialForDiameter(self, extruder_position: int):
|
||||||
|
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||||
|
if not global_stack:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not global_stack.getMetaDataEntry("has_materials", False):
|
||||||
|
return
|
||||||
|
|
||||||
|
extruder_stack = global_stack.extruders[str(extruder_position)]
|
||||||
|
|
||||||
|
material_diameter = extruder_stack.material.getProperty("material_diameter", "value")
|
||||||
|
if not material_diameter:
|
||||||
|
# in case of "empty" material
|
||||||
|
material_diameter = 0
|
||||||
|
|
||||||
|
material_approximate_diameter = str(round(material_diameter))
|
||||||
|
machine_diameter = extruder_stack.definitionChanges.getProperty("material_diameter", "value")
|
||||||
|
if not machine_diameter:
|
||||||
|
if extruder_stack.definition.hasProperty("material_diameter", "value"):
|
||||||
|
machine_diameter = extruder_stack.definition.getProperty("material_diameter", "value")
|
||||||
|
else:
|
||||||
|
machine_diameter = global_stack.definition.getProperty("material_diameter", "value")
|
||||||
|
machine_approximate_diameter = str(round(machine_diameter))
|
||||||
|
|
||||||
|
if material_approximate_diameter != machine_approximate_diameter:
|
||||||
|
Logger.log("i", "The the currently active material(s) do not match the diameter set for the printer. Finding alternatives.")
|
||||||
|
|
||||||
|
if global_stack.getMetaDataEntry("has_machine_materials", False):
|
||||||
|
materials_definition = global_stack.definition.getId()
|
||||||
|
has_material_variants = global_stack.getMetaDataEntry("has_variants", False)
|
||||||
|
else:
|
||||||
|
materials_definition = "fdmprinter"
|
||||||
|
has_material_variants = False
|
||||||
|
|
||||||
|
old_material = extruder_stack.material
|
||||||
|
search_criteria = {
|
||||||
|
"type": "material",
|
||||||
|
"approximate_diameter": machine_approximate_diameter,
|
||||||
|
"material": old_material.getMetaDataEntry("material", "value"),
|
||||||
|
"brand": old_material.getMetaDataEntry("brand", "value"),
|
||||||
|
"supplier": old_material.getMetaDataEntry("supplier", "value"),
|
||||||
|
"color_name": old_material.getMetaDataEntry("color_name", "value"),
|
||||||
|
"definition": materials_definition
|
||||||
|
}
|
||||||
|
if has_material_variants:
|
||||||
|
search_criteria["variant"] = extruder_stack.variant.getId()
|
||||||
|
|
||||||
|
container_registry = Application.getInstance().getContainerRegistry()
|
||||||
|
empty_material = container_registry.findInstanceContainers(id = "empty_material")[0]
|
||||||
|
|
||||||
|
if old_material == empty_material:
|
||||||
|
search_criteria.pop("material", None)
|
||||||
|
search_criteria.pop("supplier", None)
|
||||||
|
search_criteria.pop("brand", None)
|
||||||
|
search_criteria.pop("definition", None)
|
||||||
|
search_criteria["id"] = extruder_stack.getMetaDataEntry("preferred_material")
|
||||||
|
|
||||||
|
materials = container_registry.findInstanceContainers(**search_criteria)
|
||||||
|
if not materials:
|
||||||
|
# Same material with new diameter is not found, search for generic version of the same material type
|
||||||
|
search_criteria.pop("supplier", None)
|
||||||
|
search_criteria.pop("brand", None)
|
||||||
|
search_criteria["color_name"] = "Generic"
|
||||||
|
materials = container_registry.findInstanceContainers(**search_criteria)
|
||||||
|
if not materials:
|
||||||
|
# Generic material with new diameter is not found, search for preferred material
|
||||||
|
search_criteria.pop("color_name", None)
|
||||||
|
search_criteria.pop("material", None)
|
||||||
|
search_criteria["id"] = extruder_stack.getMetaDataEntry("preferred_material")
|
||||||
|
materials = container_registry.findInstanceContainers(**search_criteria)
|
||||||
|
if not materials:
|
||||||
|
# Preferred material with new diameter is not found, search for any material
|
||||||
|
search_criteria.pop("id", None)
|
||||||
|
materials = container_registry.findInstanceContainers(**search_criteria)
|
||||||
|
if not materials:
|
||||||
|
# Just use empty material as a final fallback
|
||||||
|
materials = [empty_material]
|
||||||
|
|
||||||
|
Logger.log("i", "Selecting new material: %s", materials[0].getId())
|
||||||
|
|
||||||
|
extruder_stack.material = materials[0]
|
||||||
|
|
||||||
## Get the value for a setting from a specific extruder.
|
## Get the value for a setting from a specific extruder.
|
||||||
#
|
#
|
||||||
# This is exposed to SettingFunction to use in value functions.
|
# This is exposed to SettingFunction to use in value functions.
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
from typing import Any, TYPE_CHECKING, Optional
|
from typing import Any, TYPE_CHECKING, Optional
|
||||||
|
|
||||||
|
from UM.Application import Application
|
||||||
from UM.Decorators import override
|
from UM.Decorators import override
|
||||||
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
||||||
from UM.Settings.ContainerStack import ContainerStack
|
from UM.Settings.ContainerStack import ContainerStack
|
||||||
@ -18,10 +19,6 @@ if TYPE_CHECKING:
|
|||||||
from cura.Settings.GlobalStack import GlobalStack
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
|
||||||
|
|
||||||
_EXTRUDER_SPECIFIC_DEFINITION_CHANGES_SETTINGS = ["machine_nozzle_size",
|
|
||||||
"material_diameter"]
|
|
||||||
|
|
||||||
|
|
||||||
## Represents an Extruder and its related containers.
|
## Represents an Extruder and its related containers.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@ -53,8 +50,26 @@ class ExtruderStack(CuraContainerStack):
|
|||||||
# when we are upgrading a definition_changes container file, there is NO guarantee that other files such as
|
# when we are upgrading a definition_changes container file, there is NO guarantee that other files such as
|
||||||
# machine an extruder stack files are upgraded before this, so we cannot read those files assuming they are in
|
# machine an extruder stack files are upgraded before this, so we cannot read those files assuming they are in
|
||||||
# the latest format.
|
# the latest format.
|
||||||
if self.getMetaDataEntry("position") == "0":
|
#
|
||||||
for key in _EXTRUDER_SPECIFIC_DEFINITION_CHANGES_SETTINGS:
|
# MORE:
|
||||||
|
# For single-extrusion machines, nozzle size is saved in the global stack, so the nozzle size value should be
|
||||||
|
# carried to the first extruder.
|
||||||
|
# For material diameter, it was supposed to be applied to all extruders, so its value should be copied to all
|
||||||
|
# extruders.
|
||||||
|
|
||||||
|
keys_to_copy = ["material_diameter", "machine_nozzle_size"] # these will be copied over to all extruders
|
||||||
|
|
||||||
|
for key in keys_to_copy:
|
||||||
|
# Since material_diameter is not on the extruder definition, we need to add it here
|
||||||
|
# WARNING: this might be very dangerous and should be refactored ASAP!
|
||||||
|
definition = stack.getSettingDefinition(key)
|
||||||
|
if definition:
|
||||||
|
self.definition.addDefinition(definition)
|
||||||
|
|
||||||
|
# Only copy the value when this extruder doesn't have the value.
|
||||||
|
if self.definitionChanges.hasProperty(key, "value"):
|
||||||
|
continue
|
||||||
|
|
||||||
setting_value = stack.definitionChanges.getProperty(key, "value")
|
setting_value = stack.definitionChanges.getProperty(key, "value")
|
||||||
if setting_value is None:
|
if setting_value is None:
|
||||||
continue
|
continue
|
||||||
@ -66,7 +81,17 @@ class ExtruderStack(CuraContainerStack):
|
|||||||
self.definitionChanges.addInstance(new_instance)
|
self.definitionChanges.addInstance(new_instance)
|
||||||
self.definitionChanges.setDirty(True)
|
self.definitionChanges.setDirty(True)
|
||||||
|
|
||||||
stack.definitionChanges.removeInstance(key, postpone_emit = True)
|
# Make sure the material diameter is up to date for the extruder stack.
|
||||||
|
if key == "material_diameter":
|
||||||
|
position = self.getMetaDataEntry("position", "0")
|
||||||
|
Application.getInstance().getExtruderManager().updateMaterialForDiameter(position)
|
||||||
|
|
||||||
|
# NOTE: We cannot remove the setting from the global stack's definition changes container because for
|
||||||
|
# material diameter, it needs to be applied to all extruders, but here we don't know how many extruders
|
||||||
|
# a machine actually has and how many extruders has already been loaded for that machine, so we have to
|
||||||
|
# keep this setting for any remaining extruders that haven't been loaded yet.
|
||||||
|
#
|
||||||
|
# Those settings will be removed in ExtruderManager which knows all those info.
|
||||||
|
|
||||||
@override(ContainerStack)
|
@override(ContainerStack)
|
||||||
def getNextStack(self) -> Optional["GlobalStack"]:
|
def getNextStack(self) -> Optional["GlobalStack"]:
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 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 collections import defaultdict
|
||||||
|
import threading
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtProperty
|
from PyQt5.QtCore import pyqtProperty
|
||||||
@ -30,7 +32,8 @@ class GlobalStack(CuraContainerStack):
|
|||||||
# This property is used to track which settings we are calculating the "resolve" for
|
# This property is used to track which settings we are calculating the "resolve" for
|
||||||
# and if so, to bypass the resolve to prevent an infinite recursion that would occur
|
# and if so, to bypass the resolve to prevent an infinite recursion that would occur
|
||||||
# if the resolve function tried to access the same property it is a resolve for.
|
# if the resolve function tried to access the same property it is a resolve for.
|
||||||
self._resolving_settings = set()
|
# Per thread we have our own resolving_settings, or strange things sometimes occur.
|
||||||
|
self._resolving_settings = defaultdict(set) # keys are thread names
|
||||||
|
|
||||||
## Get the list of extruders of this stack.
|
## Get the list of extruders of this stack.
|
||||||
#
|
#
|
||||||
@ -91,9 +94,10 @@ class GlobalStack(CuraContainerStack):
|
|||||||
|
|
||||||
# Handle the "resolve" property.
|
# Handle the "resolve" property.
|
||||||
if self._shouldResolve(key, property_name, context):
|
if self._shouldResolve(key, property_name, context):
|
||||||
self._resolving_settings.add(key)
|
current_thread = threading.current_thread()
|
||||||
|
self._resolving_settings[current_thread.name].add(key)
|
||||||
resolve = super().getProperty(key, "resolve", context)
|
resolve = super().getProperty(key, "resolve", context)
|
||||||
self._resolving_settings.remove(key)
|
self._resolving_settings[current_thread.name].remove(key)
|
||||||
if resolve is not None:
|
if resolve is not None:
|
||||||
return resolve
|
return resolve
|
||||||
|
|
||||||
@ -145,7 +149,8 @@ class GlobalStack(CuraContainerStack):
|
|||||||
# Do not try to resolve anything but the "value" property
|
# Do not try to resolve anything but the "value" property
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if key in self._resolving_settings:
|
current_thread = threading.current_thread()
|
||||||
|
if key in self._resolving_settings[current_thread.name]:
|
||||||
# To prevent infinite recursion, if getProperty is called with the same key as
|
# To prevent infinite recursion, if getProperty is called with the same key as
|
||||||
# we are already trying to resolve, we should not try to resolve again. Since
|
# we are already trying to resolve, we should not try to resolve again. Since
|
||||||
# this can happen multiple times when trying to resolve a value, we need to
|
# this can happen multiple times when trying to resolve a value, we need to
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 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 time
|
||||||
#Type hinting.
|
#Type hinting.
|
||||||
from typing import Union, List, Dict
|
from typing import Union, List, Dict
|
||||||
|
|
||||||
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
from UM.Signal import Signal
|
from UM.Signal import Signal
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
|
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
|
||||||
@ -75,6 +78,7 @@ class MachineManager(QObject):
|
|||||||
|
|
||||||
self._stacks_have_errors = None
|
self._stacks_have_errors = None
|
||||||
|
|
||||||
|
self._empty_definition_changes_container = ContainerRegistry.getInstance().findContainers(id = "empty_definition_changes")[0]
|
||||||
self._empty_variant_container = ContainerRegistry.getInstance().findContainers(id = "empty_variant")[0]
|
self._empty_variant_container = ContainerRegistry.getInstance().findContainers(id = "empty_variant")[0]
|
||||||
self._empty_material_container = ContainerRegistry.getInstance().findContainers(id = "empty_material")[0]
|
self._empty_material_container = ContainerRegistry.getInstance().findContainers(id = "empty_material")[0]
|
||||||
self._empty_quality_container = ContainerRegistry.getInstance().findContainers(id = "empty_quality")[0]
|
self._empty_quality_container = ContainerRegistry.getInstance().findContainers(id = "empty_quality")[0]
|
||||||
@ -404,15 +408,28 @@ class MachineManager(QObject):
|
|||||||
Logger.log("w", "Failed creating a new machine!")
|
Logger.log("w", "Failed creating a new machine!")
|
||||||
|
|
||||||
def _checkStacksHaveErrors(self) -> bool:
|
def _checkStacksHaveErrors(self) -> bool:
|
||||||
|
time_start = time.time()
|
||||||
if self._global_container_stack is None: #No active machine.
|
if self._global_container_stack is None: #No active machine.
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self._global_container_stack.hasErrors():
|
if self._global_container_stack.hasErrors():
|
||||||
return True
|
Logger.log("d", "Checking global stack for errors took %0.2f s and we found and error" % (time.time() - time_start))
|
||||||
for stack in ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId()):
|
|
||||||
if stack.hasErrors():
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# Not a very pretty solution, but the extruder manager doesn't really know how many extruders there are
|
||||||
|
machine_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
|
||||||
|
extruder_stacks = ExtruderManager.getInstance().getMachineExtruders(self._global_container_stack.getId())
|
||||||
|
count = 1 # we start with the global stack
|
||||||
|
for stack in extruder_stacks:
|
||||||
|
md = stack.getMetaData()
|
||||||
|
if "position" in md and int(md["position"]) >= machine_extruder_count:
|
||||||
|
continue
|
||||||
|
count += 1
|
||||||
|
if stack.hasErrors():
|
||||||
|
Logger.log("d", "Checking %s stacks for errors took %.2f s and we found an error in stack [%s]" % (count, time.time() - time_start, str(stack)))
|
||||||
|
return True
|
||||||
|
|
||||||
|
Logger.log("d", "Checking %s stacks for errors took %.2f s" % (count, time.time() - time_start))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
## Remove all instances from the top instanceContainer (effectively removing all user-changed settings)
|
## Remove all instances from the top instanceContainer (effectively removing all user-changed settings)
|
||||||
@ -764,7 +781,7 @@ class MachineManager(QObject):
|
|||||||
## Set the active material by switching out a container
|
## Set the active material by switching out a container
|
||||||
# Depending on from/to material+current variant, a quality profile is chosen and set.
|
# Depending on from/to material+current variant, a quality profile is chosen and set.
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def setActiveMaterial(self, material_id: str):
|
def setActiveMaterial(self, material_id: str, always_discard_changes = False):
|
||||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||||
containers = ContainerRegistry.getInstance().findInstanceContainers(id = material_id)
|
containers = ContainerRegistry.getInstance().findInstanceContainers(id = material_id)
|
||||||
if not containers or not self._active_container_stack:
|
if not containers or not self._active_container_stack:
|
||||||
@ -846,10 +863,10 @@ class MachineManager(QObject):
|
|||||||
if not old_quality_changes:
|
if not old_quality_changes:
|
||||||
new_quality_id = candidate_quality.getId()
|
new_quality_id = candidate_quality.getId()
|
||||||
|
|
||||||
self.setActiveQuality(new_quality_id)
|
self.setActiveQuality(new_quality_id, always_discard_changes = always_discard_changes)
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def setActiveVariant(self, variant_id: str):
|
def setActiveVariant(self, variant_id: str, always_discard_changes = False):
|
||||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||||
containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_id)
|
containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_id)
|
||||||
if not containers or not self._active_container_stack:
|
if not containers or not self._active_container_stack:
|
||||||
@ -865,7 +882,7 @@ class MachineManager(QObject):
|
|||||||
if old_material:
|
if old_material:
|
||||||
preferred_material_name = old_material.getName()
|
preferred_material_name = old_material.getName()
|
||||||
preferred_material_id = self._updateMaterialContainer(self._global_container_stack.definition, self._global_container_stack, containers[0], preferred_material_name).id
|
preferred_material_id = self._updateMaterialContainer(self._global_container_stack.definition, self._global_container_stack, containers[0], preferred_material_name).id
|
||||||
self.setActiveMaterial(preferred_material_id)
|
self.setActiveMaterial(preferred_material_id, always_discard_changes = always_discard_changes)
|
||||||
else:
|
else:
|
||||||
Logger.log("w", "While trying to set the active variant, no variant was found to replace.")
|
Logger.log("w", "While trying to set the active variant, no variant was found to replace.")
|
||||||
|
|
||||||
@ -890,10 +907,12 @@ class MachineManager(QObject):
|
|||||||
## set the active quality
|
## set the active quality
|
||||||
# \param quality_id The quality_id of either a quality or a quality_changes
|
# \param quality_id The quality_id of either a quality or a quality_changes
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def setActiveQuality(self, quality_id: str):
|
def setActiveQuality(self, quality_id: str, always_discard_changes = False):
|
||||||
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
|
||||||
self.blurSettings.emit()
|
self.blurSettings.emit()
|
||||||
|
|
||||||
|
Logger.log("d", "Attempting to change the active quality to %s", quality_id)
|
||||||
|
|
||||||
containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = quality_id)
|
containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = quality_id)
|
||||||
if not containers or not self._global_container_stack:
|
if not containers or not self._global_container_stack:
|
||||||
return
|
return
|
||||||
@ -948,11 +967,13 @@ class MachineManager(QObject):
|
|||||||
"quality_changes": stack_quality_changes
|
"quality_changes": stack_quality_changes
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Logger.log("d", "Active quality changed")
|
||||||
|
|
||||||
# show the keep/discard dialog after the containers have been switched. Otherwise, the default values on
|
# show the keep/discard dialog after the containers have been switched. Otherwise, the default values on
|
||||||
# the dialog will be the those before the switching.
|
# the dialog will be the those before the switching.
|
||||||
self._executeDelayedActiveContainerStackChanges()
|
self._executeDelayedActiveContainerStackChanges()
|
||||||
|
|
||||||
if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
|
if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1 and not always_discard_changes:
|
||||||
Application.getInstance().discardOrKeepProfileChanges()
|
Application.getInstance().discardOrKeepProfileChanges()
|
||||||
|
|
||||||
## Used to update material and variant in the active container stack with a delay.
|
## Used to update material and variant in the active container stack with a delay.
|
||||||
@ -960,6 +981,9 @@ class MachineManager(QObject):
|
|||||||
# before the user decided to keep or discard any of their changes using the dialog.
|
# before the user decided to keep or discard any of their changes using the dialog.
|
||||||
# The Application.onDiscardOrKeepProfileChangesClosed signal triggers this method.
|
# The Application.onDiscardOrKeepProfileChangesClosed signal triggers this method.
|
||||||
def _executeDelayedActiveContainerStackChanges(self):
|
def _executeDelayedActiveContainerStackChanges(self):
|
||||||
|
|
||||||
|
Logger.log("d", "Applying configuration changes...")
|
||||||
|
|
||||||
if self._new_variant_container is not None:
|
if self._new_variant_container is not None:
|
||||||
self._active_container_stack.variant = self._new_variant_container
|
self._active_container_stack.variant = self._new_variant_container
|
||||||
self._new_variant_container = None
|
self._new_variant_container = None
|
||||||
@ -984,6 +1008,8 @@ class MachineManager(QObject):
|
|||||||
|
|
||||||
self._new_quality_containers.clear()
|
self._new_quality_containers.clear()
|
||||||
|
|
||||||
|
Logger.log("d", "New configuration applied")
|
||||||
|
|
||||||
## Cancel set changes for material and variant in the active container stack.
|
## Cancel set changes for material and variant in the active container stack.
|
||||||
# Used for ignoring any changes when switching between printers (setActiveMachine)
|
# Used for ignoring any changes when switching between printers (setActiveMachine)
|
||||||
def _cancelDelayedActiveContainerStackChanges(self):
|
def _cancelDelayedActiveContainerStackChanges(self):
|
||||||
@ -1339,6 +1365,68 @@ class MachineManager(QObject):
|
|||||||
if containers:
|
if containers:
|
||||||
return containers[0].definition.getId()
|
return containers[0].definition.getId()
|
||||||
|
|
||||||
|
## Set the amount of extruders on the active machine (global stack)
|
||||||
|
# \param extruder_count int the number of extruders to set
|
||||||
|
def setActiveMachineExtruderCount(self, extruder_count):
|
||||||
|
extruder_manager = Application.getInstance().getExtruderManager()
|
||||||
|
|
||||||
|
definition_changes_container = self._global_container_stack.definitionChanges
|
||||||
|
if not self._global_container_stack or definition_changes_container == self._empty_definition_changes_container:
|
||||||
|
return
|
||||||
|
|
||||||
|
previous_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
|
||||||
|
if extruder_count == previous_extruder_count:
|
||||||
|
return
|
||||||
|
|
||||||
|
# reset all extruder number settings whose value is no longer valid
|
||||||
|
for setting_instance in self._global_container_stack.userChanges.findInstances():
|
||||||
|
setting_key = setting_instance.definition.key
|
||||||
|
if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
old_value = int(self._global_container_stack.userChanges.getProperty(setting_key, "value"))
|
||||||
|
if old_value >= extruder_count:
|
||||||
|
self._global_container_stack.userChanges.removeInstance(setting_key)
|
||||||
|
Logger.log("d", "Reset [%s] because its old value [%s] is no longer valid ", setting_key, old_value)
|
||||||
|
|
||||||
|
# Check to see if any objects are set to print with an extruder that will no longer exist
|
||||||
|
root_node = Application.getInstance().getController().getScene().getRoot()
|
||||||
|
for node in DepthFirstIterator(root_node):
|
||||||
|
if node.getMeshData():
|
||||||
|
extruder_nr = node.callDecoration("getActiveExtruderPosition")
|
||||||
|
|
||||||
|
if extruder_nr is not None and int(extruder_nr) > extruder_count - 1:
|
||||||
|
node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count - 1).getId())
|
||||||
|
|
||||||
|
definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count)
|
||||||
|
|
||||||
|
# Make sure one of the extruder stacks is active
|
||||||
|
extruder_manager.setActiveExtruderIndex(0)
|
||||||
|
|
||||||
|
# Move settable_per_extruder values out of the global container
|
||||||
|
# After CURA-4482 this should not be the case anymore, but we still want to support older project files.
|
||||||
|
global_user_container = self._global_container_stack.getTop()
|
||||||
|
|
||||||
|
# Make sure extruder_stacks exists
|
||||||
|
extruder_stacks = []
|
||||||
|
|
||||||
|
if previous_extruder_count == 1:
|
||||||
|
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
|
global_user_container = self._global_container_stack.getTop()
|
||||||
|
|
||||||
|
for setting_instance in global_user_container.findInstances():
|
||||||
|
setting_key = setting_instance.definition.key
|
||||||
|
settable_per_extruder = self._global_container_stack.getProperty(setting_key, "settable_per_extruder")
|
||||||
|
|
||||||
|
if settable_per_extruder:
|
||||||
|
limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder"))
|
||||||
|
extruder_stack = extruder_stacks[max(0, limit_to_extruder)]
|
||||||
|
extruder_stack.getTop().setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value"))
|
||||||
|
global_user_container.removeInstance(setting_key)
|
||||||
|
|
||||||
|
# Signal that the global stack has changed
|
||||||
|
Application.getInstance().globalContainerStackChanged.emit()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def createMachineManager():
|
def createMachineManager():
|
||||||
return MachineManager()
|
return MachineManager()
|
||||||
|
@ -24,16 +24,49 @@ from cura.Settings.ExtruderStack import ExtruderStack
|
|||||||
from cura.Settings.GlobalStack import GlobalStack
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
from cura.Settings.CuraContainerStack import _ContainerIndexes
|
from cura.Settings.CuraContainerStack import _ContainerIndexes
|
||||||
from cura.QualityManager import QualityManager
|
from cura.QualityManager import QualityManager
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
import zipfile
|
import zipfile
|
||||||
import io
|
import io
|
||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
|
import threading
|
||||||
|
|
||||||
i18n_catalog = i18nCatalog("cura")
|
i18n_catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# HACK:
|
||||||
|
#
|
||||||
|
# In project loading, when override the existing machine is selected, the stacks and containers that are correctly
|
||||||
|
# active in the system will be overridden at runtime. Because the project loading is done in a different thread than
|
||||||
|
# the Qt thread, something else can kick in the middle of the process. One of them is the rendering. It will access
|
||||||
|
# the current stacks and container, which have not completely been updated yet, so Cura will crash in this case.
|
||||||
|
#
|
||||||
|
# This "@call_on_qt_thread" decorator makes sure that a function will always be called on the Qt thread (blocking).
|
||||||
|
# It is applied to the read() function of project loading so it can be guaranteed that only after the project loading
|
||||||
|
# process is completely done, everything else that needs to occupy the QT thread will be executed.
|
||||||
|
#
|
||||||
|
class InterCallObject:
|
||||||
|
def __init__(self):
|
||||||
|
self.finish_event = threading.Event()
|
||||||
|
self.result = None
|
||||||
|
|
||||||
|
|
||||||
|
def call_on_qt_thread(func):
|
||||||
|
def _call_on_qt_thread_wrapper(*args, **kwargs):
|
||||||
|
def _handle_call(ico, *args, **kwargs):
|
||||||
|
ico.result = func(*args, **kwargs)
|
||||||
|
ico.finish_event.set()
|
||||||
|
inter_call_object = InterCallObject()
|
||||||
|
new_args = tuple([inter_call_object] + list(args)[:])
|
||||||
|
CuraApplication.getInstance().callLater(_handle_call, *new_args, **kwargs)
|
||||||
|
inter_call_object.finish_event.wait()
|
||||||
|
return inter_call_object.result
|
||||||
|
return _call_on_qt_thread_wrapper
|
||||||
|
|
||||||
|
|
||||||
## Base implementation for reading 3MF workspace files.
|
## Base implementation for reading 3MF workspace files.
|
||||||
class ThreeMFWorkspaceReader(WorkspaceReader):
|
class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -400,6 +433,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
# containing global.cfg / extruder.cfg
|
# containing global.cfg / extruder.cfg
|
||||||
#
|
#
|
||||||
# \param file_name
|
# \param file_name
|
||||||
|
@call_on_qt_thread
|
||||||
def read(self, file_name):
|
def read(self, file_name):
|
||||||
archive = zipfile.ZipFile(file_name, "r")
|
archive = zipfile.ZipFile(file_name, "r")
|
||||||
|
|
||||||
@ -524,6 +558,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
instance_container_files = [name for name in cura_file_names if name.endswith(self._instance_container_suffix)]
|
instance_container_files = [name for name in cura_file_names if name.endswith(self._instance_container_suffix)]
|
||||||
user_instance_containers = []
|
user_instance_containers = []
|
||||||
quality_and_definition_changes_instance_containers = []
|
quality_and_definition_changes_instance_containers = []
|
||||||
|
quality_changes_instance_containers = []
|
||||||
for instance_container_file in instance_container_files:
|
for instance_container_file in instance_container_files:
|
||||||
container_id = self._stripFileToId(instance_container_file)
|
container_id = self._stripFileToId(instance_container_file)
|
||||||
serialized = archive.open(instance_container_file).read().decode("utf-8")
|
serialized = archive.open(instance_container_file).read().decode("utf-8")
|
||||||
@ -629,6 +664,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
# The ID already exists, but nothing in the values changed, so do nothing.
|
# The ID already exists, but nothing in the values changed, so do nothing.
|
||||||
pass
|
pass
|
||||||
quality_and_definition_changes_instance_containers.append(instance_container)
|
quality_and_definition_changes_instance_containers.append(instance_container)
|
||||||
|
if container_type == "quality_changes":
|
||||||
|
quality_changes_instance_containers.append(instance_container)
|
||||||
|
|
||||||
if container_type == "definition_changes":
|
if container_type == "definition_changes":
|
||||||
definition_changes_extruder_count = instance_container.getProperty("machine_extruder_count", "value")
|
definition_changes_extruder_count = instance_container.getProperty("machine_extruder_count", "value")
|
||||||
@ -684,7 +721,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
stack.setName(global_stack_name_new)
|
stack.setName(global_stack_name_new)
|
||||||
|
|
||||||
container_stacks_added.append(stack)
|
container_stacks_added.append(stack)
|
||||||
self._container_registry.addContainer(stack)
|
# self._container_registry.addContainer(stack)
|
||||||
containers_added.append(stack)
|
containers_added.append(stack)
|
||||||
else:
|
else:
|
||||||
Logger.log("e", "Resolve strategy of %s for machine is not supported", self._resolve_strategies["machine"])
|
Logger.log("e", "Resolve strategy of %s for machine is not supported", self._resolve_strategies["machine"])
|
||||||
@ -702,6 +739,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# load extruder stack files
|
# load extruder stack files
|
||||||
|
has_extruder_stack_files = len(extruder_stack_files) > 0
|
||||||
|
empty_quality_container = self._container_registry.findInstanceContainers(id = "empty_quality")[0]
|
||||||
|
empty_quality_changes_container = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0]
|
||||||
try:
|
try:
|
||||||
for extruder_stack_file in extruder_stack_files:
|
for extruder_stack_file in extruder_stack_files:
|
||||||
container_id = self._stripFileToId(extruder_stack_file)
|
container_id = self._stripFileToId(extruder_stack_file)
|
||||||
@ -750,8 +790,24 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
# If not extruder stacks were saved in the project file (pre 3.1) create one manually
|
# If not extruder stacks were saved in the project file (pre 3.1) create one manually
|
||||||
# We re-use the container registry's addExtruderStackForSingleExtrusionMachine method for this
|
# We re-use the container registry's addExtruderStackForSingleExtrusionMachine method for this
|
||||||
if not extruder_stacks:
|
if not extruder_stacks:
|
||||||
stack = self._container_registry.addExtruderStackForSingleExtrusionMachine(global_stack, "fdmextruder")
|
# If we choose to override a machine but to create a new custom quality profile, the custom quality
|
||||||
if stack:
|
# profile is not immediately applied to the global_stack, so this fix for single extrusion machines
|
||||||
|
# will use the current custom quality profile on the existing machine. The extra optional argument
|
||||||
|
# in that function is used in this case to specify a new global stack quality_changes container so
|
||||||
|
# the fix can correctly create and copy over the custom quality settings to the newly created extruder.
|
||||||
|
new_global_quality_changes = None
|
||||||
|
if self._resolve_strategies["quality_changes"] == "new" and len(quality_changes_instance_containers) > 0:
|
||||||
|
new_global_quality_changes = quality_changes_instance_containers[0]
|
||||||
|
|
||||||
|
# Depending if the strategy is to create a new or override, the ids must be or not be unique
|
||||||
|
stack = self._container_registry.addExtruderStackForSingleExtrusionMachine(global_stack, "fdmextruder",
|
||||||
|
new_global_quality_changes,
|
||||||
|
create_new_ids = self._resolve_strategies["machine"] == "new")
|
||||||
|
if new_global_quality_changes is not None:
|
||||||
|
quality_changes_instance_containers.append(stack.qualityChanges)
|
||||||
|
quality_and_definition_changes_instance_containers.append(stack.qualityChanges)
|
||||||
|
if global_stack.quality.getId() in ("empty", "empty_quality"):
|
||||||
|
stack.quality = empty_quality_container
|
||||||
if self._resolve_strategies["machine"] == "override":
|
if self._resolve_strategies["machine"] == "override":
|
||||||
# in case the extruder is newly created (for a single-extrusion machine), we need to override
|
# in case the extruder is newly created (for a single-extrusion machine), we need to override
|
||||||
# the existing extruder stack.
|
# the existing extruder stack.
|
||||||
@ -769,6 +825,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
self._container_registry.removeContainer(container.getId())
|
self._container_registry.removeContainer(container.getId())
|
||||||
return
|
return
|
||||||
|
|
||||||
|
## In case there is a new machine and once the extruders are created, the global stack is added to the registry,
|
||||||
|
# otherwise the accContainers function in CuraContainerRegistry will create an extruder stack and then creating
|
||||||
|
# useless files
|
||||||
|
if self._resolve_strategies["machine"] == "new":
|
||||||
|
self._container_registry.addContainer(global_stack)
|
||||||
|
|
||||||
# Check quality profiles to make sure that if one stack has the "not supported" quality profile,
|
# Check quality profiles to make sure that if one stack has the "not supported" quality profile,
|
||||||
# all others should have the same.
|
# all others should have the same.
|
||||||
@ -801,17 +862,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
quality_has_been_changed = False
|
quality_has_been_changed = False
|
||||||
|
|
||||||
if has_not_supported:
|
if has_not_supported:
|
||||||
empty_quality_container = self._container_registry.findInstanceContainers(id = "empty_quality")[0]
|
|
||||||
for stack in [global_stack] + extruder_stacks_in_use:
|
for stack in [global_stack] + extruder_stacks_in_use:
|
||||||
stack.replaceContainer(_ContainerIndexes.Quality, empty_quality_container)
|
stack.replaceContainer(_ContainerIndexes.Quality, empty_quality_container)
|
||||||
empty_quality_changes_container = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0]
|
|
||||||
for stack in [global_stack] + extruder_stacks_in_use:
|
|
||||||
stack.replaceContainer(_ContainerIndexes.QualityChanges, empty_quality_changes_container)
|
stack.replaceContainer(_ContainerIndexes.QualityChanges, empty_quality_changes_container)
|
||||||
quality_has_been_changed = True
|
quality_has_been_changed = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
empty_quality_changes_container = self._container_registry.findInstanceContainers(id="empty_quality_changes")[0]
|
|
||||||
|
|
||||||
# The machine in the project has non-empty quality and there are usable qualities for this machine.
|
# The machine in the project has non-empty quality and there are usable qualities for this machine.
|
||||||
# We need to check if the current quality_type is still usable for this machine, if not, then the quality
|
# We need to check if the current quality_type is still usable for this machine, if not, then the quality
|
||||||
# will be reset to the "preferred quality" if present, otherwise "normal".
|
# will be reset to the "preferred quality" if present, otherwise "normal".
|
||||||
@ -922,9 +978,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
|
|
||||||
# sanity checks
|
# sanity checks
|
||||||
# NOTE: The following cases SHOULD NOT happen!!!!
|
# NOTE: The following cases SHOULD NOT happen!!!!
|
||||||
if not old_container:
|
if old_container.getId() in ("empty_quality_changes", "empty_definition_changes", "empty"):
|
||||||
Logger.log("e", "We try to get [%s] from the global stack [%s] but we got None instead!",
|
Logger.log("e", "We try to get [%s] from the global stack [%s] but we got None instead!",
|
||||||
changes_container_type, global_stack.getId())
|
changes_container_type, global_stack.getId())
|
||||||
|
continue
|
||||||
|
|
||||||
# Replace the quality/definition changes container if it's in the GlobalStack
|
# Replace the quality/definition changes container if it's in the GlobalStack
|
||||||
# NOTE: we can get an empty container here, but the IDs will not match,
|
# NOTE: we can get an empty container here, but the IDs will not match,
|
||||||
@ -937,6 +994,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Replace the quality/definition changes container if it's in one of the ExtruderStacks
|
# Replace the quality/definition changes container if it's in one of the ExtruderStacks
|
||||||
|
# Only apply the change if we have loaded extruder stacks from the project
|
||||||
|
if has_extruder_stack_files:
|
||||||
for each_extruder_stack in extruder_stacks:
|
for each_extruder_stack in extruder_stacks:
|
||||||
changes_container = None
|
changes_container = None
|
||||||
if changes_container_type == "quality_changes":
|
if changes_container_type == "quality_changes":
|
||||||
@ -946,9 +1005,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
|
|
||||||
# sanity checks
|
# sanity checks
|
||||||
# NOTE: The following cases SHOULD NOT happen!!!!
|
# NOTE: The following cases SHOULD NOT happen!!!!
|
||||||
if not changes_container:
|
if changes_container.getId() in ("empty_quality_changes", "empty_definition_changes", "empty"):
|
||||||
Logger.log("e", "We try to get [%s] from the extruder stack [%s] but we got None instead!",
|
Logger.log("e", "We try to get [%s] from the extruder stack [%s] but we got None instead!",
|
||||||
changes_container_type, each_extruder_stack.getId())
|
changes_container_type, each_extruder_stack.getId())
|
||||||
|
continue
|
||||||
|
|
||||||
# NOTE: we can get an empty container here, but the IDs will not match,
|
# NOTE: we can get an empty container here, but the IDs will not match,
|
||||||
# so this comparison is fine.
|
# so this comparison is fine.
|
||||||
@ -991,6 +1051,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
for stack in extruder_stacks:
|
for stack in extruder_stacks:
|
||||||
stack.setNextStack(global_stack)
|
stack.setNextStack(global_stack)
|
||||||
stack.containersChanged.emit(stack.getTop())
|
stack.containersChanged.emit(stack.getTop())
|
||||||
|
else:
|
||||||
|
CuraApplication.getInstance().getMachineManager().activeQualityChanged.emit()
|
||||||
|
|
||||||
# Actually change the active machine.
|
# Actually change the active machine.
|
||||||
Application.getInstance().setGlobalContainerStack(global_stack)
|
Application.getInstance().setGlobalContainerStack(global_stack)
|
||||||
@ -1040,13 +1102,13 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||||||
# find the old material ID
|
# find the old material ID
|
||||||
old_material_id_in_stack = stack.material.getId()
|
old_material_id_in_stack = stack.material.getId()
|
||||||
best_matching_old_material_id = None
|
best_matching_old_material_id = None
|
||||||
best_matching_old_meterial_prefix_length = -1
|
best_matching_old_material_prefix_length = -1
|
||||||
for old_parent_material_id in old_new_material_dict:
|
for old_parent_material_id in old_new_material_dict:
|
||||||
if len(old_parent_material_id) < best_matching_old_meterial_prefix_length:
|
if len(old_parent_material_id) < best_matching_old_material_prefix_length:
|
||||||
continue
|
continue
|
||||||
if len(old_parent_material_id) <= len(old_material_id_in_stack):
|
if len(old_parent_material_id) <= len(old_material_id_in_stack):
|
||||||
if old_parent_material_id == old_material_id_in_stack[0:len(old_parent_material_id)]:
|
if old_parent_material_id == old_material_id_in_stack[0:len(old_parent_material_id)]:
|
||||||
best_matching_old_meterial_prefix_length = len(old_parent_material_id)
|
best_matching_old_material_prefix_length = len(old_parent_material_id)
|
||||||
best_matching_old_material_id = old_parent_material_id
|
best_matching_old_material_id = old_parent_material_id
|
||||||
|
|
||||||
if best_matching_old_material_id is None:
|
if best_matching_old_material_id is None:
|
||||||
|
@ -390,6 +390,13 @@ UM.Dialog
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function accept() {
|
||||||
|
manager.closeBackend();
|
||||||
|
manager.onOkButtonClicked();
|
||||||
|
base.visible = false;
|
||||||
|
base.accept();
|
||||||
|
}
|
||||||
|
|
||||||
function reject() {
|
function reject() {
|
||||||
manager.onCancelButtonClicked();
|
manager.onCancelButtonClicked();
|
||||||
base.visible = false;
|
base.visible = false;
|
||||||
|
@ -97,7 +97,7 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
|||||||
file_in_archive.compress_type = zipfile.ZIP_DEFLATED
|
file_in_archive.compress_type = zipfile.ZIP_DEFLATED
|
||||||
|
|
||||||
# Do not include the network authentication keys
|
# Do not include the network authentication keys
|
||||||
ignore_keys = {"network_authentication_id", "network_authentication_key"}
|
ignore_keys = {"network_authentication_id", "network_authentication_key", "octoprint_api_key"}
|
||||||
serialized_data = container.serialize(ignored_metadata_keys = ignore_keys)
|
serialized_data = container.serialize(ignored_metadata_keys = ignore_keys)
|
||||||
|
|
||||||
archive.writestr(file_in_archive, serialized_data)
|
archive.writestr(file_in_archive, serialized_data)
|
||||||
|
@ -291,6 +291,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||||||
self._start_slice_job = None
|
self._start_slice_job = None
|
||||||
|
|
||||||
if job.isCancelled() or job.getError() or job.getResult() == StartSliceJob.StartJobResult.Error:
|
if job.isCancelled() or job.getError() or job.getResult() == StartSliceJob.StartJobResult.Error:
|
||||||
|
self.backendStateChange.emit(BackendState.Error)
|
||||||
return
|
return
|
||||||
|
|
||||||
if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible:
|
if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible:
|
||||||
@ -426,6 +427,11 @@ class CuraEngineBackend(QObject, Backend):
|
|||||||
if not isinstance(source, SceneNode):
|
if not isinstance(source, SceneNode):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# This case checks if the source node is a node that contains GCode. In this case the
|
||||||
|
# current layer data is removed so the previous data is not rendered - CURA-4821
|
||||||
|
if source.callDecoration("isBlockSlicing") and source.callDecoration("getLayerData"):
|
||||||
|
self._stored_optimized_layer_data = {}
|
||||||
|
|
||||||
build_plate_changed = set()
|
build_plate_changed = set()
|
||||||
source_build_plate_number = source.callDecoration("getBuildPlateNumber")
|
source_build_plate_number = source.callDecoration("getBuildPlateNumber")
|
||||||
if source == self._scene.getRoot():
|
if source == self._scene.getRoot():
|
||||||
|
@ -15,7 +15,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
|||||||
from UM.Settings.Validator import ValidatorState
|
from UM.Settings.Validator import ValidatorState
|
||||||
from UM.Settings.SettingRelation import RelationType
|
from UM.Settings.SettingRelation import RelationType
|
||||||
|
|
||||||
from cura.Scene.CuraSceneNode import CuraSceneNode as SceneNode
|
from cura.Scene.CuraSceneNode import CuraSceneNode
|
||||||
from cura.OneAtATimeIterator import OneAtATimeIterator
|
from cura.OneAtATimeIterator import OneAtATimeIterator
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ class StartSliceJob(Job):
|
|||||||
|
|
||||||
# Don't slice if there is a per object setting with an error value.
|
# Don't slice if there is a per object setting with an error value.
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
if type(node) is not SceneNode or not node.isSelectable():
|
if type(node) is not CuraSceneNode or not node.isSelectable():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self._checkStackForErrors(node.callDecoration("getStack")):
|
if self._checkStackForErrors(node.callDecoration("getStack")):
|
||||||
@ -161,10 +161,15 @@ class StartSliceJob(Job):
|
|||||||
if getattr(node, "_outside_buildarea", False):
|
if getattr(node, "_outside_buildarea", False):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# Filter on current build plate
|
||||||
|
build_plate_number = node.callDecoration("getBuildPlateNumber")
|
||||||
|
if build_plate_number is not None and build_plate_number != self._build_plate_number:
|
||||||
|
continue
|
||||||
|
|
||||||
children = node.getAllChildren()
|
children = node.getAllChildren()
|
||||||
children.append(node)
|
children.append(node)
|
||||||
for child_node in children:
|
for child_node in children:
|
||||||
if type(child_node) is SceneNode and child_node.getMeshData() and child_node.getMeshData().getVertices() is not None:
|
if type(child_node) is CuraSceneNode and child_node.getMeshData() and child_node.getMeshData().getVertices() is not None:
|
||||||
temp_list.append(child_node)
|
temp_list.append(child_node)
|
||||||
|
|
||||||
if temp_list:
|
if temp_list:
|
||||||
@ -176,7 +181,7 @@ class StartSliceJob(Job):
|
|||||||
temp_list = []
|
temp_list = []
|
||||||
has_printing_mesh = False
|
has_printing_mesh = False
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
if node.callDecoration("isSliceable") and type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
if node.callDecoration("isSliceable") and type(node) is CuraSceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
||||||
per_object_stack = node.callDecoration("getStack")
|
per_object_stack = node.callDecoration("getStack")
|
||||||
is_non_printing_mesh = False
|
is_non_printing_mesh = False
|
||||||
if per_object_stack:
|
if per_object_stack:
|
||||||
|
@ -49,7 +49,6 @@ class FirmwareUpdateChecker(Extension):
|
|||||||
def _onContainerAdded(self, container):
|
def _onContainerAdded(self, container):
|
||||||
# Only take care when a new GlobalStack was added
|
# Only take care when a new GlobalStack was added
|
||||||
if isinstance(container, GlobalStack):
|
if isinstance(container, GlobalStack):
|
||||||
Logger.log("i", "You have a '%s' in printer list. Let's check the firmware!", container.getId())
|
|
||||||
self.checkFirmwareVersion(container, True)
|
self.checkFirmwareVersion(container, True)
|
||||||
|
|
||||||
## Connect with software.ultimaker.com, load latest.version and check version info.
|
## Connect with software.ultimaker.com, load latest.version and check version info.
|
||||||
|
@ -44,6 +44,8 @@ class FirmwareUpdateCheckerJob(Job):
|
|||||||
# Now we just do that if the active printer is Ultimaker 3 or Ultimaker 3 Extended or any
|
# Now we just do that if the active printer is Ultimaker 3 or Ultimaker 3 Extended or any
|
||||||
# other Ultimaker 3 that will come in the future
|
# other Ultimaker 3 that will come in the future
|
||||||
if len(machine_name_parts) >= 2 and machine_name_parts[:2] == ["ultimaker", "3"]:
|
if len(machine_name_parts) >= 2 and machine_name_parts[:2] == ["ultimaker", "3"]:
|
||||||
|
Logger.log("i", "You have a UM3 in printer list. Let's check the firmware!")
|
||||||
|
|
||||||
# Nothing to parse, just get the string
|
# Nothing to parse, just get the string
|
||||||
# TODO: In the future may be done by parsing a JSON file with diferent version for each printer model
|
# TODO: In the future may be done by parsing a JSON file with diferent version for each printer model
|
||||||
current_version = reader(current_version_file).readline().rstrip()
|
current_version = reader(current_version_file).readline().rstrip()
|
||||||
|
@ -107,7 +107,7 @@ class GCodeWriter(MeshWriter):
|
|||||||
prefix_length = len(prefix)
|
prefix_length = len(prefix)
|
||||||
|
|
||||||
container_with_profile = stack.qualityChanges
|
container_with_profile = stack.qualityChanges
|
||||||
if not container_with_profile:
|
if container_with_profile.getId() == "empty_quality_changes":
|
||||||
Logger.log("e", "No valid quality profile found, not writing settings to GCode!")
|
Logger.log("e", "No valid quality profile found, not writing settings to GCode!")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@ -123,9 +123,9 @@ class GCodeWriter(MeshWriter):
|
|||||||
serialized = flat_global_container.serialize()
|
serialized = flat_global_container.serialize()
|
||||||
data = {"global_quality": serialized}
|
data = {"global_quality": serialized}
|
||||||
|
|
||||||
for extruder in sorted(ExtruderManager.getInstance().getMachineExtruders(stack.getId()), key = lambda k: k.getMetaDataEntry("position")):
|
for extruder in sorted(stack.extruders.values(), key = lambda k: k.getMetaDataEntry("position")):
|
||||||
extruder_quality = extruder.qualityChanges
|
extruder_quality = extruder.qualityChanges
|
||||||
if not extruder_quality:
|
if extruder_quality.getId() == "empty_quality_changes":
|
||||||
Logger.log("w", "No extruder quality profile found, not writing quality for extruder %s to file!", extruder.getId())
|
Logger.log("w", "No extruder quality profile found, not writing quality for extruder %s to file!", extruder.getId())
|
||||||
continue
|
continue
|
||||||
flat_extruder_quality = self._createFlattenedContainerInstance(extruder.getTop(), extruder_quality)
|
flat_extruder_quality = self._createFlattenedContainerInstance(extruder.getTop(), extruder_quality)
|
||||||
|
@ -105,60 +105,9 @@ class MachineSettingsAction(MachineAction):
|
|||||||
|
|
||||||
@pyqtSlot(int)
|
@pyqtSlot(int)
|
||||||
def setMachineExtruderCount(self, extruder_count):
|
def setMachineExtruderCount(self, extruder_count):
|
||||||
extruder_manager = Application.getInstance().getExtruderManager()
|
# Note: this method was in this class before, but since it's quite generic and other plugins also need it
|
||||||
|
# it was moved to the machine manager instead. Now this method just calls the machine manager.
|
||||||
definition_changes_container = self._global_container_stack.definitionChanges
|
Application.getInstance().getMachineManager().setActiveMachineExtruderCount(extruder_count)
|
||||||
if not self._global_container_stack or definition_changes_container == self._empty_container:
|
|
||||||
return
|
|
||||||
|
|
||||||
previous_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
|
|
||||||
if extruder_count == previous_extruder_count:
|
|
||||||
return
|
|
||||||
|
|
||||||
# reset all extruder number settings whose value is no longer valid
|
|
||||||
for setting_instance in self._global_container_stack.userChanges.findInstances():
|
|
||||||
setting_key = setting_instance.definition.key
|
|
||||||
if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
old_value = int(self._global_container_stack.userChanges.getProperty(setting_key, "value"))
|
|
||||||
if old_value >= extruder_count:
|
|
||||||
self._global_container_stack.userChanges.removeInstance(setting_key)
|
|
||||||
Logger.log("d", "Reset [%s] because its old value [%s] is no longer valid ", setting_key, old_value)
|
|
||||||
|
|
||||||
# Check to see if any objects are set to print with an extruder that will no longer exist
|
|
||||||
root_node = Application.getInstance().getController().getScene().getRoot()
|
|
||||||
for node in DepthFirstIterator(root_node):
|
|
||||||
if node.getMeshData():
|
|
||||||
extruder_nr = node.callDecoration("getActiveExtruderPosition")
|
|
||||||
|
|
||||||
if extruder_nr is not None and int(extruder_nr) > extruder_count - 1:
|
|
||||||
node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count - 1).getId())
|
|
||||||
|
|
||||||
definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count)
|
|
||||||
|
|
||||||
# Make sure one of the extruder stacks is active
|
|
||||||
extruder_manager.setActiveExtruderIndex(0)
|
|
||||||
|
|
||||||
# Move settable_per_extruder values out of the global container
|
|
||||||
# After CURA-4482 this should not be the case anymore, but we still want to support older project files.
|
|
||||||
global_user_container = self._global_container_stack.getTop()
|
|
||||||
|
|
||||||
if previous_extruder_count == 1:
|
|
||||||
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
|
||||||
global_user_container = self._global_container_stack.getTop()
|
|
||||||
|
|
||||||
for setting_instance in global_user_container.findInstances():
|
|
||||||
setting_key = setting_instance.definition.key
|
|
||||||
settable_per_extruder = self._global_container_stack.getProperty(setting_key, "settable_per_extruder")
|
|
||||||
|
|
||||||
if settable_per_extruder:
|
|
||||||
limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder"))
|
|
||||||
extruder_stack = extruder_stacks[max(0, limit_to_extruder)]
|
|
||||||
extruder_stack.getTop().setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value"))
|
|
||||||
global_user_container.removeInstance(setting_key)
|
|
||||||
|
|
||||||
self.forceUpdate()
|
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def forceUpdate(self):
|
def forceUpdate(self):
|
||||||
@ -209,79 +158,4 @@ class MachineSettingsAction(MachineAction):
|
|||||||
@pyqtSlot(int)
|
@pyqtSlot(int)
|
||||||
def updateMaterialForDiameter(self, extruder_position: int):
|
def updateMaterialForDiameter(self, extruder_position: int):
|
||||||
# Updates the material container to a material that matches the material diameter set for the printer
|
# Updates the material container to a material that matches the material diameter set for the printer
|
||||||
if not self._global_container_stack:
|
Application.getInstance().getExtruderManager().updateMaterialForDiameter(extruder_position)
|
||||||
return
|
|
||||||
|
|
||||||
if not self._global_container_stack.getMetaDataEntry("has_materials", False):
|
|
||||||
return
|
|
||||||
|
|
||||||
extruder_stack = self._global_container_stack.extruders[str(extruder_position)]
|
|
||||||
|
|
||||||
material_diameter = extruder_stack.material.getProperty("material_diameter", "value")
|
|
||||||
if not material_diameter:
|
|
||||||
# in case of "empty" material
|
|
||||||
material_diameter = 0
|
|
||||||
|
|
||||||
material_approximate_diameter = str(round(material_diameter))
|
|
||||||
machine_diameter = extruder_stack.definitionChanges.getProperty("material_diameter", "value")
|
|
||||||
if not machine_diameter:
|
|
||||||
if extruder_stack.definition.hasProperty("material_diameter", "value"):
|
|
||||||
machine_diameter = extruder_stack.definition.getProperty("material_diameter", "value")
|
|
||||||
else:
|
|
||||||
machine_diameter = self._global_container_stack.definition.getProperty("material_diameter", "value")
|
|
||||||
machine_approximate_diameter = str(round(machine_diameter))
|
|
||||||
|
|
||||||
if material_approximate_diameter != machine_approximate_diameter:
|
|
||||||
Logger.log("i", "The the currently active material(s) do not match the diameter set for the printer. Finding alternatives.")
|
|
||||||
|
|
||||||
if self._global_container_stack.getMetaDataEntry("has_machine_materials", False):
|
|
||||||
materials_definition = self._global_container_stack.definition.getId()
|
|
||||||
has_material_variants = self._global_container_stack.getMetaDataEntry("has_variants", False)
|
|
||||||
else:
|
|
||||||
materials_definition = "fdmprinter"
|
|
||||||
has_material_variants = False
|
|
||||||
|
|
||||||
old_material = extruder_stack.material
|
|
||||||
search_criteria = {
|
|
||||||
"type": "material",
|
|
||||||
"approximate_diameter": machine_approximate_diameter,
|
|
||||||
"material": old_material.getMetaDataEntry("material", "value"),
|
|
||||||
"brand": old_material.getMetaDataEntry("brand", "value"),
|
|
||||||
"supplier": old_material.getMetaDataEntry("supplier", "value"),
|
|
||||||
"color_name": old_material.getMetaDataEntry("color_name", "value"),
|
|
||||||
"definition": materials_definition
|
|
||||||
}
|
|
||||||
if has_material_variants:
|
|
||||||
search_criteria["variant"] = extruder_stack.variant.getId()
|
|
||||||
|
|
||||||
if old_material == self._empty_container:
|
|
||||||
search_criteria.pop("material", None)
|
|
||||||
search_criteria.pop("supplier", None)
|
|
||||||
search_criteria.pop("brand", None)
|
|
||||||
search_criteria.pop("definition", None)
|
|
||||||
search_criteria["id"] = extruder_stack.getMetaDataEntry("preferred_material")
|
|
||||||
|
|
||||||
materials = self._container_registry.findInstanceContainers(**search_criteria)
|
|
||||||
if not materials:
|
|
||||||
# Same material with new diameter is not found, search for generic version of the same material type
|
|
||||||
search_criteria.pop("supplier", None)
|
|
||||||
search_criteria.pop("brand", None)
|
|
||||||
search_criteria["color_name"] = "Generic"
|
|
||||||
materials = self._container_registry.findInstanceContainers(**search_criteria)
|
|
||||||
if not materials:
|
|
||||||
# Generic material with new diameter is not found, search for preferred material
|
|
||||||
search_criteria.pop("color_name", None)
|
|
||||||
search_criteria.pop("material", None)
|
|
||||||
search_criteria["id"] = extruder_stack.getMetaDataEntry("preferred_material")
|
|
||||||
materials = self._container_registry.findInstanceContainers(**search_criteria)
|
|
||||||
if not materials:
|
|
||||||
# Preferred material with new diameter is not found, search for any material
|
|
||||||
search_criteria.pop("id", None)
|
|
||||||
materials = self._container_registry.findInstanceContainers(**search_criteria)
|
|
||||||
if not materials:
|
|
||||||
# Just use empty material as a final fallback
|
|
||||||
materials = [self._empty_container]
|
|
||||||
|
|
||||||
Logger.log("i", "Selecting new material: %s", materials[0].getId())
|
|
||||||
|
|
||||||
extruder_stack.material = materials[0]
|
|
||||||
|
@ -390,7 +390,7 @@ Cura.MachineAction
|
|||||||
visible: Cura.MachineManager.hasMaterials
|
visible: Cura.MachineManager.hasMaterials
|
||||||
sourceComponent: numericTextFieldWithUnit
|
sourceComponent: numericTextFieldWithUnit
|
||||||
property string settingKey: "material_diameter"
|
property string settingKey: "material_diameter"
|
||||||
property string label: catalog.i18nc("@label", "Material diameter")
|
property string label: catalog.i18nc("@label", "Compatible material diameter")
|
||||||
property string unit: catalog.i18nc("@label", "mm")
|
property string unit: catalog.i18nc("@label", "mm")
|
||||||
property string tooltip: catalog.i18nc("@tooltip", "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile.")
|
property string tooltip: catalog.i18nc("@tooltip", "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile.")
|
||||||
function afterOnEditingFinished()
|
function afterOnEditingFinished()
|
||||||
|
@ -25,7 +25,7 @@ class PluginBrowser(QObject, Extension):
|
|||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
self._api_version = 2
|
self._api_version = 4
|
||||||
self._api_url = "http://software.ultimaker.com/cura/v%s/" % self._api_version
|
self._api_url = "http://software.ultimaker.com/cura/v%s/" % self._api_version
|
||||||
|
|
||||||
self._plugin_list_request = None
|
self._plugin_list_request = None
|
||||||
|
@ -98,11 +98,14 @@ class SimulationView(View):
|
|||||||
|
|
||||||
self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count"))
|
self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count"))
|
||||||
self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers"))
|
self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers"))
|
||||||
self._compatibility_mode = True # for safety
|
self._compatibility_mode = self._evaluateCompatibilityMode()
|
||||||
|
|
||||||
self._wireprint_warning_message = Message(catalog.i18nc("@info:status", "Cura does not accurately display layers when Wire Printing is enabled"),
|
self._wireprint_warning_message = Message(catalog.i18nc("@info:status", "Cura does not accurately display layers when Wire Printing is enabled"),
|
||||||
title = catalog.i18nc("@info:title", "Simulation View"))
|
title = catalog.i18nc("@info:title", "Simulation View"))
|
||||||
|
|
||||||
|
def _evaluateCompatibilityMode(self):
|
||||||
|
return OpenGLContext.isLegacyOpenGL() or bool(Preferences.getInstance().getValue("view/force_layer_view_compatibility_mode"))
|
||||||
|
|
||||||
def _resetSettings(self):
|
def _resetSettings(self):
|
||||||
self._layer_view_type = 0 # 0 is material color, 1 is color by linetype, 2 is speed, 3 is layer thickness
|
self._layer_view_type = 0 # 0 is material color, 1 is color by linetype, 2 is speed, 3 is layer thickness
|
||||||
self._extruder_count = 0
|
self._extruder_count = 0
|
||||||
@ -127,7 +130,7 @@ class SimulationView(View):
|
|||||||
# Currently the RenderPass constructor requires a size > 0
|
# Currently the RenderPass constructor requires a size > 0
|
||||||
# This should be fixed in RenderPass's constructor.
|
# This should be fixed in RenderPass's constructor.
|
||||||
self._layer_pass = SimulationPass(1, 1)
|
self._layer_pass = SimulationPass(1, 1)
|
||||||
self._compatibility_mode = OpenGLContext.isLegacyOpenGL() or bool(Preferences.getInstance().getValue("view/force_layer_view_compatibility_mode"))
|
self._compatibility_mode = self._evaluateCompatibilityMode()
|
||||||
self._layer_pass.setSimulationView(self)
|
self._layer_pass.setSimulationView(self)
|
||||||
return self._layer_pass
|
return self._layer_pass
|
||||||
|
|
||||||
@ -534,8 +537,7 @@ class SimulationView(View):
|
|||||||
def _updateWithPreferences(self):
|
def _updateWithPreferences(self):
|
||||||
self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count"))
|
self._solid_layers = int(Preferences.getInstance().getValue("view/top_layer_count"))
|
||||||
self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers"))
|
self._only_show_top_layers = bool(Preferences.getInstance().getValue("view/only_show_top_layers"))
|
||||||
self._compatibility_mode = OpenGLContext.isLegacyOpenGL() or bool(
|
self._compatibility_mode = self._evaluateCompatibilityMode()
|
||||||
Preferences.getInstance().getValue("view/force_layer_view_compatibility_mode"))
|
|
||||||
|
|
||||||
self.setSimulationViewType(int(float(Preferences.getInstance().getValue("layerview/layer_view_type"))));
|
self.setSimulationViewType(int(float(Preferences.getInstance().getValue("layerview/layer_view_type"))));
|
||||||
|
|
||||||
|
@ -485,7 +485,7 @@ Item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gradient colors for layer thickness
|
// Gradient colors for layer thickness (similar to parula colormap)
|
||||||
Rectangle { // In QML 5.9 can be changed by LinearGradient
|
Rectangle { // In QML 5.9 can be changed by LinearGradient
|
||||||
// Invert values because then the bar is rotated 90 degrees
|
// Invert values because then the bar is rotated 90 degrees
|
||||||
id: thicknessGradient
|
id: thicknessGradient
|
||||||
@ -499,23 +499,23 @@ Item
|
|||||||
gradient: Gradient {
|
gradient: Gradient {
|
||||||
GradientStop {
|
GradientStop {
|
||||||
position: 0.000
|
position: 0.000
|
||||||
color: Qt.rgba(1, 0, 0, 1)
|
color: Qt.rgba(1, 1, 0, 1)
|
||||||
}
|
}
|
||||||
GradientStop {
|
GradientStop {
|
||||||
position: 0.25
|
position: 0.25
|
||||||
color: Qt.rgba(0.5, 0.5, 0, 1)
|
color: Qt.rgba(1, 0.75, 0.25, 1)
|
||||||
}
|
}
|
||||||
GradientStop {
|
GradientStop {
|
||||||
position: 0.5
|
position: 0.5
|
||||||
color: Qt.rgba(0, 1, 0, 1)
|
color: Qt.rgba(0, 0.75, 0.5, 1)
|
||||||
}
|
}
|
||||||
GradientStop {
|
GradientStop {
|
||||||
position: 0.75
|
position: 0.75
|
||||||
color: Qt.rgba(0, 0.5, 0.5, 1)
|
color: Qt.rgba(0, 0.375, 0.75, 1)
|
||||||
}
|
}
|
||||||
GradientStop {
|
GradientStop {
|
||||||
position: 1.0
|
position: 1.0
|
||||||
color: Qt.rgba(0, 0, 1, 1)
|
color: Qt.rgba(0, 0, 0.5, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,9 +54,13 @@ vertex41core =
|
|||||||
vec4 layerThicknessGradientColor(float abs_value, float min_value, float max_value)
|
vec4 layerThicknessGradientColor(float abs_value, float min_value, float max_value)
|
||||||
{
|
{
|
||||||
float value = (abs_value - min_value)/(max_value - min_value);
|
float value = (abs_value - min_value)/(max_value - min_value);
|
||||||
float red = max(2*value-1, 0);
|
float red = min(max(4*value-2, 0), 1);
|
||||||
float green = 1-abs(1-2*value);
|
float green = min(1.5*value, 0.75);
|
||||||
float blue = max(1-2*value, 0);
|
if (value > 0.75)
|
||||||
|
{
|
||||||
|
green = value;
|
||||||
|
}
|
||||||
|
float blue = 0.75-abs(0.25-value);
|
||||||
return vec4(red, green, blue, 1.0);
|
return vec4(red, green, blue, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ class SliceInfo(Extension):
|
|||||||
"brand": extruder.material.getMetaData().get("brand", "")
|
"brand": extruder.material.getMetaData().get("brand", "")
|
||||||
}
|
}
|
||||||
extruder_position = int(extruder.getMetaDataEntry("position", "0"))
|
extruder_position = int(extruder.getMetaDataEntry("position", "0"))
|
||||||
if extruder_position in print_information.materialLengths:
|
if len(print_information.materialLengths) > extruder_position:
|
||||||
extruder_dict["material_used"] = print_information.materialLengths[extruder_position]
|
extruder_dict["material_used"] = print_information.materialLengths[extruder_position]
|
||||||
extruder_dict["variant"] = extruder.variant.getName()
|
extruder_dict["variant"] = extruder.variant.getName()
|
||||||
extruder_dict["nozzle_size"] = extruder.getProperty("machine_nozzle_size", "value")
|
extruder_dict["nozzle_size"] = extruder.getProperty("machine_nozzle_size", "value")
|
||||||
|
68
plugins/UCPWriter/UCPWriter.py
Normal file
68
plugins/UCPWriter/UCPWriter.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import zipfile
|
||||||
|
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
from UM.Resources import Resources
|
||||||
|
from UM.Mesh.MeshWriter import MeshWriter
|
||||||
|
from UM.Logger import Logger
|
||||||
|
from UM.PluginRegistry import PluginRegistry
|
||||||
|
|
||||||
|
MYPY = False
|
||||||
|
try:
|
||||||
|
if not MYPY:
|
||||||
|
import xml.etree.cElementTree as ET
|
||||||
|
except ImportError:
|
||||||
|
Logger.log("w", "Unable to load cElementTree, switching to slower version")
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
|
||||||
|
class UCPWriter(MeshWriter):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self._namespaces = {
|
||||||
|
"content-types": "http://schemas.openxmlformats.org/package/2006/content-types",
|
||||||
|
"relationships": "http://schemas.openxmlformats.org/package/2006/relationships",
|
||||||
|
}
|
||||||
|
|
||||||
|
def write(self, stream, nodes, mode = MeshWriter.OutputMode.BinaryMode):
|
||||||
|
self._archive = None # Reset archive
|
||||||
|
archive = zipfile.ZipFile(stream, "w", compression=zipfile.ZIP_DEFLATED)
|
||||||
|
|
||||||
|
gcode_file = zipfile.ZipInfo("3D/model.gcode")
|
||||||
|
gcode_file.compress_type = zipfile.ZIP_DEFLATED
|
||||||
|
|
||||||
|
# Create content types file
|
||||||
|
content_types_file = zipfile.ZipInfo("[Content_Types].xml")
|
||||||
|
content_types_file.compress_type = zipfile.ZIP_DEFLATED
|
||||||
|
content_types = ET.Element("Types", xmlns=self._namespaces["content-types"])
|
||||||
|
|
||||||
|
rels_type = ET.SubElement(content_types, "Default", Extension="rels",
|
||||||
|
ContentType="application/vnd.openxmlformats-package.relationships+xml")
|
||||||
|
gcode_type = ET.SubElement(content_types, "Default", Extension="gcode",
|
||||||
|
ContentType="text/x-gcode")
|
||||||
|
image_type = ET.SubElement(content_types, "Default", Extension="png",
|
||||||
|
ContentType="image/png")
|
||||||
|
|
||||||
|
# Create _rels/.rels file
|
||||||
|
relations_file = zipfile.ZipInfo("_rels/.rels")
|
||||||
|
relations_file.compress_type = zipfile.ZIP_DEFLATED
|
||||||
|
relations_element = ET.Element("Relationships", xmlns=self._namespaces["relationships"])
|
||||||
|
|
||||||
|
thumbnail_relation_element = ET.SubElement(relations_element, "Relationship", Target="/Metadata/thumbnail.png", Id="rel0",
|
||||||
|
Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail")
|
||||||
|
|
||||||
|
model_relation_element = ET.SubElement(relations_element, "Relationship", Target="/3D/model.gcode",
|
||||||
|
Id="rel1",
|
||||||
|
Type="http://schemas.ultimaker.org/package/2018/relationships/gcode")
|
||||||
|
|
||||||
|
gcode_string = StringIO()
|
||||||
|
|
||||||
|
PluginRegistry.getInstance().getPluginObject("GCodeWriter").write(gcode_string, None)
|
||||||
|
|
||||||
|
archive.write(Resources.getPath(Resources.Images, "cura-icon.png"), "Metadata/thumbnail.png")
|
||||||
|
|
||||||
|
archive.writestr(gcode_file, gcode_string.getvalue())
|
||||||
|
archive.writestr(content_types_file, b'<?xml version="1.0" encoding="UTF-8"?> \n' + ET.tostring(content_types))
|
||||||
|
archive.writestr(relations_file, b'<?xml version="1.0" encoding="UTF-8"?> \n' + ET.tostring(relations_element))
|
||||||
|
|
||||||
|
archive.close()
|
25
plugins/UCPWriter/__init__.py
Normal file
25
plugins/UCPWriter/__init__.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
|
# Uranium is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
from . import UCPWriter
|
||||||
|
|
||||||
|
from UM.i18n import i18nCatalog
|
||||||
|
|
||||||
|
i18n_catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
def getMetaData():
|
||||||
|
return {
|
||||||
|
"mesh_writer": {
|
||||||
|
"output": [
|
||||||
|
{
|
||||||
|
"mime_type": "application/x-ucp",
|
||||||
|
"mode": UCPWriter.UCPWriter.OutputMode.BinaryMode,
|
||||||
|
"extension": "UCP",
|
||||||
|
"description": i18n_catalog.i18nc("@item:inlistbox", "UCP File (WIP)")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def register(app):
|
||||||
|
return { "mesh_writer": UCPWriter.UCPWriter() }
|
8
plugins/UCPWriter/plugin.json
Normal file
8
plugins/UCPWriter/plugin.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "UCP Writer",
|
||||||
|
"author": "Ultimaker B.V.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Provides support for writing UCP files.",
|
||||||
|
"api": 4,
|
||||||
|
"i18n-catalog": "cura"
|
||||||
|
}
|
@ -287,6 +287,10 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
|
|||||||
self._updatePrintJob(print_job, print_job_data)
|
self._updatePrintJob(print_job, print_job_data)
|
||||||
|
|
||||||
if print_job.state != "queued": # Print job should be assigned to a printer.
|
if print_job.state != "queued": # Print job should be assigned to a printer.
|
||||||
|
if print_job.state == "failed":
|
||||||
|
# Print job was failed, so don't attach it to a printer.
|
||||||
|
printer = None
|
||||||
|
else:
|
||||||
printer = self._getPrinterByKey(print_job_data["printer_uuid"])
|
printer = self._getPrinterByKey(print_job_data["printer_uuid"])
|
||||||
else: # The job can "reserve" a printer if some changes are required.
|
else: # The job can "reserve" a printer if some changes are required.
|
||||||
printer = self._getPrinterByKey(print_job_data["assigned_to"])
|
printer = self._getPrinterByKey(print_job_data["assigned_to"])
|
||||||
|
@ -541,7 +541,6 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
Logger.log("w", "No definition found for machine ID %s", machine_id)
|
Logger.log("w", "No definition found for machine ID %s", machine_id)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
Logger.log("d", "Found definition for machine ID %s", machine_id)
|
|
||||||
definition = definitions[0]
|
definition = definitions[0]
|
||||||
|
|
||||||
machine_manufacturer = identifier.get("manufacturer", definition.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition.
|
machine_manufacturer = identifier.get("manufacturer", definition.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition.
|
||||||
|
@ -668,20 +668,6 @@
|
|||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": false
|
"settable_per_extruder": false
|
||||||
},
|
},
|
||||||
"slicing_tolerance":
|
|
||||||
{
|
|
||||||
"label": "Slicing Tolerance",
|
|
||||||
"description": "How to slice layers with diagonal surfaces. The areas of a layer can be generated based on where the middle of the layer intersects the surface (Middle). Alternatively each layer can have the areas which fall inside of the volume throughout the height of the layer (Exclusive) or a layer has the areas which fall inside anywhere within the layer (Inclusive). Exclusive retains the most details, Inclusive makes for the best fit and Middle takes the least time to process.",
|
|
||||||
"type": "enum",
|
|
||||||
"options":
|
|
||||||
{
|
|
||||||
"middle": "Middle",
|
|
||||||
"exclusive": "Exclusive",
|
|
||||||
"inclusive": "Inclusive"
|
|
||||||
},
|
|
||||||
"default_value": "middle",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"line_width":
|
"line_width":
|
||||||
{
|
{
|
||||||
"label": "Line Width",
|
"label": "Line Width",
|
||||||
@ -741,21 +727,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"roofing_line_width":
|
|
||||||
{
|
|
||||||
"label": "Top Surface Skin Line Width",
|
|
||||||
"description": "Width of a single line of the areas at the top of the print.",
|
|
||||||
"unit": "mm",
|
|
||||||
"minimum_value": "0.001",
|
|
||||||
"minimum_value_warning": "0.1 + 0.4 * machine_nozzle_size",
|
|
||||||
"maximum_value_warning": "2 * machine_nozzle_size",
|
|
||||||
"default_value": 0.4,
|
|
||||||
"type": "float",
|
|
||||||
"value": "skin_line_width",
|
|
||||||
"limit_to_extruder": "roofing_extruder_nr",
|
|
||||||
"settable_per_mesh": true,
|
|
||||||
"enabled": "roofing_layer_count > 0 and top_layers > 0"
|
|
||||||
},
|
|
||||||
"skin_line_width":
|
"skin_line_width":
|
||||||
{
|
{
|
||||||
"label": "Top/Bottom Line Width",
|
"label": "Top/Bottom Line Width",
|
||||||
@ -1014,34 +985,6 @@
|
|||||||
"settable_per_mesh": true,
|
"settable_per_mesh": true,
|
||||||
"enabled": "top_layers > 0"
|
"enabled": "top_layers > 0"
|
||||||
},
|
},
|
||||||
"roofing_pattern":
|
|
||||||
{
|
|
||||||
"label": "Top Surface Skin Pattern",
|
|
||||||
"description": "The pattern of the top most layers.",
|
|
||||||
"type": "enum",
|
|
||||||
"options":
|
|
||||||
{
|
|
||||||
"lines": "Lines",
|
|
||||||
"concentric": "Concentric",
|
|
||||||
"zigzag": "Zig Zag"
|
|
||||||
},
|
|
||||||
"default_value": "lines",
|
|
||||||
"value": "top_bottom_pattern",
|
|
||||||
"limit_to_extruder": "roofing_extruder_nr",
|
|
||||||
"settable_per_mesh": true,
|
|
||||||
"enabled": "roofing_layer_count > 0 and top_layers > 0"
|
|
||||||
},
|
|
||||||
"roofing_angles":
|
|
||||||
{
|
|
||||||
"label": "Top Surface Skin Line Directions",
|
|
||||||
"description": "A list of integer line directions to use when the top surface skin layers use the lines or zig zag pattern. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the traditional default angles (45 and 135 degrees).",
|
|
||||||
"type": "[int]",
|
|
||||||
"default_value": "[ ]",
|
|
||||||
"value": "skin_angles",
|
|
||||||
"enabled": "roofing_pattern != 'concentric' and roofing_layer_count > 0 and top_layers > 0",
|
|
||||||
"limit_to_extruder": "roofing_extruder_nr",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"top_bottom_extruder_nr":
|
"top_bottom_extruder_nr":
|
||||||
{
|
{
|
||||||
"label": "Top/Bottom Extruder",
|
"label": "Top/Bottom Extruder",
|
||||||
@ -1183,6 +1126,14 @@
|
|||||||
"limit_to_extruder": "wall_0_extruder_nr",
|
"limit_to_extruder": "wall_0_extruder_nr",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
|
"optimize_wall_printing_order":
|
||||||
|
{
|
||||||
|
"label": "Optimize Wall Printing Order",
|
||||||
|
"description": "Optimize the order in which walls are printed so as to reduce the number of retractions and the distance travelled. Most parts will benefit from this being enabled but some may actually take longer so please compare the print time estimates with and without optimization.",
|
||||||
|
"type": "bool",
|
||||||
|
"default_value": false,
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
"outer_inset_first":
|
"outer_inset_first":
|
||||||
{
|
{
|
||||||
"label": "Outer Before Inner Walls",
|
"label": "Outer Before Inner Walls",
|
||||||
@ -1868,14 +1819,6 @@
|
|||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"infill_enable_travel_optimization":
|
|
||||||
{
|
|
||||||
"label": "Enable Travel Optimization",
|
|
||||||
"description": "When enabled, the order in which the infill lines are printed is optimized to reduce the distance travelled. The reduction in travel time achieved very much depends on the model being sliced, infill pattern, density, etc. Note that, for some models that have many small areas of infill, the time to slice the model may be greatly increased.",
|
|
||||||
"type": "bool",
|
|
||||||
"default_value": false,
|
|
||||||
"settable_per_mesh": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1887,16 +1830,6 @@
|
|||||||
"type": "category",
|
"type": "category",
|
||||||
"children":
|
"children":
|
||||||
{
|
{
|
||||||
"material_flow_dependent_temperature":
|
|
||||||
{
|
|
||||||
"label": "Auto Temperature",
|
|
||||||
"description": "Change the temperature for each layer automatically with the average flow speed of that layer.",
|
|
||||||
"type": "bool",
|
|
||||||
"default_value": false,
|
|
||||||
"enabled": "machine_nozzle_temp_enabled and False",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": true
|
|
||||||
},
|
|
||||||
"default_material_print_temperature":
|
"default_material_print_temperature":
|
||||||
{
|
{
|
||||||
"label": "Default Printing Temperature",
|
"label": "Default Printing Temperature",
|
||||||
@ -1971,17 +1904,6 @@
|
|||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
},
|
},
|
||||||
"material_flow_temp_graph":
|
|
||||||
{
|
|
||||||
"label": "Flow Temperature Graph",
|
|
||||||
"description": "Data linking material flow (in mm3 per second) to temperature (degrees Celsius).",
|
|
||||||
"unit": "[[mm³,°C]]",
|
|
||||||
"type": "str",
|
|
||||||
"default_value": "[[3.5,200],[7.0,240]]",
|
|
||||||
"enabled": "False and machine_nozzle_temp_enabled and material_flow_dependent_temperature",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": true
|
|
||||||
},
|
|
||||||
"material_extrusion_cool_down_speed":
|
"material_extrusion_cool_down_speed":
|
||||||
{
|
{
|
||||||
"label": "Extrusion Cool Down Speed Modifier",
|
"label": "Extrusion Cool Down Speed Modifier",
|
||||||
@ -2097,6 +2019,19 @@
|
|||||||
"enabled": "machine_gcode_flavor != \"UltiGCode\"",
|
"enabled": "machine_gcode_flavor != \"UltiGCode\"",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
|
"material_flow_layer_0":
|
||||||
|
{
|
||||||
|
"label": "Initial Layer Flow",
|
||||||
|
"description": "Flow compensation for the first layer: the amount of material extruded on the initial layer is multiplied by this value.",
|
||||||
|
"unit": "%",
|
||||||
|
"default_value": 100,
|
||||||
|
"value": "material_flow",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value": "0.0001",
|
||||||
|
"minimum_value_warning": "50",
|
||||||
|
"maximum_value_warning": "150",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
"retraction_enable":
|
"retraction_enable":
|
||||||
{
|
{
|
||||||
"label": "Enable Retraction",
|
"label": "Enable Retraction",
|
||||||
@ -2106,7 +2041,8 @@
|
|||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": true
|
"settable_per_extruder": true
|
||||||
},
|
},
|
||||||
"retract_at_layer_change":{
|
"retract_at_layer_change":
|
||||||
|
{
|
||||||
"label": "Retract at Layer Change",
|
"label": "Retract at Layer Change",
|
||||||
"description": "Retract the filament when the nozzle is moving to the next layer.",
|
"description": "Retract the filament when the nozzle is moving to the next layer.",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
@ -3514,15 +3450,6 @@
|
|||||||
"settable_per_mesh": true,
|
"settable_per_mesh": true,
|
||||||
"settable_per_extruder": false
|
"settable_per_extruder": false
|
||||||
},
|
},
|
||||||
"support_tree_enable":
|
|
||||||
{
|
|
||||||
"label": "Tree Support",
|
|
||||||
"description": "Generate a tree-like support with branches that support your print. This may reduce material usage and print time.",
|
|
||||||
"type": "bool",
|
|
||||||
"default_value": false,
|
|
||||||
"settable_per_mesh": true,
|
|
||||||
"settable_per_extruder": false
|
|
||||||
},
|
|
||||||
"support_extruder_nr":
|
"support_extruder_nr":
|
||||||
{
|
{
|
||||||
"label": "Support Extruder",
|
"label": "Support Extruder",
|
||||||
@ -3841,110 +3768,6 @@
|
|||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
"settable_per_mesh": false
|
"settable_per_mesh": false
|
||||||
},
|
},
|
||||||
"support_tree_angle":
|
|
||||||
{
|
|
||||||
"label": "Tree Support Branch Angle",
|
|
||||||
"description": "The angle of the branches. Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach.",
|
|
||||||
"unit": "°",
|
|
||||||
"type": "float",
|
|
||||||
"minimum_value": "0",
|
|
||||||
"maximum_value": "90",
|
|
||||||
"maximum_value_warning": "60",
|
|
||||||
"default_value": 40,
|
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
|
||||||
"enabled": "support_tree_enable",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": true
|
|
||||||
},
|
|
||||||
"support_tree_branch_distance":
|
|
||||||
{
|
|
||||||
"label": "Tree Support Branch Distance",
|
|
||||||
"description": "How far apart the branches need to be when they touch the model. Making this distance small will cause the tree support to touch the model at more points, causing better overhang but making support harder to remove.",
|
|
||||||
"unit": "mm",
|
|
||||||
"type": "float",
|
|
||||||
"minimum_value": "0.001",
|
|
||||||
"default_value": 4,
|
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
|
||||||
"enabled": "support_tree_enable",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"support_tree_branch_diameter":
|
|
||||||
{
|
|
||||||
"label": "Tree Support Branch Diameter",
|
|
||||||
"description": "The diameter of the thinnest branches of tree support. Thicker branches are more sturdy. Branches towards the base will be thicker than this.",
|
|
||||||
"unit": "mm",
|
|
||||||
"type": "float",
|
|
||||||
"minimum_value": "0.001",
|
|
||||||
"minimum_value_warning": "support_line_width * 2",
|
|
||||||
"default_value": 2,
|
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
|
||||||
"enabled": "support_tree_enable",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": true
|
|
||||||
},
|
|
||||||
"support_tree_branch_diameter_angle":
|
|
||||||
{
|
|
||||||
"label": "Tree Support Branch Diameter Angle",
|
|
||||||
"description": "The angle of the branches' diameter as they gradually become thicker towards the bottom. An angle of 0 will cause the branches to have uniform thickness over their length. A bit of an angle can increase stability of the tree support.",
|
|
||||||
"unit": "°",
|
|
||||||
"type": "float",
|
|
||||||
"minimum_value": "0",
|
|
||||||
"maximum_value": "89.9999",
|
|
||||||
"maximum_value_warning": "15",
|
|
||||||
"default_value": 5,
|
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
|
||||||
"enabled": "support_tree_enable",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": true
|
|
||||||
},
|
|
||||||
"support_tree_collision_resolution":
|
|
||||||
{
|
|
||||||
"label": "Tree Support Collision Resolution",
|
|
||||||
"description": "Resolution to compute collisions with to avoid hitting the model. Setting this lower will produce more accurate trees that fail less often, but increases slicing time dramatically.",
|
|
||||||
"unit": "mm",
|
|
||||||
"type": "float",
|
|
||||||
"minimum_value": "0.001",
|
|
||||||
"minimum_value_warning": "support_line_width / 4",
|
|
||||||
"maximum_value_warning": "support_line_width * 2",
|
|
||||||
"default_value": 0.4,
|
|
||||||
"value": "support_line_width / 2",
|
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
|
||||||
"enabled": "support_tree_enable and support_tree_branch_diameter_angle > 0",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": true
|
|
||||||
},
|
|
||||||
"support_tree_wall_thickness":
|
|
||||||
{
|
|
||||||
"label": "Tree Support Wall Thickness",
|
|
||||||
"description": "The thickness of the walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily.",
|
|
||||||
"unit": "mm",
|
|
||||||
"type": "float",
|
|
||||||
"minimum_value": "0",
|
|
||||||
"minimum_value_warning": "wall_line_width",
|
|
||||||
"default_value": 0.8,
|
|
||||||
"value": "support_line_width",
|
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
|
||||||
"enabled": "support_tree_enable",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": true,
|
|
||||||
"children":
|
|
||||||
{
|
|
||||||
"support_tree_wall_count":
|
|
||||||
{
|
|
||||||
"label": "Tree Support Wall Line Count",
|
|
||||||
"description": "The number of walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily.",
|
|
||||||
"type": "int",
|
|
||||||
"minimum_value": "0",
|
|
||||||
"minimum_value_warning": "1",
|
|
||||||
"default_value": 1,
|
|
||||||
"value": "round(support_tree_wall_thickness / support_line_width)",
|
|
||||||
"limit_to_extruder": "support_infill_extruder_nr",
|
|
||||||
"enabled": "support_tree_enable",
|
|
||||||
"settable_per_mesh": false,
|
|
||||||
"settable_per_extruder": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gradual_support_infill_steps":
|
"gradual_support_infill_steps":
|
||||||
{
|
{
|
||||||
"label": "Gradual Support Infill Steps",
|
"label": "Gradual Support Infill Steps",
|
||||||
@ -5129,18 +4952,6 @@
|
|||||||
"default_value": false,
|
"default_value": false,
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
"meshfix_maximum_resolution":
|
|
||||||
{
|
|
||||||
"label": "Maximum Resolution",
|
|
||||||
"description": "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway.",
|
|
||||||
"type": "float",
|
|
||||||
"unit": "mm",
|
|
||||||
"default_value": 0.01,
|
|
||||||
"minimum_value": "0.001",
|
|
||||||
"minimum_value_warning": "0.005",
|
|
||||||
"maximum_value_warning": "0.1",
|
|
||||||
"settable_per_mesh": true
|
|
||||||
},
|
|
||||||
"multiple_mesh_overlap":
|
"multiple_mesh_overlap":
|
||||||
{
|
{
|
||||||
"label": "Merged Meshes Overlap",
|
"label": "Merged Meshes Overlap",
|
||||||
@ -5369,12 +5180,215 @@
|
|||||||
"description": "experimental!",
|
"description": "experimental!",
|
||||||
"children":
|
"children":
|
||||||
{
|
{
|
||||||
"optimize_wall_printing_order":
|
"support_tree_enable":
|
||||||
{
|
{
|
||||||
"label": "Optimize Wall Printing Order",
|
"label": "Tree Support",
|
||||||
"description": "Optimize the order in which walls are printed so as to reduce the number of retractions and the distance travelled. Most parts will benefit from this being enabled but some may actually take longer so please compare the print time estimates with and without optimization.",
|
"description": "Generate a tree-like support with branches that support your print. This may reduce material usage and print time, but greatly increases slicing time.",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"default_value": false,
|
"default_value": false,
|
||||||
|
"settable_per_mesh": true,
|
||||||
|
"settable_per_extruder": false
|
||||||
|
},
|
||||||
|
"support_tree_angle":
|
||||||
|
{
|
||||||
|
"label": "Tree Support Branch Angle",
|
||||||
|
"description": "The angle of the branches. Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach.",
|
||||||
|
"unit": "°",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value": "0",
|
||||||
|
"maximum_value": "90",
|
||||||
|
"maximum_value_warning": "60",
|
||||||
|
"default_value": 40,
|
||||||
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
|
"enabled": "support_tree_enable",
|
||||||
|
"settable_per_mesh": false,
|
||||||
|
"settable_per_extruder": true
|
||||||
|
},
|
||||||
|
"support_tree_branch_distance":
|
||||||
|
{
|
||||||
|
"label": "Tree Support Branch Distance",
|
||||||
|
"description": "How far apart the branches need to be when they touch the model. Making this distance small will cause the tree support to touch the model at more points, causing better overhang but making support harder to remove.",
|
||||||
|
"unit": "mm",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value": "0.001",
|
||||||
|
"default_value": 4,
|
||||||
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
|
"enabled": "support_tree_enable",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"support_tree_branch_diameter":
|
||||||
|
{
|
||||||
|
"label": "Tree Support Branch Diameter",
|
||||||
|
"description": "The diameter of the thinnest branches of tree support. Thicker branches are more sturdy. Branches towards the base will be thicker than this.",
|
||||||
|
"unit": "mm",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value": "0.001",
|
||||||
|
"minimum_value_warning": "support_line_width * 2",
|
||||||
|
"default_value": 2,
|
||||||
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
|
"enabled": "support_tree_enable",
|
||||||
|
"settable_per_mesh": false,
|
||||||
|
"settable_per_extruder": true
|
||||||
|
},
|
||||||
|
"support_tree_branch_diameter_angle":
|
||||||
|
{
|
||||||
|
"label": "Tree Support Branch Diameter Angle",
|
||||||
|
"description": "The angle of the branches' diameter as they gradually become thicker towards the bottom. An angle of 0 will cause the branches to have uniform thickness over their length. A bit of an angle can increase stability of the tree support.",
|
||||||
|
"unit": "°",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value": "0",
|
||||||
|
"maximum_value": "89.9999",
|
||||||
|
"maximum_value_warning": "15",
|
||||||
|
"default_value": 5,
|
||||||
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
|
"enabled": "support_tree_enable",
|
||||||
|
"settable_per_mesh": false,
|
||||||
|
"settable_per_extruder": true
|
||||||
|
},
|
||||||
|
"support_tree_collision_resolution":
|
||||||
|
{
|
||||||
|
"label": "Tree Support Collision Resolution",
|
||||||
|
"description": "Resolution to compute collisions with to avoid hitting the model. Setting this lower will produce more accurate trees that fail less often, but increases slicing time dramatically.",
|
||||||
|
"unit": "mm",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value": "0.001",
|
||||||
|
"minimum_value_warning": "support_line_width / 4",
|
||||||
|
"maximum_value_warning": "support_line_width * 2",
|
||||||
|
"default_value": 0.4,
|
||||||
|
"value": "support_line_width / 2",
|
||||||
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
|
"enabled": "support_tree_enable and support_tree_branch_diameter_angle > 0",
|
||||||
|
"settable_per_mesh": false,
|
||||||
|
"settable_per_extruder": true
|
||||||
|
},
|
||||||
|
"support_tree_wall_thickness":
|
||||||
|
{
|
||||||
|
"label": "Tree Support Wall Thickness",
|
||||||
|
"description": "The thickness of the walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily.",
|
||||||
|
"unit": "mm",
|
||||||
|
"type": "float",
|
||||||
|
"minimum_value": "0",
|
||||||
|
"minimum_value_warning": "wall_line_width",
|
||||||
|
"default_value": 0.8,
|
||||||
|
"value": "support_line_width",
|
||||||
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
|
"enabled": "support_tree_enable",
|
||||||
|
"settable_per_mesh": false,
|
||||||
|
"settable_per_extruder": true,
|
||||||
|
"children":
|
||||||
|
{
|
||||||
|
"support_tree_wall_count":
|
||||||
|
{
|
||||||
|
"label": "Tree Support Wall Line Count",
|
||||||
|
"description": "The number of walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily.",
|
||||||
|
"type": "int",
|
||||||
|
"minimum_value": "0",
|
||||||
|
"minimum_value_warning": "1",
|
||||||
|
"default_value": 1,
|
||||||
|
"value": "round(support_tree_wall_thickness / support_line_width)",
|
||||||
|
"limit_to_extruder": "support_infill_extruder_nr",
|
||||||
|
"enabled": "support_tree_enable",
|
||||||
|
"settable_per_mesh": false,
|
||||||
|
"settable_per_extruder": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"slicing_tolerance":
|
||||||
|
{
|
||||||
|
"label": "Slicing Tolerance",
|
||||||
|
"description": "How to slice layers with diagonal surfaces. The areas of a layer can be generated based on where the middle of the layer intersects the surface (Middle). Alternatively each layer can have the areas which fall inside of the volume throughout the height of the layer (Exclusive) or a layer has the areas which fall inside anywhere within the layer (Inclusive). Exclusive retains the most details, Inclusive makes for the best fit and Middle takes the least time to process.",
|
||||||
|
"type": "enum",
|
||||||
|
"options":
|
||||||
|
{
|
||||||
|
"middle": "Middle",
|
||||||
|
"exclusive": "Exclusive",
|
||||||
|
"inclusive": "Inclusive"
|
||||||
|
},
|
||||||
|
"default_value": "middle",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"roofing_line_width":
|
||||||
|
{
|
||||||
|
"label": "Top Surface Skin Line Width",
|
||||||
|
"description": "Width of a single line of the areas at the top of the print.",
|
||||||
|
"unit": "mm",
|
||||||
|
"minimum_value": "0.001",
|
||||||
|
"minimum_value_warning": "0.1 + 0.4 * machine_nozzle_size",
|
||||||
|
"maximum_value_warning": "2 * machine_nozzle_size",
|
||||||
|
"default_value": 0.4,
|
||||||
|
"type": "float",
|
||||||
|
"value": "skin_line_width",
|
||||||
|
"limit_to_extruder": "roofing_extruder_nr",
|
||||||
|
"settable_per_mesh": true,
|
||||||
|
"enabled": "roofing_layer_count > 0 and top_layers > 0"
|
||||||
|
},
|
||||||
|
"roofing_pattern":
|
||||||
|
{
|
||||||
|
"label": "Top Surface Skin Pattern",
|
||||||
|
"description": "The pattern of the top most layers.",
|
||||||
|
"type": "enum",
|
||||||
|
"options":
|
||||||
|
{
|
||||||
|
"lines": "Lines",
|
||||||
|
"concentric": "Concentric",
|
||||||
|
"zigzag": "Zig Zag"
|
||||||
|
},
|
||||||
|
"default_value": "lines",
|
||||||
|
"value": "top_bottom_pattern",
|
||||||
|
"limit_to_extruder": "roofing_extruder_nr",
|
||||||
|
"settable_per_mesh": true,
|
||||||
|
"enabled": "roofing_layer_count > 0 and top_layers > 0"
|
||||||
|
},
|
||||||
|
"roofing_angles":
|
||||||
|
{
|
||||||
|
"label": "Top Surface Skin Line Directions",
|
||||||
|
"description": "A list of integer line directions to use when the top surface skin layers use the lines or zig zag pattern. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the traditional default angles (45 and 135 degrees).",
|
||||||
|
"type": "[int]",
|
||||||
|
"default_value": "[ ]",
|
||||||
|
"value": "skin_angles",
|
||||||
|
"enabled": "roofing_pattern != 'concentric' and roofing_layer_count > 0 and top_layers > 0",
|
||||||
|
"limit_to_extruder": "roofing_extruder_nr",
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"infill_enable_travel_optimization":
|
||||||
|
{
|
||||||
|
"label": "Infill Travel Optimization",
|
||||||
|
"description": "When enabled, the order in which the infill lines are printed is optimized to reduce the distance travelled. The reduction in travel time achieved very much depends on the model being sliced, infill pattern, density, etc. Note that, for some models that have many small areas of infill, the time to slice the model may be greatly increased.",
|
||||||
|
"type": "bool",
|
||||||
|
"default_value": false,
|
||||||
|
"settable_per_mesh": true
|
||||||
|
},
|
||||||
|
"material_flow_dependent_temperature":
|
||||||
|
{
|
||||||
|
"label": "Auto Temperature",
|
||||||
|
"description": "Change the temperature for each layer automatically with the average flow speed of that layer.",
|
||||||
|
"type": "bool",
|
||||||
|
"default_value": false,
|
||||||
|
"enabled": "machine_nozzle_temp_enabled and False",
|
||||||
|
"settable_per_mesh": false,
|
||||||
|
"settable_per_extruder": true
|
||||||
|
},
|
||||||
|
"material_flow_temp_graph":
|
||||||
|
{
|
||||||
|
"label": "Flow Temperature Graph",
|
||||||
|
"description": "Data linking material flow (in mm3 per second) to temperature (degrees Celsius).",
|
||||||
|
"unit": "[[mm³,°C]]",
|
||||||
|
"type": "str",
|
||||||
|
"default_value": "[[3.5,200],[7.0,240]]",
|
||||||
|
"enabled": "False and machine_nozzle_temp_enabled and material_flow_dependent_temperature",
|
||||||
|
"settable_per_mesh": false,
|
||||||
|
"settable_per_extruder": true
|
||||||
|
},
|
||||||
|
"meshfix_maximum_resolution":
|
||||||
|
{
|
||||||
|
"label": "Maximum Resolution",
|
||||||
|
"description": "The minimum size of a line segment after slicing. If you increase this, the mesh will have a lower resolution. This may allow the printer to keep up with the speed it has to process g-code and will increase slice speed by removing details of the mesh that it can't process anyway.",
|
||||||
|
"type": "float",
|
||||||
|
"unit": "mm",
|
||||||
|
"default_value": 0.01,
|
||||||
|
"minimum_value": "0.001",
|
||||||
|
"minimum_value_warning": "0.005",
|
||||||
|
"maximum_value_warning": "0.1",
|
||||||
"settable_per_mesh": true
|
"settable_per_mesh": true
|
||||||
},
|
},
|
||||||
"support_skip_some_zags":
|
"support_skip_some_zags":
|
||||||
|
53
resources/definitions/gmax15plus.def.json
Normal file
53
resources/definitions/gmax15plus.def.json
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"id": "gmax15plus",
|
||||||
|
"version": 2,
|
||||||
|
"name": "gMax 1.5 Plus",
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"visible": true,
|
||||||
|
"author": "gcreate",
|
||||||
|
"manufacturer": "gcreate",
|
||||||
|
"category": "Other",
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl",
|
||||||
|
"has_variants": true,
|
||||||
|
"variants_name": "Hotend",
|
||||||
|
"preferred_variant": "*0.5mm E3D (Default)*"
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
"overrides": {
|
||||||
|
"machine_extruder_count": { "default_value": 1 },
|
||||||
|
"machine_name": { "default_value": "gMax 1.5 Plus" },
|
||||||
|
"machine_heated_bed": { "default_value": false },
|
||||||
|
"machine_width": { "default_value": 406 },
|
||||||
|
"machine_depth": { "default_value": 406 },
|
||||||
|
"machine_height": { "default_value": 533 },
|
||||||
|
"machine_center_is_zero": { "default_value": false },
|
||||||
|
"material_diameter": { "default_value": 1.75 },
|
||||||
|
"machine_nozzle_size": { "default_value": 0.5 },
|
||||||
|
"layer_height": { "default_value": 0.2 },
|
||||||
|
"layer_height_0": { "default_value": 0.3 },
|
||||||
|
"retraction_amount": { "default_value": 1 },
|
||||||
|
"retraction_speed": { "default_value": 70},
|
||||||
|
"adhesion_type": { "default_value": "skirt" },
|
||||||
|
"gantry_height": { "default_value": 50 },
|
||||||
|
"speed_print": { "default_value": 50 },
|
||||||
|
"speed_travel": { "default_value": 70 },
|
||||||
|
"machine_max_acceleration_x": { "default_value": 600 },
|
||||||
|
"machine_max_acceleration_y": { "default_value": 600 },
|
||||||
|
"machine_max_acceleration_z": { "default_value": 30 },
|
||||||
|
"machine_max_acceleration_e": { "default_value": 10000 },
|
||||||
|
"machine_max_jerk_xy": { "default_value": 8 },
|
||||||
|
"machine_max_jerk_z": { "default_value": 0.4 },
|
||||||
|
"machine_max_jerk_e": { "default_value": 5.0 },
|
||||||
|
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||||
|
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 ;Home X/Y/Z\nG29 ; Bed level\nM104 S{material_print_temperature} ; Preheat\nM109 S{material_print_temperature} ; Preheat\nG91 ;relative positioning\nG90 ;absolute positioning\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." },
|
||||||
|
"machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" },
|
||||||
|
"material_print_temperature": { "default_value": 202 },
|
||||||
|
"wall_thickness": { "default_value": 1 },
|
||||||
|
"top_bottom_thickness": { "default_value": 1 },
|
||||||
|
"bottom_thickness": { "default_value": 1 }
|
||||||
|
}
|
||||||
|
}
|
55
resources/definitions/gmax15plus_dual.def.json
Normal file
55
resources/definitions/gmax15plus_dual.def.json
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"id": "gmax15plus_dual",
|
||||||
|
"version": 2,
|
||||||
|
"name": "gMax 1.5 Plus Dual Extruder",
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"visible": true,
|
||||||
|
"author": "GTL_180109",
|
||||||
|
"manufacturer": "gCreate",
|
||||||
|
"category": "Other",
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl",
|
||||||
|
"has_variants": true,
|
||||||
|
"variants_name": "Hotend",
|
||||||
|
"preferred_variant": "*0.5mm E3D (Default)*",
|
||||||
|
"machine_extruder_trains": {
|
||||||
|
"0": "gmax15plus_dual_extruder_0",
|
||||||
|
"1": "gmax15plus_dual_extruder_1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": { "default_value": "gMax 1.5 Plus Dual Extruder" },
|
||||||
|
"machine_extruder_count": { "default_value": 2 },
|
||||||
|
"machine_heated_bed": { "default_value": false },
|
||||||
|
"machine_width": { "default_value": 406 },
|
||||||
|
"machine_depth": { "default_value": 406 },
|
||||||
|
"machine_height": { "default_value": 533 },
|
||||||
|
"machine_center_is_zero": { "default_value": false },
|
||||||
|
"material_diameter": { "default_value": 1.75 },
|
||||||
|
"machine_nozzle_size": { "default_value": 0.5 },
|
||||||
|
"layer_height": { "default_value": 0.2 },
|
||||||
|
"layer_height_0": { "default_value": 0.3 },
|
||||||
|
"retraction_amount": { "default_value": 1 },
|
||||||
|
"retraction_speed": { "default_value": 70},
|
||||||
|
"adhesion_type": { "default_value": "skirt" },
|
||||||
|
"gantry_height": { "default_value": 50 },
|
||||||
|
"speed_print": { "default_value": 50 },
|
||||||
|
"speed_travel": { "default_value": 70 },
|
||||||
|
"machine_max_acceleration_x": { "default_value": 600 },
|
||||||
|
"machine_max_acceleration_y": { "default_value": 600 },
|
||||||
|
"machine_max_acceleration_z": { "default_value": 30 },
|
||||||
|
"machine_max_acceleration_e": { "default_value": 10000 },
|
||||||
|
"machine_max_jerk_xy": { "default_value": 8 },
|
||||||
|
"machine_max_jerk_z": { "default_value": 0.4 },
|
||||||
|
"machine_max_jerk_e": { "default_value": 5.0 },
|
||||||
|
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||||
|
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 ;Home X/Y/Z\nG29 ; Bed level\nM104 S{material_print_temperature} T0 ; Preheat Left Extruder\nM104 S{material_print_temperature} T1 ; Preheat Right Extruder\nM109 S{material_print_temperature} T0 ; Preheat Left Extruder\nM109 S{material_print_temperature} T1 ; Preheat Right Extruder\nG91 ;relative positioning\nG90 ;absolute positioning\nM218 T1 X34.3 Y0; Set 2nd extruder offset. This can be changed later if needed\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." },
|
||||||
|
"machine_end_gcode": { "default_value": "M104 S0 T0;Left extruder off\nM104 S0 T1; Right extruder off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" },
|
||||||
|
"material_print_temperature": { "default_value": 202 },
|
||||||
|
"wall_thickness": { "default_value": 1 },
|
||||||
|
"top_bottom_thickness": { "default_value": 1 },
|
||||||
|
"bottom_thickness": { "default_value": 1 }
|
||||||
|
}
|
||||||
|
}
|
28
resources/extruders/gmax15plus_dual_extruder_0.def.json
Normal file
28
resources/extruders/gmax15plus_dual_extruder_0.def.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"id": "gmax15plus_dual_extruder_0",
|
||||||
|
"version": 2,
|
||||||
|
"name": "Left Extruder",
|
||||||
|
"inherits": "fdmextruder",
|
||||||
|
"metadata": {
|
||||||
|
"machine": "gmax15plus_dual",
|
||||||
|
"position": "0"
|
||||||
|
},
|
||||||
|
|
||||||
|
"overrides": {
|
||||||
|
"extruder_nr": {
|
||||||
|
"default_value": 0,
|
||||||
|
"maximum_value": "1"
|
||||||
|
},
|
||||||
|
"machine_nozzle_offset_x": { "default_value": 0.0 },
|
||||||
|
"machine_nozzle_offset_y": { "default_value": 0.0 },
|
||||||
|
"machine_nozzle_size": { "default_value": 0.5 },
|
||||||
|
|
||||||
|
"machine_extruder_start_pos_abs": { "default_value": true },
|
||||||
|
"machine_extruder_start_pos_x": { "value": 40 },
|
||||||
|
"machine_extruder_start_pos_y": { "value": 210 },
|
||||||
|
"machine_extruder_end_pos_abs": { "default_value": true },
|
||||||
|
"machine_extruder_end_pos_x": { "value": 40 },
|
||||||
|
"machine_extruder_end_pos_y": { "value": 210 }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
30
resources/extruders/gmax15plus_dual_extruder_1.def.json
Normal file
30
resources/extruders/gmax15plus_dual_extruder_1.def.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"id": "gmax15plus_dual_extruder_1",
|
||||||
|
"version": 2,
|
||||||
|
"name": "Right Extruder",
|
||||||
|
"inherits": "fdmextruder",
|
||||||
|
"metadata": {
|
||||||
|
"machine": "gmax15plus_dual",
|
||||||
|
"position": "1"
|
||||||
|
},
|
||||||
|
|
||||||
|
"overrides": {
|
||||||
|
"extruder_nr": {
|
||||||
|
"default_value": 1,
|
||||||
|
"maximum_value": "1"
|
||||||
|
},
|
||||||
|
"machine_nozzle_offset_x": { "default_value": 0.0 },
|
||||||
|
"machine_nozzle_offset_y": { "default_value": 0.0 },
|
||||||
|
"machine_nozzle_size": { "default_value": 0.5 },
|
||||||
|
|
||||||
|
"machine_extruder_start_pos_abs": { "default_value": true },
|
||||||
|
"machine_extruder_start_pos_x": { "value": 40 },
|
||||||
|
"machine_extruder_start_pos_y": { "value": 210 },
|
||||||
|
"machine_extruder_end_pos_abs": { "default_value": true },
|
||||||
|
"machine_extruder_end_pos_x": { "value": 40 },
|
||||||
|
"machine_extruder_end_pos_y": { "value": 210 }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -8,14 +8,15 @@ msgstr ""
|
|||||||
"Project-Id-Version: Cura 3.1\n"
|
"Project-Id-Version: Cura 3.1\n"
|
||||||
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
|
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
|
||||||
"POT-Creation-Date: 2017-08-02 16:53+0000\n"
|
"POT-Creation-Date: 2017-08-02 16:53+0000\n"
|
||||||
"PO-Revision-Date: 2017-12-07 13:41+0100\n"
|
"PO-Revision-Date: 2018-01-23 19:35+0000\n"
|
||||||
"Last-Translator: Bothof <info@bothof.nl>\n"
|
"Last-Translator: Paulo Miranda <av@utopica3d.com>\n"
|
||||||
"Language-Team: Bothof\n"
|
"Language-Team: Bothof\n"
|
||||||
"Language: pt_PT\n"
|
"Language: pt_PT\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Generator: Poedit 2.0.5\n"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_settings label"
|
msgctxt "machine_settings label"
|
||||||
@ -30,155 +31,152 @@ msgstr "Definições específicas da máquina"
|
|||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "extruder_nr label"
|
msgctxt "extruder_nr label"
|
||||||
msgid "Extruder"
|
msgid "Extruder"
|
||||||
msgstr "Extrusora"
|
msgstr "Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "extruder_nr description"
|
msgctxt "extruder_nr description"
|
||||||
msgid "The extruder train used for printing. This is used in multi-extrusion."
|
msgid "The extruder train used for printing. This is used in multi-extrusion."
|
||||||
msgstr "A máquina extrusora utilizada para imprimir. Esta é utilizada em extrusões múltiplas."
|
msgstr "O núcleos de extrusão utilizado para imprimir. Definição usada com múltiplos extrusores."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_nozzle_id label"
|
msgctxt "machine_nozzle_id label"
|
||||||
msgid "Nozzle ID"
|
msgid "Nozzle ID"
|
||||||
msgstr "ID do bocal"
|
msgstr "ID do Nozzle"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_nozzle_id description"
|
msgctxt "machine_nozzle_id description"
|
||||||
msgid "The nozzle ID for an extruder train, such as \"AA 0.4\" and \"BB 0.8\"."
|
msgid "The nozzle ID for an extruder train, such as \"AA 0.4\" and \"BB 0.8\"."
|
||||||
msgstr "A ID do bocal para uma máquina de extrusão, tal como \"AA 0.4\" e \"BB 0.8\"."
|
msgstr "O ID do nozzle de um núcleo de extrusão, tal como \"AA 0.4\" e \"BB 0.8\"."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_nozzle_size label"
|
msgctxt "machine_nozzle_size label"
|
||||||
msgid "Nozzle Diameter"
|
msgid "Nozzle Diameter"
|
||||||
msgstr "Diâmetro do bocal"
|
msgstr "Diâmetro do Nozzle"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_nozzle_size description"
|
msgctxt "machine_nozzle_size description"
|
||||||
msgid ""
|
msgid "The inner diameter of the nozzle. Change this setting when using a non-standard nozzle size."
|
||||||
"The inner diameter of the nozzle. Change this setting when using a non-"
|
msgstr ""
|
||||||
"standard nozzle size."
|
"O diâmetro interno do nozzle. Altere esta definição quando utilizar um nozzle com um tamanho não convencional."
|
||||||
msgstr "O diâmetro interno do bocal. Altere esta definição ao utilizar um tamanho de bocal não convencional."
|
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_nozzle_offset_x label"
|
msgctxt "machine_nozzle_offset_x label"
|
||||||
msgid "Nozzle X Offset"
|
msgid "Nozzle X Offset"
|
||||||
msgstr "Desvio X do bocal"
|
msgstr "Desvio X do Nozzle"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_nozzle_offset_x description"
|
msgctxt "machine_nozzle_offset_x description"
|
||||||
msgid "The x-coordinate of the offset of the nozzle."
|
msgid "The x-coordinate of the offset of the nozzle."
|
||||||
msgstr "A coordenada X do desvio do bocal."
|
msgstr "A coordenada X do desvio do nozzle."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_nozzle_offset_y label"
|
msgctxt "machine_nozzle_offset_y label"
|
||||||
msgid "Nozzle Y Offset"
|
msgid "Nozzle Y Offset"
|
||||||
msgstr "Desvio Y do bocal"
|
msgstr "Desvio Y do Nozzle"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_nozzle_offset_y description"
|
msgctxt "machine_nozzle_offset_y description"
|
||||||
msgid "The y-coordinate of the offset of the nozzle."
|
msgid "The y-coordinate of the offset of the nozzle."
|
||||||
msgstr "A coordenada Y do desvio do bocal."
|
msgstr "A coordenada Y do desvio do nozzle."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_start_code label"
|
msgctxt "machine_extruder_start_code label"
|
||||||
msgid "Extruder Start G-Code"
|
msgid "Extruder Start G-Code"
|
||||||
msgstr "G-Code inicial da extrusora"
|
msgstr "G-Code Inicial do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_start_code description"
|
msgctxt "machine_extruder_start_code description"
|
||||||
msgid "Start g-code to execute whenever turning the extruder on."
|
msgid "Start g-code to execute whenever turning the extruder on."
|
||||||
msgstr "G-Code inicial a ser executado sempre que a extrusora for ligada."
|
msgstr "G-Code inicial a ser executado sempre que o extrusor for ligado."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_start_pos_abs label"
|
msgctxt "machine_extruder_start_pos_abs label"
|
||||||
msgid "Extruder Start Position Absolute"
|
msgid "Extruder Start Position Absolute"
|
||||||
msgstr "Posição inicial absoluta da extrusora"
|
msgstr "Posição Inicial Absoluta do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_start_pos_abs description"
|
msgctxt "machine_extruder_start_pos_abs description"
|
||||||
msgid ""
|
msgid "Make the extruder starting position absolute rather than relative to the last-known location of the head."
|
||||||
"Make the extruder starting position absolute rather than relative to the "
|
msgstr ""
|
||||||
"last-known location of the head."
|
"Define a posição inicial do extrusor, absoluta em vez de relativa à última posição conhecida da cabeça de "
|
||||||
msgstr "Torne a posição inicial da extrusora absoluta em vez de relativa à última posição conhecida da cabeça."
|
"impressão."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_start_pos_x label"
|
msgctxt "machine_extruder_start_pos_x label"
|
||||||
msgid "Extruder Start Position X"
|
msgid "Extruder Start Position X"
|
||||||
msgstr "X da posição inicial da extrusora"
|
msgstr "Posição X Inicial do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_start_pos_x description"
|
msgctxt "machine_extruder_start_pos_x description"
|
||||||
msgid "The x-coordinate of the starting position when turning the extruder on."
|
msgid "The x-coordinate of the starting position when turning the extruder on."
|
||||||
msgstr "A coordenada X da posição inicial ao ligar a extrusora."
|
msgstr "A coordenada X da posição inicial ao ligar o extrusor."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_start_pos_y label"
|
msgctxt "machine_extruder_start_pos_y label"
|
||||||
msgid "Extruder Start Position Y"
|
msgid "Extruder Start Position Y"
|
||||||
msgstr "Y da posição inicial da extrusora"
|
msgstr "Posição Y Inicial do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_start_pos_y description"
|
msgctxt "machine_extruder_start_pos_y description"
|
||||||
msgid "The y-coordinate of the starting position when turning the extruder on."
|
msgid "The y-coordinate of the starting position when turning the extruder on."
|
||||||
msgstr "A coordenada Y da posição inicial ao ligar a extrusora."
|
msgstr "A coordenada Y da posição inicial ao ligar o extrusor."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_end_code label"
|
msgctxt "machine_extruder_end_code label"
|
||||||
msgid "Extruder End G-Code"
|
msgid "Extruder End G-Code"
|
||||||
msgstr "G-Code final da extrusora"
|
msgstr "G-Code Final do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_end_code description"
|
msgctxt "machine_extruder_end_code description"
|
||||||
msgid "End g-code to execute whenever turning the extruder off."
|
msgid "End g-code to execute whenever turning the extruder off."
|
||||||
msgstr "G-Code final a ser executado sempre que a extrusora for desligada."
|
msgstr "G-Code final a ser executado sempre que o extrusor for desligado."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_end_pos_abs label"
|
msgctxt "machine_extruder_end_pos_abs label"
|
||||||
msgid "Extruder End Position Absolute"
|
msgid "Extruder End Position Absolute"
|
||||||
msgstr "Posição final absoluta da extrusora"
|
msgstr "Posição Final Absoluta do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_end_pos_abs description"
|
msgctxt "machine_extruder_end_pos_abs description"
|
||||||
msgid ""
|
msgid "Make the extruder ending position absolute rather than relative to the last-known location of the head."
|
||||||
"Make the extruder ending position absolute rather than relative to the last-"
|
msgstr ""
|
||||||
"known location of the head."
|
"Define a posição final do extrusor, absoluta em vez de relativa à última posição conhecida da cabeça de "
|
||||||
msgstr "Torne a posição final da extrusora absoluta em vez de relativa à última localização conhecida da cabeça."
|
"impressão."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_end_pos_x label"
|
msgctxt "machine_extruder_end_pos_x label"
|
||||||
msgid "Extruder End Position X"
|
msgid "Extruder End Position X"
|
||||||
msgstr "X da posição final da extrusora"
|
msgstr "Posição X Final do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_end_pos_x description"
|
msgctxt "machine_extruder_end_pos_x description"
|
||||||
msgid "The x-coordinate of the ending position when turning the extruder off."
|
msgid "The x-coordinate of the ending position when turning the extruder off."
|
||||||
msgstr "A coordenada X da posição final ao desligar a extrusora."
|
msgstr "A coordenada X da posição final ao desligar o extrusor."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_end_pos_y label"
|
msgctxt "machine_extruder_end_pos_y label"
|
||||||
msgid "Extruder End Position Y"
|
msgid "Extruder End Position Y"
|
||||||
msgstr "Y da posição final da extrusora"
|
msgstr "Posição Y Final do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "machine_extruder_end_pos_y description"
|
msgctxt "machine_extruder_end_pos_y description"
|
||||||
msgid "The y-coordinate of the ending position when turning the extruder off."
|
msgid "The y-coordinate of the ending position when turning the extruder off."
|
||||||
msgstr "A coordenada Y da posição final ao desligar a extrusora."
|
msgstr "A coordenada Y da posição final ao desligar o extrusor."
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "extruder_prime_pos_z label"
|
msgctxt "extruder_prime_pos_z label"
|
||||||
msgid "Extruder Prime Z Position"
|
msgid "Extruder Prime Z Position"
|
||||||
msgstr "Posição Z de preparação da extrusora"
|
msgstr "Posição Z Preparação do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "extruder_prime_pos_z description"
|
msgctxt "extruder_prime_pos_z description"
|
||||||
msgid ""
|
msgid "The Z coordinate of the position where the nozzle primes at the start of printing."
|
||||||
"The Z coordinate of the position where the nozzle primes at the start of "
|
msgstr "A coordenada Z da posição onde o nozzle é preparado ao iniciar a impressão."
|
||||||
"printing."
|
|
||||||
msgstr "A coordenada Z da posição de preparação do bocal ao iniciar a impressão."
|
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "platform_adhesion label"
|
msgctxt "platform_adhesion label"
|
||||||
msgid "Build Plate Adhesion"
|
msgid "Build Plate Adhesion"
|
||||||
msgstr "Aderência à placa de construção"
|
msgstr "Aderência Base Construção"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "platform_adhesion description"
|
msgctxt "platform_adhesion description"
|
||||||
@ -188,23 +186,19 @@ msgstr "Aderência"
|
|||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "extruder_prime_pos_x label"
|
msgctxt "extruder_prime_pos_x label"
|
||||||
msgid "Extruder Prime X Position"
|
msgid "Extruder Prime X Position"
|
||||||
msgstr "Posição X de preparação da extrusora"
|
msgstr "Posição X Preparação do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "extruder_prime_pos_x description"
|
msgctxt "extruder_prime_pos_x description"
|
||||||
msgid ""
|
msgid "The X coordinate of the position where the nozzle primes at the start of printing."
|
||||||
"The X coordinate of the position where the nozzle primes at the start of "
|
msgstr "A coordenada X da posição onde o nozzle é preparado ao iniciar a impressão."
|
||||||
"printing."
|
|
||||||
msgstr "A coordenada X da posição de preparação do bocal ao iniciar a impressão."
|
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "extruder_prime_pos_y label"
|
msgctxt "extruder_prime_pos_y label"
|
||||||
msgid "Extruder Prime Y Position"
|
msgid "Extruder Prime Y Position"
|
||||||
msgstr "Posição Y de preparação da extrusora"
|
msgstr "Posição Y Preparação do Extrusor"
|
||||||
|
|
||||||
#: fdmextruder.def.json
|
#: fdmextruder.def.json
|
||||||
msgctxt "extruder_prime_pos_y description"
|
msgctxt "extruder_prime_pos_y description"
|
||||||
msgid ""
|
msgid "The Y coordinate of the position where the nozzle primes at the start of printing."
|
||||||
"The Y coordinate of the position where the nozzle primes at the start of "
|
msgstr "A coordenada Y da posição onde o nozzle é preparado ao iniciar a impressão."
|
||||||
"printing."
|
|
||||||
msgstr "A coordenada Y da posição de preparação do bocal ao iniciar a impressão."
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
BIN
resources/meshes/gmax_1-5_xt-plus_s3d_full model_150707.stl
Normal file
BIN
resources/meshes/gmax_1-5_xt-plus_s3d_full model_150707.stl
Normal file
Binary file not shown.
@ -26,33 +26,54 @@ UM.Dialog
|
|||||||
minimumHeight: maximumHeight
|
minimumHeight: maximumHeight
|
||||||
minimumWidth: maximumWidth
|
minimumWidth: maximumWidth
|
||||||
|
|
||||||
modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
|
modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal
|
||||||
|
|
||||||
property var fileUrl
|
property var fileUrl
|
||||||
|
|
||||||
function loadProjectFile(projectFile)
|
// load the entire project
|
||||||
{
|
function loadProjectFile() {
|
||||||
UM.WorkspaceFileHandler.readLocalFile(projectFile);
|
|
||||||
|
|
||||||
var meshName = backgroundItem.getMeshName(projectFile.toString());
|
// update preference
|
||||||
backgroundItem.hasMesh(decodeURIComponent(meshName));
|
if (rememberChoiceCheckBox.checked) {
|
||||||
|
UM.Preferences.setValue("cura/choice_on_open_project", "open_as_project")
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadModelFiles(fileUrls)
|
UM.WorkspaceFileHandler.readLocalFile(base.fileUrl)
|
||||||
{
|
var meshName = backgroundItem.getMeshName(base.fileUrl.toString())
|
||||||
for (var i in fileUrls)
|
backgroundItem.hasMesh(decodeURIComponent(meshName))
|
||||||
{
|
|
||||||
CuraApplication.readLocalFile(fileUrls[i]);
|
base.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
var meshName = backgroundItem.getMeshName(fileUrls[0].toString());
|
// load the project file as separated models
|
||||||
backgroundItem.hasMesh(decodeURIComponent(meshName));
|
function loadModelFiles() {
|
||||||
|
|
||||||
|
// update preference
|
||||||
|
if (rememberChoiceCheckBox.checked) {
|
||||||
|
UM.Preferences.setValue("cura/choice_on_open_project", "open_as_model")
|
||||||
}
|
}
|
||||||
|
|
||||||
onVisibleChanged:
|
CuraApplication.readLocalFile(base.fileUrl)
|
||||||
{
|
var meshName = backgroundItem.getMeshName(base.fileUrl.toString())
|
||||||
if (visible)
|
backgroundItem.hasMesh(decodeURIComponent(meshName))
|
||||||
{
|
|
||||||
|
base.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
// override UM.Dialog accept
|
||||||
|
function accept () {
|
||||||
|
var openAsPreference = UM.Preferences.getValue("cura/choice_on_open_project")
|
||||||
|
|
||||||
|
// when hitting 'enter', we always open as project unless open_as_model was explicitly stored as preference
|
||||||
|
if (openAsPreference == "open_as_model") {
|
||||||
|
loadModelFiles()
|
||||||
|
} else {
|
||||||
|
loadProjectFile()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
var rememberMyChoice = UM.Preferences.getValue("cura/choice_on_open_project") != "always_ask";
|
var rememberMyChoice = UM.Preferences.getValue("cura/choice_on_open_project") != "always_ask";
|
||||||
rememberChoiceCheckBox.checked = rememberMyChoice;
|
rememberChoiceCheckBox.checked = rememberMyChoice;
|
||||||
}
|
}
|
||||||
@ -90,47 +111,26 @@ UM.Dialog
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
Item
|
Item {
|
||||||
{
|
|
||||||
id: buttonBar
|
id: buttonBar
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
|
|
||||||
Button
|
Button {
|
||||||
{
|
|
||||||
id: openAsProjectButton
|
id: openAsProjectButton
|
||||||
text: catalog.i18nc("@action:button", "Open as project");
|
text: catalog.i18nc("@action:button", "Open as project")
|
||||||
anchors.right: importModelsButton.left
|
anchors.right: importModelsButton.left
|
||||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||||
isDefault: true
|
isDefault: true
|
||||||
onClicked:
|
onClicked: loadProjectFile()
|
||||||
{
|
|
||||||
// update preference
|
|
||||||
if (rememberChoiceCheckBox.checked)
|
|
||||||
UM.Preferences.setValue("cura/choice_on_open_project", "open_as_project");
|
|
||||||
|
|
||||||
// load this file as project
|
|
||||||
base.hide();
|
|
||||||
loadProjectFile(base.fileUrl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Button
|
Button {
|
||||||
{
|
|
||||||
id: importModelsButton
|
id: importModelsButton
|
||||||
text: catalog.i18nc("@action:button", "Import models");
|
text: catalog.i18nc("@action:button", "Import models")
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
onClicked:
|
onClicked: loadModelFiles()
|
||||||
{
|
|
||||||
// update preference
|
|
||||||
if (rememberChoiceCheckBox.checked)
|
|
||||||
UM.Preferences.setValue("cura/choice_on_open_project", "open_as_model");
|
|
||||||
|
|
||||||
// load models from this project file
|
|
||||||
base.hide();
|
|
||||||
loadModelFiles([base.fileUrl]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ Rectangle
|
|||||||
border.width: UM.Theme.getSize("default_lining").width
|
border.width: UM.Theme.getSize("default_lining").width
|
||||||
border.color: UM.Theme.getColor("lining")
|
border.color: UM.Theme.getColor("lining")
|
||||||
|
|
||||||
property bool collapsed: false;
|
property bool collapsed: true;
|
||||||
|
|
||||||
SystemPalette { id: palette }
|
SystemPalette { id: palette }
|
||||||
|
|
||||||
|
@ -213,8 +213,8 @@ UM.ManagementPage
|
|||||||
ProfileTab
|
ProfileTab
|
||||||
{
|
{
|
||||||
title: catalog.i18nc("@title:tab", "Global Settings");
|
title: catalog.i18nc("@title:tab", "Global Settings");
|
||||||
quality: Cura.MachineManager.activeMachine.qualityChanges.id
|
quality: base.currentItem != null ? base.currentItem.id : "";
|
||||||
material: Cura.MachineManager.activeMachine.material.id
|
material: Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeMachineId]
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater
|
Repeater
|
||||||
|
@ -405,7 +405,7 @@ Column
|
|||||||
Label {
|
Label {
|
||||||
id: materialInfoLabel
|
id: materialInfoLabel
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
text: catalog.i18nc("@label", "<a href='%1'>Check compatibility</a>")
|
text: "<a href='%1'>" + catalog.i18nc("@label", "Check compatibility") + "</a>"
|
||||||
font: UM.Theme.getFont("default")
|
font: UM.Theme.getFont("default")
|
||||||
color: UM.Theme.getColor("text")
|
color: UM.Theme.getColor("text")
|
||||||
linkColor: UM.Theme.getColor("text_link")
|
linkColor: UM.Theme.getColor("text_link")
|
||||||
|
@ -11,8 +11,8 @@ setting_version = 4
|
|||||||
|
|
||||||
[values]
|
[values]
|
||||||
acceleration_enabled = True
|
acceleration_enabled = True
|
||||||
acceleration_print = 2000
|
acceleration_print = 1800
|
||||||
acceleration_travel = 3500
|
acceleration_travel = 3000
|
||||||
adhesion_type = skirt
|
adhesion_type = skirt
|
||||||
brim_width = 4.0
|
brim_width = 4.0
|
||||||
cool_fan_full_at_height = 0.5
|
cool_fan_full_at_height = 0.5
|
||||||
@ -23,16 +23,16 @@ infill_pattern = zigzag
|
|||||||
infill_sparse_density = 25
|
infill_sparse_density = 25
|
||||||
initial_layer_line_width_factor = 140
|
initial_layer_line_width_factor = 140
|
||||||
jerk_enabled = True
|
jerk_enabled = True
|
||||||
jerk_print = 13
|
jerk_print = 8
|
||||||
jerk_travel = 13
|
jerk_travel = 10
|
||||||
layer_height = 0.4
|
layer_height = 0.3
|
||||||
layer_height_0 = 0.4
|
layer_height_0 = 0.3
|
||||||
material_bed_temperature = 60
|
material_bed_temperature = 60
|
||||||
material_diameter = 1.75
|
material_diameter = 1.75
|
||||||
material_print_temperature = 200
|
material_print_temperature = 200
|
||||||
material_print_temperature_layer_0 = 0
|
material_print_temperature_layer_0 = 0
|
||||||
retract_at_layer_change = False
|
retract_at_layer_change = False
|
||||||
retraction_amount = 7
|
retraction_amount = 6
|
||||||
retraction_hop = 0.075
|
retraction_hop = 0.075
|
||||||
retraction_hop_enabled = True
|
retraction_hop_enabled = True
|
||||||
retraction_hop_only_when_collides = True
|
retraction_hop_only_when_collides = True
|
||||||
|
@ -11,8 +11,8 @@ setting_version = 4
|
|||||||
|
|
||||||
[values]
|
[values]
|
||||||
acceleration_enabled = True
|
acceleration_enabled = True
|
||||||
acceleration_print = 2000
|
acceleration_print = 1800
|
||||||
acceleration_travel = 3500
|
acceleration_travel = 3000
|
||||||
adhesion_type = skirt
|
adhesion_type = skirt
|
||||||
brim_width = 4.0
|
brim_width = 4.0
|
||||||
cool_fan_full_at_height = 0.5
|
cool_fan_full_at_height = 0.5
|
||||||
@ -23,8 +23,8 @@ infill_pattern = zigzag
|
|||||||
infill_sparse_density = 25
|
infill_sparse_density = 25
|
||||||
initial_layer_line_width_factor = 140
|
initial_layer_line_width_factor = 140
|
||||||
jerk_enabled = True
|
jerk_enabled = True
|
||||||
jerk_print = 13
|
jerk_print = 8
|
||||||
jerk_travel = 13
|
jerk_travel = 10
|
||||||
layer_height = 0.1
|
layer_height = 0.1
|
||||||
layer_height_0 = 0.1
|
layer_height_0 = 0.1
|
||||||
material_bed_temperature = 60
|
material_bed_temperature = 60
|
||||||
@ -32,7 +32,7 @@ material_diameter = 1.75
|
|||||||
material_print_temperature = 200
|
material_print_temperature = 200
|
||||||
material_print_temperature_layer_0 = 0
|
material_print_temperature_layer_0 = 0
|
||||||
retract_at_layer_change = False
|
retract_at_layer_change = False
|
||||||
retraction_amount = 7
|
retraction_amount = 6
|
||||||
retraction_hop = 0.075
|
retraction_hop = 0.075
|
||||||
retraction_hop_enabled = True
|
retraction_hop_enabled = True
|
||||||
retraction_hop_only_when_collides = True
|
retraction_hop_only_when_collides = True
|
||||||
|
@ -11,8 +11,8 @@ setting_version = 4
|
|||||||
|
|
||||||
[values]
|
[values]
|
||||||
acceleration_enabled = True
|
acceleration_enabled = True
|
||||||
acceleration_print = 2000
|
acceleration_print = 1800
|
||||||
acceleration_travel = 3500
|
acceleration_travel = 3000
|
||||||
adhesion_type = skirt
|
adhesion_type = skirt
|
||||||
brim_width = 4.0
|
brim_width = 4.0
|
||||||
cool_fan_full_at_height = 0.5
|
cool_fan_full_at_height = 0.5
|
||||||
@ -23,8 +23,8 @@ infill_pattern = zigzag
|
|||||||
infill_sparse_density = 25
|
infill_sparse_density = 25
|
||||||
initial_layer_line_width_factor = 140
|
initial_layer_line_width_factor = 140
|
||||||
jerk_enabled = True
|
jerk_enabled = True
|
||||||
jerk_print = 13
|
jerk_print = 8
|
||||||
jerk_travel = 13
|
jerk_travel = 10
|
||||||
layer_height = 0.2
|
layer_height = 0.2
|
||||||
layer_height_0 = 0.2
|
layer_height_0 = 0.2
|
||||||
material_bed_temperature = 60
|
material_bed_temperature = 60
|
||||||
@ -32,7 +32,7 @@ material_diameter = 1.75
|
|||||||
material_print_temperature = 200
|
material_print_temperature = 200
|
||||||
material_print_temperature_layer_0 = 0
|
material_print_temperature_layer_0 = 0
|
||||||
retract_at_layer_change = False
|
retract_at_layer_change = False
|
||||||
retraction_amount = 7
|
retraction_amount = 6
|
||||||
retraction_hop = 0.075
|
retraction_hop = 0.075
|
||||||
retraction_hop_enabled = True
|
retraction_hop_enabled = True
|
||||||
retraction_hop_only_when_collides = True
|
retraction_hop_only_when_collides = True
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = gMax 1.5+ Dual Normal Layers
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = normal
|
||||||
|
weight = -1
|
||||||
|
setting_version = 4
|
||||||
|
global_quality = True
|
||||||
|
|
||||||
|
[values]
|
||||||
|
layer_height = 0.2
|
||||||
|
layer_height_0 = 0.28
|
||||||
|
|
||||||
|
infill_before_walls = False
|
||||||
|
infill_overlap = 20
|
||||||
|
infill_pattern = grid
|
||||||
|
|
||||||
|
speed_slowdown_layers = 1
|
||||||
|
acceleration_enabled = True
|
||||||
|
acceleration_print = 400
|
||||||
|
acceleration_travel = 700
|
||||||
|
|
||||||
|
coasting_enable = False
|
||||||
|
coasting_volume = 0.0625
|
||||||
|
|
||||||
|
retraction_combing = off
|
||||||
|
retraction_amount = 0.75
|
||||||
|
retraction_speed = 70
|
||||||
|
material_flow = 98
|
||||||
|
material_diameter = 1.75
|
||||||
|
|
||||||
|
support_use_towers = False
|
||||||
|
support_z_distance = 0.2
|
||||||
|
support_xy_distance = 1.5
|
||||||
|
support_join_distance = 10
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_pattern = lines
|
||||||
|
|
||||||
|
adhesion_type = skirt
|
||||||
|
skirt_gap = 2
|
||||||
|
|
||||||
|
cool_fan_speed = 70
|
||||||
|
cool_fan_speed_max = 85
|
||||||
|
skin_overlap = 10
|
||||||
|
speed_print = 50
|
||||||
|
speed_infill = =math.ceil(speed_print * 0.85)
|
||||||
|
speed_layer_0 = =math.ceil(speed_print * 0.45)
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 0.75)
|
||||||
|
speed_wall = =math.ceil(speed_print * 0.5)
|
||||||
|
speed_wall_x = =math.ceil(speed_print * 0.7)
|
||||||
|
|
||||||
|
top_bottom_pattern = lines
|
||||||
|
top_layers = 4
|
||||||
|
top_thickness = 1
|
||||||
|
bottom_layers = 2
|
||||||
|
wall_line_count = 2
|
||||||
|
z_seam_corner = z_seam_corner_none
|
||||||
|
|
||||||
|
ooze_shield_angle = 20
|
||||||
|
ooze_shield_dist = 4
|
||||||
|
ooze_shield_enabled = True
|
||||||
|
prime_tower_enable = False
|
||||||
|
prime_tower_position_x = 350
|
||||||
|
prime_tower_position_y = 350
|
||||||
|
prime_tower_wall_thickness = 2
|
||||||
|
switch_extruder_retraction_amount = 6
|
||||||
|
switch_extruder_retraction_speeds = 60
|
||||||
|
|
||||||
|
material_standby_temperature = =material_print_temperature - 10
|
@ -0,0 +1,72 @@
|
|||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = gMax 1.5+ Dual Thick Layers
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = course
|
||||||
|
weight = -2
|
||||||
|
setting_version = 4
|
||||||
|
global_quality = True
|
||||||
|
|
||||||
|
[values]
|
||||||
|
layer_height = 0.28
|
||||||
|
layer_height_0 = 0.32
|
||||||
|
|
||||||
|
infill_before_walls = False
|
||||||
|
infill_overlap = 20
|
||||||
|
infill_pattern = grid
|
||||||
|
|
||||||
|
speed_slowdown_layers = 1
|
||||||
|
acceleration_enabled = True
|
||||||
|
acceleration_print = 400
|
||||||
|
acceleration_travel = 700
|
||||||
|
|
||||||
|
coasting_enable = False
|
||||||
|
coasting_volume = 0.0625
|
||||||
|
|
||||||
|
retraction_combing = off
|
||||||
|
retraction_amount = 0.75
|
||||||
|
retraction_speed = 70
|
||||||
|
material_flow = 98
|
||||||
|
material_diameter = 1.75
|
||||||
|
|
||||||
|
support_use_towers = False
|
||||||
|
support_z_distance = 0.2
|
||||||
|
support_xy_distance = 1.5
|
||||||
|
support_join_distance = 10
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_pattern = lines
|
||||||
|
|
||||||
|
adhesion_type = skirt
|
||||||
|
skirt_gap = 2
|
||||||
|
|
||||||
|
cool_fan_speed = 70
|
||||||
|
cool_fan_speed_max = 85
|
||||||
|
skin_overlap = 10
|
||||||
|
speed_print = 40
|
||||||
|
speed_infill = =math.ceil(speed_print * 0.85)
|
||||||
|
speed_layer_0 = =math.ceil(speed_print * 0.5)
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 0.75)
|
||||||
|
speed_wall = =math.ceil(speed_print * 0.5)
|
||||||
|
speed_wall_x = =math.ceil(speed_print * 0.7)
|
||||||
|
|
||||||
|
top_bottom_pattern = lines
|
||||||
|
top_layers = 3
|
||||||
|
top_thickness = 1
|
||||||
|
bottom_layers = 2
|
||||||
|
wall_line_count = 2
|
||||||
|
z_seam_corner = z_seam_corner_none
|
||||||
|
|
||||||
|
ooze_shield_angle = 20
|
||||||
|
ooze_shield_dist = 4
|
||||||
|
ooze_shield_enabled = True
|
||||||
|
prime_tower_enable = False
|
||||||
|
prime_tower_position_x = 350
|
||||||
|
prime_tower_position_y = 350
|
||||||
|
prime_tower_wall_thickness = 2
|
||||||
|
switch_extruder_retraction_amount = 6
|
||||||
|
switch_extruder_retraction_speeds = 60
|
||||||
|
|
||||||
|
material_standby_temperature = =material_print_temperature - 10
|
@ -0,0 +1,72 @@
|
|||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = gMax 1.5+ Dual Thin Layers
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = high
|
||||||
|
weight = 0
|
||||||
|
setting_version = 4
|
||||||
|
global_quality = True
|
||||||
|
|
||||||
|
[values]
|
||||||
|
layer_height = 0.16
|
||||||
|
layer_height_0 = 0.2
|
||||||
|
|
||||||
|
infill_before_walls = False
|
||||||
|
infill_overlap = 20
|
||||||
|
infill_pattern = grid
|
||||||
|
|
||||||
|
speed_slowdown_layers = 1
|
||||||
|
acceleration_enabled = True
|
||||||
|
acceleration_print = 400
|
||||||
|
acceleration_travel = 700
|
||||||
|
|
||||||
|
coasting_enable = False
|
||||||
|
coasting_volume = 0.0625
|
||||||
|
|
||||||
|
retraction_combing = off
|
||||||
|
retraction_amount = 0.75
|
||||||
|
retraction_speed = 70
|
||||||
|
material_flow = 98
|
||||||
|
material_diameter = 1.75
|
||||||
|
|
||||||
|
support_use_towers = False
|
||||||
|
support_z_distance = 0.2
|
||||||
|
support_xy_distance = 1.5
|
||||||
|
support_join_distance = 10
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_pattern = lines
|
||||||
|
|
||||||
|
adhesion_type = skirt
|
||||||
|
skirt_gap = 2
|
||||||
|
|
||||||
|
cool_fan_speed = 70
|
||||||
|
cool_fan_speed_max = 85
|
||||||
|
skin_overlap = 10
|
||||||
|
speed_print = 40
|
||||||
|
speed_infill = =math.ceil(speed_print * 0.85)
|
||||||
|
speed_layer_0 = =math.ceil(speed_print * 0.4)
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 0.75)
|
||||||
|
speed_wall = =math.ceil(speed_print * 0.5)
|
||||||
|
speed_wall_x = =math.ceil(speed_print * 0.7)
|
||||||
|
|
||||||
|
top_bottom_pattern = lines
|
||||||
|
top_layers = 4
|
||||||
|
top_thickness = 1
|
||||||
|
bottom_layers = 2
|
||||||
|
wall_line_count = 2
|
||||||
|
z_seam_corner = z_seam_corner_none
|
||||||
|
|
||||||
|
ooze_shield_angle = 20
|
||||||
|
ooze_shield_dist = 4
|
||||||
|
ooze_shield_enabled = True
|
||||||
|
prime_tower_enable = False
|
||||||
|
prime_tower_position_x = 350
|
||||||
|
prime_tower_position_y = 350
|
||||||
|
prime_tower_wall_thickness = 2
|
||||||
|
switch_extruder_retraction_amount = 6
|
||||||
|
switch_extruder_retraction_speeds = 60
|
||||||
|
|
||||||
|
material_standby_temperature = =material_print_temperature - 10
|
@ -0,0 +1,71 @@
|
|||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = gMax 1.5+ Dual Very Thick Layers
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = extra_course
|
||||||
|
weight = -3
|
||||||
|
setting_version = 4
|
||||||
|
global_quality = True
|
||||||
|
|
||||||
|
[values]
|
||||||
|
layer_height = 0.32
|
||||||
|
|
||||||
|
infill_before_walls = False
|
||||||
|
infill_overlap = 20
|
||||||
|
infill_pattern = grid
|
||||||
|
|
||||||
|
speed_slowdown_layers = 1
|
||||||
|
acceleration_enabled = True
|
||||||
|
acceleration_print = 400
|
||||||
|
acceleration_travel = 700
|
||||||
|
|
||||||
|
coasting_enable = False
|
||||||
|
coasting_volume = 0.0625
|
||||||
|
|
||||||
|
retraction_combing = off
|
||||||
|
retraction_amount = 0.75
|
||||||
|
retraction_speed = 70
|
||||||
|
material_flow = 98
|
||||||
|
material_diameter = 1.75
|
||||||
|
|
||||||
|
support_use_towers = False
|
||||||
|
support_z_distance = 0.2
|
||||||
|
support_xy_distance = 1.5
|
||||||
|
support_join_distance = 10
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_pattern = lines
|
||||||
|
|
||||||
|
adhesion_type = skirt
|
||||||
|
skirt_gap = 2
|
||||||
|
|
||||||
|
cool_fan_speed = 70
|
||||||
|
cool_fan_speed_max = 85
|
||||||
|
skin_overlap = 10
|
||||||
|
speed_print = 40
|
||||||
|
speed_infill = =math.ceil(speed_print * 0.85)
|
||||||
|
speed_layer_0 = =math.ceil(speed_print * 0.45)
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 0.75)
|
||||||
|
speed_wall = =math.ceil(speed_print * 0.5)
|
||||||
|
speed_wall_x = =math.ceil(speed_print * 0.7)
|
||||||
|
|
||||||
|
top_bottom_pattern = lines
|
||||||
|
top_layers = 3
|
||||||
|
top_thickness = 1
|
||||||
|
bottom_layers = 2
|
||||||
|
wall_line_count = 2
|
||||||
|
z_seam_corner = z_seam_corner_none
|
||||||
|
|
||||||
|
ooze_shield_angle = 20
|
||||||
|
ooze_shield_dist = 4
|
||||||
|
ooze_shield_enabled = True
|
||||||
|
prime_tower_enable = False
|
||||||
|
prime_tower_position_x = 350
|
||||||
|
prime_tower_position_y = 350
|
||||||
|
prime_tower_wall_thickness = 2
|
||||||
|
switch_extruder_retraction_amount = 6
|
||||||
|
switch_extruder_retraction_speeds = 60
|
||||||
|
|
||||||
|
material_standby_temperature = =material_print_temperature - 10
|
62
resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg
Normal file
62
resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = gMax 1.5+ Normal Layers
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = normal
|
||||||
|
weight = -1
|
||||||
|
setting_version = 4
|
||||||
|
global_quality = True
|
||||||
|
|
||||||
|
[values]
|
||||||
|
layer_height = 0.2
|
||||||
|
layer_height_0 = 0.28
|
||||||
|
|
||||||
|
infill_before_walls = False
|
||||||
|
infill_overlap = 20
|
||||||
|
infill_pattern = grid
|
||||||
|
|
||||||
|
speed_slowdown_layers = 1
|
||||||
|
acceleration_enabled = True
|
||||||
|
acceleration_print = 400
|
||||||
|
acceleration_travel = 700
|
||||||
|
|
||||||
|
coasting_enable = False
|
||||||
|
coasting_volume = 0.0625
|
||||||
|
|
||||||
|
retraction_combing = off
|
||||||
|
retraction_amount = 0.75
|
||||||
|
retraction_speed = 70
|
||||||
|
material_flow = 98
|
||||||
|
material_diameter = 1.75
|
||||||
|
|
||||||
|
support_use_towers = False
|
||||||
|
support_z_distance = 0.2
|
||||||
|
support_xy_distance = 1.5
|
||||||
|
support_join_distance = 10
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_pattern = lines
|
||||||
|
|
||||||
|
adhesion_type = skirt
|
||||||
|
skirt_gap = 2
|
||||||
|
|
||||||
|
cool_fan_speed = 70
|
||||||
|
cool_fan_speed_max = 85
|
||||||
|
skin_overlap = 10
|
||||||
|
speed_print = 50
|
||||||
|
speed_infill = =math.ceil(speed_print * 0.85)
|
||||||
|
speed_layer_0 = =math.ceil(speed_print * 0.6)
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 0.75)
|
||||||
|
speed_wall = =math.ceil(speed_print * 0.5)
|
||||||
|
speed_wall_x = =math.ceil(speed_wall * 0.7)
|
||||||
|
|
||||||
|
top_bottom_pattern = lines
|
||||||
|
top_layers = 4
|
||||||
|
top_thickness = 1
|
||||||
|
bottom_layers = 2
|
||||||
|
wall_line_count = 2
|
||||||
|
z_seam_corner = z_seam_corner_none
|
||||||
|
|
||||||
|
|
60
resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg
Normal file
60
resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = gMax 1.5+ Thick Layers
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = course
|
||||||
|
weight = -2
|
||||||
|
setting_version = 4
|
||||||
|
global_quality = True
|
||||||
|
|
||||||
|
[values]
|
||||||
|
layer_height = 0.28
|
||||||
|
layer_height_0 = 0.32
|
||||||
|
|
||||||
|
infill_before_walls = False
|
||||||
|
infill_overlap = 20
|
||||||
|
infill_pattern = grid
|
||||||
|
|
||||||
|
speed_slowdown_layers = 1
|
||||||
|
acceleration_enabled = True
|
||||||
|
acceleration_print = 400
|
||||||
|
acceleration_travel = 700
|
||||||
|
|
||||||
|
coasting_enable = False
|
||||||
|
coasting_volume = 0.0625
|
||||||
|
|
||||||
|
retraction_combing = off
|
||||||
|
retraction_amount = 0.75
|
||||||
|
retraction_speed = 70
|
||||||
|
material_flow = 98
|
||||||
|
material_diameter = 1.75
|
||||||
|
|
||||||
|
support_use_towers = False
|
||||||
|
support_z_distance = 0.2
|
||||||
|
support_xy_distance = 1.5
|
||||||
|
support_join_distance = 10
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_pattern = lines
|
||||||
|
|
||||||
|
adhesion_type = skirt
|
||||||
|
skirt_gap = 2
|
||||||
|
|
||||||
|
cool_fan_speed = 70
|
||||||
|
cool_fan_speed_max = 85
|
||||||
|
skin_overlap = 10
|
||||||
|
speed_print = 50
|
||||||
|
speed_infill = =math.ceil(speed_print * 0.85)
|
||||||
|
speed_layer_0 = =math.ceil(speed_print * 0.6)
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 0.75)
|
||||||
|
speed_wall = =math.ceil(speed_print * 0.5)
|
||||||
|
speed_wall_x = =math.ceil(speed_wall * 0.7)
|
||||||
|
|
||||||
|
top_bottom_pattern = lines
|
||||||
|
top_layers = 3
|
||||||
|
top_thickness = 1
|
||||||
|
bottom_layers = 2
|
||||||
|
wall_line_count = 2
|
||||||
|
z_seam_corner = z_seam_corner_none
|
60
resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg
Normal file
60
resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = gMax 1.5+ Thin Layers
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = high
|
||||||
|
weight = 0
|
||||||
|
setting_version = 4
|
||||||
|
global_quality = True
|
||||||
|
|
||||||
|
[values]
|
||||||
|
layer_height = 0.16
|
||||||
|
layer_height_0 = 0.2
|
||||||
|
|
||||||
|
infill_before_walls = False
|
||||||
|
infill_overlap = 20
|
||||||
|
infill_pattern = grid
|
||||||
|
|
||||||
|
speed_slowdown_layers = 1
|
||||||
|
acceleration_enabled = True
|
||||||
|
acceleration_print = 400
|
||||||
|
acceleration_travel = 700
|
||||||
|
|
||||||
|
coasting_enable = False
|
||||||
|
coasting_volume = 0.0625
|
||||||
|
|
||||||
|
retraction_combing = off
|
||||||
|
retraction_amount = 0.75
|
||||||
|
retraction_speed = 70
|
||||||
|
material_flow = 98
|
||||||
|
material_diameter = 1.75
|
||||||
|
|
||||||
|
support_use_towers = False
|
||||||
|
support_z_distance = 0.2
|
||||||
|
support_xy_distance = 1.5
|
||||||
|
support_join_distance = 10
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_pattern = lines
|
||||||
|
|
||||||
|
adhesion_type = skirt
|
||||||
|
skirt_gap = 2
|
||||||
|
|
||||||
|
cool_fan_speed = 70
|
||||||
|
cool_fan_speed_max = 85
|
||||||
|
skin_overlap = 10
|
||||||
|
speed_print = 55
|
||||||
|
speed_infill = =math.ceil(speed_print * 0.85)
|
||||||
|
speed_layer_0 = =math.ceil(speed_print * 0.6)
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 0.75)
|
||||||
|
speed_wall = =math.ceil(speed_print * 0.5)
|
||||||
|
speed_wall_x = =math.ceil(speed_wall * 0.7)
|
||||||
|
|
||||||
|
top_bottom_pattern = lines
|
||||||
|
top_layers = 5
|
||||||
|
top_thickness = 1
|
||||||
|
bottom_layers = 3
|
||||||
|
wall_line_count = 2
|
||||||
|
z_seam_corner = z_seam_corner_none
|
@ -0,0 +1,59 @@
|
|||||||
|
[general]
|
||||||
|
version = 2
|
||||||
|
name = gMax 1.5+ Very Thick Layers
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
type = quality
|
||||||
|
quality_type = extra_course
|
||||||
|
weight = -3
|
||||||
|
setting_version = 4
|
||||||
|
global_quality = True
|
||||||
|
|
||||||
|
[values]
|
||||||
|
layer_height = 0.32
|
||||||
|
|
||||||
|
infill_before_walls = False
|
||||||
|
infill_overlap = 20
|
||||||
|
infill_pattern = grid
|
||||||
|
|
||||||
|
speed_slowdown_layers = 1
|
||||||
|
acceleration_enabled = True
|
||||||
|
acceleration_print = 400
|
||||||
|
acceleration_travel = 700
|
||||||
|
|
||||||
|
coasting_enable = False
|
||||||
|
coasting_volume = 0.0625
|
||||||
|
|
||||||
|
retraction_combing = off
|
||||||
|
retraction_amount = 0.75
|
||||||
|
retraction_speed = 70
|
||||||
|
material_flow = 98
|
||||||
|
material_diameter = 1.75
|
||||||
|
|
||||||
|
support_use_towers = False
|
||||||
|
support_z_distance = 0.2
|
||||||
|
support_xy_distance = 1.5
|
||||||
|
support_join_distance = 10
|
||||||
|
support_interface_enable = True
|
||||||
|
support_interface_pattern = lines
|
||||||
|
|
||||||
|
adhesion_type = skirt
|
||||||
|
skirt_gap = 2
|
||||||
|
|
||||||
|
cool_fan_speed = 70
|
||||||
|
cool_fan_speed_max = 85
|
||||||
|
skin_overlap = 10
|
||||||
|
speed_print = 45
|
||||||
|
speed_infill = =math.ceil(speed_print * 0.85)
|
||||||
|
speed_layer_0 = =math.ceil(speed_print * 0.6)
|
||||||
|
speed_topbottom = =math.ceil(speed_print * 0.75)
|
||||||
|
speed_wall = =math.ceil(speed_print * 0.6)
|
||||||
|
speed_wall_x = =math.ceil(speed_wall * 0.7)
|
||||||
|
|
||||||
|
top_bottom_pattern = lines
|
||||||
|
top_layers = 3
|
||||||
|
top_thickness = 1
|
||||||
|
bottom_layers = 2
|
||||||
|
wall_line_count = 2
|
||||||
|
z_seam_corner = z_seam_corner_none
|
@ -12,7 +12,7 @@ setting_version = 4
|
|||||||
[values]
|
[values]
|
||||||
brim_width = 4.0
|
brim_width = 4.0
|
||||||
infill_pattern = zigzag
|
infill_pattern = zigzag
|
||||||
layer_height = 0.4
|
layer_height = 0.3
|
||||||
material_diameter = 1.75
|
material_diameter = 1.75
|
||||||
speed_infill = 50
|
speed_infill = 50
|
||||||
speed_print = 50
|
speed_print = 50
|
||||||
|
@ -7,6 +7,7 @@ definition = cartesio
|
|||||||
author = Cartesio
|
author = Cartesio
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.25
|
machine_nozzle_size = 0.25
|
||||||
|
@ -7,6 +7,7 @@ definition = cartesio
|
|||||||
author = Cartesio
|
author = Cartesio
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.4
|
machine_nozzle_size = 0.4
|
||||||
|
@ -7,6 +7,7 @@ definition = cartesio
|
|||||||
author = Cartesio
|
author = Cartesio
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.8
|
machine_nozzle_size = 0.8
|
||||||
|
@ -7,6 +7,7 @@ definition = fabtotum
|
|||||||
author = FABtotum
|
author = FABtotum
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.35
|
machine_nozzle_size = 0.35
|
||||||
|
@ -7,6 +7,7 @@ definition = fabtotum
|
|||||||
author = FABtotum
|
author = FABtotum
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.4
|
machine_nozzle_size = 0.4
|
||||||
|
@ -7,6 +7,7 @@ definition = fabtotum
|
|||||||
author = FABtotum
|
author = FABtotum
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.6
|
machine_nozzle_size = 0.6
|
||||||
|
@ -7,6 +7,7 @@ definition = fabtotum
|
|||||||
author = FABtotum
|
author = FABtotum
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.2
|
machine_nozzle_size = 0.2
|
||||||
|
@ -7,6 +7,7 @@ definition = fabtotum
|
|||||||
author = FABtotum
|
author = FABtotum
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.4
|
machine_nozzle_size = 0.4
|
||||||
|
@ -7,6 +7,7 @@ definition = fabtotum
|
|||||||
author = FABtotum
|
author = FABtotum
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.6
|
machine_nozzle_size = 0.6
|
||||||
|
@ -7,6 +7,7 @@ definition = fabtotum
|
|||||||
author = FABtotum
|
author = FABtotum
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.8
|
machine_nozzle_size = 0.8
|
||||||
|
12
resources/variants/gmax15plus_025_e3d.inst.cfg
Normal file
12
resources/variants/gmax15plus_025_e3d.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.25mm E3D (Difficult)
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.25
|
12
resources/variants/gmax15plus_04_e3d.inst.cfg
Normal file
12
resources/variants/gmax15plus_04_e3d.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.4mm E3D
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.4
|
12
resources/variants/gmax15plus_05_e3d.inst.cfg
Normal file
12
resources/variants/gmax15plus_05_e3d.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.5mm E3D (Default)
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.5
|
12
resources/variants/gmax15plus_05_jhead.inst.cfg
Normal file
12
resources/variants/gmax15plus_05_jhead.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.5mm J-Head
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.5
|
12
resources/variants/gmax15plus_06_e3d.inst.cfg
Normal file
12
resources/variants/gmax15plus_06_e3d.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.6mm E3D
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.6
|
12
resources/variants/gmax15plus_08_e3d.inst.cfg
Normal file
12
resources/variants/gmax15plus_08_e3d.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.8mm E3D
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.8
|
12
resources/variants/gmax15plus_10_jhead.inst.cfg
Normal file
12
resources/variants/gmax15plus_10_jhead.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 1.0mm J-Head
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.5
|
12
resources/variants/gmax15plus_dual_025_e3d.inst.cfg
Normal file
12
resources/variants/gmax15plus_dual_025_e3d.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.25mm E3D (Difficult)
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.25
|
12
resources/variants/gmax15plus_dual_04_e3d.inst.cfg
Normal file
12
resources/variants/gmax15plus_dual_04_e3d.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.4mm E3D
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.4
|
12
resources/variants/gmax15plus_dual_05_e3d.inst.cfg
Normal file
12
resources/variants/gmax15plus_dual_05_e3d.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.5mm E3D (Default)
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.5
|
12
resources/variants/gmax15plus_dual_05_jhead.inst.cfg
Normal file
12
resources/variants/gmax15plus_dual_05_jhead.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.5mm J-Head
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.5
|
12
resources/variants/gmax15plus_dual_06_e3d.inst.cfg
Normal file
12
resources/variants/gmax15plus_dual_06_e3d.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.6mm E3D
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.6
|
12
resources/variants/gmax15plus_dual_08_e3d.inst.cfg
Normal file
12
resources/variants/gmax15plus_dual_08_e3d.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 0.8mm E3D
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.8
|
12
resources/variants/gmax15plus_dual_10_jhead.inst.cfg
Normal file
12
resources/variants/gmax15plus_dual_10_jhead.inst.cfg
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[general]
|
||||||
|
name = 1.0mm J-Head
|
||||||
|
version = 2
|
||||||
|
definition = gmax15plus_dual
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
author = gcreate
|
||||||
|
type = variant
|
||||||
|
setting_version = 4
|
||||||
|
|
||||||
|
[values]
|
||||||
|
machine_nozzle_size = 0.5
|
@ -7,6 +7,7 @@ definition = imade3d_jellybox
|
|||||||
author = IMADE3D
|
author = IMADE3D
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.4
|
machine_nozzle_size = 0.4
|
||||||
|
@ -7,6 +7,7 @@ definition = imade3d_jellybox
|
|||||||
author = IMADE3D
|
author = IMADE3D
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.4
|
machine_nozzle_size = 0.4
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.25
|
machine_nozzle_size = 0.25
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.4
|
machine_nozzle_size = 0.4
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.6
|
machine_nozzle_size = 0.6
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.8
|
machine_nozzle_size = 0.8
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2_extended
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.25
|
machine_nozzle_size = 0.25
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2_extended
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.4
|
machine_nozzle_size = 0.4
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2_extended
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.6
|
machine_nozzle_size = 0.6
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2_extended
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.8
|
machine_nozzle_size = 0.8
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.25
|
machine_nozzle_size = 0.25
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.4
|
machine_nozzle_size = 0.4
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.6
|
machine_nozzle_size = 0.6
|
||||||
|
@ -7,6 +7,7 @@ definition = ultimaker2_extended_plus
|
|||||||
author = Ultimaker
|
author = Ultimaker
|
||||||
type = variant
|
type = variant
|
||||||
setting_version = 4
|
setting_version = 4
|
||||||
|
hardware_type = nozzle
|
||||||
|
|
||||||
[values]
|
[values]
|
||||||
machine_nozzle_size = 0.8
|
machine_nozzle_size = 0.8
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user