mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-05 21:13:58 -06:00
Merge branch 'master' of github.com:Ultimaker/Cura
This commit is contained in:
commit
fc0417bd45
14 changed files with 236 additions and 130 deletions
|
@ -150,11 +150,11 @@ class QualityManager:
|
|||
|
||||
return [quality_type_dict[quality_type] for quality_type in quality_types]
|
||||
|
||||
## Fetch a more basic version of a material.
|
||||
## Fetch more basic versions of a material.
|
||||
#
|
||||
# This tries to find a generic or basic version of the given material.
|
||||
# \param material_container \type{InstanceContainer} the material
|
||||
# \return \type{List[InstanceContainer]} the basic material or None if one could not be found.
|
||||
# \return \type{List[InstanceContainer]} a list of the basic materials or an empty list if one could not be found.
|
||||
def _getBasicMaterials(self, material_container):
|
||||
base_material = material_container.getMetaDataEntry("material")
|
||||
if material_container.getDefinition().getMetaDataEntry("has_machine_quality"):
|
||||
|
|
|
@ -84,11 +84,26 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
if result == QMessageBox.No:
|
||||
return
|
||||
found_containers = []
|
||||
extruder_positions = []
|
||||
for instance_id in instance_ids:
|
||||
containers = ContainerRegistry.getInstance().findInstanceContainers(id=instance_id)
|
||||
if containers:
|
||||
found_containers.append(containers[0])
|
||||
|
||||
# Determine the position of the extruder of this container
|
||||
extruder_id = containers[0].getMetaDataEntry("extruder", "")
|
||||
if extruder_id == "":
|
||||
# Global stack
|
||||
extruder_positions.append(-1)
|
||||
else:
|
||||
extruder_containers = ContainerRegistry.getInstance().findDefinitionContainers(id=extruder_id)
|
||||
if extruder_containers:
|
||||
extruder_positions.append(int(extruder_containers[0].getMetaDataEntry("position", 0)))
|
||||
else:
|
||||
extruder_positions.append(0)
|
||||
# Ensure the profiles are always exported in order (global, extruder 0, extruder 1, ...)
|
||||
found_containers = [containers for (positions, containers) in sorted(zip(extruder_positions, found_containers))]
|
||||
|
||||
profile_writer = self._findProfileWriter(extension, description)
|
||||
|
||||
try:
|
||||
|
|
|
@ -205,7 +205,7 @@ class ExtruderManager(QObject):
|
|||
if preferred_material_id:
|
||||
search_criteria = { "type": "material", "id": preferred_material_id}
|
||||
if machine_definition.getMetaDataEntry("has_machine_materials"):
|
||||
search_criteria["definition"] = machine_definition.id
|
||||
search_criteria["definition"] = machine_definition_id
|
||||
|
||||
if machine_definition.getMetaDataEntry("has_variants") and variant:
|
||||
search_criteria["variant"] = variant.id
|
||||
|
|
|
@ -72,6 +72,9 @@ class MachineManager(QObject):
|
|||
self._auto_materials_changed = {}
|
||||
self._auto_hotends_changed = {}
|
||||
|
||||
self._material_incompatible_message = Message(catalog.i18nc("@info:status",
|
||||
"The selected material is imcompatible with the selected machine or configuration."))
|
||||
|
||||
globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value)
|
||||
activeMaterialChanged = pyqtSignal()
|
||||
activeVariantChanged = pyqtSignal()
|
||||
|
@ -549,9 +552,9 @@ class MachineManager(QObject):
|
|||
material_container.nameChanged.connect(self._onMaterialNameChanged)
|
||||
|
||||
if material_container.getMetaDataEntry("compatible") == False:
|
||||
message = Message(catalog.i18nc("@info:status",
|
||||
"The selected material is imcompatible with the selected machine or configuration."))
|
||||
message.show()
|
||||
self._material_incompatible_message.show()
|
||||
else:
|
||||
self._material_incompatible_message.hide()
|
||||
|
||||
new_quality_id = old_quality.getId()
|
||||
quality_type = old_quality.getMetaDataEntry("quality_type")
|
||||
|
@ -829,8 +832,8 @@ class MachineManager(QObject):
|
|||
# \sa getQualityVariantId
|
||||
@pyqtProperty(str, notify = activeVariantChanged)
|
||||
def activeQualityVariantId(self):
|
||||
if self._global_container_stack:
|
||||
variant = self._global_container_stack.findContainer({"type": "variant"})
|
||||
if self._active_container_stack:
|
||||
variant = self._active_container_stack.findContainer({"type": "variant"})
|
||||
if variant:
|
||||
return self.getQualityVariantId(self._global_container_stack.getBottom(), variant)
|
||||
return ""
|
||||
|
|
|
@ -8,9 +8,11 @@ from UM.Math.Matrix import Matrix
|
|||
from UM.Math.Vector import Vector
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
from UM.Scene.GroupDecorator import GroupDecorator
|
||||
from UM.Math.Quaternion import Quaternion
|
||||
import UM.Application
|
||||
from UM.Job import Job
|
||||
|
||||
from UM.Math.Quaternion import Quaternion
|
||||
|
||||
import math
|
||||
import zipfile
|
||||
|
||||
|
@ -24,113 +26,129 @@ class ThreeMFReader(MeshReader):
|
|||
def __init__(self):
|
||||
super().__init__()
|
||||
self._supported_extensions = [".3mf"]
|
||||
|
||||
self._root = None
|
||||
self._namespaces = {
|
||||
"3mf": "http://schemas.microsoft.com/3dmanufacturing/core/2015/02",
|
||||
"cura": "http://software.ultimaker.com/xml/cura/3mf/2015/10"
|
||||
}
|
||||
|
||||
def _createNodeFromObject(self, object, name = ""):
|
||||
node = SceneNode()
|
||||
mesh_builder = MeshBuilder()
|
||||
vertex_list = []
|
||||
|
||||
components = object.find(".//3mf:components", self._namespaces)
|
||||
if components:
|
||||
for component in components:
|
||||
id = component.get("objectid")
|
||||
new_object = self._root.find("./3mf:resources/3mf:object[@id='{0}']".format(id), self._namespaces)
|
||||
|
||||
new_node = self._createNodeFromObject(new_object)
|
||||
node.addChild(new_node)
|
||||
transform = component.get("transform")
|
||||
if transform is not None:
|
||||
new_node.setTransformation(self._createMatrixFromTransformationString(transform))
|
||||
|
||||
# for vertex in entry.mesh.vertices.vertex:
|
||||
for vertex in object.findall(".//3mf:vertex", self._namespaces):
|
||||
vertex_list.append([vertex.get("x"), vertex.get("y"), vertex.get("z")])
|
||||
Job.yieldThread()
|
||||
|
||||
# If this object has no vertices and just one child, just return the child.
|
||||
if len(vertex_list) == 0 and len(node.getChildren()) == 1:
|
||||
return node.getChildren()[0]
|
||||
|
||||
if len(node.getChildren()) > 0:
|
||||
group_decorator = GroupDecorator()
|
||||
node.addDecorator(group_decorator)
|
||||
|
||||
triangles = object.findall(".//3mf:triangle", self._namespaces)
|
||||
mesh_builder.reserveFaceCount(len(triangles))
|
||||
|
||||
for triangle in triangles:
|
||||
v1 = int(triangle.get("v1"))
|
||||
v2 = int(triangle.get("v2"))
|
||||
v3 = int(triangle.get("v3"))
|
||||
|
||||
mesh_builder.addFaceByPoints(vertex_list[v1][0], vertex_list[v1][1], vertex_list[v1][2],
|
||||
vertex_list[v2][0], vertex_list[v2][1], vertex_list[v2][2],
|
||||
vertex_list[v3][0], vertex_list[v3][1], vertex_list[v3][2])
|
||||
|
||||
Job.yieldThread()
|
||||
|
||||
# Rotate the model; We use a different coordinate frame.
|
||||
rotation = Matrix()
|
||||
rotation.setByRotationAxis(-0.5 * math.pi, Vector(1, 0, 0))
|
||||
flip_matrix = Matrix()
|
||||
|
||||
flip_matrix._data[1, 1] = 0
|
||||
flip_matrix._data[1, 2] = 1
|
||||
flip_matrix._data[2, 1] = 1
|
||||
flip_matrix._data[2, 2] = 0
|
||||
|
||||
# TODO: We currently do not check for normals and simply recalculate them.
|
||||
mesh_builder.calculateNormals()
|
||||
mesh_builder.setFileName(name)
|
||||
mesh_data = mesh_builder.build().getTransformed(flip_matrix)
|
||||
|
||||
if len(mesh_data.getVertices()):
|
||||
node.setMeshData(mesh_data)
|
||||
|
||||
node.setSelectable(True)
|
||||
return node
|
||||
|
||||
def _createMatrixFromTransformationString(self, transformation):
|
||||
splitted_transformation = transformation.split()
|
||||
## Transformation is saved as:
|
||||
## M00 M01 M02 0.0
|
||||
## M10 M11 M12 0.0
|
||||
## M20 M21 M22 0.0
|
||||
## M30 M31 M32 1.0
|
||||
## We switch the row & cols as that is how everyone else uses matrices!
|
||||
temp_mat = Matrix()
|
||||
# Rotation & Scale
|
||||
temp_mat._data[0, 0] = splitted_transformation[0]
|
||||
temp_mat._data[1, 0] = splitted_transformation[1]
|
||||
temp_mat._data[2, 0] = splitted_transformation[2]
|
||||
temp_mat._data[0, 1] = splitted_transformation[3]
|
||||
temp_mat._data[1, 1] = splitted_transformation[4]
|
||||
temp_mat._data[2, 1] = splitted_transformation[5]
|
||||
temp_mat._data[0, 2] = splitted_transformation[6]
|
||||
temp_mat._data[1, 2] = splitted_transformation[7]
|
||||
temp_mat._data[2, 2] = splitted_transformation[8]
|
||||
|
||||
# Translation
|
||||
temp_mat._data[0, 3] = splitted_transformation[9]
|
||||
temp_mat._data[1, 3] = splitted_transformation[10]
|
||||
temp_mat._data[2, 3] = splitted_transformation[11]
|
||||
|
||||
flip_matrix = Matrix()
|
||||
flip_matrix._data[1, 1] = 0
|
||||
flip_matrix._data[1, 2] = 1
|
||||
flip_matrix._data[2, 1] = 1
|
||||
flip_matrix._data[2, 2] = 0
|
||||
temp_mat.multiply(flip_matrix)
|
||||
|
||||
return temp_mat
|
||||
|
||||
def read(self, file_name):
|
||||
result = SceneNode()
|
||||
# The base object of 3mf is a zipped archive.
|
||||
archive = zipfile.ZipFile(file_name, "r")
|
||||
try:
|
||||
root = ET.parse(archive.open("3D/3dmodel.model"))
|
||||
self._root = ET.parse(archive.open("3D/3dmodel.model"))
|
||||
|
||||
# There can be multiple objects, try to load all of them.
|
||||
objects = root.findall("./3mf:resources/3mf:object", self._namespaces)
|
||||
if len(objects) == 0:
|
||||
Logger.log("w", "No objects found in 3MF file %s, either the file is corrupt or you are using an outdated format", file_name)
|
||||
return None
|
||||
build_items = self._root.findall("./3mf:build/3mf:item", self._namespaces)
|
||||
|
||||
for entry in objects:
|
||||
mesh_builder = MeshBuilder()
|
||||
node = SceneNode()
|
||||
vertex_list = []
|
||||
for build_item in build_items:
|
||||
id = build_item.get("objectid")
|
||||
object = self._root.find("./3mf:resources/3mf:object[@id='{0}']".format(id), self._namespaces)
|
||||
build_item_node = self._createNodeFromObject(object)
|
||||
transform = build_item.get("transform")
|
||||
if transform is not None:
|
||||
build_item_node.setTransformation(self._createMatrixFromTransformationString(transform))
|
||||
result.addChild(build_item_node)
|
||||
|
||||
# for vertex in entry.mesh.vertices.vertex:
|
||||
for vertex in entry.findall(".//3mf:vertex", self._namespaces):
|
||||
vertex_list.append([vertex.get("x"), vertex.get("y"), vertex.get("z")])
|
||||
Job.yieldThread()
|
||||
|
||||
triangles = entry.findall(".//3mf:triangle", self._namespaces)
|
||||
mesh_builder.reserveFaceCount(len(triangles))
|
||||
|
||||
for triangle in triangles:
|
||||
v1 = int(triangle.get("v1"))
|
||||
v2 = int(triangle.get("v2"))
|
||||
v3 = int(triangle.get("v3"))
|
||||
|
||||
mesh_builder.addFaceByPoints(vertex_list[v1][0], vertex_list[v1][1], vertex_list[v1][2],
|
||||
vertex_list[v2][0], vertex_list[v2][1], vertex_list[v2][2],
|
||||
vertex_list[v3][0], vertex_list[v3][1], vertex_list[v3][2])
|
||||
|
||||
Job.yieldThread()
|
||||
|
||||
# Rotate the model; We use a different coordinate frame.
|
||||
rotation = Matrix()
|
||||
rotation.setByRotationAxis(-0.5 * math.pi, Vector(1, 0, 0))
|
||||
|
||||
# TODO: We currently do not check for normals and simply recalculate them.
|
||||
mesh_builder.calculateNormals()
|
||||
mesh_builder.setFileName(file_name)
|
||||
mesh_data = mesh_builder.build().getTransformed(rotation)
|
||||
|
||||
if not len(mesh_data.getVertices()):
|
||||
Logger.log("d", "One of the objects does not have vertices. Skipping it.")
|
||||
continue # This object doesn't have data, so skip it.
|
||||
|
||||
node.setMeshData(mesh_data)
|
||||
node.setSelectable(True)
|
||||
|
||||
transformations = root.findall("./3mf:build/3mf:item[@objectid='{0}']".format(entry.get("id")), self._namespaces)
|
||||
transformation = transformations[0] if transformations else None
|
||||
if transformation is not None and transformation.get("transform"):
|
||||
splitted_transformation = transformation.get("transform").split()
|
||||
## Transformation is saved as:
|
||||
## M00 M01 M02 0.0
|
||||
## M10 M11 M12 0.0
|
||||
## M20 M21 M22 0.0
|
||||
## M30 M31 M32 1.0
|
||||
## We switch the row & cols as that is how everyone else uses matrices!
|
||||
temp_mat = Matrix()
|
||||
# Rotation & Scale
|
||||
temp_mat._data[0,0] = splitted_transformation[0]
|
||||
temp_mat._data[1,0] = splitted_transformation[1]
|
||||
temp_mat._data[2,0] = splitted_transformation[2]
|
||||
temp_mat._data[0,1] = splitted_transformation[3]
|
||||
temp_mat._data[1,1] = splitted_transformation[4]
|
||||
temp_mat._data[2,1] = splitted_transformation[5]
|
||||
temp_mat._data[0,2] = splitted_transformation[6]
|
||||
temp_mat._data[1,2] = splitted_transformation[7]
|
||||
temp_mat._data[2,2] = splitted_transformation[8]
|
||||
|
||||
# Translation
|
||||
temp_mat._data[0,3] = splitted_transformation[9]
|
||||
temp_mat._data[1,3] = splitted_transformation[10]
|
||||
temp_mat._data[2,3] = splitted_transformation[11]
|
||||
|
||||
node.setTransformation(temp_mat)
|
||||
|
||||
try:
|
||||
node.getBoundingBox() # Selftest - There might be more functions that should fail
|
||||
except:
|
||||
Logger.log("w", "Bounding box test for object failed. Skipping this object")
|
||||
continue
|
||||
|
||||
result.addChild(node)
|
||||
|
||||
Job.yieldThread()
|
||||
|
||||
# If there is more then one object, group them.
|
||||
if len(objects) > 1:
|
||||
group_decorator = GroupDecorator()
|
||||
result.addDecorator(group_decorator)
|
||||
elif len(objects) == 1:
|
||||
if result.getChildren():
|
||||
result = result.getChildren()[0] # Only one object found, return that.
|
||||
else: # we failed to load any data
|
||||
return None
|
||||
except Exception as e:
|
||||
Logger.log("e", "exception occured in 3mf reader: %s", e)
|
||||
try: # Selftest - There might be more functions that should fail
|
||||
|
@ -139,4 +157,10 @@ class ThreeMFReader(MeshReader):
|
|||
except:
|
||||
return None
|
||||
|
||||
global_container_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||
|
||||
if global_container_stack:
|
||||
translation = Vector(x=-global_container_stack.getProperty("machine_width", "value") / 2, y=0,
|
||||
z=global_container_stack.getProperty("machine_depth", "value") / 2)
|
||||
result.translate(translation, SceneNode.TransformSpace.World)
|
||||
return result
|
||||
|
|
|
@ -20,10 +20,10 @@ Select an individual item in a group or merged object and edit as usual. Just Ct
|
|||
Profile management is improved. You can now easily see and track changes made to your profiles.
|
||||
|
||||
*Improved Setting Visibility
|
||||
Make multiple settings visible at once. The Visibility Overview setting indicates why a setting is not shown in the sidebar even if it is selected.
|
||||
Make multiple settings visible at once. The Visibility Overview setting indicates why a setting is not shown in the sidebar even if it is enabled.
|
||||
|
||||
*Improved time estimation
|
||||
Time estimations are more accurate. Based on our test time estimations should be within 5% accuracy.
|
||||
Time estimations are more accurate. Based on our test time estimations should be within 5% accuracy for Ultimaker printers.
|
||||
|
||||
*Optional G-code Machine Prefix
|
||||
Disable the g-code prefix in Preferences. No more UM2_ on your printer display!
|
||||
|
@ -36,10 +36,10 @@ Configurations from older installations of Cura 2.1 are automatically imported i
|
|||
|
||||
*Slicing features
|
||||
*Infill Improvements
|
||||
We've introduced two new infill types: Tetrahedral and Cubic. They change along with the Z-axis for more uniform strength in all directions. Also, now you can change the density of the infill based on the distance from the top layers. You print get faster, use less material, and maintain the same object strength.
|
||||
We've introduced two new infill types: Tetrahedral and Cubic. They change along with the Z-axis for more uniform strength in all directions. Also, now you can change the density of the infill based on the distance from the top layers. Your objects print faster, use less material, and maintain the same strength.
|
||||
|
||||
*Set Acceleration and Jerk by Feature
|
||||
You can now set Jerk and Acceleration by feature, (infill, walls, top/bottom, etc) for more precision.
|
||||
You can now set Jerk and Acceleration by feature-type (infill, walls, top/bottom, etc), for more precision.
|
||||
|
||||
*Outer Wall Offset
|
||||
Apply an offset to where the outer wall is printed for better surface quality when the outer wall line width is smaller than the nozzle size.
|
||||
|
@ -56,8 +56,8 @@ The Skin Overlap setting allows you to overlap the skin lines with the walls for
|
|||
*Control Initial Layer Travel Speed
|
||||
Set the travel speed of the initial layer(s) to reduce risk of extruder pulling the print from the bed.
|
||||
|
||||
*Support Bottoms
|
||||
This new feature duplicates the Support Roofs feature in the places where the support rests on the model.
|
||||
*Support Interface
|
||||
It is now possible to print a support bottom as well as a support roof. Support bottoms are placed where the support rests on the model.
|
||||
|
||||
*Bug fixes & minor changes
|
||||
Deleting grouped objects works as intended again.
|
||||
|
@ -81,7 +81,7 @@ Brim is now always printed just once.
|
|||
Overlap Compensation works as intended again.
|
||||
A raft now produces a reasonable amount of retractions.
|
||||
No more string plume on top of one-at-a-time printed objects.
|
||||
Engine log can be viewed even when slicing is finished.
|
||||
Engine log is now included in the application log.
|
||||
Support roofs now only occur just below overhang.
|
||||
Brim is now also generated under the support.
|
||||
Compensate overlapping wall parts now also works for inner walls.
|
||||
|
@ -89,9 +89,10 @@ Bed Level and Checkup procedures for UMO+ can now be done without re-adding mach
|
|||
Undo and Redo now work correctly with multiple operations.
|
||||
The last used folder is now remembered (instead of defaulting to home folder)
|
||||
You can now adjust the speed at which the bed is lowered each layer.
|
||||
Support roofs now only generate directly below the mesh.
|
||||
Settings shared between skirt and brim now also activate when brim is selected.
|
||||
Made it possible to add multiple Per Model Settings at once.
|
||||
Support doesn't remove brim around the object any more.
|
||||
Draft shield and Ooze shield get their own brim or raft.
|
||||
|
||||
[2.1.3]
|
||||
|
||||
|
|
|
@ -3715,7 +3715,7 @@
|
|||
"type": "float",
|
||||
"default_value": 0.064,
|
||||
"minimum_value": "0",
|
||||
"maximum_value_warning": "2.0",
|
||||
"maximum_value_warning": "machine_nozzle_size * 5",
|
||||
"enabled": "coasting_enable",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
|
|
|
@ -9,7 +9,7 @@ Generic Nylon profile. Serves as an example file, data in this file is not corre
|
|||
<material>Nylon</material>
|
||||
<color>Generic</color>
|
||||
</name>
|
||||
<GUID>35ebb8df-66d2-41cd-9662-b7d96b9c2cbd</GUID>
|
||||
<GUID>28fb4162-db74-49e1-9008-d05f1e8bef5c</GUID>
|
||||
<version>1</version>
|
||||
<color_code>#3DF266</color_code>
|
||||
</metadata>
|
||||
|
|
25
resources/materials/ultimaker_nylon_black.xml.fdm_material
Normal file
25
resources/materials/ultimaker_nylon_black.xml.fdm_material
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Generic Nylon profile. Serves as an example file, data in this file is not correct.
|
||||
-->
|
||||
<fdmmaterial xmlns="http://www.ultimaker.com/material">
|
||||
<metadata>
|
||||
<name>
|
||||
<brand>Ultimaker</brand>
|
||||
<material>Nylon</material>
|
||||
<color>Black</color>
|
||||
</name>
|
||||
<GUID>c64c2dbe-5691-4363-a7d9-66b2dc12837f</GUID>
|
||||
<version>1</version>
|
||||
<color_code>#000000</color_code>
|
||||
</metadata>
|
||||
<properties>
|
||||
<density>1.14</density>
|
||||
<diameter>2.85</diameter>
|
||||
</properties>
|
||||
<settings>
|
||||
<setting key="print temperature">250</setting>
|
||||
<setting key="heated bed temperature">60</setting>
|
||||
<setting key="standby temperature">100</setting>
|
||||
</settings>
|
||||
</fdmmaterial>
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Generic Nylon profile. Serves as an example file, data in this file is not correct.
|
||||
-->
|
||||
<fdmmaterial xmlns="http://www.ultimaker.com/material">
|
||||
<metadata>
|
||||
<name>
|
||||
<brand>Ultimaker</brand>
|
||||
<material>Nylon</material>
|
||||
<color>Transparent</color>
|
||||
</name>
|
||||
<GUID>e256615d-a04e-4f53-b311-114b90560af9</GUID>
|
||||
<version>1</version>
|
||||
<color_code>#FFFFFF</color_code>
|
||||
</metadata>
|
||||
<properties>
|
||||
<density>1.14</density>
|
||||
<diameter>2.85</diameter>
|
||||
</properties>
|
||||
<settings>
|
||||
<setting key="print temperature">250</setting>
|
||||
<setting key="heated bed temperature">60</setting>
|
||||
<setting key="standby temperature">100</setting>
|
||||
</settings>
|
||||
</fdmmaterial>
|
|
@ -36,6 +36,7 @@ Automatically generated PLA profile. Data in this file may not be not correct.
|
|||
<machine_identifier manufacturer="Ultimaker" product="Ultimaker 2"/>
|
||||
<machine_identifier manufacturer="Ultimaker" product="Ultimaker 2 Go"/>
|
||||
<machine_identifier manufacturer="Ultimaker" product="Ultimaker 2 Extended"/>
|
||||
<setting key="standby temperature">150</setting>
|
||||
<setting key="processing temperature graph">
|
||||
<point flow="2" temperature="180"/>
|
||||
<point flow="10" temperature="230"/>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Uranium is released under the terms of the AGPLv3 or higher.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.1
|
||||
import QtQuick.Controls 1.1
|
||||
|
@ -21,10 +21,10 @@ UM.ManagementPage
|
|||
var result = { "type": "material" }
|
||||
if(Cura.MachineManager.filterMaterialsByMachine)
|
||||
{
|
||||
result.definition = Cura.MachineManager.activeDefinitionId
|
||||
result.definition = Cura.MachineManager.activeQualityDefinitionId;
|
||||
if(Cura.MachineManager.hasVariants)
|
||||
{
|
||||
result.variant = Cura.MachineManager.activeVariantId
|
||||
result.variant = Cura.MachineManager.activeQualityVariantId;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -21,37 +21,45 @@ Tab
|
|||
anchors.fill: parent
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
|
||||
TableViewColumn
|
||||
Component
|
||||
{
|
||||
role: "label"
|
||||
title: catalog.i18nc("@title:column", "Setting")
|
||||
width: parent.width * 0.4
|
||||
}
|
||||
TableViewColumn
|
||||
{
|
||||
role: "profile_value"
|
||||
title: catalog.i18nc("@title:column", "Profile")
|
||||
width: parent.width * 0.18
|
||||
delegate: Rectangle
|
||||
id: itemDelegate
|
||||
|
||||
UM.TooltipArea
|
||||
{
|
||||
property var setting: qualitySettings.getItem(styleData.row)
|
||||
height: childrenRect.height
|
||||
color: "transparent"
|
||||
width: (parent != null) ? parent.width : 0
|
||||
text: (styleData.value.substr(0,1) == "=") ? styleData.value : ""
|
||||
|
||||
Label
|
||||
{
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.right: parent.right
|
||||
text: styleData.value
|
||||
font.weight: (setting.profile_value_source == "quality_changes") ? Font.Bold : Font.Normal
|
||||
font.strikeout: quality == Cura.MachineManager.activeQualityId && setting.user_value != ""
|
||||
font.strikeout: styleData.column == 1 && quality == Cura.MachineManager.activeQualityId && setting.user_value != ""
|
||||
font.italic: setting.profile_value_source == "quality_changes" || (quality == Cura.MachineManager.activeQualityId && setting.user_value != "")
|
||||
opacity: font.strikeout ? 0.5 : 1
|
||||
color: styleData.textColor
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TableViewColumn
|
||||
{
|
||||
role: "label"
|
||||
title: catalog.i18nc("@title:column", "Setting")
|
||||
width: parent.width * 0.4
|
||||
delegate: itemDelegate
|
||||
}
|
||||
TableViewColumn
|
||||
{
|
||||
role: "profile_value"
|
||||
title: catalog.i18nc("@title:column", "Profile")
|
||||
width: parent.width * 0.18
|
||||
delegate: itemDelegate
|
||||
}
|
||||
TableViewColumn
|
||||
{
|
||||
|
@ -59,12 +67,14 @@ Tab
|
|||
title: catalog.i18nc("@title:column", "Current");
|
||||
visible: quality == Cura.MachineManager.activeQualityId
|
||||
width: parent.width * 0.18
|
||||
delegate: itemDelegate
|
||||
}
|
||||
TableViewColumn
|
||||
{
|
||||
role: "unit"
|
||||
title: catalog.i18nc("@title:column", "Unit")
|
||||
width: parent.width * 0.14
|
||||
delegate: itemDelegate
|
||||
}
|
||||
|
||||
section.property: "category"
|
||||
|
|
|
@ -208,6 +208,8 @@ UM.ManagementPage
|
|||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
currentIndex: ExtruderManager.activeExtruderIndex + 1;
|
||||
|
||||
ProfileTab
|
||||
{
|
||||
title: catalog.i18nc("@title:tab", "Global Settings");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue