mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-21 21:58:01 -06:00
Merge branch 'master' of github.com:Ultimaker/Cura into rework_file_handler
This commit is contained in:
commit
aca8110edd
19 changed files with 112 additions and 36 deletions
|
@ -27,7 +27,7 @@ import UM.Settings.ContainerRegistry
|
|||
|
||||
|
||||
# Setting for clearance around the prime
|
||||
PRIME_CLEARANCE = 1.5
|
||||
PRIME_CLEARANCE = 6.5
|
||||
|
||||
|
||||
## Build volume is a special kind of node that is responsible for rendering the printable area & disallowed areas.
|
||||
|
@ -701,6 +701,8 @@ class BuildVolume(SceneNode):
|
|||
bed_adhesion_size += value
|
||||
elif adhesion_type == "raft":
|
||||
bed_adhesion_size = self._getSettingFromAdhesionExtruder("raft_margin")
|
||||
elif adhesion_type == "none":
|
||||
bed_adhesion_size = 0
|
||||
else:
|
||||
raise Exception("Unknown bed adhesion type. Did you forget to update the build volume calculations for your new bed adhesion type?")
|
||||
|
||||
|
|
|
@ -236,6 +236,8 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
|||
extra_margin = max(0, self._getSettingProperty("raft_margin", "value"))
|
||||
elif adhesion_type == "brim":
|
||||
extra_margin = max(0, self._getSettingProperty("brim_line_count", "value") * self._getSettingProperty("skirt_brim_line_width", "value"))
|
||||
elif adhesion_type == "none":
|
||||
extra_margin = 0
|
||||
elif adhesion_type == "skirt":
|
||||
extra_margin = max(
|
||||
0, self._getSettingProperty("skirt_gap", "value") +
|
||||
|
|
|
@ -581,6 +581,8 @@ class CuraApplication(QtApplication):
|
|||
else:
|
||||
if self._previous_active_tool:
|
||||
self.getController().setActiveTool(self._previous_active_tool)
|
||||
if not self.getController().getActiveTool().getEnabled():
|
||||
self.getController().setActiveTool("TranslateTool")
|
||||
self._previous_active_tool = None
|
||||
else:
|
||||
# Default
|
||||
|
@ -777,7 +779,11 @@ class CuraApplication(QtApplication):
|
|||
for node in nodes:
|
||||
# Ensure that the object is above the build platform
|
||||
node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator)
|
||||
op.addOperation(SetTransformOperation(node, Vector(0, node.getWorldPosition().y - node.getBoundingBox().bottom, 0)))
|
||||
if node.getBoundingBox():
|
||||
center_y = node.getWorldPosition().y - node.getBoundingBox().bottom
|
||||
else:
|
||||
center_y = 0
|
||||
op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0)))
|
||||
op.push()
|
||||
|
||||
## Reset all transformations on nodes with mesh data.
|
||||
|
@ -799,11 +805,10 @@ class CuraApplication(QtApplication):
|
|||
for node in nodes:
|
||||
# Ensure that the object is above the build platform
|
||||
node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator)
|
||||
center_y = 0
|
||||
if node.callDecoration("isGroup"):
|
||||
if node.getBoundingBox():
|
||||
center_y = node.getWorldPosition().y - node.getBoundingBox().bottom
|
||||
else:
|
||||
center_y = node.getMeshData().getCenterPosition().y
|
||||
center_y = 0
|
||||
op.addOperation(SetTransformOperation(node, Vector(0, center_y, 0), Quaternion(), Vector(1, 1, 1)))
|
||||
op.push()
|
||||
|
||||
|
|
|
@ -210,7 +210,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
return {"status": "ok", "message": catalog.i18nc("@info:status", "Successfully imported profile {0}", profile_or_list[0].getName())}
|
||||
|
||||
# If it hasn't returned by now, none of the plugins loaded the profile successfully.
|
||||
return {"status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type.", file_name)}
|
||||
return {"status": "error", "message": catalog.i18nc("@info:status", "Profile {0} has an unknown file type or is corrupted.", file_name)}
|
||||
|
||||
def _configureProfile(self, profile, id_seed, new_name):
|
||||
profile.setReadOnly(False)
|
||||
|
|
|
@ -348,8 +348,8 @@ class ExtruderManager(QObject):
|
|||
if support_interface_enabled:
|
||||
used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_interface_extruder_nr", "value"))])
|
||||
|
||||
#The platform adhesion extruder. Not used if using brim and brim width is 0.
|
||||
if global_stack.getProperty("adhesion_type", "value") != "brim" or global_stack.getProperty("brim_line_count", "value") > 0:
|
||||
#The platform adhesion extruder. Not used if using none.
|
||||
if global_stack.getProperty("adhesion_type", "value") != "none":
|
||||
used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("adhesion_extruder_nr", "value"))])
|
||||
|
||||
return [container_registry.findContainerStacks(id = stack_id)[0] for stack_id in used_extruder_stack_ids]
|
||||
|
|
|
@ -220,6 +220,9 @@ class CuraEngineBackend(Backend):
|
|||
#
|
||||
# \param job The start slice job that was just finished.
|
||||
def _onStartSliceCompleted(self, job):
|
||||
if self._error_message:
|
||||
self._error_message.hide()
|
||||
|
||||
# Note that cancelled slice jobs can still call this method.
|
||||
if self._start_slice_job is job:
|
||||
self._start_slice_job = None
|
||||
|
@ -243,9 +246,8 @@ class CuraEngineBackend(Backend):
|
|||
error_keys = []
|
||||
for extruder in extruders:
|
||||
error_keys.extend(extruder.getErrorKeys())
|
||||
else:
|
||||
if not extruders:
|
||||
error_keys = self._global_container_stack.getErrorKeys()
|
||||
|
||||
error_labels = set()
|
||||
definition_container = self._global_container_stack.getBottom()
|
||||
for key in error_keys:
|
||||
|
@ -259,6 +261,14 @@ class CuraEngineBackend(Backend):
|
|||
self.backendStateChange.emit(BackendState.NotStarted)
|
||||
return
|
||||
|
||||
if job.getResult() == StartSliceJob.StartJobResult.BuildPlateError:
|
||||
if Application.getInstance().getPlatformActivity:
|
||||
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice because the prime tower or prime position(s) are invalid."))
|
||||
self._error_message.show()
|
||||
self.backendStateChange.emit(BackendState.Error)
|
||||
else:
|
||||
self.backendStateChange.emit(BackendState.NotStarted)
|
||||
|
||||
if job.getResult() == StartSliceJob.StartJobResult.NothingToSlice:
|
||||
if Application.getInstance().getPlatformActivity:
|
||||
self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."))
|
||||
|
|
|
@ -25,6 +25,7 @@ class StartJobResult(IntEnum):
|
|||
SettingError = 3
|
||||
NothingToSlice = 4
|
||||
MaterialIncompatible = 5
|
||||
BuildPlateError = 6
|
||||
|
||||
|
||||
## Formatter class that handles token expansion in start/end gcod
|
||||
|
@ -80,7 +81,7 @@ class StartSliceJob(Job):
|
|||
return
|
||||
|
||||
if Application.getInstance().getBuildVolume().hasErrors():
|
||||
self.setResult(StartJobResult.SettingError)
|
||||
self.setResult(StartJobResult.BuildPlateError)
|
||||
return
|
||||
|
||||
for extruder_stack in cura.Settings.ExtruderManager.getInstance().getMachineExtruders(stack.getId()):
|
||||
|
|
|
@ -99,4 +99,6 @@ class CuraProfileReader(ProfileReader):
|
|||
return []
|
||||
|
||||
filenames, outputs = profile_convert_funcs[0](serialized, profile_id)
|
||||
if filenames is None and outputs is None:
|
||||
return []
|
||||
return list(zip(outputs, filenames))
|
||||
|
|
|
@ -70,10 +70,19 @@ class GCodeProfileReader(ProfileReader):
|
|||
|
||||
json_data = json.loads(serialized)
|
||||
|
||||
profile_strings = [json_data["global_quality"]]
|
||||
profile_strings.extend(json_data.get("extruder_quality", []))
|
||||
profiles = []
|
||||
global_profile = readQualityProfileFromString(json_data["global_quality"])
|
||||
|
||||
return [readQualityProfileFromString(profile_string) for profile_string in profile_strings]
|
||||
# This is a fix for profiles created with 2.3.0 For some reason it added the "extruder" property to the
|
||||
# global profile.
|
||||
# The fix is simple and safe, as a global profile should never have the extruder entry.
|
||||
if global_profile.getMetaDataEntry("extruder", None) is not None:
|
||||
global_profile.setMetaDataEntry("extruder", None)
|
||||
profiles.append(global_profile)
|
||||
|
||||
for profile_string in json_data.get("extruder_quality", []):
|
||||
profiles.append(readQualityProfileFromString(profile_string))
|
||||
return profiles
|
||||
|
||||
## Unescape a string which has been escaped for use in a gcode comment.
|
||||
#
|
||||
|
|
|
@ -5,6 +5,7 @@ import configparser #To read config files.
|
|||
import io #To write config files to strings as if they were files.
|
||||
|
||||
import UM.VersionUpgrade
|
||||
from UM.Logger import Logger
|
||||
|
||||
## Creates a new profile instance by parsing a serialised profile in version 1
|
||||
# of the file format.
|
||||
|
|
|
@ -165,7 +165,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
machine_container_map = {}
|
||||
machine_nozzle_map = {}
|
||||
|
||||
all_containers = registry.findInstanceContainers(GUID = self.getMetaDataEntry("GUID"))
|
||||
all_containers = registry.findInstanceContainers(GUID = self.getMetaDataEntry("GUID"), base_file = self._id)
|
||||
for container in all_containers:
|
||||
definition_id = container.getDefinition().id
|
||||
if definition_id == "fdmprinter":
|
||||
|
@ -209,7 +209,17 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
|
|||
if not variant_containers:
|
||||
continue
|
||||
|
||||
builder.start("hotend", { "id": variant_containers[0].getName() })
|
||||
builder.start("hotend", {"id": variant_containers[0].getName()})
|
||||
|
||||
# Compatible is a special case, as it's added as a meta data entry (instead of an instance).
|
||||
compatible = hotend.getMetaDataEntry("compatible")
|
||||
if compatible is not None:
|
||||
builder.start("setting", {"key": "hardware compatible"})
|
||||
if compatible:
|
||||
builder.data("yes")
|
||||
else:
|
||||
builder.data("no")
|
||||
builder.end("setting")
|
||||
|
||||
for instance in hotend.findInstances():
|
||||
if container.getInstance(instance.definition.key) and container.getProperty(instance.definition.key, "value") == instance.value:
|
||||
|
|
|
@ -169,7 +169,7 @@
|
|||
},
|
||||
"machine_extruder_count":
|
||||
{
|
||||
"label": "Number extruders",
|
||||
"label": "Number of Extruders",
|
||||
"description": "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle.",
|
||||
"default_value": 1,
|
||||
"minimum_value": "1",
|
||||
|
@ -921,6 +921,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"fill_perimeter_gaps": {
|
||||
"label": "Fill Gaps Between Walls",
|
||||
"description": "Fills the gaps between walls where no walls fit.",
|
||||
"type": "enum",
|
||||
"options": {
|
||||
"nowhere": "Nowhere",
|
||||
"everywhere": "Everywhere"
|
||||
},
|
||||
"default_value": "everywhere",
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"xy_offset":
|
||||
{
|
||||
"label": "Horizontal Expansion",
|
||||
|
@ -2393,6 +2404,20 @@
|
|||
"settable_per_extruder": true,
|
||||
"children":
|
||||
{
|
||||
"cool_fan_speed_0":
|
||||
{
|
||||
"label": "Initial Fan Speed",
|
||||
"description": "The speed at which the fans spin at the start of the print. In subsequent layers the fan speed is gradually increased up to the layer corresponding to Regular Fan Speed at Height.",
|
||||
"unit": "%",
|
||||
"type": "float",
|
||||
"minimum_value": "0",
|
||||
"maximum_value": "100",
|
||||
"value": "cool_fan_speed",
|
||||
"default_value": 100,
|
||||
"enabled": "cool_fan_enabled",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"cool_fan_speed_min":
|
||||
{
|
||||
"label": "Regular Fan Speed",
|
||||
|
@ -2438,7 +2463,7 @@
|
|||
"cool_fan_full_at_height":
|
||||
{
|
||||
"label": "Regular Fan Speed at Height",
|
||||
"description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from zero to regular fan speed.",
|
||||
"description": "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from Initial Fan Speed to Regular Fan Speed.",
|
||||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 0.5,
|
||||
|
@ -2871,7 +2896,7 @@
|
|||
"type": "float",
|
||||
"default_value": 0.4,
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "support_interface_line_width",
|
||||
"minimum_value_warning": "support_interface_line_width - 0.0001",
|
||||
"value": "0 if support_interface_density == 0 else (support_interface_line_width * 100) / support_interface_density * (2 if support_interface_pattern == 'grid' else (3 if support_interface_pattern == 'triangles' else 1))",
|
||||
"limit_to_extruder": "support_interface_extruder_nr",
|
||||
"enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
|
||||
|
@ -2997,7 +3022,8 @@
|
|||
{
|
||||
"skirt": "Skirt",
|
||||
"brim": "Brim",
|
||||
"raft": "Raft"
|
||||
"raft": "Raft",
|
||||
"none": "None"
|
||||
},
|
||||
"default_value": "brim",
|
||||
"resolve": "'raft' if 'raft' in extruderValues('adhesion_type') else ('brim' if 'brim' in extruderValues('adhesion_type') else 'skirt')",
|
||||
|
@ -3010,7 +3036,7 @@
|
|||
"description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.",
|
||||
"type": "extruder",
|
||||
"default_value": "0",
|
||||
"enabled": "machine_extruder_count > 1",
|
||||
"enabled": "machine_extruder_count > 1 and resolveOrValue('adhesion_type') != 'none'",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false
|
||||
},
|
||||
|
@ -3747,6 +3773,17 @@
|
|||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": true
|
||||
},
|
||||
"alternate_carve_order":
|
||||
{
|
||||
"label": "Alternate Mesh Removal",
|
||||
"description": "With every layer switch from which model intersecting volumes are removed, so that the overlapping volumes become interwoven.",
|
||||
"type": "bool",
|
||||
"default_value": true,
|
||||
"enabled": "carve_multiple_volumes",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -3769,6 +3806,7 @@
|
|||
"one_at_a_time": "One at a Time"
|
||||
},
|
||||
"default_value": "all_at_once",
|
||||
"enabled": "machine_extruder_count == 1",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": false
|
||||
|
|
|
@ -71,8 +71,6 @@
|
|||
"prime_tower_position_x": { "default_value": 175 },
|
||||
"prime_tower_position_y": { "default_value": 179 },
|
||||
|
||||
"print_sequence": {"enabled": false},
|
||||
|
||||
"acceleration_enabled": { "value": "True" },
|
||||
"acceleration_layer_0": { "value": "acceleration_topbottom" },
|
||||
"acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 2000 / 4000)" },
|
||||
|
@ -101,8 +99,8 @@
|
|||
"jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" },
|
||||
"jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" },
|
||||
"layer_height_0": { "value": "round(machine_nozzle_size / 1.5, 2)" },
|
||||
"layer_start_x": { "value": "sum(extruderValues('extruder_prime_pos_x')) / len(extruderValues('extruder_prime_pos_x'))" },
|
||||
"layer_start_y": { "value": "sum(extruderValues('extruder_prime_pos_y')) / len(extruderValues('extruder_prime_pos_y'))" },
|
||||
"layer_start_x": { "value": "sum(extruderValues('machine_extruder_start_pos_x')) / len(extruderValues('machine_extruder_start_pos_x'))" },
|
||||
"layer_start_y": { "value": "sum(extruderValues('machine_extruder_start_pos_y')) / len(extruderValues('machine_extruder_start_pos_y'))" },
|
||||
"line_width": { "value": "machine_nozzle_size * 0.875" },
|
||||
"machine_min_cool_heat_time_window": { "value": "15" },
|
||||
"material_print_temperature": { "value": "200" },
|
||||
|
|
|
@ -72,9 +72,6 @@
|
|||
"machine_extruder_count": {
|
||||
"default_value": 2
|
||||
},
|
||||
"print_sequence": {
|
||||
"enabled": false
|
||||
},
|
||||
"prime_tower_position_x": {
|
||||
"default_value": 185
|
||||
},
|
||||
|
|
|
@ -19,7 +19,7 @@ UM.Dialog
|
|||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
|
||||
property int objectId: 0;
|
||||
property var objectId: 0;
|
||||
onAccepted: Printer.multiplyObject(base.objectId, parseInt(copiesField.text))
|
||||
|
||||
property variant catalog: UM.I18nCatalog { name: "cura" }
|
||||
|
|
|
@ -29,11 +29,11 @@ SettingItem
|
|||
// 4: variant
|
||||
// 5: machine
|
||||
var value;
|
||||
if ((propertyProvider.properties.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
if ((base.resolve != "None") && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
// (if user has explicitly set this).
|
||||
value = propertyProvider.properties.resolve;
|
||||
value = base.resolve;
|
||||
} else {
|
||||
value = propertyProvider.properties.value;
|
||||
}
|
||||
|
|
|
@ -96,11 +96,11 @@ SettingItem
|
|||
{
|
||||
// FIXME this needs to go away once 'resolve' is combined with 'value' in our data model.
|
||||
var value;
|
||||
if ((propertyProvider.properties.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) {
|
||||
if ((base.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) {
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
// (if user has explicitly set this).
|
||||
value = propertyProvider.properties.resolve;
|
||||
value = base.resolve;
|
||||
} else {
|
||||
value = propertyProvider.properties.value;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,8 @@ Item {
|
|||
|
||||
// Create properties to put property provider stuff in (bindings break in qt 5.5.1 otherwise)
|
||||
property var state: propertyProvider.properties.state
|
||||
property var resolve: propertyProvider.properties.resolve
|
||||
// There is no resolve property if there is only one stack.
|
||||
property var resolve: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId ? propertyProvider.properties.resolve : "None"
|
||||
property var stackLevels: propertyProvider.stackLevels
|
||||
property var stackLevel: stackLevels[0]
|
||||
|
||||
|
|
|
@ -114,11 +114,11 @@ SettingItem
|
|||
// 3: material -> user changed material in materialspage
|
||||
// 4: variant
|
||||
// 5: machine
|
||||
if ((propertyProvider.properties.resolve != "None" && propertyProvider.properties.resolve) && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
if ((base.resolve != "None" && base.resolve) && (stackLevel != 0) && (stackLevel != 1)) {
|
||||
// We have a resolve function. Indicates that the setting is not settable per extruder and that
|
||||
// we have to choose between the resolved value (default) and the global value
|
||||
// (if user has explicitly set this).
|
||||
return propertyProvider.properties.resolve;
|
||||
return base.resolve;
|
||||
} else {
|
||||
return propertyProvider.properties.value;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue