mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-07 06:57:28 -06:00
Merge branch 'master' into xray_in_solid_view
This commit is contained in:
commit
0150f37937
315 changed files with 33845 additions and 1731 deletions
|
@ -5,8 +5,8 @@ include(GNUInstallDirs)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
set(URANIUM_DIR "${CMAKE_SOURCE_DIR}/../Uranium" CACHE DIRECTORY "The location of the Uranium repository")
|
set(URANIUM_DIR "${CMAKE_SOURCE_DIR}/../Uranium" CACHE PATH "The location of the Uranium repository")
|
||||||
set(URANIUM_SCRIPTS_DIR "${URANIUM_DIR}/scripts" CACHE DIRECTORY "The location of the scripts directory of the Uranium repository")
|
set(URANIUM_SCRIPTS_DIR "${URANIUM_DIR}/scripts" CACHE PATH "The location of the scripts directory of the Uranium repository")
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
include(CuraTests)
|
include(CuraTests)
|
||||||
|
|
|
@ -4,12 +4,11 @@ from typing import Optional, Dict, TYPE_CHECKING
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty
|
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, pyqtProperty
|
||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
|
||||||
from UM.Message import Message
|
from UM.Message import Message
|
||||||
from cura import UltimakerCloudAuthentication
|
from UM.i18n import i18nCatalog
|
||||||
|
|
||||||
from cura.OAuth2.AuthorizationService import AuthorizationService
|
from cura.OAuth2.AuthorizationService import AuthorizationService
|
||||||
from cura.OAuth2.Models import OAuth2Settings
|
from cura.OAuth2.Models import OAuth2Settings
|
||||||
|
from cura.UltimakerCloud import UltimakerCloudAuthentication
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2020 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
|
@ -173,7 +173,10 @@ class Arrange:
|
||||||
def bestSpot(self, shape_arr, start_prio = 0, step = 1):
|
def bestSpot(self, shape_arr, start_prio = 0, step = 1):
|
||||||
start_idx_list = numpy.where(self._priority_unique_values == start_prio)
|
start_idx_list = numpy.where(self._priority_unique_values == start_prio)
|
||||||
if start_idx_list:
|
if start_idx_list:
|
||||||
|
try:
|
||||||
start_idx = start_idx_list[0][0]
|
start_idx = start_idx_list[0][0]
|
||||||
|
except IndexError:
|
||||||
|
start_idx = 0
|
||||||
else:
|
else:
|
||||||
start_idx = 0
|
start_idx = 0
|
||||||
for priority in self._priority_unique_values[start_idx::step]:
|
for priority in self._priority_unique_values[start_idx::step]:
|
||||||
|
|
|
@ -7,71 +7,52 @@ import time
|
||||||
from typing import cast, TYPE_CHECKING, Optional, Callable, List, Any
|
from typing import cast, TYPE_CHECKING, Optional, Callable, List, Any
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, QTimer, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS
|
from PyQt5.QtCore import QObject, QTimer, QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS
|
||||||
from PyQt5.QtGui import QColor, QIcon
|
from PyQt5.QtGui import QColor, QIcon
|
||||||
from PyQt5.QtWidgets import QMessageBox
|
|
||||||
from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType
|
from PyQt5.QtQml import qmlRegisterUncreatableType, qmlRegisterSingletonType, qmlRegisterType
|
||||||
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
import UM.Util
|
||||||
|
import cura.Settings.cura_empty_instance_containers
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Decorators import override
|
from UM.Decorators import override
|
||||||
from UM.FlameProfiler import pyqtSlot
|
from UM.FlameProfiler import pyqtSlot
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Message import Message
|
|
||||||
from UM.Platform import Platform
|
|
||||||
from UM.PluginError import PluginNotFoundError
|
|
||||||
from UM.Resources import Resources
|
|
||||||
from UM.Preferences import Preferences
|
|
||||||
from UM.Qt.QtApplication import QtApplication # The class we're inheriting from.
|
|
||||||
import UM.Util
|
|
||||||
from UM.View.SelectionPass import SelectionPass # For typing.
|
|
||||||
|
|
||||||
from UM.Math.AxisAlignedBox import AxisAlignedBox
|
from UM.Math.AxisAlignedBox import AxisAlignedBox
|
||||||
from UM.Math.Matrix import Matrix
|
from UM.Math.Matrix import Matrix
|
||||||
from UM.Math.Quaternion import Quaternion
|
from UM.Math.Quaternion import Quaternion
|
||||||
from UM.Math.Vector import Vector
|
from UM.Math.Vector import Vector
|
||||||
|
|
||||||
from UM.Mesh.ReadMeshJob import ReadMeshJob
|
from UM.Mesh.ReadMeshJob import ReadMeshJob
|
||||||
|
from UM.Message import Message
|
||||||
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
|
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
|
||||||
from UM.Operations.GroupedOperation import GroupedOperation
|
from UM.Operations.GroupedOperation import GroupedOperation
|
||||||
from UM.Operations.SetTransformOperation import SetTransformOperation
|
from UM.Operations.SetTransformOperation import SetTransformOperation
|
||||||
|
from UM.Platform import Platform
|
||||||
|
from UM.PluginError import PluginNotFoundError
|
||||||
|
from UM.Preferences import Preferences
|
||||||
|
from UM.Qt.QtApplication import QtApplication # The class we're inheriting from.
|
||||||
|
from UM.Resources import Resources
|
||||||
from UM.Scene.Camera import Camera
|
from UM.Scene.Camera import Camera
|
||||||
from UM.Scene.GroupDecorator import GroupDecorator
|
from UM.Scene.GroupDecorator import GroupDecorator
|
||||||
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
|
||||||
from UM.Scene.SceneNode import SceneNode
|
from UM.Scene.SceneNode import SceneNode
|
||||||
from UM.Scene.Selection import Selection
|
from UM.Scene.Selection import Selection
|
||||||
from UM.Scene.ToolHandle import ToolHandle
|
from UM.Scene.ToolHandle import ToolHandle
|
||||||
|
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||||
from UM.Settings.InstanceContainer import InstanceContainer
|
from UM.Settings.InstanceContainer import InstanceContainer
|
||||||
from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
|
from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
|
||||||
from UM.Settings.SettingFunction import SettingFunction
|
from UM.Settings.SettingFunction import SettingFunction
|
||||||
from UM.Settings.Validator import Validator
|
from UM.Settings.Validator import Validator
|
||||||
|
from UM.View.SelectionPass import SelectionPass # For typing.
|
||||||
from UM.Workspace.WorkspaceReader import WorkspaceReader
|
from UM.Workspace.WorkspaceReader import WorkspaceReader
|
||||||
|
from UM.i18n import i18nCatalog
|
||||||
|
from cura import ApplicationMetadata
|
||||||
from cura.API import CuraAPI
|
from cura.API import CuraAPI
|
||||||
|
|
||||||
from cura.Arranging.Arrange import Arrange
|
from cura.Arranging.Arrange import Arrange
|
||||||
from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
|
|
||||||
from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob
|
from cura.Arranging.ArrangeObjectsAllBuildPlatesJob import ArrangeObjectsAllBuildPlatesJob
|
||||||
|
from cura.Arranging.ArrangeObjectsJob import ArrangeObjectsJob
|
||||||
from cura.Arranging.ShapeArray import ShapeArray
|
from cura.Arranging.ShapeArray import ShapeArray
|
||||||
|
|
||||||
from cura.Operations.SetParentOperation import SetParentOperation
|
|
||||||
|
|
||||||
from cura.Scene.BlockSlicingDecorator import BlockSlicingDecorator
|
|
||||||
from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
|
|
||||||
from cura.Scene.ConvexHullDecorator import ConvexHullDecorator
|
|
||||||
from cura.Scene.CuraSceneController import CuraSceneController
|
|
||||||
from cura.Scene.CuraSceneNode import CuraSceneNode
|
|
||||||
|
|
||||||
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
|
|
||||||
from cura.Scene import ZOffsetDecorator
|
|
||||||
from cura.Machines.MachineErrorChecker import MachineErrorChecker
|
from cura.Machines.MachineErrorChecker import MachineErrorChecker
|
||||||
|
|
||||||
from cura.Machines.Models.BuildPlateModel import BuildPlateModel
|
from cura.Machines.Models.BuildPlateModel import BuildPlateModel
|
||||||
from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel
|
from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel
|
||||||
from cura.Machines.Models.DiscoveredPrintersModel import DiscoveredPrintersModel
|
from cura.Machines.Models.DiscoveredPrintersModel import DiscoveredPrintersModel
|
||||||
|
@ -80,6 +61,8 @@ from cura.Machines.Models.FavoriteMaterialsModel import FavoriteMaterialsModel
|
||||||
from cura.Machines.Models.FirstStartMachineActionsModel import FirstStartMachineActionsModel
|
from cura.Machines.Models.FirstStartMachineActionsModel import FirstStartMachineActionsModel
|
||||||
from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel
|
from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel
|
||||||
from cura.Machines.Models.GlobalStacksModel import GlobalStacksModel
|
from cura.Machines.Models.GlobalStacksModel import GlobalStacksModel
|
||||||
|
from cura.Machines.Models.IntentCategoryModel import IntentCategoryModel
|
||||||
|
from cura.Machines.Models.IntentModel import IntentModel
|
||||||
from cura.Machines.Models.MaterialBrandsModel import MaterialBrandsModel
|
from cura.Machines.Models.MaterialBrandsModel import MaterialBrandsModel
|
||||||
from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel
|
from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel
|
||||||
from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel
|
from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel
|
||||||
|
@ -89,51 +72,47 @@ from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfile
|
||||||
from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel
|
from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel
|
||||||
from cura.Machines.Models.SettingVisibilityPresetsModel import SettingVisibilityPresetsModel
|
from cura.Machines.Models.SettingVisibilityPresetsModel import SettingVisibilityPresetsModel
|
||||||
from cura.Machines.Models.UserChangesModel import UserChangesModel
|
from cura.Machines.Models.UserChangesModel import UserChangesModel
|
||||||
from cura.Machines.Models.IntentModel import IntentModel
|
from cura.Operations.SetParentOperation import SetParentOperation
|
||||||
from cura.Machines.Models.IntentCategoryModel import IntentCategoryModel
|
|
||||||
|
|
||||||
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
|
|
||||||
from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage
|
from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage
|
||||||
|
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice
|
||||||
import cura.Settings.cura_empty_instance_containers
|
from cura.Scene import ZOffsetDecorator
|
||||||
|
from cura.Scene.BlockSlicingDecorator import BlockSlicingDecorator
|
||||||
|
from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
|
||||||
|
from cura.Scene.ConvexHullDecorator import ConvexHullDecorator
|
||||||
|
from cura.Scene.CuraSceneController import CuraSceneController
|
||||||
|
from cura.Scene.CuraSceneNode import CuraSceneNode
|
||||||
|
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
|
||||||
from cura.Settings.ContainerManager import ContainerManager
|
from cura.Settings.ContainerManager import ContainerManager
|
||||||
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
|
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
|
||||||
from cura.Settings.CuraFormulaFunctions import CuraFormulaFunctions
|
from cura.Settings.CuraFormulaFunctions import CuraFormulaFunctions
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
from cura.Settings.ExtruderStack import ExtruderStack
|
from cura.Settings.ExtruderStack import ExtruderStack
|
||||||
|
from cura.Settings.GlobalStack import GlobalStack
|
||||||
|
from cura.Settings.IntentManager import IntentManager
|
||||||
from cura.Settings.MachineManager import MachineManager
|
from cura.Settings.MachineManager import MachineManager
|
||||||
from cura.Settings.MachineNameValidator import MachineNameValidator
|
from cura.Settings.MachineNameValidator import MachineNameValidator
|
||||||
from cura.Settings.IntentManager import IntentManager
|
|
||||||
from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
|
from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
|
||||||
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
|
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
|
||||||
from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel
|
from cura.Settings.SidebarCustomMenuItemsModel import SidebarCustomMenuItemsModel
|
||||||
from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager
|
from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager
|
||||||
|
|
||||||
from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager
|
from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager
|
||||||
|
|
||||||
from cura.UI import CuraSplashScreen, MachineActionManager, PrintInformation
|
from cura.UI import CuraSplashScreen, MachineActionManager, PrintInformation
|
||||||
|
from cura.UI.AddPrinterPagesModel import AddPrinterPagesModel
|
||||||
from cura.UI.MachineSettingsManager import MachineSettingsManager
|
from cura.UI.MachineSettingsManager import MachineSettingsManager
|
||||||
from cura.UI.ObjectsModel import ObjectsModel
|
from cura.UI.ObjectsModel import ObjectsModel
|
||||||
from cura.UI.TextManager import TextManager
|
|
||||||
from cura.UI.AddPrinterPagesModel import AddPrinterPagesModel
|
|
||||||
from cura.UI.RecommendedMode import RecommendedMode
|
from cura.UI.RecommendedMode import RecommendedMode
|
||||||
|
from cura.UI.TextManager import TextManager
|
||||||
from cura.UI.WelcomePagesModel import WelcomePagesModel
|
from cura.UI.WelcomePagesModel import WelcomePagesModel
|
||||||
from cura.UI.WhatsNewPagesModel import WhatsNewPagesModel
|
from cura.UI.WhatsNewPagesModel import WhatsNewPagesModel
|
||||||
|
from cura.UltimakerCloud import UltimakerCloudAuthentication
|
||||||
from cura.Utils.NetworkingUtil import NetworkingUtil
|
from cura.Utils.NetworkingUtil import NetworkingUtil
|
||||||
|
|
||||||
from .SingleInstance import SingleInstance
|
|
||||||
from .AutoSave import AutoSave
|
|
||||||
from . import PlatformPhysics
|
|
||||||
from . import BuildVolume
|
from . import BuildVolume
|
||||||
from . import CameraAnimation
|
from . import CameraAnimation
|
||||||
from . import CuraActions
|
from . import CuraActions
|
||||||
|
from . import PlatformPhysics
|
||||||
from . import PrintJobPreviewImageProvider
|
from . import PrintJobPreviewImageProvider
|
||||||
|
from .AutoSave import AutoSave
|
||||||
from cura.TaskManagement.OnExitCallbackManager import OnExitCallbackManager
|
from .SingleInstance import SingleInstance
|
||||||
|
|
||||||
from cura import ApplicationMetadata, UltimakerCloudAuthentication
|
|
||||||
from cura.Settings.GlobalStack import GlobalStack
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from UM.Settings.EmptyInstanceContainer import EmptyInstanceContainer
|
from UM.Settings.EmptyInstanceContainer import EmptyInstanceContainer
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
|
from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
|
||||||
|
from typing import Set
|
||||||
|
|
||||||
import cura.CuraApplication
|
import cura.CuraApplication
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
|
@ -23,7 +24,7 @@ class QualitySettingsModel(ListModel):
|
||||||
|
|
||||||
GLOBAL_STACK_POSITION = -1
|
GLOBAL_STACK_POSITION = -1
|
||||||
|
|
||||||
def __init__(self, parent = None):
|
def __init__(self, parent = None) -> None:
|
||||||
super().__init__(parent = parent)
|
super().__init__(parent = parent)
|
||||||
|
|
||||||
self.addRoleName(self.KeyRole, "key")
|
self.addRoleName(self.KeyRole, "key")
|
||||||
|
@ -38,7 +39,9 @@ class QualitySettingsModel(ListModel):
|
||||||
self._application = cura.CuraApplication.CuraApplication.getInstance()
|
self._application = cura.CuraApplication.CuraApplication.getInstance()
|
||||||
self._application.getMachineManager().activeStackChanged.connect(self._update)
|
self._application.getMachineManager().activeStackChanged.connect(self._update)
|
||||||
|
|
||||||
self._selected_position = self.GLOBAL_STACK_POSITION #Must be either GLOBAL_STACK_POSITION or an extruder position (0, 1, etc.)
|
# Must be either GLOBAL_STACK_POSITION or an extruder position (0, 1, etc.)
|
||||||
|
self._selected_position = self.GLOBAL_STACK_POSITION
|
||||||
|
|
||||||
self._selected_quality_item = None # The selected quality in the quality management page
|
self._selected_quality_item = None # The selected quality in the quality management page
|
||||||
self._i18n_catalog = None
|
self._i18n_catalog = None
|
||||||
|
|
||||||
|
@ -47,14 +50,14 @@ class QualitySettingsModel(ListModel):
|
||||||
selectedPositionChanged = pyqtSignal()
|
selectedPositionChanged = pyqtSignal()
|
||||||
selectedQualityItemChanged = pyqtSignal()
|
selectedQualityItemChanged = pyqtSignal()
|
||||||
|
|
||||||
def setSelectedPosition(self, selected_position):
|
def setSelectedPosition(self, selected_position: int) -> None:
|
||||||
if selected_position != self._selected_position:
|
if selected_position != self._selected_position:
|
||||||
self._selected_position = selected_position
|
self._selected_position = selected_position
|
||||||
self.selectedPositionChanged.emit()
|
self.selectedPositionChanged.emit()
|
||||||
self._update()
|
self._update()
|
||||||
|
|
||||||
@pyqtProperty(int, fset = setSelectedPosition, notify = selectedPositionChanged)
|
@pyqtProperty(int, fset = setSelectedPosition, notify = selectedPositionChanged)
|
||||||
def selectedPosition(self):
|
def selectedPosition(self) -> int:
|
||||||
return self._selected_position
|
return self._selected_position
|
||||||
|
|
||||||
def setSelectedQualityItem(self, selected_quality_item):
|
def setSelectedQualityItem(self, selected_quality_item):
|
||||||
|
@ -67,7 +70,7 @@ class QualitySettingsModel(ListModel):
|
||||||
def selectedQualityItem(self):
|
def selectedQualityItem(self):
|
||||||
return self._selected_quality_item
|
return self._selected_quality_item
|
||||||
|
|
||||||
def _update(self):
|
def _update(self) -> None:
|
||||||
Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
|
Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
|
||||||
|
|
||||||
if not self._selected_quality_item:
|
if not self._selected_quality_item:
|
||||||
|
@ -83,7 +86,7 @@ class QualitySettingsModel(ListModel):
|
||||||
quality_changes_group = self._selected_quality_item["quality_changes_group"]
|
quality_changes_group = self._selected_quality_item["quality_changes_group"]
|
||||||
|
|
||||||
quality_node = None
|
quality_node = None
|
||||||
settings_keys = set()
|
settings_keys = set() # type: Set[str]
|
||||||
if quality_group:
|
if quality_group:
|
||||||
if self._selected_position == self.GLOBAL_STACK_POSITION:
|
if self._selected_position == self.GLOBAL_STACK_POSITION:
|
||||||
quality_node = quality_group.node_for_global
|
quality_node = quality_group.node_for_global
|
||||||
|
|
|
@ -36,8 +36,10 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
||||||
|
|
||||||
# Make sure the timer is created on the main thread
|
# Make sure the timer is created on the main thread
|
||||||
self._recompute_convex_hull_timer = None # type: Optional[QTimer]
|
self._recompute_convex_hull_timer = None # type: Optional[QTimer]
|
||||||
|
self._timer_scheduled_to_be_created = False
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
if CuraApplication.getInstance() is not None:
|
if CuraApplication.getInstance() is not None:
|
||||||
|
self._timer_scheduled_to_be_created = True
|
||||||
CuraApplication.getInstance().callLater(self.createRecomputeConvexHullTimer)
|
CuraApplication.getInstance().callLater(self.createRecomputeConvexHullTimer)
|
||||||
|
|
||||||
self._raft_thickness = 0.0
|
self._raft_thickness = 0.0
|
||||||
|
@ -171,7 +173,12 @@ class ConvexHullDecorator(SceneNodeDecorator):
|
||||||
if self._recompute_convex_hull_timer is not None:
|
if self._recompute_convex_hull_timer is not None:
|
||||||
self._recompute_convex_hull_timer.start()
|
self._recompute_convex_hull_timer.start()
|
||||||
else:
|
else:
|
||||||
self.recomputeConvexHull()
|
from cura.CuraApplication import CuraApplication
|
||||||
|
if not self._timer_scheduled_to_be_created:
|
||||||
|
# The timer is not created and we never scheduled it. Time to create it now!
|
||||||
|
CuraApplication.getInstance().callLater(self.createRecomputeConvexHullTimer)
|
||||||
|
# Now we know for sure that the timer has been scheduled for creation, so we can try this again.
|
||||||
|
CuraApplication.getInstance().callLater(self.recomputeConvexHullDelayed)
|
||||||
|
|
||||||
def recomputeConvexHull(self) -> None:
|
def recomputeConvexHull(self) -> None:
|
||||||
controller = Application.getInstance().getController()
|
controller = Application.getInstance().getController()
|
||||||
|
|
|
@ -239,6 +239,8 @@ class ContainerManager(QObject):
|
||||||
container_type = container_registry.getContainerForMimeType(mime_type)
|
container_type = container_registry.getContainerForMimeType(mime_type)
|
||||||
if not container_type:
|
if not container_type:
|
||||||
return {"status": "error", "message": "Could not find a container to handle the specified file."}
|
return {"status": "error", "message": "Could not find a container to handle the specified file."}
|
||||||
|
if not issubclass(container_type, InstanceContainer):
|
||||||
|
return {"status": "error", "message": "This is not a material container, but another type of file."}
|
||||||
|
|
||||||
container_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_url)))
|
container_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_url)))
|
||||||
container_id = container_registry.uniqueName(container_id)
|
container_id = container_registry.uniqueName(container_id)
|
||||||
|
|
|
@ -58,7 +58,10 @@ class CuraStackBuilder:
|
||||||
# Create ExtruderStacks
|
# Create ExtruderStacks
|
||||||
extruder_dict = machine_definition.getMetaDataEntry("machine_extruder_trains")
|
extruder_dict = machine_definition.getMetaDataEntry("machine_extruder_trains")
|
||||||
for position in extruder_dict:
|
for position in extruder_dict:
|
||||||
|
try:
|
||||||
cls.createExtruderStackWithDefaultSetup(new_global_stack, position)
|
cls.createExtruderStackWithDefaultSetup(new_global_stack, position)
|
||||||
|
except IndexError:
|
||||||
|
return None
|
||||||
|
|
||||||
for new_extruder in new_global_stack.extruders.values(): # Only register the extruders if we're sure that all of them are correct.
|
for new_extruder in new_global_stack.extruders.values(): # Only register the extruders if we're sure that all of them are correct.
|
||||||
registry.addContainer(new_extruder)
|
registry.addContainer(new_extruder)
|
||||||
|
|
|
@ -320,8 +320,19 @@ class MachineManager(QObject):
|
||||||
# This signal might not have been emitted yet (if it didn't change) but we still want the models to update that depend on it because we changed the contents of the containers too.
|
# This signal might not have been emitted yet (if it didn't change) but we still want the models to update that depend on it because we changed the contents of the containers too.
|
||||||
extruder_manager.activeExtruderChanged.emit()
|
extruder_manager.activeExtruderChanged.emit()
|
||||||
|
|
||||||
|
# Validate if the machine has the correct variants
|
||||||
|
# It can happen that a variant is empty, even though the machine has variants. This will ensure that that
|
||||||
|
# that situation will be fixed (and not occur again, since it switches it out to the preferred variant instead!)
|
||||||
|
machine_node = ContainerTree.getInstance().machines[global_stack.definition.getId()]
|
||||||
|
for extruder in self._global_container_stack.extruderList:
|
||||||
|
variant_name = extruder.variant.getName()
|
||||||
|
variant_node = machine_node.variants.get(variant_name)
|
||||||
|
if variant_node is None:
|
||||||
|
Logger.log("w", "An extruder has an unknown variant, switching it to the preferred variant")
|
||||||
|
self.setVariantByName(extruder.getMetaDataEntry("position"), machine_node.preferred_variant_name)
|
||||||
self.__emitChangedSignals()
|
self.__emitChangedSignals()
|
||||||
|
|
||||||
|
|
||||||
## Given a definition id, return the machine with this id.
|
## Given a definition id, return the machine with this id.
|
||||||
# Optional: add a list of keys and values to filter the list of machines with the given definition id
|
# Optional: add a list of keys and values to filter the list of machines with the given definition id
|
||||||
# \param definition_id \type{str} definition id that needs to look for
|
# \param definition_id \type{str} definition id that needs to look for
|
||||||
|
@ -336,9 +347,9 @@ class MachineManager(QObject):
|
||||||
return cast(GlobalStack, machine)
|
return cast(GlobalStack, machine)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str, result=bool)
|
||||||
@pyqtSlot(str, str)
|
@pyqtSlot(str, str, result = bool)
|
||||||
def addMachine(self, definition_id: str, name: Optional[str] = None) -> None:
|
def addMachine(self, definition_id: str, name: Optional[str] = None) -> bool:
|
||||||
Logger.log("i", "Trying to add a machine with the definition id [%s]", definition_id)
|
Logger.log("i", "Trying to add a machine with the definition id [%s]", definition_id)
|
||||||
if name is None:
|
if name is None:
|
||||||
definitions = CuraContainerRegistry.getInstance().findDefinitionContainers(id = definition_id)
|
definitions = CuraContainerRegistry.getInstance().findDefinitionContainers(id = definition_id)
|
||||||
|
@ -353,6 +364,8 @@ class MachineManager(QObject):
|
||||||
self.setActiveMachine(new_stack.getId())
|
self.setActiveMachine(new_stack.getId())
|
||||||
else:
|
else:
|
||||||
Logger.log("w", "Failed creating a new machine!")
|
Logger.log("w", "Failed creating a new machine!")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def _checkStacksHaveErrors(self) -> bool:
|
def _checkStacksHaveErrors(self) -> bool:
|
||||||
time_start = time.time()
|
time_start = time.time()
|
||||||
|
@ -1507,7 +1520,17 @@ class MachineManager(QObject):
|
||||||
if quality_id == empty_quality_container.getId():
|
if quality_id == empty_quality_container.getId():
|
||||||
extruder.intent = empty_intent_container
|
extruder.intent = empty_intent_container
|
||||||
continue
|
continue
|
||||||
quality_node = container_tree.machines[definition_id].variants[variant_name].materials[material_base_file].qualities[quality_id]
|
|
||||||
|
# Yes, we can find this in a single line of code. This makes it easier to read and it has the benefit
|
||||||
|
# that it doesn't lump key errors together for the crashlogs
|
||||||
|
try:
|
||||||
|
machine_node = container_tree.machines[definition_id]
|
||||||
|
variant_node = machine_node.variants[variant_name]
|
||||||
|
material_node = variant_node.materials[material_base_file]
|
||||||
|
quality_node = material_node.qualities[quality_id]
|
||||||
|
except KeyError as e:
|
||||||
|
Logger.error("Can't set the intent category '{category}' since the profile '{profile}' in the stack is not supported according to the container tree.".format(category = intent_category, profile = e))
|
||||||
|
continue
|
||||||
|
|
||||||
for intent_node in quality_node.intents.values():
|
for intent_node in quality_node.intents.values():
|
||||||
if intent_node.intent_category == intent_category: # Found an intent with the correct category.
|
if intent_node.intent_category == intent_category: # Found an intent with the correct category.
|
||||||
|
|
|
@ -28,7 +28,11 @@ class TextManager(QObject):
|
||||||
|
|
||||||
def _loadChangeLogText(self) -> str:
|
def _loadChangeLogText(self) -> str:
|
||||||
# Load change log texts and organize them with a dict
|
# Load change log texts and organize them with a dict
|
||||||
|
try:
|
||||||
file_path = Resources.getPath(Resources.Texts, "change_log.txt")
|
file_path = Resources.getPath(Resources.Texts, "change_log.txt")
|
||||||
|
except FileNotFoundError:
|
||||||
|
# I have no idea how / when this happens, but we're getting crash reports about it.
|
||||||
|
return ""
|
||||||
change_logs_dict = {} # type: Dict[Version, Dict[str, List[str]]]
|
change_logs_dict = {} # type: Dict[Version, Dict[str, List[str]]]
|
||||||
with open(file_path, "r", encoding = "utf-8") as f:
|
with open(file_path, "r", encoding = "utf-8") as f:
|
||||||
open_version = None # type: Optional[Version]
|
open_version = None # type: Optional[Version]
|
||||||
|
|
|
@ -6,17 +6,20 @@ from cura.API import Account
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
|
|
||||||
## Add a Authorization header to the request for Ultimaker Cloud Api requests.
|
|
||||||
# When the user is not logged in or a token is not available, a warning will be logged
|
|
||||||
# Also add the user agent headers (see DefaultUserAgentScope)
|
|
||||||
class UltimakerCloudScope(DefaultUserAgentScope):
|
class UltimakerCloudScope(DefaultUserAgentScope):
|
||||||
|
"""Add an Authorization header to the request for Ultimaker Cloud Api requests.
|
||||||
|
|
||||||
|
When the user is not logged in or a token is not available, a warning will be logged
|
||||||
|
Also add the user agent headers (see DefaultUserAgentScope)
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, application: CuraApplication):
|
def __init__(self, application: CuraApplication):
|
||||||
super().__init__(application)
|
super().__init__(application)
|
||||||
api = application.getCuraAPI()
|
api = application.getCuraAPI()
|
||||||
self._account = api.account # type: Account
|
self._account = api.account # type: Account
|
||||||
|
|
||||||
def request_hook(self, request: QNetworkRequest):
|
def requestHook(self, request: QNetworkRequest):
|
||||||
super().request_hook(request)
|
super().requestHook(request)
|
||||||
token = self._account.accessToken
|
token = self._account.accessToken
|
||||||
if not self._account.isLoggedIn or token is None:
|
if not self._account.isLoggedIn or token is None:
|
||||||
Logger.warning("Cannot add authorization to Cloud Api request")
|
Logger.warning("Cannot add authorization to Cloud Api request")
|
||||||
|
@ -25,4 +28,4 @@ class UltimakerCloudScope(DefaultUserAgentScope):
|
||||||
header_dict = {
|
header_dict = {
|
||||||
"Authorization": "Bearer {}".format(token)
|
"Authorization": "Bearer {}".format(token)
|
||||||
}
|
}
|
||||||
self.add_headers(request, header_dict)
|
self.addHeaders(request, header_dict)
|
0
cura/UltimakerCloud/__init__.py
Normal file
0
cura/UltimakerCloud/__init__.py
Normal file
28
cura_app.py
28
cura_app.py
|
@ -1,12 +1,20 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
# Copyright (c) 2019 Ultimaker B.V.
|
# Copyright (c) 2020 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
|
# Remove the working directory from sys.path.
|
||||||
|
# This fixes a security issue where Cura could import Python packages from the
|
||||||
|
# current working directory, and therefore be made to execute locally installed
|
||||||
|
# code (e.g. in the user's home directory where AppImages by default run from).
|
||||||
|
# See issue CURA-7081.
|
||||||
|
import sys
|
||||||
|
if "" in sys.path:
|
||||||
|
sys.path.remove("")
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import faulthandler
|
import faulthandler
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
|
|
||||||
# Workaround for a race condition on certain systems where there
|
# Workaround for a race condition on certain systems where there
|
||||||
# is a race condition between Arcus and PyQt. Importing Arcus
|
# is a race condition between Arcus and PyQt. Importing Arcus
|
||||||
|
@ -15,6 +23,8 @@ import sys
|
||||||
import Arcus # @UnusedImport
|
import Arcus # @UnusedImport
|
||||||
import Savitar # @UnusedImport
|
import Savitar # @UnusedImport
|
||||||
|
|
||||||
|
from PyQt5.QtNetwork import QSslConfiguration, QSslSocket
|
||||||
|
|
||||||
from UM.Platform import Platform
|
from UM.Platform import Platform
|
||||||
from cura import ApplicationMetadata
|
from cura import ApplicationMetadata
|
||||||
from cura.ApplicationMetadata import CuraAppName
|
from cura.ApplicationMetadata import CuraAppName
|
||||||
|
@ -51,13 +61,16 @@ if with_sentry_sdk:
|
||||||
except IndexError:
|
except IndexError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Errors to be ignored by Sentry
|
||||||
|
ignore_errors = [KeyboardInterrupt, MemoryError]
|
||||||
sentry_sdk.init("https://5034bf0054fb4b889f82896326e79b13@sentry.io/1821564",
|
sentry_sdk.init("https://5034bf0054fb4b889f82896326e79b13@sentry.io/1821564",
|
||||||
before_send = CrashHandler.sentryBeforeSend,
|
before_send = CrashHandler.sentryBeforeSend,
|
||||||
environment = sentry_env,
|
environment = sentry_env,
|
||||||
release = "cura%s" % ApplicationMetadata.CuraVersion,
|
release = "cura%s" % ApplicationMetadata.CuraVersion,
|
||||||
default_integrations = False,
|
default_integrations = False,
|
||||||
max_breadcrumbs = 300,
|
max_breadcrumbs = 300,
|
||||||
server_name = "cura")
|
server_name = "cura",
|
||||||
|
ignore_errors = ignore_errors)
|
||||||
|
|
||||||
if not known_args["debug"]:
|
if not known_args["debug"]:
|
||||||
def get_cura_dir_path():
|
def get_cura_dir_path():
|
||||||
|
@ -170,9 +183,9 @@ def exceptHook(hook_type, value, traceback):
|
||||||
# Set exception hook to use the crash dialog handler
|
# Set exception hook to use the crash dialog handler
|
||||||
sys.excepthook = exceptHook
|
sys.excepthook = exceptHook
|
||||||
# Enable dumping traceback for all threads
|
# Enable dumping traceback for all threads
|
||||||
if sys.stderr:
|
if sys.stderr and not sys.stderr.closed:
|
||||||
faulthandler.enable(file = sys.stderr, all_threads = True)
|
faulthandler.enable(file = sys.stderr, all_threads = True)
|
||||||
elif sys.stdout:
|
elif sys.stdout and not sys.stdout.closed:
|
||||||
faulthandler.enable(file = sys.stdout, all_threads = True)
|
faulthandler.enable(file = sys.stdout, all_threads = True)
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
@ -209,5 +222,10 @@ if Platform.isLinux() and getattr(sys, "frozen", False):
|
||||||
import trimesh.exchange.load
|
import trimesh.exchange.load
|
||||||
os.environ["LD_LIBRARY_PATH"] = old_env
|
os.environ["LD_LIBRARY_PATH"] = old_env
|
||||||
|
|
||||||
|
if ApplicationMetadata.CuraDebugMode:
|
||||||
|
ssl_conf = QSslConfiguration.defaultConfiguration()
|
||||||
|
ssl_conf.setPeerVerifyMode(QSslSocket.VerifyNone)
|
||||||
|
QSslConfiguration.setDefaultConfiguration(ssl_conf)
|
||||||
|
|
||||||
app = CuraApplication()
|
app = CuraApplication()
|
||||||
app.run()
|
app.run()
|
||||||
|
|
|
@ -86,7 +86,7 @@ class ThreeMFReader(MeshReader):
|
||||||
|
|
||||||
## Convenience function that converts a SceneNode object (as obtained from libSavitar) to a scene node.
|
## Convenience function that converts a SceneNode object (as obtained from libSavitar) to a scene node.
|
||||||
# \returns Scene node.
|
# \returns Scene node.
|
||||||
def _convertSavitarNodeToUMNode(self, savitar_node: Savitar.SceneNode) -> Optional[SceneNode]:
|
def _convertSavitarNodeToUMNode(self, savitar_node: Savitar.SceneNode, file_name: str = "") -> Optional[SceneNode]:
|
||||||
self._object_count += 1
|
self._object_count += 1
|
||||||
node_name = "Object %s" % self._object_count
|
node_name = "Object %s" % self._object_count
|
||||||
|
|
||||||
|
@ -104,6 +104,10 @@ class ThreeMFReader(MeshReader):
|
||||||
vertices = numpy.resize(data, (int(data.size / 3), 3))
|
vertices = numpy.resize(data, (int(data.size / 3), 3))
|
||||||
mesh_builder.setVertices(vertices)
|
mesh_builder.setVertices(vertices)
|
||||||
mesh_builder.calculateNormals(fast=True)
|
mesh_builder.calculateNormals(fast=True)
|
||||||
|
if file_name:
|
||||||
|
# The filename is used to give the user the option to reload the file if it is changed on disk
|
||||||
|
# It is only set for the root node of the 3mf file
|
||||||
|
mesh_builder.setFileName(file_name)
|
||||||
mesh_data = mesh_builder.build()
|
mesh_data = mesh_builder.build()
|
||||||
|
|
||||||
if len(mesh_data.getVertices()):
|
if len(mesh_data.getVertices()):
|
||||||
|
@ -171,7 +175,7 @@ class ThreeMFReader(MeshReader):
|
||||||
scene_3mf = parser.parse(archive.open("3D/3dmodel.model").read())
|
scene_3mf = parser.parse(archive.open("3D/3dmodel.model").read())
|
||||||
self._unit = scene_3mf.getUnit()
|
self._unit = scene_3mf.getUnit()
|
||||||
for node in scene_3mf.getSceneNodes():
|
for node in scene_3mf.getSceneNodes():
|
||||||
um_node = self._convertSavitarNodeToUMNode(node)
|
um_node = self._convertSavitarNodeToUMNode(node, file_name)
|
||||||
if um_node is None:
|
if um_node is None:
|
||||||
continue
|
continue
|
||||||
# compensate for original center position, if object(s) is/are not around its zero position
|
# compensate for original center position, if object(s) is/are not around its zero position
|
||||||
|
|
|
@ -285,13 +285,13 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||||
serialized = archive.open(instance_container_file_name).read().decode("utf-8")
|
serialized = archive.open(instance_container_file_name).read().decode("utf-8")
|
||||||
|
|
||||||
# Qualities and variants don't have upgrades, so don't upgrade them
|
# Qualities and variants don't have upgrades, so don't upgrade them
|
||||||
parser = ConfigParser(interpolation = None)
|
parser = ConfigParser(interpolation = None, comment_prefixes = ())
|
||||||
parser.read_string(serialized)
|
parser.read_string(serialized)
|
||||||
container_type = parser["metadata"]["type"]
|
container_type = parser["metadata"]["type"]
|
||||||
if container_type not in ("quality", "variant"):
|
if container_type not in ("quality", "variant"):
|
||||||
serialized = InstanceContainer._updateSerialized(serialized, instance_container_file_name)
|
serialized = InstanceContainer._updateSerialized(serialized, instance_container_file_name)
|
||||||
|
|
||||||
parser = ConfigParser(interpolation = None)
|
parser = ConfigParser(interpolation = None, comment_prefixes = ())
|
||||||
parser.read_string(serialized)
|
parser.read_string(serialized)
|
||||||
container_info = ContainerInfo(instance_container_file_name, serialized, parser)
|
container_info = ContainerInfo(instance_container_file_name, serialized, parser)
|
||||||
instance_container_info_dict[container_id] = container_info
|
instance_container_info_dict[container_id] = container_info
|
||||||
|
|
|
@ -118,7 +118,7 @@ class AMFReader(MeshReader):
|
||||||
mesh.merge_vertices()
|
mesh.merge_vertices()
|
||||||
mesh.remove_unreferenced_vertices()
|
mesh.remove_unreferenced_vertices()
|
||||||
mesh.fix_normals()
|
mesh.fix_normals()
|
||||||
mesh_data = self._toMeshData(mesh)
|
mesh_data = self._toMeshData(mesh, file_name)
|
||||||
|
|
||||||
new_node = CuraSceneNode()
|
new_node = CuraSceneNode()
|
||||||
new_node.setSelectable(True)
|
new_node.setSelectable(True)
|
||||||
|
@ -147,7 +147,13 @@ class AMFReader(MeshReader):
|
||||||
|
|
||||||
return group_node
|
return group_node
|
||||||
|
|
||||||
def _toMeshData(self, tri_node: trimesh.base.Trimesh) -> MeshData:
|
## Converts a Trimesh to Uranium's MeshData.
|
||||||
|
# \param tri_node A Trimesh containing the contents of a file that was
|
||||||
|
# just read.
|
||||||
|
# \param file_name The full original filename used to watch for changes
|
||||||
|
# \return Mesh data from the Trimesh in a way that Uranium can understand
|
||||||
|
# it.
|
||||||
|
def _toMeshData(self, tri_node: trimesh.base.Trimesh, file_name: str = "") -> MeshData:
|
||||||
tri_faces = tri_node.faces
|
tri_faces = tri_node.faces
|
||||||
tri_vertices = tri_node.vertices
|
tri_vertices = tri_node.vertices
|
||||||
|
|
||||||
|
@ -169,5 +175,5 @@ class AMFReader(MeshReader):
|
||||||
indices = numpy.asarray(indices, dtype = numpy.int32)
|
indices = numpy.asarray(indices, dtype = numpy.int32)
|
||||||
normals = calculateNormalsFromIndexedVertices(vertices, indices, face_count)
|
normals = calculateNormalsFromIndexedVertices(vertices, indices, face_count)
|
||||||
|
|
||||||
mesh_data = MeshData(vertices = vertices, indices = indices, normals = normals)
|
mesh_data = MeshData(vertices = vertices, indices = indices, normals = normals,file_name = file_name)
|
||||||
return mesh_data
|
return mesh_data
|
||||||
|
|
119
plugins/CuraDrive/src/CreateBackupJob.py
Normal file
119
plugins/CuraDrive/src/CreateBackupJob.py
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
# Copyright (c) 2020 Ultimaker B.V.
|
||||||
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
import json
|
||||||
|
import threading
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
|
from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
|
||||||
|
|
||||||
|
from UM.Job import Job
|
||||||
|
from UM.Logger import Logger
|
||||||
|
from UM.Message import Message
|
||||||
|
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
|
||||||
|
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
|
||||||
|
from UM.i18n import i18nCatalog
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
|
||||||
|
|
||||||
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
|
||||||
|
class CreateBackupJob(Job):
|
||||||
|
"""Creates backup zip, requests upload url and uploads the backup file to cloud storage."""
|
||||||
|
|
||||||
|
MESSAGE_TITLE = catalog.i18nc("@info:title", "Backups")
|
||||||
|
DEFAULT_UPLOAD_ERROR_MESSAGE = catalog.i18nc("@info:backup_status", "There was an error while uploading your backup.")
|
||||||
|
|
||||||
|
def __init__(self, api_backup_url: str) -> None:
|
||||||
|
""" Create a new backup Job. start the job by calling start()
|
||||||
|
|
||||||
|
:param api_backup_url: The url of the 'backups' endpoint of the Cura Drive Api
|
||||||
|
"""
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self._api_backup_url = api_backup_url
|
||||||
|
self._json_cloud_scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance()))
|
||||||
|
|
||||||
|
self._backup_zip = None # type: Optional[bytes]
|
||||||
|
self._job_done = threading.Event()
|
||||||
|
"""Set when the job completes. Does not indicate success."""
|
||||||
|
self.backup_upload_error_message = ""
|
||||||
|
"""After the job completes, an empty string indicates success. Othrerwise, the value is a translated message."""
|
||||||
|
|
||||||
|
def run(self) -> None:
|
||||||
|
upload_message = Message(catalog.i18nc("@info:backup_status", "Creating your backup..."), title = self.MESSAGE_TITLE, progress = -1)
|
||||||
|
upload_message.show()
|
||||||
|
CuraApplication.getInstance().processEvents()
|
||||||
|
cura_api = CuraApplication.getInstance().getCuraAPI()
|
||||||
|
self._backup_zip, backup_meta_data = cura_api.backups.createBackup()
|
||||||
|
|
||||||
|
if not self._backup_zip or not backup_meta_data:
|
||||||
|
self.backup_upload_error_message = catalog.i18nc("@info:backup_status", "There was an error while creating your backup.")
|
||||||
|
upload_message.hide()
|
||||||
|
return
|
||||||
|
|
||||||
|
upload_message.setText(catalog.i18nc("@info:backup_status", "Uploading your backup..."))
|
||||||
|
CuraApplication.getInstance().processEvents()
|
||||||
|
|
||||||
|
# Create an upload entry for the backup.
|
||||||
|
timestamp = datetime.now().isoformat()
|
||||||
|
backup_meta_data["description"] = "{}.backup.{}.cura.zip".format(timestamp, backup_meta_data["cura_release"])
|
||||||
|
self._requestUploadSlot(backup_meta_data, len(self._backup_zip))
|
||||||
|
|
||||||
|
self._job_done.wait()
|
||||||
|
if self.backup_upload_error_message == "":
|
||||||
|
upload_message.setText(catalog.i18nc("@info:backup_status", "Your backup has finished uploading."))
|
||||||
|
upload_message.setProgress(None) # Hide progress bar
|
||||||
|
else:
|
||||||
|
# some error occurred. This error is presented to the user by DrivePluginExtension
|
||||||
|
upload_message.hide()
|
||||||
|
|
||||||
|
def _requestUploadSlot(self, backup_metadata: Dict[str, Any], backup_size: int) -> None:
|
||||||
|
"""Request a backup upload slot from the API.
|
||||||
|
|
||||||
|
:param backup_metadata: A dict containing some meta data about the backup.
|
||||||
|
:param backup_size: The size of the backup file in bytes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
payload = json.dumps({"data": {"backup_size": backup_size,
|
||||||
|
"metadata": backup_metadata
|
||||||
|
}
|
||||||
|
}).encode()
|
||||||
|
|
||||||
|
HttpRequestManager.getInstance().put(
|
||||||
|
self._api_backup_url,
|
||||||
|
data = payload,
|
||||||
|
callback = self._onUploadSlotCompleted,
|
||||||
|
error_callback = self._onUploadSlotCompleted,
|
||||||
|
scope = self._json_cloud_scope)
|
||||||
|
|
||||||
|
def _onUploadSlotCompleted(self, reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None) -> None:
|
||||||
|
if error is not None:
|
||||||
|
Logger.warning(str(error))
|
||||||
|
self.backup_upload_error_message = self.DEFAULT_UPLOAD_ERROR_MESSAGE
|
||||||
|
self._job_done.set()
|
||||||
|
return
|
||||||
|
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) >= 300:
|
||||||
|
Logger.warning("Could not request backup upload: %s", HttpRequestManager.readText(reply))
|
||||||
|
self.backup_upload_error_message = self.DEFAULT_UPLOAD_ERROR_MESSAGE
|
||||||
|
self._job_done.set()
|
||||||
|
return
|
||||||
|
|
||||||
|
backup_upload_url = HttpRequestManager.readJSON(reply)["data"]["upload_url"]
|
||||||
|
|
||||||
|
# Upload the backup to storage.
|
||||||
|
HttpRequestManager.getInstance().put(
|
||||||
|
backup_upload_url,
|
||||||
|
data=self._backup_zip,
|
||||||
|
callback=self._uploadFinishedCallback,
|
||||||
|
error_callback=self._uploadFinishedCallback
|
||||||
|
)
|
||||||
|
|
||||||
|
def _uploadFinishedCallback(self, reply: QNetworkReply, error: QNetworkReply.NetworkError = None):
|
||||||
|
if not HttpRequestManager.replyIndicatesSuccess(reply, error):
|
||||||
|
Logger.log("w", "Could not upload backup file: %s", HttpRequestManager.readText(reply))
|
||||||
|
self.backup_upload_error_message = self.DEFAULT_UPLOAD_ERROR_MESSAGE
|
||||||
|
|
||||||
|
self._job_done.set()
|
|
@ -1,90 +1,70 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import base64
|
from typing import Any, Optional, List, Dict, Callable
|
||||||
import hashlib
|
|
||||||
from datetime import datetime
|
|
||||||
from tempfile import NamedTemporaryFile
|
|
||||||
from typing import Any, Optional, List, Dict
|
|
||||||
|
|
||||||
import requests
|
from PyQt5.QtNetwork import QNetworkReply
|
||||||
|
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Message import Message
|
|
||||||
from UM.Signal import Signal, signalemitter
|
from UM.Signal import Signal, signalemitter
|
||||||
|
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
|
||||||
|
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
|
||||||
|
from UM.i18n import i18nCatalog
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
|
||||||
from .UploadBackupJob import UploadBackupJob
|
from .CreateBackupJob import CreateBackupJob
|
||||||
|
from .RestoreBackupJob import RestoreBackupJob
|
||||||
from .Settings import Settings
|
from .Settings import Settings
|
||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
|
||||||
## The DriveApiService is responsible for interacting with the CuraDrive API and Cura's backup handling.
|
|
||||||
@signalemitter
|
@signalemitter
|
||||||
class DriveApiService:
|
class DriveApiService:
|
||||||
|
"""The DriveApiService is responsible for interacting with the CuraDrive API and Cura's backup handling."""
|
||||||
|
|
||||||
BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL)
|
BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL)
|
||||||
|
|
||||||
# Emit signal when restoring backup started or finished.
|
|
||||||
restoringStateChanged = Signal()
|
restoringStateChanged = Signal()
|
||||||
|
"""Emits signal when restoring backup started or finished."""
|
||||||
|
|
||||||
# Emit signal when creating backup started or finished.
|
|
||||||
creatingStateChanged = Signal()
|
creatingStateChanged = Signal()
|
||||||
|
"""Emits signal when creating backup started or finished."""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self._cura_api = CuraApplication.getInstance().getCuraAPI()
|
self._cura_api = CuraApplication.getInstance().getCuraAPI()
|
||||||
|
self._json_cloud_scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance()))
|
||||||
|
|
||||||
def getBackups(self) -> List[Dict[str, Any]]:
|
def getBackups(self, changed: Callable[[List[Dict[str, Any]]], None]) -> None:
|
||||||
access_token = self._cura_api.account.accessToken
|
def callback(reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None) -> None:
|
||||||
if not access_token:
|
if error is not None:
|
||||||
Logger.log("w", "Could not get access token.")
|
Logger.log("w", "Could not get backups: " + str(error))
|
||||||
return []
|
changed([])
|
||||||
try:
|
return
|
||||||
backup_list_request = requests.get(self.BACKUP_URL, headers = {
|
|
||||||
"Authorization": "Bearer {}".format(access_token)
|
|
||||||
})
|
|
||||||
except requests.exceptions.ConnectionError:
|
|
||||||
Logger.logException("w", "Unable to connect with the server.")
|
|
||||||
return []
|
|
||||||
|
|
||||||
# HTTP status 300s mean redirection. 400s and 500s are errors.
|
backup_list_response = HttpRequestManager.readJSON(reply)
|
||||||
# Technically 300s are not errors, but the use case here relies on "requests" to handle redirects automatically.
|
|
||||||
if backup_list_request.status_code >= 300:
|
|
||||||
Logger.log("w", "Could not get backups list from remote: %s", backup_list_request.text)
|
|
||||||
Message(catalog.i18nc("@info:backup_status", "There was an error listing your backups."), title = catalog.i18nc("@info:title", "Backup")).show()
|
|
||||||
return []
|
|
||||||
|
|
||||||
backup_list_response = backup_list_request.json()
|
|
||||||
if "data" not in backup_list_response:
|
if "data" not in backup_list_response:
|
||||||
Logger.log("w", "Could not get backups from remote, actual response body was: %s", str(backup_list_response))
|
Logger.log("w", "Could not get backups from remote, actual response body was: %s",
|
||||||
return []
|
str(backup_list_response))
|
||||||
|
changed([]) # empty list of backups
|
||||||
|
return
|
||||||
|
|
||||||
return backup_list_response["data"]
|
changed(backup_list_response["data"])
|
||||||
|
|
||||||
|
HttpRequestManager.getInstance().get(
|
||||||
|
self.BACKUP_URL,
|
||||||
|
callback= callback,
|
||||||
|
error_callback = callback,
|
||||||
|
scope=self._json_cloud_scope
|
||||||
|
)
|
||||||
|
|
||||||
def createBackup(self) -> None:
|
def createBackup(self) -> None:
|
||||||
self.creatingStateChanged.emit(is_creating = True)
|
self.creatingStateChanged.emit(is_creating = True)
|
||||||
|
upload_backup_job = CreateBackupJob(self.BACKUP_URL)
|
||||||
# Create the backup.
|
|
||||||
backup_zip_file, backup_meta_data = self._cura_api.backups.createBackup()
|
|
||||||
if not backup_zip_file or not backup_meta_data:
|
|
||||||
self.creatingStateChanged.emit(is_creating = False, error_message ="Could not create backup.")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Create an upload entry for the backup.
|
|
||||||
timestamp = datetime.now().isoformat()
|
|
||||||
backup_meta_data["description"] = "{}.backup.{}.cura.zip".format(timestamp, backup_meta_data["cura_release"])
|
|
||||||
backup_upload_url = self._requestBackupUpload(backup_meta_data, len(backup_zip_file))
|
|
||||||
if not backup_upload_url:
|
|
||||||
self.creatingStateChanged.emit(is_creating = False, error_message ="Could not upload backup.")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Upload the backup to storage.
|
|
||||||
upload_backup_job = UploadBackupJob(backup_upload_url, backup_zip_file)
|
|
||||||
upload_backup_job.finished.connect(self._onUploadFinished)
|
upload_backup_job.finished.connect(self._onUploadFinished)
|
||||||
upload_backup_job.start()
|
upload_backup_job.start()
|
||||||
|
|
||||||
def _onUploadFinished(self, job: "UploadBackupJob") -> None:
|
def _onUploadFinished(self, job: "CreateBackupJob") -> None:
|
||||||
if job.backup_upload_error_message != "":
|
if job.backup_upload_error_message != "":
|
||||||
# If the job contains an error message we pass it along so the UI can display it.
|
# If the job contains an error message we pass it along so the UI can display it.
|
||||||
self.creatingStateChanged.emit(is_creating = False, error_message = job.backup_upload_error_message)
|
self.creatingStateChanged.emit(is_creating = False, error_message = job.backup_upload_error_message)
|
||||||
|
@ -96,96 +76,38 @@ class DriveApiService:
|
||||||
download_url = backup.get("download_url")
|
download_url = backup.get("download_url")
|
||||||
if not download_url:
|
if not download_url:
|
||||||
# If there is no download URL, we can't restore the backup.
|
# If there is no download URL, we can't restore the backup.
|
||||||
return self._emitRestoreError()
|
Logger.warning("backup download_url is missing. Aborting backup.")
|
||||||
|
|
||||||
try:
|
|
||||||
download_package = requests.get(download_url, stream = True)
|
|
||||||
except requests.exceptions.ConnectionError:
|
|
||||||
Logger.logException("e", "Unable to connect with the server")
|
|
||||||
return self._emitRestoreError()
|
|
||||||
|
|
||||||
if download_package.status_code >= 300:
|
|
||||||
# Something went wrong when attempting to download the backup.
|
|
||||||
Logger.log("w", "Could not download backup from url %s: %s", download_url, download_package.text)
|
|
||||||
return self._emitRestoreError()
|
|
||||||
|
|
||||||
# We store the file in a temporary path fist to ensure integrity.
|
|
||||||
temporary_backup_file = NamedTemporaryFile(delete = False)
|
|
||||||
with open(temporary_backup_file.name, "wb") as write_backup:
|
|
||||||
for chunk in download_package:
|
|
||||||
write_backup.write(chunk)
|
|
||||||
|
|
||||||
if not self._verifyMd5Hash(temporary_backup_file.name, backup.get("md5_hash", "")):
|
|
||||||
# Don't restore the backup if the MD5 hashes do not match.
|
|
||||||
# This can happen if the download was interrupted.
|
|
||||||
Logger.log("w", "Remote and local MD5 hashes do not match, not restoring backup.")
|
|
||||||
return self._emitRestoreError()
|
|
||||||
|
|
||||||
# Tell Cura to place the backup back in the user data folder.
|
|
||||||
with open(temporary_backup_file.name, "rb") as read_backup:
|
|
||||||
self._cura_api.backups.restoreBackup(read_backup.read(), backup.get("metadata", {}))
|
|
||||||
self.restoringStateChanged.emit(is_restoring = False)
|
|
||||||
|
|
||||||
def _emitRestoreError(self) -> None:
|
|
||||||
self.restoringStateChanged.emit(is_restoring = False,
|
self.restoringStateChanged.emit(is_restoring = False,
|
||||||
error_message = catalog.i18nc("@info:backup_status",
|
error_message = catalog.i18nc("@info:backup_status",
|
||||||
"There was an error trying to restore your backup."))
|
"There was an error trying to restore your backup."))
|
||||||
|
return
|
||||||
|
|
||||||
|
restore_backup_job = RestoreBackupJob(backup)
|
||||||
|
restore_backup_job.finished.connect(self._onRestoreFinished)
|
||||||
|
restore_backup_job.start()
|
||||||
|
|
||||||
|
def _onRestoreFinished(self, job: "RestoreBackupJob") -> None:
|
||||||
|
if job.restore_backup_error_message != "":
|
||||||
|
# If the job contains an error message we pass it along so the UI can display it.
|
||||||
|
self.restoringStateChanged.emit(is_restoring=False)
|
||||||
|
else:
|
||||||
|
self.restoringStateChanged.emit(is_restoring = False, error_message = job.restore_backup_error_message)
|
||||||
|
|
||||||
|
def deleteBackup(self, backup_id: str, finished_callable: Callable[[bool], None]):
|
||||||
|
|
||||||
|
def finishedCallback(reply: QNetworkReply, ca: Callable[[bool], None] = finished_callable) -> None:
|
||||||
|
self._onDeleteRequestCompleted(reply, ca)
|
||||||
|
|
||||||
|
def errorCallback(reply: QNetworkReply, error: QNetworkReply.NetworkError, ca: Callable[[bool], None] = finished_callable) -> None:
|
||||||
|
self._onDeleteRequestCompleted(reply, ca, error)
|
||||||
|
|
||||||
|
HttpRequestManager.getInstance().delete(
|
||||||
|
url = "{}/{}".format(self.BACKUP_URL, backup_id),
|
||||||
|
callback = finishedCallback,
|
||||||
|
error_callback = errorCallback,
|
||||||
|
scope= self._json_cloud_scope
|
||||||
|
)
|
||||||
|
|
||||||
# Verify the MD5 hash of a file.
|
|
||||||
# \param file_path Full path to the file.
|
|
||||||
# \param known_hash The known MD5 hash of the file.
|
|
||||||
# \return: Success or not.
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _verifyMd5Hash(file_path: str, known_hash: str) -> bool:
|
def _onDeleteRequestCompleted(reply: QNetworkReply, callable: Callable[[bool], None], error: Optional["QNetworkReply.NetworkError"] = None) -> None:
|
||||||
with open(file_path, "rb") as read_backup:
|
callable(HttpRequestManager.replyIndicatesSuccess(reply, error))
|
||||||
local_md5_hash = base64.b64encode(hashlib.md5(read_backup.read()).digest(), altchars = b"_-").decode("utf-8")
|
|
||||||
return known_hash == local_md5_hash
|
|
||||||
|
|
||||||
def deleteBackup(self, backup_id: str) -> bool:
|
|
||||||
access_token = self._cura_api.account.accessToken
|
|
||||||
if not access_token:
|
|
||||||
Logger.log("w", "Could not get access token.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
delete_backup = requests.delete("{}/{}".format(self.BACKUP_URL, backup_id), headers = {
|
|
||||||
"Authorization": "Bearer {}".format(access_token)
|
|
||||||
})
|
|
||||||
except requests.exceptions.ConnectionError:
|
|
||||||
Logger.logException("e", "Unable to connect with the server")
|
|
||||||
return False
|
|
||||||
|
|
||||||
if delete_backup.status_code >= 300:
|
|
||||||
Logger.log("w", "Could not delete backup: %s", delete_backup.text)
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Request a backup upload slot from the API.
|
|
||||||
# \param backup_metadata: A dict containing some meta data about the backup.
|
|
||||||
# \param backup_size The size of the backup file in bytes.
|
|
||||||
# \return: The upload URL for the actual backup file if successful, otherwise None.
|
|
||||||
def _requestBackupUpload(self, backup_metadata: Dict[str, Any], backup_size: int) -> Optional[str]:
|
|
||||||
access_token = self._cura_api.account.accessToken
|
|
||||||
if not access_token:
|
|
||||||
Logger.log("w", "Could not get access token.")
|
|
||||||
return None
|
|
||||||
try:
|
|
||||||
backup_upload_request = requests.put(
|
|
||||||
self.BACKUP_URL,
|
|
||||||
json = {"data": {"backup_size": backup_size,
|
|
||||||
"metadata": backup_metadata
|
|
||||||
}
|
|
||||||
},
|
|
||||||
headers = {
|
|
||||||
"Authorization": "Bearer {}".format(access_token)
|
|
||||||
})
|
|
||||||
except requests.exceptions.ConnectionError:
|
|
||||||
Logger.logException("e", "Unable to connect with the server")
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Any status code of 300 or above indicates an error.
|
|
||||||
if backup_upload_request.status_code >= 300:
|
|
||||||
Logger.log("w", "Could not request backup upload: %s", backup_upload_request.text)
|
|
||||||
return None
|
|
||||||
|
|
||||||
return backup_upload_request.json()["data"]["upload_url"]
|
|
||||||
|
|
|
@ -133,7 +133,10 @@ class DrivePluginExtension(QObject, Extension):
|
||||||
|
|
||||||
@pyqtSlot(name = "refreshBackups")
|
@pyqtSlot(name = "refreshBackups")
|
||||||
def refreshBackups(self) -> None:
|
def refreshBackups(self) -> None:
|
||||||
self._backups = self._drive_api_service.getBackups()
|
self._drive_api_service.getBackups(self._backupsChangedCallback)
|
||||||
|
|
||||||
|
def _backupsChangedCallback(self, backups: List[Dict[str, Any]]) -> None:
|
||||||
|
self._backups = backups
|
||||||
self.backupsChanged.emit()
|
self.backupsChanged.emit()
|
||||||
|
|
||||||
@pyqtProperty(bool, notify = restoringStateChanged)
|
@pyqtProperty(bool, notify = restoringStateChanged)
|
||||||
|
@ -158,5 +161,8 @@ class DrivePluginExtension(QObject, Extension):
|
||||||
|
|
||||||
@pyqtSlot(str, name = "deleteBackup")
|
@pyqtSlot(str, name = "deleteBackup")
|
||||||
def deleteBackup(self, backup_id: str) -> None:
|
def deleteBackup(self, backup_id: str) -> None:
|
||||||
self._drive_api_service.deleteBackup(backup_id)
|
self._drive_api_service.deleteBackup(backup_id, self._backupDeletedCallback)
|
||||||
|
|
||||||
|
def _backupDeletedCallback(self, success: bool):
|
||||||
|
if success:
|
||||||
self.refreshBackups()
|
self.refreshBackups()
|
||||||
|
|
92
plugins/CuraDrive/src/RestoreBackupJob.py
Normal file
92
plugins/CuraDrive/src/RestoreBackupJob.py
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
|
import threading
|
||||||
|
from tempfile import NamedTemporaryFile
|
||||||
|
from typing import Optional, Any, Dict
|
||||||
|
|
||||||
|
from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
|
||||||
|
|
||||||
|
from UM.Job import Job
|
||||||
|
from UM.Logger import Logger
|
||||||
|
from UM.PackageManager import catalog
|
||||||
|
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
|
||||||
|
|
||||||
|
class RestoreBackupJob(Job):
|
||||||
|
"""Downloads a backup and overwrites local configuration with the backup.
|
||||||
|
|
||||||
|
When `Job.finished` emits, `restore_backup_error_message` will either be `""` (no error) or an error message
|
||||||
|
"""
|
||||||
|
|
||||||
|
DISK_WRITE_BUFFER_SIZE = 512 * 1024
|
||||||
|
DEFAULT_ERROR_MESSAGE = catalog.i18nc("@info:backup_status", "There was an error trying to restore your backup.")
|
||||||
|
|
||||||
|
def __init__(self, backup: Dict[str, Any]) -> None:
|
||||||
|
""" Create a new restore Job. start the job by calling start()
|
||||||
|
|
||||||
|
:param backup: A dict containing a backup spec
|
||||||
|
"""
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
self._job_done = threading.Event()
|
||||||
|
|
||||||
|
self._backup = backup
|
||||||
|
self.restore_backup_error_message = ""
|
||||||
|
|
||||||
|
def run(self) -> None:
|
||||||
|
|
||||||
|
url = self._backup.get("download_url")
|
||||||
|
assert url is not None
|
||||||
|
|
||||||
|
HttpRequestManager.getInstance().get(
|
||||||
|
url = url,
|
||||||
|
callback = self._onRestoreRequestCompleted,
|
||||||
|
error_callback = self._onRestoreRequestCompleted
|
||||||
|
)
|
||||||
|
|
||||||
|
self._job_done.wait() # A job is considered finished when the run function completes
|
||||||
|
|
||||||
|
def _onRestoreRequestCompleted(self, reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None) -> None:
|
||||||
|
if not HttpRequestManager.replyIndicatesSuccess(reply, error):
|
||||||
|
Logger.warning("Requesting backup failed, response code %s while trying to connect to %s",
|
||||||
|
reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url())
|
||||||
|
self.restore_backup_error_message = self.DEFAULT_ERROR_MESSAGE
|
||||||
|
self._job_done.set()
|
||||||
|
return
|
||||||
|
|
||||||
|
# We store the file in a temporary path fist to ensure integrity.
|
||||||
|
temporary_backup_file = NamedTemporaryFile(delete = False)
|
||||||
|
with open(temporary_backup_file.name, "wb") as write_backup:
|
||||||
|
app = CuraApplication.getInstance()
|
||||||
|
bytes_read = reply.read(self.DISK_WRITE_BUFFER_SIZE)
|
||||||
|
while bytes_read:
|
||||||
|
write_backup.write(bytes_read)
|
||||||
|
bytes_read = reply.read(self.DISK_WRITE_BUFFER_SIZE)
|
||||||
|
app.processEvents()
|
||||||
|
|
||||||
|
if not self._verifyMd5Hash(temporary_backup_file.name, self._backup.get("md5_hash", "")):
|
||||||
|
# Don't restore the backup if the MD5 hashes do not match.
|
||||||
|
# This can happen if the download was interrupted.
|
||||||
|
Logger.log("w", "Remote and local MD5 hashes do not match, not restoring backup.")
|
||||||
|
self.restore_backup_error_message = self.DEFAULT_ERROR_MESSAGE
|
||||||
|
|
||||||
|
# Tell Cura to place the backup back in the user data folder.
|
||||||
|
with open(temporary_backup_file.name, "rb") as read_backup:
|
||||||
|
cura_api = CuraApplication.getInstance().getCuraAPI()
|
||||||
|
cura_api.backups.restoreBackup(read_backup.read(), self._backup.get("metadata", {}))
|
||||||
|
|
||||||
|
self._job_done.set()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _verifyMd5Hash(file_path: str, known_hash: str) -> bool:
|
||||||
|
"""Verify the MD5 hash of a file.
|
||||||
|
|
||||||
|
:param file_path: Full path to the file.
|
||||||
|
:param known_hash: The known MD5 hash of the file.
|
||||||
|
:return: Success or not.
|
||||||
|
"""
|
||||||
|
|
||||||
|
with open(file_path, "rb") as read_backup:
|
||||||
|
local_md5_hash = base64.b64encode(hashlib.md5(read_backup.read()).digest(), altchars = b"_-").decode("utf-8")
|
||||||
|
return known_hash == local_md5_hash
|
|
@ -1,7 +1,7 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
from cura import UltimakerCloudAuthentication
|
from cura.UltimakerCloud import UltimakerCloudAuthentication
|
||||||
|
|
||||||
|
|
||||||
class Settings:
|
class Settings:
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
# Copyright (c) 2018 Ultimaker B.V.
|
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
|
||||||
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from UM.Job import Job
|
|
||||||
from UM.Logger import Logger
|
|
||||||
from UM.Message import Message
|
|
||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
|
||||||
catalog = i18nCatalog("cura")
|
|
||||||
|
|
||||||
|
|
||||||
class UploadBackupJob(Job):
|
|
||||||
MESSAGE_TITLE = catalog.i18nc("@info:title", "Backups")
|
|
||||||
|
|
||||||
# This job is responsible for uploading the backup file to cloud storage.
|
|
||||||
# As it can take longer than some other tasks, we schedule this using a Cura Job.
|
|
||||||
def __init__(self, signed_upload_url: str, backup_zip: bytes) -> None:
|
|
||||||
super().__init__()
|
|
||||||
self._signed_upload_url = signed_upload_url
|
|
||||||
self._backup_zip = backup_zip
|
|
||||||
self._upload_success = False
|
|
||||||
self.backup_upload_error_message = ""
|
|
||||||
|
|
||||||
def run(self) -> None:
|
|
||||||
upload_message = Message(catalog.i18nc("@info:backup_status", "Uploading your backup..."), title = self.MESSAGE_TITLE, progress = -1)
|
|
||||||
upload_message.show()
|
|
||||||
|
|
||||||
backup_upload = requests.put(self._signed_upload_url, data = self._backup_zip)
|
|
||||||
upload_message.hide()
|
|
||||||
|
|
||||||
if backup_upload.status_code >= 300:
|
|
||||||
self.backup_upload_error_message = backup_upload.text
|
|
||||||
Logger.log("w", "Could not upload backup file: %s", backup_upload.text)
|
|
||||||
Message(catalog.i18nc("@info:backup_status", "There was an error while uploading your backup."), title = self.MESSAGE_TITLE).show()
|
|
||||||
else:
|
|
||||||
self._upload_success = True
|
|
||||||
Message(catalog.i18nc("@info:backup_status", "Your backup has finished uploading."), title = self.MESSAGE_TITLE).show()
|
|
||||||
|
|
||||||
self.finished.emit(self)
|
|
|
@ -421,7 +421,10 @@ class CuraEngineBackend(QObject, Backend):
|
||||||
|
|
||||||
if job.getResult() == StartJobResult.NothingToSlice:
|
if job.getResult() == StartJobResult.NothingToSlice:
|
||||||
if self._application.platformActivity:
|
if self._application.platformActivity:
|
||||||
self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume or are assigned to a disabled extruder. Please scale or rotate models to fit, or enable an extruder."),
|
self._error_message = Message(catalog.i18nc("@info:status", "Please review settings and check if your models:"
|
||||||
|
"\n- Fit within the build volume"
|
||||||
|
"\n- Are assigned to an enabled extruder"
|
||||||
|
"\n- Are not all set as modifier meshes"),
|
||||||
title = catalog.i18nc("@info:title", "Unable to slice"))
|
title = catalog.i18nc("@info:title", "Unable to slice"))
|
||||||
self._error_message.show()
|
self._error_message.show()
|
||||||
self.setState(BackendState.Error)
|
self.setState(BackendState.Error)
|
||||||
|
|
|
@ -422,13 +422,14 @@ class StartSliceJob(Job):
|
||||||
|
|
||||||
# Pre-compute material material_bed_temp_prepend and material_print_temp_prepend
|
# Pre-compute material material_bed_temp_prepend and material_print_temp_prepend
|
||||||
start_gcode = settings["machine_start_gcode"]
|
start_gcode = settings["machine_start_gcode"]
|
||||||
|
# Remove all the comments from the start g-code
|
||||||
|
start_gcode = re.sub(r";.+?(\n|$)", "\n", start_gcode)
|
||||||
bed_temperature_settings = ["material_bed_temperature", "material_bed_temperature_layer_0"]
|
bed_temperature_settings = ["material_bed_temperature", "material_bed_temperature_layer_0"]
|
||||||
pattern = r"\{(%s)(,\s?\w+)?\}" % "|".join(bed_temperature_settings) # match {setting} as well as {setting, extruder_nr}
|
pattern = r"\{(%s)(,\s?\w+)?\}" % "|".join(bed_temperature_settings) # match {setting} as well as {setting, extruder_nr}
|
||||||
settings["material_bed_temp_prepend"] = re.search(pattern, start_gcode) == None
|
settings["material_bed_temp_prepend"] = re.search(pattern, start_gcode) == None
|
||||||
print_temperature_settings = ["material_print_temperature", "material_print_temperature_layer_0", "default_material_print_temperature", "material_initial_print_temperature", "material_final_print_temperature", "material_standby_temperature"]
|
print_temperature_settings = ["material_print_temperature", "material_print_temperature_layer_0", "default_material_print_temperature", "material_initial_print_temperature", "material_final_print_temperature", "material_standby_temperature"]
|
||||||
pattern = r"\{(%s)(,\s?\w+)?\}" % "|".join(print_temperature_settings) # match {setting} as well as {setting, extruder_nr}
|
pattern = r"\{(%s)(,\s?\w+)?\}" % "|".join(print_temperature_settings) # match {setting} as well as {setting, extruder_nr}
|
||||||
settings["material_print_temp_prepend"] = re.search(pattern, start_gcode) == None
|
settings["material_print_temp_prepend"] = re.search(pattern, start_gcode) == None
|
||||||
|
|
||||||
# Replace the setting tokens in start and end g-code.
|
# Replace the setting tokens in start and end g-code.
|
||||||
# Use values from the first used extruder by default so we get the expected temperatures
|
# Use values from the first used extruder by default so we get the expected temperatures
|
||||||
initial_extruder_stack = CuraApplication.getInstance().getExtruderManager().getUsedExtruderStacks()[0]
|
initial_extruder_stack = CuraApplication.getInstance().getExtruderManager().getUsedExtruderStacks()[0]
|
||||||
|
|
|
@ -44,6 +44,7 @@ class FirmwareUpdateCheckerJob(Job):
|
||||||
try:
|
try:
|
||||||
# CURA-6698 Create an SSL context and use certifi CA certificates for verification.
|
# CURA-6698 Create an SSL context and use certifi CA certificates for verification.
|
||||||
context = ssl.SSLContext(protocol = ssl.PROTOCOL_TLSv1_2)
|
context = ssl.SSLContext(protocol = ssl.PROTOCOL_TLSv1_2)
|
||||||
|
context.verify_mode = ssl.CERT_REQUIRED
|
||||||
context.load_verify_locations(cafile = certifi.where())
|
context.load_verify_locations(cafile = certifi.where())
|
||||||
|
|
||||||
request = urllib.request.Request(url, headers = self._headers)
|
request = urllib.request.Request(url, headers = self._headers)
|
||||||
|
|
|
@ -7,20 +7,6 @@ from UM.Mesh.MeshReader import MeshReader #The class we're extending/implementin
|
||||||
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType #To add the .gcode.gz files to the MIME type database.
|
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType #To add the .gcode.gz files to the MIME type database.
|
||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
|
|
||||||
import contextlib
|
|
||||||
import resource
|
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def limit(limit, type=resource.RLIMIT_AS):
|
|
||||||
soft_limit, hard_limit = resource.getrlimit(type)
|
|
||||||
resource.setrlimit(type, (limit, hard_limit)) # set soft limit
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
finally:
|
|
||||||
resource.setrlimit(type, (soft_limit, hard_limit)) # restore
|
|
||||||
|
|
||||||
|
|
||||||
## A file reader that reads gzipped g-code.
|
## A file reader that reads gzipped g-code.
|
||||||
#
|
#
|
||||||
# If you're zipping g-code, you might as well use gzip!
|
# If you're zipping g-code, you might as well use gzip!
|
||||||
|
@ -39,8 +25,6 @@ class GCodeGzReader(MeshReader):
|
||||||
def _read(self, file_name):
|
def _read(self, file_name):
|
||||||
with open(file_name, "rb") as file:
|
with open(file_name, "rb") as file:
|
||||||
file_data = file.read()
|
file_data = file.read()
|
||||||
|
|
||||||
with limit(1 << 30): # Prevent a gzip bomb (by setting the max size to 1 gig)
|
|
||||||
uncompressed_gcode = gzip.decompress(file_data).decode("utf-8")
|
uncompressed_gcode = gzip.decompress(file_data).decode("utf-8")
|
||||||
PluginRegistry.getInstance().getPluginObject("GCodeReader").preReadFromStream(uncompressed_gcode)
|
PluginRegistry.getInstance().getPluginObject("GCodeReader").preReadFromStream(uncompressed_gcode)
|
||||||
result = PluginRegistry.getInstance().getPluginObject("GCodeReader").readFromStream(uncompressed_gcode, file_name)
|
result = PluginRegistry.getInstance().getPluginObject("GCodeReader").readFromStream(uncompressed_gcode, file_name)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2015 Ultimaker B.V.
|
# Copyright (c) 2020 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2015 Ultimaker B.V.
|
# Copyright (c) 2020 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -33,9 +33,9 @@ class ImageReaderUI(QObject):
|
||||||
self.base_height = 0.4
|
self.base_height = 0.4
|
||||||
self.peak_height = 2.5
|
self.peak_height = 2.5
|
||||||
self.smoothing = 1
|
self.smoothing = 1
|
||||||
self.lighter_is_higher = False;
|
self.lighter_is_higher = False
|
||||||
self.use_transparency_model = True;
|
self.use_transparency_model = True
|
||||||
self.transmittance_1mm = 50.0; # based on pearl PLA
|
self.transmittance_1mm = 50.0 # based on pearl PLA
|
||||||
|
|
||||||
self._ui_lock = threading.Lock()
|
self._ui_lock = threading.Lock()
|
||||||
self._cancelled = False
|
self._cancelled = False
|
||||||
|
@ -85,7 +85,7 @@ class ImageReaderUI(QObject):
|
||||||
Logger.log("d", "Creating ImageReader config UI")
|
Logger.log("d", "Creating ImageReader config UI")
|
||||||
path = os.path.join(PluginRegistry.getInstance().getPluginPath("ImageReader"), "ConfigUI.qml")
|
path = os.path.join(PluginRegistry.getInstance().getPluginPath("ImageReader"), "ConfigUI.qml")
|
||||||
self._ui_view = Application.getInstance().createQmlComponent(path, {"manager": self})
|
self._ui_view = Application.getInstance().createQmlComponent(path, {"manager": self})
|
||||||
self._ui_view.setFlags(self._ui_view.flags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMinimizeButtonHint & ~Qt.WindowMaximizeButtonHint);
|
self._ui_view.setFlags(self._ui_view.flags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowMinimizeButtonHint & ~Qt.WindowMaximizeButtonHint)
|
||||||
self._disable_size_callbacks = False
|
self._disable_size_callbacks = False
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
|
|
|
@ -107,7 +107,7 @@ Item
|
||||||
labelWidth: base.labelWidth
|
labelWidth: base.labelWidth
|
||||||
controlWidth: base.controlWidth
|
controlWidth: base.controlWidth
|
||||||
unitText: catalog.i18nc("@label", "mm")
|
unitText: catalog.i18nc("@label", "mm")
|
||||||
allowNegativeValue: true
|
minimum: Number.NEGATIVE_INFINITY
|
||||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ Item
|
||||||
labelWidth: base.labelWidth
|
labelWidth: base.labelWidth
|
||||||
controlWidth: base.controlWidth
|
controlWidth: base.controlWidth
|
||||||
unitText: catalog.i18nc("@label", "mm")
|
unitText: catalog.i18nc("@label", "mm")
|
||||||
allowNegativeValue: true
|
minimum: Number.NEGATIVE_INFINITY
|
||||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ Item
|
||||||
labelWidth: base.labelWidth
|
labelWidth: base.labelWidth
|
||||||
controlWidth: base.controlWidth
|
controlWidth: base.controlWidth
|
||||||
unitText: catalog.i18nc("@label", "mm")
|
unitText: catalog.i18nc("@label", "mm")
|
||||||
|
maximum: 2000000
|
||||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +87,7 @@ Item
|
||||||
labelWidth: base.labelWidth
|
labelWidth: base.labelWidth
|
||||||
controlWidth: base.controlWidth
|
controlWidth: base.controlWidth
|
||||||
unitText: catalog.i18nc("@label", "mm")
|
unitText: catalog.i18nc("@label", "mm")
|
||||||
|
maximum: 2000000
|
||||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,8 +206,8 @@ Item
|
||||||
|
|
||||||
axisName: "x"
|
axisName: "x"
|
||||||
axisMinOrMax: "min"
|
axisMinOrMax: "min"
|
||||||
allowNegativeValue: true
|
minimum: Number.NEGATIVE_INFINITY
|
||||||
allowPositiveValue: false
|
maximum: 0
|
||||||
|
|
||||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||||
}
|
}
|
||||||
|
@ -224,8 +226,8 @@ Item
|
||||||
|
|
||||||
axisName: "y"
|
axisName: "y"
|
||||||
axisMinOrMax: "min"
|
axisMinOrMax: "min"
|
||||||
allowNegativeValue: true
|
minimum: Number.NEGATIVE_INFINITY
|
||||||
allowPositiveValue: false
|
maximum: 0
|
||||||
|
|
||||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||||
}
|
}
|
||||||
|
@ -244,8 +246,6 @@ Item
|
||||||
|
|
||||||
axisName: "x"
|
axisName: "x"
|
||||||
axisMinOrMax: "max"
|
axisMinOrMax: "max"
|
||||||
allowNegativeValue: false
|
|
||||||
allowPositiveValue: true
|
|
||||||
|
|
||||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||||
}
|
}
|
||||||
|
@ -266,8 +266,6 @@ Item
|
||||||
|
|
||||||
axisName: "y"
|
axisName: "y"
|
||||||
axisMinOrMax: "max"
|
axisMinOrMax: "max"
|
||||||
allowNegativeValue: false
|
|
||||||
allowPositiveValue: true
|
|
||||||
|
|
||||||
forceUpdateOnChangeFunction: forceUpdateFunction
|
forceUpdateOnChangeFunction: forceUpdateFunction
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,8 @@ class ModelChecker(QObject, Extension):
|
||||||
# Check node material shrinkage and bounding box size
|
# Check node material shrinkage and bounding box size
|
||||||
for node in self.sliceableNodes():
|
for node in self.sliceableNodes():
|
||||||
node_extruder_position = node.callDecoration("getActiveExtruderPosition")
|
node_extruder_position = node.callDecoration("getActiveExtruderPosition")
|
||||||
|
if node_extruder_position is None:
|
||||||
|
continue
|
||||||
|
|
||||||
# This function can be triggered in the middle of a machine change, so do not proceed if the machine change
|
# This function can be triggered in the middle of a machine change, so do not proceed if the machine change
|
||||||
# has not done yet.
|
# has not done yet.
|
||||||
|
|
|
@ -71,7 +71,7 @@ class PerObjectSettingVisibilityHandler(UM.Settings.Models.SettingVisibilityHand
|
||||||
|
|
||||||
# Add all instances that are not added, but are in visibility list
|
# Add all instances that are not added, but are in visibility list
|
||||||
for item in visible:
|
for item in visible:
|
||||||
if settings.getInstance(item) is not None: # Setting was not added already.
|
if settings.getInstance(item) is None: # Setting was not added already.
|
||||||
definition = self._stack.getSettingDefinition(item)
|
definition = self._stack.getSettingDefinition(item)
|
||||||
if definition:
|
if definition:
|
||||||
new_instance = SettingInstance(definition, settings)
|
new_instance = SettingInstance(definition, settings)
|
||||||
|
|
|
@ -49,18 +49,6 @@ Item
|
||||||
visibility_handler.addSkipResetSetting(currentMeshType)
|
visibility_handler.addSkipResetSetting(currentMeshType)
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOverhangsMeshType()
|
|
||||||
{
|
|
||||||
if (infillOnlyCheckbox.checked)
|
|
||||||
{
|
|
||||||
setMeshType(infillMeshType)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setMeshType(cuttingMeshType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setMeshType(type)
|
function setMeshType(type)
|
||||||
{
|
{
|
||||||
UM.ActiveTool.setProperty("MeshType", type)
|
UM.ActiveTool.setProperty("MeshType", type)
|
||||||
|
@ -140,26 +128,43 @@ Item
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckBox
|
|
||||||
|
ComboBox
|
||||||
{
|
{
|
||||||
id: infillOnlyCheckbox
|
id: infillOnlyComboBox
|
||||||
|
width: parent.width / 2 - UM.Theme.getSize("default_margin").width
|
||||||
|
|
||||||
text: catalog.i18nc("@action:checkbox", "Infill only");
|
model: ListModel
|
||||||
|
{
|
||||||
|
id: infillOnlyComboBoxModel
|
||||||
|
|
||||||
style: UM.Theme.styles.checkbox;
|
Component.onCompleted: {
|
||||||
|
append({ text: catalog.i18nc("@item:inlistbox", "Infill mesh only") })
|
||||||
|
append({ text: catalog.i18nc("@item:inlistbox", "Cutting mesh") })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
visible: currentMeshType === infillMeshType || currentMeshType === cuttingMeshType
|
visible: currentMeshType === infillMeshType || currentMeshType === cuttingMeshType
|
||||||
onClicked: setOverhangsMeshType()
|
|
||||||
|
|
||||||
|
onActivated:
|
||||||
|
{
|
||||||
|
if (index == 0){
|
||||||
|
setMeshType(infillMeshType)
|
||||||
|
} else {
|
||||||
|
setMeshType(cuttingMeshType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Binding
|
Binding
|
||||||
{
|
{
|
||||||
target: infillOnlyCheckbox
|
target: infillOnlyComboBox
|
||||||
property: "checked"
|
property: "currentIndex"
|
||||||
value: currentMeshType === infillMeshType
|
value: currentMeshType === infillMeshType ? 0 : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column // Settings Dialog
|
Column // List of selected Settings to override for the selected object
|
||||||
{
|
{
|
||||||
// This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar.
|
// This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar.
|
||||||
// It kinda looks ugly otherwise (big panel, no content on it)
|
// It kinda looks ugly otherwise (big panel, no content on it)
|
||||||
|
|
|
@ -82,6 +82,7 @@ class PerObjectSettingsTool(Tool):
|
||||||
selected_object.addDecorator(SettingOverrideDecorator())
|
selected_object.addDecorator(SettingOverrideDecorator())
|
||||||
stack = selected_object.callDecoration("getStack")
|
stack = selected_object.callDecoration("getStack")
|
||||||
|
|
||||||
|
settings_visibility_changed = False
|
||||||
settings = stack.getTop()
|
settings = stack.getTop()
|
||||||
for property_key in ["infill_mesh", "cutting_mesh", "support_mesh", "anti_overhang_mesh"]:
|
for property_key in ["infill_mesh", "cutting_mesh", "support_mesh", "anti_overhang_mesh"]:
|
||||||
if property_key != mesh_type:
|
if property_key != mesh_type:
|
||||||
|
@ -97,17 +98,20 @@ class PerObjectSettingsTool(Tool):
|
||||||
|
|
||||||
for property_key in ["top_bottom_thickness", "wall_thickness"]:
|
for property_key in ["top_bottom_thickness", "wall_thickness"]:
|
||||||
if mesh_type == "infill_mesh":
|
if mesh_type == "infill_mesh":
|
||||||
if not settings.getInstance(property_key):
|
if settings.getInstance(property_key) is None:
|
||||||
definition = stack.getSettingDefinition(property_key)
|
definition = stack.getSettingDefinition(property_key)
|
||||||
new_instance = SettingInstance(definition, settings)
|
new_instance = SettingInstance(definition, settings)
|
||||||
new_instance.setProperty("value", 0)
|
new_instance.setProperty("value", 0)
|
||||||
new_instance.resetState() # Ensure that the state is not seen as a user state.
|
new_instance.resetState() # Ensure that the state is not seen as a user state.
|
||||||
settings.addInstance(new_instance)
|
settings.addInstance(new_instance)
|
||||||
visible = self.visibility_handler.getVisible()
|
settings_visibility_changed = True
|
||||||
visible.add(property_key)
|
|
||||||
self.visibility_handler.setVisible(visible)
|
|
||||||
elif old_mesh_type == "infill_mesh" and settings.getInstance(property_key) and settings.getProperty(property_key, "value") == 0:
|
elif old_mesh_type == "infill_mesh" and settings.getInstance(property_key) and settings.getProperty(property_key, "value") == 0:
|
||||||
settings.removeInstance(property_key)
|
settings.removeInstance(property_key)
|
||||||
|
settings_visibility_changed = True
|
||||||
|
|
||||||
|
if settings_visibility_changed:
|
||||||
|
self.visibility_handler.forceVisibilityChanged()
|
||||||
|
|
||||||
self.propertyChanged.emit()
|
self.propertyChanged.emit()
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -484,15 +484,53 @@ UM.Dialog
|
||||||
onClicked: dialog.accept()
|
onClicked: dialog.accept()
|
||||||
}
|
}
|
||||||
|
|
||||||
Cura.SecondaryButton
|
Item
|
||||||
{
|
{
|
||||||
objectName: "postProcessingSaveAreaButton"
|
objectName: "postProcessingSaveAreaButton"
|
||||||
visible: activeScriptsList.count > 0
|
visible: activeScriptsList.count > 0
|
||||||
height: UM.Theme.getSize("action_button").height
|
height: UM.Theme.getSize("action_button").height
|
||||||
width: height
|
width: height
|
||||||
tooltip: catalog.i18nc("@info:tooltip", "Change active post-processing scripts")
|
|
||||||
|
Cura.SecondaryButton
|
||||||
|
{
|
||||||
|
height: UM.Theme.getSize("action_button").height
|
||||||
|
tooltip:
|
||||||
|
{
|
||||||
|
var tipText = catalog.i18nc("@info:tooltip", "Change active post-processing scripts.");
|
||||||
|
if (activeScriptsList.count > 0)
|
||||||
|
{
|
||||||
|
tipText += "<br><br>" + catalog.i18ncp("@info:tooltip",
|
||||||
|
"The following script is active:",
|
||||||
|
"The following scripts are active:",
|
||||||
|
activeScriptsList.count
|
||||||
|
) + "<ul>";
|
||||||
|
for(var i = 0; i < activeScriptsList.count; i++)
|
||||||
|
{
|
||||||
|
tipText += "<li>" + manager.getScriptLabelByKey(manager.scriptList[i]) + "</li>";
|
||||||
|
}
|
||||||
|
tipText += "</ul>";
|
||||||
|
}
|
||||||
|
return tipText
|
||||||
|
}
|
||||||
|
toolTipContentAlignment: Cura.ToolTip.ContentAlignment.AlignLeft
|
||||||
onClicked: dialog.show()
|
onClicked: dialog.show()
|
||||||
iconSource: "postprocessing.svg"
|
iconSource: "postprocessing.svg"
|
||||||
fixedWidthMode: true
|
fixedWidthMode: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Cura.NotificationIcon
|
||||||
|
{
|
||||||
|
id: activeScriptCountIcon
|
||||||
|
visible: activeScriptsList.count > 0
|
||||||
|
anchors
|
||||||
|
{
|
||||||
|
top: parent.top
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: (-0.5 * width) | 0
|
||||||
|
topMargin: (-0.5 * height) | 0
|
||||||
|
}
|
||||||
|
|
||||||
|
labelText: activeScriptsList.count
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,12 +6,20 @@
|
||||||
#Authors of the 2-1 ColorMix plug-in / script:
|
#Authors of the 2-1 ColorMix plug-in / script:
|
||||||
# Written by John Hryb - john.hryb.4@gmail.com
|
# Written by John Hryb - john.hryb.4@gmail.com
|
||||||
|
|
||||||
##history / change-log:
|
#history / change-log:
|
||||||
##V1.0.0
|
#V1.0.0 - Initial
|
||||||
|
#V1.1.0 -
|
||||||
## Uses -
|
# additions:
|
||||||
## M163 - Set Mix Factor
|
#Object number - To select individual models or all when using "one at a time" print sequence
|
||||||
## M164 - Save Mix - saves to T3 as a unique mix
|
#V1.2.0
|
||||||
|
# fixed layer heights Cura starts at 1 while G-code starts at 0
|
||||||
|
# removed notes
|
||||||
|
# changed Units of measurement to Units
|
||||||
|
#V1.2.1
|
||||||
|
# Fixed mm bug when not in multiples of layer height
|
||||||
|
# Uses -
|
||||||
|
# M163 - Set Mix Factor
|
||||||
|
# M164 - Save Mix - saves to T2 as a unique mix
|
||||||
|
|
||||||
import re #To perform the search and replace.
|
import re #To perform the search and replace.
|
||||||
from ..Script import Script
|
from ..Script import Script
|
||||||
|
@ -22,20 +30,28 @@ class ColorMix(Script):
|
||||||
|
|
||||||
def getSettingDataString(self):
|
def getSettingDataString(self):
|
||||||
return """{
|
return """{
|
||||||
"name":"ColorMix 2-1",
|
"name":"ColorMix 2-1 V1.2.1",
|
||||||
"key":"ColorMix 2-1",
|
"key":"ColorMix 2-1",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"settings":
|
"settings":
|
||||||
{
|
{
|
||||||
"measurement_units":
|
"units_of_measurement":
|
||||||
{
|
{
|
||||||
"label": "Units of measurement",
|
"label": "Units",
|
||||||
"description": "Input value as mm or layer number.",
|
"description": "Input value as mm or layer number.",
|
||||||
"type": "enum",
|
"type": "enum",
|
||||||
"options": {"mm":"mm","layer":"Layer"},
|
"options": {"mm":"mm","layer":"Layer"},
|
||||||
"default_value": "layer"
|
"default_value": "layer"
|
||||||
},
|
},
|
||||||
|
"object_number":
|
||||||
|
{
|
||||||
|
"label": "Object Number",
|
||||||
|
"description": "Select model to apply to for print one at a time print sequence. 0 = everything",
|
||||||
|
"type": "int",
|
||||||
|
"default_value": 0,
|
||||||
|
"minimum_value": "0"
|
||||||
|
},
|
||||||
"start_height":
|
"start_height":
|
||||||
{
|
{
|
||||||
"label": "Start Height",
|
"label": "Start Height",
|
||||||
|
@ -59,10 +75,10 @@ class ColorMix(Script):
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 0,
|
"default_value": 0,
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "0.1",
|
"minimum_value_warning": "start_height",
|
||||||
"enabled": "c_behavior == 'blend_value'"
|
"enabled": "behavior == 'blend_value'"
|
||||||
},
|
},
|
||||||
"mix_start_ratio":
|
"mix_start":
|
||||||
{
|
{
|
||||||
"label": "Start mix ratio",
|
"label": "Start mix ratio",
|
||||||
"description": "First extruder percentage 0-100",
|
"description": "First extruder percentage 0-100",
|
||||||
|
@ -72,7 +88,7 @@ class ColorMix(Script):
|
||||||
"minimum_value_warning": "0",
|
"minimum_value_warning": "0",
|
||||||
"maximum_value_warning": "100"
|
"maximum_value_warning": "100"
|
||||||
},
|
},
|
||||||
"mix_finish_ratio":
|
"mix_finish":
|
||||||
{
|
{
|
||||||
"label": "End mix ratio",
|
"label": "End mix ratio",
|
||||||
"description": "First extruder percentage 0-100 to finish blend",
|
"description": "First extruder percentage 0-100 to finish blend",
|
||||||
|
@ -81,14 +97,7 @@ class ColorMix(Script):
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "0",
|
"minimum_value_warning": "0",
|
||||||
"maximum_value_warning": "100",
|
"maximum_value_warning": "100",
|
||||||
"enabled": "c_behavior == 'blend_value'"
|
"enabled": "behavior == 'blend_value'"
|
||||||
},
|
|
||||||
"notes":
|
|
||||||
{
|
|
||||||
"label": "Notes",
|
|
||||||
"description": "A spot to put a note",
|
|
||||||
"type": "str",
|
|
||||||
"default_value": ""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}"""
|
}"""
|
||||||
|
@ -112,52 +121,53 @@ class ColorMix(Script):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def execute(self, data):
|
def execute(self, data):
|
||||||
#get user variables
|
|
||||||
firstHeight = 0.0
|
|
||||||
secondHeight = 0.0
|
|
||||||
firstMix = 0.0
|
|
||||||
SecondMix = 0.0
|
|
||||||
|
|
||||||
firstHeight = self.getSettingValueByKey("start_height")
|
firstHeight = self.getSettingValueByKey("start_height")
|
||||||
secondHeight = self.getSettingValueByKey("finish_height")
|
secondHeight = self.getSettingValueByKey("finish_height")
|
||||||
firstMix = self.getSettingValueByKey("mix_start_ratio")
|
firstMix = self.getSettingValueByKey("mix_start")
|
||||||
SecondMix = self.getSettingValueByKey("mix_finish_ratio")
|
secondMix = self.getSettingValueByKey("mix_finish")
|
||||||
|
modelOfInterest = self.getSettingValueByKey("object_number")
|
||||||
#locals
|
|
||||||
layer = 0
|
|
||||||
|
|
||||||
#get layer height
|
#get layer height
|
||||||
layerHeight = .2
|
layerHeight = 0
|
||||||
for active_layer in data:
|
for active_layer in data:
|
||||||
lines = active_layer.split("\n")
|
lines = active_layer.split("\n")
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if ";Layer height: " in line:
|
if ";Layer height: " in line:
|
||||||
layerHeight = self.getValue(line, ";Layer height: ", layerHeight)
|
layerHeight = self.getValue(line, ";Layer height: ", layerHeight)
|
||||||
break
|
break
|
||||||
|
if layerHeight != 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
#default layerHeight if not found
|
||||||
|
if layerHeight == 0:
|
||||||
|
layerHeight = .2
|
||||||
|
|
||||||
#get layers to use
|
#get layers to use
|
||||||
startLayer = 0
|
startLayer = 0
|
||||||
endLayer = 0
|
endLayer = 0
|
||||||
if self.getSettingValueByKey("measurement_units") == "mm":
|
if self.getSettingValueByKey("units_of_measurement") == "mm":
|
||||||
if firstHeight == 0:
|
startLayer = round(firstHeight / layerHeight)
|
||||||
startLayer = 0
|
endLayer = round(secondHeight / layerHeight)
|
||||||
else:
|
else: #layer height shifts down by one for g-code
|
||||||
startLayer = firstHeight / layerHeight
|
if firstHeight <= 0:
|
||||||
if secondHeight == 0:
|
firstHeight = 1
|
||||||
endLayer = 0
|
if secondHeight <= 0:
|
||||||
else:
|
secondHeight = 1
|
||||||
endLayer = secondHeight / layerHeight
|
startLayer = firstHeight - 1
|
||||||
else: #layer height
|
endLayer = secondHeight - 1
|
||||||
startLayer = firstHeight
|
|
||||||
endLayer = secondHeight
|
|
||||||
#see if one-shot
|
#see if one-shot
|
||||||
if self.getSettingValueByKey("behavior") == "fixed_value":
|
if self.getSettingValueByKey("behavior") == "fixed_value":
|
||||||
endLayer = startLayer
|
endLayer = startLayer
|
||||||
firstExtruderIncrements = 0
|
firstExtruderIncrements = 0
|
||||||
else: #blend
|
else: #blend
|
||||||
firstExtruderIncrements = (SecondMix - firstMix) / (endLayer - startLayer)
|
firstExtruderIncrements = (secondMix - firstMix) / (endLayer - startLayer)
|
||||||
firstExtruderValue = 0
|
firstExtruderValue = 0
|
||||||
index = 0
|
index = 0
|
||||||
|
|
||||||
#start scanning
|
#start scanning
|
||||||
|
layer = -1
|
||||||
|
modelNumber = 0
|
||||||
for active_layer in data:
|
for active_layer in data:
|
||||||
modified_gcode = ""
|
modified_gcode = ""
|
||||||
lineIndex = 0;
|
lineIndex = 0;
|
||||||
|
@ -169,9 +179,17 @@ class ColorMix(Script):
|
||||||
# find current layer
|
# find current layer
|
||||||
if ";LAYER:" in line:
|
if ";LAYER:" in line:
|
||||||
layer = self.getValue(line, ";LAYER:", layer)
|
layer = self.getValue(line, ";LAYER:", layer)
|
||||||
if (layer >= startLayer) and (layer <= endLayer): #find layers of interest
|
#get model number by layer 0 repeats
|
||||||
if lines[lineIndex + 4] == "T2": #check if needing to delete old data
|
if layer == 0:
|
||||||
|
modelNumber = modelNumber + 1
|
||||||
|
#search for layers to manipulate
|
||||||
|
if (layer >= startLayer) and (layer <= endLayer):
|
||||||
|
#make sure correct model is selected
|
||||||
|
if (modelOfInterest == 0) or (modelOfInterest == modelNumber):
|
||||||
|
#Delete old data if required
|
||||||
|
if lines[lineIndex + 4] == "T2":
|
||||||
del lines[(lineIndex + 1):(lineIndex + 5)]
|
del lines[(lineIndex + 1):(lineIndex + 5)]
|
||||||
|
#add mixing commands
|
||||||
firstExtruderValue = int(((layer - startLayer) * firstExtruderIncrements) + firstMix)
|
firstExtruderValue = int(((layer - startLayer) * firstExtruderIncrements) + firstMix)
|
||||||
if firstExtruderValue == 100:
|
if firstExtruderValue == 100:
|
||||||
modified_gcode += "M163 S0 P1\n"
|
modified_gcode += "M163 S0 P1\n"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//Copyright (c) 2019 Ultimaker B.V.
|
//Copyright (c) 2020 Ultimaker B.V.
|
||||||
//Cura is released under the terms of the LGPLv3 or higher.
|
//Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import QtQuick 2.4
|
import QtQuick 2.4
|
||||||
|
|
|
@ -42,7 +42,7 @@ Item
|
||||||
rightMargin: UM.Theme.getSize("wide_margin").width
|
rightMargin: UM.Theme.getSize("wide_margin").width
|
||||||
}
|
}
|
||||||
height: UM.Theme.getSize("toolbox_footer_button").height
|
height: UM.Theme.getSize("toolbox_footer_button").height
|
||||||
text: catalog.i18nc("@info:button", "Quit Cura")
|
text: catalog.i18nc("@info:button, %1 is the application name", "Quit %1").arg(CuraApplication.applicationDisplayName)
|
||||||
onClicked: toolbox.restart()
|
onClicked: toolbox.restart()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from cura import ApplicationMetadata, UltimakerCloudAuthentication
|
from cura import ApplicationMetadata
|
||||||
|
from cura.UltimakerCloud import UltimakerCloudAuthentication
|
||||||
|
|
||||||
|
|
||||||
class CloudApiModel:
|
class CloudApiModel:
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
|
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
|
||||||
|
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
|
||||||
from ..CloudApiModel import CloudApiModel
|
from ..CloudApiModel import CloudApiModel
|
||||||
from ..UltimakerCloudScope import UltimakerCloudScope
|
|
||||||
|
|
||||||
|
|
||||||
class CloudApiClient:
|
class CloudApiClient:
|
||||||
|
@ -26,7 +27,7 @@ class CloudApiClient:
|
||||||
if self.__instance is not None:
|
if self.__instance is not None:
|
||||||
raise RuntimeError("This is a Singleton. use getInstance()")
|
raise RuntimeError("This is a Singleton. use getInstance()")
|
||||||
|
|
||||||
self._scope = UltimakerCloudScope(app) # type: UltimakerCloudScope
|
self._scope = JsonDecoratorScope(UltimakerCloudScope(app)) # type: JsonDecoratorScope
|
||||||
|
|
||||||
app.getPackageManager().packageInstalled.connect(self._onPackageInstalled)
|
app.getPackageManager().packageInstalled.connect(self._onPackageInstalled)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from typing import List, Dict, Any
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject
|
from PyQt5.QtCore import QObject
|
||||||
|
@ -11,12 +12,12 @@ from UM import i18nCatalog
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Message import Message
|
from UM.Message import Message
|
||||||
from UM.Signal import Signal
|
from UM.Signal import Signal
|
||||||
|
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
|
||||||
from cura.CuraApplication import CuraApplication, ApplicationMetadata
|
from cura.CuraApplication import CuraApplication, ApplicationMetadata
|
||||||
from ..CloudApiModel import CloudApiModel
|
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
|
||||||
from .SubscribedPackagesModel import SubscribedPackagesModel
|
from .SubscribedPackagesModel import SubscribedPackagesModel
|
||||||
from ..UltimakerCloudScope import UltimakerCloudScope
|
from ..CloudApiModel import CloudApiModel
|
||||||
|
|
||||||
from typing import List, Dict, Any
|
|
||||||
|
|
||||||
class CloudPackageChecker(QObject):
|
class CloudPackageChecker(QObject):
|
||||||
def __init__(self, application: CuraApplication) -> None:
|
def __init__(self, application: CuraApplication) -> None:
|
||||||
|
@ -24,7 +25,7 @@ class CloudPackageChecker(QObject):
|
||||||
|
|
||||||
self.discrepancies = Signal() # Emits SubscribedPackagesModel
|
self.discrepancies = Signal() # Emits SubscribedPackagesModel
|
||||||
self._application = application # type: CuraApplication
|
self._application = application # type: CuraApplication
|
||||||
self._scope = UltimakerCloudScope(application)
|
self._scope = JsonDecoratorScope(UltimakerCloudScope(application))
|
||||||
self._model = SubscribedPackagesModel()
|
self._model = SubscribedPackagesModel()
|
||||||
self._message = None # type: Optional[Message]
|
self._message = None # type: Optional[Message]
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ from UM.Message import Message
|
||||||
from UM.Signal import Signal
|
from UM.Signal import Signal
|
||||||
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
|
from UM.TaskManagement.HttpRequestManager import HttpRequestManager
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
|
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
|
||||||
from .SubscribedPackagesModel import SubscribedPackagesModel
|
from .SubscribedPackagesModel import SubscribedPackagesModel
|
||||||
from ..UltimakerCloudScope import UltimakerCloudScope
|
|
||||||
|
|
||||||
|
|
||||||
## Downloads a set of packages from the Ultimaker Cloud Marketplace
|
## Downloads a set of packages from the Ultimaker Cloud Marketplace
|
||||||
|
|
|
@ -9,22 +9,20 @@ from typing import cast, Any, Dict, List, Set, TYPE_CHECKING, Tuple, Optional, U
|
||||||
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot
|
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, pyqtSlot
|
||||||
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
||||||
|
|
||||||
|
from UM.Extension import Extension
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
from UM.Extension import Extension
|
from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
|
||||||
from UM.i18n import i18nCatalog
|
|
||||||
from UM.Version import Version
|
from UM.Version import Version
|
||||||
|
from UM.i18n import i18nCatalog
|
||||||
from cura import ApplicationMetadata
|
from cura import ApplicationMetadata
|
||||||
|
|
||||||
from cura.CuraApplication import CuraApplication
|
from cura.CuraApplication import CuraApplication
|
||||||
from cura.Machines.ContainerTree import ContainerTree
|
from cura.Machines.ContainerTree import ContainerTree
|
||||||
|
from cura.UltimakerCloud.UltimakerCloudScope import UltimakerCloudScope
|
||||||
from .CloudApiModel import CloudApiModel
|
|
||||||
from .AuthorsModel import AuthorsModel
|
from .AuthorsModel import AuthorsModel
|
||||||
|
from .CloudApiModel import CloudApiModel
|
||||||
from .CloudSync.LicenseModel import LicenseModel
|
from .CloudSync.LicenseModel import LicenseModel
|
||||||
from .PackagesModel import PackagesModel
|
from .PackagesModel import PackagesModel
|
||||||
from .UltimakerCloudScope import UltimakerCloudScope
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from UM.TaskManagement.HttpRequestData import HttpRequestData
|
from UM.TaskManagement.HttpRequestData import HttpRequestData
|
||||||
|
@ -54,7 +52,8 @@ class Toolbox(QObject, Extension):
|
||||||
self._download_request_data = None # type: Optional[HttpRequestData]
|
self._download_request_data = None # type: Optional[HttpRequestData]
|
||||||
self._download_progress = 0 # type: float
|
self._download_progress = 0 # type: float
|
||||||
self._is_downloading = False # type: bool
|
self._is_downloading = False # type: bool
|
||||||
self._scope = UltimakerCloudScope(application) # type: UltimakerCloudScope
|
self._cloud_scope = UltimakerCloudScope(application) # type: UltimakerCloudScope
|
||||||
|
self._json_scope = JsonDecoratorScope(self._cloud_scope) # type: JsonDecoratorScope
|
||||||
|
|
||||||
self._request_urls = {} # type: Dict[str, str]
|
self._request_urls = {} # type: Dict[str, str]
|
||||||
self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated
|
self._to_update = [] # type: List[str] # Package_ids that are waiting to be updated
|
||||||
|
@ -151,7 +150,7 @@ class Toolbox(QObject, Extension):
|
||||||
url = "{base_url}/packages/{package_id}/ratings".format(base_url = CloudApiModel.api_url, package_id = package_id)
|
url = "{base_url}/packages/{package_id}/ratings".format(base_url = CloudApiModel.api_url, package_id = package_id)
|
||||||
data = "{\"data\": {\"cura_version\": \"%s\", \"rating\": %i}}" % (Version(self._application.getVersion()), rating)
|
data = "{\"data\": {\"cura_version\": \"%s\", \"rating\": %i}}" % (Version(self._application.getVersion()), rating)
|
||||||
|
|
||||||
self._application.getHttpRequestManager().put(url, data = data.encode(), scope = self._scope)
|
self._application.getHttpRequestManager().put(url, data = data.encode(), scope = self._json_scope)
|
||||||
|
|
||||||
def getLicenseDialogPluginFileLocation(self) -> str:
|
def getLicenseDialogPluginFileLocation(self) -> str:
|
||||||
return self._license_dialog_plugin_file_location
|
return self._license_dialog_plugin_file_location
|
||||||
|
@ -541,7 +540,7 @@ class Toolbox(QObject, Extension):
|
||||||
self._application.getHttpRequestManager().get(url,
|
self._application.getHttpRequestManager().get(url,
|
||||||
callback = callback,
|
callback = callback,
|
||||||
error_callback = error_callback,
|
error_callback = error_callback,
|
||||||
scope=self._scope)
|
scope=self._json_scope)
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def startDownload(self, url: str) -> None:
|
def startDownload(self, url: str) -> None:
|
||||||
|
@ -554,7 +553,7 @@ class Toolbox(QObject, Extension):
|
||||||
callback = callback,
|
callback = callback,
|
||||||
error_callback = error_callback,
|
error_callback = error_callback,
|
||||||
download_progress_callback = download_progress_callback,
|
download_progress_callback = download_progress_callback,
|
||||||
scope=self._scope
|
scope=self._cloud_scope
|
||||||
)
|
)
|
||||||
|
|
||||||
self._download_request_data = request_data
|
self._download_request_data = request_data
|
||||||
|
|
|
@ -108,7 +108,7 @@ class TrimeshReader(MeshReader):
|
||||||
mesh.merge_vertices()
|
mesh.merge_vertices()
|
||||||
mesh.remove_unreferenced_vertices()
|
mesh.remove_unreferenced_vertices()
|
||||||
mesh.fix_normals()
|
mesh.fix_normals()
|
||||||
mesh_data = self._toMeshData(mesh)
|
mesh_data = self._toMeshData(mesh, file_name)
|
||||||
|
|
||||||
file_base_name = os.path.basename(file_name)
|
file_base_name = os.path.basename(file_name)
|
||||||
new_node = CuraSceneNode()
|
new_node = CuraSceneNode()
|
||||||
|
@ -133,9 +133,10 @@ class TrimeshReader(MeshReader):
|
||||||
## Converts a Trimesh to Uranium's MeshData.
|
## Converts a Trimesh to Uranium's MeshData.
|
||||||
# \param tri_node A Trimesh containing the contents of a file that was
|
# \param tri_node A Trimesh containing the contents of a file that was
|
||||||
# just read.
|
# just read.
|
||||||
|
# \param file_name The full original filename used to watch for changes
|
||||||
# \return Mesh data from the Trimesh in a way that Uranium can understand
|
# \return Mesh data from the Trimesh in a way that Uranium can understand
|
||||||
# it.
|
# it.
|
||||||
def _toMeshData(self, tri_node: trimesh.base.Trimesh) -> MeshData:
|
def _toMeshData(self, tri_node: trimesh.base.Trimesh, file_name: str = "") -> MeshData:
|
||||||
tri_faces = tri_node.faces
|
tri_faces = tri_node.faces
|
||||||
tri_vertices = tri_node.vertices
|
tri_vertices = tri_node.vertices
|
||||||
|
|
||||||
|
@ -157,5 +158,5 @@ class TrimeshReader(MeshReader):
|
||||||
indices = numpy.asarray(indices, dtype = numpy.int32)
|
indices = numpy.asarray(indices, dtype = numpy.int32)
|
||||||
normals = calculateNormalsFromIndexedVertices(vertices, indices, face_count)
|
normals = calculateNormalsFromIndexedVertices(vertices, indices, face_count)
|
||||||
|
|
||||||
mesh_data = MeshData(vertices = vertices, indices = indices, normals = normals)
|
mesh_data = MeshData(vertices = vertices, indices = indices, normals = normals, file_name = file_name)
|
||||||
return mesh_data
|
return mesh_data
|
|
@ -9,18 +9,16 @@ from PyQt5.QtCore import QUrl
|
||||||
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager
|
from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager
|
||||||
|
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from cura import UltimakerCloudAuthentication
|
|
||||||
from cura.API import Account
|
from cura.API import Account
|
||||||
|
from cura.UltimakerCloud import UltimakerCloudAuthentication
|
||||||
from .ToolPathUploader import ToolPathUploader
|
from .ToolPathUploader import ToolPathUploader
|
||||||
from ..Models.BaseModel import BaseModel
|
from ..Models.BaseModel import BaseModel
|
||||||
from ..Models.Http.CloudClusterResponse import CloudClusterResponse
|
from ..Models.Http.CloudClusterResponse import CloudClusterResponse
|
||||||
from ..Models.Http.CloudError import CloudError
|
|
||||||
from ..Models.Http.CloudClusterStatus import CloudClusterStatus
|
from ..Models.Http.CloudClusterStatus import CloudClusterStatus
|
||||||
|
from ..Models.Http.CloudError import CloudError
|
||||||
|
from ..Models.Http.CloudPrintJobResponse import CloudPrintJobResponse
|
||||||
from ..Models.Http.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
|
from ..Models.Http.CloudPrintJobUploadRequest import CloudPrintJobUploadRequest
|
||||||
from ..Models.Http.CloudPrintResponse import CloudPrintResponse
|
from ..Models.Http.CloudPrintResponse import CloudPrintResponse
|
||||||
from ..Models.Http.CloudPrintJobResponse import CloudPrintJobResponse
|
|
||||||
|
|
||||||
|
|
||||||
## The generic type variable used to document the methods below.
|
## The generic type variable used to document the methods below.
|
||||||
CloudApiClientModel = TypeVar("CloudApiClientModel", bound=BaseModel)
|
CloudApiClientModel = TypeVar("CloudApiClientModel", bound=BaseModel)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# Copyright (c) 2019 Ultimaker B.V.
|
# Copyright (c) 2019 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
from time import time
|
from time import time
|
||||||
|
import os
|
||||||
from typing import List, Optional, cast
|
from typing import List, Optional, cast
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot
|
from PyQt5.QtCore import QObject, QUrl, pyqtProperty, pyqtSignal, pyqtSlot
|
||||||
|
@ -191,8 +192,9 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice):
|
||||||
def _onPrintJobCreated(self, job: ExportFileJob) -> None:
|
def _onPrintJobCreated(self, job: ExportFileJob) -> None:
|
||||||
output = job.getOutput()
|
output = job.getOutput()
|
||||||
self._tool_path = output # store the tool path to prevent re-uploading when printing the same file again
|
self._tool_path = output # store the tool path to prevent re-uploading when printing the same file again
|
||||||
|
file_name = job.getFileName()
|
||||||
request = CloudPrintJobUploadRequest(
|
request = CloudPrintJobUploadRequest(
|
||||||
job_name=job.getFileName(),
|
job_name=os.path.splitext(file_name)[0],
|
||||||
file_size=len(output),
|
file_size=len(output),
|
||||||
content_type=job.getMimeType(),
|
content_type=job.getMimeType(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
-----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-----
|
|
34
requirements.txt
Normal file
34
requirements.txt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
colorlog
|
||||||
|
mypy==0.740
|
||||||
|
PyQt5==5.10
|
||||||
|
numpy==1.15.4
|
||||||
|
scipy==1.2.0
|
||||||
|
shapely[vectorized]==1.6.4.post2
|
||||||
|
appdirs==1.4.3
|
||||||
|
certifi==2019.11.28
|
||||||
|
cffi==1.13.1
|
||||||
|
chardet==3.0.4
|
||||||
|
cryptography==2.8
|
||||||
|
decorator==4.4.0
|
||||||
|
idna==2.8
|
||||||
|
netifaces==0.10.9
|
||||||
|
networkx==2.3
|
||||||
|
numpy-stl==2.10.1
|
||||||
|
packaging==18.0
|
||||||
|
pycollada==0.6
|
||||||
|
pycparser==2.19
|
||||||
|
pyparsing==2.4.2
|
||||||
|
pyserial==3.4
|
||||||
|
pytest
|
||||||
|
python-dateutil==2.8.0
|
||||||
|
python-utils==2.3.0
|
||||||
|
requests==2.22.0
|
||||||
|
sentry-sdk==0.13.5
|
||||||
|
six==1.12.0
|
||||||
|
trimesh==3.2.33
|
||||||
|
typing==3.7.4
|
||||||
|
twisted==19.10.0
|
||||||
|
urllib3==1.25.6
|
||||||
|
PyYAML==5.1.2
|
||||||
|
zeroconf==0.24.1
|
||||||
|
comtypes==1.1.7
|
|
@ -44,7 +44,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1
|
"value": "1"
|
||||||
},
|
},
|
||||||
"top_bottom_thickness": {
|
"top_bottom_thickness": {
|
||||||
"default_value": 1
|
"default_value": 1
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1
|
"value": "1"
|
||||||
},
|
},
|
||||||
"top_bottom_thickness": {
|
"top_bottom_thickness": {
|
||||||
"default_value": 1
|
"default_value": 1
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1
|
"value": "1"
|
||||||
},
|
},
|
||||||
"top_bottom_thickness": {
|
"top_bottom_thickness": {
|
||||||
"default_value": 1
|
"default_value": 1
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"speed_print": {
|
"speed_print": {
|
||||||
"default_value": 40
|
"default_value": 40
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
},
|
},
|
||||||
"material_diameter": { "default_value": 1.75 },
|
"material_diameter": { "default_value": 1.75 },
|
||||||
"layer_height_0": { "default_value": 0.2 },
|
"layer_height_0": { "default_value": 0.2 },
|
||||||
"wall_thickness": { "default_value": 1.2 },
|
"wall_thickness": { "value": "1.2" },
|
||||||
"speed_print": { "default_value": 40 },
|
"speed_print": { "default_value": 40 },
|
||||||
"support_enable": { "default_value": true },
|
"support_enable": { "default_value": true },
|
||||||
"retraction_enable": { "default_value": true },
|
"retraction_enable": { "default_value": true },
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1
|
"value": "1"
|
||||||
},
|
},
|
||||||
"top_bottom_thickness": {
|
"top_bottom_thickness": {
|
||||||
"default_value": 1
|
"default_value": 1
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
"machine_center_is_zero": { "default_value": false },
|
"machine_center_is_zero": { "default_value": false },
|
||||||
"layer_height": { "default_value": 0.2 },
|
"layer_height": { "default_value": 0.2 },
|
||||||
"layer_height_0": { "default_value": 0.2 },
|
"layer_height_0": { "default_value": 0.2 },
|
||||||
"wall_thickness": { "default_value": 1.2 },
|
"wall_thickness": { "value": "1.2" },
|
||||||
"top_bottom_thickness": { "default_value": 1.2 },
|
"top_bottom_thickness": { "default_value": 1.2 },
|
||||||
"infill_sparse_density": { "default_value": 20 },
|
"infill_sparse_density": { "default_value": 20 },
|
||||||
"speed_print": { "default_value": 60 },
|
"speed_print": { "default_value": 60 },
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1
|
"value": "1"
|
||||||
},
|
},
|
||||||
"top_bottom_thickness": {
|
"top_bottom_thickness": {
|
||||||
"default_value": 1
|
"default_value": 1
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1
|
"value": "1"
|
||||||
},
|
},
|
||||||
"top_bottom_thickness": {
|
"top_bottom_thickness": {
|
||||||
"default_value": 1
|
"default_value": 1
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"top_bottom_thickness": {
|
"top_bottom_thickness": {
|
||||||
"default_value": 1.2
|
"default_value": 1.2
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"top_bottom_thickness": {
|
"top_bottom_thickness": {
|
||||||
"default_value": 0.6
|
"default_value": 0.6
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||||
"machine_start_gcode": { "default_value": "G21 ;metric values\nG28 ;home all\nG90 ;absolute positioning\nM107 ;start with the fan off\nG1 F2400 Z15.0 ;raise the nozzle 15mm\nM109 S{material_print_temperature} ;Set Extruder Temperature and Wait\nM190 S{material_bed_temperature}; Wait for bed temperature to reach target temp\nT0 ;Switch to Extruder 1\nG1 F3000 X5 Y10 Z0.2 ;move to prime start position\nG92 E0 ;reset extrusion distance\nG1 F600 X160 E15 ;prime nozzle in a line\nG1 F5000 X180 ;quick wipe\nG92 E0 ;reset extrusion distance" },
|
"machine_start_gcode": { "default_value": "G21 ;metric values\nG28 ;home all\nG90 ;absolute positioning\nM107 ;start with the fan off\nG1 F2400 Z15.0 ;raise the nozzle 15mm\nM109 S{material_print_temperature} ;Set Extruder Temperature and Wait\nM190 S{material_bed_temperature}; Wait for bed temperature to reach target temp\nT0 ;Switch to Extruder 1\nG1 F3000 X5 Y10 Z0.2 ;move to prime start position\nG92 E0 ;reset extrusion distance\nG1 F600 X160 E15 ;prime nozzle in a line\nG1 F5000 X180 ;quick wipe\nG92 E0 ;reset extrusion distance" },
|
||||||
"machine_end_gcode": { "default_value": "M104 S0 ;hotend off\nM140 S0 ;bed off\nG92 E0\nG1 F2000 E-100 ;retract filament 100mm\nG92 E0\nG1 F3000 X0 Y270 ;move bed for easy part removal\nM84 ;disable steppers" },
|
"machine_end_gcode": { "default_value": "M104 S0 ;hotend off\nM140 S0 ;bed off\nG92 E0\nG1 F2000 E-100 ;retract filament 100mm\nG92 E0\nG1 F3000 X0 Y270 ;move bed for easy part removal\nM84 ;disable steppers" },
|
||||||
"wall_thickness": { "default_value": 1 },
|
"wall_thickness": { "value": "1" },
|
||||||
"top_bottom_thickness": { "default_value": 1 }
|
"top_bottom_thickness": { "default_value": 1 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
"max_skin_angle_for_expansion": { "default_value": 90 },
|
"max_skin_angle_for_expansion": { "default_value": 90 },
|
||||||
"skin_angles": { "default_value": "[135,45]" },
|
"skin_angles": { "default_value": "[135,45]" },
|
||||||
"coasting_volume": { "default_value": 0.032 },
|
"coasting_volume": { "default_value": 0.032 },
|
||||||
"wall_thickness": { "default_value": 1.2 },
|
"wall_thickness": { "value": "1.2" },
|
||||||
"cool_min_layer_time_fan_speed_max": { "default_value": 15 },
|
"cool_min_layer_time_fan_speed_max": { "default_value": 15 },
|
||||||
"cool_min_layer_time": { "default_value": 15 },
|
"cool_min_layer_time": { "default_value": 15 },
|
||||||
"support_interface_pattern": { "default_value": "zigzag" },
|
"support_interface_pattern": { "default_value": "zigzag" },
|
||||||
|
|
|
@ -7,24 +7,32 @@
|
||||||
"author": "Dagoma",
|
"author": "Dagoma",
|
||||||
"manufacturer": "Dagoma",
|
"manufacturer": "Dagoma",
|
||||||
"file_formats": "text/x-gcode",
|
"file_formats": "text/x-gcode",
|
||||||
"platform": "discoeasy200.stl",
|
"platform": "dagoma_discoeasy200.stl",
|
||||||
"platform_offset": [ 105, -59, 280],
|
"platform_offset": [0, -57.3, -11],
|
||||||
"has_machine_quality": true,
|
"has_machine_quality": true,
|
||||||
"has_materials": true,
|
"has_materials": true,
|
||||||
|
"preferred_material": "chromatik_pla",
|
||||||
"machine_extruder_trains":
|
"machine_extruder_trains":
|
||||||
{
|
{
|
||||||
"0": "dagoma_discoeasy200_extruder_0"
|
"0": "dagoma_discoeasy200_extruder_0",
|
||||||
|
"1": "dagoma_discoeasy200_extruder_1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
|
"machine_extruder_count": {
|
||||||
|
"default_value": 2
|
||||||
|
},
|
||||||
|
"machine_extruders_share_heater": {
|
||||||
|
"default_value": true
|
||||||
|
},
|
||||||
"machine_width": {
|
"machine_width": {
|
||||||
"default_value": 211
|
"default_value": 205
|
||||||
},
|
},
|
||||||
"machine_height": {
|
"machine_height": {
|
||||||
"default_value": 205
|
"default_value": 205
|
||||||
},
|
},
|
||||||
"machine_depth": {
|
"machine_depth": {
|
||||||
"default_value": 211
|
"default_value": 205
|
||||||
},
|
},
|
||||||
"machine_center_is_zero": {
|
"machine_center_is_zero": {
|
||||||
"default_value": false
|
"default_value": false
|
||||||
|
@ -66,6 +74,9 @@
|
||||||
},
|
},
|
||||||
"layer_height_0": {
|
"layer_height_0": {
|
||||||
"default_value": 0.26
|
"default_value": 0.26
|
||||||
|
},
|
||||||
|
"top_bottom_thickness": {
|
||||||
|
"default_value": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
82
resources/definitions/dagoma_discoultimate.def.json
Normal file
82
resources/definitions/dagoma_discoultimate.def.json
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
{
|
||||||
|
"name": "Dagoma DiscoUltimate",
|
||||||
|
"version": 2,
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"visible": true,
|
||||||
|
"author": "Dagoma",
|
||||||
|
"manufacturer": "Dagoma",
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"platform": "dagoma_discoultimate.stl",
|
||||||
|
"platform_offset": [0, -58.5, -11],
|
||||||
|
"has_machine_quality": true,
|
||||||
|
"has_materials": true,
|
||||||
|
"preferred_material": "chromatik_pla",
|
||||||
|
"machine_extruder_trains":
|
||||||
|
{
|
||||||
|
"0": "dagoma_discoultimate_extruder_0",
|
||||||
|
"1": "dagoma_discoultimate_extruder_1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"machine_extruder_count": {
|
||||||
|
"default_value": 2
|
||||||
|
},
|
||||||
|
"machine_extruders_share_heater": {
|
||||||
|
"default_value": true
|
||||||
|
},
|
||||||
|
"machine_width": {
|
||||||
|
"default_value": 205
|
||||||
|
},
|
||||||
|
"machine_height": {
|
||||||
|
"default_value": 205
|
||||||
|
},
|
||||||
|
"machine_depth": {
|
||||||
|
"default_value": 205
|
||||||
|
},
|
||||||
|
"machine_center_is_zero": {
|
||||||
|
"default_value": false
|
||||||
|
},
|
||||||
|
"machine_head_with_fans_polygon": {
|
||||||
|
"default_value": [
|
||||||
|
[-17, -70],
|
||||||
|
[-17, 40],
|
||||||
|
[17, 40],
|
||||||
|
[17, -70]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"gantry_height": {
|
||||||
|
"value": "10"
|
||||||
|
},
|
||||||
|
"machine_start_gcode": {
|
||||||
|
"default_value": ";Gcode by Cura\nG90\nM106 S255\nG28 X Y\nG1 X50\nM109 R90\nG28\nM104 S{material_print_temperature_layer_0}\nG29\nM107\nG1 X100 Y20 F3000\nG1 Z0.5\nM109 S{material_print_temperature_layer_0}\nM82\nG92 E0\nG1 F200 E10\nG92 E0\nG1 Z3\nG1 F6000\n"
|
||||||
|
},
|
||||||
|
"machine_end_gcode": {
|
||||||
|
"default_value": "\nM104 S0\nM106 S255\nM140 S0\nG91\nG1 E-1 F300\nG1 Z+3 F3000\nG90\nG28 X Y\nM107\nM84\n"
|
||||||
|
},
|
||||||
|
"default_material_print_temperature": {
|
||||||
|
"default_value": 205
|
||||||
|
},
|
||||||
|
"speed_print": {
|
||||||
|
"default_value": 60
|
||||||
|
},
|
||||||
|
"retraction_amount": {
|
||||||
|
"default_value": 3.5
|
||||||
|
},
|
||||||
|
"retraction_speed": {
|
||||||
|
"default_value": 50
|
||||||
|
},
|
||||||
|
"adhesion_type": {
|
||||||
|
"default_value": "skirt"
|
||||||
|
},
|
||||||
|
"skirt_line_count": {
|
||||||
|
"default_value": 2
|
||||||
|
},
|
||||||
|
"layer_height_0": {
|
||||||
|
"default_value": 0.26
|
||||||
|
},
|
||||||
|
"top_bottom_thickness": {
|
||||||
|
"default_value": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,10 +7,11 @@
|
||||||
"author": "Dagoma",
|
"author": "Dagoma",
|
||||||
"manufacturer": "Dagoma",
|
"manufacturer": "Dagoma",
|
||||||
"file_formats": "text/x-gcode",
|
"file_formats": "text/x-gcode",
|
||||||
"platform": "neva.stl",
|
"platform": "dagoma_magis.stl",
|
||||||
"platform_offset": [ 0, 0, 0],
|
"platform_offset": [0, -28, -35],
|
||||||
"has_machine_quality": true,
|
"has_machine_quality": true,
|
||||||
"has_materials": true,
|
"has_materials": true,
|
||||||
|
"preferred_material": "chromatik_pla",
|
||||||
"machine_extruder_trains":
|
"machine_extruder_trains":
|
||||||
{
|
{
|
||||||
"0": "dagoma_magis_extruder_0"
|
"0": "dagoma_magis_extruder_0"
|
||||||
|
@ -69,6 +70,9 @@
|
||||||
},
|
},
|
||||||
"layer_height_0": {
|
"layer_height_0": {
|
||||||
"default_value": 0.26
|
"default_value": 0.26
|
||||||
|
},
|
||||||
|
"top_bottom_thickness": {
|
||||||
|
"default_value": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,11 @@
|
||||||
"author": "Dagoma",
|
"author": "Dagoma",
|
||||||
"manufacturer": "Dagoma",
|
"manufacturer": "Dagoma",
|
||||||
"file_formats": "text/x-gcode",
|
"file_formats": "text/x-gcode",
|
||||||
"platform": "neva.stl",
|
"platform": "dagoma_neva.stl",
|
||||||
"platform_offset": [ 0, 0, 0],
|
"platform_offset": [0, -28, -35],
|
||||||
"has_machine_quality": true,
|
"has_machine_quality": true,
|
||||||
"has_materials": true,
|
"has_materials": true,
|
||||||
|
"preferred_material": "chromatik_pla",
|
||||||
"machine_extruder_trains":
|
"machine_extruder_trains":
|
||||||
{
|
{
|
||||||
"0": "dagoma_neva_extruder_0"
|
"0": "dagoma_neva_extruder_0"
|
||||||
|
@ -69,6 +70,9 @@
|
||||||
},
|
},
|
||||||
"layer_height_0": {
|
"layer_height_0": {
|
||||||
"default_value": 0.26
|
"default_value": 0.26
|
||||||
|
},
|
||||||
|
"top_bottom_thickness": {
|
||||||
|
"default_value": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
182
resources/definitions/dxu.def.json
Normal file
182
resources/definitions/dxu.def.json
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"name": "DXU",
|
||||||
|
"inherits": "ultimaker2_plus",
|
||||||
|
"metadata": {
|
||||||
|
"visible": true,
|
||||||
|
"author": "TheUltimakerCommunity",
|
||||||
|
"manufacturer": "DXU",
|
||||||
|
"category": "Other",
|
||||||
|
"has_variants": true,
|
||||||
|
"has_materials": true,
|
||||||
|
"has_machine_materials": false,
|
||||||
|
"has_machine_quality": false,
|
||||||
|
"has_variant_materials": false,
|
||||||
|
"weight": 0,
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"icon": "icon_ultimaker.png",
|
||||||
|
"platform": "ultimaker2_platform.obj",
|
||||||
|
"platform_texture": "dxu_backplate.png",
|
||||||
|
"platform_offset": [1.5, 0, 0],
|
||||||
|
"machine_extruder_trains":
|
||||||
|
{
|
||||||
|
"0": "dxu_extruder1",
|
||||||
|
"1": "dxu_extruder2"
|
||||||
|
},
|
||||||
|
"supported_actions": ["MachineSettingsAction", "UpgradeFirmware"]
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": {
|
||||||
|
"default_value": "dxu"
|
||||||
|
},
|
||||||
|
"machine_width": {
|
||||||
|
"default_value": 238
|
||||||
|
},
|
||||||
|
"machine_depth": {
|
||||||
|
"default_value": 223
|
||||||
|
},
|
||||||
|
"machine_height": {
|
||||||
|
"default_value": 203
|
||||||
|
},
|
||||||
|
"machine_center_is_zero": {
|
||||||
|
"default_value": false
|
||||||
|
},
|
||||||
|
"machine_nozzle_size": {
|
||||||
|
"default_value": 0.4
|
||||||
|
},
|
||||||
|
"material_diameter": {
|
||||||
|
"default_value": 1.75
|
||||||
|
},
|
||||||
|
"machine_nozzle_heat_up_speed": {
|
||||||
|
"default_value": 3.5
|
||||||
|
},
|
||||||
|
"machine_nozzle_cool_down_speed": {
|
||||||
|
"default_value": 1.5
|
||||||
|
},
|
||||||
|
"machine_min_cool_heat_time_window":
|
||||||
|
{
|
||||||
|
"default_value": 15.0
|
||||||
|
},
|
||||||
|
"machine_show_variants": {
|
||||||
|
"default_value": true
|
||||||
|
},
|
||||||
|
"machine_nozzle_head_distance": {
|
||||||
|
"default_value": 5
|
||||||
|
},
|
||||||
|
"machine_nozzle_expansion_angle": {
|
||||||
|
"default_value": 45
|
||||||
|
},
|
||||||
|
"machine_heat_zone_length": {
|
||||||
|
"default_value": 20
|
||||||
|
},
|
||||||
|
"machine_heated_bed": {
|
||||||
|
"default_value": true
|
||||||
|
},
|
||||||
|
"speed_infill": {
|
||||||
|
"value": "speed_print"
|
||||||
|
},
|
||||||
|
"speed_wall_x": {
|
||||||
|
"value": "speed_wall"
|
||||||
|
},
|
||||||
|
"layer_height_0": {
|
||||||
|
"value": "round(machine_nozzle_size / 1.5, 2)"
|
||||||
|
},
|
||||||
|
"line_width": {
|
||||||
|
"value": "round(machine_nozzle_size * 0.875, 2)"
|
||||||
|
},
|
||||||
|
"speed_support": {
|
||||||
|
"value": "speed_wall_0"
|
||||||
|
},
|
||||||
|
"machine_max_feedrate_x": {
|
||||||
|
"default_value": 300
|
||||||
|
},
|
||||||
|
"machine_max_feedrate_y": {
|
||||||
|
"default_value": 300
|
||||||
|
},
|
||||||
|
"machine_max_feedrate_z": {
|
||||||
|
"default_value": 40
|
||||||
|
},
|
||||||
|
"machine_max_feedrate_e": {
|
||||||
|
"default_value": 45
|
||||||
|
},
|
||||||
|
"machine_acceleration": {
|
||||||
|
"default_value": 3000
|
||||||
|
},
|
||||||
|
"retraction_amount": {
|
||||||
|
"default_value": 6.5
|
||||||
|
},
|
||||||
|
"retraction_speed": {
|
||||||
|
"default_value": 25
|
||||||
|
},
|
||||||
|
"switch_extruder_retraction_amount": {
|
||||||
|
"value": "retraction_amount",
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"switch_extruder_retraction_speeds": {
|
||||||
|
"value": "retraction_speed",
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"switch_extruder_retraction_speed": {
|
||||||
|
"value": "retraction_retract_speed",
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"switch_extruder_prime_speed": {
|
||||||
|
"value": "retraction_prime_speed",
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"machine_head_with_fans_polygon":
|
||||||
|
{
|
||||||
|
"default_value": [
|
||||||
|
[ -44, 14 ],
|
||||||
|
[ -44, -34 ],
|
||||||
|
[ 64, 14 ],
|
||||||
|
[ 64, -34 ]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"machine_use_extruder_offset_to_offset_coords": {
|
||||||
|
"default_value": false
|
||||||
|
},
|
||||||
|
"machine_gcode_flavor": {
|
||||||
|
"default_value": "RepRap (Marlin/Sprinter)"
|
||||||
|
},
|
||||||
|
"machine_start_gcode" : {
|
||||||
|
"value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \";material_bed_temperature={material_bed_temperature} material_print_temperature={material_print_temperature} material_print_temperature_layer_0={material_print_temperature_layer_0}\\nM190 S{material_bed_temperature_layer_0}\\nG21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nM200 D0 T{initial_extruder_nr} ;reset filament diameter\\nG28 ;home all\\nT{initial_extruder_nr} ;switch to the first nozzle used for print\\nM104 T{initial_extruder_nr} S{material_standby_temperature, initial_extruder_nr}\\nG0 X25 Y20 F7200\\nG0 Z20 F2400\\nM109 T{initial_extruder_nr} S{material_print_temperature_layer_0, initial_extruder_nr}\\nG0 X210 Y20 F7200\\nG92 E-7.0\\nG1 E0 F45 ;purge nozzle\\nG1 E-6.5 F1500\\nG1 E0 F1500\\nM400 ;finish all moves\\nT{initial_extruder_nr}\\n;end of startup sequence\\n\""
|
||||||
|
},
|
||||||
|
"machine_end_gcode" : {
|
||||||
|
"value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G90 ;absolute positioning\\nM104 S0 T0 ;extruder heater off\\nM104 S0 T1\\nM140 S0 ;turn off bed\\nT0 ; move to the first head\\nM107 ;fan off\""
|
||||||
|
},
|
||||||
|
"machine_extruder_count": {
|
||||||
|
"default_value": 2
|
||||||
|
},
|
||||||
|
"extruder_prime_pos_abs": { "default_value": false },
|
||||||
|
"extruder_prime_pos_x": { "default_value": 0.0, "enabled": false },
|
||||||
|
"extruder_prime_pos_y": { "default_value": 0.0, "enabled": false },
|
||||||
|
"extruder_prime_pos_z": { "default_value": 0.0, "enabled": false },
|
||||||
|
"layer_start_x": {
|
||||||
|
"default_value": 180.0,
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"layer_start_y": {
|
||||||
|
"default_value": 160.0,
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
"prime_tower_position_x": {
|
||||||
|
"value": "180"
|
||||||
|
},
|
||||||
|
"prime_tower_position_y": {
|
||||||
|
"value": "160"
|
||||||
|
},
|
||||||
|
"material_adhesion_tendency": {
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"machine_disallowed_areas": {
|
||||||
|
"default_value": [
|
||||||
|
[[-120, 112.5], [ -101, 112.5], [ -101, 106.5], [-120, 106.5]],
|
||||||
|
[[ 120, 112.5], [ 120, 106.5], [ 86, 106.5], [ 86, 112.5]],
|
||||||
|
[[-120, -112.5], [-120, -106.5], [ -101, -106.5], [ -101, -112.5]],
|
||||||
|
[[ 120, -112.5], [ 86, -112.5], [ 86, -106.5], [ 120, -106.5]],
|
||||||
|
[[ 120, -112.5], [ 120, -72.5], [ 93, -72.5], [ 93, -112.5]]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
resources/definitions/dxu_dual.def.json
Normal file
16
resources/definitions/dxu_dual.def.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"name": "DXU Dual",
|
||||||
|
"inherits": "dxu",
|
||||||
|
"overrides": {
|
||||||
|
"machine_start_gcode" : {
|
||||||
|
"value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \";material_bed_temperature={material_bed_temperature} material_print_temperature={material_print_temperature} material_print_temperature_layer_0={material_print_temperature_layer_0}\\nM190 S{material_bed_temperature_layer_0}\\nM104 T0 S{material_standby_temperature, 0}\\nM104 T0 S{material_print_temperature_layer_0, 0}\\nG21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nM200 D0 T0 ;reset filament diameter\\nM200 D0 T1\\nG28 ;home all\\nT1 ; move to the nozzle 2\\nG0 Z20 F2400 ;move the platform to 30mm\\nM109 T1 S{material_print_temperature_layer_0, 1}\\nG0 X210 Y20 F7200\\nG92 E0\\nG92 E-7.0 ;prime distance\\nG1 E0 F45 ;purge nozzle\\nG1 E-6.5 F1500 ; retract\\nT0 ; move to the nozzle 1\\nM104 T1 S{material_standby_temperature, 1}\\nG0 Z20 F2400\\nM109 T0 S{material_print_temperature_layer_0, 0}\\nG0 X210 Y20 F7200\\nG92 E0\\nG92 E-7.0\\nG1 E0 F45 ;purge nozzle\\nG1 E-6.5 F1500\\nM104 T0 S{material_standby_temperature, 0}\\nT{initial_extruder_nr} ;switch to the first nozzle used for print\\nM109 T{initial_extruder_nr} S{material_print_temperature_layer_0, initial_extruder_nr}\\nM400 ;finish all moves\\nG1 E0 F1500\\nG92 E0\\n;end of startup sequence\\n\""
|
||||||
|
},
|
||||||
|
"machine_end_gcode" : {
|
||||||
|
"value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G90 ;absolute positioning\\nM104 S0 T0 ;extruder heater off\\nM104 S0 T1\\nM140 S0 ;turn off bed\\nT0 ; move to the first head\\nM107 ;fan off\""
|
||||||
|
},
|
||||||
|
"prime_tower_enable": {
|
||||||
|
"default_value": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,7 +44,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1
|
"value": "1"
|
||||||
},
|
},
|
||||||
"top_bottom_thickness": {
|
"top_bottom_thickness": {
|
||||||
"default_value": 1
|
"default_value": 1
|
||||||
|
|
|
@ -142,6 +142,8 @@
|
||||||
"description": "The width (X-direction) of the printable area.",
|
"description": "The width (X-direction) of the printable area.",
|
||||||
"default_value": 100,
|
"default_value": 100,
|
||||||
"type": "float",
|
"type": "float",
|
||||||
|
"minimum_value": "0.001",
|
||||||
|
"maximum_value": "2000000",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": false,
|
"settable_per_extruder": false,
|
||||||
"settable_per_meshgroup": false
|
"settable_per_meshgroup": false
|
||||||
|
@ -152,6 +154,8 @@
|
||||||
"description": "The depth (Y-direction) of the printable area.",
|
"description": "The depth (Y-direction) of the printable area.",
|
||||||
"default_value": 100,
|
"default_value": 100,
|
||||||
"type": "float",
|
"type": "float",
|
||||||
|
"minimum_value": "0.001",
|
||||||
|
"maximum_value": "2000000",
|
||||||
"settable_per_mesh": false,
|
"settable_per_mesh": false,
|
||||||
"settable_per_extruder": false,
|
"settable_per_extruder": false,
|
||||||
"settable_per_meshgroup": false
|
"settable_per_meshgroup": false
|
||||||
|
@ -1028,6 +1032,7 @@
|
||||||
"description": "The thickness of the walls in the horizontal direction. This value divided by the wall line width defines the number of walls.",
|
"description": "The thickness of the walls in the horizontal direction. This value divided by the wall line width defines the number of walls.",
|
||||||
"unit": "mm",
|
"unit": "mm",
|
||||||
"default_value": 0.8,
|
"default_value": 0.8,
|
||||||
|
"value": "wall_line_width_0 if magic_spiralize else 0.8",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"minimum_value_warning": "line_width",
|
"minimum_value_warning": "line_width",
|
||||||
"maximum_value_warning": "10 * line_width",
|
"maximum_value_warning": "10 * line_width",
|
||||||
|
@ -1981,6 +1986,7 @@
|
||||||
"default_value": 1,
|
"default_value": 1,
|
||||||
"value": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
|
"value": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
|
"maximum_value_warning": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
|
||||||
"enabled": "top_layers > 0 or bottom_layers > 0",
|
"enabled": "top_layers > 0 or bottom_layers > 0",
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
"settable_per_mesh": true,
|
"settable_per_mesh": true,
|
||||||
|
@ -1994,6 +2000,7 @@
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 1,
|
"default_value": 1,
|
||||||
"value": "skin_preshrink",
|
"value": "skin_preshrink",
|
||||||
|
"maximum_value_warning": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"enabled": "top_layers > 0 or bottom_layers > 0",
|
"enabled": "top_layers > 0 or bottom_layers > 0",
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
@ -2007,6 +2014,7 @@
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 1,
|
"default_value": 1,
|
||||||
"value": "skin_preshrink",
|
"value": "skin_preshrink",
|
||||||
|
"maximum_value_warning": "wall_line_width_0 + (wall_line_count - 1) * wall_line_width_x",
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"enabled": "top_layers > 0 or bottom_layers > 0",
|
"enabled": "top_layers > 0 or bottom_layers > 0",
|
||||||
"limit_to_extruder": "top_bottom_extruder_nr",
|
"limit_to_extruder": "top_bottom_extruder_nr",
|
||||||
|
@ -2095,7 +2103,7 @@
|
||||||
"minimum_value": "0",
|
"minimum_value": "0",
|
||||||
"maximum_value": "machine_height",
|
"maximum_value": "machine_height",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"value": "0",
|
"value": "0 if infill_sparse_density > 0 else 0",
|
||||||
"limit_to_extruder": "infill_extruder_nr",
|
"limit_to_extruder": "infill_extruder_nr",
|
||||||
"enabled": "infill_sparse_density > 0",
|
"enabled": "infill_sparse_density > 0",
|
||||||
"settable_per_mesh": true,
|
"settable_per_mesh": true,
|
||||||
|
@ -2444,7 +2452,7 @@
|
||||||
"material_flush_purge_speed":
|
"material_flush_purge_speed":
|
||||||
{
|
{
|
||||||
"label": "Flush Purge Speed",
|
"label": "Flush Purge Speed",
|
||||||
"description": "Material Station internal value",
|
"description": "How fast to prime the material after switching to a different material.",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 0.5,
|
"default_value": 0.5,
|
||||||
"enabled": false
|
"enabled": false
|
||||||
|
@ -2452,23 +2460,23 @@
|
||||||
"material_flush_purge_length":
|
"material_flush_purge_length":
|
||||||
{
|
{
|
||||||
"label": "Flush Purge Length",
|
"label": "Flush Purge Length",
|
||||||
"description": "Material Station internal value",
|
"description": "How much material to use to purge the previous material out of the nozzle (in length of filament) when switching to a different material.",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 60,
|
"default_value": 60,
|
||||||
"enabled": false
|
"enabled": false
|
||||||
},
|
},
|
||||||
"material_end_of_filament_purge_speed":
|
"material_end_of_filament_purge_speed":
|
||||||
{
|
{
|
||||||
"label": "End Of Filament Purge Speed",
|
"label": "End of Filament Purge Speed",
|
||||||
"description": "Material Station internal value",
|
"description": "How fast to prime the material after replacing an empty spool with a fresh spool of the same material.",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 0.5,
|
"default_value": 0.5,
|
||||||
"enabled": false
|
"enabled": false
|
||||||
},
|
},
|
||||||
"material_end_of_filament_purge_length":
|
"material_end_of_filament_purge_length":
|
||||||
{
|
{
|
||||||
"label": "End Of Filament Purge Length",
|
"label": "End of Filament Purge Length",
|
||||||
"description": "Material Station internal value",
|
"description": "How much material to use to purge the previous material out of the nozzle (in length of filament) when replacing an empty spool with a fresh spool of the same material.",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 20,
|
"default_value": 20,
|
||||||
"enabled": false
|
"enabled": false
|
||||||
|
@ -2476,7 +2484,7 @@
|
||||||
"material_maximum_park_duration":
|
"material_maximum_park_duration":
|
||||||
{
|
{
|
||||||
"label": "Maximum Park Duration",
|
"label": "Maximum Park Duration",
|
||||||
"description": "Material Station internal value",
|
"description": "How long the material can be kept out of dry storage safely.",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 300,
|
"default_value": 300,
|
||||||
"enabled": false
|
"enabled": false
|
||||||
|
@ -2484,7 +2492,7 @@
|
||||||
"material_no_load_move_factor":
|
"material_no_load_move_factor":
|
||||||
{
|
{
|
||||||
"label": "No Load Move Factor",
|
"label": "No Load Move Factor",
|
||||||
"description": "Material Station internal value",
|
"description": "A factor indicating how much the filament gets compressed between the feeder and the nozzle chamber, used to determine how far to move the material for a filament switch.",
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"default_value": 0.940860215,
|
"default_value": 0.940860215,
|
||||||
"enabled": false
|
"enabled": false
|
||||||
|
@ -5875,7 +5883,7 @@
|
||||||
"label": "Mesh Fixes",
|
"label": "Mesh Fixes",
|
||||||
"type": "category",
|
"type": "category",
|
||||||
"icon": "category_fixes",
|
"icon": "category_fixes",
|
||||||
"description": "category_fixes",
|
"description": "Make the meshes more suited for 3D printing.",
|
||||||
"children":
|
"children":
|
||||||
{
|
{
|
||||||
"meshfix_union_all":
|
"meshfix_union_all":
|
||||||
|
@ -6001,7 +6009,7 @@
|
||||||
"label": "Special Modes",
|
"label": "Special Modes",
|
||||||
"type": "category",
|
"type": "category",
|
||||||
"icon": "category_blackmagic",
|
"icon": "category_blackmagic",
|
||||||
"description": "category_blackmagic",
|
"description": "Non-traditional ways to print your models.",
|
||||||
"children":
|
"children":
|
||||||
{
|
{
|
||||||
"print_sequence":
|
"print_sequence":
|
||||||
|
@ -6174,7 +6182,7 @@
|
||||||
"label": "Experimental",
|
"label": "Experimental",
|
||||||
"type": "category",
|
"type": "category",
|
||||||
"icon": "category_experimental",
|
"icon": "category_experimental",
|
||||||
"description": "experimental!",
|
"description": "Features that haven't completely been fleshed out yet.",
|
||||||
"children":
|
"children":
|
||||||
{
|
{
|
||||||
"support_tree_enable":
|
"support_tree_enable":
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
"layer_height_0": { "default_value": 0.2 },
|
"layer_height_0": { "default_value": 0.2 },
|
||||||
|
|
||||||
"infill_sparse_density": { "default_value": 20 },
|
"infill_sparse_density": { "default_value": 20 },
|
||||||
"wall_thickness": { "default_value": 1 },
|
"wall_thickness": { "value": "1" },
|
||||||
"top_bottom_thickness": { "default_value": 1 },
|
"top_bottom_thickness": { "default_value": 1 },
|
||||||
|
|
||||||
"machine_width": { "default_value": 240 },
|
"machine_width": { "default_value": 240 },
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
"layer_height": { "default_value": 0.2 },
|
"layer_height": { "default_value": 0.2 },
|
||||||
"layer_height_0": { "default_value": 0.3 },
|
"layer_height_0": { "default_value": 0.3 },
|
||||||
"infill_sparse_density": { "default_value": 20 },
|
"infill_sparse_density": { "default_value": 20 },
|
||||||
"wall_thickness": { "default_value": 1 },
|
"wall_thickness": { "value": "1" },
|
||||||
"top_bottom_thickness": { "default_value": 1 },
|
"top_bottom_thickness": { "default_value": 1 },
|
||||||
|
|
||||||
"infill_pattern": { "value": "'tetrahedral'" },
|
"infill_pattern": { "value": "'tetrahedral'" },
|
||||||
|
|
134
resources/definitions/flyingbear_base.def.json
Normal file
134
resources/definitions/flyingbear_base.def.json
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
{
|
||||||
|
"name": "Flying Bear Base Printer",
|
||||||
|
"version": 2,
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"visible": false,
|
||||||
|
"author": "oducceu",
|
||||||
|
"manufacturer": "Flying Bear",
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"first_start_actions": ["MachineSettingsAction"],
|
||||||
|
|
||||||
|
"machine_extruder_trains": { "0": "flyingbear_base_extruder_0" },
|
||||||
|
|
||||||
|
"has_materials": true,
|
||||||
|
"preferred_material": "generic_pla",
|
||||||
|
|
||||||
|
"has_variants": true,
|
||||||
|
"variants_name": "Nozzle Size",
|
||||||
|
"preferred_variant_name": "0.4mm Nozzle",
|
||||||
|
|
||||||
|
"has_machine_quality": true,
|
||||||
|
"preferred_quality_type": "normal",
|
||||||
|
|
||||||
|
"exclude_materials": ["Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_PLA_Glitter", "Vertex_Delta_PLA_Mat", "Vertex_Delta_PLA_Satin", "Vertex_Delta_PLA_Wood", "Vertex_Delta_TPU", "chromatik_pla", "dsm_arnitel2045_175", "dsm_novamid1070_175", "emotiontech_abs", "emotiontech_asax", "emotiontech_hips", "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", "generic_abs", "generic_bam", "generic_cffcpe", "generic_cffpa", "generic_cpe", "generic_cpe_plus", "generic_gffcpe", "generic_gffpa", "generic_hips", "generic_nylon", "generic_pc", "generic_petg", "generic_pla", "generic_pp", "generic_pva", "generic_tough_pla", "generic_tpu", "imade3d_petg_green", "imade3d_petg_pink", "imade3d_pla_green", "imade3d_pla_pink", "imade3d_petg_175", "imade3d_pla_175", "innofill_innoflex60_175", "leapfrog_abs_natural", "leapfrog_epla_natural", "leapfrog_pva_natural", "octofiber_pla", "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla", "structur3d_dap100silicone", "tizyx_abs", "tizyx_flex", "tizyx_petg", "tizyx_pla", "tizyx_pla_bois", "tizyx_pva", "ultimaker_abs_black", "ultimaker_abs_blue", "ultimaker_abs_green", "ultimaker_abs_grey", "ultimaker_abs_orange", "ultimaker_abs_pearl-gold", "ultimaker_abs_red", "ultimaker_abs_silver-metallic", "ultimaker_abs_white", "ultimaker_abs_yellow", "ultimaker_bam", "ultimaker_cpe_black", "ultimaker_cpe_blue", "ultimaker_cpe_dark-grey", "ultimaker_cpe_green", "ultimaker_cpe_light-grey", "ultimaker_cpe_plus_black", "ultimaker_cpe_plus_transparent", "ultimaker_cpe_plus_white", "ultimaker_cpe_red", "ultimaker_cpe_transparent", "ultimaker_cpe_white", "ultimaker_cpe_yellow", "ultimaker_nylon_black", "ultimaker_nylon_transparent", "ultimaker_pc_black", "ultimaker_pc_transparent", "ultimaker_pc_white", "ultimaker_pla_black", "ultimaker_pla_blue", "ultimaker_pla_green", "ultimaker_pla_magenta", "ultimaker_pla_orange", "ultimaker_pla_pearl-white", "ultimaker_pla_red", "ultimaker_pla_silver-metallic", "ultimaker_pla_transparent", "ultimaker_pla_white", "ultimaker_pla_yellow", "ultimaker_pp_transparent", "ultimaker_pva", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "ultimaker_tpu_black", "ultimaker_tpu_blue", "ultimaker_tpu_red", "ultimaker_tpu_white", "verbatim_bvoh_175", "zyyx_pro_flex", "zyyx_pro_pla"]
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": { "default_value": "Flying Bear Base Printer" },
|
||||||
|
|
||||||
|
"machine_start_gcode": { "default_value": "M220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\n\n;Code for nozzle cleaning and flow normalization\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.4 Y20 Z0.28 F5000.0\nG1 X10.4 Y170.0 Z0.28 F1500.0 E15\nG1 X10.1 Y170.0 Z0.28 F5000.0\nG1 X10.1 Y40 Z0.28 F1500.0 E30\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up" },
|
||||||
|
|
||||||
|
"machine_end_gcode": { "default_value": "G91 ;Relative positioning\nG1 E-2 F2700 ;Retract the filament\nG1 E-2 Z0.2 F2400 ;Retract and raise Z\nG1 X5 Y5 F3000 ;Wipe out\nG1 Z10 ;Raise Z more\nG90 ;Absolute positionning\n\nG28 X0 Y0 ;Home X and Y\n\nM106 S0 ;Turn-off fan\nM104 S0 ;Turn-off hotend\nM140 S0 ;Turn-off bed\n\nM84 X Y E ;Disable all steppers but Z" },
|
||||||
|
|
||||||
|
"machine_heated_bed": { "default_value": true },
|
||||||
|
"machine_shape": { "default_value": "rectangular" },
|
||||||
|
"machine_buildplate_type": { "value": "glass" },
|
||||||
|
"machine_center_is_zero": { "default_value": false },
|
||||||
|
|
||||||
|
"material_diameter": { "default_value": 1.75 },
|
||||||
|
|
||||||
|
"layer_height_0": { "value": 0.2 },
|
||||||
|
"line_width": { "value": "machine_nozzle_size" },
|
||||||
|
"skin_line_width": { "value": "machine_nozzle_size" },
|
||||||
|
"infill_line_width": { "value": "line_width + 0.1" },
|
||||||
|
"skirt_brim_line_width": { "value": "line_width + 0.1" },
|
||||||
|
"support_interface_line_width": { "value": "line_width - 0.1" },
|
||||||
|
|
||||||
|
"wall_thickness": { "value": "line_width * 3" },
|
||||||
|
"wall_0_wipe_dist": { "value": 0.0 },
|
||||||
|
"top_bottom_thickness": { "value": "layer_height_0 + layer_height * 3 if layer_height > 0.15 else 0.8" },
|
||||||
|
"optimize_wall_printing_order": { "value": true },
|
||||||
|
"travel_compensate_overlapping_walls_0_enabled": { "value": false },
|
||||||
|
"fill_perimeter_gaps": { "value": "'everywhere'" },
|
||||||
|
"filter_out_tiny_gaps": { "value": false },
|
||||||
|
"fill_outline_gaps": { "value": false },
|
||||||
|
"z_seam_type": { "value": "'sharpest_corner'" },
|
||||||
|
"z_seam_corner": { "value": "'z_seam_corner_weighted'" },
|
||||||
|
|
||||||
|
"infill_sparse_density": { "value": 20 },
|
||||||
|
"infill_pattern": { "value": "'lines' if infill_sparse_density > 50 else 'cubic'" },
|
||||||
|
"infill_overlap": { "value": 30 },
|
||||||
|
"skin_overlap": { "value": 10 },
|
||||||
|
"infill_wipe_dist": { "value": 0.0 },
|
||||||
|
"infill_before_walls": { "value": false },
|
||||||
|
"infill_enable_travel_optimization": { "value": true },
|
||||||
|
|
||||||
|
"material_initial_print_temperature": { "value": "material_print_temperature" },
|
||||||
|
"material_final_print_temperature": { "value": "material_print_temperature" },
|
||||||
|
"material_flow": { "value": 100 },
|
||||||
|
"retraction_enable": { "value": true },
|
||||||
|
"retraction_min_travel": { "value": 1.5 },
|
||||||
|
"retraction_count_max": { "value": 100 },
|
||||||
|
"retraction_extrusion_window": { "value": 10 },
|
||||||
|
|
||||||
|
"speed_print": { "value": 60 } ,
|
||||||
|
"speed_infill": { "value": "speed_print" },
|
||||||
|
"speed_wall": { "value": "speed_print / 2" },
|
||||||
|
"speed_wall_0": { "value": "speed_wall" },
|
||||||
|
"speed_wall_x": { "value": "speed_print" },
|
||||||
|
"speed_roofing": { "value": "speed_topbottom" },
|
||||||
|
"speed_topbottom": { "value": "speed_print / 2" },
|
||||||
|
"speed_support": { "value": "speed_print" },
|
||||||
|
"speed_support_interface": { "value": "speed_topbottom" },
|
||||||
|
"speed_prime_tower": { "value": "speed_topbottom" },
|
||||||
|
"speed_travel": { "value": "150.0 if speed_print < 60 else 250.0 if speed_print > 100 else speed_print * 2.5" },
|
||||||
|
"speed_layer_0": { "value": 20 },
|
||||||
|
"speed_print_layer_0": { "value": "speed_layer_0" },
|
||||||
|
"speed_travel_layer_0": { "value": "100 if speed_layer_0 < 20 else 150 if speed_layer_0 > 30 else speed_layer_0 * 5" },
|
||||||
|
"skirt_brim_speed": { "value": "speed_layer_0" },
|
||||||
|
"speed_z_hop": { "value": 5 },
|
||||||
|
|
||||||
|
"retraction_combing": { "value": "'off' if retraction_hop_enabled else 'noskin'" },
|
||||||
|
"travel_retract_before_outer_wall": { "value": true },
|
||||||
|
"retraction_combing_max_distance": { "value": 30 },
|
||||||
|
"travel_avoid_other_parts": { "value": true },
|
||||||
|
"travel_avoid_supports": { "value": true },
|
||||||
|
"retraction_hop_enabled": { "value": false },
|
||||||
|
"retraction_hop": { "value": 0.2 },
|
||||||
|
|
||||||
|
"cool_fan_enabled": { "value": true },
|
||||||
|
"cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" },
|
||||||
|
"cool_min_layer_time": { "value": 10 },
|
||||||
|
|
||||||
|
"support_angle": { "value": "math.floor(math.degrees(math.atan(line_width/2.0/layer_height)))" },
|
||||||
|
"support_pattern": { "value": "'zigzag'" },
|
||||||
|
"support_infill_rate": { "value": "0 if support_tree_enable else 20" },
|
||||||
|
"support_z_distance": { "value": "layer_height if layer_height >= 0.16 else layer_height*2" },
|
||||||
|
"support_xy_distance": { "value": "wall_line_width_0 * 2" },
|
||||||
|
"support_xy_overrides_z": { "value": "'xy_overrides_z'" },
|
||||||
|
"support_xy_distance_overhang": { "value": "wall_line_width_0" },
|
||||||
|
"minimum_support_area": { "value": 5 },
|
||||||
|
"minimum_interface_area": { "value": 10 },
|
||||||
|
"support_interface_enable": { "value": true },
|
||||||
|
"support_interface_height": { "value": "layer_height * 4" },
|
||||||
|
"support_interface_skip_height": { "value": 0.2 },
|
||||||
|
"support_interface_density": { "value": 33 },
|
||||||
|
"support_interface_pattern": { "value": "'grid'" },
|
||||||
|
"support_wall_count": { "value": 1 },
|
||||||
|
"support_brim_enable": { "value": true },
|
||||||
|
"support_brim_width": { "value": 4 },
|
||||||
|
"support_use_towers": { "value": false },
|
||||||
|
|
||||||
|
"adhesion_type": { "value": "'skirt'" },
|
||||||
|
"skirt_line_count": { "value": 3 },
|
||||||
|
"skirt_gap": { "value": 10 },
|
||||||
|
"skirt_brim_minimal_length": { "value": 50 },
|
||||||
|
"brim_replaces_support": { "value": false },
|
||||||
|
|
||||||
|
"meshfix_maximum_resolution": { "value": 0.05 },
|
||||||
|
"meshfix_maximum_travel_resolution": { "value": "meshfix_maximum_resolution" },
|
||||||
|
|
||||||
|
"adaptive_layer_height_variation": { "value": 0.04 },
|
||||||
|
"adaptive_layer_height_variation_step": { "value": 0.04 }
|
||||||
|
}
|
||||||
|
}
|
54
resources/definitions/flyingbear_ghost_4s.def.json
Normal file
54
resources/definitions/flyingbear_ghost_4s.def.json
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"name": "Flying Bear Ghost 4S",
|
||||||
|
"version": 2,
|
||||||
|
"inherits": "flyingbear_base",
|
||||||
|
"metadata": {
|
||||||
|
"visible": true,
|
||||||
|
"author": "oducceu",
|
||||||
|
|
||||||
|
"platform": "flyingbear_platform.obj",
|
||||||
|
"platform_texture": "flyingbear_platform.png",
|
||||||
|
|
||||||
|
"quality_definition": "flyingbear_base"
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": { "default_value": "Flying Bear Ghost 4S" },
|
||||||
|
"machine_width": { "default_value": 255 },
|
||||||
|
"machine_depth": { "default_value": 210 },
|
||||||
|
"machine_height": { "default_value": 210 },
|
||||||
|
|
||||||
|
"machine_steps_per_mm_x": { "default_value": 80 },
|
||||||
|
"machine_steps_per_mm_y": { "default_value": 80 },
|
||||||
|
"machine_steps_per_mm_z": { "default_value": 400 },
|
||||||
|
"machine_steps_per_mm_e": { "default_value": 400 },
|
||||||
|
|
||||||
|
"machine_max_feedrate_x": { "value": 200 },
|
||||||
|
"machine_max_feedrate_y": { "value": 200 },
|
||||||
|
"machine_max_feedrate_z": { "value": 20 },
|
||||||
|
"machine_max_feedrate_e": { "value": 70 },
|
||||||
|
|
||||||
|
"acceleration_enabled": { "value": false },
|
||||||
|
"jerk_enabled": { "value": false },
|
||||||
|
|
||||||
|
"machine_max_acceleration_x": { "value": 1000 },
|
||||||
|
"machine_max_acceleration_y": { "value": 1000 },
|
||||||
|
"machine_max_acceleration_z": { "value": 100 },
|
||||||
|
"machine_max_acceleration_e": { "value": 1000 },
|
||||||
|
"machine_acceleration": { "value": 1000 },
|
||||||
|
|
||||||
|
"machine_max_jerk_xy": { "value": 20 },
|
||||||
|
"machine_max_jerk_z": { "value": 0.4 },
|
||||||
|
"machine_max_jerk_e": { "value": 5.0 },
|
||||||
|
|
||||||
|
"acceleration_print": { "value": 1000 },
|
||||||
|
"acceleration_travel": { "value": 1000 },
|
||||||
|
"acceleration_travel_layer_0": { "value": "acceleration_travel" },
|
||||||
|
"acceleration_roofing": { "enabled": "acceleration_enabled and roofing_layer_count > 0 and top_layers > 0" },
|
||||||
|
|
||||||
|
"jerk_print": { "value": 20 },
|
||||||
|
"jerk_travel": { "value": "jerk_print" },
|
||||||
|
"jerk_travel_layer_0": { "value": "jerk_travel" }
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,7 +45,7 @@
|
||||||
"machine_max_jerk_e": { "default_value": 2.5 },
|
"machine_max_jerk_e": { "default_value": 2.5 },
|
||||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||||
"machine_start_gcode": {
|
"machine_start_gcode": {
|
||||||
"default_value": "G28 \nG1 Z15 F300\nM107\nG90\nM82\nM104 S215\nM140 S55\nG92 E0\nM109 S215\nM107\nM163 S0 P0.50\nM163 S1 P0.50\nM164 S4\nG0 X10 Y20 F6000\nG1 Z0.8\nG1 F300 X180 E40\nG1 F1200 Z2\nG92 E0\nG28"
|
"default_value": ";GeeeTech A10M start script\nG28 ;home\nG90 ;absolute positioning\nG1 X0 Y0 Z15 E0 F300 ;go to wait position\nM140 S{material_bed_temperature_layer_0} ;set bed temp\nM190 S{material_print_temperature_layer_0} ;set extruder temp and wait\nG1 Z0.8 F200 ;set extruder height\nG1 X220 Y0 E80 F1000 ;purge line\n;end of start script"
|
||||||
},
|
},
|
||||||
"machine_end_gcode": {
|
"machine_end_gcode": {
|
||||||
"default_value": "G91\nG1 E-1\nG0 X0 Y200\nM104 S0\nG90\nG92 E0\nM140 S0\nM84\nM104 S0\nM140 S0\nM84"
|
"default_value": "G91\nG1 E-1\nG0 X0 Y200\nM104 S0\nG90\nG92 E0\nM140 S0\nM84\nM104 S0\nM140 S0\nM84"
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
"machine_max_jerk_e": { "default_value": 2.5 },
|
"machine_max_jerk_e": { "default_value": 2.5 },
|
||||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||||
"machine_start_gcode": {
|
"machine_start_gcode": {
|
||||||
"default_value": "G28 \nG1 Z15 F300\nM107\nG90\nM82\nM104 S215\nM140 S55\nG92 E0\nM109 S215\nM107\nM163 S0 P0.50\nM163 S1 P0.50\nM164 S4\nG0 X10 Y20 F6000\nG1 Z0.8\nG1 F300 X200 E40\nG1 F1200 Z2\nG92 E0\nG28"
|
"default_value": ";GeeeTech A20M start script\nG28 ;home\nG90 ;absolute positioning\nG1 X0 Y0 Z15 E0 F300 ;go to wait position\nM140 S{material_bed_temperature_layer_0} ;set bed temp\nM190 S{material_print_temperature_layer_0} ;set extruder temp and wait\nG1 Z0.8 F200 ;set extruder height\nG1 X220 Y0 E80 F1000 ;purge line\n;end of start script"
|
||||||
},
|
},
|
||||||
"machine_end_gcode": {
|
"machine_end_gcode": {
|
||||||
"default_value": "G91\nG1 E-1\nG0 X0 Y200\nM104 S0\nG90\nG92 E0\nM140 S0\nM84\nM104 S0\nM140 S0\nM84"
|
"default_value": "G91\nG1 E-1\nG0 X0 Y200\nM104 S0\nG90\nG92 E0\nM140 S0\nM84\nM104 S0\nM140 S0\nM84"
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||||
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} ; Preheat\nM109 S{material_print_temperature} ; Preheat\nG91 ;relative positioning\nG90 ;absolute positioning\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." },
|
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} ; Preheat\nM109 S{material_print_temperature} ; Preheat\nG91 ;relative positioning\nG90 ;absolute positioning\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." },
|
||||||
"machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" },
|
"machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" },
|
||||||
"wall_thickness": { "default_value": 1 },
|
"wall_thickness": { "value": "1" },
|
||||||
"top_bottom_thickness": { "default_value": 1 }
|
"top_bottom_thickness": { "default_value": 1 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
||||||
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} T0 ; Preheat Left Extruder\nM104 S{material_print_temperature} T1 ; Preheat Right Extruder\nM109 S{material_print_temperature} T0 ; Preheat Left Extruder\nM109 S{material_print_temperature} T1 ; Preheat Right Extruder\nG91 ;relative positioning\nG90 ;absolute positioning\nM218 T1 X34.3 Y0; Set 2nd extruder offset. This can be changed later if needed\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." },
|
"machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 ;Home X/Y/Z\nM104 S{material_print_temperature} T0 ; Preheat Left Extruder\nM104 S{material_print_temperature} T1 ; Preheat Right Extruder\nM109 S{material_print_temperature} T0 ; Preheat Left Extruder\nM109 S{material_print_temperature} T1 ; Preheat Right Extruder\nG91 ;relative positioning\nG90 ;absolute positioning\nM218 T1 X34.3 Y0; Set 2nd extruder offset. This can be changed later if needed\nG1 Z25.0 F9000 ;raise nozzle 25mm\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." },
|
||||||
"machine_end_gcode": { "default_value": "M104 S0 T0;Left extruder off\nM104 S0 T1; Right extruder off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" },
|
"machine_end_gcode": { "default_value": "M104 S0 T0;Left extruder off\nM104 S0 T1; Right extruder off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning" },
|
||||||
"wall_thickness": { "default_value": 1 },
|
"wall_thickness": { "value": "1" },
|
||||||
"top_bottom_thickness": { "default_value": 1 }
|
"top_bottom_thickness": { "default_value": 1 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
"machine_center_is_zero": { "default_value": false },
|
"machine_center_is_zero": { "default_value": false },
|
||||||
"layer_height": { "default_value": 0.2 },
|
"layer_height": { "default_value": 0.2 },
|
||||||
"layer_height_0": { "default_value": 0.2 },
|
"layer_height_0": { "default_value": 0.2 },
|
||||||
"wall_thickness": { "default_value": 1.2 },
|
"wall_thickness": { "value": "1.2" },
|
||||||
"top_bottom_thickness": { "default_value": 1.2 },
|
"top_bottom_thickness": { "default_value": 1.2 },
|
||||||
"infill_sparse_density": { "default_value": 20 },
|
"infill_sparse_density": { "default_value": 20 },
|
||||||
"speed_print": { "default_value": 60 },
|
"speed_print": { "default_value": 60 },
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
"default_value": 0.15
|
"default_value": 0.15
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 0.8
|
"value": "0.8"
|
||||||
},
|
},
|
||||||
"top_bottom_thickness": {
|
"top_bottom_thickness": {
|
||||||
"default_value": 1.2
|
"default_value": 1.2
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
"default_value": 0.12
|
"default_value": 0.12
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"speed_print": {
|
"speed_print": {
|
||||||
"default_value": 40
|
"default_value": 40
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
"default_value": 0.12
|
"default_value": 0.12
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"speed_print": {
|
"speed_print": {
|
||||||
"default_value": 35
|
"default_value": 35
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
"default_value": 0.12
|
"default_value": 0.12
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"speed_print": {
|
"speed_print": {
|
||||||
"default_value": 40
|
"default_value": 40
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"speed_print": {
|
"speed_print": {
|
||||||
"default_value": 60
|
"default_value": 60
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
"default_value": 0.2
|
"default_value": 0.2
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"speed_print": {
|
"speed_print": {
|
||||||
"default_value": 60
|
"default_value": 60
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
"default_value": 60
|
"default_value": 60
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"cool_min_layer_time_fan_speed_max": {
|
"cool_min_layer_time_fan_speed_max": {
|
||||||
"default_value": 5
|
"default_value": 5
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
"default_value": 60
|
"default_value": 60
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"cool_min_layer_time_fan_speed_max": {
|
"cool_min_layer_time_fan_speed_max": {
|
||||||
"default_value": 5
|
"default_value": 5
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
"default_value": 60
|
"default_value": 60
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"default_value": 1.2
|
"value": "1.2"
|
||||||
},
|
},
|
||||||
"cool_min_layer_time_fan_speed_max": {
|
"cool_min_layer_time_fan_speed_max": {
|
||||||
"default_value": 5
|
"default_value": 5
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"layer_height": { "default_value": 0.2 },
|
"layer_height": { "default_value": 0.2 },
|
||||||
"wall_thickness": { "default_value": 0.8 },
|
"wall_thickness": { "value": "0.8" },
|
||||||
"top_bottom_thickness": { "default_value": 0.3 },
|
"top_bottom_thickness": { "default_value": 0.3 },
|
||||||
"retraction_enable": { "default_value": true },
|
"retraction_enable": { "default_value": true },
|
||||||
"retraction_speed": { "default_value": 50 },
|
"retraction_speed": { "default_value": 50 },
|
||||||
|
|
57
resources/definitions/mbot3d_grid2plus.def.json
Normal file
57
resources/definitions/mbot3d_grid2plus.def.json
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"name": "MBot3D Grid 2+",
|
||||||
|
"version": 2,
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"visible": true,
|
||||||
|
"author": "Magicfirm",
|
||||||
|
"manufacturer": "Magicfirm",
|
||||||
|
"file_formats": "application/x3g",
|
||||||
|
"machine_x3g_variant": "r1",
|
||||||
|
"machine_extruder_trains":
|
||||||
|
{
|
||||||
|
"0": "mbot3d_grid2_extruder_0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": { "default_value": "MBot3D Grid 2+" },
|
||||||
|
"machine_start_gcode": {
|
||||||
|
"default_value": "M136\nG162 X Y F2000\nG161 Z F900\nG92 X0 Y0 Z-5 A0 B0\nG1 Z0.0 F900\nG161 Z F100\nM132 X Y Z A B\nG1 X125 Y115 Z10 F450\nG1 X0 Y115 Z10 F2000.0\nM133 T0\nG1 X20 Y115 Z0.5 F800\nG1 X0 Y115 Z0.5 F600 A12\nG92 A0\n"
|
||||||
|
},
|
||||||
|
"machine_end_gcode": {
|
||||||
|
"default_value": "M18 A B(Turn off A and B steppers)\nG1 Z190 F900\nG162 X Y F2000\nM18 X Y Z(Turn off steppers after a build)\nM104 S0 T0\nM72 P1 ( Play Ta-Da song )\nM73 P100 (end build progress )\nM137 (build end)\n"
|
||||||
|
},
|
||||||
|
"machine_width": { "default_value": 235 },
|
||||||
|
"machine_depth": { "default_value": 210 },
|
||||||
|
"machine_height": { "default_value": 190 },
|
||||||
|
"machine_heated_bed": { "default_value": true },
|
||||||
|
"machine_center_is_zero": { "default_value": true },
|
||||||
|
"machine_gcode_flavor": { "default_value": "Makerbot" },
|
||||||
|
"machine_head_with_fans_polygon": { "default_value": [ [ -37, 50 ], [ 25, 50 ], [ 25, -40 ], [ -37, -40 ] ] },
|
||||||
|
"gantry_height": { "value": 10 },
|
||||||
|
"machine_steps_per_mm_x": { "default_value": 88.888889 },
|
||||||
|
"machine_steps_per_mm_y": { "default_value": 88.888889 },
|
||||||
|
"machine_steps_per_mm_z": { "default_value": 400 },
|
||||||
|
"machine_steps_per_mm_e": { "default_value": 96.27520187033366 },
|
||||||
|
"retraction_amount": { "default_value": 0.7 },
|
||||||
|
"retraction_speed": { "default_value": 15 },
|
||||||
|
"speed_print": { "default_value": 50 },
|
||||||
|
"speed_wall": { "value": 25 },
|
||||||
|
"speed_wall_x": { "value": 35 },
|
||||||
|
"speed_travel": { "value": 80 },
|
||||||
|
"speed_layer_0": { "value": 15 },
|
||||||
|
"support_interface_enable": { "default_value": true },
|
||||||
|
"support_interface_height": { "default_value": 0.8 },
|
||||||
|
"support_interface_density": { "default_value": 80 },
|
||||||
|
"support_interface_pattern": { "default_value": "grid" },
|
||||||
|
"infill_overlap": { "value": "12 if infill_sparse_density < 95 and infill_pattern != 'concentric' else 0" },
|
||||||
|
"retract_at_layer_change": { "default_value": true },
|
||||||
|
"travel_retract_before_outer_wall": { "default_value": true },
|
||||||
|
"material_initial_print_temperature": { "value": "material_print_temperature" },
|
||||||
|
"material_final_print_temperature": { "value": "material_print_temperature" },
|
||||||
|
"travel_avoid_other_parts": { "default_value": false },
|
||||||
|
"raft_airgap": { "default_value": 0.15 },
|
||||||
|
"raft_margin": { "default_value": 6 }
|
||||||
|
}
|
||||||
|
}
|
58
resources/definitions/mbot3d_grid2plus_dual.def.json
Normal file
58
resources/definitions/mbot3d_grid2plus_dual.def.json
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
{
|
||||||
|
"name": "MBot3D Grid 2+ Dual",
|
||||||
|
"version": 2,
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"visible": true,
|
||||||
|
"author": "Magicfirm",
|
||||||
|
"manufacturer": "Magicfirm",
|
||||||
|
"file_formats": "application/x3g",
|
||||||
|
"machine_x3g_variant": "z",
|
||||||
|
"machine_extruder_trains":
|
||||||
|
{
|
||||||
|
"0": "mbot3d_grid2_extruder_left",
|
||||||
|
"1": "mbot3d_grid2_extruder_right"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": { "default_value": "MBot3D Grid 2+ Dual" },
|
||||||
|
"machine_start_gcode": {
|
||||||
|
"default_value": "M136\nG162 X Y F2000\nG161 Z F900\nG92 X0 Y0 Z-5 A0 B0\nG1 Z0.0 F900\nG161 Z F100\nM132 X Y Z A B\nG1 X125 Y115 Z10 F450\nG1 X0 Y115 Z10 F2000.0\nM133 T0\nG1 X20 Y115 Z0.5 F800\nG1 X0 Y115 Z0.5 F600 A12\nG92 A0\n"
|
||||||
|
},
|
||||||
|
"machine_end_gcode": {
|
||||||
|
"default_value": "M18 A B(Turn off A and B steppers)\nG1 Z190 F900\nG162 X Y F2000\nM18 X Y Z(Turn off steppers after a build)\nM104 S0 T0\nM72 P1 ( Play Ta-Da song )\nM73 P100 (end build progress )\nM137 (build end)\n"
|
||||||
|
},
|
||||||
|
"machine_width": { "default_value": 235 },
|
||||||
|
"machine_depth": { "default_value": 210 },
|
||||||
|
"machine_height": { "default_value": 190 },
|
||||||
|
"machine_extruder_count": { "default_value": 2 },
|
||||||
|
"machine_center_is_zero": { "default_value": true },
|
||||||
|
"machine_gcode_flavor": { "default_value": "Makerbot" },
|
||||||
|
"machine_head_with_fans_polygon": { "default_value": [ [ -37, 50 ], [ 25, 50 ], [ 25, -40 ], [ -37, -40 ] ] },
|
||||||
|
"gantry_height": { "value": 10 },
|
||||||
|
"machine_steps_per_mm_x": { "default_value": 88.888889 },
|
||||||
|
"machine_steps_per_mm_y": { "default_value": 88.888889 },
|
||||||
|
"machine_steps_per_mm_z": { "default_value": 400 },
|
||||||
|
"machine_steps_per_mm_e": { "default_value": 96.27520187033366 },
|
||||||
|
"retraction_amount": { "default_value": 0.7 },
|
||||||
|
"retraction_speed": { "default_value": 15 },
|
||||||
|
"speed_print": { "default_value": 50 },
|
||||||
|
"speed_wall": { "value": 25 },
|
||||||
|
"speed_wall_x": { "value": 35 },
|
||||||
|
"speed_travel": { "value": 80 },
|
||||||
|
"speed_layer_0": { "value": 15 },
|
||||||
|
"support_interface_enable": { "default_value": true },
|
||||||
|
"support_interface_height": { "default_value": 0.8 },
|
||||||
|
"support_interface_density": { "default_value": 80 },
|
||||||
|
"support_interface_pattern": { "default_value": "grid" },
|
||||||
|
"infill_overlap": { "value": "12 if infill_sparse_density < 95 and infill_pattern != 'concentric' else 0" },
|
||||||
|
"retract_at_layer_change": { "default_value": true },
|
||||||
|
"travel_retract_before_outer_wall": { "default_value": true },
|
||||||
|
"material_initial_print_temperature": { "value": "material_print_temperature" },
|
||||||
|
"material_final_print_temperature": { "value": "material_print_temperature" },
|
||||||
|
"travel_avoid_other_parts": { "default_value": false },
|
||||||
|
"raft_airgap": { "default_value": 0.15 },
|
||||||
|
"raft_margin": { "default_value": 6 }
|
||||||
|
}
|
||||||
|
}
|
57
resources/definitions/mbot3d_grid4.def.json
Normal file
57
resources/definitions/mbot3d_grid4.def.json
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"name": "MBot3D Grid 4",
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"author": "Magicfirm",
|
||||||
|
"manufacturer": "Magicfirm",
|
||||||
|
"category": "Other",
|
||||||
|
"visible": true,
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"platform_offset": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"has_materials": true,
|
||||||
|
"machine_extruder_trains":
|
||||||
|
{
|
||||||
|
"0": "mbot3d_grid4_extruder_0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": {
|
||||||
|
"default_value": "MBot3D Grid 4"
|
||||||
|
},
|
||||||
|
"machine_width": {
|
||||||
|
"default_value": 235
|
||||||
|
},
|
||||||
|
"machine_depth": {
|
||||||
|
"default_value": 210
|
||||||
|
},
|
||||||
|
"machine_height": {
|
||||||
|
"default_value": 190
|
||||||
|
},
|
||||||
|
"machine_heated_bed": {
|
||||||
|
"default_value": true
|
||||||
|
},
|
||||||
|
"machine_center_is_zero": {
|
||||||
|
"default_value": false
|
||||||
|
},
|
||||||
|
"machine_gcode_flavor": {
|
||||||
|
"default_value": "RepRap (Marlin/Sprinter)"
|
||||||
|
},
|
||||||
|
"material_flow": {
|
||||||
|
"default_value": 100
|
||||||
|
},
|
||||||
|
"adhesion_type": {
|
||||||
|
"default_value": "skirt"
|
||||||
|
},
|
||||||
|
"machine_start_gcode": {
|
||||||
|
"default_value": ";---------- START GCODE ----------\nG21 ; set units to millimeters\nG28 ; home all axes\nG29 ;Autolevel bed\nG1 Z10 F400\nG1 X145 Z10 F2400\nG92 E0\nG1 X145 Z0.5 F400\nG1 X120 Z0.5 E20 F360\nG92 E0.0\n;----------END START GCODE ----------\n"
|
||||||
|
},
|
||||||
|
"machine_end_gcode": {
|
||||||
|
"default_value": "M104 S0 ; turn off extruder\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 Z190 F900\nG28 X Y ;home X Y axes\nM84 ; disable motors"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
resources/definitions/mbot3d_grid4_dual.def.json
Normal file
60
resources/definitions/mbot3d_grid4_dual.def.json
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"name": "MBot3D Grid 4 Dual",
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"author": "Magicfirm",
|
||||||
|
"manufacturer": "Magicfirm",
|
||||||
|
"category": "Other",
|
||||||
|
"visible": true,
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"platform_offset": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"has_materials": true,
|
||||||
|
"machine_extruder_trains": {
|
||||||
|
"0": "mbot3d_grid4_extruder_left",
|
||||||
|
"1": "mbot3d_grid4_extruder_right"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": {
|
||||||
|
"default_value": "MBot3D Grid 4 Dual"
|
||||||
|
},
|
||||||
|
"machine_width": {
|
||||||
|
"default_value": 210
|
||||||
|
},
|
||||||
|
"machine_depth": {
|
||||||
|
"default_value": 210
|
||||||
|
},
|
||||||
|
"machine_height": {
|
||||||
|
"default_value": 190
|
||||||
|
},
|
||||||
|
"machine_heated_bed": {
|
||||||
|
"default_value": true
|
||||||
|
},
|
||||||
|
"machine_center_is_zero": {
|
||||||
|
"default_value": false
|
||||||
|
},
|
||||||
|
"machine_gcode_flavor": {
|
||||||
|
"default_value": "RepRap (Marlin/Sprinter)"
|
||||||
|
},
|
||||||
|
"machine_extruder_count": {
|
||||||
|
"default_value": 2
|
||||||
|
},
|
||||||
|
"material_flow": {
|
||||||
|
"default_value": 100
|
||||||
|
},
|
||||||
|
"adhesion_type": {
|
||||||
|
"default_value": "skirt"
|
||||||
|
},
|
||||||
|
"machine_start_gcode": {
|
||||||
|
"default_value": ";---------- START GCODE ----------\nG21 ; set units to millimeters\nG28 ; home all axes\nG29 ;Autolevel bed\nG1 Z10 F400\nG1 X145 Z10 F2400\nG92 E0\nG1 X145 Z0.5 F400\nG1 X120 Z0.5 E20 F360\nG92 E0.0\n;----------END START GCODE ----------\n"
|
||||||
|
},
|
||||||
|
"machine_end_gcode": {
|
||||||
|
"default_value": "M104 S0 ; turn off extruder\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 Z190 F900\nG28 X Y ;home X Y axes\nM84 ; disable motors"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -189,7 +189,7 @@
|
||||||
"value": "machine_nozzle_size / 3"
|
"value": "machine_nozzle_size / 3"
|
||||||
},
|
},
|
||||||
"wall_thickness": {
|
"wall_thickness": {
|
||||||
"value": 0.5
|
"value": "0.5"
|
||||||
},
|
},
|
||||||
"infill_sparse_density": {
|
"infill_sparse_density": {
|
||||||
"value": 70
|
"value": 70
|
||||||
|
|
|
@ -1,44 +1,33 @@
|
||||||
{
|
{
|
||||||
"name": "Rigid3D",
|
"name": "Rigid3D 2. Nesil",
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"inherits": "fdmprinter",
|
"inherits": "rigid3d_base",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"author": "Ultimaker",
|
"quality_definition": "rigid3d_base",
|
||||||
"manufacturer": "Rigid3D",
|
|
||||||
"file_formats": "text/x-gcode",
|
"preferred_quality_type": "standard"
|
||||||
"platform_offset": [ 0, 0, 0],
|
},
|
||||||
"machine_extruder_trains":
|
"overrides": {
|
||||||
{
|
"machine_name": { "default_value": "Rigid3D 2. Nesil" },
|
||||||
"0": "rigid3d_extruder_0"
|
|
||||||
}
|
"machine_heated_bed": { "default_value": true },
|
||||||
|
|
||||||
|
"machine_width": { "default_value": 250 },
|
||||||
|
"machine_depth": { "default_value": 250 },
|
||||||
|
"machine_height": { "default_value": 210 },
|
||||||
|
|
||||||
|
"machine_center_is_zero": { "default_value": false },
|
||||||
|
|
||||||
|
"machine_start_gcode": {"default_value": " ; -- START GCODE --\n G21\n G28 ; Home extruder\n G29 ; Autolevel bed\n M107 ; Turn off fan\n G90 ; Absolute positioning\n M82 ; Extruder in absolute mode\n G92 E0 ; Reset extruder position\n ; -- end of START GCODE --\n\n"},
|
||||||
|
"machine_end_gcode": {"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn ectruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"},
|
||||||
|
|
||||||
|
"machine_head_with_fans_polygon": {
|
||||||
|
"default_value": [
|
||||||
|
[ -22, -67], [ -22, 51], [ 36, -67], [ 36, 51]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"overrides": {
|
"gantry_height": { "value": 20 }
|
||||||
"machine_start_gcode": {
|
|
||||||
"default_value": " ; -- START GCODE --\n G21\n G28 ; Home extruder\n G29 ; Autolevel bed\n M107 ; Turn off fan\n G90 ; Absolute positioning\n M82 ; Extruder in absolute mode\n G92 E0 ; Reset extruder position\n ; -- end of START GCODE --\n\n"
|
|
||||||
},
|
|
||||||
"machine_end_gcode": {
|
|
||||||
"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn ectruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"
|
|
||||||
},
|
|
||||||
"machine_head_with_fans_polygon": { "default_value": [[ 22, 67], [ 22, 51], [ 36, 51], [ 36, 67]] },
|
|
||||||
"skirt_gap": { "default_value": 5.0 },
|
|
||||||
"cool_min_layer_time": { "default_value": 10 },
|
|
||||||
"prime_tower_size": { "default_value": 7.745966692414834 },
|
|
||||||
"layer_height_0": { "default_value": 0.25 },
|
|
||||||
"support_angle": { "default_value": 45 },
|
|
||||||
"retraction_speed": { "default_value": 60.0 },
|
|
||||||
"wall_thickness": { "default_value": 0.8 },
|
|
||||||
"retraction_amount": { "default_value": 1 },
|
|
||||||
"layer_height": { "default_value": 0.25 },
|
|
||||||
"speed_print": { "default_value": 40 },
|
|
||||||
"machine_extruder_count": { "default_value": 1 },
|
|
||||||
"machine_heated_bed": { "default_value": true },
|
|
||||||
"machine_center_is_zero": { "default_value": false },
|
|
||||||
"machine_height": { "default_value": 210 },
|
|
||||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
|
||||||
"machine_depth": { "default_value": 250 },
|
|
||||||
"machine_width": { "default_value": 250 },
|
|
||||||
"machine_name": { "default_value": "Rigid3D" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +1,33 @@
|
||||||
{
|
{
|
||||||
"name": "Rigid3D 3rdGen",
|
"name": "Rigid3D 3. Nesil",
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"inherits": "fdmprinter",
|
"inherits": "rigid3d_base",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"author": "Ultimaker",
|
"quality_definition": "rigid3d_base",
|
||||||
"manufacturer": "Rigid3D",
|
|
||||||
"file_formats": "text/x-gcode",
|
"preferred_quality_type": "standard"
|
||||||
"platform_offset": [ 0, 0, 0],
|
},
|
||||||
"machine_extruder_trains":
|
"overrides": {
|
||||||
{
|
"machine_name": { "default_value": "Rigid3D 3. Nesil" },
|
||||||
"0": "rigid3d_3rdgen_extruder_0"
|
|
||||||
}
|
"machine_heated_bed": { "default_value": true },
|
||||||
|
|
||||||
|
"machine_width": { "default_value": 270 },
|
||||||
|
"machine_depth": { "default_value": 290 },
|
||||||
|
"machine_height": { "default_value": 240 },
|
||||||
|
|
||||||
|
"machine_center_is_zero": { "default_value": false },
|
||||||
|
|
||||||
|
"machine_start_gcode": {"default_value": " ; -- START GCODE --\n G21\n G28 ; Home extruder\n G29 ; Autolevel bed\n M107 ; Turn off fan\n G90 ; Absolute positioning\n M82 ; Extruder in absolute mode\n G92 E0 ; Reset extruder position\n ; -- end of START GCODE --\n\n"},
|
||||||
|
"machine_end_gcode": {"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn extruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"},
|
||||||
|
|
||||||
|
"machine_head_with_fans_polygon": {
|
||||||
|
"default_value": [
|
||||||
|
[ -18, -20], [ -18, 45], [ 32, -20], [ 32, 45]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"overrides": {
|
"gantry_height": { "value": 20 }
|
||||||
"machine_start_gcode": {
|
|
||||||
"default_value": " ; -- START GCODE --\n G21\n G28 ; Home extruder\n G29 ; Autolevel bed\n M107 ; Turn off fan\n G90 ; Absolute positioning\n M82 ; Extruder in absolute mode\n G92 E0 ; Reset extruder position\n ; -- end of START GCODE --\n\n"
|
|
||||||
},
|
|
||||||
"machine_end_gcode": {
|
|
||||||
"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn extruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"
|
|
||||||
},
|
|
||||||
"machine_head_with_fans_polygon": { "default_value": [[ 18, 0], [ 18, 65], [ 32, 65], [ 32, 0]] },
|
|
||||||
"cool_min_layer_time": { "default_value": 10 },
|
|
||||||
"prime_tower_size": { "default_value": 7.745966692414834 },
|
|
||||||
"skirt_gap": { "default_value": 5.0 },
|
|
||||||
"layer_height_0": { "default_value": 0.25 },
|
|
||||||
"support_angle": { "default_value": 45 },
|
|
||||||
"retraction_speed": { "default_value": 60.0 },
|
|
||||||
"wall_thickness": { "default_value": 0.8 },
|
|
||||||
"retraction_amount": { "default_value": 1 },
|
|
||||||
"layer_height": { "default_value": 0.25 },
|
|
||||||
"machine_extruder_count": { "default_value": 1 },
|
|
||||||
"machine_heated_bed": { "default_value": true },
|
|
||||||
"machine_center_is_zero": { "default_value": false },
|
|
||||||
"machine_height": { "default_value": 240 },
|
|
||||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
|
||||||
"machine_depth": { "default_value": 290 },
|
|
||||||
"machine_width": { "default_value": 275 },
|
|
||||||
"machine_name": { "default_value": "Rigid3D 3rd Geneartion" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
274
resources/definitions/rigid3d_base.def.json
Normal file
274
resources/definitions/rigid3d_base.def.json
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
{
|
||||||
|
"name": "Rigid3D Base Printer",
|
||||||
|
"version": 2,
|
||||||
|
"inherits": "fdmprinter",
|
||||||
|
"metadata": {
|
||||||
|
"visible": false,
|
||||||
|
"author": "Ramazan UTKU",
|
||||||
|
"manufacturer": "Rigid3D",
|
||||||
|
"file_formats": "text/x-gcode",
|
||||||
|
"has_materials": true,
|
||||||
|
"has_machine_quality": true,
|
||||||
|
|
||||||
|
"machine_extruder_trains":{
|
||||||
|
"0": "rigid3d_base_extruder_0"
|
||||||
|
},
|
||||||
|
"first_start_actions": ["MachineSettingsAction"],
|
||||||
|
"supported_actions": ["MachineSettingsAction"],
|
||||||
|
|
||||||
|
"preferred_material": "generic_pla_175",
|
||||||
|
"exclude_materials": [
|
||||||
|
"chromatik_pla",
|
||||||
|
"dsm_arnitel2045_175",
|
||||||
|
"dsm_novamid1070_175",
|
||||||
|
"emotiontech_abs",
|
||||||
|
"emotiontech_asax",
|
||||||
|
"emotiontech_hips",
|
||||||
|
"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",
|
||||||
|
"generic_abs",
|
||||||
|
"generic_bam",
|
||||||
|
"generic_cffcpe",
|
||||||
|
"generic_cffpa",
|
||||||
|
"generic_cpe",
|
||||||
|
"generic_cpe_plus",
|
||||||
|
"generic_gffcpe",
|
||||||
|
"generic_gffpa",
|
||||||
|
"generic_hips",
|
||||||
|
"generic_nylon",
|
||||||
|
"generic_pc",
|
||||||
|
"generic_petg",
|
||||||
|
"generic_pla",
|
||||||
|
"generic_pp",
|
||||||
|
"generic_pva",
|
||||||
|
"generic_tough_pla",
|
||||||
|
"generic_tpu",
|
||||||
|
"imade3d_petg_175",
|
||||||
|
"imade3d_pla_175",
|
||||||
|
"innofill_innoflex60_175",
|
||||||
|
"leapfrog_abs_natural",
|
||||||
|
"leapfrog_epla_natural",
|
||||||
|
"leapfrog_pva_natural",
|
||||||
|
"octofiber_pla",
|
||||||
|
"polyflex_pla",
|
||||||
|
"polymax_pla",
|
||||||
|
"polyplus_pla",
|
||||||
|
"polywood_pla",
|
||||||
|
"structur3d_dap100silicone",
|
||||||
|
"tizyx_abs",
|
||||||
|
"tizyx_flex",
|
||||||
|
"tizyx_petg",
|
||||||
|
"tizyx_pla",
|
||||||
|
"tizyx_pla_bois",
|
||||||
|
"tizyx_pva",
|
||||||
|
"ultimaker_abs_black",
|
||||||
|
"ultimaker_abs_blue",
|
||||||
|
"ultimaker_abs_green",
|
||||||
|
"ultimaker_abs_grey",
|
||||||
|
"ultimaker_abs_orange",
|
||||||
|
"ultimaker_abs_pearl-gold",
|
||||||
|
"ultimaker_abs_red",
|
||||||
|
"ultimaker_abs_silver-metallic",
|
||||||
|
"ultimaker_abs_white",
|
||||||
|
"ultimaker_abs_yellow",
|
||||||
|
"ultimaker_bam",
|
||||||
|
"ultimaker_cpe_black",
|
||||||
|
"ultimaker_cpe_blue",
|
||||||
|
"ultimaker_cpe_dark-grey",
|
||||||
|
"ultimaker_cpe_green",
|
||||||
|
"ultimaker_cpe_light-grey",
|
||||||
|
"ultimaker_cpe_plus_black",
|
||||||
|
"ultimaker_cpe_plus_transparent",
|
||||||
|
"ultimaker_cpe_plus_white",
|
||||||
|
"ultimaker_cpe_red",
|
||||||
|
"ultimaker_cpe_transparent",
|
||||||
|
"ultimaker_cpe_white",
|
||||||
|
"ultimaker_cpe_yellow",
|
||||||
|
"ultimaker_nylon_black",
|
||||||
|
"ultimaker_nylon_transparent",
|
||||||
|
"ultimaker_pc_black",
|
||||||
|
"ultimaker_pc_transparent",
|
||||||
|
"ultimaker_pc_white",
|
||||||
|
"ultimaker_pla_black",
|
||||||
|
"ultimaker_pla_blue",
|
||||||
|
"ultimaker_pla_green",
|
||||||
|
"ultimaker_pla_magenta",
|
||||||
|
"ultimaker_pla_orange",
|
||||||
|
"ultimaker_pla_pearl-white",
|
||||||
|
"ultimaker_pla_red",
|
||||||
|
"ultimaker_pla_silver-metallic",
|
||||||
|
"ultimaker_pla_transparent",
|
||||||
|
"ultimaker_pla_white",
|
||||||
|
"ultimaker_pla_yellow",
|
||||||
|
"ultimaker_pp_transparent",
|
||||||
|
"ultimaker_pva",
|
||||||
|
"ultimaker_tough_pla_black",
|
||||||
|
"ultimaker_tough_pla_green",
|
||||||
|
"ultimaker_tough_pla_red",
|
||||||
|
"ultimaker_tough_pla_white",
|
||||||
|
"ultimaker_tpu_black",
|
||||||
|
"ultimaker_tpu_blue",
|
||||||
|
"ultimaker_tpu_red",
|
||||||
|
"ultimaker_tpu_white",
|
||||||
|
"verbatim_bvoh_175",
|
||||||
|
"Vertex_Delta_ABS",
|
||||||
|
"Vertex_Delta_PET",
|
||||||
|
"Vertex_Delta_PLA",
|
||||||
|
"Vertex_Delta_PLA_Glitter",
|
||||||
|
"Vertex_Delta_PLA_Mat",
|
||||||
|
"Vertex_Delta_PLA_Satin",
|
||||||
|
"Vertex_Delta_PLA_Wood",
|
||||||
|
"Vertex_Delta_TPU",
|
||||||
|
"zyyx_pro_flex",
|
||||||
|
"zyyx_pro_pla"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": { "default_value": "Rigid3D Base Printer" },
|
||||||
|
|
||||||
|
"material_diameter": { "default_value": 1.75 },
|
||||||
|
|
||||||
|
"machine_max_feedrate_x": { "value": 500 },
|
||||||
|
"machine_max_feedrate_y": { "value": 500 },
|
||||||
|
"machine_max_feedrate_z": { "value": 500 },
|
||||||
|
"machine_max_feedrate_e": { "value": 500 },
|
||||||
|
|
||||||
|
"machine_max_acceleration_x": { "value": 600 },
|
||||||
|
"machine_max_acceleration_y": { "value": 600 },
|
||||||
|
"machine_max_acceleration_z": { "value": 100 },
|
||||||
|
"machine_max_acceleration_e": { "value": 600 },
|
||||||
|
"machine_acceleration": { "value": 600 },
|
||||||
|
|
||||||
|
"machine_max_jerk_xy": { "value": 10.0 },
|
||||||
|
"machine_max_jerk_z": { "value": 0.3 },
|
||||||
|
"machine_max_jerk_e": { "value": 5 },
|
||||||
|
|
||||||
|
"acceleration_print": { "value": 600 },
|
||||||
|
|
||||||
|
"acceleration_travel": { "value": 600 },
|
||||||
|
"acceleration_travel_layer_0": { "value": "acceleration_travel" },
|
||||||
|
"acceleration_roofing": { "enabled": "acceleration_enabled and roofing_layer_count > 0 and top_layers > 0" },
|
||||||
|
|
||||||
|
"jerk_print": { "value": 10 },
|
||||||
|
"jerk_travel": { "value": "jerk_print" },
|
||||||
|
"jerk_travel_layer_0": { "value": "jerk_travel" },
|
||||||
|
|
||||||
|
"acceleration_enabled": { "value": false },
|
||||||
|
"jerk_enabled": { "value": false },
|
||||||
|
|
||||||
|
"speed_print": { "value": 40.0 } ,
|
||||||
|
"speed_infill": { "value": "speed_print" },
|
||||||
|
"speed_wall": { "value": "speed_print / 2" },
|
||||||
|
"speed_wall_0": { "value": "speed_print" },
|
||||||
|
"speed_wall_x": { "value": "speed_print" },
|
||||||
|
"speed_topbottom": { "value": "speed_print" },
|
||||||
|
"speed_roofing": { "value": "speed_topbottom" },
|
||||||
|
"speed_travel": { "value": "80.0" },
|
||||||
|
"speed_layer_0": { "value": 15.0 },
|
||||||
|
"speed_print_layer_0": { "value": "speed_layer_0" },
|
||||||
|
"speed_travel_layer_0": { "value": "speed_travel" },
|
||||||
|
"speed_prime_tower": { "value": "speed_topbottom" },
|
||||||
|
"speed_support": { "value": "speed_wall_0" },
|
||||||
|
"speed_support_interface": { "value": "speed_topbottom" },
|
||||||
|
"speed_z_hop": { "value": 5 },
|
||||||
|
|
||||||
|
"skirt_brim_speed": { "value": "speed_layer_0" },
|
||||||
|
|
||||||
|
"line_width": { "value": "machine_nozzle_size" },
|
||||||
|
|
||||||
|
"optimize_wall_printing_order": { "value": "True" },
|
||||||
|
|
||||||
|
"material_initial_print_temperature": { "value": "material_print_temperature" },
|
||||||
|
"material_final_print_temperature": { "value": "material_print_temperature" },
|
||||||
|
"material_flow": { "value": 100 },
|
||||||
|
|
||||||
|
"z_seam_type": { "value": "'shortest'" },
|
||||||
|
"z_seam_corner": { "value": "'z_seam_corner_inner'" },
|
||||||
|
|
||||||
|
"infill_sparse_density": { "value": "15" },
|
||||||
|
"wall_0_wipe_dist": { "value": 0.0 },
|
||||||
|
|
||||||
|
"retraction_speed": {
|
||||||
|
"maximum_value_warning": "machine_max_feedrate_e if retraction_enable else float('inf')",
|
||||||
|
"value":30,
|
||||||
|
"maximum_value": 200
|
||||||
|
},
|
||||||
|
"retraction_retract_speed": {
|
||||||
|
"maximum_value_warning": "machine_max_feedrate_e if retraction_enable else float('inf')",
|
||||||
|
"value":"retraction_speed",
|
||||||
|
"maximum_value": 200
|
||||||
|
},
|
||||||
|
"retraction_prime_speed": {
|
||||||
|
"maximum_value_warning": "machine_max_feedrate_e if retraction_enable else float('inf')",
|
||||||
|
"value":"retraction_speed / 2",
|
||||||
|
"maximum_value": 200
|
||||||
|
},
|
||||||
|
|
||||||
|
"retraction_hop_enabled": { "value": "False" },
|
||||||
|
"retraction_hop": { "value": 0.2 },
|
||||||
|
"retraction_combing": { "value": "'off' if retraction_hop_enabled else 'noskin'" },
|
||||||
|
"retraction_amount" : { "default_value": 1.0},
|
||||||
|
"retraction_combing_max_distance": { "value": 30 },
|
||||||
|
"travel_avoid_other_parts": { "value": true },
|
||||||
|
"travel_avoid_supports": { "value": true },
|
||||||
|
"travel_retract_before_outer_wall": { "value": false },
|
||||||
|
|
||||||
|
"small_hole_max_size": { "value": 4.0 },
|
||||||
|
|
||||||
|
"retraction_enable": { "value": true },
|
||||||
|
"retraction_count_max": { "value": 5 },
|
||||||
|
"retraction_extrusion_window": { "value": "retraction_amount" },
|
||||||
|
"retraction_min_travel": { "value": 0.5 },
|
||||||
|
|
||||||
|
"cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" },
|
||||||
|
"cool_fan_enabled": { "value": true },
|
||||||
|
"cool_min_layer_time": { "value": 10 },
|
||||||
|
|
||||||
|
"adhesion_type": { "value": "'skirt'" },
|
||||||
|
"skirt_gap": { "value": 5.0 },
|
||||||
|
"skirt_line_count": { "value": 2 },
|
||||||
|
|
||||||
|
"adaptive_layer_height_variation": { "value": 0.04 },
|
||||||
|
"adaptive_layer_height_variation_step": { "value": 0.04 },
|
||||||
|
|
||||||
|
"meshfix_maximum_resolution": { "value": "0.05" },
|
||||||
|
"meshfix_maximum_travel_resolution": { "value": "meshfix_maximum_resolution" },
|
||||||
|
|
||||||
|
"support_angle": { "value": "math.floor(math.degrees(math.atan(line_width/2.0/layer_height)))" },
|
||||||
|
"support_pattern": { "value": "'zigzag'" },
|
||||||
|
"support_infill_rate": { "value": "0 if support_tree_enable else 20" },
|
||||||
|
"support_use_towers": { "value": false },
|
||||||
|
"support_xy_distance": { "value": "wall_line_width_0 * 2" },
|
||||||
|
"support_xy_distance_overhang": { "value": "wall_line_width_0" },
|
||||||
|
"support_z_distance": { "value": "layer_height if layer_height >= 0.16 else layer_height*2" },
|
||||||
|
"support_xy_overrides_z": { "value": "'xy_overrides_z'" },
|
||||||
|
"support_wall_count": { "value": 1 },
|
||||||
|
"support_brim_enable": { "value": true },
|
||||||
|
"support_brim_width": { "value": 4 },
|
||||||
|
|
||||||
|
"support_interface_enable": { "value": true },
|
||||||
|
"support_interface_height": { "value": "layer_height * 4" },
|
||||||
|
"support_interface_density": { "value": 70 },
|
||||||
|
"support_interface_pattern": { "value": "'grid'" },
|
||||||
|
"support_interface_skip_height": { "value": 0.2 },
|
||||||
|
"minimum_support_area": { "value": 5 },
|
||||||
|
"minimum_interface_area": { "value": 10 },
|
||||||
|
"top_bottom_thickness": {"value": "layer_height_0 + layer_height * 3" },
|
||||||
|
"wall_thickness": {"value": "line_width * 2" },
|
||||||
|
|
||||||
|
"layer_height_0": {"value": 0.2}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,40 +1,159 @@
|
||||||
{
|
{
|
||||||
"name": "Rigid3D Hobby",
|
"name": "Rigid3D Hobby",
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"inherits": "fdmprinter",
|
"inherits": "rigid3d_base",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"author": "Ultimaker",
|
"quality_definition": "rigid3d_base",
|
||||||
"manufacturer": "Rigid3D",
|
"preferred_quality_type": "standard",
|
||||||
"file_formats": "text/x-gcode",
|
|
||||||
"platform_offset": [ 0, 0, 0],
|
"preferred_material": "generic_pla_175",
|
||||||
"machine_extruder_trains":
|
"exclude_materials": [
|
||||||
{
|
"chromatik_pla",
|
||||||
"0": "rigid3d_hobby_extruder_0"
|
"dsm_arnitel2045_175",
|
||||||
}
|
"dsm_novamid1070_175",
|
||||||
|
"emotiontech_abs",
|
||||||
|
"emotiontech_asax",
|
||||||
|
"emotiontech_hips",
|
||||||
|
"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",
|
||||||
|
"generic_abs",
|
||||||
|
"generic_abs_175",
|
||||||
|
"generic_bam",
|
||||||
|
"generic_cffcpe",
|
||||||
|
"generic_cffpa",
|
||||||
|
"generic_cpe",
|
||||||
|
"generic_cpe_175",
|
||||||
|
"generic_cpe_plus",
|
||||||
|
"generic_gffcpe",
|
||||||
|
"generic_gffpa",
|
||||||
|
"generic_hips",
|
||||||
|
"generic_hips_175",
|
||||||
|
"generic_nylon",
|
||||||
|
"generic_nylon_175",
|
||||||
|
"generic_pc",
|
||||||
|
"generic_pc_175",
|
||||||
|
"generic_petg",
|
||||||
|
"generic_petg_175",
|
||||||
|
"generic_pla",
|
||||||
|
"generic_pp",
|
||||||
|
"generic_pva",
|
||||||
|
"generic_pva_175",
|
||||||
|
"generic_tough_pla",
|
||||||
|
"generic_tpu",
|
||||||
|
"generic_tpu_175",
|
||||||
|
"imade3d_petg_175",
|
||||||
|
"imade3d_pla_175",
|
||||||
|
"innofill_innoflex60_175",
|
||||||
|
"leapfrog_abs_natural",
|
||||||
|
"leapfrog_epla_natural",
|
||||||
|
"leapfrog_pva_natural",
|
||||||
|
"octofiber_pla",
|
||||||
|
"polyflex_pla",
|
||||||
|
"polymax_pla",
|
||||||
|
"polyplus_pla",
|
||||||
|
"polywood_pla",
|
||||||
|
"structur3d_dap100silicone",
|
||||||
|
"tizyx_abs",
|
||||||
|
"tizyx_flex",
|
||||||
|
"tizyx_petg",
|
||||||
|
"tizyx_pla",
|
||||||
|
"tizyx_pla_bois",
|
||||||
|
"tizyx_pva",
|
||||||
|
"ultimaker_abs_black",
|
||||||
|
"ultimaker_abs_blue",
|
||||||
|
"ultimaker_abs_green",
|
||||||
|
"ultimaker_abs_grey",
|
||||||
|
"ultimaker_abs_orange",
|
||||||
|
"ultimaker_abs_pearl-gold",
|
||||||
|
"ultimaker_abs_red",
|
||||||
|
"ultimaker_abs_silver-metallic",
|
||||||
|
"ultimaker_abs_white",
|
||||||
|
"ultimaker_abs_yellow",
|
||||||
|
"ultimaker_bam",
|
||||||
|
"ultimaker_cpe_black",
|
||||||
|
"ultimaker_cpe_blue",
|
||||||
|
"ultimaker_cpe_dark-grey",
|
||||||
|
"ultimaker_cpe_green",
|
||||||
|
"ultimaker_cpe_light-grey",
|
||||||
|
"ultimaker_cpe_plus_black",
|
||||||
|
"ultimaker_cpe_plus_transparent",
|
||||||
|
"ultimaker_cpe_plus_white",
|
||||||
|
"ultimaker_cpe_red",
|
||||||
|
"ultimaker_cpe_transparent",
|
||||||
|
"ultimaker_cpe_white",
|
||||||
|
"ultimaker_cpe_yellow",
|
||||||
|
"ultimaker_nylon_black",
|
||||||
|
"ultimaker_nylon_transparent",
|
||||||
|
"ultimaker_pc_black",
|
||||||
|
"ultimaker_pc_transparent",
|
||||||
|
"ultimaker_pc_white",
|
||||||
|
"ultimaker_pla_black",
|
||||||
|
"ultimaker_pla_blue",
|
||||||
|
"ultimaker_pla_green",
|
||||||
|
"ultimaker_pla_magenta",
|
||||||
|
"ultimaker_pla_orange",
|
||||||
|
"ultimaker_pla_pearl-white",
|
||||||
|
"ultimaker_pla_red",
|
||||||
|
"ultimaker_pla_silver-metallic",
|
||||||
|
"ultimaker_pla_transparent",
|
||||||
|
"ultimaker_pla_white",
|
||||||
|
"ultimaker_pla_yellow",
|
||||||
|
"ultimaker_pp_transparent",
|
||||||
|
"ultimaker_pva",
|
||||||
|
"ultimaker_tough_pla_black",
|
||||||
|
"ultimaker_tough_pla_green",
|
||||||
|
"ultimaker_tough_pla_red",
|
||||||
|
"ultimaker_tough_pla_white",
|
||||||
|
"ultimaker_tpu_black",
|
||||||
|
"ultimaker_tpu_blue",
|
||||||
|
"ultimaker_tpu_red",
|
||||||
|
"ultimaker_tpu_white",
|
||||||
|
"verbatim_bvoh_175",
|
||||||
|
"Vertex_Delta_ABS",
|
||||||
|
"Vertex_Delta_PET",
|
||||||
|
"Vertex_Delta_PLA",
|
||||||
|
"Vertex_Delta_PLA_Glitter",
|
||||||
|
"Vertex_Delta_PLA_Mat",
|
||||||
|
"Vertex_Delta_PLA_Satin",
|
||||||
|
"Vertex_Delta_PLA_Wood",
|
||||||
|
"Vertex_Delta_TPU",
|
||||||
|
"zyyx_pro_flex",
|
||||||
|
"zyyx_pro_pla"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": { "default_value": "Rigid3D Hobby" },
|
||||||
|
|
||||||
|
"machine_heated_bed": { "default_value": false },
|
||||||
|
|
||||||
|
"machine_width": { "default_value": 150 },
|
||||||
|
"machine_depth": { "default_value": 150 },
|
||||||
|
"machine_height": { "default_value": 150 },
|
||||||
|
|
||||||
|
"machine_center_is_zero": { "default_value": false },
|
||||||
|
|
||||||
|
"machine_start_gcode": {"default_value": "G21\nG28 ; Home extruder\nM420 S1 ; Enable MBL\nM107 ; Turn off fan\nG91 ; Relative positioning\nG1 Z5 F180;\nG1 X30 Y30 F3000;\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\nG92 E0 ; Reset extruder position\n"},
|
||||||
|
"machine_end_gcode": {"default_value": "G1 X0 Y145 ; Get extruder out of way.\nM107 ; Turn off fan\nG91 ; Relative positioning\nG0 Z20 ; Lift extruder up\nT0\nG1 E-1 ; Reduce filament pressure\nM104 T0 S0 ; Turn extruder heater off\nG90 ; Absolute positioning\nG92 E0 ; Reset extruder position\nM84 ; Turn steppers off\n"},
|
||||||
|
|
||||||
|
"machine_head_with_fans_polygon": {
|
||||||
|
"default_value": [
|
||||||
|
[ -16, -30], [ -16, 45], [ 16, -30], [ 16, 45]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"overrides": {
|
"gantry_height": { "value": 20 }
|
||||||
"machine_head_with_fans_polygon": { "default_value": [[ 16, 30], [ 16, 45], [ 16, 45], [ 16, 30]] },
|
|
||||||
"prime_tower_size": { "default_value": 8.660254037844387 },
|
|
||||||
"skirt_gap": { "default_value": 5.0 },
|
|
||||||
"cool_min_layer_time": { "default_value": 15 },
|
|
||||||
"support_pattern": { "default_value": "grid" },
|
|
||||||
"layer_height_0": { "default_value": 0.25 },
|
|
||||||
"skirt_line_count": { "default_value": 2 },
|
|
||||||
"support_angle": { "default_value": 45 },
|
|
||||||
"retraction_speed": { "default_value": 80 },
|
|
||||||
"wall_thickness": { "default_value": 0.8 },
|
|
||||||
"retraction_amount": { "default_value": 2 },
|
|
||||||
"layer_height": { "default_value": 0.2 },
|
|
||||||
"speed_print": { "default_value": 30 },
|
|
||||||
"machine_extruder_count": { "default_value": 1 },
|
|
||||||
"machine_heated_bed": { "default_value": false },
|
|
||||||
"machine_center_is_zero": { "default_value": false },
|
|
||||||
"machine_height": { "default_value": 150 },
|
|
||||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
|
||||||
"machine_depth": { "default_value": 150 },
|
|
||||||
"machine_width": { "default_value": 150 },
|
|
||||||
"machine_name": { "default_value": "Rigid3D Hobby" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,142 +1,161 @@
|
||||||
{
|
{
|
||||||
"name": "Rigid3D Mucit",
|
"name": "Rigid3D Mucit",
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"inherits": "fdmprinter",
|
"inherits": "rigid3d_base",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"author": "Rigid3D",
|
"quality_definition": "rigid3d_base",
|
||||||
"manufacturer": "Rigid3D",
|
"preferred_quality_type": "standard",
|
||||||
"has_materials": false,
|
|
||||||
"file_formats": "text/x-gcode",
|
|
||||||
"platform": "rigid3d_mucit_platform.stl",
|
"platform": "rigid3d_mucit_platform.stl",
|
||||||
"platform_offset": [ 0, -19, 0],
|
"platform_offset": [ 0, -19, 0],
|
||||||
"preferred_quality_type": "draft",
|
|
||||||
"machine_extruder_trains":
|
"preferred_material": "generic_pla_175",
|
||||||
{
|
"exclude_materials": [
|
||||||
"0": "rigid3d_mucit_extruder_0"
|
"chromatik_pla",
|
||||||
}
|
"dsm_arnitel2045_175",
|
||||||
|
"dsm_novamid1070_175",
|
||||||
|
"emotiontech_abs",
|
||||||
|
"emotiontech_asax",
|
||||||
|
"emotiontech_hips",
|
||||||
|
"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",
|
||||||
|
"generic_abs",
|
||||||
|
"generic_abs_175",
|
||||||
|
"generic_bam",
|
||||||
|
"generic_cffcpe",
|
||||||
|
"generic_cffpa",
|
||||||
|
"generic_cpe",
|
||||||
|
"generic_cpe_175",
|
||||||
|
"generic_cpe_plus",
|
||||||
|
"generic_gffcpe",
|
||||||
|
"generic_gffpa",
|
||||||
|
"generic_hips",
|
||||||
|
"generic_hips_175",
|
||||||
|
"generic_nylon",
|
||||||
|
"generic_nylon_175",
|
||||||
|
"generic_pc",
|
||||||
|
"generic_pc_175",
|
||||||
|
"generic_petg",
|
||||||
|
"generic_petg_175",
|
||||||
|
"generic_pla",
|
||||||
|
"generic_pp",
|
||||||
|
"generic_pva",
|
||||||
|
"generic_pva_175",
|
||||||
|
"generic_tough_pla",
|
||||||
|
"generic_tpu",
|
||||||
|
"generic_tpu_175",
|
||||||
|
"imade3d_petg_175",
|
||||||
|
"imade3d_pla_175",
|
||||||
|
"innofill_innoflex60_175",
|
||||||
|
"leapfrog_abs_natural",
|
||||||
|
"leapfrog_epla_natural",
|
||||||
|
"leapfrog_pva_natural",
|
||||||
|
"octofiber_pla",
|
||||||
|
"polyflex_pla",
|
||||||
|
"polymax_pla",
|
||||||
|
"polyplus_pla",
|
||||||
|
"polywood_pla",
|
||||||
|
"structur3d_dap100silicone",
|
||||||
|
"tizyx_abs",
|
||||||
|
"tizyx_flex",
|
||||||
|
"tizyx_petg",
|
||||||
|
"tizyx_pla",
|
||||||
|
"tizyx_pla_bois",
|
||||||
|
"tizyx_pva",
|
||||||
|
"ultimaker_abs_black",
|
||||||
|
"ultimaker_abs_blue",
|
||||||
|
"ultimaker_abs_green",
|
||||||
|
"ultimaker_abs_grey",
|
||||||
|
"ultimaker_abs_orange",
|
||||||
|
"ultimaker_abs_pearl-gold",
|
||||||
|
"ultimaker_abs_red",
|
||||||
|
"ultimaker_abs_silver-metallic",
|
||||||
|
"ultimaker_abs_white",
|
||||||
|
"ultimaker_abs_yellow",
|
||||||
|
"ultimaker_bam",
|
||||||
|
"ultimaker_cpe_black",
|
||||||
|
"ultimaker_cpe_blue",
|
||||||
|
"ultimaker_cpe_dark-grey",
|
||||||
|
"ultimaker_cpe_green",
|
||||||
|
"ultimaker_cpe_light-grey",
|
||||||
|
"ultimaker_cpe_plus_black",
|
||||||
|
"ultimaker_cpe_plus_transparent",
|
||||||
|
"ultimaker_cpe_plus_white",
|
||||||
|
"ultimaker_cpe_red",
|
||||||
|
"ultimaker_cpe_transparent",
|
||||||
|
"ultimaker_cpe_white",
|
||||||
|
"ultimaker_cpe_yellow",
|
||||||
|
"ultimaker_nylon_black",
|
||||||
|
"ultimaker_nylon_transparent",
|
||||||
|
"ultimaker_pc_black",
|
||||||
|
"ultimaker_pc_transparent",
|
||||||
|
"ultimaker_pc_white",
|
||||||
|
"ultimaker_pla_black",
|
||||||
|
"ultimaker_pla_blue",
|
||||||
|
"ultimaker_pla_green",
|
||||||
|
"ultimaker_pla_magenta",
|
||||||
|
"ultimaker_pla_orange",
|
||||||
|
"ultimaker_pla_pearl-white",
|
||||||
|
"ultimaker_pla_red",
|
||||||
|
"ultimaker_pla_silver-metallic",
|
||||||
|
"ultimaker_pla_transparent",
|
||||||
|
"ultimaker_pla_white",
|
||||||
|
"ultimaker_pla_yellow",
|
||||||
|
"ultimaker_pp_transparent",
|
||||||
|
"ultimaker_pva",
|
||||||
|
"ultimaker_tough_pla_black",
|
||||||
|
"ultimaker_tough_pla_green",
|
||||||
|
"ultimaker_tough_pla_red",
|
||||||
|
"ultimaker_tough_pla_white",
|
||||||
|
"ultimaker_tpu_black",
|
||||||
|
"ultimaker_tpu_blue",
|
||||||
|
"ultimaker_tpu_red",
|
||||||
|
"ultimaker_tpu_white",
|
||||||
|
"verbatim_bvoh_175",
|
||||||
|
"Vertex_Delta_ABS",
|
||||||
|
"Vertex_Delta_PET",
|
||||||
|
"Vertex_Delta_PLA",
|
||||||
|
"Vertex_Delta_PLA_Glitter",
|
||||||
|
"Vertex_Delta_PLA_Mat",
|
||||||
|
"Vertex_Delta_PLA_Satin",
|
||||||
|
"Vertex_Delta_PLA_Wood",
|
||||||
|
"Vertex_Delta_TPU",
|
||||||
|
"zyyx_pro_flex",
|
||||||
|
"zyyx_pro_pla"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"machine_name": { "default_value": "Rigid3D Mucit" },
|
"machine_name": { "default_value": "Rigid3D Mucit" },
|
||||||
"z_seam_type": {
|
|
||||||
"default_value": "random"
|
"machine_heated_bed": { "default_value": false },
|
||||||
|
|
||||||
|
"machine_width": { "default_value": 150 },
|
||||||
|
"machine_depth": { "default_value": 150 },
|
||||||
|
"machine_height": { "default_value": 150 },
|
||||||
|
|
||||||
|
"machine_center_is_zero": { "default_value": false },
|
||||||
|
|
||||||
|
"machine_start_gcode": {"default_value": "G21\nG28 ; Home extruder\nM420 S1 ; Enable MBL\nM107 ; Turn off fan\nG91 ; Relative positioning\nG1 Z5 F180;\nG1 X30 Y30 F3000;\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\nG92 E0 ; Reset extruder position\n"},
|
||||||
|
"machine_end_gcode": {"default_value": "G1 X0 Y145 ; Get extruder out of way.\nM107 ; Turn off fan\nG91 ; Relative positioning\nG0 Z20 ; Lift extruder up\nT0\nG1 E-1 ; Reduce filament pressure\nM104 T0 S0 ; Turn extruder heater off\nG90 ; Absolute positioning\nG92 E0 ; Reset extruder position\nM84 ; Turn steppers off\n"},
|
||||||
|
|
||||||
|
"machine_head_with_fans_polygon": {
|
||||||
|
"default_value": [
|
||||||
|
[ -20, 102], [ -20, -45], [ 45, -45], [ 45, 102]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"machine_heated_bed": {
|
|
||||||
"default_value": false
|
"gantry_height": { "value": 20 }
|
||||||
},
|
|
||||||
"layer_height_0": {
|
|
||||||
"default_value": 0.2
|
|
||||||
},
|
|
||||||
"wall_thickness": {
|
|
||||||
"default_value": 0.8
|
|
||||||
},
|
|
||||||
"top_bottom_thickness": {
|
|
||||||
"default_value": 0.8
|
|
||||||
},
|
|
||||||
"xy_offset": {
|
|
||||||
"default_value": -0.2
|
|
||||||
},
|
|
||||||
"material_print_temperature": {
|
|
||||||
"value": "205"
|
|
||||||
},
|
|
||||||
"speed_print": {
|
|
||||||
"default_value": 40
|
|
||||||
},
|
|
||||||
"speed_layer_0": {
|
|
||||||
"value": "15"
|
|
||||||
},
|
|
||||||
"speed_travel": {
|
|
||||||
"value": "100"
|
|
||||||
},
|
|
||||||
"support_enable": {
|
|
||||||
"default_value": false
|
|
||||||
},
|
|
||||||
"infill_sparse_density": {
|
|
||||||
"default_value": 15
|
|
||||||
},
|
|
||||||
"infill_pattern": {
|
|
||||||
"value": "'lines'"
|
|
||||||
},
|
|
||||||
"retraction_amount": {
|
|
||||||
"default_value": 1
|
|
||||||
},
|
|
||||||
"machine_width": {
|
|
||||||
"default_value": 150
|
|
||||||
},
|
|
||||||
"machine_height": {
|
|
||||||
"default_value": 150
|
|
||||||
},
|
|
||||||
"machine_depth": {
|
|
||||||
"default_value": 150
|
|
||||||
},
|
|
||||||
"machine_gcode_flavor": {
|
|
||||||
"default_value": "RepRap"
|
|
||||||
},
|
|
||||||
"cool_fan_enabled": {
|
|
||||||
"default_value": true
|
|
||||||
},
|
|
||||||
"cool_fan_speed": {
|
|
||||||
"value": "100"
|
|
||||||
},
|
|
||||||
"cool_fan_full_at_height": {
|
|
||||||
"value": "0.5"
|
|
||||||
},
|
|
||||||
"support_z_distance": {
|
|
||||||
"default_value": 0.2
|
|
||||||
},
|
|
||||||
"support_interface_enable": {
|
|
||||||
"default_value": true
|
|
||||||
},
|
|
||||||
"support_interface_height": {
|
|
||||||
"default_value": 0.8
|
|
||||||
},
|
|
||||||
"support_interface_density": {
|
|
||||||
"default_value": 70
|
|
||||||
},
|
|
||||||
"support_interface_pattern": {
|
|
||||||
"default_value": "grid"
|
|
||||||
},
|
|
||||||
"fill_outline_gaps": {
|
|
||||||
"default_value": true
|
|
||||||
},
|
|
||||||
"ironing_enabled": {
|
|
||||||
"default_value": true
|
|
||||||
},
|
|
||||||
"ironing_only_highest_layer": {
|
|
||||||
"default_value": true
|
|
||||||
},
|
|
||||||
"material_initial_print_temperature": {
|
|
||||||
"value": "205"
|
|
||||||
},
|
|
||||||
"optimize_wall_printing_order": {
|
|
||||||
"default_value": true
|
|
||||||
},
|
|
||||||
"retraction_speed": {
|
|
||||||
"value": "40"
|
|
||||||
},
|
|
||||||
"roofing_layer_count": {
|
|
||||||
"value": "1"
|
|
||||||
},
|
|
||||||
"speed_equalize_flow_enabled": {
|
|
||||||
"default_value": true
|
|
||||||
},
|
|
||||||
"speed_topbottom": {
|
|
||||||
"value": "40"
|
|
||||||
},
|
|
||||||
"speed_travel_layer_0": {
|
|
||||||
"value": "15"
|
|
||||||
},
|
|
||||||
"speed_wall_0": {
|
|
||||||
"value": "30"
|
|
||||||
},
|
|
||||||
"adhesion_type": {
|
|
||||||
"default_value": "skirt"
|
|
||||||
},
|
|
||||||
"machine_start_gcode": {
|
|
||||||
"default_value": "G21\nG28 ; Home extruder\nM420 S1 ; Enable MBL\nM107 ; Turn off fan\nG91 ; Relative positioning\nG1 Z5 F180;\nG1 X30 Y30 F3000;\nG90 ; Absolute positioning\nM82 ; Extruder in absolute mode\nG92 E0 ; Reset extruder position\n"
|
|
||||||
},
|
|
||||||
"machine_end_gcode": {
|
|
||||||
"default_value": "G1 X0 Y145 ; Get extruder out of way.\nM107 ; Turn off fan\nG91 ; Relative positioning\nG0 Z20 ; Lift extruder up\nT0\nG1 E-1 ; Reduce filament pressure\nM104 T0 S0 ; Turn extruder heater off\nG90 ; Absolute positioning\nG92 E0 ; Reset extruder position\nM84 ; Turn steppers off\n"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,44 +1,159 @@
|
||||||
{
|
{
|
||||||
"name": "Rigid3D Zero",
|
"name": "Rigid3D Zero",
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"inherits": "fdmprinter",
|
"inherits": "rigid3d_base",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"visible": true,
|
"visible": true,
|
||||||
"author": "Ultimaker",
|
"quality_definition": "rigid3d_base",
|
||||||
"manufacturer": "Rigid3D",
|
"preferred_quality_type": "standard",
|
||||||
"file_formats": "text/x-gcode",
|
|
||||||
"platform_offset": [ 0, 0, 0],
|
"preferred_material": "generic_pla_175",
|
||||||
"machine_extruder_trains":
|
"exclude_materials": [
|
||||||
{
|
"chromatik_pla",
|
||||||
"0": "rigid3d_zero_extruder_0"
|
"dsm_arnitel2045_175",
|
||||||
}
|
"dsm_novamid1070_175",
|
||||||
|
"emotiontech_abs",
|
||||||
|
"emotiontech_asax",
|
||||||
|
"emotiontech_hips",
|
||||||
|
"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",
|
||||||
|
"generic_abs",
|
||||||
|
"generic_abs_175",
|
||||||
|
"generic_bam",
|
||||||
|
"generic_cffcpe",
|
||||||
|
"generic_cffpa",
|
||||||
|
"generic_cpe",
|
||||||
|
"generic_cpe_175",
|
||||||
|
"generic_cpe_plus",
|
||||||
|
"generic_gffcpe",
|
||||||
|
"generic_gffpa",
|
||||||
|
"generic_hips",
|
||||||
|
"generic_hips_175",
|
||||||
|
"generic_nylon",
|
||||||
|
"generic_nylon_175",
|
||||||
|
"generic_pc",
|
||||||
|
"generic_pc_175",
|
||||||
|
"generic_petg",
|
||||||
|
"generic_petg_175",
|
||||||
|
"generic_pla",
|
||||||
|
"generic_pp",
|
||||||
|
"generic_pva",
|
||||||
|
"generic_pva_175",
|
||||||
|
"generic_tough_pla",
|
||||||
|
"generic_tpu",
|
||||||
|
"generic_tpu_175",
|
||||||
|
"imade3d_petg_175",
|
||||||
|
"imade3d_pla_175",
|
||||||
|
"innofill_innoflex60_175",
|
||||||
|
"leapfrog_abs_natural",
|
||||||
|
"leapfrog_epla_natural",
|
||||||
|
"leapfrog_pva_natural",
|
||||||
|
"octofiber_pla",
|
||||||
|
"polyflex_pla",
|
||||||
|
"polymax_pla",
|
||||||
|
"polyplus_pla",
|
||||||
|
"polywood_pla",
|
||||||
|
"structur3d_dap100silicone",
|
||||||
|
"tizyx_abs",
|
||||||
|
"tizyx_flex",
|
||||||
|
"tizyx_petg",
|
||||||
|
"tizyx_pla",
|
||||||
|
"tizyx_pla_bois",
|
||||||
|
"tizyx_pva",
|
||||||
|
"ultimaker_abs_black",
|
||||||
|
"ultimaker_abs_blue",
|
||||||
|
"ultimaker_abs_green",
|
||||||
|
"ultimaker_abs_grey",
|
||||||
|
"ultimaker_abs_orange",
|
||||||
|
"ultimaker_abs_pearl-gold",
|
||||||
|
"ultimaker_abs_red",
|
||||||
|
"ultimaker_abs_silver-metallic",
|
||||||
|
"ultimaker_abs_white",
|
||||||
|
"ultimaker_abs_yellow",
|
||||||
|
"ultimaker_bam",
|
||||||
|
"ultimaker_cpe_black",
|
||||||
|
"ultimaker_cpe_blue",
|
||||||
|
"ultimaker_cpe_dark-grey",
|
||||||
|
"ultimaker_cpe_green",
|
||||||
|
"ultimaker_cpe_light-grey",
|
||||||
|
"ultimaker_cpe_plus_black",
|
||||||
|
"ultimaker_cpe_plus_transparent",
|
||||||
|
"ultimaker_cpe_plus_white",
|
||||||
|
"ultimaker_cpe_red",
|
||||||
|
"ultimaker_cpe_transparent",
|
||||||
|
"ultimaker_cpe_white",
|
||||||
|
"ultimaker_cpe_yellow",
|
||||||
|
"ultimaker_nylon_black",
|
||||||
|
"ultimaker_nylon_transparent",
|
||||||
|
"ultimaker_pc_black",
|
||||||
|
"ultimaker_pc_transparent",
|
||||||
|
"ultimaker_pc_white",
|
||||||
|
"ultimaker_pla_black",
|
||||||
|
"ultimaker_pla_blue",
|
||||||
|
"ultimaker_pla_green",
|
||||||
|
"ultimaker_pla_magenta",
|
||||||
|
"ultimaker_pla_orange",
|
||||||
|
"ultimaker_pla_pearl-white",
|
||||||
|
"ultimaker_pla_red",
|
||||||
|
"ultimaker_pla_silver-metallic",
|
||||||
|
"ultimaker_pla_transparent",
|
||||||
|
"ultimaker_pla_white",
|
||||||
|
"ultimaker_pla_yellow",
|
||||||
|
"ultimaker_pp_transparent",
|
||||||
|
"ultimaker_pva",
|
||||||
|
"ultimaker_tough_pla_black",
|
||||||
|
"ultimaker_tough_pla_green",
|
||||||
|
"ultimaker_tough_pla_red",
|
||||||
|
"ultimaker_tough_pla_white",
|
||||||
|
"ultimaker_tpu_black",
|
||||||
|
"ultimaker_tpu_blue",
|
||||||
|
"ultimaker_tpu_red",
|
||||||
|
"ultimaker_tpu_white",
|
||||||
|
"verbatim_bvoh_175",
|
||||||
|
"Vertex_Delta_ABS",
|
||||||
|
"Vertex_Delta_PET",
|
||||||
|
"Vertex_Delta_PLA",
|
||||||
|
"Vertex_Delta_PLA_Glitter",
|
||||||
|
"Vertex_Delta_PLA_Mat",
|
||||||
|
"Vertex_Delta_PLA_Satin",
|
||||||
|
"Vertex_Delta_PLA_Wood",
|
||||||
|
"Vertex_Delta_TPU",
|
||||||
|
"zyyx_pro_flex",
|
||||||
|
"zyyx_pro_pla"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"machine_name": { "default_value": "Rigid3D Zero" },
|
||||||
|
|
||||||
|
"machine_heated_bed": { "default_value": false },
|
||||||
|
|
||||||
|
"machine_width": { "default_value": 250 },
|
||||||
|
"machine_depth": { "default_value": 250 },
|
||||||
|
"machine_height": { "default_value": 190 },
|
||||||
|
|
||||||
|
"machine_center_is_zero": { "default_value": false },
|
||||||
|
|
||||||
|
"machine_start_gcode": {"default_value": " ; -- START GCODE --\n G21\n G28 ; Home extruder\n G29 ; Autolevel bed\n M107 ; Turn off fan\n G90 ; Absolute positioning\n M82 ; Extruder in absolute mode\n G92 E0 ; Reset extruder position\n ; -- end of START GCODE --\n\n"},
|
||||||
|
"machine_end_gcode": {"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn ectruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"},
|
||||||
|
|
||||||
|
"machine_head_with_fans_polygon": {
|
||||||
|
"default_value": [
|
||||||
|
[ -40, -15], [ -40, 60], [ 30, -15], [ 30, 60]
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
"overrides": {
|
"gantry_height": { "value": 20 }
|
||||||
"machine_start_gcode": {
|
|
||||||
"default_value": " ; -- START GCODE --\n G21\n G28 ; Home extruder\n G29 ; Autolevel bed\n M107 ; Turn off fan\n G90 ; Absolute positioning\n M82 ; Extruder in absolute mode\n G92 E0 ; Reset extruder position\n ; -- end of START GCODE --\n\n"
|
|
||||||
},
|
|
||||||
"machine_end_gcode": {
|
|
||||||
"default_value": " ; -- END GCODE --\n G1 X0 Y230 ; Get extruder out of way.\n M107 ; Turn off fan\n G91 ; Relative positioning\n G0 Z20 ; Lift extruder up\n T0\n G1 E-1 ; Reduce filament pressure\n M104 T0 S0 ; Turn ectruder heater off\n G90 ; Absolute positioning\n G92 E0 ; Reset extruder position\n M140 S0 ; Disable heated bed\n M84 ; Turn steppers off\n ; -- end of END GCODE --\n"
|
|
||||||
},
|
|
||||||
"machine_head_with_fans_polygon": { "default_value": [[ 40, 15], [ 40, 60], [ 30, 60], [ 30, 15]] },
|
|
||||||
"support_pattern": { "default_value": "grid" },
|
|
||||||
"cool_min_layer_time": { "default_value": 10 },
|
|
||||||
"support_angle": { "default_value": 45 },
|
|
||||||
"prime_tower_size": { "default_value": 7.745966692414834 },
|
|
||||||
"skirt_line_count": { "default_value": 2 },
|
|
||||||
"layer_height_0": { "default_value": 0.25 },
|
|
||||||
"wall_thickness": { "default_value": 0.8 },
|
|
||||||
"retraction_amount": { "default_value": 1.5 },
|
|
||||||
"skirt_gap": { "default_value": 5.0 },
|
|
||||||
"layer_height": { "default_value": 0.25 },
|
|
||||||
"speed_print": { "default_value": 30 },
|
|
||||||
"machine_extruder_count": { "default_value": 1 },
|
|
||||||
"machine_center_is_zero": { "default_value": false },
|
|
||||||
"machine_height": { "default_value": 190 },
|
|
||||||
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
|
|
||||||
"machine_depth": { "default_value": 250 },
|
|
||||||
"machine_width": { "default_value": 250 },
|
|
||||||
"machine_name": { "default_value": "Rigid3D Zero" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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