Fix conflict

This commit is contained in:
ChrisTerBeke 2017-12-21 17:09:28 +01:00
commit 2caa8d216a
15 changed files with 221 additions and 184 deletions

36
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,36 @@
<!--
The following template is useful for filing new issues. Processing an issue will go much faster when this is filled out.
Before filing, please check if the issue already exists (either open or closed).
It is also helpful to attach a project (.3MF) file and Cura log file so we can debug issues quicker.
Information about how to find the log file can be found at https://github.com/Ultimaker/Cura/wiki/Cura-Preferences-and-Settings-Locations.
Thank you for using Cura!
-->
**Application Version**
<!-- The version of the application this issue occurs with -->
**Platform**
<!-- Information about the platform the issue occurs on -->
**Qt**
<!-- The version of Qt used (not necessary if you're using the version from Ultimaker's website) -->
**PyQt**
<!-- The version of PyQt used (not necessary if you're using the version from Ultimaker's website) -->
**Display Driver**
<!-- Video driver name and version -->
**Steps to Reproduce**
<!-- Add the steps needed that lead up to the issue (replace this text) -->
**Actual Results**
<!-- What happens after the above steps have been followed (replace this text) -->
**Expected results**
<!-- What should happen after the above steps have been followed (replace this text) -->
**Additional Information**
<!-- Extra information relevant to the issue, like screenshots (replace this text) -->

26
.gitignore vendored
View File

@ -33,21 +33,23 @@ cura.desktop
.settings
#Externally located plug-ins.
plugins/CuraSolidWorksPlugin
plugins/Doodle3D-cura-plugin
plugins/GodMode
plugins/PostProcessingPlugin
plugins/X3GWriter
plugins/FlatProfileExporter
plugins/ProfileFlattener
plugins/cura-god-mode-plugin
plugins/cura-big-flame-graph
plugins/cura-god-mode-plugin
plugins/cura-siemensnx-plugin
plugins/CuraVariSlicePlugin
plugins/CuraLiveScriptingPlugin
plugins/CuraPrintProfileCreator
plugins/OctoPrintPlugin
plugins/CuraBlenderPlugin
plugins/CuraCloudPlugin
plugins/CuraLiveScriptingPlugin
plugins/CuraOpenSCADPlugin
plugins/CuraPrintProfileCreator
plugins/CuraSolidWorksPlugin
plugins/CuraVariSlicePlugin
plugins/Doodle3D-cura-plugin
plugins/FlatProfileExporter
plugins/GodMode
plugins/OctoPrintPlugin
plugins/PostProcessingPlugin
plugins/ProfileFlattener
plugins/X3GWriter
#Build stuff
CMakeCache.txt

View File

@ -1,22 +1,16 @@
Cura
====
This is the new, shiny frontend for Cura. [daid/Cura](https://github.com/daid/Cura.git) is the old legacy Cura that everyone knows and loves/hates.
We re-worked the whole GUI code at Ultimaker, because the old code started to become unmaintainable.
This is the new, shiny frontend for Cura. Check [daid/LegacyCura](https://github.com/daid/LegacyCura) for the legacy Cura that everyone knows and loves/hates. We re-worked the whole GUI code at Ultimaker, because the old code started to become unmaintainable.
Logging Issues
------------
Use [this](https://github.com/Ultimaker/Uranium/wiki/Bug-Reporting-Template) template to report issues. New issues that do not adhere to this template will take us a lot longer to handle and will therefore have a lower pirority.
For crashes and similar issues, please attach the following information:
* (On Windows) The log as produced by dxdiag (start -> run -> dxdiag -> save output)
* The Cura GUI log file, located at
* %APPDATA%\cura\\`<Cura version>`\cura.log (Windows), or usually C:\Users\\`<your username>`\AppData\Roaming\cura\\`<Cura version>`\cura.log
* $User/Library/Application Support/cura/`<Cura version>`/cura.log (OSX)
* $USER/.local/share/cura/`<Cura version>`/cura.log (Ubuntu/Linux)
* `%APPDATA%\cura\<Cura version>\cura.log` (Windows), or usually `C:\Users\\<your username>\AppData\Roaming\cura\<Cura version>\cura.log`
* `$USER/Library/Application Support/cura/<Cura version>/cura.log` (OSX)
* `$USER/.local/share/cura/<Cura version>/cura.log` (Ubuntu/Linux)
If the Cura user interface still starts, you can also reach this directory from the application menu in Help -> Show settings folder
@ -24,53 +18,26 @@ For additional support, you could also ask in the #cura channel on FreeNode IRC.
Dependencies
------------
* [Uranium](https://github.com/Ultimaker/Uranium)
Cura is built on top of the Uranium framework.
* [CuraEngine](https://github.com/Ultimaker/CuraEngine)
This will be needed at runtime to perform the actual slicing.
* [PySerial](https://github.com/pyserial/pyserial)
Only required for USB printing support.
* [python-zeroconf](https://github.com/jstasiak/python-zeroconf)
Only required to detect mDNS-enabled printers
Configuring Cura
----------------
Link your CuraEngine backend by inserting the following lines in `$HOME/.config/cura/config.cfg` :
```
[backend]
location = /[path_to_the..]/CuraEngine/build/CuraEngine
```
* [Uranium](https://github.com/Ultimaker/Uranium) Cura is built on top of the Uranium framework.
* [CuraEngine](https://github.com/Ultimaker/CuraEngine) This will be needed at runtime to perform the actual slicing.
* [PySerial](https://github.com/pyserial/pyserial) Only required for USB printing support.
* [python-zeroconf](https://github.com/jstasiak/python-zeroconf) Only required to detect mDNS-enabled printers
Build scripts
-------------
Please checkout [cura-build](https://github.com/Ultimaker/cura-build) for detailed building instructions.
Please checkout [cura-build](https://github.com/Ultimaker/cura-build)
Third party plugins
Plugins
-------------
* [Post Processing Plugin](https://github.com/nallath/PostProcessingPlugin): Allows for post-processing scripts to run on g-code.
* [Barbarian Plugin](https://github.com/nallath/BarbarianPlugin): Simple scale tool for imperial to metric.
* [X3G Writer](https://github.com/Ghostkeeper/X3GWriter): Adds support for exporting X3G files.
* [Auto orientation](https://github.com/nallath/CuraOrientationPlugin): Calculate the optimal orientation for a model.
* [OctoPrint Plugin](https://github.com/fieldofview/OctoPrintPlugin): Send printjobs directly to OctoPrint and monitor their progress in Cura.
* [Electric Print Cost Calculator Plugin](https://github.com/zoff99/ElectricPrintCostCalculator): Calculate the electric costs of a print.
Please check our [Wiki page](https://github.com/Ultimaker/Cura/wiki/Plugin-Directory) for details about creating and using plugins.
Making profiles for other printers
----------------------------------
If your make of printer is not in the list of supported printers, and using the "Custom FDM Printer" does not offer enough flexibility, you can use [this](https://github.com/Ultimaker/Cura/blob/master/resources/definitions/ultimaker_original.def.json) as a template.
Supported printers
-------------
Please check our [Wiki page](https://github.com/Ultimaker/Cura/wiki/Adding-new-machine-profiles-to-Cura) for guidelines about adding support for new machines.
* Change the machine ID to something unique
* Change the machine_name to your printer's name
* If you have a 3D model of your platform you can put it in resources/meshes and put its name under platform
* Set your machine's dimensions with machine_width, machine_depth, and machine_height
* If your printer's origin is in the center of the bed, set machine_center_is_zero to true.
* Set your print head dimensions with the machine_head_shape parameters
* Set the start and end gcode in machine_start_gcode and machine_end_gcode
Once you are done, put the profile you have made into resources/definitions, or in definitions in your cura profile folder.
If you want to make a definition for a multi-extrusion printer, have a look at [this](https://github.com/Ultimaker/Cura/blob/master/resources/definitions/ultimaker_original_dual.def.json) as a template, along with the two extruder definitions it references [here](https://github.com/Ultimaker/Cura/blob/master/resources/extruders/ultimaker_original_dual_1st.def.json) and [here](https://github.com/Ultimaker/Cura/blob/master/resources/extruders/ultimaker_original_dual_2nd.def.json)
Configuring Cura
----------------
Please check out [Wiki page](https://github.com/Ultimaker/Cura/wiki/Cura-Settings) about configuration options for developers.
Translating Cura
----------------
@ -93,3 +60,7 @@ To submit your translation, ideally you would make two pull requests where all `
After the translation is submitted, the Cura maintainers will check for its completeness and check whether it is consistent. We will take special care to look for common mistakes, such as translating mark-up `<message>` code and such. We are often not fluent in every language, so we expect the translator and the international users to make corrections where necessary. Of course, there will always be some mistakes in every translation.
When the next Cura release comes around, some of the texts will have changed and some new texts will have been added. Around the time when the beta is released we will invoke a string freeze, meaning that no developer is allowed to make changes to the texts. Then we will update the translation template `.pot` files and ask all our translators to update their translations. If you are unable to update the translation in time for the actual release, we will remove the language from the drop-down menu in the Preferences window. The translation stays in Cura however, so that someone might pick it up again later and update it with the newest texts. Also, users who had previously selected the language can still continue Cura in their language but English text will appear among the original text.
License
----------------
Cura is released under the terms of the LGPLv3 or higher. A copy of this license should be included with the software.

View File

@ -514,7 +514,7 @@ class ContainerManager(QObject):
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
# Find the quality_changes container for this stack and merge the contents of the top container into it.
quality_changes = stack.qualityChanges
if not quality_changes or quality_changes.isReadOnly():
if not quality_changes or self._container_registry.isReadOnly(quality_changes.getId()):
Logger.log("e", "Could not update quality of a nonexistant or read only quality profile in stack %s", stack.getId())
continue
@ -687,7 +687,7 @@ class ContainerManager(QObject):
global_stack = Application.getInstance().getGlobalContainerStack()
if not global_stack or not quality_name:
return ""
machine_definition = global_stack.getBottom()
machine_definition = global_stack.definition
active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
if active_stacks is None:

View File

@ -218,25 +218,6 @@ class CuraContainerRegistry(ContainerRegistry):
if type(profile_or_list) is not list:
profile_or_list = [profile_or_list]
if len(profile_or_list) == 1:
# If there is only 1 stack file it means we're loading a legacy (pre-3.1) .curaprofile.
# In that case we find the per-extruder settings and put those in a new quality_changes container
# so that it is compatible with the new stack setup.
profile = profile_or_list[0]
extruder_stack_quality_changes_container = ContainerManager.getInstance().duplicateContainerInstance(profile)
extruder_stack_quality_changes_container.addMetaDataEntry("extruder", "fdmextruder")
for quality_changes_setting_key in extruder_stack_quality_changes_container.getAllKeys():
settable_per_extruder = extruder_stack_quality_changes_container.getProperty(quality_changes_setting_key, "settable_per_extruder")
if settable_per_extruder:
profile.removeInstance(quality_changes_setting_key, postpone_emit = True)
else:
extruder_stack_quality_changes_container.removeInstance(quality_changes_setting_key, postpone_emit = True)
# We add the new container to the profile list so things like extruder positions are taken care of
# in the next code segment.
profile_or_list.append(extruder_stack_quality_changes_container)
# Import all profiles
for profile_index, profile in enumerate(profile_or_list):
if profile_index == 0:
@ -252,6 +233,9 @@ class CuraContainerRegistry(ContainerRegistry):
profile.setMetaDataEntry("extruder", extruder_id)
profile_id = (extruder_id + "_" + name_seed).lower().replace(" ", "_")
else: #More extruders in the imported file than in the machine.
continue #Delete the additional profiles.
result = self._configureProfile(profile, profile_id, new_name)
if result is not None:
return {"status": "error", "message": catalog.i18nc(
@ -305,7 +289,7 @@ class CuraContainerRegistry(ContainerRegistry):
quality_type_criteria["definition"] = profile.getDefinition().getId()
else:
profile.setDefinition(fdmprinter)
profile.setDefinition("fdmprinter")
quality_type_criteria["definition"] = "fdmprinter"
machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
@ -422,6 +406,10 @@ class CuraContainerRegistry(ContainerRegistry):
if not isinstance(container, ContainerStack) or container.getMetaDataEntry("type") != "machine":
return
machine_extruder_trains = container.getMetaDataEntry("machine_extruder_trains")
if machine_extruder_trains is not None and machine_extruder_trains != {"0": "fdmextruder"}:
return
extruder_stacks = self.findContainerStacks(type = "extruder_train", machine = container.getId())
if not extruder_stacks:
self.addExtruderStackForSingleExtrusionMachine(container, "fdmextruder")

View File

@ -739,7 +739,7 @@ class MachineManager(QObject):
## Set the active material by switching out a container
# Depending on from/to material+current variant, a quality profile is chosen and set.
@pyqtSlot(str)
def setActiveMaterial(self, material_id: str):
def setActiveMaterial(self, material_id: str, always_discard_changes = False):
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
containers = ContainerRegistry.getInstance().findInstanceContainers(id = material_id)
if not containers or not self._active_container_stack:
@ -821,10 +821,10 @@ class MachineManager(QObject):
if not old_quality_changes:
new_quality_id = candidate_quality.getId()
self.setActiveQuality(new_quality_id)
self.setActiveQuality(new_quality_id, always_discard_changes = always_discard_changes)
@pyqtSlot(str)
def setActiveVariant(self, variant_id: str):
def setActiveVariant(self, variant_id: str, always_discard_changes = False):
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_id)
if not containers or not self._active_container_stack:
@ -840,14 +840,14 @@ class MachineManager(QObject):
if old_material:
preferred_material_name = old_material.getName()
preferred_material_id = self._updateMaterialContainer(self._global_container_stack.definition, self._global_container_stack, containers[0], preferred_material_name).id
self.setActiveMaterial(preferred_material_id)
self.setActiveMaterial(preferred_material_id, always_discard_changes = always_discard_changes)
else:
Logger.log("w", "While trying to set the active variant, no variant was found to replace.")
## set the active quality
# \param quality_id The quality_id of either a quality or a quality_changes
@pyqtSlot(str)
def setActiveQuality(self, quality_id: str):
def setActiveQuality(self, quality_id: str, always_discard_changes = False):
with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
self.blurSettings.emit()
@ -909,7 +909,7 @@ class MachineManager(QObject):
# the dialog will be the those before the switching.
self._executeDelayedActiveContainerStackChanges()
if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1 and not always_discard_changes:
Application.getInstance().discardOrKeepProfileChanges()
## Used to update material and variant in the active container stack with a delay.

View File

@ -32,14 +32,16 @@ class SettingOverrideDecorator(SceneNodeDecorator):
def __init__(self):
super().__init__()
self._stack = PerObjectContainerStack(stack_id = id(self))
self._stack = PerObjectContainerStack(stack_id = "per_object_stack_" + str(id(self)))
self._stack.setDirty(False) # This stack does not need to be saved.
self._stack.addContainer(InstanceContainer(container_id = "SettingOverrideInstanceContainer"))
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
self._is_non_printing_mesh = False
self._stack.propertyChanged.connect(self._onSettingChanged)
ContainerRegistry.getInstance().addContainer(self._stack)
Application.getInstance().getContainerRegistry().addContainer(self._stack)
Application.getInstance().globalContainerStackChanged.connect(self._updateNextStack)
self.activeExtruderChanged.connect(self._updateNextStack)
@ -57,6 +59,10 @@ class SettingOverrideDecorator(SceneNodeDecorator):
# Properly set the right extruder on the copy
deep_copy.setActiveExtruder(self._extruder_stack)
# use value from the stack because there can be a delay in signal triggering and "_is_non_printing_mesh"
# has not been updated yet.
deep_copy._is_non_printing_mesh = any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings)
return deep_copy
## Gets the currently active extruder to print this object with.
@ -80,14 +86,17 @@ class SettingOverrideDecorator(SceneNodeDecorator):
container_stack = containers[0]
return container_stack.getMetaDataEntry("position", default=None)
def isNonPrintingMesh(self):
return self._is_non_printing_mesh
def _onSettingChanged(self, instance, property_name): # Reminder: 'property' is a built-in function
# Trigger slice/need slicing if the value has changed.
if property_name == "value":
self._is_non_printing_mesh = any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings)
Application.getInstance().getBackend().needsSlicing()
Application.getInstance().getBackend().tickle()
self._node._non_printing_mesh = any(self._stack.getProperty(setting, "value") for setting in self._non_printing_mesh_settings)
## Makes sure that the stack upon which the container stack is placed is
# kept up to date.
def _updateNextStack(self):

View File

@ -461,7 +461,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
global_stack_id_new = self.getNewId(global_stack_id_original)
global_stack_need_rename = True
global_stack_name_new = self._container_registry.uniqueName(global_stack_name_original)
if self._container_registry.findContainerStacksMetadata(name = global_stack_id_original):
global_stack_name_new = self._container_registry.uniqueName(global_stack_name_original)
for each_extruder_stack_file in extruder_stack_files:
old_container_id = self._stripFileToId(each_extruder_stack_file)
@ -583,7 +584,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if machine_id:
new_machine_id = self.getNewId(machine_id)
new_id = new_machine_id + "_current_settings"
instance_container.setMetadataEntry("id", new_id)
instance_container.setMetaDataEntry("id", new_id)
instance_container.setName(new_id)
instance_container.setMetaDataEntry("machine", new_machine_id)
containers_to_add.append(instance_container)
@ -681,12 +682,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
file_name = global_stack_file)
# Ensure a unique ID and name
stack._id = global_stack_id_new
# Extruder stacks are "bound" to a machine. If we add the machine as a new one, the id of the
# bound machine also needs to change.
if stack.getMetaDataEntry("machine", None):
stack.setMetaDataEntry("machine", global_stack_id_new)
stack.setMetaDataEntry("id", global_stack_id_new)
# Only machines need a new name, stacks may be non-unique
stack.setName(global_stack_name_new)
@ -740,7 +736,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
stack.deserialize(extruder_file_content, file_name = extruder_stack_file)
# Ensure a unique ID and name
stack._id = new_id
stack.setMetaDataEntry("id", new_id)
self._container_registry.addContainer(stack)
extruder_stacks_added.append(stack)

View File

@ -19,6 +19,10 @@ from UM.Settings.SettingRelation import RelationType
from cura.OneAtATimeIterator import OneAtATimeIterator
from cura.Settings.ExtruderManager import ExtruderManager
NON_PRINTING_MESH_SETTINGS = ["anti_overhang_mesh", "infill_mesh", "cutting_mesh"]
class StartJobResult(IntEnum):
Finished = 1
Error = 2
@ -133,11 +137,15 @@ class StartSliceJob(Job):
temp_list = []
has_printing_mesh = False
for node in DepthFirstIterator(self._scene.getRoot()):
if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
_non_printing_mesh = getattr(node, "_non_printing_mesh", False)
if not getattr(node, "_outside_buildarea", False) or _non_printing_mesh:
if node.callDecoration("isSliceable") and type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
per_object_stack = node.callDecoration("getStack")
is_non_printing_mesh = False
if per_object_stack:
is_non_printing_mesh = any(per_object_stack.getProperty(key, "value") for key in NON_PRINTING_MESH_SETTINGS)
if not getattr(node, "_outside_buildarea", False) or not is_non_printing_mesh:
temp_list.append(node)
if not _non_printing_mesh:
if not is_non_printing_mesh:
has_printing_mesh = True
Job.yieldThread()

View File

@ -1,4 +1,4 @@
# Copyright (c) 2015 Ultimaker B.V.
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import configparser # For reading the legacy profile INI files.
@ -10,8 +10,10 @@ import os.path # For concatenating the path to the plugin and the relative path
from UM.Application import Application # To get the machine manager to create the new profile in.
from UM.Logger import Logger # Logging errors.
from UM.PluginRegistry import PluginRegistry # For getting the path to this plugin's directory.
from UM.Settings.ContainerRegistry import ContainerRegistry #To create unique profile IDs.
from UM.Settings.InstanceContainer import InstanceContainer # The new profile to make.
from cura.ProfileReader import ProfileReader # The plug-in type to implement.
from cura.Settings.ExtruderManager import ExtruderManager #To get the current extruder definition.
## A plugin that reads profile data from legacy Cura versions.
@ -77,7 +79,9 @@ class LegacyProfileReader(ProfileReader):
raise Exception("Unable to import legacy profile. Multi extrusion is not supported")
Logger.log("i", "Importing legacy profile from file " + file_name + ".")
profile = InstanceContainer("Imported Legacy Profile") # Create an empty profile.
container_registry = ContainerRegistry.getInstance()
profile_id = container_registry.uniqueName("Imported Legacy Profile")
profile = InstanceContainer(profile_id) # Create an empty profile.
parser = configparser.ConfigParser(interpolation = None)
try:
@ -120,7 +124,7 @@ class LegacyProfileReader(ProfileReader):
if "translation" not in dict_of_doom:
Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?")
return None
current_printer_definition = global_container_stack.getBottom()
current_printer_definition = global_container_stack.definition
profile.setDefinition(current_printer_definition.getId())
for new_setting in dict_of_doom["translation"]: # Evaluate all new settings that would get a value from the translations.
old_setting_expression = dict_of_doom["translation"][new_setting]
@ -139,14 +143,13 @@ class LegacyProfileReader(ProfileReader):
if len(profile.getAllKeys()) == 0:
Logger.log("i", "A legacy profile was imported but everything evaluates to the defaults, creating an empty profile.")
# We need to downgrade the container to version 1 (in Cura 2.1) so the upgrade system can correctly upgrade
# it to the latest version.
profile.addMetaDataEntry("type", "profile")
# don't know what quality_type it is based on, so use "normal" by default
profile.addMetaDataEntry("quality_type", "normal")
profile.setName(profile_id)
profile.setDirty(True)
#Serialise and deserialise in order to perform the version upgrade.
parser = configparser.ConfigParser(interpolation=None)
data = profile.serialize()
parser.read_string(data)
@ -159,4 +162,20 @@ class LegacyProfileReader(ProfileReader):
data = stream.getvalue()
profile.deserialize(data)
return profile
#We need to return one extruder stack and one global stack.
global_container_id = container_registry.uniqueName("Global Imported Legacy Profile")
global_profile = profile.duplicate(new_id = global_container_id, new_name = profile_id) #Needs to have the same name as the extruder profile.
global_profile.setDirty(True)
#Only the extruder stack has an extruder metadata entry.
profile.addMetaDataEntry("extruder", ExtruderManager.getInstance().getActiveExtruderStack().definition.getId())
#Split all settings into per-extruder and global settings.
for setting_key in profile.getAllKeys():
settable_per_extruder = global_container_stack.getProperty(setting_key, "settable_per_extruder")
if settable_per_extruder:
global_profile.removeInstance(setting_key)
else:
profile.removeInstance(setting_key)
return [global_profile, profile]

View File

@ -270,6 +270,20 @@ Cura.MachineAction
}
}
}
Connections
{
target: manager
onDefinedExtruderCountChanged:
{
extruderCountModel.clear();
for(var i = 0; i < manager.definedExtruderCount; ++i)
{
extruderCountModel.append({text: String(i + 1), value: i});
}
}
}
currentIndex: machineExtruderCountProvider.properties.value - 1
onActivated:
{
@ -432,7 +446,7 @@ Cura.MachineAction
property int areaHeight: parent.height - y
property string settingKey: "machine_extruder_start_code"
property bool isExtruderSetting: true
}
}
}
Column {
height: parent.height
@ -714,7 +728,7 @@ Cura.MachineAction
width: gcodeArea.width
text: _tooltip
property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false: isExtruderSetting
property bool _isExtruderSetting: (typeof(isExtruderSetting) === 'undefined') ? false : isExtruderSetting
property string _tooltip: (typeof(tooltip) === 'undefined') ? propertyProvider.properties.description : tooltip
UM.SettingPropertyProvider
@ -726,7 +740,7 @@ Cura.MachineAction
{
if(settingsTabs.currentIndex > 0)
{
return Cura.MachineManager.activeStackId;
return Cura.ExtruderManager.extruderIds[String(settingsTabs.currentIndex - 1)];
}
return "";
}

View File

@ -110,7 +110,7 @@ class SolidView(View):
except ValueError:
pass
if getattr(node, "_non_printing_mesh", False):
if node.callDecoration("isNonPrintingMesh"):
if per_mesh_stack and (per_mesh_stack.getProperty("infill_mesh", "value") or per_mesh_stack.getProperty("cutting_mesh", "value")):
renderer.queueNode(node, shader = self._non_printing_shader, uniforms = uniforms, transparent = True)
else:

View File

@ -234,7 +234,7 @@ class NetworkClusterPrinterOutputDevice(NetworkPrinterOutputDevice.NetworkPrinte
def spawnPrintView(self):
if self._print_view is None:
path = os.path.join(self._plugin_path, "PrintWindow.qml")
self._print_view = Application.getInstance().createQmlComponent(path, {"OutputDevice", self})
self._print_view = Application.getInstance().createQmlComponent(path, {"OutputDevice": self})
if self._print_view is not None:
self._print_view.show()

View File

@ -129,12 +129,17 @@ class VersionUpgrade30to31(VersionUpgrade):
if parser.has_option("values", "machine_nozzle_size"):
machine_nozzle_size = parser["values"]["machine_nozzle_size"]
definition_name = parser["general"]["name"]
machine_extruders = self._getSingleExtrusionMachineExtruders(definition_name)
machine_extruder_count = '1' # by default it is 1 and the value cannot be stored in the global stack
if parser.has_option("values", "machine_extruder_count"):
machine_extruder_count = parser["values"]["machine_extruder_count"]
#For single extuder machine we nee only first extruder
if len(machine_extruders) !=0:
if self._updateSingleExtuderDefinitionFile(machine_extruders, machine_nozzle_size):
if machine_extruder_count == '1':
definition_name = parser["general"]["name"]
machine_extruders = self._getSingleExtrusionMachineExtruders(definition_name)
# For single extruder machine we need only first extruder
if len(machine_extruders) !=0:
self._updateSingleExtruderDefinitionFile(machine_extruders, machine_nozzle_size)
parser.remove_option("values", "machine_nozzle_size")
# Update version numbers
@ -219,9 +224,9 @@ class VersionUpgrade30to31(VersionUpgrade):
machine_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.MachineStack)
machine_instances = []
machine_instance_id = None
#Find all machine instances
# Find machine instances
for item in os.listdir(machine_instances_dir):
file_path = os.path.join(machine_instances_dir, item)
if not os.path.isfile(file_path):
@ -242,57 +247,51 @@ class VersionUpgrade30to31(VersionUpgrade):
if not parser.has_option("general", "id"):
continue
machine_instances.append(parser)
#Find for extruders
extruders_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.ExtruderStack)
#"machine",[extruders]
extruder_instances_per_machine = {}
#Find all custom extruders for founded machines
for item in os.listdir(extruders_instances_dir):
file_path = os.path.join(extruders_instances_dir, item)
if not os.path.isfile(file_path):
id = parser["general"]["id"]
if id + "_settings" != definition_name:
continue
parser = configparser.ConfigParser(interpolation=None)
try:
parser.read([file_path])
except:
# skip, it is not a valid stack file
continue
if not parser.has_option("metadata", "type"):
continue
if "extruder_train" != parser["metadata"]["type"]:
continue
if not parser.has_option("metadata", "machine"):
continue
if not parser.has_option("metadata", "position"):
continue
for machine_instace in machine_instances:
machine_id = machine_instace["general"]["id"]
if machine_id != parser["metadata"]["machine"]:
continue
if machine_id + "_settings" != definition_name:
continue
if extruder_instances_per_machine.get(machine_id) is None:
extruder_instances_per_machine.update({machine_id:[]})
extruder_instances_per_machine.get(machine_id).append(parser)
#the extruder can be related only to one machine
else:
machine_instance_id = id
break
return extruder_instances_per_machine
if machine_instance_id is not None:
#Find extruder defition at index 0 and update its values
def _updateSingleExtuderDefinitionFile(self, extruder_instances_per_machine, machine_nozzle_size):
extruders_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.ExtruderStack)
#"machine",[extruders]
extruder_instances = []
# Find all custom extruders for found machines
for item in os.listdir(extruders_instances_dir):
file_path = os.path.join(extruders_instances_dir, item)
if not os.path.isfile(file_path):
continue
parser = configparser.ConfigParser(interpolation=None)
try:
parser.read([file_path])
except:
# skip, it is not a valid stack file
continue
if not parser.has_option("metadata", "type"):
continue
if "extruder_train" != parser["metadata"]["type"]:
continue
if not parser.has_option("metadata", "machine"):
continue
if not parser.has_option("metadata", "position"):
continue
if machine_instance_id != parser["metadata"]["machine"]:
continue
extruder_instances.append(parser)
return extruder_instances
# Find extruder definition at index 0 and update its values
def _updateSingleExtruderDefinitionFile(self, extruder_instances_per_machine, machine_nozzle_size):
defintion_instances_dir = Resources.getPath(CuraApplication.ResourceTypes.DefinitionChangesContainer)
@ -312,19 +311,15 @@ class VersionUpgrade30to31(VersionUpgrade):
continue
name = parser["general"]["name"]
custom_extruder_at_0_position = None
for machine_extruders in extruder_instances_per_machine:
for extruder_instance in extruder_instances_per_machine[machine_extruders]:
for extruder_instance in extruder_instances_per_machine:
if extruder_instance["general"]["id"] + "_settings" == name:
defition_position = extruder_instance["metadata"]["position"]
definition_position = extruder_instance["metadata"]["position"]
if defition_position == "0":
custom_extruder_at_0_position = extruder_instance
break
if custom_extruder_at_0_position is not None:
if definition_position == "0":
custom_extruder_at_0_position = extruder_instance
break
#If not null, then parsed file is for first extuder and then can be updated. I need to update only
# If not null, then parsed file is for first extuder and then can be updated. I need to update only
# first, because this update for single extuder machine
if custom_extruder_at_0_position is not None:
@ -374,4 +369,4 @@ class VersionUpgrade30to31(VersionUpgrade):
quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer)
with open(os.path.join(quality_changes_dir, extruder_quality_changes_filename), "w") as f:
f.write(extruder_quality_changes_output.getvalue())
f.write(extruder_quality_changes_output.getvalue())

View File

@ -737,7 +737,6 @@ class XmlMaterialProfile(InstanceContainer):
Logger.log("w", "No definition found for machine ID %s", machine_id)
continue
Logger.log("d", "Found def for machine [%s]", machine_id)
definition_metadata = definition_metadata[0]
machine_manufacturer = identifier.get("manufacturer", definition_metadata.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition.