mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-13 09:47:50 -06:00
Merge remote-tracking branch 'origin/CURA-6522_one_at_a_time_overlapping_build_area' into CURA-6522_one_at_a_time_overlapping_build_area
This commit is contained in:
commit
b30b641034
1350 changed files with 16424 additions and 11601 deletions
|
@ -9,7 +9,11 @@ DEFAULT_CURA_DISPLAY_NAME = "Ultimaker Cura"
|
|||
DEFAULT_CURA_VERSION = "master"
|
||||
DEFAULT_CURA_BUILD_TYPE = ""
|
||||
DEFAULT_CURA_DEBUG_MODE = False
|
||||
DEFAULT_CURA_SDK_VERSION = "7.0.0"
|
||||
|
||||
# Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for
|
||||
# example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the
|
||||
# CuraVersion.py.in template.
|
||||
CuraSDKVersion = "7.0.0"
|
||||
|
||||
try:
|
||||
from cura.CuraVersion import CuraAppName # type: ignore
|
||||
|
@ -32,6 +36,9 @@ try:
|
|||
except ImportError:
|
||||
CuraVersion = DEFAULT_CURA_VERSION # [CodeStyle: Reflecting imported value]
|
||||
|
||||
# CURA-6569
|
||||
# This string indicates what type of version it is. For example, "enterprise". By default it's empty which indicates
|
||||
# a default/normal Cura build.
|
||||
try:
|
||||
from cura.CuraVersion import CuraBuildType # type: ignore
|
||||
except ImportError:
|
||||
|
@ -42,7 +49,7 @@ try:
|
|||
except ImportError:
|
||||
CuraDebugMode = DEFAULT_CURA_DEBUG_MODE
|
||||
|
||||
# Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for
|
||||
# example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the
|
||||
# CuraVersion.py.in template.
|
||||
CuraSDKVersion = "7.0.0"
|
||||
# CURA-6569
|
||||
# Various convenience flags indicating what kind of Cura build it is.
|
||||
__ENTERPRISE_VERSION_TYPE = "enterprise"
|
||||
IsEnterpriseVersion = CuraBuildType.lower() == __ENTERPRISE_VERSION_TYPE
|
||||
|
|
|
@ -26,7 +26,6 @@ catalog = i18nCatalog("cura")
|
|||
|
||||
import numpy
|
||||
import math
|
||||
import copy
|
||||
|
||||
from typing import List, Optional, TYPE_CHECKING, Any, Set, cast, Iterable, Dict
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ class CuraApplication(QtApplication):
|
|||
# SettingVersion represents the set of settings available in the machine/extruder definitions.
|
||||
# You need to make sure that this version number needs to be increased if there is any non-backwards-compatible
|
||||
# changes of the settings.
|
||||
SettingVersion = 10
|
||||
SettingVersion = 11
|
||||
|
||||
Created = False
|
||||
|
||||
|
@ -720,6 +720,8 @@ class CuraApplication(QtApplication):
|
|||
## Handle loading of all plugin types (and the backend explicitly)
|
||||
# \sa PluginRegistry
|
||||
def _loadPlugins(self) -> None:
|
||||
self._plugin_registry.setCheckIfTrusted(ApplicationMetadata.IsEnterpriseVersion)
|
||||
|
||||
self._plugin_registry.addType("profile_reader", self._addProfileReader)
|
||||
self._plugin_registry.addType("profile_writer", self._addProfileWriter)
|
||||
|
||||
|
@ -1368,8 +1370,11 @@ class CuraApplication(QtApplication):
|
|||
|
||||
for node in nodes:
|
||||
mesh_data = node.getMeshData()
|
||||
if mesh_data and mesh_data.getFileName():
|
||||
job = ReadMeshJob(mesh_data.getFileName())
|
||||
|
||||
if mesh_data:
|
||||
file_name = mesh_data.getFileName()
|
||||
if file_name:
|
||||
job = ReadMeshJob(file_name)
|
||||
job._node = node # type: ignore
|
||||
job.finished.connect(self._reloadMeshFinished)
|
||||
if has_merged_nodes:
|
||||
|
@ -1796,7 +1801,7 @@ class CuraApplication(QtApplication):
|
|||
try:
|
||||
result = workspace_reader.preRead(file_path, show_dialog=False)
|
||||
return result == WorkspaceReader.PreReadResult.accepted
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
Logger.logException("e", "Could not check file %s", file_url)
|
||||
return False
|
||||
|
||||
|
@ -1892,3 +1897,7 @@ class CuraApplication(QtApplication):
|
|||
op.push()
|
||||
from UM.Scene.Selection import Selection
|
||||
Selection.clear()
|
||||
|
||||
@classmethod
|
||||
def getInstance(cls, *args, **kwargs) -> "CuraApplication":
|
||||
return cast(CuraApplication, super().getInstance(**kwargs))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from UM.Application import Application
|
||||
from UM.Qt.QtApplication import QtApplication
|
||||
from typing import Any, Optional
|
||||
import numpy
|
||||
|
||||
|
@ -232,7 +232,7 @@ class LayerPolygon:
|
|||
@classmethod
|
||||
def getColorMap(cls):
|
||||
if cls.__color_map is None:
|
||||
theme = Application.getInstance().getTheme()
|
||||
theme = QtApplication.getInstance().getTheme()
|
||||
cls.__color_map = numpy.array([
|
||||
theme.getColor("layerview_none").getRgbF(), # NoneType
|
||||
theme.getColor("layerview_inset_0").getRgbF(), # Inset0Type
|
||||
|
|
|
@ -140,7 +140,7 @@ class MachineNode(ContainerNode):
|
|||
elif groups_by_name[name].intent_category == "default": # Intent category should be stored as "default" if everything is default or as the intent if any of the extruder have an actual intent.
|
||||
groups_by_name[name].intent_category = quality_changes.get("intent_category", "default")
|
||||
|
||||
if "position" in quality_changes: # An extruder profile.
|
||||
if quality_changes.get("position") is not None: # An extruder profile.
|
||||
groups_by_name[name].metadata_per_extruder[int(quality_changes["position"])] = quality_changes
|
||||
else: # Global profile.
|
||||
groups_by_name[name].metadata_for_global = quality_changes
|
||||
|
|
|
@ -6,6 +6,7 @@ from typing import Dict, Set
|
|||
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, pyqtProperty
|
||||
|
||||
from UM.Qt.ListModel import ListModel
|
||||
from UM.Logger import Logger
|
||||
|
||||
import cura.CuraApplication # Imported like this to prevent a circular reference.
|
||||
from cura.Machines.ContainerTree import ContainerTree
|
||||
|
@ -153,7 +154,12 @@ class BaseMaterialsModel(ListModel):
|
|||
if not extruder_stack:
|
||||
return
|
||||
nozzle_name = extruder_stack.variant.getName()
|
||||
materials = ContainerTree.getInstance().machines[global_stack.definition.getId()].variants[nozzle_name].materials
|
||||
machine_node = ContainerTree.getInstance().machines[global_stack.definition.getId()]
|
||||
if nozzle_name not in machine_node.variants:
|
||||
Logger.log("w", "Unable to find variant %s in container tree", nozzle_name)
|
||||
self._available_materials = {}
|
||||
return
|
||||
materials = machine_node.variants[nozzle_name].materials
|
||||
approximate_material_diameter = extruder_stack.getApproximateMaterialDiameter()
|
||||
self._available_materials = {key: material for key, material in materials.items() if float(material.getMetaDataEntry("approximate_diameter", -1)) == approximate_material_diameter}
|
||||
|
||||
|
|
|
@ -2,13 +2,8 @@
|
|||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
from UM.Application import Application
|
||||
from UM.Logger import Logger
|
||||
from UM.Qt.ListModel import ListModel
|
||||
from UM.Util import parseBool
|
||||
|
||||
from cura.Machines.VariantType import VariantType
|
||||
|
||||
|
||||
class BuildPlateModel(ListModel):
|
||||
|
|
|
@ -11,7 +11,6 @@ from UM.Util import parseBool
|
|||
from UM.OutputDevice.OutputDeviceManager import ManualDeviceAdditionAttempt
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from PyQt5.QtCore import QObject
|
||||
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.PrinterOutput.NetworkedPrinterOutputDevice import NetworkedPrinterOutputDevice
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#Copyright (c) 2019 Ultimaker B.V.
|
||||
#Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import Qt, QTimer
|
||||
import collections
|
||||
from PyQt5.QtCore import Qt, QTimer
|
||||
from typing import TYPE_CHECKING, Optional, Dict
|
||||
from cura.Machines.Models.IntentTranslations import intent_translations
|
||||
|
||||
from cura.Machines.Models.IntentModel import IntentModel
|
||||
from cura.Settings.IntentManager import IntentManager
|
||||
|
@ -29,21 +30,29 @@ class IntentCategoryModel(ListModel):
|
|||
|
||||
modelUpdated = pyqtSignal()
|
||||
|
||||
_translations = collections.OrderedDict() # type: "collections.OrderedDict[str,Dict[str,Optional[str]]]"
|
||||
|
||||
# Translations to user-visible string. Ordered by weight.
|
||||
# TODO: Create a solution for this name and weight to be used dynamically.
|
||||
_translations = collections.OrderedDict() # type: "collections.OrderedDict[str,Dict[str,Optional[str]]]"
|
||||
_translations["default"] = {
|
||||
@classmethod
|
||||
def _get_translations(cls):
|
||||
if len(cls._translations) == 0:
|
||||
cls._translations["default"] = {
|
||||
"name": catalog.i18nc("@label", "Default")
|
||||
}
|
||||
_translations["engineering"] = {
|
||||
cls._translations["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.")
|
||||
}
|
||||
cls._translations["engineering"] = {
|
||||
"name": catalog.i18nc("@label", "Engineering"),
|
||||
"description": catalog.i18nc("@text", "Suitable for engineering work")
|
||||
|
||||
"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.")
|
||||
}
|
||||
_translations["smooth"] = {
|
||||
"name": catalog.i18nc("@label", "Smooth"),
|
||||
"description": catalog.i18nc("@text", "Optimized for a smooth surfaces")
|
||||
cls._translations["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.")
|
||||
}
|
||||
return cls._translations
|
||||
|
||||
## Creates a new model for a certain intent category.
|
||||
# \param The category to list the intent profiles for.
|
||||
|
@ -95,15 +104,15 @@ class IntentCategoryModel(ListModel):
|
|||
"name": IntentCategoryModel.translation(category, "name", catalog.i18nc("@label", "Unknown")),
|
||||
"description": IntentCategoryModel.translation(category, "description", None),
|
||||
"intent_category": category,
|
||||
"weight": list(self._translations.keys()).index(category),
|
||||
"weight": list(IntentCategoryModel._get_translations().keys()).index(category),
|
||||
"qualities": qualities
|
||||
})
|
||||
result.sort(key = lambda k: k["weight"])
|
||||
self.setItems(result)
|
||||
|
||||
## Get a display value for a category. See IntenCategoryModel._translations
|
||||
## Get a display value for a category.
|
||||
## for categories and keys
|
||||
@staticmethod
|
||||
def translation(category: str, key: str, default: Optional[str] = None):
|
||||
display_strings = IntentCategoryModel._translations.get(category, {})
|
||||
display_strings = IntentCategoryModel._get_translations().get(category, {})
|
||||
return display_strings.get(key, default)
|
||||
|
|
24
cura/Machines/Models/IntentTranslations.py
Normal file
24
cura/Machines/Models/IntentTranslations.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
import collections
|
||||
from typing import Dict, Optional
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
from typing import Dict, Optional
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
intent_translations = collections.OrderedDict() # type: collections.OrderedDict[str, Dict[str, Optional[str]]]
|
||||
intent_translations["default"] = {
|
||||
"name": catalog.i18nc("@label", "Default")
|
||||
}
|
||||
intent_translations["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.")
|
||||
}
|
||||
intent_translations["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.")
|
||||
}
|
||||
intent_translations["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.")
|
||||
}
|
|
@ -14,6 +14,7 @@ from cura.Machines.ContainerTree import ContainerTree
|
|||
from cura.Settings.cura_empty_instance_containers import empty_quality_changes_container
|
||||
from cura.Settings.IntentManager import IntentManager
|
||||
from cura.Machines.Models.MachineModelUtils import fetchLayerHeight
|
||||
from cura.Machines.Models.IntentTranslations import intent_translations
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
catalog = i18nCatalog("cura")
|
||||
|
@ -336,10 +337,11 @@ class QualityManagementModel(ListModel):
|
|||
"quality_type": quality_type,
|
||||
"quality_changes_group": None,
|
||||
"intent_category": intent_category,
|
||||
"section_name": catalog.i18nc("@label", intent_category.capitalize()),
|
||||
"section_name": catalog.i18nc("@label", intent_translations.get(intent_category, {}).get("name", catalog.i18nc("@label", "Unknown"))),
|
||||
})
|
||||
# Sort by quality_type for each intent category
|
||||
result = sorted(result, key = lambda x: (x["intent_category"], x["quality_type"]))
|
||||
|
||||
result = sorted(result, key = lambda x: (list(intent_translations).index(x["intent_category"]), x["quality_type"]))
|
||||
item_list += result
|
||||
|
||||
# Create quality_changes group items
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from UM.Logger import Logger
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.Interfaces import ContainerInterface
|
||||
from UM.Signal import Signal
|
||||
|
||||
from cura.Settings.cura_empty_instance_containers import empty_variant_container
|
||||
from cura.Machines.ContainerNode import ContainerNode
|
||||
from cura.Machines.MaterialNode import MaterialNode
|
||||
|
||||
|
@ -83,12 +82,22 @@ class VariantNode(ContainerNode):
|
|||
# if there is no match.
|
||||
def preferredMaterial(self, approximate_diameter: int) -> MaterialNode:
|
||||
for base_material, material_node in self.materials.items():
|
||||
if self.machine.preferred_material in base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
|
||||
if self.machine.preferred_material == base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
|
||||
return material_node
|
||||
# First fallback: Choose any material with matching diameter.
|
||||
|
||||
# First fallback: Check if we should be checking for the 175 variant.
|
||||
if approximate_diameter == 2:
|
||||
preferred_material = self.machine.preferred_material + "_175"
|
||||
for base_material, material_node in self.materials.items():
|
||||
if preferred_material == base_material and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
|
||||
return material_node
|
||||
|
||||
# Second fallback: Choose any material with matching diameter.
|
||||
for material_node in self.materials.values():
|
||||
if material_node.getMetaDataEntry("approximate_diameter") and approximate_diameter == int(material_node.getMetaDataEntry("approximate_diameter")):
|
||||
Logger.log("w", "Could not find preferred material %s, falling back to whatever works", self.machine.preferred_material)
|
||||
return material_node
|
||||
|
||||
fallback = next(iter(self.materials.values())) # Should only happen with empty material node.
|
||||
Logger.log("w", "Could not find preferred material {preferred_material} with diameter {diameter} for variant {variant_id}, falling back to {fallback}.".format(
|
||||
preferred_material = self.machine.preferred_material,
|
||||
|
|
|
@ -99,7 +99,7 @@ class AuthorizationHelpers:
|
|||
})
|
||||
except requests.exceptions.ConnectionError:
|
||||
# Connection was suddenly dropped. Nothing we can do about that.
|
||||
Logger.log("w", "Something failed while attempting to parse the JWT token")
|
||||
Logger.logException("w", "Something failed while attempting to parse the JWT token")
|
||||
return None
|
||||
if token_request.status_code not in (200, 201):
|
||||
Logger.log("w", "Could not retrieve token data from auth server: %s", token_request.text)
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
import os
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
from urllib.parse import urlencode
|
||||
|
||||
|
@ -14,7 +13,6 @@ from PyQt5.QtGui import QDesktopServices
|
|||
|
||||
from UM.Logger import Logger
|
||||
from UM.Message import Message
|
||||
from UM.Platform import Platform
|
||||
from UM.Signal import Signal
|
||||
|
||||
from cura.OAuth2.LocalAuthorizationServer import LocalAuthorizationServer
|
||||
|
|
|
@ -17,6 +17,7 @@ from cura.Scene import ZOffsetDecorator
|
|||
|
||||
import random # used for list shuffling
|
||||
|
||||
|
||||
class PlatformPhysics:
|
||||
def __init__(self, controller, volume):
|
||||
super().__init__()
|
||||
|
|
|
@ -20,7 +20,7 @@ class FirmwareUpdater(QObject):
|
|||
|
||||
self._output_device = output_device
|
||||
|
||||
self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True)
|
||||
self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True, name = "FirmwareUpdateThread")
|
||||
|
||||
self._firmware_file = ""
|
||||
self._firmware_progress = 0
|
||||
|
@ -43,7 +43,7 @@ class FirmwareUpdater(QObject):
|
|||
## Cleanup after a succesful update
|
||||
def _cleanupAfterUpdate(self) -> None:
|
||||
# Clean up for next attempt.
|
||||
self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True)
|
||||
self._update_firmware_thread = Thread(target=self._updateFirmware, daemon=True, name = "FirmwareUpdateThread")
|
||||
self._firmware_file = ""
|
||||
self._onFirmwareProgress(100)
|
||||
self._setFirmwareUpdateState(FirmwareUpdateState.completed)
|
||||
|
|
|
@ -4,12 +4,12 @@ from cura.Scene.CuraSceneNode import CuraSceneNode
|
|||
|
||||
## Make a SceneNode build plate aware CuraSceneNode objects all have this decorator.
|
||||
class BuildPlateDecorator(SceneNodeDecorator):
|
||||
def __init__(self, build_plate_number = -1):
|
||||
def __init__(self, build_plate_number: int = -1) -> None:
|
||||
super().__init__()
|
||||
self._build_plate_number = None
|
||||
self._build_plate_number = build_plate_number
|
||||
self.setBuildPlateNumber(build_plate_number)
|
||||
|
||||
def setBuildPlateNumber(self, nr):
|
||||
def setBuildPlateNumber(self, nr: int) -> None:
|
||||
# Make sure that groups are set correctly
|
||||
# setBuildPlateForSelection in CuraActions makes sure that no single childs are set.
|
||||
self._build_plate_number = nr
|
||||
|
@ -19,7 +19,7 @@ class BuildPlateDecorator(SceneNodeDecorator):
|
|||
for child in self._node.getChildren():
|
||||
child.callDecoration("setBuildPlateNumber", nr)
|
||||
|
||||
def getBuildPlateNumber(self):
|
||||
def getBuildPlateNumber(self) -> int:
|
||||
return self._build_plate_number
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Copyright (c) 2015 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import Optional
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
from UM.Application import Application
|
||||
from UM.Math.Polygon import Polygon
|
||||
|
@ -11,6 +11,9 @@ from UM.Math.Color import Color
|
|||
from UM.Mesh.MeshBuilder import MeshBuilder # To create a mesh to display the convex hull with.
|
||||
from UM.View.GL.OpenGL import OpenGL
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from UM.Mesh.MeshData import MeshData
|
||||
|
||||
|
||||
class ConvexHullNode(SceneNode):
|
||||
shader = None # To prevent the shader from being re-built over and over again, only load it once.
|
||||
|
@ -44,7 +47,7 @@ class ConvexHullNode(SceneNode):
|
|||
# The node this mesh is "watching"
|
||||
self._node = node
|
||||
# Area of the head + fans for display as a shadow on the buildplate
|
||||
self._convex_hull_head_mesh = None
|
||||
self._convex_hull_head_mesh = None # type: Optional[MeshData]
|
||||
|
||||
self._node.decoratorsChanged.connect(self._onNodeDecoratorsChanged)
|
||||
self._onNodeDecoratorsChanged(self._node)
|
||||
|
|
|
@ -247,7 +247,7 @@ class ContainerManager(QObject):
|
|||
|
||||
try:
|
||||
with open(file_url, "rt", encoding = "utf-8") as f:
|
||||
container.deserialize(f.read())
|
||||
container.deserialize(f.read(), file_url)
|
||||
except PermissionError:
|
||||
return {"status": "error", "message": "Permission denied when trying to read the file."}
|
||||
except ContainerFormatError:
|
||||
|
@ -339,11 +339,11 @@ class ContainerManager(QObject):
|
|||
# \return A list of names of materials with the same GUID.
|
||||
@pyqtSlot("QVariant", bool, result = "QStringList")
|
||||
def getLinkedMaterials(self, material_node: "MaterialNode", exclude_self: bool = False) -> List[str]:
|
||||
same_guid = ContainerRegistry.getInstance().findInstanceContainersMetadata(guid = material_node.guid)
|
||||
same_guid = ContainerRegistry.getInstance().findInstanceContainersMetadata(GUID = material_node.guid)
|
||||
if exclude_self:
|
||||
return [metadata["name"] for metadata in same_guid if metadata["base_file"] != material_node.base_file]
|
||||
return list({meta["name"] for meta in same_guid if meta["base_file"] != material_node.base_file})
|
||||
else:
|
||||
return [metadata["name"] for metadata in same_guid]
|
||||
return list({meta["name"] for meta in same_guid})
|
||||
|
||||
## Unlink a material from all other materials by creating a new GUID
|
||||
# \param material_id \type{str} the id of the material to create a new GUID for.
|
||||
|
|
|
@ -12,7 +12,6 @@ from UM.Scene.SceneNode import SceneNode
|
|||
from UM.Scene.Selection import Selection
|
||||
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry # Finding containers by ID.
|
||||
from UM.Decorators import deprecated
|
||||
|
||||
from typing import Any, cast, Dict, List, Optional, TYPE_CHECKING, Union
|
||||
|
||||
|
@ -369,7 +368,7 @@ class ExtruderManager(QObject):
|
|||
printer = global_stack.getId(), expected = expected_extruder_definition_0_id, got = extruder_stack_0.definition.getId()))
|
||||
try:
|
||||
extruder_definition = container_registry.findDefinitionContainers(id = expected_extruder_definition_0_id)[0]
|
||||
except IndexError as e:
|
||||
except IndexError:
|
||||
# It still needs to break, but we want to know what extruder ID made it break.
|
||||
msg = "Unable to find extruder definition with the id [%s]" % expected_extruder_definition_0_id
|
||||
Logger.logException("e", msg)
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
#Copyright (c) 2019 Ultimaker B.V.
|
||||
#Cura is released under the terms of the LGPLv3 or higher.
|
||||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot
|
||||
from typing import Any, Dict, List, Optional, Set, Tuple, TYPE_CHECKING
|
||||
import cura.CuraApplication
|
||||
|
||||
from UM.Logger import Logger
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
|
||||
import cura.CuraApplication
|
||||
from cura.Machines.ContainerTree import ContainerTree
|
||||
from cura.Settings.cura_empty_instance_containers import empty_intent_container
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
|
@ -36,8 +38,12 @@ class IntentManager(QObject):
|
|||
# \return A list of metadata dictionaries matching the search criteria, or
|
||||
# an empty list if nothing was found.
|
||||
def intentMetadatas(self, definition_id: str, nozzle_name: str, material_base_file: str) -> List[Dict[str, Any]]:
|
||||
material_node = ContainerTree.getInstance().machines[definition_id].variants[nozzle_name].materials[material_base_file]
|
||||
intent_metadatas = []
|
||||
intent_metadatas = [] # type: List[Dict[str, Any]]
|
||||
materials = ContainerTree.getInstance().machines[definition_id].variants[nozzle_name].materials
|
||||
if material_base_file not in materials:
|
||||
return intent_metadatas
|
||||
|
||||
material_node = materials[material_base_file]
|
||||
for quality_node in material_node.qualities.values():
|
||||
for intent_node in quality_node.intents.values():
|
||||
intent_metadatas.append(intent_node.getMetadata())
|
||||
|
@ -116,7 +122,7 @@ class IntentManager(QObject):
|
|||
## The intent that gets selected by default when no intent is available for
|
||||
# the configuration, an extruder can't match the intent that the user
|
||||
# selects, or just when creating a new printer.
|
||||
def getDefaultIntent(self) -> InstanceContainer:
|
||||
def getDefaultIntent(self) -> "InstanceContainer":
|
||||
return empty_intent_container
|
||||
|
||||
@pyqtProperty(str, notify = intentCategoryChanged)
|
||||
|
|
|
@ -28,20 +28,21 @@ if TYPE_CHECKING:
|
|||
class SettingInheritanceManager(QObject):
|
||||
def __init__(self, parent = None) -> None:
|
||||
super().__init__(parent)
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
|
||||
|
||||
self._global_container_stack = None # type: Optional[ContainerStack]
|
||||
self._settings_with_inheritance_warning = [] # type: List[str]
|
||||
self._active_container_stack = None # type: Optional[ExtruderStack]
|
||||
self._onGlobalContainerChanged()
|
||||
|
||||
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged)
|
||||
self._onActiveExtruderChanged()
|
||||
|
||||
self._update_timer = QTimer()
|
||||
self._update_timer.setInterval(500)
|
||||
self._update_timer.setSingleShot(True)
|
||||
self._update_timer.timeout.connect(self._update)
|
||||
|
||||
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
|
||||
ExtruderManager.getInstance().activeExtruderChanged.connect(self._onActiveExtruderChanged)
|
||||
self._onGlobalContainerChanged()
|
||||
self._onActiveExtruderChanged()
|
||||
|
||||
settingsWithIntheritanceChanged = pyqtSignal()
|
||||
|
||||
## Get the keys of all children settings with an override.
|
||||
|
@ -106,7 +107,7 @@ class SettingInheritanceManager(QObject):
|
|||
if self._active_container_stack is not None:
|
||||
self._active_container_stack.propertyChanged.connect(self._onPropertyChanged)
|
||||
self._active_container_stack.containersChanged.connect(self._onContainersChanged)
|
||||
self._update() # Ensure that the settings_with_inheritance_warning list is populated.
|
||||
self._update_timer.start() # Ensure that the settings_with_inheritance_warning list is populated.
|
||||
|
||||
def _onPropertyChanged(self, key: str, property_name: str) -> None:
|
||||
if (property_name == "value" or property_name == "enabled") and self._global_container_stack:
|
||||
|
|
|
@ -56,11 +56,11 @@ class CuraSplashScreen(QSplashScreen):
|
|||
if buildtype:
|
||||
version[0] += " (%s)" % buildtype
|
||||
|
||||
# draw version text
|
||||
# Draw version text
|
||||
font = QFont() # Using system-default font here
|
||||
font.setPixelSize(37)
|
||||
painter.setFont(font)
|
||||
painter.drawText(215, 66, 330 * self._scale, 230 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[0])
|
||||
painter.drawText(60, 66, 330 * self._scale, 230 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[0])
|
||||
if len(version) > 1:
|
||||
font.setPixelSize(16)
|
||||
painter.setFont(font)
|
||||
|
@ -68,14 +68,14 @@ class CuraSplashScreen(QSplashScreen):
|
|||
painter.drawText(247, 105, 330 * self._scale, 255 * self._scale, Qt.AlignLeft | Qt.AlignTop, version[1])
|
||||
painter.setPen(QColor(255, 255, 255, 255))
|
||||
|
||||
# draw the loading image
|
||||
# Draw the loading image
|
||||
pen = QPen()
|
||||
pen.setWidth(6 * self._scale)
|
||||
pen.setColor(QColor(32, 166, 219, 255))
|
||||
painter.setPen(pen)
|
||||
painter.drawArc(60, 150, 32 * self._scale, 32 * self._scale, self._loading_image_rotation_angle * 16, 300 * 16)
|
||||
|
||||
# draw message text
|
||||
# Draw message text
|
||||
if self._current_message:
|
||||
font = QFont() # Using system-default font here
|
||||
font.setPixelSize(13)
|
||||
|
|
|
@ -13,8 +13,8 @@ UM.Dialog
|
|||
id: base
|
||||
title: catalog.i18nc("@title:window", "Open Project")
|
||||
|
||||
minimumWidth: 500 * screenScaleFactor
|
||||
minimumHeight: 450 * screenScaleFactor
|
||||
minimumWidth: UM.Theme.getSize("popup_dialog").width
|
||||
minimumHeight: UM.Theme.getSize("popup_dialog").height
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ except ImportError:
|
|||
from . import ThreeMFWorkspaceReader
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Platform import Platform
|
||||
|
||||
catalog = i18nCatalog("cura")
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ Window
|
|||
minimumHeight: Math.round(UM.Theme.getSize("modal_window_minimum").height)
|
||||
maximumWidth: Math.round(minimumWidth * 1.2)
|
||||
maximumHeight: Math.round(minimumHeight * 1.2)
|
||||
modality: Qt.ApplicationModal
|
||||
width: minimumWidth
|
||||
height: minimumHeight
|
||||
color: UM.Theme.getColor("main_background")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import numpy
|
||||
|
@ -72,7 +72,7 @@ class GcodeStartEndFormatter(Formatter):
|
|||
value = default_value_str
|
||||
# "-1" is global stack, and if the setting value exists in the global stack, use it as the fallback value.
|
||||
if key in kwargs["-1"]:
|
||||
value = kwargs["-1"]
|
||||
value = kwargs["-1"][key]
|
||||
if str(extruder_nr) in kwargs and key in kwargs[str(extruder_nr)]:
|
||||
value = kwargs[str(extruder_nr)][key]
|
||||
|
||||
|
|
|
@ -143,6 +143,52 @@ UM.Dialog
|
|||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea {
|
||||
Layout.fillWidth:true
|
||||
height: childrenRect.height
|
||||
text: catalog.i18nc("@info:tooltip","For lithophanes a simple logarithmic model for translucency is available. For height maps the pixel values correspond to heights linearly.")
|
||||
Row {
|
||||
width: parent.width
|
||||
|
||||
Label {
|
||||
text: "Color Model"
|
||||
width: 150 * screenScaleFactor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
ComboBox {
|
||||
id: color_model
|
||||
objectName: "ColorModel"
|
||||
model: [ catalog.i18nc("@item:inlistbox","Linear"), catalog.i18nc("@item:inlistbox","Translucency") ]
|
||||
width: 180 * screenScaleFactor
|
||||
onCurrentIndexChanged: { manager.onColorModelChanged(currentIndex) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea {
|
||||
Layout.fillWidth:true
|
||||
height: childrenRect.height
|
||||
text: catalog.i18nc("@info:tooltip","The percentage of light penetrating a print with a thickness of 1 millimeter. Lowering this value increases the contrast in dark regions and decreases the contrast in light regions of the image.")
|
||||
visible: color_model.currentText == catalog.i18nc("@item:inlistbox","Translucency")
|
||||
Row {
|
||||
width: parent.width
|
||||
|
||||
Label {
|
||||
text: catalog.i18nc("@action:label", "1mm Transmittance (%)")
|
||||
width: 150 * screenScaleFactor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
TextField {
|
||||
id: transmittance
|
||||
objectName: "Transmittance"
|
||||
focus: true
|
||||
validator: RegExpValidator {regExp: /^[1-9]\d{0,2}([\,|\.]\d*)?$/}
|
||||
width: 180 * screenScaleFactor
|
||||
onTextChanged: { manager.onTransmittanceChanged(text) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UM.TooltipArea {
|
||||
Layout.fillWidth:true
|
||||
height: childrenRect.height
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
import numpy
|
||||
|
||||
import math
|
||||
|
||||
from PyQt5.QtGui import QImage, qRed, qGreen, qBlue
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
|
@ -46,9 +48,9 @@ class ImageReader(MeshReader):
|
|||
|
||||
def _read(self, file_name):
|
||||
size = max(self._ui.getWidth(), self._ui.getDepth())
|
||||
return self._generateSceneNode(file_name, size, self._ui.peak_height, self._ui.base_height, self._ui.smoothing, 512, self._ui.lighter_is_higher)
|
||||
return self._generateSceneNode(file_name, size, self._ui.peak_height, self._ui.base_height, self._ui.smoothing, 512, self._ui.lighter_is_higher, self._ui.use_transparency_model, self._ui.transmittance_1mm)
|
||||
|
||||
def _generateSceneNode(self, file_name, xz_size, peak_height, base_height, blur_iterations, max_size, lighter_is_higher):
|
||||
def _generateSceneNode(self, file_name, xz_size, peak_height, base_height, blur_iterations, max_size, lighter_is_higher, use_transparency_model, transmittance_1mm):
|
||||
scene_node = SceneNode()
|
||||
|
||||
mesh = MeshBuilder()
|
||||
|
@ -99,12 +101,14 @@ class ImageReader(MeshReader):
|
|||
for x in range(0, width):
|
||||
for y in range(0, height):
|
||||
qrgb = img.pixel(x, y)
|
||||
avg = float(qRed(qrgb) + qGreen(qrgb) + qBlue(qrgb)) / (3 * 255)
|
||||
height_data[y, x] = avg
|
||||
if use_transparency_model:
|
||||
height_data[y, x] = (0.299 * math.pow(qRed(qrgb) / 255.0, 2.2) + 0.587 * math.pow(qGreen(qrgb) / 255.0, 2.2) + 0.114 * math.pow(qBlue(qrgb) / 255.0, 2.2))
|
||||
else:
|
||||
height_data[y, x] = (0.212655 * qRed(qrgb) + 0.715158 * qGreen(qrgb) + 0.072187 * qBlue(qrgb)) / 255 # fast computation ignoring gamma and degamma
|
||||
|
||||
Job.yieldThread()
|
||||
|
||||
if not lighter_is_higher:
|
||||
if lighter_is_higher == use_transparency_model:
|
||||
height_data = 1 - height_data
|
||||
|
||||
for _ in range(0, blur_iterations):
|
||||
|
@ -124,6 +128,13 @@ class ImageReader(MeshReader):
|
|||
|
||||
Job.yieldThread()
|
||||
|
||||
if use_transparency_model:
|
||||
divisor = 1.0 / math.log(transmittance_1mm / 100.0) # log-base doesn't matter here. Precompute this value for faster computation of each pixel.
|
||||
min_luminance = (transmittance_1mm / 100.0) ** (peak_height - base_height)
|
||||
for (y, x) in numpy.ndindex(height_data.shape):
|
||||
mapped_luminance = min_luminance + (1.0 - min_luminance) * height_data[y, x]
|
||||
height_data[y, x] = base_height + divisor * math.log(mapped_luminance) # use same base as a couple lines above this
|
||||
else:
|
||||
height_data *= scale_vector.y
|
||||
height_data += base_height
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@ class ImageReaderUI(QObject):
|
|||
self.peak_height = 2.5
|
||||
self.smoothing = 1
|
||||
self.lighter_is_higher = False;
|
||||
self.use_transparency_model = True;
|
||||
self.transmittance_1mm = 50.0; # based on pearl PLA
|
||||
|
||||
self._ui_lock = threading.Lock()
|
||||
self._cancelled = False
|
||||
|
@ -75,6 +77,7 @@ class ImageReaderUI(QObject):
|
|||
|
||||
self._ui_view.findChild(QObject, "Base_Height").setProperty("text", str(self.base_height))
|
||||
self._ui_view.findChild(QObject, "Peak_Height").setProperty("text", str(self.peak_height))
|
||||
self._ui_view.findChild(QObject, "Transmittance").setProperty("text", str(self.transmittance_1mm))
|
||||
self._ui_view.findChild(QObject, "Smoothing").setProperty("value", self.smoothing)
|
||||
|
||||
def _createConfigUI(self):
|
||||
|
@ -144,3 +147,11 @@ class ImageReaderUI(QObject):
|
|||
@pyqtSlot(int)
|
||||
def onImageColorInvertChanged(self, value):
|
||||
self.lighter_is_higher = (value == 1)
|
||||
|
||||
@pyqtSlot(int)
|
||||
def onColorModelChanged(self, value):
|
||||
self.use_transparency_model = (value == 0)
|
||||
|
||||
@pyqtSlot(int)
|
||||
def onTransmittanceChanged(self, value):
|
||||
self.transmittance_1mm = value
|
||||
|
|
|
@ -157,7 +157,7 @@ class LegacyProfileReader(ProfileReader):
|
|||
data = stream.getvalue()
|
||||
|
||||
profile = InstanceContainer(profile_id)
|
||||
profile.deserialize(data) # Also performs the version upgrade.
|
||||
profile.deserialize(data, file_name) # Also performs the version upgrade.
|
||||
profile.setDirty(True)
|
||||
|
||||
#We need to return one extruder stack and one global stack.
|
||||
|
|
|
@ -5,7 +5,6 @@ import configparser # An input for some functions we're testing.
|
|||
import os.path # To find the integration test .ini files.
|
||||
import pytest # To register tests with.
|
||||
import unittest.mock # To mock the application, plug-in and container registry out.
|
||||
import os.path
|
||||
import sys
|
||||
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
|
||||
|
||||
|
@ -16,6 +15,7 @@ import UM.Settings.InstanceContainer # To intercept the serialised data from the
|
|||
|
||||
import LegacyProfileReader as LegacyProfileReaderModule # To get the directory of the module.
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def legacy_profile_reader():
|
||||
try:
|
||||
|
@ -162,7 +162,7 @@ def test_read(legacy_profile_reader, file_name):
|
|||
plugin_registry.getPluginPath = unittest.mock.MagicMock(return_value = os.path.dirname(LegacyProfileReaderModule.__file__))
|
||||
|
||||
# Mock out the resulting InstanceContainer so that we can intercept the data before it's passed through the version upgrader.
|
||||
def deserialize(self, data): # Intercepts the serialised data that we'd perform the version upgrade from when deserializing.
|
||||
def deserialize(self, data, filename): # Intercepts the serialised data that we'd perform the version upgrade from when deserializing.
|
||||
global intercepted_data
|
||||
intercepted_data = data
|
||||
|
||||
|
|
|
@ -87,9 +87,25 @@ Cura.MachineAction
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: machineNameLabel
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
text: Cura.MachineManager.activeMachine.name
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font: UM.Theme.getFont("large_bold")
|
||||
color: UM.Theme.getColor("text")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
UM.TabRow
|
||||
{
|
||||
id: tabBar
|
||||
anchors.top: machineNameLabel.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
Repeater
|
||||
{
|
||||
|
|
|
@ -331,6 +331,18 @@ Item
|
|||
onGlobalContainerChanged: extruderCountModel.update()
|
||||
}
|
||||
}
|
||||
|
||||
Cura.SimpleCheckBox // "Shared Heater"
|
||||
{
|
||||
id: sharedHeaterCheckBox
|
||||
containerStackId: machineStackId
|
||||
settingKey: "machine_extruders_share_heater"
|
||||
settingStoreIndex: propertyStoreIndex
|
||||
labelText: catalog.i18nc("@label", "Shared Heater")
|
||||
labelFont: base.labelFont
|
||||
labelWidth: base.labelWidth
|
||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal
|
||||
from PyQt5.QtCore import pyqtProperty
|
||||
from UM.FlameProfiler import pyqtSlot
|
||||
|
||||
from UM.Application import Application
|
||||
|
@ -13,6 +13,7 @@ import UM.Settings.Models.SettingVisibilityHandler
|
|||
from cura.Settings.ExtruderManager import ExtruderManager #To get global-inherits-stack setting values from different extruders.
|
||||
from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
|
||||
|
||||
|
||||
## The per object setting visibility handler ensures that only setting
|
||||
# definitions that have a matching instance Container are returned as visible.
|
||||
class PerObjectSettingVisibilityHandler(UM.Settings.Models.SettingVisibilityHandler.SettingVisibilityHandler):
|
||||
|
|
|
@ -12,14 +12,18 @@ import Cura 1.0 as Cura
|
|||
Item
|
||||
{
|
||||
|
||||
// An Item whose bounds are guaranteed to be safe for overlays to be placed.
|
||||
// Defaults to parent, ie. the entire available area
|
||||
property var safeArea: parent
|
||||
|
||||
// Subtract the actionPanel from the safe area. This way the view won't draw interface elements under/over it
|
||||
Item {
|
||||
id: safeArea
|
||||
visible: false
|
||||
anchors.left: parent.left
|
||||
anchors.right: actionPanelWidget.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: actionPanelWidget.top
|
||||
Item
|
||||
{
|
||||
id: childSafeArea
|
||||
x: safeArea.x - parent.x
|
||||
y: safeArea.y - parent.y
|
||||
width: actionPanelWidget.x - x
|
||||
height: actionPanelWidget.y - y
|
||||
}
|
||||
|
||||
Loader
|
||||
|
@ -29,9 +33,10 @@ Item
|
|||
|
||||
source: UM.Controller.activeView != null && UM.Controller.activeView.mainComponent != null ? UM.Controller.activeView.mainComponent : ""
|
||||
|
||||
onLoaded: {
|
||||
onLoaded:
|
||||
{
|
||||
if (previewMain.item.safeArea !== undefined){
|
||||
previewMain.item.safeArea = Qt.binding(function() { return safeArea });
|
||||
previewMain.item.safeArea = Qt.binding(function() { return childSafeArea });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,9 +48,13 @@ class WindowsRemovableDrivePlugin(RemovableDrivePlugin.RemovableDrivePlugin):
|
|||
drives = {}
|
||||
|
||||
bitmask = ctypes.windll.kernel32.GetLogicalDrives()
|
||||
# Check possible drive letters, from A to Z
|
||||
# Check possible drive letters, from C to Z
|
||||
# Note: using ascii_uppercase because we do not want this to change with locale!
|
||||
for letter in string.ascii_uppercase:
|
||||
# Skip A and B, since those drives are typically reserved for floppy disks.
|
||||
# Those drives can theoretically be reassigned but it's safer to not check them for removable drives.
|
||||
# Windows will also behave weirdly even with some of its internal functions if you do this (e.g. search indexing doesn't search it).
|
||||
# Users that have removable drives in A or B will just have to save to file and select the drive there.
|
||||
for letter in string.ascii_uppercase[2:]:
|
||||
drive = "{0}:/".format(letter)
|
||||
|
||||
# Do we really want to skip A and B?
|
||||
|
|
|
@ -155,30 +155,19 @@ Item
|
|||
}
|
||||
|
||||
onPositionChanged: parent.onHandleDragged()
|
||||
onPressed: sliderRoot.setActiveHandle(rangeHandle)
|
||||
}
|
||||
|
||||
SimulationSliderLabel
|
||||
onPressed:
|
||||
{
|
||||
id: rangleHandleLabel
|
||||
|
||||
height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
|
||||
x: parent.x - width - UM.Theme.getSize("default_margin").width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
target: Qt.point(sliderRoot.width, y + height / 2)
|
||||
visible: sliderRoot.activeHandle == parent
|
||||
|
||||
// custom properties
|
||||
maximumValue: sliderRoot.maximumValue
|
||||
value: sliderRoot.upperValue
|
||||
busy: UM.SimulationView.busy
|
||||
setValue: rangeHandle.setValueManually // connect callback functions
|
||||
sliderRoot.setActiveHandle(rangeHandle)
|
||||
sliderRoot.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onHeightChanged : {
|
||||
// After a height change, the pixel-position of the lower handle is out of sync with the property value
|
||||
// After a height change, the pixel-position of the handles is out of sync with the property value
|
||||
setLowerValue(lowerValue)
|
||||
setUpperValue(upperValue)
|
||||
}
|
||||
|
||||
// Upper handle
|
||||
|
@ -275,11 +264,12 @@ Item
|
|||
{
|
||||
id: upperHandleLabel
|
||||
|
||||
height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
|
||||
x: parent.x - parent.width - width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
target: Qt.point(sliderRoot.width, y + height / 2)
|
||||
visible: sliderRoot.activeHandle == parent
|
||||
height: sliderRoot.handleSize
|
||||
anchors.bottom: parent.top
|
||||
anchors.bottomMargin: UM.Theme.getSize("narrow_margin").height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
target: Qt.point(parent.width / 2, parent.top)
|
||||
visible: sliderRoot.activeHandle == parent || sliderRoot.activeHandle == rangeHandle
|
||||
|
||||
// custom properties
|
||||
maximumValue: sliderRoot.maximumValue
|
||||
|
@ -384,11 +374,12 @@ Item
|
|||
{
|
||||
id: lowerHandleLabel
|
||||
|
||||
height: sliderRoot.handleSize + UM.Theme.getSize("default_margin").height
|
||||
x: parent.x - parent.width - width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
target: Qt.point(sliderRoot.width + width, y + height / 2)
|
||||
visible: sliderRoot.activeHandle == parent
|
||||
height: sliderRoot.handleSize
|
||||
anchors.top: parent.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("narrow_margin").height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
target: Qt.point(parent.width / 2, parent.bottom)
|
||||
visible: sliderRoot.activeHandle == parent || sliderRoot.activeHandle == rangeHandle
|
||||
|
||||
// custom properties
|
||||
maximumValue: sliderRoot.maximumValue
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
from UM.Application import Application
|
||||
from UM.Math.Color import Color
|
||||
from UM.Math.Vector import Vector
|
||||
from UM.PluginRegistry import PluginRegistry
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
from UM.View.GL.OpenGL import OpenGL
|
||||
|
|
|
@ -56,6 +56,11 @@ Item
|
|||
return Math.min(Math.max(value, sliderRoot.minimumValue), sliderRoot.maximumValue)
|
||||
}
|
||||
|
||||
onWidthChanged : {
|
||||
// After a width change, the pixel-position of the handle is out of sync with the property value
|
||||
setHandleValue(handleValue)
|
||||
}
|
||||
|
||||
// slider track
|
||||
Rectangle
|
||||
{
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) 2017 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls.Styles 1.1
|
||||
|
@ -20,9 +19,9 @@ UM.PointingRectangle {
|
|||
property int startFrom: 1
|
||||
|
||||
target: Qt.point(parent.width, y + height / 2)
|
||||
arrowSize: UM.Theme.getSize("default_arrow").width
|
||||
arrowSize: UM.Theme.getSize("button_tooltip_arrow").height
|
||||
height: parent.height
|
||||
width: valueLabel.width + UM.Theme.getSize("default_margin").width
|
||||
width: valueLabel.width
|
||||
visible: false
|
||||
|
||||
color: UM.Theme.getColor("tool_panel_background")
|
||||
|
@ -40,25 +39,34 @@ UM.PointingRectangle {
|
|||
anchors.fill: parent
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: maxValueMetrics
|
||||
font: valueLabel.font
|
||||
text: maximumValue + 1 // layers are 0 based, add 1 for display value
|
||||
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: valueLabel
|
||||
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
alignWhenCentered: false
|
||||
}
|
||||
|
||||
width: ((maximumValue + 1).toString().length + 1) * 10 * screenScaleFactor
|
||||
width: maxValueMetrics.width + UM.Theme.getSize("default_margin").width
|
||||
text: sliderLabelRoot.value + startFrom // the current handle value, add 1 because layers is an array
|
||||
horizontalAlignment: TextInput.AlignRight
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
|
||||
// key bindings, work when label is currenctly focused (active handle in LayerSlider)
|
||||
Keys.onUpPressed: sliderLabelRoot.setValue(sliderLabelRoot.value + ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
|
||||
Keys.onDownPressed: sliderLabelRoot.setValue(sliderLabelRoot.value - ((event.modifiers & Qt.ShiftModifier) ? 10 : 1))
|
||||
|
||||
style: TextFieldStyle {
|
||||
textColor: UM.Theme.getColor("setting_control_text")
|
||||
textColor: UM.Theme.getColor("text")
|
||||
font: UM.Theme.getFont("default")
|
||||
renderType: Text.NativeRendering
|
||||
background: Item { }
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,8 @@ class SimulationView(CuraView):
|
|||
def beginRendering(self) -> None:
|
||||
scene = self.getController().getScene()
|
||||
renderer = self.getRenderer()
|
||||
if renderer is None:
|
||||
return
|
||||
|
||||
if not self._ghost_shader:
|
||||
self._ghost_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader"))
|
||||
|
@ -490,7 +492,11 @@ class SimulationView(CuraView):
|
|||
|
||||
# Make sure the SimulationPass is created
|
||||
layer_pass = self.getSimulationPass()
|
||||
self.getRenderer().addRenderPass(layer_pass)
|
||||
renderer = self.getRenderer()
|
||||
if renderer is None:
|
||||
return False
|
||||
|
||||
renderer.addRenderPass(layer_pass)
|
||||
|
||||
# Make sure the NozzleNode is add to the root
|
||||
nozzle = self.getNozzleNode()
|
||||
|
@ -509,7 +515,7 @@ class SimulationView(CuraView):
|
|||
self._simulationview_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))
|
||||
|
||||
if not self._composite_pass:
|
||||
self._composite_pass = cast(CompositePass, self.getRenderer().getRenderPass("composite"))
|
||||
self._composite_pass = cast(CompositePass, renderer.getRenderPass("composite"))
|
||||
|
||||
self._old_layer_bindings = self._composite_pass.getLayerBindings()[:] # make a copy so we can restore to it later
|
||||
self._composite_pass.getLayerBindings().append("simulationview")
|
||||
|
@ -525,7 +531,13 @@ class SimulationView(CuraView):
|
|||
self._global_container_stack.propertyChanged.disconnect(self._onPropertyChanged)
|
||||
if self._nozzle_node:
|
||||
self._nozzle_node.setParent(None)
|
||||
self.getRenderer().removeRenderPass(self._layer_pass)
|
||||
|
||||
renderer = self.getRenderer()
|
||||
if renderer is None:
|
||||
return False
|
||||
|
||||
if self._layer_pass is not None:
|
||||
renderer.removeRenderPass(self._layer_pass)
|
||||
if self._composite_pass:
|
||||
self._composite_pass.setLayerBindings(cast(List[str], self._old_layer_bindings))
|
||||
self._composite_pass.setCompositeShader(cast(ShaderProgram, self._old_composite_shader))
|
||||
|
|
|
@ -18,7 +18,10 @@ Item
|
|||
|
||||
|
||||
property bool isSimulationPlaying: false
|
||||
readonly property var layerSliderSafeYMax: safeArea.y + safeArea.height
|
||||
readonly property real layerSliderSafeYMin: safeArea.y
|
||||
readonly property real layerSliderSafeYMax: safeArea.y + safeArea.height
|
||||
readonly property real pathSliderSafeXMin: safeArea.x + playButton.width
|
||||
readonly property real pathSliderSafeXMax: safeArea.x + safeArea.width
|
||||
|
||||
visible: UM.SimulationView.layerActivity && CuraApplication.platformActivity
|
||||
|
||||
|
@ -26,13 +29,21 @@ Item
|
|||
PathSlider
|
||||
{
|
||||
id: pathSlider
|
||||
|
||||
readonly property real preferredWidth: UM.Theme.getSize("slider_layerview_size").height // not a typo, should be as long as layerview slider
|
||||
readonly property real margin: UM.Theme.getSize("default_margin").width
|
||||
readonly property real pathSliderSafeWidth: pathSliderSafeXMax - pathSliderSafeXMin
|
||||
|
||||
height: UM.Theme.getSize("slider_handle").width
|
||||
width: UM.Theme.getSize("slider_layerview_size").height
|
||||
width: preferredWidth + margin * 2 < pathSliderSafeWidth ? preferredWidth : pathSliderSafeWidth - margin * 2
|
||||
|
||||
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
|
||||
anchors.bottomMargin: margin
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.horizontalCenterOffset: -(parent.width - pathSliderSafeXMax - pathSliderSafeXMin) / 2 // center between parent top and layerSliderSafeYMax
|
||||
|
||||
|
||||
visible: !UM.SimulationView.compatibilityMode
|
||||
|
||||
|
@ -183,17 +194,19 @@ Item
|
|||
LayerSlider
|
||||
{
|
||||
property var preferredHeight: UM.Theme.getSize("slider_layerview_size").height
|
||||
property double heightMargin: UM.Theme.getSize("default_margin").height
|
||||
property double heightMargin: UM.Theme.getSize("default_margin").height * 3 // extra margin to accomodate layer number tooltips
|
||||
property double layerSliderSafeHeight: layerSliderSafeYMax - layerSliderSafeYMin
|
||||
|
||||
id: layerSlider
|
||||
|
||||
width: UM.Theme.getSize("slider_handle").width
|
||||
height: preferredHeight + heightMargin * 2 < layerSliderSafeYMax ? preferredHeight : layerSliderSafeYMax - heightMargin * 2
|
||||
height: preferredHeight + heightMargin * 2 < layerSliderSafeHeight ? preferredHeight : layerSliderSafeHeight - heightMargin * 2
|
||||
|
||||
anchors
|
||||
{
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
verticalCenterOffset: -(parent.height - layerSliderSafeYMax) / 2 // center between parent top and layerSliderSafeYMax
|
||||
verticalCenterOffset: -(parent.height - layerSliderSafeYMax - layerSliderSafeYMin) / 2 // center between parent top and layerSliderSafeYMax
|
||||
rightMargin: UM.Theme.getSize("default_margin").width
|
||||
bottomMargin: heightMargin
|
||||
topMargin: heightMargin
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Toolbox is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
// Main window for the Toolbox
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Dialogs 1.1
|
||||
import QtQuick.Window 2.2
|
||||
import UM 1.1 as UM
|
||||
|
||||
import "./pages"
|
||||
import "./dialogs"
|
||||
import "./components"
|
||||
|
||||
Window
|
||||
{
|
||||
id: base
|
||||
|
@ -14,8 +20,8 @@ Window
|
|||
modality: Qt.ApplicationModal
|
||||
flags: Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint
|
||||
|
||||
width: Math.floor(720 * screenScaleFactor)
|
||||
height: Math.floor(640 * screenScaleFactor)
|
||||
width: UM.Theme.getSize("large_popup_dialog").width
|
||||
height: UM.Theme.getSize("large_popup_dialog").height
|
||||
minimumWidth: width
|
||||
maximumWidth: minimumWidth
|
||||
minimumHeight: height
|
||||
|
@ -29,9 +35,16 @@ Window
|
|||
Item
|
||||
{
|
||||
anchors.fill: parent
|
||||
|
||||
WelcomePage
|
||||
{
|
||||
visible: toolbox.viewPage === "welcome"
|
||||
}
|
||||
|
||||
ToolboxHeader
|
||||
{
|
||||
id: header
|
||||
visible: toolbox.viewPage !== "welcome"
|
||||
}
|
||||
|
||||
Item
|
||||
|
|
|
@ -67,7 +67,7 @@ Item
|
|||
width: UM.Theme.getSize("toolbox_thumbnail_small").width - UM.Theme.getSize("wide_margin").width
|
||||
height: UM.Theme.getSize("toolbox_thumbnail_small").height - UM.Theme.getSize("wide_margin").width
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: model.icon_url || "../images/logobot.svg"
|
||||
source: model.icon_url || "../../images/logobot.svg"
|
||||
mipmap: true
|
||||
}
|
||||
UM.RecolorImage
|
||||
|
@ -82,7 +82,7 @@ Item
|
|||
sourceSize.height: height
|
||||
visible: installedPackages != 0
|
||||
color: (installedPackages >= packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border")
|
||||
source: "../images/installed_check.svg"
|
||||
source: "../../images/installed_check.svg"
|
||||
}
|
||||
}
|
||||
Item
|
|
@ -23,7 +23,7 @@ Rectangle
|
|||
height: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height
|
||||
width: UM.Theme.getSize("toolbox_thumbnail_large").height - 4 * UM.Theme.getSize("default_margin").height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: model.icon_url || "../images/logobot.svg"
|
||||
source: model.icon_url || "../../images/logobot.svg"
|
||||
mipmap: true
|
||||
anchors
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ Rectangle
|
|||
}
|
||||
visible: installedPackages != 0
|
||||
color: (installedPackages >= packageCount) ? UM.Theme.getColor("primary") : UM.Theme.getColor("border")
|
||||
source: "../images/installed_check.svg"
|
||||
source: "../../images/installed_check.svg"
|
||||
}
|
||||
|
||||
SmallRatingWidget
|
|
@ -14,7 +14,7 @@ import Cura 1.0 as Cura
|
|||
|
||||
UM.Dialog
|
||||
{
|
||||
// This dialog asks the user whether he/she wants to open a project file as a project or import models.
|
||||
// This dialog asks the user to confirm he/she wants to uninstall materials/pprofiles which are currently in use
|
||||
id: base
|
||||
|
||||
title: catalog.i18nc("@title:window", "Confirm uninstall") + toolbox.pluginToUninstall
|
|
@ -6,6 +6,8 @@ import QtQuick.Controls 1.4
|
|||
import QtQuick.Controls.Styles 1.4
|
||||
import UM 1.1 as UM
|
||||
|
||||
import "../components"
|
||||
|
||||
Item
|
||||
{
|
||||
id: page
|
||||
|
@ -31,7 +33,7 @@ Item
|
|||
width: UM.Theme.getSize("toolbox_thumbnail_medium").width
|
||||
height: UM.Theme.getSize("toolbox_thumbnail_medium").height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: details.icon_url || "../images/logobot.svg"
|
||||
source: details.icon_url || "../../images/logobot.svg"
|
||||
mipmap: true
|
||||
anchors
|
||||
{
|
|
@ -8,6 +8,8 @@ import UM 1.1 as UM
|
|||
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
import "../components"
|
||||
|
||||
Item
|
||||
{
|
||||
id: page
|
||||
|
@ -44,7 +46,7 @@ Item
|
|||
{
|
||||
anchors.fill: parent
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: details === null ? "" : (details.icon_url || "../images/logobot.svg")
|
||||
source: details === null ? "" : (details.icon_url || "../../images/logobot.svg")
|
||||
mipmap: true
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ import QtQuick 2.10
|
|||
import QtQuick.Controls 2.3
|
||||
import UM 1.1 as UM
|
||||
|
||||
import "../components"
|
||||
|
||||
ScrollView
|
||||
{
|
||||
clip: true
|
|
@ -6,6 +6,8 @@ import QtQuick.Controls 2.3
|
|||
|
||||
import UM 1.1 as UM
|
||||
|
||||
import "../components"
|
||||
|
||||
ScrollView
|
||||
{
|
||||
id: page
|
53
plugins/Toolbox/resources/qml/pages/WelcomePage.qml
Normal file
53
plugins/Toolbox/resources/qml/pages/WelcomePage.qml
Normal file
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Window 2.2
|
||||
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
Column
|
||||
{
|
||||
id: welcomePage
|
||||
spacing: UM.Theme.getSize("wide_margin").height
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
anchors.centerIn: parent
|
||||
|
||||
Image
|
||||
{
|
||||
id: profileImage
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "../../images/logobot.svg"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: Math.round(parent.width / 4)
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: welcomeTextLabel
|
||||
text: catalog.i18nc("@description", "Get plugins and materials verified by Ultimaker")
|
||||
width: Math.round(parent.width / 2)
|
||||
font: UM.Theme.getFont("default")
|
||||
color: UM.Theme.getColor("text")
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
wrapMode: Label.WordWrap
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Cura.PrimaryButton
|
||||
{
|
||||
id: loginButton
|
||||
width: UM.Theme.getSize("account_button").width
|
||||
height: UM.Theme.getSize("account_button").height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: catalog.i18nc("@button", "Sign in")
|
||||
onClicked: Cura.API.account.login()
|
||||
fixedWidthMode: true
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import re
|
||||
from typing import Dict
|
||||
from PyQt5.QtCore import Qt, pyqtProperty
|
||||
from UM.Qt.ListModel import ListModel
|
||||
|
||||
|
||||
## Model that holds supported configurations (for material/quality packages).
|
||||
class ConfigsModel(ListModel):
|
||||
def __init__(self, parent = None):
|
||||
|
|
|
@ -59,13 +59,15 @@ class Toolbox(QObject, Extension):
|
|||
# The responses as given by the server parsed to a list.
|
||||
self._server_response_data = {
|
||||
"authors": [],
|
||||
"packages": []
|
||||
"packages": [],
|
||||
"updates": [],
|
||||
} # type: Dict[str, List[Any]]
|
||||
|
||||
# Models:
|
||||
self._models = {
|
||||
"authors": AuthorsModel(self),
|
||||
"packages": PackagesModel(self),
|
||||
"updates": PackagesModel(self),
|
||||
} # type: Dict[str, Union[AuthorsModel, PackagesModel]]
|
||||
|
||||
self._plugins_showcase_model = PackagesModel(self)
|
||||
|
@ -86,7 +88,7 @@ class Toolbox(QObject, Extension):
|
|||
|
||||
# View page defines which type of page layout to use. For example,
|
||||
# possible values include "overview", "detail" or "author".
|
||||
self._view_page = "loading" # type: str
|
||||
self._view_page = "welcome" # type: str
|
||||
|
||||
# Active package refers to which package is currently being downloaded,
|
||||
# installed, or otherwise modified.
|
||||
|
@ -105,7 +107,6 @@ class Toolbox(QObject, Extension):
|
|||
self._restart_dialog_message = "" # type: str
|
||||
|
||||
self._application.initializationFinished.connect(self._onAppInitialized)
|
||||
self._application.getCuraAPI().account.loginStateChanged.connect(self._updateRequestHeader)
|
||||
self._application.getCuraAPI().account.accessTokenChanged.connect(self._updateRequestHeader)
|
||||
|
||||
# Signals:
|
||||
|
@ -126,6 +127,16 @@ class Toolbox(QObject, Extension):
|
|||
showLicenseDialog = pyqtSignal()
|
||||
uninstallVariablesChanged = pyqtSignal()
|
||||
|
||||
## Go back to the start state (welcome screen or loading if no login required)
|
||||
def _restart(self):
|
||||
self._updateRequestHeader()
|
||||
# For an Essentials build, login is mandatory
|
||||
if not self._application.getCuraAPI().account.isLoggedIn and ApplicationMetadata.IsEnterpriseVersion:
|
||||
self.setViewPage("welcome")
|
||||
else:
|
||||
self.setViewPage("loading")
|
||||
self._fetchPackageData()
|
||||
|
||||
def _updateRequestHeader(self):
|
||||
self._request_headers = [
|
||||
(b"User-Agent",
|
||||
|
@ -186,18 +197,27 @@ class Toolbox(QObject, Extension):
|
|||
cloud_api_version = self._cloud_api_version,
|
||||
sdk_version = self._sdk_version
|
||||
)
|
||||
|
||||
# We need to construct a query like installed_packages=ID:VERSION&installed_packages=ID:VERSION, etc.
|
||||
installed_package_ids_with_versions = [":".join(items) for items in
|
||||
self._package_manager.getAllInstalledPackageIdsAndVersions()]
|
||||
installed_packages_query = "&installed_packages=".join(installed_package_ids_with_versions)
|
||||
|
||||
self._request_urls = {
|
||||
"authors": QUrl("{base_url}/authors".format(base_url = self._api_url)),
|
||||
"packages": QUrl("{base_url}/packages".format(base_url = self._api_url))
|
||||
"packages": QUrl("{base_url}/packages".format(base_url = self._api_url)),
|
||||
"updates": QUrl("{base_url}/packages/package-updates?installed_packages={query}".format(
|
||||
base_url = self._api_url, query = installed_packages_query))
|
||||
}
|
||||
|
||||
# Request the latest and greatest!
|
||||
self._fetchPackageData()
|
||||
self._application.getCuraAPI().account.loginStateChanged.connect(self._restart)
|
||||
|
||||
def _fetchPackageData(self):
|
||||
# Create the network manager:
|
||||
# This was formerly its own function but really had no reason to be as
|
||||
# it was never called more than once ever.
|
||||
# On boot we check which packages have updates.
|
||||
if CuraApplication.getInstance().getPreferences().getValue("info/automatic_update_check") and len(installed_package_ids_with_versions) > 0:
|
||||
# Request the latest and greatest!
|
||||
self._fetchPackageUpdates()
|
||||
|
||||
def _prepareNetworkManager(self):
|
||||
if self._network_manager is not None:
|
||||
self._network_manager.finished.disconnect(self._onRequestFinished)
|
||||
self._network_manager.networkAccessibleChanged.disconnect(self._onNetworkAccessibleChanged)
|
||||
|
@ -205,16 +225,21 @@ class Toolbox(QObject, Extension):
|
|||
self._network_manager.finished.connect(self._onRequestFinished)
|
||||
self._network_manager.networkAccessibleChanged.connect(self._onNetworkAccessibleChanged)
|
||||
|
||||
def _fetchPackageUpdates(self):
|
||||
self._prepareNetworkManager()
|
||||
self._makeRequestByType("updates")
|
||||
|
||||
def _fetchPackageData(self):
|
||||
self._prepareNetworkManager()
|
||||
# Make remote requests:
|
||||
self._makeRequestByType("packages")
|
||||
self._makeRequestByType("authors")
|
||||
|
||||
# Gather installed packages:
|
||||
self._updateInstalledModels()
|
||||
|
||||
# Displays the toolbox
|
||||
@pyqtSlot()
|
||||
def browsePackages(self) -> None:
|
||||
self._fetchPackageData()
|
||||
def launch(self) -> None:
|
||||
|
||||
if not self._dialog:
|
||||
self._dialog = self._createDialog("Toolbox.qml")
|
||||
|
@ -223,6 +248,8 @@ class Toolbox(QObject, Extension):
|
|||
Logger.log("e", "Unexpected error trying to create the 'Marketplace' dialog.")
|
||||
return
|
||||
|
||||
self._restart()
|
||||
|
||||
self._dialog.show()
|
||||
|
||||
# Apply enabled/disabled state to installed plugins
|
||||
|
@ -328,7 +355,7 @@ class Toolbox(QObject, Extension):
|
|||
self._package_used_qualities = package_used_qualities
|
||||
# Ask change to default material / profile
|
||||
if self._confirm_reset_dialog is None:
|
||||
self._confirm_reset_dialog = self._createDialog("ToolboxConfirmUninstallResetDialog.qml")
|
||||
self._confirm_reset_dialog = self._createDialog("dialogs/ToolboxConfirmUninstallResetDialog.qml")
|
||||
self.uninstallVariablesChanged.emit()
|
||||
if self._confirm_reset_dialog is None:
|
||||
Logger.log("e", "ToolboxConfirmUninstallResetDialog should have been initialized, but it is not. Not showing dialog and not uninstalling package.")
|
||||
|
@ -630,6 +657,10 @@ class Toolbox(QObject, Extension):
|
|||
elif response_type == "authors":
|
||||
self._models[response_type].setFilter({"package_types": "material"})
|
||||
self._models[response_type].setFilter({"tags": "generic"})
|
||||
elif response_type == "updates":
|
||||
# Tell the package manager that there's a new set of updates available.
|
||||
packages = set([pkg["package_id"] for pkg in self._server_response_data[response_type]])
|
||||
self._package_manager.setPackagesWithUpdate(packages)
|
||||
|
||||
self.metadataChanged.emit()
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ from cura.Settings.GlobalStack import GlobalStack
|
|||
from .CloudApiClient import CloudApiClient
|
||||
from .CloudOutputDevice import CloudOutputDevice
|
||||
from ..Models.Http.CloudClusterResponse import CloudClusterResponse
|
||||
from ..Messages.CloudPrinterDetectedMessage import CloudPrinterDetectedMessage
|
||||
|
||||
|
||||
## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters.
|
||||
|
@ -111,7 +110,6 @@ class CloudOutputDeviceManager:
|
|||
)
|
||||
self._remote_clusters[device.getId()] = device
|
||||
self.discoveredDevicesChanged.emit()
|
||||
self._checkIfNewClusterWasAdded(device.clusterData.cluster_id)
|
||||
self._connectToActiveMachine()
|
||||
|
||||
def _onDiscoveredDeviceUpdated(self, cluster_data: CloudClusterResponse) -> None:
|
||||
|
@ -184,10 +182,3 @@ class CloudOutputDeviceManager:
|
|||
output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
|
||||
if device.key not in output_device_manager.getOutputDeviceIds():
|
||||
output_device_manager.addOutputDevice(device)
|
||||
|
||||
## Checks if Cura has a machine stack (printer) for the given cluster ID and shows a message if it hasn't.
|
||||
def _checkIfNewClusterWasAdded(self, cluster_id: str) -> None:
|
||||
container_registry = CuraApplication.getInstance().getContainerRegistry()
|
||||
cloud_machines = container_registry.findContainersMetadata(**{self.META_CLUSTER_ID: "*"}) # all cloud machines
|
||||
if not any(machine[self.META_CLUSTER_ID] == cluster_id for machine in cloud_machines):
|
||||
CloudPrinterDetectedMessage().show()
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
# Copyright (c) 2019 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from UM import i18nCatalog
|
||||
from UM.Message import Message
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
||||
I18N_CATALOG = i18nCatalog("cura")
|
||||
|
||||
|
||||
## Message shown when a new printer was added to your account but not yet in Cura.
|
||||
class CloudPrinterDetectedMessage(Message):
|
||||
|
||||
# Singleton used to prevent duplicate messages of this type at the same time.
|
||||
__is_visible = False
|
||||
|
||||
# Store in preferences to hide this message in the future.
|
||||
_preference_key = "cloud/block_new_printers_popup"
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(
|
||||
title=I18N_CATALOG.i18nc("@info:title", "New cloud printers found"),
|
||||
text=I18N_CATALOG.i18nc("@info:message", "New printers have been found connected to your account, "
|
||||
"you can find them in your list of discovered printers."),
|
||||
lifetime=0,
|
||||
dismissable=True,
|
||||
option_state=False,
|
||||
option_text=I18N_CATALOG.i18nc("@info:option_text", "Do not show this message again")
|
||||
)
|
||||
self.optionToggled.connect(self._onDontAskMeAgain)
|
||||
CuraApplication.getInstance().getPreferences().addPreference(self._preference_key, False)
|
||||
|
||||
def show(self) -> None:
|
||||
if CuraApplication.getInstance().getPreferences().getValue(self._preference_key):
|
||||
return
|
||||
if CloudPrinterDetectedMessage.__is_visible:
|
||||
return
|
||||
super().show()
|
||||
CloudPrinterDetectedMessage.__is_visible = True
|
||||
|
||||
def hide(self, send_signal = True) -> None:
|
||||
super().hide(send_signal)
|
||||
CloudPrinterDetectedMessage.__is_visible = False
|
||||
|
||||
def _onDontAskMeAgain(self, checked: bool) -> None:
|
||||
CuraApplication.getInstance().getPreferences().setValue(self._preference_key, checked)
|
|
@ -2,8 +2,6 @@
|
|||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
from typing import List, Optional, Union, Dict, Any
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
from cura.PrinterOutput.Models.PrinterConfigurationModel import PrinterConfigurationModel
|
||||
|
||||
from .ClusterBuildPlate import ClusterBuildPlate
|
||||
|
|
|
@ -43,7 +43,7 @@ class ZeroConfClient:
|
|||
Logger.logException("e", "Failed to create zeroconf instance.")
|
||||
return
|
||||
|
||||
self._service_changed_request_thread = Thread(target = self._handleOnServiceChangedRequests, daemon = True)
|
||||
self._service_changed_request_thread = Thread(target = self._handleOnServiceChangedRequests, daemon = True, name = "ZeroConfServiceChangedThread")
|
||||
self._service_changed_request_thread.start()
|
||||
self._zero_conf_browser = ServiceBrowser(self._zero_conf, self.ZERO_CONF_NAME, [self._queueService])
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
self._all_baud_rates = [115200, 250000, 500000, 230400, 57600, 38400, 19200, 9600]
|
||||
|
||||
# Instead of using a timer, we really need the update to be as a thread, as reading from serial can block.
|
||||
self._update_thread = Thread(target = self._update, daemon = True)
|
||||
self._update_thread = Thread(target = self._update, daemon = True, name = "USBPrinterUpdate")
|
||||
|
||||
self._last_temperature_request = None # type: Optional[int]
|
||||
self._firmware_idle_count = 0
|
||||
|
@ -212,7 +212,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
|
|||
self._serial.close()
|
||||
|
||||
# Re-create the thread so it can be started again later.
|
||||
self._update_thread = Thread(target=self._update, daemon=True)
|
||||
self._update_thread = Thread(target=self._update, daemon=True, name = "USBPrinterUpdate")
|
||||
self._serial = None
|
||||
|
||||
## Send a command to printer.
|
||||
|
|
|
@ -6,7 +6,7 @@ import io #To write config files to strings as if they were files.
|
|||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
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.
|
||||
|
@ -20,6 +20,7 @@ def importFrom(serialised: str, filename: str) -> Optional["Profile"]:
|
|||
except (configparser.Error, UM.VersionUpgrade.FormatException, UM.VersionUpgrade.InvalidVersionException):
|
||||
return None
|
||||
|
||||
|
||||
## A representation of a profile used as intermediary form for conversion from
|
||||
# one format to the other.
|
||||
class Profile:
|
||||
|
|
|
@ -325,6 +325,8 @@ class VersionUpgrade41to42(VersionUpgrade):
|
|||
material_id = parser["containers"]["3"]
|
||||
old_quality_id = parser["containers"]["2"]
|
||||
if material_id in _creality_quality_per_material and old_quality_id in _creality_quality_per_material[material_id]:
|
||||
if definition_id == "creality_cr10_extruder_0": # We can't disambiguate between Creality CR-10 and Creality-CR10S since they share the same extruder definition. Have to go by the name.
|
||||
if "cr-10s" in parser["metadata"].get("machine", "Creality CR-10").lower(): # Not perfect, since the user can change this name :(
|
||||
parser["containers"]["2"] = _creality_quality_per_material[material_id][old_quality_id]
|
||||
|
||||
stack_copy = {} # type: Dict[str, str] # Make a copy so that we don't modify the dict we're iterating over.
|
||||
|
|
|
@ -66,6 +66,13 @@ class VersionUpgrade43to44(VersionUpgrade):
|
|||
# Alternate skin rotation should be translated to top/bottom line directions.
|
||||
if "skin_alternate_rotation" in parser["values"] and parseBool(parser["values"]["skin_alternate_rotation"]):
|
||||
parser["values"]["skin_angles"] = "[45, 135, 0, 90]"
|
||||
# Unit of adaptive layers topography size changed.
|
||||
if "adaptive_layer_height_threshold" in parser["values"]:
|
||||
val = parser["values"]["adaptive_layer_height_threshold"]
|
||||
if val.startswith("="):
|
||||
val = val[1:]
|
||||
val = "=({val}) / 1000".format(val = val) # Convert microns to millimetres. Works even if the profile contained a formula.
|
||||
parser["values"]["adaptive_layer_height_threshold"] = val
|
||||
|
||||
result = io.StringIO()
|
||||
parser.write(result)
|
||||
|
|
|
@ -10,7 +10,7 @@ definition = creality_cr10s
|
|||
|
||||
[metadata]
|
||||
type = definition_changes
|
||||
setting_version = 10
|
||||
setting_version = 11
|
||||
|
||||
[values]
|
||||
%s
|
||||
|
|
|
@ -720,6 +720,8 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
new_hotend_material._dirty = False
|
||||
|
||||
if is_new_material:
|
||||
if ContainerRegistry.getInstance().isReadOnly(self.getId()):
|
||||
ContainerRegistry.getInstance().setExplicitReadOnly(new_hotend_material.getId())
|
||||
containers_to_add.append(new_hotend_material)
|
||||
|
||||
# there is only one ID for a machine. Once we have reached here, it means we have already found
|
||||
|
|
13
public_key.pem
Normal file
13
public_key.pem
Normal file
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIICCgKCAgEA8k8IJsNNM097VM2pJ5vxkHcLhHf76JCB0iyvqpUuIgl8Zcp78Go+
|
||||
WtVkbVBZPPfSSB8GwjEtxvZeWj3i6e3nfreuuzq2sw6Gh860wMiQbNgL+rYCU3m9
|
||||
XxvC0kXgZt+oYs13N5LTePV7BG4goa/JOcN8dsu2ptZKfgH6TPhwshMeOGr/RoGr
|
||||
Jw1DrpvVeq/yTkrEHQHdtHr81GDghfK1vzxYQCt94MOFQCeShhtIC/jHelenJA94
|
||||
EpXqcWwCzFDfCQ3aXmCNHnMAsTHer7DWDfvsaUFyvJznrxkuQZIOQydGCNWhePTw
|
||||
nGiaMydchknr9TT3F+W/yuCs4u5GdZsz7S+1qbG4hblXo6dV6CTzkdKhh/MzONPC
|
||||
w6u1QBHUeTWN98zcTdtGIn53jjZEyYTodPnw/p4xLHVCju78a7uwm5U0rahcs6gw
|
||||
658glo3uT41mmTrXTBIVTV+4f/dSrwJVpNfTy/E4wi6fiuFeN8ojqXqN+NbIymfJ
|
||||
aKar/Jf/nM3QpEYaPz7yyn8PW8MZ7iomqnsPzyQGE1aymuEbw0ipTzMB7Oy/DfuU
|
||||
d4JU8FFuVuWJj3zNaXW7U/ggzbt5vkdIP/VNVfNZf741J/yKRbCI0+j4mthbruVQ
|
||||
Ka4aB2EVp1ozisHMaALg5tAeUgrQDZjGnVmSQLt+yFUUbG4e0XFQBb8CAwEAAQ==
|
||||
-----END RSA PUBLIC KEY-----
|
|
@ -6,7 +6,7 @@
|
|||
"type": "extruder",
|
||||
"author": "Ultimaker",
|
||||
"manufacturer": "Unknown",
|
||||
"setting_version": 10,
|
||||
"setting_version": 11,
|
||||
"visible": false,
|
||||
"position": "0"
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"author": "Ultimaker",
|
||||
"category": "Other",
|
||||
"manufacturer": "Unknown",
|
||||
"setting_version": 10,
|
||||
"setting_version": 11,
|
||||
"file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g",
|
||||
"visible": false,
|
||||
"has_materials": true,
|
||||
|
@ -387,6 +387,16 @@
|
|||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": false
|
||||
},
|
||||
"machine_extruders_share_heater":
|
||||
{
|
||||
"label": "Extruders Share Heater",
|
||||
"description": "Whether the extruders share a single heater rather than each extruder having its own heater.",
|
||||
"type": "bool",
|
||||
"default_value": false,
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": false
|
||||
},
|
||||
"machine_disallowed_areas":
|
||||
{
|
||||
"label": "Disallowed Areas",
|
||||
|
@ -2144,7 +2154,7 @@
|
|||
"minimum_value": "-273.15",
|
||||
"minimum_value_warning": "material_standby_temperature",
|
||||
"maximum_value_warning": "material_print_temperature",
|
||||
"enabled": "machine_nozzle_temp_enabled",
|
||||
"enabled": "machine_nozzle_temp_enabled and not machine_extruders_share_heater",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
|
@ -2159,7 +2169,7 @@
|
|||
"minimum_value": "-273.15",
|
||||
"minimum_value_warning": "material_standby_temperature",
|
||||
"maximum_value_warning": "material_print_temperature",
|
||||
"enabled": "machine_nozzle_temp_enabled",
|
||||
"enabled": "machine_nozzle_temp_enabled and not machine_extruders_share_heater",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
|
@ -7046,11 +7056,12 @@
|
|||
},
|
||||
"adaptive_layer_height_threshold":
|
||||
{
|
||||
"label": "Adaptive Layers Threshold",
|
||||
"description": "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer.",
|
||||
"label": "Adaptive Layers Topography Size",
|
||||
"description": "Target horizontal distance between two adjacent layers. Reducing this setting causes thinner layers to be used to bring the edges of the layers closer together.",
|
||||
"type": "float",
|
||||
"enabled": "adaptive_layer_height_enabled",
|
||||
"default_value": 200.0,
|
||||
"default_value": 0.2,
|
||||
"unit": "mm",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": false,
|
||||
"settable_per_meshgroup": false
|
||||
|
@ -7346,6 +7357,7 @@
|
|||
"description": "Retract the filament when the nozzle is moving over a non-printed area.",
|
||||
"type": "bool",
|
||||
"default_value": true,
|
||||
"value": "retraction_enable",
|
||||
"enabled": "clean_between_layers",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
|
@ -7358,6 +7370,7 @@
|
|||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 1,
|
||||
"value": "retraction_amount",
|
||||
"minimum_value_warning": "-0.0001",
|
||||
"maximum_value_warning": "10.0",
|
||||
"enabled": "wipe_retraction_enable and clean_between_layers",
|
||||
|
@ -7372,6 +7385,7 @@
|
|||
"unit": "mm³",
|
||||
"type": "float",
|
||||
"default_value": 0,
|
||||
"value": "retraction_extra_prime_amount",
|
||||
"minimum_value_warning": "-0.0001",
|
||||
"maximum_value_warning": "10.0",
|
||||
"enabled": "wipe_retraction_enable and clean_between_layers",
|
||||
|
@ -7385,6 +7399,7 @@
|
|||
"unit": "mm/s",
|
||||
"type": "float",
|
||||
"default_value": 5,
|
||||
"value": "retraction_speed",
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "1",
|
||||
"maximum_value": "machine_max_feedrate_e",
|
||||
|
@ -7406,13 +7421,13 @@
|
|||
"minimum_value_warning": "1",
|
||||
"maximum_value_warning": "70",
|
||||
"enabled": "wipe_retraction_enable and clean_between_layers",
|
||||
"value": "retraction_speed",
|
||||
"value": "wipe_retraction_speed",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
},
|
||||
"wipe_retraction_prime_speed":
|
||||
{
|
||||
"label": "Retraction Prime Speed",
|
||||
"label": "Wipe Retraction Prime Speed",
|
||||
"description": "The speed at which the filament is primed during a wipe retraction move.",
|
||||
"unit": "mm/s",
|
||||
"type": "float",
|
||||
|
@ -7422,7 +7437,7 @@
|
|||
"minimum_value_warning": "1",
|
||||
"maximum_value_warning": "70",
|
||||
"enabled": "wipe_retraction_enable and clean_between_layers",
|
||||
"value": "retraction_speed",
|
||||
"value": "wipe_retraction_speed",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true
|
||||
}
|
||||
|
@ -7443,10 +7458,11 @@
|
|||
},
|
||||
"wipe_hop_enable":
|
||||
{
|
||||
"label": "Wipe Z Hop When Retracted",
|
||||
"description": "Whenever a retraction is done, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate.",
|
||||
"label": "Wipe Z Hop",
|
||||
"description": "When wiping, the build plate is lowered to create clearance between the nozzle and the print. It prevents the nozzle from hitting the print during travel moves, reducing the chance to knock the print from the build plate.",
|
||||
"type": "bool",
|
||||
"default_value": true,
|
||||
"value": "retraction_hop_enabled",
|
||||
"enabled": "clean_between_layers",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
|
@ -7459,6 +7475,7 @@
|
|||
"unit": "mm",
|
||||
"type": "float",
|
||||
"default_value": 1,
|
||||
"value": "retraction_hop",
|
||||
"enabled": "wipe_hop_enable and clean_between_layers",
|
||||
"settable_per_mesh": false,
|
||||
"settable_per_extruder": true,
|
||||
|
@ -7470,7 +7487,8 @@
|
|||
"description": "Speed to move the z-axis during the hop.",
|
||||
"unit": "mm/s",
|
||||
"type": "float",
|
||||
"default_value": 100,
|
||||
"default_value": 10,
|
||||
"value": "speed_z_hop",
|
||||
"minimum_value": "0",
|
||||
"minimum_value_warning": "1",
|
||||
"enabled": "wipe_hop_enable and clean_between_layers",
|
||||
|
@ -7523,8 +7541,9 @@
|
|||
"type": "float",
|
||||
"minimum_value": "0",
|
||||
"default_value": 0,
|
||||
"settable_per_mesh": true
|
||||
},
|
||||
"settable_per_mesh": true,
|
||||
"children":
|
||||
{
|
||||
"small_feature_max_length":
|
||||
{
|
||||
"label": "Small Feature Max Length",
|
||||
|
@ -7535,6 +7554,8 @@
|
|||
"default_value": 0,
|
||||
"value": "small_hole_max_size * math.pi",
|
||||
"settable_per_mesh": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"small_feature_speed_factor":
|
||||
{
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"supports_usb_connection": false,
|
||||
"machine_extruder_trains":
|
||||
{
|
||||
"0": "alya3dp_extruder_0"
|
||||
"0": "kupido_extruder_0"
|
||||
}
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"machine_name": { "default_value": "ALYA 3DP" },
|
||||
"machine_name": { "default_value": "KUPIDO" },
|
||||
"machine_heated_bed": { "default_value": true },
|
||||
"machine_width": { "default_value": 195 },
|
||||
"machine_height": { "default_value": 190 },
|
||||
|
|
115
resources/definitions/leapfrog_bolt_pro.def.json
Normal file
115
resources/definitions/leapfrog_bolt_pro.def.json
Normal file
|
@ -0,0 +1,115 @@
|
|||
{
|
||||
"version": 2,
|
||||
"name": "Leapfrog Bolt Pro",
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Karan and Vincent 20191104",
|
||||
"manufacturer": "Leapfrog B.V.",
|
||||
"category": "Other",
|
||||
"platform": "leapfrog_bolt_pro_platform.stl",
|
||||
"platform_offset": [0, 0, -14],
|
||||
"file_formats": "text/x-gcode",
|
||||
"supports_usb_connection": false,
|
||||
"supports_network_connection": false,
|
||||
"has_materials": true,
|
||||
"has_machine_quality": true,
|
||||
"has_variants": true,
|
||||
"preferred_variant_name": "Brass 0.4",
|
||||
"preferred_material": "leapfrog_epla_natural",
|
||||
"variants_name": "Hot end",
|
||||
"exclude_materials": [
|
||||
"generic_pla_175",
|
||||
"generic_abs_175",
|
||||
"generic_cpe_175",
|
||||
"generic_hips_175",
|
||||
"generic_nylon_175",
|
||||
"generic_pc_175",
|
||||
"generic_petg_175",
|
||||
"generic_pva_175",
|
||||
"generic_tpu_175",
|
||||
"chromatik_pla",
|
||||
"dsm_arnitel2045_175",
|
||||
"dsm_novamid1070_175",
|
||||
"emotiontech_abs",
|
||||
"emotiontech_petg",
|
||||
"emotiontech_pla",
|
||||
"emotiontech_pva-m",
|
||||
"emotiontech_pva-oks",
|
||||
"emotiontech_pva-s",
|
||||
"emotiontech_tpu98a",
|
||||
"fabtotum_abs",
|
||||
"fabtotum_nylon",
|
||||
"fabtotum_pla",
|
||||
"fabtotum_tpu",
|
||||
"fiberlogy_hd_pla",
|
||||
"filo3d_pla",
|
||||
"filo3d_pla_green",
|
||||
"filo3d_pla_red",
|
||||
"imade3d_petg_175",
|
||||
"imade3d_pla_175",
|
||||
"innofill_innoflex60_175",
|
||||
"octofiber_pla",
|
||||
"polyflex_pla",
|
||||
"polymax_pla",
|
||||
"polyplus_pla",
|
||||
"polywood_pla",
|
||||
"tizyx_abs",
|
||||
"tizyx_pla",
|
||||
"tizyx_flex",
|
||||
"tizyx_petg",
|
||||
"tizyx_pva",
|
||||
"tizyx_pla_bois",
|
||||
"verbatim_bvoh_175",
|
||||
"Vertex_Delta_ABS",
|
||||
"Vertex_Delta_PET",
|
||||
"Vertex_Delta_PLA_Glitter",
|
||||
"Vertex_Delta_PLA_Mat",
|
||||
"Vertex_Delta_PLA_Satin",
|
||||
"Vertex_Delta_PLA_Wood",
|
||||
"Vertex_Delta_PLA",
|
||||
"Vertex_Delta_TPU",
|
||||
"zyyx_pro_flex",
|
||||
"zyyx_pro_pla"
|
||||
],
|
||||
"machine_extruder_trains":
|
||||
{
|
||||
"0": "leapfrog_bolt_pro_extruder_right",
|
||||
"1": "leapfrog_bolt_pro_extruder_left"
|
||||
}
|
||||
},
|
||||
"overrides": {
|
||||
"machine_name": {"default_value": "Leapfrog Bolt Pro" },
|
||||
"machine_extruder_count": {"default_value": 2},
|
||||
"machine_center_is_zero": {"default_value": false},
|
||||
"machine_width": {"default_value": 302},
|
||||
"machine_height": {"default_value": 205},
|
||||
"machine_depth": {"default_value": 322},
|
||||
"machine_heated_bed": {"default_value": true},
|
||||
"machine_head_with_fans_polygon": {"default_value": [[-60, 110 ], [-60, -45], [60, -45 ], [60, 110]]},
|
||||
"machine_max_feedrate_z": {"default_value": 16.7 },
|
||||
"machine_max_feedrate_e": {"default_value": 50 },
|
||||
"machine_max_acceleration_z": {"default_value": 100 },
|
||||
"machine_acceleration": {"default_value": 400 },
|
||||
"machine_max_jerk_xy": {"default_value": 20 },
|
||||
"machine_max_jerk_z": {"default_value": 0.4 },
|
||||
"machine_max_jerk_e": {"default_value": 5 },
|
||||
"machine_gcode_flavor": {"default_value": "RepRap (Marlin/Sprinter)"},
|
||||
"material_final_print_temperature": {"value": "default_material_print_temperature" },
|
||||
"material_initial_print_temperature": {"value": "default_material_print_temperature" },
|
||||
"gantry_height": {"value": "20"},
|
||||
"retraction_combing": { "default_value": "all" },
|
||||
"retraction_amount": {"default_value": 2},
|
||||
"adhesion_type": {"default_value": "skirt"},
|
||||
"skirt_line_count": {"default_value": 3},
|
||||
"machine_use_extruder_offset_to_offset_coords": {"default_value": true},
|
||||
"machine_start_gcode": {"default_value": "G90\nG28 X0 Y0 Z0\nG1 Z5 F1000\nG92 E0\nG1 Y-32 F12000\nG1 E15 F1000\nG1 E45 F150\nG4 S5"},
|
||||
"machine_end_gcode": {"default_value": "G92 E0\nG1 E-3 F300\nM104 S0 T0\nM104 S0 T1\nM140 S0\nG28 X0 Y0\nM84"},
|
||||
"prime_tower_enable": { "resolve": "extruders_enabled_count > 1"},
|
||||
"prime_tower_position_x": {"value": "169" },
|
||||
"prime_tower_position_y": {"value": "25" },
|
||||
"speed_travel": { "value": "200" },
|
||||
"build_volume_temperature": {"enabled": false},
|
||||
"material_standby_temperature": {"enabled": false }
|
||||
}
|
||||
}
|
68
resources/definitions/makeblock_mcreate.def.json
Normal file
68
resources/definitions/makeblock_mcreate.def.json
Normal file
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"version": 2,
|
||||
"name": "Makeblock mCreate",
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"author": "Makeblock",
|
||||
"manufacturer": "Makeblock",
|
||||
"visible": true,
|
||||
"file_formats": "application/gzip;text/x-gcode",
|
||||
"has_machine_quality": true,
|
||||
"preferred_quality_type": "normal",
|
||||
"machine_extruder_trains": {
|
||||
"0": "makeblock_mcreate_extruder_0"
|
||||
}
|
||||
},
|
||||
"overrides": {
|
||||
"machine_name": {
|
||||
"default_value": "Makeblock mCreate"
|
||||
},
|
||||
"machine_width": {
|
||||
"default_value": 225
|
||||
},
|
||||
"machine_depth": {
|
||||
"default_value": 225
|
||||
},
|
||||
"machine_height": {
|
||||
"default_value": 300
|
||||
},
|
||||
"machine_heated_bed": {
|
||||
"default_value": true
|
||||
},
|
||||
"machine_head_with_fans_polygon": {
|
||||
"default_value": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"machine_gcode_flavor": {
|
||||
"default_value": "Marlin"
|
||||
},
|
||||
"gantry_height": {
|
||||
"value": 15.0
|
||||
},
|
||||
"machine_extruder_count": {
|
||||
"default_value": 1
|
||||
},
|
||||
"machine_start_gcode": {
|
||||
"default_value": "; Mcreate Start Gcode \nG28 ; Home all axes \nG92 E0 ; Reset Extruder\nG1 X0 Y0 Z15 F3000.0 ; Move to start position \nG1 E10 F400 ;load filament \nG1 E2 F400 ;retarct filament \nG92 E0 ; Reset Extruder \nG1 X0 Y130 Z15 F3000.0 \nG12 ; clean nozzle \nG1 X0 Y0 Z0.3 F3000.0 ; Move to start position \nG1 E9.0 F400 ;loadsome filament \nG92 E0 ; Reset Extruder \n; End of start GCode"
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": "; Mcreate end Gcode \nG4 ; Wait command in buffer have finished \nG92 E0 \nG1 E-2 F300; retract filament \nG28 X Z; home x z axis \nG1 F3000 Y220;Move Heat Bed to the front for easy print removal \nM104 S0; Turn off the nozzle heat \nM140 S0; Turn off the bed heat \nM107 ; Turn off the Fan \nM84 ; Disable stepper motors \n; End of GCode"
|
||||
}
|
||||
}
|
||||
}
|
598
resources/definitions/skriware_2.def.json
Normal file
598
resources/definitions/skriware_2.def.json
Normal file
|
@ -0,0 +1,598 @@
|
|||
{
|
||||
"name": "Skriware 2",
|
||||
"version": 2,
|
||||
"inherits": "fdmprinter",
|
||||
"metadata": {
|
||||
"visible": true,
|
||||
"author": "Skriware",
|
||||
"manufacturer": "Skriware",
|
||||
"category": "Other",
|
||||
"file_formats": "text/x-gcode",
|
||||
"platform_offset": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"supports_usb_connection": false,
|
||||
"platform": "skriware_2_platform.stl",
|
||||
"machine_extruder_trains": {
|
||||
"0": "skriware_2_extruder_0",
|
||||
"1": "skriware_2_extruder_1"
|
||||
}
|
||||
},
|
||||
"overrides": {
|
||||
"jerk_print_layer_0": {
|
||||
"value": "5"
|
||||
},
|
||||
"jerk_prime_tower": {
|
||||
"value": "5"
|
||||
},
|
||||
"expand_skins_expand_distance": {
|
||||
"value": "1.2"
|
||||
},
|
||||
"jerk_support_interface": {
|
||||
"value": "5"
|
||||
},
|
||||
"jerk_travel_layer_0": {
|
||||
"value": "5.0"
|
||||
},
|
||||
"wipe_retraction_prime_speed": {
|
||||
"value": "30"
|
||||
},
|
||||
"material_standby_temperature": {
|
||||
"default_value": 195
|
||||
},
|
||||
"acceleration_support_bottom": {
|
||||
"value": "250"
|
||||
},
|
||||
"raft_base_line_width": {
|
||||
"value": "0.5"
|
||||
},
|
||||
"raft_speed": {
|
||||
"value": "30.0"
|
||||
},
|
||||
"jerk_topbottom": {
|
||||
"value": "5"
|
||||
},
|
||||
"ironing_inset": {
|
||||
"value": "0.2"
|
||||
},
|
||||
"acceleration_wall": {
|
||||
"value": "250"
|
||||
},
|
||||
"cross_infill_pocket_size": {
|
||||
"value": "5.333333333333333"
|
||||
},
|
||||
"jerk_support_roof": {
|
||||
"value": "5"
|
||||
},
|
||||
"acceleration_print": {
|
||||
"default_value": 250
|
||||
},
|
||||
"meshfix_maximum_travel_resolution": {
|
||||
"value": "0.8"
|
||||
},
|
||||
"support_top_distance": {
|
||||
"value": "0.22"
|
||||
},
|
||||
"acceleration_enabled": {
|
||||
"default_value": true
|
||||
},
|
||||
"optimize_wall_printing_order": {
|
||||
"default_value": true
|
||||
},
|
||||
"jerk_layer_0": {
|
||||
"value": "5"
|
||||
},
|
||||
"infill_line_distance": {
|
||||
"value": "5.333333333333333"
|
||||
},
|
||||
"acceleration_ironing": {
|
||||
"value": "250"
|
||||
},
|
||||
"material_print_temperature_layer_0": {
|
||||
"value": "195"
|
||||
},
|
||||
"bridge_skin_speed_2": {
|
||||
"value": "15"
|
||||
},
|
||||
"acceleration_travel": {
|
||||
"value": "250"
|
||||
},
|
||||
"switch_extruder_retraction_speed": {
|
||||
"value": "30"
|
||||
},
|
||||
"jerk_print": {
|
||||
"default_value": 5
|
||||
},
|
||||
"material_guid": {
|
||||
"default_value": "0ff92885-617b-4144-a03c-9989872454bc"
|
||||
},
|
||||
"raft_interface_acceleration": {
|
||||
"value": "250"
|
||||
},
|
||||
"acceleration_support_interface": {
|
||||
"value": "250"
|
||||
},
|
||||
"cool_fan_full_layer": {
|
||||
"value": "1"
|
||||
},
|
||||
"skirt_brim_minimal_length": {
|
||||
"default_value": 50
|
||||
},
|
||||
"material_bed_temperature": {
|
||||
"value": "50"
|
||||
},
|
||||
"speed_slowdown_layers": {
|
||||
"default_value": 1
|
||||
},
|
||||
"speed_travel": {
|
||||
"value": "150"
|
||||
},
|
||||
"skin_overlap": {
|
||||
"value": "15"
|
||||
},
|
||||
"acceleration_infill": {
|
||||
"value": "250"
|
||||
},
|
||||
"support_roof_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"raft_base_jerk": {
|
||||
"value": "5"
|
||||
},
|
||||
"retraction_retract_speed": {
|
||||
"value": "30"
|
||||
},
|
||||
"infill_wipe_dist": {
|
||||
"value": "0.1"
|
||||
},
|
||||
"jerk_wall_x": {
|
||||
"value": "5"
|
||||
},
|
||||
"layer_height": {
|
||||
"default_value": 0.2
|
||||
},
|
||||
"bottom_skin_expand_distance": {
|
||||
"value": "1.2000000000000002"
|
||||
},
|
||||
"machine_start_gcode": {
|
||||
"default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nG28 X0 Y0;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nM420 S1 Z0.9 ;enable bed levelling\nG1 Z10 F250 ;move the platform down 10mm\nM107 ;fan off\nM42 P11 S255 ;turn on front fan\nM140 S{material_bed_temperature}\nM104 T0 S{material_print_temperature}\nM104 T1 S{material_print_temperature}\nG1 F2500 Y260\nM190 S{material_bed_temperature}\nM109 T0 S{material_print_temperature}\nM109 T1 S{material_print_temperature}\nM60 ;enable E-FADE Algorithm\nM62 A ;filament sensor off\nG92 E0 ;zero the extruded length\nT1\nG92 E0;zero the extruded length\nG1 F300 Z0.3\nG1 F1200 X20\nG1 F1200 X180 E21 ;extrude 21 mm of feed stock\nG1 F1200 E15 ;retracting 6 mm\nG1 F2000 E21\nG1 F2000 E15\nG1 F300 Z1.5\nG92 E0 ;zero the extruded length again\nT0\nG92 E0 ;zero the extruded length\nG1 F1200 Y258\nG1 F300 Z0.3\nG1 F1200 X40 E21 ;extrude 21 mm of feed stock\nG1 F1200 E15 ;retracting 6 mm\nG1 F2000 E21\nG1 F2000 E15\nG1 Z1.5\nM61 A\nM63 A ;filament sensor on\nG92 E0 ;zero the extruded length again\nM58 ;end of Start G-Code and signal retract management"
|
||||
},
|
||||
"travel_retract_before_outer_wall": {
|
||||
"default_value": true
|
||||
},
|
||||
"xy_offset_layer_0": {
|
||||
"value": "-0.16"
|
||||
},
|
||||
"adhesion_type": {
|
||||
"default_value": "raft"
|
||||
},
|
||||
"min_skin_width_for_expansion": {
|
||||
"value": "0.671279704941824"
|
||||
},
|
||||
"support_bottom_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"prime_tower_position_x": {
|
||||
"value": "1"
|
||||
},
|
||||
"machine_depth": {
|
||||
"default_value": 260
|
||||
},
|
||||
"retraction_speed": {
|
||||
"default_value": 30
|
||||
},
|
||||
"support_skip_some_zags": {
|
||||
"default_value": true
|
||||
},
|
||||
"remove_empty_first_layers": {
|
||||
"default_value": false
|
||||
},
|
||||
"z_seam_x": {
|
||||
"value": "115"
|
||||
},
|
||||
"support_xy_distance_overhang": {
|
||||
"value": "0.5"
|
||||
},
|
||||
"support_tree_wall_thickness": {
|
||||
"value": "0.4"
|
||||
},
|
||||
"acceleration_print_layer_0": {
|
||||
"value": "250"
|
||||
},
|
||||
"support_xy_distance": {
|
||||
"default_value": 0.8
|
||||
},
|
||||
"support_roof_line_distance": {
|
||||
"value": "0.5714285714285714"
|
||||
},
|
||||
"jerk_enabled": {
|
||||
"default_value": true
|
||||
},
|
||||
"min_infill_area": {
|
||||
"default_value": 1
|
||||
},
|
||||
"travel_avoid_supports": {
|
||||
"default_value": true
|
||||
},
|
||||
"bottom_layers": {
|
||||
"value": "3"
|
||||
},
|
||||
"multiple_mesh_overlap": {
|
||||
"default_value": 0
|
||||
},
|
||||
"retraction_hop_enabled": {
|
||||
"default_value": true
|
||||
},
|
||||
"acceleration_topbottom": {
|
||||
"value": "250"
|
||||
},
|
||||
"jerk_wall": {
|
||||
"value": "5"
|
||||
},
|
||||
"jerk_wall_0": {
|
||||
"value": "5"
|
||||
},
|
||||
"skin_overlap_mm": {
|
||||
"value": "0.06"
|
||||
},
|
||||
"retraction_min_travel": {
|
||||
"value": "1"
|
||||
},
|
||||
"support_interface_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"material_diameter": {
|
||||
"default_value": 1.75
|
||||
},
|
||||
"speed_roofing": {
|
||||
"value": "30.0"
|
||||
},
|
||||
"skin_outline_count": {
|
||||
"default_value": 0
|
||||
},
|
||||
"skin_no_small_gaps_heuristic": {
|
||||
"default_value": true
|
||||
},
|
||||
"top_bottom_pattern_0": {
|
||||
"value": "'zigzag'"
|
||||
},
|
||||
"top_skin_expand_distance": {
|
||||
"value": "1.2000000000000002"
|
||||
},
|
||||
"acceleration_travel_layer_0": {
|
||||
"value": "250.0"
|
||||
},
|
||||
"prime_tower_min_volume": {
|
||||
"default_value": 4
|
||||
},
|
||||
"switch_extruder_retraction_speeds": {
|
||||
"default_value": 30
|
||||
},
|
||||
"skin_preshrink": {
|
||||
"value": "1.2000000000000002"
|
||||
},
|
||||
"material_bed_temperature_layer_0": {
|
||||
"value": "50"
|
||||
},
|
||||
"support_tree_collision_resolution": {
|
||||
"value": "0.2"
|
||||
},
|
||||
"machine_height": {
|
||||
"default_value": 210
|
||||
},
|
||||
"raft_acceleration": {
|
||||
"value": "250"
|
||||
},
|
||||
"fill_outline_gaps": {
|
||||
"default_value": true
|
||||
},
|
||||
"wall_x_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"jerk_support_bottom": {
|
||||
"value": "5"
|
||||
},
|
||||
"machine_end_gcode": {
|
||||
"default_value": "M59\nG92 E1\nG1 E-1 F300\nM104 T0 S0\nM104 T1 S0\nM140 S0\nG28 X0 Y0\nM84\nM106 S0\nM107"
|
||||
},
|
||||
"infill_sparse_density": {
|
||||
"default_value": 15
|
||||
},
|
||||
"meshfix_maximum_deviation": {
|
||||
"default_value": 0.005
|
||||
},
|
||||
"wall_0_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"material_adhesion_tendency": {
|
||||
"default_value": 0
|
||||
},
|
||||
"prime_tower_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"prime_tower_position_y": {
|
||||
"value": "1"
|
||||
},
|
||||
"support_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"retract_at_layer_change": {
|
||||
"default_value": true
|
||||
},
|
||||
"machine_extruder_count": {
|
||||
"default_value": 2
|
||||
},
|
||||
"wall_thickness": {
|
||||
"default_value": 1.2
|
||||
},
|
||||
"support_infill_sparse_thickness": {
|
||||
"value": "0.2"
|
||||
},
|
||||
"raft_surface_acceleration": {
|
||||
"value": "250"
|
||||
},
|
||||
"roofing_layer_count": {
|
||||
"value": "1"
|
||||
},
|
||||
"skirt_brim_line_width": {
|
||||
"value": "0.5"
|
||||
},
|
||||
"jerk_support": {
|
||||
"value": "5"
|
||||
},
|
||||
"raft_surface_jerk": {
|
||||
"value": "5"
|
||||
},
|
||||
"speed_equalize_flow_max": {
|
||||
"default_value": 40
|
||||
},
|
||||
"raft_surface_speed": {
|
||||
"value": "30.0"
|
||||
},
|
||||
"jerk_travel": {
|
||||
"value": "5"
|
||||
},
|
||||
"support_zag_skip_count": {
|
||||
"value": "8"
|
||||
},
|
||||
"retraction_combing": {
|
||||
"default_value": "infill"
|
||||
},
|
||||
"raft_interface_line_spacing": {
|
||||
"value": "0.4"
|
||||
},
|
||||
"layer_height_0": {
|
||||
"default_value": 0.2
|
||||
},
|
||||
"extruders_enabled_count": {
|
||||
"value": "2"
|
||||
},
|
||||
"support_line_distance": {
|
||||
"value": "1.3333333333333333"
|
||||
},
|
||||
"support_roof_density": {
|
||||
"value": "70"
|
||||
},
|
||||
"raft_base_line_spacing": {
|
||||
"value": "0.8"
|
||||
},
|
||||
"acceleration_prime_tower": {
|
||||
"value": "250"
|
||||
},
|
||||
"skin_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"support_z_distance": {
|
||||
"default_value": 0.22
|
||||
},
|
||||
"bottom_skin_preshrink": {
|
||||
"value": "1.2000000000000002"
|
||||
},
|
||||
"jerk_skirt_brim": {
|
||||
"value": "5"
|
||||
},
|
||||
"z_seam_y": {
|
||||
"value": "180"
|
||||
},
|
||||
"skirt_line_count": {
|
||||
"default_value": 2
|
||||
},
|
||||
"raft_margin": {
|
||||
"default_value": 4
|
||||
},
|
||||
"infill_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"wipe_retraction_retract_speed": {
|
||||
"value": "30"
|
||||
},
|
||||
"z_seam_corner": {
|
||||
"default_value": "z_seam_corner_weighted"
|
||||
},
|
||||
"support_roof_height": {
|
||||
"value": "0.4"
|
||||
},
|
||||
"top_layers": {
|
||||
"value": "4"
|
||||
},
|
||||
"support_infill_rate": {
|
||||
"value": "30"
|
||||
},
|
||||
"raft_interface_speed": {
|
||||
"value": "35"
|
||||
},
|
||||
"default_material_print_temperature": {
|
||||
"default_value": 195
|
||||
},
|
||||
"acceleration_layer_0": {
|
||||
"value": "250"
|
||||
},
|
||||
"support_skip_zag_per_mm": {
|
||||
"default_value": 10
|
||||
},
|
||||
"material_initial_print_temperature": {
|
||||
"value": "195"
|
||||
},
|
||||
"raft_interface_jerk": {
|
||||
"value": "5"
|
||||
},
|
||||
"machine_width": {
|
||||
"default_value": 210
|
||||
},
|
||||
"wall_line_count": {
|
||||
"value": "3"
|
||||
},
|
||||
"retraction_amount": {
|
||||
"default_value": 3
|
||||
},
|
||||
"infill_sparse_thickness": {
|
||||
"value": "0.2"
|
||||
},
|
||||
"support_initial_layer_line_distance": {
|
||||
"value": "1.3333333333333333"
|
||||
},
|
||||
"jerk_support_infill": {
|
||||
"value": "5"
|
||||
},
|
||||
"acceleration_roofing": {
|
||||
"value": "250"
|
||||
},
|
||||
"retraction_extrusion_window": {
|
||||
"value": "3"
|
||||
},
|
||||
"raft_interface_line_width": {
|
||||
"value": "0.4"
|
||||
},
|
||||
"acceleration_support_roof": {
|
||||
"value": "250"
|
||||
},
|
||||
"support_brim_line_count": {
|
||||
"value": "16"
|
||||
},
|
||||
"layer_0_z_overlap": {
|
||||
"value": "0.1"
|
||||
},
|
||||
"support_angle": {
|
||||
"default_value": 60
|
||||
},
|
||||
"machine_heated_bed": {
|
||||
"default_value": true
|
||||
},
|
||||
"raft_surface_thickness": {
|
||||
"value": "0.2"
|
||||
},
|
||||
"cool_min_layer_time": {
|
||||
"default_value": 10
|
||||
},
|
||||
"gantry_height": {
|
||||
"value": "210"
|
||||
},
|
||||
"raft_airgap": {
|
||||
"default_value": 0.2
|
||||
},
|
||||
"acceleration_skirt_brim": {
|
||||
"value": "250"
|
||||
},
|
||||
"skirt_brim_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"jerk_infill": {
|
||||
"value": "5"
|
||||
},
|
||||
"roofing_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"support_use_towers": {
|
||||
"default_value": false
|
||||
},
|
||||
"ooze_shield_angle": {
|
||||
"default_value": 50
|
||||
},
|
||||
"material_flow": {
|
||||
"default_value": 99
|
||||
},
|
||||
"speed_travel_layer_0": {
|
||||
"value": "75.0"
|
||||
},
|
||||
"raft_base_acceleration": {
|
||||
"value": "250"
|
||||
},
|
||||
"retraction_count_max": {
|
||||
"default_value": 40
|
||||
},
|
||||
"ooze_shield_dist": {
|
||||
"default_value": 4
|
||||
},
|
||||
"acceleration_support": {
|
||||
"value": "250"
|
||||
},
|
||||
"max_skin_angle_for_expansion": {
|
||||
"default_value": 50
|
||||
},
|
||||
"coasting_enable": {
|
||||
"default_value": true
|
||||
},
|
||||
"brim_width": {
|
||||
"default_value": 10
|
||||
},
|
||||
"acceleration_support_infill": {
|
||||
"value": "250"
|
||||
},
|
||||
"retraction_prime_speed": {
|
||||
"value": "30"
|
||||
},
|
||||
"raft_base_speed": {
|
||||
"value": "35"
|
||||
},
|
||||
"acceleration_wall_0": {
|
||||
"value": "250"
|
||||
},
|
||||
"xy_offset": {
|
||||
"default_value": -0.16
|
||||
},
|
||||
"prime_tower_size": {
|
||||
"default_value": 1
|
||||
},
|
||||
"jerk_ironing": {
|
||||
"value": "5"
|
||||
},
|
||||
"switch_extruder_prime_speed": {
|
||||
"value": "30"
|
||||
},
|
||||
"raft_jerk": {
|
||||
"value": "5"
|
||||
},
|
||||
"top_skin_preshrink": {
|
||||
"value": "1.2000000000000002"
|
||||
},
|
||||
"material_print_temperature": {
|
||||
"value": "195"
|
||||
},
|
||||
"wall_material_flow": {
|
||||
"value": "99"
|
||||
},
|
||||
"jerk_roofing": {
|
||||
"value": "5"
|
||||
},
|
||||
"cool_fan_full_at_height": {
|
||||
"value": "0"
|
||||
},
|
||||
"acceleration_wall_x": {
|
||||
"value": "250"
|
||||
},
|
||||
"support_bottom_distance": {
|
||||
"value": "0.23"
|
||||
},
|
||||
"cool_min_speed": {
|
||||
"default_value": 15
|
||||
},
|
||||
"default_material_bed_temperature": {
|
||||
"default_value": 50
|
||||
},
|
||||
"raft_interface_thickness": {
|
||||
"value": "0.2"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -67,8 +67,6 @@
|
|||
"extruder_prime_pos_abs": { "default_value": true },
|
||||
"machine_start_gcode": { "default_value": "" },
|
||||
"machine_end_gcode": { "default_value": "" },
|
||||
"prime_tower_position_x": { "value": "345" },
|
||||
"prime_tower_position_y": { "value": "222.5" },
|
||||
"prime_blob_enable": { "enabled": true, "default_value": false },
|
||||
|
||||
"speed_travel":
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Extruder 1",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "BIBO2 dual",
|
||||
"machine": "bibo2_dual",
|
||||
"position": "0"
|
||||
},
|
||||
"overrides": {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Extruder 2",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "BIBO2 dual",
|
||||
"machine": "bibo2_dual",
|
||||
"position": "1"
|
||||
},
|
||||
"overrides": {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Left Extruder",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "Creality CR-X",
|
||||
"machine": "creality_cr-x",
|
||||
"position": "0"
|
||||
},
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Right Extruder",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "Creality CR-X",
|
||||
"machine": "creality_cr-x",
|
||||
"position": "1"
|
||||
},
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Extruder 1",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "Creatable_D3",
|
||||
"machine": "creatable_d3",
|
||||
"position": "0"
|
||||
},
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Extruder 1",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "hellbot_magna_i",
|
||||
"machine": "hellbot_magna_I",
|
||||
"position": "0"
|
||||
},
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "0.4mm Nozzle",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "Tyro",
|
||||
"machine": "key3d_tyro",
|
||||
"position": "0"
|
||||
},
|
||||
|
||||
|
|
21
resources/extruders/leapfrog_bolt_pro_extruder_left.def.json
Normal file
21
resources/extruders/leapfrog_bolt_pro_extruder_left.def.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"version": 2,
|
||||
"name": "Left extruder",
|
||||
"inherits": "fdmextruder",
|
||||
"metadata": {
|
||||
"machine": "leapfrog_bolt_pro",
|
||||
"position": "1"
|
||||
},
|
||||
"overrides": {
|
||||
"extruder_nr": {
|
||||
"default_value": 1,
|
||||
"maximum_value": "1"
|
||||
},
|
||||
"machine_nozzle_size": { "default_value": 0.4 },
|
||||
"material_diameter": { "default_value": 1.75 },
|
||||
"machine_nozzle_head_distance": { "default_value": 22 },
|
||||
"machine_nozzle_offset_x": { "default_value": 0 },
|
||||
"machine_nozzle_offset_y": { "default_value": 0.0 },
|
||||
"machine_extruder_start_code": { "default_value": "G1 Y-32 F12000\nG1 X6 F1000\nG1 X-32 F4000\nG1 X6" }
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue