Merge branch 'libArachne_rebased' into CURA-7555_Beading_strategy_user_control

This commit is contained in:
Kostas Karmas 2020-08-20 17:16:10 +02:00
commit 8f58a7e3a0
135 changed files with 529 additions and 478 deletions

View File

@ -30,24 +30,16 @@ configure_file(${CMAKE_SOURCE_DIR}/cura.desktop.in ${CMAKE_BINARY_DIR}/cura.desk
configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY) configure_file(cura/CuraVersion.py.in CuraVersion.py @ONLY)
# FIXME: Remove the code for CMake <3.12 once we have switched over completely. # FIXME: The new FindPython3 finds the system's Python3.6 reather than the Python3.5 that we built for Cura's environment.
# FindPython3 is a new module since CMake 3.12. It deprecates FindPythonInterp and FindPythonLibs. The FindPython3 # So we're using the old method here, with FindPythonInterp for now.
# module is copied from the CMake repository here so in CMake <3.12 we can still use it. find_package(PythonInterp 3 REQUIRED)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
# Use FindPythonInterp and FindPythonLibs for CMake <3.12
find_package(PythonInterp 3 REQUIRED)
set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE}) set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
set(Python3_VERSION ${PYTHON_VERSION_STRING})
set(Python3_VERSION_MAJOR ${PYTHON_VERSION_MAJOR})
set(Python3_VERSION_MINOR ${PYTHON_VERSION_MINOR})
set(Python3_VERSION_PATCH ${PYTHON_VERSION_PATCH})
else()
# Use FindPython3 for CMake >=3.12
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
endif()
set(Python3_VERSION ${PYTHON_VERSION_STRING})
set(Python3_VERSION_MAJOR ${PYTHON_VERSION_MAJOR})
set(Python3_VERSION_MINOR ${PYTHON_VERSION_MINOR})
set(Python3_VERSION_PATCH ${PYTHON_VERSION_PATCH})
if(NOT ${URANIUM_DIR} STREQUAL "") if(NOT ${URANIUM_DIR} STREQUAL "")
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${URANIUM_DIR}/cmake") set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${URANIUM_DIR}/cmake")

View File

@ -4,18 +4,11 @@
include(CTest) include(CTest)
include(CMakeParseArguments) include(CMakeParseArguments)
# FIXME: Remove the code for CMake <3.12 once we have switched over completely. # FIXME: The new FindPython3 finds the system's Python3.6 reather than the Python3.5 that we built for Cura's environment.
# FindPython3 is a new module since CMake 3.12. It deprecates FindPythonInterp and FindPythonLibs. The FindPython3 # So we're using the old method here, with FindPythonInterp for now.
# module is copied from the CMake repository here so in CMake <3.12 we can still use it. find_package(PythonInterp 3 REQUIRED)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
# Use FindPythonInterp and FindPythonLibs for CMake <3.12
find_package(PythonInterp 3 REQUIRED)
set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE}) set(Python3_EXECUTABLE ${PYTHON_EXECUTABLE})
else()
# Use FindPython3 for CMake >=3.12
find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
endif()
add_custom_target(test-verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose) add_custom_target(test-verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose)

View File

@ -76,8 +76,8 @@ class PreviewPass(RenderPass):
Logger.error("Unable to compile shader program: overhang.shader") Logger.error("Unable to compile shader program: overhang.shader")
if not self._non_printing_shader: if not self._non_printing_shader:
self._non_printing_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "transparent_object.shader"))
if self._non_printing_shader: if self._non_printing_shader:
self._non_printing_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "transparent_object.shader"))
self._non_printing_shader.setUniformValue("u_diffuseColor", [0.5, 0.5, 0.5, 0.5]) self._non_printing_shader.setUniformValue("u_diffuseColor", [0.5, 0.5, 0.5, 0.5])
self._non_printing_shader.setUniformValue("u_opacity", 0.6) self._non_printing_shader.setUniformValue("u_opacity", 0.6)

View File

@ -122,6 +122,8 @@ class ContainerManager(QObject):
root_material.setMetaDataEntry(entry_name, entry_value) root_material.setMetaDataEntry(entry_name, entry_value)
if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed. if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed.
root_material.metaDataChanged.emit(root_material) root_material.metaDataChanged.emit(root_material)
cura.CuraApplication.CuraApplication.getInstance().getMachineManager().updateUponMaterialMetadataChange()
return True return True
@pyqtSlot(str, result = str) @pyqtSlot(str, result = str)

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Any, cast, List, Optional from typing import Any, cast, List, Optional, Dict
from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject from PyQt5.QtCore import pyqtProperty, pyqtSignal, QObject
from UM.Application import Application from UM.Application import Application
@ -60,6 +60,8 @@ class CuraContainerStack(ContainerStack):
import cura.CuraApplication #Here to prevent circular imports. import cura.CuraApplication #Here to prevent circular imports.
self.setMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.SettingVersion) self.setMetaDataEntry("setting_version", cura.CuraApplication.CuraApplication.SettingVersion)
self._settable_per_extruder_cache = {} # type: Dict[str, Any]
self.setDirty(False) self.setDirty(False)
# This is emitted whenever the containersChanged signal from the ContainerStack base class is emitted. # This is emitted whenever the containersChanged signal from the ContainerStack base class is emitted.
@ -387,6 +389,18 @@ class CuraContainerStack(ContainerStack):
value = int(Application.getInstance().getMachineManager().defaultExtruderPosition) value = int(Application.getInstance().getMachineManager().defaultExtruderPosition)
return value return value
def getProperty(self, key: str, property_name: str, context = None) -> Any:
if property_name == "settable_per_extruder":
# Setable per extruder isn't a value that can ever change. So once we requested it once, we can just keep
# that in memory.
try:
return self._settable_per_extruder_cache[key]
except KeyError:
self._settable_per_extruder_cache[key] = super().getProperty(key, property_name, context)
return self._settable_per_extruder_cache[key]
return super().getProperty(key, property_name, context)
class _ContainerIndexes: class _ContainerIndexes:
"""Private helper class to keep track of container positions and their types.""" """Private helper class to keep track of container positions and their types."""

View File

@ -16,13 +16,13 @@ from .ExtruderStack import ExtruderStack
class CuraStackBuilder: class CuraStackBuilder:
"""Contains helper functions to create new machines.""" """Contains helper functions to create new machines."""
@classmethod @classmethod
def createMachine(cls, name: str, definition_id: str) -> Optional[GlobalStack]: def createMachine(cls, name: str, definition_id: str, machine_extruder_count: Optional[int] = None) -> Optional[GlobalStack]:
"""Create a new instance of a machine. """Create a new instance of a machine.
:param name: The name of the new machine. :param name: The name of the new machine.
:param definition_id: The ID of the machine definition to use. :param definition_id: The ID of the machine definition to use.
:param machine_extruder_count: The number of extruders in the machine.
:return: The new global stack or None if an error occurred. :return: The new global stack or None if an error occurred.
""" """
@ -66,7 +66,14 @@ class CuraStackBuilder:
Logger.logException("e", "Failed to create an extruder stack for position {pos}: {err}".format(pos = position, err = str(e))) Logger.logException("e", "Failed to create an extruder stack for position {pos}: {err}".format(pos = position, err = str(e)))
return None return None
for new_extruder in new_global_stack.extruderList: # Only register the extruders if we're sure that all of them are correct. # If given, set the machine_extruder_count when creating the machine, or else the extruderList used bellow will
# not return the correct extruder list (since by default, the machine_extruder_count is 1) in machines with
# settable number of extruders.
if machine_extruder_count and 0 <= machine_extruder_count <= len(extruder_dict):
new_global_stack.setProperty("machine_extruder_count", "value", machine_extruder_count)
# Only register the extruders if we're sure that all of them are correct.
for new_extruder in new_global_stack.extruderList:
registry.addContainer(new_extruder) registry.addContainer(new_extruder)
# Register the global stack after the extruder stacks are created. This prevents the registry from adding another # Register the global stack after the extruder stacks are created. This prevents the registry from adding another

View File

@ -131,13 +131,13 @@ class ExtruderStack(CuraContainerStack):
if not self._next_stack: if not self._next_stack:
raise Exceptions.NoGlobalStackError("Extruder {id} is missing the next stack!".format(id = self.id)) raise Exceptions.NoGlobalStackError("Extruder {id} is missing the next stack!".format(id = self.id))
if context is None: if context:
context = PropertyEvaluationContext() context.pushContainer(self)
context.pushContainer(self)
if not super().getProperty(key, "settable_per_extruder", context): if not super().getProperty(key, "settable_per_extruder", context):
result = self.getNextStack().getProperty(key, property_name, context) result = self.getNextStack().getProperty(key, property_name, context)
context.popContainer() if context:
context.popContainer()
return result return result
limit_to_extruder = super().getProperty(key, "limit_to_extruder", context) limit_to_extruder = super().getProperty(key, "limit_to_extruder", context)
@ -150,13 +150,15 @@ class ExtruderStack(CuraContainerStack):
try: try:
result = self.getNextStack().extruderList[int(limit_to_extruder)].getProperty(key, property_name, context) result = self.getNextStack().extruderList[int(limit_to_extruder)].getProperty(key, property_name, context)
if result is not None: if result is not None:
context.popContainer() if context:
context.popContainer()
return result return result
except IndexError: except IndexError:
pass pass
result = super().getProperty(key, property_name, context) result = super().getProperty(key, property_name, context)
context.popContainer() if context:
context.popContainer()
return result return result
@override(CuraContainerStack) @override(CuraContainerStack)

View File

@ -211,9 +211,8 @@ class GlobalStack(CuraContainerStack):
if not self.definition.findDefinitions(key = key): if not self.definition.findDefinitions(key = key):
return None return None
if context is None: if context:
context = PropertyEvaluationContext() context.pushContainer(self)
context.pushContainer(self)
# Handle the "resolve" property. # Handle the "resolve" property.
#TODO: Why the hell does this involve threading? #TODO: Why the hell does this involve threading?
@ -238,13 +237,15 @@ class GlobalStack(CuraContainerStack):
if super().getProperty(key, "settable_per_extruder", context): if super().getProperty(key, "settable_per_extruder", context):
result = self._extruders[str(limit_to_extruder)].getProperty(key, property_name, context) result = self._extruders[str(limit_to_extruder)].getProperty(key, property_name, context)
if result is not None: if result is not None:
context.popContainer() if context:
context.popContainer()
return result return result
else: else:
Logger.log("e", "Setting {setting} has limit_to_extruder but is not settable per extruder!", setting = key) Logger.log("e", "Setting {setting} has limit_to_extruder but is not settable per extruder!", setting = key)
result = super().getProperty(key, property_name, context) result = super().getProperty(key, property_name, context)
context.popContainer() if context:
context.popContainer()
return result return result
@override(ContainerStack) @override(ContainerStack)
@ -256,8 +257,6 @@ class GlobalStack(CuraContainerStack):
raise Exceptions.InvalidOperationError("Global stack cannot have a next stack!") raise Exceptions.InvalidOperationError("Global stack cannot have a next stack!")
# protected:
# Determine whether or not we should try to get the "resolve" property instead of the # Determine whether or not we should try to get the "resolve" property instead of the
# requested property. # requested property.
def _shouldResolve(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> bool: def _shouldResolve(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> bool:
@ -265,6 +264,10 @@ 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 not self.definition.getProperty(key, "resolve"):
# If there isn't a resolve set for this setting, there isn't anything to do here.
return False
current_thread = threading.current_thread() current_thread = threading.current_thread()
if key in self._resolving_settings[current_thread.name]: 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
@ -273,10 +276,8 @@ class GlobalStack(CuraContainerStack):
# track all settings that are being resolved. # track all settings that are being resolved.
return False return False
setting_state = super().getProperty(key, "state", context = context) if self.hasUserValue(key):
if setting_state is not None and setting_state != InstanceState.Default: # When the user has explicitly set a value, we should ignore any resolve and just return that value.
# When the user has explicitly set a value, we should ignore any resolve and
# just return that value.
return False return False
return True return True

View File

@ -1212,9 +1212,8 @@ class MachineManager(QObject):
return return
if not available_quality_types: if not available_quality_types:
if global_stack.qualityChanges == empty_quality_changes_container: Logger.log("i", "No available quality types found, setting all qualities to empty (Not Supported).")
Logger.log("i", "No available quality types found, setting all qualities to empty (Not Supported).") self._setEmptyQuality()
self._setEmptyQuality()
return return
if current_quality_type in available_quality_types: if current_quality_type in available_quality_types:
@ -1704,7 +1703,7 @@ class MachineManager(QObject):
return False return False
return global_stack.qualityChanges != empty_quality_changes_container return global_stack.qualityChanges != empty_quality_changes_container
def _updateUponMaterialMetadataChange(self) -> None: def updateUponMaterialMetadataChange(self) -> None:
if self._global_container_stack is None: if self._global_container_stack is None:
return return
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):

View File

@ -506,6 +506,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# Now we know which material is in which extruder. Let's use that to sort the material_labels according to # Now we know which material is in which extruder. Let's use that to sort the material_labels according to
# their extruder position # their extruder position
material_labels = [material_name for pos, material_name in sorted(materials_in_extruders_dict.items())] material_labels = [material_name for pos, material_name in sorted(materials_in_extruders_dict.items())]
machine_extruder_count = self._getMachineExtruderCount()
if machine_extruder_count:
material_labels = material_labels[:machine_extruder_count]
num_visible_settings = 0 num_visible_settings = 0
try: try:
@ -665,7 +668,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# We need to create a new machine # We need to create a new machine
machine_name = self._container_registry.uniqueName(self._machine_info.name) machine_name = self._container_registry.uniqueName(self._machine_info.name)
global_stack = CuraStackBuilder.createMachine(machine_name, self._machine_info.definition_id) # Printers with modifiable number of extruders (such as CFFF) will specify a machine_extruder_count in their
# quality_changes file. If that's the case, take the extruder count into account when creating the machine
# or else the extruderList will return only the first extruder, leading to missing non-global settings in
# the other extruders.
machine_extruder_count = self._getMachineExtruderCount() # type: Optional[int]
global_stack = CuraStackBuilder.createMachine(machine_name, self._machine_info.definition_id, machine_extruder_count)
if global_stack: # Only switch if creating the machine was successful. if global_stack: # Only switch if creating the machine was successful.
extruder_stack_dict = {str(position): extruder for position, extruder in enumerate(global_stack.extruderList)} extruder_stack_dict = {str(position): extruder for position, extruder in enumerate(global_stack.extruderList)}
@ -922,6 +930,29 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._machine_info.quality_changes_info.name = quality_changes_name self._machine_info.quality_changes_info.name = quality_changes_name
def _getMachineExtruderCount(self) -> Optional[int]:
"""
Extracts the machine extruder count from the definition_changes file of the printer. If it is not specified in
the file, None is returned instead.
:return: The count of the machine's extruders
"""
machine_extruder_count = None
if self._machine_info \
and self._machine_info.definition_changes_info \
and "values" in self._machine_info.definition_changes_info.parser \
and "machine_extruder_count" in self._machine_info.definition_changes_info.parser["values"]:
try:
# Theoretically, if the machine_extruder_count is a setting formula (e.g. "=3"), this will produce a
# value error and the project file loading will load the settings in the first extruder only.
# This is not expected to happen though, since all machine definitions define the machine_extruder_count
# as an integer.
machine_extruder_count = int(self._machine_info.definition_changes_info.parser["values"]["machine_extruder_count"])
except ValueError:
Logger.log("w", "'machine_extruder_count' in file '{file_name}' is not a number."
.format(file_name = self._machine_info.definition_changes_info.file_name))
return machine_extruder_count
def _createNewQualityChanges(self, quality_type: str, intent_category: Optional[str], name: str, global_stack: GlobalStack, extruder_stack: Optional[ExtruderStack]) -> InstanceContainer: def _createNewQualityChanges(self, quality_type: str, intent_category: Optional[str], name: str, global_stack: GlobalStack, extruder_stack: Optional[ExtruderStack]) -> InstanceContainer:
"""Helper class to create a new quality changes profile. """Helper class to create a new quality changes profile.

View File

@ -51,7 +51,7 @@
# M207 S<mm> F<mm/m> - set the retract length <S> or feed rate <F> # M207 S<mm> F<mm/m> - set the retract length <S> or feed rate <F>
# M117 - output the current changes # M117 - output the current changes
from typing import List, Optional, Dict from typing import List, Dict
from ..Script import Script from ..Script import Script
import re import re
@ -336,7 +336,7 @@ class ChangeAtZ(Script):
caz_instance = ChangeAtZProcessor() caz_instance = ChangeAtZProcessor()
caz_instance.TargetValues = {} caz_instance.targetValues = {}
# copy over our settings to our change z class # copy over our settings to our change z class
self.setIntSettingIfEnabled(caz_instance, "e1_Change_speed", "speed", "e2_speed") self.setIntSettingIfEnabled(caz_instance, "e1_Change_speed", "speed", "e2_speed")
@ -352,23 +352,23 @@ class ChangeAtZ(Script):
self.setFloatSettingIfEnabled(caz_instance, "caz_change_retractlength", "retractlength", "caz_retractlength") self.setFloatSettingIfEnabled(caz_instance, "caz_change_retractlength", "retractlength", "caz_retractlength")
# is this mod enabled? # is this mod enabled?
caz_instance.IsEnabled = self.getSettingValueByKey("caz_enabled") caz_instance.enabled = self.getSettingValueByKey("caz_enabled")
# are we emitting data to the LCD? # are we emitting data to the LCD?
caz_instance.IsDisplayingChangesToLcd = self.getSettingValueByKey("caz_output_to_display") caz_instance.displayChangesToLcd = self.getSettingValueByKey("caz_output_to_display")
# are we doing linear move retractions? # are we doing linear move retractions?
caz_instance.IsLinearRetraction = self.getSettingValueByKey("caz_retractstyle") == "linear" caz_instance.linearRetraction = self.getSettingValueByKey("caz_retractstyle") == "linear"
# see if we're applying to a single layer or to all layers hence forth # see if we're applying to a single layer or to all layers hence forth
caz_instance.IsApplyToSingleLayer = self.getSettingValueByKey("c_behavior") == "single_layer" caz_instance.applyToSingleLayer = self.getSettingValueByKey("c_behavior") == "single_layer"
# used for easy reference of layer or height targeting # used for easy reference of layer or height targeting
caz_instance.IsTargetByLayer = self.getSettingValueByKey("a_trigger") == "layer_no" caz_instance.targetByLayer = self.getSettingValueByKey("a_trigger") == "layer_no"
# change our target based on what we're targeting # change our target based on what we're targeting
caz_instance.TargetLayer = self.getIntSettingByKey("b_targetL", None) caz_instance.targetLayer = self.getIntSettingByKey("b_targetL", None)
caz_instance.TargetZ = self.getFloatSettingByKey("b_targetZ", None) caz_instance.targetZ = self.getFloatSettingByKey("b_targetZ", None)
# run our script # run our script
return caz_instance.execute(data) return caz_instance.execute(data)
@ -388,7 +388,7 @@ class ChangeAtZ(Script):
return return
# set our value in the target settings # set our value in the target settings
caz_instance.TargetValues[target] = value caz_instance.targetValues[target] = value
# Sets the given TargetValue in the ChangeAtZ instance if the trigger is specified # Sets the given TargetValue in the ChangeAtZ instance if the trigger is specified
def setFloatSettingIfEnabled(self, caz_instance, trigger, target, setting): def setFloatSettingIfEnabled(self, caz_instance, trigger, target, setting):
@ -405,7 +405,7 @@ class ChangeAtZ(Script):
return return
# set our value in the target settings # set our value in the target settings
caz_instance.TargetValues[target] = value caz_instance.targetValues[target] = value
# Returns the given settings value as an integer or the default if it cannot parse it # Returns the given settings value as an integer or the default if it cannot parse it
def getIntSettingByKey(self, key, default): def getIntSettingByKey(self, key, default):
@ -430,13 +430,13 @@ class ChangeAtZ(Script):
class GCodeCommand: class GCodeCommand:
# The GCode command itself (ex: G10) # The GCode command itself (ex: G10)
Command = None, command = None,
# Contains any arguments passed to the command. The key is the argument name, the value is the value of the argument. # Contains any arguments passed to the command. The key is the argument name, the value is the value of the argument.
Arguments = {} arguments = {}
# Contains the components of the command broken into pieces # Contains the components of the command broken into pieces
Components = [] components = []
# Constructor. Sets up defaults # Constructor. Sets up defaults
def __init__(self): def __init__(self):
@ -468,10 +468,10 @@ class GCodeCommand:
return None return None
# stores all the components of the command within the class for later # stores all the components of the command within the class for later
command.Components = command_pieces command.components = command_pieces
# set the actual command # set the actual command
command.Command = command_pieces[0] command.command = command_pieces[0]
# stop here if we don't have any parameters # stop here if we don't have any parameters
if len(command_pieces) == 1: if len(command_pieces) == 1:
@ -488,15 +488,15 @@ class GCodeCommand:
linear_command = GCodeCommand.getFromLine(line) linear_command = GCodeCommand.getFromLine(line)
# if it's not a linear move, we don't care # if it's not a linear move, we don't care
if linear_command is None or (linear_command.Command != "G0" and linear_command.Command != "G1"): if linear_command is None or (linear_command.command != "G0" and linear_command.command != "G1"):
return None return None
# convert our values to floats (or defaults) # convert our values to floats (or defaults)
linear_command.Arguments["F"] = linear_command.getArgumentAsFloat("F", None) linear_command.arguments["F"] = linear_command.getArgumentAsFloat("F", None)
linear_command.Arguments["X"] = linear_command.getArgumentAsFloat("X", None) linear_command.arguments["X"] = linear_command.getArgumentAsFloat("X", None)
linear_command.Arguments["Y"] = linear_command.getArgumentAsFloat("Y", None) linear_command.arguments["Y"] = linear_command.getArgumentAsFloat("Y", None)
linear_command.Arguments["Z"] = linear_command.getArgumentAsFloat("Z", None) linear_command.arguments["Z"] = linear_command.getArgumentAsFloat("Z", None)
linear_command.Arguments["E"] = linear_command.getArgumentAsFloat("E", None) linear_command.arguments["E"] = linear_command.getArgumentAsFloat("E", None)
# return our new command # return our new command
return linear_command return linear_command
@ -508,11 +508,11 @@ class GCodeCommand:
self.parseArguments() self.parseArguments()
# if we don't have the parameter, return the default # if we don't have the parameter, return the default
if name not in self.Arguments: if name not in self.arguments:
return default return default
# otherwise return the value # otherwise return the value
return self.Arguments[name] return self.arguments[name]
# Gets the value of a parameter as a float or returns the default # Gets the value of a parameter as a float or returns the default
def getArgumentAsFloat(self, name: str, default: float = None) -> float: def getArgumentAsFloat(self, name: str, default: float = None) -> float:
@ -593,14 +593,14 @@ class GCodeCommand:
def parseArguments(self): def parseArguments(self):
# stop here if we don't have any remaining components # stop here if we don't have any remaining components
if len(self.Components) <= 1: if len(self.components) <= 1:
return None return None
# iterate and index all of our parameters, skip the first component as it's the command # iterate and index all of our parameters, skip the first component as it's the command
for i in range(1, len(self.Components)): for i in range(1, len(self.components)):
# get our component # get our component
component = self.Components[i] component = self.components[i]
# get the first character of the parameter, which is the name # get the first character of the parameter, which is the name
component_name = component[0] component_name = component[0]
@ -613,10 +613,10 @@ class GCodeCommand:
component_value = component[1:] component_value = component[1:]
# index the argument # index the argument
self.Arguments[component_name] = component_value self.arguments[component_name] = component_value
# clear the components to we don't process again # clear the components to we don't process again
self.Components = [] self.components = []
# Easy function for replacing any GCODE parameter variable in a given GCODE command # Easy function for replacing any GCODE parameter variable in a given GCODE command
@staticmethod @staticmethod
@ -625,8 +625,8 @@ class GCodeCommand:
# Resets the model back to defaults # Resets the model back to defaults
def reset(self): def reset(self):
self.Command = None self.command = None
self.Arguments = {} self.arguments = {}
# The primary ChangeAtZ class that does all the gcode editing. This was broken out into an # The primary ChangeAtZ class that does all the gcode editing. This was broken out into an
@ -634,55 +634,55 @@ class GCodeCommand:
class ChangeAtZProcessor: class ChangeAtZProcessor:
# Holds our current height # Holds our current height
CurrentZ = None currentZ = None
# Holds our current layer number # Holds our current layer number
CurrentLayer = None currentLayer = None
# Indicates if we're only supposed to apply our settings to a single layer or multiple layers # Indicates if we're only supposed to apply our settings to a single layer or multiple layers
IsApplyToSingleLayer = False applyToSingleLayer = False
# Indicates if this should emit the changes as they happen to the LCD # Indicates if this should emit the changes as they happen to the LCD
IsDisplayingChangesToLcd = False displayChangesToLcd = False
# Indicates that this mod is still enabled (or not) # Indicates that this mod is still enabled (or not)
IsEnabled = True enabled = True
# Indicates if we're processing inside the target layer or not # Indicates if we're processing inside the target layer or not
IsInsideTargetLayer = False insideTargetLayer = False
# Indicates if we have restored the previous values from before we started our pass # Indicates if we have restored the previous values from before we started our pass
IsLastValuesRestored = False lastValuesRestored = False
# Indicates if the user has opted for linear move retractions or firmware retractions # Indicates if the user has opted for linear move retractions or firmware retractions
IsLinearRetraction = True linearRetraction = True
# Indicates if we're targetting by layer or height value # Indicates if we're targetting by layer or height value
IsTargetByLayer = True targetByLayer = True
# Indicates if we have injected our changed values for the given layer yet # Indicates if we have injected our changed values for the given layer yet
IsTargetValuesInjected = False targetValuesInjected = False
# Holds the last extrusion value, used with detecting when a retraction is made # Holds the last extrusion value, used with detecting when a retraction is made
LastE = None lastE = None
# An index of our gcodes which we're monitoring # An index of our gcodes which we're monitoring
LastValues = {} lastValues = {}
# The detected layer height from the gcode # The detected layer height from the gcode
LayerHeight = None layerHeight = None
# The target layer # The target layer
TargetLayer = None targetLayer = None
# Holds the values the user has requested to change # Holds the values the user has requested to change
TargetValues = {} targetValues = {}
# The target height in mm # The target height in mm
TargetZ = None targetZ = None
# Used to track if we've been inside our target layer yet # Used to track if we've been inside our target layer yet
WasInsideTargetLayer = False wasInsideTargetLayer = False
# boots up the class with defaults # boots up the class with defaults
def __init__(self): def __init__(self):
@ -692,7 +692,7 @@ class ChangeAtZProcessor:
def execute(self, data): def execute(self, data):
# short cut the whole thing if we're not enabled # short cut the whole thing if we're not enabled
if not self.IsEnabled: if not self.enabled:
return data return data
# our layer cursor # our layer cursor
@ -750,14 +750,14 @@ class ChangeAtZProcessor:
# for each of our target values, get the value to restore # for each of our target values, get the value to restore
# no point in restoring values we haven't changed # no point in restoring values we haven't changed
for key in self.TargetValues: for key in self.targetValues:
# skip target values we can't restore # skip target values we can't restore
if key not in self.LastValues: if key not in self.lastValues:
continue continue
# save into our changed # save into our changed
changed[key] = self.LastValues[key] changed[key] = self.lastValues[key]
# return our collection of changed values # return our collection of changed values
return changed return changed
@ -766,7 +766,7 @@ class ChangeAtZProcessor:
def getDisplayChangesFromValues(self, values: Dict[str, any]) -> str: def getDisplayChangesFromValues(self, values: Dict[str, any]) -> str:
# stop here if we're not outputting data # stop here if we're not outputting data
if not self.IsDisplayingChangesToLcd: if not self.displayChangesToLcd:
return "" return ""
# will hold all the default settings for the target layer # will hold all the default settings for the target layer
@ -833,7 +833,7 @@ class ChangeAtZProcessor:
def getTargetDisplayValues(self) -> str: def getTargetDisplayValues(self) -> str:
# convert our target values to something we can output # convert our target values to something we can output
return self.getDisplayChangesFromValues(self.TargetValues) return self.getDisplayChangesFromValues(self.targetValues)
# Builds the the relevant GCODE lines from the given collection of values # Builds the the relevant GCODE lines from the given collection of values
def getCodeFromValues(self, values: Dict[str, any]) -> str: def getCodeFromValues(self, values: Dict[str, any]) -> str:
@ -898,7 +898,7 @@ class ChangeAtZProcessor:
# set retract rate # set retract rate
if "retractfeedrate" in values: if "retractfeedrate" in values:
if self.IsLinearRetraction: if self.linearRetraction:
codes.append(";RETRACTFEEDRATE " + str(values["retractfeedrate"] * 60) + "") codes.append(";RETRACTFEEDRATE " + str(values["retractfeedrate"] * 60) + "")
else: else:
codes.append("M207 F" + str(values["retractfeedrate"] * 60) + "") codes.append("M207 F" + str(values["retractfeedrate"] * 60) + "")
@ -906,7 +906,7 @@ class ChangeAtZProcessor:
# set retract length # set retract length
if "retractlength" in values: if "retractlength" in values:
if self.IsLinearRetraction: if self.linearRetraction:
codes.append(";RETRACTLENGTH " + str(values["retractlength"]) + "") codes.append(";RETRACTLENGTH " + str(values["retractlength"]) + "")
else: else:
codes.append("M207 S" + str(values["retractlength"]) + "") codes.append("M207 S" + str(values["retractlength"]) + "")
@ -923,19 +923,19 @@ class ChangeAtZProcessor:
def getInjectCode(self) -> str: def getInjectCode(self) -> str:
# if we're now outside of our target layer and haven't restored our last values, do so now # if we're now outside of our target layer and haven't restored our last values, do so now
if not self.IsInsideTargetLayer and self.WasInsideTargetLayer and not self.IsLastValuesRestored: if not self.insideTargetLayer and self.wasInsideTargetLayer and not self.lastValuesRestored:
# mark that we've injected the last values # mark that we've injected the last values
self.IsLastValuesRestored = True self.lastValuesRestored = True
# inject the defaults # inject the defaults
return self.getLastValues() + "\n" + self.getLastDisplayValues() return self.getLastValues() + "\n" + self.getLastDisplayValues()
# if we're inside our target layer but haven't added our values yet, do so now # if we're inside our target layer but haven't added our values yet, do so now
if self.IsInsideTargetLayer and not self.IsTargetValuesInjected: if self.insideTargetLayer and not self.targetValuesInjected:
# mark that we've injected the target values # mark that we've injected the target values
self.IsTargetValuesInjected = True self.targetValuesInjected = True
# inject the defaults # inject the defaults
return self.getTargetValues() + "\n" + self.getTargetDisplayValues() return self.getTargetValues() + "\n" + self.getTargetDisplayValues()
@ -960,35 +960,35 @@ class ChangeAtZProcessor:
def getTargetValues(self) -> str: def getTargetValues(self) -> str:
# build the gcode to change our current values # build the gcode to change our current values
return self.getCodeFromValues(self.TargetValues) return self.getCodeFromValues(self.targetValues)
# Determines if the current line is at or below the target required to start modifying # Determines if the current line is at or below the target required to start modifying
def isTargetLayerOrHeight(self) -> bool: def isTargetLayerOrHeight(self) -> bool:
# target selected by layer no. # target selected by layer no.
if self.IsTargetByLayer: if self.targetByLayer:
# if we don't have a current layer, we're not there yet # if we don't have a current layer, we're not there yet
if self.CurrentLayer is None: if self.currentLayer is None:
return False return False
# if we're applying to a single layer, stop if our layer is not identical # if we're applying to a single layer, stop if our layer is not identical
if self.IsApplyToSingleLayer: if self.applyToSingleLayer:
return self.CurrentLayer == self.TargetLayer return self.currentLayer == self.targetLayer
else: else:
return self.CurrentLayer >= self.TargetLayer return self.currentLayer >= self.targetLayer
else: else:
# if we don't have a current Z, we're not there yet # if we don't have a current Z, we're not there yet
if self.CurrentZ is None: if self.currentZ is None:
return False return False
# if we're applying to a single layer, stop if our Z is not identical # if we're applying to a single layer, stop if our Z is not identical
if self.IsApplyToSingleLayer: if self.applyToSingleLayer:
return self.CurrentZ == self.TargetZ return self.currentZ == self.targetZ
else: else:
return self.CurrentZ >= self.TargetZ return self.currentZ >= self.targetZ
# Marks any current ChangeZ layer defaults in the layer for deletion # Marks any current ChangeZ layer defaults in the layer for deletion
@staticmethod @staticmethod
@ -999,7 +999,7 @@ class ChangeAtZProcessor:
def processLayerHeight(self, line: str): def processLayerHeight(self, line: str):
# stop here if we haven't entered a layer yet # stop here if we haven't entered a layer yet
if self.CurrentLayer is None: if self.currentLayer is None:
return return
# get our gcode command # get our gcode command
@ -1010,7 +1010,7 @@ class ChangeAtZProcessor:
return return
# stop here if this isn't a linear move command # stop here if this isn't a linear move command
if command.Command != "G0" and command.Command != "G1": if command.command != "G0" and command.command != "G1":
return return
# get our value from the command # get our value from the command
@ -1021,15 +1021,15 @@ class ChangeAtZProcessor:
return return
# stop if there's no change # stop if there's no change
if current_z == self.CurrentZ: if current_z == self.currentZ:
return return
# set our current Z value # set our current Z value
self.CurrentZ = current_z self.currentZ = current_z
# if we don't have a layer height yet, set it based on the current Z value # if we don't have a layer height yet, set it based on the current Z value
if self.LayerHeight is None: if self.layerHeight is None:
self.LayerHeight = self.CurrentZ self.layerHeight = self.currentZ
# Grabs the current layer number # Grabs the current layer number
def processLayerNumber(self, line: str): def processLayerNumber(self, line: str):
@ -1042,11 +1042,11 @@ class ChangeAtZProcessor:
current_layer = GCodeCommand.getDirectArgumentAsInt(line, ";LAYER:", None) current_layer = GCodeCommand.getDirectArgumentAsInt(line, ";LAYER:", None)
# this should never happen, but if our layer number hasn't changed, stop here # this should never happen, but if our layer number hasn't changed, stop here
if current_layer == self.CurrentLayer: if current_layer == self.currentLayer:
return return
# update our current layer # update our current layer
self.CurrentLayer = current_layer self.currentLayer = current_layer
# Makes any linear move changes and also injects either target or restored values depending on the plugin state # Makes any linear move changes and also injects either target or restored values depending on the plugin state
def processLine(self, line: str) -> str: def processLine(self, line: str) -> str:
@ -1059,10 +1059,10 @@ class ChangeAtZProcessor:
# if we're not inside the target layer, simply read the any # if we're not inside the target layer, simply read the any
# settings we can and revert any ChangeAtZ deletions # settings we can and revert any ChangeAtZ deletions
if not self.IsInsideTargetLayer: if not self.insideTargetLayer:
# read any settings if we haven't hit our target layer yet # read any settings if we haven't hit our target layer yet
if not self.WasInsideTargetLayer: if not self.wasInsideTargetLayer:
self.processSetting(line) self.processSetting(line)
# if we haven't hit our target yet, leave the defaults as is (unmark them for deletion) # if we haven't hit our target yet, leave the defaults as is (unmark them for deletion)
@ -1074,7 +1074,7 @@ class ChangeAtZProcessor:
modified_gcode += self.getInjectCode() modified_gcode += self.getInjectCode()
# modify our command if we're still inside our target layer, otherwise pass unmodified # modify our command if we're still inside our target layer, otherwise pass unmodified
if self.IsInsideTargetLayer: if self.insideTargetLayer:
modified_gcode += self.processLinearMove(line) + "\n" modified_gcode += self.processLinearMove(line) + "\n"
else: else:
modified_gcode += line + "\n" modified_gcode += line + "\n"
@ -1104,11 +1104,11 @@ class ChangeAtZProcessor:
return line return line
# get our linear move parameters # get our linear move parameters
feed_rate = linear_command.Arguments["F"] feed_rate = linear_command.arguments["F"]
x_coord = linear_command.Arguments["X"] x_coord = linear_command.arguments["X"]
y_coord = linear_command.Arguments["Y"] y_coord = linear_command.arguments["Y"]
z_coord = linear_command.Arguments["Z"] z_coord = linear_command.arguments["Z"]
extrude_length = linear_command.Arguments["E"] extrude_length = linear_command.arguments["E"]
# set our new line to our old line # set our new line to our old line
new_line = line new_line = line
@ -1124,7 +1124,7 @@ class ChangeAtZProcessor:
new_line = self.processPrintSpeed(feed_rate, new_line) new_line = self.processPrintSpeed(feed_rate, new_line)
# set our current extrude position # set our current extrude position
self.LastE = extrude_length if extrude_length is not None else self.LastE self.lastE = extrude_length if extrude_length is not None else self.lastE
# if no changes have been made, stop here # if no changes have been made, stop here
if new_line == line: if new_line == line:
@ -1137,11 +1137,11 @@ class ChangeAtZProcessor:
def processPrintSpeed(self, feed_rate: float, new_line: str) -> str: def processPrintSpeed(self, feed_rate: float, new_line: str) -> str:
# if we're not setting print speed or we don't have a feed rate, stop here # if we're not setting print speed or we don't have a feed rate, stop here
if "printspeed" not in self.TargetValues or feed_rate is None: if "printspeed" not in self.targetValues or feed_rate is None:
return new_line return new_line
# get our requested print speed # get our requested print speed
print_speed = int(self.TargetValues["printspeed"]) print_speed = int(self.targetValues["printspeed"])
# if they requested no change to print speed (ie: 100%), stop here # if they requested no change to print speed (ie: 100%), stop here
if print_speed == 100: if print_speed == 100:
@ -1157,11 +1157,11 @@ class ChangeAtZProcessor:
def processRetractLength(self, extrude_length: float, feed_rate: float, new_line: str, x_coord: float, y_coord: float, z_coord: float) -> str: def processRetractLength(self, extrude_length: float, feed_rate: float, new_line: str, x_coord: float, y_coord: float, z_coord: float) -> str:
# if we don't have a retract length in the file we can't add one # if we don't have a retract length in the file we can't add one
if "retractlength" not in self.LastValues or self.LastValues["retractlength"] == 0: if "retractlength" not in self.lastValues or self.lastValues["retractlength"] == 0:
return new_line return new_line
# if we're not changing retraction length, stop here # if we're not changing retraction length, stop here
if "retractlength" not in self.TargetValues: if "retractlength" not in self.targetValues:
return new_line return new_line
# retractions are only F (feed rate) and E (extrude), at least in cura # retractions are only F (feed rate) and E (extrude), at least in cura
@ -1173,22 +1173,22 @@ class ChangeAtZProcessor:
return new_line return new_line
# stop here if we don't know our last extrude value # stop here if we don't know our last extrude value
if self.LastE is None: if self.lastE is None:
return new_line return new_line
# if there's no change in extrude we have nothing to change # if there's no change in extrude we have nothing to change
if self.LastE == extrude_length: if self.lastE == extrude_length:
return new_line return new_line
# if our last extrude was lower than our current, we're restoring, so skip # if our last extrude was lower than our current, we're restoring, so skip
if self.LastE < extrude_length: if self.lastE < extrude_length:
return new_line return new_line
# get our desired retract length # get our desired retract length
retract_length = float(self.TargetValues["retractlength"]) retract_length = float(self.targetValues["retractlength"])
# subtract the difference between the default and the desired # subtract the difference between the default and the desired
extrude_length -= (retract_length - self.LastValues["retractlength"]) extrude_length -= (retract_length - self.lastValues["retractlength"])
# replace our extrude amount # replace our extrude amount
return GCodeCommand.replaceDirectArgument(new_line, "E", extrude_length) return GCodeCommand.replaceDirectArgument(new_line, "E", extrude_length)
@ -1197,7 +1197,7 @@ class ChangeAtZProcessor:
def processRetractLengthSetting(self, line: str): def processRetractLengthSetting(self, line: str):
# skip if we're not doing linear retractions # skip if we're not doing linear retractions
if not self.IsLinearRetraction: if not self.linearRetraction:
return return
# get our command from the line # get our command from the line
@ -1208,11 +1208,11 @@ class ChangeAtZProcessor:
return return
# get our linear move parameters # get our linear move parameters
feed_rate = linear_command.Arguments["F"] feed_rate = linear_command.arguments["F"]
x_coord = linear_command.Arguments["X"] x_coord = linear_command.arguments["X"]
y_coord = linear_command.Arguments["Y"] y_coord = linear_command.arguments["Y"]
z_coord = linear_command.Arguments["Z"] z_coord = linear_command.arguments["Z"]
extrude_length = linear_command.Arguments["E"] extrude_length = linear_command.arguments["E"]
# the command we're looking for only has extrude and feed rate # the command we're looking for only has extrude and feed rate
if x_coord is not None or y_coord is not None or z_coord is not None: if x_coord is not None or y_coord is not None or z_coord is not None:
@ -1230,17 +1230,17 @@ class ChangeAtZProcessor:
return return
# what ever the last negative retract length is it wins # what ever the last negative retract length is it wins
self.LastValues["retractlength"] = extrude_length self.lastValues["retractlength"] = extrude_length
# Handles any changes to retraction feed rate for the given linear motion command # Handles any changes to retraction feed rate for the given linear motion command
def processRetractFeedRate(self, extrude_length: float, feed_rate: float, new_line: str, x_coord: float, y_coord: float, z_coord: float) -> str: def processRetractFeedRate(self, extrude_length: float, feed_rate: float, new_line: str, x_coord: float, y_coord: float, z_coord: float) -> str:
# skip if we're not doing linear retractions # skip if we're not doing linear retractions
if not self.IsLinearRetraction: if not self.linearRetraction:
return new_line return new_line
# if we're not changing retraction length, stop here # if we're not changing retraction length, stop here
if "retractfeedrate" not in self.TargetValues: if "retractfeedrate" not in self.targetValues:
return new_line return new_line
# retractions are only F (feed rate) and E (extrude), at least in cura # retractions are only F (feed rate) and E (extrude), at least in cura
@ -1252,7 +1252,7 @@ class ChangeAtZProcessor:
return new_line return new_line
# get our desired retract feed rate # get our desired retract feed rate
retract_feed_rate = float(self.TargetValues["retractfeedrate"]) retract_feed_rate = float(self.targetValues["retractfeedrate"])
# convert to units/min # convert to units/min
retract_feed_rate *= 60 retract_feed_rate *= 60
@ -1264,7 +1264,7 @@ class ChangeAtZProcessor:
def processSetting(self, line: str): def processSetting(self, line: str):
# if we're in layers already we're out of settings # if we're in layers already we're out of settings
if self.CurrentLayer is not None: if self.currentLayer is not None:
return return
# check our retract length # check our retract length
@ -1277,16 +1277,16 @@ class ChangeAtZProcessor:
if not self.isTargetLayerOrHeight(): if not self.isTargetLayerOrHeight():
# flag that we're outside our target layer # flag that we're outside our target layer
self.IsInsideTargetLayer = False self.insideTargetLayer = False
# skip to the next line # skip to the next line
return return
# flip if we hit our target layer # flip if we hit our target layer
self.WasInsideTargetLayer = True self.wasInsideTargetLayer = True
# flag that we're inside our target layer # flag that we're inside our target layer
self.IsInsideTargetLayer = True self.insideTargetLayer = True
# Removes all the ChangeZ layer defaults from the given layer # Removes all the ChangeZ layer defaults from the given layer
@staticmethod @staticmethod
@ -1296,22 +1296,22 @@ class ChangeAtZProcessor:
# Resets the class contents to defaults # Resets the class contents to defaults
def reset(self): def reset(self):
self.TargetValues = {} self.targetValues = {}
self.IsApplyToSingleLayer = False self.applyToSingleLayer = False
self.LastE = None self.lastE = None
self.CurrentZ = None self.currentZ = None
self.CurrentLayer = None self.currentLayer = None
self.IsTargetByLayer = True self.targetByLayer = True
self.TargetLayer = None self.targetLayer = None
self.TargetZ = None self.targetZ = None
self.LayerHeight = None self.layerHeight = None
self.LastValues = {} self.lastValues = {}
self.IsLinearRetraction = True self.linearRetraction = True
self.IsInsideTargetLayer = False self.insideTargetLayer = False
self.IsTargetValuesInjected = False self.targetValuesInjected = False
self.IsLastValuesRestored = False self.lastValuesRestored = False
self.WasInsideTargetLayer = False self.wasInsideTargetLayer = False
self.IsEnabled = True self.enabled = True
# Sets the original GCODE line in a given GCODE command # Sets the original GCODE line in a given GCODE command
@staticmethod @staticmethod
@ -1341,31 +1341,31 @@ class ChangeAtZProcessor:
return return
# handle retract length changes # handle retract length changes
if command.Command == "M207": if command.command == "M207":
# get our retract length if provided # get our retract length if provided
if "S" in command.Arguments: if "S" in command.arguments:
self.LastValues["retractlength"] = command.getArgumentAsFloat("S") self.lastValues["retractlength"] = command.getArgumentAsFloat("S")
# get our retract feedrate if provided, convert from mm/m to mm/s # get our retract feedrate if provided, convert from mm/m to mm/s
if "F" in command.Arguments: if "F" in command.arguments:
self.LastValues["retractfeedrate"] = command.getArgumentAsFloat("F") / 60.0 self.lastValues["retractfeedrate"] = command.getArgumentAsFloat("F") / 60.0
# move to the next command # move to the next command
return return
# handle bed temp changes # handle bed temp changes
if command.Command == "M140" or command.Command == "M190": if command.command == "M140" or command.command == "M190":
# get our bed temp if provided # get our bed temp if provided
if "S" in command.Arguments: if "S" in command.arguments:
self.LastValues["bedTemp"] = command.getArgumentAsFloat("S") self.lastValues["bedTemp"] = command.getArgumentAsFloat("S")
# move to the next command # move to the next command
return return
# handle extruder temp changes # handle extruder temp changes
if command.Command == "M104" or command.Command == "M109": if command.command == "M104" or command.command == "M109":
# get our tempurature # get our tempurature
tempurature = command.getArgumentAsFloat("S") tempurature = command.getArgumentAsFloat("S")
@ -1379,26 +1379,26 @@ class ChangeAtZProcessor:
# set our extruder temp based on the extruder # set our extruder temp based on the extruder
if extruder is None or extruder == 0: if extruder is None or extruder == 0:
self.LastValues["extruderOne"] = tempurature self.lastValues["extruderOne"] = tempurature
if extruder is None or extruder == 1: if extruder is None or extruder == 1:
self.LastValues["extruderTwo"] = tempurature self.lastValues["extruderTwo"] = tempurature
# move to the next command # move to the next command
return return
# handle fan speed changes # handle fan speed changes
if command.Command == "M106": if command.command == "M106":
# get our bed temp if provided # get our bed temp if provided
if "S" in command.Arguments: if "S" in command.arguments:
self.LastValues["fanSpeed"] = (command.getArgumentAsInt("S") / 255.0) * 100 self.lastValues["fanSpeed"] = (command.getArgumentAsInt("S") / 255.0) * 100
# move to the next command # move to the next command
return return
# handle flow rate changes # handle flow rate changes
if command.Command == "M221": if command.command == "M221":
# get our flow rate # get our flow rate
tempurature = command.getArgumentAsFloat("S") tempurature = command.getArgumentAsFloat("S")
@ -1412,21 +1412,21 @@ class ChangeAtZProcessor:
# set our extruder temp based on the extruder # set our extruder temp based on the extruder
if extruder is None: if extruder is None:
self.LastValues["flowrate"] = tempurature self.lastValues["flowrate"] = tempurature
elif extruder == 1: elif extruder == 1:
self.LastValues["flowrateOne"] = tempurature self.lastValues["flowrateOne"] = tempurature
elif extruder == 1: elif extruder == 1:
self.LastValues["flowrateTwo"] = tempurature self.lastValues["flowrateTwo"] = tempurature
# move to the next command # move to the next command
return return
# handle print speed changes # handle print speed changes
if command.Command == "M220": if command.command == "M220":
# get our speed if provided # get our speed if provided
if "S" in command.Arguments: if "S" in command.arguments:
self.LastValues["speed"] = command.getArgumentAsInt("S") self.lastValues["speed"] = command.getArgumentAsInt("S")
# move to the next command # move to the next command
return return

View File

@ -32,6 +32,7 @@ class SimulationPass(RenderPass):
self._current_shader = None # This shader will be the shadow or the normal depending if the user wants to see the paths or the layers self._current_shader = None # This shader will be the shadow or the normal depending if the user wants to see the paths or the layers
self._tool_handle_shader = None self._tool_handle_shader = None
self._nozzle_shader = None self._nozzle_shader = None
self._disabled_shader = None
self._old_current_layer = 0 self._old_current_layer = 0
self._old_current_path = 0 self._old_current_path = 0
self._switching_layers = True # It tracks when the user is moving the layers' slider self._switching_layers = True # It tracks when the user is moving the layers' slider
@ -90,9 +91,17 @@ class SimulationPass(RenderPass):
self._nozzle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader")) self._nozzle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader"))
self._nozzle_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("layerview_nozzle").getRgb())) self._nozzle_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("layerview_nozzle").getRgb()))
if not self._disabled_shader:
self._disabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "striped.shader"))
self._disabled_shader.setUniformValue("u_diffuseColor1", Color(*Application.getInstance().getTheme().getColor("model_unslicable").getRgb()))
self._disabled_shader.setUniformValue("u_diffuseColor2", Color(*Application.getInstance().getTheme().getColor("model_unslicable_alt").getRgb()))
self._disabled_shader.setUniformValue("u_width", 50.0)
self._disabled_shader.setUniformValue("u_opacity", 0.6)
self.bind() self.bind()
tool_handle_batch = RenderBatch(self._tool_handle_shader, type = RenderBatch.RenderType.Overlay, backface_cull = True) tool_handle_batch = RenderBatch(self._tool_handle_shader, type = RenderBatch.RenderType.Overlay, backface_cull = True)
disabled_batch = RenderBatch(self._disabled_shader)
head_position = None # Indicates the current position of the print head head_position = None # Indicates the current position of the print head
nozzle_node = None nozzle_node = None
@ -105,6 +114,9 @@ class SimulationPass(RenderPass):
nozzle_node = node nozzle_node = node
nozzle_node.setVisible(False) nozzle_node.setVisible(False)
elif getattr(node, "_outside_buildarea", False) and isinstance(node, SceneNode) and node.getMeshData() and node.isVisible():
disabled_batch.addItem(node.getWorldTransformation(copy=False), node.getMeshData())
elif isinstance(node, SceneNode) and (node.getMeshData() or node.callDecoration("isBlockSlicing")) and node.isVisible(): elif isinstance(node, SceneNode) and (node.getMeshData() or node.callDecoration("isBlockSlicing")) and node.isVisible():
layer_data = node.callDecoration("getLayerData") layer_data = node.callDecoration("getLayerData")
if not layer_data: if not layer_data:
@ -183,6 +195,9 @@ class SimulationPass(RenderPass):
nozzle_batch.addItem(nozzle_node.getWorldTransformation(), mesh = nozzle_node.getMeshData()) nozzle_batch.addItem(nozzle_node.getWorldTransformation(), mesh = nozzle_node.getMeshData())
nozzle_batch.render(self._scene.getActiveCamera()) nozzle_batch.render(self._scene.getActiveCamera())
if len(disabled_batch.items) > 0:
disabled_batch.render(self._scene.getActiveCamera())
# Render toolhandles on top of the layerview # Render toolhandles on top of the layerview
if len(tool_handle_batch.items) > 0: if len(tool_handle_batch.items) > 0:
tool_handle_batch.render(self._scene.getActiveCamera()) tool_handle_batch.render(self._scene.getActiveCamera())

