mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-14 17:25:57 +08:00
Merge branch 'master' into master
This commit is contained in:
commit
20971cecc9
@ -1,16 +0,0 @@
|
|||||||
image: registry.gitlab.com/ultimaker/cura/cura-build-environment:centos7
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- build
|
|
||||||
|
|
||||||
build and test linux:
|
|
||||||
stage: build
|
|
||||||
tags:
|
|
||||||
- cura
|
|
||||||
- docker
|
|
||||||
- linux
|
|
||||||
script:
|
|
||||||
- docker/build.sh
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- build
|
|
@ -22,13 +22,6 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
CuraAppName = DEFAULT_CURA_APP_NAME
|
CuraAppName = DEFAULT_CURA_APP_NAME
|
||||||
|
|
||||||
try:
|
|
||||||
from cura.CuraVersion import CuraAppDisplayName # type: ignore
|
|
||||||
if CuraAppDisplayName == "":
|
|
||||||
CuraAppDisplayName = DEFAULT_CURA_DISPLAY_NAME
|
|
||||||
except ImportError:
|
|
||||||
CuraAppDisplayName = DEFAULT_CURA_DISPLAY_NAME
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from cura.CuraVersion import CuraVersion # type: ignore
|
from cura.CuraVersion import CuraVersion # type: ignore
|
||||||
if CuraVersion == "":
|
if CuraVersion == "":
|
||||||
@ -53,3 +46,13 @@ except ImportError:
|
|||||||
# Various convenience flags indicating what kind of Cura build it is.
|
# Various convenience flags indicating what kind of Cura build it is.
|
||||||
__ENTERPRISE_VERSION_TYPE = "enterprise"
|
__ENTERPRISE_VERSION_TYPE = "enterprise"
|
||||||
IsEnterpriseVersion = CuraBuildType.lower() == __ENTERPRISE_VERSION_TYPE
|
IsEnterpriseVersion = CuraBuildType.lower() == __ENTERPRISE_VERSION_TYPE
|
||||||
|
|
||||||
|
try:
|
||||||
|
from cura.CuraVersion import CuraAppDisplayName # type: ignore
|
||||||
|
if CuraAppDisplayName == "":
|
||||||
|
CuraAppDisplayName = DEFAULT_CURA_DISPLAY_NAME
|
||||||
|
if IsEnterpriseVersion:
|
||||||
|
CuraAppDisplayName = CuraAppDisplayName + " Enterprise"
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
CuraAppDisplayName = DEFAULT_CURA_DISPLAY_NAME
|
||||||
|
@ -67,11 +67,9 @@ from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
|
|||||||
from cura.Scene.ConvexHullDecorator import ConvexHullDecorator
|
from cura.Scene.ConvexHullDecorator import ConvexHullDecorator
|
||||||
from cura.Scene.CuraSceneController import CuraSceneController
|
from cura.Scene.CuraSceneController import CuraSceneController
|
||||||
from cura.Scene.CuraSceneNode import CuraSceneNode
|
from cura.Scene.CuraSceneNode import CuraSceneNode
|
||||||
from cura.Scene.GCodeListDecorator import GCodeListDecorator
|
|
||||||
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
|
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
|
||||||
from cura.Scene import ZOffsetDecorator
|
from cura.Scene import ZOffsetDecorator
|
||||||
|
|
||||||
from cura.Machines.ContainerTree import ContainerTree
|
|
||||||
from cura.Machines.MachineErrorChecker import MachineErrorChecker
|
from cura.Machines.MachineErrorChecker import MachineErrorChecker
|
||||||
|
|
||||||
from cura.Machines.Models.BuildPlateModel import BuildPlateModel
|
from cura.Machines.Models.BuildPlateModel import BuildPlateModel
|
||||||
@ -170,7 +168,7 @@ class CuraApplication(QtApplication):
|
|||||||
app_display_name = ApplicationMetadata.CuraAppDisplayName,
|
app_display_name = ApplicationMetadata.CuraAppDisplayName,
|
||||||
version = ApplicationMetadata.CuraVersion,
|
version = ApplicationMetadata.CuraVersion,
|
||||||
api_version = ApplicationMetadata.CuraSDKVersion,
|
api_version = ApplicationMetadata.CuraSDKVersion,
|
||||||
buildtype = ApplicationMetadata.CuraBuildType,
|
build_type = ApplicationMetadata.CuraBuildType,
|
||||||
is_debug_mode = ApplicationMetadata.CuraDebugMode,
|
is_debug_mode = ApplicationMetadata.CuraDebugMode,
|
||||||
tray_icon_name = "cura-icon-32.png",
|
tray_icon_name = "cura-icon-32.png",
|
||||||
**kwargs)
|
**kwargs)
|
||||||
|
@ -162,6 +162,7 @@ class MachineNode(ContainerNode):
|
|||||||
container_registry = ContainerRegistry.getInstance()
|
container_registry = ContainerRegistry.getInstance()
|
||||||
if not self.has_variants:
|
if not self.has_variants:
|
||||||
self.variants["empty"] = VariantNode("empty_variant", machine = self)
|
self.variants["empty"] = VariantNode("empty_variant", machine = self)
|
||||||
|
self.variants["empty"].materialsChanged.connect(self.materialsChanged)
|
||||||
else:
|
else:
|
||||||
# Find all the variants for this definition ID.
|
# Find all the variants for this definition ID.
|
||||||
variants = container_registry.findInstanceContainersMetadata(type = "variant", definition = self.container_id, hardware_type = "nozzle")
|
variants = container_registry.findInstanceContainersMetadata(type = "variant", definition = self.container_id, hardware_type = "nozzle")
|
||||||
|
@ -1008,9 +1008,9 @@ class MachineManager(QObject):
|
|||||||
|
|
||||||
# Set quality and quality_changes for each ExtruderStack
|
# Set quality and quality_changes for each ExtruderStack
|
||||||
for position, node in quality_group.nodes_for_extruders.items():
|
for position, node in quality_group.nodes_for_extruders.items():
|
||||||
self._global_container_stack.extruders[str(position)].quality = node.container
|
self._global_container_stack.extruderList[position].quality = node.container
|
||||||
if empty_quality_changes:
|
if empty_quality_changes:
|
||||||
self._global_container_stack.extruders[str(position)].qualityChanges = empty_quality_changes_container
|
self._global_container_stack.extruderList[position].qualityChanges = empty_quality_changes_container
|
||||||
|
|
||||||
self.activeQualityGroupChanged.emit()
|
self.activeQualityGroupChanged.emit()
|
||||||
self.activeQualityChangesGroupChanged.emit()
|
self.activeQualityChangesGroupChanged.emit()
|
||||||
@ -1241,6 +1241,7 @@ class MachineManager(QObject):
|
|||||||
if not new_machine:
|
if not new_machine:
|
||||||
new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_sync", machine_definition_id)
|
new_machine = CuraStackBuilder.createMachine(machine_definition_id + "_sync", machine_definition_id)
|
||||||
if not new_machine:
|
if not new_machine:
|
||||||
|
Logger.log("e", "Failed to create new machine when switching configuration.")
|
||||||
return
|
return
|
||||||
|
|
||||||
for metadata_key in self._global_container_stack.getMetaData():
|
for metadata_key in self._global_container_stack.getMetaData():
|
||||||
@ -1256,8 +1257,22 @@ class MachineManager(QObject):
|
|||||||
new_machine.setMetaDataEntry("hidden", False)
|
new_machine.setMetaDataEntry("hidden", False)
|
||||||
self._global_container_stack.setMetaDataEntry("hidden", True)
|
self._global_container_stack.setMetaDataEntry("hidden", True)
|
||||||
|
|
||||||
|
# The new_machine does not contain user changes (global or per-extruder user changes).
|
||||||
|
# Keep a temporary copy of the global and per-extruder user changes and transfer them to the user changes
|
||||||
|
# of the new machine after the new_machine becomes active.
|
||||||
|
global_user_changes = self._global_container_stack.userChanges
|
||||||
|
per_extruder_user_changes = {}
|
||||||
|
for extruder_name, extruder_stack in self._global_container_stack.extruders.items():
|
||||||
|
per_extruder_user_changes[extruder_name] = extruder_stack.userChanges
|
||||||
|
|
||||||
self.setActiveMachine(new_machine.getId())
|
self.setActiveMachine(new_machine.getId())
|
||||||
|
|
||||||
|
# Apply the global and per-extruder userChanges to the new_machine (which is of different type than the
|
||||||
|
# previous one).
|
||||||
|
self._global_container_stack.setUserChanges(global_user_changes)
|
||||||
|
for extruder_name in self._global_container_stack.extruders.keys():
|
||||||
|
self._global_container_stack.extruders[extruder_name].setUserChanges(per_extruder_user_changes[extruder_name])
|
||||||
|
|
||||||
@pyqtSlot(QObject)
|
@pyqtSlot(QObject)
|
||||||
def applyRemoteConfiguration(self, configuration: PrinterConfigurationModel) -> None:
|
def applyRemoteConfiguration(self, configuration: PrinterConfigurationModel) -> None:
|
||||||
if self._global_container_stack is None:
|
if self._global_container_stack is None:
|
||||||
|
@ -7,14 +7,21 @@ from PyQt5.QtWidgets import QSplashScreen
|
|||||||
|
|
||||||
from UM.Resources import Resources
|
from UM.Resources import Resources
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
|
from cura import ApplicationMetadata
|
||||||
|
|
||||||
|
|
||||||
class CuraSplashScreen(QSplashScreen):
|
class CuraSplashScreen(QSplashScreen):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._scale = 0.7
|
self._scale = 0.7
|
||||||
|
self._version_y_offset = 0 # when extra visual elements are in the background image, move version text down
|
||||||
|
|
||||||
|
if ApplicationMetadata.IsEnterpriseVersion:
|
||||||
|
splash_image = QPixmap(Resources.getPath(Resources.Images, "cura_enterprise.png"))
|
||||||
|
self._version_y_offset = 26
|
||||||
|
else:
|
||||||
splash_image = QPixmap(Resources.getPath(Resources.Images, "cura.png"))
|
splash_image = QPixmap(Resources.getPath(Resources.Images, "cura.png"))
|
||||||
|
|
||||||
self.setPixmap(splash_image)
|
self.setPixmap(splash_image)
|
||||||
|
|
||||||
self._current_message = ""
|
self._current_message = ""
|
||||||
@ -52,20 +59,17 @@ class CuraSplashScreen(QSplashScreen):
|
|||||||
painter.setRenderHint(QPainter.Antialiasing, True)
|
painter.setRenderHint(QPainter.Antialiasing, True)
|
||||||
|
|
||||||
version = Application.getInstance().getVersion().split("-")
|
version = Application.getInstance().getVersion().split("-")
|
||||||
buildtype = Application.getInstance().getBuildType()
|
|
||||||
if buildtype:
|
|
||||||
version[0] += " (%s)" % buildtype
|
|
||||||
|
|
||||||
# Draw version text
|
# Draw version text
|
||||||
font = QFont() # Using system-default font here
|
font = QFont() # Using system-default font here
|
||||||
font.setPixelSize(37)
|
font.setPixelSize(18)
|
||||||
painter.setFont(font)
|
painter.setFont(font)
|
||||||
painter.drawText(60, 66, 330 * self._scale, 230 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[0])
|
painter.drawText(60, 70 + self._version_y_offset, 330 * self._scale, 230 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[0])
|
||||||
if len(version) > 1:
|
if len(version) > 1:
|
||||||
font.setPixelSize(16)
|
font.setPixelSize(16)
|
||||||
painter.setFont(font)
|
painter.setFont(font)
|
||||||
painter.setPen(QColor(200, 200, 200, 255))
|
painter.setPen(QColor(200, 200, 200, 255))
|
||||||
painter.drawText(247, 105, 330 * self._scale, 255 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[1])
|
painter.drawText(247, 105 + self._version_y_offset, 330 * self._scale, 255 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[1])
|
||||||
painter.setPen(QColor(255, 255, 255, 255))
|
painter.setPen(QColor(255, 255, 255, 255))
|
||||||
|
|
||||||
# Draw the loading image
|
# Draw the loading image
|
||||||
|
190
plugins/PostProcessingPlugin/scripts/ColorMix.py
Normal file
190
plugins/PostProcessingPlugin/scripts/ColorMix.py
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
# ColorMix script - 2-1 extruder color mix and blending
|
||||||
|
# This script is specific for the Geeetech A10M dual extruder but should work with other Marlin printers.
|
||||||
|
# It runs with the PostProcessingPlugin which is released under the terms of the AGPLv3 or higher.
|
||||||
|
# This script is licensed under the Creative Commons - Attribution - Share Alike (CC BY-SA) terms
|
||||||
|
|
||||||
|
#Authors of the 2-1 ColorMix plug-in / script:
|
||||||
|
# Written by John Hryb - john.hryb.4@gmail.com
|
||||||
|
|
||||||
|
##history / change-log:
|
||||||
|
##V1.0.0
|
||||||
|
|
||||||
|
## Uses -
|
||||||
|
## M163 - Set Mix Factor
|
||||||
|
## M164 - Save Mix - saves to T3 as a unique mix
|
||||||
|
|
||||||
|
import re #To perform the search and replace.
|
||||||
|
from ..Script import Script
|
||||||
|
|
||||||
|
class ColorMix(Script):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def getSettingDataString(self):
|
||||||
|
return """{
|
||||||
|
"name":"ColorMix 2-1",
|
||||||
|
"key":"ColorMix 2-1",
|
||||||
|
"metadata": {},
|
||||||
|
"version": 2,
|
||||||
|
"settings":
|
||||||
|
{
|
||||||
|
"measurement_units":
|
||||||
|
{
|
||||||
|
"label": "Units of measurement",
|
||||||
|
"description": "Input value as mm or layer number.",
|
||||||
|
"type": "enum",
|
||||||
|
"options": {"mm":"mm","layer":"Layer"},
|
||||||
|
"default_value": "layer"
|
||||||
|
},
|
||||||
|
"start_height":
|
||||||
|
{
|
||||||
|
"label": "Start Height",
|
||||||
|
"description": "Value to start at (mm or layer)",
|
||||||
|
"type": "float",
|
||||||
|
"default_value": 0,
|
||||||
|
"minimum_value": "0"
|
||||||
|
},
|
||||||
|
"behavior":
|
||||||
|
{
|
||||||
|
"label": "Fixed or blend",
|
||||||
|
"description": "Select Fixed (set new mixture) or Blend mode (dynamic mix)",
|
||||||
|
"type": "enum",
|
||||||
|
"options": {"fixed_value":"Fixed","blend_value":"Blend"},
|
||||||
|
"default_value": "fixed_value"
|
||||||
|
},
|
||||||
|
"finish_height":
|
||||||
|
{
|
||||||
|
"label": "Finish Height",
|
||||||
|
"description": "Value to stop at (mm or layer)",
|
||||||
|
"type": "float",
|
||||||
|
"default_value": 0,
|
||||||
|
"minimum_value": "0",
|
||||||
|
"minimum_value_warning": "0.1",
|
||||||
|
"enabled": "c_behavior == 'blend_value'"
|
||||||
|
},
|
||||||
|
"mix_start_ratio":
|
||||||
|
{
|
||||||
|
"label": "Start mix ratio",
|
||||||
|
"description": "First extruder percentage 0-100",
|
||||||
|
"type": "float",
|
||||||
|
"default_value": 100,
|
||||||
|
"minimum_value": "0",
|
||||||
|
"minimum_value_warning": "0",
|
||||||
|
"maximum_value_warning": "100"
|
||||||
|
},
|
||||||
|
"mix_finish_ratio":
|
||||||
|
{
|
||||||
|
"label": "End mix ratio",
|
||||||
|
"description": "First extruder percentage 0-100 to finish blend",
|
||||||
|
"type": "float",
|
||||||
|
"default_value": 0,
|
||||||
|
"minimum_value": "0",
|
||||||
|
"minimum_value_warning": "0",
|
||||||
|
"maximum_value_warning": "100",
|
||||||
|
"enabled": "c_behavior == 'blend_value'"
|
||||||
|
},
|
||||||
|
"notes":
|
||||||
|
{
|
||||||
|
"label": "Notes",
|
||||||
|
"description": "A spot to put a note",
|
||||||
|
"type": "str",
|
||||||
|
"default_value": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
def getValue(self, line, key, default = None): #replace default getvalue due to comment-reading feature
|
||||||
|
if not key in line or (";" in line and line.find(key) > line.find(";") and
|
||||||
|
not ";ChangeAtZ" in key and not ";LAYER:" in key):
|
||||||
|
return default
|
||||||
|
subPart = line[line.find(key) + len(key):] #allows for string lengths larger than 1
|
||||||
|
if ";ChangeAtZ" in key:
|
||||||
|
m = re.search("^[0-4]", subPart)
|
||||||
|
elif ";LAYER:" in key:
|
||||||
|
m = re.search("^[+-]?[0-9]*", subPart)
|
||||||
|
else:
|
||||||
|
#the minus at the beginning allows for negative values, e.g. for delta printers
|
||||||
|
m = re.search("^[-]?[0-9]*\.?[0-9]*", subPart)
|
||||||
|
if m == None:
|
||||||
|
return default
|
||||||
|
try:
|
||||||
|
return float(m.group(0))
|
||||||
|
except:
|
||||||
|
return default
|
||||||
|
|
||||||
|
def execute(self, data):
|
||||||
|
#get user variables
|
||||||
|
firstHeight = 0.0
|
||||||
|
secondHeight = 0.0
|
||||||
|
firstMix = 0.0
|
||||||
|
SecondMix = 0.0
|
||||||
|
|
||||||
|
firstHeight = self.getSettingValueByKey("start_height")
|
||||||
|
secondHeight = self.getSettingValueByKey("finish_height")
|
||||||
|
firstMix = self.getSettingValueByKey("mix_start_ratio")
|
||||||
|
SecondMix = self.getSettingValueByKey("mix_finish_ratio")
|
||||||
|
|
||||||
|
#locals
|
||||||
|
layer = 0
|
||||||
|
|
||||||
|
#get layer height
|
||||||
|
layerHeight = .2
|
||||||
|
for active_layer in data:
|
||||||
|
lines = active_layer.split("\n")
|
||||||
|
for line in lines:
|
||||||
|
if ";Layer height: " in line:
|
||||||
|
layerHeight = self.getValue(line, ";Layer height: ", layerHeight)
|
||||||
|
break
|
||||||
|
#get layers to use
|
||||||
|
startLayer = 0
|
||||||
|
endLayer = 0
|
||||||
|
if self.getSettingValueByKey("measurement_units") == "mm":
|
||||||
|
if firstHeight == 0:
|
||||||
|
startLayer = 0
|
||||||
|
else:
|
||||||
|
startLayer = firstHeight / layerHeight
|
||||||
|
if secondHeight == 0:
|
||||||
|
endLayer = 0
|
||||||
|
else:
|
||||||
|
endLayer = secondHeight / layerHeight
|
||||||
|
else: #layer height
|
||||||
|
startLayer = firstHeight
|
||||||
|
endLayer = secondHeight
|
||||||
|
#see if one-shot
|
||||||
|
if self.getSettingValueByKey("behavior") == "fixed_value":
|
||||||
|
endLayer = startLayer
|
||||||
|
firstExtruderIncrements = 0
|
||||||
|
else: #blend
|
||||||
|
firstExtruderIncrements = (SecondMix - firstMix) / (endLayer - startLayer)
|
||||||
|
firstExtruderValue = 0
|
||||||
|
index = 0
|
||||||
|
#start scanning
|
||||||
|
for active_layer in data:
|
||||||
|
modified_gcode = ""
|
||||||
|
lineIndex = 0;
|
||||||
|
lines = active_layer.split("\n")
|
||||||
|
for line in lines:
|
||||||
|
#dont leave blanks
|
||||||
|
if line != "":
|
||||||
|
modified_gcode += line + "\n"
|
||||||
|
# find current layer
|
||||||
|
if ";LAYER:" in line:
|
||||||
|
layer = self.getValue(line, ";LAYER:", layer)
|
||||||
|
if (layer >= startLayer) and (layer <= endLayer): #find layers of interest
|
||||||
|
if lines[lineIndex + 4] == "T2": #check if needing to delete old data
|
||||||
|
del lines[(lineIndex + 1):(lineIndex + 5)]
|
||||||
|
firstExtruderValue = int(((layer - startLayer) * firstExtruderIncrements) + firstMix)
|
||||||
|
if firstExtruderValue == 100:
|
||||||
|
modified_gcode += "M163 S0 P1\n"
|
||||||
|
modified_gcode += "M163 S1 P0\n"
|
||||||
|
elif firstExtruderValue == 0:
|
||||||
|
modified_gcode += "M163 S0 P0\n"
|
||||||
|
modified_gcode += "M163 S1 P1\n"
|
||||||
|
else:
|
||||||
|
modified_gcode += "M163 S0 P0.{:02d}\n".format(firstExtruderValue)
|
||||||
|
modified_gcode += "M163 S1 P0.{:02d}\n".format(100 - firstExtruderValue)
|
||||||
|
modified_gcode += "M164 S2\n"
|
||||||
|
modified_gcode += "T2\n"
|
||||||
|
lineIndex += 1 #for deleting index
|
||||||
|
data[index] = modified_gcode
|
||||||
|
index += 1
|
||||||
|
return data
|
@ -125,11 +125,11 @@ class ZeroConfClient:
|
|||||||
if not info.address:
|
if not info.address:
|
||||||
info = zero_conf.get_service_info(service_type, name)
|
info = zero_conf.get_service_info(service_type, name)
|
||||||
|
|
||||||
if info:
|
if info and info.address:
|
||||||
type_of_device = info.properties.get(b"type", None)
|
type_of_device = info.properties.get(b"type", None)
|
||||||
if type_of_device:
|
if type_of_device:
|
||||||
if type_of_device == b"printer":
|
if type_of_device == b"printer":
|
||||||
address = '.'.join(map(lambda n: str(n), info.address))
|
address = '.'.join(map(str, info.address))
|
||||||
self.addedNetworkCluster.emit(str(name), address, info.properties)
|
self.addedNetworkCluster.emit(str(name), address, info.properties)
|
||||||
else:
|
else:
|
||||||
Logger.log("w", "The type of the found device is '%s', not 'printer'." % type_of_device)
|
Logger.log("w", "The type of the found device is '%s', not 'printer'." % type_of_device)
|
||||||
|
BIN
resources/images/cura_enterprise.png
Normal file
BIN
resources/images/cura_enterprise.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
@ -12,7 +12,7 @@ UM.Dialog
|
|||||||
id: base
|
id: base
|
||||||
|
|
||||||
//: About dialog title
|
//: About dialog title
|
||||||
title: catalog.i18nc("@title:window","About Cura")
|
title: catalog.i18nc("@title:window","About " + catalog.i18nc("@title:window", CuraApplication.applicationDisplayName))
|
||||||
|
|
||||||
minimumWidth: 500 * screenScaleFactor
|
minimumWidth: 500 * screenScaleFactor
|
||||||
minimumHeight: 650 * screenScaleFactor
|
minimumHeight: 650 * screenScaleFactor
|
||||||
|
Loading…
x
Reference in New Issue
Block a user