mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-16 03:07:53 -06:00
Merge branch '5.4' into CURA-10599_fix_exclude_materials
This commit is contained in:
commit
c8c6b59a08
8 changed files with 79 additions and 68 deletions
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2022 Ultimaker B.V.
|
||||
# Copyright (c) 2023 UltiMaker
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import enum
|
||||
import os
|
||||
|
@ -147,6 +147,7 @@ class CuraApplication(QtApplication):
|
|||
DefinitionChangesContainer = Resources.UserType + 10
|
||||
SettingVisibilityPreset = Resources.UserType + 11
|
||||
IntentInstanceContainer = Resources.UserType + 12
|
||||
ImageFiles = Resources.UserType + 13
|
||||
|
||||
pyqtEnum(ResourceTypes)
|
||||
|
||||
|
@ -425,6 +426,7 @@ class CuraApplication(QtApplication):
|
|||
Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
|
||||
Resources.addStorageType(self.ResourceTypes.SettingVisibilityPreset, "setting_visibility")
|
||||
Resources.addStorageType(self.ResourceTypes.IntentInstanceContainer, "intent")
|
||||
Resources.addStorageType(self.ResourceTypes.ImageFiles, "images")
|
||||
|
||||
self._container_registry.addResourceType(self.ResourceTypes.QualityInstanceContainer, "quality")
|
||||
self._container_registry.addResourceType(self.ResourceTypes.QualityChangesInstanceContainer, "quality_changes")
|
||||
|
@ -435,6 +437,7 @@ class CuraApplication(QtApplication):
|
|||
self._container_registry.addResourceType(self.ResourceTypes.MachineStack, "machine")
|
||||
self._container_registry.addResourceType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes")
|
||||
self._container_registry.addResourceType(self.ResourceTypes.IntentInstanceContainer, "intent")
|
||||
self._container_registry.addResourceType(self.ResourceTypes.ImageFiles, "images")
|
||||
|
||||
Resources.addType(self.ResourceTypes.QmlFiles, "qml")
|
||||
Resources.addType(self.ResourceTypes.Firmware, "firmware")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Copyright (c) 2023 UltiMaker
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
import glob
|
||||
import os
|
||||
|
@ -55,7 +55,9 @@ class CuraPackageManager(PackageManager):
|
|||
def initialize(self) -> None:
|
||||
self._installation_dirs_dict["materials"] = Resources.getStoragePath(CuraApplication.ResourceTypes.MaterialInstanceContainer)
|
||||
self._installation_dirs_dict["qualities"] = Resources.getStoragePath(CuraApplication.ResourceTypes.QualityInstanceContainer)
|
||||
self._installation_dirs_dict["variants"] = Resources.getStoragePath(CuraApplication.ResourceTypes.VariantInstanceContainer)
|
||||
self._installation_dirs_dict["variants"] = Resources.getStoragePath(
|
||||
CuraApplication.ResourceTypes.VariantInstanceContainer)
|
||||
self._installation_dirs_dict["images"] = Resources.getStoragePath(CuraApplication.ResourceTypes.ImageFiles)
|
||||
|
||||
# Due to a bug in Cura 5.1.0 we needed to change the directory structure of the curapackage on the server side (See SD-3871).
|
||||
# Although the material intent profiles will be installed in the `intent` folder, the curapackage from the server side will
|
||||
|
|
|
@ -1,29 +1,32 @@
|
|||
# Copyright (c) 2022 Ultimaker B.V.
|
||||
# Copyright (c) 2023 UltiMaker
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import collections
|
||||
from typing import OrderedDict, Optional
|
||||
from typing import Optional
|
||||
|
||||
from PyQt6.QtCore import Qt, QTimer, QObject
|
||||
from PyQt6.QtCore import Qt, QTimer, QObject, QUrl
|
||||
|
||||
import cura
|
||||
from UM import i18nCatalog
|
||||
from UM.Logger import Logger
|
||||
from UM.Qt.ListModel import ListModel
|
||||
from UM.Resources import Resources
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.Interfaces import ContainerInterface
|
||||
|
||||
from cura.Machines.Models.IntentCategoryModel import IntentCategoryModel
|
||||
from cura.Settings.IntentManager import IntentManager
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
class IntentSelectionModel(ListModel):
|
||||
|
||||
NameRole = Qt.ItemDataRole.UserRole + 1
|
||||
IntentCategoryRole = Qt.ItemDataRole.UserRole + 2
|
||||
WeightRole = Qt.ItemDataRole.UserRole + 3
|
||||
DescriptionRole = Qt.ItemDataRole.UserRole + 4
|
||||
IconRole = Qt.ItemDataRole.UserRole + 5
|
||||
CustomIconRole = Qt.ItemDataRole.UserRole + 6
|
||||
|
||||
def __init__(self, parent: Optional[QObject] = None) -> None:
|
||||
super().__init__(parent)
|
||||
|
@ -33,6 +36,7 @@ class IntentSelectionModel(ListModel):
|
|||
self.addRoleName(self.WeightRole, "weight")
|
||||
self.addRoleName(self.DescriptionRole, "description")
|
||||
self.addRoleName(self.IconRole, "icon")
|
||||
self.addRoleName(self.CustomIconRole, "custom_icon")
|
||||
|
||||
application = cura.CuraApplication.CuraApplication.getInstance()
|
||||
|
||||
|
@ -53,36 +57,8 @@ class IntentSelectionModel(ListModel):
|
|||
|
||||
self._onChange()
|
||||
|
||||
@staticmethod
|
||||
def _getDefaultProfileInformation() -> OrderedDict[str, dict]:
|
||||
""" Default information user-visible string. Ordered by weight. """
|
||||
default_profile_information = collections.OrderedDict()
|
||||
default_profile_information["default"] = {
|
||||
"name": catalog.i18nc("@label", "Default"),
|
||||
"icon": "GearCheck"
|
||||
}
|
||||
default_profile_information["visual"] = {
|
||||
"name": catalog.i18nc("@label", "Visual"),
|
||||
"description": catalog.i18nc("@text", "The visual profile is designed to print visual prototypes and models with the intent of high visual and surface quality."),
|
||||
"icon" : "Visual"
|
||||
}
|
||||
default_profile_information["engineering"] = {
|
||||
"name": catalog.i18nc("@label", "Engineering"),
|
||||
"description": catalog.i18nc("@text", "The engineering profile is designed to print functional prototypes and end-use parts with the intent of better accuracy and for closer tolerances."),
|
||||
"icon": "Nut"
|
||||
}
|
||||
default_profile_information["quick"] = {
|
||||
"name": catalog.i18nc("@label", "Draft"),
|
||||
"description": catalog.i18nc("@text", "The draft profile is designed to print initial prototypes and concept validation with the intent of significant print time reduction."),
|
||||
"icon": "SpeedOMeter"
|
||||
}
|
||||
default_profile_information["annealing"] = {
|
||||
"name": catalog.i18nc("@label", "Annealing"),
|
||||
"description": catalog.i18nc("@text",
|
||||
"The annealing profile requires post-processing in an oven after the print is finished. This profile retains the dimensional accuracy of the printed part after annealing and improves strength, stiffness, and thermal resistance."),
|
||||
"icon": "Anneal"
|
||||
}
|
||||
return default_profile_information
|
||||
_default_intent_categories = ["default", "visual", "engineering", "quick", "annealing"]
|
||||
_icons = {"default": "GearCheck", "visual": "Visual", "engineering": "Nut", "quick": "SpeedOMeter", "annealing": "Anneal"}
|
||||
|
||||
def _onContainerChange(self, container: ContainerInterface) -> None:
|
||||
"""Updates the list of intents if an intent profile was added or removed."""
|
||||
|
@ -108,25 +84,42 @@ class IntentSelectionModel(ListModel):
|
|||
self.setItems([])
|
||||
return
|
||||
|
||||
default_profile_info = self._getDefaultProfileInformation()
|
||||
|
||||
available_categories = IntentManager.getInstance().currentAvailableIntentCategories()
|
||||
|
||||
result = []
|
||||
for i, category in enumerate(available_categories):
|
||||
profile_info = default_profile_info.get(category, {})
|
||||
for category in available_categories:
|
||||
|
||||
try:
|
||||
weight = list(default_profile_info.keys()).index(category)
|
||||
except ValueError:
|
||||
weight = len(available_categories) + i
|
||||
if category in self._default_intent_categories:
|
||||
result.append({
|
||||
"name": IntentCategoryModel.translation(category, "name", category.title()),
|
||||
"description": IntentCategoryModel.translation(category, "description", None),
|
||||
"icon": self._icons[category],
|
||||
"custom_icon": None,
|
||||
"intent_category": category,
|
||||
"weight": self._default_intent_categories.index(category),
|
||||
})
|
||||
else:
|
||||
# There can be multiple intents with the same category, use one of these
|
||||
# intent-metadata's for the icon/description defintions for the intent
|
||||
intent_metadata = cura.CuraApplication.CuraApplication \
|
||||
.getInstance() \
|
||||
.getContainerRegistry() \
|
||||
.findContainersMetadata(type="intent", definition=global_stack.definition.getId(),
|
||||
intent_category=category)[0]
|
||||
|
||||
result.append({
|
||||
"name": profile_info.get("name", category.title()),
|
||||
"description": profile_info.get("description", None),
|
||||
"icon" : profile_info.get("icon", ""),
|
||||
"intent_category": category,
|
||||
"weight": weight,
|
||||
})
|
||||
icon = intent_metadata.get("icon", None)
|
||||
if icon is not None:
|
||||
icon = QUrl.fromLocalFile(
|
||||
Resources.getPath(cura.CuraApplication.CuraApplication.ResourceTypes.ImageFiles, icon))
|
||||
|
||||
result.append({
|
||||
"name": intent_metadata.get("name", category.title()),
|
||||
"description": intent_metadata.get("description", None),
|
||||
"custom_icon": icon,
|
||||
"icon": None,
|
||||
"intent_category": category,
|
||||
"weight": 5,
|
||||
})
|
||||
|
||||
result.sort(key=lambda k: k["weight"])
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2021 Ultimaker B.V.
|
||||
# Copyright (c) 2023 UltiMaker
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from UM.Settings.SQLQueryFactory import SQLQueryFactory
|
||||
|
@ -10,8 +10,8 @@ class IntentDatabaseHandler(DatabaseMetadataContainerController):
|
|||
"""The Database handler for Intent containers"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(SQLQueryFactory(table = "intent",
|
||||
fields = {
|
||||
super().__init__(SQLQueryFactory(table="intent",
|
||||
fields={
|
||||
"id": "text",
|
||||
"name": "text",
|
||||
"quality_type": "text",
|
||||
|
@ -20,6 +20,8 @@ class IntentDatabaseHandler(DatabaseMetadataContainerController):
|
|||
"definition": "text",
|
||||
"material": "text",
|
||||
"version": "text",
|
||||
"setting_version": "text"
|
||||
"setting_version": "text",
|
||||
"icon": "text",
|
||||
"description": "text",
|
||||
}))
|
||||
self._container_type = InstanceContainer
|
||||
|
|
|
@ -1665,15 +1665,16 @@
|
|||
{
|
||||
"label": "Small Top/Bottom Width",
|
||||
"description": "Small top/bottom regions are filled with walls instead of the default top/bottom pattern. This helps to avoids jerky motions.",
|
||||
"value": "skin_line_width * 2",
|
||||
"default_value": 1,
|
||||
"value": "0",
|
||||
"default_value": 0,
|
||||
"minimum_value": "0",
|
||||
"maximum_value_warning": "skin_line_width * 10",
|
||||
"type": "float",
|
||||
"enabled": "(top_layers > 0 or bottom_layers > 0) and top_bottom_pattern != 'concentric'",
|
||||
"enabled": false,
|
||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||
"settable_per_mesh": true,
|
||||
"unit": "mm"
|
||||
"unit": "mm",
|
||||
"comment": "Disabled for 5.4.x, as we're worried about micro-segments in the infill. Also disabled in the engine, so forcing this > 0 will not do anything at the moment."
|
||||
},
|
||||
"skin_no_small_gaps_heuristic":
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2022 Ultimaker B.V.
|
||||
// Copyright (c) 2023 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
|
@ -32,6 +32,7 @@ Item
|
|||
{
|
||||
profileName: model.name
|
||||
icon: model.icon
|
||||
custom_icon: model.custom_icon
|
||||
tooltipText: model.description ? model.description : ""
|
||||
|
||||
selected: Cura.MachineManager.activeIntentCategory == model.intent_category
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2022 Ultimaker B.V.
|
||||
// Copyright (c) 2023 UltiMaker
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
|
@ -19,6 +19,7 @@ Rectangle
|
|||
property bool selected: false
|
||||
property string profileName: ""
|
||||
property string icon: ""
|
||||
property string custom_icon: ""
|
||||
property alias tooltipText: tooltip.text
|
||||
|
||||
signal clicked()
|
||||
|
@ -55,22 +56,32 @@ Rectangle
|
|||
id: intentIcon
|
||||
width: UM.Theme.getSize("recommended_button_icon").width
|
||||
height: UM.Theme.getSize("recommended_button_icon").height
|
||||
|
||||
UM.ColorImage
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
visible: icon != ""
|
||||
visible: icon !== ""
|
||||
source: UM.Theme.getIcon(icon)
|
||||
color: UM.Theme.getColor("icon")
|
||||
}
|
||||
|
||||
UM.ColorImage
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
visible: custom_icon !== ""
|
||||
source: custom_icon
|
||||
color: UM.Theme.getColor("icon")
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: circle
|
||||
anchors.fill: parent
|
||||
radius: width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: icon == ""
|
||||
visible: icon === "" && custom_icon === ""
|
||||
border.width: UM.Theme.getSize("thick_lining").width
|
||||
border.color: UM.Theme.getColor("text")
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M19 5H5V19H19V5ZM6 3C4.34315 3 3 4.34315 3 6V18C3 19.6569 4.34315 21 6 21H18C19.6569 21 21 19.6569 21 18V6C21 4.34315 19.6569 3 18 3H6Z" fill="black"/>
|
||||
<path d="M16 8L15.3416 8.32918C14.4971 8.75147 13.5029 8.75147 12.6584 8.32918L11.3416 7.67082C10.4971 7.24853 9.50294 7.24853 8.65836 7.67082L8 8" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M16 12L15.3416 12.3292C14.4971 12.7515 13.5029 12.7515 12.6584 12.3292L11.3416 11.6708C10.4971 11.2485 9.50294 11.2485 8.65836 11.6708L8 12" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M16 16L15.3416 16.3292C14.4971 16.7515 13.5029 16.7515 12.6584 16.3292L11.3416 15.6708C10.4971 15.2485 9.50294 15.2485 8.65836 15.6708L8 16" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M5 5H19V19H5V5ZM3 6C3 4.34315 4.34315 3 6 3H18C19.6569 3 21 4.34315 21 6V18C21 19.6569 19.6569 21 18 21H6C4.34315 21 3 19.6569 3 18V6ZM13.1058 7.43463L11.7891 6.7763C10.663 6.21324 9.33744 6.21324 8.21136 6.77628L7.55301 7.10546C7.05903 7.35245 6.8588 7.95312 7.10579 8.4471C7.35278 8.94108 7.95345 9.1413 8.44743 8.89431L9.10579 8.56514C9.66886 8.2836 10.3317 8.28365 10.8946 8.56515L12.2114 9.22351C13.3374 9.78654 14.6631 9.78652 15.7891 9.22348L16.4474 8.89433C16.9414 8.64735 17.1416 8.04668 16.8947 7.5527C16.6477 7.05871 16.047 6.85847 15.553 7.10545L14.8946 7.43466C14.3316 7.71616 13.6688 7.71613 13.1058 7.43463ZM11.7891 10.7763L13.1058 11.4347C13.6688 11.7162 14.3316 11.7162 14.8946 11.4347L15.553 11.1055C16.047 10.8585 16.6477 11.0587 16.8946 11.5527C17.1416 12.0467 16.9414 12.6474 16.4474 12.8943L15.7891 13.2235C14.663 13.7866 13.3374 13.7866 12.2114 13.2235L10.8946 12.5651C10.3317 12.2836 9.66887 12.2836 9.10581 12.5651L8.44745 12.8943C7.95348 13.1413 7.3528 12.9411 7.1058 12.4472C6.8588 11.9532 7.05901 11.3525 7.55298 11.1055L8.21134 10.7763C9.33743 10.2132 10.663 10.2132 11.7891 10.7763ZM13.1058 15.4347L11.7891 14.7763C10.663 14.2132 9.33743 14.2132 8.21134 14.7763L7.55298 15.1055C7.05901 15.3525 6.8588 15.9532 7.1058 16.4472C7.3528 16.9411 7.95348 17.1413 8.44745 16.8943L9.10581 16.5651C9.66887 16.2836 10.3317 16.2836 10.8946 16.5651L12.2114 17.2235C13.3374 17.7866 14.663 17.7866 15.7891 17.2235L16.4474 16.8943C16.9414 16.6474 17.1416 16.0467 16.8946 15.5527C16.6477 15.0587 16.047 14.8585 15.553 15.1055L14.8946 15.4347C14.3316 15.7162 13.6688 15.7162 13.1058 15.4347Z"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 983 B After Width: | Height: | Size: 1.7 KiB |
Loading…
Add table
Add a link
Reference in a new issue