Merge remote-tracking branch 'origin/master' into CURA-6387_http_request_manager

This commit is contained in:
Lipu Fei 2020-01-06 11:15:37 +01:00
commit 5a689c2389
22 changed files with 605 additions and 301 deletions

View File

@ -2,7 +2,7 @@
# 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 Optional, Dict, Any, Set, List from typing import Optional, Dict, Any, Set, List
from PyQt5.QtCore import Qt, QObject, pyqtProperty, pyqtSignal from PyQt5.QtCore import Qt, QObject, pyqtProperty, pyqtSignal, QTimer
import cura.CuraApplication import cura.CuraApplication
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
@ -32,9 +32,14 @@ class IntentModel(ListModel):
self._intent_category = "engineering" self._intent_category = "engineering"
self._update_timer = QTimer()
self._update_timer.setInterval(100)
self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._update)
machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager() machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()
machine_manager.globalContainerChanged.connect(self._update) machine_manager.globalContainerChanged.connect(self._updateDelayed)
machine_manager.extruderChanged.connect(self._update) # We also need to update if an extruder gets disabled machine_manager.extruderChanged.connect(self._updateDelayed) # We also need to update if an extruder gets disabled
ContainerRegistry.getInstance().containerAdded.connect(self._onChanged) ContainerRegistry.getInstance().containerAdded.connect(self._onChanged)
ContainerRegistry.getInstance().containerRemoved.connect(self._onChanged) ContainerRegistry.getInstance().containerRemoved.connect(self._onChanged)
self._layer_height_unit = "" # This is cached self._layer_height_unit = "" # This is cached
@ -52,9 +57,12 @@ class IntentModel(ListModel):
def intentCategory(self) -> str: def intentCategory(self) -> str:
return self._intent_category return self._intent_category
def _updateDelayed(self):
self._update_timer.start()
def _onChanged(self, container): def _onChanged(self, container):
if container.getMetaDataEntry("type") == "intent": if container.getMetaDataEntry("type") == "intent":
self._update() self._updateDelayed()
def _update(self) -> None: def _update(self) -> None:
new_items = [] # type: List[Dict[str, Any]] new_items = [] # type: List[Dict[str, Any]]

View File

@ -1,6 +1,6 @@
from UM.Logger import Logger from UM.Logger import Logger
from PyQt5.QtCore import Qt, pyqtSlot, QObject from PyQt5.QtCore import Qt, pyqtSlot, QObject, QTimer
from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QApplication
from UM.Scene.Camera import Camera from UM.Scene.Camera import Camera
@ -26,16 +26,23 @@ class CuraSceneController(QObject):
self._last_selected_index = 0 self._last_selected_index = 0
self._max_build_plate = 1 # default self._max_build_plate = 1 # default
self._change_timer = QTimer()
self._change_timer.setInterval(100)
self._change_timer.setSingleShot(True)
self._change_timer.timeout.connect(self.updateMaxBuildPlate)
Application.getInstance().getController().getScene().sceneChanged.connect(self.updateMaxBuildPlateDelayed)
Application.getInstance().getController().getScene().sceneChanged.connect(self.updateMaxBuildPlate) # it may be a bit inefficient when changing a lot simultaneously def updateMaxBuildPlateDelayed(self, *args):
def updateMaxBuildPlate(self, *args):
if args: if args:
source = args[0] source = args[0]
else: else:
source = None source = None
if not isinstance(source, SceneNode) or isinstance(source, Camera): if not isinstance(source, SceneNode) or isinstance(source, Camera):
return return
self._change_timer.start()
def updateMaxBuildPlate(self, *args):
max_build_plate = self._calcMaxBuildPlate() max_build_plate = self._calcMaxBuildPlate()
changed = False changed = False
if max_build_plate != self._max_build_plate: if max_build_plate != self._max_build_plate:

View File

@ -82,13 +82,9 @@ class MachineManager(QObject):
self._stacks_have_errors = None # type: Optional[bool] self._stacks_have_errors = None # type: Optional[bool]
self._onGlobalContainerChanged()
extruder_manager = self._application.getExtruderManager() extruder_manager = self._application.getExtruderManager()
extruder_manager.activeExtruderChanged.connect(self._onActiveExtruderStackChanged) extruder_manager.activeExtruderChanged.connect(self._onActiveExtruderStackChanged)
self._onActiveExtruderStackChanged()
extruder_manager.activeExtruderChanged.connect(self.activeMaterialChanged) extruder_manager.activeExtruderChanged.connect(self.activeMaterialChanged)
extruder_manager.activeExtruderChanged.connect(self.activeVariantChanged) extruder_manager.activeExtruderChanged.connect(self.activeVariantChanged)
extruder_manager.activeExtruderChanged.connect(self.activeQualityChanged) extruder_manager.activeExtruderChanged.connect(self.activeQualityChanged)

View File

@ -7,7 +7,7 @@ import os
import unicodedata import unicodedata
from typing import Dict, List, Optional, TYPE_CHECKING from typing import Dict, List, Optional, TYPE_CHECKING
from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot, QTimer
from UM.Logger import Logger from UM.Logger import Logger
from UM.Qt.Duration import Duration from UM.Qt.Duration import Duration
@ -47,7 +47,12 @@ class PrintInformation(QObject):
if self._backend: if self._backend:
self._backend.printDurationMessage.connect(self._onPrintDurationMessage) self._backend.printDurationMessage.connect(self._onPrintDurationMessage)
self._application.getController().getScene().sceneChanged.connect(self._onSceneChanged) self._application.getController().getScene().sceneChanged.connect(self._onSceneChangedDelayed)
self._change_timer = QTimer()
self._change_timer.setInterval(100)
self._change_timer.setSingleShot(True)
self._change_timer.timeout.connect(self._onSceneChanged)
self._is_user_specified_job_name = False self._is_user_specified_job_name = False
self._base_name = "" self._base_name = ""
@ -418,12 +423,14 @@ class PrintInformation(QObject):
self._onPrintDurationMessage(build_plate, temp_message, temp_material_amounts) self._onPrintDurationMessage(build_plate, temp_message, temp_material_amounts)
## Listen to scene changes to check if we need to reset the print information def _onSceneChangedDelayed(self, scene_node: SceneNode) -> None:
def _onSceneChanged(self, scene_node: SceneNode) -> None:
# Ignore any changes that are not related to sliceable objects # Ignore any changes that are not related to sliceable objects
if not isinstance(scene_node, SceneNode)\ if not isinstance(scene_node, SceneNode) \
or not scene_node.callDecoration("isSliceable")\ or not scene_node.callDecoration("isSliceable") \
or not scene_node.callDecoration("getBuildPlateNumber") == self._active_build_plate: or not scene_node.callDecoration("getBuildPlateNumber") == self._active_build_plate:
return return
self._change_timer.start()
## Listen to scene changes to check if we need to reset the print information
def _onSceneChanged(self) -> None:
self.setToZeroPrintInformation(self._active_build_plate) self.setToZeroPrintInformation(self._active_build_plate)

View File

@ -46,19 +46,10 @@ class SimulationPass(RenderPass):
self._layer_view = layerview self._layer_view = layerview
self._compatibility_mode = layerview.getCompatibilityMode() self._compatibility_mode = layerview.getCompatibilityMode()
def render(self): def _updateLayerShaderValues(self):
if not self._layer_shader:
if self._compatibility_mode:
shader_filename = "layers.shader"
shadow_shader_filename = "layers_shadow.shader"
else:
shader_filename = "layers3d.shader"
shadow_shader_filename = "layers3d_shadow.shader"
self._layer_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), shader_filename))
self._layer_shadow_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), shadow_shader_filename))
self._current_shader = self._layer_shader
# Use extruder 0 if the extruder manager reports extruder index -1 (for single extrusion printers) # Use extruder 0 if the extruder manager reports extruder index -1 (for single extrusion printers)
self._layer_shader.setUniformValue("u_active_extruder", float(max(0, self._extruder_manager.activeExtruderIndex))) self._layer_shader.setUniformValue("u_active_extruder",
float(max(0, self._extruder_manager.activeExtruderIndex)))
if self._layer_view: if self._layer_view:
self._layer_shader.setUniformValue("u_max_feedrate", self._layer_view.getMaxFeedrate()) self._layer_shader.setUniformValue("u_max_feedrate", self._layer_view.getMaxFeedrate())
self._layer_shader.setUniformValue("u_min_feedrate", self._layer_view.getMinFeedrate()) self._layer_shader.setUniformValue("u_min_feedrate", self._layer_view.getMinFeedrate())
@ -71,7 +62,7 @@ class SimulationPass(RenderPass):
self._layer_shader.setUniformValue("u_show_skin", self._layer_view.getShowSkin()) self._layer_shader.setUniformValue("u_show_skin", self._layer_view.getShowSkin())
self._layer_shader.setUniformValue("u_show_infill", self._layer_view.getShowInfill()) self._layer_shader.setUniformValue("u_show_infill", self._layer_view.getShowInfill())
else: else:
#defaults # defaults
self._layer_shader.setUniformValue("u_max_feedrate", 1) self._layer_shader.setUniformValue("u_max_feedrate", 1)
self._layer_shader.setUniformValue("u_min_feedrate", 0) self._layer_shader.setUniformValue("u_min_feedrate", 0)
self._layer_shader.setUniformValue("u_max_thickness", 1) self._layer_shader.setUniformValue("u_max_thickness", 1)
@ -83,6 +74,20 @@ class SimulationPass(RenderPass):
self._layer_shader.setUniformValue("u_show_skin", 1) self._layer_shader.setUniformValue("u_show_skin", 1)
self._layer_shader.setUniformValue("u_show_infill", 1) self._layer_shader.setUniformValue("u_show_infill", 1)
def render(self):
if not self._layer_shader:
if self._compatibility_mode:
shader_filename = "layers.shader"
shadow_shader_filename = "layers_shadow.shader"
else:
shader_filename = "layers3d.shader"
shadow_shader_filename = "layers3d_shadow.shader"
self._layer_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), shader_filename))
self._layer_shadow_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), shadow_shader_filename))
self._current_shader = self._layer_shader
self._updateLayerShaderValues()
if not self._tool_handle_shader: if not self._tool_handle_shader:
self._tool_handle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "toolhandle.shader")) self._tool_handle_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "toolhandle.shader"))
@ -93,12 +98,10 @@ class SimulationPass(RenderPass):
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)
active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
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
for node in DepthFirstIterator(self._scene.getRoot()): for node in DepthFirstIterator(self._scene.getRoot()):
if isinstance(node, ToolHandle): if isinstance(node, ToolHandle):
tool_handle_batch.addItem(node.getWorldTransformation(), mesh = node.getSolidMesh()) tool_handle_batch.addItem(node.getWorldTransformation(), mesh = node.getSolidMesh())
@ -113,29 +116,24 @@ class SimulationPass(RenderPass):
# Render all layers below a certain number as line mesh instead of vertices. # Render all layers below a certain number as line mesh instead of vertices.
if self._layer_view._current_layer_num > -1 and ((not self._layer_view._only_show_top_layers) or (not self._layer_view.getCompatibilityMode())): if self._layer_view._current_layer_num > -1 and ((not self._layer_view._only_show_top_layers) or (not self._layer_view.getCompatibilityMode())):
start = 0 start = self._layer_view.start_elements_index
end = 0 end = self._layer_view.end_elements_index
element_counts = layer_data.getElementCounts() index = self._layer_view._current_path_num
for layer in sorted(element_counts.keys()): offset = 0
# In the current layer, we show just the indicated paths layer = layer_data.getLayer(self._layer_view._current_layer_num)
if layer == self._layer_view._current_layer_num: if layer is None:
# We look for the position of the head, searching the point of the current path continue
index = self._layer_view._current_path_num for polygon in layer.polygons:
offset = 0 # The size indicates all values in the two-dimension array, and the second dimension is
for polygon in layer_data.getLayer(layer).polygons: # always size 3 because we have 3D points.
# The size indicates all values in the two-dimension array, and the second dimension is if index >= polygon.data.size // 3 - offset:
# always size 3 because we have 3D points. index -= polygon.data.size // 3 - offset
if index >= polygon.data.size // 3 - offset: offset = 1 # This is to avoid the first point when there is more than one polygon, since has the same value as the last point in the previous polygon
index -= polygon.data.size // 3 - offset continue
offset = 1 # This is to avoid the first point when there is more than one polygon, since has the same value as the last point in the previous polygon # The head position is calculated and translated
continue head_position = Vector(polygon.data[index + offset][0], polygon.data[index + offset][1],
# The head position is calculated and translated polygon.data[index + offset][2]) + node.getWorldPosition()
head_position = Vector(polygon.data[index+offset][0], polygon.data[index+offset][1], polygon.data[index+offset][2]) + node.getWorldPosition() break
break
break
if self._layer_view._minimum_layer_num > layer:
start += element_counts[layer]
end += element_counts[layer]
# Calculate the range of paths in the last layer # Calculate the range of paths in the last layer
current_layer_start = end current_layer_start = end

View File

@ -71,6 +71,8 @@ class SimulationView(CuraView):
self._max_paths = 0 self._max_paths = 0
self._current_path_num = 0 self._current_path_num = 0
self._minimum_path_num = 0 self._minimum_path_num = 0
self.start_elements_index = 0
self.end_elements_index = 0
self.currentLayerNumChanged.connect(self._onCurrentLayerNumChanged) self.currentLayerNumChanged.connect(self._onCurrentLayerNumChanged)
self._busy = False self._busy = False
@ -243,6 +245,7 @@ class SimulationView(CuraView):
self._minimum_layer_num = self._current_layer_num self._minimum_layer_num = self._current_layer_num
self._startUpdateTopLayers() self._startUpdateTopLayers()
self.recalculateStartEndElements()
self.currentLayerNumChanged.emit() self.currentLayerNumChanged.emit()
@ -257,7 +260,7 @@ class SimulationView(CuraView):
self._current_layer_num = self._minimum_layer_num self._current_layer_num = self._minimum_layer_num
self._startUpdateTopLayers() self._startUpdateTopLayers()
self.recalculateStartEndElements()
self.currentLayerNumChanged.emit() self.currentLayerNumChanged.emit()
def setPath(self, value: int) -> None: def setPath(self, value: int) -> None:
@ -271,7 +274,7 @@ class SimulationView(CuraView):
self._minimum_path_num = self._current_path_num self._minimum_path_num = self._current_path_num
self._startUpdateTopLayers() self._startUpdateTopLayers()
self.recalculateStartEndElements()
self.currentPathNumChanged.emit() self.currentPathNumChanged.emit()
def setMinimumPath(self, value: int) -> None: def setMinimumPath(self, value: int) -> None:
@ -359,6 +362,24 @@ class SimulationView(CuraView):
return 0.0 # If it's still max-float, there are no measurements. Use 0 then. return 0.0 # If it's still max-float, there are no measurements. Use 0 then.
return self._min_thickness return self._min_thickness
def recalculateStartEndElements(self):
self.start_elements_index = 0
self.end_elements_index = 0
scene = self.getController().getScene()
for node in DepthFirstIterator(scene.getRoot()): # type: ignore
layer_data = node.callDecoration("getLayerData")
if not layer_data:
continue
# Found a the layer data!
element_counts = layer_data.getElementCounts()
for layer in sorted(element_counts.keys()):
if layer == self._current_layer_num:
break
if self._minimum_layer_num > layer:
self.start_elements_index += element_counts[layer]
self.end_elements_index += element_counts[layer]
def getMaxThickness(self) -> float: def getMaxThickness(self) -> float:
return self._max_thickness return self._max_thickness
@ -578,7 +599,7 @@ class SimulationView(CuraView):
def _startUpdateTopLayers(self) -> None: def _startUpdateTopLayers(self) -> None:
if not self._compatibility_mode: if not self._compatibility_mode:
return return
self.recalculateStartEndElements()
if self._top_layers_job: if self._top_layers_job:
self._top_layers_job.finished.disconnect(self._updateCurrentLayerMesh) self._top_layers_job.finished.disconnect(self._updateCurrentLayerMesh)
self._top_layers_job.cancel() self._top_layers_job.cancel()

View File

@ -0,0 +1,58 @@
{
"version": 2,
"name": "BeamUp S",
"inherits": "fdmprinter",
"metadata": {
"visible": true,
"author": "BeamUp",
"manufacturer": "BeamUp",
"file_formats": "text/x-gcode",
"platform": "beamup_s.stl",
"platform_offset": [0, -5, -10],
"has_machine_quality": true,
"has_materials": true,
"machine_extruder_trains":
{
"0": "beamup_s_extruder_0"
}
},
"overrides": {
"machine_name": {
"default_value": "BeamUp S"
},
"machine_width": {
"default_value": 200
},
"machine_depth": {
"default_value": 180
},
"machine_height": {
"default_value": 130
},
"machine_heated_bed": {
"default_value": false
},
"machine_center_is_zero": {
"default_value": false
},
"machine_nozzle_heat_up_speed": {
"default_value": 2
},
"machine_nozzle_cool_down_speed": {
"default_value": 2
},
"gantry_height": {
"value": "0"
},
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
"machine_start_gcode": {
"default_value": "G28 ; home\nG29 ; level\nM80 ; led\nG1 Z15.0 F6000\nT0\nG92 E0.0000\nG1 E-1.4500 F1800\nG1 X5 Y0 Z0.300 F6000\nM300 S3000 P300\nG1 E1.0000 F1800\nG92 E0.0000\nG1 X180 Y0 E15 F662"
},
"machine_end_gcode": {
"default_value": "G28 ; home\nM104 S0 ; turn off\n M140 S0 ; turn off\nM84 ; disable motors\nM107 ; fan off"
}
}
}

View File

@ -2681,150 +2681,6 @@
"maximum_value_warning": "150", "maximum_value_warning": "150",
"settable_per_mesh": true "settable_per_mesh": true
}, },
"retraction_enable":
{
"label": "Enable Retraction",
"description": "Retract the filament when the nozzle is moving over a non-printed area. ",
"type": "bool",
"default_value": true,
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retract_at_layer_change":
{
"label": "Retract at Layer Change",
"description": "Retract the filament when the nozzle is moving to the next layer.",
"type": "bool",
"default_value": false,
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_amount":
{
"label": "Retraction Distance",
"description": "The length of material retracted during a retraction move.",
"unit": "mm",
"type": "float",
"default_value": 6.5,
"minimum_value_warning": "-0.0001",
"maximum_value_warning": "10.0",
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_speed":
{
"label": "Retraction Speed",
"description": "The speed at which the filament is retracted and primed during a retraction move.",
"unit": "mm/s",
"type": "float",
"default_value": 25,
"minimum_value": "0.0001",
"minimum_value_warning": "1",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value_warning": "70",
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children":
{
"retraction_retract_speed":
{
"label": "Retraction Retract Speed",
"description": "The speed at which the filament is retracted during a retraction move.",
"unit": "mm/s",
"type": "float",
"default_value": 25,
"minimum_value": "0.0001",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"minimum_value_warning": "1",
"maximum_value_warning": "70",
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
"value": "retraction_speed",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_prime_speed":
{
"label": "Retraction Prime Speed",
"description": "The speed at which the filament is primed during a retraction move.",
"unit": "mm/s",
"type": "float",
"default_value": 25,
"minimum_value": "0.0001",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"minimum_value_warning": "1",
"maximum_value_warning": "70",
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
"value": "retraction_speed",
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
},
"retraction_extra_prime_amount":
{
"label": "Retraction Extra Prime Amount",
"description": "Some material can ooze away during a travel move, which can be compensated for here.",
"unit": "mm³",
"type": "float",
"default_value": 0,
"minimum_value_warning": "-0.0001",
"maximum_value_warning": "5.0",
"enabled": "retraction_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_min_travel":
{
"label": "Retraction Minimum Travel",
"description": "The minimum distance of travel needed for a retraction to happen at all. This helps to get fewer retractions in a small area.",
"unit": "mm",
"type": "float",
"default_value": 1.5,
"value": "line_width * 2",
"minimum_value": "0",
"minimum_value_warning": "line_width * 1.5",
"maximum_value_warning": "10",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_count_max":
{
"label": "Maximum Retraction Count",
"description": "This setting limits the number of retractions occurring within the minimum extrusion distance window. Further retractions within this window will be ignored. This avoids retracting repeatedly on the same piece of filament, as that can flatten the filament and cause grinding issues.",
"default_value": 90,
"minimum_value": "0",
"maximum_value_warning": "100",
"type": "int",
"enabled": "retraction_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_extrusion_window":
{
"label": "Minimum Extrusion Distance Window",
"description": "The window in which the maximum retraction count is enforced. This value should be approximately the same as the retraction distance, so that effectively the number of times a retraction passes the same patch of material is limited.",
"unit": "mm",
"type": "float",
"default_value": 4.5,
"minimum_value": "0",
"maximum_value_warning": "retraction_amount * 2",
"value": "retraction_amount",
"enabled": "retraction_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"limit_support_retractions":
{
"label": "Limit Support Retractions",
"description": "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excessive stringing within the support structure.",
"type": "bool",
"default_value": true,
"enabled": "retraction_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"material_standby_temperature": "material_standby_temperature":
{ {
"label": "Standby Temperature", "label": "Standby Temperature",
@ -2838,83 +2694,6 @@
"enabled": "extruders_enabled_count > 1 and machine_nozzle_temp_enabled", "enabled": "extruders_enabled_count > 1 and machine_nozzle_temp_enabled",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true "settable_per_extruder": true
},
"switch_extruder_retraction_amount":
{
"label": "Nozzle Switch Retraction Distance",
"description": "The amount of retraction when switching extruders. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone.",
"type": "float",
"unit": "mm",
"enabled": "retraction_enable",
"default_value": 20,
"value": "machine_heat_zone_length",
"minimum_value_warning": "0",
"maximum_value_warning": "100",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"switch_extruder_retraction_speeds":
{
"label": "Nozzle Switch Retraction Speed",
"description": "The speed at which the filament is retracted. A higher retraction speed works better, but a very high retraction speed can lead to filament grinding.",
"type": "float",
"unit": "mm/s",
"enabled": "retraction_enable",
"default_value": 20,
"minimum_value": "0.1",
"minimum_value_warning": "1",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value_warning": "70",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children":
{
"switch_extruder_retraction_speed":
{
"label": "Nozzle Switch Retract Speed",
"description": "The speed at which the filament is retracted during a nozzle switch retract.",
"type": "float",
"unit": "mm/s",
"enabled": "retraction_enable",
"default_value": 20,
"value": "switch_extruder_retraction_speeds",
"minimum_value": "0.1",
"minimum_value_warning": "1",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value_warning": "70",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"switch_extruder_prime_speed":
{
"label": "Nozzle Switch Prime Speed",
"description": "The speed at which the filament is pushed back after a nozzle switch retraction.",
"type": "float",
"unit": "mm/s",
"enabled": "retraction_enable",
"default_value": 20,
"value": "switch_extruder_retraction_speeds",
"minimum_value": "0.1",
"minimum_value_warning": "1",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value_warning": "70",
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
},
"switch_extruder_extra_prime_amount":
{
"label": "Nozzle Switch Extra Prime Amount",
"description": "Extra material to prime after nozzle switching.",
"type": "float",
"unit": "mm³",
"default_value": 0,
"minimum_value_warning": "0",
"maximum_value_warning": "100",
"enabled": "retraction_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
} }
} }
}, },
@ -3830,6 +3609,150 @@
"type": "category", "type": "category",
"children": "children":
{ {
"retraction_enable":
{
"label": "Enable Retraction",
"description": "Retract the filament when the nozzle is moving over a non-printed area. ",
"type": "bool",
"default_value": true,
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retract_at_layer_change":
{
"label": "Retract at Layer Change",
"description": "Retract the filament when the nozzle is moving to the next layer.",
"type": "bool",
"default_value": false,
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_amount":
{
"label": "Retraction Distance",
"description": "The length of material retracted during a retraction move.",
"unit": "mm",
"type": "float",
"default_value": 6.5,
"minimum_value_warning": "-0.0001",
"maximum_value_warning": "10.0",
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_speed":
{
"label": "Retraction Speed",
"description": "The speed at which the filament is retracted and primed during a retraction move.",
"unit": "mm/s",
"type": "float",
"default_value": 25,
"minimum_value": "0.0001",
"minimum_value_warning": "1",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value_warning": "70",
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children":
{
"retraction_retract_speed":
{
"label": "Retraction Retract Speed",
"description": "The speed at which the filament is retracted during a retraction move.",
"unit": "mm/s",
"type": "float",
"default_value": 25,
"minimum_value": "0.0001",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"minimum_value_warning": "1",
"maximum_value_warning": "70",
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
"value": "retraction_speed",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_prime_speed":
{
"label": "Retraction Prime Speed",
"description": "The speed at which the filament is primed during a retraction move.",
"unit": "mm/s",
"type": "float",
"default_value": 25,
"minimum_value": "0.0001",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"minimum_value_warning": "1",
"maximum_value_warning": "70",
"enabled": "retraction_enable and machine_gcode_flavor != \"UltiGCode\"",
"value": "retraction_speed",
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
},
"retraction_extra_prime_amount":
{
"label": "Retraction Extra Prime Amount",
"description": "Some material can ooze away during a travel move, which can be compensated for here.",
"unit": "mm³",
"type": "float",
"default_value": 0,
"minimum_value_warning": "-0.0001",
"maximum_value_warning": "5.0",
"enabled": "retraction_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_min_travel":
{
"label": "Retraction Minimum Travel",
"description": "The minimum distance of travel needed for a retraction to happen at all. This helps to get fewer retractions in a small area.",
"unit": "mm",
"type": "float",
"default_value": 1.5,
"value": "line_width * 2",
"minimum_value": "0",
"minimum_value_warning": "line_width * 1.5",
"maximum_value_warning": "10",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_count_max":
{
"label": "Maximum Retraction Count",
"description": "This setting limits the number of retractions occurring within the minimum extrusion distance window. Further retractions within this window will be ignored. This avoids retracting repeatedly on the same piece of filament, as that can flatten the filament and cause grinding issues.",
"default_value": 90,
"minimum_value": "0",
"maximum_value_warning": "100",
"type": "int",
"enabled": "retraction_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_extrusion_window":
{
"label": "Minimum Extrusion Distance Window",
"description": "The window in which the maximum retraction count is enforced. This value should be approximately the same as the retraction distance, so that effectively the number of times a retraction passes the same patch of material is limited.",
"unit": "mm",
"type": "float",
"default_value": 4.5,
"minimum_value": "0",
"maximum_value_warning": "retraction_amount * 2",
"value": "retraction_amount",
"enabled": "retraction_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"limit_support_retractions":
{
"label": "Limit Support Retractions",
"description": "Omit retraction when moving from support to support in a straight line. Enabling this setting saves print time, but can lead to excessive stringing within the support structure.",
"type": "bool",
"default_value": true,
"enabled": "retraction_enable and (support_enable or support_tree_enable)",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"retraction_combing": "retraction_combing":
{ {
"label": "Combing Mode", "label": "Combing Mode",
@ -5843,6 +5766,83 @@
"maximum_value_warning": "20", "maximum_value_warning": "20",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false "settable_per_extruder": false
},
"switch_extruder_retraction_amount":
{
"label": "Nozzle Switch Retraction Distance",
"description": "The amount of retraction when switching extruders. Set to 0 for no retraction at all. This should generally be the same as the length of the heat zone.",
"type": "float",
"unit": "mm",
"enabled": "retraction_enable and extruders_enabled_count > 1",
"default_value": 20,
"value": "machine_heat_zone_length",
"minimum_value_warning": "0",
"maximum_value_warning": "100",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"switch_extruder_retraction_speeds":
{
"label": "Nozzle Switch Retraction Speed",
"description": "The speed at which the filament is retracted. A higher retraction speed works better, but a very high retraction speed can lead to filament grinding.",
"type": "float",
"unit": "mm/s",
"enabled": "retraction_enable and extruders_enabled_count > 1",
"default_value": 20,
"minimum_value": "0.1",
"minimum_value_warning": "1",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value_warning": "70",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children":
{
"switch_extruder_retraction_speed":
{
"label": "Nozzle Switch Retract Speed",
"description": "The speed at which the filament is retracted during a nozzle switch retract.",
"type": "float",
"unit": "mm/s",
"enabled": "retraction_enable and extruders_enabled_count > 1",
"default_value": 20,
"value": "switch_extruder_retraction_speeds",
"minimum_value": "0.1",
"minimum_value_warning": "1",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value_warning": "70",
"settable_per_mesh": false,
"settable_per_extruder": true
},
"switch_extruder_prime_speed":
{
"label": "Nozzle Switch Prime Speed",
"description": "The speed at which the filament is pushed back after a nozzle switch retraction.",
"type": "float",
"unit": "mm/s",
"enabled": "retraction_enable and extruders_enabled_count > 1",
"default_value": 20,
"value": "switch_extruder_retraction_speeds",
"minimum_value": "0.1",
"minimum_value_warning": "1",
"maximum_value": "machine_max_feedrate_e if retraction_enable else float('inf')",
"maximum_value_warning": "70",
"settable_per_mesh": false,
"settable_per_extruder": true
}
}
},
"switch_extruder_extra_prime_amount":
{
"label": "Nozzle Switch Extra Prime Amount",
"description": "Extra material to prime after nozzle switching.",
"type": "float",
"unit": "mm³",
"default_value": 0,
"minimum_value_warning": "0",
"maximum_value_warning": "100",
"enabled": "retraction_enable and extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": true
} }
} }
}, },

View File

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

Binary file not shown.

View File

@ -14,11 +14,11 @@ Menu
property int extruderIndex: 0 property int extruderIndex: 0
property string currentRootMaterialId: Cura.MachineManager.currentRootMaterialId[extruderIndex] property string currentRootMaterialId: Cura.MachineManager.currentRootMaterialId[extruderIndex]
property string activeMaterialId: property var activeExtruder: Cura.MachineManager.activeMachine.extruderList[extruderIndex]
{ property bool isActiveExtruderEnabled: activeExtruder === undefined ? false : activeExtruder.isEnabled
var extruder = Cura.MachineManager.activeMachine.extruderList[extruderIndex]
return (extruder === undefined) ? "" : extruder.material.id property string activeMaterialId: activeExtruder === undefined ? false : activeExtruder.material.id
}
property bool updateModels: true property bool updateModels: true
Cura.FavoriteMaterialsModel Cura.FavoriteMaterialsModel
{ {
@ -54,7 +54,7 @@ Menu
{ {
text: model.brand + " " + model.name text: model.brand + " " + model.name
checkable: true checkable: true
enabled: Cura.MachineManager.activeMachine.extruderList[extruderIndex].isEnabled enabled: isActiveExtruderEnabled
checked: model.root_material_id === menu.currentRootMaterialId checked: model.root_material_id === menu.currentRootMaterialId
onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node)
exclusiveGroup: favoriteGroup // One favorite and one item from the others can be active at the same time. exclusiveGroup: favoriteGroup // One favorite and one item from the others can be active at the same time.
@ -77,11 +77,7 @@ Menu
{ {
text: model.name text: model.name
checkable: true checkable: true
enabled: enabled: isActiveExtruderEnabled
{
var extruder = Cura.MachineManager.activeMachine.extruderList[extruderIndex]
return (extruder === undefined) ? false : extruder.isEnabled
}
checked: model.root_material_id === menu.currentRootMaterialId checked: model.root_material_id === menu.currentRootMaterialId
exclusiveGroup: group exclusiveGroup: group
onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node)
@ -120,11 +116,7 @@ Menu
{ {
text: model.name text: model.name
checkable: true checkable: true
enabled: enabled: isActiveExtruderEnabled
{
var extruder = Cura.MachineManager.activeMachine.extruderList[extruderIndex]
return (extruder === undefined) ? false : extruder.isEnabled
}
checked: model.id === menu.activeMaterialId checked: model.id === menu.activeMaterialId
exclusiveGroup: group exclusiveGroup: group
onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node) onTriggered: Cura.MachineManager.setMaterial(extruderIndex, model.container_node)

View File

@ -33,7 +33,7 @@ SettingItem
anchors.fill: parent anchors.fill: parent
radius: UM.Theme.getSize("setting_control_radius").width radius: UM.Theme.getSize("setting_control_radius").width
border.width: Math.round(UM.Theme.getSize("default_lining").width) border.width: UM.Theme.getSize("default_lining").width
border.color: border.color:
{ {
if(!enabled) if(!enabled)

View File

@ -25,7 +25,7 @@ Item
visible: true visible: true
radius: UM.Theme.getSize("setting_control_radius").width radius: UM.Theme.getSize("setting_control_radius").width
border.width: Math.round(UM.Theme.getSize("default_lining").width) border.width: UM.Theme.getSize("default_lining").width
border.color: border.color:
{ {
if (hoverMouseArea.containsMouse || clearFilterButton.containsMouse) if (hoverMouseArea.containsMouse || clearFilterButton.containsMouse)

View File

@ -66,7 +66,7 @@ Item
{ {
id: networkPrinterListView id: networkPrinterListView
anchors.fill: parent anchors.fill: parent
model: CuraApplication.getDiscoveredPrintersModel().discoveredPrinters model: contentLoader.enabled ? CuraApplication.getDiscoveredPrintersModel().discoveredPrinters: undefined
section.property: "modelData.sectionName" section.property: "modelData.sectionName"
section.criteria: ViewSection.FullString section.criteria: ViewSection.FullString

View File

@ -71,6 +71,7 @@ Item
right: parent.right right: parent.right
} }
source: base.pageUrl source: base.pageUrl
enabled: base.visible
} }
} }
} }

View File

@ -0,0 +1,40 @@
[general]
version = 4
name = BeamUp S Coarse
definition = beamup_s
[metadata]
setting_version = 10
type = quality
quality_type = coarse
weight = -3
material = generic_pla
[values]
layer_height = 0.30
adhesion_type = brim
brim_line_count = 5
infill_before_walls = False
initial_layer_line_width_factor = 120.0
material_print_temperature = 215
material_print_temperature_layer_0 = 230
retraction_amount = 1.5
retraction_speed = 30
speed_infill = 50
speed_layer_0 = 25
speed_print = 50
speed_support_interface = 50
speed_topbottom = 50
speed_wall_0 = 35
speed_wall_x = 50
support_enable = True
support_angle = 60
support_infill_rate = 20
support_interface_enable = True
support_interface_height = 0.60
support_interface_pattern = zigzag
support_interface_skip_height = 0.30
support_offset = 0.8
support_z_distance = 0.2
wall_thickness = 0.8
zig_zaggify_infill = True

View File

@ -0,0 +1,40 @@
[general]
version = 4
name = BeamUp S Draft
definition = beamup_s
[metadata]
setting_version = 10
type = quality
quality_type = draft
weight = -2
material = generic_pla
[values]
layer_height = 0.2
adhesion_type = brim
brim_line_count = 5
infill_before_walls = False
initial_layer_line_width_factor = 120.0
material_print_temperature = 210
material_print_temperature_layer_0 = 230
retraction_amount = 1.5
retraction_speed = 30
speed_infill = 45
speed_layer_0 = 25
speed_print = 45
speed_support_interface = 45
speed_topbottom = 45
speed_wall_0 = 35
speed_wall_x = 45
support_enable = True
support_angle = 60
support_infill_rate = 20
support_interface_enable = True
support_interface_height = 0.40
support_interface_pattern = zigzag
support_interface_skip_height = 0.20
support_offset = 0.8
support_z_distance = 0.2
wall_thickness = 0.8
zig_zaggify_infill = True

View File

@ -0,0 +1,40 @@
[general]
version = 4
name = BeamUp S Extra Fine
definition = beamup_s
[metadata]
setting_version = 10
type = quality
quality_type = high
weight = 1
material = generic_pla
[values]
layer_height = 0.06
adhesion_type = brim
brim_line_count = 5
infill_before_walls = False
initial_layer_line_width_factor = 120.0
material_print_temperature = 195
material_print_temperature_layer_0 = 230
retraction_amount = 1.5
retraction_speed = 30
speed_infill = 40
speed_layer_0 = 25
speed_print = 40
speed_support_interface = 40
speed_topbottom = 40
speed_wall_0 = 30
speed_wall_x = 40
support_enable = True
support_angle = 60
support_infill_rate = 20
support_interface_enable = True
support_interface_height = 0.30
support_interface_pattern = zigzag
support_interface_skip_height = 0.06
support_offset = 0.8
support_z_distance = 0.2
wall_thickness = 0.8
zig_zaggify_infill = True

View File

@ -0,0 +1,40 @@
[general]
version = 4
name = BeamUp S Fine
definition = beamup_s
[metadata]
setting_version = 10
type = quality
quality_type = normal
weight = 0
material = generic_pla
[values]
layer_height = 0.1
adhesion_type = brim
brim_line_count = 5
infill_before_walls = False
initial_layer_line_width_factor = 120.0
material_print_temperature = 200
material_print_temperature_layer_0 = 230
retraction_amount = 1.5
retraction_speed = 30
speed_infill = 40
speed_layer_0 = 25
speed_print = 40
speed_support_interface = 40
speed_topbottom = 40
speed_wall_0 = 30
speed_wall_x = 40
support_enable = True
support_angle = 60
support_infill_rate = 20
support_interface_enable = True
support_interface_height = 0.30
support_interface_pattern = zigzag
support_interface_skip_height = 0.10
support_offset = 0.8
support_z_distance = 0.2
wall_thickness = 0.8
zig_zaggify_infill = True

View File

@ -0,0 +1,40 @@
[general]
version = 4
name = BeamUp S Normal
definition = beamup_s
[metadata]
setting_version = 10
type = quality
quality_type = fast
weight = -1
material = generic_pla
[values]
layer_height = 0.15
adhesion_type = brim
brim_line_count = 5
infill_before_walls = False
initial_layer_line_width_factor = 120.0
material_print_temperature = 205
material_print_temperature_layer_0 = 230
retraction_amount = 1.5
retraction_speed = 30
speed_infill = 45
speed_layer_0 = 25
speed_print = 45
speed_support_interface = 45
speed_topbottom = 45
speed_wall_0 = 35
speed_wall_x = 45
support_enable = True
support_angle = 60
support_infill_rate = 20
support_interface_enable = True
support_interface_height = 0.45
support_interface_pattern = zigzag
support_interface_skip_height = 0.15
support_offset = 0.8
support_z_distance = 0.2
wall_thickness = 0.8
zig_zaggify_infill = True

View File

@ -76,9 +76,9 @@ def main():
print("\nCommand %s failed checking. :(" % commands[i]) print("\nCommand %s failed checking. :(" % commands[i])
success_code = 1 success_code = 1
if success_code: if success_code:
print("MYPY check was compleded, but did not pass") print("MYPY check was completed, but did not pass")
else: else:
print("MYPY check was compleded and passed with flying colors") print("MYPY check was completed and passed with flying colors")
return success_code return success_code
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -15,6 +15,7 @@ def machine_manager(application, extruder_manager, container_registry, global_st
application.getGlobalContainerStack = MagicMock(return_value = global_stack) application.getGlobalContainerStack = MagicMock(return_value = global_stack)
with patch("cura.Settings.CuraContainerRegistry.CuraContainerRegistry.getInstance", MagicMock(return_value=container_registry)): with patch("cura.Settings.CuraContainerRegistry.CuraContainerRegistry.getInstance", MagicMock(return_value=container_registry)):
manager = MachineManager(application) manager = MachineManager(application)
manager._onGlobalContainerChanged()
return manager return manager