View File

@ -282,12 +282,13 @@ Item
enabled: !cameraButton.enabled enabled: !cameraButton.enabled
} }
/* //Warning message is commented out because it's factually incorrect. Fix CURA-7637 to allow camera connections via cloud.
MonitorInfoBlurb MonitorInfoBlurb
{ {
id: cameraDisabledInfo id: cameraDisabledInfo
text: catalog.i18nc("@info", "The webcam is not available because you are monitoring a cloud printer.") text: catalog.i18nc("@info", "The webcam is not available because you are monitoring a cloud printer.")
target: cameraButton target: cameraButton
} }*/
} }
// Divider // Divider

View File

@ -1,5 +1,6 @@
# Copyright (c) 2019 Ultimaker B.V. # Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
import os import os
from typing import Dict, List, Optional, Set from typing import Dict, List, Optional, Set
@ -37,7 +38,7 @@ class CloudOutputDeviceManager:
SYNC_SERVICE_NAME = "CloudOutputDeviceManager" SYNC_SERVICE_NAME = "CloudOutputDeviceManager"
# The translation catalog for this device. # The translation catalog for this device.
I18N_CATALOG = i18nCatalog("cura") i18n_catalog = i18nCatalog("cura")
# Signal emitted when the list of discovered devices changed. # Signal emitted when the list of discovered devices changed.
discoveredDevicesChanged = Signal() discoveredDevicesChanged = Signal()
@ -221,7 +222,7 @@ class CloudOutputDeviceManager:
) )
message = Message( message = Message(
title = self.I18N_CATALOG.i18ncp( title = self.i18n_catalog.i18ncp(
"info:status", "info:status",
"New printer detected from your Ultimaker account", "New printer detected from your Ultimaker account",
"New printers detected from your Ultimaker account", "New printers detected from your Ultimaker account",
@ -234,11 +235,7 @@ class CloudOutputDeviceManager:
message.show() message.show()
for idx, device in enumerate(new_devices): for idx, device in enumerate(new_devices):
message_text = self.I18N_CATALOG.i18nc( message_text = self.i18n_catalog.i18nc("info:status Filled in with printer name and printer model.", "Adding printer {name} ({model}) from your account").format(name = device.name, model = device.printerTypeName)
"info:status", "Adding printer {} ({}) from your account",
device.name,
device.printerTypeName
)
message.setText(message_text) message.setText(message_text)
if len(new_devices) > 1: if len(new_devices) > 1:
message.setProgress((idx / len(new_devices)) * 100) message.setProgress((idx / len(new_devices)) * 100)
@ -255,16 +252,12 @@ class CloudOutputDeviceManager:
if len(new_devices) > max_disp_devices: if len(new_devices) > max_disp_devices:
num_hidden = len(new_devices) - max_disp_devices num_hidden = len(new_devices) - max_disp_devices
device_name_list = ["<li>{} ({})</li>".format(device.name, device.printerTypeName) for device in new_devices[0:max_disp_devices]] device_name_list = ["<li>{} ({})</li>".format(device.name, device.printerTypeName) for device in new_devices[0:max_disp_devices]]
device_name_list.append(self.I18N_CATALOG.i18nc("info:hidden list items", "<li>... and {} others</li>", num_hidden)) device_name_list.append("<li>" + self.i18n_catalog.i18ncp("info:{0} gets replaced by a number of printers", "... and {0} other", "... and {0} others", num_hidden) + "</li>")
device_names = "".join(device_name_list) device_names = "".join(device_name_list)
else: else:
device_names = "".join(["<li>{} ({})</li>".format(device.name, device.printerTypeName) for device in new_devices]) device_names = "".join(["<li>{} ({})</li>".format(device.name, device.printerTypeName) for device in new_devices])
message_text = self.I18N_CATALOG.i18nc( message_text = self.i18n_catalog.i18nc("info:status", "Printers added from Digital Factory:") + "<ul>" + device_names + "</ul>"
"info:status",
"Printers added from Digital Factory:<ul>{}</ul>",
device_names
)
message.setText(message_text) message.setText(message_text)
def _updateOutdatedMachine(self, outdated_machine: GlobalStack, new_cloud_output_device: CloudOutputDevice) -> None: def _updateOutdatedMachine(self, outdated_machine: GlobalStack, new_cloud_output_device: CloudOutputDevice) -> None:
@ -318,7 +311,7 @@ class CloudOutputDeviceManager:
# Generate message # Generate message
self._removed_printers_message = Message( self._removed_printers_message = Message(
title = self.I18N_CATALOG.i18ncp( title = self.i18n_catalog.i18ncp(
"info:status", "info:status",
"A cloud connection is not available for a printer", "A cloud connection is not available for a printer",
"A cloud connection is not available for some printers", "A cloud connection is not available for some printers",
@ -326,27 +319,27 @@ class CloudOutputDeviceManager:
) )
) )
device_names = "".join(["<li>{} ({})</li>".format(self._um_cloud_printers[device].name, self._um_cloud_printers[device].definition.name) for device in self.reported_device_ids]) device_names = "".join(["<li>{} ({})</li>".format(self._um_cloud_printers[device].name, self._um_cloud_printers[device].definition.name) for device in self.reported_device_ids])
message_text = self.I18N_CATALOG.i18ncp( message_text = self.i18n_catalog.i18ncp(
"info:status", "info:status",
"This printer is not linked to the Digital Factory:", "This printer is not linked to the Digital Factory:",
"These printers are not linked to the Digital Factory:", "These printers are not linked to the Digital Factory:",
len(self.reported_device_ids) len(self.reported_device_ids)
) )
message_text += "<br/><ul>{}</ul><br/>".format(device_names) message_text += "<br/><ul>{}</ul><br/>".format(device_names)
digital_factory_string = self.I18N_CATALOG.i18nc("info:name", "Ultimaker Digital Factory") digital_factory_string = self.i18n_catalog.i18nc("info:name", "Ultimaker Digital Factory")
message_text += self.I18N_CATALOG.i18nc( message_text += self.i18n_catalog.i18nc(
"info:status", "info:status",
"To establish a connection, please visit the {website_link}".format(website_link = "<a href='https://digitalfactory.ultimaker.com/'>{}</a>.".format(digital_factory_string)) "To establish a connection, please visit the {website_link}".format(website_link = "<a href='https://digitalfactory.ultimaker.com/'>{}</a>.".format(digital_factory_string))
) )
self._removed_printers_message.setText(message_text) self._removed_printers_message.setText(message_text)
self._removed_printers_message.addAction("keep_printer_configurations_action", self._removed_printers_message.addAction("keep_printer_configurations_action",
name = self.I18N_CATALOG.i18nc("@action:button", "Keep printer configurations"), name = self.i18n_catalog.i18nc("@action:button", "Keep printer configurations"),
icon = "", icon = "",
description = "Keep cloud printers in Ultimaker Cura when not connected to your account.", description = "Keep cloud printers in Ultimaker Cura when not connected to your account.",
button_align = Message.ActionButtonAlignment.ALIGN_RIGHT) button_align = Message.ActionButtonAlignment.ALIGN_RIGHT)
self._removed_printers_message.addAction("remove_printers_action", self._removed_printers_message.addAction("remove_printers_action",
name = self.I18N_CATALOG.i18nc("@action:button", "Remove printers"), name = self.i18n_catalog.i18nc("@action:button", "Remove printers"),
icon = "", icon = "",
description = "Remove cloud printer(s) which aren't linked to your account.", description = "Remove cloud printer(s) which aren't linked to your account.",
button_style = Message.ActionButtonStyle.SECONDARY, button_style = Message.ActionButtonStyle.SECONDARY,
@ -423,16 +416,11 @@ class CloudOutputDeviceManager:
machine.setMetaDataEntry(self.META_HOST_GUID, device.clusterData.host_guid) machine.setMetaDataEntry(self.META_HOST_GUID, device.clusterData.host_guid)
machine.setMetaDataEntry("group_name", device.name) machine.setMetaDataEntry("group_name", device.name)
machine.setMetaDataEntry("group_size", device.clusterSize) machine.setMetaDataEntry("group_size", device.clusterSize)
digital_factory_string = self.I18N_CATALOG.i18nc("info:name", "Ultimaker Digital Factory") digital_factory_string = self.i18n_catalog.i18nc("info:name", "Ultimaker Digital Factory")
digital_factory_link = "<a href='https://digitalfactory.ultimaker.com/'>{}</a>".format(digital_factory_string) digital_factory_link = "<a href='https://digitalfactory.ultimaker.com/'>{digital_factory_string}</a>".format(digital_factory_string = digital_factory_string)
removal_warning_string = self.I18N_CATALOG.i18nc( removal_warning_string = self.i18n_catalog.i18nc("@message {printer_name} is replaced with the name of the printer", "{printer_name} will be removed until the next account sync.").format(printer_name = device.name) \
"@label ({printer_name} is replaced with the name of the printer", + "<br>" + self.i18n_catalog.i18nc("@message {printer_name} is replaced with the name of the printer", "To remove {printer_name} permanently, visit {digital_factory_link}").format(printer_name = device.name, digital_factory_link = digital_factory_link) \
"{printer_name} will be removed until the next account sync. <br> To remove {printer_name} permanently, " + "<br><br>" + self.i18n_catalog.i18nc("@message {printer_name} is replaced with the name of the printer", "Are you sure you want to remove {printer_name} temporarily?").format(printer_name = device.name)
"visit {digital_factory_link}"
"<br><br>Are you sure you want to remove {printer_name} temporarily?".format(printer_name = device.name,
digital_factory_link = digital_factory_link)
)
machine.setMetaDataEntry("removal_warning", removal_warning_string) machine.setMetaDataEntry("removal_warning", removal_warning_string)
machine.addConfiguredConnectionType(device.connectionType.value) machine.addConfiguredConnectionType(device.connectionType.value)
@ -469,10 +457,15 @@ class CloudOutputDeviceManager:
remove_printers_ids = {self._um_cloud_printers[i].getId() for i in self.reported_device_ids} remove_printers_ids = {self._um_cloud_printers[i].getId() for i in self.reported_device_ids}
all_ids = {m.getId() for m in CuraApplication.getInstance().getContainerRegistry().findContainerStacks(type = "machine")} all_ids = {m.getId() for m in CuraApplication.getInstance().getContainerRegistry().findContainerStacks(type = "machine")}
question_title = self.I18N_CATALOG.i18nc("@title:window", "Remove printers?") question_title = self.i18n_catalog.i18nc("@title:window", "Remove printers?")
question_content = self.I18N_CATALOG.i18nc("@label", "You are about to remove {} printer(s) from Cura. This action cannot be undone. \nAre you sure you want to continue?".format(len(remove_printers_ids))) question_content = self.i18n_catalog.i18ncp(
"@label",
"You are about to remove {num_printers} printer from Cura. This action cannot be undone.\nAre you sure you want to continue?",
"You are about to remove {num_printers} printers from Cura. This action cannot be undone.\nAre you sure you want to continue?",
len(remove_printers_ids)
).format(num_printers = len(remove_printers_ids))
if remove_printers_ids == all_ids: if remove_printers_ids == all_ids:
question_content = self.I18N_CATALOG.i18nc("@label", "You are about to remove all printers from Cura. This action cannot be undone. \nAre you sure you want to continue?") question_content = self.i18n_catalog.i18nc("@label", "You are about to remove all printers from Cura. This action cannot be undone.\nAre you sure you want to continue?")
result = QMessageBox.question(None, question_title, question_content) result = QMessageBox.question(None, question_title, question_content)
if result == QMessageBox.No: if result == QMessageBox.No:
return return

View File

@ -74,7 +74,6 @@
"material_initial_print_temperature": { "value": "material_print_temperature" }, "material_initial_print_temperature": { "value": "material_print_temperature" },
"material_final_print_temperature": { "value": "material_print_temperature" }, "material_final_print_temperature": { "value": "material_print_temperature" },
"material_flow": { "value": 100 }, "material_flow": { "value": 100 },
"travel_compensate_overlapping_walls_0_enabled": { "value": "False" },
"z_seam_type": { "value": "'back'" }, "z_seam_type": { "value": "'back'" },
"z_seam_corner": { "value": "'z_seam_corner_weighted'" }, "z_seam_corner": { "value": "'z_seam_corner_weighted'" },

View File

@ -0,0 +1,79 @@
{
"name": "Cocoon Create",
"version": 2,
"inherits": "fdmprinter",
"metadata": {
"visible": true,
"author": "Thushan Fernando",
"manufacturer": "Cocoon Create",
"file_formats": "text/x-gcode",
"preferred_quality_type": "fine",
"has_materials": true,
"platform": "wanhao_200_200_platform.obj",
"platform_texture": "Cocoon-backplate.png",
"machine_extruder_trains": {
"0": "cocoon_create_extruder_0"
},
"platform_offset": [
0,
-28,
0
]
},
"overrides": {
"machine_name": {
"default_value": "Cocoon Create"
},
"machine_width": {
"default_value": 200
},
"machine_height": {
"default_value": 180
},
"machine_depth": {
"default_value": 200
},
"machine_heated_bed": {
"default_value": true
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
"default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E3 ;extrude 3mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..."
},
"machine_end_gcode": {
"default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning"
},
"material_diameter": {
"default_value": 1.75
},
"layer_height": {
"default_value": 0.10
},
"layer_height_0": {
"default_value": 0.2
},
"wall_thickness": {
"value": "0.8"
},
"top_bottom_thickness": {
"default_value": 0.6
},
"speed_print": {
"default_value": 50
},
"support_enable": {
"default_value": true
},
"retraction_enable": {
"default_value": true
},
"retraction_amount": {
"default_value": 4.5
},
"retraction_speed": {
"default_value": 25
}
}
}

View File

@ -0,0 +1,79 @@
{
"name": "Cocoon Create Touch",
"version": 2,
"inherits": "fdmprinter",
"metadata": {
"visible": true,
"author": "Thushan Fernando",
"manufacturer": "Cocoon Create",
"file_formats": "text/x-gcode",
"preferred_quality_type": "fine",
"has_materials": true,
"platform": "wanhao_200_200_platform.obj",
"platform_texture": "Cocoon-backplate.png",
"machine_extruder_trains": {
"0": "cocoon_create_touch_extruder_0"
},
"platform_offset": [
0,
-28,
0
]
},
"overrides": {
"machine_name": {
"default_value": "Cocoon Create Touch"
},
"machine_width": {
"default_value": 200
},
"machine_height": {
"default_value": 180
},
"machine_depth": {
"default_value": 200
},
"machine_heated_bed": {
"default_value": true
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
"default_value": "G21 ;metric values\n G90 ;absolute positioning\n M82 ;set extruder to absolute mode\n M107 ;start with the fan off\n G28 X0 Y0 ;move X/Y to min endstops\n G28 Z0 ;move Z to min endstops\n G1 Z15.0 F{speed_travel} ;move the platform down 15mm\n G92 E0 ;zero the extruded length\n G1 F200 E3 ;extrude 3mm of feed stock\n G92 E0 ;zero the extruded length again\n G1 F{speed_travel} \n ;Put printing message on LCD screen\n M117 Printing..."
},
"machine_end_gcode": {
"default_value": "M104 S0 ;extruder heater off \n G91 ;relative positioning\n G1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\n G1 Z+0.5 E-5 X-20 Y-20 F{speed_travel} ;move Z up a bit and retract filament even more\n G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\n M84 ;steppers off\n G90 ;absolute positioning"
},
"material_diameter": {
"default_value": 1.75
},
"layer_height": {
"default_value": 0.10
},
"layer_height_0": {
"default_value": 0.2
},
"wall_thickness": {
"value": "0.8"
},
"top_bottom_thickness": {
"default_value": 0.6
},
"speed_print": {
"default_value": 50
},
"support_enable": {
"default_value": true
},
"retraction_enable": {
"default_value": true
},
"retraction_amount": {
"default_value": 4.5
},
"retraction_speed": {
"default_value": 25
}
}
}

View File

@ -183,7 +183,6 @@
"material_initial_print_temperature": { "value": "material_print_temperature" }, "material_initial_print_temperature": { "value": "material_print_temperature" },
"material_final_print_temperature": { "value": "material_print_temperature" }, "material_final_print_temperature": { "value": "material_print_temperature" },
"material_flow": { "value": 100 }, "material_flow": { "value": 100 },
"travel_compensate_overlapping_walls_0_enabled": { "value": "False" },
"z_seam_type": { "value": "'back'" }, "z_seam_type": { "value": "'back'" },
"z_seam_corner": { "value": "'z_seam_corner_weighted'" }, "z_seam_corner": { "value": "'z_seam_corner_weighted'" },

View File

@ -20,9 +20,6 @@
"machine_heated_bed": { "machine_heated_bed": {
"default_value": true "default_value": true
}, },
"travel_compensate_overlapping_walls_enabled": {
"default_value": false
},
"layer_height": { "layer_height": {
"default_value": 0.2 "default_value": 0.2
}, },

View File

@ -1330,38 +1330,6 @@
"limit_to_extruder": "infill_extruder_nr", "limit_to_extruder": "infill_extruder_nr",
"settable_per_mesh": true "settable_per_mesh": true
}, },
"travel_compensate_overlapping_walls_enabled":
{
"label": "Compensate Wall Overlaps",
"description": "Compensate the flow for parts of a wall being printed where there is already a wall in place.",
"type": "bool",
"default_value": true,
"limit_to_extruder": "wall_x_extruder_nr",
"settable_per_mesh": true,
"children":
{
"travel_compensate_overlapping_walls_0_enabled":
{
"label": "Compensate Outer Wall Overlaps",
"description": "Compensate the flow for parts of an outer wall being printed where there is already a wall in place.",
"type": "bool",
"default_value": true,
"value": "travel_compensate_overlapping_walls_enabled",
"limit_to_extruder": "wall_0_extruder_nr",
"settable_per_mesh": true
},
"travel_compensate_overlapping_walls_x_enabled":
{
"label": "Compensate Inner Wall Overlaps",
"description": "Compensate the flow for parts of an inner wall being printed where there is already a wall in place.",
"type": "bool",
"default_value": true,
"value": "travel_compensate_overlapping_walls_enabled",
"limit_to_extruder": "wall_x_extruder_nr",
"settable_per_mesh": true
}
}
},
"wall_min_flow": "wall_min_flow":
{ {
"label": "Minimum Wall Flow", "label": "Minimum Wall Flow",
@ -1371,7 +1339,6 @@
"maximum_value": "100", "maximum_value": "100",
"default_value": 0, "default_value": 0,
"type": "float", "type": "float",
"enabled": "travel_compensate_overlapping_walls_0_enabled or travel_compensate_overlapping_walls_x_enabled",
"settable_per_mesh": true "settable_per_mesh": true
}, },
"wall_min_flow_retract": "wall_min_flow_retract":
@ -1380,7 +1347,7 @@
"description": "If enabled, retraction is used rather than combing for travel moves that replace walls whose flow is below the minimum flow threshold.", "description": "If enabled, retraction is used rather than combing for travel moves that replace walls whose flow is below the minimum flow threshold.",
"type": "bool", "type": "bool",
"default_value": false, "default_value": false,
"enabled": "(travel_compensate_overlapping_walls_0_enabled or travel_compensate_overlapping_walls_x_enabled) and wall_min_flow > 0", "enabled": "wall_min_flow > 0",
"settable_per_mesh": true "settable_per_mesh": true
}, },
"fill_perimeter_gaps": "fill_perimeter_gaps":
@ -4379,7 +4346,7 @@
"type": "bool", "type": "bool",
"default_value": false, "default_value": false,
"value": "support_pattern == 'cross' or support_pattern == 'gyroid'", "value": "support_pattern == 'cross' or support_pattern == 'gyroid'",
"enabled": "(support_enable or support_meshes_present) and (support_pattern == 'grid' or support_pattern == 'triangles' or support_pattern == 'cross' or support_pattern == 'gyroid')", "enabled": "(support_enable or support_meshes_present) and (support_pattern == 'lines' or support_pattern == 'grid' or support_pattern == 'triangles' or support_pattern == 'cross' or support_pattern == 'gyroid')",
"limit_to_extruder": "support_infill_extruder_nr", "limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
@ -6199,7 +6166,7 @@
"infill_mesh_order": "infill_mesh_order":
{ {
"label": "Mesh Processing Rank", "label": "Mesh Processing Rank",
"description": "Determines the priority of this mesh when considering overlapping volumes. Areas where multiple meshes reside will be won by the lower rank mesh. An infill mesh with a higher order will modify the infill of infill meshes with lower order and normal meshes.", "description": "Determines the priority of this mesh when considering multiple overlapping infill meshes. Areas where multiple infill meshes overlap will take on the settings of the mesh with the lowest rank. An infill mesh with a higher order will modify the infill of infill meshes with lower order and normal meshes.",
"default_value": 0, "default_value": 0,
"value": "1 if infill_mesh else 0", "value": "1 if infill_mesh else 0",
"minimum_value_warning": "1", "minimum_value_warning": "1",

View File

@ -48,7 +48,6 @@
"wall_0_wipe_dist": { "value": 0.0 }, "wall_0_wipe_dist": { "value": 0.0 },
"top_bottom_thickness": { "value": "layer_height_0 + layer_height * 3 if layer_height > 0.15 else 0.8" }, "top_bottom_thickness": { "value": "layer_height_0 + layer_height * 3 if layer_height > 0.15 else 0.8" },
"optimize_wall_printing_order": { "value": true }, "optimize_wall_printing_order": { "value": true },
"travel_compensate_overlapping_walls_0_enabled": { "value": false },
"fill_perimeter_gaps": { "value": "'everywhere'" }, "fill_perimeter_gaps": { "value": "'everywhere'" },
"filter_out_tiny_gaps": { "value": false }, "filter_out_tiny_gaps": { "value": false },
"fill_outline_gaps": { "value": false }, "fill_outline_gaps": { "value": false },

View File

@ -91,7 +91,6 @@
"wall_0_inset": {"value": "0" }, "wall_0_inset": {"value": "0" },
"outer_inset_first": {"value": true }, "outer_inset_first": {"value": true },
"alternate_extra_perimeter": {"value": false }, "alternate_extra_perimeter": {"value": false },
"travel_compensate_overlapping_walls_enabled": {"value": false },
"filter_out_tiny_gaps": {"value": true }, "filter_out_tiny_gaps": {"value": true },
"fill_outline_gaps": {"value": true }, "fill_outline_gaps": {"value": true },
"z_seam_type": {"value": "'shortest'"}, "z_seam_type": {"value": "'shortest'"},

View File

@ -176,15 +176,6 @@
"skin_outline_count": { "skin_outline_count": {
"value": 0 "value": 0
}, },
"travel_compensate_overlapping_walls_enabled": {
"value": "False"
},
"travel_compensate_overlapping_walls_0_enabled": {
"value": "False"
},
"travel_compensate_overlapping_walls_x_enabled": {
"value": "False"
},
"wall_0_wipe_dist": { "wall_0_wipe_dist": {
"value": "machine_nozzle_size / 3" "value": "machine_nozzle_size / 3"
}, },

View File

@ -107,9 +107,6 @@
"switch_extruder_retraction_speed": { "switch_extruder_retraction_speed": {
"value": "30" "value": "30"
}, },
"travel_compensate_overlapping_walls_enabled": {
"default_value": false
},
"raft_base_acceleration": { "raft_base_acceleration": {
"value": "400" "value": "400"
}, },
@ -383,9 +380,6 @@
"acceleration_support_infill": { "acceleration_support_infill": {
"value": "400" "value": "400"
}, },
"travel_compensate_overlapping_walls_0_enabled": {
"value": "False"
},
"support_bottom_material_flow": { "support_bottom_material_flow": {
"value": "99" "value": "99"
}, },
@ -638,9 +632,6 @@
"skirt_line_count": { "skirt_line_count": {
"default_value": 2 "default_value": 2
}, },
"travel_compensate_overlapping_walls_x_enabled": {
"value": "False"
},
"jerk_wall_0": { "jerk_wall_0": {
"value": "10" "value": "10"
}, },

View File

@ -83,7 +83,6 @@
"material_initial_print_temperature": { "value": "material_print_temperature" }, "material_initial_print_temperature": { "value": "material_print_temperature" },
"material_final_print_temperature": { "value": "material_print_temperature" }, "material_final_print_temperature": { "value": "material_print_temperature" },
"material_flow": { "value": 100 }, "material_flow": { "value": 100 },
"travel_compensate_overlapping_walls_0_enabled": { "value": "False" },
"z_seam_type": { "value": "'back'" }, "z_seam_type": { "value": "'back'" },
"z_seam_corner": { "value": "'z_seam_corner_weighted'" }, "z_seam_corner": { "value": "'z_seam_corner_weighted'" },

View File

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

View File

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

View File

@ -1488,12 +1488,12 @@ msgstr "다림질 라인 사이의 거리."
#: fdmprinter.def.json #: fdmprinter.def.json
msgctxt "ironing_flow label" msgctxt "ironing_flow label"
msgid "Ironing Flow" msgid "Ironing Flow"
msgstr "다림질 과정" msgstr "다림질 압출량"
#: fdmprinter.def.json #: fdmprinter.def.json
msgctxt "ironing_flow description" msgctxt "ironing_flow description"
msgid "The amount of material, relative to a normal skin line, to extrude during ironing. Keeping the nozzle filled helps filling some of the crevices of the top surface, but too much results in overextrusion and blips on the side of the surface." msgid "The amount of material, relative to a normal skin line, to extrude during ironing. Keeping the nozzle filled helps filling some of the crevices of the top surface, but too much results in overextrusion and blips on the side of the surface."
msgstr "다림질하는 동안 기본 스킨 라인을 기준으로 한 재료의 양. 노즐을 가득 채우면 윗면의 틈새가 채워서포트만 표면의 과도한 압출과 틈이 너무 많이 생깁니다." msgstr "다림질하는 동안 기본 스킨 라인을 기준으로 한 재료의 압출량. 노즐을 가득 채우면 윗면의 틈새를 채울 수 있지만 표면에 과도한 압출과 필라멘트 덩어리가 생길 수 있습니다."
#: fdmprinter.def.json #: fdmprinter.def.json
msgctxt "ironing_inset label" msgctxt "ironing_inset label"

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -77,7 +77,7 @@ Item
Repeater Repeater
{ {
id: extrudersRepeater id: extrudersRepeater
model: activePrinter != null ? activePrinter.extruderList : null model: activePrinter != null ? activePrinter.extruders : null
ExtruderBox ExtruderBox
{ {

View File

@ -104,16 +104,6 @@ Popup
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
// We set it by means of a binding, since then we can use the when condition, which we need to
// prevent a binding loop.
Binding
{
target: parent
property: "height"
value: parent.childrenRect.height
when: parent.visibleChildren.length > 0
}
// Add the qualities that belong to the intent // Add the qualities that belong to the intent
Repeater Repeater
{ {
@ -148,11 +138,7 @@ Popup
Item Item
{ {
height: childrenRect.height height: childrenRect.height
anchors width: popup.contentWidth
{
left: parent.left
right: parent.right
}
Label Label
{ {

View File

@ -1,4 +1,4 @@
// Copyright (c) 2019 Ultimaker B.V. // Copyright (c) 2020 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7 import QtQuick 2.7
@ -11,7 +11,7 @@ UM.PointingRectangle
id: base id: base
property real sourceWidth: 0 property real sourceWidth: 0
width: UM.Theme.getSize("tooltip").width width: UM.Theme.getSize("tooltip").width
height: label.height + UM.Theme.getSize("tooltip_margins").height * 2 height: textScroll.height + UM.Theme.getSize("tooltip_margins").height * 2
color: UM.Theme.getColor("tooltip") color: UM.Theme.getColor("tooltip")
arrowSize: UM.Theme.getSize("default_arrow").width arrowSize: UM.Theme.getSize("default_arrow").width
@ -59,22 +59,48 @@ UM.PointingRectangle
base.opacity = 0; base.opacity = 0;
} }
Label MouseArea
{ {
id: label; enabled: parent.opacity > 0
anchors visible: enabled
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
onHoveredChanged:
{ {
top: parent.top; if(containsMouse && base.opacity > 0)
topMargin: UM.Theme.getSize("tooltip_margins").height; {
left: parent.left; base.show(Qt.point(target.x - 1, target.y - UM.Theme.getSize("tooltip_arrow_margins").height / 2)); //Same arrow position as before.
leftMargin: UM.Theme.getSize("tooltip_margins").width; }
right: parent.right; else
rightMargin: UM.Theme.getSize("tooltip_margins").width; {
base.hide();
}
}
ScrollView
{
id: textScroll
width: parent.width
height: Math.min(label.height, base.parent.height)
ScrollBar.horizontal: ScrollBar {
active: false //Only allow vertical scrolling. We should grow vertically only, but due to how the label is positioned it allocates space in the ScrollView horizontally.
}
Label
{
id: label
x: UM.Theme.getSize("tooltip_margins").width
y: UM.Theme.getSize("tooltip_margins").height
width: base.width - UM.Theme.getSize("tooltip_margins").width * 2
wrapMode: Text.Wrap;
textFormat: Text.RichText
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("tooltip_text");
renderType: Text.NativeRendering
}
} }
wrapMode: Text.Wrap;
textFormat: Text.RichText
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("tooltip_text");
renderType: Text.NativeRendering
} }
} }

View File

@ -21,9 +21,6 @@ wall_0_wipe_dist = 0.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
top_bottom_pattern = lines top_bottom_pattern = lines
optimize_wall_printing_order = True optimize_wall_printing_order = True
travel_compensate_overlapping_walls_enabled = True
travel_compensate_overlapping_walls_0_enabled = True
travel_compensate_overlapping_walls_x_enabled = True
fill_perimeter_gaps = everywhere fill_perimeter_gaps = everywhere
filter_out_tiny_gaps = True filter_out_tiny_gaps = True
z_seam_type = sharpest_corner z_seam_type = sharpest_corner

View File

@ -21,9 +21,6 @@ wall_0_wipe_dist = 0.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
top_bottom_pattern = lines top_bottom_pattern = lines
optimize_wall_printing_order = True optimize_wall_printing_order = True
travel_compensate_overlapping_walls_enabled = True
travel_compensate_overlapping_walls_0_enabled = True
travel_compensate_overlapping_walls_x_enabled = True
fill_perimeter_gaps = everywhere fill_perimeter_gaps = everywhere
filter_out_tiny_gaps = True filter_out_tiny_gaps = True
z_seam_type = sharpest_corner z_seam_type = sharpest_corner

View File

@ -21,9 +21,6 @@ wall_0_wipe_dist = 0.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
top_bottom_pattern = lines top_bottom_pattern = lines
optimize_wall_printing_order = True optimize_wall_printing_order = True
travel_compensate_overlapping_walls_enabled = True
travel_compensate_overlapping_walls_0_enabled = True
travel_compensate_overlapping_walls_x_enabled = True
fill_perimeter_gaps = everywhere fill_perimeter_gaps = everywhere
filter_out_tiny_gaps = True filter_out_tiny_gaps = True
z_seam_type = sharpest_corner z_seam_type = sharpest_corner

View File

@ -21,9 +21,6 @@ wall_0_wipe_dist = 0.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
top_bottom_pattern = lines top_bottom_pattern = lines
optimize_wall_printing_order = True optimize_wall_printing_order = True
travel_compensate_overlapping_walls_enabled = True
travel_compensate_overlapping_walls_0_enabled = True
travel_compensate_overlapping_walls_x_enabled = True
fill_perimeter_gaps = everywhere fill_perimeter_gaps = everywhere
filter_out_tiny_gaps = True filter_out_tiny_gaps = True
z_seam_type = sharpest_corner z_seam_type = sharpest_corner

View File

@ -21,9 +21,6 @@ wall_0_wipe_dist = 0.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
top_bottom_pattern = lines top_bottom_pattern = lines
optimize_wall_printing_order = True optimize_wall_printing_order = True
travel_compensate_overlapping_walls_enabled = True
travel_compensate_overlapping_walls_0_enabled = True
travel_compensate_overlapping_walls_x_enabled = True
fill_perimeter_gaps = everywhere fill_perimeter_gaps = everywhere
filter_out_tiny_gaps = True filter_out_tiny_gaps = True
z_seam_type = sharpest_corner z_seam_type = sharpest_corner

View File

@ -21,9 +21,6 @@ wall_0_wipe_dist = 0.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
top_bottom_pattern = lines top_bottom_pattern = lines
optimize_wall_printing_order = True optimize_wall_printing_order = True
travel_compensate_overlapping_walls_enabled = True
travel_compensate_overlapping_walls_0_enabled = True
travel_compensate_overlapping_walls_x_enabled = True
fill_perimeter_gaps = everywhere fill_perimeter_gaps = everywhere
filter_out_tiny_gaps = True filter_out_tiny_gaps = True
z_seam_type = sharpest_corner z_seam_type = sharpest_corner

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 50 infill_sparse_density = 50
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 1.2
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = =layer_height * 3 top_bottom_thickness = =layer_height * 3
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -18,7 +18,6 @@ wall_thickness = 2.4
top_bottom_thickness = 0.8 top_bottom_thickness = 0.8
wall_0_inset = -0.05 wall_0_inset = -0.05
fill_perimeter_gaps = nowhere fill_perimeter_gaps = nowhere
travel_compensate_overlapping_walls_enabled =
infill_sparse_density = 40 infill_sparse_density = 40
infill_pattern = grid infill_pattern = grid

View File

@ -63,8 +63,6 @@ support_use_towers = False
support_xy_distance = 0.8 support_xy_distance = 0.8
support_xy_distance_overhang = =machine_nozzle_size / 2 support_xy_distance_overhang = =machine_nozzle_size / 2
support_z_distance = 0.2 support_z_distance = 0.2
travel_compensate_overlapping_walls_0_enabled = =travel_compensate_overlapping_walls_enabled
travel_compensate_overlapping_walls_x_enabled = =travel_compensate_overlapping_walls_enabled
travel_retract_before_outer_wall = True travel_retract_before_outer_wall = True
wall_0_wipe_dist = =round(line_width * 1.2,1) wall_0_wipe_dist = =round(line_width * 1.2,1)
bridge_settings_enabled = True bridge_settings_enabled = True

View File

@ -63,8 +63,6 @@ support_use_towers = False
support_xy_distance = 0.8 support_xy_distance = 0.8
support_xy_distance_overhang = =machine_nozzle_size / 2 support_xy_distance_overhang = =machine_nozzle_size / 2
support_z_distance = 0.2 support_z_distance = 0.2
travel_compensate_overlapping_walls_0_enabled = =travel_compensate_overlapping_walls_enabled
travel_compensate_overlapping_walls_x_enabled = =travel_compensate_overlapping_walls_enabled
travel_retract_before_outer_wall = True travel_retract_before_outer_wall = True
wall_0_wipe_dist = =round(line_width * 1.2,1) wall_0_wipe_dist = =round(line_width * 1.2,1)
bridge_settings_enabled = True bridge_settings_enabled = True

View File

@ -63,8 +63,6 @@ support_use_towers = False
support_xy_distance = 0.8 support_xy_distance = 0.8
support_xy_distance_overhang = =machine_nozzle_size / 2 support_xy_distance_overhang = =machine_nozzle_size / 2
support_z_distance = 0.2 support_z_distance = 0.2
travel_compensate_overlapping_walls_0_enabled = =travel_compensate_overlapping_walls_enabled
travel_compensate_overlapping_walls_x_enabled = =travel_compensate_overlapping_walls_enabled
travel_retract_before_outer_wall = True travel_retract_before_outer_wall = True
wall_0_wipe_dist = =round(line_width * 1.2,1) wall_0_wipe_dist = =round(line_width * 1.2,1)
bridge_settings_enabled = True bridge_settings_enabled = True

View File

@ -63,8 +63,6 @@ support_use_towers = False
support_xy_distance = 0.8 support_xy_distance = 0.8
support_xy_distance_overhang = =machine_nozzle_size / 2 support_xy_distance_overhang = =machine_nozzle_size / 2
support_z_distance = 0.2 support_z_distance = 0.2
travel_compensate_overlapping_walls_0_enabled = =travel_compensate_overlapping_walls_enabled
travel_compensate_overlapping_walls_x_enabled = =travel_compensate_overlapping_walls_enabled
travel_retract_before_outer_wall = True travel_retract_before_outer_wall = True
wall_0_wipe_dist = =round(line_width * 1.2,1) wall_0_wipe_dist = =round(line_width * 1.2,1)
bridge_settings_enabled = True bridge_settings_enabled = True

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